diff --git a/intern/cycles/device/hiprt/device_impl.cpp b/intern/cycles/device/hiprt/device_impl.cpp index f805359ae6d..db603cd725e 100644 --- a/intern/cycles/device/hiprt/device_impl.cpp +++ b/intern/cycles/device/hiprt/device_impl.cpp @@ -65,7 +65,7 @@ HIPRTDevice::HIPRTDevice(const DeviceInfo &info, Stats &stats, Profiler &profile functions_table(NULL), scratch_buffer_size(0), scratch_buffer(this, "scratch_buffer", MEM_DEVICE_ONLY), - visibility(this, "visibility", MEM_READ_ONLY), + prim_visibility(this, "prim_visibility", MEM_GLOBAL), instance_transform_matrix(this, "instance_transform_matrix", MEM_READ_ONLY), transform_headers(this, "transform_headers", MEM_READ_ONLY), user_instance_id(this, "user_instance_id", MEM_GLOBAL), @@ -104,7 +104,7 @@ HIPRTDevice::~HIPRTDevice() { HIPContextScope scope(this); user_instance_id.free(); - visibility.free(); + prim_visibility.free(); hiprt_blas_ptr.free(); blas_ptr.free(); instance_transform_matrix.free(); @@ -388,54 +388,72 @@ hiprtGeometryBuildInput HIPRTDevice::prepare_triangle_blas(BVHHIPRT *bvh, Mesh * hiprtGeometryBuildInput geom_input; geom_input.geomType = Triangle; - if (mesh->has_motion_blur() && - !(bvh->params.num_motion_triangle_steps == 0 || bvh->params.use_spatial_split)) - { + if (mesh->has_motion_blur()) { const Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + const float3 *vert_steps = attr_mP->data_float3(); + const size_t num_verts = mesh->get_verts().size(); + const size_t num_steps = mesh->get_motion_steps(); const size_t num_triangles = mesh->num_triangles(); - - const int num_bvh_steps = bvh->params.num_motion_triangle_steps * 2 + 1; - const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1); - + const float3 *verts = mesh->get_verts().data(); int num_bounds = 0; - bvh->custom_primitive_bound.alloc(num_triangles * num_bvh_steps); - for (uint j = 0; j < num_triangles; j++) { - Mesh::Triangle t = mesh->get_triangle(j); - const float3 *verts = mesh->get_verts().data(); + if (bvh->params.num_motion_triangle_steps == 0 || bvh->params.use_spatial_split) { + bvh->custom_primitive_bound.alloc(num_triangles); + bvh->custom_prim_info.resize(num_triangles); + for (uint j = 0; j < num_triangles; j++) { + Mesh::Triangle t = mesh->get_triangle(j); + BoundBox bounds = BoundBox::empty; + t.bounds_grow(verts, bounds); + for (size_t step = 0; step < num_steps - 1; step++) { + t.bounds_grow(vert_steps + step * num_verts, bounds); + } - const size_t num_verts = mesh->get_verts().size(); - const size_t num_steps = mesh->get_motion_steps(); - const float3 *vert_steps = attr_mP->data_float3(); - - float3 prev_verts[3]; - t.motion_verts(verts, vert_steps, num_verts, num_steps, 0.0f, prev_verts); - BoundBox prev_bounds = BoundBox::empty; - prev_bounds.grow(prev_verts[0]); - prev_bounds.grow(prev_verts[1]); - prev_bounds.grow(prev_verts[2]); - - for (int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) { - const float curr_time = (float)(bvh_step)*num_bvh_steps_inv_1; - float3 curr_verts[3]; - t.motion_verts(verts, vert_steps, num_verts, num_steps, curr_time, curr_verts); - BoundBox curr_bounds = BoundBox::empty; - curr_bounds.grow(curr_verts[0]); - curr_bounds.grow(curr_verts[1]); - curr_bounds.grow(curr_verts[2]); - BoundBox bounds = prev_bounds; - bounds.grow(curr_bounds); if (bounds.valid()) { - const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1; bvh->custom_primitive_bound[num_bounds] = bounds; bvh->custom_prim_info[num_bounds].x = j; bvh->custom_prim_info[num_bounds].y = mesh->primitive_type(); - bvh->prims_time[num_bounds].x = curr_time; - bvh->prims_time[num_bounds].y = prev_time; num_bounds++; } - prev_bounds = curr_bounds; + } + } + else { + const int num_bvh_steps = bvh->params.num_motion_triangle_steps * 2 + 1; + const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1); + + bvh->custom_primitive_bound.alloc(num_triangles * num_bvh_steps); + bvh->custom_prim_info.resize(num_triangles * num_bvh_steps); + + for (uint j = 0; j < num_triangles; j++) { + Mesh::Triangle t = mesh->get_triangle(j); + float3 prev_verts[3]; + t.motion_verts(verts, vert_steps, num_verts, num_steps, 0.0f, prev_verts); + BoundBox prev_bounds = BoundBox::empty; + prev_bounds.grow(prev_verts[0]); + prev_bounds.grow(prev_verts[1]); + prev_bounds.grow(prev_verts[2]); + + for (int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) { + const float curr_time = (float)(bvh_step)*num_bvh_steps_inv_1; + float3 curr_verts[3]; + t.motion_verts(verts, vert_steps, num_verts, num_steps, curr_time, curr_verts); + BoundBox curr_bounds = BoundBox::empty; + curr_bounds.grow(curr_verts[0]); + curr_bounds.grow(curr_verts[1]); + curr_bounds.grow(curr_verts[2]); + BoundBox bounds = prev_bounds; + bounds.grow(curr_bounds); + if (bounds.valid()) { + const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1; + bvh->custom_primitive_bound[num_bounds] = bounds; + bvh->custom_prim_info[num_bounds].x = j; + bvh->custom_prim_info[num_bounds].y = mesh->primitive_type(); + bvh->prims_time[num_bounds].x = curr_time; + bvh->prims_time[num_bounds].y = prev_time; + num_bounds++; + } + prev_bounds = curr_bounds; + } } } @@ -449,7 +467,6 @@ hiprtGeometryBuildInput HIPRTDevice::prepare_triangle_blas(BVHHIPRT *bvh, Mesh * geom_input.geomType = Motion_Triangle; } else { - size_t triangle_size = mesh->get_triangles().size(); void *triangle_data = mesh->get_triangles().data(); @@ -480,6 +497,7 @@ hiprtGeometryBuildInput HIPRTDevice::prepare_triangle_blas(BVHHIPRT *bvh, Mesh * geom_input.type = hiprtPrimitiveTypeTriangleMesh; geom_input.triangleMesh.primitive = &(bvh->triangle_mesh); } + return geom_input; } @@ -800,7 +818,7 @@ hiprtScene HIPRTDevice::build_tlas(BVHHIPRT *bvh, size_t num_object = objects.size(); user_instance_id.alloc(num_object); - visibility.alloc(num_object); + prim_visibility.alloc(num_object); hiprt_blas_ptr.alloc(num_object); blas_ptr.alloc(num_object); transform_headers.alloc(num_object); @@ -913,7 +931,7 @@ hiprtScene HIPRTDevice::build_tlas(BVHHIPRT *bvh, transform_headers[num_instances] = current_header; user_instance_id[num_instances] = blender_instance_id; - visibility[num_instances] = mask; + prim_visibility[num_instances] = mask; hiprt_blas_ptr[num_instances] = (uint64_t)hiprt_geom_current; num_instances++; } @@ -928,7 +946,7 @@ hiprtScene HIPRTDevice::build_tlas(BVHHIPRT *bvh, scene_input_ptr.frameType = hiprtFrameTypeMatrix; user_instance_id.copy_to_device(); - visibility.copy_to_device(); + prim_visibility.copy_to_device(); hiprt_blas_ptr.copy_to_device(); blas_ptr.copy_to_device(); transform_headers.copy_to_device(); @@ -942,7 +960,7 @@ hiprtScene HIPRTDevice::build_tlas(BVHHIPRT *bvh, instance_transform_matrix.host_pointer = 0; } - scene_input_ptr.instanceMasks = (void *)visibility.device_pointer; + scene_input_ptr.instanceMasks = (void *)prim_visibility.device_pointer; scene_input_ptr.instanceGeometries = (void *)hiprt_blas_ptr.device_pointer; scene_input_ptr.instanceTransformHeaders = (void *)transform_headers.device_pointer; scene_input_ptr.instanceFrames = (void *)instance_transform_matrix.device_pointer; diff --git a/intern/cycles/device/hiprt/device_impl.h b/intern/cycles/device/hiprt/device_impl.h index d7e6dbb0c20..51970dc8e8a 100644 --- a/intern/cycles/device/hiprt/device_impl.h +++ b/intern/cycles/device/hiprt/device_impl.h @@ -82,7 +82,11 @@ class HIPRTDevice : public HIPDevice { * are defined on the GPU side as members of KernelParamsHIPRT struct the host memory is copied * to GPU through const_copy_to() function. */ - device_vector visibility; + /* Originally, visibility was only passed to HIP RT but after a bug report it was noted it was + * required for custom primitives (i.e., motion triangles). This buffer, however, has visibility + * per object not per primitive so the same buffer as the one that is passed to HIP RT can be + * used. */ + device_vector prim_visibility; /* instance_transform_matrix passes transform matrix of instances converted from Cycles Transform * format to instanceFrames member of hiprtSceneBuildInput. */ diff --git a/intern/cycles/kernel/device/hiprt/common.h b/intern/cycles/kernel/device/hiprt/common.h index cd691643ee4..af6ea295858 100644 --- a/intern/cycles/kernel/device/hiprt/common.h +++ b/intern/cycles/kernel/device/hiprt/common.h @@ -177,7 +177,6 @@ ccl_device_inline bool motion_triangle_custom_intersect(const hiprtRay &ray, void *payload, hiprtHit &hit) { -# ifdef MOTION_BLUR RayPayload *local_payload = (RayPayload *)payload; KernelGlobals kg = local_payload->kg; int object_id = kernel_data_fetch(user_instance_id, hit.instanceID); @@ -202,7 +201,7 @@ ccl_device_inline bool motion_triangle_custom_intersect(const hiprtRay &ray, local_payload->visibility, object_id, prim_id_global, - prim_id_local); + hit.instanceID); if (b_hit) { hit.uv.x = isect.u; @@ -212,9 +211,6 @@ ccl_device_inline bool motion_triangle_custom_intersect(const hiprtRay &ray, local_payload->prim_type = isect.type; } return b_hit; -# else - return false; -# endif } ccl_device_inline bool motion_triangle_custom_local_intersect(const hiprtRay &ray,