summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-09-30 12:50:30 -0700
committerGitHub <noreply@github.com>2024-09-30 12:50:30 -0700
commit15d1c6c51c5f24663d2567d7e56da62a2bca1c22 (patch)
tree78733e327dca1421f39ecff4073463d74500c14c
parentbc11579dd998224bcb429d88aeb07d49e2217a35 (diff)
Add COM API for querying metadata. (#5168)
* Add COM API for querying metadata. * Fix tests. * fix test.
-rw-r--r--include/slang.h27
-rw-r--r--source/compiler-core/slang-artifact-associated-impl.cpp20
-rw-r--r--source/compiler-core/slang-artifact-associated-impl.h8
-rw-r--r--source/compiler-core/slang-artifact-associated.h2
-rw-r--r--source/slang-record-replay/record/slang-component-type.cpp19
-rw-r--r--source/slang-record-replay/record/slang-component-type.h9
-rw-r--r--source/slang-record-replay/record/slang-entrypoint.h17
-rw-r--r--source/slang-record-replay/record/slang-module.h17
-rw-r--r--source/slang-record-replay/record/slang-type-conformance.h17
-rwxr-xr-xsource/slang/slang-compiler.h65
-rw-r--r--source/slang/slang-parameter-binding.cpp11
-rw-r--r--source/slang/slang.cpp97
-rw-r--r--tests/bindings/hlsl-to-vulkan-combined.hlsl.expected4
-rw-r--r--tests/bindings/hlsl-to-vulkan-global.hlsl.expected4
-rw-r--r--tests/slang-extension/dynamic-resource-gl.slang.1.expected10
-rw-r--r--tools/slang-unit-test/unit-test-image-format-reflection.cpp2
-rw-r--r--tools/slang-unit-test/unit-test-parameter-usage-reflection.cpp68
17 files changed, 360 insertions, 37 deletions
diff --git a/include/slang.h b/include/slang.h
index 8e42632ff..81b3ac1cb 100644
--- a/include/slang.h
+++ b/include/slang.h
@@ -5280,6 +5280,22 @@ namespace slang
#define SLANG_UUID_ISession ISession::getTypeGuid()
+ struct IMetadata : public ISlangCastable
+ {
+ SLANG_COM_INTERFACE(0x8044a8a3, 0xddc0, 0x4b7f, { 0xaf, 0x8e, 0x2, 0x6e, 0x90, 0x5d, 0x73, 0x32 })
+
+ /*
+ Returns whether a resource parameter at the specifieid binding location is actually being used
+ in the compiled shader.
+ */
+ virtual SlangResult isParameterLocationUsed(
+ SlangParameterCategory category, // is this a `t` register? `s` register?
+ SlangUInt spaceIndex, // `space` for D3D12, `set` for Vulkan
+ SlangUInt registerIndex, // `register` for D3D12, `binding` for Vulkan
+ bool& outUsed) = 0;
+ };
+ #define SLANG_UUID_IMetadata IMetadata::getTypeGuid()
+
/** A component type is a unit of shader code layout, reflection, and linking.
A component type is a unit of shader code that can be included into
@@ -5492,6 +5508,17 @@ namespace slang
SlangInt targetIndex,
IBlob** outCode,
IBlob** outDiagnostics = nullptr) = 0;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL getTargetMetadata(
+ SlangInt targetIndex,
+ IMetadata** outMetadata,
+ IBlob** outDiagnostics = nullptr) = 0;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointMetadata(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ IMetadata** outMetadata,
+ IBlob** outDiagnostics = nullptr) = 0;
};
#define SLANG_UUID_IComponentType IComponentType::getTypeGuid()
diff --git a/source/compiler-core/slang-artifact-associated-impl.cpp b/source/compiler-core/slang-artifact-associated-impl.cpp
index f29c0f596..07d69bf8e 100644
--- a/source/compiler-core/slang-artifact-associated-impl.cpp
+++ b/source/compiler-core/slang-artifact-associated-impl.cpp
@@ -313,4 +313,24 @@ Slice<String> ArtifactPostEmitMetadata::getExportedFunctionMangledNames()
return Slice<String>(m_exportedFunctionMangledNames.getBuffer(), m_exportedFunctionMangledNames.getCount());
}
+SlangResult ArtifactPostEmitMetadata::isParameterLocationUsed(
+ SlangParameterCategory category,
+ SlangUInt spaceIndex,
+ SlangUInt registerIndex,
+ bool& outUsed)
+{
+ for (const auto& range : getUsedBindingRanges())
+ {
+ if (range.containsBinding((slang::ParameterCategory)category, spaceIndex, registerIndex))
+ {
+ outUsed = true;
+ return SLANG_OK;
+ }
+ }
+
+ outUsed = false;
+ return SLANG_OK;
+}
+
+
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-associated-impl.h b/source/compiler-core/slang-artifact-associated-impl.h
index a6e323b0a..d11498604 100644
--- a/source/compiler-core/slang-artifact-associated-impl.h
+++ b/source/compiler-core/slang-artifact-associated-impl.h
@@ -134,6 +134,7 @@ struct ShaderBindingRange
case slang::ShaderResource:
case slang::UnorderedAccess:
case slang::SamplerState:
+ case slang::DescriptorTableSlot:
return true;
default:
return false;
@@ -157,6 +158,13 @@ public:
SLANG_NO_THROW virtual Slice<ShaderBindingRange> SLANG_MCALL getUsedBindingRanges() SLANG_OVERRIDE;
SLANG_NO_THROW virtual Slice<String> SLANG_MCALL getExportedFunctionMangledNames() SLANG_OVERRIDE;
+ // IMetadata
+ SLANG_NO_THROW virtual SlangResult SLANG_MCALL isParameterLocationUsed(
+ SlangParameterCategory category, // is this a `t` register? `s` register?
+ SlangUInt spaceIndex, // `space` for D3D12, `set` for Vulkan
+ SlangUInt registerIndex, // `register` for D3D12, `binding` for Vulkan
+ bool& outUsed) SLANG_OVERRIDE;
+
void* getInterface(const Guid& uuid);
void* getObject(const Guid& uuid);
diff --git a/source/compiler-core/slang-artifact-associated.h b/source/compiler-core/slang-artifact-associated.h
index 766494271..91ae09aab 100644
--- a/source/compiler-core/slang-artifact-associated.h
+++ b/source/compiler-core/slang-artifact-associated.h
@@ -117,7 +117,7 @@ public:
struct ShaderBindingRange;
-class IArtifactPostEmitMetadata : public ICastable
+class IArtifactPostEmitMetadata : public slang::IMetadata
{
public:
SLANG_COM_INTERFACE(0x5d03bce9, 0xafb1, 0x4fc8, { 0xa4, 0x6f, 0x3c, 0xe0, 0x7b, 0x6, 0x1b, 0x1b });
diff --git a/source/slang-record-replay/record/slang-component-type.cpp b/source/slang-record-replay/record/slang-component-type.cpp
index 5ebf73574..bc38acfae 100644
--- a/source/slang-record-replay/record/slang-component-type.cpp
+++ b/source/slang-record-replay/record/slang-component-type.cpp
@@ -127,6 +127,25 @@ namespace SlangRecord
return res;
}
+ SLANG_NO_THROW SlangResult SLANG_MCALL IComponentTypeRecorder::getEntryPointMetadata(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics)
+ {
+ // No need to record this call.
+ return m_actualComponentType->getEntryPointMetadata(entryPointIndex, targetIndex, outMetadata, outDiagnostics);
+ }
+
+ SLANG_NO_THROW SlangResult SLANG_MCALL IComponentTypeRecorder::getTargetMetadata(
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics)
+ {
+ // No need to record this call.
+ return m_actualComponentType->getTargetMetadata(targetIndex, outMetadata, outDiagnostics);
+ }
+
SLANG_NO_THROW SlangResult IComponentTypeRecorder::getResultAsFileSystem(
SlangInt entryPointIndex,
SlangInt targetIndex,
diff --git a/source/slang-record-replay/record/slang-component-type.h b/source/slang-record-replay/record/slang-component-type.h
index 110733044..52e07d9c0 100644
--- a/source/slang-record-replay/record/slang-component-type.h
+++ b/source/slang-record-replay/record/slang-component-type.h
@@ -61,6 +61,15 @@ namespace SlangRecord
SlangInt targetIndex,
slang::IBlob** outCode,
slang::IBlob** outDiagnostics = nullptr) override;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointMetadata(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) override;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL getTargetMetadata(
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics = nullptr) override;
protected:
virtual ApiClassId getClassId() = 0;
virtual SessionRecorder* getSessionRecorder() = 0;
diff --git a/source/slang-record-replay/record/slang-entrypoint.h b/source/slang-record-replay/record/slang-entrypoint.h
index abe2dc9c0..29a3329fe 100644
--- a/source/slang-record-replay/record/slang-entrypoint.h
+++ b/source/slang-record-replay/record/slang-entrypoint.h
@@ -69,6 +69,23 @@ namespace SlangRecord
return Super::getTargetCode(targetIndex, outCode, outDiagnostics);
}
+ SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointMetadata(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getEntryPointMetadata(entryPointIndex, targetIndex, outMetadata, outDiagnostics);
+ }
+
+ SLANG_NO_THROW SlangResult SLANG_MCALL getTargetMetadata(
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getTargetMetadata(targetIndex, outMetadata, outDiagnostics);
+ }
+
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem(
SlangInt entryPointIndex,
SlangInt targetIndex,
diff --git a/source/slang-record-replay/record/slang-module.h b/source/slang-record-replay/record/slang-module.h
index e793bea98..ce009eac8 100644
--- a/source/slang-record-replay/record/slang-module.h
+++ b/source/slang-record-replay/record/slang-module.h
@@ -85,6 +85,23 @@ namespace SlangRecord
return Super::getTargetCode(targetIndex, outCode, outDiagnostics);
}
+ SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointMetadata(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getEntryPointMetadata(entryPointIndex, targetIndex, outMetadata, outDiagnostics);
+ }
+
+ SLANG_NO_THROW SlangResult SLANG_MCALL getTargetMetadata(
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getTargetMetadata(targetIndex, outMetadata, outDiagnostics);
+ }
+
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem(
SlangInt entryPointIndex,
SlangInt targetIndex,
diff --git a/source/slang-record-replay/record/slang-type-conformance.h b/source/slang-record-replay/record/slang-type-conformance.h
index d1dfb3238..6c6889d02 100644
--- a/source/slang-record-replay/record/slang-type-conformance.h
+++ b/source/slang-record-replay/record/slang-type-conformance.h
@@ -65,6 +65,23 @@ namespace SlangRecord
return Super::getTargetCode(targetIndex, outCode, outDiagnostics);
}
+ SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointMetadata(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getEntryPointMetadata(entryPointIndex, targetIndex, outMetadata, outDiagnostics);
+ }
+
+ SLANG_NO_THROW SlangResult SLANG_MCALL getTargetMetadata(
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getTargetMetadata(targetIndex, outMetadata, outDiagnostics);
+ }
+
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem(
SlangInt entryPointIndex,
SlangInt targetIndex,
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 820cab03f..17501163f 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -317,10 +317,22 @@ namespace Slang
SlangInt targetIndex,
slang::IBlob** outCode,
slang::IBlob** outDiagnostics) SLANG_OVERRIDE;
+
+ IArtifact* getTargetArtifact(SlangInt targetIndex, slang::IBlob** outDiagnostics);
+
SLANG_NO_THROW SlangResult SLANG_MCALL getTargetCode(
SlangInt targetIndex,
slang::IBlob** outCode,
slang::IBlob** outDiagnostics = nullptr) SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointMetadata(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL getTargetMetadata(
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics = nullptr) SLANG_OVERRIDE;
SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem(
SlangInt entryPointIndex,
@@ -580,6 +592,8 @@ namespace Slang
Scope* m_lookupScope = nullptr;
std::unique_ptr<Dictionary<String, IntVal*>> m_mapMangledNameToIntVal;
+
+ Dictionary<Int, ComPtr<IArtifact>> m_targetArtifacts;
};
/// A component type built up from other component types.
@@ -914,6 +928,23 @@ namespace Slang
return Super::getTargetCode(targetIndex, outCode, outDiagnostics);
}
+ SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointMetadata(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getEntryPointMetadata(entryPointIndex, targetIndex, outMetadata, outDiagnostics);
+ }
+
+ SLANG_NO_THROW SlangResult SLANG_MCALL getTargetMetadata(
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getTargetMetadata(targetIndex, outMetadata, outDiagnostics);
+ }
+
SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem(
SlangInt entryPointIndex,
SlangInt targetIndex,
@@ -1159,6 +1190,23 @@ namespace Slang
return Super::getTargetCode(targetIndex, outCode, outDiagnostics);
}
+ SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointMetadata(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getEntryPointMetadata(entryPointIndex, targetIndex, outMetadata, outDiagnostics);
+ }
+
+ SLANG_NO_THROW SlangResult SLANG_MCALL getTargetMetadata(
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getTargetMetadata(targetIndex, outMetadata, outDiagnostics);
+ }
+
SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem(
SlangInt entryPointIndex,
SlangInt targetIndex,
@@ -1460,6 +1508,23 @@ namespace Slang
return Super::getEntryPointHash(entryPointIndex, targetIndex, outHash);
}
+ SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointMetadata(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getEntryPointMetadata(entryPointIndex, targetIndex, outMetadata, outDiagnostics);
+ }
+
+ SLANG_NO_THROW SlangResult SLANG_MCALL getTargetMetadata(
+ SlangInt targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics) SLANG_OVERRIDE
+ {
+ return Super::getTargetMetadata(targetIndex, outMetadata, outDiagnostics);
+ }
+
/// Get a serialized representation of the checked module.
virtual SLANG_NO_THROW SlangResult SLANG_MCALL serialize(ISlangBlob** outSerializedBlob) override;
diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp
index ea22cbcba..5d3331c6f 100644
--- a/source/slang/slang-parameter-binding.cpp
+++ b/source/slang/slang-parameter-binding.cpp
@@ -1225,10 +1225,6 @@ static void addExplicitParameterBindings_GLSL(
}
}
- // We use the HLSL binding directly (even though this notionally for GLSL/Vulkan)
- // We'll do the shifting at later later point in _maybeApplyHLSLToVulkanShifts
- info[kResInfo].resInfo = typeLayout->findOrAddResourceInfo(hlslInfo.kind);
-
if (warnedMissingVulkanLayoutModifier)
{
// If we warn due to invalid bindings and user did not set how to interpret 'hlsl style bindings', we should map
@@ -1236,7 +1232,7 @@ static void addExplicitParameterBindings_GLSL(
if(!hlslToVulkanLayoutOptions
|| hlslToVulkanLayoutOptions->getKindShiftEnabledFlags() == HLSLToVulkanLayoutOptions::KindFlag::None)
{
- info[kResInfo].resInfo->kind = LayoutResourceKind::DescriptorTableSlot;
+ info[kResInfo].resInfo = typeLayout->findOrAddResourceInfo(LayoutResourceKind::DescriptorTableSlot);
info[kResInfo].resInfo->count = 1;
}
else
@@ -1245,6 +1241,11 @@ static void addExplicitParameterBindings_GLSL(
}
}
+ // We use the HLSL binding directly (even though this notionally for GLSL/Vulkan)
+ // We'll do the shifting at later later point in _maybeApplyHLSLToVulkanShifts
+ if (!info[kResInfo].resInfo)
+ info[kResInfo].resInfo = typeLayout->findOrAddResourceInfo(hlslInfo.kind);
+
info[kResInfo].semanticInfo.kind = info[kResInfo].resInfo->kind;
info[kResInfo].semanticInfo.index = UInt(hlslInfo.index);
info[kResInfo].semanticInfo.space = UInt(hlslInfo.space);
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index dc5f9a755..c9717272b 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -4704,6 +4704,38 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointHostCallable(
return artifact->loadSharedLibrary(ArtifactKeep::Yes, outSharedLibrary);
}
+SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointMetadata(
+ SlangInt entryPointIndex,
+ Int targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics)
+{
+ auto linkage = getLinkage();
+ if (targetIndex < 0 || targetIndex >= linkage->targets.getCount())
+ return SLANG_E_INVALID_ARG;
+ auto target = linkage->targets[targetIndex];
+
+ auto targetProgram = getTargetProgram(target);
+
+ DiagnosticSink sink(linkage->getSourceManager(), Lexer::sourceLocationLexer);
+ applySettingsToDiagnosticSink(&sink, &sink, linkage->m_optionSet);
+ applySettingsToDiagnosticSink(&sink, &sink, m_optionSet);
+
+ IArtifact* artifact = targetProgram->getOrCreateEntryPointResult(entryPointIndex, &sink);
+ sink.getBlobIfNeeded(outDiagnostics);
+
+ if (artifact == nullptr)
+ return SLANG_E_NOT_AVAILABLE;
+
+ auto metadata = findAssociatedRepresentation<IArtifactPostEmitMetadata>(artifact);
+ if (!metadata)
+ return SLANG_E_NOT_AVAILABLE;
+
+ *outMetadata = static_cast<slang::IMetadata*>(metadata);
+ (*outMetadata)->addRef();
+ return SLANG_OK;
+}
+
RefPtr<ComponentType> ComponentType::specialize(
SpecializationArg const* inSpecializationArgs,
SlangInt specializationArgCount,
@@ -4933,14 +4965,16 @@ void ComponentType::enumerateIRModules(EnumerateIRModulesCallback callback, void
acceptVisitor(&visitor, nullptr);
}
-SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getTargetCode(
- Int targetIndex,
- slang::IBlob** outCode,
- slang::IBlob** outDiagnostics)
+IArtifact* ComponentType::getTargetArtifact(Int targetIndex, slang::IBlob** outDiagnostics)
{
auto linkage = getLinkage();
if (targetIndex < 0 || targetIndex >= linkage->targets.getCount())
- return SLANG_E_INVALID_ARG;
+ return nullptr;
+ ComPtr<IArtifact> artifact;
+ if (m_targetArtifacts.tryGetValue(targetIndex, artifact))
+ {
+ return artifact.get();
+ }
// If the user hasn't specified any entry points, then we should
// discover all entrypoints that are defined in linked modules, and
@@ -4964,8 +4998,13 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getTargetCode(
}
RefPtr<CompositeComponentType> composite = new CompositeComponentType(linkage, components);
ComPtr<IComponentType> linkedComponentType;
- SLANG_RETURN_ON_FAIL(composite->link(linkedComponentType.writeRef(), outDiagnostics));
- return linkedComponentType->getTargetCode(targetIndex, outCode, outDiagnostics);
+ SLANG_RETURN_NULL_ON_FAIL(composite->link(linkedComponentType.writeRef(), outDiagnostics));
+ auto targetArtifact = static_cast<ComponentType*>(linkedComponentType.get())->getTargetArtifact(targetIndex, outDiagnostics);
+ if (targetArtifact)
+ {
+ m_targetArtifacts[targetIndex] = targetArtifact;
+ }
+ return targetArtifact;
}
auto target = linkage->targets[targetIndex];
@@ -4975,8 +5014,18 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getTargetCode(
applySettingsToDiagnosticSink(&sink, &sink, linkage->m_optionSet);
applySettingsToDiagnosticSink(&sink, &sink, m_optionSet);
- IArtifact* artifact = targetProgram->getOrCreateWholeProgramResult(&sink);
+ IArtifact* targetArtifact = targetProgram->getOrCreateWholeProgramResult(&sink);
sink.getBlobIfNeeded(outDiagnostics);
+ m_targetArtifacts[targetIndex] = ComPtr<IArtifact>(targetArtifact);
+ return targetArtifact;
+}
+
+SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getTargetCode(
+ Int targetIndex,
+ slang::IBlob** outCode,
+ slang::IBlob** outDiagnostics)
+{
+ IArtifact* artifact = getTargetArtifact(targetIndex, outDiagnostics);
if (artifact == nullptr)
return SLANG_FAIL;
@@ -4984,6 +5033,24 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getTargetCode(
return artifact->loadBlob(ArtifactKeep::Yes, outCode);
}
+SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getTargetMetadata(
+ Int targetIndex,
+ slang::IMetadata** outMetadata,
+ slang::IBlob** outDiagnostics)
+{
+ IArtifact* artifact = getTargetArtifact(targetIndex, outDiagnostics);
+
+ if (artifact == nullptr)
+ return SLANG_FAIL;
+
+ auto metadata = findAssociatedRepresentation<IArtifactPostEmitMetadata>(artifact);
+ if (!metadata)
+ return SLANG_E_NOT_AVAILABLE;
+ *outMetadata = static_cast<slang::IMetadata*>(metadata);
+ (*outMetadata)->addRef();
+ return SLANG_OK;
+}
+
//
// CompositeComponentType
//
@@ -6888,19 +6955,7 @@ SlangResult EndToEndCompileRequest::isParameterLocationUsed(Int entryPointIndex,
if (!metadata)
return SLANG_E_NOT_AVAILABLE;
-
- // TODO: optimize this with a binary search through a sorted list
- for (const auto& range : metadata->getUsedBindingRanges())
- {
- if (range.containsBinding((slang::ParameterCategory)category, spaceIndex, registerIndex))
- {
- outUsed = true;
- return SLANG_OK;
- }
- }
-
- outUsed = false;
- return SLANG_OK;
+ return metadata->isParameterLocationUsed(category, spaceIndex, registerIndex, outUsed);
}
} // namespace Slang
diff --git a/tests/bindings/hlsl-to-vulkan-combined.hlsl.expected b/tests/bindings/hlsl-to-vulkan-combined.hlsl.expected
index de67a3592..7466a276d 100644
--- a/tests/bindings/hlsl-to-vulkan-combined.hlsl.expected
+++ b/tests/bindings/hlsl-to-vulkan-combined.hlsl.expected
@@ -41,11 +41,11 @@ standard output = {
"bindings": [
{
"name": "t0",
- "binding": {"kind": "descriptorTableSlot", "index": 0}
+ "binding": {"kind": "descriptorTableSlot", "index": 0, "used": 0}
},
{
"name": "t1",
- "binding": {"kind": "descriptorTableSlot", "index": 1}
+ "binding": {"kind": "descriptorTableSlot", "index": 1, "used": 0}
}
]
}
diff --git a/tests/bindings/hlsl-to-vulkan-global.hlsl.expected b/tests/bindings/hlsl-to-vulkan-global.hlsl.expected
index b0b8f6a17..e0e0db832 100644
--- a/tests/bindings/hlsl-to-vulkan-global.hlsl.expected
+++ b/tests/bindings/hlsl-to-vulkan-global.hlsl.expected
@@ -64,11 +64,11 @@ standard output = {
},
{
"name": "t",
- "binding": {"kind": "descriptorTableSlot", "index": 0}
+ "binding": {"kind": "descriptorTableSlot", "index": 0, "used": 1}
},
{
"name": "sampler",
- "binding": {"kind": "descriptorTableSlot", "index": 1}
+ "binding": {"kind": "descriptorTableSlot", "index": 1, "used": 1}
}
]
}
diff --git a/tests/slang-extension/dynamic-resource-gl.slang.1.expected b/tests/slang-extension/dynamic-resource-gl.slang.1.expected
index fe48e643a..703cb1229 100644
--- a/tests/slang-extension/dynamic-resource-gl.slang.1.expected
+++ b/tests/slang-extension/dynamic-resource-gl.slang.1.expected
@@ -70,23 +70,23 @@ standard output = {
"bindings": [
{
"name": "g_TextureHeap",
- "binding": {"kind": "descriptorTableSlot", "space": 1, "index": 0}
+ "binding": {"kind": "descriptorTableSlot", "space": 1, "index": 0, "used": 1}
},
{
"name": "g_SamplerHeap",
- "binding": {"kind": "descriptorTableSlot", "space": 1, "index": 2}
+ "binding": {"kind": "descriptorTableSlot", "space": 1, "index": 2, "used": 1}
},
{
"name": "g_SingleDynamicResourceA",
- "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 0}
+ "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 0, "used": 1}
},
{
"name": "g_SingleDynamicResourceB",
- "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 1}
+ "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 1, "used": 1}
},
{
"name": "g_SingleDynamicResourceC",
- "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 2}
+ "binding": {"kind": "descriptorTableSlot", "space": 2, "index": 2, "used": 1}
}
]
}
diff --git a/tools/slang-unit-test/unit-test-image-format-reflection.cpp b/tools/slang-unit-test/unit-test-image-format-reflection.cpp
index 2ada598b4..34678472c 100644
--- a/tools/slang-unit-test/unit-test-image-format-reflection.cpp
+++ b/tools/slang-unit-test/unit-test-image-format-reflection.cpp
@@ -1,4 +1,4 @@
-// unit-test-translation-unit-import.cpp
+// unit-test-image-format-reflection.cpp
#include "slang.h"
diff --git a/tools/slang-unit-test/unit-test-parameter-usage-reflection.cpp b/tools/slang-unit-test/unit-test-parameter-usage-reflection.cpp
new file mode 100644
index 000000000..911bdc5a4
--- /dev/null
+++ b/tools/slang-unit-test/unit-test-parameter-usage-reflection.cpp
@@ -0,0 +1,68 @@
+// unit-test-parameter-usage-reflection.cpp
+
+#include "slang.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "tools/unit-test/slang-unit-test.h"
+#include "slang-com-ptr.h"
+#include "../../source/core/slang-io.h"
+#include "../../source/core/slang-process.h"
+
+using namespace Slang;
+
+// Test that the isParameterLocationUsed API works.
+
+SLANG_UNIT_TEST(isParameterLocationUsedReflection)
+{
+ // Source for a module that contains an undecorated entrypoint.
+ const char* userSourceBody = R"(
+ Texture2D g_tex : register(t0);
+ [shader("fragment")]
+ float4 fragMain(float4 pos:SV_Position) : SV_Target
+ {
+ return g_tex.Load(int3(0, 0, 0));
+ }
+ )";
+
+ auto moduleName = "moduleG" + String(Process::getId());
+ String userSource = "import " + moduleName + ";\n" + userSourceBody;
+ ComPtr<slang::IGlobalSession> globalSession;
+ SLANG_CHECK(slang_createGlobalSession(SLANG_API_VERSION, globalSession.writeRef()) == SLANG_OK);
+ slang::TargetDesc targetDesc = {};
+ targetDesc.format = SLANG_SPIRV;
+ targetDesc.profile = globalSession->findProfile("spirv_1_5");
+ slang::SessionDesc sessionDesc = {};
+ sessionDesc.targetCount = 1;
+ sessionDesc.targets = &targetDesc;
+ ComPtr<slang::ISession> session;
+ SLANG_CHECK(globalSession->createSession(sessionDesc, session.writeRef()) == SLANG_OK);
+
+ ComPtr<slang::IBlob> diagnosticBlob;
+ auto module = session->loadModuleFromSourceString("m", "m.slang", userSourceBody, diagnosticBlob.writeRef());
+ SLANG_CHECK(module != nullptr);
+
+ ComPtr<slang::IEntryPoint> entryPoint;
+ module->findAndCheckEntryPoint("fragMain", SLANG_STAGE_FRAGMENT, entryPoint.writeRef(), diagnosticBlob.writeRef());
+ SLANG_CHECK(entryPoint != nullptr);
+
+ ComPtr<slang::IComponentType> compositeProgram;
+ slang::IComponentType* components[] = { module, entryPoint.get() };
+ session->createCompositeComponentType(components, 2, compositeProgram.writeRef(), diagnosticBlob.writeRef());
+ SLANG_CHECK(compositeProgram != nullptr);
+
+ ComPtr<slang::IComponentType> linkedProgram;
+ compositeProgram->link(linkedProgram.writeRef(), nullptr);
+
+ ComPtr<slang::IMetadata> metadata;
+ linkedProgram->getTargetMetadata(0, metadata.writeRef(), nullptr);
+
+ bool isUsed = false;
+ metadata->isParameterLocationUsed(SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT, 0, 0, isUsed);
+ SLANG_CHECK(isUsed);
+
+ metadata->isParameterLocationUsed(SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT, 0, 1, isUsed);
+ SLANG_CHECK(!isUsed);
+}
+