• 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 // 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 class RendererVk;
21 
22 // Conversion buffers hold translated index and vertex data.
23 struct ConversionBuffer
24 {
25     ConversionBuffer(RendererVk *renderer,
26                      VkBufferUsageFlags usageFlags,
27                      size_t initialSize,
28                      size_t alignment,
29                      bool hostVisible);
30     ~ConversionBuffer();
31 
32     ConversionBuffer(ConversionBuffer &&other);
33 
34     // One state value determines if we need to re-stream vertex data.
35     bool dirty;
36 
37     // One additional state value keeps the last allocation offset.
38     VkDeviceSize lastAllocationOffset;
39 
40     // The conversion is stored in a dynamic buffer.
41     vk::DynamicBuffer data;
42 };
43 
44 class BufferVk : public BufferImpl
45 {
46   public:
47     BufferVk(const gl::BufferState &state);
48     ~BufferVk() override;
49     void destroy(const gl::Context *context) override;
50 
51     angle::Result setData(const gl::Context *context,
52                           gl::BufferBinding target,
53                           const void *data,
54                           size_t size,
55                           gl::BufferUsage usage) override;
56     angle::Result setSubData(const gl::Context *context,
57                              gl::BufferBinding target,
58                              const void *data,
59                              size_t size,
60                              size_t offset) override;
61     angle::Result copySubData(const gl::Context *context,
62                               BufferImpl *source,
63                               GLintptr sourceOffset,
64                               GLintptr destOffset,
65                               GLsizeiptr size) override;
66     angle::Result map(const gl::Context *context, GLenum access, void **mapPtr) override;
67     angle::Result mapRange(const gl::Context *context,
68                            size_t offset,
69                            size_t length,
70                            GLbitfield access,
71                            void **mapPtr) override;
72     angle::Result unmap(const gl::Context *context, GLboolean *result) override;
73 
74     angle::Result getIndexRange(const gl::Context *context,
75                                 gl::DrawElementsType type,
76                                 size_t offset,
77                                 size_t count,
78                                 bool primitiveRestartEnabled,
79                                 gl::IndexRange *outRange) override;
80 
getSize()81     GLint64 getSize() const { return mState.getSize(); }
82 
83     void onDataChanged() override;
84 
getBuffer()85     const vk::BufferHelper &getBuffer() const
86     {
87         ASSERT(isBufferValid());
88         return *mBuffer;
89     }
90 
getBuffer()91     vk::BufferHelper &getBuffer()
92     {
93         ASSERT(isBufferValid());
94         return *mBuffer;
95     }
96 
isBufferValid()97     bool isBufferValid() const { return mBuffer && mBuffer->valid(); }
98 
99     angle::Result mapImpl(ContextVk *contextVk, void **mapPtr);
100     angle::Result mapRangeImpl(ContextVk *contextVk,
101                                VkDeviceSize offset,
102                                VkDeviceSize length,
103                                GLbitfield access,
104                                void **mapPtr);
105     angle::Result unmapImpl(ContextVk *contextVk);
106 
107     // Calls copyBuffer internally.
108     angle::Result copyToBufferImpl(ContextVk *contextVk,
109                                    vk::BufferHelper *destBuffer,
110                                    uint32_t copyCount,
111                                    const VkBufferCopy *copies);
112 
113     ConversionBuffer *getVertexConversionBuffer(RendererVk *renderer,
114                                                 angle::FormatID formatID,
115                                                 GLuint stride,
116                                                 size_t offset,
117                                                 bool hostVisible);
118 
119   private:
120     void initializeStagingBuffer(ContextVk *contextVk, gl::BufferBinding target, size_t size);
121     angle::Result initializeShadowBuffer(ContextVk *contextVk,
122                                          gl::BufferBinding target,
123                                          size_t size);
124 
getShadowBuffer(size_t offset)125     ANGLE_INLINE uint8_t *getShadowBuffer(size_t offset)
126     {
127         return (mShadowBuffer.getCurrentBuffer() + offset);
128     }
129 
getShadowBuffer(size_t offset)130     ANGLE_INLINE const uint8_t *getShadowBuffer(size_t offset) const
131     {
132         return (mShadowBuffer.getCurrentBuffer() + offset);
133     }
134 
135     void updateShadowBuffer(const uint8_t *data, size_t size, size_t offset);
136     angle::Result directUpdate(ContextVk *contextVk,
137                                const uint8_t *data,
138                                size_t size,
139                                size_t offset);
140     angle::Result stagedUpdate(ContextVk *contextVk,
141                                const uint8_t *data,
142                                size_t size,
143                                size_t offset);
144     angle::Result acquireAndUpdate(ContextVk *contextVk,
145                                    const uint8_t *data,
146                                    size_t size,
147                                    size_t offset);
148     angle::Result setDataImpl(ContextVk *contextVk,
149                               const uint8_t *data,
150                               size_t size,
151                               size_t offset);
152     void release(ContextVk *context);
153     void markConversionBuffersDirty();
154 
155     angle::Result acquireBufferHelper(ContextVk *contextVk,
156                                       size_t sizeInBytes,
157                                       vk::BufferHelper **bufferHelperOut);
158 
159     struct VertexConversionBuffer : public ConversionBuffer
160     {
161         VertexConversionBuffer(RendererVk *renderer,
162                                angle::FormatID formatIDIn,
163                                GLuint strideIn,
164                                size_t offsetIn,
165                                bool hostVisible);
166         ~VertexConversionBuffer();
167 
168         VertexConversionBuffer(VertexConversionBuffer &&other);
169 
170         // The conversion is identified by the triple of {format, stride, offset}.
171         angle::FormatID formatID;
172         GLuint stride;
173         size_t offset;
174     };
175 
176     vk::BufferHelper *mBuffer;
177 
178     // Pool of BufferHelpers for mBuffer to acquire from
179     vk::DynamicBuffer mBufferPool;
180 
181     // All staging buffer support is provided by a DynamicBuffer.
182     vk::DynamicBuffer mStagingBuffer;
183 
184     // For GPU-read only buffers glMap* latency is reduced by maintaining a copy
185     // of the buffer which is writeable only by the CPU. The contents are updated on all
186     // glData/glSubData/glCopy calls. With this, a glMap* call becomes a non-blocking
187     // operation by elimnating the need to wait on any recorded or in-flight GPU commands.
188     // We use DynamicShadowBuffer class to encapsulate all the bookeeping logic.
189     vk::DynamicShadowBuffer mShadowBuffer;
190 
191     // A cache of converted vertex data.
192     std::vector<VertexConversionBuffer> mVertexConversionBuffers;
193 };
194 
195 }  // namespace rx
196 
197 #endif  // LIBANGLE_RENDERER_VULKAN_BUFFERVK_H_
198