1 // Copyright 2019 yuzu 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 <limits> 8 9 #include <glad/glad.h> 10 11 #include "common/common_types.h" 12 #include "core/core.h" 13 #include "video_core/dirty_flags.h" 14 #include "video_core/engines/maxwell_3d.h" 15 16 namespace Tegra { 17 class GPU; 18 } 19 20 namespace OpenGL { 21 22 namespace Dirty { 23 24 enum : u8 { 25 First = VideoCommon::Dirty::LastCommonEntry, 26 27 VertexFormats, 28 VertexFormat0, 29 VertexFormat31 = VertexFormat0 + 31, 30 31 VertexBuffers, 32 VertexBuffer0, 33 VertexBuffer31 = VertexBuffer0 + 31, 34 35 VertexInstances, 36 VertexInstance0, 37 VertexInstance31 = VertexInstance0 + 31, 38 39 ViewportTransform, 40 Viewports, 41 Viewport0, 42 Viewport15 = Viewport0 + 15, 43 44 Scissors, 45 Scissor0, 46 Scissor15 = Scissor0 + 15, 47 48 ColorMaskCommon, 49 ColorMasks, 50 ColorMask0, 51 ColorMask7 = ColorMask0 + 7, 52 53 BlendColor, 54 BlendIndependentEnabled, 55 BlendStates, 56 BlendState0, 57 BlendState7 = BlendState0 + 7, 58 59 Shaders, 60 ClipDistances, 61 62 PolygonModes, 63 PolygonModeFront, 64 PolygonModeBack, 65 66 ColorMask, 67 FrontFace, 68 CullTest, 69 DepthMask, 70 DepthTest, 71 StencilTest, 72 AlphaTest, 73 PrimitiveRestart, 74 PolygonOffset, 75 MultisampleControl, 76 RasterizeEnable, 77 FramebufferSRGB, 78 LogicOp, 79 FragmentClampColor, 80 PointSize, 81 LineWidth, 82 ClipControl, 83 DepthClampEnabled, 84 85 Last 86 }; 87 static_assert(Last <= std::numeric_limits<u8>::max()); 88 89 } // namespace Dirty 90 91 class StateTracker { 92 public: 93 explicit StateTracker(Tegra::GPU& gpu); 94 BindIndexBuffer(GLuint new_index_buffer)95 void BindIndexBuffer(GLuint new_index_buffer) { 96 if (index_buffer == new_index_buffer) { 97 return; 98 } 99 index_buffer = new_index_buffer; 100 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, new_index_buffer); 101 } 102 NotifyScreenDrawVertexArray()103 void NotifyScreenDrawVertexArray() { 104 flags[OpenGL::Dirty::VertexFormats] = true; 105 flags[OpenGL::Dirty::VertexFormat0 + 0] = true; 106 flags[OpenGL::Dirty::VertexFormat0 + 1] = true; 107 108 flags[OpenGL::Dirty::VertexBuffers] = true; 109 flags[OpenGL::Dirty::VertexBuffer0] = true; 110 111 flags[OpenGL::Dirty::VertexInstances] = true; 112 flags[OpenGL::Dirty::VertexInstance0 + 0] = true; 113 flags[OpenGL::Dirty::VertexInstance0 + 1] = true; 114 } 115 NotifyPolygonModes()116 void NotifyPolygonModes() { 117 flags[OpenGL::Dirty::PolygonModes] = true; 118 flags[OpenGL::Dirty::PolygonModeFront] = true; 119 flags[OpenGL::Dirty::PolygonModeBack] = true; 120 } 121 NotifyViewport0()122 void NotifyViewport0() { 123 flags[OpenGL::Dirty::Viewports] = true; 124 flags[OpenGL::Dirty::Viewport0] = true; 125 } 126 NotifyScissor0()127 void NotifyScissor0() { 128 flags[OpenGL::Dirty::Scissors] = true; 129 flags[OpenGL::Dirty::Scissor0] = true; 130 } 131 NotifyColorMask0()132 void NotifyColorMask0() { 133 flags[OpenGL::Dirty::ColorMasks] = true; 134 flags[OpenGL::Dirty::ColorMask0] = true; 135 } 136 NotifyBlend0()137 void NotifyBlend0() { 138 flags[OpenGL::Dirty::BlendStates] = true; 139 flags[OpenGL::Dirty::BlendState0] = true; 140 } 141 NotifyFramebuffer()142 void NotifyFramebuffer() { 143 flags[VideoCommon::Dirty::RenderTargets] = true; 144 } 145 NotifyFrontFace()146 void NotifyFrontFace() { 147 flags[OpenGL::Dirty::FrontFace] = true; 148 } 149 NotifyCullTest()150 void NotifyCullTest() { 151 flags[OpenGL::Dirty::CullTest] = true; 152 } 153 NotifyDepthMask()154 void NotifyDepthMask() { 155 flags[OpenGL::Dirty::DepthMask] = true; 156 } 157 NotifyDepthTest()158 void NotifyDepthTest() { 159 flags[OpenGL::Dirty::DepthTest] = true; 160 } 161 NotifyStencilTest()162 void NotifyStencilTest() { 163 flags[OpenGL::Dirty::StencilTest] = true; 164 } 165 NotifyPolygonOffset()166 void NotifyPolygonOffset() { 167 flags[OpenGL::Dirty::PolygonOffset] = true; 168 } 169 NotifyRasterizeEnable()170 void NotifyRasterizeEnable() { 171 flags[OpenGL::Dirty::RasterizeEnable] = true; 172 } 173 NotifyFramebufferSRGB()174 void NotifyFramebufferSRGB() { 175 flags[OpenGL::Dirty::FramebufferSRGB] = true; 176 } 177 NotifyLogicOp()178 void NotifyLogicOp() { 179 flags[OpenGL::Dirty::LogicOp] = true; 180 } 181 NotifyClipControl()182 void NotifyClipControl() { 183 flags[OpenGL::Dirty::ClipControl] = true; 184 } 185 NotifyAlphaTest()186 void NotifyAlphaTest() { 187 flags[OpenGL::Dirty::AlphaTest] = true; 188 } 189 190 private: 191 Tegra::Engines::Maxwell3D::DirtyState::Flags& flags; 192 193 GLuint index_buffer = 0; 194 }; 195 196 } // namespace OpenGL 197