Merge branch 'blender-v4.0-release' into main

This commit is contained in:
Brecht Van Lommel
2023-11-09 18:24:05 +01:00
5 changed files with 86 additions and 66 deletions

View File

@@ -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;

View File

@@ -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<uint32_t> 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<uint32_t> prim_visibility;
/* instance_transform_matrix passes transform matrix of instances converted from Cycles Transform
* format to instanceFrames member of hiprtSceneBuildInput. */

View File

@@ -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,

View File

@@ -644,18 +644,6 @@ static bool fcu_test_selected(FCurve *fcu)
return false;
}
static void invert_snap(eSnapMode &snap_mode)
{
if (snap_mode & SCE_SNAP_TO_FRAME) {
snap_mode &= ~SCE_SNAP_TO_FRAME;
snap_mode |= SCE_SNAP_TO_SECOND;
}
else if (snap_mode & SCE_SNAP_TO_SECOND) {
snap_mode &= ~SCE_SNAP_TO_SECOND;
snap_mode |= SCE_SNAP_TO_FRAME;
}
}
/* This function is called on recalc_data to apply the transforms applied
* to the transdata on to the actual keyframe data
*/
@@ -668,10 +656,6 @@ static void flushTransGraphData(TransInfo *t)
eSnapMode snap_mode = t->tsnap.mode;
if (t->modifiers & MOD_SNAP_INVERT) {
invert_snap(snap_mode);
}
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
/* flush to 2d vector from internally used 3d vector */
for (a = 0,

View File

@@ -129,10 +129,28 @@ bool validSnap(const TransInfo *t)
void transform_snap_flag_from_modifiers_set(TransInfo *t)
{
if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA)) {
if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) {
/* Those space-types define their own invert behavior instead of toggling it on/off. */
return;
}
if (t->spacetype == SPACE_GRAPH) {
/* This is to stay consistent with the behavior from 3.6. */
if (t->modifiers & MOD_SNAP_INVERT) {
t->tsnap.mode |= SCE_SNAP_TO_INCREMENT;
}
else {
t->tsnap.mode &= ~SCE_SNAP_TO_INCREMENT;
}
/* In 3.6 when snapping was disabled, pressing the invert button would turn on snapping.
* But it wouldn't turn it off when it was enabled. */
if ((t->modifiers & MOD_SNAP) || (t->modifiers & MOD_SNAP_INVERT)) {
t->tsnap.flag |= SCE_SNAP;
}
else {
t->tsnap.flag &= ~SCE_SNAP;
}
return;
}
SET_FLAG_FROM_TEST(t->tsnap.flag,
(((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP) ||
((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP_INVERT)),