Commit e7da32f1 by Qin Jiajia Committed by Commit Bot

Fix the failure in UpdateImageTextureInUse

If we update the texture data between two dispatch calls, ReadPixels can't get right result after the second dispatch call. The failure reason is that after the first dispatch, ReadPixels will sync framebufer state which will update color render target. Finally, TextureD3D::ensureRenderTarget is reached. However, we are in compute pipeline. mTexStorage->isRenderTarget() will be false. That results the current texture will create a new render target storage. But the UAV is still bound with the previous texture storage. If there is no texture dirty bit between these two dispatch calls, applyTexturesForCompute won't be called. After the second dispatch, readPixels will read data from the new texture storage which is not updated. Bug: angleproject:3015 Change-Id: Ib2494ab8bf6e12faefc0a7370719d383526c36ba Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1390710Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jiajia Qin <jiajia.qin@intel.com>
parent ccd91316
...@@ -569,6 +569,9 @@ angle::Result TextureD3D::ensureRenderTarget(const gl::Context *context) ...@@ -569,6 +569,9 @@ angle::Result TextureD3D::ensureRenderTarget(const gl::Context *context)
ANGLE_TRY(mTexStorage->copyToStorage(context, newRenderTargetStorage.get())); ANGLE_TRY(mTexStorage->copyToStorage(context, newRenderTargetStorage.get()));
ANGLE_TRY(setCompleteTexStorage(context, newRenderTargetStorage.get())); ANGLE_TRY(setCompleteTexStorage(context, newRenderTargetStorage.get()));
newRenderTargetStorage.release(); newRenderTargetStorage.release();
// If this texture is used in compute shader, we should invalidate this texture so that
// the UAV/SRV is rebound again with this new texture storage in next dispatch call.
mTexStorage->invalidateTextures();
} }
} }
......
...@@ -70,6 +70,8 @@ class TextureStorage : angle::NonCopyable ...@@ -70,6 +70,8 @@ class TextureStorage : angle::NonCopyable
virtual angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context, virtual angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
bool useLevelZeroTexture); bool useLevelZeroTexture);
virtual void invalidateTextures() {}
protected: protected:
const angle::Subject *mSubject; const angle::Subject *mSubject;
}; };
......
...@@ -217,6 +217,9 @@ class StateManager11 final : angle::NonCopyable ...@@ -217,6 +217,9 @@ class StateManager11 final : angle::NonCopyable
// Called by VertexArray11 element array buffer sync. // Called by VertexArray11 element array buffer sync.
void invalidateIndexBuffer(); void invalidateIndexBuffer();
// Called by TextureStorage11. Also called internally.
void invalidateTexturesAndSamplers();
void setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv); void setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv);
void setRenderTargets(ID3D11RenderTargetView **rtvs, UINT numRtvs, ID3D11DepthStencilView *dsv); void setRenderTargets(ID3D11RenderTargetView **rtvs, UINT numRtvs, ID3D11DepthStencilView *dsv);
...@@ -376,7 +379,6 @@ class StateManager11 final : angle::NonCopyable ...@@ -376,7 +379,6 @@ class StateManager11 final : angle::NonCopyable
angle::Result syncTransformFeedbackBuffers(const gl::Context *context); angle::Result syncTransformFeedbackBuffers(const gl::Context *context);
// These are currently only called internally. // These are currently only called internally.
void invalidateTexturesAndSamplers();
void invalidateDriverUniforms(); void invalidateDriverUniforms();
void invalidateProgramUniforms(); void invalidateProgramUniforms();
void invalidateConstantBuffer(unsigned int slot); void invalidateConstantBuffer(unsigned int slot);
......
...@@ -702,6 +702,11 @@ angle::Result TextureStorage11::copyToStorage(const gl::Context *context, ...@@ -702,6 +702,11 @@ angle::Result TextureStorage11::copyToStorage(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
void TextureStorage11::invalidateTextures()
{
mRenderer->getStateManager()->invalidateTexturesAndSamplers();
}
angle::Result TextureStorage11::setData(const gl::Context *context, angle::Result TextureStorage11::setData(const gl::Context *context,
const gl::ImageIndex &index, const gl::ImageIndex &index,
ImageD3D *image, ImageD3D *image,
......
...@@ -92,6 +92,7 @@ class TextureStorage11 : public TextureStorage ...@@ -92,6 +92,7 @@ class TextureStorage11 : public TextureStorage
GLenum type, GLenum type,
const gl::PixelUnpackState &unpack, const gl::PixelUnpackState &unpack,
const uint8_t *pixelData) override; const uint8_t *pixelData) override;
void invalidateTextures() override;
virtual angle::Result getSRVForSampler(const gl::Context *context, virtual angle::Result getSRVForSampler(const gl::Context *context,
const gl::TextureState &textureState, const gl::TextureState &textureState,
......
...@@ -2465,7 +2465,6 @@ TEST_P(SimpleStateChangeTestES31, UpdateImageTextureInUse) ...@@ -2465,7 +2465,6 @@ TEST_P(SimpleStateChangeTestES31, UpdateImageTextureInUse)
glDispatchCompute(1, 1, 1); glDispatchCompute(1, 1, 1);
// Update the texture to be YBGR, while the Texture is in-use. Should not affect the dispatch. // Update the texture to be YBGR, while the Texture is in-use. Should not affect the dispatch.
glBindTexture(GL_TEXTURE_2D, texRead);
std::array<GLColor, 4> ybgr = {{GLColor::yellow, GLColor::blue, GLColor::green, GLColor::red}}; std::array<GLColor, 4> ybgr = {{GLColor::yellow, GLColor::blue, GLColor::green, GLColor::red}};
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, ybgr.data()); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, ybgr.data());
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
......
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