Commit 95277a30 by jchen10 Committed by Commit Bot

ES31: Add DispatchComputeIndirect support for D3D11

BUG=angleproject:2270 TEST=angle_end2end_tests.ComputeShaderTest.DispatchComputeIndirect/ES3_1_D3D11 Change-Id: I29bd888ce1e7e3e09b5635699a36164cd97cd7de Reviewed-on: https://chromium-review.googlesource.com/1209563Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jie A Chen <jie.a.chen@intel.com>
parent 89652a35
...@@ -482,8 +482,7 @@ gl::Error Context11::dispatchCompute(const gl::Context *context, ...@@ -482,8 +482,7 @@ gl::Error Context11::dispatchCompute(const gl::Context *context,
gl::Error Context11::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) gl::Error Context11::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
{ {
UNIMPLEMENTED(); return mRenderer->dispatchComputeIndirect(context, indirect);
return gl::InternalError();
} }
angle::Result Context11::triggerDrawCallProgramRecompilation(const gl::Context *context, angle::Result Context11::triggerDrawCallProgramRecompilation(const gl::Context *context,
......
...@@ -3692,6 +3692,30 @@ angle::Result Renderer11::dispatchCompute(const gl::Context *context, ...@@ -3692,6 +3692,30 @@ angle::Result Renderer11::dispatchCompute(const gl::Context *context,
return angle::Result::Continue(); return angle::Result::Continue();
} }
angle::Result Renderer11::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
{
const auto &glState = context->getGLState();
auto *dispatchIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DispatchIndirect);
ASSERT(dispatchIndirectBuffer);
Buffer11 *storage = GetImplAs<Buffer11>(dispatchIndirectBuffer);
const uint8_t *bufferData = nullptr;
// TODO(jie.a.chen@intel.com): num_groups_x,y,z have to be written into the driver constant
// buffer for the built-in variable gl_NumWorkGroups. There is an opportunity for optimization
// to use GPU->GPU copy instead.
// https://bugs.chromium.org/p/angleproject/issues/detail?id=2807
ANGLE_TRY(storage->getData(context, &bufferData));
const GLuint *groups = reinterpret_cast<const GLuint *>(bufferData + indirect);
ANGLE_TRY(mStateManager.updateStateForCompute(context, groups[0], groups[1], groups[2]));
ANGLE_TRY(applyComputeShader(context));
ID3D11Buffer *buffer = nullptr;
ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDIRECT, &buffer));
mDeviceContext->DispatchIndirect(buffer, static_cast<UINT>(indirect));
return angle::Result::Continue();
}
angle::Result Renderer11::createStagingTexture(const gl::Context *context, angle::Result Renderer11::createStagingTexture(const gl::Context *context,
ResourceType textureType, ResourceType textureType,
......
...@@ -417,6 +417,7 @@ class Renderer11 : public RendererD3D ...@@ -417,6 +417,7 @@ class Renderer11 : public RendererD3D
GLuint numGroupsX, GLuint numGroupsX,
GLuint numGroupsY, GLuint numGroupsY,
GLuint numGroupsZ); GLuint numGroupsZ);
angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect);
angle::Result applyComputeShader(const gl::Context *context); angle::Result applyComputeShader(const gl::Context *context);
angle::Result createStagingTexture(const gl::Context *context, angle::Result createStagingTexture(const gl::Context *context,
......
...@@ -395,6 +395,62 @@ TEST_P(ComputeShaderTest, DispatchCompute) ...@@ -395,6 +395,62 @@ TEST_P(ComputeShaderTest, DispatchCompute)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Basic test for DispatchComputeIndirect.
TEST_P(ComputeShaderTest, DispatchComputeIndirect)
{
GLTexture texture;
GLFramebuffer framebuffer;
const char kCSSource[] =
R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(r32ui, binding = 0) uniform highp uimage2D uImage;
void main()
{
imageStore(uImage, ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y), uvec4(100, 0, 0, 0));
})";
ANGLE_GL_COMPUTE_PROGRAM(program, kCSSource);
glUseProgram(program.get());
const int kWidth = 4, kHeight = 6;
GLuint inputValues[] = {0};
GLBuffer buffer;
glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer);
GLuint params[] = {kWidth, kHeight, 1};
glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(params), params, GL_STATIC_DRAW);
glBindTexture(GL_TEXTURE_2D, texture);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
inputValues);
EXPECT_GL_NO_ERROR();
glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
EXPECT_GL_NO_ERROR();
glDispatchComputeIndirect(0);
EXPECT_GL_NO_ERROR();
glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
glUseProgram(0);
GLuint outputValues[kWidth][kHeight];
GLuint expectedValue = 100u;
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_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
EXPECT_GL_NO_ERROR();
for (int i = 0; i < kWidth; i++)
{
for (int j = 0; j < kHeight; j++)
{
EXPECT_EQ(expectedValue, outputValues[i][j]);
}
}
}
// Use image uniform to write texture in compute shader, and verify the content is expected. // Use image uniform to write texture in compute shader, and verify the content is expected.
TEST_P(ComputeShaderTest, BindImageTexture) TEST_P(ComputeShaderTest, BindImageTexture)
{ {
......
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