Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/device/optix/device_impl.cpp
| Show First 20 Lines • Show All 309 Lines • ▼ Show 20 Lines | bool OptiXDevice::load_kernels(const uint kernel_features) | ||||
| group_descs[PG_HITD].kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP; | group_descs[PG_HITD].kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP; | ||||
| group_descs[PG_HITD].hitgroup.moduleCH = optix_module; | group_descs[PG_HITD].hitgroup.moduleCH = optix_module; | ||||
| group_descs[PG_HITD].hitgroup.entryFunctionNameCH = "__closesthit__kernel_optix_hit"; | group_descs[PG_HITD].hitgroup.entryFunctionNameCH = "__closesthit__kernel_optix_hit"; | ||||
| group_descs[PG_HITD].hitgroup.moduleAH = optix_module; | group_descs[PG_HITD].hitgroup.moduleAH = optix_module; | ||||
| group_descs[PG_HITD].hitgroup.entryFunctionNameAH = "__anyhit__kernel_optix_visibility_test"; | group_descs[PG_HITD].hitgroup.entryFunctionNameAH = "__anyhit__kernel_optix_visibility_test"; | ||||
| group_descs[PG_HITS].kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP; | group_descs[PG_HITS].kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP; | ||||
| group_descs[PG_HITS].hitgroup.moduleAH = optix_module; | group_descs[PG_HITS].hitgroup.moduleAH = optix_module; | ||||
| group_descs[PG_HITS].hitgroup.entryFunctionNameAH = "__anyhit__kernel_optix_shadow_all_hit"; | group_descs[PG_HITS].hitgroup.entryFunctionNameAH = "__anyhit__kernel_optix_shadow_all_hit"; | ||||
| group_descs[PG_HITV].kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP; | |||||
| group_descs[PG_HITV].hitgroup.moduleCH = optix_module; | |||||
| group_descs[PG_HITV].hitgroup.entryFunctionNameCH = "__closesthit__kernel_optix_hit"; | |||||
| group_descs[PG_HITV].hitgroup.moduleAH = optix_module; | |||||
| 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 = {}; | ||||
| builtin_options.builtinISModuleType = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE; | builtin_options.builtinISModuleType = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE; | ||||
| builtin_options.usesMotionBlur = false; | builtin_options.usesMotionBlur = false; | ||||
| ▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | bool OptiXDevice::load_kernels(const uint kernel_features) | ||||
| sbt_data.copy_to_device(); /* Upload SBT to device. */ | sbt_data.copy_to_device(); /* Upload SBT to device. */ | ||||
| /* Calculate maximum trace continuation stack size. */ | /* Calculate maximum trace continuation stack size. */ | ||||
| unsigned int trace_css = stack_size[PG_HITD].cssCH; | unsigned int trace_css = stack_size[PG_HITD].cssCH; | ||||
| /* This is based on the maximum of closest-hit and any-hit/intersection programs. */ | /* This is based on the maximum of closest-hit and any-hit/intersection programs. */ | ||||
| trace_css = std::max(trace_css, stack_size[PG_HITD].cssIS + stack_size[PG_HITD].cssAH); | trace_css = std::max(trace_css, stack_size[PG_HITD].cssIS + stack_size[PG_HITD].cssAH); | ||||
| trace_css = std::max(trace_css, stack_size[PG_HITS].cssIS + stack_size[PG_HITS].cssAH); | trace_css = std::max(trace_css, stack_size[PG_HITS].cssIS + stack_size[PG_HITS].cssAH); | ||||
| trace_css = std::max(trace_css, stack_size[PG_HITL].cssIS + stack_size[PG_HITL].cssAH); | trace_css = std::max(trace_css, stack_size[PG_HITL].cssIS + stack_size[PG_HITL].cssAH); | ||||
| trace_css = std::max(trace_css, stack_size[PG_HITV].cssIS + stack_size[PG_HITV].cssAH); | |||||
| trace_css = std::max(trace_css, | trace_css = std::max(trace_css, | ||||
| stack_size[PG_HITD_MOTION].cssIS + stack_size[PG_HITD_MOTION].cssAH); | stack_size[PG_HITD_MOTION].cssIS + stack_size[PG_HITD_MOTION].cssAH); | ||||
| trace_css = std::max(trace_css, | trace_css = std::max(trace_css, | ||||
| stack_size[PG_HITS_MOTION].cssIS + stack_size[PG_HITS_MOTION].cssAH); | stack_size[PG_HITS_MOTION].cssIS + stack_size[PG_HITS_MOTION].cssAH); | ||||
| 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_LINEINFO; | ||||
| } | } | ||||
| 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]); | ||||
| pipeline_groups.push_back(groups[PG_HITD]); | pipeline_groups.push_back(groups[PG_HITD]); | ||||
| pipeline_groups.push_back(groups[PG_HITS]); | pipeline_groups.push_back(groups[PG_HITS]); | ||||
| pipeline_groups.push_back(groups[PG_HITL]); | pipeline_groups.push_back(groups[PG_HITL]); | ||||
| pipeline_groups.push_back(groups[PG_HITV]); | |||||
| if (motion_blur) { | if (motion_blur) { | ||||
| pipeline_groups.push_back(groups[PG_HITD_MOTION]); | pipeline_groups.push_back(groups[PG_HITD_MOTION]); | ||||
| pipeline_groups.push_back(groups[PG_HITS_MOTION]); | pipeline_groups.push_back(groups[PG_HITS_MOTION]); | ||||
| } | } | ||||
| pipeline_groups.push_back(groups[PG_CALL_SVM_AO]); | pipeline_groups.push_back(groups[PG_CALL_SVM_AO]); | ||||
| pipeline_groups.push_back(groups[PG_CALL_SVM_BEVEL]); | pipeline_groups.push_back(groups[PG_CALL_SVM_BEVEL]); | ||||
| optix_assert(optixPipelineCreate(context, | optix_assert(optixPipelineCreate(context, | ||||
| Show All 22 Lines | if (kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) { | ||||
| pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_CLOSEST]); | pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_CLOSEST]); | ||||
| pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_SHADOW]); | pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_SHADOW]); | ||||
| pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_SUBSURFACE]); | pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_SUBSURFACE]); | ||||
| pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_VOLUME_STACK]); | pipeline_groups.push_back(groups[PG_RGEN_INTERSECT_VOLUME_STACK]); | ||||
| pipeline_groups.push_back(groups[PG_MISS]); | pipeline_groups.push_back(groups[PG_MISS]); | ||||
| pipeline_groups.push_back(groups[PG_HITD]); | pipeline_groups.push_back(groups[PG_HITD]); | ||||
| pipeline_groups.push_back(groups[PG_HITS]); | pipeline_groups.push_back(groups[PG_HITS]); | ||||
| pipeline_groups.push_back(groups[PG_HITL]); | pipeline_groups.push_back(groups[PG_HITL]); | ||||
| pipeline_groups.push_back(groups[PG_HITV]); | |||||
| if (motion_blur) { | if (motion_blur) { | ||||
| pipeline_groups.push_back(groups[PG_HITD_MOTION]); | pipeline_groups.push_back(groups[PG_HITD_MOTION]); | ||||
| pipeline_groups.push_back(groups[PG_HITS_MOTION]); | pipeline_groups.push_back(groups[PG_HITS_MOTION]); | ||||
| } | } | ||||
| optix_assert(optixPipelineCreate(context, | optix_assert(optixPipelineCreate(context, | ||||
| &pipeline_options, | &pipeline_options, | ||||
| &link_options, | &link_options, | ||||
| ▲ Show 20 Lines • Show All 915 Lines • ▼ Show 20 Lines | for (Object *ob : bvh->objects) { | ||||
| /* Clear transform to identity matrix. */ | /* Clear transform to identity matrix. */ | ||||
| instance.transform[0] = 1.0f; | instance.transform[0] = 1.0f; | ||||
| instance.transform[5] = 1.0f; | instance.transform[5] = 1.0f; | ||||
| instance.transform[10] = 1.0f; | instance.transform[10] = 1.0f; | ||||
| /* Set user instance ID to object index (but leave low bit blank). */ | /* Set user instance ID to object index (but leave low bit blank). */ | ||||
| instance.instanceId = ob->get_device_index() << 1; | instance.instanceId = ob->get_device_index() << 1; | ||||
| /* Have to have at least one bit in the mask, or else instance would always be culled. */ | /* Add some of the object visibility bits to the mask. | ||||
| instance.visibilityMask = 1; | * __prim_visibility contains the combined visibility bits of all instances, so is not | ||||
| * reliable if they differ between instances. But the OptiX visibility mask can only contain | |||||
| if (ob->get_geometry()->has_volume) { | * 8 bits, so have to trade-off here and select just a few important ones. | ||||
| /* Volumes have a special bit set in the visibility mask so a trace can mask only volumes. | |||||
| */ | */ | ||||
| instance.visibilityMask |= 2; | instance.visibilityMask = ob->visibility_for_tracing() & 0xFF; | ||||
| } | |||||
| if (ob->get_geometry()->geometry_type == Geometry::HAIR) { | /* Have to have at least one bit in the mask, or else instance would always be culled. */ | ||||
| /* Same applies to curves (so they can be skipped in local trace calls). */ | if (0 == instance.visibilityMask) { | ||||
| instance.visibilityMask |= 4; | instance.visibilityMask = 0xFF; | ||||
| } | |||||
| if (motion_blur && ob->get_geometry()->has_motion_blur() && | 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()) { | |||||
| /* 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 { | |||||
| /* Can disable __anyhit__kernel_optix_visibility_test by default (except for thick curves, | |||||
| * since it needs to filter out endcaps there). | |||||
| * 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. | |||||
| */ | |||||
| 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); | ||||
| ▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | for (Object *ob : bvh->objects) { | ||||
| 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. */ | /* Disable instance transform if object uses motion transform already. */ | ||||
| instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM; | 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 { | else { | ||||
| /* Disable instance transform if geometry already has it applied to vertex data. */ | /* Disable instance transform if geometry already has it applied to vertex data. */ | ||||
| instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM; | instance.flags |= OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM; | ||||
| /* Non-instanced objects read ID from 'prim_object', so distinguish | /* Non-instanced objects read ID from 'prim_object', so distinguish | ||||
| * them from instanced objects with the low bit set. */ | * them from instanced objects with the low bit set. */ | ||||
| instance.instanceId |= 1; | instance.instanceId |= 1; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Upload instance descriptions. */ | /* Upload instance descriptions. */ | ||||
| ▲ Show 20 Lines • Show All 71 Lines • Show Last 20 Lines | |||||