Skip to content

Commit

Permalink
Shader asserts are in. Thanks Alexey Gladkov aka @Rewlion!
Browse files Browse the repository at this point in the history
Example: /*$(Assert: i < 5, "i was %f", i)*/
See UserDocumentation/GigiShaders_Documentation for more info.

Functionality:
* Set Variables have support for min and max
* Subgraph loops can use CONSTANT variables for loop count. Dynamic variable support coming later.

Compiler:
* Better error messaging when subgraphs fail to inline. Says what the problem is.
* Large graphs were having slow downs due to ReferenceFixupVisitor scanning the graph too deeply too often. A visited flag cleaned this up.

Viewer:
* Variables can have a UI scope to group them better in the UI
* Conditional Copy Resource nodes now say whether their condition is true or false in the render graph window.
* Better protection against using bad formats for depth textures
* Better explanation when a texture can't be created (like, when it has an invalid size specified)
* New snapshots interface to be able to save and load cameras, variable values, imported resource settings, or what window is being viewed. Generalizes a couple pre-existing features that needed more functionality.
  • Loading branch information
Atrix256 committed Oct 8, 2024
1 parent 3071068 commit e5b5fc4
Show file tree
Hide file tree
Showing 161 changed files with 12,633 additions and 472 deletions.
21 changes: 20 additions & 1 deletion GigiCompilerLib/Backends/DX12/Backend_DX12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,7 @@ struct BackendDX12 : public BackendBase
stringReplacementMap[destinationString] << " = ";
}

// Handle SetVariableOperator::BitwiseNot
// Handle operations which require a prefix to the operands
if (setVar.op == SetVariableOperator::BitwiseNot)
{
const Variable& destVar = renderGraph.variables[setVar.destination.variableIndex];
Expand All @@ -1082,6 +1082,14 @@ struct BackendDX12 : public BackendBase
{
stringReplacementMap[destinationString] << "Pow2GE(";
}
else if (setVar.op == SetVariableOperator::Minimum)
{
stringReplacementMap[destinationString] << "min(";
}
else if (setVar.op == SetVariableOperator::Maximum)
{
stringReplacementMap[destinationString] << "max(";
}

// Write out the first operand
if (setVar.AVar.variableIndex != -1)
Expand Down Expand Up @@ -1120,6 +1128,9 @@ struct BackendDX12 : public BackendBase
case SetVariableOperator::Divide: stringReplacementMap[destinationString] << " / "; break;
case SetVariableOperator::Modulo: stringReplacementMap[destinationString] << " % "; break;

case SetVariableOperator::Minimum:
case SetVariableOperator::Maximum: stringReplacementMap[destinationString] << ", "; break;

case SetVariableOperator::BitwiseOr: stringReplacementMap[destinationString] << (destVarIsBool ? " || " : " | "); break;
case SetVariableOperator::BitwiseAnd: stringReplacementMap[destinationString] << (destVarIsBool ? " && " : " & "); break;
case SetVariableOperator::BitwiseXor: stringReplacementMap[destinationString] << " ^ "; break;
Expand All @@ -1142,6 +1153,11 @@ struct BackendDX12 : public BackendBase
{
stringReplacementMap[destinationString] << setVar.BLiteral;
}

if (setVar.op == SetVariableOperator::Minimum || setVar.op == SetVariableOperator::Maximum)
{
stringReplacementMap[destinationString] << ")";
}
}

// All done
Expand Down Expand Up @@ -1815,6 +1831,9 @@ void CopyShaderFileDX12(const Shader& shader, const std::unordered_map<std::stri
}
);

for (const TokenReplacement& replacement : shader.tokenReplacements)
shaderSpecificStringReplacementMap[replacement.name] << replacement.value;

// Replace the strings
ProcessStringReplacement(shaderFileContents, shaderSpecificStringReplacementMap, stringReplacementMap, renderGraph);

Expand Down
2 changes: 1 addition & 1 deletion GigiCompilerLib/Backends/Shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ inline void WriteFileIfDifferent(const std::string& fileName, const std::vector<

inline void ProcessStringReplacement(std::string& str, std::unordered_map<std::string, std::ostringstream>& stringReplacementMap, const RenderGraph& renderGraph)
{
// Gigi "preprocessor"
// Gigi preprocessor
size_t offset = 0;
while (1)
{
Expand Down
72 changes: 67 additions & 5 deletions GigiCompilerLib/SubGraphs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -874,11 +874,51 @@ static bool InlineSubGraph(RenderGraph& parentGraph, RenderGraphNode_Action_SubG
// Handle variable replacement
// This is when subgraph variables are replaced by parent graph variables
{
// Handle "replaceWithValue" - make a constant var with that as the default, and set replaceWithStr to it
{
for (SubGraphVariableSettings& variableSettings : subGraphNode.variableSettings)
{
if (variableSettings.replaceWithValue.empty())
continue;

int childVariableIndex = GetVariableIndex(childGraph, variableSettings.name.c_str());
if (childVariableIndex == -1)
{
ShowErrorMessage("Could not find variable \"%s\" in \"%s\" for node \"%s\".", variableSettings.name.c_str(), childFileName.c_str(), subGraphNode.name.c_str());
continue;
}

// make a unique name for the new variable
char variableName[1024];
int index = 0;
do
{
sprintf_s(variableName, "__literal_%i", index);
index++;
}
while (VariableNameExists(parentGraph, variableName));

// make a new variable in the parent graph
Variable newVariable;
newVariable.name = variableName;
newVariable.comment = "Made to replace variable \"" + variableSettings.name + "\" with a constant value in subgraph node \"" + subGraphNode.name + "\"";
newVariable.type = childGraph.variables[childVariableIndex].type;
newVariable.Const = true;
newVariable.dflt = variableSettings.replaceWithValue;
newVariable.transient = true;
parentGraph.variables.push_back(newVariable);

// tell the subgraph to use this new variable instead
variableSettings.replaceWithStr = variableName;
}
}

// Replace variable references
{
RenameData renameData;
for (const SubGraphVariableSettings& variableSettings : subGraphNode.variableSettings)
{
// if no variable replacement to do, skip this
if (variableSettings.replaceWithStr.empty() && !variableSettings.isLoopIndex)
continue;

Expand Down Expand Up @@ -1077,10 +1117,25 @@ bool ExpandLoopedSubgraphs(RenderGraph& renderGraph)

const RenderGraphNode_Action_SubGraph& subGraph = node.actionSubGraph;

if (subGraph.loopCount > 1)
// Get the loop count
// If a variable is specified, it overrides the literal value given.
int loopCount = subGraph.loopCount;
if (!subGraph.loopCountVariable.name.empty())
{
for (const Variable& var : renderGraph.variables)
{
if (var.name == subGraph.loopCountVariable.name)
{
sscanf_s(var.dflt.c_str(), "%i", &loopCount);
break;
}
}
}

if (loopCount > 1)
{
// Loop over the number of iterations we want
for (int loopIdx = 0; loopIdx < subGraph.loopCount; ++loopIdx)
for (int loopIdx = 0; loopIdx < loopCount; ++loopIdx)
{
// Copy the original node
RenderGraphNode loopNode = node;
Expand Down Expand Up @@ -1111,7 +1166,7 @@ bool ExpandLoopedSubgraphs(RenderGraph& renderGraph)

// If this is the last iteration, other nodes in the parent graph need to have references
// to the original subgraph updated to point to the last iteration.
if (loopIdx == subGraph.loopCount-1)
if (loopIdx == loopCount-1)
{
renameData.m_nodeRenames[oldName] = loopSubGraph.name;
}
Expand Down Expand Up @@ -1304,8 +1359,15 @@ bool InlineSubGraphs(RenderGraph& renderGraph)
// detect and report the error of not being able to make progress
if (subgraphNodesRemain && !madeProgress)
{
ShowErrorMessage("Unable to make progress inlining subgraphs");
return false;
for (int nodeIndex = 0; nodeIndex < renderGraph.nodes.size(); ++nodeIndex)
{
RenderGraphNode& node = renderGraph.nodes[nodeIndex];
if (node._index != RenderGraphNode::c_index_actionSubGraph)
continue;

ShowErrorMessage("Unable to make progress inlining subgraphs. Node \"%s\" could not be inlined, are all of it's inputs plugged in?", node.actionSubGraph.name.c_str());
return false;
}
}
}

Expand Down
22 changes: 15 additions & 7 deletions GigiCompilerLib/gigicompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,21 @@ GigiCompileResult GigiCompile(GigiBuildFlavor buildFlavor, const std::string& js
if (PostLoad)
PostLoad(renderGraph);

// Shader references need to be resolved first
{
ShaderReferenceFixupVisitor visitor(renderGraph);
if (!Visit(renderGraph, visitor, "renderGraph"))
return GigiCompileResult::ReferenceFixup;
}

// Process Asserts declarations inside shaders
if (backend == Backend::Interpreter)
{
ShaderAssertsVisitor visitor{ renderGraph };
if (!Visit(renderGraph, visitor, "renderGraph"))
return GigiCompileResult::ShaderAsserts;
}

// Get data from shaders
{
ShaderDataVisitor visitor(renderGraph);
Expand All @@ -273,13 +288,6 @@ GigiCompileResult GigiCompile(GigiBuildFlavor buildFlavor, const std::string& js
return GigiCompileResult::Validation;
}

// Shader references need to be resolved first
{
ShaderReferenceFixupVisitor visitor(renderGraph);
if (!Visit(renderGraph, visitor, "renderGraph"))
return GigiCompileResult::ReferenceFixup;
}

// resolve the node references from names into indices
{
ReferenceFixupVisitor visitor(renderGraph);
Expand Down
6 changes: 6 additions & 0 deletions GigiCompilerLib/gigiinterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@ class IGigiInterpreter
break;
}

case SetVariableOperator::Minimum: dest = std::min(A, B); break;
case SetVariableOperator::Maximum: dest = std::max(A, B); break;

case SetVariableOperator::Noop: dest = A; break;
}
}
Expand Down Expand Up @@ -410,6 +413,9 @@ class IGigiInterpreter
break;
}

case SetVariableOperator::Minimum: dest = std::min(A, B); break;
case SetVariableOperator::Maximum: dest = std::max(A, B); break;

case SetVariableOperator::Noop: dest = A; break;
}
}
Expand Down
53 changes: 53 additions & 0 deletions GigiEdit/MakeUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -1483,7 +1483,58 @@ inline UIOverrideResult ShowUIOverride(RenderGraph& renderGraph, uint64_t _FLAGS
// Sort the list of variables
std::vector<std::string> vars;
for (const Variable& var : renderGraph.variables)
{
if (var.Const)
continue;
vars.push_back(var.name);
}
CaseInsensitiveSort(vars);

// add a blank to the beginning
vars.insert(vars.begin(), "");

// Show a drop down
for (const std::string& label : vars)
{
bool is_selected = value.name == label;
std::string safeLabel = label + "##";
if (ImGui::Selectable(safeLabel.c_str(), is_selected))
{
value.name = label;
dirtyFlag = true;
}
if (is_selected)
ImGui::SetItemDefaultFocus();
}

ImGui::EndCombo();
}
ShowUIToolTip(tooltip);

ImGui::SameLine();
if (ArrowButton2("GoToData", ImGuiDir_Right, true, false))
OnGoToVariable(value.name.c_str());
ShowUIToolTip("Go to Variable");

ImGui::PopID();

return UIOverrideResult::Finished;
}

inline UIOverrideResult ShowUIOverride(RenderGraph& renderGraph, uint64_t _FLAGS, bool& dirtyFlag, const char* label, const char* tooltip, VariableReferenceConstOnly& value, TypePathEntry path, ShowUIOverrideContext showUIOverrideContext)
{
ImGui::PushID(label);

if (ImGui::BeginCombo(label, value.name.c_str()))
{
// Sort the list of variables
std::vector<std::string> vars;
for (const Variable& var : renderGraph.variables)
{
if (!var.Const)
continue;
vars.push_back(var.name);
}
CaseInsensitiveSort(vars);

// add a blank to the beginning
Expand Down Expand Up @@ -1922,6 +1973,8 @@ struct ShaderTypeCodeGenerator
"struct VSInput\n"
"{\n"
"\tfloat3 position : POSITION;\n"
"\tuint vertexID : SV_VertexID;\n"
"\tuint instanceId : SV_InstanceID;\n"
"\t//TODO: fill this out\n"
"};\n"
"\n"
Expand Down
19 changes: 19 additions & 0 deletions GigiEdit/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1676,6 +1676,24 @@ struct Example :
name << ")";
break;
}
case SetVariableOperator::Minimum:
{
name << "Min(";
name << GetRHS(item.ALiteral, item.ANode, item.AVar, item.AVarIndex);
name << ",";
name << GetRHS(item.BLiteral, item.BNode, item.BVar, item.BVarIndex);
name << ")";
break;
}
case SetVariableOperator::Maximum:
{
name << "Max(";
name << GetRHS(item.ALiteral, item.ANode, item.AVar, item.AVarIndex);
name << ",";
name << GetRHS(item.BLiteral, item.BNode, item.BVar, item.BVarIndex);
name << ")";
break;
}
case SetVariableOperator::BitwiseOr:
{
name << GetRHS(item.ALiteral, item.ANode, item.AVar, item.AVarIndex);
Expand Down Expand Up @@ -1761,6 +1779,7 @@ struct Example :
EnsureVariableExists("JitteredViewProjMtx", VariableVisibility::Host, DataFieldType::Float4x4, "1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f");
EnsureVariableExists("InvJitteredViewProjMtx", VariableVisibility::Host, DataFieldType::Float4x4, "1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f");
EnsureVariableExists("CameraPos", VariableVisibility::Host, DataFieldType::Float3, "0.0f, 0.0f, 0.0f");
EnsureVariableExists("CameraAltitudeAzimuth", VariableVisibility::Host, DataFieldType::Float2, "0.0f, 0.0f");
EnsureVariableExists("CameraChanged", VariableVisibility::Host, DataFieldType::Bool, "false");
EnsureVariableExists("CameraJitter", VariableVisibility::Host, DataFieldType::Float2, "0.5f, 0.5f");
EnsureVariableExists("ShadingRateImageTileSize", VariableVisibility::Host, DataFieldType::Uint, "16");
Expand Down
Loading

0 comments on commit e5b5fc4

Please sign in to comment.