diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 1aa10fe6e..fdbcee6c9 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -3204,6 +3204,11 @@ namespace bgfx BGFX_API_FUNC(uint32_t readTexture(TextureHandle _handle, void* _data, uint8_t _mip) ) { + BGFX_CHECK_HANDLE("readTexture", m_textureHandle, _handle); + + const TextureRef& ref = m_textureRef[_handle.idx]; + BX_CHECK(_mip < ref.m_numMips, "Invalid mip: %d num mips:", _mip, ref.m_numMips); BX_UNUSED(ref); + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::ReadTexture); cmdbuf.write(_handle); cmdbuf.write(_data); @@ -3215,8 +3220,10 @@ namespace bgfx { 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); + BGFX_CHECK_HANDLE("readTexture", m_textureHandle, textureHandle); + return readTexture(textureHandle, _data,0); } diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 98e7a9caa..df860e310 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -1844,11 +1844,10 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { const TextureD3D11& texture = m_textures[_handle.idx]; D3D11_MAPPED_SUBRESOURCE mapped; - BX_CHECK(_mipMap(texture.m_ptr, _mip, D3D11_MAP_READ, 0, &mapped) ); - uint32_t srcWidth = texture.m_width>>_mip; - uint32_t srcHeight = texture.m_height>>_mip; + uint32_t srcWidth = bx::uint32_max(1, texture.m_width >>_mip); + uint32_t srcHeight = bx::uint32_max(1, texture.m_height>>_mip); uint8_t* src = (uint8_t*)mapped.pData; uint32_t srcPitch = mapped.RowPitch; diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 01d86879f..d7a449ea8 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -1403,7 +1403,6 @@ namespace bgfx { namespace d3d12 void readTexture(TextureHandle _handle, void* _data, uint8_t _mip ) BX_OVERRIDE { - _mip; const TextureD3D12& texture = m_textures[_handle.idx]; D3D12_RESOURCE_DESC desc = texture.m_ptr->GetDesc(); @@ -1413,7 +1412,7 @@ namespace bgfx { namespace d3d12 uint64_t total; uint64_t srcPitch; m_device->GetCopyableFootprints(&desc - , 0 + , _mip , 1 , 0 , &layout @@ -1439,16 +1438,18 @@ namespace bgfx { namespace d3d12 finish(); m_commandList = m_cmd.alloc(); + uint32_t srcWidth = bx::uint32_max(1, texture.m_width >>_mip); + uint32_t srcHeight = bx::uint32_max(1, texture.m_height>>_mip); uint8_t* src; readback->Map(0, NULL, (void**)&src); 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 dstPitch = srcWidth*bpp/8; uint32_t pitch = bx::uint32_min(uint32_t(srcPitch), dstPitch); - for (uint32_t yy = 0, height = texture.m_height; yy < height; ++yy) + for (uint32_t yy = 0, height = srcHeight; yy < height; ++yy) { memcpy(dst, src, pitch); diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index abe7847f6..72ac1e539 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -990,7 +990,6 @@ namespace bgfx { namespace d3d9 void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) BX_OVERRIDE { TextureD3D9& texture = m_textures[_handle.idx]; - BX_CHECK( _mipLockRect(_mip @@ -999,8 +998,8 @@ namespace bgfx { namespace d3d9 , D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY ) ); - uint32_t srcWidth = texture.m_width>>_mip; - uint32_t srcHeight = texture.m_height>>_mip; + uint32_t srcWidth = bx::uint32_max(1, texture.m_width >>_mip); + uint32_t srcHeight = bx::uint32_max(1, texture.m_height>>_mip); uint32_t srcPitch = lockedRect.Pitch; uint8_t* src = (uint8_t*)lockedRect.pBits; diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index 7f67ac635..b45b8a2fe 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -806,13 +806,13 @@ namespace bgfx { namespace mtl BX_CHECK(_mip> _mip; - uint32_t height = texture.m_ptr.height() >> _mip; + uint32_t srcWidth = bx::uint32_max(1, texture.m_ptr.width() >> _mip); + uint32_t srcHeight = bx::uint32_max(1, texture.m_ptr.height() >> _mip); const uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(texture.m_textureFormat) ); - MTLRegion region = { { 0, 0, 0 }, { width, height, 1 } }; + MTLRegion region = { { 0, 0, 0 }, { srcWidth, srcHeight, 1 } }; - texture.m_ptr.getBytes(_data, width*bpp/8, 0, region, _mip, 0); + texture.m_ptr.getBytes(_data, srcWidth*bpp/8, 0, region, _mip, 0); m_commandBuffer = m_commandQueue.commandBuffer(); retain(m_commandBuffer); //NOTE: keep alive to be useable at 'flip'