summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Leino <aleino@nvidia.com>2025-03-12 13:44:57 +0200
committerGitHub <noreply@github.com>2025-03-12 13:44:57 +0200
commitf4d5372d3354e62770b076b47892b5172223e98a (patch)
tree48220e9716dd585ffa64635e977df2878fc63bdc
parent7a942cfdc338d199b8e775d16b0b9b49699363d7 (diff)
Migrate render-test away from deprecated compile request API (#6514)
* Add a simple interface parameter test Since there's no documentation, it's nice to have a simple test case in order to experiment with this feature of the testing framework. * Add shader entry point attributes to tests * Fix specialization arguments for tests - Add some missing arguments - Rremove one extraneous argument. * Stop using deprecated compile request in render-test Use a session object instead of the deprecated compile request object. This closes issue #4760.
-rw-r--r--tests/bugs/texture2d-gather.hlsl3
-rw-r--r--tests/compute/compile-time-loop.slang2
-rw-r--r--tests/compute/constexpr.slang2
-rw-r--r--tests/compute/discard-stmt.slang2
-rw-r--r--tests/compute/dynamic-dispatch-bindless-texture.slang1
-rw-r--r--tests/compute/interface-shader-param.slang2
-rw-r--r--tests/compute/simple-interface-parameter.slang27
-rw-r--r--tests/compute/simple-interface-parameter.slang.expected.txt4
-rw-r--r--tests/compute/texture-sampling-no-1d-arrays.slang2
-rw-r--r--tests/glsl-intrinsic/shader-invocation-group/shader-invocation-group.slang2
-rw-r--r--tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_Exclusive.slang1
-rw-r--r--tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_Inclusive.slang1
-rw-r--r--tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_None.slang1
-rw-r--r--tests/glsl-intrinsic/shader-subgroup/shader-subgroup-ballot.slang1
-rw-r--r--tests/glsl-intrinsic/shader-subgroup/shader-subgroup-builtin-variables-2.slang1
-rw-r--r--tests/glsl-intrinsic/shader-subgroup/shader-subgroup-builtin-variables.slang1
-rw-r--r--tests/glsl-intrinsic/shader-subgroup/shader-subgroup-vote.slang1
-rw-r--r--tests/glsl/ssbo.slang1
-rw-r--r--tests/language-feature/shader-params/interface-shader-param-ordinary.slang1
-rw-r--r--tests/pipeline/rasterization/mesh/task-groupshared.slang1
-rw-r--r--tests/pipeline/rasterization/mesh/task-simple.slang1
-rw-r--r--tests/render/cross-compile-entry-point.slang2
-rw-r--r--tests/render/cross-compile0.hlsl2
-rw-r--r--tests/render/imported-parameters.hlsl2
-rw-r--r--tests/render/multiple-stage-io-locations-without-user-semantics.slang2
-rw-r--r--tests/render/multiple-stage-io-locations.slang2
-rw-r--r--tests/render/nointerpolation.hlsl2
-rw-r--r--tests/render/render0.hlsl2
-rw-r--r--tools/render-test/slang-support.cpp500
-rw-r--r--tools/render-test/slang-support.h2
30 files changed, 421 insertions, 153 deletions
diff --git a/tests/bugs/texture2d-gather.hlsl b/tests/bugs/texture2d-gather.hlsl
index 7344d863d..46f921b26 100644
--- a/tests/bugs/texture2d-gather.hlsl
+++ b/tests/bugs/texture2d-gather.hlsl
@@ -31,6 +31,7 @@ struct VertexStageOutput
float4 position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -41,7 +42,7 @@ VertexStageOutput vertexMain(VertexStageInput input)
return output;
}
-// Fragment Shader
+[shader("fragment")]
float4 fragmentMain(VertexStageOutput input) : SV_Target
{
return g_texture.GatherRed(g_sampler, input.color.xy);
diff --git a/tests/compute/compile-time-loop.slang b/tests/compute/compile-time-loop.slang
index 9035bde2a..c70cfb1b9 100644
--- a/tests/compute/compile-time-loop.slang
+++ b/tests/compute/compile-time-loop.slang
@@ -45,6 +45,7 @@ struct VertexStageOutput
float4 sv_position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -70,6 +71,7 @@ struct FragmentStageOutput
Fragment fragment : SV_Target;
};
+[shader("fragment")]
FragmentStageOutput fragmentMain(FragmentStageInput input)
{
FragmentStageOutput output;
diff --git a/tests/compute/constexpr.slang b/tests/compute/constexpr.slang
index f1cd76841..5370de733 100644
--- a/tests/compute/constexpr.slang
+++ b/tests/compute/constexpr.slang
@@ -52,6 +52,7 @@ struct VertexStageOutput
float4 sv_position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -77,6 +78,7 @@ struct FragmentStageOutput
Fragment fragment : SV_Target;
};
+[shader("fragment")]
FragmentStageOutput fragmentMain(FragmentStageInput input)
{
// The texel offset argument to `Texture2D.Sample` is
diff --git a/tests/compute/discard-stmt.slang b/tests/compute/discard-stmt.slang
index fa00c9ec3..6988d611b 100644
--- a/tests/compute/discard-stmt.slang
+++ b/tests/compute/discard-stmt.slang
@@ -46,6 +46,7 @@ struct VertexStageOutput
float4 sv_position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -71,6 +72,7 @@ struct FragmentStageOutput
Fragment fragment : SV_Target;
};
+[shader("fragment")]
FragmentStageOutput fragmentMain(FragmentStageInput input)
{
FragmentStageOutput output;
diff --git a/tests/compute/dynamic-dispatch-bindless-texture.slang b/tests/compute/dynamic-dispatch-bindless-texture.slang
index 34ef67d1e..b02ca9686 100644
--- a/tests/compute/dynamic-dispatch-bindless-texture.slang
+++ b/tests/compute/dynamic-dispatch-bindless-texture.slang
@@ -25,7 +25,6 @@ void computeMain(int3 dispatchThreadID : SV_DispatchThreadID)
gOutputBuffer[tid] = uint(trunc(outputVal));
}
-//TEST_INPUT: globalExistentialType __Dynamic
// Type must be marked `public` to ensure it is visible in the generated DLL.
export struct MyImpl : IInterface
diff --git a/tests/compute/interface-shader-param.slang b/tests/compute/interface-shader-param.slang
index 7965253b2..58e477fcb 100644
--- a/tests/compute/interface-shader-param.slang
+++ b/tests/compute/interface-shader-param.slang
@@ -84,6 +84,7 @@ RWStructuredBuffer<int> gOutputBuffer;
// Now we'll define a global shader parameter for the
// random number generation strategy.
//
+//TEST_INPUT: globalSpecializationArg MyStrategy
//TEST_INPUT:set gStrategy = new MyStrategy{}
uniform IRandomNumberGenerationStrategy gStrategy;
@@ -93,6 +94,7 @@ uniform IRandomNumberGenerationStrategy gStrategy;
//
[numthreads(4, 1, 1)]
void computeMain(
+//TEST_INPUT: entryPointSpecializationArg MyModifier
//TEST_INPUT:set modifier = new MyModifier{}
uniform IModifier modifier,
int3 dispatchThreadID : SV_DispatchThreadID)
diff --git a/tests/compute/simple-interface-parameter.slang b/tests/compute/simple-interface-parameter.slang
new file mode 100644
index 000000000..067fb621f
--- /dev/null
+++ b/tests/compute/simple-interface-parameter.slang
@@ -0,0 +1,27 @@
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
+
+interface IGetter
+{
+ int get(int x);
+}
+
+//TEST_INPUT:set gOutputBuffer = out ubuffer(data=[0 0 0 0], stride=4)
+RWStructuredBuffer<int> gOutputBuffer;
+
+//TEST_INPUT: globalSpecializationArg MyGetter
+//TEST_INPUT: set gGetter = new MyGetter{}
+uniform IGetter gGetter;
+
+[numthreads(4, 1, 1)]
+void computeMain(int3 dispatchThreadID : SV_DispatchThreadID)
+{
+ gOutputBuffer[dispatchThreadID.x] = gGetter.get(dispatchThreadID.x);
+}
+
+struct MyGetter : IGetter
+{
+ int get(int x)
+ {
+ return x + 1;
+ }
+}
diff --git a/tests/compute/simple-interface-parameter.slang.expected.txt b/tests/compute/simple-interface-parameter.slang.expected.txt
new file mode 100644
index 000000000..94ebaf900
--- /dev/null
+++ b/tests/compute/simple-interface-parameter.slang.expected.txt
@@ -0,0 +1,4 @@
+1
+2
+3
+4
diff --git a/tests/compute/texture-sampling-no-1d-arrays.slang b/tests/compute/texture-sampling-no-1d-arrays.slang
index f95050fca..0985374cc 100644
--- a/tests/compute/texture-sampling-no-1d-arrays.slang
+++ b/tests/compute/texture-sampling-no-1d-arrays.slang
@@ -60,6 +60,7 @@ struct VertexStageOutput
float4 sv_position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -85,6 +86,7 @@ struct FragmentStageOutput
Fragment fragment : SV_Target;
};
+[shader("fragment")]
FragmentStageOutput fragmentMain(FragmentStageInput input)
{
FragmentStageOutput output;
diff --git a/tests/glsl-intrinsic/shader-invocation-group/shader-invocation-group.slang b/tests/glsl-intrinsic/shader-invocation-group/shader-invocation-group.slang
index 201f33ea2..d68979675 100644
--- a/tests/glsl-intrinsic/shader-invocation-group/shader-invocation-group.slang
+++ b/tests/glsl-intrinsic/shader-invocation-group/shader-invocation-group.slang
@@ -34,6 +34,8 @@ bool testAllInvocationsEqual()
&& allInvocationsEqual(gl_GlobalInvocationID.x == 0) == false
;
}
+
+[shader("compute")]
void computeMain()
{
outputBuffer.data[0] = true
diff --git a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_Exclusive.slang b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_Exclusive.slang
index 0a0fcade5..c77fa5929 100644
--- a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_Exclusive.slang
+++ b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_Exclusive.slang
@@ -183,6 +183,7 @@ bool testArithmetic() {
;
}
+[shader("compute")]
void computeMain()
{
diff --git a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_Inclusive.slang b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_Inclusive.slang
index 58c7d5aaa..40f77ee61 100644
--- a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_Inclusive.slang
+++ b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_Inclusive.slang
@@ -183,6 +183,7 @@ bool testArithmetic() {
;
}
+[shader("compute")]
void computeMain()
{
diff --git a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_None.slang b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_None.slang
index bb6316a59..4bea35b6e 100644
--- a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_None.slang
+++ b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-arithmetic_None.slang
@@ -182,6 +182,7 @@ bool testArithmetic() {
;
}
+[shader("compute")]
void computeMain()
{
diff --git a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-ballot.slang b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-ballot.slang
index 04f1b935a..82fb38f5e 100644
--- a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-ballot.slang
+++ b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-ballot.slang
@@ -139,6 +139,7 @@ bool testBallot() {
;
}
+[shader("compute")]
void computeMain()
{
outputBuffer.data[0] = true
diff --git a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-builtin-variables-2.slang b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-builtin-variables-2.slang
index 2e3896cc5..aceff939b 100644
--- a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-builtin-variables-2.slang
+++ b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-builtin-variables-2.slang
@@ -16,6 +16,7 @@ buffer MyBlockName2
layout(local_size_x = 4) in;
+[shader("compute")]
void computeMain(int3 dispatchThreadID : SV_DispatchThreadID)
{
// There may be some issues with structure padding for global context containing
diff --git a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-builtin-variables.slang b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-builtin-variables.slang
index 2d11ca5fb..bfef48374 100644
--- a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-builtin-variables.slang
+++ b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-builtin-variables.slang
@@ -25,6 +25,7 @@ buffer MyBlockName2
layout(local_size_x = 32) in;
+[shader("compute")]
void computeMain()
{
if (gl_GlobalInvocationID.x == 3) {
diff --git a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-vote.slang b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-vote.slang
index c0b6e3788..23466b742 100644
--- a/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-vote.slang
+++ b/tests/glsl-intrinsic/shader-subgroup/shader-subgroup-vote.slang
@@ -126,6 +126,7 @@ void _barrier()
#endif
}
+[shader("compute")]
void computeMain()
{
//seperate tests since testing concurrency
diff --git a/tests/glsl/ssbo.slang b/tests/glsl/ssbo.slang
index 4f4db07cd..1eb2722ff 100644
--- a/tests/glsl/ssbo.slang
+++ b/tests/glsl/ssbo.slang
@@ -17,6 +17,7 @@ buffer MyBlockName2
} outputBuffer;
layout(local_size_x = 4) in;
+[shader("compute")]
void computeMain()
{
outputBuffer.data[gl_GlobalInvocationID.x] = inputBuffer.data[gl_GlobalInvocationID.x];
diff --git a/tests/language-feature/shader-params/interface-shader-param-ordinary.slang b/tests/language-feature/shader-params/interface-shader-param-ordinary.slang
index 7196f9b04..fa4657d76 100644
--- a/tests/language-feature/shader-params/interface-shader-param-ordinary.slang
+++ b/tests/language-feature/shader-params/interface-shader-param-ordinary.slang
@@ -23,6 +23,7 @@ RWStructuredBuffer<int> gOutputBuffer;
//TEST_INPUT:set delta = 65536
uniform int delta;
+//TEST_INPUT: globalSpecializationArg MyModifier
//TEST_INPUT:set gModifier = new MyModifier{ ubuffer(data=[4 3 2 1], stride=4), 3 } }
uniform IModifier gModifier;
diff --git a/tests/pipeline/rasterization/mesh/task-groupshared.slang b/tests/pipeline/rasterization/mesh/task-groupshared.slang
index 46334bf3e..4d88de780 100644
--- a/tests/pipeline/rasterization/mesh/task-groupshared.slang
+++ b/tests/pipeline/rasterization/mesh/task-groupshared.slang
@@ -32,6 +32,7 @@ struct MeshPayload
groupshared MeshPayload p;
[numthreads(1, 1, 1)]
+[shader("amplification")]
void taskMain(in uint tig : SV_GroupIndex)
{
p.exponent = 3;
diff --git a/tests/pipeline/rasterization/mesh/task-simple.slang b/tests/pipeline/rasterization/mesh/task-simple.slang
index 053b24045..61cc6da3d 100644
--- a/tests/pipeline/rasterization/mesh/task-simple.slang
+++ b/tests/pipeline/rasterization/mesh/task-simple.slang
@@ -35,6 +35,7 @@ struct MeshPayload
};
[numthreads(1, 1, 1)]
+[shader("amplification")]
void taskMain(in uint tig : SV_GroupIndex)
{
MeshPayload p;
diff --git a/tests/render/cross-compile-entry-point.slang b/tests/render/cross-compile-entry-point.slang
index d8cb687c5..3b5faa111 100644
--- a/tests/render/cross-compile-entry-point.slang
+++ b/tests/render/cross-compile-entry-point.slang
@@ -50,6 +50,7 @@ struct VertexStageOutput
float4 sv_position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -76,6 +77,7 @@ struct FragmentStageOutput
Fragment fragment : SV_Target;
};
+[shader("fragment")]
FragmentStageOutput fragmentMain(FragmentStageInput input)
{
FragmentStageOutput output;
diff --git a/tests/render/cross-compile0.hlsl b/tests/render/cross-compile0.hlsl
index 1d33b68bf..1820a17f0 100644
--- a/tests/render/cross-compile0.hlsl
+++ b/tests/render/cross-compile0.hlsl
@@ -45,6 +45,7 @@ struct VertexStageOutput
float4 sv_position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -71,6 +72,7 @@ struct FragmentStageOutput
Fragment fragment : SV_Target;
};
+[shader("fragment")]
FragmentStageOutput fragmentMain(FragmentStageInput input)
{
FragmentStageOutput output;
diff --git a/tests/render/imported-parameters.hlsl b/tests/render/imported-parameters.hlsl
index 495ff8da2..1ed27bfa0 100644
--- a/tests/render/imported-parameters.hlsl
+++ b/tests/render/imported-parameters.hlsl
@@ -38,6 +38,7 @@ struct VertexStageOutput
float4 sv_position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -64,6 +65,7 @@ struct FragmentStageOutput
Fragment fragment : SV_Target;
};
+[shader("fragment")]
FragmentStageOutput fragmentMain(FragmentStageInput input)
{
FragmentStageOutput output;
diff --git a/tests/render/multiple-stage-io-locations-without-user-semantics.slang b/tests/render/multiple-stage-io-locations-without-user-semantics.slang
index af0e3e39f..585b8e34e 100644
--- a/tests/render/multiple-stage-io-locations-without-user-semantics.slang
+++ b/tests/render/multiple-stage-io-locations-without-user-semantics.slang
@@ -31,6 +31,7 @@ struct VertexStageOutput
float4 sv_position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -58,6 +59,7 @@ struct FragmentStageOutput
Fragment fragment : SV_Target;
};
+[shader("fragment")]
FragmentStageOutput fragmentMain(FragmentStageInput input)
{
FragmentStageOutput output;
diff --git a/tests/render/multiple-stage-io-locations.slang b/tests/render/multiple-stage-io-locations.slang
index 9f74d1398..5e27a9cf1 100644
--- a/tests/render/multiple-stage-io-locations.slang
+++ b/tests/render/multiple-stage-io-locations.slang
@@ -32,6 +32,7 @@ struct VertexStageOutput
float4 sv_position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -59,6 +60,7 @@ struct FragmentStageOutput
Fragment fragment : SV_Target;
};
+[shader("fragment")]
FragmentStageOutput fragmentMain(FragmentStageInput input)
{
FragmentStageOutput output;
diff --git a/tests/render/nointerpolation.hlsl b/tests/render/nointerpolation.hlsl
index d514379d0..145bd3bed 100644
--- a/tests/render/nointerpolation.hlsl
+++ b/tests/render/nointerpolation.hlsl
@@ -41,6 +41,7 @@ struct VertexStageOutput
float4 sv_position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -66,6 +67,7 @@ struct FragmentStageOutput
Fragment fragment : SV_Target;
};
+[shader("fragment")]
FragmentStageOutput fragmentMain(FragmentStageInput input)
{
FragmentStageOutput output;
diff --git a/tests/render/render0.hlsl b/tests/render/render0.hlsl
index 90ca42430..9fd169b06 100644
--- a/tests/render/render0.hlsl
+++ b/tests/render/render0.hlsl
@@ -38,6 +38,7 @@ struct VertexStageOutput
float4 sv_position : SV_Position;
};
+[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
VertexStageOutput output;
@@ -63,6 +64,7 @@ struct FragmentStageOutput
Fragment fragment : SV_Target;
};
+[shader("fragment")]
FragmentStageOutput fragmentMain(FragmentStageInput input)
{
FragmentStageOutput output;
diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp
index 5f9ae5a7f..dfde5f386 100644
--- a/tools/render-test/slang-support.cpp
+++ b/tools/render-test/slang-support.cpp
@@ -4,6 +4,8 @@
#include "slang-support.h"
+#include "../../source/compiler-core/slang-artifact-desc-util.h"
+#include "../../source/core/slang-file-system.h"
#include "../../source/core/slang-string-util.h"
#include "../../source/core/slang-test-tool-util.h"
#include "options.h"
@@ -36,7 +38,7 @@ void ShaderCompilerUtil::Output::reset()
}
globalSession = nullptr;
- m_requestDEPRECATED = nullptr;
+ m_session = nullptr;
}
static SlangResult _compileProgramImpl(
@@ -48,58 +50,84 @@ static SlangResult _compileProgramImpl(
{
out.reset();
- slang::SessionDesc sessionDesc = {};
- List<slang::PreprocessorMacroDesc> macros;
- sessionDesc.preprocessorMacroCount = (SlangInt)macros.getCount();
- sessionDesc.preprocessorMacros = macros.getBuffer();
-
- ComPtr<SlangCompileRequest> slangRequest = nullptr;
- SLANG_ALLOW_DEPRECATED_BEGIN
- globalSession->createCompileRequest(slangRequest.writeRef());
- SLANG_ALLOW_DEPRECATED_END
- out.m_requestDEPRECATED = slangRequest;
- out.globalSession = globalSession;
+ List<const char*> args;
+ for (const auto& arg : options.downstreamArgs.getArgsByName("slang"))
+ {
+ args.add(arg.value.getBuffer());
+ // The -load-repro feature is not maintained, and not supported by the new compile API.
+ // TODO: Remove this when the feature has been deprecated.
+ SLANG_ASSERT(arg.value != "-load-repro");
+ }
- // Parse all the extra args
+ slang::TargetDesc sessionTargetDesc = {};
+ slang::SessionDesc sessionDesc = {};
+ ComPtr<ISlangUnknown> sessionDescMemory;
+ // If there are additional args parse them
+ if (args.getCount())
{
- List<const char*> args;
- for (const auto& arg : options.downstreamArgs.getArgsByName("slang"))
+ const auto res = globalSession->parseCommandLineArguments(
+ int(args.getCount()),
+ args.getBuffer(),
+ &sessionDesc,
+ sessionDescMemory.writeRef());
+ // If there is a parse failure and diagnostic, output it
+ if (SLANG_FAILED(res))
+ {
+ fprintf(stderr, "error: Failed to parse command line arguments: %d\n", int(res));
+ return res;
+ }
+ // We're setting the targets ourselves, below.
+ // To simplify that, we're currently not expecting targets to be added by the command line
+ // arguments.
+ if (sessionDesc.targetCount > 0)
{
- args.add(arg.value.getBuffer());
- // The -load-repro feature is not maintained, and not supported by the new compile API.
- // TODO: Remove this when the feature has been deprecated.
- SLANG_ASSERT(arg.value != "-load-repro");
+ fprintf(stderr, "error: Command line arguments added targets.\n");
+ return SLANG_FAIL;
}
+ }
- // If there are additional args parse them
- if (args.getCount())
+ // Argument parsing may have already added options, so add those first.
+ // For module reference options there are two cases:
+ // 1. If it's a slang module, then record the path and later create an IModule from that.
+ // 2. If not, then propagate the option.
+ // The reason to propagate the option in case 2 is that there is not currently a way of
+ // representing a module for a downstream compiler in the compilation API.
+ List<slang::CompilerOptionEntry> sessionOptionEntries;
+ List<Slang::String> referencedSlangModulePaths;
+ for (int optionIndex = 0; optionIndex < sessionDesc.compilerOptionEntryCount; optionIndex++)
+ {
+ slang::CompilerOptionEntry& option = sessionDesc.compilerOptionEntries[optionIndex];
+ if (option.name == slang::CompilerOptionName::ReferenceModule)
{
- const auto res =
- slangRequest->processCommandLineArguments(args.getBuffer(), int(args.getCount()));
- // If there is a parse failure and diagnostic, output it
- if (SLANG_FAILED(res))
+ SLANG_ASSERT(option.value.kind == slang::CompilerOptionValueKind::String);
+ const char* path = option.value.stringValue0;
+ auto desc = Slang::ArtifactDescUtil::getDescFromPath(Slang::UnownedStringSlice(path));
+ switch (desc.payload)
{
- if (auto diagnostics = slangRequest->getDiagnosticOutput())
+ case Slang::ArtifactDesc::Payload::SlangIR:
+ case Slang::ArtifactDesc::Payload::Slang:
+ referencedSlangModulePaths.add(option.value.stringValue0);
+ break;
+ case Slang::ArtifactDesc::Payload::DXIL:
+ sessionOptionEntries.add(option);
+ break;
+ default:
{
- fprintf(stderr, "%s", diagnostics);
+ fprintf(
+ stderr,
+ "error: Unexpected artifact payload type: %d\n",
+ (int)desc.payload);
+ return SLANG_FAIL;
}
- return res;
}
}
+ else
+ {
+ sessionOptionEntries.add(option);
+ }
}
- spSetCodeGenTarget(slangRequest, input.target);
- if (input.profile.getLength()) // do not set profile unless requested
- spSetTargetProfile(
- slangRequest,
- 0,
- spFindProfile(out.globalSession, input.profile.getBuffer()));
- if (options.generateSPIRVDirectly)
- spSetTargetFlags(slangRequest, 0, SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY);
- else
- spSetTargetFlags(slangRequest, 0, 0);
-
- slangRequest->setAllowGLSLInput(options.allowGLSL);
+ List<slang::PreprocessorMacroDesc> macros;
// Define a macro so that shader code in a test can detect what language we
// are nominally working with.
@@ -107,26 +135,26 @@ static SlangResult _compileProgramImpl(
switch (input.sourceLanguage)
{
case SLANG_SOURCE_LANGUAGE_GLSL:
- spAddPreprocessorDefine(slangRequest, "__GLSL__", "1");
+ macros.add({"__GLSL__", "1"});
break;
case SLANG_SOURCE_LANGUAGE_SLANG:
- spAddPreprocessorDefine(slangRequest, "__SLANG__", "1");
+ macros.add({"__SLANG__", "1"});
// fall through
case SLANG_SOURCE_LANGUAGE_HLSL:
- spAddPreprocessorDefine(slangRequest, "__HLSL__", "1");
+ macros.add({"__HLSL__", "1"});
break;
case SLANG_SOURCE_LANGUAGE_C:
- spAddPreprocessorDefine(slangRequest, "__C__", "1");
+ macros.add({"__C__", "1"});
break;
case SLANG_SOURCE_LANGUAGE_CPP:
- spAddPreprocessorDefine(slangRequest, "__CPP__", "1");
+ macros.add({"__CPP__", "1"});
break;
case SLANG_SOURCE_LANGUAGE_CUDA:
- spAddPreprocessorDefine(slangRequest, "__CUDA__", "1");
+ macros.add({"__CUDA__", "1"});
break;
case SLANG_SOURCE_LANGUAGE_WGSL:
- spAddPreprocessorDefine(slangRequest, "__WGSL__", "1");
+ macros.add({"__WGSL__", "1"});
break;
default:
@@ -134,50 +162,195 @@ static SlangResult _compileProgramImpl(
break;
}
- if (input.passThrough != SLANG_PASS_THROUGH_NONE)
{
- spSetPassThrough(slangRequest, input.passThrough);
+ slang::CompilerOptionEntry entry;
+ entry.name = slang::CompilerOptionName::AllowGLSL;
+ entry.value.kind = slang::CompilerOptionValueKind::Int;
+ entry.value.intValue0 = int(options.allowGLSL);
+ sessionOptionEntries.add(entry);
}
+
+ {
+ slang::CompilerOptionEntry entry;
+ entry.name = slang::CompilerOptionName::PassThrough;
+ entry.value.kind = slang::CompilerOptionValueKind::Int;
+ entry.value.intValue0 = int(input.passThrough);
+ sessionOptionEntries.add(entry);
+ }
+
+ {
+ slang::CompilerOptionEntry entry;
+ entry.name = slang::CompilerOptionName::LineDirectiveMode;
+ entry.value.kind = slang::CompilerOptionValueKind::Int;
+ entry.value.intValue0 = int(SlangLineDirectiveMode::SLANG_LINE_DIRECTIVE_MODE_NONE);
+ sessionOptionEntries.add(entry);
+ }
+
+ sessionTargetDesc.format = input.target;
+ if (input.profile.getLength()) // do not set profile unless requested
+ sessionTargetDesc.profile = globalSession->findProfile(input.profile.getBuffer());
+ if (options.generateSPIRVDirectly)
+ sessionTargetDesc.flags |= SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY;
else
+ sessionTargetDesc.flags = 0;
+
+ // Not expecting argument parsing to have added any targets
+ SLANG_ASSERT(sessionDesc.targetCount == 0);
+ sessionDesc.targetCount = 1;
+ sessionDesc.targets = &sessionTargetDesc;
+
+ if (options.generateSPIRVDirectly)
{
- spSetCompileFlags(slangRequest, SLANG_COMPILE_FLAG_NO_CODEGEN);
+ slang::CompilerOptionEntry entry;
+ entry.name = slang::CompilerOptionName::DebugInformation;
+ entry.value.kind = slang::CompilerOptionValueKind::Int;
+ entry.value.intValue0 =
+ int(options.disableDebugInfo ? SlangDebugInfoLevel::SLANG_DEBUG_INFO_LEVEL_NONE
+ : SlangDebugInfoLevel::SLANG_DEBUG_INFO_LEVEL_STANDARD);
+ sessionOptionEntries.add(entry);
}
+ sessionDesc.compilerOptionEntryCount = sessionOptionEntries.getCount();
+ sessionDesc.compilerOptionEntries = sessionOptionEntries.getBuffer();
- const auto sourceLanguage = input.sourceLanguage;
+ // Argument parsing should not have added macros.
+ SLANG_ASSERT(sessionDesc.preprocessorMacroCount == 0);
+ sessionDesc.preprocessorMacroCount = (SlangInt)macros.getCount();
+ sessionDesc.preprocessorMacros = macros.getBuffer();
+
+ ComPtr<slang::ISession> slangSession = nullptr;
+ SLANG_RETURN_ON_FAIL(globalSession->createSession(sessionDesc, slangSession.writeRef()));
+ out.m_session = slangSession;
+ out.globalSession = globalSession;
- int translationUnitIndex = 0;
+ String source(request.source.dataBegin, request.source.dataEnd);
+ ComPtr<slang::IBlob> diagnostics;
+ ComPtr<slang::IModule> module(slangSession->loadModuleFromSourceString(
+ "main",
+ request.source.path,
+ source.getBuffer(),
+ diagnostics.writeRef()));
+ if (!module)
{
- translationUnitIndex = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr);
- spAddTranslationUnitSourceString(
- slangRequest,
- translationUnitIndex,
- request.source.path,
- request.source.dataBegin);
+ fprintf(
+ stderr,
+ "error: Failed to load module: %s\n",
+ diagnostics ? (char*)diagnostics->getBufferPointer() : "(no diagnostic output)");
+ return SLANG_FAIL;
}
- const int globalSpecializationArgCount = int(request.globalSpecializationArgs.getCount());
+ // Some tests are verifying that various warnings are printed, so print any diagnostics!
+ if (diagnostics && (diagnostics->getBufferSize() > 0U))
+ StdWriters::getError().print("%s", (char*)diagnostics->getBufferPointer());
+
+ ComPtr<slang::IModule> specializedModule;
+ List<ComPtr<slang::IEntryPoint>> specializedEntryPoints;
+ List<slang::IComponentType*> componentsRawPtr;
+
+ ComPtr<ISlangFileSystem> osFileSystem =
+ ComPtr<ISlangFileSystem>(Slang::OSFileSystem::getExtSingleton());
+
+ // This list is just kept so that the modules will be freed at scope exit
+ List<ComPtr<slang::IModule>> referencedModules;
+ for (auto& path : referencedSlangModulePaths)
+ {
+ auto desc =
+ Slang::ArtifactDescUtil::getDescFromPath(Slang::UnownedStringSlice(path.getBuffer()));
+ // If it's a GPU binary, then we'll assume it's a library
+ if (ArtifactDescUtil::isGpuUsable(desc))
+ {
+ desc.kind = ArtifactKind::Library;
+ }
+ const String name = ArtifactDescUtil::getBaseNameFromPath(desc, path.getUnownedSlice());
+
+ ComPtr<slang::IBlob> codeBlob;
+ SlangResult result = osFileSystem->loadFile(path.getBuffer(), codeBlob.writeRef());
+ if (SLANG_FAILED(result))
+ {
+ fprintf(stderr, "error: Failed to read referenced module file: %s\n", path.getBuffer());
+ return SLANG_FAIL;
+ }
+
+ ComPtr<slang::IModule> module;
+ switch (desc.payload)
+ {
+ case Slang::ArtifactDesc::Payload::Slang:
+ {
+ String sourceString(
+ (const char*)codeBlob->getBufferPointer(),
+ (const char*)codeBlob->getBufferPointer() + codeBlob->getBufferSize());
+ module = ComPtr<slang::IModule>(slangSession->loadModuleFromSourceString(
+ name.getBuffer(),
+ path.getBuffer(),
+ sourceString.getBuffer(),
+ diagnostics.writeRef()));
+ break;
+ }
+ case Slang::ArtifactDesc::Payload::SlangIR:
+ {
+ module = ComPtr<slang::IModule>(slangSession->loadModuleFromIRBlob(
+ name.getBuffer(),
+ path.getBuffer(),
+ codeBlob,
+ diagnostics.writeRef()));
+ break;
+ }
+ default:
+ {
+ SLANG_UNREACHABLE("Unexpected artifact payload type");
+ }
+ }
+
+ if (!module)
+ {
+ fprintf(
+ stderr,
+ "error: Failed to load referenced module: %s: %s\n",
+ path.getBuffer(),
+ diagnostics ? (char*)diagnostics->getBufferPointer() : "(no diagnostic output)");
+ return SLANG_FAIL;
+ }
+ referencedModules.add(module);
+ componentsRawPtr.add(module.get());
+ }
+
+ int globalSpecializationArgCount = int(request.globalSpecializationArgs.getCount());
+ int moduleSpecializationArgCount = module->getSpecializationParamCount();
+ if (globalSpecializationArgCount != moduleSpecializationArgCount)
+ {
+ fprintf(
+ stderr,
+ "error: The specialization argument count of the request (%d) does not match that of "
+ "the module (%d)!\n",
+ globalSpecializationArgCount,
+ moduleSpecializationArgCount);
+ return SLANG_FAIL;
+ }
+ List<slang::SpecializationArg> moduleSpecializationArgs;
for (int ii = 0; ii < globalSpecializationArgCount; ++ii)
{
- spSetTypeNameForGlobalExistentialTypeParam(
- slangRequest,
- ii,
- request.globalSpecializationArgs[ii].getBuffer());
+ String specializedTypeName = request.globalSpecializationArgs[ii].getBuffer();
+ slang::TypeReflection* typeReflection =
+ module->getLayout()->findTypeByName(specializedTypeName.getBuffer());
+ moduleSpecializationArgs.add(slang::SpecializationArg::fromType(typeReflection));
}
- const int entryPointSpecializationArgCount =
- int(request.entryPointSpecializationArgs.getCount());
- auto setEntryPointSpecializationArgs = [&](int entryPoint)
{
- for (int ii = 0; ii < entryPointSpecializationArgCount; ++ii)
+ ComPtr<slang::IBlob> diagnostics;
+ auto res = module->specialize(
+ moduleSpecializationArgs.getBuffer(),
+ moduleSpecializationArgs.getCount(),
+ (slang::IComponentType**)specializedModule.writeRef(),
+ diagnostics.writeRef());
+ if (SLANG_FAILED(res))
{
- spSetTypeNameForEntryPointExistentialTypeParam(
- slangRequest,
- entryPoint,
- ii,
- request.entryPointSpecializationArgs[ii].getBuffer());
+ fprintf(
+ stderr,
+ "error: Failed to specialize module: %s\n",
+ diagnostics ? (char*)diagnostics->getBufferPointer() : "(no diagnostic output)");
+ return res;
}
- };
+ }
Index explicitEntryPointCount = request.entryPoints.getCount();
for (Index ee = 0; ee < explicitEntryPointCount; ++ee)
@@ -192,107 +365,134 @@ static SlangResult _compileProgramImpl(
}
auto& entryPointInfo = request.entryPoints[ee];
- int entryPointIndex = spAddEntryPoint(
- slangRequest,
- translationUnitIndex,
- entryPointInfo.name,
- entryPointInfo.slangStage);
- SLANG_ASSERT(entryPointIndex == ee);
-
- setEntryPointSpecializationArgs(entryPointIndex);
- }
-
- spSetLineDirectiveMode(slangRequest, SLANG_LINE_DIRECTIVE_MODE_NONE);
-
- if (options.generateSPIRVDirectly)
- {
- if (options.disableDebugInfo)
- spSetDebugInfoLevel(slangRequest, SLANG_DEBUG_INFO_LEVEL_NONE);
- else
- spSetDebugInfoLevel(slangRequest, SLANG_DEBUG_INFO_LEVEL_STANDARD);
- }
-
- const SlangResult res = spCompile(slangRequest);
-
- if (auto diagnostics = spGetDiagnosticOutput(slangRequest))
- {
- StdWriters::getError().print("%s", diagnostics);
- }
-
- SLANG_RETURN_ON_FAIL(res);
-
- ComPtr<slang::IComponentType> linkedSlangProgram;
-
- List<ShaderCompileRequest::EntryPoint> actualEntryPoints;
- if (input.passThrough == SLANG_PASS_THROUGH_NONE)
- {
- // In the case where pass-through compilation is not being used,
- // we can use the Slang reflection information to discover what
- // the entry points were, and then use those to drive the
- // loading of code.
- //
- auto reflection = slang::ProgramLayout::get(slangRequest);
- SLANG_RETURN_ON_FAIL(spCompileRequest_getProgramWithEntryPoints(
- slangRequest,
- linkedSlangProgram.writeRef()));
-
- // Get the amount of entry points in reflection
- Index entryPointCount = Index(reflection->getEntryPointCount());
-
- // We must have at least one entry point (whether explicit or implicit)
- SLANG_ASSERT(entryPointCount);
- for (Index ee = 0; ee < entryPointCount; ++ee)
+ ComPtr<slang::IEntryPoint> entryPoint;
+ ComPtr<slang::IBlob> diagnostics;
+ auto res = module->findAndCheckEntryPoint(
+ entryPointInfo.name,
+ entryPointInfo.slangStage,
+ entryPoint.writeRef(),
+ diagnostics.writeRef());
+ if (SLANG_FAILED(res))
{
- auto entryPoint = reflection->getEntryPointByIndex(ee);
- const char* entryPointName = entryPoint->getName();
- SLANG_ASSERT(entryPointName);
+ fprintf(
+ stderr,
+ "error: Failed to find entry point '%s': %s\n",
+ entryPointInfo.name,
+ diagnostics ? (char*)diagnostics->getBufferPointer() : "(no diagnostic output)");
+ return res;
+ }
- auto slangStage = entryPoint->getStage();
+ const int entryPointSpecializationArgCount =
+ int(request.entryPointSpecializationArgs.getCount());
+ if (entryPointSpecializationArgCount != entryPoint->getSpecializationParamCount())
+ {
+ fprintf(
+ stderr,
+ "error: %s\n",
+ "The specialization argument count of the requested entry point does not match "
+ "that of the entry point!");
+ return SLANG_FAIL;
+ }
- ShaderCompileRequest::EntryPoint entryPointInfo;
- entryPointInfo.name = entryPointName;
- entryPointInfo.slangStage = slangStage;
+ List<slang::SpecializationArg> entryPointSpecializationArgs;
+ for (int ii = 0; ii < entryPointSpecializationArgCount; ++ii)
+ {
+ String specializedTypeName = request.entryPointSpecializationArgs[ii].getBuffer();
+ slang::TypeReflection* typeReflection =
+ module->getLayout()->findTypeByName(specializedTypeName.getBuffer());
+ entryPointSpecializationArgs.add(slang::SpecializationArg::fromType(typeReflection));
+ }
- actualEntryPoints.add(entryPointInfo);
+ ComPtr<slang::IEntryPoint> specializedEntryPoint;
+ {
+ ComPtr<slang::IBlob> diagnostics;
+ auto res = entryPoint->specialize(
+ entryPointSpecializationArgs.getBuffer(),
+ entryPointSpecializationArgs.getCount(),
+ (slang::IComponentType**)specializedEntryPoint.writeRef(),
+ diagnostics.writeRef());
+ if (SLANG_FAILED(res))
+ {
+ fprintf(
+ stderr,
+ "error: Failed to specialize entry point: %s\n",
+ diagnostics ? (char*)diagnostics->getBufferPointer()
+ : "(no diagnostic output)");
+ return res;
+ }
}
+ specializedEntryPoints.add(specializedEntryPoint);
}
- else
+
+ if (input.passThrough == SLANG_PASS_THROUGH_NONE)
{
- actualEntryPoints = request.entryPoints;
+ componentsRawPtr.add(specializedModule);
+ for (auto& specializedEntryPoint : specializedEntryPoints)
+ componentsRawPtr.add(specializedEntryPoint);
}
+ // This list just makes sure that the components get released
+ List<ComPtr<slang::ITypeConformance>> typeConformanceComponents;
if (request.typeConformances.getCount())
{
- ComPtr<slang::ISession> session;
- slangRequest->getSession(session.writeRef());
- List<ComPtr<slang::ITypeConformance>> typeConformanceComponents;
- List<slang::IComponentType*> componentsRawPtr;
- componentsRawPtr.add(linkedSlangProgram.get());
- auto reflection = slang::ProgramLayout::get(slangRequest);
- ComPtr<ISlangBlob> outDiagnostic;
+ auto reflection = module->getLayout();
for (auto& conformance : request.typeConformances)
{
+ ComPtr<ISlangBlob> outDiagnostic;
auto derivedType = reflection->findTypeByName(conformance.derivedTypeName.getBuffer());
auto baseType = reflection->findTypeByName(conformance.baseTypeName.getBuffer());
ComPtr<slang::ITypeConformance> conformanceComponentType;
- session->createTypeConformanceComponentType(
+ SlangResult res = slangSession->createTypeConformanceComponentType(
derivedType,
baseType,
conformanceComponentType.writeRef(),
conformance.idOverride,
outDiagnostic.writeRef());
+ if (SLANG_FAILED(res))
+ {
+ fprintf(
+ stderr,
+ "error: Failed to handle type conformances: %s\n",
+ outDiagnostic ? (char*)outDiagnostic->getBufferPointer()
+ : "(no diagnostic output)");
+ return res;
+ }
typeConformanceComponents.add(conformanceComponentType);
componentsRawPtr.add(conformanceComponentType);
}
- ComPtr<slang::IComponentType> newProgram;
- session->createCompositeComponentType(
+ }
+
+ ComPtr<slang::IComponentType> linkedSlangProgram;
+ if (componentsRawPtr.getCount() > 0)
+ {
+ ComPtr<slang::IComponentType> composite;
+ ComPtr<ISlangBlob> outDiagnostic;
+ SlangResult res = slangSession->createCompositeComponentType(
componentsRawPtr.getBuffer(),
componentsRawPtr.getCount(),
- newProgram.writeRef(),
+ composite.writeRef(),
outDiagnostic.writeRef());
- linkedSlangProgram = newProgram;
+ if (SLANG_FAILED(res))
+ {
+ fprintf(
+ stderr,
+ "error: Failed to create composite: %s\n",
+ outDiagnostic ? (char*)outDiagnostic->getBufferPointer()
+ : "(no diagnostic output)");
+ return res;
+ }
+ res = composite->link(linkedSlangProgram.writeRef(), outDiagnostic.writeRef());
+ if (SLANG_FAILED(res))
+ {
+ fprintf(
+ stderr,
+ "error: Failed to link program: %s\n",
+ outDiagnostic ? (char*)outDiagnostic->getBufferPointer()
+ : "(no diagnostic output)");
+ }
}
+
out.set(linkedSlangProgram);
return SLANG_OK;
}
@@ -348,13 +548,13 @@ static SlangResult compileProgram(
//
SLANG_RETURN_ON_FAIL(_compileProgramImpl(globalSession, options, input, request, out));
- out.m_requestDEPRECATED = slangOutput.m_requestDEPRECATED;
- // slangOutput.desc.slangGlobalScope and slangOutput.slangProgram are the same object, but
- // the latter is a ComPtr while the former isn't. Therefore we need to detach so that the
- // object doesn't get destroyed.
+ out.m_session = slangOutput.m_session;
+ // slangOutput.desc.slangGlobalScope and slangOutput.slangProgram are the same object,
+ // but the latter is a ComPtr while the former isn't. Therefore we need to detach so
+ // that the object doesn't get destroyed.
SLANG_ASSERT(slangOutput.desc.slangGlobalScope == slangOutput.slangProgram.get());
out.desc.slangGlobalScope = slangOutput.slangProgram.detach();
- slangOutput.m_requestDEPRECATED = nullptr;
+ slangOutput.m_session = nullptr;
return SLANG_OK;
}
}
diff --git a/tools/render-test/slang-support.h b/tools/render-test/slang-support.h
index 60e63b57f..916166c3a 100644
--- a/tools/render-test/slang-support.h
+++ b/tools/render-test/slang-support.h
@@ -67,7 +67,7 @@ struct ShaderCompilerUtil
ComPtr<slang::IComponentType> slangProgram;
ShaderProgramDesc desc = {};
- ComPtr<SlangCompileRequest> m_requestDEPRECATED = nullptr;
+ ComPtr<slang::ISession> m_session = nullptr;
slang::IGlobalSession* globalSession = nullptr;
};