diff options
Diffstat (limited to 'src/video_core/regs_lighting.h')
| -rw-r--r-- | src/video_core/regs_lighting.h | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/src/video_core/regs_lighting.h b/src/video_core/regs_lighting.h index 6793405d9..fbfebc0a7 100644 --- a/src/video_core/regs_lighting.h +++ b/src/video_core/regs_lighting.h | |||
| @@ -26,6 +26,16 @@ struct LightingRegs { | |||
| 26 | DistanceAttenuation = 16, | 26 | DistanceAttenuation = 16, |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | static LightingSampler SpotlightAttenuationSampler(unsigned index) { | ||
| 30 | return static_cast<LightingSampler>( | ||
| 31 | static_cast<unsigned>(LightingSampler::SpotlightAttenuation) + index); | ||
| 32 | } | ||
| 33 | |||
| 34 | static LightingSampler DistanceAttenuationSampler(unsigned index) { | ||
| 35 | return static_cast<LightingSampler>( | ||
| 36 | static_cast<unsigned>(LightingSampler::DistanceAttenuation) + index); | ||
| 37 | } | ||
| 38 | |||
| 29 | /** | 39 | /** |
| 30 | * Pica fragment lighting supports using different LUTs for each lighting component: Reflectance | 40 | * Pica fragment lighting supports using different LUTs for each lighting component: Reflectance |
| 31 | * R, G, and B channels, distribution function for specular components 0 and 1, fresnel factor, | 41 | * R, G, and B channels, distribution function for specular components 0 and 1, fresnel factor, |
| @@ -73,6 +83,8 @@ struct LightingRegs { | |||
| 73 | VH = 1, // Cosine of the angle between the view and half-angle vectors | 83 | VH = 1, // Cosine of the angle between the view and half-angle vectors |
| 74 | NV = 2, // Cosine of the angle between the normal and the view vector | 84 | NV = 2, // Cosine of the angle between the normal and the view vector |
| 75 | LN = 3, // Cosine of the angle between the light and the normal vectors | 85 | LN = 3, // Cosine of the angle between the light and the normal vectors |
| 86 | SP = 4, // Cosine of the angle between the light and the inverse spotlight vectors | ||
| 87 | CP = 5, // TODO: document and implement | ||
| 76 | }; | 88 | }; |
| 77 | 89 | ||
| 78 | enum class LightingBumpMode : u32 { | 90 | enum class LightingBumpMode : u32 { |
| @@ -104,6 +116,9 @@ struct LightingRegs { | |||
| 104 | return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && | 116 | return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && |
| 105 | (config != LightingConfig::Config5); | 117 | (config != LightingConfig::Config5); |
| 106 | 118 | ||
| 119 | case LightingSampler::SpotlightAttenuation: | ||
| 120 | return (config != LightingConfig::Config2) && (config != LightingConfig::Config3); | ||
| 121 | |||
| 107 | case LightingSampler::Fresnel: | 122 | case LightingSampler::Fresnel: |
| 108 | return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && | 123 | return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && |
| 109 | (config != LightingConfig::Config4); | 124 | (config != LightingConfig::Config4); |
| @@ -116,11 +131,10 @@ struct LightingRegs { | |||
| 116 | return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) || | 131 | return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) || |
| 117 | (config == LightingConfig::Config7); | 132 | (config == LightingConfig::Config7); |
| 118 | default: | 133 | default: |
| 119 | UNREACHABLE_MSG("Regs::IsLightingSamplerSupported: Reached " | 134 | UNREACHABLE_MSG("Regs::IsLightingSamplerSupported: Reached unreachable section, " |
| 120 | "unreachable section, sampler should be one " | 135 | "sampler should be one of Distribution0, Distribution1, " |
| 121 | "of Distribution0, Distribution1, Fresnel, " | 136 | "SpotlightAttenuation, Fresnel, ReflectRed, ReflectGreen or " |
| 122 | "ReflectRed, ReflectGreen or ReflectBlue, instead " | 137 | "ReflectBlue, instead got %i", |
| 123 | "got %i", | ||
| 124 | static_cast<int>(config)); | 138 | static_cast<int>(config)); |
| 125 | } | 139 | } |
| 126 | } | 140 | } |
| @@ -140,7 +154,16 @@ struct LightingRegs { | |||
| 140 | BitField<0, 16, u32> z; | 154 | BitField<0, 16, u32> z; |
| 141 | }; | 155 | }; |
| 142 | 156 | ||
| 143 | INSERT_PADDING_WORDS(0x3); | 157 | // inverse spotlight direction vector, encoded as fixed1.1.11 |
| 158 | union { | ||
| 159 | BitField<0, 13, s32> spot_x; | ||
| 160 | BitField<16, 13, s32> spot_y; | ||
| 161 | }; | ||
| 162 | union { | ||
| 163 | BitField<0, 13, s32> spot_z; | ||
| 164 | }; | ||
| 165 | |||
| 166 | INSERT_PADDING_WORDS(0x1); | ||
| 144 | 167 | ||
| 145 | union { | 168 | union { |
| 146 | BitField<0, 1, u32> directional; | 169 | BitField<0, 1, u32> directional; |
| @@ -169,8 +192,16 @@ struct LightingRegs { | |||
| 169 | } config0; | 192 | } config0; |
| 170 | 193 | ||
| 171 | union { | 194 | union { |
| 195 | u32 raw; | ||
| 196 | |||
| 197 | // Each bit specifies whether spot light attenuation should be applied for the corresponding | ||
| 198 | // light. | ||
| 199 | BitField<8, 8, u32> disable_spot_atten; | ||
| 200 | |||
| 172 | BitField<16, 1, u32> disable_lut_d0; | 201 | BitField<16, 1, u32> disable_lut_d0; |
| 173 | BitField<17, 1, u32> disable_lut_d1; | 202 | BitField<17, 1, u32> disable_lut_d1; |
| 203 | // Note: by intuition, BitField<18, 1, u32> should be disable_lut_sp, but it is actually a | ||
| 204 | // dummy bit which is always set as 1. | ||
| 174 | BitField<19, 1, u32> disable_lut_fr; | 205 | BitField<19, 1, u32> disable_lut_fr; |
| 175 | BitField<20, 1, u32> disable_lut_rr; | 206 | BitField<20, 1, u32> disable_lut_rr; |
| 176 | BitField<21, 1, u32> disable_lut_rg; | 207 | BitField<21, 1, u32> disable_lut_rg; |
| @@ -178,23 +209,15 @@ struct LightingRegs { | |||
| 178 | 209 | ||
| 179 | // Each bit specifies whether distance attenuation should be applied for the corresponding | 210 | // Each bit specifies whether distance attenuation should be applied for the corresponding |
| 180 | // light. | 211 | // light. |
| 181 | BitField<24, 1, u32> disable_dist_atten_light_0; | 212 | BitField<24, 8, u32> disable_dist_atten; |
| 182 | BitField<25, 1, u32> disable_dist_atten_light_1; | ||
| 183 | BitField<26, 1, u32> disable_dist_atten_light_2; | ||
| 184 | BitField<27, 1, u32> disable_dist_atten_light_3; | ||
| 185 | BitField<28, 1, u32> disable_dist_atten_light_4; | ||
| 186 | BitField<29, 1, u32> disable_dist_atten_light_5; | ||
| 187 | BitField<30, 1, u32> disable_dist_atten_light_6; | ||
| 188 | BitField<31, 1, u32> disable_dist_atten_light_7; | ||
| 189 | } config1; | 213 | } config1; |
| 190 | 214 | ||
| 191 | bool IsDistAttenDisabled(unsigned index) const { | 215 | bool IsDistAttenDisabled(unsigned index) const { |
| 192 | const unsigned disable[] = { | 216 | return (config1.disable_dist_atten & (1 << index)) != 0; |
| 193 | config1.disable_dist_atten_light_0, config1.disable_dist_atten_light_1, | 217 | } |
| 194 | config1.disable_dist_atten_light_2, config1.disable_dist_atten_light_3, | 218 | |
| 195 | config1.disable_dist_atten_light_4, config1.disable_dist_atten_light_5, | 219 | bool IsSpotAttenDisabled(unsigned index) const { |
| 196 | config1.disable_dist_atten_light_6, config1.disable_dist_atten_light_7}; | 220 | return (config1.disable_spot_atten & (1 << index)) != 0; |
| 197 | return disable[index] != 0; | ||
| 198 | } | 221 | } |
| 199 | 222 | ||
| 200 | union { | 223 | union { |