From 633746b5e4c635574408ca6210021b5c30483055 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 15:38:10 -0600 Subject: [PATCH 01/16] Actually preserve pv/ps if predicate fails --- src/xenia/gpu/spirv_shader_translator.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 5684a24e3..a36b8dfca 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -720,7 +720,7 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( dest, b.createLoad(pv_)); } - b.createStore(dest, pv_); + b.createStore(pv_dest, pv_); StoreToResult(dest, instr.result, pred_cond); } } @@ -970,7 +970,7 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( b.createLoad(ps_)); } - b.createStore(dest, ps_); + b.createStore(ps_dest, ps_); StoreToResult(dest, instr.result, pred_cond); } } @@ -1200,7 +1200,12 @@ void SpirvShaderTranslator::StoreToResult(Id source_value_id, storage_pointer = b.createAccessChain(storage_class, storage_pointer, storage_offsets); } - auto storage_value = b.createLoad(storage_pointer); + + // Only load from storage if we need it later. + Id storage_value = 0; + if (!result.has_all_writes() || predicate_cond) { + b.createLoad(storage_pointer); + } // Convert to the appropriate type, if needed. if (b.getTypeId(source_value_id) != storage_type) { From e78537571f81a4010f712204d57ae9303e73973c Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 16:13:13 -0600 Subject: [PATCH 02/16] 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_)); } From 9b805b929e403497fb23975aea0ebd2f10222ac9 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 16:17:43 -0600 Subject: [PATCH 03/16] 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_)); } From d2e3b5533d27aa86a080d0e1a27c2e2c43e5bc5e Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 16:29:12 -0600 Subject: [PATCH 04/16] Whoops --- src/xenia/gpu/spirv_shader_translator.cc | 60 ++++++++++++++++++------ 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 5b146ce8d..9d1253353 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -596,9 +596,12 @@ 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)); + Id pred_cond = 0; + if (instr.is_predicated) { + pred_cond = + b.createBinOp(spv::Op::OpLogicalEqual, bool_type_, b.createLoad(p0_), + b.makeBoolConstant(instr.predicate_condition)); + } switch (instr.vector_opcode) { case AluVectorOpcode::kAdd: { @@ -656,7 +659,10 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( 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); + if (pred_cond) { + cond = + b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + } b.createConditionalBranch(cond, kill_block, continue_block); b.setBuildPoint(kill_block); @@ -672,7 +678,10 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( 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); + if (pred_cond) { + cond = + b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + } b.createConditionalBranch(cond, kill_block, continue_block); b.setBuildPoint(kill_block); @@ -688,7 +697,10 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( 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); + if (pred_cond) { + cond = + b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + } b.createConditionalBranch(cond, kill_block, continue_block); b.setBuildPoint(kill_block); @@ -704,7 +716,10 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( 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); + if (pred_cond) { + cond = + b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + } b.createConditionalBranch(cond, kill_block, continue_block); b.setBuildPoint(kill_block); @@ -831,9 +846,12 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( } } - Id pred_cond = - b.createBinOp(spv::Op::OpLogicalEqual, bool_type_, b.createLoad(p0_), - b.makeBoolConstant(instr.predicate_condition)); + Id pred_cond = 0; + if (instr.is_predicated) { + pred_cond = + b.createBinOp(spv::Op::OpLogicalEqual, bool_type_, b.createLoad(p0_), + b.makeBoolConstant(instr.predicate_condition)); + } switch (instr.scalar_opcode) { case AluScalarOpcode::kAdds: @@ -876,7 +894,10 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( 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); + if (pred_cond) { + cond = + b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + } b.createConditionalBranch(cond, kill_block, continue_block); b.setBuildPoint(kill_block); @@ -891,7 +912,10 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( 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); + if (pred_cond) { + cond = + b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + } b.createConditionalBranch(cond, kill_block, continue_block); b.setBuildPoint(kill_block); @@ -906,7 +930,10 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( 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); + if (pred_cond) { + cond = + b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + } b.createConditionalBranch(cond, kill_block, continue_block); b.setBuildPoint(kill_block); @@ -921,7 +948,10 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( 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); + if (pred_cond) { + cond = + b.createBinOp(spv::Op::OpLogicalAnd, bool_type_, cond, pred_cond); + } b.createConditionalBranch(cond, kill_block, continue_block); b.setBuildPoint(kill_block); @@ -1345,7 +1375,7 @@ void SpirvShaderTranslator::StoreToResult(Id source_value_id, // Only load from storage if we need it later. Id storage_value = 0; if (!result.has_all_writes() || predicate_cond) { - b.createLoad(storage_pointer); + storage_value = b.createLoad(storage_pointer); } // Convert to the appropriate type, if needed. From fa3ca4a5d7c806b3ea16e43e26a0c3e67aa16ff3 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 16:30:57 -0600 Subject: [PATCH 05/16] Short-circuit if the store has no writes. --- src/xenia/gpu/spirv_shader_translator.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 9d1253353..bff854a87 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -1289,6 +1289,10 @@ void SpirvShaderTranslator::StoreToResult(Id source_value_id, return; } + if (!result.has_any_writes()) { + return; + } + Id storage_pointer = 0; Id storage_type = vec4_float_type_; spv::StorageClass storage_class; From d217f7b3c34786642193717aa034cb37a6f2a0ee Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 16:39:54 -0600 Subject: [PATCH 06/16] MaxAs/SetpClr --- src/xenia/gpu/spirv_shader_translator.cc | 24 ++++++++++++++++++++++++ src/xenia/gpu/spirv_shader_translator.h | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index bff854a87..9fd4ba10d 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -54,6 +54,7 @@ void SpirvShaderTranslator::StartTranslation() { bool_type_ = b.makeBoolType(); float_type_ = b.makeFloatType(32); + int_type_ = b.makeIntType(32); Id uint_type = b.makeUintType(32); vec2_float_type_ = b.makeVectorType(float_type_, 2); vec3_float_type_ = b.makeVectorType(float_type_, 3); @@ -961,6 +962,24 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( dest = b.makeFloatConstant(0.f); } break; + case AluScalarOpcode::kMaxAs: { + // a0 = clamp(floor(src0 + 0.5), -256, 255) + auto addr = b.createBinOp(spv::Op::OpFAdd, float_type_, sources[0], + b.makeFloatConstant(0.5f)); + addr = b.createUnaryOp(spv::Op::OpConvertFToS, int_type_, addr); + addr = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, int_type_, + spv::GLSLstd450::kSClamp, + {addr, b.makeIntConstant(-256), b.makeIntConstant(255)}); + b.createStore(addr, a0_); + + // dest = src0 >= src1 ? src0 : src1 + auto cond = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, bool_type_, + sources[0], sources[1]); + dest = b.createTriOp(spv::Op::OpSelect, float_type_, cond, sources[0], + sources[1]); + } break; + case AluScalarOpcode::kMaxs: { // dest = max(src0, src1) dest = CreateGlslStd450InstructionCall( @@ -1050,6 +1069,11 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( b.makeFloatConstant(1.f), b.makeFloatConstant(0.f)); } break; + case AluScalarOpcode::kSetpClr: { + b.createStore(b.makeBoolConstant(false), p0_); + dest = b.makeFloatConstant(FLT_MAX); + } break; + case AluScalarOpcode::kSetpEq: { auto cond = b.createBinOp(spv::Op::OpFOrdEqual, bool_type_, sources[0], b.makeFloatConstant(0.f)); diff --git a/src/xenia/gpu/spirv_shader_translator.h b/src/xenia/gpu/spirv_shader_translator.h index 1ec006d50..31894a901 100644 --- a/src/xenia/gpu/spirv_shader_translator.h +++ b/src/xenia/gpu/spirv_shader_translator.h @@ -104,7 +104,7 @@ class SpirvShaderTranslator : public ShaderTranslator { spv::Function* translated_main_ = 0; // Types. - spv::Id float_type_ = 0, bool_type_ = 0; + spv::Id float_type_ = 0, bool_type_ = 0, int_type_ = 0; spv::Id vec2_float_type_ = 0, vec3_float_type_ = 0, vec4_float_type_ = 0; spv::Id vec4_uint_type_ = 0; spv::Id vec4_bool_type_ = 0; From 3877afe90a68f922f8ffcb26fccb77029cdf8e93 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 16:42:58 -0600 Subject: [PATCH 07/16] MaxAsf --- src/xenia/gpu/spirv_shader_translator.cc | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 9fd4ba10d..bccd797d1 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -962,6 +962,21 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( dest = b.makeFloatConstant(0.f); } break; + case AluScalarOpcode::kMaxAsf: { + auto addr = + b.createUnaryOp(spv::Op::OpConvertFToS, int_type_, sources[0]); + addr = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, int_type_, + spv::GLSLstd450::kSClamp, + {addr, b.makeIntConstant(-256), b.makeIntConstant(255)}); + b.createStore(addr, a0_); + + // dest = src0 >= src1 ? src0 : src1 + dest = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, float_type_, + spv::GLSLstd450::kFMax, {sources[0], sources[1]}); + } break; + case AluScalarOpcode::kMaxAs: { // a0 = clamp(floor(src0 + 0.5), -256, 255) auto addr = b.createBinOp(spv::Op::OpFAdd, float_type_, sources[0], @@ -974,10 +989,9 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( b.createStore(addr, a0_); // dest = src0 >= src1 ? src0 : src1 - auto cond = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, bool_type_, - sources[0], sources[1]); - dest = b.createTriOp(spv::Op::OpSelect, float_type_, cond, sources[0], - sources[1]); + dest = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, float_type_, + spv::GLSLstd450::kFMax, {sources[0], sources[1]}); } break; case AluScalarOpcode::kMaxs: { From 568845e81db9c1e13babb2896d6c0582c2bb774b Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 16:47:06 -0600 Subject: [PATCH 08/16] Dp4 --- src/xenia/gpu/spirv_shader_translator.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index bccd797d1..da1d88850 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -642,6 +642,10 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( // TODO } break; + case AluVectorOpcode::kDp4: { + dest = b.createBinOp(spv::Op::OpDot, float_type_, sources[0], sources[1]); + } break; + case AluVectorOpcode::kFloor: { dest = CreateGlslStd450InstructionCall( spv::Decoration::DecorationInvariant, vec4_float_type_, From 1d4190af02a7ed36ddde98e4647bf1fcfcc71c9a Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 16:52:43 -0600 Subject: [PATCH 09/16] MaxA --- src/xenia/gpu/spirv_shader_translator.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index da1d88850..1c829ddec 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -740,6 +740,24 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( dest = b.createBinOp(spv::Op::OpFAdd, vec4_float_type_, dest, sources[2]); } break; + case AluVectorOpcode::kMaxA: { + // a0 = clamp(floor(src0.w + 0.5), -256, 255) + auto addr = b.createCompositeExtract(sources[0], float_type_, 3); + addr = b.createBinOp(spv::Op::OpFAdd, float_type_, addr, + b.makeFloatConstant(0.5f)); + addr = b.createUnaryOp(spv::Op::OpConvertFToS, int_type_, addr); + addr = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, int_type_, + spv::GLSLstd450::kSClamp, + {addr, b.makeIntConstant(-256), b.makeIntConstant(255)}); + b.createStore(addr, a0_); + + // dest = src0 >= src1 ? src0 : src1 + dest = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, vec4_float_type_, + spv::GLSLstd450::kFMax, {sources[0], sources[1]}); + } break; + case AluVectorOpcode::kMax: { dest = CreateGlslStd450InstructionCall( spv::Decoration::DecorationInvariant, vec4_float_type_, From 13049912ee91a014b71cdf5b71162eb2b05260a9 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 17:12:08 -0600 Subject: [PATCH 10/16] Vec Log --- src/xenia/gpu/spirv_shader_translator.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 1c829ddec..ed03d29e0 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -740,6 +740,9 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( dest = b.createBinOp(spv::Op::OpFAdd, vec4_float_type_, dest, sources[2]); } break; + case AluVectorOpcode::kMax4: { + } break; + case AluVectorOpcode::kMaxA: { // a0 = clamp(floor(src0.w + 0.5), -256, 255) auto addr = b.createCompositeExtract(sources[0], float_type_, 3); @@ -984,6 +987,15 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( dest = b.makeFloatConstant(0.f); } break; + case AluScalarOpcode::kLogc: { + } break; + + case AluScalarOpcode::kLog: { + auto log = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, float_type_, + spv::GLSLstd450::kLog2, {sources[0]}); + } break; + case AluScalarOpcode::kMaxAsf: { auto addr = b.createUnaryOp(spv::Op::OpConvertFToS, int_type_, sources[0]); From cbac9b2f4e2fb84704ec10be4253d248b4b22f1a Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 17:39:18 -0600 Subject: [PATCH 11/16] Use vec4 zero rather than float zero where needed --- src/xenia/gpu/spirv_shader_translator.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index ed03d29e0..644e766ef 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -613,7 +613,7 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( case AluVectorOpcode::kCndEq: { // dest = src0 == 0.0 ? src1 : src2; auto c = b.createBinOp(spv::Op::OpFOrdEqual, vec4_bool_type_, sources[0], - b.makeFloatConstant(0.f)); + vec4_float_zero_); dest = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, c, sources[1], sources[2]); } break; @@ -621,7 +621,7 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( case AluVectorOpcode::kCndGe: { // dest = src0 == 0.0 ? src1 : src2; auto c = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, vec4_bool_type_, - sources[0], b.makeFloatConstant(0.f)); + sources[0], vec4_float_zero_); dest = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, c, sources[1], sources[2]); } break; @@ -629,7 +629,7 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( case AluVectorOpcode::kCndGt: { // dest = src0 == 0.0 ? src1 : src2; auto c = b.createBinOp(spv::Op::OpFOrdGreaterThan, vec4_bool_type_, - sources[0], b.makeFloatConstant(0.f)); + sources[0], vec4_float_zero_); dest = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, c, sources[1], sources[2]); } break; @@ -1184,6 +1184,12 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( b.makeFloatConstant(0.f), b.makeFloatConstant(1.f)); } break; + case AluScalarOpcode::kSetpPop: { + } break; + + case AluScalarOpcode::kSetpRstr: { + } break; + case AluScalarOpcode::kSin: { dest = CreateGlslStd450InstructionCall( spv::Decoration::DecorationInvariant, float_type_, GLSLstd450::kSin, From 0680e451bc8a0c1e9ef1b65b5572d84ff871aa7d Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 17:59:59 -0600 Subject: [PATCH 12/16] Exp2 --- src/xenia/gpu/spirv_shader_translator.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 644e766ef..4370d020e 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -900,6 +900,12 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( {sources[0]}); } break; + case AluScalarOpcode::kExp: { + dest = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, float_type_, GLSLstd450::kExp2, + {sources[0]}); + } break; + case AluScalarOpcode::kKillsEq: { auto continue_block = &b.makeNewBlock(); auto kill_block = &b.makeNewBlock(); From 5c2b5123ac166b1e6eb960bc9ffc9ce605e91ec4 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 18:15:11 -0600 Subject: [PATCH 13/16] Floors/Frcs/Truncs --- src/xenia/gpu/spirv_shader_translator.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 4370d020e..1f3140ed8 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -906,6 +906,18 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( {sources[0]}); } break; + case AluScalarOpcode::kFloors: { + dest = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, float_type_, GLSLstd450::kFloor, + {sources[0]}); + } break; + + case AluScalarOpcode::kFrcs: { + dest = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, float_type_, GLSLstd450::kFract, + {sources[0]}); + } break; + case AluScalarOpcode::kKillsEq: { auto continue_block = &b.makeNewBlock(); auto kill_block = &b.makeNewBlock(); @@ -1213,6 +1225,12 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( dest = b.createBinOp(spv::Op::OpFSub, float_type_, sources[0], ps_); } break; + case AluScalarOpcode::kTruncs: { + dest = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, float_type_, GLSLstd450::kTrunc, + {sources[0]}); + } break; + default: break; } From 9030c87386efd215c8d4ed27ae4ae07c700b26c4 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 18:52:49 -0600 Subject: [PATCH 14/16] SetpPop/SetpRstr --- src/xenia/gpu/spirv_shader_translator.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 1f3140ed8..b4e49a1ca 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -1203,9 +1203,22 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction( } break; case AluScalarOpcode::kSetpPop: { + auto src = b.createBinOp(spv::Op::OpFSub, float_type_, sources[0], + b.makeFloatConstant(1.f)); + auto c = b.createBinOp(spv::Op::OpFOrdLessThanEqual, bool_type_, src, + b.makeFloatConstant(0.f)); + b.createStore(c, p0_); + + dest = CreateGlslStd450InstructionCall( + spv::Decoration::DecorationInvariant, float_type_, GLSLstd450::kFMax, + {sources[0], b.makeFloatConstant(0.f)}); } break; case AluScalarOpcode::kSetpRstr: { + auto c = b.createBinOp(spv::Op::OpFOrdEqual, bool_type_, sources[0], + b.makeFloatConstant(0.f)); + b.createStore(c, p0_); + dest = sources[0]; } break; case AluScalarOpcode::kSin: { From 2785a94fea1f8d69ee4a376ed5693a5fbbae2475 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 19:10:24 -0600 Subject: [PATCH 15/16] SetpXXPush --- src/xenia/gpu/spirv_shader_translator.cc | 96 ++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index b4e49a1ca..fcf862fda 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -778,6 +778,102 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction( sources[1]); } break; + case AluVectorOpcode::kSetpEqPush: { + auto c0 = b.createBinOp(spv::Op::OpFOrdEqual, vec4_bool_type_, sources[0], + vec4_float_zero_); + auto c1 = b.createBinOp(spv::Op::OpFOrdEqual, vec4_bool_type_, sources[1], + vec4_float_zero_); + auto c_and = + b.createBinOp(spv::Op::OpLogicalAnd, vec4_bool_type_, c0, c1); + auto c_and_x = b.createCompositeExtract(c_and, bool_type_, 0); + auto c_and_w = b.createCompositeExtract(c_and, bool_type_, 3); + + // p0 + b.createStore(c_and_w, p0_); + + // dest + auto s0_x = b.createCompositeExtract(sources[0], float_type_, 0); + s0_x = b.createBinOp(spv::Op::OpFAdd, float_type_, s0_x, + b.makeFloatConstant(1.f)); + auto s0 = b.smearScalar(spv::Decoration::DecorationInvariant, s0_x, + vec4_float_type_); + + dest = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, c_and_x, + vec4_float_zero_, s0); + } break; + + case AluVectorOpcode::kSetpGePush: { + auto c0 = b.createBinOp(spv::Op::OpFOrdEqual, vec4_bool_type_, sources[0], + vec4_float_zero_); + auto c1 = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, vec4_bool_type_, + sources[1], vec4_float_zero_); + auto c_and = + b.createBinOp(spv::Op::OpLogicalAnd, vec4_bool_type_, c0, c1); + auto c_and_x = b.createCompositeExtract(c_and, bool_type_, 0); + auto c_and_w = b.createCompositeExtract(c_and, bool_type_, 3); + + // p0 + b.createStore(c_and_w, p0_); + + // dest + auto s0_x = b.createCompositeExtract(sources[0], float_type_, 0); + s0_x = b.createBinOp(spv::Op::OpFAdd, float_type_, s0_x, + b.makeFloatConstant(1.f)); + auto s0 = b.smearScalar(spv::Decoration::DecorationInvariant, s0_x, + vec4_float_type_); + + dest = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, c_and_x, + vec4_float_zero_, s0); + } break; + + case AluVectorOpcode::kSetpGtPush: { + auto c0 = b.createBinOp(spv::Op::OpFOrdEqual, vec4_bool_type_, sources[0], + vec4_float_zero_); + auto c1 = b.createBinOp(spv::Op::OpFOrdGreaterThan, vec4_bool_type_, + sources[1], vec4_float_zero_); + auto c_and = + b.createBinOp(spv::Op::OpLogicalAnd, vec4_bool_type_, c0, c1); + auto c_and_x = b.createCompositeExtract(c_and, bool_type_, 0); + auto c_and_w = b.createCompositeExtract(c_and, bool_type_, 3); + + // p0 + b.createStore(c_and_w, p0_); + + // dest + auto s0_x = b.createCompositeExtract(sources[0], float_type_, 0); + s0_x = b.createBinOp(spv::Op::OpFAdd, float_type_, s0_x, + b.makeFloatConstant(1.f)); + auto s0 = b.smearScalar(spv::Decoration::DecorationInvariant, s0_x, + vec4_float_type_); + + dest = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, c_and_x, + vec4_float_zero_, s0); + } break; + + case AluVectorOpcode::kSetpNePush: { + auto c0 = b.createBinOp(spv::Op::OpFOrdNotEqual, vec4_bool_type_, + sources[0], vec4_float_zero_); + auto c1 = b.createBinOp(spv::Op::OpFOrdEqual, vec4_bool_type_, sources[1], + vec4_float_zero_); + auto c_and = + b.createBinOp(spv::Op::OpLogicalAnd, vec4_bool_type_, c0, c1); + auto c_and_x = b.createCompositeExtract(c_and, bool_type_, 0); + auto c_and_w = b.createCompositeExtract(c_and, bool_type_, 3); + + // p0 + b.createStore(c_and_w, p0_); + + // dest + auto s0_x = b.createCompositeExtract(sources[0], float_type_, 0); + s0_x = b.createBinOp(spv::Op::OpFAdd, float_type_, s0_x, + b.makeFloatConstant(1.f)); + auto s0 = b.smearScalar(spv::Decoration::DecorationInvariant, s0_x, + vec4_float_type_); + + dest = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, c_and_x, + vec4_float_zero_, s0); + } break; + case AluVectorOpcode::kSeq: { // foreach(el) src0 == src1 ? 1.0 : 0.0 auto c = b.createBinOp(spv::Op::OpFOrdEqual, vec4_bool_type_, sources[0], From 8a29330f8c40533404510a0168f9105fdb68eddd Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 21 Feb 2016 20:42:37 -0600 Subject: [PATCH 16/16] First-pass image sampling --- src/xenia/gpu/spirv_shader_translator.cc | 94 +++++++++++++++++++++++- src/xenia/gpu/spirv_shader_translator.h | 3 + 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index fcf862fda..8c2057242 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -163,6 +163,46 @@ void SpirvShaderTranslator::StartTranslation() { push_consts_ = b.createVariable(spv::StorageClass::StorageClassPushConstant, push_constants_type, "push_consts"); + // Texture bindings + Id img_t[] = { + b.makeImageType(float_type_, spv::Dim::Dim1D, false, false, false, 1, + spv::ImageFormat::ImageFormatUnknown), + b.makeImageType(float_type_, spv::Dim::Dim2D, false, false, false, 1, + spv::ImageFormat::ImageFormatUnknown), + b.makeImageType(float_type_, spv::Dim::Dim3D, false, false, false, 1, + spv::ImageFormat::ImageFormatUnknown), + b.makeImageType(float_type_, spv::Dim::DimCube, false, false, false, 1, + spv::ImageFormat::ImageFormatUnknown)}; + Id samplers_t = b.makeSamplerType(); + + Id img_a_t[] = {b.makeArrayType(img_t[0], b.makeUintConstant(32), 0), + b.makeArrayType(img_t[1], b.makeUintConstant(32), 0), + b.makeArrayType(img_t[2], b.makeUintConstant(32), 0), + b.makeArrayType(img_t[3], b.makeUintConstant(32), 0)}; + Id samplers_a = b.makeArrayType(samplers_t, b.makeUintConstant(32), 0); + + Id img_s[] = { + b.makeStructType({img_a_t[0]}, "img1D_type"), + b.makeStructType({img_a_t[1]}, "img2D_type"), + b.makeStructType({img_a_t[2]}, "img3D_type"), + b.makeStructType({img_a_t[3]}, "imgCube_type"), + }; + Id samplers_s = b.makeStructType({samplers_a}, "samplers_type"); + + for (int i = 0; i < 4; i++) { + img_[i] = b.createVariable(spv::StorageClass::StorageClassUniformConstant, + img_s[i], + xe::format_string("images%dD", i + 1).c_str()); + b.addDecoration(img_[i], spv::Decoration::DecorationBlock); + b.addDecoration(img_[i], spv::Decoration::DecorationDescriptorSet, 2); + b.addDecoration(img_[i], spv::Decoration::DecorationBinding, i + 1); + } + samplers_ = b.createVariable(spv::StorageClass::StorageClassUniformConstant, + samplers_s, "samplers"); + b.addDecoration(samplers_, spv::Decoration::DecorationBlock); + b.addDecoration(samplers_, spv::Decoration::DecorationDescriptorSet, 2); + b.addDecoration(samplers_, spv::Decoration::DecorationBinding, 0); + // Interpolators. Id interpolators_type = b.makeArrayType(vec4_float_type_, b.makeUintConstant(16), 0); @@ -552,6 +592,8 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction( const ParsedVertexFetchInstruction& instr) { auto& b = *builder_; + // TODO: instr.is_predicated + // Operand 0 is the index // Operand 1 is the binding // TODO: Indexed fetch @@ -568,7 +610,57 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( const ParsedTextureFetchInstruction& instr) { auto& b = *builder_; - EmitUnimplementedTranslationError(); + // TODO: instr.is_predicated + // Operand 0 is the offset + // Operand 1 is the sampler index + Id dest = 0; + Id src = LoadFromOperand(instr.operands[0]); + assert_not_zero(src); + + uint32_t dim_idx = 0; + switch (instr.dimension) { + case TextureDimension::k1D: + dim_idx = 0; + break; + case TextureDimension::k2D: + dim_idx = 1; + break; + case TextureDimension::k3D: + dim_idx = 2; + break; + case TextureDimension::kCube: + dim_idx = 3; + break; + default: + assert_unhandled_case(instr.dimension); + } + + switch (instr.opcode) { + case FetchOpcode::kTextureFetch: { + auto image_index = b.makeUintConstant(instr.operands[1].storage_index); + auto image_ptr = + b.createAccessChain(spv::StorageClass::StorageClassUniformConstant, + img_[dim_idx], std::vector({image_index})); + auto sampler_ptr = + b.createAccessChain(spv::StorageClass::StorageClassUniformConstant, + samplers_, std::vector({image_index})); + auto image = b.createLoad(image_ptr); + auto sampler = b.createLoad(sampler_ptr); + + auto tex = b.createBinOp(spv::Op::OpSampledImage, b.getImageType(image), + image, sampler); + dest = b.createBinOp(spv::Op::OpImageSampleImplicitLod, vec4_float_type_, + tex, src); + } break; + default: + // TODO: the rest of these + break; + } + + if (dest) { + b.createStore(dest, pv_); + StoreToResult(dest, instr.result); + } } void SpirvShaderTranslator::ProcessAluInstruction( diff --git a/src/xenia/gpu/spirv_shader_translator.h b/src/xenia/gpu/spirv_shader_translator.h index 31894a901..0d8b1e14c 100644 --- a/src/xenia/gpu/spirv_shader_translator.h +++ b/src/xenia/gpu/spirv_shader_translator.h @@ -108,6 +108,7 @@ class SpirvShaderTranslator : public ShaderTranslator { spv::Id vec2_float_type_ = 0, vec3_float_type_ = 0, vec4_float_type_ = 0; spv::Id vec4_uint_type_ = 0; spv::Id vec4_bool_type_ = 0; + spv::Id sampled_image_type_ = 0; // Constants. spv::Id vec4_float_zero_ = 0, vec4_float_one_ = 0; @@ -121,6 +122,8 @@ class SpirvShaderTranslator : public ShaderTranslator { spv::Id push_consts_ = 0; spv::Id interpolators_ = 0; spv::Id frag_outputs_ = 0; + spv::Id samplers_ = 0; + spv::Id img_[4] = {0}; // Images {1D, 2D, 3D, Cube} // Map of {binding -> {offset -> spv input}} std::map> vertex_binding_map_;