Back to home page

EIC code displayed by LXR

 
 

    


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()  // static
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 PIP::CreatePipelineOptions
0047 ----------------------------
0048 
0049 traversableGraphFlags
0050     OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_GAS : got no intersects with this
0051     OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING  : works 
0052  
0053 usesPrimitiveTypeFlags
0054     from optix7-;optix7-types
0055     Setting to zero corresponds to enabling OPTIX_PRIMITIVE_TYPE_FLAGS_CUSTOM and OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE.
0056 
0057     Changed form unset 0 to OPTIX_PRIMITIVE_TYPE_FLAGS_CUSTOM removing OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE
0058 
0059 **/
0060 
0061 
0062 OptixPipelineCompileOptions PIP::CreatePipelineOptions(unsigned numPayloadValues, unsigned numAttributeValues ) // static
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 ;   // in optixTrace call
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() // static
0100 {
0101     OptixProgramGroupOptions program_group_options   = {}; // Initialize to zeros
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 ) ;   // was 2 
0126 
0127 /**
0128 PIP::PIP
0129 ---------
0130 
0131 PTX read from *ptx_path_* is used to CreateModule
0132 
0133 * num_payload_values and num_attribute_values MUST MATCH payload and attribute slots 
0134   used in the PTX, see CSGOptiX7.cu  
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),     // see trace
0142     num_attribute_values(2),   // see __intersection__is
0143 #else
0144     num_payload_values(8),     // see trace and setPayload 
0145     num_attribute_values(6),   // see __intersection__is
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 PIP::init
0163 -----------
0164 
0165 Names the programs to form the pipeline  
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 PIP::CreateModule
0194 -------------------
0195 
0196 PTX from file is read and compiled into the module
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 ) // static 
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]; // For error reporting from OptiX creation functions
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 PIP::createRaygenPG
0320 ---------------------
0321 
0322 Creates member raygen_pg
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 PIP::createMissPG
0366 ---------------------
0367 
0368 Creates member miss_pg
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 PIP::createHitgroupPG
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 PIP::linkPipeline
0453 -------------------
0454 
0455 Create pipeline from the program_groups
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 PIP::configureStack
0526 ------------------------
0527 
0528 https://on-demand.gputechconf.com/siggraph/2019/pdf/sig915-optix-performance-tools-tricks.pdf
0529 
0530 https://sibr.gitlabpages.inria.fr/docs/0.9.6/OptixRaycaster_8cpp_source.html
0531 
0532 /Developer/OptiX_700/include/optix_stack_size.h
0533  
0534 /Developer/OptiX_700/SDK/optixPathTracer/optixPathTracer.cpp
0535 
0536 In optix_stack_size.h:
0537    OptixStackSizes
0538    optixUtilAccumulateStackSizes()
0539    optixUtilComputeStackSizes()
0540    optixPipelineSetStackSize()
0541 These analyze your shaders. Source code included!
0542 Detailed control over stack size See optixPathTracer for example
0543  
0544 
0545 **/
0546 void PIP::configureStack()
0547 {
0548     // following OptiX_700/SDK/optixPathTracer/optixPathTracer.cpp
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;   // only RG invokes trace, no recursion   
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     // see optix7-;optix7-host : it states that IAS->GAS needs to be two  
0601     unsigned maxTraversableGraphDepth = 2 ; 
0602 
0603     LOG(LEVEL) 
0604         << "(further inputs to optixPipelineSetStackSize)"
0605         << std::endl 
0606         << " maxTraversableGraphDepth " << maxTraversableGraphDepth
0607         ;  
0608 
0609 
0610     //OPTIX_CHECK_LOG( optixProgramGroupGetStackSize(raygen_pg, OptixStackSizes* stackSizes ) );
0611 
0612     OPTIX_CHECK( optixPipelineSetStackSize( pipeline,
0613                                        directCallableStackSizeFromTraversal,
0614                                        directCallableStackSizeFromState,
0615                                        continuationStackSize,
0616                                        maxTraversableGraphDepth ) ) ;
0617 }
0618 
0619