From e78537571f81a4010f712204d57ae9303e73973c Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 16:13:13 -0600 Subject: [PATCH] Vector kill ops --- src/xenia/gpu/spirv_shader_translator.cc | 77 ++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index a36b8dfca..fd97c6bf1 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -596,6 +596,10 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( sources[i] = LoadFromOperand(instr.operands[i]); } + Id pred_cond = + b.createBinOp(spv::Op::OpLogicalEqual, bool_type_, b.createLoad(p0_), + b.makeBoolConstant(instr.predicate_condition)); + switch (instr.vector_opcode) { case AluVectorOpcode::kAdd: { dest = b.createBinOp(spv::Op::OpFAdd, vec4_float_type_, sources[0], @@ -630,6 +634,10 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( // TODO: } break; + case AluVectorOpcode::kDst: { + // TODO + } break; + case AluVectorOpcode::kFloor: { dest = CreateGlslStd450InstructionCall( spv::Decoration::DecorationInvariant, vec4_float_type_, @@ -642,6 +650,70 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( spv::GLSLstd450::kFract, {sources[0]}); } break; + case AluVectorOpcode::kKillEq: { + auto continue_block = &b.makeNewBlock(); + auto kill_block = &b.makeNewBlock(); + auto cond = b.createBinOp(spv::Op::OpFOrdEqual, vec4_bool_type_, + sources[0], sources[1]); + cond = b.createUnaryOp(spv::Op::OpAny, bool_type_, cond); + 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 = vec4_float_zero_; + } break; + + case AluVectorOpcode::kKillGe: { + auto continue_block = &b.makeNewBlock(); + auto kill_block = &b.makeNewBlock(); + auto cond = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, + vec4_bool_type_, sources[0], sources[1]); + cond = b.createUnaryOp(spv::Op::OpAny, bool_type_, cond); + 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 = vec4_float_zero_; + } break; + + case AluVectorOpcode::kKillGt: { + auto continue_block = &b.makeNewBlock(); + auto kill_block = &b.makeNewBlock(); + auto cond = b.createBinOp(spv::Op::OpFOrdGreaterThan, vec4_bool_type_, + sources[0], sources[1]); + cond = b.createUnaryOp(spv::Op::OpAny, bool_type_, cond); + 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 = vec4_float_zero_; + } break; + + case AluVectorOpcode::kKillNe: { + auto continue_block = &b.makeNewBlock(); + auto kill_block = &b.makeNewBlock(); + auto cond = b.createBinOp(spv::Op::OpFOrdNotEqual, vec4_bool_type_, + sources[0], sources[1]); + cond = b.createUnaryOp(spv::Op::OpAny, bool_type_, cond); + 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 = vec4_float_zero_; + } break; + case AluVectorOpcode::kMad: { dest = b.createBinOp(spv::Op::OpFMul, vec4_float_type_, sources[0], sources[1]); @@ -709,13 +781,8 @@ 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_)); }