1 //
2 // Copyright 2002 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 
7 // VertexBuffer.h: Defines the abstract VertexBuffer class and VertexBufferInterface
8 // class with derivations, classes that perform graphics API agnostic vertex buffer operations.
9 
10 #ifndef LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_
11 #define LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_
12 
13 #include "common/PackedEnums.h"
14 #include "common/angleutils.h"
15 #include "libANGLE/Error.h"
16 #include "libANGLE/renderer/Format.h"
17 
18 #include <GLES2/gl2.h>
19 
20 #include <cstddef>
21 #include <cstdint>
22 #include <vector>
23 
24 namespace gl
25 {
26 class Context;
27 struct VertexAttribute;
28 class VertexBinding;
29 struct VertexAttribCurrentValueData;
30 }  // namespace gl
31 
32 namespace rx
33 {
34 class BufferFactoryD3D;
35 
36 // Use a ref-counting scheme with self-deletion on release. We do this so that we can more
37 // easily manage the static buffer cache, without deleting currently bound buffers.
38 class VertexBuffer : angle::NonCopyable
39 {
40   public:
41     VertexBuffer();
42 
43     virtual angle::Result initialize(const gl::Context *context,
44                                      unsigned int size,
45                                      bool dynamicUsage) = 0;
46 
47     // Warning: you should ensure binding really matches attrib.bindingIndex before using this
48     // function.
49     virtual angle::Result storeVertexAttributes(const gl::Context *context,
50                                                 const gl::VertexAttribute &attrib,
51                                                 const gl::VertexBinding &binding,
52                                                 gl::VertexAttribType currentValueType,
53                                                 GLint start,
54                                                 size_t count,
55                                                 GLsizei instances,
56                                                 unsigned int offset,
57                                                 const uint8_t *sourceData) = 0;
58 
59     virtual unsigned int getBufferSize() const                                         = 0;
60     virtual angle::Result setBufferSize(const gl::Context *context, unsigned int size) = 0;
61     virtual angle::Result discard(const gl::Context *context)                          = 0;
62 
63     unsigned int getSerial() const;
64 
65     // This may be overridden (e.g. by VertexBuffer11) if necessary.
hintUnmapResource()66     virtual void hintUnmapResource() {}
67 
68     // Reference counting.
69     void addRef();
70     void release();
71 
72   protected:
73     void updateSerial();
74     virtual ~VertexBuffer();
75 
76   private:
77     unsigned int mSerial;
78     static unsigned int mNextSerial;
79     unsigned int mRefCount;
80 };
81 
82 class VertexBufferInterface : angle::NonCopyable
83 {
84   public:
85     VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic);
86     virtual ~VertexBufferInterface();
87 
88     unsigned int getBufferSize() const;
empty()89     bool empty() const { return getBufferSize() == 0; }
90 
91     unsigned int getSerial() const;
92 
93     VertexBuffer *getVertexBuffer() const;
94 
95   protected:
96     angle::Result discard(const gl::Context *context);
97 
98     angle::Result setBufferSize(const gl::Context *context, unsigned int size);
99 
100     angle::Result getSpaceRequired(const gl::Context *context,
101                                    const gl::VertexAttribute &attrib,
102                                    const gl::VertexBinding &binding,
103                                    size_t count,
104                                    GLsizei instances,
105                                    GLuint baseInstance,
106                                    unsigned int *spaceInBytesOut) const;
107     BufferFactoryD3D *const mFactory;
108     VertexBuffer *mVertexBuffer;
109     bool mDynamic;
110 };
111 
112 class StreamingVertexBufferInterface : public VertexBufferInterface
113 {
114   public:
115     StreamingVertexBufferInterface(BufferFactoryD3D *factory);
116     ~StreamingVertexBufferInterface() override;
117 
118     angle::Result initialize(const gl::Context *context, std::size_t initialSize);
119     void reset();
120 
121     angle::Result storeDynamicAttribute(const gl::Context *context,
122                                         const gl::VertexAttribute &attrib,
123                                         const gl::VertexBinding &binding,
124                                         gl::VertexAttribType currentValueType,
125                                         GLint start,
126                                         size_t count,
127                                         GLsizei instances,
128                                         GLuint baseInstance,
129                                         unsigned int *outStreamOffset,
130                                         const uint8_t *sourceData);
131 
132     angle::Result reserveVertexSpace(const gl::Context *context,
133                                      const gl::VertexAttribute &attribute,
134                                      const gl::VertexBinding &binding,
135                                      size_t count,
136                                      GLsizei instances,
137                                      GLuint baseInstance);
138 
139   private:
140     angle::Result reserveSpace(const gl::Context *context, unsigned int size);
141 
142     unsigned int mWritePosition;
143     unsigned int mReservedSpace;
144 };
145 
146 class StaticVertexBufferInterface : public VertexBufferInterface
147 {
148   public:
149     explicit StaticVertexBufferInterface(BufferFactoryD3D *factory);
150     ~StaticVertexBufferInterface() override;
151 
152     // Warning: you should ensure binding really matches attrib.bindingIndex before using these
153     // functions.
154     angle::Result storeStaticAttribute(const gl::Context *context,
155                                        const gl::VertexAttribute &attrib,
156                                        const gl::VertexBinding &binding,
157                                        GLint start,
158                                        GLsizei count,
159                                        GLsizei instances,
160                                        const uint8_t *sourceData);
161 
162     bool matchesAttribute(const gl::VertexAttribute &attribute,
163                           const gl::VertexBinding &binding) const;
164 
165     void setAttribute(const gl::VertexAttribute &attribute, const gl::VertexBinding &binding);
166 
167   private:
168     class AttributeSignature final : angle::NonCopyable
169     {
170       public:
171         AttributeSignature();
172 
173         bool matchesAttribute(const gl::VertexAttribute &attrib,
174                               const gl::VertexBinding &binding) const;
175 
176         void set(const gl::VertexAttribute &attrib, const gl::VertexBinding &binding);
177 
178       private:
179         angle::FormatID formatID;
180         GLuint stride;
181         size_t offset;
182     };
183 
184     AttributeSignature mSignature;
185 };
186 
187 }  // namespace rx
188 
189 #endif  // LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_
190