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