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) ...@@ -542,6 +542,7 @@ StateManager11::StateManager11(Renderer11 *renderer)
mCurrentValueAttribs(), mCurrentValueAttribs(),
mCurrentInputLayout(), mCurrentInputLayout(),
mInputLayoutIsDirty(false), mInputLayoutIsDirty(false),
mVertexAttribsNeedTranslation(false),
mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0), mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0),
mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED), mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED),
mDirtySwizzles(false), mDirtySwizzles(false),
...@@ -976,7 +977,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -976,7 +977,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
{ {
size_t attribIndex = size_t attribIndex =
static_cast<size_t>(dirtyBit - gl::State::DIRTY_BIT_CURRENT_VALUE_0); static_cast<size_t>(dirtyBit - gl::State::DIRTY_BIT_CURRENT_VALUE_0);
mDirtyCurrentValueAttribs.set(attribIndex); invalidateCurrentValueAttrib(attribIndex);
} }
break; break;
} }
...@@ -1367,6 +1368,8 @@ void StateManager11::invalidateVertexBuffer() ...@@ -1367,6 +1368,8 @@ void StateManager11::invalidateVertexBuffer()
gl::MAX_VERTEX_ATTRIBS); gl::MAX_VERTEX_ATTRIBS);
mDirtyVertexBufferRange = gl::RangeUI(0, limit); mDirtyVertexBufferRange = gl::RangeUI(0, limit);
mInputLayoutIsDirty = true; mInputLayoutIsDirty = true;
mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS);
invalidateVertexAttributeTranslation();
} }
void StateManager11::invalidateViewport(const gl::Context *context) void StateManager11::invalidateViewport(const gl::Context *context)
...@@ -1458,6 +1461,11 @@ void StateManager11::setRenderTargets(ID3D11RenderTargetView **rtvs, ...@@ -1458,6 +1461,11 @@ void StateManager11::setRenderTargets(ID3D11RenderTargetView **rtvs,
mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET); mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
} }
void StateManager11::invalidateVertexAttributeTranslation()
{
mVertexAttribsNeedTranslation = true;
}
void StateManager11::onBeginQuery(Query11 *query) void StateManager11::onBeginQuery(Query11 *query)
{ {
mCurrentQueries.insert(query); mCurrentQueries.insert(query);
...@@ -1712,22 +1720,22 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb ...@@ -1712,22 +1720,22 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb
void StateManager11::invalidateCurrentValueAttrib(size_t attribIndex) void StateManager11::invalidateCurrentValueAttrib(size_t attribIndex)
{ {
mDirtyCurrentValueAttribs.set(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 &dirtyActiveAttribs = (activeAttribsMask & mDirtyCurrentValueAttribs);
const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes();
const auto &vertexBindings = state.getVertexArray()->getVertexBindings();
if (!dirtyActiveAttribs.any()) if (!dirtyActiveAttribs.any())
{ {
return gl::NoError(); return gl::NoError();
} }
invalidateVertexBuffer(); const auto &vertexAttributes = glState.getVertexArray()->getVertexAttributes();
mDirtyCurrentValueAttribs = (mDirtyCurrentValueAttribs & ~dirtyActiveAttribs); const auto &vertexBindings = glState.getVertexArray()->getVertexBindings();
mDirtyCurrentValueAttribs = (mDirtyCurrentValueAttribs & ~dirtyActiveAttribs);
for (auto attribIndex : dirtyActiveAttribs) for (auto attribIndex : dirtyActiveAttribs)
{ {
...@@ -1735,7 +1743,7 @@ gl::Error StateManager11::syncCurrentValueAttribs(const gl::State &state) ...@@ -1735,7 +1743,7 @@ gl::Error StateManager11::syncCurrentValueAttribs(const gl::State &state)
continue; continue;
const auto *attrib = &vertexAttributes[attribIndex]; const auto *attrib = &vertexAttributes[attribIndex];
const auto &currentValue = state.getVertexAttribCurrentValue(attribIndex); const auto &currentValue = glState.getVertexAttribCurrentValue(attribIndex);
auto currentValueAttrib = &mCurrentValueAttribs[attribIndex]; auto currentValueAttrib = &mCurrentValueAttribs[attribIndex];
currentValueAttrib->currentValueType = currentValue.Type; currentValueAttrib->currentValueType = currentValue.Type;
currentValueAttrib->attribute = attrib; currentValueAttrib->attribute = attrib;
...@@ -1940,6 +1948,9 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod ...@@ -1940,6 +1948,9 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod
case DIRTY_BIT_SHADERS: case DIRTY_BIT_SHADERS:
ANGLE_TRY(syncProgram(context, drawMode)); ANGLE_TRY(syncProgram(context, drawMode));
break; break;
case DIRTY_BIT_CURRENT_VALUE_ATTRIBS:
ANGLE_TRY(syncCurrentValueAttribs(glState));
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -2481,14 +2492,15 @@ gl::Error StateManager11::applyVertexBuffer(const gl::Context *context, ...@@ -2481,14 +2492,15 @@ gl::Error StateManager11::applyVertexBuffer(const gl::Context *context,
const auto &vertexArray = state.getVertexArray(); const auto &vertexArray = state.getVertexArray();
auto *vertexArray11 = GetImplAs<VertexArray11>(vertexArray); auto *vertexArray11 = GetImplAs<VertexArray11>(vertexArray);
if (vertexArray11->hasDirtyOrDynamicAttrib(context)) if (mVertexAttribsNeedTranslation)
{ {
ANGLE_TRY(vertexArray11->updateDirtyAndDynamicAttribs(context, &mVertexDataManager, first, ANGLE_TRY(vertexArray11->updateDirtyAndDynamicAttribs(context, &mVertexDataManager, first,
count, instances)); 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) if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != first)
{ {
......
...@@ -182,6 +182,9 @@ class StateManager11 final : angle::NonCopyable ...@@ -182,6 +182,9 @@ class StateManager11 final : angle::NonCopyable
// Called by the Framebuffer11 and VertexArray11. // Called by the Framebuffer11 and VertexArray11.
void invalidateShaders(); void invalidateShaders();
// Called by VertexArray11 to trigger attribute translation.
void invalidateVertexAttributeTranslation();
void setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv); void setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv);
void setRenderTargets(ID3D11RenderTargetView **rtvs, UINT numRtvs, ID3D11DepthStencilView *dsv); void setRenderTargets(ID3D11RenderTargetView **rtvs, UINT numRtvs, ID3D11DepthStencilView *dsv);
...@@ -307,7 +310,8 @@ class StateManager11 final : angle::NonCopyable ...@@ -307,7 +310,8 @@ class StateManager11 final : angle::NonCopyable
gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd); gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd);
void handleMultiviewDrawFramebufferChange(const gl::Context *context); 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 generateSwizzle(const gl::Context *context, gl::Texture *texture);
gl::Error generateSwizzlesForShader(const gl::Context *context, gl::SamplerType type); gl::Error generateSwizzlesForShader(const gl::Context *context, gl::SamplerType type);
...@@ -342,6 +346,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -342,6 +346,7 @@ class StateManager11 final : angle::NonCopyable
DIRTY_BIT_DRIVER_UNIFORMS, DIRTY_BIT_DRIVER_UNIFORMS,
DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS, DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS,
DIRTY_BIT_SHADERS, DIRTY_BIT_SHADERS,
DIRTY_BIT_CURRENT_VALUE_ATTRIBS,
DIRTY_BIT_INVALID, DIRTY_BIT_INVALID,
DIRTY_BIT_MAX = DIRTY_BIT_INVALID, DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
}; };
...@@ -440,6 +445,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -440,6 +445,7 @@ class StateManager11 final : angle::NonCopyable
// Current applied input layout. // Current applied input layout.
ResourceSerial mCurrentInputLayout; ResourceSerial mCurrentInputLayout;
bool mInputLayoutIsDirty; bool mInputLayoutIsDirty;
bool mVertexAttribsNeedTranslation;
// Current applied vertex states. // Current applied vertex states.
// TODO(jmadill): Figure out how to use ResourceSerial here. // TODO(jmadill): Figure out how to use ResourceSerial here.
......
...@@ -101,6 +101,8 @@ void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t ...@@ -101,6 +101,8 @@ void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t
mAttributeStorageTypes[attribIndex] = newStorageType; mAttributeStorageTypes[attribIndex] = newStorageType;
StateManager11 *stateManager = GetImplAs<Context11>(context)->getRenderer()->getStateManager();
if (newStorageType == VertexStorageType::DYNAMIC) if (newStorageType == VertexStorageType::DYNAMIC)
{ {
if (oldStorageType != VertexStorageType::DYNAMIC) if (oldStorageType != VertexStorageType::DYNAMIC)
...@@ -113,6 +115,7 @@ void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t ...@@ -113,6 +115,7 @@ void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t
else else
{ {
mAttribsToTranslate.set(attribIndex); mAttribsToTranslate.set(attribIndex);
stateManager->invalidateVertexAttributeTranslation();
if (oldStorageType == VertexStorageType::DYNAMIC) if (oldStorageType == VertexStorageType::DYNAMIC)
{ {
...@@ -126,8 +129,6 @@ void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t ...@@ -126,8 +129,6 @@ void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t
Buffer11 *oldBuffer11 = oldBufferGL ? GetImplAs<Buffer11>(oldBufferGL) : nullptr; Buffer11 *oldBuffer11 = oldBufferGL ? GetImplAs<Buffer11>(oldBufferGL) : nullptr;
Buffer11 *newBuffer11 = newBufferGL ? GetImplAs<Buffer11>(newBufferGL) : nullptr; Buffer11 *newBuffer11 = newBufferGL ? GetImplAs<Buffer11>(newBufferGL) : nullptr;
StateManager11 *stateManager = GetImplAs<Context11>(context)->getRenderer()->getStateManager();
if (oldBuffer11 != newBuffer11 || oldStorageType != newStorageType) if (oldBuffer11 != newBuffer11 || oldStorageType != newStorageType)
{ {
OnBufferDataDirtyChannel *newChannel = nullptr; 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