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