Родитель
e725a6399f
Коммит
c45f09a6d8
|
@ -100,6 +100,38 @@ namespace ShaderConductor
|
|||
class SC_API Compiler
|
||||
{
|
||||
public:
|
||||
struct ShaderModel
|
||||
{
|
||||
uint8_t major_ver : 6;
|
||||
uint8_t minor_ver : 2;
|
||||
|
||||
uint32_t FullVersion() const noexcept
|
||||
{
|
||||
return (major_ver << 2) | minor_ver;
|
||||
}
|
||||
|
||||
bool operator<(const ShaderModel& other) const noexcept
|
||||
{
|
||||
return this->FullVersion() < other.FullVersion();
|
||||
}
|
||||
bool operator==(const ShaderModel& other) const noexcept
|
||||
{
|
||||
return this->FullVersion() == other.FullVersion();
|
||||
}
|
||||
bool operator>(const ShaderModel& other) const noexcept
|
||||
{
|
||||
return other < *this;
|
||||
}
|
||||
bool operator<=(const ShaderModel& other) const noexcept
|
||||
{
|
||||
return (*this < other) || (*this == other);
|
||||
}
|
||||
bool operator>=(const ShaderModel& other) const noexcept
|
||||
{
|
||||
return (*this > other) || (*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
struct SourceDesc
|
||||
{
|
||||
const char* source;
|
||||
|
@ -111,6 +143,17 @@ namespace ShaderConductor
|
|||
std::function<Blob*(const char* includeName)> loadIncludeCallback;
|
||||
};
|
||||
|
||||
struct Options
|
||||
{
|
||||
bool packMatricesInRowMajor = true; // Experimental: Decide how a matrix get packed
|
||||
bool enable16bitTypes = false; // Enable 16-bit types, such as half, uint16_t. Requires shader model 6.2+
|
||||
bool enableDebugInfo = false; // Embed debug info into the binary
|
||||
bool disableOptimizations = false; // Force to turn off optimizations. Ignore optimizationLevel below.
|
||||
|
||||
int optimizationLevel = 3; // 0 to 3, no optimization to most optimization
|
||||
ShaderModel shaderModel = { 6, 0 };
|
||||
};
|
||||
|
||||
struct TargetDesc
|
||||
{
|
||||
ShadingLanguage language;
|
||||
|
@ -134,7 +177,7 @@ namespace ShaderConductor
|
|||
};
|
||||
|
||||
public:
|
||||
static ResultDesc Compile(const SourceDesc& source, const TargetDesc& target);
|
||||
static ResultDesc Compile(const SourceDesc& source, const Options& options, const TargetDesc& target);
|
||||
static ResultDesc Disassemble(const DisassembleDesc& source);
|
||||
};
|
||||
} // namespace ShaderConductor
|
||||
|
|
|
@ -308,7 +308,8 @@ namespace
|
|||
result.hasError = true;
|
||||
}
|
||||
|
||||
Compiler::ResultDesc CompileToBinary(const Compiler::SourceDesc& source, ShadingLanguage targetLanguage)
|
||||
Compiler::ResultDesc CompileToBinary(const Compiler::SourceDesc& source, const Compiler::Options& options,
|
||||
ShadingLanguage targetLanguage)
|
||||
{
|
||||
assert((targetLanguage == ShadingLanguage::Dxil) || (targetLanguage == ShadingLanguage::SpirV));
|
||||
|
||||
|
@ -342,7 +343,10 @@ namespace
|
|||
default:
|
||||
llvm_unreachable("Invalid shader stage.");
|
||||
}
|
||||
shaderProfile += L"_6_0";
|
||||
shaderProfile.push_back(L'_');
|
||||
shaderProfile.push_back(L'0' + options.shaderModel.major_ver);
|
||||
shaderProfile.push_back(L'_');
|
||||
shaderProfile.push_back(L'0' + options.shaderModel.minor_ver);
|
||||
|
||||
std::vector<DxcDefine> dxcDefines;
|
||||
std::vector<std::wstring> dxcDefineStrings;
|
||||
|
@ -386,6 +390,51 @@ namespace
|
|||
Unicode::UTF8ToUTF16String(source.entryPoint, &entryPointUtf16);
|
||||
|
||||
std::vector<std::wstring> dxcArgStrings;
|
||||
|
||||
// HLSL matrices are translated into SPIR-V OpTypeMatrixs in a transposed manner,
|
||||
// See also https://antiagainst.github.io/post/hlsl-for-vulkan-matrices/
|
||||
if (options.packMatricesInRowMajor)
|
||||
{
|
||||
dxcArgStrings.push_back(L"-Zpc");
|
||||
}
|
||||
else
|
||||
{
|
||||
dxcArgStrings.push_back(L"-Zpr");
|
||||
}
|
||||
|
||||
if (options.enable16bitTypes)
|
||||
{
|
||||
if (options.shaderModel >= Compiler::ShaderModel{ 6, 2 })
|
||||
{
|
||||
dxcArgStrings.push_back(L"-enable-16bit-types");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("16-bit types requires shader model 6.2 or up.");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.enableDebugInfo)
|
||||
{
|
||||
dxcArgStrings.push_back(L"-Zi");
|
||||
}
|
||||
|
||||
if (options.disableOptimizations)
|
||||
{
|
||||
dxcArgStrings.push_back(L"-Od");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (options.optimizationLevel < 4)
|
||||
{
|
||||
dxcArgStrings.push_back(std::wstring(L"-O") + static_cast<wchar_t>(L'0' + options.optimizationLevel));
|
||||
}
|
||||
else
|
||||
{
|
||||
llvm_unreachable("Invalid optimization level.");
|
||||
}
|
||||
}
|
||||
|
||||
switch (targetLanguage)
|
||||
{
|
||||
case ShadingLanguage::Dxil:
|
||||
|
@ -672,7 +721,7 @@ namespace ShaderConductor
|
|||
delete blob;
|
||||
}
|
||||
|
||||
Compiler::ResultDesc Compiler::Compile(const SourceDesc& source, const TargetDesc& target)
|
||||
Compiler::ResultDesc Compiler::Compile(const SourceDesc& source, const Options& options, const TargetDesc& target)
|
||||
{
|
||||
SourceDesc sourceOverride = source;
|
||||
if (!sourceOverride.entryPoint || (strlen(sourceOverride.entryPoint) == 0))
|
||||
|
@ -685,7 +734,7 @@ namespace ShaderConductor
|
|||
}
|
||||
|
||||
const auto binaryLanguage = target.language == ShadingLanguage::Dxil ? ShadingLanguage::Dxil : ShadingLanguage::SpirV;
|
||||
auto ret = CompileToBinary(sourceOverride, binaryLanguage);
|
||||
auto ret = CompileToBinary(sourceOverride, options, binaryLanguage);
|
||||
|
||||
if (!ret.hasError && (target.language != binaryLanguage))
|
||||
{
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#version 300
|
||||
#extension GL_ARB_separate_shader_objects : require
|
||||
|
||||
out gl_PerVertex
|
||||
{
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
layout(std140) uniform type_cbVS
|
||||
{
|
||||
mat4 wvp;
|
||||
} cbVS;
|
||||
|
||||
in vec4 in_var_POSITION;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = cbVS.wvp * in_var_POSITION;
|
||||
}
|
||||
|
|
@ -91,13 +91,14 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
void HlslToAnyTest(const std::string& name, const Compiler::SourceDesc& source, const Compiler::TargetDesc& target, bool expectSuccess)
|
||||
void HlslToAnyTest(const std::string& name, const Compiler::SourceDesc& source, const Compiler::Options& options,
|
||||
const Compiler::TargetDesc& target, bool expectSuccess)
|
||||
{
|
||||
static const std::string extMap[] = { "dxil", "spv", "hlsl", "glsl", "essl", "msl" };
|
||||
static_assert(sizeof(extMap) / sizeof(extMap[0]) == static_cast<uint32_t>(ShadingLanguage::NumShadingLanguages),
|
||||
"extMap doesn't match with the number of shading languages.");
|
||||
|
||||
const auto result = Compiler::Compile(source, target);
|
||||
const auto result = Compiler::Compile(source, options, target);
|
||||
|
||||
if (expectSuccess)
|
||||
{
|
||||
|
@ -145,7 +146,7 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
void RunTests(ShadingLanguage targetSl)
|
||||
void RunTests(ShadingLanguage targetSl, const Compiler::Options& options = {})
|
||||
{
|
||||
for (const auto& combination : m_combinations)
|
||||
{
|
||||
|
@ -153,7 +154,8 @@ namespace
|
|||
{
|
||||
if (std::get<1>(target).language == targetSl)
|
||||
{
|
||||
HlslToAnyTest(std::get<0>(combination), std::get<1>(combination), std::get<1>(target), std::get<0>(target));
|
||||
HlslToAnyTest(std::get<0>(combination), std::get<1>(combination), options, std::get<1>(target),
|
||||
std::get<0>(target));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -404,6 +406,21 @@ namespace
|
|||
RunTests(ShadingLanguage::Glsl);
|
||||
}
|
||||
|
||||
TEST_F(VertexShaderTest, ToGlslColumnMajor)
|
||||
{
|
||||
const std::string fileName = TEST_DATA_DIR "Input/Transform_VS.hlsl";
|
||||
|
||||
std::vector<uint8_t> input = LoadFile(fileName, true);
|
||||
TrimTailingZeros(&input);
|
||||
const std::string source = std::string(reinterpret_cast<char*>(input.data()), input.size());
|
||||
|
||||
Compiler::Options options;
|
||||
options.packMatricesInRowMajor = false;
|
||||
|
||||
HlslToAnyTest("Transform_VS_ColumnMajor", { source.c_str(), fileName.c_str(), nullptr, ShaderStage::VertexShader }, options,
|
||||
{ ShadingLanguage::Glsl, "300" }, true);
|
||||
}
|
||||
|
||||
TEST_F(VertexShaderTest, ToEssl)
|
||||
{
|
||||
RunTests(ShadingLanguage::Essl);
|
||||
|
@ -528,7 +545,7 @@ namespace
|
|||
const std::string source = std::string(reinterpret_cast<char*>(input.data()), input.size());
|
||||
|
||||
const auto result =
|
||||
Compiler::Compile({ source.c_str(), fileName.c_str(), "main", ShaderStage::PixelShader }, { ShadingLanguage::Glsl, "30" });
|
||||
Compiler::Compile({ source.c_str(), fileName.c_str(), "main", ShaderStage::PixelShader }, {}, { ShadingLanguage::Glsl, "30" });
|
||||
|
||||
EXPECT_FALSE(result.hasError);
|
||||
EXPECT_EQ(result.errorWarningMsg, nullptr);
|
||||
|
@ -550,7 +567,7 @@ namespace
|
|||
const std::string source = std::string(reinterpret_cast<char*>(input.data()), input.size());
|
||||
|
||||
const auto result =
|
||||
Compiler::Compile({ source.c_str(), fileName.c_str(), "main", ShaderStage::PixelShader }, { ShadingLanguage::Glsl, "30" });
|
||||
Compiler::Compile({ source.c_str(), fileName.c_str(), "main", ShaderStage::PixelShader }, {}, { ShadingLanguage::Glsl, "30" });
|
||||
|
||||
EXPECT_TRUE(result.hasError);
|
||||
const char* errorStr = reinterpret_cast<const char*>(result.errorWarningMsg->Data());
|
||||
|
@ -569,7 +586,7 @@ namespace
|
|||
const std::string source = std::string(reinterpret_cast<char*>(input.data()), input.size());
|
||||
|
||||
const auto result =
|
||||
Compiler::Compile({ source.c_str(), fileName.c_str(), "main", ShaderStage::PixelShader }, { ShadingLanguage::Glsl, "30" });
|
||||
Compiler::Compile({ source.c_str(), fileName.c_str(), "main", ShaderStage::PixelShader }, {}, { ShadingLanguage::Glsl, "30" });
|
||||
|
||||
EXPECT_FALSE(result.hasError);
|
||||
EXPECT_EQ(result.errorWarningMsg, nullptr);
|
||||
|
|
|
@ -167,7 +167,7 @@ int main(int argc, char** argv)
|
|||
|
||||
try
|
||||
{
|
||||
const auto result = Compiler::Compile(sourceDesc, targetDesc);
|
||||
const auto result = Compiler::Compile(sourceDesc, {}, targetDesc);
|
||||
|
||||
if (result.errorWarningMsg != nullptr)
|
||||
{
|
||||
|
|
|
@ -39,13 +39,15 @@ void Compile(SourceDescription* source, TargetDescription* target, ResultDescrip
|
|||
sourceDesc.defines = nullptr;
|
||||
sourceDesc.numDefines = 0;
|
||||
|
||||
Compiler::Options options;
|
||||
|
||||
Compiler::TargetDesc targetDesc;
|
||||
targetDesc.language = target->shadingLanguage;
|
||||
targetDesc.version = target->version;
|
||||
|
||||
try
|
||||
{
|
||||
const auto translation = Compiler::Compile(sourceDesc, targetDesc);
|
||||
const auto translation = Compiler::Compile(sourceDesc, options, targetDesc);
|
||||
|
||||
if (translation.errorWarningMsg != nullptr)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче