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.
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

View File

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

View File

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

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);
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 (*save_screen_shot)(const char* _filePath);
void (*save_screen_shot)(bgfx_frame_buffer_handle_t _handle, const char* _filePath);
} bgfx_interface_vtbl_t;

View File

@ -6,7 +6,7 @@
#ifndef 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.

View File

@ -2449,12 +2449,15 @@ namespace bgfx
case CommandBuffer::SaveScreenShot:
{
FrameBufferHandle handle;
_cmdbuf.read(handle);
uint16_t len;
_cmdbuf.read(len);
const char* filePath = (const char*)_cmdbuf.skip(len);
m_renderCtx->saveScreenShot(filePath);
m_renderCtx->saveScreenShot(handle, filePath);
}
break;
@ -3844,10 +3847,10 @@ error:
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();
s_ctx->saveScreenShot(_filePath);
s_ctx->saveScreenShot(_handle, _filePath);
}
} // 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_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()

View File

@ -2166,7 +2166,7 @@ namespace bgfx
virtual void destroyFrameBuffer(FrameBufferHandle _handle) = 0;
virtual void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) = 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 updateUniform(uint16_t _loc, const void* _data, 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;
}
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);
uint16_t len = (uint16_t)bx::strnlen(_filePath)+1;
cmdbuf.write(_handle);
cmdbuf.write(len);
cmdbuf.write(_filePath, len);
}

View File

@ -1975,16 +1975,21 @@ BX_PRAGMA_DIAGNOSTIC_POP();
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);
return;
}
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;
backBuffer->GetDesc(&backBufferDesc);

View File

@ -1559,8 +1559,10 @@ namespace bgfx { namespace d3d12
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;
m_cmd.finish(m_backBufferColorFence[idx]);
ID3D12Resource* backBuffer = m_backBufferColor[idx];

View File

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

View File

@ -2523,14 +2523,24 @@ namespace bgfx { namespace gl
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;
uint8_t* data = (uint8_t*)BX_ALLOC(g_allocator, length);
SwapChainGL* swapChain = NULL;
uint32_t width = m_resolution.m_width;
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
, 0
, width

View File

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