29 _maxBindings = maxBindings;
34 const size_t count =
_bindings.second.size();
48 const size_t count =
_bindings.second.size();
56 const size_t count =
_bindings.first.size();
70 const size_t count =
_bindings.first.size();
197 s_multiDrawIndexData.
_countData.resize(256, 0u);
226 "GLUtil::InternalFormatAndDataType: OpenGL only supports RGB(A)8 and BC1/2/3/7 for SRGB!" );
229 if ( isNormalized && !isDepth )
251 "GLUtil::InternalFormat: Vulkan only supports 8Bpp for BGR(A) format, so for now we completely ignore other data types." );
257 ret.
_dataType = gl46core::GL_UNSIGNED_SHORT_5_6_5;
261 ret._dataType = gl46core::GL_UNSIGNED_SHORT_4_4_4_4;
268 switch ( baseFormat )
274 ret._internalFormat = gl46core::GL_DEPTH_COMPONENT;
291 ret._internalFormat = gl46core::GL_DEPTH_COMPONENT;
308 ret._internalFormat = isNormalized ? gl46core::GL_RED : gl46core::GL_RED_INTEGER;
326 ret._internalFormat = isNormalized ? gl46core::GL_RG : gl46core::GL_RG_INTEGER;
344 ret._internalFormat = baseFormat ==
GFXImageFormat::RGB ? (isNormalized ? gl46core::GL_RGB : gl46core::GL_RGB_INTEGER) : (isNormalized ? gl46core::GL_BGR : gl46core::GL_BGR_INTEGER);
349 ret._format = gl46core::GL_RGB565;
355 case GFXDataFormat::UNSIGNED_BYTE : ret._format = isNormalized ? (isSRGB ? gl46core::GL_SRGB8 : gl46core::GL_RGB8) : gl46core::GL_RGB8UI;
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;
370 ret._internalFormat = baseFormat ==
GFXImageFormat::RGBA ? (isNormalized ? gl46core::GL_RGBA : gl46core::GL_RGBA_INTEGER) : (isNormalized ? gl46core::GL_BGRA : gl46core::GL_BGRA_INTEGER);
373 ret._format = gl46core::GL_RGBA4;
379 case GFXDataFormat::UNSIGNED_BYTE: ret._format = isNormalized ? (isSRGB ? gl46core::GL_SRGB8_ALPHA8 : gl46core::GL_RGBA8) : gl46core::GL_RGBA8UI;
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;
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;
409 DIVIDE_ASSERT(ret._format != gl46core::GL_NONE && ret._dataType != gl46core::GL_NONE,
"GLUtil::internalFormat: Unsupported texture and format combination!");
415 if ( msaaSamples > 0u )
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!" );
462 if ( internalFormat != gl46core::GL_NONE )
469 if ( useIndirectBuffer )
478 gl46core::glDrawElementsIndirect( primitiveType, internalFormat, (
bufferPtr)offset );
483 const bufferPtr offset = (
bufferPtr)(drawCommand.
_cmd.
firstIndex * (internalFormat == gl46core::GL_UNSIGNED_SHORT ?
sizeof( gl46core::GLushort ) :
sizeof( gl46core::GLuint )));
502 glMultiDrawElements( primitiveType, s_multiDrawIndexData.
_countData.data(), internalFormat, (
const void*
const*)s_multiDrawIndexData.
_indexOffsetData.data(), drawCommand.
_drawCount );
515 glDrawElements( primitiveType, drawCommand.
_cmd.
indexCount, internalFormat, offset );
549 if ( useIndirectBuffer )
558 gl46core::glDrawArraysIndirect( primitiveType, (
bufferPtr)offset );
605 gl46core::glGenTextures(
static_cast<gl46core::GLsizei
>(poolSize),
_handles.data() );
613 gl46core::GLuint count = 0u;
615 for (
U32 i = 0u; i < entryCount; ++i )
629 if ( lifeLeft == 0u )
637 gl46core::glDeleteTextures( count,
_tempBuffer.data() );
638 gl46core::glGenTextures( count,
_tempBuffer.data() );
641 for (
U32 i = 0u; i < entryCount; ++i )
649 return entry._idx == i;
653 memset(
_tempBuffer.data(), 0,
sizeof( gl46core::GLuint ) * count );
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 );
679 if ( hash != 0u && hash != SIZE_MAX)
684 if (
entry._hash == hash )
697 return std::make_pair(
_handles[idx],
true );
702 for (
U32 i = 0u; i < count; ++i )
708 _cache.emplace_back(hash, i);
710 return std::make_pair(
_handles[i],
false );
722 return std::make_pair( 0u,
false );
731 for (
U32 i = 0u; i < count; ++i )
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 )
758 if ( type == gl46core::GL_DEBUG_TYPE_OTHER && severity == gl46core::GL_DEBUG_SEVERITY_NOTIFICATION )
765 const char* gl_source =
"Unknown Source";
766 if ( source == gl46core::GL_DEBUG_SOURCE_API )
768 gl_source =
"OpenGL";
770 else if ( source == gl46core::GL_DEBUG_SOURCE_WINDOW_SYSTEM )
772 gl_source =
"Windows";
774 else if ( source == gl46core::GL_DEBUG_SOURCE_SHADER_COMPILER )
776 gl_source =
"Shader Compiler";
778 else if ( source == gl46core::GL_DEBUG_SOURCE_THIRD_PARTY )
780 gl_source =
"Third Party";
782 else if ( source == gl46core::GL_DEBUG_SOURCE_APPLICATION )
784 gl_source =
"Application";
786 else if ( source == gl46core::GL_DEBUG_SOURCE_OTHER )
791 const char* gl_type =
"Unknown Type";
792 if ( type == gl46core::GL_DEBUG_TYPE_ERROR )
796 else if ( type == gl46core::GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR )
798 gl_type =
"Deprecated behavior";
800 else if ( type == gl46core::GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR )
802 gl_type =
"Undefined behavior";
804 else if ( type == gl46core::GL_DEBUG_TYPE_PORTABILITY )
806 gl_type =
"Portability";
808 else if ( type == gl46core::GL_DEBUG_TYPE_PERFORMANCE )
810 gl_type =
"Performance";
812 else if ( type == gl46core::GL_DEBUG_TYPE_OTHER )
816 else if ( type == gl46core::GL_DEBUG_TYPE_MARKER )
820 else if ( type == gl46core::GL_DEBUG_TYPE_PUSH_GROUP )
824 else if ( type == gl46core::GL_DEBUG_TYPE_POP_GROUP )
830 const char* gl_severity =
"Unknown Severity";
831 if ( severity == gl46core::GL_DEBUG_SEVERITY_HIGH )
833 gl_severity =
"High";
835 else if ( severity == gl46core::GL_DEBUG_SEVERITY_MEDIUM )
837 gl_severity =
"Medium";
839 else if ( severity == gl46core::GL_DEBUG_SEVERITY_LOW )
843 else if ( severity == gl46core::GL_DEBUG_SEVERITY_NOTIFICATION )
845 gl_severity =
"Info";
848 std::string fullScope =
"GL";
851 fullScope.append(
"::" );
858 const bool isPipeline = activeProgram == 0u;
860 const string outputError = Util::StringFormat<string>(
"[{} Thread][Source: {}][Type: {}][ID: {}][Severity: {}][Bound {} : {}][DebugGroup: {}][Message: {}]",
861 userParam ==
nullptr ?
"Main" :
"Worker",
866 isPipeline ?
"Pipeline" :
"Program",
867 isPipeline ? activePipeline : activeProgram,
876 if ( severity == gl46core::GL_DEBUG_SEVERITY_NOTIFICATION )
880 else if ( severity == gl46core::GL_DEBUG_SEVERITY_LOW || severity == gl46core::GL_DEBUG_SEVERITY_MEDIUM )
#define PROFILE_SCOPE_AUTO(CATEGORY)
static GLStateTracker & GetStateTracker() noexcept
vector< State > _usageMap
eastl::fixed_vector< CacheEntry, InitialCacheSize, true > _cache
std::pair< gl46core::GLuint, bool > allocate(size_t hash, bool retry=false)
void deallocate(gl46core::GLuint handle, U32 frameDelay=1)
vector< gl46core::GLuint > _tempBuffer
vector< gl46core::GLuint > _handles
void init(U32 maxBindings) noexcept
const BufferBindingParams & bindingParams(gl46core::GLuint index)
bool instanceDivisorFlag(gl46core::GLuint index)
std::array< gl46core::GLenum, to_base(QueryType::COUNT)> glQueryTypeTable
NO_DESTROY Mutex s_glSecondaryContextMutex
gl46core::GLuint s_lastQueryResult
std::array< gl46core::GLenum, to_base(StencilOperation::COUNT)> glStencilOpTable
std::array< gl46core::GLenum, to_base(PrimitiveTopology::COUNT)> glPrimitiveTypeTable
std::array< gl46core::GLenum, to_base(ShaderType::COUNT)> glShaderStageTable
std::array< gl46core::GLenum, to_base(BlendOperation::COUNT)> glBlendOpTable
thread_local SDL_GLContext s_glSecondaryContext
std::array< gl46core::GLenum, to_base(GFXDataFormat::COUNT)> glDataFormatTable
const DisplayWindow * s_glMainRenderWindow
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
void OnStartup()
Populate enumeration tables with appropriate API values.
std::array< gl46core::GLenum, to_base(BlendProperty::COUNT)> glBlendTable
std::array< gl46core::GLenum, to_base(FillMode::COUNT)> glFillModeTable
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
std::array< gl46core::GLenum, to_base(TextureType::COUNT)> glTextureTypeTable
std::array< gl46core::GLenum, to_base(ComparisonFunction::COUNT)> glCompareFuncTable
FormatAndDataType InternalFormatAndDataType(const GFXImageFormat baseFormat, const GFXDataFormat dataType, const GFXImagePacking packing) noexcept
constexpr Optick::Category::Type Graphics
static NO_DESTROY glVertexDataIndexContainer s_multiDrawIndexData
Handle console commands that start with a forward slash.
std::lock_guard< mutex > LockGuard
constexpr U32 to_U32(const T value)
bool isEnabledOption(const GenericDrawCommand &cmd, CmdRenderOptions option) noexcept
@ TRIANGLE_STRIP_ADJACENCY
@ 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.
@ COUNT
Place all properties above this.
eastl::vector< Type > vector
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.
@ TESSELLATION_EVAL_INVOCATIONS
@ 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)
@ BACK
Cull Back facing polygons (aka CW)
@ COUNT
Place all properties above this.
@ FRONT
Cull Front facing polygons (aka CCW)
Project const SceneEntry & entry
constexpr auto to_base(const Type value) -> Type
static void ToggleFlag(const Flags flag, const bool state)
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)
size_t _drawIndirectBufferOffset
gl46core::GLuint _activeShaderPipelineHandle
gl46core::GLuint _activeShaderProgramHandle
DebugScope _debugScope[Config::MAX_DEBUG_SCOPE_DEPTH]
IndirectIndexedDrawCommand _cmd
vector< gl46core::GLsizei > _countData
vector< gl46core::GLint > _baseVertexData
vector< gl46core::GLuint > _indexOffsetData