summaryrefslogtreecommitdiff
path: root/source/slang/slang-emit-spirv.cpp
diff options
context:
space:
mode:
authorEllie Hermaszewska <ellieh@nvidia.com>2023-08-29 06:05:26 +0800
committerGitHub <noreply@github.com>2023-08-28 15:05:26 -0700
commit508dc3a95de50de4a4d07d0a72a18e40d55b0e2e (patch)
tree7487232f5c0db0dd607e2a91b539f6a592789b06 /source/slang/slang-emit-spirv.cpp
parent06f7ef354cdde4cf8e8797d8853ed2d9c3208b5b (diff)
Allow bitwise or expressions and numeric literals in spirv_asm blocks (#3157)
* Add -spirv-core-grammar option to load alternate spirv defs Also embed a version to use by default * Use perfect hash for spv op lookup * Neaten perfect hash embedding * Refactor spirv grammar lookup in preperation for more kinds of lookups * Load spirv capability list from spec * Add all SPIR-V enums to lookup table * regenerate vs projects * appease msvc * Use string slices for spir-v core grammar lookups * wiggle * comment * Add OpInfo for spv ops * regenerate vs projects * Embed op names * Add min/max operand counts and enum categories to spirv info * neaten * Operand kinds for spirv ops * Store and embed all information relating to spirv enums and qualifiers * Use SPIR-V spec to position instructions in spirv_asm blocks * Neaten spir-v info embedding * Neaten perfect hash embedding * Add assignment syntax to spirv_asm snippets * Better errors for spirv_asm parser * Add warning for too many operands in spirv asm * squash warnings * neaten * test wiggle * Lookup enums for spirv * Put OpCapability and OpExtension in the correct place for spirv_asm blocks * Tests for OpCapability and OpExtension * ci wiggle * Add expected failure * Allow raising immediate values to constant ids where necessary in spirv_asm blocks * Allow bitwise or expressions and numeric literals in spirv_asm blocks * test numeric literals * Fix memory issues. * fix. --------- Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'source/slang/slang-emit-spirv.cpp')
-rw-r--r--source/slang/slang-emit-spirv.cpp106
1 files changed, 67 insertions, 39 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 0022bdd85..c6aedbe3b 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -3808,25 +3808,34 @@ struct SPIRVEmitContext
for(const auto spvInst : inst->getInsts())
{
const bool isLast = spvInst == inst->getLastChild();
- const auto opcodeString = spvInst->getOpcodeString();
- SpvOp opcode;
- const bool foundOpCode = lookupSpvOp(opcodeString, opcode)
- || lookupSpvOp((String("Op") + opcodeString).getUnownedSlice(), opcode);
- if(!foundOpCode)
- {
- m_sink->diagnose(
- spvInst->getOpcode(),
- Diagnostics::unrecognizedSPIRVOpcode,
- opcodeString
- );
- return nullptr;
- }
+ const SpvOp opcode = SpvOp(spvInst->getOpcodeOperandWord());
- const auto parentForOpCode = [this](SpvOp opcode, SpvInstParent* defaultParent){
- return
- opcode == SpvOpConstant ? getSection(SpvLogicalSectionID::ConstantsAndTypes)
- : opcode == SpvOpName ? getSection(SpvLogicalSectionID::DebugNames)
- : defaultParent;
+ 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_)
+ {
+ 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);
+ default:
+ return defaultParent;
+
+ }
+ }
};
last = emitInstCustomOperandFunc(
@@ -3843,24 +3852,48 @@ struct SPIRVEmitContext
{
switch(operand->getOp())
{
+ case kIROp_SPIRVAsmOperandEnum:
case kIROp_SPIRVAsmOperandLiteral:
{
const auto v = as<IRConstant>(operand->getValue());
SLANG_ASSERT(v);
- switch(v->getOp())
+ if(operand->getOperandCount() >= 2)
{
- 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;
+ 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);
}
- default:
- SLANG_UNREACHABLE("Unhandled case in emitSPIRVAsm");
+ else
+ {
+ 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;
}
@@ -3868,18 +3901,13 @@ struct SPIRVEmitContext
{
const auto i = operand->getValue();
emitOperand(ensureInst(i));
+
break;
}
- case kIROp_SPIRVAsmOperandEnum:
+ case kIROp_SPIRVAsmOperandResult:
{
- const auto s = cast<IRStringLit>(operand->getValue())->getStringSlice();
- if(s == "result")
- {
- SLANG_ASSERT(isLast);
- emitOperand(kResultID);
- }
- else
- SLANG_UNIMPLEMENTED_X("lookup enum operands in spirv_asm");
+ SLANG_ASSERT(isLast);
+ emitOperand(kResultID);
break;
}
case kIROp_SPIRVAsmOperandId: