Invalid vertex buffer size when using rtContextLaunchProgressive2D

Hello,

I am trying to render particle data with ambient occlusion using Optix progressive launches. As starting point my code is based on the optixProgressiveVCA example, removing the remote features and adding more spheres.

Instead of creating a geometry for just one sphere, I am creating a vertex buffer containing the position and radius of each particle:

m_posBuffer = m_context->createBuffer( RT_BUFFER_INPUT, RT_FORMAT_FLOAT4, NUM_PARTICLES );
float4*	positions = reinterpret_cast<float4*>(m_posBuffer->map());

for( unsigned int i = 0; i < NUM_PARTICLES; i+=4 )
{
   positions->x	= rand ()/(RAND_MAX*1.0f) * NUM_PARTICLES / 10.0f - NUM_PARTICLES / 10.0f;;
   positions->y = rand ()/(RAND_MAX*1.0f) * NUM_PARTICLES / 10.0f - NUM_PARTICLES / 10.0f;;
   positions->z = rand ()/(RAND_MAX*1.0f) * NUM_PARTICLES / 10.0f - NUM_PARTICLES / 10.0f;;
   positions->w = 1.0f;
   }
m_posBuffer->unmap();

Then I create the geometry holding that buffer, the geometry instance and the root group:

Geometry particles = m_context->createGeometry();
particles->setPrimitiveCount(NUM_PARTICLES);
particles->setBoundingBoxProgram( m_context->createProgramFromPTXFile( "shaders/spheres.ptx", "bounds" ) );
particles->setIntersectionProgram( m_context->createProgramFromPTXFile( "shaders/spheres.ptx", "intersect" ) );
particles["vertex_buffer"]->setBuffer ( m_posBuffer );

GeometryInstance gi = m_context->createGeometryInstance();
gi->setGeometry( particles );
gi->setMaterialCount( 1 );
gi->setMaterial( 0, m_material ); 

	
GeometryGroup geometrygroup = m_context->createGeometryGroup();
geometrygroup->setChildCount( 1 );
geometrygroup->setChild( 0, gi );

Acceleration accel = m_context->createAcceleration("Trbvh");
accel->setProperty("vertex_buffer_name", "vertex_buffer");
geometrygroup->setAcceleration( accel);

m_context["top_object"]->set( geometrygroup );

the material is from the optixProgressiveVCA’s ambient occlusion shader.

Finally I’ve modified the sphere shader from the optixProgressiveVCA example by adding the vertex buffer and receive the primitive idx in the corresponding methods:

...
rtBuffer<float4>	vertex_buffer;
...
template<bool use_robust_method>
static __device__
void intersect_sphere(int primIdx)
{
	const float4	lookUp 	= vertex_buffer[primIdx];
	const float3	center 	= make_float3 (lookUp);
	const float	radius 	= lookUp.w;
...
}

RT_PROGRAM void intersect(int primIdx)
{
	//rtPrintf( "primIdx %d", primIdx);
  intersect_sphere<false>( primIdx );
}

RT_PROGRAM void robust_intersect(int primIdx)
{
  intersect_sphere<true>( primIdx );
}

RT_PROGRAM void bounds (int primIdx, float result[6])
{
	//rtPrintf( "primIdx %d", primIdx);
//	const int 		idx		= index_buffer[primIdx];
	const float4	lookUp 	= vertex_buffer[primIdx];
	const float3	center 	= make_float3 (lookUp);
	const float		radius 	= lookUp.w;
...
}

Validating the context shows no error, but when running the application is I got:

Invalid value (Details: Function “RTresult _rtContextLaunchProgressive2D(RTcontext, unsigned int, RTsize, RTsize, unsigned int)” caught exception: Invalid vertex buffer size. Possible reasons: stride too large with no index buffer.)

I guess I am missing something in the set-up, I checked the swimmingShark example in Optix 3.8 that renders a set of bubbles but can’t find what. Any leads would be very useful.

Thanks!

Benjamin

Using:

Titan-Z GPU (Kepler)
Driver Version: 367.57
CUDA 8.0
Optix 4.0.2
Ubuntu 16

Looking at the first code block, that is not doing what you intended at all.
Try this:

m_posBuffer = m_context->createBuffer( RT_BUFFER_INPUT, RT_FORMAT_FLOAT4, NUM_PARTICLES ); // Buffer is float4. .xyz = position, .w = radius
float4*	positions = reinterpret_cast<float4*>(m_posBuffer->map()); // Interpreted as float4.
const float s = float(NUM_PARTICLES) / 10.0f; // Performance: Calculate once outside the loop.
for( unsigned int i = 0; i < NUM_PARTICLES; ++i ) // The loop needs to be exercised NUM_PARTICLES times. 
{
  positions->x = float(rand()) / float(RAND_MAX) * s - s;
  positions->y = float(rand()) / float(RAND_MAX) * s - s;
  positions->z = float(rand()) / float(RAND_MAX) * s - s;
  positions->w = 1.0f;
  ++positions; // Next float4 sphere definition.
}
m_posBuffer->unmap();

Then the main problem should be this:
accel->setProperty(“vertex_buffer_name”, “vertex_buffer”);

Please have a look into the OptiX Programming Guide Chapter 3.5 Acceleration Structures for Ray Tracing, esp. section 3.5.3 Properties.
Setting the vertex_buffer_name in a Trbvh acceleration structure builder is meant to tell the builder that the vertex data is containing triangle data in a specific layout which could help to speed up the acceleration structure build time.

Since you’re not using triangles at all, this would be incorrect to do. Instead I would recommend to remove that line and additionally rename the vertex_buffer variable to sphere_buffer for more clarity and to avoid clashing with that optimization mechanism.

Note that using rtContextLaunchProgressive2D() without actually using a remote device is only meant for local debugging purposes until deploying it on a remote device like the NVIDIA VCA.
You can achieve faster accumulation times on a local system when implementing that step in your ray generation program manually.
Find some simple example code here: https://devtalk.nvidia.com/default/topic/937885/?comment=4891565

Hello Detlef,

Thanks for the quick response.

By adding the increment to the position pointer, changing the buffer name and removing the suggested line:

accel->setProperty(“vertex_buffer_name”, “vertex_buffer”);

the error have gone. Thanks for the recommendation to get faster accumulation times, but we will also need remote capabilities, I’ll post another question on this.

Regards,

Benjamin