Mip + blit fixes (#2281)

* D3D12: Fix readback for non-zero mip

* Fix blit with non-zero mip

This required clamping the blit extents to the mip size, which is moved out of the renderers now

* Assert formatting
This commit is contained in:
pezcode 2020-10-10 00:32:50 +02:00 committed by GitHub
parent 7f2861eceb
commit 09c11bca29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 85 additions and 103 deletions

View File

@ -3866,8 +3866,37 @@ namespace bgfx
, bimg::getName(bimg::TextureFormat::Enum(src.m_format) )
, bimg::getName(bimg::TextureFormat::Enum(dst.m_format) )
);
BX_UNUSED(src, dst);
BGFX_ENCODER(blit(_id, _dst, _dstMip, _dstX, _dstY, _dstZ, _src, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth) );
BX_ASSERT(_srcMip < src.m_numMips, "Invalid blit src mip (%d > %d)", _srcMip, src.m_numMips - 1);
BX_ASSERT(_dstMip < dst.m_numMips, "Invalid blit dst mip (%d > %d)", _dstMip, dst.m_numMips - 1);
uint32_t srcWidth = bx::uint32_max(1, src.m_width >> _srcMip);
uint32_t srcHeight = bx::uint32_max(1, src.m_height >> _srcMip);
uint32_t srcDepth = bx::uint32_max(1, src.m_depth >> _srcMip);
uint32_t dstWidth = bx::uint32_max(1, dst.m_width >> _dstMip);
uint32_t dstHeight = bx::uint32_max(1, dst.m_height >> _dstMip);
uint32_t dstDepth = bx::uint32_max(1, dst.m_depth >> _dstMip);
BX_ASSERT(_srcX < srcWidth && _srcY < srcHeight && _srcZ < srcDepth
, "Blit src coordinates out of range (%d,%d,%d) >= (%d,%d,%d)"
, _srcX, _srcY, _srcZ
, srcWidth, srcHeight, srcDepth);
BX_ASSERT(_dstX < dstWidth && _dstY < dstHeight && _dstZ < dstDepth
, "Blit dst coordinates out of range (%d,%d,%d) >= (%d,%d,%d)"
, _dstX, _dstY, _dstZ
, dstWidth, dstHeight, dstDepth);
srcWidth = bx::uint32_min(srcWidth, _srcX + _width) - _srcX;
srcHeight = bx::uint32_min(srcHeight, _srcY + _height) - _srcY;
srcDepth = bx::uint32_min(srcDepth, _srcZ + _depth) - _srcZ;
dstWidth = bx::uint32_min(dstWidth, _dstX + _width) - _dstX;
dstHeight = bx::uint32_min(dstHeight, _dstY + _height) - _dstY;
dstDepth = bx::uint32_min(dstDepth, _dstZ + _depth) - _dstZ;
uint16_t width = uint16_t(bx::min(srcWidth, dstWidth));
uint16_t height = uint16_t(bx::min(srcHeight, dstHeight));
uint16_t depth = uint16_t(bx::min(srcDepth, dstDepth));
BGFX_ENCODER(blit(_id, _dst, _dstMip, _dstX, _dstY, _dstZ, _src, _srcMip, _srcX, _srcY, _srcZ, width, height, depth) );
}
#undef BGFX_ENCODER

View File

@ -1811,6 +1811,9 @@ namespace bgfx
{
void init(
BackbufferRatio::Enum _ratio
, uint16_t _width
, uint16_t _height
, uint16_t _depth
, TextureFormat::Enum _format
, uint32_t _storageSize
, uint8_t _numMips
@ -1824,6 +1827,9 @@ namespace bgfx
m_storageSize = _storageSize;
m_refCount = 1;
m_bbRatio = uint8_t(_ratio);
m_width = _width;
m_height = _height;
m_depth = _depth;
m_format = uint8_t(_format);
m_numMips = _numMips;
m_numLayers = _numLayers;
@ -1848,6 +1854,9 @@ namespace bgfx
uint32_t m_storageSize;
int16_t m_refCount;
uint8_t m_bbRatio;
uint16_t m_width;
uint16_t m_height;
uint16_t m_depth;
uint8_t m_format;
uint8_t m_numMips;
uint16_t m_numLayers;
@ -4248,6 +4257,9 @@ namespace bgfx
TextureRef& ref = m_textureRef[handle.idx];
ref.init(
_ratio
, (uint16_t)imageContainer.m_width
, (uint16_t)imageContainer.m_height
, (uint16_t)imageContainer.m_depth
, _info->format
, _info->storageSize
, imageContainer.m_numMips

View File

@ -5425,25 +5425,15 @@ namespace bgfx { namespace d3d11
const TextureD3D11& src = m_textures[blit.m_src.idx];
const TextureD3D11& dst = m_textures[blit.m_dst.idx];
uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX;
uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY;
uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ;
uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX;
uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY;
uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ;
uint32_t width = bx::uint32_min(srcWidth, dstWidth);
uint32_t height = bx::uint32_min(srcHeight, dstHeight);
uint32_t depth = bx::uint32_min(srcDepth, dstDepth);
if (TextureD3D11::Texture3D == src.m_type)
{
D3D11_BOX box;
box.left = blit.m_srcX;
box.top = blit.m_srcY;
box.front = blit.m_srcZ;
box.right = blit.m_srcX + width;
box.bottom = blit.m_srcY + height;;
box.back = blit.m_srcZ + bx::uint32_imax(1, depth);
box.right = blit.m_srcX + blit.m_width;
box.bottom = blit.m_srcY + blit.m_height;
box.back = blit.m_srcZ + bx::uint32_imax(1, blit.m_depth);
deviceCtx->CopySubresourceRegion(dst.m_ptr
, blit.m_dstMip
@ -5459,7 +5449,7 @@ namespace bgfx { namespace d3d11
{
bool depthStencil = bimg::isDepth(bimg::TextureFormat::Enum(src.m_textureFormat) );
BX_ASSERT(!depthStencil
|| (width == src.m_width && height == src.m_height)
|| (blit.m_width == bx::uint32_max(1, src.m_width >> blit.m_srcMip) && blit.m_height == bx::uint32_max(1, src.m_height >> blit.m_srcMip))
, "When blitting depthstencil surface, source resolution must match destination."
);
@ -5467,8 +5457,8 @@ namespace bgfx { namespace d3d11
box.left = blit.m_srcX;
box.top = blit.m_srcY;
box.front = 0;
box.right = blit.m_srcX + width;
box.bottom = blit.m_srcY + height;
box.right = blit.m_srcX + blit.m_width;
box.bottom = blit.m_srcY + blit.m_height;
box.back = 1;
const uint32_t srcZ = blit.m_srcZ;

View File

@ -1656,31 +1656,32 @@ namespace bgfx { namespace d3d12
ID3D12Resource* readback = createCommittedResource(m_device, HeapProperty::ReadBack, total);
uint32_t srcWidth = bx::uint32_max(1, texture.m_width >>_mip);
uint32_t srcHeight = bx::uint32_max(1, texture.m_height>>_mip);
D3D12_BOX box;
box.left = 0;
box.top = 0;
box.right = texture.m_width;
box.bottom = texture.m_height;
box.right = srcWidth;
box.bottom = srcHeight;
box.front = 0;
box.back = 1;
D3D12_TEXTURE_COPY_LOCATION dstLocation = { readback, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, { layout } };
D3D12_TEXTURE_COPY_LOCATION srcLocation = { texture.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, {} };
D3D12_TEXTURE_COPY_LOCATION srcLocation = { texture.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, { } };
srcLocation.SubresourceIndex = _mip;
m_commandList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, &box);
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;
const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(texture.m_textureFormat) );
uint8_t* dst = (uint8_t*)_data;
uint32_t dstPitch = srcWidth*bpp/8;
uint32_t pitch = bx::uint32_min(srcPitch, dstPitch);
uint8_t* src;
readback->Map(0, NULL, (void**)&src);
for (uint32_t yy = 0, height = srcHeight; yy < height; ++yy)
@ -5831,28 +5832,20 @@ namespace bgfx { namespace d3d12
state = src.setState(m_commandList, D3D12_RESOURCE_STATE_COPY_SOURCE);
}
uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX;
uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY;
uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ;
uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX;
uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY;
uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ;
uint32_t width = bx::uint32_min(srcWidth, dstWidth);
uint32_t height = bx::uint32_min(srcHeight, dstHeight);
uint32_t depth = bx::uint32_min(srcDepth, dstDepth);
if (TextureD3D12::Texture3D == src.m_type)
{
D3D12_BOX box;
box.left = blit.m_srcX;
box.top = blit.m_srcY;
box.front = blit.m_srcZ;
box.right = blit.m_srcX + width;
box.bottom = blit.m_srcY + height;;
box.back = blit.m_srcZ + bx::uint32_imax(1, depth);
box.right = blit.m_srcX + blit.m_width;
box.bottom = blit.m_srcY + blit.m_height;
box.back = blit.m_srcZ + bx::uint32_imax(1, blit.m_depth);
D3D12_TEXTURE_COPY_LOCATION dstLocation = { dst.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, { { 0, { DXGI_FORMAT_UNKNOWN, 0, 0, 0, 0 } } } };
D3D12_TEXTURE_COPY_LOCATION srcLocation = { src.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, { { 0, { DXGI_FORMAT_UNKNOWN, 0, 0, 0, 0 } } } };
D3D12_TEXTURE_COPY_LOCATION dstLocation = { dst.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, { } };
dstLocation.SubresourceIndex = blit.m_dstMip;
D3D12_TEXTURE_COPY_LOCATION srcLocation = { src.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, { } };
srcLocation.SubresourceIndex = blit.m_srcMip;
m_commandList->CopyTextureRegion(&dstLocation
, blit.m_dstX
, blit.m_dstY
@ -5867,8 +5860,8 @@ namespace bgfx { namespace d3d12
box.left = blit.m_srcX;
box.top = blit.m_srcY;
box.front = 0;
box.right = blit.m_srcX + width;
box.bottom = blit.m_srcY + height;;
box.right = blit.m_srcX + blit.m_width;
box.bottom = blit.m_srcY + blit.m_height;
box.back = 1;
const uint32_t srcZ = TextureD3D12::TextureCube == src.m_type

View File

@ -3671,15 +3671,8 @@ namespace bgfx { namespace d3d9
const TextureD3D9& src = m_textures[blit.m_src.idx];
const TextureD3D9& dst = m_textures[blit.m_dst.idx];
uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX;
uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY;
uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX;
uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY;
uint32_t width = bx::uint32_min(srcWidth, dstWidth);
uint32_t height = bx::uint32_min(srcHeight, dstHeight);
RECT srcRect = { LONG(blit.m_srcX), LONG(blit.m_srcY), LONG(blit.m_srcX + width), LONG(blit.m_srcY + height) };
RECT dstRect = { LONG(blit.m_dstX), LONG(blit.m_dstY), LONG(blit.m_dstX + width), LONG(blit.m_dstY + height) };
RECT srcRect = { LONG(blit.m_srcX), LONG(blit.m_srcY), LONG(blit.m_srcX + blit.m_width), LONG(blit.m_srcY + blit.m_height) };
RECT dstRect = { LONG(blit.m_dstX), LONG(blit.m_dstY), LONG(blit.m_dstX + blit.m_width), LONG(blit.m_dstY + blit.m_height) };
IDirect3DSurface9* srcSurface = src.getSurface(uint8_t(blit.m_srcZ), blit.m_srcMip);
IDirect3DSurface9* dstSurface = dst.getSurface(uint8_t(blit.m_dstZ), blit.m_dstMip);

View File

@ -6943,16 +6943,6 @@ namespace bgfx { namespace gl
const TextureGL& src = m_textures[bi.m_src.idx];
const TextureGL& dst = m_textures[bi.m_dst.idx];
uint32_t srcWidth = bx::uint32_min(src.m_width, bi.m_srcX + bi.m_width) - bi.m_srcX;
uint32_t srcHeight = bx::uint32_min(src.m_height, bi.m_srcY + bi.m_height) - bi.m_srcY;
uint32_t srcDepth = bx::uint32_min(src.m_depth, bi.m_srcZ + bi.m_depth) - bi.m_srcZ;
uint32_t dstWidth = bx::uint32_min(dst.m_width, bi.m_dstX + bi.m_width) - bi.m_dstX;
uint32_t dstHeight = bx::uint32_min(dst.m_height, bi.m_dstY + bi.m_height) - bi.m_dstY;
uint32_t dstDepth = bx::uint32_min(dst.m_depth, bi.m_dstZ + bi.m_depth) - bi.m_dstZ;
uint32_t width = bx::uint32_min(srcWidth, dstWidth);
uint32_t height = bx::uint32_min(srcHeight, dstHeight);
uint32_t depth = bx::uint32_min(srcDepth, dstDepth);
GL_CHECK(glCopyImageSubData(src.m_id
, src.m_target
, bi.m_srcMip
@ -6965,9 +6955,9 @@ namespace bgfx { namespace gl
, bi.m_dstX
, bi.m_dstY
, bi.m_dstZ
, width
, height
, bx::uint32_imax(depth, 1)
, bi.m_width
, bi.m_height
, bx::uint32_imax(bi.m_depth, 1)
) );
}
}
@ -6980,13 +6970,6 @@ namespace bgfx { namespace gl
const TextureGL& src = m_textures[bi.m_src.idx];
const TextureGL& dst = m_textures[bi.m_dst.idx];
uint32_t srcWidth = bx::uint32_min(src.m_width, bi.m_srcX + bi.m_width) - bi.m_srcX;
uint32_t srcHeight = bx::uint32_min(src.m_height, bi.m_srcY + bi.m_height) - bi.m_srcY;
uint32_t dstWidth = bx::uint32_min(dst.m_width, bi.m_dstX + bi.m_width) - bi.m_dstX;
uint32_t dstHeight = bx::uint32_min(dst.m_height, bi.m_dstY + bi.m_height) - bi.m_dstY;
uint32_t width = bx::uint32_min(srcWidth, dstWidth);
uint32_t height = bx::uint32_min(srcHeight, dstHeight);
BX_ASSERT(0 == bi.m_srcZ && 0 == bi.m_dstZ && 0 == bi.m_depth
, "Blitting 3D regions is not supported"
);
@ -7016,8 +6999,8 @@ namespace bgfx { namespace gl
, bi.m_dstY
, bi.m_srcX
, bi.m_srcY
, width
, height
, bi.m_width
, bi.m_height
) );
GL_CHECK(glDeleteFramebuffers(1, &fbo) );

View File

@ -3621,15 +3621,6 @@ namespace bgfx { namespace mtl
const TextureMtl& src = m_textures[blit.m_src.idx];
const TextureMtl& dst = m_textures[blit.m_dst.idx];
uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX;
uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY;
uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ;
uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX;
uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY;
uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ;
uint32_t width = bx::uint32_min(srcWidth, dstWidth);
uint32_t height = bx::uint32_min(srcHeight, dstHeight);
uint32_t depth = bx::uint32_min(srcDepth, dstDepth);
#if BX_PLATFORM_OSX
bool readBack = !!(dst.m_flags & BGFX_TEXTURE_READ_BACK);
#endif // BX_PLATFORM_OSX
@ -3641,7 +3632,7 @@ namespace bgfx { namespace mtl
, 0
, 0
, MTLOriginMake(blit.m_srcX, blit.m_srcY, blit.m_srcZ)
, MTLSizeMake(width, height, bx::uint32_imax(depth, 1) )
, MTLSizeMake(blit.m_width, blit.m_height, bx::uint32_imax(blit.m_depth, 1) )
, dst.m_ptr
, 0
, 0
@ -3662,7 +3653,7 @@ namespace bgfx { namespace mtl
, blit.m_srcZ
, blit.m_srcMip
, MTLOriginMake(blit.m_srcX, blit.m_srcY, 0)
, MTLSizeMake(width, height, 1)
, MTLSizeMake(blit.m_width, blit.m_height, 1)
, dst.m_ptr
, blit.m_dstZ
, blit.m_dstMip

View File

@ -6355,9 +6355,9 @@ VK_DESTROY
blitInfo.srcOffsets[0].x = blit.m_srcX;
blitInfo.srcOffsets[0].y = blit.m_srcY;
blitInfo.srcOffsets[0].z = srcZ;
blitInfo.srcOffsets[1].x = bx::min<int32_t>(blit.m_srcX + blit.m_width, src.m_width);
blitInfo.srcOffsets[1].y = bx::min<int32_t>(blit.m_srcY + blit.m_height, src.m_height);
blitInfo.srcOffsets[1].z = bx::max<int32_t>(bx::min(srcZ + depth, src.m_depth), 1);
blitInfo.srcOffsets[1].x = blit.m_srcX + blit.m_width;
blitInfo.srcOffsets[1].y = blit.m_srcY + blit.m_height;
blitInfo.srcOffsets[1].z = bx::max<int32_t>(srcZ + depth, 1);
blitInfo.dstSubresource.aspectMask = dst.m_aspectMask;
blitInfo.dstSubresource.mipLevel = blit.m_dstMip;
blitInfo.dstSubresource.baseArrayLayer = dstLayer;
@ -6365,9 +6365,9 @@ VK_DESTROY
blitInfo.dstOffsets[0].x = blit.m_dstX;
blitInfo.dstOffsets[0].y = blit.m_dstY;
blitInfo.dstOffsets[0].z = dstZ;
blitInfo.dstOffsets[1].x = bx::min<int32_t>(blit.m_dstX + blit.m_width, dst.m_width);
blitInfo.dstOffsets[1].y = bx::min<int32_t>(blit.m_dstY + blit.m_height, dst.m_height);
blitInfo.dstOffsets[1].z = bx::max<int32_t>(bx::min(dstZ + depth, dst.m_depth), 1);
blitInfo.dstOffsets[1].x = blit.m_dstX + blit.m_width;
blitInfo.dstOffsets[1].y = blit.m_dstY + blit.m_height;
blitInfo.dstOffsets[1].z = bx::max<int32_t>(dstZ + depth, 1);
VkFilter filter = bimg::isDepth(bimg::TextureFormat::Enum(src.m_textureFormat) ) ? VK_FILTER_NEAREST : VK_FILTER_LINEAR;
vkCmdBlitImage(
commandBuffer

View File

@ -3955,16 +3955,7 @@ namespace bgfx { namespace webgpu
const TextureWgpu& src = m_textures[blit.m_src.idx];
const TextureWgpu& dst = m_textures[blit.m_dst.idx];
uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX;
uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY;
uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ;
uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX;
uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY;
uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ;
uint32_t width = bx::uint32_min(srcWidth, dstWidth);
uint32_t height = bx::uint32_min(srcHeight, dstHeight);
uint32_t depth = bx::uint32_min(srcDepth, dstDepth);
bool readBack = !!(dst.m_flags & BGFX_TEXTURE_READ_BACK);
bool readBack = !!(dst.m_flags & BGFX_TEXTURE_READ_BACK);
wgpu::TextureCopyView srcView;
srcView.texture = src.m_ptr;
@ -3978,14 +3969,14 @@ namespace bgfx { namespace webgpu
dstView.mipLevel = blit.m_dstMip;
dstView.arrayLayer = blit.m_dstZ;
if (depth == 0)
if (blit.m_depth == 0)
{
wgpu::Extent3D copyExtent = { width, height, 1 };
wgpu::Extent3D copyExtent = { blit.m_width, blit.m_height, 1 };
bce.CopyTextureToTexture(&srcView, &dstView, &copyExtent);
}
else
{
wgpu::Extent3D copyExtent = { width, height, depth };
wgpu::Extent3D copyExtent = { blit.m_width, blit.m_height, blit.m_depth };
bce.CopyTextureToTexture(&srcView, &dstView, &copyExtent);
}