From 9b805b929e403497fb23975aea0ebd2f10222ac9 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 16:17:43 -0600 Subject: [PATCH] Scalar kill ops --- src/xenia/gpu/spirv_shader_translator.cc | 84 ++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index fd97c6bf1..5b146ce8d 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -831,6 +831,10 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( } } + Id pred_cond = + b.createBinOp(spv::Op::OpLogicalEqual, bool_type_, b.createLoad(p0_), + b.makeBoolConstant(instr.predicate_condition)); + switch (instr.scalar_opcode) { case AluScalarOpcode::kAdds: case AluScalarOpcode::kAddsc0: @@ -852,6 +856,81 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( {sources[0]}); } break; + case AluScalarOpcode::kKillsEq: { + auto continue_block = &b.makeNewBlock(); + auto kill_block = &b.makeNewBlock(); + auto cond = b.createBinOp(spv::Op::OpFOrdEqual, bool_type_, sources[0], + b.makeFloatConstant(0.f)); + cond = b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + b.createConditionalBranch(cond, kill_block, continue_block); + + b.setBuildPoint(kill_block); + b.createNoResultOp(spv::Op::OpKill); + + b.setBuildPoint(continue_block); + dest = b.makeFloatConstant(0.f); + } break; + + case AluScalarOpcode::kKillsGe: { + auto continue_block = &b.makeNewBlock(); + auto kill_block = &b.makeNewBlock(); + auto cond = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, bool_type_, + sources[0], b.makeFloatConstant(0.f)); + cond = b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + b.createConditionalBranch(cond, kill_block, continue_block); + + b.setBuildPoint(kill_block); + b.createNoResultOp(spv::Op::OpKill); + + b.setBuildPoint(continue_block); + dest = b.makeFloatConstant(0.f); + } break; + + case AluScalarOpcode::kKillsGt: { + auto continue_block = &b.makeNewBlock(); + auto kill_block = &b.makeNewBlock(); + auto cond = b.createBinOp(spv::Op::OpFOrdGreaterThan, bool_type_, + sources[0], b.makeFloatConstant(0.f)); + cond = b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + b.createConditionalBranch(cond, kill_block, continue_block); + + b.setBuildPoint(kill_block); + b.createNoResultOp(spv::Op::OpKill); + + b.setBuildPoint(continue_block); + dest = b.makeFloatConstant(0.f); + } break; + + case AluScalarOpcode::kKillsNe: { + auto continue_block = &b.makeNewBlock(); + auto kill_block = &b.makeNewBlock(); + auto cond = b.createBinOp(spv::Op::OpFOrdNotEqual, bool_type_, sources[0], + b.makeFloatConstant(0.f)); + cond = b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + b.createConditionalBranch(cond, kill_block, continue_block); + + b.setBuildPoint(kill_block); + b.createNoResultOp(spv::Op::OpKill); + + b.setBuildPoint(continue_block); + dest = b.makeFloatConstant(0.f); + } break; + + case AluScalarOpcode::kKillsOne: { + auto continue_block = &b.makeNewBlock(); + auto kill_block = &b.makeNewBlock(); + auto cond = b.createBinOp(spv::Op::OpFOrdEqual, bool_type_, sources[0], + b.makeFloatConstant(1.f)); + cond = b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + b.createConditionalBranch(cond, kill_block, continue_block); + + b.setBuildPoint(kill_block); + b.createNoResultOp(spv::Op::OpKill); + + b.setBuildPoint(continue_block); + dest = b.makeFloatConstant(0.f); + } break; + case AluScalarOpcode::kMaxs: { // dest = max(src0, src1) dest = CreateGlslStd450InstructionCall( @@ -1026,13 +1105,8 @@ 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_)); }