summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/ir
diff options
context:
space:
mode:
authorGravatar ameerj2021-03-25 11:31:37 -0400
committerGravatar ameerj2021-07-22 21:51:24 -0400
commit32c5483beb2f79f5d55eb2906f2bfdfa1698bca3 (patch)
treebca00dad85f6823746aee66f43dc0cbe2f337481 /src/shader_recompiler/frontend/ir
parentshader: Track first bindless argument instead of the instruction itself (diff)
downloadyuzu-32c5483beb2f79f5d55eb2906f2bfdfa1698bca3.tar.gz
yuzu-32c5483beb2f79f5d55eb2906f2bfdfa1698bca3.tar.xz
yuzu-32c5483beb2f79f5d55eb2906f2bfdfa1698bca3.zip
shader: Implement SHFL
Diffstat (limited to 'src/shader_recompiler/frontend/ir')
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp23
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h12
-rw-r--r--src/shader_recompiler/frontend/ir/microinstruction.cpp12
-rw-r--r--src/shader_recompiler/frontend/ir/microinstruction.h1
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc7
5 files changed, 53 insertions, 2 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index 6280c08f6..418b7f5ac 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -374,6 +374,10 @@ U1 IREmitter::GetSparseFromOp(const Value& op) {
374 return Inst<U1>(Opcode::GetSparseFromOp, op); 374 return Inst<U1>(Opcode::GetSparseFromOp, op);
375} 375}
376 376
377U1 IREmitter::GetInBoundsFromOp(const Value& op) {
378 return Inst<U1>(Opcode::GetInBoundsFromOp, op);
379}
380
377F16F32F64 IREmitter::FPAdd(const F16F32F64& a, const F16F32F64& b, FpControl control) { 381F16F32F64 IREmitter::FPAdd(const F16F32F64& a, const F16F32F64& b, FpControl control) {
378 if (a.Type() != b.Type()) { 382 if (a.Type() != b.Type()) {
379 throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); 383 throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type());
@@ -1486,4 +1490,23 @@ U32 IREmitter::SubgroupBallot(const U1& value) {
1486 return Inst<U32>(Opcode::SubgroupBallot, value); 1490 return Inst<U32>(Opcode::SubgroupBallot, value);
1487} 1491}
1488 1492
1493U32 IREmitter::ShuffleIndex(const IR::U32& value, const IR::U32& index, const IR::U32& clamp,
1494 const IR::U32& seg_mask) {
1495 return Inst<U32>(Opcode::ShuffleIndex, value, index, clamp, seg_mask);
1496}
1497
1498U32 IREmitter::ShuffleUp(const IR::U32& value, const IR::U32& index, const IR::U32& clamp,
1499 const IR::U32& seg_mask) {
1500 return Inst<U32>(Opcode::ShuffleUp, value, index, clamp, seg_mask);
1501}
1502
1503U32 IREmitter::ShuffleDown(const IR::U32& value, const IR::U32& index, const IR::U32& clamp,
1504 const IR::U32& seg_mask) {
1505 return Inst<U32>(Opcode::ShuffleDown, value, index, clamp, seg_mask);
1506}
1507
1508U32 IREmitter::ShuffleButterfly(const IR::U32& value, const IR::U32& index, const IR::U32& clamp,
1509 const IR::U32& seg_mask) {
1510 return Inst<U32>(Opcode::ShuffleButterfly, value, index, clamp, seg_mask);
1511}
1489} // namespace Shader::IR 1512} // namespace Shader::IR
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index ebbda78a9..64738735e 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -104,6 +104,7 @@ public:
104 [[nodiscard]] U1 GetCarryFromOp(const Value& op); 104 [[nodiscard]] U1 GetCarryFromOp(const Value& op);
105 [[nodiscard]] U1 GetOverflowFromOp(const Value& op); 105 [[nodiscard]] U1 GetOverflowFromOp(const Value& op);
106 [[nodiscard]] U1 GetSparseFromOp(const Value& op); 106 [[nodiscard]] U1 GetSparseFromOp(const Value& op);
107 [[nodiscard]] U1 GetInBoundsFromOp(const Value& op);
107 108
108 [[nodiscard]] Value CompositeConstruct(const Value& e1, const Value& e2); 109 [[nodiscard]] Value CompositeConstruct(const Value& e1, const Value& e2);
109 [[nodiscard]] Value CompositeConstruct(const Value& e1, const Value& e2, const Value& e3); 110 [[nodiscard]] Value CompositeConstruct(const Value& e1, const Value& e2, const Value& e3);
@@ -147,7 +148,8 @@ public:
147 [[nodiscard]] F32F64 FPRecipSqrt(const F32F64& value); 148 [[nodiscard]] F32F64 FPRecipSqrt(const F32F64& value);
148 [[nodiscard]] F32 FPSqrt(const F32& value); 149 [[nodiscard]] F32 FPSqrt(const F32& value);
149 [[nodiscard]] F16F32F64 FPSaturate(const F16F32F64& value); 150 [[nodiscard]] F16F32F64 FPSaturate(const F16F32F64& value);
150 [[nodiscard]] F16F32F64 FPClamp(const F16F32F64& value, const F16F32F64& min_value, const F16F32F64& max_value); 151 [[nodiscard]] F16F32F64 FPClamp(const F16F32F64& value, const F16F32F64& min_value,
152 const F16F32F64& max_value);
151 [[nodiscard]] F16F32F64 FPRoundEven(const F16F32F64& value, FpControl control = {}); 153 [[nodiscard]] F16F32F64 FPRoundEven(const F16F32F64& value, FpControl control = {});
152 [[nodiscard]] F16F32F64 FPFloor(const F16F32F64& value, FpControl control = {}); 154 [[nodiscard]] F16F32F64 FPFloor(const F16F32F64& value, FpControl control = {});
153 [[nodiscard]] F16F32F64 FPCeil(const F16F32F64& value, FpControl control = {}); 155 [[nodiscard]] F16F32F64 FPCeil(const F16F32F64& value, FpControl control = {});
@@ -242,6 +244,14 @@ public:
242 [[nodiscard]] U1 VoteAny(const U1& value); 244 [[nodiscard]] U1 VoteAny(const U1& value);
243 [[nodiscard]] U1 VoteEqual(const U1& value); 245 [[nodiscard]] U1 VoteEqual(const U1& value);
244 [[nodiscard]] U32 SubgroupBallot(const U1& value); 246 [[nodiscard]] U32 SubgroupBallot(const U1& value);
247 [[nodiscard]] U32 ShuffleIndex(const IR::U32& value, const IR::U32& index, const IR::U32& clamp,
248 const IR::U32& seg_mask);
249 [[nodiscard]] U32 ShuffleUp(const IR::U32& value, const IR::U32& index, const IR::U32& clamp,
250 const IR::U32& seg_mask);
251 [[nodiscard]] U32 ShuffleDown(const IR::U32& value, const IR::U32& index, const IR::U32& clamp,
252 const IR::U32& seg_mask);
253 [[nodiscard]] U32 ShuffleButterfly(const IR::U32& value, const IR::U32& index,
254 const IR::U32& clamp, const IR::U32& seg_mask);
245 255
246private: 256private:
247 IR::Block::iterator insertion_point; 257 IR::Block::iterator insertion_point;
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp
index ba3968056..be8eb4d4c 100644
--- a/src/shader_recompiler/frontend/ir/microinstruction.cpp
+++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp
@@ -89,6 +89,7 @@ bool Inst::IsPseudoInstruction() const noexcept {
89 case Opcode::GetCarryFromOp: 89 case Opcode::GetCarryFromOp:
90 case Opcode::GetOverflowFromOp: 90 case Opcode::GetOverflowFromOp:
91 case Opcode::GetSparseFromOp: 91 case Opcode::GetSparseFromOp:
92 case Opcode::GetInBoundsFromOp:
92 return true; 93 return true;
93 default: 94 default:
94 return false; 95 return false;
@@ -123,6 +124,9 @@ Inst* Inst::GetAssociatedPseudoOperation(IR::Opcode opcode) {
123 case Opcode::GetSparseFromOp: 124 case Opcode::GetSparseFromOp:
124 CheckPseudoInstruction(associated_insts->sparse_inst, Opcode::GetSparseFromOp); 125 CheckPseudoInstruction(associated_insts->sparse_inst, Opcode::GetSparseFromOp);
125 return associated_insts->sparse_inst; 126 return associated_insts->sparse_inst;
127 case Opcode::GetInBoundsFromOp:
128 CheckPseudoInstruction(associated_insts->in_bounds_inst, Opcode::GetInBoundsFromOp);
129 return associated_insts->in_bounds_inst;
126 default: 130 default:
127 throw InvalidArgument("{} is not a pseudo-instruction", opcode); 131 throw InvalidArgument("{} is not a pseudo-instruction", opcode);
128 } 132 }
@@ -262,6 +266,10 @@ void Inst::Use(const Value& value) {
262 AllocAssociatedInsts(assoc_inst); 266 AllocAssociatedInsts(assoc_inst);
263 SetPseudoInstruction(assoc_inst->sparse_inst, this); 267 SetPseudoInstruction(assoc_inst->sparse_inst, this);
264 break; 268 break;
269 case Opcode::GetInBoundsFromOp:
270 AllocAssociatedInsts(assoc_inst);
271 SetPseudoInstruction(assoc_inst->in_bounds_inst, this);
272 break;
265 default: 273 default:
266 break; 274 break;
267 } 275 }
@@ -289,6 +297,10 @@ void Inst::UndoUse(const Value& value) {
289 AllocAssociatedInsts(assoc_inst); 297 AllocAssociatedInsts(assoc_inst);
290 RemovePseudoInstruction(assoc_inst->overflow_inst, Opcode::GetOverflowFromOp); 298 RemovePseudoInstruction(assoc_inst->overflow_inst, Opcode::GetOverflowFromOp);
291 break; 299 break;
300 case Opcode::GetInBoundsFromOp:
301 AllocAssociatedInsts(assoc_inst);
302 RemovePseudoInstruction(assoc_inst->in_bounds_inst, Opcode::GetInBoundsFromOp);
303 break;
292 default: 304 default:
293 break; 305 break;
294 } 306 }
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.h b/src/shader_recompiler/frontend/ir/microinstruction.h
index d5336c438..770bbd550 100644
--- a/src/shader_recompiler/frontend/ir/microinstruction.h
+++ b/src/shader_recompiler/frontend/ir/microinstruction.h
@@ -134,6 +134,7 @@ static_assert(sizeof(Inst) <= 128, "Inst size unintentionally increased");
134 134
135struct AssociatedInsts { 135struct AssociatedInsts {
136 union { 136 union {
137 Inst* in_bounds_inst;
137 Inst* sparse_inst; 138 Inst* sparse_inst;
138 Inst* zero_inst{}; 139 Inst* zero_inst{};
139 }; 140 };
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index dd17212a1..a2479c46a 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -159,6 +159,7 @@ OPCODE(GetSignFromOp, U1, Opaq
159OPCODE(GetCarryFromOp, U1, Opaque, ) 159OPCODE(GetCarryFromOp, U1, Opaque, )
160OPCODE(GetOverflowFromOp, U1, Opaque, ) 160OPCODE(GetOverflowFromOp, U1, Opaque, )
161OPCODE(GetSparseFromOp, U1, Opaque, ) 161OPCODE(GetSparseFromOp, U1, Opaque, )
162OPCODE(GetInBoundsFromOp, U1, Opaque, )
162 163
163// Floating-point operations 164// Floating-point operations
164OPCODE(FPAbs16, F16, F16, ) 165OPCODE(FPAbs16, F16, F16, )
@@ -363,8 +364,12 @@ OPCODE(ImageSampleExplicitLod, F32x4, U32,
363OPCODE(ImageSampleDrefImplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) 364OPCODE(ImageSampleDrefImplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, )
364OPCODE(ImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) 365OPCODE(ImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, )
365 366
366// Vote operations 367// Warp operations
367OPCODE(VoteAll, U1, U1, ) 368OPCODE(VoteAll, U1, U1, )
368OPCODE(VoteAny, U1, U1, ) 369OPCODE(VoteAny, U1, U1, )
369OPCODE(VoteEqual, U1, U1, ) 370OPCODE(VoteEqual, U1, U1, )
370OPCODE(SubgroupBallot, U32, U1, ) 371OPCODE(SubgroupBallot, U32, U1, )
372OPCODE(ShuffleIndex, U32, U32, U32, U32, U32, )
373OPCODE(ShuffleUp, U32, U32, U32, U32, U32, )
374OPCODE(ShuffleDown, U32, U32, U32, U32, U32, )
375OPCODE(ShuffleButterfly, U32, U32, U32, U32, U32, )