| 2321 | } |
| 2322 | |
| 2323 | void Pipeline::BuildSbt() { |
| 2324 | // As of now, no function support if not using any ray generation shader |
| 2325 | assert(GetRayGenShaderGroupsCount() > 0); |
| 2326 | |
| 2327 | // Gather shader indices |
| 2328 | // --- |
| 2329 | // Used this as reference: |
| 2330 | // https://github.com/nvpro-samples/nvpro_core/blob/ba24b73e3a918adfe6ca932a6bf749a1d874d9b0/nvvk/sbtwrapper_vk.cpp#L81 |
| 2331 | std::vector<uint32_t> ray_gen_group_handle_indices; |
| 2332 | std::vector<uint32_t> miss_group_handle_indices; |
| 2333 | std::vector<uint32_t> hit_group_handle_indices; |
| 2334 | |
| 2335 | uint32_t shader_i = 0; |
| 2336 | for (uint32_t ray_gen_i = 0; ray_gen_i < size32(ray_gen_shaders_); ++ray_gen_i) { |
| 2337 | ray_gen_group_handle_indices.emplace_back(shader_i++); |
| 2338 | } |
| 2339 | for (uint32_t miss_i = 0; miss_i < size32(miss_shaders_); ++miss_i) { |
| 2340 | miss_group_handle_indices.emplace_back(shader_i++); |
| 2341 | } |
| 2342 | for (uint32_t hit_i = 0; hit_i < (size32(hit_shaders_)); ++hit_i) { |
| 2343 | hit_group_handle_indices.emplace_back(shader_i++); |
| 2344 | } |
| 2345 | |
| 2346 | for (const Pipeline* lib : libraries_) { |
| 2347 | for (uint32_t ray_gen_i = 0; ray_gen_i < size32(lib->ray_gen_shaders_); ++ray_gen_i) { |
| 2348 | ray_gen_group_handle_indices.emplace_back(shader_i++); |
| 2349 | } |
| 2350 | for (uint32_t miss_i = 0; miss_i < size32(lib->miss_shaders_); ++miss_i) { |
| 2351 | miss_group_handle_indices.emplace_back(shader_i++); |
| 2352 | } |
| 2353 | for (uint32_t hit_i = 0; hit_i < (size32(lib->hit_shaders_)); ++hit_i) { |
| 2354 | hit_group_handle_indices.emplace_back(shader_i++); |
| 2355 | } |
| 2356 | } |
| 2357 | |
| 2358 | VkPhysicalDeviceRayTracingPipelinePropertiesKHR rt_pipeline_props = vku::InitStructHelper(); |
| 2359 | test_.GetPhysicalDeviceProperties2(rt_pipeline_props); |
| 2360 | const uint32_t sbt_shader_size = rt_pipeline_props.shaderGroupHandleSize + shader_record_size_; |
| 2361 | const uint32_t sbt_shader_size_aligned = Align(sbt_shader_size, rt_pipeline_props.shaderGroupHandleAlignment); |
| 2362 | |
| 2363 | // Since every ray generation entry in the ray tracing shader headers buffer can be the start of the ray gen SBT, |
| 2364 | // they all have to be aligned to shaderGroupBaseAlignment (which may be smaller than the handle size) |
| 2365 | const VkDeviceSize ray_gen_shaders_sbt_entry_byte_size = |
| 2366 | GetRayGenShaderGroupsCount() * Align(sbt_shader_size, rt_pipeline_props.shaderGroupBaseAlignment); |
| 2367 | // For miss and closest hit shaders, we consider that the corresponding SBTs always start at the first miss/closest hit entry |
| 2368 | // => only it needs to be aligned to shaderGroupBaseAlignment, |
| 2369 | // and within miss/closes hit entries alignment is shaderGroupHandleAlignment |
| 2370 | const VkDeviceSize miss_shaders_sbt_entry_byte_size = GetMissShaderGroupsCount() * sbt_shader_size_aligned; |
| 2371 | const VkDeviceSize hit_shaders_sbt_entry_byte_size = GetHitShaderGroupsCount() * sbt_shader_size_aligned; |
| 2372 | VkDeviceSize sbt_buffer_size = ray_gen_shaders_sbt_entry_byte_size; |
| 2373 | sbt_buffer_size = Align<VkDeviceSize>(sbt_buffer_size, rt_pipeline_props.shaderGroupBaseAlignment); |
| 2374 | sbt_buffer_size += miss_shaders_sbt_entry_byte_size; |
| 2375 | sbt_buffer_size = Align<VkDeviceSize>(sbt_buffer_size, rt_pipeline_props.shaderGroupBaseAlignment); |
| 2376 | sbt_buffer_size += hit_shaders_sbt_entry_byte_size; |
| 2377 | |
| 2378 | // Allocate buffer to store SBT, and fill it with sbt_host_storage |
| 2379 | VkBufferCreateInfo sbt_buffer_info = vku::InitStructHelper(); |
| 2380 |
nothing calls this directly
no test coverage detected