diff --git a/src/bgfx.cpp b/src/bgfx.cpp index f8c800376..b5fb396d5 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -1148,6 +1148,38 @@ namespace bgfx BX_TRACE("Max FB attachments: %d", g_caps.maxFBAttachments); } + TextureFormat::Enum getViableTextureFormat(const ImageContainer& _imageContainer) + { + const uint32_t formatCaps = g_caps.formats[_imageContainer.m_format]; + bool convert = 0 == formatCaps; + + if (_imageContainer.m_cubeMap) + { + convert |= 0 == (formatCaps & BGFX_CAPS_FORMAT_TEXTURE_CUBE) + && 0 != (formatCaps & BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED) + ; + } + else if (_imageContainer.m_depth > 1) + { + convert |= 0 == (formatCaps & BGFX_CAPS_FORMAT_TEXTURE_3D) + && 0 != (formatCaps & BGFX_CAPS_FORMAT_TEXTURE_3D_EMULATED) + ; + } + else + { + convert |= 0 == (formatCaps & BGFX_CAPS_FORMAT_TEXTURE_2D) + && 0 != (formatCaps & BGFX_CAPS_FORMAT_TEXTURE_2D_EMULATED) + ; + } + + if (convert) + { + return TextureFormat::BGRA8; + } + + return _imageContainer.m_format; + } + static TextureFormat::Enum s_emulatedFormats[] = { TextureFormat::BC1, diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 0de275352..f0db3bafc 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -332,6 +332,7 @@ namespace bgfx void release(const Memory* _mem); const char* getAttribName(Attrib::Enum _attr); void getTextureSizeFromRatio(BackbufferRatio::Enum _ratio, uint16_t& _width, uint16_t& _height); + TextureFormat::Enum getViableTextureFormat(const ImageContainer& _imageContainer); inline uint32_t castfu(float _value) { diff --git a/src/image.cpp b/src/image.cpp index 796abe881..a9da90ead 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -1218,18 +1218,18 @@ namespace bgfx void packR5G6B5(void* _dst, const float* _src) { *( (uint16_t*)_dst) = 0 - | uint16_t(toUnorm(_src[0], 31.0f) ) + | uint16_t(toUnorm(_src[0], 31.0f)<<11) | uint16_t(toUnorm(_src[1], 63.0f)<< 5) - | uint16_t(toUnorm(_src[2], 31.0f)<<11) + | uint16_t(toUnorm(_src[2], 31.0f) ) ; } void unpackR5G6B5(float* _dst, const void* _src) { uint16_t packed = *( (const uint16_t*)_src); - _dst[0] = float( ( (packed ) & 0x1f) ) / 31.0f; + _dst[0] = float( ( (packed>>11) & 0x1f) ) / 31.0f; _dst[1] = float( ( (packed>> 5) & 0x3f) ) / 63.0f; - _dst[2] = float( ( (packed>>11) & 0x1f) ) / 31.0f; + _dst[2] = float( ( (packed ) & 0x1f) ) / 31.0f; } // RGBA4 diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 4446d6b03..76d243099 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -3930,22 +3930,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_width = textureWidth; m_height = textureHeight; m_depth = imageContainer.m_depth; - m_requestedFormat = (uint8_t)imageContainer.m_format; - m_textureFormat = (uint8_t)imageContainer.m_format; - - const TextureFormatInfo& tfi = s_textureFormat[m_requestedFormat]; - const bool convert = DXGI_FORMAT_UNKNOWN == tfi.m_fmt; - - uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); - if (convert) - { - m_textureFormat = (uint8_t)TextureFormat::BGRA8; - bpp = 32; - } + m_requestedFormat = uint8_t(imageContainer.m_format); + m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) ); + const bool convert = m_textureFormat != m_requestedFormat; + const uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); if (imageContainer.m_cubeMap) { - m_type = TextureCube; + m_type = TextureCube; } else if (imageContainer.m_depth > 1) { @@ -4056,7 +4048,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (format == DXGI_FORMAT_UNKNOWN) { // not swizzled and not sRGB, or sRGB unsupported - format = s_textureFormat[m_textureFormat].m_fmt; + format = s_textureFormat[m_textureFormat].m_fmt; srvd.Format = s_textureFormat[m_textureFormat].m_fmtSrv; } diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 409d33bce..775c93cd1 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -3769,18 +3769,10 @@ data.NumQualityLevels = 0; m_width = textureWidth; m_height = textureHeight; m_depth = imageContainer.m_depth; - m_requestedFormat = (uint8_t)imageContainer.m_format; - m_textureFormat = (uint8_t)imageContainer.m_format; - - const TextureFormatInfo& tfi = s_textureFormat[m_requestedFormat]; - const bool convert = DXGI_FORMAT_UNKNOWN == tfi.m_fmt; - - uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); - if (convert) - { - m_textureFormat = (uint8_t)TextureFormat::BGRA8; - bpp = 32; - } + m_requestedFormat = uint8_t(imageContainer.m_format); + m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) ); + const bool convert = m_textureFormat != m_requestedFormat; + const uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); if (imageContainer.m_cubeMap) { diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 15a72b6b5..c934deda8 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -2828,16 +2828,11 @@ namespace bgfx { namespace d3d9 m_height = textureHeight; m_depth = imageContainer.m_depth; m_numMips = numMips; - m_requestedFormat = - m_textureFormat = uint8_t(imageContainer.m_format); + m_requestedFormat = uint8_t(imageContainer.m_format); + m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) ); + const bool convert = m_textureFormat != m_requestedFormat; - const TextureFormatInfo& tfi = s_textureFormat[m_requestedFormat]; uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); - if (D3DFMT_UNKNOWN == tfi.m_fmt) - { - m_textureFormat = (uint8_t)TextureFormat::BGRA8; - bpp = 32; - } if (imageContainer.m_cubeMap) { @@ -2880,8 +2875,6 @@ namespace bgfx { namespace d3d9 && imageContainer.m_format != TextureFormat::BC5 ; - const bool convert = m_textureFormat != m_requestedFormat; - for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side) { uint32_t width = textureWidth; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index b7561cc5b..fb074345f 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -260,7 +260,7 @@ namespace bgfx { namespace gl { GL_RGBA32I, GL_ZERO, GL_RGBA, GL_INT, false }, // RGBA32I { GL_RGBA32UI, GL_ZERO, GL_RGBA, GL_UNSIGNED_INT, false }, // RGBA32U { GL_RGBA32F, GL_ZERO, GL_RGBA, GL_FLOAT, false }, // RGBA32F - { GL_RGB565, GL_ZERO, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false }, // R5G6B5 + { GL_RGB565, GL_ZERO, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, false }, // R5G6B5 { GL_RGBA4, GL_ZERO, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, false }, // RGBA4 { GL_RGB5_A1, GL_ZERO, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, false }, // RGB5A1 { GL_RGB10_A2, GL_ZERO, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false }, // RGB10A2 @@ -3951,7 +3951,7 @@ namespace bgfx { namespace gl } } - bool TextureGL::init(GLenum _target, uint32_t _width, uint32_t _height, uint32_t _depth, TextureFormat::Enum _format, uint8_t _numMips, uint32_t _flags) + bool TextureGL::init(GLenum _target, uint32_t _width, uint32_t _height, uint32_t _depth, uint8_t _numMips, uint32_t _flags) { m_target = _target; m_numMips = _numMips; @@ -3959,9 +3959,7 @@ namespace bgfx { namespace gl m_width = _width; m_height = _height; m_depth = _depth; - m_currentSamplerHash = UINT32_MAX; - m_requestedFormat = - m_textureFormat = uint8_t(_format); + m_currentSamplerHash = UINT32_MAX; const bool writeOnly = 0 != (m_flags&BGFX_TEXTURE_RT_WRITE_ONLY); const bool computeWrite = 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE ); @@ -3972,7 +3970,7 @@ namespace bgfx { namespace gl BX_CHECK(0 != m_id, "Failed to generate texture id."); GL_CHECK(glBindTexture(_target, m_id) ); - const TextureFormatInfo& tfi = s_textureFormat[_format]; + const TextureFormatInfo& tfi = s_textureFormat[m_textureFormat]; m_fmt = tfi.m_fmt; m_type = tfi.m_type; @@ -3981,11 +3979,9 @@ namespace bgfx { namespace gl && !s_textureFormat[m_requestedFormat].m_supported && !s_renderGL->m_textureSwizzleSupport ; - const bool compressed = isCompressed(TextureFormat::Enum(m_requestedFormat) ); - const bool convert = false - || (compressed && m_textureFormat != m_requestedFormat) + const bool convert = false + || m_textureFormat != m_requestedFormat || swizzle - || !s_textureFormat[m_requestedFormat].m_supported ; if (convert) @@ -4097,6 +4093,9 @@ namespace bgfx { namespace gl textureDepth = imageContainer.m_depth; } + m_requestedFormat = uint8_t(imageContainer.m_format); + m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) ); + GLenum target = GL_TEXTURE_2D; if (imageContainer.m_cubeMap) { @@ -4111,7 +4110,6 @@ namespace bgfx { namespace gl , textureWidth , textureHeight , textureDepth - , imageContainer.m_format , numMips , _flags ) ) diff --git a/src/renderer_gl.h b/src/renderer_gl.h index 91c49c22f..47f2c5271 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -1120,7 +1120,7 @@ namespace bgfx { namespace gl { } - bool init(GLenum _target, uint32_t _width, uint32_t _height, uint32_t _depth, TextureFormat::Enum _format, uint8_t _numMips, uint32_t _flags); + bool init(GLenum _target, uint32_t _width, uint32_t _height, uint32_t _depth, uint8_t _numMips, uint32_t _flags); void create(const Memory* _mem, uint32_t _flags, uint8_t _skip); void destroy(); void overrideInternal(uintptr_t _ptr); diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index 08faee495..ffb2c38a7 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -1855,20 +1855,10 @@ namespace bgfx { namespace mtl const uint32_t textureHeight = bx::uint32_max(blockInfo.blockHeight, imageContainer.m_height>>startLod); m_flags = _flags; - m_requestedFormat = (uint8_t)imageContainer.m_format; - m_textureFormat = MTLPixelFormatInvalid == s_textureFormat[m_requestedFormat].m_fmt - ? uint8_t(TextureFormat::BGRA8) - : m_requestedFormat - ; - - const bool convert = m_requestedFormat != m_textureFormat; - - uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); - if (convert) - { - m_textureFormat = (uint8_t)TextureFormat::RGBA8; - bpp = 32; - } + m_requestedFormat = uint8_t(imageContainer.m_format); + m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) ); + const bool convert = m_textureFormat != m_requestedFormat; + const uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); TextureDescriptor desc = s_renderMtl->m_textureDescriptor;