diff options
| author | bunnei <bunneidev@gmail.com> | 2015-05-06 22:18:11 -0400 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2015-05-09 22:12:36 -0400 | 
| commit | a806b420a64d44e8b9a0d6f0a742d7eaad06168a (patch) | |
| tree | 5620a7882d73cbefbf63a0a0813507fc512eef16 /src/video_core | |
| parent | 44927f03061a8703a2b2c4411d367a5a8047d18a (diff) | |
rasterizer: Implement combiner buffer input.
Diffstat (limited to 'src/video_core')
| -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 {              Texture1               = 0x4,              Texture2               = 0x5,              Texture3               = 0x6, -            // 0x7-0xc = primary color?? + +            PreviousBuffer         = 0xd,              Constant               = 0xe,              Previous               = 0xf,          }; @@ -309,11 +310,36 @@ struct Regs {      TevStageConfig tev_stage2;      INSERT_PADDING_WORDS(0x3);      TevStageConfig tev_stage3; -    INSERT_PADDING_WORDS(0x13); +    INSERT_PADDING_WORDS(0x3); + +    union { +        // Tev stages 0-3 write their output to the combiner buffer if the corresponding bit in +        // these masks are set +        BitField< 8, 4, u32> update_mask_rgb; +        BitField<12, 4, u32> update_mask_a; + +        bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { +            return (stage_index < 4) && (update_mask_rgb & (1 << stage_index)); +        } + +        bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const { +            return (stage_index < 4) && (update_mask_a & (1 << stage_index)); +        } +    } tev_combiner_buffer_input; +     +    INSERT_PADDING_WORDS(0xf);      TevStageConfig tev_stage4;      INSERT_PADDING_WORDS(0x3);      TevStageConfig tev_stage5; -    INSERT_PADDING_WORDS(0x3); + +    union { +        BitField< 0, 8, u32> r; +        BitField< 8, 8, u32> g; +        BitField<16, 8, u32> b; +        BitField<24, 8, u32> a; +    } tev_combiner_buffer_color; + +    INSERT_PADDING_WORDS(0x2);      const std::array<Regs::TevStageConfig,6> GetTevStages() const {          return { tev_stage0, tev_stage1, @@ -784,8 +810,10 @@ struct Regs {          ADD_FIELD(tev_stage1);          ADD_FIELD(tev_stage2);          ADD_FIELD(tev_stage3); +        ADD_FIELD(tev_combiner_buffer_input);          ADD_FIELD(tev_stage4);          ADD_FIELD(tev_stage5); +        ADD_FIELD(tev_combiner_buffer_color);          ADD_FIELD(output_merger);          ADD_FIELD(framebuffer);          ADD_FIELD(vertex_attributes); @@ -859,8 +887,10 @@ ASSERT_REG_POSITION(tev_stage0, 0xc0);  ASSERT_REG_POSITION(tev_stage1, 0xc8);  ASSERT_REG_POSITION(tev_stage2, 0xd0);  ASSERT_REG_POSITION(tev_stage3, 0xd8); +ASSERT_REG_POSITION(tev_combiner_buffer_input, 0xe0);  ASSERT_REG_POSITION(tev_stage4, 0xf0);  ASSERT_REG_POSITION(tev_stage5, 0xf8); +ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd);  ASSERT_REG_POSITION(output_merger, 0x100);  ASSERT_REG_POSITION(framebuffer, 0x110);  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,              // with some basic arithmetic. Alpha combiners can be configured separately but work              // analogously.              Math::Vec4<u8> combiner_output; -            for (const auto& tev_stage : tev_stages) { +            Math::Vec4<u8> combiner_buffer = { +                registers.tev_combiner_buffer_color.r, registers.tev_combiner_buffer_color.g, +                registers.tev_combiner_buffer_color.b, registers.tev_combiner_buffer_color.a +            }; + +            for (unsigned tev_stage_index = 0; tev_stage_index < tev_stages.size(); ++tev_stage_index) { +                const auto& tev_stage = tev_stages[tev_stage_index];                  using Source = Regs::TevStageConfig::Source;                  using ColorModifier = Regs::TevStageConfig::ColorModifier;                  using AlphaModifier = Regs::TevStageConfig::AlphaModifier; @@ -398,6 +404,9 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,                      case Source::Texture2:                          return texture_color[2]; +                    case Source::PreviousBuffer: +                        return combiner_buffer; +                      case Source::Constant:                          return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b, tev_stage.const_a}; @@ -579,6 +588,16 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,                  auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result);                  combiner_output = Math::MakeVec(color_output, alpha_output); + +                if (registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferColor(tev_stage_index)) { +                    combiner_buffer.r() = combiner_output.r(); +                    combiner_buffer.g() = combiner_output.g(); +                    combiner_buffer.b() = combiner_output.b(); +                } + +                if (registers.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferAlpha(tev_stage_index)) { +                    combiner_buffer.a() = combiner_output.a(); +                }              }              if (registers.output_merger.alpha_test.enable) { | 
