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