gl_rasterizer.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. // Copyright 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <cstddef>
  7. #include <cstring>
  8. #include <memory>
  9. #include <unordered_map>
  10. #include <vector>
  11. #include <glad/glad.h>
  12. #include "common/bit_field.h"
  13. #include "common/common_types.h"
  14. #include "common/hash.h"
  15. #include "common/vector_math.h"
  16. #include "core/hw/gpu.h"
  17. #include "video_core/pica_state.h"
  18. #include "video_core/pica_types.h"
  19. #include "video_core/rasterizer_interface.h"
  20. #include "video_core/regs_framebuffer.h"
  21. #include "video_core/regs_lighting.h"
  22. #include "video_core/regs_rasterizer.h"
  23. #include "video_core/regs_texturing.h"
  24. #include "video_core/renderer_opengl/gl_rasterizer_cache.h"
  25. #include "video_core/renderer_opengl/gl_resource_manager.h"
  26. #include "video_core/renderer_opengl/gl_shader_gen.h"
  27. #include "video_core/renderer_opengl/gl_state.h"
  28. #include "video_core/renderer_opengl/pica_to_gl.h"
  29. #include "video_core/shader/shader.h"
  30. struct ScreenInfo;
  31. class RasterizerOpenGL : public VideoCore::RasterizerInterface {
  32. public:
  33. RasterizerOpenGL();
  34. ~RasterizerOpenGL() override;
  35. void AddTriangle(const Pica::Shader::OutputVertex& v0, const Pica::Shader::OutputVertex& v1,
  36. const Pica::Shader::OutputVertex& v2) override;
  37. void DrawTriangles() override;
  38. void NotifyPicaRegisterChanged(u32 id) override;
  39. void FlushAll() override;
  40. void FlushRegion(PAddr addr, u32 size) override;
  41. void FlushAndInvalidateRegion(PAddr addr, u32 size) override;
  42. bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) override;
  43. bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override;
  44. bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override;
  45. bool AccelerateDisplay(const GPU::Regs::FramebufferConfig& config, PAddr framebuffer_addr,
  46. u32 pixel_stride, ScreenInfo& screen_info) override;
  47. /// OpenGL shader generated for a given Pica register state
  48. struct PicaShader {
  49. /// OpenGL shader resource
  50. OGLShader shader;
  51. };
  52. private:
  53. struct SamplerInfo {
  54. using TextureConfig = Pica::TexturingRegs::TextureConfig;
  55. OGLSampler sampler;
  56. /// Creates the sampler object, initializing its state so that it's in sync with the
  57. /// SamplerInfo struct.
  58. void Create();
  59. /// Syncs the sampler object with the config, updating any necessary state.
  60. void SyncWithConfig(const TextureConfig& config);
  61. private:
  62. TextureConfig::TextureFilter mag_filter;
  63. TextureConfig::TextureFilter min_filter;
  64. TextureConfig::WrapMode wrap_s;
  65. TextureConfig::WrapMode wrap_t;
  66. u32 border_color;
  67. };
  68. /// Structure that the hardware rendered vertices are composed of
  69. struct HardwareVertex {
  70. HardwareVertex(const Pica::Shader::OutputVertex& v, bool flip_quaternion) {
  71. position[0] = v.pos.x.ToFloat32();
  72. position[1] = v.pos.y.ToFloat32();
  73. position[2] = v.pos.z.ToFloat32();
  74. position[3] = v.pos.w.ToFloat32();
  75. color[0] = v.color.x.ToFloat32();
  76. color[1] = v.color.y.ToFloat32();
  77. color[2] = v.color.z.ToFloat32();
  78. color[3] = v.color.w.ToFloat32();
  79. tex_coord0[0] = v.tc0.x.ToFloat32();
  80. tex_coord0[1] = v.tc0.y.ToFloat32();
  81. tex_coord1[0] = v.tc1.x.ToFloat32();
  82. tex_coord1[1] = v.tc1.y.ToFloat32();
  83. tex_coord2[0] = v.tc2.x.ToFloat32();
  84. tex_coord2[1] = v.tc2.y.ToFloat32();
  85. tex_coord0_w = v.tc0_w.ToFloat32();
  86. normquat[0] = v.quat.x.ToFloat32();
  87. normquat[1] = v.quat.y.ToFloat32();
  88. normquat[2] = v.quat.z.ToFloat32();
  89. normquat[3] = v.quat.w.ToFloat32();
  90. view[0] = v.view.x.ToFloat32();
  91. view[1] = v.view.y.ToFloat32();
  92. view[2] = v.view.z.ToFloat32();
  93. if (flip_quaternion) {
  94. for (float& x : normquat) {
  95. x = -x;
  96. }
  97. }
  98. }
  99. GLfloat position[4];
  100. GLfloat color[4];
  101. GLfloat tex_coord0[2];
  102. GLfloat tex_coord1[2];
  103. GLfloat tex_coord2[2];
  104. GLfloat tex_coord0_w;
  105. GLfloat normquat[4];
  106. GLfloat view[3];
  107. };
  108. struct LightSrc {
  109. alignas(16) GLvec3 specular_0;
  110. alignas(16) GLvec3 specular_1;
  111. alignas(16) GLvec3 diffuse;
  112. alignas(16) GLvec3 ambient;
  113. alignas(16) GLvec3 position;
  114. alignas(16) GLvec3 spot_direction; // negated
  115. GLfloat dist_atten_bias;
  116. GLfloat dist_atten_scale;
  117. };
  118. /// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned
  119. // NOTE: Always keep a vec4 at the end. The GL spec is not clear wether the alignment at
  120. // the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not.
  121. // Not following that rule will cause problems on some AMD drivers.
  122. struct UniformData {
  123. alignas(8) GLvec2 framebuffer_scale;
  124. GLint alphatest_ref;
  125. GLfloat depth_scale;
  126. GLfloat depth_offset;
  127. GLint scissor_x1;
  128. GLint scissor_y1;
  129. GLint scissor_x2;
  130. GLint scissor_y2;
  131. alignas(16) GLvec3 fog_color;
  132. alignas(8) GLvec2 proctex_noise_f;
  133. alignas(8) GLvec2 proctex_noise_a;
  134. alignas(8) GLvec2 proctex_noise_p;
  135. alignas(16) GLvec3 lighting_global_ambient;
  136. LightSrc light_src[8];
  137. alignas(16) GLvec4 const_color[6]; // A vec4 color for each of the six tev stages
  138. alignas(16) GLvec4 tev_combiner_buffer_color;
  139. };
  140. static_assert(
  141. sizeof(UniformData) == 0x460,
  142. "The size of the UniformData structure has changed, update the structure in the shader");
  143. static_assert(sizeof(UniformData) < 16384,
  144. "UniformData structure must be less than 16kb as per the OpenGL spec");
  145. /// Sets the OpenGL shader in accordance with the current PICA register state
  146. void SetShader();
  147. /// Syncs the cull mode to match the PICA register
  148. void SyncCullMode();
  149. /// Syncs the depth scale to match the PICA register
  150. void SyncDepthScale();
  151. /// Syncs the depth offset to match the PICA register
  152. void SyncDepthOffset();
  153. /// Syncs the blend enabled status to match the PICA register
  154. void SyncBlendEnabled();
  155. /// Syncs the blend functions to match the PICA register
  156. void SyncBlendFuncs();
  157. /// Syncs the blend color to match the PICA register
  158. void SyncBlendColor();
  159. /// Syncs the fog states to match the PICA register
  160. void SyncFogColor();
  161. void SyncFogLUT();
  162. /// Sync the procedural texture noise configuration to match the PICA register
  163. void SyncProcTexNoise();
  164. /// Sync the procedural texture lookup tables
  165. void SyncProcTexNoiseLUT();
  166. void SyncProcTexColorMap();
  167. void SyncProcTexAlphaMap();
  168. void SyncProcTexLUT();
  169. void SyncProcTexDiffLUT();
  170. /// Syncs the alpha test states to match the PICA register
  171. void SyncAlphaTest();
  172. /// Syncs the logic op states to match the PICA register
  173. void SyncLogicOp();
  174. /// Syncs the color write mask to match the PICA register state
  175. void SyncColorWriteMask();
  176. /// Syncs the stencil write mask to match the PICA register state
  177. void SyncStencilWriteMask();
  178. /// Syncs the depth write mask to match the PICA register state
  179. void SyncDepthWriteMask();
  180. /// Syncs the stencil test states to match the PICA register
  181. void SyncStencilTest();
  182. /// Syncs the depth test states to match the PICA register
  183. void SyncDepthTest();
  184. /// Syncs the TEV combiner color buffer to match the PICA register
  185. void SyncCombinerColor();
  186. /// Syncs the TEV constant color to match the PICA register
  187. void SyncTevConstColor(int tev_index, const Pica::TexturingRegs::TevStageConfig& tev_stage);
  188. /// Syncs the lighting global ambient color to match the PICA register
  189. void SyncGlobalAmbient();
  190. /// Syncs the lighting lookup tables
  191. void SyncLightingLUT(unsigned index);
  192. /// Syncs the specified light's specular 0 color to match the PICA register
  193. void SyncLightSpecular0(int light_index);
  194. /// Syncs the specified light's specular 1 color to match the PICA register
  195. void SyncLightSpecular1(int light_index);
  196. /// Syncs the specified light's diffuse color to match the PICA register
  197. void SyncLightDiffuse(int light_index);
  198. /// Syncs the specified light's ambient color to match the PICA register
  199. void SyncLightAmbient(int light_index);
  200. /// Syncs the specified light's position to match the PICA register
  201. void SyncLightPosition(int light_index);
  202. /// Syncs the specified spot light direcition to match the PICA register
  203. void SyncLightSpotDirection(int light_index);
  204. /// Syncs the specified light's distance attenuation bias to match the PICA register
  205. void SyncLightDistanceAttenuationBias(int light_index);
  206. /// Syncs the specified light's distance attenuation scale to match the PICA register
  207. void SyncLightDistanceAttenuationScale(int light_index);
  208. OpenGLState state;
  209. RasterizerCacheOpenGL res_cache;
  210. std::vector<HardwareVertex> vertex_batch;
  211. std::unordered_map<GLShader::PicaShaderConfig, std::unique_ptr<PicaShader>> shader_cache;
  212. const PicaShader* current_shader = nullptr;
  213. bool shader_dirty;
  214. struct {
  215. UniformData data;
  216. std::array<bool, Pica::LightingRegs::NumLightingSampler> lut_dirty;
  217. bool fog_lut_dirty;
  218. bool proctex_noise_lut_dirty;
  219. bool proctex_color_map_dirty;
  220. bool proctex_alpha_map_dirty;
  221. bool proctex_lut_dirty;
  222. bool proctex_diff_lut_dirty;
  223. bool dirty;
  224. } uniform_block_data = {};
  225. std::array<SamplerInfo, 3> texture_samplers;
  226. OGLVertexArray vertex_array;
  227. OGLBuffer vertex_buffer;
  228. OGLBuffer uniform_buffer;
  229. OGLFramebuffer framebuffer;
  230. OGLBuffer lighting_lut_buffer;
  231. OGLTexture lighting_lut;
  232. std::array<std::array<GLvec2, 256>, Pica::LightingRegs::NumLightingSampler> lighting_lut_data{};
  233. OGLBuffer fog_lut_buffer;
  234. OGLTexture fog_lut;
  235. std::array<GLvec2, 128> fog_lut_data{};
  236. OGLBuffer proctex_noise_lut_buffer;
  237. OGLTexture proctex_noise_lut;
  238. std::array<GLvec2, 128> proctex_noise_lut_data{};
  239. OGLBuffer proctex_color_map_buffer;
  240. OGLTexture proctex_color_map;
  241. std::array<GLvec2, 128> proctex_color_map_data{};
  242. OGLBuffer proctex_alpha_map_buffer;
  243. OGLTexture proctex_alpha_map;
  244. std::array<GLvec2, 128> proctex_alpha_map_data{};
  245. OGLBuffer proctex_lut_buffer;
  246. OGLTexture proctex_lut;
  247. std::array<GLvec4, 256> proctex_lut_data{};
  248. OGLBuffer proctex_diff_lut_buffer;
  249. OGLTexture proctex_diff_lut;
  250. std::array<GLvec4, 256> proctex_diff_lut_data{};
  251. };