diff options
| author | 2015-11-19 19:00:42 -0500 | |
|---|---|---|
| committer | 2016-02-05 17:18:36 -0500 | |
| commit | 781b0465795fb80404e2790be2d10bfb1f7149aa (patch) | |
| tree | 33dc7c84f56ff9dc86aaf88aa4869812ee0f9643 /src | |
| parent | gl_shader_gen: Refactor lighting config to match Pica register naming. (diff) | |
| download | yuzu-781b0465795fb80404e2790be2d10bfb1f7149aa.tar.gz yuzu-781b0465795fb80404e2790be2d10bfb1f7149aa.tar.xz yuzu-781b0465795fb80404e2790be2d10bfb1f7149aa.zip | |
gl_shader_gen: Add support for D0 LUT scaling.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/pica.h | 68 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 2 |
3 files changed, 71 insertions, 3 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index b1cf072f1..5d27da5d1 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -657,6 +657,44 @@ struct Regs { | |||
| 657 | DistanceAttenuation = 16, | 657 | DistanceAttenuation = 16, |
| 658 | }; | 658 | }; |
| 659 | 659 | ||
| 660 | /** | ||
| 661 | * Pica fragment lighting supports using different LUTs for each lighting component: | ||
| 662 | * Reflectance R, G, and B channels, distribution function for specular components 0 and 1, | ||
| 663 | * fresnel factor, and spotlight attenuation. Furthermore, which LUTs are used for each channel | ||
| 664 | * (or whether a channel is enabled at all) is specified by various pre-defined lighting | ||
| 665 | * configurations. With configurations that require more LUTs, more cycles are required on HW to | ||
| 666 | * perform lighting computations. | ||
| 667 | */ | ||
| 668 | enum class LightingConfig { | ||
| 669 | Config0 = 0, ///< Reflect Red, Distribution 0, Spotlight | ||
| 670 | Config1 = 1, ///< Reflect Red, Fresnel, Spotlight | ||
| 671 | Config2 = 2, ///< Reflect Red, Distribution 0/1 | ||
| 672 | Config3 = 3, ///< Distribution 0/1, Fresnel | ||
| 673 | Config4 = 4, ///< Reflect Red/Green/Blue, Distribution 0/1, Spotlight | ||
| 674 | Config5 = 5, ///< Reflect Red/Green/Blue, Distribution 0, Fresnel, Spotlight | ||
| 675 | Config6 = 6, ///< Reflect Red, Distribution 0/1, Fresnel, Spotlight | ||
| 676 | Config7 = 8, ///< Reflect Red/Green/Blue, Distribution 0/1, Fresnel, Spotlight | ||
| 677 | ///< NOTE: '8' is intentional, '7' does not appear to be a valid configuration | ||
| 678 | }; | ||
| 679 | |||
| 680 | /// Selects which lighting components are affected by fresnel | ||
| 681 | enum class LightingFresnelSelector { | ||
| 682 | None = 0, ///< Fresnel is disabled | ||
| 683 | PrimaryAlpha = 1, ///< Primary (diffuse) lighting alpha is affected by fresnel | ||
| 684 | SecondaryAlpha = 2, ///< Secondary (specular) lighting alpha is affected by fresnel | ||
| 685 | Both = PrimaryAlpha | SecondaryAlpha, ///< Both primary and secondary lighting alphas are affected by fresnel | ||
| 686 | }; | ||
| 687 | |||
| 688 | /// Factor used to scale the output of a lighting LUT | ||
| 689 | enum class LightingScale { | ||
| 690 | Scale1 = 0, ///< Scale is 1x | ||
| 691 | Scale2 = 1, ///< Scale is 2x | ||
| 692 | Scale4 = 2, ///< Scale is 4x | ||
| 693 | Scale8 = 3, ///< Scale is 8x | ||
| 694 | Scale1_4 = 6, ///< Scale is 0.25x | ||
| 695 | Scale1_2 = 7, ///< Scale is 0.5x | ||
| 696 | }; | ||
| 697 | |||
| 660 | enum class LightingLutInput { | 698 | enum class LightingLutInput { |
| 661 | NH = 0, // Cosine of the angle between the normal and half-angle vectors | 699 | NH = 0, // Cosine of the angle between the normal and half-angle vectors |
| 662 | VH = 1, // Cosine of the angle between the view and half-angle vectors | 700 | VH = 1, // Cosine of the angle between the view and half-angle vectors |
| @@ -775,7 +813,35 @@ struct Regs { | |||
| 775 | BitField<24, 3, u32> rr; | 813 | BitField<24, 3, u32> rr; |
| 776 | } lut_input; | 814 | } lut_input; |
| 777 | 815 | ||
| 778 | INSERT_PADDING_WORDS(0x7); | 816 | union { |
| 817 | BitField< 0, 3, LightingScale> d0; | ||
| 818 | BitField< 4, 3, LightingScale> d1; | ||
| 819 | BitField< 8, 3, LightingScale> sp; | ||
| 820 | BitField<12, 3, LightingScale> fr; | ||
| 821 | BitField<16, 3, LightingScale> rb; | ||
| 822 | BitField<20, 3, LightingScale> rg; | ||
| 823 | BitField<24, 3, LightingScale> rr; | ||
| 824 | |||
| 825 | static float GetScale(LightingScale scale) { | ||
| 826 | switch (scale) { | ||
| 827 | case LightingScale::Scale1: | ||
| 828 | return 1.0f; | ||
| 829 | case LightingScale::Scale2: | ||
| 830 | return 2.0f; | ||
| 831 | case LightingScale::Scale4: | ||
| 832 | return 4.0f; | ||
| 833 | case LightingScale::Scale8: | ||
| 834 | return 8.0f; | ||
| 835 | case LightingScale::Scale1_4: | ||
| 836 | return 0.25f; | ||
| 837 | case LightingScale::Scale1_2: | ||
| 838 | return 0.5f; | ||
| 839 | } | ||
| 840 | return 0.0f; | ||
| 841 | } | ||
| 842 | } lut_scale; | ||
| 843 | |||
| 844 | INSERT_PADDING_WORDS(0x6); | ||
| 779 | 845 | ||
| 780 | union { | 846 | union { |
| 781 | // There are 8 light enable "slots", corresponding to the total number of lights | 847 | // There are 8 light enable "slots", corresponding to the total number of lights |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 2042be786..72ded8f22 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -90,6 +90,7 @@ struct PicaShaderConfig { | |||
| 90 | res.lighting.lut_d0.enable = regs.lighting.lut_enable_d0 == 0; | 90 | res.lighting.lut_d0.enable = regs.lighting.lut_enable_d0 == 0; |
| 91 | res.lighting.lut_d0.abs_input = regs.lighting.abs_lut_input.d0 == 0; | 91 | res.lighting.lut_d0.abs_input = regs.lighting.abs_lut_input.d0 == 0; |
| 92 | res.lighting.lut_d0.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.d0.Value(); | 92 | res.lighting.lut_d0.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.d0.Value(); |
| 93 | res.lighting.lut_d0.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d0); | ||
| 93 | res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0; | 94 | res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0; |
| 94 | 95 | ||
| 95 | return res; | 96 | return res; |
| @@ -130,7 +131,8 @@ struct PicaShaderConfig { | |||
| 130 | bool enable = false; | 131 | bool enable = false; |
| 131 | bool abs_input = false; | 132 | bool abs_input = false; |
| 132 | Pica::Regs::LightingLutInput type = Pica::Regs::LightingLutInput::NH; | 133 | Pica::Regs::LightingLutInput type = Pica::Regs::LightingLutInput::NH; |
| 133 | } lut_d0; | 134 | float scale = 1.0f; |
| 135 | } lut_d0, lut_d1, lut_fr; | ||
| 134 | } lighting; | 136 | } lighting; |
| 135 | }; | 137 | }; |
| 136 | }; | 138 | }; |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index a2770cc6e..9044a3813 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -412,7 +412,7 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | |||
| 412 | std::string d0_lut_value = "1.0"; | 412 | std::string d0_lut_value = "1.0"; |
| 413 | if (config.lighting.lut_d0.enable) { | 413 | if (config.lighting.lut_d0.enable) { |
| 414 | std::string d0_lut_index = GetLutIndex(light_config.num, config.lighting.lut_d0.type, config.lighting.lut_d0.abs_input); | 414 | std::string d0_lut_index = GetLutIndex(light_config.num, config.lighting.lut_d0.type, config.lighting.lut_d0.abs_input); |
| 415 | d0_lut_value = GetLutValue(Regs::LightingSampler::Distribution0, d0_lut_index); | 415 | d0_lut_value = "(" + std::to_string(config.lighting.lut_d0.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution0, d0_lut_index) + ")"; |
| 416 | } | 416 | } |
| 417 | 417 | ||
| 418 | // Compute secondary fragment color (specular lighting) function | 418 | // Compute secondary fragment color (specular lighting) function |