summaryrefslogtreecommitdiff
path: root/source/slang/slang-emit-spirv.cpp
diff options
context:
space:
mode:
authorEllie Hermaszewska <ellieh@nvidia.com>2024-10-29 14:49:26 +0800
committerGitHub <noreply@github.com>2024-10-29 14:49:26 +0800
commitf65d756bff8d4c5cbc15bd0322a2ae8e6b896a21 (patch)
treeea1d61342cd29368e19135000ec2948813096205 /source/slang/slang-emit-spirv.cpp
parenta729c15e9dce9f5116a38afc66329ab2ca4cea54 (diff)
format
* format * Minor test fixes * enable checking cpp format in ci
Diffstat (limited to 'source/slang/slang-emit-spirv.cpp')
-rw-r--r--source/slang/slang-emit-spirv.cpp3505
1 files changed, 1919 insertions, 1586 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 3ba7cf43b..e134c579e 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -1,19 +1,19 @@
// slang-emit-spirv.cpp
+#include "../core/slang-memory-arena.h"
#include "slang-compiler.h"
#include "slang-emit-base.h"
-
-#include "slang-ir-util.h"
#include "slang-ir-call-graph.h"
-#include "slang-ir.h"
#include "slang-ir-insts.h"
#include "slang-ir-layout.h"
-#include "slang-ir-spirv-snippet.h"
#include "slang-ir-spirv-legalize.h"
-#include "slang-spirv-val.h"
+#include "slang-ir-spirv-snippet.h"
+#include "slang-ir-util.h"
+#include "slang-ir.h"
#include "slang-lookup-spirv.h"
+#include "slang-spirv-val.h"
#include "spirv/unified1/spirv.h"
-#include "../core/slang-memory-arena.h"
+
#include <type_traits>
namespace Slang
@@ -70,7 +70,7 @@ namespace Slang
// the enumeration of the ordering in Section 2.4 and use it to
// define a list of *logical sections* that make up a SPIR-V module.
- /// Logical sections of a SPIR-V module.
+/// Logical sections of a SPIR-V module.
enum class SpvLogicalSectionID
{
Capabilities,
@@ -124,38 +124,38 @@ struct SpvInst;
// earlier and instructions such as functions will be used
// as parents.
- /// Base type for SPIR-V instructions and logical sections of a module
- ///
- /// Holds and supports appending to a list of child instructions.
+/// Base type for SPIR-V instructions and logical sections of a module
+///
+/// Holds and supports appending to a list of child instructions.
struct SpvInstParent
{
public:
- /// Add an instruction to the end of the list of children
+ /// Add an instruction to the end of the list of children
void addInst(SpvInst* inst);
- /// Dump all children, recursively, to a flattened list of SPIR-V words
+ /// Dump all children, recursively, to a flattened list of SPIR-V words
void dumpTo(List<SpvWord>& ioWords);
- /// The first child, if any.
+ /// The first child, if any.
SpvInst* m_firstChild = nullptr;
- /// A pointer to the null pointer at the end of the linked list.
- ///
- /// If the list of children is empty this points to `m_firstChild`,
- /// while if it is non-empty it points to the `nextSibling` field
- /// of the last instruction.
- ///
+ /// A pointer to the null pointer at the end of the linked list.
+ ///
+ /// If the list of children is empty this points to `m_firstChild`,
+ /// while if it is non-empty it points to the `nextSibling` field
+ /// of the last instruction.
+ ///
SpvInst* m_lastChild = nullptr;
};
// A SPIR-V instruction is then (in the general case) a potential
// parent to other instructions.
- /// A type to represent a SPIR-V instruction to be emitted.
- ///
- /// This type alows the instruction to be built up across
- /// multiple steps in a mutable fashion.
- ///
+/// A type to represent a SPIR-V instruction to be emitted.
+///
+/// This type alows the instruction to be built up across
+/// multiple steps in a mutable fashion.
+///
struct SpvInst : SpvInstParent
{
// [2.3: Physical Layout of a SPIR-V Module and Instruction]
@@ -169,7 +169,7 @@ struct SpvInst : SpvInstParent
// intermediate structure, and compute the word count on
// the fly when writing an instruction to an output buffer.
- /// The SPIR-V opcode for the instruction
+ /// The SPIR-V opcode for the instruction
SpvOp opcode;
// [2.3: Physical Layout of a SPIR-V Module and Instruction]
@@ -190,9 +190,9 @@ struct SpvInst : SpvInstParent
// cases where we needed to do post-processing, then we would
// need to store a more refined representation here.
- /// The additional words of the instruction after the opcode
+ /// The additional words of the instruction after the opcode
SpvWord* operandWords = nullptr;
- /// The amount of operand words
+ /// The amount of operand words
uint32_t operandWordsCount = 0;
// We will store the instructions in a given `SpvInstParent`
@@ -200,15 +200,15 @@ struct SpvInst : SpvInstParent
SpvInstParent* parent = nullptr;
- /// The next instruction in the same `SpvInstParent`
+ /// The next instruction in the same `SpvInstParent`
SpvInst* nextSibling = nullptr;
SpvInst* prevSibling = nullptr;
-
- /// The result <id> produced by this instruction, or zero if it has no result.
+
+ /// The result <id> produced by this instruction, or zero if it has no result.
SpvWord id = 0;
- /// Dump the instruction (and any children, recursively) into the flat array of SPIR-V words.
+ /// Dump the instruction (and any children, recursively) into the flat array of SPIR-V words.
void dumpTo(List<SpvWord>& ioWords)
{
// [2.2: Terms]
@@ -229,7 +229,7 @@ struct SpvInst : SpvInstParent
// The operand words simply follow the opcode word.
//
ioWords.addRange(operandWords, operandWordsCount);
-
+
// In our representation choice, the children of a
// parent instruction will always follow the encoded
// words of a parent:
@@ -278,7 +278,7 @@ struct SpvInst : SpvInstParent
}
};
- /// A logical section of a SPIR-V module
+/// A logical section of a SPIR-V module
struct SpvLogicalSection : SpvInstParent
{
};
@@ -309,7 +309,7 @@ void SpvInstParent::addInst(SpvInst* inst)
void SpvInstParent::dumpTo(List<SpvWord>& ioWords)
{
- for( auto child = m_firstChild; child; child = child->nextSibling )
+ for (auto child = m_firstChild; child; child = child->nextSibling)
{
child->dumpTo(ioWords);
}
@@ -333,7 +333,10 @@ struct SpvLiteralInteger
static SpvLiteralInteger from32(int32_t value) { return from32(uint32_t(value)); }
static SpvLiteralInteger from32(uint32_t value) { return SpvLiteralInteger{{value}}; }
static SpvLiteralInteger from64(int64_t value) { return from64(uint64_t(value)); }
- static SpvLiteralInteger from64(uint64_t value) { return SpvLiteralInteger{{SpvWord(value), SpvWord(value >> 32)}}; }
+ static SpvLiteralInteger from64(uint64_t value)
+ {
+ return SpvLiteralInteger{{SpvWord(value), SpvWord(value >> 32)}};
+ }
List<SpvWord> value; // Words, stored low words to high (TODO, SmallArray or something here)
};
@@ -341,7 +344,10 @@ struct SpvLiteralInteger
struct SpvLiteralBits
{
static SpvLiteralBits from32(uint32_t value) { return SpvLiteralBits{{value}}; }
- static SpvLiteralBits from64(uint64_t value) { return SpvLiteralBits{{SpvWord(value), SpvWord(value >> 32)}}; }
+ static SpvLiteralBits from64(uint64_t value)
+ {
+ return SpvLiteralBits{{SpvWord(value), SpvWord(value >> 32)}};
+ }
static SpvLiteralBits fromUnownedStringSlice(UnownedStringSlice text)
{
SpvLiteralBits result;
@@ -392,20 +398,29 @@ struct OperandsOf
{
OperandsOf(IRInst* irInst)
: irInst(irInst)
- {}
+ {
+ }
IRInst* irInst = nullptr;
};
/// Helper type for not emitting an operand in this position
-struct SkipThisOptionalOperand {};
+struct SkipThisOptionalOperand
+{
+};
template<typename T>
struct OptionalOperand
{
static_assert(std::is_trivial_v<T>);
- OptionalOperand(SkipThisOptionalOperand) : present(false) {}
- OptionalOperand(T value) : present(true), value(value) {}
+ OptionalOperand(SkipThisOptionalOperand)
+ : present(false)
+ {
+ }
+ OptionalOperand(T value)
+ : present(true), value(value)
+ {
+ }
bool present;
T value;
};
@@ -443,12 +458,10 @@ constexpr bool isSingular = !isPlural<T>;
// to defining the main context type that will drive SPIR-V
// code generation.
- /// Context used for translating a Slang IR module to SPIR-V
-struct SPIRVEmitContext
- : public SourceEmitterBase
- , public SPIRVEmitSharedContext
+/// Context used for translating a Slang IR module to SPIR-V
+struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContext
{
- /// The Slang IR module being translated
+ /// The Slang IR module being translated
IRModule* m_irModule;
// [2.2: Terms]
@@ -461,7 +474,8 @@ struct SPIRVEmitContext
//
// > Bound; where all <id>s in this module are guaranteed to satisfy
// > 0 < id < Bound
- // > Bound should be small, smaller is better, with all <id> in a module being densely packed and near 0.
+ // > Bound should be small, smaller is better, with all <id> in a module being densely packed
+ // and near 0.
//
// Instructions will be referred to by their <id>s.
// We need to generate <id>s for instructions, and also
@@ -474,14 +488,14 @@ struct SPIRVEmitContext
// but we expect the amount of slop to be small (and
// it can be cleaned up by other tools/passes).
- /// The next destination `<id>` to allocate.
+ /// The next destination `<id>` to allocate.
SpvWord m_nextID = 1;
OrderedHashSet<IRPtrTypeBase*> m_forwardDeclaredPointers;
SpvInst* m_nullDwarfExpr = nullptr;
- // A hash set to prevent redecorating the same spv inst.
+ // A hash set to prevent redecorating the same spv inst.
HashSet<SpvId> m_decoratedSpvInsts;
SpvAddressingModel m_addressingMode = SpvAddressingModelLogical;
@@ -490,26 +504,23 @@ struct SPIRVEmitContext
// in a single array so that we can easily look up a
// section by its `SpvLogicalSectionID`.
- /// The logical sections of the SPIR-V module
+ /// The logical sections of the SPIR-V module
SpvLogicalSection m_sections[int(SpvLogicalSectionID::Count)];
- /// Get a logical section based on its `SpvLogicalSectionID`
- SpvLogicalSection* getSection(SpvLogicalSectionID id)
- {
- return &m_sections[int(id)];
- }
+ /// Get a logical section based on its `SpvLogicalSectionID`
+ SpvLogicalSection* getSection(SpvLogicalSectionID id) { return &m_sections[int(id)]; }
// At the end of emission we need a single linear stream of words,
// so we will eventually flatten `m_sections` into a single array.
- /// The final array of SPIR-V words that defines the encoded module
+ /// The final array of SPIR-V words that defines the encoded module
List<SpvWord> m_words;
- /// Emit the concrete words that make up the binary SPIR-V module.
- ///
- /// This function fills in `m_words` based on the data in `m_sections`.
- /// This function should only be called once.
- ///
+ /// Emit the concrete words that make up the binary SPIR-V module.
+ ///
+ /// This function fills in `m_words` based on the data in `m_sections`.
+ /// This function should only be called once.
+ ///
void emitPhysicalLayout()
{
// [2.3: Physical Layout of a SPIR-V Module and Instruction]
@@ -543,8 +554,8 @@ struct SPIRVEmitContext
//
// Once we are done emitting the header, we emit all
// the instructions in our logical sections.
- //
- for( int ii = 0; ii < int(SpvLogicalSectionID::Count); ++ii )
+ //
+ for (int ii = 0; ii < int(SpvLogicalSectionID::Count); ++ii)
{
m_sections[ii].dumpTo(m_words);
}
@@ -559,7 +570,7 @@ struct SPIRVEmitContext
// have been emitted, where a Slang IR instruction maps
// to the corresponding SPIR-V instruction.
- /// Map a Slang IR instruction to the corresponding SPIR-V instruction
+ /// Map a Slang IR instruction to the corresponding SPIR-V instruction
Dictionary<IRInst*, SpvInst*> m_mapIRInstToSpvInst;
// Sometimes we need to reserve an ID for an `IRInst` without actually
@@ -568,10 +579,10 @@ struct SPIRVEmitContext
// `IRInst` may not have been emitted.
Dictionary<IRInst*, SpvWord> m_mapIRInstToSpvID;
- // Map a Slang IR instruction to the corresponding SPIR-V debug instruction.
+ // Map a Slang IR instruction to the corresponding SPIR-V debug instruction.
Dictionary<IRInst*, SpvInst*> m_mapIRInstToSpvDebugInst;
- /// Register that `irInst` maps to `spvInst`
+ /// Register that `irInst` maps to `spvInst`
void registerInst(IRInst* irInst, SpvInst* spvInst)
{
m_mapIRInstToSpvInst.add(irInst, spvInst);
@@ -587,7 +598,7 @@ struct SPIRVEmitContext
}
}
- /// Register that `irInst` has debug info represented by `spvDebugInst`.
+ /// Register that `irInst` has debug info represented by `spvDebugInst`.
void registerDebugInst(IRInst* irInst, SpvInst* spvDebugInst)
{
m_mapIRInstToSpvDebugInst.add(irInst, spvDebugInst);
@@ -607,7 +618,7 @@ struct SPIRVEmitContext
return nullptr;
}
- /// Get or reserve a SpvID for an IR value.
+ /// Get or reserve a SpvID for an IR value.
SpvWord getIRInstSpvID(IRInst* inst)
{
// If we have already emitted an SpvInst for `inst`, return its ID.
@@ -631,16 +642,13 @@ struct SPIRVEmitContext
//
// We will allocate <id>s on emand as they are needed.
- SpvWord freshID()
- {
- return m_nextID++;
- }
+ SpvWord freshID() { return m_nextID++; }
- /// Get the <id> for `inst`, or assign one if it doesn't have one yet
+ /// Get the <id> for `inst`, or assign one if it doesn't have one yet
SpvWord getID(SpvInst* inst)
{
auto id = inst->id;
- if( !id )
+ if (!id)
{
id = freshID();
inst->id = id;
@@ -670,26 +678,24 @@ struct SPIRVEmitContext
{
SLANG_FORCE_INLINE operator SpvInst*() const { return m_inst; }
- InstConstructScope(SPIRVEmitContext* context, SpvOp opcode, IRInst* irInst = nullptr):
- m_context(context)
+ InstConstructScope(SPIRVEmitContext* context, SpvOp opcode, IRInst* irInst = nullptr)
+ : m_context(context)
{
m_context->_beginInst(opcode, irInst, *this);
}
- ~InstConstructScope()
- {
- m_context->_endInst(*this);
- }
+ ~InstConstructScope() { m_context->_endInst(*this); }
- SpvInst* m_inst; ///< The instruction associated with this scope
- SPIRVEmitContext* m_context; ///< The context
- SpvInst* m_previousInst; ///< The previously live inst
- Index m_operandsStartIndex; ///< The start index for operands of m_inst
+ SpvInst* m_inst; ///< The instruction associated with this scope
+ SPIRVEmitContext* m_context; ///< The context
+ SpvInst* m_previousInst; ///< The previously live inst
+ Index m_operandsStartIndex; ///< The start index for operands of m_inst
};
// ...If we're speculatively adding them to see if we have a memoized results
struct OperandMemoizeScope
{
- OperandMemoizeScope(SPIRVEmitContext* context) : m_context(context)
+ OperandMemoizeScope(SPIRVEmitContext* context)
+ : m_context(context)
{
m_tmpOperandStack.swapWith(m_context->m_operandStack);
std::swap(m_tmpPeeking, m_context->m_peekingOperands);
@@ -708,17 +714,17 @@ struct SPIRVEmitContext
SpvInst* m_tmpInst = nullptr;
};
- /// Holds memory for instructions and operands.
+ /// Holds memory for instructions and operands.
MemoryArena m_memoryArena;
- /// Begin emitting an instruction with the given SPIR-V `opcode`.
- ///
- /// If `irInst` is non-null, then the resulting SPIR-V instruction
- /// will be registered as corresponding to `irInst`.
- ///
- /// The created instruction is stored in m_currentInst.
- ///
- /// Should not typically be called directly use InstConstructScope to scope construction
+ /// Begin emitting an instruction with the given SPIR-V `opcode`.
+ ///
+ /// If `irInst` is non-null, then the resulting SPIR-V instruction
+ /// will be registered as corresponding to `irInst`.
+ ///
+ /// The created instruction is stored in m_currentInst.
+ ///
+ /// Should not typically be called directly use InstConstructScope to scope construction
void _beginInst(SpvOp opcode, IRInst* irInst, InstConstructScope& ioScope)
{
SLANG_ASSERT(this == ioScope.m_context);
@@ -727,7 +733,7 @@ struct SPIRVEmitContext
auto spvInst = new (m_memoryArena.allocate(sizeof(SpvInst))) SpvInst();
spvInst->opcode = opcode;
- if(irInst)
+ if (irInst)
{
registerInst(irInst, spvInst);
}
@@ -741,8 +747,8 @@ struct SPIRVEmitContext
m_currentInst = spvInst;
}
- /// End emitting an instruction
- /// Should not typically be called directly use InstConstructScope to scope construction
+ /// End emitting an instruction
+ /// Should not typically be called directly use InstConstructScope to scope construction
void _endInst(const InstConstructScope& scope)
{
SLANG_ASSERT(scope.m_inst == m_currentInst);
@@ -751,11 +757,13 @@ struct SPIRVEmitContext
// Work out how many operands were added
const Index operandsCount = m_operandStack.getCount() - operandsStartIndex;
-
+
if (operandsCount)
{
// Allocate the operands
- m_currentInst->operandWords = m_memoryArena.allocateAndCopyArray(m_operandStack.getBuffer() + operandsStartIndex, operandsCount);
+ m_currentInst->operandWords = m_memoryArena.allocateAndCopyArray(
+ m_operandStack.getBuffer() + operandsStartIndex,
+ operandsCount);
// Set the count
m_currentInst->operandWordsCount = uint32_t(operandsCount);
}
@@ -795,7 +803,7 @@ struct SPIRVEmitContext
// The simplest case is when an instruction takes an operand
// that is just a literal SPIR-V word.
- /// Emit a literal `word` as an operand to the current instruction
+ /// Emit a literal `word` as an operand to the current instruction
void emitOperand(SpvWord word)
{
// Can only add operands if we are constructing an instruction (ie in _beginInst/_endInst)
@@ -809,11 +817,8 @@ struct SPIRVEmitContext
// the same. If we have a `SpvInst` we can look up or
// generate an <id> for it.
- /// Emit an operand to the current instruction, which references `src` by its <id>
- void emitOperand(SpvInst* src)
- {
- emitOperand(getID(src));
- }
+ /// Emit an operand to the current instruction, which references `src` by its <id>
+ void emitOperand(SpvInst* src) { emitOperand(getID(src)); }
// Commonly, we will have an operand in the form of an `IRInst`
// which might either represent an instruction we've already
@@ -821,7 +826,7 @@ struct SPIRVEmitContext
// or which we have yet to emit (because it is a global-scope
// instruction that has not been referenced before).
- /// Emit an operand to the current instruction, which references `src` by its <id>
+ /// Emit an operand to the current instruction, which references `src` by its <id>
void emitOperand(IRInst* src)
{
SpvInst* spvSrc = ensureInst(src);
@@ -832,7 +837,7 @@ struct SPIRVEmitContext
// which requires us to follow the SPIR-V rules to
// encode the string into multiple operand words.
- /// Emit an operand that is encoded as a literal string
+ /// Emit an operand that is encoded as a literal string
void emitOperand(UnownedStringSlice const& text)
{
// Can only emitOperands if we are in an instruction
@@ -850,7 +855,10 @@ struct SPIRVEmitContext
// have access to the `SpvInst` that will get the <id>.
// We will use a dummy `enum` type to support this case.
- enum ResultIDToken { kResultID };
+ enum ResultIDToken
+ {
+ kResultID
+ };
void emitOperand(ResultIDToken)
{
@@ -864,41 +872,41 @@ struct SPIRVEmitContext
void emitOperand(const SpvLiteralBits& bits)
{
- for(const auto v : bits.value)
+ for (const auto v : bits.value)
emitOperand(v);
}
void emitOperand(const SpvLiteralInteger& integer)
{
- for(const auto v : integer.value)
+ for (const auto v : integer.value)
emitOperand(v);
}
template<typename T>
void emitOperand(const List<T>& os)
{
- for(const auto& o : os)
+ for (const auto& o : os)
emitOperand(o);
}
template<typename T>
void emitOperand(const IROperandList<T>& os)
{
- for(const auto& o : os)
+ for (const auto& o : os)
emitOperand(o);
}
template<typename T, Index N>
void emitOperand(const Array<T, N>& os)
{
- for(const auto& o : os)
+ for (const auto& o : os)
emitOperand(o);
}
template<typename T>
void emitOperand(const ArrayView<T>& os)
{
- for(const auto& o : os)
+ for (const auto& o : os)
emitOperand(o);
}
@@ -925,40 +933,40 @@ struct SPIRVEmitContext
switch (type->getOp())
{
case kIROp_DoubleType:
- {
- if (auto fval = as<IRFloatLit>(inst))
- return SpvLiteralBits::from64(DoubleAsInt64(fval->getValue()));
- break;
- }
+ {
+ if (auto fval = as<IRFloatLit>(inst))
+ return SpvLiteralBits::from64(DoubleAsInt64(fval->getValue()));
+ break;
+ }
case kIROp_HalfType:
- {
- if (auto fval = as<IRFloatLit>(inst))
- return SpvLiteralBits::from32(uint32_t(FloatToHalf((float)fval->getValue())));
- break;
- }
+ {
+ if (auto fval = as<IRFloatLit>(inst))
+ return SpvLiteralBits::from32(uint32_t(FloatToHalf((float)fval->getValue())));
+ break;
+ }
case kIROp_FloatType:
- {
- if (auto fval = as<IRFloatLit>(inst))
- return SpvLiteralBits::from32(FloatAsInt((float)fval->getValue()));
- break;
- }
+ {
+ if (auto fval = as<IRFloatLit>(inst))
+ return SpvLiteralBits::from32(FloatAsInt((float)fval->getValue()));
+ break;
+ }
case kIROp_Int64Type:
case kIROp_UInt64Type:
#if SLANG_PTR_IS_64
case kIROp_PtrType:
case kIROp_UIntPtrType:
#endif
- {
- if (auto val = as<IRIntLit>(inst))
- return SpvLiteralBits::from64(uint64_t(val->getValue()));
- break;
- }
+ {
+ if (auto val = as<IRIntLit>(inst))
+ return SpvLiteralBits::from64(uint64_t(val->getValue()));
+ break;
+ }
default:
- {
- if (auto val = as<IRIntLit>(inst))
- return SpvLiteralBits::from32(uint32_t(val->getValue()));
- break;
- }
+ {
+ if (auto val = as<IRIntLit>(inst))
+ return SpvLiteralBits::from32(uint32_t(val->getValue()));
+ break;
+ }
}
return SpvLiteralBits::from32(0);
}
@@ -982,23 +990,15 @@ struct SPIRVEmitContext
case kIROp_PtrType:
case kIROp_UIntPtrType:
#endif
- {
- result = emitOpConstant(
- inst,
- type,
- SpvLiteralBits::from64(uint64_t(val))
- );
- break;
- }
+ {
+ result = emitOpConstant(inst, type, SpvLiteralBits::from64(uint64_t(val)));
+ break;
+ }
default:
- {
- result = emitOpConstant(
- inst,
- type,
- SpvLiteralBits::from32(uint32_t(val))
- );
- break;
- }
+ {
+ result = emitOpConstant(inst, type, SpvLiteralBits::from32(uint32_t(val)));
+ break;
+ }
}
m_spvIntConstants[key] = result;
m_mapIRInstToSpvInst[inst] = result;
@@ -1017,19 +1017,17 @@ struct SPIRVEmitContext
}
if (type->getOp() == kIROp_DoubleType)
{
- result = emitOpConstant(
- inst,
- type,
- SpvLiteralBits::from64(uint64_t(DoubleAsInt64(val))));
+ result =
+ emitOpConstant(inst, type, SpvLiteralBits::from64(uint64_t(DoubleAsInt64(val))));
}
- else if(type->getOp() == kIROp_FloatType)
+ else if (type->getOp() == kIROp_FloatType)
{
result = emitOpConstant(
inst,
type,
SpvLiteralBits::from32(uint32_t(FloatAsInt(float(val)))));
}
- else if(type->getOp() == kIROp_HalfType)
+ else if (type->getOp() == kIROp_HalfType)
{
result = emitOpConstant(
inst,
@@ -1045,24 +1043,24 @@ struct SPIRVEmitContext
return result;
}
- /// Emit operand words for all the operands of a given IR instruction
+ /// Emit operand words for all the operands of a given IR instruction
void emitOperand(OperandsOf const& other)
{
auto irInst = other.irInst;
auto operandCount = irInst->getOperandCount();
- for( UInt ii = 0; ii < operandCount; ++ii )
+ for (UInt ii = 0; ii < operandCount; ++ii)
{
emitOperand(irInst->getOperand(ii));
}
}
- /// Do nothing
- void emitOperand(SkipThisOptionalOperand) { }
+ /// Do nothing
+ void emitOperand(SkipThisOptionalOperand) {}
template<typename T>
void emitOperand(OptionalOperand<T> o)
{
- if(o.present)
+ if (o.present)
emitOperand(o.value);
}
@@ -1082,18 +1080,21 @@ struct SPIRVEmitContext
// encouraged to use these instead.
//
template<typename... Operands>
- SpvInst* emitInst(SpvInstParent* parent, IRInst* irInst, SpvOp opcode, const Operands& ...ops)
+ SpvInst* emitInst(SpvInstParent* parent, IRInst* irInst, SpvOp opcode, const Operands&... ops)
{
return emitInstCustomOperandFunc(
parent,
irInst,
opcode,
- [&](){(emitOperand(ops), ...);}
- );
+ [&]() { (emitOperand(ops), ...); });
}
template<typename OperandEmitFunc>
- SpvInst* emitInstCustomOperandFunc(SpvInstParent* parent, IRInst* irInst, SpvOp opcode, const OperandEmitFunc& f)
+ SpvInst* emitInstCustomOperandFunc(
+ SpvInstParent* parent,
+ IRInst* irInst,
+ SpvOp opcode,
+ const OperandEmitFunc& f)
{
InstConstructScope scopeInst(this, opcode, irInst);
SpvInst* spvInst = scopeInst;
@@ -1113,16 +1114,14 @@ struct SPIRVEmitContext
// We take the resultId here explicitly here to make sure we don't try
// and memoize its value.
ResultIDToken resultId,
- const Operands& ...ops
- )
+ const Operands&... ops)
{
return emitInstMemoizedCustomOperandFunc(
parent,
irInst,
opcode,
resultId,
- [&](){(emitOperand(ops), ...);}
- );
+ [&]() { (emitOperand(ops), ...); });
}
template<typename OperandEmitFunc>
@@ -1133,8 +1132,7 @@ struct SPIRVEmitContext
// We take the resultId here explicitly here to make sure we don't try
// and memoize its value.
ResultIDToken resultId,
- const OperandEmitFunc& f
- )
+ const OperandEmitFunc& f)
{
List<SpvWord> ourOperands;
{
@@ -1182,8 +1180,7 @@ struct SPIRVEmitContext
SpvInstParent* parent,
IRInst* irInst,
SpvOp opcode,
- const OperandEmitFunc& f
- )
+ const OperandEmitFunc& f)
{
List<SpvWord> ourOperands;
{
@@ -1217,13 +1214,13 @@ struct SPIRVEmitContext
// Specific emit funcs
//
-# define SLANG_IN_SPIRV_EMIT_CONTEXT
-# include "slang-emit-spirv-ops.h"
- #include "slang-emit-spirv-ops-debug-info-ext.h"
-# undef SLANG_IN_SPIRV_EMIT_CONTEXT
+#define SLANG_IN_SPIRV_EMIT_CONTEXT
+#include "slang-emit-spirv-ops-debug-info-ext.h"
+#include "slang-emit-spirv-ops.h"
+#undef SLANG_IN_SPIRV_EMIT_CONTEXT
- /// The SPIRV OpExtInstImport inst that represents the GLSL450
- /// extended instruction set.
+ /// The SPIRV OpExtInstImport inst that represents the GLSL450
+ /// extended instruction set.
SpvInst* m_glsl450ExtInst = nullptr;
SpvInst* getGLSL450ExtInst()
@@ -1272,50 +1269,30 @@ struct SPIRVEmitContext
SLANG_EXHAUSTIVE_SWITCH_BEGIN
switch (addrSpace)
{
- case AddressSpace::Generic:
- return SpvStorageClassMax;
- case AddressSpace::ThreadLocal:
- return SpvStorageClassPrivate;
- case AddressSpace::GroupShared:
- return SpvStorageClassWorkgroup;
- case AddressSpace::Uniform:
- return SpvStorageClassUniform;
- case AddressSpace::Input:
- return SpvStorageClassInput;
- case AddressSpace::Output:
- return SpvStorageClassOutput;
- case AddressSpace::TaskPayloadWorkgroup:
- return SpvStorageClassTaskPayloadWorkgroupEXT;
- case AddressSpace::Function:
- return SpvStorageClassFunction;
- case AddressSpace::StorageBuffer:
- return SpvStorageClassStorageBuffer;
- case AddressSpace::PushConstant:
- return SpvStorageClassPushConstant;
- case AddressSpace::RayPayloadKHR:
- return SpvStorageClassRayPayloadKHR;
- case AddressSpace::IncomingRayPayload:
- return SpvStorageClassIncomingRayPayloadKHR;
- case AddressSpace::CallableDataKHR:
- return SpvStorageClassCallableDataKHR;
- case AddressSpace::IncomingCallableData:
- return SpvStorageClassIncomingCallableDataKHR;
- case AddressSpace::HitObjectAttribute:
- return SpvStorageClassHitObjectAttributeNV;
- case AddressSpace::HitAttribute:
- return SpvStorageClassHitAttributeKHR;
- case AddressSpace::ShaderRecordBuffer:
- return SpvStorageClassShaderRecordBufferKHR;
- case AddressSpace::UniformConstant:
- return SpvStorageClassUniformConstant;
- case AddressSpace::Image:
- return SpvStorageClassImage;
- case AddressSpace::UserPointer:
- return SpvStorageClassPhysicalStorageBuffer;
+ case AddressSpace::Generic: return SpvStorageClassMax;
+ case AddressSpace::ThreadLocal: return SpvStorageClassPrivate;
+ case AddressSpace::GroupShared: return SpvStorageClassWorkgroup;
+ case AddressSpace::Uniform: return SpvStorageClassUniform;
+ case AddressSpace::Input: return SpvStorageClassInput;
+ case AddressSpace::Output: return SpvStorageClassOutput;
+ case AddressSpace::TaskPayloadWorkgroup: return SpvStorageClassTaskPayloadWorkgroupEXT;
+ case AddressSpace::Function: return SpvStorageClassFunction;
+ case AddressSpace::StorageBuffer: return SpvStorageClassStorageBuffer;
+ case AddressSpace::PushConstant: return SpvStorageClassPushConstant;
+ case AddressSpace::RayPayloadKHR: return SpvStorageClassRayPayloadKHR;
+ case AddressSpace::IncomingRayPayload: return SpvStorageClassIncomingRayPayloadKHR;
+ case AddressSpace::CallableDataKHR: return SpvStorageClassCallableDataKHR;
+ case AddressSpace::IncomingCallableData: return SpvStorageClassIncomingCallableDataKHR;
+ case AddressSpace::HitObjectAttribute: return SpvStorageClassHitObjectAttributeNV;
+ case AddressSpace::HitAttribute: return SpvStorageClassHitAttributeKHR;
+ case AddressSpace::ShaderRecordBuffer: return SpvStorageClassShaderRecordBufferKHR;
+ case AddressSpace::UniformConstant: return SpvStorageClassUniformConstant;
+ case AddressSpace::Image: return SpvStorageClassImage;
+ case AddressSpace::UserPointer: return SpvStorageClassPhysicalStorageBuffer;
case AddressSpace::Global:
case AddressSpace::MetalObjectData:
case AddressSpace::SpecializationConstant:
- // msvc is limiting us from putting the UNEXPECTED macro here, so
+ // msvc is limiting us from putting the UNEXPECTED macro here, so
// just fall out
;
}
@@ -1332,8 +1309,8 @@ struct SPIRVEmitContext
// which do not directly relate to any instruction in the
// Slang IR.
- /// Emit the mandatory "front-matter" instructions that
- /// the SPIR-V module must include to make it usable.
+ /// Emit the mandatory "front-matter" instructions that
+ /// the SPIR-V module must include to make it usable.
void emitFrontMatter()
{
// TODO: We should ideally add SPIR-V capabilities to
@@ -1344,8 +1321,7 @@ struct SPIRVEmitContext
emitOpCapability(
getSection(SpvLogicalSectionID::Capabilities),
nullptr,
- SpvCapabilityShader
- );
+ SpvCapabilityShader);
// [2.4: Logical Layout of a Module]
//
@@ -1365,8 +1341,7 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::MemoryModel),
nullptr,
m_addressingMode,
- SpvMemoryModelGLSL450
- );
+ SpvMemoryModelGLSL450);
}
IRInst* m_defaultDebugSource = nullptr;
@@ -1377,11 +1352,7 @@ struct SPIRVEmitContext
SpvInst* result = nullptr;
if (m_extensionInsts.tryGetValue(name, result))
return result;
- result = emitOpExtension(
- getSection(SpvLogicalSectionID::Extensions),
- nullptr,
- name
- );
+ result = emitOpExtension(getSection(SpvLogicalSectionID::Extensions), nullptr, name);
m_extensionInsts[name] = result;
return result;
}
@@ -1429,7 +1400,8 @@ struct SPIRVEmitContext
bool shouldEmitSPIRVReflectionInfo()
{
- return m_targetProgram->getOptionSet().getBoolOption(CompilerOptionName::VulkanEmitReflection);
+ return m_targetProgram->getOptionSet().getBoolOption(
+ CompilerOptionName::VulkanEmitReflection);
}
void requirePhysicalStorageAddressing()
@@ -1444,21 +1416,22 @@ struct SPIRVEmitContext
// Next, let's look at emitting some of the instructions
// that can occur at global scope.
- /// Emit an instruction that is expected to appear at the global scope of the SPIR-V module.
- ///
- /// Returns the corresponding SPIR-V instruction.
- ///
+ /// Emit an instruction that is expected to appear at the global scope of the SPIR-V module.
+ ///
+ /// Returns the corresponding SPIR-V instruction.
+ ///
SpvInst* emitGlobalInst(IRInst* inst)
{
- switch( inst->getOp() & kIROpMask_OpMask )
+ switch (inst->getOp() & kIROpMask_OpMask)
{
- // [3.32.6: Type-Declaration Instructions]
- //
+ // [3.32.6: Type-Declaration Instructions]
+ //
case kIROp_VoidType: return emitOpTypeVoid(inst);
- case kIROp_BoolType: return emitOpTypeBool(inst);
+ case kIROp_BoolType:
+ return emitOpTypeBool(inst);
- // > OpTypeInt
+ // > OpTypeInt
case kIROp_UInt16Type:
case kIROp_Int16Type:
@@ -1479,11 +1452,10 @@ struct SPIRVEmitContext
return emitOpTypeInt(
inst,
SpvLiteralInteger::from32(int32_t(i.width)),
- SpvLiteralInteger::from32(i.isSigned)
- );
+ SpvLiteralInteger::from32(i.isSigned));
}
- // > OpTypeFloat
+ // > OpTypeFloat
case kIROp_HalfType:
case kIROp_FloatType:
@@ -1508,16 +1480,17 @@ struct SPIRVEmitContext
if (ptrType->hasAddressSpace())
storageClass = addressSpaceToStorageClass(ptrType->getAddressSpace());
if (storageClass == SpvStorageClassStorageBuffer)
- ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_storage_buffer_storage_class"));
+ ensureExtensionDeclaration(
+ UnownedStringSlice("SPV_KHR_storage_buffer_storage_class"));
if (storageClass == SpvStorageClassPhysicalStorageBuffer)
{
requirePhysicalStorageAddressing();
}
auto valueType = ptrType->getValueType();
// If we haven't emitted the inner type yet, we need to emit a forward declaration.
- bool useForwardDeclaration = (!m_mapIRInstToSpvInst.containsKey(valueType)
- && as<IRStructType>(valueType)
- && storageClass == SpvStorageClassPhysicalStorageBuffer);
+ bool useForwardDeclaration =
+ (!m_mapIRInstToSpvInst.containsKey(valueType) && as<IRStructType>(valueType) &&
+ storageClass == SpvStorageClassPhysicalStorageBuffer);
SpvId valueTypeId;
if (as<IRVoidType>(valueType))
{
@@ -1539,14 +1512,11 @@ struct SPIRVEmitContext
}
}
- auto resultSpvType = emitOpTypePointer(
- inst,
- storageClass,
- valueTypeId);
+ auto resultSpvType = emitOpTypePointer(inst, storageClass, valueTypeId);
if (useForwardDeclaration)
{
- // After everything has been emitted, we will move the pointer definition to the end
- // of the Types & Constants section.
+ // After everything has been emitted, we will move the pointer definition to the
+ // end of the Types & Constants section.
if (m_forwardDeclaredPointers.add(ptrType))
emitOpTypeForwardPointer(resultSpvType, storageClass);
}
@@ -1557,14 +1527,18 @@ struct SPIRVEmitContext
IRSizeAndAlignment sizeAndAlignment;
uint32_t stride;
- getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), valueType, &sizeAndAlignment);
+ getNaturalSizeAndAlignment(
+ m_targetProgram->getOptionSet(),
+ valueType,
+ &sizeAndAlignment);
uint64_t valueSize = sizeAndAlignment.size;
- // Any unsized data type (e.g. struct or array) will have size of kIndeterminateSize,
- // in such case the stride is invalid, so we have to provide a non-zero value to pass the
- // spirv validator.
- stride = (valueSize >= (uint64_t)sizeAndAlignment.kIndeterminateSize) ?
- 0xFFFF : (uint32_t)sizeAndAlignment.getStride();
+ // Any unsized data type (e.g. struct or array) will have size of
+ // kIndeterminateSize, in such case the stride is invalid, so we have to
+ // provide a non-zero value to pass the spirv validator.
+ stride = (valueSize >= (uint64_t)sizeAndAlignment.kIndeterminateSize)
+ ? 0xFFFF
+ : (uint32_t)sizeAndAlignment.getStride();
emitOpDecorateArrayStride(
getSection(SpvLogicalSectionID::Annotations),
nullptr,
@@ -1583,10 +1557,7 @@ struct SPIRVEmitContext
{
types.add(field->getFieldType());
}
- auto spvStructType = emitOpTypeStruct(
- inst,
- types
- );
+ auto spvStructType = emitOpTypeStruct(inst, types);
emitDecorations(inst, getID(spvStructType));
auto structType = as<IRStructType>(inst);
@@ -1599,8 +1570,9 @@ struct SPIRVEmitContext
if (structSize >= (uint64_t)IRSizeAndAlignment::kIndeterminateSize)
{
IRBuilder builder(inst);
- if ((isSpirv14OrLater() || !inst->findDecorationImpl(kIROp_SPIRVBufferBlockDecoration))
- && !inst->findDecorationImpl(kIROp_SPIRVBlockDecoration))
+ if ((isSpirv14OrLater() ||
+ !inst->findDecorationImpl(kIROp_SPIRVBufferBlockDecoration)) &&
+ !inst->findDecorationImpl(kIROp_SPIRVBlockDecoration))
{
auto decoration = builder.addDecoration(inst, kIROp_SPIRVBlockDecoration);
emitDecoration(getID(spvStructType), decoration);
@@ -1624,21 +1596,25 @@ struct SPIRVEmitContext
static_cast<IRBasicType*>(matrixType->getElementType())->getBaseType(),
static_cast<IRIntLit*>(matrixType->getColumnCount())->getValue(),
nullptr);
- const auto columnCount = static_cast<IRIntLit*>(matrixType->getRowCount())->getValue();
+ const auto columnCount =
+ static_cast<IRIntLit*>(matrixType->getRowCount())->getValue();
auto matrixSPVType = emitOpTypeMatrix(
inst,
vectorSpvType,
- SpvLiteralInteger::from32(int32_t(columnCount))
- );
+ SpvLiteralInteger::from32(int32_t(columnCount)));
return matrixSPVType;
}
case kIROp_ArrayType:
case kIROp_UnsizedArrayType:
{
const auto elementType = static_cast<IRArrayTypeBase*>(inst)->getElementType();
- const auto arrayType = inst->getOp() == kIROp_ArrayType
- ? emitOpTypeArray(inst, elementType, static_cast<IRArrayTypeBase*>(inst)->getElementCount())
- : emitOpTypeRuntimeArray(inst, elementType);
+ const auto arrayType =
+ inst->getOp() == kIROp_ArrayType
+ ? emitOpTypeArray(
+ inst,
+ elementType,
+ static_cast<IRArrayTypeBase*>(inst)->getElementCount())
+ : emitOpTypeRuntimeArray(inst, elementType);
auto strideInst = as<IRArrayTypeBase>(inst)->getArrayStride();
int stride = 0;
if (strideInst)
@@ -1648,7 +1624,10 @@ struct SPIRVEmitContext
else
{
IRSizeAndAlignment sizeAndAlignment;
- getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), elementType, &sizeAndAlignment);
+ getNaturalSizeAndAlignment(
+ m_targetProgram->getOptionSet(),
+ elementType,
+ &sizeAndAlignment);
stride = (int)sizeAndAlignment.getStride();
}
emitOpDecorateArrayStride(
@@ -1666,11 +1645,9 @@ struct SPIRVEmitContext
}
case kIROp_SubpassInputType:
return ensureSubpassInputType(inst, cast<IRSubpassInputType>(inst));
- case kIROp_TextureType:
- return ensureTextureType(inst, cast<IRTextureType>(inst));
+ case kIROp_TextureType: return ensureTextureType(inst, cast<IRTextureType>(inst));
case kIROp_SamplerStateType:
- case kIROp_SamplerComparisonStateType:
- return emitOpTypeSampler(inst);
+ case kIROp_SamplerComparisonStateType: return emitOpTypeSampler(inst);
case kIROp_RaytracingAccelerationStructureType:
requireSPIRVCapability(SpvCapabilityRayTracingKHR);
@@ -1689,7 +1666,10 @@ struct SPIRVEmitContext
case kIROp_HLSLConstBufferPointerType:
requirePhysicalStorageAddressing();
- return emitOpTypePointer(inst, SpvStorageClassPhysicalStorageBuffer, inst->getOperand(0));
+ return emitOpTypePointer(
+ inst,
+ SpvStorageClassPhysicalStorageBuffer,
+ inst->getOperand(0));
case kIROp_FuncType:
// > OpTypeFunction
@@ -1701,8 +1681,7 @@ struct SPIRVEmitContext
return emitOpTypeFunction(
inst,
static_cast<IRFuncType*>(inst)->getResultType(),
- static_cast<IRFuncType*>(inst)->getParamTypes()
- );
+ static_cast<IRFuncType*>(inst)->getParamTypes());
case kIROp_RateQualifiedType:
{
@@ -1710,7 +1689,7 @@ struct SPIRVEmitContext
registerInst(inst, result);
return result;
}
- // > OpTypeForwardPointer
+ // > OpTypeForwardPointer
case kIROp_Func:
// [3.32.6: Function Instructions]
@@ -1727,49 +1706,50 @@ struct SPIRVEmitContext
case kIROp_FloatLit:
case kIROp_StringLit:
case kIROp_PtrLit:
- {
- return emitLit(inst);
- }
+ {
+ return emitLit(inst);
+ }
case kIROp_MakeVectorFromScalar:
- {
- const auto scalar = inst->getOperand(0);
- const auto vecTy = as<IRVectorType>(inst->getDataType());
- SLANG_ASSERT(vecTy);
- const auto numElems = as<IRIntLit>(vecTy->getElementCount());
- SLANG_ASSERT(numElems);
- return emitSplat(
- getSection(SpvLogicalSectionID::ConstantsAndTypes),
- inst,
- scalar,
- numElems->getValue());
- }
+ {
+ const auto scalar = inst->getOperand(0);
+ const auto vecTy = as<IRVectorType>(inst->getDataType());
+ SLANG_ASSERT(vecTy);
+ const auto numElems = as<IRIntLit>(vecTy->getElementCount());
+ SLANG_ASSERT(numElems);
+ return emitSplat(
+ getSection(SpvLogicalSectionID::ConstantsAndTypes),
+ inst,
+ scalar,
+ numElems->getValue());
+ }
case kIROp_MakeVector:
case kIROp_MakeArray:
case kIROp_MakeStruct:
return emitCompositeConstruct(getSection(SpvLogicalSectionID::ConstantsAndTypes), inst);
case kIROp_MakeArrayFromElement:
- return emitMakeArrayFromElement(getSection(SpvLogicalSectionID::ConstantsAndTypes), inst);
+ return emitMakeArrayFromElement(
+ getSection(SpvLogicalSectionID::ConstantsAndTypes),
+ inst);
case kIROp_MakeMatrix:
return emitMakeMatrix(getSection(SpvLogicalSectionID::ConstantsAndTypes), inst);
case kIROp_MakeMatrixFromScalar:
- return emitMakeMatrixFromScalar(getSection(SpvLogicalSectionID::ConstantsAndTypes), inst);
- case kIROp_GlobalParam:
- return emitGlobalParam(as<IRGlobalParam>(inst));
- case kIROp_GlobalVar:
- return emitGlobalVar(as<IRGlobalVar>(inst));
- case kIROp_SPIRVAsmOperandBuiltinVar:
- return emitBuiltinVar(inst);
+ return emitMakeMatrixFromScalar(
+ getSection(SpvLogicalSectionID::ConstantsAndTypes),
+ inst);
+ case kIROp_GlobalParam: return emitGlobalParam(as<IRGlobalParam>(inst));
+ case kIROp_GlobalVar: return emitGlobalVar(as<IRGlobalVar>(inst));
+ case kIROp_SPIRVAsmOperandBuiltinVar: return emitBuiltinVar(inst);
case kIROp_Var:
return emitVar(getSection(SpvLogicalSectionID::GlobalVariables), inst);
- // ...
+ // ...
case kIROp_Specialize:
{
const auto s = as<IRSpecialize>(inst);
const auto g = s->getBase();
- const auto e =
- "Specialize instruction remains in IR for SPIR-V emit, is something undefined?\n" +
- dumpIRToString(g);
+ const auto e = "Specialize instruction remains in IR for SPIR-V emit, is something "
+ "undefined?\n" +
+ dumpIRToString(g);
SLANG_UNEXPECTED(e.getBuffer());
}
@@ -1788,9 +1768,10 @@ struct SPIRVEmitContext
getNonSemanticDebugInfoExtInst(),
debugSource->getFileName());
}
- // SPIRV does not allow string lits longer than 65535, so we need to split the source string
- // in OpDebugSourceContinued instructions.
- auto sourceStrHead = sourceStr.getLength() > 65535 ? sourceStr.head(65535) : sourceStr;
+ // SPIRV does not allow string lits longer than 65535, so we need to split the
+ // source string in OpDebugSourceContinued instructions.
+ auto sourceStrHead =
+ sourceStr.getLength() > 65535 ? sourceStr.head(65535) : sourceStr;
auto spvStrHead = emitInst(
getSection(SpvLogicalSectionID::DebugStringsAndSource),
nullptr,
@@ -1816,8 +1797,12 @@ struct SPIRVEmitContext
SpvOpString,
kResultID,
SpvLiteralBits::fromUnownedStringSlice(slice));
- emitOpDebugSourceContinued(getSection(SpvLogicalSectionID::ConstantsAndTypes),
- nullptr, m_voidType, getNonSemanticDebugInfoExtInst(), sliceSpvStr);
+ emitOpDebugSourceContinued(
+ getSection(SpvLogicalSectionID::ConstantsAndTypes),
+ nullptr,
+ m_voidType,
+ getNonSemanticDebugInfoExtInst(),
+ sliceSpvStr);
}
auto moduleInst = inst->getModule()->getModuleInst();
@@ -1832,33 +1817,31 @@ struct SPIRVEmitContext
moduleInst,
inst->getFullType(),
getNonSemanticDebugInfoExtInst(),
- emitIntConstant(100, builder.getUIntType()), // ExtDebugInfo version.
- emitIntConstant(5, builder.getUIntType()), // DWARF version.
+ emitIntConstant(100, builder.getUIntType()), // ExtDebugInfo version.
+ emitIntConstant(5, builder.getUIntType()), // DWARF version.
result,
- emitIntConstant(SpvSourceLanguageSlang, builder.getUIntType())); // Language.
+ emitIntConstant(
+ SpvSourceLanguageSlang,
+ builder.getUIntType())); // Language.
registerDebugInst(moduleInst, translationUnit);
}
return result;
}
- case kIROp_GetStringHash:
- return emitGetStringHash(inst);
- case kIROp_AttributedType:
- return ensureInst(as<IRAttributedType>(inst)->getBaseType());
- case kIROp_AllocateOpaqueHandle:
- return nullptr;
+ case kIROp_GetStringHash: return emitGetStringHash(inst);
+ case kIROp_AttributedType: return ensureInst(as<IRAttributedType>(inst)->getBaseType());
+ case kIROp_AllocateOpaqueHandle: return nullptr;
case kIROp_HLSLTriangleStreamType:
case kIROp_HLSLLineStreamType:
case kIROp_HLSLPointStreamType:
case kIROp_VerticesType:
case kIROp_IndicesType:
- case kIROp_PrimitivesType:
- return nullptr;
+ case kIROp_PrimitivesType: return nullptr;
default:
{
if (as<IRSPIRVAsmOperand>(inst))
return nullptr;
- String e = "Unhandled global inst in spirv-emit:\n"
- + dumpIRToString(inst, {IRDumpOptions::Mode::Detailed, 0});
+ String e = "Unhandled global inst in spirv-emit:\n" +
+ dumpIRToString(inst, {IRDumpOptions::Mode::Detailed, 0});
SLANG_UNIMPLEMENTED_X(e.begin());
}
}
@@ -1866,52 +1849,53 @@ struct SPIRVEmitContext
static SpvImageFormat getSpvImageFormat(IRTextureTypeBase* type)
{
- ImageFormat imageFormat = type->hasFormat() ? (ImageFormat)type->getFormat() : ImageFormat::unknown;
+ ImageFormat imageFormat =
+ type->hasFormat() ? (ImageFormat)type->getFormat() : ImageFormat::unknown;
switch (imageFormat)
{
- case ImageFormat::unknown: return SpvImageFormatUnknown;
- case ImageFormat::rgba32f: return SpvImageFormatRgba32f;
- case ImageFormat::rgba16f: return SpvImageFormatRgba16f;
- case ImageFormat::rg32f: return SpvImageFormatRg32f;
- case ImageFormat::rg16f: return SpvImageFormatRg16f;
- case ImageFormat::r11f_g11f_b10f: return SpvImageFormatR11fG11fB10f;
- case ImageFormat::r32f: return SpvImageFormatR32f;
- case ImageFormat::r16f: return SpvImageFormatR16f;
- case ImageFormat::rgba16: return SpvImageFormatRgba16;
- case ImageFormat::rgb10_a2: return SpvImageFormatRgb10A2;
- case ImageFormat::rgba8: return SpvImageFormatRgba8;
- case ImageFormat::rg16: return SpvImageFormatRg16;
- case ImageFormat::rg8: return SpvImageFormatRg8;
- case ImageFormat::r16: return SpvImageFormatR16;
- case ImageFormat::r8: return SpvImageFormatR8;
- case ImageFormat::rgba16_snorm: return SpvImageFormatRgba16Snorm;
- case ImageFormat::rgba8_snorm: return SpvImageFormatRgba8Snorm;
- case ImageFormat::rg16_snorm: return SpvImageFormatRg16Snorm;
- case ImageFormat::rg8_snorm: return SpvImageFormatRg8Snorm;
- case ImageFormat::r16_snorm: return SpvImageFormatR16Snorm;
- case ImageFormat::r8_snorm: return SpvImageFormatR8Snorm;
- case ImageFormat::rgba32i: return SpvImageFormatRgba32i;
- case ImageFormat::rgba16i: return SpvImageFormatRgba16i;
- case ImageFormat::rgba8i: return SpvImageFormatRgba8i;
- case ImageFormat::rg32i: return SpvImageFormatRg32i;
- case ImageFormat::rg16i: return SpvImageFormatRg16i;
- case ImageFormat::rg8i: return SpvImageFormatRg8i;
- case ImageFormat::r32i: return SpvImageFormatR32i;
- case ImageFormat::r16i: return SpvImageFormatR16i;
- case ImageFormat::r8i: return SpvImageFormatR8i;
- case ImageFormat::rgba32ui: return SpvImageFormatRgba32ui;
- case ImageFormat::rgba16ui: return SpvImageFormatRgba16ui;
- case ImageFormat::rgb10_a2ui: return SpvImageFormatRgb10a2ui;
- case ImageFormat::rgba8ui: return SpvImageFormatRgba8ui;
- case ImageFormat::rg32ui: return SpvImageFormatRg32ui;
- case ImageFormat::rg16ui: return SpvImageFormatRg16ui;
- case ImageFormat::rg8ui: return SpvImageFormatRg8ui;
- case ImageFormat::r32ui: return SpvImageFormatR32ui;
- case ImageFormat::r16ui: return SpvImageFormatR16ui;
- case ImageFormat::r8ui: return SpvImageFormatR8ui;
- case ImageFormat::r64ui: return SpvImageFormatR64ui;
- case ImageFormat::r64i: return SpvImageFormatR64i;
- default: SLANG_UNIMPLEMENTED_X("unknown image format for spirv emit");
+ case ImageFormat::unknown: return SpvImageFormatUnknown;
+ case ImageFormat::rgba32f: return SpvImageFormatRgba32f;
+ case ImageFormat::rgba16f: return SpvImageFormatRgba16f;
+ case ImageFormat::rg32f: return SpvImageFormatRg32f;
+ case ImageFormat::rg16f: return SpvImageFormatRg16f;
+ case ImageFormat::r11f_g11f_b10f: return SpvImageFormatR11fG11fB10f;
+ case ImageFormat::r32f: return SpvImageFormatR32f;
+ case ImageFormat::r16f: return SpvImageFormatR16f;
+ case ImageFormat::rgba16: return SpvImageFormatRgba16;
+ case ImageFormat::rgb10_a2: return SpvImageFormatRgb10A2;
+ case ImageFormat::rgba8: return SpvImageFormatRgba8;
+ case ImageFormat::rg16: return SpvImageFormatRg16;
+ case ImageFormat::rg8: return SpvImageFormatRg8;
+ case ImageFormat::r16: return SpvImageFormatR16;
+ case ImageFormat::r8: return SpvImageFormatR8;
+ case ImageFormat::rgba16_snorm: return SpvImageFormatRgba16Snorm;
+ case ImageFormat::rgba8_snorm: return SpvImageFormatRgba8Snorm;
+ case ImageFormat::rg16_snorm: return SpvImageFormatRg16Snorm;
+ case ImageFormat::rg8_snorm: return SpvImageFormatRg8Snorm;
+ case ImageFormat::r16_snorm: return SpvImageFormatR16Snorm;
+ case ImageFormat::r8_snorm: return SpvImageFormatR8Snorm;
+ case ImageFormat::rgba32i: return SpvImageFormatRgba32i;
+ case ImageFormat::rgba16i: return SpvImageFormatRgba16i;
+ case ImageFormat::rgba8i: return SpvImageFormatRgba8i;
+ case ImageFormat::rg32i: return SpvImageFormatRg32i;
+ case ImageFormat::rg16i: return SpvImageFormatRg16i;
+ case ImageFormat::rg8i: return SpvImageFormatRg8i;
+ case ImageFormat::r32i: return SpvImageFormatR32i;
+ case ImageFormat::r16i: return SpvImageFormatR16i;
+ case ImageFormat::r8i: return SpvImageFormatR8i;
+ case ImageFormat::rgba32ui: return SpvImageFormatRgba32ui;
+ case ImageFormat::rgba16ui: return SpvImageFormatRgba16ui;
+ case ImageFormat::rgb10_a2ui: return SpvImageFormatRgb10a2ui;
+ case ImageFormat::rgba8ui: return SpvImageFormatRgba8ui;
+ case ImageFormat::rg32ui: return SpvImageFormatRg32ui;
+ case ImageFormat::rg16ui: return SpvImageFormatRg16ui;
+ case ImageFormat::rg8ui: return SpvImageFormatRg8ui;
+ case ImageFormat::r32ui: return SpvImageFormatR32ui;
+ case ImageFormat::r16ui: return SpvImageFormatR16ui;
+ case ImageFormat::r8ui: return SpvImageFormatR8ui;
+ case ImageFormat::r64ui: return SpvImageFormatR64ui;
+ case ImageFormat::r64i: return SpvImageFormatR64i;
+ default: SLANG_UNIMPLEMENTED_X("unknown image format for spirv emit");
}
}
@@ -1926,18 +1910,16 @@ struct SPIRVEmitContext
}
// https://registry.khronos.org/vulkan/specs/1.3/html/chap37.html#VUID-StandaloneSpirv-DescriptorSet-06491
- // Only UniformConstant, Uniform or StorageBuffer storage class are allowed to be decorated with descriptor
- // set or binding.
+ // Only UniformConstant, Uniform or StorageBuffer storage class are allowed to be decorated with
+ // descriptor set or binding.
static inline bool isBindingAllowed(SpvStorageClass storageClass)
{
- switch(storageClass)
+ switch (storageClass)
{
case SpvStorageClassUniformConstant:
case SpvStorageClassUniform:
- case SpvStorageClassStorageBuffer:
- return true;
- default:
- return false;
+ case SpvStorageClassStorageBuffer: return true;
+ default: return false;
}
}
@@ -1958,17 +1940,16 @@ struct SPIRVEmitContext
case SpvImageFormatRgba32ui:
case SpvImageFormatRgba16ui:
case SpvImageFormatRgba8ui:
- case SpvImageFormatR32ui:
- return SpvCapabilityShader;
+ case SpvImageFormatR32ui: return SpvCapabilityShader;
case SpvImageFormatR64ui:
- case SpvImageFormatR64i:
- return SpvCapabilityInt64ImageEXT;
- default:
- return SpvCapabilityStorageImageExtendedFormats;
+ case SpvImageFormatR64i: return SpvCapabilityInt64ImageEXT;
+ default: return SpvCapabilityStorageImageExtendedFormats;
}
}
- void setImageFormatCapabilityAndExtension(SpvImageFormat format, SpvCapability_ setCapabilityMask)
+ void setImageFormatCapabilityAndExtension(
+ SpvImageFormat format,
+ SpvCapability_ setCapabilityMask)
{
switch (format)
{
@@ -1986,17 +1967,20 @@ struct SPIRVEmitContext
case SpvImageFormatRgba16ui:
case SpvImageFormatRgba8ui:
case SpvImageFormatR32ui:
- if(setCapabilityMask == SpvCapabilityShader) return;
+ if (setCapabilityMask == SpvCapabilityShader)
+ return;
requireSPIRVCapability(SpvCapabilityShader);
return;
case SpvImageFormatR64ui:
case SpvImageFormatR64i:
- if(setCapabilityMask == SpvCapabilityInt64ImageEXT) return;
+ if (setCapabilityMask == SpvCapabilityInt64ImageEXT)
+ return;
ensureExtensionDeclaration(UnownedStringSlice("SPV_EXT_shader_image_int64"));
requireSPIRVCapability(SpvCapabilityInt64ImageEXT);
return;
default:
- if(setCapabilityMask == SpvCapabilityStorageImageExtendedFormats) return;
+ if (setCapabilityMask == SpvCapabilityStorageImageExtendedFormats)
+ return;
requireSPIRVCapability(SpvCapabilityStorageImageExtendedFormats);
return;
}
@@ -2025,7 +2009,8 @@ struct SPIRVEmitContext
sampledUnknown = 0,
// indicates an image compatible with sampling operations
sampledImage = 1,
- // indicates an image compatible with read/write operations (a storage or subpass data image).
+ // indicates an image compatible with read/write operations (a storage or subpass data
+ // image).
readWriteImage = 2,
// indicates single-sampled content
@@ -2039,8 +2024,9 @@ struct SPIRVEmitContext
{
IRInst* sampledType = inst->getElementType();
SpvDim dim = SpvDimSubpassData;
- SpvWord ms = inst->isMultisample() ? ImageOpConstants::isMultisampled : ImageOpConstants::notMultisampled;
- SpvWord sampled = 2;
+ SpvWord ms = inst->isMultisample() ? ImageOpConstants::isMultisampled
+ : ImageOpConstants::notMultisampled;
+ SpvWord sampled = 2;
requireSPIRVCapability(SpvCapabilityInputAttachment);
requireSPIRVCapability(SpvCapabilityStorageImageReadWithoutFormat);
setImageFormatCapabilityAndExtension(SpvImageFormatUnknown, SpvCapabilityShader);
@@ -2052,49 +2038,41 @@ struct SPIRVEmitContext
SpvLiteralInteger::from32(0),
SpvLiteralInteger::from32(ms),
SpvLiteralInteger::from32(sampled),
- SpvImageFormatUnknown
- );
+ SpvImageFormatUnknown);
}
SpvInst* ensureTextureType(IRInst* assignee, IRTextureTypeBase* inst)
{
IRInst* sampledType = inst->getElementType();
SpvDim dim = SpvDim1D; // Silence uninitialized warnings from msvc...
- switch(inst->GetBaseShape())
+ switch (inst->GetBaseShape())
{
- case SLANG_TEXTURE_1D:
- dim = SpvDim1D;
- break;
- case SLANG_TEXTURE_2D:
- dim = SpvDim2D;
- break;
- case SLANG_TEXTURE_3D:
- dim = SpvDim3D;
- break;
- case SLANG_TEXTURE_CUBE:
- dim = SpvDimCube;
- break;
- case SLANG_TEXTURE_BUFFER:
- dim = SpvDimBuffer;
- break;
+ case SLANG_TEXTURE_1D: dim = SpvDim1D; break;
+ case SLANG_TEXTURE_2D: dim = SpvDim2D; break;
+ case SLANG_TEXTURE_3D: dim = SpvDim3D; break;
+ case SLANG_TEXTURE_CUBE: dim = SpvDimCube; break;
+ case SLANG_TEXTURE_BUFFER: dim = SpvDimBuffer; break;
}
- SpvWord arrayed = inst->isArray() ? ImageOpConstants::isArrayed : ImageOpConstants::notArrayed;
+ SpvWord arrayed =
+ inst->isArray() ? ImageOpConstants::isArrayed : ImageOpConstants::notArrayed;
// Vulkan spec 16.1: "The “Depth” operand of OpTypeImage is ignored."
- SpvWord depth = ImageOpConstants::unknownDepthImage; // No knowledge of if this is a depth image
- SpvWord ms = inst->isMultisample() ? ImageOpConstants::isMultisampled : ImageOpConstants::notMultisampled;
+ SpvWord depth =
+ ImageOpConstants::unknownDepthImage; // No knowledge of if this is a depth image
+ SpvWord ms = inst->isMultisample() ? ImageOpConstants::isMultisampled
+ : ImageOpConstants::notMultisampled;
SpvWord sampled = ImageOpConstants::sampledUnknown;
- switch(inst->getAccess())
+ switch (inst->getAccess())
{
- case SlangResourceAccess::SLANG_RESOURCE_ACCESS_READ_WRITE:
- case SlangResourceAccess::SLANG_RESOURCE_ACCESS_RASTER_ORDERED:
- sampled = ImageOpConstants::readWriteImage;
- break;
- case SlangResourceAccess::SLANG_RESOURCE_ACCESS_NONE:
- case SlangResourceAccess::SLANG_RESOURCE_ACCESS_READ:
- sampled = ImageOpConstants::sampledImage;
- break;
+ case SlangResourceAccess::SLANG_RESOURCE_ACCESS_READ_WRITE:
+ case SlangResourceAccess::SLANG_RESOURCE_ACCESS_RASTER_ORDERED:
+ sampled = ImageOpConstants::readWriteImage;
+ break;
+ case SlangResourceAccess::SLANG_RESOURCE_ACCESS_NONE:
+ case SlangResourceAccess::SLANG_RESOURCE_ACCESS_READ:
+ sampled = ImageOpConstants::sampledImage;
+ break;
}
SpvImageFormat format = getSpvImageFormat(inst);
@@ -2116,35 +2094,19 @@ struct SPIRVEmitContext
case kIROp_UNormAttr:
switch (vectorSize)
{
- case 1:
- format = SpvImageFormatR8;
- break;
- case 2:
- format = SpvImageFormatRg8;
- break;
- case 3:
- format = SpvImageFormatRgba8;
- break;
- case 4:
- format = SpvImageFormatRgba8;
- break;
+ case 1: format = SpvImageFormatR8; break;
+ case 2: format = SpvImageFormatRg8; break;
+ case 3: format = SpvImageFormatRgba8; break;
+ case 4: format = SpvImageFormatRgba8; break;
}
break;
case kIROp_SNormAttr:
switch (vectorSize)
{
- case 1:
- format = SpvImageFormatR8Snorm;
- break;
- case 2:
- format = SpvImageFormatRg8Snorm;
- break;
- case 3:
- format = SpvImageFormatRgba8Snorm;
- break;
- case 4:
- format = SpvImageFormatRgba8Snorm;
- break;
+ case 1: format = SpvImageFormatR8Snorm; break;
+ case 2: format = SpvImageFormatRg8Snorm; break;
+ case 3: format = SpvImageFormatRgba8Snorm; break;
+ case 4: format = SpvImageFormatRgba8Snorm; break;
}
break;
}
@@ -2156,44 +2118,53 @@ struct SPIRVEmitContext
// Capabilities, according to section 3.8
//
// SPIR-V requires that the sampled/rw info on the image isn't unknown
- SLANG_ASSERT(sampled == ImageOpConstants::sampledImage || sampled == ImageOpConstants::readWriteImage);
- if(ms == ImageOpConstants::isMultisampled)
+ SLANG_ASSERT(
+ sampled == ImageOpConstants::sampledImage ||
+ sampled == ImageOpConstants::readWriteImage);
+ if (ms == ImageOpConstants::isMultisampled)
requireSPIRVCapability(SpvCapabilityStorageImageMultisample);
- switch(dim)
+ switch (dim)
{
case SpvDim1D:
- requireSPIRVCapability(sampled == ImageOpConstants::sampledImage ? SpvCapabilitySampled1D : SpvCapabilityImage1D);
+ requireSPIRVCapability(
+ sampled == ImageOpConstants::sampledImage ? SpvCapabilitySampled1D
+ : SpvCapabilityImage1D);
break;
case SpvDim2D:
// Also requires Shader or Kernel, but these are a given (?)
- if(sampled == ImageOpConstants::readWriteImage && ms == ImageOpConstants::isMultisampled && arrayed == ImageOpConstants::isArrayed)
+ if (sampled == ImageOpConstants::readWriteImage &&
+ ms == ImageOpConstants::isMultisampled && arrayed == ImageOpConstants::isArrayed)
requireSPIRVCapability(SpvCapabilityImageMSArray);
break;
- case SpvDim3D:
- break;
+ case SpvDim3D: break;
case SpvDimCube:
// Requires shader also
- if(sampled == ImageOpConstants::readWriteImage && arrayed == ImageOpConstants::isArrayed)
+ if (sampled == ImageOpConstants::readWriteImage &&
+ arrayed == ImageOpConstants::isArrayed)
requireSPIRVCapability(SpvCapabilityImageCubeArray);
break;
case SpvDimRect:
- requireSPIRVCapability(sampled == ImageOpConstants::sampledImage ? SpvCapabilitySampledRect : SpvCapabilityImageRect);
+ requireSPIRVCapability(
+ sampled == ImageOpConstants::sampledImage ? SpvCapabilitySampledRect
+ : SpvCapabilityImageRect);
break;
case SpvDimBuffer:
- requireSPIRVCapability(sampled == ImageOpConstants::sampledImage ? SpvCapabilitySampledBuffer : SpvCapabilityImageBuffer);
+ requireSPIRVCapability(
+ sampled == ImageOpConstants::sampledImage ? SpvCapabilitySampledBuffer
+ : SpvCapabilityImageBuffer);
break;
case SpvDimTileImageDataEXT:
SLANG_UNIMPLEMENTED_X("OpTypeImage Capabilities for SpvDimTileImageDataEXT");
break;
}
- if(format == SpvImageFormatUnknown && sampled == ImageOpConstants::readWriteImage)
+ if (format == SpvImageFormatUnknown && sampled == ImageOpConstants::readWriteImage)
{
// TODO: It may not be necessary to have both of these
// depending on if we read or write
requireSPIRVCapability(SpvCapabilityStorageImageReadWithoutFormat);
requireSPIRVCapability(SpvCapabilityStorageImageWriteWithoutFormat);
}
-
+
setImageFormatCapabilityAndExtension(format, SpvCapabilityShader);
//
@@ -2210,11 +2181,8 @@ struct SPIRVEmitContext
SpvLiteralInteger::from32(arrayed),
SpvLiteralInteger::from32(ms),
SpvLiteralInteger::from32(sampled),
- format
- );
- return emitOpTypeSampledImage(
- assignee,
- imageType);
+ format);
+ return emitOpTypeSampledImage(assignee, imageType);
}
return emitOpTypeImage(
@@ -2225,8 +2193,7 @@ struct SPIRVEmitContext
SpvLiteralInteger::from32(arrayed),
SpvLiteralInteger::from32(ms),
SpvLiteralInteger::from32(sampled),
- format
- );
+ format);
}
// Ensures an SpvInst for the specified vector type is emitted.
@@ -2245,8 +2212,7 @@ struct SPIRVEmitContext
auto result = emitOpTypeVector(
inst,
inst->getElementType(),
- SpvLiteralInteger::from32(int32_t(elementCount))
- );
+ SpvLiteralInteger::from32(int32_t(elementCount)));
return result;
}
@@ -2255,21 +2221,35 @@ struct SPIRVEmitContext
switch (mode)
{
case IRInterpolationMode::NoInterpolation:
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), nullptr, varInst, SpvDecorationFlat);
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ nullptr,
+ varInst,
+ SpvDecorationFlat);
return true;
case IRInterpolationMode::NoPerspective:
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), nullptr, varInst, SpvDecorationNoPerspective);
- return true;
- case IRInterpolationMode::Linear:
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ nullptr,
+ varInst,
+ SpvDecorationNoPerspective);
return true;
+ case IRInterpolationMode::Linear: return true;
case IRInterpolationMode::Sample:
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), nullptr, varInst, SpvDecorationSample);
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ nullptr,
+ varInst,
+ SpvDecorationSample);
return true;
case IRInterpolationMode::Centroid:
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), nullptr, varInst, SpvDecorationCentroid);
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ nullptr,
+ varInst,
+ SpvDecorationCentroid);
return true;
- default:
- return false;
+ default: return false;
}
}
void emitSystemVarDecoration(IRInst* var, SpvInst* varInst)
@@ -2279,7 +2259,11 @@ struct SPIRVEmitContext
switch (decor->getOp())
{
case kIROp_GLSLPrimitivesRateDecoration:
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), decor, varInst, SpvDecorationPerPrimitiveEXT);
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ decor,
+ varInst,
+ SpvDecorationPerPrimitiveEXT);
break;
}
}
@@ -2300,16 +2284,14 @@ struct SPIRVEmitContext
UInt space = rr->getSpace();
switch (rr->getResourceKind())
{
- case LayoutResourceKind::Uniform:
- break;
+ case LayoutResourceKind::Uniform: break;
case LayoutResourceKind::VaryingInput:
emitOpDecorateLocation(
getSection(SpvLogicalSectionID::Annotations),
nullptr,
varInst,
- SpvLiteralInteger::from32(int32_t(index))
- );
+ SpvLiteralInteger::from32(int32_t(index)));
if (space != 0)
{
emitOpDecorateIndex(
@@ -2324,8 +2306,7 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::Annotations),
nullptr,
varInst,
- SpvLiteralInteger::from32(int32_t(index))
- );
+ SpvLiteralInteger::from32(int32_t(index)));
if (space != 0)
{
emitOpDecorateIndex(
@@ -2341,8 +2322,7 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::Annotations),
nullptr,
varInst,
- SpvLiteralInteger::from32(int32_t(index))
- );
+ SpvLiteralInteger::from32(int32_t(index)));
break;
case LayoutResourceKind::ConstantBuffer:
@@ -2394,12 +2374,10 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::Annotations),
nullptr,
varInst,
- SpvLiteralInteger::from32((int32_t)index)
- );
+ SpvLiteralInteger::from32((int32_t)index));
}
break;
- default:
- break;
+ default: break;
}
}
if (needDefaultSetBindingDecoration && !hasExplicitSetBinding && !isDescirptorSetDecorated)
@@ -2420,13 +2398,16 @@ struct SPIRVEmitContext
{
// Only emit a default `flat` for fragment
// stage varying inputs.
- if (layout
- && layout->getStage() == Stage::Fragment
- && layout->usesResourceKind(LayoutResourceKind::VaryingInput))
+ if (layout && layout->getStage() == Stage::Fragment &&
+ layout->usesResourceKind(LayoutResourceKind::VaryingInput))
{
const auto ptrType = as<IRPtrTypeBase>(var->getDataType());
if (ptrType && isIntegralScalarOrCompositeType(ptrType->getValueType()))
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), nullptr, varInst, SpvDecorationFlat);
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ nullptr,
+ varInst,
+ SpvDecorationFlat);
}
}
@@ -2435,10 +2416,15 @@ struct SPIRVEmitContext
switch (decor->getOp())
{
case kIROp_GLSLPrimitivesRateDecoration:
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), decor, varInst, SpvDecorationPerPrimitiveEXT);
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ decor,
+ varInst,
+ SpvDecorationPerPrimitiveEXT);
break;
case kIROp_RequireSPIRVDescriptorIndexingExtensionDecoration:
- ensureExtensionDeclarationBeforeSpv15(UnownedStringSlice("SPV_EXT_descriptor_indexing"));
+ ensureExtensionDeclarationBeforeSpv15(
+ UnownedStringSlice("SPV_EXT_descriptor_indexing"));
requireSPIRVCapability(SpvCapabilityRuntimeDescriptorArray);
break;
}
@@ -2449,11 +2435,15 @@ struct SPIRVEmitContext
{
if (auto nameDecor = irInst->findDecoration<IRNameHintDecoration>())
{
- emitOpName(getSection(SpvLogicalSectionID::DebugNames), nullptr, spvInst, nameDecor->getName());
+ emitOpName(
+ getSection(SpvLogicalSectionID::DebugNames),
+ nullptr,
+ spvInst,
+ nameDecor->getName());
}
}
- /// Emit a specialization constant.
+ /// Emit a specialization constant.
SpvInst* emitSpecializationConstant(IRGlobalParam* param, IRVarOffsetAttr* offset)
{
IRInst* defaultVal = nullptr;
@@ -2524,7 +2514,7 @@ struct SPIRVEmitContext
return result;
}
- /// Emit a global parameter definition.
+ /// Emit a global parameter definition.
SpvInst* emitGlobalParam(IRGlobalParam* param)
{
auto layout = getVarLayout(param);
@@ -2551,8 +2541,7 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::GlobalVariables),
param,
param->getDataType(),
- storageClass
- );
+ storageClass);
maybeEmitPointerDecoration(varInst, param);
if (layout)
emitVarLayout(param, varInst, layout);
@@ -2560,7 +2549,7 @@ struct SPIRVEmitContext
return varInst;
}
- /// Emit a global variable definition.
+ /// Emit a global variable definition.
SpvInst* emitGlobalVar(IRGlobalVar* globalVar)
{
auto layout = getVarLayout(globalVar);
@@ -2574,10 +2563,9 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::GlobalVariables),
globalVar,
globalVar->getDataType(),
- storageClass
- );
+ storageClass);
maybeEmitPointerDecoration(varInst, globalVar);
- if(layout)
+ if (layout)
emitVarLayout(globalVar, varInst, layout);
emitDecorations(globalVar, getID(varInst));
return varInst;
@@ -2588,7 +2576,10 @@ struct SPIRVEmitContext
const auto kind = (SpvBuiltIn)(getIntVal(spvAsmBuiltinVar->getOperand(0)));
IRBuilder builder(spvAsmBuiltinVar);
builder.setInsertBefore(spvAsmBuiltinVar);
- auto varInst = getBuiltinGlobalVar(builder.getPtrType(kIROp_PtrType, spvAsmBuiltinVar->getDataType(), AddressSpace::Input), kind, spvAsmBuiltinVar);
+ auto varInst = getBuiltinGlobalVar(
+ builder.getPtrType(kIROp_PtrType, spvAsmBuiltinVar->getDataType(), AddressSpace::Input),
+ kind,
+ spvAsmBuiltinVar);
registerInst(spvAsmBuiltinVar, varInst);
return varInst;
}
@@ -2597,7 +2588,9 @@ struct SPIRVEmitContext
{
StringBuilder sb;
sb << "-target spirv ";
- m_targetProgram->getOptionSet().writeCommandLineArgs(m_targetProgram->getTargetReq()->getSession(), sb);
+ m_targetProgram->getOptionSet().writeCommandLineArgs(
+ m_targetProgram->getTargetReq()->getSession(),
+ sb);
sb << " -stage " << getStageName(entryPointDecor->getProfile().getStage());
if (auto entryPointName = as<IRStringLit>(getName(entryPointDecor->getParent())))
{
@@ -2607,7 +2600,7 @@ struct SPIRVEmitContext
return sb.produceString();
}
- /// Emit the given `irFunc` to SPIR-V
+ /// Emit the given `irFunc` to SPIR-V
SpvInst* emitFunc(IRFunc* irFunc)
{
// [2.4: Logical Layout of a Module]
@@ -2622,7 +2615,7 @@ struct SPIRVEmitContext
// on whether they have a body or not, since these
// are encoded differently (and to different sections).
//
- if( isDefinition(irFunc) )
+ if (isDefinition(irFunc))
{
return emitFuncDefinition(irFunc);
}
@@ -2632,7 +2625,7 @@ struct SPIRVEmitContext
}
}
- /// Emit a declaration for the given `irFunc`
+ /// Emit a declaration for the given `irFunc`
SpvInst* emitFuncDeclaration(IRFunc* irFunc)
{
if (irFunc->findDecorationImpl(kIROp_SPIRVOpDecoration))
@@ -2645,10 +2638,10 @@ struct SPIRVEmitContext
UNREACHABLE_RETURN(nullptr);
}
- /// Emit a SPIR-V function definition for the Slang IR function `irFunc`.
+ /// Emit a SPIR-V function definition for the Slang IR function `irFunc`.
SpvInst* emitFuncDefinition(IRFunc* irFunc)
{
- if(!irFunc->getFirstBlock())
+ if (!irFunc->getFirstBlock())
m_sink->diagnose(irFunc, Diagnostics::noBlocksOrIntrinsic, "spirv");
// [2.4: Logical Layout of a Module]
@@ -2688,8 +2681,7 @@ struct SPIRVEmitContext
irFunc,
irFunc->getDataType()->getResultType(),
spvFunctionControl,
- irFunc->getDataType()
- );
+ irFunc->getDataType());
// > OpFunctionParameter
//
@@ -2697,7 +2689,7 @@ struct SPIRVEmitContext
// the parameters of a SPIR-V function must appear as direct
// children of the function instruction, and before any basic blocks.
//
- for( auto irParam : irFunc->getParams() )
+ for (auto irParam : irFunc->getParams())
{
emitParam(spvFunc, irParam);
}
@@ -2719,7 +2711,7 @@ struct SPIRVEmitContext
// the blocks in the Slang IR)
//
SpvInst* funcDebugScope = nullptr;
- for( auto irBlock : irFunc->getBlocks() )
+ for (auto irBlock : irFunc->getBlocks())
{
auto spvBlock = emitOpLabel(spvFunc, irBlock);
if (irBlock == irFunc->getFirstBlock())
@@ -2732,12 +2724,11 @@ struct SPIRVEmitContext
{
switch (inst->getOp())
{
- case kIROp_Var:
- emitLocalInst(spvBlock, inst);
- break;
+ case kIROp_Var: emitLocalInst(spvBlock, inst); break;
case kIROp_DebugVar:
- // Declare an ordinary local variable for debugDeclare association of a debug variable.
- // This variable is what we will actually write values to upon a `kIROp_DebugValue` inst.
+ // Declare an ordinary local variable for debugDeclare association
+ // of a debug variable. This variable is what we will actually write
+ // values to upon a `kIROp_DebugValue` inst.
emitDebugVarBackingLocalVarDeclaration(spvBlock, as<IRDebugVar>(inst));
break;
}
@@ -2748,7 +2739,12 @@ struct SPIRVEmitContext
}
if (funcDebugScope)
{
- emitOpDebugScope(spvBlock, nullptr, m_voidType, getNonSemanticDebugInfoExtInst(), funcDebugScope);
+ emitOpDebugScope(
+ spvBlock,
+ nullptr,
+ m_voidType,
+ getNonSemanticDebugInfoExtInst(),
+ funcDebugScope);
}
// In addition to normal basic blocks,
// all loops gets a header block.
@@ -2788,7 +2784,7 @@ struct SPIRVEmitContext
// We will defer the emit of the contents in loop header block
// until all Phi insts are emitted.
List<IRLoop*> pendingLoopInsts;
- for( auto irBlock : irFunc->getBlocks() )
+ for (auto irBlock : irFunc->getBlocks())
{
// Note: because we already created the block above,
// we can be sure that it will have been registred.
@@ -2807,7 +2803,7 @@ struct SPIRVEmitContext
emitPhi(spvBlock, irParam);
}
}
- for( auto irInst : irBlock->getOrdinaryInsts() )
+ for (auto irInst : irBlock->getOrdinaryInsts())
{
// Any instructions local to the block will be emitted as children
// of the block.
@@ -2855,7 +2851,7 @@ struct SPIRVEmitContext
return spvFunc;
}
- /// Check if a block is a loop's target block.
+ /// Check if a block is a loop's target block.
bool isLoopTargetBlock(IRInst* block, IRInst*& loopInst)
{
for (auto use = block->firstUse; use; use = use->nextUse)
@@ -2882,35 +2878,43 @@ struct SPIRVEmitContext
switch (memoryOrder)
{
case kIRMemoryOrder_Relaxed:
- return emitIntConstant(IRIntegerValue{ SpvMemorySemanticsMaskNone }, builder.getUIntType());
+ return emitIntConstant(
+ IRIntegerValue{SpvMemorySemanticsMaskNone},
+ builder.getUIntType());
case kIRMemoryOrder_Acquire:
- return emitIntConstant(IRIntegerValue{ SpvMemorySemanticsAcquireMask }, builder.getUIntType());
+ return emitIntConstant(
+ IRIntegerValue{SpvMemorySemanticsAcquireMask},
+ builder.getUIntType());
case kIRMemoryOrder_Release:
- return emitIntConstant(IRIntegerValue{ SpvMemorySemanticsReleaseMask }, builder.getUIntType());
+ return emitIntConstant(
+ IRIntegerValue{SpvMemorySemanticsReleaseMask},
+ builder.getUIntType());
case kIRMemoryOrder_AcquireRelease:
- return emitIntConstant(IRIntegerValue{ SpvMemorySemanticsAcquireReleaseMask }, builder.getUIntType());
+ return emitIntConstant(
+ IRIntegerValue{SpvMemorySemanticsAcquireReleaseMask},
+ builder.getUIntType());
case kIRMemoryOrder_SeqCst:
- return emitIntConstant(IRIntegerValue{ SpvMemorySemanticsSequentiallyConsistentMask }, builder.getUIntType());
- default:
- SLANG_UNEXPECTED("unhandled memory order");
- UNREACHABLE_RETURN(nullptr);
+ return emitIntConstant(
+ IRIntegerValue{SpvMemorySemanticsSequentiallyConsistentMask},
+ builder.getUIntType());
+ default: SLANG_UNEXPECTED("unhandled memory order"); UNREACHABLE_RETURN(nullptr);
}
}
SpvOp getSpvAtomicOp(IRInst* atomicInst, bool& outNegateOperand)
{
auto typeSelect = [&](SpvOp sop, SpvOp uop, SpvOp fop)
+ {
+ auto scalarType = getVectorElementType(atomicInst->getDataType());
+ if (isIntegralType(scalarType))
{
- auto scalarType = getVectorElementType(atomicInst->getDataType());
- if (isIntegralType(scalarType))
- {
- auto intInfo = getIntTypeInfo(scalarType);
- if (intInfo.isSigned)
- return sop;
- return uop;
- }
- return fop;
- };
+ auto intInfo = getIntTypeInfo(scalarType);
+ if (intInfo.isSigned)
+ return sop;
+ return uop;
+ }
+ return fop;
+ };
outNegateOperand = false;
switch (atomicInst->getOp())
{
@@ -2924,15 +2928,10 @@ struct SPIRVEmitContext
return typeSelect(SpvOpAtomicSMin, SpvOpAtomicUMin, SpvOpAtomicFMinEXT);
case kIROp_AtomicMax:
return typeSelect(SpvOpAtomicSMax, SpvOpAtomicUMax, SpvOpAtomicFMaxEXT);
- case kIROp_AtomicAnd:
- return SpvOpAtomicAnd;
- case kIROp_AtomicOr:
- return SpvOpAtomicOr;
- case kIROp_AtomicXor:
- return SpvOpAtomicXor;
- default:
- SLANG_UNEXPECTED("unhandled atomic op");
- UNREACHABLE_RETURN(SpvOpNop);
+ case kIROp_AtomicAnd: return SpvOpAtomicAnd;
+ case kIROp_AtomicOr: return SpvOpAtomicOr;
+ case kIROp_AtomicXor: return SpvOpAtomicXor;
+ default: SLANG_UNEXPECTED("unhandled atomic op"); UNREACHABLE_RETURN(SpvOpNop);
}
}
@@ -2942,65 +2941,65 @@ struct SPIRVEmitContext
switch (op)
{
case SpvOpAtomicFAddEXT:
- {
- switch (typeOp)
{
- case kIROp_FloatType:
- ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float_add"));
- requireSPIRVCapability(SpvCapabilityAtomicFloat32AddEXT);
- break;
- case kIROp_DoubleType:
- ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float_add"));
- requireSPIRVCapability(SpvCapabilityAtomicFloat64AddEXT);
- break;
- case kIROp_HalfType:
- ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float16_add"));
- requireSPIRVCapability(SpvCapabilityAtomicFloat16AddEXT);
- break;
- case kIROp_VectorType:
- if (as<IRVectorType>(atomicInst->getDataType())->getElementType()->getOp() == kIROp_HalfType)
+ switch (typeOp)
{
- ensureExtensionDeclaration(toSlice("VK_NV_shader_atomic_float16_vector"));
- requireSPIRVCapability(SpvCapabilityAtomicFloat16VectorNV);
+ case kIROp_FloatType:
+ ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float_add"));
+ requireSPIRVCapability(SpvCapabilityAtomicFloat32AddEXT);
+ break;
+ case kIROp_DoubleType:
+ ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float_add"));
+ requireSPIRVCapability(SpvCapabilityAtomicFloat64AddEXT);
+ break;
+ case kIROp_HalfType:
+ ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float16_add"));
+ requireSPIRVCapability(SpvCapabilityAtomicFloat16AddEXT);
+ break;
+ case kIROp_VectorType:
+ if (as<IRVectorType>(atomicInst->getDataType())->getElementType()->getOp() ==
+ kIROp_HalfType)
+ {
+ ensureExtensionDeclaration(toSlice("VK_NV_shader_atomic_float16_vector"));
+ requireSPIRVCapability(SpvCapabilityAtomicFloat16VectorNV);
+ }
+ break;
}
- break;
}
- }
- break;
+ break;
case SpvOpAtomicFMinEXT:
case SpvOpAtomicFMaxEXT:
- {
- switch (typeOp)
{
- case kIROp_FloatType:
- ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float_min_max"));
- requireSPIRVCapability(SpvCapabilityAtomicFloat32MinMaxEXT);
- break;
- case kIROp_DoubleType:
- ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float_min_max"));
- requireSPIRVCapability(SpvCapabilityAtomicFloat64MinMaxEXT);
- break;
- case kIROp_HalfType:
- ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float_min_max"));
- requireSPIRVCapability(SpvCapabilityAtomicFloat16MinMaxEXT);
- break;
- case kIROp_VectorType:
- if (as<IRVectorType>(atomicInst->getDataType())->getElementType()->getOp() == kIROp_HalfType)
+ switch (typeOp)
{
- ensureExtensionDeclaration(toSlice("VK_NV_shader_atomic_float16_vector"));
- requireSPIRVCapability(SpvCapabilityAtomicFloat16VectorNV);
+ case kIROp_FloatType:
+ ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float_min_max"));
+ requireSPIRVCapability(SpvCapabilityAtomicFloat32MinMaxEXT);
+ break;
+ case kIROp_DoubleType:
+ ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float_min_max"));
+ requireSPIRVCapability(SpvCapabilityAtomicFloat64MinMaxEXT);
+ break;
+ case kIROp_HalfType:
+ ensureExtensionDeclaration(toSlice("SPV_EXT_shader_atomic_float_min_max"));
+ requireSPIRVCapability(SpvCapabilityAtomicFloat16MinMaxEXT);
+ break;
+ case kIROp_VectorType:
+ if (as<IRVectorType>(atomicInst->getDataType())->getElementType()->getOp() ==
+ kIROp_HalfType)
+ {
+ ensureExtensionDeclaration(toSlice("VK_NV_shader_atomic_float16_vector"));
+ requireSPIRVCapability(SpvCapabilityAtomicFloat16VectorNV);
+ }
+ break;
}
- break;
}
- }
- break;
+ break;
}
switch (typeOp)
{
case kIROp_UInt64Type:
- case kIROp_Int64Type:
- requireSPIRVCapability(SpvCapabilityInt64Atomics);
- break;
+ case kIROp_Int64Type: requireSPIRVCapability(SpvCapabilityInt64Atomics); break;
}
}
@@ -3042,8 +3041,15 @@ struct SPIRVEmitContext
if (hasBackingVar)
{
- emitOpDebugDeclare(parent, nullptr, m_voidType, getNonSemanticDebugInfoExtInst(),
- spvDebugLocalVar, debugVar, getDwarfExpr(), List<SpvInst*>());
+ emitOpDebugDeclare(
+ parent,
+ nullptr,
+ m_voidType,
+ getNonSemanticDebugInfoExtInst(),
+ spvDebugLocalVar,
+ debugVar,
+ getDwarfExpr(),
+ List<SpvInst*>());
}
return spvDebugLocalVar;
@@ -3053,14 +3059,11 @@ struct SPIRVEmitContext
{
switch (type->getOp())
{
- case kIROp_UnsizedArrayType:
- return false;
- case kIROp_ArrayType:
- return isLegalType(as<IRArrayType>(type)->getElementType());
+ case kIROp_UnsizedArrayType: return false;
+ case kIROp_ArrayType: return isLegalType(as<IRArrayType>(type)->getElementType());
case kIROp_VectorType:
case kIROp_StructType:
- case kIROp_MatrixType:
- return true;
+ case kIROp_MatrixType: return true;
case kIROp_PtrType:
return as<IRPtrTypeBase>(type)->getAddressSpace() == AddressSpace::UserPointer;
default:
@@ -3088,7 +3091,8 @@ struct SPIRVEmitContext
if (sizeAlignment.size != IRSizeAndAlignment::kIndeterminateSize)
{
auto debugVarPtrType = builder.getPtrType(varType, AddressSpace::Function);
- auto actualHelperVar = emitOpVariable(parent, debugVar, debugVarPtrType, SpvStorageClassFunction);
+ auto actualHelperVar =
+ emitOpVariable(parent, debugVar, debugVarPtrType, SpvStorageClassFunction);
maybeEmitPointerDecoration(actualHelperVar, debugVar);
return actualHelperVar;
}
@@ -3103,108 +3107,64 @@ struct SPIRVEmitContext
// for local instructions they will usually emit into
// a known parent (the basic block that contains them).
- /// Emit an instruction that is local to the body of the given `parent`.
+ /// Emit an instruction that is local to the body of the given `parent`.
SpvInst* emitLocalInst(SpvInstParent* parent, IRInst* inst)
{
SpvInst* result = nullptr;
- switch( inst->getOp() )
+ switch (inst->getOp())
{
default:
{
if (as<IRSPIRVAsmOperand>(inst))
return nullptr;
- String e = "Unhandled local inst in spirv-emit:\n"
- + dumpIRToString(inst, {IRDumpOptions::Mode::Detailed, 0});
+ String e = "Unhandled local inst in spirv-emit:\n" +
+ dumpIRToString(inst, {IRDumpOptions::Mode::Detailed, 0});
SLANG_UNIMPLEMENTED_X(e.getBuffer());
}
case kIROp_Specialize:
case kIROp_MissingReturn:
case kIROp_StaticAssert:
- case kIROp_Unmodified:
- break;
- case kIROp_Var:
- result = emitVar(parent, inst);
- break;
- case kIROp_Call:
- result = emitCall(parent, static_cast<IRCall*>(inst));
- break;
- case kIROp_FieldAddress:
- result = emitFieldAddress(parent, as<IRFieldAddress>(inst));
- break;
- case kIROp_FieldExtract:
- result = emitFieldExtract(parent, as<IRFieldExtract>(inst));
- break;
+ case kIROp_Unmodified: break;
+ case kIROp_Var: result = emitVar(parent, inst); break;
+ case kIROp_Call: result = emitCall(parent, static_cast<IRCall*>(inst)); break;
+ case kIROp_FieldAddress: result = emitFieldAddress(parent, as<IRFieldAddress>(inst)); break;
+ case kIROp_FieldExtract: result = emitFieldExtract(parent, as<IRFieldExtract>(inst)); break;
case kIROp_GetElementPtr:
result = emitGetElementPtr(parent, as<IRGetElementPtr>(inst));
break;
- case kIROp_GetOffsetPtr:
- result = emitGetOffsetPtr(parent, inst);
- break;
- case kIROp_GetElement:
- result = emitGetElement(parent, as<IRGetElement>(inst));
- break;
- case kIROp_MakeStruct:
- result = emitCompositeConstruct(parent, inst);
- break;
- case kIROp_MakeArrayFromElement:
- result = emitMakeArrayFromElement(parent, inst);
- break;
- case kIROp_MakeMatrixFromScalar:
- result = emitMakeMatrixFromScalar(parent, inst);
- break;
- case kIROp_MakeMatrix:
- result = emitMakeMatrix(parent, inst);
- break;
- case kIROp_Load:
- result = emitLoad(parent, as<IRLoad>(inst));
- break;
- case kIROp_Store:
- result = emitStore(parent, as<IRStore>(inst));
- break;
+ case kIROp_GetOffsetPtr: result = emitGetOffsetPtr(parent, inst); break;
+ case kIROp_GetElement: result = emitGetElement(parent, as<IRGetElement>(inst)); break;
+ case kIROp_MakeStruct: result = emitCompositeConstruct(parent, inst); break;
+ case kIROp_MakeArrayFromElement: result = emitMakeArrayFromElement(parent, inst); break;
+ case kIROp_MakeMatrixFromScalar: result = emitMakeMatrixFromScalar(parent, inst); break;
+ case kIROp_MakeMatrix: result = emitMakeMatrix(parent, inst); break;
+ case kIROp_Load: result = emitLoad(parent, as<IRLoad>(inst)); break;
+ case kIROp_Store: result = emitStore(parent, as<IRStore>(inst)); break;
case kIROp_SwizzledStore:
result = emitSwizzledStore(parent, as<IRSwizzledStore>(inst));
break;
- case kIROp_swizzleSet:
- result = emitSwizzleSet(parent, as<IRSwizzleSet>(inst));
- break;
+ case kIROp_swizzleSet: result = emitSwizzleSet(parent, as<IRSwizzleSet>(inst)); break;
case kIROp_RWStructuredBufferGetElementPtr:
result = emitStructuredBufferGetElementPtr(parent, inst);
break;
case kIROp_StructuredBufferGetDimensions:
result = emitStructuredBufferGetDimensions(parent, inst);
break;
- case kIROp_swizzle:
- result = emitSwizzle(parent, as<IRSwizzle>(inst));
- break;
- case kIROp_IntCast:
- result = emitIntCast(parent, as<IRIntCast>(inst));
- break;
- case kIROp_FloatCast:
- result = emitFloatCast(parent, as<IRFloatCast>(inst));
- break;
+ case kIROp_swizzle: result = emitSwizzle(parent, as<IRSwizzle>(inst)); break;
+ case kIROp_IntCast: result = emitIntCast(parent, as<IRIntCast>(inst)); break;
+ case kIROp_FloatCast: result = emitFloatCast(parent, as<IRFloatCast>(inst)); break;
case kIROp_CastIntToFloat:
result = emitIntToFloatCast(parent, as<IRCastIntToFloat>(inst));
break;
case kIROp_CastFloatToInt:
result = emitFloatToIntCast(parent, as<IRCastFloatToInt>(inst));
break;
- case kIROp_CastPtrToInt:
- result = emitCastPtrToInt(parent, inst);
- break;
- case kIROp_CastPtrToBool:
- result = emitCastPtrToBool(parent, inst);
- break;
- case kIROp_CastIntToPtr:
- result = emitCastIntToPtr(parent, inst);
- break;
+ case kIROp_CastPtrToInt: result = emitCastPtrToInt(parent, inst); break;
+ case kIROp_CastPtrToBool: result = emitCastPtrToBool(parent, inst); break;
+ case kIROp_CastIntToPtr: result = emitCastIntToPtr(parent, inst); break;
case kIROp_PtrCast:
case kIROp_BitCast:
- result = emitOpBitcast(
- parent,
- inst,
- inst->getDataType(),
- inst->getOperand(0)
- );
+ result = emitOpBitcast(parent, inst, inst->getDataType(), inst->getOperand(0));
break;
case kIROp_Add:
case kIROp_Sub:
@@ -3227,9 +3187,7 @@ struct SPIRVEmitContext
case kIROp_Greater:
case kIROp_Geq:
case kIROp_Rsh:
- case kIROp_Lsh:
- result = emitArithmetic(parent, inst);
- break;
+ case kIROp_Lsh: result = emitArithmetic(parent, inst); break;
case kIROp_GlobalValueRef:
{
auto inner = ensureInst(inst->getOperand(0));
@@ -3256,33 +3214,53 @@ struct SPIRVEmitContext
{
auto parentFunc = getParentFunc(inst);
- HashSet<IRFunc*>* entryPointsUsingInst = getReferencingEntryPoints(m_referencingEntryPoints, parentFunc);
+ HashSet<IRFunc*>* entryPointsUsingInst =
+ getReferencingEntryPoints(m_referencingEntryPoints, parentFunc);
for (IRFunc* entryPoint : *entryPointsUsingInst)
{
bool isQuad = true;
IREntryPointDecoration* entryPointDecor = nullptr;
- for(auto dec : entryPoint->getDecorations())
+ for (auto dec : entryPoint->getDecorations())
{
- if(auto maybeEntryPointDecor = as<IREntryPointDecoration>(dec))
+ if (auto maybeEntryPointDecor = as<IREntryPointDecoration>(dec))
entryPointDecor = maybeEntryPointDecor;
- if(as<IRDerivativeGroupLinearDecoration>(dec))
+ if (as<IRDerivativeGroupLinearDecoration>(dec))
isQuad = false;
}
- if (!entryPointDecor || entryPointDecor->getProfile().getStage() != Stage::Compute)
+ if (!entryPointDecor ||
+ entryPointDecor->getProfile().getStage() != Stage::Compute)
continue;
- ensureExtensionDeclaration(UnownedStringSlice("SPV_NV_compute_shader_derivatives"));
- auto numThreadsDecor = entryPointDecor->findDecoration<IRNumThreadsDecoration>();
+ ensureExtensionDeclaration(
+ UnownedStringSlice("SPV_NV_compute_shader_derivatives"));
+ auto numThreadsDecor =
+ entryPointDecor->findDecoration<IRNumThreadsDecoration>();
if (isQuad)
{
- verifyComputeDerivativeGroupModifiers(this->m_sink, inst->sourceLoc, true, false, numThreadsDecor);
- requireSPIRVExecutionMode(nullptr, getIRInstSpvID(entryPoint), SpvExecutionModeDerivativeGroupQuadsNV);
+ verifyComputeDerivativeGroupModifiers(
+ this->m_sink,
+ inst->sourceLoc,
+ true,
+ false,
+ numThreadsDecor);
+ requireSPIRVExecutionMode(
+ nullptr,
+ getIRInstSpvID(entryPoint),
+ SpvExecutionModeDerivativeGroupQuadsNV);
requireSPIRVCapability(SpvCapabilityComputeDerivativeGroupQuadsNV);
}
else
{
- verifyComputeDerivativeGroupModifiers(this->m_sink, inst->sourceLoc, false, true, numThreadsDecor);
- requireSPIRVExecutionMode(nullptr, getIRInstSpvID(entryPoint), SpvExecutionModeDerivativeGroupLinearNV);
+ verifyComputeDerivativeGroupModifiers(
+ this->m_sink,
+ inst->sourceLoc,
+ false,
+ true,
+ numThreadsDecor);
+ requireSPIRVExecutionMode(
+ nullptr,
+ getIRInstSpvID(entryPoint),
+ SpvExecutionModeDerivativeGroupLinearNV);
requireSPIRVCapability(SpvCapabilityComputeDerivativeGroupLinearNV);
}
}
@@ -3298,7 +3276,8 @@ struct SPIRVEmitContext
case kIROp_discard:
if (shouldEmitDiscardAsDemote())
{
- ensureExtensionDeclarationBeforeSpv16(toSlice("SPV_EXT_demote_to_helper_invocation"));
+ ensureExtensionDeclarationBeforeSpv16(
+ toSlice("SPV_EXT_demote_to_helper_invocation"));
requireSPIRVCapability(SpvCapabilityDemoteToHelperInvocation);
result = emitOpDemoteToHelperInvocation(parent, inst);
}
@@ -3310,7 +3289,10 @@ struct SPIRVEmitContext
case kIROp_BeginFragmentShaderInterlock:
ensureExtensionDeclaration(UnownedStringSlice("SPV_EXT_fragment_shader_interlock"));
requireSPIRVCapability(SpvCapabilityFragmentShaderPixelInterlockEXT);
- requireSPIRVExecutionMode(nullptr, getIRInstSpvID(getParentFunc(inst)), SpvExecutionModePixelInterlockOrderedEXT);
+ requireSPIRVExecutionMode(
+ nullptr,
+ getIRInstSpvID(getParentFunc(inst)),
+ SpvExecutionModePixelInterlockOrderedEXT);
result = emitOpBeginInvocationInterlockEXT(parent, inst);
break;
case kIROp_EndFragmentShaderInterlock:
@@ -3342,7 +3324,7 @@ struct SPIRVEmitContext
// after everything else to ensure Phi instructions (which come
// from the actual loop target block) are emitted first.
emitOpBranch(parent, nullptr, blockId);
-
+
result = block;
break;
}
@@ -3358,8 +3340,7 @@ struct SPIRVEmitContext
ifelseInst->getCondition(),
ifelseInst->getTrueBlock(),
falseLabel ? getID(ensureInst(falseLabel)) : afterBlockID,
- makeArray<SpvLiteralInteger>()
- );
+ makeArray<SpvLiteralInteger>());
break;
}
case kIROp_Switch:
@@ -3367,31 +3348,32 @@ struct SPIRVEmitContext
auto switchInst = as<IRSwitch>(inst);
auto mergeBlockID = getIRInstSpvID(switchInst->getBreakLabel());
emitOpSelectionMerge(parent, nullptr, mergeBlockID, SpvSelectionControlMaskNone);
- result = emitInstCustomOperandFunc(parent, inst, SpvOpSwitch, [&]() {
- emitOperand(switchInst->getCondition());
- auto defaultLabel = switchInst->getDefaultLabel();
- emitOperand(defaultLabel ? getID(ensureInst(defaultLabel)) : mergeBlockID);
- for (UInt c = 0; c < switchInst->getCaseCount(); c++)
+ result = emitInstCustomOperandFunc(
+ parent,
+ inst,
+ SpvOpSwitch,
+ [&]()
{
- auto value = switchInst->getCaseValue(c);
- auto intLit = as<IRIntLit>(value);
- SLANG_ASSERT(intLit);
- emitOperand((SpvWord)intLit->getValue());
- auto caseLabel = switchInst->getCaseLabel(c);
- emitOperand(caseLabel ? getID(ensureInst(caseLabel)) : mergeBlockID);
- }
- });
+ emitOperand(switchInst->getCondition());
+ auto defaultLabel = switchInst->getDefaultLabel();
+ emitOperand(defaultLabel ? getID(ensureInst(defaultLabel)) : mergeBlockID);
+ for (UInt c = 0; c < switchInst->getCaseCount(); c++)
+ {
+ auto value = switchInst->getCaseValue(c);
+ auto intLit = as<IRIntLit>(value);
+ SLANG_ASSERT(intLit);
+ emitOperand((SpvWord)intLit->getValue());
+ auto caseLabel = switchInst->getCaseLabel(c);
+ emitOperand(caseLabel ? getID(ensureInst(caseLabel)) : mergeBlockID);
+ }
+ });
break;
}
- case kIROp_Unreachable:
- result = emitOpUnreachable(parent, inst);
- break;
+ case kIROp_Unreachable: result = emitOpUnreachable(parent, inst); break;
case kIROp_conditionalBranch:
SLANG_UNEXPECTED("Unstructured branching is not supported by SPIRV.");
break;
- case kIROp_MakeVector:
- result = emitConstruct(parent, inst);
- break;
+ case kIROp_MakeVector: result = emitConstruct(parent, inst); break;
case kIROp_MakeVectorFromScalar:
{
const auto scalar = inst->getOperand(0);
@@ -3402,94 +3384,125 @@ struct SPIRVEmitContext
result = emitSplat(parent, inst, scalar, numElems->getValue());
}
break;
- case kIROp_MakeArray:
- result = emitConstruct(parent, inst);
- break;
+ case kIROp_MakeArray: result = emitConstruct(parent, inst); break;
case kIROp_Select:
- result = emitInst(parent, inst, SpvOpSelect, inst->getFullType(), kResultID, OperandsOf(inst));
- break;
- case kIROp_DebugLine:
- result = emitDebugLine(parent, as<IRDebugLine>(inst));
- break;
- case kIROp_DebugVar:
- result = emitDebugVarDeclaration(parent, as<IRDebugVar>(inst));
- break;
- case kIROp_DebugValue:
- result = emitDebugValue(parent, as<IRDebugValue>(inst));
- break;
- case kIROp_GetStringHash:
- result = emitGetStringHash(inst);
- break;
- case kIROp_undefined:
- result = emitOpUndef(parent, inst, inst->getDataType());
- break;
- case kIROp_SPIRVAsm:
- result = emitSPIRVAsm(parent, as<IRSPIRVAsm>(inst));
- break;
- case kIROp_ImageLoad:
- result = emitImageLoad(parent, as<IRImageLoad>(inst));
- break;
- case kIROp_ImageStore:
- result = emitImageStore(parent, as<IRImageStore>(inst));
- break;
+ result = emitInst(
+ parent,
+ inst,
+ SpvOpSelect,
+ inst->getFullType(),
+ kResultID,
+ OperandsOf(inst));
+ break;
+ case kIROp_DebugLine: result = emitDebugLine(parent, as<IRDebugLine>(inst)); break;
+ case kIROp_DebugVar: result = emitDebugVarDeclaration(parent, as<IRDebugVar>(inst)); break;
+ case kIROp_DebugValue: result = emitDebugValue(parent, as<IRDebugValue>(inst)); break;
+ case kIROp_GetStringHash: result = emitGetStringHash(inst); break;
+ case kIROp_undefined: result = emitOpUndef(parent, inst, inst->getDataType()); break;
+ case kIROp_SPIRVAsm: result = emitSPIRVAsm(parent, as<IRSPIRVAsm>(inst)); break;
+ case kIROp_ImageLoad: result = emitImageLoad(parent, as<IRImageLoad>(inst)); break;
+ case kIROp_ImageStore: result = emitImageStore(parent, as<IRImageStore>(inst)); break;
case kIROp_ImageSubscript:
result = emitImageSubscript(parent, as<IRImageSubscript>(inst));
break;
case kIROp_AtomicInc:
{
IRBuilder builder{inst};
- const auto memoryScope = emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
+ const auto memoryScope =
+ emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(1));
- result = emitOpAtomicIIncrement(parent, inst, inst->getFullType(), inst->getOperand(0), memoryScope, memorySemantics);
+ result = emitOpAtomicIIncrement(
+ parent,
+ inst,
+ inst->getFullType(),
+ inst->getOperand(0),
+ memoryScope,
+ memorySemantics);
ensureAtomicCapability(inst, SpvOpAtomicIIncrement);
}
break;
case kIROp_AtomicDec:
{
- IRBuilder builder{ inst };
- const auto memoryScope = emitIntConstant(IRIntegerValue{ SpvScopeDevice }, builder.getUIntType());
+ IRBuilder builder{inst};
+ const auto memoryScope =
+ emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(1));
- result = emitOpAtomicIDecrement(parent, inst, inst->getFullType(), inst->getOperand(0), memoryScope, memorySemantics);
+ result = emitOpAtomicIDecrement(
+ parent,
+ inst,
+ inst->getFullType(),
+ inst->getOperand(0),
+ memoryScope,
+ memorySemantics);
ensureAtomicCapability(inst, SpvOpAtomicIDecrement);
}
break;
case kIROp_AtomicLoad:
{
- IRBuilder builder{ inst };
- const auto memoryScope = emitIntConstant(IRIntegerValue{ SpvScopeDevice }, builder.getUIntType());
+ IRBuilder builder{inst};
+ const auto memoryScope =
+ emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(1));
- result = emitOpAtomicLoad(parent, inst, inst->getFullType(), inst->getOperand(0), memoryScope, memorySemantics);
+ result = emitOpAtomicLoad(
+ parent,
+ inst,
+ inst->getFullType(),
+ inst->getOperand(0),
+ memoryScope,
+ memorySemantics);
ensureAtomicCapability(inst, SpvOpAtomicLoad);
}
break;
case kIROp_AtomicStore:
{
- IRBuilder builder{ inst };
- const auto memoryScope = emitIntConstant(IRIntegerValue{ SpvScopeDevice }, builder.getUIntType());
+ IRBuilder builder{inst};
+ const auto memoryScope =
+ emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(2));
- result = emitOpAtomicStore(parent, inst, inst->getOperand(0), memoryScope, memorySemantics, inst->getOperand(1));
+ result = emitOpAtomicStore(
+ parent,
+ inst,
+ inst->getOperand(0),
+ memoryScope,
+ memorySemantics,
+ inst->getOperand(1));
ensureAtomicCapability(inst, SpvOpAtomicStore);
}
break;
case kIROp_AtomicExchange:
{
- IRBuilder builder{ inst };
- const auto memoryScope = emitIntConstant(IRIntegerValue{ SpvScopeDevice }, builder.getUIntType());
+ IRBuilder builder{inst};
+ const auto memoryScope =
+ emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(2));
- result = emitOpAtomicExchange(parent, inst, inst->getFullType(), inst->getOperand(0), memoryScope, memorySemantics, inst->getOperand(1));
+ result = emitOpAtomicExchange(
+ parent,
+ inst,
+ inst->getFullType(),
+ inst->getOperand(0),
+ memoryScope,
+ memorySemantics,
+ inst->getOperand(1));
ensureAtomicCapability(inst, SpvOpAtomicExchange);
}
break;
case kIROp_AtomicCompareExchange:
{
- IRBuilder builder{ inst };
- const auto memoryScope = emitIntConstant(IRIntegerValue{ SpvScopeDevice }, builder.getUIntType());
+ IRBuilder builder{inst};
+ const auto memoryScope =
+ emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
const auto memorySemanticsEqual = emitMemorySemanticMask(inst->getOperand(3));
const auto memorySemanticsUnequal = emitMemorySemanticMask(inst->getOperand(4));
result = emitOpAtomicCompareExchange(
- parent, inst, inst->getFullType(), inst->getOperand(0),
- memoryScope, memorySemanticsEqual, memorySemanticsUnequal,
- inst->getOperand(2), inst->getOperand(1));
+ parent,
+ inst,
+ inst->getFullType(),
+ inst->getOperand(0),
+ memoryScope,
+ memorySemanticsEqual,
+ memorySemanticsUnequal,
+ inst->getOperand(2),
+ inst->getOperand(1));
ensureAtomicCapability(inst, SpvOpAtomicCompareExchange);
}
break;
@@ -3501,8 +3514,9 @@ struct SPIRVEmitContext
case kIROp_AtomicOr:
case kIROp_AtomicXor:
{
- IRBuilder builder{ inst };
- const auto memoryScope = emitIntConstant(IRIntegerValue{ SpvScopeDevice }, builder.getUIntType());
+ IRBuilder builder{inst};
+ const auto memoryScope =
+ emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(2));
bool negateOperand = false;
auto spvOp = getSpvAtomicOp(inst, negateOperand);
@@ -3513,17 +3527,35 @@ struct SPIRVEmitContext
auto negatedOperand = builder.emitNeg(inst->getDataType(), operand);
operand = negatedOperand;
}
- result = emitOpAtomicOp(parent, inst, spvOp, inst->getFullType(), inst->getOperand(0), memoryScope, memorySemantics, operand);
+ result = emitOpAtomicOp(
+ parent,
+ inst,
+ spvOp,
+ inst->getFullType(),
+ inst->getOperand(0),
+ memoryScope,
+ memorySemantics,
+ operand);
ensureAtomicCapability(inst, spvOp);
}
break;
case kIROp_ControlBarrier:
{
- IRBuilder builder{ inst };
- const auto executionScope = emitIntConstant(IRIntegerValue{ SpvScopeWorkgroup }, builder.getUIntType());
- const auto memoryScope = emitIntConstant(IRIntegerValue{ SpvScopeInvocation }, builder.getUIntType());
- const auto memorySemantics = emitIntConstant(IRIntegerValue{ SpvMemorySemanticsMaskNone }, builder.getUIntType());
- emitInst(parent, inst, SpvOpControlBarrier, executionScope, memoryScope, memorySemantics);
+ IRBuilder builder{inst};
+ const auto executionScope =
+ emitIntConstant(IRIntegerValue{SpvScopeWorkgroup}, builder.getUIntType());
+ const auto memoryScope =
+ emitIntConstant(IRIntegerValue{SpvScopeInvocation}, builder.getUIntType());
+ const auto memorySemantics = emitIntConstant(
+ IRIntegerValue{SpvMemorySemanticsMaskNone},
+ builder.getUIntType());
+ emitInst(
+ parent,
+ inst,
+ SpvOpControlBarrier,
+ executionScope,
+ memoryScope,
+ memorySemantics);
}
break;
case kIROp_Printf:
@@ -3543,8 +3575,15 @@ struct SPIRVEmitContext
}
}
ensureExtensionDeclaration(toSlice("SPV_KHR_non_semantic_info"));
- result = emitInst(parent, inst, SpvOpExtInst, inst->getFullType(), kResultID,
- getNonSemanticDebugPrintfExtInst(), SpvLiteralInteger::from32(1), operands.getArrayView());
+ result = emitInst(
+ parent,
+ inst,
+ SpvOpExtInst,
+ inst->getFullType(),
+ kResultID,
+ getNonSemanticDebugPrintfExtInst(),
+ SpvLiteralInteger::from32(1),
+ operands.getArrayView());
}
break;
}
@@ -3557,11 +3596,27 @@ struct SPIRVEmitContext
{
if (load->hasAuxCoord1())
{
- return emitInst(parent, load, SpvOpImageRead, load->getDataType(), kResultID, load->getImage(), load->getCoord(), SpvImageOperandsSampleMask, load->getAuxCoord1());
+ return emitInst(
+ parent,
+ load,
+ SpvOpImageRead,
+ load->getDataType(),
+ kResultID,
+ load->getImage(),
+ load->getCoord(),
+ SpvImageOperandsSampleMask,
+ load->getAuxCoord1());
}
else
{
- return emitInst(parent, load, SpvOpImageRead, load->getDataType(), kResultID, load->getImage(), load->getCoord());
+ return emitInst(
+ parent,
+ load,
+ SpvOpImageRead,
+ load->getDataType(),
+ kResultID,
+ load->getImage(),
+ load->getCoord());
}
}
@@ -3569,11 +3624,25 @@ struct SPIRVEmitContext
{
if (store->hasAuxCoord1())
{
- return emitInst(parent, store, SpvOpImageWrite, store->getImage(), store->getCoord(), store->getValue(), SpvImageOperandsSampleMask, store->getAuxCoord1());
+ return emitInst(
+ parent,
+ store,
+ SpvOpImageWrite,
+ store->getImage(),
+ store->getCoord(),
+ store->getValue(),
+ SpvImageOperandsSampleMask,
+ store->getAuxCoord1());
}
else
{
- return emitInst(parent, store, SpvOpImageWrite, store->getImage(), store->getCoord(), store->getValue());
+ return emitInst(
+ parent,
+ store,
+ SpvOpImageWrite,
+ store->getImage(),
+ store->getCoord(),
+ store->getValue());
}
}
@@ -3581,7 +3650,15 @@ struct SPIRVEmitContext
{
IRBuilder builder(subscript);
builder.setInsertBefore(subscript);
- return emitInst(parent, subscript, SpvOpImageTexelPointer, subscript->getDataType(), kResultID, subscript->getImage(), subscript->getCoord(), builder.getIntValue(builder.getIntType(), 0));
+ return emitInst(
+ parent,
+ subscript,
+ SpvOpImageTexelPointer,
+ subscript->getDataType(),
+ kResultID,
+ subscript->getImage(),
+ subscript->getCoord(),
+ builder.getIntValue(builder.getIntType(), 0));
}
SpvInst* emitGetStringHash(IRInst* inst)
@@ -3592,13 +3669,15 @@ struct SPIRVEmitContext
if (stringLit)
{
auto slice = stringLit->getStringSlice();
- return emitIntConstant(getStableHashCode32(slice.begin(), slice.getLength()).hash, inst->getDataType());
+ return emitIntConstant(
+ getStableHashCode32(slice.begin(), slice.getLength()).hash,
+ inst->getDataType());
}
else
{
- // Couldn't handle
- String e = "Unhandled local inst in spirv-emit:\n"
- + dumpIRToString(inst, { IRDumpOptions::Mode::Detailed, 0 });
+ // Couldn't handle
+ String e = "Unhandled local inst in spirv-emit:\n" +
+ dumpIRToString(inst, {IRDumpOptions::Mode::Detailed, 0});
SLANG_UNIMPLEMENTED_X(e.getBuffer());
}
}
@@ -3623,28 +3702,26 @@ struct SPIRVEmitContext
SpvInst* spvInst = nullptr;
if (cast<IRBoolLit>(inst)->getValue())
{
- spvInst = emitOpConstantTrue(
- inst,
- inst->getDataType()
- );
+ spvInst = emitOpConstantTrue(inst, inst->getDataType());
}
else
{
- spvInst = emitOpConstantFalse(
- inst,
- inst->getDataType()
- );
+ spvInst = emitOpConstantFalse(inst, inst->getDataType());
}
m_mapIRInstToSpvInst[inst] = spvInst;
return spvInst;
}
case kIROp_StringLit:
- {
- auto value = as<IRStringLit>(inst)->getStringSlice();
- return emitInst(getSection(SpvLogicalSectionID::DebugStringsAndSource), inst, SpvOpString, kResultID, SpvLiteralBits::fromUnownedStringSlice(value));
- }
- default:
- return nullptr;
+ {
+ auto value = as<IRStringLit>(inst)->getStringSlice();
+ return emitInst(
+ getSection(SpvLogicalSectionID::DebugStringsAndSource),
+ inst,
+ SpvOpString,
+ kResultID,
+ SpvLiteralBits::fromUnownedStringSlice(value));
+ }
+ default: return nullptr;
}
}
@@ -3653,14 +3730,14 @@ struct SPIRVEmitContext
// to emit any decoratons that were attached to it that have
// a SPIR-V equivalent.
- /// Emit appropriate SPIR-V decorations for the given IR `irInst`.
- ///
- /// The given `dstID` should be the `<id>` of the SPIR-V instruction being decorated,
- /// and should correspond to `irInst`.
- ///
+ /// Emit appropriate SPIR-V decorations for the given IR `irInst`.
+ ///
+ /// The given `dstID` should be the `<id>` of the SPIR-V instruction being decorated,
+ /// and should correspond to `irInst`.
+ ///
void emitDecorations(IRInst* irInst, SpvWord dstID)
{
- for( auto decoration : irInst->getDecorations() )
+ for (auto decoration : irInst->getDecorations())
{
emitDecoration(dstID, decoration);
}
@@ -3731,8 +3808,7 @@ struct SPIRVEmitContext
{
case kIROp_SwizzledStore:
case kIROp_Store:
- case kIROp_Call:
- return result;
+ case kIROp_Call: return result;
}
}
return SpvExecutionModeMax;
@@ -3781,11 +3857,12 @@ struct SPIRVEmitContext
return sb.produceString();
}
- /// Emit an appropriate SPIR-V decoration for the given IR `decoration`, if necessary and possible.
- ///
- /// The given `dstID` should be the `<id>` of the SPIR-V instruction being decorated,
- /// and should correspond to the parent of `decoration` in the Slang IR.
- ///
+ /// Emit an appropriate SPIR-V decoration for the given IR `decoration`, if necessary and
+ /// possible.
+ ///
+ /// The given `dstID` should be the `<id>` of the SPIR-V instruction being decorated,
+ /// and should correspond to the parent of `decoration` in the Slang IR.
+ ///
void emitDecoration(SpvWord dstID, IRDecoration* decoration)
{
// Unlike in the Slang IR, decorations in SPIR-V are not children
@@ -3802,10 +3879,9 @@ struct SPIRVEmitContext
// be emitted if the owning instruction gets emitted.
bool isRayTracingObject = false;
- switch( decoration->getOp() )
+ switch (decoration->getOp())
{
- default:
- break;
+ default: break;
// [3.32.2. Debug Instructions]
//
@@ -3838,7 +3914,8 @@ struct SPIRVEmitContext
List<SpvInst*> params;
HashSet<SpvInst*> paramsSet;
List<IRInst*> referencedBuiltinIRVars;
- // `interface` part: reference all global variables that are used by this entrypoint.
+ // `interface` part: reference all global variables that are used by this
+ // entrypoint.
for (auto globalInst : m_irModule->getModuleInst()->getChildren())
{
switch (globalInst->getOp())
@@ -3846,79 +3923,76 @@ struct SPIRVEmitContext
case kIROp_GlobalVar:
case kIROp_GlobalParam:
case kIROp_SPIRVAsmOperandBuiltinVar:
- {
- SpvInst* spvGlobalInst;
- if (m_mapIRInstToSpvInst.tryGetValue(globalInst, spvGlobalInst))
{
- // Is this globalInst referenced by this entry point?
- auto refSet = m_referencingEntryPoints.tryGetValue(globalInst);
- if (refSet && refSet->contains(entryPoint))
+ SpvInst* spvGlobalInst;
+ if (m_mapIRInstToSpvInst.tryGetValue(globalInst, spvGlobalInst))
{
- if (!isSpirv14OrLater())
+ // Is this globalInst referenced by this entry point?
+ auto refSet = m_referencingEntryPoints.tryGetValue(globalInst);
+ if (refSet && refSet->contains(entryPoint))
{
- // Prior to SPIRV 1.4, we can only reference In and Out variables
- // in the interface part.
- if (auto ptrType = as<IRPtrTypeBase>(globalInst->getDataType()))
+ if (!isSpirv14OrLater())
{
- auto addrSpace = ptrType->getAddressSpace();
- if (addrSpace != AddressSpace::Input && addrSpace != AddressSpace::Output)
- continue;
+ // Prior to SPIRV 1.4, we can only reference In and Out
+ // variables in the interface part.
+ if (auto ptrType =
+ as<IRPtrTypeBase>(globalInst->getDataType()))
+ {
+ auto addrSpace = ptrType->getAddressSpace();
+ if (addrSpace != AddressSpace::Input &&
+ addrSpace != AddressSpace::Output)
+ continue;
+ }
}
- }
- paramsSet.add(spvGlobalInst);
- referencedBuiltinIRVars.add(globalInst);
+ paramsSet.add(spvGlobalInst);
+ referencedBuiltinIRVars.add(globalInst);
- // Don't add a global param to the interface if it is a specialization constant.
- switch (spvGlobalInst->opcode)
- {
- case SpvOpSpecConstant:
- case SpvOpSpecConstantFalse:
- case SpvOpSpecConstantTrue:
- case SpvOpSpecConstantComposite:
- break;
- default:
- params.add(spvGlobalInst);
- break;
+ // Don't add a global param to the interface if it is a
+ // specialization constant.
+ switch (spvGlobalInst->opcode)
+ {
+ case SpvOpSpecConstant:
+ case SpvOpSpecConstantFalse:
+ case SpvOpSpecConstantTrue:
+ case SpvOpSpecConstantComposite: break;
+ default: params.add(spvGlobalInst); break;
+ }
}
}
+ break;
}
- break;
- }
- default:
- break;
+ default: break;
}
}
- emitOpEntryPoint(
- section,
- decoration,
- spvStage,
- dstID,
- name,
- params
- );
+ emitOpEntryPoint(section, decoration, spvStage, dstID, name, params);
// Stage specific execution mode and capability declarations.
switch (entryPointDecor->getProfile().getStage())
{
case Stage::Fragment:
- //OpExecutionMode %main OriginUpperLeft
- requireSPIRVExecutionMode(nullptr, getIRInstSpvID(entryPoint), SpvExecutionModeOriginUpperLeft);
- maybeEmitEntryPointDepthReplacingExecutionMode(entryPoint, referencedBuiltinIRVars);
+ // OpExecutionMode %main OriginUpperLeft
+ requireSPIRVExecutionMode(
+ nullptr,
+ getIRInstSpvID(entryPoint),
+ SpvExecutionModeOriginUpperLeft);
+ maybeEmitEntryPointDepthReplacingExecutionMode(
+ entryPoint,
+ referencedBuiltinIRVars);
for (auto decor : entryPoint->getDecorations())
{
switch (decor->getOp())
{
case kIROp_EarlyDepthStencilDecoration:
- requireSPIRVExecutionMode(nullptr, getIRInstSpvID(entryPoint), SpvExecutionModeEarlyFragmentTests);
- break;
- default:
+ requireSPIRVExecutionMode(
+ nullptr,
+ getIRInstSpvID(entryPoint),
+ SpvExecutionModeEarlyFragmentTests);
break;
+ default: break;
}
}
break;
- case Stage::Geometry:
- requireSPIRVCapability(SpvCapabilityGeometry);
- break;
+ case Stage::Geometry: requireSPIRVCapability(SpvCapabilityGeometry); break;
case Stage::Miss:
case Stage::AnyHit:
case Stage::ClosestHit:
@@ -3934,30 +4008,31 @@ struct SPIRVEmitContext
ensureExtensionDeclaration(UnownedStringSlice("SPV_EXT_mesh_shader"));
break;
case Stage::Hull:
- {
- requireSPIRVCapability(SpvCapabilityTessellation);
-
- SpvExecutionMode mode = SpvExecutionModeSpacingEqual;
- if (auto partitioningDecor = entryPoint->findDecoration<IRPartitioningDecoration>())
{
- auto arg = partitioningDecor->getPartitioning()->getStringSlice();
- if (arg.caseInsensitiveEquals(toSlice("integer")))
- mode = SpvExecutionModeSpacingEqual;
- else if (arg.caseInsensitiveEquals(toSlice("fractional_even")))
- mode = SpvExecutionModeSpacingFractionalEven;
- else if (arg.caseInsensitiveEquals(toSlice("fractional_odd")))
- mode = SpvExecutionModeSpacingFractionalOdd;
- else
- m_sink->diagnose(partitioningDecor, Diagnostics::unknownTessPartitioning, arg);
+ requireSPIRVCapability(SpvCapabilityTessellation);
+
+ SpvExecutionMode mode = SpvExecutionModeSpacingEqual;
+ if (auto partitioningDecor =
+ entryPoint->findDecoration<IRPartitioningDecoration>())
+ {
+ auto arg = partitioningDecor->getPartitioning()->getStringSlice();
+ if (arg.caseInsensitiveEquals(toSlice("integer")))
+ mode = SpvExecutionModeSpacingEqual;
+ else if (arg.caseInsensitiveEquals(toSlice("fractional_even")))
+ mode = SpvExecutionModeSpacingFractionalEven;
+ else if (arg.caseInsensitiveEquals(toSlice("fractional_odd")))
+ mode = SpvExecutionModeSpacingFractionalOdd;
+ else
+ m_sink->diagnose(
+ partitioningDecor,
+ Diagnostics::unknownTessPartitioning,
+ arg);
+ }
+ requireSPIRVExecutionMode(nullptr, getIRInstSpvID(entryPoint), mode);
+ break;
}
- requireSPIRVExecutionMode(nullptr, getIRInstSpvID(entryPoint), mode);
- break;
- }
- case Stage::Domain:
- requireSPIRVCapability(SpvCapabilityTessellation);
- break;
- default:
- break;
+ case Stage::Domain: requireSPIRVCapability(SpvCapabilityTessellation); break;
+ default: break;
}
}
break;
@@ -3982,20 +4057,23 @@ struct SPIRVEmitContext
SpvExecutionModeLocalSize,
SpvLiteralInteger::from32(int32_t(numThreads->getX()->getValue())),
SpvLiteralInteger::from32(int32_t(numThreads->getY()->getValue())),
- SpvLiteralInteger::from32(int32_t(numThreads->getZ()->getValue()))
- );
+ SpvLiteralInteger::from32(int32_t(numThreads->getZ()->getValue())));
}
break;
case kIROp_MaxVertexCountDecoration:
// Don't do anything here, instead wait until we see OutputTopologyDecoration
- // and emit them together to ensure MaxVertexCount always appears before OutputTopology,
- // which seemed to be required by SPIRV.
+ // and emit them together to ensure MaxVertexCount always appears before
+ // OutputTopology, which seemed to be required by SPIRV.
break;
case kIROp_InstanceDecoration:
{
auto decor = as<IRInstanceDecoration>(decoration);
auto count = int32_t(getIntVal(decor->getCount()));
- requireSPIRVExecutionMode(decoration, dstID, SpvExecutionModeInvocations, SpvLiteralInteger::from32(count));
+ requireSPIRVExecutionMode(
+ decoration,
+ dstID,
+ SpvExecutionModeInvocations,
+ SpvLiteralInteger::from32(count));
}
break;
case kIROp_TriangleInputPrimitiveTypeDecoration:
@@ -4003,8 +4081,8 @@ struct SPIRVEmitContext
case kIROp_LineAdjInputPrimitiveTypeDecoration:
case kIROp_PointInputPrimitiveTypeDecoration:
case kIROp_TriangleAdjInputPrimitiveTypeDecoration:
- // Defer this until we see kIROp_StreamOutputTypeDecoration because the driver wants to see
- // them before the output.
+ // Defer this until we see kIROp_StreamOutputTypeDecoration because the driver wants
+ // to see them before the output.
break;
case kIROp_StreamOutputTypeDecoration:
{
@@ -4019,26 +4097,32 @@ struct SPIRVEmitContext
requireSPIRVExecutionMode(inputDecor, dstID, SpvExecutionModeInputLines);
break;
case kIROp_LineAdjInputPrimitiveTypeDecoration:
- requireSPIRVExecutionMode(inputDecor, dstID, SpvExecutionModeInputLinesAdjacency);
+ requireSPIRVExecutionMode(
+ inputDecor,
+ dstID,
+ SpvExecutionModeInputLinesAdjacency);
break;
case kIROp_PointInputPrimitiveTypeDecoration:
requireSPIRVExecutionMode(inputDecor, dstID, SpvExecutionModeInputPoints);
break;
case kIROp_TriangleAdjInputPrimitiveTypeDecoration:
- requireSPIRVExecutionMode(inputDecor, dstID, SpvExecutionModeInputTrianglesAdjacency);
+ requireSPIRVExecutionMode(
+ inputDecor,
+ dstID,
+ SpvExecutionModeInputTrianglesAdjacency);
break;
}
}
- // SPIRV requires MaxVertexCount decoration to appear before OutputTopologyDecoration,
- // so we emit them here.
- if (auto maxVertexCount = decoration->getParent()->findDecoration<IRMaxVertexCountDecoration>())
+ // SPIRV requires MaxVertexCount decoration to appear before
+ // OutputTopologyDecoration, so we emit them here.
+ if (auto maxVertexCount =
+ decoration->getParent()->findDecoration<IRMaxVertexCountDecoration>())
{
requireSPIRVExecutionMode(
maxVertexCount,
dstID,
SpvExecutionModeOutputVertices,
- SpvLiteralInteger::from32(int32_t(getIntVal(maxVertexCount->getCount())))
- );
+ SpvLiteralInteger::from32(int32_t(getIntVal(maxVertexCount->getCount()))));
}
auto decor = as<IRStreamOutputTypeDecoration>(decoration);
@@ -4053,7 +4137,10 @@ struct SPIRVEmitContext
requireSPIRVExecutionMode(decoration, dstID, SpvExecutionModeOutputLineStrip);
break;
case kIROp_HLSLTriangleStreamType:
- requireSPIRVExecutionMode(decoration, dstID, SpvExecutionModeOutputTriangleStrip);
+ requireSPIRVExecutionMode(
+ decoration,
+ dstID,
+ SpvExecutionModeOutputTriangleStrip);
break;
default: SLANG_ASSERT(!"Unknown stream out type");
}
@@ -4065,8 +4152,7 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::Annotations),
decoration,
dstID,
- SpvDecorationBufferBlock
- );
+ SpvDecorationBufferBlock);
}
break;
case kIROp_SPIRVBlockDecoration:
@@ -4075,8 +4161,7 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::Annotations),
decoration,
dstID,
- SpvDecorationBlock
- );
+ SpvDecorationBlock);
}
break;
@@ -4089,15 +4174,15 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::Annotations),
decoration,
dstID,
- SpvDecorationNonUniform
- );
+ SpvDecorationNonUniform);
}
break;
case kIROp_OutputTopologyDecoration:
{
auto entryPoint = decoration->getParent();
- IREntryPointDecoration* entryPointDecor = entryPoint ? entryPoint->findDecoration<IREntryPointDecoration>() : nullptr;
+ IREntryPointDecoration* entryPointDecor =
+ entryPoint ? entryPoint->findDecoration<IREntryPointDecoration>() : nullptr;
const auto o = cast<IROutputTopologyDecoration>(decoration);
const auto t = o->getTopology()->getStringSlice();
@@ -4125,7 +4210,7 @@ struct SPIRVEmitContext
else if (t == "point")
m = SpvExecutionModeOutputPoints;
}
-
+
SLANG_ASSERT(m != SpvExecutionModeMax);
requireSPIRVExecutionMode(decoration, dstID, m);
}
@@ -4138,8 +4223,7 @@ struct SPIRVEmitContext
decoration,
dstID,
SpvExecutionModeOutputVertices,
- SpvLiteralInteger::from32(int32_t(c->getMaxSize()->getValue()))
- );
+ SpvLiteralInteger::from32(int32_t(c->getMaxSize()->getValue())));
}
break;
@@ -4150,8 +4234,7 @@ struct SPIRVEmitContext
decoration,
dstID,
SpvExecutionModeOutputPrimitivesEXT,
- SpvLiteralInteger::from32(int32_t(c->getMaxSize()->getValue()))
- );
+ SpvLiteralInteger::from32(int32_t(c->getMaxSize()->getValue())));
}
break;
@@ -4163,14 +4246,14 @@ struct SPIRVEmitContext
isRayTracingObject = true;
break;
case kIROp_VulkanHitObjectAttributesDecoration:
- // needed since GLSL will not set optypes accordingly, but will keep the decoration
+ // needed since GLSL will not set optypes accordingly, but will keep the decoration
ensureExtensionDeclaration(UnownedStringSlice("SPV_NV_shader_invocation_reorder"));
requireSPIRVCapability(SpvCapabilityShaderInvocationReorderNV);
isRayTracingObject = true;
break;
case kIROp_VulkanRayPayloadDecoration:
case kIROp_VulkanRayPayloadInDecoration:
- // needed since GLSL will not set optypes accordingly, but will keep the decoration
+ // needed since GLSL will not set optypes accordingly, but will keep the decoration
ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_ray_tracing"));
requireSPIRVCapability(SpvCapabilityRayTracingKHR);
isRayTracingObject = true;
@@ -4215,65 +4298,76 @@ struct SPIRVEmitContext
}
break;
case kIROp_MemoryQualifierSetDecoration:
- {
- auto collection = as<IRMemoryQualifierSetDecoration>(decoration);
- IRIntegerValue flags = collection->getMemoryQualifierBit();
- if (flags & MemoryQualifierSetModifier::Flags::kCoherent)
- {
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations),
- nullptr,
- dstID,
- SpvDecorationCoherent);
- }
- if (flags & MemoryQualifierSetModifier::Flags::kVolatile)
- {
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations),
- nullptr,
- dstID,
- SpvDecorationVolatile);
- }
- if (flags & MemoryQualifierSetModifier::Flags::kRestrict)
{
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations),
- nullptr,
- dstID,
- SpvDecorationRestrict);
- }
- if (flags & MemoryQualifierSetModifier::Flags::kReadOnly)
- {
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations),
- nullptr,
- dstID,
- SpvDecorationNonWritable);
+ auto collection = as<IRMemoryQualifierSetDecoration>(decoration);
+ IRIntegerValue flags = collection->getMemoryQualifierBit();
+ if (flags & MemoryQualifierSetModifier::Flags::kCoherent)
+ {
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ nullptr,
+ dstID,
+ SpvDecorationCoherent);
+ }
+ if (flags & MemoryQualifierSetModifier::Flags::kVolatile)
+ {
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ nullptr,
+ dstID,
+ SpvDecorationVolatile);
+ }
+ if (flags & MemoryQualifierSetModifier::Flags::kRestrict)
+ {
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ nullptr,
+ dstID,
+ SpvDecorationRestrict);
+ }
+ if (flags & MemoryQualifierSetModifier::Flags::kReadOnly)
+ {
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ nullptr,
+ dstID,
+ SpvDecorationNonWritable);
+ }
+ if (flags & MemoryQualifierSetModifier::Flags::kWriteOnly)
+ {
+ emitOpDecorate(
+ getSection(SpvLogicalSectionID::Annotations),
+ nullptr,
+ dstID,
+ SpvDecorationNonReadable);
+ }
+ break;
}
- if (flags & MemoryQualifierSetModifier::Flags::kWriteOnly)
+ case kIROp_DownstreamModuleExportDecoration:
{
- emitOpDecorate(getSection(SpvLogicalSectionID::Annotations),
- nullptr,
+ requireSPIRVCapability(SpvCapabilityLinkage);
+ auto name =
+ decoration->getParent()->findDecoration<IRExportDecoration>()->getMangledName();
+ emitInst(
+ getSection(SpvLogicalSectionID::Annotations),
+ decoration,
+ SpvOpDecorate,
dstID,
- SpvDecorationNonReadable);
+ SpvDecorationLinkageAttributes,
+ name,
+ SpvLinkageTypeExport);
+ break;
}
- break;
- }
- case kIROp_DownstreamModuleExportDecoration:
- {
- requireSPIRVCapability(SpvCapabilityLinkage);
- auto name = decoration->getParent()->findDecoration<IRExportDecoration>()->getMangledName();
- emitInst(getSection(SpvLogicalSectionID::Annotations),
- decoration,
- SpvOpDecorate,
- dstID,
- SpvDecorationLinkageAttributes, name, SpvLinkageTypeExport);
- break;
- }
- // ...
+ // ...
}
- if(isRayTracingObject)
+ if (isRayTracingObject)
{
- if (decoration->getOperandCount() > 0) {
- //if not greater than 0, this is not a layout decoration (no val)
- emitOpDecorateLocation(getSection(SpvLogicalSectionID::Annotations),
+ if (decoration->getOperandCount() > 0)
+ {
+ // if not greater than 0, this is not a layout decoration (no val)
+ emitOpDecorateLocation(
+ getSection(SpvLogicalSectionID::Annotations),
decoration,
dstID,
SpvLiteralInteger::from32(int32_t(getIntVal(decoration->getOperand(0)))));
@@ -4284,35 +4378,42 @@ struct SPIRVEmitContext
{
switch (decoration->getOp())
{
- default:
- break;
+ default: break;
case kIROp_SemanticDecoration:
{
- ensureExtensionDeclarationBeforeSpv14(toSlice("SPV_GOOGLE_hlsl_functionality1"));
- emitOpDecorateString(getSection(SpvLogicalSectionID::Annotations),
- decoration,
- dstID,
- SpvDecorationUserSemantic,
- cast<IRSemanticDecoration>(decoration)->getSemanticName());
+ ensureExtensionDeclarationBeforeSpv14(
+ toSlice("SPV_GOOGLE_hlsl_functionality1"));
+ emitOpDecorateString(
+ getSection(SpvLogicalSectionID::Annotations),
+ decoration,
+ dstID,
+ SpvDecorationUserSemantic,
+ cast<IRSemanticDecoration>(decoration)->getSemanticName());
}
break;
case kIROp_UserTypeNameDecoration:
{
ensureExtensionDeclaration(toSlice("SPV_GOOGLE_user_type"));
- ensureExtensionDeclarationBeforeSpv14(toSlice("SPV_GOOGLE_hlsl_functionality1"));
- emitOpDecorateString(getSection(SpvLogicalSectionID::Annotations),
+ ensureExtensionDeclarationBeforeSpv14(
+ toSlice("SPV_GOOGLE_hlsl_functionality1"));
+ emitOpDecorateString(
+ getSection(SpvLogicalSectionID::Annotations),
decoration,
dstID,
SpvDecorationUserTypeGOOGLE,
- legalizeUserTypeName(cast<IRUserTypeNameDecoration>(decoration)->getUserTypeName()->getStringSlice()).getUnownedSlice());
+ legalizeUserTypeName(cast<IRUserTypeNameDecoration>(decoration)
+ ->getUserTypeName()
+ ->getStringSlice())
+ .getUnownedSlice());
}
break;
case kIROp_CounterBufferDecoration:
{
- emitOpDecorateCounterBuffer(getSection(SpvLogicalSectionID::Annotations),
- decoration,
- dstID,
- as<IRCounterBufferDecoration>(decoration)->getCounterBuffer());
+ emitOpDecorateCounterBuffer(
+ getSection(SpvLogicalSectionID::Annotations),
+ decoration,
+ dstID,
+ as<IRCounterBufferDecoration>(decoration)->getCounterBuffer());
}
break;
}
@@ -4322,24 +4423,24 @@ struct SPIRVEmitContext
void emitLayoutDecorations(IRStructType* structType, SpvWord spvStructID)
{
/*****
- * SPIRV Spec:
- * Each structure-type member must have an Offset decoration.
- *
- * Each array type must have an ArrayStride decoration, unless it is an
- * array that contains a structure decorated with Block or BufferBlock, in
- * which case it must not have an ArrayStride decoration.
- *
- * Each structure-type member that is a matrix or array-of-matrices must be
- * decorated with a MatrixStride Decoration, and one of the RowMajor or
- * ColMajor decorations.
- *
- * The ArrayStride, MatrixStride, and Offset decorations must be large
- * enough to hold the size of the objects they affect (that is, specifying
- * overlap is invalid). Each ArrayStride and MatrixStride must be greater
- * than zero, and it is invalid for two members of a given structure to be
- * assigned the same Offset.
- *
- *****/
+ * SPIRV Spec:
+ * Each structure-type member must have an Offset decoration.
+ *
+ * Each array type must have an ArrayStride decoration, unless it is an
+ * array that contains a structure decorated with Block or BufferBlock, in
+ * which case it must not have an ArrayStride decoration.
+ *
+ * Each structure-type member that is a matrix or array-of-matrices must be
+ * decorated with a MatrixStride Decoration, and one of the RowMajor or
+ * ColMajor decorations.
+ *
+ * The ArrayStride, MatrixStride, and Offset decorations must be large
+ * enough to hold the size of the objects they affect (that is, specifying
+ * overlap is invalid). Each ArrayStride and MatrixStride must be greater
+ * than zero, and it is invalid for two members of a given structure to be
+ * assigned the same Offset.
+ *
+ *****/
auto layout = structType->findDecoration<IRSizeAndAlignmentDecoration>();
IRTypeLayoutRuleName layoutRuleName = IRTypeLayoutRuleName::Natural;
if (layout)
@@ -4370,8 +4471,7 @@ struct SPIRVEmitContext
nullptr,
spvStructID,
SpvLiteralInteger::from32(id),
- SpvDecorationCoherent
- );
+ SpvDecorationCoherent);
}
if (flags & MemoryQualifierSetModifier::Flags::kVolatile)
{
@@ -4380,8 +4480,7 @@ struct SPIRVEmitContext
nullptr,
spvStructID,
SpvLiteralInteger::from32(id),
- SpvDecorationVolatile
- );
+ SpvDecorationVolatile);
}
if (flags & MemoryQualifierSetModifier::Flags::kRestrict)
{
@@ -4390,8 +4489,7 @@ struct SPIRVEmitContext
nullptr,
spvStructID,
SpvLiteralInteger::from32(id),
- SpvDecorationRestrict
- );
+ SpvDecorationRestrict);
}
if (flags & MemoryQualifierSetModifier::Flags::kReadOnly)
{
@@ -4400,8 +4498,7 @@ struct SPIRVEmitContext
nullptr,
spvStructID,
SpvLiteralInteger::from32(id),
- SpvDecorationNonWritable
- );
+ SpvDecorationNonWritable);
}
if (flags & MemoryQualifierSetModifier::Flags::kWriteOnly)
{
@@ -4410,15 +4507,16 @@ struct SPIRVEmitContext
nullptr,
spvStructID,
SpvLiteralInteger::from32(id),
- SpvDecorationNonReadable
- );
+ SpvDecorationNonReadable);
}
}
- else if (auto semanticDecor = field->getKey()->findDecoration<IRSemanticDecoration>())
+ else if (
+ auto semanticDecor = field->getKey()->findDecoration<IRSemanticDecoration>())
{
if (shouldEmitSPIRVReflectionInfo())
{
- ensureExtensionDeclarationBeforeSpv14(toSlice("SPV_GOOGLE_hlsl_functionality1"));
+ ensureExtensionDeclarationBeforeSpv14(
+ toSlice("SPV_GOOGLE_hlsl_functionality1"));
emitOpMemberDecorateString(
getSection(SpvLogicalSectionID::Annotations),
nullptr,
@@ -4433,11 +4531,17 @@ struct SPIRVEmitContext
IRIntegerValue offset = 0;
if (auto offsetDecor = field->getKey()->findDecoration<IRPackOffsetDecoration>())
{
- offset = (getIntVal(offsetDecor->getRegisterOffset()) * 4 + getIntVal(offsetDecor->getComponentOffset())) * 4;
+ offset = (getIntVal(offsetDecor->getRegisterOffset()) * 4 +
+ getIntVal(offsetDecor->getComponentOffset())) *
+ 4;
}
else
{
- getOffset(m_targetProgram->getOptionSet(), IRTypeLayoutRules::get(layoutRuleName), field, &offset);
+ getOffset(
+ m_targetProgram->getOptionSet(),
+ IRTypeLayoutRules::get(layoutRuleName),
+ field,
+ &offset);
}
emitOpMemberDecorateOffset(
getSection(SpvLogicalSectionID::Annotations),
@@ -4462,7 +4566,11 @@ struct SPIRVEmitContext
IRIntegerValue matrixStride = 0;
auto rule = IRTypeLayoutRules::get(layoutRuleName);
IRSizeAndAlignment elementSizeAlignment;
- getSizeAndAlignment(m_targetProgram->getOptionSet(), rule, matrixType->getElementType(), &elementSizeAlignment);
+ getSizeAndAlignment(
+ m_targetProgram->getOptionSet(),
+ rule,
+ matrixType->getElementType(),
+ &elementSizeAlignment);
IRIntegerValue matrixMinorVectorCount = 0;
// Reminder: the meaning of row/column major layout
// in our semantics is the *opposite* of what GLSL/SPIRV
@@ -4493,7 +4601,8 @@ struct SPIRVEmitContext
// We need the size of our vector. To get the stride we need to know how 'big'
// each vector element is inside an array, due to this we align our vector
// as if a composite.
- auto vectorSize = rule->getVectorSizeAndAlignment(elementSizeAlignment, matrixMinorVectorCount);
+ auto vectorSize =
+ rule->getVectorSizeAndAlignment(elementSizeAlignment, matrixMinorVectorCount);
vectorSize = rule->alignCompositeElement(vectorSize);
matrixStride = vectorSize.getStride();
emitOpMemberDecorateMatrixStride(
@@ -4507,33 +4616,31 @@ struct SPIRVEmitContext
}
}
- /// Map a Slang `Stage` to a corresponding SPIR-V execution model
+ /// Map a Slang `Stage` to a corresponding SPIR-V execution model
SpvExecutionModel mapStageToExecutionModel(Stage stage)
{
- switch( stage )
+ switch (stage)
{
- default:
- SLANG_UNEXPECTED("unhandled stage");
- UNREACHABLE_RETURN((SpvExecutionModel)0);
+ default: SLANG_UNEXPECTED("unhandled stage"); UNREACHABLE_RETURN((SpvExecutionModel)0);
#define CASE(STAGE, MODEL) \
- case Stage::STAGE: return SpvExecutionModel##MODEL
-
- CASE(Vertex, Vertex);
- CASE(Hull, TessellationControl);
- CASE(Domain, TessellationEvaluation);
- CASE(Geometry, Geometry);
- CASE(Fragment, Fragment);
- CASE(Compute, GLCompute);
- CASE(Mesh, MeshEXT);
- CASE(Amplification, TaskEXT);
- CASE(ClosestHit, ClosestHitKHR);
- CASE(AnyHit, AnyHitKHR);
- CASE(Callable, CallableKHR);
- CASE(Miss, MissKHR);
- CASE(Intersection, IntersectionKHR);
- CASE(RayGeneration, RayGenerationKHR);
- // TODO: Extended execution models for ray tracing, etc.
+ case Stage::STAGE: return SpvExecutionModel##MODEL
+
+ CASE(Vertex, Vertex);
+ CASE(Hull, TessellationControl);
+ CASE(Domain, TessellationEvaluation);
+ CASE(Geometry, Geometry);
+ CASE(Fragment, Fragment);
+ CASE(Compute, GLCompute);
+ CASE(Mesh, MeshEXT);
+ CASE(Amplification, TaskEXT);
+ CASE(ClosestHit, ClosestHitKHR);
+ CASE(AnyHit, AnyHitKHR);
+ CASE(Callable, CallableKHR);
+ CASE(Miss, MissKHR);
+ CASE(Intersection, IntersectionKHR);
+ CASE(RayGeneration, RayGenerationKHR);
+ // TODO: Extended execution models for ray tracing, etc.
#undef CASE
}
@@ -4580,8 +4687,7 @@ struct SPIRVEmitContext
{
if (!irInst)
return;
- if (irInst->getOp() != kIROp_GlobalVar &&
- irInst->getOp() != kIROp_GlobalParam)
+ if (irInst->getOp() != kIROp_GlobalVar && irInst->getOp() != kIROp_GlobalParam)
return;
auto ptrType = as<IRPtrType>(irInst->getDataType());
if (!ptrType)
@@ -4592,7 +4698,9 @@ struct SPIRVEmitContext
if (isIntegralScalarOrCompositeType(ptrType->getValueType()))
{
if (isInstUsedInStage(irInst, Stage::Fragment))
- _maybeEmitInterpolationModifierDecoration(IRInterpolationMode::NoInterpolation, getID(spvInst));
+ _maybeEmitInterpolationModifierDecoration(
+ IRInterpolationMode::NoInterpolation,
+ getID(spvInst));
}
}
}
@@ -4614,14 +4722,12 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::GlobalVariables),
nullptr,
type,
- addressSpaceToStorageClass(ptrType->getAddressSpace())
- );
+ addressSpaceToStorageClass(ptrType->getAddressSpace()));
emitOpDecorateBuiltIn(
getSection(SpvLogicalSectionID::Annotations),
nullptr,
varInst,
- builtinVal
- );
+ builtinVal);
switch (builtinVal)
{
case SpvBuiltInTessLevelInner:
@@ -4630,8 +4736,7 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::Annotations),
nullptr,
varInst,
- SpvDecorationPatch
- );
+ SpvDecorationPatch);
break;
}
m_builtinGlobalVars[key] = varInst;
@@ -4683,8 +4788,12 @@ struct SPIRVEmitContext
else if (semanticName == "sv_innercoverage")
{
requireSPIRVCapability(SpvCapabilityFragmentFullyCoveredEXT);
- ensureExtensionDeclaration(UnownedStringSlice("SPV_EXT_fragment_fully_covered"));
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInFullyCoveredEXT, inst);
+ ensureExtensionDeclaration(
+ UnownedStringSlice("SPV_EXT_fragment_fully_covered"));
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInFullyCoveredEXT,
+ inst);
}
else if (semanticName == "sv_depth")
{
@@ -4700,7 +4809,10 @@ struct SPIRVEmitContext
}
else if (semanticName == "sv_dispatchthreadid")
{
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInGlobalInvocationId, inst);
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInGlobalInvocationId,
+ inst);
}
else if (semanticName == "sv_domainlocation")
{
@@ -4712,11 +4824,17 @@ struct SPIRVEmitContext
}
else if (semanticName == "sv_groupindex")
{
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInLocalInvocationIndex, inst);
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInLocalInvocationIndex,
+ inst);
}
else if (semanticName == "sv_groupthreadid")
{
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInLocalInvocationId, inst);
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInLocalInvocationId,
+ inst);
}
else if (semanticName == "sv_gsinstanceid")
{
@@ -4752,7 +4870,8 @@ struct SPIRVEmitContext
{
for (auto entryPoint : *entryPoints)
{
- if (auto entryPointDecor = entryPoint->findDecoration<IREntryPointDecoration>())
+ if (auto entryPointDecor =
+ entryPoint->findDecoration<IREntryPointDecoration>())
{
switch (entryPointDecor->getProfile().getStage())
{
@@ -4763,9 +4882,7 @@ struct SPIRVEmitContext
case Stage::AnyHit:
case Stage::ClosestHit:
case Stage::Hull:
- case Stage::Domain:
- needGeometryCapability = false;
- break;
+ case Stage::Domain: needGeometryCapability = false; break;
}
}
}
@@ -4791,7 +4908,10 @@ struct SPIRVEmitContext
{
requireSPIRVCapability(SpvCapabilityStencilExportEXT);
ensureExtensionDeclaration(UnownedStringSlice("SPV_EXT_shader_stencil_export"));
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInFragStencilRefEXT, inst);
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInFragStencilRefEXT,
+ inst);
}
else if (semanticName == "sv_tessfactor")
{
@@ -4825,12 +4945,16 @@ struct SPIRVEmitContext
{
requireSPIRVCapability(SpvCapabilityPerViewAttributesNV);
ensureExtensionDeclaration(UnownedStringSlice("SPV_NV_mesh_shader"));
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInViewportMaskPerViewNV, inst);
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInViewportMaskPerViewNV,
+ inst);
}
else if (semanticName == "sv_barycentrics")
{
requireSPIRVCapability(SpvCapabilityFragmentBarycentricKHR);
- ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_fragment_shader_barycentric"));
+ ensureExtensionDeclaration(
+ UnownedStringSlice("SPV_KHR_fragment_shader_barycentric"));
return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInBaryCoordKHR, inst);
// TODO: There is also the `gl_BaryCoordNoPerspNV` builtin, which
@@ -4841,17 +4965,27 @@ struct SPIRVEmitContext
{
requireSPIRVCapability(SpvCapabilityMeshShadingEXT);
ensureExtensionDeclaration(UnownedStringSlice("SPV_EXT_mesh_shader"));
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInCullPrimitiveEXT, inst);
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInCullPrimitiveEXT,
+ inst);
}
else if (semanticName == "sv_shadingrate")
{
requireSPIRVCapability(SpvCapabilityFragmentShadingRateKHR);
ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_fragment_shading_rate"));
auto importDecor = inst->findDecoration<IRImportDecoration>();
- if (importDecor && importDecor->getMangledName() == "gl_PrimitiveShadingRateEXT")
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInPrimitiveShadingRateKHR, inst);
+ if (importDecor &&
+ importDecor->getMangledName() == "gl_PrimitiveShadingRateEXT")
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInPrimitiveShadingRateKHR,
+ inst);
else
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInShadingRateKHR, inst);
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInShadingRateKHR,
+ inst);
}
SLANG_UNREACHABLE("Unimplemented system value in spirv emit.");
}
@@ -4862,15 +4996,24 @@ struct SPIRVEmitContext
// GLSL, SPIR-V makes no such distinction so we can use similar logic
// to above.
//
- if(const auto linkageDecoration = inst->findDecoration<IRLinkageDecoration>())
+ if (const auto linkageDecoration = inst->findDecoration<IRLinkageDecoration>())
{
const auto name = linkageDecoration->getMangledName();
- if(name == "gl_PrimitiveTriangleIndicesEXT")
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInPrimitiveTriangleIndicesEXT, inst);
- if(name == "gl_PrimitiveLineIndicesEXT")
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInPrimitiveLineIndicesEXT, inst);
- if(name == "gl_PrimitivePointIndicesEXT")
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInPrimitivePointIndicesEXT, inst);
+ if (name == "gl_PrimitiveTriangleIndicesEXT")
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInPrimitiveTriangleIndicesEXT,
+ inst);
+ if (name == "gl_PrimitiveLineIndicesEXT")
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInPrimitiveLineIndicesEXT,
+ inst);
+ if (name == "gl_PrimitivePointIndicesEXT")
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInPrimitivePointIndicesEXT,
+ inst);
}
return nullptr;
@@ -4881,7 +5024,8 @@ struct SPIRVEmitContext
auto ptrType = as<IRPtrType>(unwrapArray(inst->getDataType()));
if (!ptrType)
return;
- if (addressSpaceToStorageClass(ptrType->getAddressSpace()) == SpvStorageClassPhysicalStorageBuffer)
+ if (addressSpaceToStorageClass(ptrType->getAddressSpace()) ==
+ SpvStorageClassPhysicalStorageBuffer)
{
// If inst has a pointer type with PhysicalStorageBuffer address space,
// emit AliasedPointer decoration.
@@ -4889,8 +5033,7 @@ struct SPIRVEmitContext
getSection(SpvLogicalSectionID::Annotations),
nullptr,
varInst,
- (as<IRVar>(inst) ? SpvDecorationAliasedPointer : SpvDecorationAliased)
- );
+ (as<IRVar>(inst) ? SpvDecorationAliasedPointer : SpvDecorationAliased));
}
else
{
@@ -4899,15 +5042,17 @@ struct SPIRVEmitContext
ptrType = as<IRPtrType>(unwrapArray(ptrType->getValueType()));
if (!ptrType)
return;
- if (addressSpaceToStorageClass(ptrType->getAddressSpace()) == SpvStorageClassPhysicalStorageBuffer)
+ if (addressSpaceToStorageClass(ptrType->getAddressSpace()) ==
+ SpvStorageClassPhysicalStorageBuffer)
{
emitOpDecorate(
getSection(SpvLogicalSectionID::Annotations),
nullptr,
varInst,
- (inst->getOp() == kIROp_GlobalVar || inst->getOp() == kIROp_Var || inst->getOp() == kIROp_DebugVar
- ? SpvDecorationAliasedPointer : SpvDecorationAliased)
- );
+ (inst->getOp() == kIROp_GlobalVar || inst->getOp() == kIROp_Var ||
+ inst->getOp() == kIROp_DebugVar
+ ? SpvDecorationAliasedPointer
+ : SpvDecorationAliased));
}
}
}
@@ -4932,15 +5077,15 @@ struct SPIRVEmitContext
return varSpvInst;
}
- /// Cached `IRParam` indices in an `IRBlock`. For use in `getParamIndexInBlock`.
+ /// Cached `IRParam` indices in an `IRBlock`. For use in `getParamIndexInBlock`.
struct BlockParamIndexInfo : public RefObject
{
Dictionary<IRParam*, int> mapParamToIndex;
};
Dictionary<IRBlock*, RefPtr<BlockParamIndexInfo>> m_mapIRBlockToParamIndexInfo;
- /// Returns the index of an `IRParam` inside a `IRBlock`.
- /// The results are cached in `m_mapIRBlockToParamIndexInfo` to avoid linear search.
+ /// Returns the index of an `IRParam` inside a `IRBlock`.
+ /// The results are cached in `m_mapIRBlockToParamIndexInfo` to avoid linear search.
int getParamIndexInBlock(IRBlock* block, IRParam* paramInst)
{
RefPtr<BlockParamIndexInfo> info;
@@ -4973,10 +5118,8 @@ struct SPIRVEmitContext
{
case kIROp_Func:
case kIROp_GlobalParam:
- case kIROp_GlobalVar:
- return true;
- default:
- return false;
+ case kIROp_GlobalVar: return true;
+ default: return false;
}
}
@@ -5001,9 +5144,11 @@ struct SPIRVEmitContext
loopHeaderBlock,
nullptr,
getIRInstSpvID(loopInst->getBreakBlock()),
- SpvSelectionControlMaskNone
- );
- emitInst(loopHeaderBlock, nullptr, SpvOpSwitch,
+ SpvSelectionControlMaskNone);
+ emitInst(
+ loopHeaderBlock,
+ nullptr,
+ SpvOpSwitch,
emitIntConstant(0, builder.getIntType()),
getIRInstSpvID(loopInst->getTargetBlock()));
return;
@@ -5020,8 +5165,7 @@ struct SPIRVEmitContext
case IRLoopControl::kIRLoopControl_Loop:
loopControl = SpvLoopControlDontUnrollMask;
break;
- default:
- break;
+ default: break;
}
}
emitOpLoopMerge(
@@ -5029,8 +5173,7 @@ struct SPIRVEmitContext
nullptr,
getIRInstSpvID(loopInst->getBreakBlock()),
getIRInstSpvID(loopInst->getContinueBlock()),
- loopControl
- );
+ loopControl);
emitOpBranch(loopHeaderBlock, nullptr, loopInst->getTargetBlock());
}
@@ -5058,42 +5201,43 @@ struct SPIRVEmitContext
int paramIndex = getParamIndexInBlock(block, inst);
// Emit a Phi instruction.
- auto phiSpvInst = emitInstCustomOperandFunc(parent, inst, SpvOpPhi, [&]() {
- emitOperand(inst->getFullType());
- emitOperand(kResultID);
- // Find phi arguments from incoming branch instructions that target `block`.
- for (auto use = block->firstUse; use; use = use->nextUse)
- {
- auto branchInst = as<IRUnconditionalBranch>(use->getUser());
- if (!branchInst)
- continue;
- if (branchInst->getTargetBlock() != inst->getParent())
- continue;
-
- UInt argStartIndex = 0;
- switch (branchInst->getOp())
+ auto phiSpvInst = emitInstCustomOperandFunc(
+ parent,
+ inst,
+ SpvOpPhi,
+ [&]()
+ {
+ emitOperand(inst->getFullType());
+ emitOperand(kResultID);
+ // Find phi arguments from incoming branch instructions that target `block`.
+ for (auto use = block->firstUse; use; use = use->nextUse)
{
- case kIROp_unconditionalBranch:
- argStartIndex = 1;
- break;
- case kIROp_loop:
- argStartIndex = 3;
- break;
- default:
- // A phi argument can only come from an unconditional branch inst.
- // Other uses are not relavent so we should skip.
- continue;
+ auto branchInst = as<IRUnconditionalBranch>(use->getUser());
+ if (!branchInst)
+ continue;
+ if (branchInst->getTargetBlock() != inst->getParent())
+ continue;
+
+ UInt argStartIndex = 0;
+ switch (branchInst->getOp())
+ {
+ case kIROp_unconditionalBranch: argStartIndex = 1; break;
+ case kIROp_loop: argStartIndex = 3; break;
+ default:
+ // A phi argument can only come from an unconditional branch inst.
+ // Other uses are not relavent so we should skip.
+ continue;
+ }
+ SLANG_ASSERT(argStartIndex + paramIndex < branchInst->getOperandCount());
+ auto valueInst = branchInst->getOperand(argStartIndex + paramIndex);
+ if (isGlobalValueInst(valueInst))
+ ensureInst(valueInst);
+ emitOperand(getIRInstSpvID(valueInst));
+ auto sourceBlock = as<IRBlock>(branchInst->getParent());
+ SLANG_ASSERT(sourceBlock);
+ emitOperand(getIRInstSpvID(sourceBlock));
}
- SLANG_ASSERT(argStartIndex + paramIndex < branchInst->getOperandCount());
- auto valueInst = branchInst->getOperand(argStartIndex + paramIndex);
- if (isGlobalValueInst(valueInst))
- ensureInst(valueInst);
- emitOperand(getIRInstSpvID(valueInst));
- auto sourceBlock = as<IRBlock>(branchInst->getParent());
- SLANG_ASSERT(sourceBlock);
- emitOperand(getIRInstSpvID(sourceBlock));
- }
- });
+ });
maybeEmitName(phiSpvInst, inst);
return phiSpvInst;
@@ -5109,7 +5253,8 @@ struct SPIRVEmitContext
// We want to detect any call to an intrinsic operation, and inline
// the SPIRV snippet directly at the call site.
if (auto targetIntrinsic = Slang::findBestTargetIntrinsicDecoration(
- funcValue, m_targetRequest->getTargetCaps()))
+ funcValue,
+ m_targetRequest->getTargetCaps()))
{
return emitIntrinsicCallExpr(parent, static_cast<IRCall*>(inst), targetIntrinsic);
}
@@ -5128,8 +5273,7 @@ struct SPIRVEmitContext
inst,
inst->getFullType(),
funcValue,
- inst->getArgsList()
- );
+ inst->getArgsList());
}
}
@@ -5164,7 +5308,7 @@ struct SPIRVEmitContext
{
IRBuilder builder(m_irModule);
builder.setInsertBefore(inst);
- if(snippet->usedPtrResultTypeStorageClasses.getCount())
+ if (snippet->usedPtrResultTypeStorageClasses.getCount())
SLANG_UNIMPLEMENTED_X("specifying storage classes in __target_intrinsic modifiers");
}
return emitSpvSnippet(parent, inst, context, snippet);
@@ -5194,15 +5338,16 @@ struct SPIRVEmitContext
result = emitOpConstantComposite(
nullptr,
builder.getVectorType(floatType, builder.getIntValue(builder.getIntType(), 2)),
- makeArray(element1, element2)
- );
+ makeArray(element1, element2));
}
break;
case SpvSnippet::ASMType::Int:
result = emitIntConstant((IRIntegerValue)constant.intValues[0], builder.getIntType());
break;
case SpvSnippet::ASMType::UInt16:
- result = emitIntConstant((IRIntegerValue)constant.intValues[0], builder.getType(kIROp_UInt16Type));
+ result = emitIntConstant(
+ (IRIntegerValue)constant.intValues[0],
+ builder.getType(kIROp_UInt16Type));
break;
case SpvSnippet::ASMType::UInt2:
{
@@ -5212,8 +5357,7 @@ struct SPIRVEmitContext
result = emitOpConstantComposite(
nullptr,
builder.getVectorType(uintType, builder.getIntValue(builder.getIntType(), 2)),
- makeArray(element1, element2)
- );
+ makeArray(element1, element2));
}
break;
}
@@ -5229,31 +5373,22 @@ struct SPIRVEmitContext
IRType* irType = nullptr;
switch (type)
{
- case SpvSnippet::ASMType::Float:
- irType = builder.getType(kIROp_FloatType);
- break;
- case SpvSnippet::ASMType::Half:
- irType = builder.getType(kIROp_HalfType);
- break;
- case SpvSnippet::ASMType::Int:
- irType = builder.getIntType();
- break;
- case SpvSnippet::ASMType::UInt:
- irType = builder.getUIntType();
- break;
- case SpvSnippet::ASMType::UInt16:
- irType = builder.getType(kIROp_UInt16Type);
- break;
+ case SpvSnippet::ASMType::Float: irType = builder.getType(kIROp_FloatType); break;
+ case SpvSnippet::ASMType::Half: irType = builder.getType(kIROp_HalfType); break;
+ case SpvSnippet::ASMType::Int: irType = builder.getIntType(); break;
+ case SpvSnippet::ASMType::UInt: irType = builder.getUIntType(); break;
+ case SpvSnippet::ASMType::UInt16: irType = builder.getType(kIROp_UInt16Type); break;
case SpvSnippet::ASMType::Float2:
irType = builder.getVectorType(
- builder.getType(kIROp_FloatType), builder.getIntValue(builder.getIntType(), 2));
+ builder.getType(kIROp_FloatType),
+ builder.getIntValue(builder.getIntType(), 2));
break;
case SpvSnippet::ASMType::UInt2:
irType = builder.getVectorType(
- builder.getType(kIROp_UIntType), builder.getIntValue(builder.getIntType(), 2));
+ builder.getType(kIROp_UIntType),
+ builder.getIntValue(builder.getIntType(), 2));
break;
- default:
- SLANG_UNEXPECTED("unhandled case in emitSpvSnippetASMTypeOperand");
+ default: SLANG_UNEXPECTED("unhandled case in emitSpvSnippetASMTypeOperand");
}
emitOperand(irType);
}
@@ -5274,16 +5409,12 @@ struct SPIRVEmitContext
{
switch (operand.type)
{
- case SpvSnippet::ASMOperandType::SpvWord:
- emitOperand(operand.content);
- break;
+ case SpvSnippet::ASMOperandType::SpvWord: emitOperand(operand.content); break;
case SpvSnippet::ASMOperandType::ObjectReference:
SLANG_ASSERT(operand.content < (SpvWord)context.argumentIds.getCount());
emitOperand(context.argumentIds[operand.content]);
break;
- case SpvSnippet::ASMOperandType::ResultId:
- emitOperand(kResultID);
- break;
+ case SpvSnippet::ASMOperandType::ResultId: emitOperand(kResultID); break;
case SpvSnippet::ASMOperandType::ResultTypeId:
{
emitOperand(context.resultType);
@@ -5335,14 +5466,11 @@ struct SPIRVEmitContext
{
switch (extractBaseType(context.irResultType))
{
- case BaseType::Float:
- constant.type = SpvSnippet::ASMType::Float;
- break;
+ case BaseType::Float: constant.type = SpvSnippet::ASMType::Float; break;
case BaseType::Double:
constant.type = SpvSnippet::ASMType::Double;
break;
- default:
- break;
+ default: break;
}
}
SpvInst* spvConstant = maybeEmitSpvConstant(constant);
@@ -5413,14 +5541,9 @@ struct SPIRVEmitContext
else
{
baseStructType = as<IRStructType>(base->getDataType());
-
+
auto structPtrType = builder.getPtrType(baseStructType);
- auto varInst = emitOpVariable(
- parent,
- nullptr,
- structPtrType,
- SpvStorageClassFunction
- );
+ auto varInst = emitOpVariable(parent, nullptr, structPtrType, SpvStorageClassFunction);
emitOpStore(parent, nullptr, varInst, base);
baseId = getID(varInst);
}
@@ -5434,8 +5557,7 @@ struct SPIRVEmitContext
fieldAddress,
fieldAddress->getFullType(),
baseId,
- makeArray(fieldId)
- );
+ makeArray(fieldId));
}
SpvInst* emitFieldExtract(SpvInstParent* parent, IRFieldExtract* inst)
@@ -5445,22 +5567,25 @@ struct SPIRVEmitContext
IRStructType* baseStructType = as<IRStructType>(inst->getBase()->getDataType());
SLANG_ASSERT(baseStructType && "field_extract requires base to be a struct.");
- auto fieldId = static_cast<SpvWord>(getStructFieldId(
- baseStructType,
- as<IRStructKey>(inst->getField())));
-
+ auto fieldId = static_cast<SpvWord>(
+ getStructFieldId(baseStructType, as<IRStructKey>(inst->getField())));
+
return emitOpCompositeExtract(
parent,
inst,
inst->getDataType(),
inst->getBase(),
- makeArray(SpvLiteralInteger::from32(fieldId))
- );
+ makeArray(SpvLiteralInteger::from32(fieldId)));
}
SpvInst* emitGetOffsetPtr(SpvInstParent* parent, IRInst* inst)
{
- return emitOpPtrAccessChain(parent, inst, inst->getDataType(), inst->getOperand(0), inst->getOperand(1));
+ return emitOpPtrAccessChain(
+ parent,
+ inst,
+ inst->getDataType(),
+ inst->getOperand(0),
+ inst->getOperand(1));
}
SpvInst* emitGetElementPtr(SpvInstParent* parent, IRGetElementPtr* inst)
@@ -5473,24 +5598,27 @@ struct SPIRVEmitContext
auto resultType = as<IRPtrTypeBase>(inst->getDataType());
SLANG_ASSERT(resultType);
- if(const auto basePtrType = as<IRPtrTypeBase>(base->getDataType()))
+ if (const auto basePtrType = as<IRPtrTypeBase>(base->getDataType()))
{
// If the base pointer has a specific address space and the
// expected result type doesn't, then make sure they match.
// It's invalid spir-v if they don't match
- resultType = getPtrTypeWithAddressSpace(cast<IRPtrTypeBase>(inst->getDataType()), basePtrType->getAddressSpace());
+ resultType = getPtrTypeWithAddressSpace(
+ cast<IRPtrTypeBase>(inst->getDataType()),
+ basePtrType->getAddressSpace());
}
else
{
- SLANG_ASSERT(as<IRPointerLikeType>(base->getDataType()) || !"invalid IR: base of getElementPtr must be a pointer.");
+ SLANG_ASSERT(
+ as<IRPointerLikeType>(base->getDataType()) ||
+ !"invalid IR: base of getElementPtr must be a pointer.");
}
return emitOpAccessChain(
parent,
inst,
inst->getFullType(),
baseId,
- makeArray(inst->getIndex())
- );
+ makeArray(inst->getIndex()));
}
SpvInst* emitGetElement(SpvInstParent* parent, IRGetElement* inst)
@@ -5499,9 +5627,7 @@ struct SPIRVEmitContext
auto base = inst->getBase();
const auto baseTy = base->getDataType();
SLANG_ASSERT(
- as<IRPointerLikeType>(baseTy) ||
- as<IRArrayType>(baseTy) ||
- as<IRVectorType>(baseTy) ||
+ as<IRPointerLikeType>(baseTy) || as<IRArrayType>(baseTy) || as<IRVectorType>(baseTy) ||
as<IRMatrixType>(baseTy));
IRBuilder builder(m_irModule);
@@ -5516,25 +5642,38 @@ struct SPIRVEmitContext
inst,
inst->getFullType(),
inst->getBase(),
- makeArray(SpvLiteralInteger::from32((int32_t)index->getValue()))
- );
+ makeArray(SpvLiteralInteger::from32((int32_t)index->getValue())));
}
else
{
SLANG_ASSERT(as<IRVectorType>(baseTy));
// SPIRV Only allows dynamic element extract on vector types.
- return emitOpVectorExtractDynamic(parent, inst, inst->getFullType(), inst->getBase(), inst->getIndex());
+ return emitOpVectorExtractDynamic(
+ parent,
+ inst,
+ inst->getFullType(),
+ inst->getBase(),
+ inst->getIndex());
}
}
SpvInst* emitLoad(SpvInstParent* parent, IRLoad* inst)
{
auto ptrType = as<IRPtrTypeBase>(inst->getPtr()->getDataType());
- if (ptrType && addressSpaceToStorageClass(ptrType->getAddressSpace()) == SpvStorageClassPhysicalStorageBuffer)
+ if (ptrType && addressSpaceToStorageClass(ptrType->getAddressSpace()) ==
+ SpvStorageClassPhysicalStorageBuffer)
{
IRSizeAndAlignment sizeAndAlignment;
- getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), ptrType->getValueType(), &sizeAndAlignment);
- return emitOpLoadAligned(parent, inst, inst->getDataType(), inst->getPtr(), SpvLiteralInteger::from32(sizeAndAlignment.alignment));
+ getNaturalSizeAndAlignment(
+ m_targetProgram->getOptionSet(),
+ ptrType->getValueType(),
+ &sizeAndAlignment);
+ return emitOpLoadAligned(
+ parent,
+ inst,
+ inst->getDataType(),
+ inst->getPtr(),
+ SpvLiteralInteger::from32(sizeAndAlignment.alignment));
}
else
{
@@ -5545,11 +5684,20 @@ struct SPIRVEmitContext
SpvInst* emitStore(SpvInstParent* parent, IRStore* inst)
{
auto ptrType = as<IRPtrTypeBase>(inst->getPtr()->getDataType());
- if (ptrType && addressSpaceToStorageClass(ptrType->getAddressSpace()) == SpvStorageClassPhysicalStorageBuffer)
+ if (ptrType && addressSpaceToStorageClass(ptrType->getAddressSpace()) ==
+ SpvStorageClassPhysicalStorageBuffer)
{
IRSizeAndAlignment sizeAndAlignment;
- getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), ptrType->getValueType(), &sizeAndAlignment);
- return emitOpStoreAligned(parent, inst, inst->getPtr(), inst->getVal(), SpvLiteralInteger::from32(sizeAndAlignment.alignment));
+ getNaturalSizeAndAlignment(
+ m_targetProgram->getOptionSet(),
+ ptrType->getValueType(),
+ &sizeAndAlignment);
+ return emitOpStoreAligned(
+ parent,
+ inst,
+ inst->getPtr(),
+ inst->getVal(),
+ SpvLiteralInteger::from32(sizeAndAlignment.alignment));
}
else
{
@@ -5562,7 +5710,9 @@ struct SPIRVEmitContext
auto sourceVectorType = as<IRVectorType>(inst->getSource()->getDataType());
SLANG_ASSERT(sourceVectorType);
auto sourceElementType = sourceVectorType->getElementType();
- SLANG_ASSERT(getIntVal(sourceVectorType->getElementCount()) == (IRIntegerValue)inst->getElementCount());
+ SLANG_ASSERT(
+ getIntVal(sourceVectorType->getElementCount()) ==
+ (IRIntegerValue)inst->getElementCount());
SpvInst* result = nullptr;
IRBuilder builder(inst);
builder.setInsertBefore(inst);
@@ -5574,9 +5724,20 @@ struct SPIRVEmitContext
for (UInt i = 0; i < inst->getElementCount(); i++)
{
auto index = inst->getElementIndex(i);
- auto addr = emitOpAccessChain(parent, nullptr, ptrElementType, inst->getDest(), makeArray(index));
- auto val = emitOpCompositeExtract(parent, nullptr, sourceElementType, inst->getSource(), makeArray(SpvLiteralInteger::from32((int32_t)i)));
- result = emitOpStore(parent, (i == inst->getElementCount() - 1 ? inst : nullptr), addr, val);
+ auto addr = emitOpAccessChain(
+ parent,
+ nullptr,
+ ptrElementType,
+ inst->getDest(),
+ makeArray(index));
+ auto val = emitOpCompositeExtract(
+ parent,
+ nullptr,
+ sourceElementType,
+ inst->getSource(),
+ makeArray(SpvLiteralInteger::from32((int32_t)i)));
+ result =
+ emitOpStore(parent, (i == inst->getElementCount() - 1 ? inst : nullptr), addr, val);
}
return result;
}
@@ -5587,7 +5748,13 @@ struct SPIRVEmitContext
{
auto index = inst->getElementIndex(0);
if (auto intLit = as<IRIntLit>(index))
- return emitOpCompositeInsert(parent, inst, inst->getFullType(), inst->getSource(), inst->getBase(), makeArray(SpvLiteralInteger::from32((uint32_t)intLit->value.intVal)));
+ return emitOpCompositeInsert(
+ parent,
+ inst,
+ inst->getFullType(),
+ inst->getSource(),
+ inst->getBase(),
+ makeArray(SpvLiteralInteger::from32((uint32_t)intLit->value.intVal)));
}
auto resultVectorType = as<IRVectorType>(inst->getDataType());
List<SpvLiteralInteger> shuffleIndices;
@@ -5599,7 +5766,8 @@ struct SPIRVEmitContext
{
auto destIndex = (int32_t)getIntVal(inst->getElementIndex(i));
SLANG_ASSERT(destIndex < shuffleIndices.getCount());
- shuffleIndices[destIndex] = SpvLiteralInteger::from32((int32_t)(i + shuffleIndices.getCount()));
+ shuffleIndices[destIndex] =
+ SpvLiteralInteger::from32((int32_t)(i + shuffleIndices.getCount()));
}
auto source = inst->getSource();
if (!as<IRVectorType>(source->getDataType()))
@@ -5608,13 +5776,21 @@ struct SPIRVEmitContext
builder.setInsertBefore(inst);
source = builder.emitMakeVectorFromScalar(resultVectorType, source);
}
- return emitOpVectorShuffle(parent, inst, inst->getFullType(), inst->getBase(), inst->getSource(), shuffleIndices.getArrayView());
+ return emitOpVectorShuffle(
+ parent,
+ inst,
+ inst->getFullType(),
+ inst->getBase(),
+ inst->getSource(),
+ shuffleIndices.getArrayView());
}
- IRPtrTypeBase* getPtrTypeWithAddressSpace(IRPtrTypeBase* ptrTypeWithNoAddressSpace, AddressSpace addressSpace)
+ IRPtrTypeBase* getPtrTypeWithAddressSpace(
+ IRPtrTypeBase* ptrTypeWithNoAddressSpace,
+ AddressSpace addressSpace)
{
// If it's already ok, return as is
- if(ptrTypeWithNoAddressSpace->getAddressSpace() == addressSpace)
+ if (ptrTypeWithNoAddressSpace->getAddressSpace() == addressSpace)
return ptrTypeWithNoAddressSpace;
// It has an address space, but it doesn't match then fail, this
@@ -5625,29 +5801,35 @@ struct SPIRVEmitContext
return builder.getPtrType(
ptrTypeWithNoAddressSpace->getOp(),
ptrTypeWithNoAddressSpace->getValueType(),
- addressSpace
- );
+ addressSpace);
}
SpvInst* emitStructuredBufferGetElementPtr(SpvInstParent* parent, IRInst* inst)
{
//"%addr = OpAccessChain resultType*StorageBuffer resultId _0 const(int, 0) _1;"
IRBuilder builder(inst);
- auto addressSpace = isSpirv14OrLater() ? AddressSpace::StorageBuffer : AddressSpace::Uniform;
+ auto addressSpace =
+ isSpirv14OrLater() ? AddressSpace::StorageBuffer : AddressSpace::Uniform;
return emitOpAccessChain(
parent,
inst,
// Make sure the resulting pointer has the correct storage class
getPtrTypeWithAddressSpace(cast<IRPtrTypeBase>(inst->getDataType()), addressSpace),
inst->getOperand(0),
- makeArray(emitIntConstant(0, builder.getIntType()), ensureInst(inst->getOperand(1)))
- );
+ makeArray(emitIntConstant(0, builder.getIntType()), ensureInst(inst->getOperand(1))));
}
SpvInst* emitStructuredBufferGetDimensions(SpvInstParent* parent, IRInst* inst)
{
IRBuilder builder(inst);
- auto arrayLength = emitInst(parent, nullptr, SpvOpArrayLength, builder.getUIntType(), kResultID, inst->getOperand(0), SpvLiteralInteger::from32(0));
+ auto arrayLength = emitInst(
+ parent,
+ nullptr,
+ SpvOpArrayLength,
+ builder.getUIntType(),
+ kResultID,
+ inst->getOperand(0),
+ SpvLiteralInteger::from32(0));
auto elementType = as<IRPtrType>(inst->getOperand(0)->getDataType())->getValueType();
IRIntegerValue stride = 0;
if (auto sizeDecor = elementType->findDecoration<IRSizeAndAlignmentDecoration>())
@@ -5655,7 +5837,8 @@ struct SPIRVEmitContext
stride = align(sizeDecor->getSize(), (int)sizeDecor->getAlignment());
}
auto strideOperand = emitIntConstant(stride, builder.getUIntType());
- auto result = emitOpCompositeConstruct(parent, inst, inst->getDataType(), arrayLength, strideOperand);
+ auto result =
+ emitOpCompositeConstruct(parent, inst, inst->getDataType(), arrayLength, strideOperand);
return result;
}
@@ -5669,22 +5852,26 @@ struct SPIRVEmitContext
inst,
inst->getDataType(),
inst->getBase(),
- makeArray(SpvLiteralInteger::from32(int32_t(index)))
- );
+ makeArray(SpvLiteralInteger::from32(int32_t(index))));
}
else
{
- return emitInstCustomOperandFunc(parent, inst, SpvOpVectorShuffle, [&]() {
- emitOperand(inst->getDataType());
- emitOperand(kResultID);
- emitOperand(inst->getBase());
- emitOperand(inst->getBase());
- for (UInt i = 0; i < inst->getElementCount(); i++)
+ return emitInstCustomOperandFunc(
+ parent,
+ inst,
+ SpvOpVectorShuffle,
+ [&]()
{
- auto index = as<IRIntLit>(inst->getElementIndex(i));
- emitOperand((SpvWord)index->getValue());
- }
- });
+ emitOperand(inst->getDataType());
+ emitOperand(kResultID);
+ emitOperand(inst->getBase());
+ emitOperand(inst->getBase());
+ for (UInt i = 0; i < inst->getElementCount(); i++)
+ {
+ auto index = as<IRIntLit>(inst->getElementIndex(i));
+ emitOperand((SpvWord)index->getValue());
+ }
+ });
}
}
@@ -5705,12 +5892,28 @@ struct SPIRVEmitContext
auto one = builder.getIntValue(toType, 1);
if (auto vecType = as<IRVectorType>(toTypeV))
{
- auto zeroV = emitSplat(parent, nullptr, zero, getIntVal(vecType->getElementCount()));
+ auto zeroV =
+ emitSplat(parent, nullptr, zero, getIntVal(vecType->getElementCount()));
auto oneV = emitSplat(parent, nullptr, one, getIntVal(vecType->getElementCount()));
- return emitInst(parent, inst, SpvOpSelect, inst->getFullType(), kResultID, inst->getOperand(0),
- oneV, zeroV);
+ return emitInst(
+ parent,
+ inst,
+ SpvOpSelect,
+ inst->getFullType(),
+ kResultID,
+ inst->getOperand(0),
+ oneV,
+ zeroV);
}
- return emitInst(parent, inst, SpvOpSelect, inst->getFullType(), kResultID, inst->getOperand(0), one, zero);
+ return emitInst(
+ parent,
+ inst,
+ SpvOpSelect,
+ inst->getFullType(),
+ kResultID,
+ inst->getOperand(0),
+ one,
+ zero);
}
else if (as<IRBoolType>(toType))
{
@@ -5720,12 +5923,23 @@ struct SPIRVEmitContext
auto zero = builder.getIntValue(fromType, 0);
if (auto vecType = as<IRVectorType>(toTypeV))
{
- auto zeroV = emitSplat(parent, nullptr, zero, getIntVal(vecType->getElementCount()));
- return emitOpINotEqual(parent, inst, inst->getFullType(), inst->getOperand(0), zeroV);
+ auto zeroV =
+ emitSplat(parent, nullptr, zero, getIntVal(vecType->getElementCount()));
+ return emitOpINotEqual(
+ parent,
+ inst,
+ inst->getFullType(),
+ inst->getOperand(0),
+ zeroV);
}
else
{
- return emitOpINotEqual(parent, inst, inst->getFullType(), inst->getOperand(0), zero);
+ return emitOpINotEqual(
+ parent,
+ inst,
+ inst->getFullType(),
+ inst->getOperand(0),
+ zero);
}
}
@@ -5735,29 +5949,34 @@ struct SPIRVEmitContext
const auto fromInfo = getIntTypeInfo(fromType);
const auto toInfo = getIntTypeInfo(toType);
- if(fromInfo == toInfo)
+ if (fromInfo == toInfo)
return emitOpCopyObject(parent, inst, toTypeV, inst->getOperand(0));
- else if(fromInfo.width == toInfo.width)
+ else if (fromInfo.width == toInfo.width)
return emitOpBitcast(parent, inst, toTypeV, inst->getOperand(0));
- else if(!fromInfo.isSigned && !toInfo.isSigned)
+ else if (!fromInfo.isSigned && !toInfo.isSigned)
// unsigned to unsigned, don't sign extend
return emitOpUConvert(parent, inst, toTypeV, inst->getOperand(0));
- else if(toInfo.isSigned)
+ else if (toInfo.isSigned)
// unsigned to signed, sign extend
return emitOpSConvert(parent, inst, toTypeV, inst->getOperand(0));
- else if(fromInfo.isSigned)
+ else if (fromInfo.isSigned)
// signed to unsigned, sign extend
return emitOpSConvert(parent, inst, toTypeV, inst->getOperand(0));
- else if(fromInfo.isSigned && toInfo.isSigned)
+ else if (fromInfo.isSigned && toInfo.isSigned)
// signed to signed, sign extend
return emitOpSConvert(parent, inst, toTypeV, inst->getOperand(0));
SLANG_UNREACHABLE(__func__);
}
- SpvInst* emitFloatCastForMatrix(SpvInstParent* parent, IRFloatCast* inst, IRMatrixType* fromTypeM, IRMatrixType* toTypeM)
+ SpvInst* emitFloatCastForMatrix(
+ SpvInstParent* parent,
+ IRFloatCast* inst,
+ IRMatrixType* fromTypeM,
+ IRMatrixType* toTypeM)
{
- // Because there is no spirv instruction to convert matrix to matrix, we need to convert it row by row.
+ // Because there is no spirv instruction to convert matrix to matrix, we need to convert it
+ // row by row.
auto rowCount = getIntVal(fromTypeM->getRowCount());
auto colCount = getIntVal(fromTypeM->getColumnCount());
@@ -5770,8 +5989,12 @@ struct SPIRVEmitContext
// convert each row vector to toType.
for (uint32_t i = 0; i < rowCount; i++)
{
- auto rowVector = emitOpCompositeExtract(parent, nullptr, fromTypeV,
- inst->getOperand(0), makeArray(SpvLiteralInteger::from32(i)));
+ auto rowVector = emitOpCompositeExtract(
+ parent,
+ nullptr,
+ fromTypeV,
+ inst->getOperand(0),
+ makeArray(SpvLiteralInteger::from32(i)));
auto rowVectorConverted = emitOpFConvert(parent, nullptr, toVectorV, rowVector);
rowVectorsConverted.add(rowVectorConverted);
@@ -5807,13 +6030,15 @@ struct SPIRVEmitContext
toType = toTypeV;
}
- // We'd better give some diagnostics to at least point out which line in the shader is wrong, so
- // it can help the user or developers to locate the issue easier.
- if (!isFloatingType(fromType)) {
+ // We'd better give some diagnostics to at least point out which line in the shader is
+ // wrong, so it can help the user or developers to locate the issue easier.
+ if (!isFloatingType(fromType))
+ {
m_sink->diagnose(inst, Diagnostics::internalCompilerError);
}
- if (!isFloatingType(toType)) {
+ if (!isFloatingType(toType))
+ {
m_sink->diagnose(inst, Diagnostics::internalCompilerError);
}
@@ -5823,7 +6048,11 @@ struct SPIRVEmitContext
if (isMatrixCast)
{
- return emitFloatCastForMatrix(parent, inst, as<IRMatrixType>(fromTypeV), as<IRMatrixType>(toTypeV));
+ return emitFloatCastForMatrix(
+ parent,
+ inst,
+ as<IRMatrixType>(fromTypeV),
+ as<IRMatrixType>(toTypeV));
}
return emitOpFConvert(parent, inst, toTypeV, inst->getOperand(0));
@@ -5843,8 +6072,8 @@ struct SPIRVEmitContext
const auto fromInfo = getIntTypeInfo(fromType);
return fromInfo.isSigned
- ? emitOpConvertSToF(parent, inst, toTypeV, inst->getOperand(0))
- : emitOpConvertUToF(parent, inst, toTypeV, inst->getOperand(0));
+ ? emitOpConvertSToF(parent, inst, toTypeV, inst->getOperand(0))
+ : emitOpConvertUToF(parent, inst, toTypeV, inst->getOperand(0));
}
else if (as<IRBoolType>(fromType))
{
@@ -5857,7 +6086,15 @@ struct SPIRVEmitContext
one = builder.emitMakeVectorFromScalar(toTypeV, one);
zero = builder.emitMakeVectorFromScalar(toTypeV, zero);
}
- return emitInst(parent, inst, SpvOpSelect, inst->getFullType(), kResultID, inst->getOperand(0), one, zero);
+ return emitInst(
+ parent,
+ inst,
+ SpvOpSelect,
+ inst->getFullType(),
+ kResultID,
+ inst->getOperand(0),
+ one,
+ zero);
}
else
{
@@ -5882,12 +6119,27 @@ struct SPIRVEmitContext
auto zero = builder.getIntValue(fromType, 0);
if (auto vecType = as<IRVectorType>(toTypeV))
{
- auto zeroV = emitSplat(parent, nullptr, zero, getIntVal(vecType->getElementCount()));
- return emitInst(parent, inst, SpvOpFUnordNotEqual, inst->getFullType(), kResultID, inst->getOperand(0), zeroV);
+ auto zeroV =
+ emitSplat(parent, nullptr, zero, getIntVal(vecType->getElementCount()));
+ return emitInst(
+ parent,
+ inst,
+ SpvOpFUnordNotEqual,
+ inst->getFullType(),
+ kResultID,
+ inst->getOperand(0),
+ zeroV);
}
else
{
- return emitInst(parent, inst, SpvOpFUnordNotEqual, inst->getFullType(), kResultID, inst->getOperand(0), zero);
+ return emitInst(
+ parent,
+ inst,
+ SpvOpFUnordNotEqual,
+ inst->getFullType(),
+ kResultID,
+ inst->getOperand(0),
+ zero);
}
}
@@ -5895,26 +6147,48 @@ struct SPIRVEmitContext
const auto toInfo = getIntTypeInfo(toType);
- return toInfo.isSigned
- ? emitOpConvertFToS(parent, inst, toTypeV, inst->getOperand(0))
- : emitOpConvertFToU(parent, inst, toTypeV, inst->getOperand(0));
+ return toInfo.isSigned ? emitOpConvertFToS(parent, inst, toTypeV, inst->getOperand(0))
+ : emitOpConvertFToU(parent, inst, toTypeV, inst->getOperand(0));
}
SpvInst* emitCastPtrToInt(SpvInstParent* parent, IRInst* inst)
{
- return emitInst(parent, inst, SpvOpConvertPtrToU, inst->getFullType(), kResultID, inst->getOperand(0));
+ return emitInst(
+ parent,
+ inst,
+ SpvOpConvertPtrToU,
+ inst->getFullType(),
+ kResultID,
+ inst->getOperand(0));
}
SpvInst* emitCastPtrToBool(SpvInstParent* parent, IRInst* inst)
{
IRBuilder builder(inst);
- auto uintVal = emitInst(parent, nullptr, SpvOpConvertPtrToU, builder.getUInt64Type(), kResultID, inst->getOperand(0));
- return emitOpINotEqual(parent, inst, kResultID, uintVal, builder.getIntValue(builder.getUInt64Type(), 0));
+ auto uintVal = emitInst(
+ parent,
+ nullptr,
+ SpvOpConvertPtrToU,
+ builder.getUInt64Type(),
+ kResultID,
+ inst->getOperand(0));
+ return emitOpINotEqual(
+ parent,
+ inst,
+ kResultID,
+ uintVal,
+ builder.getIntValue(builder.getUInt64Type(), 0));
}
SpvInst* emitCastIntToPtr(SpvInstParent* parent, IRInst* inst)
{
- return emitInst(parent, inst, SpvOpConvertUToPtr, inst->getFullType(), kResultID, inst->getOperand(0));
+ return emitInst(
+ parent,
+ inst,
+ SpvOpConvertUToPtr,
+ inst->getFullType(),
+ kResultID,
+ inst->getOperand(0));
}
template<typename T, typename Ts>
@@ -6009,17 +6283,9 @@ struct SPIRVEmitContext
if (inst->getOperandCount() == 1)
{
if (inst->getDataType() == inst->getOperand(0)->getDataType())
- return emitOpCopyObject(
- parent,
- inst,
- inst->getFullType(),
- inst->getOperand(0));
+ return emitOpCopyObject(parent, inst, inst->getFullType(), inst->getOperand(0));
else
- return emitOpBitcast(
- parent,
- inst,
- inst->getFullType(),
- inst->getOperand(0));
+ return emitOpBitcast(parent, inst, inst->getFullType(), inst->getOperand(0));
}
else
{
@@ -6037,16 +6303,12 @@ struct SPIRVEmitContext
{
const auto scalarTy = as<IRBasicType>(scalar->getDataType());
SLANG_ASSERT(scalarTy);
- const auto spvVecTy = ensureVectorType(
- scalarTy->getBaseType(),
- numElems,
- nullptr);
+ const auto spvVecTy = ensureVectorType(scalarTy->getBaseType(), numElems, nullptr);
return emitCompositeConstruct(
parent,
inst,
spvVecTy,
- List<IRInst*>::makeRepeated(scalar, Index(numElems))
- );
+ List<IRInst*>::makeRepeated(scalar, Index(numElems)));
}
bool isSignedType(IRType* type)
@@ -6054,19 +6316,14 @@ struct SPIRVEmitContext
switch (type->getOp())
{
case kIROp_FloatType:
- case kIROp_DoubleType:
- return true;
+ case kIROp_DoubleType: return true;
case kIROp_IntType:
case kIROp_Int16Type:
case kIROp_Int64Type:
- case kIROp_Int8Type:
- return true;
- case kIROp_VectorType:
- return isSignedType(as<IRVectorType>(type)->getElementType());
- case kIROp_MatrixType:
- return isSignedType(as<IRMatrixType>(type)->getElementType());
- default:
- return false;
+ case kIROp_Int8Type: return true;
+ case kIROp_VectorType: return isSignedType(as<IRVectorType>(type)->getElementType());
+ case kIROp_MatrixType: return isSignedType(as<IRMatrixType>(type)->getElementType());
+ default: return false;
}
}
@@ -6076,18 +6333,20 @@ struct SPIRVEmitContext
{
case kIROp_FloatType:
case kIROp_DoubleType:
- case kIROp_HalfType:
- return true;
- case kIROp_VectorType:
- return isFloatType(as<IRVectorType>(type)->getElementType());
- case kIROp_MatrixType:
- return isFloatType(as<IRMatrixType>(type)->getElementType());
- default:
- return false;
+ case kIROp_HalfType: return true;
+ case kIROp_VectorType: return isFloatType(as<IRVectorType>(type)->getElementType());
+ case kIROp_MatrixType: return isFloatType(as<IRMatrixType>(type)->getElementType());
+ default: return false;
}
}
- SpvInst* emitVectorOrScalarArithmetic(SpvInstParent* parent, IRInst* instToRegister, IRInst* type, IROp op, UInt operandCount, ArrayView<IRInst*> operands)
+ SpvInst* emitVectorOrScalarArithmetic(
+ SpvInstParent* parent,
+ IRInst* instToRegister,
+ IRInst* type,
+ IROp op,
+ UInt operandCount,
+ ArrayView<IRInst*> operands)
{
IRType* elementType = getVectorElementType(operands[0]->getDataType());
IRBasicType* basicType = as<IRBasicType>(elementType);
@@ -6097,72 +6356,54 @@ struct SPIRVEmitContext
{
case BaseType::Float:
case BaseType::Double:
- case BaseType::Half:
- isFloatingPoint = true;
- break;
- case BaseType::Bool:
- isBool = true;
- break;
- default:
- break;
+ case BaseType::Half: isFloatingPoint = true; break;
+ case BaseType::Bool: isBool = true; break;
+ default: break;
}
SpvOp opCode = SpvOpUndef;
bool isSigned = isSignedType(basicType);
switch (op)
{
- case kIROp_Add:
- opCode = isFloatingPoint ? SpvOpFAdd : SpvOpIAdd;
- break;
- case kIROp_Sub:
- opCode = isFloatingPoint ? SpvOpFSub : SpvOpISub;
- break;
- case kIROp_Mul:
- opCode = isFloatingPoint ? SpvOpFMul : SpvOpIMul;
- break;
+ case kIROp_Add: opCode = isFloatingPoint ? SpvOpFAdd : SpvOpIAdd; break;
+ case kIROp_Sub: opCode = isFloatingPoint ? SpvOpFSub : SpvOpISub; break;
+ case kIROp_Mul: opCode = isFloatingPoint ? SpvOpFMul : SpvOpIMul; break;
case kIROp_Div:
opCode = isFloatingPoint ? SpvOpFDiv : isSigned ? SpvOpSDiv : SpvOpUDiv;
break;
- case kIROp_IRem:
- opCode = isSigned ? SpvOpSRem : SpvOpUMod;
- break;
- case kIROp_FRem:
- opCode = SpvOpFRem;
- break;
+ case kIROp_IRem: opCode = isSigned ? SpvOpSRem : SpvOpUMod; break;
+ case kIROp_FRem: opCode = SpvOpFRem; break;
case kIROp_Less:
opCode = isFloatingPoint ? SpvOpFOrdLessThan
- : isSigned ? SpvOpSLessThan : SpvOpULessThan;
+ : isSigned ? SpvOpSLessThan
+ : SpvOpULessThan;
break;
case kIROp_Leq:
opCode = isFloatingPoint ? SpvOpFOrdLessThanEqual
- : isSigned ? SpvOpSLessThanEqual : SpvOpULessThanEqual;
+ : isSigned ? SpvOpSLessThanEqual
+ : SpvOpULessThanEqual;
break;
case kIROp_Eql:
opCode = isFloatingPoint ? SpvOpFOrdEqual : isBool ? SpvOpLogicalEqual : SpvOpIEqual;
break;
case kIROp_Neq:
opCode = isFloatingPoint ? SpvOpFUnordNotEqual
- : isBool ? SpvOpLogicalNotEqual : SpvOpINotEqual;
+ : isBool ? SpvOpLogicalNotEqual
+ : SpvOpINotEqual;
break;
case kIROp_Geq:
opCode = isFloatingPoint ? SpvOpFOrdGreaterThanEqual
- : isSigned ? SpvOpSGreaterThanEqual : SpvOpUGreaterThanEqual;
+ : isSigned ? SpvOpSGreaterThanEqual
+ : SpvOpUGreaterThanEqual;
break;
case kIROp_Greater:
opCode = isFloatingPoint ? SpvOpFOrdGreaterThan
- : isSigned ? SpvOpSGreaterThan : SpvOpUGreaterThan;
- break;
- case kIROp_Neg:
- opCode = isFloatingPoint ? SpvOpFNegate : SpvOpSNegate;
- break;
- case kIROp_And:
- opCode = SpvOpLogicalAnd;
- break;
- case kIROp_Or:
- opCode = SpvOpLogicalOr;
- break;
- case kIROp_Not:
- opCode = SpvOpLogicalNot;
+ : isSigned ? SpvOpSGreaterThan
+ : SpvOpUGreaterThan;
break;
+ case kIROp_Neg: opCode = isFloatingPoint ? SpvOpFNegate : SpvOpSNegate; break;
+ case kIROp_And: opCode = SpvOpLogicalAnd; break;
+ case kIROp_Or: opCode = SpvOpLogicalOr; break;
+ case kIROp_Not: opCode = SpvOpLogicalNot; break;
case kIROp_BitAnd:
if (isBool)
opCode = SpvOpLogicalAnd;
@@ -6190,12 +6431,8 @@ struct SPIRVEmitContext
case kIROp_Rsh:
opCode = isSigned ? SpvOpShiftRightArithmetic : SpvOpShiftRightLogical;
break;
- case kIROp_Lsh:
- opCode = SpvOpShiftLeftLogical;
- break;
- default:
- SLANG_ASSERT(!"unknown arithmetic opcode");
- break;
+ case kIROp_Lsh: opCode = SpvOpShiftLeftLogical; break;
+ default: SLANG_ASSERT(!"unknown arithmetic opcode"); break;
}
if (operandCount == 1)
{
@@ -6211,17 +6448,28 @@ struct SPIRVEmitContext
{
if (lVec && !rVec)
{
- return emitInst(parent, instToRegister, SpvOpVectorTimesScalar, type, kResultID, operands);
+ return emitInst(
+ parent,
+ instToRegister,
+ SpvOpVectorTimesScalar,
+ type,
+ kResultID,
+ operands);
}
else if (!lVec && rVec)
{
- IRInst* newOperands[2] = { operands[1], operands[0] };
- return emitInst(parent, instToRegister, SpvOpVectorTimesScalar, type, kResultID, ArrayView<IRInst*>(newOperands, 2));
+ IRInst* newOperands[2] = {operands[1], operands[0]};
+ return emitInst(
+ parent,
+ instToRegister,
+ SpvOpVectorTimesScalar,
+ type,
+ kResultID,
+ ArrayView<IRInst*>(newOperands, 2));
}
}
- const auto go = [&](const auto l, const auto r) {
- return emitInst(parent, instToRegister, opCode, type, kResultID, l, r);
- };
+ const auto go = [&](const auto l, const auto r)
+ { return emitInst(parent, instToRegister, opCode, type, kResultID, l, r); };
if (lVec && !rVec)
{
const auto len = as<IRIntLit>(lVec->getElementCount());
@@ -6267,7 +6515,13 @@ struct SPIRVEmitContext
operands.add(originalOperand);
}
}
- rows.add(emitVectorOrScalarArithmetic(parent, nullptr, rowVectorType, inst->getOp(), inst->getOperandCount(), operands.getArrayView()));
+ rows.add(emitVectorOrScalarArithmetic(
+ parent,
+ nullptr,
+ rowVectorType,
+ inst->getOp(),
+ inst->getOperandCount(),
+ operands.getArrayView()));
}
return emitCompositeConstruct(parent, inst, inst->getDataType(), rows);
}
@@ -6275,7 +6529,13 @@ struct SPIRVEmitContext
Array<IRInst*, 4> operands;
for (UInt i = 0; i < inst->getOperandCount(); i++)
operands.add(inst->getOperand(i));
- return emitVectorOrScalarArithmetic(parent, inst, inst->getDataType(), inst->getOp(), inst->getOperandCount(), operands.getView());
+ return emitVectorOrScalarArithmetic(
+ parent,
+ inst,
+ inst->getDataType(),
+ inst->getOp(),
+ inst->getOperandCount(),
+ operands.getView());
}
SpvInst* emitDebugLine(SpvInstParent* parent, IRDebugLine* debugLine)
@@ -6283,7 +6543,11 @@ struct SPIRVEmitContext
auto scope = findDebugScope(debugLine);
if (!scope)
return nullptr;
- return emitOpDebugLine(parent, debugLine, debugLine->getFullType(), getNonSemanticDebugInfoExtInst(),
+ return emitOpDebugLine(
+ parent,
+ debugLine,
+ debugLine->getFullType(),
+ getNonSemanticDebugInfoExtInst(),
debugLine->getSource(),
debugLine->getLineStart(),
debugLine->getLineEnd(),
@@ -6304,7 +6568,11 @@ struct SPIRVEmitContext
return m_nullDwarfExpr;
}
- bool translateIRAccessChain(IRBuilder& builder, IRInst* baseType, const List<IRInst*>& irAccessChain, List<SpvInst*>& spvAccessChain)
+ bool translateIRAccessChain(
+ IRBuilder& builder,
+ IRInst* baseType,
+ const List<IRInst*>& irAccessChain,
+ List<SpvInst*>& spvAccessChain)
{
auto type = baseType;
for (Index i = 0; i < irAccessChain.getCount(); i++)
@@ -6335,7 +6603,9 @@ struct SPIRVEmitContext
else if (auto vectorType = as<IRVectorType>(type))
type = vectorType->getElementType();
else if (auto matrixType = as<IRMatrixType>(type))
- type = builder.getVectorType(matrixType->getElementType(), matrixType->getColumnCount());
+ type = builder.getVectorType(
+ matrixType->getElementType(),
+ matrixType->getColumnCount());
else
return false;
spvAccessChain.add(ensureInst(element));
@@ -6347,7 +6617,7 @@ struct SPIRVEmitContext
SpvInst* emitDebugValue(SpvInstParent* parent, IRDebugValue* debugValue)
{
// We are asked to update the value for a debug variable.
- // A debug variable is already emited as a OpDebugVariable +
+ // A debug variable is already emited as a OpDebugVariable +
// OpVariable + OpDebugDeclare. We only need to store the new value
// into the associated OpVariable. The `debugValue->getDebugVar()` inst
// already maps to the `OpVariable` SpvInst, so we just need to emit
@@ -6372,26 +6642,33 @@ struct SPIRVEmitContext
// If the root variable can't be represented by a normal variable,
// try to emit a DebugValue if possible. Usually this means that the variable
// represents a shader resource.
- //
+ //
// SPIR-V requires the access chain specified in a DebugValue operation to
// be fully static. We will skip emitting the debug inst if the access chain
// isn't static.
//
auto type = unwrapAttributedType(debugValue->getDebugVar()->getDataType());
List<SpvInst*> accessChain;
- bool isConstAccessChain = translateIRAccessChain(builder, type, irAccessChain, accessChain);
-
+ bool isConstAccessChain =
+ translateIRAccessChain(builder, type, irAccessChain, accessChain);
+
if (isConstAccessChain)
{
return emitOpDebugValue(
- parent, debugValue, m_voidType, getNonSemanticDebugInfoExtInst(),
- rootVar, debugValue->getValue(), getDwarfExpr(), accessChain);
+ parent,
+ debugValue,
+ m_voidType,
+ getNonSemanticDebugInfoExtInst(),
+ rootVar,
+ debugValue->getValue(),
+ getDwarfExpr(),
+ accessChain);
}
// Fallback to not emit anything for now.
return nullptr;
}
-
+
// The ordinary case is the debug variable has a backing ordinary variable.
// We can simply emit a store into the backing variable for the DebugValue operation.
//
@@ -6453,7 +6730,8 @@ struct SPIRVEmitContext
{
static uint32_t uid = 0;
uid++;
- name = builder.getStringValue((String("unnamed_type_") + String(uid)).getUnownedSlice());
+ name = builder.getStringValue(
+ (String("unnamed_type_") + String(uid)).getUnownedSlice());
}
IRSizeAndAlignment structSizeAlignment;
getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), type, &structSizeAlignment);
@@ -6466,21 +6744,25 @@ struct SPIRVEmitContext
getNaturalOffset(m_targetProgram->getOptionSet(), field, &offset);
auto fieldType = field->getFieldType();
- getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), fieldType, &sizeAlignment);
+ getNaturalSizeAndAlignment(
+ m_targetProgram->getOptionSet(),
+ fieldType,
+ &sizeAlignment);
SpvInst* forwardRef = nullptr;
SpvInst* spvFieldType = nullptr;
if (auto fieldPtrType = as<IRPtrTypeBase>(fieldType))
{
auto fieldPtrBaseType = fieldPtrType->getValueType();
- if (as<IRStructType>(fieldPtrBaseType)
- && m_emittingTypes.contains(fieldPtrBaseType))
+ if (as<IRStructType>(fieldPtrBaseType) &&
+ m_emittingTypes.contains(fieldPtrBaseType))
{
forwardRef = emitDebugForwardRefs(fieldPtrBaseType);
SpvStorageClass storageClass = SpvStorageClassFunction;
if (fieldPtrType->hasAddressSpace())
- storageClass = addressSpaceToStorageClass(fieldPtrType->getAddressSpace());
+ storageClass =
+ addressSpaceToStorageClass(fieldPtrType->getAddressSpace());
spvFieldType = emitOpDebugTypePointer(
getSection(SpvLogicalSectionID::ConstantsAndTypes),
@@ -6519,8 +6801,12 @@ struct SPIRVEmitContext
if (m_mapForwardRefsToDebugType.tryGetValue(type, forwardRef))
{
// "OpExtInstWithForwardRefsKHR" requires "forward declared ID" at the end.
- auto tmp = m_memoryArena.allocateArray<SpvWord>(forwardRef->operandWordsCount + members.getCount());
- memcpy(tmp, forwardRef->operandWords, forwardRef->operandWordsCount * sizeof(SpvWord));
+ auto tmp = m_memoryArena.allocateArray<SpvWord>(
+ forwardRef->operandWordsCount + members.getCount());
+ memcpy(
+ tmp,
+ forwardRef->operandWords,
+ forwardRef->operandWordsCount * sizeof(SpvWord));
for (Index i = 0; i < members.getCount(); i++)
tmp[forwardRef->operandWordsCount + i] = getID(members[i]);
forwardRef->operandWords = tmp;
@@ -6547,14 +6833,16 @@ struct SPIRVEmitContext
if (auto arrayType = as<IRArrayTypeBase>(type))
{
auto sizedArrayType = as<IRArrayType>(arrayType);
- return emitOpDebugTypeArray(getSection(SpvLogicalSectionID::ConstantsAndTypes),
+ return emitOpDebugTypeArray(
+ getSection(SpvLogicalSectionID::ConstantsAndTypes),
nullptr,
m_voidType,
getNonSemanticDebugInfoExtInst(),
emitDebugType(arrayType->getElementType()),
- sizedArrayType
- ? builder.getIntValue(builder.getUIntType(), getIntVal(sizedArrayType->getElementCount()))
- : builder.getIntValue(builder.getUIntType(), 0));
+ sizedArrayType ? builder.getIntValue(
+ builder.getUIntType(),
+ getIntVal(sizedArrayType->getElementCount()))
+ : builder.getIntValue(builder.getUIntType(), 0));
}
else if (auto vectorType = as<IRVectorType>(type))
{
@@ -6565,7 +6853,9 @@ struct SPIRVEmitContext
m_voidType,
getNonSemanticDebugInfoExtInst(),
elementType,
- builder.getIntValue(builder.getUIntType(), getIntVal(vectorType->getElementCount())));
+ builder.getIntValue(
+ builder.getUIntType(),
+ getIntVal(vectorType->getElementCount())));
}
else if (auto matrixType = as<IRMatrixType>(type))
{
@@ -6574,13 +6864,16 @@ struct SPIRVEmitContext
IRType* innerVectorType = nullptr;
if (getIntVal(matrixType->getLayout()) == kMatrixLayoutMode_ColumnMajor)
{
- innerVectorType = builder.getVectorType(matrixType->getElementType(), matrixType->getRowCount());
+ innerVectorType =
+ builder.getVectorType(matrixType->getElementType(), matrixType->getRowCount());
isColumnMajor = true;
count = matrixType->getColumnCount();
}
else
{
- innerVectorType = builder.getVectorType(matrixType->getElementType(), matrixType->getColumnCount());
+ innerVectorType = builder.getVectorType(
+ matrixType->getElementType(),
+ matrixType->getColumnCount());
count = matrixType->getRowCount();
}
auto elementType = emitDebugType(innerVectorType);
@@ -6692,7 +6985,8 @@ struct SPIRVEmitContext
{
static uint32_t uid = 0;
uid++;
- name = builder.getStringValue((String("unnamed_forward_type_") + String(uid)).getUnownedSlice());
+ name = builder.getStringValue(
+ (String("unnamed_forward_type_") + String(uid)).getUnownedSlice());
}
IRSizeAndAlignment structSizeAlignment;
getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), type, &structSizeAlignment);
@@ -6740,12 +7034,27 @@ struct SPIRVEmitContext
IRBuilder builder(function);
auto debugFunc = emitOpDebugFunction(
getSection(SpvLogicalSectionID::ConstantsAndTypes),
- nullptr, m_voidType, getNonSemanticDebugInfoExtInst(),
- name, debugType, debugLoc->getSource(), debugLoc->getLine(), debugLoc->getCol(), scope, name,
- builder.getIntValue(builder.getUIntType(), 0), debugLoc->getLine());
+ nullptr,
+ m_voidType,
+ getNonSemanticDebugInfoExtInst(),
+ name,
+ debugType,
+ debugLoc->getSource(),
+ debugLoc->getLine(),
+ debugLoc->getCol(),
+ scope,
+ name,
+ builder.getIntValue(builder.getUIntType(), 0),
+ debugLoc->getLine());
registerDebugInst(function, debugFunc);
- emitOpDebugFunctionDefinition(firstBlock, nullptr, m_voidType, getNonSemanticDebugInfoExtInst(), debugFunc, spvFunc);
+ emitOpDebugFunctionDefinition(
+ firstBlock,
+ nullptr,
+ m_voidType,
+ getNonSemanticDebugInfoExtInst(),
+ debugFunc,
+ spvFunc);
return debugFunc;
}
@@ -6757,175 +7066,178 @@ struct SPIRVEmitContext
// This keeps track of the named IDs used in the asm block
Dictionary<UnownedStringSlice, SpvWord> idMap;
- for(const auto spvInst : inst->getInsts())
+ for (const auto spvInst : inst->getInsts())
{
const bool isLast = spvInst == inst->getLastChild();
- const auto parentForOpCode = [this](SpvOp opcode, SpvInstParent* defaultParent) -> SpvInstParent*{
+ const auto parentForOpCode =
+ [this](SpvOp opcode, SpvInstParent* defaultParent) -> SpvInstParent*
+ {
const auto info = m_grammarInfo->opInfos.lookup(opcode);
SLANG_ASSERT(info.has_value());
- switch(info->class_)
+ switch (info->class_)
{
- case SPIRVCoreGrammarInfo::OpInfo::TypeDeclaration:
- case SPIRVCoreGrammarInfo::OpInfo::ConstantCreation:
- return getSection(SpvLogicalSectionID::ConstantsAndTypes);
- // Don't add this case, it's not correct as not all "Debug"
- // instructions belong in this block
- // case SPIRVCoreGrammarInfo::OpInfo::Debug:
- // return getSection(SpvLogicalSectionID::DebugNames);
- default:
- switch(opcode)
- {
- case SpvOpName:
- return getSection(SpvLogicalSectionID::DebugNames);
- case SpvOpCapability:
- return getSection(SpvLogicalSectionID::Capabilities);
- case SpvOpExtension:
- return getSection(SpvLogicalSectionID::Extensions);
- case SpvOpExecutionMode:
- case SpvOpExecutionModeId:
- return getSection(SpvLogicalSectionID::ExecutionModes);
- case SpvOpDecorate:
- case SpvOpDecorateId:
- case SpvOpDecorateString:
- case SpvOpMemberDecorate:
- case SpvOpMemberDecorateString:
- return getSection(SpvLogicalSectionID::Annotations);
- default:
- return defaultParent;
-
- }
+ case SPIRVCoreGrammarInfo::OpInfo::TypeDeclaration:
+ case SPIRVCoreGrammarInfo::OpInfo::ConstantCreation:
+ return getSection(SpvLogicalSectionID::ConstantsAndTypes);
+ // Don't add this case, it's not correct as not all "Debug"
+ // instructions belong in this block
+ // case SPIRVCoreGrammarInfo::OpInfo::Debug:
+ // return getSection(SpvLogicalSectionID::DebugNames);
+ default:
+ switch (opcode)
+ {
+ case SpvOpName: return getSection(SpvLogicalSectionID::DebugNames);
+ case SpvOpCapability: return getSection(SpvLogicalSectionID::Capabilities);
+ case SpvOpExtension: return getSection(SpvLogicalSectionID::Extensions);
+ case SpvOpExecutionMode:
+ case SpvOpExecutionModeId:
+ return getSection(SpvLogicalSectionID::ExecutionModes);
+ case SpvOpDecorate:
+ case SpvOpDecorateId:
+ case SpvOpDecorateString:
+ case SpvOpMemberDecorate:
+ case SpvOpMemberDecorateString:
+ return getSection(SpvLogicalSectionID::Annotations);
+ default: return defaultParent;
+ }
}
};
- const auto emitSpvAsmOperand = [&](IRSPIRVAsmOperand* operand){
- switch(operand->getOp())
+ const auto emitSpvAsmOperand = [&](IRSPIRVAsmOperand* operand)
+ {
+ switch (operand->getOp())
{
case kIROp_SPIRVAsmOperandEnum:
case kIROp_SPIRVAsmOperandLiteral:
- {
- const auto v = as<IRConstant>(operand->getValue());
- SLANG_ASSERT(v);
- if(operand->getOperandCount() >= 2)
-
{
- const auto constantType = cast<IRType>(operand->getOperand(1));
- SpvInst* constant;
- switch(v->getOp())
- {
- case kIROp_IntLit:
+ const auto v = as<IRConstant>(operand->getValue());
+ SLANG_ASSERT(v);
+ if (operand->getOperandCount() >= 2)
+
{
- // TODO: range checking
- const auto i = cast<IRIntLit>(v)->getValue();
- constant = emitIntConstant(i, constantType);
- break;
- }
- case kIROp_StringLit:
- SLANG_UNIMPLEMENTED_X("String constants in SPIR-V emit");
- default:
- SLANG_UNREACHABLE("Unhandled case in emitSPIRVAsm");
+ const auto constantType = cast<IRType>(operand->getOperand(1));
+ SpvInst* constant;
+ switch (v->getOp())
+ {
+ case kIROp_IntLit:
+ {
+ // TODO: range checking
+ const auto i = cast<IRIntLit>(v)->getValue();
+ constant = emitIntConstant(i, constantType);
+ break;
+ }
+ case kIROp_StringLit:
+ SLANG_UNIMPLEMENTED_X("String constants in SPIR-V emit");
+ default: SLANG_UNREACHABLE("Unhandled case in emitSPIRVAsm");
+ }
+ emitOperand(constant);
}
- emitOperand(constant);
- }
- else
- {
- switch(v->getOp())
- {
- case kIROp_StringLit:
- emitOperand(SpvLiteralBits::fromUnownedStringSlice(v->getStringSlice()));
- break;
- case kIROp_IntLit:
+ else
{
- // TODO: range checking
- const auto i = cast<IRIntLit>(v)->getValue();
- emitOperand(SpvLiteralInteger::from32(uint32_t(i)));
- break;
- }
- default:
- SLANG_UNREACHABLE("Unhandled case in emitSPIRVAsm");
+ switch (v->getOp())
+ {
+ case kIROp_StringLit:
+ emitOperand(
+ SpvLiteralBits::fromUnownedStringSlice(v->getStringSlice()));
+ break;
+ case kIROp_IntLit:
+ {
+ // TODO: range checking
+ const auto i = cast<IRIntLit>(v)->getValue();
+ emitOperand(SpvLiteralInteger::from32(uint32_t(i)));
+ break;
+ }
+ default: SLANG_UNREACHABLE("Unhandled case in emitSPIRVAsm");
+ }
}
+ break;
}
- break;
- }
case kIROp_SPIRVAsmOperandInst:
- {
- const auto i = operand->getValue();
- emitOperand(ensureInst(i));
+ {
+ const auto i = operand->getValue();
+ emitOperand(ensureInst(i));
- break;
- }
+ break;
+ }
case kIROp_SPIRVAsmOperandResult:
- {
- SLANG_ASSERT(isLast);
- emitOperand(kResultID);
- break;
- }
+ {
+ SLANG_ASSERT(isLast);
+ emitOperand(kResultID);
+ break;
+ }
case kIROp_SPIRVAsmOperandId:
- {
- const auto idName = cast<IRStringLit>(operand->getValue())->getStringSlice();
- SpvWord id;
- if(!idMap.tryGetValue(idName, id))
{
- id = freshID();
- idMap.set(idName, id);
+ const auto idName =
+ cast<IRStringLit>(operand->getValue())->getStringSlice();
+ SpvWord id;
+ if (!idMap.tryGetValue(idName, id))
+ {
+ id = freshID();
+ idMap.set(idName, id);
+ }
+ emitOperand(id);
+ break;
}
- emitOperand(id);
- break;
- }
case kIROp_SPIRVAsmOperandSampledType:
- {
- // Make a 4 vector of the component type
- IRBuilder builder(m_irModule);
- const auto elementType = cast<IRType>(operand->getValue());
- const auto sampledType = builder.getVectorType(getSPIRVSampledElementType(getVectorElementType(elementType)), 4);
- emitOperand(ensureInst(sampledType));
- break;
- }
+ {
+ // Make a 4 vector of the component type
+ IRBuilder builder(m_irModule);
+ const auto elementType = cast<IRType>(operand->getValue());
+ const auto sampledType = builder.getVectorType(
+ getSPIRVSampledElementType(getVectorElementType(elementType)),
+ 4);
+ emitOperand(ensureInst(sampledType));
+ break;
+ }
case kIROp_SPIRVAsmOperandImageType:
case kIROp_SPIRVAsmOperandSampledImageType:
- {
- IRBuilder builder(m_irModule);
- auto textureInst = as<IRTextureTypeBase>(operand->getValue()->getDataType());
- auto imageType = builder.getTextureType(
- textureInst->getElementType(),
- textureInst->getShapeInst(),
- textureInst->getIsArrayInst(),
- textureInst->getIsMultisampleInst(),
- textureInst->getSampleCountInst(),
- textureInst->getAccessInst(),
- textureInst->getIsShadowInst(),
- builder.getIntValue(builder.getIntType(), (operand->getOp() == kIROp_SPIRVAsmOperandSampledImageType ? 1 : 0)),
- textureInst->getFormatInst());
- emitOperand(ensureInst(imageType));
- break;
- }
+ {
+ IRBuilder builder(m_irModule);
+ auto textureInst =
+ as<IRTextureTypeBase>(operand->getValue()->getDataType());
+ auto imageType = builder.getTextureType(
+ textureInst->getElementType(),
+ textureInst->getShapeInst(),
+ textureInst->getIsArrayInst(),
+ textureInst->getIsMultisampleInst(),
+ textureInst->getSampleCountInst(),
+ textureInst->getAccessInst(),
+ textureInst->getIsShadowInst(),
+ builder.getIntValue(
+ builder.getIntType(),
+ (operand->getOp() == kIROp_SPIRVAsmOperandSampledImageType ? 1
+ : 0)),
+ textureInst->getFormatInst());
+ emitOperand(ensureInst(imageType));
+ break;
+ }
case kIROp_SPIRVAsmOperandBuiltinVar:
- {
- emitOperand(ensureInst(operand));
- break;
- }
+ {
+ emitOperand(ensureInst(operand));
+ break;
+ }
case kIROp_SPIRVAsmOperandGLSL450Set:
- {
- emitOperand(getGLSL450ExtInst());
- break;
- }
+ {
+ emitOperand(getGLSL450ExtInst());
+ break;
+ }
case kIROp_SPIRVAsmOperandDebugPrintfSet:
- {
- emitOperand(getNonSemanticDebugPrintfExtInst());
- break;
- }
- default:
- SLANG_UNREACHABLE("Unhandled case in emitSPIRVAsm");
+ {
+ emitOperand(getNonSemanticDebugPrintfExtInst());
+ break;
+ }
+ default: SLANG_UNREACHABLE("Unhandled case in emitSPIRVAsm");
}
};
- if(spvInst->getOpcodeOperand()->getOp() == kIROp_SPIRVAsmOperandTruncate)
+ if (spvInst->getOpcodeOperand()->getOp() == kIROp_SPIRVAsmOperandTruncate)
{
- const auto getSlangType = [&](IRSPIRVAsmOperand* operand) -> IRType*{
- switch(operand->getOp())
+ const auto getSlangType = [&](IRSPIRVAsmOperand* operand) -> IRType*
+ {
+ switch (operand->getOp())
{
- case kIROp_SPIRVAsmOperandInst:
- return cast<IRType>(operand->getValue());
+ case kIROp_SPIRVAsmOperandInst: return cast<IRType>(operand->getValue());
case kIROp_SPIRVAsmOperandSampledType:
{
// Make a 4 vector of the component type
@@ -6938,8 +7250,7 @@ struct SPIRVEmitContext
case kIROp_SPIRVAsmOperandResult:
case kIROp_SPIRVAsmOperandId:
SLANG_UNEXPECTED("truncate should have been given slang types");
- default:
- SLANG_UNREACHABLE("Unhandled case in emitSPIRVAsm");
+ default: SLANG_UNREACHABLE("Unhandled case in emitSPIRVAsm");
}
};
@@ -6953,22 +7264,26 @@ struct SPIRVEmitContext
// If the component types are not the same, convert them to be so.
if (!isTypeEqual(getVectorElementType(toType), fromElementType))
{
- SpvOp convertOp = isIntegralType(fromElementType) ? (isSignedType(fromElementType) ? SpvOpSConvert : SpvOpUConvert) : SpvOpFConvert;
- auto newFromType = replaceVectorElementType(fromType, getVectorElementType(toType));
+ SpvOp convertOp =
+ isIntegralType(fromElementType)
+ ? (isSignedType(fromElementType) ? SpvOpSConvert : SpvOpUConvert)
+ : SpvOpFConvert;
+ auto newFromType =
+ replaceVectorElementType(fromType, getVectorElementType(toType));
fromSpvInst = emitInstCustomOperandFunc(
parent,
nullptr,
convertOp,
- [&]() {
+ [&]()
+ {
emitOperand(newFromType);
- emitOperand(kResultID),
- emitSpvAsmOperand(fromIdOperand);
+ emitOperand(kResultID), emitSpvAsmOperand(fromIdOperand);
});
}
// If we don't need truncation, but a different result ID is
// expected, then just unify them in the idMap
- if(isTypeEqual(toType, fromType))
+ if (isTypeEqual(toType, fromType))
{
// TODO: if this is the last inst, we should just remove it
// and rewrite the penultimate one
@@ -6976,41 +7291,44 @@ struct SPIRVEmitContext
parent,
isLast ? as<IRInst>(inst) : spvInst,
SpvOpCopyObject,
- [&](){
+ [&]()
+ {
emitOperand(toType);
emitSpvAsmOperand(toIdOperand);
- fromSpvInst ? emitOperand(fromSpvInst) : emitSpvAsmOperand(fromIdOperand);
- }
- );
+ fromSpvInst ? emitOperand(fromSpvInst)
+ : emitSpvAsmOperand(fromIdOperand);
+ });
}
// Otherwise, if we are truncating to a scalar, extract the first element
- else if(!as<IRVectorType>(toType))
+ else if (!as<IRVectorType>(toType))
{
last = emitInstCustomOperandFunc(
parent,
isLast ? as<IRInst>(inst) : spvInst,
SpvOpCompositeExtract,
- [&](){
+ [&]()
+ {
emitOperand(toType);
emitSpvAsmOperand(toIdOperand);
- fromSpvInst ? emitOperand(fromSpvInst) : emitSpvAsmOperand(fromIdOperand);
+ fromSpvInst ? emitOperand(fromSpvInst)
+ : emitSpvAsmOperand(fromIdOperand);
emitOperand(SpvLiteralInteger::from32(0));
- }
- );
+ });
}
// Otherwise, if we are truncating to a 1-vector from a scalar
- else if(as<IRVectorType>(toType) && !as<IRVectorType>(fromType))
+ else if (as<IRVectorType>(toType) && !as<IRVectorType>(fromType))
{
last = emitInstCustomOperandFunc(
parent,
isLast ? as<IRInst>(inst) : spvInst,
SpvOpCompositeConstruct,
- [&](){
+ [&]()
+ {
emitOperand(toType);
emitSpvAsmOperand(toIdOperand);
- fromSpvInst ? emitOperand(fromSpvInst) : emitSpvAsmOperand(fromIdOperand);
- }
- );
+ fromSpvInst ? emitOperand(fromSpvInst)
+ : emitSpvAsmOperand(fromIdOperand);
+ });
}
// Otherwise, we are truncating a vector to a smaller vector
else
@@ -7019,21 +7337,22 @@ struct SPIRVEmitContext
const auto toVectorSize = getIntVal(toVector->getElementCount());
const auto fromVector = cast<IRVectorType>(unwrapAttributedType(fromType));
const auto fromVectorSize = getIntVal(fromVector->getElementCount());
- if(toVectorSize > fromVectorSize)
+ if (toVectorSize > fromVectorSize)
m_sink->diagnose(inst, Diagnostics::spirvInvalidTruncate);
last = emitInstCustomOperandFunc(
parent,
isLast ? as<IRInst>(inst) : spvInst,
SpvOpVectorShuffle,
- [&](){
+ [&]()
+ {
emitOperand(toType);
emitSpvAsmOperand(toIdOperand);
- fromSpvInst ? emitOperand(fromSpvInst) : emitSpvAsmOperand(fromIdOperand);
+ fromSpvInst ? emitOperand(fromSpvInst)
+ : emitSpvAsmOperand(fromIdOperand);
emitOperand(emitOpUndef(parent, nullptr, fromVector));
- for(Int32 i = 0; i < toVectorSize; ++i)
+ for (Int32 i = 0; i < toVectorSize; ++i)
emitOperand(SpvLiteralInteger::from32(i));
- }
- );
+ });
}
}
else
@@ -7043,36 +7362,44 @@ struct SPIRVEmitContext
switch (opcode)
{
case SpvOpCapability:
- requireSPIRVCapability((SpvCapability)getIntVal(spvInst->getOperand(1)->getOperand(0)));
+ requireSPIRVCapability(
+ (SpvCapability)getIntVal(spvInst->getOperand(1)->getOperand(0)));
continue;
case SpvOpExtension:
- ensureExtensionDeclaration(as<IRStringLit>(spvInst->getOperand(1)->getOperand(0))->getStringSlice());
+ ensureExtensionDeclaration(
+ as<IRStringLit>(spvInst->getOperand(1)->getOperand(0))->getStringSlice());
continue;
case SpvOpExecutionMode:
- {
- if (auto refEntryPointSet = m_referencingEntryPoints.tryGetValue(getParentFunc(inst)))
{
- for (auto entryPoint : *refEntryPointSet)
+ if (auto refEntryPointSet =
+ m_referencingEntryPoints.tryGetValue(getParentFunc(inst)))
{
- emitInstMemoizedNoResultIDCustomOperandFunc(getSection(SpvLogicalSectionID::ExecutionModes), nullptr, SpvOpExecutionMode,
- [&]() {
- emitOperand(entryPoint);
- for (UInt s = 2; s < spvInst->getOperandCount(); s++)
- emitSpvAsmOperand(as<IRSPIRVAsmOperand>(spvInst->getOperand(s)));
- });
+ for (auto entryPoint : *refEntryPointSet)
+ {
+ emitInstMemoizedNoResultIDCustomOperandFunc(
+ getSection(SpvLogicalSectionID::ExecutionModes),
+ nullptr,
+ SpvOpExecutionMode,
+ [&]()
+ {
+ emitOperand(entryPoint);
+ for (UInt s = 2; s < spvInst->getOperandCount(); s++)
+ emitSpvAsmOperand(
+ as<IRSPIRVAsmOperand>(spvInst->getOperand(s)));
+ });
+ }
}
+ continue;
}
- continue;
- }
- default:
- break;
+ default: break;
}
const auto opParent = parentForOpCode(opcode, parent);
const auto opInfo = m_grammarInfo->opInfos.lookup(opcode);
// TODO: handle resultIdIndex == 1, for constants
- const bool memoize = opParent == getSection(SpvLogicalSectionID::ConstantsAndTypes)
- && opInfo && opInfo->resultIdIndex == 0;
+ const bool memoize =
+ opParent == getSection(SpvLogicalSectionID::ConstantsAndTypes) && opInfo &&
+ opInfo->resultIdIndex == 0;
// We want the "result instruction" to refer to the top level
// block which assumes its value, the others are free to refer
@@ -7081,21 +7408,22 @@ struct SPIRVEmitContext
// assigned to result is not necessarily the last instruction
const auto assignedInst = isLast ? as<IRInst>(inst) : spvInst;
- if(memoize)
+ if (memoize)
{
last = emitInstMemoizedCustomOperandFunc(
opParent,
assignedInst,
opcode,
kResultID,
- [&](){
+ [&]()
+ {
Index i = 0;
- for(const auto operand : spvInst->getSPIRVOperands()) {
- if(i++ != 0)
+ for (const auto operand : spvInst->getSPIRVOperands())
+ {
+ if (i++ != 0)
emitSpvAsmOperand(operand);
};
- }
- );
+ });
// The result operand is the one at index 1, after the
// opcode itself.
@@ -7105,7 +7433,7 @@ struct SPIRVEmitContext
// memoized instructions is that they come before their
// uses.
const auto resOperand = cast<IRSPIRVAsmOperand>(spvInst->getOperand(1));
- if(resOperand->getOp() == kIROp_SPIRVAsmOperandId)
+ if (resOperand->getOp() == kIROp_SPIRVAsmOperandId)
{
const auto idName =
cast<IRStringLit>(resOperand->getValue())->getStringSlice();
@@ -7118,16 +7446,16 @@ struct SPIRVEmitContext
opParent,
assignedInst,
opcode,
- [&](){
- for(const auto operand : spvInst->getSPIRVOperands())
+ [&]()
+ {
+ for (const auto operand : spvInst->getSPIRVOperands())
emitSpvAsmOperand(operand);
- }
- );
+ });
}
}
}
- for(const auto& [name, id] : idMap)
+ for (const auto& [name, id] : idMap)
emitOpName(getSection(SpvLogicalSectionID::DebugNames), nullptr, id, name);
return last;
@@ -7138,18 +7466,18 @@ struct SPIRVEmitContext
{
if (m_capabilities.add(capability))
{
- emitOpCapability(
- getSection(SpvLogicalSectionID::Capabilities),
- nullptr,
- capability
- );
+ emitOpCapability(getSection(SpvLogicalSectionID::Capabilities), nullptr, capability);
}
}
// https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpExecutionMode
Dictionary<SpvWord, OrderedHashSet<SpvExecutionMode>> m_executionModes;
template<typename... Operands>
- void requireSPIRVExecutionMode(IRInst* parentInst, SpvWord entryPoint, SpvExecutionMode executionMode, const Operands& ...ops)
+ void requireSPIRVExecutionMode(
+ IRInst* parentInst,
+ SpvWord entryPoint,
+ SpvExecutionMode executionMode,
+ const Operands&... ops)
{
if (m_executionModes[entryPoint].add(executionMode))
{
@@ -7159,24 +7487,21 @@ struct SPIRVEmitContext
SpvOpExecutionMode,
entryPoint,
executionMode,
- ops...
- );
+ ops...);
}
- }
+ }
SPIRVEmitContext(IRModule* module, TargetProgram* program, DiagnosticSink* sink)
- : SPIRVEmitSharedContext(module, program, sink)
- , m_irModule(module)
- , m_memoryArena(2048)
+ : SPIRVEmitSharedContext(module, program, sink), m_irModule(module), m_memoryArena(2048)
{
}
};
SlangResult emitSPIRVFromIR(
- CodeGenContext* codeGenContext,
- IRModule* irModule,
- const List<IRFunc*>& irEntryPoints,
- List<uint8_t>& spirvOut)
+ CodeGenContext* codeGenContext,
+ IRModule* irModule,
+ const List<IRFunc*>& irEntryPoints,
+ List<uint8_t>& spirvOut)
{
spirvOut.clear();
@@ -7196,7 +7521,7 @@ SlangResult emitSPIRVFromIR(
SPIRVEmitContext context(irModule, codeGenContext->getTargetProgram(), sink);
legalizeIRForSPIRV(&context, irModule, irEntryPoints, codeGenContext);
-
+
#if 0
{
DiagnosticSinkWriter writer(codeGenContext->getSink());
@@ -7209,8 +7534,10 @@ SlangResult emitSPIRVFromIR(
}
#endif
- auto shouldPreserveParams = codeGenContext->getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::PreserveParameters);
- auto generateWholeProgram = codeGenContext->getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::GenerateWholeProgram);
+ auto shouldPreserveParams = codeGenContext->getTargetProgram()->getOptionSet().getBoolOption(
+ CompilerOptionName::PreserveParameters);
+ auto generateWholeProgram = codeGenContext->getTargetProgram()->getOptionSet().getBoolOption(
+ CompilerOptionName::GenerateWholeProgram);
for (auto inst : irModule->getGlobalInsts())
{
if (as<IRDebugSource>(inst))
@@ -7240,13 +7567,19 @@ SlangResult emitSPIRVFromIR(
// environment variable that will be set in the software testing environment.
auto sourceLanguage = SpvSourceLanguageSlang;
StringBuilder noSlangEnv;
- PlatformUtil::getEnvironmentVariable(toSlice("SLANG_USE_SPV_SOURCE_LANGUAGE_UNKNOWN"), noSlangEnv);
+ PlatformUtil::getEnvironmentVariable(
+ toSlice("SLANG_USE_SPV_SOURCE_LANGUAGE_UNKNOWN"),
+ noSlangEnv);
if (noSlangEnv.produceString() == "1")
{
sourceLanguage = SpvSourceLanguageUnknown;
}
- context.emitInst(context.getSection(SpvLogicalSectionID::DebugStringsAndSource), nullptr, SpvOpSource,
- SpvLiteralInteger::from32(sourceLanguage), // language identifier, should be SpvSourceLanguageSlang.
+ context.emitInst(
+ context.getSection(SpvLogicalSectionID::DebugStringsAndSource),
+ nullptr,
+ SpvOpSource,
+ SpvLiteralInteger::from32(
+ sourceLanguage), // language identifier, should be SpvSourceLanguageSlang.
SpvLiteralInteger::from32(1)); // language version.
for (auto irEntryPoint : irEntryPoints)
@@ -7279,7 +7612,7 @@ SlangResult emitSPIRVFromIR(
context.emitPhysicalLayout();
spirvOut.addRange(
- (uint8_t const*) context.m_words.getBuffer(),
+ (uint8_t const*)context.m_words.getBuffer(),
context.m_words.getCount() * Index(sizeof(context.m_words[0])));
return SLANG_OK;