Commit: f96fffe0db53145872a3d60bb8f4bd3b24e8d32b
Author: mano-wii
Date:   Mon Mar 4 10:18:57 2019 -0300
Branches: master
https://developer.blender.org/rBf96fffe0db53145872a3d60bb8f4bd3b24e8d32b

Fix/workaround T62167: Random crash when displaying wireframes.

Some old AMD drivers crash when a vbo with stride 1 is used a few times.
I have not found a real solution to this problem. So the solution was to use a 
vbo with stride 4 (which in theory is less efficient and takes up more memory 
space).

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

M       source/blender/draw/intern/draw_cache_impl_displist.c
M       source/blender/draw/intern/draw_cache_impl_mesh.c
M       source/blender/gpu/GPU_extensions.h
M       source/blender/gpu/intern/gpu_extensions.c

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

diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c 
b/source/blender/draw/intern/draw_cache_impl_displist.c
index b9555c5e54b..63514acf1c2 100644
--- a/source/blender/draw/intern/draw_cache_impl_displist.c
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -35,6 +35,7 @@
 #include "BKE_displist.h"
 
 #include "GPU_batch.h"
+#include "GPU_extensions.h"
 
 #include "draw_cache_impl.h"  /* own include */
 
@@ -206,10 +207,16 @@ void DRW_displist_vertbuf_create_pos_and_nor(ListBase 
*lb, GPUVertBuf *vbo)
 void DRW_displist_vertbuf_create_wiredata(ListBase *lb, GPUVertBuf *vbo)
 {
        static GPUVertFormat format = { 0 };
-       // static struct { uint wd; } attr_id;  /* UNUSED */
+       static struct { uint wd; } attr_id;
        if (format.attr_len == 0) {
                /* initialize vertex format */
-               /* attr_id.wd = */ GPU_vertformat_attr_add(&format, "wd", 
GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
+               if (!GPU_crappy_amd_driver()) {
+                       /* Some AMD drivers strangely crash with a vbo with 
this format. */
+                       attr_id.wd = GPU_vertformat_attr_add(&format, "wd", 
GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
+               }
+               else {
+                       attr_id.wd = GPU_vertformat_attr_add(&format, "wd", 
GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+               }
        }
 
        int vbo_len_used = curve_render_surface_vert_len_get(lb);
@@ -217,8 +224,16 @@ void DRW_displist_vertbuf_create_wiredata(ListBase *lb, 
GPUVertBuf *vbo)
        GPU_vertbuf_init_with_format(vbo, &format);
        GPU_vertbuf_data_alloc(vbo, vbo_len_used);
 
-       BLI_assert(vbo->format.stride == 1);
-       memset(vbo->data, 0xFF, (size_t)vbo_len_used);
+       if (vbo->format.stride == 1) {
+               memset(vbo->data, 0xFF, (size_t)vbo_len_used);
+       }
+       else {
+               GPUVertBufRaw wd_step;
+               GPU_vertbuf_attr_get_raw_data(vbo, attr_id.wd, &wd_step);
+               for (int i = 0; i < vbo_len_used; i++) {
+                       *((float *)GPU_vertbuf_raw_step(&wd_step)) = 1.0f;
+               }
+       }
 }
 
 void DRW_displist_indexbuf_create_triangles_in_order(ListBase *lb, GPUIndexBuf 
*ibo)
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c 
b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 25dec2b491f..1feea1b09ba 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -52,6 +52,7 @@
 #include "bmesh.h"
 
 #include "GPU_batch.h"
+#include "GPU_extensions.h"
 #include "GPU_material.h"
 
 #include "DRW_render.h"
@@ -2671,12 +2672,34 @@ static float mesh_loop_edge_factor_get(
        return d;
 }
 
+static void vertbuf_raw_step_u8(GPUVertBufRaw *wd_step, const uchar wiredata)
+{
+       *((uchar *)GPU_vertbuf_raw_step(wd_step)) = wiredata;
+}
+
+static void vertbuf_raw_step_u8_to_f32(GPUVertBufRaw *wd_step, const uchar 
wiredata)
+{
+       *((float *)GPU_vertbuf_raw_step(wd_step)) = wiredata / 255.0f;
+}
+
 static void mesh_create_loop_edge_fac(MeshRenderData *rdata, GPUVertBuf *vbo)
 {
        static GPUVertFormat format = { 0 };
        static struct { uint wd; } attr_id;
+       static union { float f; uchar u; } data;
+       static void (*vertbuf_raw_step)(GPUVertBufRaw *, const uchar);
        if (format.attr_len == 0) {
-               attr_id.wd = GPU_vertformat_attr_add(&format, "wd", 
GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
+               if (!GPU_crappy_amd_driver()) {
+                       /* Some AMD drivers strangely crash with a vbo with 
this format. */
+                       attr_id.wd = GPU_vertformat_attr_add(&format, "wd", 
GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
+                       vertbuf_raw_step = vertbuf_raw_step_u8;
+                       data.u = UCHAR_MAX;
+               }
+               else {
+                       attr_id.wd = GPU_vertformat_attr_add(&format, "wd", 
GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+                       vertbuf_raw_step = vertbuf_raw_step_u8_to_f32;
+                       data.f = 1.0f;
+               }
        }
        const int poly_len = mesh_render_data_polys_len_get(rdata);
        const int loop_len = mesh_render_data_loops_len_get(rdata);
@@ -2699,7 +2722,7 @@ static void mesh_create_loop_edge_fac(MeshRenderData 
*rdata, GPUVertBuf *vbo)
                        BM_ITER_MESH_INDEX (efa, &iter_efa, bm, 
BM_FACES_OF_MESH, f) {
                                BM_ITER_ELEM (loop, &iter_loop, efa, 
BM_LOOPS_OF_FACE) {
                                        float ratio = 
mesh_loop_edge_factor_get(efa->no, loop->v->co, loop->v->no, loop->next->v->co);
-                                       *((uchar 
*)GPU_vertbuf_raw_step(&wd_step)) = ratio * 255;
+                                       vertbuf_raw_step(&wd_step, ratio * 255);
                                }
                        }
                        BLI_assert(GPU_vertbuf_raw_used(&wd_step) == loop_len);
@@ -2736,7 +2759,7 @@ static void mesh_create_loop_edge_fac(MeshRenderData 
*rdata, GPUVertBuf *vbo)
                                        ed->flag ^= ME_EDGE_TMP_TAG;
 
                                        if (use_edge_render) {
-                                               *((uchar 
*)GPU_vertbuf_raw_step(&wd_step)) = (ed->flag & ME_EDGERENDER) ? 255 : 0;
+                                               vertbuf_raw_step(&wd_step, 
(ed->flag & ME_EDGERENDER) ? 255 : 0);
                                        }
                                        else {
                                                float vnor_f[3];
@@ -2745,7 +2768,7 @@ static void mesh_create_loop_edge_fac(MeshRenderData 
*rdata, GPUVertBuf *vbo)
                                                                                
        mvert[ml1->v].co,
                                                                                
        vnor_f,
                                                                                
        mvert[ml2->v].co);
-                                               *((uchar 
*)GPU_vertbuf_raw_step(&wd_step)) = ratio * 253 + 1;
+                                               vertbuf_raw_step(&wd_step, 
ratio * 253 + 1);
                                        }
                                }
                        }
@@ -2753,7 +2776,6 @@ static void mesh_create_loop_edge_fac(MeshRenderData 
*rdata, GPUVertBuf *vbo)
                        for (int l = 0; l < loop_len; l++, mloop++) {
                                MEdge *ed = (MEdge *)rdata->medge + mloop->e;
                                if (ed->flag & ME_EDGE_TMP_TAG) {
-                                       uchar data = 255;
                                        GPU_vertbuf_attr_set(vbo, attr_id.wd, 
l, &data);
                                }
                        }
diff --git a/source/blender/gpu/GPU_extensions.h 
b/source/blender/gpu/GPU_extensions.h
index 59cd4aa2776..3154119592d 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -47,6 +47,7 @@ void GPU_get_dfdy_factors(float fac[2]);
 bool GPU_mip_render_workaround(void);
 bool GPU_depth_blitting_workaround(void);
 bool GPU_unused_fb_slot_workaround(void);
+bool GPU_crappy_amd_driver(void);
 
 bool GPU_mem_stats_supported(void);
 void GPU_mem_stats_get(int *totalmem, int *freemem);
diff --git a/source/blender/gpu/intern/gpu_extensions.c 
b/source/blender/gpu/intern/gpu_extensions.c
index b1c8a972980..6fb40b06177 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -211,6 +211,12 @@ bool GPU_unused_fb_slot_workaround(void)
        return GG.unused_fb_slot_workaround;
 }
 
+bool GPU_crappy_amd_driver(void)
+{
+       /* Currently are the same drivers with the `unused_fb_slot` problem. */
+       return GPU_unused_fb_slot_workaround();
+}
+
 void gpu_extensions_init(void)
 {
        /* during 2.8 development each platform has its own OpenGL minimum 
requirements

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to