diff options
| author | 2015-08-19 04:39:24 -0300 | |
|---|---|---|
| committer | 2015-09-07 16:46:25 -0300 | |
| commit | 86d5461bcd0890ec8c039249424f26af636982d8 (patch) | |
| tree | d9a7ff9432aaf34a8acfb34ca7fb9a7be23a7168 /src | |
| parent | Shader Debugger: Initialize input_vertex to prevent crashes (diff) | |
| download | yuzu-86d5461bcd0890ec8c039249424f26af636982d8.tar.gz yuzu-86d5461bcd0890ec8c039249424f26af636982d8.tar.xz yuzu-86d5461bcd0890ec8c039249424f26af636982d8.zip | |
Shader Disassembly: Introduce variables to hold common subexpressions
Diffstat (limited to 'src')
| -rw-r--r-- | src/citra_qt/debugger/graphics_vertex_shader.cpp | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/src/citra_qt/debugger/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics_vertex_shader.cpp index e5af76074..ce81e7fae 100644 --- a/src/citra_qt/debugger/graphics_vertex_shader.cpp +++ b/src/citra_qt/debugger/graphics_vertex_shader.cpp | |||
| @@ -111,8 +111,12 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con | |||
| 111 | } | 111 | } |
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | Instruction instr = par->info.code[index.row()]; | 114 | const Instruction instr = par->info.code[index.row()]; |
| 115 | const SwizzlePattern& swizzle = par->info.swizzle_info[instr.common.operand_desc_id].pattern; | 115 | const OpCode opcode = instr.opcode; |
| 116 | const OpCode::Info opcode_info = opcode.GetInfo(); | ||
| 117 | const u32 operand_desc_id = opcode_info.type == OpCode::Type::MultiplyAdd ? | ||
| 118 | instr.mad.operand_desc_id.Value() : instr.common.operand_desc_id.Value(); | ||
| 119 | const SwizzlePattern swizzle = par->info.swizzle_info[operand_desc_id].pattern; | ||
| 116 | 120 | ||
| 117 | // longest known instruction name: "setemit " | 121 | // longest known instruction name: "setemit " |
| 118 | int kOpcodeColumnWidth = 8; | 122 | int kOpcodeColumnWidth = 8; |
| @@ -121,9 +125,9 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con | |||
| 121 | // "-rXX.xyzw ", no attempt is made to align indexed inputs | 125 | // "-rXX.xyzw ", no attempt is made to align indexed inputs |
| 122 | int kInputOperandColumnWidth = 11; | 126 | int kInputOperandColumnWidth = 11; |
| 123 | 127 | ||
| 124 | output << instr.opcode.Value().GetInfo().name; | 128 | output << opcode_info.name; |
| 125 | 129 | ||
| 126 | switch (instr.opcode.Value().GetInfo().type) { | 130 | switch (opcode_info.type) { |
| 127 | case OpCode::Type::Trivial: | 131 | case OpCode::Type::Trivial: |
| 128 | // Nothing to do here | 132 | // Nothing to do here |
| 129 | break; | 133 | break; |
| @@ -131,7 +135,7 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con | |||
| 131 | case OpCode::Type::Arithmetic: | 135 | case OpCode::Type::Arithmetic: |
| 132 | { | 136 | { |
| 133 | // Use custom code for special instructions | 137 | // Use custom code for special instructions |
| 134 | switch (instr.opcode.Value().EffectiveOpCode()) { | 138 | switch (opcode.EffectiveOpCode()) { |
| 135 | case OpCode::Id::CMP: | 139 | case OpCode::Id::CMP: |
| 136 | { | 140 | { |
| 137 | AlignToColumn(kOpcodeColumnWidth); | 141 | AlignToColumn(kOpcodeColumnWidth); |
| @@ -161,24 +165,24 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con | |||
| 161 | { | 165 | { |
| 162 | AlignToColumn(kOpcodeColumnWidth); | 166 | AlignToColumn(kOpcodeColumnWidth); |
| 163 | 167 | ||
| 164 | bool src_is_inverted = 0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed); | 168 | bool src_is_inverted = 0 != (opcode_info.subtype & OpCode::Info::SrcInversed); |
| 165 | 169 | ||
| 166 | if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::Dest) { | 170 | if (opcode_info.subtype & OpCode::Info::Dest) { |
| 167 | // e.g. "r12.xy__" | 171 | // e.g. "r12.xy__" |
| 168 | output << std::setw(3) << std::right << instr.common.dest.Value().GetName() << '.' << swizzle.DestMaskToString(); | 172 | output << std::setw(3) << std::right << instr.common.dest.Value().GetName() << '.' << swizzle.DestMaskToString(); |
| 169 | } else if (instr.opcode.Value().GetInfo().subtype == OpCode::Info::MOVA) { | 173 | } else if (opcode_info.subtype == OpCode::Info::MOVA) { |
| 170 | output << " a0." << swizzle.DestMaskToString(); | 174 | output << " a0." << swizzle.DestMaskToString(); |
| 171 | } | 175 | } |
| 172 | AlignToColumn(kOutputColumnWidth); | 176 | AlignToColumn(kOutputColumnWidth); |
| 173 | 177 | ||
| 174 | if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::Src1) { | 178 | if (opcode_info.subtype & OpCode::Info::Src1) { |
| 175 | SourceRegister src1 = instr.common.GetSrc1(src_is_inverted); | 179 | SourceRegister src1 = instr.common.GetSrc1(src_is_inverted); |
| 176 | print_input(output, src1, swizzle.negate_src1, swizzle.SelectorToString(false), true, instr.common.AddressRegisterName()); | 180 | print_input(output, src1, swizzle.negate_src1, swizzle.SelectorToString(false), true, instr.common.AddressRegisterName()); |
| 177 | AlignToColumn(kInputOperandColumnWidth); | 181 | AlignToColumn(kInputOperandColumnWidth); |
| 178 | } | 182 | } |
| 179 | 183 | ||
| 180 | // TODO: In some cases, the Address Register is used as an index for SRC2 instead of SRC1 | 184 | // TODO: In some cases, the Address Register is used as an index for SRC2 instead of SRC1 |
| 181 | if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::Src2) { | 185 | if (opcode_info.subtype & OpCode::Info::Src2) { |
| 182 | SourceRegister src2 = instr.common.GetSrc2(src_is_inverted); | 186 | SourceRegister src2 = instr.common.GetSrc2(src_is_inverted); |
| 183 | print_input(output, src2, swizzle.negate_src2, swizzle.SelectorToString(true)); | 187 | print_input(output, src2, swizzle.negate_src2, swizzle.SelectorToString(true)); |
| 184 | AlignToColumn(kInputOperandColumnWidth); | 188 | AlignToColumn(kInputOperandColumnWidth); |
| @@ -194,13 +198,13 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con | |||
| 194 | { | 198 | { |
| 195 | output << ' '; | 199 | output << ' '; |
| 196 | 200 | ||
| 197 | switch (instr.opcode.Value().EffectiveOpCode()) { | 201 | switch (opcode.EffectiveOpCode()) { |
| 198 | case OpCode::Id::LOOP: | 202 | case OpCode::Id::LOOP: |
| 199 | output << "(unknown instruction format)"; | 203 | output << "(unknown instruction format)"; |
| 200 | break; | 204 | break; |
| 201 | 205 | ||
| 202 | default: | 206 | default: |
| 203 | if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::HasCondition) { | 207 | if (opcode_info.subtype & OpCode::Info::HasCondition) { |
| 204 | output << '('; | 208 | output << '('; |
| 205 | 209 | ||
| 206 | if (instr.flow_control.op != instr.flow_control.JustY) { | 210 | if (instr.flow_control.op != instr.flow_control.JustY) { |
| @@ -220,23 +224,23 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con | |||
| 220 | } | 224 | } |
| 221 | 225 | ||
| 222 | output << ") "; | 226 | output << ") "; |
| 223 | } else if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::HasUniformIndex) { | 227 | } else if (opcode_info.subtype & OpCode::Info::HasUniformIndex) { |
| 224 | output << 'b' << instr.flow_control.bool_uniform_id << ' '; | 228 | output << 'b' << instr.flow_control.bool_uniform_id << ' '; |
| 225 | } | 229 | } |
| 226 | 230 | ||
| 227 | u32 target_addr = instr.flow_control.dest_offset; | 231 | u32 target_addr = instr.flow_control.dest_offset; |
| 228 | u32 target_addr_else = instr.flow_control.dest_offset; | 232 | u32 target_addr_else = instr.flow_control.dest_offset; |
| 229 | 233 | ||
| 230 | if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::HasAlternative) { | 234 | if (opcode_info.subtype & OpCode::Info::HasAlternative) { |
| 231 | output << "else jump to 0x" << std::setw(4) << std::right << std::setfill('0') << (4 * instr.flow_control.dest_offset); | 235 | output << "else jump to 0x" << std::setw(4) << std::right << std::setfill('0') << (4 * instr.flow_control.dest_offset); |
| 232 | } else if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::HasExplicitDest) { | 236 | } else if (opcode_info.subtype & OpCode::Info::HasExplicitDest) { |
| 233 | output << "jump to 0x" << std::setw(4) << std::right << std::setfill('0') << (4 * instr.flow_control.dest_offset); | 237 | output << "jump to 0x" << std::setw(4) << std::right << std::setfill('0') << (4 * instr.flow_control.dest_offset); |
| 234 | } else { | 238 | } else { |
| 235 | // TODO: Handle other cases | 239 | // TODO: Handle other cases |
| 236 | output << "(unknown destination)"; | 240 | output << "(unknown destination)"; |
| 237 | } | 241 | } |
| 238 | 242 | ||
| 239 | if (instr.opcode.Value().GetInfo().subtype & OpCode::Info::HasFinishPoint) { | 243 | if (opcode_info.subtype & OpCode::Info::HasFinishPoint) { |
| 240 | output << " (return on " << std::setw(4) << std::right << std::setfill('0') | 244 | output << " (return on " << std::setw(4) << std::right << std::setfill('0') |
| 241 | << (4 * instr.flow_control.dest_offset + 4 * instr.flow_control.num_instructions) << ')'; | 245 | << (4 * instr.flow_control.dest_offset + 4 * instr.flow_control.num_instructions) << ')'; |
| 242 | } | 246 | } |