فهرست منبع

Update nihstro submodule to the initial release version.

Includes more opcodes to implement in the future.
archshift 11 سال پیش
والد
کامیت
7d43aef4d0
3فایلهای تغییر یافته به همراه60 افزوده شده و 58 حذف شده
  1. 1 1
      externals/nihstro
  2. 21 20
      src/citra_qt/debugger/graphics_vertex_shader.cpp
  3. 38 37
      src/video_core/vertex_shader.cpp

+ 1 - 1
externals/nihstro

@@ -1 +1 @@
-Subproject commit 0a8b4d221425f13e24a3cef9b02edc3221bab211
+Subproject commit 4a78588b308564f7ebae193e0ae00d9a0d5741d5

+ 21 - 20
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 << ")";
                     }

+ 38 - 37
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<u32>(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;
             }