From fab1c9f4c745ba84983c2448646376799d461e96 Mon Sep 17 00:00:00 2001 From: Yong He Date: Fri, 9 Oct 2020 11:29:11 -0700 Subject: Support CUDA bindless texture in dynamic dispatch code. (#1575) --- source/slang/slang-emit-c-like.cpp | 10 ++++- source/slang/slang-ir-any-value-marshalling.cpp | 51 ++++++++++++++++++++++++- source/slang/slang-ir-inst-defs.h | 1 + source/slang/slang-ir-insts.h | 5 +++ source/slang/slang-ir.cpp | 26 +++++++++++++ 5 files changed, 91 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index e0499319f..e27a5b972 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -2090,7 +2090,15 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO emitType(inst->getDataType()); emitArgs(inst); break; - + case kIROp_makeUInt64: + m_writer->emit("(("); + emitType(inst->getDataType()); + m_writer->emit("("); + emitOperand(inst->getOperand(1), getInfo(EmitOp::General)); + m_writer->emit(") << 32) + "); + emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); + m_writer->emit(")"); + break; case kIROp_constructVectorFromScalar: { // Simple constructor call diff --git a/source/slang/slang-ir-any-value-marshalling.cpp b/source/slang/slang-ir-any-value-marshalling.cpp index 0a988da1d..9322ed0eb 100644 --- a/source/slang/slang-ir-any-value-marshalling.cpp +++ b/source/slang/slang-ir-any-value-marshalling.cpp @@ -85,7 +85,8 @@ namespace Slang IRInst* anyValueVar; // Defines what to do with basic typed data elements. virtual void marshalBasicType(IRBuilder* builder, IRType* dataType, IRInst* concreteTypedVar) = 0; - + // Defines what to do with resource handle elements. + virtual void marshalResourceHandle(IRBuilder* builder, IRType* dataType, IRInst* concreteTypedVar) = 0; // Validates that the type fits in the given AnyValueSize. // After calling emitMarshallingCode, `fieldOffset` will be increased to the required `AnyValue` size. // If this is larger than the provided AnyValue size, report a dianogstic. We might want to front load @@ -188,6 +189,11 @@ namespace Slang break; } default: + if (as(dataType) || as(dataType)) + { + context->marshalResourceHandle(builder, dataType, concreteTypedVar); + return; + } SLANG_UNIMPLEMENTED_X("Unimplemented type packing"); break; } @@ -243,6 +249,29 @@ namespace Slang SLANG_UNREACHABLE("unknown basic type"); } } + + virtual void marshalResourceHandle(IRBuilder* builder, IRType* dataType, IRInst* concreteVar) override + { + SLANG_UNUSED(dataType); + if (fieldOffset + 1 < static_cast(anyValInfo->fieldKeys.getCount())) + { + auto srcVal = builder->emitLoad(concreteVar); + auto uint64Val = builder->emitBitCast(builder->getUInt64Type(), srcVal); + auto lowBits = builder->emitConstructorInst(builder->getUIntType(), 1, &uint64Val); + auto shiftedBits = builder->emitShr( + builder->getUInt64Type(), + uint64Val, + builder->getIntValue(builder->getIntType(), 32)); + auto highBits = builder->emitBitCast(builder->getUIntType(), shiftedBits); + auto dstAddr1 = builder->emitFieldAddress( + uintPtrType, anyValueVar, anyValInfo->fieldKeys[fieldOffset]); + builder->emitStore(dstAddr1, lowBits); + auto dstAddr2 = builder->emitFieldAddress( + uintPtrType, anyValueVar, anyValInfo->fieldKeys[fieldOffset + 1]); + builder->emitStore(dstAddr2, highBits); + fieldOffset += 2; + } + } }; IRFunc* generatePackingFunc(IRType* type, IRAnyValueType* anyValueType) @@ -335,6 +364,26 @@ namespace Slang SLANG_UNREACHABLE("unknown basic type"); } } + + virtual void marshalResourceHandle( + IRBuilder* builder, IRType* dataType, IRInst* concreteVar) override + { + if (fieldOffset + 1 < static_cast(anyValInfo->fieldKeys.getCount())) + { + auto srcAddr = builder->emitFieldAddress( + uintPtrType, anyValueVar, anyValInfo->fieldKeys[fieldOffset]); + auto lowBits = builder->emitLoad(srcAddr); + + auto srcAddr1 = builder->emitFieldAddress( + uintPtrType, anyValueVar, anyValInfo->fieldKeys[fieldOffset + 1]); + auto highBits = builder->emitLoad(srcAddr1); + + auto combinedBits = builder->emitMakeUInt64(lowBits, highBits); + combinedBits = builder->emitBitCast(dataType, combinedBits); + builder->emitStore(concreteVar, combinedBits); + fieldOffset += 2; + } + } }; IRFunc* generateUnpackingFunc(IRType* type, IRAnyValueType* anyValueType) diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index c7d223ab6..340f18c8c 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -234,6 +234,7 @@ INST(BindGlobalGenericParam, bind_global_generic_param, 2, 0) INST(Construct, construct, 0, 0) +INST(makeUInt64, makeUInt64, 2, 0) INST(makeVector, makeVector, 0, 0) INST(MakeMatrix, makeMatrix, 0, 0) INST(makeArray, makeArray, 0, 0) diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 658e50f28..af0f737ea 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -1779,6 +1779,7 @@ struct IRBuilder IRBasicType* getBoolType(); IRBasicType* getIntType(); IRBasicType* getUIntType(); + IRBasicType* getUInt64Type(); IRStringType* getStringType(); IRAssociatedType* getAssociatedType(ArrayView constraintTypes); @@ -1942,6 +1943,8 @@ struct IRBuilder UInt argCount, IRInst* const* args); + IRInst* emitMakeUInt64(IRInst* low, IRInst* high); + // Creates an RTTI object. Result is of `IRRTTIType`. IRInst* emitMakeRTTIObject(IRInst* typeInst); @@ -2303,6 +2306,8 @@ struct IRBuilder IRInst* emitAdd(IRType* type, IRInst* left, IRInst* right); IRInst* emitMul(IRType* type, IRInst* left, IRInst* right); + IRInst* emitShr(IRType* type, IRInst* op0, IRInst* op1); + IRInst* emitShl(IRType* type, IRInst* op0, IRInst* op1); // // Decorations diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index 3820119d2..6f0cc43e2 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -2230,6 +2230,11 @@ namespace Slang return (IRBasicType*)getType(kIROp_UIntType); } + IRBasicType* IRBuilder::getUInt64Type() + { + return (IRBasicType*)getType(kIROp_UInt64Type); + } + IRStringType* IRBuilder::getStringType() { return (IRStringType*)getType(kIROp_StringType); @@ -2750,6 +2755,12 @@ namespace Slang return inst; } + IRInst* IRBuilder::emitMakeUInt64(IRInst* low, IRInst* high) + { + IRInst* args[2] = {low, high}; + return emitIntrinsicInst(getUInt64Type(), kIROp_makeUInt64, 2, args); + } + IRInst* IRBuilder::emitMakeRTTIObject(IRInst* typeInst) { auto inst = createInst( @@ -3786,6 +3797,20 @@ namespace Slang return inst; } + IRInst* IRBuilder::emitShr(IRType* type, IRInst* left, IRInst* right) + { + auto inst = createInst(this, kIROp_Rsh, type, left, right); + addInst(inst); + return inst; + } + + IRInst* IRBuilder::emitShl(IRType* type, IRInst* left, IRInst* right) + { + auto inst = createInst(this, kIROp_Lsh, type, left, right); + addInst(inst); + return inst; + } + IRInst* IRBuilder::emitGpuForeach(List args) { auto inst = createInst( @@ -5300,6 +5325,7 @@ namespace Slang case kIROp_getAddr: case kIROp_GetValueFromExistentialBox: case kIROp_Construct: + case kIROp_makeUInt64: case kIROp_makeVector: case kIROp_MakeMatrix: case kIROp_makeArray: -- cgit v1.2.3