summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/src/renderer_gl.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/src/renderer_gl.cpp')
-rw-r--r--3rdparty/bgfx/src/renderer_gl.cpp676
1 files changed, 497 insertions, 179 deletions
diff --git a/3rdparty/bgfx/src/renderer_gl.cpp b/3rdparty/bgfx/src/renderer_gl.cpp
index 4545f55756a..557614ef960 100644
--- a/3rdparty/bgfx/src/renderer_gl.cpp
+++ b/3rdparty/bgfx/src/renderer_gl.cpp
@@ -81,10 +81,11 @@ namespace bgfx { namespace gl
static const GLenum s_attribType[] =
{
- GL_UNSIGNED_BYTE,
- GL_SHORT,
- GL_HALF_FLOAT,
- GL_FLOAT,
+ GL_UNSIGNED_BYTE, // Uint8
+ GL_UNSIGNED_INT_10_10_10_2, // Uint10
+ GL_SHORT, // Int16
+ GL_HALF_FLOAT, // Half
+ GL_FLOAT, // Float
};
BX_STATIC_ASSERT(AttribType::Count == BX_COUNTOF(s_attribType) );
@@ -154,11 +155,12 @@ namespace bgfx { namespace gl
GL_BACK,
};
- static const GLenum s_textureAddress[] =
+ static GLenum s_textureAddress[] =
{
GL_REPEAT,
GL_MIRRORED_REPEAT,
GL_CLAMP_TO_EDGE,
+ GL_CLAMP_TO_BORDER,
};
static const GLenum s_textureFilterMag[] =
@@ -205,21 +207,44 @@ namespace bgfx { namespace gl
{ GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, GL_ZERO, GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, GL_ZERO, false }, // PTC24
{ GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO, false }, // Unknown
{ GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO, false }, // R1
+ { GL_ALPHA, GL_ZERO, GL_ALPHA, GL_UNSIGNED_BYTE, false }, // A8
{ GL_R8, GL_ZERO, GL_RED, GL_UNSIGNED_BYTE, false }, // R8
+ { GL_R8I, GL_ZERO, GL_RED, GL_BYTE, false }, // R8S
+ { GL_R8UI, GL_ZERO, GL_RED, GL_UNSIGNED_BYTE, false }, // R8S
+ { GL_R8_SNORM, GL_ZERO, GL_RED, GL_BYTE, false }, // R8S
{ GL_R16, GL_ZERO, GL_RED, GL_UNSIGNED_SHORT, false }, // R16
+ { GL_R16I, GL_ZERO, GL_RED, GL_SHORT, false }, // R16I
+ { GL_R16UI, GL_ZERO, GL_RED, GL_UNSIGNED_SHORT, false }, // R16U
{ GL_R16F, GL_ZERO, GL_RED, GL_HALF_FLOAT, false }, // R16F
- { GL_R32UI, GL_ZERO, GL_RED, GL_UNSIGNED_INT, false }, // R32
+ { GL_R16_SNORM, GL_ZERO, GL_RED, GL_SHORT, false }, // R16S
+ { GL_R32I, GL_ZERO, GL_RED, GL_INT, false }, // R32I
+ { GL_R32UI, GL_ZERO, GL_RED, GL_UNSIGNED_INT, false }, // R32U
{ GL_R32F, GL_ZERO, GL_RED, GL_FLOAT, false }, // R32F
{ GL_RG8, GL_ZERO, GL_RG, GL_UNSIGNED_BYTE, false }, // RG8
+ { GL_RG8I, GL_ZERO, GL_RG, GL_BYTE, false }, // RG8I
+ { GL_RG8UI, GL_ZERO, GL_RG, GL_UNSIGNED_BYTE, false }, // RG8U
+ { GL_RG8_SNORM, GL_ZERO, GL_RG, GL_BYTE, false }, // RG8S
{ GL_RG16, GL_ZERO, GL_RG, GL_UNSIGNED_SHORT, false }, // RG16
+ { GL_RG16I, GL_ZERO, GL_RG, GL_SHORT, false }, // RG16
+ { GL_RG16UI, GL_ZERO, GL_RG, GL_UNSIGNED_SHORT, false }, // RG16
{ GL_RG16F, GL_ZERO, GL_RG, GL_FLOAT, false }, // RG16F
- { GL_RG32UI, GL_ZERO, GL_RG, GL_UNSIGNED_INT, false }, // RG32
+ { GL_RG16_SNORM, GL_ZERO, GL_RG, GL_SHORT, false }, // RG16S
+ { GL_RG32I, GL_ZERO, GL_RG, GL_INT, false }, // RG32I
+ { GL_RG32UI, GL_ZERO, GL_RG, GL_UNSIGNED_INT, false }, // RG32U
{ GL_RG32F, GL_ZERO, GL_RG, GL_FLOAT, false }, // RG32F
+ { GL_RGB9_E5, GL_ZERO, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, false }, // RGB9E5F
{ GL_RGBA8, GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE, false }, // BGRA8
{ GL_RGBA8, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, false }, // RGBA8
- { GL_RGBA16, GL_ZERO, GL_RGBA, GL_UNSIGNED_BYTE, false }, // RGBA16
+ { GL_RGBA8I, GL_ZERO, GL_RGBA, GL_BYTE, false }, // RGBA8I
+ { GL_RGBA8UI, GL_ZERO, GL_RGBA, GL_UNSIGNED_BYTE, false }, // RGBA8U
+ { GL_RGBA8_SNORM, GL_ZERO, GL_RGBA, GL_BYTE, false }, // RGBA8S
+ { GL_RGBA16, GL_ZERO, GL_RGBA, GL_UNSIGNED_SHORT, false }, // RGBA16
+ { GL_RGBA16I, GL_ZERO, GL_RGBA, GL_SHORT, false }, // RGBA16I
+ { GL_RGBA16UI, GL_ZERO, GL_RGBA, GL_UNSIGNED_SHORT, false }, // RGBA16U
{ GL_RGBA16F, GL_ZERO, GL_RGBA, GL_HALF_FLOAT, false }, // RGBA16F
- { GL_RGBA32UI, GL_ZERO, GL_RGBA, GL_UNSIGNED_INT, false }, // RGBA32
+ { GL_RGBA16_SNORM, GL_ZERO, GL_RGBA, GL_SHORT, false }, // RGBA16S
+ { GL_RGBA32I, GL_ZERO, GL_RGBA, GL_INT, false }, // RGBA32I
+ { GL_RGBA32UI, GL_ZERO, GL_RGBA, GL_UNSIGNED_INT, false }, // RGBA32U
{ GL_RGBA32F, GL_ZERO, GL_RGBA, GL_FLOAT, false }, // RGBA32F
{ GL_RGB565, GL_ZERO, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, false }, // R5G6B5
{ GL_RGBA4, GL_ZERO, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, false }, // RGBA4
@@ -261,21 +286,44 @@ namespace bgfx { namespace gl
GL_ZERO, // PTC24
GL_ZERO, // Unknown
GL_ZERO, // R1
+ GL_ALPHA, // A8
GL_R8, // R8
+ GL_R8I, // R8I
+ GL_R8UI, // R8U
+ GL_R8_SNORM, // R8S
GL_R16, // R16
+ GL_R16I, // R16I
+ GL_R16UI, // R16U
GL_R16F, // R16F
- GL_R32UI, // R32
+ GL_R16_SNORM, // R16S
+ GL_R32I, // R32I
+ GL_R32UI, // R32U
GL_R32F, // R32F
GL_RG8, // RG8
+ GL_RG8I, // RG8I
+ GL_RG8UI, // RG8U
+ GL_RG8_SNORM, // RG8S
GL_RG16, // RG16
+ GL_RG16I, // RG16I
+ GL_RG16UI, // RG16U
GL_RG16F, // RG16F
- GL_RG32UI, // RG32
+ GL_RG16_SNORM, // RG16S
+ GL_RG32I, // RG32I
+ GL_RG32UI, // RG32U
GL_RG32F, // RG32F
+ GL_RGB9_E5, // RGB9E5F
GL_RGBA8, // BGRA8
GL_RGBA8, // RGBA8
+ GL_RGBA8I, // RGBA8I
+ GL_RGBA8UI, // RGBA8UI
+ GL_RGBA8_SNORM, // RGBA8S
GL_RGBA16, // RGBA16
+ GL_RGBA16I, // RGBA16I
+ GL_RGBA16UI, // RGBA16U
GL_RGBA16F, // RGBA16F
- GL_RGBA32UI, // RGBA32
+ GL_RGBA16_SNORM, // RGBA16S
+ GL_RGBA32I, // RGBA32I
+ GL_RGBA32UI, // RGBA32U
GL_RGBA32F, // RGBA32F
GL_RGB565, // R5G6B5
GL_RGBA4, // RGBA4
@@ -315,21 +363,44 @@ namespace bgfx { namespace gl
GL_ZERO, // PTC24
GL_ZERO, // Unknown
GL_ZERO, // R1
+ GL_ALPHA, // A8
GL_R8, // R8
+ GL_R8I, // R8I
+ GL_R8UI, // R8UI
+ GL_R8_SNORM, // R8S
GL_R16, // R16
+ GL_R16I, // R16I
+ GL_R16UI, // R16U
GL_R16F, // R16F
- GL_R32UI, // R32
+ GL_R16_SNORM, // R16S
+ GL_R32I, // R32I
+ GL_R32UI, // R32U
GL_R32F, // R32F
GL_RG8, // RG8
+ GL_RG8I, // RG8I
+ GL_RG8UI, // RG8U
+ GL_RG8_SNORM, // RG8S
GL_RG16, // RG16
+ GL_RG16I, // RG16I
+ GL_RG16UI, // RG16U
GL_RG16F, // RG16F
- GL_RG32UI, // RG32
+ GL_RG16_SNORM, // RG16S
+ GL_RG32I, // RG32I
+ GL_RG32UI, // RG32U
GL_RG32F, // RG32F
+ GL_RGB9_E5, // RGB9E5F
GL_RGBA8, // BGRA8
GL_RGBA8, // RGBA8
+ GL_RGBA8I, // RGBA8I
+ GL_RGBA8UI, // RGBA8UI
+ GL_RGBA8_SNORM, // RGBA8S
GL_RGBA16, // RGBA16
+ GL_RGBA16I, // RGBA16I
+ GL_RGBA16UI, // RGBA16U
GL_RGBA16F, // RGBA16F
- GL_RGBA32UI, // RGBA32
+ GL_RGBA16_SNORM, // RGBA16S
+ GL_RGBA32I, // RGBA32I
+ GL_RGBA32UI, // RGBA32U
GL_RGBA32F, // RGBA32F
GL_RGB565, // R5G6B5
GL_RGBA4, // RGBA4
@@ -384,6 +455,8 @@ namespace bgfx { namespace gl
ARB_half_float_pixel,
ARB_half_float_vertex,
ARB_instanced_arrays,
+ ARB_internalformat_query,
+ ARB_internalformat_query2,
ARB_invalidate_subdata,
ARB_map_buffer_range,
ARB_multi_draw_indirect,
@@ -452,6 +525,8 @@ namespace bgfx { namespace gl
EXT_texture_filter_anisotropic,
EXT_texture_format_BGRA8888,
EXT_texture_rg,
+ EXT_texture_shared_exponent,
+ EXT_texture_snorm,
EXT_texture_sRGB,
EXT_texture_storage,
EXT_texture_swizzle,
@@ -479,6 +554,7 @@ namespace bgfx { namespace gl
MOZ_WEBGL_compressed_texture_s3tc,
MOZ_WEBGL_depth_texture,
+ NV_texture_border_clamp,
NV_draw_buffers,
NVX_gpu_memory_info,
@@ -578,6 +654,8 @@ namespace bgfx { namespace gl
{ "ARB_half_float_pixel", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
{ "ARB_half_float_vertex", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
{ "ARB_instanced_arrays", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
+ { "ARB_internalformat_query", BGFX_CONFIG_RENDERER_OPENGL >= 42, true },
+ { "ARB_internalformat_query2", BGFX_CONFIG_RENDERER_OPENGL >= 43, true },
{ "ARB_invalidate_subdata", BGFX_CONFIG_RENDERER_OPENGL >= 43, true },
{ "ARB_map_buffer_range", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
{ "ARB_multi_draw_indirect", BGFX_CONFIG_RENDERER_OPENGL >= 43, true },
@@ -646,6 +724,8 @@ namespace bgfx { namespace gl
{ "EXT_texture_filter_anisotropic", false, true },
{ "EXT_texture_format_BGRA8888", false, true },
{ "EXT_texture_rg", false, true }, // GLES2 extension.
+ { "EXT_texture_shared_exponent", false, true },
+ { "EXT_texture_snorm", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
{ "EXT_texture_sRGB", false, true },
{ "EXT_texture_storage", false, true },
{ "EXT_texture_swizzle", false, true },
@@ -673,6 +753,7 @@ namespace bgfx { namespace gl
{ "MOZ_WEBGL_compressed_texture_s3tc", false, true },
{ "MOZ_WEBGL_depth_texture", false, true },
+ { "NV_texture_border_clamp", false, true }, // GLES2 extension.
{ "NV_draw_buffers", false, true }, // GLES2 extension.
{ "NVX_gpu_memory_info", false, true },
@@ -958,7 +1039,7 @@ namespace bgfx { namespace gl
;
GLsizei size = (16*16*getBitsPerPixel(_format) )/8;
- void* data = alloca(size);
+ void* data = bx::alignPtr(alloca(size+16), 0, 16);
if (isCompressed(_format) )
{
@@ -1005,17 +1086,20 @@ namespace bgfx { namespace gl
GLuint id;
GL_CHECK(glGenTextures(1, &id) );
GL_CHECK(glBindTexture(GL_TEXTURE_2D, id) );
- GL_CHECK(glTexStorage2D(GL_TEXTURE_2D, 1, s_imageFormat[_format], 16, 16) );
-
- glBindImageTexture(0
- , id
- , 0
- , GL_FALSE
- , 0
- , GL_READ_WRITE
- , s_imageFormat[_format]
- );
+ glTexStorage2D(GL_TEXTURE_2D, 1, s_imageFormat[_format], 16, 16);
GLenum err = glGetError();
+ if (0 == err)
+ {
+ glBindImageTexture(0
+ , id
+ , 0
+ , GL_FALSE
+ , 0
+ , GL_READ_WRITE
+ , s_imageFormat[_format]
+ );
+ err = glGetError();
+ }
GL_CHECK(glDeleteTextures(1, &id) );
@@ -1051,17 +1135,17 @@ namespace bgfx { namespace gl
if (isDepth(_format) )
{
const ImageBlockInfo& info = getBlockInfo(_format);
- if (0 < info.stencilBits)
+ if (0 == info.depthBits)
{
- attachment = GL_DEPTH_STENCIL_ATTACHMENT;
+ attachment = GL_STENCIL_ATTACHMENT;
}
- else if (0 == info.depthBits)
+ else if (0 == info.stencilBits)
{
- attachment = GL_STENCIL_ATTACHMENT;
+ attachment = GL_DEPTH_ATTACHMENT;
}
else
{
- attachment = GL_DEPTH_ATTACHMENT;
+ attachment = GL_DEPTH_STENCIL_ATTACHMENT;
}
}
else
@@ -1114,6 +1198,7 @@ namespace bgfx { namespace gl
, m_vaoSupport(false)
, m_samplerObjectSupport(false)
, m_shadowSamplersSupport(false)
+ , m_borderColorSupport(BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) )
, m_programBinarySupport(false)
, m_textureSwizzleSupport(false)
, m_depthTextureSupport(false)
@@ -1144,9 +1229,9 @@ namespace bgfx { namespace gl
// Must be after context is initialized?!
m_ovr.init();
- m_vendor = getGLString(GL_VENDOR);
- m_renderer = getGLString(GL_RENDERER);
- m_version = getGLString(GL_VERSION);
+ m_vendor = getGLString(GL_VENDOR);
+ m_renderer = getGLString(GL_RENDERER);
+ m_version = getGLString(GL_VERSION);
m_glslVersion = getGLString(GL_SHADING_LANGUAGE_VERSION);
GLint numCmpFormats = 0;
@@ -1198,6 +1283,8 @@ namespace bgfx { namespace gl
GL_GET(GL_MAX_TEXTURE_SIZE, 64);
GL_GET(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, 0);
GL_GET(GL_MAX_RENDERBUFFER_SIZE, 1);
+ GL_GET(GL_MAX_COLOR_ATTACHMENTS, 1);
+ GL_GET(GL_MAX_DRAW_BUFFERS, 1);
#undef GL_GET
BX_TRACE(" Vendor: %s", m_vendor);
@@ -1213,6 +1300,15 @@ namespace bgfx { namespace gl
^ (uint64_t(getGLStringHash(GL_VERSION ) )<<16)
;
+ if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 31)
+ && 0 == strcmp(m_vendor, "Imagination Technologies")
+ && NULL != strstr(m_version, "(SDK 3.5@3510720)") )
+ {
+ // Skip initializing extensions that are broken in emulator.
+ s_extension[Extension::ARB_program_interface_query ].m_initialize =
+ s_extension[Extension::ARB_shader_storage_buffer_object].m_initialize = false;
+ }
+
if (BX_ENABLED(BGFX_CONFIG_RENDERER_USE_EXTENSIONS) )
{
const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
@@ -1408,12 +1504,13 @@ namespace bgfx { namespace gl
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
|| BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 30) )
{
- setTextureFormat(TextureFormat::R16, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT);
- setTextureFormat(TextureFormat::RG16, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT);
- setTextureFormat(TextureFormat::RGBA16, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT);
- setTextureFormat(TextureFormat::R32, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT);
- setTextureFormat(TextureFormat::RG32, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT);
- setTextureFormat(TextureFormat::RGBA32, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
+ setTextureFormat(TextureFormat::R16I, GL_R16I, GL_RED_INTEGER, GL_SHORT);
+ setTextureFormat(TextureFormat::R16U, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT);
+// setTextureFormat(TextureFormat::RG16, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT);
+// setTextureFormat(TextureFormat::RGBA16, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT);
+ setTextureFormat(TextureFormat::R32U, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT);
+ setTextureFormat(TextureFormat::RG32U, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT);
+ setTextureFormat(TextureFormat::RGBA32U, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
}
if (s_extension[Extension::EXT_texture_format_BGRA8888 ].m_supported
@@ -1457,7 +1554,10 @@ namespace bgfx { namespace gl
s_textureFormat[TextureFormat::R8].m_fmt = GL_LUMINANCE;
}
- for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
+ for (uint32_t ii = BX_ENABLED(BX_PLATFORM_IOS) ? TextureFormat::Unknown : 0 // skip test on iOS!
+ ; ii < TextureFormat::Count
+ ; ++ii
+ )
{
if (TextureFormat::Unknown != ii
&& TextureFormat::UnknownDepth != ii)
@@ -1504,6 +1604,34 @@ namespace bgfx { namespace gl
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
+ if (NULL != glGetInternalformativ)
+ {
+ GLint maxSamples;
+ glGetInternalformativ(GL_RENDERBUFFER
+ , s_textureFormat[ii].m_internalFmt
+ , GL_SAMPLES
+ , 1
+ , &maxSamples
+ );
+ GLenum err = glGetError();
+ supported |= 0 == err && maxSamples > 0
+ ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA
+ : BGFX_CAPS_FORMAT_TEXTURE_NONE
+ ;
+
+ glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE
+ , s_textureFormat[ii].m_internalFmt
+ , GL_SAMPLES
+ , 1
+ , &maxSamples
+ );
+ err = glGetError();
+ supported |= 0 == err && maxSamples > 0
+ ? BGFX_CAPS_FORMAT_TEXTURE_MSAA
+ : BGFX_CAPS_FORMAT_TEXTURE_NONE
+ ;
+ }
+
g_caps.formats[ii] = supported;
}
@@ -1522,6 +1650,12 @@ namespace bgfx { namespace gl
? BGFX_CAPS_VERTEX_ATTRIB_HALF
: 0
;
+ g_caps.supported |= false
+ || s_extension[Extension::ARB_vertex_type_2_10_10_10_rev].m_supported
+ || s_extension[Extension::OES_vertex_type_10_10_10_2].m_supported
+ ? BGFX_CAPS_VERTEX_ATTRIB_UINT10
+ : 0
+ ;
g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 30)
|| s_extension[Extension::EXT_frag_depth].m_supported
? BGFX_CAPS_FRAGMENT_DEPTH
@@ -1570,7 +1704,9 @@ namespace bgfx { namespace gl
|| s_extension[Extension::EXT_draw_buffers ].m_supported
|| s_extension[Extension::WEBGL_draw_buffers].m_supported)
{
- g_caps.maxFBAttachments = uint8_t(bx::uint32_min(glGet(GL_MAX_COLOR_ATTACHMENTS), BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) );
+ g_caps.maxFBAttachments = uint8_t(bx::uint32_min(glGet(GL_MAX_DRAW_BUFFERS)
+ , BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS)
+ );
}
m_vaoSupport = !!(BGFX_CONFIG_RENDERER_OPENGLES >= 30)
@@ -1621,14 +1757,17 @@ namespace bgfx { namespace gl
|| s_extension[Extension::WEBKIT_WEBGL_depth_texture].m_supported
;
- m_timerQuerySupport = 0
+ m_timerQuerySupport = false
|| s_extension[Extension::ANGLE_timer_query ].m_supported
|| s_extension[Extension::ARB_timer_query ].m_supported
|| s_extension[Extension::EXT_disjoint_timer_query].m_supported
|| s_extension[Extension::EXT_timer_query ].m_supported
;
- m_timerQuerySupport &= NULL != glGetQueryObjectui64v;
+ m_timerQuerySupport &= true
+ && NULL != glGetQueryObjectiv
+ && NULL != glGetQueryObjectui64v
+ ;
g_caps.supported |= m_depthTextureSupport
? BGFX_CAPS_TEXTURE_COMPARE_LEQUAL
@@ -1640,10 +1779,16 @@ namespace bgfx { namespace gl
: 0
;
- g_caps.supported |= GlContext::isSwapChainSupported()
- ? BGFX_CAPS_SWAP_CHAIN
- : 0
- ;
+ g_caps.supported |= m_glctx.getCaps();
+
+ if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES) )
+ {
+ m_borderColorSupport = s_extension[Extension::NV_texture_border_clamp].m_supported;
+ s_textureAddress[BGFX_TEXTURE_U_BORDER>>BGFX_TEXTURE_U_SHIFT] = s_extension[Extension::NV_texture_border_clamp].m_supported
+ ? GL_CLAMP_TO_BORDER
+ : GL_CLAMP_TO_EDGE
+ ;
+ }
if (s_extension[Extension::EXT_texture_filter_anisotropic].m_supported)
{
@@ -1753,7 +1898,7 @@ namespace bgfx { namespace gl
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
&& m_timerQuerySupport)
{
- m_queries.create();
+ m_gpuTimer.create();
}
// Init reserved part of view name.
@@ -1784,7 +1929,7 @@ namespace bgfx { namespace gl
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
&& m_timerQuerySupport)
{
- m_queries.destroy();
+ m_gpuTimer.destroy();
}
destroyMsaaFbo();
@@ -2150,9 +2295,15 @@ namespace bgfx { namespace gl
m_resolution = _resolution;
m_resolution.m_flags = flags;
+ if ( (flags & BGFX_RESET_HMD)
+ && m_ovr.isInitialized() )
+ {
+ flags &= ~BGFX_RESET_MSAA_MASK;
+ }
+
setRenderContextSize(m_resolution.m_width
, m_resolution.m_height
- , m_resolution.m_flags
+ , flags
);
updateCapture();
@@ -2368,21 +2519,53 @@ namespace bgfx { namespace gl
}
}
- void setSamplerState(uint32_t _stage, uint32_t _numMips, uint32_t _flags)
+ void setSamplerState(uint32_t _stage, uint32_t _numMips, uint32_t _flags, const float _rgba[4])
{
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
|| BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 30) )
{
if (0 == (BGFX_SAMPLER_DEFAULT_FLAGS & _flags) )
{
+ const uint32_t index = (_flags & BGFX_TEXTURE_BORDER_COLOR_MASK) >> BGFX_TEXTURE_BORDER_COLOR_SHIFT;
+
_flags &= ~BGFX_TEXTURE_RESERVED_MASK;
_flags &= BGFX_TEXTURE_SAMPLER_BITS_MASK;
_flags |= _numMips<<BGFX_TEXTURE_RESERVED_SHIFT;
- GLuint sampler = m_samplerStateCache.find(_flags);
+
+ GLuint sampler;
+
+ bool hasBorderColor = false;
+ bx::HashMurmur2A murmur;
+ uint32_t hash;
+
+ murmur.begin();
+ murmur.add(_flags);
+ if (!needBorderColor(_flags) )
+ {
+ murmur.add(-1);
+ hash = murmur.end();
+
+ sampler = m_samplerStateCache.find(hash);
+ }
+ else
+ {
+ murmur.add(index);
+ hash = murmur.end();
+
+ if (NULL != _rgba)
+ {
+ hasBorderColor = true;
+ sampler = UINT32_MAX;
+ }
+ else
+ {
+ sampler = m_samplerStateCache.find(hash);
+ }
+ }
if (UINT32_MAX == sampler)
{
- sampler = m_samplerStateCache.add(_flags);
+ sampler = m_samplerStateCache.add(hash);
GL_CHECK(glSamplerParameteri(sampler
, GL_TEXTURE_WRAP_S
@@ -2403,6 +2586,15 @@ namespace bgfx { namespace gl
GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, magFilter) );
GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, minFilter) );
+ if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
+ || m_borderColorSupport)
+ {
+ if (hasBorderColor)
+ {
+ GL_CHECK(glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, _rgba) );
+ }
+ }
+
if (0 != (_flags & (BGFX_TEXTURE_MIN_ANISOTROPIC|BGFX_TEXTURE_MAG_ANISOTROPIC) )
&& 0.0f < m_maxAnisotropy)
{
@@ -2461,7 +2653,7 @@ namespace bgfx { namespace gl
bx::write(&writer, magic);
TextureCreate tc;
- tc.m_flags = BGFX_TEXTURE_RT;
+ tc.m_flags = BGFX_TEXTURE_RT|( ((m_resolution.m_flags & BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT) << BGFX_TEXTURE_RT_MSAA_SHIFT);;
tc.m_width = m_ovr.m_rtSize.w;
tc.m_height = m_ovr.m_rtSize.h;
tc.m_sides = 0;
@@ -2615,13 +2807,13 @@ namespace bgfx { namespace gl
}
}
- void commit(ConstantBuffer& _constantBuffer)
+ void commit(UniformBuffer& _uniformBuffer)
{
- _constantBuffer.reset();
+ _uniformBuffer.reset();
for (;;)
{
- uint32_t opcode = _constantBuffer.read();
+ uint32_t opcode = _uniformBuffer.read();
if (UniformType::End == opcode)
{
@@ -2632,21 +2824,21 @@ namespace bgfx { namespace gl
uint16_t ignore;
uint16_t num;
uint16_t copy;
- ConstantBuffer::decodeOpcode(opcode, type, ignore, num, copy);
+ UniformBuffer::decodeOpcode(opcode, type, ignore, num, copy);
const char* data;
if (copy)
{
- data = _constantBuffer.read(g_uniformTypeSize[type]*num);
+ data = _uniformBuffer.read(g_uniformTypeSize[type]*num);
}
else
{
UniformHandle handle;
- memcpy(&handle, _constantBuffer.read(sizeof(UniformHandle) ), sizeof(UniformHandle) );
+ memcpy(&handle, _uniformBuffer.read(sizeof(UniformHandle) ), sizeof(UniformHandle) );
data = (const char*)m_uniforms[handle.idx];
}
- uint32_t loc = _constantBuffer.read();
+ uint32_t loc = _uniformBuffer.read();
#define CASE_IMPLEMENT_UNIFORM(_uniform, _glsuffix, _dxsuffix, _type) \
case UniformType::_uniform: \
@@ -2666,29 +2858,24 @@ namespace bgfx { namespace gl
switch (type)
{
-// case ConstantType::Uniform1iv:
+// case ConstantType::Int1:
// {
// int* value = (int*)data;
-// BX_TRACE("Uniform1iv sampler %d, loc %d (num %d, copy %d)", *value, loc, num, copy);
+// BX_TRACE("Int1 sampler %d, loc %d (num %d, copy %d)", *value, loc, num, copy);
// GL_CHECK(glUniform1iv(loc, num, value) );
// }
// break;
- CASE_IMPLEMENT_UNIFORM(Uniform1i, 1iv, I, int);
- CASE_IMPLEMENT_UNIFORM(Uniform1f, 1fv, F, float);
- CASE_IMPLEMENT_UNIFORM(Uniform1iv, 1iv, I, int);
- CASE_IMPLEMENT_UNIFORM(Uniform1fv, 1fv, F, float);
- CASE_IMPLEMENT_UNIFORM(Uniform2fv, 2fv, F, float);
- CASE_IMPLEMENT_UNIFORM(Uniform3fv, 3fv, F, float);
- CASE_IMPLEMENT_UNIFORM(Uniform4fv, 4fv, F, float);
- CASE_IMPLEMENT_UNIFORM_T(Uniform3x3fv, Matrix3fv, F, float);
- CASE_IMPLEMENT_UNIFORM_T(Uniform4x4fv, Matrix4fv, F, float);
+ CASE_IMPLEMENT_UNIFORM(Int1, 1iv, I, int);
+ CASE_IMPLEMENT_UNIFORM(Vec4, 4fv, F, float);
+ CASE_IMPLEMENT_UNIFORM_T(Mat3, Matrix3fv, F, float);
+ CASE_IMPLEMENT_UNIFORM_T(Mat4, Matrix4fv, F, float);
case UniformType::End:
break;
default:
- BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _constantBuffer.getPos(), opcode, type, loc, num, copy);
+ BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy);
break;
}
@@ -2715,7 +2902,7 @@ namespace bgfx { namespace gl
{
if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags)
{
- uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_CLEAR_COLOR_PALETTE-1, _clear.m_index[0]);
+ uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[0]);
const float* rgba = _palette[index];
const float rr = rgba[0];
const float gg = rgba[1];
@@ -2808,7 +2995,7 @@ namespace bgfx { namespace gl
Vertex* vertex = (Vertex*)_clearQuad.m_vb->data;
BX_CHECK(vertexDecl.m_stride == sizeof(Vertex), "Stride/Vertex mismatch (stride %d, sizeof(Vertex) %d)", vertexDecl.m_stride, sizeof(Vertex) );
- const float depth = _clear.m_depth;
+ const float depth = _clear.m_depth * 2.0f - 1.0f;
vertex->m_x = -1.0f;
vertex->m_y = -1.0f;
@@ -2840,7 +3027,7 @@ namespace bgfx { namespace gl
float mrtClear[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS][4];
for (uint32_t ii = 0; ii < numMrt; ++ii)
{
- uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_CLEAR_COLOR_PALETTE-1, _clear.m_index[ii]);
+ uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[ii]);
memcpy(mrtClear[ii], _palette[index], 16);
}
@@ -2879,7 +3066,7 @@ namespace bgfx { namespace gl
FrameBufferGL m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS];
UniformRegistry m_uniformReg;
void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
- QueriesGL m_queries;
+ TimerQueryGL m_gpuTimer;
VaoStateCache m_vaoStateCache;
SamplerStateCache m_samplerStateCache;
@@ -2900,6 +3087,7 @@ namespace bgfx { namespace gl
bool m_vaoSupport;
bool m_samplerObjectSupport;
bool m_shadowSamplersSupport;
+ bool m_borderColorSupport;
bool m_programBinarySupport;
bool m_textureSwizzleSupport;
bool m_depthTextureSupport;
@@ -3033,28 +3221,22 @@ namespace bgfx { namespace gl
{
case GL_INT:
case GL_UNSIGNED_INT:
- return UniformType::Uniform1iv;
+ return UniformType::Int1;
case GL_FLOAT:
- return UniformType::Uniform1fv;
-
case GL_FLOAT_VEC2:
- return UniformType::Uniform2fv;
-
case GL_FLOAT_VEC3:
- return UniformType::Uniform3fv;
-
case GL_FLOAT_VEC4:
- return UniformType::Uniform4fv;
+ return UniformType::Vec4;
case GL_FLOAT_MAT2:
break;
case GL_FLOAT_MAT3:
- return UniformType::Uniform3x3fv;
+ return UniformType::Mat3;
case GL_FLOAT_MAT4:
- return UniformType::Uniform4x4fv;
+ return UniformType::Mat4;
case GL_SAMPLER_2D:
case GL_INT_SAMPLER_2D:
@@ -3085,7 +3267,7 @@ namespace bgfx { namespace gl
case GL_IMAGE_CUBE:
case GL_INT_IMAGE_CUBE:
case GL_UNSIGNED_INT_IMAGE_CUBE:
- return UniformType::Uniform1iv;
+ return UniformType::Int1;
};
BX_CHECK(false, "Unrecognized GL type 0x%04x.", _type);
@@ -3154,7 +3336,7 @@ namespace bgfx { namespace gl
{
if (NULL != m_constantBuffer)
{
- ConstantBuffer::destroy(m_constantBuffer);
+ UniformBuffer::destroy(m_constantBuffer);
m_constantBuffer = NULL;
}
m_numPredefined = 0;
@@ -3179,8 +3361,12 @@ namespace bgfx { namespace gl
GL_CHECK(glBindFragDataLocation(m_id, 0, "bgfx_FragColor") );
#endif // BGFX_CONFIG_RENDERER_OPENGL >= 31
- if (s_extension[Extension::ARB_program_interface_query].m_supported
- || BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 31) )
+ bool piqSupported = true
+ && s_extension[Extension::ARB_program_interface_query ].m_supported
+ && s_extension[Extension::ARB_shader_storage_buffer_object].m_supported
+ ;
+
+ if (piqSupported)
{
GL_CHECK(glGetProgramInterfaceiv(m_id, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &activeAttribs ) );
GL_CHECK(glGetProgramInterfaceiv(m_id, GL_UNIFORM, GL_ACTIVE_RESOURCES, &activeUniforms) );
@@ -3217,8 +3403,6 @@ namespace bgfx { namespace gl
m_numPredefined = 0;
m_numSamplers = 0;
- const bool piqSupported = s_extension[Extension::ARB_program_interface_query].m_supported;
-
BX_TRACE("Uniforms (%d):", activeUniforms);
for (int32_t ii = 0; ii < activeUniforms; ++ii)
{
@@ -3235,8 +3419,7 @@ namespace bgfx { namespace gl
GLint num;
GLint loc;
- if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 31)
- || piqSupported)
+ if (piqSupported)
{
GL_CHECK(glGetProgramResourceiv(m_id
, GL_UNIFORM
@@ -3334,11 +3517,13 @@ namespace bgfx { namespace gl
else
{
const UniformInfo* info = s_renderGL->m_uniformReg.find(name);
+ BX_WARN(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name);
+
if (NULL != info)
{
if (NULL == m_constantBuffer)
{
- m_constantBuffer = ConstantBuffer::create(1024);
+ m_constantBuffer = UniformBuffer::create(1024);
}
UniformType::Enum type = convertGlType(gltype);
@@ -3364,8 +3549,7 @@ namespace bgfx { namespace gl
m_constantBuffer->finish();
}
- if (s_extension[Extension::ARB_program_interface_query].m_supported
- || BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 31) )
+ if (piqSupported)
{
struct VariableInfo
{
@@ -3415,6 +3599,10 @@ namespace bgfx { namespace gl
m_used[used++] = ii;
}
}
+ BX_CHECK(used < BX_COUNTOF(m_used), "Out of bounds %d > array size %d."
+ , used
+ , BX_COUNTOF(m_used)
+ );
m_used[used] = Attrib::Count;
used = 0;
@@ -3427,6 +3615,10 @@ namespace bgfx { namespace gl
m_instanceData[used++] = loc;
}
}
+ BX_CHECK(used < BX_COUNTOF(m_instanceData), "Out of bounds %d > array size %d."
+ , used
+ , BX_COUNTOF(m_instanceData)
+ );
m_instanceData[used] = 0xffff;
}
@@ -3445,13 +3637,33 @@ namespace bgfx { namespace gl
if (-1 != loc)
{
- if (0xff != _vertexDecl.m_attributes[attr])
+ if (UINT16_MAX != _vertexDecl.m_attributes[attr])
{
GL_CHECK(glEnableVertexAttribArray(loc) );
GL_CHECK(glVertexAttribDivisor(loc, 0) );
uint32_t baseVertex = _baseVertex*_vertexDecl.m_stride + _vertexDecl.m_offset[attr];
- GL_CHECK(glVertexAttribPointer(loc, num, s_attribType[type], normalized, _vertexDecl.m_stride, (void*)(uintptr_t)baseVertex) );
+ if ( (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL >= 30) || BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 31) )
+ && (AttribType::Uint8 == type || AttribType::Int16 == type)
+ && !normalized)
+ {
+ GL_CHECK(glVertexAttribIPointer(loc
+ , num
+ , s_attribType[type]
+ , _vertexDecl.m_stride
+ , (void*)(uintptr_t)baseVertex)
+ );
+ }
+ else
+ {
+ GL_CHECK(glVertexAttribPointer(loc
+ , num
+ , s_attribType[type]
+ , normalized
+ , _vertexDecl.m_stride
+ , (void*)(uintptr_t)baseVertex)
+ );
+ }
}
else
{
@@ -3550,7 +3762,7 @@ namespace bgfx { namespace gl
m_width = _width;
m_height = _height;
m_depth = _depth;
- m_currentFlags = UINT32_MAX;
+ m_currentSamplerHash = UINT32_MAX;
m_requestedFormat = _format;
m_textureFormat = _format;
@@ -3610,7 +3822,7 @@ namespace bgfx { namespace gl
}
}
- setSamplerState(_flags);
+ setSamplerState(_flags, NULL);
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
&& TextureFormat::BGRA8 == m_requestedFormat
@@ -3987,7 +4199,7 @@ namespace bgfx { namespace gl
}
}
- void TextureGL::setSamplerState(uint32_t _flags)
+ void TextureGL::setSamplerState(uint32_t _flags, const float _rgba[4])
{
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES < 30)
&& !s_textureFilter[m_textureFormat])
@@ -4006,9 +4218,26 @@ namespace bgfx { namespace gl
}
const uint32_t flags = (0 != (BGFX_SAMPLER_DEFAULT_FLAGS & _flags) ? m_flags : _flags) & BGFX_TEXTURE_SAMPLER_BITS_MASK;
- if (flags != m_currentFlags)
+
+ bool hasBorderColor = false;
+ bx::HashMurmur2A murmur;
+ murmur.begin();
+ murmur.add(flags);
+ if (NULL != _rgba)
+ {
+ if (BGFX_TEXTURE_U_BORDER == (flags & BGFX_TEXTURE_U_BORDER)
+ || BGFX_TEXTURE_V_BORDER == (flags & BGFX_TEXTURE_V_BORDER)
+ || BGFX_TEXTURE_W_BORDER == (flags & BGFX_TEXTURE_W_BORDER) )
+ {
+ murmur.add(_rgba, 16);
+ hasBorderColor = true;
+ }
+ }
+ uint32_t hash = murmur.end();
+
+ if (hash != m_currentSamplerHash)
{
- const GLenum target = m_target;
+ const GLenum target = m_target;
const uint8_t numMips = m_numMips;
GL_CHECK(glTexParameteri(target, GL_TEXTURE_WRAP_S, s_textureAddress[(flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT]) );
@@ -4030,6 +4259,16 @@ namespace bgfx { namespace gl
getFilters(flags, 1 < numMips, magFilter, minFilter);
GL_CHECK(glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter) );
GL_CHECK(glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter) );
+
+ if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
+ || s_renderGL->m_borderColorSupport)
+ {
+ if (hasBorderColor)
+ {
+ GL_CHECK(glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, _rgba) );
+ }
+ }
+
if (0 != (flags & (BGFX_TEXTURE_MIN_ANISOTROPIC|BGFX_TEXTURE_MAG_ANISOTROPIC) )
&& 0.0f < s_renderGL->m_maxAnisotropy)
{
@@ -4051,12 +4290,18 @@ namespace bgfx { namespace gl
}
}
- m_currentFlags = flags;
+ m_currentSamplerHash = hash;
}
}
- void TextureGL::commit(uint32_t _stage, uint32_t _flags)
+ void TextureGL::commit(uint32_t _stage, uint32_t _flags, const float _palette[][4])
{
+ const uint32_t flags = 0 == (BGFX_SAMPLER_DEFAULT_FLAGS & _flags)
+ ? _flags
+ : m_flags
+ ;
+ const uint32_t index = (flags & BGFX_TEXTURE_BORDER_COLOR_MASK) >> BGFX_TEXTURE_BORDER_COLOR_SHIFT;
+
GL_CHECK(glActiveTexture(GL_TEXTURE0+_stage) );
GL_CHECK(glBindTexture(m_target, m_id) );
@@ -4064,7 +4309,7 @@ namespace bgfx { namespace gl
&& BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES < 30) )
{
// GLES2 doesn't have support for sampler object.
- setSamplerState(_flags);
+ setSamplerState(flags, _palette[index]);
}
else if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
&& BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL < 31) )
@@ -4072,17 +4317,17 @@ namespace bgfx { namespace gl
// In case that GL 2.1 sampler object is supported via extension.
if (s_renderGL->m_samplerObjectSupport)
{
- s_renderGL->setSamplerState(_stage, m_numMips, _flags);
+ s_renderGL->setSamplerState(_stage, m_numMips, flags, _palette[index]);
}
else
{
- setSamplerState(_flags);
+ setSamplerState(flags, _palette[index]);
}
}
else
{
// Everything else has sampler object.
- s_renderGL->setSamplerState(_stage, m_numMips, _flags);
+ s_renderGL->setSamplerState(_stage, m_numMips, flags, _palette[index]);
}
}
@@ -4275,7 +4520,8 @@ namespace bgfx { namespace gl
if (usesTextureLod)
{
BX_WARN(s_extension[Extension::EXT_shader_texture_lod].m_supported, "EXT_shader_texture_lod is used but not supported by GLES2 driver.");
- if (s_extension[Extension::EXT_shader_texture_lod].m_supported)
+ if (s_extension[Extension::EXT_shader_texture_lod].m_supported
+ /*&& GL_VERTEX_SHADER == m_type*/)
{
writeString(&writer
, "#extension GL_EXT_shader_texture_lod : enable\n"
@@ -4348,7 +4594,10 @@ namespace bgfx { namespace gl
bool usesIUsamplers = !!bx::findIdentifierMatch(code, s_uisamplers);
- uint32_t version = usesIUsamplers ? 130 : (usesTextureLod ? 120 : 0);
+ uint32_t version = usesIUsamplers
+ ? 130
+ : (usesTextureLod ? 120 : 0)
+ ;
if (0 != version)
{
@@ -4363,6 +4612,44 @@ namespace bgfx { namespace gl
}
}
+ if (130 <= version)
+ {
+ if (m_type == GL_FRAGMENT_SHADER)
+ {
+ writeString(&writer, "#define varying in\n");
+ }
+ else
+ {
+ writeString(&writer, "#define attribute in\n");
+ writeString(&writer, "#define varying out\n");
+ }
+
+ uint32_t fragData = 0;
+
+ if (!!bx::findIdentifierMatch(code, "gl_FragData") )
+ {
+ for (uint32_t ii = 0, num = g_caps.maxFBAttachments; ii < num; ++ii)
+ {
+ char tmpFragData[16];
+ bx::snprintf(tmpFragData, BX_COUNTOF(tmpFragData), "gl_FragData[%d]", ii);
+ fragData = bx::uint32_max(fragData, NULL == strstr(code, tmpFragData) ? 0 : ii+1);
+ }
+
+ BGFX_FATAL(0 != fragData, Fatal::InvalidShader, "Unable to find and patch gl_FragData!");
+ }
+
+ if (0 != fragData)
+ {
+ writeStringf(&writer, "out vec4 bgfx_FragData[%d];\n", fragData);
+ writeString(&writer, "#define gl_FragData bgfx_FragData\n");
+ }
+ else
+ {
+ writeString(&writer, "out vec4 bgfx_FragColor;\n");
+ writeString(&writer, "#define gl_FragColor bgfx_FragColor\n");
+ }
+ }
+
writeString(&writer
, "#define lowp\n"
"#define mediump\n"
@@ -4609,13 +4896,16 @@ namespace bgfx { namespace gl
m_num = uint8_t(colorIdx);
- if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) )
+ if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 31) )
{
if (0 == colorIdx)
{
- // When only depth is attached disable draw buffer to avoid
- // GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER.
- GL_CHECK(glDrawBuffer(GL_NONE) );
+ if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) )
+ {
+ // When only depth is attached disable draw buffer to avoid
+ // GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER.
+ GL_CHECK(glDrawBuffer(GL_NONE) );
+ }
}
else
{
@@ -4782,11 +5072,9 @@ namespace bgfx { namespace gl
int64_t elapsed = -bx::getHPCounter();
int64_t captureElapsed = 0;
- if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
- && (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
- && m_timerQuerySupport)
+ if (m_timerQuerySupport)
{
- m_queries.begin(0, GL_TIME_ELAPSED);
+ m_gpuTimer.begin();
}
if (0 < _render->m_iboffset)
@@ -4808,14 +5096,14 @@ namespace bgfx { namespace gl
currentState.m_flags = BGFX_STATE_NONE;
currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
- const bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();
- _render->m_hmdEnabled = hmdEnabled;
+ _render->m_hmdInitialized = m_ovr.isInitialized();
+ const bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();
ViewState viewState(_render, hmdEnabled);
uint16_t programIdx = invalidHandle;
SortKey key;
- uint8_t view = 0xff;
+ uint16_t view = UINT16_MAX;
FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
int32_t height = hmdEnabled
? _render->m_hmd.height
@@ -4879,7 +5167,7 @@ namespace bgfx { namespace gl
restartState = 2;
item = restartItem;
restartItem = numItems;
- view = 0xff;
+ view = UINT16_MAX;
continue;
}
@@ -4925,8 +5213,15 @@ namespace bgfx { namespace gl
GL_CHECK(glInsertEventMarker(0, viewName) );
}
- viewState.m_rect.m_x = eye * (viewState.m_rect.m_width+1)/2;
- viewState.m_rect.m_width /= 2;
+ if (m_ovr.isEnabled() )
+ {
+ m_ovr.getViewport(eye, &viewState.m_rect);
+ }
+ else
+ {
+ viewState.m_rect.m_x = eye * (viewState.m_rect.m_width+1)/2;
+ viewState.m_rect.m_width /= 2;
+ }
}
else
{
@@ -4954,7 +5249,7 @@ namespace bgfx { namespace gl
if (BGFX_CLEAR_NONE != (clear.m_flags & BGFX_CLEAR_MASK) )
{
- clearQuad(_clearQuad, viewState.m_rect, clear, height, _render->m_clearColor);
+ clearQuad(_clearQuad, viewState.m_rect, clear, height, _render->m_colorPalette);
}
GL_CHECK(glDisable(GL_STENCIL_TEST) );
@@ -5011,7 +5306,7 @@ namespace bgfx { namespace gl
case Binding::IndexBuffer:
{
const IndexBufferGL& buffer = m_indexBuffers[bind.m_idx];
- GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ii, buffer.m_id));
+ GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ii, buffer.m_id) );
barrier |= GL_SHADER_STORAGE_BARRIER_BIT;
}
break;
@@ -5019,7 +5314,7 @@ namespace bgfx { namespace gl
case Binding::VertexBuffer:
{
const VertexBufferGL& buffer = m_vertexBuffers[bind.m_idx];
- GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ii, buffer.m_id));
+ GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ii, buffer.m_id) );
barrier |= GL_SHADER_STORAGE_BARRIER_BIT;
}
break;
@@ -5030,7 +5325,7 @@ namespace bgfx { namespace gl
if (0 != barrier)
{
bool constantsChanged = compute.m_constBegin < compute.m_constEnd;
- rendererUpdateUniforms(this, _render->m_constantBuffer, compute.m_constBegin, compute.m_constEnd);
+ rendererUpdateUniforms(this, _render->m_uniformBuffer, compute.m_constBegin, compute.m_constEnd);
if (constantsChanged
&& NULL != program.m_constantBuffer)
@@ -5057,7 +5352,7 @@ namespace bgfx { namespace gl
uintptr_t args = compute.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
for (uint32_t ii = 0; ii < numDrawIndirect; ++ii)
{
- GL_CHECK(glDispatchComputeIndirect(args) );
+ GL_CHECK(glDispatchComputeIndirect((GLintptr)args) );
args += BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
}
}
@@ -5174,7 +5469,7 @@ namespace bgfx { namespace gl
GLint ref = (stencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
GLint mask = (stencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
uint32_t func = (stencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT;
- GL_CHECK(glStencilFuncSeparate(face, s_cmpFunc[func], ref, mask));
+ GL_CHECK(glStencilFuncSeparate(face, s_cmpFunc[func], ref, mask) );
}
if ( (BGFX_STENCIL_OP_FAIL_S_MASK|BGFX_STENCIL_OP_FAIL_Z_MASK|BGFX_STENCIL_OP_PASS_Z_MASK) & changed)
@@ -5294,7 +5589,7 @@ namespace bgfx { namespace gl
const uint32_t srcA = (blend>> 8)&0xf;
const uint32_t dstA = (blend>>12)&0xf;
- const uint32_t equ = uint32_t((newFlags&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT);
+ const uint32_t equ = uint32_t( (newFlags&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT);
const uint32_t equRGB = (equ )&0x7;
const uint32_t equA = (equ>>3)&0x7;
@@ -5386,7 +5681,7 @@ namespace bgfx { namespace gl
bool programChanged = false;
bool constantsChanged = draw.m_constBegin < draw.m_constEnd;
bool bindAttribs = false;
- rendererUpdateUniforms(this, _render->m_constantBuffer, draw.m_constBegin, draw.m_constEnd);
+ rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_constBegin, draw.m_constEnd);
if (key.m_program != programIdx)
{
@@ -5417,20 +5712,20 @@ namespace bgfx { namespace gl
{
for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage)
{
- const Binding& sampler = draw.m_bind[stage];
+ const Binding& bind = draw.m_bind[stage];
Binding& current = currentState.m_bind[stage];
- if (current.m_idx != sampler.m_idx
- || current.m_un.m_draw.m_flags != sampler.m_un.m_draw.m_flags
+ if (current.m_idx != bind.m_idx
+ || current.m_un.m_draw.m_flags != bind.m_un.m_draw.m_flags
|| programChanged)
{
- if (invalidHandle != sampler.m_idx)
+ if (invalidHandle != bind.m_idx)
{
- TextureGL& texture = m_textures[sampler.m_idx];
- texture.commit(stage, sampler.m_un.m_draw.m_flags);
+ TextureGL& texture = m_textures[bind.m_idx];
+ texture.commit(stage, bind.m_un.m_draw.m_flags, _render->m_colorPalette);
}
}
- current = sampler;
+ current = bind;
}
}
@@ -5664,6 +5959,7 @@ namespace bgfx { namespace gl
{
const IndexBufferGL& ib = m_indexBuffers[draw.m_indexBuffer.idx];
const bool hasIndex16 = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32);
+ const uint32_t indexSize = hasIndex16 ? 2 : 4;
const GLenum indexFormat = hasIndex16
? GL_UNSIGNED_SHORT
: GL_UNSIGNED_INT
@@ -5671,7 +5967,6 @@ namespace bgfx { namespace gl
if (UINT32_MAX == draw.m_numIndices)
{
- const uint32_t indexSize = hasIndex16 ? 2 : 4;
numIndices = ib.m_size/indexSize;
numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
numInstances = draw.m_numInstances;
@@ -5694,7 +5989,7 @@ namespace bgfx { namespace gl
GL_CHECK(glDrawElementsInstanced(prim.m_type
, numIndices
, indexFormat
- , (void*)(uintptr_t)(draw.m_startIndex*2)
+ , (void*)(uintptr_t)(draw.m_startIndex*indexSize)
, draw.m_numInstances
) );
}
@@ -5749,26 +6044,41 @@ namespace bgfx { namespace gl
min = min > frameTime ? frameTime : min;
max = max < frameTime ? frameTime : max;
- if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
+ static uint32_t maxGpuLatency = 0;
+ static double maxGpuElapsed = 0.0f;
+ double elapsedGpuMs = 0.0;
+ uint64_t elapsedGl = 0;
+
+ if (m_timerQuerySupport)
{
- double elapsedGpuMs = 0.0;
- uint64_t elapsedGl = 0;
- if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
- && m_timerQuerySupport)
+ m_gpuTimer.end();
+ while (m_gpuTimer.get() )
{
- m_queries.end(GL_TIME_ELAPSED);
- elapsedGl = m_queries.getResult(0);
- elapsedGpuMs = double(elapsedGl)/1e6;
+ elapsedGl = m_gpuTimer.m_elapsed;
+ elapsedGpuMs = double(elapsedGl)/1e6;
+ maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed;
}
+ maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1);
+ }
+
+ const int64_t timerFreq = bx::getHPFrequency();
+ Stats& perfStats = _render->m_perfStats;
+ perfStats.cpuTime = frameTime;
+ perfStats.cpuTimerFreq = timerFreq;
+ perfStats.gpuTime = elapsedGl;
+ perfStats.gpuTimerFreq = 1000000000;
+
+ if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
+ {
TextVideoMem& tvm = m_textVideoMem;
static int64_t next = now;
if (now >= next)
{
- next = now + bx::getHPFrequency();
- double freq = double(bx::getHPFrequency() );
+ next = now + timerFreq;
+ double freq = double(timerFreq);
double toMs = 1000.0/freq;
tvm.clear();
@@ -5776,10 +6086,14 @@ namespace bgfx { namespace gl
tvm.printf(0, pos++, BGFX_CONFIG_DEBUG ? 0x89 : 0x8f, " %s / " BX_COMPILER_NAME " / " BX_CPU_NAME " / " BX_ARCH_NAME " / " BX_PLATFORM_NAME " "
, getRendererName()
);
- tvm.printf(0, pos++, 0x0f, " Vendor: %s", m_vendor);
- tvm.printf(0, pos++, 0x0f, " Renderer: %s", m_renderer);
- tvm.printf(0, pos++, 0x0f, " Version: %s", m_version);
- tvm.printf(0, pos++, 0x0f, "GLSL version: %s", m_glslVersion);
+ tvm.printf(0, pos++, 0x8f, " Vendor: %s ", m_vendor);
+ tvm.printf(0, pos++, 0x8f, " Renderer: %s ", m_renderer);
+ tvm.printf(0, pos++, 0x8f, " Version: %s ", m_version);
+ tvm.printf(0, pos++, 0x8f, " GLSL version: %s ", m_glslVersion);
+
+ char processMemoryUsed[16];
+ bx::prettify(processMemoryUsed, BX_COUNTOF(processMemoryUsed), bx::getProcessMemoryUsed() );
+ tvm.printf(0, pos++, 0x8f, " Memory: %s (process) ", processMemoryUsed);
pos = 10;
tvm.printf(10, pos++, 0x8e, " Frame CPU: %7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS "
@@ -5802,18 +6116,21 @@ namespace bgfx { namespace gl
);
double elapsedCpuMs = double(elapsed)*toMs;
- tvm.printf(10, pos++, 0x8e, " Submitted: %4d (draw %4d, compute %4d) / CPU %3.4f [ms] %c GPU %3.4f [ms]"
+ tvm.printf(10, pos++, 0x8e, " Submitted: %5d (draw %5d, compute %4d) / CPU %7.4f [ms] %c GPU %7.4f [ms] (latency %d) "
, _render->m_num
, statsKeyType[0]
, statsKeyType[1]
, elapsedCpuMs
, elapsedCpuMs > elapsedGpuMs ? '>' : '<'
- , elapsedGpuMs
+ , maxGpuElapsed
+ , maxGpuLatency
);
+ maxGpuLatency = 0;
+ maxGpuElapsed = 0.0;
for (uint32_t ii = 0; ii < BX_COUNTOF(s_primInfo); ++ii)
{
- tvm.printf(10, pos++, 0x8e, " %9s: %7d (#inst: %5d), submitted: %7d"
+ tvm.printf(10, pos++, 0x8e, " %9s: %7d (#inst: %5d), submitted: %7d "
, s_primName[ii]
, statsNumPrimsRendered[ii]
, statsNumInstances[ii]
@@ -5826,9 +6143,10 @@ namespace bgfx { namespace gl
tvm.printf(tvm.m_width-27, 0, 0x1f, " [F11 - RenderDoc capture] ");
}
- tvm.printf(10, pos++, 0x8e, " Indices: %7d", statsNumIndices);
- tvm.printf(10, pos++, 0x8e, " DVB size: %7d", _render->m_vboffset);
- tvm.printf(10, pos++, 0x8e, " DIB size: %7d", _render->m_iboffset);
+ tvm.printf(10, pos++, 0x8e, " Indices: %7d ", statsNumIndices);
+ tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax);
+ tvm.printf(10, pos++, 0x8e, " DVB size: %7d ", _render->m_vboffset);
+ tvm.printf(10, pos++, 0x8e, " DIB size: %7d ", _render->m_iboffset);
pos++;
tvm.printf(10, pos++, 0x8e, " State cache: ");
@@ -5837,10 +6155,6 @@ namespace bgfx { namespace gl
, m_vaoStateCache.getCount()
, m_samplerStateCache.getCount()
);
- pos++;
-
- double captureMs = double(captureElapsed)*toMs;
- tvm.printf(10, pos++, 0x8e, " Capture: %3.4f [ms]", captureMs);
#if BGFX_CONFIG_RENDERER_OPENGL
if (s_extension[Extension::ATI_meminfo].m_supported)
@@ -5855,7 +6169,7 @@ namespace bgfx { namespace gl
GL_CHECK(glGetIntegerv(GL_RENDERBUFFER_FREE_MEMORY_ATI, rbfFree) );
pos++;
- tvm.printf(10, pos++, 0x8c, " -------------| free| free b| aux| aux fb");
+ tvm.printf(10, pos++, 0x8c, " -------------| free| free b| aux| aux fb ");
char tmp0[16];
char tmp1[16];
@@ -5866,19 +6180,19 @@ namespace bgfx { namespace gl
bx::prettify(tmp1, BX_COUNTOF(tmp1), vboFree[1]);
bx::prettify(tmp2, BX_COUNTOF(tmp2), vboFree[2]);
bx::prettify(tmp3, BX_COUNTOF(tmp3), vboFree[3]);
- tvm.printf(10, pos++, 0x8e, " VBO: %10s, %10s, %10s, %10s", tmp0, tmp1, tmp2, tmp3);
+ tvm.printf(10, pos++, 0x8e, " VBO: %10s, %10s, %10s, %10s ", tmp0, tmp1, tmp2, tmp3);
bx::prettify(tmp0, BX_COUNTOF(tmp0), texFree[0]);
bx::prettify(tmp1, BX_COUNTOF(tmp1), texFree[1]);
bx::prettify(tmp2, BX_COUNTOF(tmp2), texFree[2]);
bx::prettify(tmp3, BX_COUNTOF(tmp3), texFree[3]);
- tvm.printf(10, pos++, 0x8e, " Texture: %10s, %10s, %10s, %10s", tmp0, tmp1, tmp2, tmp3);
+ tvm.printf(10, pos++, 0x8e, " Texture: %10s, %10s, %10s, %10s ", tmp0, tmp1, tmp2, tmp3);
bx::prettify(tmp0, BX_COUNTOF(tmp0), rbfFree[0]);
bx::prettify(tmp1, BX_COUNTOF(tmp1), rbfFree[1]);
bx::prettify(tmp2, BX_COUNTOF(tmp2), rbfFree[2]);
bx::prettify(tmp3, BX_COUNTOF(tmp3), rbfFree[3]);
- tvm.printf(10, pos++, 0x8e, " Render Buffer: %10s, %10s, %10s, %10s", tmp0, tmp1, tmp2, tmp3);
+ tvm.printf(10, pos++, 0x8e, " Render Buffer: %10s, %10s, %10s, %10s ", tmp0, tmp1, tmp2, tmp3);
}
else if (s_extension[Extension::NVX_gpu_memory_info].m_supported)
{
@@ -5896,30 +6210,34 @@ namespace bgfx { namespace gl
GLint evictedMemory;
GL_CHECK(glGetIntegerv(GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX, &evictedMemory) );
- pos += 2;
+ pos++;
char tmp0[16];
char tmp1[16];
bx::prettify(tmp0, BX_COUNTOF(tmp0), dedicated);
- tvm.printf(10, pos++, 0x8e, " Dedicated: %10s", tmp0);
+ tvm.printf(10, pos++, 0x8e, " Dedicated: %10s ", tmp0);
bx::prettify(tmp0, BX_COUNTOF(tmp0), currAvail);
bx::prettify(tmp1, BX_COUNTOF(tmp1), totalAvail);
- tvm.printf(10, pos++, 0x8e, " Available: %10s / %10s", tmp0, tmp1);
+ tvm.printf(10, pos++, 0x8e, " Available: %10s / %10s ", tmp0, tmp1);
bx::prettify(tmp0, BX_COUNTOF(tmp0), evictedCount);
bx::prettify(tmp1, BX_COUNTOF(tmp1), evictedMemory);
- tvm.printf(10, pos++, 0x8e, " Eviction: %10s / %10s", tmp0, tmp1);
+ tvm.printf(10, pos++, 0x8e, " Eviction: %10s / %10s ", tmp0, tmp1);
}
#endif // BGFX_CONFIG_RENDERER_OPENGL
+ pos++;
+ double captureMs = double(captureElapsed)*toMs;
+ tvm.printf(10, pos++, 0x8e, " Capture: %7.4f [ms] ", captureMs);
+
uint8_t attr[2] = { 0x89, 0x8a };
uint8_t attrIndex = _render->m_waitSubmit < _render->m_waitRender;
pos++;
- tvm.printf(10, pos++, attr[attrIndex&1], "Submit wait: %3.4f [ms]", double(_render->m_waitSubmit)*toMs);
- tvm.printf(10, pos++, attr[(attrIndex+1)&1], "Render wait: %3.4f [ms]", double(_render->m_waitRender)*toMs);
+ tvm.printf(10, pos++, attr[attrIndex&1], " Submit wait: %7.4f [ms] ", double(_render->m_waitSubmit)*toMs);
+ tvm.printf(10, pos++, attr[(attrIndex+1)&1], " Render wait: %7.4f [ms] ", double(_render->m_waitRender)*toMs);
min = frameTime;
max = frameTime;