mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-11-09 09:35:43 +00:00
Fixed BC texture block-size rounding in readback/create/update. (#3822)
This commit is contained in:
+16
-7
@@ -1923,13 +1923,16 @@ namespace bgfx { namespace d3d11
|
||||
uint8_t* src = (uint8_t*)mapped.pData;
|
||||
uint32_t srcPitch = mapped.RowPitch;
|
||||
|
||||
const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(texture.m_textureFormat) );
|
||||
const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(texture.m_textureFormat) );
|
||||
const uint32_t blockWidth = bx::max<uint32_t>(1, blockInfo.blockWidth);
|
||||
const uint32_t blockHeight = bx::max<uint32_t>(1, blockInfo.blockHeight);
|
||||
uint8_t* dst = (uint8_t*)_data;
|
||||
uint32_t dstPitch = srcWidth*bpp/8;
|
||||
uint32_t dstPitch = ( (srcWidth + blockWidth - 1)/blockWidth)*blockInfo.blockSize;
|
||||
uint32_t numRows = (srcHeight + blockHeight - 1)/blockHeight;
|
||||
|
||||
uint32_t pitch = bx::min(srcPitch, dstPitch);
|
||||
|
||||
bx::memCopy(dst, dstPitch, src, srcPitch, pitch, srcHeight);
|
||||
bx::memCopy(dst, dstPitch, src, srcPitch, pitch, numRows);
|
||||
|
||||
m_deviceCtx->Unmap(texture.m_ptr, subresource);
|
||||
}
|
||||
@@ -4451,8 +4454,8 @@ namespace bgfx { namespace d3d11
|
||||
}
|
||||
else if (compressed)
|
||||
{
|
||||
srd[kk].SysMemPitch = (mip.m_width /blockInfo.blockWidth )*mip.m_blockSize;
|
||||
srd[kk].SysMemSlicePitch = (mip.m_height/blockInfo.blockHeight)*srd[kk].SysMemPitch;
|
||||
const uint32_t numBlocksX = (mip.m_width + blockInfo.blockWidth - 1) / blockInfo.blockWidth;
|
||||
srd[kk].SysMemPitch = numBlocksX * mip.m_blockSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4478,7 +4481,7 @@ namespace bgfx { namespace d3d11
|
||||
}
|
||||
}
|
||||
|
||||
srd[kk].SysMemSlicePitch = mip.m_height*srd[kk].SysMemPitch;
|
||||
srd[kk].SysMemSlicePitch = ( (mip.m_height + blockInfo.blockHeight - 1) / blockInfo.blockHeight) * srd[kk].SysMemPitch;
|
||||
++kk;
|
||||
}
|
||||
}
|
||||
@@ -4885,7 +4888,13 @@ namespace bgfx { namespace d3d11
|
||||
uint32_t rectPitch = _rect.m_width*bpp/8;
|
||||
if (bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ) )
|
||||
{
|
||||
rectPitch = (_rect.m_width / blockInfo.blockWidth)*blockInfo.blockSize;
|
||||
const uint32_t blockW = blockInfo.blockWidth;
|
||||
const uint32_t blockH = blockInfo.blockHeight;
|
||||
const uint32_t alignedW = bx::max<uint32_t>(blockW, bx::alignUp(_rect.m_width, blockW) );
|
||||
const uint32_t alignedH = bx::max<uint32_t>(blockH, bx::alignUp(_rect.m_height, blockH) );
|
||||
box.right = box.left + alignedW;
|
||||
box.bottom = box.top + alignedH;
|
||||
rectPitch = (alignedW / blockW) * blockInfo.blockSize;
|
||||
}
|
||||
|
||||
const uint32_t srcPitch = UINT16_MAX == _pitch ? rectPitch : _pitch;
|
||||
|
||||
+23
-12
@@ -2279,16 +2279,19 @@ namespace bgfx { namespace d3d12
|
||||
finish();
|
||||
m_commandList = m_cmd.alloc();
|
||||
|
||||
const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(texture.m_textureFormat) );
|
||||
const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(texture.m_textureFormat) );
|
||||
const uint32_t blockWidth = bx::max<uint32_t>(1, blockInfo.blockWidth);
|
||||
const uint32_t blockHeight = bx::max<uint32_t>(1, blockInfo.blockHeight);
|
||||
uint8_t* dst = (uint8_t*)_data;
|
||||
uint32_t dstPitch = srcWidth*bpp/8;
|
||||
uint32_t dstPitch = ( (srcWidth + blockWidth - 1)/blockWidth)*blockInfo.blockSize;
|
||||
uint32_t numBlockRows = (srcHeight + blockHeight - 1)/blockHeight;
|
||||
|
||||
uint32_t pitch = bx::min(srcPitch, dstPitch);
|
||||
|
||||
uint8_t* src;
|
||||
readback->Map(0, NULL, (void**)&src);
|
||||
|
||||
bx::memCopy(dst, dstPitch, src, srcPitch, pitch, srcHeight);
|
||||
bx::memCopy(dst, dstPitch, src, srcPitch, pitch, numBlockRows);
|
||||
|
||||
D3D12_RANGE writeRange = { 0, 0 };
|
||||
readback->Unmap(0, &writeRange);
|
||||
@@ -5952,14 +5955,16 @@ namespace bgfx { namespace d3d12
|
||||
}
|
||||
else if (compressed)
|
||||
{
|
||||
const uint32_t pitch = bx::strideAlign( (mip.m_width /blockInfo.blockWidth )*mip.m_blockSize, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
const uint32_t slice = bx::strideAlign( (mip.m_height/blockInfo.blockHeight)*pitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
|
||||
const uint32_t numBlocksX = (mip.m_width + blockInfo.blockWidth - 1) / blockInfo.blockWidth;
|
||||
const uint32_t numBlocksY = (mip.m_height + blockInfo.blockHeight - 1) / blockInfo.blockHeight;
|
||||
const uint32_t pitch = bx::strideAlign(numBlocksX*mip.m_blockSize, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
const uint32_t slice = bx::strideAlign(numBlocksY*pitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
|
||||
const uint32_t size = slice*mip.m_depth;
|
||||
|
||||
uint8_t* temp = (uint8_t*)bx::alloc(g_allocator, size);
|
||||
bimg::imageCopy(temp
|
||||
, mip.m_height/blockInfo.blockHeight
|
||||
, (mip.m_width /blockInfo.blockWidth )*mip.m_blockSize
|
||||
, numBlocksY
|
||||
, numBlocksX*mip.m_blockSize
|
||||
, mip.m_depth
|
||||
, mip.m_data
|
||||
, pitch
|
||||
@@ -6394,10 +6399,16 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
const uint32_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) );
|
||||
uint32_t rectPitch = _rect.m_width*bpp/8;
|
||||
uint32_t boxWidth = _rect.m_width;
|
||||
uint32_t boxHeight = _rect.m_height;
|
||||
if (bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ) )
|
||||
{
|
||||
const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat) );
|
||||
rectPitch = (_rect.m_width / blockInfo.blockWidth) * blockInfo.blockSize;
|
||||
const uint32_t blockW = blockInfo.blockWidth;
|
||||
const uint32_t blockH = blockInfo.blockHeight;
|
||||
boxWidth = bx::max<uint32_t>(blockW, bx::alignUp(_rect.m_width, blockW) );
|
||||
boxHeight = bx::max<uint32_t>(blockH, bx::alignUp(_rect.m_height, blockH) );
|
||||
rectPitch = (boxWidth / blockW) * blockInfo.blockSize;
|
||||
}
|
||||
|
||||
const uint32_t srcPitch = UINT16_MAX == _pitch ? rectPitch : _pitch;
|
||||
@@ -6408,8 +6419,8 @@ namespace bgfx { namespace d3d12
|
||||
D3D12_BOX box;
|
||||
box.left = 0;
|
||||
box.top = 0;
|
||||
box.right = box.left + _rect.m_width;
|
||||
box.bottom = box.top + _rect.m_height;
|
||||
box.right = box.left + boxWidth;
|
||||
box.bottom = box.top + boxHeight;
|
||||
|
||||
box.front = 0;
|
||||
box.back = _depth;
|
||||
@@ -6446,8 +6457,8 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
D3D12_RESOURCE_DESC desc = getResourceDesc(m_ptr);
|
||||
|
||||
desc.Width = _rect.m_width;
|
||||
desc.Height = _rect.m_height;
|
||||
desc.Width = boxWidth;
|
||||
desc.Height = boxHeight;
|
||||
|
||||
if (TextureD3D12::Texture3D == m_type)
|
||||
{
|
||||
|
||||
+16
-4
@@ -1374,9 +1374,17 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
|
||||
const uint32_t srcHeight = bx::max(1, texture.m_ptr->height() >> _mip);
|
||||
const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(texture.m_textureFormat) );
|
||||
|
||||
const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(texture.m_textureFormat) );
|
||||
const uint32_t numBlocksX = (srcWidth + blockInfo.blockWidth - 1) / blockInfo.blockWidth;
|
||||
const uint32_t bytesPerRow = bimg::isCompressed(bimg::TextureFormat::Enum(texture.m_textureFormat) )
|
||||
? numBlocksX * blockInfo.blockSize
|
||||
: srcWidth * bpp / 8
|
||||
;
|
||||
BX_UNUSED(bpp);
|
||||
|
||||
MTL::Region region(0, 0, 0, srcWidth, srcHeight, 1);
|
||||
|
||||
texture.m_ptr->getBytes(_data, srcWidth*bpp/8, 0, region, _mip, _layer);
|
||||
texture.m_ptr->getBytes(_data, bytesPerRow, 0, region, _mip, _layer);
|
||||
}
|
||||
|
||||
void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips, uint16_t _numLayers) override
|
||||
@@ -3820,9 +3828,11 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
|
||||
}
|
||||
else
|
||||
{
|
||||
bytesPerRow = (mip.m_width / blockInfo.blockWidth)*mip.m_blockSize;
|
||||
const uint32_t numBlocksX = (mip.m_width + blockInfo.blockWidth - 1) / blockInfo.blockWidth;
|
||||
const uint32_t numBlocksY = (mip.m_height + blockInfo.blockHeight - 1) / blockInfo.blockHeight;
|
||||
bytesPerRow = numBlocksX * mip.m_blockSize;
|
||||
bytesPerImage = desc->textureType() == MTL::TextureType3D
|
||||
? (mip.m_height/blockInfo.blockHeight)*bytesPerRow
|
||||
? numBlocksY * bytesPerRow
|
||||
: 0
|
||||
;
|
||||
}
|
||||
@@ -3920,7 +3930,9 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
|
||||
else
|
||||
{
|
||||
const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat) );
|
||||
rectpitch = (_rect.m_width / blockInfo.blockWidth)*blockInfo.blockSize;
|
||||
const uint32_t blockW = blockInfo.blockWidth;
|
||||
const uint32_t alignedW = bx::max<uint32_t>(blockW, bx::alignUp(_rect.m_width, blockW) );
|
||||
rectpitch = (alignedW / blockW)*blockInfo.blockSize;
|
||||
}
|
||||
}
|
||||
const uint32_t srcpitch = UINT16_MAX == _pitch ? rectpitch : _pitch;
|
||||
|
||||
+36
-13
@@ -6358,9 +6358,10 @@ VK_DESTROY
|
||||
|
||||
uint32_t ReadbackVK::pitch(uint8_t _mip) const
|
||||
{
|
||||
uint32_t mipWidth = bx::max(1, m_width >> _mip);
|
||||
uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_format) );
|
||||
return mipWidth * bpp / 8;
|
||||
const uint32_t mipWidth = bx::max(1, m_width >> _mip);
|
||||
const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_format) );
|
||||
const uint32_t numBlocksX = (mipWidth + blockInfo.blockWidth - 1) / blockInfo.blockWidth;
|
||||
return numBlocksX * blockInfo.blockSize;
|
||||
}
|
||||
|
||||
void ReadbackVK::copyImageToBuffer(VkCommandBuffer _commandBuffer, VkBuffer _buffer, VkImageLayout _layout, VkImageAspectFlags _aspect, uint16_t _layer, uint8_t _mip) const
|
||||
@@ -6370,6 +6371,10 @@ VK_DESTROY
|
||||
uint32_t mipWidth = bx::max(1, m_width >> _mip);
|
||||
uint32_t mipHeight = bx::max(1, m_height >> _mip);
|
||||
|
||||
const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_format) );
|
||||
const uint32_t numBlocksX = (mipWidth + blockInfo.blockWidth - 1) / blockInfo.blockWidth;
|
||||
const uint32_t numBlocksY = (mipHeight + blockInfo.blockHeight - 1) / blockInfo.blockHeight;
|
||||
|
||||
setImageMemoryBarrier(
|
||||
_commandBuffer
|
||||
, m_image
|
||||
@@ -6384,8 +6389,8 @@ VK_DESTROY
|
||||
|
||||
VkBufferImageCopy bic;
|
||||
bic.bufferOffset = 0;
|
||||
bic.bufferRowLength = mipWidth;
|
||||
bic.bufferImageHeight = mipHeight;
|
||||
bic.bufferRowLength = numBlocksX * blockInfo.blockWidth;
|
||||
bic.bufferImageHeight = numBlocksY * blockInfo.blockHeight;
|
||||
bic.imageSubresource.aspectMask = _aspect;
|
||||
bic.imageSubresource.mipLevel = _mip;
|
||||
bic.imageSubresource.baseArrayLayer = _layer;
|
||||
@@ -6434,11 +6439,14 @@ VK_DESTROY
|
||||
const uint32_t mipHeight = bx::max(1, m_height >> _mip);
|
||||
const uint32_t rowPitch = pitch(_mip);
|
||||
|
||||
const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_format) );
|
||||
const uint32_t numRows = (mipHeight + blockInfo.blockHeight - 1) / blockInfo.blockHeight;
|
||||
|
||||
const uint8_t* src;
|
||||
VK_CHECK(vkMapMemory(s_renderVK->m_device, _memory, 0, VK_WHOLE_SIZE, 0, (void**)&src) );
|
||||
src += _offset;
|
||||
|
||||
bx::gather(_data, src, rowPitch, rowPitch, mipHeight);
|
||||
bx::gather(_data, src, rowPitch, rowPitch, numRows);
|
||||
|
||||
vkUnmapMemory(s_renderVK->m_device, _memory);
|
||||
}
|
||||
@@ -6810,15 +6818,17 @@ VK_DESTROY
|
||||
}
|
||||
else if (compressed)
|
||||
{
|
||||
const uint32_t pitch = bx::strideAlign( (mip.m_width / blockInfo.blockWidth) * mip.m_blockSize, alignment);
|
||||
const uint32_t slice = bx::strideAlign( (mip.m_height / blockInfo.blockHeight) * pitch, alignment);
|
||||
const uint32_t numBlocksX = (mip.m_width + blockInfo.blockWidth - 1) / blockInfo.blockWidth;
|
||||
const uint32_t numBlocksY = (mip.m_height + blockInfo.blockHeight - 1) / blockInfo.blockHeight;
|
||||
const uint32_t pitch = bx::strideAlign(numBlocksX * mip.m_blockSize, alignment);
|
||||
const uint32_t slice = bx::strideAlign(numBlocksY * pitch, alignment);
|
||||
const uint32_t size = slice * mip.m_depth;
|
||||
|
||||
uint8_t* temp = (uint8_t*)bx::alloc(g_allocator, size);
|
||||
bimg::imageCopy(
|
||||
temp
|
||||
, mip.m_height / blockInfo.blockHeight
|
||||
, (mip.m_width / blockInfo.blockWidth) * mip.m_blockSize
|
||||
, numBlocksY
|
||||
, numBlocksX * mip.m_blockSize
|
||||
, mip.m_depth
|
||||
, mip.m_data
|
||||
, pitch
|
||||
@@ -7032,8 +7042,14 @@ VK_DESTROY
|
||||
numRows = numBlocksY;
|
||||
}
|
||||
|
||||
const uint32_t srcPitch = UINT16_MAX == _pitch ? rectPitch : _pitch;
|
||||
const uint32_t size = convert || UINT16_MAX == _pitch
|
||||
const bool repackPitch = true
|
||||
&& !convert
|
||||
&& UINT16_MAX != _pitch
|
||||
&& _pitch != rectPitch
|
||||
;
|
||||
|
||||
const uint32_t srcPitch = (UINT16_MAX == _pitch || repackPitch) ? rectPitch : _pitch;
|
||||
const uint32_t size = convert || UINT16_MAX == _pitch || repackPitch
|
||||
? slicePitch * _depth
|
||||
: numRows * srcPitch * _depth
|
||||
;
|
||||
@@ -7042,7 +7058,8 @@ VK_DESTROY
|
||||
// formats, must be a multiple of the block width.
|
||||
uint32_t bufferRowLength = 0;
|
||||
if (!convert
|
||||
&& UINT16_MAX != _pitch)
|
||||
&& UINT16_MAX != _pitch
|
||||
&& !repackPitch)
|
||||
{
|
||||
bufferRowLength = compressed
|
||||
? (srcPitch / blockInfo.blockSize) * blockInfo.blockWidth
|
||||
@@ -7073,6 +7090,12 @@ VK_DESTROY
|
||||
region.imageExtent.width = bx::clamp<uint32_t>(region.imageExtent.width, 0u, bx::max(1u, m_width >> _mip) - _rect.m_x);
|
||||
region.imageExtent.height = bx::clamp<uint32_t>(region.imageExtent.height, 0u, bx::max(1u, m_height >> _mip) - _rect.m_y);
|
||||
}
|
||||
else if (repackPitch)
|
||||
{
|
||||
temp = (uint8_t*)bx::alloc(g_allocator, slicePitch * _depth);
|
||||
bimg::imageCopy(temp, numRows, _pitch, _depth, data, rectPitch);
|
||||
data = temp;
|
||||
}
|
||||
|
||||
StagingBufferVK stagingBuffer = s_renderVK->allocFromScratchStagingBuffer(size, align, data);
|
||||
region.bufferOffset += stagingBuffer.m_offset;
|
||||
|
||||
Reference in New Issue
Block a user