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