summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Tony Wasserka2015-01-03 13:29:44 +0100
committerGravatar archshift2015-01-12 15:34:36 -0800
commite02db3904bae35e1fd78cac9b5422be6a7fea57f (patch)
tree6f2758cc98051d28e1777f5346c641988f7fa949 /src
parentMerge pull request #476 from lioncash/asr (diff)
downloadyuzu-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.cpp69
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) {