diff options
| author | Ellie Hermaszewska <ellieh@nvidia.com> | 2022-11-16 09:49:06 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-16 09:49:06 +0800 |
| commit | 1643471da0d6239177d11b0301c26d1adf95c0fb (patch) | |
| tree | 9b8fddf92a5f817541e055a2657f9b0a00f90069 /tests/pipeline | |
| parent | 4917d71100aafcc38a81cd99d2a44a4cb3a89a0c (diff) | |
Mesh shader support (#2464)
* Add gdb generated files to .gitignore
* Switch to c++17
TODO: Ellie update coding style doc
* WIP mesh shaders
* Add MeshOutputType and mesh output decorations
* Lift array type layout creation out of _createTypeLayout
in preparation for sharing it elsewhere
* Initial pass at GLSL legalization for mesh shaders
* Create output types for builtin mesh outputs
This should be rendered as an out paramter block
* Handle writes to member fields in mesh shader output
* Per primitive output from mesh shaders
* Add mesh shader tests
* Redeclare mesh output builtins
* Remove unused instruction
* Emit explicit mesh output max max size
* Add unimplemented warning for array members in mesh output
* Implement mesh output splitting for GLSL in terms of getSubscriptVal
* Allow HLSL syntax for mesh output modifiers
* Improve error messages for mesh output
* Add test for HLSL style mesh output syntax
* Emit explicit mesh output indices max size
* HLSL generation support for mesh shaders
* Better errors for mesh shader misuse
* Neaten comments
* Regenerate vs2019 project files
* Fix build on vs2019
* Retreat on c++17
Will make the change in a separate PR
* slang-glslang binary dep 11.10.0 -> 11.12.0-32
* Fixes for msvc compiler
* Update msvc project
Diffstat (limited to 'tests/pipeline')
15 files changed, 888 insertions, 0 deletions
diff --git a/tests/pipeline/rasterization/mesh/component-write.slang b/tests/pipeline/rasterization/mesh/component-write.slang new file mode 100644 index 000000000..a34f6ee31 --- /dev/null +++ b/tests/pipeline/rasterization/mesh/component-write.slang @@ -0,0 +1,49 @@ +// component-write.slang + +// This tests that writing to individual components of the output struct works + +//TEST:CROSS_COMPILE:-target spirv -profile glsl_450+spirv_1_4 -entry main -stage mesh + +const static float2 positions[3] = { + float2(0.0, -0.5), + float2(0.5, 0.5), + float2(-0.5, 0.5) +}; + +const static float3 colors[3] = { + float3(1.0, 1.0, 0.0), + float3(0.0, 1.0, 1.0), + float3(1.0, 0.0, 1.0) +}; + +struct Vertex +{ + float4 pos : SV_Position; + float3 color : Color; +}; + +const static uint MAX_VERTS = 3; +const static uint MAX_PRIMS = 1; + +[outputtopology("triangle")] +[numthreads(3, 1, 1)] +void main( + in uint tig : SV_GroupIndex, + out Vertices<Vertex, MAX_VERTS> verts, + out Indices<uint3, MAX_PRIMS> triangles + ) +{ + const uint numVertices = 3; + const uint numPrimitives = 1; + SetMeshOutputCounts(numVertices, numPrimitives); + + if(tig < numVertices) { + verts[tig].pos = float4(positions[tig], 0, 1); + verts[tig].color = colors[tig]; + } + + if(tig < numPrimitives) { + triangles[tig] = uint3(0,1,2); + } +} + diff --git a/tests/pipeline/rasterization/mesh/component-write.slang.glsl b/tests/pipeline/rasterization/mesh/component-write.slang.glsl new file mode 100644 index 000000000..5234fb62f --- /dev/null +++ b/tests/pipeline/rasterization/mesh/component-write.slang.glsl @@ -0,0 +1,39 @@ +#version 450 +#extension GL_EXT_mesh_shader : require +layout(row_major) uniform; +layout(row_major) buffer; +const vec3 colors_0[3] = { vec3(1.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000), vec3(0.00000000000000000000, 1.00000000000000000000, 1.00000000000000000000), vec3(1.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000) }; +const vec2 positions_0[3] = { vec2(0.00000000000000000000, -0.50000000000000000000), vec2(0.50000000000000000000, 0.50000000000000000000), vec2(-0.50000000000000000000, 0.50000000000000000000) }; +layout(location = 0) +out vec3 _S1[3]; + +out gl_MeshPerVertexEXT +{ + vec4 gl_Position; +} gl_MeshVerticesEXT[3]; + +layout(local_size_x = 3, local_size_y = 1, local_size_z = 1) in; +layout(max_vertices = 3) out; +layout(max_primitives = 1) out; +layout(triangles) out; +void main() +{ + SetMeshOutputsEXT(3U, 1U); + if(gl_LocalInvocationIndex < 3U) + { + gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(positions_0[gl_LocalInvocationIndex], 0.00000000000000000000, 1.00000000000000000000); + _S1[gl_LocalInvocationIndex] = colors_0[gl_LocalInvocationIndex]; + } + else + { + } + if(gl_LocalInvocationIndex < 1U) + { + gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0U, 1U, 2U); + } + else + { + } + return; +} + diff --git a/tests/pipeline/rasterization/mesh/hello.slang b/tests/pipeline/rasterization/mesh/hello.slang new file mode 100644 index 000000000..5eea900d3 --- /dev/null +++ b/tests/pipeline/rasterization/mesh/hello.slang @@ -0,0 +1,49 @@ +// hello.slang + +// Test that a simple mesh shader compiles + +//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage mesh -profile glsl_450+spirv_1_4 +//TEST:CROSS_COMPILE:-target dxil-assembly -entry main -stage mesh -profile sm_6_6 + +const static float2 positions[3] = { + float2(0.0, -0.5), + float2(0.5, 0.5), + float2(-0.5, 0.5) +}; + +const static float3 colors[3] = { + float3(1.0, 1.0, 0.0), + float3(0.0, 1.0, 1.0), + float3(1.0, 0.0, 1.0) +}; + +struct Vertex +{ + float4 pos : SV_Position; + float3 color : Color; +}; + +const static uint MAX_VERTS = 3; +const static uint MAX_PRIMS = 1; + +[outputtopology("triangle")] +[numthreads(3, 1, 1)] +void main( + in uint tig : SV_GroupIndex, + out Vertices<Vertex, MAX_VERTS> verts, + out Indices<uint3, MAX_PRIMS> triangles + ) +{ + const uint numVertices = 3; + const uint numPrimitives = 1; + SetMeshOutputCounts(numVertices, numPrimitives); + + if(tig < numVertices) { + verts[tig] = {float4(positions[tig], 0, 1), colors[tig]}; + } + + if(tig < numPrimitives) { + triangles[tig] = uint3(0,1,2); + } +} + diff --git a/tests/pipeline/rasterization/mesh/hello.slang.glsl b/tests/pipeline/rasterization/mesh/hello.slang.glsl new file mode 100644 index 000000000..66630012b --- /dev/null +++ b/tests/pipeline/rasterization/mesh/hello.slang.glsl @@ -0,0 +1,46 @@ +#version 450 +#extension GL_EXT_mesh_shader : require +layout(row_major) uniform; +layout(row_major) buffer; +const vec3 colors_0[3] = { vec3(1.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000), vec3(0.00000000000000000000, 1.00000000000000000000, 1.00000000000000000000), vec3(1.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000) }; +const vec2 positions_0[3] = { vec2(0.00000000000000000000, -0.50000000000000000000), vec2(0.50000000000000000000, 0.50000000000000000000), vec2(-0.50000000000000000000, 0.50000000000000000000) }; +layout(location = 0) +out vec3 _S1[3]; + +out gl_MeshPerVertexEXT +{ + vec4 gl_Position; +} gl_MeshVerticesEXT[3]; + +struct Vertex_0 +{ + vec4 pos_0; + vec3 color_0; +}; + +layout(local_size_x = 3, local_size_y = 1, local_size_z = 1) in; +layout(max_vertices = 3) out; +layout(max_primitives = 1) out; +layout(triangles) out; +void main() +{ + SetMeshOutputsEXT(3U, 1U); + if(gl_LocalInvocationIndex < 3U) + { + Vertex_0 _S2 = { vec4(positions_0[gl_LocalInvocationIndex], 0.00000000000000000000, 1.00000000000000000000), colors_0[gl_LocalInvocationIndex] }; + gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = _S2.pos_0; + _S1[gl_LocalInvocationIndex] = _S2.color_0; + } + else + { + } + if(gl_LocalInvocationIndex < 1U) + { + gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0U, 1U, 2U); + } + else + { + } + return; +} + diff --git a/tests/pipeline/rasterization/mesh/hello.slang.hlsl b/tests/pipeline/rasterization/mesh/hello.slang.hlsl new file mode 100644 index 000000000..ea41895b1 --- /dev/null +++ b/tests/pipeline/rasterization/mesh/hello.slang.hlsl @@ -0,0 +1,36 @@ +#pragma pack_matrix(column_major) +#ifdef SLANG_HLSL_ENABLE_NVAPI +#include "nvHLSLExtns.h" +#endif + +static const float3 colors_0[int(3)] = { float3(1.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000), float3(0.00000000000000000000, 1.00000000000000000000, 1.00000000000000000000), float3(1.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000) }; +static const float2 positions_0[int(3)] = { float2(0.00000000000000000000, -0.50000000000000000000), float2(0.50000000000000000000, 0.50000000000000000000), float2(-0.50000000000000000000, 0.50000000000000000000) }; +struct Vertex_0 +{ + float4 pos_0 : SV_Position; + float3 color_0 : Color; +}; + +[numthreads(3, 1, 1)] +[outputtopology("triangle")] +void main(uint tig_0 : SV_GROUPINDEX, vertices out Vertex_0 verts_0[int(3)], indices out uint3 triangles_0[int(1)]) +{ + SetMeshOutputCounts(3U, 1U); + if(tig_0 < 3U) + { + Vertex_0 _S1 = { float4(positions_0[tig_0], 0.00000000000000000000, 1.00000000000000000000), colors_0[tig_0] }; + verts_0[tig_0] = _S1; + } + else + { + } + if(tig_0 < 1U) + { + triangles_0[tig_0] = uint3(0U, 1U, 2U); + } + else + { + } + return; +} + diff --git a/tests/pipeline/rasterization/mesh/hlsl-syntax.slang b/tests/pipeline/rasterization/mesh/hlsl-syntax.slang new file mode 100644 index 000000000..a0b397ca2 --- /dev/null +++ b/tests/pipeline/rasterization/mesh/hlsl-syntax.slang @@ -0,0 +1,54 @@ +// hlsl-syntax.slang + +// Test that we can ingest hlsl mesh output syntax + +//TEST:CROSS_COMPILE:-target spirv -profile glsl_450+spirv_1_4 -entry main -stage mesh + +const static float2 positions[3] = { + float2(0.0, -0.5), + float2(0.5, 0.5), + float2(-0.5, 0.5) +}; + +const static float3 colors[3] = { + float3(1.0, 1.0, 0.0), + float3(0.0, 1.0, 1.0), + float3(1.0, 0.0, 1.0) +}; + +struct Vertex +{ + float4 pos : SV_Position; + float3 color : Color; +}; + +const static uint MAX_VERTS = 3; +const static uint MAX_PRIMS = 1; + +// Test that we can convert the HLSL Syntax to the typed syntax +void foo(uint tig, out Vertices<Vertex, MAX_VERTS> verts) +{ + if(tig < 3) { + verts[tig] = {float4(positions[tig], 0, 1), colors[tig]}; + } +} + +[outputtopology("triangle")] +[numthreads(3, 1, 1)] +void main( + in uint tig : SV_GroupIndex, + out vertices Vertex verts[MAX_VERTS], + out indices uint3 triangles[MAX_PRIMS] + ) +{ + const uint numVertices = 3; + const uint numPrimitives = 1; + SetMeshOutputCounts(numVertices, numPrimitives); + + foo(tig, verts); + + if(tig < numPrimitives) { + triangles[tig] = uint3(0,1,2); + } +} + diff --git a/tests/pipeline/rasterization/mesh/hlsl-syntax.slang.glsl b/tests/pipeline/rasterization/mesh/hlsl-syntax.slang.glsl new file mode 100644 index 000000000..4a6b8f86f --- /dev/null +++ b/tests/pipeline/rasterization/mesh/hlsl-syntax.slang.glsl @@ -0,0 +1,51 @@ +#version 450 +#extension GL_EXT_mesh_shader : require +layout(row_major) uniform; +layout(row_major) buffer; +const vec3 colors_0[3] = { vec3(1.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000), vec3(0.00000000000000000000, 1.00000000000000000000, 1.00000000000000000000), vec3(1.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000) }; +const vec2 positions_0[3] = { vec2(0.00000000000000000000, -0.50000000000000000000), vec2(0.50000000000000000000, 0.50000000000000000000), vec2(-0.50000000000000000000, 0.50000000000000000000) }; +layout(location = 0) +out vec3 _S1[3]; + +out gl_MeshPerVertexEXT +{ + vec4 gl_Position; +} gl_MeshVerticesEXT[3]; + +struct Vertex_0 +{ + vec4 pos_0; + vec3 color_0; +}; + +void foo_0(uint _S2) +{ + if(_S2 < 3U) + { + Vertex_0 _S3 = { vec4(positions_0[_S2], 0.00000000000000000000, 1.00000000000000000000), colors_0[_S2] }; + gl_MeshVerticesEXT[_S2].gl_Position = _S3.pos_0; + _S1[_S2] = _S3.color_0; + } + else + { + } + return; +} + +layout(local_size_x = 3, local_size_y = 1, local_size_z = 1) in; +layout(max_vertices = 3) out; +layout(max_primitives = 1) out; +layout(triangles) out; +void main() +{ + SetMeshOutputsEXT(3U, 1U); + foo_0(gl_LocalInvocationIndex); + if(gl_LocalInvocationIndex < 1U) + { + gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0U, 1U, 2U); + } + else + { + } + return; +} diff --git a/tests/pipeline/rasterization/mesh/nested-component-write.slang b/tests/pipeline/rasterization/mesh/nested-component-write.slang new file mode 100644 index 000000000..68bb6dfb9 --- /dev/null +++ b/tests/pipeline/rasterization/mesh/nested-component-write.slang @@ -0,0 +1,51 @@ +// nested-component-write.slang + +// This tests that writing to individual components nested structs works for +// mesh shader outputs. + +//TEST:CROSS_COMPILE:-target spirv -profile glsl_450+spirv_1_4 -entry main -stage mesh + +struct Foo +{ + float4 pos : SV_Position; + Bar bar; +}; + +struct Bar +{ + Baz baz : Color; +}; + +struct Baz +{ + float3 color; +}; + +struct Vertex +{ + Foo foo; +}; + +const static uint MAX_VERTS = 3; +const static uint MAX_PRIMS = 1; + +[outputtopology("triangle")] +[numthreads(3, 1, 1)] +void main( + in uint tig : SV_GroupIndex, + out Vertices<Vertex, MAX_VERTS> verts, + out Indices<uint3, MAX_PRIMS> triangles + ) +{ + SetMeshOutputCounts(3, 1); + + if(tig < 3) { + verts[tig].foo.pos = float4(0, 0, 0, 1); + verts[tig].foo.bar.baz.color = float3(1, 2, 3); + } + + if(tig < 1) { + triangles[tig] = uint3(0,1,2); + } +} + diff --git a/tests/pipeline/rasterization/mesh/nested-component-write.slang.glsl b/tests/pipeline/rasterization/mesh/nested-component-write.slang.glsl new file mode 100644 index 000000000..4c70955a1 --- /dev/null +++ b/tests/pipeline/rasterization/mesh/nested-component-write.slang.glsl @@ -0,0 +1,37 @@ +#version 450 +#extension GL_EXT_mesh_shader : require +layout(row_major) uniform; +layout(row_major) buffer; +layout(location = 0) +out vec3 _S1[3]; + +out gl_MeshPerVertexEXT +{ + vec4 gl_Position; +} gl_MeshVerticesEXT[3]; + +layout(local_size_x = 3, local_size_y = 1, local_size_z = 1) in; +layout(max_vertices = 3) out; +layout(max_primitives = 1) out; +layout(triangles) out; +void main() +{ + SetMeshOutputsEXT(3U, 1U); + if(gl_LocalInvocationIndex < 3U) + { + gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000); + _S1[gl_LocalInvocationIndex] = vec3(1.00000000000000000000, 2.00000000000000000000, 3.00000000000000000000); + } + else + { + } + if(gl_LocalInvocationIndex < 1U) + { + gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0U, 1U, 2U); + } + else + { + } + return; +} + diff --git a/tests/pipeline/rasterization/mesh/passing-outputs.slang b/tests/pipeline/rasterization/mesh/passing-outputs.slang new file mode 100644 index 000000000..321c1179e --- /dev/null +++ b/tests/pipeline/rasterization/mesh/passing-outputs.slang @@ -0,0 +1,114 @@ +// component-write.slang + +// This tests that writing to individual components of the output struct works + +//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage mesh -profile glsl_450+spirv_1_4 + +// DXC is stricter than we are about passing references to individual mesh shader outputs +// We could get around this by doing what we do for GLSL, i.e. use a temporary +// variable to pass as the out parameter, and then copy that into the array +// after the function call. +//TEST_DISABLED:CROSS_COMPILE:-target dxil-assembly -entry main -stage mesh -profile sm_6_6 + +const static uint MAX_VERTS = 3; +const static uint MAX_PRIMS = 1; + +struct Texes +{ + float2 tex1; + float4 tex2; +} + +struct Vertex +{ + float4 pos : SV_Position; + float3 col : Color; + Texes ts : Coord; +}; + +void everything<let N : uint>(out Vertices<Vertex, N> vs) +{ + vs[0] = {float4(0), float3(1)}; +} + +void just_one(out Vertex v) +{ + v = {float4(0), float3(1)}; +} + +void just_two(out Vertex v, out Vertex w) +{ + v = {float4(0), float3(1)}; + w = v; +} + +void part_of_one(out float4 p) +{ + p = float4(1,2,3,4); +} + +void write_struct(out Texes t) +{ + t.tex1 = float2(0); + t.tex2 = float4(1); +} + +// Split out the things to test to avoid main becoming an unreadable jumble +void a<let N : uint>(out Vertices<Vertex, N> vs) +{ + // Test passing a reference to the entire array + everything(vs); +} + +void b<let N : uint>(out Vertices<Vertex, N> vs) +{ + // test passing two references to the same element + just_two(vs[0], vs[0]); +} + +void c<let N : uint>(out Vertices<Vertex, N> vs, uint tig) +{ + // Test passing a reference to an element + just_one(vs[tig]); +} + +void d<let N : uint>(out Vertices<Vertex, N> vs, uint tig) +{ + // Test passing references to different elements (to check that the operand + // rewriting doesn't mess the order) + just_two(vs[tig], vs[0]); +} + +void e<let N : uint>(out Vertices<Vertex, N> vs, uint tig) +{ + // Test passing a scalar member and a struct member and a struct member's member + part_of_one(vs[tig].pos); + write_struct(vs[tig].ts); + part_of_one(vs[tig].ts.tex2); +} + +[outputtopology("triangle")] +[numthreads(3, 1, 1)] +void main( + in uint tig : SV_GroupIndex, + out Vertices<Vertex, MAX_VERTS> verts, + out Indices<uint3, MAX_PRIMS> triangles + ) +{ + const uint numVertices = 3; + const uint numPrimitives = 1; + SetMeshOutputCounts(numVertices, numPrimitives); + + if(tig < numVertices) { + a(verts); + b(verts); + c(verts, tig); + d(verts, tig); + e(verts, tig); + } + + if(tig < numPrimitives) { + triangles[tig] = uint3(0,1,2); + } +} + diff --git a/tests/pipeline/rasterization/mesh/passing-outputs.slang.glsl b/tests/pipeline/rasterization/mesh/passing-outputs.slang.glsl new file mode 100644 index 000000000..cfd7675ab --- /dev/null +++ b/tests/pipeline/rasterization/mesh/passing-outputs.slang.glsl @@ -0,0 +1,172 @@ +#version 450 +#extension GL_EXT_mesh_shader : require +layout(row_major) uniform; +layout(row_major) buffer; +struct Texes_0 +{ + vec2 tex1_0; + vec4 tex2_0; +}; + +struct Vertex_0 +{ + vec4 pos_0; + vec3 col_0; + Texes_0 ts_0; +}; + +void just_two_0(out Vertex_0 v_0, out Vertex_0 w_0) +{ + Texes_0 _S1 = { vec2(0.00000000000000000000, 0.00000000000000000000), vec4(0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000) }; + Vertex_0 _S2 = { vec4(0), vec3(1), _S1 }; + v_0 = _S2; + w_0 = v_0; + return; +} + +void just_one_0(out Vertex_0 v_1) +{ + Texes_0 _S3 = { vec2(0.00000000000000000000, 0.00000000000000000000), vec4(0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000) }; + Vertex_0 _S4 = { vec4(0), vec3(1), _S3 }; + v_1 = _S4; + return; +} + +void part_of_one_0(out vec4 p_0) +{ + p_0 = vec4(1.00000000000000000000, 2.00000000000000000000, 3.00000000000000000000, 4.00000000000000000000); + return; +} + +void write_struct_0(out Texes_0 t_0) +{ + t_0.tex1_0 = vec2(0); + t_0.tex2_0 = vec4(1); + return; +} + +layout(location = 0) +out vec3 _S5[3]; + +layout(location = 1) +out vec2 _S6[3]; + +layout(location = 2) +out vec4 _S7[3]; + +out gl_MeshPerVertexEXT +{ + vec4 gl_Position; +} gl_MeshVerticesEXT[3]; + +void everything_0() +{ + Texes_0 _S8 = { vec2(0.00000000000000000000, 0.00000000000000000000), vec4(0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000) }; + Vertex_0 _S9 = { vec4(0), vec3(1), _S8 }; + gl_MeshVerticesEXT[0U].gl_Position = _S9.pos_0; + _S5[0U] = _S9.col_0; + Texes_0 _S10 = _S9.ts_0; + _S6[0U] = _S10.tex1_0; + _S7[0U] = _S10.tex2_0; + return; +} + +void a_0() +{ + everything_0(); + return; +} + +void b_0() +{ + Vertex_0 _S11; + Vertex_0 _S12; + just_two_0(_S12, _S11); + Vertex_0 _S13 = _S12; + gl_MeshVerticesEXT[0U].gl_Position = _S13.pos_0; + _S5[0U] = _S13.col_0; + Texes_0 _S14 = _S13.ts_0; + _S6[0U] = _S14.tex1_0; + _S7[0U] = _S14.tex2_0; + Vertex_0 _S15 = _S11; + gl_MeshVerticesEXT[0U].gl_Position = _S15.pos_0; + _S5[0U] = _S15.col_0; + Texes_0 _S16 = _S15.ts_0; + _S6[0U] = _S16.tex1_0; + _S7[0U] = _S16.tex2_0; + return; +} + +void c_0(uint _S17) +{ + Vertex_0 _S18; + just_one_0(_S18); + Vertex_0 _S19 = _S18; + gl_MeshVerticesEXT[_S17].gl_Position = _S19.pos_0; + _S5[_S17] = _S19.col_0; + Texes_0 _S20 = _S19.ts_0; + _S6[_S17] = _S20.tex1_0; + _S7[_S17] = _S20.tex2_0; + return; +} + +void d_0(uint _S21) +{ + Vertex_0 _S22; + Vertex_0 _S23; + just_two_0(_S23, _S22); + Vertex_0 _S24 = _S23; + gl_MeshVerticesEXT[_S21].gl_Position = _S24.pos_0; + _S5[_S21] = _S24.col_0; + Texes_0 _S25 = _S24.ts_0; + _S6[_S21] = _S25.tex1_0; + _S7[_S21] = _S25.tex2_0; + Vertex_0 _S26 = _S22; + gl_MeshVerticesEXT[0U].gl_Position = _S26.pos_0; + _S5[0U] = _S26.col_0; + Texes_0 _S27 = _S26.ts_0; + _S6[0U] = _S27.tex1_0; + _S7[0U] = _S27.tex2_0; + return; +} + +void e_0(uint _S28) +{ + part_of_one_0(gl_MeshVerticesEXT[_S28].gl_Position); + Texes_0 _S29; + write_struct_0(_S29); + Texes_0 _S30 = _S29; + _S6[_S28] = _S30.tex1_0; + _S7[_S28] = _S30.tex2_0; + part_of_one_0(_S7[_S28]); + return; +} + +layout(local_size_x = 3, local_size_y = 1, local_size_z = 1) in; +layout(max_vertices = 3) out; +layout(max_primitives = 1) out; +layout(triangles) out; +void main() +{ + SetMeshOutputsEXT(3U, 1U); + if(gl_LocalInvocationIndex < 3U) + { + a_0(); + b_0(); + c_0(gl_LocalInvocationIndex); + d_0(gl_LocalInvocationIndex); + e_0(gl_LocalInvocationIndex); + } + else + { + } + if(gl_LocalInvocationIndex < 1U) + { + gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0U, 1U, 2U); + } + else + { + } + return; +} + diff --git a/tests/pipeline/rasterization/mesh/primitive-output.slang b/tests/pipeline/rasterization/mesh/primitive-output.slang new file mode 100644 index 000000000..fdbcf6912 --- /dev/null +++ b/tests/pipeline/rasterization/mesh/primitive-output.slang @@ -0,0 +1,57 @@ +// hello.slang + +// Test that a simple mesh shader compiles + +//TEST:CROSS_COMPILE:-target spirv -profile glsl_450+spirv_1_4 -entry main -stage mesh + +const static float2 positions[3] = { + float2(0.0, -0.5), + float2(0.5, 0.5), + float2(-0.5, 0.5) +}; + +const static float3 colors[3] = { + float3(1.0, 1.0, 0.0), + float3(0.0, 1.0, 1.0), + float3(1.0, 0.0, 1.0) +}; + +struct Vertex +{ + float4 pos : SV_Position; + float3 color : Color; +}; + +struct Prim +{ + float3 triangleNormal : Normal; + uint id : SV_PrimitiveID; + bool cull : SV_CullPrimitive; +}; + +const static uint MAX_VERTS = 3; +const static uint MAX_PRIMS = 1; + +[outputtopology("triangle")] +[numthreads(3, 1, 1)] +void main( + in uint tig : SV_GroupIndex, + out Indices<uint3, MAX_PRIMS> triangles, + out Vertices<Vertex, MAX_VERTS> verts, + out Primitives<Prim, MAX_PRIMS> primitives + ) +{ + const uint numVertices = 3; + const uint numPrimitives = 1; + SetMeshOutputCounts(numVertices, numPrimitives); + + if(tig < numVertices) { + verts[tig] = {float4(positions[tig], 0, 1), colors[tig]}; + } + + if(tig < numPrimitives) { + triangles[tig] = uint3(0,1,2); + primitives[tig] = {float3(0,0,1), tig, false}; + } +} + diff --git a/tests/pipeline/rasterization/mesh/primitive-output.slang.glsl b/tests/pipeline/rasterization/mesh/primitive-output.slang.glsl new file mode 100644 index 000000000..b7b4f1d62 --- /dev/null +++ b/tests/pipeline/rasterization/mesh/primitive-output.slang.glsl @@ -0,0 +1,66 @@ +#version 450 +#extension GL_EXT_mesh_shader : require +layout(row_major) uniform; +layout(row_major) buffer; +const vec3 colors_0[3] = { vec3(1.00000000000000000000, 1.00000000000000000000, 0.00000000000000000000), vec3(0.00000000000000000000, 1.00000000000000000000, 1.00000000000000000000), vec3(1.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000) }; +const vec2 positions_0[3] = { vec2(0.00000000000000000000, -0.50000000000000000000), vec2(0.50000000000000000000, 0.50000000000000000000), vec2(-0.50000000000000000000, 0.50000000000000000000) }; +layout(location = 0) +out vec3 _S1[3]; + +out gl_MeshPerVertexEXT +{ + vec4 gl_Position; +} gl_MeshVerticesEXT[3]; + +perprimitiveEXT layout(location = 1) +out vec3 _S2[1]; + +perprimitiveEXT out gl_MeshPerPrimitiveEXT +{ + int gl_PrimitiveID; + bool gl_CullPrimitiveEXT; +} gl_MeshPrimitivesEXT[1]; + +struct Vertex_0 +{ + vec4 pos_0; + vec3 color_0; +}; + +struct Prim_0 +{ + vec3 triangleNormal_0; + uint id_0; + bool cull_0; +}; + +layout(local_size_x = 3, local_size_y = 1, local_size_z = 1) in; +layout(max_vertices = 3) out; +layout(max_primitives = 1) out; +layout(triangles) out; +void main() +{ + SetMeshOutputsEXT(3U, 1U); + if(gl_LocalInvocationIndex < 3U) + { + Vertex_0 _S3 = { vec4(positions_0[gl_LocalInvocationIndex], 0.00000000000000000000, 1.00000000000000000000), colors_0[gl_LocalInvocationIndex] }; + gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = _S3.pos_0; + _S1[gl_LocalInvocationIndex] = _S3.color_0; + } + else + { + } + if(gl_LocalInvocationIndex < 1U) + { + gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0U, 1U, 2U); + Prim_0 _S4 = { vec3(0.00000000000000000000, 0.00000000000000000000, 1.00000000000000000000), gl_LocalInvocationIndex, false }; + _S2[gl_LocalInvocationIndex] = _S4.triangleNormal_0; + gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveID = int(_S4.id_0); + gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_CullPrimitiveEXT = _S4.cull_0; + } + else + { + } + return; +} + diff --git a/tests/pipeline/rasterization/mesh/swizzled-store.slang b/tests/pipeline/rasterization/mesh/swizzled-store.slang new file mode 100644 index 000000000..f85f9ed62 --- /dev/null +++ b/tests/pipeline/rasterization/mesh/swizzled-store.slang @@ -0,0 +1,32 @@ +// component-write.slang + +// This tests that writing to individual components of the output struct works + +//TEST:CROSS_COMPILE:-target spirv -profile glsl_450+spirv_1_4 -entry main -stage mesh + +const static uint MAX_VERTS = 3; +const static uint MAX_PRIMS = 1; + +[outputtopology("triangle")] +[numthreads(3, 1, 1)] +void main( + in uint tig : SV_GroupIndex, + out Vertices<float4, MAX_VERTS> verts : SV_Position, + out Indices<uint3, MAX_PRIMS> triangles + ) +{ + const uint numVertices = 3; + const uint numPrimitives = 1; + SetMeshOutputCounts(numVertices, numPrimitives); + + if(tig < numVertices) { + verts[tig].wz = float2(1, 0); + verts[tig].x = 0; + verts[tig].y = 0; + } + + if(tig < numPrimitives) { + triangles[tig] = uint3(0,1,2); + } +} + diff --git a/tests/pipeline/rasterization/mesh/swizzled-store.slang.glsl b/tests/pipeline/rasterization/mesh/swizzled-store.slang.glsl new file mode 100644 index 000000000..b2467901e --- /dev/null +++ b/tests/pipeline/rasterization/mesh/swizzled-store.slang.glsl @@ -0,0 +1,35 @@ +#version 450 +#extension GL_EXT_mesh_shader : require +layout(row_major) uniform; +layout(row_major) buffer; +out gl_MeshPerVertexEXT +{ + vec4 gl_Position; +} gl_MeshVerticesEXT[3]; + +layout(local_size_x = 3, local_size_y = 1, local_size_z = 1) in; +layout(max_vertices = 3) out; +layout(max_primitives = 1) out; +layout(triangles) out; +void main() +{ + SetMeshOutputsEXT(3U, 1U); + if(gl_LocalInvocationIndex < 3U) + { + gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.wz = vec2(1.00000000000000000000, 0.00000000000000000000); + gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = 0.00000000000000000000; + gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = 0.00000000000000000000; + } + else + { + } + if(gl_LocalInvocationIndex < 1U) + { + gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0U, 1U, 2U); + } + else + { + } + return; +} + |
