diff options
| author | Yong He <yonghe@outlook.com> | 2022-09-15 20:37:45 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-15 20:37:45 -0700 |
| commit | a5d3bec25d70f23da1e79cd7773981ff34593611 (patch) | |
| tree | 92c8cb983c57bbee141d4e6f3f91f265e04d6a08 | |
| parent | a6032446c6bf7f64d1e201bf438a4c7605a3dbb4 (diff) | |
Run simple compute kernel in gfx-smoke test. (#2400)
27 files changed, 356 insertions, 105 deletions
diff --git a/.gitignore b/.gitignore index 574e7d3a1..78fe95953 100644 --- a/.gitignore +++ b/.gitignore @@ -63,10 +63,11 @@ prelude/*.h.cpp /examples/heterogeneous-hello-world/shader.cpp /multiple-definitions.hlsl /external/slang-llvm/ +/external/slang-glslang/ build/**/*.tlog build/**/*.lastbuildstate build/**/*.recipe build/**/*.log *.dll -*.dxil +*.dxil
\ No newline at end of file diff --git a/prelude/slang-cpp-prelude.h b/prelude/slang-cpp-prelude.h index 5922388eb..b2a8dd6ac 100644 --- a/prelude/slang-cpp-prelude.h +++ b/prelude/slang-cpp-prelude.h @@ -6,7 +6,7 @@ // https://stackoverflow.com/questions/39130040/cmath-hides-isnan-in-math-h-in-c14-c11 #ifdef SLANG_LLVM -# include "slang-llvm.h" +#include "slang-llvm.h" #else // SLANG_LLVM # if SLANG_GCC_FAMILY && __GNUC__ < 6 # include <cmath> diff --git a/slang-gfx.h b/slang-gfx.h index 4f7c930b2..a26dc57e7 100644 --- a/slang-gfx.h +++ b/slang-gfx.h @@ -1103,23 +1103,9 @@ enum class ShaderObjectContainerType class IShaderObject : public ISlangUnknown { public: - SLANG_NO_THROW ComPtr<IShaderObject> SLANG_MCALL getObject(ShaderOffset const& offset) - { - ComPtr<IShaderObject> object = nullptr; - SLANG_RETURN_NULL_ON_FAIL(getObject(offset, object.writeRef())); - return object; - } - virtual SLANG_NO_THROW slang::TypeLayoutReflection* SLANG_MCALL getElementTypeLayout() = 0; virtual SLANG_NO_THROW ShaderObjectContainerType SLANG_MCALL getContainerType() = 0; virtual SLANG_NO_THROW GfxCount SLANG_MCALL getEntryPointCount() = 0; - - ComPtr<IShaderObject> getEntryPoint(GfxIndex index) - { - ComPtr<IShaderObject> entryPoint = nullptr; - SLANG_RETURN_NULL_ON_FAIL(getEntryPoint(index, entryPoint.writeRef())); - return entryPoint; - } virtual SLANG_NO_THROW Result SLANG_MCALL getEntryPoint(GfxIndex index, IShaderObject** entryPoint) = 0; virtual SLANG_NO_THROW Result SLANG_MCALL @@ -1153,6 +1139,20 @@ public: /// Use the provided constant buffer instead of the internally created one. virtual SLANG_NO_THROW Result SLANG_MCALL setConstantBufferOverride(IBufferResource* constantBuffer) = 0; + + + inline ComPtr<IShaderObject> getObject(ShaderOffset const& offset) + { + ComPtr<IShaderObject> object = nullptr; + SLANG_RETURN_NULL_ON_FAIL(getObject(offset, object.writeRef())); + return object; + } + inline ComPtr<IShaderObject> getEntryPoint(GfxIndex index) + { + ComPtr<IShaderObject> entryPoint = nullptr; + SLANG_RETURN_NULL_ON_FAIL(getEntryPoint(index, entryPoint.writeRef())); + return entryPoint; + } }; #define SLANG_UUID_IShaderObject \ { \ @@ -1638,10 +1638,6 @@ public: uploadBufferData(IBufferResource* dst, Offset offset, Size size, void* data) = 0; virtual SLANG_NO_THROW void SLANG_MCALL textureBarrier( GfxCount count, ITextureResource* const* textures, ResourceState src, ResourceState dst) = 0; - void textureBarrier(ITextureResource* texture, ResourceState src, ResourceState dst) - { - textureBarrier(1, &texture, src, dst); - } virtual SLANG_NO_THROW void SLANG_MCALL textureSubresourceBarrier( ITextureResource* texture, SubresourceRange subresourceRange, @@ -1649,10 +1645,6 @@ public: ResourceState dst) = 0; virtual SLANG_NO_THROW void SLANG_MCALL bufferBarrier( GfxCount count, IBufferResource* const* buffers, ResourceState src, ResourceState dst) = 0; - void bufferBarrier(IBufferResource* buffer, ResourceState src, ResourceState dst) - { - bufferBarrier(1, &buffer, src, dst); - } virtual SLANG_NO_THROW void SLANG_MCALL clearResourceView( IResourceView* view, ClearValue* clearValue, ClearResourceViewFlags::Enum flags) = 0; virtual SLANG_NO_THROW void SLANG_MCALL resolveResource( @@ -1670,6 +1662,14 @@ public: Offset offset) = 0; virtual SLANG_NO_THROW void SLANG_MCALL beginDebugEvent(const char* name, float rgbColor[3]) = 0; virtual SLANG_NO_THROW void SLANG_MCALL endDebugEvent() = 0; + inline void textureBarrier(ITextureResource* texture, ResourceState src, ResourceState dst) + { + textureBarrier(1, &texture, src, dst); + } + inline void bufferBarrier(IBufferResource* buffer, ResourceState src, ResourceState dst) + { + bufferBarrier(1, &buffer, src, dst); + } }; class IRenderCommandEncoder : public IResourceCommandEncoder @@ -1846,7 +1846,7 @@ public: IRenderPassLayout* renderPass, IFramebuffer* framebuffer, IRenderCommandEncoder** outEncoder) = 0; - IRenderCommandEncoder* + inline IRenderCommandEncoder* encodeRenderCommands(IRenderPassLayout* renderPass, IFramebuffer* framebuffer) { IRenderCommandEncoder* result; @@ -1856,7 +1856,7 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL encodeComputeCommands(IComputeCommandEncoder** outEncoder) = 0; - IComputeCommandEncoder* encodeComputeCommands() + inline IComputeCommandEncoder* encodeComputeCommands() { IComputeCommandEncoder* result; encodeComputeCommands(&result); @@ -1865,7 +1865,7 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL encodeResourceCommands(IResourceCommandEncoder** outEncoder) = 0; - IResourceCommandEncoder* encodeResourceCommands() + inline IResourceCommandEncoder* encodeResourceCommands() { IResourceCommandEncoder* result; encodeResourceCommands(&result); @@ -1874,7 +1874,7 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) = 0; - IRayTracingCommandEncoder* encodeRayTracingCommands() + inline IRayTracingCommandEncoder* encodeRayTracingCommands() { IRayTracingCommandEncoder* result; encodeRayTracingCommands(&result); diff --git a/source/core/slang-smart-pointer.h b/source/core/slang-smart-pointer.h index 75c4398a5..80e8adbf1 100644 --- a/source/core/slang-smart-pointer.h +++ b/source/core/slang-smart-pointer.h @@ -217,6 +217,11 @@ namespace Slang return pointer; } + T* get() const + { + return pointer; + } + operator T*() const { return pointer; diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 5d4b57543..82783c0b6 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -571,12 +571,58 @@ T __attachToNativeRef(NativeRef<T> nativeVal) __magic_type(StringType) __intrinsic_type($(kIROp_StringType)) struct String -{}; +{ + __target_intrinsic(cpp) + __init(int val); + __target_intrinsic(cpp) + __init(uint val); + __target_intrinsic(cpp) + __init(int64_t val); + __target_intrinsic(cpp) + __init(uint64_t val); + __target_intrinsic(cpp) + __init(float val); + __target_intrinsic(cpp) + __init(double val); + + __target_intrinsic(cpp) + int64_t getLength(); + + property int length + { + get { return (int)getLength(); } + } +}; __magic_type(NativeStringType) __intrinsic_type($(kIROp_NativeStringType)) struct NativeString -{}; +{ + __target_intrinsic(cpp, "int(strlen($0))") + int getLength(); + + __target_intrinsic(cpp, "(void*)((const char*)($0))") + Ptr<void> getBuffer(); + + property int length { [__unsafeForceInlineEarly] get{return getLength();} } +}; + +extension Ptr<void> +{ + __implicit_conversion($(kConversionCost_PtrToVoidPtr)) + [__unsafeForceInlineEarly] + __init(NativeString nativeStr) { this = nativeStr.getBuffer(); } + + __generic<T> + __intrinsic_op(0) + __implicit_conversion($(kConversionCost_PtrToVoidPtr)) + __init(Ptr<T> ptr); + + __generic<T> + __intrinsic_op(0) + __implicit_conversion($(kConversionCost_PtrToVoidPtr)) + __init(NativeRef<T> ptr); +} __magic_type(DynamicType) __intrinsic_type($(kIROp_DynamicType)) diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h index 00a4a482c..d6f9a305b 100644 --- a/source/slang/slang-ast-support-types.h +++ b/source/slang/slang-ast-support-types.h @@ -91,6 +91,7 @@ namespace Slang kConversionCost_NoneToOptional = 150, kConversionCost_ValToOptional = 150, kConversionCost_NullPtrToPtr = 150, + kConversionCost_PtrToVoidPtr = 150, // Conversions that are lossless, but change "kind" kConversionCost_UnsignedToSignedPromotion = 200, diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 734471fd0..dcd25419e 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -981,9 +981,8 @@ void CLikeSourceEmitter::emitSimpleValueImpl(IRInst* inst) m_writer->emitUInt64(uint64_t(litInst->value.intVal)); m_writer->emit(")"); #else - m_writer->emit("uint("); m_writer->emit(UInt(uint32_t(litInst->value.intVal))); - m_writer->emit(")"); + m_writer->emit("U"); #endif break; } @@ -1617,6 +1616,7 @@ void CLikeSourceEmitter::emitComInterfaceCallExpr(IRCall* inst, EmitOpInfo const auto outerPrec = inOuterPrec; bool needClose = maybeEmitParens(outerPrec, prec); + emitOperand(object, leftSide(outerPrec, prec)); m_writer->emit("->"); m_writer->emit(getName(methodKey)); @@ -1634,10 +1634,19 @@ void CLikeSourceEmitter::emitCallExpr(IRCall* inst, EmitOpInfo outerPrec) // Detect if this is a call into a COM interface method. if (funcValue->getOp() == kIROp_lookup_interface_method) { - const auto operand0TypeOp = funcValue->getOperand(0)->getDataType()->getOp(); - - switch (operand0TypeOp) + auto operand0Type = funcValue->getOperand(0)->getDataType(); + switch (operand0Type->getOp()) { + case kIROp_WitnessTableIDType: + case kIROp_WitnessTableType: + if (as<IRWitnessTableTypeBase>(operand0Type) + ->getConformanceType() + ->findDecoration<IRComInterfaceDecoration>()) + { + emitComInterfaceCallExpr(inst, outerPrec); + return; + } + break; case kIROp_ComPtrType: case kIROp_PtrType: case kIROp_NativePtrType: diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index bc145dca1..dd3acff78 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -2533,7 +2533,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut m_writer->emit("*>("); auto prec = getInfo(EmitOp::Postfix); emitOperand(inst->getOperand(0), leftSide(getInfo(EmitOp::General), prec)); - m_writer->emit(".Ptr()"); + m_writer->emit(".get()"); m_writer->emit("))"); return true; } diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp index 7c712d2c5..cbeddcb13 100644 --- a/source/slang/slang-emit-cuda.cpp +++ b/source/slang/slang-emit-cuda.cpp @@ -34,6 +34,8 @@ static bool _isSingleNameBasicType(IROp op) case kIROp_UInt16Type: case kIROp_UIntType: case kIROp_UInt64Type: + case kIROp_IntPtrType: + case kIROp_UIntPtrType: { return false; } @@ -53,14 +55,18 @@ UnownedStringSlice CUDASourceEmitter::getBuiltinTypeName(IROp op) case kIROp_Int16Type: return UnownedStringSlice("short"); case kIROp_IntType: return UnownedStringSlice("int"); case kIROp_Int64Type: return UnownedStringSlice("longlong"); - case kIROp_IntPtrType: return UnownedStringSlice("intptr_t"); case kIROp_UInt8Type: return UnownedStringSlice("uchar"); case kIROp_UInt16Type: return UnownedStringSlice("ushort"); case kIROp_UIntType: return UnownedStringSlice("uint"); case kIROp_UInt64Type: return UnownedStringSlice("ulonglong"); - case kIROp_UIntPtrType: return UnownedStringSlice("uintptr_t"); - +#if SLANG_PTR_IS_64 + case kIROp_IntPtrType: return UnownedStringSlice("int64_t"); + case kIROp_UIntPtrType: return UnownedStringSlice("uint64_t"); +#else + case kIROp_IntPtrType: return UnownedStringSlice("int"); + case kIROp_UIntPtrType: return UnownedStringSlice("uint"); +#endif case kIROp_HalfType: { m_extensionTracker->requireBaseType(BaseType::Half); diff --git a/source/slang/slang-ir-dll-import.cpp b/source/slang/slang-ir-dll-import.cpp index bfd384f70..8b611feba 100644 --- a/source/slang/slang-ir-dll-import.cpp +++ b/source/slang/slang-ir-dll-import.cpp @@ -111,7 +111,7 @@ struct DllImportContext auto funcPtr = builder.createGlobalVar(nativeType); builder.setInsertInto(funcPtr); builder.emitBlock(); - builder.emitReturn(builder.getPtrValue(nullptr)); + builder.emitReturn(builder.getNullVoidPtrValue()); builder.setInsertInto(func); auto block = builder.emitBlock(); @@ -126,7 +126,7 @@ struct DllImportContext params.add(builder.emitParam((IRType*)paramType)); } - IRInst* cmpArgs[] = {builder.emitLoad(nativeType, funcPtr), builder.getPtrValue(nullptr)}; + IRInst* cmpArgs[] = {builder.emitLoad(nativeType, funcPtr), builder.getNullVoidPtrValue() }; auto isUninitialized = builder.emitIntrinsicInst(builder.getBoolType(), kIROp_Eql, 2, cmpArgs); @@ -141,7 +141,7 @@ struct DllImportContext if (dllImportDecoration->getLibraryName() == "") { - modulePtr = builder.getPtrValue(nullptr); + modulePtr = builder.getNullVoidPtrValue(); } else { diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index f7347ce0b..76dbe55f9 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -2262,7 +2262,9 @@ public: IRInst* getIntValue(IRType* type, IRIntegerValue value); IRInst* getFloatValue(IRType* type, IRFloatingPointValue value); IRStringLit* getStringValue(const UnownedStringSlice& slice); - IRPtrLit* getPtrValue(void* value); + IRPtrLit* _getPtrValue(void* ptr); + IRPtrLit* getNullPtrValue(IRType* type); + IRPtrLit* getNullVoidPtrValue() { return getNullPtrValue(getPtrType(getVoidType())); } IRVoidLit* getVoidValue(); IRInst* getCapabilityValue(CapabilitySet const& caps); diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp index 6667a6d9d..a5130e8b6 100644 --- a/source/slang/slang-ir-link.cpp +++ b/source/slang/slang-ir-link.cpp @@ -272,7 +272,8 @@ IRInst* IRSpecContext::maybeCloneValue(IRInst* originalValue) case kIROp_PtrLit: { IRConstant* c = (IRConstant*)originalValue; - return builder->getPtrValue(c->value.ptrVal); + SLANG_RELEASE_ASSERT(c->value.ptrVal == nullptr); + return builder->getNullVoidPtrValue(); } break; diff --git a/source/slang/slang-ir-lower-com-methods.cpp b/source/slang/slang-ir-lower-com-methods.cpp index 6d5ddb261..b991dbd03 100644 --- a/source/slang/slang-ir-lower-com-methods.cpp +++ b/source/slang/slang-ir-lower-com-methods.cpp @@ -30,9 +30,21 @@ struct ComMethodLoweringContext : public InstPassBase auto callee = as<IRLookupWitnessMethod>(comCall->getCallee()); SLANG_ASSERT(callee); + IRLookupWitnessMethod* innerMostCallee = callee; + while (innerMostCallee->getOperand(0)->getOp() == kIROp_lookup_interface_method) + { + innerMostCallee = as<IRLookupWitnessMethod>(innerMostCallee->getOperand(0)); + } + if (callee != innerMostCallee) + { + callee = (IRLookupWitnessMethod*)builder.emitLookupInterfaceMethodInst( + callee->getDataType(), + innerMostCallee->getWitnessTable(), + callee->getRequirementKey()); + } comCallees.Add(callee); - auto calleeType = as<IRFuncType>(comCall->getCallee()->getDataType()); + auto calleeType = as<IRFuncType>(callee->getDataType()); SLANG_ASSERT(calleeType); auto nativeFuncType = marshal.getNativeFuncType(builder, calleeType); @@ -45,7 +57,7 @@ struct ComMethodLoweringContext : public InstPassBase builder, calleeType, nativeFuncType, - comCall->getCallee(), + callee, args.getCount(), args.getArrayView().getBuffer()); diff --git a/source/slang/slang-ir-lower-existential.cpp b/source/slang/slang-ir-lower-existential.cpp index 2d533b424..f7669a557 100644 --- a/source/slang/slang-ir-lower-existential.cpp +++ b/source/slang/slang-ir-lower-existential.cpp @@ -20,9 +20,10 @@ namespace Slang IRBuilder builderStorage(sharedContext->sharedBuilderStorage); auto builder = &builderStorage; builder->setInsertBefore(inst); - auto value = inst->getWrappedValue(); auto valueType = sharedContext->lowerType(builder, value->getDataType()); + if (valueType->getOp() == kIROp_ComPtrType) + return; auto witnessTableType = cast<IRWitnessTableTypeBase>(inst->getWitnessTable()->getDataType()); auto interfaceType = witnessTableType->getConformanceType(); if (interfaceType->findDecoration<IRComInterfaceDecoration>()) diff --git a/source/slang/slang-ir-lower-generic-function.cpp b/source/slang/slang-ir-lower-generic-function.cpp index 0f94f137d..806ea8826 100644 --- a/source/slang/slang-ir-lower-generic-function.cpp +++ b/source/slang/slang-ir-lower-generic-function.cpp @@ -268,6 +268,8 @@ namespace Slang IRInst* interfaceRequirementVal = nullptr; auto witnessTableType = as<IRWitnessTableType>(lookupInst->getWitnessTable()->getDataType()); if (!witnessTableType) return; + if (witnessTableType->getConformanceType()->findDecoration<IRComInterfaceDecoration>()) + return; auto interfaceType = maybeLowerInterfaceType(cast<IRInterfaceType>(witnessTableType->getConformanceType())); interfaceRequirementVal = sharedContext->findInterfaceRequirementVal(interfaceType, lookupInst->getRequirementKey()); lookupInst->setFullType((IRType*)interfaceRequirementVal); diff --git a/source/slang/slang-ir-lower-optional-type.cpp b/source/slang/slang-ir-lower-optional-type.cpp index 96f8353bb..c4a40774c 100644 --- a/source/slang/slang-ir-lower-optional-type.cpp +++ b/source/slang/slang-ir-lower-optional-type.cpp @@ -118,12 +118,20 @@ namespace Slang builder->setInsertBefore(inst); auto info = getLoweredOptionalType(builder, inst->getDataType()); - List<IRInst*> operands; - operands.add(inst->getOperand(0)); - operands.add(builder->getBoolValue(true)); - auto makeStruct = builder->emitMakeStruct(info->loweredType, operands); - inst->replaceUsesWith(makeStruct); - inst->removeAndDeallocate(); + if (info->loweredType != info->valueType) + { + List<IRInst*> operands; + operands.add(inst->getOperand(0)); + operands.add(builder->getBoolValue(true)); + auto makeStruct = builder->emitMakeStruct(info->loweredType, operands); + inst->replaceUsesWith(makeStruct); + inst->removeAndDeallocate(); + } + else + { + inst->replaceUsesWith(inst->getOperand(0)); + inst->removeAndDeallocate(); + } } void processMakeOptionalNone(IRMakeOptionalNone* inst) @@ -133,13 +141,20 @@ namespace Slang builder->setInsertBefore(inst); auto info = getLoweredOptionalType(builder, inst->getDataType()); - - List<IRInst*> operands; - operands.add(inst->getDefaultValue()); - operands.add(builder->getBoolValue(false)); - auto makeStruct = builder->emitMakeStruct(info->loweredType, operands); - inst->replaceUsesWith(makeStruct); - inst->removeAndDeallocate(); + if (info->loweredType != info->valueType) + { + List<IRInst*> operands; + operands.add(inst->getDefaultValue()); + operands.add(builder->getBoolValue(false)); + auto makeStruct = builder->emitMakeStruct(info->loweredType, operands); + inst->replaceUsesWith(makeStruct); + inst->removeAndDeallocate(); + } + else + { + inst->replaceUsesWith(builder->getNullPtrValue(info->valueType)); + inst->removeAndDeallocate(); + } } IRInst* getOptionalHasValue(IRBuilder* builder, IRInst* optionalInst) diff --git a/source/slang/slang-ir-marshal-native-call.cpp b/source/slang/slang-ir-marshal-native-call.cpp index e4c202798..215e6001b 100644 --- a/source/slang/slang-ir-marshal-native-call.cpp +++ b/source/slang/slang-ir-marshal-native-call.cpp @@ -33,7 +33,7 @@ namespace Slang for (UInt i = 0; i < declaredFuncType->getParamCount(); ++i) { auto paramType = declaredFuncType->getParamType(i); - nativeParamTypes.add(getNativeType(builder, as<IRType>(paramType))); + nativeParamTypes.add(getNativeType(builder, (IRType*)(paramType))); } IRType* returnType = declaredFuncType->getResultType(); if (auto resultType = as<IRResultType>(declaredFuncType->getResultType())) @@ -70,9 +70,9 @@ namespace Slang } void NativeCallMarshallingContext::marshalManagedValueToNativeValue( - IRBuilder& builder, IRInst* originalArg, List<IRInst*>& args) + IRBuilder& builder, IRType* originalParamType, IRInst* originalArg, List<IRInst*>& args) { - switch (originalArg->getDataType()->getOp()) + switch (originalParamType->getOp()) { case kIROp_InOutType: case kIROp_RefType: @@ -257,7 +257,8 @@ namespace Slang List<IRInst*> args; for (Int i = 0; i < argCount; i++) { - marshalManagedValueToNativeValue(builder, originalArgs[i], args); + auto paramType = originalFuncType->getParamType(i); + marshalManagedValueToNativeValue(builder, paramType, originalArgs[i], args); } IRType* originalReturnType = originalFuncType->getResultType(); diff --git a/source/slang/slang-ir-marshal-native-call.h b/source/slang/slang-ir-marshal-native-call.h index e70d177ac..e287f00a2 100644 --- a/source/slang/slang-ir-marshal-native-call.h +++ b/source/slang/slang-ir-marshal-native-call.h @@ -43,7 +43,7 @@ namespace Slang // Marshal a managed value to a native value for input into a native functions. void marshalManagedValueToNativeValue( - IRBuilder& builder, IRInst* originalArg, List<IRInst*>& args); + IRBuilder& builder, IRType* originalParamType, IRInst* originalArg, List<IRInst*>& args); // Marshal a managed value to a native value for the return value of a native function. void marshalManagedValueToNativeResultValue( diff --git a/source/slang/slang-ir-peephole.cpp b/source/slang/slang-ir-peephole.cpp index d67c87ca9..32950edc9 100644 --- a/source/slang/slang-ir-peephole.cpp +++ b/source/slang/slang-ir-peephole.cpp @@ -90,7 +90,7 @@ struct PeepholeContext : InstPassBase auto ptr = inst->getOperand(0); IRBuilder builder(&sharedBuilderStorage); builder.setInsertBefore(inst); - auto neq = builder.emitNeq(ptr, builder.getPtrValue(nullptr)); + auto neq = builder.emitNeq(ptr, builder.getNullVoidPtrValue()); inst->replaceUsesWith(neq); inst->removeAndDeallocate(); changed = true; @@ -177,6 +177,26 @@ struct PeepholeContext : InstPassBase } } break; + case kIROp_GetNativePtr: + { + if (inst->getOperand(0)->getOp() == kIROp_PtrLit) + { + inst->replaceUsesWith(inst->getOperand(0)); + inst->removeAndDeallocate(); + changed = true; + } + } + break; + case kIROp_MakeExistential: + { + if (inst->getOperand(0)->getOp() == kIROp_ExtractExistentialValue) + { + inst->replaceUsesWith(inst->getOperand(0)->getOperand(0)); + inst->removeAndDeallocate(); + changed = true; + } + } + break; default: break; } diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp index 7775fdb91..1f13eb754 100644 --- a/source/slang/slang-ir-util.cpp +++ b/source/slang/slang-ir-util.cpp @@ -53,7 +53,10 @@ bool isComInterfaceType(IRType* type) { return true; } - + if (auto witnessTableType = as<IRWitnessTableTypeBase>(type)) + { + return isComInterfaceType((IRType*)witnessTableType->getConformanceType()); + } if (auto ptrType = as<IRNativePtrType>(type)) { auto valueType = ptrType->getValueType(); diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index 19d3ce59a..46d6d445d 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -2203,15 +2203,24 @@ namespace Slang return static_cast<IRStringLit*>(_findOrEmitConstant(keyInst)); } - IRPtrLit* IRBuilder::getPtrValue(void* value) + IRPtrLit* IRBuilder::_getPtrValue(void* data) { - IRType* type = getPtrType(getVoidType()); + auto type = getPtrType(getVoidType()); + IRConstant keyInst; + memset(&keyInst, 0, sizeof(keyInst)); + keyInst.m_op = kIROp_PtrLit; + keyInst.typeUse.usedValue = type; + keyInst.value.ptrVal = data; + return (IRPtrLit*)_findOrEmitConstant(keyInst); + } + IRPtrLit* IRBuilder::getNullPtrValue(IRType* type) + { IRConstant keyInst; memset(&keyInst, 0, sizeof(keyInst)); keyInst.m_op = kIROp_PtrLit; keyInst.typeUse.usedValue = type; - keyInst.value.ptrVal = value; + keyInst.value.ptrVal = nullptr; return (IRPtrLit*) _findOrEmitConstant(keyInst); } @@ -4589,6 +4598,9 @@ namespace Slang switch (managedPtrType->getOp()) { case kIROp_InterfaceType: + return emitIntrinsicInst( + getPtrType(getNativePtrType((IRType*)managedPtrType)), kIROp_GetManagedPtrWriteRef, 1, &ptrToManagedPtr); + break; case kIROp_ComPtrType: return emitIntrinsicInst( getPtrType(getNativePtrType((IRType*)managedPtrType->getOperand(0))), kIROp_GetManagedPtrWriteRef, 1, &ptrToManagedPtr); @@ -4651,7 +4663,7 @@ namespace Slang void IRBuilder::addHighLevelDeclDecoration(IRInst* inst, Decl* decl) { - auto ptrConst = getPtrValue(decl); + auto ptrConst = _getPtrValue(decl); addDecoration(inst, kIROp_HighLevelDeclDecoration, ptrConst); } @@ -6193,6 +6205,7 @@ namespace Slang case kIROp_PackAnyValue: case kIROp_UnpackAnyValue: case kIROp_Reinterpret: + case kIROp_GetNativePtr: return false; } } diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 90f8208b2..c02efc971 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -3451,7 +3451,7 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo> LoweredValInfo visitNullPtrLiteralExpr(NullPtrLiteralExpr*) { - return LoweredValInfo::simple(context->irBuilder->getPtrValue(nullptr)); + return LoweredValInfo::simple(context->irBuilder->getNullVoidPtrValue()); } LoweredValInfo visitNoneLiteralExpr(NoneLiteralExpr*) @@ -3889,7 +3889,10 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo> // These may include `out` and `inout` arguments that // require "fixup" work on the other side. // - auto funcType = lowerType(context, funcExpr->type); + FuncDeclBaseTypeInfo funcTypeInfo; + _lowerFuncDeclBaseTypeInfo(context, funcDeclRef.template as<FunctionDeclBase>(), funcTypeInfo); + + auto funcType = funcTypeInfo.type; addDirectCallArgs(expr, funcDeclRef, &irArgs, &argFixups); auto result = emitCallToDeclRef( context, diff --git a/tests/cpu-program/gfx-smoke.slang b/tests/cpu-program/gfx-smoke.slang index fda6d5454..2ad33052f 100644 --- a/tests/cpu-program/gfx-smoke.slang +++ b/tests/cpu-program/gfx-smoke.slang @@ -3,14 +3,102 @@ __target_intrinsic(cpp, "printf(\"%s\\n\", ($0).getBuffer())") void writeln(String text); import gfx; +import slang; public __extern_cpp int main() { gfx.DeviceDesc deviceDesc = {}; deviceDesc.deviceType = gfx.DeviceType.CPU; - Optional<gfx.IDevice> obj; - if (gfx.succeeded(gfx.gfxCreateDevice(&deviceDesc, obj)) && obj.hasValue) - writeln("succ"); - else + Optional<gfx.IDevice> device; + gfx.gfxCreateDevice(&deviceDesc, device); + if (device == none) + { writeln("fail"); + return -1; + } + + gfx.CommandQueueDesc queueDesc = {}; + queueDesc.type = gfx.QueueType.Graphics; + Optional<gfx.ICommandQueue> queue; + device.value.createCommandQueue(&queueDesc, queue); + + gfx.ShaderProgramDesc2 programDesc = {}; + NativeString s = + "[shader(\"compute\")]" + "[numthreads(4, 1, 1)]" + "void computeMain(" + " uint3 sv_dispatchThreadID: SV_DispatchThreadID," + " uniform RWStructuredBuffer<float> buffer" + " )" + "{" + " var input = buffer[sv_dispatchThreadID.x];" + " buffer[sv_dispatchThreadID.x] = sv_dispatchThreadID.x;" + "}"; + programDesc.sourceData = s; + programDesc.sourceType = gfx.ShaderModuleSourceType.SlangSource; + programDesc.sourceDataSize = s.length; + programDesc.entryPointCount = 1; + NativeString entryPointName = "computeMain"; + programDesc.entryPointNames = &entryPointName; + Optional<gfx.IShaderProgram> program; + Optional<slang.ISlangBlob> diagBlob; + device.value.createProgram2(&programDesc, program, diagBlob); + + Optional<gfx.IPipelineState> pipeline; + gfx.ComputePipelineStateDesc pipelineDesc = {}; + pipelineDesc.program = NativeRef<gfx.IShaderProgram>(program.value); + device.value.createComputePipelineState(&pipelineDesc, pipeline); + + Optional<gfx.ITransientResourceHeap> transientHeap; + gfx.TransientResourceHeapDesc transientHeapDesc = {}; + transientHeapDesc.constantBufferDescriptorCount = 64; + transientHeapDesc.constantBufferSize = 1024; + transientHeapDesc.srvDescriptorCount = 1024; + transientHeapDesc.uavDescriptorCount = 1024; + transientHeapDesc.samplerDescriptorCount = 256; + transientHeapDesc.accelerationStructureDescriptorCount = 32; + device.value.createTransientResourceHeap(&transientHeapDesc, transientHeap); + + Optional<gfx.IBufferResource> buffer; + gfx.BufferResourceDesc bufferDesc = {}; + bufferDesc.memoryType = gfx.MemoryType.DeviceLocal; + bufferDesc.allowedStates.add(gfx.ResourceState.UnorderedAccess); + bufferDesc.defaultState = gfx.ResourceState.UnorderedAccess; + bufferDesc.elementSize = 4; + bufferDesc.sizeInBytes = 256; + bufferDesc.type = gfx.ResourceType.Buffer; + device.value.createBufferResource(&bufferDesc, nullptr, buffer); + + Optional<gfx.IResourceView> bufferView; + gfx.ResourceViewDesc viewDesc = {}; + viewDesc.type = gfx.ResourceViewType.UnorderedAccess; + device.value.createBufferView(buffer.value, none, &viewDesc, bufferView); + + Optional<gfx.ICommandBuffer> commandBuffer; + transientHeap.value.createCommandBuffer(commandBuffer); + Optional<gfx.IComputeCommandEncoder> encoder; + commandBuffer.value.encodeComputeCommands(encoder); + Optional<gfx.IShaderObject> rootObject; + encoder.value.bindPipeline(pipeline.value, rootObject); + Optional<gfx.IShaderObject> entryPointObject; + rootObject.value.getEntryPoint(0, entryPointObject); + gfx.ShaderOffset offset = {}; + entryPointObject.value.setResource(&offset, bufferView.value); + encoder.value.dispatchCompute(1, 1, 1); + encoder.value.endEncoding(); + commandBuffer.value.close(); + + NativeRef<gfx.ICommandBuffer> commandBufferRef = NativeRef<gfx.ICommandBuffer>(commandBuffer.value); + queue.value.executeCommandBuffers(1, &commandBufferRef, none, 0); + queue.value.waitOnHost(); + + Optional<slang.ISlangBlob> blob; + device.value.readBufferResource(buffer.value, 0, 16, blob); + + for (int i = 0; i < 4; i++) + { + float val = ((float *)blob.value.getBufferPointer())[i]; + writeln(String(val)); + } + return 0; }
\ No newline at end of file diff --git a/tests/cpu-program/gfx-smoke.slang.expected b/tests/cpu-program/gfx-smoke.slang.expected index 981dcfc29..aa0dd7680 100644 --- a/tests/cpu-program/gfx-smoke.slang.expected +++ b/tests/cpu-program/gfx-smoke.slang.expected @@ -2,5 +2,8 @@ result code = 0 standard error = { } standard output = { -succ +0 +1 +2 +3 } diff --git a/tests/language-feature/types/intptr.slang b/tests/language-feature/types/intptr.slang index ea626adad..0be67cdb7 100644 --- a/tests/language-feature/types/intptr.slang +++ b/tests/language-feature/types/intptr.slang @@ -8,10 +8,12 @@ RWStructuredBuffer<int> outputBuffer; __target_intrinsic(cpp, "sizeof(intptr_t)") +__target_intrinsic(cuda, "sizeof(size_t)") intptr_t getNativeIntPtrSize(); __generic<T> __target_intrinsic(cpp, "sizeof($0)") +__target_intrinsic(cuda, "sizeof($0)") intptr_t getSizeOf(T val); intptr_t getIntPtrVal() { return 0z; } diff --git a/tools/gfx/gfx.slang b/tools/gfx/gfx.slang index d57b746db..17a38e28d 100644 --- a/tools/gfx/gfx.slang +++ b/tools/gfx/gfx.slang @@ -864,9 +864,9 @@ interface IShaderObject slang::TypeLayoutReflection* getElementTypeLayout(); ShaderObjectContainerType getContainerType(); GfxCount getEntryPointCount(); - Result getEntryPoint(GfxIndex index, out IShaderObject entryPoint); - Result setData(ShaderOffset* offset, void *data, Size size); - Result getObject(ShaderOffset* offset, out IShaderObject object); + Result getEntryPoint(GfxIndex index, out Optional<IShaderObject> entryPoint); + Result setData(ShaderOffset *offset, void *data, Size size); + Result getObject(ShaderOffset *offset, out Optional<IShaderObject> object); Result setObject(ShaderOffset* offset, IShaderObject object); Result setResource(ShaderOffset* offset, IResourceView resourceView); Result setSampler(ShaderOffset* offset, ISamplerState sampler); @@ -1473,7 +1473,7 @@ interface IComputeCommandEncoder : IResourceCommandEncoder // sub-shader-objects bound to it. The user must be responsible for ensuring that any // resources or shader objects that is set into `outRooShaderObject` stays alive during // the execution of the command buffer. - Result bindPipeline(IPipelineState state, out IShaderObject outRootShaderObject); + Result bindPipeline(IPipelineState state, out Optional<IShaderObject> outRootShaderObject); // Sets the current pipeline state along with a pre-created mutable root shader object. Result bindPipelineWithRootObject(IPipelineState state, IShaderObject rootObject); @@ -1542,11 +1542,11 @@ interface ICommandBuffer IFramebuffer framebuffer, out IRenderCommandEncoder outEncoder); - void encodeComputeCommands(out IComputeCommandEncoder encoder); + void encodeComputeCommands(out Optional<IComputeCommandEncoder> encoder); - void encodeResourceCommands(out IResourceCommandEncoder outEncoder); + void encodeResourceCommands(out Optional<IResourceCommandEncoder> outEncoder); - void encodeRayTracingCommands(out IRayTracingCommandEncoder outEncoder); + void encodeRayTracingCommands(out Optional<IRayTracingCommandEncoder> outEncoder); void close(); @@ -1616,7 +1616,7 @@ interface ITransientResourceHeap // buffers must be closed before submission. The current D3D12 implementation has a limitation // that only one command buffer maybe recorded at a time. User must finish recording a command // buffer before creating another command buffer. - Result createCommandBuffer(out ICommandBuffer outCommandBuffer); + Result createCommandBuffer(out Optional<ICommandBuffer> outCommandBuffer); }; struct SwapchainDesc @@ -1759,7 +1759,7 @@ interface IDevice Result createTransientResourceHeap( TransientResourceHeapDesc *desc, - out ITransientResourceHeap outHeap); + out Optional<ITransientResourceHeap> outHeap); /// Create a texture resource. /// @@ -1795,7 +1795,7 @@ interface IDevice Result createBufferResource( BufferResourceDesc* desc, void *initData, - out IBufferResource outResource); + out Optional<IBufferResource> outResource); Result createBufferFromNativeHandle( InteropHandle handle, @@ -1814,9 +1814,9 @@ interface IDevice Result createBufferView( IBufferResource buffer, - IBufferResource counterBuffer, + Optional<IBufferResource> counterBuffer, ResourceViewDesc* desc, - out IResourceView outView); + out Optional<IResourceView> outView); Result createFramebufferLayout(FramebufferLayoutDesc* desc, out IFramebufferLayout outFrameBuffer); @@ -1832,7 +1832,7 @@ interface IDevice Result createInputLayout( InputLayoutDesc* desc, out IInputLayout outLayout); - Result createCommandQueue(CommandQueueDesc* desc, out ICommandQueue outQueue); + Result createCommandQueue(CommandQueueDesc* desc, out Optional<ICommandQueue> outQueue); Result createShaderObject( slang::TypeReflection *type, @@ -1863,19 +1863,19 @@ interface IDevice Result createProgram2( ShaderProgramDesc2 *desc, - out IShaderProgram outProgram, - out slang::ISlangBlob outDiagnosticBlob); + out Optional<IShaderProgram> outProgram, + out Optional<slang::ISlangBlob> outDiagnosticBlob); Result createGraphicsPipelineState( - GraphicsPipelineStateDesc* desc, - out IPipelineState outState); + GraphicsPipelineStateDesc *desc, + out Optional<IPipelineState> outState); Result createComputePipelineState( ComputePipelineStateDesc* desc, - out IPipelineState outState); + out Optional<IPipelineState> outState); Result createRayTracingPipelineState( - RayTracingPipelineStateDesc* desc, out IPipelineState outState); + RayTracingPipelineStateDesc *desc, out Optional<IPipelineState> outState); /// Read back texture resource and stores the result in `outBlob`. Result readTextureResource( @@ -1889,7 +1889,7 @@ interface IDevice IBufferResource buffer, Offset offset, Size size, - out slang::ISlangBlob outBlob); + out Optional<slang::ISlangBlob> outBlob); /// Get the type of this renderer DeviceInfo* getDeviceInfo(); diff --git a/tools/gfx/renderer-shared.cpp b/tools/gfx/renderer-shared.cpp index 2e5454851..69046d216 100644 --- a/tools/gfx/renderer-shared.cpp +++ b/tools/gfx/renderer-shared.cpp @@ -472,14 +472,31 @@ Result RendererBase::createProgram2( ISlangBlob** outDiagnostic) { auto slangSession = slangContext.session.get(); - - SLANG_RELEASE_ASSERT(desc.sourceType == ShaderModuleSourceType::SlangSourceFile); - - auto fileName = (char*)desc.sourceData; + slang::IModule* module = nullptr; ComPtr<slang::IBlob> diagnosticsBlob; - slang::IModule* module = slangSession->loadModule(fileName, diagnosticsBlob.writeRef()); - if (!module) - return SLANG_FAIL; + switch (desc.sourceType) + { + case ShaderModuleSourceType::SlangSourceFile: + { + auto fileName = (char*)desc.sourceData; + module = slangSession->loadModule(fileName, diagnosticsBlob.writeRef()); + if (!module) + return SLANG_FAIL; + break; + } + case ShaderModuleSourceType::SlangSource: + { + auto hash = getStableHashCode32((char*)desc.sourceData, desc.sourceDataSize); + auto hashStr = String(hash); + auto srcBlob = UnownedRawBlob::create(desc.sourceData, desc.sourceDataSize); + module = slangSession->loadModuleFromSource(hashStr.getBuffer(), hashStr.getBuffer(), srcBlob, diagnosticsBlob.writeRef()); + if (!module) + return SLANG_FAIL; + break; + } + default: + SLANG_RELEASE_ASSERT(false); + } Slang::List<ComPtr<slang::IComponentType>> componentTypes; componentTypes.add(ComPtr<slang::IComponentType>(module)); |
