From 119c06e453c6f42c1d4d0283860f11c4c1243491 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 8 Nov 2018 16:51:12 +0100 Subject: [PATCH] [dxvk] Add pipelines needed for depth-stencil packing - Add method to retrieve meta pack pipeline for a given format - Add descriptor update template --- src/dxvk/dxvk_meta_pack.cpp | 164 ++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_meta_pack.h | 94 +++++++++++++++++++++ src/dxvk/meson.build | 1 + 3 files changed, 259 insertions(+) create mode 100644 src/dxvk/dxvk_meta_pack.cpp create mode 100644 src/dxvk/dxvk_meta_pack.h diff --git a/src/dxvk/dxvk_meta_pack.cpp b/src/dxvk/dxvk_meta_pack.cpp new file mode 100644 index 00000000..8c4280e2 --- /dev/null +++ b/src/dxvk/dxvk_meta_pack.cpp @@ -0,0 +1,164 @@ +#include "dxvk_meta_pack.h" + +#include +#include + +namespace dxvk { + + DxvkMetaPackObjects::DxvkMetaPackObjects(const Rc& vkd) + : m_vkd (vkd), + m_dsetLayout (createDescriptorSetLayout()), + m_pipeLayout (createPipelineLayout()), + m_template (createDescriptorUpdateTemplate()), + m_pipeD24S8 (createPipeline(dxvk_pack_d24s8)), + m_pipeD32S8 (createPipeline(dxvk_pack_d32s8)) { + + } + + + DxvkMetaPackObjects::~DxvkMetaPackObjects() { + m_vkd->vkDestroyPipeline(m_vkd->device(), m_pipeD32S8, nullptr); + m_vkd->vkDestroyPipeline(m_vkd->device(), m_pipeD24S8, nullptr); + + m_vkd->vkDestroyDescriptorUpdateTemplateKHR( + m_vkd->device(), m_template, nullptr); + + m_vkd->vkDestroyPipelineLayout( + m_vkd->device(), m_pipeLayout, nullptr); + + m_vkd->vkDestroyDescriptorSetLayout( + m_vkd->device(), m_dsetLayout, nullptr); + } + + + DxvkMetaPackPipeline DxvkMetaPackObjects::getPipeline(VkFormat format) { + DxvkMetaPackPipeline result; + result.dsetTemplate = m_template; + result.dsetLayout = m_dsetLayout; + result.pipeLayout = m_pipeLayout; + result.pipeHandle = VK_NULL_HANDLE; + + switch (format) { + case VK_FORMAT_D24_UNORM_S8_UINT: result.pipeHandle = m_pipeD24S8; break; + case VK_FORMAT_D32_SFLOAT_S8_UINT: result.pipeHandle = m_pipeD32S8; break; + default: Logger::err(str::format("DxvkMetaPackObjects: Unknown format: ", format)); + } + + return result; + } + + + VkDescriptorSetLayout DxvkMetaPackObjects::createDescriptorSetLayout() { + std::array bindings = {{ + { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, + { 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, + { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, + }}; + + VkDescriptorSetLayoutCreateInfo dsetInfo; + dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + dsetInfo.pNext = nullptr; + dsetInfo.flags = 0; + dsetInfo.bindingCount = bindings.size(); + dsetInfo.pBindings = bindings.data(); + + VkDescriptorSetLayout result = VK_NULL_HANDLE; + if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(), &dsetInfo, nullptr, &result) != VK_SUCCESS) + throw DxvkError("DxvkMetaPackObjects: Failed to create descriptor set layout"); + return result; + } + + + VkPipelineLayout DxvkMetaPackObjects::createPipelineLayout() { + VkPushConstantRange push; + push.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + push.offset = 0; + push.size = sizeof(DxvkMetaPackArgs); + + VkPipelineLayoutCreateInfo layoutInfo; + layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + layoutInfo.pNext = nullptr; + layoutInfo.flags = 0; + layoutInfo.setLayoutCount = 1; + layoutInfo.pSetLayouts = &m_dsetLayout; + layoutInfo.pushConstantRangeCount = 1; + layoutInfo.pPushConstantRanges = &push; + + VkPipelineLayout result = VK_NULL_HANDLE; + if (m_vkd->vkCreatePipelineLayout(m_vkd->device(), &layoutInfo, nullptr, &result) != VK_SUCCESS) + throw DxvkError("DxvkMetaPackObjects: Failed to create pipeline layout"); + return result; + } + + + VkDescriptorUpdateTemplateKHR DxvkMetaPackObjects::createDescriptorUpdateTemplate() { + std::array bindings = {{ + { 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, offsetof(DxvkMetaPackDescriptors, dstBuffer), 0 }, + { 1, 0, 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, offsetof(DxvkMetaPackDescriptors, srcDepth), 0 }, + { 2, 0, 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, offsetof(DxvkMetaPackDescriptors, srcStencil), 0 }, + }}; + + VkDescriptorUpdateTemplateCreateInfoKHR templateInfo; + templateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR; + templateInfo.pNext = nullptr; + templateInfo.flags = 0; + templateInfo.descriptorUpdateEntryCount = bindings.size(); + templateInfo.pDescriptorUpdateEntries = bindings.data(); + templateInfo.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR; + templateInfo.descriptorSetLayout = m_dsetLayout; + templateInfo.pipelineBindPoint = VK_PIPELINE_BIND_POINT_COMPUTE; + templateInfo.pipelineLayout = m_pipeLayout; + templateInfo.set = 0; + + VkDescriptorUpdateTemplateKHR result = VK_NULL_HANDLE; + if (m_vkd->vkCreateDescriptorUpdateTemplateKHR(m_vkd->device(), + &templateInfo, nullptr, &result) != VK_SUCCESS) + throw DxvkError("DxvkMetaPackObjects: Failed to create descriptor update template"); + return result; + } + + + VkPipeline DxvkMetaPackObjects::createPipeline(const SpirvCodeBuffer& code) { + VkShaderModuleCreateInfo shaderInfo; + shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shaderInfo.pNext = nullptr; + shaderInfo.flags = 0; + shaderInfo.codeSize = code.size(); + shaderInfo.pCode = code.data(); + + VkShaderModule module = VK_NULL_HANDLE; + + if (m_vkd->vkCreateShaderModule(m_vkd->device(), &shaderInfo, nullptr, &module) != VK_SUCCESS) + throw DxvkError("DxvkMetaPackObjects: Failed to create shader module"); + + VkPipelineShaderStageCreateInfo stageInfo; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.pNext = nullptr; + stageInfo.flags = 0; + stageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; + stageInfo.module = module; + stageInfo.pName = "main"; + stageInfo.pSpecializationInfo = nullptr; + + VkComputePipelineCreateInfo pipeInfo; + pipeInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + pipeInfo.pNext = nullptr; + pipeInfo.flags = 0; + pipeInfo.stage = stageInfo; + pipeInfo.layout = m_pipeLayout; + pipeInfo.basePipelineHandle = VK_NULL_HANDLE; + pipeInfo.basePipelineIndex = -1; + + VkPipeline result = VK_NULL_HANDLE; + + VkResult status = m_vkd->vkCreateComputePipelines( + m_vkd->device(), VK_NULL_HANDLE, 1, &pipeInfo, nullptr, &result); + + m_vkd->vkDestroyShaderModule(m_vkd->device(), module, nullptr); + + if (status != VK_SUCCESS) + throw DxvkError("DxvkMetaPackObjects: Failed to create pipeline"); + return result; + } + +} \ No newline at end of file diff --git a/src/dxvk/dxvk_meta_pack.h b/src/dxvk/dxvk_meta_pack.h new file mode 100644 index 00000000..fdbe4686 --- /dev/null +++ b/src/dxvk/dxvk_meta_pack.h @@ -0,0 +1,94 @@ +#pragma once + +#include "../spirv/spirv_code_buffer.h" + +#include "dxvk_cmdlist.h" +#include "dxvk_resource.h" + +namespace dxvk { + + /** + * \brief Packing arguments + * + * Passed in as push constants + * to the compute shader. + */ + struct DxvkMetaPackArgs { + VkOffset2D srcOffset; + VkExtent2D srcExtent; + }; + + + /** + * \brief Packing pipeline + * + * Stores the objects for a single pipeline + * that is used to pack depth-stencil image + * data into a linear buffer. + */ + struct DxvkMetaPackPipeline { + VkDescriptorUpdateTemplateKHR dsetTemplate; + VkDescriptorSetLayout dsetLayout; + VkPipelineLayout pipeLayout; + VkPipeline pipeHandle; + }; + + + /** + * \brief Packing descriptors + */ + struct DxvkMetaPackDescriptors { + VkDescriptorBufferInfo dstBuffer; + VkDescriptorImageInfo srcDepth; + VkDescriptorImageInfo srcStencil; + }; + + + /** + * \brief Depth-stencil pack objects + * + * Stores compute shaders and related objects + * for depth-stencil image packing operations. + */ + class DxvkMetaPackObjects : public RcObject { + + public: + + DxvkMetaPackObjects(const Rc& vkd); + ~DxvkMetaPackObjects(); + + /** + * \brief Retrieves pipeline for a packed format + * + * \param [in] format Destination format + * \returns Packed pipeline + */ + DxvkMetaPackPipeline getPipeline(VkFormat format); + + private: + + Rc m_vkd; + + VkDescriptorSetLayout m_dsetLayout; + VkPipelineLayout m_pipeLayout; + + VkDescriptorUpdateTemplateKHR m_template; + + VkShaderModule m_shaderD24S8; + VkShaderModule m_shaderD32S8; + + VkPipeline m_pipeD24S8; + VkPipeline m_pipeD32S8; + + VkDescriptorSetLayout createDescriptorSetLayout(); + + VkPipelineLayout createPipelineLayout(); + + VkDescriptorUpdateTemplateKHR createDescriptorUpdateTemplate(); + + VkPipeline createPipeline( + const SpirvCodeBuffer& code); + + }; + +} \ No newline at end of file diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index dbe2ff8b..4b221396 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -66,6 +66,7 @@ dxvk_src = files([ 'dxvk_meta_clear.cpp', 'dxvk_meta_copy.cpp', 'dxvk_meta_mipgen.cpp', + 'dxvk_meta_pack.cpp', 'dxvk_meta_resolve.cpp', 'dxvk_openvr.cpp', 'dxvk_options.cpp',