Hello,
I’m writing openGL app with raytraced shadows by Optix, so the idea is to use only raygen and miss program (reference), but I got into a pickle and can’t progress further. I’m using NVRTC to compile .cu into ptx string, which works fine. The main module is built, program groups for miss and raygen program are built with no problem as well. But the optixPipelineCreate
fails with
[ 2][COMPILE FEEDBACK]: COMPILE ERROR: failed to create pipeline
Info: Pipeline has 1 module(s), 2 entry function(s), 1 trace call(s), 0 continuation callable call(s), 0 direct callable call(s), 2 basic block(s) in entry functions, 8 instruction(s) in entry functions, 7 non-entry function(s), 53 basic block(s) in non-entry functions, 627 instruction(s) in non-entry functions
My .cu file is very minimalistic so far, I just want to know it works before writing all the fragment to light traces and light source logic. (pipeline creating fails even with empty functions)
#include <optix.h>
#include "optixSettings.h"
extern "C"
{
__constant__ Params params;
}
static __forceinline__ __device__ void computeOrAndDir(uint3 idx, uint3 dim, float3& origin, float3& direction)
{
int fa = 50;
fa += 10;
}
//raygen function to generate new rays
extern "C" __global__ void __raygen__rg() {
//get thread indices
const uint3 idx = optixGetLaunchIndex();
const uint3 dim = optixGetLaunchDimensions();
//get ray origin from the input matrix and direction from lights input.
float3 ray_origin, ray_direction;
computeOrAndDir(idx, dim, ray_origin, ray_direction);
//for each light sample call optixTrace
unsigned int isVisible = 0;
float distance = 0; //distance of origin and light sample pos
float epsilon = 0.01; //offset so we don't hit the same triangle
optixTrace(
params.handle,
ray_origin,
ray_direction,
epsilon,
distance - epsilon,
0.0f,
OptixVisibilityMask(0xFF),
OPTIX_RAY_FLAG_DISABLE_ANYHIT | OPTIX_RAY_FLAG_DISABLE_CLOSESTHIT | OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT,
0, 0,
0, //missSBTindex
isVisible //payload
);
if (isVisible) {
//set output matrix to 1.0
}
else {
//set output matrix to 0.0
}
}
extern "C" __global__ void __miss__ms() {
optixSetPayload_0(1);
}
I was trying to follow the programmers guide while writing the program creation code with some modifications. The scene GAS is built from OpenGL VBO and EBO, ray origins will be taken from OpenGL geometry pass matrix.
void Raytracer::setUpPrograms() {
OptixModuleCompileOptions module_compile_options = {};
module_compile_options.maxRegisterCount = OPTIX_COMPILE_DEFAULT_MAX_REGISTER_COUNT;
module_compile_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_0;//OPTIX_COMPILE_OPTIMIZATION_DEFAULT;
module_compile_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL; //OPTIX_COMPILE_DEBUG_LEVEL_MINIMAL;
OptixPipelineCompileOptions pipeline_compile_options = {};
pipeline_compile_options.usesMotionBlur = false;
pipeline_compile_options.numPayloadValues = 1; // only one int in payload (visibility)
//pipeline_compile_options.numAttributeValues = 1;
pipeline_compile_options.traversableGraphFlags = OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_GAS; // check if preTransform is applied
//pipeline_compile_options.exceptionFlags = OPTIX_EXCEPTION_FLAG_DEBUG | OPTIX_EXCEPTION_FLAG_TRACE_DEPTH | OPTIX_EXCEPTION_FLAG_STACK_OVERFLOW;
pipeline_compile_options.pipelineLaunchParamsVariableName = "params";
pipeline_compile_options.usesPrimitiveTypeFlags = OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE;
char log[2048]; // For error reporting from OptiX creation functions
OptixModule module = nullptr;
size_t ptxSize = 0;
const char* ptxData = readPtxFile(ptxSize);
size_t sizeof_log = sizeof(log);
OPTIX_CHECK_LOG(optixModuleCreateFromPTX(
mOptixContext,
&module_compile_options,
&pipeline_compile_options,
ptxData, ptxSize,
log, &sizeof_log,
&module
));
//create program groups
OptixProgramGroup raygen_prog_group = nullptr;
OptixProgramGroup miss_prog_group = nullptr;
OptixProgramGroupOptions program_group_options = {}; // Initialize to zeros
OptixProgramGroupDesc raygen_prog_group_desc = {}; //
raygen_prog_group_desc.kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
raygen_prog_group_desc.raygen.module = module;
raygen_prog_group_desc.raygen.entryFunctionName = "__raygen__rg";
OPTIX_CHECK_LOG(optixProgramGroupCreate(
mOptixContext,
&raygen_prog_group_desc,
1, // num program groups
&program_group_options,
log,
&sizeof_log,
&raygen_prog_group
));
OptixProgramGroupDesc miss_prog_group_desc = {};
miss_prog_group_desc.kind = OPTIX_PROGRAM_GROUP_KIND_MISS;
miss_prog_group_desc.miss.module = module;
miss_prog_group_desc.miss.entryFunctionName = "__miss__ms";
OPTIX_CHECK_LOG(optixProgramGroupCreate(
mOptixContext,
&miss_prog_group_desc,
1, // num program groups
&program_group_options,
log,
&sizeof_log,
&miss_prog_group
));
//
// Link pipeline
//
OptixPipeline pipeline = nullptr;
const uint32_t max_trace_depth = 1;
OptixProgramGroup program_groups[] = { raygen_prog_group, miss_prog_group };
OptixPipelineLinkOptions pipeline_link_options = {};
pipeline_link_options.maxTraceDepth = max_trace_depth;
pipeline_link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL;
OPTIX_CHECK_LOG(optixPipelineCreate(
mOptixContext,
&pipeline_compile_options,
&pipeline_link_options,
program_groups,
sizeof(program_groups) / sizeof(program_groups[0]),
log,
&sizeof_log,
&pipeline
));
}
Thinking the issue was in .cu compilation I’ve moved from usign VS to nvcc the .cu file to rather using nvrtc according to sample code, but the issue persisted. Also I have a tendency of making stupid mistakes. Any helpful comment is greatly appreciated.