Răsfoiți Sursa

Merge pull request #517 from bunnei/blend-factors

Pica: Implement blend factors.
Tony Wasserka 11 ani în urmă
părinte
comite
e1f9f9ea04
2 a modificat fișierele cu 67 adăugiri și 10 ștergeri
  1. 21 6
      src/video_core/pica.h
  2. 46 4
      src/video_core/rasterizer.cpp

+ 21 - 6
src/video_core/pica.h

@@ -332,11 +332,21 @@ struct Regs {
             };
 
             enum BlendFactor : u32 {
-                Zero = 0,
-                One = 1,
-
-                SourceAlpha = 6,
-                OneMinusSourceAlpha = 7,
+                Zero                    = 0,
+                One                     = 1,
+                SourceColor             = 2,
+                OneMinusSourceColor     = 3,
+                DestColor               = 4,
+                OneMinusDestColor       = 5,
+                SourceAlpha             = 6,
+                OneMinusSourceAlpha     = 7,
+                DestAlpha               = 8,
+                OneMinusDestAlpha       = 9,
+                ConstantColor           = 10,
+                OneMinusConstantColor   = 11,
+                ConstantAlpha           = 12,
+                OneMinusConstantAlpha   = 13,
+                SourceAlphaSaturate     = 14
             };
 
             BitField< 0, 8, BlendEquation> blend_equation_rgb;
@@ -357,7 +367,12 @@ struct Regs {
             BitField<0, 4, Op> op;
         } logic_op;
 
-        INSERT_PADDING_WORDS(0x1);
+        union {
+            BitField< 0, 8, u32> r;
+            BitField< 8, 8, u32> g;
+            BitField<16, 8, u32> b;
+            BitField<24, 8, u32> a;
+        } blend_const;
 
         union {
             BitField< 0, 1, u32> enable;

+ 46 - 4
src/video_core/rasterizer.cpp

@@ -528,18 +528,48 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
                 auto params = registers.output_merger.alpha_blending;
 
                 auto LookupFactorRGB = [&](decltype(params)::BlendFactor factor) -> Math::Vec3<u8> {
-                    switch(factor) {
+                    switch (factor) {
                     case params.Zero:
                         return Math::Vec3<u8>(0, 0, 0);
 
                     case params.One:
                         return Math::Vec3<u8>(255, 255, 255);
 
+                    case params.SourceColor:
+                        return combiner_output.rgb();
+
+                    case params.OneMinusSourceColor:
+                        return Math::Vec3<u8>(255 - combiner_output.r(), 255 - combiner_output.g(), 255 - combiner_output.b());
+
+                    case params.DestColor:
+                        return dest.rgb();
+
+                    case params.OneMinusDestColor:
+                        return Math::Vec3<u8>(255 - dest.r(), 255 - dest.g(), 255 - dest.b());
+
                     case params.SourceAlpha:
-                        return Math::MakeVec(combiner_output.a(), combiner_output.a(), combiner_output.a());
+                        return Math::Vec3<u8>(combiner_output.a(), combiner_output.a(), combiner_output.a());
 
                     case params.OneMinusSourceAlpha:
-                        return Math::Vec3<u8>(255-combiner_output.a(), 255-combiner_output.a(), 255-combiner_output.a());
+                        return Math::Vec3<u8>(255 - combiner_output.a(), 255 - combiner_output.a(), 255 - combiner_output.a());
+
+                    case params.DestAlpha:
+                        return Math::Vec3<u8>(dest.a(), dest.a(), dest.a());
+
+                    case params.OneMinusDestAlpha:
+                        return Math::Vec3<u8>(255 - dest.a(), 255 - dest.a(), 255 - dest.a());
+
+                    case params.ConstantColor:
+                        return Math::Vec3<u8>(registers.output_merger.blend_const.r, registers.output_merger.blend_const.g, registers.output_merger.blend_const.b);
+
+                    case params.OneMinusConstantColor:
+                        return Math::Vec3<u8>(255 - registers.output_merger.blend_const.r, 255 - registers.output_merger.blend_const.g, 255 - registers.output_merger.blend_const.b);
+
+                    case params.ConstantAlpha:
+                        return Math::Vec3<u8>(registers.output_merger.blend_const.a, registers.output_merger.blend_const.a, registers.output_merger.blend_const.a);
+
+                    case params.OneMinusConstantAlpha:
+                        return Math::Vec3<u8>(255 - registers.output_merger.blend_const.a, 255 - registers.output_merger.blend_const.a, 255 - registers.output_merger.blend_const.a);
 
                     default:
                         LOG_CRITICAL(HW_GPU, "Unknown color blend factor %x", factor);
@@ -549,7 +579,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
                 };
 
                 auto LookupFactorA = [&](decltype(params)::BlendFactor factor) -> u8 {
-                    switch(factor) {
+                    switch (factor) {
                     case params.Zero:
                         return 0;
 
@@ -562,6 +592,18 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
                     case params.OneMinusSourceAlpha:
                         return 255 - combiner_output.a();
 
+                    case params.DestAlpha:
+                        return dest.a();
+
+                    case params.OneMinusDestAlpha:
+                        return 255 - dest.a();
+
+                    case params.ConstantAlpha:
+                        return registers.output_merger.blend_const.a;
+
+                    case params.OneMinusConstantAlpha:
+                        return 255 - registers.output_merger.blend_const.a;
+
                     default:
                         LOG_CRITICAL(HW_GPU, "Unknown alpha blend factor %x", factor);
                         exit(0);