[Bf-blender-cvs] [4269a8504f7] tmp-drw-callbatching: DRW: Make workaround for drivers with broken gl_InstanceID

Clément Foucault noreply at git.blender.org
Sat Aug 17 14:50:22 CEST 2019


Commit: 4269a8504f71e3fc990c777c7929deebcbf203c7
Author: Clément Foucault
Date:   Fri Jun 7 20:51:58 2019 +0200
Branches: tmp-drw-callbatching
https://developer.blender.org/rB4269a8504f71e3fc990c777c7929deebcbf203c7

DRW: Make workaround for drivers with broken gl_InstanceID

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

M	source/blender/draw/modes/shaders/common_view_lib.glsl
M	source/blender/gpu/intern/gpu_batch.c
M	source/blender/gpu/intern/gpu_shader.c

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

diff --git a/source/blender/draw/modes/shaders/common_view_lib.glsl b/source/blender/draw/modes/shaders/common_view_lib.glsl
index be7a660decd..4c057d2ba88 100644
--- a/source/blender/draw/modes/shaders/common_view_lib.glsl
+++ b/source/blender/draw/modes/shaders/common_view_lib.glsl
@@ -36,6 +36,10 @@ uniform int baseInstance;
 #  ifdef IN_PLACE_INSTANCES
 /* When drawing instances of an object at the same position. */
 #    define instanceId 0
+#  elif defined(GPU_CRAPPY_AMD_DRIVER)
+/* NOTE: This does contain the baseInstance ofset */
+in int _instanceId;
+#    define instanceId (_instanceId - baseInstance)
 #  else
 #    define instanceId gl_InstanceID
 #  endif
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
index 9d24fc6b27e..b279435772b 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -446,6 +446,34 @@ static void create_bindings(GPUVertBuf *verts,
   }
 }
 
+static void instance_id_workaround(GPUBatch *batch)
+{
+  /**
+   * A driver bug make it so that when using an attribute with GL_INT_2_10_10_10_REV as format,
+   * the gl_InstanceID is incremented by the 2 bit component of the attrib. To workaround this,
+   * we create a new vertex attrib containing the expected value of gl_InstanceID.
+   **/
+  const GPUShaderInput *input = GPU_shaderinterface_attr(batch->interface, "_instanceId");
+  if (input) {
+#define DRW_RESOURCE_CHUNK_LEN 512 /* Keep in sync. */
+    static GLint vbo_id = 0;
+    if (vbo_id == 0) {
+      short data[DRW_RESOURCE_CHUNK_LEN];
+      for (int i = 0; i < DRW_RESOURCE_CHUNK_LEN; i++) {
+        data[i] = i;
+      }
+      /* GPU_context takes care of deleting `vbo_id` at the end. */
+      vbo_id = GPU_buf_alloc();
+      glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
+      glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
+    }
+    glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
+    glEnableVertexAttribArray(input->location);
+    glVertexAttribIPointer(input->location, 1, GL_SHORT, 0, NULL);
+    glVertexAttribDivisor(input->location, 1);
+  }
+}
+
 static void batch_update_program_bindings(GPUBatch *batch, uint i_first)
 {
   /* Reverse order so first vbos have more prevalence (in term of attrib override). */
@@ -460,6 +488,9 @@ static void batch_update_program_bindings(GPUBatch *batch, uint i_first)
   if (batch->elem) {
     GPU_indexbuf_use(batch->elem);
   }
+  if (GPU_crappy_amd_driver()) {
+    instance_id_workaround(batch);
+  }
 }
 
 void GPU_batch_program_use_begin(GPUBatch *batch)
@@ -638,7 +669,7 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi
   }
 
   if (!GPU_arb_base_instance_is_supported()) {
-    if (i_first > 0 && i_count > 0) {
+    if (i_first > 0) {
       /* If using offset drawing with instancing, we must
        * use the default VAO and redo bindings. */
       glBindVertexArray(GPU_vao_default());
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 98af9714580..9ac0a409d72 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -259,6 +259,9 @@ static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
   /* some useful defines to detect GPU type */
   if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
     strcat(defines, "#define GPU_ATI\n");
+    if (GPU_crappy_amd_driver()) {
+      strcat(defines, "#define GPU_CRAPPY_AMD_DRIVER\n");
+    }
   }
   else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY)) {
     strcat(defines, "#define GPU_NVIDIA\n");



More information about the Bf-blender-cvs mailing list