Implement NonSemantic.Shader.DebugInfo.100

See https://github.com/KhronosGroup/SPIRV-Registry.
This commit is contained in:
Jeremy Hayes
2021-12-09 16:26:48 -07:00
parent 9e78bc8108
commit 7a914ce926
55 changed files with 11275 additions and 96 deletions

View File

@@ -50,6 +50,10 @@
#include "Logger.h"
#include "spirv.hpp"
#include "spvIR.h"
namespace spv {
#include "GLSL.ext.KHR.h"
#include "NonSemanticShaderDebugInfo100.h"
}
#include <algorithm>
#include <map>
@@ -82,7 +86,7 @@ public:
void setSource(spv::SourceLanguage lang, int version)
{
source = lang;
sourceLang = lang;
sourceVersion = version;
}
spv::Id getStringId(const std::string& str)
@@ -106,11 +110,25 @@ public:
void setSourceFile(const std::string& file)
{
sourceFileStringId = getStringId(file);
currentFileId = sourceFileStringId;
}
void setSourceText(const std::string& text) { sourceText = text; }
void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
void setEmitOpLines() { emitOpLines = true; }
void setEmitNonSemanticShaderDebugInfo(bool const emit)
{
emitNonSemanticShaderDebugInfo = emit;
if(emit)
{
importNonSemanticShaderDebugInfoInstructions();
}
}
void setEmitNonSemanticShaderDebugSource(bool const src)
{
emitNonSemanticShaderDebugSource = src;
}
void addExtension(const char* ext) { extensions.insert(ext); }
void removeExtension(const char* ext)
{
@@ -163,10 +181,11 @@ public:
void setLine(int line, const char* filename);
// Low-level OpLine. See setLine() for a layered helper.
void addLine(Id fileName, int line, int column);
void addDebugScopeAndLine(Id fileName, int line, int column);
// For creating new types (will return old type if the requested one was already made).
Id makeVoidType();
Id makeBoolType();
Id makeBoolType(bool const compilerGenerated = true);
Id makePointer(StorageClass, Id pointee);
Id makeForwardPointer(StorageClass);
Id makePointerFromForwardPointer(StorageClass, Id forwardPointerType, Id pointee);
@@ -174,7 +193,7 @@ public:
Id makeIntType(int width) { return makeIntegerType(width, true); }
Id makeUintType(int width) { return makeIntegerType(width, false); }
Id makeFloatType(int width);
Id makeStructType(const std::vector<Id>& members, const char*);
Id makeStructType(const std::vector<Id>& members, const char* name, bool const compilerGenerated = true);
Id makeStructResultType(Id type0, Id type1);
Id makeVectorType(Id component, int size);
Id makeMatrixType(Id component, int cols, int rows);
@@ -187,6 +206,36 @@ public:
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
Id makeGenericType(spv::Op opcode, std::vector<spv::IdImmediate>& operands);
// SPIR-V NonSemantic Shader DebugInfo Instructions
struct DebugTypeLoc {
std::string name {};
int line {0};
int column {0};
};
std::unordered_map<Id, DebugTypeLoc> debugTypeLocs;
Id makeDebugInfoNone();
Id makeBoolDebugType(int const size);
Id makeIntegerDebugType(int const width, bool const hasSign);
Id makeFloatDebugType(int const width);
Id makeSequentialDebugType(Id const baseType, Id const componentCount, NonSemanticShaderDebugInfo100Instructions const sequenceType);
Id makeArrayDebugType(Id const baseType, Id const componentCount);
Id makeVectorDebugType(Id const baseType, int const componentCount);
Id makeMatrixDebugType(Id const vectorType, int const vectorCount, bool columnMajor = true);
Id makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTypeLoc);
Id makeCompositeDebugType(std::vector<Id> const& memberTypes, char const*const name,
NonSemanticShaderDebugInfo100DebugCompositeType const tag, bool const isOpaqueType = false);
Id makeDebugSource(const Id fileName);
Id makeDebugCompilationUnit();
Id createDebugGlobalVariable(Id const type, char const*const name, Id const variable);
Id createDebugLocalVariable(Id type, char const*const name, size_t const argNumber = 0);
Id makeDebugExpression();
Id makeDebugDeclare(Id const debugLocalVariable, Id const localVariable);
Id makeDebugValue(Id const debugLocalVariable, Id const value);
Id makeDebugFunctionType(Id returnType, const std::vector<Id>& paramTypes);
Id makeDebugFunction(Function* function, Id nameId, Id funcTypeId);
Id makeDebugLexicalBlock(uint32_t line);
std::string unmangleFunctionName(std::string const& name) const;
// accelerationStructureNV type
Id makeAccelerationStructureType();
// rayQueryEXT type
@@ -261,6 +310,8 @@ public:
// See if a resultId is valid for use as an initializer.
bool isValidInitializer(Id resultId) const { return isConstant(resultId) || isGlobalVariable(resultId); }
bool isRayTracingOpCode(Op opcode) const;
int getScalarTypeWidth(Id typeId) const
{
Id scalarTypeId = getScalarTypeId(typeId);
@@ -322,6 +373,8 @@ public:
Id makeFloat16Constant(float f16, bool specConstant = false);
Id makeFpConstant(Id type, double d, bool specConstant = false);
Id importNonSemanticShaderDebugInfoInstructions();
// Turn the array of constants into a proper spv constant of the requested type.
Id makeCompositeConstant(Id type, const std::vector<Id>& comps, bool specConst = false);
@@ -344,7 +397,12 @@ public:
void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector<const char*>& strings);
// At the end of what block do the next create*() instructions go?
void setBuildPoint(Block* bp) { buildPoint = bp; }
// Also reset current last DebugScope and current source line to unknown
void setBuildPoint(Block* bp) {
buildPoint = bp;
lastDebugScopeId = NoResult;
currentLine = 0;
}
Block* getBuildPoint() const { return buildPoint; }
// Make the entry-point function. The returned pointer is only valid
@@ -355,12 +413,22 @@ public:
// Return the function, pass back the entry.
// The returned pointer is only valid for the lifetime of this builder.
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name,
const std::vector<Id>& paramTypes, const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
const std::vector<Id>& paramTypes, const std::vector<char const*>& paramNames,
const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
// Create a return. An 'implicit' return is one not appearing in the source
// code. In the case of an implicit return, no post-return block is inserted.
void makeReturn(bool implicit, Id retVal = 0);
// Initialize state and generate instructions for new lexical scope
void enterScope(uint32_t line);
// Set state and generate instructions to exit current lexical scope
void leaveScope();
// Prepare builder for generation of instructions for a function.
void enterFunction(Function const* function);
// Generate all the code needed to finish up a function.
void leaveFunction();
@@ -369,8 +437,8 @@ public:
void makeStatementTerminator(spv::Op opcode, const char *name);
// Create a global or function local or IO variable.
Id createVariable(Decoration precision, StorageClass, Id type, const char* name = nullptr,
Id initializer = NoResult);
Id createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name = nullptr,
Id initializer = NoResult, bool const compilerGenerated = true);
// Create an intermediate with an undefined value.
Id createUndefined(Id type);
@@ -805,13 +873,23 @@ public:
const;
unsigned int spvVersion; // the version of SPIR-V to emit in the header
SourceLanguage source;
SourceLanguage sourceLang;
int sourceVersion;
spv::Id sourceFileStringId;
spv::Id nonSemanticShaderCompilationUnitId {0};
spv::Id nonSemanticShaderDebugInfo {0};
spv::Id debugInfoNone {0};
spv::Id debugExpression {0}; // Debug expression with zero operations.
std::string sourceText;
int currentLine;
const char* currentFile;
spv::Id currentFileId;
std::stack<spv::Id> currentDebugScopeId;
spv::Id lastDebugScopeId;
bool emitOpLines;
bool emitNonSemanticShaderDebugInfo;
bool restoreNonSemanticShaderDebugInfo;
bool emitNonSemanticShaderDebugSource;
std::set<std::string> extensions;
std::vector<const char*> sourceExtensions;
std::vector<const char*> moduleProcesses;
@@ -845,6 +923,8 @@ public:
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
// map type opcodes to type instructions
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes;
// map type opcodes to debug type instructions
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedDebugTypes;
// list of OpConstantNull instructions
std::vector<Instruction*> nullConstants;
@@ -860,6 +940,12 @@ public:
// map from include file name ids to their contents
std::map<spv::Id, const std::string*> includeFiles;
// map from core id to debug id
std::map <spv::Id, spv::Id> debugId;
// map from file name string id to DebugSource id
std::unordered_map<spv::Id, spv::Id> debugSourceId;
// The stream for outputting warnings and errors.
SpvBuildLogger* logger;
}; // end Builder class