Creating multiple pipelines with different __raygen__

Hi,

I’m a beginner at using OptiX. I’m starting code development from several sample codes. Now I’d like to generate multiple pipelines with a single module, and I wrote codes below:

//-----------Generate pipelines--------------
constexpr char *raygen_program[]{"__raygen__pinhole", "__raygen__simplehit"};
constexpr char *misshit_program[]{"__miss__radiance", "__miss__simplehit"};
for (int i = 0; i < numPipeLine; i++) {//Want to generate numPipeLine pipelines.
            pipeline[i] = nullptr;
            vector<OptixProgramGroup> prgs_per_pipeline = program_group;//program_group has closest hit, intersection, and direct callables.           
            
            // i-th Ray generation program 
            OptixProgramGroupOptions raygen_prg_options = {};
            OptixProgramGroupDesc raygen_prg_desc = {};
            raygen_prg_desc.kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
            raygen_prg_desc.raygen.module = module;
            raygen_prg_desc.raygen.entryFunctionName = raygen_program[i];
            OPTIX_CHECK_LOG(optixProgramGroupCreate(context, &raygen_prg_desc, 1, &raygen_prg_options, log, &sizeof_log, &raygen_prg[i]));
            prgs_per_pipeline.push_back(raygen_prg[i]);//Raygen program is push backed for optixPipelineCreate           
            
            // i-th Miss hit program 
            OptixProgramGroupOptions miss_prg_options = {};
            OptixProgramGroupDesc miss_prg_desc = {};
            miss_prg_desc.kind = OPTIX_PROGRAM_GROUP_KIND_MISS;
            miss_prg_desc.miss.module = module;
            miss_prg_desc.miss.entryFunctionName = misshit_program[i];
            OPTIX_CHECK_LOG(optixProgramGroupCreate(context, &miss_prg_desc, 1, &miss_prg_options, log, &sizeof_log, &miss_prg[i]));
            prgs_per_pipeline.push_back(miss_prg[i]);//Miss hit program is push backed for optixPipelineCreate            
            
            //optixPipelineCreate for i-th pipeline
            OptixPipelineLinkOptions pipe_link_option = {};
            pipe_link_option.maxTraceDepth = 5;
            pipe_link_option.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL;
            OPTIX_CHECK_LOG(optixPipelineCreate(context, &pipeline_compile_options, &pipe_link_option, prgs_per_pipeline.data(), prgs_per_pipeline.size(), log, &sizeof_log, &pipeline[i]));
            OptixStackSizes stack_sizes = {};
            for (auto &&prg: prgs_per_pipeline) OPTIX_CHECK(optixUtilAccumulateStackSizes(prg, &stack_sizes));
            uint32_t stack_size_traversable, stack_size_state, continuation_stack_size;
            OPTIX_CHECK(optixUtilComputeStackSizes(&stack_sizes, pipe_link_option.maxTraceDepth, 0, 3, &stack_size_traversable, &stack_size_state, &continuation_stack_size));
            OPTIX_CHECK(optixPipelineSetStackSize(pipeline[i], stack_size_traversable, stack_size_state, continuation_stack_size, 2));
}
//-----------End Generate pipelines---------------

The code could be compiled with no error. Then I expected the following code can switch the pipelines called by changing i:
OPTIX_CHECK(optixLaunch(pipeline[i], stream, params_on_device, sizeof(Params), &sbt, params.width, params.height, 1));

However, the code always calls pipeline[0] even if i is set to 1. So what is my mistake?

Any help is greatly appreciated.
Kai

The pipeline is coupled with the Shader Binding Table (SBT).
Each pipeline needs its own SBT which contains the matching SBT record headers (32 bytes of information about your pipeline’s entry point functions).

Check your calls to optixSbtRecordPackHeader() for the ray generation program groups and the raygenRecord field in your shader binding tables (plural!).

You can not switch only the pipeline inside the optixLaunch().
Means your &sbt argument should be &sbt[i] instead.

Related thread:
https://forums.developer.nvidia.com/t/how-to-handle-multiple-ray-generators/83446

Related search for “SBT” in this OptiX forum for more information:
https://forums.developer.nvidia.com/search?q=SBT%20%20%23visualization%3Aoptix

Related chapters inside the OptiX Programming Guide:
https://raytracing-docs.nvidia.com/optix7/guide/index.html#program_pipeline_creation#program-pipeline-creation
https://raytracing-docs.nvidia.com/optix7/guide/index.html#shader_binding_table#shader-binding-table

Hi droettger,

Thank you very much for your quick and concise reply. As you indicated, I had a mistake in optixSbtRecordPackHeader() that used only the first __raygen__ and __miss__ programs. By preparing SBT per pipeline, I could solve this issue and now the intended switching was implemented.

Thanks a lot!