diff options
| author | 2021-05-23 04:08:58 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:29 -0400 | |
| commit | 7b03b9711815d0c4c39bb26f83ada9f6957bb269 (patch) | |
| tree | 13753413eba95f750532525259a1647ab5f96321 /src/shader_recompiler/backend | |
| parent | spirv: Support OpenGL uniform buffers and change bindings (diff) | |
| download | yuzu-7b03b9711815d0c4c39bb26f83ada9f6957bb269.tar.gz yuzu-7b03b9711815d0c4c39bb26f83ada9f6957bb269.tar.xz yuzu-7b03b9711815d0c4c39bb26f83ada9f6957bb269.zip | |
spirv: Implement int8 and int16 conversion fallbacks
Diffstat (limited to 'src/shader_recompiler/backend')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp | 99 |
1 files changed, 80 insertions, 19 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp index 757165626..acb8957fe 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp | |||
| @@ -5,17 +5,62 @@ | |||
| 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 | Id ExtractU16(EmitContext& ctx, Id value) { | ||
| 10 | if (ctx.profile.support_int16) { | ||
| 11 | return ctx.OpUConvert(ctx.U16, value); | ||
| 12 | } else { | ||
| 13 | return ctx.OpBitFieldUExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(16u)); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | Id ExtractS16(EmitContext& ctx, Id value) { | ||
| 18 | if (ctx.profile.support_int16) { | ||
| 19 | return ctx.OpUConvert(ctx.S16, value); | ||
| 20 | } else { | ||
| 21 | return ctx.OpBitFieldSExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(16u)); | ||
| 22 | } | ||
| 23 | } | ||
| 24 | |||
| 25 | Id ExtractU8(EmitContext& ctx, Id value) { | ||
| 26 | if (ctx.profile.support_int16) { | ||
| 27 | return ctx.OpUConvert(ctx.U8, value); | ||
| 28 | } else { | ||
| 29 | return ctx.OpBitFieldUExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(8u)); | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | Id ExtractS8(EmitContext& ctx, Id value) { | ||
| 34 | if (ctx.profile.support_int8) { | ||
| 35 | return ctx.OpSConvert(ctx.S8, value); | ||
| 36 | } else { | ||
| 37 | return ctx.OpBitFieldSExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(8u)); | ||
| 38 | } | ||
| 39 | } | ||
| 40 | } // Anonymous namespace | ||
| 8 | 41 | ||
| 9 | Id EmitConvertS16F16(EmitContext& ctx, Id value) { | 42 | Id EmitConvertS16F16(EmitContext& ctx, Id value) { |
| 10 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); | 43 | if (ctx.profile.support_int16) { |
| 44 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); | ||
| 45 | } else { | ||
| 46 | return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value)); | ||
| 47 | } | ||
| 11 | } | 48 | } |
| 12 | 49 | ||
| 13 | Id EmitConvertS16F32(EmitContext& ctx, Id value) { | 50 | Id EmitConvertS16F32(EmitContext& ctx, Id value) { |
| 14 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); | 51 | if (ctx.profile.support_int16) { |
| 52 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); | ||
| 53 | } else { | ||
| 54 | return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value)); | ||
| 55 | } | ||
| 15 | } | 56 | } |
| 16 | 57 | ||
| 17 | Id EmitConvertS16F64(EmitContext& ctx, Id value) { | 58 | Id EmitConvertS16F64(EmitContext& ctx, Id value) { |
| 18 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); | 59 | if (ctx.profile.support_int16) { |
| 60 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); | ||
| 61 | } else { | ||
| 62 | return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value)); | ||
| 63 | } | ||
| 19 | } | 64 | } |
| 20 | 65 | ||
| 21 | Id EmitConvertS32F16(EmitContext& ctx, Id value) { | 66 | Id EmitConvertS32F16(EmitContext& ctx, Id value) { |
| @@ -23,7 +68,11 @@ Id EmitConvertS32F16(EmitContext& ctx, Id value) { | |||
| 23 | } | 68 | } |
| 24 | 69 | ||
| 25 | Id EmitConvertS32F32(EmitContext& ctx, Id value) { | 70 | Id EmitConvertS32F32(EmitContext& ctx, Id value) { |
| 26 | return ctx.OpConvertFToS(ctx.U32[1], value); | 71 | if (ctx.profile.has_broken_signed_operations) { |
| 72 | return ctx.OpBitcast(ctx.U32[1], ctx.OpConvertFToS(ctx.S32[1], value)); | ||
| 73 | } else { | ||
| 74 | return ctx.OpConvertFToS(ctx.U32[1], value); | ||
| 75 | } | ||
| 27 | } | 76 | } |
| 28 | 77 | ||
| 29 | Id EmitConvertS32F64(EmitContext& ctx, Id value) { | 78 | Id EmitConvertS32F64(EmitContext& ctx, Id value) { |
| @@ -43,15 +92,27 @@ Id EmitConvertS64F64(EmitContext& ctx, Id value) { | |||
| 43 | } | 92 | } |
| 44 | 93 | ||
| 45 | Id EmitConvertU16F16(EmitContext& ctx, Id value) { | 94 | Id EmitConvertU16F16(EmitContext& ctx, Id value) { |
| 46 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); | 95 | if (ctx.profile.support_int16) { |
| 96 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); | ||
| 97 | } else { | ||
| 98 | return ExtractU16(ctx, ctx.OpConvertFToU(ctx.U32[1], value)); | ||
| 99 | } | ||
| 47 | } | 100 | } |
| 48 | 101 | ||
| 49 | Id EmitConvertU16F32(EmitContext& ctx, Id value) { | 102 | Id EmitConvertU16F32(EmitContext& ctx, Id value) { |
| 50 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); | 103 | if (ctx.profile.support_int16) { |
| 104 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); | ||
| 105 | } else { | ||
| 106 | return ExtractU16(ctx, ctx.OpConvertFToU(ctx.U32[1], value)); | ||
| 107 | } | ||
| 51 | } | 108 | } |
| 52 | 109 | ||
| 53 | Id EmitConvertU16F64(EmitContext& ctx, Id value) { | 110 | Id EmitConvertU16F64(EmitContext& ctx, Id value) { |
| 54 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); | 111 | if (ctx.profile.support_int16) { |
| 112 | return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); | ||
| 113 | } else { | ||
| 114 | return ExtractU16(ctx, ctx.OpConvertFToU(ctx.U32[1], value)); | ||
| 115 | } | ||
| 55 | } | 116 | } |
| 56 | 117 | ||
| 57 | Id EmitConvertU32F16(EmitContext& ctx, Id value) { | 118 | Id EmitConvertU32F16(EmitContext& ctx, Id value) { |
| @@ -103,11 +164,11 @@ Id EmitConvertF64F32(EmitContext& ctx, Id value) { | |||
| 103 | } | 164 | } |
| 104 | 165 | ||
| 105 | Id EmitConvertF16S8(EmitContext& ctx, Id value) { | 166 | Id EmitConvertF16S8(EmitContext& ctx, Id value) { |
| 106 | return ctx.OpConvertSToF(ctx.F16[1], value); | 167 | return ctx.OpConvertSToF(ctx.F16[1], ExtractS8(ctx, value)); |
| 107 | } | 168 | } |
| 108 | 169 | ||
| 109 | Id EmitConvertF16S16(EmitContext& ctx, Id value) { | 170 | Id EmitConvertF16S16(EmitContext& ctx, Id value) { |
| 110 | return ctx.OpConvertSToF(ctx.F16[1], value); | 171 | return ctx.OpConvertSToF(ctx.F16[1], ExtractS16(ctx, value)); |
| 111 | } | 172 | } |
| 112 | 173 | ||
| 113 | Id EmitConvertF16S32(EmitContext& ctx, Id value) { | 174 | Id EmitConvertF16S32(EmitContext& ctx, Id value) { |
| @@ -119,11 +180,11 @@ Id EmitConvertF16S64(EmitContext& ctx, Id value) { | |||
| 119 | } | 180 | } |
| 120 | 181 | ||
| 121 | Id EmitConvertF16U8(EmitContext& ctx, Id value) { | 182 | Id EmitConvertF16U8(EmitContext& ctx, Id value) { |
| 122 | return ctx.OpConvertUToF(ctx.F16[1], value); | 183 | return ctx.OpConvertUToF(ctx.F16[1], ExtractU8(ctx, value)); |
| 123 | } | 184 | } |
| 124 | 185 | ||
| 125 | Id EmitConvertF16U16(EmitContext& ctx, Id value) { | 186 | Id EmitConvertF16U16(EmitContext& ctx, Id value) { |
| 126 | return ctx.OpConvertUToF(ctx.F16[1], value); | 187 | return ctx.OpConvertUToF(ctx.F16[1], ExtractU16(ctx, value)); |
| 127 | } | 188 | } |
| 128 | 189 | ||
| 129 | Id EmitConvertF16U32(EmitContext& ctx, Id value) { | 190 | Id EmitConvertF16U32(EmitContext& ctx, Id value) { |
| @@ -135,11 +196,11 @@ Id EmitConvertF16U64(EmitContext& ctx, Id value) { | |||
| 135 | } | 196 | } |
| 136 | 197 | ||
| 137 | Id EmitConvertF32S8(EmitContext& ctx, Id value) { | 198 | Id EmitConvertF32S8(EmitContext& ctx, Id value) { |
| 138 | return ctx.OpConvertSToF(ctx.F32[1], ctx.OpUConvert(ctx.U8, value)); | 199 | return ctx.OpConvertSToF(ctx.F32[1], ExtractS8(ctx, value)); |
| 139 | } | 200 | } |
| 140 | 201 | ||
| 141 | Id EmitConvertF32S16(EmitContext& ctx, Id value) { | 202 | Id EmitConvertF32S16(EmitContext& ctx, Id value) { |
| 142 | return ctx.OpConvertSToF(ctx.F32[1], ctx.OpUConvert(ctx.U16, value)); | 203 | return ctx.OpConvertSToF(ctx.F32[1], ExtractS16(ctx, value)); |
| 143 | } | 204 | } |
| 144 | 205 | ||
| 145 | Id EmitConvertF32S32(EmitContext& ctx, Id value) { | 206 | Id EmitConvertF32S32(EmitContext& ctx, Id value) { |
| @@ -151,11 +212,11 @@ Id EmitConvertF32S64(EmitContext& ctx, Id value) { | |||
| 151 | } | 212 | } |
| 152 | 213 | ||
| 153 | Id EmitConvertF32U8(EmitContext& ctx, Id value) { | 214 | Id EmitConvertF32U8(EmitContext& ctx, Id value) { |
| 154 | return ctx.OpConvertUToF(ctx.F32[1], ctx.OpUConvert(ctx.U8, value)); | 215 | return ctx.OpConvertUToF(ctx.F32[1], ExtractU8(ctx, value)); |
| 155 | } | 216 | } |
| 156 | 217 | ||
| 157 | Id EmitConvertF32U16(EmitContext& ctx, Id value) { | 218 | Id EmitConvertF32U16(EmitContext& ctx, Id value) { |
| 158 | return ctx.OpConvertUToF(ctx.F32[1], ctx.OpUConvert(ctx.U16, value)); | 219 | return ctx.OpConvertUToF(ctx.F32[1], ExtractU16(ctx, value)); |
| 159 | } | 220 | } |
| 160 | 221 | ||
| 161 | Id EmitConvertF32U32(EmitContext& ctx, Id value) { | 222 | Id EmitConvertF32U32(EmitContext& ctx, Id value) { |
| @@ -167,11 +228,11 @@ Id EmitConvertF32U64(EmitContext& ctx, Id value) { | |||
| 167 | } | 228 | } |
| 168 | 229 | ||
| 169 | Id EmitConvertF64S8(EmitContext& ctx, Id value) { | 230 | Id EmitConvertF64S8(EmitContext& ctx, Id value) { |
| 170 | return ctx.OpConvertSToF(ctx.F64[1], ctx.OpUConvert(ctx.U8, value)); | 231 | return ctx.OpConvertSToF(ctx.F64[1], ExtractS8(ctx, value)); |
| 171 | } | 232 | } |
| 172 | 233 | ||
| 173 | Id EmitConvertF64S16(EmitContext& ctx, Id value) { | 234 | Id EmitConvertF64S16(EmitContext& ctx, Id value) { |
| 174 | return ctx.OpConvertSToF(ctx.F64[1], ctx.OpUConvert(ctx.U16, value)); | 235 | return ctx.OpConvertSToF(ctx.F64[1], ExtractS16(ctx, value)); |
| 175 | } | 236 | } |
| 176 | 237 | ||
| 177 | Id EmitConvertF64S32(EmitContext& ctx, Id value) { | 238 | Id EmitConvertF64S32(EmitContext& ctx, Id value) { |
| @@ -183,11 +244,11 @@ Id EmitConvertF64S64(EmitContext& ctx, Id value) { | |||
| 183 | } | 244 | } |
| 184 | 245 | ||
| 185 | Id EmitConvertF64U8(EmitContext& ctx, Id value) { | 246 | Id EmitConvertF64U8(EmitContext& ctx, Id value) { |
| 186 | return ctx.OpConvertUToF(ctx.F64[1], ctx.OpUConvert(ctx.U8, value)); | 247 | return ctx.OpConvertUToF(ctx.F64[1], ExtractU8(ctx, value)); |
| 187 | } | 248 | } |
| 188 | 249 | ||
| 189 | Id EmitConvertF64U16(EmitContext& ctx, Id value) { | 250 | Id EmitConvertF64U16(EmitContext& ctx, Id value) { |
| 190 | return ctx.OpConvertUToF(ctx.F64[1], ctx.OpUConvert(ctx.U16, value)); | 251 | return ctx.OpConvertUToF(ctx.F64[1], ExtractU16(ctx, value)); |
| 191 | } | 252 | } |
| 192 | 253 | ||
| 193 | Id EmitConvertF64U32(EmitContext& ctx, Id value) { | 254 | Id EmitConvertF64U32(EmitContext& ctx, Id value) { |