[Bf-blender-cvs] [3bd05751fb9] blender-v2.91-release: Fix T84459: Wireframe not displaying with AMD GPU

Jeroen Bakker noreply at git.blender.org
Wed Jan 13 14:31:17 CET 2021


Commit: 3bd05751fb90ff268a4d75cf407cdf0090b05bd8
Author: Jeroen Bakker
Date:   Mon Jan 11 08:44:53 2021 +0100
Branches: blender-v2.91-release
https://developer.blender.org/rB3bd05751fb90ff268a4d75cf407cdf0090b05bd8

Fix T84459: Wireframe not displaying with AMD GPU

Issue appears to be caused by AMD graphics driver later than 20.11.1 and
affects older GPUs (Polaris/FIJI cards). Wireframe drawing uses the same
OpenGL data type for storing normals what is known to be faulty.

This patch enabled storing the normals using GPU_COMP_I16. It also
solves the normals drawing in edit mode for vertex and loop normals.

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

M	source/blender/draw/intern/draw_cache_extract_mesh.c

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

diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 40600237235..b6776c8d14c 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -1907,7 +1907,7 @@ typedef struct PosNorLoop {
 
 typedef struct MeshExtract_PosNor_Data {
   PosNorLoop *vbo_data;
-  GPUPackedNormal packed_nor[];
+  GPUNormal normals[];
 } MeshExtract_PosNor_Data;
 
 static void *extract_pos_nor_init(const MeshRenderData *mr,
@@ -1926,7 +1926,7 @@ static void *extract_pos_nor_init(const MeshRenderData *mr,
   GPU_vertbuf_data_alloc(vbo, mr->loop_len + mr->loop_loose_len);
 
   /* Pack normals per vert, reduce amount of computation. */
-  size_t packed_nor_len = sizeof(GPUPackedNormal) * mr->vert_len;
+  size_t packed_nor_len = sizeof(GPUNormal) * mr->vert_len;
   MeshExtract_PosNor_Data *data = MEM_mallocN(sizeof(*data) + packed_nor_len, __func__);
   data->vbo_data = (PosNorLoop *)GPU_vertbuf_get_data(vbo);
 
@@ -1936,13 +1936,13 @@ static void *extract_pos_nor_init(const MeshRenderData *mr,
     BMVert *eve;
     int v;
     BM_ITER_MESH_INDEX (eve, &iter, mr->bm, BM_VERTS_OF_MESH, v) {
-      data->packed_nor[v] = GPU_normal_convert_i10_v3(bm_vert_no_get(mr, eve));
+      data->normals[v].low = GPU_normal_convert_i10_v3(bm_vert_no_get(mr, eve));
     }
   }
   else {
     const MVert *mv = mr->mvert;
     for (int v = 0; v < mr->vert_len; v++, mv++) {
-      data->packed_nor[v] = GPU_normal_convert_i10_s3(mv->no);
+      data->normals[v].low = GPU_normal_convert_i10_s3(mv->no);
     }
   }
   return data;
@@ -1957,7 +1957,7 @@ static void extract_pos_nor_iter_poly_bm(const MeshRenderData *mr,
   {
     PosNorLoop *vert = &data->vbo_data[l_index];
     copy_v3_v3(vert->pos, bm_vert_co_get(mr, l->v));
-    vert->nor = data->packed_nor[BM_elem_index_get(l->v)];
+    vert->nor = data->normals[BM_elem_index_get(l->v)].low;
     BMFace *efa = l->f;
     vert->nor.w = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) ? -1 : 0;
   }
@@ -1974,7 +1974,7 @@ static void extract_pos_nor_iter_poly_mesh(const MeshRenderData *mr,
     PosNorLoop *vert = &data->vbo_data[ml_index];
     const MVert *mv = &mr->mvert[ml->v];
     copy_v3_v3(vert->pos, mv->co);
-    vert->nor = data->packed_nor[ml->v];
+    vert->nor = data->normals[ml->v].low;
     /* Flag for paint mode overlay. */
     if (mp->flag & ME_HIDE || mv->flag & ME_HIDE ||
         ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) &&
@@ -2002,8 +2002,8 @@ static void extract_pos_nor_iter_ledge_bm(const MeshRenderData *mr,
     PosNorLoop *vert = &data->vbo_data[l_index];
     copy_v3_v3(vert[0].pos, bm_vert_co_get(mr, eed->v1));
     copy_v3_v3(vert[1].pos, bm_vert_co_get(mr, eed->v2));
-    vert[0].nor = data->packed_nor[BM_elem_index_get(eed->v1)];
-    vert[1].nor = data->packed_nor[BM_elem_index_get(eed->v2)];
+    vert[0].nor = data->normals[BM_elem_index_get(eed->v1)].low;
+    vert[1].nor = data->normals[BM_elem_index_get(eed->v2)].low;
   }
   EXTRACT_LEDGE_FOREACH_BM_END;
 }
@@ -2019,8 +2019,8 @@ static void extract_pos_nor_iter_ledge_mesh(const MeshRenderData *mr,
     PosNorLoop *vert = &data->vbo_data[ml_index];
     copy_v3_v3(vert[0].pos, mr->mvert[med->v1].co);
     copy_v3_v3(vert[1].pos, mr->mvert[med->v2].co);
-    vert[0].nor = data->packed_nor[med->v1];
-    vert[1].nor = data->packed_nor[med->v2];
+    vert[0].nor = data->normals[med->v1].low;
+    vert[1].nor = data->normals[med->v2].low;
   }
   EXTRACT_LEDGE_FOREACH_MESH_END;
 }
@@ -2036,7 +2036,7 @@ static void extract_pos_nor_iter_lvert_bm(const MeshRenderData *mr,
     const int l_index = offset + lvert_index;
     PosNorLoop *vert = &data->vbo_data[l_index];
     copy_v3_v3(vert->pos, bm_vert_co_get(mr, eve));
-    vert->nor = data->packed_nor[BM_elem_index_get(eve)];
+    vert->nor = data->normals[BM_elem_index_get(eve)].low;
   }
   EXTRACT_LVERT_FOREACH_BM_END;
 }
@@ -2053,7 +2053,7 @@ static void extract_pos_nor_iter_lvert_mesh(const MeshRenderData *mr,
     const int v_index = mr->lverts[lvert_index];
     PosNorLoop *vert = &data->vbo_data[ml_index];
     copy_v3_v3(vert->pos, mv->co);
-    vert->nor = data->packed_nor[v_index];
+    vert->nor = data->normals[v_index].low;
   }
   EXTRACT_LVERT_FOREACH_MESH_END;
 }
@@ -2080,6 +2080,198 @@ static const MeshExtract extract_pos_nor = {
 };
 /** \} */
 
+/* ---------------------------------------------------------------------- */
+/** \name Extract Position and High Quality Vertex Normal
+ * \{ */
+
+typedef struct PosNorHQLoop {
+  float pos[3];
+  short nor[4];
+} PosNorHQLoop;
+
+typedef struct MeshExtract_PosNorHQ_Data {
+  PosNorHQLoop *vbo_data;
+  GPUNormal normals[];
+} MeshExtract_PosNorHQ_Data;
+
+static void *extract_pos_nor_hq_init(const MeshRenderData *mr,
+                                     struct MeshBatchCache *UNUSED(cache),
+                                     void *buf)
+{
+  static GPUVertFormat format = {0};
+  if (format.attr_len == 0) {
+    /* WARNING Adjust #PosNorHQLoop struct accordingly. */
+    GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+    GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+    GPU_vertformat_alias_add(&format, "vnor");
+  }
+  GPUVertBuf *vbo = buf;
+  GPU_vertbuf_init_with_format(vbo, &format);
+  GPU_vertbuf_data_alloc(vbo, mr->loop_len + mr->loop_loose_len);
+
+  /* Pack normals per vert, reduce amount of computation. */
+  size_t packed_nor_len = sizeof(GPUNormal) * mr->vert_len;
+  MeshExtract_PosNorHQ_Data *data = MEM_mallocN(sizeof(*data) + packed_nor_len, __func__);
+  data->vbo_data = (PosNorHQLoop *)GPU_vertbuf_get_data(vbo);
+
+  /* Quicker than doing it for each loop. */
+  if (mr->extract_type == MR_EXTRACT_BMESH) {
+    BMIter iter;
+    BMVert *eve;
+    int v;
+    BM_ITER_MESH_INDEX (eve, &iter, mr->bm, BM_VERTS_OF_MESH, v) {
+      normal_float_to_short_v3(data->normals[v].high, bm_vert_no_get(mr, eve));
+    }
+  }
+  else {
+    const MVert *mv = mr->mvert;
+    for (int v = 0; v < mr->vert_len; v++, mv++) {
+      copy_v3_v3_short(data->normals[v].high, mv->no);
+    }
+  }
+  return data;
+}
+
+static void extract_pos_nor_hq_iter_poly_bm(const MeshRenderData *mr,
+                                            const ExtractPolyBMesh_Params *params,
+                                            void *_data)
+{
+  MeshExtract_PosNorHQ_Data *data = _data;
+  EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr)
+  {
+    PosNorHQLoop *vert = &data->vbo_data[l_index];
+    copy_v3_v3(vert->pos, bm_vert_co_get(mr, l->v));
+    copy_v3_v3_short(vert->nor, data->normals[BM_elem_index_get(l->v)].high);
+
+    BMFace *efa = l->f;
+    vert->nor[3] = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) ? -1 : 0;
+  }
+  EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l);
+}
+
+static void extract_pos_nor_hq_iter_poly_mesh(const MeshRenderData *mr,
+                                              const ExtractPolyMesh_Params *params,
+                                              void *_data)
+{
+  MeshExtract_PosNorHQ_Data *data = _data;
+  EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr)
+  {
+    PosNorHQLoop *vert = &data->vbo_data[ml_index];
+    const MVert *mv = &mr->mvert[ml->v];
+    copy_v3_v3(vert->pos, mv->co);
+    copy_v3_v3_short(vert->nor, data->normals[ml->v].high);
+
+    /* Flag for paint mode overlay. */
+    if (mp->flag & ME_HIDE || mv->flag & ME_HIDE ||
+        ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) &&
+         (mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
+      vert->nor[3] = -1;
+    }
+    else if (mv->flag & SELECT) {
+      vert->nor[3] = 1;
+    }
+    else {
+      vert->nor[3] = 0;
+    }
+  }
+  EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END;
+}
+
+static void extract_pos_nor_hq_iter_ledge_bm(const MeshRenderData *mr,
+                                             const ExtractLEdgeBMesh_Params *params,
+                                             void *_data)
+{
+  MeshExtract_PosNorHQ_Data *data = _data;
+  EXTRACT_LEDGE_FOREACH_BM_BEGIN(eed, ledge_index, params)
+  {
+    int l_index = mr->loop_len + ledge_index * 2;
+    PosNorHQLoop *vert = &data->vbo_data[l_index];
+    copy_v3_v3(vert[0].pos, bm_vert_co_get(mr, eed->v1));
+    copy_v3_v3(vert[1].pos, bm_vert_co_get(mr, eed->v2));
+    copy_v3_v3_short(vert[0].nor, data->normals[BM_elem_index_get(eed->v1)].high);
+    vert[0].nor[3] = 0;
+    copy_v3_v3_short(vert[1].nor, data->normals[BM_elem_index_get(eed->v2)].high);
+    vert[1].nor[3] = 0;
+  }
+  EXTRACT_LEDGE_FOREACH_BM_END;
+}
+
+static void extract_pos_nor_hq_iter_ledge_mesh(const MeshRenderData *mr,
+                                               const ExtractLEdgeMesh_Params *params,
+                                               void *_data)
+{
+  MeshExtract_PosNorHQ_Data *data = _data;
+  EXTRACT_LEDGE_FOREACH_MESH_BEGIN(med, ledge_index, params, mr)
+  {
+    const int ml_index = mr->loop_len + ledge_index * 2;
+    PosNorHQLoop *vert = &data->vbo_data[ml_index];
+    copy_v3_v3(vert[0].pos, mr->mvert[med->v1].co);
+    copy_v3_v3(vert[1].pos, mr->mvert[med->v2].co);
+    copy_v3_v3_short(vert[0].nor, data->normals[med->v1].high);
+    vert[0].nor[3] = 0;
+    copy_v3_v3_short(vert[1].nor, data->normals[med->v2].high);
+    vert[1].nor[3] = 0;
+  }
+  EXTRACT_LEDGE_FOREACH_MESH_END;
+}
+
+static void extract_pos_nor_hq_iter_lvert_bm(const MeshRenderData *mr,
+                                             const ExtractLVertBMesh_Params *params,
+                                             void *_data)
+{
+  MeshExtract_PosNorHQ_Data *data = _data;
+  const int offset = mr->loop_len + (mr->edge_loose_len * 2);
+  EXTRACT_LVERT_FOREACH_BM_BEGIN(eve, lvert_index, params)
+  {
+    const int l_index = offset + lvert_index;
+    PosNorHQLoop *vert = &data->vbo_data[l_index];
+    copy_v3_v3(vert->pos, bm_vert_co_get(mr, eve));
+    copy_v3_v3_short(vert->nor, data->normals[BM_elem_index_get(eve)].high);
+    vert->nor[3] = 0;
+  }
+  EXTRACT_LVERT_FOREACH_BM_END;
+}
+
+static void extract_pos_nor_hq_iter_lvert_mesh(const MeshRenderData *mr,
+           

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list