mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	rasterizer: Implement combiner buffer input.
This commit is contained in:
		
							parent
							
								
									44927f0306
								
							
						
					
					
						commit
						a806b420a6
					
				
					 2 changed files with 53 additions and 4 deletions
				
			
		|  | @ -226,7 +226,8 @@ struct Regs { | ||||||
|             Texture1               = 0x4, |             Texture1               = 0x4, | ||||||
|             Texture2               = 0x5, |             Texture2               = 0x5, | ||||||
|             Texture3               = 0x6, |             Texture3               = 0x6, | ||||||
|             // 0x7-0xc = primary color??
 | 
 | ||||||
|  |             PreviousBuffer         = 0xd, | ||||||
|             Constant               = 0xe, |             Constant               = 0xe, | ||||||
|             Previous               = 0xf, |             Previous               = 0xf, | ||||||
|         }; |         }; | ||||||
|  | @ -309,11 +310,36 @@ struct Regs { | ||||||
|     TevStageConfig tev_stage2; |     TevStageConfig tev_stage2; | ||||||
|     INSERT_PADDING_WORDS(0x3); |     INSERT_PADDING_WORDS(0x3); | ||||||
|     TevStageConfig tev_stage3; |     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; |     TevStageConfig tev_stage4; | ||||||
|     INSERT_PADDING_WORDS(0x3); |     INSERT_PADDING_WORDS(0x3); | ||||||
|     TevStageConfig tev_stage5; |     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 { |     const std::array<Regs::TevStageConfig,6> GetTevStages() const { | ||||||
|         return { tev_stage0, tev_stage1, |         return { tev_stage0, tev_stage1, | ||||||
|  | @ -784,8 +810,10 @@ struct Regs { | ||||||
|         ADD_FIELD(tev_stage1); |         ADD_FIELD(tev_stage1); | ||||||
|         ADD_FIELD(tev_stage2); |         ADD_FIELD(tev_stage2); | ||||||
|         ADD_FIELD(tev_stage3); |         ADD_FIELD(tev_stage3); | ||||||
|  |         ADD_FIELD(tev_combiner_buffer_input); | ||||||
|         ADD_FIELD(tev_stage4); |         ADD_FIELD(tev_stage4); | ||||||
|         ADD_FIELD(tev_stage5); |         ADD_FIELD(tev_stage5); | ||||||
|  |         ADD_FIELD(tev_combiner_buffer_color); | ||||||
|         ADD_FIELD(output_merger); |         ADD_FIELD(output_merger); | ||||||
|         ADD_FIELD(framebuffer); |         ADD_FIELD(framebuffer); | ||||||
|         ADD_FIELD(vertex_attributes); |         ADD_FIELD(vertex_attributes); | ||||||
|  | @ -859,8 +887,10 @@ ASSERT_REG_POSITION(tev_stage0, 0xc0); | ||||||
| ASSERT_REG_POSITION(tev_stage1, 0xc8); | ASSERT_REG_POSITION(tev_stage1, 0xc8); | ||||||
| ASSERT_REG_POSITION(tev_stage2, 0xd0); | ASSERT_REG_POSITION(tev_stage2, 0xd0); | ||||||
| ASSERT_REG_POSITION(tev_stage3, 0xd8); | ASSERT_REG_POSITION(tev_stage3, 0xd8); | ||||||
|  | ASSERT_REG_POSITION(tev_combiner_buffer_input, 0xe0); | ||||||
| ASSERT_REG_POSITION(tev_stage4, 0xf0); | ASSERT_REG_POSITION(tev_stage4, 0xf0); | ||||||
| ASSERT_REG_POSITION(tev_stage5, 0xf8); | ASSERT_REG_POSITION(tev_stage5, 0xf8); | ||||||
|  | ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd); | ||||||
| ASSERT_REG_POSITION(output_merger, 0x100); | ASSERT_REG_POSITION(output_merger, 0x100); | ||||||
| ASSERT_REG_POSITION(framebuffer, 0x110); | ASSERT_REG_POSITION(framebuffer, 0x110); | ||||||
| ASSERT_REG_POSITION(vertex_attributes, 0x200); | ASSERT_REG_POSITION(vertex_attributes, 0x200); | ||||||
|  |  | ||||||
|  | @ -376,7 +376,13 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, | ||||||
|             // with some basic arithmetic. Alpha combiners can be configured separately but work
 |             // with some basic arithmetic. Alpha combiners can be configured separately but work
 | ||||||
|             // analogously.
 |             // analogously.
 | ||||||
|             Math::Vec4<u8> combiner_output; |             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 Source = Regs::TevStageConfig::Source; | ||||||
|                 using ColorModifier = Regs::TevStageConfig::ColorModifier; |                 using ColorModifier = Regs::TevStageConfig::ColorModifier; | ||||||
|                 using AlphaModifier = Regs::TevStageConfig::AlphaModifier; |                 using AlphaModifier = Regs::TevStageConfig::AlphaModifier; | ||||||
|  | @ -398,6 +404,9 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, | ||||||
|                     case Source::Texture2: |                     case Source::Texture2: | ||||||
|                         return texture_color[2]; |                         return texture_color[2]; | ||||||
| 
 | 
 | ||||||
|  |                     case Source::PreviousBuffer: | ||||||
|  |                         return combiner_buffer; | ||||||
|  | 
 | ||||||
|                     case Source::Constant: |                     case Source::Constant: | ||||||
|                         return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b, tev_stage.const_a}; |                         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); |                 auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result); | ||||||
| 
 | 
 | ||||||
|                 combiner_output = Math::MakeVec(color_output, alpha_output); |                 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) { |             if (registers.output_merger.alpha_test.enable) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue