Commit c9bdeff4 by Jamie Madill Committed by Commit Bot

D3D11: Refactor RenderTarget apply into StateManager11.

This is a refactoring patch only, and doesn't change the behaviour. The intent is to make it easy to turn on the Framebuffer dirty bits in a subsequent patch, once we can cleanly handle textures and renderbuffers getting recreated. BUG=angleproject:1260 Change-Id: Iaa5cfe222b020724e088eee5f1ae909b6f981a08 Reviewed-on: https://chromium-review.googlesource.com/325423Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 570f67d7
...@@ -8,8 +8,15 @@ ...@@ -8,8 +8,15 @@
#include "common/debug.h" #include "common/debug.h"
#include <stdio.h> #include <stdio.h>
#include <limits>
#include <vector> #include <vector>
namespace angle
{
const uintptr_t DirtyPointer = std::numeric_limits<uintptr_t>::max();
}
size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer) size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer)
{ {
// Attempt to just print to the current buffer // Attempt to just print to the current buffer
......
...@@ -33,6 +33,7 @@ class NonCopyable ...@@ -33,6 +33,7 @@ class NonCopyable
void operator=(const NonCopyable&) = delete; void operator=(const NonCopyable&) = delete;
}; };
extern const uintptr_t DirtyPointer;
} }
template <typename T, size_t N> template <typename T, size_t N>
......
...@@ -37,8 +37,6 @@ const int ScratchMemoryBufferLifetime = 1000; ...@@ -37,8 +37,6 @@ const int ScratchMemoryBufferLifetime = 1000;
} // anonymous namespace } // anonymous namespace
const uintptr_t RendererD3D::DirtyPointer = std::numeric_limits<uintptr_t>::max();
RendererD3D::RendererD3D(egl::Display *display) RendererD3D::RendererD3D(egl::Display *display)
: mDisplay(display), : mDisplay(display),
mDeviceLost(false), mDeviceLost(false),
......
...@@ -172,8 +172,6 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -172,8 +172,6 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
SourceIndexData *sourceIndexInfo) = 0; SourceIndexData *sourceIndexInfo) = 0;
virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0; virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0;
virtual void markAllStateDirty() = 0;
virtual unsigned int getReservedVertexUniformVectors() const = 0; virtual unsigned int getReservedVertexUniformVectors() const = 0;
virtual unsigned int getReservedFragmentUniformVectors() const = 0; virtual unsigned int getReservedFragmentUniformVectors() const = 0;
virtual unsigned int getReservedVertexUniformBuffers() const = 0; virtual unsigned int getReservedVertexUniformBuffers() const = 0;
...@@ -263,7 +261,6 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -263,7 +261,6 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
static unsigned int GetBlendSampleMask(const gl::Data &data, int samples); static unsigned int GetBlendSampleMask(const gl::Data &data, int samples);
// dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state. // dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state.
static const uintptr_t DirtyPointer;
egl::Display *mDisplay; egl::Display *mDisplay;
bool mDeviceLost; bool mDeviceLost;
......
...@@ -709,7 +709,8 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ...@@ -709,7 +709,8 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source,
deviceContext->GSSetShader(support.geometryShader, nullptr, 0); deviceContext->GSSetShader(support.geometryShader, nullptr, 0);
// Unset the currently bound shader resource to avoid conflicts // Unset the currently bound shader resource to avoid conflicts
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); auto stateManager = mRenderer->getStateManager();
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
// Apply render target // Apply render target
mRenderer->setOneTimeRenderTarget(dest); mRenderer->setOneTimeRenderTarget(dest);
...@@ -725,7 +726,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ...@@ -725,7 +726,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source,
deviceContext->RSSetViewports(1, &viewport); deviceContext->RSSetViewports(1, &viewport);
// Apply textures // Apply textures
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers // Apply samplers
deviceContext->PSSetSamplers(0, 1, &mPointSampler); deviceContext->PSSetSamplers(0, 1, &mPointSampler);
...@@ -734,7 +735,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ...@@ -734,7 +735,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source,
deviceContext->Draw(drawCount, 0); deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer // Unbind textures and render targets and vertex buffer
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
mRenderer->unapplyRenderTargets(); mRenderer->unapplyRenderTargets();
...@@ -846,7 +847,8 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, ...@@ -846,7 +847,8 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source,
deviceContext->GSSetShader(support.geometryShader, nullptr, 0); deviceContext->GSSetShader(support.geometryShader, nullptr, 0);
// Unset the currently bound shader resource to avoid conflicts // Unset the currently bound shader resource to avoid conflicts
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); auto stateManager = mRenderer->getStateManager();
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
// Apply render target // Apply render target
mRenderer->setOneTimeRenderTarget(dest); mRenderer->setOneTimeRenderTarget(dest);
...@@ -862,7 +864,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, ...@@ -862,7 +864,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source,
deviceContext->RSSetViewports(1, &viewport); deviceContext->RSSetViewports(1, &viewport);
// Apply textures // Apply textures
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers // Apply samplers
ID3D11SamplerState *sampler = nullptr; ID3D11SamplerState *sampler = nullptr;
...@@ -881,7 +883,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, ...@@ -881,7 +883,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source,
deviceContext->Draw(drawCount, 0); deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer // Unbind textures and render targets and vertex buffer
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
mRenderer->unapplyRenderTargets(); mRenderer->unapplyRenderTargets();
...@@ -973,7 +975,8 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou ...@@ -973,7 +975,8 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
deviceContext->GSSetShader(nullptr, nullptr, 0); deviceContext->GSSetShader(nullptr, nullptr, 0);
// Unset the currently bound shader resource to avoid conflicts // Unset the currently bound shader resource to avoid conflicts
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); auto stateManager = mRenderer->getStateManager();
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
// Apply render target // Apply render target
deviceContext->OMSetRenderTargets(0, nullptr, dest); deviceContext->OMSetRenderTargets(0, nullptr, dest);
...@@ -989,7 +992,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou ...@@ -989,7 +992,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
deviceContext->RSSetViewports(1, &viewport); deviceContext->RSSetViewports(1, &viewport);
// Apply textures // Apply textures
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers // Apply samplers
deviceContext->PSSetSamplers(0, 1, &mPointSampler); deviceContext->PSSetSamplers(0, 1, &mPointSampler);
...@@ -998,7 +1001,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou ...@@ -998,7 +1001,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
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
mRenderer->unapplyRenderTargets(); mRenderer->unapplyRenderTargets();
......
...@@ -224,11 +224,12 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac ...@@ -224,11 +224,12 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
// Are we doing a 2D or 3D copy? // Are we doing a 2D or 3D copy?
ID3D11GeometryShader *geometryShader = ((destSize.depth > 1) ? mBufferToTextureGS : NULL); ID3D11GeometryShader *geometryShader = ((destSize.depth > 1) ? mBufferToTextureGS : NULL);
auto stateManager = mRenderer->getStateManager();
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);
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV);
deviceContext->IASetInputLayout(NULL); deviceContext->IASetInputLayout(NULL);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
...@@ -261,7 +262,7 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac ...@@ -261,7 +262,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
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer); deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer);
mRenderer->markAllStateDirty(); mRenderer->markAllStateDirty();
......
...@@ -87,73 +87,6 @@ enum ...@@ -87,73 +87,6 @@ enum
MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16 MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
}; };
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 && gl::RangeUI(mipMin, mipMax).intersects(gl::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!!
ID3D11Resource *GetViewResource(ID3D11View *view)
{
ID3D11Resource *resource = NULL;
ASSERT(view);
view->GetResource(&resource);
resource->Release();
return resource;
}
void CalculateConstantBufferParams(GLintptr offset, GLsizeiptr size, UINT *outFirstConstant, UINT *outNumConstants) void CalculateConstantBufferParams(GLintptr offset, GLsizeiptr size, UINT *outFirstConstant, UINT *outNumConstants)
{ {
// The offset must be aligned to 256 bytes (should have been enforced by glBindBufferRange). // The offset must be aligned to 256 bytes (should have been enforced by glBindBufferRange).
...@@ -430,49 +363,10 @@ void GetTriFanIndices(const GLvoid *indices, ...@@ -430,49 +363,10 @@ void GetTriFanIndices(const GLvoid *indices,
} // anonymous namespace } // anonymous namespace
void Renderer11::SRVCache::update(size_t resourceIndex, ID3D11ShaderResourceView *srv)
{
ASSERT(resourceIndex < mCurrentSRVs.size());
SRVRecord *record = &mCurrentSRVs[resourceIndex];
record->srv = reinterpret_cast<uintptr_t>(srv);
if (srv)
{
record->resource = reinterpret_cast<uintptr_t>(GetViewResource(srv));
srv->GetDesc(&record->desc);
mHighestUsedSRV = std::max(resourceIndex + 1, mHighestUsedSRV);
}
else
{
record->resource = 0;
if (resourceIndex + 1 == mHighestUsedSRV)
{
do
{
--mHighestUsedSRV;
}
while (mHighestUsedSRV > 0 &&
mCurrentSRVs[mHighestUsedSRV].srv == 0);
}
}
}
void Renderer11::SRVCache::clear()
{
if (mCurrentSRVs.empty())
{
return;
}
memset(&mCurrentSRVs[0], 0, sizeof(SRVRecord) * mCurrentSRVs.size());
mHighestUsedSRV = 0;
}
Renderer11::Renderer11(egl::Display *display) Renderer11::Renderer11(egl::Display *display)
: RendererD3D(display), : RendererD3D(display),
mStateCache(this), mStateCache(this),
mStateManager(), mStateManager(this),
mLastHistogramUpdateTime(ANGLEPlatformCurrent()->monotonicallyIncreasingTime()), mLastHistogramUpdateTime(ANGLEPlatformCurrent()->monotonicallyIncreasingTime()),
mDebug(nullptr) mDebug(nullptr)
{ {
...@@ -901,18 +795,17 @@ void Renderer11::initializeDevice() ...@@ -901,18 +795,17 @@ void Renderer11::initializeDevice()
ASSERT(!mPixelTransfer); ASSERT(!mPixelTransfer);
mPixelTransfer = new PixelTransfer11(this); mPixelTransfer = new PixelTransfer11(this);
mStateManager.initialize(mDeviceContext, &mStateCache, &mRenderer11DeviceCaps);
const gl::Caps &rendererCaps = getRendererCaps(); const gl::Caps &rendererCaps = getRendererCaps();
mStateManager.initialize(rendererCaps);
mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurVertexSRVs.initialize(rendererCaps.maxVertexTextureImageUnits); mStateManager.initialize(rendererCaps);
mCurPixelSRVs.initialize(rendererCaps.maxTextureImageUnits);
markAllStateDirty(); markAllStateDirty();
...@@ -930,9 +823,6 @@ void Renderer11::initializeDevice() ...@@ -930,9 +823,6 @@ void Renderer11::initializeDevice()
angleFeatureLevel = ANGLE_FEATURE_LEVEL_11_1; angleFeatureLevel = ANGLE_FEATURE_LEVEL_11_1;
} }
// Initialize cached NULL SRV block
mNullSRVs.resize(getRendererCaps().maxTextureImageUnits, nullptr);
ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11FeatureLevel", ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11FeatureLevel",
angleFeatureLevel, angleFeatureLevel,
NUM_ANGLE_FEATURE_LEVELS); NUM_ANGLE_FEATURE_LEVELS);
...@@ -1316,7 +1206,7 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t ...@@ -1316,7 +1206,7 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t
ASSERT((type == gl::SAMPLER_PIXEL && static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits) || ASSERT((type == gl::SAMPLER_PIXEL && static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits) ||
(type == gl::SAMPLER_VERTEX && static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits)); (type == gl::SAMPLER_VERTEX && static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits));
setShaderResource(type, index, textureSRV); mStateManager.setShaderResource(type, index, textureSRV);
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
...@@ -1538,152 +1428,9 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSi ...@@ -1538,152 +1428,9 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSi
return count >= minCount; return count >= minCount;
} }
void Renderer11::unsetConflictingSRVs(gl::SamplerType samplerType, uintptr_t resource, const gl::ImageIndex &index)
{
auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
{
auto &record = currentSRVs[resourceIndex];
if (record.srv && record.resource == resource && ImageIndexConflictsWithSRV(index, record.desc))
{
setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL);
}
}
}
gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer) gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
{ {
// Get the color render buffer and serial return mStateManager.syncFramebuffer(framebuffer);
// Also extract the render target dimensions and view
unsigned int renderTargetWidth = 0;
unsigned int renderTargetHeight = 0;
ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
bool missingColorRenderTarget = true;
const FramebufferD3D *framebufferD3D = GetImplAs<FramebufferD3D>(framebuffer);
const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender();
for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
{
const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
if (colorbuffer)
{
// the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order)
// check for zero-sized default framebuffer, which is a special case.
// in this case we do not wish to modify any state and just silently return false.
// this will not report any gl error but will cause the calling method to return.
const gl::Extents &size = colorbuffer->getSize();
if (size.width == 0 || size.height == 0)
{
return gl::Error(GL_NO_ERROR);
}
// Extract the render target dimensions and view
RenderTarget11 *renderTarget = NULL;
gl::Error error = colorbuffer->getRenderTarget(&renderTarget);
if (error.isError())
{
return error;
}
ASSERT(renderTarget);
framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
ASSERT(framebufferRTVs[colorAttachment]);
if (missingColorRenderTarget)
{
renderTargetWidth = renderTarget->getWidth();
renderTargetHeight = renderTarget->getHeight();
missingColorRenderTarget = false;
}
// Unbind render target SRVs from the shader here to prevent D3D11 warnings.
if (colorbuffer->type() == GL_TEXTURE)
{
uintptr_t rtResource = reinterpret_cast<uintptr_t>(GetViewResource(framebufferRTVs[colorAttachment]));
const gl::ImageIndex &index = colorbuffer->getTextureImageIndex();
// The index doesn't need to be corrected for the small compressed texture workaround
// because a rendertarget is never compressed.
unsetConflictingSRVs(gl::SAMPLER_VERTEX, rtResource, index);
unsetConflictingSRVs(gl::SAMPLER_PIXEL, rtResource, index);
}
}
}
// Get the depth stencil buffers
ID3D11DepthStencilView* framebufferDSV = NULL;
const gl::FramebufferAttachment *depthStencil = framebuffer->getDepthOrStencilbuffer();
if (depthStencil)
{
RenderTarget11 *depthStencilRenderTarget = NULL;
gl::Error error = depthStencil->getRenderTarget(&depthStencilRenderTarget);
if (error.isError())
{
SafeRelease(framebufferRTVs);
return error;
}
ASSERT(depthStencilRenderTarget);
framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
ASSERT(framebufferDSV);
// If there is no render buffer, the width, height and format values come from
// the depth stencil
if (missingColorRenderTarget)
{
renderTargetWidth = depthStencilRenderTarget->getWidth();
renderTargetHeight = depthStencilRenderTarget->getHeight();
}
// Unbind render target SRVs from the shader here to prevent D3D11 warnings.
if (depthStencil->type() == GL_TEXTURE)
{
uintptr_t depthStencilResource = reinterpret_cast<uintptr_t>(GetViewResource(framebufferDSV));
const gl::ImageIndex &index = depthStencil->getTextureImageIndex();
// The index doesn't need to be corrected for the small compressed texture workaround
// because a rendertarget is never compressed.
unsetConflictingSRVs(gl::SAMPLER_VERTEX, depthStencilResource, index);
unsetConflictingSRVs(gl::SAMPLER_PIXEL, depthStencilResource, index);
}
unsigned int stencilSize = depthStencil->getStencilSize();
mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize);
}
// Apply the render target and depth stencil
if (!mDepthStencilInitialized ||
memcmp(framebufferRTVs, mAppliedRTVs, sizeof(framebufferRTVs)) != 0 ||
reinterpret_cast<uintptr_t>(framebufferDSV) != mAppliedDSV)
{
mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, framebufferRTVs, framebufferDSV);
mStateManager.setViewportBounds(renderTargetWidth, renderTargetHeight);
mStateManager.forceSetBlendState();
if (!mDepthStencilInitialized)
{
mStateManager.forceSetRasterState();
}
for (size_t rtIndex = 0; rtIndex < ArraySize(framebufferRTVs); rtIndex++)
{
mAppliedRTVs[rtIndex] = reinterpret_cast<uintptr_t>(framebufferRTVs[rtIndex]);
}
mAppliedDSV = reinterpret_cast<uintptr_t>(framebufferDSV);
mDepthStencilInitialized = true;
}
const Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
gl::Error error = framebuffer11->invalidateSwizzles();
if (error.isError())
{
return error;
}
return gl::Error(GL_NO_ERROR);
} }
gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceInfo) gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceInfo)
...@@ -2431,39 +2178,25 @@ void Renderer11::markAllStateDirty() ...@@ -2431,39 +2178,25 @@ void Renderer11::markAllStateDirty()
{ {
TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty"); TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty");
markRenderTargetStateDirty();
// 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.
mCurVertexSRVs.clear();
mCurPixelSRVs.clear();
ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size());
for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId) for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId)
{ {
mForceSetVertexSamplerStates[vsamplerId] = true; mForceSetVertexSamplerStates[vsamplerId] = true;
} }
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;
} }
mStateManager.forceSetBlendState(); mStateManager.invalidateEverything();
mStateManager.forceSetDepthStencilState();
mStateManager.forceSetRasterState();
mStateManager.forceSetScissorState();
mStateManager.forceSetViewportState();
mAppliedIB = NULL; mAppliedIB = NULL;
mAppliedIBFormat = DXGI_FORMAT_UNKNOWN; mAppliedIBFormat = DXGI_FORMAT_UNKNOWN;
mAppliedIBOffset = 0; mAppliedIBOffset = 0;
mAppliedVertexShader = DirtyPointer; mAppliedVertexShader = angle::DirtyPointer;
mAppliedGeometryShader = DirtyPointer; mAppliedGeometryShader = angle::DirtyPointer;
mAppliedPixelShader = DirtyPointer; mAppliedPixelShader = angle::DirtyPointer;
mAppliedNumXFBBindings = static_cast<size_t>(-1); mAppliedNumXFBBindings = static_cast<size_t>(-1);
...@@ -2495,16 +2228,6 @@ void Renderer11::markAllStateDirty() ...@@ -2495,16 +2228,6 @@ void Renderer11::markAllStateDirty()
mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
} }
void Renderer11::markRenderTargetStateDirty()
{
for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++)
{
mAppliedRTVs[rtIndex] = DirtyPointer;
}
mAppliedDSV = DirtyPointer;
mDepthStencilInitialized = false;
}
void Renderer11::releaseDeviceResources() void Renderer11::releaseDeviceResources()
{ {
mStateCache.clear(); mStateCache.clear();
...@@ -3069,9 +2792,9 @@ void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView ...@@ -3069,9 +2792,9 @@ void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView
// Do not preserve the serial for this one-time-use render target // Do not preserve the serial for this one-time-use render target
for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++) for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++)
{ {
mAppliedRTVs[rtIndex] = DirtyPointer; mAppliedRTVs[rtIndex] = angle::DirtyPointer;
} }
mAppliedDSV = DirtyPointer; mAppliedDSV = angle::DirtyPointer;
} }
gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT)
...@@ -4185,28 +3908,6 @@ WorkaroundsD3D Renderer11::generateWorkarounds() const ...@@ -4185,28 +3908,6 @@ WorkaroundsD3D Renderer11::generateWorkarounds() const
return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps.featureLevel); return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps.featureLevel);
} }
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());
const SRVRecord &record = currentSRVs[resourceSlot];
if (record.srv != reinterpret_cast<uintptr_t>(srv))
{
if (shaderType == gl::SAMPLER_VERTEX)
{
mDeviceContext->VSSetShaderResources(resourceSlot, 1, &srv);
}
else
{
mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv);
}
currentSRVs.update(resourceSlot, srv);
}
}
void Renderer11::createAnnotator() void Renderer11::createAnnotator()
{ {
// The D3D11 renderer must choose the D3D9 debug annotator because the D3D11 interface // The D3D11 renderer must choose the D3D9 debug annotator because the D3D11 interface
...@@ -4223,40 +3924,7 @@ void Renderer11::createAnnotator() ...@@ -4223,40 +3924,7 @@ void Renderer11::createAnnotator()
gl::Error Renderer11::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) gl::Error Renderer11::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd)
{ {
if (rangeStart == rangeEnd) return mStateManager.clearTextures(samplerType, rangeStart, rangeEnd);
{
return gl::Error(GL_NO_ERROR);
}
auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
gl::Range<size_t> clearRange(rangeStart, rangeStart);
clearRange.extend(std::min(rangeEnd, currentSRVs.highestUsed()));
if (clearRange.empty())
{
return gl::Error(GL_NO_ERROR);
}
if (samplerType == gl::SAMPLER_VERTEX)
{
mDeviceContext->VSSetShaderResources(static_cast<unsigned int>(rangeStart),
static_cast<unsigned int>(rangeEnd - rangeStart),
&mNullSRVs[0]);
}
else
{
mDeviceContext->PSSetShaderResources(static_cast<unsigned int>(rangeStart),
static_cast<unsigned int>(rangeEnd - rangeStart),
&mNullSRVs[0]);
}
for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; ++samplerIndex)
{
currentSRVs.update(samplerIndex, nullptr);
}
return gl::Error(GL_NO_ERROR);
} }
egl::Error Renderer11::getEGLDevice(DeviceImpl **device) egl::Error Renderer11::getEGLDevice(DeviceImpl **device)
......
...@@ -145,9 +145,6 @@ class Renderer11 : public RendererD3D ...@@ -145,9 +145,6 @@ class Renderer11 : public RendererD3D
SourceIndexData *sourceIndexInfo) override; SourceIndexData *sourceIndexInfo) override;
void applyTransformFeedbackBuffers(const gl::State &state) override; void applyTransformFeedbackBuffers(const gl::State &state) override;
virtual void markAllStateDirty();
void markRenderTargetStateDirty();
// lost device // lost device
bool testDeviceLost() override; bool testDeviceLost() override;
bool testDeviceResettable() override; bool testDeviceResettable() override;
...@@ -254,6 +251,7 @@ class Renderer11 : public RendererD3D ...@@ -254,6 +251,7 @@ class Renderer11 : public RendererD3D
virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
void markAllStateDirty();
void unapplyRenderTargets(); void unapplyRenderTargets();
void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView); void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView);
gl::Error packPixels(const TextureHelper11 &textureHelper, gl::Error packPixels(const TextureHelper11 &textureHelper,
...@@ -272,8 +270,6 @@ class Renderer11 : public RendererD3D ...@@ -272,8 +270,6 @@ class Renderer11 : public RendererD3D
const gl::PixelPackState &pack, const gl::PixelPackState &pack,
uint8_t *pixels); uint8_t *pixels);
void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv);
gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTargetD3D *readRenderTarget, gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTargetD3D *readRenderTarget,
RenderTargetD3D *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, RenderTargetD3D *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
bool colorBlit, bool depthBlit, bool stencilBlit); bool colorBlit, bool depthBlit, bool stencilBlit);
...@@ -283,6 +279,7 @@ class Renderer11 : public RendererD3D ...@@ -283,6 +279,7 @@ class Renderer11 : public RendererD3D
RendererClass getRendererClass() const override { return RENDERER_D3D11; } RendererClass getRendererClass() const override { return RENDERER_D3D11; }
InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; } InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; }
StateManager11 *getStateManager() { return &mStateManager; }
void onSwap(); void onSwap();
void onBufferDelete(const Buffer11 *deleted); void onBufferDelete(const Buffer11 *deleted);
...@@ -329,7 +326,6 @@ class Renderer11 : public RendererD3D ...@@ -329,7 +326,6 @@ class Renderer11 : public RendererD3D
int instances); int instances);
ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
void unsetConflictingSRVs(gl::SamplerType shaderType, uintptr_t resource, const gl::ImageIndex &index);
void populateRenderer11DeviceCaps(); void populateRenderer11DeviceCaps();
...@@ -366,49 +362,6 @@ class Renderer11 : public RendererD3D ...@@ -366,49 +362,6 @@ class Renderer11 : public RendererD3D
std::vector<bool> mForceSetPixelSamplerStates; std::vector<bool> mForceSetPixelSamplerStates;
std::vector<gl::SamplerState> mCurPixelSamplerStates; std::vector<gl::SamplerState> mCurPixelSamplerStates;
// Currently applied textures
struct SRVRecord
{
uintptr_t srv;
uintptr_t resource;
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
};
// A cache of current SRVs that also tracks the highest 'used' (non-NULL) SRV
// We might want to investigate a more robust approach that is also fast when there's
// a large gap between used SRVs (e.g. if SRV 0 and 7 are non-NULL, this approach will
// waste time on SRVs 1-6.)
class SRVCache : angle::NonCopyable
{
public:
SRVCache()
: mHighestUsedSRV(0)
{
}
void initialize(size_t size)
{
mCurrentSRVs.resize(size);
}
size_t size() const { return mCurrentSRVs.size(); }
size_t highestUsed() const { return mHighestUsedSRV; }
const SRVRecord &operator[](size_t index) const { return mCurrentSRVs[index]; }
void clear();
void update(size_t resourceIndex, ID3D11ShaderResourceView *srv);
private:
std::vector<SRVRecord> mCurrentSRVs;
size_t mHighestUsedSRV;
};
SRVCache mCurVertexSRVs;
SRVCache mCurPixelSRVs;
// A block of NULL pointers, cached so we don't re-allocate every draw call
std::vector<ID3D11ShaderResourceView*> mNullSRVs;
StateManager11 mStateManager; StateManager11 mStateManager;
// Currently applied primitive topology // Currently applied primitive topology
......
...@@ -9,13 +9,128 @@ ...@@ -9,13 +9,128 @@
#include "libANGLE/renderer/d3d/d3d11/StateManager11.h" #include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
#include "common/BitSetIterator.h" #include "common/BitSetIterator.h"
#include "common/utilities.h"
#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
namespace rx namespace rx
{ {
StateManager11::StateManager11() namespace
: mBlendStateIsDirty(false), {
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 &&
gl::RangeUI(mipMin, mipMax)
.intersects(gl::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!!
ID3D11Resource *GetViewResource(ID3D11View *view)
{
ID3D11Resource *resource = NULL;
ASSERT(view);
view->GetResource(&resource);
resource->Release();
return resource;
}
} // anonymous namespace
void StateManager11::SRVCache::update(size_t resourceIndex, ID3D11ShaderResourceView *srv)
{
ASSERT(resourceIndex < mCurrentSRVs.size());
SRVRecord *record = &mCurrentSRVs[resourceIndex];
record->srv = reinterpret_cast<uintptr_t>(srv);
if (srv)
{
record->resource = reinterpret_cast<uintptr_t>(GetViewResource(srv));
srv->GetDesc(&record->desc);
mHighestUsedSRV = std::max(resourceIndex + 1, mHighestUsedSRV);
}
else
{
record->resource = 0;
if (resourceIndex + 1 == mHighestUsedSRV)
{
do
{
--mHighestUsedSRV;
} while (mHighestUsedSRV > 0 && mCurrentSRVs[mHighestUsedSRV].srv == 0);
}
}
}
void StateManager11::SRVCache::clear()
{
if (mCurrentSRVs.empty())
{
return;
}
memset(&mCurrentSRVs[0], 0, sizeof(SRVRecord) * mCurrentSRVs.size());
mHighestUsedSRV = 0;
}
StateManager11::StateManager11(Renderer11 *renderer)
: mRenderer(renderer),
mBlendStateIsDirty(false),
mCurBlendColor(0, 0, 0, 0), mCurBlendColor(0, 0, 0, 0),
mCurSampleMask(0), mCurSampleMask(0),
mDepthStencilStateIsDirty(false), mDepthStencilStateIsDirty(false),
...@@ -31,9 +146,9 @@ StateManager11::StateManager11() ...@@ -31,9 +146,9 @@ StateManager11::StateManager11()
mCurNear(0.0f), mCurNear(0.0f),
mCurFar(0.0f), mCurFar(0.0f),
mViewportBounds(), mViewportBounds(),
mRenderer11DeviceCaps(nullptr), mCurPresentPathFastEnabled(false),
mDeviceContext(nullptr), mCurPresentPathFastColorBufferHeight(0),
mStateCache(nullptr) mAppliedDSV(angle::DirtyPointer)
{ {
mCurBlendState.blend = false; mCurBlendState.blend = false;
mCurBlendState.sourceBlendRGB = GL_ONE; mCurBlendState.sourceBlendRGB = GL_ONE;
...@@ -80,15 +195,6 @@ StateManager11::~StateManager11() ...@@ -80,15 +195,6 @@ StateManager11::~StateManager11()
{ {
} }
void StateManager11::initialize(ID3D11DeviceContext *deviceContext,
RenderStateCache *stateCache,
Renderer11DeviceCaps *renderer11DeviceCaps)
{
mDeviceContext = deviceContext;
mStateCache = stateCache;
mRenderer11DeviceCaps = renderer11DeviceCaps;
}
void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized, void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
unsigned int stencilSize) unsigned int stencilSize)
{ {
...@@ -101,7 +207,7 @@ void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized, ...@@ -101,7 +207,7 @@ void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
void StateManager11::setViewportBounds(const int width, const int height) void StateManager11::setViewportBounds(const int width, const int height)
{ {
if (mRenderer11DeviceCaps->featureLevel <= D3D_FEATURE_LEVEL_9_3 && if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 &&
(mViewportBounds.width != width || mViewportBounds.height != height)) (mViewportBounds.width != width || mViewportBounds.height != height))
{ {
mViewportBounds = gl::Extents(width, height, 1); mViewportBounds = gl::Extents(width, height, 1);
...@@ -349,7 +455,8 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer, ...@@ -349,7 +455,8 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer,
} }
ID3D11BlendState *dxBlendState = nullptr; ID3D11BlendState *dxBlendState = nullptr;
gl::Error error = mStateCache->getBlendState(framebuffer, blendState, &dxBlendState); gl::Error error =
mRenderer->getStateCache().getBlendState(framebuffer, blendState, &dxBlendState);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -376,7 +483,7 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer, ...@@ -376,7 +483,7 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer,
blendColors[3] = blendColor.alpha; blendColors[3] = blendColor.alpha;
} }
mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask); mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState, blendColors, sampleMask);
mCurBlendState = blendState; mCurBlendState = blendState;
mCurBlendColor = blendColor; mCurBlendColor = blendColor;
...@@ -424,8 +531,8 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState) ...@@ -424,8 +531,8 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState)
(depthStencilState.stencilBackMask & maxStencil)); (depthStencilState.stencilBackMask & maxStencil));
ID3D11DepthStencilState *dxDepthStencilState = NULL; ID3D11DepthStencilState *dxDepthStencilState = NULL;
gl::Error error = mStateCache->getDepthStencilState(depthStencilState, disableDepth, gl::Error error = mRenderer->getStateCache().getDepthStencilState(
disableStencil, &dxDepthStencilState); depthStencilState, disableDepth, disableStencil, &dxDepthStencilState);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -443,7 +550,7 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState) ...@@ -443,7 +550,7 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState)
"Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK"); "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK");
UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu); UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu);
mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef); mRenderer->getDeviceContext()->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
mCurDepthStencilState = depthStencilState; mCurDepthStencilState = depthStencilState;
mCurStencilRef = stencilRef; mCurStencilRef = stencilRef;
...@@ -464,14 +571,14 @@ gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterSt ...@@ -464,14 +571,14 @@ gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterSt
} }
ID3D11RasterizerState *dxRasterState = nullptr; ID3D11RasterizerState *dxRasterState = nullptr;
gl::Error error = gl::Error error = mRenderer->getStateCache().getRasterizerState(rasterState, mCurScissorEnabled,
mStateCache->getRasterizerState(rasterState, mCurScissorEnabled, &dxRasterState); &dxRasterState);
if (error.isError()) if (error.isError())
{ {
return error; return error;
} }
mDeviceContext->RSSetState(dxRasterState); mRenderer->getDeviceContext()->RSSetState(dxRasterState);
mCurRasterState = rasterState; mCurRasterState = rasterState;
mRasterizerStateIsDirty = false; mRasterizerStateIsDirty = false;
...@@ -492,7 +599,7 @@ void StateManager11::setScissorRectangle(const gl::Rectangle &scissor, bool enab ...@@ -492,7 +599,7 @@ void StateManager11::setScissorRectangle(const gl::Rectangle &scissor, bool enab
rect.right = scissor.x + std::max(0, scissor.width); rect.right = scissor.x + std::max(0, scissor.width);
rect.bottom = scissor.y + std::max(0, scissor.height); rect.bottom = scissor.y + std::max(0, scissor.height);
mDeviceContext->RSSetScissorRects(1, &rect); mRenderer->getDeviceContext()->RSSetScissorRects(1, &rect);
} }
mCurScissorRect = scissor; mCurScissorRect = scissor;
...@@ -516,7 +623,7 @@ void StateManager11::setViewport(const gl::Caps *caps, ...@@ -516,7 +623,7 @@ void StateManager11::setViewport(const gl::Caps *caps,
int dxMinViewportBoundsX = -dxMaxViewportBoundsX; int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
int dxMinViewportBoundsY = -dxMaxViewportBoundsY; int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
if (mRenderer11DeviceCaps->featureLevel <= D3D_FEATURE_LEVEL_9_3) if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
{ {
// Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget. // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget.
dxMaxViewportBoundsX = static_cast<int>(mViewportBounds.width); dxMaxViewportBoundsX = static_cast<int>(mViewportBounds.width);
...@@ -538,7 +645,7 @@ void StateManager11::setViewport(const gl::Caps *caps, ...@@ -538,7 +645,7 @@ void StateManager11::setViewport(const gl::Caps *caps,
dxViewport.MinDepth = actualZNear; dxViewport.MinDepth = actualZNear;
dxViewport.MaxDepth = actualZFar; dxViewport.MaxDepth = actualZFar;
mDeviceContext->RSSetViewports(1, &dxViewport); mRenderer->getDeviceContext()->RSSetViewports(1, &dxViewport);
mCurViewport = viewport; mCurViewport = viewport;
mCurNear = actualZNear; mCurNear = actualZNear;
...@@ -546,7 +653,7 @@ void StateManager11::setViewport(const gl::Caps *caps, ...@@ -546,7 +653,7 @@ void StateManager11::setViewport(const gl::Caps *caps,
// On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders
// using viewAdjust (like the D3D9 renderer). // using viewAdjust (like the D3D9 renderer).
if (mRenderer11DeviceCaps->featureLevel <= D3D_FEATURE_LEVEL_9_3) if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
{ {
mVertexConstants.viewAdjust[0] = static_cast<float>((viewport.width - dxViewportWidth) + mVertexConstants.viewAdjust[0] = static_cast<float>((viewport.width - dxViewportWidth) +
2 * (viewport.x - dxViewportTopLeftX)) / 2 * (viewport.x - dxViewportTopLeftX)) /
...@@ -584,4 +691,276 @@ void StateManager11::setViewport(const gl::Caps *caps, ...@@ -584,4 +691,276 @@ void StateManager11::setViewport(const gl::Caps *caps,
mViewportStateIsDirty = false; mViewportStateIsDirty = false;
} }
void StateManager11::invalidateRenderTarget()
{
for (auto &appliedRTV : mAppliedRTVs)
{
appliedRTV = angle::DirtyPointer;
}
mAppliedDSV = angle::DirtyPointer;
}
void StateManager11::invalidateEverything()
{
mBlendStateIsDirty = true;
mDepthStencilStateIsDirty = true;
mRasterizerStateIsDirty = true;
mScissorStateIsDirty = true;
mViewportStateIsDirty = true;
// 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.
mCurVertexSRVs.clear();
mCurPixelSRVs.clear();
invalidateRenderTarget();
}
bool StateManager11::setRenderTargets(const RenderTargetArray &renderTargets,
ID3D11DepthStencilView *depthStencil)
{
// TODO(jmadill): Use context caps?
UINT drawBuffers = mRenderer->getRendererCaps().maxDrawBuffers;
// Apply the render target and depth stencil
size_t arraySize = sizeof(uintptr_t) * drawBuffers;
if (memcmp(renderTargets.data(), mAppliedRTVs.data(), arraySize) == 0 &&
reinterpret_cast<uintptr_t>(depthStencil) == mAppliedDSV)
{
return false;
}
// The D3D11 blend state is heavily dependent on the current render target.
mBlendStateIsDirty = true;
for (UINT rtIndex = 0; rtIndex < drawBuffers; rtIndex++)
{
mAppliedRTVs[rtIndex] = reinterpret_cast<uintptr_t>(renderTargets[rtIndex]);
}
mAppliedDSV = reinterpret_cast<uintptr_t>(depthStencil);
mRenderer->getDeviceContext()->OMSetRenderTargets(drawBuffers, renderTargets.data(),
depthStencil);
return true;
}
void StateManager11::setRenderTarget(ID3D11RenderTargetView *renderTarget,
ID3D11DepthStencilView *depthStencil)
{
mRenderer->getDeviceContext()->OMSetRenderTargets(1, &renderTarget, depthStencil);
}
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)
{
if (rangeStart == rangeEnd)
{
return gl::Error(GL_NO_ERROR);
}
auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
gl::Range<size_t> clearRange(rangeStart, rangeStart);
clearRange.extend(std::min(rangeEnd, currentSRVs.highestUsed()));
if (clearRange.empty())
{
return gl::Error(GL_NO_ERROR);
}
auto deviceContext = mRenderer->getDeviceContext();
if (samplerType == gl::SAMPLER_VERTEX)
{
deviceContext->VSSetShaderResources(static_cast<unsigned int>(rangeStart),
static_cast<unsigned int>(rangeEnd - rangeStart),
&mNullSRVs[0]);
}
else
{
deviceContext->PSSetShaderResources(static_cast<unsigned int>(rangeStart),
static_cast<unsigned int>(rangeEnd - rangeStart),
&mNullSRVs[0]);
}
for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; ++samplerIndex)
{
currentSRVs.update(samplerIndex, nullptr);
}
return gl::Error(GL_NO_ERROR);
}
void StateManager11::unsetConflictingSRVs(gl::SamplerType samplerType,
uintptr_t resource,
const gl::ImageIndex &index)
{
auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
{
auto &record = currentSRVs[resourceIndex];
if (record.srv && record.resource == resource &&
ImageIndexConflictsWithSRV(index, record.desc))
{
setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL);
}
}
}
void StateManager11::initialize(const gl::Caps &caps)
{
mCurVertexSRVs.initialize(caps.maxVertexTextureImageUnits);
mCurPixelSRVs.initialize(caps.maxTextureImageUnits);
// Initialize cached NULL SRV block
mNullSRVs.resize(caps.maxTextureImageUnits, nullptr);
}
gl::Error StateManager11::syncFramebuffer(const gl::Framebuffer *framebuffer)
{
// Get the color render buffer and serial
// Also extract the render target dimensions and view
unsigned int renderTargetWidth = 0;
unsigned int renderTargetHeight = 0;
DXGI_FORMAT renderTargetFormat = DXGI_FORMAT_UNKNOWN;
RenderTargetArray framebufferRTVs;
bool missingColorRenderTarget = true;
framebufferRTVs.fill(nullptr);
const Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
const gl::AttachmentList &colorbuffers = framebuffer11->getColorAttachmentsForRender();
for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
{
const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
if (colorbuffer)
{
// the draw buffer must be either "none", "back" for the default buffer or the same
// index as this color (in order)
// check for zero-sized default framebuffer, which is a special case.
// in this case we do not wish to modify any state and just silently return false.
// this will not report any gl error but will cause the calling method to return.
const gl::Extents &size = colorbuffer->getSize();
if (size.width == 0 || size.height == 0)
{
return gl::Error(GL_NO_ERROR);
}
// Extract the render target dimensions and view
RenderTarget11 *renderTarget = NULL;
gl::Error error = colorbuffer->getRenderTarget(&renderTarget);
if (error.isError())
{
return error;
}
ASSERT(renderTarget);
framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
ASSERT(framebufferRTVs[colorAttachment]);
if (missingColorRenderTarget)
{
renderTargetWidth = renderTarget->getWidth();
renderTargetHeight = renderTarget->getHeight();
renderTargetFormat = renderTarget->getDXGIFormat();
missingColorRenderTarget = false;
}
// Unbind render target SRVs from the shader here to prevent D3D11 warnings.
if (colorbuffer->type() == GL_TEXTURE)
{
uintptr_t rtResource =
reinterpret_cast<uintptr_t>(GetViewResource(framebufferRTVs[colorAttachment]));
const gl::ImageIndex &index = colorbuffer->getTextureImageIndex();
// The index doesn't need to be corrected for the small compressed texture
// workaround
// because a rendertarget is never compressed.
unsetConflictingSRVs(gl::SAMPLER_VERTEX, rtResource, index);
unsetConflictingSRVs(gl::SAMPLER_PIXEL, rtResource, index);
}
}
}
// Get the depth stencil buffers
ID3D11DepthStencilView *framebufferDSV = NULL;
const gl::FramebufferAttachment *depthStencil = framebuffer->getDepthOrStencilbuffer();
if (depthStencil)
{
RenderTarget11 *depthStencilRenderTarget = NULL;
gl::Error error = depthStencil->getRenderTarget(&depthStencilRenderTarget);
if (error.isError())
{
return error;
}
ASSERT(depthStencilRenderTarget);
framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
ASSERT(framebufferDSV);
// If there is no render buffer, the width, height and format values come from
// the depth stencil
if (missingColorRenderTarget)
{
renderTargetWidth = depthStencilRenderTarget->getWidth();
renderTargetHeight = depthStencilRenderTarget->getHeight();
}
// Unbind render target SRVs from the shader here to prevent D3D11 warnings.
if (depthStencil->type() == GL_TEXTURE)
{
uintptr_t depthStencilResource =
reinterpret_cast<uintptr_t>(GetViewResource(framebufferDSV));
const gl::ImageIndex &index = depthStencil->getTextureImageIndex();
// The index doesn't need to be corrected for the small compressed texture workaround
// because a rendertarget is never compressed.
unsetConflictingSRVs(gl::SAMPLER_VERTEX, depthStencilResource, index);
unsetConflictingSRVs(gl::SAMPLER_PIXEL, depthStencilResource, index);
}
}
if (setRenderTargets(framebufferRTVs, framebufferDSV))
{
setViewportBounds(renderTargetWidth, renderTargetHeight);
}
gl::Error error = framebuffer11->invalidateSwizzles();
if (error.isError())
{
return error;
}
return gl::Error(GL_NO_ERROR);
}
} // namespace rx } // namespace rx
...@@ -9,10 +9,13 @@ ...@@ -9,10 +9,13 @@
#ifndef LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_ #ifndef LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_
#define LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_ #define LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_
#include <array>
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/Data.h" #include "libANGLE/Data.h"
#include "libANGLE/State.h" #include "libANGLE/State.h"
#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h" #include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h"
namespace rx namespace rx
...@@ -24,13 +27,10 @@ struct Renderer11DeviceCaps; ...@@ -24,13 +27,10 @@ struct Renderer11DeviceCaps;
class StateManager11 final : angle::NonCopyable class StateManager11 final : angle::NonCopyable
{ {
public: public:
StateManager11(); StateManager11(Renderer11 *renderer);
~StateManager11(); ~StateManager11();
void initialize(ID3D11DeviceContext *deviceContext, void initialize(const gl::Caps &caps);
RenderStateCache *stateCache,
Renderer11DeviceCaps *renderer11DeviceCaps);
void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits); void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits);
gl::Error setBlendState(const gl::Framebuffer *framebuffer, gl::Error setBlendState(const gl::Framebuffer *framebuffer,
...@@ -46,19 +46,33 @@ class StateManager11 final : angle::NonCopyable ...@@ -46,19 +46,33 @@ class StateManager11 final : angle::NonCopyable
void setViewport(const gl::Caps *caps, const gl::Rectangle &viewport, float zNear, float zFar); void setViewport(const gl::Caps *caps, const gl::Rectangle &viewport, float zNear, float zFar);
void forceSetBlendState() { mBlendStateIsDirty = true; }
void forceSetDepthStencilState() { mDepthStencilStateIsDirty = true; }
void forceSetRasterState() { mRasterizerStateIsDirty = true; }
void forceSetScissorState() { mScissorStateIsDirty = true; }
void forceSetViewportState() { mViewportStateIsDirty = true; }
void setViewportBounds(const int width, const int height);
const dx_VertexConstants &getVertexConstants() const { return mVertexConstants; } const dx_VertexConstants &getVertexConstants() const { return mVertexConstants; }
const dx_PixelConstants &getPixelConstants() const { return mPixelConstants; } const dx_PixelConstants &getPixelConstants() const { return mPixelConstants; }
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize); void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
void setShaderResource(gl::SamplerType shaderType,
UINT resourceSlot,
ID3D11ShaderResourceView *srv);
gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd);
gl::Error syncFramebuffer(const gl::Framebuffer *framebuffer);
void invalidateRenderTarget();
void invalidateEverything();
bool setRenderTargets(const RenderTargetArray &renderTargets,
ID3D11DepthStencilView *depthStencil);
void setRenderTarget(ID3D11RenderTargetView *renderTarget,
ID3D11DepthStencilView *depthStencil);
private: private:
void unsetConflictingSRVs(gl::SamplerType shaderType,
uintptr_t resource,
const gl::ImageIndex &index);
void setViewportBounds(const int width, const int height);
Renderer11 *mRenderer;
// Blend State // Blend State
bool mBlendStateIsDirty; bool mBlendStateIsDirty;
// TODO(dianx) temporary representation of a dirty bit. once we move enough states in, // TODO(dianx) temporary representation of a dirty bit. once we move enough states in,
...@@ -98,9 +112,50 @@ class StateManager11 final : angle::NonCopyable ...@@ -98,9 +112,50 @@ class StateManager11 final : angle::NonCopyable
// Render target variables // Render target variables
gl::Extents mViewportBounds; gl::Extents mViewportBounds;
Renderer11DeviceCaps *mRenderer11DeviceCaps; // EGL_ANGLE_experimental_present_path variables
ID3D11DeviceContext *mDeviceContext; bool mCurPresentPathFastEnabled;
RenderStateCache *mStateCache; int mCurPresentPathFastColorBufferHeight;
// Current RenderTarget state
std::array<uintptr_t, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS> mAppliedRTVs;
uintptr_t mAppliedDSV;
// Currently applied textures
struct SRVRecord
{
uintptr_t srv;
uintptr_t resource;
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
};
// A cache of current SRVs that also tracks the highest 'used' (non-NULL) SRV
// We might want to investigate a more robust approach that is also fast when there's
// a large gap between used SRVs (e.g. if SRV 0 and 7 are non-NULL, this approach will
// waste time on SRVs 1-6.)
class SRVCache : angle::NonCopyable
{
public:
SRVCache() : mHighestUsedSRV(0) {}
void initialize(size_t size) { mCurrentSRVs.resize(size); }
size_t size() const { return mCurrentSRVs.size(); }
size_t highestUsed() const { return mHighestUsedSRV; }
const SRVRecord &operator[](size_t index) const { return mCurrentSRVs[index]; }
void clear();
void update(size_t resourceIndex, ID3D11ShaderResourceView *srv);
private:
std::vector<SRVRecord> mCurrentSRVs;
size_t mHighestUsedSRV;
};
SRVCache mCurVertexSRVs;
SRVCache mCurPixelSRVs;
// A block of NULL pointers, cached so we don't re-allocate every draw call
std::vector<ID3D11ShaderResourceView *> mNullSRVs;
}; };
} // namespace rx } // namespace rx
......
...@@ -746,7 +746,8 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, ...@@ -746,7 +746,8 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width,
deviceContext->RSSetViewports(1, &viewport); deviceContext->RSSetViewports(1, &viewport);
// Apply textures // Apply textures
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView); auto stateManager = mRenderer->getStateManager();
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView);
deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler); deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler);
// Draw // Draw
...@@ -755,7 +756,7 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, ...@@ -755,7 +756,7 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width,
// Rendering to the swapchain is now complete. Now we can call Present(). // 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 // 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. // cleanup is caught under the current eglSwapBuffers() PIX/Graphics Diagnostics call rather than the next one.
mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets(); mRenderer->unapplyRenderTargets();
mRenderer->markAllStateDirty(); mRenderer->markAllStateDirty();
...@@ -803,7 +804,7 @@ EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height) ...@@ -803,7 +804,7 @@ EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height)
// Some swapping mechanisms such as DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL unbind the current render // Some swapping mechanisms such as DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL unbind the current render
// target. Mark it dirty. // target. Mark it dirty.
mRenderer->markRenderTargetStateDirty(); mRenderer->getStateManager()->invalidateRenderTarget();
if (result == DXGI_ERROR_DEVICE_REMOVED) if (result == DXGI_ERROR_DEVICE_REMOVED)
{ {
......
...@@ -10,13 +10,14 @@ ...@@ -10,13 +10,14 @@
#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_ #ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
#define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_ #define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
#include <array>
#include <vector>
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h"
#include <vector>
namespace gl namespace gl
{ {
class FramebufferAttachment; class FramebufferAttachment;
...@@ -28,6 +29,8 @@ class RenderTarget11; ...@@ -28,6 +29,8 @@ class RenderTarget11;
struct WorkaroundsD3D; struct WorkaroundsD3D;
struct Renderer11DeviceCaps; struct Renderer11DeviceCaps;
using RenderTargetArray = std::array<ID3D11RenderTargetView *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
namespace gl_d3d11 namespace gl_d3d11
{ {
......
...@@ -2007,14 +2007,14 @@ void Renderer9::markAllStateDirty() ...@@ -2007,14 +2007,14 @@ void Renderer9::markAllStateDirty()
for (unsigned int i = 0; i < mCurVertexTextures.size(); i++) for (unsigned int i = 0; i < mCurVertexTextures.size(); i++)
{ {
mCurVertexSamplerStates[i].forceSet = true; mCurVertexSamplerStates[i].forceSet = true;
mCurVertexTextures[i] = DirtyPointer; mCurVertexTextures[i] = angle::DirtyPointer;
} }
ASSERT(mCurPixelSamplerStates.size() == mCurPixelTextures.size()); ASSERT(mCurPixelSamplerStates.size() == mCurPixelTextures.size());
for (unsigned int i = 0; i < mCurPixelSamplerStates.size(); i++) for (unsigned int i = 0; i < mCurPixelSamplerStates.size(); i++)
{ {
mCurPixelSamplerStates[i].forceSet = true; mCurPixelSamplerStates[i].forceSet = true;
mCurPixelTextures[i] = DirtyPointer; mCurPixelTextures[i] = angle::DirtyPointer;
} }
mAppliedIBSerial = 0; mAppliedIBSerial = 0;
......
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