From b0db58f09833cc18df78239d450315bdbebd2c65 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 9 Apr 2022 13:35:06 +0200 Subject: [PATCH] [dxvk] Introduce new way to create DxvkShader objects --- src/dxvk/dxvk_shader.cpp | 62 +++++++++++++++++++++++--------- src/dxvk/dxvk_shader.h | 78 ++++++++++++++++++++++++++++++++-------- 2 files changed, 109 insertions(+), 31 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 20acd0733..641d67336 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -64,7 +64,7 @@ namespace dxvk { m_stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; m_stage.pNext = nullptr; m_stage.flags = 0; - m_stage.stage = shader->stage(); + m_stage.stage = shader->info().stage; m_stage.module = VK_NULL_HANDLE; m_stage.pName = "main"; m_stage.pSpecializationInfo = nullptr; @@ -105,14 +105,44 @@ namespace dxvk { SpirvCodeBuffer code, const DxvkShaderOptions& options, DxvkShaderConstData&& constData) - : m_stage(stage), m_code(code), m_interface(iface), - m_options(options), m_constData(std::move(constData)) { - // Write back resource slot infos - for (uint32_t i = 0; i < slotCount; i++) - m_slots.push_back(slotInfos[i]); - - // Gather the offsets where the binding IDs - // are stored so we can quickly remap them. + : DxvkShader(DxvkShaderCreateInfo { + stage, slotCount, slotInfos, + iface.inputSlots, iface.outputSlots, + iface.pushConstOffset, iface.pushConstSize, + uint32_t(constData.sizeInBytes()), + reinterpret_cast(constData.data()), + options.rasterizedStream, + { options.xfbStrides[0], options.xfbStrides[1], + options.xfbStrides[2], options.xfbStrides[3] } + }, std::move(code)) { + } + + + DxvkShader::DxvkShader( + const DxvkShaderCreateInfo& info, + SpirvCodeBuffer&& spirv) + : m_info(info), m_code(spirv) { + m_info.resourceSlots = nullptr; + m_info.uniformData = nullptr; + + // Copy resource binding slot infos + if (info.resourceSlotCount) { + m_slots.resize(info.resourceSlotCount); + for (uint32_t i = 0; i < info.resourceSlotCount; i++) + m_slots[i] = info.resourceSlots[i]; + m_info.resourceSlots = m_slots.data(); + } + + // Copy uniform buffer data + if (info.uniformSize) { + m_uniformData.resize(info.uniformSize); + std::memcpy(m_uniformData.data(), info.uniformData, info.uniformSize); + m_info.uniformData = m_uniformData.data(); + } + + // Run an analysis pass over the SPIR-V code to gather some + // info that we may need during pipeline compilation. + SpirvCodeBuffer code = std::move(spirv); uint32_t o1VarId = 0; for (auto ins : code) { @@ -147,8 +177,8 @@ namespace dxvk { } } } - - + + DxvkShader::~DxvkShader() { } @@ -157,12 +187,12 @@ namespace dxvk { void DxvkShader::defineResourceSlots( DxvkDescriptorSlotMapping& mapping) const { for (const auto& slot : m_slots) - mapping.defineSlot(m_stage, slot); + mapping.defineSlot(m_info.stage, slot); - if (m_interface.pushConstSize) { - mapping.definePushConstRange(m_stage, - m_interface.pushConstOffset, - m_interface.pushConstSize); + if (m_info.pushConstSize) { + mapping.definePushConstRange(m_info.stage, + m_info.pushConstOffset, + m_info.pushConstSize); } } diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 17967cfff..46c1390d8 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -117,6 +117,31 @@ namespace dxvk { }; + /** + * \brief Shader info + */ + struct DxvkShaderCreateInfo { + /// Shader stage + VkShaderStageFlagBits stage; + /// Descriptor info + uint32_t resourceSlotCount = 0; + const DxvkResourceSlot* resourceSlots = nullptr; + /// Input and output register mask + uint32_t inputMask = 0; + uint32_t outputMask = 0; + /// Push constant range + uint32_t pushConstOffset = 0; + uint32_t pushConstSize = 0; + /// Uniform buffer data + uint32_t uniformSize = 0; + const char* uniformData = nullptr; + /// Rasterized stream, or -1 + int32_t xfbRasterizedStream = 0; + /// Transform feedback vertex strides + uint32_t xfbStrides[MaxNumXfbBuffers] = { }; + }; + + /** * \brief Shader module create info */ @@ -146,15 +171,27 @@ namespace dxvk { SpirvCodeBuffer code, const DxvkShaderOptions& options, DxvkShaderConstData&& constData); - + + DxvkShader( + const DxvkShaderCreateInfo& info, + SpirvCodeBuffer&& spirv); + ~DxvkShader(); + /** + * \brief Shader info + * \returns Shader info + */ + const DxvkShaderCreateInfo& info() const { + return m_info; + } + /** * \brief Shader stage * \returns Shader stage */ VkShaderStageFlagBits stage() const { - return m_stage; + return m_info.stage; } /** @@ -197,7 +234,12 @@ namespace dxvk { * \returns Shader interface slots */ DxvkInterfaceSlots interfaceSlots() const { - return m_interface; + DxvkInterfaceSlots iface = { }; + iface.inputSlots = m_info.inputMask; + iface.outputSlots = m_info.outputMask; + iface.pushConstOffset = m_info.pushConstOffset; + iface.pushConstSize = m_info.pushConstSize; + return iface; } /** @@ -205,7 +247,11 @@ namespace dxvk { * \returns Shader options */ DxvkShaderOptions shaderOptions() const { - return m_options; + DxvkShaderOptions options = { }; + options.rasterizedStream = m_info.xfbRasterizedStream; + for (uint32_t i = 0; i < MaxNumXfbBuffers; i++) + options.xfbStrides[i] = m_info.xfbStrides[i]; + return options; } /** @@ -216,8 +262,11 @@ namespace dxvk { * shader object. * \returns Shader constant data */ - const DxvkShaderConstData& shaderConstants() const { - return m_constData; + DxvkShaderConstData shaderConstants() const { + return m_info.uniformSize + ? DxvkShaderConstData(m_info.uniformSize / sizeof(uint32_t), + reinterpret_cast(m_info.uniformData)) + : DxvkShaderConstData(); } /** @@ -279,20 +328,19 @@ namespace dxvk { private: - VkShaderStageFlagBits m_stage; - SpirvCompressedBuffer m_code; + DxvkShaderCreateInfo m_info; + SpirvCompressedBuffer m_code; - std::vector m_slots; - std::vector m_idOffsets; - DxvkInterfaceSlots m_interface; DxvkShaderFlags m_flags; - DxvkShaderOptions m_options; - DxvkShaderConstData m_constData; DxvkShaderKey m_key; size_t m_hash = 0; - size_t m_o1IdxOffset = 0; - size_t m_o1LocOffset = 0; + size_t m_o1IdxOffset = 0; + size_t m_o1LocOffset = 0; + + std::vector m_slots; + std::vector m_uniformData; + std::vector m_idOffsets; static void eliminateInput(SpirvCodeBuffer& code, uint32_t location);