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
...@@ -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