gl_state.h 7.0 KB

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