Skip to content

Commit a5dfa5c

Browse files
author
Tim Foley
authored
IR: add support for discard statement (shader-slang#261)
- Add definition of `discard` instruction - A `discard` is a terminator instruction, just like `returnVoid` - Lower `DiscardStmt` in AST to a `discard` instruction in the IR - Emit `discard` instruction as a `discard;` statement when emitting HLSL/GLSL - Add a test case using the "graphics compute" mode that tests discard. The test writes to one entry in a UAV before doing a conditional (always true at runtime) discard, and then writes to another entry; we expect to see the results of the first write, but not the second.
1 parent 6e591ad commit a5dfa5c

File tree

7 files changed

+122
-0
lines changed

7 files changed

+122
-0
lines changed

source/slang/emit.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -5296,6 +5296,10 @@ emitDeclImpl(decl, nullptr);
52965296
emit(";\n");
52975297
break;
52985298

5299+
case kIROp_discard:
5300+
emit("discard;\n");
5301+
break;
5302+
52995303
case kIROp_swizzleSet:
53005304
{
53015305
auto ii = (IRSwizzleSet*)inst;
@@ -5425,6 +5429,7 @@ emitDeclImpl(decl, nullptr);
54255429

54265430
case kIROp_ReturnVal:
54275431
case kIROp_ReturnVoid:
5432+
case kIROp_discard:
54285433
emitIRInst(ctx, terminator);
54295434
return;
54305435

source/slang/ir-inst-defs.h

+2
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ INST(if, if, 3, 0)
181181
INST(ifElse, ifElse, 4, 0)
182182
INST(loopTest, loopTest, 3, 0)
183183

184+
INST(discard, discard, 0, 0)
185+
184186
INST(Add, add, 2, 0)
185187
INST(Sub, sub, 2, 0)
186188
INST(Mul, mul, 2, 0)

source/slang/ir-insts.h

+5
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ struct IRReturnVal : IRReturn
135135
struct IRReturnVoid : IRReturn
136136
{};
137137

138+
struct IRDiscard : IRTerminatorInst
139+
{};
140+
138141
struct IRBlock;
139142

140143
struct IRUnconditionalBranch : IRTerminatorInst
@@ -464,6 +467,8 @@ struct IRBuilder
464467

465468
IRInst* emitReturn();
466469

470+
IRInst* emitDiscard();
471+
467472
IRInst* emitBranch(
468473
IRBlock* block);
469474

source/slang/ir.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ namespace Slang
166166
case kIROp_if:
167167
case kIROp_ifElse:
168168
case kIROp_loopTest:
169+
case kIROp_discard:
169170
return true;
170171
}
171172
}
@@ -1150,6 +1151,17 @@ namespace Slang
11501151
return inst;
11511152
}
11521153

1154+
IRInst* IRBuilder::emitDiscard()
1155+
{
1156+
auto inst = createInst<IRDiscard>(
1157+
this,
1158+
kIROp_discard,
1159+
nullptr);
1160+
addInst(inst);
1161+
return inst;
1162+
}
1163+
1164+
11531165
IRInst* IRBuilder::emitBranch(
11541166
IRBlock* pBlock)
11551167
{

source/slang/lower-to-ir.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -1912,6 +1912,11 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>
19121912
getBuilder()->emitReturn();
19131913
}
19141914
}
1915+
1916+
void visitDiscardStmt(DiscardStmt* /*stmt*/)
1917+
{
1918+
getBuilder()->emitDiscard();
1919+
}
19151920
};
19161921

19171922
void lowerStmt(

tests/compute/discard-stmt.slang

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//TEST(compute):COMPARE_RENDER_COMPUTE:
2+
//TEST_INPUT: Texture2D(size=4, content = one) : dxbinding(0),glbinding(0)
3+
//TEST_INPUT: Sampler : dxbinding(0),glbinding(0)
4+
//TEST_INPUT: ubuffer(data=[0 0], stride=4):dxbinding(1),glbinding(0),out
5+
6+
7+
Texture2D tex;
8+
SamplerState samp;
9+
RWStructuredBuffer<float> outputBuffer;
10+
11+
cbuffer Uniforms
12+
{
13+
float4x4 modelViewProjection;
14+
}
15+
16+
struct AssembledVertex
17+
{
18+
float3 position;
19+
float3 color;
20+
float2 uv;
21+
};
22+
23+
struct CoarseVertex
24+
{
25+
float3 color;
26+
float2 uv;
27+
};
28+
29+
struct Fragment
30+
{
31+
float4 color;
32+
};
33+
34+
35+
// Vertex Shader
36+
37+
struct VertexStageInput
38+
{
39+
AssembledVertex assembledVertex : A;
40+
};
41+
42+
struct VertexStageOutput
43+
{
44+
CoarseVertex coarseVertex : CoarseVertex;
45+
float4 sv_position : SV_Position;
46+
};
47+
48+
VertexStageOutput vertexMain(VertexStageInput input)
49+
{
50+
VertexStageOutput output;
51+
52+
float3 position = input.assembledVertex.position;
53+
float3 color = input.assembledVertex.color;
54+
55+
output.coarseVertex.color = color;
56+
output.sv_position = mul(modelViewProjection, float4(position, 1.0));
57+
output.coarseVertex.uv = input.assembledVertex.uv;
58+
return output;
59+
}
60+
61+
// Fragment Shader
62+
63+
struct FragmentStageInput
64+
{
65+
CoarseVertex coarseVertex : CoarseVertex;
66+
};
67+
68+
struct FragmentStageOutput
69+
{
70+
Fragment fragment : SV_Target;
71+
};
72+
73+
FragmentStageOutput fragmentMain(FragmentStageInput input)
74+
{
75+
FragmentStageOutput output;
76+
77+
float3 color = input.coarseVertex.color;
78+
float2 uv = input.coarseVertex.uv;
79+
output.fragment.color = float4(color, 1.0);
80+
81+
float4 val = float4(color, 1.0);
82+
val = val - 16*tex.Sample(samp, uv);
83+
84+
outputBuffer[0] = 1;
85+
86+
if(val.x < 0)
87+
discard;
88+
89+
outputBuffer[1] = 1;
90+
return output;
91+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
3F800000
2+
0

0 commit comments

Comments
 (0)