summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-08-20 01:03:06 -0700
committerGitHub <noreply@github.com>2022-08-20 01:03:06 -0700
commitaf70651a4843b16dd24e14b5cedffe399ebeb862 (patch)
treea6aefd5db94a048114b9a8d7ed3f826533105fab /source
parent6412c4913b6a063438bb11863f2c154d3ae42dfe (diff)
Call `gfx` in slang program. (#2370)
Diffstat (limited to 'source')
-rw-r--r--source/slang-rt/slang-rt.cpp11
-rw-r--r--source/slang-rt/slang-rt.h2
-rw-r--r--source/slang/slang-emit-c-like.cpp44
-rw-r--r--source/slang/slang-emit-cpp.cpp3
-rw-r--r--source/slang/slang-emit.cpp2
-rw-r--r--source/slang/slang-ir-com-interface.cpp5
-rw-r--r--source/slang/slang-ir-dll-import.cpp28
-rw-r--r--source/slang/slang-ir-dll-import.h3
-rw-r--r--source/slang/slang-ir-generics-lowering-context.cpp4
-rw-r--r--source/slang/slang-ir-layout.cpp13
-rw-r--r--source/slang/slang-ir-lower-generics.cpp3
-rw-r--r--source/slang/slang-ir-marshal-native-call.cpp5
-rw-r--r--source/slang/slang-ir.h13
-rw-r--r--source/slang/slang-lower-to-ir.cpp50
-rw-r--r--source/slangc/main.cpp1
15 files changed, 162 insertions, 25 deletions
diff --git a/source/slang-rt/slang-rt.cpp b/source/slang-rt/slang-rt.cpp
index 94699dfa0..49d4f2c9a 100644
--- a/source/slang-rt/slang-rt.cpp
+++ b/source/slang-rt/slang-rt.cpp
@@ -25,7 +25,7 @@ extern "C"
ComPtr<ISlangSharedLibrary> lib;
if (!slangRT_loadedLibraries.TryGetValue(modulePath, lib))
{
- if (DefaultSharedLibraryLoader::getSingleton()->loadPlatformSharedLibrary(
+ if (DefaultSharedLibraryLoader::getSingleton()->loadSharedLibrary(
modulePath.getBuffer(), lib.writeRef()) != SLANG_OK)
{
_slang_rt_abort("Failed to load DLL \"" + modulePath + "\"");
@@ -36,7 +36,7 @@ extern "C"
}
SLANG_RT_API void* SLANG_MCALL
- _slang_rt_load_dll_func(void* moduleHandle, Slang::String funcName)
+ _slang_rt_load_dll_func(void* moduleHandle, Slang::String funcName, uint32_t argSize)
{
if (moduleHandle == nullptr)
{
@@ -46,6 +46,13 @@ extern "C"
auto funcPtr = lib->findFuncByName(funcName.getBuffer());
if (!funcPtr)
{
+ // If failed, try stdcall mangled name.
+ StringBuilder sb;
+ sb << "_" << funcName << "@" << argSize;
+ funcPtr = lib->findFuncByName(sb.ToString().getBuffer());
+ }
+ if (!funcPtr)
+ {
_slang_rt_abort("Cannot find function \"" + funcName + "\" in loaded library.");
}
return (void*)funcPtr;
diff --git a/source/slang-rt/slang-rt.h b/source/slang-rt/slang-rt.h
index 3941b3acc..69d8a875b 100644
--- a/source/slang-rt/slang-rt.h
+++ b/source/slang-rt/slang-rt.h
@@ -26,7 +26,7 @@ extern "C"
SLANG_RT_API void SLANG_MCALL _slang_rt_abort(Slang::String errorMessage);
SLANG_RT_API void* SLANG_MCALL _slang_rt_load_dll(Slang::String modulePath);
SLANG_RT_API void* SLANG_MCALL
- _slang_rt_load_dll_func(void* moduleHandle, Slang::String modulePath);
+ _slang_rt_load_dll_func(void* moduleHandle, Slang::String modulePath, uint32_t argSize);
}
#endif
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index 226e29764..e98c8c6f3 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -3378,16 +3378,25 @@ void CLikeSourceEmitter::ensureInstOperandsRec(ComputeEmitActionsContext* ctx, I
auto requiredLevel = EmitAction::Definition;
switch (inst->getOp())
{
- case kIROp_InterfaceType:
- requiredLevel = EmitAction::ForwardDeclaration;
- break;
- case kIROp_COMWitnessDecoration:
+ case kIROp_NativePtrType:
requiredLevel = EmitAction::ForwardDeclaration;
break;
default:
break;
}
+ if (auto comWitnessDecoration = as<IRCOMWitnessDecoration>(inst))
+ {
+ // A COMWitnessDecoration marks the interface inheritance of a class.
+ // We need to make sure the implemented interface is emited before the class.
+ // The witness table itself doesn't matter.
+ if (auto witnessTable = as<IRWitnessTable>(comWitnessDecoration->getWitnessTable()))
+ {
+ ensureInstOperand(ctx, witnessTable->getConformanceType(), requiredLevel);
+ }
+ requiredLevel = EmitAction::ForwardDeclaration;
+ }
+
for(UInt ii = 0; ii < operandCount; ++ii)
{
// TODO: there are some special cases we can add here,
@@ -3415,13 +3424,26 @@ void CLikeSourceEmitter::ensureGlobalInst(ComputeEmitActionsContext* ctx, IRInst
{
case kIROp_Generic:
return;
-
+ case kIROp_ThisType:
+ return;
default:
break;
}
if (as<IRBasicType>(inst))
return;
+ // Certain inst ops will always emit as definition.
+ switch (inst->getOp())
+ {
+ case kIROp_NativePtrType:
+ // Pointer type will have their value type emited as forward declaration,
+ // but the pointer type itself should be considered emitted as definition.
+ requiredLevel = EmitAction::Level::Definition;
+ break;
+ default:
+ break;
+ }
+
// Have we already processed this instruction?
EmitAction::Level existingLevel;
if(ctx->mapInstToLevel.TryGetValue(inst, existingLevel))
@@ -3457,7 +3479,9 @@ void CLikeSourceEmitter::ensureGlobalInst(ComputeEmitActionsContext* ctx, IRInst
switch (inst->getOp())
{
case kIROp_InterfaceRequirementEntry:
+ {
return;
+ }
default:
break;
@@ -3496,6 +3520,16 @@ void CLikeSourceEmitter::emitForwardDeclaration(IRInst* inst)
m_writer->emit(getName(inst));
m_writer->emit(";\n");
break;
+ case kIROp_InterfaceType:
+ {
+ if (inst->findDecoration<IRComInterfaceDecoration>())
+ {
+ m_writer->emit("struct ");
+ m_writer->emit(getName(inst));
+ m_writer->emit(";\n");
+ }
+ break;
+ }
default:
SLANG_UNREACHABLE("emit forward declaration");
}
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 3cfe4d8d4..345b6548a 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -1775,7 +1775,7 @@ void CPPSourceEmitter::emitComInterface(IRInterfaceType* interfaceType)
for (UInt i = 0; i < interfaceType->getOperandCount(); i++)
{
auto entry = as<IRInterfaceRequirementEntry>(interfaceType->getOperand(i));
- if (auto witnessTableType = as<IRWitnessTableType>(entry->getRequirementVal()))
+ if (auto witnessTableType = as<IRWitnessTableTypeBase>(entry->getRequirementVal()))
{
if (isFirst)
{
@@ -2931,6 +2931,7 @@ void CPPSourceEmitter::_emitForwardDeclarations(const List<EmitAction>& actions)
{
case kIROp_Func:
case kIROp_StructType:
+ case kIROp_InterfaceType:
emitForwardDeclaration(action.inst);
break;
default:
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 4cbfa97ab..6e78c82dc 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -218,7 +218,7 @@ Result linkAndOptimizeIR(
case CodeGenTarget::HostCPPSource:
{
lowerComInterfaces(irModule, artifactDesc.style, sink);
- generateDllImportFuncs(irModule, sink);
+ generateDllImportFuncs(codeGenContext->getTargetReq(), irModule, sink);
generateDllExportFuncs(irModule, sink);
break;
}
diff --git a/source/slang/slang-ir-com-interface.cpp b/source/slang/slang-ir-com-interface.cpp
index d9d54d9d2..3e52054cd 100644
--- a/source/slang/slang-ir-com-interface.cpp
+++ b/source/slang/slang-ir-com-interface.cpp
@@ -16,6 +16,8 @@ static bool _canReplace(IRUse* use)
case kIROp_WitnessTableType:
case kIROp_RTTIPointerType:
case kIROp_RTTIHandleType:
+ case kIROp_ComPtrType:
+ case kIROp_NativePtrType:
{
// Don't replace
return false;
@@ -25,7 +27,6 @@ static bool _canReplace(IRUse* use)
// Appears replacable.
break;
}
- case kIROp_ComPtrType:
case kIROp_PtrType:
{
// We can have ** and ComPtr<T>*.
@@ -98,7 +99,7 @@ void lowerComInterfaces(IRModule* module, ArtifactStyle artifactStyle, Diagnosti
// so has to be a raw pointer
IRType* result = (artifactStyle == ArtifactStyle::Host) ?
static_cast<IRType*>(builder.getComPtrType(comIntf)) :
- static_cast<IRType*>(builder.getPtrType(comIntf));
+ static_cast<IRType*>(builder.getNativePtrType(comIntf));
// Go through replacing all of the replacable uses
for (auto use : uses)
diff --git a/source/slang/slang-ir-dll-import.cpp b/source/slang/slang-ir-dll-import.cpp
index 01e1241ff..bfd384f70 100644
--- a/source/slang/slang-ir-dll-import.cpp
+++ b/source/slang/slang-ir-dll-import.cpp
@@ -4,6 +4,7 @@
#include "slang-ir.h"
#include "slang-ir-insts.h"
#include "slang-ir-marshal-native-call.h"
+#include "slang-ir-layout.h"
namespace Slang
{
@@ -12,6 +13,7 @@ struct DllImportContext
{
IRModule* module;
DiagnosticSink* diagnosticSink;
+ TargetRequest* targetReq;
SharedIRBuilder sharedBuilder;
@@ -56,12 +58,13 @@ struct DllImportContext
builder.setInsertInto(module->getModuleInst());
IRType* stringType = builder.getStringType();
- IRType* paramTypes[] = {builder.getPtrType(builder.getVoidType()), stringType};
+ IRType* uintType = builder.getUIntType();
+ IRType* paramTypes[] = {builder.getPtrType(builder.getVoidType()), stringType, uintType };
loadFuncPtrFunc = createBuiltinIntrinsicFunc(
- 2,
+ 3,
paramTypes,
builder.getPtrType(builder.getVoidType()),
- UnownedStringSlice("_slang_rt_load_dll_func($0, $1)"));
+ UnownedStringSlice("_slang_rt_load_dll_func($0, $1, $2)"));
}
return loadFuncPtrFunc;
}
@@ -84,6 +87,17 @@ struct DllImportContext
return stringGetBufferFunc;
}
+ uint32_t getStdCallArgumentSize(IRFunc* func)
+ {
+ uint32_t result = 0;
+ for (auto param : func->getParams())
+ {
+ IRSizeAndAlignment sizeAndAlignment;
+ getNaturalSizeAndAlignment(targetReq, param->getDataType(), &sizeAndAlignment);
+ result += (uint32_t)align(sizeAndAlignment.size, 4);
+ }
+ return result;
+ }
void processFunc(IRFunc* func, IRDllImportDecoration* dllImportDecoration)
{
@@ -136,10 +150,11 @@ struct DllImportContext
getLoadDllFunc(),
builder.getStringValue(dllImportDecoration->getLibraryName()));
}
+ auto argumentSize = builder.getIntValue(builder.getUIntType(), getStdCallArgumentSize(func));
IRInst* loadDllFuncArgs[] = {
- modulePtr, builder.getStringValue(dllImportDecoration->getFunctionName())};
+ modulePtr, builder.getStringValue(dllImportDecoration->getFunctionName()), argumentSize};
auto loadedNativeFuncPtr = builder.emitCallInst(
- builder.getPtrType(builder.getVoidType()), getLoadFuncPtrFunc(), 2, loadDllFuncArgs);
+ builder.getPtrType(builder.getVoidType()), getLoadFuncPtrFunc(), 3, loadDllFuncArgs);
builder.emitStore(
funcPtr, builder.emitBitCast(nativeType, loadedNativeFuncPtr));
builder.emitBranch(afterBlock);
@@ -175,10 +190,11 @@ struct DllImportContext
}
};
-void generateDllImportFuncs(IRModule* module, DiagnosticSink* sink)
+void generateDllImportFuncs(TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink)
{
DllImportContext context;
context.module = module;
+ context.targetReq = targetReq;
context.diagnosticSink = sink;
context.sharedBuilder.init(module);
return context.processModule();
diff --git a/source/slang/slang-ir-dll-import.h b/source/slang/slang-ir-dll-import.h
index d2dc1a9a3..8ea97527b 100644
--- a/source/slang/slang-ir-dll-import.h
+++ b/source/slang/slang-ir-dll-import.h
@@ -5,6 +5,7 @@ namespace Slang
{
struct IRModule;
class DiagnosticSink;
+ class TargetRequest;
/// Generate implementations for functions marked as [DllImport].
- void generateDllImportFuncs(IRModule* module, DiagnosticSink* sink);
+ void generateDllImportFuncs(TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink);
}
diff --git a/source/slang/slang-ir-generics-lowering-context.cpp b/source/slang/slang-ir-generics-lowering-context.cpp
index fbe298d3f..48178340d 100644
--- a/source/slang/slang-ir-generics-lowering-context.cpp
+++ b/source/slang/slang-ir-generics-lowering-context.cpp
@@ -45,9 +45,7 @@ namespace Slang
return true;
}
- // TODO(JS): Perhaps it should do IRPtrTypeBase, or some more expansive set of 'PtrType's
- // but for now test for PtrType
- if (auto ptrType = as<IRPtrType>(type))
+ if (auto ptrType = as<IRNativePtrType>(type))
{
auto valueType = ptrType->getValueType();
return valueType->findDecoration<IRComInterfaceDecoration>() != nullptr;
diff --git a/source/slang/slang-ir-layout.cpp b/source/slang/slang-ir-layout.cpp
index cbf0a6e61..0e4ccc1fe 100644
--- a/source/slang/slang-ir-layout.cpp
+++ b/source/slang/slang-ir-layout.cpp
@@ -256,6 +256,19 @@ static Result _calcNaturalSizeAndAlignment(
outSizeAndAlignment);
}
break;
+ case kIROp_OutType:
+ case kIROp_InOutType:
+ case kIROp_RefType:
+ case kIROp_RawPointerType:
+ case kIROp_PtrType:
+ case kIROp_NativePtrType:
+ case kIROp_ComPtrType:
+ case kIROp_NativeStringType:
+ {
+ *outSizeAndAlignment = IRSizeAndAlignment(sizeof(void*), sizeof(void*));
+ return SLANG_OK;
+ }
+ break;
default:
break;
}
diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp
index c95f6976c..6b8150605 100644
--- a/source/slang/slang-ir-lower-generics.cpp
+++ b/source/slang/slang-ir-lower-generics.cpp
@@ -55,6 +55,9 @@ namespace Slang
switch (inst->getOp())
{
case kIROp_WitnessTableIDType:
+ if (isComInterfaceType((IRType*)inst->getOperand(0)))
+ continue;
+ // fall through
case kIROp_RTTIHandleType:
{
IRBuilder builder(sharedContext->sharedBuilderStorage);
diff --git a/source/slang/slang-ir-marshal-native-call.cpp b/source/slang/slang-ir-marshal-native-call.cpp
index 8a97bfd3e..e4c202798 100644
--- a/source/slang/slang-ir-marshal-native-call.cpp
+++ b/source/slang/slang-ir-marshal-native-call.cpp
@@ -16,6 +16,10 @@ namespace Slang
return builder.getNativePtrType(type);
case kIROp_ComPtrType:
return builder.getNativePtrType((IRType*)as<IRComPtrType>(type)->getOperand(0));
+ case kIROp_InOutType:
+ case kIROp_RefType:
+ case kIROp_OutType:
+ return builder.getPtrType(getNativeType(builder, (IRType*)type->getOperand(0)));
default:
return type;
}
@@ -72,6 +76,7 @@ namespace Slang
{
case kIROp_InOutType:
case kIROp_RefType:
+ case kIROp_OutType:
return marshalRefManagedValueToNativeValue(
builder, originalArg, args);
case kIROp_StringType:
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index 47c6621f3..aea425a9b 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -1306,8 +1306,17 @@ SIMPLE_IR_PARENT_TYPE(OutTypeBase, PtrTypeBase)
SIMPLE_IR_TYPE(OutType, OutTypeBase)
SIMPLE_IR_TYPE(InOutType, OutTypeBase)
-SIMPLE_IR_TYPE(ComPtrType, Type)
-SIMPLE_IR_TYPE(NativePtrType, Type)
+struct IRComPtrType : public IRType
+{
+ IR_LEAF_ISA(ComPtrType);
+ IRType* getValueType() { return (IRType*)getOperand(0); }
+};
+
+struct IRNativePtrType : public IRType
+{
+ IR_LEAF_ISA(NativePtrType);
+ IRType* getValueType() { return (IRType*)getOperand(0); }
+};
struct IRPseudoPtrType : public IRPtrTypeBase
{
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index 1f3da064a..1285afca8 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -1185,6 +1185,31 @@ static void addLinkageDecoration(
addLinkageDecoration(context, inst, decl, mangledName.getUnownedSlice());
}
+bool shouldDeclBeTreatedAsInterfaceRequirement(Decl* requirementDecl)
+{
+ if (auto funcDecl = as<CallableDecl>(requirementDecl))
+ {
+ }
+ else if (auto propertyDecl = as<PropertyDecl>(requirementDecl))
+ {
+ }
+ else if (auto assocTypeDecl = as<AssocTypeDecl>(requirementDecl))
+ {
+ }
+ else if (auto typeConstraint = as<TypeConstraintDecl>(requirementDecl))
+ {
+ }
+ else if (auto genericDecl = as<GenericDecl>(requirementDecl))
+ {
+ return shouldDeclBeTreatedAsInterfaceRequirement(genericDecl->inner);
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+}
+
IRStructKey* getInterfaceRequirementKey(
IRGenContext* context,
Decl* requirementDecl)
@@ -1195,6 +1220,12 @@ IRStructKey* getInterfaceRequirementKey(
// decl as the requirement key.
if (auto genericDecl = as<GenericDecl>(requirementDecl))
return getInterfaceRequirementKey(context, genericDecl->inner);
+
+ // Only specific types of decls are treated as requirements, e.g. methods and asssociated types.
+ // Other types of decls are allowed but not regarded as a requirement.
+ if (!shouldDeclBeTreatedAsInterfaceRequirement(requirementDecl))
+ return nullptr;
+
IRStructKey* requirementKey = nullptr;
if(context->shared->interfaceRequirementKeys.TryGetValue(requirementDecl, requirementKey))
{
@@ -1356,6 +1387,9 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower
//
auto irReqKey = getInterfaceRequirementKey(context, reqDeclRef.getDecl());
+ if (!irReqKey)
+ continue;
+
// We expect that each of the witness tables in `caseWitnessTables`
// will have an entry to match these keys. However, we may not
// have a concrete `IRWitnessTable` for each of the case types, either
@@ -5866,6 +5900,8 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
auto satisfyingWitness = entry.Value;
auto irRequirementKey = getInterfaceRequirementKey(requiredMemberDecl);
+ if (!irRequirementKey) continue;
+
IRInst* irSatisfyingVal = nullptr;
switch(satisfyingWitness.getFlavor())
@@ -6613,6 +6649,9 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
UInt operandCount = 0;
for (auto requirementDecl : decl->members)
{
+ if (!shouldDeclBeTreatedAsInterfaceRequirement(requirementDecl))
+ continue;
+
operandCount++;
// As a special case, any type constraints placed
// on an associated type will *also* need to be turned
@@ -6647,8 +6686,10 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
for (auto requirementDecl : decl->members)
{
+ auto requirementKey = getInterfaceRequirementKey(requirementDecl);
+ if (!requirementKey) continue;
auto entry = subBuilder->createInterfaceRequirementEntry(
- getInterfaceRequirementKey(requirementDecl),
+ requirementKey,
nullptr);
if (auto inheritance = as<InheritanceDecl>(requirementDecl))
{
@@ -8551,6 +8592,13 @@ static void ensureAllDeclsRec(
ensureAllDeclsRec(context, memberDecl);
}
}
+ else if (auto namespaceDecl = as<NamespaceDecl>(decl))
+ {
+ for (auto memberDecl : namespaceDecl->members)
+ {
+ ensureAllDeclsRec(context, memberDecl);
+ }
+ }
else if (auto genericDecl = as<GenericDecl>(decl))
{
ensureAllDeclsRec(context, genericDecl->inner);
diff --git a/source/slangc/main.cpp b/source/slangc/main.cpp
index 887eca77a..2870a5a3c 100644
--- a/source/slangc/main.cpp
+++ b/source/slangc/main.cpp
@@ -89,6 +89,7 @@ SLANG_TEST_TOOL_API SlangResult innerMain(StdWriters* stdWriters, slang::IGlobal
}
SlangCompileRequest* compileRequest = spCreateCompileRequest(session);
+ compileRequest->addSearchPath(Path::getParentDirectory(Path::getExecutablePath()).getBuffer());
SlangResult res = _compile(compileRequest, argc, argv);
// Now that we are done, clean up after ourselves
spDestroyCompileRequest(compileRequest);