summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/CMakeLists.txt1
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.cpp8
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.h2
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h1
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp16
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp3
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h2
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc1
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_swizzled_add.cpp44
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.h1
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp4
-rw-r--r--src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp3
-rw-r--r--src/shader_recompiler/shader_info.h1
14 files changed, 87 insertions, 4 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt
index 44ab929b7..5ce420cbf 100644
--- a/src/shader_recompiler/CMakeLists.txt
+++ b/src/shader_recompiler/CMakeLists.txt
@@ -89,6 +89,7 @@ add_library(shader_recompiler STATIC
89 frontend/maxwell/translate/impl/floating_point_multiply.cpp 89 frontend/maxwell/translate/impl/floating_point_multiply.cpp
90 frontend/maxwell/translate/impl/floating_point_range_reduction.cpp 90 frontend/maxwell/translate/impl/floating_point_range_reduction.cpp
91 frontend/maxwell/translate/impl/floating_point_set_predicate.cpp 91 frontend/maxwell/translate/impl/floating_point_set_predicate.cpp
92 frontend/maxwell/translate/impl/floating_point_swizzled_add.cpp
92 frontend/maxwell/translate/impl/half_floating_point_add.cpp 93 frontend/maxwell/translate/impl/half_floating_point_add.cpp
93 frontend/maxwell/translate/impl/half_floating_point_fused_multiply_add.cpp 94 frontend/maxwell/translate/impl/half_floating_point_fused_multiply_add.cpp
94 frontend/maxwell/translate/impl/half_floating_point_helper.cpp 95 frontend/maxwell/translate/impl/half_floating_point_helper.cpp
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp
index 96d0e9b4d..7531f8b21 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_context.cpp
@@ -393,6 +393,14 @@ void EmitContext::DefineInputs(const Info& info) {
393 subgroup_local_invocation_id = 393 subgroup_local_invocation_id =
394 DefineInput(*this, U32[1], spv::BuiltIn::SubgroupLocalInvocationId); 394 DefineInput(*this, U32[1], spv::BuiltIn::SubgroupLocalInvocationId);
395 } 395 }
396 if (info.uses_fswzadd) {
397 const Id f32_one{Constant(F32[1], 1.0f)};
398 const Id f32_minus_one{Constant(F32[1], -1.0f)};
399 const Id f32_zero{Constant(F32[1], 0.0f)};
400 fswzadd_lut_a = ConstantComposite(F32[4], f32_minus_one, f32_one, f32_minus_one, f32_zero);
401 fswzadd_lut_b =
402 ConstantComposite(F32[4], f32_minus_one, f32_minus_one, f32_one, f32_minus_one);
403 }
396 if (info.loads_position) { 404 if (info.loads_position) {
397 const bool is_fragment{stage != Stage::Fragment}; 405 const bool is_fragment{stage != Stage::Fragment};
398 const spv::BuiltIn built_in{is_fragment ? spv::BuiltIn::Position : spv::BuiltIn::FragCoord}; 406 const spv::BuiltIn built_in{is_fragment ? spv::BuiltIn::Position : spv::BuiltIn::FragCoord};
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h
index 1a4e8221a..ffac39c4f 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.h
+++ b/src/shader_recompiler/backend/spirv/emit_context.h
@@ -103,6 +103,8 @@ public:
103 Id vertex_index{}; 103 Id vertex_index{};
104 Id base_vertex{}; 104 Id base_vertex{};
105 Id front_face{}; 105 Id front_face{};
106 Id fswzadd_lut_a{};
107 Id fswzadd_lut_b{};
106 108
107 Id local_memory{}; 109 Id local_memory{};
108 110
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index 02648d769..3d0c6f7ba 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -397,5 +397,6 @@ Id EmitShuffleDown(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clam
397 Id segmentation_mask); 397 Id segmentation_mask);
398Id EmitShuffleButterfly(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp, 398Id EmitShuffleButterfly(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp,
399 Id segmentation_mask); 399 Id segmentation_mask);
400Id EmitFSwizzleAdd(EmitContext& ctx, Id op_a, Id op_b, Id swizzle);
400 401
401} // namespace Shader::Backend::SPIRV 402} // namespace Shader::Backend::SPIRV
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
index 44d8a347f..cbc5b1c96 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
@@ -132,4 +132,20 @@ Id EmitShuffleButterfly(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id
132 return SelectValue(ctx, in_range, value, src_thread_id); 132 return SelectValue(ctx, in_range, value, src_thread_id);
133} 133}
134 134
135Id EmitFSwizzleAdd(EmitContext& ctx, Id op_a, Id op_b, Id swizzle) {
136 const Id three{ctx.Constant(ctx.U32[1], 3)};
137 Id mask{ctx.OpLoad(ctx.U32[1], ctx.subgroup_local_invocation_id)};
138 mask = ctx.OpBitwiseAnd(ctx.U32[1], mask, three);
139 mask = ctx.OpShiftLeftLogical(ctx.U32[1], mask, ctx.Constant(ctx.U32[1], 1));
140 mask = ctx.OpShiftRightLogical(ctx.U32[1], swizzle, mask);
141 mask = ctx.OpBitwiseAnd(ctx.U32[1], mask, three);
142
143 const Id modifier_a{ctx.OpVectorExtractDynamic(ctx.F32[1], ctx.fswzadd_lut_a, mask)};
144 const Id modifier_b{ctx.OpVectorExtractDynamic(ctx.F32[1], ctx.fswzadd_lut_b, mask)};
145
146 const Id result_a{ctx.OpFMul(ctx.F32[1], op_a, modifier_a)};
147 const Id result_b{ctx.OpFMul(ctx.F32[1], op_b, modifier_b)};
148 return ctx.OpFAdd(ctx.F32[1], result_a, result_b);
149}
150
135} // namespace Shader::Backend::SPIRV 151} // namespace Shader::Backend::SPIRV
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index 552472487..505fba46a 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -1602,4 +1602,7 @@ U32 IREmitter::ShuffleButterfly(const IR::U32& value, const IR::U32& index, cons
1602 const IR::U32& seg_mask) { 1602 const IR::U32& seg_mask) {
1603 return Inst<U32>(Opcode::ShuffleButterfly, value, index, clamp, seg_mask); 1603 return Inst<U32>(Opcode::ShuffleButterfly, value, index, clamp, seg_mask);
1604} 1604}
1605F32 IREmitter::FSwizzleAdd(const F32& a, const F32& b, const U32& swizzle, FpControl control) {
1606 return Inst<F32>(Opcode::FSwizzleAdd, Flags{control}, a, b, swizzle);
1607}
1605} // namespace Shader::IR 1608} // namespace Shader::IR
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index 17bc32fc8..8f3325738 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -277,6 +277,8 @@ public:
277 const IR::U32& seg_mask); 277 const IR::U32& seg_mask);
278 [[nodiscard]] U32 ShuffleButterfly(const IR::U32& value, const IR::U32& index, 278 [[nodiscard]] U32 ShuffleButterfly(const IR::U32& value, const IR::U32& index,
279 const IR::U32& clamp, const IR::U32& seg_mask); 279 const IR::U32& clamp, const IR::U32& seg_mask);
280 [[nodiscard]] F32 FSwizzleAdd(const F32& a, const F32& b, const U32& swizzle,
281 FpControl control = {});
280 282
281private: 283private:
282 IR::Block::iterator insertion_point; 284 IR::Block::iterator insertion_point;
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index fb79e3d8d..717aa71ca 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -408,3 +408,4 @@ OPCODE(ShuffleIndex, U32, U32,
408OPCODE(ShuffleUp, U32, U32, U32, U32, U32, ) 408OPCODE(ShuffleUp, U32, U32, U32, U32, U32, )
409OPCODE(ShuffleDown, U32, U32, U32, U32, U32, ) 409OPCODE(ShuffleDown, U32, U32, U32, U32, U32, )
410OPCODE(ShuffleButterfly, U32, U32, U32, U32, U32, ) 410OPCODE(ShuffleButterfly, U32, U32, U32, U32, U32, )
411OPCODE(FSwizzleAdd, F32, F32, F32, U32, )
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_swizzled_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_swizzled_add.cpp
new file mode 100644
index 000000000..e42921a21
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_swizzled_add.cpp
@@ -0,0 +1,44 @@
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 "common/common_types.h"
6#include "shader_recompiler/exception.h"
7#include "shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h"
8#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
9
10namespace Shader::Maxwell {
11void TranslatorVisitor::FSWZADD(u64 insn) {
12 union {
13 u64 raw;
14 BitField<0, 8, IR::Reg> dest_reg;
15 BitField<28, 8, u64> swizzle;
16 BitField<38, 1, u64> ndv;
17 BitField<39, 2, FpRounding> round;
18 BitField<44, 1, u64> ftz;
19 BitField<47, 1, u64> cc;
20 } const fswzadd{insn};
21
22 if (fswzadd.ndv != 0) {
23 throw NotImplementedException("FSWZADD NDV");
24 }
25
26 const IR::F32 src_a{GetFloatReg8(insn)};
27 const IR::F32 src_b{GetFloatReg20(insn)};
28 const IR::U32 swizzle{ir.Imm32(static_cast<u32>(fswzadd.swizzle))};
29
30 const IR::FpControl fp_control{
31 .no_contraction{false},
32 .rounding{CastFpRounding(fswzadd.round)},
33 .fmz_mode{fswzadd.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None},
34 };
35
36 const IR::F32 result{ir.FSwizzleAdd(src_a, src_b, swizzle, fp_control)};
37 F(fswzadd.dest_reg, result);
38
39 if (fswzadd.cc != 0) {
40 throw NotImplementedException("FSWZADD CC");
41 }
42}
43
44} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
index 9bae89c10..30b570ce4 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
@@ -91,6 +91,10 @@ IR::U32 TranslatorVisitor::GetReg39(u64 insn) {
91 return X(reg.index); 91 return X(reg.index);
92} 92}
93 93
94IR::F32 TranslatorVisitor::GetFloatReg8(u64 insn) {
95 return ir.BitCast<IR::F32>(GetReg8(insn));
96}
97
94IR::F32 TranslatorVisitor::GetFloatReg20(u64 insn) { 98IR::F32 TranslatorVisitor::GetFloatReg20(u64 insn) {
95 return ir.BitCast<IR::F32>(GetReg20(insn)); 99 return ir.BitCast<IR::F32>(GetReg20(insn));
96} 100}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
index 54c31deb4..bf7d1bae8 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
@@ -353,6 +353,7 @@ public:
353 [[nodiscard]] IR::U32 GetReg8(u64 insn); 353 [[nodiscard]] IR::U32 GetReg8(u64 insn);
354 [[nodiscard]] IR::U32 GetReg20(u64 insn); 354 [[nodiscard]] IR::U32 GetReg20(u64 insn);
355 [[nodiscard]] IR::U32 GetReg39(u64 insn); 355 [[nodiscard]] IR::U32 GetReg39(u64 insn);
356 [[nodiscard]] IR::F32 GetFloatReg8(u64 insn);
356 [[nodiscard]] IR::F32 GetFloatReg20(u64 insn); 357 [[nodiscard]] IR::F32 GetFloatReg20(u64 insn);
357 [[nodiscard]] IR::F32 GetFloatReg39(u64 insn); 358 [[nodiscard]] IR::F32 GetFloatReg39(u64 insn);
358 [[nodiscard]] IR::F64 GetDoubleReg20(u64 insn); 359 [[nodiscard]] IR::F64 GetDoubleReg20(u64 insn);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
index a0057a473..6a580f831 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -89,10 +89,6 @@ void TranslatorVisitor::FCHK_imm(u64) {
89 ThrowNotImplemented(Opcode::FCHK_imm); 89 ThrowNotImplemented(Opcode::FCHK_imm);
90} 90}
91 91
92void TranslatorVisitor::FSWZADD(u64) {
93 ThrowNotImplemented(Opcode::FSWZADD);
94}
95
96void TranslatorVisitor::GETCRSPTR(u64) { 92void TranslatorVisitor::GETCRSPTR(u64) {
97 ThrowNotImplemented(Opcode::GETCRSPTR); 93 ThrowNotImplemented(Opcode::GETCRSPTR);
98} 94}
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
index c932c307b..81090335f 100644
--- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
+++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
@@ -389,6 +389,9 @@ void VisitUsages(Info& info, IR::Inst& inst) {
389 case IR::Opcode::SubgroupBallot: 389 case IR::Opcode::SubgroupBallot:
390 info.uses_subgroup_vote = true; 390 info.uses_subgroup_vote = true;
391 break; 391 break;
392 case IR::Opcode::FSwizzleAdd:
393 info.uses_fswzadd = true;
394 break;
392 default: 395 default:
393 break; 396 break;
394 } 397 }
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h
index 9111159f3..4b4006b7f 100644
--- a/src/shader_recompiler/shader_info.h
+++ b/src/shader_recompiler/shader_info.h
@@ -94,6 +94,7 @@ struct Info {
94 bool uses_sparse_residency{}; 94 bool uses_sparse_residency{};
95 bool uses_demote_to_helper_invocation{}; 95 bool uses_demote_to_helper_invocation{};
96 bool uses_subgroup_vote{}; 96 bool uses_subgroup_vote{};
97 bool uses_fswzadd{};
97 98
98 IR::Type used_constant_buffer_types{}; 99 IR::Type used_constant_buffer_types{};
99 100