gl_rasterizer.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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. GLfloat dist_atten_bias;
  115. GLfloat dist_atten_scale;
  116. };
  117. /// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned
  118. // NOTE: Always keep a vec4 at the end. The GL spec is not clear wether the alignment at
  119. // the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not.
  120. // Not following that rule will cause problems on some AMD drivers.
  121. struct UniformData {
  122. alignas(8) GLvec2 framebuffer_scale;
  123. GLint alphatest_ref;
  124. GLfloat depth_scale;
  125. GLfloat depth_offset;
  126. GLint scissor_x1;
  127. GLint scissor_y1;
  128. GLint scissor_x2;
  129. GLint scissor_y2;
  130. alignas(16) GLvec3 fog_color;
  131. alignas(16) GLvec3 lighting_global_ambient;
  132. LightSrc light_src[8];
  133. alignas(16) GLvec4 const_color[6]; // A vec4 color for each of the six tev stages
  134. alignas(16) GLvec4 tev_combiner_buffer_color;
  135. };
  136. static_assert(
  137. sizeof(UniformData) == 0x3C0,
  138. "The size of the UniformData structure has changed, update the structure in the shader");
  139. static_assert(sizeof(UniformData) < 16384,
  140. "UniformData structure must be less than 16kb as per the OpenGL spec");
  141. /// Sets the OpenGL shader in accordance with the current PICA register state
  142. void SetShader();
  143. /// Syncs the cull mode to match the PICA register
  144. void SyncCullMode();
  145. /// Syncs the depth scale to match the PICA register
  146. void SyncDepthScale();
  147. /// Syncs the depth offset to match the PICA register
  148. void SyncDepthOffset();
  149. /// Syncs the blend enabled status to match the PICA register
  150. void SyncBlendEnabled();
  151. /// Syncs the blend functions to match the PICA register
  152. void SyncBlendFuncs();
  153. /// Syncs the blend color to match the PICA register
  154. void SyncBlendColor();
  155. /// Syncs the fog states to match the PICA register
  156. void SyncFogColor();
  157. void SyncFogLUT();
  158. /// Syncs the alpha test states to match the PICA register
  159. void SyncAlphaTest();
  160. /// Syncs the logic op states to match the PICA register
  161. void SyncLogicOp();
  162. /// Syncs the color write mask to match the PICA register state
  163. void SyncColorWriteMask();
  164. /// Syncs the stencil write mask to match the PICA register state
  165. void SyncStencilWriteMask();
  166. /// Syncs the depth write mask to match the PICA register state
  167. void SyncDepthWriteMask();
  168. /// Syncs the stencil test states to match the PICA register
  169. void SyncStencilTest();
  170. /// Syncs the depth test states to match the PICA register
  171. void SyncDepthTest();
  172. /// Syncs the TEV combiner color buffer to match the PICA register
  173. void SyncCombinerColor();
  174. /// Syncs the TEV constant color to match the PICA register
  175. void SyncTevConstColor(int tev_index, const Pica::TexturingRegs::TevStageConfig& tev_stage);
  176. /// Syncs the lighting global ambient color to match the PICA register
  177. void SyncGlobalAmbient();
  178. /// Syncs the lighting lookup tables
  179. void SyncLightingLUT(unsigned index);
  180. /// Syncs the specified light's specular 0 color to match the PICA register
  181. void SyncLightSpecular0(int light_index);
  182. /// Syncs the specified light's specular 1 color to match the PICA register
  183. void SyncLightSpecular1(int light_index);
  184. /// Syncs the specified light's diffuse color to match the PICA register
  185. void SyncLightDiffuse(int light_index);
  186. /// Syncs the specified light's ambient color to match the PICA register
  187. void SyncLightAmbient(int light_index);
  188. /// Syncs the specified light's position to match the PICA register
  189. void SyncLightPosition(int light_index);
  190. /// Syncs the specified light's distance attenuation bias to match the PICA register
  191. void SyncLightDistanceAttenuationBias(int light_index);
  192. /// Syncs the specified light's distance attenuation scale to match the PICA register
  193. void SyncLightDistanceAttenuationScale(int light_index);
  194. OpenGLState state;
  195. RasterizerCacheOpenGL res_cache;
  196. std::vector<HardwareVertex> vertex_batch;
  197. std::unordered_map<GLShader::PicaShaderConfig, std::unique_ptr<PicaShader>> shader_cache;
  198. const PicaShader* current_shader = nullptr;
  199. bool shader_dirty;
  200. struct {
  201. UniformData data;
  202. bool lut_dirty[6];
  203. bool fog_lut_dirty;
  204. bool dirty;
  205. } uniform_block_data = {};
  206. std::array<SamplerInfo, 3> texture_samplers;
  207. OGLVertexArray vertex_array;
  208. OGLBuffer vertex_buffer;
  209. OGLBuffer uniform_buffer;
  210. OGLFramebuffer framebuffer;
  211. std::array<OGLTexture, 6> lighting_luts;
  212. std::array<std::array<GLvec4, 256>, 6> lighting_lut_data{};
  213. OGLTexture fog_lut;
  214. std::array<GLuint, 128> fog_lut_data{};
  215. };