Commit 2cd45629 by Jamie Madill Committed by Commit Bot

D3D11: Consolidate Vertex Buffer application.

With this change, IASetVertexBuffers is only called from a single code site in StateManager11. All other classes call through to here. This will make adopting the dirty bits for InputLayouts and VBs much simpler. BUG=angleproject:2052 Change-Id: I6e7b6146deb7f80f5f0e75dd0aff18eb4cc2bfc2 Reviewed-on: https://chromium-review.googlesource.com/524232Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 863b6236
...@@ -1038,7 +1038,6 @@ gl::Error Blit11::swizzleTexture(const d3d11::SharedSRV &source, ...@@ -1038,7 +1038,6 @@ gl::Error Blit11::swizzleTexture(const d3d11::SharedSRV &source,
ANGLE_TRY(getShaderSupport(*shader, &support)); ANGLE_TRY(getShaderSupport(*shader, &support));
UINT stride = 0; UINT stride = 0;
UINT startIdx = 0;
UINT drawCount = 0; UINT drawCount = 0;
D3D11_PRIMITIVE_TOPOLOGY topology; D3D11_PRIMITIVE_TOPOLOGY topology;
...@@ -1067,8 +1066,7 @@ gl::Error Blit11::swizzleTexture(const d3d11::SharedSRV &source, ...@@ -1067,8 +1066,7 @@ gl::Error Blit11::swizzleTexture(const d3d11::SharedSRV &source,
auto stateManager = mRenderer->getStateManager(); auto stateManager = mRenderer->getStateManager();
// Apply vertex buffer // Apply vertex buffer
ID3D11Buffer *vertexBuffer = mVertexBuffer.get(); stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &startIdx);
// Apply constant buffer // Apply constant buffer
ID3D11Buffer *constantBuffer = mSwizzleCB.get(); ID3D11Buffer *constantBuffer = mSwizzleCB.get();
...@@ -1113,13 +1111,8 @@ gl::Error Blit11::swizzleTexture(const d3d11::SharedSRV &source, ...@@ -1113,13 +1111,8 @@ gl::Error Blit11::swizzleTexture(const d3d11::SharedSRV &source,
// Draw the quad // Draw the quad
deviceContext->Draw(drawCount, 0); deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer // Unbind shader resources and dirty state.
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
UINT zero = 0;
ID3D11Buffer *const nullBuffer = nullptr;
deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
mRenderer->markAllStateDirty(); mRenderer->markAllStateDirty();
return gl::NoError(); return gl::NoError();
...@@ -1176,7 +1169,6 @@ gl::Error Blit11::copyTexture(const d3d11::SharedSRV &source, ...@@ -1176,7 +1169,6 @@ gl::Error Blit11::copyTexture(const d3d11::SharedSRV &source,
} }
UINT stride = 0; UINT stride = 0;
UINT startIdx = 0;
UINT drawCount = 0; UINT drawCount = 0;
D3D11_PRIMITIVE_TOPOLOGY topology; D3D11_PRIMITIVE_TOPOLOGY topology;
...@@ -1188,8 +1180,7 @@ gl::Error Blit11::copyTexture(const d3d11::SharedSRV &source, ...@@ -1188,8 +1180,7 @@ gl::Error Blit11::copyTexture(const d3d11::SharedSRV &source,
auto stateManager = mRenderer->getStateManager(); auto stateManager = mRenderer->getStateManager();
// Apply vertex buffer // Apply vertex buffer
ID3D11Buffer *vertexBuffer = mVertexBuffer.get(); stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &startIdx);
// Apply state // Apply state
if (maskOffAlpha) if (maskOffAlpha)
...@@ -1267,13 +1258,9 @@ gl::Error Blit11::copyTexture(const d3d11::SharedSRV &source, ...@@ -1267,13 +1258,9 @@ gl::Error Blit11::copyTexture(const d3d11::SharedSRV &source,
// Draw the quad // Draw the quad
deviceContext->Draw(drawCount, 0); deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer // Unbind shader resource and invalidate state.
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
UINT zero = 0;
ID3D11Buffer *const nullBuffer = nullptr;
deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
mRenderer->markAllStateDirty(); mRenderer->markAllStateDirty();
return gl::NoError(); return gl::NoError();
...@@ -1317,7 +1304,6 @@ gl::Error Blit11::copyDepth(const d3d11::SharedSRV &source, ...@@ -1317,7 +1304,6 @@ gl::Error Blit11::copyDepth(const d3d11::SharedSRV &source,
} }
UINT stride = 0; UINT stride = 0;
UINT startIdx = 0;
UINT drawCount = 0; UINT drawCount = 0;
D3D11_PRIMITIVE_TOPOLOGY topology; D3D11_PRIMITIVE_TOPOLOGY topology;
...@@ -1326,9 +1312,10 @@ gl::Error Blit11::copyDepth(const d3d11::SharedSRV &source, ...@@ -1326,9 +1312,10 @@ gl::Error Blit11::copyDepth(const d3d11::SharedSRV &source,
deviceContext->Unmap(mVertexBuffer.get(), 0); deviceContext->Unmap(mVertexBuffer.get(), 0);
auto stateManager = mRenderer->getStateManager();
// Apply vertex buffer // Apply vertex buffer
ID3D11Buffer *vertexBuffer = mVertexBuffer.get(); stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &startIdx);
// Apply state // Apply state
deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF); deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF);
...@@ -1354,8 +1341,6 @@ gl::Error Blit11::copyDepth(const d3d11::SharedSRV &source, ...@@ -1354,8 +1341,6 @@ gl::Error Blit11::copyDepth(const d3d11::SharedSRV &source,
ANGLE_TRY(mQuad2DVS.resolve(mRenderer)); ANGLE_TRY(mQuad2DVS.resolve(mRenderer));
ANGLE_TRY(mDepthPS.resolve(mRenderer)); ANGLE_TRY(mDepthPS.resolve(mRenderer));
auto stateManager = mRenderer->getStateManager();
// Apply shaders // Apply shaders
stateManager->setInputLayout(&mQuad2DIL.getObj()); stateManager->setInputLayout(&mQuad2DIL.getObj());
deviceContext->IASetPrimitiveTopology(topology); deviceContext->IASetPrimitiveTopology(topology);
...@@ -1390,13 +1375,9 @@ gl::Error Blit11::copyDepth(const d3d11::SharedSRV &source, ...@@ -1390,13 +1375,9 @@ gl::Error Blit11::copyDepth(const d3d11::SharedSRV &source,
// Draw the quad // Draw the quad
deviceContext->Draw(drawCount, 0); deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer // Unbind shader resources and invalidate all state.
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
UINT zero = 0;
ID3D11Buffer *const nullBuffer = nullptr;
deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
mRenderer->markAllStateDirty(); mRenderer->markAllStateDirty();
return gl::NoError(); return gl::NoError();
......
...@@ -717,13 +717,11 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, ...@@ -717,13 +717,11 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams,
if (useVertexBuffer()) if (useVertexBuffer())
{ {
ANGLE_TRY(ensureVertexBufferCreated()); ANGLE_TRY(ensureVertexBufferCreated());
const UINT offset = 0; stateManager->setSingleVertexBuffer(&mVertexBuffer, g_VertexSize, 0);
ID3D11Buffer *vertexBuffer = mVertexBuffer.get();
deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &g_VertexSize, &offset);
} }
else else
{ {
deviceContext->IASetVertexBuffers(0, 0, nullptr, nullptr, nullptr); stateManager->setSingleVertexBuffer(nullptr, 0, 0);
} }
deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
......
...@@ -174,9 +174,6 @@ bool InputLayoutCache::PackedAttributeLayout::operator<(const PackedAttributeLay ...@@ -174,9 +174,6 @@ bool InputLayoutCache::PackedAttributeLayout::operator<(const PackedAttributeLay
InputLayoutCache::InputLayoutCache() InputLayoutCache::InputLayoutCache()
: mPointSpriteVertexBuffer(), mPointSpriteIndexBuffer(), mCacheSize(kDefaultCacheSize) : mPointSpriteVertexBuffer(), mPointSpriteIndexBuffer(), mCacheSize(kDefaultCacheSize)
{ {
mCurrentBuffers.fill(nullptr);
mCurrentVertexStrides.fill(std::numeric_limits<UINT>::max());
mCurrentVertexOffsets.fill(std::numeric_limits<UINT>::max());
mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS); mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
} }
...@@ -184,27 +181,11 @@ InputLayoutCache::~InputLayoutCache() ...@@ -184,27 +181,11 @@ InputLayoutCache::~InputLayoutCache()
{ {
} }
void InputLayoutCache::initialize()
{
clear();
}
void InputLayoutCache::clear() void InputLayoutCache::clear()
{ {
mLayoutMap.clear(); mLayoutMap.clear();
mPointSpriteVertexBuffer.reset(); mPointSpriteVertexBuffer.reset();
mPointSpriteIndexBuffer.reset(); mPointSpriteIndexBuffer.reset();
markDirty();
}
void InputLayoutCache::markDirty()
{
for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
mCurrentBuffers[i] = nullptr;
mCurrentVertexStrides[i] = static_cast<UINT>(-1);
mCurrentVertexOffsets[i] = static_cast<UINT>(-1);
}
} }
gl::Error InputLayoutCache::applyVertexBuffers( gl::Error InputLayoutCache::applyVertexBuffers(
...@@ -218,6 +199,7 @@ gl::Error InputLayoutCache::applyVertexBuffers( ...@@ -218,6 +199,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(
GLsizei numIndicesPerInstance) GLsizei numIndicesPerInstance)
{ {
ID3D11DeviceContext *deviceContext = renderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = renderer->getDeviceContext();
auto *stateManager = renderer->getStateManager();
gl::Program *program = state.getProgram(); gl::Program *program = state.getProgram();
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
...@@ -249,10 +231,6 @@ gl::Error InputLayoutCache::applyVertexBuffers( ...@@ -249,10 +231,6 @@ gl::Error InputLayoutCache::applyVertexBuffers(
ANGLE_TRY( ANGLE_TRY(
updateInputLayout(renderer, state, mode, sortedSemanticIndices, numIndicesPerInstance)); updateInputLayout(renderer, state, mode, sortedSemanticIndices, numIndicesPerInstance));
bool dirtyBuffers = false;
size_t minDiff = gl::MAX_VERTEX_ATTRIBS;
size_t maxDiff = 0;
// Note that if we use instance emulation, we reserve the first buffer slot. // Note that if we use instance emulation, we reserve the first buffer slot.
size_t reservedBuffers = GetReservedBufferCount(programUsesInstancedPointSprites); size_t reservedBuffers = GetReservedBufferCount(programUsesInstancedPointSprites);
...@@ -307,18 +285,7 @@ gl::Error InputLayoutCache::applyVertexBuffers( ...@@ -307,18 +285,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(
size_t bufferIndex = reservedBuffers + attribIndex; size_t bufferIndex = reservedBuffers + attribIndex;
if (buffer != mCurrentBuffers[bufferIndex] || stateManager->queueVertexBufferChange(bufferIndex, buffer, vertexStride, vertexOffset);
vertexStride != mCurrentVertexStrides[bufferIndex] ||
vertexOffset != mCurrentVertexOffsets[bufferIndex])
{
dirtyBuffers = true;
minDiff = std::min(minDiff, bufferIndex);
maxDiff = std::max(maxDiff, bufferIndex);
mCurrentBuffers[bufferIndex] = buffer;
mCurrentVertexStrides[bufferIndex] = vertexStride;
mCurrentVertexOffsets[bufferIndex] = vertexOffset;
}
} }
// Instanced PointSprite emulation requires two additional ID3D11Buffers. A vertex buffer needs // Instanced PointSprite emulation requires two additional ID3D11Buffers. A vertex buffer needs
...@@ -358,16 +325,10 @@ gl::Error InputLayoutCache::applyVertexBuffers( ...@@ -358,16 +325,10 @@ gl::Error InputLayoutCache::applyVertexBuffers(
&mPointSpriteVertexBuffer)); &mPointSpriteVertexBuffer));
} }
mCurrentBuffers[0] = mPointSpriteVertexBuffer.get();
// Set the stride to 0 if GL_POINTS mode is not being used to instruct the driver to avoid // Set the stride to 0 if GL_POINTS mode is not being used to instruct the driver to avoid
// indexing into the vertex buffer. // indexing into the vertex buffer.
mCurrentVertexStrides[0] = instancedPointSpritesActive ? pointSpriteVertexStride : 0; UINT stride = instancedPointSpritesActive ? pointSpriteVertexStride : 0;
mCurrentVertexOffsets[0] = 0; stateManager->queueVertexBufferChange(0, mPointSpriteVertexBuffer.get(), stride, 0);
// Update maxDiff to include the additional point sprite vertex buffer
// to ensure that IASetVertexBuffers uses the correct buffer count.
minDiff = 0;
maxDiff = std::max(maxDiff, static_cast<size_t>(0));
if (!mPointSpriteIndexBuffer.valid()) if (!mPointSpriteIndexBuffer.valid())
{ {
...@@ -400,15 +361,7 @@ gl::Error InputLayoutCache::applyVertexBuffers( ...@@ -400,15 +361,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(
} }
} }
if (dirtyBuffers) stateManager->applyVertexBufferChanges();
{
ASSERT(minDiff <= maxDiff && maxDiff < gl::MAX_VERTEX_ATTRIBS);
deviceContext->IASetVertexBuffers(
static_cast<UINT>(minDiff), static_cast<UINT>(maxDiff - minDiff + 1),
&mCurrentBuffers[minDiff], &mCurrentVertexStrides[minDiff],
&mCurrentVertexOffsets[minDiff]);
}
return gl::NoError(); return gl::NoError();
} }
...@@ -416,6 +369,8 @@ gl::Error InputLayoutCache::updateVertexOffsetsForPointSpritesEmulation(Renderer ...@@ -416,6 +369,8 @@ gl::Error InputLayoutCache::updateVertexOffsetsForPointSpritesEmulation(Renderer
GLint startVertex, GLint startVertex,
GLsizei emulatedInstanceId) GLsizei emulatedInstanceId)
{ {
auto *stateManager = renderer->getStateManager();
size_t reservedBuffers = GetReservedBufferCount(true); size_t reservedBuffers = GetReservedBufferCount(true);
for (size_t attribIndex = 0; attribIndex < mCurrentAttributes.size(); ++attribIndex) for (size_t attribIndex = 0; attribIndex < mCurrentAttributes.size(); ++attribIndex)
{ {
...@@ -426,15 +381,12 @@ gl::Error InputLayoutCache::updateVertexOffsetsForPointSpritesEmulation(Renderer ...@@ -426,15 +381,12 @@ gl::Error InputLayoutCache::updateVertexOffsetsForPointSpritesEmulation(Renderer
{ {
unsigned int offset = 0; unsigned int offset = 0;
ANGLE_TRY_RESULT(attrib.computeOffset(startVertex), offset); ANGLE_TRY_RESULT(attrib.computeOffset(startVertex), offset);
mCurrentVertexOffsets[bufferIndex] = offset += (attrib.stride * (emulatedInstanceId / attrib.divisor));
offset + (attrib.stride * (emulatedInstanceId / attrib.divisor)); stateManager->queueVertexOffsetChange(bufferIndex, offset);
} }
} }
ID3D11DeviceContext *deviceContext = renderer->getDeviceContext(); stateManager->applyVertexBufferChanges();
deviceContext->IASetVertexBuffers(0, gl::MAX_VERTEX_ATTRIBS, mCurrentBuffers.data(),
mCurrentVertexStrides.data(), mCurrentVertexOffsets.data());
return gl::NoError(); return gl::NoError();
} }
......
...@@ -41,11 +41,9 @@ class InputLayoutCache : angle::NonCopyable ...@@ -41,11 +41,9 @@ class InputLayoutCache : angle::NonCopyable
{ {
public: public:
InputLayoutCache(); InputLayoutCache();
virtual ~InputLayoutCache(); ~InputLayoutCache();
void initialize();
void clear(); void clear();
void markDirty();
gl::Error applyVertexBuffers(Renderer11 *renderer, gl::Error applyVertexBuffers(Renderer11 *renderer,
const gl::State &state, const gl::State &state,
...@@ -105,9 +103,6 @@ class InputLayoutCache : angle::NonCopyable ...@@ -105,9 +103,6 @@ class InputLayoutCache : angle::NonCopyable
std::map<PackedAttributeLayout, d3d11::InputLayout> mLayoutMap; std::map<PackedAttributeLayout, d3d11::InputLayout> mLayoutMap;
std::array<ID3D11Buffer *, gl::MAX_VERTEX_ATTRIBS> mCurrentBuffers;
std::array<UINT, gl::MAX_VERTEX_ATTRIBS> mCurrentVertexStrides;
std::array<UINT, gl::MAX_VERTEX_ATTRIBS> mCurrentVertexOffsets;
std::vector<const TranslatedAttribute *> mCurrentAttributes; std::vector<const TranslatedAttribute *> mCurrentAttributes;
d3d11::Buffer mPointSpriteVertexBuffer; d3d11::Buffer mPointSpriteVertexBuffer;
......
...@@ -180,9 +180,6 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac ...@@ -180,9 +180,6 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
ID3D11Buffer *nullBuffer = nullptr;
UINT zero = 0;
// Are we doing a 2D or 3D copy? // Are we doing a 2D or 3D copy?
ID3D11GeometryShader *geometryShader = ID3D11GeometryShader *geometryShader =
((destSize.depth > 1) ? mBufferToTextureGS.get() : nullptr); ((destSize.depth > 1) ? mBufferToTextureGS.get() : nullptr);
...@@ -195,7 +192,7 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac ...@@ -195,7 +192,7 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
stateManager->setInputLayout(nullptr); stateManager->setInputLayout(nullptr);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); stateManager->setSingleVertexBuffer(nullptr, 0, 0);
deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF); deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF);
deviceContext->OMSetDepthStencilState(mCopyDepthStencilState.get(), 0xFFFFFFFF); deviceContext->OMSetDepthStencilState(mCopyDepthStencilState.get(), 0xFFFFFFFF);
deviceContext->RSSetState(mCopyRasterizerState.get()); deviceContext->RSSetState(mCopyRasterizerState.get());
...@@ -224,8 +221,10 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac ...@@ -224,8 +221,10 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
UINT numPixels = (destArea.width * destArea.height * destArea.depth); UINT numPixels = (destArea.width * destArea.height * destArea.depth);
deviceContext->Draw(numPixels, 0); deviceContext->Draw(numPixels, 0);
// Unbind textures and render targets and vertex buffer // Unbind shader resources and invalidate state.
stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr);
ID3D11Buffer *nullBuffer = nullptr;
deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer); deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer);
mRenderer->markAllStateDirty(); mRenderer->markAllStateDirty();
......
...@@ -789,7 +789,6 @@ void Renderer11::initializeDevice() ...@@ -789,7 +789,6 @@ void Renderer11::initializeDevice()
populateRenderer11DeviceCaps(); populateRenderer11DeviceCaps();
mStateCache.clear(); mStateCache.clear();
mInputLayoutCache.initialize();
ASSERT(!mVertexDataManager && !mIndexDataManager); ASSERT(!mVertexDataManager && !mIndexDataManager);
mVertexDataManager = new VertexDataManager(this); mVertexDataManager = new VertexDataManager(this);
...@@ -2813,8 +2812,6 @@ void Renderer11::markAllStateDirty() ...@@ -2813,8 +2812,6 @@ void Renderer11::markAllStateDirty()
memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants11)); memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants11));
memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants11)); memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants11));
mInputLayoutCache.markDirty();
for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++) for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++)
{ {
mCurrentConstantBufferVS[i] = static_cast<unsigned int>(-1); mCurrentConstantBufferVS[i] = static_cast<unsigned int>(-1);
......
...@@ -160,7 +160,8 @@ StateManager11::StateManager11(Renderer11 *renderer) ...@@ -160,7 +160,8 @@ StateManager11::StateManager11(Renderer11 *renderer)
mRenderTargetIsDirty(false), mRenderTargetIsDirty(false),
mDirtyCurrentValueAttribs(), mDirtyCurrentValueAttribs(),
mCurrentValueAttribs(), mCurrentValueAttribs(),
mCurrentInputLayout() mCurrentInputLayout(),
mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0)
{ {
mCurBlendState.blend = false; mCurBlendState.blend = false;
mCurBlendState.sourceBlendRGB = GL_ONE; mCurBlendState.sourceBlendRGB = GL_ONE;
...@@ -204,6 +205,10 @@ StateManager11::StateManager11(Renderer11 *renderer) ...@@ -204,6 +205,10 @@ StateManager11::StateManager11(Renderer11 *renderer)
// Initially all current value attributes must be updated on first use. // Initially all current value attributes must be updated on first use.
mDirtyCurrentValueAttribs.flip(); mDirtyCurrentValueAttribs.flip();
mCurrentVertexBuffers.fill(nullptr);
mCurrentVertexStrides.fill(std::numeric_limits<UINT>::max());
mCurrentVertexOffsets.fill(std::numeric_limits<UINT>::max());
} }
StateManager11::~StateManager11() StateManager11::~StateManager11()
...@@ -491,6 +496,8 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit ...@@ -491,6 +496,8 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit
break; break;
} }
} }
// TODO(jmadill): Input layout and vertex buffer state.
} }
gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer, gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer,
...@@ -823,6 +830,16 @@ void StateManager11::invalidateEverything() ...@@ -823,6 +830,16 @@ void StateManager11::invalidateEverything()
// All calls to IASetInputLayout go through the state manager, so it shouldn't be // All calls to IASetInputLayout go through the state manager, so it shouldn't be
// necessary to invalidate the state. // necessary to invalidate the state.
// Invalidate the vertex buffer state.
invalidateVertexBuffer();
}
void StateManager11::invalidateVertexBuffer()
{
unsigned int limit = std::min<unsigned int>(mRenderer->getNativeCaps().maxVertexAttributes,
gl::MAX_VERTEX_ATTRIBS);
mDirtyVertexBufferRange = gl::RangeUI(0, limit);
} }
void StateManager11::setOneTimeRenderTarget(ID3D11RenderTargetView *rtv, void StateManager11::setOneTimeRenderTarget(ID3D11RenderTargetView *rtv,
...@@ -1157,4 +1174,63 @@ void StateManager11::setInputLayout(const d3d11::InputLayout *inputLayout) ...@@ -1157,4 +1174,63 @@ void StateManager11::setInputLayout(const d3d11::InputLayout *inputLayout)
} }
} }
bool StateManager11::queueVertexBufferChange(size_t bufferIndex,
ID3D11Buffer *buffer,
UINT stride,
UINT offset)
{
if (buffer != mCurrentVertexBuffers[bufferIndex] ||
stride != mCurrentVertexStrides[bufferIndex] ||
offset != mCurrentVertexOffsets[bufferIndex])
{
mDirtyVertexBufferRange.extend(static_cast<unsigned int>(bufferIndex));
mCurrentVertexBuffers[bufferIndex] = buffer;
mCurrentVertexStrides[bufferIndex] = stride;
mCurrentVertexOffsets[bufferIndex] = offset;
return true;
}
return false;
}
bool StateManager11::queueVertexOffsetChange(size_t bufferIndex, UINT offsetOnly)
{
if (offsetOnly != mCurrentVertexOffsets[bufferIndex])
{
mDirtyVertexBufferRange.extend(static_cast<unsigned int>(bufferIndex));
mCurrentVertexOffsets[bufferIndex] = offsetOnly;
return true;
}
return false;
}
void StateManager11::applyVertexBufferChanges()
{
if (mDirtyVertexBufferRange.empty())
{
return;
}
ASSERT(mDirtyVertexBufferRange.high() <= gl::MAX_VERTEX_ATTRIBS);
UINT start = static_cast<UINT>(mDirtyVertexBufferRange.low());
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
deviceContext->IASetVertexBuffers(start, static_cast<UINT>(mDirtyVertexBufferRange.length()),
&mCurrentVertexBuffers[start], &mCurrentVertexStrides[start],
&mCurrentVertexOffsets[start]);
mDirtyVertexBufferRange = gl::RangeUI(gl::MAX_VERTEX_ATTRIBS, 0);
}
void StateManager11::setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset)
{
ID3D11Buffer *native = buffer ? buffer->get() : nullptr;
if (queueVertexBufferChange(0, native, stride, offset))
{
applyVertexBufferChanges();
}
}
} // namespace rx } // namespace rx
...@@ -90,6 +90,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -90,6 +90,7 @@ class StateManager11 final : angle::NonCopyable
void invalidateRenderTarget(); void invalidateRenderTarget();
void invalidateBoundViews(); void invalidateBoundViews();
void invalidateVertexBuffer();
void invalidateEverything(); void invalidateEverything();
void setOneTimeRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv); void setOneTimeRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv);
...@@ -108,6 +109,16 @@ class StateManager11 final : angle::NonCopyable ...@@ -108,6 +109,16 @@ class StateManager11 final : angle::NonCopyable
void setInputLayout(const d3d11::InputLayout *inputLayout); void setInputLayout(const d3d11::InputLayout *inputLayout);
// TODO(jmadill): Migrate to d3d11::Buffer.
bool queueVertexBufferChange(size_t bufferIndex,
ID3D11Buffer *buffer,
UINT stride,
UINT offset);
bool queueVertexOffsetChange(size_t bufferIndex, UINT offsetOnly);
void applyVertexBufferChanges();
void setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset);
private: private:
void setViewportBounds(const int width, const int height); void setViewportBounds(const int width, const int height);
void unsetConflictingSRVs(gl::SamplerType shaderType, void unsetConflictingSRVs(gl::SamplerType shaderType,
...@@ -212,6 +223,13 @@ class StateManager11 final : angle::NonCopyable ...@@ -212,6 +223,13 @@ class StateManager11 final : angle::NonCopyable
// Current applied input layout. // Current applied input layout.
ResourceSerial mCurrentInputLayout; ResourceSerial mCurrentInputLayout;
// Current applied vertex states.
// TODO(jmadill): Figure out how to use ResourceSerial here.
std::array<ID3D11Buffer *, gl::MAX_VERTEX_ATTRIBS> mCurrentVertexBuffers;
std::array<UINT, gl::MAX_VERTEX_ATTRIBS> mCurrentVertexStrides;
std::array<UINT, gl::MAX_VERTEX_ATTRIBS> mCurrentVertexOffsets;
gl::RangeUI mDirtyVertexBufferRange;
}; };
} // namespace rx } // namespace rx
......
...@@ -769,10 +769,10 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, ...@@ -769,10 +769,10 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width,
deviceContext->Unmap(mQuadVB.get(), 0); deviceContext->Unmap(mQuadVB.get(), 0);
static UINT stride = sizeof(d3d11::PositionTexCoordVertex); auto stateManager = mRenderer->getStateManager();
static UINT startIdx = 0;
ID3D11Buffer *vertexBuffer = mQuadVB.get(); constexpr UINT stride = sizeof(d3d11::PositionTexCoordVertex);
deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &startIdx); stateManager->setSingleVertexBuffer(&mQuadVB, stride, 0);
// Apply state // Apply state
deviceContext->OMSetDepthStencilState(nullptr, 0xFFFFFFFF); deviceContext->OMSetDepthStencilState(nullptr, 0xFFFFFFFF);
...@@ -782,8 +782,6 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, ...@@ -782,8 +782,6 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width,
deviceContext->RSSetState(mPassThroughRS.get()); deviceContext->RSSetState(mPassThroughRS.get());
auto stateManager = mRenderer->getStateManager();
// Apply shaders // Apply shaders
stateManager->setInputLayout(&mPassThroughIL); stateManager->setInputLayout(&mPassThroughIL);
deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
......
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