Commit 2bc94733 by Jamie Madill Committed by Commit Bot

D3D11: Minor optimizations to vertex attribute application.

Introduce a dirty bit for current value attribs, and try to speed up the check for dirty vertex attribs. This series of small optimizations gives about a 15% improvement on the draw call benchmark for the D3D11 backend with the null driver. BUG=angleproject:1155 Change-Id: Idf560efa3af62776e8bdbdf693f8b06db8792c21 Reviewed-on: https://chromium-review.googlesource.com/666048Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent f1581583
......@@ -542,6 +542,7 @@ StateManager11::StateManager11(Renderer11 *renderer)
mCurrentValueAttribs(),
mCurrentInputLayout(),
mInputLayoutIsDirty(false),
mVertexAttribsNeedTranslation(false),
mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0),
mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED),
mDirtySwizzles(false),
......@@ -976,7 +977,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
{
size_t attribIndex =
static_cast<size_t>(dirtyBit - gl::State::DIRTY_BIT_CURRENT_VALUE_0);
mDirtyCurrentValueAttribs.set(attribIndex);
invalidateCurrentValueAttrib(attribIndex);
}
break;
}
......@@ -1367,6 +1368,8 @@ void StateManager11::invalidateVertexBuffer()
gl::MAX_VERTEX_ATTRIBS);
mDirtyVertexBufferRange = gl::RangeUI(0, limit);
mInputLayoutIsDirty = true;
mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS);
invalidateVertexAttributeTranslation();
}
void StateManager11::invalidateViewport(const gl::Context *context)
......@@ -1458,6 +1461,11 @@ void StateManager11::setRenderTargets(ID3D11RenderTargetView **rtvs,
mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
}
void StateManager11::invalidateVertexAttributeTranslation()
{
mVertexAttribsNeedTranslation = true;
}
void StateManager11::onBeginQuery(Query11 *query)
{
mCurrentQueries.insert(query);
......@@ -1712,22 +1720,22 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb
void StateManager11::invalidateCurrentValueAttrib(size_t attribIndex)
{
mDirtyCurrentValueAttribs.set(attribIndex);
mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS);
}
gl::Error StateManager11::syncCurrentValueAttribs(const gl::State &state)
gl::Error StateManager11::syncCurrentValueAttribs(const gl::State &glState)
{
const auto &activeAttribsMask = state.getProgram()->getActiveAttribLocationsMask();
const auto &activeAttribsMask = glState.getProgram()->getActiveAttribLocationsMask();
const auto &dirtyActiveAttribs = (activeAttribsMask & mDirtyCurrentValueAttribs);
const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes();
const auto &vertexBindings = state.getVertexArray()->getVertexBindings();
if (!dirtyActiveAttribs.any())
{
return gl::NoError();
}
invalidateVertexBuffer();
mDirtyCurrentValueAttribs = (mDirtyCurrentValueAttribs & ~dirtyActiveAttribs);
const auto &vertexAttributes = glState.getVertexArray()->getVertexAttributes();
const auto &vertexBindings = glState.getVertexArray()->getVertexBindings();
mDirtyCurrentValueAttribs = (mDirtyCurrentValueAttribs & ~dirtyActiveAttribs);
for (auto attribIndex : dirtyActiveAttribs)
{
......@@ -1735,7 +1743,7 @@ gl::Error StateManager11::syncCurrentValueAttribs(const gl::State &state)
continue;
const auto *attrib = &vertexAttributes[attribIndex];
const auto &currentValue = state.getVertexAttribCurrentValue(attribIndex);
const auto &currentValue = glState.getVertexAttribCurrentValue(attribIndex);
auto currentValueAttrib = &mCurrentValueAttribs[attribIndex];
currentValueAttrib->currentValueType = currentValue.Type;
currentValueAttrib->attribute = attrib;
......@@ -1940,6 +1948,9 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod
case DIRTY_BIT_SHADERS:
ANGLE_TRY(syncProgram(context, drawMode));
break;
case DIRTY_BIT_CURRENT_VALUE_ATTRIBS:
ANGLE_TRY(syncCurrentValueAttribs(glState));
break;
default:
UNREACHABLE();
break;
......@@ -2481,14 +2492,15 @@ gl::Error StateManager11::applyVertexBuffer(const gl::Context *context,
const auto &vertexArray = state.getVertexArray();
auto *vertexArray11 = GetImplAs<VertexArray11>(vertexArray);
if (vertexArray11->hasDirtyOrDynamicAttrib(context))
if (mVertexAttribsNeedTranslation)
{
ANGLE_TRY(vertexArray11->updateDirtyAndDynamicAttribs(context, &mVertexDataManager, first,
count, instances));
invalidateVertexBuffer();
}
mInputLayoutIsDirty = true;
ANGLE_TRY(syncCurrentValueAttribs(state));
// Determine if we need to update attribs on the next draw.
mVertexAttribsNeedTranslation = (vertexArray11->hasDynamicAttrib(context));
}
if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != first)
{
......
......@@ -182,6 +182,9 @@ class StateManager11 final : angle::NonCopyable
// Called by the Framebuffer11 and VertexArray11.
void invalidateShaders();
// Called by VertexArray11 to trigger attribute translation.
void invalidateVertexAttributeTranslation();
void setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv);
void setRenderTargets(ID3D11RenderTargetView **rtvs, UINT numRtvs, ID3D11DepthStencilView *dsv);
......@@ -307,7 +310,8 @@ class StateManager11 final : angle::NonCopyable
gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd);
void handleMultiviewDrawFramebufferChange(const gl::Context *context);
gl::Error syncCurrentValueAttribs(const gl::State &state);
gl::Error syncVertexAttributes(const gl::Context *context);
gl::Error syncCurrentValueAttribs(const gl::State &glState);
gl::Error generateSwizzle(const gl::Context *context, gl::Texture *texture);
gl::Error generateSwizzlesForShader(const gl::Context *context, gl::SamplerType type);
......@@ -342,6 +346,7 @@ class StateManager11 final : angle::NonCopyable
DIRTY_BIT_DRIVER_UNIFORMS,
DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS,
DIRTY_BIT_SHADERS,
DIRTY_BIT_CURRENT_VALUE_ATTRIBS,
DIRTY_BIT_INVALID,
DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
};
......@@ -440,6 +445,7 @@ class StateManager11 final : angle::NonCopyable
// Current applied input layout.
ResourceSerial mCurrentInputLayout;
bool mInputLayoutIsDirty;
bool mVertexAttribsNeedTranslation;
// Current applied vertex states.
// TODO(jmadill): Figure out how to use ResourceSerial here.
......
......@@ -101,6 +101,8 @@ void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t
mAttributeStorageTypes[attribIndex] = newStorageType;
StateManager11 *stateManager = GetImplAs<Context11>(context)->getRenderer()->getStateManager();
if (newStorageType == VertexStorageType::DYNAMIC)
{
if (oldStorageType != VertexStorageType::DYNAMIC)
......@@ -113,6 +115,7 @@ void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t
else
{
mAttribsToTranslate.set(attribIndex);
stateManager->invalidateVertexAttributeTranslation();
if (oldStorageType == VertexStorageType::DYNAMIC)
{
......@@ -126,8 +129,6 @@ void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t
Buffer11 *oldBuffer11 = oldBufferGL ? GetImplAs<Buffer11>(oldBufferGL) : nullptr;
Buffer11 *newBuffer11 = newBufferGL ? GetImplAs<Buffer11>(newBufferGL) : nullptr;
StateManager11 *stateManager = GetImplAs<Context11>(context)->getRenderer()->getStateManager();
if (oldBuffer11 != newBuffer11 || oldStorageType != newStorageType)
{
OnBufferDataDirtyChannel *newChannel = nullptr;
......
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