Commit 913ff54d by Xinghua Cao Committed by Commit Bot

ES31: support compute shader uniform buffer on D3D backend

BUG=angleproject:2759 TEST=angle_end2end_tests.ComputeShaderTest.UniformBuffer/ES3_1_D3D11 Change-Id: I92326c3a84f13b364aed0daf567b68f8a411ed2b Reviewed-on: https://chromium-review.googlesource.com/1164843Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJiajia Qin <jiajia.qin@intel.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Xinghua Cao <xinghua.cao@intel.com>
parent 3e29cf31
...@@ -33,6 +33,7 @@ enum ...@@ -33,6 +33,7 @@ enum
IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS = 16, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS = 16,
IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS = 16, IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS = 16,
IMPLEMENTATION_MAX_COMPUTE_SHADER_UNIFORM_BUFFERS = 16,
IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS = IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS =
IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS + IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS +
IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS, IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS,
......
...@@ -725,7 +725,8 @@ angle::Result StateManager11::updateStateForCompute(const gl::Context *context, ...@@ -725,7 +725,8 @@ angle::Result StateManager11::updateStateForCompute(const gl::Context *context,
// TODO(jmadill): More complete implementation. // TODO(jmadill): More complete implementation.
ANGLE_TRY(syncTexturesForCompute(context)); ANGLE_TRY(syncTexturesForCompute(context));
// TODO(Xinghua): applyUniformBuffers for compute shader. // TODO(Xinghua): Use dirty bits.
ANGLE_TRY(syncUniformBuffers(context));
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -3333,6 +3334,33 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con ...@@ -3333,6 +3334,33 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con
break; break;
} }
case gl::ShaderType::Compute:
{
if (mCurrentConstantBufferCS[bufferIndex] == constantBuffer->getSerial() &&
mCurrentConstantBufferCSOffset[bufferIndex] == uniformBufferOffset &&
mCurrentConstantBufferCSSize[bufferIndex] == uniformBufferSize)
{
continue;
}
if (firstConstant != 0 && uniformBufferSize != 0)
{
deviceContext1->CSSetConstantBuffers1(appliedIndex, 1,
constantBuffer->getPointer(),
&firstConstant, &numConstants);
}
else
{
deviceContext->CSSetConstantBuffers(appliedIndex, 1,
constantBuffer->getPointer());
}
mCurrentConstantBufferCS[appliedIndex] = constantBuffer->getSerial();
mCurrentConstantBufferCSOffset[appliedIndex] = uniformBufferOffset;
mCurrentConstantBufferCSSize[appliedIndex] = uniformBufferSize;
break;
}
// TODO(jiawei.shao@intel.com): update geometry shader uniform buffers. // TODO(jiawei.shao@intel.com): update geometry shader uniform buffers.
case gl::ShaderType::Geometry: case gl::ShaderType::Geometry:
UNIMPLEMENTED(); UNIMPLEMENTED();
...@@ -3351,11 +3379,18 @@ angle::Result StateManager11::syncUniformBuffers(const gl::Context *context) ...@@ -3351,11 +3379,18 @@ angle::Result StateManager11::syncUniformBuffers(const gl::Context *context)
gl::ShaderMap<unsigned int> shaderReservedUBOs = mRenderer->getReservedShaderUniformBuffers(); gl::ShaderMap<unsigned int> shaderReservedUBOs = mRenderer->getReservedShaderUniformBuffers();
mProgramD3D->updateUniformBufferCache(context->getCaps(), shaderReservedUBOs); mProgramD3D->updateUniformBufferCache(context->getCaps(), shaderReservedUBOs);
ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Vertex)); if (mProgramD3D->hasShaderStage(gl::ShaderType::Compute))
ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Fragment)); {
if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry)) ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Compute));
}
else
{ {
ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Geometry)); ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Vertex));
ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Fragment));
if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry))
{
ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Geometry));
}
} }
return angle::Result::Continue(); return angle::Result::Continue();
......
...@@ -549,6 +549,14 @@ class StateManager11 final : angle::NonCopyable ...@@ -549,6 +549,14 @@ class StateManager11 final : angle::NonCopyable
FragmentConstantBufferArray<GLintptr> mCurrentConstantBufferPSOffset; FragmentConstantBufferArray<GLintptr> mCurrentConstantBufferPSOffset;
FragmentConstantBufferArray<GLsizeiptr> mCurrentConstantBufferPSSize; FragmentConstantBufferArray<GLsizeiptr> mCurrentConstantBufferPSSize;
template <typename T>
using ComputeConstantBufferArray =
std::array<T, gl::IMPLEMENTATION_MAX_COMPUTE_SHADER_UNIFORM_BUFFERS>;
ComputeConstantBufferArray<ResourceSerial> mCurrentConstantBufferCS;
ComputeConstantBufferArray<GLintptr> mCurrentConstantBufferCSOffset;
ComputeConstantBufferArray<GLsizeiptr> mCurrentConstantBufferCSSize;
// Currently applied transform feedback buffers // Currently applied transform feedback buffers
Serial mAppliedTFSerial; Serial mAppliedTFSerial;
......
...@@ -1625,6 +1625,68 @@ TEST_P(ComputeShaderTest, AtomicFunctionsInNonInitializerSingleAssignment) ...@@ -1625,6 +1625,68 @@ TEST_P(ComputeShaderTest, AtomicFunctionsInNonInitializerSingleAssignment)
runSharedMemoryTest<GLint, 9, 1>(kCSShader, GL_R32I, GL_INT, inputData, expectedValues); runSharedMemoryTest<GLint, 9, 1>(kCSShader, GL_R32I, GL_INT, inputData, expectedValues);
} }
// Basic uniform buffer functionality.
TEST_P(ComputeShaderTest, UniformBuffer)
{
GLTexture texture;
GLBuffer buffer;
GLFramebuffer framebuffer;
const std::string csSource =
R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
uniform uni
{
uvec4 value;
};
layout(rgba32ui, binding = 0) writeonly uniform highp uimage2D uImage;
void main()
{
imageStore(uImage, ivec2(gl_LocalInvocationID.xy), value);
})";
constexpr int kWidth = 1, kHeight = 1;
constexpr GLuint kInputValues[4] = {56, 57, 58, 59};
glBindTexture(GL_TEXTURE_2D, texture);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, kWidth, kHeight);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
kInputValues);
EXPECT_GL_NO_ERROR();
ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
glUseProgram(program.get());
GLint uniformBufferIndex = glGetUniformBlockIndex(program, "uni");
EXPECT_NE(uniformBufferIndex, -1);
GLuint data[4] = {201, 202, 203, 204};
glBindBuffer(GL_UNIFORM_BUFFER, buffer);
glBufferData(GL_UNIFORM_BUFFER, sizeof(GLuint) * 4, data, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
glUniformBlockBinding(program, uniformBufferIndex, 0);
EXPECT_GL_NO_ERROR();
glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI);
EXPECT_GL_NO_ERROR();
glDispatchCompute(1, 1, 1);
EXPECT_GL_NO_ERROR();
glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
GLuint outputValues[kWidth * kHeight * 4];
glUseProgram(0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
EXPECT_GL_NO_ERROR();
glReadPixels(0, 0, kWidth, kHeight, GL_RGBA_INTEGER, GL_UNSIGNED_INT, outputValues);
EXPECT_GL_NO_ERROR();
for (int i = 0; i < kWidth * kHeight * 4; i++)
{
EXPECT_EQ(data[i], outputValues[i]);
}
}
// Check that it is not possible to create a compute shader when the context does not support ES // Check that it is not possible to create a compute shader when the context does not support ES
// 3.10 // 3.10
TEST_P(ComputeShaderTestES3, NotSupported) TEST_P(ComputeShaderTestES3, NotSupported)
......
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