[Bf-blender-cvs] [64490bdedb7] master: GLTexture: Add direct state access support

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


Commit: 64490bdedb7291523df3c1cf633aee7a455e2e36
Author: Clément Foucault
Date:   Sat Sep 5 17:36:00 2020 +0200
Branches: master
https://developer.blender.org/rB64490bdedb7291523df3c1cf633aee7a455e2e36

GLTexture: Add direct state access support

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

M	source/blender/gpu/opengl/gl_texture.cc
M	source/blender/gpu/opengl/gl_texture.hh

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

diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc
index f72dd3322b2..9c78fbd514f 100644
--- a/source/blender/gpu/opengl/gl_texture.cc
+++ b/source/blender/gpu/opengl/gl_texture.cc
@@ -77,6 +77,9 @@ bool GLTexture::init_internal(void)
 
   target_ = to_gl_target(type_);
 
+  /* We need to bind once to define the texture type.  */
+  GLContext::state_manager_active_get()->texture_bind_temp(this);
+
   if (!this->proxy_check(0)) {
     return false;
   }
@@ -84,11 +87,10 @@ bool GLTexture::init_internal(void)
   this->ensure_mipmaps(0);
 
   /* Avoid issue with incomplete textures. */
-  if (false) {
-    /* TODO(fclem) Direct State Access. */
+  if (GLEW_ARB_direct_state_access) {
+    glTextureParameteri(tex_id_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   }
   else {
-    GLContext::state_manager_active_get()->texture_bind_temp(this);
     glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   }
 
@@ -110,13 +112,15 @@ bool GLTexture::init_internal(GPUVertBuf *vbo)
 {
   target_ = to_gl_target(type_);
 
+  /* We need to bind once to define the texture type.  */
+  GLContext::state_manager_active_get()->texture_bind_temp(this);
+
   GLenum internal_format = to_gl_internal_format(format_);
 
-  if (false) {
-    /* TODO(fclem) Direct State Access. */
+  if (GLEW_ARB_direct_state_access) {
+    glTextureBuffer(tex_id_, internal_format, vbo->vbo_id);
   }
   else {
-    GLContext::state_manager_active_get()->texture_bind_temp(this);
     glTexBuffer(target_, internal_format, vbo->vbo_id);
   }
 
@@ -203,6 +207,43 @@ void GLTexture::ensure_mipmaps(int miplvl)
 /** \name Operations
  * \{ */
 
+void GLTexture::update_sub_direct_state_access(
+    int mip, int offset[3], int extent[3], GLenum format, GLenum type, const void *data)
+{
+  if (format_flag_ & GPU_FORMAT_COMPRESSED) {
+    size_t size = ((extent[0] + 3) / 4) * ((extent[1] + 3) / 4) * to_block_size(format_);
+    switch (this->dimensions_count()) {
+      default:
+      case 1:
+        glCompressedTextureSubImage1D(tex_id_, mip, offset[0], extent[0], format, size, data);
+        break;
+      case 2:
+        glCompressedTextureSubImage2D(
+            tex_id_, mip, UNPACK2(offset), UNPACK2(extent), format, size, data);
+        break;
+      case 3:
+        glCompressedTextureSubImage3D(
+            tex_id_, mip, UNPACK3(offset), UNPACK3(extent), format, size, data);
+        break;
+    }
+  }
+  else {
+    switch (this->dimensions_count()) {
+      default:
+      case 1:
+        glTextureSubImage1D(tex_id_, mip, offset[0], extent[0], format, type, data);
+        break;
+      case 2:
+        glTextureSubImage2D(tex_id_, mip, UNPACK2(offset), UNPACK2(extent), format, type, data);
+        break;
+      case 3:
+        glTextureSubImage3D(tex_id_, mip, UNPACK3(offset), UNPACK3(extent), format, type, data);
+        break;
+    }
+  }
+  GL_CHECK_ERROR("Post-update_sub_direct_state_access");
+}
+
 void GLTexture::update_sub(
     int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data)
 {
@@ -220,11 +261,13 @@ void GLTexture::update_sub(
   GLenum gl_format = to_gl_data_format(format_);
   GLenum gl_type = to_gl(type);
 
-  GLContext::state_manager_active_get()->texture_bind_temp(this);
+  if (GLEW_ARB_direct_state_access) {
+    this->update_sub_direct_state_access(mip, offset, extent, gl_format, gl_type, data);
+    return;
+  }
 
-  if (true && type_ == GPU_TEXTURE_CUBE) {
-    /* TODO(fclem) bypass if direct state access is available. */
-    /* Workaround when ARB_direct_state_access is not available. */
+  GLContext::state_manager_active_get()->texture_bind_temp(this);
+  if (type_ == GPU_TEXTURE_CUBE) {
     for (int i = 0; i < extent[2]; i++) {
       GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + offset[2] + i;
       glTexSubImage2D(target, mip, UNPACK2(offset), UNPACK2(extent), gl_format, gl_type, data);
@@ -280,11 +323,11 @@ void GLTexture::generate_mipmap(void)
     return;
   }
 
-  if (false) {
-    /* TODO(fclem) Direct State Access. */
+  /* Downsample from mip 0 using implementation. */
+  if (GLEW_ARB_direct_state_access) {
+    glGenerateTextureMipmap(tex_id_);
   }
   else {
-    /* Downsample from mip 0 using implementation. */
     GLContext::state_manager_active_get()->texture_bind_temp(this);
     glGenerateMipmap(target_);
   }
@@ -360,9 +403,8 @@ void *GLTexture::read(int mip, eGPUDataFormat type)
   GLenum gl_format = to_gl_data_format(format_);
   GLenum gl_type = to_gl(type);
 
-  if (false) {
-    /* TODO(fclem) Direct State Access. */
-    /* NOTE: DSA can read GL_TEXTURE_CUBE_MAP directly. */
+  if (GLEW_ARB_direct_state_access) {
+    glGetTextureImage(tex_id_, mip, gl_format, gl_type, texture_size, data);
   }
   else {
     GLContext::state_manager_active_get()->texture_bind_temp(this);
@@ -392,8 +434,8 @@ void GLTexture::swizzle_set(const char swizzle[4])
                          (GLint)swizzle_to_gl(swizzle[1]),
                          (GLint)swizzle_to_gl(swizzle[2]),
                          (GLint)swizzle_to_gl(swizzle[3])};
-  if (false) {
-    /* TODO(fclem) Direct State Access. */
+  if (GLEW_ARB_direct_state_access) {
+    glTextureParameteriv(tex_id_, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle);
   }
   else {
     GLContext::state_manager_active_get()->texture_bind_temp(this);
@@ -404,8 +446,9 @@ void GLTexture::swizzle_set(const char swizzle[4])
 void GLTexture::mip_range_set(int min, int max)
 {
   BLI_assert(min <= max && min >= 0 && max <= mipmaps_);
-  if (false) {
-    /* TODO(fclem) Direct State Access. */
+  if (GLEW_ARB_direct_state_access) {
+    glTextureParameteri(tex_id_, GL_TEXTURE_BASE_LEVEL, min);
+    glTextureParameteri(tex_id_, GL_TEXTURE_MAX_LEVEL, max);
   }
   else {
     GLContext::state_manager_active_get()->texture_bind_temp(this);
diff --git a/source/blender/gpu/opengl/gl_texture.hh b/source/blender/gpu/opengl/gl_texture.hh
index c18949c264e..ef86d1b9e7e 100644
--- a/source/blender/gpu/opengl/gl_texture.hh
+++ b/source/blender/gpu/opengl/gl_texture.hh
@@ -89,6 +89,8 @@ class GLTexture : public Texture {
  private:
   bool proxy_check(int mip);
   void ensure_mipmaps(int mip);
+  void update_sub_direct_state_access(
+      int mip, int offset[3], int extent[3], GLenum gl_format, GLenum gl_type, const void *data);
   GPUFrameBuffer *framebuffer_get(void);
 
   MEM_CXX_CLASS_ALLOC_FUNCS("GLTexture")



More information about the Bf-blender-cvs mailing list