summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/windows-selfhosted.yml2
-rw-r--r--build/visual-studio/slang/slang.vcxproj4
-rw-r--r--build/visual-studio/slang/slang.vcxproj.filters12
-rw-r--r--slang.h1
-rw-r--r--source/slang-glslang/slang-glslang.cpp2
-rw-r--r--source/slang/core.meta.slang37
-rw-r--r--source/slang/diff.meta.slang4
-rw-r--r--source/slang/hlsl.meta.slang38
-rw-r--r--source/slang/slang-ast-builder.cpp15
-rw-r--r--source/slang/slang-ast-builder.h2
-rw-r--r--source/slang/slang-ast-support-types.h3
-rw-r--r--source/slang/slang-ast-type.cpp5
-rw-r--r--source/slang/slang-ast-type.h3
-rw-r--r--source/slang/slang-check-conversion.cpp22
-rw-r--r--source/slang/slang-check-decl.cpp17
-rwxr-xr-xsource/slang/slang-compiler.h2
-rw-r--r--source/slang/slang-emit-c-like.cpp46
-rw-r--r--source/slang/slang-emit-cpp.cpp15
-rw-r--r--source/slang/slang-emit-glsl.cpp6
-rw-r--r--source/slang/slang-emit-spirv.cpp33
-rw-r--r--source/slang/slang-emit.cpp17
-rw-r--r--source/slang/slang-ir-autodiff-fwd.cpp5
-rw-r--r--source/slang/slang-ir-byte-address-legalize.cpp102
-rw-r--r--source/slang/slang-ir-inst-defs.h9
-rw-r--r--source/slang/slang-ir-insts.h18
-rw-r--r--source/slang/slang-ir-lower-buffer-element-type.cpp658
-rw-r--r--source/slang/slang-ir-lower-buffer-element-type.h20
-rw-r--r--source/slang/slang-ir-specialize-matrix-layout.cpp46
-rw-r--r--source/slang/slang-ir-specialize-matrix-layout.h16
-rw-r--r--source/slang/slang-ir-spirv-legalize.cpp28
-rw-r--r--source/slang/slang-ir-util.cpp48
-rw-r--r--source/slang/slang-ir-util.h1
-rw-r--r--source/slang/slang-ir-wrap-structured-buffers.cpp71
-rw-r--r--source/slang/slang-ir.cpp8
-rw-r--r--source/slang/slang-ir.h1
-rw-r--r--source/slang/slang-lower-to-ir.cpp5
-rw-r--r--source/slang/slang-options.cpp8
-rw-r--r--source/slang/slang-spirv-val.cpp32
-rw-r--r--source/slang/slang-type-layout.cpp28
-rw-r--r--source/slang/slang.natvis12
-rw-r--r--tests/compute/comma-operator.slang.glsl11
-rw-r--r--tests/compute/unbounded-array-of-array-syntax.slang.glsl3
-rw-r--r--tests/cross-compile/array-of-buffers.slang.glsl7
-rw-r--r--tests/cross-compile/array-of-buffers.slang.hlsl8
-rw-r--r--tests/cross-compile/func-resource-param-array.slang.glsl13
-rw-r--r--tests/diagnostics/bad-operator-call.slang26
-rw-r--r--tests/diagnostics/bad-operator-call.slang.expected70
-rw-r--r--tests/experimental/liveness/liveness-2.slang27
-rw-r--r--tests/experimental/liveness/liveness-2.slang.expected59
-rw-r--r--tests/experimental/liveness/liveness-3.slang49
-rw-r--r--tests/experimental/liveness/liveness-3.slang.expected134
-rw-r--r--tests/experimental/liveness/liveness-4.slang35
-rw-r--r--tests/experimental/liveness/liveness-4.slang.expected56
-rw-r--r--tests/experimental/liveness/liveness-5.slang42
-rw-r--r--tests/experimental/liveness/liveness-5.slang.expected98
-rw-r--r--tests/experimental/liveness/liveness-6.slang47
-rw-r--r--tests/experimental/liveness/liveness-6.slang.expected107
-rw-r--r--tests/experimental/liveness/liveness-7.slang34
-rw-r--r--tests/experimental/liveness/liveness-7.slang.expected66
-rw-r--r--tests/experimental/liveness/liveness.slang80
-rw-r--r--tests/experimental/liveness/liveness.slang.expected168
-rw-r--r--tests/hlsl-intrinsic/debug-break.slang7
-rw-r--r--tests/hlsl-intrinsic/debug-break.slang.expected24
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-assign.slang.1.expected3
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected3
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-miss.slang.1.expected3
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-nop.slang.1.expected3
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-output.slang.1.expected2
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected3
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected2
-rw-r--r--tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected2
-rw-r--r--tests/hlsl/glsl-matrix-layout.slang67
-rw-r--r--tests/hlsl/glsl-matrix-layout.slang.expected.txt14
-rw-r--r--tests/spirv/spirv-debug-break.slang6
-rw-r--r--tests/spirv/spirv-debug-break.slang.expected37
-rw-r--r--tools/slang-test/test-reporter.cpp7
76 files changed, 1370 insertions, 1355 deletions
diff --git a/.github/workflows/windows-selfhosted.yml b/.github/workflows/windows-selfhosted.yml
index 7d8d64199..62370feb4 100644
--- a/.github/workflows/windows-selfhosted.yml
+++ b/.github/workflows/windows-selfhosted.yml
@@ -40,5 +40,5 @@ jobs:
run: |
$slangTestBinDir = ".\bin\windows-${{matrix.testPlatform}}\${{matrix.configuration}}\";
$env:Path += ";$slangTestBinDir";
- & "$slangTestBinDir\slang-test.exe" -appveyor -bindir "$slangTestBinDir\" -platform ${{matrix.testPlatform}} -configuration ${{matrix.configuration}} -category ${{matrix.testCategory}} 2>&1;
+ & "$slangTestBinDir\slang-test.exe" -appveyor -bindir "$slangTestBinDir\" -platform ${{matrix.testPlatform}} -configuration ${{matrix.configuration}} -category ${{matrix.testCategory}} -api all-cpu 2>&1;
\ No newline at end of file
diff --git a/build/visual-studio/slang/slang.vcxproj b/build/visual-studio/slang/slang.vcxproj
index 20d84e0e4..7d655f0c5 100644
--- a/build/visual-studio/slang/slang.vcxproj
+++ b/build/visual-studio/slang/slang.vcxproj
@@ -406,6 +406,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClInclude Include="..\..\..\source\slang\slang-ir-loop-unroll.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-lower-binding-query.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-lower-bit-cast.h" />
+ <ClInclude Include="..\..\..\source\slang\slang-ir-lower-buffer-element-type.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-lower-com-methods.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-lower-error-handling.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-lower-existential.h" />
@@ -442,6 +443,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClInclude Include="..\..\..\source\slang\slang-ir-specialize-dispatch.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-specialize-dynamic-associatedtype-lookup.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-specialize-function-call.h" />
+ <ClInclude Include="..\..\..\source\slang\slang-ir-specialize-matrix-layout.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-specialize-resources.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-specialize.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-spirv-legalize.h" />
@@ -612,6 +614,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClCompile Include="..\..\..\source\slang\slang-ir-loop-unroll.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-lower-binding-query.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-lower-bit-cast.cpp" />
+ <ClCompile Include="..\..\..\source\slang\slang-ir-lower-buffer-element-type.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-lower-com-methods.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-lower-error-handling.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-lower-existential.cpp" />
@@ -648,6 +651,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClCompile Include="..\..\..\source\slang\slang-ir-specialize-dispatch.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-specialize-dynamic-associatedtype-lookup.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-specialize-function-call.cpp" />
+ <ClCompile Include="..\..\..\source\slang\slang-ir-specialize-matrix-layout.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-specialize-resources.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-specialize.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-spirv-legalize.cpp" />
diff --git a/build/visual-studio/slang/slang.vcxproj.filters b/build/visual-studio/slang/slang.vcxproj.filters
index 1ff77e487..8e8023520 100644
--- a/build/visual-studio/slang/slang.vcxproj.filters
+++ b/build/visual-studio/slang/slang.vcxproj.filters
@@ -306,6 +306,9 @@
<ClInclude Include="..\..\..\source\slang\slang-ir-lower-bit-cast.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\slang\slang-ir-lower-buffer-element-type.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\slang\slang-ir-lower-com-methods.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -414,6 +417,9 @@
<ClInclude Include="..\..\..\source\slang\slang-ir-specialize-function-call.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\slang\slang-ir-specialize-matrix-layout.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\slang\slang-ir-specialize-resources.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -920,6 +926,9 @@
<ClCompile Include="..\..\..\source\slang\slang-ir-lower-bit-cast.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\slang\slang-ir-lower-buffer-element-type.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\slang\slang-ir-lower-com-methods.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -1028,6 +1037,9 @@
<ClCompile Include="..\..\..\source\slang\slang-ir-specialize-function-call.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\slang\slang-ir-specialize-matrix-layout.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\slang\slang-ir-specialize-resources.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/slang.h b/slang.h
index ae62a2dd8..b799b5483 100644
--- a/slang.h
+++ b/slang.h
@@ -4131,7 +4131,6 @@ namespace slang
virtual SLANG_NO_THROW void SLANG_MCALL setReportPerfBenchmark(bool value) = 0;
-
};
#define SLANG_UUID_ICompileRequest ICompileRequest::getTypeGuid()
diff --git a/source/slang-glslang/slang-glslang.cpp b/source/slang-glslang/slang-glslang.cpp
index bbf154a69..32834232f 100644
--- a/source/slang-glslang/slang-glslang.cpp
+++ b/source/slang-glslang/slang-glslang.cpp
@@ -509,7 +509,7 @@ static spv_target_env _getUniversalTargetEnv(glslang::EShTargetLanguageVersion i
return SPV_ENV_UNIVERSAL_1_2;
}
-static int glslang_compileGLSLToSPIRV(const glslang_CompileRequest_1_2& request)
+static int glslang_compileGLSLToSPIRV(glslang_CompileRequest_1_2 request)
{
// Check that the encoding matches
assert(glslang::EShTargetSpv_1_4 == _makeTargetLanguageVersion(1, 4));
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 257d5930b..ebf4b5d76 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -894,8 +894,11 @@ struct vector
__init(vector<T,N> value);
}
+const int kRowMajorMatrixLayout = $(SLANG_MATRIX_LAYOUT_ROW_MAJOR);
+const int kColumnMajorMatrixLayout = $(SLANG_MATRIX_LAYOUT_COLUMN_MAJOR);
+
/// A matrix with `R` rows and `C` columns, with elements of type `T`.
-__generic<T = float, let R : int = 4, let C : int = 4>
+__generic<T = float, let R : int = 4, let C : int = 4, let L : int = $(SLANG_MATRIX_LAYOUT_MODE_UNKNOWN)>
__magic_type(MatrixExpressionType)
struct matrix
{
@@ -1111,7 +1114,7 @@ for (int tt = 0; tt < kBaseTypeCount; ++tt)
for( int R = 2; R <= 4; ++R )
for( int C = 2; C <= 4; ++C )
{
- sb << "__generic<T> __extension matrix<T, " << R << "," << C << ">\n{\n";
+ sb << "__generic<T, let L:int> __extension matrix<T, " << R << "," << C << ", L>\n{\n";
// initialize from R*C scalars
sb << "__intrinsic_op(" << int(kIROp_MakeMatrix) << ") __init(";
@@ -1137,7 +1140,7 @@ for( int C = 2; C <= 4; ++C )
for( int cc = C; cc <= 4; ++cc )
{
if(rr == R && cc == C) continue;
- sb << "__intrinsic_op(" << int(kIROp_MatrixReshape) << ") __init(matrix<T," << rr << "," << cc << "> value);\n";
+ sb << "__intrinsic_op(" << int(kIROp_MatrixReshape) << ") __init(matrix<T," << rr << "," << cc << ", L> value);\n";
}
sb << "}\n";
}
@@ -1207,16 +1210,16 @@ extension vector<T, N> : IDifferentiable
}
}
-__generic<T:__BuiltinFloatingPointType, let R: int, let C: int>
-extension matrix<T, R, C> : IDifferentiable
+__generic<T:__BuiltinFloatingPointType, let R: int, let C: int, let L : int>
+extension matrix<T, R, C, L> : IDifferentiable
{
- typedef matrix<T, R, C> Differential;
+ typedef matrix<T, R, C, L> Differential;
[__unsafeForceInlineEarly]
[BackwardDifferentiable]
static Differential dzero()
{
- return matrix<T, R, C>(__slang_noop_cast<T>(T.dzero()));
+ return matrix<T, R, C, L>(__slang_noop_cast<T>(T.dzero()));
}
[__unsafeForceInlineEarly]
@@ -2425,9 +2428,9 @@ vector<T,N> operator$(op.name)(in out vector<T,N> value)
{$(fixity.bodyPrefix) value = value $(op.binOp) T(1); return $(fixity.returnVal); }
$(fixity.qual)
-__generic<T : __BuiltinArithmeticType, let R : int, let C : int>
+__generic<T : __BuiltinArithmeticType, let R : int, let C : int, let L : int>
[__unsafeForceInlineEarly]
-matrix<T,R,C> operator$(op.name)(in out matrix<T,R,C> value)
+matrix<T,R,C> operator$(op.name)(in out matrix<T,R,C,L> value)
{$(fixity.bodyPrefix) value = value $(op.binOp) T(1); return $(fixity.returnVal); }
$(fixity.qual)
@@ -2609,9 +2612,9 @@ __generic<L: __BuiltinIntegerType, R: __BuiltinIntegerType, let N : int, let M :
__intrinsic_op($(info.op))
matrix<L,N,M> operator$(info.name)(matrix<L,N,M> left, matrix<R,N,M> right);
-__generic<L: __BuiltinIntegerType, R: __BuiltinIntegerType, let N : int, let M : int>
+__generic<L: __BuiltinIntegerType, R: __BuiltinIntegerType, let N : int, let M : int, let Layout : int>
[__unsafeForceInlineEarly]
-matrix<L, N, M> operator$(info.name)=(in out matrix<L, N, M> left, matrix<R, N, M> right)
+matrix<L, N, M> operator$(info.name)=(in out matrix<L, N, M, Layout> left, matrix<R, N, M> right)
{
left = left $(info.name) right;
return left;
@@ -2641,9 +2644,9 @@ __generic<L: __BuiltinIntegerType, R: __BuiltinIntegerType, let N : int, let M :
__intrinsic_op($(info.op))
matrix<L,N,M> operator$(info.name)(matrix<L,N,M> left, R right);
-__generic<L: __BuiltinIntegerType, R: __BuiltinIntegerType, let N : int, let M : int>
+__generic<L: __BuiltinIntegerType, R: __BuiltinIntegerType, let N : int, let M : int, let Layout : int>
[__unsafeForceInlineEarly]
-matrix<L,N,M> operator$(info.name)=(in out matrix<L,N,M> left, R right)
+matrix<L,N,M> operator$(info.name)=(in out matrix<L,N,M, Layout> left, R right)
{
left = left $(info.name) right;
return left;
@@ -2696,17 +2699,17 @@ ${{{{
return left;
}
- __generic<T : $(op.interface), let R : int, let C : int>
+ __generic<T : $(op.interface), let R : int, let C : int, let Layout : int>
[__unsafeForceInlineEarly]
- matrix<T,R,C> operator$(op.name)=(in out matrix<T,R,C> left, matrix<T,R,C> right)
+ matrix<T,R,C> operator$(op.name)=(in out matrix<T,R,C,Layout> left, matrix<T,R,C> right)
{
left = left $(op.name) right;
return left;
}
- __generic<T : $(op.interface), let R : int, let C : int>
+ __generic<T : $(op.interface), let R : int, let C : int, let Layout : int>
[__unsafeForceInlineEarly]
- matrix<T,R,C> operator$(op.name)=(in out matrix<T,R,C> left, T right)
+ matrix<T,R,C> operator$(op.name)=(in out matrix<T,R,C, Layout> left, T right)
{
left = left $(op.name) right;
return left;
diff --git a/source/slang/diff.meta.slang b/source/slang/diff.meta.slang
index 3e381e55d..ce0e72d34 100644
--- a/source/slang/diff.meta.slang
+++ b/source/slang/diff.meta.slang
@@ -1403,11 +1403,11 @@ void __sincos_impl(vector<T, N> x, out vector<T, N> s, out vector<T, N> c)
c = cos(x);
}
-__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>
+__generic<T : __BuiltinFloatingPointType, let N : int, let M : int, let L1 : int, let L2 : int>
[BackwardDifferentiable]
[PrimalSubstituteOf(sincos)]
[PreferRecompute]
-void __sincos_impl(matrix<T, N, M> x, out matrix<T, N, M> s, out matrix<T, N, M> c)
+void __sincos_impl(matrix<T, N, M> x, out matrix<T, N, M, L1> s, out matrix<T, N, M, L2> c)
{
s = sin(x);
c = cos(x);
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 9de14ad96..015b1c4ad 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -235,19 +235,20 @@ struct StructuredBuffer
out uint numStructs,
out uint stride);
- __target_intrinsic(glsl, "$0._data[$1]")
- __target_intrinsic(spirv_direct, "%addr = OpAccessChain resultType*StorageBuffer resultId _0 const(int, 0) _1; OpLoad resultType resultId %addr;")
- [__readNone]
+ //__target_intrinsic(glsl, "$0._data[$1]")
+ //__target_intrinsic(spirv_direct, "%addr = OpAccessChain resultType*StorageBuffer resultId _0 const(int, 0) _1; OpLoad resultType resultId %addr;")
+ __intrinsic_op($(kIROp_StructuredBufferLoad))
T Load(int location);
- [__readNone]
+ __intrinsic_op($(kIROp_StructuredBufferLoadStatus))
T Load(int location, out uint status);
__subscript(uint index) -> T
{
- __target_intrinsic(glsl, "$0._data[$1]")
- __target_intrinsic(spirv_direct, "%addr = OpAccessChain resultType*StorageBuffer resultId _0 const(int, 0) _1; OpLoad resultType resultId %addr;")
+ //__target_intrinsic(glsl, "$0._data[$1]")
+ //__target_intrinsic(spirv_direct, "%addr = OpAccessChain resultType*StorageBuffer resultId _0 const(int, 0) _1; OpLoad resultType resultId %addr;")
[__readNone]
+ __intrinsic_op($(kIROp_StructuredBufferLoad))
get;
};
};
@@ -709,7 +710,6 @@ static const struct {
for(auto item : kMutableStructuredBufferCases) {
}}}}
-
__generic<T>
__magic_type(HLSL$(item.name)Type)
__intrinsic_type($(item.op))
@@ -724,18 +724,22 @@ struct $(item.name)
uint IncrementCounter();
- __target_intrinsic(glsl, "$0._data[$1]")
- __target_intrinsic(spirv_direct, "%addr = OpAccessChain resultType*StorageBuffer resultId _0 const(int, 0) _1; OpLoad resultType resultId %addr;")
+ //__target_intrinsic(glsl, "$0._data[$1]")
+ //__target_intrinsic(spirv_direct, "%addr = OpAccessChain resultType*StorageBuffer resultId _0 const(int, 0) _1; OpLoad resultType resultId %addr;")
[__NoSideEffect]
+ __intrinsic_op($(kIROp_RWStructuredBufferLoad))
T Load(int location);
+
[__NoSideEffect]
+ __intrinsic_op($(kIROp_RWStructuredBufferLoadStatus))
T Load(int location, out uint status);
__subscript(uint index) -> T
{
- __target_intrinsic(glsl, "$0._data[$1]")
- __target_intrinsic(spirv_direct, "*StorageBuffer OpAccessChain resultType resultId _0 const(int, 0) _1")
+ //__target_intrinsic(glsl, "$0._data[$1]")
+ //__target_intrinsic(spirv_direct, "*StorageBuffer OpAccessChain resultType resultId _0 const(int, 0) _1")
[__NoSideEffect]
+ __intrinsic_op($(kIROp_RWStructuredBufferGetElementPtr))
ref;
}
};
@@ -2248,10 +2252,10 @@ vector<T, N> frexp(vector<T, N> x, out vector<T, N> exp)
VECTOR_MAP_BINARY(T, N, frexp, x, exp);
}
-__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>
+__generic<T : __BuiltinFloatingPointType, let N : int, let M : int, let L : int>
__target_intrinsic(hlsl)
[__readNone]
-matrix<T, N, M> frexp(matrix<T, N, M> x, out matrix<T, N, M> exp)
+matrix<T, N, M> frexp(matrix<T, N, M> x, out matrix<T, N, M, L> exp)
{
MATRIX_MAP_BINARY(T, N, M, frexp, x, exp);
}
@@ -2924,10 +2928,10 @@ vector<T,N> modf(vector<T,N> x, out vector<T,N> ip)
VECTOR_MAP_BINARY(T, N, modf, x, ip);
}
-__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>
+__generic<T : __BuiltinFloatingPointType, let N : int, let M : int, let L : int>
__target_intrinsic(hlsl)
[__readNone]
-matrix<T,N,M> modf(matrix<T,N,M> x, out matrix<T,N,M> ip)
+matrix<T,N,M> modf(matrix<T,N,M> x, out matrix<T,N,M,L> ip)
{
MATRIX_MAP_BINARY(T, N, M, modf, x, ip);
}
@@ -3664,10 +3668,10 @@ void sincos(vector<T,N> x, out vector<T,N> s, out vector<T,N> c)
c = cos(x);
}
-__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>
+__generic<T : __BuiltinFloatingPointType, let N : int, let M : int, let L1: int, let L2 : int>
__target_intrinsic(hlsl)
[__readNone]
-void sincos(matrix<T,N,M> x, out matrix<T,N,M> s, out matrix<T,N,M> c)
+void sincos(matrix<T,N,M> x, out matrix<T,N,M,L1> s, out matrix<T,N,M,L2> c)
{
s = sin(x);
c = cos(x);
diff --git a/source/slang/slang-ast-builder.cpp b/source/slang/slang-ast-builder.cpp
index bb4f53433..a76f6e07f 100644
--- a/source/slang/slang-ast-builder.cpp
+++ b/source/slang/slang-ast-builder.cpp
@@ -383,6 +383,21 @@ VectorExpressionType* ASTBuilder::getVectorType(
return as<VectorExpressionType>(getSpecializedBuiltinType(makeArrayView(args), "VectorExpressionType"));
}
+MatrixExpressionType* ASTBuilder::getMatrixType(Type* elementType, IntVal* rowCount, IntVal* colCount, IntVal* layout)
+{
+ // Canonicalize constant size arguments to int.
+ if (auto rowCountConstantInt = as<ConstantIntVal>(rowCount))
+ {
+ rowCount = getIntVal(getIntType(), rowCountConstantInt->getValue());
+ }
+ if (auto colCountConstantInt = as<ConstantIntVal>(colCount))
+ {
+ colCount = getIntVal(getIntType(), colCountConstantInt->getValue());
+ }
+ Val* args[] = { elementType, rowCount, colCount, layout };
+ return as<MatrixExpressionType>(getSpecializedBuiltinType(makeArrayView(args), "MatrixExpressionType"));
+}
+
DifferentialPairType* ASTBuilder::getDifferentialPairType(
Type* valueType,
Witness* primalIsDifferentialWitness)
diff --git a/source/slang/slang-ast-builder.h b/source/slang/slang-ast-builder.h
index 5c0e74851..2674ef1b2 100644
--- a/source/slang/slang-ast-builder.h
+++ b/source/slang/slang-ast-builder.h
@@ -424,6 +424,8 @@ public:
VectorExpressionType* getVectorType(Type* elementType, IntVal* elementCount);
+ MatrixExpressionType* getMatrixType(Type* elementType, IntVal* rowCount, IntVal* colCount, IntVal* layout);
+
ConstantBufferType* getConstantBufferType(Type* elementType);
ParameterBlockType* getParameterBlockType(Type* elementType);
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h
index 9140be967..b1d3a34a2 100644
--- a/source/slang/slang-ast-support-types.h
+++ b/source/slang/slang-ast-support-types.h
@@ -80,6 +80,9 @@ namespace Slang
// No conversion at all
kConversionCost_None = 0,
+ // Convert between matrices of different layout
+ kConversionCost_MatrixLayout = 5,
+
// Conversion from a buffer to the type it carries needs to add a minimal
// extra cost, just so we can distinguish an overload on `ConstantBuffer<Foo>`
// from one on `Foo`
diff --git a/source/slang/slang-ast-type.cpp b/source/slang/slang-ast-type.cpp
index 7ea5e8ed1..6d4a52cae 100644
--- a/source/slang/slang-ast-type.cpp
+++ b/source/slang/slang-ast-type.cpp
@@ -238,6 +238,11 @@ IntVal* MatrixExpressionType::getColumnCount()
return as<IntVal>(_getGenericTypeArg(this, 2));
}
+IntVal* MatrixExpressionType::getLayout()
+{
+ return as<IntVal>(_getGenericTypeArg(this, 3));
+}
+
Type* MatrixExpressionType::getRowType()
{
if (!rowType)
diff --git a/source/slang/slang-ast-type.h b/source/slang/slang-ast-type.h
index f3dc975a3..c2a13542d 100644
--- a/source/slang/slang-ast-type.h
+++ b/source/slang/slang-ast-type.h
@@ -435,7 +435,7 @@ class VectorExpressionType : public ArithmeticExpressionType
IntVal* getElementCount();
};
-// A matrix type, e.g., `matrix<T,R,C>`
+// A matrix type, e.g., `matrix<T,R,C,L>`
class MatrixExpressionType : public ArithmeticExpressionType
{
SLANG_AST_CLASS(MatrixExpressionType)
@@ -443,6 +443,7 @@ class MatrixExpressionType : public ArithmeticExpressionType
Type* getElementType();
IntVal* getRowCount();
IntVal* getColumnCount();
+ IntVal* getLayout();
Type* getRowType();
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp
index 09a783fb4..5a9c8df12 100644
--- a/source/slang/slang-check-conversion.cpp
+++ b/source/slang/slang-check-conversion.cpp
@@ -894,6 +894,28 @@ namespace Slang
}
return true;
}
+ // matrix type with different layouts are convertible
+ if (auto fromMatrixType = as<MatrixExpressionType>(fromType))
+ {
+ if (auto toMatrixType = as<MatrixExpressionType>(toType))
+ {
+ if (fromMatrixType->getElementType()->equals(toMatrixType->getElementType()) &&
+ fromMatrixType->getRowCount()->equals(toMatrixType->getRowCount()) &&
+ fromMatrixType->getColumnCount()->equals(toMatrixType->getColumnCount()))
+ {
+ if (outCost)
+ {
+ *outCost = kConversionCost_MatrixLayout;
+ }
+ if (outToExpr)
+ {
+ *outToExpr = fromExpr;
+ }
+ return true;
+ }
+ }
+
+ }
// A type is always convertible to any of its supertypes.
//
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 4e8a00907..6385e5f57 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -1069,6 +1069,23 @@ namespace Slang
validateArraySizeForVariable(varDecl);
}
+ // If there is a matrix layout modifier, we will modify the matrix type now.
+ if (auto matrixType = as<MatrixExpressionType>(varDecl->type.type))
+ {
+ if (auto matrixLayoutModifier = varDecl->findModifier<MatrixLayoutModifier>())
+ {
+ auto matrixLayout = as<ColumnMajorLayoutModifier>(matrixLayoutModifier) ? SLANG_MATRIX_LAYOUT_COLUMN_MAJOR : SLANG_MATRIX_LAYOUT_ROW_MAJOR;
+ auto newMatrixType = getASTBuilder()->getMatrixType(
+ matrixType->getElementType(),
+ matrixType->getRowCount(),
+ matrixType->getColumnCount(),
+ getASTBuilder()->getIntVal(getASTBuilder()->getIntType(), matrixLayout));
+ varDecl->type.type = newMatrixType;
+ if (varDecl->initExpr)
+ varDecl->initExpr = coerce(CoercionSite::Initializer, varDecl->type, varDecl->initExpr);
+ }
+ }
+
checkMeshOutputDecl(varDecl);
// The NVAPI library allows user code to express extended operations
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index a6231d959..e42e97b89 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -1783,7 +1783,6 @@ namespace Slang
char const* value);
SlangResult setMatrixLayoutMode(
SlangMatrixLayoutMode mode);
-
/// Create an initially-empty linkage
Linkage(Session* session, ASTBuilder* astBuilder, Linkage* builtinLinkage);
@@ -2672,6 +2671,7 @@ namespace Slang
virtual SLANG_NO_THROW void SLANG_MCALL setDebugInfoFormat(SlangDebugInfoFormat format) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL setReportDownstreamTime(bool value) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL setReportPerfBenchmark(bool value) SLANG_OVERRIDE;
+
void setHLSLToVulkanLayoutOptions(int targetIndex, HLSLToVulkanLayoutOptions* vulkanLayoutOptions);
EndToEndCompileRequest(
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index 0cc3a196b..95c691d8b 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -2146,6 +2146,52 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
}
break;
+ case kIROp_StructuredBufferLoad:
+ case kIROp_RWStructuredBufferLoad:
+ {
+ auto base = inst->getOperand(0);
+ emitOperand(base, outerPrec);
+ m_writer->emit(".Load(");
+ emitOperand(inst->getOperand(1), EmitOpInfo());
+ m_writer->emit(")");
+ }
+ break;
+
+ case kIROp_StructuredBufferLoadStatus:
+ case kIROp_RWStructuredBufferLoadStatus:
+ {
+ auto base = inst->getOperand(0);
+ emitOperand(base, outerPrec);
+ m_writer->emit(".Load(");
+ emitOperand(inst->getOperand(1), EmitOpInfo());
+ m_writer->emit(", ");
+ emitOperand(inst->getOperand(2), EmitOpInfo());
+ m_writer->emit(")");
+ }
+ break;
+
+ case kIROp_RWStructuredBufferGetElementPtr:
+ {
+ auto base = inst->getOperand(0);
+ emitOperand(base, outerPrec);
+ m_writer->emit("[");
+ emitOperand(inst->getOperand(1), EmitOpInfo());
+ m_writer->emit("]");
+ }
+ break;
+
+ case kIROp_RWStructuredBufferStore:
+ {
+ auto base = inst->getOperand(0);
+ emitOperand(base, EmitOpInfo());
+ m_writer->emit(".Store(");
+ emitOperand(inst->getOperand(1), EmitOpInfo());
+ m_writer->emit(", ");
+ emitOperand(inst->getOperand(2), EmitOpInfo());
+ m_writer->emit(")");
+ }
+ break;
+
case kIROp_Call:
{
emitCallExpr((IRCall*)inst, outerPrec);
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 83af4ad47..dee8e7197 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -1391,13 +1391,24 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
auto outerPrec = getInfo(EmitOp::General);
auto prec = getInfo(EmitOp::Postfix);
emitOperand(baseInst, leftSide(outerPrec, prec));
- m_writer->emit("->rows + ");
+ m_writer->emit("->rows + (");
emitOperand(getElementInst->getIndex(), getInfo(EmitOp::General));
- m_writer->emit(")");
+ m_writer->emit("))");
return true;
}
return false;
}
+ case kIROp_RWStructuredBufferGetElementPtr:
+ {
+ m_writer->emit("(&(");
+ auto base = inst->getOperand(0);
+ auto outerPrec = getInfo(EmitOp::General);
+ emitOperand(base, outerPrec);
+ m_writer->emit("[");
+ emitOperand(inst->getOperand(1), EmitOpInfo());
+ m_writer->emit("]))");
+ return true;
+ }
case kIROp_swizzle:
{
// For C++ we don't need to emit a swizzle function
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index 22a0c323b..0920c236c 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -1959,6 +1959,10 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
return true;
}
case kIROp_StructuredBufferLoad:
+ case kIROp_StructuredBufferLoadStatus:
+ case kIROp_RWStructuredBufferLoad:
+ case kIROp_RWStructuredBufferLoadStatus:
+ case kIROp_RWStructuredBufferGetElementPtr:
{
auto outerPrec = inOuterPrec;
auto prec = getInfo(EmitOp::Postfix);
@@ -1972,7 +1976,7 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
maybeCloseParens(needClose);
return true;
}
- case kIROp_StructuredBufferStore:
+ case kIROp_RWStructuredBufferStore:
{
auto outerPrec = inOuterPrec;
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index c16ee6a90..bafbb79f1 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -1619,6 +1619,15 @@ struct SPIRVEmitContext
return emitLoad(parent, as<IRLoad>(inst));
case kIROp_Store:
return emitStore(parent, as<IRStore>(inst));
+ case kIROp_StructuredBufferLoad:
+ case kIROp_StructuredBufferLoadStatus:
+ case kIROp_RWStructuredBufferLoad:
+ case kIROp_RWStructuredBufferLoadStatus:
+ return emitStructuredBufferLoad(parent, inst);
+ case kIROp_RWStructuredBufferStore:
+ return emitStructuredBufferStore(parent, inst);
+ case kIROp_RWStructuredBufferGetElementPtr:
+ return emitStructuredBufferGetElementPtr(parent, inst);
case kIROp_swizzle:
return emitSwizzle(parent, as<IRSwizzle>(inst));
case kIROp_IntCast:
@@ -2645,6 +2654,30 @@ struct SPIRVEmitContext
return emitInst(parent, inst, SpvOpStore, inst->getPtr(), inst->getVal());
}
+ SpvInst* emitStructuredBufferLoad(SpvInstParent* parent, IRInst* inst)
+ {
+ //"%addr = OpAccessChain resultType*StorageBuffer resultId _0 const(int, 0) _1; OpLoad resultType resultId %addr;"
+ IRBuilder builder(inst);
+ auto addr = emitInst(parent, inst, SpvOpAccessChain, inst->getOperand(0)->getDataType(), kResultID, inst->getOperand(0), emitIntConstant(0, builder.getIntType()), inst->getOperand(1));
+ return emitInst(parent, inst, SpvOpLoad, inst->getFullType(), kResultID, addr);
+ }
+
+ SpvInst* emitStructuredBufferStore(SpvInstParent* parent, IRInst* inst)
+ {
+ //"%addr = OpAccessChain resultType*StorageBuffer resultId _0 const(int, 0) _1; OpStore %addr _2;"
+ IRBuilder builder(inst);
+ auto addr = emitInst(parent, inst, SpvOpAccessChain, inst->getOperand(0)->getDataType(), kResultID, inst->getOperand(0), emitIntConstant(0, builder.getIntType()), inst->getOperand(1));
+ return emitInst(parent, inst, SpvOpStore, addr, inst->getOperand(2));
+ }
+
+ SpvInst* emitStructuredBufferGetElementPtr(SpvInstParent* parent, IRInst* inst)
+ {
+ //"%addr = OpAccessChain resultType*StorageBuffer resultId _0 const(int, 0) _1;"
+ IRBuilder builder(inst);
+ auto addr = emitInst(parent, inst, SpvOpAccessChain, inst->getDataType(), kResultID, inst->getOperand(0), emitIntConstant(0, builder.getIntType()), inst->getOperand(1));
+ return addr;
+ }
+
SpvInst* emitSwizzle(SpvInstParent* parent, IRSwizzle* inst)
{
if (inst->getElementCount() == 1)
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 343c18916..4b95ca9c8 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -49,6 +49,7 @@
#include "slang-ir-specialize-arrays.h"
#include "slang-ir-specialize-buffer-load-arg.h"
#include "slang-ir-specialize-resources.h"
+#include "slang-ir-specialize-matrix-layout.h"
#include "slang-ir-ssa.h"
#include "slang-ir-ssa-simplification.h"
#include "slang-ir-strip-cached-dict.h"
@@ -59,6 +60,7 @@
#include "slang-ir-liveness.h"
#include "slang-ir-glsl-liveness.h"
#include "slang-ir-legalize-uniform-buffer-load.h"
+#include "slang-ir-lower-buffer-element-type.h"
#include "slang-ir-string-hash.h"
#include "slang-ir-simplify-for-emit.h"
#include "slang-ir-pytorch-cpp-binding.h"
@@ -353,6 +355,9 @@ Result linkAndOptimizeIR(
simplifyIR(irModule, sink);
+ // Fill in default matrix layout into matrix types that left layout unspecified.
+ specializeMatrixLayout(codeGenContext->getTargetReq(), irModule);
+
// It's important that this takes place before defunctionalization as we
// want to be able to easily discover the cooperate and fallback funcitons
// being passed to saturated_cooperation
@@ -588,10 +593,6 @@ Result linkAndOptimizeIR(
}
eliminateDeadCode(irModule);
- // Rewrite functions that return arrays to return them via `out` parameter,
- // since our target languages doesn't allow returning arrays.
- legalizeArrayReturnType(irModule);
-
#if 0
dumpIRIfEnabled(codeGenContext, irModule, "AFTER RESOURCE SPECIALIZATION");
#endif
@@ -857,6 +858,14 @@ Result linkAndOptimizeIR(
// arrays that the emitters can deal with.
legalizeMeshOutputTypes(irModule);
+ // We need to lower any types used in a buffer resource (e.g. ContantBuffer or StructuredBuffer) into
+ // a simple storage type that has target independent layout.
+ lowerBufferElementTypeToStorageType(targetRequest, irModule);
+
+ // Rewrite functions that return arrays to return them via `out` parameter,
+ // since our target languages doesn't allow returning arrays.
+ legalizeArrayReturnType(irModule);
+
if (isKhronosTarget(targetRequest) || target == CodeGenTarget::HLSL)
{
legalizeUniformBufferLoad(irModule);
diff --git a/source/slang/slang-ir-autodiff-fwd.cpp b/source/slang/slang-ir-autodiff-fwd.cpp
index f1099547c..efaaec906 100644
--- a/source/slang/slang-ir-autodiff-fwd.cpp
+++ b/source/slang/slang-ir-autodiff-fwd.cpp
@@ -1858,7 +1858,10 @@ InstPair ForwardDiffTranscriber::transcribeInstImpl(IRBuilder* builder, IRInst*
case kIROp_ByteAddressBufferLoad:
case kIROp_ByteAddressBufferStore:
case kIROp_StructuredBufferLoad:
- case kIROp_StructuredBufferStore:
+ case kIROp_RWStructuredBufferLoad:
+ case kIROp_RWStructuredBufferLoadStatus:
+ case kIROp_RWStructuredBufferStore:
+ case kIROp_RWStructuredBufferGetElementPtr:
case kIROp_Reinterpret:
case kIROp_IsType:
case kIROp_ImageSubscript:
diff --git a/source/slang/slang-ir-byte-address-legalize.cpp b/source/slang/slang-ir-byte-address-legalize.cpp
index 14f985c3b..a6d0acee7 100644
--- a/source/slang/slang-ir-byte-address-legalize.cpp
+++ b/source/slang/slang-ir-byte-address-legalize.cpp
@@ -212,6 +212,15 @@ struct ByteAddressBufferLegalizationContext
return getNaturalOffset(target, field, outOffset);
}
+ SlangResult getSizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAndAlignment* outSizeAlignment)
+ {
+ if (target->getHLSLToVulkanLayoutOptions() && target->getHLSLToVulkanLayoutOptions()->shouldUseGLLayout())
+ {
+ return getStd430SizeAndAlignment(target, type, outSizeAlignment);
+ }
+ return getNaturalSizeAndAlignment(target, type, outSizeAlignment);
+ }
+
// The core workhorse routine for the load case is `emitLegalLoad`,
// which tries to emit load operations that read a value of the
// given `type` from the given `buffer` at the required `baseOffset`
@@ -312,23 +321,42 @@ struct ByteAddressBufferLegalizationContext
// small detail that we need to construct the row type
// that we expect to load for each "element."
//
- // TODO: The logic here assumes row-major layout, because
- // the row-vs-column-major information has been dropped
- // by this point in the IR.
- //
- // In order to allow both row- and column-major matrices
- // to be loaded from byte-address buffers, we would need
- // to make row-vs-column-major-ness be part of the IR
- // type system so that IR layout can take it into account.
- //
- // For now we have to live with the "natural" layout of
- // matrices always being row-major.
- //
- auto rowCountInst = as<IRIntLit>(matType->getRowCount());
- if( rowCountInst )
+ if (getIntVal(matType->getLayout()) != SLANG_MATRIX_LAYOUT_COLUMN_MAJOR)
{
- auto rowType = m_builder.getVectorType(matType->getElementType(), matType->getColumnCount());
- return emitLegalSequenceLoad(type, buffer, baseOffset, immediateOffset, kIROp_MakeMatrix, rowType, rowCountInst->getValue());
+ auto rowCountInst = as<IRIntLit>(matType->getRowCount());
+ if( rowCountInst )
+ {
+ auto rowType = m_builder.getVectorType(matType->getElementType(), matType->getColumnCount());
+ return emitLegalSequenceLoad(type, buffer, baseOffset, immediateOffset, kIROp_MakeMatrix, rowType, rowCountInst->getValue());
+ }
+ }
+ else
+ {
+ List<IRInst*> elements;
+ auto colCount = (Index)getIntVal(matType->getColumnCount());
+ auto rowCount = (Index)getIntVal(matType->getRowCount());
+ auto colVectorType = m_builder.getVectorType(matType->getElementType(), rowCount);
+ IRSizeAndAlignment colVectorSizeAlignment;
+ getSizeAndAlignment(m_target, colVectorType, &colVectorSizeAlignment);
+ for (Index c = 0; c < colCount; c++)
+ {
+ auto colVector = emitLegalLoad(colVectorType, buffer, baseOffset, immediateOffset);
+ for (Index r = 0; r < rowCount; r++)
+ {
+ elements.add(m_builder.emitElementExtract(colVector, (IRIntegerValue)r));
+ }
+ immediateOffset += colVectorSizeAlignment.getStride();
+ }
+ List<IRInst*> args;
+ for (Index r = 0; r < rowCount; r++)
+ {
+ for (Index c = 0; c < colCount; c++)
+ {
+ auto index = c * rowCount + r;
+ args.add(elements[index]);
+ }
+ }
+ return m_builder.emitMakeMatrix(matType, (UInt)args.getCount(), args.getBuffer());
}
}
else if( auto vecType = as<IRVectorType>(type) )
@@ -832,14 +860,40 @@ struct ByteAddressBufferLegalizationContext
}
else if( auto matType = as<IRMatrixType>(type) )
{
- // Matrix storesget the same caveat as the load case:
- // we are only supporting row-major layout for now.
- //
- auto rowCountInst = as<IRIntLit>(matType->getRowCount());
- if( rowCountInst )
+ auto layout = getIntVal(matType->getLayout());
+ if (layout != SLANG_MATRIX_LAYOUT_COLUMN_MAJOR)
{
- auto rowType = m_builder.getVectorType(matType->getElementType(), matType->getColumnCount());
- return emitLegalSequenceStore(buffer, baseOffset, immediateOffset, value, rowType, rowCountInst->getValue());
+ auto rowCountInst = as<IRIntLit>(matType->getRowCount());
+ if( rowCountInst )
+ {
+ auto rowType = m_builder.getVectorType(matType->getElementType(), matType->getColumnCount());
+ return emitLegalSequenceStore(buffer, baseOffset, immediateOffset, value, rowType, rowCountInst->getValue());
+ }
+ }
+ else
+ {
+ auto colCount = (Index)getIntVal(matType->getColumnCount());
+ auto rowCount = (Index)getIntVal(matType->getRowCount());
+ List<IRInst*> srcRows;
+ for (Index r = 0; r < rowCount; r++)
+ srcRows.add(m_builder.emitElementExtract(value, (IRIntegerValue)r));
+ for (Index c = 0; c < colCount; c++)
+ {
+ List<IRInst*> colVectorArgs;
+ for (Index r = 0; r < rowCount; r++)
+ {
+ auto rowVector = srcRows[r];
+ auto element = m_builder.emitElementExtract(rowVector, (IRIntegerValue)c);
+ colVectorArgs.add(element);
+ }
+ auto colVectorType = m_builder.getVectorType(matType->getElementType(), rowCount);
+ auto colVector = m_builder.emitMakeVector(colVectorType, colVectorArgs);
+ IRSizeAndAlignment colVectorSizeAlignment;
+ getSizeAndAlignment(m_target, colVectorType, &colVectorSizeAlignment);
+ emitLegalStore(colVectorType, buffer, baseOffset, immediateOffset, colVector);
+ immediateOffset += colVectorSizeAlignment.getStride();
+ }
+ return SLANG_OK;
}
}
else if( auto vecType = as<IRVectorType>(type) )
@@ -903,7 +957,7 @@ struct ByteAddressBufferLegalizationContext
auto index = m_builder.emitIntrinsicInst(indexType, kIROp_Div, 2, divArgs);
IRInst* args[] = { structuredBuffer, index, value };
- m_builder.emitIntrinsicInst(type, kIROp_StructuredBufferStore, 3, args);
+ m_builder.emitIntrinsicInst(type, kIROp_RWStructuredBufferStore, 3, args);
return SLANG_OK;
}
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index 062da75e8..c3c92f9ba 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -52,7 +52,7 @@ INST(Nop, nop, 0, 0)
INST(BasicBlockType, BasicBlock, 0, HOISTABLE)
INST(VectorType, Vec, 2, HOISTABLE)
- INST(MatrixType, Mat, 3, HOISTABLE)
+ INST(MatrixType, Mat, 4, HOISTABLE)
INST(ConjunctionType, Conjunction, 0, HOISTABLE)
INST(AttributedType, Attributed, 0, HOISTABLE)
@@ -427,6 +427,9 @@ INST(ByteAddressBufferStore, byteAddressBufferStore, 3, 0)
// - `dst` is a value of type T
//
INST(StructuredBufferLoad, structuredBufferLoad, 2, 0)
+INST(StructuredBufferLoadStatus, structuredBufferLoadStatus, 3, 0)
+INST(RWStructuredBufferLoad, rwstructuredBufferLoad, 2, 0)
+INST(RWStructuredBufferLoadStatus, rwstructuredBufferLoadStatus, 3, 0)
// Store data to a structured buffer
//
@@ -437,7 +440,9 @@ INST(StructuredBufferLoad, structuredBufferLoad, 2, 0)
// - `offset` is an `int`
// - `src` is a value of type T
//
-INST(StructuredBufferStore, structuredBufferStore, 3, 0)
+INST(RWStructuredBufferStore, rwstructuredBufferStore, 3, 0)
+
+INST(RWStructuredBufferGetElementPtr, rwstructuredBufferGetElementPtr, 2, 0)
INST(MeshOutputRef, meshOutputRef, 2, 0)
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index 2d8393698..dfd662be3 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -1979,6 +1979,14 @@ struct IRStore : IRInst
IRInst* getVal() { return val.get(); }
};
+struct IRRWStructuredBufferStore : IRInst
+{
+ IR_LEAF_ISA(RWStructuredBufferStore)
+ IRInst* getStructuredBuffer() { return getOperand(0); }
+ IRInst* getIndex() { return getOperand(1); }
+ IRInst* getVal() { return getOperand(2); }
+};
+
struct IRFieldExtract : IRInst
{
IRUse base;
@@ -2015,6 +2023,13 @@ struct IRGetElementPtr : IRInst
IRInst* getIndex() { return getOperand(1); }
};
+struct IRRWStructuredBufferGetElementPtr : IRInst
+{
+ IR_LEAF_ISA(RWStructuredBufferGetElementPtr);
+ IRInst* getBase() { return getOperand(0); }
+ IRInst* getIndex() { return getOperand(1); }
+};
+
struct IRLoadReverseGradient : IRInst
{
IR_LEAF_ISA(LoadReverseGradient)
@@ -2957,7 +2972,8 @@ public:
IRMatrixType* getMatrixType(
IRType* elementType,
IRInst* rowCount,
- IRInst* columnCount);
+ IRInst* columnCount,
+ IRInst* layout);
IRArrayListType* getArrayListType(IRType* elementType);
IRTensorViewType* getTensorViewType(IRType* elementType);
diff --git a/source/slang/slang-ir-lower-buffer-element-type.cpp b/source/slang/slang-ir-lower-buffer-element-type.cpp
new file mode 100644
index 000000000..3ef94d415
--- /dev/null
+++ b/source/slang/slang-ir-lower-buffer-element-type.cpp
@@ -0,0 +1,658 @@
+#include "slang-ir-lower-buffer-element-type.h"
+#include "slang-ir.h"
+#include "slang-ir-insts.h"
+#include "slang-ir-util.h"
+#include "slang-ir-clone.h"
+
+namespace Slang
+{
+ struct LoweredElementTypeContext
+ {
+ struct LoweredElementTypeInfo
+ {
+ IRType* originalType;
+ IRType* loweredType;
+ IRType* loweredInnerArrayType = nullptr; // For matrix/array types that are lowered into a struct type, this is the inner array type of the data field.
+ IRStructKey* loweredInnerStructKey = nullptr; // For matrix/array types that are lowered into a struct type, this is the struct key of the data field.
+ IRFunc* convertOriginalToLowered = nullptr;
+ IRFunc* convertLoweredToOriginal = nullptr;
+ };
+ Dictionary<IRType*, LoweredElementTypeInfo> loweredTypeInfo;
+ Dictionary<IRType*, LoweredElementTypeInfo> mapLoweredTypeToInfo;
+
+ SlangMatrixLayoutMode defaultMatrixLayout = SLANG_MATRIX_LAYOUT_ROW_MAJOR;
+
+ LoweredElementTypeContext(SlangMatrixLayoutMode inDefaultMatrixLayout)
+ : defaultMatrixLayout(inDefaultMatrixLayout)
+ {}
+
+ IRFunc* createMatrixUnpackFunc(
+ IRMatrixType* matrixType,
+ IRStructType* structType,
+ IRStructKey* dataKey,
+ IRArrayType* arrayType)
+ {
+ IRBuilder builder(structType);
+ builder.setInsertAfter(structType);
+ auto func = builder.createFunc();
+ auto funcType = builder.getFuncType(1, (IRType**)&structType, matrixType);
+ func->setFullType(funcType);
+ builder.addNameHintDecoration(func, UnownedStringSlice("unpackStorage"));
+ builder.setInsertInto(func);
+ builder.emitBlock();
+ auto rowCount = (Index)getIntVal(matrixType->getRowCount());
+ auto colCount = (Index)getIntVal(matrixType->getColumnCount());
+ auto packedParam = builder.emitParam(structType);
+ auto vectorArray = builder.emitFieldExtract(arrayType, packedParam, dataKey);
+ List<IRInst*> args;
+ args.setCount(rowCount * colCount);
+ if (getIntVal(matrixType->getLayout()) == SLANG_MATRIX_LAYOUT_COLUMN_MAJOR)
+ {
+ for (IRIntegerValue c = 0; c < colCount; c++)
+ {
+ auto vector = builder.emitElementExtract(vectorArray, c);
+ for (IRIntegerValue r = 0; r < rowCount; r++)
+ {
+ auto element = builder.emitElementExtract(vector, r);
+ args[(Index)(r*colCount + c)] = element;
+ }
+ }
+ }
+ else
+ {
+ for (IRIntegerValue r = 0; r < rowCount; r++)
+ {
+ auto vector = builder.emitElementExtract(vectorArray, r);
+ for (IRIntegerValue c = 0; c < colCount; c++)
+ {
+ auto element = builder.emitElementExtract(vector, c);
+ args[(Index)(r * colCount + c)] = element;
+ }
+ }
+ }
+ IRInst* result = builder.emitMakeMatrix(matrixType, (UInt)args.getCount(), args.getBuffer());
+ builder.emitReturn(result);
+ return func;
+ }
+
+ IRFunc* createMatrixPackFunc(
+ IRMatrixType* matrixType,
+ IRStructType* structType,
+ IRVectorType* vectorType,
+ IRArrayType* arrayType)
+ {
+ IRBuilder builder(structType);
+ builder.setInsertAfter(structType);
+ auto func = builder.createFunc();
+ auto funcType = builder.getFuncType(1, (IRType**)&matrixType, structType);
+ func->setFullType(funcType);
+ builder.addNameHintDecoration(func, UnownedStringSlice("packMatrix"));
+ builder.setInsertInto(func);
+ builder.emitBlock();
+ auto rowCount = getIntVal(matrixType->getRowCount());
+ auto colCount = getIntVal(matrixType->getColumnCount());
+ auto originalParam = builder.emitParam(matrixType);
+ List<IRInst*> elements;
+ elements.setCount((Index)(rowCount * colCount));
+ for (IRIntegerValue r = 0; r < rowCount; r++)
+ {
+ auto vector = builder.emitElementExtract(originalParam, r);
+ for (IRIntegerValue c = 0; c < colCount; c++)
+ {
+ auto element = builder.emitElementExtract(vector, c);
+ elements[(Index)(r * colCount + c)] = element;
+ }
+ }
+ List<IRInst*> vectors;
+ if (getIntVal(matrixType->getLayout()) == SLANG_MATRIX_LAYOUT_COLUMN_MAJOR)
+ {
+ for (IRIntegerValue c = 0; c < colCount; c++)
+ {
+ List<IRInst*> vecArgs;
+ for (IRIntegerValue r = 0; r < rowCount; r++)
+ {
+ auto element = elements[(Index)(r * colCount + c)];
+ vecArgs.add(element);
+ }
+ auto colVector = builder.emitMakeVector(vectorType, (UInt)vecArgs.getCount(), vecArgs.getBuffer());
+ vectors.add(colVector);
+ }
+ }
+ else
+ {
+ for (IRIntegerValue r = 0; r < rowCount; r++)
+ {
+ List<IRInst*> vecArgs;
+ for (IRIntegerValue c = 0; c < colCount; c++)
+ {
+ auto element = elements[(Index)(r * colCount + c)];
+ vecArgs.add(element);
+ }
+ auto rowVector = builder.emitMakeVector(vectorType, (UInt)vecArgs.getCount(), vecArgs.getBuffer());
+ vectors.add(rowVector);
+ }
+ }
+
+ auto vectorArray = builder.emitMakeArray(arrayType, (UInt)vectors.getCount(), vectors.getBuffer());
+ auto result = builder.emitMakeStruct(structType, 1, &vectorArray);
+ builder.emitReturn(result);
+ return func;
+ }
+
+ IRFunc* createArrayUnpackFunc(
+ IRArrayType* arrayType,
+ IRStructType* structType,
+ IRStructKey* dataKey,
+ IRArrayType* innerArrayType,
+ LoweredElementTypeInfo innerTypeInfo)
+ {
+ IRBuilder builder(structType);
+ builder.setInsertAfter(structType);
+ auto func = builder.createFunc();
+ auto funcType = builder.getFuncType(1, (IRType**)&structType, arrayType);
+ func->setFullType(funcType);
+ builder.addNameHintDecoration(func, UnownedStringSlice("unpackStorage"));
+ builder.setInsertInto(func);
+ builder.emitBlock();
+ auto packedParam = builder.emitParam(structType);
+ auto packedArray = builder.emitFieldExtract(innerArrayType, packedParam, dataKey);
+ auto count = getIntVal(arrayType->getElementCount());
+ List<IRInst*> args;
+ args.setCount((Index)count);
+ for (IRIntegerValue ii = 0; ii < count; ++ii)
+ {
+ auto packedElement = builder.emitElementExtract(packedArray, ii);
+ auto originalElement = builder.emitCallInst(innerTypeInfo.originalType, innerTypeInfo.convertLoweredToOriginal, 1, &packedElement);
+ args[(Index)ii] = originalElement;
+ }
+ auto result = builder.emitMakeArray(arrayType, (UInt)args.getCount(), args.getBuffer());
+ builder.emitReturn(result);
+ return func;
+ }
+
+ IRFunc* createArrayPackFunc(
+ IRArrayType* arrayType,
+ IRStructType* structType,
+ IRArrayType* innerArrayType,
+ LoweredElementTypeInfo innerTypeInfo)
+ {
+ IRBuilder builder(structType);
+ builder.setInsertAfter(structType);
+ auto func = builder.createFunc();
+ auto funcType = builder.getFuncType(1, (IRType**)&structType, arrayType);
+ func->setFullType(funcType);
+ builder.addNameHintDecoration(func, UnownedStringSlice("packStorage"));
+ builder.setInsertInto(func);
+ builder.emitBlock();
+ auto originalParam = builder.emitParam(arrayType);
+ auto count = getIntVal(arrayType->getElementCount());
+ List<IRInst*> args;
+ args.setCount((Index)count);
+ for (IRIntegerValue ii = 0; ii < count; ++ii)
+ {
+ auto originalElement = builder.emitElementExtract(originalParam, ii);
+ auto packedElement = builder.emitCallInst(innerTypeInfo.loweredType, innerTypeInfo.convertOriginalToLowered, 1, &originalElement);
+ args[(Index)ii] = packedElement;
+ }
+ auto packedArray = builder.emitMakeArray(innerArrayType, (UInt)args.getCount(), args.getBuffer());
+ auto result = builder.emitMakeStruct(structType, 1, &packedArray);
+ builder.emitReturn(result);
+ return func;
+ }
+
+ LoweredElementTypeInfo getLoweredTypeInfoImpl(IRType* type)
+ {
+ IRBuilder builder(type);
+ builder.setInsertAfter(type);
+
+ LoweredElementTypeInfo info;
+ info.originalType = type;
+
+ if (auto matrixType = as<IRMatrixType>(type))
+ {
+ if (getIntVal(matrixType->getLayout()) == defaultMatrixLayout)
+ {
+ info.loweredType = type;
+ return info;
+ }
+
+ auto loweredType = builder.createStructType();
+ StringBuilder nameSB;
+ bool isColMajor = getIntVal(matrixType->getLayout()) == SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
+ nameSB << "_MatrixStorage_";
+ getTypeNameHint(nameSB, matrixType->getElementType());
+ nameSB << getIntVal(matrixType->getRowCount()) << "x" << getIntVal(matrixType->getColumnCount());
+ if (isColMajor)
+ nameSB << "_ColMajor";
+ builder.addNameHintDecoration(loweredType, nameSB.produceString().getUnownedSlice());
+ auto structKey = builder.createStructKey();
+ builder.addNameHintDecoration(structKey, UnownedStringSlice("data"));
+ auto vectorType = builder.getVectorType(matrixType->getElementType(),
+ isColMajor?matrixType->getRowCount():matrixType->getColumnCount());
+ auto arrayType = builder.getArrayType(vectorType, isColMajor?matrixType->getColumnCount():matrixType->getRowCount());
+ builder.createStructField(loweredType, structKey, arrayType);
+
+ info.loweredType = loweredType;
+ info.loweredInnerArrayType = arrayType;
+ info.loweredInnerStructKey = structKey;
+ info.convertLoweredToOriginal = createMatrixUnpackFunc(matrixType, loweredType, structKey, arrayType);
+ info.convertOriginalToLowered = createMatrixPackFunc(matrixType, loweredType, vectorType, arrayType);
+ return info;
+ }
+ else if (auto arrayType = as<IRArrayType>(type))
+ {
+ auto loweredInnerTypeInfo = getLoweredTypeInfo(arrayType->getElementType());
+
+ if (loweredInnerTypeInfo.loweredType != loweredInnerTypeInfo.originalType)
+ {
+ auto loweredType = builder.createStructType();
+ info.loweredType = loweredType;
+ StringBuilder nameSB;
+ nameSB << "_ArrayStorage_";
+ getTypeNameHint(nameSB, arrayType->getElementType());
+ nameSB << getIntVal(arrayType->getElementCount());
+ builder.addNameHintDecoration(loweredType, nameSB.produceString().getUnownedSlice());
+ auto structKey = builder.createStructKey();
+ builder.addNameHintDecoration(structKey, UnownedStringSlice("data"));
+ auto innerArrayType = builder.getArrayType(loweredInnerTypeInfo.loweredType, arrayType->getElementCount());
+ builder.createStructField(loweredType, structKey, innerArrayType);
+ info.loweredInnerArrayType = innerArrayType;
+ info.loweredInnerStructKey = structKey;
+ info.convertLoweredToOriginal = createArrayUnpackFunc(arrayType, loweredType, structKey, innerArrayType, loweredInnerTypeInfo);
+ info.convertOriginalToLowered = createArrayPackFunc(arrayType, loweredType, innerArrayType, loweredInnerTypeInfo);
+ }
+ else
+ {
+ info.loweredType = type;
+ }
+ return info;
+ }
+ else if (auto structType = as<IRStructType>(type))
+ {
+ bool hasNonTrivialField = false;
+ List<LoweredElementTypeInfo> fieldLoweredTypeInfo;
+ for (auto field : structType->getFields())
+ {
+ auto loweredFieldTypeInfo = getLoweredTypeInfo(field->getFieldType());
+ fieldLoweredTypeInfo.add(loweredFieldTypeInfo);
+ if (loweredFieldTypeInfo.loweredType != loweredFieldTypeInfo.originalType)
+ hasNonTrivialField = true;
+ }
+
+ if (!hasNonTrivialField)
+ {
+ info.loweredType = type;
+ return info;
+ }
+
+ auto loweredType = builder.createStructType();
+ StringBuilder nameSB;
+ getTypeNameHint(nameSB, type);
+ nameSB << "_Storage";
+ builder.addNameHintDecoration(loweredType, nameSB.produceString().getUnownedSlice());
+ info.loweredType = loweredType;
+
+ // Create fields.
+ {
+ Index fieldId = 0;
+ for (auto field : structType->getFields())
+ {
+ auto loweredFieldTypeInfo = fieldLoweredTypeInfo[fieldId];
+ builder.createStructField(loweredType, field->getKey(), loweredFieldTypeInfo.loweredType);
+ fieldId++;
+ }
+ }
+
+ // Create unpack func.
+ {
+ builder.setInsertAfter(loweredType);
+ info.convertLoweredToOriginal = builder.createFunc();
+ builder.setInsertInto(info.convertLoweredToOriginal);
+ builder.addNameHintDecoration(info.convertLoweredToOriginal, UnownedStringSlice("unpackStorage"));
+ info.convertLoweredToOriginal->setFullType(builder.getFuncType(1, (IRType**)&loweredType, type));
+ builder.emitBlock();
+ auto loweredParam = builder.emitParam(loweredType);
+ List<IRInst*> args;
+ Index fieldId = 0;
+ for (auto field : structType->getFields())
+ {
+ auto storageField = builder.emitFieldExtract(fieldLoweredTypeInfo[fieldId].loweredType, loweredParam, field->getKey());
+ auto unpackedField = fieldLoweredTypeInfo[fieldId].convertLoweredToOriginal
+ ? builder.emitCallInst(field->getFieldType(), fieldLoweredTypeInfo[fieldId].convertLoweredToOriginal, 1, &storageField)
+ : storageField;
+ args.add(unpackedField);
+ fieldId++;
+ }
+ auto result = builder.emitMakeStruct(type, args);
+ builder.emitReturn(result);
+ }
+
+ // Create pack func.
+ {
+ builder.setInsertAfter(info.convertLoweredToOriginal);
+ info.convertOriginalToLowered = builder.createFunc();
+ builder.setInsertInto(info.convertOriginalToLowered);
+ builder.addNameHintDecoration(info.convertOriginalToLowered, UnownedStringSlice("packStorage"));
+ info.convertOriginalToLowered->setFullType(builder.getFuncType(1, (IRType**)&type, loweredType));
+ builder.emitBlock();
+ auto param = builder.emitParam(type);
+ List<IRInst*> args;
+ Index fieldId = 0;
+ for (auto field : structType->getFields())
+ {
+ auto fieldVal = builder.emitFieldExtract(type, param, field->getKey());
+ auto packedField = fieldLoweredTypeInfo[fieldId].convertOriginalToLowered
+ ? builder.emitCallInst(fieldLoweredTypeInfo[fieldId].loweredType, fieldLoweredTypeInfo[fieldId].convertOriginalToLowered, 1, &fieldVal)
+ : fieldVal;
+ args.add(packedField);
+ fieldId++;
+ }
+ auto result = builder.emitMakeStruct(loweredType, args);
+ builder.emitReturn(result);
+ }
+
+ return info;
+ }
+
+ info.loweredType = type;
+ return info;
+ }
+
+ LoweredElementTypeInfo getLoweredTypeInfo(IRType* type)
+ {
+ LoweredElementTypeInfo info;
+ if (loweredTypeInfo.tryGetValue(type, info))
+ return info;
+ info = getLoweredTypeInfoImpl(type);
+ loweredTypeInfo[type] = info;
+ mapLoweredTypeToInfo[info.loweredType] = info;
+ return info;
+ }
+
+ IRType* getLoweredPtrLikeType(IRType* originalPtrLikeType, IRType* newElementType)
+ {
+ if (as<IRPointerLikeType>(originalPtrLikeType) || as<IRPtrTypeBase>(originalPtrLikeType) || as<IRHLSLStructuredBufferTypeBase>(originalPtrLikeType))
+ {
+ IRBuilder builder(newElementType);
+ builder.setInsertAfter(newElementType);
+ return builder.getType(originalPtrLikeType->getOp(), newElementType);
+ }
+ SLANG_UNREACHABLE("unhandled ptr like or buffer type");
+ }
+
+ IRInst* getStoreVal(IRInst* storeInst)
+ {
+ if (auto store = as<IRStore>(storeInst))
+ return store->getVal();
+ else if (auto sbStore = as<IRRWStructuredBufferStore>(storeInst))
+ return sbStore->getVal();
+ return nullptr;
+ }
+
+ void processModule(IRModule* module)
+ {
+ IRBuilder builder(module);
+ struct BufferTypeInfo
+ {
+ IRType* bufferType;
+ IRType* elementType;
+ };
+ List<BufferTypeInfo> bufferTypeInsts;
+ for (auto globalInst : module->getGlobalInsts())
+ {
+ IRType* elementType = nullptr;
+ if (auto structBuffer = as<IRHLSLStructuredBufferTypeBase>(globalInst))
+ elementType = structBuffer->getElementType();
+ else if (auto constBuffer = as<IRUniformParameterGroupType>(globalInst))
+ elementType = constBuffer->getElementType();
+ if (as<IRTextureBufferType>(globalInst))
+ continue;
+ if (!as<IRStructType>(elementType) && !as<IRMatrixType>(elementType) && !as<IRArrayType>(elementType))
+ continue;
+ bufferTypeInsts.add(BufferTypeInfo{ (IRType*)globalInst, elementType });
+ }
+
+ // Maintain a pending work list of all matrix addresses, and try to lower them out of existance
+ // after everything else has been lowered.
+ List<IRInst*> matrixAddrInsts;
+
+ for (auto bufferTypeInfo : bufferTypeInsts)
+ {
+ auto bufferType = bufferTypeInfo.bufferType;
+ auto elementType = bufferTypeInfo.elementType;
+ auto loweredBufferElementTypeInfo = getLoweredTypeInfo(elementType);
+
+ // If the lowered type is the same as original type, no change is required.
+ if (!loweredBufferElementTypeInfo.convertLoweredToOriginal)
+ continue;
+
+ builder.setInsertBefore(bufferType);
+
+ auto loweredBufferType = builder.getType(
+ bufferType->getOp(),
+ loweredBufferElementTypeInfo.loweredType);
+
+ // We treat a value of a buffer type as a pointer, and use a work list to translate
+ // all loads and stores through the pointer values that needs lowering.
+
+ List<IRInst*> ptrValsWorkList;
+ traverseUses(bufferType, [&](IRUse* use)
+ {
+ auto user = use->getUser();
+ if (use != &user->typeUse)
+ return;
+ ptrValsWorkList.add(use->getUser());
+ });
+
+ // Translate the values to use new lowered buffer type instead.
+ for (Index i = 0; i < ptrValsWorkList.getCount(); i++)
+ {
+ auto ptrVal = ptrValsWorkList[i];
+ auto oldPtrType = ptrVal->getFullType();
+ auto originalElementType = oldPtrType->getOperand(0);
+ auto loweredElementTypeInfo = getLoweredTypeInfo((IRType*)originalElementType);
+ if (!loweredElementTypeInfo.convertLoweredToOriginal)
+ continue;
+
+ ptrVal->setFullType(getLoweredPtrLikeType(ptrVal->getFullType(), loweredElementTypeInfo.loweredType));
+
+ traverseUses(ptrVal, [&](IRUse* use)
+ {
+ auto user = use->getUser();
+ switch (user->getOp())
+ {
+ case kIROp_Load:
+ case kIROp_StructuredBufferLoad:
+ case kIROp_StructuredBufferLoadStatus:
+ case kIROp_RWStructuredBufferLoad:
+ case kIROp_RWStructuredBufferLoadStatus:
+ {
+ IRCloneEnv cloneEnv = {};
+ builder.setInsertBefore(user);
+ auto newLoad = cloneInst(&cloneEnv, &builder, user);
+ newLoad->setFullType(loweredElementTypeInfo.loweredType);
+ auto unpackedVal = builder.emitCallInst(elementType, loweredElementTypeInfo.convertLoweredToOriginal, 1, &newLoad);
+ user->replaceUsesWith(unpackedVal);
+ user->removeAndDeallocate();
+ break;
+ }
+ case kIROp_Store:
+ case kIROp_RWStructuredBufferStore:
+ {
+ // Use must be the dest operand of the store inst.
+ if (use != user->getOperands() + 0)
+ break;
+ IRCloneEnv cloneEnv = {};
+ builder.setInsertBefore(user);
+ auto originalVal = getStoreVal(user);
+ auto packedVal = builder.emitCallInst(loweredElementTypeInfo.loweredType, loweredElementTypeInfo.convertOriginalToLowered, 1, &originalVal);
+ if (auto store = as<IRStore>(user))
+ store->val.set(packedVal);
+ else if (auto sbStore = as<IRRWStructuredBufferStore>(user))
+ sbStore->setOperand(2, packedVal);
+ else
+ SLANG_UNREACHABLE("unhandled store type");
+ break;
+ }
+ case kIROp_GetElementPtr:
+ case kIROp_FieldAddress:
+ {
+ // If original type is an array, the lowered type will be a struct.
+ // In that case, all existing address insts should be appended with a field extract.
+ if (as<IRArrayType>(originalElementType))
+ {
+ builder.setInsertBefore(user);
+ List<IRInst*> args;
+ for (UInt i = 0; i < user->getOperandCount(); i++)
+ args.add(user->getOperand(i));
+ auto newArrayPtrVal = builder.emitFieldAddress(
+ builder.getPtrType(loweredElementTypeInfo.loweredInnerArrayType),
+ ptrVal,
+ loweredElementTypeInfo.loweredInnerStructKey);
+ builder.replaceOperand(use, newArrayPtrVal);
+ ptrValsWorkList.add(user);
+ }
+ else if (as<IRMatrixType>(originalElementType))
+ {
+ // We are tring to get a pointer to a lowered matrix element.
+ // We process this insts at a later phase.
+ SLANG_ASSERT(user->getOp() == kIROp_GetElementPtr);
+ matrixAddrInsts.add(user);
+ }
+ else
+ {
+ // If we getting a derived address from the pointer, we need to recursively
+ // lower the new address. We do so by pushing the address inst into the
+ // work list.
+ ptrValsWorkList.add(user);
+ }
+ }
+ break;
+ case kIROp_RWStructuredBufferGetElementPtr:
+ ptrValsWorkList.add(user);
+ break;
+ default:
+ SLANG_UNREACHABLE("unhandled inst of a buffer/pointer value that needs storage lowering.");
+ break;
+ }
+ });
+ }
+
+ // Replace all remaining uses of bufferType to loweredBufferType, these uses are non-operational and should be
+ // directly replaceable, such as uses in `IRFuncType`.
+ bufferType->replaceUsesWith(loweredBufferType);
+ bufferType->removeAndDeallocate();
+ }
+
+ lowerMatrixAddresses(module, matrixAddrInsts);
+ }
+
+ // Lower all getElementPtr insts of a lowered matrix out of existance.
+ void lowerMatrixAddresses(IRModule* module, List<IRInst*>& matrixAddrInsts)
+ {
+ IRBuilder builder(module);
+ for (auto majorAddr : matrixAddrInsts)
+ {
+ auto majorGEP = as<IRGetElementPtr>(majorAddr);
+ SLANG_ASSERT(majorGEP);
+ auto loweredMatrixType = cast<IRPtrTypeBase>(majorGEP->getBase()->getFullType())->getValueType();
+ auto matrixTypeInfo = mapLoweredTypeToInfo.tryGetValue(loweredMatrixType);
+ SLANG_ASSERT(matrixTypeInfo);
+ auto matrixType = as<IRMatrixType>(matrixTypeInfo->originalType);
+ auto rowCount = getIntVal(matrixType->getRowCount());
+ traverseUses(majorAddr, [&](IRUse* use)
+ {
+ auto user = use->getUser();
+ builder.setInsertBefore(user);
+ switch (user->getOp())
+ {
+ case kIROp_Load:
+ {
+ IRInst* resultInst = nullptr;
+ auto dataPtr = builder.emitFieldAddress(
+ builder.getPtrType(matrixTypeInfo->loweredInnerArrayType),
+ majorGEP->getBase(),
+ matrixTypeInfo->loweredInnerStructKey);
+ if (getIntVal(matrixType->getLayout()) == SLANG_MATRIX_LAYOUT_COLUMN_MAJOR)
+ {
+ List<IRInst*> args;
+ for (IRIntegerValue i = 0; i < rowCount; i++)
+ {
+ auto vector = builder.emitLoad(builder.emitElementAddress(dataPtr, i));
+ auto element = builder.emitElementExtract(vector, majorGEP->getIndex());
+ args.add(element);
+ }
+ resultInst = builder.emitMakeVector(builder.getVectorType(matrixType->getElementType(), (IRIntegerValue)args.getCount()), args);
+ }
+ else
+ {
+ auto element = builder.emitElementAddress(dataPtr, majorGEP->getIndex());
+ resultInst = builder.emitLoad(element);
+ }
+ user->replaceUsesWith(resultInst);
+ user->removeAndDeallocate();
+ }
+ break;
+ case kIROp_Store:
+ {
+ auto storeInst = cast<IRStore>(user);
+ if (storeInst->getOperand(0) != majorAddr)
+ break;
+ auto dataPtr = builder.emitFieldAddress(
+ builder.getPtrType(matrixTypeInfo->loweredInnerArrayType),
+ majorGEP->getBase(),
+ matrixTypeInfo->loweredInnerStructKey);
+ if (getIntVal(matrixType->getLayout()) == SLANG_MATRIX_LAYOUT_COLUMN_MAJOR)
+ {
+ for (IRIntegerValue i = 0; i < rowCount; i++)
+ {
+ auto vectorAddr = builder.emitElementAddress(dataPtr, i);
+ auto elementAddr = builder.emitElementAddress(vectorAddr, majorGEP->getIndex());
+ builder.emitStore(elementAddr, builder.emitElementExtract(storeInst->getVal(), i));
+ }
+ }
+ else
+ {
+ auto rowAddr = builder.emitElementAddress(dataPtr, majorGEP->getIndex());
+ builder.emitStore(rowAddr, storeInst->getVal());
+ user->removeAndDeallocate();
+ }
+ break;
+ }
+ case kIROp_GetElementPtr:
+ {
+ auto gep2 = cast<IRGetElementPtr>(user);
+ auto rowIndex = majorGEP->getIndex();
+ auto colIndex = gep2->getIndex();
+ if (getIntVal(matrixType->getLayout()) == SLANG_MATRIX_LAYOUT_COLUMN_MAJOR)
+ {
+ Swap(rowIndex, colIndex);
+ }
+ auto dataPtr = builder.emitFieldAddress(
+ builder.getPtrType(matrixTypeInfo->loweredInnerArrayType),
+ majorGEP->getBase(),
+ matrixTypeInfo->loweredInnerStructKey);
+ auto vectorAddr = builder.emitElementAddress(dataPtr, rowIndex);
+ auto elementAddr = builder.emitElementAddress(vectorAddr, colIndex);
+ gep2->replaceUsesWith(elementAddr);
+ gep2->removeAndDeallocate();
+ break;
+ }
+ default:
+ SLANG_UNREACHABLE("unhandled inst of a matrix address inst that needs storage lowering.");
+ break;
+ }
+ });
+ }
+ }
+ };
+
+ void lowerBufferElementTypeToStorageType(TargetRequest* target, IRModule* module)
+ {
+ SlangMatrixLayoutMode defaultMatrixMode = (SlangMatrixLayoutMode)target->getDefaultMatrixLayoutMode();
+ if (defaultMatrixMode == SLANG_MATRIX_LAYOUT_MODE_UNKNOWN)
+ defaultMatrixMode = SLANG_MATRIX_LAYOUT_ROW_MAJOR;
+ LoweredElementTypeContext context(defaultMatrixMode);
+ context.processModule(module);
+ }
+}
diff --git a/source/slang/slang-ir-lower-buffer-element-type.h b/source/slang/slang-ir-lower-buffer-element-type.h
new file mode 100644
index 000000000..bbee71df4
--- /dev/null
+++ b/source/slang/slang-ir-lower-buffer-element-type.h
@@ -0,0 +1,20 @@
+#ifndef SLANG_IR_LOWER_BUFFER_ELEMENT_TYPE_H
+#define SLANG_IR_LOWER_BUFFER_ELEMENT_TYPE_H
+
+namespace Slang
+{
+ struct IRModule;
+ class TargetRequest;
+
+ // For each struct type S used as element type of a ConstantBuffer, ParameterBlock or [RW]StructuredBuffer,
+ // we create a lowered type L, where matrix types are lowered to arrays of vectors based on major-ness,
+ // and loads from the buffer are converted to L_to_S(load(buffer)), and stores to the buffer are
+ // converted to store(buffer, S_to_L(val)).
+ // This pass needs to take place after type legalization, and before array return type lowering
+ // because it may create functions that returns array typed values.
+ //
+ void lowerBufferElementTypeToStorageType(TargetRequest* target, IRModule* module);
+
+}
+
+#endif
diff --git a/source/slang/slang-ir-specialize-matrix-layout.cpp b/source/slang/slang-ir-specialize-matrix-layout.cpp
new file mode 100644
index 000000000..5ce61f4cf
--- /dev/null
+++ b/source/slang/slang-ir-specialize-matrix-layout.cpp
@@ -0,0 +1,46 @@
+#include "slang-ir-specialize-matrix-layout.h"
+#include "slang-ir.h"
+#include "slang-ir-insts.h"
+#include "slang-compiler.h"
+
+namespace Slang
+{
+
+ void visitParent(List<IRMatrixType*>& typeWorkList, IRInst* parent)
+ {
+ for (auto child : parent->getChildren())
+ {
+ if (auto matrixType = as<IRMatrixType>(child))
+ {
+ if (auto constLayout = as<IRIntLit>(matrixType->getLayout()))
+ {
+ if (constLayout->getValue() == SLANG_MATRIX_LAYOUT_MODE_UNKNOWN)
+ {
+ typeWorkList.add(matrixType);
+ }
+ }
+ }
+ visitParent(typeWorkList, child);
+ }
+ }
+
+ void specializeMatrixLayout(TargetRequest* target, IRModule* module)
+ {
+ List<IRMatrixType*> typeWorkList;
+ visitParent(typeWorkList, module->getModuleInst());
+
+ IRIntegerValue defaultLayout = target->getDefaultMatrixLayoutMode();
+ if (defaultLayout == SLANG_MATRIX_LAYOUT_MODE_UNKNOWN)
+ defaultLayout = SLANG_MATRIX_LAYOUT_ROW_MAJOR;
+
+ IRBuilder builder(module);
+ for (auto matrixType : typeWorkList)
+ {
+ builder.setInsertBefore(matrixType);
+ auto replacementMatrixType = builder.getMatrixType(matrixType->getElementType(), matrixType->getRowCount(), matrixType->getColumnCount(),
+ builder.getIntValue(builder.getIntType(), defaultLayout));
+ matrixType->replaceUsesWith(replacementMatrixType);
+ }
+ }
+
+}
diff --git a/source/slang/slang-ir-specialize-matrix-layout.h b/source/slang/slang-ir-specialize-matrix-layout.h
new file mode 100644
index 000000000..3074f72cf
--- /dev/null
+++ b/source/slang/slang-ir-specialize-matrix-layout.h
@@ -0,0 +1,16 @@
+#ifndef SLANG_IR_SPECIALIZE_MATRIX_LAYOUT_H
+#define SLANG_IR_SPECIALIZE_MATRIX_LAYOUT_H
+
+namespace Slang
+{
+ struct IRModule;
+ class TargetRequest;
+
+ // Repalce all matrix types whose layout is not specified with the default layout
+ // of the target request.
+ //
+ void specializeMatrixLayout(TargetRequest* target, IRModule* module);
+
+}
+
+#endif
diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp
index daea4582a..cc9bf4164 100644
--- a/source/slang/slang-ir-spirv-legalize.cpp
+++ b/source/slang/slang-ir-spirv-legalize.cpp
@@ -182,30 +182,41 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
}
}
- void processGetElementPtr(IRGetElementPtr* inst)
+ void processGetElementPtrImpl(IRInst* gepInst, IRInst* base, IRInst* index)
{
- if (auto ptrType = as<IRPtrTypeBase>(inst->getBase()->getDataType()))
+ if (auto ptrType = as<IRPtrTypeBase>(base->getDataType()))
{
if (!ptrType->hasAddressSpace())
return;
- auto oldResultType = as<IRPtrTypeBase>(inst->getDataType());
+ auto oldResultType = as<IRPtrTypeBase>(gepInst->getDataType());
if (oldResultType->getAddressSpace() != ptrType->getAddressSpace())
{
IRBuilder builder(m_sharedContext->m_irModule);
- builder.setInsertBefore(inst);
+ builder.setInsertBefore(gepInst);
auto newPtrType = builder.getPtrType(
oldResultType->getOp(),
oldResultType->getValueType(),
ptrType->getAddressSpace());
+ IRInst* args[2] = { base, index };
auto newInst =
- builder.emitElementAddress(newPtrType, inst->getBase(), inst->getIndex());
- inst->replaceUsesWith(newInst);
- inst->removeAndDeallocate();
+ builder.emitIntrinsicInst(newPtrType, gepInst->getOp(), 2, args);
+ gepInst->replaceUsesWith(newInst);
+ gepInst->removeAndDeallocate();
addUsersToWorkList(newInst);
}
}
}
+ void processGetElementPtr(IRGetElementPtr* gepInst)
+ {
+ processGetElementPtrImpl(gepInst, gepInst->getBase(), gepInst->getIndex());
+ }
+
+ void processRWStructuredBufferGetElementPtr(IRRWStructuredBufferGetElementPtr* gepInst)
+ {
+ processGetElementPtrImpl(gepInst, gepInst->getBase(), gepInst->getIndex());
+ }
+
void processFieldAddress(IRFieldAddress* inst)
{
if (auto ptrType = as<IRPtrTypeBase>(inst->getBase()->getDataType()))
@@ -286,6 +297,9 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
case kIROp_FieldAddress:
processFieldAddress(as<IRFieldAddress>(inst));
break;
+ case kIROp_RWStructuredBufferGetElementPtr:
+ processRWStructuredBufferGetElementPtr(as<IRRWStructuredBufferGetElementPtr>(inst));
+ break;
case kIROp_HLSLStructuredBufferType:
case kIROp_HLSLRWStructuredBufferType:
processStructuredBufferType(as<IRHLSLStructuredBufferTypeBase>(inst));
diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp
index 41ac19ee9..f96cc174c 100644
--- a/source/slang/slang-ir-util.cpp
+++ b/source/slang/slang-ir-util.cpp
@@ -407,6 +407,8 @@ bool isPtrLikeOrHandleType(IRInst* type)
return true;
if (as<IRPseudoPtrType>(type))
return true;
+ if (as<IRHLSLStructuredBufferTypeBase>(type))
+ return true;
switch (type->getOp())
{
case kIROp_ComPtrType:
@@ -871,10 +873,15 @@ bool isGlobalOrUnknownMutableAddress(IRGlobalValueWithCode* parentFunc, IRInst*
if (root)
{
+ // If this is a global readonly resource, it is not a mutable address.
if (as<IRParameterGroupType>(root->getDataType()))
{
return false;
}
+ if (as<IRHLSLStructuredBufferType>(root->getDataType()))
+ {
+ return false;
+ }
}
switch (root->getOp())
@@ -991,6 +998,47 @@ void resetScratchDataBit(IRInst* inst, int bitIndex)
}
}
+UnownedStringSlice getBasicTypeNameHint(IRType* basicType)
+{
+ switch (basicType->getOp())
+ {
+ case kIROp_IntType:
+ return UnownedStringSlice::fromLiteral("int");
+ case kIROp_Int8Type:
+ return UnownedStringSlice::fromLiteral("int8");
+ case kIROp_Int16Type:
+ return UnownedStringSlice::fromLiteral("int16");
+ case kIROp_Int64Type:
+ return UnownedStringSlice::fromLiteral("int64");
+ case kIROp_IntPtrType:
+ return UnownedStringSlice::fromLiteral("intptr");
+ case kIROp_UIntType:
+ return UnownedStringSlice::fromLiteral("uint");
+ case kIROp_UInt8Type:
+ return UnownedStringSlice::fromLiteral("uint8");
+ case kIROp_UInt16Type:
+ return UnownedStringSlice::fromLiteral("uint16");
+ case kIROp_UInt64Type:
+ return UnownedStringSlice::fromLiteral("uint64");
+ case kIROp_UIntPtrType:
+ return UnownedStringSlice::fromLiteral("uintptr");
+ case kIROp_FloatType:
+ return UnownedStringSlice::fromLiteral("float");
+ case kIROp_HalfType:
+ return UnownedStringSlice::fromLiteral("half");
+ case kIROp_DoubleType:
+ return UnownedStringSlice::fromLiteral("double");
+ case kIROp_BoolType:
+ return UnownedStringSlice::fromLiteral("bool");
+ case kIROp_VoidType:
+ return UnownedStringSlice::fromLiteral("void");
+ case kIROp_CharType:
+ return UnownedStringSlice::fromLiteral("char");
+ default:
+ return UnownedStringSlice();
+ }
+}
+
struct GenericChildrenMigrationContextImpl
{
IRCloneEnv cloneEnv;
diff --git a/source/slang/slang-ir-util.h b/source/slang/slang-ir-util.h
index fc44b8d30..a0336e1c2 100644
--- a/source/slang/slang-ir-util.h
+++ b/source/slang/slang-ir-util.h
@@ -223,6 +223,7 @@ bool isOne(IRInst* inst);
void initializeScratchData(IRInst* inst);
void resetScratchDataBit(IRInst* inst, int bitIndex);
+
}
#endif
diff --git a/source/slang/slang-ir-wrap-structured-buffers.cpp b/source/slang/slang-ir-wrap-structured-buffers.cpp
index 0e7248320..6b7043416 100644
--- a/source/slang/slang-ir-wrap-structured-buffers.cpp
+++ b/source/slang/slang-ir-wrap-structured-buffers.cpp
@@ -161,50 +161,21 @@ struct WrapStructuredBuffersContext
// are calls that could potentially be intrinsic
// operations on `*StructuredBuffer`.
//
- auto call = as<IRCall>(valueUse->getUser());
- if(!call)
- return;
- if(call->getArgCount() == 0)
- return;
- if(call->getArg(0) != valueOfStructuredBufferType)
- return;
-
- // At this point we have a candidate `call` instruction,
- // but we need to determine whether it is a call to
- // one of the `*StructuredBuffer` intrinsics that we want
- // to rewrite, or if it is another user-defined function
- // that we should leave along (even if that user-defined
- // function happens to return a matrix).
- //
- // For now we will do this in a somewhat ad-hoc fashion.
- // We know that the `Load` and `operator[]` operations
- // on `*StructuredBuffer` are generic, and unlike user-defined
- // generic functions they will not have been specialized
- // before we get here.
- //
- // We will thus use the fact that the callee of the call
- // is a `specialize` instruction to let us know that it
- // is an intrinsic, and thus should be one of the functions
- // we care about.
- //
- // TODO: Figure out if there is a more robust way to make
- // this check. It is possible that structured buffer
- // access should be modeled with explicit IR opcodes
- // rather than just as builtin functions.
- //
- auto callee = call->getCallee();
- if(!as<IRSpecialize>(callee))
+ auto user = valueUse->getUser();
+ switch (user->getOp())
+ {
+ case kIROp_StructuredBufferLoad:
+ case kIROp_StructuredBufferLoadStatus:
+ case kIROp_RWStructuredBufferStore:
+ case kIROp_RWStructuredBufferLoadStatus:
+ case kIROp_RWStructuredBufferGetElementPtr:
+ break;
+ default:
return;
+ }
- // At this point it seems likely we have one of the calls
- // we want to rewrite, but there are still intrinsics
- // like `GetDimensions` that we want to leave alone.
- //
- // For now we will look at the return type of the call,
- // where we care about two cases.
- //
- builder->setInsertBefore(call->getNextInst());
- auto oldResultType = call->getDataType();
+ builder->setInsertAfter(user);
+ auto oldResultType = user->getDataType();
// First we care about the case for `Load`, which
// will return the element type, which would be
@@ -217,7 +188,7 @@ struct WrapStructuredBuffersContext
// go ahead and modify its type to be correct.
//
auto newResultType = wrapperStruct;
- builder->setDataType(call, newResultType);
+ builder->setDataType(user, newResultType);
// Next, we need to make sure to extract the
// field from the wrapper struct, so that
@@ -232,12 +203,12 @@ struct WrapStructuredBuffersContext
//
// float4x4 newVal = call.wrapped;
//
- auto newVal = builder->emitFieldExtract(oldResultType, call, wrappedFieldKey);
+ auto newVal = builder->emitFieldExtract(oldResultType, user, wrappedFieldKey);
// Any code that used the value of `call` should
// now use `newVal` instead...
//
- call->replaceUsesWith(newVal);
+ user->replaceUsesWith(newVal);
//
// ... except for one important gotcha, which is
// that `newVal` itself used `call`, and replacing
@@ -251,7 +222,7 @@ struct WrapStructuredBuffersContext
// of `replaceUsesWith` that can handle cases like
// this.
//
- newVal->setOperand(0, call);
+ newVal->setOperand(0, user);
}
//
// The second interesting case is the `ref` accessor
@@ -276,11 +247,11 @@ struct WrapStructuredBuffersContext
// there if you want the comments.
auto newResultType = builder->getPtrType(oldPtrType->getOp(), wrapperStruct);
- builder->setDataType(call, newResultType);
+ builder->setDataType(user, newResultType);
- auto newVal = builder->emitFieldAddress(oldResultType, call, wrappedFieldKey);
- call->replaceUsesWith(newVal);
- newVal->setOperand(0, call);
+ auto newVal = builder->emitFieldAddress(oldResultType, user, wrappedFieldKey);
+ user->replaceUsesWith(newVal);
+ newVal->setOperand(0, user);
}
}
});
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp
index 0a79cec57..49c91dc22 100644
--- a/source/slang/slang-ir.cpp
+++ b/source/slang/slang-ir.cpp
@@ -2808,9 +2808,10 @@ namespace Slang
IRMatrixType* IRBuilder::getMatrixType(
IRType* elementType,
IRInst* rowCount,
- IRInst* columnCount)
+ IRInst* columnCount,
+ IRInst* layout)
{
- IRInst* operands[] = { elementType, rowCount, columnCount };
+ IRInst* operands[] = { elementType, rowCount, columnCount, layout };
return (IRMatrixType*)getType(
kIROp_MatrixType,
sizeof(operands) / sizeof(operands[0]),
@@ -7304,6 +7305,9 @@ namespace Slang
case kIROp_MakeDifferentialPair:
case kIROp_MakeTuple:
case kIROp_GetTupleElement:
+ case kIROp_StructuredBufferLoad:
+ case kIROp_RWStructuredBufferLoad:
+ case kIROp_RWStructuredBufferGetElementPtr:
case kIROp_Load: // We are ignoring the possibility of loads from bad addresses, or `volatile` loads
case kIROp_LoadReverseGradient:
case kIROp_ReverseGradientDiffPairRef:
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index cdce11bbb..c5778004b 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -1553,6 +1553,7 @@ struct IRMatrixType : IRType
IRType* getElementType() { return (IRType*)getOperand(0); }
IRInst* getRowCount() { return getOperand(1); }
IRInst* getColumnCount() { return getOperand(2); }
+ IRInst* getLayout() { return getOperand(3); }
IR_LEAF_ISA(MatrixType)
};
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index b1a38febd..d67d57001 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -1817,11 +1817,12 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower
auto elementType = lowerType(context, type->getElementType());
auto rowCount = lowerSimpleVal(context, type->getRowCount());
auto columnCount = lowerSimpleVal(context, type->getColumnCount());
-
+ auto layout = lowerSimpleVal(context, type->getLayout());
return getBuilder()->getMatrixType(
elementType,
rowCount,
- columnCount);
+ columnCount,
+ layout);
}
IRType* visitArrayExpressionType(ArrayExpressionType* type)
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index dbd6b97a4..85602b744 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -372,11 +372,11 @@ void initCommandOptions(CommandOptions& options)
const Option generalOpts[] =
{
- { OptionKind::MacroDefine, "-D?...", "-D<name>[=<value>], -D <name>[=<value>]",
- "Insert a preprocessor macro.\n"
+ { OptionKind::MacroDefine, "-D?...", "-D<name>[=<value>], -D <name>[=<value>]",
+ "Insert a preprocessor macro.\n"
"The space between - D and <name> is optional. If no <value> is specified, Slang will define the macro with an empty value." },
{ OptionKind::DepFile, "-depfile", "-depfile <path>", "Save the source file dependency list in a file." },
- { OptionKind::EntryPointName, "-entry", "-entry <name>",
+ { OptionKind::EntryPointName, "-entry", "-entry <name>",
"Specify the name of an entry-point function.\n"
"When compiling from a single file, this defaults to main if you specify a stage using -stage.\n"
"Multiple -entry options may be used in a single invocation. "
@@ -386,7 +386,7 @@ void initCommandOptions(CommandOptions& options)
{ OptionKind::EmitIr, "-emit-ir", nullptr, "Emit IR typically as a '.slang-module' when outputting to a container." },
{ OptionKind::Help, "-h,-help,--help", "-h or -h <help-category>", "Print this message, or help in specified category." },
{ OptionKind::HelpStyle, "-help-style", "-help-style <help-style>", "Help formatting style" },
- { OptionKind::Include, "-I?...", "-I<path>, -I <path>",
+ { OptionKind::Include, "-I?...", "-I<path>, -I <path>",
"Add a path to be used in resolving '#include' "
"and 'import' operations."},
{ OptionKind::Language, "-lang", "-lang <language>", "Set the language for the following input files."},
diff --git a/source/slang/slang-spirv-val.cpp b/source/slang/slang-spirv-val.cpp
index 990ccd909..54bf5348b 100644
--- a/source/slang/slang-spirv-val.cpp
+++ b/source/slang/slang-spirv-val.cpp
@@ -3,6 +3,29 @@
namespace Slang
{
+SlangResult debugDisassembleSPIRV(const List<uint8_t>& spirv, String& outDis)
+{
+ CommandLine commandLine;
+ commandLine.m_executableLocation.setName("spirv-dis");
+ RefPtr<Process> p;
+ const auto createResult = Process::create(commandLine, 0, p);
+ // If we failed to even start the process, then validation isn't available
+ SLANG_RETURN_ON_FAIL(createResult);
+ const auto in = p->getStream(StdStreamType::In);
+ const auto out = p->getStream(StdStreamType::Out);
+ // Write the assembly
+ SLANG_RETURN_ON_FAIL(in->write(spirv.getBuffer(), spirv.getCount()));
+ in->close();
+ // Wait for it to finish
+ if (!p->waitForTermination(1000))
+ return SLANG_FAIL;
+
+ List<Byte> outData;
+ SLANG_RETURN_ON_FAIL(StreamUtil::readAll(out, 0, outData));
+ outDis = String((const char*)outData.getBuffer());
+ return SLANG_OK;
+}
+
SlangResult debugValidateSPIRV(const List<uint8_t>& spirv)
{
// Set up our process
@@ -25,6 +48,7 @@ SlangResult debugValidateSPIRV(const List<uint8_t>& spirv)
if(!p->waitForTermination(1000))
return SLANG_FAIL;
+
// TODO: allow inheriting stderr in Process
List<Byte> outData;
SLANG_RETURN_ON_FAIL(StreamUtil::readAll(out, 0, outData));
@@ -32,8 +56,14 @@ SlangResult debugValidateSPIRV(const List<uint8_t>& spirv)
outData.clear();
SLANG_RETURN_ON_FAIL(StreamUtil::readAll(err, 0, outData));
fwrite(outData.getBuffer(), outData.getCount(), 1, stderr);
-
const auto ret = p->getReturnValue();
+ if (SLANG_FAILED(ret))
+ {
+ String spirvDis;
+ debugDisassembleSPIRV(spirv, spirvDis);
+ fwrite(spirvDis.getBuffer(), spirvDis.getLength(), 1, stderr);
+ }
+
return ret == 0 ? SLANG_OK : SLANG_FAIL;
}
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index d075b12e2..bf3df4adc 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -2866,23 +2866,6 @@ static TypeLayoutResult _createTypeLayout(
if (declForModifiers)
{
- // TODO: The approach implemented here has a row/column-major
- // layout model recursively affect any sub-fields (so that
- // the layout of a nested struct depends on the context where
- // it is nested). This is consistent with the GLSL behavior
- // for these modifiers, but it is *not* how HLSL is supposed
- // to work.
- //
- // In the trivial case where `row_major` and `column_major`
- // are only applied to leaf fields/variables of matrix type
- // the difference should be immaterial.
-
- if (declForModifiers->hasModifier<RowMajorLayoutModifier>())
- subContext.matrixLayoutMode = kMatrixLayoutMode_RowMajor;
-
- if (declForModifiers->hasModifier<ColumnMajorLayoutModifier>())
- subContext.matrixLayoutMode = kMatrixLayoutMode_ColumnMajor;
-
// TODO: really need to look for other modifiers that affect
// layout, such as GLSL `std140`.
}
@@ -3866,7 +3849,12 @@ static TypeLayoutResult _createTypeLayout(
//
size_t layoutMajorCount = rowCount;
size_t layoutMinorCount = colCount;
- if (context.matrixLayoutMode == kMatrixLayoutMode_ColumnMajor)
+ auto matrixLayout = getIntVal(matType->getLayout());
+ if (matrixLayout == SLANG_MATRIX_LAYOUT_MODE_UNKNOWN)
+ {
+ matrixLayout = context.matrixLayoutMode;
+ }
+ if (matrixLayout == SLANG_MATRIX_LAYOUT_COLUMN_MAJOR)
{
size_t tmp = layoutMajorCount;
layoutMajorCount = layoutMinorCount;
@@ -3891,7 +3879,7 @@ static TypeLayoutResult _createTypeLayout(
size_t rowStride = 0;
size_t colStride = 0;
- if(context.matrixLayoutMode == kMatrixLayoutMode_ColumnMajor)
+ if (matrixLayout == SLANG_MATRIX_LAYOUT_COLUMN_MAJOR)
{
colStride = majorStride;
rowStride = minorStride;
@@ -3918,7 +3906,7 @@ static TypeLayoutResult _createTypeLayout(
typeLayout->elementTypeLayout = rowTypeLayout;
typeLayout->uniformStride = rowStride;
- typeLayout->mode = context.matrixLayoutMode;
+ typeLayout->mode = (MatrixLayoutMode)matrixLayout;
typeLayout->addResourceUsage(info.kind, info.size);
diff --git a/source/slang/slang.natvis b/source/slang/slang.natvis
index 912a8f2a7..619b76b85 100644
--- a/source/slang/slang.natvis
+++ b/source/slang/slang.natvis
@@ -792,4 +792,16 @@
<Type Name="Slang::TypeEqualityWitness">
<DisplayString>{sub,na} == {sup,na}</DisplayString>
</Type>
+
+ <Type Name="Slang::ConstantIntVal">
+ <DisplayString>ConstantIntVal ({m_operands.m_buffer[1].values.intOperand} : {*(Type*)m_operands.m_buffer[0].values.nodeOperand})</DisplayString>
+ </Type>
+
+ <Type Name="Slang::GenericParamIntVal">
+ <DisplayString>GenericParamIntVal ({*(DeclRefBase*)m_operands.m_buffer[1].values.nodeOperand})</DisplayString>
+ </Type>
+
+ <Type Name="Slang::BasicExpressionType">
+ <DisplayString>BasicExpressionType ({*(DeclRefBase*)m_operands.m_buffer[0].values.nodeOperand})</DisplayString>
+ </Type>
</AutoVisualizer>
diff --git a/tests/compute/comma-operator.slang.glsl b/tests/compute/comma-operator.slang.glsl
index 3107f5773..af7120704 100644
--- a/tests/compute/comma-operator.slang.glsl
+++ b/tests/compute/comma-operator.slang.glsl
@@ -3,8 +3,7 @@
//TEST_IGNORE_FILE:
-layout(std430, binding = 0)
-buffer _S1 {
+layout(std430, binding = 0) buffer _S1 {
int _data[];
} outputBuffer_0;
@@ -13,12 +12,10 @@ int test_0(int inVal_0)
return inVal_0 * 2 + 1;
}
-layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;void main()
+layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
+void main()
{
uint tid_0 = gl_GlobalInvocationID.x;
-
- int outVal_0 = test_0(outputBuffer_0._data[tid_0]);
-
- outputBuffer_0._data[tid_0] = outVal_0;
+ outputBuffer_0._data[tid_0] = test_0(outputBuffer_0._data[tid_0]);
return;
}
diff --git a/tests/compute/unbounded-array-of-array-syntax.slang.glsl b/tests/compute/unbounded-array-of-array-syntax.slang.glsl
index f30012cc3..73148ae10 100644
--- a/tests/compute/unbounded-array-of-array-syntax.slang.glsl
+++ b/tests/compute/unbounded-array-of-array-syntax.slang.glsl
@@ -32,7 +32,6 @@ void main()
{
innerIndex_1 = innerIndex_0;
}
- uint _S4 = uint(innerIndex_1);
- ((outputBuffer_0)._data[(uint(index_0))]) = ((g_aoa_0[_S3])._data[(_S4)]);
+ outputBuffer_0._data[uint(index_0)] = g_aoa_0[_S3]._data[uint(innerIndex_1)];
return;
}
diff --git a/tests/cross-compile/array-of-buffers.slang.glsl b/tests/cross-compile/array-of-buffers.slang.glsl
index 62990033e..a198a5277 100644
--- a/tests/cross-compile/array-of-buffers.slang.glsl
+++ b/tests/cross-compile/array-of-buffers.slang.glsl
@@ -11,6 +11,7 @@ layout(std140) uniform _S1
{
uint index_0;
} C_0;
+
struct S_0
{
vec4 f_0;
@@ -36,9 +37,7 @@ out vec4 _S6;
void main()
{
- S_0 _S7 = ((sb1_0[C_0.index_0])._data[(C_0.index_0)]);
- vec4 _S8 = cb_0[C_0.index_0].f_0 + _S7.f_0;
- uint _S9 = ((bb_0[C_0.index_0])._data[(int(C_0.index_0 * 4U))/4]);
- _S6 = _S8 + ((sb2_0[C_0.index_0])._data[(C_0.index_0)]) + vec4(float(_S9));
+ uint _S7 = ((bb_0[C_0.index_0])._data[(int(C_0.index_0 * 4U))/4]);
+ _S6 = cb_0[C_0.index_0].f_0 + sb1_0[C_0.index_0]._data[C_0.index_0].f_0 + sb2_0[C_0.index_0]._data[C_0.index_0] + vec4(float(_S7));
return;
}
diff --git a/tests/cross-compile/array-of-buffers.slang.hlsl b/tests/cross-compile/array-of-buffers.slang.hlsl
index e709d323a..ca4b76bbe 100644
--- a/tests/cross-compile/array-of-buffers.slang.hlsl
+++ b/tests/cross-compile/array-of-buffers.slang.hlsl
@@ -13,6 +13,7 @@ cbuffer C_0 : register(b0)
{
SLANG_ParameterGroup_C_0 C_0;
}
+
struct S_0
{
float4 f_0;
@@ -25,10 +26,9 @@ StructuredBuffer<S_0 > sb1_0[int(4)] : register(t0);
RWStructuredBuffer<float4 > sb2_0[int(5)] : register(u0);
ByteAddressBuffer bb_0[int(6)] : register(t4);
+
float4 main() : SV_TARGET
{
- S_0 _S1 = sb1_0[C_0.index_0][C_0.index_0];
- float4 _S2 = cb_0[C_0.index_0].f_0 + _S1.f_0;
- uint _S3 = bb_0[C_0.index_0].Load(int(C_0.index_0 * 4U));
- return _S2 + sb2_0[C_0.index_0][C_0.index_0] + (float4)float(_S3);
+ uint _S1 = bb_0[C_0.index_0].Load(int(C_0.index_0 * 4U));
+ return cb_0[C_0.index_0].f_0 + sb1_0[C_0.index_0].Load(C_0.index_0).f_0 + sb2_0[C_0.index_0][C_0.index_0] + (float4)float(_S1);
}
diff --git a/tests/cross-compile/func-resource-param-array.slang.glsl b/tests/cross-compile/func-resource-param-array.slang.glsl
index d5d1bd08c..9e396e55f 100644
--- a/tests/cross-compile/func-resource-param-array.slang.glsl
+++ b/tests/cross-compile/func-resource-param-array.slang.glsl
@@ -16,22 +16,22 @@ layout(std430, binding = 2) buffer _S3 {
int f_0(uint _S4)
{
- return ((a_0)._data[(_S4)]);
+ return a_0._data[_S4];
}
int f_1(uint _S5, uint _S6)
{
- return ((b_0[_S5])._data[(_S6)]);
+ return b_0[_S5]._data[_S6];
}
int g_0(uint _S7, uint _S8)
{
- return ((b_0[_S7])._data[(_S8)]);
+ return b_0[_S7]._data[_S8];
}
int g_1(uint _S9, uint _S10, uint _S11)
{
- return ((c_0[_S9][_S10])._data[(_S11)]);
+ return c_0[_S9][_S10]._data[_S11];
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -39,10 +39,7 @@ void main()
{
uint ii_0 = gl_GlobalInvocationID.x;
uint jj_0 = gl_GlobalInvocationID.y;
-
- int tmp_0 = f_0(ii_0) + f_0(jj_0) + f_1(ii_0, jj_0) + g_0(ii_0, jj_0) + g_1(ii_0, jj_0, gl_GlobalInvocationID.z);
-
- ((a_0)._data[(ii_0)]) = tmp_0;
+ a_0._data[ii_0] = f_0(ii_0) + f_0(jj_0) + f_1(ii_0, jj_0) + g_0(ii_0, jj_0) + g_1(ii_0, jj_0, gl_GlobalInvocationID.z);
return;
}
diff --git a/tests/diagnostics/bad-operator-call.slang b/tests/diagnostics/bad-operator-call.slang
index 1455d1cc3..2764d27ae 100644
--- a/tests/diagnostics/bad-operator-call.slang
+++ b/tests/diagnostics/bad-operator-call.slang
@@ -1,6 +1,6 @@
// bad-operator-call.slang
-//DIAGNOSTIC_TEST(windows):SIMPLE:
+//DIAGNOSTIC_TEST(windows):SIMPLE(filecheck=CHECK):
// Test that bad calls to operators produce reasonable diagnostic messages.
@@ -13,22 +13,22 @@ struct S {}
void test()
{
int a;
- S b;
-
- a += b;
-
- a = a + b;
-
+ S b;
+ // CHECK:{{.*}}.slang(18): error {{.*}}: no overload for '+=' applicable to arguments of type (int, S)
+ a += b;
+ // CHECK:{{.*}}.slang(20): error {{.*}}: no overload for '+' applicable to arguments of type (int, S)
+ a = a + b;
+ // CHECK:{{.*}}.slang(22): error {{.*}}: no overload for '~' applicable to arguments of type (S)
a = ~b;
vector<int, 4> c;
- vector<float, 3> d;
-
+ vector<float, 3> d;
+ // CHECK:{{.*}}.slang(27): error {{.*}}: argument passed to parameter '0' must be l-value.
a += c;
- c = a + c;
-
- d += c;
-
+ c = a + c;
+ // CHECK:{{.*}}.slang(31): error {{.*}}: no overload for '+=' applicable to arguments of type (vector<float,3>, vector<int,4>)
+ d += c;
+ // CHECK:{{.*}}.slang(33): error {{.*}}: no overload for '+' applicable to arguments of type (vector<int,4>, vector<float,3>)
d = c + d;
} \ No newline at end of file
diff --git a/tests/diagnostics/bad-operator-call.slang.expected b/tests/diagnostics/bad-operator-call.slang.expected
deleted file mode 100644
index 3abca8f23..000000000
--- a/tests/diagnostics/bad-operator-call.slang.expected
+++ /dev/null
@@ -1,70 +0,0 @@
-result code = -1
-standard error = {
-tests/diagnostics/bad-operator-call.slang(18): error 39999: no overload for '+=' applicable to arguments of type (int, S)
- a += b;
- ^~
-core.meta.slang(2655): note 39999: candidate: func +=<T, R:int, C:int>(out matrix<T,R,C>, T) -> matrix<T,R,C>
-core.meta.slang(2647): note 39999: candidate: func +=<T, R:int, C:int>(out matrix<T,R,C>, matrix<T,R,C>) -> matrix<T,R,C>
-core.meta.slang(2639): note 39999: candidate: func +=<T, N:int>(out vector<T,N>, T) -> vector<T,N>
-core.meta.slang(2631): note 39999: candidate: func +=<T, N:int>(out vector<T,N>, vector<T,N>) -> vector<T,N>
-core.meta.slang(2623): note 39999: candidate: func +=<T>(out T, T) -> T
-tests/diagnostics/bad-operator-call.slang(20): error 39999: no overload for '+' applicable to arguments of type (int, S)
- a = a + b;
- ^
-core.meta.slang(2481): note 39999: candidate: func +(uintptr_t, uintptr_t) -> uintptr_t
-core.meta.slang(2473): note 39999: candidate: func +(uint64_t, uint64_t) -> uint64_t
-core.meta.slang(2465): note 39999: candidate: func +(uint, uint) -> uint
-core.meta.slang(2457): note 39999: candidate: func +(uint16_t, uint16_t) -> uint16_t
-core.meta.slang(2449): note 39999: candidate: func +(uint8_t, uint8_t) -> uint8_t
-core.meta.slang(2441): note 39999: candidate: func +(double, double) -> double
-core.meta.slang(2433): note 39999: candidate: func +(float, float) -> float
-core.meta.slang(2425): note 39999: candidate: func +(half, half) -> half
-core.meta.slang(2417): note 39999: candidate: func +(intptr_t, intptr_t) -> intptr_t
-core.meta.slang(2409): note 39999: candidate: func +(int64_t, int64_t) -> int64_t
-tests/diagnostics/bad-operator-call.slang(20): note 39999: 3 more overload candidates
- a = a + b;
- ^
-tests/diagnostics/bad-operator-call.slang(22): error 39999: no overload for '~' applicable to arguments of type (S)
- a = ~b;
- ^
-core.meta.slang(2350): note 39999: candidate: __prefix func ~(uintptr_t) -> uintptr_t
-core.meta.slang(2346): note 39999: candidate: __prefix func ~(uint64_t) -> uint64_t
-core.meta.slang(2342): note 39999: candidate: __prefix func ~(uint) -> uint
-core.meta.slang(2338): note 39999: candidate: __prefix func ~(uint16_t) -> uint16_t
-core.meta.slang(2334): note 39999: candidate: __prefix func ~(uint8_t) -> uint8_t
-core.meta.slang(2330): note 39999: candidate: __prefix func ~(intptr_t) -> intptr_t
-core.meta.slang(2326): note 39999: candidate: __prefix func ~(int64_t) -> int64_t
-core.meta.slang(2322): note 39999: candidate: __prefix func ~(int) -> int
-core.meta.slang(2318): note 39999: candidate: __prefix func ~(int16_t) -> int16_t
-core.meta.slang(2314): note 39999: candidate: __prefix func ~(int8_t) -> int8_t
-tests/diagnostics/bad-operator-call.slang(27): error 30047: argument passed to parameter '0' must be l-value.
- a += c;
- ^
-tests/diagnostics/bad-operator-call.slang(27): note 30063: argument was implicitly cast from 'int' to 'vector<int,4>', and Slang does not support using an implicit cast as an l-value with this type
-tests/diagnostics/bad-operator-call.slang(31): error 39999: no overload for '+=' applicable to arguments of type (vector<float,3>, vector<int,4>)
- d += c;
- ^~
-core.meta.slang(2655): note 39999: candidate: func +=<T, R:int, C:int>(out matrix<T,R,C>, T) -> matrix<T,R,C>
-core.meta.slang(2647): note 39999: candidate: func +=<T, R:int, C:int>(out matrix<T,R,C>, matrix<T,R,C>) -> matrix<T,R,C>
-core.meta.slang(2639): note 39999: candidate: func +=<T, N:int>(out vector<T,N>, T) -> vector<T,N>
-core.meta.slang(2631): note 39999: candidate: func +=<T, N:int>(out vector<T,N>, vector<T,N>) -> vector<T,N>
-core.meta.slang(2623): note 39999: candidate: func +=<T>(out T, T) -> T
-tests/diagnostics/bad-operator-call.slang(33): error 39999: no overload for '+' applicable to arguments of type (vector<int,4>, vector<float,3>)
- d = c + d;
- ^
-core.meta.slang(2487): note 39999: candidate: func +<4>(uintptr_t4, uintptr_t) -> uintptr_t4
-core.meta.slang(2485): note 39999: candidate: func +<3>(uintptr_t, uintptr_t3) -> uintptr_t3
-core.meta.slang(2481): note 39999: candidate: func +(uintptr_t, uintptr_t) -> uintptr_t
-core.meta.slang(2479): note 39999: candidate: func +<4>(uint64_t4, uint64_t) -> uint64_t4
-core.meta.slang(2477): note 39999: candidate: func +<3>(uint64_t, uint64_t3) -> uint64_t3
-core.meta.slang(2473): note 39999: candidate: func +(uint64_t, uint64_t) -> uint64_t
-core.meta.slang(2471): note 39999: candidate: func +<4>(uint4, uint) -> uint4
-core.meta.slang(2469): note 39999: candidate: func +<3>(uint, uint3) -> uint3
-core.meta.slang(2465): note 39999: candidate: func +(uint, uint) -> uint
-core.meta.slang(2463): note 39999: candidate: func +<4>(uint16_t4, uint16_t) -> uint16_t4
-tests/diagnostics/bad-operator-call.slang(33): note 39999: 29 more overload candidates
- d = c + d;
- ^
-}
-standard output = {
-}
diff --git a/tests/experimental/liveness/liveness-2.slang b/tests/experimental/liveness/liveness-2.slang
deleted file mode 100644
index 06382971f..000000000
--- a/tests/experimental/liveness/liveness-2.slang
+++ /dev/null
@@ -1,27 +0,0 @@
-//TEST:SIMPLE:-target glsl -entry computeMain -profile cs_6_3 -track-liveness -line-directive-mode none
-
-//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
-RWStructuredBuffer<int> outputBuffer;
-
-// Test loop handling.
-
-int calcThing(int offset)
-{
- int idx[3];
-
- for (int i = 0; i < 3; ++i)
- {
- idx[i] = offset + i;
- }
-
- // Now read back
- return idx[0] + idx[1] + idx[2];
-}
-
-[numthreads(4, 1, 1)]
-void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
-{
- int index = int(dispatchThreadID.x);
-
- outputBuffer[index] = calcThing(index);
-}
diff --git a/tests/experimental/liveness/liveness-2.slang.expected b/tests/experimental/liveness/liveness-2.slang.expected
deleted file mode 100644
index 3ae6d3875..000000000
--- a/tests/experimental/liveness/liveness-2.slang.expected
+++ /dev/null
@@ -1,59 +0,0 @@
-result code = 0
-standard error = {
-}
-standard output = {
-#version 450
-#extension GL_EXT_spirv_intrinsics : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-layout(std430, binding = 0) buffer _S1 {
- int _data[];
-} outputBuffer_0;
-spirv_instruction(id = 256)
-void livenessStart_0(spirv_by_reference int _0[3], spirv_literal int _1);
-
-spirv_instruction(id = 256)
-void livenessStart_1(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_0(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_1(spirv_by_reference int _0[3], spirv_literal int _1);
-
-int calcThing_0(int offset_0)
-{
- int idx_0[3];
- livenessStart_0(idx_0, 0);
- int i_0;
- livenessStart_1(i_0, 0);
- i_0 = 0;
- for(;;)
- {
- if(i_0 < 3)
- {
- }
- else
- {
- livenessEnd_0(i_0, 0);
- break;
- }
- idx_0[i_0] = offset_0 + i_0;
- i_0 = i_0 + 1;
- }
- int _S2 = idx_0[0] + idx_0[1];
- int _S3 = idx_0[2];
- livenessEnd_1(idx_0, 0);
- return _S2 + _S3;
-}
-
-layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
-void main()
-{
- int index_0 = int(gl_GlobalInvocationID.x);
- int _S4 = calcThing_0(index_0);
- ((outputBuffer_0)._data[(uint(index_0))]) = _S4;
- return;
-}
-
-}
diff --git a/tests/experimental/liveness/liveness-3.slang b/tests/experimental/liveness/liveness-3.slang
deleted file mode 100644
index a0c5c8604..000000000
--- a/tests/experimental/liveness/liveness-3.slang
+++ /dev/null
@@ -1,49 +0,0 @@
-//TEST:SIMPLE:-target glsl -entry computeMain -profile cs_6_3 -track-liveness -line-directive-mode none
-
-//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
-RWStructuredBuffer<int> outputBuffer;
-
-// Test loop handling, with more complex structure
-
-int calcThing(int offset)
-{
- int total = 0;
- int another[2] = { 1, 2};
-
- for (int k = 0; k < 20; ++k)
- {
- int idx[3] = {};
-
- for (int i = 0; i < 17; ++i)
- {
- int modRange = i % 3;
-
- another[i & 1] += modRange;
-
- if (i % 3 != 0)
- {
- offset += 1;
- }
-
- idx[modRange] += offset + i;
- }
-
- if ((k + 7) % 5 == 4)
- {
- return total;
- }
-
- // Now read back
- total += idx[0] + idx[1] + idx[2];
- }
-
- return -total;
-}
-
-[numthreads(4, 1, 1)]
-void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
-{
- int index = int(dispatchThreadID.x);
-
- outputBuffer[index] = calcThing(index);
-}
diff --git a/tests/experimental/liveness/liveness-3.slang.expected b/tests/experimental/liveness/liveness-3.slang.expected
deleted file mode 100644
index c2191e9b9..000000000
--- a/tests/experimental/liveness/liveness-3.slang.expected
+++ /dev/null
@@ -1,134 +0,0 @@
-result code = 0
-standard error = {
-}
-standard output = {
-#version 450
-#extension GL_EXT_spirv_intrinsics : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-layout(std430, binding = 0) buffer _S1 {
- int _data[];
-} outputBuffer_0;
-spirv_instruction(id = 256)
-void livenessStart_0(spirv_by_reference int _0[2], spirv_literal int _1);
-
-spirv_instruction(id = 256)
-void livenessStart_1(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_0(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 256)
-void livenessStart_2(spirv_by_reference int _0[3], spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_1(spirv_by_reference int _0[3], spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_2(spirv_by_reference int _0[2], spirv_literal int _1);
-
-int calcThing_0(int offset_0)
-{
- int another_0[2];
- livenessStart_0(another_0, 0);
- another_0[0] = 1;
- another_0[1] = 2;
- int k_0;
- livenessStart_1(k_0, 0);
- k_0 = 0;
- int _S2;
- livenessStart_1(_S2, 0);
- _S2 = offset_0;
- int total_0;
- livenessStart_1(total_0, 0);
- total_0 = 0;
- for(;;)
- {
- if(k_0 < 20)
- {
- }
- else
- {
- livenessEnd_0(_S2, 0);
- livenessEnd_0(k_0, 0);
- break;
- }
- int idx_0[3];
- livenessStart_2(idx_0, 0);
- idx_0[0] = 0;
- idx_0[1] = 0;
- idx_0[2] = 0;
- bool _S3 = (k_0 + 7) % 5 == 4;
- int k_1 = k_0 + 1;
- int i_0;
- livenessStart_1(i_0, 0);
- i_0 = 0;
- int _S4;
- livenessStart_1(_S4, 0);
- _S4 = _S2;
- for(;;)
- {
- if(i_0 < 17)
- {
- }
- else
- {
- livenessEnd_0(i_0, 0);
- break;
- }
- int modRange_0 = i_0 % 3;
- another_0[i_0 & 1] = another_0[i_0 & 1] + modRange_0;
- if(modRange_0 != 0)
- {
- _S4 = _S4 + 1;
- }
- else
- {
- }
- int _S5 = _S4;
- livenessEnd_0(_S4, 0);
- idx_0[modRange_0] = idx_0[modRange_0] + (_S5 + i_0);
- i_0 = i_0 + 1;
- livenessStart_1(_S4, 0);
- }
- livenessEnd_0(_S2, 0);
- livenessEnd_0(k_0, 0);
- if(_S3)
- {
- livenessEnd_0(_S4, 0);
- livenessEnd_1(idx_0, 0);
- livenessEnd_2(another_0, 0);
- return total_0;
- }
- int _S6 = idx_0[0] + idx_0[1];
- int _S7 = idx_0[2];
- livenessEnd_1(idx_0, 0);
- int _S8 = _S6 + _S7;
- int _S9 = total_0;
- livenessEnd_0(total_0, 0);
- int total_1 = _S9 + _S8;
- livenessStart_1(k_0, 0);
- k_0 = k_1;
- livenessStart_1(_S2, 0);
- int _S10 = _S4;
- livenessEnd_0(_S4, 0);
- _S2 = _S10;
- livenessStart_1(total_0, 0);
- total_0 = total_1;
- }
- livenessEnd_2(another_0, 0);
- int _S11 = total_0;
- livenessEnd_0(total_0, 0);
- return - _S11;
-}
-
-layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
-void main()
-{
- int index_0 = int(gl_GlobalInvocationID.x);
- int _S12 = calcThing_0(index_0);
- ((outputBuffer_0)._data[(uint(index_0))]) = _S12;
- return;
-}
-
-}
diff --git a/tests/experimental/liveness/liveness-4.slang b/tests/experimental/liveness/liveness-4.slang
deleted file mode 100644
index a835f3a4e..000000000
--- a/tests/experimental/liveness/liveness-4.slang
+++ /dev/null
@@ -1,35 +0,0 @@
-//TEST:SIMPLE:-target glsl -entry computeMain -profile cs_6_3 -track-liveness -line-directive-mode none
-
-//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
-RWStructuredBuffer<int> outputBuffer;
-
-// Test loop handling, with more complex structure
-// Here to test anothers liveness.
-
-int calcThing(int offset)
-{
- int another[2] = { 1, 2};
-
- for (int k = 0; k < 20; ++k)
- {
- for (int i = 0; i < 17; ++i)
- {
- another[i & 1] += k + i;
- }
-
- if ((k + 7) % 5 == 4)
- {
- return 1;
- }
- }
-
- return -2;
-}
-
-[numthreads(4, 1, 1)]
-void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
-{
- int index = int(dispatchThreadID.x);
-
- outputBuffer[index] = calcThing(index);
-}
diff --git a/tests/experimental/liveness/liveness-4.slang.expected b/tests/experimental/liveness/liveness-4.slang.expected
deleted file mode 100644
index ee7986319..000000000
--- a/tests/experimental/liveness/liveness-4.slang.expected
+++ /dev/null
@@ -1,56 +0,0 @@
-result code = 0
-standard error = {
-}
-standard output = {
-#version 450
-#extension GL_EXT_spirv_intrinsics : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-layout(std430, binding = 0) buffer _S1 {
- int _data[];
-} outputBuffer_0;
-spirv_instruction(id = 256)
-void livenessStart_0(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_0(spirv_by_reference int _0, spirv_literal int _1);
-
-int calcThing_0(int offset_0)
-{
- int k_0;
- livenessStart_0(k_0, 0);
- k_0 = 0;
- for(;;)
- {
- if(k_0 < 20)
- {
- }
- else
- {
- livenessEnd_0(k_0, 0);
- break;
- }
- bool _S2 = (k_0 + 7) % 5 == 4;
- int _S3 = k_0;
- livenessEnd_0(k_0, 0);
- int k_1 = _S3 + 1;
- if(_S2)
- {
- return 1;
- }
- livenessStart_0(k_0, 0);
- k_0 = k_1;
- }
- return -2;
-}
-
-layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
-void main()
-{
- int index_0 = int(gl_GlobalInvocationID.x);
- int _S4 = calcThing_0(index_0);
- ((outputBuffer_0)._data[(uint(index_0))]) = _S4;
- return;
-}
-
-}
diff --git a/tests/experimental/liveness/liveness-5.slang b/tests/experimental/liveness/liveness-5.slang
deleted file mode 100644
index 98fa6ff6f..000000000
--- a/tests/experimental/liveness/liveness-5.slang
+++ /dev/null
@@ -1,42 +0,0 @@
-//TEST:SIMPLE:-target glsl -entry computeMain -profile cs_6_3 -track-liveness -line-directive-mode none
-
-//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
-RWStructuredBuffer<int> outputBuffer;
-
-// Test loop handling, with more complex structure
-
-int calcThing(int offset)
-{
- int total = 0;
- int another[2] = { 1, 2};
-
- for (int k = 0; k < 20; ++k)
- {
- for (int i = 0; i < 17; ++i)
- {
- another[i & 1] += k + i;
- }
-
- total += another[k & 1];
-
- if ((k + 7) % 5 == 4)
- {
- return 1;
- }
- }
-
- if (total > 4)
- {
- total = -total;
- }
-
- return total;
-}
-
-[numthreads(4, 1, 1)]
-void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
-{
- int index = int(dispatchThreadID.x);
-
- outputBuffer[index] = calcThing(index);
-}
diff --git a/tests/experimental/liveness/liveness-5.slang.expected b/tests/experimental/liveness/liveness-5.slang.expected
deleted file mode 100644
index 901b93bc6..000000000
--- a/tests/experimental/liveness/liveness-5.slang.expected
+++ /dev/null
@@ -1,98 +0,0 @@
-result code = 0
-standard error = {
-}
-standard output = {
-#version 450
-#extension GL_EXT_spirv_intrinsics : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-layout(std430, binding = 0) buffer _S1 {
- int _data[];
-} outputBuffer_0;
-spirv_instruction(id = 256)
-void livenessStart_0(spirv_by_reference int _0[2], spirv_literal int _1);
-
-spirv_instruction(id = 256)
-void livenessStart_1(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_0(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_1(spirv_by_reference int _0[2], spirv_literal int _1);
-
-int calcThing_0(int offset_0)
-{
- int another_0[2];
- livenessStart_0(another_0, 0);
- another_0[0] = 1;
- another_0[1] = 2;
- int k_0;
- livenessStart_1(k_0, 0);
- k_0 = 0;
- int total_0;
- livenessStart_1(total_0, 0);
- total_0 = 0;
- for(;;)
- {
- if(k_0 < 20)
- {
- }
- else
- {
- livenessEnd_0(k_0, 0);
- break;
- }
- bool _S2 = (k_0 + 7) % 5 == 4;
- int k_1 = k_0 + 1;
- int i_0;
- livenessStart_1(i_0, 0);
- i_0 = 0;
- for(;;)
- {
- if(i_0 < 17)
- {
- }
- else
- {
- livenessEnd_0(i_0, 0);
- break;
- }
- another_0[i_0 & 1] = another_0[i_0 & 1] + (k_0 + i_0);
- i_0 = i_0 + 1;
- }
- livenessEnd_0(k_0, 0);
- int _S3 = total_0;
- livenessEnd_0(total_0, 0);
- int total_1 = _S3 + another_0[k_0 & 1];
- if(_S2)
- {
- livenessEnd_1(another_0, 0);
- return 1;
- }
- livenessStart_1(k_0, 0);
- k_0 = k_1;
- livenessStart_1(total_0, 0);
- total_0 = total_1;
- }
- livenessEnd_1(another_0, 0);
- if(total_0 > 4)
- {
- total_0 = - total_0;
- }
- else
- {
- }
- return total_0;
-}
-
-layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
-void main()
-{
- int index_0 = int(gl_GlobalInvocationID.x);
- int _S4 = calcThing_0(index_0);
- ((outputBuffer_0)._data[(uint(index_0))]) = _S4;
- return;
-}
-
-}
diff --git a/tests/experimental/liveness/liveness-6.slang b/tests/experimental/liveness/liveness-6.slang
deleted file mode 100644
index d124efd35..000000000
--- a/tests/experimental/liveness/liveness-6.slang
+++ /dev/null
@@ -1,47 +0,0 @@
-//TEST:SIMPLE:-target glsl -entry computeMain -profile cs_6_3 -track-liveness -line-directive-mode none
-
-//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
-RWStructuredBuffer<int> outputBuffer;
-
-// Test loop handling, with more complex structure
-// More testing around liveness and loops.
-
-int calcThing(int offset)
-{
- int total = 0;
- int another[2] = { 1, 2};
-
- for (int k = 0; k < 20; ++k)
- {
- int arr[2] = { 2, 3};
-
- for (int i = 0; i < 17; ++i)
- {
- another[i & 1] += k + i;
- arr[k & 1] += i;
- }
-
- total += another[k & 1];
- total += arr[k & 1];
-
- if ((k + 7) % 5 == 4)
- {
- return 1;
- }
- }
-
- if (total > 4)
- {
- total = -total;
- }
-
- return total;
-}
-
-[numthreads(4, 1, 1)]
-void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
-{
- int index = int(dispatchThreadID.x);
-
- outputBuffer[index] = calcThing(index);
-}
diff --git a/tests/experimental/liveness/liveness-6.slang.expected b/tests/experimental/liveness/liveness-6.slang.expected
deleted file mode 100644
index 1fe9408c8..000000000
--- a/tests/experimental/liveness/liveness-6.slang.expected
+++ /dev/null
@@ -1,107 +0,0 @@
-result code = 0
-standard error = {
-}
-standard output = {
-#version 450
-#extension GL_EXT_spirv_intrinsics : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-layout(std430, binding = 0) buffer _S1 {
- int _data[];
-} outputBuffer_0;
-spirv_instruction(id = 256)
-void livenessStart_0(spirv_by_reference int _0[2], spirv_literal int _1);
-
-spirv_instruction(id = 256)
-void livenessStart_1(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_0(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_1(spirv_by_reference int _0[2], spirv_literal int _1);
-
-int calcThing_0(int offset_0)
-{
- int another_0[2];
- livenessStart_0(another_0, 0);
- another_0[0] = 1;
- another_0[1] = 2;
- int k_0;
- livenessStart_1(k_0, 0);
- k_0 = 0;
- int total_0;
- livenessStart_1(total_0, 0);
- total_0 = 0;
- for(;;)
- {
- if(k_0 < 20)
- {
- }
- else
- {
- livenessEnd_0(k_0, 0);
- break;
- }
- int arr_0[2];
- livenessStart_0(arr_0, 0);
- arr_0[0] = 2;
- arr_0[1] = 3;
- int _S2 = k_0 & 1;
- bool _S3 = (k_0 + 7) % 5 == 4;
- int k_1 = k_0 + 1;
- int i_0;
- livenessStart_1(i_0, 0);
- i_0 = 0;
- for(;;)
- {
- if(i_0 < 17)
- {
- }
- else
- {
- livenessEnd_0(i_0, 0);
- break;
- }
- another_0[i_0 & 1] = another_0[i_0 & 1] + (k_0 + i_0);
- arr_0[_S2] = arr_0[_S2] + i_0;
- i_0 = i_0 + 1;
- }
- livenessEnd_0(k_0, 0);
- int _S4 = total_0;
- livenessEnd_0(total_0, 0);
- int total_1 = _S4 + another_0[_S2];
- int _S5 = arr_0[_S2];
- livenessEnd_1(arr_0, 0);
- int total_2 = total_1 + _S5;
- if(_S3)
- {
- livenessEnd_1(another_0, 0);
- return 1;
- }
- livenessStart_1(k_0, 0);
- k_0 = k_1;
- livenessStart_1(total_0, 0);
- total_0 = total_2;
- }
- livenessEnd_1(another_0, 0);
- if(total_0 > 4)
- {
- total_0 = - total_0;
- }
- else
- {
- }
- return total_0;
-}
-
-layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
-void main()
-{
- int index_0 = int(gl_GlobalInvocationID.x);
- int _S6 = calcThing_0(index_0);
- ((outputBuffer_0)._data[(uint(index_0))]) = _S6;
- return;
-}
-
-}
diff --git a/tests/experimental/liveness/liveness-7.slang b/tests/experimental/liveness/liveness-7.slang
deleted file mode 100644
index 1bf53b09d..000000000
--- a/tests/experimental/liveness/liveness-7.slang
+++ /dev/null
@@ -1,34 +0,0 @@
-//DISABLED_TEST:SIMPLE:-target glsl -entry computeMain -profile cs_6_3 -track-liveness -line-directive-mode none
-
-// This test is disabled because the loop will always be optimized out so no liveness info will be inserted.
-
-//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
-RWStructuredBuffer<int> outputBuffer;
-
-// Test loop handling, with more complex structure, and when code is unreachable
-// More testing around liveness and loops.
-
-int calcThing(int offset)
-{
- int arr[2] = { 2, 3};
-
- for (int k = 0; k < 20; ++k)
- {
- if (((k + offset) & 1) != 0)
- {
- return arr[0];
- }
- else
- {
- return arr[1];
- }
- }
-}
-
-[numthreads(4, 1, 1)]
-void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
-{
- int index = int(dispatchThreadID.x);
-
- outputBuffer[index] = calcThing(index);
-}
diff --git a/tests/experimental/liveness/liveness-7.slang.expected b/tests/experimental/liveness/liveness-7.slang.expected
deleted file mode 100644
index 52eafa5d1..000000000
--- a/tests/experimental/liveness/liveness-7.slang.expected
+++ /dev/null
@@ -1,66 +0,0 @@
-result code = 0
-standard error = {
-}
-standard output = {
-#version 450
-#extension GL_EXT_spirv_intrinsics : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-spirv_instruction(id = 256)
-void livenessStart_0(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_0(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 256)
-void livenessStart_1(spirv_by_reference int _0[2], spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_1(spirv_by_reference int _0[2], spirv_literal int _1);
-
-int calcThing_0(int offset_0)
-{
- const int _S1[2] = { 2, 3 };
- int k_0;
- int _S2;
- int arr_0[2];
- livenessStart_0(k_0, 0);
- livenessEnd_0(k_0, 0);
- k_0 = 0;
- livenessStart_0(_S2, 0);
- _S2 = offset_0;
- livenessStart_1(arr_0, 0);
- arr_0 = _S1;
- for(;;)
- {
- int _S3 = _S2;
- livenessEnd_0(_S2, 0);
- if((0 + _S3 & 1) != 0)
- {
- int _S4[2] = arr_0;
- livenessEnd_1(arr_0, 0);
- return _S4[0];
- }
- else
- {
- int _S5[2] = arr_0;
- livenessEnd_1(arr_0, 0);
- return _S5[1];
- }
- }
-}
-
-layout(std430, binding = 0) buffer _S6 {
- int _data[];
-} outputBuffer_0;
-layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
-void main()
-{
- int index_0 = int(gl_GlobalInvocationID.x);
- uint _S7 = uint(index_0);
- int _S8 = calcThing_0(index_0);
- ((outputBuffer_0)._data[(_S7)]) = _S8;
- return;
-}
-
-}
diff --git a/tests/experimental/liveness/liveness.slang b/tests/experimental/liveness/liveness.slang
deleted file mode 100644
index a84cf268a..000000000
--- a/tests/experimental/liveness/liveness.slang
+++ /dev/null
@@ -1,80 +0,0 @@
-//TEST:SIMPLE:-target glsl -entry computeMain -profile cs_6_3 -track-liveness -line-directive-mode none
-
-//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
-RWStructuredBuffer<int> outputBuffer;
-
-struct SomeStruct
-{
- int a;
- int x;
- // Make it 'big'
- int c[100];
-};
-
-//TEST_INPUT:ubuffer(data=[1 4 27 17], stride=4):name anotherBuffer
-RWStructuredBuffer<int> anotherBuffer;
-
-SomeStruct makeSomeStruct()
-{
- SomeStruct s = {};
- return s;
-}
-
-// A silly function that is in some sense 'slow'
-int someSlowFunc(int a)
-{
- uint v = a;
- for (int i = 0; i < a * 20; ++i)
- {
- v = ((v >> 1) | (v << 31)) * i;
- }
- return int(v);
-}
-
-int somethingElse(inout SomeStruct s)
-{
- s.x ++;
- return s.x;
-}
-
-int doThing(SomeStruct s)
-{
- return s.x * 2 + 1;
-}
-
-[numthreads(4, 1, 1)]
-void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
-{
- int index = int(dispatchThreadID.x);
-
- int res = index;
-
- for (int i = 0; i < index; ++i)
- {
- int v = someSlowFunc(index); // s mut not be considered live here.
-
- SomeStruct s;
- SomeStruct t = makeSomeStruct();
- SomeStruct u = {};
-
- if ((v & 0x100) != 0)
- {
- s.x = anotherBuffer[v & 3];
- t.x = anotherBuffer[v & 3];
- }
- else
- {
- {
- SomeStruct x = u;
- x.x = anotherBuffer[v & 3] + 1;
- u = x;
- }
- }
-
- s.c[index & 7]++;
-
- res += s.x + t.x + u.x + doThing(t) + somethingElse(t) + s.c[2];
- }
-
- outputBuffer[index] = res;
-}
diff --git a/tests/experimental/liveness/liveness.slang.expected b/tests/experimental/liveness/liveness.slang.expected
deleted file mode 100644
index 8fa260ca5..000000000
--- a/tests/experimental/liveness/liveness.slang.expected
+++ /dev/null
@@ -1,168 +0,0 @@
-result code = 0
-standard error = {
-}
-standard output = {
-#version 450
-#extension GL_EXT_spirv_intrinsics : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-layout(std430, binding = 1) buffer _S1 {
- int _data[];
-} anotherBuffer_0;
-layout(std430, binding = 0) buffer _S2 {
- int _data[];
-} outputBuffer_0;
-spirv_instruction(id = 256)
-void livenessStart_0(spirv_by_reference uint _0, spirv_literal int _1);
-
-spirv_instruction(id = 256)
-void livenessStart_1(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_0(spirv_by_reference int _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_1(spirv_by_reference uint _0, spirv_literal int _1);
-
-int someSlowFunc_0(int a_0)
-{
- uint _S3 = uint(a_0);
- int _S4 = a_0 * 20;
- uint v_0;
- livenessStart_0(v_0, 0);
- v_0 = _S3;
- int i_0;
- livenessStart_1(i_0, 0);
- i_0 = 0;
- for(;;)
- {
- if(i_0 < _S4)
- {
- }
- else
- {
- livenessEnd_0(i_0, 0);
- break;
- }
- uint _S5 = v_0 >> 1;
- uint _S6 = v_0;
- livenessEnd_1(v_0, 0);
- uint _S7 = uint(int(_S5 | _S6 << 31) * i_0);
- int i_1 = i_0 + 1;
- livenessStart_0(v_0, 0);
- v_0 = _S7;
- i_0 = i_1;
- }
- return int(v_0);
-}
-
-struct SomeStruct_0
-{
- int a_1;
- int x_0;
- int c_0[100];
-};
-
-SomeStruct_0 makeSomeStruct_0()
-{
- const int _S8[100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- SomeStruct_0 s_0 = { 0, 0, _S8 };
- return s_0;
-}
-
-int doThing_0(SomeStruct_0 s_1)
-{
- return s_1.x_0 * 2 + 1;
-}
-
-int somethingElse_0(inout SomeStruct_0 s_2)
-{
- int _S9 = s_2.x_0 + 1;
- s_2.x_0 = _S9;
- return _S9;
-}
-
-spirv_instruction(id = 256)
-void livenessStart_2(spirv_by_reference SomeStruct_0 _0, spirv_literal int _1);
-
-spirv_instruction(id = 257)
-void livenessEnd_2(spirv_by_reference SomeStruct_0 _0, spirv_literal int _1);
-
-layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
-void main()
-{
- int index_0 = int(gl_GlobalInvocationID.x);
- const int _S10[100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int _S11 = index_0 & 7;
- uint _S12 = uint(index_0);
- int i_2;
- livenessStart_1(i_2, 0);
- i_2 = 0;
- int res_0;
- livenessStart_1(res_0, 0);
- res_0 = index_0;
- for(;;)
- {
- if(i_2 < index_0)
- {
- }
- else
- {
- livenessEnd_0(i_2, 0);
- break;
- }
- int v_1 = someSlowFunc_0(index_0);
- SomeStruct_0 s_3;
- livenessStart_2(s_3, 0);
- SomeStruct_0 t_0;
- livenessStart_2(t_0, 0);
- t_0 = makeSomeStruct_0();
- SomeStruct_0 u_0;
- if((v_1 & 256) != 0)
- {
- uint _S13 = uint(v_1 & 3);
- s_3.x_0 = ((anotherBuffer_0)._data[(_S13)]);
- t_0.x_0 = ((anotherBuffer_0)._data[(_S13)]);
- livenessStart_2(u_0, 0);
- u_0.a_1 = 0;
- u_0.x_0 = 0;
- u_0.c_0 = _S10;
- }
- else
- {
- SomeStruct_0 x_1;
- livenessStart_2(x_1, 0);
- x_1.a_1 = 0;
- x_1.x_0 = 0;
- x_1.c_0 = _S10;
- x_1.x_0 = ((anotherBuffer_0)._data[(uint(v_1 & 3))]) + 1;
- SomeStruct_0 _S14 = x_1;
- livenessEnd_2(x_1, 0);
- livenessStart_2(u_0, 0);
- u_0 = _S14;
- }
- s_3.c_0[_S11] = s_3.c_0[_S11] + 1;
- int _S15 = s_3.x_0 + t_0.x_0;
- SomeStruct_0 _S16 = u_0;
- livenessEnd_2(u_0, 0);
- int _S17 = _S15 + _S16.x_0 + doThing_0(t_0);
- int _S18 = somethingElse_0(t_0);
- livenessEnd_2(t_0, 0);
- int _S19 = _S17 + _S18;
- int _S20 = s_3.c_0[2];
- livenessEnd_2(s_3, 0);
- int _S21 = _S19 + _S20;
- int _S22 = res_0;
- livenessEnd_0(res_0, 0);
- int res_1 = _S22 + _S21;
- i_2 = i_2 + 1;
- livenessStart_1(res_0, 0);
- res_0 = res_1;
- }
- int _S23 = res_0;
- livenessEnd_0(res_0, 0);
- ((outputBuffer_0)._data[(_S12)]) = _S23;
- return;
-}
-
-}
diff --git a/tests/hlsl-intrinsic/debug-break.slang b/tests/hlsl-intrinsic/debug-break.slang
index e46c42004..5c783f332 100644
--- a/tests/hlsl-intrinsic/debug-break.slang
+++ b/tests/hlsl-intrinsic/debug-break.slang
@@ -1,4 +1,4 @@
-//TEST:SIMPLE:-stage compute -entry computeMain -target glsl -line-directive-mode none
+//TEST:SIMPLE(filecheck=CHECK):-stage compute -entry computeMain -target glsl -line-directive-mode none
// We can't enable because output source includes path to prelude.
//DISABLE_TEST:SIMPLE:-stage compute -entry computeMain -target cpp -line-directive-mode none
//DISABLE_TEST:SIMPLE:-stage compute -entry computeMain -target cuda -line-directive-mode none
@@ -10,6 +10,11 @@
//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0], stride=4):out,name outputBuffer
+// CHECK: spirv_instruction(id = 1, set = "NonSemantic.DebugBreak")
+// CHECK: void debugBreak{{.*}}();
+// CHECK: void main
+// CHECK: debugBreak{{.*}}();
+
RWStructuredBuffer<int> outputBuffer;
[numthreads(4, 1, 1)]
diff --git a/tests/hlsl-intrinsic/debug-break.slang.expected b/tests/hlsl-intrinsic/debug-break.slang.expected
deleted file mode 100644
index 503cdfd72..000000000
--- a/tests/hlsl-intrinsic/debug-break.slang.expected
+++ /dev/null
@@ -1,24 +0,0 @@
-result code = 0
-standard error = {
-}
-standard output = {
-#version 450
-#extension GL_EXT_spirv_intrinsics : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-layout(std430, binding = 0) buffer _S1 {
- int _data[];
-} outputBuffer_0;
-spirv_instruction(id = 1, set = "NonSemantic.DebugBreak")
-void debugBreak_0();
-
-layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
-void main()
-{
- int idx_0 = int(gl_GlobalInvocationID.x);
- debugBreak_0();
- ((outputBuffer_0)._data[(uint(idx_0))]) = idx_0;
- return;
-}
-
-}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-assign.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-assign.slang.1.expected
index 97b04be47..4338e70ac 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-assign.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-assign.slang.1.expected
@@ -36,8 +36,7 @@ void main()
hitObjectNV hitObj_1;
hitObjectRecordMissNV(hitObj_1, _S5, ray_0.Origin_0, ray_0.TMin_0, ray_0.Direction_0, ray_0.TMax_0);
bool _S6 = (hitObjectIsMissNV((hitObj_1)));
- uint _S7 = uint(int(_S6));
- ((outputBuffer_0)._data[(_S4)]) = _S7;
+ outputBuffer_0._data[_S4] = uint(int(_S6));
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected
index 0fd0214e4..199fdc86b 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected
@@ -104,8 +104,7 @@ void main()
hitObjectNV hitObj_1;
hitObjectRecordHitNV(hitObj_1, scene_0, _S14, _S16, _S15, 0U, 0U, 4U, _S17.Origin_0, _S17.TMin_0, _S17.Direction_0, _S17.TMax_0, (0));
uint _S18 = calcValue_0(hitObj_1);
- uint r_4 = r_3 + _S18;
- ((outputBuffer_0)._data[(_S10)]) = r_4;
+ outputBuffer_0._data[_S10] = r_3 + _S18;
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-miss.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-miss.slang.1.expected
index c79c238e6..ed80f38d3 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-miss.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-miss.slang.1.expected
@@ -31,8 +31,7 @@ void main()
hitObjectNV hitObj_0;
hitObjectRecordMissNV(hitObj_0, _S2, ray_0.Origin_0, ray_0.TMin_0, ray_0.Direction_0, ray_0.TMax_0);
bool _S3 = (hitObjectIsMissNV((hitObj_0)));
- uint _S4 = uint(int(_S3));
- ((outputBuffer_0)._data[(_S2)]) = _S4;
+ outputBuffer_0._data[_S2] = uint(int(_S3));
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-nop.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-nop.slang.1.expected
index 956dddad3..c8136645c 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-nop.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-nop.slang.1.expected
@@ -20,8 +20,7 @@ void main()
hitObjectRecordEmptyNV((hitObj_0));
uint _S4 = uint(idx_0);
bool _S5 = (hitObjectIsEmptyNV((hitObj_0)));
- uint _S6 = uint(_S5);
- ((outputBuffer_0)._data[(_S4)]) = _S6;
+ outputBuffer_0._data[_S4] = uint(_S5);
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-output.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-output.slang.1.expected
index f5e7908af..a6c28c86b 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-output.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-output.slang.1.expected
@@ -86,7 +86,7 @@ void main()
hitObjectRecordMissNV(hitObj_1, idx_1, ray_2.Origin_0, ray_2.TMin_0, ray_2.Direction_0, ray_2.TMax_0);
accumulate_0(r_0, hitObj_1);
accumulate_0(r_0, hitObj_0);
- ((outputBuffer_0)._data[(idx_1)]) = r_0;
+ outputBuffer_0._data[idx_1] = r_0;
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected
index ae8efee2b..00213c62d 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected
@@ -113,8 +113,7 @@ void main()
otherValues_0.b_0 = _S12;
HitObject_Invoke_0(scene_0, hitObj_0, otherValues_0);
uint _S13 = calcValue_0(hitObj_0);
- uint r_4 = r_3 + _S13;
- ((outputBuffer_0)._data[(uint(idx_0))]) = r_4;
+ outputBuffer_0._data[uint(idx_0)] = r_3 + _S13;
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected
index 89344c39a..535a7ccb7 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected
@@ -83,7 +83,7 @@ void main()
hitObjectTraceRayMotionNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S7.Origin_0, _S7.TMin_0, _S7.Direction_0, _S7.TMax_0, currentTime_0, (0));
uint _S8 = uint(idx_0);
uint _S9 = calcValue_0(hitObj_0);
- ((outputBuffer_0)._data[(_S8)]) = _S9;
+ outputBuffer_0._data[_S8] = _S9;
return;
}
diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected
index 8fc6a1cf5..b1441df72 100644
--- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected
+++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected
@@ -81,7 +81,7 @@ void main()
hitObjectTraceRayNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S7.Origin_0, _S7.TMin_0, _S7.Direction_0, _S7.TMax_0, (0));
uint _S8 = uint(idx_0);
uint _S9 = calcValue_0(hitObj_0);
- ((outputBuffer_0)._data[(_S8)]) = _S9;
+ outputBuffer_0._data[_S8] = _S9;
return;
}
diff --git a/tests/hlsl/glsl-matrix-layout.slang b/tests/hlsl/glsl-matrix-layout.slang
new file mode 100644
index 000000000..6178cc813
--- /dev/null
+++ b/tests/hlsl/glsl-matrix-layout.slang
@@ -0,0 +1,67 @@
+// Test that storage type lowering correctly handles matrix layout modifiers.
+
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -shaderobj -output-using-type -xslang -use-glsl-matrix-layout-modifier -xslang -fvk-use-gl-layout
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0 0 ], stride=4):out,name=outputBuffer
+RWStructuredBuffer<float> outputBuffer;
+
+struct MyStruct
+{
+ // row_major here is flipped by the `-use-glsl-matrix-layout-modifier` compiler option so
+ // it actually means column_major here.
+ row_major float3x2 mat;
+ int otherVal[4];
+
+}
+
+//TEST_INPUT: set gConst = cbuffer(data=[1.0 3.0 5.0 0.0 2.0 4.0 6.0 0.0 100 101 102 103])
+// gConst will be:
+// -- --
+// | 1.0 2.0 |
+// | 3.0 4.0 |
+// | 5.0 6.0 |
+// -- --
+ConstantBuffer<MyStruct> gConst;
+
+//TEST_INPUT: set gStructBuffer = ubuffer(data=[1.0 3.0 5.0 0.0 2.0 4.0 6.0 0.0 100 101 102 103 1.0 3.0 5.0 0.0 2.0 4.0 6.0 0.0 100 101 102 103])
+RWStructuredBuffer<MyStruct[2]> gStructBuffer;
+
+//TEST_INPUT: set gRawBuffer = ubuffer(data=[1.0 3.0 5.0 0.0 2.0 4.0 6.0 0.0 100 101 102 103])
+RWByteAddressBuffer gRawBuffer;
+
+[numthreads(1, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ {
+ float2 v = float2(2.0, 3.0);
+ float3 vm = mul(gConst.mat, v);
+ outputBuffer[0] = vm.x; // 8
+ outputBuffer[1] = vm.y; // 18
+ outputBuffer[2] = vm.z; // 28
+ }
+ {
+ float2 v = float2(2.0, 3.0);
+ float3 vm = mul(gStructBuffer[0][0].mat, v);
+ outputBuffer[3] = vm.x; // 8
+ outputBuffer[4] = vm.y; // 18
+ outputBuffer[5] = vm.z; // 28
+ }
+ {
+ float2 v = float2(2.0, 3.0);
+ float3 vm = mul(gRawBuffer.Load<MyStruct>(0).mat, v);
+ outputBuffer[6] = vm.x; // 8
+ outputBuffer[7] = vm.y; // 18
+ outputBuffer[8] = vm.z; // 28
+ gRawBuffer.Store(0, gRawBuffer.Load<MyStruct>(0));
+ vm = mul(gRawBuffer.Load<MyStruct>(0).mat, v);
+ outputBuffer[9] = vm.x; // 8
+ outputBuffer[10] = vm.y; // 18
+ outputBuffer[11] = vm.z; // 28
+ }
+
+ {
+ int original;
+ InterlockedAdd(gStructBuffer[0][0].otherVal[0], 1, original);
+ outputBuffer[12] = gStructBuffer[0][0].otherVal[0];
+ }
+}
diff --git a/tests/hlsl/glsl-matrix-layout.slang.expected.txt b/tests/hlsl/glsl-matrix-layout.slang.expected.txt
new file mode 100644
index 000000000..0c2522f4f
--- /dev/null
+++ b/tests/hlsl/glsl-matrix-layout.slang.expected.txt
@@ -0,0 +1,14 @@
+type: float
+8
+18
+28
+8
+18
+28
+8
+18
+28
+8
+18
+28
+101.0 \ No newline at end of file
diff --git a/tests/spirv/spirv-debug-break.slang b/tests/spirv/spirv-debug-break.slang
index 18e8c8597..e57024037 100644
--- a/tests/spirv/spirv-debug-break.slang
+++ b/tests/spirv/spirv-debug-break.slang
@@ -1,5 +1,5 @@
// spirv-instruction.slang
-//TEST(compute, vulkan):SIMPLE:-target glsl -entry computeMain -stage compute
+//TEST(compute, vulkan):SIMPLE(filecheck=CHECK):-target glsl -entry computeMain -stage compute
[[vk::spirv_instruction(1, "NonSemantic.DebugBreak")]]
void _spvDebugBreak(int v);
@@ -7,6 +7,10 @@ void _spvDebugBreak(int v);
[ForceInline]
void _debugBreak() { _spvDebugBreak(1); }
+// CHECK:spirv_instruction(id = 1, set = "NonSemantic.DebugBreak")
+// CHECK:void _spvDebugBreak_0(int _0);
+// CHECK:void main()
+// CHECK:_spvDebugBreak_0(1);
//TEST_INPUT:set resultBuffer = out ubuffer(data=[0 0 0 0], stride=4)
RWStructuredBuffer<uint> resultBuffer;
diff --git a/tests/spirv/spirv-debug-break.slang.expected b/tests/spirv/spirv-debug-break.slang.expected
deleted file mode 100644
index 219aab7d2..000000000
--- a/tests/spirv/spirv-debug-break.slang.expected
+++ /dev/null
@@ -1,37 +0,0 @@
-result code = 0
-standard error = {
-}
-standard output = {
-#version 450
-#extension GL_EXT_spirv_intrinsics : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-
-#line 12 0
-layout(std430, binding = 0) buffer _S1 {
- uint _data[];
-} resultBuffer_0;
-
-#line 5
-spirv_instruction(id = 1, set = "NonSemantic.DebugBreak")
-void _spvDebugBreak_0(int _0);
-
-
-#line 15
-layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
-void main()
-{
-
-#line 17
- uint threadId_0 = gl_GlobalInvocationID.x;
-
- _spvDebugBreak_0(1);
-
- uint _S2 = threadId_0 + threadId_0;
-
-#line 21
- ((resultBuffer_0)._data[(threadId_0)]) = _S2;
- return;
-}
-
-}
diff --git a/tools/slang-test/test-reporter.cpp b/tools/slang-test/test-reporter.cpp
index e0696eab2..ede5823c7 100644
--- a/tools/slang-test/test-reporter.cpp
+++ b/tools/slang-test/test-reporter.cpp
@@ -221,13 +221,6 @@ void TestReporter::dumpOutputDifference(const String& expectedOutput, const Stri
expectedOutput.getBuffer(),
actualOutput.getBuffer());
-
- if (m_dumpOutputOnFailure && canWriteStdError())
- {
- fprintf(stderr, "%s", builder.getBuffer());
- fflush(stderr);
- }
-
// Add to the m_currentInfo
message(TestMessageType::TestFailure, builder);
}