Commit 10a4d434 by Xinghua Cao Committed by Commit Bot

ES31: Enable some dirty bits and dirty objects for compute pipeline

BUG=angleproject:2265 TEST=dEQP-GLES31.functional.shaders.builtin_var.compute.* angle_end2end_test.ShaderStorageBufferTest31 .MultiStorageBuffersForMultiPrograms Change-Id: Icc3df122602951a2328003c10a76696ab4c9f0d8 Reviewed-on: https://chromium-review.googlesource.com/792951 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 12a18ad3
......@@ -411,6 +411,13 @@ Context::Context(rx::EGLImplFactory *implFactory,
mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
// TODO(xinghua.cao@intel.com): add other dirty bits and dirty objects.
mComputeDirtyBits.set(State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_BINDING);
mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_EXECUTABLE);
mComputeDirtyBits.set(State::DIRTY_BIT_TEXTURE_BINDINGS);
mComputeDirtyBits.set(State::DIRTY_BIT_SAMPLER_BINDINGS);
handleError(mImplementation->initialize());
}
......@@ -4217,19 +4224,26 @@ Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
return NoError();
}
void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
Error Context::prepareForDispatch()
{
if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
syncRendererState(mComputeDirtyBits, mComputeDirtyObjects);
if (isRobustResourceInitEnabled())
{
return;
ANGLE_TRY(mGLState.clearUnclearedActiveTextures(this));
}
// TODO(jmadill): Dirty bits for compute.
if (isRobustResourceInitEnabled())
return NoError();
}
void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
{
if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
{
ANGLE_CONTEXT_TRY(mGLState.clearUnclearedActiveTextures(this));
return;
}
ANGLE_CONTEXT_TRY(prepareForDispatch());
handleError(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
}
......
......@@ -996,6 +996,7 @@ class Context final : public ValidationContext
Error getScratchBuffer(size_t requestedSizeBytes, angle::MemoryBuffer **scratchBufferOut) const;
Error getZeroFilledBuffer(size_t requstedSizeBytes, angle::MemoryBuffer **zeroBufferOut) const;
Error prepareForDispatch();
void dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ);
void dispatchComputeIndirect(GLintptr indirect);
......@@ -1122,6 +1123,8 @@ class Context final : public ValidationContext
State::DirtyObjects mClearDirtyObjects;
State::DirtyBits mBlitDirtyBits;
State::DirtyObjects mBlitDirtyObjects;
State::DirtyBits mComputeDirtyBits;
State::DirtyObjects mComputeDirtyObjects;
Workarounds mWorkarounds;
......
......@@ -1266,6 +1266,10 @@ void State::setBufferBinding(const Context *context, BufferBinding target, Buffe
getVertexArray()->setElementArrayBuffer(context, buffer);
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
break;
case BufferBinding::ShaderStorage:
mBoundBuffers[target].set(context, buffer);
mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
break;
default:
mBoundBuffers[target].set(context, buffer);
break;
......
......@@ -394,6 +394,7 @@ class State : public OnAttachmentDirtyReceiver, angle::NonCopyable
DIRTY_BIT_RENDERBUFFER_BINDING,
DIRTY_BIT_VERTEX_ARRAY_BINDING,
DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING,
DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING,
DIRTY_BIT_PROGRAM_BINDING,
DIRTY_BIT_PROGRAM_EXECUTABLE,
// TODO(jmadill): Fine-grained dirty bits for each texture/sampler.
......
......@@ -167,7 +167,8 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
mIsMultiviewEnabled(extensions.multiview),
mLocalDirtyBits(),
mMultiviewDirtyBits(),
mProgramTexturesAndSamplersDirty(true)
mProgramTexturesAndSamplersDirty(true),
mProgramStorageBuffersDirty(true)
{
ASSERT(mFunctions);
ASSERT(extensions.maxViews >= 1u);
......@@ -884,6 +885,12 @@ void StateManagerGL::setGenericShaderState(const gl::Context *context)
mProgramTexturesAndSamplersDirty = false;
}
if (mProgramStorageBuffersDirty)
{
updateProgramStorageBufferBindings(context);
mProgramStorageBuffersDirty = false;
}
// TODO(xinghua.cao@intel.com): Track image units state with dirty bits to
// avoid update every draw call.
ASSERT(context->getClientVersion() >= gl::ES_3_1 || program->getImageBindings().size() == 0);
......@@ -979,6 +986,12 @@ void StateManagerGL::updateProgramTextureAndSamplerBindings(const gl::Context *c
}
}
}
}
void StateManagerGL::updateProgramStorageBufferBindings(const gl::Context *context)
{
const gl::State &glState = context->getGLState();
const gl::Program *program = glState.getProgram();
for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount();
blockIndex++)
......@@ -1921,7 +1934,7 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt
case gl::State::DIRTY_BIT_PROGRAM_BINDING:
{
mProgramTexturesAndSamplersDirty = true;
mProgramStorageBuffersDirty = true;
gl::Program *program = state.getProgram();
if (program != nullptr)
{
......@@ -1940,12 +1953,16 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt
break;
case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
mProgramTexturesAndSamplersDirty = true;
mProgramStorageBuffersDirty = true;
propagateNumViewsToVAO(state.getProgram(),
GetImplAs<VertexArrayGL>(state.getVertexArray()));
updateMultiviewBaseViewLayerIndexUniform(
state.getProgram(),
state.getDrawFramebuffer()->getImplementation()->getState());
break;
case gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING:
mProgramStorageBuffersDirty = true;
break;
case gl::State::DIRTY_BIT_MULTISAMPLING:
setMultisamplingStateEnabled(state.isMultisamplingEnabled());
break;
......
......@@ -199,6 +199,7 @@ class StateManagerGL final : angle::NonCopyable
void propagateNumViewsToVAO(const gl::Program *program, VertexArrayGL *vao);
void updateProgramTextureAndSamplerBindings(const gl::Context *context);
void updateProgramStorageBufferBindings(const gl::Context *context);
void syncTransformFeedbackState(const gl::Context *context);
......@@ -356,6 +357,7 @@ class StateManagerGL final : angle::NonCopyable
angle::BitSet<MULTIVIEW_DIRTY_BIT_MAX> mMultiviewDirtyBits;
bool mProgramTexturesAndSamplersDirty;
bool mProgramStorageBuffersDirty;
};
}
......
......@@ -712,6 +712,9 @@ void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits
case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
WARN() << "DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING unimplemented";
break;
case gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING:
WARN() << "DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING unimplemented";
break;
case gl::State::DIRTY_BIT_MULTISAMPLING:
WARN() << "DIRTY_BIT_MULTISAMPLING unimplemented";
break;
......
......@@ -526,6 +526,12 @@
1951 D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_with_and_without_instance_name = FAIL
1951 D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_block_array_size = FAIL
1951 D3D11 : dEQP-GLES31.functional.ssbo.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.num_work_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.work_group_size = FAIL
1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.work_group_id = FAIL
1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.local_invocation_id = FAIL
1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.global_invocation_id = FAIL
1442 D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.local_invocation_index = FAIL
// OPENGL Failing Tests
1665 WIN NVIDIA OPENGL : dEQP-GLES31.functional.draw_indirect.negative.command_offset_not_in_buffer_unsigned32_wrap = FAIL
......@@ -590,12 +596,6 @@
// OpenGL and D3D11 Failing Tests
1663 OPENGL D3D11 : dEQP-GLES31.functional.draw_indirect.compute_interop.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.num_work_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.work_group_size = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.work_group_id = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.local_invocation_id = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.global_invocation_id = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_var.compute.local_invocation_index = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.lowp_compute.scalar = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.lowp_compute.vec2 = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.add.lowp_compute.vec3 = FAIL
......
......@@ -189,6 +189,94 @@ TEST_P(ShaderStorageBufferTest31, AtomicMemoryFunctions)
EXPECT_GL_NO_ERROR();
}
// Test multiple storage buffers work correctly when program switching. In angle, storage buffer
// bindings are updated accord to current program. If switch program, need to update storage buffer
// bindings again.
TEST_P(ShaderStorageBufferTest31, MultiStorageBuffersForMultiPrograms)
{
const std::string &csSource1 =
R"(#version 310 es
layout(local_size_x=3, local_size_y=1, local_size_z=1) in;
layout(binding = 1) buffer Output {
uint result1[];
} sb_out1;
void main()
{
highp uint offset = gl_LocalInvocationID.x;
sb_out1.result1[gl_LocalInvocationIndex] = gl_LocalInvocationIndex + 1u;
})";
const std::string &csSource2 =
R"(#version 310 es
layout(local_size_x=3, local_size_y=1, local_size_z=1) in;
layout(binding = 2) buffer Output {
uint result2[];
} sb_out2;
void main()
{
highp uint offset = gl_LocalInvocationID.x;
sb_out2.result2[gl_LocalInvocationIndex] = gl_LocalInvocationIndex + 2u;
})";
constexpr unsigned int numInvocations = 3;
int arrayStride1 = 0, arrayStride2 = 0;
GLenum props[] = {GL_ARRAY_STRIDE};
GLBuffer shaderStorageBuffer1, shaderStorageBuffer2;
ANGLE_GL_COMPUTE_PROGRAM(program1, csSource1);
ANGLE_GL_COMPUTE_PROGRAM(program2, csSource2);
EXPECT_GL_NO_ERROR();
unsigned int outVarIndex1 =
glGetProgramResourceIndex(program1.get(), GL_BUFFER_VARIABLE, "Output.result1");
glGetProgramResourceiv(program1.get(), GL_BUFFER_VARIABLE, outVarIndex1, 1, props, 1, 0,
&arrayStride1);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer1);
glBufferData(GL_SHADER_STORAGE_BUFFER, numInvocations * arrayStride1, nullptr, GL_STREAM_READ);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer1);
EXPECT_GL_NO_ERROR();
unsigned int outVarIndex2 =
glGetProgramResourceIndex(program2.get(), GL_BUFFER_VARIABLE, "Output.result2");
glGetProgramResourceiv(program2.get(), GL_BUFFER_VARIABLE, outVarIndex2, 1, props, 1, 0,
&arrayStride2);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer2);
glBufferData(GL_SHADER_STORAGE_BUFFER, numInvocations * arrayStride2, nullptr, GL_STREAM_READ);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, shaderStorageBuffer2);
EXPECT_GL_NO_ERROR();
glUseProgram(program1.get());
glDispatchCompute(1, 1, 1);
EXPECT_GL_NO_ERROR();
glUseProgram(program2.get());
glDispatchCompute(1, 1, 1);
EXPECT_GL_NO_ERROR();
glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer1);
const void *ptr1 =
glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * arrayStride1, GL_MAP_READ_BIT);
for (unsigned int idx = 0; idx < numInvocations; idx++)
{
EXPECT_EQ(idx + 1, *((const GLuint *)((const GLbyte *)ptr1 + idx * arrayStride1)));
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
EXPECT_GL_NO_ERROR();
glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer2);
const void *ptr2 =
glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3 * arrayStride2, GL_MAP_READ_BIT);
EXPECT_GL_NO_ERROR();
for (unsigned int idx = 0; idx < numInvocations; idx++)
{
EXPECT_EQ(idx + 2, *((const GLuint *)((const GLbyte *)ptr2 + idx * arrayStride2)));
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
EXPECT_GL_NO_ERROR();
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
EXPECT_GL_NO_ERROR();
}
ANGLE_INSTANTIATE_TEST(ShaderStorageBufferTest31, ES31_OPENGL(), ES31_OPENGLES());
} // namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment