Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
glResources.cpp
Go to the documentation of this file.
1
2
5
9
11
13
14namespace Divide
15{
16 namespace
17 {
19 {
23 };
25 };
26
27 void VAOBindings::init( const U32 maxBindings ) noexcept
28 {
29 _maxBindings = maxBindings;
30 }
31
32 bool VAOBindings::instanceDivisorFlag( const gl46core::GLuint index )
33 {
34 const size_t count = _bindings.second.size();
35 if ( count > 0 )
36 {
37 DIVIDE_ASSERT( index <= count );
38 return _bindings.second[index];
39 }
40
42 _bindings.second.resize( _maxBindings );
43 return _bindings.second.front();
44 }
45
46 void VAOBindings::instanceDivisorFlag( const gl46core::GLuint index, const bool divisorFlag )
47 {
48 const size_t count = _bindings.second.size();
49 DIVIDE_ASSERT( count > 0 && count > index );
50
51 _bindings.second[index] = divisorFlag;
52 }
53
54 const VAOBindings::BufferBindingParams& VAOBindings::bindingParams( const gl46core::GLuint index )
55 {
56 const size_t count = _bindings.first.size();
57 if ( count > 0 )
58 {
59 DIVIDE_ASSERT( index <= count );
60 return _bindings.first[index];
61 }
62
64 _bindings.first.resize( _maxBindings );
65 return _bindings.first.front();
66 }
67
68 void VAOBindings::bindingParams( const gl46core::GLuint index, const BufferBindingParams& newParams )
69 {
70 const size_t count = _bindings.first.size();
71 DIVIDE_ASSERT( count > 0 && count > index );
72
73 _bindings.first[index] = newParams;
74 }
75
76 namespace GLUtil
77 {
78
79 /*-----------Object Management----*/
81
83 thread_local SDL_GLContext s_glSecondaryContext = nullptr;
85
86 std::array<gl46core::GLenum, to_base( BlendProperty::COUNT )> glBlendTable;
87 std::array<gl46core::GLenum, to_base( BlendOperation::COUNT )> glBlendOpTable;
88 std::array<gl46core::GLenum, to_base( ComparisonFunction::COUNT )> glCompareFuncTable;
89 std::array<gl46core::GLenum, to_base( StencilOperation::COUNT )> glStencilOpTable;
90 std::array<gl46core::GLenum, to_base( CullMode::COUNT )> glCullModeTable;
91 std::array<gl46core::GLenum, to_base( FillMode::COUNT )> glFillModeTable;
92 std::array<gl46core::GLenum, to_base( TextureType::COUNT )> glTextureTypeTable;
93 std::array<gl46core::GLenum, to_base( PrimitiveTopology::COUNT )> glPrimitiveTypeTable;
94 std::array<gl46core::GLenum, to_base( GFXDataFormat::COUNT )> glDataFormatTable;
95 std::array<gl46core::GLenum, to_base( TextureWrap::COUNT )> glWrapTable;
96 std::array<gl46core::GLenum, to_base( ShaderType::COUNT )> glShaderStageTable;
97 std::array<gl46core::GLenum, to_base( QueryType::COUNT )> glQueryTypeTable;
98
99 void OnStartup()
100 {
101 glBlendTable[to_base( BlendProperty::ZERO )] = gl46core::GL_ZERO;
102 glBlendTable[to_base( BlendProperty::ONE )] = gl46core::GL_ONE;
103 glBlendTable[to_base( BlendProperty::SRC_COLOR )] = gl46core::GL_SRC_COLOR;
104 glBlendTable[to_base( BlendProperty::INV_SRC_COLOR )] = gl46core::GL_ONE_MINUS_SRC_COLOR;
105 glBlendTable[to_base( BlendProperty::SRC_ALPHA )] = gl46core::GL_SRC_ALPHA;
106 glBlendTable[to_base( BlendProperty::INV_SRC_ALPHA )] = gl46core::GL_ONE_MINUS_SRC_ALPHA;
107 glBlendTable[to_base( BlendProperty::DEST_ALPHA )] = gl46core::GL_DST_ALPHA;
108 glBlendTable[to_base( BlendProperty::INV_DEST_ALPHA )] = gl46core::GL_ONE_MINUS_DST_ALPHA;
109 glBlendTable[to_base( BlendProperty::DEST_COLOR )] = gl46core::GL_DST_COLOR;
110 glBlendTable[to_base( BlendProperty::INV_DEST_COLOR )] = gl46core::GL_ONE_MINUS_DST_COLOR;
111 glBlendTable[to_base( BlendProperty::SRC_ALPHA_SAT )] = gl46core::GL_SRC_ALPHA_SATURATE;
112
113 glBlendOpTable[to_base( BlendOperation::ADD )] = gl46core::GL_FUNC_ADD;
114 glBlendOpTable[to_base( BlendOperation::SUBTRACT )] = gl46core::GL_FUNC_SUBTRACT;
115 glBlendOpTable[to_base( BlendOperation::REV_SUBTRACT )] = gl46core::GL_FUNC_REVERSE_SUBTRACT;
116 glBlendOpTable[to_base( BlendOperation::MIN )] = gl46core::GL_MIN;
117 glBlendOpTable[to_base( BlendOperation::MAX )] = gl46core::GL_MAX;
118
122 glCompareFuncTable[to_base( ComparisonFunction::LEQUAL )] = gl46core::GL_LEQUAL;
123 glCompareFuncTable[to_base( ComparisonFunction::GREATER )] = gl46core::GL_GREATER;
124 glCompareFuncTable[to_base( ComparisonFunction::NEQUAL )] = gl46core::GL_NOTEQUAL;
125 glCompareFuncTable[to_base( ComparisonFunction::GEQUAL )] = gl46core::GL_GEQUAL;
126 glCompareFuncTable[to_base( ComparisonFunction::ALWAYS )] = gl46core::GL_ALWAYS;
127
128 glStencilOpTable[to_base( StencilOperation::KEEP )] = gl46core::GL_KEEP;
129 glStencilOpTable[to_base( StencilOperation::ZERO )] = gl46core::GL_ZERO;
130 glStencilOpTable[to_base( StencilOperation::REPLACE )] = gl46core::GL_REPLACE;
131 glStencilOpTable[to_base( StencilOperation::INCR )] = gl46core::GL_INCR;
132 glStencilOpTable[to_base( StencilOperation::DECR )] = gl46core::GL_DECR;
133 glStencilOpTable[to_base( StencilOperation::INV )] = gl46core::GL_INVERT;
134 glStencilOpTable[to_base( StencilOperation::INCR_WRAP )] = gl46core::GL_INCR_WRAP;
135 glStencilOpTable[to_base( StencilOperation::DECR_WRAP )] = gl46core::GL_DECR_WRAP;
136
137 glCullModeTable[to_base( CullMode::BACK )] = gl46core::GL_BACK;
138 glCullModeTable[to_base( CullMode::FRONT )] = gl46core::GL_FRONT;
139 glCullModeTable[to_base( CullMode::ALL )] = gl46core::GL_FRONT_AND_BACK;
140 glCullModeTable[to_base( CullMode::NONE )] = gl46core::GL_NONE;
141
142 glFillModeTable[to_base( FillMode::POINT )] = gl46core::GL_POINT;
143 glFillModeTable[to_base( FillMode::WIREFRAME )] = gl46core::GL_LINE;
144 glFillModeTable[to_base( FillMode::SOLID )] = gl46core::GL_FILL;
145
146 glTextureTypeTable[to_base( TextureType::TEXTURE_1D )] = gl46core::GL_TEXTURE_1D;
147 glTextureTypeTable[to_base( TextureType::TEXTURE_2D )] = gl46core::GL_TEXTURE_2D;
148 glTextureTypeTable[to_base( TextureType::TEXTURE_3D )] = gl46core::GL_TEXTURE_3D;
149 glTextureTypeTable[to_base( TextureType::TEXTURE_CUBE_MAP )] = gl46core::GL_TEXTURE_CUBE_MAP;
150 glTextureTypeTable[to_base( TextureType::TEXTURE_1D_ARRAY )] = gl46core::GL_TEXTURE_1D_ARRAY;
151 glTextureTypeTable[to_base( TextureType::TEXTURE_2D_ARRAY )] = gl46core::GL_TEXTURE_2D_ARRAY;
152 glTextureTypeTable[to_base( TextureType::TEXTURE_CUBE_ARRAY )] = gl46core::GL_TEXTURE_CUBE_MAP_ARRAY;
153
156 glPrimitiveTypeTable[to_base( PrimitiveTopology::LINE_STRIP )] = gl46core::GL_LINE_STRIP;
157 glPrimitiveTypeTable[to_base( PrimitiveTopology::TRIANGLES )] = gl46core::GL_TRIANGLES;
158 glPrimitiveTypeTable[to_base( PrimitiveTopology::TRIANGLE_STRIP )] = gl46core::GL_TRIANGLE_STRIP;
159 glPrimitiveTypeTable[to_base( PrimitiveTopology::TRIANGLE_FAN )] = gl46core::GL_TRIANGLE_FAN;
160 glPrimitiveTypeTable[to_base( PrimitiveTopology::LINES_ADJANCENCY )] = gl46core::GL_LINES_ADJACENCY;
161 glPrimitiveTypeTable[to_base( PrimitiveTopology::LINE_STRIP_ADJACENCY )] = gl46core::GL_LINE_STRIP_ADJACENCY;
162 glPrimitiveTypeTable[to_base( PrimitiveTopology::TRIANGLES_ADJACENCY )] = gl46core::GL_TRIANGLES_ADJACENCY;
163 glPrimitiveTypeTable[to_base( PrimitiveTopology::TRIANGLE_STRIP_ADJACENCY )] = gl46core::GL_TRIANGLE_STRIP_ADJACENCY;
164 glPrimitiveTypeTable[to_base( PrimitiveTopology::PATCH )] = gl46core::GL_PATCHES;
166
167 glDataFormatTable[to_base( GFXDataFormat::UNSIGNED_BYTE )] = gl46core::GL_UNSIGNED_BYTE;
168 glDataFormatTable[to_base( GFXDataFormat::UNSIGNED_SHORT )] = gl46core::GL_UNSIGNED_SHORT;
169 glDataFormatTable[to_base( GFXDataFormat::UNSIGNED_INT )] = gl46core::GL_UNSIGNED_INT;
173 glDataFormatTable[to_base( GFXDataFormat::FLOAT_16 )] = gl46core::GL_HALF_FLOAT;
174 glDataFormatTable[to_base( GFXDataFormat::FLOAT_32 )] = gl46core::GL_FLOAT;
175
176 glWrapTable[to_base( TextureWrap::MIRROR_REPEAT )] = gl46core::GL_MIRRORED_REPEAT;
177 glWrapTable[to_base( TextureWrap::REPEAT )] = gl46core::GL_REPEAT;
178 glWrapTable[to_base( TextureWrap::CLAMP_TO_EDGE )] = gl46core::GL_CLAMP_TO_EDGE;
179 glWrapTable[to_base( TextureWrap::CLAMP_TO_BORDER )] = gl46core::GL_CLAMP_TO_BORDER;
180 glWrapTable[to_base( TextureWrap::MIRROR_CLAMP_TO_EDGE )] = gl46core::GL_MIRROR_CLAMP_TO_EDGE;
181
182 glShaderStageTable[to_base( ShaderType::VERTEX )] = gl46core::GL_VERTEX_SHADER;
183 glShaderStageTable[to_base( ShaderType::FRAGMENT )] = gl46core::GL_FRAGMENT_SHADER;
184 glShaderStageTable[to_base( ShaderType::GEOMETRY )] = gl46core::GL_GEOMETRY_SHADER;
185 glShaderStageTable[to_base( ShaderType::TESSELLATION_CTRL )] = gl46core::GL_TESS_CONTROL_SHADER;
186 glShaderStageTable[to_base( ShaderType::TESSELLATION_EVAL )] = gl46core::GL_TESS_EVALUATION_SHADER;
187 glShaderStageTable[to_base( ShaderType::COMPUTE )] = gl46core::GL_COMPUTE_SHADER;
188
189 glQueryTypeTable[to_U8(log2(to_base(QueryType::VERTICES_SUBMITTED))) - 1] = gl46core::GL_VERTICES_SUBMITTED;
190 glQueryTypeTable[to_U8(log2(to_base(QueryType::PRIMITIVES_GENERATED))) - 1] = gl46core::GL_PRIMITIVES_GENERATED;
191 glQueryTypeTable[to_U8(log2(to_base(QueryType::TESSELLATION_PATCHES))) - 1] = gl46core::GL_TESS_CONTROL_SHADER_PATCHES;
192 glQueryTypeTable[to_U8(log2(to_base(QueryType::TESSELLATION_EVAL_INVOCATIONS))) - 1] = gl46core::GL_TESS_EVALUATION_SHADER_INVOCATIONS;
193 glQueryTypeTable[to_U8(log2(to_base(QueryType::GPU_TIME))) - 1] = gl46core::GL_TIME_ELAPSED;
194 glQueryTypeTable[to_U8(log2(to_base(QueryType::SAMPLE_COUNT))) - 1] = gl46core::GL_SAMPLES_PASSED;
195 glQueryTypeTable[to_U8(log2(to_base(QueryType::ANY_SAMPLE_RENDERED))) - 1] = gl46core::GL_ANY_SAMPLES_PASSED_CONSERVATIVE;
196
197 s_multiDrawIndexData._countData.resize(256, 0u);
198 s_multiDrawIndexData._indexOffsetData.resize(256, 0u);
199 s_multiDrawIndexData._baseVertexData.resize(256, 0);
200 }
201
202 FormatAndDataType InternalFormatAndDataType( const GFXImageFormat baseFormat, const GFXDataFormat dataType, const GFXImagePacking packing) noexcept
203 {
204 const bool isDepth = IsDepthTexture(packing);
205 const bool isSRGB = packing == GFXImagePacking::NORMALIZED_SRGB;
206 const bool isPacked = packing == GFXImagePacking::RGB_565 || packing == GFXImagePacking::RGBA_4444;
207 const bool isNormalized = packing == GFXImagePacking::NORMALIZED || isSRGB || isDepth || isPacked;
208
209 if ( isDepth )
210 {
211 DIVIDE_ASSERT( baseFormat == GFXImageFormat::RED );
212 }
213
214 if ( isSRGB )
215 {
217 baseFormat == GFXImageFormat::RGB ||
218 baseFormat == GFXImageFormat::BGR ||
219 baseFormat == GFXImageFormat::RGBA ||
220 baseFormat == GFXImageFormat::BGRA ||
221 baseFormat == GFXImageFormat::DXT1_RGB ||
222 baseFormat == GFXImageFormat::DXT1_RGBA ||
223 baseFormat == GFXImageFormat::DXT3_RGBA ||
224 baseFormat == GFXImageFormat::DXT5_RGBA ||
225 baseFormat == GFXImageFormat::BC7,
226 "GLUtil::InternalFormatAndDataType: OpenGL only supports RGB(A)8 and BC1/2/3/7 for SRGB!" );
227 }
228
229 if ( isNormalized && !isDepth )
230 {
232 dataType == GFXDataFormat::UNSIGNED_BYTE ||
233 dataType == GFXDataFormat::SIGNED_SHORT ||
234 dataType == GFXDataFormat::UNSIGNED_SHORT ||
235 dataType == GFXDataFormat::FLOAT_16 ||
236 dataType == GFXDataFormat::FLOAT_32 );
237 }
238
239 if ( isPacked )
240 {
241 DIVIDE_ASSERT(baseFormat == GFXImageFormat::RGB ||
242 baseFormat == GFXImageFormat::BGR ||
243 baseFormat == GFXImageFormat::RGBA ||
244 baseFormat == GFXImageFormat::BGRA);
245 }
246
247 if ( baseFormat == GFXImageFormat::BGR || baseFormat == GFXImageFormat::BGRA )
248 {
250 dataType == GFXDataFormat::SIGNED_BYTE,
251 "GLUtil::InternalFormat: Vulkan only supports 8Bpp for BGR(A) format, so for now we completely ignore other data types." );
252 }
253
254 FormatAndDataType ret{};
255 if ( packing == GFXImagePacking::RGB_565 )
256 {
257 ret._dataType = gl46core::GL_UNSIGNED_SHORT_5_6_5;
258 }
259 else if ( packing == GFXImagePacking::RGBA_4444 )
260 {
261 ret._dataType = gl46core::GL_UNSIGNED_SHORT_4_4_4_4;
262 }
263 else
264 {
265 ret._dataType = glDataFormatTable[to_base( dataType )];
266 }
267
268 switch ( baseFormat )
269 {
271 {
272 if ( packing == GFXImagePacking::DEPTH )
273 {
274 ret._internalFormat = gl46core::GL_DEPTH_COMPONENT;
275
276 switch ( dataType )
277 {
281 case GFXDataFormat::UNSIGNED_SHORT: ret._format = gl46core::GL_DEPTH_COMPONENT16; break;
283 case GFXDataFormat::UNSIGNED_INT: ret._format = gl46core::GL_DEPTH_COMPONENT24; break;
285 case GFXDataFormat::FLOAT_32: ret._format = gl46core::GL_DEPTH_COMPONENT32F; break;
286 default: break;
287 }
288 }
289 else if ( packing == GFXImagePacking::DEPTH_STENCIL )
290 {
291 ret._internalFormat = gl46core::GL_DEPTH_COMPONENT;
292
293 switch ( dataType )
294 {
300 case GFXDataFormat::UNSIGNED_INT: ret._format = gl46core::GL_DEPTH24_STENCIL8; break;
302 case GFXDataFormat::FLOAT_32: ret._format = gl46core::GL_DEPTH32F_STENCIL8; break;
303 default: break;
304 }
305 }
306 else
307 {
308 ret._internalFormat = isNormalized ? gl46core::GL_RED : gl46core::GL_RED_INTEGER;
309
310 switch ( dataType )
311 {
312 case GFXDataFormat::UNSIGNED_BYTE: ret._format = isNormalized ? gl46core::GL_R8 : gl46core::GL_R8UI; break;
313 case GFXDataFormat::UNSIGNED_SHORT: ret._format = isNormalized ? gl46core::GL_R16 : gl46core::GL_R16UI; break;
314 case GFXDataFormat::SIGNED_BYTE: ret._format = isNormalized ? gl46core::GL_R8_SNORM : gl46core::GL_R8I; break;
315 case GFXDataFormat::SIGNED_SHORT: ret._format = isNormalized ? gl46core::GL_R16_SNORM : gl46core::GL_R16I; break;
316 case GFXDataFormat::UNSIGNED_INT: ret._format = gl46core::GL_R32UI; ret._internalFormat = gl46core::GL_RED_INTEGER; DIVIDE_ASSERT(!isNormalized); break;
317 case GFXDataFormat::SIGNED_INT: ret._format = gl46core::GL_R32I; ret._internalFormat = gl46core::GL_RED_INTEGER; DIVIDE_ASSERT(!isNormalized); break;
318 case GFXDataFormat::FLOAT_16: ret._format = gl46core::GL_R16F; ret._internalFormat = gl46core::GL_RED; break;
319 case GFXDataFormat::FLOAT_32: ret._format = gl46core::GL_R32F; ret._internalFormat = gl46core::GL_RED; break;
320 default: break;
321 }
322 }
323 }break;
325 {
326 ret._internalFormat = isNormalized ? gl46core::GL_RG : gl46core::GL_RG_INTEGER;
327
328 switch ( dataType )
329 {
330 case GFXDataFormat::UNSIGNED_BYTE: ret._format = isNormalized ? gl46core::GL_RG8 : gl46core::GL_RG8UI; break;
331 case GFXDataFormat::UNSIGNED_SHORT: ret._format = isNormalized ? gl46core::GL_RG16 : gl46core::GL_RG16UI; break;
332 case GFXDataFormat::SIGNED_BYTE: ret._format = isNormalized ? gl46core::GL_RG8_SNORM : gl46core::GL_RG8I; break;
333 case GFXDataFormat::SIGNED_SHORT: ret._format = isNormalized ? gl46core::GL_RG16_SNORM : gl46core::GL_RG16I; break;
334 case GFXDataFormat::UNSIGNED_INT: ret._format = gl46core::GL_RG32UI; ret._internalFormat = gl46core::GL_RG_INTEGER; DIVIDE_ASSERT(!isNormalized); break;
335 case GFXDataFormat::SIGNED_INT: ret._format = gl46core::GL_RG32I; ret._internalFormat = gl46core::GL_RG_INTEGER; DIVIDE_ASSERT(!isNormalized); break;
336 case GFXDataFormat::FLOAT_16: ret._format = gl46core::GL_RG16F; ret._internalFormat = gl46core::GL_RG; break;
337 case GFXDataFormat::FLOAT_32: ret._format = gl46core::GL_RG32F; ret._internalFormat = gl46core::GL_RG; break;
338 default: break;
339 }
340 }break;
343 {
344 ret._internalFormat = baseFormat == GFXImageFormat::RGB ? (isNormalized ? gl46core::GL_RGB : gl46core::GL_RGB_INTEGER) : (isNormalized ? gl46core::GL_BGR : gl46core::GL_BGR_INTEGER);
345 if ( packing == GFXImagePacking::RGB_565 )
346 {
347 DIVIDE_ASSERT( isNormalized );
348
349 ret._format = gl46core::GL_RGB565;
350 }
351 else
352 {
353 switch ( dataType )
354 {
355 case GFXDataFormat::UNSIGNED_BYTE : ret._format = isNormalized ? (isSRGB ? gl46core::GL_SRGB8 : gl46core::GL_RGB8) : gl46core::GL_RGB8UI; break;
356 case GFXDataFormat::UNSIGNED_SHORT: ret._format = isNormalized ? gl46core::GL_RGB16 : gl46core::GL_RGB16UI; break;
357 case GFXDataFormat::SIGNED_BYTE: ret._format = isNormalized ? gl46core::GL_RGB8_SNORM : gl46core::GL_RGB8I; break;
358 case GFXDataFormat::SIGNED_SHORT: ret._format = isNormalized ? gl46core::GL_RGB16_SNORM : gl46core::GL_RGB16I; break;
359 case GFXDataFormat::UNSIGNED_INT: ret._format = gl46core::GL_RGB32UI; ret._internalFormat = gl46core::GL_RGB_INTEGER; DIVIDE_ASSERT( !isNormalized ); break;
360 case GFXDataFormat::SIGNED_INT: ret._format = gl46core::GL_RGB32I; ret._internalFormat = gl46core::GL_RGB_INTEGER; DIVIDE_ASSERT( !isNormalized ); break;
361 case GFXDataFormat::FLOAT_16: ret._format = gl46core::GL_RGB16F; ret._internalFormat = gl46core::GL_RGB; break;
362 case GFXDataFormat::FLOAT_32: ret._format = gl46core::GL_RGB32F; ret._internalFormat = gl46core::GL_RGB; break;
363 default: break;
364 }
365 }
366 }break;
369 {
370 ret._internalFormat = baseFormat == GFXImageFormat::RGBA ? (isNormalized ? gl46core::GL_RGBA : gl46core::GL_RGBA_INTEGER) : (isNormalized ? gl46core::GL_BGRA : gl46core::GL_BGRA_INTEGER);
371 if ( packing == GFXImagePacking::RGBA_4444 )
372 {
373 ret._format = gl46core::GL_RGBA4;
374 }
375 else
376 {
377 switch ( dataType )
378 {
379 case GFXDataFormat::UNSIGNED_BYTE: ret._format = isNormalized ? (isSRGB ? gl46core::GL_SRGB8_ALPHA8 : gl46core::GL_RGBA8) : gl46core::GL_RGBA8UI; break;
380 case GFXDataFormat::UNSIGNED_SHORT: ret._format = isNormalized ? gl46core::GL_RGBA16 : gl46core::GL_RGBA16UI; break;
381 case GFXDataFormat::SIGNED_BYTE: ret._format = isNormalized ? gl46core::GL_RGBA8_SNORM : gl46core::GL_RGBA8I; break;
382 case GFXDataFormat::SIGNED_SHORT: ret._format = isNormalized ? gl46core::GL_RGBA16_SNORM : gl46core::GL_RGBA16I; break;
383 case GFXDataFormat::UNSIGNED_INT: ret._format = gl46core::GL_RGBA32UI; ret._internalFormat = gl46core::GL_RGBA_INTEGER; DIVIDE_ASSERT( !isNormalized ); break;
384 case GFXDataFormat::SIGNED_INT: ret._format = gl46core::GL_RGBA32I; ret._internalFormat = gl46core::GL_RGBA_INTEGER; DIVIDE_ASSERT( !isNormalized ); break;
385 case GFXDataFormat::FLOAT_16: ret._format = gl46core::GL_RGBA16F; ret._internalFormat = gl46core::GL_RGBA; break;
386 case GFXDataFormat::FLOAT_32: ret._format = gl46core::GL_RGBA32F; ret._internalFormat = gl46core::GL_RGBA; break;
387 default: break;
388 }
389 }
390 }break;
391
392 // compressed formats
393 case GFXImageFormat::DXT1_RGB: ret._format = ret._internalFormat = packing == GFXImagePacking::NORMALIZED_SRGB ? gl::GL_COMPRESSED_SRGB_S3TC_DXT1_EXT : gl::GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break; //BC1
394 case GFXImageFormat::DXT1_RGBA: ret._format = ret._internalFormat = packing == GFXImagePacking::NORMALIZED_SRGB ? gl::GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT : gl::GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; //BC1a
395 case GFXImageFormat::DXT3_RGBA: ret._format = ret._internalFormat = packing == GFXImagePacking::NORMALIZED_SRGB ? gl::GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT : gl::GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; //BC2
396 case GFXImageFormat::DXT5_RGBA: ret._format = ret._internalFormat = packing == GFXImagePacking::NORMALIZED_SRGB ? gl::GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : gl::GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; //BC3
397 case GFXImageFormat::BC3n: ret._format = ret._internalFormat = gl::GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
398 case GFXImageFormat::BC4s: ret._format = ret._internalFormat = gl::GL_COMPRESSED_SIGNED_RED_RGTC1_EXT; break;
399 case GFXImageFormat::BC4u: ret._format = ret._internalFormat = gl::GL_COMPRESSED_RED_RGTC1_EXT; break;
400 case GFXImageFormat::BC5s: ret._format = ret._internalFormat = gl::GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT; break;
401 case GFXImageFormat::BC5u: ret._format = ret._internalFormat = gl::GL_COMPRESSED_RED_GREEN_RGTC2_EXT; break;
402 case GFXImageFormat::BC6s: ret._format = ret._internalFormat = gl::GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT; break;
403 case GFXImageFormat::BC6u: ret._format = ret._internalFormat = gl::GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; break;
404 case GFXImageFormat::BC7: ret._format = ret._internalFormat = packing == GFXImagePacking::NORMALIZED_SRGB ? gl::GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB : gl::GL_COMPRESSED_RGBA_BPTC_UNORM; break; //BC7
405
406 default: break;
407 }
408
409 DIVIDE_ASSERT(ret._format != gl46core::GL_NONE && ret._dataType != gl46core::GL_NONE, "GLUtil::internalFormat: Unsupported texture and format combination!");
410 return ret;
411 }
412
413 gl46core::GLenum internalTextureType( const TextureType type, const U8 msaaSamples )
414 {
415 if ( msaaSamples > 0u )
416 {
417 switch ( type )
418 {
419 case TextureType::TEXTURE_2D: return gl46core::GL_TEXTURE_2D_MULTISAMPLE;
420 case TextureType::TEXTURE_2D_ARRAY: return gl46core::GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
421
427 case TextureType::COUNT:
429 break;
430 }
431 }
432
433 return GLUtil::glTextureTypeTable[to_base( type )];
434 }
435
436 bool ValidateSDL( const I32 errCode, bool assert )
437 {
438 if ( errCode != 0 )
439 {
440 Console::errorfn( LOCALE_STR( "SDL_ERROR" ), SDL_GetError() );
441 if ( assert )
442 {
443 DIVIDE_UNEXPECTED_CALL_MSG( SDL_GetError() );
444 }
445 return false;
446 }
447
448 return true;
449 }
450
451 void SubmitRenderCommand( const GenericDrawCommand& drawCommand, const gl46core::GLenum internalFormat)
452 {
453 if ( drawCommand._drawCount > 0u && drawCommand._cmd.instanceCount > 0u)
454 {
455 const bool useIndirectBuffer = isEnabledOption( drawCommand, CmdRenderOptions::RENDER_INDIRECT );
456
457 if ( !useIndirectBuffer && drawCommand._cmd.instanceCount > 1u && drawCommand._drawCount > 1u ) [[unlikely]]
458 {
459 DIVIDE_UNEXPECTED_CALL_MSG( "Multi-draw is incompatible with instancing as gl_DrawID will have the wrong value (base instance is also used for buffer indexing). Split the call into multiple draw commands with manual uniform-updates in-between!" );
460 }
461
462 if ( internalFormat != gl46core::GL_NONE )
463 {
464 // We could collapse multiple of these into a generic glMultiDrawElementsBaseVertex and pass 1 or 0 to the required parameters for the exceptions
465 // but those exceptions are the common case and I don't know what kind of bookeeping the driver does for multi-draw calls so a few if-checks and we
466 // handle all that app-side. Also, the simpler the command, the larger the chance it is very well optimised by now and extremely supported by tools -Ionut
467
468 const gl46core::GLenum primitiveType = glPrimitiveTypeTable[to_base( GL_API::GetStateTracker()._activeTopology )];
469 if ( useIndirectBuffer )
470 {
471 const size_t offset = (drawCommand._commandOffset * sizeof( IndirectIndexedDrawCommand )) + GL_API::GetStateTracker()._drawIndirectBufferOffset;
472 if ( drawCommand._drawCount > 1u )
473 {
474 gl46core::glMultiDrawElementsIndirect( primitiveType, internalFormat, (bufferPtr)offset, drawCommand._drawCount, sizeof( IndirectIndexedDrawCommand ) );
475 }
476 else
477 {
478 gl46core::glDrawElementsIndirect( primitiveType, internalFormat, (bufferPtr)offset );
479 }
480 }
481 else
482 {
483 const bufferPtr offset = (bufferPtr)(drawCommand._cmd.firstIndex * (internalFormat == gl46core::GL_UNSIGNED_SHORT ? sizeof( gl46core::GLushort ) : sizeof( gl46core::GLuint )));
484 if ( drawCommand._drawCount > 1u )
485 {
486 if ( s_multiDrawIndexData._countData.size() < drawCommand._drawCount )
487 {
488 // Well, a memory allocation here is BAD. Really bad!
489 s_multiDrawIndexData._countData.resize( drawCommand._drawCount * 2 );
490 s_multiDrawIndexData._indexOffsetData.resize( drawCommand._drawCount * 2 );
491 s_multiDrawIndexData._baseVertexData.resize( drawCommand._drawCount * 2 );
492 }
493 eastl::fill( begin( s_multiDrawIndexData._countData ), begin( s_multiDrawIndexData._countData ) + drawCommand._drawCount, drawCommand._cmd.indexCount );
494 eastl::fill( begin( s_multiDrawIndexData._indexOffsetData ), begin( s_multiDrawIndexData._indexOffsetData ) + drawCommand._drawCount, drawCommand._cmd.firstIndex );
495 if ( drawCommand._cmd.baseVertex > 0u )
496 {
497 eastl::fill( begin( s_multiDrawIndexData._baseVertexData ), begin( s_multiDrawIndexData._baseVertexData ) + drawCommand._drawCount, drawCommand._cmd.baseVertex );
498 glMultiDrawElementsBaseVertex( primitiveType, s_multiDrawIndexData._countData.data(), internalFormat, (const void* const*)s_multiDrawIndexData._indexOffsetData.data(), drawCommand._drawCount, s_multiDrawIndexData._baseVertexData.data() );
499 }
500 else
501 {
502 glMultiDrawElements( primitiveType, s_multiDrawIndexData._countData.data(), internalFormat, (const void* const*)s_multiDrawIndexData._indexOffsetData.data(), drawCommand._drawCount );
503 }
504 }
505 else
506 {
507 if ( drawCommand._cmd.instanceCount == 1u )
508 {
509 if ( drawCommand._cmd.baseVertex > 0u )
510 {
511 glDrawElementsBaseVertex( primitiveType, drawCommand._cmd.indexCount, internalFormat, offset, drawCommand._cmd.baseVertex );
512 }
513 else// (drawCommand._cmd.baseVertex == 0)
514 {
515 glDrawElements( primitiveType, drawCommand._cmd.indexCount, internalFormat, offset );
516 }
517 }
518 else// (drawCommand._cmd.instanceCount > 1u)
519 {
520 if ( drawCommand._cmd.baseVertex > 0u )
521 {
522 if ( drawCommand._cmd.baseInstance > 0u )
523 {
524 glDrawElementsInstancedBaseVertexBaseInstance( primitiveType, drawCommand._cmd.indexCount, internalFormat, offset, drawCommand._cmd.instanceCount, drawCommand._cmd.baseVertex, drawCommand._cmd.baseInstance );
525 }
526 else // (drawCommand._cmd.baseInstance == 0)
527 {
528 glDrawElementsInstancedBaseVertex( primitiveType, drawCommand._cmd.indexCount, internalFormat, offset, drawCommand._cmd.instanceCount, drawCommand._cmd.baseVertex );
529 }
530 }
531 else // (drawCommand._cmd.baseVertex == 0)
532 {
533 if ( drawCommand._cmd.baseInstance > 0u )
534 {
535 glDrawElementsInstancedBaseInstance( primitiveType, drawCommand._cmd.indexCount, internalFormat, offset, drawCommand._cmd.instanceCount, drawCommand._cmd.baseInstance );
536 }
537 else // (drawCommand._cmd.baseInstance == 0)
538 {
539 glDrawElementsInstanced( primitiveType, drawCommand._cmd.indexCount, internalFormat, offset, drawCommand._cmd.instanceCount );
540 }
541 }
542 }
543 }
544 }
545 }
546 else
547 {
548 const gl46core::GLenum primitiveType = glPrimitiveTypeTable[to_base( GL_API::GetStateTracker()._activeTopology )];
549 if ( useIndirectBuffer )
550 {
551 const size_t offset = (drawCommand._commandOffset * sizeof( IndirectNonIndexedDrawCommand )) + GL_API::GetStateTracker()._drawIndirectBufferOffset;
552 if ( drawCommand._drawCount > 1u )
553 {
554 gl46core::glMultiDrawArraysIndirect( primitiveType, (bufferPtr)offset, drawCommand._drawCount, sizeof( IndirectNonIndexedDrawCommand ) );
555 }
556 else [[likely]]
557 {
558 gl46core::glDrawArraysIndirect( primitiveType, (bufferPtr)offset );
559 }
560 }
561 else
562 {
563 if ( drawCommand._drawCount > 1u )
564 {
565 if ( s_multiDrawIndexData._countData.size() < drawCommand._drawCount )
566 {
567 // Well, a memory allocation here is BAD. Really bad!
568 s_multiDrawIndexData._countData.resize( drawCommand._drawCount * 2 );
569 s_multiDrawIndexData._baseVertexData.resize( drawCommand._drawCount * 2 );
570 }
571 eastl::fill( begin( s_multiDrawIndexData._countData ), begin( s_multiDrawIndexData._countData ) + drawCommand._drawCount, drawCommand._cmd.indexCount );
572 eastl::fill( begin( s_multiDrawIndexData._baseVertexData ), begin( s_multiDrawIndexData._baseVertexData ) + drawCommand._drawCount, drawCommand._cmd.baseVertex );
573 gl46core::glMultiDrawArrays( primitiveType, s_multiDrawIndexData._baseVertexData.data(), s_multiDrawIndexData._countData.data(), drawCommand._drawCount );
574 }
575 else //( drawCommand._drawCount == 1u )
576 {
577 if ( drawCommand._cmd.instanceCount == 1u )
578 {
579 gl46core::glDrawArrays( primitiveType, drawCommand._cmd.baseVertex, drawCommand._cmd.vertexCount );
580 }
581 else //(drawCommand._cmd.instanceCount > 1u)
582 {
583 if ( drawCommand._cmd.baseInstance == 0u )
584 {
585 gl46core::glDrawArraysInstanced( primitiveType, drawCommand._cmd.baseVertex, drawCommand._cmd.vertexCount, drawCommand._cmd.instanceCount );
586 }
587 else //( drawCommand._cmd.baseInstance > 0u )
588 {
589 gl46core::glDrawArraysInstancedBaseInstance( primitiveType, drawCommand._cmd.baseVertex, drawCommand._cmd.vertexCount, drawCommand._cmd.instanceCount, drawCommand._cmd.baseInstance );
590 }
591 }
592 }
593 }
594 }
595 }
596 }
597
598 void glTextureViewCache::init( const U32 poolSize )
599 {
600 _usageMap.resize( poolSize, State::FREE );
601 _handles.resize( poolSize, 0u );
602 _lifeLeft.resize( poolSize, 0u );
603 _tempBuffer.resize( poolSize, 0u );
604
605 gl46core::glGenTextures( static_cast<gl46core::GLsizei>(poolSize), _handles.data() );
606 }
607
609 {
611
613 gl46core::GLuint count = 0u;
614 const U32 entryCount = to_U32( _tempBuffer.size() );
615 for ( U32 i = 0u; i < entryCount; ++i )
616 {
617 if ( _usageMap[i] != State::CLEAN )
618 {
619 continue;
620 }
621
622 U32& lifeLeft = _lifeLeft[i];
623
624 if ( lifeLeft > 0u )
625 {
626 lifeLeft -= 1u;
627 }
628
629 if ( lifeLeft == 0u )
630 {
631 _tempBuffer[count++] = _handles[i];
632 }
633 }
634
635 if ( count > 0u )
636 {
637 gl46core::glDeleteTextures( count, _tempBuffer.data() );
638 gl46core::glGenTextures( count, _tempBuffer.data() );
639
640 U32 newIndex = 0u;
641 for ( U32 i = 0u; i < entryCount; ++i )
642 {
643 if ( _lifeLeft[i] == 0u && _usageMap[i] == State::CLEAN )
644 {
646 _handles[i] = _tempBuffer[newIndex++];
647 erase_if( _cache, [i]( const CacheEntry& entry )
648 {
649 return entry._idx == i;
650 } );
651 }
652 }
653 memset( _tempBuffer.data(), 0, sizeof( gl46core::GLuint ) * count );
654 }
655 }
656
658 {
660 const U32 entryCount = to_U32( _tempBuffer.size() );
661 gl46core::glDeleteTextures( static_cast<gl46core::GLsizei>(entryCount), _handles.data() );
662 memset( _handles.data(), 0, sizeof( gl46core::GLuint ) * entryCount );
663 memset( _lifeLeft.data(), 0, sizeof( U32 ) * entryCount );
664 std::fill( begin( _usageMap ), end( _usageMap ), State::CLEAN );
665 _cache.clear();
666 }
667
668 gl46core::GLuint glTextureViewCache::allocate( const bool retry )
669 {
670 return allocate( 0u, retry ).first;
671 }
672
673 std::pair<gl46core::GLuint, bool> glTextureViewCache::allocate( const size_t hash, const bool retry )
674 {
676 {
678
679 if ( hash != 0u && hash != SIZE_MAX)
680 {
681 U32 idx = U32_MAX;
682 for ( const CacheEntry& entry : _cache )
683 {
684 if ( entry._hash == hash )
685 {
686 // Return the OpenGL handle for the sampler object matching the specified hash value
687 idx = entry._idx;
688 break;
689 }
690 }
691
692 if ( idx != U32_MAX )
693 {
694 assert( _usageMap[idx] != State::FREE );
695 _usageMap[idx] = State::USED;
696 _lifeLeft[idx] += 1;
697 return std::make_pair( _handles[idx], true );
698 }
699 }
700
701 const U32 count = to_U32( _handles.size() );
702 for ( U32 i = 0u; i < count; ++i )
703 {
704 if ( _usageMap[i] == State::FREE )
705 {
707 _lifeLeft[i] = 1u;
708 _cache.emplace_back(hash, i);
709
710 return std::make_pair( _handles[i], false );
711 }
712 }
713 }
714
715 if ( !retry )
716 {
717 onFrameEnd();
718 return allocate( hash, true );
719 }
720
722 return std::make_pair( 0u, false );
723 }
724
725 void glTextureViewCache::deallocate( const gl46core::GLuint handle, const U32 frameDelay )
726 {
728
730 const U32 count = to_U32( _handles.size() );
731 for ( U32 i = 0u; i < count; ++i )
732 {
733 if ( _handles[i] == handle )
734 {
735 _lifeLeft[i] = frameDelay;
737 return;
738 }
739 }
740
742 }
743
745 void DebugCallback( const gl46core::GLenum source,
746 const gl46core::GLenum type,
747 const gl46core::GLuint id,
748 const gl46core::GLenum severity,
749 [[maybe_unused]] const gl46core::GLsizei length,
750 const gl46core::GLchar* message,
751 const void* userParam )
752 {
753 if ( GL_API::GetStateTracker()._enabledAPIDebugging && !(*GL_API::GetStateTracker()._enabledAPIDebugging) )
754 {
755 return;
756 }
757
758 if ( type == gl46core::GL_DEBUG_TYPE_OTHER && severity == gl46core::GL_DEBUG_SEVERITY_NOTIFICATION )
759 {
760 // Really don't care about these
761 return;
762 }
763
764 // Translate message source
765 const char* gl_source = "Unknown Source";
766 if ( source == gl46core::GL_DEBUG_SOURCE_API )
767 {
768 gl_source = "OpenGL";
769 }
770 else if ( source == gl46core::GL_DEBUG_SOURCE_WINDOW_SYSTEM )
771 {
772 gl_source = "Windows";
773 }
774 else if ( source == gl46core::GL_DEBUG_SOURCE_SHADER_COMPILER )
775 {
776 gl_source = "Shader Compiler";
777 }
778 else if ( source == gl46core::GL_DEBUG_SOURCE_THIRD_PARTY )
779 {
780 gl_source = "Third Party";
781 }
782 else if ( source == gl46core::GL_DEBUG_SOURCE_APPLICATION )
783 {
784 gl_source = "Application";
785 }
786 else if ( source == gl46core::GL_DEBUG_SOURCE_OTHER )
787 {
788 gl_source = "Other";
789 }
790 // Translate message type
791 const char* gl_type = "Unknown Type";
792 if ( type == gl46core::GL_DEBUG_TYPE_ERROR )
793 {
794 gl_type = "Error";
795 }
796 else if ( type == gl46core::GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR )
797 {
798 gl_type = "Deprecated behavior";
799 }
800 else if ( type == gl46core::GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR )
801 {
802 gl_type = "Undefined behavior";
803 }
804 else if ( type == gl46core::GL_DEBUG_TYPE_PORTABILITY )
805 {
806 gl_type = "Portability";
807 }
808 else if ( type == gl46core::GL_DEBUG_TYPE_PERFORMANCE )
809 {
810 gl_type = "Performance";
811 }
812 else if ( type == gl46core::GL_DEBUG_TYPE_OTHER )
813 {
814 gl_type = "Other";
815 }
816 else if ( type == gl46core::GL_DEBUG_TYPE_MARKER )
817 {
818 gl_type = "Marker";
819 }
820 else if ( type == gl46core::GL_DEBUG_TYPE_PUSH_GROUP )
821 {
822 gl_type = "Push";
823 }
824 else if ( type == gl46core::GL_DEBUG_TYPE_POP_GROUP )
825 {
826 gl_type = "Pop";
827 }
828
829 // Translate message severity
830 const char* gl_severity = "Unknown Severity";
831 if ( severity == gl46core::GL_DEBUG_SEVERITY_HIGH )
832 {
833 gl_severity = "High";
834 }
835 else if ( severity == gl46core::GL_DEBUG_SEVERITY_MEDIUM )
836 {
837 gl_severity = "Medium";
838 }
839 else if ( severity == gl46core::GL_DEBUG_SEVERITY_LOW )
840 {
841 gl_severity = "Low";
842 }
843 else if ( severity == gl46core::GL_DEBUG_SEVERITY_NOTIFICATION )
844 {
845 gl_severity = "Info";
846 }
847
848 std::string fullScope = "GL";
849 for ( U8 i = 0u; i < GL_API::GetStateTracker()._debugScopeDepth; ++i )
850 {
851 fullScope.append( "::" );
852 fullScope.append( GL_API::GetStateTracker()._debugScope[i]._name );
853 }
854 // Print the message and the details
855 const gl46core::GLuint activeProgram = GL_API::GetStateTracker()._activeShaderProgramHandle;
856 const gl46core::GLuint activePipeline = GL_API::GetStateTracker()._activeShaderPipelineHandle;
857
858 const bool isPipeline = activeProgram == 0u;
859
860 const string outputError = Util::StringFormat<string>("[{} Thread][Source: {}][Type: {}][ID: {}][Severity: {}][Bound {} : {}][DebugGroup: {}][Message: {}]",
861 userParam == nullptr ? "Main" : "Worker",
862 gl_source,
863 gl_type,
864 id,
865 gl_severity,
866 isPipeline ? "Pipeline" : "Program",
867 isPipeline ? activePipeline : activeProgram,
868 fullScope,
869 message );
870
871 const bool isConsoleImmediate = Console::IsFlagSet( Console::Flags::PRINT_IMMEDIATE );
872 const bool severityDecoration = Console::IsFlagSet( Console::Flags::DECORATE_SEVERITY );
875
876 if ( severity == gl46core::GL_DEBUG_SEVERITY_NOTIFICATION )
877 {
878 Console::printfn( outputError.c_str() );
879 }
880 else if ( severity == gl46core::GL_DEBUG_SEVERITY_LOW || severity == gl46core::GL_DEBUG_SEVERITY_MEDIUM )
881 {
882 Console::warnfn( outputError.c_str() );
883 }
884 else
885 {
886 Console::errorfn( outputError.c_str() );
887 DIVIDE_ASSERT( GL_API::GetStateTracker()._assertOnAPIError && !(*GL_API::GetStateTracker()._assertOnAPIError), outputError.c_str());
888 }
891
892 }
893
894 } // namespace GLUtil
895
896} //namespace Divide
#define LOCALE_STR(X)
Definition: Localization.h:91
#define DIVIDE_ASSERT(...)
#define NO_DESTROY
#define DIVIDE_UNEXPECTED_CALL()
#define DIVIDE_UNEXPECTED_CALL_MSG(X)
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
static GLStateTracker & GetStateTracker() noexcept
Definition: GLWrapper.cpp:1749
eastl::fixed_vector< CacheEntry, InitialCacheSize, true > _cache
Definition: glResources.h:140
std::pair< gl46core::GLuint, bool > allocate(size_t hash, bool retry=false)
void deallocate(gl46core::GLuint handle, U32 frameDelay=1)
vector< gl46core::GLuint > _tempBuffer
Definition: glResources.h:132
vector< gl46core::GLuint > _handles
Definition: glResources.h:131
void init(U32 maxBindings) noexcept
Definition: glResources.cpp:27
const BufferBindingParams & bindingParams(gl46core::GLuint index)
Definition: glResources.cpp:54
bool instanceDivisorFlag(gl46core::GLuint index)
Definition: glResources.cpp:32
void * SDL_GLContext
Definition: glResources.h:39
std::array< gl46core::GLenum, to_base(QueryType::COUNT)> glQueryTypeTable
Definition: glResources.cpp:97
NO_DESTROY Mutex s_glSecondaryContextMutex
Definition: glResources.cpp:84
gl46core::GLuint s_lastQueryResult
Definition: glResources.cpp:80
std::array< gl46core::GLenum, to_base(StencilOperation::COUNT)> glStencilOpTable
Definition: glResources.cpp:89
std::array< gl46core::GLenum, to_base(PrimitiveTopology::COUNT)> glPrimitiveTypeTable
Definition: glResources.cpp:93
std::array< gl46core::GLenum, to_base(ShaderType::COUNT)> glShaderStageTable
Definition: glResources.cpp:96
std::array< gl46core::GLenum, to_base(BlendOperation::COUNT)> glBlendOpTable
Definition: glResources.cpp:87
thread_local SDL_GLContext s_glSecondaryContext
Definition: glResources.cpp:83
std::array< gl46core::GLenum, to_base(GFXDataFormat::COUNT)> glDataFormatTable
Definition: glResources.cpp:94
const DisplayWindow * s_glMainRenderWindow
Definition: glResources.cpp:82
void SubmitRenderCommand(const GenericDrawCommand &drawCommand, const gl46core::GLenum internalFormat)
Note: If internal format is not GL_NONE, an indexed draw is issued!
bool ValidateSDL(const I32 errCode, bool assert)
std::array< gl46core::GLenum, to_base(TextureWrap::COUNT)> glWrapTable
Definition: glResources.cpp:95
void OnStartup()
Populate enumeration tables with appropriate API values.
Definition: glResources.cpp:99
std::array< gl46core::GLenum, to_base(BlendProperty::COUNT)> glBlendTable
Definition: glResources.cpp:86
std::array< gl46core::GLenum, to_base(FillMode::COUNT)> glFillModeTable
Definition: glResources.cpp:91
gl46core::GLenum internalTextureType(const TextureType type, const U8 msaaSamples)
void DebugCallback(const gl46core::GLenum source, const gl46core::GLenum type, const gl46core::GLuint id, const gl46core::GLenum severity, const gl46core::GLsizei length, const gl46core::GLchar *message, const void *userParam)
Print OpenGL specific messages.
std::array< gl46core::GLenum, to_base(CullMode::COUNT)> glCullModeTable
Definition: glResources.cpp:90
std::array< gl46core::GLenum, to_base(TextureType::COUNT)> glTextureTypeTable
Definition: glResources.cpp:92
std::array< gl46core::GLenum, to_base(ComparisonFunction::COUNT)> glCompareFuncTable
Definition: glResources.cpp:88
FormatAndDataType InternalFormatAndDataType(const GFXImageFormat baseFormat, const GFXDataFormat dataType, const GFXImagePacking packing) noexcept
constexpr Optick::Category::Type Graphics
Definition: Profiler.h:60
static NO_DESTROY glVertexDataIndexContainer s_multiDrawIndexData
Definition: glResources.cpp:24
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
std::lock_guard< mutex > LockGuard
Definition: SharedMutex.h:55
constexpr U32 to_U32(const T value)
bool isEnabledOption(const GenericDrawCommand &cmd, CmdRenderOptions option) noexcept
std::mutex Mutex
Definition: SharedMutex.h:40
int32_t I32
uint8_t U8
@ INV
Bitwise inverts the current stencil buffer value.
@ COUNT
Place all properties above this.
@ ZERO
Sets the stencil buffer value to 0.
@ REPLACE
Sets the stencil buffer value to ref, as specified by StencilFunc.
@ KEEP
Keeps the current value.
@ DECR
Decrements the current stencil buffer value. Clamps to 0.
@ COUNT
Place all properties above this.
constexpr gl46core::GLuint GL_NULL_HANDLE
Invalid object value. Used to compare handles and determine if they were properly created.
Definition: glResources.h:105
@ COUNT
Place all properties above this.
eastl::vector< Type > vector
Definition: Vector.h:42
bool IsDepthTexture(GFXImagePacking packing) noexcept
@ NEQUAL
Passes if the incoming YYY value is not equal to the stored YYY value.
@ LESS
Passes if the incoming YYY value is less than the stored YYY value.
@ COUNT
Place all properties above this.
@ EQUAL
Passes if the incoming YYY value is equal to the stored YYY value.
@ GREATER
Passes if the incoming YYY value is greater than the stored YYY value.
@ WIREFRAME
Boundary edges of the polygon are drawn as line segments.
@ COUNT
Place all properties above this.
@ SOLID
The interior of the polygon is filled.
constexpr U8 to_U8(const T value)
constexpr U32 U32_MAX
@ BACK
Cull Back facing polygons (aka CW)
@ COUNT
Place all properties above this.
@ ALL
Cull All polygons.
@ FRONT
Cull Front facing polygons (aka CCW)
uint32_t U32
Project const SceneEntry & entry
Definition: DefaultScene.h:41
void * bufferPtr
constexpr auto to_base(const Type value) -> Type
static void ToggleFlag(const Flags flag, const bool state)
Definition: Console.h:135
static NO_INLINE void errorfn(const char *format, T &&... args)
static NO_INLINE void warnfn(const char *format, T &&... args)
static NO_INLINE void printfn(const char *format, T &&... args)
static bool IsFlagSet(const Flags flag)
Definition: Console.h:140
gl46core::GLuint _activeShaderPipelineHandle
gl46core::GLuint _activeShaderProgramHandle
DebugScope _debugScope[Config::MAX_DEBUG_SCOPE_DEPTH]
Definition: glResources.h:136
IndirectIndexedDrawCommand _cmd