VK_NV_raytracing: Cannot create bottom level AS with two kinds of geometries

I try filling BLAS creation info with the following:

VkGeometryTrianglesNV trias = {};
	trias.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
	trias.indexCount = uint32_t(m_model_indices.size());
	trias.indexData = m_index_buffer;
	trias.indexOffset = 0;
	trias.indexType = VK_INDEX_TYPE_UINT32;
	trias.vertexCount = uint32_t(m_model_vertices.size());
	trias.vertexData = m_vertex_buffer;
	trias.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
	trias.vertexOffset = 0;
	trias.vertexStride = sizeof(Vertex);
	trias.transformData = VK_NULL_HANDLE;

	VkGeometryAABBNV spheres = {};
	spheres.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
	spheres.aabbData = m_sphere_buffer;
	spheres.numAABBs = uint32_t(m_sphere_primitives.size());
	spheres.stride = sizeof(SpherePrimitive);
	spheres.offset = 0;

	VkGeometryNV g[2] = {};
	
	g[0].sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
	g[0].flags = VK_GEOMETRY_OPAQUE_BIT_NV;
	g[0].geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
	g[0].geometry.triangles = trias;
	g[0].geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
	g[0].geometry.aabbs.numAABBs = 0;

	g[1].sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
	g[1].flags = VK_GEOMETRY_OPAQUE_BIT_NV;
	g[1].geometryType = VK_GEOMETRY_TYPE_AABBS_NV;
	g[1].geometry.aabbs = spheres;
	g[1].geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
	g[1].geometry.triangles.vertexCount = 0;
	g[1].geometry.triangles.indexCount = 0;
	
	VkAccelerationStructureInfoNV si = {};
	si.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
	si.instanceCount = 0;
	si.geometryCount = 2;
	si.pGeometries = &g[0];
	si.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;

But when i request the memory requirements for the scratch buffer i get zero.
If i change geometryCount and pGeometries in VkAccelerationStructureInfoNV and point to only one of the two geometries then i get the right memory requirements.

I have an RTX 2070 GPU and the OS is Windows 10.
Driver version: 417.35

Thanks in advance.

I don’t think you are allowed to mix triangles and AABBs in the same bottom level acceleration structure.

Did you ever manage to get your application working with AABBs and procedural geometry?

VkAccelerationStructureInfoNV contains the member pGeometries and the procedural geometry is another instance of VkGeometryNV. I have not seen any prohibition in the Vulkan spec. Maybe i missed something or it is not clear enough. Either way yes i managed to get an app with AABBs and procedural geometry working.
You can find it here: https://github.com/georgeouzou/vk_exp

Thanks for the github link. It helps to see another implementation and a different approach when debugging mine.

I know the bottom level acceleration structure API accepts both (and the C signature technically doesn’t prevent you from providing triangles and AABB geometries at the same time). But it does smell fishy with respect to hit groups that can only be specified at the top level AS and their role with hit group shaders.

It feels like the specification needs clarification. It’s not quite clear to me also if it’s valid to have a hit shader group that handles both triangles and AABBs at the same time.

Given that in practice the HitAttribute used to communicate between the intersection and closest-hit shaders are quite different between triangles (vec2 barrycentrics) and procedurals (whatever you want), it feel like putting the triangles and AABBs in separate bottom level acceleration structures is the right approach.

@gouz, i have run into a “zero memory requirement” error too, but in a different area of building AS. RTX reports a zero update memory scratch size for compressed AS. Have you tried to conservatively guess the correct size of the memory and then let it build? That did the trick for my problem, that is you can in fact update compressed AS.

Regards

@gouz just tested it myself, and it does build, but does not show, so i guess this is a double bug.

@GPSnoopy you cannot specify both in the same geometry, but you should be able to have multiple geometries that mix triangles and aabbs in the same AS. The hit group in the top level is an offset into the SBT, and the traceNV in the shader supplies the stride for geometries. So you can in fact have different hit groups for different geometries. In fact that is pretty standard if you consider baking static models with a bunch of different diffuse textures into one AS. Each geometry would represent one “texture group” and have different SBT entries that contain the index into a texture array.

Regards

@virtual_storm Thanks i will try this again, working around the “zero memory requirement”
I tried to get it working with multiple geometries and using the offsets in traceNV as you mention but i could not create the combined BLAS.

It is clear that it is impossible to create mixed-type BLAS if you look at type definitions in vulkan header. VkGeometryTypeNV is not a bit mask. It has only two possible values, which occupies only the same single bit: VK_GEOMETRY_TYPE_TRIANGLES_NV = 0 and VK_GEOMETRY_TYPE_AABBS_NV = 1. You cannot combine them using bitwise OR when fill VkGeometryNV.geometryType with value. There is no variant data type in C, so VkGeometryDataNV contains both structures, one of them is the only active – I think this is the reason.