diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2022-08-16 16:12:45 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-16 13:12:45 -0700 |
| commit | 42de00db3ffe07599fff6d47d0d7228181ee3082 (patch) | |
| tree | 84367b359cd2701212214379d4d604488c4fac91 /source/compiler-core | |
| parent | ac71724c03392b429e44641a3641b2bcf7cc55fc (diff) | |
Move metadata/diagnostics to associated types (#2358)
* #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.
* First attempt at file abstraction around Artifact.
* Added creation of lock file.
* Move functionality for determining file paths to the IArtifactUtil.
Add casting to ICastable.
* Added some casting/finding mechanisms.
* Simplify IArtifact interface, and use Items for file reps.
* Fix problem with libraries on DXIL.
* Split out ArtifactRepresentation.
* Move ArtifactDesc functionality to ArtifactDescUtil. ArtifactInfoUtil becomes ArtifactDescUtil.
* Split implementations from the interfaces for Artifact.
* Use TypeTextUtil for target name outputting.
* Add artifact impls.
* Add ICastableList
* Added UnknownCastableAdapter
* Make ISlangSharedLibrary derive from ICastable, and remain backwards compatible with slang-llvm.
* Refactor Representation on Artifact.
* Make our ISlangBlobs also derive from ICastable.
Make ISlangBlob atomic ref counted.
* Split out CastableList and related types, and placed in core.
* Small fixes around IArtifact.
Improve IArtifact docs.
First impl of getChildren for IArtifact.
* Documentation improvements for Artifact related types.
* Fix typo.
* Special case adding a ICastableList to a LazyCastableList.
* Small simplification of LazyCastableList, by adding State member.
* Removed the ILockFile interface because IFileArtifactRepresentation can be used.
* Implement DiagnosticsArtifactRepresentation.
* Added PostEmitMetadataArtifactRepresentation
* Add searching by predicate.
Added handling of accessing Artifact as ISharedLibrary
* Fix typo.
* Add find to IArtifacgtList.
Fix some missing SLANG_NO_THROW.
* Small improvements around ArtifactDesc types.
* Another small change around ArtifactKind.
* Some more shuffling of ArtifactDesc.
* Make IArtifact castable
Remove IArtifactList
Made IArtifactContainer derive from IArtifact
Made ModuleLibrary atomic ref counted/given IModuleLibrary interface.
* Must call _requireChildren before any children access.
* Fix missing SLANG_MCALL on castAs.
* Fix missing SLANG_OVERRIDE.
* Added IArtifactHandler
* Use ICastable for basis of scope/lookup.
* WIP first attempt to remove CompileResult.
* Fix support for for downstream compiler shared library adapter.
* Fix issues found when replacing CompileResult.
* Fix typo.
* Fix getting items form 'significant' member of an Artifact.
* Split out ArtifactUtil & ArtifactHandler.
* Work around for problem on Visual studio.
* Improve searching.
* Add missing files.
* Split out Artifact associated types.
Don't produce a container by default - use associated for 'metadata'.
* Remove no longer used ArtifactPayload type.
* Generalized converting representations.
Small improvements to artifacts.
* Fix intermediate dumping issue.
* Removed #if 0 out CompileResult.
Remove DownstreamCompileResult maybeDumpIntermediate.
* Pull out functionality for dumping artifact output into ArtifactOutputUtil
Fixed a bug in naming files based on ArtifactDesc.
* std::atomic issue.
* Fix outputting as text bug.
Some small improvements.
* Add fix around prefix for dumping.
Improved how handling for extensions work form ArtifactDesc.
* Dump assembly if available.
Diffstat (limited to 'source/compiler-core')
| -rw-r--r-- | source/compiler-core/slang-artifact-associated-impl.cpp | 99 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-associated-impl.h | 144 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-associated.h | 79 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-desc-util.cpp | 220 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-desc-util.h | 14 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-handler-impl.cpp | 68 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-handler-impl.h | 3 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-helper.cpp | 7 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-helper.h | 18 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-impl.h | 3 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-representation-impl.cpp | 116 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-representation-impl.h | 140 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-representation.h | 65 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-util.cpp | 20 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-util.h | 6 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact.h | 14 |
16 files changed, 555 insertions, 461 deletions
diff --git a/source/compiler-core/slang-artifact-associated-impl.cpp b/source/compiler-core/slang-artifact-associated-impl.cpp new file mode 100644 index 000000000..17ede975e --- /dev/null +++ b/source/compiler-core/slang-artifact-associated-impl.cpp @@ -0,0 +1,99 @@ +// slang-artifact-associated-impl.cpp +#include "slang-artifact-associated-impl.h" + +#include "../core/slang-file-system.h" + +#include "../core/slang-type-text-util.h" +#include "../core/slang-io.h" +#include "../core/slang-array-view.h" + +#include "slang-artifact-util.h" + +namespace Slang { + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactDiagnostics !!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +void* ArtifactDiagnostics::getInterface(const Guid& guid) +{ + if (guid == ISlangUnknown::getTypeGuid() || + guid == ICastable::getTypeGuid() || + guid == IDiagnostics::getTypeGuid()) + { + return static_cast<IDiagnostics*>(this); + } + return nullptr; +} + +void* ArtifactDiagnostics::getObject(const Guid& guid) +{ + SLANG_UNUSED(guid); + return nullptr; +} + +void* ArtifactDiagnostics::castAs(const Guid& guid) +{ + if (auto intf = getInterface(guid)) + { + return intf; + } + return getObject(guid); +} + +ZeroTerminatedCharSlice ArtifactDiagnostics::_allocateSlice(const Slice<char>& in) +{ + if (in.count == 0) + { + return ZeroTerminatedCharSlice("", 0); + } + const char* dst = m_arena.allocateString(in.data, in.count); + return ZeroTerminatedCharSlice(dst, in.count); +} + +void ArtifactDiagnostics::add(const Diagnostic& inDiagnostic) +{ + Diagnostic diagnostic(inDiagnostic); + + diagnostic.text = _allocateSlice(inDiagnostic.text); + diagnostic.code = _allocateSlice(inDiagnostic.code); + diagnostic.filePath = _allocateSlice(inDiagnostic.filePath); + + m_diagnostics.add(diagnostic); +} + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PostEmitMetadata !!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +void* PostEmitMetadata::getInterface(const Guid& guid) +{ + if (guid == ISlangUnknown::getTypeGuid() || + guid == ICastable::getTypeGuid() || + guid == IPostEmitMetadata::getTypeGuid()) + { + return static_cast<IPostEmitMetadata*>(this); + } + return nullptr; +} + +void* PostEmitMetadata::getObject(const Guid& uuid) +{ + if (uuid == getTypeGuid()) + { + return this; + } + return nullptr; +} + +void* PostEmitMetadata::castAs(const Guid& guid) +{ + if (auto ptr = getInterface(guid)) + { + return ptr; + } + return getObject(guid); +} + +Slice<ShaderBindingRange> PostEmitMetadata::getBindingRanges() +{ + return Slice<ShaderBindingRange>(m_usedBindings.getBuffer(), m_usedBindings.getCount()); +} + +} // namespace Slang diff --git a/source/compiler-core/slang-artifact-associated-impl.h b/source/compiler-core/slang-artifact-associated-impl.h new file mode 100644 index 000000000..dcd796c1e --- /dev/null +++ b/source/compiler-core/slang-artifact-associated-impl.h @@ -0,0 +1,144 @@ +// slang-artifact-associated-impl.h +#ifndef SLANG_ARTIFACT_ASSOCIATED_IMPL_H +#define SLANG_ARTIFACT_ASSOCIATED_IMPL_H + +#include "../../slang-com-helper.h" +#include "../../slang-com-ptr.h" + +#include "../core/slang-com-object.h" +#include "../core/slang-memory-arena.h" + +#include "slang-artifact-associated.h" + +namespace Slang +{ + +class ArtifactDiagnostics : public ComBaseObject, public IDiagnostics +{ +public: + SLANG_COM_BASE_IUNKNOWN_ALL + + // ICastable + SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE; + // IDiagnostic + SLANG_NO_THROW virtual const Diagnostic* SLANG_MCALL getAt(Index i) SLANG_OVERRIDE { return &m_diagnostics[i]; } + SLANG_NO_THROW virtual Count SLANG_MCALL getCount() SLANG_OVERRIDE { return m_diagnostics.getCount(); } + SLANG_NO_THROW virtual void SLANG_MCALL add(const Diagnostic& diagnostic) SLANG_OVERRIDE; + SLANG_NO_THROW virtual void SLANG_MCALL removeAt(Index i) SLANG_OVERRIDE { m_diagnostics.removeAt(i); } + SLANG_NO_THROW virtual SlangResult SLANG_MCALL getResult() SLANG_OVERRIDE { return m_result; } + SLANG_NO_THROW virtual void SLANG_MCALL setResult(SlangResult res) SLANG_OVERRIDE { m_result = res; } + + ArtifactDiagnostics(): + m_arena(1024) + { + } + +protected: + void* getInterface(const Guid& uuid); + void* getObject(const Guid& uuid); + + ZeroTerminatedCharSlice _allocateSlice(const Slice<char>& in); + + // We could consider storing paths, codes in StringSlicePool, but for now we just allocate all 'string type things' + // in the arena. + MemoryArena m_arena; + + List<Diagnostic> m_diagnostics; + SlangResult m_result = SLANG_OK; + + ZeroTerminatedCharSlice m_raw; +}; + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! PostEmitMetadata !!!!!!!!!!!!!!!!!!!!!!!!!! */ + +struct ShaderBindingRange +{ + slang::ParameterCategory category = slang::ParameterCategory::None; + UInt spaceIndex = 0; + UInt registerIndex = 0; + UInt registerCount = 0; // 0 for unsized + + bool isInfinite() const + { + return registerCount == 0; + } + + bool containsBinding(slang::ParameterCategory _category, UInt _spaceIndex, UInt _registerIndex) const + { + return category == _category + && spaceIndex == _spaceIndex + && registerIndex <= _registerIndex + && (isInfinite() || registerCount + registerIndex > _registerIndex); + } + + bool intersectsWith(const ShaderBindingRange& other) const + { + if (category != other.category || spaceIndex != other.spaceIndex) + return false; + + const bool leftIntersection = (registerIndex < other.registerIndex + other.registerCount) || other.isInfinite(); + const bool rightIntersection = (other.registerIndex < registerIndex + registerCount) || isInfinite(); + + return leftIntersection && rightIntersection; + } + + bool adjacentTo(const ShaderBindingRange& other) const + { + if (category != other.category || spaceIndex != other.spaceIndex) + return false; + + const bool leftIntersection = (registerIndex <= other.registerIndex + other.registerCount) || other.isInfinite(); + const bool rightIntersection = (other.registerIndex <= registerIndex + registerCount) || isInfinite(); + + return leftIntersection && rightIntersection; + } + + void mergeWith(const ShaderBindingRange other) + { + UInt newRegisterIndex = Math::Min(registerIndex, other.registerIndex); + + if (other.isInfinite()) + registerCount = 0; + else if (!isInfinite()) + registerCount = Math::Max(registerIndex + registerCount, other.registerIndex + other.registerCount) - newRegisterIndex; + + registerIndex = newRegisterIndex; + } + + static bool isUsageTracked(slang::ParameterCategory category) + { + switch (category) + { + case slang::ConstantBuffer: + case slang::ShaderResource: + case slang::UnorderedAccess: + case slang::SamplerState: + return true; + default: + return false; + } + } +}; + +class PostEmitMetadata : public ComBaseObject, public IPostEmitMetadata +{ +public: + SLANG_CLASS_GUID(0x6f82509f, 0xe48b, 0x4b83, { 0xa3, 0x84, 0x5d, 0x70, 0x83, 0x19, 0x83, 0xcc }) + + SLANG_COM_BASE_IUNKNOWN_ALL + + // ICastable + SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE; + + // IPostEmitMetadata + SLANG_NO_THROW virtual Slice<ShaderBindingRange> SLANG_MCALL getBindingRanges() SLANG_OVERRIDE; + + void* getInterface(const Guid& uuid); + void* getObject(const Guid& uuid); + + List<ShaderBindingRange> m_usedBindings; +}; + +} // namespace Slang + +#endif diff --git a/source/compiler-core/slang-artifact-associated.h b/source/compiler-core/slang-artifact-associated.h new file mode 100644 index 000000000..af47d2e59 --- /dev/null +++ b/source/compiler-core/slang-artifact-associated.h @@ -0,0 +1,79 @@ +// slang-artifact-associated.h +#ifndef SLANG_ARTIFACT_ASSOCIATED_H +#define SLANG_ARTIFACT_ASSOCIATED_H + +#include "slang-artifact.h" + +namespace Slang +{ + +/* Diagnostics. + +If there are raw diagnostics they can be associated to an artifact as (Kind::Text, Payload::Diagnostics) artifact */ +class IDiagnostics : public ICastable +{ +public: + SLANG_COM_INTERFACE(0x91f9b857, 0xcd6b, 0x45ca, { 0x8e, 0x3, 0x8f, 0xa3, 0x3c, 0x5c, 0xf0, 0x1a }); + + enum class Severity + { + Unknown, + Info, + Warning, + Error, + CountOf, + }; + enum class Stage + { + Compile, + Link, + }; + + struct Location + { + Int line = 0; ///< One indexed line number. 0 if not defined + Int column = 0; ///< One indexed *character (not byte)* column number. 0 if not defined + }; + + struct Diagnostic + { + Severity severity = Severity::Unknown; ///< The severity of error + Stage stage = Stage::Compile; ///< The stage the error came from + ZeroTerminatedCharSlice text; ///< The text of the error + ZeroTerminatedCharSlice code; ///< The compiler specific error code + ZeroTerminatedCharSlice filePath; ///< The path the error originated from + Location location; + }; + + /// Get the diagnostic at the index + SLANG_NO_THROW virtual const Diagnostic* SLANG_MCALL getAt(Index i) = 0; + /// Get the amount of diangostics + SLANG_NO_THROW virtual Count SLANG_MCALL getCount() = 0; + /// Add a diagnostic + SLANG_NO_THROW virtual void SLANG_MCALL add(const Diagnostic& diagnostic) = 0; + /// Remove the diagnostic at the index + SLANG_NO_THROW virtual void SLANG_MCALL removeAt(Index i) = 0; + + /// Get raw diagnostics information + SLANG_NO_THROW virtual ZeroTerminatedCharSlice SLANG_MCALL getRaw() = 0; + + /// Get the result for a compilation + SLANG_NO_THROW virtual SlangResult SLANG_MCALL getResult() = 0; + /// Set the result + SLANG_NO_THROW virtual void SLANG_MCALL setResult(SlangResult res) = 0; +}; + +struct ShaderBindingRange; + +class IPostEmitMetadata : public ICastable +{ +public: + SLANG_COM_INTERFACE(0x5d03bce9, 0xafb1, 0x4fc8, { 0xa4, 0x6f, 0x3c, 0xe0, 0x7b, 0x6, 0x1b, 0x1b }); + + /// Get the binding ranges + SLANG_NO_THROW virtual Slice<ShaderBindingRange> SLANG_MCALL getBindingRanges() = 0; +}; + +} // namespace Slang + +#endif diff --git a/source/compiler-core/slang-artifact-desc-util.cpp b/source/compiler-core/slang-artifact-desc-util.cpp index 2c2b177c2..490020a27 100644 --- a/source/compiler-core/slang-artifact-desc-util.cpp +++ b/source/compiler-core/slang-artifact-desc-util.cpp @@ -215,7 +215,6 @@ SLANG_HIERARCHICAL_ENUM(ArtifactKind, SLANG_ARTIFACT_KIND, SLANG_ARTIFACT_KIND_E x(SlangAST, AST) \ x(CompileResults, Base) \ x(MetaData, Base) \ - x(PostEmitMetadata, MetaData) \ x(DebugInfo, MetaData) \ x(Diagnostics, MetaData) @@ -466,66 +465,28 @@ static const KindExtension g_cpuKindExts[] = return getDescFromExtension(extension); } -/* static*/ UnownedStringSlice ArtifactDescUtil::getCpuExtensionForKind(Kind kind) +/* static*/ SlangResult ArtifactDescUtil::appendCpuExtensionForKind(Kind kind, StringBuilder& out) { for (const auto& kindExt : g_cpuKindExts) { if (kind == kindExt.kind) { - return kindExt.ext; + out << kindExt.ext; + return SLANG_OK; } } - return UnownedStringSlice(); + return SLANG_E_NOT_FOUND; } -UnownedStringSlice ArtifactDescUtil::getAssemblyExtensionForPayload(ArtifactPayload payload) +static UnownedStringSlice _getPayloadExtension(ArtifactPayload payload) { + typedef 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(); -} + /* Misc */ + case Payload::Unknown: return toSlice("unknown"); -UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& desc) -{ - 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) - { + /* Source types */ case Payload::HLSL: return toSlice("hlsl"); case Payload::GLSL: return toSlice("glsl"); @@ -537,24 +498,8 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des case Payload::CUDA: return toSlice("cu"); case Payload::Slang: return toSlice("slang"); - default: break; - } - } - default: break; - } - - if (ArtifactDescUtil::isCpuLikeTarget(desc)) - { - return getCpuExtensionForKind(desc.kind); - } - - if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike)) - { - switch (desc.payload) - { - case Payload::None: return UnownedStringSlice(); - case Payload::Unknown: return toSlice("unknown"); + /* Binary types */ case Payload::DXIL: return toSlice("dxil"); case Payload::DXBC: return toSlice("dxbc"); case Payload::SPIRV: return toSlice("spv"); @@ -563,20 +508,90 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des case Payload::LLVMIR: return toSlice("llvm-ir"); - case Payload::SlangIR: + case Payload::SlangIR: return toSlice("slang-ir"); + + case Payload::MetalAIR: return toSlice("air"); + + default: break; + } + return UnownedStringSlice(); +} + +SlangResult ArtifactDescUtil::appendDefaultExtension(const ArtifactDesc& desc, StringBuilder& out) +{ + switch (desc.kind) + { + case ArtifactKind::Library: { - return (desc.kind == ArtifactKind::Library) ? toSlice("slang-module") : toSlice("slang-ir"); + // Special cases + if (desc.payload == Payload::SlangIR) + { + out << toSlice("slang-module"); + return SLANG_OK; + } + else if (desc.payload == Payload::MetalAIR) + { + // https://developer.apple.com/documentation/metal/shader_libraries/building_a_library_with_metal_s_command-line_tools + out << toSlice("metallib"); + return SLANG_OK; + } + + break; } - case Payload::MetalAIR: + case ArtifactKind::Zip: { - // 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"); + out << toSlice("zip"); + return SLANG_OK; + } + case ArtifactKind::Riff: + { + out << toSlice("riff"); + return SLANG_OK; + } + case ArtifactKind::Assembly: + { + // Special case PTX, because it is assembly + if (desc.payload == Payload::PTX) + { + out << _getPayloadExtension(desc.payload); + return SLANG_OK; + } + + // We'll just use asm for all CPU assembly type + if (isDerivedFrom(desc.payload, ArtifactPayload::CPULike)) + { + out << toSlice("asm"); + return SLANG_OK; + } + + // Use the payload extension "-asm" + out << _getPayloadExtension(desc.payload); + out << toSlice("-asm"); + return SLANG_OK; + } + case ArtifactKind::Source: + { + out << _getPayloadExtension(desc.payload); + return SLANG_OK; } default: break; + } + + if (ArtifactDescUtil::isCpuLikeTarget(desc) && !isDerivedFrom(desc.payload, ArtifactPayload::Source)) + { + return appendCpuExtensionForKind(desc.kind, out); + } + else + { + auto slice = _getPayloadExtension(desc.payload); + if (slice.getLength()) + { + out << slice; + return SLANG_OK; } } - return UnownedStringSlice(); + return SLANG_E_NOT_FOUND; } /* static */String ArtifactDescUtil::getBaseNameFromPath(const ArtifactDesc& desc, const UnownedStringSlice& path) @@ -602,7 +617,10 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des // Strip any extension { - auto descExt = getDefaultExtension(desc); + StringBuilder descExt; + + appendDefaultExtension(desc, descExt); + // Strip the extension if it's a match if (descExt.getLength() && Path::getPathExt(name) == descExt) @@ -620,27 +638,17 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des return getBaseNameFromPath(desc, path); } -/* static */SlangResult ArtifactDescUtil::calcPathForDesc(const ArtifactDesc& desc, const UnownedStringSlice& basePath, StringBuilder& outPath) +/* static */SlangResult ArtifactDescUtil::calcNameForDesc(const ArtifactDesc& desc, const UnownedStringSlice& inBaseName, StringBuilder& outName) { - outPath.Clear(); - - UnownedStringSlice baseName; - - // Append the directory - Index pos = Path::findLastSeparatorIndex(basePath); - if (pos >= 0) - { - // Keep the stem including the delimiter - outPath.append(basePath.head(pos + 1)); - // Get the baseName - baseName = basePath.tail(pos + 1); - } + UnownedStringSlice baseName(inBaseName); + // If there is no basename, set one if (baseName.getLength() == 0) { baseName = toSlice("unknown"); } + // Prefix if (isCpuBinary(desc) && (desc.kind == ArtifactKind::SharedLibrary || desc.kind == ArtifactKind::Library)) @@ -648,21 +656,47 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des const bool isSharedLibraryPrefixPlatform = SLANG_LINUX_FAMILY || SLANG_APPLE_FAMILY; if (isSharedLibraryPrefixPlatform) { - outPath << "lib"; - outPath << baseName; + outName << "lib"; } } - // If there is an extension append it - const UnownedStringSlice ext = getDefaultExtension(desc); + // Output the basename + outName << baseName; - if (ext.getLength()) + // If there is an extension append it + StringBuilder ext; + if (SLANG_SUCCEEDED(appendDefaultExtension(desc, ext)) && ext.getLength() > 0) { - outPath.appendChar('.'); - outPath.append(ext); + outName.appendChar('.'); + outName.append(ext); } return SLANG_OK; } +/* static */SlangResult ArtifactDescUtil::calcPathForDesc(const ArtifactDesc& desc, const UnownedStringSlice& basePath, StringBuilder& outPath) +{ + outPath.Clear(); + + // Append the directory + Index pos = Path::findLastSeparatorIndex(basePath); + if (pos >= 0) + { + // Keep the stem including the delimiter + outPath.append(basePath.head(pos + 1)); + + StringBuilder buf; + const auto baseName = basePath.tail(pos + 1); + + SLANG_RETURN_ON_FAIL(calcNameForDesc(desc, baseName, buf)); + outPath.append(buf); + + return SLANG_OK; + } + else + { + return calcNameForDesc(desc, basePath, outPath); + } +} + } // namespace Slang diff --git a/source/compiler-core/slang-artifact-desc-util.h b/source/compiler-core/slang-artifact-desc-util.h index e3d1e6478..6f35cb500 100644 --- a/source/compiler-core/slang-artifact-desc-util.h +++ b/source/compiler-core/slang-artifact-desc-util.h @@ -50,9 +50,6 @@ struct ArtifactDescUtil /// True if the desc holds textual information static bool isText(const ArtifactDesc& desc); - /// Given an assembly type returns it's extension from the payload type - static UnownedStringSlice getAssemblyExtensionForPayload(ArtifactPayload payload); - /// True if artifact appears to be linkable static bool isLinkable(const ArtifactDesc& desc); @@ -62,11 +59,11 @@ struct ArtifactDescUtil /// Try to determine the desc from a path static ArtifactDesc getDescFromPath(const UnownedStringSlice& slice); - /// Gets the default file extension for the artifact type. Returns empty slice if not known - static UnownedStringSlice getDefaultExtension(const ArtifactDesc& desc); + /// Appends the default file extension for the artifact type. + static SlangResult appendDefaultExtension(const ArtifactDesc& desc, StringBuilder& out); /// Get the extension for CPU/Host for a kind - static UnownedStringSlice getCpuExtensionForKind(Kind kind); + static SlangResult appendCpuExtensionForKind(Kind kind, StringBuilder& out); /// Given a desc and a path returns the base name (stripped of prefix and extension) static String getBaseNameFromPath(const ArtifactDesc& desc, const UnownedStringSlice& path); @@ -78,9 +75,12 @@ struct ArtifactDescUtil static String getBaseName(const ArtifactDesc& desc, IFileArtifactRepresentation* fileRep); - /// Given a desc, and a basePath returns a suitable path for a entity of specified desc + /// Given a desc and a basePath returns a suitable path for a entity of specified desc static SlangResult calcPathForDesc(const ArtifactDesc& desc, const UnownedStringSlice& basePath, StringBuilder& outPath); + /// Given a desc and a baseName works out the the output file name + static SlangResult calcNameForDesc(const ArtifactDesc& desc, const UnownedStringSlice& baseName, StringBuilder& outName); + /// Given a target returns the ArtifactDesc static ArtifactDesc makeDescFromCompileTarget(SlangCompileTarget target); diff --git a/source/compiler-core/slang-artifact-handler-impl.cpp b/source/compiler-core/slang-artifact-handler-impl.cpp index c93a4907b..f324a1d43 100644 --- a/source/compiler-core/slang-artifact-handler-impl.cpp +++ b/source/compiler-core/slang-artifact-handler-impl.cpp @@ -182,23 +182,21 @@ SlangResult DefaultArtifactHandler::expandChildren(IArtifactContainer* container return SLANG_E_NOT_IMPLEMENTED; } - - SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable) { + const auto reps = artifact->getRepresentations(); + // See if we already have a rep of this type + for (ICastable* rep : reps) { - for (ICastable* rep : artifact->getRepresentations()) + if (rep->castAs(guid)) { - if (rep->castAs(guid)) - { - rep->addRef(); - *outCastable = rep; - return SLANG_OK; - } + rep->addRef(); + *outCastable = rep; + return SLANG_OK; } } - + // TODO(JS): Temporary whilst DownstreamCompileResult is // Special handling for DownstreamCompileResult if (auto downstreamResult = findRepresentation<DownstreamCompileResult>(artifact)) @@ -217,14 +215,23 @@ SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifac } } - // Normal construction - if (guid == ISlangBlob::getTypeGuid()) + // We can ask each representation if they can do the conversion to the type, if they can we just use that + for (ICastable* castable : reps) { - ComPtr<ISlangBlob> blob; - SLANG_RETURN_ON_FAIL(_loadBlob(artifact, keep, blob.writeRef())); - return _addRepresentation(artifact, keep, blob, outCastable); + if (auto rep = as<IArtifactRepresentation>(castable)) + { + ComPtr<ICastable> created; + if (SLANG_SUCCEEDED(rep->createRepresentation(guid, created.writeRef()))) + { + SLANG_ASSERT(created); + // Add the rep + return _addRepresentation(artifact, keep, created, outCastable); + } + } } - else if (guid == ISlangSharedLibrary::getTypeGuid()) + + // Special case shared library + if (guid == ISlangSharedLibrary::getTypeGuid()) { ComPtr<ISlangSharedLibrary> sharedLib; SLANG_RETURN_ON_FAIL(_loadSharedLibrary(artifact, keep, sharedLib.writeRef())); @@ -348,33 +355,4 @@ SlangResult DefaultArtifactHandler::_loadSharedLibrary(IArtifact* artifact, Arti return SLANG_FAIL; } -SlangResult DefaultArtifactHandler::_loadBlob(IArtifact* artifact, ArtifactKeep keep, ISlangBlob** outBlob) -{ - SLANG_UNUSED(keep); - - ComPtr<ISlangBlob> blob; - - // Look for a representation that we can serialize into a blob - for (auto rep : artifact->getRepresentations()) - { - if (auto artifactRep = as<IArtifactRepresentation>(rep)) - { - SlangResult res = artifactRep->writeToBlob(blob.writeRef()); - if (SLANG_SUCCEEDED(res) && blob) - { - break; - } - } - } - - // Wasn't able to construct - if (!blob) - { - return SLANG_E_NOT_FOUND; - } - - *outBlob = blob.detach(); - return SLANG_OK; -} - } // namespace Slang diff --git a/source/compiler-core/slang-artifact-handler-impl.h b/source/compiler-core/slang-artifact-handler-impl.h index c7861b598..f49fa4230 100644 --- a/source/compiler-core/slang-artifact-handler-impl.h +++ b/source/compiler-core/slang-artifact-handler-impl.h @@ -29,8 +29,7 @@ public: protected: SlangResult _loadSharedLibrary(IArtifact* artifact, ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary); - SlangResult _loadBlob(IArtifact* artifact, ArtifactKeep keep, ISlangBlob** outBlob); - + void* getInterface(const Guid& uuid); void* getObject(const Guid& uuid); diff --git a/source/compiler-core/slang-artifact-helper.cpp b/source/compiler-core/slang-artifact-helper.cpp index ce6fab7d9..39e81b668 100644 --- a/source/compiler-core/slang-artifact-helper.cpp +++ b/source/compiler-core/slang-artifact-helper.cpp @@ -5,6 +5,7 @@ #include "slang-artifact-representation-impl.h" #include "slang-artifact-desc-util.h" +#include "slang-artifact-util.h" #include "../core/slang-castable-list-impl.h" @@ -14,7 +15,6 @@ namespace Slang { - /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! DefaultArtifactHelper !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ /* static */DefaultArtifactHelper DefaultArtifactHelper::g_singleton; @@ -121,4 +121,9 @@ ArtifactDesc DefaultArtifactHelper::makeDescFromCompileTarget(SlangCompileTarget return ArtifactDescUtil::makeDescFromCompileTarget(target); } +void DefaultArtifactHelper::getCastable(ISlangUnknown* unk, ICastable** outCastable) +{ + *outCastable = CastableUtil::getCastable(unk).detach(); +} + } // namespace Slang diff --git a/source/compiler-core/slang-artifact-helper.h b/source/compiler-core/slang-artifact-helper.h index 41bf0f2c9..6a07c16ee 100644 --- a/source/compiler-core/slang-artifact-helper.h +++ b/source/compiler-core/slang-artifact-helper.h @@ -14,27 +14,43 @@ class IArtifactHelper : public ICastable { SLANG_COM_INTERFACE(0x882b25d7, 0xe300, 0x4b20, { 0xbe, 0xb, 0x26, 0xd2, 0x52, 0x3e, 0x70, 0x20 }) + /// Create an artifact virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifact(const ArtifactDesc& desc, const char* name, IArtifact** outArtifact) = 0; + /// Create a container with desc, and specified name. name can be passed as nullptr for no name virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifactContainer(const ArtifactDesc& desc, const char* name, IArtifactContainer** outArtifactContainer) = 0; + /// Get the parent to a kind virtual SLANG_NO_THROW ArtifactKind SLANG_MCALL getKindParent(ArtifactKind kind) = 0; + /// Get the name of a kind virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getKindName(ArtifactKind kind) = 0; + /// Returns true if kind is derived from base virtual SLANG_NO_THROW bool SLANG_MCALL isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) = 0; + /// Get the parent payload for payload virtual SLANG_NO_THROW ArtifactPayload SLANG_MCALL getPayloadParent(ArtifactPayload payload) = 0; + /// Get the payload name text virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getPayloadName(ArtifactPayload payload) = 0; + /// Returns true if payload is derived from base virtual SLANG_NO_THROW bool SLANG_MCALL isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) = 0; + /// Get the parent type of a style virtual SLANG_NO_THROW ArtifactStyle SLANG_MCALL getStyleParent(ArtifactStyle style) = 0; + /// Get text name for a style virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) = 0; + /// Returns true if style is derived from base virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) = 0; + /// Create a lock file, the path of which can be used to generate other temporary files virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const char* nameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile) = 0; /// Given a desc and a basePath returns a suitable name virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) = 0; + /// Given a compile target return the equivalent desc virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescFromCompileTarget(SlangCompileTarget target) = 0; + + /// Given an interface returns as a castable interface. This might just cast unk into ICastable, or wrap it such that it uses the castable interface + virtual SLANG_NO_THROW void SLANG_MCALL getCastable(ISlangUnknown* unk, ICastable** outCastable) = 0; }; class DefaultArtifactHelper : public IArtifactHelper @@ -70,6 +86,8 @@ public: virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescFromCompileTarget(SlangCompileTarget target) SLANG_OVERRIDE; + virtual SLANG_NO_THROW void SLANG_MCALL getCastable(ISlangUnknown* unk, ICastable** outCastable) SLANG_OVERRIDE; + static IArtifactHelper* getSingleton() { return &g_singleton; } protected: diff --git a/source/compiler-core/slang-artifact-impl.h b/source/compiler-core/slang-artifact-impl.h index e0a976929..a6e99a4f7 100644 --- a/source/compiler-core/slang-artifact-impl.h +++ b/source/compiler-core/slang-artifact-impl.h @@ -47,7 +47,8 @@ public: virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadSharedLibrary(ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary) SLANG_OVERRIDE; virtual SLANG_NO_THROW const char* SLANG_MCALL getName() SLANG_OVERRIDE { return m_name.getBuffer(); } - + virtual SLANG_NO_THROW void SLANG_MCALL setName(const char* name) SLANG_OVERRIDE { m_name = name; } + virtual SLANG_NO_THROW void SLANG_MCALL addAssociated(ICastable* castable) SLANG_OVERRIDE; virtual SLANG_NO_THROW void* SLANG_MCALL findAssociated(const Guid& unk) SLANG_OVERRIDE; virtual SLANG_NO_THROW ICastableList* SLANG_MCALL getAssociated() SLANG_OVERRIDE; diff --git a/source/compiler-core/slang-artifact-representation-impl.cpp b/source/compiler-core/slang-artifact-representation-impl.cpp index 32ec055d8..802f2c1dd 100644 --- a/source/compiler-core/slang-artifact-representation-impl.cpp +++ b/source/compiler-core/slang-artifact-representation-impl.cpp @@ -9,6 +9,8 @@ #include "slang-artifact-util.h" +#include "../core/slang-castable-list-impl.h" + namespace Slang { /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FileArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!!!!!! */ @@ -45,16 +47,23 @@ void* FileArtifactRepresentation::castAs(const Guid& guid) return getObject(guid); } -SlangResult FileArtifactRepresentation::writeToBlob(ISlangBlob** blob) +SlangResult FileArtifactRepresentation::createRepresentation(const Guid& typeGuid, ICastable** outCastable) { - if (m_kind == Kind::NameOnly) + // We can convert into a blob only, and only if we have a path + // If it's referenced by a name only, it's a file that *can't* be loaded as a blob in general. + if (typeGuid != ISlangBlob::getTypeGuid() || + m_kind == Kind::NameOnly) { - // If it's referenced by a name only, it's a file that *can't* be loaded as a blob in general. return SLANG_E_NOT_AVAILABLE; } + ComPtr<ISlangBlob> blob; + auto fileSystem = _getFileSystem(); - return fileSystem->loadFile(m_path.getBuffer(), blob); + SLANG_RETURN_ON_FAIL(fileSystem->loadFile(m_path.getBuffer(), blob.writeRef())); + + *outCastable = CastableUtil::getCastable(blob).detach(); + return SLANG_OK; } bool FileArtifactRepresentation::exists() @@ -94,105 +103,6 @@ FileArtifactRepresentation::~FileArtifactRepresentation() } } -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DiagnosticsArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -void* DiagnosticsArtifactRepresentation::getInterface(const Guid& guid) -{ - if (guid == ISlangUnknown::getTypeGuid() || - guid == ICastable::getTypeGuid() || - guid == IArtifactRepresentation::getTypeGuid() || - guid == IDiagnosticsArtifactRepresentation::getTypeGuid()) - { - return static_cast<DiagnosticsArtifactRepresentation*>(this); - } - return nullptr; -} - -void* DiagnosticsArtifactRepresentation::getObject(const Guid& guid) -{ - SLANG_UNUSED(guid); - return nullptr; -} - -void* DiagnosticsArtifactRepresentation::castAs(const Guid& guid) -{ - if (auto intf = getInterface(guid)) - { - return intf; - } - return getObject(guid); -} - -SlangResult DiagnosticsArtifactRepresentation::writeToBlob(ISlangBlob** outBlob) -{ - *outBlob = nullptr; - return SLANG_E_NOT_IMPLEMENTED; -} - -bool DiagnosticsArtifactRepresentation::exists() -{ - return true; -} - -ZeroTerminatedCharSlice DiagnosticsArtifactRepresentation::_allocateSlice(const Slice<char>& in) -{ - if (in.count == 0) - { - return ZeroTerminatedCharSlice("", 0); - } - const char* dst = m_arena.allocateString(in.data, in.count); - return ZeroTerminatedCharSlice(dst, in.count); -} - -void DiagnosticsArtifactRepresentation::add(const Diagnostic& inDiagnostic) -{ - Diagnostic diagnostic(inDiagnostic); - - diagnostic.text = _allocateSlice(inDiagnostic.text); - diagnostic.code = _allocateSlice(inDiagnostic.code); - diagnostic.filePath = _allocateSlice(inDiagnostic.filePath); - - m_diagnostics.add(diagnostic); -} - -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PostEmitMetadataArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -void* PostEmitMetadataArtifactRepresentation::getInterface(const Guid& guid) -{ - if (guid == ISlangUnknown::getTypeGuid() || - guid == ICastable::getTypeGuid() || - guid == IArtifactRepresentation::getTypeGuid() || - guid == IPostEmitMetadataArtifactRepresentation::getTypeGuid()) - { - return static_cast<IPostEmitMetadataArtifactRepresentation*>(this); - } - return nullptr; -} - -void* PostEmitMetadataArtifactRepresentation::getObject(const Guid& uuid) -{ - if (uuid == getTypeGuid()) - { - return this; - } - return nullptr; -} - -void* PostEmitMetadataArtifactRepresentation::castAs(const Guid& guid) -{ - if (auto ptr = getInterface(guid)) - { - return ptr; - } - return getObject(guid); -} - - -Slice<ShaderBindingRange> PostEmitMetadataArtifactRepresentation::getBindingRanges() -{ - return Slice<ShaderBindingRange>(m_metadata.usedBindings.getBuffer(), m_metadata.usedBindings.getCount()); -} - /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PostEmitMetadataArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!!!!!! */ void* ObjectArtifactRepresentation::castAs(const Guid& guid) diff --git a/source/compiler-core/slang-artifact-representation-impl.h b/source/compiler-core/slang-artifact-representation-impl.h index fb2e37c76..5e6716641 100644 --- a/source/compiler-core/slang-artifact-representation-impl.h +++ b/source/compiler-core/slang-artifact-representation-impl.h @@ -25,7 +25,7 @@ public: SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE; // IArtifactRepresentation - SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) SLANG_OVERRIDE; + SLANG_NO_THROW SlangResult SLANG_MCALL createRepresentation(const Guid& typeGuid, ICastable** outCastable) SLANG_OVERRIDE; SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE; // IFileArtifactRepresentation @@ -60,142 +60,6 @@ protected: ComPtr<ISlangMutableFileSystem> m_fileSystem; }; -class DiagnosticsArtifactRepresentation : public ComBaseObject, public IDiagnosticsArtifactRepresentation -{ -public: - SLANG_COM_BASE_IUNKNOWN_ALL - - // ICastable - SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE; - // IArtifactRepresentation - SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) SLANG_OVERRIDE; - SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE; - // IDiagnosticArtifactRepresentation - SLANG_NO_THROW virtual const Diagnostic* SLANG_MCALL getAt(Index i) SLANG_OVERRIDE { return &m_diagnostics[i]; } - SLANG_NO_THROW virtual Count SLANG_MCALL getCount() SLANG_OVERRIDE { return m_diagnostics.getCount(); } - SLANG_NO_THROW virtual void SLANG_MCALL add(const Diagnostic& diagnostic) SLANG_OVERRIDE; - SLANG_NO_THROW virtual void SLANG_MCALL removeAt(Index i) SLANG_OVERRIDE { m_diagnostics.removeAt(i); } - SLANG_NO_THROW virtual SlangResult SLANG_MCALL getResult() SLANG_OVERRIDE { return m_result; } - SLANG_NO_THROW virtual void SLANG_MCALL setResult(SlangResult res) SLANG_OVERRIDE { m_result = res; } - - DiagnosticsArtifactRepresentation(): - m_arena(1024) - { - } - -protected: - void* getInterface(const Guid& uuid); - void* getObject(const Guid& uuid); - - ZeroTerminatedCharSlice _allocateSlice(const Slice<char>& in); - - // We could consider storing paths, codes in StringSlicePool, but for now we just allocate all 'string type things' - // in the arena. - MemoryArena m_arena; - - List<Diagnostic> m_diagnostics; - SlangResult m_result = SLANG_OK; - - ZeroTerminatedCharSlice m_raw; -}; - -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! PostEmitMetadataArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!!!!! */ - -struct ShaderBindingRange -{ - slang::ParameterCategory category = slang::ParameterCategory::None; - UInt spaceIndex = 0; - UInt registerIndex = 0; - UInt registerCount = 0; // 0 for unsized - - bool isInfinite() const - { - return registerCount == 0; - } - - bool containsBinding(slang::ParameterCategory _category, UInt _spaceIndex, UInt _registerIndex) const - { - return category == _category - && spaceIndex == _spaceIndex - && registerIndex <= _registerIndex - && (isInfinite() || registerCount + registerIndex > _registerIndex); - } - - bool intersectsWith(const ShaderBindingRange& other) const - { - if (category != other.category || spaceIndex != other.spaceIndex) - return false; - - const bool leftIntersection = (registerIndex < other.registerIndex + other.registerCount) || other.isInfinite(); - const bool rightIntersection = (other.registerIndex < registerIndex + registerCount) || isInfinite(); - - return leftIntersection && rightIntersection; - } - - bool adjacentTo(const ShaderBindingRange& other) const - { - if (category != other.category || spaceIndex != other.spaceIndex) - return false; - - const bool leftIntersection = (registerIndex <= other.registerIndex + other.registerCount) || other.isInfinite(); - const bool rightIntersection = (other.registerIndex <= registerIndex + registerCount) || isInfinite(); - - return leftIntersection && rightIntersection; - } - - void mergeWith(const ShaderBindingRange other) - { - UInt newRegisterIndex = Math::Min(registerIndex, other.registerIndex); - - if (other.isInfinite()) - registerCount = 0; - else if (!isInfinite()) - registerCount = Math::Max(registerIndex + registerCount, other.registerIndex + other.registerCount) - newRegisterIndex; - - registerIndex = newRegisterIndex; - } - - static bool isUsageTracked(slang::ParameterCategory category) - { - switch (category) - { - case slang::ConstantBuffer: - case slang::ShaderResource: - case slang::UnorderedAccess: - case slang::SamplerState: - return true; - default: - return false; - } - } -}; - -struct PostEmitMetadata -{ - List<ShaderBindingRange> usedBindings; -}; - -class PostEmitMetadataArtifactRepresentation : public ComBaseObject, public IPostEmitMetadataArtifactRepresentation -{ -public: - SLANG_CLASS_GUID(0x6f82509f, 0xe48b, 0x4b83, { 0xa3, 0x84, 0x5d, 0x70, 0x83, 0x19, 0x83, 0xcc }) - - SLANG_COM_BASE_IUNKNOWN_ALL - - // ICastable - SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE; - // IArtifactRepresentation - SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** outBlob) SLANG_OVERRIDE { SLANG_UNUSED(outBlob); return SLANG_E_NOT_AVAILABLE; } - SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE { return true; } - // IPostEmitMetadataArtifactRepresentation - SLANG_NO_THROW virtual Slice<ShaderBindingRange> SLANG_MCALL getBindingRanges() SLANG_OVERRIDE; - - void* getInterface(const Guid& uuid); - void* getObject(const Guid& uuid); - - PostEmitMetadata m_metadata; -}; - /* This allows wrapping any object to be an artifact representation. NOTE! Only allows casting from a single guid. Passing a RefObject across an ABI bounday remains risky! @@ -210,7 +74,7 @@ public: // ICastable SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE; // IArtifactRepresentation - SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** outBlob) SLANG_OVERRIDE { SLANG_UNUSED(outBlob); return SLANG_E_NOT_AVAILABLE; } + SLANG_NO_THROW SlangResult SLANG_MCALL createRepresentation(const Guid& guid, ICastable** outCastable) SLANG_OVERRIDE { SLANG_UNUSED(guid); SLANG_UNUSED(outCastable); return SLANG_E_NOT_AVAILABLE; } SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE { return m_object; } ObjectArtifactRepresentation(const Guid& typeGuid, RefObject* obj): diff --git a/source/compiler-core/slang-artifact-representation.h b/source/compiler-core/slang-artifact-representation.h index 43a975d3c..466494052 100644 --- a/source/compiler-core/slang-artifact-representation.h +++ b/source/compiler-core/slang-artifact-representation.h @@ -40,71 +40,6 @@ public: virtual SLANG_NO_THROW IFileArtifactRepresentation* SLANG_MCALL getLockFile() = 0; }; -/* Diagnostics. - -If there are raw diagnostics they can be associated to an artifact as (Kind::Text, Payload::Diagnostics) artifact */ -class IDiagnosticsArtifactRepresentation : public IArtifactRepresentation -{ -public: - SLANG_COM_INTERFACE(0x91f9b857, 0xcd6b, 0x45ca, { 0x8e, 0x3, 0x8f, 0xa3, 0x3c, 0x5c, 0xf0, 0x1a }); - - enum class Severity - { - Unknown, - Info, - Warning, - Error, - CountOf, - }; - enum class Stage - { - Compile, - Link, - }; - - struct Location - { - Int line = 0; ///< One indexed line number. 0 if not defined - Int column = 0; ///< One indexed *character (not byte)* column number. 0 if not defined - }; - - struct Diagnostic - { - Severity severity = Severity::Unknown; ///< The severity of error - Stage stage = Stage::Compile; ///< The stage the error came from - ZeroTerminatedCharSlice text; ///< The text of the error - ZeroTerminatedCharSlice code; ///< The compiler specific error code - ZeroTerminatedCharSlice filePath; ///< The path the error originated from - Location location; - }; - - /// Get the diagnostic at the index - SLANG_NO_THROW virtual const Diagnostic* SLANG_MCALL getAt(Index i) = 0; - /// Get the amount of diangostics - SLANG_NO_THROW virtual Count SLANG_MCALL getCount() = 0; - /// Add a diagnostic - SLANG_NO_THROW virtual void SLANG_MCALL add(const Diagnostic& diagnostic) = 0; - /// Remove the diagnostic at the index - SLANG_NO_THROW virtual void SLANG_MCALL removeAt(Index i) = 0; - - /// Get the result for a compilation - SLANG_NO_THROW virtual SlangResult SLANG_MCALL getResult() = 0; - /// Set the result - SLANG_NO_THROW virtual void SLANG_MCALL setResult(SlangResult res) = 0; -}; - -struct ShaderBindingRange; - -class IPostEmitMetadataArtifactRepresentation : public IArtifactRepresentation -{ -public: - SLANG_COM_INTERFACE(0x5d03bce9, 0xafb1, 0x4fc8, { 0xa4, 0x6f, 0x3c, 0xe0, 0x7b, 0x6, 0x1b, 0x1b }); - - /// Get the binding ranges - SLANG_NO_THROW virtual Slice<ShaderBindingRange> SLANG_MCALL getBindingRanges() = 0; -}; - - } // namespace Slang #endif diff --git a/source/compiler-core/slang-artifact-util.cpp b/source/compiler-core/slang-artifact-util.cpp index f93924afb..fb3157522 100644 --- a/source/compiler-core/slang-artifact-util.cpp +++ b/source/compiler-core/slang-artifact-util.cpp @@ -23,10 +23,15 @@ namespace Slang { return ArtifactContainer::create(ArtifactDesc::make(ArtifactKind::Container, ArtifactPayload::CompileResults)); } -/* static */ComPtr<IArtifact> ArtifactUtil::createArtifactForCompileTarget(SlangCompileTarget target) +/* static */ComPtr<IArtifact> ArtifactUtil::createArtifact(const ArtifactDesc& desc, const char* name) { - auto desc = ArtifactDescUtil::makeDescFromCompileTarget(target); + auto artifact = createArtifact(desc); + artifact->setName(name); + return artifact; +} +/* static */ComPtr<IArtifact> ArtifactUtil::createArtifact(const ArtifactDesc& desc) +{ if (isDerivedFrom(desc.kind, ArtifactKind::Container)) { auto container = ArtifactContainer::create(desc); @@ -41,6 +46,12 @@ namespace Slang { } } +/* static */ComPtr<IArtifact> ArtifactUtil::createArtifactForCompileTarget(SlangCompileTarget target) +{ + auto desc = ArtifactDescUtil::makeDescFromCompileTarget(target); + return createArtifact(desc); +} + /* static */bool ArtifactUtil::isSignificant(IArtifact* artifact, void* data) { SLANG_UNUSED(data); @@ -79,6 +90,11 @@ namespace Slang { return true; } +/* static */IArtifact* ArtifactUtil::findSignificant(IArtifact* artifact) +{ + return artifact->findArtifactByPredicate(IArtifact::FindStyle::SelfOrChildren, &ArtifactUtil::isSignificant, nullptr); +} + /* static */String ArtifactUtil::getBaseName(IArtifact* artifact) { if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact)) diff --git a/source/compiler-core/slang-artifact-util.h b/source/compiler-core/slang-artifact-util.h index 541a1f058..c4768a7b8 100644 --- a/source/compiler-core/slang-artifact-util.h +++ b/source/compiler-core/slang-artifact-util.h @@ -30,10 +30,14 @@ struct ArtifactUtil /// Creates an empty artifact for a type static ComPtr<IArtifact> createArtifactForCompileTarget(SlangCompileTarget target); + /// Create an artifact + static ComPtr<IArtifact> createArtifact(const ArtifactDesc& desc, const char* name); + static ComPtr<IArtifact> createArtifact(const ArtifactDesc& desc); + /// Returns true if an artifact is 'significant' static bool isSignificant(IArtifact* artifact, void* data = nullptr); /// Find a significant artifact - static IArtifact* findSignificant(IArtifact* artifact) { return artifact->findArtifactByPredicate(IArtifact::FindStyle::SelfOrChildren, &isSignificant, nullptr); } + static IArtifact* findSignificant(IArtifact* artifact); }; } // namespace Slang diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h index bde7f9a08..c54282c09 100644 --- a/source/compiler-core/slang-artifact.h +++ b/source/compiler-core/slang-artifact.h @@ -140,7 +140,6 @@ enum class ArtifactPayload : uint8_t DebugInfo, ///< Debugging information Diagnostics, ///< Diagnostics information - PostEmitMetadata, ///< Post emit meta data CountOf, }; @@ -343,6 +342,8 @@ public: /// Get the name of the artifact. This can be empty. virtual SLANG_NO_THROW const char* SLANG_MCALL getName() = 0; + /// Set the name associated with the artifact + virtual SLANG_NO_THROW void SLANG_MCALL setName(const char* name) = 0; /// Add data associated with this artifact virtual SLANG_NO_THROW void SLANG_MCALL addAssociated(ICastable* castable) = 0; @@ -411,6 +412,12 @@ SLANG_FORCE_INLINE T* findRepresentation(IArtifact* artifact) return reinterpret_cast<T*>(artifact->findRepresentation(T::getTypeGuid())); } +template <typename T> +SLANG_FORCE_INLINE T* findAssociated(IArtifact* artifact) +{ + return reinterpret_cast<T*>(artifact->findAssociated(T::getTypeGuid())); +} + /* The IArtifactRepresentation interface represents a single representation that can be part of an artifact. It's special in so far as @@ -421,9 +428,10 @@ class IArtifactRepresentation : public ICastable { SLANG_COM_INTERFACE(0x311457a8, 0x1796, 0x4ebb, { 0x9a, 0xfc, 0x46, 0xa5, 0x44, 0xc7, 0x6e, 0xa9 }) - /// Convert the instance into a serializable blob. + /// Create a representation of the specified typeGuid interface. + /// Calling castAs on the castable will return the specific type /// Returns SLANG_E_NOT_IMPLEMENTED if an implementation doesn't implement - virtual SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) = 0; + virtual SLANG_NO_THROW SlangResult SLANG_MCALL createRepresentation(const Guid& typeGuid, ICastable** outCastable) = 0; /// Returns true if this representation exists and is available for use. virtual SLANG_NO_THROW bool SLANG_MCALL exists() = 0; |
