[Bf-blender-cvs] [31c77a14af7] master: GPUTexture: Add support for samplers

Clément Foucault noreply at git.blender.org
Sat Sep 5 17:50:08 CEST 2020


Commit: 31c77a14af7cac2bc52ecaffde1bae9775dc47ae
Author: Clément Foucault
Date:   Sat Sep 5 17:31:53 2020 +0200
Branches: master
https://developer.blender.org/rB31c77a14af7cac2bc52ecaffde1bae9775dc47ae

GPUTexture: Add support for samplers

This just add back the support.
This commit also includes a bit of cleanup.

# Conflicts:
#	source/blender/gpu/GPU_texture.h

===================================================================

M	source/blender/editors/interface/interface_icons.c
M	source/blender/gpu/GPU_texture.h
M	source/blender/gpu/intern/gpu_backend.hh
M	source/blender/gpu/intern/gpu_extensions.cc
M	source/blender/gpu/intern/gpu_texture.cc
M	source/blender/gpu/opengl/gl_backend.hh
M	source/blender/gpu/opengl/gl_state.cc
M	source/blender/gpu/opengl/gl_texture.cc
M	source/blender/gpu/opengl/gl_texture.hh
M	source/blender/makesrna/intern/rna_userdef.c

===================================================================

diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index af9ef2e7b3d..70061427c33 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1566,8 +1566,7 @@ static void icon_draw_cache_texture_flush_ex(GPUTexture *texture,
   const int img_binding = GPU_shader_get_texture_binding(shader, "image");
   const int data_loc = GPU_shader_get_uniform(shader, "calls_data");
 
-  GPU_texture_bind(texture, img_binding);
-  GPU_sampler_icon_bind(img_binding);
+  GPU_texture_bind_ex(texture, GPU_SAMPLER_ICON, img_binding, false);
   GPU_shader_uniform_vector(
       shader, data_loc, 4, ICON_DRAW_CACHE_SIZE * 3, (float *)texture_draw_calls->drawcall_cache);
 
@@ -1718,8 +1717,7 @@ static void icon_draw_texture(float x,
   GPU_shader_uniform_vector(shader, rect_tex_loc, 4, 1, (float[4]){x1, y1, x2, y2});
   GPU_shader_uniform_vector(shader, rect_geom_loc, 4, 1, (float[4]){x, y, x + w, y + h});
 
-  GPU_texture_bind(texture, img_binding);
-  GPU_sampler_icon_bind(img_binding);
+  GPU_texture_bind_ex(texture, GPU_SAMPLER_ICON, img_binding, false);
 
   GPUBatch *quad = GPU_batch_preset_quad();
   GPU_batch_set_shader(quad, shader);
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index e56866c5259..667fca776ad 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -66,11 +66,7 @@ ENUM_OPERATORS(eGPUSamplerState)
 extern "C" {
 #endif
 
-#define GPU_SAMPLER_DEFAULT GPU_SAMPLER_FILTER
-#define GPU_SAMPLER_REPEAT (GPU_SAMPLER_REPEAT_S | GPU_SAMPLER_REPEAT_T | GPU_SAMPLER_REPEAT_R)
-
-void GPU_samplers_init(void);
-void GPU_samplers_free(void);
+void GPU_samplers_update(void);
 
 /* GPU Texture
  * - always returns unsigned char RGBA textures
@@ -294,8 +290,6 @@ int GPU_texture_opengl_bindcode(const GPUTexture *tex);
 
 void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size);
 
-void GPU_sampler_icon_bind(int unit);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/gpu/intern/gpu_backend.hh b/source/blender/gpu/intern/gpu_backend.hh
index 06aff94dffe..330c7d59b6d 100644
--- a/source/blender/gpu/intern/gpu_backend.hh
+++ b/source/blender/gpu/intern/gpu_backend.hh
@@ -43,6 +43,8 @@ class GPUBackend {
 
   static GPUBackend *get(void);
 
+  virtual void samplers_update(void) = 0;
+
   virtual GPUContext *context_alloc(void *ghost_window) = 0;
 
   virtual Batch *batch_alloc(void) = 0;
diff --git a/source/blender/gpu/intern/gpu_extensions.cc b/source/blender/gpu/intern/gpu_extensions.cc
index 6fe08d81cda..b473e719211 100644
--- a/source/blender/gpu/intern/gpu_extensions.cc
+++ b/source/blender/gpu/intern/gpu_extensions.cc
@@ -386,13 +386,11 @@ void gpu_extensions_init(void)
   }
 
   GPU_invalid_tex_init();
-  GPU_samplers_init();
 }
 
 void gpu_extensions_exit(void)
 {
   GPU_invalid_tex_free();
-  GPU_samplers_free();
 }
 
 bool GPU_mem_stats_supported(void)
diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc
index 9d431ef4648..d75dc9b728a 100644
--- a/source/blender/gpu/intern/gpu_texture.cc
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -482,6 +482,7 @@ void GPU_texture_bind_ex(GPUTexture *tex_,
                          const bool UNUSED(set_number))
 {
   Texture *tex = reinterpret_cast<Texture *>(tex_);
+  state = (state >= GPU_SAMPLER_MAX) ? tex->sampler_state : state;
   GPU_context_active_get()->state_manager->texture_bind(tex, state, unit);
 }
 
@@ -717,19 +718,10 @@ void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *r_size)
  * Override texture sampler state for one sampler unit only.
  * \{ */
 
-void GPU_samplers_init(void)
+/* Update user defined sampler states. */
+void GPU_samplers_update(void)
 {
-  /* TODO(fclem) port samplers to GLTextures. */
-}
-
-void GPU_sampler_icon_bind(int UNUSED(unit))
-{
-  /* TODO(fclem) port samplers to GLTextures. */
-}
-
-void GPU_samplers_free(void)
-{
-  /* TODO(fclem) port samplers to GLTextures. */
+  GPUBackend::get()->samplers_update();
 }
 
 /** \} */
diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh
index 6029ff9e309..f769d9c1cfe 100644
--- a/source/blender/gpu/opengl/gl_backend.hh
+++ b/source/blender/gpu/opengl/gl_backend.hh
@@ -43,11 +43,25 @@ class GLBackend : public GPUBackend {
   GLSharedOrphanLists shared_orphan_list_;
 
  public:
+  GLBackend()
+  {
+    GLTexture::samplers_init();
+  }
+  ~GLBackend()
+  {
+    GLTexture::samplers_free();
+  }
+
   static GLBackend *get(void)
   {
     return static_cast<GLBackend *>(GPUBackend::get());
   }
 
+  void samplers_update(void) override
+  {
+    GLTexture::samplers_update();
+  };
+
   GPUContext *context_alloc(void *ghost_window)
   {
     return new GLContext(ghost_window, shared_orphan_list_);
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc
index 1fd39cf80eb..6bb7e41252c 100644
--- a/source/blender/gpu/opengl/gl_state.cc
+++ b/source/blender/gpu/opengl/gl_state.cc
@@ -427,13 +427,13 @@ void GLStateManager::set_blend(const eGPUBlend value)
 /** \name Texture state managment
  * \{ */
 
-void GLStateManager::texture_bind(Texture *tex_, eGPUSamplerState sampler, int unit)
+void GLStateManager::texture_bind(Texture *tex_, eGPUSamplerState sampler_type, int unit)
 {
   BLI_assert(unit < GPU_max_textures());
   GLTexture *tex = static_cast<GLTexture *>(tex_);
   targets_[unit] = tex->target_;
   textures_[unit] = tex->tex_id_;
-  samplers_[unit] = sampler;
+  samplers_[unit] = GLTexture::samplers_[sampler_type];
   tex->is_bound_ = true;
   dirty_texture_binds_ |= 1 << unit;
 }
@@ -462,6 +462,7 @@ void GLStateManager::texture_unbind(Texture *tex_)
   for (int i = 0; i < ARRAY_SIZE(textures_); i++) {
     if (textures_[i] == tex_id) {
       textures_[i] = 0;
+      samplers_[i] = 0;
       dirty_texture_binds_ |= 1 << i;
     }
   }
@@ -473,6 +474,7 @@ void GLStateManager::texture_unbind_all(void)
   for (int i = 0; i < ARRAY_SIZE(textures_); i++) {
     if (textures_[i] != 0) {
       textures_[i] = 0;
+      samplers_[i] = 0;
       dirty_texture_binds_ |= 1 << i;
     }
   }
@@ -494,7 +496,7 @@ void GLStateManager::texture_bind_apply(void)
       if (dirty_bind & 1) {
         glActiveTexture(GL_TEXTURE0 + unit);
         glBindTexture(targets_[unit], textures_[unit]);
-        // glBindSampler(unit, samplers_[unit]);
+        glBindSampler(unit, samplers_[unit]);
       }
     }
     dirty_texture_binds_ = 0;
diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc
index 7c72dc6a5c3..b9a7347c8ed 100644
--- a/source/blender/gpu/opengl/gl_texture.cc
+++ b/source/blender/gpu/opengl/gl_texture.cc
@@ -23,6 +23,8 @@
 
 #include "BKE_global.h"
 
+#include "DNA_userdef_types.h"
+
 #include "GPU_extensions.h"
 #include "GPU_framebuffer.h"
 
@@ -424,6 +426,77 @@ struct GPUFrameBuffer *GLTexture::framebuffer_get(void)
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Sampler objects
+ * \{ */
+
+GLuint GLTexture::samplers_[GPU_SAMPLER_MAX] = {0};
+
+void GLTexture::samplers_init(void)
+{
+  glGenSamplers(GPU_SAMPLER_MAX, samplers_);
+  for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) {
+    eGPUSamplerState state = static_cast<eGPUSamplerState>(i);
+    GLenum clamp_type = (state & GPU_SAMPLER_CLAMP_BORDER) ? GL_CLAMP_TO_BORDER : GL_CLAMP_TO_EDGE;
+    GLenum wrap_s = (state & GPU_SAMPLER_REPEAT_S) ? GL_REPEAT : clamp_type;
+    GLenum wrap_t = (state & GPU_SAMPLER_REPEAT_T) ? GL_REPEAT : clamp_type;
+    GLenum wrap_r = (state & GPU_SAMPLER_REPEAT_R) ? GL_REPEAT : clamp_type;
+    GLenum mag_filter = (state & GPU_SAMPLER_FILTER) ? GL_LINEAR : GL_NEAREST;
+    GLenum min_filter = (state & GPU_SAMPLER_FILTER) ?
+                            ((state & GPU_SAMPLER_MIPMAP) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) :
+                            ((state & GPU_SAMPLER_MIPMAP) ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST);
+    GLenum compare_mode = (state & GPU_SAMPLER_COMPARE) ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE;
+
+    glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_S, wrap_s);
+    glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_T, wrap_t);
+    glSamplerParameteri(samplers_[i], GL_TEXTURE_WRAP_R, wrap_r);
+    glSamplerParameteri(samplers_[i], GL_TEXTURE_MIN_FILTER, min_filter);
+    glSamplerParameteri(samplers_[i], GL_TEXTURE_MAG_FILTER, mag_filter);
+    glSamplerParameteri(samplers_[i], GL_TEXTURE_COMPARE_MODE, compare_mode);
+    glSamplerParameteri(samplers_[i], GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
+
+    /** Other states are left to default:
+     * - GL_TEXTURE_BORDER_COLOR is {0, 0, 0, 0}.
+     * - GL_TEXTURE_MIN_LOD is -1000.
+     * - GL_TEXTURE_MAX_LOD is 1000.
+     * - GL_TEXTURE_LOD_BIAS is 0.0f.
+     **/
+  }
+  samplers_update();
+
+  /* Custom sampler for icons. */
+  GLuint icon_sampler = samplers_[GPU_SAMPLER_ICON];
+  glSamplerParameteri(icon_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+  glSamplerParameteri(icon_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glSamplerParameterf(icon_sampler, GL_TEXTURE_LOD_BIAS, -0.5f);
+}
+
+void GLTexture::samplers_update(void)
+{
+  if (!GLEW_EXT_texture_filter_anisotropic) {
+    return;
+  }
+
+  float max_anisotropy = 1.0f;
+  glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
+
+  float aniso_filter = max_ff(max_anisotropy, U.anisotropic_filter);
+
+  for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) {
+    eGPUSamplerState state = static_cast<eGPUSamplerState>(i);
+    if (state & GPU_SAMPLER_MIPMAP) {
+      glSamplerParameterf(samplers_[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso_filter);
+    }
+  }
+}
+
+void GLTexture::samplers_free(void)
+{
+  glDeleteSamplers(GPU_SAMPLER_MAX, samplers_);
+}
+
+/** \} */
+
 /* TODO(fclem) Legacy. Should be removed at some point. */
 uint GLTexture::gl_bindcode_get(void) const
 {
diff --git a/source/blender/gpu/opengl/gl_texture.hh b/source/blender/gpu/opengl/gl_texture.hh
index 0e054d7996a..36da89dad8e 100644
--- a/source/blender/gpu/opengl/gl_texture.hh
+++ b/source/blender/gpu/opengl/gl

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list