Commit ac6ff938 by Corentin Wallez Committed by Jamie Madill

Unset SRVs which resource are being bound to an RTV

This is the extension of a previously debug-only workaround for D3D doing the unsetting by itself (with a warning). It made our state tracking of the bound SRVs out of sync with D3D's and caused some rendering to not take place. BUG=427245 Change-Id: Id378030b64fddafbb3d406872a7dfd2c84793221 Reviewed-on: https://chromium-review.googlesource.com/229066Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 7e81c9d5
...@@ -503,6 +503,7 @@ inline unsigned int averageFloat10(unsigned int a, unsigned int b) ...@@ -503,6 +503,7 @@ inline unsigned int averageFloat10(unsigned int a, unsigned int b)
namespace rx namespace rx
{ {
// Represents intervals of the type [a, b)
template <typename T> template <typename T>
struct Range struct Range
{ {
...@@ -513,6 +514,18 @@ struct Range ...@@ -513,6 +514,18 @@ struct Range
T end; T end;
T length() const { return end - start; } T length() const { return end - start; }
bool intersects(Range<T> other)
{
if (start <= other.start)
{
return other.start < end;
}
else
{
return start < other.end;
}
}
}; };
typedef Range<int> RangeI; typedef Range<int> RangeI;
......
...@@ -83,6 +83,63 @@ enum ...@@ -83,6 +83,63 @@ enum
MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16 MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
}; };
static bool ImageIndexConflictsWithSRV(const gl::ImageIndex *index, D3D11_SHADER_RESOURCE_VIEW_DESC desc)
{
unsigned mipLevel = index->mipIndex;
unsigned layerIndex = index->layerIndex;
GLenum type = index->type;
switch (desc.ViewDimension)
{
case D3D11_SRV_DIMENSION_TEXTURE2D:
{
unsigned maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip;
maxSrvMip = (desc.Texture2D.MipLevels == -1) ? INT_MAX : maxSrvMip;
unsigned mipMin = index->mipIndex;
unsigned mipMax = (layerIndex == -1) ? INT_MAX : layerIndex;
return type == GL_TEXTURE_2D && RangeUI(mipMin, mipMax).intersects(RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip));
}
case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
{
unsigned maxSrvMip = desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip;
maxSrvMip = (desc.Texture2DArray.MipLevels == -1) ? INT_MAX : maxSrvMip;
unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize;
// Cube maps can be mapped to Texture2DArray SRVs
return (type == GL_TEXTURE_2D_ARRAY || gl::IsCubemapTextureTarget(type)) &&
desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip &&
desc.Texture2DArray.FirstArraySlice <= layerIndex && layerIndex < maxSlice;
}
case D3D11_SRV_DIMENSION_TEXTURECUBE:
{
unsigned maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip;
maxSrvMip = (desc.TextureCube.MipLevels == -1) ? INT_MAX : maxSrvMip;
return gl::IsCubemapTextureTarget(type) &&
desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
}
case D3D11_SRV_DIMENSION_TEXTURE3D:
{
unsigned maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip;
maxSrvMip = (desc.Texture3D.MipLevels == -1) ? INT_MAX : maxSrvMip;
return type == GL_TEXTURE_3D &&
desc.Texture3D.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
}
default:
// We only handle the cases corresponding to valid image indexes
UNIMPLEMENTED();
}
return false;
}
// Does *not* increment the resource ref count!! // Does *not* increment the resource ref count!!
ID3D11Resource *GetSRVResource(ID3D11ShaderResourceView *srv) ID3D11Resource *GetSRVResource(ID3D11ShaderResourceView *srv)
{ {
...@@ -849,15 +906,15 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) ...@@ -849,15 +906,15 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
return count >= minCount; return count >= minCount;
} }
void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11Resource *resource) void Renderer11::unsetConflictingSRVs(gl::SamplerType samplerType, const ID3D11Resource *resource, const gl::ImageIndex* index)
{ {
auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex) for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
{ {
ID3D11ShaderResourceView *srv = currentSRVs[resourceIndex]; auto &record = currentSRVs[resourceIndex];
if (srv && GetSRVResource(srv) == resource) if (record.srv && record.resource == resource && ImageIndexConflictsWithSRV(index, record.desc))
{ {
setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL); setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL);
} }
...@@ -915,12 +972,18 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer) ...@@ -915,12 +972,18 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
missingColorRenderTarget = false; missingColorRenderTarget = false;
} }
#if !defined(NDEBUG)
// Unbind render target SRVs from the shader here to prevent D3D11 warnings. // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
ID3D11Resource *renderTargetResource = renderTarget->getTexture(); if (colorbuffer->isTexture())
unsetSRVsWithResource(gl::SAMPLER_VERTEX, renderTargetResource); {
unsetSRVsWithResource(gl::SAMPLER_PIXEL, renderTargetResource); ID3D11Resource *renderTargetResource = renderTarget->getTexture();
#endif const gl::ImageIndex *index = colorbuffer->getTextureImageIndex();
ASSERT(index);
// The index doesn't need to be corrected for the small compressed texture workaround
// because a rendertarget is never compressed.
unsetConflictingSRVs(gl::SAMPLER_VERTEX, renderTargetResource, index);
unsetConflictingSRVs(gl::SAMPLER_PIXEL, renderTargetResource, index);
}
} }
} }
...@@ -1673,6 +1736,12 @@ void Renderer11::markAllStateDirty() ...@@ -1673,6 +1736,12 @@ void Renderer11::markAllStateDirty()
mDepthStencilInitialized = false; mDepthStencilInitialized = false;
mRenderTargetDescInitialized = false; mRenderTargetDescInitialized = false;
// We reset the current SRV data because it might not be in sync with D3D's state
// anymore. For example when a currently used SRV is used as an RTV, D3D silently
// remove it from its state.
memset(mCurVertexSRVs.data(), 0, sizeof(SRVRecord) * mCurVertexSRVs.size());
memset(mCurPixelSRVs.data(), 0, sizeof(SRVRecord) * mCurPixelSRVs.size());
ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size()); ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size());
for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId) for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId)
{ {
...@@ -2180,6 +2249,7 @@ void Renderer11::unapplyRenderTargets() ...@@ -2180,6 +2249,7 @@ void Renderer11::unapplyRenderTargets()
setOneTimeRenderTarget(NULL); setOneTimeRenderTarget(NULL);
} }
// When finished with this rendertarget, markAllStateDirty must be called.
void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView) void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView)
{ {
ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
...@@ -3334,8 +3404,9 @@ void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot ...@@ -3334,8 +3404,9 @@ void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot
auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size()); ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
auto &record = currentSRVs[resourceSlot];
if (currentSRVs[resourceSlot] != srv) if (record.srv != srv)
{ {
if (shaderType == gl::SAMPLER_VERTEX) if (shaderType == gl::SAMPLER_VERTEX)
{ {
...@@ -3346,7 +3417,12 @@ void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot ...@@ -3346,7 +3417,12 @@ void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot
mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv); mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv);
} }
currentSRVs[resourceSlot] = srv; record.srv = srv;
if (srv)
{
srv->GetResource(&record.resource);
srv->GetDesc(&record.desc);
}
} }
} }
} }
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
namespace gl namespace gl
{ {
class FramebufferAttachment; class FramebufferAttachment;
struct ImageIndex;
} }
namespace rx namespace rx
...@@ -225,7 +226,7 @@ class Renderer11 : public RendererD3D ...@@ -225,7 +226,7 @@ class Renderer11 : public RendererD3D
RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
bool colorBlit, bool depthBlit, bool stencilBlit); bool colorBlit, bool depthBlit, bool stencilBlit);
ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
void unsetSRVsWithResource(gl::SamplerType shaderType, const ID3D11Resource *resource); void unsetConflictingSRVs(gl::SamplerType shaderType, const ID3D11Resource *resource, const gl::ImageIndex *index);
static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel); static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel);
static void invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer); static void invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer);
...@@ -263,8 +264,14 @@ class Renderer11 : public RendererD3D ...@@ -263,8 +264,14 @@ class Renderer11 : public RendererD3D
std::vector<gl::SamplerState> mCurPixelSamplerStates; std::vector<gl::SamplerState> mCurPixelSamplerStates;
// Currently applied textures // Currently applied textures
std::vector<ID3D11ShaderResourceView*> mCurVertexSRVs; struct SRVRecord
std::vector<ID3D11ShaderResourceView*> mCurPixelSRVs; {
ID3D11ShaderResourceView *srv;
ID3D11Resource *resource;
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
};
std::vector<SRVRecord> mCurVertexSRVs;
std::vector<SRVRecord> mCurPixelSRVs;
// Currently applied blend state // Currently applied blend state
bool mForceSetBlendState; bool mForceSetBlendState;
......
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