-
Notifications
You must be signed in to change notification settings - Fork 178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Metal Task Shader payload #4238
Changes from 3 commits
539b91c
728dbf3
7dacd93
451b295
12ff1bd
552dbb5
c9ae64a
7c56921
06d240f
3e2c6af
2aac740
d3f05a6
4b8ceed
b52440e
f2c3a4b
e7a9fd6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
//TEST:SIMPLE(filecheck=CHECK): -target metal | ||
//TEST:SIMPLE(filecheck=CHECK-ASM): -target metallib | ||
//TEST:REFLECTION(filecheck=REFLECT):-target metal -entry main_kernel -stage task | ||
|
||
// TEST_INPUT: ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer | ||
|
||
uniform RWStructuredBuffer<float> outputBuffer; | ||
|
||
cbuffer Uniforms | ||
{ | ||
float4x4 modelViewProjection; | ||
} | ||
|
||
// CHECK-ASM: define void @taskMain | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no //CHECK: lines in the file, so test in line 1 will fail There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not entirely sure what those check comments do, copied them from the rasterization test file. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They are regular expressions used to match the result of the generated source file or buffer content. A //CHECK line will try to match a line in the output with the regex following |
||
|
||
// | ||
// Task shader | ||
// | ||
|
||
struct MeshPayload | ||
{ | ||
int exponent; | ||
}; | ||
|
||
[numthreads(1,1,1)] | ||
void taskMain() | ||
{ | ||
MeshPayload p; | ||
p.exponent = 3; | ||
DispatchMesh(1, 1, 1, p); | ||
} | ||
|
||
// | ||
// Mesh shader | ||
// | ||
|
||
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; | ||
int index : Index; | ||
int value : Value; | ||
}; | ||
|
||
const static uint MAX_VERTS = 12; | ||
const static uint MAX_PRIMS = 4; | ||
|
||
[outputtopology("triangle")] | ||
[numthreads(12, 1, 1)] | ||
void meshMain( | ||
in uint tig: SV_GroupIndex, | ||
in payload MeshPayload meshPayload, | ||
// Check that we correctly generate the specific 'in payload' that HLSL | ||
// requires: | ||
// HLSL: , in payload MeshPayload | ||
OutputVertices<Vertex, MAX_VERTS> verts, | ||
OutputIndices<uint3, MAX_PRIMS> triangles) | ||
{ | ||
const uint numVertices = 12; | ||
const uint numPrimitives = 4; | ||
SetMeshOutputCounts(numVertices, numPrimitives); | ||
|
||
if (tig < numVertices) | ||
{ | ||
const int tri = tig / 3; | ||
verts[tig] = { float4(positions[tig % 3], 0, 1), colors[tig % 3], tri, int(pow(tri, meshPayload.exponent)) }; | ||
} | ||
|
||
if (tig < numPrimitives) | ||
triangles[tig] = tig * 3 + uint3(0, 1, 2); | ||
} | ||
|
||
// | ||
// Fragment Shader | ||
// | ||
|
||
struct Fragment | ||
{ | ||
float4 color : SV_Target; | ||
}; | ||
|
||
Fragment fragmentMain(Vertex input) | ||
{ | ||
outputBuffer[input.index] = input.value; | ||
|
||
Fragment output; | ||
output.color = float4(input.color, 1.0); | ||
return output; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there are more than one DispatchMesh call, this will insert duplicate parameters into the entry point. We should probably make sure we insert at most once for the referencing entry point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also there could be more than one entry points in a single module. I feel like instead of inserting into the entry point, we should try to find the parent function of the call site, assert that it is a object shader entry point, and insert a param into the EntryPoint if it is t already there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auto parentFunc = getParentFunc(call)
should give you the user func, you can thenbuilder.setInsertInto(parentFunc->getFirstBlock()->getFirstOrdinaryInst())
for the param.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we still assume that the DispatchMesh call is done directly from inside the entry point, but we make sure that the payload parameter is only generated once per entrypoint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, let's do that for now. we can add a diagnostic if oarent func isnt an entrypoint.