summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-08-03 17:10:46 -0400
committerGitHub <noreply@github.com>2022-08-03 17:10:46 -0400
commite43ef82e288afe486f45ef2736d378e88f40cc90 (patch)
tree356841a992263d6a5d03e9d6704868c2cc12190c /source
parente81a5fe56f3177fc3c7040e2320ae083e3746eb7 (diff)
Improvements around Artifact (#2346)
* #include an absolute path didn't work - because paths were taken to always be relative. * WIP with hierarchical enums. * Some small fixes and improvements around artifact desc related types. * Improvements around hierarchical enum. * Fixes to get Artifact types refactor to be able to execute tests. * Attempt to better categorize PTX. * Work around for potentially unused function warning. * Typo fix. * Simplify Artifact header. * Small improvements around Artifact kind/payload/style. * Added IDestroyable/ICastable * Add IArtifactList. * First impl of IArtifactUtil. * Use the ICastable interface for IArtifactRepresentation. * Added IArtifactRepresentation & IArtifactAssociated. * Add SLANG_OVERRIDE to avoid gcc/clang warning. * Fix calling convention issue on win32. * Fix missing SLANG_OVERRIDE.
Diffstat (limited to 'source')
-rw-r--r--source/compiler-core/slang-artifact-info.cpp326
-rw-r--r--source/compiler-core/slang-artifact-info.h76
-rw-r--r--source/compiler-core/slang-artifact-util.cpp63
-rw-r--r--source/compiler-core/slang-artifact-util.h65
-rw-r--r--source/compiler-core/slang-artifact.cpp425
-rw-r--r--source/compiler-core/slang-artifact.h296
-rw-r--r--source/core/slang-destroyable.h41
-rw-r--r--source/slang/slang-compiler.cpp4
-rw-r--r--source/slang/slang-ir-link.cpp2
-rw-r--r--source/slang/slang-module-library.cpp22
-rw-r--r--source/slang/slang-module-library.h10
-rw-r--r--source/slang/slang-options.cpp6
-rw-r--r--source/slang/slang-parameter-binding.cpp2
-rw-r--r--source/slang/slang-type-layout.cpp2
-rw-r--r--source/slang/slang.cpp6
15 files changed, 993 insertions, 353 deletions
diff --git a/source/compiler-core/slang-artifact-info.cpp b/source/compiler-core/slang-artifact-info.cpp
index b67adb666..f76bf45f0 100644
--- a/source/compiler-core/slang-artifact-info.cpp
+++ b/source/compiler-core/slang-artifact-info.cpp
@@ -6,86 +6,8 @@
namespace Slang {
-static ArtifactPayloadInfo::Lookup _makePayloadInfoLookup()
-{
- ArtifactPayloadInfo::Lookup values;
- memset(&values, 0, sizeof(values));
-
-
- typedef ArtifactPayload Payload;
- typedef ArtifactPayloadInfo::Flag Flag;
- typedef ArtifactPayloadInfo::Flags Flags;
- typedef ArtifactPayloadInfo::Flavor Flavor;
-
- struct Info
- {
- Payload payload;
- Flavor flavor;
- Flags flags;
- };
-
- const Info infos[] =
- {
- {Payload::None, Flavor::None, 0},
- {Payload::Unknown, Flavor::Unknown, 0},
-
- // It seems as if DXBC is potentially linkable from
- // https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-keywords#export
-
- // We can't *actually* link PTX or SPIR-V currently but it is in principal possible
- // so let's say we accept for now
-
- {Payload::DXIL, Flavor::Binary, Flag::IsGpuNative | Flag::IsLinkable},
- {Payload::DXBC, Flavor::Binary, Flag::IsGpuNative | Flag::IsLinkable},
- {Payload::SPIRV, Flavor::Binary, Flag::IsGpuNative | Flag::IsLinkable },
- {Payload::PTX, Flavor::Binary, Flag::IsGpuNative | Flag::IsLinkable },
-
- {Payload::DXILAssembly, Flavor::Assembly, 0},
- {Payload::DXBCAssembly, Flavor::Assembly, 0},
- {Payload::SPIRVAssembly, Flavor::Assembly, 0},
- {Payload::PTXAssembly, Flavor::Assembly, 0},
-
- {Payload::HostCPU, Flavor::Binary, Flag::IsCpuNative | Flag::IsLinkable},
-
- // Do we want some other Flavor for these?
- {Payload::SlangIR, Flavor::Binary, Flag::IsLinkable},
- {Payload::LLVMIR, Flavor::Binary, 0},
- {Payload::SlangAST, Flavor::Binary, 0},
-
- {Payload::X86, Flavor::Binary, Flag::IsCpuNative | Flag::IsLinkable},
- {Payload::X86_64, Flavor::Binary, Flag::IsCpuNative | Flag::IsLinkable},
- {Payload::AARCH, Flavor::Binary, Flag::IsCpuNative | Flag::IsLinkable},
- {Payload::AARCH64, Flavor::Binary, Flag::IsCpuNative | Flag::IsLinkable},
-
- {Payload::HLSL, Flavor::Source, 0},
- {Payload::GLSL, Flavor::Source, 0},
- {Payload::CPP, Flavor::Source, 0},
- {Payload::C, Flavor::Source, 0},
- {Payload::CUDA, Flavor::Source, 0},
- {Payload::Slang, Flavor::Source, 0},
-
- {Payload::DebugInfo, Flavor::Unknown, 0},
-
- {Payload::Diagnostics, Flavor::Unknown, 0},
-
- {Payload::Zip, Flavor::Container, 0},
- };
-
- for (auto info : infos)
- {
- auto& v = values.values[Index(info.payload)];
- v.flavor = info.flavor;
- v.flags = info.flags;
- }
-
- return values;
-}
-
-/* static */const ArtifactPayloadInfo::Lookup ArtifactPayloadInfo::Lookup::g_values = _makePayloadInfoLookup();
-
/* !!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactInfoUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
namespace { // anonymous
struct KindExtension
{
@@ -95,7 +17,7 @@ struct KindExtension
} // anonymous
#define SLANG_KIND_EXTENSION(kind, ext) \
- { ArtifactKind::kind, UnownedStringSlice::fromLiteral(ext) },
+ { ArtifactKind::kind, toSlice(ext) },
static const KindExtension g_cpuKindExts[] =
{
@@ -120,6 +42,41 @@ static const KindExtension g_cpuKindExts[] =
#endif
};
+/* static */ bool ArtifactInfoUtil::isCpuBinary(const ArtifactDesc& desc)
+{
+ return isDerivedFrom(desc.kind, ArtifactKind::BinaryLike) && isDerivedFrom(desc.payload, ArtifactPayload::CPULike);
+}
+
+/* static */bool ArtifactInfoUtil::isText(const ArtifactDesc& desc)
+{
+ // If it's derived from text...
+ if (isDerivedFrom(desc.kind, ArtifactKind::Text))
+ {
+ return true;
+ }
+
+ // Special case PTX...
+ if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike))
+ {
+ return desc.payload == ArtifactPayload::PTX;
+ }
+
+ // Not text
+ return false;
+}
+
+/* static */bool ArtifactInfoUtil::isGpuUsable(const ArtifactDesc& desc)
+{
+ if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike))
+ {
+ return isDerivedFrom(desc.payload, ArtifactPayload::KernelLike);
+ }
+
+ // PTX is a kind of special case, it's an 'assembly' (low level text represention) that can be passed
+ // to CUDA runtime
+ return desc.kind == ArtifactKind::Assembly && desc.payload == ArtifactPayload::PTX;
+}
+
/* static */bool ArtifactInfoUtil::isKindBinaryLinkable(Kind kind)
{
switch (kind)
@@ -134,71 +91,53 @@ static const KindExtension g_cpuKindExts[] =
return false;
}
-/* static */bool ArtifactInfoUtil::isBinaryLinkable(const ArtifactDesc& desc)
+/* static */bool ArtifactInfoUtil::isLinkable(const ArtifactDesc& desc)
{
- return isKindBinaryLinkable(desc.kind) &&
- getInfo(desc.payload).isSet(ArtifactPayloadInfo::Flag::IsLinkable);
-}
+ if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike))
+ {
+ if (isDerivedFrom(desc.payload, ArtifactPayload::KernelLike))
+ {
+ // It seems as if DXBC is potentially linkable from
+ // https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-keywords#export
-/* static */bool ArtifactInfoUtil::isPayloadCpuBinary(Payload payload)
-{
- auto info = getInfo(payload);
- return info.isSet(ArtifactPayloadInfo::Flag::IsCpuNative) && info.flavor == ArtifactPayloadInfo::Flavor::Binary;
-}
+ // We can't *actually* link PTX or SPIR-V currently but it is in principal possible
+ // so let's say we accept for now
-/* static */bool ArtifactInfoUtil::isPayloadGpuBinary(Payload payload)
-{
- auto info = getInfo(payload);
- return info.isSet(ArtifactPayloadInfo::Flag::IsGpuNative) && info.flavor == ArtifactPayloadInfo::Flavor::Binary;
-}
+ return true;
+ }
+ else if (isDerivedFrom(desc.payload, ArtifactPayload::CPULike))
+ {
+ // If kind is exe or shared library, linking will arguably not work
+ if (desc.kind == ArtifactKind::SharedLibrary ||
+ desc.kind == ArtifactKind::Executable)
+ {
+ return false;
+ }
-/* static */bool ArtifactInfoUtil::isPayloadCpuTarget(Payload payload)
-{
- return isPayloadCpuBinary(payload) ||
- (payload == Payload::C || payload == Payload::CPP);
+ return true;
+ }
+ else if (isDerivedFrom(desc.payload, ArtifactPayload::GeneralIR))
+ {
+ // We'll *assume* IR is linkable
+ return true;
+ }
+ }
+ return false;
}
-/* static */UnownedStringSlice ArtifactInfoUtil::getDefaultExtensionForPayload(Payload payload)
+/* static */bool ArtifactInfoUtil::isCpuLikeTarget(const ArtifactDesc& desc)
{
- switch (payload)
- {
- case Payload::None: return UnownedStringSlice();
- case Payload::Unknown: return UnownedStringSlice::fromLiteral("unknown");
-
- case Payload::DXIL: return UnownedStringSlice::fromLiteral("dxil");
- case Payload::DXBC: return UnownedStringSlice::fromLiteral("dxbc");
- case Payload::SPIRV: return UnownedStringSlice::fromLiteral("spirv");
-
- case Payload::PTX: return UnownedStringSlice::fromLiteral("ptx");
-
- case Payload::X86:
- case Payload::X86_64:
- case Payload::AARCH:
- case Payload::AARCH64:
- case Payload::HostCPU:
+ if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike))
{
- return UnownedStringSlice();
+ return isDerivedFrom(desc.payload, ArtifactPayload::CPULike);
}
-
- case Payload::SlangIR: return UnownedStringSlice::fromLiteral("slang-ir");
- case Payload::LLVMIR: return UnownedStringSlice::fromLiteral("llvm-ir");
-
- case Payload::HLSL: return UnownedStringSlice::fromLiteral("hlsl");
- case Payload::GLSL: return UnownedStringSlice::fromLiteral("glsl");
-
- case Payload::CPP: return UnownedStringSlice::fromLiteral("cpp");
- case Payload::C: return UnownedStringSlice::fromLiteral("c");
-
- case Payload::CUDA: return UnownedStringSlice::fromLiteral("cu");
-
- case Payload::Slang: return UnownedStringSlice::fromLiteral("slang");
-
- case Payload::Zip: return UnownedStringSlice::fromLiteral("zip");
-
- default: break;
+ else if (isDerivedFrom(desc.kind, ArtifactKind::Source))
+ {
+ // We'll assume C/C++ are targetting CPU, although that is perhaps somewhat arguable.
+ return desc.payload == Payload::C || desc.payload == Payload::Cpp;
}
- SLANG_UNEXPECTED("Unknown content type");
+ return false;
}
/* static */ArtifactDesc ArtifactInfoUtil::getDescFromExtension(const UnownedStringSlice& slice)
@@ -209,6 +148,32 @@ static const KindExtension g_cpuKindExts[] =
return ArtifactDesc::make(ArtifactKind::Library, ArtifactPayload::SlangIR);
}
+ // Metal
+ // https://developer.apple.com/documentation/metal/shader_libraries/building_a_library_with_metal_s_command-line_tools
+ if (slice == toSlice("air"))
+ {
+ return ArtifactDesc::make(ArtifactKind::ObjectCode, ArtifactPayload::MetalAIR);
+ }
+ else if (slice == toSlice("metallib") || slice == toSlice("metalar"))
+ {
+ return ArtifactDesc::make(ArtifactKind::Library, ArtifactPayload::MetalAIR);
+ }
+
+ if (slice == toSlice("zip"))
+ {
+ return ArtifactDesc::make(ArtifactKind::Zip, ArtifactPayload::Unknown);
+ }
+ else if (slice == toSlice("riff"))
+ {
+ return ArtifactDesc::make(ArtifactKind::Riff, ArtifactPayload::Unknown);
+ }
+
+ if (slice == toSlice("asm"))
+ {
+ // We'll assume asm means current CPU assembler..
+ return ArtifactDesc::make(ArtifactKind::Assembly, ArtifactPayload::HostCPU);
+ }
+
for (const auto& kindExt : g_cpuKindExts)
{
if (slice == kindExt.ext)
@@ -241,16 +206,105 @@ static const KindExtension g_cpuKindExts[] =
return UnownedStringSlice();
}
+UnownedStringSlice ArtifactInfoUtil::getAssemblyExtensionForPayload(ArtifactPayload payload)
+{
+ switch (payload)
+ {
+ case ArtifactPayload::DXIL: return toSlice("dxil-asm");
+ case ArtifactPayload::DXBC: return toSlice("dxbc-asm");
+ case ArtifactPayload::SPIRV: return toSlice("spv-asm");
+ case ArtifactPayload::PTX: return toSlice("ptx");
+
+ // TODO(JS):
+ // Not sure what to do for metal - does it have an assembly name?
+
+ default: break;
+ }
+
+ // We'll just use asm for all CPU assembly type
+ if (isDerivedFrom(payload, ArtifactPayload::CPULike))
+ {
+ return toSlice("asm");
+ }
+
+ if (isDerivedFrom(payload, ArtifactPayload::GeneralIR))
+ {
+ switch (payload)
+ {
+ case ArtifactPayload::SlangIR: return toSlice("slang-ir-asm");
+ case ArtifactPayload::LLVMIR: return toSlice("llvm-ir-asm");
+ break;
+ }
+ }
+
+ return UnownedStringSlice();
+}
+
UnownedStringSlice ArtifactInfoUtil::getDefaultExtension(const ArtifactDesc& desc)
{
- if (ArtifactInfoUtil::isPayloadCpuBinary(desc.payload))
+ switch (desc.kind)
+ {
+ case ArtifactKind::Zip: return toSlice("zip");
+ case ArtifactKind::Riff: return toSlice("riff");
+ case ArtifactKind::Assembly:
+ {
+ return getAssemblyExtensionForPayload(desc.payload);
+ }
+ case ArtifactKind::Source:
+ {
+ switch (desc.payload)
+ {
+ case Payload::HLSL: return toSlice("hlsl");
+ case Payload::GLSL: return toSlice("glsl");
+
+ case Payload::Cpp: return toSlice("cpp");
+ case Payload::C: return toSlice("c");
+
+ case Payload::Metal: return toSlice("metal");
+
+ case Payload::CUDA: return toSlice("cu");
+
+ case Payload::Slang: return toSlice("slang");
+ default: break;
+ }
+ }
+ default: break;
+ }
+
+ if (ArtifactInfoUtil::isCpuLikeTarget(desc))
{
return getCpuExtensionForKind(desc.kind);
}
- else
+
+ if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike))
{
- return getDefaultExtensionForPayload(desc.payload);
+ switch (desc.payload)
+ {
+ case Payload::None: return UnownedStringSlice();
+ case Payload::Unknown: return toSlice("unknown");
+
+ case Payload::DXIL: return toSlice("dxil");
+ case Payload::DXBC: return toSlice("dxbc");
+ case Payload::SPIRV: return toSlice("spv");
+
+ case Payload::PTX: return toSlice("ptx");
+
+ case Payload::LLVMIR: return toSlice("llvm-ir");
+
+ case Payload::SlangIR:
+ {
+ return (desc.kind == ArtifactKind::Library) ? toSlice("slang-module") : toSlice("slang-ir");
+ }
+ case Payload::MetalAIR:
+ {
+ // https://developer.apple.com/documentation/metal/shader_libraries/building_a_library_with_metal_s_command-line_tools
+ return (desc.kind == ArtifactKind::Library) ? toSlice("metallib") : toSlice("air");
+ }
+ default: break;
+ }
}
+
+ return UnownedStringSlice();
}
/* static */String ArtifactInfoUtil::getBaseNameFromPath(const ArtifactDesc& desc, const UnownedStringSlice& path)
diff --git a/source/compiler-core/slang-artifact-info.h b/source/compiler-core/slang-artifact-info.h
index e63349937..393771a6f 100644
--- a/source/compiler-core/slang-artifact-info.h
+++ b/source/compiler-core/slang-artifact-info.h
@@ -7,53 +7,6 @@
namespace Slang
{
-/* We want to centralize information about artifact descs and related types, such that when new types are added they only need
-to be added/altered in one place */
-struct ArtifactPayloadInfo
-{
- typedef ArtifactPayloadInfo This;
- enum class Flavor : uint8_t
- {
- Unknown,
- None,
- Assembly,
- Source,
- Container,
- Binary,
- CountOf,
- };
-
- typedef uint8_t Flags;
- struct Flag
- {
- enum Enum : Flags
- {
- IsCpuNative = 0x01, ///< True if is a CPU native type
- IsGpuNative = 0x02, ///< True if is a GPU native type
- IsLinkable = 0x04, ///< True if in principal is linkable
- };
- };
-
- bool isSet(Flag::Enum flag) const { return (flags & Flags(flag)) != 0; }
- bool isReset(Flag::Enum flag) const { return (flags & Flags(flag)) == 0; }
-
- struct Lookup;
-
- Flags flags;
- Flavor flavor;
-};
-
-struct ArtifactPayloadInfo::Lookup
-{
- void setFlag(ArtifactPayload payload, Flag::Enum flag) { values[Index(payload)].flags |= Flags(flag); }
- void setFlags(ArtifactPayload payload, Flags flags) { values[Index(payload)].flags |= flags; }
-
- This values[Index(ArtifactPayload::CountOf)];
- static const Lookup g_values;
-};
-
-SLANG_FORCE_INLINE ArtifactPayloadInfo getInfo(ArtifactPayload payload) { return ArtifactPayloadInfo::Lookup::g_values.values[Index(payload)]; }
-
struct ArtifactInfoUtil
{
typedef ArtifactPayload Payload;
@@ -62,27 +15,22 @@ struct ArtifactInfoUtil
/// Returns true if the kind is binary linkable
static bool isKindBinaryLinkable(Kind kind);
- /// Returns true if the payload type is CPU
- static bool isPayloadCpuBinary(Payload payload);
- /// Returns true if the payload type is applicable to the GPU
- static bool isPayloadGpuBinary(Payload payload);
-
- /// True if is a CPU target
- static bool isPayloadCpuTarget(Payload payload);
-
/// True if is a CPU target - either
- static bool isCpuTarget(const ArtifactDesc& desc) { return isPayloadCpuTarget(desc.payload); }
-
+ static bool isCpuLikeTarget(const ArtifactDesc& desc);
+
/// True if is a CPU binary
- static bool isCpuBinary(const ArtifactDesc& desc) { return isPayloadCpuBinary(desc.payload); }
- /// True if is a GPU binary
- static bool isGpuBinary(const ArtifactDesc& desc) { return isPayloadGpuBinary(desc.payload); }
+ static bool isCpuBinary(const ArtifactDesc& desc);
+ /// True if is a GPU usable (can be passed to a driver/API and be used
+ static bool isGpuUsable(const ArtifactDesc& desc);
+
+ /// True if the desc holds textual information
+ static bool isText(const ArtifactDesc& desc);
- /// True if artifact appears to be binary linkable
- static bool isBinaryLinkable(const ArtifactDesc& desc);
+ /// Given an assembly type returns it's extension from the payload type
+ static UnownedStringSlice getAssemblyExtensionForPayload(ArtifactPayload payload);
- /// Get the default extension type for a payload type
- static UnownedStringSlice getDefaultExtensionForPayload(Payload payload);
+ /// True if artifact appears to be linkable
+ static bool isLinkable(const ArtifactDesc& desc);
/// Try to determine the desc from just a file extension (passed without .)
static ArtifactDesc getDescFromExtension(const UnownedStringSlice& slice);
diff --git a/source/compiler-core/slang-artifact-util.cpp b/source/compiler-core/slang-artifact-util.cpp
new file mode 100644
index 000000000..3ca10446c
--- /dev/null
+++ b/source/compiler-core/slang-artifact-util.cpp
@@ -0,0 +1,63 @@
+// slang-artifact.cpp
+#include "slang-artifact-util.h"
+
+#include "slang-artifact-info.h"
+
+namespace Slang {
+
+/* static */ArtifactUtilImpl ArtifactUtilImpl::g_singleton;
+
+SlangResult ArtifactUtilImpl::queryInterface(SlangUUID const& uuid, void** outObject)
+{
+ if (auto intf = getInterface(uuid))
+ {
+ *outObject = intf;
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+}
+
+void* ArtifactUtilImpl::getInterface(const Guid& guid)
+{
+ if (guid == ISlangUnknown::getTypeGuid() || guid == IArtifactUtil::getTypeGuid())
+ {
+ return static_cast<IArtifactUtil*>(this);
+ }
+ return nullptr;
+}
+
+
+SlangResult ArtifactUtilImpl::createArtifact(const ArtifactDesc& desc, const char* inName, IArtifact** outArtifact)
+{
+ String name;
+ if (inName)
+ {
+ name = inName;
+ }
+
+ ComPtr<IArtifact> artifact(new Artifact(desc, name));
+
+ *outArtifact = artifact.detach();
+ return SLANG_OK;
+}
+
+SlangResult ArtifactUtilImpl::createArtifactList(IArtifact* parent, IArtifactList** outArtifactList)
+{
+ ComPtr<IArtifactList> artifactList(new ArtifactList(parent));
+ *outArtifactList = artifactList.detach();
+ return SLANG_OK;
+}
+
+ArtifactKind ArtifactUtilImpl::getKindParent(ArtifactKind kind) { return getParent(kind); }
+UnownedStringSlice ArtifactUtilImpl::getKindName(ArtifactKind kind) { return getName(kind); }
+bool ArtifactUtilImpl::isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) { return isDerivedFrom(kind, base); }
+
+ArtifactPayload ArtifactUtilImpl::getPayloadParent(ArtifactPayload payload) { return getParent(payload); }
+UnownedStringSlice ArtifactUtilImpl::getPayloadName(ArtifactPayload payload) { return getName(payload); }
+bool ArtifactUtilImpl::isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) { return isDerivedFrom(payload, base); }
+
+ArtifactStyle ArtifactUtilImpl::getStyleParent(ArtifactStyle style) { return getParent(style); }
+UnownedStringSlice ArtifactUtilImpl::getStyleName(ArtifactStyle style) { return getName(style); }
+bool ArtifactUtilImpl::isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) { return isDerivedFrom(style, base); }
+
+} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-util.h b/source/compiler-core/slang-artifact-util.h
new file mode 100644
index 000000000..2b006fd78
--- /dev/null
+++ b/source/compiler-core/slang-artifact-util.h
@@ -0,0 +1,65 @@
+// slang-artifact-util.h
+#ifndef SLANG_ARTIFACT_UTIL_H
+#define SLANG_ARTIFACT_UTIL_H
+
+#include "slang-artifact.h"
+
+namespace Slang
+{
+
+class IArtifactUtil : public ISlangUnknown
+{
+ SLANG_COM_INTERFACE(0x882b25d7, 0xe300, 0x4b20, { 0xbe, 0xb, 0x26, 0xd2, 0x52, 0x3e, 0x70, 0x20 })
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifact(const ArtifactDesc& desc, const char* name, IArtifact** outArtifact) = 0;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifactList(IArtifact* parent, IArtifactList** outArtifactList) = 0;
+
+ virtual SLANG_NO_THROW ArtifactKind SLANG_MCALL getKindParent(ArtifactKind kind) = 0;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getKindName(ArtifactKind kind) = 0;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) = 0;
+
+ virtual SLANG_NO_THROW ArtifactPayload SLANG_MCALL getPayloadParent(ArtifactPayload payload) = 0;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getPayloadName(ArtifactPayload payload) = 0;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) = 0;
+
+ virtual SLANG_NO_THROW ArtifactStyle SLANG_MCALL getStyleParent(ArtifactStyle style) = 0;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) = 0;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) = 0;
+};
+
+class ArtifactUtilImpl : public IArtifactUtil
+{
+ // ISlangUnknown
+ SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
+
+ // IArtifactInterface
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifact(const ArtifactDesc& desc, const char* name, IArtifact** outArtifact) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifactList(IArtifact* parent, IArtifactList** outArtifactList) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW ArtifactKind SLANG_MCALL getKindParent(ArtifactKind kind) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getKindName(ArtifactKind kind) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW ArtifactPayload SLANG_MCALL getPayloadParent(ArtifactPayload payload) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getPayloadName(ArtifactPayload payload) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW ArtifactStyle SLANG_MCALL getStyleParent(ArtifactStyle style) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) SLANG_OVERRIDE;
+
+ static IArtifactUtil* getSingleton() { return &g_singleton; }
+
+protected:
+ void* getInterface(const Guid& guid);
+
+ static ArtifactUtilImpl g_singleton;
+};
+
+} // namespace Slang
+
+#endif
diff --git a/source/compiler-core/slang-artifact.cpp b/source/compiler-core/slang-artifact.cpp
index bf61763c8..cb77f5140 100644
--- a/source/compiler-core/slang-artifact.cpp
+++ b/source/compiler-core/slang-artifact.cpp
@@ -5,9 +5,236 @@
#include "../core/slang-type-text-util.h"
#include "../core/slang-io.h"
+#include "../core/slang-array-view.h"
namespace Slang {
+namespace { // anonymous
+
+struct HierarchicalEnumEntry
+{
+ Index value;
+ Index parent;
+ const char* name;
+};
+
+static bool _isHierarchicalEnumOk(ConstArrayView<HierarchicalEnumEntry> entries, Count countOf)
+{
+ // All values should be set
+ if (entries.getCount() != countOf)
+ {
+ return false;
+ }
+
+ List<uint8_t> isUsed;
+ isUsed.setCount(countOf);
+ ::memset(isUsed.getBuffer(), 0, countOf);
+
+ for (const auto& entry : entries)
+ {
+ const auto value = entry.value;
+ // Must be in range
+ if (value < 0 || value >= countOf)
+ {
+ return false;
+ }
+
+ if (isUsed[value] != 0)
+ {
+ return false;
+ }
+ // Mark as used
+ isUsed[value]++;
+ }
+
+ // There can't be any gaps
+ for (auto v : isUsed)
+ {
+ if (v == 0)
+ {
+ return false;
+ }
+ }
+
+ // Okay, looks reasonable..
+ return true;
+}
+
+template <typename T>
+struct HierarchicalEnumTable
+{
+ HierarchicalEnumTable(ConstArrayView<HierarchicalEnumEntry> entries)
+ {
+ // Remove warnings around this not being used.
+ {
+ const auto unused = _isHierarchicalEnumOk;
+ SLANG_UNUSED(unused);
+ }
+
+ SLANG_COMPILE_TIME_ASSERT(Index(T::Invalid) < Index(T::Base));
+ SLANG_ASSERT(entries.getCount() == Count(T::CountOf));
+
+ SLANG_ASSERT(_isHierarchicalEnumOk(entries, Count(T::CountOf)));
+
+ ::memset(&m_parents, 0, sizeof(m_parents));
+
+ for (const auto& entry : entries)
+ {
+ const auto value = entry.value;
+ m_parents[value] = T(entry.parent);
+ m_names[value] = UnownedStringSlice(entry.name);
+ }
+
+ // TODO(JS): NOTE! If we wanted to use parent to indicate if a value was *invalid*
+ // we would want the Parent of Base to be Base.
+ //
+ // Base parent should be invalid
+ SLANG_ASSERT(getParent(T::Base) == T::Invalid);
+ // Invalids parent should be invalid
+ SLANG_ASSERT(getParent(T::Invalid) == T::Invalid);
+ }
+
+ T getParent(T kind) const
+ {
+ return (kind >= T::CountOf) ?
+ T::Invalid :
+ m_parents[Index(kind)];
+ }
+ UnownedStringSlice getName(T kind) const
+ {
+ return (kind >= T::CountOf) ?
+ UnownedStringSlice() :
+ m_names[Index(kind)];
+ }
+
+ bool isDerivedFrom(T type, T base) const
+ {
+ if (Index(type) >= Index(T::CountOf))
+ {
+ return false;
+ }
+
+ do
+ {
+ if (type == base)
+ {
+ return true;
+ }
+ type = m_parents[Index(type)];
+ } while (Index(type) > Index(T::Base));
+
+ return false;
+ }
+
+protected:
+ T m_parents[Count(T::CountOf)];
+ UnownedStringSlice m_names[Count(T::CountOf)];
+};
+
+} // anonymous
+
+// Macro utils to create "enum hierarchy" tables
+
+#define SLANG_HIERARCHICAL_ENUM_GET_VALUES(ENUM_TYPE, ENUM_TYPE_MACRO, ENUM_ENTRY_MACRO) \
+static ConstArrayView<HierarchicalEnumEntry> _getEntries##ENUM_TYPE() \
+{ \
+ static const HierarchicalEnumEntry values[] = { ENUM_TYPE_MACRO(ENUM_ENTRY_MACRO) }; \
+ return makeConstArrayView(values); \
+}
+
+#define SLANG_HIERARCHICAL_ENUM(ENUM_TYPE, ENUM_TYPE_MACRO, ENUM_VALUE_MACRO) \
+SLANG_HIERARCHICAL_ENUM_GET_VALUES(ENUM_TYPE, ENUM_TYPE_MACRO, ENUM_VALUE_MACRO) \
+\
+static const HierarchicalEnumTable<ENUM_TYPE> g_table##ENUM_TYPE(_getEntries##ENUM_TYPE()); \
+\
+ENUM_TYPE getParent(ENUM_TYPE kind) { return g_table##ENUM_TYPE.getParent(kind); } \
+UnownedStringSlice getName(ENUM_TYPE kind) { return g_table##ENUM_TYPE.getName(kind); } \
+bool isDerivedFrom(ENUM_TYPE kind, ENUM_TYPE base) { return g_table##ENUM_TYPE.isDerivedFrom(kind, base); }
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactKind !!!!!!!!!!!!!!!!!!!!!!! */
+
+#define SLANG_ARTIFACT_KIND(x) \
+ x(Invalid, Invalid) \
+ x(Base, Invalid) \
+ x(None, Base) \
+ x(Unknown, Base) \
+ x(Container, Base) \
+ x(Zip, Container) \
+ x(Riff, Container) \
+ x(Text, Base) \
+ x(HumanText, Text) \
+ x(Source, Text) \
+ x(Assembly, Text) \
+ x(BinaryLike, Base) \
+ x(ObjectCode, BinaryLike) \
+ x(Library, BinaryLike) \
+ x(Executable, BinaryLike) \
+ x(SharedLibrary, BinaryLike) \
+ x(HostCallable, BinaryLike) \
+ \
+ x(DebugInfo, Base) \
+ x(Diagnostics, Base)
+
+#define SLANG_ARTIFACT_KIND_ENTRY(TYPE, PARENT) { Index(ArtifactKind::TYPE), Index(ArtifactKind::PARENT), #TYPE },
+
+SLANG_HIERARCHICAL_ENUM(ArtifactKind, SLANG_ARTIFACT_KIND, SLANG_ARTIFACT_KIND_ENTRY)
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactPayload !!!!!!!!!!!!!!!!!!!!!!! */
+
+#define SLANG_ARTIFACT_PAYLOAD(x) \
+ x(Invalid, Invalid) \
+ x(Base, Invalid) \
+ x(None, Base) \
+ x(Unknown, Base) \
+ x(Source, Base) \
+ x(C, Source) \
+ x(Cpp, Source) \
+ x(HLSL, Source) \
+ x(GLSL, Source) \
+ x(CUDA, Source) \
+ x(Metal, Source) \
+ x(Slang, Source) \
+ x(KernelLike, Base) \
+ x(DXIL, KernelLike) \
+ x(DXBC, KernelLike) \
+ x(SPIRV, KernelLike) \
+ x(PTX, KernelLike) \
+ x(CuBin, KernelLike) \
+ x(MetalAIR, KernelLike) \
+ x(CPULike, Base) \
+ x(UnknownCPU, CPULike) \
+ x(X86, CPULike) \
+ x(X86_64, CPULike) \
+ x(Aarch, CPULike) \
+ x(Aarch64, CPULike) \
+ x(HostCPU, CPULike) \
+ x(UniversalCPU, CPULike) \
+ x(GeneralIR, Base) \
+ x(SlangIR, GeneralIR) \
+ x(LLVMIR, GeneralIR) \
+ x(AST, Base) \
+ x(SlangAST, AST)
+
+#define SLANG_ARTIFACT_PAYLOAD_ENTRY(TYPE, PARENT) { Index(ArtifactPayload::TYPE), Index(ArtifactPayload::PARENT), #TYPE },
+
+SLANG_HIERARCHICAL_ENUM(ArtifactPayload, SLANG_ARTIFACT_PAYLOAD, SLANG_ARTIFACT_PAYLOAD_ENTRY)
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactStyle !!!!!!!!!!!!!!!!!!!!!!! */
+
+#define SLANG_ARTIFACT_STYLE(x) \
+ x(Invalid, Invalid) \
+ x(Base, Invalid) \
+ x(Unknown, Base) \
+ x(Kernel, Base) \
+ x(Host, Base)
+
+#define SLANG_ARTIFACT_STYLE_ENTRY(TYPE, PARENT) { Index(ArtifactStyle::TYPE), Index(ArtifactStyle::PARENT), #TYPE },
+
+SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYLE_ENTRY)
+
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactDesc !!!!!!!!!!!!!!!!!!!!!!! */
+
/* static */ArtifactDesc ArtifactDesc::makeFromCompileTarget(SlangCompileTarget target)
{
switch (target)
@@ -20,31 +247,106 @@ namespace Slang {
{
// For the moment we make all just map to GLSL, but we could use flags
// or some other mechanism to distinguish the types
- return make(Kind::Text, Payload::GLSL, Style::Kernel, 0);
+ return make(Kind::Source, Payload::GLSL, Style::Kernel, 0);
}
- case SLANG_HLSL: return make(Kind::Text, Payload::HLSL, Style::Kernel, 0);
+ case SLANG_HLSL: return make(Kind::Source, Payload::HLSL, Style::Kernel, 0);
case SLANG_SPIRV: return make(Kind::Executable, Payload::SPIRV, Style::Kernel, 0);
- case SLANG_SPIRV_ASM: return make(Kind::Text, Payload::SPIRVAssembly, Style::Kernel, 0);
+ case SLANG_SPIRV_ASM: return make(Kind::Assembly, Payload::SPIRV, Style::Kernel, 0);
case SLANG_DXBC: return make(Kind::Executable, Payload::DXBC, Style::Kernel, 0);
- case SLANG_DXBC_ASM: return make(Kind::Text, Payload::DXBCAssembly, Style::Kernel, 0);
+ case SLANG_DXBC_ASM: return make(Kind::Assembly, Payload::DXBC, Style::Kernel, 0);
case SLANG_DXIL: return make(Kind::Executable, Payload::DXIL, Style::Kernel, 0);
- case SLANG_DXIL_ASM: return make(Kind::Text, Payload::DXILAssembly, Style::Kernel, 0);
- case SLANG_C_SOURCE: return make(Kind::Text, Payload::C, Style::Kernel, 0);
- case SLANG_CPP_SOURCE: return make(Kind::Text, Payload::CPP, Style::Kernel, 0);
- case SLANG_HOST_CPP_SOURCE: return make(Kind::Text, Payload::CPP, Style::Host, 0);
+ case SLANG_DXIL_ASM: return make(Kind::Assembly, Payload::DXIL, Style::Kernel, 0);
+ case SLANG_C_SOURCE: return make(Kind::Source, Payload::C, Style::Kernel, 0);
+ case SLANG_CPP_SOURCE: return make(Kind::Source, Payload::Cpp, Style::Kernel, 0);
+ case SLANG_HOST_CPP_SOURCE: return make(Kind::Source, Payload::Cpp, Style::Host, 0);
case SLANG_HOST_EXECUTABLE: return make(Kind::Executable, Payload::HostCPU, Style::Host, 0);
case SLANG_SHADER_SHARED_LIBRARY: return make(Kind::SharedLibrary, Payload::HostCPU, Style::Kernel, 0);
- case SLANG_SHADER_HOST_CALLABLE: return make(Kind::Callable, Payload::HostCPU, Style::Kernel, 0);
- case SLANG_CUDA_SOURCE: return make(Kind::Text, Payload::CUDA, Style::Kernel, 0);
+ case SLANG_SHADER_HOST_CALLABLE: return make(Kind::HostCallable, Payload::HostCPU, Style::Kernel, 0);
+ case SLANG_CUDA_SOURCE: return make(Kind::Source, Payload::CUDA, Style::Kernel, 0);
+ // TODO(JS):
+ // Not entirely clear how best to represent PTX here. We could mark as 'Assembly'. Saying it is
+ // 'Executable' implies it is Binary (which PTX isn't). Executable also implies 'complete for executation',
+ // irrespective of it being text.
case SLANG_PTX: return make(Kind::Executable, Payload::PTX, Style::Kernel, 0);
case SLANG_OBJECT_CODE: return make(Kind::ObjectCode, Payload::HostCPU, Style::Kernel, 0);
- case SLANG_HOST_HOST_CALLABLE: return make(Kind::Callable, Payload::HostCPU, Style::Host, 0);
+ case SLANG_HOST_HOST_CALLABLE: return make(Kind::HostCallable, Payload::HostCPU, Style::Host, 0);
default: break;
}
SLANG_UNEXPECTED("Unhandled type");
}
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactList !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void* ArtifactList::getInterface(const Guid& guid)
+{
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ICastable::getTypeGuid() ||
+ guid == IArtifactList::getTypeGuid())
+ {
+ return static_cast<IArtifactList*>(this);
+ }
+ return nullptr;
+}
+
+void* ArtifactList::getObject(const Guid& guid)
+{
+ // For now we can't cast to an object
+ SLANG_UNUSED(guid);
+ return nullptr;
+}
+
+void* ArtifactList::castAs(const Guid& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ return getObject(guid);
+}
+
+void ArtifactList::add(IArtifact* artifact)
+{
+ // Must be set
+ SLANG_ASSERT(artifact);
+ // Can't already be in the list
+ SLANG_ASSERT(m_artifacts.indexOf(artifact) < 0);
+ // Can't have another owner
+ SLANG_ASSERT(artifact->getParent() == nullptr);
+
+ // Set the parent
+ artifact->setParent(m_parent);
+
+ // Add
+ m_artifacts.add(ComPtr<IArtifact>(artifact));
+}
+
+void ArtifactList::removeAt(Index index)
+{
+ IArtifact* artifact = m_artifacts[index];
+ artifact->setParent(nullptr);
+ m_artifacts.removeAt(index);
+}
+
+void ArtifactList::clear()
+{
+ _setParent(nullptr);
+ m_artifacts.clear();
+}
+
+void ArtifactList::_setParent(IArtifact* parent)
+{
+ if (m_parent == parent)
+ {
+ return;
+ }
+
+ for (IArtifact* artifact : m_artifacts)
+ {
+ artifact->setParent(artifact);
+ }
+}
+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Artifact !!!!!!!!!!!!!!!!!!!!!!!!!!! */
void* Artifact::getInterface(const Guid& uuid)
@@ -78,9 +380,30 @@ bool Artifact::exists()
return true;
}
- // If we have an associated entry that represents the artifact it exists
- if (findElement(IArtifactInstance::getTypeGuid()))
+ for (ISlangUnknown* item : m_items)
{
+ ComPtr<ICastable> castable;
+
+ if (SLANG_SUCCEEDED(item->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
+ {
+ auto rep = (IArtifactRepresentation*)castable->castAs(IArtifactRepresentation::getTypeGuid());
+ if (rep)
+ {
+ // It is a rep and it exists
+ if (rep->exists())
+ {
+ return true;
+ }
+ continue;
+ }
+ // Associated types don't encapsulate an artifact representation, so don't signal existance
+ if (castable->castAs(IArtifactAssociated::getTypeGuid()))
+ {
+ continue;
+ }
+ }
+
+ // It can't be IArtifactRepresentation or IArtifactAssociated, so we assume means it exists
return true;
}
@@ -94,54 +417,57 @@ bool Artifact::exists()
return File::exists(m_path);
}
-ISlangUnknown* Artifact::findElement(const Guid& guid)
+
+void Artifact::addItem(ISlangUnknown* intf)
+{
+ SLANG_ASSERT(intf);
+ // Can't already be in there
+ SLANG_ASSERT(m_items.indexOf(intf) < 0);
+ // Add it
+ m_items.add(ComPtr<ISlangUnknown>(intf));
+}
+
+void Artifact::removeItemAt(Index i)
{
- for (auto const& element : m_elements)
- {
- ISlangUnknown* value = element.value;
+ m_items.removeAt(i);
+}
+
- ISlangUnknown* intf = nullptr;
- if (SLANG_SUCCEEDED(value->queryInterface(guid, (void**)&intf)) && intf)
+void* Artifact::findItemInterface(const Guid& guid)
+{
+ for (ISlangUnknown* intf : m_items)
+ {
+ ISlangUnknown* cast = nullptr;
+ if (SLANG_SUCCEEDED(intf->queryInterface(guid, (void**)&cast)) && cast)
{
// NOTE! This assumes we *DONT* need to ref count to keep an interface in scope
// (as strict COM requires so as to allow on demand interfaces).
- intf->release();
- return intf;
+ cast->release();
+ return cast;
}
}
-
return nullptr;
}
-void Artifact::addElement(const Desc& desc, ISlangUnknown* intf)
-{
- SLANG_ASSERT(intf);
- Element element{ desc, ComPtr<ISlangUnknown>(intf) };
- m_elements.add(element);
-}
-
-void Artifact::removeElementAt(Index i)
+void* Artifact::findItemObject(const Guid& classGuid)
{
- m_elements.removeAt(i);
-}
-
-void* Artifact::findElementObject(const Guid& classGuid)
-{
- ComPtr<IArtifactInstance> instance;
- for (const auto& element : m_elements)
+ for (ISlangUnknown* intf : m_items)
{
- ISlangUnknown* value = element.value;
-
- if (SLANG_SUCCEEDED(value->queryInterface(IArtifactInstance::getTypeGuid(), (void**)instance.writeRef())) && instance)
+ ComPtr<ICastable> castable;
+ if (SLANG_SUCCEEDED(intf->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
{
- void* classInstance = instance->queryObject(classGuid);
- if (classInstance)
+ void* obj = castable->castAs(classGuid);
+
+ // NOTE! This assumes we *DONT* need to ref count to keep an interface in scope
+ // (as strict COM requires so as to allow on demand interfaces).
+
+ // If could cast return the result
+ if (obj)
{
- return classInstance;
+ return obj;
}
}
}
-
return nullptr;
}
@@ -270,14 +596,13 @@ SlangResult Artifact::loadBlob(Keep keep, ISlangBlob** outBlob)
else
{
// Look for a representation that we can serialize into a blob
- for (const auto& element : m_elements)
+ for (ISlangUnknown* intf : m_items)
{
- ISlangUnknown* intf = element.value;
-
- ComPtr<IArtifactInstance> inst;
- if (SLANG_SUCCEEDED(intf->queryInterface(IArtifactInstance::getTypeGuid(), (void**)inst.writeRef())) && inst)
+
+ ComPtr<IArtifactRepresentation> rep;
+ if (SLANG_SUCCEEDED(intf->queryInterface(IArtifactRepresentation::getTypeGuid(), (void**)rep.writeRef())) && rep)
{
- SlangResult res = inst->writeToBlob(blob.writeRef());
+ SlangResult res = rep->writeToBlob(blob.writeRef());
if (SLANG_SUCCEEDED(res) && blob)
{
break;
diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h
index 362dac16f..c63ec3b67 100644
--- a/source/compiler-core/slang-artifact.h
+++ b/source/compiler-core/slang-artifact.h
@@ -8,84 +8,153 @@
#include "../../slang-com-ptr.h"
#include "../core/slang-com-object.h"
+#include "../core/slang-destroyable.h"
namespace Slang
{
+/* As a rule of thumb, if we can define some aspect in a hierarchy then we should do so at the highest level.
+If some aspect can apply to multiple items identically we move that to a separate enum.
+
+NOTE!
+New Kinds must be added at the end. Values can be depreciated, or disabled
+but never removed, without breaking binary compatability.
+
+Any change requires a change to SLANG_ARTIFACT_KIND
+*/
enum class ArtifactKind : uint8_t
-{
- None, ///< There is no container
+{
+ Invalid, ///< Invalid
+ Base, ///< Base kind of all valid kinds
- Unknown, ///< There is a container of unknown type
+ None, ///< Doesn't contain anything
+ Unknown, ///< Unknown
- Library, ///< Library of object code (typically made up multiple ObjectCode)
- ObjectCode, ///< Object code (for CPU typically .o or .obj file types)
+ Container, ///< Container like types
+ Zip, ///< Zip container
+ Riff, ///< Riff format
- Executable, ///< Self contained such it can exectuted. On GPU this would be a kernel.
- SharedLibrary, ///< Shared library/dll
- Callable, ///< Callable directly (can mean there isn't a binary artifact)
+ Text, ///< Representation is text. Encoding is utf8, unless prefixed with 'encoding'.
+
+ Source, ///< Source (Source type is in payload)
+ Assembly, ///< Assembly (Type is in payload)
+ HumanText, ///< Text for human consumption
- Text, ///< Text
+ BinaryLike, ///< Kinds which are 'binary like' - can be executed, linked with and so forth.
+
+ ObjectCode, ///< Object file
+ Library, ///< Library (collection of object code)
+ Executable, ///< Executable
+ SharedLibrary, ///< Shared library - can be dynamically linked
+ HostCallable, ///< Code can be executed directly on the host
- Container, ///< A container holding other things
+ DebugInfo, ///< Debugging information
+ Diagnostics, ///< Diagnostics information
CountOf,
};
+
+/// Get the parent kind
+ArtifactKind getParent(ArtifactKind kind);
+/// Returns true if kind is derived from base
+bool isDerivedFrom(ArtifactKind kind, ArtifactKind base);
+/// Get the name for the kind
+UnownedStringSlice getName(ArtifactKind kind);
-enum class ArtifactPayload : uint8_t
-{
- None, ///< There is no payload
+/* Payload.
- Unknown, ///< Has payload but its unknown variety
+SlangIR and LLVMIR can be GPU or CPU orientated, so put in own category.
- DXIL,
- DXBC,
- SPIRV,
- PTX,
+NOTE!
+New Payloads must be added at the end. Values can be depreciated, or disabled
+but never removed, without breaking binary compatability.
- DXILAssembly,
- DXBCAssembly,
- SPIRVAssembly,
- PTXAssembly,
+Any change requires a change to SLANG_ARTIFACT_PAYLOAD
+*/
+enum class ArtifactPayload : uint8_t
+{
+ Invalid, ///< Is invalid - indicates some kind of problem
+ Base, ///< The base of the hierarchy
+
+ None, ///< Doesn't have a payload
+ Unknown, ///< Unknown but probably valid
+
+ Source, ///< Source code
+
+ C, ///< C source
+ Cpp, ///< C++ source
+ HLSL, ///< HLSL source
+ GLSL, ///< GLSL source
+ CUDA, ///< CUDA source
+ Metal, ///< Metal source
+ Slang, ///< Slang source
+
+ KernelLike, ///< GPU Kernel like
+
+ DXIL, ///< DXIL
+ DXBC, ///< DXBC
+ SPIRV, ///< SPIR-V
+ PTX, ///< PTX. NOTE! PTX is a text format, but is handable to CUDA API.
+ MetalAIR, ///< Metal AIR
+ CuBin, ///< CUDA binary
+
+ CPULike, ///< CPU code
+
+ UnknownCPU, ///< CPU code for unknown/undetermined type
+ X86, ///< X86
+ X86_64, ///< X86_64
+ Aarch, ///< 32 bit arm
+ Aarch64, ///< Aarch64
+ HostCPU, ///< HostCPU
+ UniversalCPU, ///< CPU code for multiple CPU types
- HostCPU, ///< The host CPU architecture
+ GeneralIR, ///< General purpose IR representation (IR)
SlangIR, ///< Slang IR
LLVMIR, ///< LLVM IR
- SlangAST, ///< Slang AST
-
- X86,
- X86_64,
- AARCH,
- AARCH64,
+ AST, ///< Abstract syntax tree (AST)
- HLSL, ///< HLSL
- GLSL, ///< GLSL
- CPP, ///< C++
- C, ///< C Language
- CUDA, ///< CUDA
- Slang, ///< Slang
+ SlangAST, ///< Slang AST
- DebugInfo, ///< Debug information
+ CountOf,
+};
- Diagnostics, ///< Diagnostics
+/// Get the parent payload
+ArtifactPayload getParent(ArtifactPayload payload);
+/// Returns true if payload is derived from base
+bool isDerivedFrom(ArtifactPayload payload, ArtifactPayload base);
+/// Get the name for the payload
+UnownedStringSlice getName(ArtifactPayload payload);
- Zip, ///< It's a zip
+/* Style.
- CountOf,
-};
+NOTE!
+New Styles must be added at the end. Values can be depreciated, or disabled
+but never removed, without breaking binary compatability.
+Any change requires a change to SLANG_ARTIFACT_STYLE
+*/
enum class ArtifactStyle : uint8_t
{
- Unknown, ///< Unknown
+ Invalid, ///< Invalid style (indicating an error)
+ Base,
+
+ Unknown, ///< Unknown
- Kernel, ///< Compiled as `GPU kernel` style.
- Host, ///< Compiled in `host` style
+ Kernel, ///< Compiled as `GPU kernel` style.
+ Host, ///< Compiled in `host` style
CountOf,
};
+/// Get the parent style
+ArtifactStyle getParent(ArtifactStyle style);
+/// Returns true if style is derived from base
+bool isDerivedFrom(ArtifactStyle style, ArtifactStyle base);
+/// Get the name for the style
+UnownedStringSlice getName(ArtifactStyle style);
+
typedef uint8_t ArtifactFlags;
struct ArtifactFlag
{
@@ -95,7 +164,6 @@ struct ArtifactFlag
};
};
-
/**
A value type to describe aspects of the contents of an Artifact.
**/
@@ -180,13 +248,13 @@ enum ArtifactPathType
Existing, ///< Is an existing file
};
-/* The IArtifactInstance interface represents a single instance of a type that can be part of an artifact. It's special in so far
+/* The IArtifactRepresentation interface represents a single representation that can be part of an artifact. It's special in so far
as
-* IArtifactInstance can be queried for it's underlying object class
+* IArtifactRepresentation can be queried for it's underlying object class
* Can optionally serialize into a blob
*/
-class IArtifactInstance : public ISlangUnknown
+class IArtifactRepresentation : public ICastable
{
SLANG_COM_INTERFACE(0x311457a8, 0x1796, 0x4ebb, { 0x9a, 0xfc, 0x46, 0xa5, 0x44, 0xc7, 0x6e, 0xa9 })
@@ -194,13 +262,15 @@ class IArtifactInstance : public ISlangUnknown
/// Returns SLANG_E_NOT_IMPLEMENTED if an implementation doesn't implement
virtual SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) = 0;
- /// Queries for the backing object type. The type is represented by a guid.
- /// If the object doesn't derive from the type guid the function returns nullptr.
- /// Unlike the analagous queryInterface method the ref count remains unchanged.
- /// NOTE!
- /// Whilst this method *could) be used across an ABI boundary (whereas using something like dynamic_cast would not),
- /// it is generally dangerous to do so.
- virtual SLANG_NO_THROW void* SLANG_MCALL queryObject(const Guid& classGuid) = 0;
+ /// Returns true if this representation exists and is available for use.
+ virtual SLANG_NO_THROW bool SLANG_MCALL exists() = 0;
+};
+
+/* Interface for types that are associated with an artifact, but aren't a representation, or are
+only part of a representation. */
+class IArtifactAssociated : public ICastable
+{
+ SLANG_COM_INTERFACE(0xafc0e4db, 0x16d4, 0x4d7a, { 0x93, 0x5f, 0x3e, 0x47, 0x7a, 0x23, 0x2a, 0x7f })
};
/* The IArtifact interface is designed to represent some Artifact of compilation. It could be input to or output from a compilation.
@@ -255,6 +325,11 @@ public:
/// Get the Desc defining the contents of the artifact
virtual SLANG_NO_THROW Desc SLANG_MCALL getDesc() = 0;
+ /// Get the artifact (if any) that this artifact belongs to
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL getParent() = 0;
+ /// Set the parent that 'owns' this artifact. The parent is *not* reference counted (ie weak reference)
+ virtual SLANG_NO_THROW void SLANG_MCALL setParent(IArtifact* parent) = 0;
+
/// Returns true if the artifact in principal exists
virtual SLANG_NO_THROW bool SLANG_MCALL exists() = 0;
@@ -275,12 +350,6 @@ public:
/// artifact name needs to be correct.
virtual SLANG_NO_THROW SlangResult SLANG_MCALL requireFileLike(Keep keep) = 0;
- /// Finds an instance of that has the the interface guid
- virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL findElement(const Guid& guid) = 0;
-
- /// Find an element that derives from IArtifactInstance, and which queryObject works with the classGuid
- virtual SLANG_NO_THROW void* SLANG_MCALL findElementObject(const Guid& classGuid) = 0;
-
/// Add items
virtual SLANG_NO_THROW void SLANG_MCALL setPath(PathType pathType, const char* filePath) = 0;
@@ -295,19 +364,78 @@ public:
/// Get the name of the artifact. This can be empty.
virtual SLANG_NO_THROW const char* SLANG_MCALL getName() = 0;
- /// Add an interface
- virtual SLANG_NO_THROW void SLANG_MCALL addElement(const Desc& desc, ISlangUnknown* intf) = 0;
-
- /// Get the item at the index
- virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getElementAt(Index i) = 0;
- /// Get the desc associated with an element
- virtual SLANG_NO_THROW Desc SLANG_MCALL getElementDescAt(Index i) = 0;
+ /// Find an item by casting it's interface
+ virtual SLANG_NO_THROW void* SLANG_MCALL findItemInterface(const Guid& uuid) = 0;
+ /// Only works on ICastable derived items. Can find interfaces or objects.
+ virtual SLANG_NO_THROW void* SLANG_MCALL findItemObject(const Guid& classGuid) = 0;
+ /// Add a representation
+ virtual SLANG_NO_THROW void SLANG_MCALL addItem(ISlangUnknown* item) = 0;
+ /// Get the item at the index
+ virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getItemAt(Index i) = 0;
/// Remove the element at the specified index.
- virtual SLANG_NO_THROW void SLANG_MCALL removeElementAt(Index i) = 0;
-
+ virtual SLANG_NO_THROW void SLANG_MCALL removeItemAt(Index i) = 0;
/// Get the amount of elements
- virtual SLANG_NO_THROW Index SLANG_MCALL getElementCount() = 0;
+ virtual SLANG_NO_THROW Index SLANG_MCALL getItemCount() = 0;
+};
+
+/* A list of artifacts. */
+class IArtifactList : public ICastable
+{
+ SLANG_COM_INTERFACE(0x5ef6ace5, 0xc928, 0x4c7b, { 0xbc, 0xba, 0x83, 0xa9, 0xd9, 0x66, 0x64, 0x27 })
+
+ /// Get the artifact this list belongs to. Can be nullptr.
+ /// Note this is a *weak* reference.
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL getParent() = 0;
+ /// The parent is no longer accessible
+ virtual SLANG_NO_THROW void SLANG_MCALL setParent(IArtifact* artifact) = 0;
+
+ /// Get the artifact at the specified index
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL getAt(Index index) = 0;
+ /// Get the count of all the artifacts
+ virtual SLANG_NO_THROW Count SLANG_MCALL getCount() = 0;
+ /// Add the artifact to the list
+ virtual SLANG_NO_THROW void SLANG_MCALL add(IArtifact* artifact) = 0;
+ /// Removes at index, keeps other artifacts in the same order
+ virtual SLANG_NO_THROW void SLANG_MCALL removeAt(Index index) = 0;
+ /// Clear the list
+ virtual SLANG_NO_THROW void SLANG_MCALL clear() = 0;
+};
+
+class ArtifactList : public ComObject, public IArtifactList
+{
+public:
+ SLANG_COM_OBJECT_IUNKNOWN_ALL
+
+ // ICastable
+ SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+
+ // IArtifactList
+ SLANG_NO_THROW IArtifact* SLANG_MCALL getParent() SLANG_OVERRIDE { return m_parent; }
+ SLANG_NO_THROW void SLANG_MCALL setParent(IArtifact* parent) SLANG_OVERRIDE { _setParent(parent); }
+
+ SLANG_NO_THROW IArtifact* SLANG_MCALL getAt(Index index) SLANG_OVERRIDE { return m_artifacts[index]; }
+ SLANG_NO_THROW Count SLANG_MCALL getCount() SLANG_OVERRIDE { return m_artifacts.getCount(); }
+ SLANG_NO_THROW void SLANG_MCALL add(IArtifact* artifact) SLANG_OVERRIDE;
+ SLANG_NO_THROW void SLANG_MCALL removeAt(Index index) SLANG_OVERRIDE;
+ SLANG_NO_THROW void SLANG_MCALL clear() SLANG_OVERRIDE;
+
+ // NOTE! The parent is a weak reference.
+ ArtifactList(IArtifact* parent):
+ m_parent(parent)
+ {
+ }
+
+ virtual ~ArtifactList() { _setParent(nullptr); }
+
+protected:
+ void* getInterface(const Guid& guid);
+ void* getObject(const Guid& guid);
+
+ void _setParent(IArtifact* artifact);
+
+ IArtifact* m_parent;
+ List<ComPtr<IArtifact>> m_artifacts;
};
/*
@@ -342,27 +470,29 @@ public:
/// IArtifact impl
virtual SLANG_NO_THROW Desc SLANG_MCALL getDesc() SLANG_OVERRIDE { return m_desc; }
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL getParent() SLANG_OVERRIDE { return m_parent; }
+ virtual SLANG_NO_THROW void SLANG_MCALL setParent(IArtifact* parent) SLANG_OVERRIDE { m_parent = parent; }
virtual SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadBlob(Keep keep, ISlangBlob** outBlob) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL requireFile(Keep keep) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL requireFileLike(Keep keep) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL findElement(const Guid& guid) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW void* SLANG_MCALL findElementObject(const Guid& classGuid) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL setPath(PathType pathType, const char* path) SLANG_OVERRIDE { _setPath(pathType, path); }
virtual SLANG_NO_THROW void SLANG_MCALL setBlob(ISlangBlob* blob) SLANG_OVERRIDE { m_blob = blob; }
virtual SLANG_NO_THROW PathType SLANG_MCALL getPathType() SLANG_OVERRIDE { return m_pathType; }
virtual SLANG_NO_THROW const char* SLANG_MCALL getPath() SLANG_OVERRIDE { return m_path.getBuffer(); }
virtual SLANG_NO_THROW const char* SLANG_MCALL getName() SLANG_OVERRIDE { return m_name.getBuffer(); }
- virtual SLANG_NO_THROW void SLANG_MCALL addElement(const Desc& desc, ISlangUnknown* intf) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getElementAt(Index i) SLANG_OVERRIDE { return m_elements[i].value; }
- virtual SLANG_NO_THROW Desc SLANG_MCALL getElementDescAt(Index i) SLANG_OVERRIDE { return m_elements[i].desc; }
- virtual SLANG_NO_THROW void SLANG_MCALL removeElementAt(Index i) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW Index SLANG_MCALL getElementCount() SLANG_OVERRIDE { return m_elements.getCount(); }
+ virtual SLANG_NO_THROW void* SLANG_MCALL findItemInterface(const Guid& uuid) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW void* SLANG_MCALL findItemObject(const Guid& classGuid) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW void SLANG_MCALL addItem(ISlangUnknown* intf) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getItemAt(Index i) SLANG_OVERRIDE { return m_items[i]; }
+ virtual SLANG_NO_THROW void SLANG_MCALL removeItemAt(Index i) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW Index SLANG_MCALL getItemCount() SLANG_OVERRIDE { return m_items.getCount(); }
/// Ctor
Artifact(const Desc& desc, const String& name) :
m_desc(desc),
- m_name(name)
+ m_name(name),
+ m_parent(nullptr)
{}
/// Dtor
~Artifact();
@@ -372,13 +502,9 @@ protected:
void _setPath(PathType pathType, const String& path) { m_pathType = pathType; m_path = path; }
- struct Element
- {
- ArtifactDesc desc;
- ComPtr<ISlangUnknown> value;
- };
-
Desc m_desc; ///< Description of the artifact
+ IArtifact* m_parent; ///< Artifact this artifact belongs to
+
String m_name; ///< Name of this artifact
PathType m_pathType = PathType::None; ///< What the path indicates
@@ -387,7 +513,7 @@ protected:
ComPtr<ISlangBlob> m_blob; ///< Blob to store result in memory
- List<Element> m_elements; ///< Associated elements
+ List<ComPtr<ISlangUnknown>> m_items; ///< Associated items
};
} // namespace Slang
diff --git a/source/core/slang-destroyable.h b/source/core/slang-destroyable.h
new file mode 100644
index 000000000..4e6be2629
--- /dev/null
+++ b/source/core/slang-destroyable.h
@@ -0,0 +1,41 @@
+#ifndef SLANG_CORE_DESTROYABLE_H
+#define SLANG_CORE_DESTROYABLE_H
+
+#include "slang-string.h"
+
+#include "../../slang-com-helper.h"
+#include "../../slang-com-ptr.h"
+
+namespace Slang
+{
+
+/* An interface to provide a mechanism to cast, that doesn't require ref counting
+and doesn't have to return a pointer to a ISlangUnknown derived class */
+class ICastable : public ISlangUnknown
+{
+ SLANG_COM_INTERFACE(0x87ede0e1, 0x4852, 0x44b0, { 0x8b, 0xf2, 0xcb, 0x31, 0x87, 0x4d, 0xe2, 0x39 } );
+
+ /// Can be used to cast to interfaces without reference counting.
+ /// Also provides access to internal implementations, when they provide a guid
+ /// Can simulate a 'generated' interface as long as kept in scope by cast from.
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) = 0;
+};
+
+/* An interface that allows for an object to implement 'destruction'. A destroyed
+interface/object should release any other contained references.
+Behavior of an interface that is IDestroyed should be defined on the interface. Typically
+it will produce an assert on debug builds.
+Calling destroy/isDestroyed can always be performed. */
+class IDestroyable : public ICastable
+{
+ SLANG_COM_INTERFACE(0x99c6228e, 0xa82, 0x43eb, { 0x8f, 0xd1, 0xf3, 0x54, 0x3e, 0x2e, 0x86, 0xc0 } );
+
+ /// Destroy. Can call on destroyed - is a no op.
+ virtual SLANG_NO_THROW void SLANG_MCALL destroy() = 0;
+ /// Once destroyed *no* functionality is supported other than IUnknown and destroy/isDestroyed
+ virtual SLANG_NO_THROW bool SLANG_MCALL isDestroyed() = 0;
+};
+
+}
+
+#endif // SLANG_CORE_DESTROYABLE_H
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index d4c5812b7..8a9c322b2 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -1303,7 +1303,7 @@ void printDiagnosticArg(StringBuilder& sb, CodeGenTarget val)
// If we aren't using LLVM 'host callable', we want downstream compile to produce a shared library
if (compilerType != PassThroughMode::LLVM &&
- ArtifactDesc::makeFromCompileTarget(asExternal(target)).kind == ArtifactKind::Callable)
+ ArtifactDesc::makeFromCompileTarget(asExternal(target)).kind == ArtifactKind::HostCallable)
{
target = CodeGenTarget::ShaderSharedLibrary;
}
@@ -1800,7 +1800,7 @@ void printDiagnosticArg(StringBuilder& sb, CodeGenTarget val)
ComPtr<ISlangBlob> blob;
if (SLANG_FAILED(result.getBlob(blob)))
{
- if (ArtifactDesc::makeFromCompileTarget(asExternal(targetReq->getTarget())).kind == ArtifactKind::Callable)
+ if (ArtifactDesc::makeFromCompileTarget(asExternal(targetReq->getTarget())).kind == ArtifactKind::HostCallable)
{
// Some HostCallable are not directly representable as a 'binary'.
// So here, we just ignore if that appears the case, and don't output an unexpected error.
diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp
index 14724046a..636a32a4d 100644
--- a/source/slang/slang-ir-link.cpp
+++ b/source/slang/slang-ir-link.cpp
@@ -1411,7 +1411,7 @@ LinkedIR linkIR(
});
for (IArtifact* artifact : linkage->m_libModules)
{
- ModuleLibrary* library = (ModuleLibrary*)artifact->findElementObject(ModuleLibrary::getTypeGuid());
+ ModuleLibrary* library = (ModuleLibrary*)artifact->findItemObject(ModuleLibrary::getTypeGuid());
if (library)
{
irModules.addRange(library->m_modules.getBuffer()->readRef(), library->m_modules.getCount());
diff --git a/source/slang/slang-module-library.cpp b/source/slang/slang-module-library.cpp
index 140be4d64..b60555766 100644
--- a/source/slang/slang-module-library.cpp
+++ b/source/slang/slang-module-library.cpp
@@ -15,13 +15,27 @@ namespace Slang {
void* ModuleLibrary::getInterface(const Guid& uuid)
{
- if (uuid == ISlangUnknown::getTypeGuid() || uuid == IArtifactInstance::getTypeGuid())
+ if (uuid == ISlangUnknown::getTypeGuid() || uuid == ICastable::getTypeGuid() || uuid == IArtifactRepresentation::getTypeGuid())
{
- return static_cast<IArtifactInstance*>(this);
+ return static_cast<IArtifactRepresentation*>(this);
}
return nullptr;
}
+void* ModuleLibrary::getObject(const Guid& uuid)
+{
+ return uuid == getTypeGuid() ? this : nullptr;
+}
+
+void* ModuleLibrary::castAs(const Guid& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ return getObject(guid);
+}
+
SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, EndToEndCompileRequest* req, RefPtr<ModuleLibrary>& outLibrary)
{
RefPtr<ModuleLibrary> library = new ModuleLibrary;
@@ -77,7 +91,7 @@ SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, EndToEndCo
SlangResult loadModuleLibrary(ArtifactKeep keep, IArtifact* artifact, EndToEndCompileRequest* req, RefPtr<ModuleLibrary>& outLibrary)
{
- if (auto foundLibrary = (ModuleLibrary*)artifact->findElementObject(ModuleLibrary::getTypeGuid()))
+ if (auto foundLibrary = (ModuleLibrary*)artifact->findItemObject(ModuleLibrary::getTypeGuid()))
{
outLibrary = foundLibrary;
return SLANG_OK;
@@ -93,7 +107,7 @@ SlangResult loadModuleLibrary(ArtifactKeep keep, IArtifact* artifact, EndToEndCo
if (canKeep(keep))
{
- artifact->addElement(artifact->getDesc(), library);
+ artifact->addItem(library);
}
outLibrary = library;
diff --git a/source/slang/slang-module-library.h b/source/slang/slang-module-library.h
index 7b65dad9e..58d10bfc3 100644
--- a/source/slang/slang-module-library.h
+++ b/source/slang/slang-module-library.h
@@ -10,7 +10,7 @@ namespace Slang
{
// Class to hold information serialized in from a -r slang-lib/slang-module
-class ModuleLibrary : public ComObject, public IArtifactInstance
+class ModuleLibrary : public ComObject, public IArtifactRepresentation
{
public:
@@ -18,14 +18,18 @@ public:
SLANG_CLASS_GUID(0x2f7412bd, 0x6154, 0x40a9, { 0x89, 0xb3, 0x62, 0xe0, 0x24, 0x17, 0x24, 0xa1 });
- // IArtifactInstance
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+
+ // IArtifactRepresentation
virtual SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) SLANG_OVERRIDE { SLANG_UNUSED(blob); return SLANG_E_NOT_IMPLEMENTED; }
- virtual SLANG_NO_THROW void* SLANG_MCALL queryObject(const Guid& classGuid) SLANG_OVERRIDE { return classGuid == getTypeGuid() ? this : nullptr; }
+ virtual SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE { return true; }
List<FrontEndCompileRequest::ExtraEntryPointInfo> m_entryPoints;
List<RefPtr<IRModule>> m_modules;
void* getInterface(const Guid& uuid);
+ void* getObject(const Guid& uuid);
};
SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, EndToEndCompileRequest* req, RefPtr<ModuleLibrary>& module);
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index 9825e4e23..f56395f5b 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -1467,12 +1467,12 @@ struct OptionsParser
}
// If it's a GPU binary, then we'll assume it's a library
- if (ArtifactInfoUtil::isGpuBinary(desc))
+ if (ArtifactInfoUtil::isGpuUsable(desc))
{
desc.kind = ArtifactKind::Library;
}
- if (!ArtifactInfoUtil::isBinaryLinkable(desc))
+ if (!ArtifactInfoUtil::isLinkable(desc))
{
sink->diagnose(referenceModuleName.loc, Diagnostics::kindNotLinkable, Path::getPathExt(path));
return SLANG_FAIL;
@@ -2036,7 +2036,7 @@ struct OptionsParser
// and output type is callable, add an empty' rawOutput.
if (rawOutputs.getCount() == 0 &&
rawTargets.getCount() == 1 &&
- ArtifactDesc::makeFromCompileTarget(asExternal(rawTargets[0].format)).kind == ArtifactKind::Callable)
+ ArtifactDesc::makeFromCompileTarget(asExternal(rawTargets[0].format)).kind == ArtifactKind::HostCallable)
{
RawOutput rawOutput;
rawOutput.impliedFormat = rawTargets[0].format;
diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp
index d0b12b19b..220cfb992 100644
--- a/source/slang/slang-parameter-binding.cpp
+++ b/source/slang/slang-parameter-binding.cpp
@@ -3032,7 +3032,7 @@ static int _calcTotalNumUsedRegistersForLayoutResourceKind(ParameterBindingConte
static bool _isCPUTarget(CodeGenTarget target)
{
const auto desc = ArtifactDesc::makeFromCompileTarget(asExternal(target));
- return ArtifactInfoUtil::isCpuTarget(desc);
+ return ArtifactInfoUtil::isCpuLikeTarget(desc);
}
static bool _isPTXTarget(CodeGenTarget target)
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index 09a21fb6f..cde70d488 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -1606,7 +1606,7 @@ bool isKhronosTarget(TargetRequest* targetReq)
bool isCPUTarget(TargetRequest* targetReq)
{
- return ArtifactInfoUtil::isCpuTarget(ArtifactDesc::makeFromCompileTarget(asExternal(targetReq->getTarget())));
+ return ArtifactInfoUtil::isCpuLikeTarget(ArtifactDesc::makeFromCompileTarget(asExternal(targetReq->getTarget())));
}
bool isCUDATarget(TargetRequest* targetReq)
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 891b9827a..b3762e471 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -727,7 +727,7 @@ SlangPassThrough Session::getDownstreamCompilerForTransition(SlangCompileTarget
const auto desc = ArtifactDesc::makeFromCompileTarget(inTarget);
// Special case host-callable
- if ((desc.kind == ArtifactKind::Callable) &&
+ if ((desc.kind == ArtifactKind::HostCallable) &&
(source == CodeGenTarget::CSource || source == CodeGenTarget::CPPSource))
{
// We prefer LLVM if it's available
@@ -4507,9 +4507,9 @@ SlangResult EndToEndCompileRequest::addLibraryReference(const void* libData, siz
const auto desc = ArtifactDesc::make(ArtifactKind::Library, ArtifactPayload::SlangIR);
// Create an artifact without any name (as one is not provided)
- RefPtr<Artifact> artifact = new Artifact(desc, String());
+ ComPtr<IArtifact> artifact(new Artifact(desc, String()));
- artifact->addElement(desc, library);
+ artifact->addItem(library);
return _addLibraryReference(this, artifact);
}