File indexing completed on 2026-04-09 07:49:03
0001 #include <iostream>
0002 #include <iomanip>
0003 #include <cstring>
0004 #include <sstream>
0005 #include <fstream>
0006 #include <cassert>
0007
0008 #include <optix.h>
0009 #include <optix_stubs.h>
0010 #include <optix_stack_size.h>
0011
0012 #include <cuda_runtime.h>
0013 #include "scuda.h" // roundUp
0014 #include "sstr.h"
0015 #include "ssys.h"
0016 #include "spath.h"
0017
0018 #include "OPTIX_CHECK.h"
0019
0020 #include "Ctx.h"
0021 #include "Binding.h"
0022 #include "OPT.h"
0023 #include "PIP.h"
0024 #include "SLOG.hh"
0025
0026 const plog::Severity PIP::LEVEL = SLOG::EnvLevel("PIP", "DEBUG");
0027
0028
0029
0030
0031 bool PIP::OptiXVersionIsSupported()
0032 {
0033 bool ok = false ;
0034 #if OPTIX_VERSION == 70000 || OPTIX_VERSION == 70500 || OPTIX_VERSION == 70600
0035 ok = true ;
0036 #elif OPTIX_VERSION >= 80000
0037 ok = true ;
0038 #endif
0039 return ok ;
0040 }
0041
0042
0043 const char* PIP::CreatePipelineOptions_exceptionFlags = ssys::getenvvar("PIP__CreatePipelineOptions_exceptionFlags", "STACK_OVERFLOW" );
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 OptixPipelineCompileOptions PIP::CreatePipelineOptions(unsigned numPayloadValues, unsigned numAttributeValues )
0063 {
0064 unsigned traversableGraphFlags=OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING ;
0065
0066 OptixPipelineCompileOptions pipeline_compile_options = {} ;
0067 pipeline_compile_options.usesMotionBlur = false;
0068 pipeline_compile_options.traversableGraphFlags = traversableGraphFlags ;
0069 pipeline_compile_options.numPayloadValues = numPayloadValues ;
0070 pipeline_compile_options.numAttributeValues = numAttributeValues ;
0071 pipeline_compile_options.exceptionFlags = OPT::ExceptionFlags( CreatePipelineOptions_exceptionFlags ) ;
0072 pipeline_compile_options.pipelineLaunchParamsVariableName = "params";
0073 pipeline_compile_options.usesPrimitiveTypeFlags = OPTIX_PRIMITIVE_TYPE_FLAGS_CUSTOM ;
0074
0075 return pipeline_compile_options ;
0076 }
0077
0078 std::string PIP::Desc_PipelineCompileOptions(const OptixPipelineCompileOptions& pipeline_compile_options )
0079 {
0080 std::stringstream ss ;
0081 ss
0082 << "[PIP::Desc_PipelineCompileOptions" << std::endl
0083 << " pipeline_compile_options.numPayloadValues " << pipeline_compile_options.numPayloadValues << std::endl
0084 << " pipeline_compile_options.numAttributeValues " << pipeline_compile_options.numAttributeValues << std::endl
0085 << " pipeline_compile_options.exceptionFlags " << pipeline_compile_options.exceptionFlags
0086 << OPT::Desc_ExceptionFlags( pipeline_compile_options.exceptionFlags )
0087 << std::endl
0088 << "]PIP::Desc_PipelineCompileOptions" << std::endl
0089 ;
0090 std::string str = ss.str() ;
0091 return str ;
0092 }
0093
0094
0095
0096
0097
0098
0099 OptixProgramGroupOptions PIP::CreateProgramGroupOptions()
0100 {
0101 OptixProgramGroupOptions program_group_options = {};
0102 return program_group_options ;
0103 }
0104
0105
0106 const char* PIP::desc() const
0107 {
0108 std::stringstream ss ;
0109 ss << "PIP "
0110 << " td:" << max_trace_depth
0111 << " pv:" << num_payload_values
0112 << " av:" << num_attribute_values
0113 #ifdef WITH_PRD
0114 << " WITH_PRD "
0115 #else
0116 << " NOT_WITH_PRD "
0117 #endif
0118 << " "
0119 ;
0120
0121 std::string s = ss.str();
0122 return strdup(s.c_str());
0123 }
0124
0125 const int PIP::MAX_TRACE_DEPTH = ssys::getenvint("PIP__max_trace_depth", 1 ) ;
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 PIP::PIP(const char* ptx_path_, const Properties* properties_ )
0138 :
0139 max_trace_depth(MAX_TRACE_DEPTH),
0140 #ifdef WITH_PRD
0141 num_payload_values(2),
0142 num_attribute_values(2),
0143 #else
0144 num_payload_values(8),
0145 num_attribute_values(6),
0146 #endif
0147 properties(properties_),
0148 pipeline_compile_options(CreatePipelineOptions(num_payload_values,num_attribute_values)),
0149 program_group_options(CreateProgramGroupOptions()),
0150 module(CreateModule(ptx_path_,pipeline_compile_options))
0151 {
0152 init();
0153 }
0154
0155
0156 PIP::~PIP()
0157 {
0158 destroy();
0159 }
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169 void PIP::init()
0170 {
0171 LOG(LEVEL) << "[" ;
0172
0173 createRaygenPG();
0174 createMissPG();
0175 createHitgroupPG();
0176 linkPipeline(max_trace_depth);
0177
0178 LOG(LEVEL) << "]" ;
0179 }
0180
0181
0182 void PIP::destroy()
0183 {
0184 destroyPipeline();
0185 destroyRaygenPG();
0186 destroyMissPG();
0187 destroyHitgroupPG();
0188 destroyModule();
0189 }
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200 const char* PIP::CreateModule_optLevel = ssys::getenvvar("PIP__CreateModule_optLevel", "DEFAULT" ) ;
0201 const char* PIP::CreateModule_debugLevel = ssys::getenvvar("PIP__CreateModule_debugLevel", "DEFAULT" ) ;
0202
0203 std::string PIP::Desc()
0204 {
0205 std::stringstream ss ;
0206 ss
0207 << "[PIP::Desc" << std::endl
0208 << " PIP__CreateModule_optLevel " << CreateModule_optLevel << std::endl
0209 << " PIP__CreateModule_debugLevel " << CreateModule_debugLevel << std::endl
0210 << "]PIP::Desc" << std::endl
0211 ;
0212
0213 std::string str = ss.str() ;
0214 return str ;
0215 }
0216
0217
0218 std::string PIP::Desc_ModuleCompileOptions(const OptixModuleCompileOptions& module_compile_options )
0219 {
0220 std::stringstream ss ;
0221 ss
0222 << "[PIP::Desc_ModuleCompileOptions" << std::endl
0223 << " module_compile_options.maxRegisterCount " << module_compile_options.maxRegisterCount
0224 << " OPTIX_COMPILE_DEFAULT_MAX_REGISTER_COUNT " << OPTIX_COMPILE_DEFAULT_MAX_REGISTER_COUNT
0225 << std::endl
0226 << " module_compile_options.optLevel " << module_compile_options.optLevel
0227 << " " << OPT::OptimizationLevel_( module_compile_options.optLevel )
0228 << std::endl
0229 << " module_compile_options.debugLevel " << module_compile_options.debugLevel
0230 << " " << OPT::DebugLevel_( module_compile_options.debugLevel )
0231 << std::endl
0232 << "]PIP::Desc_ModuleCompileOptions"
0233 << std::endl
0234 ;
0235 std::string str = ss.str() ;
0236 return str ;
0237 }
0238
0239 OptixModule PIP::CreateModule(const char* ptx_path, OptixPipelineCompileOptions& pipeline_compile_options )
0240 {
0241 std::string ptx ;
0242 bool ptx_ok = spath::Read(ptx, ptx_path );
0243
0244 LOG_IF(fatal, !ptx_ok)
0245 << std::endl
0246 << " ptx_path " << ptx_path
0247 << std::endl
0248 << " ptx.size " << ptx.size()
0249 << std::endl
0250 << " ptx_ok " << ( ptx_ok ? "YES" : "NO " )
0251 << std::endl
0252 ;
0253
0254 LOG(LEVEL)
0255 << std::endl
0256 << " ptx_path " << ptx_path
0257 << std::endl
0258 << " ptx.size " << ptx.size()
0259 << std::endl
0260 << " ptx_ok " << ( ptx_ok ? "YES" : "NO " )
0261 << std::endl
0262 ;
0263 assert(ptx_ok);
0264
0265 int maxRegisterCount = OPTIX_COMPILE_DEFAULT_MAX_REGISTER_COUNT ;
0266 OptixCompileOptimizationLevel optLevel = OPT::OptimizationLevel(CreateModule_optLevel) ;
0267 OptixCompileDebugLevel debugLevel = OPT::DebugLevel(CreateModule_debugLevel) ;
0268
0269 OptixModule module = nullptr ;
0270 OptixModuleCompileOptions module_compile_options = {};
0271 module_compile_options.maxRegisterCount = maxRegisterCount ;
0272 module_compile_options.optLevel = optLevel ;
0273 module_compile_options.debugLevel = debugLevel ;
0274
0275 LOG(LEVEL)
0276 << Desc()
0277 << Desc_ModuleCompileOptions( module_compile_options )
0278 ;
0279
0280
0281 size_t sizeof_log = 0 ;
0282 char log[2048];
0283
0284 #if OPTIX_VERSION <= 70600
0285 OPTIX_CHECK_LOG( optixModuleCreateFromPTX(
0286 Ctx::context,
0287 &module_compile_options,
0288 &pipeline_compile_options,
0289 ptx.c_str(),
0290 ptx.size(),
0291 log,
0292 &sizeof_log,
0293 &module
0294 ) );
0295 #else
0296 OPTIX_CHECK_LOG( optixModuleCreate(
0297 Ctx::context,
0298 &module_compile_options,
0299 &pipeline_compile_options,
0300 ptx.c_str(),
0301 ptx.size(),
0302 log,
0303 &sizeof_log,
0304 &module
0305 ) );
0306
0307 #endif
0308
0309 return module ;
0310 }
0311
0312 void PIP::destroyModule()
0313 {
0314 OPTIX_CHECK( optixModuleDestroy( module ) );
0315 }
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328 void PIP::createRaygenPG()
0329 {
0330 bool DUMMY = ssys::getenvbool("PIP__createRaygenPG_DUMMY");
0331 LOG(LEVEL) << " DUMMY " << ( DUMMY ? "YES" : "NO " ) ;
0332
0333
0334 OptixProgramGroupDesc desc = {};
0335 desc.kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
0336 desc.raygen.module = module;
0337 desc.raygen.entryFunctionName = DUMMY ? RG_DUMMY : RG ;
0338
0339 size_t sizeof_log = 0 ;
0340 char log[2048];
0341 unsigned num_program_groups = 1 ;
0342
0343 OPTIX_CHECK_LOG( optixProgramGroupCreate(
0344 Ctx::context,
0345 &desc,
0346 num_program_groups,
0347 &program_group_options,
0348 log,
0349 &sizeof_log,
0350 &raygen_pg
0351 ) );
0352
0353 if(sizeof_log > 0) std::cout << log << std::endl ;
0354 assert( sizeof_log == 0);
0355 }
0356
0357 void PIP::destroyRaygenPG()
0358 {
0359 OPTIX_CHECK( optixProgramGroupDestroy( raygen_pg ) );
0360 }
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372 void PIP::createMissPG()
0373 {
0374 OptixProgramGroupDesc desc = {};
0375 desc.kind = OPTIX_PROGRAM_GROUP_KIND_MISS;
0376 desc.miss.module = module;
0377 desc.miss.entryFunctionName = MS ;
0378
0379 size_t sizeof_log = 0 ;
0380 char log[2048];
0381 unsigned num_program_groups = 1 ;
0382
0383 OPTIX_CHECK_LOG( optixProgramGroupCreate(
0384 Ctx::context,
0385 &desc,
0386 num_program_groups,
0387 &program_group_options,
0388 log,
0389 &sizeof_log,
0390 &miss_pg
0391 ) );
0392
0393 if(sizeof_log > 0) std::cout << log << std::endl ;
0394 assert( sizeof_log == 0);
0395 }
0396
0397 void PIP::destroyMissPG()
0398 {
0399 OPTIX_CHECK( optixProgramGroupDestroy( miss_pg ) );
0400 }
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411 void PIP::createHitgroupPG()
0412 {
0413 OptixProgramGroupDesc desc = {};
0414 desc.kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP;
0415
0416 desc.hitgroup.moduleIS = module ;
0417 desc.hitgroup.entryFunctionNameIS = IS ;
0418
0419 desc.hitgroup.moduleCH = module ;
0420 desc.hitgroup.entryFunctionNameCH = CH ;
0421
0422 desc.hitgroup.moduleAH = nullptr ;
0423 desc.hitgroup.entryFunctionNameAH = nullptr ;
0424
0425 size_t sizeof_log = 0 ;
0426 char log[2048];
0427 unsigned num_program_groups = 1 ;
0428
0429
0430 OPTIX_CHECK_LOG( optixProgramGroupCreate(
0431 Ctx::context,
0432 &desc,
0433 num_program_groups,
0434 &program_group_options,
0435 log,
0436 &sizeof_log,
0437 &hitgroup_pg
0438 ) );
0439
0440 if(sizeof_log > 0) std::cout << log << std::endl ;
0441 assert( sizeof_log == 0);
0442 }
0443
0444 void PIP::destroyHitgroupPG()
0445 {
0446 OPTIX_CHECK( optixProgramGroupDestroy( hitgroup_pg ) );
0447 }
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460 const char* PIP::linkPipeline_debugLevel = ssys::getenvvar("PIP__linkPipeline_debugLevel", "DEFAULT" ) ;
0461
0462
0463 std::string PIP::Desc_PipelineLinkOptions(const OptixPipelineLinkOptions& pipeline_link_options )
0464 {
0465 std::stringstream ss ;
0466 ss
0467 << "[PIP::Desc_PipelineLinkOptions" << std::endl
0468 << " pipeline_link_options.maxTraceDepth " << pipeline_link_options.maxTraceDepth << std::endl
0469 #if OPTIX_VERSION <= 70600
0470 << " pipeline_link_options.debugLevel " << pipeline_link_options.debugLevel
0471 << " " << OPT::DebugLevel_(pipeline_link_options.debugLevel )
0472 << std::endl
0473 << " PIP__linkPipeline_debugLevel " << linkPipeline_debugLevel
0474 #endif
0475 << std::endl
0476 << "]PIP::Desc_PipelineLinkOptions" << std::endl
0477 ;
0478 std::string str = ss.str() ;
0479 return str ;
0480 }
0481
0482
0483 void PIP::linkPipeline(unsigned max_trace_depth)
0484 {
0485 OptixProgramGroup program_groups[] = { raygen_pg, miss_pg, hitgroup_pg };
0486
0487 OptixPipelineLinkOptions pipeline_link_options = {};
0488 pipeline_link_options.maxTraceDepth = max_trace_depth ;
0489
0490 #if OPTIX_VERSION == 70000
0491 pipeline_link_options.overrideUsesMotionBlur = false;
0492 #endif
0493
0494 #if OPTIX_VERSION <= 70600
0495 OptixCompileDebugLevel debugLevel = OPT::DebugLevel(linkPipeline_debugLevel) ;
0496 pipeline_link_options.debugLevel = debugLevel;
0497 #endif
0498
0499 size_t sizeof_log = 0 ;
0500 char log[2048];
0501
0502 OPTIX_CHECK_LOG( optixPipelineCreate(
0503 Ctx::context,
0504 &pipeline_compile_options,
0505 &pipeline_link_options,
0506 program_groups,
0507 sizeof( program_groups ) / sizeof( program_groups[0] ),
0508 log,
0509 &sizeof_log,
0510 &pipeline
0511 ) );
0512
0513 if(sizeof_log > 0) std::cout << log << std::endl ;
0514 assert( sizeof_log == 0);
0515 }
0516
0517 void PIP::destroyPipeline()
0518 {
0519 OPTIX_CHECK( optixPipelineDestroy( pipeline ) );
0520 }
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546 void PIP::configureStack()
0547 {
0548
0549
0550 OptixStackSizes stackSizes = {};
0551
0552 #if OPTIX_VERSION <= 70600
0553 OPTIX_CHECK( optixUtilAccumulateStackSizes( raygen_pg, &stackSizes ) );
0554 OPTIX_CHECK( optixUtilAccumulateStackSizes( miss_pg, &stackSizes ) );
0555 OPTIX_CHECK( optixUtilAccumulateStackSizes( hitgroup_pg, &stackSizes ) );
0556 #else
0557 OPTIX_CHECK( optixUtilAccumulateStackSizes( raygen_pg, &stackSizes, pipeline ) );
0558 OPTIX_CHECK( optixUtilAccumulateStackSizes( miss_pg, &stackSizes, pipeline ) );
0559 OPTIX_CHECK( optixUtilAccumulateStackSizes( hitgroup_pg, &stackSizes, pipeline ) );
0560 #endif
0561
0562
0563
0564 uint32_t max_trace_depth = 1;
0565 uint32_t max_cc_depth = 0;
0566 uint32_t max_dc_depth = 0;
0567
0568 LOG(LEVEL)
0569 << "(inputs to optixUtilComputeStackSizes)"
0570 << std::endl
0571 << " max_trace_depth " << max_trace_depth
0572 << " max_cc_depth " << max_cc_depth
0573 << " max_dc_depth " << max_dc_depth
0574 ;
0575
0576 uint32_t directCallableStackSizeFromTraversal;
0577 uint32_t directCallableStackSizeFromState;
0578 uint32_t continuationStackSize;
0579
0580 OPTIX_CHECK( optixUtilComputeStackSizes(
0581 &stackSizes,
0582 max_trace_depth,
0583 max_cc_depth,
0584 max_dc_depth,
0585 &directCallableStackSizeFromTraversal,
0586 &directCallableStackSizeFromState,
0587 &continuationStackSize
0588 ) );
0589
0590 LOG(LEVEL)
0591 << "(outputs from optixUtilComputeStackSizes) "
0592 << std::endl
0593 << " directCallableStackSizeFromTraversal " << directCallableStackSizeFromTraversal
0594 << std::endl
0595 << " directCallableStackSizeFromState " << directCallableStackSizeFromState
0596 << std::endl
0597 << " continuationStackSize " << continuationStackSize
0598 ;
0599
0600
0601 unsigned maxTraversableGraphDepth = 2 ;
0602
0603 LOG(LEVEL)
0604 << "(further inputs to optixPipelineSetStackSize)"
0605 << std::endl
0606 << " maxTraversableGraphDepth " << maxTraversableGraphDepth
0607 ;
0608
0609
0610
0611
0612 OPTIX_CHECK( optixPipelineSetStackSize( pipeline,
0613 directCallableStackSizeFromTraversal,
0614 directCallableStackSizeFromState,
0615 continuationStackSize,
0616 maxTraversableGraphDepth ) ) ;
0617 }
0618
0619