diff options
Diffstat (limited to '3rdparty/bgfx/src/renderer_gl.cpp')
-rw-r--r-- | 3rdparty/bgfx/src/renderer_gl.cpp | 676 |
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; |