Hash :
e8c0aa81
Author :
Date :
2021-01-26T23:40:36
Vulkan: Clean up transform feedback extension pause/resume 1. The xfb counter buffer barrier issued was wrong, following a typo in the spec. This barrier is now correctly issued using the usual barrier APIs. 2. A mechanism was added to automatically pause/resume transform feedback when a program pipeline needs to be rebound. This is incorrect as it misses the xfb counter buffer barrier. The render pass is broken instead if transform feedback is active/unpaused and the program pipeline is changed. 3. The transform feedback counter buffers are now disposed of when transform feedback is ended. This avoids an unnecessary barrier that this change would have otherwise incurred (and hence render pass break) in Manhattan which repurposes the same transform feedback object. Bug: angleproject:5528 Change-Id: I1ffe8b4b8975645ba43afd70e9cdbb0765529da5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2651647 Reviewed-by: Tim Van Patten <timvp@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
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
//
// 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/glslang_wrapper_utils.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace gl
{
class ProgramState;
} // namespace gl
namespace rx
{
namespace vk
{
class DescriptorSetLayoutDesc;
}
class TransformFeedbackVk : public TransformFeedbackImpl
{
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 initDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount,
VkDescriptorSet descSet) const;
void updateDescriptorSet(ContextVk *contextVk,
const gl::ProgramState &programState,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
VkDescriptorSet descSet) 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;
}
vk::UniformsAndXfbDesc &getTransformFeedbackDesc() { return mXFBBuffersDesc; }
private:
void writeDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount,
VkDescriptorBufferInfo *bufferInfo,
VkDescriptorSet descSet) const;
void initializeXFBBuffersDesc(ContextVk *contextVk, size_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;
// Aligned offset for emulation. Could be smaller than offset.
gl::TransformFeedbackBuffersArray<VkDeviceSize> mAlignedBufferOffsets;
// Counter buffer used for pause and resume.
gl::TransformFeedbackBuffersArray<vk::BufferHelper> mCounterBufferHelpers;
gl::TransformFeedbackBuffersArray<VkBuffer> mCounterBufferHandles;
// Keys to look up in the descriptor set cache
vk::UniformsAndXfbDesc mXFBBuffersDesc;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_TRANSFORMFEEDBACKVK_H_