Commit 96682377 by Qin Jiajia Committed by Commit Bot

Fix the RTV and SRV conflict

This change fixes below error: Message 0: ID3D11DeviceContext::CSSetShaderResources: Resource being set to CS shader resource slot 0 is still bound on output! Forcing to NULL. Bug: angleproject:3658 Change-Id: I72d656cf61ffb7c39660c019eab980c39eafb70f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1688307Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jiajia Qin <jiajia.qin@intel.com>
parent cdab03aa
...@@ -794,8 +794,15 @@ void StateManager11::setShaderResourceInternal(gl::ShaderType shaderType, ...@@ -794,8 +794,15 @@ void StateManager11::setShaderResourceInternal(gl::ShaderType shaderType,
deviceContext->PSSetShaderResources(resourceSlot, 1, &srvPtr); deviceContext->PSSetShaderResources(resourceSlot, 1, &srvPtr);
break; break;
case gl::ShaderType::Compute: case gl::ShaderType::Compute:
{
if (srvPtr)
{
uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(srvPtr));
unsetConflictingRTVs(resource);
}
deviceContext->CSSetShaderResources(resourceSlot, 1, &srvPtr); deviceContext->CSSetShaderResources(resourceSlot, 1, &srvPtr);
break; break;
}
default: default:
UNREACHABLE(); UNREACHABLE();
} }
...@@ -1722,6 +1729,8 @@ void StateManager11::setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthSte ...@@ -1722,6 +1729,8 @@ void StateManager11::setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthSte
} }
mRenderer->getDeviceContext()->OMSetRenderTargets(1, &rtv, dsv); mRenderer->getDeviceContext()->OMSetRenderTargets(1, &rtv, dsv);
mCurRTVs.clear();
mCurRTVs.update(0, rtv);
mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET); mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
} }
...@@ -1740,6 +1749,11 @@ void StateManager11::setRenderTargets(ID3D11RenderTargetView **rtvs, ...@@ -1740,6 +1749,11 @@ void StateManager11::setRenderTargets(ID3D11RenderTargetView **rtvs,
} }
mRenderer->getDeviceContext()->OMSetRenderTargets(numRTVs, (numRTVs > 0) ? rtvs : nullptr, dsv); mRenderer->getDeviceContext()->OMSetRenderTargets(numRTVs, (numRTVs > 0) ? rtvs : nullptr, dsv);
mCurRTVs.clear();
for (UINT i = 0; i < numRTVs; i++)
{
mCurRTVs.update(i, rtvs[i]);
}
mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET); mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
} }
...@@ -1866,6 +1880,24 @@ void StateManager11::unsetConflictingUAVs(gl::PipelineType pipeline, ...@@ -1866,6 +1880,24 @@ void StateManager11::unsetConflictingUAVs(gl::PipelineType pipeline,
} }
} }
void StateManager11::unsetConflictingRTVs(uintptr_t resource)
{
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
size_t count = std::min(mCurRTVs.size(), mCurRTVs.highestUsed());
for (size_t resourceIndex = 0; resourceIndex < count; ++resourceIndex)
{
auto &record = mCurRTVs[resourceIndex];
if (record.view && record.resource == resource)
{
deviceContext->OMSetRenderTargets(0, nullptr, nullptr);
mCurRTVs.clear();
mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
return;
}
}
}
void StateManager11::unsetConflictingAttachmentResources( void StateManager11::unsetConflictingAttachmentResources(
const gl::FramebufferAttachment &attachment, const gl::FramebufferAttachment &attachment,
ID3D11Resource *resource) ID3D11Resource *resource)
...@@ -1915,7 +1947,7 @@ angle::Result StateManager11::ensureInitialized(const gl::Context *context) ...@@ -1915,7 +1947,7 @@ angle::Result StateManager11::ensureInitialized(const gl::Context *context)
mForceSetShaderSamplerStates[shaderType].resize(maxShaderTextureImageUnits, true); mForceSetShaderSamplerStates[shaderType].resize(maxShaderTextureImageUnits, true);
mCurShaderSamplerStates[shaderType].resize(maxShaderTextureImageUnits); mCurShaderSamplerStates[shaderType].resize(maxShaderTextureImageUnits);
} }
mCurRTVs.initialize(caps.maxColorAttachments);
mCurComputeUAVs.initialize(caps.maxImageUnits); mCurComputeUAVs.initialize(caps.maxImageUnits);
// Initialize cached NULL SRV block // Initialize cached NULL SRV block
...@@ -2026,7 +2058,11 @@ angle::Result StateManager11::syncFramebuffer(const gl::Context *context) ...@@ -2026,7 +2058,11 @@ angle::Result StateManager11::syncFramebuffer(const gl::Context *context)
// Apply the render target and depth stencil // Apply the render target and depth stencil
mRenderer->getDeviceContext()->OMSetRenderTargets(maxExistingRT, framebufferRTVs.data(), mRenderer->getDeviceContext()->OMSetRenderTargets(maxExistingRT, framebufferRTVs.data(),
framebufferDSV); framebufferDSV);
mCurRTVs.clear();
for (UINT i = 0; i < maxExistingRT; i++)
{
mCurRTVs.update(i, framebufferRTVs[i]);
}
return angle::Result::Continue; return angle::Result::Continue;
} }
......
...@@ -307,6 +307,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -307,6 +307,7 @@ class StateManager11 final : angle::NonCopyable
gl::ShaderType shaderType, gl::ShaderType shaderType,
uintptr_t resource, uintptr_t resource,
const gl::ImageIndex *index); const gl::ImageIndex *index);
void unsetConflictingRTVs(uintptr_t resource);
void unsetConflictingAttachmentResources(const gl::FramebufferAttachment &attachment, void unsetConflictingAttachmentResources(const gl::FramebufferAttachment &attachment,
ID3D11Resource *resource); ID3D11Resource *resource);
...@@ -535,8 +536,11 @@ class StateManager11 final : angle::NonCopyable ...@@ -535,8 +536,11 @@ class StateManager11 final : angle::NonCopyable
using SRVCache = ViewCache<ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC>; using SRVCache = ViewCache<ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC>;
using UAVCache = ViewCache<ID3D11UnorderedAccessView, D3D11_UNORDERED_ACCESS_VIEW_DESC>; using UAVCache = ViewCache<ID3D11UnorderedAccessView, D3D11_UNORDERED_ACCESS_VIEW_DESC>;
using RTVCache = ViewCache<ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC>;
gl::ShaderMap<SRVCache> mCurShaderSRVs; gl::ShaderMap<SRVCache> mCurShaderSRVs;
UAVCache mCurComputeUAVs; UAVCache mCurComputeUAVs;
RTVCache mCurRTVs;
SRVCache *getSRVCache(gl::ShaderType shaderType); SRVCache *getSRVCache(gl::ShaderType shaderType);
// A block of NULL pointers, cached so we don't re-allocate every draw call // A block of NULL pointers, cached so we don't re-allocate every draw call
......
...@@ -2962,6 +2962,107 @@ void main() ...@@ -2962,6 +2962,107 @@ void main()
EXPECT_EQ(expectedValue, outputValues); EXPECT_EQ(expectedValue, outputValues);
} }
// Test that a resource is bound on render pipeline output, and then it's bound as the compute
// pipeline input. It works well. See http://anglebug.com/3658
TEST_P(ComputeShaderTest, DrawTexture1DispatchTexture2)
{
const char kCSSource[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
precision highp sampler2D;
uniform sampler2D tex;
layout(rgba32f, binding = 0) writeonly uniform highp image2D image;
void main()
{
vec4 value = texelFetch(tex, ivec2(gl_LocalInvocationID.xy), 0);
imageStore(image, ivec2(gl_LocalInvocationID.xy), vec4(value.x - 1.0, 1.0, 0.0, value.w - 1.0));
})";
const char kVSSource[] = R"(#version 310 es
layout (location = 0) in vec2 pos;
out vec2 texCoord;
void main(void) {
texCoord = 0.5*pos + 0.5;
gl_Position = vec4(pos, 0.0, 1.0);
})";
const char kFSSource[] = R"(#version 310 es
precision highp float;
uniform sampler2D tex;
in vec2 texCoord;
out vec4 fragColor;
void main(void) {
fragColor = texture(tex, texCoord);
})";
GLuint aPosLoc = 0;
ANGLE_GL_PROGRAM(program, kVSSource, kFSSource);
ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
glBindAttribLocation(program, aPosLoc, "pos");
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
GLfloat vertices[] = {-1, -1, 1, -1, -1, 1, 1, 1};
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(aPosLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(aPosLoc);
constexpr GLfloat kInputValues[4] = {1.0, 0.0, 0.0, 1.0};
constexpr GLfloat kZero[4] = {0.0, 0.0, 0.0, 0.0};
GLFramebuffer framebuffer;
GLTexture texture[3];
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, kInputValues);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, kZero);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, kZero);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glUniform1i(glGetUniformLocation(program, "tex"), 0);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
GLfloat actual[4];
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, actual);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(1.0, actual[0]);
EXPECT_EQ(0.0, actual[1]);
EXPECT_EQ(0.0, actual[2]);
EXPECT_EQ(1.0, actual[3]);
glUseProgram(csProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glUniform1i(glGetUniformLocation(program, "tex"), 0);
glBindImageTexture(0, texture[2], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
glDispatchCompute(1, 1, 1);
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[2], 0);
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, actual);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(0.0, actual[0]);
EXPECT_EQ(1.0, actual[1]);
EXPECT_EQ(0.0, actual[2]);
EXPECT_EQ(0.0, actual[3]);
}
// Test that render pipeline and compute pipeline access to the same texture. // Test that render pipeline and compute pipeline access to the same texture.
// Steps: // Steps:
// 1. DispatchCompute. // 1. DispatchCompute.
......
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