mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 11:52:12 +01:00
[dxbc] Refactored shader compiler to return a DxvkShader
This commit is contained in:
parent
a2f66025f8
commit
e872448ca3
@ -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.
|
||||
|
||||
- `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.
|
||||
|
||||
## Samples and executables
|
||||
|
@ -17,16 +17,12 @@ namespace dxvk {
|
||||
BytecodeLength);
|
||||
|
||||
DxbcModule module(reader);
|
||||
|
||||
SpirvCodeBuffer spirvCode = module.compile();
|
||||
|
||||
// TODO pre-process shader bindings
|
||||
std::vector<DxvkResourceSlot> resourceSlots;
|
||||
m_shader = module.compile();
|
||||
|
||||
// If requested by the user, dump both the raw DXBC
|
||||
// shader and the compiled SPIR-V module to a file.
|
||||
const std::string dumpPath = env::getEnvVar(L"DXVK_SHADER_DUMP_PATH");
|
||||
const std::string readPath = env::getEnvVar(L"DXVK_SHADER_READ_PATH");
|
||||
const std::string dumpPath
|
||||
= env::getEnvVar(L"DXVK_SHADER_DUMP_PATH");
|
||||
|
||||
if (dumpPath.size() != 0) {
|
||||
const std::string baseName = str::format(dumpPath, "/",
|
||||
@ -36,25 +32,9 @@ namespace dxvk {
|
||||
reader.store(std::ofstream(str::format(baseName, ".dxbc"),
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,7 +64,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
SpirvCodeBuffer DxbcCompiler::finalize() {
|
||||
Rc<DxvkShader> DxbcCompiler::finalize() {
|
||||
return m_gen->finalize();
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ namespace dxvk {
|
||||
void processInstruction(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
SpirvCodeBuffer finalize();
|
||||
Rc<DxvkShader> finalize();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -40,7 +40,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
SpirvCodeBuffer DxbcModule::compile() const {
|
||||
Rc<DxvkShader> DxbcModule::compile() const {
|
||||
if (m_shexChunk == nullptr)
|
||||
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
|
||||
|
||||
@ -50,6 +50,7 @@ namespace dxvk {
|
||||
|
||||
for (auto ins : *m_shexChunk)
|
||||
compiler.processInstruction(ins);
|
||||
|
||||
return compiler.finalize();
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,9 @@ namespace dxvk {
|
||||
|
||||
/**
|
||||
* \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:
|
||||
|
||||
|
@ -135,7 +135,7 @@ namespace dxvk {
|
||||
uint32_t regId,
|
||||
const DxbcValue& index) = 0;
|
||||
|
||||
virtual SpirvCodeBuffer finalize() = 0;
|
||||
virtual Rc<DxvkShader> finalize() = 0;
|
||||
|
||||
static Rc<DxbcCodeGen> create(
|
||||
const DxbcProgramVersion& version,
|
||||
|
@ -141,7 +141,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
SpirvCodeBuffer DxbcPsCodeGen::finalize() {
|
||||
Rc<DxvkShader> DxbcPsCodeGen::finalize() {
|
||||
m_module.functionBegin(
|
||||
m_module.defVoidType(),
|
||||
m_entryPointId,
|
||||
@ -166,7 +166,10 @@ namespace dxvk {
|
||||
m_module.setOriginUpperLeft(m_entryPointId);
|
||||
m_module.setDebugName(m_entryPointId, "main");
|
||||
|
||||
return m_module.compile();
|
||||
return new DxvkShader(
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0, nullptr,
|
||||
m_module.compile());
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace dxvk {
|
||||
uint32_t regId,
|
||||
const DxbcValue& index);
|
||||
|
||||
SpirvCodeBuffer finalize() final;
|
||||
Rc<DxvkShader> finalize() final;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -108,7 +108,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
SpirvCodeBuffer DxbcVsCodeGen::finalize() {
|
||||
Rc<DxvkShader> DxbcVsCodeGen::finalize() {
|
||||
m_module.functionBegin(
|
||||
m_module.defVoidType(),
|
||||
m_entryPointId,
|
||||
@ -132,7 +132,10 @@ namespace dxvk {
|
||||
m_entryPointInterfaces.data());
|
||||
m_module.setDebugName(m_entryPointId, "main");
|
||||
|
||||
return m_module.compile();
|
||||
return new DxvkShader(
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, nullptr,
|
||||
m_module.compile());
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace dxvk {
|
||||
uint32_t regId,
|
||||
const DxbcValue& index);
|
||||
|
||||
SpirvCodeBuffer finalize() final;
|
||||
Rc<DxvkShader> finalize() final;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -13,7 +13,7 @@ namespace dxvk {
|
||||
slotMapping.bindingCount(),
|
||||
slotMapping.bindingInfos());
|
||||
|
||||
m_cs = cs->createShaderModule(slotMapping);
|
||||
m_cs = cs->createShaderModule(vkd, slotMapping);
|
||||
|
||||
this->compilePipeline();
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ namespace dxvk {
|
||||
uint32_t slotCount,
|
||||
const DxvkResourceSlot* slotInfos,
|
||||
const SpirvCodeBuffer& code) {
|
||||
return new DxvkShader(m_vkd, stage,
|
||||
return new DxvkShader(stage,
|
||||
slotCount, slotInfos, code);
|
||||
}
|
||||
|
||||
|
@ -55,11 +55,11 @@ namespace dxvk {
|
||||
slotMapping.bindingCount(),
|
||||
slotMapping.bindingInfos());
|
||||
|
||||
if (vs != nullptr) m_vs = vs ->createShaderModule(slotMapping);
|
||||
if (tcs != nullptr) m_tcs = tcs->createShaderModule(slotMapping);
|
||||
if (tes != nullptr) m_tes = tes->createShaderModule(slotMapping);
|
||||
if (gs != nullptr) m_gs = gs ->createShaderModule(slotMapping);
|
||||
if (fs != nullptr) m_fs = fs ->createShaderModule(slotMapping);
|
||||
if (vs != nullptr) m_vs = vs ->createShaderModule(vkd, slotMapping);
|
||||
if (tcs != nullptr) m_tcs = tcs->createShaderModule(vkd, slotMapping);
|
||||
if (tes != nullptr) m_tes = tes->createShaderModule(vkd, slotMapping);
|
||||
if (gs != nullptr) m_gs = gs ->createShaderModule(vkd, slotMapping);
|
||||
if (fs != nullptr) m_fs = fs ->createShaderModule(vkd, slotMapping);
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,12 +41,11 @@ namespace dxvk {
|
||||
|
||||
|
||||
DxvkShader::DxvkShader(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
VkShaderStageFlagBits stage,
|
||||
uint32_t slotCount,
|
||||
const DxvkResourceSlot* slotInfos,
|
||||
const SpirvCodeBuffer& code)
|
||||
: m_vkd(vkd), m_stage(stage), m_code(code) {
|
||||
VkShaderStageFlagBits stage,
|
||||
uint32_t slotCount,
|
||||
const DxvkResourceSlot* slotInfos,
|
||||
const SpirvCodeBuffer& code)
|
||||
: m_stage(stage), m_code(code) {
|
||||
for (uint32_t i = 0; i < slotCount; i++)
|
||||
m_slots.push_back(slotInfos[i]);
|
||||
}
|
||||
@ -65,9 +64,15 @@ namespace dxvk {
|
||||
|
||||
|
||||
Rc<DxvkShaderModule> DxvkShader::createShaderModule(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
const DxvkDescriptorSlotMapping& mapping) const {
|
||||
// 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));
|
||||
}
|
||||
|
||||
}
|
@ -68,15 +68,19 @@ namespace dxvk {
|
||||
public:
|
||||
|
||||
DxvkShader(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
VkShaderStageFlagBits stage,
|
||||
uint32_t slotCount,
|
||||
const DxvkResourceSlot* slotInfos,
|
||||
const SpirvCodeBuffer& code);
|
||||
|
||||
~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(
|
||||
DxvkDescriptorSlotMapping& mapping) const;
|
||||
@ -85,15 +89,24 @@ namespace dxvk {
|
||||
* \brief Creates a shader module
|
||||
*
|
||||
* Maps the binding slot numbers
|
||||
* \param [in] vkd Vulkan device functions
|
||||
* \param [in] mapping Resource slot mapping
|
||||
* \returns The shader module
|
||||
*/
|
||||
Rc<DxvkShaderModule> createShaderModule(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
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:
|
||||
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
VkShaderStageFlagBits m_stage;
|
||||
SpirvCodeBuffer m_code;
|
||||
|
||||
|
@ -40,8 +40,8 @@ int WINAPI WinMain(HINSTANCE hInstance,
|
||||
DxbcReader reader(dxbcCode.data(), dxbcCode.size());
|
||||
DxbcModule module(reader);
|
||||
|
||||
auto shader = module.compile();
|
||||
shader.store(std::ofstream(
|
||||
Rc<DxvkShader> shader = module.compile();
|
||||
shader->dump(std::ofstream(
|
||||
str::fromws(argv[2]), std::ios::binary));
|
||||
return 0;
|
||||
} catch (const DxvkError& e) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user