Commit 4148fd74 by Jamie Madill Committed by Commit Bot

Add separate dirty bits for Pixel and Fragment uniforms.

Also use a single UpdateSubresource call to update the buffer. Should improve performance on some benchmarks. BUG=angleproject:1390 Change-Id: I70d54d86d3d3beb0e2caee86338ee03081070ac8 Reviewed-on: https://chromium-review.googlesource.com/663895Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 371ed53a
......@@ -558,7 +558,9 @@ ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer)
mUsedComputeSamplerRange(0),
mDirtySamplerMapping(true),
mSerial(issueSerial()),
mUniformsDirty(true)
mVertexUniformsDirty(true),
mFragmentUniformsDirty(true),
mComputeUniformsDirty(true)
{
mDynamicHLSL = new DynamicHLSL(renderer);
}
......@@ -1833,7 +1835,16 @@ const std::vector<GLint> &ProgramD3D::getFragmentUniformBufferCache() const
void ProgramD3D::dirtyAllUniforms()
{
mUniformsDirty = true;
mVertexUniformsDirty = true;
mFragmentUniformsDirty = true;
mComputeUniformsDirty = true;
}
void ProgramD3D::markUniformsClean()
{
mVertexUniformsDirty = false;
mFragmentUniformsDirty = false;
mComputeUniformsDirty = false;
}
void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
......@@ -2194,8 +2205,6 @@ void ProgramD3D::setUniformInternal(GLint location, GLsizei count, const T *v, G
const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
D3DUniform *targetUniform = mD3DUniforms[locationInfo.index];
mUniformsDirty = true;
if (targetUniform->typeInfo.isSampler)
{
ASSERT(uniformType == GL_INT);
......@@ -2207,16 +2216,19 @@ void ProgramD3D::setUniformInternal(GLint location, GLsizei count, const T *v, G
if (targetUniform->vsData)
{
setUniformImpl(locationInfo, count, v, targetUniform->vsData, uniformType);
mVertexUniformsDirty = true;
}
if (targetUniform->psData)
{
setUniformImpl(locationInfo, count, v, targetUniform->psData, uniformType);
mFragmentUniformsDirty = true;
}
if (targetUniform->csData)
{
setUniformImpl(locationInfo, count, v, targetUniform->csData, uniformType);
mComputeUniformsDirty = true;
}
}
......@@ -2252,8 +2264,6 @@ void ProgramD3D::setUniformMatrixfvImpl(GLint location,
target += targetMatrixStride;
value += cols * rows;
}
mUniformsDirty = true;
}
template <int cols, int rows>
......@@ -2269,18 +2279,21 @@ void ProgramD3D::setUniformMatrixfvInternal(GLint location,
{
setUniformMatrixfvImpl<cols, rows>(location, countIn, transpose, value,
targetUniform->vsData, targetUniformType);
mVertexUniformsDirty = true;
}
if (targetUniform->psData)
{
setUniformMatrixfvImpl<cols, rows>(location, countIn, transpose, value,
targetUniform->psData, targetUniformType);
mFragmentUniformsDirty = true;
}
if (targetUniform->csData)
{
setUniformMatrixfvImpl<cols, rows>(location, countIn, transpose, value,
targetUniform->csData, targetUniformType);
mComputeUniformsDirty = true;
}
}
......@@ -2423,7 +2436,7 @@ void ProgramD3D::reset()
mGeometryShaderPreamble.clear();
mUniformsDirty = true;
dirtyAllUniforms();
mCachedPixelExecutableIndex.reset();
mCachedVertexExecutableIndex.reset();
......
......@@ -292,9 +292,11 @@ class ProgramD3D : public ProgramImpl
bool hasGeometryExecutableForPrimitiveType(GLenum drawMode);
bool hasPixelExecutableForCachedOutputLayout();
bool areUniformsDirty() const { return mUniformsDirty; }
bool areVertexUniformsDirty() const { return mVertexUniformsDirty; }
bool areFragmentUniformsDirty() const { return mFragmentUniformsDirty; }
bool areComputeUniformsDirty() const { return mComputeUniformsDirty; }
const std::vector<D3DUniform *> &getD3DUniforms() const { return mD3DUniforms; }
void markUniformsClean() { mUniformsDirty = false; }
void markUniformsClean();
private:
// These forward-declared tasks are used for multi-thread shader compiles.
......@@ -492,7 +494,9 @@ class ProgramD3D : public ProgramImpl
std::vector<D3DUniform *> mD3DUniforms;
std::vector<D3DUniformBlock> mD3DUniformBlocks;
bool mUniformsDirty;
bool mVertexUniformsDirty;
bool mFragmentUniformsDirty;
bool mComputeUniformsDirty;
std::map<std::string, sh::BlockMemberInfo> mBlockInfo;
std::map<std::string, size_t> mBlockDataSizes;
......
......@@ -104,16 +104,12 @@ gl::Error UniformStorage11::getConstantBuffer(Renderer11 *renderer, const d3d11:
{
if (size() > 0 && !mConstantBuffer.valid())
{
D3D11_BUFFER_DESC constantBufferDescription = {0};
D3D11_BUFFER_DESC desc = {0};
desc.ByteWidth = static_cast<unsigned int>(size());
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDescription.ByteWidth = static_cast<unsigned int>(size());
constantBufferDescription.Usage = D3D11_USAGE_DYNAMIC;
constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
constantBufferDescription.MiscFlags = 0;
constantBufferDescription.StructureByteStride = 0;
ANGLE_TRY(renderer->allocateResource(constantBufferDescription, &mConstantBuffer));
ANGLE_TRY(renderer->allocateResource(desc, &mConstantBuffer));
}
*bufferOut = &mConstantBuffer;
......
......@@ -168,6 +168,14 @@ void SortAttributesByLayout(const gl::Program *program,
}
}
void UpdateUniformBuffer(ID3D11DeviceContext *deviceContext,
UniformStorage11 *storage,
const d3d11::Buffer *buffer)
{
deviceContext->UpdateSubresource(buffer->get(), 0, nullptr, storage->getDataPointer(0, 0), 0,
0);
}
} // anonymous namespace
// StateManager11::SRVCache Implementation.
......@@ -1812,7 +1820,7 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod
}
// TODO(jmadill): Use dirty bits.
if (programD3D->areUniformsDirty())
if (programD3D->areVertexUniformsDirty() || programD3D->areFragmentUniformsDirty())
{
mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS);
}
......@@ -2622,37 +2630,14 @@ gl::Error StateManager11::applyUniforms(ProgramD3D *programD3D)
const d3d11::Buffer *pixelConstantBuffer = nullptr;
ANGLE_TRY(fragmentUniformStorage->getConstantBuffer(mRenderer, &pixelConstantBuffer));
bool uniformsDirty = programD3D->areUniformsDirty();
if (vertexUniformStorage->size() > 0 && uniformsDirty)
if (vertexUniformStorage->size() > 0 && programD3D->areVertexUniformsDirty())
{
D3D11_MAPPED_SUBRESOURCE map = {0};
HRESULT result =
deviceContext->Map(vertexConstantBuffer->get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
if (FAILED(result))
{
return gl::OutOfMemory() << "Failed to Map vertex constants: " << gl::FmtHR(result);
}
memcpy(map.pData, vertexUniformStorage->getDataPointer(0, 0), vertexUniformStorage->size());
deviceContext->Unmap(vertexConstantBuffer->get(), 0);
UpdateUniformBuffer(deviceContext, vertexUniformStorage, vertexConstantBuffer);
}
if (fragmentUniformStorage->size() > 0 && uniformsDirty)
if (fragmentUniformStorage->size() > 0 && programD3D->areFragmentUniformsDirty())
{
D3D11_MAPPED_SUBRESOURCE map = {0};
HRESULT result =
deviceContext->Map(pixelConstantBuffer->get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
if (FAILED(result))
{
return gl::OutOfMemory() << "Failed to Map fragment constants: " << gl::FmtHR(result);
}
memcpy(map.pData, fragmentUniformStorage->getDataPointer(0, 0),
fragmentUniformStorage->size());
deviceContext->Unmap(pixelConstantBuffer->get(), 0);
UpdateUniformBuffer(deviceContext, fragmentUniformStorage, pixelConstantBuffer);
}
unsigned int slot = d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK;
......@@ -2741,23 +2726,9 @@ gl::Error StateManager11::applyComputeUniforms(ProgramD3D *programD3D)
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
bool uniformsDirty = programD3D->areUniformsDirty();
if (computeUniformStorage->size() > 0 && uniformsDirty)
if (computeUniformStorage->size() > 0 && programD3D->areComputeUniformsDirty())
{
D3D11_MAPPED_SUBRESOURCE map = {0};
HRESULT result =
deviceContext->Map(constantBuffer->get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
if (FAILED(result))
{
return gl::OutOfMemory() << "Failed to Map compute constants: " << gl::FmtHR(result);
}
memcpy(map.pData, computeUniformStorage->getDataPointer(0, 0),
computeUniformStorage->size());
deviceContext->Unmap(constantBuffer->get(), 0);
UpdateUniformBuffer(deviceContext, computeUniformStorage, constantBuffer);
programD3D->markUniformsClean();
}
......
......@@ -1838,8 +1838,8 @@ gl::Error Renderer9::applyShaders(const gl::Context *context, GLenum drawMode)
gl::Error Renderer9::applyUniforms(ProgramD3D *programD3D)
{
// Skip updates if we're not dirty.
if (!programD3D->areUniformsDirty())
// Skip updates if we're not dirty. Note that D3D9 cannot have compute.
if (!programD3D->areVertexUniformsDirty() && !programD3D->areFragmentUniformsDirty())
{
return gl::NoError();
}
......
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