mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-08 16:50:44 +00:00
Match SPIR-V version as much as possible when rebuilding shaders
This commit is contained in:
@@ -241,6 +241,8 @@ Other custom tools can be configured, but for those the command line arguments m
|
||||
* ``{entry_point}`` will be replaced by the entry point name, only when compiling a shader.
|
||||
* ``{glsl_stage4}`` will be replaced by the glsl stage short-hand, one of: vert, tesc, tese, geom, frag, or comp.
|
||||
* ``{hlsl_stage2}`` will be replaced by the hlsl stage short-hand, one of: vs, hs, ds, gs, ps, or cs.
|
||||
* ``{spirv_ver}`` will be replaced by the SPIR-V version in use, e.g. spirv1.2 or spirv1.6.
|
||||
* ``{vulkan_ver}`` will be replaced by the Vulkan-identified SPIR-V version in use, e.g. vulkan1.0 or vulkan1.3. This value may be lossy, and will pick the next *lowest* version that compiles with a given SPIR-V version. E.g. SPIR-V 1.2 was not used by a vulkan version, so will be rounded down to vulkan1.0.
|
||||
|
||||
You must also select the input and output format of the tool, such as HLSL input and SPIR-V output. This will be used to match the tool against a given need at runtime with different types of shaders.
|
||||
|
||||
|
||||
@@ -699,15 +699,15 @@ rdcstr ShaderProcessingTool::DefaultArguments() const
|
||||
else if(tool == KnownShaderTool::spirv_dis || tool == KnownShaderTool::spirv_dis_OpenGL)
|
||||
return "--no-color";
|
||||
else if(tool == KnownShaderTool::glslangValidatorGLSL)
|
||||
return "-g -V -S {glsl_stage4}";
|
||||
return "-g -V -S {glsl_stage4} --target-env {spirv_ver}";
|
||||
else if(tool == KnownShaderTool::glslangValidatorGLSL_OpenGL)
|
||||
return "-g -G -S {glsl_stage4}";
|
||||
return "-g -G -S {glsl_stage4} --target-env {spirv_ver}";
|
||||
else if(tool == KnownShaderTool::glslangValidatorHLSL)
|
||||
return "-D -g -V -S {glsl_stage4} -e {entry_point}";
|
||||
return "-D -g -V -S {glsl_stage4} -e {entry_point} --target-env {spirv_ver}";
|
||||
else if(tool == KnownShaderTool::spirv_as || tool == KnownShaderTool::spirv_as_OpenGL)
|
||||
return "";
|
||||
else if(tool == KnownShaderTool::dxcSPIRV)
|
||||
return "-T {hlsl_stage2}_6_0 -E {entry_point} -spirv";
|
||||
return "-T {hlsl_stage2}_6_0 -E {entry_point} -spirv -fspv-target-env={vulkan_ver}";
|
||||
else if(tool == KnownShaderTool::dxcDXIL)
|
||||
return "-T {hlsl_stage2}_6_0 -E {entry_point}";
|
||||
else if(tool == KnownShaderTool::fxc)
|
||||
|
||||
@@ -113,6 +113,8 @@ struct ShaderProcessingTool
|
||||
:param str source: The source code, preprocessed into a single file.
|
||||
:param str entryPoint: The name of the entry point in the shader to compile.
|
||||
:param renderdoc.ShaderStage stage: The pipeline stage that this shader represents.
|
||||
:param str spirvVer: The version of SPIR-V in use for this shader, or an empty string for defaults.
|
||||
The current version can be obtained from reflection data via the ``@spirver`` compile flag.
|
||||
:param str args: arguments to pass to the tool. The default arguments can be obtained using
|
||||
:meth:`DefaultArguments` which can then be customised as desired. Passing an empty string uses the
|
||||
default arguments.
|
||||
@@ -120,7 +122,7 @@ struct ShaderProcessingTool
|
||||
:rtype: ShaderToolOutput
|
||||
)");
|
||||
ShaderToolOutput CompileShader(QWidget *window, rdcstr source, rdcstr entryPoint,
|
||||
ShaderStage stage, rdcstr args) const;
|
||||
ShaderStage stage, rdcstr spirvVer, rdcstr args) const;
|
||||
|
||||
private:
|
||||
DOCUMENT("Internal function");
|
||||
|
||||
@@ -41,6 +41,22 @@ static QString tmpPath(const QString &filename)
|
||||
return QDir(QDir::tempPath()).absoluteFilePath(filename);
|
||||
}
|
||||
|
||||
QString vulkanVerForSpirVer(QString spirvVer)
|
||||
{
|
||||
if(spirvVer == lit("spirv1.0") || spirvVer == lit("spirv1.1") || spirvVer == lit("spirv1.2"))
|
||||
return lit("vulkan1.0");
|
||||
if(spirvVer == lit("spirv1.3"))
|
||||
return lit("vulkan1.1");
|
||||
if(spirvVer == lit("spirv1.4"))
|
||||
return lit("vulkan1.1spirv1.4");
|
||||
if(spirvVer == lit("spirv1.5"))
|
||||
return lit("vulkan1.2");
|
||||
if(spirvVer == lit("spirv1.6"))
|
||||
return lit("vulkan1.3");
|
||||
else
|
||||
return lit("vulkan1.3");
|
||||
}
|
||||
|
||||
static ShaderToolOutput RunTool(const ShaderProcessingTool &tool, QWidget *window,
|
||||
QString input_file, QString output_file, QStringList &argList)
|
||||
{
|
||||
@@ -243,6 +259,11 @@ ShaderToolOutput ShaderProcessingTool::DisassembleShader(QWidget *window,
|
||||
|
||||
input_file = tmpPath(lit("shader_input"));
|
||||
|
||||
QString spirvVer = lit("spirv1.0");
|
||||
for(const ShaderCompileFlag &flag : shaderDetails->debugInfo.compileFlags.flags)
|
||||
if(flag.name == "@spirver")
|
||||
spirvVer = flag.value;
|
||||
|
||||
// replace arguments after expansion to avoid problems with quoting paths etc
|
||||
for(QString &arg : argList)
|
||||
{
|
||||
@@ -262,6 +283,10 @@ ShaderToolOutput ShaderProcessingTool::DisassembleShader(QWidget *window,
|
||||
arg.replace(0, 13, glsl_stage4[int(shaderDetails->stage)]);
|
||||
if(arg.left(13) == lit("{hlsl_stage2}"))
|
||||
arg.replace(0, 13, hlsl_stage2[int(shaderDetails->stage)]);
|
||||
if(arg.left(11) == lit("{spirv_ver}"))
|
||||
arg.replace(0, 11, spirvVer);
|
||||
if(arg.left(12) == lit("{vulkan_ver}"))
|
||||
arg.replace(0, 12, vulkanVerForSpirVer(spirvVer));
|
||||
}
|
||||
|
||||
QFile binHandle(input_file);
|
||||
@@ -287,7 +312,7 @@ ShaderToolOutput ShaderProcessingTool::DisassembleShader(QWidget *window,
|
||||
|
||||
ShaderToolOutput ShaderProcessingTool::CompileShader(QWidget *window, rdcstr source,
|
||||
rdcstr entryPoint, ShaderStage stage,
|
||||
rdcstr arguments) const
|
||||
rdcstr spirvVer, rdcstr arguments) const
|
||||
{
|
||||
QStringList argList = ParseArgsList(arguments.isEmpty() ? DefaultArguments() : arguments);
|
||||
// always append IO arguments for known tools, so we read/write to our own files and override any
|
||||
@@ -298,6 +323,9 @@ ShaderToolOutput ShaderProcessingTool::CompileShader(QWidget *window, rdcstr sou
|
||||
|
||||
input_file = tmpPath(lit("shader_input"));
|
||||
|
||||
if(spirvVer.isEmpty())
|
||||
spirvVer = "spirv1.0";
|
||||
|
||||
// replace arguments after expansion to avoid problems with quoting paths etc
|
||||
for(QString &arg : argList)
|
||||
{
|
||||
@@ -313,6 +341,10 @@ ShaderToolOutput ShaderProcessingTool::CompileShader(QWidget *window, rdcstr sou
|
||||
arg.replace(0, 13, glsl_stage4[int(stage)]);
|
||||
if(arg.left(13) == lit("{hlsl_stage2}"))
|
||||
arg.replace(0, 13, hlsl_stage2[int(stage)]);
|
||||
if(arg.left(11) == lit("{spirv_ver}"))
|
||||
arg.replace(0, 11, spirvVer);
|
||||
if(arg.left(12) == lit("{vulkan_ver}"))
|
||||
arg.replace(0, 12, vulkanVerForSpirVer(spirvVer));
|
||||
}
|
||||
|
||||
QFile binHandle(input_file);
|
||||
|
||||
@@ -88,7 +88,7 @@ ShaderToolOutput ShaderProcessingTool::DisassembleShader(QWidget *window,
|
||||
|
||||
ShaderToolOutput ShaderProcessingTool::CompileShader(QWidget *window, rdcstr source,
|
||||
rdcstr entryPoint, ShaderStage stage,
|
||||
rdcstr arguments) const
|
||||
rdcstr spirvVer, rdcstr arguments) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -1043,7 +1043,13 @@ IShaderViewer *PipelineStateViewer::EditDecompiledSource(const ShaderProcessingT
|
||||
rdcstrpairs files;
|
||||
files.push_back(rdcpair<rdcstr, rdcstr>("decompiled", source));
|
||||
|
||||
IShaderViewer *sv = EditShader(id, shaderDetails->stage, shaderDetails->entryPoint, {},
|
||||
ShaderCompileFlags flags;
|
||||
|
||||
for(const ShaderCompileFlag &flag : shaderDetails->debugInfo.compileFlags.flags)
|
||||
if(flag.name == "@spirver")
|
||||
flags.flags.push_back(flag);
|
||||
|
||||
IShaderViewer *sv = EditShader(id, shaderDetails->stage, shaderDetails->entryPoint, flags,
|
||||
KnownShaderTool::Unknown, tool.output, files);
|
||||
|
||||
sv->ShowErrors(out.log);
|
||||
|
||||
@@ -6029,6 +6029,11 @@ void ShaderViewer::on_refresh_clicked()
|
||||
|
||||
rdcarray<ShaderEncoding> accepted = m_Ctx.TargetShaderEncodings();
|
||||
|
||||
rdcstr spirvVer = "spirv1.0";
|
||||
for(const ShaderCompileFlag &flag : m_Flags.flags)
|
||||
if(flag.name == "@spirver")
|
||||
spirvVer = flag.value;
|
||||
|
||||
if(m_CustomShader || (accepted.indexOf(encoding) >= 0 &&
|
||||
ui->compileTool->currentIndex() == ui->compileTool->count() - 1))
|
||||
{
|
||||
@@ -6041,7 +6046,7 @@ void ShaderViewer::on_refresh_clicked()
|
||||
if(QString(tool.name) == ui->compileTool->currentText())
|
||||
{
|
||||
ShaderToolOutput out = tool.CompileShader(this, source, ui->entryFunc->text(), m_Stage,
|
||||
ui->toolCommandLine->toPlainText());
|
||||
spirvVer, ui->toolCommandLine->toPlainText());
|
||||
|
||||
ShowErrors(out.log);
|
||||
|
||||
|
||||
@@ -4415,7 +4415,7 @@ void TextureViewer::reloadCustomShaders(const QString &filter)
|
||||
}
|
||||
|
||||
ShaderToolOutput out =
|
||||
tool.CompileShader(this, source, "main", ShaderStage::Pixel, "");
|
||||
tool.CompileShader(this, source, "main", ShaderStage::Pixel, "", "");
|
||||
|
||||
errors = out.log;
|
||||
|
||||
|
||||
@@ -936,6 +936,9 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
|
||||
if(!cmdline.empty())
|
||||
reflection.debugInfo.compileFlags.flags = {{"@cmdline", cmdline}};
|
||||
|
||||
reflection.debugInfo.compileFlags.flags.push_back(
|
||||
{"@spirver", StringFormat::Fmt("spirv%d.%d", m_MajorVersion, m_MinorVersion)});
|
||||
|
||||
{
|
||||
auto it = funcToDebugFunc.find(entry->id);
|
||||
if(it != funcToDebugFunc.end())
|
||||
|
||||
Reference in New Issue
Block a user