mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-10-30 04:35:35 +00:00
Fix MSAA blit into a multisampled destination and stale MSAA resolve. (#3921)
This commit is contained in:
+12
-3
@@ -5442,7 +5442,7 @@ namespace bgfx { namespace d3d11
|
||||
for (uint32_t ii = _layer, end = _layer + _numLayers; ii < end; ++ii)
|
||||
{
|
||||
const UINT resource = _mip + (ii * m_numMips);
|
||||
deviceCtx->ResolveSubresource(m_texture2d, resource, m_rt, resource, resolveFormat);
|
||||
deviceCtx->ResolveSubresource(m_texture2d, resource, m_rt, ii, resolveFormat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6122,6 +6122,15 @@ namespace bgfx { namespace d3d11
|
||||
const TextureD3D11& src = m_textures[blit.m_src.idx];
|
||||
const TextureD3D11& dst = m_textures[blit.m_dst.idx];
|
||||
|
||||
const bool srcReadsMsaaRt = NULL != src.m_rt && dst.isMsaaSurface();
|
||||
|
||||
if (NULL != src.m_rt
|
||||
&& !srcReadsMsaaRt
|
||||
&& 0 == blit.m_srcMip)
|
||||
{
|
||||
src.resolve(BGFX_RESOLVE_NONE, blit.m_srcZ, 1, 0);
|
||||
}
|
||||
|
||||
if ( src.isMsaaSurface()
|
||||
&& !dst.isMsaaSurface()
|
||||
&& TextureD3D11::Texture3D != src.m_type)
|
||||
@@ -6229,7 +6238,7 @@ namespace bgfx { namespace d3d11
|
||||
, "When blitting depthstencil surface, source resolution must match destination."
|
||||
);
|
||||
|
||||
const bool msaaToMsaa = src.isMsaaSurface() && dst.isMsaaSurface();
|
||||
const bool msaaToMsaa = (src.isMsaaSurface() || srcReadsMsaaRt) && dst.isMsaaSurface();
|
||||
const bool wholeSubResource = depthStencil || msaaToMsaa;
|
||||
|
||||
const D3D11_BOX box =
|
||||
@@ -6251,7 +6260,7 @@ namespace bgfx { namespace d3d11
|
||||
, wholeSubResource ? 0 : blit.m_dstX
|
||||
, wholeSubResource ? 0 : blit.m_dstY
|
||||
, 0
|
||||
, src.m_ptr
|
||||
, srcReadsMsaaRt ? src.m_rt : src.m_ptr
|
||||
, srcZ*src.m_numMips+blit.m_srcMip
|
||||
, wholeSubResource ? NULL : &box
|
||||
);
|
||||
|
||||
+30
-7
@@ -7062,6 +7062,14 @@ namespace bgfx { namespace d3d12
|
||||
, D3D12_RESOURCE_STATE_RESOLVE_DEST
|
||||
);
|
||||
|
||||
const TextureFormatInfo& tfi = s_textureFormat[m_textureFormat];
|
||||
const bool useSrgb = true
|
||||
&& 0 != (m_flags & BGFX_TEXTURE_SRGB)
|
||||
&& !bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) )
|
||||
&& DXGI_FORMAT_UNKNOWN != tfi.m_fmtSrgb
|
||||
;
|
||||
const DXGI_FORMAT resolveFormat = useSrgb ? tfi.m_fmtSrgb : tfi.m_fmt;
|
||||
|
||||
for (uint32_t ii = _layer, end = _layer + _numLayers; ii < end; ++ii)
|
||||
{
|
||||
const uint32_t resource = _mip + (ii * m_numMips);
|
||||
@@ -7070,7 +7078,7 @@ namespace bgfx { namespace d3d12
|
||||
, resource
|
||||
, m_ptr
|
||||
, resource
|
||||
, s_textureFormat[m_textureFormat].m_fmt
|
||||
, resolveFormat
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7122,6 +7130,12 @@ namespace bgfx { namespace d3d12
|
||||
;
|
||||
}
|
||||
|
||||
bool TextureD3D12::isMultisampled() const
|
||||
{
|
||||
const uint32_t msaaQuality = bx::satSub<uint32_t>(uint32_t( (m_flags&BGFX_TEXTURE_RT_MSAA_MASK) >> BGFX_TEXTURE_RT_MSAA_SHIFT), 1u);
|
||||
return 1 < s_msaa[msaaQuality].Count;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_STATES TextureD3D12::setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state)
|
||||
{
|
||||
if (m_state != _state)
|
||||
@@ -7753,10 +7767,10 @@ namespace bgfx { namespace d3d12
|
||||
{
|
||||
ID3D12GraphicsCommandList* commandList = s_renderD3D12->m_commandList;
|
||||
|
||||
Query& query = m_query[_idx];
|
||||
Query& query = m_query[_idx];
|
||||
query.m_ready = true;
|
||||
query.m_fence = s_renderD3D12->m_cmd.m_currentFence - 1;
|
||||
uint32_t offset = _idx * 2;
|
||||
query.m_fence = s_renderD3D12->m_cmd.m_currentFence;
|
||||
const uint32_t offset = _idx * 2;
|
||||
|
||||
commandList->EndQuery(m_queryHeap
|
||||
, D3D12_QUERY_TYPE_TIMESTAMP
|
||||
@@ -7873,7 +7887,7 @@ namespace bgfx { namespace d3d12
|
||||
, m_readback
|
||||
, handle.idx * sizeof(uint64_t)
|
||||
);
|
||||
m_fence[idx] = s_renderD3D12->m_cmd.m_currentFence - 1;
|
||||
m_fence[idx] = s_renderD3D12->m_cmd.m_currentFence;
|
||||
m_control.commit(1);
|
||||
}
|
||||
|
||||
@@ -7956,6 +7970,13 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
if (currentSrc.idx != blit.m_src.idx)
|
||||
{
|
||||
if (NULL != src.m_singleMsaa
|
||||
&& !dst.isMultisampled()
|
||||
&& 0 == blit.m_srcMip)
|
||||
{
|
||||
src.resolve(m_commandList, BGFX_RESOLVE_NONE, blit.m_srcZ, 1, 0);
|
||||
}
|
||||
|
||||
if (D3D12_RESOURCE_STATES(UINT32_MAX) != srcState)
|
||||
{
|
||||
TextureD3D12& prev = m_textures[currentSrc.idx];
|
||||
@@ -8094,7 +8115,7 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
const D3D12_TEXTURE_COPY_LOCATION srcLocation =
|
||||
{
|
||||
.pResource = NULL != src.m_singleMsaa ? src.m_singleMsaa : src.m_ptr,
|
||||
.pResource = NULL != src.m_singleMsaa && !dst.isMultisampled() ? src.m_singleMsaa : src.m_ptr,
|
||||
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||
.SubresourceIndex = srcZ*src.m_numMips+blit.m_srcMip,
|
||||
};
|
||||
@@ -8238,7 +8259,7 @@ namespace bgfx { namespace d3d12
|
||||
UniformCacheState ucs(_render);
|
||||
BlitState bs(_render);
|
||||
|
||||
uint32_t blendFactor = 0;
|
||||
uint32_t blendFactor = UINT32_MAX;
|
||||
|
||||
const uint64_t primType = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;
|
||||
uint8_t primIndex = uint8_t(primType >> BGFX_STATE_PT_SHIFT);
|
||||
@@ -8442,6 +8463,7 @@ namespace bgfx { namespace d3d12
|
||||
if (commandListChanged)
|
||||
{
|
||||
commandListChanged = false;
|
||||
blendFactor = UINT32_MAX;
|
||||
|
||||
m_commandList->SetComputeRootSignature(m_computeRootSignature);
|
||||
ID3D12DescriptorHeap* heaps[] = {
|
||||
@@ -8762,6 +8784,7 @@ namespace bgfx { namespace d3d12
|
||||
{
|
||||
wasCompute = false;
|
||||
commandListChanged = false;
|
||||
blendFactor = UINT32_MAX;
|
||||
|
||||
m_commandList->SetGraphicsRootSignature(m_rootSignature);
|
||||
ID3D12DescriptorHeap* heaps[] = {
|
||||
|
||||
@@ -457,6 +457,7 @@ namespace bgfx { namespace d3d12
|
||||
void resolve(ID3D12GraphicsCommandList* _commandList, uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip);
|
||||
D3D12_RESOURCE_STATES setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);
|
||||
bool isMsaaSurface() const;
|
||||
bool isMultisampled() const;
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC m_srvd;
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC m_uavd;
|
||||
|
||||
+62
-4
@@ -7605,6 +7605,51 @@ namespace bgfx { namespace gl
|
||||
return true;
|
||||
}
|
||||
|
||||
static void resolveMsaaRbo(const TextureGL& _src, GLuint _currentFbo)
|
||||
{
|
||||
if (0 == _src.m_rbo
|
||||
|| NULL == glBlitFramebuffer
|
||||
|| bimg::isDepth(bimg::TextureFormat::Enum(_src.m_textureFormat) ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GLuint fbo[2];
|
||||
GL_CHECK(glGenFramebuffers(BX_COUNTOF(fbo), fbo) );
|
||||
|
||||
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[0]) );
|
||||
GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER
|
||||
, GL_COLOR_ATTACHMENT0
|
||||
, GL_RENDERBUFFER
|
||||
, _src.m_rbo
|
||||
) );
|
||||
|
||||
GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]) );
|
||||
GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER
|
||||
, GL_COLOR_ATTACHMENT0
|
||||
, _src.m_target
|
||||
, _src.m_id
|
||||
, 0
|
||||
) );
|
||||
|
||||
GL_CHECK(glDisable(GL_SCISSOR_TEST) );
|
||||
GL_CHECK(glBlitFramebuffer(
|
||||
0
|
||||
, 0
|
||||
, _src.m_width
|
||||
, _src.m_height
|
||||
, 0
|
||||
, 0
|
||||
, _src.m_width
|
||||
, _src.m_height
|
||||
, GL_COLOR_BUFFER_BIT
|
||||
, GL_NEAREST
|
||||
) );
|
||||
|
||||
GL_CHECK(glDeleteFramebuffers(BX_COUNTOF(fbo), fbo) );
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, _currentFbo) );
|
||||
}
|
||||
|
||||
static bool blitCompressed2D(
|
||||
const BlitItem& _bi
|
||||
, const TextureGL& _src
|
||||
@@ -7742,13 +7787,21 @@ namespace bgfx { namespace gl
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool srcReadsMsaaRbo = 0 != src.m_rbo && dst.isMsaaSurface();
|
||||
|
||||
if (!srcReadsMsaaRbo
|
||||
&& 0 == bi.m_srcMip)
|
||||
{
|
||||
resolveMsaaRbo(src, m_currentFbo);
|
||||
}
|
||||
|
||||
GL_CHECK(glCopyImageSubData(
|
||||
src.m_id
|
||||
, src.m_target
|
||||
, bi.m_srcMip
|
||||
srcReadsMsaaRbo ? src.m_rbo : src.m_id
|
||||
, srcReadsMsaaRbo ? GL_RENDERBUFFER : src.m_target
|
||||
, srcReadsMsaaRbo ? 0 : bi.m_srcMip
|
||||
, bi.m_srcX
|
||||
, bi.m_srcY
|
||||
, bi.m_srcZ
|
||||
, srcReadsMsaaRbo ? 0 : bi.m_srcZ
|
||||
, dst.m_id
|
||||
, dst.m_target
|
||||
, bi.m_dstMip
|
||||
@@ -7774,6 +7827,11 @@ namespace bgfx { namespace gl
|
||||
, "Blitting 3D regions is not supported"
|
||||
);
|
||||
|
||||
if (0 == bi.m_srcMip)
|
||||
{
|
||||
resolveMsaaRbo(src, m_currentFbo);
|
||||
}
|
||||
|
||||
GLuint fbo;
|
||||
GL_CHECK(glGenFramebuffers(1, &fbo) );
|
||||
|
||||
|
||||
@@ -1465,6 +1465,14 @@ namespace bgfx { namespace gl
|
||||
;
|
||||
}
|
||||
|
||||
bool isMsaaSurface() const
|
||||
{
|
||||
return 0
|
||||
|| GL_TEXTURE_2D_MULTISAMPLE == m_target
|
||||
|| GL_TEXTURE_2D_MULTISAMPLE_ARRAY == m_target
|
||||
;
|
||||
}
|
||||
|
||||
GLuint m_id;
|
||||
GLuint m_rbo;
|
||||
GLenum m_target;
|
||||
|
||||
+22
-6
@@ -9530,6 +9530,14 @@ VK_DESTROY
|
||||
BX_ASSERT(false, "Removing external texture failed!");
|
||||
}
|
||||
|
||||
static bool blitReadsSingleMsaa(const TextureVK& _src, const TextureVK& _dst)
|
||||
{
|
||||
return true
|
||||
&& VK_NULL_HANDLE != _src.m_singleMsaaImage
|
||||
&& 1 == _dst.m_sampler.Count
|
||||
;
|
||||
}
|
||||
|
||||
void RendererContextVK::submitBlitBatch(BlitState& _bs, uint16_t _view)
|
||||
{
|
||||
constexpr uint32_t kMaxItems = 128;
|
||||
@@ -9550,7 +9558,13 @@ VK_DESTROY
|
||||
TextureVK& src = m_textures[blit.m_src.idx];
|
||||
TextureVK& dst = m_textures[blit.m_dst.idx];
|
||||
|
||||
srcLayouts[item] = VK_NULL_HANDLE != src.m_singleMsaaImage
|
||||
if (blitReadsSingleMsaa(src, dst)
|
||||
&& 0 == blit.m_srcMip)
|
||||
{
|
||||
src.resolve(m_commandBuffer, BGFX_RESOLVE_NONE, blit.m_srcZ, 1, 0);
|
||||
}
|
||||
|
||||
srcLayouts[item] = blitReadsSingleMsaa(src, dst)
|
||||
? src.m_currentSingleMsaaImageLayout
|
||||
: src.m_currentImageLayout
|
||||
;
|
||||
@@ -9566,12 +9580,14 @@ VK_DESTROY
|
||||
TextureVK& src = m_textures[blit.m_src.idx];
|
||||
TextureVK& dst = m_textures[blit.m_dst.idx];
|
||||
|
||||
const bool srcSingleMsaa = blitReadsSingleMsaa(src, dst);
|
||||
|
||||
src.setState(
|
||||
m_commandBuffer
|
||||
, blit.m_src.idx == blit.m_dst.idx
|
||||
? VK_IMAGE_LAYOUT_GENERAL
|
||||
: VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
|
||||
, VK_NULL_HANDLE != src.m_singleMsaaImage
|
||||
, srcSingleMsaa
|
||||
);
|
||||
|
||||
if (blit.m_src.idx != blit.m_dst.idx)
|
||||
@@ -9579,7 +9595,7 @@ VK_DESTROY
|
||||
dst.setState(m_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
}
|
||||
|
||||
const uint16_t srcSamples = VK_NULL_HANDLE != src.m_singleMsaaImage ? 1 : src.m_sampler.Count;
|
||||
const uint16_t srcSamples = srcSingleMsaa ? 1 : src.m_sampler.Count;
|
||||
const uint16_t dstSamples = dst.m_sampler.Count;
|
||||
|
||||
const bool resolve = true
|
||||
@@ -9675,8 +9691,8 @@ VK_DESTROY
|
||||
{
|
||||
vkCmdCopyImage(
|
||||
m_commandBuffer
|
||||
, VK_NULL_HANDLE != src.m_singleMsaaImage ? src.m_singleMsaaImage : src.m_textureImage
|
||||
, VK_NULL_HANDLE != src.m_singleMsaaImage ? src.m_currentSingleMsaaImageLayout : src.m_currentImageLayout
|
||||
, srcSingleMsaa ? src.m_singleMsaaImage : src.m_textureImage
|
||||
, srcSingleMsaa ? src.m_currentSingleMsaaImageLayout : src.m_currentImageLayout
|
||||
, dst.m_textureImage
|
||||
, dst.m_currentImageLayout
|
||||
, 1
|
||||
@@ -9698,7 +9714,7 @@ VK_DESTROY
|
||||
TextureVK& src = m_textures[blit.m_src.idx];
|
||||
TextureVK& dst = m_textures[blit.m_dst.idx];
|
||||
|
||||
src.setState(m_commandBuffer, srcLayouts[item], VK_NULL_HANDLE != src.m_singleMsaaImage);
|
||||
src.setState(m_commandBuffer, srcLayouts[item], blitReadsSingleMsaa(src, dst) );
|
||||
dst.setState(m_commandBuffer, dstLayouts[item]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user