summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-10 18:21:28 -0300
committerGravatar ameerj2021-07-22 21:51:31 -0400
commitc4fd6b55bc9acd06b2fc89f84fd175d78e14110a (patch)
treec246a1c64f4826faedcf5c93be778116e48caf85 /src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp
parentglasm: Add MUFU instructions to GLASM (diff)
downloadyuzu-c4fd6b55bc9acd06b2fc89f84fd175d78e14110a.tar.gz
yuzu-c4fd6b55bc9acd06b2fc89f84fd175d78e14110a.tar.xz
yuzu-c4fd6b55bc9acd06b2fc89f84fd175d78e14110a.zip
glasm: Implement shuffle and vote instructions on GLASM
Diffstat (limited to 'src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp
index e69de29bb..37eb577cd 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp
@@ -0,0 +1,118 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "shader_recompiler/backend/glasm/emit_context.h"
6#include "shader_recompiler/backend/glasm/emit_glasm_instructions.h"
7#include "shader_recompiler/frontend/ir/value.h"
8
9namespace Shader::Backend::GLASM {
10
11void EmitLaneId(EmitContext& ctx, IR::Inst& inst) {
12 ctx.Add("MOV.S {}.x,{}.threadid;", inst, ctx.stage_name);
13}
14
15void EmitVoteAll(EmitContext& ctx, IR::Inst& inst, ScalarS32 pred) {
16 ctx.Add("TGALL.S {}.x,{};", inst, pred);
17}
18
19void EmitVoteAny(EmitContext& ctx, IR::Inst& inst, ScalarS32 pred) {
20 ctx.Add("TGANY.S {}.x,{};", inst, pred);
21}
22
23void EmitVoteEqual(EmitContext& ctx, IR::Inst& inst, ScalarS32 pred) {
24 ctx.Add("TGEQ.S {}.x,{};", inst, pred);
25}
26
27void EmitSubgroupBallot(EmitContext& ctx, IR::Inst& inst, ScalarS32 pred) {
28 ctx.Add("TGBALLOT {}.x,{};", inst, pred);
29}
30
31void EmitSubgroupEqMask(EmitContext& ctx, IR::Inst& inst) {
32 ctx.Add("MOV.U {},{}.threadeqmask;", inst, ctx.stage_name);
33}
34
35void EmitSubgroupLtMask(EmitContext& ctx, IR::Inst& inst) {
36 ctx.Add("MOV.U {},{}.threadltmask;", inst, ctx.stage_name);
37}
38
39void EmitSubgroupLeMask(EmitContext& ctx, IR::Inst& inst) {
40 ctx.Add("MOV.U {},{}.threadlemask;", inst, ctx.stage_name);
41}
42
43void EmitSubgroupGtMask(EmitContext& ctx, IR::Inst& inst) {
44 ctx.Add("MOV.U {},{}.threadgtmask;", inst, ctx.stage_name);
45}
46
47void EmitSubgroupGeMask(EmitContext& ctx, IR::Inst& inst) {
48 ctx.Add("MOV.U {},{}.threadgemask;", inst, ctx.stage_name);
49}
50
51static void Shuffle(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 index,
52 const IR::Value& clamp, const IR::Value& segmentation_mask,
53 std::string_view op) {
54 std::string mask;
55 if (clamp.IsImmediate() && segmentation_mask.IsImmediate()) {
56 mask = fmt::to_string(clamp.U32() | (segmentation_mask.U32() << 8));
57 } else {
58 mask = "RC";
59 ctx.Add("BFI.U RC.x,{{5,8,0,0}},{},{};",
60 ScalarU32{ctx.reg_alloc.Consume(segmentation_mask)},
61 ScalarU32{ctx.reg_alloc.Consume(clamp)});
62 }
63 const Register value_ret{ctx.reg_alloc.Define(inst)};
64 IR::Inst* const in_bounds{inst.GetAssociatedPseudoOperation(IR::Opcode::GetInBoundsFromOp)};
65 if (in_bounds) {
66 const Register bounds_ret{ctx.reg_alloc.Define(*in_bounds)};
67 ctx.Add("SHF{}.U {},{},{},{};"
68 "MOV.U {}.x,{}.y;",
69 op, bounds_ret, value, index, mask, value_ret, bounds_ret);
70 in_bounds->Invalidate();
71 } else {
72 ctx.Add("SHF{}.U {},{},{},{};"
73 "MOV.U {}.x,{}.y;",
74 op, value_ret, value, index, mask, value_ret, value_ret);
75 }
76}
77
78void EmitShuffleIndex(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 index,
79 const IR::Value& clamp, const IR::Value& segmentation_mask) {
80 Shuffle(ctx, inst, value, index, clamp, segmentation_mask, "IDX");
81}
82
83void EmitShuffleUp(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 index,
84 const IR::Value& clamp, const IR::Value& segmentation_mask) {
85 Shuffle(ctx, inst, value, index, clamp, segmentation_mask, "UP");
86}
87
88void EmitShuffleDown(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 index,
89 const IR::Value& clamp, const IR::Value& segmentation_mask) {
90 Shuffle(ctx, inst, value, index, clamp, segmentation_mask, "DOWN");
91}
92
93void EmitShuffleButterfly(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 index,
94 const IR::Value& clamp, const IR::Value& segmentation_mask) {
95 Shuffle(ctx, inst, value, index, clamp, segmentation_mask, "XOR");
96}
97
98void EmitFSwizzleAdd(EmitContext&, ScalarF32, ScalarF32, ScalarU32) {
99 throw NotImplementedException("GLASM instruction");
100}
101
102void EmitDPdxFine(EmitContext&, ScalarF32) {
103 throw NotImplementedException("GLASM instruction");
104}
105
106void EmitDPdyFine(EmitContext&, ScalarF32) {
107 throw NotImplementedException("GLASM instruction");
108}
109
110void EmitDPdxCoarse(EmitContext&, ScalarF32) {
111 throw NotImplementedException("GLASM instruction");
112}
113
114void EmitDPdyCoarse(EmitContext&, ScalarF32) {
115 throw NotImplementedException("GLASM instruction");
116}
117
118} // namespace Shader::Backend::GLASM