summaryrefslogtreecommitdiff
path: root/source/slang/slang-emit-spirv.cpp
diff options
context:
space:
mode:
authorkaizhangNV <149626564+kaizhangNV@users.noreply.github.com>2024-12-12 16:50:44 -0600
committerGitHub <noreply@github.com>2024-12-12 14:50:44 -0800
commit78c9bd1c2fbd55889e62a2032e9bc96684ced3b5 (patch)
tree63332e647aa597450b642751c8c6b2fd7f66439e /source/slang/slang-emit-spirv.cpp
parentb4e63d7bc44fc969d24202fc51a774378a489294 (diff)
Bit extract (#5847)
* promoting bitfield extraction and insertion to become intrinsics for internal compiler use * removing duplicate intrinsics from glsl.meta.slang * refactor: update function signatures of bitfield extraction and insertion to use uint as the parameter type for offset and bits. --------- Co-authored-by: Nate Morrical <natemorrical@gmail.com> 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.cpp60
1 files changed, 60 insertions, 0 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 8759ea9d4..c618946ec 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -3404,6 +3404,12 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
case kIROp_BitCast:
result = emitOpBitcast(parent, inst, inst->getDataType(), inst->getOperand(0));
break;
+ case kIROp_BitfieldExtract:
+ result = emitBitfieldExtract(parent, inst);
+ break;
+ case kIROp_BitfieldInsert:
+ result = emitBitfieldInsert(parent, inst);
+ break;
case kIROp_MakeUInt64:
result = emitMakeUInt64(parent, inst);
break;
@@ -6537,6 +6543,60 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
inst->getOperand(0));
}
+ SpvInst* emitBitfieldExtract(SpvInstParent* parent, IRInst* inst)
+ {
+ auto dataType = inst->getDataType();
+ IRVectorType* vectorType = as<IRVectorType>(dataType);
+ Slang::IRType* elementType = dataType;
+ if (vectorType)
+ elementType = vectorType->getElementType();
+
+ const IntInfo i = getIntTypeInfo(elementType);
+
+ // NM: technically, using bitfield intrinsics for anything non-32-bit goes against
+ // VK specification: VUID-StandaloneSpirv-Base-04781. However, it works on at least
+ // NVIDIA HW.
+ SpvOp opcode = i.isSigned ? SpvOpBitFieldSExtract : SpvOpBitFieldUExtract;
+ return emitInst(
+ parent,
+ inst,
+ opcode,
+ inst->getFullType(),
+ kResultID,
+ inst->getOperand(0),
+ inst->getOperand(1),
+ inst->getOperand(2));
+ }
+
+ SpvInst* emitBitfieldInsert(SpvInstParent* parent, IRInst* inst)
+ {
+ auto dataType = inst->getDataType();
+ IRVectorType* vectorType = as<IRVectorType>(dataType);
+ Slang::IRType* elementType = dataType;
+ if (vectorType)
+ elementType = vectorType->getElementType();
+
+ const IntInfo i = getIntTypeInfo(elementType);
+
+ if (i.width == 64)
+ requireSPIRVCapability(SpvCapabilityInt64);
+ if (i.width == 16)
+ requireSPIRVCapability(SpvCapabilityInt16);
+ if (i.width == 8)
+ requireSPIRVCapability(SpvCapabilityInt8);
+
+ return emitInst(
+ parent,
+ inst,
+ SpvOpBitFieldInsert,
+ inst->getFullType(),
+ kResultID,
+ inst->getOperand(0),
+ inst->getOperand(1),
+ inst->getOperand(2),
+ inst->getOperand(3));
+ }
+
template<typename T, typename Ts>
SpvInst* emitCompositeConstruct(
SpvInstParent* parent,