I have been experimenting with the optixCustomPrimitive example from the optix SDK 8.0.0. My goal is to load a volume into memory and to render it using optix passing the bounding box of the volume as a custom primitive. To achieve this I have tinkered with the code and read through the optix documentation but my application always fails on optixLaunch with an “invalid value” error. I am having difficulty debugging this error as it is unclear what the reason is. I am attaching the optix calls and configuration that I have used and my shader.cu file. I am sorry if this is a very foolish question but are c++ namespaces not allowed as part of the launchParams since the params are placed in a extern C block in the shaders.cu?
// sbt and params structs
#include <optix.h>
#include <cuda_runtime.h>
#include "common.h"
#include <stdint.h>
namespace core {
namespace optix {
struct Light {
float3 position;
float3 color;
float intensity;
char pad[4];
};
struct Volume {
unsigned char* data;
float3 position;
int3 dimensions;
float3 spacing;
float scale;
common::VolumeTypes type;
char pad[12];
};
struct Camera {
float3 position, view, up;
int32_t imageHeight, imageWidth;
float fov;
float IMAGE_PLANE_DISTANCE;
char pad[12];
};
struct OptixParams {
unsigned char* canvas;
OptixTraversableHandle handle;
Light* lights;
Camera activeCamera;
Volume volume;
};
struct RayGenSbtRecord {
__align__(OPTIX_SBT_RECORD_ALIGNMENT)
char header[OPTIX_SBT_RECORD_HEADER_SIZE];
};
struct MissSbtRecord {
__align__(OPTIX_SBT_RECORD_ALIGNMENT)
char header[OPTIX_SBT_RECORD_HEADER_SIZE];
};
struct HitGroupSbtRecord {
__align__(OPTIX_SBT_RECORD_ALIGNMENT)
char header[OPTIX_SBT_RECORD_HEADER_SIZE];
};
};
};
//----------------------------------------------------------------
// shaders.cu
#include <optix.h>
#include <cuda_runtime.h>
#include "optix-params.h"
extern "C" {
__constant__ core::optix::OptixParams params;
}
extern "C"
__global__ void __raygen__generateTraceRays() {
}
extern "C"
__global__ void __miss__sampleEnvironmentMap() {
}
extern "C"
__global__ void __closesthit__renderVolume() {
}
//------------------------------------------------------------------
// Launch setup
// init
m_cudaContext = 0;
optixInit();
cudaFree(0);
optixDeviceContextCreate(m_cudaContext, nullptr, &m_optixContext);
// module create
module_compile_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_0;
module_compile_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL;
pipeline_compile_options.usesMotionBlur = false;
pipeline_compile_options.traversableGraphFlags = OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_GAS;
pipeline_compile_options.numPayloadValues = 2;
pipeline_compile_options.numAttributeValues = 2;
pipeline_compile_options.exceptionFlags = OPTIX_EXCEPTION_FLAG_NONE; // TODO: should be OPTIX_EXCEPTION_FLAG_STACK_OVERFLOW;
pipeline_compile_options.pipelineLaunchParamsVariableName = "params";
optixModuleCreate(
m_optixContext,
&module_compile_options,
&pipeline_compile_options,
moduleOptixIR.c_str(),
moduleOptixIR.size(),
logString, &logStringSize,
&module
);
// raygen program
raygen_prog_group_desc.kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
raygen_prog_group_desc.raygen.module = module;
raygen_prog_group_desc.raygen.entryFunctionName = "__raygen__generateTraceRays";
optixProgramGroupCreate(
m_optixContext,
&raygen_prog_group_desc,
1, // num program groups
&program_group_options,
logString, &logStringSize,
&m_raygen_prog_group
);
// miss program
miss_prog_group_desc.kind = OPTIX_PROGRAM_GROUP_KIND_MISS;
miss_prog_group_desc.miss.module = module;
miss_prog_group_desc.miss.entryFunctionName = "__miss__sampleEnvironmentMap";
optixProgramGroupCreate(
m_optixContext,
&miss_prog_group_desc,
1, // num program groups
&program_group_options,
logString, &logStringSize,
&m_miss_prog_group
);
// hitgroup program
hitgroup_prog_group_desc.kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP;
hitgroup_prog_group_desc.hitgroup.moduleCH = module;
hitgroup_prog_group_desc.hitgroup.entryFunctionNameCH = "__closesthit__renderVolume";
hitgroup_prog_group_desc.hitgroup.moduleAH = nullptr;
hitgroup_prog_group_desc.hitgroup.entryFunctionNameAH = nullptr;
hitgroup_prog_group_desc.hitgroup.moduleIS = nullptr;//intersectionModule;
hitgroup_prog_group_desc.hitgroup.entryFunctionNameIS = nullptr;
optixProgramGroupCreate(
m_optixContext,
&hitgroup_prog_group_desc,
1, // num program groups
&program_group_options,
logString, &logStringSize,
&m_hitgroup_prog_group
);
const uint32_t max_trace_depth = 1;
OptixProgramGroup program_groups[] = { m_raygen_prog_group, m_miss_prog_group, m_hitgroup_prog_group };
// pipeline create
OptixPipelineLinkOptions pipeline_link_options = {};
pipeline_link_options.maxTraceDepth = max_trace_depth;
optixPipelineCreate(
m_optixContext,
&pipeline_compile_options,
&pipeline_link_options,
program_groups,
sizeof(program_groups) / sizeof(program_groups[0]),
logString, &logStringSize,
&m_pipeline
);
// set stack size
OptixStackSizes stack_sizes = {};
for (auto& prog_group : program_groups)
{
util::OPTIX_CHECK(
optixUtilAccumulateStackSizes(prog_group, &stack_sizes, m_pipeline),
log, std::string(__FILE__) + " : " + std::to_string(__LINE__) + " " + "optixUtilAccumulateStackSizes"
);
}
uint32_t direct_callable_stack_size_from_traversal;
uint32_t direct_callable_stack_size_from_state;
uint32_t continuation_stack_size;
optixUtilComputeStackSizes(
&stack_sizes, max_trace_depth,
0, // maxCCDepth
0, // maxDCDEpth
&direct_callable_stack_size_from_traversal,
&direct_callable_stack_size_from_state, &continuation_stack_size
);
optixPipelineSetStackSize(
m_pipeline, direct_callable_stack_size_from_traversal,
direct_callable_stack_size_from_state, continuation_stack_size,
1 // maxTraversableDepth
);
// SBT setup
CUdeviceptr raygen_record;
const size_t raygen_record_size = sizeof(RayGenSbtRecord);
cudaMalloc(reinterpret_cast<void**>(&raygen_record), raygen_record_size),
RayGenSbtRecord rg_sbt;
optixSbtRecordPackHeader(m_raygen_prog_group, &rg_sbt),
cudaMemcpy(
reinterpret_cast<void*>(raygen_record),
&rg_sbt,
raygen_record_size,
cudaMemcpyHostToDevice
);
CUdeviceptr miss_record;
size_t miss_record_size = sizeof(MissSbtRecord);
cudaMalloc(reinterpret_cast<void**>(&miss_record), miss_record_size),
MissSbtRecord ms_sbt;
optixSbtRecordPackHeader(m_miss_prog_group, &ms_sbt),
cudaMemcpy(
reinterpret_cast<void*>(miss_record),
&ms_sbt,
miss_record_size,
cudaMemcpyHostToDevice
);
CUdeviceptr hitgroup_record;
size_t hitgroup_record_size = sizeof(HitGroupSbtRecord);
cudaMalloc(reinterpret_cast<void**>(&hitgroup_record), hitgroup_record_size),
HitGroupSbtRecord hg_sbt;
optixSbtRecordPackHeader(m_hitgroup_prog_group, &hg_sbt),
cudaMemcpy(
reinterpret_cast<void*>(hitgroup_record),
&hg_sbt,
hitgroup_record_size,
cudaMemcpyHostToDevice
);
m_sbt.raygenRecord = raygen_record;
m_sbt.missRecordBase = miss_record;
m_sbt.missRecordStrideInBytes = sizeof(MissSbtRecord);
m_sbt.missRecordCount = 1;
m_sbt.hitgroupRecordBase = hitgroup_record;
m_sbt.hitgroupRecordStrideInBytes = sizeof(HitGroupSbtRecord);
m_sbt.hitgroupRecordCount = 1;
// optix launch
optixLaunch(
m_pipeline, 0, m_d_params, sizeof(OptixParams), &m_sbt,
m_params.activeCamera.imageWidth, m_params.activeCamera.imageHeight, /*depth=*/1
);