diff options
Diffstat (limited to 'src/shader_recompiler/backend')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv.h | 6 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp | 56 |
2 files changed, 41 insertions, 21 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index af6b8a68f..204c5f9e0 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -276,7 +276,7 @@ Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b); | |||
| 276 | Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b); | 276 | Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b); |
| 277 | Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b); | 277 | Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b); |
| 278 | Id EmitBitFieldInsert(EmitContext& ctx, Id base, Id insert, Id offset, Id count); | 278 | Id EmitBitFieldInsert(EmitContext& ctx, Id base, Id insert, Id offset, Id count); |
| 279 | Id EmitBitFieldSExtract(EmitContext& ctx, Id base, Id offset, Id count); | 279 | Id EmitBitFieldSExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count); |
| 280 | Id EmitBitFieldUExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count); | 280 | Id EmitBitFieldUExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count); |
| 281 | Id EmitBitReverse32(EmitContext& ctx, Id value); | 281 | Id EmitBitReverse32(EmitContext& ctx, Id value); |
| 282 | Id EmitBitCount32(EmitContext& ctx, Id value); | 282 | Id EmitBitCount32(EmitContext& ctx, Id value); |
| @@ -287,8 +287,8 @@ Id EmitSMin32(EmitContext& ctx, Id a, Id b); | |||
| 287 | Id EmitUMin32(EmitContext& ctx, Id a, Id b); | 287 | Id EmitUMin32(EmitContext& ctx, Id a, Id b); |
| 288 | Id EmitSMax32(EmitContext& ctx, Id a, Id b); | 288 | Id EmitSMax32(EmitContext& ctx, Id a, Id b); |
| 289 | Id EmitUMax32(EmitContext& ctx, Id a, Id b); | 289 | Id EmitUMax32(EmitContext& ctx, Id a, Id b); |
| 290 | Id EmitSClamp32(EmitContext& ctx, Id value, Id min, Id max); | 290 | Id EmitSClamp32(EmitContext& ctx, IR::Inst* inst, Id value, Id min, Id max); |
| 291 | Id EmitUClamp32(EmitContext& ctx, Id value, Id min, Id max); | 291 | Id EmitUClamp32(EmitContext& ctx, IR::Inst* inst, Id value, Id min, Id max); |
| 292 | Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs); | 292 | Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs); |
| 293 | Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs); | 293 | Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs); |
| 294 | Id EmitIEqual(EmitContext& ctx, Id lhs, Id rhs); | 294 | Id EmitIEqual(EmitContext& ctx, Id lhs, Id rhs); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp index 37fc7c7a2..8bf43b91d 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp | |||
| @@ -5,6 +5,25 @@ | |||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | 6 | ||
| 7 | namespace Shader::Backend::SPIRV { | 7 | namespace Shader::Backend::SPIRV { |
| 8 | namespace { | ||
| 9 | void SetZeroFlag(EmitContext& ctx, IR::Inst* inst, Id result) { | ||
| 10 | IR::Inst* const zero{inst->GetAssociatedPseudoOperation(IR::Opcode::GetZeroFromOp)}; | ||
| 11 | if (!zero) { | ||
| 12 | return; | ||
| 13 | } | ||
| 14 | zero->SetDefinition(ctx.OpIEqual(ctx.U1, result, ctx.u32_zero_value)); | ||
| 15 | zero->Invalidate(); | ||
| 16 | } | ||
| 17 | |||
| 18 | void SetSignFlag(EmitContext& ctx, IR::Inst* inst, Id result) { | ||
| 19 | IR::Inst* const sign{inst->GetAssociatedPseudoOperation(IR::Opcode::GetSignFromOp)}; | ||
| 20 | if (!sign) { | ||
| 21 | return; | ||
| 22 | } | ||
| 23 | sign->SetDefinition(ctx.OpSLessThan(ctx.U1, result, ctx.u32_zero_value)); | ||
| 24 | sign->Invalidate(); | ||
| 25 | } | ||
| 26 | } // Anonymous namespace | ||
| 8 | 27 | ||
| 9 | Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { | 28 | Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { |
| 10 | Id result{}; | 29 | Id result{}; |
| @@ -19,14 +38,8 @@ Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { | |||
| 19 | } else { | 38 | } else { |
| 20 | result = ctx.OpIAdd(ctx.U32[1], a, b); | 39 | result = ctx.OpIAdd(ctx.U32[1], a, b); |
| 21 | } | 40 | } |
| 22 | if (IR::Inst* const zero{inst->GetAssociatedPseudoOperation(IR::Opcode::GetZeroFromOp)}) { | 41 | SetZeroFlag(ctx, inst, result); |
| 23 | zero->SetDefinition(ctx.OpIEqual(ctx.U1, result, ctx.u32_zero_value)); | 42 | SetSignFlag(ctx, inst, result); |
| 24 | zero->Invalidate(); | ||
| 25 | } | ||
| 26 | if (IR::Inst* const sign{inst->GetAssociatedPseudoOperation(IR::Opcode::GetSignFromOp)}) { | ||
| 27 | sign->SetDefinition(ctx.OpSLessThan(ctx.U1, result, ctx.u32_zero_value)); | ||
| 28 | sign->Invalidate(); | ||
| 29 | } | ||
| 30 | if (IR::Inst * overflow{inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp)}) { | 43 | if (IR::Inst * overflow{inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp)}) { |
| 31 | // https://stackoverflow.com/questions/55468823/how-to-detect-integer-overflow-in-c | 44 | // https://stackoverflow.com/questions/55468823/how-to-detect-integer-overflow-in-c |
| 32 | constexpr u32 s32_max{static_cast<u32>(std::numeric_limits<s32>::max())}; | 45 | constexpr u32 s32_max{static_cast<u32>(std::numeric_limits<s32>::max())}; |
| @@ -114,16 +127,17 @@ Id EmitBitFieldInsert(EmitContext& ctx, Id base, Id insert, Id offset, Id count) | |||
| 114 | return ctx.OpBitFieldInsert(ctx.U32[1], base, insert, offset, count); | 127 | return ctx.OpBitFieldInsert(ctx.U32[1], base, insert, offset, count); |
| 115 | } | 128 | } |
| 116 | 129 | ||
| 117 | Id EmitBitFieldSExtract(EmitContext& ctx, Id base, Id offset, Id count) { | 130 | Id EmitBitFieldSExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count) { |
| 118 | return ctx.OpBitFieldSExtract(ctx.U32[1], base, offset, count); | 131 | const Id result{ctx.OpBitFieldSExtract(ctx.U32[1], base, offset, count)}; |
| 132 | SetZeroFlag(ctx, inst, result); | ||
| 133 | SetSignFlag(ctx, inst, result); | ||
| 134 | return result; | ||
| 119 | } | 135 | } |
| 120 | 136 | ||
| 121 | Id EmitBitFieldUExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count) { | 137 | Id EmitBitFieldUExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count) { |
| 122 | const Id result{ctx.OpBitFieldUExtract(ctx.U32[1], base, offset, count)}; | 138 | const Id result{ctx.OpBitFieldUExtract(ctx.U32[1], base, offset, count)}; |
| 123 | if (IR::Inst* const zero{inst->GetAssociatedPseudoOperation(IR::Opcode::GetZeroFromOp)}) { | 139 | SetZeroFlag(ctx, inst, result); |
| 124 | zero->SetDefinition(ctx.OpIEqual(ctx.U1, result, ctx.u32_zero_value)); | 140 | SetSignFlag(ctx, inst, result); |
| 125 | zero->Invalidate(); | ||
| 126 | } | ||
| 127 | return result; | 141 | return result; |
| 128 | } | 142 | } |
| 129 | 143 | ||
| @@ -163,12 +177,18 @@ Id EmitUMax32(EmitContext& ctx, Id a, Id b) { | |||
| 163 | return ctx.OpUMax(ctx.U32[1], a, b); | 177 | return ctx.OpUMax(ctx.U32[1], a, b); |
| 164 | } | 178 | } |
| 165 | 179 | ||
| 166 | Id EmitSClamp32(EmitContext& ctx, Id value, Id min, Id max) { | 180 | Id EmitSClamp32(EmitContext& ctx, IR::Inst* inst, Id value, Id min, Id max) { |
| 167 | return ctx.OpSClamp(ctx.U32[1], value, min, max); | 181 | const Id result{ctx.OpSClamp(ctx.U32[1], value, min, max)}; |
| 182 | SetZeroFlag(ctx, inst, result); | ||
| 183 | SetSignFlag(ctx, inst, result); | ||
| 184 | return result; | ||
| 168 | } | 185 | } |
| 169 | 186 | ||
| 170 | Id EmitUClamp32(EmitContext& ctx, Id value, Id min, Id max) { | 187 | Id EmitUClamp32(EmitContext& ctx, IR::Inst* inst, Id value, Id min, Id max) { |
| 171 | return ctx.OpUClamp(ctx.U32[1], value, min, max); | 188 | const Id result{ctx.OpUClamp(ctx.U32[1], value, min, max)}; |
| 189 | SetZeroFlag(ctx, inst, result); | ||
| 190 | SetSignFlag(ctx, inst, result); | ||
| 191 | return result; | ||
| 172 | } | 192 | } |
| 173 | 193 | ||
| 174 | Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs) { | 194 | Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs) { |