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
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 setupDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
const DirtyBits &dirtyBitsMask,
DirtyBits dirtyBitMask,
vk::CommandBuffer **commandBufferOut);
angle::Result setupIndexedDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
......@@ -209,11 +215,29 @@ class ContextVk : public ContextImpl, public vk::Context
angle::Result updateDriverUniforms(const gl::State &glState);
angle::Result updateActiveTextures(const gl::Context *context);
angle::Result updateDefaultAttributes();
angle::Result updateDefaultAttribute(size_t attribIndex);
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;
gl::PrimitiveMode mCurrentDrawMode;
......
......@@ -176,8 +176,7 @@ bool ProgramVk::ShaderInfo::valid() const
// ProgramVk implementation.
ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
: storage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
kUniformBlockDynamicBufferMinSize),
uniformsDirty(false)
kUniformBlockDynamicBufferMinSize)
{
}
......@@ -397,9 +396,6 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
}
}
bool anyDirty = false;
bool allDirty = true;
for (vk::ShaderType shaderType : vk::AllShaderTypes())
{
if (requiredBufferSize[shaderType] > 0)
......@@ -416,20 +412,14 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
// Initialize uniform buffer memory to zero by default.
mDefaultUniformBlocks[shaderType].uniformData.fill(0);
mDefaultUniformBlocks[shaderType].uniformsDirty = true;
anyDirty = true;
}
else
{
allDirty = false;
mDefaultUniformBlocksDirty.set(shaderType);
}
}
if (anyDirty)
if (mDefaultUniformBlocksDirty.any())
{
// Initialize the "empty" uniform block if necessary.
if (!allDirty)
if (!mDefaultUniformBlocksDirty.all())
{
VkBufferCreateInfo uniformBufferInfo;
uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
......@@ -475,8 +465,9 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum
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];
// 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
const GLint componentCount = linkedUniform.typeInfo->componentCount;
UpdateDefaultUniformBlock(count, locationInfo.arrayIndex, componentCount, v, layoutInfo,
&uniformBlock.uniformData);
uniformBlock.uniformsDirty = true;
mDefaultUniformBlocksDirty.set(shaderType);
}
}
else
{
for (auto &uniformBlock : mDefaultUniformBlocks)
for (vk::ShaderType shaderType : vk::AllShaderTypes())
{
DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[shaderType];
const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
// 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
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,
const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
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];
// Assume an offset of -1 means the block is unused.
......@@ -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
// setter did not update any data. We still want the uniform to be included when we'll
// update the descriptor sets.
uniformBlock.uniformsDirty = uniformBlock.uniformsDirty || updated;
if (updated)
{
mDefaultUniformBlocksDirty.set(shaderType);
}
}
}
......@@ -787,13 +784,13 @@ angle::Result ProgramVk::updateUniforms(ContextVk *contextVk)
{
DefaultUniformBlock &uniformBlock = mDefaultUniformBlocks[shaderType];
if (uniformBlock.uniformsDirty)
if (mDefaultUniformBlocksDirty[shaderType])
{
bool bufferModified = false;
ANGLE_TRY(SyncDefaultUniformBlock(contextVk, &uniformBlock.storage,
uniformBlock.uniformData,
&mUniformBlocksOffsets[shaderType], &bufferModified));
uniformBlock.uniformsDirty = false;
mDefaultUniformBlocksDirty.reset(shaderType);
if (bufferModified)
{
......
......@@ -116,11 +116,7 @@ class ProgramVk : public ProgramImpl
bool hasTextures() const { return !mState.getSamplerBindings().empty(); }
bool dirtyUniforms() const
{
return (mDefaultUniformBlocks[vk::ShaderType::VertexShader].uniformsDirty ||
mDefaultUniformBlocks[vk::ShaderType::FragmentShader].uniformsDirty);
}
bool dirtyUniforms() const { return mDefaultUniformBlocksDirty.any(); }
private:
template <int cols, int rows>
......@@ -154,7 +150,6 @@ class ProgramVk : public ProgramImpl
// Shadow copies of the shader uniform data.
angle::MemoryBuffer uniformData;
bool uniformsDirty;
// 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.
......@@ -162,6 +157,7 @@ class ProgramVk : public ProgramImpl
};
vk::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks;
vk::ShaderBitSet mDefaultUniformBlocksDirty;
vk::ShaderMap<uint32_t> mUniformBlocksOffsets;
// This is a special "empty" placeholder buffer for when a shader has no uniforms.
......
......@@ -679,6 +679,8 @@ enum class ShaderType
template <typename T>
using ShaderMap = angle::PackedEnumMap<ShaderType, T>;
using ShaderBitSet = angle::PackedEnumBitSet<ShaderType>;
using AllShaderTypes = angle::AllEnums<vk::ShaderType>;
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