xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/VertexArrayVk.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // VertexArrayVk.h:
7 //    Defines the class interface for VertexArrayVk, implementing VertexArrayImpl.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_
11 #define LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_
12 
13 #include "libANGLE/renderer/VertexArrayImpl.h"
14 #include "libANGLE/renderer/vulkan/UtilsVk.h"
15 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
16 #include "libANGLE/renderer/vulkan/vk_helpers.h"
17 
18 namespace rx
19 {
20 enum class BufferBindingDirty
21 {
22     No,
23     Yes,
24 };
25 
26 struct AttributeRange
27 {
28     // Stream vertex attribute start pointer address.
29     uintptr_t startAddr;
30     // Stream vertex attribute end pointer address.
31     uintptr_t endAddr;
32     // Stream vertex attribute first used pointer address.
33     // ie. startAddr + startVertex * stride.
34     uintptr_t copyStartAddr;
AttributeRangeAttributeRange35     AttributeRange() : startAddr(0), endAddr(0), copyStartAddr(0) {}
AttributeRangeAttributeRange36     AttributeRange(uintptr_t start, uintptr_t end, uintptr_t copyStart)
37         : startAddr(start), endAddr(end), copyStartAddr(copyStart)
38     {}
39 };
40 
41 ANGLE_INLINE bool operator<(const AttributeRange &a, const AttributeRange &b)
42 {
43     return a.startAddr == b.startAddr ? a.endAddr < b.endAddr : a.startAddr < b.startAddr;
44 }
45 
46 class VertexArrayVk : public VertexArrayImpl
47 {
48   public:
49     VertexArrayVk(ContextVk *contextVk, const gl::VertexArrayState &state);
50     ~VertexArrayVk() override;
51 
52     void destroy(const gl::Context *context) override;
53 
54     angle::Result syncState(const gl::Context *context,
55                             const gl::VertexArray::DirtyBits &dirtyBits,
56                             gl::VertexArray::DirtyAttribBitsArray *attribBits,
57                             gl::VertexArray::DirtyBindingBitsArray *bindingBits) override;
58 
59     angle::Result updateActiveAttribInfo(ContextVk *contextVk);
60 
61     angle::Result updateDefaultAttrib(ContextVk *contextVk, size_t attribIndex);
62 
63     angle::Result updateStreamedAttribs(const gl::Context *context,
64                                         GLint firstVertex,
65                                         GLsizei vertexOrIndexCount,
66                                         GLsizei instanceCount,
67                                         gl::DrawElementsType indexTypeOrInvalid,
68                                         const void *indices);
69 
70     angle::Result handleLineLoop(ContextVk *contextVk,
71                                  GLint firstVertex,
72                                  GLsizei vertexOrIndexCount,
73                                  gl::DrawElementsType indexTypeOrInvalid,
74                                  const void *indices,
75                                  vk::BufferHelper **indexBufferOut,
76                                  uint32_t *indexCountOut);
77 
78     angle::Result handleLineLoopIndexIndirect(ContextVk *contextVk,
79                                               gl::DrawElementsType glIndexType,
80                                               vk::BufferHelper *srcIndexBuffer,
81                                               vk::BufferHelper *srcIndirectBuffer,
82                                               VkDeviceSize indirectBufferOffset,
83                                               vk::BufferHelper **indexBufferOut,
84                                               vk::BufferHelper **indirectBufferOut);
85 
86     angle::Result handleLineLoopIndirectDraw(const gl::Context *context,
87                                              vk::BufferHelper *indirectBufferVk,
88                                              VkDeviceSize indirectBufferOffset,
89                                              vk::BufferHelper **indexBufferOut,
90                                              vk::BufferHelper **indirectBufferOut);
91 
getCurrentArrayBufferHandles()92     const gl::AttribArray<VkBuffer> &getCurrentArrayBufferHandles() const
93     {
94         return mCurrentArrayBufferHandles;
95     }
96 
getCurrentArrayBufferOffsets()97     const gl::AttribArray<VkDeviceSize> &getCurrentArrayBufferOffsets() const
98     {
99         return mCurrentArrayBufferOffsets;
100     }
101 
getCurrentArrayBufferRelativeOffsets()102     const gl::AttribArray<GLuint> &getCurrentArrayBufferRelativeOffsets() const
103     {
104         return mCurrentArrayBufferRelativeOffsets;
105     }
106 
getCurrentArrayBuffers()107     const gl::AttribArray<vk::BufferHelper *> &getCurrentArrayBuffers() const
108     {
109         return mCurrentArrayBuffers;
110     }
111 
getCurrentArrayBufferFormats()112     const gl::AttribArray<angle::FormatID> &getCurrentArrayBufferFormats() const
113     {
114         return mCurrentArrayBufferFormats;
115     }
116 
getCurrentArrayBufferStrides()117     const gl::AttribArray<GLuint> &getCurrentArrayBufferStrides() const
118     {
119         return mCurrentArrayBufferStrides;
120     }
121 
getCurrentArrayBufferDivisors()122     const gl::AttribArray<GLuint> &getCurrentArrayBufferDivisors() const
123     {
124         return mCurrentArrayBufferDivisors;
125     }
126 
getCurrentArrayBufferCompressed()127     const gl::AttributesMask &getCurrentArrayBufferCompressed() const
128     {
129         return mCurrentArrayBufferCompressed;
130     }
131 
132     // Update mCurrentElementArrayBuffer based on the vertex array state
133     void updateCurrentElementArrayBuffer();
134 
getCurrentElementArrayBuffer()135     vk::BufferHelper *getCurrentElementArrayBuffer() const { return mCurrentElementArrayBuffer; }
136 
137     angle::Result convertIndexBufferGPU(ContextVk *contextVk,
138                                         BufferVk *bufferVk,
139                                         const void *indices);
140 
141     angle::Result convertIndexBufferIndirectGPU(ContextVk *contextVk,
142                                                 vk::BufferHelper *srcIndirectBuf,
143                                                 VkDeviceSize srcIndirectBufOffset,
144                                                 vk::BufferHelper **indirectBufferVkOut);
145 
146     angle::Result convertIndexBufferCPU(ContextVk *contextVk,
147                                         gl::DrawElementsType indexType,
148                                         size_t indexCount,
149                                         const void *sourcePointer,
150                                         BufferBindingDirty *bufferBindingDirty);
151 
getStreamingVertexAttribsMask()152     const gl::AttributesMask &getStreamingVertexAttribsMask() const
153     {
154         return mStreamingVertexAttribsMask;
155     }
156 
157   private:
158     gl::AttributesMask mergeClientAttribsRange(
159         vk::Renderer *renderer,
160         const gl::AttributesMask activeStreamedAttribs,
161         size_t startVertex,
162         size_t endVertex,
163         std::array<AttributeRange, gl::MAX_VERTEX_ATTRIBS> &mergeRangesOut,
164         std::array<size_t, gl::MAX_VERTEX_ATTRIBS> &mergedIndexesOut) const;
165 
166     angle::Result setDefaultPackedInput(ContextVk *contextVk,
167                                         size_t attribIndex,
168                                         angle::FormatID *formatOut);
169 
170     angle::Result convertVertexBufferGPU(ContextVk *contextVk,
171                                          BufferVk *srcBuffer,
172                                          VertexConversionBuffer *conversion,
173                                          const angle::Format &srcFormat,
174                                          const angle::Format &dstFormat);
175     angle::Result convertVertexBufferCPU(ContextVk *contextVk,
176                                          BufferVk *srcBuffer,
177                                          VertexConversionBuffer *conversion,
178                                          const angle::Format &srcFormat,
179                                          const angle::Format &dstFormat,
180                                          const VertexCopyFunction vertexLoadFunction);
181 
182     angle::Result syncDirtyAttrib(ContextVk *contextVk,
183                                   const gl::VertexAttribute &attrib,
184                                   const gl::VertexBinding &binding,
185                                   size_t attribIndex,
186                                   bool bufferOnly);
187 
188     gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles;
189     gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets;
190     // The offset into the buffer to the first attrib
191     gl::AttribArray<GLuint> mCurrentArrayBufferRelativeOffsets;
192     gl::AttribArray<vk::BufferHelper *> mCurrentArrayBuffers;
193     // Tracks BufferSerial of mCurrentArrayBuffers since they are always valid to access.
194     gl::AttribArray<vk::BufferSerial> mCurrentArrayBufferSerial;
195     // Cache strides of attributes for a fast pipeline cache update when VAOs are changed
196     gl::AttribArray<angle::FormatID> mCurrentArrayBufferFormats;
197     gl::AttribArray<GLuint> mCurrentArrayBufferStrides;
198     gl::AttribArray<GLuint> mCurrentArrayBufferDivisors;
199     gl::AttributesMask mCurrentArrayBufferCompressed;
200     vk::BufferHelper *mCurrentElementArrayBuffer;
201 
202     // Cached element array buffers for improving performance.
203     vk::BufferHelperQueue mCachedStreamIndexBuffers;
204 
205     ConversionBuffer mStreamedIndexData;
206     ConversionBuffer mTranslatedByteIndexData;
207     ConversionBuffer mTranslatedByteIndirectData;
208 
209     LineLoopHelper mLineLoopHelper;
210     Optional<GLint> mLineLoopBufferFirstIndex;
211     Optional<size_t> mLineLoopBufferLastIndex;
212     bool mDirtyLineLoopTranslation;
213 
214     // Track client and/or emulated attribs that we have to stream their buffer contents
215     gl::AttributesMask mStreamingVertexAttribsMask;
216 
217     // The attrib/binding dirty bits that requires graphics pipeline update
218     gl::VertexArray::DirtyBindingBits mBindingDirtyBitsRequiresPipelineUpdate;
219     gl::VertexArray::DirtyAttribBits mAttribDirtyBitsRequiresPipelineUpdate;
220 };
221 }  // namespace rx
222 
223 #endif  // LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_
224