summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-05-06 22:18:11 -0400
committerGravatar bunnei2015-05-09 22:12:36 -0400
commita806b420a64d44e8b9a0d6f0a742d7eaad06168a (patch)
tree5620a7882d73cbefbf63a0a0813507fc512eef16 /src
parentrasterizer: Return zero'd vectors on error conditions. (diff)
downloadyuzu-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.h36
-rw-r--r--src/video_core/rasterizer.cpp21
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);
859ASSERT_REG_POSITION(tev_stage1, 0xc8); 887ASSERT_REG_POSITION(tev_stage1, 0xc8);
860ASSERT_REG_POSITION(tev_stage2, 0xd0); 888ASSERT_REG_POSITION(tev_stage2, 0xd0);
861ASSERT_REG_POSITION(tev_stage3, 0xd8); 889ASSERT_REG_POSITION(tev_stage3, 0xd8);
890ASSERT_REG_POSITION(tev_combiner_buffer_input, 0xe0);
862ASSERT_REG_POSITION(tev_stage4, 0xf0); 891ASSERT_REG_POSITION(tev_stage4, 0xf0);
863ASSERT_REG_POSITION(tev_stage5, 0xf8); 892ASSERT_REG_POSITION(tev_stage5, 0xf8);
893ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd);
864ASSERT_REG_POSITION(output_merger, 0x100); 894ASSERT_REG_POSITION(output_merger, 0x100);
865ASSERT_REG_POSITION(framebuffer, 0x110); 895ASSERT_REG_POSITION(framebuffer, 0x110);
866ASSERT_REG_POSITION(vertex_attributes, 0x200); 896ASSERT_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) {