From 08a173e5ecc3c06f70d6a66d28a43d587eb22cf6 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sat, 20 Feb 2016 21:28:25 -0600 Subject: [PATCH 1/3] Scalar Sxxx --- src/xenia/gpu/spirv_shader_translator.cc | 40 +++++++++++++++--------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 943da9d45..c071cfa1f 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -724,19 +724,35 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( } break; case AluScalarOpcode::kSeqs: { - // TODO: dest = src0 == 0.0 ? 1.0 : 0.0; + // dest = src0 == 0.0 ? 1.0 : 0.0; + auto cond = b.createBinOp(spv::Op::OpFOrdEqual, bool_type_, sources[0], + b.makeFloatConstant(0.f)); + dest = b.createTriOp(spv::Op::OpSelect, float_type_, cond, + b.makeFloatConstant(1.f), b.makeFloatConstant(0.f)); } break; case AluScalarOpcode::kSges: { - // TODO: dest = src0 >= 0.0 ? 1.0 : 0.0; + // dest = src0 >= 0.0 ? 1.0 : 0.0; + auto cond = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, bool_type_, + sources[0], b.makeFloatConstant(0.f)); + dest = b.createTriOp(spv::Op::OpSelect, float_type_, cond, + b.makeFloatConstant(1.f), b.makeFloatConstant(0.f)); } break; case AluScalarOpcode::kSgts: { - // TODO: dest = src0 > 0.0 ? 1.0 : 0.0; + // dest = src0 > 0.0 ? 1.0 : 0.0; + auto cond = b.createBinOp(spv::Op::OpFOrdGreaterThan, bool_type_, + sources[0], b.makeFloatConstant(0.f)); + dest = b.createTriOp(spv::Op::OpSelect, float_type_, cond, + b.makeFloatConstant(1.f), b.makeFloatConstant(0.f)); } break; case AluScalarOpcode::kSnes: { - // TODO: dest = src0 != 0.0 ? 1.0 : 0.0; + // dest = src0 != 0.0 ? 1.0 : 0.0; + auto cond = b.createBinOp(spv::Op::OpFOrdNotEqual, bool_type_, sources[0], + b.makeFloatConstant(0.f)); + dest = b.createTriOp(spv::Op::OpSelect, float_type_, cond, + b.makeFloatConstant(1.f), b.makeFloatConstant(0.f)); } break; case AluScalarOpcode::kSetpEq: { @@ -932,29 +948,26 @@ Id SpirvShaderTranslator::LoadFromOperand(const InstructionOperand& op) { swiz = op.components[op.component_count - 1]; } - uint32_t swiz_id = 0; switch (swiz) { case SwizzleSource::kX: - swiz_id = 0; + operands.push_back(0); break; case SwizzleSource::kY: - swiz_id = 1; + operands.push_back(1); break; case SwizzleSource::kZ: - swiz_id = 2; + operands.push_back(2); break; case SwizzleSource::kW: - swiz_id = 3; + operands.push_back(3); break; case SwizzleSource::k0: - swiz_id = 4; + operands.push_back(4); break; case SwizzleSource::k1: - swiz_id = 5; + operands.push_back(5); break; } - - operands.push_back(swiz_id); } storage_value = @@ -1096,7 +1109,6 @@ void SpirvShaderTranslator::StoreToResult(Id source_value_id, continue; } - uint32_t swiz_id = 0; switch (swiz) { case SwizzleSource::kX: operands.push_back(0); From ca01bb231169732df929c7c0f782ac1da3352219 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sat, 20 Feb 2016 21:53:22 -0600 Subject: [PATCH 2/3] ALU predicated discard --- src/xenia/gpu/spirv_shader_translator.cc | 39 ++++++++++++++++++++++-- src/xenia/gpu/spirv_shader_translator.h | 3 +- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index c071cfa1f..f3997266d 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -599,8 +599,20 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( } if (dest) { + // If predicated, discard the result from the instruction. + Id pred_cond = 0; + Id pv_dest = dest; + if (instr.is_predicated) { + pred_cond = + b.createBinOp(spv::Op::OpLogicalEqual, bool_type_, b.createLoad(p0_), + b.makeBoolConstant(instr.predicate_condition)); + + pv_dest = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, pred_cond, + dest, b.createLoad(pv_)); + } + b.createStore(dest, pv_); - StoreToResult(dest, instr.result); + StoreToResult(dest, instr.result, pred_cond); } } @@ -839,8 +851,20 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( } if (dest) { + // If predicated, discard the result from the instruction. + Id pred_cond = 0; + Id ps_dest = dest; + if (instr.is_predicated) { + pred_cond = + b.createBinOp(spv::Op::OpLogicalEqual, bool_type_, b.createLoad(p0_), + b.makeBoolConstant(instr.predicate_condition)); + + ps_dest = b.createTriOp(spv::Op::OpSelect, float_type_, pred_cond, dest, + b.createLoad(ps_)); + } + b.createStore(dest, ps_); - StoreToResult(dest, instr.result); + StoreToResult(dest, instr.result, pred_cond); } } @@ -978,7 +1002,8 @@ Id SpirvShaderTranslator::LoadFromOperand(const InstructionOperand& op) { } void SpirvShaderTranslator::StoreToResult(Id source_value_id, - const InstructionResult& result) { + const InstructionResult& result, + Id predicate_cond) { auto& b = *builder_; if (result.storage_target == InstructionStorageTarget::kNone) { @@ -1153,6 +1178,14 @@ void SpirvShaderTranslator::StoreToResult(Id source_value_id, // Perform store into the pointer. assert_true(b.getNumComponents(source_value_id) == b.getNumTypeComponents(storage_type)); + + // Discard if predicate condition is false. + if (predicate_cond) { + source_value_id = + b.createTriOp(spv::Op::OpSelect, storage_type, predicate_cond, + source_value_id, storage_value); + } + b.createStore(source_value_id, storage_pointer); } diff --git a/src/xenia/gpu/spirv_shader_translator.h b/src/xenia/gpu/spirv_shader_translator.h index fbd3af8cd..f56325fc6 100644 --- a/src/xenia/gpu/spirv_shader_translator.h +++ b/src/xenia/gpu/spirv_shader_translator.h @@ -71,7 +71,8 @@ class SpirvShaderTranslator : public ShaderTranslator { // Stores a value based on the specified result information. // The value will be transformed into the appropriate form for the result and // the proper components will be selected. - void StoreToResult(spv::Id source_value_id, const InstructionResult& result); + void StoreToResult(spv::Id source_value_id, const InstructionResult& result, + spv::Id predicate_cond = 0); xe::ui::spirv::SpirvDisassembler disassembler_; From 2629ae4a14447d4877713a1f87373da6136384f9 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sat, 20 Feb 2016 21:55:32 -0600 Subject: [PATCH 3/3] Fix using incorrect result types for compares --- src/xenia/gpu/spirv_shader_translator.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index f3997266d..f8cf69af9 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -566,7 +566,7 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( case AluVectorOpcode::kSge: { // foreach(el) src0 >= src1 ? 1.0 : 0.0 - auto c = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, vec4_float_type_, + auto c = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, vec4_bool_type_, sources[0], sources[1]); dest = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, c, vec4_float_one_, vec4_float_zero_); @@ -574,7 +574,7 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( case AluVectorOpcode::kSgt: { // foreach(el) src0 > src1 ? 1.0 : 0.0 - auto c = b.createBinOp(spv::Op::OpFOrdGreaterThan, vec4_float_type_, + auto c = b.createBinOp(spv::Op::OpFOrdGreaterThan, vec4_bool_type_, sources[0], sources[1]); dest = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, c, vec4_float_one_, vec4_float_zero_); @@ -582,7 +582,7 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( case AluVectorOpcode::kSne: { // foreach(el) src0 != src1 ? 1.0 : 0.0 - auto c = b.createBinOp(spv::Op::OpFOrdNotEqual, vec4_float_type_, + auto c = b.createBinOp(spv::Op::OpFOrdNotEqual, vec4_bool_type_, sources[0], sources[1]); dest = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, c, vec4_float_one_, vec4_float_zero_); @@ -726,7 +726,7 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( case AluScalarOpcode::kRsq: { // dest = src0 != 0.0 ? inversesqrt(src0) : 0.0; - auto c = b.createBinOp(spv::Op::OpFOrdEqual, float_type_, sources[0], + auto c = b.createBinOp(spv::Op::OpFOrdEqual, bool_type_, sources[0], b.makeFloatConstant(0.f)); auto d = CreateGlslStd450InstructionCall( spv::Decoration::DecorationInvariant, vec4_float_type_,