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.cpp698
1 files changed, 525 insertions, 173 deletions
diff --git a/3rdparty/bgfx/src/renderer_gl.cpp b/3rdparty/bgfx/src/renderer_gl.cpp
index 38875bbd2d7..4545f55756a 100644
--- a/3rdparty/bgfx/src/renderer_gl.cpp
+++ b/3rdparty/bgfx/src/renderer_gl.cpp
@@ -178,6 +178,7 @@ namespace bgfx { namespace gl
struct TextureFormatInfo
{
GLenum m_internalFmt;
+ GLenum m_internalFmtSrgb;
GLenum m_fmt;
GLenum m_type;
bool m_supported;
@@ -185,55 +186,55 @@ namespace bgfx { namespace gl
static TextureFormatInfo s_textureFormat[] =
{
- { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_ZERO, false }, // BC1
- { GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_ZERO, false }, // BC2
- { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_ZERO, false }, // BC3
- { GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_ZERO, false }, // BC4
- { GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_ZERO, false }, // BC5
- { GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, GL_ZERO, false }, // BC6H
- { GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_ZERO, false }, // BC7
- { GL_ETC1_RGB8_OES, GL_ETC1_RGB8_OES, GL_ZERO, false }, // ETC1
- { GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, GL_ZERO, false }, // ETC2
- { GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_ZERO, false }, // ETC2A
- { GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_ZERO, false }, // ETC2A1
- { GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, GL_ZERO, false }, // PTC12
- { GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_ZERO, false }, // PTC14
- { GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_ZERO, false }, // PTC12A
- { GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_ZERO, false }, // PTC14A
- { GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, GL_ZERO, false }, // PTC22
- { GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, GL_ZERO, false }, // PTC24
- { GL_ZERO, GL_ZERO, GL_ZERO, false }, // Unknown
- { GL_ZERO, GL_ZERO, GL_ZERO, false }, // R1
- { GL_R8, GL_RED, GL_UNSIGNED_BYTE, false }, // R8
- { GL_R16, GL_RED, GL_UNSIGNED_SHORT, false }, // R16
- { GL_R16F, GL_RED, GL_HALF_FLOAT, false }, // R16F
- { GL_R32UI, GL_RED, GL_UNSIGNED_INT, false }, // R32
- { GL_R32F, GL_RED, GL_FLOAT, false }, // R32F
- { GL_RG8, GL_RG, GL_UNSIGNED_BYTE, false }, // RG8
- { GL_RG16, GL_RG, GL_UNSIGNED_SHORT, false }, // RG16
- { GL_RG16F, GL_RG, GL_FLOAT, false }, // RG16F
- { GL_RG32UI, GL_RG, GL_UNSIGNED_INT, false }, // RG32
- { GL_RG32F, GL_RG, GL_FLOAT, false }, // RG32F
- { GL_RGBA, GL_BGRA, GL_UNSIGNED_BYTE, false }, // BGRA8
- { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, false }, // RGBA8
- { GL_RGBA16, GL_RGBA, GL_UNSIGNED_BYTE, false }, // RGBA16
- { GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, false }, // RGBA16F
- { GL_RGBA32UI, GL_RGBA, GL_UNSIGNED_INT, false }, // RGBA32
- { GL_RGBA32F, GL_RGBA, GL_FLOAT, false }, // RGBA32F
- { GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, false }, // R5G6B5
- { GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, false }, // RGBA4
- { GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, false }, // RGB5A1
- { GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false }, // RGB10A2
- { GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, false }, // R11G11B10F
- { GL_ZERO, GL_ZERO, GL_ZERO, false }, // UnknownDepth
- { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, false }, // D16
- { GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, false }, // D24
- { GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, false }, // D24S8
- { GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, false }, // D32
- { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, false }, // D16F
- { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, false }, // D24F
- { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, false }, // D32F
- { GL_STENCIL_INDEX8, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, false }, // D0S8
+ { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_ZERO, false }, // BC1
+ { GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_ZERO, false }, // BC2
+ { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_ZERO, false }, // BC3
+ { GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_ZERO, GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_ZERO, false }, // BC4
+ { GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_ZERO, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_ZERO, false }, // BC5
+ { GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, GL_ZERO, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, GL_ZERO, false }, // BC6H
+ { GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_ZERO, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_ZERO, false }, // BC7
+ { GL_ETC1_RGB8_OES, GL_ZERO, GL_ETC1_RGB8_OES, GL_ZERO, false }, // ETC1
+ { GL_COMPRESSED_RGB8_ETC2, GL_ZERO, GL_COMPRESSED_RGB8_ETC2, GL_ZERO, false }, // ETC2
+ { GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_ZERO, false }, // ETC2A
+ { GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_ZERO, false }, // ETC2A1
+ { GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, GL_ZERO, false }, // PTC12
+ { GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_ZERO, false }, // PTC14
+ { GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_ZERO, false }, // PTC12A
+ { GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_ZERO, false }, // PTC14A
+ { GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, GL_ZERO, GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, GL_ZERO, false }, // PTC22
+ { 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_R8, GL_ZERO, GL_RED, GL_UNSIGNED_BYTE, false }, // R8
+ { GL_R16, GL_ZERO, GL_RED, GL_UNSIGNED_SHORT, false }, // R16
+ { GL_R16F, GL_ZERO, GL_RED, GL_HALF_FLOAT, false }, // R16F
+ { GL_R32UI, GL_ZERO, GL_RED, GL_UNSIGNED_INT, false }, // R32
+ { GL_R32F, GL_ZERO, GL_RED, GL_FLOAT, false }, // R32F
+ { GL_RG8, GL_ZERO, GL_RG, GL_UNSIGNED_BYTE, false }, // RG8
+ { GL_RG16, 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_RG32F, GL_ZERO, GL_RG, GL_FLOAT, false }, // RG32F
+ { 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_RGBA16F, GL_ZERO, GL_RGBA, GL_HALF_FLOAT, false }, // RGBA16F
+ { GL_RGBA32UI, GL_ZERO, GL_RGBA, GL_UNSIGNED_INT, false }, // RGBA32
+ { 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
+ { GL_RGB5_A1, GL_ZERO, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, false }, // RGB5A1
+ { GL_RGB10_A2, GL_ZERO, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false }, // RGB10A2
+ { GL_R11F_G11F_B10F, GL_ZERO, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, false }, // R11G11B10F
+ { GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO, false }, // UnknownDepth
+ { GL_DEPTH_COMPONENT16, GL_ZERO, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, false }, // D16
+ { GL_DEPTH_COMPONENT24, GL_ZERO, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, false }, // D24
+ { GL_DEPTH24_STENCIL8, GL_ZERO, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, false }, // D24S8
+ { GL_DEPTH_COMPONENT32, GL_ZERO, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, false }, // D32
+ { GL_DEPTH_COMPONENT32F, GL_ZERO, GL_DEPTH_COMPONENT, GL_FLOAT, false }, // D16F
+ { GL_DEPTH_COMPONENT32F, GL_ZERO, GL_DEPTH_COMPONENT, GL_FLOAT, false }, // D24F
+ { GL_DEPTH_COMPONENT32F, GL_ZERO, GL_DEPTH_COMPONENT, GL_FLOAT, false }, // D32F
+ { GL_STENCIL_INDEX8, GL_ZERO, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, false }, // D0S8
};
BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat) );
@@ -352,6 +353,7 @@ namespace bgfx { namespace gl
enum Enum
{
AMD_conservative_depth,
+ AMD_multi_draw_indirect,
ANGLE_depth_texture,
ANGLE_framebuffer_blit,
@@ -373,6 +375,7 @@ namespace bgfx { namespace gl
ARB_depth_buffer_float,
ARB_depth_clamp,
ARB_draw_buffers_blend,
+ ARB_draw_indirect,
ARB_draw_instanced,
ARB_ES3_compatibility,
ARB_framebuffer_object,
@@ -383,6 +386,7 @@ namespace bgfx { namespace gl
ARB_instanced_arrays,
ARB_invalidate_subdata,
ARB_map_buffer_range,
+ ARB_multi_draw_indirect,
ARB_multisample,
ARB_occlusion_query,
ARB_occlusion_query2,
@@ -425,6 +429,7 @@ namespace bgfx { namespace gl
EXT_compressed_ETC1_RGB8_sub_texture,
EXT_debug_label,
EXT_debug_marker,
+ EXT_debug_tool,
EXT_discard_framebuffer,
EXT_disjoint_timer_query,
EXT_draw_buffers,
@@ -432,6 +437,7 @@ namespace bgfx { namespace gl
EXT_framebuffer_blit,
EXT_framebuffer_object,
EXT_framebuffer_sRGB,
+ EXT_multi_draw_indirect,
EXT_occlusion_query_boolean,
EXT_packed_float,
EXT_read_format_bgra,
@@ -468,6 +474,7 @@ namespace bgfx { namespace gl
INTEL_fragment_shader_ordering,
KHR_debug,
+ KHR_no_error,
MOZ_WEBGL_compressed_texture_s3tc,
MOZ_WEBGL_depth_texture,
@@ -540,6 +547,7 @@ namespace bgfx { namespace gl
static Extension s_extension[] =
{
{ "AMD_conservative_depth", false, true },
+ { "AMD_multi_draw_indirect", false, true },
{ "ANGLE_depth_texture", false, true },
{ "ANGLE_framebuffer_blit", false, true },
@@ -561,6 +569,7 @@ namespace bgfx { namespace gl
{ "ARB_depth_buffer_float", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
{ "ARB_depth_clamp", BGFX_CONFIG_RENDERER_OPENGL >= 32, true },
{ "ARB_draw_buffers_blend", BGFX_CONFIG_RENDERER_OPENGL >= 40, true },
+ { "ARB_draw_indirect", BGFX_CONFIG_RENDERER_OPENGL >= 40, true },
{ "ARB_draw_instanced", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
{ "ARB_ES3_compatibility", BGFX_CONFIG_RENDERER_OPENGL >= 43, true },
{ "ARB_framebuffer_object", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
@@ -571,6 +580,7 @@ namespace bgfx { namespace gl
{ "ARB_instanced_arrays", BGFX_CONFIG_RENDERER_OPENGL >= 33, 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 },
{ "ARB_multisample", false, true },
{ "ARB_occlusion_query", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
{ "ARB_occlusion_query2", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
@@ -613,6 +623,7 @@ namespace bgfx { namespace gl
{ "EXT_compressed_ETC1_RGB8_sub_texture", false, true }, // GLES2 extension.
{ "EXT_debug_label", false, true },
{ "EXT_debug_marker", false, true },
+ { "EXT_debug_tool", false, true }, // RenderDoc extension.
{ "EXT_discard_framebuffer", false, true }, // GLES2 extension.
{ "EXT_disjoint_timer_query", false, true }, // GLES2 extension.
{ "EXT_draw_buffers", false, true }, // GLES2 extension.
@@ -620,6 +631,7 @@ namespace bgfx { namespace gl
{ "EXT_framebuffer_blit", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
{ "EXT_framebuffer_object", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
{ "EXT_framebuffer_sRGB", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
+ { "EXT_multi_draw_indirect", false, true }, // GLES3.1 extension.
{ "EXT_occlusion_query_boolean", false, true },
{ "EXT_packed_float", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
{ "EXT_read_format_bgra", false, true },
@@ -656,6 +668,7 @@ namespace bgfx { namespace gl
{ "INTEL_fragment_shader_ordering", false, true },
{ "KHR_debug", BGFX_CONFIG_RENDERER_OPENGL >= 43, true },
+ { "KHR_no_error", false, true },
{ "MOZ_WEBGL_compressed_texture_s3tc", false, true },
{ "MOZ_WEBGL_depth_texture", false, true },
@@ -805,6 +818,26 @@ namespace bgfx { namespace gl
{
}
+ static void GL_APIENTRY stubMultiDrawArraysIndirect(GLenum _mode, const void* _indirect, GLsizei _drawcount, GLsizei _stride)
+ {
+ const uint8_t* args = (const uint8_t*)_indirect;
+ for (GLsizei ii = 0; ii < _drawcount; ++ii)
+ {
+ GL_CHECK(glDrawArraysIndirect(_mode, (void*)args) );
+ args += _stride;
+ }
+ }
+
+ static void GL_APIENTRY stubMultiDrawElementsIndirect(GLenum _mode, GLenum _type, const void* _indirect, GLsizei _drawcount, GLsizei _stride)
+ {
+ const uint8_t* args = (const uint8_t*)_indirect;
+ for (GLsizei ii = 0; ii < _drawcount; ++ii)
+ {
+ GL_CHECK(glDrawElementsIndirect(_mode, _type, (void*)args) );
+ args += _stride;
+ }
+ }
+
typedef void (*PostSwapBuffersFn)(uint32_t _width, uint32_t _height);
static const char* getGLString(GLenum _name)
@@ -863,30 +896,26 @@ namespace bgfx { namespace gl
const char* toString(GLenum _enum)
{
-#if defined(GL_DEBUG_SOURCE_API_ARB)
switch (_enum)
{
- case GL_DEBUG_SOURCE_API_ARB: return "API";
- case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: return "WinSys";
- case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: return "Shader";
- case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: return "3rdparty";
- case GL_DEBUG_SOURCE_APPLICATION_ARB: return "Application";
- case GL_DEBUG_SOURCE_OTHER_ARB: return "Other";
- case GL_DEBUG_TYPE_ERROR_ARB: return "Error";
- case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: return "Deprecated behavior";
- case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: return "Undefined behavior";
- case GL_DEBUG_TYPE_PORTABILITY_ARB: return "Portability";
- case GL_DEBUG_TYPE_PERFORMANCE_ARB: return "Performance";
- case GL_DEBUG_TYPE_OTHER_ARB: return "Other";
- case GL_DEBUG_SEVERITY_HIGH_ARB: return "High";
- case GL_DEBUG_SEVERITY_MEDIUM_ARB: return "Medium";
- case GL_DEBUG_SEVERITY_LOW_ARB: return "Low";
+ case GL_DEBUG_SOURCE_API: return "API";
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM: return "WinSys";
+ case GL_DEBUG_SOURCE_SHADER_COMPILER: return "Shader";
+ case GL_DEBUG_SOURCE_THIRD_PARTY: return "3rdparty";
+ case GL_DEBUG_SOURCE_APPLICATION: return "Application";
+ case GL_DEBUG_SOURCE_OTHER: return "Other";
+ case GL_DEBUG_TYPE_ERROR: return "Error";
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: return "Deprecated behavior";
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: return "Undefined behavior";
+ case GL_DEBUG_TYPE_PORTABILITY: return "Portability";
+ case GL_DEBUG_TYPE_PERFORMANCE: return "Performance";
+ case GL_DEBUG_TYPE_OTHER: return "Other";
+ case GL_DEBUG_SEVERITY_HIGH: return "High";
+ case GL_DEBUG_SEVERITY_MEDIUM: return "Medium";
+ case GL_DEBUG_SEVERITY_LOW: return "Low";
default:
break;
}
-#else
- BX_UNUSED(_enum);
-#endif // defined(GL_DEBUG_SOURCE_API_ARB)
return "<unknown>";
}
@@ -920,10 +949,35 @@ namespace bgfx { namespace gl
tfi.m_type = _type;
}
- bool isTextureFormatValid(TextureFormat::Enum _format)
+ void initTestTexture(TextureFormat::Enum _format, bool srgb = false)
{
const TextureFormatInfo& tfi = s_textureFormat[_format];
- if (GL_ZERO == tfi.m_internalFmt)
+ GLenum internalFmt = srgb
+ ? tfi.m_internalFmtSrgb
+ : tfi.m_internalFmt
+ ;
+
+ GLsizei size = (16*16*getBitsPerPixel(_format) )/8;
+ void* data = alloca(size);
+
+ if (isCompressed(_format) )
+ {
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, internalFmt, 16, 16, 0, size, data);
+ }
+ else
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, internalFmt, 16, 16, 0, tfi.m_fmt, tfi.m_type, data);
+ }
+ }
+
+ static bool isTextureFormatValid(TextureFormat::Enum _format, bool srgb = false)
+ {
+ const TextureFormatInfo& tfi = s_textureFormat[_format];
+ GLenum internalFmt = srgb
+ ? tfi.m_internalFmtSrgb
+ : tfi.m_internalFmt
+ ;
+ if (GL_ZERO == internalFmt)
{
return false;
}
@@ -931,25 +985,109 @@ namespace bgfx { namespace gl
GLuint id;
GL_CHECK(glGenTextures(1, &id) );
GL_CHECK(glBindTexture(GL_TEXTURE_2D, id) );
+ initTestTexture(_format);
- GLsizei size = (16*16*getBitsPerPixel(_format) )/8;
- void* data = alloca(size);
+ GLenum err = glGetError();
+ BX_WARN(0 == err, "TextureFormat::%s is not supported (%x: %s).", getName(_format), err, glEnumName(err) );
- if (isCompressed(_format) )
+ GL_CHECK(glDeleteTextures(1, &id) );
+
+ return 0 == err;
+ }
+
+ static bool isImageFormatValid(TextureFormat::Enum _format)
+ {
+ if (GL_ZERO == s_imageFormat[_format])
{
- glCompressedTexImage2D(GL_TEXTURE_2D, 0, tfi.m_internalFmt, 16, 16, 0, size, data);
+ return false;
}
- else
+
+ 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]
+ );
+ GLenum err = glGetError();
+
+ GL_CHECK(glDeleteTextures(1, &id) );
+
+ return 0 == err;
+ }
+
+ static bool isFramebufferFormatValid(TextureFormat::Enum _format, bool srgb = false)
+ {
+ const TextureFormatInfo& tfi = s_textureFormat[_format];
+ GLenum internalFmt = srgb
+ ? tfi.m_internalFmtSrgb
+ : tfi.m_internalFmt
+ ;
+ if (GL_ZERO == internalFmt
+ || !tfi.m_supported)
{
- glTexImage2D(GL_TEXTURE_2D, 0, tfi.m_internalFmt, 16, 16, 0, tfi.m_fmt, tfi.m_type, data);
+ return false;
}
+ GLuint fbo;
+ GL_CHECK(glGenFramebuffers(1, &fbo) );
+ GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, fbo) );
+
+ GLuint id;
+ GL_CHECK(glGenTextures(1, &id) );
+ GL_CHECK(glBindTexture(GL_TEXTURE_2D, id) );
+
+ initTestTexture(_format);
+
GLenum err = glGetError();
- BX_WARN(0 == err, "TextureFormat::%s is not supported (%x: %s).", getName(_format), err, glEnumName(err) );
+
+ GLenum attachment;
+ if (isDepth(_format) )
+ {
+ const ImageBlockInfo& info = getBlockInfo(_format);
+ if (0 < info.stencilBits)
+ {
+ attachment = GL_DEPTH_STENCIL_ATTACHMENT;
+ }
+ else if (0 == info.depthBits)
+ {
+ attachment = GL_STENCIL_ATTACHMENT;
+ }
+ else
+ {
+ attachment = GL_DEPTH_ATTACHMENT;
+ }
+ }
+ else
+ {
+ attachment = GL_COLOR_ATTACHMENT0;
+ }
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER
+ , attachment
+ , GL_TEXTURE_2D
+ , id
+ , 0
+ );
+ err = glGetError();
+
+ if (0 == err)
+ {
+ err = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ }
+
+ GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
+ GL_CHECK(glDeleteFramebuffers(1, &fbo) );
GL_CHECK(glDeleteTextures(1, &id) );
- return 0 == err;
+ return GL_FRAMEBUFFER_COMPLETE == err;
}
static void getFilters(uint32_t _flags, bool _hasMips, GLenum& _magFilter, GLenum& _minFilter)
@@ -1235,6 +1373,12 @@ namespace bgfx { namespace gl
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES < 30) )
{
setTextureFormat(TextureFormat::RGBA16F, GL_RGBA, GL_RGBA, GL_HALF_FLOAT);
+ // internalFormat and format must match:
+ // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexImage2D.xml
+ setTextureFormat(TextureFormat::RGBA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
+ setTextureFormat(TextureFormat::R5G6B5, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
+ setTextureFormat(TextureFormat::RGBA4, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
+ setTextureFormat(TextureFormat::RGB5A1, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
if (s_extension[Extension::OES_texture_half_float].m_supported
|| s_extension[Extension::OES_texture_float ].m_supported)
@@ -1313,21 +1457,54 @@ namespace bgfx { namespace gl
s_textureFormat[TextureFormat::R8].m_fmt = GL_LUMINANCE;
}
- if (!BX_ENABLED(BX_PLATFORM_EMSCRIPTEN) )
+ for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
{
- for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
+ if (TextureFormat::Unknown != ii
+ && TextureFormat::UnknownDepth != ii)
{
- if (TextureFormat::Unknown != ii
- && TextureFormat::UnknownDepth != ii)
- {
- s_textureFormat[ii].m_supported = isTextureFormatValid( (TextureFormat::Enum)ii);
- }
+ s_textureFormat[ii].m_supported = isTextureFormatValid(TextureFormat::Enum(ii) );
}
}
+ if (BX_ENABLED(0) )
+ {
+ // Disable all compressed texture formats. For testing only.
+ for (uint32_t ii = 0; ii < TextureFormat::Unknown; ++ii)
+ {
+ s_textureFormat[ii].m_supported = false;
+ }
+ }
+
+ const bool computeSupport = false
+ || !!(BGFX_CONFIG_RENDERER_OPENGLES >= 31)
+ || s_extension[Extension::ARB_compute_shader].m_supported
+ ;
+
for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
{
- g_caps.formats[ii] = s_textureFormat[ii].m_supported ? 1 : 0;
+ uint8_t supported = 0;
+ supported |= s_textureFormat[ii].m_supported
+ ? BGFX_CAPS_FORMAT_TEXTURE_COLOR
+ : BGFX_CAPS_FORMAT_TEXTURE_NONE
+ ;
+
+ supported |= isTextureFormatValid(TextureFormat::Enum(ii), true)
+ ? BGFX_CAPS_FORMAT_TEXTURE_COLOR_SRGB
+ : BGFX_CAPS_FORMAT_TEXTURE_NONE
+ ;
+
+ supported |= computeSupport
+ && isImageFormatValid(TextureFormat::Enum(ii) )
+ ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE
+ : BGFX_CAPS_FORMAT_TEXTURE_NONE
+ ;
+
+ supported |= isFramebufferFormatValid(TextureFormat::Enum(ii) )
+ ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
+ : BGFX_CAPS_FORMAT_TEXTURE_NONE
+ ;
+
+ g_caps.formats[ii] = supported;
}
g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 30)
@@ -1364,6 +1541,28 @@ namespace bgfx { namespace gl
: 0
;
+ const bool drawIndirectSupported = false
+ || s_extension[Extension::AMD_multi_draw_indirect].m_supported
+ || s_extension[Extension::ARB_draw_indirect ].m_supported
+ || s_extension[Extension::ARB_multi_draw_indirect].m_supported
+ || s_extension[Extension::EXT_multi_draw_indirect].m_supported
+ ;
+
+ if (drawIndirectSupported)
+ {
+ if (NULL == glMultiDrawArraysIndirect
+ || NULL == glMultiDrawElementsIndirect)
+ {
+ glMultiDrawArraysIndirect = stubMultiDrawArraysIndirect;
+ glMultiDrawElementsIndirect = stubMultiDrawElementsIndirect;
+ }
+ }
+
+ g_caps.supported |= drawIndirectSupported
+ ? BGFX_CAPS_DRAW_INDIRECT
+ : 0
+ ;
+
g_caps.maxTextureSize = uint16_t(glGet(GL_MAX_TEXTURE_SIZE) );
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
@@ -1436,8 +1635,7 @@ namespace bgfx { namespace gl
: 0
;
- g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGLES >= 31)
- || s_extension[Extension::ARB_compute_shader].m_supported
+ g_caps.supported |= computeSupport
? BGFX_CAPS_COMPUTE
: 0
;
@@ -1496,12 +1694,23 @@ namespace bgfx { namespace gl
}
}
-#if BGFX_CONFIG_RENDERER_OPENGL
if (s_extension[Extension::ARB_debug_output].m_supported
|| s_extension[Extension::KHR_debug].m_supported)
{
- GL_CHECK(glDebugMessageCallback(debugProcCb, NULL) );
- GL_CHECK(glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM_ARB, 0, NULL, GL_TRUE) );
+ if (NULL != glDebugMessageControl
+ && NULL != glDebugMessageInsert
+ && NULL != glDebugMessageCallback
+ && NULL != glGetDebugMessageLog)
+ {
+ GL_CHECK(glDebugMessageCallback(debugProcCb, NULL) );
+ GL_CHECK(glDebugMessageControl(GL_DONT_CARE
+ , GL_DONT_CARE
+ , GL_DEBUG_SEVERITY_MEDIUM
+ , 0
+ , NULL
+ , GL_TRUE
+ ) );
+ }
}
if (s_extension[Extension::ARB_seamless_cube_map].m_supported)
@@ -1513,7 +1722,6 @@ namespace bgfx { namespace gl
{
GL_CHECK(glEnable(GL_DEPTH_CLAMP) );
}
-#endif // BGFX_CONFIG_RENDERER_OPENGL
if (NULL == glFrameTerminatorGREMEDY
|| !s_extension[Extension::GREMEDY_frame_terminator].m_supported)
@@ -1530,6 +1738,8 @@ namespace bgfx { namespace gl
;
}
+ setGraphicsDebuggerPresent(s_extension[Extension::EXT_debug_tool].m_supported);
+
if (NULL == glObjectLabel)
{
glObjectLabel = stubObjectLabel;
@@ -1616,7 +1826,7 @@ namespace bgfx { namespace gl
}
}
- void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint8_t _flags) BX_OVERRIDE
+ void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint16_t _flags) BX_OVERRIDE
{
m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags);
}
@@ -1637,9 +1847,9 @@ namespace bgfx { namespace gl
{
}
- void createVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle, uint8_t /*_flags*/) BX_OVERRIDE
+ void createVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle, uint16_t _flags) BX_OVERRIDE
{
- m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle);
+ m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle, _flags);
}
void destroyVertexBuffer(VertexBufferHandle _handle) BX_OVERRIDE
@@ -1647,7 +1857,7 @@ namespace bgfx { namespace gl
m_vertexBuffers[_handle.idx].destroy();
}
- void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint8_t _flags) BX_OVERRIDE
+ void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) BX_OVERRIDE
{
m_indexBuffers[_handle.idx].create(_size, NULL, _flags);
}
@@ -1662,10 +1872,10 @@ namespace bgfx { namespace gl
m_indexBuffers[_handle.idx].destroy();
}
- void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint8_t /*_flags*/) BX_OVERRIDE
+ void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) BX_OVERRIDE
{
VertexDeclHandle decl = BGFX_INVALID_HANDLE;
- m_vertexBuffers[_handle.idx].create(_size, NULL, decl);
+ m_vertexBuffers[_handle.idx].create(_size, NULL, decl, _flags);
}
void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) BX_OVERRIDE
@@ -2239,9 +2449,9 @@ namespace bgfx { namespace gl
config.OGL.Header.RTSize.h = m_resolution.m_height;
# endif // OVR_VERSION > OVR_VERSION_043
config.OGL.Header.Multisample = 0;
- config.OGL.Window = g_bgfxHwnd;
- config.OGL.DC = GetDC(g_bgfxHwnd);
- if (m_ovr.postReset(g_bgfxHwnd, &config.Config, !!(m_resolution.m_flags & BGFX_RESET_HMD_DEBUG) ) )
+ config.OGL.Window = (HWND)g_platformData.nwh;
+ config.OGL.DC = GetDC(config.OGL.Window);
+ if (m_ovr.postReset(g_platformData.nwh, &config.Config, !!(m_resolution.m_flags & BGFX_RESET_HMD_DEBUG) ) )
{
uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);
const Memory* mem = alloc(size);
@@ -3066,8 +3276,11 @@ namespace bgfx { namespace gl
*array = '\0';
array++;
char* end = strchr(array, ']');
- *end = '\0';
- offset = atoi(array);
+ if (NULL != end)
+ { // Some devices (Amazon Fire) might not return terminating brace.
+ *end = '\0';
+ offset = atoi(array);
+ }
}
switch (gltype)
@@ -3329,18 +3542,20 @@ namespace bgfx { namespace gl
}
}
- bool TextureGL::init(GLenum _target, uint32_t _width, uint32_t _height, uint8_t _format, uint8_t _numMips, uint32_t _flags)
+ bool TextureGL::init(GLenum _target, uint32_t _width, uint32_t _height, uint32_t _depth, uint8_t _format, uint8_t _numMips, uint32_t _flags)
{
- m_target = _target;
+ m_target = _target;
m_numMips = _numMips;
- m_flags = _flags;
- m_currentFlags = UINT32_MAX;
- m_width = _width;
- m_height = _height;
+ m_flags = _flags;
+ m_width = _width;
+ m_height = _height;
+ m_depth = _depth;
+ m_currentFlags = UINT32_MAX;
m_requestedFormat = _format;
m_textureFormat = _format;
- const bool bufferOnly = 0 != (m_flags&BGFX_TEXTURE_RT_BUFFER_ONLY);
+ const bool bufferOnly = 0 != (m_flags&BGFX_TEXTURE_RT_BUFFER_ONLY);
+ const bool computeWrite = 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE );
if (!bufferOnly)
{
@@ -3361,6 +3576,7 @@ namespace bgfx { namespace gl
const bool convert = false
|| (compressed && m_textureFormat != m_requestedFormat)
|| swizzle
+ || !s_textureFormat[m_requestedFormat].m_supported
;
if (convert)
@@ -3371,6 +3587,29 @@ namespace bgfx { namespace gl
m_type = tfiRgba8.m_type;
}
+ if (computeWrite)
+ {
+ if (_target == GL_TEXTURE_3D)
+ {
+ GL_CHECK(glTexStorage3D(_target
+ , _numMips
+ , s_textureFormat[m_textureFormat].m_internalFmt
+ , m_width
+ , m_height
+ , _depth
+ ) );
+ }
+ else
+ {
+ GL_CHECK(glTexStorage2D(_target
+ , _numMips
+ , s_textureFormat[m_textureFormat].m_internalFmt
+ , m_width
+ , m_height
+ ) );
+ }
+ }
+
setSamplerState(_flags);
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
@@ -3439,9 +3678,15 @@ namespace bgfx { namespace gl
uint8_t numMips = imageContainer.m_numMips;
const uint8_t startLod = uint8_t(bx::uint32_min(_skip, numMips-1) );
numMips -= startLod;
- const ImageBlockInfo& blockInfo = getBlockInfo(TextureFormat::Enum(imageContainer.m_format) );
- const uint32_t textureWidth = bx::uint32_max(blockInfo.blockWidth, imageContainer.m_width >>startLod);
- const uint32_t textureHeight = bx::uint32_max(blockInfo.blockHeight, imageContainer.m_height>>startLod);
+ uint32_t textureWidth;
+ uint32_t textureHeight;
+ uint32_t textureDepth;
+ {
+ const ImageBlockInfo& ibi = getBlockInfo(TextureFormat::Enum(imageContainer.m_format) );
+ textureWidth = bx::uint32_max(ibi.blockWidth, imageContainer.m_width >>startLod);
+ textureHeight = bx::uint32_max(ibi.blockHeight, imageContainer.m_height>>startLod);
+ textureDepth = imageContainer.m_depth;
+ }
GLenum target = GL_TEXTURE_2D;
if (imageContainer.m_cubeMap)
@@ -3456,6 +3701,7 @@ namespace bgfx { namespace gl
if (!init(target
, textureWidth
, textureHeight
+ , textureDepth
, imageContainer.m_format
, numMips
, _flags
@@ -3464,9 +3710,15 @@ namespace bgfx { namespace gl
return;
}
+ const bool computeWrite = 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE);
+ const bool srgb = 0 != (m_flags&BGFX_TEXTURE_SRGB);
+
target = GL_TEXTURE_CUBE_MAP == m_target ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : m_target;
- const GLenum internalFmt = s_textureFormat[m_textureFormat].m_internalFmt;
+ const GLenum internalFmt = srgb
+ ? s_textureFormat[m_textureFormat].m_internalFmtSrgb
+ : s_textureFormat[m_textureFormat].m_internalFmt
+ ;
const bool swizzle = true
&& TextureFormat::BGRA8 == m_requestedFormat
@@ -3475,17 +3727,9 @@ namespace bgfx { namespace gl
;
const bool compressed = isCompressed(TextureFormat::Enum(m_requestedFormat) );
const bool convert = false
- || (compressed && m_textureFormat != m_requestedFormat)
+ || m_textureFormat != m_requestedFormat
|| swizzle
;
- uint32_t blockWidth = 1;
- uint32_t blockHeight = 1;
-
- if (convert && compressed)
- {
- blockWidth = blockInfo.blockWidth;
- blockHeight = blockInfo.blockHeight;
- }
BX_TRACE("Texture%-4s %3d: %s (requested: %s), %dx%dx%d%s."
, imageContainer.m_cubeMap ? "Cube" : (1 < imageContainer.m_depth ? "3D" : "2D")
@@ -3520,14 +3764,15 @@ namespace bgfx { namespace gl
for (uint8_t lod = 0, num = numMips; lod < num; ++lod)
{
- width = bx::uint32_max(blockWidth, width);
- height = bx::uint32_max(blockHeight, height);
+ width = bx::uint32_max(1, width);
+ height = bx::uint32_max(1, height);
depth = bx::uint32_max(1, depth);
ImageMip mip;
if (imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) )
{
- if (compressed)
+ if (compressed
+ && !convert)
{
compressedTexImage(target+side
, lod
@@ -3546,7 +3791,13 @@ namespace bgfx { namespace gl
if (convert)
{
- imageDecodeToRgba8(temp, mip.m_data, mip.m_width, mip.m_height, mip.m_width*4, mip.m_format);
+ imageDecodeToRgba8(temp
+ , mip.m_data
+ , mip.m_width
+ , mip.m_height
+ , mip.m_width*4
+ , mip.m_format
+ );
data = temp;
}
@@ -3563,7 +3814,7 @@ namespace bgfx { namespace gl
);
}
}
- else
+ else if (!computeWrite)
{
if (compressed)
{
@@ -3724,6 +3975,12 @@ namespace bgfx { namespace gl
) );
}
+ if (!convert
+ && unpackRowLength)
+ {
+ GL_CHECK(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0) );
+ }
+
if (NULL != temp)
{
BX_FREE(g_allocator, temp);
@@ -4133,11 +4390,14 @@ namespace bgfx { namespace gl
writeString(&writer, "#version 140\n");
}
+ writeString(&writer, "#define texture2DLod textureLod\n");
+ writeString(&writer, "#define texture3DLod textureLod\n");
+ writeString(&writer, "#define textureCubeLod textureLod\n");
+
if (m_type == GL_FRAGMENT_SHADER)
{
writeString(&writer, "#define varying in\n");
writeString(&writer, "#define texture2D texture\n");
- writeString(&writer, "#define texture2DLod textureLod\n");
writeString(&writer, "#define texture2DProj textureProj\n");
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) )
@@ -4152,9 +4412,7 @@ namespace bgfx { namespace gl
}
writeString(&writer, "#define texture3D texture\n");
- writeString(&writer, "#define texture3DLod textureLod\n");
writeString(&writer, "#define textureCube texture\n");
- writeString(&writer, "#define textureCubeLod textureLod\n");
uint32_t fragData = 0;
@@ -4782,7 +5040,38 @@ namespace bgfx { namespace gl
viewState.setPredefined<1>(this, view, eye, program, _render, compute);
- GL_CHECK(glDispatchCompute(compute.m_numX, compute.m_numY, compute.m_numZ) );
+ if (isValid(compute.m_indirectBuffer) )
+ {
+ const VertexBufferGL& vb = m_vertexBuffers[compute.m_indirectBuffer.idx];
+ if (currentState.m_indirectBuffer.idx != compute.m_indirectBuffer.idx)
+ {
+ currentState.m_indirectBuffer = compute.m_indirectBuffer;
+ GL_CHECK(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, vb.m_id) );
+ }
+
+ uint32_t numDrawIndirect = UINT16_MAX == compute.m_numIndirect
+ ? vb.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE
+ : compute.m_numIndirect
+ ;
+
+ uintptr_t args = compute.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
+ for (uint32_t ii = 0; ii < numDrawIndirect; ++ii)
+ {
+ GL_CHECK(glDispatchComputeIndirect(args) );
+ args += BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
+ }
+ }
+ else
+ {
+ if (isValid(currentState.m_indirectBuffer) )
+ {
+ currentState.m_indirectBuffer.idx = invalidHandle;
+ GL_CHECK(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0) );
+ }
+
+ GL_CHECK(glDispatchCompute(compute.m_numX, compute.m_numY, compute.m_numZ) );
+ }
+
GL_CHECK(glMemoryBarrier(barrier) );
}
}
@@ -4790,6 +5079,8 @@ namespace bgfx { namespace gl
continue;
}
+ bool resetState = viewChanged || wasCompute;
+
if (wasCompute)
{
wasCompute = false;
@@ -4812,7 +5103,7 @@ namespace bgfx { namespace gl
uint64_t changedStencil = currentState.m_stencil ^ draw.m_stencil;
currentState.m_stencil = newStencil;
- if (viewChanged)
+ if (resetState)
{
currentState.clear();
currentState.m_scissor = !draw.m_scissor;
@@ -5310,61 +5601,116 @@ namespace bgfx { namespace gl
numVertices = vb.m_size/vertexDecl.m_stride;
}
- uint32_t numIndices = 0;
+ uint32_t numIndices = 0;
uint32_t numPrimsSubmitted = 0;
- uint32_t numInstances = 0;
- uint32_t numPrimsRendered = 0;
+ uint32_t numInstances = 0;
+ uint32_t numPrimsRendered = 0;
+ uint32_t numDrawIndirect = 0;
- if (isValid(draw.m_indexBuffer) )
+ if (isValid(draw.m_indirectBuffer) )
{
- const IndexBufferGL& ib = m_indexBuffers[draw.m_indexBuffer.idx];
- const bool hasIndex16 = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32);
- const GLenum indexFormat = hasIndex16
- ? GL_UNSIGNED_SHORT
- : GL_UNSIGNED_INT
- ;
+ const VertexBufferGL& vb = m_vertexBuffers[draw.m_indirectBuffer.idx];
+ if (currentState.m_indirectBuffer.idx != draw.m_indirectBuffer.idx)
+ {
+ currentState.m_indirectBuffer = draw.m_indirectBuffer;
+ GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, vb.m_id) );
+ }
- if (UINT32_MAX == draw.m_numIndices)
+ if (isValid(draw.m_indexBuffer) )
{
- const uint32_t indexSize = hasIndex16 ? 2 : 4;
- numIndices = ib.m_size/indexSize;
- numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
- numInstances = draw.m_numInstances;
- numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
-
- GL_CHECK(glDrawElementsInstanced(prim.m_type
- , numIndices
- , indexFormat
- , (void*)0
- , draw.m_numInstances
+ const IndexBufferGL& ib = m_indexBuffers[draw.m_indexBuffer.idx];
+ const bool hasIndex16 = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32);
+ const GLenum indexFormat = hasIndex16
+ ? GL_UNSIGNED_SHORT
+ : GL_UNSIGNED_INT
+ ;
+
+ numDrawIndirect = UINT16_MAX == draw.m_numIndirect
+ ? vb.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE
+ : draw.m_numIndirect
+ ;
+
+ uintptr_t args = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
+ GL_CHECK(glMultiDrawElementsIndirect(prim.m_type, indexFormat
+ , (void*)args
+ , numDrawIndirect
+ , BGFX_CONFIG_DRAW_INDIRECT_STRIDE
) );
}
- else if (prim.m_min <= draw.m_numIndices)
+ else
{
- numIndices = draw.m_numIndices;
- numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
- numInstances = draw.m_numInstances;
- numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
+ numDrawIndirect = UINT16_MAX == draw.m_numIndirect
+ ? vb.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE
+ : draw.m_numIndirect
+ ;
- GL_CHECK(glDrawElementsInstanced(prim.m_type
- , numIndices
- , indexFormat
- , (void*)(uintptr_t)(draw.m_startIndex*2)
- , draw.m_numInstances
+ uintptr_t args = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
+ GL_CHECK(glMultiDrawArraysIndirect(prim.m_type
+ , (void*)args
+ , numDrawIndirect
+ , BGFX_CONFIG_DRAW_INDIRECT_STRIDE
) );
}
}
else
{
- numPrimsSubmitted = numVertices/prim.m_div - prim.m_sub;
- numInstances = draw.m_numInstances;
- numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
+ if (isValid(currentState.m_indirectBuffer) )
+ {
+ currentState.m_indirectBuffer.idx = invalidHandle;
+ GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0) );
+ }
- GL_CHECK(glDrawArraysInstanced(prim.m_type
- , 0
- , numVertices
- , draw.m_numInstances
- ) );
+ if (isValid(draw.m_indexBuffer) )
+ {
+ const IndexBufferGL& ib = m_indexBuffers[draw.m_indexBuffer.idx];
+ const bool hasIndex16 = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32);
+ const GLenum indexFormat = hasIndex16
+ ? GL_UNSIGNED_SHORT
+ : GL_UNSIGNED_INT
+ ;
+
+ 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;
+ numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
+
+ GL_CHECK(glDrawElementsInstanced(prim.m_type
+ , numIndices
+ , indexFormat
+ , (void*)0
+ , draw.m_numInstances
+ ) );
+ }
+ else if (prim.m_min <= draw.m_numIndices)
+ {
+ numIndices = draw.m_numIndices;
+ numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
+ numInstances = draw.m_numInstances;
+ numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
+
+ GL_CHECK(glDrawElementsInstanced(prim.m_type
+ , numIndices
+ , indexFormat
+ , (void*)(uintptr_t)(draw.m_startIndex*2)
+ , draw.m_numInstances
+ ) );
+ }
+ }
+ else
+ {
+ numPrimsSubmitted = numVertices/prim.m_div - prim.m_sub;
+ numInstances = draw.m_numInstances;
+ numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
+
+ GL_CHECK(glDrawArraysInstanced(prim.m_type
+ , 0
+ , numVertices
+ , draw.m_numInstances
+ ) );
+ }
}
statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
@@ -5379,6 +5725,11 @@ namespace bgfx { namespace gl
if (0 < _render->m_num)
{
+ if (0 != (m_resolution.m_flags & BGFX_RESET_FLUSH_AFTER_RENDER) )
+ {
+ GL_CHECK(glFlush() );
+ }
+
captureElapsed = -bx::getHPCounter();
capture();
captureElapsed += bx::getHPCounter();
@@ -5459,6 +5810,7 @@ namespace bgfx { namespace gl
, elapsedCpuMs > elapsedGpuMs ? '>' : '<'
, elapsedGpuMs
);
+
for (uint32_t ii = 0; ii < BX_COUNTOF(s_primInfo); ++ii)
{
tvm.printf(10, pos++, 0x8e, " %9s: %7d (#inst: %5d), submitted: %7d"