Skip to content

Commit bb3f79d

Browse files
Mohan MaiyaAngle LUCI CQ
authored andcommitted
Reorder shader resource dirty bits
Process storage and atomic buffer dirty bits before uniform dirty bits. This helps the vulkan backend avoid duplicate work when multiple shader resources are dirty Bug: angleproject:426412564 Change-Id: Ibab3da44ee32d22078df851bfed4967d1c2a605e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6680035 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: mohan maiya <m.maiya@samsung.com> Reviewed-by: Charlie Lao <cclao@google.com>
1 parent bbe53b7 commit bb3f79d

3 files changed

Lines changed: 129 additions & 6 deletions

File tree

src/libANGLE/State.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,10 @@ enum DirtyBitType
139139
DIRTY_BIT_TEXTURE_BINDINGS,
140140
DIRTY_BIT_IMAGE_BINDINGS,
141141
DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
142-
// Top-level dirty bit. Also see mUniformBufferBlocksDirtyTypeMask.
143-
DIRTY_BIT_UNIFORM_BUFFER_BINDINGS,
144142
DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING,
145143
DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING,
144+
// Top-level dirty bit. Also see mUniformBufferBlocksDirtyTypeMask.
145+
DIRTY_BIT_UNIFORM_BUFFER_BINDINGS,
146146
DIRTY_BIT_MULTISAMPLING,
147147
DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
148148
DIRTY_BIT_COVERAGE_MODULATION, // CHROMIUM_framebuffer_mixed_samples

src/libANGLE/renderer/vulkan/ContextVk.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5946,6 +5946,15 @@ angle::Result ContextVk::syncState(const gl::Context *context,
59465946
"Dirty bit order");
59475947
iter.setLaterBit(gl::state::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
59485948
break;
5949+
case gl::state::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING:
5950+
ANGLE_TRY(invalidateCurrentShaderResources(command));
5951+
// invalidateCurrentShaderResources(...) already dirties all uniform buffers
5952+
static_assert(gl::state::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS >
5953+
gl::state::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING,
5954+
"Dirty bit order");
5955+
iter.resetLaterBit(gl::state::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
5956+
invalidateDriverUniforms();
5957+
break;
59495958
case gl::state::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS:
59505959
{
59515960
constexpr gl::BufferDirtyTypeBitMask kOnlyOffsetDirtyMask{
@@ -5964,10 +5973,6 @@ angle::Result ContextVk::syncState(const gl::Context *context,
59645973
}
59655974
break;
59665975
}
5967-
case gl::state::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING:
5968-
ANGLE_TRY(invalidateCurrentShaderResources(command));
5969-
invalidateDriverUniforms();
5970-
break;
59715976
case gl::state::DIRTY_BIT_MULTISAMPLING:
59725977
// When disabled, this should configure the pipeline to render as if single-sampled,
59735978
// and write the results to all samples of a pixel regardless of coverage. See

src/tests/gl_tests/UniformBufferTest.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,124 @@ void main()
13521352
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
13531353
}
13541354

1355+
// Test that buffer range changes to inactive UBOs works.
1356+
TEST_P(UniformBufferTest31, UniformBufferBindingRangeChangeToInactiveUBO)
1357+
{
1358+
constexpr char kFS[] = R"(#version 310 es
1359+
precision highp float;
1360+
1361+
layout (binding = 0) uniform block0 {
1362+
vec4 color;
1363+
} uni0;
1364+
1365+
layout (binding = 1) uniform block1 {
1366+
vec4 color;
1367+
} uni1;
1368+
1369+
out vec4 fragColor;
1370+
1371+
void main()
1372+
{
1373+
fragColor = uni0.color + uni1.color;
1374+
})";
1375+
1376+
constexpr char kFSWithInactiveUBO[] = R"(#version 310 es
1377+
precision highp float;
1378+
1379+
layout (binding = 0) uniform block0 {
1380+
vec4 color;
1381+
} uni0;
1382+
1383+
layout (binding = 1) uniform block1 {
1384+
vec4 color;
1385+
} uni1;
1386+
1387+
out vec4 fragColor;
1388+
1389+
void main()
1390+
{
1391+
fragColor = uni0.color;
1392+
})";
1393+
1394+
// Setup UBOs
1395+
constexpr GLsizei kVec4Size = 4 * sizeof(float);
1396+
1397+
GLint alignment;
1398+
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &alignment);
1399+
if (alignment < kVec4Size)
1400+
{
1401+
alignment = kVec4Size;
1402+
}
1403+
ASSERT_EQ(alignment % 4, 0);
1404+
1405+
// Put two colors in the uniform buffer, the sum of which is yellow.
1406+
// Note: |alignment| is in bytes, so we can place each uniform in |alignment/4| floats.
1407+
std::vector<float> colors(alignment / 2, 0);
1408+
1409+
// Set first-half of buffer to red color
1410+
colors[0] = 1.0;
1411+
colors[1] = 0.0;
1412+
colors[2] = 0.0;
1413+
colors[3] = 1.0;
1414+
// Set last-half of the buffer to green color
1415+
colors[alignment / 4 + 0] = 0.0;
1416+
colors[alignment / 4 + 1] = 1.0;
1417+
colors[alignment / 4 + 2] = 0.0;
1418+
colors[alignment / 4 + 3] = 1.0;
1419+
1420+
GLBuffer ubo0;
1421+
glBindBuffer(GL_UNIFORM_BUFFER, ubo0);
1422+
glBufferData(GL_UNIFORM_BUFFER, alignment * 2, colors.data(), GL_STATIC_DRAW);
1423+
EXPECT_GL_NO_ERROR();
1424+
1425+
// Switch color order for the other UBO
1426+
// Set first-half of buffer to green color
1427+
colors[0] = 0.0;
1428+
colors[1] = 1.0;
1429+
colors[2] = 0.0;
1430+
colors[3] = 1.0;
1431+
// Set last-half of the buffer to red color
1432+
colors[alignment / 4 + 0] = 1.0;
1433+
colors[alignment / 4 + 1] = 0.0;
1434+
colors[alignment / 4 + 2] = 0.0;
1435+
colors[alignment / 4 + 3] = 1.0;
1436+
GLBuffer ubo1;
1437+
glBindBuffer(GL_UNIFORM_BUFFER, ubo1);
1438+
glBufferData(GL_UNIFORM_BUFFER, alignment * 2, colors.data(), GL_STATIC_DRAW);
1439+
EXPECT_GL_NO_ERROR();
1440+
1441+
// Setup programs for draw
1442+
ANGLE_GL_PROGRAM(programA, essl31_shaders::vs::Simple(), kFS);
1443+
ANGLE_GL_PROGRAM(programB, essl31_shaders::vs::Simple(), kFSWithInactiveUBO);
1444+
1445+
glClearColor(0, 0, 0, 0);
1446+
glClear(GL_COLOR_BUFFER_BIT);
1447+
1448+
// Draw with programA with ubo0 and ubo1 with buffer range = [0, size / 2)
1449+
glUseProgram(programA);
1450+
glBindBufferRange(GL_UNIFORM_BUFFER, 0, ubo0, 0, kVec4Size);
1451+
glBindBufferRange(GL_UNIFORM_BUFFER, 1, ubo1, 0, kVec4Size);
1452+
drawQuad(programA, essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
1453+
EXPECT_GL_NO_ERROR();
1454+
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
1455+
1456+
// Draw with programB with ubo0 with buffer range = [size / 2, size)
1457+
// ubo1 is an inactive UBO in programB
1458+
glUseProgram(programB);
1459+
glBindBufferRange(GL_UNIFORM_BUFFER, 0, ubo0, alignment, kVec4Size);
1460+
glBindBufferRange(GL_UNIFORM_BUFFER, 1, ubo1, alignment, kVec4Size);
1461+
drawQuad(programB, essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
1462+
EXPECT_GL_NO_ERROR();
1463+
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1464+
1465+
// Draw with programA again but with no changes to ubo0 and ubo1 buffer range
1466+
glUseProgram(programA);
1467+
drawQuad(programA, essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
1468+
EXPECT_GL_NO_ERROR();
1469+
1470+
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
1471+
}
1472+
13551473
// Test that buffer range changes to both SSBO and UBO buffers work.
13561474
TEST_P(UniformBufferTest31, UniformBufferBindingRangeChangeWithSSBO)
13571475
{

0 commit comments

Comments
 (0)