From 0f6aff6f74cddc8e5b53ebabe388fb87aae4ebb7 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Sun, 1 Nov 2020 21:48:14 +0300 Subject: [PATCH] [SPIR-V] Unary math functions --- src/xenia/gpu/spirv_shader_translator_alu.cc | 100 +++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/src/xenia/gpu/spirv_shader_translator_alu.cc b/src/xenia/gpu/spirv_shader_translator_alu.cc index 819ca15ed..ed054f70a 100644 --- a/src/xenia/gpu/spirv_shader_translator_alu.cc +++ b/src/xenia/gpu/spirv_shader_translator_alu.cc @@ -10,6 +10,8 @@ #include "xenia/gpu/spirv_shader_translator.h" #include +#include +#include #include #include "third_party/glslang/SPIRV/GLSL.std.450.h" @@ -1210,6 +1212,104 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( return builder_->createBuiltinCall( type_float_, ext_inst_glsl_std_450_, GLSLstd450(kOps[size_t(instr.scalar_opcode)]), id_vector_temp_); + case ucode::AluScalarOpcode::kLogc: { + id_vector_temp_.clear(); + id_vector_temp_.push_back(GetOperandComponents( + operand_storage[0], instr.scalar_operands[0], 0b0001)); + spv::Id result = builder_->createBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Log2, id_vector_temp_); + return builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(-INFINITY)), + builder_->makeFloatConstant(-FLT_MAX), result); + } + case ucode::AluScalarOpcode::kRcpc: { + spv::Id result = builder_->createBinOp( + spv::OpFDiv, type_float_, const_float_1_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], + 0b0001)); + builder_->addDecoration(result, spv::DecorationNoContraction); + result = builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(-INFINITY)), + builder_->makeFloatConstant(-FLT_MAX), result); + return builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(INFINITY)), + builder_->makeFloatConstant(FLT_MAX), result); + } + case ucode::AluScalarOpcode::kRcpf: { + spv::Id result = builder_->createBinOp( + spv::OpFDiv, type_float_, const_float_1_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], + 0b0001)); + builder_->addDecoration(result, spv::DecorationNoContraction); + result = builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(INFINITY)), + const_float_0_, result); + // Can't create -0.0f with makeFloatConstant due to float comparison + // internally, cast to bit pattern. + result = builder_->createTriOp( + spv::OpSelect, type_uint_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(-INFINITY)), + builder_->makeUintConstant(uint32_t(INT32_MIN)), + builder_->createUnaryOp(spv::OpBitcast, type_uint_, result)); + return builder_->createUnaryOp(spv::OpBitcast, type_float_, result); + } + case ucode::AluScalarOpcode::kRcp: { + spv::Id result = builder_->createBinOp( + spv::OpFDiv, type_float_, const_float_1_, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], + 0b0001)); + builder_->addDecoration(result, spv::DecorationNoContraction); + return result; + } + case ucode::AluScalarOpcode::kRsqc: { + id_vector_temp_.clear(); + id_vector_temp_.push_back(GetOperandComponents( + operand_storage[0], instr.scalar_operands[0], 0b0001)); + spv::Id result = + builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450InverseSqrt, id_vector_temp_); + result = builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(-INFINITY)), + builder_->makeFloatConstant(-FLT_MAX), result); + return builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(INFINITY)), + builder_->makeFloatConstant(FLT_MAX), result); + } + case ucode::AluScalarOpcode::kRsqf: { + id_vector_temp_.clear(); + id_vector_temp_.push_back(GetOperandComponents( + operand_storage[0], instr.scalar_operands[0], 0b0001)); + spv::Id result = + builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450InverseSqrt, id_vector_temp_); + result = builder_->createTriOp( + spv::OpSelect, type_float_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(INFINITY)), + const_float_0_, result); + // Can't create -0.0f with makeFloatConstant due to float comparison + // internally, cast to bit pattern. + result = builder_->createTriOp( + spv::OpSelect, type_uint_, + builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, + builder_->makeFloatConstant(-INFINITY)), + builder_->makeUintConstant(uint32_t(INT32_MIN)), + builder_->createUnaryOp(spv::OpBitcast, type_uint_, result)); + return builder_->createUnaryOp(spv::OpBitcast, type_float_, result); + } // TODO(Triang3l): Implement the rest of instructions. }