Added initial texture read back support.

This commit is contained in:
Branimir Karadžić 2015-10-20 16:32:08 -07:00
parent 1be1714780
commit 6aa6efda12
14 changed files with 232 additions and 10 deletions

View File

@ -169,7 +169,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
const bgfx::Caps* caps = bgfx::getCaps();
const bool texture3DSupported = !!(caps->supported & BGFX_CAPS_TEXTURE_3D);
const bool blitSupported = !!(caps->supported & BGFX_CAPS_BLIT);
const bool blitSupported = !!(caps->supported & BGFX_CAPS_TEXTURE_BLIT);
uint32_t numTextures3d = 0;
bgfx::TextureHandle textures3d[3] = {};

View File

@ -215,6 +215,16 @@ class HDR : public entry::AppI
m_bright = bgfx::createFrameBuffer(bgfx::BackbufferRatio::Half, bgfx::TextureFormat::BGRA8);
m_blur = bgfx::createFrameBuffer(bgfx::BackbufferRatio::Eighth, bgfx::TextureFormat::BGRA8);
m_lumBgra8 = 0;
if ( (BGFX_CAPS_TEXTURE_BLIT|BGFX_CAPS_TEXTURE_READ_BACK) == (bgfx::getCaps()->supported & BGFX_CAPS_TEXTURE_BLIT|BGFX_CAPS_TEXTURE_READ_BACK) )
{
m_rb = bgfx::createTexture2D(1, 1, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_READ_BACK);
}
else
{
m_rb.idx = bgfx::invalidHandle;
}
// Imgui.
imguiCreate();
@ -306,7 +316,7 @@ class HDR : public entry::AppI
, m_height
);
imguiBeginScrollArea("Settings", m_width - m_width / 5 - 10, 10, m_width / 5, m_height / 3, &m_scrollArea);
imguiBeginScrollArea("Settings", m_width - m_width / 5 - 10, 10, m_width / 5, m_height / 2, &m_scrollArea);
imguiSeparatorLine();
imguiSlider("Speed", m_speed, 0.0f, 1.0f, 0.01f);
@ -316,6 +326,14 @@ class HDR : public entry::AppI
imguiSlider("White point", m_white, 0.1f, 2.0f, 0.01f);
imguiSlider("Threshold", m_threshold, 0.1f, 2.0f, 0.01f);
if (bgfx::isValid(m_rb) )
{
union { uint32_t color; uint8_t bgra[4]; } cast = { m_lumBgra8 };
float exponent = cast.bgra[3]/255.0f * 255.0f - 128.0f;
float lumAvg = cast.bgra[2]/255.0f * exp2(exponent);
imguiSlider("Lum Avg", lumAvg, 0.0f, 1.0f, 0.01f, false);
}
imguiEndScrollArea();
imguiEndFrame();
@ -473,6 +491,12 @@ class HDR : public entry::AppI
screenSpaceQuad( (float)m_width, (float)m_height, s_originBottomLeft);
bgfx::submit(9, m_tonemapProgram);
if (bgfx::isValid(m_rb) )
{
bgfx::blit(9, m_rb, 0, 0, m_lum[4]);
bgfx::readTexture(m_rb, &m_lumBgra8);
}
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx::frame();
@ -505,6 +529,7 @@ class HDR : public entry::AppI
Mesh* m_mesh;
bgfx::TextureHandle m_fbtextures[2];
bgfx::TextureHandle m_rb;
bgfx::FrameBufferHandle m_fbh;
bgfx::FrameBufferHandle m_lum[5];
bgfx::FrameBufferHandle m_bright;
@ -514,6 +539,7 @@ class HDR : public entry::AppI
uint32_t m_height;
uint32_t m_debug;
uint32_t m_reset;
uint32_t m_lumBgra8;
uint32_t m_oldWidth;
uint32_t m_oldHeight;

View File

@ -1394,6 +1394,12 @@ namespace bgfx
///
void updateTextureCube(TextureHandle _handle, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const Memory* _mem, uint16_t _pitch = UINT16_MAX);
///
void readTexture(TextureHandle _handle, void* _data);
///
void readTexture(FrameBufferHandle _handle, uint8_t _attachment, void* _data);
/// Destroy texture.
///
/// @attention C99 equivalent is `bgfx_destroy_texture`.
@ -2052,12 +2058,18 @@ namespace bgfx
///
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);
///
void blit(uint8_t _id, TextureHandle _dst, uint16_t _dstX, uint16_t _dstY, FrameBufferHandle _src, uint8_t _attachment = 0, 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);
///
void blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, FrameBufferHandle _src, uint8_t _attachment = 0, 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.

View File

@ -311,6 +311,7 @@
#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_READ_BACK UINT32_C(0x00800000) //!<
#define BGFX_TEXTURE_BORDER_COLOR_SHIFT 24 //!<
#define BGFX_TEXTURE_BORDER_COLOR_MASK UINT32_C(0x0f000000) //!<
#define BGFX_TEXTURE_RESERVED_SHIFT 28 //!<
@ -367,7 +368,8 @@
#define BGFX_CAPS_INDEX32 UINT64_C(0x0000000000002000) //!< 32-bit indices are supported.
#define BGFX_CAPS_DRAW_INDIRECT UINT64_C(0x0000000000004000) //!< Draw indirect is supported.
#define BGFX_CAPS_HIDPI UINT64_C(0x0000000000008000) //!< HiDPI rendering is supported.
#define BGFX_CAPS_BLIT UINT64_C(0x0000000000010000) //!< Blit is supported.
#define BGFX_CAPS_TEXTURE_BLIT UINT64_C(0x0000000000010000) //!< Texture blit is supported.
#define BGFX_CAPS_TEXTURE_READ_BACK UINT64_C(0x0000000000020000) //!< Read-back texture is supported.
///
#define BGFX_CAPS_FORMAT_TEXTURE_NONE UINT8_C(0x00) //!< Texture format is not supported.

View File

@ -977,7 +977,7 @@ namespace bgfx
CAPS_FLAGS(BGFX_CAPS_INDEX32),
CAPS_FLAGS(BGFX_CAPS_DRAW_INDIRECT),
CAPS_FLAGS(BGFX_CAPS_HIDPI),
CAPS_FLAGS(BGFX_CAPS_BLIT),
CAPS_FLAGS(BGFX_CAPS_TEXTURE_BLIT),
#undef CAPS_FLAGS
};
@ -2058,6 +2058,18 @@ again:
}
break;
case CommandBuffer::ReadTexture:
{
TextureHandle handle;
_cmdbuf.read(handle);
void* data;
_cmdbuf.read(data);
m_renderCtx->readTexture(handle, data);
}
break;
case CommandBuffer::ResizeTexture:
{
TextureHandle handle;
@ -2903,6 +2915,20 @@ again:
}
}
void readTexture(TextureHandle _handle, void* _data)
{
BGFX_CHECK_MAIN_THREAD();
BX_CHECK(NULL != _data, "_data can't be NULL");
s_ctx->readTexture(_handle, _data);
}
void readTexture(FrameBufferHandle _handle, uint8_t _attachment, void* _data)
{
BGFX_CHECK_MAIN_THREAD();
BX_CHECK(NULL != _data, "_data can't be NULL");
s_ctx->readTexture(_handle, _attachment, _data);
}
FrameBufferHandle createFrameBuffer(uint16_t _width, uint16_t _height, TextureFormat::Enum _format, uint32_t _textureFlags)
{
_textureFlags |= _textureFlags&BGFX_TEXTURE_RT_MSAA_MASK ? 0 : BGFX_TEXTURE_RT;
@ -3278,12 +3304,23 @@ again:
blit(_id, _dst, 0, _dstX, _dstY, 0, _src, 0, _srcX, _srcY, 0, _width, _height, 0);
}
void blit(uint8_t _id, TextureHandle _dst, uint16_t _dstX, uint16_t _dstY, FrameBufferHandle _src, uint8_t _attachment, uint16_t _srcX, uint16_t _srcY, uint16_t _width, uint16_t _height)
{
blit(_id, _dst, 0, _dstX, _dstY, 0, _src, _attachment, 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 blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, FrameBufferHandle _src, uint8_t _attachment, 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, _attachment, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth);
}
void saveScreenShot(const char* _filePath)
{
BGFX_CHECK_MAIN_THREAD();

View File

@ -583,6 +583,7 @@ namespace bgfx
DestroyTexture,
DestroyFrameBuffer,
DestroyUniform,
ReadTexture,
SaveScreenShot,
};
@ -1941,6 +1942,7 @@ namespace bgfx
virtual void updateTextureBegin(TextureHandle _handle, uint8_t _side, uint8_t _mip) = 0;
virtual void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) = 0;
virtual void updateTextureEnd() = 0;
virtual void readTexture(TextureHandle _handle, void* _data) = 0;
virtual void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) = 0;
virtual void destroyTexture(TextureHandle _handle) = 0;
virtual void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const TextureHandle* _textureHandles) = 0;
@ -2990,6 +2992,22 @@ namespace bgfx
textureDecRef(_handle);
}
BGFX_API_FUNC(void readTexture(TextureHandle _handle, void* _data) )
{
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::ReadTexture);
cmdbuf.write(_handle);
cmdbuf.write(_data);
}
BGFX_API_FUNC(void readTexture(FrameBufferHandle _handle, uint8_t _attachment, void* _data) )
{
const FrameBufferRef& ref = m_frameBufferRef[_handle.idx];
BX_CHECK(!ref.m_window, "Can't sample window frame buffer.");
TextureHandle textureHandle = ref.un.m_th[_attachment];
BX_CHECK(isValid(textureHandle), "Frame buffer texture %d is invalid.", _attachment);
readTexture(textureHandle, _data);
}
void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height)
{
const TextureRef& textureRef = m_textureRef[_handle.idx];
@ -3623,6 +3641,15 @@ namespace bgfx
m_submit->blit(_id, _dst, _dstMip, _dstX, _dstY, _dstZ, _src, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth);
}
BGFX_API_FUNC(void blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, FrameBufferHandle _src, uint8_t _attachment, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth) )
{
const FrameBufferRef& ref = m_frameBufferRef[_src.idx];
BX_CHECK(!ref.m_window, "Can't sample window frame buffer.");
TextureHandle textureHandle = ref.un.m_th[_attachment];
BX_CHECK(isValid(textureHandle), "Frame buffer texture %d is invalid.", _attachment);
blit(_id, _dst, _dstMip, _dstX, _dstY, _dstZ, textureHandle, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth);
}
BGFX_API_FUNC(uint32_t frame() );
void dumpViewStats();

View File

@ -121,6 +121,7 @@ typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuin
typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
typedef void (GL_APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void);
typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data);
@ -139,6 +140,7 @@ typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint prog
typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name);
typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name);
typedef void (GL_APIENTRYP PFNGLGETTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, void *pixels);
typedef void (GL_APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params);
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params);
@ -302,6 +304,7 @@ GL_IMPORT______(true, PFNGLGENVERTEXARRAYSPROC, glGenVertexAr
GL_IMPORT______(false, PFNGLGETACTIVEATTRIBPROC, glGetActiveAttrib);
GL_IMPORT______(false, PFNGLGETATTRIBLOCATIONPROC, glGetAttribLocation);
GL_IMPORT______(false, PFNGLGETACTIVEUNIFORMPROC, glGetActiveUniform);
GL_IMPORT______(true, PFNGLGETCOMPRESSEDTEXIMAGEPROC, glGetCompressedTexImage);
GL_IMPORT______(true, PFNGLGETDEBUGMESSAGELOGPROC, glGetDebugMessageLog);
GL_IMPORT______(false, PFNGLGETERRORPROC, glGetError);
GL_IMPORT______(false, PFNGLGETFLOATVPROC, glGetFloatv);
@ -320,6 +323,7 @@ GL_IMPORT______(true, PFNGLGETPROGRAMRESOURCEIVPROC, glGetProgramR
GL_IMPORT______(true, PFNGLGETPROGRAMRESOURCENAMEPROC, glGetProgramResourceName);
GL_IMPORT______(true, PFNGLGETPROGRAMRESOURCELOCATIONPROC, glGetProgramResourceLocation);
GL_IMPORT______(true, PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC, glGetProgramResourceLocationIndex);
GL_IMPORT______(true, PFNGLGETTEXIMAGEPROC, glGetTexImage);
GL_IMPORT______(true, PFNGLGETQUERYIVPROC, glGetQueryiv);
GL_IMPORT______(true, PFNGLGETQUERYOBJECTIVPROC, glGetQueryObjectiv);
GL_IMPORT______(true, PFNGLGETQUERYOBJECTI64VPROC, glGetQueryObjecti64v);
@ -519,6 +523,9 @@ GL_IMPORT_____x(true, PFNGLMEMORYBARRIERPROC, glMemoryBarri
GL_IMPORT_____x(true, PFNGLDISPATCHCOMPUTEPROC, glDispatchCompute);
GL_IMPORT_____x(true, PFNGLDISPATCHCOMPUTEINDIRECTPROC, glDispatchComputeIndirect);
GL_IMPORT_____x(true, PFNGLGETCOMPRESSEDTEXIMAGEPROC, glGetCompressedTexImage);
GL_IMPORT_____x(true, PFNGLGETTEXIMAGEPROC, glGetTexImage);
GL_IMPORT_NV___(true, PFNGLDRAWBUFFERSPROC, glDrawBuffers);
GL_IMPORT_NV___(true, PFNGLGENQUERIESPROC, glGenQueries);
GL_IMPORT_NV___(true, PFNGLDELETEQUERIESPROC, glDeleteQueries);

View File

@ -1156,7 +1156,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();
| BGFX_CAPS_SWAP_CHAIN
| (m_ovr.isInitialized() ? BGFX_CAPS_HMD : 0)
| BGFX_CAPS_DRAW_INDIRECT
| BGFX_CAPS_BLIT
| BGFX_CAPS_TEXTURE_BLIT
| BGFX_CAPS_TEXTURE_READ_BACK
);
if (m_featureLevel <= D3D_FEATURE_LEVEL_9_2)
@ -1652,6 +1653,32 @@ BX_PRAGMA_DIAGNOSTIC_POP();
{
}
void readTexture(TextureHandle _handle, void* _data) BX_OVERRIDE
{
const TextureD3D11& texture = m_textures[_handle.idx];
D3D11_MAPPED_SUBRESOURCE mapped;
DX_CHECK(m_deviceCtx->Map(texture.m_ptr, 0, D3D11_MAP_READ, 0, &mapped) );
uint8_t* src = (uint8_t*)mapped.pData;
uint32_t srcPitch = mapped.RowPitch;
const uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(texture.m_textureFormat) );
uint8_t* dst = (uint8_t*)_data;
uint32_t dstPitch = texture.m_width*bpp/8;
uint32_t pitch = bx::uint32_min(srcPitch, dstPitch);
for (uint32_t yy = 0, height = texture.m_height; yy < height; ++yy)
{
memcpy(dst, src, pitch);
src += srcPitch;
dst += dstPitch;
}
m_deviceCtx->Unmap(texture.m_ptr, 0);
}
void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE
{
TextureD3D11& texture = m_textures[_handle.idx];
@ -3903,11 +3930,12 @@ BX_PRAGMA_DIAGNOSTIC_POP();
}
}
const bool bufferOnly = 0 != (m_flags&BGFX_TEXTURE_RT_BUFFER_ONLY);
const bool bufferOnly = 0 != (m_flags&(BGFX_TEXTURE_RT_BUFFER_ONLY|BGFX_TEXTURE_READ_BACK) );
const bool computeWrite = 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE);
const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK);
const bool srgb = 0 != (m_flags&BGFX_TEXTURE_SRGB) || imageContainer.m_srgb;
const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST);
const bool readBack = 0 != (m_flags&BGFX_TEXTURE_READ_BACK);
const uint32_t msaaQuality = bx::uint32_satsub( (m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1);
const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality];
@ -3966,6 +3994,13 @@ BX_PRAGMA_DIAGNOSTIC_POP();
desc.Usage = D3D11_USAGE_DEFAULT;
}
if (readBack)
{
desc.BindFlags = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
}
if (imageContainer.m_cubeMap)
{
desc.ArraySize = 6;

View File

@ -884,7 +884,7 @@ namespace bgfx { namespace d3d12
| BGFX_CAPS_COMPUTE
| (m_options.ROVsSupported ? BGFX_CAPS_FRAGMENT_ORDERING : 0)
// | BGFX_CAPS_SWAP_CHAIN
| BGFX_CAPS_BLIT
| BGFX_CAPS_TEXTURE_BLIT
);
g_caps.maxTextureSize = 16384;
g_caps.maxFBAttachments = uint8_t(bx::uint32_min(16, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) );
@ -1250,6 +1250,10 @@ namespace bgfx { namespace d3d12
{
}
void readTexture(TextureHandle /*_handle*/, void* /*_data*/) BX_OVERRIDE
{
}
void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE
{
TextureD3D12& texture = m_textures[_handle.idx];

View File

@ -535,7 +535,8 @@ namespace bgfx { namespace d3d9
| BGFX_CAPS_FRAGMENT_DEPTH
| BGFX_CAPS_SWAP_CHAIN
| ( (UINT16_MAX < m_caps.MaxVertexIndex) ? BGFX_CAPS_INDEX32 : 0)
| ( (m_caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) ? BGFX_CAPS_BLIT : 0)
// | ( (m_caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) ? BGFX_CAPS_TEXTURE_BLIT : 0)
// | BGFX_CAPS_TEXTURE_READ_BACK
);
g_caps.maxTextureSize = uint16_t(bx::uint32_min(m_caps.MaxTextureWidth, m_caps.MaxTextureHeight) );
// g_caps.maxVertexIndex = m_caps.MaxVertexIndex;
@ -902,6 +903,37 @@ namespace bgfx { namespace d3d9
m_updateTexture = NULL;
}
void readTexture(TextureHandle _handle, void* _data) BX_OVERRIDE
{
TextureD3D9& texture = m_textures[_handle.idx];
D3DLOCKED_RECT lockedRect;
DX_CHECK(texture.m_texture2d->LockRect(0
, &lockedRect
, NULL
, D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY
) );
uint32_t srcPitch = lockedRect.Pitch;
uint8_t* src = (uint8_t*)lockedRect.pBits;
const uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(texture.m_textureFormat) );
uint8_t* dst = (uint8_t*)_data;
uint32_t dstPitch = texture.m_width*bpp/8;
uint32_t pitch = bx::uint32_min(srcPitch, dstPitch);
for (uint32_t yy = 0, height = texture.m_height; yy < height; ++yy)
{
memcpy(dst, src, pitch);
src += srcPitch;
dst += dstPitch;
}
DX_CHECK(texture.m_texture2d->UnlockRect(0) );
}
void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE
{
TextureD3D9& texture = m_textures[_handle.idx];

View File

@ -1204,6 +1204,7 @@ namespace bgfx { namespace gl
, m_maxMsaa(0)
, m_vao(0)
, m_blitSupported(false)
, m_readBackSupported(false)
, m_vaoSupport(false)
, m_samplerObjectSupport(false)
, m_shadowSamplersSupport(false)
@ -1713,7 +1714,7 @@ namespace bgfx { namespace gl
{
m_blitSupported = NULL != glCopyImageSubData;
g_caps.supported |= m_blitSupported
? BGFX_CAPS_BLIT
? BGFX_CAPS_TEXTURE_BLIT
: 0
;
}
@ -2093,6 +2094,36 @@ namespace bgfx { namespace gl
{
}
void readTexture(TextureHandle _handle, void* _data) BX_OVERRIDE
{
if (m_readBackSupported)
{
const TextureGL& texture = m_textures[_handle.idx];
const bool compressed = isCompressed(TextureFormat::Enum(texture.m_textureFormat) );
GL_CHECK(glBindTexture(texture.m_target, texture.m_id) );
if (compressed)
{
GL_CHECK(glGetCompressedTexImage(texture.m_target
, 0
, _data
) );
}
else
{
GL_CHECK(glGetTexImage(texture.m_target
, 0
, texture.m_fmt
, texture.m_type
, _data
) );
}
GL_CHECK(glBindTexture(texture.m_target, 0) );
}
}
void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE
{
TextureGL& texture = m_textures[_handle.idx];
@ -3106,6 +3137,7 @@ namespace bgfx { namespace gl
int32_t m_maxMsaa;
GLuint m_vao;
bool m_blitSupported;
bool m_readBackSupported;
bool m_vaoSupport;
bool m_samplerObjectSupport;
bool m_shadowSamplersSupport;

View File

@ -612,6 +612,10 @@ namespace bgfx { namespace mtl
{
}
void readTexture(TextureHandle /*_handle*/, void* /*_data*/) BX_OVERRIDE
{
}
void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE
{
TextureMtl& texture = m_textures[_handle.idx];

View File

@ -113,6 +113,10 @@ namespace bgfx { namespace noop
{
}
void readTexture(TextureHandle /*_handle*/, void* /*_data*/) BX_OVERRIDE
{
}
void resizeTexture(TextureHandle /*_handle*/, uint16_t /*_width*/, uint16_t /*_height*/) BX_OVERRIDE
{
}