summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-09-15 20:37:45 -0700
committerGitHub <noreply@github.com>2022-09-15 20:37:45 -0700
commita5d3bec25d70f23da1e79cd7773981ff34593611 (patch)
tree92c8cb983c57bbee141d4e6f3f91f265e04d6a08
parenta6032446c6bf7f64d1e201bf438a4c7605a3dbb4 (diff)
Run simple compute kernel in gfx-smoke test. (#2400)
-rw-r--r--.gitignore3
-rw-r--r--prelude/slang-cpp-prelude.h2
-rw-r--r--slang-gfx.h52
-rw-r--r--source/core/slang-smart-pointer.h5
-rw-r--r--source/slang/core.meta.slang50
-rw-r--r--source/slang/slang-ast-support-types.h1
-rw-r--r--source/slang/slang-emit-c-like.cpp19
-rw-r--r--source/slang/slang-emit-cpp.cpp2
-rw-r--r--source/slang/slang-emit-cuda.cpp12
-rw-r--r--source/slang/slang-ir-dll-import.cpp6
-rw-r--r--source/slang/slang-ir-insts.h4
-rw-r--r--source/slang/slang-ir-link.cpp3
-rw-r--r--source/slang/slang-ir-lower-com-methods.cpp16
-rw-r--r--source/slang/slang-ir-lower-existential.cpp3
-rw-r--r--source/slang/slang-ir-lower-generic-function.cpp2
-rw-r--r--source/slang/slang-ir-lower-optional-type.cpp41
-rw-r--r--source/slang/slang-ir-marshal-native-call.cpp9
-rw-r--r--source/slang/slang-ir-marshal-native-call.h2
-rw-r--r--source/slang/slang-ir-peephole.cpp22
-rw-r--r--source/slang/slang-ir-util.cpp5
-rw-r--r--source/slang/slang-ir.cpp21
-rw-r--r--source/slang/slang-lower-to-ir.cpp7
-rw-r--r--tests/cpu-program/gfx-smoke.slang96
-rw-r--r--tests/cpu-program/gfx-smoke.slang.expected5
-rw-r--r--tests/language-feature/types/intptr.slang2
-rw-r--r--tools/gfx/gfx.slang40
-rw-r--r--tools/gfx/renderer-shared.cpp31
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));