1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-27 04:54:15 +01:00

[dxvk] DxvkShader creates a VkShaderModule again

This commit is contained in:
Philip Rebohle 2017-11-20 14:03:00 +01:00
parent a895b0159b
commit a9a03fec69
16 changed files with 122 additions and 48 deletions

View File

@ -50,7 +50,7 @@ namespace dxvk {
} }
Rc<DxvkShader> DxbcCompiler::finalize() { SpirvCodeBuffer DxbcCompiler::finalize() {
return m_gen->finalize(); return m_gen->finalize();
} }

View File

@ -21,7 +21,7 @@ namespace dxvk {
void processInstruction( void processInstruction(
const DxbcInstruction& ins); const DxbcInstruction& ins);
Rc<DxvkShader> finalize(); SpirvCodeBuffer finalize();
private: private:

View File

@ -40,7 +40,7 @@ namespace dxvk {
} }
Rc<DxvkShader> DxbcModule::compile() const { SpirvCodeBuffer DxbcModule::compile() const {
if (m_shexChunk == nullptr) if (m_shexChunk == nullptr)
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk"); throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");

View File

@ -31,7 +31,7 @@ namespace dxvk {
* \brief Compiles DXBC shader to SPIR-V module * \brief Compiles DXBC shader to SPIR-V module
* \returns The compiled DXVK shader object * \returns The compiled DXVK shader object
*/ */
Rc<DxvkShader> compile() const; SpirvCodeBuffer compile() const;
private: private:

View File

@ -109,7 +109,7 @@ namespace dxvk {
uint32_t regId, uint32_t regId,
const DxbcValue& index) = 0; const DxbcValue& index) = 0;
virtual Rc<DxvkShader> finalize() = 0; virtual SpirvCodeBuffer finalize() = 0;
static Rc<DxbcCodeGen> create( static Rc<DxbcCodeGen> create(
const DxbcProgramVersion& version); const DxbcProgramVersion& version);

View File

@ -88,7 +88,7 @@ namespace dxvk {
} }
Rc<DxvkShader> DxbcPsCodeGen::finalize() { SpirvCodeBuffer DxbcPsCodeGen::finalize() {
m_module.functionBegin( m_module.functionBegin(
m_module.defVoidType(), m_module.defVoidType(),
m_entryPointId, m_entryPointId,
@ -112,9 +112,7 @@ namespace dxvk {
m_entryPointInterfaces.data()); m_entryPointInterfaces.data());
m_module.setDebugName(m_entryPointId, "main"); m_module.setDebugName(m_entryPointId, "main");
return new DxvkShader( return m_module.compile();
VK_SHADER_STAGE_FRAGMENT_BIT,
m_module.compile());
} }

View File

@ -30,7 +30,7 @@ namespace dxvk {
uint32_t regId, uint32_t regId,
const DxbcValue& index); const DxbcValue& index);
Rc<DxvkShader> finalize() final; SpirvCodeBuffer finalize() final;
private: private:

View File

@ -95,7 +95,7 @@ namespace dxvk {
} }
Rc<DxvkShader> DxbcVsCodeGen::finalize() { SpirvCodeBuffer DxbcVsCodeGen::finalize() {
m_module.functionBegin( m_module.functionBegin(
m_module.defVoidType(), m_module.defVoidType(),
m_entryPointId, m_entryPointId,
@ -119,9 +119,7 @@ namespace dxvk {
m_entryPointInterfaces.data()); m_entryPointInterfaces.data());
m_module.setDebugName(m_entryPointId, "main"); m_module.setDebugName(m_entryPointId, "main");
return new DxvkShader( return m_module.compile();
VK_SHADER_STAGE_VERTEX_BIT,
m_module.compile());
} }

View File

@ -30,7 +30,7 @@ namespace dxvk {
uint32_t regId, uint32_t regId,
const DxbcValue& index); const DxbcValue& index);
Rc<DxvkShader> finalize() final; SpirvCodeBuffer finalize() final;
private: private:

View File

@ -5,7 +5,7 @@ namespace dxvk {
DxvkComputePipeline::DxvkComputePipeline( DxvkComputePipeline::DxvkComputePipeline(
const Rc<vk::DeviceFn>& vkd, const Rc<vk::DeviceFn>& vkd,
const Rc<DxvkShader>& shader) const Rc<DxvkShader>& shader)
: m_vkd(vkd) { : m_vkd(vkd), m_shader(shader) {
TRACE(this, shader); TRACE(this, shader);
std::vector<VkDescriptorSetLayoutBinding> bindings; std::vector<VkDescriptorSetLayoutBinding> bindings;
@ -40,27 +40,12 @@ namespace dxvk {
throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create pipeline layout"); throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create pipeline layout");
} }
SpirvCodeBuffer code = shader->code();
VkShaderModuleCreateInfo minfo;
minfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
minfo.pNext = nullptr;
minfo.flags = 0;
minfo.codeSize = code.size();
minfo.pCode = code.data();
if (m_vkd->vkCreateShaderModule(m_vkd->device(),
&minfo, nullptr, &m_module) != VK_SUCCESS) {
this->destroyObjects();
throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create shader module");
}
VkPipelineShaderStageCreateInfo sinfo; VkPipelineShaderStageCreateInfo sinfo;
sinfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; sinfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
sinfo.pNext = nullptr; sinfo.pNext = nullptr;
sinfo.flags = 0; sinfo.flags = 0;
sinfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; sinfo.stage = VK_SHADER_STAGE_COMPUTE_BIT;
sinfo.module = m_module; sinfo.module = m_shader->module();
sinfo.pName = "main"; sinfo.pName = "main";
sinfo.pSpecializationInfo = nullptr; sinfo.pSpecializationInfo = nullptr;
@ -91,9 +76,6 @@ namespace dxvk {
if (m_pipeline != VK_NULL_HANDLE) if (m_pipeline != VK_NULL_HANDLE)
m_vkd->vkDestroyPipeline(m_vkd->device(), m_pipeline, nullptr); m_vkd->vkDestroyPipeline(m_vkd->device(), m_pipeline, nullptr);
if (m_module != VK_NULL_HANDLE)
m_vkd->vkDestroyShaderModule(m_vkd->device(), m_module, nullptr);
if (m_pipelineLayout != VK_NULL_HANDLE) if (m_pipelineLayout != VK_NULL_HANDLE)
m_vkd->vkDestroyPipelineLayout(m_vkd->device(), m_pipelineLayout, nullptr); m_vkd->vkDestroyPipelineLayout(m_vkd->device(), m_pipelineLayout, nullptr);

View File

@ -55,9 +55,10 @@ namespace dxvk {
private: private:
Rc<vk::DeviceFn> m_vkd; Rc<vk::DeviceFn> m_vkd;
Rc<DxvkShader> m_shader;
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE; VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
VkShaderModule m_module = VK_NULL_HANDLE;
VkPipeline m_pipeline = VK_NULL_HANDLE; VkPipeline m_pipeline = VK_NULL_HANDLE;
void destroyObjects(); void destroyObjects();

View File

@ -72,7 +72,72 @@ namespace dxvk {
VkPipeline DxvkGraphicsPipeline::compilePipeline( VkPipeline DxvkGraphicsPipeline::compilePipeline(
const DxvkGraphicsPipelineStateInfo& state) const { const DxvkGraphicsPipelineStateInfo& state) const {
std::array<VkDynamicState, 4> dynamicStates = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR,
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
};
std::vector<VkPipelineShaderStageCreateInfo> stages;
if (m_vs != nullptr) stages.push_back(m_vs->stageInfo());
if (m_tcs != nullptr) stages.push_back(m_tcs->stageInfo());
if (m_tes != nullptr) stages.push_back(m_tes->stageInfo());
if (m_gs != nullptr) stages.push_back(m_gs->stageInfo());
if (m_fs != nullptr) stages.push_back(m_fs->stageInfo());
VkPipelineViewportStateCreateInfo vpInfo;
vpInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
vpInfo.pNext = nullptr;
vpInfo.flags = 0;
vpInfo.viewportCount = state.viewportCount;
vpInfo.pViewports = nullptr;
vpInfo.scissorCount = state.viewportCount;
vpInfo.pViewports = nullptr;
VkPipelineDynamicStateCreateInfo dsInfo;
dsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dsInfo.pNext = nullptr;
dsInfo.flags = 0;
dsInfo.dynamicStateCount = dynamicStates.size();
dsInfo.pDynamicStates = dynamicStates.data();
VkGraphicsPipelineCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
info.pNext = nullptr;
info.flags = 0;
info.stageCount = stages.size();
info.pStages = stages.data();
info.pVertexInputState = &state.inputLayout->info();
info.pInputAssemblyState = &state.inputAssemblyState->info();
info.pTessellationState = nullptr; // TODO implement
info.pViewportState = &vpInfo;
info.pRasterizationState = &state.rasterizerState->info();
info.pMultisampleState = &state.multisampleState->info();
info.pDepthStencilState = &state.depthStencilState->info();
info.pColorBlendState = &state.blendState->info();
info.pDynamicState = &dsInfo;
info.layout = m_pipelineLayout;
info.renderPass = state.renderPass;
info.subpass = 0;
info.basePipelineHandle = VK_NULL_HANDLE;
info.basePipelineIndex = 0;
VkPipeline pipeline = VK_NULL_HANDLE;
if (m_vkd->vkCreateGraphicsPipelines(m_vkd->device(),
VK_NULL_HANDLE, 1, &info, nullptr, &pipeline) != VK_SUCCESS)
throw DxvkError("DxvkGraphicsPipeline::DxvkGraphicsPipeline: Failed to compile pipeline");
return pipeline;
}
void DxvkGraphicsPipeline::destroyObjects() {
if (m_pipelineLayout != VK_NULL_HANDLE)
m_vkd->vkDestroyPipelineLayout(m_vkd->device(), m_pipelineLayout, nullptr);
if (m_descriptorSetLayout != VK_NULL_HANDLE)
m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_descriptorSetLayout, nullptr);
} }
} }

View File

@ -84,6 +84,8 @@ namespace dxvk {
VkPipeline compilePipeline( VkPipeline compilePipeline(
const DxvkGraphicsPipelineStateInfo& state) const; const DxvkGraphicsPipelineStateInfo& state) const;
void destroyObjects();
}; };
} }

View File

@ -3,16 +3,44 @@
namespace dxvk { namespace dxvk {
DxvkShader::DxvkShader( DxvkShader::DxvkShader(
const Rc<vk::DeviceFn>& vkd,
VkShaderStageFlagBits stage, VkShaderStageFlagBits stage,
SpirvCodeBuffer&& code) const SpirvCodeBuffer& code)
: m_stage (stage), : m_vkd(vkd), m_stage(stage) {
m_code (std::move(code)) {
TRACE(this, stage); TRACE(this, stage);
VkShaderModuleCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
info.pNext = nullptr;
info.flags = 0;
info.codeSize = code.size();
info.pCode = code.data();
if (m_vkd->vkCreateShaderModule(m_vkd->device(),
&info, nullptr, &m_module) != VK_SUCCESS)
throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create shader module");
} }
DxvkShader::~DxvkShader() { DxvkShader::~DxvkShader() {
TRACE(this); TRACE(this);
m_vkd->vkDestroyShaderModule(
m_vkd->device(), m_module, nullptr);
}
VkPipelineShaderStageCreateInfo DxvkShader::stageInfo() const {
VkPipelineShaderStageCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
info.pNext = nullptr;
info.flags = 0;
info.stage = m_stage;
info.module = m_module;
info.pName = "main";
info.pSpecializationInfo = nullptr;
return info;
} }
} }

View File

@ -38,22 +38,22 @@ namespace dxvk {
public: public:
DxvkShader( DxvkShader(
const Rc<vk::DeviceFn>& vkd,
VkShaderStageFlagBits stage, VkShaderStageFlagBits stage,
SpirvCodeBuffer&& code); const SpirvCodeBuffer& code);
~DxvkShader(); ~DxvkShader();
/** VkShaderModule module() const {
* \brief Retrieves shader code return m_module;
* \returns Shader code buffer
*/
const SpirvCodeBuffer& code() const {
return m_code;
} }
VkPipelineShaderStageCreateInfo stageInfo() const;
private: private:
Rc<vk::DeviceFn> m_vkd;
VkShaderStageFlagBits m_stage; VkShaderStageFlagBits m_stage;
SpirvCodeBuffer m_code; VkShaderModule m_module;
}; };

View File

@ -37,7 +37,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
DxbcModule module(reader); DxbcModule module(reader);
auto shader = module.compile(); auto shader = module.compile();
shader->code().store(std::ofstream( shader.store(std::ofstream(
str::fromws(argv[2]), std::ios::binary)); str::fromws(argv[2]), std::ios::binary));
return 0; return 0;
} catch (const DxvkError& e) { } catch (const DxvkError& e) {