diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 6338ea86e..65eb75e35 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -118,7 +118,7 @@ namespace dxvk { info.flags = baseHandle == VK_NULL_HANDLE ? VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT : VK_PIPELINE_CREATE_DERIVATIVE_BIT; - info.stage = csm->stageInfo(&specInfo); + info.stage = csm.stageInfo(&specInfo); info.layout = m_layout->pipelineLayout(); info.basePipelineHandle = baseHandle; info.basePipelineIndex = -1; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 504f27faf..cbb68a5ac 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -213,11 +213,11 @@ namespace dxvk { auto tesm = createShaderModule(m_tes, moduleInfo); auto fsm = createShaderModule(m_fs, moduleInfo); - if (m_vs != nullptr) stages.push_back(vsm->stageInfo(&specInfo)); - if (m_tcs != nullptr) stages.push_back(tcsm->stageInfo(&specInfo)); - if (m_tes != nullptr) stages.push_back(tesm->stageInfo(&specInfo)); - if (m_gs != nullptr) stages.push_back(gsm->stageInfo(&specInfo)); - if (m_fs != nullptr) stages.push_back(fsm->stageInfo(&specInfo)); + if (vsm) stages.push_back(vsm.stageInfo(&specInfo)); + if (tcsm) stages.push_back(tcsm.stageInfo(&specInfo)); + if (tesm) stages.push_back(tesm.stageInfo(&specInfo)); + if (gsm) stages.push_back(gsm.stageInfo(&specInfo)); + if (fsm) stages.push_back(fsm.stageInfo(&specInfo)); // Fix up color write masks using the component mappings std::array omBlendAttachments; @@ -428,12 +428,12 @@ namespace dxvk { } - Rc DxvkGraphicsPipeline::createShaderModule( + DxvkShaderModule DxvkGraphicsPipeline::createShaderModule( const Rc& shader, const DxvkShaderModuleCreateInfo& info) const { return shader != nullptr ? shader->createShaderModule(m_vkd, m_slotMapping, info) - : nullptr; + : DxvkShaderModule(); } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 090bf7883..aaf64e43a 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -280,7 +280,7 @@ namespace dxvk { void destroyPipeline( VkPipeline pipeline) const; - Rc createShaderModule( + DxvkShaderModule createShaderModule( const Rc& shader, const DxvkShaderModuleCreateInfo& info) const; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 6e9a06301..0fab07b6a 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -38,11 +38,28 @@ namespace dxvk { } + DxvkShaderModule::DxvkShaderModule() + : m_vkd(nullptr), m_info { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + nullptr, 0, VkShaderStageFlagBits(0), VK_NULL_HANDLE, nullptr, nullptr } { + + } + + + DxvkShaderModule::DxvkShaderModule(DxvkShaderModule&& other) + : m_vkd (std::move(other.m_vkd)), + m_info(std::exchange(m_info, VkPipelineShaderStageCreateInfo())) { + + } + + DxvkShaderModule::DxvkShaderModule( const Rc& vkd, const Rc& shader, const SpirvCodeBuffer& code) - : m_vkd(vkd), m_shader(shader) { + : m_vkd(vkd), m_info { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + nullptr, 0, shader->stage(), VK_NULL_HANDLE, "main", nullptr } { VkShaderModuleCreateInfo info; info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; info.pNext = nullptr; @@ -50,31 +67,26 @@ namespace dxvk { info.codeSize = code.size(); info.pCode = code.data(); - if (m_vkd->vkCreateShaderModule(m_vkd->device(), - &info, nullptr, &m_module) != VK_SUCCESS) + if (m_vkd->vkCreateShaderModule(m_vkd->device(), &info, nullptr, &m_info.module) != VK_SUCCESS) throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create shader module"); } DxvkShaderModule::~DxvkShaderModule() { - m_vkd->vkDestroyShaderModule( - m_vkd->device(), m_module, nullptr); + if (m_vkd != nullptr) { + m_vkd->vkDestroyShaderModule( + m_vkd->device(), m_info.module, nullptr); + } } - VkPipelineShaderStageCreateInfo DxvkShaderModule::stageInfo(const VkSpecializationInfo* specInfo) const { - VkPipelineShaderStageCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.stage = m_shader->stage(); - info.module = m_module; - info.pName = "main"; - info.pSpecializationInfo = specInfo; - return info; + DxvkShaderModule& DxvkShaderModule::operator = (DxvkShaderModule&& other) { + m_vkd = std::move(other.m_vkd); + m_info = std::exchange(other.m_info, VkPipelineShaderStageCreateInfo()); + return *this; } - - + + DxvkShader::DxvkShader( VkShaderStageFlagBits stage, uint32_t slotCount, @@ -137,7 +149,7 @@ namespace dxvk { } - Rc DxvkShader::createShaderModule( + DxvkShaderModule DxvkShader::createShaderModule( const Rc& vkd, const DxvkDescriptorSlotMapping& mapping, const DxvkShaderModuleCreateInfo& info) { @@ -155,7 +167,7 @@ namespace dxvk { if (info.fsDualSrcBlend && m_o1IdxOffset && m_o1LocOffset) std::swap(code[m_o1IdxOffset], code[m_o1LocOffset]); - return new DxvkShaderModule(vkd, this, spirvCode); + return DxvkShaderModule(vkd, this, spirvCode); } diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 6ea46e76e..e177cb7be 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -175,7 +175,7 @@ namespace dxvk { * \param [in] info Module create info * \returns The shader module */ - Rc createShaderModule( + DxvkShaderModule createShaderModule( const Rc& vkd, const DxvkDescriptorSlotMapping& mapping, const DxvkShaderModuleCreateInfo& info); @@ -269,9 +269,13 @@ namespace dxvk { * context will create pipeline objects on the * fly when executing draw calls. */ - class DxvkShaderModule : public RcObject { + class DxvkShaderModule { public: + + DxvkShaderModule(); + + DxvkShaderModule(DxvkShaderModule&& other); DxvkShaderModule( const Rc& vkd, @@ -279,14 +283,8 @@ namespace dxvk { const SpirvCodeBuffer& code); ~DxvkShaderModule(); - - /** - * \brief Shader module handle - * \returns Shader module handle - */ - VkShaderModule handle() const { - return m_module; - } + + DxvkShaderModule& operator = (DxvkShaderModule&& other); /** * \brief Shader stage creation info @@ -295,29 +293,24 @@ namespace dxvk { * \returns Shader stage create info */ VkPipelineShaderStageCreateInfo stageInfo( - const VkSpecializationInfo* specInfo) const; + const VkSpecializationInfo* specInfo) const { + VkPipelineShaderStageCreateInfo info = m_info; + info.pSpecializationInfo = specInfo; + return info; + } /** - * \brief Shader object - * \returns The shader + * \brief Checks whether module is valid + * \returns \c true if module is valid */ - Rc shader() const { - return m_shader; - } - - /** - * \brief Retrieves shader key - * \returns Unique shader key - */ - DxvkShaderKey getShaderKey() const { - return m_shader->getShaderKey(); + operator bool () const { + return m_info.module != VK_NULL_HANDLE; } private: - Rc m_vkd; - Rc m_shader; - VkShaderModule m_module; + Rc m_vkd; + VkPipelineShaderStageCreateInfo m_info; };