From 6528b1c7f32d8e2c8de8f4e1dd386533cd14b8f1 Mon Sep 17 00:00:00 2001 From: lucy96chen <47800040+lucy96chen@users.noreply.github.com> Date: Tue, 25 Jan 2022 10:26:29 -0800 Subject: Add implementations for resolveResource() to D3D12 and Vulkan backends (#2094) * Added implementations for resolveResource to both D3D and Vulkan backends * Simple test for resolving a multisampled resource written and confirmed to run successfully for D3D12 * Fixed a bug preventing MSAA from working in Vulkan * Changed test format to RGBA32 Float (because swiftshader) --- tools/gfx/cuda/render-cuda.cpp | 4 +++ tools/gfx/d3d12/render-d3d12.cpp | 39 +++++++++++++++++++++--- tools/gfx/debug-layer.cpp | 4 ++- tools/gfx/debug-layer.h | 2 ++ tools/gfx/immediate-renderer-base.cpp | 4 +++ tools/gfx/vulkan/render-vk.cpp | 57 +++++++++++++++++++++++++++++------ tools/gfx/vulkan/vk-api.h | 1 + 7 files changed, 96 insertions(+), 15 deletions(-) (limited to 'tools/gfx') diff --git a/tools/gfx/cuda/render-cuda.cpp b/tools/gfx/cuda/render-cuda.cpp index 3e55242f0..0446dc055 100644 --- a/tools/gfx/cuda/render-cuda.cpp +++ b/tools/gfx/cuda/render-cuda.cpp @@ -1111,13 +1111,17 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL resolveResource( ITextureResource* source, + ResourceState sourceState, SubresourceRange sourceRange, ITextureResource* dest, + ResourceState destState, SubresourceRange destRange) override { SLANG_UNUSED(source); + SLANG_UNUSED(sourceState); SLANG_UNUSED(sourceRange); SLANG_UNUSED(dest); + SLANG_UNUSED(destState); SLANG_UNUSED(destRange); SLANG_UNIMPLEMENTED_X("resolveResource"); } diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp index e0c324d34..1b146bc4e 100644 --- a/tools/gfx/d3d12/render-d3d12.cpp +++ b/tools/gfx/d3d12/render-d3d12.cpp @@ -4314,15 +4314,44 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL resolveResource( ITextureResource* source, + ResourceState sourceState, SubresourceRange sourceRange, ITextureResource* dest, + ResourceState destState, SubresourceRange destRange) override { - SLANG_UNUSED(source); - SLANG_UNUSED(sourceRange); - SLANG_UNUSED(dest); - SLANG_UNUSED(destRange); - SLANG_UNIMPLEMENTED_X("resolveResource"); + auto srcTexture = static_cast(source); + auto srcDesc = srcTexture->getDesc(); + auto dstTexture = static_cast(dest); + auto dstDesc = dstTexture->getDesc(); + + for (uint32_t layer = 0; layer < sourceRange.layerCount; ++layer) + { + for (uint32_t mip = 0; mip < sourceRange.mipLevelCount; ++mip) + { + auto srcSubresourceIndex = D3DUtil::getSubresourceIndex( + mip + sourceRange.mipLevel, + layer + sourceRange.baseArrayLayer, + 0, + srcDesc->numMipLevels, + srcDesc->arraySize); + auto dstSubresourceIndex = D3DUtil::getSubresourceIndex( + mip + destRange.mipLevel, + layer + destRange.baseArrayLayer, + 0, + dstDesc->numMipLevels, + dstDesc->arraySize); + + DXGI_FORMAT format = D3DUtil::getMapFormat(srcDesc->format); + + m_commandBuffer->m_cmdList->ResolveSubresource( + dstTexture->m_resource.getResource(), + dstSubresourceIndex, + srcTexture->m_resource.getResource(), + srcSubresourceIndex, + format); + } + } } virtual SLANG_NO_THROW void SLANG_MCALL copyTextureToBuffer( diff --git a/tools/gfx/debug-layer.cpp b/tools/gfx/debug-layer.cpp index 53deec385..f34a77556 100644 --- a/tools/gfx/debug-layer.cpp +++ b/tools/gfx/debug-layer.cpp @@ -1343,12 +1343,14 @@ void DebugResourceCommandEncoder::clearResourceView( void DebugResourceCommandEncoder::resolveResource( ITextureResource* source, + ResourceState sourceState, SubresourceRange sourceRange, ITextureResource* dest, + ResourceState destState, SubresourceRange destRange) { SLANG_GFX_API_FUNC; - baseObject->resolveResource(getInnerObj(source), sourceRange, getInnerObj(dest), destRange); + baseObject->resolveResource(getInnerObj(source), sourceState, sourceRange, getInnerObj(dest), destState, destRange); } void DebugResourceCommandEncoder::copyTextureToBuffer( diff --git a/tools/gfx/debug-layer.h b/tools/gfx/debug-layer.h index a2de7eb31..94f3e3f14 100644 --- a/tools/gfx/debug-layer.h +++ b/tools/gfx/debug-layer.h @@ -463,8 +463,10 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL resolveResource( ITextureResource* source, + ResourceState sourceState, SubresourceRange sourceRange, ITextureResource* dest, + ResourceState destState, SubresourceRange destRange) override; virtual SLANG_NO_THROW void SLANG_MCALL copyTextureToBuffer( diff --git a/tools/gfx/immediate-renderer-base.cpp b/tools/gfx/immediate-renderer-base.cpp index ab2a51275..91b89c8cf 100644 --- a/tools/gfx/immediate-renderer-base.cpp +++ b/tools/gfx/immediate-renderer-base.cpp @@ -385,13 +385,17 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL resolveResource( ITextureResource* source, + ResourceState sourceState, SubresourceRange sourceRange, ITextureResource* dest, + ResourceState destState, SubresourceRange destRange) override { SLANG_UNUSED(source); + SLANG_UNUSED(sourceState); SLANG_UNUSED(sourceRange); SLANG_UNUSED(dest); + SLANG_UNUSED(destState); SLANG_UNUSED(destRange); SLANG_UNIMPLEMENTED_X("resolveResource"); } diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index f31195cc8..517580c08 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -561,6 +561,7 @@ public: VkAttachmentReference m_depthReference; bool m_hasDepthStencilAttachment; uint32_t m_renderTargetCount; + VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; public: ~FramebufferLayoutImpl() @@ -601,6 +602,8 @@ public: dst.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; dst.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; dst.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + sampleCount = Math::Max(dst.samples, sampleCount); } if (desc.depthStencil) @@ -615,6 +618,8 @@ public: dst.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; dst.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; dst.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + sampleCount = Math::Max(dst.samples, sampleCount); } Array& colorReferences = m_colorReferences; @@ -4780,15 +4785,43 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL resolveResource( ITextureResource* source, + ResourceState sourceState, SubresourceRange sourceRange, ITextureResource* dest, + ResourceState destState, SubresourceRange destRange) override { - SLANG_UNUSED(source); - SLANG_UNUSED(sourceRange); - SLANG_UNUSED(dest); - SLANG_UNUSED(destRange); - SLANG_UNIMPLEMENTED_X("resolveResource"); + auto srcTexture = static_cast(source); + auto srcExtent = srcTexture->getDesc()->size; + auto dstTexture = static_cast(dest); + + auto srcImage = srcTexture->m_image; + auto dstImage = dstTexture->m_image; + + auto srcImageLayout = VulkanUtil::getImageLayoutFromState(sourceState); + auto dstImageLayout = VulkanUtil::getImageLayoutFromState(destState); + + for (uint32_t layer = 0; layer < sourceRange.layerCount; ++layer) + { + for (uint32_t mip = 0; mip < sourceRange.mipLevelCount; ++mip) + { + VkImageResolve region = {}; + region.srcSubresource.aspectMask = getAspectMask(sourceRange.aspectMask); + region.srcSubresource.baseArrayLayer = layer + sourceRange.baseArrayLayer; + region.srcSubresource.layerCount = 1; + region.srcSubresource.mipLevel = mip + sourceRange.mipLevel; + region.srcOffset = { 0, 0, 0 }; + region.dstSubresource.aspectMask = getAspectMask(destRange.aspectMask); + region.dstSubresource.baseArrayLayer = layer + destRange.baseArrayLayer; + region.dstSubresource.layerCount = 1; + region.dstSubresource.mipLevel = mip + destRange.mipLevel; + region.dstOffset = { 0, 0, 0 }; + region.extent = { (uint32_t)srcExtent.width, (uint32_t)srcExtent.height, (uint32_t)srcExtent.depth }; + + auto& vkApi = m_commandBuffer->m_renderer->m_api; + vkApi.vkCmdResolveImage(m_commandBuffer->m_commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, 1, ®ion); + } + } } virtual SLANG_NO_THROW void SLANG_MCALL copyTextureToBuffer( @@ -7092,6 +7125,10 @@ static VkImageUsageFlagBits _calcImageUsageFlags(ResourceState state) return VK_IMAGE_USAGE_TRANSFER_SRC_BIT; case ResourceState::CopyDestination: return VK_IMAGE_USAGE_TRANSFER_DST_BIT; + case ResourceState::ResolveSource: + return VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + case ResourceState::ResolveDestination: + return VK_IMAGE_USAGE_TRANSFER_DST_BIT; default: { assert(!"Unsupported"); @@ -7323,7 +7360,7 @@ Result VKDevice::getTextureAllocationInfo( imageInfo.usage = _calcImageUsageFlags(desc.allowedStates, desc.memoryType, nullptr); imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageInfo.samples = (VkSampleCountFlagBits)desc.sampleDesc.numSamples; VkImage image; SLANG_VK_RETURN_ON_FAIL(m_api.vkCreateImage(m_device, &imageInfo, nullptr, &image)); @@ -7402,7 +7439,7 @@ Result VKDevice::createTextureResource(const ITextureResource::Desc& descIn, con imageInfo.usage = _calcImageUsageFlags(desc.allowedStates, desc.memoryType, initData); imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageInfo.samples = (VkSampleCountFlagBits)desc.sampleDesc.numSamples; VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO }; #if SLANG_WINDOWS_FAMILY @@ -8278,10 +8315,12 @@ Result VKDevice::createGraphicsPipelineState(const GraphicsPipelineStateDesc& in rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; rasterizer.depthBiasEnable = VK_FALSE; + auto framebufferLayoutImpl = static_cast(desc.framebufferLayout); + VkPipelineMultisampleStateCreateInfo multisampling = {}; multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisampling.sampleShadingEnable = VK_FALSE; - multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + multisampling.rasterizationSamples = framebufferLayoutImpl->sampleCount; VkPipelineColorBlendAttachmentState colorBlendAttachment = {}; colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; @@ -8332,7 +8371,7 @@ Result VKDevice::createGraphicsPipelineState(const GraphicsPipelineStateDesc& in pipelineInfo.pColorBlendState = &colorBlending; pipelineInfo.pDepthStencilState = &depthStencilStateInfo; pipelineInfo.layout = programImpl->m_rootObjectLayout->m_pipelineLayout; - pipelineInfo.renderPass = static_cast(desc.framebufferLayout)->m_renderPass; + pipelineInfo.renderPass = framebufferLayoutImpl->m_renderPass; pipelineInfo.subpass = 0; pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; pipelineInfo.pDynamicState = &dynamicStateInfo; diff --git a/tools/gfx/vulkan/vk-api.h b/tools/gfx/vulkan/vk-api.h index 72a6e73c8..7df51668f 100644 --- a/tools/gfx/vulkan/vk-api.h +++ b/tools/gfx/vulkan/vk-api.h @@ -98,6 +98,7 @@ namespace gfx { x(vkCmdCopyBufferToImage)\ x(vkCmdCopyImage) \ x(vkCmdCopyImageToBuffer) \ + x(vkCmdResolveImage) \ x(vkCmdPushConstants) \ x(vkCmdSetStencilReference) \ x(vkCmdWriteTimestamp) \ -- cgit v1.2.3