diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 7db9e7089fd..a64b22c4e76 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -605,6 +605,7 @@ set(GLSL_SRC engines/eevee_next/shaders/eevee_thickness_lib.glsl engines/eevee_next/shaders/eevee_transparency_lib.glsl engines/eevee_next/shaders/eevee_velocity_lib.glsl + engines/eevee_next/shaders/eevee_vertex_copy_comp.glsl engines/eevee_next/shaders/eevee_volume_integration_comp.glsl engines/eevee_next/shaders/eevee_volume_lib.glsl engines/eevee_next/shaders/eevee_volume_material_comp.glsl diff --git a/source/blender/draw/engines/eevee_next/eevee_defines.hh b/source/blender/draw/engines/eevee_next/eevee_defines.hh index a05e14e661f..38cc1c5d5ab 100644 --- a/source/blender/draw/engines/eevee_next/eevee_defines.hh +++ b/source/blender/draw/engines/eevee_next/eevee_defines.hh @@ -155,6 +155,9 @@ #define VOLUME_INTEGRATION_GROUP_SIZE 8 #define VOLUME_HIT_DEPTH_MAX 16 +/* Velocity. */ +#define VERTEX_COPY_GROUP_SIZE 64 + /* Resource bindings. */ /* Textures. */ diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.cc b/source/blender/draw/engines/eevee_next/eevee_shader.cc index 9008b8b1040..7060cd92de0 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader.cc +++ b/source/blender/draw/engines/eevee_next/eevee_shader.cc @@ -274,6 +274,8 @@ const char *ShaderModule::static_shader_create_info_name_get(eShaderType shader_ return "eevee_surfel_list_sort"; case SURFEL_RAY: return "eevee_surfel_ray"; + case VERTEX_COPY: + return "eevee_vertex_copy"; case VOLUME_INTEGRATION: return "eevee_volume_integration"; case VOLUME_OCCUPANCY_CONVERT: diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.hh b/source/blender/draw/engines/eevee_next/eevee_shader.hh index bf2d5eb1340..b94a152e3eb 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader.hh +++ b/source/blender/draw/engines/eevee_next/eevee_shader.hh @@ -137,6 +137,8 @@ enum eShaderType { SURFEL_LIST_SORT, SURFEL_RAY, + VERTEX_COPY, + VOLUME_INTEGRATION, VOLUME_OCCUPANCY_CONVERT, VOLUME_RESOLVE, diff --git a/source/blender/draw/engines/eevee_next/eevee_velocity.cc b/source/blender/draw/engines/eevee_next/eevee_velocity.cc index 6339ddb2bb5..ff46a6df978 100644 --- a/source/blender/draw/engines/eevee_next/eevee_velocity.cc +++ b/source/blender/draw/engines/eevee_next/eevee_velocity.cc @@ -259,13 +259,34 @@ void VelocityModule::geometry_steps_fill() * `tot_len * sizeof(float4)` is greater than max SSBO size. */ geometry_steps[step_]->resize(max_ii(16, dst_ofs)); + PassSimple copy_ps("Velocity Copy Pass"); + copy_ps.init(); + copy_ps.state_set(DRW_STATE_NO_DRAW); + copy_ps.shader_set(inst_.shaders.static_shader_get(VERTEX_COPY)); + copy_ps.bind_ssbo("out_buf", *geometry_steps[step_]); + for (VelocityGeometryData &geom : geometry_map.values()) { - GPU_storagebuf_copy_sub_from_vertbuf(*geometry_steps[step_], - geom.pos_buf, - geom.ofs * sizeof(float4), - 0, - geom.len * sizeof(float4)); + const GPUVertFormat *format = GPU_vertbuf_get_format(geom.pos_buf); + if (format->stride == 16) { + GPU_storagebuf_copy_sub_from_vertbuf(*geometry_steps[step_], + geom.pos_buf, + geom.ofs * sizeof(float4), + 0, + geom.len * sizeof(float4)); + } + else { + BLI_assert(format->stride % 4 == 0); + copy_ps.bind_ssbo("in_buf", geom.pos_buf); + copy_ps.push_constant("start_offset", geom.ofs); + copy_ps.push_constant("vertex_stride", int(format->stride / 4)); + copy_ps.push_constant("vertex_count", geom.len); + copy_ps.dispatch(int3(divide_ceil_u(geom.len, VERTEX_COPY_GROUP_SIZE), 1, 1)); + } } + + copy_ps.barrier(GPU_BARRIER_SHADER_STORAGE); + inst_.manager->submit(copy_ps); + /* Copy back the #VelocityGeometryIndex into #VelocityObjectData which are * indexed using persistent keys (unlike geometries which are indexed by volatile ID). */ for (VelocityObjectData &vel : velocity_map.values()) { diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_vertex_copy_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_vertex_copy_comp.glsl new file mode 100644 index 00000000000..68e9b4b688d --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_vertex_copy_comp.glsl @@ -0,0 +1,15 @@ +/* SPDX-FileCopyrightText: 2022-2023 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +void main() +{ + uint vertex = gl_GlobalInvocationID.x; + if (vertex >= vertex_count) { + return; + } + out_buf[start_offset + vertex] = vec4(in_buf[vertex * vertex_stride + 0], + in_buf[vertex * vertex_stride + 1], + in_buf[vertex * vertex_stride + 2], + 1.0); +} diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh index 09c82f38e95..ae8937e301d 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh @@ -38,4 +38,14 @@ GPU_SHADER_CREATE_INFO(eevee_velocity_geom) .fragment_out(0, Type::VEC4, "out_velocity") .additional_info("eevee_velocity_camera"); +GPU_SHADER_CREATE_INFO(eevee_vertex_copy) + .compute_source("eevee_vertex_copy_comp.glsl") + .local_group_size(VERTEX_COPY_GROUP_SIZE) + .storage_buf(0, Qualifier::READ, "float", "in_buf[]") + .storage_buf(1, Qualifier::WRITE, "vec4", "out_buf[]") + .push_constant(Type::INT, "start_offset") + .push_constant(Type::INT, "vertex_stride") + .push_constant(Type::INT, "vertex_count") + .do_static_compilation(true); + /** \} */