diff options
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp | 62 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/impl.h | 2 |
2 files changed, 48 insertions, 16 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp index 3d0c48457..ae2d37405 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_integer.cpp | |||
| @@ -34,7 +34,7 @@ union F2I { | |||
| 34 | BitField<8, 2, DestFormat> dest_format; | 34 | BitField<8, 2, DestFormat> dest_format; |
| 35 | BitField<10, 2, SrcFormat> src_format; | 35 | BitField<10, 2, SrcFormat> src_format; |
| 36 | BitField<12, 1, u64> is_signed; | 36 | BitField<12, 1, u64> is_signed; |
| 37 | BitField<39, 1, Rounding> rounding; | 37 | BitField<39, 2, Rounding> rounding; |
| 38 | BitField<49, 1, u64> half; | 38 | BitField<49, 1, u64> half; |
| 39 | BitField<44, 1, u64> ftz; | 39 | BitField<44, 1, u64> ftz; |
| 40 | BitField<45, 1, u64> abs; | 40 | BitField<45, 1, u64> abs; |
| @@ -55,6 +55,28 @@ size_t BitSize(DestFormat dest_format) { | |||
| 55 | } | 55 | } |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | IR::F64 UnpackCbuf(TranslatorVisitor& v, u64 insn) { | ||
| 59 | union { | ||
| 60 | u64 raw; | ||
| 61 | BitField<20, 14, s64> offset; | ||
| 62 | BitField<34, 5, u64> binding; | ||
| 63 | } const cbuf{insn}; | ||
| 64 | if (cbuf.binding >= 18) { | ||
| 65 | throw NotImplementedException("Out of bounds constant buffer binding {}", cbuf.binding); | ||
| 66 | } | ||
| 67 | if (cbuf.offset >= 0x4'000 || cbuf.offset < 0) { | ||
| 68 | throw NotImplementedException("Out of bounds constant buffer offset {}", cbuf.offset * 4); | ||
| 69 | } | ||
| 70 | if (cbuf.offset % 2 != 0) { | ||
| 71 | throw NotImplementedException("Unaligned F64 constant buffer offset {}", cbuf.offset * 4); | ||
| 72 | } | ||
| 73 | const IR::U32 binding{v.ir.Imm32(static_cast<u32>(cbuf.binding))}; | ||
| 74 | const IR::U32 byte_offset{v.ir.Imm32(static_cast<u32>(cbuf.offset) * 4 + 4)}; | ||
| 75 | const IR::U32 cbuf_data{v.ir.GetCbuf(binding, byte_offset)}; | ||
| 76 | const IR::Value vector{v.ir.CompositeConstruct(v.ir.Imm32(0U), cbuf_data)}; | ||
| 77 | return v.ir.PackDouble2x32(vector); | ||
| 78 | } | ||
| 79 | |||
| 58 | void TranslateF2I(TranslatorVisitor& v, u64 insn, const IR::F16F32F64& src_a) { | 80 | void TranslateF2I(TranslatorVisitor& v, u64 insn, const IR::F16F32F64& src_a) { |
| 59 | // F2I is used to convert from a floating point value to an integer | 81 | // F2I is used to convert from a floating point value to an integer |
| 60 | const F2I f2i{insn}; | 82 | const F2I f2i{insn}; |
| @@ -82,19 +104,16 @@ void TranslateF2I(TranslatorVisitor& v, u64 insn, const IR::F16F32F64& src_a) { | |||
| 82 | const size_t bitsize{BitSize(f2i.dest_format)}; | 104 | const size_t bitsize{BitSize(f2i.dest_format)}; |
| 83 | const IR::U16U32U64 result{v.ir.ConvertFToI(bitsize, is_signed, rounded_value)}; | 105 | const IR::U16U32U64 result{v.ir.ConvertFToI(bitsize, is_signed, rounded_value)}; |
| 84 | 106 | ||
| 85 | v.X(f2i.dest_reg, result); | 107 | if (bitsize == 64) { |
| 108 | const IR::Value vector{v.ir.UnpackUint2x32(result)}; | ||
| 109 | v.X(f2i.dest_reg + 0, IR::U32{v.ir.CompositeExtract(vector, 0)}); | ||
| 110 | v.X(f2i.dest_reg + 1, IR::U32{v.ir.CompositeExtract(vector, 1)}); | ||
| 111 | } else { | ||
| 112 | v.X(f2i.dest_reg, result); | ||
| 113 | } | ||
| 86 | 114 | ||
| 87 | if (f2i.cc != 0) { | 115 | if (f2i.cc != 0) { |
| 88 | v.SetZFlag(v.ir.GetZeroFromOp(result)); | 116 | throw NotImplementedException("F2I CC"); |
| 89 | if (is_signed) { | ||
| 90 | v.SetSFlag(v.ir.GetSignFromOp(result)); | ||
| 91 | } else { | ||
| 92 | v.ResetSFlag(); | ||
| 93 | } | ||
| 94 | v.ResetCFlag(); | ||
| 95 | |||
| 96 | // TODO: Investigate if out of bound conversions sets the overflow flag | ||
| 97 | v.ResetOFlag(); | ||
| 98 | } | 117 | } |
| 99 | } | 118 | } |
| 100 | } // Anonymous namespace | 119 | } // Anonymous namespace |
| @@ -118,12 +137,25 @@ void TranslatorVisitor::F2I_reg(u64 insn) { | |||
| 118 | f2i.base.src_format.Value()); | 137 | f2i.base.src_format.Value()); |
| 119 | } | 138 | } |
| 120 | }()}; | 139 | }()}; |
| 121 | |||
| 122 | TranslateF2I(*this, insn, op_a); | 140 | TranslateF2I(*this, insn, op_a); |
| 123 | } | 141 | } |
| 124 | 142 | ||
| 125 | void TranslatorVisitor::F2I_cbuf(u64) { | 143 | void TranslatorVisitor::F2I_cbuf(u64 insn) { |
| 126 | throw NotImplementedException("{}", Opcode::F2I_cbuf); | 144 | const F2I f2i{insn}; |
| 145 | const IR::F16F32F64 op_a{[&]() -> IR::F16F32F64 { | ||
| 146 | switch (f2i.src_format) { | ||
| 147 | case SrcFormat::F16: | ||
| 148 | return IR::F16{ir.CompositeExtract(ir.UnpackFloat2x16(GetCbuf(insn)), f2i.half)}; | ||
| 149 | case SrcFormat::F32: | ||
| 150 | return GetCbufF(insn); | ||
| 151 | case SrcFormat::F64: { | ||
| 152 | return UnpackCbuf(*this, insn); | ||
| 153 | } | ||
| 154 | default: | ||
| 155 | throw NotImplementedException("Invalid F2I source format {}", f2i.src_format.Value()); | ||
| 156 | } | ||
| 157 | }()}; | ||
| 158 | TranslateF2I(*this, insn, op_a); | ||
| 127 | } | 159 | } |
| 128 | 160 | ||
| 129 | void TranslatorVisitor::F2I_imm(u64) { | 161 | void TranslatorVisitor::F2I_imm(u64) { |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h index 8bd468244..27aba2cf8 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h | |||
| @@ -11,7 +11,7 @@ namespace Shader::Maxwell { | |||
| 11 | 11 | ||
| 12 | class TranslatorVisitor { | 12 | class TranslatorVisitor { |
| 13 | public: | 13 | public: |
| 14 | explicit TranslatorVisitor(Environment& env_, IR::Block& block) : env{env_} ,ir(block) {} | 14 | explicit TranslatorVisitor(Environment& env_, IR::Block& block) : env{env_}, ir(block) {} |
| 15 | 15 | ||
| 16 | Environment& env; | 16 | Environment& env; |
| 17 | IR::IREmitter ir; | 17 | IR::IREmitter ir; |