summaryrefslogtreecommitdiff
path: root/src/video_core/vertex_shader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/vertex_shader.cpp')
-rw-r--r--src/video_core/vertex_shader.cpp75
1 files changed, 38 insertions, 37 deletions
diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp
index bc8c0041c..4eb3e743e 100644
--- a/src/video_core/vertex_shader.cpp
+++ b/src/video_core/vertex_shader.cpp
@@ -17,6 +17,7 @@
17#include "vertex_shader.h" 17#include "vertex_shader.h"
18#include "debug_utils/debug_utils.h" 18#include "debug_utils/debug_utils.h"
19 19
20using nihstro::OpCode;
20using nihstro::Instruction; 21using nihstro::Instruction;
21using nihstro::RegisterType; 22using nihstro::RegisterType;
22using nihstro::SourceRegister; 23using nihstro::SourceRegister;
@@ -154,10 +155,10 @@ static void ProcessShaderCode(VertexShaderState& state) {
154 } 155 }
155 }; 156 };
156 157
157 switch (instr.opcode.GetInfo().type) { 158 switch (instr.opcode.Value().GetInfo().type) {
158 case Instruction::OpCodeType::Arithmetic: 159 case OpCode::Type::Arithmetic:
159 { 160 {
160 bool is_inverted = 0 != (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::SrcInversed); 161 bool is_inverted = 0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed);
161 // TODO: We don't really support this properly: For instance, the address register 162 // TODO: We don't really support this properly: For instance, the address register
162 // offset needs to be applied to SRC2 instead, etc. 163 // offset needs to be applied to SRC2 instead, etc.
163 // For now, we just abort in this situation. 164 // For now, we just abort in this situation.
@@ -197,15 +198,15 @@ static void ProcessShaderCode(VertexShaderState& state) {
197 src2[3] = src2[3] * float24::FromFloat32(-1); 198 src2[3] = src2[3] * float24::FromFloat32(-1);
198 } 199 }
199 200
200 float24* dest = (instr.common.dest < 0x08) ? state.output_register_table[4*instr.common.dest.GetIndex()] 201 float24* dest = (instr.common.dest.Value() < 0x08) ? state.output_register_table[4*instr.common.dest.Value().GetIndex()]
201 : (instr.common.dest < 0x10) ? dummy_vec4_float24 202 : (instr.common.dest.Value() < 0x10) ? dummy_vec4_float24
202 : (instr.common.dest < 0x20) ? &state.temporary_registers[instr.common.dest.GetIndex()][0] 203 : (instr.common.dest.Value() < 0x20) ? &state.temporary_registers[instr.common.dest.Value().GetIndex()][0]
203 : dummy_vec4_float24; 204 : dummy_vec4_float24;
204 205
205 state.debug.max_opdesc_id = std::max<u32>(state.debug.max_opdesc_id, 1+instr.common.operand_desc_id); 206 state.debug.max_opdesc_id = std::max<u32>(state.debug.max_opdesc_id, 1+instr.common.operand_desc_id);
206 207
207 switch (instr.opcode.EffectiveOpCode()) { 208 switch (instr.opcode.Value().EffectiveOpCode()) {
208 case Instruction::OpCode::ADD: 209 case OpCode::Id::ADD:
209 { 210 {
210 for (int i = 0; i < 4; ++i) { 211 for (int i = 0; i < 4; ++i) {
211 if (!swizzle.DestComponentEnabled(i)) 212 if (!swizzle.DestComponentEnabled(i))
@@ -217,7 +218,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
217 break; 218 break;
218 } 219 }
219 220
220 case Instruction::OpCode::MUL: 221 case OpCode::Id::MUL:
221 { 222 {
222 for (int i = 0; i < 4; ++i) { 223 for (int i = 0; i < 4; ++i) {
223 if (!swizzle.DestComponentEnabled(i)) 224 if (!swizzle.DestComponentEnabled(i))
@@ -229,7 +230,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
229 break; 230 break;
230 } 231 }
231 232
232 case Instruction::OpCode::MAX: 233 case OpCode::Id::MAX:
233 for (int i = 0; i < 4; ++i) { 234 for (int i = 0; i < 4; ++i) {
234 if (!swizzle.DestComponentEnabled(i)) 235 if (!swizzle.DestComponentEnabled(i))
235 continue; 236 continue;
@@ -238,11 +239,11 @@ static void ProcessShaderCode(VertexShaderState& state) {
238 } 239 }
239 break; 240 break;
240 241
241 case Instruction::OpCode::DP3: 242 case OpCode::Id::DP3:
242 case Instruction::OpCode::DP4: 243 case OpCode::Id::DP4:
243 { 244 {
244 float24 dot = float24::FromFloat32(0.f); 245 float24 dot = float24::FromFloat32(0.f);
245 int num_components = (instr.opcode == Instruction::OpCode::DP3) ? 3 : 4; 246 int num_components = (instr.opcode.Value() == OpCode::Id::DP3) ? 3 : 4;
246 for (int i = 0; i < num_components; ++i) 247 for (int i = 0; i < num_components; ++i)
247 dot = dot + src1[i] * src2[i]; 248 dot = dot + src1[i] * src2[i];
248 249
@@ -256,7 +257,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
256 } 257 }
257 258
258 // Reciprocal 259 // Reciprocal
259 case Instruction::OpCode::RCP: 260 case OpCode::Id::RCP:
260 { 261 {
261 for (int i = 0; i < 4; ++i) { 262 for (int i = 0; i < 4; ++i) {
262 if (!swizzle.DestComponentEnabled(i)) 263 if (!swizzle.DestComponentEnabled(i))
@@ -271,7 +272,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
271 } 272 }
272 273
273 // Reciprocal Square Root 274 // Reciprocal Square Root
274 case Instruction::OpCode::RSQ: 275 case OpCode::Id::RSQ:
275 { 276 {
276 for (int i = 0; i < 4; ++i) { 277 for (int i = 0; i < 4; ++i) {
277 if (!swizzle.DestComponentEnabled(i)) 278 if (!swizzle.DestComponentEnabled(i))
@@ -285,7 +286,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
285 break; 286 break;
286 } 287 }
287 288
288 case Instruction::OpCode::MOVA: 289 case OpCode::Id::MOVA:
289 { 290 {
290 for (int i = 0; i < 2; ++i) { 291 for (int i = 0; i < 2; ++i) {
291 if (!swizzle.DestComponentEnabled(i)) 292 if (!swizzle.DestComponentEnabled(i))
@@ -298,7 +299,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
298 break; 299 break;
299 } 300 }
300 301
301 case Instruction::OpCode::MOV: 302 case OpCode::Id::MOV:
302 { 303 {
303 for (int i = 0; i < 4; ++i) { 304 for (int i = 0; i < 4; ++i) {
304 if (!swizzle.DestComponentEnabled(i)) 305 if (!swizzle.DestComponentEnabled(i))
@@ -309,7 +310,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
309 break; 310 break;
310 } 311 }
311 312
312 case Instruction::OpCode::CMP: 313 case OpCode::Id::CMP:
313 for (int i = 0; i < 2; ++i) { 314 for (int i = 0; i < 2; ++i) {
314 // TODO: Can you restrict to one compare via dest masking? 315 // TODO: Can you restrict to one compare via dest masking?
315 316
@@ -350,7 +351,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
350 351
351 default: 352 default:
352 LOG_ERROR(HW_GPU, "Unhandled arithmetic instruction: 0x%02x (%s): 0x%08x", 353 LOG_ERROR(HW_GPU, "Unhandled arithmetic instruction: 0x%02x (%s): 0x%08x",
353 (int)instr.opcode.Value(), instr.opcode.GetInfo().name, instr.hex); 354 (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex);
354 DEBUG_ASSERT(false); 355 DEBUG_ASSERT(false);
355 break; 356 break;
356 } 357 }
@@ -358,9 +359,9 @@ static void ProcessShaderCode(VertexShaderState& state) {
358 break; 359 break;
359 } 360 }
360 361
361 case Instruction::OpCodeType::MultiplyAdd: 362 case OpCode::Type::MultiplyAdd:
362 { 363 {
363 if (instr.opcode.EffectiveOpCode() == Instruction::OpCode::MAD) { 364 if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD) {
364 const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.mad.operand_desc_id]; 365 const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.mad.operand_desc_id];
365 366
366 const float24* src1_ = LookupSourceRegister(instr.mad.src1); 367 const float24* src1_ = LookupSourceRegister(instr.mad.src1);
@@ -408,9 +409,9 @@ static void ProcessShaderCode(VertexShaderState& state) {
408 src3[3] = src3[3] * float24::FromFloat32(-1); 409 src3[3] = src3[3] * float24::FromFloat32(-1);
409 } 410 }
410 411
411 float24* dest = (instr.mad.dest < 0x08) ? state.output_register_table[4*instr.mad.dest.GetIndex()] 412 float24* dest = (instr.mad.dest.Value() < 0x08) ? state.output_register_table[4*instr.mad.dest.Value().GetIndex()]
412 : (instr.mad.dest < 0x10) ? dummy_vec4_float24 413 : (instr.mad.dest.Value() < 0x10) ? dummy_vec4_float24
413 : (instr.mad.dest < 0x20) ? &state.temporary_registers[instr.mad.dest.GetIndex()][0] 414 : (instr.mad.dest.Value() < 0x20) ? &state.temporary_registers[instr.mad.dest.Value().GetIndex()][0]
414 : dummy_vec4_float24; 415 : dummy_vec4_float24;
415 416
416 for (int i = 0; i < 4; ++i) { 417 for (int i = 0; i < 4; ++i) {
@@ -421,7 +422,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
421 } 422 }
422 } else { 423 } else {
423 LOG_ERROR(HW_GPU, "Unhandled multiply-add instruction: 0x%02x (%s): 0x%08x", 424 LOG_ERROR(HW_GPU, "Unhandled multiply-add instruction: 0x%02x (%s): 0x%08x",
424 (int)instr.opcode.Value(), instr.opcode.GetInfo().name, instr.hex); 425 (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex);
425 } 426 }
426 break; 427 break;
427 } 428 }
@@ -448,31 +449,31 @@ static void ProcessShaderCode(VertexShaderState& state) {
448 }; 449 };
449 450
450 // Handle each instruction on its own 451 // Handle each instruction on its own
451 switch (instr.opcode) { 452 switch (instr.opcode.Value()) {
452 case Instruction::OpCode::END: 453 case OpCode::Id::END:
453 exit_loop = true; 454 exit_loop = true;
454 break; 455 break;
455 456
456 case Instruction::OpCode::JMPC: 457 case OpCode::Id::JMPC:
457 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { 458 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) {
458 state.program_counter = &shader_memory[instr.flow_control.dest_offset] - 1; 459 state.program_counter = &shader_memory[instr.flow_control.dest_offset] - 1;
459 } 460 }
460 break; 461 break;
461 462
462 case Instruction::OpCode::JMPU: 463 case OpCode::Id::JMPU:
463 if (shader_uniforms.b[instr.flow_control.bool_uniform_id]) { 464 if (shader_uniforms.b[instr.flow_control.bool_uniform_id]) {
464 state.program_counter = &shader_memory[instr.flow_control.dest_offset] - 1; 465 state.program_counter = &shader_memory[instr.flow_control.dest_offset] - 1;
465 } 466 }
466 break; 467 break;
467 468
468 case Instruction::OpCode::CALL: 469 case OpCode::Id::CALL:
469 call(state, 470 call(state,
470 instr.flow_control.dest_offset, 471 instr.flow_control.dest_offset,
471 instr.flow_control.num_instructions, 472 instr.flow_control.num_instructions,
472 binary_offset + 1, 0, 0); 473 binary_offset + 1, 0, 0);
473 break; 474 break;
474 475
475 case Instruction::OpCode::CALLU: 476 case OpCode::Id::CALLU:
476 if (shader_uniforms.b[instr.flow_control.bool_uniform_id]) { 477 if (shader_uniforms.b[instr.flow_control.bool_uniform_id]) {
477 call(state, 478 call(state,
478 instr.flow_control.dest_offset, 479 instr.flow_control.dest_offset,
@@ -481,7 +482,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
481 } 482 }
482 break; 483 break;
483 484
484 case Instruction::OpCode::CALLC: 485 case OpCode::Id::CALLC:
485 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { 486 if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) {
486 call(state, 487 call(state,
487 instr.flow_control.dest_offset, 488 instr.flow_control.dest_offset,
@@ -490,10 +491,10 @@ static void ProcessShaderCode(VertexShaderState& state) {
490 } 491 }
491 break; 492 break;
492 493
493 case Instruction::OpCode::NOP: 494 case OpCode::Id::NOP:
494 break; 495 break;
495 496
496 case Instruction::OpCode::IFU: 497 case OpCode::Id::IFU:
497 if (shader_uniforms.b[instr.flow_control.bool_uniform_id]) { 498 if (shader_uniforms.b[instr.flow_control.bool_uniform_id]) {
498 call(state, 499 call(state,
499 binary_offset + 1, 500 binary_offset + 1,
@@ -508,7 +509,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
508 509
509 break; 510 break;
510 511
511 case Instruction::OpCode::IFC: 512 case OpCode::Id::IFC:
512 { 513 {
513 // TODO: Do we need to consider swizzlers here? 514 // TODO: Do we need to consider swizzlers here?
514 515
@@ -527,7 +528,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
527 break; 528 break;
528 } 529 }
529 530
530 case Instruction::OpCode::LOOP: 531 case OpCode::Id::LOOP:
531 { 532 {
532 state.address_registers[2] = shader_uniforms.i[instr.flow_control.int_uniform_id].y; 533 state.address_registers[2] = shader_uniforms.i[instr.flow_control.int_uniform_id].y;
533 534
@@ -542,7 +543,7 @@ static void ProcessShaderCode(VertexShaderState& state) {
542 543
543 default: 544 default:
544 LOG_ERROR(HW_GPU, "Unhandled instruction: 0x%02x (%s): 0x%08x", 545 LOG_ERROR(HW_GPU, "Unhandled instruction: 0x%02x (%s): 0x%08x",
545 (int)instr.opcode.Value(), instr.opcode.GetInfo().name, instr.hex); 546 (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex);
546 break; 547 break;
547 } 548 }
548 549