Merge branch 'blender-v4.0-release' into main
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)),
|
||||
|
||||
Reference in New Issue
Block a user