gl_state.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 <type_traits>
  7. #include <glad/glad.h>
  8. #include "video_core/engines/maxwell_3d.h"
  9. namespace OpenGL {
  10. class OpenGLState {
  11. public:
  12. struct {
  13. bool enabled = false; // GL_FRAMEBUFFER_SRGB
  14. } framebuffer_srgb;
  15. struct {
  16. bool alpha_to_coverage = false; // GL_ALPHA_TO_COVERAGE
  17. bool alpha_to_one = false; // GL_ALPHA_TO_ONE
  18. } multisample_control;
  19. struct {
  20. bool enabled = false; // GL_CLAMP_FRAGMENT_COLOR_ARB
  21. } fragment_color_clamp;
  22. struct {
  23. bool far_plane = false;
  24. bool near_plane = false;
  25. } depth_clamp; // GL_DEPTH_CLAMP
  26. struct {
  27. bool enabled = false; // GL_CULL_FACE
  28. GLenum mode = GL_BACK; // GL_CULL_FACE_MODE
  29. GLenum front_face = GL_CCW; // GL_FRONT_FACE
  30. } cull;
  31. struct {
  32. bool test_enabled = false; // GL_DEPTH_TEST
  33. GLboolean write_mask = GL_TRUE; // GL_DEPTH_WRITEMASK
  34. GLenum test_func = GL_LESS; // GL_DEPTH_FUNC
  35. } depth;
  36. struct {
  37. bool enabled = false;
  38. GLuint index = 0;
  39. } primitive_restart; // GL_PRIMITIVE_RESTART
  40. bool rasterizer_discard = false; // GL_RASTERIZER_DISCARD
  41. struct ColorMask {
  42. GLboolean red_enabled = GL_TRUE;
  43. GLboolean green_enabled = GL_TRUE;
  44. GLboolean blue_enabled = GL_TRUE;
  45. GLboolean alpha_enabled = GL_TRUE;
  46. };
  47. std::array<ColorMask, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets>
  48. color_mask; // GL_COLOR_WRITEMASK
  49. struct {
  50. bool test_enabled = false; // GL_STENCIL_TEST
  51. struct {
  52. GLenum test_func = GL_ALWAYS; // GL_STENCIL_FUNC
  53. GLint test_ref = 0; // GL_STENCIL_REF
  54. GLuint test_mask = 0xFFFFFFFF; // GL_STENCIL_VALUE_MASK
  55. GLuint write_mask = 0xFFFFFFFF; // GL_STENCIL_WRITEMASK
  56. GLenum action_stencil_fail = GL_KEEP; // GL_STENCIL_FAIL
  57. GLenum action_depth_fail = GL_KEEP; // GL_STENCIL_PASS_DEPTH_FAIL
  58. GLenum action_depth_pass = GL_KEEP; // GL_STENCIL_PASS_DEPTH_PASS
  59. } front, back;
  60. } stencil;
  61. struct Blend {
  62. bool enabled = false; // GL_BLEND
  63. GLenum rgb_equation = GL_FUNC_ADD; // GL_BLEND_EQUATION_RGB
  64. GLenum a_equation = GL_FUNC_ADD; // GL_BLEND_EQUATION_ALPHA
  65. GLenum src_rgb_func = GL_ONE; // GL_BLEND_SRC_RGB
  66. GLenum dst_rgb_func = GL_ZERO; // GL_BLEND_DST_RGB
  67. GLenum src_a_func = GL_ONE; // GL_BLEND_SRC_ALPHA
  68. GLenum dst_a_func = GL_ZERO; // GL_BLEND_DST_ALPHA
  69. };
  70. std::array<Blend, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> blend;
  71. struct {
  72. bool enabled = false;
  73. } independant_blend;
  74. struct {
  75. GLclampf red = 0.0f;
  76. GLclampf green = 0.0f;
  77. GLclampf blue = 0.0f;
  78. GLclampf alpha = 0.0f;
  79. } blend_color; // GL_BLEND_COLOR
  80. struct {
  81. bool enabled = false; // GL_LOGIC_OP_MODE
  82. GLenum operation = GL_COPY;
  83. } logic_op;
  84. static constexpr std::size_t NumSamplers = 32 * 5;
  85. static constexpr std::size_t NumImages = 8 * 5;
  86. std::array<GLuint, NumSamplers> textures = {};
  87. std::array<GLuint, NumSamplers> samplers = {};
  88. std::array<GLuint, NumImages> images = {};
  89. struct {
  90. GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING
  91. GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING
  92. GLuint vertex_array = 0; // GL_VERTEX_ARRAY_BINDING
  93. GLuint shader_program = 0; // GL_CURRENT_PROGRAM
  94. GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
  95. } draw;
  96. struct Viewport {
  97. GLint x = 0;
  98. GLint y = 0;
  99. GLint width = 0;
  100. GLint height = 0;
  101. GLfloat depth_range_near = 0.0f; // GL_DEPTH_RANGE
  102. GLfloat depth_range_far = 1.0f; // GL_DEPTH_RANGE
  103. struct {
  104. bool enabled = false; // GL_SCISSOR_TEST
  105. GLint x = 0;
  106. GLint y = 0;
  107. GLsizei width = 0;
  108. GLsizei height = 0;
  109. } scissor;
  110. };
  111. std::array<Viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports;
  112. struct {
  113. bool program_control = false; // GL_PROGRAM_POINT_SIZE
  114. GLfloat size = 1.0f; // GL_POINT_SIZE
  115. } point;
  116. struct {
  117. bool point_enable = false;
  118. bool line_enable = false;
  119. bool fill_enable = false;
  120. GLfloat units = 0.0f;
  121. GLfloat factor = 0.0f;
  122. GLfloat clamp = 0.0f;
  123. } polygon_offset;
  124. struct {
  125. bool enabled = false; // GL_ALPHA_TEST
  126. GLenum func = GL_ALWAYS; // GL_ALPHA_TEST_FUNC
  127. GLfloat ref = 0.0f; // GL_ALPHA_TEST_REF
  128. } alpha_test;
  129. std::array<bool, 8> clip_distance = {}; // GL_CLIP_DISTANCE
  130. struct {
  131. GLenum origin = GL_LOWER_LEFT;
  132. GLenum depth_mode = GL_NEGATIVE_ONE_TO_ONE;
  133. } clip_control;
  134. OpenGLState();
  135. /// Get the currently active OpenGL state
  136. static OpenGLState GetCurState() {
  137. return cur_state;
  138. }
  139. void SetDefaultViewports();
  140. /// Apply this state as the current OpenGL state
  141. void Apply();
  142. void ApplyFramebufferState();
  143. void ApplyVertexArrayState();
  144. void ApplyShaderProgram();
  145. void ApplyProgramPipeline();
  146. void ApplyClipDistances();
  147. void ApplyPointSize();
  148. void ApplyFragmentColorClamp();
  149. void ApplyMultisample();
  150. void ApplySRgb();
  151. void ApplyCulling();
  152. void ApplyRasterizerDiscard();
  153. void ApplyColorMask();
  154. void ApplyDepth();
  155. void ApplyPrimitiveRestart();
  156. void ApplyStencilTest();
  157. void ApplyViewport();
  158. void ApplyTargetBlending(std::size_t target, bool force);
  159. void ApplyGlobalBlending();
  160. void ApplyBlending();
  161. void ApplyLogicOp();
  162. void ApplyTextures();
  163. void ApplySamplers();
  164. void ApplyImages();
  165. void ApplyDepthClamp();
  166. void ApplyPolygonOffset();
  167. void ApplyAlphaTest();
  168. void ApplyClipControl();
  169. /// Resets any references to the given resource
  170. OpenGLState& UnbindTexture(GLuint handle);
  171. OpenGLState& ResetSampler(GLuint handle);
  172. OpenGLState& ResetProgram(GLuint handle);
  173. OpenGLState& ResetPipeline(GLuint handle);
  174. OpenGLState& ResetVertexArray(GLuint handle);
  175. OpenGLState& ResetFramebuffer(GLuint handle);
  176. /// Viewport does not affects glClearBuffer so emulate viewport using scissor test
  177. void EmulateViewportWithScissor();
  178. void MarkDirtyBlendState() {
  179. dirty.blend_state = true;
  180. }
  181. void MarkDirtyStencilState() {
  182. dirty.stencil_state = true;
  183. }
  184. void MarkDirtyPolygonOffset() {
  185. dirty.polygon_offset = true;
  186. }
  187. void MarkDirtyColorMask() {
  188. dirty.color_mask = true;
  189. }
  190. void AllDirty() {
  191. dirty.blend_state = true;
  192. dirty.stencil_state = true;
  193. dirty.polygon_offset = true;
  194. dirty.color_mask = true;
  195. }
  196. private:
  197. static OpenGLState cur_state;
  198. struct {
  199. bool blend_state;
  200. bool stencil_state;
  201. bool viewport_state;
  202. bool polygon_offset;
  203. bool color_mask;
  204. } dirty{};
  205. };
  206. static_assert(std::is_trivially_copyable_v<OpenGLState>);
  207. } // namespace OpenGL