diff --git a/src/rhi/qrhid3d11.cpp b/src/rhi/qrhid3d11.cpp index 821bd0230e41b55f96b996e1ca33955624fcc144..839fbbb2a70e35580fee26626c590785e987105c 100644 --- a/src/rhi/qrhid3d11.cpp +++ b/src/rhi/qrhid3d11.cpp @@ -654,6 +654,10 @@ bool QRhiD3D11::readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &r QD3D11Texture *texD = QRHI_RES(QD3D11Texture, rb.texture); QD3D11SwapChain *swapChainD = nullptr; if (texD) { + if (texD->sampleDesc.Count > 1) { + qWarning("Multisample texture cannot be read back"); + return false; + } src = texD->tex; dxgiFormat = toD3DTextureFormat(texD->m_format, texD->m_flags); pixelSize = texD->m_pixelSize; @@ -1314,7 +1318,8 @@ bool QD3D11RenderBuffer::build() D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; memset(&dsvDesc, 0, sizeof(dsvDesc)); dsvDesc.Format = dsFormat; - dsvDesc.ViewDimension = desc.SampleDesc.Count > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; + dsvDesc.ViewDimension = desc.SampleDesc.Count > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS + : D3D11_DSV_DIMENSION_TEXTURE2D; hr = rhiD->dev->CreateDepthStencilView(tex, &dsvDesc, &dsv); if (FAILED(hr)) { qWarning("Failed to create dsv: %s", qPrintable(comErrorMessage(hr))); @@ -1382,12 +1387,24 @@ bool QD3D11Texture::build() if (tex) release(); + QRHI_RES_RHI(QRhiD3D11); const QSize size = safeSize(m_pixelSize); const bool isDepth = isDepthTextureFormat(m_format); const bool isCube = m_flags.testFlag(CubeMap); const bool hasMipMaps = m_flags.testFlag(MipMapped); mipLevelCount = hasMipMaps ? qCeil(log2(qMax(size.width(), size.height()))) + 1 : 1; + sampleDesc = rhiD->effectiveSampleCount(m_sampleCount); + if (sampleDesc.Count > 1) { + if (isCube) { + qWarning("Cubemap texture cannot be multisample"); + return false; + } + if (hasMipMaps) { + qWarning("Multisample texture cannot have mipmaps"); + return false; + } + } uint bindFlags = D3D11_BIND_SHADER_RESOURCE; if (m_flags.testFlag(RenderTarget)) { @@ -1404,12 +1421,11 @@ bool QD3D11Texture::build() desc.MipLevels = mipLevelCount; desc.ArraySize = isCube ? 6 : 1;; desc.Format = toD3DTextureFormat(m_format, m_flags); - desc.SampleDesc.Count = 1; + desc.SampleDesc = sampleDesc; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = bindFlags; desc.MiscFlags = isCube ? D3D11_RESOURCE_MISC_TEXTURECUBE : 0; - QRHI_RES_RHI(QRhiD3D11); HRESULT hr = rhiD->dev->CreateTexture2D(&desc, nullptr, &tex); if (FAILED(hr)) { qWarning("Failed to create texture: %s", qPrintable(comErrorMessage(hr))); @@ -1423,8 +1439,12 @@ bool QD3D11Texture::build() srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; srvDesc.TextureCube.MipLevels = desc.MipLevels; } else { - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = desc.MipLevels; + if (sampleDesc.Count > 1) { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + } else { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = desc.MipLevels; + } } hr = rhiD->dev->CreateShaderResourceView(tex, &srvDesc, &srv); @@ -1617,7 +1637,8 @@ bool QD3D11TextureRenderTarget::build() rtvDesc.Texture2DArray.FirstArraySlice = m_desc.colorAttachments[i].layer; rtvDesc.Texture2DArray.ArraySize = 1; } else { - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.ViewDimension = texD->sampleDesc.Count > 1 ? D3D11_RTV_DIMENSION_TEXTURE2DMS + : D3D11_RTV_DIMENSION_TEXTURE2D; } HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[i]); @@ -1633,17 +1654,19 @@ bool QD3D11TextureRenderTarget::build() if (hasDepthStencil) { if (m_desc.depthTexture) { ownsDsv = true; + QD3D11Texture *depthTexD = QRHI_RES(QD3D11Texture, m_desc.depthTexture); D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; memset(&dsvDesc, 0, sizeof(dsvDesc)); - dsvDesc.Format = toD3DDepthTextureDSVFormat(m_desc.depthTexture->format()); - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - HRESULT hr = rhiD->dev->CreateDepthStencilView(QRHI_RES(QD3D11Texture, m_desc.depthTexture)->tex, &dsvDesc, &dsv); + dsvDesc.Format = toD3DDepthTextureDSVFormat(depthTexD->format()); + dsvDesc.ViewDimension = depthTexD->sampleDesc.Count > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS + : D3D11_DSV_DIMENSION_TEXTURE2D; + HRESULT hr = rhiD->dev->CreateDepthStencilView(depthTexD->tex, &dsvDesc, &dsv); if (FAILED(hr)) { qWarning("Failed to create dsv: %s", qPrintable(comErrorMessage(hr))); return false; } if (d.colorAttCount == 0) - d.pixelSize = m_desc.depthTexture->pixelSize(); + d.pixelSize = depthTexD->pixelSize(); } else { ownsDsv = false; dsv = QRHI_RES(QD3D11RenderBuffer, m_desc.depthStencilBuffer)->dsv; diff --git a/src/rhi/qrhid3d11_p.h b/src/rhi/qrhid3d11_p.h index adfc0e1e1eda3469d306c208b22972b260688053..5bc44adc320f825935f3ff0ae9e50213454ffd1e 100644 --- a/src/rhi/qrhid3d11_p.h +++ b/src/rhi/qrhid3d11_p.h @@ -86,6 +86,7 @@ struct QD3D11Texture : public QRhiTexture ID3D11Texture2D *tex = nullptr; ID3D11ShaderResourceView *srv = nullptr; uint mipLevelCount = 0; + DXGI_SAMPLE_DESC sampleDesc; uint generation = 0; friend class QRhiD3D11; }; diff --git a/todo.txt b/todo.txt index bfd4bceb301baaf4a2e662e3ea1cc82038dea298..c1c688618d5c085c6cfb47e96a747f999b586cc8 100644 --- a/todo.txt +++ b/todo.txt @@ -12,8 +12,8 @@ test cubemap test cubemap face as target face cubemap readback? (test vk/d3d, impl for gl/mtl) -msaa offscreen (msaa texture. no readback.) -resolveimage (color and ds, only to resolve samples) +mtl, gl, vk: msaa tex+rt +mtl, gl, vk: resolveimage gl: tex size stuff (npot etc.) gl: tex formats (texture, readback) @@ -31,7 +31,7 @@ vk: rendering hangs sometimes when minimize and back on some systems? mtl: cbuffers, textures, samplers set should be batched too cbuffer alignment rules - some things fail to translate (to hlsl e.g. with structs), which is fine but how to mitigate what does image copy do for compressed formats? -does reading back an msaa swapchain buffer work? +does/should reading back an msaa swapchain buffer work? (breaks with vk, d3d at least) figure sg out for minimizing viewport/scissor cmds vk: test FrameOpDeviceLost somehow d3d device loss? @@ -65,6 +65,9 @@ dxc for d3d as an alternative to fxc? hlsl -> dxc -> spirv -> spirv-cross hmmm... +++ done +d3d: resolveimage (color and ds, only to resolve samples) +d3d: msaa tex+rt +multisample texture (and tex rt) (no readback) gl: compressed textures vk, gl: texcopy move cb api into QRhiCommandBuffer