diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2019-11-10 06:17:46 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2019-11-10 06:17:46 +0000 |
| commit | 9e62ec0d4b9c7ea9d6fc3d19b9d29481dffb697c (patch) | |
| tree | f9f26c569259ec3b83c9b19dbe0c40f472243ce6 /Graphics/GraphicsEngineVulkan | |
| parent | Allowed swap chains without the depth buffer (diff) | |
| download | DiligentCore-9e62ec0d4b9c7ea9d6fc3d19b9d29481dffb697c.tar.gz DiligentCore-9e62ec0d4b9c7ea9d6fc3d19b9d29481dffb697c.zip | |
Added 'ResolveTextureSubresource' device context command (API Version 240041) (not yet implemented in OpenGL backend)
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
7 files changed, 81 insertions, 6 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index 14f9975b..d8b89810 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -246,6 +246,10 @@ public: virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)override final; + virtual void ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs)override final; + VkDescriptorSet AllocateDynamicDescriptorSet(VkDescriptorSetLayout SetLayout, const char* DebugName = "") { // Descriptor pools are externally synchronized, meaning that the application must not allocate diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h index a95dce56..517b7e50 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h @@ -412,6 +412,22 @@ namespace VulkanUtilities vkCmdBlitImage(m_VkCmdBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter); } + __forceinline void ResolveImage(VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageResolve* pRegions) + { + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + if (m_State.RenderPass != VK_NULL_HANDLE) + { + // Resolve must be performed outside of render pass. + EndRenderPass(); + } + vkCmdResolveImage(m_VkCmdBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); + } + void FlushBarriers(); __forceinline void SetVkCmdBuffer(VkCommandBuffer VkCmdBuffer) diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index c4e1e6cd..7231ac5e 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -2249,4 +2249,59 @@ namespace Diligent } } } + + void DeviceContextVkImpl::ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs) + { + TDeviceContextBase::ResolveTextureSubresource(pSrcTexture, pDstTexture, ResolveAttribs); + + auto* pSrcTexVk = ValidatedCast<TextureVkImpl>(pSrcTexture); + auto* pDstTexVk = ValidatedCast<TextureVkImpl>(pDstTexture); + const auto& SrcTexDesc = pSrcTexVk->GetDesc(); + const auto& DstTexDesc = pDstTexVk->GetDesc(); + + DEV_CHECK_ERR(SrcTexDesc.Format == DstTexDesc.Format, "Vulkan requires that source and destination textures of a resolve operation " + "have the same format (18.6)");(void)DstTexDesc; + + EnsureVkCmdBuffer(); + // srcImageLayout must be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL (18.6) + TransitionOrVerifyTextureState(*pSrcTexVk, ResolveAttribs.SrcTextureTransitionMode, RESOURCE_STATE_RESOLVE_SOURCE, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + "Resolving multi-sampled texture (DeviceContextVkImpl::ResolveTextureSubresource)"); + + // dstImageLayout must be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL (18.6) + TransitionOrVerifyTextureState(*pDstTexVk, ResolveAttribs.DstTextureTransitionMode, RESOURCE_STATE_RESOLVE_DEST, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + "Resolving multi-sampled texture (DeviceContextVkImpl::ResolveTextureSubresource)"); + + const auto& ResolveFmtAttribs = GetTextureFormatAttribs(SrcTexDesc.Format); + DEV_CHECK_ERR(ResolveFmtAttribs.ComponentType != COMPONENT_TYPE_DEPTH && ResolveFmtAttribs.ComponentType != COMPONENT_TYPE_DEPTH_STENCIL, + "Vulkan only allows resolve operation for color formats");(void)ResolveFmtAttribs; + // The aspectMask member of srcSubresource and dstSubresource must only contain VK_IMAGE_ASPECT_COLOR_BIT (18.6) + VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + VkImageResolve ResolveRegion; + ResolveRegion.srcSubresource.baseArrayLayer = ResolveAttribs.SrcSlice; + ResolveRegion.srcSubresource.layerCount = 1; + ResolveRegion.srcSubresource.mipLevel = ResolveAttribs.SrcMipLevel; + ResolveRegion.srcSubresource.aspectMask = aspectMask; + + ResolveRegion.dstSubresource.baseArrayLayer = ResolveAttribs.DstSlice; + ResolveRegion.dstSubresource.layerCount = 1; + ResolveRegion.dstSubresource.mipLevel = ResolveAttribs.DstMipLevel; + ResolveRegion.dstSubresource.aspectMask = aspectMask; + + ResolveRegion.srcOffset = VkOffset3D{}; + ResolveRegion.dstOffset = VkOffset3D{}; + const auto& MipAttribs = GetMipLevelProperties(SrcTexDesc, ResolveAttribs.SrcMipLevel); + ResolveRegion.extent = VkExtent3D + { + static_cast<uint32_t>(MipAttribs.LogicalWidth), + static_cast<uint32_t>(MipAttribs.LogicalHeight), + static_cast<uint32_t>(MipAttribs.Depth) + }; + + m_CommandBuffer.ResolveImage(pSrcTexVk->GetVkImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + pDstTexVk->GetVkImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, &ResolveRegion); + } } diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 41ff3a9e..1c4cd26c 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -55,7 +55,7 @@ VkRenderPassCreateInfo PipelineStateVkImpl::GetRenderPassCreateInfo( RenderPassCI.attachmentCount = (DSVFormat != TEX_FORMAT_UNKNOWN ? 1 : 0) + NumRenderTargets; uint32_t AttachmentInd = 0; - VkSampleCountFlagBits SampleCountFlags = static_cast<VkSampleCountFlagBits>(1 << (SampleCount - 1)); + VkSampleCountFlagBits SampleCountFlags = static_cast<VkSampleCountFlagBits>(SampleCount); VkAttachmentReference* pDepthAttachmentReference = nullptr; if (DSVFormat != TEX_FORMAT_UNKNOWN) { @@ -356,7 +356,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters MSStateCI.flags = 0; // reserved for future use // If subpass uses color and/or depth/stencil attachments, then the rasterizationSamples member of // pMultisampleState must be the same as the sample count for those subpass attachments - MSStateCI.rasterizationSamples = static_cast<VkSampleCountFlagBits>(1 << (GraphicsPipeline.SmplDesc.Count-1)); + MSStateCI.rasterizationSamples = static_cast<VkSampleCountFlagBits>(GraphicsPipeline.SmplDesc.Count); MSStateCI.sampleShadingEnable = VK_FALSE; MSStateCI.minSampleShading = 0; // a minimum fraction of sample shading if sampleShadingEnable is set to VK_TRUE. uint32_t SampleMask[] = {GraphicsPipeline.SampleMask, 0}; // Vulkan spec allows up to 64 samples diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index 31edb0af..e1d3a8cd 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -412,7 +412,7 @@ void SwapChainVkImpl::InitBuffersAndViews() DepthBufferDesc.Width = m_SwapChainDesc.Width; DepthBufferDesc.Height = m_SwapChainDesc.Height; DepthBufferDesc.Format = m_SwapChainDesc.DepthBufferFormat; - DepthBufferDesc.SampleCount = m_SwapChainDesc.SamplesCount; + DepthBufferDesc.SampleCount = 1; DepthBufferDesc.Usage = USAGE_DEFAULT; DepthBufferDesc.BindFlags = BIND_DEPTH_STENCIL; diff --git a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp index b74d4f60..12deef67 100644 --- a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp @@ -110,7 +110,7 @@ TextureVkImpl :: TextureVkImpl(IReferenceCounters* pRefCounters, else ImageCI.arrayLayers = 1; - ImageCI.samples = static_cast<VkSampleCountFlagBits>(1 << (m_Desc.SampleCount-1)); + ImageCI.samples = static_cast<VkSampleCountFlagBits>(m_Desc.SampleCount); ImageCI.tiling = VK_IMAGE_TILING_OPTIMAL; ImageCI.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp index fa286903..9987f013 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp @@ -1294,8 +1294,8 @@ VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag) case RESOURCE_STATE_INDIRECT_ARGUMENT: UNEXPECTED("Invalid resource state"); return VK_IMAGE_LAYOUT_UNDEFINED; case RESOURCE_STATE_COPY_DEST: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; case RESOURCE_STATE_COPY_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - case RESOURCE_STATE_RESOLVE_DEST: UNSUPPORTED("Not currently implemented"); return VK_IMAGE_LAYOUT_UNDEFINED; - case RESOURCE_STATE_RESOLVE_SOURCE: UNSUPPORTED("Not currently implemented"); return VK_IMAGE_LAYOUT_UNDEFINED; + case RESOURCE_STATE_RESOLVE_DEST: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + case RESOURCE_STATE_RESOLVE_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; case RESOURCE_STATE_PRESENT: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; default: |
