[Bf-blender-cvs] [a1f9eebc0b5] master: DRW: Remove automatic bind locations and use hardcoded locations for textures

Clément Foucault noreply at git.blender.org
Tue Jun 2 23:47:16 CEST 2020


Commit: a1f9eebc0b5f0e9a5683ecfcb0e79bac74d1ca14
Author: Clément Foucault
Date:   Tue Jun 2 18:14:28 2020 +0200
Branches: master
https://developer.blender.org/rBa1f9eebc0b5f0e9a5683ecfcb0e79bac74d1ca14

DRW: Remove automatic bind locations and use hardcoded locations for textures

This cleanup use the recent changes in shader interface to allow querying
the binding location a texture should use.

This should aleviate all issue we have with texture state change recompiling
the shaders at drawtime.

All binds are now treated like persistent binds and will stick until a new
shading group bind a different shader. The only difference is that you can
still change it with a new subgroup or same shader shgroup.

Since unbinding can be heavy we only do it when using `--debug-gpu`.

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

M	source/blender/draw/intern/draw_manager.c
M	source/blender/draw/intern/draw_manager.h
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/draw/intern/draw_manager_exec.c
M	source/blender/gpu/GPU_shader.h
M	source/blender/gpu/GPU_texture.h
M	source/blender/gpu/intern/gpu_shader.c
M	source/blender/gpu/intern/gpu_texture.c

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

diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index f2096073ac4..e7dff422105 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -591,9 +591,6 @@ static void drw_viewport_var_init(void)
     ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d);
   }
 
-  /* Alloc array of texture reference. */
-  memset(&DST.RST, 0x0, sizeof(DST.RST));
-
   if (G_draw.view_ubo == NULL) {
     G_draw.view_ubo = DRW_uniformbuffer_create(sizeof(DRWViewUboStorage), NULL);
   }
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 295e45c0fb3..b8c344bf80d 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -277,13 +277,9 @@ typedef enum {
   DRW_UNIFORM_FLOAT,
   DRW_UNIFORM_FLOAT_COPY,
   DRW_UNIFORM_TEXTURE,
-  DRW_UNIFORM_TEXTURE_PERSIST,
   DRW_UNIFORM_TEXTURE_REF,
-  DRW_UNIFORM_TEXTURE_REF_PERSIST,
   DRW_UNIFORM_BLOCK,
-  DRW_UNIFORM_BLOCK_PERSIST,
   DRW_UNIFORM_BLOCK_REF,
-  DRW_UNIFORM_BLOCK_REF_PERSIST,
   DRW_UNIFORM_TFEEDBACK_TARGET,
   /** Per drawcall uniforms/UBO */
   DRW_UNIFORM_BLOCK_OBMATS,
@@ -303,11 +299,25 @@ struct DRWUniform {
   union {
     /* For reference or array/vector types. */
     const void *pvalue;
-    /* Single values. */
+    /* DRW_UNIFORM_TEXTURE */
+    struct {
+      union {
+        GPUTexture *texture;
+        GPUTexture **texture_ref;
+      };
+      eGPUSamplerState sampler_state;
+    };
+    /* DRW_UNIFORM_BLOCK */
+    union {
+      GPUUniformBuffer *block;
+      GPUUniformBuffer **block_ref;
+    };
+    /* DRW_UNIFORM_FLOAT_COPY */
     float fvalue[4];
+    /* DRW_UNIFORM_INT_COPY */
     int ivalue[4];
   };
-  int location;
+  int location;           /* Use as binding point for textures and ubos. */
   uint32_t type : 5;      /* DRWUniformType */
   uint32_t length : 5;    /* cannot be more than 16 */
   uint32_t arraysize : 5; /* cannot be more than 16 too */
@@ -549,20 +559,6 @@ typedef struct DRWManager {
 
   GPUDrawList *draw_list;
 
-  /** GPU Resource State: Memory storage between drawing. */
-  struct {
-    /* High end GPUs supports up to 32 binds per shader stage.
-     * We only use textures during the vertex and fragment stage,
-     * so 2 * 32 slots is a nice limit. */
-    GPUTexture *bound_texs[DST_MAX_SLOTS];
-    uint64_t bound_tex_slots;
-    uint64_t bound_tex_slots_persist;
-
-    GPUUniformBuffer *bound_ubos[DST_MAX_SLOTS];
-    uint64_t bound_ubo_slots;
-    uint64_t bound_ubo_slots_persist;
-  } RST;
-
   struct {
     /* TODO(fclem) optimize: use chunks. */
     DRWDebugLine *lines;
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 8c89aa826e1..8a1ae666057 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -202,6 +202,20 @@ static DRWUniform *drw_shgroup_uniform_create_ex(DRWShadingGroup *shgroup,
       BLI_assert(length <= 4);
       memcpy(uni->fvalue, value, sizeof(float) * length);
       break;
+    case DRW_UNIFORM_BLOCK:
+      uni->block = (GPUUniformBuffer *)value;
+      break;
+    case DRW_UNIFORM_BLOCK_REF:
+      uni->block_ref = (GPUUniformBuffer **)value;
+      break;
+    case DRW_UNIFORM_TEXTURE:
+      uni->texture = (GPUTexture *)value;
+      uni->sampler_state = GPU_SAMPLER_MAX; /* Use texture state for now. */
+      break;
+    case DRW_UNIFORM_TEXTURE_REF:
+      uni->texture_ref = (GPUTexture **)value;
+      uni->sampler_state = GPU_SAMPLER_MAX; /* Use texture state for now. */
+      break;
     default:
       uni->pvalue = (const float *)value;
       break;
@@ -228,12 +242,11 @@ static void drw_shgroup_uniform(DRWShadingGroup *shgroup,
                                 int arraysize)
 {
   int location;
-  if (ELEM(type,
-           DRW_UNIFORM_BLOCK,
-           DRW_UNIFORM_BLOCK_PERSIST,
-           DRW_UNIFORM_BLOCK_REF,
-           DRW_UNIFORM_BLOCK_REF_PERSIST)) {
-    location = GPU_shader_get_uniform_block(shgroup->shader, name);
+  if (ELEM(type, DRW_UNIFORM_BLOCK, DRW_UNIFORM_BLOCK_REF)) {
+    location = GPU_shader_get_uniform_block_binding(shgroup->shader, name);
+  }
+  else if (ELEM(type, DRW_UNIFORM_TEXTURE, DRW_UNIFORM_TEXTURE_REF)) {
+    location = GPU_shader_get_texture_binding(shgroup->shader, name);
   }
   else {
     location = GPU_shader_get_uniform(shgroup->shader, name);
@@ -259,12 +272,13 @@ void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, con
 
 /* Same as DRW_shgroup_uniform_texture but is guaranteed to be bound if shader does not change
  * between shgrp. */
+/* TODO remove */
 void DRW_shgroup_uniform_texture_persistent(DRWShadingGroup *shgroup,
                                             const char *name,
                                             const GPUTexture *tex)
 {
   BLI_assert(tex != NULL);
-  drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE_PERSIST, tex, 0, 1);
+  drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE, tex, 0, 1);
 }
 
 void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
@@ -275,12 +289,13 @@ void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name,
 
 /* Same as DRW_shgroup_uniform_texture_ref but is guaranteed to be bound if shader does not change
  * between shgrp. */
+/* TODO remove */
 void DRW_shgroup_uniform_texture_ref_persistent(DRWShadingGroup *shgroup,
                                                 const char *name,
                                                 GPUTexture **tex)
 {
   BLI_assert(tex != NULL);
-  drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE_REF_PERSIST, tex, 0, 1);
+  drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE_REF, tex, 0, 1);
 }
 
 void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup,
@@ -293,12 +308,13 @@ void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup,
 
 /* Same as DRW_shgroup_uniform_block but is guaranteed to be bound if shader does not change
  * between shgrp. */
+/* TODO remove */
 void DRW_shgroup_uniform_block_persistent(DRWShadingGroup *shgroup,
                                           const char *name,
                                           const GPUUniformBuffer *ubo)
 {
   BLI_assert(ubo != NULL);
-  drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK_PERSIST, ubo, 0, 1);
+  drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK, ubo, 0, 1);
 }
 
 void DRW_shgroup_uniform_block_ref(DRWShadingGroup *shgroup,
@@ -311,12 +327,13 @@ void DRW_shgroup_uniform_block_ref(DRWShadingGroup *shgroup,
 
 /* Same as DRW_shgroup_uniform_block_ref but is guaranteed to be bound if shader does not change
  * between shgrp. */
+/* TODO remove */
 void DRW_shgroup_uniform_block_ref_persistent(DRWShadingGroup *shgroup,
                                               const char *name,
                                               GPUUniformBuffer **ubo)
 {
   BLI_assert(ubo != NULL);
-  drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK_REF_PERSIST, ubo, 0, 1);
+  drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK_REF, ubo, 0, 1);
 }
 
 void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup,
@@ -1208,9 +1225,9 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
   shgroup->uniforms = NULL;
 
   /* TODO(fclem) make them builtin. */
-  int view_ubo_location = GPU_shader_get_uniform_block(shader, "viewBlock");
-  int model_ubo_location = GPU_shader_get_uniform_block(shader, "modelBlock");
-  int info_ubo_location = GPU_shader_get_uniform_block(shader, "infoBlock");
+  int view_ubo_location = GPU_shader_get_uniform_block_binding(shader, "viewBlock");
+  int model_ubo_location = GPU_shader_get_uniform_block_binding(shader, "modelBlock");
+  int info_ubo_location = GPU_shader_get_uniform_block_binding(shader, "infoBlock");
   int baseinst_location = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_BASE_INSTANCE);
   int chunkid_location = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_RESOURCE_CHUNK);
   int resourceid_location = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_RESOURCE_ID);
@@ -1264,7 +1281,7 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
 
   if (view_ubo_location != -1) {
     drw_shgroup_uniform_create_ex(
-        shgroup, view_ubo_location, DRW_UNIFORM_BLOCK_PERSIST, G_draw.view_ubo, 0, 1);
+        shgroup, view_ubo_location, DRW_UNIFORM_BLOCK, G_draw.view_ubo, 0, 1);
   }
   else {
     /* Only here to support builtin shaders. This should not be used by engines. */
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 48e0115741f..25fdb8080a8 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -22,6 +22,7 @@
 
 #include "draw_manager.h"
 
+#include "BLI_alloca.h"
 #include "BLI_math.h"
 #include "BLI_math_bits.h"
 #include "BLI_memblock.h"
@@ -744,107 +745,6 @@ BLI_INLINE void draw_indirect_call(DRWShadingGroup *shgroup, DRWCommandsState *s
   }
 }
 
-enum {
-  BIND_NONE = 0,
-  BIND_TEMP = 1,    /* Release slot after this shading group. */
-  BIND_PERSIST = 2, /* Release slot only after the next shader change. */
-};
-
-static void set_bound_flags(uint64_t *slots, uint64_t *persist_slots, int slot_idx, char bind_type)
-{
-  uint64_t slot = 1llu << (unsigned long)slot_idx;
-  *slots |= slot;
-  if (bind_type == BIND_PERSIST) {
-    *persist_slots |= slot;
-  }
-}
-
-static int get_empty_slot_index(uint64_t slots)
-{
-  uint64_t empty_slots = ~slots;
-  /* Find first empty slot using bitscan. */
-  if (empty_slots != 0) {
-    if ((empty_slots & 0xFFFFFFFFlu) != 0) {
-      return (int)bitscan_forward_uint(empty_slots);
-    }
-    else {
-      return (int)bitscan_forward_uint(empty_slots >> 32) + 32;
-    }
-  }
-  else {
-    /* Greater than GPU_max_textures() */
-    return 99999;
-  }
-}
-
-static void bind_texture(GPUTexture *tex, char bind_type)
-{
-  int idx = GPU_texture_bound_number(tex);
-  if (idx == -1) {
-    /* Texture isn't bound yet. Find an empty slot and bind it.

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list