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/vulkan/render-vk.cpp | 57 +++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 9 deletions(-) (limited to 'tools/gfx/vulkan/render-vk.cpp') 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; -- cgit v1.2.3