diff options
| author | 2015-05-09 22:45:05 -0400 | |
|---|---|---|
| committer | 2015-05-09 22:45:05 -0400 | |
| commit | ba0bfe7d82a241f1dbe449a1bdcc2a76c594c667 (patch) | |
| tree | e4274244ccd93c0b4e15e84f551c99382e8169d9 /src/video_core/rasterizer.cpp | |
| parent | Merge pull request #736 from yuriks/remove-BIT (diff) | |
| parent | rasterizer: Implemented combiner output scaling. (diff) | |
| download | yuzu-ba0bfe7d82a241f1dbe449a1bdcc2a76c594c667.tar.gz yuzu-ba0bfe7d82a241f1dbe449a1bdcc2a76c594c667.tar.xz yuzu-ba0bfe7d82a241f1dbe449a1bdcc2a76c594c667.zip | |
Merge pull request #726 from bunnei/gpu-improvements
GPU improvements
Diffstat (limited to 'src/video_core/rasterizer.cpp')
| -rw-r--r-- | src/video_core/rasterizer.cpp | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 3b3fef484..46a326bb4 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -90,7 +90,7 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { | |||
| 90 | UNIMPLEMENTED(); | 90 | UNIMPLEMENTED(); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | return {}; | 93 | return {0, 0, 0, 0}; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | static u32 GetDepth(int x, int y) { | 96 | static u32 GetDepth(int x, int y) { |
| @@ -376,7 +376,13 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, | |||
| 376 | // with some basic arithmetic. Alpha combiners can be configured separately but work | 376 | // with some basic arithmetic. Alpha combiners can be configured separately but work |
| 377 | // analogously. | 377 | // analogously. |
| 378 | Math::Vec4<u8> combiner_output; | 378 | Math::Vec4<u8> combiner_output; |
| 379 | for (const auto& tev_stage : tev_stages) { | 379 | Math::Vec4<u8> combiner_buffer = { |
| 380 | registers.tev_combiner_buffer_color.r, registers.tev_combiner_buffer_color.g, | ||
| 381 | registers.tev_combiner_buffer_color.b, registers.tev_combiner_buffer_color.a | ||
| 382 | }; | ||
| 383 | |||
| 384 | for (unsigned tev_stage_index = 0; tev_stage_index < tev_stages.size(); ++tev_stage_index) { | ||
| 385 | const auto& tev_stage = tev_stages[tev_stage_index]; | ||
| 380 | using Source = Regs::TevStageConfig::Source; | 386 | using Source = Regs::TevStageConfig::Source; |
| 381 | using ColorModifier = Regs::TevStageConfig::ColorModifier; | 387 | using ColorModifier = Regs::TevStageConfig::ColorModifier; |
| 382 | using AlphaModifier = Regs::TevStageConfig::AlphaModifier; | 388 | using AlphaModifier = Regs::TevStageConfig::AlphaModifier; |
| @@ -398,6 +404,9 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, | |||
| 398 | case Source::Texture2: | 404 | case Source::Texture2: |
| 399 | return texture_color[2]; | 405 | return texture_color[2]; |
| 400 | 406 | ||
| 407 | case Source::PreviousBuffer: | ||
| 408 | return combiner_buffer; | ||
| 409 | |||
| 401 | case Source::Constant: | 410 | case Source::Constant: |
| 402 | return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b, tev_stage.const_a}; | 411 | return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b, tev_stage.const_a}; |
| 403 | 412 | ||
| @@ -407,7 +416,7 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, | |||
| 407 | default: | 416 | default: |
| 408 | LOG_ERROR(HW_GPU, "Unknown color combiner source %d\n", (int)source); | 417 | LOG_ERROR(HW_GPU, "Unknown color combiner source %d\n", (int)source); |
| 409 | UNIMPLEMENTED(); | 418 | UNIMPLEMENTED(); |
| 410 | return {}; | 419 | return {0, 0, 0, 0}; |
| 411 | } | 420 | } |
| 412 | }; | 421 | }; |
| 413 | 422 | ||
| @@ -490,6 +499,16 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, | |||
| 490 | return result.Cast<u8>(); | 499 | return result.Cast<u8>(); |
| 491 | } | 500 | } |
| 492 | 501 | ||
| 502 | case Operation::AddSigned: | ||
| 503 | { | ||
| 504 | // TODO(bunnei): Verify that the color conversion from (float) 0.5f to (byte) 128 is correct | ||
| 505 | auto result = input[0].Cast<int>() + input[1].Cast<int>() - Math::MakeVec<int>(128, 128, 128); | ||
| 506 | result.r() = MathUtil::Clamp<int>(result.r(), 0, 255); | ||
| 507 | result.g() = MathUtil::Clamp<int>(result.g(), 0, 255); | ||
| 508 | result.b() = MathUtil::Clamp<int>(result.b(), 0, 255); | ||
| 509 | return result.Cast<u8>(); | ||
| 510 | } | ||
| 511 | |||
| 493 | case Operation::Lerp: | 512 | case Operation::Lerp: |
| 494 | return ((input[0] * input[2] + input[1] * (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) / 255).Cast<u8>(); | 513 | return ((input[0] * input[2] + input[1] * (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) / 255).Cast<u8>(); |
| 495 | 514 | ||
| @@ -524,7 +543,7 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, | |||
| 524 | default: | 543 | default: |
| 525 | LOG_ERROR(HW_GPU, "Unknown color combiner operation %d\n", (int)op); | 544 | LOG_ERROR(HW_GPU, "Unknown color combiner operation %d\n", (int)op); |
| 526 | UNIMPLEMENTED(); | 545 | UNIMPLEMENTED(); |
| 527 | return {}; | 546 | return {0, 0, 0}; |
| 528 | } | 547 | } |
| 529 | }; | 548 | }; |
| 530 | 549 | ||
| @@ -578,7 +597,20 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, | |||
| 578 | }; | 597 | }; |
| 579 | auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result); | 598 | auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result); |
| 580 | 599 | ||
| 581 | combiner_output = Math::MakeVec(color_output, alpha_output); | 600 | combiner_output[0] = std::min((unsigned)255, color_output.r() * tev_stage.GetColorMultiplier()); |
| 601 | combiner_output[1] = std::min((unsigned)255, color_output.g() * tev_stage.GetColorMultiplier()); | ||
| 602 | combiner_output[2] = std::min((unsigned)255, color_output.b() * tev_stage.GetColorMultiplier()); | ||
| 603 | combiner_output[3] = std::min((unsigned)255, alpha_output * tev_stage.GetAlphaMultiplier()); | ||
| 604 | |||
| 605 | if (registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferColor(tev_stage_index)) { | ||
| 606 | combiner_buffer.r() = combiner_output.r(); | ||
| 607 | combiner_buffer.g() = combiner_output.g(); | ||
| 608 | combiner_buffer.b() = combiner_output.b(); | ||
| 609 | } | ||
| 610 | |||
| 611 | if (registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferAlpha(tev_stage_index)) { | ||
| 612 | combiner_buffer.a() = combiner_output.a(); | ||
| 613 | } | ||
| 582 | } | 614 | } |
| 583 | 615 | ||
| 584 | if (registers.output_merger.alpha_test.enable) { | 616 | if (registers.output_merger.alpha_test.enable) { |
| @@ -624,9 +656,10 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, | |||
| 624 | 656 | ||
| 625 | // TODO: Does depth indeed only get written even if depth testing is enabled? | 657 | // TODO: Does depth indeed only get written even if depth testing is enabled? |
| 626 | if (registers.output_merger.depth_test_enable) { | 658 | if (registers.output_merger.depth_test_enable) { |
| 627 | u16 z = (u16)((v0.screenpos[2].ToFloat32() * w0 + | 659 | unsigned num_bits = Pica::Regs::DepthBitsPerPixel(registers.framebuffer.depth_format); |
| 628 | v1.screenpos[2].ToFloat32() * w1 + | 660 | u32 z = (u32)((v0.screenpos[2].ToFloat32() * w0 + |
| 629 | v2.screenpos[2].ToFloat32() * w2) * 65535.f / wsum); | 661 | v1.screenpos[2].ToFloat32() * w1 + |
| 662 | v2.screenpos[2].ToFloat32() * w2) * ((1 << num_bits) - 1) / wsum); | ||
| 630 | u32 ref_z = GetDepth(x >> 4, y >> 4); | 663 | u32 ref_z = GetDepth(x >> 4, y >> 4); |
| 631 | 664 | ||
| 632 | bool pass = false; | 665 | bool pass = false; |