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.cpp744
1 files changed, 408 insertions, 336 deletions
diff --git a/3rdparty/bgfx/src/renderer_gl.cpp b/3rdparty/bgfx/src/renderer_gl.cpp
index 7f0afda9a04..3fe8afcba0f 100644
--- a/3rdparty/bgfx/src/renderer_gl.cpp
+++ b/3rdparty/bgfx/src/renderer_gl.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2018 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
@@ -14,6 +14,14 @@ namespace bgfx { namespace gl
{
static char s_viewName[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME];
+ inline void setViewType(ViewId _view, const bx::StringView _str)
+ {
+ if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION || BGFX_CONFIG_PROFILER) )
+ {
+ bx::memCopy(&s_viewName[_view][3], _str.getPtr(), _str.getLength() );
+ }
+ }
+
struct PrimInfo
{
GLenum m_type;
@@ -1005,6 +1013,14 @@ namespace bgfx { namespace gl
{
}
+ static void GL_APIENTRY stubPushDebugGroup(GLenum /*_source*/, GLuint /*_id*/, GLsizei /*_length*/, const char* /*_message*/)
+ {
+ }
+
+ static void GL_APIENTRY stubPopDebugGroup()
+ {
+ }
+
static void GL_APIENTRY stubObjectLabel(GLenum /*_identifier*/, GLuint /*_name*/, GLsizei /*_length*/, const char* /*_label*/)
{
}
@@ -1039,10 +1055,22 @@ namespace bgfx { namespace gl
typedef void (*PostSwapBuffersFn)(uint32_t _width, uint32_t _height);
+ void flushGlError()
+ {
+ for (GLenum err = glGetError(); err != 0; err = glGetError() );
+ }
+
+ GLenum getGlError()
+ {
+ GLenum err = glGetError();
+ flushGlError();
+ return err;
+ }
+
static const char* getGLString(GLenum _name)
{
const char* str = (const char*)glGetString(_name);
- glGetError(); // ignore error if glGetString returns NULL.
+ getGlError(); // ignore error if glGetString returns NULL.
if (NULL != str)
{
return str;
@@ -1054,7 +1082,7 @@ namespace bgfx { namespace gl
static uint32_t getGLStringHash(GLenum _name)
{
const char* str = (const char*)glGetString(_name);
- glGetError(); // ignore error if glGetString returns NULL.
+ getGlError(); // ignore error if glGetString returns NULL.
if (NULL != str)
{
return bx::hash<bx::HashMurmur2A>(str, (uint32_t)bx::strLen(str) );
@@ -1139,7 +1167,7 @@ namespace bgfx { namespace gl
{
GLint result = 0;
glGetIntegerv(_pname, &result);
- GLenum err = glGetError();
+ GLenum err = getGlError();
BX_WARN(0 == err, "glGetIntegerv(0x%04x, ...) failed with GL error: 0x%04x.", _pname, err);
return 0 == err ? result : 0;
}
@@ -1152,11 +1180,6 @@ namespace bgfx { namespace gl
tfi.m_type = _type;
}
- void flushGlError()
- {
- for (GLenum err = glGetError(); err != 0; err = glGetError() );
- }
-
static void texSubImage(
GLenum _target
, GLint _level
@@ -1441,7 +1464,7 @@ namespace bgfx { namespace gl
uint32_t block = bx::uint32_max(4, dim);
size = (block*block*bpp)/8;
compressedTexImage(target, ii, internalFmt, dim, dim, 0, 0, size, data);
- err |= glGetError();
+ err |= getGlError();
}
}
else
@@ -1451,7 +1474,7 @@ namespace bgfx { namespace gl
dim = bx::uint32_max(1, dim);
size = (dim*dim*bpp)/8;
texImage(target, 0, ii, internalFmt, dim, dim, 0, 0, tfi.m_fmt, tfi.m_type, data);
- err |= glGetError();
+ err |= getGlError();
}
}
@@ -1497,7 +1520,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
, _dim
, _dim
);
- err = glGetError();
+ err = getGlError();
}
if (0 == err)
@@ -1516,7 +1539,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
&& _mipAutogen)
{
glGenerateMipmap(target);
- err = glGetError();
+ err = getGlError();
}
}
@@ -1540,7 +1563,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
GLenum err = 0;
glTexStorage2D(GL_TEXTURE_2D, 1, s_imageFormat[_format], _dim, _dim);
- err |= glGetError();
+ err |= getGlError();
if (0 == err)
{
glBindImageTexture(0
@@ -1551,7 +1574,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
, GL_READ_WRITE
, s_imageFormat[_format]
);
- err |= glGetError();
+ err |= getGlError();
}
GL_CHECK(glDeleteTextures(1, &id) );
@@ -1590,7 +1613,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glDeleteRenderbuffers(1, &rbo);
- GLenum err = glGetError();
+ GLenum err = getGlError();
return 0 == err;
}
@@ -1632,7 +1655,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
, id
, 0
);
- err = glGetError();
+ err = getGlError();
if (0 == err)
{
@@ -1656,8 +1679,14 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
_minFilter = s_textureFilterMin[min][_hasMips ? mip+1 : 0];
}
- void updateExtension(const char* _name)
+ void updateExtension(const bx::StringView& _name)
{
+ bx::StringView ext(_name);
+ if (0 == bx::strCmp(ext, "GL_", 3) ) // skip GL_
+ {
+ ext.set(ext.getPtr()+3, ext.getTerm() );
+ }
+
bool supported = false;
for (uint32_t ii = 0; ii < Extension::Count; ++ii)
{
@@ -1665,12 +1694,6 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (!extension.m_supported
&& extension.m_initialize)
{
- const char* ext = _name;
- if (0 == bx::strCmp(ext, "GL_", 3) ) // skip GL_
- {
- ext += 3;
- }
-
if (0 == bx::strCmp(ext, extension.m_name) )
{
extension.m_supported = true;
@@ -1680,7 +1703,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
}
}
- BX_TRACE("GL_EXTENSION %s: %s", supported ? " (supported)" : "", _name);
+ BX_TRACE("GL_EXTENSION %s: %.*s", supported ? " (supported)" : "", _name.getLength(), _name.getPtr() );
BX_UNUSED(supported);
}
@@ -1738,6 +1761,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
, m_hash( (BX_PLATFORM_WINDOWS<<1) | BX_ARCH_64BIT)
, m_backBufferFbo(0)
, m_msaaBackBufferFbo(0)
+ , m_clearQuadColor(BGFX_INVALID_HANDLE)
+ , m_clearQuadDepth(BGFX_INVALID_HANDLE)
{
bx::memSet(m_msaaBackBufferRbos, 0, sizeof(m_msaaBackBufferRbos) );
}
@@ -1838,6 +1863,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
GL_GET(GL_MAX_RENDERBUFFER_SIZE, 1);
GL_GET(GL_MAX_COLOR_ATTACHMENTS, 1);
GL_GET(GL_MAX_DRAW_BUFFERS, 1);
+ GL_GET(GL_MAX_LABEL_LENGTH, 0);
+
#undef GL_GET
BX_TRACE(" Vendor: %s", m_vendor);
@@ -1872,32 +1899,19 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (BX_ENABLED(BGFX_CONFIG_RENDERER_USE_EXTENSIONS) )
{
const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
- glGetError(); // ignore error if glGetString returns NULL.
+ getGlError(); // ignore error if glGetString returns NULL.
if (NULL != extensions)
{
- char name[1024];
- const char* pos = extensions;
- const char* end = extensions + bx::strLen(extensions);
+ bx::StringView ext(extensions);
uint32_t index = 0;
- while (pos < end)
+ while (!ext.isEmpty() )
{
- uint32_t len;
- const bx::StringView space = bx::strFind(pos, ' ');
- if (!space.isEmpty() )
- {
- len = bx::uint32_min(sizeof(name), (uint32_t)(space.getPtr() - pos) );
- }
- else
- {
- len = bx::uint32_min(sizeof(name), (uint32_t)bx::strLen(pos) );
- }
-
- bx::strCopy(name, BX_COUNTOF(name), pos, len);
- name[len] = '\0';
+ const bx::StringView space = bx::strFind(ext, ' ');
+ const bx::StringView token = bx::StringView(ext.getPtr(), space.getPtr() );
+ updateExtension(token);
- updateExtension(name);
+ ext.set(space.getPtr() + (space.isEmpty() ? 0 : 1), ext.getTerm() );
- pos += len+1;
++index;
}
}
@@ -1905,7 +1919,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
{
GLint numExtensions = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
- glGetError(); // ignore error if glGetIntegerv returns NULL.
+ getGlError(); // ignore error if glGetIntegerv returns NULL.
for (GLint index = 0; index < numExtensions; ++index)
{
@@ -2148,6 +2162,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
{
+ const TextureFormat::Enum fmt = TextureFormat::Enum(ii);
+
uint16_t supported = BGFX_CAPS_FORMAT_TEXTURE_NONE;
supported |= s_textureFormat[ii].m_supported
? BGFX_CAPS_FORMAT_TEXTURE_2D
@@ -2156,30 +2172,33 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
- supported |= isTextureFormatValid(TextureFormat::Enum(ii), true)
+ supported |= isTextureFormatValid(fmt, true)
? BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB
| BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB
| BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
- supported |= isTextureFormatValid(TextureFormat::Enum(ii), false, true)
- ? BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN
- : BGFX_CAPS_FORMAT_TEXTURE_NONE
- ;
+ if (!bimg::isCompressed(bimg::TextureFormat::Enum(fmt) ) )
+ {
+ supported |= isTextureFormatValid(fmt, false, true)
+ ? BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN
+ : BGFX_CAPS_FORMAT_TEXTURE_NONE
+ ;
+ }
supported |= computeSupport
- && isImageFormatValid(TextureFormat::Enum(ii) )
+ && isImageFormatValid(fmt)
? BGFX_CAPS_FORMAT_TEXTURE_IMAGE
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
- supported |= isFramebufferFormatValid(TextureFormat::Enum(ii) )
+ supported |= isFramebufferFormatValid(fmt)
? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
- supported |= isFramebufferFormatValid(TextureFormat::Enum(ii), false, true)
+ supported |= isFramebufferFormatValid(fmt, false, true)
? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
@@ -2193,7 +2212,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
, 1
, &maxSamples
);
- GLenum err = glGetError();
+ GLenum err = getGlError();
supported |= 0 == err && maxSamples > 0
? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA
: BGFX_CAPS_FORMAT_TEXTURE_NONE
@@ -2205,7 +2224,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
, 1
, &maxSamples
);
- err = glGetError();
+ err = getGlError();
supported |= 0 == err && maxSamples > 0
? BGFX_CAPS_FORMAT_TEXTURE_MSAA
: BGFX_CAPS_FORMAT_TEXTURE_NONE
@@ -2422,12 +2441,18 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
m_atocSupport = s_extension[Extension::ARB_multisample].m_supported;
m_conservativeRasterSupport = s_extension[Extension::NV_conservative_raster].m_supported;
+ m_imageLoadStoreSupport = false
+ || s_extension[Extension::ARB_shader_image_load_store].m_supported
+ || s_extension[Extension::EXT_shader_image_load_store].m_supported
+ ;
+
g_caps.supported |= 0
| (m_atocSupport ? BGFX_CAPS_ALPHA_TO_COVERAGE : 0)
| (m_conservativeRasterSupport ? BGFX_CAPS_CONSERVATIVE_RASTER : 0)
| (m_occlusionQuerySupport ? BGFX_CAPS_OCCLUSION_QUERY : 0)
| (m_depthTextureSupport ? BGFX_CAPS_TEXTURE_COMPARE_LEQUAL : 0)
| (computeSupport ? BGFX_CAPS_COMPUTE : 0)
+ | (m_imageLoadStoreSupport ? BGFX_CAPS_FRAMEBUFFER_RW : 0)
;
g_caps.supported |= m_glctx.getCaps();
@@ -2509,6 +2534,13 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
}
}
+ if (NULL == glPushDebugGroup
+ || NULL == glPopDebugGroup)
+ {
+ glPushDebugGroup = stubPushDebugGroup;
+ glPopDebugGroup = stubPopDebugGroup;
+ }
+
if (s_extension[Extension::ARB_seamless_cube_map].m_supported)
{
GL_CHECK(glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS) );
@@ -2520,6 +2552,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
glInsertEventMarker = stubInsertEventMarker;
}
+ m_maxLabelLen = uint16_t(glGet(GL_MAX_LABEL_LENGTH) );
+
setGraphicsDebuggerPresent(s_extension[Extension::EXT_debug_tool].m_supported);
if (NULL == glObjectLabel)
@@ -2652,20 +2686,20 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
m_indexBuffers[_handle.idx].destroy();
}
- void createVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl) override
+ void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override
{
- VertexDecl& decl = m_vertexDecls[_handle.idx];
- bx::memCopy(&decl, &_decl, sizeof(VertexDecl) );
- dump(decl);
+ VertexLayout& layout = m_vertexLayouts[_handle.idx];
+ bx::memCopy(&layout, &_layout, sizeof(VertexLayout) );
+ dump(layout);
}
- void destroyVertexDecl(VertexDeclHandle /*_handle*/) override
+ void destroyVertexLayout(VertexLayoutHandle /*_handle*/) override
{
}
- void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexDeclHandle _declHandle, uint16_t _flags) override
+ void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override
{
- m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle, _flags);
+ m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _layoutHandle, _flags);
}
void destroyVertexBuffer(VertexBufferHandle _handle) override
@@ -2690,8 +2724,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override
{
- VertexDeclHandle decl = BGFX_INVALID_HANDLE;
- m_vertexBuffers[_handle.idx].create(_size, NULL, decl, _flags);
+ VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE;
+ m_vertexBuffers[_handle.idx].create(_size, NULL, layoutHandle, _flags);
}
void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override
@@ -2777,26 +2811,24 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
const TextureGL& texture = m_textures[_handle.idx];
const bool compressed = bimg::isCompressed(bimg::TextureFormat::Enum(texture.m_textureFormat) );
- if(!compressed)
+ if (!compressed)
{
- Attachment attachment[1];
- attachment[0].handle = _handle;
- attachment[0].mip = 0;
- attachment[0].layer = 0;
+ Attachment at[1];
+ at[0].init(_handle);
FrameBufferGL frameBuffer;
- frameBuffer.create(1, attachment);
+ frameBuffer.create(BX_COUNTOF(at), at);
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.m_fbo[0]) );
GL_CHECK(glFramebufferTexture2D(
GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, texture.m_id
- , attachment[0].mip
+ , at[0].mip
) );
if (!BX_ENABLED(BX_PLATFORM_EMSCRIPTEN)
- && !BX_ENABLED(BX_PLATFORM_IOS))
+ && !BX_ENABLED(BX_PLATFORM_IOS) )
{
GL_CHECK(glReadBuffer(GL_COLOR_ATTACHMENT0) );
}
@@ -2927,6 +2959,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
width = frameBuffer.m_width;
height = frameBuffer.m_height;
}
+
m_glctx.makeCurrent(swapChain);
uint32_t length = width*height*4;
@@ -2970,26 +3003,46 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
bx::memCopy(m_uniforms[_loc], _data, _size);
}
- void setMarker(const char* _marker, uint32_t _size) override
+ void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override
{
- GL_CHECK(glInsertEventMarker(_size, _marker) );
+ m_occlusionQuery.invalidate(_handle);
}
- void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override
+ void setMarker(const char* _marker, uint16_t _len) override
{
- m_occlusionQuery.invalidate(_handle);
+ GL_CHECK(glInsertEventMarker(_len, _marker) );
}
- virtual void setName(Handle _handle, const char* _name) override
+ virtual void setName(Handle _handle, const char* _name, uint16_t _len) override
{
+ uint16_t len = bx::min(_len, m_maxLabelLen);
+
switch (_handle.type)
{
+ case Handle::IndexBuffer:
+ GL_CHECK(glObjectLabel(GL_BUFFER, m_indexBuffers[_handle.idx].m_id, len, _name) );
+ break;
+
case Handle::Shader:
- GL_CHECK(glObjectLabel(GL_SHADER, m_shaders[_handle.idx].m_id, -1, _name) );
+ GL_CHECK(glObjectLabel(GL_SHADER, m_shaders[_handle.idx].m_id, len, _name) );
break;
case Handle::Texture:
- GL_CHECK(glObjectLabel(GL_TEXTURE, m_textures[_handle.idx].m_id, -1, _name) );
+ {
+ GLint id = m_textures[_handle.idx].m_id;
+ if (0 != id)
+ {
+ GL_CHECK(glObjectLabel(GL_TEXTURE, id, len, _name) );
+ }
+ else
+ {
+ GL_CHECK(glObjectLabel(GL_RENDERBUFFER, m_textures[_handle.idx].m_rbo, len, _name) );
+ }
+ }
+ break;
+
+ case Handle::VertexBuffer:
+ GL_CHECK(glObjectLabel(GL_BUFFER, m_vertexBuffers[_handle.idx].m_id, len, _name) );
break;
default:
@@ -3028,7 +3081,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
GL_CHECK(glUniform1i(program.m_sampler[0], 0) );
float proj[16];
- bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f, 0.0f, true);
+ bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f, 0.0f, g_caps.homogeneousDepth);
GL_CHECK(glUniformMatrix4fv(program.m_predefined[0].m_loc
, 1
@@ -3058,7 +3111,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (0 < numVertices)
{
m_indexBuffers[_blitter.m_ib->handle.idx].update(0, _numIndices*2, _blitter.m_ib->data);
- m_vertexBuffers[_blitter.m_vb->handle.idx].update(0, numVertices*_blitter.m_decl.m_stride, _blitter.m_vb->data);
+ m_vertexBuffers[_blitter.m_vb->handle.idx].update(0, numVertices*_blitter.m_layout.m_stride, _blitter.m_vb->data);
VertexBufferGL& vb = m_vertexBuffers[_blitter.m_vb->handle.idx];
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
@@ -3068,7 +3121,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
ProgramGL& program = m_program[_blitter.m_program.idx];
program.bindAttributesBegin();
- program.bindAttributes(_blitter.m_decl, 0);
+ program.bindAttributes(_blitter.m_layout, 0);
program.bindAttributesEnd();
GL_CHECK(glDrawElements(GL_TRIANGLES
@@ -3192,6 +3245,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (UINT16_MAX != frameBuffer.m_denseIdx)
{
m_glctx.makeCurrent(frameBuffer.m_swapChain);
+ GL_CHECK(glFrontFace(GL_CW) );
+
frameBuffer.m_needPresent = true;
m_currentFbo = 0;
}
@@ -3200,6 +3255,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
m_glctx.makeCurrent(NULL);
m_currentFbo = frameBuffer.m_fbo[0];
}
+
+ frameBuffer.set();
}
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_currentFbo) );
@@ -3227,11 +3284,16 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (0 == m_msaaBackBufferFbo // iOS
&& 1 < _msaa)
{
+ GLenum storageFormat = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER)
+ ? GL_SRGB8_ALPHA8
+ : GL_RGBA8
+ ;
+
GL_CHECK(glGenFramebuffers(1, &m_msaaBackBufferFbo) );
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
GL_CHECK(glGenRenderbuffers(BX_COUNTOF(m_msaaBackBufferRbos), m_msaaBackBufferRbos) );
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_msaaBackBufferRbos[0]) );
- GL_CHECK(glRenderbufferStorageMultisample(GL_RENDERBUFFER, _msaa, GL_RGBA8, _width, _height) );
+ GL_CHECK(glRenderbufferStorageMultisample(GL_RENDERBUFFER, _msaa, storageFormat, _width, _height) );
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_msaaBackBufferRbos[1]) );
GL_CHECK(glRenderbufferStorageMultisample(GL_RENDERBUFFER, _msaa, GL_DEPTH24_STENCIL8, _width, _height) );
GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_msaaBackBufferRbos[0]) );
@@ -3616,16 +3678,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
switch (type)
{
-// case ConstantType::Int1:
-// {
-// int* value = (int*)data;
-// 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(Int1, 1iv, I, int);
- CASE_IMPLEMENT_UNIFORM(Vec4, 4fv, F, float);
+ CASE_IMPLEMENT_UNIFORM(Sampler, 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);
@@ -3739,57 +3793,42 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
GL_CHECK(glDisable(GL_STENCIL_TEST) );
}
- VertexBufferGL& vb = m_vertexBuffers[_clearQuad.m_vb->handle.idx];
- VertexDecl& vertexDecl = m_vertexDecls[_clearQuad.m_vb->decl.idx];
-
- {
- struct Vertex
- {
- float m_x;
- float m_y;
- float m_z;
- };
-
- 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 * 2.0f - 1.0f;
-
- vertex->m_x = -1.0f;
- vertex->m_y = -1.0f;
- vertex->m_z = depth;
- vertex++;
- vertex->m_x = 1.0f;
- vertex->m_y = -1.0f;
- vertex->m_z = depth;
- vertex++;
- vertex->m_x = -1.0f;
- vertex->m_y = 1.0f;
- vertex->m_z = depth;
- vertex++;
- vertex->m_x = 1.0f;
- vertex->m_y = 1.0f;
- vertex->m_z = depth;
- }
-
- vb.update(0, 4*_clearQuad.m_decl.m_stride, _clearQuad.m_vb->data);
+ VertexBufferGL& vb = m_vertexBuffers[_clearQuad.m_vb.idx];
+ VertexLayout& layout = _clearQuad.m_layout;
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
ProgramGL& program = m_program[_clearQuad.m_program[numMrt-1].idx];
GL_CHECK(glUseProgram(program.m_id) );
program.bindAttributesBegin();
- program.bindAttributes(vertexDecl, 0);
+ program.bindAttributes(layout, 0);
program.bindAttributesEnd();
- float mrtClear[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS][4];
+ if (m_clearQuadColor.idx == kInvalidHandle)
+ {
+ const UniformRegInfo* infoClearColor = m_uniformReg.find("bgfx_clear_color");
+ if (NULL != infoClearColor)
+ m_clearQuadColor = infoClearColor->m_handle;
+ }
+
+ if (m_clearQuadDepth.idx == kInvalidHandle)
+ {
+ const UniformRegInfo* infoClearDepth = m_uniformReg.find("bgfx_clear_depth");
+ if (NULL != infoClearDepth)
+ m_clearQuadDepth = infoClearDepth->m_handle;
+ }
+
+ float mrtClearDepth[4] = { g_caps.homogeneousDepth ? (_clear.m_depth * 2.0f - 1.0f) : _clear.m_depth };
+ updateUniform(m_clearQuadDepth.idx, mrtClearDepth, sizeof(float)*4);
+
+ float mrtClearColor[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS][4];
if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags)
{
for (uint32_t ii = 0; ii < numMrt; ++ii)
{
uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[ii]);
- bx::memCopy(mrtClear[ii], _palette[index], 16);
+ bx::memCopy(mrtClearColor[ii], _palette[index], 16);
}
}
else
@@ -3804,11 +3843,13 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
for (uint32_t ii = 0; ii < numMrt; ++ii)
{
- bx::memCopy(mrtClear[ii], rgba, 16);
+ bx::memCopy(mrtClearColor[ii], rgba, 16);
}
}
- GL_CHECK(glUniform4fv(0, numMrt, mrtClear[0]) );
+ updateUniform(m_clearQuadColor.idx, mrtClearColor[0], numMrt * sizeof(float) * 4);
+
+ commit(*program.m_constantBuffer);
GL_CHECK(glDrawArrays(GL_TRIANGLE_STRIP
, 0
@@ -3827,7 +3868,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
ShaderGL m_shaders[BGFX_CONFIG_MAX_SHADERS];
ProgramGL m_program[BGFX_CONFIG_MAX_PROGRAMS];
TextureGL m_textures[BGFX_CONFIG_MAX_TEXTURES];
- VertexDecl m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS];
+ VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS];
FrameBufferGL m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS];
UniformRegistry m_uniformReg;
void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
@@ -3850,6 +3891,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
float m_maxAnisotropyDefault;
int32_t m_maxMsaa;
GLuint m_vao;
+ uint16_t m_maxLabelLen;
bool m_blitSupported;
bool m_readBackSupported;
bool m_vaoSupport;
@@ -3864,6 +3906,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
bool m_occlusionQuerySupport;
bool m_atocSupport;
bool m_conservativeRasterSupport;
+ bool m_imageLoadStoreSupport;
bool m_flip;
uint64_t m_hash;
@@ -3875,6 +3918,9 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
GlContext m_glctx;
bool m_needPresent;
+ UniformHandle m_clearQuadColor;
+ UniformHandle m_clearQuadDepth;
+
const char* m_vendor;
const char* m_renderer;
const char* m_version;
@@ -4020,7 +4066,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
{
case GL_INT:
case GL_UNSIGNED_INT:
- return UniformType::Int1;
+ return UniformType::Sampler;
case GL_FLOAT:
case GL_FLOAT_VEC2:
@@ -4076,7 +4122,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
case GL_IMAGE_CUBE:
case GL_INT_IMAGE_CUBE:
case GL_UNSIGNED_INT_IMAGE_CUBE:
- return UniformType::Int1;
+ return UniformType::Sampler;
};
BX_CHECK(false, "Unrecognized GL type 0x%04x.", _type);
@@ -4462,7 +4508,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
m_instanceData[used] = 0xffff;
}
- void ProgramGL::bindAttributes(const VertexDecl& _vertexDecl, uint32_t _baseVertex)
+ void ProgramGL::bindAttributes(const VertexLayout& _layout, uint32_t _baseVertex)
{
for (uint32_t ii = 0, iiEnd = m_usedCount; ii < iiEnd; ++ii)
{
@@ -4473,16 +4519,16 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
AttribType::Enum type;
bool normalized;
bool asInt;
- _vertexDecl.decode(attr, num, type, normalized, asInt);
+ _layout.decode(attr, num, type, normalized, asInt);
if (-1 != loc)
{
- if (UINT16_MAX != _vertexDecl.m_attributes[attr])
+ if (UINT16_MAX != _layout.m_attributes[attr])
{
GL_CHECK(glEnableVertexAttribArray(loc) );
GL_CHECK(glVertexAttribDivisor(loc, 0) );
- uint32_t baseVertex = _baseVertex*_vertexDecl.m_stride + _vertexDecl.m_offset[attr];
+ uint32_t baseVertex = _baseVertex*_layout.m_stride + _layout.m_offset[attr];
if ( (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL >= 30) || BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 31) )
&& (AttribType::Uint8 == type || AttribType::Int16 == type)
&& !normalized)
@@ -4490,7 +4536,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
GL_CHECK(glVertexAttribIPointer(loc
, num
, s_attribType[type]
- , _vertexDecl.m_stride
+ , _layout.m_stride
, (void*)(uintptr_t)baseVertex)
);
}
@@ -4500,7 +4546,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
, num
, s_attribType[type]
, normalized
- , _vertexDecl.m_stride
+ , _layout.m_stride
, (void*)(uintptr_t)baseVertex)
);
}
@@ -4554,7 +4600,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
void VertexBufferGL::destroy()
{
- GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
+ GL_CHECK(glBindBuffer(m_target, 0) );
GL_CHECK(glDeleteBuffers(1, &m_id) );
}
@@ -4709,22 +4755,20 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (bimg::imageParse(imageContainer, _mem->data, _mem->size) )
{
- uint8_t numMips = imageContainer.m_numMips;
- const uint8_t startLod = uint8_t(bx::uint32_min(_skip, numMips-1) );
- numMips -= startLod;
- const uint16_t numLayers = imageContainer.m_numLayers;
- uint32_t textureWidth;
- uint32_t textureHeight;
- uint32_t textureDepth;
- {
- const bimg::ImageBlockInfo& ibi = bimg::getBlockInfo(bimg::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 = 1 < imageContainer.m_depth
- ? imageContainer.m_depth
- : imageContainer.m_numLayers
- ;
- }
+ const uint8_t startLod = bx::min<uint8_t>(_skip, imageContainer.m_numMips-1);
+
+ bimg::TextureInfo ti;
+ bimg::imageGetSize(
+ &ti
+ , uint16_t(imageContainer.m_width >>startLod)
+ , uint16_t(imageContainer.m_height>>startLod)
+ , uint16_t(imageContainer.m_depth >>startLod)
+ , imageContainer.m_cubeMap
+ , 1 < imageContainer.m_numMips
+ , imageContainer.m_numLayers
+ , imageContainer.m_format
+ );
+ ti.numMips = bx::min<uint8_t>(imageContainer.m_numMips-startLod, ti.numMips);
m_requestedFormat = uint8_t(imageContainer.m_format);
m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) );
@@ -4746,7 +4790,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
target = GL_TEXTURE_3D;
}
- const bool textureArray = 1 < numLayers;
+ const bool textureArray = 1 < ti.numLayers;
if (textureArray)
{
switch (target)
@@ -4758,16 +4802,18 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
}
if (!init(target
- , textureWidth
- , textureHeight
- , textureDepth
- , numMips
- , _flags
- ) )
+ , ti.width
+ , ti.height
+ , textureArray ? ti.numLayers : ti.depth
+ , ti.numMips
+ , _flags
+ ) )
{
return;
}
+ m_numLayers = ti.numLayers;
+
target = isCubeMap()
? GL_TEXTURE_CUBE_MAP_POSITIVE_X
: m_target
@@ -4795,9 +4841,9 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
, getName( (TextureFormat::Enum)m_textureFormat)
, srgb ? "+sRGB " : ""
, getName( (TextureFormat::Enum)m_requestedFormat)
- , numLayers
- , textureWidth
- , textureHeight
+ , ti.numLayers
+ , ti.width
+ , ti.height
, imageContainer.m_cubeMap ? 6 : (1 < imageContainer.m_depth ? imageContainer.m_depth : 0)
, 0 != (m_flags&BGFX_TEXTURE_RT_MASK) ? " (render target)" : ""
);
@@ -4813,22 +4859,22 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
uint8_t* temp = NULL;
if (convert)
{
- temp = (uint8_t*)BX_ALLOC(g_allocator, textureWidth*textureHeight*4);
+ temp = (uint8_t*)BX_ALLOC(g_allocator, ti.width*ti.height*4);
}
- const uint16_t numSides = numLayers * (imageContainer.m_cubeMap ? 6 : 1);
+ const uint16_t numSides = ti.numLayers * (imageContainer.m_cubeMap ? 6 : 1);
for (uint16_t side = 0; side < numSides; ++side)
{
- uint32_t width = textureWidth;
- uint32_t height = textureHeight;
- uint32_t depth = imageContainer.m_depth;
+ uint32_t width = ti.width;
+ uint32_t height = ti.height;
+ uint32_t depth = ti.depth;
GLenum imageTarget = imageContainer.m_cubeMap && !textureArray
? target+side
: target
;
- for (uint8_t lod = 0, num = numMips; lod < num; ++lod)
+ for (uint8_t lod = 0, num = ti.numMips; lod < num; ++lod)
{
width = bx::uint32_max(1, width);
height = bx::uint32_max(1, height);
@@ -4890,8 +4936,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
{
if (compressed)
{
- uint32_t size = bx::uint32_max(1, (width + 3)>>2)
- * bx::uint32_max(1, (height + 3)>>2)
+ uint32_t size = bx::max<uint32_t>(1, (width + 3)>>2)
+ * bx::max<uint32_t>(1, (height + 3)>>2)
* 4*4* bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) )/8
;
@@ -5300,8 +5346,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (0 != m_id)
{
- if (GL_COMPUTE_SHADER != m_type
- && 0 != bx::strCmp(code, "#version 430", 12) )
+ if (GL_COMPUTE_SHADER != m_type)
{
int32_t tempLen = code.getLength() + (4<<10);
char* temp = (char*)alloca(tempLen);
@@ -5493,7 +5538,22 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
&& s_extension[Extension::ARB_shader_texture_lod].m_supported
&& !bx::findIdentifierMatch(code, s_ARB_shader_texture_lod).isEmpty()
;
- const bool usesGpuShader4 = !bx::findIdentifierMatch(code, s_EXT_gpu_shader4).isEmpty();
+
+ const bool usesVertexID = true
+ && !s_extension[Extension::EXT_gpu_shader4].m_supported
+ && !bx::findIdentifierMatch(code, "gl_VertexID").isEmpty()
+ ;
+
+ const bool usesInstanceID = true
+ && !s_extension[Extension::EXT_gpu_shader4].m_supported
+ && !bx::findIdentifierMatch(code, "gl_InstanceID").isEmpty()
+ ;
+
+ const bool usesGpuShader4 = true
+ && s_extension[Extension::EXT_gpu_shader4].m_supported
+ && !bx::findIdentifierMatch(code, s_EXT_gpu_shader4).isEmpty()
+ ;
+
const bool usesGpuShader5 = !bx::findIdentifierMatch(code, s_ARB_gpu_shader5).isEmpty();
const bool usesIUsamplers = !bx::findIdentifierMatch(code, s_uisamplers).isEmpty();
const bool usesUint = !bx::findIdentifierMatch(code, s_uint).isEmpty();
@@ -5508,6 +5568,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
: usesTextureArray
|| usesTexture3D
|| usesIUsamplers
+ || usesVertexID
|| usesUint
|| usesTexelFetch
|| usesGpuShader5
@@ -5516,12 +5577,11 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
: 120
;
- if (0 != version)
- {
- bx::write(&writer, &err, "#version %d\n", version);
- }
+ version = 0 == bx::strCmp(code, "#version 430", 12) ? 430 : version;
- if (usesTextureLod)
+ bx::write(&writer, &err, "#version %d\n", version);
+
+ if (430 > version && usesTextureLod)
{
if (m_type == GL_FRAGMENT_SHADER)
{
@@ -5534,6 +5594,11 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
}
}
+ if (usesInstanceID)
+ {
+ bx::write(&writer, "#extension GL_ARB_draw_instanced : enable\n");
+ }
+
if (usesGpuShader4)
{
bx::write(&writer, "#extension GL_EXT_gpu_shader4 : enable\n");
@@ -5560,7 +5625,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (BX_ENABLED(BX_PLATFORM_OSX) )
{
- bx::write(&writer, "#define texture2DArrayLodEXT texture2DArray\n");
+ bx::write(&writer, "#define texture2DArrayLod texture2DArray\n");
}
else
{
@@ -5584,14 +5649,17 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (130 <= version)
{
- if (m_type == GL_FRAGMENT_SHADER)
- {
- bx::write(&writer, "#define varying in\n");
- }
- else
+ if (430 > version)
{
- bx::write(&writer, "#define attribute in\n");
- bx::write(&writer, "#define varying out\n");
+ if (m_type == GL_FRAGMENT_SHADER)
+ {
+ bx::write(&writer, "#define varying in\n");
+ }
+ else
+ {
+ bx::write(&writer, "#define attribute in\n");
+ bx::write(&writer, "#define varying out\n");
+ }
}
uint32_t fragData = 0;
@@ -5613,7 +5681,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
bx::write(&writer, &err, "out vec4 bgfx_FragData[%d];\n", fragData);
bx::write(&writer, "#define gl_FragData bgfx_FragData\n");
}
- else
+ else if (!bx::findIdentifierMatch(code, "gl_FragColor").isEmpty() )
{
bx::write(&writer, "out vec4 bgfx_FragColor;\n");
bx::write(&writer, "#define gl_FragColor bgfx_FragColor\n");
@@ -5650,7 +5718,16 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
);
}
- bx::write(&writer, code);
+ if (version == 430)
+ {
+ int32_t verLen = bx::strLen("#version 430\n");
+ bx::write(&writer, code.getPtr()+verLen, code.getLength()-verLen);
+ }
+ else
+ {
+ bx::write(&writer, code);
+ }
+
bx::write(&writer, '\0');
}
else if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL >= 31)
@@ -5767,7 +5844,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
code.set(temp);
}
- else if (GL_COMPUTE_SHADER == m_type)
+ else // GL_COMPUTE_SHADER
{
int32_t codeLen = (int32_t)bx::strLen(code);
int32_t tempLen = codeLen + (4<<10);
@@ -5776,15 +5853,19 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
bx::write(&writer
, "#version 430\n"
- "#define texture2DLod textureLod\n"
- "#define texture3DLod textureLod\n"
- "#define textureCubeLod textureLod\n"
- "#define texture2DGrad textureGrad\n"
- "#define texture3DGrad textureGrad\n"
- "#define textureCubeGrad textureGrad\n"
+ "#define texture2DLod textureLod\n"
+ "#define texture2DLodOffset textureLodOffset\n"
+ "#define texture2DArrayLod textureLod\n"
+ "#define texture2DArrayLodOffset textureLodOffset\n"
+ "#define texture3DLod textureLod\n"
+ "#define textureCubeLod textureLod\n"
+ "#define texture2DGrad textureGrad\n"
+ "#define texture3DGrad textureGrad\n"
+ "#define textureCubeGrad textureGrad\n"
);
- bx::write(&writer, code.getPtr()+bx::strLen("#version 430"), codeLen);
+ int32_t verLen = bx::strLen("#version 430\n");
+ bx::write(&writer, code.getPtr()+verLen, codeLen-verLen);
bx::write(&writer, '\0');
code = temp;
@@ -5906,7 +5987,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
attachment = GL_DEPTH_ATTACHMENT;
}
}
- else
+ else if (Access::Write == at.access)
{
buffers[colorIdx] = attachment;
++colorIdx;
@@ -5938,9 +6019,9 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
) );
}
}
- else if (Access::Write == at.access)
+ else
{
- if (1 < texture.m_depth
+ if (1 < texture.m_numLayers
&& !texture.isCubeMap())
{
GL_CHECK(glFramebufferTextureLayer(GL_FRAMEBUFFER
@@ -5965,10 +6046,6 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
) );
}
}
- else
- {
- BX_CHECK(false, "");
- }
needResolve |= (0 != texture.m_rbo) && (0 != texture.m_id);
}
@@ -6166,6 +6243,36 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
GL_CHECK(glInvalidateFramebuffer(GL_FRAMEBUFFER, idx, buffers) );
}
+ void FrameBufferGL::set()
+ {
+ for(uint32_t ii = 0; ii < m_numTh; ++ii)
+ {
+ const Attachment& at = m_attachment[ii];
+
+ if (at.access == Access::Write)
+ {
+ continue;
+ }
+
+ if (isValid(at.handle) )
+ {
+ const TextureGL& texture = s_renderGL->m_textures[at.handle.idx];
+
+ if(0 != (texture.m_flags&BGFX_TEXTURE_COMPUTE_WRITE))
+ {
+ GL_CHECK(glBindImageTexture(ii
+ , texture.m_id
+ , at.mip
+ , GL_FALSE //texture.isLayered() ? GL_TRUE : GL_FALSE
+ , at.layer
+ , s_access[Access::ReadWrite]
+ , s_imageFormat[texture.m_textureFormat])
+ );
+ }
+ }
+ }
+ }
+
void OcclusionQueryGL::create()
{
for (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii)
@@ -6292,6 +6399,10 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
renderDocTriggerCapture();
}
+ m_glctx.makeCurrent(NULL);
+
+ BGFX_GL_PROFILER_BEGIN_LITERAL("rendererSubmit", kColorView);
+
if (1 < m_numWindows
&& m_vaoSupport)
{
@@ -6301,8 +6412,6 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
m_vao = 0;
}
- m_glctx.makeCurrent(NULL);
-
const GLuint defaultVao = m_vao;
if (0 != defaultVao)
{
@@ -6327,12 +6436,14 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (0 < _render->m_iboffset)
{
+ BGFX_PROFILER_SCOPE("bgfx/Update transient index buffer", kColorResource);
TransientIndexBuffer* ib = _render->m_transientIb;
m_indexBuffers[ib->handle.idx].update(0, _render->m_iboffset, ib->data, true);
}
if (0 < _render->m_vboffset)
{
+ BGFX_PROFILER_SCOPE("bgfx/Update transient vertex buffer", kColorResource);
TransientVertexBuffer* vb = _render->m_transientVb;
m_vertexBuffers[vb->handle.idx].update(0, _render->m_vboffset, vb->data, true);
}
@@ -6347,12 +6458,11 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
RenderBind currentBind;
currentBind.clear();
- const bool hmdEnabled = false;
static ViewState viewState;
- viewState.reset(_render, hmdEnabled);
+ viewState.reset(_render);
- uint16_t programIdx = kInvalidHandle;
- uint16_t boundProgramIdx = kInvalidHandle;
+ ProgramHandle currentProgram = BGFX_INVALID_HANDLE;
+ ProgramHandle boundProgram = BGFX_INVALID_HANDLE;
SortKey key;
uint16_t view = UINT16_MAX;
FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS };
@@ -6406,18 +6516,14 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
m_occlusionQuery.resolve(_render);
}
- uint8_t eye = 0;
-
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
{
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
- bool viewRestart = false;
- uint8_t restartState = 0;
viewState.m_rect = _render->m_view[0].m_rect;
-
int32_t numItems = _render->m_numRenderItems;
- for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;)
+
+ for (int32_t item = 0; item < numItems;)
{
const uint64_t encodedKey = _render->m_sortKeys[item];
const bool isCompute = key.decode(encodedKey, _render->m_viewRemap);
@@ -6435,17 +6541,15 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (viewChanged)
{
- if (1 == restartState)
+ view = key.m_view;
+ currentProgram = BGFX_INVALID_HANDLE;
+
+ if (item > 1)
{
- restartState = 2;
- item = restartItem;
- restartItem = numItems;
- view = UINT16_MAX;
- continue;
+ profiler.end();
}
- view = key.m_view;
- programIdx = kInvalidHandle;
+ BGFX_GL_PROFILER_END();
if (_render->m_view[view].m_fbh.idx != fbh.idx)
{
@@ -6454,55 +6558,12 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
resolutionHeight = setFrameBuffer(fbh, resolutionHeight, discardFlags);
}
- viewRestart = ( (BGFX_VIEW_STEREO == (_render->m_view[view].m_flags & BGFX_VIEW_STEREO) ) );
- viewRestart &= hmdEnabled;
- if (viewRestart)
- {
- if (0 == restartState)
- {
- restartState = 1;
- restartItem = item - 1;
- }
-
- eye = (restartState - 1) & 1;
- restartState &= 1;
- }
- else
- {
- eye = 0;
- }
-
- if (item > 1)
- {
- profiler.end();
- }
+ setViewType(view, " ");
+ BGFX_GL_PROFILER_BEGIN(view, kColorView);
profiler.begin(view);
viewState.m_rect = _render->m_view[view].m_rect;
- if (viewRestart)
- {
- if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) )
- {
- char* viewName = s_viewName[view];
- viewName[3] = ' ';
- viewName[4] = eye ? 'R' : 'L';
- GL_CHECK(glInsertEventMarker(0, viewName) );
- }
-
- viewState.m_rect.m_x = eye * (viewState.m_rect.m_width+1)/2;
- viewState.m_rect.m_width /= 2;
- }
- else
- {
- if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) )
- {
- char* viewName = s_viewName[view];
- viewName[3] = ' ';
- viewName[4] = ' ';
- GL_CHECK(glInsertEventMarker(0, viewName) );
- }
- }
const Rect& scissorRect = _render->m_view[view].m_scissor;
viewHasScissor = !scissorRect.isZero();
@@ -6537,19 +6598,16 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
{
wasCompute = true;
- if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) )
- {
- char* viewName = s_viewName[view];
- viewName[3] = 'C';
- GL_CHECK(glInsertEventMarker(0, viewName) );
- }
+ setViewType(view, "C");
+ BGFX_GL_PROFILER_END();
+ BGFX_GL_PROFILER_BEGIN(view, kColorCompute);
}
if (computeSupported)
{
const RenderCompute& compute = renderItem.compute;
- ProgramGL& program = m_program[key.m_program];
+ ProgramGL& program = m_program[key.m_program.idx];
GL_CHECK(glUseProgram(program.m_id) );
GLbitfield barrier = 0;
@@ -6569,24 +6627,16 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
case Binding::Image:
{
- if (Access::Read == bind.m_access)
- {
- TextureGL& texture = m_textures[bind.m_idx];
- texture.commit(ii, uint32_t(texture.m_flags), _render->m_colorPalette);
- }
- else
- {
- const TextureGL& texture = m_textures[bind.m_idx];
- GL_CHECK(glBindImageTexture(ii
- , texture.m_id
- , bind.m_mip
- , texture.isCubeMap() ? GL_TRUE : GL_FALSE
- , 0
- , s_access[bind.m_access]
- , s_imageFormat[bind.m_format])
- );
- barrier |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
- }
+ const TextureGL& texture = m_textures[bind.m_idx];
+ GL_CHECK(glBindImageTexture(ii
+ , texture.m_id
+ , bind.m_mip
+ , texture.isCubeMap() || texture.m_target == GL_TEXTURE_2D_ARRAY ? GL_TRUE : GL_FALSE
+ , 0
+ , s_access[bind.m_access]
+ , s_imageFormat[bind.m_format])
+ );
+ barrier |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
}
break;
@@ -6620,10 +6670,11 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
commit(*program.m_constantBuffer);
}
- viewState.setPredefined<1>(this, view, eye, program, _render, compute);
+ viewState.setPredefined<1>(this, view, program, _render, compute);
if (isValid(compute.m_indirectBuffer) )
{
+ barrier |= GL_COMMAND_BARRIER_BIT;
const VertexBufferGL& vb = m_vertexBuffers[compute.m_indirectBuffer.idx];
if (currentState.m_indirectBuffer.idx != compute.m_indirectBuffer.idx)
{
@@ -6667,12 +6718,9 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
{
wasCompute = false;
- if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) )
- {
- char* viewName = s_viewName[view];
- viewName[3] = ' ';
- GL_CHECK(glInsertEventMarker(0, viewName) );
- }
+ setViewType(view, " ");
+ BGFX_GL_PROFILER_END();
+ BGFX_GL_PROFILER_BEGIN(view, kColorDraw);
}
const RenderDraw& draw = renderItem.draw;
@@ -7041,13 +7089,13 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
bool bindAttribs = false;
rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd);
- if (key.m_program != programIdx)
+ if (key.m_program.idx != currentProgram.idx)
{
- programIdx = key.m_program;
- GLuint id = kInvalidHandle == programIdx ? 0 : m_program[programIdx].m_id;
+ currentProgram = key.m_program;
+ GLuint id = isValid(currentProgram) ? m_program[currentProgram.idx].m_id : 0;
// Skip rendering if program index is valid, but program is invalid.
- programIdx = 0 == id ? kInvalidHandle : programIdx;
+ currentProgram = 0 == id ? ProgramHandle{kInvalidHandle} : currentProgram;
GL_CHECK(glUseProgram(id) );
programChanged =
@@ -7055,9 +7103,9 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
bindAttribs = true;
}
- if (kInvalidHandle != programIdx)
+ if (isValid(currentProgram) )
{
- ProgramGL& program = m_program[programIdx];
+ ProgramGL& program = m_program[currentProgram.idx];
if (constantsChanged
&& NULL != program.m_constantBuffer)
@@ -7065,7 +7113,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
commit(*program.m_constantBuffer);
}
- viewState.setPredefined<1>(this, view, eye, program, _render, draw);
+ viewState.setPredefined<1>(this, view, program, _render, draw);
{
for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage)
@@ -7111,11 +7159,12 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
{
bool diffStreamHandles = false;
- for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask)
+ for (uint32_t idx = 0, streamMask = draw.m_streamMask
; 0 != streamMask
- ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask)
+ ; streamMask >>= 1, idx += 1
)
{
+ const uint32_t ntz = bx::uint32_cnttz(streamMask);
streamMask >>= ntz;
idx += ntz;
@@ -7138,11 +7187,12 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
currentState.m_instanceDataOffset = draw.m_instanceDataOffset;
currentState.m_instanceDataStride = draw.m_instanceDataStride;
- for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask)
+ for (uint32_t idx = 0, streamMask = draw.m_streamMask
; 0 != streamMask
- ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask)
+ ; streamMask >>= 1, idx += 1
)
{
+ const uint32_t ntz = bx::uint32_cnttz(streamMask);
streamMask >>= ntz;
idx += ntz;
@@ -7171,11 +7221,12 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (0 != currentState.m_streamMask)
{
bool diffStartVertex = false;
- for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask)
+ for (uint32_t idx = 0, streamMask = draw.m_streamMask
; 0 != streamMask
- ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask)
+ ; streamMask >>= 1, idx += 1
)
{
+ const uint32_t ntz = bx::uint32_cnttz(streamMask);
streamMask >>= ntz;
idx += ntz;
@@ -7188,32 +7239,35 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (bindAttribs || diffStartVertex)
{
- if(kInvalidHandle != boundProgramIdx)
+ if (isValid(boundProgram) )
{
- ProgramGL& boundProgram = m_program[boundProgramIdx];
- boundProgram.unbindAttributes();
+ m_program[boundProgram.idx].unbindAttributes();
+ boundProgram = BGFX_INVALID_HANDLE;
}
- boundProgramIdx = programIdx;
+ boundProgram = currentProgram;
program.bindAttributesBegin();
if (UINT8_MAX != draw.m_streamMask)
{
- for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask)
+ for (uint32_t idx = 0, streamMask = draw.m_streamMask
; 0 != streamMask
- ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask)
+ ; streamMask >>= 1, idx += 1
)
{
+ const uint32_t ntz = bx::uint32_cnttz(streamMask);
streamMask >>= ntz;
idx += ntz;
currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex;
const VertexBufferGL& vb = m_vertexBuffers[draw.m_stream[idx].m_handle.idx];
- uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[idx].m_decl.idx : vb.m_decl.idx;
+ const uint16_t decl = isValid(draw.m_stream[idx].m_layoutHandle)
+ ? draw.m_stream[idx].m_layoutHandle.idx
+ : vb.m_layoutHandle.idx;
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
- program.bindAttributes(m_vertexDecls[decl], draw.m_stream[idx].m_startVertex);
+ program.bindAttributes(m_vertexLayouts[decl], draw.m_stream[idx].m_startVertex);
}
}
@@ -7233,19 +7287,20 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
uint32_t numVertices = draw.m_numVertices;
if (UINT32_MAX == numVertices)
{
- for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask)
+ for (uint32_t idx = 0, streamMask = draw.m_streamMask
; 0 != streamMask
- ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask)
+ ; streamMask >>= 1, idx += 1
)
{
+ const uint32_t ntz = bx::uint32_cnttz(streamMask);
streamMask >>= ntz;
idx += ntz;
const VertexBufferGL& vb = m_vertexBuffers[draw.m_stream[idx].m_handle.idx];
- uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[idx].m_decl.idx : vb.m_decl.idx;
- const VertexDecl& vertexDecl = m_vertexDecls[decl];
+ uint16_t decl = !isValid(vb.m_layoutHandle) ? draw.m_stream[idx].m_layoutHandle.idx : vb.m_layoutHandle.idx;
+ const VertexLayout& layout = m_vertexLayouts[decl];
- numVertices = bx::uint32_min(numVertices, vb.m_size/vertexDecl.m_stride);
+ numVertices = bx::uint32_min(numVertices, vb.m_size/layout.m_stride);
}
}
@@ -7384,10 +7439,17 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
}
}
- if(kInvalidHandle != boundProgramIdx)
+ if (isValid(boundProgram) )
+ {
+ m_program[boundProgram.idx].unbindAttributes();
+ boundProgram = BGFX_INVALID_HANDLE;
+ }
+
+ if (wasCompute)
{
- ProgramGL& boundProgram = m_program[boundProgramIdx];
- boundProgram.unbindAttributes();
+ setViewType(view, "C");
+ BGFX_GL_PROFILER_END();
+ BGFX_GL_PROFILER_BEGIN(view, kColorCompute);
}
submitBlit(bs, BGFX_CONFIG_MAX_VIEWS);
@@ -7414,6 +7476,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
}
}
+ BGFX_GL_PROFILER_END();
+
m_glctx.makeCurrent(NULL);
int64_t timeEnd = bx::getHPCounter();
int64_t frameTime = timeEnd - timeBegin;
@@ -7459,6 +7523,8 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
{
+ BGFX_GL_PROFILER_BEGIN_LITERAL("debugstats", kColorFrame);
+
m_needPresent = true;
TextVideoMem& tvm = m_textVideoMem;
@@ -7627,10 +7693,16 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
}
blit(this, _textVideoMemBlitter, tvm);
+
+ BGFX_GL_PROFILER_END();
}
else if (_render->m_debug & BGFX_DEBUG_TEXT)
{
+ BGFX_GL_PROFILER_BEGIN_LITERAL("debugtext", kColorFrame);
+
blit(this, _textVideoMemBlitter, _render->m_textVideoMem);
+
+ BGFX_GL_PROFILER_END();
}
}
} } // namespace bgfx