[Bf-blender-cvs] [b0e2e454967] master: Cycles: Enable MetalRT pointclouds & other fixes
Michael Jones
noreply at git.blender.org
Mon Nov 14 17:39:20 CET 2022
Commit: b0e2e4549676817f23a6122aeeefc0d07bc62a42
Author: Michael Jones
Date: Mon Nov 14 15:35:47 2022 +0000
Branches: master
https://developer.blender.org/rBb0e2e4549676817f23a6122aeeefc0d07bc62a42
Cycles: Enable MetalRT pointclouds & other fixes
Code authored by Marco Giordano.
This fixes pointcloud rendering on MetalRT and some other subtle MetalRT bugs:
- Incorrect kernel hashing
- Missing specialisation constants
- Incorrect visibility filtering
- Missing null pointer check
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D16499
===================================================================
M intern/cycles/device/metal/bvh.mm
M intern/cycles/device/metal/device_impl.mm
M intern/cycles/device/metal/kernel.h
M intern/cycles/device/metal/kernel.mm
M intern/cycles/kernel/data_template.h
M intern/cycles/kernel/device/metal/bvh.h
M intern/cycles/kernel/device/metal/kernel.metal
M intern/cycles/scene/object.cpp
===================================================================
diff --git a/intern/cycles/device/metal/bvh.mm b/intern/cycles/device/metal/bvh.mm
index 09c4ace081e..a7fd64d3c98 100644
--- a/intern/cycles/device/metal/bvh.mm
+++ b/intern/cycles/device/metal/bvh.mm
@@ -496,7 +496,7 @@ bool BVHMetal::build_BLAS_pointcloud(Progress &progress,
num_motion_steps = pointcloud->get_motion_steps();
}
- const size_t num_aabbs = num_motion_steps;
+ const size_t num_aabbs = num_motion_steps * num_points;
MTLResourceOptions storage_mode;
if (device.hasUnifiedMemory) {
@@ -757,6 +757,10 @@ bool BVHMetal::build_TLAS(Progress &progress,
}
}
+ if (num_instances == 0) {
+ return false;
+ }
+
/*------------------------------------------------*/
BVH_status("Building TLAS | %7d instances", (int)num_instances);
/*------------------------------------------------*/
diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm
index 6f1042b1e55..604abc2be1a 100644
--- a/intern/cycles/device/metal/device_impl.mm
+++ b/intern/cycles/device/metal/device_impl.mm
@@ -307,6 +307,9 @@ void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_feat
MD5Hash md5;
md5.append(baked_constants);
md5.append(source);
+ if (use_metalrt) {
+ md5.append(std::to_string(kernel_features & METALRT_FEATURE_MASK));
+ }
source_md5[pso_type] = md5.get_hex();
}
diff --git a/intern/cycles/device/metal/kernel.h b/intern/cycles/device/metal/kernel.h
index 11393f8b7e1..3e88d2daea7 100644
--- a/intern/cycles/device/metal/kernel.h
+++ b/intern/cycles/device/metal/kernel.h
@@ -54,6 +54,10 @@ enum MetalPipelineType {
PSO_NUM
};
+# define METALRT_FEATURE_MASK \
+ (KERNEL_FEATURE_HAIR | KERNEL_FEATURE_HAIR_THICK | KERNEL_FEATURE_POINTCLOUD | \
+ KERNEL_FEATURE_OBJECT_MOTION)
+
const char *kernel_type_as_string(MetalPipelineType pso_type);
struct MetalKernelPipeline {
@@ -67,9 +71,7 @@ struct MetalKernelPipeline {
KernelData kernel_data_;
bool use_metalrt;
- bool metalrt_hair;
- bool metalrt_hair_thick;
- bool metalrt_pointcloud;
+ uint32_t metalrt_features = 0;
int threads_per_threadgroup;
diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm
index 35cf832c537..86e5a78692e 100644
--- a/intern/cycles/device/metal/kernel.mm
+++ b/intern/cycles/device/metal/kernel.mm
@@ -274,12 +274,9 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel,
/* metalrt options */
request.pipeline->use_metalrt = device->use_metalrt;
- request.pipeline->metalrt_hair = device->use_metalrt &&
- (device->kernel_features & KERNEL_FEATURE_HAIR);
- request.pipeline->metalrt_hair_thick = device->use_metalrt &&
- (device->kernel_features & KERNEL_FEATURE_HAIR_THICK);
- request.pipeline->metalrt_pointcloud = device->use_metalrt &&
- (device->kernel_features & KERNEL_FEATURE_POINTCLOUD);
+ request.pipeline->metalrt_features = device->use_metalrt ?
+ (device->kernel_features & METALRT_FEATURE_MASK) :
+ 0;
{
thread_scoped_lock lock(cache_mutex);
@@ -316,9 +313,13 @@ MetalKernelPipeline *ShaderCache::get_best_pipeline(DeviceKernel kernel, const M
/* metalrt options */
bool use_metalrt = device->use_metalrt;
- bool metalrt_hair = use_metalrt && (device->kernel_features & KERNEL_FEATURE_HAIR);
- bool metalrt_hair_thick = use_metalrt && (device->kernel_features & KERNEL_FEATURE_HAIR_THICK);
- bool metalrt_pointcloud = use_metalrt && (device->kernel_features & KERNEL_FEATURE_POINTCLOUD);
+ bool device_metalrt_hair = use_metalrt && device->kernel_features & KERNEL_FEATURE_HAIR;
+ bool device_metalrt_hair_thick = use_metalrt &&
+ device->kernel_features & KERNEL_FEATURE_HAIR_THICK;
+ bool device_metalrt_pointcloud = use_metalrt &&
+ device->kernel_features & KERNEL_FEATURE_POINTCLOUD;
+ bool device_metalrt_motion = use_metalrt &&
+ device->kernel_features & KERNEL_FEATURE_OBJECT_MOTION;
MetalKernelPipeline *best_pipeline = nullptr;
for (auto &pipeline : collection) {
@@ -327,9 +328,16 @@ MetalKernelPipeline *ShaderCache::get_best_pipeline(DeviceKernel kernel, const M
continue;
}
- if (pipeline->use_metalrt != use_metalrt || pipeline->metalrt_hair != metalrt_hair ||
- pipeline->metalrt_hair_thick != metalrt_hair_thick ||
- pipeline->metalrt_pointcloud != metalrt_pointcloud) {
+ bool pipeline_metalrt_hair = pipeline->metalrt_features & KERNEL_FEATURE_HAIR;
+ bool pipeline_metalrt_hair_thick = pipeline->metalrt_features & KERNEL_FEATURE_HAIR_THICK;
+ bool pipeline_metalrt_pointcloud = pipeline->metalrt_features & KERNEL_FEATURE_POINTCLOUD;
+ bool pipeline_metalrt_motion = use_metalrt &&
+ pipeline->metalrt_features & KERNEL_FEATURE_OBJECT_MOTION;
+
+ if (pipeline->use_metalrt != use_metalrt || pipeline_metalrt_hair != device_metalrt_hair ||
+ pipeline_metalrt_hair_thick != device_metalrt_hair_thick ||
+ pipeline_metalrt_pointcloud != device_metalrt_pointcloud ||
+ pipeline_metalrt_motion != device_metalrt_motion) {
/* wrong combination of metalrt options */
continue;
}
@@ -400,6 +408,8 @@ static MTLFunctionConstantValues *GetConstantValues(KernelData const *data = nul
if (!data) {
data = &zero_data;
}
+ int zero_int = 0;
+ [constant_values setConstantValue:&zero_int type:MTLDataType_int atIndex:Kernel_DummyConstant];
# define KERNEL_STRUCT_MEMBER(parent, _type, name) \
[constant_values setConstantValue:&data->parent.name \
@@ -423,10 +433,7 @@ void MetalKernelPipeline::compile()
MTLFunctionDescriptor *func_desc = [MTLIntersectionFunctionDescriptor functionDescriptor];
func_desc.name = entryPoint;
- if (pso_type == PSO_SPECIALIZED_SHADE) {
- func_desc.constantValues = GetConstantValues(&kernel_data_);
- }
- else if (pso_type == PSO_SPECIALIZED_INTERSECT) {
+ if (pso_type != PSO_GENERIC) {
func_desc.constantValues = GetConstantValues(&kernel_data_);
}
else {
@@ -471,6 +478,13 @@ void MetalKernelPipeline::compile()
const char *function_name = function_names[i];
desc.name = [@(function_name) copy];
+ if (pso_type != PSO_GENERIC) {
+ desc.constantValues = GetConstantValues(&kernel_data_);
+ }
+ else {
+ desc.constantValues = GetConstantValues();
+ }
+
NSError *error = NULL;
rt_intersection_function[i] = [mtlLibrary newFunctionWithDescriptor:desc error:&error];
@@ -491,6 +505,10 @@ void MetalKernelPipeline::compile()
NSArray *table_functions[METALRT_TABLE_NUM] = {nil};
NSArray *linked_functions = nil;
+ bool metalrt_hair = use_metalrt && (metalrt_features & KERNEL_FEATURE_HAIR);
+ bool metalrt_hair_thick = use_metalrt && (metalrt_features & KERNEL_FEATURE_HAIR_THICK);
+ bool metalrt_pointcloud = use_metalrt && (metalrt_features & KERNEL_FEATURE_POINTCLOUD);
+
if (use_metalrt) {
id<MTLFunction> curve_intersect_default = nil;
id<MTLFunction> curve_intersect_shadow = nil;
@@ -735,7 +753,8 @@ void MetalKernelPipeline::compile()
newIntersectionFunctionTableWithDescriptor:ift_desc];
/* Finally write the function handles into this pipeline's table */
- for (int i = 0; i < 2; i++) {
+ int size = (int)[table_functions[table] count];
+ for (int i = 0; i < size; i++) {
id<MTLFunctionHandle> handle = [pipeline
functionHandleWithFunction:table_functions[table][i]];
[intersection_func_table[table] setFunction:handle atIndex:i];
diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h
index 1e9e25f2f9d..6b89de13797 100644
--- a/intern/cycles/kernel/data_template.h
+++ b/intern/cycles/kernel/data_template.h
@@ -49,11 +49,11 @@ KERNEL_STRUCT_BEGIN(KernelBVH, bvh)
KERNEL_STRUCT_MEMBER(bvh, int, root)
KERNEL_STRUCT_MEMBER(bvh, int, have_motion)
KERNEL_STRUCT_MEMBER(bvh, int, have_curves)
+KERNEL_STRUCT_MEMBER(bvh, int, have_points)
+KERNEL_STRUCT_MEMBER(bvh, int, have_volumes)
KERNEL_STRUCT_MEMBER(bvh, int, bvh_layout)
KERNEL_STRUCT_MEMBER(bvh, int, use_bvh_steps)
KERNEL_STRUCT_MEMBER(bvh, int, curve_subdivisions)
-KERNEL_STRUCT_MEMBER(bvh, int, pad1)
-KERNEL_STRUCT_MEMBER(bvh, int, pad2)
KERNEL_STRUCT_END(KernelBVH)
/* Film. */
diff --git a/intern/cycles/kernel/device/metal/bvh.h b/intern/cycles/kernel/device/metal/bvh.h
index 03faa3f020f..2ea2d9c2601 100644
--- a/intern/cycles/kernel/device/metal/bvh.h
+++ b/intern/cycles/kernel/device/metal/bvh.h
@@ -79,7 +79,8 @@ ccl_device_intersect bool scene_intersect(KernelGlobals kg,
metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
metalrt_intersector_type metalrt_intersect;
- if (!kernel_data.bvh.have_curves) {
+ bool triangle_only = !kernel_data.bvh.have_curves && !kernel_data.bvh.have_points;
+ if (triangle_only) {
metalrt_intersect.assume_geometry_type(metal::raytracing::geometry_type::triangle);
}
@@ -177,7 +178,9 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
metalrt_intersector_type metalrt_intersect;
metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
- if (!kernel_data.bvh.have_curves) {
+
+ bool triangle_only = !kernel_data.bvh.have_curves && !kernel_data.bvh.have_points;
+ if (triangle_only) {
metalrt_intersect.assume_geometry_type(metal::raytracing::geometry_type::triangle);
}
@@ -205,7 +208,9 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
if (lcg_state) {
*lcg_state = payload.lcg_state;
}
- *local_isect = payload.local_isect;
+ if (local_isect) {
+ *local_isect = payload.local_isect;
+ }
return payload.result;
}
@@ -240,7 +245,9 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg,
metalrt_intersector_type metalrt_intersect;
metalrt_in
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list