Commit 2b858c2f by Jamie Madill Committed by Commit Bot

Vulkan: More micro-optimizations to setupDraw.

Still a hotspot but much improved. Bug: angleproject:2786 Change-Id: Ie68ff314e6c952f281b48f6d9af37b5dcd194d6a Reviewed-on: https://chromium-review.googlesource.com/1194882 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org>
parent a153eddb
...@@ -138,6 +138,13 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer) ...@@ -138,6 +138,13 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
mNewCommandBufferDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS); mNewCommandBufferDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
mNewCommandBufferDirtyBits.set(DIRTY_BIT_INDEX_BUFFER); mNewCommandBufferDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
mNewCommandBufferDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS); mNewCommandBufferDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS);
mDirtyBitHandlers[DIRTY_BIT_DEFAULT_ATTRIBS] = &ContextVk::handleDirtyDefaultAttribs;
mDirtyBitHandlers[DIRTY_BIT_PIPELINE] = &ContextVk::handleDirtyPipeline;
mDirtyBitHandlers[DIRTY_BIT_TEXTURES] = &ContextVk::handleDirtyTextures;
mDirtyBitHandlers[DIRTY_BIT_VERTEX_BUFFERS] = &ContextVk::handleDirtyVertexBuffers;
mDirtyBitHandlers[DIRTY_BIT_INDEX_BUFFER] = &ContextVk::handleDirtyIndexBuffer;
mDirtyBitHandlers[DIRTY_BIT_DESCRIPTOR_SETS] = &ContextVk::handleDirtyDescriptorSets;
} }
ContextVk::~ContextVk() = default; ContextVk::~ContextVk() = default;
...@@ -254,13 +261,14 @@ angle::Result ContextVk::initPipeline(const gl::DrawCallParams &drawCallParams) ...@@ -254,13 +261,14 @@ angle::Result ContextVk::initPipeline(const gl::DrawCallParams &drawCallParams)
angle::Result ContextVk::setupDraw(const gl::Context *context, angle::Result ContextVk::setupDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams, const gl::DrawCallParams &drawCallParams,
const DirtyBits &dirtyBitsMask, DirtyBits dirtyBitMask,
vk::CommandBuffer **commandBufferOut) vk::CommandBuffer **commandBufferOut)
{ {
// Set any dirty bits that depend on draw call parameters or other objects. // Set any dirty bits that depend on draw call parameters or other objects.
if (drawCallParams.mode() != mCurrentDrawMode) if (drawCallParams.mode() != mCurrentDrawMode)
{ {
invalidateCurrentPipeline(); mCurrentPipeline = nullptr;
mDirtyBits.set(DIRTY_BIT_PIPELINE);
mCurrentDrawMode = drawCallParams.mode(); mCurrentDrawMode = drawCallParams.mode();
} }
...@@ -282,102 +290,16 @@ angle::Result ContextVk::setupDraw(const gl::Context *context, ...@@ -282,102 +290,16 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
mDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS); mDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS);
} }
DirtyBits dirtyBits = mDirtyBits & dirtyBitMask;
if (dirtyBits.none())
return angle::Result::Continue();
// Flush any relevant dirty bits. // Flush any relevant dirty bits.
for (size_t dirtyBit : mDirtyBits &dirtyBitsMask) for (size_t dirtyBit : dirtyBits)
{ {
mDirtyBits.reset(dirtyBit); mDirtyBits.reset(dirtyBit);
switch (dirtyBit) ANGLE_TRY((this->*mDirtyBitHandlers[dirtyBit])(context, drawCallParams, *commandBufferOut));
{
case DIRTY_BIT_DEFAULT_ATTRIBS:
ANGLE_TRY(updateDefaultAttributes());
break;
case DIRTY_BIT_PIPELINE:
{
if (!mCurrentPipeline)
{
ANGLE_TRY(initPipeline(drawCallParams));
}
(*commandBufferOut)
->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline->get());
// Update the queue serial for the pipeline object.
ASSERT(mCurrentPipeline && mCurrentPipeline->valid());
mCurrentPipeline->updateSerial(mRenderer->getCurrentQueueSerial());
break;
}
case DIRTY_BIT_TEXTURES:
{
ANGLE_TRY(updateActiveTextures(context));
// TODO(jmadill): Should probably merge this for loop with programVk's descriptor
// update.
for (size_t textureIndex : mProgram->getState().getActiveSamplersMask())
{
// Ensure any writes to the textures are flushed before we read from them.
TextureVk *textureVk = mActiveTextures[textureIndex];
ANGLE_TRY(textureVk->ensureImageInitialized(this));
textureVk->addReadDependency(mDrawFramebuffer);
}
if (mProgram->hasTextures())
{
ANGLE_TRY(mProgram->updateTexturesDescriptorSet(this));
}
break;
}
case DIRTY_BIT_DESCRIPTOR_SETS:
{
ANGLE_TRY(mProgram->updateDescriptorSets(this, drawCallParams, *commandBufferOut));
// Bind the graphics descriptor sets.
(*commandBufferOut)
->bindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,
mProgram->getPipelineLayout(),
kDriverUniformsDescriptorSetIndex, 1,
&mDriverUniformsDescriptorSet, 0, nullptr);
break;
}
case DIRTY_BIT_VERTEX_BUFFERS:
{
BindNonNullVertexBufferRanges(*commandBufferOut,
mProgram->getState().getActiveAttribLocationsMask(),
mProgram->getState().getMaxActiveAttribLocation(),
mVertexArray->getCurrentArrayBufferHandles(),
mVertexArray->getCurrentArrayBufferOffsets());
const auto &arrayBufferResources = mVertexArray->getCurrentArrayBufferResources();
for (size_t attribIndex : context->getStateCache().getActiveBufferedAttribsMask())
{
if (arrayBufferResources[attribIndex])
arrayBufferResources[attribIndex]->addReadDependency(mDrawFramebuffer);
}
break;
}
case DIRTY_BIT_INDEX_BUFFER:
{
(*commandBufferOut)
->bindIndexBuffer(mVertexArray->getCurrentElementArrayBufferHandle(),
mVertexArray->getCurrentElementArrayBufferOffset(),
gl_vk::GetIndexType(mCurrentDrawElementsType));
vk::CommandGraphResource *elementArrayBufferResource =
mVertexArray->getCurrentElementArrayBufferResource();
if (elementArrayBufferResource)
{
elementArrayBufferResource->addReadDependency(mDrawFramebuffer);
}
break;
}
default:
UNREACHABLE();
break;
}
} }
return angle::Result::Continue(); return angle::Result::Continue();
...@@ -428,6 +350,109 @@ angle::Result ContextVk::setupLineLoopDraw(const gl::Context *context, ...@@ -428,6 +350,109 @@ angle::Result ContextVk::setupLineLoopDraw(const gl::Context *context,
return setupDraw(context, drawCallParams, mIndexedDirtyBitsMask, commandBufferOut); return setupDraw(context, drawCallParams, mIndexedDirtyBitsMask, commandBufferOut);
} }
angle::Result ContextVk::handleDirtyDefaultAttribs(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer)
{
ASSERT(mDirtyDefaultAttribsMask.any());
for (size_t attribIndex : mDirtyDefaultAttribsMask)
{
ANGLE_TRY(updateDefaultAttribute(attribIndex))
}
mDirtyDefaultAttribsMask.reset();
return angle::Result::Continue();
}
angle::Result ContextVk::handleDirtyPipeline(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer)
{
if (!mCurrentPipeline)
{
ANGLE_TRY(initPipeline(drawCallParams));
}
commandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline->get());
// Update the queue serial for the pipeline object.
ASSERT(mCurrentPipeline && mCurrentPipeline->valid());
mCurrentPipeline->updateSerial(mRenderer->getCurrentQueueSerial());
return angle::Result::Continue();
}
angle::Result ContextVk::handleDirtyTextures(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer)
{
ANGLE_TRY(updateActiveTextures(context));
// TODO(jmadill): Should probably merge this for loop with programVk's descriptor update.
for (size_t textureIndex : mProgram->getState().getActiveSamplersMask())
{
// Ensure any writes to the textures are flushed before we read from them.
TextureVk *textureVk = mActiveTextures[textureIndex];
ANGLE_TRY(textureVk->ensureImageInitialized(this));
textureVk->addReadDependency(mDrawFramebuffer);
}
if (mProgram->hasTextures())
{
ANGLE_TRY(mProgram->updateTexturesDescriptorSet(this));
}
return angle::Result::Continue();
}
angle::Result ContextVk::handleDirtyVertexBuffers(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer)
{
BindNonNullVertexBufferRanges(
commandBuffer, mProgram->getState().getActiveAttribLocationsMask(),
mProgram->getState().getMaxActiveAttribLocation(),
mVertexArray->getCurrentArrayBufferHandles(), mVertexArray->getCurrentArrayBufferOffsets());
const auto &arrayBufferResources = mVertexArray->getCurrentArrayBufferResources();
for (size_t attribIndex : context->getStateCache().getActiveBufferedAttribsMask())
{
if (arrayBufferResources[attribIndex])
arrayBufferResources[attribIndex]->addReadDependency(mDrawFramebuffer);
}
return angle::Result::Continue();
}
angle::Result ContextVk::handleDirtyIndexBuffer(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer)
{
commandBuffer->bindIndexBuffer(mVertexArray->getCurrentElementArrayBufferHandle(),
mVertexArray->getCurrentElementArrayBufferOffset(),
gl_vk::GetIndexType(mCurrentDrawElementsType));
vk::CommandGraphResource *elementArrayBufferResource =
mVertexArray->getCurrentElementArrayBufferResource();
if (elementArrayBufferResource)
{
elementArrayBufferResource->addReadDependency(mDrawFramebuffer);
}
return angle::Result::Continue();
}
angle::Result ContextVk::handleDirtyDescriptorSets(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer)
{
ANGLE_TRY(mProgram->updateDescriptorSets(this, drawCallParams, commandBuffer));
// Bind the graphics descriptor sets.
commandBuffer->bindDescriptorSets(
VK_PIPELINE_BIND_POINT_GRAPHICS, mProgram->getPipelineLayout(),
kDriverUniformsDescriptorSetIndex, 1, &mDriverUniformsDescriptorSet, 0, nullptr);
return angle::Result::Continue();
}
gl::Error ContextVk::drawArrays(const gl::Context *context, gl::Error ContextVk::drawArrays(const gl::Context *context,
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
GLint first, GLint first,
...@@ -1182,19 +1207,6 @@ void ContextVk::invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask) ...@@ -1182,19 +1207,6 @@ void ContextVk::invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask)
} }
} }
angle::Result ContextVk::updateDefaultAttributes()
{
ASSERT(mDirtyDefaultAttribsMask.any());
for (size_t attribIndex : mDirtyDefaultAttribsMask)
{
ANGLE_TRY(updateDefaultAttribute(attribIndex))
}
mDirtyDefaultAttribsMask.reset();
return angle::Result::Continue();
}
angle::Result ContextVk::updateDefaultAttribute(size_t attribIndex) angle::Result ContextVk::updateDefaultAttribute(size_t attribIndex)
{ {
vk::DynamicBuffer &defaultBuffer = mDefaultAttribBuffers[attribIndex]; vk::DynamicBuffer &defaultBuffer = mDefaultAttribBuffers[attribIndex];
......
...@@ -191,10 +191,16 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -191,10 +191,16 @@ class ContextVk : public ContextImpl, public vk::Context
using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>; using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
using DirtyBitHandler = angle::Result (ContextVk::*)(const gl::Context *,
const gl::DrawCallParams &,
vk::CommandBuffer *commandBuffer);
std::array<DirtyBitHandler, DIRTY_BIT_MAX> mDirtyBitHandlers;
angle::Result initPipeline(const gl::DrawCallParams &drawCallParams); angle::Result initPipeline(const gl::DrawCallParams &drawCallParams);
angle::Result setupDraw(const gl::Context *context, angle::Result setupDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams, const gl::DrawCallParams &drawCallParams,
const DirtyBits &dirtyBitsMask, DirtyBits dirtyBitMask,
vk::CommandBuffer **commandBufferOut); vk::CommandBuffer **commandBufferOut);
angle::Result setupIndexedDraw(const gl::Context *context, angle::Result setupIndexedDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams, const gl::DrawCallParams &drawCallParams,
...@@ -209,11 +215,29 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -209,11 +215,29 @@ class ContextVk : public ContextImpl, public vk::Context
angle::Result updateDriverUniforms(const gl::State &glState); angle::Result updateDriverUniforms(const gl::State &glState);
angle::Result updateActiveTextures(const gl::Context *context); angle::Result updateActiveTextures(const gl::Context *context);
angle::Result updateDefaultAttributes();
angle::Result updateDefaultAttribute(size_t attribIndex); angle::Result updateDefaultAttribute(size_t attribIndex);
void invalidateCurrentTextures(); void invalidateCurrentTextures();
angle::Result handleDirtyDefaultAttribs(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyPipeline(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyTextures(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyVertexBuffers(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyIndexBuffer(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyDescriptorSets(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer);
vk::PipelineAndSerial *mCurrentPipeline; vk::PipelineAndSerial *mCurrentPipeline;
gl::PrimitiveMode mCurrentDrawMode; gl::PrimitiveMode mCurrentDrawMode;
......
...@@ -176,8 +176,7 @@ bool ProgramVk::ShaderInfo::valid() const ...@@ -176,8 +176,7 @@ bool ProgramVk::ShaderInfo::valid() const
// ProgramVk implementation. // ProgramVk implementation.
ProgramVk::DefaultUniformBlock::DefaultUniformBlock() ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
: storage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, : storage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
kUniformBlockDynamicBufferMinSize), kUniformBlockDynamicBufferMinSize)
uniformsDirty(false)
{ {
} }
...@@ -397,9 +396,6 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext) ...@@ -397,9 +396,6 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
} }
} }
bool anyDirty = false;
bool allDirty = true;
for (vk::ShaderType shaderType : vk::AllShaderTypes()) for (vk::ShaderType shaderType : vk::AllShaderTypes())
{ {
if (requiredBufferSize[shaderType] > 0) if (requiredBufferSize[shaderType] > 0)
...@@ -416,20 +412,14 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext) ...@@ -416,20 +412,14 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
// Initialize uniform buffer memory to zero by default. // Initialize uniform buffer memory to zero by default.
mDefaultUniformBlocks[shaderType].uniformData.fill(0); mDefaultUniformBlocks[shaderType].uniformData.fill(0);
mDefaultUniformBlocks[shaderType].uniformsDirty = true; mDefaultUniformBlocksDirty.set(shaderType);
anyDirty = true;
}
else
{
allDirty = false;
} }
} }
if (anyDirty) if (mDefaultUniformBlocksDirty.any())
{ {
// Initialize the "empty" uniform block if necessary. // Initialize the "empty" uniform block if necessary.
if (!allDirty) if (!mDefaultUniformBlocksDirty.all())
{ {
VkBufferCreateInfo uniformBufferInfo; VkBufferCreateInfo uniformBufferInfo;
uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
...@@ -475,8 +465,9 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum ...@@ -475,8 +465,9 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum
if (linkedUniform.typeInfo->type == entryPointType) if (linkedUniform.typeInfo->type == entryPointType)
{ {
for (auto &uniformBlock : mDefaultUniformBlocks) for (vk::ShaderType shaderType : vk::AllShaderTypes())
{ {
DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[shaderType];
const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location]; const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
// Assume an offset of -1 means the block is unused. // Assume an offset of -1 means the block is unused.
...@@ -488,13 +479,14 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum ...@@ -488,13 +479,14 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum
const GLint componentCount = linkedUniform.typeInfo->componentCount; const GLint componentCount = linkedUniform.typeInfo->componentCount;
UpdateDefaultUniformBlock(count, locationInfo.arrayIndex, componentCount, v, layoutInfo, UpdateDefaultUniformBlock(count, locationInfo.arrayIndex, componentCount, v, layoutInfo,
&uniformBlock.uniformData); &uniformBlock.uniformData);
uniformBlock.uniformsDirty = true; mDefaultUniformBlocksDirty.set(shaderType);
} }
} }
else else
{ {
for (auto &uniformBlock : mDefaultUniformBlocks) for (vk::ShaderType shaderType : vk::AllShaderTypes())
{ {
DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[shaderType];
const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location]; const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
// Assume an offset of -1 means the block is unused. // Assume an offset of -1 means the block is unused.
...@@ -521,7 +513,8 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum ...@@ -521,7 +513,8 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum
dest[c] = (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE; dest[c] = (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE;
} }
} }
uniformBlock.uniformsDirty = true;
mDefaultUniformBlocksDirty.set(shaderType);
} }
} }
} }
...@@ -626,8 +619,9 @@ void ProgramVk::setUniformMatrixfv(GLint location, ...@@ -626,8 +619,9 @@ void ProgramVk::setUniformMatrixfv(GLint location,
const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location]; const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index]; const gl::LinkedUniform &linkedUniform = mState.getUniforms()[locationInfo.index];
for (auto &uniformBlock : mDefaultUniformBlocks) for (vk::ShaderType shaderType : vk::AllShaderTypes())
{ {
DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[shaderType];
const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location]; const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
// Assume an offset of -1 means the block is unused. // Assume an offset of -1 means the block is unused.
...@@ -643,7 +637,10 @@ void ProgramVk::setUniformMatrixfv(GLint location, ...@@ -643,7 +637,10 @@ void ProgramVk::setUniformMatrixfv(GLint location,
// If the uniformsDirty flag was true, we don't want to flip it to false here if the // If the uniformsDirty flag was true, we don't want to flip it to false here if the
// setter did not update any data. We still want the uniform to be included when we'll // setter did not update any data. We still want the uniform to be included when we'll
// update the descriptor sets. // update the descriptor sets.
uniformBlock.uniformsDirty = uniformBlock.uniformsDirty || updated; if (updated)
{
mDefaultUniformBlocksDirty.set(shaderType);
}
} }
} }
...@@ -787,13 +784,13 @@ angle::Result ProgramVk::updateUniforms(ContextVk *contextVk) ...@@ -787,13 +784,13 @@ angle::Result ProgramVk::updateUniforms(ContextVk *contextVk)
{ {
DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[shaderType]; DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[shaderType];
if (uniformBlock.uniformsDirty) if (mDefaultUniformBlocksDirty[shaderType])
{ {
bool bufferModified = false; bool bufferModified = false;
ANGLE_TRY(SyncDefaultUniformBlock(contextVk, &uniformBlock.storage, ANGLE_TRY(SyncDefaultUniformBlock(contextVk, &uniformBlock.storage,
uniformBlock.uniformData, uniformBlock.uniformData,
&mUniformBlocksOffsets[shaderType], &bufferModified)); &mUniformBlocksOffsets[shaderType], &bufferModified));
uniformBlock.uniformsDirty = false; mDefaultUniformBlocksDirty.reset(shaderType);
if (bufferModified) if (bufferModified)
{ {
......
...@@ -116,11 +116,7 @@ class ProgramVk : public ProgramImpl ...@@ -116,11 +116,7 @@ class ProgramVk : public ProgramImpl
bool hasTextures() const { return !mState.getSamplerBindings().empty(); } bool hasTextures() const { return !mState.getSamplerBindings().empty(); }
bool dirtyUniforms() const bool dirtyUniforms() const { return mDefaultUniformBlocksDirty.any(); }
{
return (mDefaultUniformBlocks[vk::ShaderType::VertexShader].uniformsDirty ||
mDefaultUniformBlocks[vk::ShaderType::FragmentShader].uniformsDirty);
}
private: private:
template <int cols, int rows> template <int cols, int rows>
...@@ -154,7 +150,6 @@ class ProgramVk : public ProgramImpl ...@@ -154,7 +150,6 @@ class ProgramVk : public ProgramImpl
// Shadow copies of the shader uniform data. // Shadow copies of the shader uniform data.
angle::MemoryBuffer uniformData; angle::MemoryBuffer uniformData;
bool uniformsDirty;
// Since the default blocks are laid out in std140, this tells us where to write on a call // Since the default blocks are laid out in std140, this tells us where to write on a call
// to a setUniform method. They are arranged in uniform location order. // to a setUniform method. They are arranged in uniform location order.
...@@ -162,6 +157,7 @@ class ProgramVk : public ProgramImpl ...@@ -162,6 +157,7 @@ class ProgramVk : public ProgramImpl
}; };
vk::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks; vk::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks;
vk::ShaderBitSet mDefaultUniformBlocksDirty;
vk::ShaderMap<uint32_t> mUniformBlocksOffsets; vk::ShaderMap<uint32_t> mUniformBlocksOffsets;
// This is a special "empty" placeholder buffer for when a shader has no uniforms. // This is a special "empty" placeholder buffer for when a shader has no uniforms.
......
...@@ -679,6 +679,8 @@ enum class ShaderType ...@@ -679,6 +679,8 @@ enum class ShaderType
template <typename T> template <typename T>
using ShaderMap = angle::PackedEnumMap<ShaderType, T>; using ShaderMap = angle::PackedEnumMap<ShaderType, T>;
using ShaderBitSet = angle::PackedEnumBitSet<ShaderType>;
using AllShaderTypes = angle::AllEnums<vk::ShaderType>; using AllShaderTypes = angle::AllEnums<vk::ShaderType>;
angle::Result InitShaderAndSerial(Context *context, angle::Result InitShaderAndSerial(Context *context,
......
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