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