diff options
Diffstat (limited to 'src/video_core/vertex_shader.cpp')
| -rw-r--r-- | src/video_core/vertex_shader.cpp | 75 |
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 | ||
| 20 | using nihstro::OpCode; | ||
| 20 | using nihstro::Instruction; | 21 | using nihstro::Instruction; |
| 21 | using nihstro::RegisterType; | 22 | using nihstro::RegisterType; |
| 22 | using nihstro::SourceRegister; | 23 | using 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 | ||