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