diff options
| author | 2015-01-03 13:29:44 +0100 | |
|---|---|---|
| committer | 2015-01-12 15:34:36 -0800 | |
| commit | e02db3904bae35e1fd78cac9b5422be6a7fea57f (patch) | |
| tree | 6f2758cc98051d28e1777f5346c641988f7fa949 /src | |
| parent | Merge pull request #476 from lioncash/asr (diff) | |
| download | yuzu-e02db3904bae35e1fd78cac9b5422be6a7fea57f.tar.gz yuzu-e02db3904bae35e1fd78cac9b5422be6a7fea57f.tar.xz yuzu-e02db3904bae35e1fd78cac9b5422be6a7fea57f.zip | |
Pica/VertexShader: Implement the MAD instruction.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/vertex_shader.cpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp index ff825e2e1..fd82d3985 100644 --- a/src/video_core/vertex_shader.cpp +++ b/src/video_core/vertex_shader.cpp | |||
| @@ -348,6 +348,75 @@ static void ProcessShaderCode(VertexShaderState& state) { | |||
| 348 | 348 | ||
| 349 | break; | 349 | break; |
| 350 | } | 350 | } |
| 351 | |||
| 352 | case Instruction::OpCodeType::MultiplyAdd: | ||
| 353 | { | ||
| 354 | if (instr.opcode.EffectiveOpCode() == Instruction::OpCode::MAD) { | ||
| 355 | const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.mad.operand_desc_id]; | ||
| 356 | |||
| 357 | const float24* src1_ = LookupSourceRegister(instr.mad.src1); | ||
| 358 | const float24* src2_ = LookupSourceRegister(instr.mad.src2); | ||
| 359 | const float24* src3_ = LookupSourceRegister(instr.mad.src3); | ||
| 360 | |||
| 361 | const bool negate_src1 = ((bool)swizzle.negate_src1 != false); | ||
| 362 | const bool negate_src2 = ((bool)swizzle.negate_src2 != false); | ||
| 363 | const bool negate_src3 = ((bool)swizzle.negate_src3 != false); | ||
| 364 | |||
| 365 | float24 src1[4] = { | ||
| 366 | src1_[(int)swizzle.GetSelectorSrc1(0)], | ||
| 367 | src1_[(int)swizzle.GetSelectorSrc1(1)], | ||
| 368 | src1_[(int)swizzle.GetSelectorSrc1(2)], | ||
| 369 | src1_[(int)swizzle.GetSelectorSrc1(3)], | ||
| 370 | }; | ||
| 371 | if (negate_src1) { | ||
| 372 | src1[0] = src1[0] * float24::FromFloat32(-1); | ||
| 373 | src1[1] = src1[1] * float24::FromFloat32(-1); | ||
| 374 | src1[2] = src1[2] * float24::FromFloat32(-1); | ||
| 375 | src1[3] = src1[3] * float24::FromFloat32(-1); | ||
| 376 | } | ||
| 377 | float24 src2[4] = { | ||
| 378 | src2_[(int)swizzle.GetSelectorSrc2(0)], | ||
| 379 | src2_[(int)swizzle.GetSelectorSrc2(1)], | ||
| 380 | src2_[(int)swizzle.GetSelectorSrc2(2)], | ||
| 381 | src2_[(int)swizzle.GetSelectorSrc2(3)], | ||
| 382 | }; | ||
| 383 | if (negate_src2) { | ||
| 384 | src2[0] = src2[0] * float24::FromFloat32(-1); | ||
| 385 | src2[1] = src2[1] * float24::FromFloat32(-1); | ||
| 386 | src2[2] = src2[2] * float24::FromFloat32(-1); | ||
| 387 | src2[3] = src2[3] * float24::FromFloat32(-1); | ||
| 388 | } | ||
| 389 | float24 src3[4] = { | ||
| 390 | src3_[(int)swizzle.GetSelectorSrc3(0)], | ||
| 391 | src3_[(int)swizzle.GetSelectorSrc3(1)], | ||
| 392 | src3_[(int)swizzle.GetSelectorSrc3(2)], | ||
| 393 | src3_[(int)swizzle.GetSelectorSrc3(3)], | ||
| 394 | }; | ||
| 395 | if (negate_src3) { | ||
| 396 | src3[0] = src3[0] * float24::FromFloat32(-1); | ||
| 397 | src3[1] = src3[1] * float24::FromFloat32(-1); | ||
| 398 | src3[2] = src3[2] * float24::FromFloat32(-1); | ||
| 399 | src3[3] = src3[3] * float24::FromFloat32(-1); | ||
| 400 | } | ||
| 401 | |||
| 402 | float24* dest = (instr.mad.dest < 0x08) ? state.output_register_table[4*instr.mad.dest.GetIndex()] | ||
| 403 | : (instr.mad.dest < 0x10) ? dummy_vec4_float24 | ||
| 404 | : (instr.mad.dest < 0x20) ? &state.temporary_registers[instr.mad.dest.GetIndex()][0] | ||
| 405 | : dummy_vec4_float24; | ||
| 406 | |||
| 407 | for (int i = 0; i < 4; ++i) { | ||
| 408 | if (!swizzle.DestComponentEnabled(i)) | ||
| 409 | continue; | ||
| 410 | |||
| 411 | dest[i] = src1[i] * src2[i] + src3[i]; | ||
| 412 | } | ||
| 413 | } else { | ||
| 414 | LOG_ERROR(HW_GPU, "Unhandled multiply-add instruction: 0x%02x (%s): 0x%08x", | ||
| 415 | (int)instr.opcode.Value(), instr.opcode.GetInfo().name, instr.hex); | ||
| 416 | } | ||
| 417 | break; | ||
| 418 | } | ||
| 419 | |||
| 351 | default: | 420 | default: |
| 352 | // Handle each instruction on its own | 421 | // Handle each instruction on its own |
| 353 | switch (instr.opcode) { | 422 | switch (instr.opcode) { |