diff options
| author | 2014-12-21 03:00:25 +0100 | |
|---|---|---|
| committer | 2014-12-31 16:32:55 +0100 | |
| commit | a7ae0330b1e4d5aa7fab3bb07bb2cf58f8572dc5 (patch) | |
| tree | c95a7eb9b78dde4ae716ce8b168cc4fd80eebea9 /src | |
| parent | Pica/Rasterizer: Implement depth testing. (diff) | |
| download | yuzu-a7ae0330b1e4d5aa7fab3bb07bb2cf58f8572dc5.tar.gz yuzu-a7ae0330b1e4d5aa7fab3bb07bb2cf58f8572dc5.tar.xz yuzu-a7ae0330b1e4d5aa7fab3bb07bb2cf58f8572dc5.zip | |
Pica/Rasterizer: Implement alpha blending.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/rasterizer.cpp | 84 |
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 | ||
| 28 | static 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 | |||
| 28 | static u32 GetDepth(int x, int y) { | 40 | static 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 | } |