/ src / video_core / rasterizer_accelerated.h
rasterizer_accelerated.h
  1  // Copyright 2023 Citra Emulator Project
  2  // Licensed under GPLv2 or any later version
  3  // Refer to the license.txt file included.
  4  
  5  #pragma once
  6  
  7  #include "common/vector_math.h"
  8  #include "video_core/rasterizer_interface.h"
  9  #include "video_core/shader/generator/pica_fs_config.h"
 10  #include "video_core/shader/generator/shader_uniforms.h"
 11  
 12  namespace Memory {
 13  class MemorySystem;
 14  }
 15  
 16  namespace Pica {
 17  class PicaCore;
 18  }
 19  
 20  namespace VideoCore {
 21  
 22  class RasterizerAccelerated : public RasterizerInterface {
 23  public:
 24      explicit RasterizerAccelerated(Memory::MemorySystem& memory, Pica::PicaCore& pica);
 25      virtual ~RasterizerAccelerated() = default;
 26  
 27      void AddTriangle(const Pica::OutputVertex& v0, const Pica::OutputVertex& v1,
 28                       const Pica::OutputVertex& v2) override;
 29  
 30      void NotifyPicaRegisterChanged(u32 id) override;
 31  
 32      void SyncEntireState() override;
 33  
 34  protected:
 35      /// Sync fixed-function pipeline state
 36      virtual void SyncFixedState() = 0;
 37  
 38      /// Notifies that a fixed function PICA register changed to the video backend
 39      virtual void NotifyFixedFunctionPicaRegisterChanged(u32 id) = 0;
 40  
 41      /// Syncs the depth scale to match the PICA register
 42      void SyncDepthScale();
 43  
 44      /// Syncs the depth offset to match the PICA register
 45      void SyncDepthOffset();
 46  
 47      /// Syncs the fog states to match the PICA register
 48      void SyncFogColor();
 49  
 50      /// Sync the procedural texture noise configuration to match the PICA register
 51      void SyncProcTexNoise();
 52  
 53      /// Sync the procedural texture bias configuration to match the PICA register
 54      void SyncProcTexBias();
 55  
 56      /// Syncs the alpha test states to match the PICA register
 57      void SyncAlphaTest();
 58  
 59      /// Syncs the TEV combiner color buffer to match the PICA register
 60      void SyncCombinerColor();
 61  
 62      /// Syncs the TEV constant color to match the PICA register
 63      void SyncTevConstColor(std::size_t tev_index,
 64                             const Pica::TexturingRegs::TevStageConfig& tev_stage);
 65  
 66      /// Syncs the lighting global ambient color to match the PICA register
 67      void SyncGlobalAmbient();
 68  
 69      /// Syncs the specified light's specular 0 color to match the PICA register
 70      void SyncLightSpecular0(int light_index);
 71  
 72      /// Syncs the specified light's specular 1 color to match the PICA register
 73      void SyncLightSpecular1(int light_index);
 74  
 75      /// Syncs the specified light's diffuse color to match the PICA register
 76      void SyncLightDiffuse(int light_index);
 77  
 78      /// Syncs the specified light's ambient color to match the PICA register
 79      void SyncLightAmbient(int light_index);
 80  
 81      /// Syncs the specified light's position to match the PICA register
 82      void SyncLightPosition(int light_index);
 83  
 84      /// Syncs the specified spot light direcition to match the PICA register
 85      void SyncLightSpotDirection(int light_index);
 86  
 87      /// Syncs the specified light's distance attenuation bias to match the PICA register
 88      void SyncLightDistanceAttenuationBias(int light_index);
 89  
 90      /// Syncs the specified light's distance attenuation scale to match the PICA register
 91      void SyncLightDistanceAttenuationScale(int light_index);
 92  
 93      /// Syncs the shadow rendering bias to match the PICA register
 94      void SyncShadowBias();
 95  
 96      /// Syncs the shadow texture bias to match the PICA register
 97      void SyncShadowTextureBias();
 98  
 99      /// Syncs the texture LOD bias to match the PICA register
100      void SyncTextureLodBias(int tex_index);
101  
102      /// Syncs the texture border color to match the PICA registers
103      void SyncTextureBorderColor(int tex_index);
104  
105      /// Syncs the clip plane state to match the PICA register
106      void SyncClipPlane();
107  
108  protected:
109      /// Structure that keeps tracks of the vertex shader uniform state
110      struct VSUniformBlockData {
111          Pica::Shader::Generator::VSUniformData data{};
112          bool dirty = true;
113      };
114  
115      /// Structure that keeps tracks of the fragment shader uniform state
116      struct FSUniformBlockData {
117          Pica::Shader::Generator::FSUniformData data{};
118          std::array<bool, Pica::LightingRegs::NumLightingSampler> lighting_lut_dirty{};
119          bool lighting_lut_dirty_any = true;
120          bool fog_lut_dirty = true;
121          bool proctex_noise_lut_dirty = true;
122          bool proctex_color_map_dirty = true;
123          bool proctex_alpha_map_dirty = true;
124          bool proctex_lut_dirty = true;
125          bool proctex_diff_lut_dirty = true;
126          bool dirty = true;
127      };
128  
129      /// Structure that the hardware rendered vertices are composed of
130      struct HardwareVertex {
131          HardwareVertex() = default;
132          HardwareVertex(const Pica::OutputVertex& v, bool flip_quaternion);
133  
134          Common::Vec4f position;
135          Common::Vec4f color;
136          Common::Vec2f tex_coord0;
137          Common::Vec2f tex_coord1;
138          Common::Vec2f tex_coord2;
139          float tex_coord0_w;
140          Common::Vec4f normquat;
141          Common::Vec3f view;
142      };
143  
144      struct VertexArrayInfo {
145          u32 vs_input_index_min;
146          u32 vs_input_index_max;
147          u32 vs_input_size;
148      };
149  
150      /// Retrieve the range and the size of the input vertex
151      VertexArrayInfo AnalyzeVertexArray(bool is_indexed, u32 stride_alignment = 1);
152  
153  protected:
154      Memory::MemorySystem& memory;
155      Pica::PicaCore& pica;
156      Pica::RegsInternal& regs;
157  
158      std::vector<HardwareVertex> vertex_batch;
159      Pica::Shader::UserConfig user_config{};
160      bool shader_dirty = true;
161  
162      VSUniformBlockData vs_uniform_block_data{};
163      FSUniformBlockData fs_uniform_block_data{};
164      using LightLUT = std::array<Common::Vec2f, 256>;
165      std::array<LightLUT, Pica::LightingRegs::NumLightingSampler> lighting_lut_data{};
166      std::array<Common::Vec2f, 128> fog_lut_data{};
167      std::array<Common::Vec2f, 128> proctex_noise_lut_data{};
168      std::array<Common::Vec2f, 128> proctex_color_map_data{};
169      std::array<Common::Vec2f, 128> proctex_alpha_map_data{};
170      std::array<Common::Vec4f, 256> proctex_lut_data{};
171      std::array<Common::Vec4f, 256> proctex_diff_lut_data{};
172  };
173  
174  } // namespace VideoCore