Просмотр исходного кода

OpenGL: Add support for Sampler Objects to state tracker

Yuri Kunde Schlesner 11 лет назад
Родитель
Сommit
ec28f037e6

+ 24 - 0
src/video_core/renderer_opengl/gl_resource_manager.h

@@ -37,6 +37,30 @@ public:
     GLuint handle = 0;
     GLuint handle = 0;
 };
 };
 
 
+class OGLSampler : private NonCopyable {
+public:
+    OGLSampler() = default;
+    OGLSampler(OGLSampler&& o) { std::swap(handle, o.handle); }
+    ~OGLSampler() { Release(); }
+    OGLSampler& operator=(OGLSampler&& o) { std::swap(handle, o.handle); return *this; }
+
+    /// Creates a new internal OpenGL resource and stores the handle
+    void Create() {
+        if (handle != 0) return;
+        glGenSamplers(1, &handle);
+    }
+
+    /// Deletes the internal OpenGL resource
+    void Release() {
+        if (handle == 0) return;
+        glDeleteSamplers(1, &handle);
+        OpenGLState::ResetSampler(handle);
+        handle = 0;
+    }
+
+    GLuint handle = 0;
+};
+
 class OGLShader : private NonCopyable {
 class OGLShader : private NonCopyable {
 public:
 public:
     OGLShader() = default;
     OGLShader() = default;

+ 16 - 4
src/video_core/renderer_opengl/gl_state.cpp

@@ -44,6 +44,7 @@ OpenGLState::OpenGLState() {
 
 
     for (auto& texture_unit : texture_units) {
     for (auto& texture_unit : texture_units) {
         texture_unit.texture_2d = 0;
         texture_unit.texture_2d = 0;
+        texture_unit.sampler = 0;
     }
     }
 
 
     draw.framebuffer = 0;
     draw.framebuffer = 0;
@@ -154,10 +155,13 @@ void OpenGLState::Apply() {
     }
     }
 
 
     // Textures
     // Textures
-    for (unsigned texture_index = 0; texture_index < ARRAY_SIZE(texture_units); ++texture_index) {
-        if (texture_units[texture_index].texture_2d != cur_state.texture_units[texture_index].texture_2d) {
-            glActiveTexture(GL_TEXTURE0 + texture_index);
-            glBindTexture(GL_TEXTURE_2D, texture_units[texture_index].texture_2d);
+    for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) {
+        if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) {
+            glActiveTexture(GL_TEXTURE0 + i);
+            glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d);
+        }
+        if (texture_units[i].sampler != cur_state.texture_units[i].sampler) {
+            glBindSampler(i, texture_units[i].sampler);
         }
         }
     }
     }
 
 
@@ -192,6 +196,14 @@ void OpenGLState::ResetTexture(GLuint id) {
     }
     }
 }
 }
 
 
+void OpenGLState::ResetSampler(GLuint id) {
+    for (auto& unit : cur_state.texture_units) {
+        if (unit.sampler == id) {
+            unit.sampler = 0;
+        }
+    }
+}
+
 void OpenGLState::ResetProgram(GLuint id) {
 void OpenGLState::ResetProgram(GLuint id) {
     if (cur_state.draw.shader_program == id) {
     if (cur_state.draw.shader_program == id) {
         cur_state.draw.shader_program = 0;
         cur_state.draw.shader_program = 0;

+ 2 - 0
src/video_core/renderer_opengl/gl_state.h

@@ -57,6 +57,7 @@ public:
     // 3 texture units - one for each that is used in PICA fragment shader emulation
     // 3 texture units - one for each that is used in PICA fragment shader emulation
     struct {
     struct {
         GLuint texture_2d; // GL_TEXTURE_BINDING_2D
         GLuint texture_2d; // GL_TEXTURE_BINDING_2D
+        GLuint sampler; // GL_SAMPLER_BINDING
     } texture_units[3];
     } texture_units[3];
 
 
     struct {
     struct {
@@ -77,6 +78,7 @@ public:
     void Apply();
     void Apply();
 
 
     static void ResetTexture(GLuint id);
     static void ResetTexture(GLuint id);
+    static void ResetSampler(GLuint id);
     static void ResetProgram(GLuint id);
     static void ResetProgram(GLuint id);
     static void ResetBuffer(GLuint id);
     static void ResetBuffer(GLuint id);
     static void ResetVertexArray(GLuint id);
     static void ResetVertexArray(GLuint id);