From 6db69990da9f232e6d982cdcb69c2e27d93075cf Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 19 Feb 2021 18:10:18 -0300 Subject: spirv: Add lower fp16 to fp32 pass --- .../backend/spirv/emit_spirv_convert.cpp | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp') diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp new file mode 100644 index 000000000..76ccaffce --- /dev/null +++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp @@ -0,0 +1,89 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "shader_recompiler/backend/spirv/emit_spirv.h" + +namespace Shader::Backend::SPIRV { + +Id EmitConvertS16F16(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); +} + +Id EmitConvertS16F32(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); +} + +Id EmitConvertS16F64(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); +} + +Id EmitConvertS32F16(EmitContext& ctx, Id value) { + return ctx.OpConvertFToS(ctx.U32[1], value); +} + +Id EmitConvertS32F32(EmitContext& ctx, Id value) { + return ctx.OpConvertFToS(ctx.U32[1], value); +} + +Id EmitConvertS32F64(EmitContext& ctx, Id value) { + return ctx.OpConvertFToS(ctx.U32[1], value); +} + +Id EmitConvertS64F16(EmitContext& ctx, Id value) { + return ctx.OpConvertFToS(ctx.U64, value); +} + +Id EmitConvertS64F32(EmitContext& ctx, Id value) { + return ctx.OpConvertFToS(ctx.U64, value); +} + +Id EmitConvertS64F64(EmitContext& ctx, Id value) { + return ctx.OpConvertFToS(ctx.U64, value); +} + +Id EmitConvertU16F16(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); +} + +Id EmitConvertU16F32(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); +} + +Id EmitConvertU16F64(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); +} + +Id EmitConvertU32F16(EmitContext& ctx, Id value) { + return ctx.OpConvertFToU(ctx.U32[1], value); +} + +Id EmitConvertU32F32(EmitContext& ctx, Id value) { + return ctx.OpConvertFToU(ctx.U32[1], value); +} + +Id EmitConvertU32F64(EmitContext& ctx, Id value) { + return ctx.OpConvertFToU(ctx.U32[1], value); +} + +Id EmitConvertU64F16(EmitContext& ctx, Id value) { + return ctx.OpConvertFToU(ctx.U64, value); +} + +Id EmitConvertU64F32(EmitContext& ctx, Id value) { + return ctx.OpConvertFToU(ctx.U64, value); +} + +Id EmitConvertU64F64(EmitContext& ctx, Id value) { + return ctx.OpConvertFToU(ctx.U64, value); +} + +Id EmitConvertU64U32(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U64, value); +} + +Id EmitConvertU32U64(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], value); +} + +} // namespace Shader::Backend::SPIRV -- cgit v1.2.3 From 4006929c986a2e0e52429fe21201a7ad5ca3fea9 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 3 Mar 2021 03:07:19 -0300 Subject: shader: Implement HADD2 --- .../backend/spirv/emit_spirv_convert.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp') diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp index 76ccaffce..edcc2a1cc 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp @@ -86,4 +86,20 @@ Id EmitConvertU32U64(EmitContext& ctx, Id value) { return ctx.OpUConvert(ctx.U32[1], value); } +Id EmitConvertF16F32(EmitContext& ctx, Id value) { + return ctx.OpFConvert(ctx.F16[1], value); +} + +Id EmitConvertF32F16(EmitContext& ctx, Id value) { + return ctx.OpFConvert(ctx.F32[1], value); +} + +Id EmitConvertF32F64(EmitContext& ctx, Id value) { + return ctx.OpFConvert(ctx.F32[1], value); +} + +Id EmitConvertF64F32(EmitContext& ctx, Id value) { + return ctx.OpFConvert(ctx.F64[1], value); +} + } // namespace Shader::Backend::SPIRV -- cgit v1.2.3 From ab463712474de5f99eec137a9c6233e55fe184f0 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 8 Mar 2021 18:31:53 -0300 Subject: shader: Initial support for textures and TEX --- .../backend/spirv/emit_spirv_convert.cpp | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp') diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp index edcc2a1cc..2aff673aa 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp @@ -102,4 +102,52 @@ Id EmitConvertF64F32(EmitContext& ctx, Id value) { return ctx.OpFConvert(ctx.F64[1], value); } +Id EmitConvertF16S32(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F16[1], value); +} + +Id EmitConvertF16S64(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F16[1], value); +} + +Id EmitConvertF16U32(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F16[1], value); +} + +Id EmitConvertF16U64(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F16[1], value); +} + +Id EmitConvertF32S32(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F32[1], value); +} + +Id EmitConvertF32S64(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F32[1], value); +} + +Id EmitConvertF32U32(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F32[1], value); +} + +Id EmitConvertF32U64(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F32[1], value); +} + +Id EmitConvertF64S32(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F64[1], value); +} + +Id EmitConvertF64S64(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F64[1], value); +} + +Id EmitConvertF64U32(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F64[1], value); +} + +Id EmitConvertF64U64(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F64[1], value); +} + } // namespace Shader::Backend::SPIRV -- cgit v1.2.3 From f91859efd259995806c2944f7941b105b58300d3 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 20 Mar 2021 05:04:12 -0300 Subject: shader: Implement I2F --- .../backend/spirv/emit_spirv_convert.cpp | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp') diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp index 2aff673aa..757165626 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp @@ -102,6 +102,14 @@ Id EmitConvertF64F32(EmitContext& ctx, Id value) { return ctx.OpFConvert(ctx.F64[1], value); } +Id EmitConvertF16S8(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F16[1], value); +} + +Id EmitConvertF16S16(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F16[1], value); +} + Id EmitConvertF16S32(EmitContext& ctx, Id value) { return ctx.OpConvertSToF(ctx.F16[1], value); } @@ -110,6 +118,14 @@ Id EmitConvertF16S64(EmitContext& ctx, Id value) { return ctx.OpConvertSToF(ctx.F16[1], value); } +Id EmitConvertF16U8(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F16[1], value); +} + +Id EmitConvertF16U16(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F16[1], value); +} + Id EmitConvertF16U32(EmitContext& ctx, Id value) { return ctx.OpConvertUToF(ctx.F16[1], value); } @@ -118,6 +134,14 @@ Id EmitConvertF16U64(EmitContext& ctx, Id value) { return ctx.OpConvertUToF(ctx.F16[1], value); } +Id EmitConvertF32S8(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F32[1], ctx.OpUConvert(ctx.U8, value)); +} + +Id EmitConvertF32S16(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F32[1], ctx.OpUConvert(ctx.U16, value)); +} + Id EmitConvertF32S32(EmitContext& ctx, Id value) { return ctx.OpConvertSToF(ctx.F32[1], value); } @@ -126,6 +150,14 @@ Id EmitConvertF32S64(EmitContext& ctx, Id value) { return ctx.OpConvertSToF(ctx.F32[1], value); } +Id EmitConvertF32U8(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F32[1], ctx.OpUConvert(ctx.U8, value)); +} + +Id EmitConvertF32U16(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F32[1], ctx.OpUConvert(ctx.U16, value)); +} + Id EmitConvertF32U32(EmitContext& ctx, Id value) { return ctx.OpConvertUToF(ctx.F32[1], value); } @@ -134,6 +166,14 @@ Id EmitConvertF32U64(EmitContext& ctx, Id value) { return ctx.OpConvertUToF(ctx.F32[1], value); } +Id EmitConvertF64S8(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F64[1], ctx.OpUConvert(ctx.U8, value)); +} + +Id EmitConvertF64S16(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F64[1], ctx.OpUConvert(ctx.U16, value)); +} + Id EmitConvertF64S32(EmitContext& ctx, Id value) { return ctx.OpConvertSToF(ctx.F64[1], value); } @@ -142,6 +182,14 @@ Id EmitConvertF64S64(EmitContext& ctx, Id value) { return ctx.OpConvertSToF(ctx.F64[1], value); } +Id EmitConvertF64U8(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F64[1], ctx.OpUConvert(ctx.U8, value)); +} + +Id EmitConvertF64U16(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F64[1], ctx.OpUConvert(ctx.U16, value)); +} + Id EmitConvertF64U32(EmitContext& ctx, Id value) { return ctx.OpConvertUToF(ctx.F64[1], value); } -- cgit v1.2.3 From 7b03b9711815d0c4c39bb26f83ada9f6957bb269 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 23 May 2021 04:08:58 -0300 Subject: spirv: Implement int8 and int16 conversion fallbacks --- .../backend/spirv/emit_spirv_convert.cpp | 99 +++++++++++++++++----- 1 file changed, 80 insertions(+), 19 deletions(-) (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp') 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 @@ #include "shader_recompiler/backend/spirv/emit_spirv.h" namespace Shader::Backend::SPIRV { +namespace { +Id ExtractU16(EmitContext& ctx, Id value) { + if (ctx.profile.support_int16) { + return ctx.OpUConvert(ctx.U16, value); + } else { + return ctx.OpBitFieldUExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(16u)); + } +} + +Id ExtractS16(EmitContext& ctx, Id value) { + if (ctx.profile.support_int16) { + return ctx.OpUConvert(ctx.S16, value); + } else { + return ctx.OpBitFieldSExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(16u)); + } +} + +Id ExtractU8(EmitContext& ctx, Id value) { + if (ctx.profile.support_int16) { + return ctx.OpUConvert(ctx.U8, value); + } else { + return ctx.OpBitFieldUExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(8u)); + } +} + +Id ExtractS8(EmitContext& ctx, Id value) { + if (ctx.profile.support_int8) { + return ctx.OpSConvert(ctx.S8, value); + } else { + return ctx.OpBitFieldSExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(8u)); + } +} +} // Anonymous namespace Id EmitConvertS16F16(EmitContext& ctx, Id value) { - return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); + if (ctx.profile.support_int16) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); + } else { + return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value)); + } } Id EmitConvertS16F32(EmitContext& ctx, Id value) { - return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); + if (ctx.profile.support_int16) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); + } else { + return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value)); + } } Id EmitConvertS16F64(EmitContext& ctx, Id value) { - return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); + if (ctx.profile.support_int16) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); + } else { + return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value)); + } } Id EmitConvertS32F16(EmitContext& ctx, Id value) { @@ -23,7 +68,11 @@ Id EmitConvertS32F16(EmitContext& ctx, Id value) { } Id EmitConvertS32F32(EmitContext& ctx, Id value) { - return ctx.OpConvertFToS(ctx.U32[1], value); + if (ctx.profile.has_broken_signed_operations) { + return ctx.OpBitcast(ctx.U32[1], ctx.OpConvertFToS(ctx.S32[1], value)); + } else { + return ctx.OpConvertFToS(ctx.U32[1], value); + } } Id EmitConvertS32F64(EmitContext& ctx, Id value) { @@ -43,15 +92,27 @@ Id EmitConvertS64F64(EmitContext& ctx, Id value) { } Id EmitConvertU16F16(EmitContext& ctx, Id value) { - return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); + if (ctx.profile.support_int16) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); + } else { + return ExtractU16(ctx, ctx.OpConvertFToU(ctx.U32[1], value)); + } } Id EmitConvertU16F32(EmitContext& ctx, Id value) { - return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); + if (ctx.profile.support_int16) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); + } else { + return ExtractU16(ctx, ctx.OpConvertFToU(ctx.U32[1], value)); + } } Id EmitConvertU16F64(EmitContext& ctx, Id value) { - return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); + if (ctx.profile.support_int16) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); + } else { + return ExtractU16(ctx, ctx.OpConvertFToU(ctx.U32[1], value)); + } } Id EmitConvertU32F16(EmitContext& ctx, Id value) { @@ -103,11 +164,11 @@ Id EmitConvertF64F32(EmitContext& ctx, Id value) { } Id EmitConvertF16S8(EmitContext& ctx, Id value) { - return ctx.OpConvertSToF(ctx.F16[1], value); + return ctx.OpConvertSToF(ctx.F16[1], ExtractS8(ctx, value)); } Id EmitConvertF16S16(EmitContext& ctx, Id value) { - return ctx.OpConvertSToF(ctx.F16[1], value); + return ctx.OpConvertSToF(ctx.F16[1], ExtractS16(ctx, value)); } Id EmitConvertF16S32(EmitContext& ctx, Id value) { @@ -119,11 +180,11 @@ Id EmitConvertF16S64(EmitContext& ctx, Id value) { } Id EmitConvertF16U8(EmitContext& ctx, Id value) { - return ctx.OpConvertUToF(ctx.F16[1], value); + return ctx.OpConvertUToF(ctx.F16[1], ExtractU8(ctx, value)); } Id EmitConvertF16U16(EmitContext& ctx, Id value) { - return ctx.OpConvertUToF(ctx.F16[1], value); + return ctx.OpConvertUToF(ctx.F16[1], ExtractU16(ctx, value)); } Id EmitConvertF16U32(EmitContext& ctx, Id value) { @@ -135,11 +196,11 @@ Id EmitConvertF16U64(EmitContext& ctx, Id value) { } Id EmitConvertF32S8(EmitContext& ctx, Id value) { - return ctx.OpConvertSToF(ctx.F32[1], ctx.OpUConvert(ctx.U8, value)); + return ctx.OpConvertSToF(ctx.F32[1], ExtractS8(ctx, value)); } Id EmitConvertF32S16(EmitContext& ctx, Id value) { - return ctx.OpConvertSToF(ctx.F32[1], ctx.OpUConvert(ctx.U16, value)); + return ctx.OpConvertSToF(ctx.F32[1], ExtractS16(ctx, value)); } Id EmitConvertF32S32(EmitContext& ctx, Id value) { @@ -151,11 +212,11 @@ Id EmitConvertF32S64(EmitContext& ctx, Id value) { } Id EmitConvertF32U8(EmitContext& ctx, Id value) { - return ctx.OpConvertUToF(ctx.F32[1], ctx.OpUConvert(ctx.U8, value)); + return ctx.OpConvertUToF(ctx.F32[1], ExtractU8(ctx, value)); } Id EmitConvertF32U16(EmitContext& ctx, Id value) { - return ctx.OpConvertUToF(ctx.F32[1], ctx.OpUConvert(ctx.U16, value)); + return ctx.OpConvertUToF(ctx.F32[1], ExtractU16(ctx, value)); } Id EmitConvertF32U32(EmitContext& ctx, Id value) { @@ -167,11 +228,11 @@ Id EmitConvertF32U64(EmitContext& ctx, Id value) { } Id EmitConvertF64S8(EmitContext& ctx, Id value) { - return ctx.OpConvertSToF(ctx.F64[1], ctx.OpUConvert(ctx.U8, value)); + return ctx.OpConvertSToF(ctx.F64[1], ExtractS8(ctx, value)); } Id EmitConvertF64S16(EmitContext& ctx, Id value) { - return ctx.OpConvertSToF(ctx.F64[1], ctx.OpUConvert(ctx.U16, value)); + return ctx.OpConvertSToF(ctx.F64[1], ExtractS16(ctx, value)); } Id EmitConvertF64S32(EmitContext& ctx, Id value) { @@ -183,11 +244,11 @@ Id EmitConvertF64S64(EmitContext& ctx, Id value) { } Id EmitConvertF64U8(EmitContext& ctx, Id value) { - return ctx.OpConvertUToF(ctx.F64[1], ctx.OpUConvert(ctx.U8, value)); + return ctx.OpConvertUToF(ctx.F64[1], ExtractU8(ctx, value)); } Id EmitConvertF64U16(EmitContext& ctx, Id value) { - return ctx.OpConvertUToF(ctx.F64[1], ctx.OpUConvert(ctx.U16, value)); + return ctx.OpConvertUToF(ctx.F64[1], ExtractU16(ctx, value)); } Id EmitConvertF64U32(EmitContext& ctx, Id value) { -- cgit v1.2.3 From bed090807afd3364ed6ef18a031a0ffd95a1b89b Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 3 May 2021 20:53:00 -0300 Subject: Move SPIR-V emission functions to their own header --- src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp') diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp index acb8957fe..fd74e475f 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "shader_recompiler/backend/spirv/emit_spirv.h" +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" namespace Shader::Backend::SPIRV { namespace { -- cgit v1.2.3 From 8554a644df7ad909e418f3e96016e95abc55712f Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 11 Jun 2021 00:18:24 -0300 Subject: spirv/convert: Catch more broken signed operations on Nvidia OpenGL BitCast U32 to S32 before converting to float on drivers with broken signed operations. --- src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp') diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp index fd74e475f..2c4250a0c 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp @@ -205,6 +205,9 @@ Id EmitConvertF32S16(EmitContext& ctx, Id value) { } Id EmitConvertF32S32(EmitContext& ctx, Id value) { + if (ctx.profile.has_broken_signed_operations) { + value = ctx.OpBitcast(ctx.S32[1], value); + } return ctx.OpConvertSToF(ctx.F32[1], value); } @@ -237,6 +240,9 @@ Id EmitConvertF64S16(EmitContext& ctx, Id value) { } Id EmitConvertF64S32(EmitContext& ctx, Id value) { + if (ctx.profile.has_broken_signed_operations) { + value = ctx.OpBitcast(ctx.S32[1], value); + } return ctx.OpConvertSToF(ctx.F64[1], value); } -- cgit v1.2.3 From d52bacf6f035ddbc4b2333953709cbd3993e4817 Mon Sep 17 00:00:00 2001 From: ameerj Date: Fri, 11 Jun 2021 01:11:59 -0400 Subject: spirv/convert: Catch more signed operations oversights The sign bit on integers of size < 32 was not properly preserved in casts --- src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp') diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp index 2c4250a0c..fd42b7a16 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp @@ -17,14 +17,14 @@ Id ExtractU16(EmitContext& ctx, Id value) { Id ExtractS16(EmitContext& ctx, Id value) { if (ctx.profile.support_int16) { - return ctx.OpUConvert(ctx.S16, value); + return ctx.OpSConvert(ctx.S16, value); } else { return ctx.OpBitFieldSExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(16u)); } } Id ExtractU8(EmitContext& ctx, Id value) { - if (ctx.profile.support_int16) { + if (ctx.profile.support_int8) { return ctx.OpUConvert(ctx.U8, value); } else { return ctx.OpBitFieldUExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(8u)); @@ -42,7 +42,7 @@ Id ExtractS8(EmitContext& ctx, Id value) { Id EmitConvertS16F16(EmitContext& ctx, Id value) { if (ctx.profile.support_int16) { - return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); + return ctx.OpSConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); } else { return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value)); } @@ -50,7 +50,7 @@ Id EmitConvertS16F16(EmitContext& ctx, Id value) { Id EmitConvertS16F32(EmitContext& ctx, Id value) { if (ctx.profile.support_int16) { - return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); + return ctx.OpSConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); } else { return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value)); } @@ -58,7 +58,7 @@ Id EmitConvertS16F32(EmitContext& ctx, Id value) { Id EmitConvertS16F64(EmitContext& ctx, Id value) { if (ctx.profile.support_int16) { - return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); + return ctx.OpSConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); } else { return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value)); } -- cgit v1.2.3