Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/device/optix/device_impl.cpp
| Show First 20 Lines • Show All 202 Lines • ▼ Show 20 Lines | bool OptiXDevice::load_kernels(const uint kernel_features) | ||||
| module_options.maxRegisterCount = 0; /* Do not set an explicit register limit. */ | module_options.maxRegisterCount = 0; /* Do not set an explicit register limit. */ | ||||
| if (DebugFlags().optix.use_debug) { | if (DebugFlags().optix.use_debug) { | ||||
| module_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_0; | module_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_0; | ||||
| module_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL; | module_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL; | ||||
| } | } | ||||
| else { | else { | ||||
| module_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_3; | module_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_3; | ||||
| module_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_LINEINFO; | module_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_NONE; | ||||
| } | } | ||||
| module_options.boundValues = nullptr; | module_options.boundValues = nullptr; | ||||
| module_options.numBoundValues = 0; | module_options.numBoundValues = 0; | ||||
| # if OPTIX_ABI_VERSION >= 55 | |||||
| module_options.payloadTypes = nullptr; | |||||
| module_options.numPayloadTypes = 0; | |||||
| # endif | |||||
| OptixPipelineCompileOptions pipeline_options = {}; | OptixPipelineCompileOptions pipeline_options = {}; | ||||
| /* Default to no motion blur and two-level graph, since it is the fastest option. */ | /* Default to no motion blur and two-level graph, since it is the fastest option. */ | ||||
| pipeline_options.usesMotionBlur = false; | pipeline_options.usesMotionBlur = false; | ||||
| pipeline_options.traversableGraphFlags = | pipeline_options.traversableGraphFlags = | ||||
| OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING; | OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING; | ||||
| pipeline_options.numPayloadValues = 6; | pipeline_options.numPayloadValues = 6; | ||||
| pipeline_options.numAttributeValues = 2; /* u, v */ | pipeline_options.numAttributeValues = 2; /* u, v */ | ||||
| pipeline_options.exceptionFlags = OPTIX_EXCEPTION_FLAG_NONE; | pipeline_options.exceptionFlags = OPTIX_EXCEPTION_FLAG_NONE; | ||||
| pipeline_options.pipelineLaunchParamsVariableName = "__params"; /* See globals.h */ | pipeline_options.pipelineLaunchParamsVariableName = "__params"; /* See globals.h */ | ||||
| pipeline_options.usesPrimitiveTypeFlags = OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE; | pipeline_options.usesPrimitiveTypeFlags = OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE; | ||||
| if (kernel_features & KERNEL_FEATURE_HAIR) { | if (kernel_features & KERNEL_FEATURE_HAIR) { | ||||
| if (kernel_features & KERNEL_FEATURE_HAIR_THICK) { | if (kernel_features & KERNEL_FEATURE_HAIR_THICK) { | ||||
| # if OPTIX_ABI_VERSION >= 55 | |||||
| pipeline_options.usesPrimitiveTypeFlags |= OPTIX_PRIMITIVE_TYPE_FLAGS_ROUND_CATMULLROM; | |||||
| # else | |||||
| pipeline_options.usesPrimitiveTypeFlags |= OPTIX_PRIMITIVE_TYPE_FLAGS_ROUND_CUBIC_BSPLINE; | pipeline_options.usesPrimitiveTypeFlags |= OPTIX_PRIMITIVE_TYPE_FLAGS_ROUND_CUBIC_BSPLINE; | ||||
| # endif | |||||
| } | } | ||||
| else | else | ||||
| pipeline_options.usesPrimitiveTypeFlags |= OPTIX_PRIMITIVE_TYPE_FLAGS_CUSTOM; | pipeline_options.usesPrimitiveTypeFlags |= OPTIX_PRIMITIVE_TYPE_FLAGS_CUSTOM; | ||||
| } | } | ||||
| /* Keep track of whether motion blur is enabled, so to enable/disable motion in BVH builds | /* Keep track of whether motion blur is enabled, so to enable/disable motion in BVH builds | ||||
| * This is necessary since objects may be reported to have motion if the Vector pass is | * This is necessary since objects may be reported to have motion if the Vector pass is | ||||
| * active, but may still need to be rendered without motion blur if that isn't active as well. */ | * active, but may still need to be rendered without motion blur if that isn't active as well. */ | ||||
| ▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | # endif | ||||
| group_descs[PG_HITV].hitgroup.entryFunctionNameCH = "__closesthit__kernel_optix_hit"; | group_descs[PG_HITV].hitgroup.entryFunctionNameCH = "__closesthit__kernel_optix_hit"; | ||||
| group_descs[PG_HITV].hitgroup.moduleAH = optix_module; | group_descs[PG_HITV].hitgroup.moduleAH = optix_module; | ||||
| group_descs[PG_HITV].hitgroup.entryFunctionNameAH = "__anyhit__kernel_optix_volume_test"; | group_descs[PG_HITV].hitgroup.entryFunctionNameAH = "__anyhit__kernel_optix_volume_test"; | ||||
| if (kernel_features & KERNEL_FEATURE_HAIR) { | if (kernel_features & KERNEL_FEATURE_HAIR) { | ||||
| if (kernel_features & KERNEL_FEATURE_HAIR_THICK) { | if (kernel_features & KERNEL_FEATURE_HAIR_THICK) { | ||||
| /* Built-in thick curve intersection. */ | /* Built-in thick curve intersection. */ | ||||
| OptixBuiltinISOptions builtin_options = {}; | OptixBuiltinISOptions builtin_options = {}; | ||||
| # if OPTIX_ABI_VERSION >= 55 | |||||
| builtin_options.builtinISModuleType = OPTIX_PRIMITIVE_TYPE_ROUND_CATMULLROM; | |||||
| builtin_options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_TRACE; | |||||
| builtin_options.curveEndcapFlags = OPTIX_CURVE_ENDCAP_DEFAULT; /* Disable endcaps. */ | |||||
| # else | |||||
| builtin_options.builtinISModuleType = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE; | builtin_options.builtinISModuleType = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE; | ||||
| # endif | |||||
| builtin_options.usesMotionBlur = false; | builtin_options.usesMotionBlur = false; | ||||
| optix_assert(optixBuiltinISModuleGet( | optix_assert(optixBuiltinISModuleGet( | ||||
| context, &module_options, &pipeline_options, &builtin_options, &builtin_modules[0])); | context, &module_options, &pipeline_options, &builtin_options, &builtin_modules[0])); | ||||
| group_descs[PG_HITD].hitgroup.moduleIS = builtin_modules[0]; | group_descs[PG_HITD].hitgroup.moduleIS = builtin_modules[0]; | ||||
| group_descs[PG_HITD].hitgroup.entryFunctionNameIS = nullptr; | group_descs[PG_HITD].hitgroup.entryFunctionNameIS = nullptr; | ||||
| group_descs[PG_HITS].hitgroup.moduleIS = builtin_modules[0]; | group_descs[PG_HITS].hitgroup.moduleIS = builtin_modules[0]; | ||||
| ▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | # endif | ||||
| OptixPipelineLinkOptions link_options = {}; | OptixPipelineLinkOptions link_options = {}; | ||||
| link_options.maxTraceDepth = 1; | link_options.maxTraceDepth = 1; | ||||
| if (DebugFlags().optix.use_debug) { | if (DebugFlags().optix.use_debug) { | ||||
| link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL; | link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL; | ||||
| } | } | ||||
| else { | else { | ||||
| link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_LINEINFO; | link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_NONE; | ||||
| } | } | ||||
| if (kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) { | if (kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) { | ||||
| /* Create shader raytracing pipeline. */ | /* Create shader raytracing pipeline. */ | ||||
| vector<OptixProgramGroup> pipeline_groups; | vector<OptixProgramGroup> pipeline_groups; | ||||
| pipeline_groups.reserve(NUM_PROGRAM_GROUPS); | pipeline_groups.reserve(NUM_PROGRAM_GROUPS); | ||||
| pipeline_groups.push_back(groups[PG_RGEN_SHADE_SURFACE_RAYTRACE]); | pipeline_groups.push_back(groups[PG_RGEN_SHADE_SURFACE_RAYTRACE]); | ||||
| pipeline_groups.push_back(groups[PG_MISS]); | pipeline_groups.push_back(groups[PG_MISS]); | ||||
| ▲ Show 20 Lines • Show All 604 Lines • ▼ Show 20 Lines | bool OptiXDevice::build_optix_bvh(BVHOptiX *bvh, | ||||
| /* Allocate required output buffers. */ | /* Allocate required output buffers. */ | ||||
| device_only_memory<char> temp_mem(this, "optix temp as build mem"); | device_only_memory<char> temp_mem(this, "optix temp as build mem"); | ||||
| temp_mem.alloc_to_device(align_up(sizes.tempSizeInBytes, 8) + 8); | temp_mem.alloc_to_device(align_up(sizes.tempSizeInBytes, 8) + 8); | ||||
| if (!temp_mem.device_pointer) { | if (!temp_mem.device_pointer) { | ||||
| /* Make sure temporary memory allocation succeeded. */ | /* Make sure temporary memory allocation succeeded. */ | ||||
| return false; | return false; | ||||
| } | } | ||||
| device_only_memory<char> &out_data = bvh->as_data; | device_only_memory<char> &out_data = *bvh->as_data; | ||||
| if (operation == OPTIX_BUILD_OPERATION_BUILD) { | if (operation == OPTIX_BUILD_OPERATION_BUILD) { | ||||
| assert(out_data.device == this); | assert(out_data.device == this); | ||||
| out_data.alloc_to_device(sizes.outputSizeInBytes); | out_data.alloc_to_device(sizes.outputSizeInBytes); | ||||
| if (!out_data.device_pointer) { | if (!out_data.device_pointer) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| ▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | if (!bvh->params.top_level) { | ||||
| /* Refit is only possible in viewport for now (because AS is built with | /* Refit is only possible in viewport for now (because AS is built with | ||||
| * OPTIX_BUILD_FLAG_ALLOW_UPDATE only there, see above). */ | * OPTIX_BUILD_FLAG_ALLOW_UPDATE only there, see above). */ | ||||
| OptixBuildOperation operation = OPTIX_BUILD_OPERATION_BUILD; | OptixBuildOperation operation = OPTIX_BUILD_OPERATION_BUILD; | ||||
| if (refit && !use_fast_trace_bvh) { | if (refit && !use_fast_trace_bvh) { | ||||
| assert(bvh_optix->traversable_handle != 0); | assert(bvh_optix->traversable_handle != 0); | ||||
| operation = OPTIX_BUILD_OPERATION_UPDATE; | operation = OPTIX_BUILD_OPERATION_UPDATE; | ||||
| } | } | ||||
| else { | else { | ||||
| bvh_optix->as_data.free(); | bvh_optix->as_data->free(); | ||||
| bvh_optix->traversable_handle = 0; | bvh_optix->traversable_handle = 0; | ||||
| } | } | ||||
| /* Build bottom level acceleration structures (BLAS). */ | /* Build bottom level acceleration structures (BLAS). */ | ||||
| Geometry *const geom = bvh->geometry[0]; | Geometry *const geom = bvh->geometry[0]; | ||||
| if (geom->geometry_type == Geometry::HAIR) { | if (geom->geometry_type == Geometry::HAIR) { | ||||
| /* Build BLAS for curve primitives. */ | /* Build BLAS for curve primitives. */ | ||||
| Hair *const hair = static_cast<Hair *const>(geom); | Hair *const hair = static_cast<Hair *const>(geom); | ||||
| Show All 38 Lines | if (geom->geometry_type == Geometry::HAIR) { | ||||
| for (int segment = 0; segment < curve.num_segments(); ++segment, ++i) { | for (int segment = 0; segment < curve.num_segments(); ++segment, ++i) { | ||||
| if (hair->curve_shape == CURVE_THICK) { | if (hair->curve_shape == CURVE_THICK) { | ||||
| int k0 = curve.first_key + segment; | int k0 = curve.first_key + segment; | ||||
| int k1 = k0 + 1; | int k1 = k0 + 1; | ||||
| int ka = max(k0 - 1, curve.first_key); | int ka = max(k0 - 1, curve.first_key); | ||||
| int kb = min(k1 + 1, curve.first_key + curve.num_keys - 1); | int kb = min(k1 + 1, curve.first_key + curve.num_keys - 1); | ||||
| index_data[i] = i * 4; | |||||
| float4 *const v = vertex_data.data() + step * num_vertices + index_data[i]; | |||||
| # if OPTIX_ABI_VERSION >= 55 | |||||
| v[0] = make_float4(keys[ka].x, keys[ka].y, keys[ka].z, curve_radius[ka]); | |||||
| v[1] = make_float4(keys[k0].x, keys[k0].y, keys[k0].z, curve_radius[k0]); | |||||
| v[2] = make_float4(keys[k1].x, keys[k1].y, keys[k1].z, curve_radius[k1]); | |||||
| v[3] = make_float4(keys[kb].x, keys[kb].y, keys[kb].z, curve_radius[kb]); | |||||
| # else | |||||
| const float4 px = make_float4(keys[ka].x, keys[k0].x, keys[k1].x, keys[kb].x); | const float4 px = make_float4(keys[ka].x, keys[k0].x, keys[k1].x, keys[kb].x); | ||||
| const float4 py = make_float4(keys[ka].y, keys[k0].y, keys[k1].y, keys[kb].y); | const float4 py = make_float4(keys[ka].y, keys[k0].y, keys[k1].y, keys[kb].y); | ||||
| const float4 pz = make_float4(keys[ka].z, keys[k0].z, keys[k1].z, keys[kb].z); | const float4 pz = make_float4(keys[ka].z, keys[k0].z, keys[k1].z, keys[kb].z); | ||||
| const float4 pw = make_float4( | const float4 pw = make_float4( | ||||
| curve_radius[ka], curve_radius[k0], curve_radius[k1], curve_radius[kb]); | curve_radius[ka], curve_radius[k0], curve_radius[k1], curve_radius[kb]); | ||||
| /* Convert Catmull-Rom data to Bezier spline. */ | /* Convert Catmull-Rom data to Bezier spline. */ | ||||
| static const float4 cr2bsp0 = make_float4(+7, -4, +5, -2) / 6.f; | static const float4 cr2bsp0 = make_float4(+7, -4, +5, -2) / 6.f; | ||||
| static const float4 cr2bsp1 = make_float4(-2, 11, -4, +1) / 6.f; | static const float4 cr2bsp1 = make_float4(-2, 11, -4, +1) / 6.f; | ||||
| static const float4 cr2bsp2 = make_float4(+1, -4, 11, -2) / 6.f; | static const float4 cr2bsp2 = make_float4(+1, -4, 11, -2) / 6.f; | ||||
| static const float4 cr2bsp3 = make_float4(-2, +5, -4, +7) / 6.f; | static const float4 cr2bsp3 = make_float4(-2, +5, -4, +7) / 6.f; | ||||
| index_data[i] = i * 4; | |||||
| float4 *const v = vertex_data.data() + step * num_vertices + index_data[i]; | |||||
| v[0] = make_float4( | v[0] = make_float4( | ||||
| dot(cr2bsp0, px), dot(cr2bsp0, py), dot(cr2bsp0, pz), dot(cr2bsp0, pw)); | dot(cr2bsp0, px), dot(cr2bsp0, py), dot(cr2bsp0, pz), dot(cr2bsp0, pw)); | ||||
| v[1] = make_float4( | v[1] = make_float4( | ||||
| dot(cr2bsp1, px), dot(cr2bsp1, py), dot(cr2bsp1, pz), dot(cr2bsp1, pw)); | dot(cr2bsp1, px), dot(cr2bsp1, py), dot(cr2bsp1, pz), dot(cr2bsp1, pw)); | ||||
| v[2] = make_float4( | v[2] = make_float4( | ||||
| dot(cr2bsp2, px), dot(cr2bsp2, py), dot(cr2bsp2, pz), dot(cr2bsp2, pw)); | dot(cr2bsp2, px), dot(cr2bsp2, py), dot(cr2bsp2, pz), dot(cr2bsp2, pw)); | ||||
| v[3] = make_float4( | v[3] = make_float4( | ||||
| dot(cr2bsp3, px), dot(cr2bsp3, py), dot(cr2bsp3, pz), dot(cr2bsp3, pw)); | dot(cr2bsp3, px), dot(cr2bsp3, py), dot(cr2bsp3, pz), dot(cr2bsp3, pw)); | ||||
| # endif | |||||
| } | } | ||||
| else { | else { | ||||
| BoundBox bounds = BoundBox::empty; | BoundBox bounds = BoundBox::empty; | ||||
| curve.bounds_grow(segment, keys, hair->get_curve_radius().data(), bounds); | curve.bounds_grow(segment, keys, hair->get_curve_radius().data(), bounds); | ||||
| const size_t index = step * num_segments + i; | const size_t index = step * num_segments + i; | ||||
| aabb_data[index].minX = bounds.min.x; | aabb_data[index].minX = bounds.min.x; | ||||
| aabb_data[index].minY = bounds.min.y; | aabb_data[index].minY = bounds.min.y; | ||||
| Show All 25 Lines | # endif | ||||
| vertex_ptrs.push_back(base_ptr); | vertex_ptrs.push_back(base_ptr); | ||||
| } | } | ||||
| /* Force a single any-hit call, so shadow record-all behavior works correctly. */ | /* Force a single any-hit call, so shadow record-all behavior works correctly. */ | ||||
| unsigned int build_flags = OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL; | unsigned int build_flags = OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL; | ||||
| OptixBuildInput build_input = {}; | OptixBuildInput build_input = {}; | ||||
| if (hair->curve_shape == CURVE_THICK) { | if (hair->curve_shape == CURVE_THICK) { | ||||
| build_input.type = OPTIX_BUILD_INPUT_TYPE_CURVES; | build_input.type = OPTIX_BUILD_INPUT_TYPE_CURVES; | ||||
| # if OPTIX_ABI_VERSION >= 55 | |||||
| build_input.curveArray.curveType = OPTIX_PRIMITIVE_TYPE_ROUND_CATMULLROM; | |||||
| # else | |||||
| build_input.curveArray.curveType = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE; | build_input.curveArray.curveType = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE; | ||||
| # endif | |||||
| build_input.curveArray.numPrimitives = num_segments; | build_input.curveArray.numPrimitives = num_segments; | ||||
| build_input.curveArray.vertexBuffers = (CUdeviceptr *)vertex_ptrs.data(); | build_input.curveArray.vertexBuffers = (CUdeviceptr *)vertex_ptrs.data(); | ||||
| build_input.curveArray.numVertices = num_vertices; | build_input.curveArray.numVertices = num_vertices; | ||||
| build_input.curveArray.vertexStrideInBytes = sizeof(float4); | build_input.curveArray.vertexStrideInBytes = sizeof(float4); | ||||
| build_input.curveArray.widthBuffers = (CUdeviceptr *)width_ptrs.data(); | build_input.curveArray.widthBuffers = (CUdeviceptr *)width_ptrs.data(); | ||||
| build_input.curveArray.widthStrideInBytes = sizeof(float4); | build_input.curveArray.widthStrideInBytes = sizeof(float4); | ||||
| build_input.curveArray.indexBuffer = (CUdeviceptr)index_data.device_pointer; | build_input.curveArray.indexBuffer = (CUdeviceptr)index_data.device_pointer; | ||||
| build_input.curveArray.indexStrideInBytes = sizeof(int); | build_input.curveArray.indexStrideInBytes = sizeof(int); | ||||
| ▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | else if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { | ||||
| progress.set_error("Failed to build OptiX acceleration structure"); | progress.set_error("Failed to build OptiX acceleration structure"); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| unsigned int num_instances = 0; | unsigned int num_instances = 0; | ||||
| unsigned int max_num_instances = 0xFFFFFFFF; | unsigned int max_num_instances = 0xFFFFFFFF; | ||||
| bvh_optix->as_data.free(); | bvh_optix->as_data->free(); | ||||
| bvh_optix->traversable_handle = 0; | bvh_optix->traversable_handle = 0; | ||||
| bvh_optix->motion_transform_data.free(); | bvh_optix->motion_transform_data->free(); | ||||
| optixDeviceContextGetProperty(context, | optixDeviceContextGetProperty(context, | ||||
| OPTIX_DEVICE_PROPERTY_LIMIT_MAX_INSTANCE_ID, | OPTIX_DEVICE_PROPERTY_LIMIT_MAX_INSTANCE_ID, | ||||
| &max_num_instances, | &max_num_instances, | ||||
| sizeof(max_num_instances)); | sizeof(max_num_instances)); | ||||
| /* Do not count first bit, which is used to distinguish instanced and non-instanced objects. */ | /* Do not count first bit, which is used to distinguish instanced and non-instanced objects. */ | ||||
| max_num_instances >>= 1; | max_num_instances >>= 1; | ||||
| if (bvh->objects.size() > max_num_instances) { | if (bvh->objects.size() > max_num_instances) { | ||||
| Show All 16 Lines | if (motion_blur) { | ||||
| OPTIX_TRANSFORM_BYTE_ALIGNMENT); | OPTIX_TRANSFORM_BYTE_ALIGNMENT); | ||||
| const size_t motion_keys = max(ob->get_motion().size(), 2) - 2; | const size_t motion_keys = max(ob->get_motion().size(), 2) - 2; | ||||
| total_motion_transform_size = total_motion_transform_size + | total_motion_transform_size = total_motion_transform_size + | ||||
| sizeof(OptixSRTMotionTransform) + | sizeof(OptixSRTMotionTransform) + | ||||
| motion_keys * sizeof(OptixSRTData); | motion_keys * sizeof(OptixSRTData); | ||||
| } | } | ||||
| } | } | ||||
| assert(bvh_optix->motion_transform_data.device == this); | assert(bvh_optix->motion_transform_data->device == this); | ||||
| bvh_optix->motion_transform_data.alloc_to_device(total_motion_transform_size); | bvh_optix->motion_transform_data->alloc_to_device(total_motion_transform_size); | ||||
| } | } | ||||
| for (Object *ob : bvh->objects) { | for (Object *ob : bvh->objects) { | ||||
| /* Skip non-traceable objects. */ | /* Skip non-traceable objects. */ | ||||
| if (!ob->is_traceable()) { | if (!ob->is_traceable()) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| Show All 25 Lines | for (Object *ob : bvh->objects) { | ||||
| if (ob->get_geometry()->geometry_type == Geometry::HAIR && | if (ob->get_geometry()->geometry_type == Geometry::HAIR && | ||||
| static_cast<const Hair *>(ob->get_geometry())->curve_shape == CURVE_THICK) { | static_cast<const Hair *>(ob->get_geometry())->curve_shape == CURVE_THICK) { | ||||
| if (motion_blur && ob->get_geometry()->has_motion_blur()) { | if (motion_blur && ob->get_geometry()->has_motion_blur()) { | ||||
| /* Select between motion blur and non-motion blur built-in intersection module. */ | /* Select between motion blur and non-motion blur built-in intersection module. */ | ||||
| instance.sbtOffset = PG_HITD_MOTION - PG_HITD; | instance.sbtOffset = PG_HITD_MOTION - PG_HITD; | ||||
| } | } | ||||
| } | } | ||||
| else { | # if OPTIX_ABI_VERSION < 55 | ||||
| /* Can disable __anyhit__kernel_optix_visibility_test by default (except for thick curves, | /* Cannot disable any-hit program for thick curves, since it needs to filter out endcaps. */ | ||||
| * since it needs to filter out end-caps there). | else | ||||
| # endif | |||||
| { | |||||
| /* Can disable __anyhit__kernel_optix_visibility_test by default. | |||||
| * It is enabled where necessary (visibility mask exceeds 8 bits or the other any-hit | * It is enabled where necessary (visibility mask exceeds 8 bits or the other any-hit | ||||
| * programs like __anyhit__kernel_optix_shadow_all_hit) via OPTIX_RAY_FLAG_ENFORCE_ANYHIT. | * programs like __anyhit__kernel_optix_shadow_all_hit) via OPTIX_RAY_FLAG_ENFORCE_ANYHIT. | ||||
| */ | */ | ||||
| instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_ANYHIT; | instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_ANYHIT; | ||||
| } | } | ||||
| /* Insert motion traversable if object has motion. */ | /* Insert motion traversable if object has motion. */ | ||||
| if (motion_blur && ob->use_motion()) { | if (motion_blur && ob->use_motion()) { | ||||
| size_t motion_keys = max(ob->get_motion().size(), 2) - 2; | size_t motion_keys = max(ob->get_motion().size(), 2) - 2; | ||||
| size_t motion_transform_size = sizeof(OptixSRTMotionTransform) + | size_t motion_transform_size = sizeof(OptixSRTMotionTransform) + | ||||
| motion_keys * sizeof(OptixSRTData); | motion_keys * sizeof(OptixSRTData); | ||||
| const CUDAContextScope scope(this); | const CUDAContextScope scope(this); | ||||
| motion_transform_offset = align_up(motion_transform_offset, | motion_transform_offset = align_up(motion_transform_offset, | ||||
| OPTIX_TRANSFORM_BYTE_ALIGNMENT); | OPTIX_TRANSFORM_BYTE_ALIGNMENT); | ||||
| CUdeviceptr motion_transform_gpu = bvh_optix->motion_transform_data.device_pointer + | CUdeviceptr motion_transform_gpu = bvh_optix->motion_transform_data->device_pointer + | ||||
| motion_transform_offset; | motion_transform_offset; | ||||
| motion_transform_offset += motion_transform_size; | motion_transform_offset += motion_transform_size; | ||||
| /* Allocate host side memory for motion transform and fill it with transform data. */ | /* Allocate host side memory for motion transform and fill it with transform data. */ | ||||
| OptixSRTMotionTransform &motion_transform = *reinterpret_cast<OptixSRTMotionTransform *>( | OptixSRTMotionTransform &motion_transform = *reinterpret_cast<OptixSRTMotionTransform *>( | ||||
| new uint8_t[motion_transform_size]); | new uint8_t[motion_transform_size]); | ||||
| motion_transform.child = handle; | motion_transform.child = handle; | ||||
| motion_transform.motionOptions.numKeys = ob->get_motion().size(); | motion_transform.motionOptions.numKeys = ob->get_motion().size(); | ||||
| Show All 36 Lines | # endif | ||||
| srt_data[i].ty = decomp[i].y.y; | srt_data[i].ty = decomp[i].y.y; | ||||
| srt_data[i].tz = decomp[i].y.z; | srt_data[i].tz = decomp[i].y.z; | ||||
| } | } | ||||
| /* Upload motion transform to GPU. */ | /* Upload motion transform to GPU. */ | ||||
| cuMemcpyHtoD(motion_transform_gpu, &motion_transform, motion_transform_size); | cuMemcpyHtoD(motion_transform_gpu, &motion_transform, motion_transform_size); | ||||
| delete[] reinterpret_cast<uint8_t *>(&motion_transform); | delete[] reinterpret_cast<uint8_t *>(&motion_transform); | ||||
| /* Disable instance transform if object uses motion transform already. */ | |||||
| instance.flags |= OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM; | |||||
| /* Get traversable handle to motion transform. */ | /* Get traversable handle to motion transform. */ | ||||
| optixConvertPointerToTraversableHandle(context, | optixConvertPointerToTraversableHandle(context, | ||||
| motion_transform_gpu, | motion_transform_gpu, | ||||
| OPTIX_TRAVERSABLE_TYPE_SRT_MOTION_TRANSFORM, | OPTIX_TRAVERSABLE_TYPE_SRT_MOTION_TRANSFORM, | ||||
| &instance.traversableHandle); | &instance.traversableHandle); | ||||
| } | } | ||||
| else { | else { | ||||
| instance.traversableHandle = handle; | instance.traversableHandle = handle; | ||||
| if (ob->get_geometry()->is_instanced()) { | if (ob->get_geometry()->is_instanced()) { | ||||
| /* Set transform matrix. */ | /* Set transform matrix. */ | ||||
| memcpy(instance.transform, &ob->get_tfm(), sizeof(instance.transform)); | memcpy(instance.transform, &ob->get_tfm(), sizeof(instance.transform)); | ||||
| } | } | ||||
| else { | |||||
| /* Disable instance transform if geometry already has it applied to vertex data. */ | |||||
| instance.flags |= OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| /* Upload instance descriptions. */ | /* Upload instance descriptions. */ | ||||
| instances.resize(num_instances); | instances.resize(num_instances); | ||||
| instances.copy_to_device(); | instances.copy_to_device(); | ||||
| /* Build top-level acceleration structure (TLAS) */ | /* Build top-level acceleration structure (TLAS) */ | ||||
| ▲ Show 20 Lines • Show All 67 Lines • Show Last 20 Lines | |||||