| 207 | } |
| 208 | |
| 209 | bool VulkanStatsProvider::create_query_pools(uint32_t queue_family_index) |
| 210 | { |
| 211 | vkb::core::DeviceC &device = render_context.get_device(); |
| 212 | vkb::core::PhysicalDeviceC const &gpu = device.get_gpu(); |
| 213 | uint32_t num_framebuffers = static_cast<uint32_t>(render_context.get_render_frames().size()); |
| 214 | |
| 215 | // Now we know the available counters, we can build a query pool that will collect them. |
| 216 | // We will check that the counters can be collected in a single pass. Multi-pass would |
| 217 | // be a big performance hit so for these samples, we don't want to use it. |
| 218 | VkQueryPoolPerformanceCreateInfoKHR perf_create_info{}; |
| 219 | perf_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR; |
| 220 | perf_create_info.queueFamilyIndex = queue_family_index; |
| 221 | perf_create_info.counterIndexCount = static_cast<uint32_t>(counter_indices.size()); |
| 222 | perf_create_info.pCounterIndices = counter_indices.data(); |
| 223 | |
| 224 | uint32_t passes_needed = gpu.get_queue_family_performance_query_passes(&perf_create_info); |
| 225 | if (passes_needed != 1) |
| 226 | { |
| 227 | // Needs more than one pass, remove all our supported stats |
| 228 | LOGW("Requested Vulkan stats require multiple passes, we won't collect them"); |
| 229 | return false; |
| 230 | } |
| 231 | |
| 232 | // We will need a query pool to report the stats back to us |
| 233 | VkQueryPoolCreateInfo pool_create_info{}; |
| 234 | pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; |
| 235 | pool_create_info.pNext = &perf_create_info; |
| 236 | pool_create_info.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR; |
| 237 | pool_create_info.queryCount = num_framebuffers; |
| 238 | |
| 239 | query_pool = std::make_unique<QueryPool>(device, pool_create_info); |
| 240 | |
| 241 | if (!query_pool) |
| 242 | { |
| 243 | LOGW("Failed to create performance query pool"); |
| 244 | return false; |
| 245 | } |
| 246 | |
| 247 | // Reset the query pool before first use. We cannot do these in the command buffer |
| 248 | // as that is invalid usage for performance queries due to the potential for multiple |
| 249 | // passes being required. |
| 250 | query_pool->host_reset(0, num_framebuffers); |
| 251 | |
| 252 | if (has_timestamps) |
| 253 | { |
| 254 | // If we support timestamp queries we will use those to more accurately measure |
| 255 | // the time spent executing a command buffer than just a frame-to-frame timer |
| 256 | // in software. |
| 257 | VkQueryPoolCreateInfo timestamp_pool_create_info{}; |
| 258 | timestamp_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; |
| 259 | timestamp_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP; |
| 260 | timestamp_pool_create_info.queryCount = num_framebuffers * 2; // 2 timestamps per frame (start & end) |
| 261 | |
| 262 | timestamp_pool = std::make_unique<QueryPool>(device, timestamp_pool_create_info); |
| 263 | } |
| 264 | |
| 265 | return true; |
| 266 | } |
nothing calls this directly
no test coverage detected