1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[dxbc] Refactored shader compiler to return a DxvkShader

This commit is contained in:
Philip Rebohle 2017-12-08 18:14:05 +01:00
parent a2f66025f8
commit e872448ca3
17 changed files with 60 additions and 56 deletions

View File

@ -35,7 +35,6 @@ DXVK will create a file `dxgi.log` in the current working directory and may prin
The behaviour of DXVK can be modified with environment variables. The behaviour of DXVK can be modified with environment variables.
- `DXVK_SHADER_DUMP_PATH=directory` Writes all DXBC and SPIR-V shaders to the given directory - `DXVK_SHADER_DUMP_PATH=directory` Writes all DXBC and SPIR-V shaders to the given directory
- `DXVK_SHADER_READS_PATH=directory` Reads SPIR-V shaders from the given directory instead of compiling the DXBC shader.
- `DXVK_DEBUG_LAYERS=1` Enables Vulkan debug layers. Highly recommended for troubleshooting and debugging purposes. - `DXVK_DEBUG_LAYERS=1` Enables Vulkan debug layers. Highly recommended for troubleshooting and debugging purposes.
## Samples and executables ## Samples and executables

View File

@ -17,16 +17,12 @@ namespace dxvk {
BytecodeLength); BytecodeLength);
DxbcModule module(reader); DxbcModule module(reader);
m_shader = module.compile();
SpirvCodeBuffer spirvCode = module.compile();
// TODO pre-process shader bindings
std::vector<DxvkResourceSlot> resourceSlots;
// If requested by the user, dump both the raw DXBC // If requested by the user, dump both the raw DXBC
// shader and the compiled SPIR-V module to a file. // shader and the compiled SPIR-V module to a file.
const std::string dumpPath = env::getEnvVar(L"DXVK_SHADER_DUMP_PATH"); const std::string dumpPath
const std::string readPath = env::getEnvVar(L"DXVK_SHADER_READ_PATH"); = env::getEnvVar(L"DXVK_SHADER_DUMP_PATH");
if (dumpPath.size() != 0) { if (dumpPath.size() != 0) {
const std::string baseName = str::format(dumpPath, "/", const std::string baseName = str::format(dumpPath, "/",
@ -36,25 +32,9 @@ namespace dxvk {
reader.store(std::ofstream(str::format(baseName, ".dxbc"), reader.store(std::ofstream(str::format(baseName, ".dxbc"),
std::ios_base::binary | std::ios_base::trunc)); std::ios_base::binary | std::ios_base::trunc));
spirvCode.store(std::ofstream(str::format(baseName, ".spv"), m_shader->dump(std::ofstream(str::format(baseName, ".spv"),
std::ios_base::binary | std::ios_base::trunc)); std::ios_base::binary | std::ios_base::trunc));
} }
if (readPath.size() != 0) {
const std::string baseName = str::format(readPath, "/",
ConstructFileName(ComputeShaderHash(pShaderBytecode, BytecodeLength),
module.version().type()));
spirvCode = SpirvCodeBuffer(std::ifstream(
str::format(baseName, ".spv"),
std::ios_base::binary));
}
m_shader = pDevice->GetDXVKDevice()->createShader(
module.version().shaderStage(),
resourceSlots.size(),
resourceSlots.data(),
spirvCode);
} }

View File

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

View File

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

View File

@ -40,7 +40,7 @@ namespace dxvk {
} }
SpirvCodeBuffer DxbcModule::compile() const { Rc<DxvkShader> 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");
@ -50,6 +50,7 @@ namespace dxvk {
for (auto ins : *m_shexChunk) for (auto ins : *m_shexChunk)
compiler.processInstruction(ins); compiler.processInstruction(ins);
return compiler.finalize(); return compiler.finalize();
} }

View File

@ -46,9 +46,9 @@ 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 shader object
*/ */
SpirvCodeBuffer compile() const; Rc<DxvkShader> compile() const;
private: private:

View File

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

View File

@ -141,7 +141,7 @@ namespace dxvk {
} }
SpirvCodeBuffer DxbcPsCodeGen::finalize() { Rc<DxvkShader> DxbcPsCodeGen::finalize() {
m_module.functionBegin( m_module.functionBegin(
m_module.defVoidType(), m_module.defVoidType(),
m_entryPointId, m_entryPointId,
@ -166,7 +166,10 @@ namespace dxvk {
m_module.setOriginUpperLeft(m_entryPointId); m_module.setOriginUpperLeft(m_entryPointId);
m_module.setDebugName(m_entryPointId, "main"); m_module.setDebugName(m_entryPointId, "main");
return m_module.compile(); return new DxvkShader(
VK_SHADER_STAGE_FRAGMENT_BIT,
0, nullptr,
m_module.compile());
} }

View File

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

View File

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

View File

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

View File

@ -13,7 +13,7 @@ namespace dxvk {
slotMapping.bindingCount(), slotMapping.bindingCount(),
slotMapping.bindingInfos()); slotMapping.bindingInfos());
m_cs = cs->createShaderModule(slotMapping); m_cs = cs->createShaderModule(vkd, slotMapping);
this->compilePipeline(); this->compilePipeline();
} }

View File

@ -97,7 +97,7 @@ namespace dxvk {
uint32_t slotCount, uint32_t slotCount,
const DxvkResourceSlot* slotInfos, const DxvkResourceSlot* slotInfos,
const SpirvCodeBuffer& code) { const SpirvCodeBuffer& code) {
return new DxvkShader(m_vkd, stage, return new DxvkShader(stage,
slotCount, slotInfos, code); slotCount, slotInfos, code);
} }

View File

@ -55,11 +55,11 @@ namespace dxvk {
slotMapping.bindingCount(), slotMapping.bindingCount(),
slotMapping.bindingInfos()); slotMapping.bindingInfos());
if (vs != nullptr) m_vs = vs ->createShaderModule(slotMapping); if (vs != nullptr) m_vs = vs ->createShaderModule(vkd, slotMapping);
if (tcs != nullptr) m_tcs = tcs->createShaderModule(slotMapping); if (tcs != nullptr) m_tcs = tcs->createShaderModule(vkd, slotMapping);
if (tes != nullptr) m_tes = tes->createShaderModule(slotMapping); if (tes != nullptr) m_tes = tes->createShaderModule(vkd, slotMapping);
if (gs != nullptr) m_gs = gs ->createShaderModule(slotMapping); if (gs != nullptr) m_gs = gs ->createShaderModule(vkd, slotMapping);
if (fs != nullptr) m_fs = fs ->createShaderModule(slotMapping); if (fs != nullptr) m_fs = fs ->createShaderModule(vkd, slotMapping);
} }

View File

@ -41,12 +41,11 @@ namespace dxvk {
DxvkShader::DxvkShader( DxvkShader::DxvkShader(
const Rc<vk::DeviceFn>& vkd, VkShaderStageFlagBits stage,
VkShaderStageFlagBits stage, uint32_t slotCount,
uint32_t slotCount, const DxvkResourceSlot* slotInfos,
const DxvkResourceSlot* slotInfos, const SpirvCodeBuffer& code)
const SpirvCodeBuffer& code) : m_stage(stage), m_code(code) {
: m_vkd(vkd), m_stage(stage), m_code(code) {
for (uint32_t i = 0; i < slotCount; i++) for (uint32_t i = 0; i < slotCount; i++)
m_slots.push_back(slotInfos[i]); m_slots.push_back(slotInfos[i]);
} }
@ -65,9 +64,15 @@ namespace dxvk {
Rc<DxvkShaderModule> DxvkShader::createShaderModule( Rc<DxvkShaderModule> DxvkShader::createShaderModule(
const Rc<vk::DeviceFn>& vkd,
const DxvkDescriptorSlotMapping& mapping) const { const DxvkDescriptorSlotMapping& mapping) const {
// TODO apply mapping // TODO apply mapping
return new DxvkShaderModule(m_vkd, m_stage, m_code); return new DxvkShaderModule(vkd, m_stage, m_code);
}
void DxvkShader::dump(std::ostream&& outputStream) const {
m_code.store(std::move(outputStream));
} }
} }

View File

@ -68,15 +68,19 @@ namespace dxvk {
public: public:
DxvkShader( DxvkShader(
const Rc<vk::DeviceFn>& vkd,
VkShaderStageFlagBits stage, VkShaderStageFlagBits stage,
uint32_t slotCount, uint32_t slotCount,
const DxvkResourceSlot* slotInfos, const DxvkResourceSlot* slotInfos,
const SpirvCodeBuffer& code); const SpirvCodeBuffer& code);
~DxvkShader(); ~DxvkShader();
/** /**
* \brief * \brief Adds resource slots definitions to a mapping
*
* Used to generate the exact descriptor set layout when
* compiling a graphics or compute pipeline. Slot indices
* have to be mapped to actual binding numbers.
*/ */
void defineResourceSlots( void defineResourceSlots(
DxvkDescriptorSlotMapping& mapping) const; DxvkDescriptorSlotMapping& mapping) const;
@ -85,15 +89,24 @@ namespace dxvk {
* \brief Creates a shader module * \brief Creates a shader module
* *
* Maps the binding slot numbers * Maps the binding slot numbers
* \param [in] vkd Vulkan device functions
* \param [in] mapping Resource slot mapping * \param [in] mapping Resource slot mapping
* \returns The shader module * \returns The shader module
*/ */
Rc<DxvkShaderModule> createShaderModule( Rc<DxvkShaderModule> createShaderModule(
const Rc<vk::DeviceFn>& vkd,
const DxvkDescriptorSlotMapping& mapping) const; const DxvkDescriptorSlotMapping& mapping) const;
/**
* \brief Dumps SPIR-V shader
*
* Can be used to store the SPIR-V code in a file.
* \param [in] outputStream Stream to write to
*/
void dump(std::ostream&& outputStream) const;
private: private:
Rc<vk::DeviceFn> m_vkd;
VkShaderStageFlagBits m_stage; VkShaderStageFlagBits m_stage;
SpirvCodeBuffer m_code; SpirvCodeBuffer m_code;

View File

@ -40,8 +40,8 @@ int WINAPI WinMain(HINSTANCE hInstance,
DxbcReader reader(dxbcCode.data(), dxbcCode.size()); DxbcReader reader(dxbcCode.data(), dxbcCode.size());
DxbcModule module(reader); DxbcModule module(reader);
auto shader = module.compile(); Rc<DxvkShader> shader = module.compile();
shader.store(std::ofstream( shader->dump(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) {