Commit 39eab03f by Jamie Madill

Add robust D3D11 SRV state tracking.

This will ensure our currently set pixel and vertex SRVs match with the underlying D3D state, and reduce the need for resetting them as often. BUG=angle:756 BUG=417424 Change-Id: I42e9e25182b279871ac4cdf8da5e2ab62c8cf71f Reviewed-on: https://chromium-review.googlesource.com/225052Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarBrandon Jones <bajones@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 2f1cd4a3
...@@ -465,8 +465,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT ...@@ -465,8 +465,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0); deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0);
// Unset the currently bound shader resource to avoid conflicts // Unset the currently bound shader resource to avoid conflicts
ID3D11ShaderResourceView *const nullSRV = NULL; mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
deviceContext->PSSetShaderResources(0, 1, &nullSRV);
// Apply render target // Apply render target
mRenderer->setOneTimeRenderTarget(dest); mRenderer->setOneTimeRenderTarget(dest);
...@@ -482,7 +481,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT ...@@ -482,7 +481,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
deviceContext->RSSetViewports(1, &viewport); deviceContext->RSSetViewports(1, &viewport);
// Apply textures // Apply textures
deviceContext->PSSetShaderResources(0, 1, &source); mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers // Apply samplers
deviceContext->PSSetSamplers(0, 1, &mPointSampler); deviceContext->PSSetSamplers(0, 1, &mPointSampler);
...@@ -491,7 +490,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT ...@@ -491,7 +490,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
deviceContext->Draw(drawCount, 0); deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer // Unbind textures and render targets and vertex buffer
deviceContext->PSSetShaderResources(0, 1, &nullSRV); mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets(); mRenderer->unapplyRenderTargets();
...@@ -583,8 +582,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s ...@@ -583,8 +582,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s
deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0); deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0);
// Unset the currently bound shader resource to avoid conflicts // Unset the currently bound shader resource to avoid conflicts
ID3D11ShaderResourceView *const nullSRV = NULL; mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
deviceContext->PSSetShaderResources(0, 1, &nullSRV);
// Apply render target // Apply render target
mRenderer->setOneTimeRenderTarget(dest); mRenderer->setOneTimeRenderTarget(dest);
...@@ -600,7 +598,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s ...@@ -600,7 +598,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s
deviceContext->RSSetViewports(1, &viewport); deviceContext->RSSetViewports(1, &viewport);
// Apply textures // Apply textures
deviceContext->PSSetShaderResources(0, 1, &source); mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers // Apply samplers
ID3D11SamplerState *sampler = NULL; ID3D11SamplerState *sampler = NULL;
...@@ -619,7 +617,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s ...@@ -619,7 +617,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s
deviceContext->Draw(drawCount, 0); deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer // Unbind textures and render targets and vertex buffer
deviceContext->PSSetShaderResources(0, 1, &nullSRV); mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets(); mRenderer->unapplyRenderTargets();
...@@ -698,8 +696,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou ...@@ -698,8 +696,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
deviceContext->GSSetShader(NULL, NULL, 0); deviceContext->GSSetShader(NULL, NULL, 0);
// Unset the currently bound shader resource to avoid conflicts // Unset the currently bound shader resource to avoid conflicts
ID3D11ShaderResourceView *const nullSRV = NULL; mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
deviceContext->PSSetShaderResources(0, 1, &nullSRV);
// Apply render target // Apply render target
deviceContext->OMSetRenderTargets(0, NULL, dest); deviceContext->OMSetRenderTargets(0, NULL, dest);
...@@ -715,7 +712,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou ...@@ -715,7 +712,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
deviceContext->RSSetViewports(1, &viewport); deviceContext->RSSetViewports(1, &viewport);
// Apply textures // Apply textures
deviceContext->PSSetShaderResources(0, 1, &source); mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers // Apply samplers
deviceContext->PSSetSamplers(0, 1, &mPointSampler); deviceContext->PSSetSamplers(0, 1, &mPointSampler);
...@@ -724,7 +721,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou ...@@ -724,7 +721,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
deviceContext->Draw(drawCount, 0); deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer // Unbind textures and render targets and vertex buffer
deviceContext->PSSetShaderResources(0, 1, &nullSRV); mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets(); mRenderer->unapplyRenderTargets();
......
...@@ -216,7 +216,6 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac ...@@ -216,7 +216,6 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
ID3D11ShaderResourceView *nullSRV = NULL;
ID3D11Buffer *nullBuffer = NULL; ID3D11Buffer *nullBuffer = NULL;
UINT zero = 0; UINT zero = 0;
...@@ -226,7 +225,7 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac ...@@ -226,7 +225,7 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0); deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0);
deviceContext->GSSetShader(geometryShader, NULL, 0); deviceContext->GSSetShader(geometryShader, NULL, 0);
deviceContext->PSSetShader(pixelShader, NULL, 0); deviceContext->PSSetShader(pixelShader, NULL, 0);
deviceContext->PSSetShaderResources(0, 1, &bufferSRV); mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV);
deviceContext->IASetInputLayout(NULL); deviceContext->IASetInputLayout(NULL);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
...@@ -259,7 +258,7 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac ...@@ -259,7 +258,7 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
deviceContext->Draw(numPixels, 0); deviceContext->Draw(numPixels, 0);
// Unbind textures and render targets and vertex buffer // Unbind textures and render targets and vertex buffer
deviceContext->PSSetShaderResources(0, 1, &nullSRV); mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer); deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer);
mRenderer->markAllStateDirty(); mRenderer->markAllStateDirty();
......
...@@ -91,22 +91,6 @@ ID3D11Resource *GetSRVResource(ID3D11ShaderResourceView *srv) ...@@ -91,22 +91,6 @@ ID3D11Resource *GetSRVResource(ID3D11ShaderResourceView *srv)
return resource; return resource;
} }
bool UnsetSRVsWithResource(std::vector<ID3D11ShaderResourceView *> &srvs, const ID3D11Resource *resource)
{
bool foundAny = false;
for (auto &srv : srvs)
{
if (srv && GetSRVResource(srv) == resource)
{
srv = NULL;
foundAny = true;
}
}
return foundAny;
}
} }
Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay) Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay)
...@@ -542,11 +526,10 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Textu ...@@ -542,11 +526,10 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Textu
gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
{ {
ID3D11ShaderResourceView *textureSRV = NULL; ID3D11ShaderResourceView *textureSRV = NULL;
bool forceSetTexture = false;
if (texture) if (texture)
{ {
TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation()); TextureD3D *textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
TextureStorage *texStorage = textureImpl->getNativeTexture(); TextureStorage *texStorage = textureImpl->getNativeTexture();
ASSERT(texStorage != NULL); ASSERT(texStorage != NULL);
...@@ -566,33 +549,13 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t ...@@ -566,33 +549,13 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t
// missing the shader resource view // missing the shader resource view
ASSERT(textureSRV != NULL); ASSERT(textureSRV != NULL);
forceSetTexture = textureImpl->hasDirtyImages();
textureImpl->resetDirty(); textureImpl->resetDirty();
} }
if (type == gl::SAMPLER_PIXEL) ASSERT((type == gl::SAMPLER_PIXEL && static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits) ||
{ (type == gl::SAMPLER_VERTEX && static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits));
ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits);
if (forceSetTexture || mCurPixelSRVs[index] != textureSRV)
{
mDeviceContext->PSSetShaderResources(index, 1, &textureSRV);
}
mCurPixelSRVs[index] = textureSRV;
}
else if (type == gl::SAMPLER_VERTEX)
{
ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits);
if (forceSetTexture || mCurVertexSRVs[index] != textureSRV)
{
mDeviceContext->VSSetShaderResources(index, 1, &textureSRV);
}
mCurVertexSRVs[index] = textureSRV; setShaderResource(type, index, textureSRV);
}
else UNREACHABLE();
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
...@@ -867,6 +830,21 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) ...@@ -867,6 +830,21 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
return count >= minCount; return count >= minCount;
} }
void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11Resource *resource)
{
auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
{
ID3D11ShaderResourceView *srv = currentSRVs[resourceIndex];
if (srv && GetSRVResource(srv) == resource)
{
setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL);
}
}
}
gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
{ {
// Get the color render buffer and serial // Get the color render buffer and serial
...@@ -919,19 +897,10 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) ...@@ -919,19 +897,10 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
} }
#if !defined(NDEBUG) #if !defined(NDEBUG)
// Detect if this color buffer is already bound as a texture and unbind it first to prevent // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
// D3D11 warnings.
ID3D11Resource *renderTargetResource = renderTarget->getTexture(); ID3D11Resource *renderTargetResource = renderTarget->getTexture();
unsetSRVsWithResource(gl::SAMPLER_VERTEX, renderTargetResource);
if (UnsetSRVsWithResource(mCurVertexSRVs, renderTargetResource)) unsetSRVsWithResource(gl::SAMPLER_PIXEL, renderTargetResource);
{
mDeviceContext->VSSetShaderResources(0, static_cast<UINT>(mCurVertexSRVs.size()), mCurVertexSRVs.data());
}
if (UnsetSRVsWithResource(mCurPixelSRVs, renderTargetResource))
{
mDeviceContext->PSSetShaderResources(0, static_cast<UINT>(mCurPixelSRVs.size()), mCurPixelSRVs.data());
}
#endif #endif
} }
} }
...@@ -1691,14 +1660,12 @@ void Renderer11::markAllStateDirty() ...@@ -1691,14 +1660,12 @@ void Renderer11::markAllStateDirty()
for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId) for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId)
{ {
mForceSetVertexSamplerStates[vsamplerId] = true; mForceSetVertexSamplerStates[vsamplerId] = true;
mCurVertexSRVs[vsamplerId] = NULL;
} }
ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size()); ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size());
for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId) for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId)
{ {
mForceSetPixelSamplerStates[fsamplerId] = true; mForceSetPixelSamplerStates[fsamplerId] = true;
mCurPixelSRVs[fsamplerId] = NULL;
} }
mForceSetBlendState = true; mForceSetBlendState = true;
...@@ -3225,4 +3192,25 @@ Workarounds Renderer11::generateWorkarounds() const ...@@ -3225,4 +3192,25 @@ Workarounds Renderer11::generateWorkarounds() const
return d3d11::GenerateWorkarounds(); return d3d11::GenerateWorkarounds();
} }
void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv)
{
auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
if (currentSRVs[resourceSlot] != srv)
{
if (shaderType == gl::SAMPLER_VERTEX)
{
mDeviceContext->VSSetShaderResources(resourceSlot, 1, &srv);
}
else
{
mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv);
}
currentSRVs[resourceSlot] = srv;
}
}
} }
...@@ -203,6 +203,8 @@ class Renderer11 : public Renderer ...@@ -203,6 +203,8 @@ class Renderer11 : public Renderer
gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels); GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv);
private: private:
DISALLOW_COPY_AND_ASSIGN(Renderer11); DISALLOW_COPY_AND_ASSIGN(Renderer11);
...@@ -216,6 +218,7 @@ class Renderer11 : public Renderer ...@@ -216,6 +218,7 @@ class Renderer11 : public Renderer
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);
static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel); static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel);
static void invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer); static void invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer);
......
...@@ -572,7 +572,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) ...@@ -572,7 +572,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
deviceContext->RSSetViewports(1, &viewport); deviceContext->RSSetViewports(1, &viewport);
// Apply textures // Apply textures
deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView); mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView);
deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler); deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler);
// Draw // Draw
...@@ -602,8 +602,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) ...@@ -602,8 +602,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
} }
// Unbind // Unbind
static ID3D11ShaderResourceView *const nullSRV = NULL; mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
deviceContext->PSSetShaderResources(0, 1, &nullSRV);
mRenderer->unapplyRenderTargets(); mRenderer->unapplyRenderTargets();
mRenderer->markAllStateDirty(); mRenderer->markAllStateDirty();
......
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