diff options
author | mano-wii <germano.costa@ig.com.br> | 2019-03-01 18:36:34 +0300 |
---|---|---|
committer | mano-wii <germano.costa@ig.com.br> | 2019-03-01 18:40:20 +0300 |
commit | fa5950d87820655ef357a3a0ec301ff4816a00e5 (patch) | |
tree | 4a9b9e8c888912789232c2ae8134b9cf16fa48fc /source/blender | |
parent | 5eee1b4d1bfe23515350809511e8e8fcc1c64500 (diff) |
Fix crash with wireframe on highpoly curves on some AMD gpus.
Differential Revision: https://developer.blender.org/D4433
Diffstat (limited to 'source/blender')
4 files changed, 40 insertions, 18 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 2ec4ab526ef..7a8cea23655 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -81,7 +81,8 @@ struct GPUBatch **DRW_metaball_batch_cache_get_surface_shaded( struct GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(struct Object *ob); /* DispList */ -void DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(struct ListBase *lb, struct GPUVertBuf *vbo); +void DRW_displist_vertbuf_create_pos_and_nor(struct ListBase *lb, struct GPUVertBuf *vbo); +void DRW_displist_vertbuf_create_wiredata(struct ListBase *lb, struct GPUVertBuf *vbo); void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv( struct ListBase *lb, struct GPUVertBuf *vbo_pos_nor, struct GPUVertBuf *vbo_uv); void DRW_displist_indexbuf_create_lines_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo); diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c index d40e33ab6e7..ebffedf9454 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.c +++ b/source/blender/draw/intern/draw_cache_impl_curve.c @@ -346,6 +346,7 @@ static void curve_cd_calc_used_gpu_layers(int *cd_layers, struct GPUMaterial **g typedef struct CurveBatchCache { struct { GPUVertBuf *pos_nor; + GPUVertBuf *edge_fac; GPUVertBuf *curves_pos; GPUVertBuf *loop_pos_nor; @@ -915,6 +916,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob) if (DRW_batch_requested(cache->batch.surfaces_edges, GPU_PRIM_LINES)) { DRW_ibo_request(cache->batch.surfaces_edges, &cache->ibo.surfaces_lines); DRW_vbo_request(cache->batch.surfaces_edges, &cache->ordered.pos_nor); + DRW_vbo_request(cache->batch.surfaces_edges, &cache->ordered.edge_fac); } if (DRW_batch_requested(cache->batch.curves, GPU_PRIM_LINE_STRIP)) { DRW_ibo_request(cache->batch.curves, &cache->ibo.curves_lines); @@ -954,6 +956,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob) /* Generate MeshRenderData flags */ int mr_flag = 0; DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.pos_nor, CU_DATATYPE_SURFACE); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.edge_fac, CU_DATATYPE_SURFACE); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.curves_pos, CU_DATATYPE_WIRE); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_pos_nor, CU_DATATYPE_SURFACE); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_uv, CU_DATATYPE_SURFACE); @@ -979,7 +982,10 @@ void DRW_curve_batch_cache_create_requested(Object *ob) /* Generate VBOs */ if (DRW_vbo_requested(cache->ordered.pos_nor)) { - DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(lb, cache->ordered.pos_nor); + DRW_displist_vertbuf_create_pos_and_nor(lb, cache->ordered.pos_nor); + } + if (DRW_vbo_requested(cache->ordered.edge_fac)) { + DRW_displist_vertbuf_create_wiredata(lb, cache->ordered.edge_fac); } if (DRW_vbo_requested(cache->ordered.curves_pos)) { curve_create_curves_pos(rdata, cache->ordered.curves_pos); diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c index b93c63503db..c9952928755 100644 --- a/source/blender/draw/intern/draw_cache_impl_displist.c +++ b/source/blender/draw/intern/draw_cache_impl_displist.c @@ -165,15 +165,14 @@ static int displist_indexbufbuilder_tess_set( return v_idx; } -void DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(ListBase *lb, GPUVertBuf *vbo) +void DRW_displist_vertbuf_create_pos_and_nor(ListBase *lb, GPUVertBuf *vbo) { static GPUVertFormat format = { 0 }; - static struct { uint pos, nor, wd; } attr_id; + static struct { uint pos, nor; } attr_id; if (format.attr_len == 0) { /* initialize vertex format */ attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - attr_id.wd = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); + attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I10, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); } GPU_vertbuf_init_with_format(vbo, &format); @@ -189,13 +188,10 @@ void DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(ListBase *lb, GPUVertB const float *fp_no = dl->nors; const int vbo_end = vbo_len_used + dl_vert_len(dl); while (vbo_len_used < vbo_end) { - uchar sharpness = 0xFF; - GPU_vertbuf_attr_set(vbo, attr_id.wd, vbo_len_used, &sharpness); GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, fp_co); if (fp_no) { - static short short_no[4]; - normal_float_to_short_v3(short_no, fp_no); - GPU_vertbuf_attr_set(vbo, attr_id.nor, vbo_len_used, short_no); + GPUPackedNormal vnor_pack = GPU_normal_convert_i10_v3(fp_no); + GPU_vertbuf_attr_set(vbo, attr_id.nor, vbo_len_used, &vnor_pack); if (ndata_is_single == false) { fp_no += 3; } @@ -207,6 +203,22 @@ void DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(ListBase *lb, GPUVertB } } +void DRW_displist_vertbuf_create_wiredata(ListBase *lb, GPUVertBuf *vbo) +{ + static GPUVertFormat format = { 0 }; + 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); + } + + int vbo_len_used = curve_render_surface_vert_len_get(lb); + + GPU_vertbuf_init_with_format(vbo, &format); + GPU_vertbuf_data_alloc(vbo, vbo_len_used); + memset(vbo->data, 0xFF, (size_t)(vbo_len_used * format.stride)); +} + void DRW_displist_indexbuf_create_triangles_in_order(ListBase *lb, GPUIndexBuf *ibo) { const int tri_len = curve_render_surface_tri_len_get(lb); diff --git a/source/blender/draw/intern/draw_cache_impl_metaball.c b/source/blender/draw/intern/draw_cache_impl_metaball.c index 0d2c06e4c02..811f01aa83a 100644 --- a/source/blender/draw/intern/draw_cache_impl_metaball.c +++ b/source/blender/draw/intern/draw_cache_impl_metaball.c @@ -139,7 +139,7 @@ static GPUVertBuf *mball_batch_cache_get_pos_and_normals(Object *ob, MetaBallBat if (cache->pos_nor_in_order == NULL) { ListBase *lb = &ob->runtime.curve_cache->disp; cache->pos_nor_in_order = MEM_callocN(sizeof(GPUVertBuf), __func__); - DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(lb, cache->pos_nor_in_order); + DRW_displist_vertbuf_create_pos_and_nor(lb, cache->pos_nor_in_order); } return cache->pos_nor_in_order; } @@ -202,16 +202,19 @@ GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(Object *ob) if (cache->face_wire.batch == NULL) { ListBase *lb = &ob->runtime.curve_cache->disp; - GPUVertBuf *vbo_pos_nor = MEM_callocN(sizeof(GPUVertBuf), __func__); - DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(lb, vbo_pos_nor); + GPUVertBuf *vbo_wiredata = MEM_callocN(sizeof(GPUVertBuf), __func__); + DRW_displist_vertbuf_create_wiredata(lb, vbo_wiredata); GPUIndexBuf *ibo = MEM_callocN(sizeof(GPUIndexBuf), __func__); DRW_displist_indexbuf_create_lines_in_order(lb, ibo); - cache->face_wire.batch = GPU_batch_create_ex(GPU_PRIM_LINES, - vbo_pos_nor, - ibo, - GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX); + cache->face_wire.batch = GPU_batch_create_ex( + GPU_PRIM_LINES, + mball_batch_cache_get_pos_and_normals(ob, cache), + ibo, + GPU_BATCH_OWNS_INDEX); + + GPU_batch_vertbuf_add_ex(cache->face_wire.batch, vbo_wiredata, true); } return cache->face_wire.batch; |