Commit 88fc6da3 by Jamie Madill Committed by Commit Bot

Vulkan: Mega-refactor to VertexArrayVk.

This moves a lot of the code in VertexArrayVk into ContextVk. Having the code in a centralized place makes the code a bit more organized since the Context is reponsible for binding state to the command buffers. It also makes it easier to use dirty bits to track the command buffer state. Bug: angleproject:2786 Change-Id: I5cefbb14028e8f3fe651f26e997ca88f8f1c7628 Reviewed-on: https://chromium-review.googlesource.com/1188953 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 253038d8
...@@ -98,6 +98,7 @@ class StateCache final : angle::NonCopyable ...@@ -98,6 +98,7 @@ class StateCache final : angle::NonCopyable
AttributesMask getActiveClientAttribsMask() const { return mCachedActiveClientAttribsMask; } AttributesMask getActiveClientAttribsMask() const { return mCachedActiveClientAttribsMask; }
AttributesMask getActiveDefaultAttribsMask() const { return mCachedActiveDefaultAttribsMask; } AttributesMask getActiveDefaultAttribsMask() const { return mCachedActiveDefaultAttribsMask; }
bool hasAnyEnabledClientAttrib() const { return mCachedHasAnyEnabledClientAttrib; } bool hasAnyEnabledClientAttrib() const { return mCachedHasAnyEnabledClientAttrib; }
bool hasAnyActiveClientAttrib() const { return mCachedActiveClientAttribsMask.any(); }
// Places that can trigger updateVertexElementLimits: // Places that can trigger updateVertexElementLimits:
// 1. onVertexArrayBindingChange. // 1. onVertexArrayBindingChange.
......
...@@ -158,6 +158,7 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -158,6 +158,7 @@ class ContextVk : public ContextImpl, public vk::Context
void invalidateCurrentPipeline(); void invalidateCurrentPipeline();
void invalidateDefaultAttribute(size_t attribIndex); void invalidateDefaultAttribute(size_t attribIndex);
void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
vk::DynamicDescriptorPool *getDynamicDescriptorPool(uint32_t descriptorSetIndex); vk::DynamicDescriptorPool *getDynamicDescriptorPool(uint32_t descriptorSetIndex);
...@@ -173,19 +174,27 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -173,19 +174,27 @@ class ContextVk : public ContextImpl, public vk::Context
void handleError(VkResult errorCode, const char *file, unsigned int line) override; void handleError(VkResult errorCode, const char *file, unsigned int line) override;
const gl::ActiveTextureArray<TextureVk *> &getActiveTextures() const; const gl::ActiveTextureArray<TextureVk *> &getActiveTextures() const;
void setIndexBufferDirty() { mIndexBufferDirty = true; }
private: private:
gl::Error initPipeline(const gl::DrawCallParams &drawCallParams); angle::Result initPipeline(const gl::DrawCallParams &drawCallParams);
gl::Error setupDraw(const gl::Context *context, angle::Result setupDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams, const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer **commandBufferOut, bool useIndexBuffer,
bool *shouldApplyVertexArrayOut); vk::CommandBuffer **commandBufferOut);
angle::Result setupIndexedDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer **commandBufferOut);
angle::Result setupLineLoopDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer **commandBufferOut);
void updateScissor(const gl::State &glState) const; void updateScissor(const gl::State &glState) const;
void updateFlipViewportDrawFramebuffer(const gl::State &glState); void updateFlipViewportDrawFramebuffer(const gl::State &glState);
void updateFlipViewportReadFramebuffer(const gl::State &glState); void updateFlipViewportReadFramebuffer(const gl::State &glState);
angle::Result updateDriverUniforms(const gl::State &glState); angle::Result updateDriverUniforms(const gl::State &glState);
gl::Error updateActiveTextures(const gl::Context *context); angle::Result updateActiveTextures(const gl::Context *context);
angle::Result updateDefaultAttributes(); angle::Result updateDefaultAttributes();
angle::Result updateDefaultAttribute(size_t attribIndex); angle::Result updateDefaultAttribute(size_t attribIndex);
...@@ -200,9 +209,18 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -200,9 +209,18 @@ class ContextVk : public ContextImpl, public vk::Context
// threads simultaneously. Hence, we keep them in the ContextVk instead of the RendererVk. // threads simultaneously. Hence, we keep them in the ContextVk instead of the RendererVk.
vk::DescriptorSetLayoutArray<vk::DynamicDescriptorPool> mDynamicDescriptorPools; vk::DescriptorSetLayoutArray<vk::DynamicDescriptorPool> mDynamicDescriptorPools;
// Triggers adding dependencies to the command graph. // Dirty bits.
// TODO(jmadill): Make this into a dirty bit set. http://anglebug.com/2786
bool mDirtyDefaultAttribs;
bool mPipelineDirty;
bool mTexturesDirty; bool mTexturesDirty;
bool mVertexArrayBindingHasChanged; bool mVertexBuffersDirty;
bool mIndexBufferDirty;
bool mDescriptorSetsDirty;
// The offset we had the last time we bound the index buffer.
const GLvoid *mLastIndexBufferOffset;
GLenum mCurrentDrawElementsType;
// Cached clear value/mask for color and depth/stencil. // Cached clear value/mask for color and depth/stencil.
VkClearValue mClearColorValue; VkClearValue mClearColorValue;
...@@ -235,7 +253,7 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -235,7 +253,7 @@ class ContextVk : public ContextImpl, public vk::Context
gl::ActiveTextureArray<TextureVk *> mActiveTextures; gl::ActiveTextureArray<TextureVk *> mActiveTextures;
// "Current Value" aka default vertex attribute state. // "Current Value" aka default vertex attribute state.
gl::AttributesMask mDirtyDefaultAttribs; gl::AttributesMask mDirtyDefaultAttribsMask;
gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers; gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers;
}; };
} // namespace rx } // namespace rx
......
...@@ -183,8 +183,7 @@ ProgramVk::DefaultUniformBlock::DefaultUniformBlock() ...@@ -183,8 +183,7 @@ ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
ProgramVk::DefaultUniformBlock::~DefaultUniformBlock() = default; ProgramVk::DefaultUniformBlock::~DefaultUniformBlock() = default;
ProgramVk::ProgramVk(const gl::ProgramState &state) ProgramVk::ProgramVk(const gl::ProgramState &state) : ProgramImpl(state), mUniformBlocksOffsets{}
: ProgramImpl(state), mUniformBlocksOffsets{}, mDirtyTextures(false)
{ {
mUsedDescriptorSetRange.invalidate(); mUsedDescriptorSetRange.invalidate();
} }
...@@ -222,7 +221,6 @@ angle::Result ProgramVk::reset(ContextVk *contextVk) ...@@ -222,7 +221,6 @@ angle::Result ProgramVk::reset(ContextVk *contextVk)
mDescriptorSets.clear(); mDescriptorSets.clear();
mUsedDescriptorSetRange.invalidate(); mUsedDescriptorSetRange.invalidate();
mDirtyTextures = false;
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -276,7 +274,6 @@ gl::LinkResult ProgramVk::linkImpl(const gl::Context *glContext, ...@@ -276,7 +274,6 @@ gl::LinkResult ProgramVk::linkImpl(const gl::Context *glContext,
{ {
// Ensure the descriptor set range includes the textures at position 1. // Ensure the descriptor set range includes the textures at position 1.
mUsedDescriptorSetRange.extend(kTextureDescriptorSetIndex); mUsedDescriptorSetRange.extend(kTextureDescriptorSetIndex);
mDirtyTextures = true;
} }
// Store a reference to the pipeline and descriptor set layouts. This will create them if they // Store a reference to the pipeline and descriptor set layouts. This will create them if they
...@@ -334,7 +331,6 @@ gl::LinkResult ProgramVk::linkImpl(const gl::Context *glContext, ...@@ -334,7 +331,6 @@ gl::LinkResult ProgramVk::linkImpl(const gl::Context *glContext,
{ {
// Ensure the descriptor set range includes the textures at position 1. // Ensure the descriptor set range includes the textures at position 1.
mUsedDescriptorSetRange.extend(kTextureDescriptorSetIndex); mUsedDescriptorSetRange.extend(kTextureDescriptorSetIndex);
mDirtyTextures = true;
} }
} }
...@@ -783,11 +779,7 @@ void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint ...@@ -783,11 +779,7 @@ void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint
angle::Result ProgramVk::updateUniforms(ContextVk *contextVk) angle::Result ProgramVk::updateUniforms(ContextVk *contextVk)
{ {
if (!mDefaultUniformBlocks[vk::ShaderType::VertexShader].uniformsDirty && ASSERT(dirtyUniforms());
!mDefaultUniformBlocks[vk::ShaderType::FragmentShader].uniformsDirty)
{
return angle::Result::Continue();
}
// Update buffer memory by immediate mapping. This immediate update only works once. // Update buffer memory by immediate mapping. This immediate update only works once.
bool anyNewBufferAllocated = false; bool anyNewBufferAllocated = false;
...@@ -865,11 +857,7 @@ angle::Result ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk ...@@ -865,11 +857,7 @@ angle::Result ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk
angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk) angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
{ {
if (mState.getSamplerBindings().empty() || !mDirtyTextures) ASSERT(hasTextures());
{
return angle::Result::Continue();
}
ANGLE_TRY(allocateDescriptorSet(contextVk, kTextureDescriptorSetIndex)); ANGLE_TRY(allocateDescriptorSet(contextVk, kTextureDescriptorSetIndex));
ASSERT(mUsedDescriptorSetRange.contains(1)); ASSERT(mUsedDescriptorSetRange.contains(1));
...@@ -923,15 +911,9 @@ angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk) ...@@ -923,15 +911,9 @@ angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
ASSERT(writeCount > 0); ASSERT(writeCount > 0);
vkUpdateDescriptorSets(device, writeCount, writeDescriptorInfo.data(), 0, nullptr); vkUpdateDescriptorSets(device, writeCount, writeDescriptorInfo.data(), 0, nullptr);
mDirtyTextures = false;
return angle::Result::Continue(); return angle::Result::Continue();
} }
void ProgramVk::invalidateTextures()
{
mDirtyTextures = true;
}
void ProgramVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize) void ProgramVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize)
{ {
for (DefaultUniformBlock &block : mDefaultUniformBlocks) for (DefaultUniformBlock &block : mDefaultUniformBlocks)
...@@ -942,17 +924,10 @@ void ProgramVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize) ...@@ -942,17 +924,10 @@ void ProgramVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize)
angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk, angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk,
const gl::DrawCallParams &drawCallParams, const gl::DrawCallParams &drawCallParams,
VkDescriptorSet driverUniformsDescriptorSet,
vk::CommandBuffer *commandBuffer) vk::CommandBuffer *commandBuffer)
{ {
// TODO(jmadill): Line rasterization emulation shaders. http://anglebug.com/2598 // TODO(jmadill): Line rasterization emulation shaders. http://anglebug.com/2598
// Can probably use better dirty bits here. // Can probably use better dirty bits here.
ANGLE_TRY(updateUniforms(contextVk));
ANGLE_TRY(updateTexturesDescriptorSet(contextVk));
commandBuffer->bindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, mPipelineLayout.get(),
kDriverUniformsDescriptorSetIndex, 1,
&driverUniformsDescriptorSet, 0, nullptr);
if (mUsedDescriptorSetRange.empty()) if (mUsedDescriptorSetRange.empty())
return angle::Result::Continue(); return angle::Result::Continue();
......
...@@ -103,17 +103,25 @@ class ProgramVk : public ProgramImpl ...@@ -103,17 +103,25 @@ class ProgramVk : public ProgramImpl
const vk::PipelineLayout **pipelineLayoutOut); const vk::PipelineLayout **pipelineLayoutOut);
angle::Result updateUniforms(ContextVk *contextVk); angle::Result updateUniforms(ContextVk *contextVk);
angle::Result updateTexturesDescriptorSet(ContextVk *contextVk);
void invalidateTextures();
angle::Result updateDescriptorSets(ContextVk *contextVk, angle::Result updateDescriptorSets(ContextVk *contextVk,
const gl::DrawCallParams &drawCallParams, const gl::DrawCallParams &drawCallParams,
VkDescriptorSet driverUniformsDescriptorSet,
vk::CommandBuffer *commandBuffer); vk::CommandBuffer *commandBuffer);
// For testing only. // For testing only.
void setDefaultUniformBlocksMinSizeForTesting(size_t minSize); void setDefaultUniformBlocksMinSizeForTesting(size_t minSize);
const vk::PipelineLayout &getPipelineLayout() const { return mPipelineLayout.get(); }
bool hasTextures() const { return !mState.getSamplerBindings().empty(); }
bool dirtyUniforms() const
{
return (mDefaultUniformBlocks[vk::ShaderType::VertexShader].uniformsDirty ||
mDefaultUniformBlocks[vk::ShaderType::FragmentShader].uniformsDirty);
}
private: private:
template <int cols, int rows> template <int cols, int rows>
void setUniformMatrixfv(GLint location, void setUniformMatrixfv(GLint location,
...@@ -126,7 +134,6 @@ class ProgramVk : public ProgramImpl ...@@ -126,7 +134,6 @@ class ProgramVk : public ProgramImpl
angle::Result initDefaultUniformBlocks(const gl::Context *glContext); angle::Result initDefaultUniformBlocks(const gl::Context *glContext);
angle::Result updateDefaultUniformsDescriptorSet(ContextVk *contextVk); angle::Result updateDefaultUniformsDescriptorSet(ContextVk *contextVk);
angle::Result updateTexturesDescriptorSet(ContextVk *contextVk);
template <class T> template <class T>
void getUniformImpl(GLint location, T *v, GLenum entryPointType) const; void getUniformImpl(GLint location, T *v, GLenum entryPointType) const;
...@@ -165,7 +172,6 @@ class ProgramVk : public ProgramImpl ...@@ -165,7 +172,6 @@ class ProgramVk : public ProgramImpl
// Descriptor sets for uniform blocks and textures for this program. // Descriptor sets for uniform blocks and textures for this program.
std::vector<VkDescriptorSet> mDescriptorSets; std::vector<VkDescriptorSet> mDescriptorSets;
gl::RangeUI mUsedDescriptorSetRange; gl::RangeUI mUsedDescriptorSetRange;
bool mDirtyTextures;
// We keep a reference to the pipeline and descriptor set layouts. This ensures they don't get // We keep a reference to the pipeline and descriptor set layouts. This ensures they don't get
// deleted while this program is in use. // deleted while this program is in use.
......
...@@ -41,19 +41,8 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -41,19 +41,8 @@ class VertexArrayVk : public VertexArrayImpl
const gl::VertexArray::DirtyAttribBitsArray &attribBits, const gl::VertexArray::DirtyAttribBitsArray &attribBits,
const gl::VertexArray::DirtyBindingBitsArray &bindingBits) override; const gl::VertexArray::DirtyBindingBitsArray &bindingBits) override;
void updateDrawDependencies(vk::CommandGraphResource *drawFramebuffer,
const gl::AttributesMask &activeAttribsMask,
vk::CommandGraphResource *elementArrayBufferOverride,
Serial serial,
bool isDrawElements);
void getPackedInputDescriptions(vk::PipelineDesc *pipelineDesc); void getPackedInputDescriptions(vk::PipelineDesc *pipelineDesc);
// Draw call handling.
gl::Error drawArrays(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer,
bool shouldApplyVertexArray);
gl::Error drawElements(const gl::Context *context, gl::Error drawElements(const gl::Context *context,
const gl::DrawCallParams &drawCallParams, const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer, vk::CommandBuffer *commandBuffer,
...@@ -64,6 +53,46 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -64,6 +53,46 @@ class VertexArrayVk : public VertexArrayImpl
VkBuffer bufferHandle, VkBuffer bufferHandle,
uint32_t offset); uint32_t offset);
angle::Result updateClientAttribs(const gl::Context *context,
const gl::DrawCallParams &drawCallParams);
angle::Result handleLineLoop(ContextVk *contextVk, const gl::DrawCallParams &drawCallParams);
const gl::AttribArray<VkBuffer> &getCurrentArrayBufferHandles() const
{
return mCurrentArrayBufferHandles;
}
const gl::AttribArray<VkDeviceSize> &getCurrentArrayBufferOffsets() const
{
return mCurrentArrayBufferOffsets;
}
const gl::AttribArray<vk::CommandGraphResource *> &getCurrentArrayBufferResources() const
{
return mCurrentArrayBufferResources;
}
VkBuffer getCurrentElementArrayBufferHandle() const { return mCurrentElementArrayBufferHandle; }
VkDeviceSize getCurrentElementArrayBufferOffset() const
{
return mCurrentElementArrayBufferOffset;
}
void updateCurrentElementArrayBufferOffset(const GLvoid *offset)
{
mCurrentElementArrayBufferOffset = reinterpret_cast<VkDeviceSize>(offset);
}
vk::CommandGraphResource *getCurrentElementArrayBufferResource() const
{
return mCurrentElementArrayBufferResource;
}
angle::Result updateIndexTranslation(ContextVk *contextVk,
const gl::DrawCallParams &drawCallParams);
private: private:
// This will update any dirty packed input descriptions, regardless if they're used by the // This will update any dirty packed input descriptions, regardless if they're used by the
// active program. This could lead to slight inefficiencies when the app would repeatedly // active program. This could lead to slight inefficiencies when the app would repeatedly
...@@ -79,9 +108,6 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -79,9 +108,6 @@ class VertexArrayVk : public VertexArrayImpl
const gl::AttributesMask &activeAttribsMask, const gl::AttributesMask &activeAttribsMask,
Serial serial); Serial serial);
void updateElementArrayBufferReadDependency(vk::CommandGraphResource *drawFramebuffer,
Serial serial);
angle::Result streamIndexData(ContextVk *contextVk, angle::Result streamIndexData(ContextVk *contextVk,
GLenum indexType, GLenum indexType,
size_t indexCount, size_t indexCount,
...@@ -93,15 +119,6 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -93,15 +119,6 @@ class VertexArrayVk : public VertexArrayImpl
size_t attribIndex); size_t attribIndex);
void ensureConversionReleased(RendererVk *renderer, size_t attribIndex); void ensureConversionReleased(RendererVk *renderer, size_t attribIndex);
gl::Error onDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer,
bool newCommandBuffer);
gl::Error onIndexedDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer,
bool newCommandBuffer);
angle::Result syncDirtyAttrib(ContextVk *contextVk, angle::Result syncDirtyAttrib(ContextVk *contextVk,
const gl::VertexAttribute &attrib, const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
...@@ -132,15 +149,7 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -132,15 +149,7 @@ class VertexArrayVk : public VertexArrayImpl
Optional<GLint> mLineLoopBufferFirstIndex; Optional<GLint> mLineLoopBufferFirstIndex;
Optional<size_t> mLineLoopBufferLastIndex; Optional<size_t> mLineLoopBufferLastIndex;
bool mDirtyLineLoopTranslation; bool mDirtyLineLoopTranslation;
// Cache variable for determining whether or not to store new dependencies in the node.
bool mVertexBuffersDirty;
bool mIndexBufferDirty;
// The offset we had the last time we bound the index buffer.
uintptr_t mLastIndexBufferOffset;
}; };
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_ #endif // LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_
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