@@ -187,6 +187,7 @@ void OptixRenderer::render()
187187
188188 // Handle light-related parameters safely to prevent null pointer access
189189 m_systemParameter.lights = scene.m_lights ;
190+ m_systemParameter.numLights = scene.m_numLights ;
190191 m_systemParameter.lightAliasTable = scene.d_lightAliasTable ;
191192 m_systemParameter.instanceLightMapping = scene.d_instanceLightMapping ;
192193 m_systemParameter.numInstancedLightMesh = scene.numInstancedLightMesh ;
@@ -198,13 +199,22 @@ void OptixRenderer::render()
198199
199200 CUDA_CHECK (cudaMemcpyAsync ((void *)m_d_systemParameter, &m_systemParameter, sizeof (SystemParameter), cudaMemcpyHostToDevice, backend.getCudaStream ()));
200201
202+ // Debug: Check for errors before OptixLaunch
203+ CUDA_CHECK (cudaPeekAtLastError ());
204+
201205 // Only launch OptixLaunch if we have a valid top object (scene is not empty)
202206 if (m_systemParameter.topObject != 0 ) {
203207 OPTIX_CHECK (m_api.optixLaunch (m_pipeline, backend.getCudaStream (), (CUdeviceptr)m_d_systemParameter, sizeof (SystemParameter), &m_sbt, m_width, m_height, 1 ));
208+
209+ // Check immediately after OptixLaunch with device sync
210+ CUDA_CHECK (cudaDeviceSynchronize ());
211+ cudaError_t err = cudaPeekAtLastError ();
212+ if (err != cudaSuccess) {
213+ std::cout << " ERROR: OptixLaunch kernels failed with CUDA error: " << cudaGetErrorString (err) << std::endl;
214+ }
204215 }
205216
206217 CUDA_CHECK (cudaStreamSynchronize (backend.getCudaStream ()));
207-
208218 CUDA_CHECK (cudaDeviceSynchronize ());
209219 CUDA_CHECK (cudaPeekAtLastError ());
210220
@@ -317,6 +327,10 @@ void OptixRenderer::updateAnimatedEntities(CUstream cudaStream, float currentTim
317327 unsigned int sbtIndex = entitySbtOffset + rayType;
318328 m_sbtRecordGeometryInstanceData[sbtIndex].data .indices = (Int3 *)geometry.indices ;
319329 m_sbtRecordGeometryInstanceData[sbtIndex].data .attributes = (VertexAttributes *)geometry.attributes ;
330+
331+ // CRITICAL FIX: Add bounds information to prevent illegal memory access
332+ m_sbtRecordGeometryInstanceData[sbtIndex].data .numIndices = geometry.numIndices / 3 ; // Convert to triangle count
333+ m_sbtRecordGeometryInstanceData[sbtIndex].data .numAttributes = geometry.numAttributes ;
320334 }
321335 }
322336 }
@@ -592,6 +606,10 @@ void OptixRenderer::update()
592606 {
593607 m_sbtRecordGeometryInstanceData[sbtIndex + rayType].data .indices = (Int3 *)geometry.indices ;
594608 m_sbtRecordGeometryInstanceData[sbtIndex + rayType].data .attributes = (VertexAttributes *)geometry.attributes ;
609+
610+ // CRITICAL FIX: Add bounds information to prevent illegal memory access
611+ m_sbtRecordGeometryInstanceData[sbtIndex + rayType].data .numIndices = geometry.numIndices / 3 ; // Convert to triangle count
612+ m_sbtRecordGeometryInstanceData[sbtIndex + rayType].data .numAttributes = geometry.numAttributes ;
595613 }
596614 }
597615 }
@@ -704,6 +722,10 @@ void OptixRenderer::update()
704722 {
705723 m_sbtRecordGeometryInstanceData[sbtIndex + rayType].data .indices = (Int3 *)geometry.indices ;
706724 m_sbtRecordGeometryInstanceData[sbtIndex + rayType].data .attributes = (VertexAttributes *)geometry.attributes ;
725+
726+ // CRITICAL FIX: Add bounds information to prevent illegal memory access
727+ m_sbtRecordGeometryInstanceData[sbtIndex + rayType].data .numIndices = geometry.numIndices / 3 ; // Convert to triangle count
728+ m_sbtRecordGeometryInstanceData[sbtIndex + rayType].data .numAttributes = geometry.numAttributes ;
707729 }
708730 }
709731 }
@@ -1467,6 +1489,12 @@ void OptixRenderer::init()
14671489 {
14681490 unsigned int geometryIndex = chunkIndex * scene.uninstancedGeometryCount + objectId;
14691491
1492+ // Skip SBT creation if geometry has null pointers (empty geometry)
1493+ assert (geometryIndex < m_geometries.size ());
1494+ if (m_geometries[geometryIndex].indices == nullptr || m_geometries[geometryIndex].attributes == nullptr ) {
1495+ continue ; // Skip this geometry, no SBT records created
1496+ }
1497+
14701498 for (unsigned int rayType = 0 ; rayType < numTypesOfRays; ++rayType)
14711499 {
14721500 if (rayType == 0 )
@@ -1478,10 +1506,16 @@ void OptixRenderer::init()
14781506 memcpy (m_sbtRecordGeometryInstanceData[sbtRecordIndex].header , m_sbtRecordHitShadow.header , OPTIX_SBT_RECORD_HEADER_SIZE);
14791507 }
14801508
1481- assert (geometryIndex < m_geometries.size ());
14821509 m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .indices = (Int3 *)m_geometries[geometryIndex].indices ;
14831510 m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .attributes = (VertexAttributes *)m_geometries[geometryIndex].attributes ;
1484- m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .materialIndex = objectId;
1511+
1512+ // CRITICAL FIX: Add bounds information to prevent illegal memory access
1513+ m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .numIndices = m_geometries[geometryIndex].numIndices / 3 ; // Convert to triangle count
1514+ m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .numAttributes = m_geometries[geometryIndex].numAttributes ;
1515+
1516+ // Map objectId to material index (objectId 1->16 maps to material index 0->15)
1517+ unsigned int materialIndex = (objectId >= 1 ) ? (objectId - 1 ) : 0 ;
1518+ m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .materialIndex = materialIndex;
14851519 sbtRecordIndex++;
14861520 }
14871521 }
@@ -1495,6 +1529,12 @@ void OptixRenderer::init()
14951529 // Instanced geometries are stored after all chunk-based geometries
14961530 unsigned int geometryIndex = scene.numChunks * scene.uninstancedGeometryCount + (objectId - GetInstancedObjectIdBegin ());
14971531
1532+ // Skip SBT creation if geometry has null pointers (empty geometry)
1533+ assert (geometryIndex < m_geometries.size ());
1534+ if (m_geometries[geometryIndex].indices == nullptr || m_geometries[geometryIndex].attributes == nullptr ) {
1535+ continue ; // Skip this geometry, no SBT records created
1536+ }
1537+
14981538 for (unsigned int rayType = 0 ; rayType < numTypesOfRays; ++rayType)
14991539 {
15001540 if (rayType == 0 )
@@ -1506,10 +1546,16 @@ void OptixRenderer::init()
15061546 memcpy (m_sbtRecordGeometryInstanceData[sbtRecordIndex].header , m_sbtRecordHitShadow.header , OPTIX_SBT_RECORD_HEADER_SIZE);
15071547 }
15081548
1509- assert (geometryIndex < m_geometries.size ());
15101549 m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .indices = (Int3 *)m_geometries[geometryIndex].indices ;
15111550 m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .attributes = (VertexAttributes *)m_geometries[geometryIndex].attributes ;
1512- m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .materialIndex = objectId;
1551+
1552+ // CRITICAL FIX: Add bounds information to prevent illegal memory access
1553+ m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .numIndices = m_geometries[geometryIndex].numIndices / 3 ; // Convert to triangle count
1554+ m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .numAttributes = m_geometries[geometryIndex].numAttributes ;
1555+
1556+ // Map objectId to material index (objectId 1->16 maps to material index 0->15)
1557+ unsigned int materialIndex = (objectId >= 1 ) ? (objectId - 1 ) : 0 ;
1558+ m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .materialIndex = materialIndex;
15131559 sbtRecordIndex++;
15141560 }
15151561 }
@@ -1538,6 +1584,11 @@ void OptixRenderer::init()
15381584 assert (geometryIndex < m_geometries.size ());
15391585 m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .indices = (Int3 *)m_geometries[geometryIndex].indices ;
15401586 m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .attributes = (VertexAttributes *)m_geometries[geometryIndex].attributes ;
1587+
1588+ // CRITICAL FIX: Add bounds information to prevent illegal memory access
1589+ m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .numIndices = m_geometries[geometryIndex].numIndices / 3 ; // Convert to triangle count
1590+ m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .numAttributes = m_geometries[geometryIndex].numAttributes ;
1591+
15411592 // Use the correct material index for entities from the material array
15421593 unsigned int entityMaterialIndex = m_entityMaterialStartIndex + static_cast <unsigned int >(entity->getType ());
15431594 m_sbtRecordGeometryInstanceData[sbtRecordIndex].data .materialIndex = entityMaterialIndex;
@@ -1592,6 +1643,9 @@ void OptixRenderer::init()
15921643 {
15931644 CUDA_CHECK (cudaMalloc ((void **)&m_systemParameter.materialParameters , sizeof (MaterialParameter) * m_materialParameters.size ()));
15941645 CUDA_CHECK (cudaMemcpyAsync ((void *)m_systemParameter.materialParameters , m_materialParameters.data (), sizeof (MaterialParameter) * m_materialParameters.size (), cudaMemcpyHostToDevice, Backend::Get ().getCudaStream ()));
1646+
1647+ // Set the number of material parameters for bounds checking
1648+ m_systemParameter.numMaterialParameters = (unsigned int )m_materialParameters.size ();
15951649
15961650 CUDA_CHECK (cudaMalloc ((void **)&m_d_systemParameter, sizeof (SystemParameter)));
15971651 CUDA_CHECK (cudaMemcpyAsync ((void *)m_d_systemParameter, &m_systemParameter, sizeof (SystemParameter), cudaMemcpyHostToDevice, Backend::Get ().getCudaStream ()));
0 commit comments