Added ability to specify swap chain for screenshot.

This commit is contained in:
Branimir Karadžić 2017-03-02 18:02:14 -08:00
parent 7e76736082
commit 86fc54ccfc
15 changed files with 84 additions and 38 deletions

View File

@ -439,7 +439,8 @@ int _main_(int _argc, char** _argv)
// Take screen shot at frame 150. // Take screen shot at frame 150.
if (150 == frame) if (150 == frame)
{ {
bgfx::saveScreenShot("temp/frame150"); bgfx::FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
bgfx::saveScreenShot(fbh, "temp/frame150");
} }
// Advance to next frame. Rendering thread will be kicked to // Advance to next frame. Rendering thread will be kicked to

View File

@ -312,9 +312,11 @@ BX_PRAGMA_DIAGNOSTIC_POP();
} }
else if (0 == bx::strncmp(_argv[1], "screenshot") ) else if (0 == bx::strncmp(_argv[1], "screenshot") )
{ {
bgfx::FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
if (_argc > 2) if (_argc > 2)
{ {
bgfx::saveScreenShot(_argv[2]); bgfx::saveScreenShot(fbh, _argv[2]);
} }
else else
{ {
@ -323,7 +325,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
char filePath[256]; char filePath[256];
bx::snprintf(filePath, sizeof(filePath), "temp/screenshot-%d", tt); bx::snprintf(filePath, sizeof(filePath), "temp/screenshot-%d", tt);
bgfx::saveScreenShot(filePath); bgfx::saveScreenShot(fbh, filePath);
} }
return 0; return 0;

View File

@ -2812,6 +2812,7 @@ namespace bgfx
/// Request screen shot. /// Request screen shot.
/// ///
/// @param[in] _handle Frame buffer handle.
/// @param[in] _filePath Will be passed to `bgfx::CallbackI::screenShot` callback. /// @param[in] _filePath Will be passed to `bgfx::CallbackI::screenShot` callback.
/// ///
/// @remarks /// @remarks
@ -2819,7 +2820,7 @@ namespace bgfx
/// ///
/// @attention C99 equivalent is `bgfx_save_screen_shot`. /// @attention C99 equivalent is `bgfx_save_screen_shot`.
/// ///
void saveScreenShot(const char* _filePath); void saveScreenShot(FrameBufferHandle _handle, const char* _filePath);
} // namespace bgfx } // namespace bgfx

View File

@ -909,6 +909,6 @@ BGFX_C_API void bgfx_discard();
BGFX_C_API void bgfx_blit(uint8_t _id, bgfx_texture_handle_t _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, bgfx_texture_handle_t _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth); BGFX_C_API void bgfx_blit(uint8_t _id, bgfx_texture_handle_t _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, bgfx_texture_handle_t _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth);
/**/ /**/
BGFX_C_API void bgfx_save_screen_shot(const char* _filePath); BGFX_C_API void bgfx_save_screen_shot(bgfx_frame_buffer_handle_t _handle, const char* _filePath);
#endif // BGFX_C99_H_HEADER_GUARD #endif // BGFX_C99_H_HEADER_GUARD

View File

@ -198,7 +198,7 @@ typedef struct bgfx_interface_vtbl
uint32_t (*dispatch_indirect)(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags); uint32_t (*dispatch_indirect)(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags);
void (*discard)(); void (*discard)();
void (*blit)(uint8_t _id, bgfx_texture_handle_t _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, bgfx_texture_handle_t _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth); void (*blit)(uint8_t _id, bgfx_texture_handle_t _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, bgfx_texture_handle_t _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth);
void (*save_screen_shot)(const char* _filePath); void (*save_screen_shot)(bgfx_frame_buffer_handle_t _handle, const char* _filePath);
} bgfx_interface_vtbl_t; } bgfx_interface_vtbl_t;

View File

@ -6,7 +6,7 @@
#ifndef BGFX_DEFINES_H_HEADER_GUARD #ifndef BGFX_DEFINES_H_HEADER_GUARD
#define BGFX_DEFINES_H_HEADER_GUARD #define BGFX_DEFINES_H_HEADER_GUARD
#define BGFX_API_VERSION UINT32_C(36) #define BGFX_API_VERSION UINT32_C(37)
/// ///
#define BGFX_STATE_RGB_WRITE UINT64_C(0x0000000000000001) //!< Enable RGB write. #define BGFX_STATE_RGB_WRITE UINT64_C(0x0000000000000001) //!< Enable RGB write.

View File

@ -2449,12 +2449,15 @@ namespace bgfx
case CommandBuffer::SaveScreenShot: case CommandBuffer::SaveScreenShot:
{ {
FrameBufferHandle handle;
_cmdbuf.read(handle);
uint16_t len; uint16_t len;
_cmdbuf.read(len); _cmdbuf.read(len);
const char* filePath = (const char*)_cmdbuf.skip(len); const char* filePath = (const char*)_cmdbuf.skip(len);
m_renderCtx->saveScreenShot(filePath); m_renderCtx->saveScreenShot(handle, filePath);
} }
break; break;
@ -3844,10 +3847,10 @@ error:
s_ctx->blit(_id, _dst, _dstMip, _dstX, _dstY, _dstZ, _src, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth); s_ctx->blit(_id, _dst, _dstMip, _dstX, _dstY, _dstZ, _src, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth);
} }
void saveScreenShot(const char* _filePath) void saveScreenShot(FrameBufferHandle _handle, const char* _filePath)
{ {
BGFX_CHECK_MAIN_THREAD(); BGFX_CHECK_MAIN_THREAD();
s_ctx->saveScreenShot(_filePath); s_ctx->saveScreenShot(_handle, _filePath);
} }
} // namespace bgfx } // namespace bgfx
@ -4775,9 +4778,10 @@ BGFX_C_API void bgfx_blit(uint8_t _id, bgfx_texture_handle_t _dst, uint8_t _dstM
bgfx::blit(_id, dst.cpp, _dstMip, _dstX, _dstY, _dstZ, src.cpp, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth); bgfx::blit(_id, dst.cpp, _dstMip, _dstX, _dstY, _dstZ, src.cpp, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth);
} }
BGFX_C_API void bgfx_save_screen_shot(const char* _filePath) BGFX_C_API void bgfx_save_screen_shot(bgfx_frame_buffer_handle _handle, const char* _filePath)
{ {
bgfx::saveScreenShot(_filePath); union { bgfx_frame_buffer_handle_t c; bgfx::FrameBufferHandle cpp; } handle = { _handle };
bgfx::saveScreenShot(handle.cpp, _filePath);
} }
BGFX_C_API bgfx_render_frame_t bgfx_render_frame() BGFX_C_API bgfx_render_frame_t bgfx_render_frame()

View File

@ -2166,7 +2166,7 @@ namespace bgfx
virtual void destroyFrameBuffer(FrameBufferHandle _handle) = 0; virtual void destroyFrameBuffer(FrameBufferHandle _handle) = 0;
virtual void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) = 0; virtual void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) = 0;
virtual void destroyUniform(UniformHandle _handle) = 0; virtual void destroyUniform(UniformHandle _handle) = 0;
virtual void saveScreenShot(const char* _filePath) = 0; virtual void saveScreenShot(FrameBufferHandle _handle, const char* _filePath) = 0;
virtual void updateViewName(uint8_t _id, const char* _name) = 0; virtual void updateViewName(uint8_t _id, const char* _name) = 0;
virtual void updateUniform(uint16_t _loc, const void* _data, uint32_t _size) = 0; virtual void updateUniform(uint16_t _loc, const void* _data, uint32_t _size) = 0;
virtual void setMarker(const char* _marker, uint32_t _size) = 0; virtual void setMarker(const char* _marker, uint32_t _size) = 0;
@ -3625,10 +3625,20 @@ namespace bgfx
m_freeOcclusionQueryHandle[m_numFreeOcclusionQueryHandles++] = _handle; m_freeOcclusionQueryHandle[m_numFreeOcclusionQueryHandles++] = _handle;
} }
BGFX_API_FUNC(void saveScreenShot(const char* _filePath) ) BGFX_API_FUNC(void saveScreenShot(FrameBufferHandle _handle, const char* _filePath) )
{ {
BGFX_CHECK_HANDLE_INVALID_OK("saveScreenShot", m_frameBufferHandle, _handle);
if (isValid(_handle) )
{
FrameBufferRef& ref = m_frameBufferRef[_handle.idx];
BX_CHECK(ref.m_window, "saveScreenShot can be done only for window frame buffer handles (handle: %d).", _handle.idx); BX_UNUSED(ref);
return;
}
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::SaveScreenShot); CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::SaveScreenShot);
uint16_t len = (uint16_t)bx::strnlen(_filePath)+1; uint16_t len = (uint16_t)bx::strnlen(_filePath)+1;
cmdbuf.write(_handle);
cmdbuf.write(len); cmdbuf.write(len);
cmdbuf.write(_filePath, len); cmdbuf.write(_filePath, len);
} }

View File

@ -1975,16 +1975,21 @@ BX_PRAGMA_DIAGNOSTIC_POP();
m_uniformReg.remove(_handle); m_uniformReg.remove(_handle);
} }
void saveScreenShot(const char* _filePath) BX_OVERRIDE void saveScreenShot(FrameBufferHandle _handle, const char* _filePath) BX_OVERRIDE
{ {
if (NULL == m_swapChain) IDXGISwapChain* swapChain = isValid(_handle)
? m_frameBuffers[_handle.idx].m_swapChain
: m_swapChain
;
if (NULL == swapChain)
{ {
BX_TRACE("Unable to capture screenshot %s.", _filePath); BX_TRACE("Unable to capture screenshot %s.", _filePath);
return; return;
} }
ID3D11Texture2D* backBuffer; ID3D11Texture2D* backBuffer;
DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) ); DX_CHECK(swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) );
D3D11_TEXTURE2D_DESC backBufferDesc; D3D11_TEXTURE2D_DESC backBufferDesc;
backBuffer->GetDesc(&backBufferDesc); backBuffer->GetDesc(&backBufferDesc);

View File

@ -1559,8 +1559,10 @@ namespace bgfx { namespace d3d12
m_uniformReg.remove(_handle); m_uniformReg.remove(_handle);
} }
void saveScreenShot(const char* _filePath) BX_OVERRIDE void saveScreenShot(FrameBufferHandle _handle, const char* _filePath) BX_OVERRIDE
{ {
BX_UNUSED(_handle);
uint32_t idx = (m_backBufferColorIdx-1) % m_scd.BufferCount; uint32_t idx = (m_backBufferColorIdx-1) % m_scd.BufferCount;
m_cmd.finish(m_backBufferColorFence[idx]); m_cmd.finish(m_backBufferColorFence[idx]);
ID3D12Resource* backBuffer = m_backBufferColor[idx]; ID3D12Resource* backBuffer = m_backBufferColor[idx];

View File

@ -1129,9 +1129,11 @@ namespace bgfx { namespace d3d9
m_uniformReg.remove(_handle); m_uniformReg.remove(_handle);
} }
void saveScreenShot(const char* _filePath) BX_OVERRIDE void saveScreenShot(FrameBufferHandle _handle, const char* _filePath) BX_OVERRIDE
{ {
#if BX_PLATFORM_WINDOWS #if BX_PLATFORM_WINDOWS
BX_UNUSED(_handle);
IDirect3DSurface9* surface; IDirect3DSurface9* surface;
D3DDEVICE_CREATION_PARAMETERS dcp; D3DDEVICE_CREATION_PARAMETERS dcp;
DX_CHECK(m_device->GetCreationParameters(&dcp) ); DX_CHECK(m_device->GetCreationParameters(&dcp) );
@ -1175,6 +1177,8 @@ namespace bgfx { namespace d3d9
DX_CHECK(surface->UnlockRect() ); DX_CHECK(surface->UnlockRect() );
DX_RELEASE(surface, 0); DX_RELEASE(surface, 0);
#else
BX_UNUSED(_handle, _filePath);
#endif // BX_PLATFORM_WINDOWS #endif // BX_PLATFORM_WINDOWS
} }

View File

@ -2523,14 +2523,24 @@ namespace bgfx { namespace gl
m_uniformReg.remove(_handle); m_uniformReg.remove(_handle);
} }
void saveScreenShot(const char* _filePath) BX_OVERRIDE void saveScreenShot(FrameBufferHandle _handle, const char* _filePath) BX_OVERRIDE
{ {
uint32_t length = m_resolution.m_width*m_resolution.m_height*4; SwapChainGL* swapChain = NULL;
uint8_t* data = (uint8_t*)BX_ALLOC(g_allocator, length);
uint32_t width = m_resolution.m_width; uint32_t width = m_resolution.m_width;
uint32_t height = m_resolution.m_height; uint32_t height = m_resolution.m_height;
if (isValid(_handle) )
{
const FrameBufferGL& frameBuffer = m_frameBuffers[_handle.idx];
swapChain = frameBuffer.m_swapChain;
width = frameBuffer.m_width;
height = frameBuffer.m_height;
}
m_glctx.makeCurrent(swapChain);
uint32_t length = width*height*4;
uint8_t* data = (uint8_t*)BX_ALLOC(g_allocator, length);
GL_CHECK(glReadPixels(0 GL_CHECK(glReadPixels(0
, 0 , 0
, width , width

View File

@ -911,10 +911,14 @@ namespace bgfx { namespace mtl
} }
//cmdPost //cmdPost
void saveScreenShot(const char* _filePath) BX_OVERRIDE void saveScreenShot(FrameBufferHandle _handle, const char* _filePath) BX_OVERRIDE
{ {
BX_UNUSED(_handle);
if (NULL == m_screenshotTarget) if (NULL == m_screenshotTarget)
{
return; return;
}
m_cmd.kick(false, true); m_cmd.kick(false, true);
m_commandBuffer = 0; m_commandBuffer = 0;
@ -2938,8 +2942,7 @@ namespace bgfx { namespace mtl
{ {
m_cmd.finish(false); m_cmd.finish(false);
if (m_commandBuffer == NULL)
if ( m_commandBuffer == NULL )
{ {
m_commandBuffer = m_cmd.alloc(); m_commandBuffer = m_cmd.alloc();
} }
@ -2949,7 +2952,7 @@ namespace bgfx { namespace mtl
m_gpuTimer.addHandlers(m_commandBuffer); m_gpuTimer.addHandlers(m_commandBuffer);
if ( m_blitCommandEncoder ) if (m_blitCommandEncoder)
{ {
m_blitCommandEncoder.endEncoding(); m_blitCommandEncoder.endEncoding();
m_blitCommandEncoder = 0; m_blitCommandEncoder = 0;
@ -2957,18 +2960,19 @@ namespace bgfx { namespace mtl
updateResolution(_render->m_resolution); updateResolution(_render->m_resolution);
if ( m_saveScreenshot || NULL != m_capture ) if (m_saveScreenshot
|| NULL != m_capture)
{ {
if ( m_screenshotTarget ) if (m_screenshotTarget)
{ {
if ( m_screenshotTarget.width() != m_resolution.m_width || if (m_screenshotTarget.width() != m_resolution.m_width
m_screenshotTarget.height() != m_resolution.m_height ) || m_screenshotTarget.height() != m_resolution.m_height)
{ {
MTL_RELEASE(m_screenshotTarget); MTL_RELEASE(m_screenshotTarget);
} }
} }
if ( NULL == m_screenshotTarget) if (NULL == m_screenshotTarget)
{ {
m_textureDescriptor.textureType = MTLTextureType2D; m_textureDescriptor.textureType = MTLTextureType2D;
m_textureDescriptor.pixelFormat = m_metalLayer.pixelFormat; m_textureDescriptor.pixelFormat = m_metalLayer.pixelFormat;
@ -2981,13 +2985,16 @@ namespace bgfx { namespace mtl
if ( m_iOS9Runtime || m_macOS11Runtime ) if ( m_iOS9Runtime || m_macOS11Runtime )
{ {
m_textureDescriptor.cpuCacheMode = MTLCPUCacheModeDefaultCache; m_textureDescriptor.cpuCacheMode = MTLCPUCacheModeDefaultCache;
m_textureDescriptor.storageMode = (MTLStorageMode)(((BX_ENABLED(BX_PLATFORM_IOS)) ? 0 /* MTLStorageModeShared */ : 1 /*MTLStorageModeManaged*/) m_textureDescriptor.storageMode = (MTLStorageMode)(BX_ENABLED(BX_PLATFORM_IOS)
); ? 0 /* MTLStorageModeShared */
m_textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; : 1 /*MTLStorageModeManaged*/
);
m_textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
} }
m_screenshotTarget = m_device.newTextureWithDescriptor(m_textureDescriptor); m_screenshotTarget = m_device.newTextureWithDescriptor(m_textureDescriptor);
} }
m_saveScreenshot = false; m_saveScreenshot = false;
} }
else else

View File

@ -177,7 +177,7 @@ namespace bgfx { namespace noop
{ {
} }
void saveScreenShot(const char* /*_filePath*/) BX_OVERRIDE void saveScreenShot(FrameBufferHandle /*_handle*/, const char* /*_filePath*/) BX_OVERRIDE
{ {
} }

View File

@ -2097,7 +2097,7 @@ VK_IMPORT_DEVICE
m_uniforms[_handle.idx] = NULL; m_uniforms[_handle.idx] = NULL;
} }
void saveScreenShot(const char* /*_filePath*/) BX_OVERRIDE void saveScreenShot(FrameBufferHandle /*_handle*/, const char* /*_filePath*/) BX_OVERRIDE
{ {
} }