diff options
| author | 2015-05-06 22:18:11 -0400 | |
|---|---|---|
| committer | 2015-05-09 22:12:36 -0400 | |
| commit | a806b420a64d44e8b9a0d6f0a742d7eaad06168a (patch) | |
| tree | 5620a7882d73cbefbf63a0a0813507fc512eef16 /src | |
| parent | rasterizer: Return zero'd vectors on error conditions. (diff) | |
| download | yuzu-a806b420a64d44e8b9a0d6f0a742d7eaad06168a.tar.gz yuzu-a806b420a64d44e8b9a0d6f0a742d7eaad06168a.tar.xz yuzu-a806b420a64d44e8b9a0d6f0a742d7eaad06168a.zip | |
rasterizer: Implement combiner buffer input.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/pica.h | 36 | ||||
| -rw-r--r-- | src/video_core/rasterizer.cpp | 21 |
2 files changed, 53 insertions, 4 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index e4a91058c..30c8b7816 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -226,7 +226,8 @@ struct Regs { | |||
| 226 | Texture1 = 0x4, | 226 | Texture1 = 0x4, |
| 227 | Texture2 = 0x5, | 227 | Texture2 = 0x5, |
| 228 | Texture3 = 0x6, | 228 | Texture3 = 0x6, |
| 229 | // 0x7-0xc = primary color?? | 229 | |
| 230 | PreviousBuffer = 0xd, | ||
| 230 | Constant = 0xe, | 231 | Constant = 0xe, |
| 231 | Previous = 0xf, | 232 | Previous = 0xf, |
| 232 | }; | 233 | }; |
| @@ -309,11 +310,36 @@ struct Regs { | |||
| 309 | TevStageConfig tev_stage2; | 310 | TevStageConfig tev_stage2; |
| 310 | INSERT_PADDING_WORDS(0x3); | 311 | INSERT_PADDING_WORDS(0x3); |
| 311 | TevStageConfig tev_stage3; | 312 | TevStageConfig tev_stage3; |
| 312 | INSERT_PADDING_WORDS(0x13); | 313 | INSERT_PADDING_WORDS(0x3); |
| 314 | |||
| 315 | union { | ||
| 316 | // Tev stages 0-3 write their output to the combiner buffer if the corresponding bit in | ||
| 317 | // these masks are set | ||
| 318 | BitField< 8, 4, u32> update_mask_rgb; | ||
| 319 | BitField<12, 4, u32> update_mask_a; | ||
| 320 | |||
| 321 | bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { | ||
| 322 | return (stage_index < 4) && (update_mask_rgb & (1 << stage_index)); | ||
| 323 | } | ||
| 324 | |||
| 325 | bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const { | ||
| 326 | return (stage_index < 4) && (update_mask_a & (1 << stage_index)); | ||
| 327 | } | ||
| 328 | } tev_combiner_buffer_input; | ||
| 329 | |||
| 330 | INSERT_PADDING_WORDS(0xf); | ||
| 313 | TevStageConfig tev_stage4; | 331 | TevStageConfig tev_stage4; |
| 314 | INSERT_PADDING_WORDS(0x3); | 332 | INSERT_PADDING_WORDS(0x3); |
| 315 | TevStageConfig tev_stage5; | 333 | TevStageConfig tev_stage5; |
| 316 | INSERT_PADDING_WORDS(0x3); | 334 | |
| 335 | union { | ||
| 336 | BitField< 0, 8, u32> r; | ||
| 337 | BitField< 8, 8, u32> g; | ||
| 338 | BitField<16, 8, u32> b; | ||
| 339 | BitField<24, 8, u32> a; | ||
| 340 | } tev_combiner_buffer_color; | ||
| 341 | |||
| 342 | INSERT_PADDING_WORDS(0x2); | ||
| 317 | 343 | ||
| 318 | const std::array<Regs::TevStageConfig,6> GetTevStages() const { | 344 | const std::array<Regs::TevStageConfig,6> GetTevStages() const { |
| 319 | return { tev_stage0, tev_stage1, | 345 | return { tev_stage0, tev_stage1, |
| @@ -784,8 +810,10 @@ struct Regs { | |||
| 784 | ADD_FIELD(tev_stage1); | 810 | ADD_FIELD(tev_stage1); |
| 785 | ADD_FIELD(tev_stage2); | 811 | ADD_FIELD(tev_stage2); |
| 786 | ADD_FIELD(tev_stage3); | 812 | ADD_FIELD(tev_stage3); |
| 813 | ADD_FIELD(tev_combiner_buffer_input); | ||
| 787 | ADD_FIELD(tev_stage4); | 814 | ADD_FIELD(tev_stage4); |
| 788 | ADD_FIELD(tev_stage5); | 815 | ADD_FIELD(tev_stage5); |
| 816 | ADD_FIELD(tev_combiner_buffer_color); | ||
| 789 | ADD_FIELD(output_merger); | 817 | ADD_FIELD(output_merger); |
| 790 | ADD_FIELD(framebuffer); | 818 | ADD_FIELD(framebuffer); |
| 791 | ADD_FIELD(vertex_attributes); | 819 | ADD_FIELD(vertex_attributes); |
| @@ -859,8 +887,10 @@ ASSERT_REG_POSITION(tev_stage0, 0xc0); | |||
| 859 | ASSERT_REG_POSITION(tev_stage1, 0xc8); | 887 | ASSERT_REG_POSITION(tev_stage1, 0xc8); |
| 860 | ASSERT_REG_POSITION(tev_stage2, 0xd0); | 888 | ASSERT_REG_POSITION(tev_stage2, 0xd0); |
| 861 | ASSERT_REG_POSITION(tev_stage3, 0xd8); | 889 | ASSERT_REG_POSITION(tev_stage3, 0xd8); |
| 890 | ASSERT_REG_POSITION(tev_combiner_buffer_input, 0xe0); | ||
| 862 | ASSERT_REG_POSITION(tev_stage4, 0xf0); | 891 | ASSERT_REG_POSITION(tev_stage4, 0xf0); |
| 863 | ASSERT_REG_POSITION(tev_stage5, 0xf8); | 892 | ASSERT_REG_POSITION(tev_stage5, 0xf8); |
| 893 | ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd); | ||
| 864 | ASSERT_REG_POSITION(output_merger, 0x100); | 894 | ASSERT_REG_POSITION(output_merger, 0x100); |
| 865 | ASSERT_REG_POSITION(framebuffer, 0x110); | 895 | ASSERT_REG_POSITION(framebuffer, 0x110); |
| 866 | ASSERT_REG_POSITION(vertex_attributes, 0x200); | 896 | ASSERT_REG_POSITION(vertex_attributes, 0x200); |
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 3b36afad9..7bdb503c8 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -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 | ||
| @@ -579,6 +588,16 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, | |||
| 579 | auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result); | 588 | auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result); |
| 580 | 589 | ||
| 581 | combiner_output = Math::MakeVec(color_output, alpha_output); | 590 | combiner_output = Math::MakeVec(color_output, alpha_output); |
| 591 | |||
| 592 | if (registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferColor(tev_stage_index)) { | ||
| 593 | combiner_buffer.r() = combiner_output.r(); | ||
| 594 | combiner_buffer.g() = combiner_output.g(); | ||
| 595 | combiner_buffer.b() = combiner_output.b(); | ||
| 596 | } | ||
| 597 | |||
| 598 | if (registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferAlpha(tev_stage_index)) { | ||
| 599 | combiner_buffer.a() = combiner_output.a(); | ||
| 600 | } | ||
| 582 | } | 601 | } |
| 583 | 602 | ||
| 584 | if (registers.output_merger.alpha_test.enable) { | 603 | if (registers.output_merger.alpha_test.enable) { |