[Bf-blender-cvs] [922d53a791d] master: Metal: Adding alternative support for GPU_PRIM_TRI_FAN/LINE_LOOP For Metal backend.

Jason Fielder noreply at git.blender.org
Wed Mar 30 20:40:49 CEST 2022


Commit: 922d53a791d53b77e5ffcf65003555fae0a0e883
Author: Jason Fielder
Date:   Wed Mar 30 20:24:39 2022 +0200
Branches: master
https://developer.blender.org/rB922d53a791d53b77e5ffcf65003555fae0a0e883

Metal: Adding alternative support for GPU_PRIM_TRI_FAN/LINE_LOOP For Metal backend.

- Metal uniform array compatibility in DRW module.
- Guard OpenGL-specific workarounds and flushes behind GPU_type_matches_ex API guard. Add further render boundaries for render paths called outside of the main loop.

Authored by Apple: Michael Parkin-White

Ref: T96261

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D14438

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

M	source/blender/draw/engines/eevee/eevee_effects.c
M	source/blender/draw/engines/eevee/eevee_occlusion.c
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_manager.c
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/draw/intern/draw_manager_exec.c
M	source/blender/draw/intern/draw_manager_shader.c
M	source/blender/editors/interface/interface_draw.c
M	source/blender/editors/interface/interface_widgets.c
M	source/blender/editors/screen/screen_draw.c
M	source/blender/gpu/GPU_primitive.h
M	source/blender/gpu/intern/gpu_batch_presets.c
M	source/blender/gpu/shaders/gpu_shader_2D_image_rect_vert.glsl

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

diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 78b9b68bb01..5fa719facf4 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -108,7 +108,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
    * MinMax Pyramid
    */
 
-  if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+  if (GPU_type_matches_ex(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) {
     /* Intel gpu seems to have problem rendering to only depth hiz_format */
     DRW_texture_ensure_2d(&txl->maxzbuffer, UNPACK2(effects->hiz_size), GPU_R32F, DRW_TEX_MIPMAP);
     GPU_framebuffer_ensure_config(&fbl->maxzbuffer_fb,
@@ -230,7 +230,7 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
 
   /* Intel gpu seems to have problem rendering to only depth format.
    * Use color texture instead. */
-  if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+  if (GPU_type_matches_ex(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) {
     downsample_write = DRW_STATE_WRITE_COLOR;
   }
 
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index e148ac53cd4..d896c4e9331 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -200,7 +200,8 @@ void EEVEE_occlusion_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
     }
 
     if (GPU_mip_render_workaround() ||
-        GPU_type_matches(GPU_DEVICE_INTEL_UHD, GPU_OS_WIN, GPU_DRIVER_ANY)) {
+        GPU_type_matches_ex(
+            GPU_DEVICE_INTEL_UHD, GPU_OS_WIN, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) {
       /* Fix dot corruption on intel HD5XX/HD6XX series. */
       GPU_flush();
     }
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 8fc97ddcfc2..1c2a580e26d 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -26,6 +26,7 @@
 
 #include "GPU_batch.h"
 #include "GPU_batch_utils.h"
+#include "GPU_capabilities.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -395,12 +396,12 @@ GPUBatch *DRW_cache_quad_get(void)
 
     int v = 0;
     int flag = VCLASS_EMPTY_SCALED;
-    const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
+    const float p[4][2] = {{-1.0f, 1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f}, {1.0f, -1.0f}};
     for (int a = 0; a < 4; a++) {
       GPU_vertbuf_vert_set(vbo, v++, &(Vert){{p[a][0], p[a][1], 0.0f}, flag});
     }
 
-    SHC.drw_quad = GPU_batch_create_ex(GPU_PRIM_TRI_FAN, vbo, NULL, GPU_BATCH_OWNS_VBO);
+    SHC.drw_quad = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
   }
   return SHC.drw_quad;
 }
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 39ae01697a1..75c27937f25 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -55,6 +55,7 @@
 #include "GPU_framebuffer.h"
 #include "GPU_immediate.h"
 #include "GPU_matrix.h"
+#include "GPU_platform.h"
 #include "GPU_shader_shared.h"
 #include "GPU_state.h"
 #include "GPU_uniform_buffer.h"
@@ -1706,7 +1707,9 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
   drw_engines_draw_scene();
 
   /* Fix 3D view "lagging" on APPLE and WIN32+NVIDIA. (See T56996, T61474) */
-  GPU_flush();
+  if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_ANY, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) {
+    GPU_flush();
+  }
 
   DRW_stats_reset();
 
@@ -1938,6 +1941,9 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
   };
   drw_context_state_init();
 
+  /* Begin GPU workload Boundary */
+  GPU_render_begin();
+
   const int size[2] = {engine->resolution_x, engine->resolution_y};
 
   drw_manager_init(&DST, NULL, size);
@@ -1993,6 +1999,9 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
 
   /* Reset state after drawing */
   DRW_state_reset();
+
+  /* End GPU workload Boundary */
+  GPU_render_end();
 }
 
 void DRW_render_object_iter(
@@ -2072,7 +2081,10 @@ void DRW_custom_pipeline(DrawEngineType *draw_engine_type,
    * resources as the main thread (viewport) may lead to data
    * races and undefined behavior on certain drivers. Using
    * GPU_finish to sync seems to fix the issue. (see T62997) */
-  GPU_finish();
+  eGPUBackendType type = GPU_backend_get_type();
+  if (type == GPU_BACKEND_OPENGL) {
+    GPU_finish();
+  }
 
   drw_manager_exit(&DST);
 }
@@ -2173,7 +2185,9 @@ void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph,
   drw_engines_draw_scene();
 
   /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */
-  GPU_flush();
+  if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_ANY, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) {
+    GPU_flush();
+  }
 
   if (DST.draw_ctx.evil_C) {
     DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
@@ -3094,6 +3108,7 @@ void DRW_opengl_context_enable_ex(bool UNUSED(restore))
      * This shall remain in effect until immediate mode supports
      * multiple threads. */
     BLI_ticket_mutex_lock(DST.gl_context_mutex);
+    GPU_render_begin();
     WM_opengl_context_activate(DST.gl_context);
     GPU_context_active_set(DST.gpu_context);
   }
@@ -3105,7 +3120,9 @@ void DRW_opengl_context_disable_ex(bool restore)
 #ifdef __APPLE__
     /* Need to flush before disabling draw context, otherwise it does not
      * always finish drawing and viewport can be empty or partially drawn */
-    GPU_flush();
+    if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) {
+      GPU_flush();
+    }
 #endif
 
     if (BLI_thread_is_main() && restore) {
@@ -3116,6 +3133,10 @@ void DRW_opengl_context_disable_ex(bool restore)
       GPU_context_active_set(NULL);
     }
 
+    /* Render boundaries are opened and closed here as this may be
+     * called outside of an existing render loop. */
+    GPU_render_end();
+
     BLI_ticket_mutex_unlock(DST.gl_context_mutex);
   }
 }
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index b01c901c77f..2c9ebfc080e 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -498,9 +498,13 @@ void DRW_shgroup_uniform_vec4_array_copy(DRWShadingGroup *shgroup,
     return;
   }
 
+  /* Each array element stored as an individual entry in the uniform list.
+   * All entries from the same array share the same base location,
+   * and array-size used to determine the number of elements
+   * copied in draw_update_uniforms. */
   for (int i = 0; i < arraysize; i++) {
     drw_shgroup_uniform_create_ex(
-        shgroup, location + i, DRW_UNIFORM_FLOAT_COPY, &value[i], 0, 4, 1);
+        shgroup, location, DRW_UNIFORM_FLOAT_COPY, &value[i], 0, 4, arraysize);
   }
 }
 
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 7d6ce51ff35..3b5b06c94d4 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -584,21 +584,85 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
                                  DRWCommandsState *state,
                                  bool *use_tfeedback)
 {
+#define MAX_UNIFORM_STACK_SIZE 64
+
+  /* Uniform array elements stored as separate entries. We need to batch these together */
+  int current_uniform_array_loc = -1;
+  unsigned int current_array_index = 0;
+  static union {
+    int istack[MAX_UNIFORM_STACK_SIZE];
+    float fstack[MAX_UNIFORM_STACK_SIZE];
+  } uniform_stack;
+
+  /* Loop through uniforms. */
   for (DRWUniformChunk *unichunk = shgroup->uniforms; unichunk; unichunk = unichunk->next) {
     DRWUniform *uni = unichunk->uniforms;
+
     for (int i = 0; i < unichunk->uniform_used; i++, uni++) {
+
+      /* For uniform array copies, copy per-array-element data into local buffer before upload. */
+      if (uni->arraysize > 1 &&
+          (uni->type == DRW_UNIFORM_INT_COPY || uni->type == DRW_UNIFORM_FLOAT_COPY)) {
+
+        /* Begin copying uniform array. */
+        if (current_array_index == 0) {
+          current_uniform_array_loc = uni->location;
+        }
+
+        /* Debug check same array loc. */
+        BLI_assert(current_uniform_array_loc > -1);
+        BLI_assert(current_uniform_array_loc == uni->location);
+
+        /* Copy array element data to local buffer. */
+        BLI_assert(((current_array_index + 1) * uni->length) <= MAX_UNIFORM_STACK_SIZE);
+        if (uni->type == DRW_UNIFORM_INT_COPY) {
+          memcpy(&uniform_stack.istack[current_array_index * uni->length],
+                 uni->ivalue,
+                 sizeof(int) * uni->length);
+        }
+        else {
+          memcpy(&uniform_stack.fstack[current_array_index * uni->length],
+                 uni->fvalue,
+                 sizeof(float) * uni->length);
+        }
+        current_array_index++;
+        BLI_assert(current_array_index <= uni->arraysize);
+
+        /* Flush array data to shader. */
+        if (current_array_index == uni->arraysize) {
+          if (uni->type == DRW_UNIFORM_INT_COPY) {
+            GPU_shader_uniform_vector_int(
+                shgroup->shader, uni->location, uni->length, uni->arraysize, uniform_stack.istack);
+          }
+          else {
+            GPU_shader_uniform_vector(
+                shgroup->shader, uni->location, uni->length, uni->arraysize, uniform_stack.fstack);
+          }
+          current_array_index = 0;
+          current_uniform_array_loc = -1;
+        }
+        continue;
+      }
+
+      /* Handle standard cases. */
       switch (uni->type) {
         case DRW_UNIFORM_INT_COPY:
-          GPU_shader_uniform_vector_int(
-              shgroup->shader, uni->location, uni->length, uni->arraysize, uni->ivalue);
+          BLI_assert(uni->arraysize == 1);
+          if (uni->arraysize == 1) {
+            GPU_shader_uniform_vector_int(
+       

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list