Просмотр исходного кода

pica: prepare registers for spotlight

wwylele 9 лет назад
Родитель
Сommit
b5addf8fb8
1 измененных файлов с 43 добавлено и 20 удалено
  1. 43 20
      src/video_core/regs_lighting.h

+ 43 - 20
src/video_core/regs_lighting.h

@@ -26,6 +26,16 @@ struct LightingRegs {
         DistanceAttenuation = 16,
         DistanceAttenuation = 16,
     };
     };
 
 
+    static LightingSampler SpotlightAttenuationSampler(unsigned index) {
+        return static_cast<LightingSampler>(
+            static_cast<unsigned>(LightingSampler::SpotlightAttenuation) + index);
+    }
+
+    static LightingSampler DistanceAttenuationSampler(unsigned index) {
+        return static_cast<LightingSampler>(
+            static_cast<unsigned>(LightingSampler::DistanceAttenuation) + index);
+    }
+
     /**
     /**
     * Pica fragment lighting supports using different LUTs for each lighting component:  Reflectance
     * Pica fragment lighting supports using different LUTs for each lighting component:  Reflectance
     * R, G, and B channels, distribution function for specular components 0 and 1, fresnel factor,
     * R, G, and B channels, distribution function for specular components 0 and 1, fresnel factor,
@@ -73,6 +83,8 @@ struct LightingRegs {
         VH = 1, // Cosine of the angle between the view and half-angle vectors
         VH = 1, // Cosine of the angle between the view and half-angle vectors
         NV = 2, // Cosine of the angle between the normal and the view vector
         NV = 2, // Cosine of the angle between the normal and the view vector
         LN = 3, // Cosine of the angle between the light and the normal vectors
         LN = 3, // Cosine of the angle between the light and the normal vectors
+        SP = 4, // Cosine of the angle between the light and the inverse spotlight vectors
+        CP = 5, // TODO: document and implement
     };
     };
 
 
     enum class LightingBumpMode : u32 {
     enum class LightingBumpMode : u32 {
@@ -104,6 +116,9 @@ struct LightingRegs {
             return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) &&
             return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) &&
                    (config != LightingConfig::Config5);
                    (config != LightingConfig::Config5);
 
 
+        case LightingSampler::SpotlightAttenuation:
+            return (config != LightingConfig::Config2) && (config != LightingConfig::Config3);
+
         case LightingSampler::Fresnel:
         case LightingSampler::Fresnel:
             return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) &&
             return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) &&
                    (config != LightingConfig::Config4);
                    (config != LightingConfig::Config4);
@@ -116,11 +131,10 @@ struct LightingRegs {
             return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) ||
             return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) ||
                    (config == LightingConfig::Config7);
                    (config == LightingConfig::Config7);
         default:
         default:
-            UNREACHABLE_MSG("Regs::IsLightingSamplerSupported: Reached "
-                            "unreachable section, sampler should be one "
-                            "of Distribution0, Distribution1, Fresnel, "
-                            "ReflectRed, ReflectGreen or ReflectBlue, instead "
-                            "got %i",
+            UNREACHABLE_MSG("Regs::IsLightingSamplerSupported: Reached unreachable section, "
+                            "sampler should be one of Distribution0, Distribution1, "
+                            "SpotlightAttenuation, Fresnel, ReflectRed, ReflectGreen or "
+                            "ReflectBlue, instead got %i",
                             static_cast<int>(config));
                             static_cast<int>(config));
         }
         }
     }
     }
@@ -140,7 +154,16 @@ struct LightingRegs {
             BitField<0, 16, u32> z;
             BitField<0, 16, u32> z;
         };
         };
 
 
-        INSERT_PADDING_WORDS(0x3);
+        // inverse spotlight direction vector, encoded as fixed1.1.11
+        union {
+            BitField<0, 13, s32> spot_x;
+            BitField<16, 13, s32> spot_y;
+        };
+        union {
+            BitField<0, 13, s32> spot_z;
+        };
+
+        INSERT_PADDING_WORDS(0x1);
 
 
         union {
         union {
             BitField<0, 1, u32> directional;
             BitField<0, 1, u32> directional;
@@ -169,8 +192,16 @@ struct LightingRegs {
     } config0;
     } config0;
 
 
     union {
     union {
+        u32 raw;
+
+        // Each bit specifies whether spot light attenuation should be applied for the corresponding
+        // light.
+        BitField<8, 8, u32> disable_spot_atten;
+
         BitField<16, 1, u32> disable_lut_d0;
         BitField<16, 1, u32> disable_lut_d0;
         BitField<17, 1, u32> disable_lut_d1;
         BitField<17, 1, u32> disable_lut_d1;
+        // Note: by intuition, BitField<18, 1, u32> should be disable_lut_sp, but it is actually a
+        // dummy bit which is always set as 1.
         BitField<19, 1, u32> disable_lut_fr;
         BitField<19, 1, u32> disable_lut_fr;
         BitField<20, 1, u32> disable_lut_rr;
         BitField<20, 1, u32> disable_lut_rr;
         BitField<21, 1, u32> disable_lut_rg;
         BitField<21, 1, u32> disable_lut_rg;
@@ -178,23 +209,15 @@ struct LightingRegs {
 
 
         // Each bit specifies whether distance attenuation should be applied for the corresponding
         // Each bit specifies whether distance attenuation should be applied for the corresponding
         // light.
         // light.
-        BitField<24, 1, u32> disable_dist_atten_light_0;
-        BitField<25, 1, u32> disable_dist_atten_light_1;
-        BitField<26, 1, u32> disable_dist_atten_light_2;
-        BitField<27, 1, u32> disable_dist_atten_light_3;
-        BitField<28, 1, u32> disable_dist_atten_light_4;
-        BitField<29, 1, u32> disable_dist_atten_light_5;
-        BitField<30, 1, u32> disable_dist_atten_light_6;
-        BitField<31, 1, u32> disable_dist_atten_light_7;
+        BitField<24, 8, u32> disable_dist_atten;
     } config1;
     } config1;
 
 
     bool IsDistAttenDisabled(unsigned index) const {
     bool IsDistAttenDisabled(unsigned index) const {
-        const unsigned disable[] = {
-            config1.disable_dist_atten_light_0, config1.disable_dist_atten_light_1,
-            config1.disable_dist_atten_light_2, config1.disable_dist_atten_light_3,
-            config1.disable_dist_atten_light_4, config1.disable_dist_atten_light_5,
-            config1.disable_dist_atten_light_6, config1.disable_dist_atten_light_7};
-        return disable[index] != 0;
+        return (config1.disable_dist_atten & (1 << index)) != 0;
+    }
+
+    bool IsSpotAttenDisabled(unsigned index) const {
+        return (config1.disable_spot_atten & (1 << index)) != 0;
     }
     }
 
 
     union {
     union {