Commit 4028159e by Dian Xiang

Using dirty bit notification for D3D11 viewport state

BUG=angleproject:1161 This is a continuation of the dirty bit refactor Change-Id: I101f415094dd406f6b0a40cb260f1cbbfec7b62c Reviewed-on: https://chromium-review.googlesource.com/313249Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tryjob-Request: Dian Xiang <dianx@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarDian Xiang <dianx@google.com>
parent 29a65546
......@@ -587,8 +587,7 @@ Error Framebuffer::clearBufferfv(Context *context,
// Sync the clear state
context->syncRendererState(context->getState().clearStateBitMask());
return mImpl->clearBufferfv(context->getState(), buffer, drawbuffer, values);
return mImpl->clearBufferfv(context->getData(), buffer, drawbuffer, values);
}
Error Framebuffer::clearBufferuiv(Context *context,
......@@ -604,7 +603,7 @@ Error Framebuffer::clearBufferuiv(Context *context,
// Sync the clear state
context->syncRendererState(context->getState().clearStateBitMask());
return mImpl->clearBufferuiv(context->getState(), buffer, drawbuffer, values);
return mImpl->clearBufferuiv(context->getData(), buffer, drawbuffer, values);
}
Error Framebuffer::clearBufferiv(Context *context,
......@@ -620,7 +619,7 @@ Error Framebuffer::clearBufferiv(Context *context,
// Sync the clear state
context->syncRendererState(context->getState().clearStateBitMask());
return mImpl->clearBufferiv(context->getState(), buffer, drawbuffer, values);
return mImpl->clearBufferiv(context->getData(), buffer, drawbuffer, values);
}
Error Framebuffer::clearBufferfi(Context *context,
......@@ -637,7 +636,7 @@ Error Framebuffer::clearBufferfi(Context *context,
// Sync the clear state
context->syncRendererState(context->getState().clearStateBitMask());
return mImpl->clearBufferfi(context->getState(), buffer, drawbuffer, depth, stencil);
return mImpl->clearBufferfi(context->getData(), buffer, drawbuffer, depth, stencil);
}
GLenum Framebuffer::getImplementationColorReadFormat() const
......
......@@ -44,10 +44,23 @@ class FramebufferImpl : angle::NonCopyable
virtual gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) = 0;
virtual gl::Error clear(const gl::Data &data, GLbitfield mask) = 0;
virtual gl::Error clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) = 0;
virtual gl::Error clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) = 0;
virtual gl::Error clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) = 0;
virtual gl::Error clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) = 0;
virtual gl::Error clearBufferfv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLfloat *values) = 0;
virtual gl::Error clearBufferuiv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLuint *values) = 0;
virtual gl::Error clearBufferiv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLint *values) = 0;
virtual gl::Error clearBufferfi(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
GLfloat depth,
GLint stencil) = 0;
virtual GLenum getImplementationColorReadFormat() const = 0;
virtual GLenum getImplementationColorReadType() const = 0;
......
......@@ -36,10 +36,10 @@ class MockFramebufferImpl : public rx::FramebufferImpl
MOCK_METHOD3(invalidateSub, gl::Error(size_t, const GLenum *, const gl::Rectangle &));
MOCK_METHOD2(clear, gl::Error(const gl::Data &, GLbitfield));
MOCK_METHOD4(clearBufferfv, gl::Error(const gl::State &, GLenum, GLint, const GLfloat *));
MOCK_METHOD4(clearBufferuiv, gl::Error(const gl::State &, GLenum, GLint, const GLuint *));
MOCK_METHOD4(clearBufferiv, gl::Error(const gl::State &, GLenum, GLint, const GLint *));
MOCK_METHOD5(clearBufferfi, gl::Error(const gl::State &, GLenum, GLint, GLfloat, GLint));
MOCK_METHOD4(clearBufferfv, gl::Error(const gl::Data &, GLenum, GLint, const GLfloat *));
MOCK_METHOD4(clearBufferuiv, gl::Error(const gl::Data &, GLenum, GLint, const GLuint *));
MOCK_METHOD4(clearBufferiv, gl::Error(const gl::Data &, GLenum, GLint, const GLint *));
MOCK_METHOD5(clearBufferfi, gl::Error(const gl::Data &, GLenum, GLint, GLfloat, GLint));
MOCK_CONST_METHOD0(getImplementationColorReadFormat, GLenum());
MOCK_CONST_METHOD0(getImplementationColorReadType, GLenum());
......
......@@ -125,13 +125,16 @@ gl::Error FramebufferD3D::clear(const gl::Data &data, GLbitfield mask)
{
const gl::State &state = *data.state;
ClearParameters clearParams = GetClearParameters(state, mask);
return clear(state, clearParams);
return clear(data, clearParams);
}
gl::Error FramebufferD3D::clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values)
gl::Error FramebufferD3D::clearBufferfv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLfloat *values)
{
// glClearBufferfv can be called to clear the color buffer or depth buffer
ClearParameters clearParams = GetClearParameters(state, 0);
ClearParameters clearParams = GetClearParameters(*data.state, 0);
if (buffer == GL_COLOR)
{
......@@ -149,13 +152,16 @@ gl::Error FramebufferD3D::clearBufferfv(const gl::State &state, GLenum buffer, G
clearParams.depthClearValue = values[0];
}
return clear(state, clearParams);
return clear(data, clearParams);
}
gl::Error FramebufferD3D::clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values)
gl::Error FramebufferD3D::clearBufferuiv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLuint *values)
{
// glClearBufferuiv can only be called to clear a color buffer
ClearParameters clearParams = GetClearParameters(state, 0);
ClearParameters clearParams = GetClearParameters(*data.state, 0);
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
......@@ -163,13 +169,16 @@ gl::Error FramebufferD3D::clearBufferuiv(const gl::State &state, GLenum buffer,
clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_UNSIGNED_INT;
return clear(state, clearParams);
return clear(data, clearParams);
}
gl::Error FramebufferD3D::clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values)
gl::Error FramebufferD3D::clearBufferiv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLint *values)
{
// glClearBufferiv can be called to clear the color buffer or stencil buffer
ClearParameters clearParams = GetClearParameters(state, 0);
ClearParameters clearParams = GetClearParameters(*data.state, 0);
if (buffer == GL_COLOR)
{
......@@ -187,19 +196,23 @@ gl::Error FramebufferD3D::clearBufferiv(const gl::State &state, GLenum buffer, G
clearParams.stencilClearValue = values[1];
}
return clear(state, clearParams);
return clear(data, clearParams);
}
gl::Error FramebufferD3D::clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
gl::Error FramebufferD3D::clearBufferfi(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
GLfloat depth,
GLint stencil)
{
// glClearBufferfi can only be called to clear a depth stencil buffer
ClearParameters clearParams = GetClearParameters(state, 0);
ClearParameters clearParams = GetClearParameters(*data.state, 0);
clearParams.clearDepth = true;
clearParams.depthClearValue = depth;
clearParams.clearStencil = true;
clearParams.stencilClearValue = stencil;
return clear(state, clearParams);
return clear(data, clearParams);
}
GLenum FramebufferD3D::getImplementationColorReadFormat() const
......
......@@ -67,10 +67,23 @@ class FramebufferD3D : public FramebufferImpl
void setReadBuffer(GLenum buffer) override;
gl::Error clear(const gl::Data &data, GLbitfield mask) override;
gl::Error clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) override;
gl::Error clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) override;
gl::Error clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) override;
gl::Error clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override;
gl::Error clearBufferfv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLfloat *values) override;
gl::Error clearBufferuiv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLuint *values) override;
gl::Error clearBufferiv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLint *values) override;
gl::Error clearBufferfi(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
GLfloat depth,
GLint stencil) override;
GLenum getImplementationColorReadFormat() const override;
GLenum getImplementationColorReadType() const override;
......@@ -89,7 +102,7 @@ class FramebufferD3D : public FramebufferImpl
mutable bool mInvalidateColorAttachmentCache;
private:
virtual gl::Error clear(const gl::State &state, const ClearParameters &clearParams) = 0;
virtual gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) = 0;
virtual gl::Error readPixelsImpl(const gl::Rectangle &area,
GLenum format,
......
......@@ -358,7 +358,7 @@ gl::Error RendererD3D::applyRenderTarget(const gl::Data &data, GLenum drawMode,
float nearZ = data.state->getNearPlane();
float farZ = data.state->getFarPlane();
setViewport(data.state->getViewport(), nearZ, farZ, drawMode,
setViewport(data.caps, data.state->getViewport(), nearZ, farZ, drawMode,
data.state->getRasterizerState().frontFace, ignoreViewport);
setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled());
......
......@@ -162,7 +162,12 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
virtual gl::Error setDepthStencilState(const gl::State &glState) = 0;
virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0;
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
virtual void setViewport(const gl::Caps *caps,
const gl::Rectangle &viewport,
float zNear,
float zFar,
GLenum drawMode,
GLenum frontFace,
bool ignoreViewport) = 0;
virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0;
......
......@@ -91,7 +91,7 @@ gl::Error Framebuffer11::invalidateSwizzles() const
return gl::Error(GL_NO_ERROR);
}
gl::Error Framebuffer11::clear(const gl::State &state, const ClearParameters &clearParams)
gl::Error Framebuffer11::clear(const gl::Data &data, const ClearParameters &clearParams)
{
Clear11 *clearer = mRenderer->getClearer();
gl::Error error = clearer->clearFramebuffer(clearParams, mData);
......
......@@ -29,7 +29,7 @@ class Framebuffer11 : public FramebufferD3D
gl::Error invalidateSwizzles() const;
private:
gl::Error clear(const gl::State &state, const ClearParameters &clearParams) override;
gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) override;
gl::Error readPixelsImpl(const gl::Rectangle &area,
GLenum format,
......
......@@ -890,7 +890,7 @@ void Renderer11::initializeDevice()
ASSERT(!mPixelTransfer);
mPixelTransfer = new PixelTransfer11(this);
mStateManager.initialize(mDeviceContext, &mStateCache);
mStateManager.initialize(mDeviceContext, &mStateCache, &mRenderer11DeviceCaps);
const gl::Caps &rendererCaps = getRendererCaps();
......@@ -1444,96 +1444,15 @@ void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
mStateManager.setScissorRectangle(scissor, enabled);
}
void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
void Renderer11::setViewport(const gl::Caps *caps,
const gl::Rectangle &viewport,
float zNear,
float zFar,
GLenum drawMode,
GLenum frontFace,
bool ignoreViewport)
{
gl::Rectangle actualViewport = viewport;
float actualZNear = gl::clamp01(zNear);
float actualZFar = gl::clamp01(zFar);
if (ignoreViewport)
{
actualViewport.x = 0;
actualViewport.y = 0;
actualViewport.width = static_cast<int>(mRenderTargetDesc.width);
actualViewport.height = static_cast<int>(mRenderTargetDesc.height);
actualZNear = 0.0f;
actualZFar = 1.0f;
}
bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
actualZNear != mCurNear || actualZFar != mCurFar;
if (viewportChanged)
{
const gl::Caps& caps = getRendererCaps();
int dxMaxViewportBoundsX = static_cast<int>(caps.maxViewportWidth);
int dxMaxViewportBoundsY = static_cast<int>(caps.maxViewportHeight);
int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
// Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget.
dxMaxViewportBoundsX = static_cast<int>(mRenderTargetDesc.width);
dxMaxViewportBoundsY = static_cast<int>(mRenderTargetDesc.height);
dxMinViewportBoundsX = 0;
dxMinViewportBoundsY = 0;
}
int dxViewportTopLeftX = gl::clamp(actualViewport.x, dxMinViewportBoundsX, dxMaxViewportBoundsX);
int dxViewportTopLeftY = gl::clamp(actualViewport.y, dxMinViewportBoundsY, dxMaxViewportBoundsY);
int dxViewportWidth = gl::clamp(actualViewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX);
int dxViewportHeight = gl::clamp(actualViewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY);
D3D11_VIEWPORT dxViewport;
dxViewport.TopLeftX = static_cast<float>(dxViewportTopLeftX);
dxViewport.TopLeftY = static_cast<float>(dxViewportTopLeftY);
dxViewport.Width = static_cast<float>(dxViewportWidth);
dxViewport.Height = static_cast<float>(dxViewportHeight);
dxViewport.MinDepth = actualZNear;
dxViewport.MaxDepth = actualZFar;
mDeviceContext->RSSetViewports(1, &dxViewport);
mCurViewport = actualViewport;
mCurNear = actualZNear;
mCurFar = actualZFar;
// On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders using viewAdjust (like the D3D9 renderer).
if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
mVertexConstants.viewAdjust[0] = static_cast<float>((actualViewport.width - dxViewportWidth) + 2 * (actualViewport.x - dxViewportTopLeftX)) / dxViewport.Width;
mVertexConstants.viewAdjust[1] = static_cast<float>((actualViewport.height - dxViewportHeight) + 2 * (actualViewport.y - dxViewportTopLeftY)) / dxViewport.Height;
mVertexConstants.viewAdjust[2] = static_cast<float>(actualViewport.width) / dxViewport.Width;
mVertexConstants.viewAdjust[3] = static_cast<float>(actualViewport.height) / dxViewport.Height;
}
mPixelConstants.viewCoords[0] = actualViewport.width * 0.5f;
mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f;
mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f);
mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
// Instanced pointsprite emulation requires ViewCoords to be defined in the
// the vertex shader.
mVertexConstants.viewCoords[0] = mPixelConstants.viewCoords[0];
mVertexConstants.viewCoords[1] = mPixelConstants.viewCoords[1];
mVertexConstants.viewCoords[2] = mPixelConstants.viewCoords[2];
mVertexConstants.viewCoords[3] = mPixelConstants.viewCoords[3];
mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
mVertexConstants.depthRange[0] = actualZNear;
mVertexConstants.depthRange[1] = actualZFar;
mVertexConstants.depthRange[2] = actualZFar - actualZNear;
mPixelConstants.depthRange[0] = actualZNear;
mPixelConstants.depthRange[1] = actualZFar;
mPixelConstants.depthRange[2] = actualZFar - actualZNear;
}
mForceSetViewport = false;
mStateManager.setViewport(caps, viewport, zNear, zFar);
}
bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize)
......@@ -1675,7 +1594,6 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
{
renderTargetWidth = depthStencilRenderTarget->getWidth();
renderTargetHeight = depthStencilRenderTarget->getHeight();
renderTargetFormat = depthStencilRenderTarget->getDXGIFormat();
}
// Unbind render target SRVs from the shader here to prevent D3D11 warnings.
......@@ -1694,16 +1612,12 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
}
// Apply the render target and depth stencil
if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
if (!mDepthStencilInitialized ||
memcmp(framebufferRTVs, mAppliedRTVs, sizeof(framebufferRTVs)) != 0 ||
reinterpret_cast<uintptr_t>(framebufferDSV) != mAppliedDSV)
{
mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, framebufferRTVs, framebufferDSV);
mRenderTargetDesc.width = renderTargetWidth;
mRenderTargetDesc.height = renderTargetHeight;
mRenderTargetDesc.format = renderTargetFormat;
mForceSetViewport = true;
mStateManager.setViewportBounds(renderTargetWidth, renderTargetHeight);
mStateManager.forceSetBlendState();
if (!mDepthStencilInitialized)
......@@ -1716,7 +1630,6 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
mAppliedRTVs[rtIndex] = reinterpret_cast<uintptr_t>(framebufferRTVs[rtIndex]);
}
mAppliedDSV = reinterpret_cast<uintptr_t>(framebufferDSV);
mRenderTargetDescInitialized = true;
mDepthStencilInitialized = true;
}
......@@ -2429,23 +2342,27 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS);
}
if (memcmp(&mVertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0)
const dx_VertexConstants &vertexConstants = mStateManager.getVertexConstants();
if (memcmp(&vertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0)
{
ASSERT(mDriverConstantBufferVS != nullptr);
if (mDriverConstantBufferVS)
{
mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &mVertexConstants, 16, 0);
memcpy(&mAppliedVertexConstants, &mVertexConstants, sizeof(dx_VertexConstants));
mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &vertexConstants,
16, 0);
memcpy(&mAppliedVertexConstants, &vertexConstants, sizeof(dx_VertexConstants));
}
}
if (memcmp(&mPixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0)
const dx_PixelConstants &pixelConstants = mStateManager.getPixelConstants();
if (memcmp(&pixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0)
{
ASSERT(mDriverConstantBufferPS != nullptr);
if (mDriverConstantBufferPS)
{
mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0);
memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants));
mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &pixelConstants, 16,
0);
memcpy(&mAppliedPixelConstants, &pixelConstants, sizeof(dx_PixelConstants));
}
}
......@@ -2477,7 +2394,6 @@ void Renderer11::markAllStateDirty()
}
mAppliedDSV = DirtyPointer;
mDepthStencilInitialized = false;
mRenderTargetDescInitialized = false;
// We reset the current SRV data because it might not be in sync with D3D's state
// anymore. For example when a currently used SRV is used as an RTV, D3D silently
......@@ -2501,7 +2417,7 @@ void Renderer11::markAllStateDirty()
mStateManager.forceSetDepthStencilState();
mStateManager.forceSetRasterState();
mStateManager.forceSetScissorState();
mForceSetViewport = true;
mStateManager.forceSetViewportState();
mAppliedIB = NULL;
mAppliedIBFormat = DXGI_FORMAT_UNKNOWN;
......
......@@ -130,7 +130,12 @@ class Renderer11 : public RendererD3D
gl::Error setDepthStencilState(const gl::State &glState) override;
virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
virtual void setViewport(const gl::Caps *caps,
const gl::Rectangle &viewport,
float zNear,
float zFar,
GLenum drawMode,
GLenum frontFace,
bool ignoreViewport);
virtual bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize);
......@@ -351,15 +356,6 @@ class Renderer11 : public RendererD3D
uintptr_t mAppliedRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
uintptr_t mAppliedDSV;
bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized;
struct RenderTargetDesc
{
size_t width;
size_t height;
DXGI_FORMAT format;
};
RenderTargetDesc mRenderTargetDesc;
// Currently applied sampler states
std::vector<bool> mForceSetVertexSamplerStates;
......@@ -413,12 +409,6 @@ class Renderer11 : public RendererD3D
StateManager11 mStateManager;
// Currently applied viewport
bool mForceSetViewport;
gl::Rectangle mCurViewport;
float mCurNear;
float mCurFar;
// Currently applied primitive topology
D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology;
......@@ -444,7 +434,6 @@ class Renderer11 : public RendererD3D
uintptr_t mAppliedGeometryShader;
uintptr_t mAppliedPixelShader;
dx_VertexConstants mVertexConstants;
dx_VertexConstants mAppliedVertexConstants;
ID3D11Buffer *mDriverConstantBufferVS;
ID3D11Buffer *mCurrentVertexConstantBuffer;
......@@ -452,7 +441,6 @@ class Renderer11 : public RendererD3D
GLintptr mCurrentConstantBufferVSOffset[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
GLsizeiptr mCurrentConstantBufferVSSize[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
dx_PixelConstants mPixelConstants;
dx_PixelConstants mAppliedPixelConstants;
ID3D11Buffer *mDriverConstantBufferPS;
ID3D11Buffer *mCurrentPixelConstantBuffer;
......
......@@ -26,6 +26,12 @@ StateManager11::StateManager11()
mScissorStateIsDirty(false),
mCurScissorEnabled(false),
mCurScissorRect(),
mViewportStateIsDirty(false),
mCurViewport(),
mCurNear(0.0f),
mCurFar(0.0f),
mViewportBounds(),
mRenderer11DeviceCaps(nullptr),
mDeviceContext(nullptr),
mStateCache(nullptr)
{
......@@ -74,10 +80,13 @@ StateManager11::~StateManager11()
{
}
void StateManager11::initialize(ID3D11DeviceContext *deviceContext, RenderStateCache *stateCache)
void StateManager11::initialize(ID3D11DeviceContext *deviceContext,
RenderStateCache *stateCache,
Renderer11DeviceCaps *renderer11DeviceCaps)
{
mDeviceContext = deviceContext;
mStateCache = stateCache;
mDeviceContext = deviceContext;
mStateCache = stateCache;
mRenderer11DeviceCaps = renderer11DeviceCaps;
}
void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
......@@ -90,6 +99,16 @@ void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
}
}
void StateManager11::setViewportBounds(const int width, const int height)
{
if (mRenderer11DeviceCaps->featureLevel <= D3D_FEATURE_LEVEL_9_3 &&
(mViewportBounds.width != width || mViewportBounds.height != height))
{
mViewportBounds = gl::Extents(width, height, 1);
mViewportStateIsDirty = true;
}
}
void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
{
for (unsigned int dirtyBit : angle::IterateBitSet(dirtyBits))
......@@ -296,6 +315,18 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit
mRasterizerStateIsDirty = true;
}
break;
case gl::State::DIRTY_BIT_DEPTH_RANGE:
if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar)
{
mViewportStateIsDirty = true;
}
break;
case gl::State::DIRTY_BIT_VIEWPORT:
if (state.getViewport() != mCurViewport)
{
mViewportStateIsDirty = true;
}
break;
default:
break;
}
......@@ -464,4 +495,88 @@ void StateManager11::setScissorRectangle(const gl::Rectangle &scissor, bool enab
mScissorStateIsDirty = false;
}
void StateManager11::setViewport(const gl::Caps *caps,
const gl::Rectangle &viewport,
float zNear,
float zFar)
{
if (!mViewportStateIsDirty)
return;
float actualZNear = gl::clamp01(zNear);
float actualZFar = gl::clamp01(zFar);
int dxMaxViewportBoundsX = static_cast<int>(caps->maxViewportWidth);
int dxMaxViewportBoundsY = static_cast<int>(caps->maxViewportHeight);
int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
if (mRenderer11DeviceCaps->featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
// Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget.
dxMaxViewportBoundsX = static_cast<int>(mViewportBounds.width);
dxMaxViewportBoundsY = static_cast<int>(mViewportBounds.height);
dxMinViewportBoundsX = 0;
dxMinViewportBoundsY = 0;
}
int dxViewportTopLeftX = gl::clamp(viewport.x, dxMinViewportBoundsX, dxMaxViewportBoundsX);
int dxViewportTopLeftY = gl::clamp(viewport.y, dxMinViewportBoundsY, dxMaxViewportBoundsY);
int dxViewportWidth = gl::clamp(viewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX);
int dxViewportHeight = gl::clamp(viewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY);
D3D11_VIEWPORT dxViewport;
dxViewport.TopLeftX = static_cast<float>(dxViewportTopLeftX);
dxViewport.TopLeftY = static_cast<float>(dxViewportTopLeftY);
dxViewport.Width = static_cast<float>(dxViewportWidth);
dxViewport.Height = static_cast<float>(dxViewportHeight);
dxViewport.MinDepth = actualZNear;
dxViewport.MaxDepth = actualZFar;
mDeviceContext->RSSetViewports(1, &dxViewport);
mCurViewport = viewport;
mCurNear = actualZNear;
mCurFar = actualZFar;
// On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders
// using viewAdjust (like the D3D9 renderer).
if (mRenderer11DeviceCaps->featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
mVertexConstants.viewAdjust[0] = static_cast<float>((viewport.width - dxViewportWidth) +
2 * (viewport.x - dxViewportTopLeftX)) /
dxViewport.Width;
mVertexConstants.viewAdjust[1] = static_cast<float>((viewport.height - dxViewportHeight) +
2 * (viewport.y - dxViewportTopLeftY)) /
dxViewport.Height;
mVertexConstants.viewAdjust[2] = static_cast<float>(viewport.width) / dxViewport.Width;
mVertexConstants.viewAdjust[3] = static_cast<float>(viewport.height) / dxViewport.Height;
}
mPixelConstants.viewCoords[0] = viewport.width * 0.5f;
mPixelConstants.viewCoords[1] = viewport.height * 0.5f;
mPixelConstants.viewCoords[2] = viewport.x + (viewport.width * 0.5f);
mPixelConstants.viewCoords[3] = viewport.y + (viewport.height * 0.5f);
// Instanced pointsprite emulation requires ViewCoords to be defined in the
// the vertex shader.
mVertexConstants.viewCoords[0] = mPixelConstants.viewCoords[0];
mVertexConstants.viewCoords[1] = mPixelConstants.viewCoords[1];
mVertexConstants.viewCoords[2] = mPixelConstants.viewCoords[2];
mVertexConstants.viewCoords[3] = mPixelConstants.viewCoords[3];
mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
mVertexConstants.depthRange[0] = actualZNear;
mVertexConstants.depthRange[1] = actualZFar;
mVertexConstants.depthRange[2] = actualZFar - actualZNear;
mPixelConstants.depthRange[0] = actualZNear;
mPixelConstants.depthRange[1] = actualZFar;
mPixelConstants.depthRange[2] = actualZFar - actualZNear;
mViewportStateIsDirty = false;
}
} // namespace rx
......@@ -13,11 +13,13 @@
#include "libANGLE/Data.h"
#include "libANGLE/State.h"
#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
namespace rx
{
class Renderer11;
struct RenderTargetDesc;
struct Renderer11DeviceCaps;
class StateManager11 final : angle::NonCopyable
{
......@@ -25,7 +27,9 @@ class StateManager11 final : angle::NonCopyable
StateManager11();
~StateManager11();
void initialize(ID3D11DeviceContext *deviceContext, RenderStateCache *stateCache);
void initialize(ID3D11DeviceContext *deviceContext,
RenderStateCache *stateCache,
Renderer11DeviceCaps *renderer11DeviceCaps);
void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits);
......@@ -40,10 +44,17 @@ class StateManager11 final : angle::NonCopyable
void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
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_PixelConstants &getPixelConstants() const { return mPixelConstants; }
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
......@@ -74,6 +85,20 @@ class StateManager11 final : angle::NonCopyable
bool mCurScissorEnabled;
gl::Rectangle mCurScissorRect;
// Currently applied viewport state
bool mViewportStateIsDirty;
gl::Rectangle mCurViewport;
float mCurNear;
float mCurFar;
// Things needed in viewport state
dx_VertexConstants mVertexConstants;
dx_PixelConstants mPixelConstants;
// Render target variables
gl::Extents mViewportBounds;
Renderer11DeviceCaps *mRenderer11DeviceCaps;
ID3D11DeviceContext *mDeviceContext;
RenderStateCache *mStateCache;
};
......
......@@ -53,7 +53,7 @@ gl::Error Framebuffer9::invalidateSub(size_t, const GLenum *, const gl::Rectangl
return gl::Error(GL_NO_ERROR);
}
gl::Error Framebuffer9::clear(const gl::State &state, const ClearParameters &clearParams)
gl::Error Framebuffer9::clear(const gl::Data &data, const ClearParameters &clearParams)
{
const gl::FramebufferAttachment *colorAttachment = mData.getColorAttachment(0);
const gl::FramebufferAttachment *depthStencilAttachment = mData.getDepthOrStencilAttachment();
......@@ -64,11 +64,12 @@ gl::Error Framebuffer9::clear(const gl::State &state, const ClearParameters &cle
return error;
}
float nearZ = state.getNearPlane();
float farZ = state.getFarPlane();
mRenderer->setViewport(state.getViewport(), nearZ, farZ, GL_TRIANGLES, state.getRasterizerState().frontFace, true);
float nearZ = data.state->getNearPlane();
float farZ = data.state->getFarPlane();
mRenderer->setViewport(data.caps, data.state->getViewport(), nearZ, farZ, GL_TRIANGLES,
data.state->getRasterizerState().frontFace, true);
mRenderer->setScissorRectangle(state.getScissor(), state.isScissorTestEnabled());
mRenderer->setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled());
return mRenderer->clear(clearParams, colorAttachment, depthStencilAttachment);
}
......
......@@ -26,7 +26,7 @@ class Framebuffer9 : public FramebufferD3D
gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override;
private:
gl::Error clear(const gl::State &state, const ClearParameters &clearParams) override;
gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) override;
gl::Error readPixelsImpl(const gl::Rectangle &area,
GLenum format,
......
......@@ -1161,7 +1161,12 @@ void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
mForceSetScissor = false;
}
void Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
void Renderer9::setViewport(const gl::Caps *caps,
const gl::Rectangle &viewport,
float zNear,
float zFar,
GLenum drawMode,
GLenum frontFace,
bool ignoreViewport)
{
gl::Rectangle actualViewport = viewport;
......
......@@ -104,7 +104,12 @@ class Renderer9 : public RendererD3D
virtual gl::Error setDepthStencilState(const gl::State &glState);
virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
virtual void setViewport(const gl::Caps *caps,
const gl::Rectangle &viewport,
float zNear,
float zFar,
GLenum drawMode,
GLenum frontFace,
bool ignoreViewport);
gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
......
......@@ -213,7 +213,10 @@ gl::Error FramebufferGL::clear(const gl::Data &data, GLbitfield mask)
return gl::Error(GL_NO_ERROR);
}
gl::Error FramebufferGL::clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values)
gl::Error FramebufferGL::clearBufferfv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLfloat *values)
{
syncClearBufferState(buffer, drawbuffer);
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
......@@ -222,7 +225,10 @@ gl::Error FramebufferGL::clearBufferfv(const gl::State &state, GLenum buffer, GL
return gl::Error(GL_NO_ERROR);
}
gl::Error FramebufferGL::clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values)
gl::Error FramebufferGL::clearBufferuiv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLuint *values)
{
syncClearBufferState(buffer, drawbuffer);
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
......@@ -231,7 +237,10 @@ gl::Error FramebufferGL::clearBufferuiv(const gl::State &state, GLenum buffer, G
return gl::Error(GL_NO_ERROR);
}
gl::Error FramebufferGL::clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values)
gl::Error FramebufferGL::clearBufferiv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLint *values)
{
syncClearBufferState(buffer, drawbuffer);
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
......@@ -240,7 +249,11 @@ gl::Error FramebufferGL::clearBufferiv(const gl::State &state, GLenum buffer, GL
return gl::Error(GL_NO_ERROR);
}
gl::Error FramebufferGL::clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
gl::Error FramebufferGL::clearBufferfi(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
GLfloat depth,
GLint stencil)
{
syncClearBufferState(buffer, drawbuffer);
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
......
......@@ -49,10 +49,23 @@ class FramebufferGL : public FramebufferImpl
gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override;
gl::Error clear(const gl::Data &data, GLbitfield mask) override;
gl::Error clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) override;
gl::Error clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) override;
gl::Error clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) override;
gl::Error clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override;
gl::Error clearBufferfv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLfloat *values) override;
gl::Error clearBufferuiv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLuint *values) override;
gl::Error clearBufferiv(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
const GLint *values) override;
gl::Error clearBufferfi(const gl::Data &data,
GLenum buffer,
GLint drawbuffer,
GLfloat depth,
GLint stencil) override;
GLenum getImplementationColorReadFormat() const override;
GLenum getImplementationColorReadType() const override;
......
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