From 7d43aef4d0c956524be5df1ff062c09eb3512aba Mon Sep 17 00:00:00 2001 From: archshift Date: Sun, 8 Mar 2015 13:52:38 -0700 Subject: Update nihstro submodule to the initial release version. Includes more opcodes to implement in the future. --- externals/nihstro | 2 +- src/citra_qt/debugger/graphics_vertex_shader.cpp | 41 ++++++------- src/video_core/vertex_shader.cpp | 75 ++++++++++++------------ 3 files changed, 60 insertions(+), 58 deletions(-) diff --git a/externals/nihstro b/externals/nihstro index 0a8b4d22..4a78588b 160000 --- a/externals/nihstro +++ b/externals/nihstro @@ -1 +1 @@ -Subproject commit 0a8b4d221425f13e24a3cef9b02edc3221bab211 +Subproject commit 4a78588b308564f7ebae193e0ae00d9a0d5741d5 diff --git a/src/citra_qt/debugger/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics_vertex_shader.cpp index 06eaf0bf..3b072d01 100644 --- a/src/citra_qt/debugger/graphics_vertex_shader.cpp +++ b/src/citra_qt/debugger/graphics_vertex_shader.cpp @@ -12,6 +12,7 @@ #include "graphics_vertex_shader.h" +using nihstro::OpCode; using nihstro::Instruction; using nihstro::SourceRegister; using nihstro::SwizzlePattern; @@ -78,7 +79,7 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con const SwizzlePattern& swizzle = info.swizzle_info[instr.common.operand_desc_id].pattern; // longest known instruction name: "setemit " - output << std::setw(8) << std::left << instr.opcode.GetInfo().name; + output << std::setw(8) << std::left << instr.opcode.Value().GetInfo().name; // e.g. "-c92.xyzw" static auto print_input = [](std::stringstream& output, const SourceRegister& input, @@ -109,16 +110,16 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con print_input_indexed(output, input, negate, swizzle_mask, address_register_name); }; - switch (instr.opcode.GetInfo().type) { - case Instruction::OpCodeType::Trivial: + switch (instr.opcode.Value().GetInfo().type) { + case OpCode::Type::Trivial: // Nothing to do here break; - case Instruction::OpCodeType::Arithmetic: + case OpCode::Type::Arithmetic: { // Use custom code for special instructions - switch (instr.opcode.EffectiveOpCode()) { - case Instruction::OpCode::CMP: + switch (instr.opcode.Value().EffectiveOpCode()) { + case OpCode::Id::CMP: { // NOTE: CMP always writes both cc components, so we do not consider the dest mask here. output << std::setw(4) << std::right << "cc."; @@ -142,13 +143,13 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con default: { - bool src_is_inverted = 0 != (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::SrcInversed); + bool src_is_inverted = 0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed); - if (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::Dest) { + if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::Dest) { // e.g. "r12.xy__" - output << std::setw(4) << std::right << instr.common.dest.GetName() + "."; + output << std::setw(4) << std::right << instr.common.dest.Value().GetName() + "."; output << swizzle.DestMaskToString(); - } else if (instr.opcode.GetInfo().subtype == Instruction::OpCodeInfo::MOVA) { + } else if (instr.opcode.Value().GetInfo().subtype == OpCode::Info::MOVA) { output << std::setw(4) << std::right << "a0."; output << swizzle.DestMaskToString(); } else { @@ -156,7 +157,7 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con } output << " "; - if (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::Src1) { + if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::Src1) { SourceRegister src1 = instr.common.GetSrc1(src_is_inverted); print_input_indexed(output, src1, swizzle.negate_src1, swizzle.SelectorToString(false), instr.common.AddressRegisterName()); } else { @@ -164,7 +165,7 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con } // TODO: In some cases, the Address Register is used as an index for SRC2 instead of SRC1 - if (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::Src2) { + if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::Src2) { SourceRegister src2 = instr.common.GetSrc2(src_is_inverted); print_input(output, src2, swizzle.negate_src2, swizzle.SelectorToString(false)); } @@ -175,17 +176,17 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con break; } - case Instruction::OpCodeType::Conditional: + case OpCode::Type::Conditional: { - switch (instr.opcode.EffectiveOpCode()) { - case Instruction::OpCode::LOOP: + switch (instr.opcode.Value().EffectiveOpCode()) { + case OpCode::Id::LOOP: output << "(unknown instruction format)"; break; default: output << "if "; - if (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::HasCondition) { + if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::HasCondition) { const char* ops[] = { " || ", " && ", "", "" }; @@ -198,22 +199,22 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con output << ((!instr.flow_control.refy) ? "!" : " ") << "cc.y"; output << " "; - } else if (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::HasUniformIndex) { + } else if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::HasUniformIndex) { output << "b" << instr.flow_control.bool_uniform_id << " "; } u32 target_addr = instr.flow_control.dest_offset; u32 target_addr_else = instr.flow_control.dest_offset; - if (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::HasAlternative) { + if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::HasAlternative) { output << "else jump to 0x" << std::setw(4) << std::right << std::setfill('0') << 4 * instr.flow_control.dest_offset << " "; - } else if (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::HasExplicitDest) { + } else if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::HasExplicitDest) { output << "jump to 0x" << std::setw(4) << std::right << std::setfill('0') << 4 * instr.flow_control.dest_offset << " "; } else { // TODO: Handle other cases } - if (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::HasFinishPoint) { + if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::HasFinishPoint) { output << "(return on " << std::setw(4) << std::right << std::setfill('0') << 4 * instr.flow_control.dest_offset + 4 * instr.flow_control.num_instructions << ")"; } diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp index bc8c0041..4eb3e743 100644 --- a/src/video_core/vertex_shader.cpp +++ b/src/video_core/vertex_shader.cpp @@ -17,6 +17,7 @@ #include "vertex_shader.h" #include "debug_utils/debug_utils.h" +using nihstro::OpCode; using nihstro::Instruction; using nihstro::RegisterType; using nihstro::SourceRegister; @@ -154,10 +155,10 @@ static void ProcessShaderCode(VertexShaderState& state) { } }; - switch (instr.opcode.GetInfo().type) { - case Instruction::OpCodeType::Arithmetic: + switch (instr.opcode.Value().GetInfo().type) { + case OpCode::Type::Arithmetic: { - bool is_inverted = 0 != (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::SrcInversed); + bool is_inverted = 0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed); // TODO: We don't really support this properly: For instance, the address register // offset needs to be applied to SRC2 instead, etc. // For now, we just abort in this situation. @@ -197,15 +198,15 @@ static void ProcessShaderCode(VertexShaderState& state) { src2[3] = src2[3] * float24::FromFloat32(-1); } - float24* dest = (instr.common.dest < 0x08) ? state.output_register_table[4*instr.common.dest.GetIndex()] - : (instr.common.dest < 0x10) ? dummy_vec4_float24 - : (instr.common.dest < 0x20) ? &state.temporary_registers[instr.common.dest.GetIndex()][0] + float24* dest = (instr.common.dest.Value() < 0x08) ? state.output_register_table[4*instr.common.dest.Value().GetIndex()] + : (instr.common.dest.Value() < 0x10) ? dummy_vec4_float24 + : (instr.common.dest.Value() < 0x20) ? &state.temporary_registers[instr.common.dest.Value().GetIndex()][0] : dummy_vec4_float24; state.debug.max_opdesc_id = std::max(state.debug.max_opdesc_id, 1+instr.common.operand_desc_id); - switch (instr.opcode.EffectiveOpCode()) { - case Instruction::OpCode::ADD: + switch (instr.opcode.Value().EffectiveOpCode()) { + case OpCode::Id::ADD: { for (int i = 0; i < 4; ++i) { if (!swizzle.DestComponentEnabled(i)) @@ -217,7 +218,7 @@ static void ProcessShaderCode(VertexShaderState& state) { break; } - case Instruction::OpCode::MUL: + case OpCode::Id::MUL: { for (int i = 0; i < 4; ++i) { if (!swizzle.DestComponentEnabled(i)) @@ -229,7 +230,7 @@ static void ProcessShaderCode(VertexShaderState& state) { break; } - case Instruction::OpCode::MAX: + case OpCode::Id::MAX: for (int i = 0; i < 4; ++i) { if (!swizzle.DestComponentEnabled(i)) continue; @@ -238,11 +239,11 @@ static void ProcessShaderCode(VertexShaderState& state) { } break; - case Instruction::OpCode::DP3: - case Instruction::OpCode::DP4: + case OpCode::Id::DP3: + case OpCode::Id::DP4: { float24 dot = float24::FromFloat32(0.f); - int num_components = (instr.opcode == Instruction::OpCode::DP3) ? 3 : 4; + int num_components = (instr.opcode.Value() == OpCode::Id::DP3) ? 3 : 4; for (int i = 0; i < num_components; ++i) dot = dot + src1[i] * src2[i]; @@ -256,7 +257,7 @@ static void ProcessShaderCode(VertexShaderState& state) { } // Reciprocal - case Instruction::OpCode::RCP: + case OpCode::Id::RCP: { for (int i = 0; i < 4; ++i) { if (!swizzle.DestComponentEnabled(i)) @@ -271,7 +272,7 @@ static void ProcessShaderCode(VertexShaderState& state) { } // Reciprocal Square Root - case Instruction::OpCode::RSQ: + case OpCode::Id::RSQ: { for (int i = 0; i < 4; ++i) { if (!swizzle.DestComponentEnabled(i)) @@ -285,7 +286,7 @@ static void ProcessShaderCode(VertexShaderState& state) { break; } - case Instruction::OpCode::MOVA: + case OpCode::Id::MOVA: { for (int i = 0; i < 2; ++i) { if (!swizzle.DestComponentEnabled(i)) @@ -298,7 +299,7 @@ static void ProcessShaderCode(VertexShaderState& state) { break; } - case Instruction::OpCode::MOV: + case OpCode::Id::MOV: { for (int i = 0; i < 4; ++i) { if (!swizzle.DestComponentEnabled(i)) @@ -309,7 +310,7 @@ static void ProcessShaderCode(VertexShaderState& state) { break; } - case Instruction::OpCode::CMP: + case OpCode::Id::CMP: for (int i = 0; i < 2; ++i) { // TODO: Can you restrict to one compare via dest masking? @@ -350,7 +351,7 @@ static void ProcessShaderCode(VertexShaderState& state) { default: LOG_ERROR(HW_GPU, "Unhandled arithmetic instruction: 0x%02x (%s): 0x%08x", - (int)instr.opcode.Value(), instr.opcode.GetInfo().name, instr.hex); + (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex); DEBUG_ASSERT(false); break; } @@ -358,9 +359,9 @@ static void ProcessShaderCode(VertexShaderState& state) { break; } - case Instruction::OpCodeType::MultiplyAdd: + case OpCode::Type::MultiplyAdd: { - if (instr.opcode.EffectiveOpCode() == Instruction::OpCode::MAD) { + if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD) { const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.mad.operand_desc_id]; const float24* src1_ = LookupSourceRegister(instr.mad.src1); @@ -408,9 +409,9 @@ static void ProcessShaderCode(VertexShaderState& state) { src3[3] = src3[3] * float24::FromFloat32(-1); } - float24* dest = (instr.mad.dest < 0x08) ? state.output_register_table[4*instr.mad.dest.GetIndex()] - : (instr.mad.dest < 0x10) ? dummy_vec4_float24 - : (instr.mad.dest < 0x20) ? &state.temporary_registers[instr.mad.dest.GetIndex()][0] + float24* dest = (instr.mad.dest.Value() < 0x08) ? state.output_register_table[4*instr.mad.dest.Value().GetIndex()] + : (instr.mad.dest.Value() < 0x10) ? dummy_vec4_float24 + : (instr.mad.dest.Value() < 0x20) ? &state.temporary_registers[instr.mad.dest.Value().GetIndex()][0] : dummy_vec4_float24; for (int i = 0; i < 4; ++i) { @@ -421,7 +422,7 @@ static void ProcessShaderCode(VertexShaderState& state) { } } else { LOG_ERROR(HW_GPU, "Unhandled multiply-add instruction: 0x%02x (%s): 0x%08x", - (int)instr.opcode.Value(), instr.opcode.GetInfo().name, instr.hex); + (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex); } break; } @@ -448,31 +449,31 @@ static void ProcessShaderCode(VertexShaderState& state) { }; // Handle each instruction on its own - switch (instr.opcode) { - case Instruction::OpCode::END: + switch (instr.opcode.Value()) { + case OpCode::Id::END: exit_loop = true; break; - case Instruction::OpCode::JMPC: + case OpCode::Id::JMPC: if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { state.program_counter = &shader_memory[instr.flow_control.dest_offset] - 1; } break; - case Instruction::OpCode::JMPU: + case OpCode::Id::JMPU: if (shader_uniforms.b[instr.flow_control.bool_uniform_id]) { state.program_counter = &shader_memory[instr.flow_control.dest_offset] - 1; } break; - case Instruction::OpCode::CALL: + case OpCode::Id::CALL: call(state, instr.flow_control.dest_offset, instr.flow_control.num_instructions, binary_offset + 1, 0, 0); break; - case Instruction::OpCode::CALLU: + case OpCode::Id::CALLU: if (shader_uniforms.b[instr.flow_control.bool_uniform_id]) { call(state, instr.flow_control.dest_offset, @@ -481,7 +482,7 @@ static void ProcessShaderCode(VertexShaderState& state) { } break; - case Instruction::OpCode::CALLC: + case OpCode::Id::CALLC: if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { call(state, instr.flow_control.dest_offset, @@ -490,10 +491,10 @@ static void ProcessShaderCode(VertexShaderState& state) { } break; - case Instruction::OpCode::NOP: + case OpCode::Id::NOP: break; - case Instruction::OpCode::IFU: + case OpCode::Id::IFU: if (shader_uniforms.b[instr.flow_control.bool_uniform_id]) { call(state, binary_offset + 1, @@ -508,7 +509,7 @@ static void ProcessShaderCode(VertexShaderState& state) { break; - case Instruction::OpCode::IFC: + case OpCode::Id::IFC: { // TODO: Do we need to consider swizzlers here? @@ -527,7 +528,7 @@ static void ProcessShaderCode(VertexShaderState& state) { break; } - case Instruction::OpCode::LOOP: + case OpCode::Id::LOOP: { state.address_registers[2] = shader_uniforms.i[instr.flow_control.int_uniform_id].y; @@ -542,7 +543,7 @@ static void ProcessShaderCode(VertexShaderState& state) { default: LOG_ERROR(HW_GPU, "Unhandled instruction: 0x%02x (%s): 0x%08x", - (int)instr.opcode.Value(), instr.opcode.GetInfo().name, instr.hex); + (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex); break; } -- cgit v1.2.3