@@ -36,7 +36,252 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3636#ifndef GLMEMORY_H
3737#define GLMEMORY_H
3838
39- #include " gl_shader.h"
39+ #include " common/Common.h"
40+ #include " GL/glew.h"
41+ #include " tr_local.h"
42+ #include " BufferBind.h"
43+
44+ class GLBuffer {
45+ public:
46+ friend class GLVAO ;
47+
48+ std::string name;
49+ const GLuint64 SYNC_TIMEOUT = 10000000000 ; // 10 seconds
50+
51+ GLuint id;
52+
53+ GLBuffer ( const char * newName, const GLuint newBindingPoint, const GLbitfield newFlags, const GLbitfield newMapFlags ) :
54+ name ( newName ),
55+ internalTarget ( 0 ),
56+ internalBindingPoint ( newBindingPoint ),
57+ flags ( newFlags ),
58+ mapFlags ( newMapFlags ) {
59+ }
60+
61+ GLBuffer ( const char * newName, const GLenum newTarget, const GLuint newBindingPoint,
62+ const GLbitfield newFlags, const GLbitfield newMapFlags ) :
63+ name ( newName ),
64+ internalTarget ( newTarget ),
65+ internalBindingPoint ( newBindingPoint ),
66+ flags ( newFlags ),
67+ mapFlags ( newMapFlags ) {
68+ }
69+
70+ void BindBufferBase ( GLenum target = 0 , GLuint bindingPoint = 0 ) {
71+ target = target ? target : internalTarget;
72+ bindingPoint = bindingPoint ? bindingPoint : internalBindingPoint;
73+ glBindBufferBase ( target, bindingPoint, id );
74+ }
75+
76+ void UnBindBufferBase ( GLenum target = 0 , GLuint bindingPoint = 0 ) {
77+ target = target ? target : internalTarget;
78+ bindingPoint = bindingPoint ? bindingPoint : internalBindingPoint;
79+ glBindBufferBase ( target, bindingPoint, 0 );
80+ }
81+
82+ void BindBuffer ( GLenum target = 0 ) {
83+ target = target ? target : internalTarget;
84+ glBindBuffer ( target, id );
85+ }
86+
87+ void UnBindBuffer ( GLenum target = 0 ) {
88+ target = target ? target : internalTarget;
89+ glBindBuffer ( target, 0 );
90+ }
91+
92+ void BufferData ( const GLsizeiptr size, const void * data, const GLenum usageFlags ) {
93+ glNamedBufferData ( id, size * sizeof ( uint32_t ), data, usageFlags );
94+ }
95+
96+ void BufferStorage ( const GLsizeiptr newAreaSize, const GLsizeiptr areaCount, const void * data ) {
97+ areaSize = newAreaSize;
98+ maxAreas = areaCount;
99+ glNamedBufferStorage ( id, areaSize * areaCount * sizeof ( uint32_t ), data, flags );
100+ syncs.resize ( areaCount );
101+
102+ GL_CheckErrors ();
103+ }
104+
105+ void AreaIncr () {
106+ syncs[area] = glFenceSync ( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 );
107+ area++;
108+ if ( area >= maxAreas ) {
109+ area = 0 ;
110+ }
111+ }
112+
113+ void MapAll () {
114+ if ( !mapped ) {
115+ mapped = true ;
116+ data = ( uint32_t * ) glMapNamedBufferRange ( id, 0 , areaSize * maxAreas * sizeof ( uint32_t ), flags | mapFlags );
117+ }
118+ }
119+
120+ uint32_t * GetCurrentAreaData () {
121+ if ( syncs[area] != nullptr ) {
122+ if ( glClientWaitSync ( syncs[area], GL_SYNC_FLUSH_COMMANDS_BIT, SYNC_TIMEOUT ) == GL_TIMEOUT_EXPIRED ) {
123+ Sys::Drop ( " Failed buffer %s area %u sync" , name, area );
124+ }
125+ glDeleteSync ( syncs[area] );
126+ }
127+
128+ return data + area * areaSize;
129+ }
130+
131+ uint32_t * GetData () {
132+ return data;
133+ }
134+
135+ void FlushCurrentArea () {
136+ glFlushMappedNamedBufferRange ( id, area * areaSize * sizeof ( uint32_t ), areaSize * sizeof ( uint32_t ) );
137+ }
138+
139+ void FlushAll () {
140+ glFlushMappedNamedBufferRange ( id, 0 , maxAreas * areaSize * sizeof ( uint32_t ) );
141+ }
142+
143+ void FlushRange ( const GLsizeiptr offset, const GLsizeiptr size ) {
144+ glFlushMappedNamedBufferRange ( id, offset * sizeof ( uint32_t ), size * sizeof ( uint32_t ) );
145+ }
146+
147+ uint32_t * MapBufferRange ( const GLuint count ) {
148+ return MapBufferRange ( 0 , count );
149+ }
150+
151+ uint32_t * MapBufferRange ( const GLuint offset, const GLuint count ) {
152+ if ( !mapped ) {
153+ mapped = true ;
154+ data = ( uint32_t * ) glMapNamedBufferRange ( id,
155+ offset * sizeof ( uint32_t ), count * sizeof ( uint32_t ),
156+ flags | mapFlags );
157+ }
158+
159+ return data;
160+ }
161+
162+ void UnmapBuffer () {
163+ if ( mapped ) {
164+ mapped = false ;
165+ glUnmapNamedBuffer ( id );
166+ }
167+ }
168+
169+ void GenBuffer () {
170+ glCreateBuffers ( 1 , &id );
171+ }
172+
173+ void DelBuffer () {
174+ glDeleteBuffers ( 1 , &id );
175+ mapped = false ;
176+ }
177+
178+ private:
179+ const GLenum internalTarget;
180+ const GLuint internalBindingPoint;
181+
182+ bool mapped = false ;
183+ const GLbitfield flags;
184+ const GLbitfield mapFlags;
185+
186+ std::vector<GLsync> syncs;
187+ GLsizeiptr area = 0 ;
188+ GLsizeiptr areaSize = 0 ;
189+ GLsizeiptr maxAreas = 0 ;
190+ uint32_t * data;
191+ };
192+
193+ // Shorthands for buffers that are only bound to one specific target
194+ class GLSSBO : public GLBuffer {
195+ public:
196+ GLSSBO ( const char * name, const GLuint bindingPoint, const GLbitfield flags, const GLbitfield mapFlags ) :
197+ GLBuffer ( name, GL_SHADER_STORAGE_BUFFER, bindingPoint, flags, mapFlags ) {
198+ }
199+ };
200+
201+ class GLUBO : public GLBuffer {
202+ public:
203+ GLUBO ( const char * name, const GLsizeiptr bindingPoint, const GLbitfield flags, const GLbitfield mapFlags ) :
204+ GLBuffer ( name, GL_UNIFORM_BUFFER, bindingPoint, flags, mapFlags ) {
205+ }
206+ };
207+
208+ class GLAtomicCounterBuffer : public GLBuffer {
209+ public:
210+ GLAtomicCounterBuffer ( const char * name, const GLsizeiptr bindingPoint, const GLbitfield flags, const GLbitfield mapFlags ) :
211+ GLBuffer ( name, GL_ATOMIC_COUNTER_BUFFER, bindingPoint, flags, mapFlags ) {
212+ }
213+ };
214+
215+ class GLVAO {
216+ public:
217+ vboAttributeLayout_t attrs[ATTR_INDEX_MAX];
218+ uint32_t enabledAttrs;
219+
220+ GLVAO ( const GLuint newVBOBindingPoint ) :
221+ VBOBindingPoint ( newVBOBindingPoint ) {
222+ }
223+
224+ ~GLVAO () = default ;
225+
226+ void Bind () {
227+ glBindVertexArray ( id );
228+ }
229+
230+ void SetAttrs ( const vertexAttributeSpec_t* attrBegin, const vertexAttributeSpec_t* attrEnd ) {
231+ uint32_t ofs = 0 ;
232+ for ( const vertexAttributeSpec_t* spec = attrBegin; spec < attrEnd; spec++ ) {
233+ vboAttributeLayout_t& attr = attrs[spec->attrIndex ];
234+ ASSERT_NQ ( spec->numComponents , 0U );
235+ attr.componentType = spec->componentStorageType ;
236+ if ( attr.componentType == GL_HALF_FLOAT && !glConfig2.halfFloatVertexAvailable ) {
237+ attr.componentType = GL_FLOAT;
238+ }
239+ attr.numComponents = spec->numComponents ;
240+ attr.normalize = spec->attrOptions & ATTR_OPTION_NORMALIZE ? GL_TRUE : GL_FALSE;
241+
242+ attr.ofs = ofs;
243+ ofs += attr.numComponents * R_ComponentSize ( attr.componentType );
244+ ofs = ( ofs + 3 ) & ~3 ; // 4 is minimum alignment for any vertex attribute
245+
246+ enabledAttrs |= 1 << spec->attrIndex ;
247+ }
248+
249+ stride = ofs;
250+
251+ for ( const vertexAttributeSpec_t* spec = attrBegin; spec < attrEnd; spec++ ) {
252+ const int index = spec->attrIndex ;
253+ vboAttributeLayout_t& attr = attrs[index];
254+
255+ attr.stride = stride;
256+
257+ glEnableVertexArrayAttrib ( id, index );
258+ glVertexArrayAttribFormat ( id, index, attr.numComponents , attr.componentType ,
259+ attr.normalize , attr.ofs );
260+ glVertexArrayAttribBinding ( id, index, VBOBindingPoint );
261+ }
262+ }
263+
264+ void SetVertexBuffer ( const GLBuffer buffer, const GLuint offset ) {
265+ glVertexArrayVertexBuffer ( id, VBOBindingPoint, buffer.id , offset, stride );
266+ }
267+
268+ void SetIndexBuffer ( const GLBuffer buffer ) {
269+ glVertexArrayElementBuffer ( id, buffer.id );
270+ }
271+
272+ void GenVAO () {
273+ glGenVertexArrays ( 1 , &id );
274+ }
275+
276+ void DelVAO () {
277+ glDeleteVertexArrays ( 1 , &id );
278+ }
279+
280+ private:
281+ GLuint id;
282+ const GLuint VBOBindingPoint;
283+ GLuint stride;
284+ };
40285
41286void GLBufferCopy ( GLBuffer* src, GLBuffer* dst, GLintptr srcOffset, GLintptr dstOffset, GLsizeiptr size );
42287
0 commit comments