diff options
-rw-r--r-- | source/blender/blenkernel/BKE_subdiv_modifier.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subdiv_modifier.c | 4 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_subdivision.cc | 151 |
3 files changed, 100 insertions, 59 deletions
diff --git a/source/blender/blenkernel/BKE_subdiv_modifier.h b/source/blender/blenkernel/BKE_subdiv_modifier.h index 40e8ee2f999..e9de7d1532e 100644 --- a/source/blender/blenkernel/BKE_subdiv_modifier.h +++ b/source/blender/blenkernel/BKE_subdiv_modifier.h @@ -13,6 +13,10 @@ extern "C" { #endif +/* Hardcoded for until GPU shaders are automatically generated, then we will have a more + * programmatic way of detecting this. */ +#define MAX_GPU_SUBDIV_SSBOS 12 + struct Mesh; struct Object; struct Scene; diff --git a/source/blender/blenkernel/intern/subdiv_modifier.c b/source/blender/blenkernel/intern/subdiv_modifier.c index 34dfdaf7595..83772f153d9 100644 --- a/source/blender/blenkernel/intern/subdiv_modifier.c +++ b/source/blender/blenkernel/intern/subdiv_modifier.c @@ -77,6 +77,10 @@ static bool is_subdivision_evaluation_possible_on_gpu(void) return false; } + if (GPU_max_shader_storage_buffer_bindings() < MAX_GPU_SUBDIV_SSBOS) { + return false; + } + const int available_evaluators = openSubdiv_getAvailableEvaluators(); if ((available_evaluators & OPENSUBDIV_EVALUATOR_GLSL_COMPUTE) == 0) { return false; diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 8682a15feba..8aa7ff66d65 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -1244,15 +1244,17 @@ void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache, GPUVertBuf *pos_no GPUShader *shader = get_patch_evaluation_shader(SHADER_PATCH_EVALUATION); GPU_shader_bind(shader); - GPU_vertbuf_bind_as_ssbo(src_buffer, 0); - GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_handles, 1); - GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_quadtree, 2); - GPU_vertbuf_bind_as_ssbo(cache->patch_coords, 3); - GPU_vertbuf_bind_as_ssbo(cache->verts_orig_index, 4); - GPU_vertbuf_bind_as_ssbo(patch_arrays_buffer, 5); - GPU_vertbuf_bind_as_ssbo(patch_index_buffer, 6); - GPU_vertbuf_bind_as_ssbo(patch_param_buffer, 7); - GPU_vertbuf_bind_as_ssbo(pos_nor, 8); + int binding_point = 0; + GPU_vertbuf_bind_as_ssbo(src_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_handles, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_quadtree, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->patch_coords, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->verts_orig_index, binding_point++); + GPU_vertbuf_bind_as_ssbo(patch_arrays_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(patch_index_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(patch_param_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(pos_nor, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads); @@ -1308,15 +1310,17 @@ void draw_subdiv_extract_uvs(const DRWSubdivCache *cache, GPUShader *shader = get_patch_evaluation_shader(SHADER_PATCH_EVALUATION_FVAR); GPU_shader_bind(shader); - GPU_vertbuf_bind_as_ssbo(src_buffer, 0); - GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_handles, 1); - GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_quadtree, 2); - GPU_vertbuf_bind_as_ssbo(cache->patch_coords, 3); - GPU_vertbuf_bind_as_ssbo(cache->verts_orig_index, 4); - GPU_vertbuf_bind_as_ssbo(patch_arrays_buffer, 5); - GPU_vertbuf_bind_as_ssbo(patch_index_buffer, 6); - GPU_vertbuf_bind_as_ssbo(patch_param_buffer, 7); - GPU_vertbuf_bind_as_ssbo(uvs, 8); + int binding_point = 0; + GPU_vertbuf_bind_as_ssbo(src_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_handles, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_quadtree, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->patch_coords, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->verts_orig_index, binding_point++); + GPU_vertbuf_bind_as_ssbo(patch_arrays_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(patch_index_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(patch_param_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(uvs, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); /* The buffer offset has the stride baked in (which is 2 as we have UVs) so remove the stride by * dividing by 2 */ @@ -1380,13 +1384,15 @@ void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache, GPU_shader_bind(shader); + int binding_point = 0; /* subdiv_polygon_offset is always at binding point 0 for each shader using it. */ - GPU_vertbuf_bind_as_ssbo(cache->subdiv_polygon_offset_buffer, 0); - GPU_vertbuf_bind_as_ssbo(src_data, 1); - GPU_vertbuf_bind_as_ssbo(cache->face_ptex_offset_buffer, 2); - GPU_vertbuf_bind_as_ssbo(cache->patch_coords, 3); - GPU_vertbuf_bind_as_ssbo(cache->extra_coarse_face_data, 4); - GPU_vertbuf_bind_as_ssbo(dst_data, 5); + GPU_vertbuf_bind_as_ssbo(cache->subdiv_polygon_offset_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(src_data, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->face_ptex_offset_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->patch_coords, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->extra_coarse_face_data, binding_point++); + GPU_vertbuf_bind_as_ssbo(dst_data, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, 0, dst_offset, cache->num_subdiv_quads); @@ -1406,12 +1412,15 @@ void draw_subdiv_build_sculpt_data_buffer(const DRWSubdivCache *cache, GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_SCULPT_DATA, nullptr); GPU_shader_bind(shader); + /* Mask VBO is always at binding point 0. */ if (mask_vbo) { GPU_vertbuf_bind_as_ssbo(mask_vbo, 0); } - GPU_vertbuf_bind_as_ssbo(face_set_vbo, 1); - GPU_vertbuf_bind_as_ssbo(sculpt_data, 2); + int binding_point = 1; + GPU_vertbuf_bind_as_ssbo(face_set_vbo, binding_point++); + GPU_vertbuf_bind_as_ssbo(sculpt_data, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads, mask_vbo != nullptr); @@ -1439,6 +1448,7 @@ void draw_subdiv_accumulate_normals(const DRWSubdivCache *cache, GPU_vertbuf_bind_as_ssbo(face_adjacency_lists, binding_point++); GPU_vertbuf_bind_as_ssbo(vertex_loop_map, binding_point++); GPU_vertbuf_bind_as_ssbo(vertex_normals, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_verts); @@ -1463,6 +1473,7 @@ void draw_subdiv_finalize_normals(const DRWSubdivCache *cache, GPU_vertbuf_bind_as_ssbo(vertex_normals, binding_point++); GPU_vertbuf_bind_as_ssbo(subdiv_loop_subdiv_vert_index, binding_point++); GPU_vertbuf_bind_as_ssbo(pos_nor, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads); @@ -1482,9 +1493,12 @@ void draw_subdiv_finalize_custom_normals(const DRWSubdivCache *cache, GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_NORMALS_FINALIZE, "#define CUSTOM_NORMALS"); GPU_shader_bind(shader); - GPU_vertbuf_bind_as_ssbo(src_custom_normals, 0); + int binding_point = 0; + GPU_vertbuf_bind_as_ssbo(src_custom_normals, binding_point++); /* outputPosNor is bound at index 2 in the base shader. */ - GPU_vertbuf_bind_as_ssbo(pos_nor, 2); + binding_point = 2; + GPU_vertbuf_bind_as_ssbo(pos_nor, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads); @@ -1519,15 +1533,22 @@ void draw_subdiv_build_tris_buffer(const DRWSubdivCache *cache, do_single_material ? SHADER_BUFFER_TRIS : SHADER_BUFFER_TRIS_MULTIPLE_MATERIALS, defines); GPU_shader_bind(shader); - /* Outputs */ - GPU_indexbuf_bind_as_ssbo(subdiv_tris, 1); - if (!do_single_material) { - GPU_vertbuf_bind_as_ssbo(cache->polygon_mat_offset, 2); /* subdiv_polygon_offset is always at binding point 0 for each shader using it. */ GPU_vertbuf_bind_as_ssbo(cache->subdiv_polygon_offset_buffer, 0); } + int binding_point = 1; + + /* Outputs */ + GPU_indexbuf_bind_as_ssbo(subdiv_tris, binding_point++); + + if (!do_single_material) { + GPU_vertbuf_bind_as_ssbo(cache->polygon_mat_offset, binding_point++); + } + + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); + drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads); /* This generates an index buffer, so we need to put a barrier on the element array. */ @@ -1574,18 +1595,20 @@ void draw_subdiv_build_fdots_buffers(const DRWSubdivCache *cache, GPUShader *shader = get_patch_evaluation_shader(SHADER_PATCH_EVALUATION_FACE_DOTS); GPU_shader_bind(shader); - GPU_vertbuf_bind_as_ssbo(src_buffer, 0); - GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_handles, 1); - GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_quadtree, 2); - GPU_vertbuf_bind_as_ssbo(cache->fdots_patch_coords, 3); - GPU_vertbuf_bind_as_ssbo(cache->verts_orig_index, 4); - GPU_vertbuf_bind_as_ssbo(patch_arrays_buffer, 5); - GPU_vertbuf_bind_as_ssbo(patch_index_buffer, 6); - GPU_vertbuf_bind_as_ssbo(patch_param_buffer, 7); - GPU_vertbuf_bind_as_ssbo(fdots_pos, 8); - GPU_vertbuf_bind_as_ssbo(fdots_nor, 9); - GPU_indexbuf_bind_as_ssbo(fdots_indices, 10); - GPU_vertbuf_bind_as_ssbo(cache->extra_coarse_face_data, 11); + int binding_point = 0; + GPU_vertbuf_bind_as_ssbo(src_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_handles, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_quadtree, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->fdots_patch_coords, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->verts_orig_index, binding_point++); + GPU_vertbuf_bind_as_ssbo(patch_arrays_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(patch_index_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(patch_param_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(fdots_pos, binding_point++); + GPU_vertbuf_bind_as_ssbo(fdots_nor, binding_point++); + GPU_indexbuf_bind_as_ssbo(fdots_indices, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->extra_coarse_face_data, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_coarse_poly); @@ -1607,8 +1630,10 @@ void draw_subdiv_build_lines_buffer(const DRWSubdivCache *cache, GPUIndexBuf *li GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_LINES, nullptr); GPU_shader_bind(shader); - GPU_vertbuf_bind_as_ssbo(cache->edges_orig_index, 0); - GPU_indexbuf_bind_as_ssbo(lines_indices, 1); + int binding_point = 0; + GPU_vertbuf_bind_as_ssbo(cache->edges_orig_index, binding_point++); + GPU_indexbuf_bind_as_ssbo(lines_indices, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads); @@ -1648,9 +1673,11 @@ void draw_subdiv_build_edge_fac_buffer(const DRWSubdivCache *cache, GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_EDGE_FAC, defines); GPU_shader_bind(shader); - GPU_vertbuf_bind_as_ssbo(pos_nor, 0); - GPU_vertbuf_bind_as_ssbo(edge_idx, 1); - GPU_vertbuf_bind_as_ssbo(edge_fac, 2); + int binding_point = 0; + GPU_vertbuf_bind_as_ssbo(pos_nor, binding_point++); + GPU_vertbuf_bind_as_ssbo(edge_idx, binding_point++); + GPU_vertbuf_bind_as_ssbo(edge_fac, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads); @@ -1673,14 +1700,16 @@ void draw_subdiv_build_lnor_buffer(const DRWSubdivCache *cache, GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_LNOR, "#define SUBDIV_POLYGON_OFFSET\n"); GPU_shader_bind(shader); + int binding_point = 0; /* Inputs */ - GPU_vertbuf_bind_as_ssbo(pos_nor, 1); - GPU_vertbuf_bind_as_ssbo(cache->extra_coarse_face_data, 2); /* subdiv_polygon_offset is always at binding point 0 for each shader using it. */ - GPU_vertbuf_bind_as_ssbo(cache->subdiv_polygon_offset_buffer, 0); + GPU_vertbuf_bind_as_ssbo(cache->subdiv_polygon_offset_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(pos_nor, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->extra_coarse_face_data, binding_point++); /* Outputs */ - GPU_vertbuf_bind_as_ssbo(lnor, 3); + GPU_vertbuf_bind_as_ssbo(lnor, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads); @@ -1699,13 +1728,15 @@ void draw_subdiv_build_edituv_stretch_area_buffer(const DRWSubdivCache *cache, "#define SUBDIV_POLYGON_OFFSET\n"); GPU_shader_bind(shader); + int binding_point = 0; /* Inputs */ - GPU_vertbuf_bind_as_ssbo(coarse_data, 1); /* subdiv_polygon_offset is always at binding point 0 for each shader using it. */ - GPU_vertbuf_bind_as_ssbo(cache->subdiv_polygon_offset_buffer, 0); + GPU_vertbuf_bind_as_ssbo(cache->subdiv_polygon_offset_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(coarse_data, binding_point++); /* Outputs */ - GPU_vertbuf_bind_as_ssbo(subdiv_data, 2); + GPU_vertbuf_bind_as_ssbo(subdiv_data, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads); @@ -1725,12 +1756,14 @@ void draw_subdiv_build_edituv_stretch_angle_buffer(const DRWSubdivCache *cache, GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_UV_STRETCH_ANGLE, nullptr); GPU_shader_bind(shader); + int binding_point = 0; /* Inputs */ - GPU_vertbuf_bind_as_ssbo(pos_nor, 0); - GPU_vertbuf_bind_as_ssbo(uvs, 1); + GPU_vertbuf_bind_as_ssbo(pos_nor, binding_point++); + GPU_vertbuf_bind_as_ssbo(uvs, binding_point++); /* Outputs */ - GPU_vertbuf_bind_as_ssbo(stretch_angles, 2); + GPU_vertbuf_bind_as_ssbo(stretch_angles, binding_point++); + BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); drw_subdiv_compute_dispatch(cache, shader, uvs_offset, 0, cache->num_subdiv_quads); |