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
AttributesMask getActiveClientAttribsMask() const { return mCachedActiveClientAttribsMask; }
AttributesMask getActiveDefaultAttribsMask() const { return mCachedActiveDefaultAttribsMask; }
bool hasAnyEnabledClientAttrib() const { return mCachedHasAnyEnabledClientAttrib; }
bool hasAnyActiveClientAttrib() const { return mCachedActiveClientAttribsMask.any(); }
// Places that can trigger updateVertexElementLimits:
// 1. onVertexArrayBindingChange.
......
......@@ -158,6 +158,7 @@ class ContextVk : public ContextImpl, public vk::Context
void invalidateCurrentPipeline();
void invalidateDefaultAttribute(size_t attribIndex);
void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
vk::DynamicDescriptorPool *getDynamicDescriptorPool(uint32_t descriptorSetIndex);
......@@ -173,19 +174,27 @@ class ContextVk : public ContextImpl, public vk::Context
void handleError(VkResult errorCode, const char *file, unsigned int line) override;
const gl::ActiveTextureArray<TextureVk *> &getActiveTextures() const;
void setIndexBufferDirty() { mIndexBufferDirty = true; }
private:
gl::Error initPipeline(const gl::DrawCallParams &drawCallParams);
gl::Error setupDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer **commandBufferOut,
bool *shouldApplyVertexArrayOut);
angle::Result initPipeline(const gl::DrawCallParams &drawCallParams);
angle::Result setupDraw(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
bool useIndexBuffer,
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 updateFlipViewportDrawFramebuffer(const gl::State &glState);
void updateFlipViewportReadFramebuffer(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 updateDefaultAttribute(size_t attribIndex);
......@@ -200,9 +209,18 @@ class ContextVk : public ContextImpl, public vk::Context
// threads simultaneously. Hence, we keep them in the ContextVk instead of the RendererVk.
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 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.
VkClearValue mClearColorValue;
......@@ -235,7 +253,7 @@ class ContextVk : public ContextImpl, public vk::Context
gl::ActiveTextureArray<TextureVk *> mActiveTextures;
// "Current Value" aka default vertex attribute state.
gl::AttributesMask mDirtyDefaultAttribs;
gl::AttributesMask mDirtyDefaultAttribsMask;
gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers;
};
} // namespace rx
......
......@@ -183,8 +183,7 @@ ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
ProgramVk::DefaultUniformBlock::~DefaultUniformBlock() = default;
ProgramVk::ProgramVk(const gl::ProgramState &state)
: ProgramImpl(state), mUniformBlocksOffsets{}, mDirtyTextures(false)
ProgramVk::ProgramVk(const gl::ProgramState &state) : ProgramImpl(state), mUniformBlocksOffsets{}
{
mUsedDescriptorSetRange.invalidate();
}
......@@ -222,7 +221,6 @@ angle::Result ProgramVk::reset(ContextVk *contextVk)
mDescriptorSets.clear();
mUsedDescriptorSetRange.invalidate();
mDirtyTextures = false;
return angle::Result::Continue();
}
......@@ -276,7 +274,6 @@ gl::LinkResult ProgramVk::linkImpl(const gl::Context *glContext,
{
// Ensure the descriptor set range includes the textures at position 1.
mUsedDescriptorSetRange.extend(kTextureDescriptorSetIndex);
mDirtyTextures = true;
}
// 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,
{
// Ensure the descriptor set range includes the textures at position 1.
mUsedDescriptorSetRange.extend(kTextureDescriptorSetIndex);
mDirtyTextures = true;
}
}
......@@ -783,11 +779,7 @@ void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint
angle::Result ProgramVk::updateUniforms(ContextVk *contextVk)
{
if (!mDefaultUniformBlocks[vk::ShaderType::VertexShader].uniformsDirty &&
!mDefaultUniformBlocks[vk::ShaderType::FragmentShader].uniformsDirty)
{
return angle::Result::Continue();
}
ASSERT(dirtyUniforms());
// Update buffer memory by immediate mapping. This immediate update only works once.
bool anyNewBufferAllocated = false;
......@@ -865,11 +857,7 @@ angle::Result ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk
angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
{
if (mState.getSamplerBindings().empty() || !mDirtyTextures)
{
return angle::Result::Continue();
}
ASSERT(hasTextures());
ANGLE_TRY(allocateDescriptorSet(contextVk, kTextureDescriptorSetIndex));
ASSERT(mUsedDescriptorSetRange.contains(1));
......@@ -923,15 +911,9 @@ angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
ASSERT(writeCount > 0);
vkUpdateDescriptorSets(device, writeCount, writeDescriptorInfo.data(), 0, nullptr);
mDirtyTextures = false;
return angle::Result::Continue();
}
void ProgramVk::invalidateTextures()
{
mDirtyTextures = true;
}
void ProgramVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize)
{
for (DefaultUniformBlock &block : mDefaultUniformBlocks)
......@@ -942,17 +924,10 @@ void ProgramVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize)
angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk,
const gl::DrawCallParams &drawCallParams,
VkDescriptorSet driverUniformsDescriptorSet,
vk::CommandBuffer *commandBuffer)
{
// TODO(jmadill): Line rasterization emulation shaders. http://anglebug.com/2598
// 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())
return angle::Result::Continue();
......
......@@ -103,17 +103,25 @@ class ProgramVk : public ProgramImpl
const vk::PipelineLayout **pipelineLayoutOut);
angle::Result updateUniforms(ContextVk *contextVk);
void invalidateTextures();
angle::Result updateTexturesDescriptorSet(ContextVk *contextVk);
angle::Result updateDescriptorSets(ContextVk *contextVk,
const gl::DrawCallParams &drawCallParams,
VkDescriptorSet driverUniformsDescriptorSet,
vk::CommandBuffer *commandBuffer);
// For testing only.
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:
template <int cols, int rows>
void setUniformMatrixfv(GLint location,
......@@ -126,7 +134,6 @@ class ProgramVk : public ProgramImpl
angle::Result initDefaultUniformBlocks(const gl::Context *glContext);
angle::Result updateDefaultUniformsDescriptorSet(ContextVk *contextVk);
angle::Result updateTexturesDescriptorSet(ContextVk *contextVk);
template <class T>
void getUniformImpl(GLint location, T *v, GLenum entryPointType) const;
......@@ -165,7 +172,6 @@ class ProgramVk : public ProgramImpl
// Descriptor sets for uniform blocks and textures for this program.
std::vector<VkDescriptorSet> mDescriptorSets;
gl::RangeUI mUsedDescriptorSetRange;
bool mDirtyTextures;
// We keep a reference to the pipeline and descriptor set layouts. This ensures they don't get
// deleted while this program is in use.
......
......@@ -41,19 +41,8 @@ class VertexArrayVk : public VertexArrayImpl
const gl::VertexArray::DirtyAttribBitsArray &attribBits,
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);
// 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,
const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer,
......@@ -64,6 +53,46 @@ class VertexArrayVk : public VertexArrayImpl
VkBuffer bufferHandle,
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:
// 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
......@@ -79,9 +108,6 @@ class VertexArrayVk : public VertexArrayImpl
const gl::AttributesMask &activeAttribsMask,
Serial serial);
void updateElementArrayBufferReadDependency(vk::CommandGraphResource *drawFramebuffer,
Serial serial);
angle::Result streamIndexData(ContextVk *contextVk,
GLenum indexType,
size_t indexCount,
......@@ -93,15 +119,6 @@ class VertexArrayVk : public VertexArrayImpl
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,
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
......@@ -132,15 +149,7 @@ class VertexArrayVk : public VertexArrayImpl
Optional<GLint> mLineLoopBufferFirstIndex;
Optional<size_t> mLineLoopBufferLastIndex;
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
#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