From ad5a46779a30f901b262be3a7d775e2505921599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 15 Oct 2015 16:38:59 -0700 Subject: [PATCH] Added blit. --- include/bgfx/bgfx.h | 12 ++++++++ include/bgfx/bgfxdefines.h | 1 + include/bgfx/c99/bgfx.h | 3 ++ src/bgfx.cpp | 51 +++++++++++++++++++++++++++++++- src/bgfx_p.h | 60 ++++++++++++++++++++++++++++++++++++-- src/config.h | 4 +++ src/glimports.h | 4 +++ src/renderer_d3d11.cpp | 32 ++++++++++++++++++++ src/renderer_d3d9.cpp | 45 ++++++++++++++++++++++++---- src/renderer_gl.cpp | 44 ++++++++++++++++++++++++++-- 10 files changed, 245 insertions(+), 11 deletions(-) diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index 52495322..0f9a9811 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -2046,6 +2046,18 @@ namespace bgfx /// void discard(); + /// Blit texture region between two textures. + /// + /// @attention C99 equivalent is `bgfx_blit`. + /// + void blit(uint8_t _id, TextureHandle _dst, uint16_t _dstX, uint16_t _dstY, TextureHandle _src, uint16_t _srcX = 0, uint16_t _srcY = 0, uint16_t _width = UINT16_MAX, uint16_t _height = UINT16_MAX); + + /// Blit texture region between two textures. + /// + /// @attention C99 equivalent is `bgfx_blit`. + /// + void blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, TextureHandle _src, uint8_t _srcMip = 0, uint16_t _srcX = 0, uint16_t _srcY = 0, uint16_t _srcZ = 0, uint16_t _width = UINT16_MAX, uint16_t _height = UINT16_MAX, uint16_t _depth = UINT16_MAX); + /// Request screen shot. /// /// @param[in] _filePath Will be passed to `bgfx::CallbackI::screenShot` callback. diff --git a/include/bgfx/bgfxdefines.h b/include/bgfx/bgfxdefines.h index b239be1c..05f4bad0 100644 --- a/include/bgfx/bgfxdefines.h +++ b/include/bgfx/bgfxdefines.h @@ -310,6 +310,7 @@ #define BGFX_TEXTURE_COMPARE_MASK UINT32_C(0x000f0000) //!< #define BGFX_TEXTURE_COMPUTE_WRITE UINT32_C(0x00100000) //!< #define BGFX_TEXTURE_SRGB UINT32_C(0x00200000) //!< +#define BGFX_TEXTURE_BLIT_DST UINT32_C(0x00400000) //!< #define BGFX_TEXTURE_BORDER_COLOR_SHIFT 24 //!< #define BGFX_TEXTURE_BORDER_COLOR_MASK UINT32_C(0x0f000000) //!< #define BGFX_TEXTURE_RESERVED_SHIFT 28 //!< diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index b7aeecda..89f401ca 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -770,6 +770,9 @@ BGFX_C_API uint32_t bgfx_dispatch_indirect(uint8_t _id, bgfx_program_handle_t _h /**/ 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); diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 34d56ddb..622e3d4e 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -852,6 +852,31 @@ namespace bgfx return m_num; } + void Frame::blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, TextureHandle _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth) + { + uint16_t item = m_numBlitItems++; + + BlitItem& blit = m_blitItem[item]; + blit.m_srcX = _srcX; + blit.m_srcY = _srcY; + blit.m_srcZ = _srcZ; + blit.m_dstX = _dstX; + blit.m_dstY = _dstY; + blit.m_dstZ = _dstZ; + blit.m_width = _width; + blit.m_height = _height; + blit.m_depth = _depth; + blit.m_srcMip = _srcMip; + blit.m_dstMip = _dstMip; + blit.m_src = _src; + blit.m_dst = _dst; + + BlitKey key; + key.m_view = _id; + key.m_item = item; + m_blitKeys[item] = key.encode(); + } + void Frame::sort() { for (uint32_t ii = 0, num = m_num; ii < num; ++ii) @@ -859,6 +884,12 @@ namespace bgfx m_sortKeys[ii] = SortKey::remapView(m_sortKeys[ii], m_viewRemap); } bx::radixSort64(m_sortKeys, s_ctx->m_tempKeys, m_sortValues, s_ctx->m_tempValues, m_num); + + for (uint32_t ii = 0, num = m_num; ii < num; ++ii) + { + m_blitKeys[ii] = BlitKey::remapView(m_blitKeys[ii], m_viewRemap); + } + bx::radixSort32(m_blitKeys, (uint32_t*)&s_ctx->m_tempKeys, m_numBlitItems); } RenderFrame::Enum renderFrame() @@ -1631,7 +1662,7 @@ again: } else { -#if 0 +#if 1 if (s_rendererCreator[RendererType::Metal].supported) { _type = RendererType::Metal; @@ -3241,6 +3272,17 @@ again: s_ctx->discard(); } + void blit(uint8_t _id, TextureHandle _dst, uint16_t _dstX, uint16_t _dstY, TextureHandle _src, uint16_t _srcX, uint16_t _srcY, uint16_t _width, uint16_t _height) + { + blit(_id, _dst, 0, _dstX, _dstY, 0, _src, 0, _srcX, _srcY, 0, _width, _height, 0); + } + + void blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, TextureHandle _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth) + { + BGFX_CHECK_MAIN_THREAD(); + s_ctx->blit(_id, _dst, _dstMip, _dstX, _dstY, _dstZ, _src, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth); + } + void saveScreenShot(const char* _filePath) { BGFX_CHECK_MAIN_THREAD(); @@ -4059,6 +4101,13 @@ BGFX_C_API void bgfx_discard() 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) +{ + union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } dst = { _dst }; + union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } src = { _src }; + 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::saveScreenShot(_filePath); diff --git a/src/bgfx_p.h b/src/bgfx_p.h index b7bbcf67..9913ed63 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -759,6 +759,34 @@ namespace bgfx }; #undef SORT_KEY_RENDER_DRAW + struct BlitKey + { + uint32_t encode() + { + return 0 + | (uint32_t(m_view) << 24) + | uint32_t(m_item) + ; + } + + void decode(uint32_t _key) + { + m_item = uint16_t(_key & UINT16_MAX); + m_view = uint8_t(_key >> 24); + } + + static uint32_t remapView(uint32_t _key, uint8_t _viewRemap[BGFX_CONFIG_MAX_VIEWS]) + { + const uint8_t oldView = uint8_t(_key >> 24); + const uint32_t view = uint32_t(_viewRemap[oldView]) << 24; + const uint32_t key = (_key & ~UINT32_C(0xff000000) ) | view; + return key; + } + + uint16_t m_item; + uint8_t m_view; + }; + BX_ALIGN_DECL_16(struct) Matrix4 { union @@ -1184,6 +1212,23 @@ namespace bgfx RenderCompute compute; }; + struct BlitItem + { + uint16_t m_srcX; + uint16_t m_srcY; + uint16_t m_srcZ; + uint16_t m_dstX; + uint16_t m_dstY; + uint16_t m_dstZ; + uint16_t m_width; + uint16_t m_height; + uint16_t m_depth; + uint8_t m_srcMip; + uint8_t m_dstMip; + TextureHandle m_src; + TextureHandle m_dst; + }; + struct Resolution { Resolution() @@ -1274,9 +1319,10 @@ namespace bgfx m_matrixCache.reset(); m_rectCache.reset(); m_key.reset(); - m_num = 0; + m_num = 0; m_numRenderItems = 0; - m_numDropped = 0; + m_numDropped = 0; + m_numBlitItems = 0; m_iboffset = 0; m_vboffset = 0; m_cmdPre.start(); @@ -1501,6 +1547,8 @@ namespace bgfx return dispatch(_id, _handle, 0, 0, 0, _flags); } + void blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, TextureHandle _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth); + void sort(); bool checkAvailTransientIndexBuffer(uint32_t _num) @@ -1622,6 +1670,8 @@ namespace bgfx RenderItem m_renderItem[BGFX_CONFIG_MAX_DRAW_CALLS+1]; RenderDraw m_draw; RenderCompute m_compute; + uint32_t m_blitKeys[BGFX_CONFIG_MAX_BLIT_ITEMS+1]; + BlitItem m_blitItem[BGFX_CONFIG_MAX_BLIT_ITEMS+1]; uint64_t m_flags; uint32_t m_uniformBegin; uint32_t m_uniformEnd; @@ -1632,6 +1682,7 @@ namespace bgfx RenderItemCount m_num; RenderItemCount m_numRenderItems; RenderItemCount m_numDropped; + uint16_t m_numBlitItems; MatrixCache m_matrixCache; RectCache m_rectCache; @@ -3559,6 +3610,11 @@ namespace bgfx m_submit->discard(); } + BGFX_API_FUNC(void blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, TextureHandle _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth) ) + { + m_submit->blit(_id, _dst, _dstMip, _dstX, _dstY, _dstZ, _src, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth); + } + BGFX_API_FUNC(uint32_t frame() ); void dumpViewStats(); diff --git a/src/config.h b/src/config.h index 7aecc9b0..a150861a 100644 --- a/src/config.h +++ b/src/config.h @@ -189,6 +189,10 @@ # define BGFX_CONFIG_MAX_DRAW_CALLS ( (64<<10)-1) #endif // BGFX_CONFIG_MAX_DRAW_CALLS +#ifndef BGFX_CONFIG_MAX_BLIT_ITEMS +# define BGFX_CONFIG_MAX_BLIT_ITEMS 256 +#endif // BGFX_CONFIG_MAX_BLIT_ITEMS + #ifndef BGFX_CONFIG_MAX_MATRIX_CACHE # define BGFX_CONFIG_MAX_MATRIX_CACHE (BGFX_CONFIG_MAX_DRAW_CALLS+1) #endif // BGFX_CONFIG_MAX_MATRIX_CACHE diff --git a/src/glimports.h b/src/glimports.h index 42f966ec..3467cc50 100644 --- a/src/glimports.h +++ b/src/glimports.h @@ -71,6 +71,7 @@ typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum targ typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void); typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode); @@ -251,6 +252,7 @@ GL_IMPORT______(false, PFNGLCOMPRESSEDTEXIMAGE2DPROC, glCompressedT GL_IMPORT______(false, PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC, glCompressedTexSubImage2D); GL_IMPORT______(true , PFNGLCOMPRESSEDTEXIMAGE3DPROC, glCompressedTexImage3D); GL_IMPORT______(true , PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedTexSubImage3D); +GL_IMPORT______(true , PFNGLCOPYIMAGESUBDATAPROC, glCopyImageSubData); GL_IMPORT______(false, PFNGLCREATEPROGRAMPROC, glCreateProgram); GL_IMPORT______(false, PFNGLCREATESHADERPROC, glCreateShader); GL_IMPORT______(false, PFNGLCULLFACEPROC, glCullFace); @@ -451,6 +453,8 @@ GL_IMPORT______(true, PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC, glGetTranslat GL_IMPORT_ANGLE(true, PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer); GL_IMPORT_ANGLE(true, PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample); +GL_IMPORT_EXT__(true , PFNGLCOPYIMAGESUBDATAPROC, glCopyImageSubData); + GL_IMPORT_KHR__(true, PFNGLDEBUGMESSAGECONTROLPROC, glDebugMessageControl); GL_IMPORT_KHR__(true, PFNGLDEBUGMESSAGEINSERTPROC, glDebugMessageInsert); GL_IMPORT_KHR__(true, PFNGLDEBUGMESSAGECALLBACKPROC, glDebugMessageCallback); diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index a7a383d3..5d437902 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -4450,6 +4450,11 @@ BX_PRAGMA_DIAGNOSTIC_POP(); uint16_t view = UINT16_MAX; FrameBufferHandle fbh = BGFX_INVALID_HANDLE; + BlitKey blitKey; + blitKey.decode(_render->m_blitKeys[0]); + uint16_t numBlitItems = _render->m_numBlitItems; + uint16_t blitItem = 0; + const uint64_t primType = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0; uint8_t primIndex = uint8_t(primType >> BGFX_STATE_PT_SHIFT); PrimInfo prim = s_primInfo[primIndex]; @@ -4583,6 +4588,33 @@ BX_PRAGMA_DIAGNOSTIC_POP(); clearQuad(_clearQuad, viewState.m_rect, clr, _render->m_colorPalette); prim = s_primInfo[BX_COUNTOF(s_primName)]; // Force primitive type update after clear quad. } + + for (; blitItem < numBlitItems && blitKey.m_view == view; blitItem++) + { + const BlitItem& blit = _render->m_blitItem[blitItem]; + blitKey.decode(_render->m_blitKeys[blitItem+1]); + + const TextureD3D11 src = m_textures[blit.m_src.idx]; + const TextureD3D11 dst = m_textures[blit.m_dst.idx]; + + D3D11_BOX box; + box.left = blit.m_srcX; + box.top = blit.m_srcY; + box.front = blit.m_srcZ; + box.right = blit.m_srcX + blit.m_width; + box.bottom = blit.m_srcY + blit.m_height; + box.back = blit.m_srcZ + bx::uint16_max(blit.m_depth, 1); + + deviceCtx->CopySubresourceRegion(dst.m_ptr + , blit.m_dstMip + , blit.m_dstX + , blit.m_dstY + , blit.m_dstZ + , src.m_ptr + , blit.m_srcMip + , &box + ); + } } if (isCompute) diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index d14956ab..b573bae0 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -2290,22 +2290,23 @@ namespace bgfx { namespace d3d9 void TextureD3D9::createTexture(uint32_t _width, uint32_t _height, uint8_t _numMips) { - m_width = (uint16_t)_width; - m_height = (uint16_t)_height; + m_width = (uint16_t)_width; + m_height = (uint16_t)_height; m_numMips = _numMips; - m_type = Texture2D; + m_type = Texture2D; const TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat; DWORD usage = 0; D3DPOOL pool = s_renderD3D9->m_pool; const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); + const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST); if (isDepth(fmt) ) { usage = D3DUSAGE_DEPTHSTENCIL; pool = D3DPOOL_DEFAULT; } - else if (renderTarget) + else if (renderTarget || blit) { usage = D3DUSAGE_RENDERTARGET; pool = D3DPOOL_DEFAULT; @@ -2793,7 +2794,7 @@ namespace bgfx { namespace d3d9 { TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat; if (TextureFormat::Unknown != fmt - && (isDepth(fmt) || !!(m_flags&BGFX_TEXTURE_RT_MASK) ) ) + && (isDepth(fmt) || !!(m_flags&(BGFX_TEXTURE_RT_MASK|BGFX_TEXTURE_BLIT_DST) ) ) ) { DX_RELEASE(m_ptr, 0); DX_RELEASE(m_surface, 0); @@ -2804,7 +2805,7 @@ namespace bgfx { namespace d3d9 { TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat; if (TextureFormat::Unknown != fmt - && (isDepth(fmt) || !!(m_flags&BGFX_TEXTURE_RT_MASK) ) ) + && (isDepth(fmt) || !!(m_flags&(BGFX_TEXTURE_RT_MASK|BGFX_TEXTURE_BLIT_DST)) ) ) { createTexture(m_width, m_height, m_numMips); } @@ -3202,6 +3203,11 @@ namespace bgfx { namespace d3d9 FrameBufferHandle fbh = BGFX_INVALID_HANDLE; uint32_t blendFactor = 0; + BlitKey blitKey; + blitKey.decode(_render->m_blitKeys[0]); + uint16_t numBlitItems = _render->m_numBlitItems; + uint16_t blitItem = 0; + uint8_t primIndex; { const uint64_t pt = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0; @@ -3293,6 +3299,33 @@ namespace bgfx { namespace d3d9 DX_CHECK(device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE) ); DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE) ); DX_CHECK(device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER) ); + + for (; blitItem < numBlitItems && blitKey.m_view == view; blitItem++) + { + const BlitItem& blit = _render->m_blitItem[blitItem]; + blitKey.decode(_render->m_blitKeys[blitItem+1]); + + const TextureD3D9 src = m_textures[blit.m_src.idx]; + const TextureD3D9 dst = m_textures[blit.m_dst.idx]; + + RECT srcRect = { blit.m_srcX, blit.m_srcY, blit.m_srcX + blit.m_width, blit.m_srcY + blit.m_height }; + RECT dstRect = { blit.m_dstX, blit.m_dstY, blit.m_dstX + blit.m_width, blit.m_dstY + blit.m_height }; + + IDirect3DSurface9* srcSurface; + DX_CHECK(src.m_texture2d->GetSurfaceLevel(blit.m_srcMip, &srcSurface) ); + + IDirect3DSurface9* dstSurface; + DX_CHECK(dst.m_texture2d->GetSurfaceLevel(blit.m_dstMip, &dstSurface) ); + + DX_CHECK(m_device->StretchRect(srcSurface + , &srcRect + , dstSurface + , &dstRect + , D3DTEXF_NONE + ) ); + srcSurface->Release(); + dstSurface->Release(); + } } uint16_t scissor = draw.m_scissor; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 557614ef..147e1302 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -441,6 +441,7 @@ namespace bgfx { namespace gl ARB_compute_shader, ARB_conservative_depth, + ARB_copy_image, ARB_debug_label, ARB_debug_output, ARB_depth_buffer_float, @@ -499,6 +500,7 @@ namespace bgfx { namespace gl EXT_blend_subtract, EXT_color_buffer_half_float, EXT_color_buffer_float, + EXT_copy_image, EXT_compressed_ETC1_RGB8_sub_texture, EXT_debug_label, EXT_debug_marker, @@ -554,10 +556,12 @@ namespace bgfx { namespace gl MOZ_WEBGL_compressed_texture_s3tc, MOZ_WEBGL_depth_texture, - NV_texture_border_clamp, + NV_copy_image, NV_draw_buffers, + NV_texture_border_clamp, NVX_gpu_memory_info, + OES_copy_image, OES_compressed_ETC1_RGB8_texture, OES_depth24, OES_depth32, @@ -640,6 +644,7 @@ namespace bgfx { namespace gl { "ARB_compute_shader", BGFX_CONFIG_RENDERER_OPENGL >= 43, true }, { "ARB_conservative_depth", BGFX_CONFIG_RENDERER_OPENGL >= 42, true }, + { "ARB_copy_image", BGFX_CONFIG_RENDERER_OPENGL >= 42, true }, { "ARB_debug_label", false, true }, { "ARB_debug_output", BGFX_CONFIG_RENDERER_OPENGL >= 43, true }, { "ARB_depth_buffer_float", BGFX_CONFIG_RENDERER_OPENGL >= 33, true }, @@ -698,6 +703,7 @@ namespace bgfx { namespace gl { "EXT_blend_subtract", BGFX_CONFIG_RENDERER_OPENGL >= 14, true }, { "EXT_color_buffer_half_float", false, true }, // GLES2 extension. { "EXT_color_buffer_float", false, true }, // GLES2 extension. + { "EXT_copy_image", false, true }, // GLES2 extension. { "EXT_compressed_ETC1_RGB8_sub_texture", false, true }, // GLES2 extension. { "EXT_debug_label", false, true }, { "EXT_debug_marker", false, true }, @@ -753,10 +759,12 @@ namespace bgfx { namespace gl { "MOZ_WEBGL_compressed_texture_s3tc", false, true }, { "MOZ_WEBGL_depth_texture", false, true }, - { "NV_texture_border_clamp", false, true }, // GLES2 extension. + { "NV_copy_image", false, true }, { "NV_draw_buffers", false, true }, // GLES2 extension. + { "NV_texture_border_clamp", false, true }, // GLES2 extension. { "NVX_gpu_memory_info", false, true }, + { "OES_copy_image", false, true }, { "OES_compressed_ETC1_RGB8_texture", false, true }, { "OES_depth24", false, true }, { "OES_depth32", false, true }, @@ -5105,6 +5113,12 @@ namespace bgfx { namespace gl SortKey key; uint16_t view = UINT16_MAX; FrameBufferHandle fbh = BGFX_INVALID_HANDLE; + + BlitKey blitKey; + blitKey.decode(_render->m_blitKeys[0]); + uint16_t numBlitItems = _render->m_numBlitItems; + uint16_t blitItem = 0; + int32_t height = hmdEnabled ? _render->m_hmd.height : _render->m_resolution.m_height @@ -5257,6 +5271,32 @@ namespace bgfx { namespace gl GL_CHECK(glDepthFunc(GL_LESS) ); GL_CHECK(glEnable(GL_CULL_FACE) ); GL_CHECK(glDisable(GL_BLEND) ); + + for (; blitItem < numBlitItems && blitKey.m_view == view; blitItem++) + { + const BlitItem& blit = _render->m_blitItem[blitItem]; + blitKey.decode(_render->m_blitKeys[blitItem+1]); + + const TextureGL src = m_textures[blit.m_src.idx]; + const TextureGL dst = m_textures[blit.m_dst.idx]; + + GL_CHECK(glCopyImageSubData(src.m_id + , src.m_target + , blit.m_srcMip + , blit.m_srcX + , blit.m_srcY + , blit.m_srcZ + , dst.m_id + , dst.m_target + , blit.m_dstMip + , blit.m_dstX + , blit.m_dstY + , blit.m_dstZ + , blit.m_width + , blit.m_height + , bx::uint32_max(blit.m_depth, 1) + ) ); + } } if (isCompute)