diff options
Diffstat (limited to 'src/video_core/shader/shader_interpreter.cpp')
-rw-r--r-- | src/video_core/shader/shader_interpreter.cpp | 290 |
1 files changed, 147 insertions, 143 deletions
diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp index f6c86a759..681ff9728 100644 --- a/src/video_core/shader/shader_interpreter.cpp +++ b/src/video_core/shader/shader_interpreter.cpp @@ -40,7 +40,7 @@ struct CallStackElement { u32 loop_address; // The address where we'll return to after each loop iteration }; -template<bool Debug> +template <bool Debug> void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned offset) { // TODO: Is there a maximal size for this? boost::container::static_vector<CallStackElement, 16> call_stack; @@ -74,14 +74,18 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned } } - const Instruction instr = { program_code[program_counter] }; - const SwizzlePattern swizzle = { swizzle_data[instr.common.operand_desc_id] }; + const Instruction instr = {program_code[program_counter]}; + const SwizzlePattern swizzle = {swizzle_data[instr.common.operand_desc_id]}; - auto call = [&program_counter, &call_stack](UnitState<Debug>& state, u32 offset, u32 num_instructions, - u32 return_offset, u8 repeat_count, u8 loop_increment) { - program_counter = offset - 1; // -1 to make sure when incrementing the PC we end up at the correct offset + auto call = [&program_counter, &call_stack](UnitState<Debug>& state, u32 offset, + u32 num_instructions, u32 return_offset, + u8 repeat_count, u8 loop_increment) { + program_counter = + offset - + 1; // -1 to make sure when incrementing the PC we end up at the correct offset ASSERT(call_stack.size() < call_stack.capacity()); - call_stack.push_back({ offset + num_instructions, return_offset, repeat_count, loop_increment, offset }); + call_stack.push_back( + {offset + num_instructions, return_offset, repeat_count, loop_increment, offset}); }; Record<DebugDataRecord::CUR_INSTR>(state.debug, iteration, program_counter); if (iteration > 0) @@ -106,24 +110,26 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned }; switch (instr.opcode.Value().GetInfo().type) { - case OpCode::Type::Arithmetic: - { - const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); + case OpCode::Type::Arithmetic: { + const bool is_inverted = + (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); - const int address_offset = (instr.common.address_register_index == 0) - ? 0 : state.address_registers[instr.common.address_register_index - 1]; + const int address_offset = + (instr.common.address_register_index == 0) + ? 0 + : state.address_registers[instr.common.address_register_index - 1]; - const float24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) + (!is_inverted * address_offset)); - const float24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted) + ( is_inverted * address_offset)); + const float24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) + + (!is_inverted * address_offset)); + const float24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted) + + (is_inverted * address_offset)); const bool negate_src1 = ((bool)swizzle.negate_src1 != false); const bool negate_src2 = ((bool)swizzle.negate_src2 != false); float24 src1[4] = { - src1_[(int)swizzle.GetSelectorSrc1(0)], - src1_[(int)swizzle.GetSelectorSrc1(1)], - src1_[(int)swizzle.GetSelectorSrc1(2)], - src1_[(int)swizzle.GetSelectorSrc1(3)], + src1_[(int)swizzle.GetSelectorSrc1(0)], src1_[(int)swizzle.GetSelectorSrc1(1)], + src1_[(int)swizzle.GetSelectorSrc1(2)], src1_[(int)swizzle.GetSelectorSrc1(3)], }; if (negate_src1) { src1[0] = src1[0] * float24::FromFloat32(-1); @@ -132,10 +138,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src1[3] = src1[3] * float24::FromFloat32(-1); } float24 src2[4] = { - src2_[(int)swizzle.GetSelectorSrc2(0)], - src2_[(int)swizzle.GetSelectorSrc2(1)], - src2_[(int)swizzle.GetSelectorSrc2(2)], - src2_[(int)swizzle.GetSelectorSrc2(3)], + src2_[(int)swizzle.GetSelectorSrc2(0)], src2_[(int)swizzle.GetSelectorSrc2(1)], + src2_[(int)swizzle.GetSelectorSrc2(2)], src2_[(int)swizzle.GetSelectorSrc2(3)], }; if (negate_src2) { src2[0] = src2[0] * float24::FromFloat32(-1); @@ -144,15 +148,18 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src2[3] = src2[3] * float24::FromFloat32(-1); } - float24* dest = (instr.common.dest.Value() < 0x10) ? &state.output_registers.value[instr.common.dest.Value().GetIndex()][0] - : (instr.common.dest.Value() < 0x20) ? &state.registers.temporary[instr.common.dest.Value().GetIndex()][0] - : dummy_vec4_float24; + float24* dest = + (instr.common.dest.Value() < 0x10) + ? &state.output_registers.value[instr.common.dest.Value().GetIndex()][0] + : (instr.common.dest.Value() < 0x20) + ? &state.registers.temporary[instr.common.dest.Value().GetIndex()][0] + : dummy_vec4_float24; - state.debug.max_opdesc_id = std::max<u32>(state.debug.max_opdesc_id, 1+instr.common.operand_desc_id); + state.debug.max_opdesc_id = + std::max<u32>(state.debug.max_opdesc_id, 1 + instr.common.operand_desc_id); switch (instr.opcode.Value().EffectiveOpCode()) { - case OpCode::Id::ADD: - { + case OpCode::Id::ADD: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::SRC2>(state.debug, iteration, src2); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); @@ -166,8 +173,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; } - case OpCode::Id::MUL: - { + case OpCode::Id::MUL: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::SRC2>(state.debug, iteration, src2); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); @@ -228,8 +234,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned case OpCode::Id::DP3: case OpCode::Id::DP4: case OpCode::Id::DPH: - case OpCode::Id::DPHI: - { + case OpCode::Id::DPHI: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::SRC2>(state.debug, iteration, src2); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); @@ -239,7 +244,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src1[3] = float24::FromFloat32(1.0f); int num_components = (opcode == OpCode::Id::DP3) ? 3 : 4; - float24 dot = std::inner_product(src1, src1 + num_components, src2, float24::FromFloat32(0.f)); + float24 dot = std::inner_product(src1, src1 + num_components, src2, + float24::FromFloat32(0.f)); for (int i = 0; i < 4; ++i) { if (!swizzle.DestComponentEnabled(i)) @@ -252,8 +258,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned } // Reciprocal - case OpCode::Id::RCP: - { + case OpCode::Id::RCP: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); float24 rcp_res = float24::FromFloat32(1.0f / src1[0].ToFloat32()); @@ -268,8 +273,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned } // Reciprocal Square Root - case OpCode::Id::RSQ: - { + case OpCode::Id::RSQ: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); float24 rsq_res = float24::FromFloat32(1.0f / std::sqrt(src1[0].ToFloat32())); @@ -283,8 +287,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; } - case OpCode::Id::MOVA: - { + case OpCode::Id::MOVA: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); for (int i = 0; i < 2; ++i) { if (!swizzle.DestComponentEnabled(i)) @@ -293,12 +296,12 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned // TODO: Figure out how the rounding is done on hardware state.address_registers[i] = static_cast<s32>(src1[i].ToFloat32()); } - Record<DebugDataRecord::ADDR_REG_OUT>(state.debug, iteration, state.address_registers); + Record<DebugDataRecord::ADDR_REG_OUT>(state.debug, iteration, + state.address_registers); break; } - case OpCode::Id::MOV: - { + case OpCode::Id::MOV: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); for (int i = 0; i < 4; ++i) { @@ -320,7 +323,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned if (!swizzle.DestComponentEnabled(i)) continue; - dest[i] = (src1[i] >= src2[i]) ? float24::FromFloat32(1.0f) : float24::FromFloat32(0.0f); + dest[i] = (src1[i] >= src2[i]) ? float24::FromFloat32(1.0f) + : float24::FromFloat32(0.0f); } Record<DebugDataRecord::DEST_OUT>(state.debug, iteration, dest); break; @@ -334,7 +338,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned if (!swizzle.DestComponentEnabled(i)) continue; - dest[i] = (src1[i] < src2[i]) ? float24::FromFloat32(1.0f) : float24::FromFloat32(0.0f); + dest[i] = (src1[i] < src2[i]) ? float24::FromFloat32(1.0f) + : float24::FromFloat32(0.0f); } Record<DebugDataRecord::DEST_OUT>(state.debug, iteration, dest); break; @@ -349,40 +354,39 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned auto op = (i == 0) ? compare_op.x.Value() : compare_op.y.Value(); switch (op) { - case Instruction::Common::CompareOpType::Equal: - state.conditional_code[i] = (src1[i] == src2[i]); - break; + case Instruction::Common::CompareOpType::Equal: + state.conditional_code[i] = (src1[i] == src2[i]); + break; - case Instruction::Common::CompareOpType::NotEqual: - state.conditional_code[i] = (src1[i] != src2[i]); - break; + case Instruction::Common::CompareOpType::NotEqual: + state.conditional_code[i] = (src1[i] != src2[i]); + break; - case Instruction::Common::CompareOpType::LessThan: - state.conditional_code[i] = (src1[i] < src2[i]); - break; + case Instruction::Common::CompareOpType::LessThan: + state.conditional_code[i] = (src1[i] < src2[i]); + break; - case Instruction::Common::CompareOpType::LessEqual: - state.conditional_code[i] = (src1[i] <= src2[i]); - break; + case Instruction::Common::CompareOpType::LessEqual: + state.conditional_code[i] = (src1[i] <= src2[i]); + break; - case Instruction::Common::CompareOpType::GreaterThan: - state.conditional_code[i] = (src1[i] > src2[i]); - break; + case Instruction::Common::CompareOpType::GreaterThan: + state.conditional_code[i] = (src1[i] > src2[i]); + break; - case Instruction::Common::CompareOpType::GreaterEqual: - state.conditional_code[i] = (src1[i] >= src2[i]); - break; + case Instruction::Common::CompareOpType::GreaterEqual: + state.conditional_code[i] = (src1[i] >= src2[i]); + break; - default: - LOG_ERROR(HW_GPU, "Unknown compare mode %x", static_cast<int>(op)); - break; + default: + LOG_ERROR(HW_GPU, "Unknown compare mode %x", static_cast<int>(op)); + break; } } Record<DebugDataRecord::CMP_RESULT>(state.debug, iteration, state.conditional_code); break; - case OpCode::Id::EX2: - { + case OpCode::Id::EX2: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); @@ -399,8 +403,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; } - case OpCode::Id::LG2: - { + case OpCode::Id::LG2: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); @@ -419,7 +422,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned default: LOG_ERROR(HW_GPU, "Unhandled arithmetic instruction: 0x%02x (%s): 0x%08x", - (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex); + (int)instr.opcode.Value().EffectiveOpCode(), + instr.opcode.Value().GetInfo().name, instr.hex); DEBUG_ASSERT(false); break; } @@ -427,30 +431,32 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; } - case OpCode::Type::MultiplyAdd: - { + case OpCode::Type::MultiplyAdd: { if ((instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD) || (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI)) { - const SwizzlePattern& swizzle = *reinterpret_cast<const SwizzlePattern*>(&swizzle_data[instr.mad.operand_desc_id]); + const SwizzlePattern& swizzle = *reinterpret_cast<const SwizzlePattern*>( + &swizzle_data[instr.mad.operand_desc_id]); bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI); - const int address_offset = (instr.mad.address_register_index == 0) - ? 0 : state.address_registers[instr.mad.address_register_index - 1]; + const int address_offset = + (instr.mad.address_register_index == 0) + ? 0 + : state.address_registers[instr.mad.address_register_index - 1]; const float24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted)); - const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted) + (!is_inverted * address_offset)); - const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) + ( is_inverted * address_offset)); + const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted) + + (!is_inverted * address_offset)); + const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) + + (is_inverted * address_offset)); const bool negate_src1 = ((bool)swizzle.negate_src1 != false); const bool negate_src2 = ((bool)swizzle.negate_src2 != false); const bool negate_src3 = ((bool)swizzle.negate_src3 != false); float24 src1[4] = { - src1_[(int)swizzle.GetSelectorSrc1(0)], - src1_[(int)swizzle.GetSelectorSrc1(1)], - src1_[(int)swizzle.GetSelectorSrc1(2)], - src1_[(int)swizzle.GetSelectorSrc1(3)], + src1_[(int)swizzle.GetSelectorSrc1(0)], src1_[(int)swizzle.GetSelectorSrc1(1)], + src1_[(int)swizzle.GetSelectorSrc1(2)], src1_[(int)swizzle.GetSelectorSrc1(3)], }; if (negate_src1) { src1[0] = src1[0] * float24::FromFloat32(-1); @@ -459,10 +465,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src1[3] = src1[3] * float24::FromFloat32(-1); } float24 src2[4] = { - src2_[(int)swizzle.GetSelectorSrc2(0)], - src2_[(int)swizzle.GetSelectorSrc2(1)], - src2_[(int)swizzle.GetSelectorSrc2(2)], - src2_[(int)swizzle.GetSelectorSrc2(3)], + src2_[(int)swizzle.GetSelectorSrc2(0)], src2_[(int)swizzle.GetSelectorSrc2(1)], + src2_[(int)swizzle.GetSelectorSrc2(2)], src2_[(int)swizzle.GetSelectorSrc2(3)], }; if (negate_src2) { src2[0] = src2[0] * float24::FromFloat32(-1); @@ -471,10 +475,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src2[3] = src2[3] * float24::FromFloat32(-1); } float24 src3[4] = { - src3_[(int)swizzle.GetSelectorSrc3(0)], - src3_[(int)swizzle.GetSelectorSrc3(1)], - src3_[(int)swizzle.GetSelectorSrc3(2)], - src3_[(int)swizzle.GetSelectorSrc3(3)], + src3_[(int)swizzle.GetSelectorSrc3(0)], src3_[(int)swizzle.GetSelectorSrc3(1)], + src3_[(int)swizzle.GetSelectorSrc3(2)], src3_[(int)swizzle.GetSelectorSrc3(3)], }; if (negate_src3) { src3[0] = src3[0] * float24::FromFloat32(-1); @@ -483,9 +485,12 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src3[3] = src3[3] * float24::FromFloat32(-1); } - float24* dest = (instr.mad.dest.Value() < 0x10) ? &state.output_registers.value[instr.mad.dest.Value().GetIndex()][0] - : (instr.mad.dest.Value() < 0x20) ? &state.registers.temporary[instr.mad.dest.Value().GetIndex()][0] - : dummy_vec4_float24; + float24* dest = + (instr.mad.dest.Value() < 0x10) + ? &state.output_registers.value[instr.mad.dest.Value().GetIndex()][0] + : (instr.mad.dest.Value() < 0x20) + ? &state.registers.temporary[instr.mad.dest.Value().GetIndex()][0] + : dummy_vec4_float24; Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::SRC2>(state.debug, iteration, src2); @@ -500,16 +505,17 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned Record<DebugDataRecord::DEST_OUT>(state.debug, iteration, dest); } else { LOG_ERROR(HW_GPU, "Unhandled multiply-add instruction: 0x%02x (%s): 0x%08x", - (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex); + (int)instr.opcode.Value().EffectiveOpCode(), + instr.opcode.Value().GetInfo().name, instr.hex); } break; } - default: - { - static auto evaluate_condition = [](const UnitState<Debug>& state, bool refx, bool refy, Instruction::FlowControlType flow_control) { - bool results[2] = { refx == state.conditional_code[0], - refy == state.conditional_code[1] }; + default: { + static auto evaluate_condition = [](const UnitState<Debug>& state, bool refx, bool refy, + Instruction::FlowControlType flow_control) { + bool results[2] = {refx == state.conditional_code[0], + refy == state.conditional_code[1]}; switch (flow_control.op) { case flow_control.Or: @@ -533,44 +539,45 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; case OpCode::Id::JMPC: - Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, state.conditional_code); - if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { + Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, + state.conditional_code); + if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, + instr.flow_control)) { program_counter = instr.flow_control.dest_offset - 1; } break; case OpCode::Id::JMPU: - Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); + Record<DebugDataRecord::COND_BOOL_IN>( + state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); - if (uniforms.b[instr.flow_control.bool_uniform_id] == !(instr.flow_control.num_instructions & 1)) { + if (uniforms.b[instr.flow_control.bool_uniform_id] == + !(instr.flow_control.num_instructions & 1)) { program_counter = instr.flow_control.dest_offset - 1; } break; case OpCode::Id::CALL: - call(state, - instr.flow_control.dest_offset, - instr.flow_control.num_instructions, + call(state, instr.flow_control.dest_offset, instr.flow_control.num_instructions, program_counter + 1, 0, 0); break; case OpCode::Id::CALLU: - Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); + Record<DebugDataRecord::COND_BOOL_IN>( + state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); if (uniforms.b[instr.flow_control.bool_uniform_id]) { - call(state, - instr.flow_control.dest_offset, - instr.flow_control.num_instructions, - program_counter + 1, 0, 0); + call(state, instr.flow_control.dest_offset, instr.flow_control.num_instructions, + program_counter + 1, 0, 0); } break; case OpCode::Id::CALLC: - Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, state.conditional_code); - if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { - call(state, - instr.flow_control.dest_offset, - instr.flow_control.num_instructions, - program_counter + 1, 0, 0); + Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, + state.conditional_code); + if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, + instr.flow_control)) { + call(state, instr.flow_control.dest_offset, instr.flow_control.num_instructions, + program_counter + 1, 0, 0); } break; @@ -578,43 +585,42 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; case OpCode::Id::IFU: - Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); + Record<DebugDataRecord::COND_BOOL_IN>( + state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); if (uniforms.b[instr.flow_control.bool_uniform_id]) { - call(state, - program_counter + 1, + call(state, program_counter + 1, instr.flow_control.dest_offset - program_counter - 1, - instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); + instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, + 0); } else { - call(state, - instr.flow_control.dest_offset, - instr.flow_control.num_instructions, - instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); + call(state, instr.flow_control.dest_offset, instr.flow_control.num_instructions, + instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, + 0); } break; - case OpCode::Id::IFC: - { + case OpCode::Id::IFC: { // TODO: Do we need to consider swizzlers here? - Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, state.conditional_code); - if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { - call(state, - program_counter + 1, + Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, + state.conditional_code); + if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, + instr.flow_control)) { + call(state, program_counter + 1, instr.flow_control.dest_offset - program_counter - 1, - instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); + instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, + 0); } else { - call(state, - instr.flow_control.dest_offset, - instr.flow_control.num_instructions, - instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); + call(state, instr.flow_control.dest_offset, instr.flow_control.num_instructions, + instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, + 0); } break; } - case OpCode::Id::LOOP: - { + case OpCode::Id::LOOP: { Math::Vec4<u8> loop_param(uniforms.i[instr.flow_control.int_uniform_id].x, uniforms.i[instr.flow_control.int_uniform_id].y, uniforms.i[instr.flow_control.int_uniform_id].z, @@ -622,18 +628,16 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned state.address_registers[2] = loop_param.y; Record<DebugDataRecord::LOOP_INT_IN>(state.debug, iteration, loop_param); - call(state, - program_counter + 1, + call(state, program_counter + 1, instr.flow_control.dest_offset - program_counter + 1, - instr.flow_control.dest_offset + 1, - loop_param.x, - loop_param.z); + instr.flow_control.dest_offset + 1, loop_param.x, loop_param.z); break; } default: LOG_ERROR(HW_GPU, "Unhandled instruction: 0x%02x (%s): 0x%08x", - (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex); + (int)instr.opcode.Value().EffectiveOpCode(), + instr.opcode.Value().GetInfo().name, instr.hex); break; } |