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 // BufferVk.h: 7 // Defines the class interface for BufferVk, implementing BufferImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_VULKAN_BUFFERVK_H_ 11 #define LIBANGLE_RENDERER_VULKAN_BUFFERVK_H_ 12 13 #include "libANGLE/Buffer.h" 14 #include "libANGLE/Observer.h" 15 #include "libANGLE/renderer/BufferImpl.h" 16 #include "libANGLE/renderer/vulkan/vk_helpers.h" 17 18 namespace rx 19 { 20 // Conversion buffers hold translated index and vertex data. 21 struct ConversionBuffer 22 { 23 ConversionBuffer(vk::Renderer *renderer, 24 VkBufferUsageFlags usageFlags, 25 size_t initialSize, 26 size_t alignment, 27 bool hostVisible); 28 ~ConversionBuffer(); 29 30 ConversionBuffer(ConversionBuffer &&other); 31 32 // One state value determines if we need to re-stream vertex data. 33 bool dirty; 34 35 // Where the conversion data is stored. 36 std::unique_ptr<vk::BufferHelper> data; 37 }; 38 39 enum class BufferUpdateType 40 { 41 StorageRedefined, 42 ContentsUpdate, 43 }; 44 45 struct BufferDataSource 46 { 47 // Buffer data can come from two sources: 48 // glBufferData and glBufferSubData upload through a CPU pointer 49 const void *data = nullptr; 50 // glCopyBufferSubData copies data from another buffer 51 vk::BufferHelper *buffer = nullptr; 52 VkDeviceSize bufferOffset = 0; 53 }; 54 55 VkBufferUsageFlags GetDefaultBufferUsageFlags(vk::Renderer *renderer); 56 57 class BufferVk : public BufferImpl 58 { 59 public: 60 BufferVk(const gl::BufferState &state); 61 ~BufferVk() override; 62 void destroy(const gl::Context *context) override; 63 64 angle::Result setExternalBufferData(const gl::Context *context, 65 gl::BufferBinding target, 66 GLeglClientBufferEXT clientBuffer, 67 size_t size, 68 VkMemoryPropertyFlags memoryPropertyFlags); 69 angle::Result setDataWithUsageFlags(const gl::Context *context, 70 gl::BufferBinding target, 71 GLeglClientBufferEXT clientBuffer, 72 const void *data, 73 size_t size, 74 gl::BufferUsage usage, 75 GLbitfield flags) override; 76 angle::Result setData(const gl::Context *context, 77 gl::BufferBinding target, 78 const void *data, 79 size_t size, 80 gl::BufferUsage usage) override; 81 angle::Result setSubData(const gl::Context *context, 82 gl::BufferBinding target, 83 const void *data, 84 size_t size, 85 size_t offset) override; 86 angle::Result copySubData(const gl::Context *context, 87 BufferImpl *source, 88 GLintptr sourceOffset, 89 GLintptr destOffset, 90 GLsizeiptr size) override; 91 angle::Result map(const gl::Context *context, GLenum access, void **mapPtr) override; 92 angle::Result mapRange(const gl::Context *context, 93 size_t offset, 94 size_t length, 95 GLbitfield access, 96 void **mapPtr) override; 97 angle::Result unmap(const gl::Context *context, GLboolean *result) override; 98 angle::Result getSubData(const gl::Context *context, 99 GLintptr offset, 100 GLsizeiptr size, 101 void *outData) override; 102 103 angle::Result getIndexRange(const gl::Context *context, 104 gl::DrawElementsType type, 105 size_t offset, 106 size_t count, 107 bool primitiveRestartEnabled, 108 gl::IndexRange *outRange) override; 109 getSize()110 GLint64 getSize() const { return mState.getSize(); } 111 112 void onDataChanged() override; 113 getBuffer()114 vk::BufferHelper &getBuffer() 115 { 116 ASSERT(isBufferValid()); 117 return mBuffer; 118 } 119 getBufferSerial()120 vk::BufferSerial getBufferSerial() { return mBuffer.getBufferSerial(); } 121 isBufferValid()122 bool isBufferValid() const { return mBuffer.valid(); } 123 bool isCurrentlyInUse(vk::Renderer *renderer) const; 124 125 angle::Result mapImpl(ContextVk *contextVk, GLbitfield access, void **mapPtr); 126 angle::Result mapRangeImpl(ContextVk *contextVk, 127 VkDeviceSize offset, 128 VkDeviceSize length, 129 GLbitfield access, 130 void **mapPtr); 131 angle::Result unmapImpl(ContextVk *contextVk); 132 angle::Result ghostMappedBuffer(ContextVk *contextVk, 133 VkDeviceSize offset, 134 VkDeviceSize length, 135 GLbitfield access, 136 void **mapPtr); 137 138 ConversionBuffer *getVertexConversionBuffer(vk::Renderer *renderer, 139 angle::FormatID formatID, 140 GLuint stride, 141 size_t offset, 142 bool hostVisible); 143 144 private: 145 angle::Result updateBuffer(ContextVk *contextVk, 146 size_t bufferSize, 147 const BufferDataSource &dataSource, 148 size_t size, 149 size_t offset); 150 angle::Result directUpdate(ContextVk *contextVk, 151 const BufferDataSource &dataSource, 152 size_t size, 153 size_t offset); 154 angle::Result stagedUpdate(ContextVk *contextVk, 155 const BufferDataSource &dataSource, 156 size_t size, 157 size_t offset); 158 angle::Result allocStagingBuffer(ContextVk *contextVk, 159 vk::MemoryCoherency coherency, 160 VkDeviceSize size, 161 uint8_t **mapPtr); 162 angle::Result flushStagingBuffer(ContextVk *contextVk, VkDeviceSize offset, VkDeviceSize size); 163 angle::Result acquireAndUpdate(ContextVk *contextVk, 164 size_t bufferSize, 165 const BufferDataSource &dataSource, 166 size_t updateSize, 167 size_t updateOffset, 168 BufferUpdateType updateType); 169 angle::Result setDataWithMemoryType(const gl::Context *context, 170 gl::BufferBinding target, 171 const void *data, 172 size_t size, 173 VkMemoryPropertyFlags memoryPropertyFlags, 174 gl::BufferUsage usage); 175 angle::Result handleDeviceLocalBufferMap(ContextVk *contextVk, 176 VkDeviceSize offset, 177 VkDeviceSize size, 178 uint8_t **mapPtr); 179 angle::Result setDataImpl(ContextVk *contextVk, 180 size_t bufferSize, 181 const BufferDataSource &dataSource, 182 size_t updateSize, 183 size_t updateOffset, 184 BufferUpdateType updateType); 185 angle::Result release(ContextVk *context); 186 void dataUpdated(); 187 188 angle::Result acquireBufferHelper(ContextVk *contextVk, 189 size_t sizeInBytes, 190 BufferUsageType usageType); 191 isExternalBuffer()192 bool isExternalBuffer() const { return mClientBuffer != nullptr; } 193 BufferUpdateType calculateBufferUpdateTypeOnFullUpdate( 194 vk::Renderer *renderer, 195 size_t size, 196 VkMemoryPropertyFlags memoryPropertyFlags, 197 BufferUsageType usageType, 198 const void *data) const; 199 bool shouldRedefineStorage(vk::Renderer *renderer, 200 BufferUsageType usageType, 201 VkMemoryPropertyFlags memoryPropertyFlags, 202 size_t size) const; 203 204 struct VertexConversionBuffer : public ConversionBuffer 205 { 206 VertexConversionBuffer(vk::Renderer *renderer, 207 angle::FormatID formatIDIn, 208 GLuint strideIn, 209 size_t offsetIn, 210 bool hostVisible); 211 ~VertexConversionBuffer(); 212 213 VertexConversionBuffer(VertexConversionBuffer &&other); 214 215 // The conversion is identified by the triple of {format, stride, offset}. 216 angle::FormatID formatID; 217 GLuint stride; 218 size_t offset; 219 }; 220 221 vk::BufferHelper mBuffer; 222 223 // If not null, this is the external memory pointer passed from client API. 224 void *mClientBuffer; 225 226 uint32_t mMemoryTypeIndex; 227 // Memory/Usage property that will be used for memory allocation. 228 VkMemoryPropertyFlags mMemoryPropertyFlags; 229 230 // The staging buffer to aid map operations. This is used when buffers are not host visible or 231 // for performance optimization when only a smaller range of buffer is mapped. 232 vk::BufferHelper mStagingBuffer; 233 234 // A cache of converted vertex data. 235 std::vector<VertexConversionBuffer> mVertexConversionBuffers; 236 237 // Tracks whether mStagingBuffer has been mapped to user or not 238 bool mIsStagingBufferMapped; 239 240 // Tracks if BufferVk object has valid data or not. 241 bool mHasValidData; 242 243 // True if the buffer is currently mapped for CPU write access. If the map call is originated 244 // from OpenGLES API call, then this should be consistent with mState.getAccessFlags() bits. 245 // Otherwise it is mapped from ANGLE internal and will not be consistent with mState access 246 // bits, so we have to keep record of it. 247 bool mIsMappedForWrite; 248 // True if usage is dynamic. May affect how we allocate memory. 249 BufferUsageType mUsageType; 250 // Similar as mIsMappedForWrite, this maybe different from mState's getMapOffset/getMapLength if 251 // mapped from angle internal. 252 VkDeviceSize mMappedOffset; 253 VkDeviceSize mMappedLength; 254 }; 255 256 } // namespace rx 257 258 #endif // LIBANGLE_RENDERER_VULKAN_BUFFERVK_H_ 259