Commit 5aeed4cc by Dian Xiang Committed by Jamie Madill

Using dirty bit notification for D3D9 viewport state

BUG=angleproject:1249 This is a continuation of D3D dirty bit refactor for D3D9 performance enhancements Change-Id: Iedd7eb003981cac7f81a58560cb326760f01c06a Reviewed-on: https://chromium-review.googlesource.com/317313Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tryjob-Request: Dian Xiang <dianx@google.com> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent fecbed9f
......@@ -956,84 +956,8 @@ void Renderer9::setViewport(const gl::Caps *caps,
GLenum frontFace,
bool ignoreViewport)
{
int renderTargetWidth = mStateManager.getRenderTargetWidth();
int renderTargetHeight = mStateManager.getRenderTargetHeight();
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>(renderTargetWidth);
actualViewport.height = static_cast<int>(renderTargetHeight);
actualZNear = 0.0f;
actualZFar = 1.0f;
}
D3DVIEWPORT9 dxViewport;
dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast<int>(renderTargetWidth));
dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast<int>(renderTargetHeight));
dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(renderTargetWidth) -
static_cast<int>(dxViewport.X));
dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(renderTargetHeight) -
static_cast<int>(dxViewport.Y));
dxViewport.MinZ = actualZNear;
dxViewport.MaxZ = actualZFar;
float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f);
bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
actualZNear != mCurNear || actualZFar != mCurFar || mCurDepthFront != depthFront;
if (viewportChanged)
{
mDevice->SetViewport(&dxViewport);
mCurViewport = actualViewport;
mCurNear = actualZNear;
mCurFar = actualZFar;
mCurDepthFront = depthFront;
dx_VertexConstants vc = {};
dx_PixelConstants pc = {};
vc.viewAdjust[0] = (float)((actualViewport.width - (int)dxViewport.Width) + 2 * (actualViewport.x - (int)dxViewport.X) - 1) / dxViewport.Width;
vc.viewAdjust[1] = (float)((actualViewport.height - (int)dxViewport.Height) + 2 * (actualViewport.y - (int)dxViewport.Y) - 1) / dxViewport.Height;
vc.viewAdjust[2] = (float)actualViewport.width / dxViewport.Width;
vc.viewAdjust[3] = (float)actualViewport.height / dxViewport.Height;
pc.viewCoords[0] = actualViewport.width * 0.5f;
pc.viewCoords[1] = actualViewport.height * 0.5f;
pc.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f);
pc.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
pc.depthFront[2] = depthFront;
vc.depthRange[0] = actualZNear;
vc.depthRange[1] = actualZFar;
vc.depthRange[2] = actualZFar - actualZNear;
pc.depthRange[0] = actualZNear;
pc.depthRange[1] = actualZFar;
pc.depthRange[2] = actualZFar - actualZNear;
if (memcmp(&vc, &mVertexConstants, sizeof(dx_VertexConstants)) != 0)
{
mVertexConstants = vc;
mDxUniformsDirty = true;
}
if (memcmp(&pc, &mPixelConstants, sizeof(dx_PixelConstants)) != 0)
{
mPixelConstants = pc;
mDxUniformsDirty = true;
}
}
mForceSetViewport = false;
mStateManager.setViewportState(caps, viewport, zNear, zFar, drawMode, frontFace,
ignoreViewport);
}
bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize)
......@@ -1221,7 +1145,6 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt
if (renderTargetChanged || !mRenderTargetDescInitialized)
{
mForceSetViewport = true;
mStateManager.forceSetBlendState();
mStateManager.forceSetScissorState();
mStateManager.setRenderTargetBounds(renderTargetWidth, renderTargetHeight);
......@@ -1709,7 +1632,7 @@ gl::Error Renderer9::applyShadersImpl(const gl::Data &data, GLenum /*drawMode*/)
if (programSerial != mAppliedProgramSerial)
{
programD3D->dirtyAllUniforms();
mDxUniformsDirty = true;
mStateManager.forceSetDXUniformsState();
mAppliedProgramSerial = programSerial;
}
......@@ -1760,12 +1683,7 @@ gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D,
}
// Driver uniforms
if (mDxUniformsDirty)
{
mDevice->SetVertexShaderConstantF(0, (float*)&mVertexConstants, sizeof(dx_VertexConstants) / sizeof(float[4]));
mDevice->SetPixelShaderConstantF(0, (float*)&mPixelConstants, sizeof(dx_PixelConstants) / sizeof(float[4]));
mDxUniformsDirty = false;
}
mStateManager.setShaderConstants();
return gl::Error(GL_NO_ERROR);
}
......@@ -2067,11 +1985,11 @@ void Renderer9::markAllStateDirty()
mDepthStencilInitialized = false;
mRenderTargetDescInitialized = false;
mForceSetViewport = true;
mStateManager.forceSetRasterState();
mStateManager.forceSetDepthStencilState();
mStateManager.forceSetBlendState();
mStateManager.forceSetScissorState();
mStateManager.forceSetViewportState();
ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size());
for (unsigned int i = 0; i < mCurVertexTextures.size(); i++)
......@@ -2091,7 +2009,7 @@ void Renderer9::markAllStateDirty()
mAppliedVertexShader = NULL;
mAppliedPixelShader = NULL;
mAppliedProgramSerial = 0;
mDxUniformsDirty = true;
mStateManager.forceSetDXUniformsState();
mVertexDeclarationCache.markStateDirty();
}
......
......@@ -336,12 +336,6 @@ class Renderer9 : public RendererD3D
StateManager9 mStateManager;
bool mForceSetViewport;
gl::Rectangle mCurViewport;
float mCurNear;
float mCurFar;
float mCurDepthFront;
// Currently applied sampler states
struct CurSamplerState
{
......@@ -363,10 +357,6 @@ class Renderer9 : public RendererD3D
IDirect3DPixelShader9 *mAppliedPixelShader;
unsigned int mAppliedProgramSerial;
dx_VertexConstants mVertexConstants;
dx_PixelConstants mPixelConstants;
bool mDxUniformsDirty;
// A pool of event queries that are currently unused.
std::vector<IDirect3DQuery9*> mEventQueryPool;
VertexShaderCache mVertexShaderCache;
......
......@@ -8,6 +8,7 @@
#include "libANGLE/renderer/d3d/d3d9/StateManager9.h"
#include "common/BitSetIterator.h"
#include "common/utilities.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h"
......@@ -29,6 +30,11 @@ StateManager9::StateManager9(Renderer9 *renderer9)
mCurStencilSize(0),
mCurScissorRect(),
mCurScissorEnabled(false),
mCurViewport(),
mCurNear(0.0f),
mCurFar(0.0f),
mCurDepthFront(0.0f),
mCurIgnoreViewport(false),
mRenderer9(renderer9),
mDirtyBits()
{
......@@ -81,6 +87,16 @@ void StateManager9::forceSetScissorState()
mDirtyBits |= mScissorStateDirtyBits;
}
void StateManager9::forceSetViewportState()
{
mForceSetViewport = true;
}
void StateManager9::forceSetDXUniformsState()
{
mDxUniformsDirty = true;
}
void StateManager9::updateStencilSizeIfChanged(bool depthStencilInitialized,
unsigned int stencilSize)
{
......@@ -177,6 +193,9 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits
if (state.getRasterizerState().frontFace != mCurRasterState.frontFace)
{
mDirtyBits.set(DIRTY_BIT_CULL_MODE);
// Viewport state depends on rasterizer.frontface
mDirtyBits.set(DIRTY_BIT_VIEWPORT);
}
break;
case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
......@@ -302,6 +321,18 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits
mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT);
}
break;
case gl::State::DIRTY_BIT_DEPTH_RANGE:
if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar)
{
mDirtyBits.set(DIRTY_BIT_VIEWPORT);
}
break;
case gl::State::DIRTY_BIT_VIEWPORT:
if (state.getViewport() != mCurViewport)
{
mDirtyBits.set(DIRTY_BIT_VIEWPORT);
}
break;
default:
break;
}
......@@ -405,6 +436,113 @@ gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState,
return gl::Error(GL_NO_ERROR);
}
void StateManager9::setViewportState(const gl::Caps *caps,
const gl::Rectangle &viewport,
float zNear,
float zFar,
GLenum drawMode,
GLenum frontFace,
bool ignoreViewport)
{
if (!mDirtyBits.test(DIRTY_BIT_VIEWPORT) && mCurIgnoreViewport == ignoreViewport)
return;
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>(mRenderTargetBounds.width);
actualViewport.height = static_cast<int>(mRenderTargetBounds.height);
actualZNear = 0.0f;
actualZFar = 1.0f;
}
D3DVIEWPORT9 dxViewport;
dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetBounds.width));
dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetBounds.height));
dxViewport.Width =
gl::clamp(actualViewport.width, 0,
static_cast<int>(mRenderTargetBounds.width) - static_cast<int>(dxViewport.X));
dxViewport.Height =
gl::clamp(actualViewport.height, 0,
static_cast<int>(mRenderTargetBounds.height) - static_cast<int>(dxViewport.Y));
dxViewport.MinZ = actualZNear;
dxViewport.MaxZ = actualZFar;
float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f);
mRenderer9->getDevice()->SetViewport(&dxViewport);
mCurViewport = actualViewport;
mCurNear = actualZNear;
mCurFar = actualZFar;
mCurDepthFront = depthFront;
mCurIgnoreViewport = ignoreViewport;
// Setting shader constants
dx_VertexConstants vc = {};
dx_PixelConstants pc = {};
vc.viewAdjust[0] =
static_cast<float>((actualViewport.width - static_cast<int>(dxViewport.Width)) +
2 * (actualViewport.x - static_cast<int>(dxViewport.X)) - 1) /
dxViewport.Width;
vc.viewAdjust[1] =
static_cast<float>((actualViewport.height - static_cast<int>(dxViewport.Height)) +
2 * (actualViewport.y - static_cast<int>(dxViewport.Y)) - 1) /
dxViewport.Height;
vc.viewAdjust[2] = static_cast<float>(actualViewport.width) / dxViewport.Width;
vc.viewAdjust[3] = static_cast<float>(actualViewport.height) / dxViewport.Height;
pc.viewCoords[0] = actualViewport.width * 0.5f;
pc.viewCoords[1] = actualViewport.height * 0.5f;
pc.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f);
pc.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
pc.depthFront[2] = depthFront;
vc.depthRange[0] = actualZNear;
vc.depthRange[1] = actualZFar;
vc.depthRange[2] = actualZFar - actualZNear;
pc.depthRange[0] = actualZNear;
pc.depthRange[1] = actualZFar;
pc.depthRange[2] = actualZFar - actualZNear;
if (memcmp(&vc, &mVertexConstants, sizeof(dx_VertexConstants)) != 0)
{
mVertexConstants = vc;
mDxUniformsDirty = true;
}
if (memcmp(&pc, &mPixelConstants, sizeof(dx_PixelConstants)) != 0)
{
mPixelConstants = pc;
mDxUniformsDirty = true;
}
mForceSetViewport = false;
}
void StateManager9::setShaderConstants()
{
if (!mDxUniformsDirty)
return;
IDirect3DDevice9 *device = mRenderer9->getDevice();
device->SetVertexShaderConstantF(0, reinterpret_cast<float *>(&mVertexConstants),
sizeof(dx_VertexConstants) / sizeof(float[4]));
device->SetPixelShaderConstantF(0, reinterpret_cast<float *>(&mPixelConstants),
sizeof(dx_PixelConstants) / sizeof(float[4]));
mDxUniformsDirty = false;
}
// This is separate from the main state loop because other functions
// outside call only setScissorState to update scissor state
void StateManager9::setScissorState(const gl::Rectangle &scissor, bool enabled)
......@@ -420,6 +558,7 @@ void StateManager9::setRenderTargetBounds(size_t width, size_t height)
{
mRenderTargetBounds.width = (int)width;
mRenderTargetBounds.height = (int)height;
forceSetViewportState();
}
void StateManager9::setScissorEnabled(bool scissorEnabled)
......
......@@ -12,6 +12,7 @@
#include "libANGLE/angletypes.h"
#include "libANGLE/Data.h"
#include "libANGLE/State.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
namespace rx
{
......@@ -28,14 +29,26 @@ class StateManager9 final : angle::NonCopyable
gl::Error setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask);
void setScissorState(const gl::Rectangle &scissor, bool enabled);
void setViewportState(const gl::Caps *caps,
const gl::Rectangle &viewport,
float zNear,
float zFar,
GLenum drawMode,
GLenum frontFace,
bool ignoreViewport);
void setShaderConstants();
void forceSetBlendState();
void forceSetRasterState();
void forceSetDepthStencilState();
void forceSetScissorState();
void forceSetViewportState();
void forceSetDXUniformsState();
void updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize);
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
void setRenderTargetBounds(size_t width, size_t height);
int getRenderTargetWidth() const { return mRenderTargetBounds.width; }
......@@ -121,6 +134,9 @@ class StateManager9 final : angle::NonCopyable
DIRTY_BIT_SCISSOR_ENABLED,
DIRTY_BIT_SCISSOR_RECT,
// Viewport dirty bits
DIRTY_BIT_VIEWPORT,
DIRTY_BIT_MAX
};
......@@ -151,6 +167,18 @@ class StateManager9 final : angle::NonCopyable
gl::Extents mRenderTargetBounds;
DirtyBits mScissorStateDirtyBits;
// Currently applied viewport states
bool mForceSetViewport;
gl::Rectangle mCurViewport;
float mCurNear;
float mCurFar;
float mCurDepthFront;
bool mCurIgnoreViewport;
dx_VertexConstants mVertexConstants;
dx_PixelConstants mPixelConstants;
bool mDxUniformsDirty;
// FIXME: Unsupported by D3D9
static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK;
......
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