Fixed auto-gen mips on resolved MSAA render targets. (#3845)

This commit is contained in:
Branimir Karadžić
2026-07-24 22:44:05 +00:00
committed by GitHub
parent c1da9d62b0
commit 8e50cd586c
5 changed files with 152 additions and 29 deletions
+6 -1
View File
@@ -4849,7 +4849,12 @@ namespace bgfx { namespace d3d11
desc.MipLevels = 1;
DX_CHECK(s_renderD3D11->m_device->CreateTexture2D(&desc, NULL, &m_rt2d) );
desc.BindFlags &= ~(D3D11_BIND_RENDER_TARGET|D3D11_BIND_DEPTH_STENCIL);
const bool autoGenMips = 0 != (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS);
desc.BindFlags &= ~D3D11_BIND_DEPTH_STENCIL;
if (!autoGenMips)
{
desc.BindFlags &= ~D3D11_BIND_RENDER_TARGET;
}
desc.SampleDesc = s_msaa[0];
desc.MipLevels = savedMipLevels;
}
+3 -3
View File
@@ -352,9 +352,9 @@ namespace bgfx { namespace d3d11
void set();
HRESULT present(uint32_t _syncInterval, uint32_t _flags);
ID3D11RenderTargetView* m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
ID3D11UnorderedAccessView* m_uav[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
ID3D11RenderTargetView* m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
ID3D11UnorderedAccessView* m_uav[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
ID3D11DepthStencilView* m_dsv;
Dxgi::SwapChainI* m_swapChain;
void* m_nwh;
+59 -22
View File
@@ -2749,10 +2749,10 @@ namespace bgfx { namespace d3d12
DX_RELEASE(m_backBufferColor[ii], 1);
#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
}
DX_RELEASE(m_backBufferDepthStencil, 0);
}
DX_RELEASE(m_backBufferDepthStencil, 0);
for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
{
m_frameBuffers[ii].preReset();
@@ -4461,7 +4461,12 @@ namespace bgfx { namespace d3d12
return;
}
device->CreateUnorderedAccessView(_texture.m_ptr
ID3D12Resource* resource = NULL != _texture.m_singleMsaa
? _texture.m_singleMsaa
: _texture.m_ptr
;
device->CreateUnorderedAccessView(resource
, NULL
, &uavd
, cpuHandle
@@ -6753,11 +6758,28 @@ namespace bgfx { namespace d3d12
if (autoGenMips
&& renderTarget
&& 1 < m_numMips
&& NULL == m_singleMsaa
)
&& 1 < m_numMips)
{
s_renderD3D12->generateMips(_commandList, *this);
if (NULL != m_singleMsaa)
{
setResourceBarrier(_commandList
, m_singleMsaa
, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
, D3D12_RESOURCE_STATE_UNORDERED_ACCESS
);
s_renderD3D12->generateMips(_commandList, *this);
setResourceBarrier(_commandList
, m_singleMsaa
, D3D12_RESOURCE_STATE_UNORDERED_ACCESS
, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
);
}
else
{
s_renderD3D12->generateMips(_commandList, *this);
}
}
}
@@ -6805,8 +6827,11 @@ namespace bgfx { namespace d3d12
uint16_t samplerStateIdx = getSamplerState(samplerFlags, BGFX_MAX_COMPUTE_BINDINGS, NULL);
_commandList->SetComputeRootDescriptorTable(ComputeRp::Sampler, m_samplerAllocator.get(samplerStateIdx) );
D3D12_RESOURCE_STATES prevState = _texture.setState(_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
BX_UNUSED(prevState);
if (NULL == _texture.m_singleMsaa)
{
D3D12_RESOURCE_STATES prevState = _texture.setState(_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
BX_UNUSED(prevState);
}
const uint32_t numSlices = (TextureD3D12::TextureCube == _texture.m_type ? 6 : 1)
* bx::max<uint32_t>(_texture.m_numLayers, 1)
@@ -6902,7 +6927,7 @@ namespace bgfx { namespace d3d12
D3D12_RESOURCE_BARRIER barrier = {};
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
barrier.UAV.pResource = _texture.m_ptr;
barrier.UAV.pResource = NULL != _texture.m_singleMsaa ? _texture.m_singleMsaa : _texture.m_ptr;
_commandList->ResourceBarrier(1, &barrier);
topMip += numMips;
@@ -7548,7 +7573,18 @@ namespace bgfx { namespace d3d12
{
if (D3D12_RESOURCE_STATES(UINT32_MAX) != state)
{
m_textures[currentSrc.idx].setState(m_commandList, state);
TextureD3D12& prev = m_textures[currentSrc.idx];
if (NULL != prev.m_singleMsaa)
{
setResourceBarrier(m_commandList
, prev.m_singleMsaa
, D3D12_RESOURCE_STATE_COPY_SOURCE
, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
);
}
prev.setState(m_commandList, state);
}
currentSrc = blit.m_src.to<TextureHandle>();
@@ -7633,22 +7669,23 @@ namespace bgfx { namespace d3d12
, depthStencil ? NULL : &box
);
}
if (NULL != src.m_singleMsaa)
{
setResourceBarrier(
m_commandList
, src.m_singleMsaa
, D3D12_RESOURCE_STATE_COPY_SOURCE
, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
);
}
}
if (isValid(currentSrc)
&& D3D12_RESOURCE_STATES(UINT32_MAX) != state)
{
m_textures[currentSrc.idx].setState(m_commandList, state);
TextureD3D12& src = m_textures[currentSrc.idx];
if (NULL != src.m_singleMsaa)
{
setResourceBarrier(m_commandList
, src.m_singleMsaa
, D3D12_RESOURCE_STATE_COPY_SOURCE
, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
);
}
src.setState(m_commandList, state);
}
}
+2 -2
View File
@@ -565,9 +565,9 @@ namespace bgfx { namespace mtl
uint32_t m_height;
uint16_t m_denseIdx;
TextureHandle m_colorHandle[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
TextureHandle m_colorHandle[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
TextureHandle m_depthHandle;
Attachment m_colorAttachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
Attachment m_colorAttachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
Attachment m_depthAttachment;
uint8_t m_num; // number of color handles
};
+82 -1
View File
@@ -6556,7 +6556,6 @@ VK_DESTROY
if (m_sampler.Count > 1)
{
BX_ASSERT(VK_IMAGE_VIEW_TYPE_3D != m_type, "Can't create multisample 3D image.");
BX_ASSERT(m_numMips <= 1, "Can't create multisample image with mip chain.");
}
VkImageCreateInfo ici;
@@ -6614,6 +6613,10 @@ VK_DESTROY
: ici.mipLevels
;
BX_ASSERT(1 == m_sampler.Count || ici.mipLevels <= 1
, "Can't create multisample image with mip chain."
);
if (0 != _external)
{
static_assert(sizeof(m_textureImage) == sizeof(_external), "Size must match!");
@@ -7245,6 +7248,84 @@ VK_DESTROY
, 1
, &resolve
);
const bool autoGenMips = true
&& 0 != (_resolve & BGFX_RESOLVE_AUTO_GEN_MIPS)
&& 0 == (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY)
&& (_mip + 1) < m_numMips
;
if (autoGenMips)
{
BGFX_PROFILER_SCOPE("Resolve - Generate Mipmaps (MSAA)", kColorResource);
int32_t mipWidth = bx::max<int32_t>(int32_t(m_width) >> _mip, 1);
int32_t mipHeight = bx::max<int32_t>(int32_t(m_height) >> _mip, 1);
const VkFilter filter = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) )
? VK_FILTER_NEAREST
: VK_FILTER_LINEAR
;
VkImageBlit blit;
blit.srcOffsets[0] = { 0, 0, 0 };
blit.srcSubresource.aspectMask = m_aspectFlags;
blit.srcSubresource.baseArrayLayer = _layer;
blit.srcSubresource.layerCount = numLayers;
blit.dstOffsets[0] = { 0, 0, 0 };
blit.dstSubresource.aspectMask = m_aspectFlags;
blit.dstSubresource.baseArrayLayer = _layer;
blit.dstSubresource.layerCount = numLayers;
for (uint32_t i = _mip + 1; i < m_numMips; i++)
{
BGFX_PROFILER_SCOPE("Mipmap", kColorResource);
blit.srcOffsets[1] = { mipWidth, mipHeight, 1 };
blit.srcSubresource.mipLevel = i - 1;
mipWidth = bx::max(mipWidth >> 1, 1);
mipHeight = bx::max(mipHeight >> 1, 1);
blit.dstOffsets[1] = { mipWidth, mipHeight, 1 };
blit.dstSubresource.mipLevel = i;
setImageMemoryBarrier(
_commandBuffer
, m_singleMsaaImage
, m_aspectFlags
, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
, blit.srcSubresource.mipLevel
, 1
, _layer
, numLayers
);
vkCmdBlitImage(
_commandBuffer
, m_singleMsaaImage
, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
, m_singleMsaaImage
, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
, 1
, &blit
, filter
);
}
setImageMemoryBarrier(
_commandBuffer
, m_singleMsaaImage
, m_aspectFlags
, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
, _mip
, m_numMips - _mip - 1
, _layer
, numLayers
);
}
}
if (needMipGen)