Commit da7185fb by Jamie Madill Committed by Commit Bot

D3D11: Consolidate SRV and Sampler application.

This adds an internal and external version of the setShaderResource method. The external version sets the state as dirty. BUG=angleproject:2052 Change-Id: I6d2d47490c0af89ff5592d4e9c53eb69f8a3264d Reviewed-on: https://chromium-review.googlesource.com/659397Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 7ef2ddab
......@@ -1107,18 +1107,13 @@ gl::Error Blit11::swizzleTexture(const gl::Context *context,
// Set the viewport
stateManager->setSimpleViewport(size);
// Apply textures
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source.get());
// Apply samplers
ID3D11SamplerState *samplerState = mPointSampler.get();
deviceContext->PSSetSamplers(0, 1, &samplerState);
// Apply textures and sampler
stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
// Draw the quad
deviceContext->Draw(drawCount, 0);
// Unbind shader resources and dirty state.
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
// Dirty state.
mRenderer->markAllStateDirty(context);
return gl::NoError();
......@@ -1233,32 +1228,25 @@ gl::Error Blit11::copyTexture(const gl::Context *context,
// Set the viewport
stateManager->setSimpleViewport(destSize);
// Apply textures
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source.get());
// Apply samplers
ID3D11SamplerState *sampler = nullptr;
// Apply texture and sampler
switch (filter)
{
case GL_NEAREST:
sampler = mPointSampler.get();
stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
break;
case GL_LINEAR:
sampler = mLinearSampler.get();
stateManager->setSimplePixelTextureAndSampler(source, mLinearSampler);
break;
default:
UNREACHABLE();
return gl::InternalError() << "Internal error, unknown blit filter mode.";
}
deviceContext->PSSetSamplers(0, 1, &sampler);
// Draw the quad
deviceContext->Draw(drawCount, 0);
// Unbind shader resource and invalidate state.
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
// Invalidate state.
mRenderer->markAllStateDirty(context);
return gl::NoError();
......@@ -1356,19 +1344,13 @@ gl::Error Blit11::copyDepth(const gl::Context *context,
// Set the viewport
stateManager->setSimpleViewport(destSize);
// Apply textures
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source.get());
// Apply samplers
ID3D11SamplerState *samplerState = mPointSampler.get();
deviceContext->PSSetSamplers(0, 1, &samplerState);
// Apply texture and sampler
stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
// Draw the quad
deviceContext->Draw(drawCount, 0);
// Unbind shader resources and invalidate all state.
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
// Invalidate all state.
mRenderer->markAllStateDirty(context);
return gl::NoError();
......@@ -2000,13 +1982,10 @@ gl::ErrorOrResult<TextureHelper11> Blit11::resolveDepth(const gl::Context *conte
stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF);
stateManager->setRenderTargets(nullptr, 0, mResolvedDepthDSView.get());
stateManager->setSimpleBlendState(nullptr);
// Set the viewport
stateManager->setSimpleViewport(extents);
ID3D11ShaderResourceView *pixelViews[] = {depth->getShaderResourceView().get()};
deviceContext->PSSetShaderResources(0, 1, pixelViews);
// Set the viewport
stateManager->setShaderResourceShared(gl::SAMPLER_PIXEL, 0, &depth->getShaderResourceView());
// Trigger the blit on the GPU.
deviceContext->Draw(6, 0);
......@@ -2166,12 +2145,9 @@ gl::ErrorOrResult<TextureHelper11> Blit11::resolveStencil(const gl::Context *con
// Set the viewport
stateManager->setSimpleViewport(extents);
ID3D11ShaderResourceView *pixelViews[] = {
depthStencil->getShaderResourceView().get(), mStencilSRV.get(),
};
deviceContext->PSSetShaderResources(0, 2, pixelViews);
stateManager->setShaderResourceShared(gl::SAMPLER_PIXEL, 0,
&depthStencil->getShaderResourceView());
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 1, &mStencilSRV);
// Trigger the blit on the GPU.
deviceContext->Draw(6, 0);
......
......@@ -165,7 +165,7 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage
uint8_t **mapPointerOut) override;
void unmap() override;
gl::ErrorOrResult<ID3D11ShaderResourceView *> getSRVForFormat(DXGI_FORMAT srvFormat);
gl::ErrorOrResult<const d3d11::ShaderResourceView *> getSRVForFormat(DXGI_FORMAT srvFormat);
private:
static void FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc,
......@@ -669,7 +669,7 @@ gl::Error Buffer11::getConstantBufferRange(GLintptr offset,
return gl::NoError();
}
gl::ErrorOrResult<ID3D11ShaderResourceView *> Buffer11::getSRV(DXGI_FORMAT srvFormat)
gl::ErrorOrResult<const d3d11::ShaderResourceView *> Buffer11::getSRV(DXGI_FORMAT srvFormat)
{
BufferStorage *storage = nullptr;
ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK), storage);
......@@ -1179,14 +1179,14 @@ void Buffer11::NativeStorage::unmap()
context->Unmap(mBuffer.get(), 0);
}
gl::ErrorOrResult<ID3D11ShaderResourceView *> Buffer11::NativeStorage::getSRVForFormat(
gl::ErrorOrResult<const d3d11::ShaderResourceView *> Buffer11::NativeStorage::getSRVForFormat(
DXGI_FORMAT srvFormat)
{
auto bufferSRVIt = mBufferResourceViews.find(srvFormat);
if (bufferSRVIt != mBufferResourceViews.end())
{
return bufferSRVIt->second.get();
return &bufferSRVIt->second;
}
const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(srvFormat);
......@@ -1200,7 +1200,7 @@ gl::ErrorOrResult<ID3D11ShaderResourceView *> Buffer11::NativeStorage::getSRVFor
ANGLE_TRY(mRenderer->allocateResource(bufferSRVDesc, mBuffer.get(),
&mBufferResourceViews[srvFormat]));
return mBufferResourceViews[srvFormat].get();
return &mBufferResourceViews[srvFormat];
}
void Buffer11::NativeStorage::clearSRVs()
......
......@@ -62,7 +62,7 @@ class Buffer11 : public BufferD3D
const d3d11::Buffer **bufferOut,
UINT *firstConstantOut,
UINT *numConstantsOut);
gl::ErrorOrResult<ID3D11ShaderResourceView *> getSRV(DXGI_FORMAT srvFormat);
gl::ErrorOrResult<const d3d11::ShaderResourceView *> getSRV(DXGI_FORMAT srvFormat);
bool isMapped() const { return mMappedStorage != nullptr; }
gl::Error packPixels(const gl::Context *context,
const gl::FramebufferAttachment &readAttachment,
......
......@@ -171,7 +171,7 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::Context *context,
DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat;
ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN);
Buffer11 *bufferStorage11 = GetAs<Buffer11>(sourceBuffer.getImplementation());
ID3D11ShaderResourceView *bufferSRV = nullptr;
const d3d11::ShaderResourceView *bufferSRV = nullptr;
ANGLE_TRY_RESULT(bufferStorage11->getSRV(srvFormat), bufferSRV);
ASSERT(bufferSRV != nullptr);
......
......@@ -585,8 +585,11 @@ StateManager11::StateManager11(Renderer11 *renderer)
mCurRasterState.pointDrawMode = false;
mCurRasterState.multiSample = false;
// Start with all internal dirty bits set.
mInternalDirtyBits.set();
// Initially all current value attributes must be updated on first use.
mDirtyCurrentValueAttribs.flip();
mDirtyCurrentValueAttribs.set();
mCurrentVertexBuffers.fill(nullptr);
mCurrentVertexStrides.fill(std::numeric_limits<UINT>::max());
......@@ -597,6 +600,33 @@ StateManager11::~StateManager11()
{
}
template <typename SRVType>
void StateManager11::setShaderResourceInternal(gl::SamplerType shaderType,
UINT resourceSlot,
const SRVType *srv)
{
auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
const SRVRecord &record = currentSRVs[resourceSlot];
if (record.srv != reinterpret_cast<uintptr_t>(srv))
{
auto deviceContext = mRenderer->getDeviceContext();
ID3D11ShaderResourceView *srvPtr = srv ? srv->get() : nullptr;
if (shaderType == gl::SAMPLER_VERTEX)
{
deviceContext->VSSetShaderResources(resourceSlot, 1, &srvPtr);
}
else
{
deviceContext->PSSetShaderResources(resourceSlot, 1, &srvPtr);
}
currentSRVs.update(resourceSlot, srvPtr);
}
}
void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
unsigned int stencilSize)
{
......@@ -1458,31 +1488,6 @@ gl::Error StateManager11::onMakeCurrent(const gl::Context *context)
return gl::NoError();
}
void StateManager11::setShaderResource(gl::SamplerType shaderType,
UINT resourceSlot,
ID3D11ShaderResourceView *srv)
{
auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
const SRVRecord &record = currentSRVs[resourceSlot];
if (record.srv != reinterpret_cast<uintptr_t>(srv))
{
auto deviceContext = mRenderer->getDeviceContext();
if (shaderType == gl::SAMPLER_VERTEX)
{
deviceContext->VSSetShaderResources(resourceSlot, 1, &srv);
}
else
{
deviceContext->PSSetShaderResources(resourceSlot, 1, &srv);
}
currentSRVs.update(resourceSlot, srv);
}
}
gl::Error StateManager11::clearTextures(gl::SamplerType samplerType,
size_t rangeStart,
size_t rangeEnd)
......@@ -1535,7 +1540,8 @@ void StateManager11::unsetConflictingSRVs(gl::SamplerType samplerType,
if (record.srv && record.resource == resource &&
ImageIndexConflictsWithSRV(index, record.desc))
{
setShaderResource(samplerType, static_cast<UINT>(resourceIndex), nullptr);
setShaderResourceInternal<d3d11::ShaderResourceView>(
samplerType, static_cast<UINT>(resourceIndex), nullptr);
}
}
}
......@@ -1554,6 +1560,12 @@ void StateManager11::unsetConflictingAttachmentResources(
unsetConflictingSRVs(gl::SAMPLER_VERTEX, resourcePtr, index);
unsetConflictingSRVs(gl::SAMPLER_PIXEL, resourcePtr, index);
}
else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
{
uintptr_t resourcePtr = reinterpret_cast<uintptr_t>(resource);
unsetConflictingSRVs(gl::SAMPLER_VERTEX, resourcePtr, gl::ImageIndex::Make2D(0));
unsetConflictingSRVs(gl::SAMPLER_PIXEL, resourcePtr, gl::ImageIndex::Make2D(0));
}
}
gl::Error StateManager11::initialize(const gl::Caps &caps, const gl::Extensions &extensions)
......@@ -1908,6 +1920,26 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod
return gl::NoError();
}
void StateManager11::setShaderResourceShared(gl::SamplerType shaderType,
UINT resourceSlot,
const d3d11::SharedSRV *srv)
{
setShaderResourceInternal(shaderType, resourceSlot, srv);
// TODO(jmadill): Narrower dirty region.
mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
}
void StateManager11::setShaderResource(gl::SamplerType shaderType,
UINT resourceSlot,
const d3d11::ShaderResourceView *srv)
{
setShaderResourceInternal(shaderType, resourceSlot, srv);
// TODO(jmadill): Narrower dirty region.
mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
}
void StateManager11::setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology)
{
if (primitiveTopology != mCurrentPrimitiveTopology)
......@@ -2091,8 +2123,8 @@ void StateManager11::setSimpleViewport(int width, int height)
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = static_cast<FLOAT>(width);
viewport.Height = static_cast<FLOAT>(height);
viewport.Width = static_cast<FLOAT>(width);
viewport.Height = static_cast<FLOAT>(height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
......@@ -2100,6 +2132,18 @@ void StateManager11::setSimpleViewport(int width, int height)
mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
}
void StateManager11::setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv,
const d3d11::SamplerState &samplerState)
{
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
setShaderResourceInternal(gl::SAMPLER_PIXEL, 0, &srv);
deviceContext->PSSetSamplers(0, 1, samplerState.getPointer());
// TODO(jmadill): Narrower dirty region.
mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
}
// For each Direct3D sampler of either the pixel or vertex stage,
// looks up the corresponding OpenGL texture image unit and texture type,
// and sets the texture and its addressing/filtering state (or NULL when inactive).
......@@ -2300,7 +2344,7 @@ gl::Error StateManager11::setTexture(const gl::Context *context,
(type == gl::SAMPLER_VERTEX &&
static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxVertexTextureImageUnits));
setShaderResource(type, index, textureSRV->get());
setShaderResourceInternal(type, index, textureSRV);
return gl::NoError();
}
......
......@@ -158,10 +158,6 @@ class StateManager11 final : angle::NonCopyable
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
void setShaderResource(gl::SamplerType shaderType,
UINT resourceSlot,
ID3D11ShaderResourceView *srv);
// Checks are done on a framebuffer state change to trigger other state changes.
// The Context is allowed to be nullptr for these methods, when called in EGL init code.
void invalidateRenderTarget(const gl::Context *context);
......@@ -200,6 +196,12 @@ class StateManager11 final : angle::NonCopyable
gl::Error updateState(const gl::Context *context, GLenum drawMode);
void setShaderResourceShared(gl::SamplerType shaderType,
UINT resourceSlot,
const d3d11::SharedSRV *srv);
void setShaderResource(gl::SamplerType shaderType,
UINT resourceSlot,
const d3d11::ShaderResourceView *srv);
void setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology);
void setDrawShaders(const d3d11::VertexShader *vertexShader,
......@@ -216,6 +218,8 @@ class StateManager11 final : angle::NonCopyable
void setRasterizerState(const d3d11::RasterizerState *rasterizerState);
void setSimpleViewport(const gl::Extents &viewportExtents);
void setSimpleViewport(int width, int height);
void setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv,
const d3d11::SamplerState &samplerState);
// Not handled by an internal dirty bit because of the extra draw parameters.
gl::Error applyVertexBuffer(const gl::Context *context,
......@@ -246,6 +250,11 @@ class StateManager11 final : angle::NonCopyable
InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; }
private:
template <typename SRVType>
void setShaderResourceInternal(gl::SamplerType shaderType,
UINT resourceSlot,
const SRVType *srv);
void unsetConflictingSRVs(gl::SamplerType shaderType,
uintptr_t resource,
const gl::ImageIndex &index);
......
......@@ -843,19 +843,12 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(const gl::Context *context,
stateManager->setSimpleViewport(mWidth, mHeight);
// Apply textures
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView.get());
ID3D11SamplerState *samplerState = mPassThroughSampler.get();
deviceContext->PSSetSamplers(0, 1, &samplerState);
stateManager->setSimplePixelTextureAndSampler(mOffscreenSRView, mPassThroughSampler);
// Draw
deviceContext->Draw(4, 0);
// Rendering to the swapchain is now complete. Now we can call Present().
// Before that, we perform any cleanup on the D3D device. We do this before Present() to make sure the
// cleanup is caught under the current eglSwapBuffers() PIX/Graphics Diagnostics call rather than the next one.
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
mRenderer->markAllStateDirty(context);
return EGL_SUCCESS;
......
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