From 78c9bd1c2fbd55889e62a2032e9bc96684ced3b5 Mon Sep 17 00:00:00 2001 From: kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:50:44 -0600 Subject: 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 Co-authored-by: Yong He --- source/slang/slang-emit-spirv.cpp | 60 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'source/slang/slang-emit-spirv.cpp') 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(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(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 SpvInst* emitCompositeConstruct( SpvInstParent* parent, -- cgit v1.2.3