Hash :
297687c6
Author :
Date :
2023-05-18T17:27:54
Vulkan: Reduce CPU overhead for uniform buffer change One of the common usage pattern is change uniform buffers and draw. Right now every uniform buffer change goes into ShaderResource dirty code path that rebuilds entire ShaderResource cache key and descriptor set etc. This CL keeps SHaderResource dirty code path, and will be used when program changes or framebuffer changes. But uniform buffer change will go down its own code path that only update uniform buffer related state. This CL along with prior two CLs reduced asphalt_9 average frame time (with multi context hacked away) from 5.375 ms to 5.2594 ms (reduced 2.15%). Bug: b/282194402 Change-Id: Ibae2895663918ddc10bf13bc559f1483f94d2e11 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4528314 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Roman Lavrov <romanl@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// TransformFeedbackVk.h:
// Defines the class interface for TransformFeedbackVk, implementing TransformFeedbackImpl.
//
#ifndef LIBANGLE_RENDERER_VULKAN_TRANSFORMFEEDBACKVK_H_
#define LIBANGLE_RENDERER_VULKAN_TRANSFORMFEEDBACKVK_H_
#include "libANGLE/renderer/TransformFeedbackImpl.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace gl
{
class ProgramState;
} // namespace gl
namespace rx
{
class UpdateDescriptorSetsBuilder;
class ShaderInterfaceVariableInfoMap;
namespace vk
{
class DescriptorSetLayoutDesc;
} // namespace vk
class TransformFeedbackVk : public TransformFeedbackImpl, public angle::ObserverInterface
{
public:
TransformFeedbackVk(const gl::TransformFeedbackState &state);
~TransformFeedbackVk() override;
void onDestroy(const gl::Context *context) override;
angle::Result begin(const gl::Context *context, gl::PrimitiveMode primitiveMode) override;
angle::Result end(const gl::Context *context) override;
angle::Result pause(const gl::Context *context) override;
angle::Result resume(const gl::Context *context) override;
angle::Result bindIndexedBuffer(const gl::Context *context,
size_t index,
const gl::OffsetBindingPointer<gl::Buffer> &binding) override;
void updateDescriptorSetLayout(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount,
vk::DescriptorSetLayoutDesc *descSetLayoutOut) const;
void getBufferOffsets(ContextVk *contextVk,
GLint drawCallFirstVertex,
int32_t *offsetsOut,
size_t offsetsSize) const;
bool getAndResetBufferRebindState()
{
bool retVal = mRebindTransformFeedbackBuffer;
mRebindTransformFeedbackBuffer = false;
return retVal;
}
const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &getBufferHelpers() const
{
return mBufferHelpers;
}
const gl::TransformFeedbackBuffersArray<VkBuffer> &getBufferHandles() const
{
return mBufferHandles;
}
const gl::TransformFeedbackBuffersArray<VkDeviceSize> &getBufferOffsets() const
{
return mBufferOffsets;
}
const gl::TransformFeedbackBuffersArray<VkDeviceSize> &getBufferSizes() const
{
return mBufferSizes;
}
gl::TransformFeedbackBuffersArray<vk::BufferHelper> &getCounterBufferHelpers()
{
return mCounterBufferHelpers;
}
const gl::TransformFeedbackBuffersArray<VkBuffer> &getCounterBufferHandles() const
{
return mCounterBufferHandles;
}
void updateTransformFeedbackDescriptorDesc(
const vk::Context *context,
const gl::ProgramExecutable &executable,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
const vk::WriteDescriptorDescs &writeDescriptorDescs,
const vk::BufferHelper &emptyBuffer,
bool activeUnpaused,
vk::DescriptorSetDescBuilder *builder) const;
const gl::TransformFeedbackBuffersArray<VkDeviceSize> &getCounterBufferOffsets() const
{
return mCounterBufferOffsets;
}
void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
void onNewDescriptorSet(const gl::ProgramExecutable &executable,
const vk::SharedDescriptorSetCacheKey &sharedCacheKey);
private:
void initializeXFBVariables(ContextVk *contextVk, uint32_t xfbBufferCount);
void releaseCounterBuffers(RendererVk *renderer);
// This member variable is set when glBindTransformFeedbackBuffers/glBeginTransformFeedback
// is called and unset in dirty bit handler for transform feedback state change. If this
// value is true, vertex shader will record transform feedback varyings from the beginning
// of the buffer.
bool mRebindTransformFeedbackBuffer;
gl::TransformFeedbackBuffersArray<vk::BufferHelper *> mBufferHelpers;
gl::TransformFeedbackBuffersArray<VkBuffer> mBufferHandles;
gl::TransformFeedbackBuffersArray<VkDeviceSize> mBufferOffsets;
gl::TransformFeedbackBuffersArray<VkDeviceSize> mBufferSizes;
// Counter buffer used for pause and resume.
gl::TransformFeedbackBuffersArray<vk::BufferHelper> mCounterBufferHelpers;
gl::TransformFeedbackBuffersArray<VkBuffer> mCounterBufferHandles;
gl::TransformFeedbackBuffersArray<VkDeviceSize> mCounterBufferOffsets;
// Buffer binding points
std::vector<angle::ObserverBinding> mBufferObserverBindings;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_TRANSFORMFEEDBACKVK_H_