From 856208328c6a93eb94933d7cb9444c78bc9f5e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 19 Feb 2026 16:46:41 -0800 Subject: [PATCH] Use back buffer format when capturing screen shot. (#3603) --- bindings/d/package.d | 2 +- examples/07-callback/callback.cpp | 47 +++++++++++++++++--- include/bgfx/bgfx.h | 2 + include/bgfx/c99/bgfx.h | 2 +- include/bgfx/defines.h | 2 +- scripts/bgfx.idl | 2 +- scripts/temp.bgfx.h | 2 +- scripts/temp.bgfx.hpp | 2 + src/bgfx.cpp | 42 +++++++++++++++--- src/renderer_d3d11.cpp | 74 +++++-------------------------- src/renderer_d3d12.cpp | 33 ++++++++++---- src/renderer_gl.cpp | 5 ++- src/renderer_mtl.mm | 34 ++++++-------- src/renderer_vk.cpp | 54 +++++++--------------- 14 files changed, 157 insertions(+), 146 deletions(-) diff --git a/bindings/d/package.d b/bindings/d/package.d index 5ca264289..16e8bd378 100644 --- a/bindings/d/package.d +++ b/bindings/d/package.d @@ -9,7 +9,7 @@ import bindbc.common.types: c_int64, c_uint64, va_list; import bindbc.bgfx.config; static import bgfx.impl; -enum uint apiVersion = 138; +enum uint apiVersion = 139; alias ViewID = ushort; diff --git a/examples/07-callback/callback.cpp b/examples/07-callback/callback.cpp index 52d9af4b3..e0c85beec 100644 --- a/examples/07-callback/callback.cpp +++ b/examples/07-callback/callback.cpp @@ -80,13 +80,48 @@ void savePng(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t } } -void saveTga(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, bool _grayscale, bool _yflip) +void saveTga(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, bimg::TextureFormat::Enum _format, bool _yflip) { bx::FileWriter writer; bx::Error err; if (bx::open(&writer, _filePath, false, &err) ) { - bimg::imageWriteTga(&writer, _width, _height, _srcPitch, _src, _grayscale, _yflip, &err); + if (bimg::TextureFormat::RGBA8 == _format) + { + bimg::imageSwizzleBgra8(const_cast(_src), _srcPitch, _width, _height, _src, _srcPitch); + bimg::imageWriteTga(&writer, _width, _height, _srcPitch, _src, false, _yflip); + } + else if (bimg::TextureFormat::BGRA8 == _format) + { + bimg::imageWriteTga(&writer, _width, _height, _srcPitch, _src, false, _yflip); + } + else + { + bx::DefaultAllocator allocator; + + const uint8_t dstBpp = bimg::getBitsPerPixel(bimg::TextureFormat::BGRA8); + const uint32_t dstPitch = _width * dstBpp / 8; + const uint32_t dstSize = _height * dstPitch; + + void* dst = bx::alloc(&allocator, dstSize); + + bimg::imageConvert( + &allocator + , dst + , bimg::TextureFormat::BGRA8 + , _src + , bimg::TextureFormat::Enum(_format) + , _width + , _height + , 1 + ); + + bimg::imageWriteTga(&writer, _width, _height, _srcPitch, _src, false, _yflip); + + bx::free(&allocator, dst); + } + + bimg::imageWriteTga(&writer, _width, _height, _srcPitch, _src, false, _yflip, &err); bx::close(&writer); } } @@ -184,17 +219,17 @@ struct BgfxCallback : public bgfx::CallbackI } } - virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t /*_size*/, bool _yflip) override + virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, bgfx::TextureFormat::Enum _format, const void* _data, uint32_t /*_size*/, bool _yflip) override { char temp[1024]; // Save screen shot as PNG. bx::snprintf(temp, BX_COUNTOF(temp), "%s.png", _filePath); - savePng(temp, _width, _height, _pitch, _data, bimg::TextureFormat::BGRA8, _yflip); + savePng(temp, _width, _height, _pitch, _data, bimg::TextureFormat::Enum(_format), _yflip); // Save screen shot as TGA. bx::snprintf(temp, BX_COUNTOF(temp), "%s.tga", _filePath); - saveTga(temp, _width, _height, _pitch, _data, false, _yflip); + saveTga(temp, _width, _height, _pitch, _data, bimg::TextureFormat::Enum(_format), _yflip); } virtual void captureBegin(uint32_t _width, uint32_t _height, uint32_t /*_pitch*/, bgfx::TextureFormat::Enum /*_format*/, bool _yflip) override @@ -345,7 +380,7 @@ public: // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH - , 0x303030ff + , 0x383028ff , 1.0f , 0 ); diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index 86bf80573..2356b357a 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -617,6 +617,7 @@ namespace bgfx /// @param[in] _height Image height. /// @param[in] _pitch Number of bytes to skip between the start of /// each horizontal line of the image. + /// @param[in] _format Texture format. See: `TextureFormat::Enum`. /// @param[in] _data Image data. /// @param[in] _size Image size. /// @param[in] _yflip If true, image origin is bottom left. @@ -628,6 +629,7 @@ namespace bgfx , uint32_t _width , uint32_t _height , uint32_t _pitch + , TextureFormat::Enum _format , const void* _data , uint32_t _size , bool _yflip diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index 3d08e28e9..55e0a889d 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -493,7 +493,7 @@ typedef struct bgfx_callback_vtbl_s uint32_t (*cache_read_size)(bgfx_callback_interface_t* _this, uint64_t _id); bool (*cache_read)(bgfx_callback_interface_t* _this, uint64_t _id, void* _data, uint32_t _size); void (*cache_write)(bgfx_callback_interface_t* _this, uint64_t _id, const void* _data, uint32_t _size); - void (*screen_shot)(bgfx_callback_interface_t* _this, const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t _size, bool _yflip); + void (*screen_shot)(bgfx_callback_interface_t* _this, const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, bgfx_texture_format_t _format, const void* _data, uint32_t _size, bool _yflip); void (*capture_begin)(bgfx_callback_interface_t* _this, uint32_t _width, uint32_t _height, uint32_t _pitch, bgfx_texture_format_t _format, bool _yflip); void (*capture_end)(bgfx_callback_interface_t* _this); void (*capture_frame)(bgfx_callback_interface_t* _this, const void* _data, uint32_t _size); diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index 4f7cce8b2..2fbdf2c99 100644 --- a/include/bgfx/defines.h +++ b/include/bgfx/defines.h @@ -15,7 +15,7 @@ #ifndef BGFX_DEFINES_H_HEADER_GUARD #define BGFX_DEFINES_H_HEADER_GUARD -#define BGFX_API_VERSION UINT32_C(138) +#define BGFX_API_VERSION UINT32_C(139) /** * Color RGB/alpha/depth write. When it's not specified write will be disabled. diff --git a/scripts/bgfx.idl b/scripts/bgfx.idl index 6be4d3e0d..b9f6f8f11 100644 --- a/scripts/bgfx.idl +++ b/scripts/bgfx.idl @@ -1,7 +1,7 @@ -- vim: syntax=lua -- bgfx interface -version(138) +version(139) typedef "bool" typedef "char" diff --git a/scripts/temp.bgfx.h b/scripts/temp.bgfx.h index 5f00b1ed4..c07da4092 100644 --- a/scripts/temp.bgfx.h +++ b/scripts/temp.bgfx.h @@ -98,7 +98,7 @@ typedef struct bgfx_callback_vtbl_s uint32_t (*cache_read_size)(bgfx_callback_interface_t* _this, uint64_t _id); bool (*cache_read)(bgfx_callback_interface_t* _this, uint64_t _id, void* _data, uint32_t _size); void (*cache_write)(bgfx_callback_interface_t* _this, uint64_t _id, const void* _data, uint32_t _size); - void (*screen_shot)(bgfx_callback_interface_t* _this, const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t _size, bool _yflip); + void (*screen_shot)(bgfx_callback_interface_t* _this, const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, bgfx_texture_format_t _format, const void* _data, uint32_t _size, bool _yflip); void (*capture_begin)(bgfx_callback_interface_t* _this, uint32_t _width, uint32_t _height, uint32_t _pitch, bgfx_texture_format_t _format, bool _yflip); void (*capture_end)(bgfx_callback_interface_t* _this); void (*capture_frame)(bgfx_callback_interface_t* _this, const void* _data, uint32_t _size); diff --git a/scripts/temp.bgfx.hpp b/scripts/temp.bgfx.hpp index 1040d85db..a5b02518f 100644 --- a/scripts/temp.bgfx.hpp +++ b/scripts/temp.bgfx.hpp @@ -186,6 +186,7 @@ $structs /// @param[in] _height Image height. /// @param[in] _pitch Number of bytes to skip between the start of /// each horizontal line of the image. + /// @param[in] _format Texture format. See: `TextureFormat::Enum`. /// @param[in] _data Image data. /// @param[in] _size Image size. /// @param[in] _yflip If true, image origin is bottom left. @@ -197,6 +198,7 @@ $structs , uint32_t _width , uint32_t _height , uint32_t _pitch + , TextureFormat::Enum _format , const void* _data , uint32_t _size , bool _yflip diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 46252216b..fc1a98fad 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -226,7 +226,7 @@ namespace bgfx { } - virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t _size, bool _yflip) override + virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, TextureFormat::Enum _format, const void* _data, uint32_t _size, bool _yflip) override { BX_UNUSED(_filePath, _width, _height, _pitch, _data, _size, _yflip); @@ -238,7 +238,39 @@ namespace bgfx bx::FileWriter writer; if (bx::open(&writer, filePath) ) { - bimg::imageWriteTga(&writer, _width, _height, _pitch, _data, false, _yflip); + if (TextureFormat::RGBA8 == _format) + { + bimg::imageSwizzleBgra8(const_cast(_data), _pitch, _width, _height, _data, _pitch); + bimg::imageWriteTga(&writer, _width, _height, _pitch, _data, false, _yflip); + } + else if (TextureFormat::BGRA8 == _format) + { + bimg::imageWriteTga(&writer, _width, _height, _pitch, _data, false, _yflip); + } + else + { + const uint8_t dstBpp = bimg::getBitsPerPixel(bimg::TextureFormat::BGRA8); + const uint32_t dstPitch = _width * dstBpp / 8; + const uint32_t dstSize = _height * dstPitch; + + void* dst = bx::alloc(g_allocator, dstSize); + + bimg::imageConvert( + g_allocator + , dst + , bimg::TextureFormat::BGRA8 + , _data + , bimg::TextureFormat::Enum(_format) + , _width + , _height + , 1 + ); + + bimg::imageWriteTga(&writer, _width, _height, _pitch, _data, false, _yflip); + + bx::free(g_allocator, dst); + } + bx::close(&writer); } } @@ -3618,7 +3650,7 @@ namespace bgfx } Resolution::Resolution() - : formatColor(TextureFormat::BGRA8) + : formatColor(TextureFormat::RGBA8) , formatDepthStencil(TextureFormat::D24S8) , width(1280) , height(720) @@ -6132,9 +6164,9 @@ namespace bgfx m_interface->vtbl->cache_write(m_interface, _id, _data, _size); } - virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t _size, bool _yflip) override + virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, TextureFormat::Enum _format, const void* _data, uint32_t _size, bool _yflip) override { - m_interface->vtbl->screen_shot(m_interface, _filePath, _width, _height, _pitch, _data, _size, _yflip); + m_interface->vtbl->screen_shot(m_interface, _filePath, _width, _height, _pitch, (bgfx_texture_format_t)_format, _data, _size, _yflip); } virtual void captureBegin(uint32_t _width, uint32_t _height, uint32_t _pitch, TextureFormat::Enum _format, bool _yflip) override diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 56cf674c6..96be7056a 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -1865,7 +1865,6 @@ namespace bgfx { namespace d3d11 void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { - BX_UNUSED(_external); return m_textures[_handle.idx].create(_mem, _flags, _skip, _external); } @@ -2033,12 +2032,14 @@ namespace bgfx { namespace d3d11 colorFormat = TextureFormat::Enum(i); break; } + if (s_textureFormat[i].m_fmtSrgb == backBufferDesc.Format) { colorFormat = TextureFormat::Enum(i); break; } } + if (colorFormat == TextureFormat::Enum::Count) { BX_TRACE("Unable to capture screenshot %s.", _filePath); @@ -2078,69 +2079,18 @@ namespace bgfx { namespace d3d11 D3D11_MAPPED_SUBRESOURCE mapped; DX_CHECK(m_deviceCtx->Map(texture, 0, D3D11_MAP_READ, 0, &mapped) ); - if (colorFormat == TextureFormat::RGBA8) - { - bimg::imageSwizzleBgra8( - mapped.pData - , mapped.RowPitch - , backBufferDesc.Width - , backBufferDesc.Height - , mapped.pData - , mapped.RowPitch - ); - g_callback->screenShot( - _filePath - , backBufferDesc.Width - , backBufferDesc.Height - , mapped.RowPitch - , mapped.pData - , backBufferDesc.Height*mapped.RowPitch - , false - ); - } - else if (colorFormat == TextureFormat::BGRA8) - { - g_callback->screenShot( - _filePath - , backBufferDesc.Width - , backBufferDesc.Height - , mapped.RowPitch - , mapped.pData - , backBufferDesc.Height*mapped.RowPitch - , false - ); - } - else - { - const uint8_t dstBpp = bimg::getBitsPerPixel(bimg::TextureFormat::BGRA8); - const uint32_t dstPitch = backBufferDesc.Width * dstBpp / 8; - const uint32_t dstSize = backBufferDesc.Height * dstPitch; - void* dst = bx::alloc(g_allocator, dstSize); - bimg::imageConvert( - dst - , dstBpp - , bimg::getPack(bimg::TextureFormat::BGRA8) - , mapped.pData - , bimg::getBitsPerPixel(bimg::TextureFormat::Enum(colorFormat)) - , bimg::getUnpack(bimg::TextureFormat::Enum(colorFormat)) - , backBufferDesc.Width - , backBufferDesc.Height - , 1 - , mapped.RowPitch - , dstPitch + g_callback->screenShot( + _filePath + , backBufferDesc.Width + , backBufferDesc.Height + , mapped.RowPitch + , colorFormat + , mapped.pData + , backBufferDesc.Height*mapped.RowPitch + , false ); - g_callback->screenShot( - _filePath - , backBufferDesc.Width - , backBufferDesc.Height - , dstPitch - , dst - , backBufferDesc.Height*dstPitch - , false - ); - bx::free(g_allocator, dst); - } + m_deviceCtx->Unmap(texture, 0); DX_RELEASE(texture, 0); diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index c439d0e31..c25cb2482 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -2322,6 +2322,28 @@ namespace bgfx { namespace d3d12 D3D12_RESOURCE_DESC desc = getResourceDesc(backBuffer); + TextureFormat::Enum colorFormat = TextureFormat::Enum::Count; + for (int i = 0; i < TextureFormat::Enum::Count; i++) + { + if (s_textureFormat[i].m_fmt == desc.Format) + { + colorFormat = TextureFormat::Enum(i); + break; + } + + if (s_textureFormat[i].m_fmtSrgb == desc.Format) + { + colorFormat = TextureFormat::Enum(i); + break; + } + } + + if (colorFormat == TextureFormat::Enum::Count) + { + BX_TRACE("Unable to capture screenshot %s.", _filePath); + return; + } + const uint32_t width = (uint32_t)desc.Width; const uint32_t height = (uint32_t)desc.Height; @@ -2359,22 +2381,17 @@ namespace bgfx { namespace d3d12 void* data; readback->Map(0, NULL, (void**)&data); - bimg::imageSwizzleBgra8( - data - , layout.Footprint.RowPitch - , width - , height - , data - , layout.Footprint.RowPitch - ); + g_callback->screenShot(_filePath , width , height , layout.Footprint.RowPitch + , colorFormat , data , (uint32_t)total , false ); + D3D12_RANGE writeRange = { 0, 0 }; readback->Unmap(0, &writeRange); diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index a01d06f1a..763fc469e 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -3600,15 +3600,18 @@ namespace bgfx { namespace gl , data ) ); + TextureFormat::Enum format = TextureFormat::BGRA8; + if (GL_RGBA == m_readPixelsFmt) { - bimg::imageSwizzleBgra8(data, width*4, width, height, data, width*4); + format = TextureFormat::RGBA8; } g_callback->screenShot(_filePath , width , height , width*4 + , format , data , length , true diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index 27ebde9d8..aa3349718 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -1252,22 +1252,25 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames m_cmd.kick(false, true); m_commandBuffer = 0; - uint32_t width = m_screenshotTarget.width(); - uint32_t height = m_screenshotTarget.height(); - uint32_t length = width*height*4; - uint8_t* data = (uint8_t*)bx::alloc(g_allocator, length); + const uint32_t width = m_screenshotTarget.width(); + const uint32_t height = m_screenshotTarget.height(); + const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_resolution.formatColor) ); + const uint32_t pitch = width * bpp / 8; + const uint32_t size = height*pitch; + uint8_t* data = (uint8_t*)bx::alloc(g_allocator, size); MTLRegion region = { { 0, 0, 0 }, { width, height, 1 } }; - m_screenshotTarget.getBytes(data, 4*width, 0, region, 0, 0); + m_screenshotTarget.getBytes(data, pitch, 0, region, 0, 0); g_callback->screenShot( _filePath , m_screenshotTarget.width() , m_screenshotTarget.height() - , width*4 + , pitch + , m_resolution.formatColor , data - , length + , size , false ); @@ -1599,22 +1602,13 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames MTLRegion region = { { 0, 0, 0 }, { m_resolution.width, m_resolution.height, 1 } }; - m_screenshotTarget.getBytes(m_capture, 4*m_resolution.width, 0, region, 0, 0); + const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_resolution.formatColor) ); + const uint32_t pitch = m_resolution.width * bpp / 8; + + m_screenshotTarget.getBytes(m_capture, pitch, 0, region, 0, 0); m_commandBuffer = m_cmd.alloc(); - if (m_screenshotTarget.pixelFormat() == kMtlPixelFormatRGBA8Uint) - { - bimg::imageSwizzleBgra8( - m_capture - , m_resolution.width*4 - , m_resolution.width - , m_resolution.height - , m_capture - , m_resolution.width*4 - ); - } - g_callback->captureFrame(m_capture, m_captureSize); RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor(); diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 7355e0936..c9ae16a2c 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -2590,7 +2590,7 @@ VK_IMPORT_DEVICE return; } - auto callback = [](void* _src, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _userData) + auto callback = [](void* _src, uint32_t _width, uint32_t _height, bgfx::TextureFormat::Enum _format, uint32_t _pitch, const void* _userData) { const char* filePath = (const char*)_userData; g_callback->screenShot( @@ -2598,13 +2598,14 @@ VK_IMPORT_DEVICE , _width , _height , _pitch + , _format , _src , _height * _pitch , false ); }; - const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(swapChain.m_colorFormat) ); + const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(swapChain.m_colorFormat) ); const uint32_t size = frameBuffer.m_width * frameBuffer.m_height * bpp / 8; DeviceMemoryAllocationVK stagingMemory; @@ -2860,11 +2861,9 @@ VK_IMPORT_DEVICE if (m_resolution.reset & BGFX_RESET_CAPTURE) { - const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_backBuffer.m_swapChain.m_colorFormat) ); - const uint32_t captureSize = m_backBuffer.m_width * m_backBuffer.m_height * bpp / 8; - - const uint8_t dstBpp = bimg::getBitsPerPixel(bimg::TextureFormat::BGRA8); - const uint32_t dstPitch = m_backBuffer.m_width * dstBpp / 8; + const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_backBuffer.m_swapChain.m_colorFormat) ); + const uint32_t pitch = m_backBuffer.m_width * bpp / 8; + const uint32_t captureSize = m_backBuffer.m_width * pitch; if (captureSize > m_captureSize) { @@ -2875,7 +2874,7 @@ VK_IMPORT_DEVICE VK_CHECK(createReadbackBuffer(m_captureSize, &m_captureBuffer, &m_captureMemory) ); } - g_callback->captureBegin(m_resolution.width, m_resolution.height, dstPitch, TextureFormat::BGRA8, false); + g_callback->captureBegin(m_resolution.width, m_resolution.height, pitch, m_resolution.formatColor, false); } } @@ -4185,18 +4184,17 @@ VK_IMPORT_DEVICE && NULL != _swapChain.m_nwh && _swapChain.m_needPresent && _swapChain.m_supportsReadback - && bimg::imageConvert(bimg::TextureFormat::BGRA8, bimg::TextureFormat::Enum(_swapChain.m_colorFormat) ) ; } - typedef void (*SwapChainReadFunc)(void* /*src*/, uint32_t /*width*/, uint32_t /*height*/, uint32_t /*pitch*/, const void* /*userData*/); + typedef void (*SwapChainReadFn)(void* _src, uint32_t _width, uint32_t _height, bgfx::TextureFormat::Enum _format, uint32_t _pitch, const void* _userData); - bool readSwapChain(const SwapChainVK& _swapChain, VkBuffer _buffer, DeviceMemoryAllocationVK _memory, SwapChainReadFunc _func, const void* _userData = NULL) + bool readSwapChain(const SwapChainVK& _swapChain, VkBuffer _buffer, DeviceMemoryAllocationVK _memory, SwapChainReadFn _func, const void* _userData = NULL) { if (isSwapChainReadable(_swapChain) ) { // source for the copy is the last rendered swapchain image - const VkImage image = _swapChain.m_backBufferColorImage[_swapChain.m_backBufferColorIdx]; + const VkImage image = _swapChain.m_backBufferColorImage[_swapChain.m_backBufferColorIdx]; const VkImageLayout layout = _swapChain.m_backBufferColorImageLayout[_swapChain.m_backBufferColorIdx]; const uint32_t width = _swapChain.m_sci.imageExtent.width; @@ -4214,29 +4212,7 @@ VK_IMPORT_DEVICE uint8_t* src; VK_CHECK(vkMapMemory(m_device, _memory.mem, _memory.offset, _memory.size, 0, (void**)&src) ); - if (_swapChain.m_colorFormat == TextureFormat::RGBA8) - { - bimg::imageSwizzleBgra8(src, pitch, width, height, src, pitch); - _func(src, width, height, pitch, _userData); - } - else if (_swapChain.m_colorFormat == TextureFormat::BGRA8) - { - _func(src, width, height, pitch, _userData); - } - else - { - const uint8_t dstBpp = bimg::getBitsPerPixel(bimg::TextureFormat::BGRA8); - const uint32_t dstPitch = width * dstBpp / 8; - const uint32_t dstSize = height * dstPitch; - - void* dst = bx::alloc(g_allocator, dstSize); - - bimg::imageConvert(g_allocator, dst, bimg::TextureFormat::BGRA8, src, bimg::TextureFormat::Enum(_swapChain.m_colorFormat), width, height, 1); - - _func(dst, width, height, dstPitch, _userData); - - bx::free(g_allocator, dst); - } + _func(src, width, height, _swapChain.m_colorFormat, pitch, _userData); vkUnmapMemory(m_device, _memory.mem); @@ -4254,7 +4230,7 @@ VK_IMPORT_DEVICE { m_backBuffer.resolve(); - auto callback = [](void* _src, uint32_t /*_width*/, uint32_t _height, uint32_t _pitch, const void* /*_userData*/) + auto callback = [](void* _src, uint32_t /*_width*/, uint32_t _height, TextureFormat::Enum /*_format*/, uint32_t _pitch, const void* /*_userData*/) { const uint32_t size = _height * _pitch; g_callback->captureFrame(_src, size); @@ -8132,13 +8108,12 @@ retry: return selectedFormat; } - VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)bx::alloc(g_allocator, numSurfaceFormats * sizeof(VkSurfaceFormatKHR) ); + VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)BX_STACK_ALLOC(numSurfaceFormats * sizeof(VkSurfaceFormatKHR) ); result = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &numSurfaceFormats, surfaceFormats); if (VK_SUCCESS != result) { BX_TRACE("findSurfaceFormat error: vkGetPhysicalDeviceSurfaceFormatsKHR failed %d: %s.", result, getName(result) ); - bx::free(g_allocator, surfaceFormats); return selectedFormat; } @@ -8159,10 +8134,11 @@ retry: for (uint32_t jj = 0; jj < numSurfaceFormats; jj++) { - if (_colorSpace == surfaceFormats[jj].colorSpace + if (_colorSpace == surfaceFormats[jj].colorSpace && requestedVkFormat == surfaceFormats[jj].format) { selectedFormat = requested; + if (0 != ii && s_renderVK->m_swapChainFormats[_format] != selectedFormat) {