summaryrefslogtreecommitdiff
path: root/src/video_core/rasterizer.cpp
diff options
context:
space:
mode:
authorGravatar Tony Wasserka2014-12-21 03:00:25 +0100
committerGravatar Tony Wasserka2014-12-31 16:32:55 +0100
commita7ae0330b1e4d5aa7fab3bb07bb2cf58f8572dc5 (patch)
treec95a7eb9b78dde4ae716ce8b168cc4fd80eebea9 /src/video_core/rasterizer.cpp
parentPica/Rasterizer: Implement depth testing. (diff)
downloadyuzu-a7ae0330b1e4d5aa7fab3bb07bb2cf58f8572dc5.tar.gz
yuzu-a7ae0330b1e4d5aa7fab3bb07bb2cf58f8572dc5.tar.xz
yuzu-a7ae0330b1e4d5aa7fab3bb07bb2cf58f8572dc5.zip
Pica/Rasterizer: Implement alpha blending.
Diffstat (limited to 'src/video_core/rasterizer.cpp')
-rw-r--r--src/video_core/rasterizer.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index 8dff2db27..5f7971fe2 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -25,6 +25,18 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
25 *(color_buffer + x + y * registers.framebuffer.GetWidth()) = value; 25 *(color_buffer + x + y * registers.framebuffer.GetWidth()) = value;
26} 26}
27 27
28static const Math::Vec4<u8> GetPixel(int x, int y) {
29 u32* color_buffer_u32 = reinterpret_cast<u32*>(Memory::GetPointer(PAddrToVAddr(registers.framebuffer.GetColorBufferPhysicalAddress())));
30
31 u32 value = *(color_buffer_u32 + x + y * registers.framebuffer.GetWidth());
32 Math::Vec4<u8> ret;
33 ret.a() = value >> 24;
34 ret.r() = (value >> 16) & 0xFF;
35 ret.g() = (value >> 8) & 0xFF;
36 ret.b() = value & 0xFF;
37 return ret;
38 }
39
28static u32 GetDepth(int x, int y) { 40static u32 GetDepth(int x, int y) {
29 u16* depth_buffer = reinterpret_cast<u16*>(Memory::GetPointer(PAddrToVAddr(registers.framebuffer.GetDepthBufferPhysicalAddress()))); 41 u16* depth_buffer = reinterpret_cast<u16*>(Memory::GetPointer(PAddrToVAddr(registers.framebuffer.GetDepthBufferPhysicalAddress())));
30 42
@@ -430,6 +442,78 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
430 SetDepth(x >> 4, y >> 4, z); 442 SetDepth(x >> 4, y >> 4, z);
431 } 443 }
432 444
445 auto dest = GetPixel(x >> 4, y >> 4);
446
447 if (registers.output_merger.alphablend_enable) {
448 auto params = registers.output_merger.alpha_blending;
449
450 auto LookupFactorRGB = [&](decltype(params)::BlendFactor factor) -> Math::Vec3<u8> {
451 switch(factor) {
452 case params.Zero:
453 return Math::Vec3<u8>(0, 0, 0);
454
455 case params.One:
456 return Math::Vec3<u8>(255, 255, 255);
457
458 case params.SourceAlpha:
459 return Math::MakeVec(combiner_output.a(), combiner_output.a(), combiner_output.a());
460
461 case params.OneMinusSourceAlpha:
462 return Math::Vec3<u8>(255-combiner_output.a(), 255-combiner_output.a(), 255-combiner_output.a());
463
464 default:
465 LOG_CRITICAL(HW_GPU, "Unknown color blend factor %x", factor);
466 exit(0);
467 break;
468 }
469 };
470
471 auto LookupFactorA = [&](decltype(params)::BlendFactor factor) -> u8 {
472 switch(factor) {
473 case params.Zero:
474 return 0;
475
476 case params.One:
477 return 255;
478
479 case params.SourceAlpha:
480 return combiner_output.a();
481
482 case params.OneMinusSourceAlpha:
483 return 255 - combiner_output.a();
484
485 default:
486 LOG_CRITICAL(HW_GPU, "Unknown alpha blend factor %x", factor);
487 exit(0);
488 break;
489 }
490 };
491
492 auto srcfactor = Math::MakeVec(LookupFactorRGB(params.factor_source_rgb),
493 LookupFactorA(params.factor_source_a));
494 auto dstfactor = Math::MakeVec(LookupFactorRGB(params.factor_dest_rgb),
495 LookupFactorA(params.factor_dest_a));
496
497 switch (params.blend_equation_rgb) {
498 case params.Add:
499 {
500 auto result = (combiner_output * srcfactor + dest * dstfactor) / 255;
501 result.r() = std::min(255, result.r());
502 result.g() = std::min(255, result.g());
503 result.b() = std::min(255, result.b());
504 combiner_output = result.Cast<u8>();
505 break;
506 }
507
508 default:
509 LOG_CRITICAL(HW_GPU, "Unknown RGB blend equation %x", params.blend_equation_rgb.Value());
510 exit(0);
511 }
512 } else {
513 LOG_CRITICAL(HW_GPU, "logic op: %x", registers.output_merger.logic_op);
514 exit(0);
515 }
516
433 DrawPixel(x >> 4, y >> 4, combiner_output); 517 DrawPixel(x >> 4, y >> 4, combiner_output);
434 } 518 }
435 } 519 }