2017-12-07 10:12:48 +01:00
|
|
|
#include "d3d11_device.h"
|
2017-12-06 14:16:14 +01:00
|
|
|
#include "d3d11_shader.h"
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
2017-12-06 18:54:01 +01:00
|
|
|
D3D11ShaderModule:: D3D11ShaderModule() { }
|
|
|
|
D3D11ShaderModule::~D3D11ShaderModule() { }
|
|
|
|
|
|
|
|
|
|
|
|
D3D11ShaderModule::D3D11ShaderModule(
|
2018-01-07 20:05:27 +01:00
|
|
|
const DxbcOptions* pDxbcOptions,
|
2017-12-07 10:12:48 +01:00
|
|
|
D3D11Device* pDevice,
|
|
|
|
const void* pShaderBytecode,
|
|
|
|
size_t BytecodeLength) {
|
2017-12-06 18:54:01 +01:00
|
|
|
DxbcReader reader(
|
|
|
|
reinterpret_cast<const char*>(pShaderBytecode),
|
|
|
|
BytecodeLength);
|
|
|
|
|
|
|
|
DxbcModule module(reader);
|
|
|
|
|
2018-01-12 00:06:54 +01:00
|
|
|
// Construct the shader name that we'll use for
|
|
|
|
// debug messages and as the dump/read file name
|
|
|
|
m_name = ConstructFileName(
|
|
|
|
ComputeShaderHash(pShaderBytecode, BytecodeLength),
|
|
|
|
module.version().type());
|
|
|
|
|
|
|
|
Logger::debug(str::format("Compiling shader ", m_name));
|
|
|
|
|
2017-12-06 18:54:01 +01:00
|
|
|
// If requested by the user, dump both the raw DXBC
|
|
|
|
// shader and the compiled SPIR-V module to a file.
|
2018-01-12 00:06:54 +01:00
|
|
|
const std::string dumpPath = env::getEnvVar(L"DXVK_SHADER_DUMP_PATH");
|
|
|
|
const std::string readPath = env::getEnvVar(L"DXVK_SHADER_READ_PATH");
|
2017-12-06 18:54:01 +01:00
|
|
|
|
|
|
|
if (dumpPath.size() != 0) {
|
2018-01-12 00:06:54 +01:00
|
|
|
reader.store(std::ofstream(str::format(dumpPath, "/", m_name, ".dxbc"),
|
2017-12-06 18:54:01 +01:00
|
|
|
std::ios_base::binary | std::ios_base::trunc));
|
2017-12-18 16:41:05 +01:00
|
|
|
}
|
|
|
|
|
2018-01-07 20:05:27 +01:00
|
|
|
m_shader = module.compile(*pDxbcOptions);
|
2017-12-18 16:41:05 +01:00
|
|
|
|
|
|
|
if (dumpPath.size() != 0) {
|
2018-01-12 00:06:54 +01:00
|
|
|
m_shader->dump(std::ofstream(str::format(dumpPath, "/", m_name, ".spv"),
|
2017-12-06 18:54:01 +01:00
|
|
|
std::ios_base::binary | std::ios_base::trunc));
|
|
|
|
}
|
2017-12-10 12:21:33 +01:00
|
|
|
|
|
|
|
// If requested by the user, replace
|
|
|
|
// the shader with another file.
|
|
|
|
if (readPath.size() != 0) {
|
|
|
|
m_shader->read(std::ifstream(
|
2018-01-12 00:06:54 +01:00
|
|
|
str::format(readPath, "/", m_name, ".spv"),
|
2017-12-10 12:21:33 +01:00
|
|
|
std::ios_base::binary));
|
|
|
|
}
|
2017-12-06 18:54:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Sha1Hash D3D11ShaderModule::ComputeShaderHash(
|
|
|
|
const void* pShaderBytecode,
|
|
|
|
size_t BytecodeLength) const {
|
|
|
|
return Sha1Hash::compute(
|
|
|
|
reinterpret_cast<const uint8_t*>(pShaderBytecode),
|
|
|
|
BytecodeLength);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string D3D11ShaderModule::ConstructFileName(
|
|
|
|
const Sha1Hash& hash,
|
|
|
|
const DxbcProgramType& type) const {
|
|
|
|
std::string typeStr;
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case DxbcProgramType::PixelShader: typeStr = "PS_"; break;
|
|
|
|
case DxbcProgramType::VertexShader: typeStr = "VS_"; break;
|
|
|
|
case DxbcProgramType::GeometryShader: typeStr = "GS_"; break;
|
|
|
|
case DxbcProgramType::HullShader: typeStr = "HS_"; break;
|
|
|
|
case DxbcProgramType::DomainShader: typeStr = "DS_"; break;
|
|
|
|
case DxbcProgramType::ComputeShader: typeStr = "CS_"; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return str::format(typeStr, hash.toString());
|
|
|
|
}
|
|
|
|
|
2017-12-06 14:16:14 +01:00
|
|
|
}
|