1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2020 Raspberry Pi Ltd 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "v3dv_private.h" 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "util/timespec.h" 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_cistatic const char *v3dv_counters[][3] = { 29bf215546Sopenharmony_ci {"FEP", "FEP-valid-primitives-no-rendered-pixels", "[FEP] Valid primitives that result in no rendered pixels, for all rendered tiles"}, 30bf215546Sopenharmony_ci {"FEP", "FEP-valid-primitives-rendered-pixels", "[FEP] Valid primitives for all rendered tiles (primitives may be counted in more than one tile)"}, 31bf215546Sopenharmony_ci {"FEP", "FEP-clipped-quads", "[FEP] Early-Z/Near/Far clipped quads"}, 32bf215546Sopenharmony_ci {"FEP", "FEP-valid-quads", "[FEP] Valid quads"}, 33bf215546Sopenharmony_ci {"TLB", "TLB-quads-not-passing-stencil-test", "[TLB] Quads with no pixels passing the stencil test"}, 34bf215546Sopenharmony_ci {"TLB", "TLB-quads-not-passing-z-and-stencil-test", "[TLB] Quads with no pixels passing the Z and stencil tests"}, 35bf215546Sopenharmony_ci {"TLB", "TLB-quads-passing-z-and-stencil-test", "[TLB] Quads with any pixels passing the Z and stencil tests"}, 36bf215546Sopenharmony_ci {"TLB", "TLB-quads-with-zero-coverage", "[TLB] Quads with all pixels having zero coverage"}, 37bf215546Sopenharmony_ci {"TLB", "TLB-quads-with-non-zero-coverage", "[TLB] Quads with any pixels having non-zero coverage"}, 38bf215546Sopenharmony_ci {"TLB", "TLB-quads-written-to-color-buffer", "[TLB] Quads with valid pixels written to colour buffer"}, 39bf215546Sopenharmony_ci {"PTB", "PTB-primitives-discarded-outside-viewport", "[PTB] Primitives discarded by being outside the viewport"}, 40bf215546Sopenharmony_ci {"PTB", "PTB-primitives-need-clipping", "[PTB] Primitives that need clipping"}, 41bf215546Sopenharmony_ci {"PTB", "PTB-primitives-discared-reversed", "[PTB] Primitives that are discarded because they are reversed"}, 42bf215546Sopenharmony_ci {"QPU", "QPU-total-idle-clk-cycles", "[QPU] Total idle clock cycles for all QPUs"}, 43bf215546Sopenharmony_ci {"QPU", "QPU-total-active-clk-cycles-vertex-coord-shading", "[QPU] Total active clock cycles for all QPUs doing vertex/coordinate/user shading (counts only when QPU is not stalled)"}, 44bf215546Sopenharmony_ci {"QPU", "QPU-total-active-clk-cycles-fragment-shading", "[QPU] Total active clock cycles for all QPUs doing fragment shading (counts only when QPU is not stalled)"}, 45bf215546Sopenharmony_ci {"QPU", "QPU-total-clk-cycles-executing-valid-instr", "[QPU] Total clock cycles for all QPUs executing valid instructions"}, 46bf215546Sopenharmony_ci {"QPU", "QPU-total-clk-cycles-waiting-TMU", "[QPU] Total clock cycles for all QPUs stalled waiting for TMUs only (counter won't increment if QPU also stalling for another reason)"}, 47bf215546Sopenharmony_ci {"QPU", "QPU-total-clk-cycles-waiting-scoreboard", "[QPU] Total clock cycles for all QPUs stalled waiting for Scoreboard only (counter won't increment if QPU also stalling for another reason)"}, 48bf215546Sopenharmony_ci {"QPU", "QPU-total-clk-cycles-waiting-varyings", "[QPU] Total clock cycles for all QPUs stalled waiting for Varyings only (counter won't increment if QPU also stalling for another reason)"}, 49bf215546Sopenharmony_ci {"QPU", "QPU-total-instr-cache-hit", "[QPU] Total instruction cache hits for all slices"}, 50bf215546Sopenharmony_ci {"QPU", "QPU-total-instr-cache-miss", "[QPU] Total instruction cache misses for all slices"}, 51bf215546Sopenharmony_ci {"QPU", "QPU-total-uniform-cache-hit", "[QPU] Total uniforms cache hits for all slices"}, 52bf215546Sopenharmony_ci {"QPU", "QPU-total-uniform-cache-miss", "[QPU] Total uniforms cache misses for all slices"}, 53bf215546Sopenharmony_ci {"TMU", "TMU-total-text-quads-access", "[TMU] Total texture cache accesses"}, 54bf215546Sopenharmony_ci {"TMU", "TMU-total-text-cache-miss", "[TMU] Total texture cache misses (number of fetches from memory/L2cache)"}, 55bf215546Sopenharmony_ci {"VPM", "VPM-total-clk-cycles-VDW-stalled", "[VPM] Total clock cycles VDW is stalled waiting for VPM access"}, 56bf215546Sopenharmony_ci {"VPM", "VPM-total-clk-cycles-VCD-stalled", "[VPM] Total clock cycles VCD is stalled waiting for VPM access"}, 57bf215546Sopenharmony_ci {"CLE", "CLE-bin-thread-active-cycles", "[CLE] Bin thread active cycles"}, 58bf215546Sopenharmony_ci {"CLE", "CLE-render-thread-active-cycles", "[CLE] Render thread active cycles"}, 59bf215546Sopenharmony_ci {"L2T", "L2T-total-cache-hit", "[L2T] Total Level 2 cache hits"}, 60bf215546Sopenharmony_ci {"L2T", "L2T-total-cache-miss", "[L2T] Total Level 2 cache misses"}, 61bf215546Sopenharmony_ci {"CORE", "cycle-count", "[CORE] Cycle counter"}, 62bf215546Sopenharmony_ci {"QPU", "QPU-total-clk-cycles-waiting-vertex-coord-shading", "[QPU] Total stalled clock cycles for all QPUs doing vertex/coordinate/user shading"}, 63bf215546Sopenharmony_ci {"QPU", "QPU-total-clk-cycles-waiting-fragment-shading", "[QPU] Total stalled clock cycles for all QPUs doing fragment shading"}, 64bf215546Sopenharmony_ci {"PTB", "PTB-primitives-binned", "[PTB] Total primitives binned"}, 65bf215546Sopenharmony_ci {"AXI", "AXI-writes-seen-watch-0", "[AXI] Writes seen by watch 0"}, 66bf215546Sopenharmony_ci {"AXI", "AXI-reads-seen-watch-0", "[AXI] Reads seen by watch 0"}, 67bf215546Sopenharmony_ci {"AXI", "AXI-writes-stalled-seen-watch-0", "[AXI] Write stalls seen by watch 0"}, 68bf215546Sopenharmony_ci {"AXI", "AXI-reads-stalled-seen-watch-0", "[AXI] Read stalls seen by watch 0"}, 69bf215546Sopenharmony_ci {"AXI", "AXI-write-bytes-seen-watch-0", "[AXI] Total bytes written seen by watch 0"}, 70bf215546Sopenharmony_ci {"AXI", "AXI-read-bytes-seen-watch-0", "[AXI] Total bytes read seen by watch 0"}, 71bf215546Sopenharmony_ci {"AXI", "AXI-writes-seen-watch-1", "[AXI] Writes seen by watch 1"}, 72bf215546Sopenharmony_ci {"AXI", "AXI-reads-seen-watch-1", "[AXI] Reads seen by watch 1"}, 73bf215546Sopenharmony_ci {"AXI", "AXI-writes-stalled-seen-watch-1", "[AXI] Write stalls seen by watch 1"}, 74bf215546Sopenharmony_ci {"AXI", "AXI-reads-stalled-seen-watch-1", "[AXI] Read stalls seen by watch 1"}, 75bf215546Sopenharmony_ci {"AXI", "AXI-write-bytes-seen-watch-1", "[AXI] Total bytes written seen by watch 1"}, 76bf215546Sopenharmony_ci {"AXI", "AXI-read-bytes-seen-watch-1", "[AXI] Total bytes read seen by watch 1"}, 77bf215546Sopenharmony_ci {"TLB", "TLB-partial-quads-written-to-color-buffer", "[TLB] Partial quads written to the colour buffer"}, 78bf215546Sopenharmony_ci {"TMU", "TMU-total-config-access", "[TMU] Total config accesses"}, 79bf215546Sopenharmony_ci {"L2T", "L2T-no-id-stalled", "[L2T] No ID stall"}, 80bf215546Sopenharmony_ci {"L2T", "L2T-command-queue-stalled", "[L2T] Command queue full stall"}, 81bf215546Sopenharmony_ci {"L2T", "L2T-TMU-writes", "[L2T] TMU write accesses"}, 82bf215546Sopenharmony_ci {"TMU", "TMU-active-cycles", "[TMU] Active cycles"}, 83bf215546Sopenharmony_ci {"TMU", "TMU-stalled-cycles", "[TMU] Stalled cycles"}, 84bf215546Sopenharmony_ci {"CLE", "CLE-thread-active-cycles", "[CLE] Bin or render thread active cycles"}, 85bf215546Sopenharmony_ci {"L2T", "L2T-TMU-reads", "[L2T] TMU read accesses"}, 86bf215546Sopenharmony_ci {"L2T", "L2T-CLE-reads", "[L2T] CLE read accesses"}, 87bf215546Sopenharmony_ci {"L2T", "L2T-VCD-reads", "[L2T] VCD read accesses"}, 88bf215546Sopenharmony_ci {"L2T", "L2T-TMU-config-reads", "[L2T] TMU CFG read accesses"}, 89bf215546Sopenharmony_ci {"L2T", "L2T-SLC0-reads", "[L2T] SLC0 read accesses"}, 90bf215546Sopenharmony_ci {"L2T", "L2T-SLC1-reads", "[L2T] SLC1 read accesses"}, 91bf215546Sopenharmony_ci {"L2T", "L2T-SLC2-reads", "[L2T] SLC2 read accesses"}, 92bf215546Sopenharmony_ci {"L2T", "L2T-TMU-write-miss", "[L2T] TMU write misses"}, 93bf215546Sopenharmony_ci {"L2T", "L2T-TMU-read-miss", "[L2T] TMU read misses"}, 94bf215546Sopenharmony_ci {"L2T", "L2T-CLE-read-miss", "[L2T] CLE read misses"}, 95bf215546Sopenharmony_ci {"L2T", "L2T-VCD-read-miss", "[L2T] VCD read misses"}, 96bf215546Sopenharmony_ci {"L2T", "L2T-TMU-config-read-miss", "[L2T] TMU CFG read misses"}, 97bf215546Sopenharmony_ci {"L2T", "L2T-SLC0-read-miss", "[L2T] SLC0 read misses"}, 98bf215546Sopenharmony_ci {"L2T", "L2T-SLC1-read-miss", "[L2T] SLC1 read misses"}, 99bf215546Sopenharmony_ci {"L2T", "L2T-SLC2-read-miss", "[L2T] SLC2 read misses"}, 100bf215546Sopenharmony_ci {"CORE", "core-memory-writes", "[CORE] Total memory writes"}, 101bf215546Sopenharmony_ci {"L2T", "L2T-memory-writes", "[L2T] Total memory writes"}, 102bf215546Sopenharmony_ci {"PTB", "PTB-memory-writes", "[PTB] Total memory writes"}, 103bf215546Sopenharmony_ci {"TLB", "TLB-memory-writes", "[TLB] Total memory writes"}, 104bf215546Sopenharmony_ci {"CORE", "core-memory-reads", "[CORE] Total memory reads"}, 105bf215546Sopenharmony_ci {"L2T", "L2T-memory-reads", "[L2T] Total memory reads"}, 106bf215546Sopenharmony_ci {"PTB", "PTB-memory-reads", "[PTB] Total memory reads"}, 107bf215546Sopenharmony_ci {"PSE", "PSE-memory-reads", "[PSE] Total memory reads"}, 108bf215546Sopenharmony_ci {"TLB", "TLB-memory-reads", "[TLB] Total memory reads"}, 109bf215546Sopenharmony_ci {"GMP", "GMP-memory-reads", "[GMP] Total memory reads"}, 110bf215546Sopenharmony_ci {"PTB", "PTB-memory-words-writes", "[PTB] Total memory words written"}, 111bf215546Sopenharmony_ci {"TLB", "TLB-memory-words-writes", "[TLB] Total memory words written"}, 112bf215546Sopenharmony_ci {"PSE", "PSE-memory-words-reads", "[PSE] Total memory words read"}, 113bf215546Sopenharmony_ci {"TLB", "TLB-memory-words-reads", "[TLB] Total memory words read"}, 114bf215546Sopenharmony_ci {"TMU", "TMU-MRU-hits", "[TMU] Total MRU hits"}, 115bf215546Sopenharmony_ci {"CORE", "compute-active-cycles", "[CORE] Compute active cycles"}, 116bf215546Sopenharmony_ci}; 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_cistatic void 119bf215546Sopenharmony_cikperfmon_create(struct v3dv_device *device, 120bf215546Sopenharmony_ci struct v3dv_query_pool *pool, 121bf215546Sopenharmony_ci uint32_t query) 122bf215546Sopenharmony_ci{ 123bf215546Sopenharmony_ci for (uint32_t i = 0; i < pool->perfmon.nperfmons; i++) { 124bf215546Sopenharmony_ci assert(i * DRM_V3D_MAX_PERF_COUNTERS < pool->perfmon.ncounters); 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci struct drm_v3d_perfmon_create req = { 127bf215546Sopenharmony_ci .ncounters = MIN2(pool->perfmon.ncounters - 128bf215546Sopenharmony_ci i * DRM_V3D_MAX_PERF_COUNTERS, 129bf215546Sopenharmony_ci DRM_V3D_MAX_PERF_COUNTERS), 130bf215546Sopenharmony_ci }; 131bf215546Sopenharmony_ci memcpy(req.counters, 132bf215546Sopenharmony_ci &pool->perfmon.counters[i * DRM_V3D_MAX_PERF_COUNTERS], 133bf215546Sopenharmony_ci req.ncounters); 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci int ret = v3dv_ioctl(device->pdevice->render_fd, 136bf215546Sopenharmony_ci DRM_IOCTL_V3D_PERFMON_CREATE, 137bf215546Sopenharmony_ci &req); 138bf215546Sopenharmony_ci if (ret) 139bf215546Sopenharmony_ci fprintf(stderr, "Failed to create perfmon: %s\n", strerror(ret)); 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci pool->queries[query].perf.kperfmon_ids[i] = req.id; 142bf215546Sopenharmony_ci } 143bf215546Sopenharmony_ci} 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_cistatic void 146bf215546Sopenharmony_cikperfmon_destroy(struct v3dv_device *device, 147bf215546Sopenharmony_ci struct v3dv_query_pool *pool, 148bf215546Sopenharmony_ci uint32_t query) 149bf215546Sopenharmony_ci{ 150bf215546Sopenharmony_ci /* Skip destroying if never created */ 151bf215546Sopenharmony_ci if (!pool->queries[query].perf.kperfmon_ids[0]) 152bf215546Sopenharmony_ci return; 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci for (uint32_t i = 0; i < pool->perfmon.nperfmons; i++) { 155bf215546Sopenharmony_ci struct drm_v3d_perfmon_destroy req = { 156bf215546Sopenharmony_ci .id = pool->queries[query].perf.kperfmon_ids[i] 157bf215546Sopenharmony_ci }; 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci int ret = v3dv_ioctl(device->pdevice->render_fd, 160bf215546Sopenharmony_ci DRM_IOCTL_V3D_PERFMON_DESTROY, 161bf215546Sopenharmony_ci &req); 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci if (ret) { 164bf215546Sopenharmony_ci fprintf(stderr, "Failed to destroy perfmon %u: %s\n", 165bf215546Sopenharmony_ci req.id, strerror(ret)); 166bf215546Sopenharmony_ci } 167bf215546Sopenharmony_ci } 168bf215546Sopenharmony_ci} 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 171bf215546Sopenharmony_civ3dv_CreateQueryPool(VkDevice _device, 172bf215546Sopenharmony_ci const VkQueryPoolCreateInfo *pCreateInfo, 173bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 174bf215546Sopenharmony_ci VkQueryPool *pQueryPool) 175bf215546Sopenharmony_ci{ 176bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_device, device, _device); 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci assert(pCreateInfo->queryType == VK_QUERY_TYPE_OCCLUSION || 179bf215546Sopenharmony_ci pCreateInfo->queryType == VK_QUERY_TYPE_TIMESTAMP || 180bf215546Sopenharmony_ci pCreateInfo->queryType == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR); 181bf215546Sopenharmony_ci assert(pCreateInfo->queryCount > 0); 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci struct v3dv_query_pool *pool = 184bf215546Sopenharmony_ci vk_object_zalloc(&device->vk, pAllocator, sizeof(*pool), 185bf215546Sopenharmony_ci VK_OBJECT_TYPE_QUERY_POOL); 186bf215546Sopenharmony_ci if (pool == NULL) 187bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci pool->query_type = pCreateInfo->queryType; 190bf215546Sopenharmony_ci pool->query_count = pCreateInfo->queryCount; 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci uint32_t query_idx = 0; 193bf215546Sopenharmony_ci VkResult result; 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci const uint32_t pool_bytes = sizeof(struct v3dv_query) * pool->query_count; 196bf215546Sopenharmony_ci pool->queries = vk_alloc2(&device->vk.alloc, pAllocator, pool_bytes, 8, 197bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 198bf215546Sopenharmony_ci if (pool->queries == NULL) { 199bf215546Sopenharmony_ci result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 200bf215546Sopenharmony_ci goto fail; 201bf215546Sopenharmony_ci } 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci switch (pool->query_type) { 204bf215546Sopenharmony_ci case VK_QUERY_TYPE_OCCLUSION: { 205bf215546Sopenharmony_ci /* The hardware allows us to setup groups of 16 queries in consecutive 206bf215546Sopenharmony_ci * 4-byte addresses, requiring only that each group of 16 queries is 207bf215546Sopenharmony_ci * aligned to a 1024 byte boundary. 208bf215546Sopenharmony_ci */ 209bf215546Sopenharmony_ci const uint32_t query_groups = DIV_ROUND_UP(pool->query_count, 16); 210bf215546Sopenharmony_ci const uint32_t bo_size = query_groups * 1024; 211bf215546Sopenharmony_ci pool->bo = v3dv_bo_alloc(device, bo_size, "query", true); 212bf215546Sopenharmony_ci if (!pool->bo) { 213bf215546Sopenharmony_ci result = vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 214bf215546Sopenharmony_ci goto fail; 215bf215546Sopenharmony_ci } 216bf215546Sopenharmony_ci if (!v3dv_bo_map(device, pool->bo, bo_size)) { 217bf215546Sopenharmony_ci result = vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 218bf215546Sopenharmony_ci goto fail; 219bf215546Sopenharmony_ci } 220bf215546Sopenharmony_ci break; 221bf215546Sopenharmony_ci } 222bf215546Sopenharmony_ci case VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR: { 223bf215546Sopenharmony_ci const VkQueryPoolPerformanceCreateInfoKHR *pq_info = 224bf215546Sopenharmony_ci vk_find_struct_const(pCreateInfo->pNext, 225bf215546Sopenharmony_ci QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR); 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci assert(pq_info); 228bf215546Sopenharmony_ci assert(pq_info->counterIndexCount <= V3D_PERFCNT_NUM); 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci pool->perfmon.ncounters = pq_info->counterIndexCount; 231bf215546Sopenharmony_ci for (uint32_t i = 0; i < pq_info->counterIndexCount; i++) 232bf215546Sopenharmony_ci pool->perfmon.counters[i] = pq_info->pCounterIndices[i]; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci pool->perfmon.nperfmons = DIV_ROUND_UP(pool->perfmon.ncounters, 235bf215546Sopenharmony_ci DRM_V3D_MAX_PERF_COUNTERS); 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci assert(pool->perfmon.nperfmons <= V3DV_MAX_PERFMONS); 238bf215546Sopenharmony_ci break; 239bf215546Sopenharmony_ci } 240bf215546Sopenharmony_ci case VK_QUERY_TYPE_TIMESTAMP: 241bf215546Sopenharmony_ci break; 242bf215546Sopenharmony_ci default: 243bf215546Sopenharmony_ci unreachable("Unsupported query type"); 244bf215546Sopenharmony_ci } 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci for (; query_idx < pool->query_count; query_idx++) { 247bf215546Sopenharmony_ci pool->queries[query_idx].maybe_available = false; 248bf215546Sopenharmony_ci switch (pool->query_type) { 249bf215546Sopenharmony_ci case VK_QUERY_TYPE_OCCLUSION: { 250bf215546Sopenharmony_ci const uint32_t query_group = query_idx / 16; 251bf215546Sopenharmony_ci const uint32_t query_offset = query_group * 1024 + (query_idx % 16) * 4; 252bf215546Sopenharmony_ci pool->queries[query_idx].bo = pool->bo; 253bf215546Sopenharmony_ci pool->queries[query_idx].offset = query_offset; 254bf215546Sopenharmony_ci break; 255bf215546Sopenharmony_ci } 256bf215546Sopenharmony_ci case VK_QUERY_TYPE_TIMESTAMP: 257bf215546Sopenharmony_ci pool->queries[query_idx].value = 0; 258bf215546Sopenharmony_ci break; 259bf215546Sopenharmony_ci case VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR: { 260bf215546Sopenharmony_ci result = vk_sync_create(&device->vk, 261bf215546Sopenharmony_ci &device->pdevice->drm_syncobj_type, 0, 0, 262bf215546Sopenharmony_ci &pool->queries[query_idx].perf.last_job_sync); 263bf215546Sopenharmony_ci if (result != VK_SUCCESS) 264bf215546Sopenharmony_ci goto fail; 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci for (uint32_t j = 0; j < pool->perfmon.nperfmons; j++) 267bf215546Sopenharmony_ci pool->queries[query_idx].perf.kperfmon_ids[j] = 0; 268bf215546Sopenharmony_ci break; 269bf215546Sopenharmony_ci } 270bf215546Sopenharmony_ci default: 271bf215546Sopenharmony_ci unreachable("Unsupported query type"); 272bf215546Sopenharmony_ci } 273bf215546Sopenharmony_ci } 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci *pQueryPool = v3dv_query_pool_to_handle(pool); 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci return VK_SUCCESS; 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_cifail: 280bf215546Sopenharmony_ci if (pool->query_type == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR) { 281bf215546Sopenharmony_ci for (uint32_t j = 0; j < query_idx; j++) 282bf215546Sopenharmony_ci vk_sync_destroy(&device->vk, pool->queries[j].perf.last_job_sync); 283bf215546Sopenharmony_ci } 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci if (pool->bo) 286bf215546Sopenharmony_ci v3dv_bo_free(device, pool->bo); 287bf215546Sopenharmony_ci if (pool->queries) 288bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, pool->queries); 289bf215546Sopenharmony_ci vk_object_free(&device->vk, pAllocator, pool); 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci return result; 292bf215546Sopenharmony_ci} 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 295bf215546Sopenharmony_civ3dv_DestroyQueryPool(VkDevice _device, 296bf215546Sopenharmony_ci VkQueryPool queryPool, 297bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 298bf215546Sopenharmony_ci{ 299bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_device, device, _device); 300bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_query_pool, pool, queryPool); 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci if (!pool) 303bf215546Sopenharmony_ci return; 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci if (pool->bo) 306bf215546Sopenharmony_ci v3dv_bo_free(device, pool->bo); 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci if (pool->query_type == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR) { 309bf215546Sopenharmony_ci for (uint32_t i = 0; i < pool->query_count; i++) { 310bf215546Sopenharmony_ci kperfmon_destroy(device, pool, i); 311bf215546Sopenharmony_ci vk_sync_destroy(&device->vk, pool->queries[i].perf.last_job_sync); 312bf215546Sopenharmony_ci } 313bf215546Sopenharmony_ci } 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci if (pool->queries) 316bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, pool->queries); 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci vk_object_free(&device->vk, pAllocator, pool); 319bf215546Sopenharmony_ci} 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_cistatic void 322bf215546Sopenharmony_ciwrite_to_buffer(void *dst, uint32_t idx, bool do_64bit, uint64_t value) 323bf215546Sopenharmony_ci{ 324bf215546Sopenharmony_ci if (do_64bit) { 325bf215546Sopenharmony_ci uint64_t *dst64 = (uint64_t *) dst; 326bf215546Sopenharmony_ci dst64[idx] = value; 327bf215546Sopenharmony_ci } else { 328bf215546Sopenharmony_ci uint32_t *dst32 = (uint32_t *) dst; 329bf215546Sopenharmony_ci dst32[idx] = (uint32_t) value; 330bf215546Sopenharmony_ci } 331bf215546Sopenharmony_ci} 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_cistatic VkResult 334bf215546Sopenharmony_ciquery_wait_available(struct v3dv_device *device, 335bf215546Sopenharmony_ci struct v3dv_query *q, 336bf215546Sopenharmony_ci VkQueryType query_type) 337bf215546Sopenharmony_ci{ 338bf215546Sopenharmony_ci if (!q->maybe_available) { 339bf215546Sopenharmony_ci struct timespec timeout; 340bf215546Sopenharmony_ci timespec_get(&timeout, TIME_UTC); 341bf215546Sopenharmony_ci timespec_add_msec(&timeout, &timeout, 2000); 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci mtx_lock(&device->query_mutex); 346bf215546Sopenharmony_ci while (!q->maybe_available) { 347bf215546Sopenharmony_ci if (vk_device_is_lost(&device->vk)) { 348bf215546Sopenharmony_ci result = VK_ERROR_DEVICE_LOST; 349bf215546Sopenharmony_ci break; 350bf215546Sopenharmony_ci } 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci int ret = cnd_timedwait(&device->query_ended, 353bf215546Sopenharmony_ci &device->query_mutex, 354bf215546Sopenharmony_ci &timeout); 355bf215546Sopenharmony_ci if (ret != thrd_success) { 356bf215546Sopenharmony_ci mtx_unlock(&device->query_mutex); 357bf215546Sopenharmony_ci result = vk_device_set_lost(&device->vk, "Query wait failed"); 358bf215546Sopenharmony_ci break; 359bf215546Sopenharmony_ci } 360bf215546Sopenharmony_ci } 361bf215546Sopenharmony_ci mtx_unlock(&device->query_mutex); 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci if (result != VK_SUCCESS) 364bf215546Sopenharmony_ci return result; 365bf215546Sopenharmony_ci } 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci if (query_type == VK_QUERY_TYPE_OCCLUSION && 368bf215546Sopenharmony_ci !v3dv_bo_wait(device, q->bo, 0xffffffffffffffffull)) 369bf215546Sopenharmony_ci return vk_device_set_lost(&device->vk, "Query BO wait failed: %m"); 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_ci if (query_type == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR && 372bf215546Sopenharmony_ci vk_sync_wait(&device->vk, q->perf.last_job_sync, 373bf215546Sopenharmony_ci 0, VK_SYNC_WAIT_COMPLETE, UINT64_MAX) != VK_SUCCESS) 374bf215546Sopenharmony_ci return vk_device_set_lost(&device->vk, "Query job wait failed"); 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci return VK_SUCCESS; 377bf215546Sopenharmony_ci} 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_cistatic VkResult 380bf215546Sopenharmony_ciwrite_occlusion_query_result(struct v3dv_device *device, 381bf215546Sopenharmony_ci struct v3dv_query_pool *pool, 382bf215546Sopenharmony_ci uint32_t query, 383bf215546Sopenharmony_ci bool do_64bit, 384bf215546Sopenharmony_ci void *data, 385bf215546Sopenharmony_ci uint32_t slot) 386bf215546Sopenharmony_ci{ 387bf215546Sopenharmony_ci assert(pool && pool->query_type == VK_QUERY_TYPE_OCCLUSION); 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci if (vk_device_is_lost(&device->vk)) 390bf215546Sopenharmony_ci return VK_ERROR_DEVICE_LOST; 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci struct v3dv_query *q = &pool->queries[query]; 393bf215546Sopenharmony_ci assert(q->bo && q->bo->map); 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci const uint8_t *query_addr = ((uint8_t *) q->bo->map) + q->offset; 396bf215546Sopenharmony_ci write_to_buffer(data, slot, do_64bit, (uint64_t) *((uint32_t *)query_addr)); 397bf215546Sopenharmony_ci return VK_SUCCESS; 398bf215546Sopenharmony_ci} 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_cistatic VkResult 401bf215546Sopenharmony_ciwrite_timestamp_query_result(struct v3dv_device *device, 402bf215546Sopenharmony_ci struct v3dv_query_pool *pool, 403bf215546Sopenharmony_ci uint32_t query, 404bf215546Sopenharmony_ci bool do_64bit, 405bf215546Sopenharmony_ci void *data, 406bf215546Sopenharmony_ci uint32_t slot) 407bf215546Sopenharmony_ci{ 408bf215546Sopenharmony_ci assert(pool && pool->query_type == VK_QUERY_TYPE_TIMESTAMP); 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci struct v3dv_query *q = &pool->queries[query]; 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci write_to_buffer(data, slot, do_64bit, q->value); 413bf215546Sopenharmony_ci return VK_SUCCESS; 414bf215546Sopenharmony_ci} 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_cistatic VkResult 417bf215546Sopenharmony_ciwrite_performance_query_result(struct v3dv_device *device, 418bf215546Sopenharmony_ci struct v3dv_query_pool *pool, 419bf215546Sopenharmony_ci uint32_t query, 420bf215546Sopenharmony_ci bool do_64bit, 421bf215546Sopenharmony_ci void *data, 422bf215546Sopenharmony_ci uint32_t slot) 423bf215546Sopenharmony_ci{ 424bf215546Sopenharmony_ci assert(pool && pool->query_type == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR); 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci struct v3dv_query *q = &pool->queries[query]; 427bf215546Sopenharmony_ci uint64_t counter_values[V3D_PERFCNT_NUM]; 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci for (uint32_t i = 0; i < pool->perfmon.nperfmons; i++) { 430bf215546Sopenharmony_ci struct drm_v3d_perfmon_get_values req = { 431bf215546Sopenharmony_ci .id = q->perf.kperfmon_ids[i], 432bf215546Sopenharmony_ci .values_ptr = (uintptr_t)(&counter_values[i * 433bf215546Sopenharmony_ci DRM_V3D_MAX_PERF_COUNTERS]) 434bf215546Sopenharmony_ci }; 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci int ret = v3dv_ioctl(device->pdevice->render_fd, 437bf215546Sopenharmony_ci DRM_IOCTL_V3D_PERFMON_GET_VALUES, 438bf215546Sopenharmony_ci &req); 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci if (ret) { 441bf215546Sopenharmony_ci fprintf(stderr, "failed to get perfmon values: %s\n", strerror(ret)); 442bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_DEVICE_LOST); 443bf215546Sopenharmony_ci } 444bf215546Sopenharmony_ci } 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci for (uint32_t i = 0; i < pool->perfmon.ncounters; i++) 447bf215546Sopenharmony_ci write_to_buffer(data, slot + i, do_64bit, counter_values[i]); 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci return VK_SUCCESS; 450bf215546Sopenharmony_ci} 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_cistatic VkResult 453bf215546Sopenharmony_ciquery_check_available(struct v3dv_device *device, 454bf215546Sopenharmony_ci struct v3dv_query *q, 455bf215546Sopenharmony_ci VkQueryType query_type) 456bf215546Sopenharmony_ci{ 457bf215546Sopenharmony_ci if (!q->maybe_available) 458bf215546Sopenharmony_ci return VK_NOT_READY; 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci if (query_type == VK_QUERY_TYPE_OCCLUSION && 461bf215546Sopenharmony_ci !v3dv_bo_wait(device, q->bo, 0)) 462bf215546Sopenharmony_ci return VK_NOT_READY; 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci if (query_type == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR && 465bf215546Sopenharmony_ci vk_sync_wait(&device->vk, q->perf.last_job_sync, 466bf215546Sopenharmony_ci 0, VK_SYNC_WAIT_COMPLETE, 0) != VK_SUCCESS) 467bf215546Sopenharmony_ci return VK_NOT_READY; 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci return VK_SUCCESS; 470bf215546Sopenharmony_ci} 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_cistatic VkResult 473bf215546Sopenharmony_ciwrite_query_result(struct v3dv_device *device, 474bf215546Sopenharmony_ci struct v3dv_query_pool *pool, 475bf215546Sopenharmony_ci uint32_t query, 476bf215546Sopenharmony_ci bool do_64bit, 477bf215546Sopenharmony_ci void *data, 478bf215546Sopenharmony_ci uint32_t slot) 479bf215546Sopenharmony_ci{ 480bf215546Sopenharmony_ci switch (pool->query_type) { 481bf215546Sopenharmony_ci case VK_QUERY_TYPE_OCCLUSION: 482bf215546Sopenharmony_ci return write_occlusion_query_result(device, pool, query, do_64bit, 483bf215546Sopenharmony_ci data, slot); 484bf215546Sopenharmony_ci case VK_QUERY_TYPE_TIMESTAMP: 485bf215546Sopenharmony_ci return write_timestamp_query_result(device, pool, query, do_64bit, 486bf215546Sopenharmony_ci data, slot); 487bf215546Sopenharmony_ci case VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR: 488bf215546Sopenharmony_ci return write_performance_query_result(device, pool, query, do_64bit, 489bf215546Sopenharmony_ci data, slot); 490bf215546Sopenharmony_ci default: 491bf215546Sopenharmony_ci unreachable("Unsupported query type"); 492bf215546Sopenharmony_ci } 493bf215546Sopenharmony_ci} 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_cistatic VkResult 496bf215546Sopenharmony_ciquery_is_available(struct v3dv_device *device, 497bf215546Sopenharmony_ci struct v3dv_query_pool *pool, 498bf215546Sopenharmony_ci uint32_t query, 499bf215546Sopenharmony_ci bool do_wait, 500bf215546Sopenharmony_ci bool *available) 501bf215546Sopenharmony_ci{ 502bf215546Sopenharmony_ci struct v3dv_query *q = &pool->queries[query]; 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci assert(pool->query_type != VK_QUERY_TYPE_OCCLUSION || 505bf215546Sopenharmony_ci (q->bo && q->bo->map)); 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci if (do_wait) { 508bf215546Sopenharmony_ci VkResult result = query_wait_available(device, q, pool->query_type); 509bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 510bf215546Sopenharmony_ci *available = false; 511bf215546Sopenharmony_ci return result; 512bf215546Sopenharmony_ci } 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci *available = true; 515bf215546Sopenharmony_ci } else { 516bf215546Sopenharmony_ci VkResult result = query_check_available(device, q, pool->query_type); 517bf215546Sopenharmony_ci assert(result == VK_SUCCESS || result == VK_NOT_READY); 518bf215546Sopenharmony_ci *available = (result == VK_SUCCESS); 519bf215546Sopenharmony_ci } 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_ci return VK_SUCCESS; 522bf215546Sopenharmony_ci} 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_cistatic uint32_t 525bf215546Sopenharmony_ciget_query_result_count(struct v3dv_query_pool *pool) 526bf215546Sopenharmony_ci{ 527bf215546Sopenharmony_ci switch (pool->query_type) { 528bf215546Sopenharmony_ci case VK_QUERY_TYPE_OCCLUSION: 529bf215546Sopenharmony_ci case VK_QUERY_TYPE_TIMESTAMP: 530bf215546Sopenharmony_ci return 1; 531bf215546Sopenharmony_ci case VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR: 532bf215546Sopenharmony_ci return pool->perfmon.ncounters; 533bf215546Sopenharmony_ci default: 534bf215546Sopenharmony_ci unreachable("Unsupported query type"); 535bf215546Sopenharmony_ci } 536bf215546Sopenharmony_ci} 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ciVkResult 539bf215546Sopenharmony_civ3dv_get_query_pool_results(struct v3dv_device *device, 540bf215546Sopenharmony_ci struct v3dv_query_pool *pool, 541bf215546Sopenharmony_ci uint32_t first, 542bf215546Sopenharmony_ci uint32_t count, 543bf215546Sopenharmony_ci void *data, 544bf215546Sopenharmony_ci VkDeviceSize stride, 545bf215546Sopenharmony_ci VkQueryResultFlags flags) 546bf215546Sopenharmony_ci{ 547bf215546Sopenharmony_ci assert(first < pool->query_count); 548bf215546Sopenharmony_ci assert(first + count <= pool->query_count); 549bf215546Sopenharmony_ci assert(data); 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci const bool do_64bit = flags & VK_QUERY_RESULT_64_BIT || 552bf215546Sopenharmony_ci pool->query_type == VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR; 553bf215546Sopenharmony_ci const bool do_wait = flags & VK_QUERY_RESULT_WAIT_BIT; 554bf215546Sopenharmony_ci const bool do_partial = flags & VK_QUERY_RESULT_PARTIAL_BIT; 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci uint32_t result_count = get_query_result_count(pool); 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 559bf215546Sopenharmony_ci for (uint32_t i = first; i < first + count; i++) { 560bf215546Sopenharmony_ci bool available = false; 561bf215546Sopenharmony_ci VkResult query_result = 562bf215546Sopenharmony_ci query_is_available(device, pool, i, do_wait, &available); 563bf215546Sopenharmony_ci if (query_result == VK_ERROR_DEVICE_LOST) 564bf215546Sopenharmony_ci result = VK_ERROR_DEVICE_LOST; 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci /** 567bf215546Sopenharmony_ci * From the Vulkan 1.0 spec: 568bf215546Sopenharmony_ci * 569bf215546Sopenharmony_ci * "If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are 570bf215546Sopenharmony_ci * both not set then no result values are written to pData for queries 571bf215546Sopenharmony_ci * that are in the unavailable state at the time of the call, and 572bf215546Sopenharmony_ci * vkGetQueryPoolResults returns VK_NOT_READY. However, availability 573bf215546Sopenharmony_ci * state is still written to pData for those queries if 574bf215546Sopenharmony_ci * VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set." 575bf215546Sopenharmony_ci */ 576bf215546Sopenharmony_ci uint32_t slot = 0; 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci const bool write_result = available || do_partial; 579bf215546Sopenharmony_ci if (write_result) 580bf215546Sopenharmony_ci write_query_result(device, pool, i, do_64bit, data, slot); 581bf215546Sopenharmony_ci slot += result_count; 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_ci if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) 584bf215546Sopenharmony_ci write_to_buffer(data, slot++, do_64bit, available ? 1u : 0u); 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci if (!write_result && result != VK_ERROR_DEVICE_LOST) 587bf215546Sopenharmony_ci result = VK_NOT_READY; 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci data += stride; 590bf215546Sopenharmony_ci } 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci return result; 593bf215546Sopenharmony_ci} 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 596bf215546Sopenharmony_civ3dv_GetQueryPoolResults(VkDevice _device, 597bf215546Sopenharmony_ci VkQueryPool queryPool, 598bf215546Sopenharmony_ci uint32_t firstQuery, 599bf215546Sopenharmony_ci uint32_t queryCount, 600bf215546Sopenharmony_ci size_t dataSize, 601bf215546Sopenharmony_ci void *pData, 602bf215546Sopenharmony_ci VkDeviceSize stride, 603bf215546Sopenharmony_ci VkQueryResultFlags flags) 604bf215546Sopenharmony_ci{ 605bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_device, device, _device); 606bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_query_pool, pool, queryPool); 607bf215546Sopenharmony_ci 608bf215546Sopenharmony_ci return v3dv_get_query_pool_results(device, pool, firstQuery, queryCount, 609bf215546Sopenharmony_ci pData, stride, flags); 610bf215546Sopenharmony_ci} 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 613bf215546Sopenharmony_civ3dv_CmdResetQueryPool(VkCommandBuffer commandBuffer, 614bf215546Sopenharmony_ci VkQueryPool queryPool, 615bf215546Sopenharmony_ci uint32_t firstQuery, 616bf215546Sopenharmony_ci uint32_t queryCount) 617bf215546Sopenharmony_ci{ 618bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer); 619bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_query_pool, pool, queryPool); 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci v3dv_cmd_buffer_reset_queries(cmd_buffer, pool, firstQuery, queryCount); 622bf215546Sopenharmony_ci} 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 625bf215546Sopenharmony_civ3dv_CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, 626bf215546Sopenharmony_ci VkQueryPool queryPool, 627bf215546Sopenharmony_ci uint32_t firstQuery, 628bf215546Sopenharmony_ci uint32_t queryCount, 629bf215546Sopenharmony_ci VkBuffer dstBuffer, 630bf215546Sopenharmony_ci VkDeviceSize dstOffset, 631bf215546Sopenharmony_ci VkDeviceSize stride, 632bf215546Sopenharmony_ci VkQueryResultFlags flags) 633bf215546Sopenharmony_ci{ 634bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer); 635bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_query_pool, pool, queryPool); 636bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_buffer, dst, dstBuffer); 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci v3dv_cmd_buffer_copy_query_results(cmd_buffer, pool, 639bf215546Sopenharmony_ci firstQuery, queryCount, 640bf215546Sopenharmony_ci dst, dstOffset, stride, flags); 641bf215546Sopenharmony_ci} 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 644bf215546Sopenharmony_civ3dv_CmdBeginQuery(VkCommandBuffer commandBuffer, 645bf215546Sopenharmony_ci VkQueryPool queryPool, 646bf215546Sopenharmony_ci uint32_t query, 647bf215546Sopenharmony_ci VkQueryControlFlags flags) 648bf215546Sopenharmony_ci{ 649bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer); 650bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_query_pool, pool, queryPool); 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_ci v3dv_cmd_buffer_begin_query(cmd_buffer, pool, query, flags); 653bf215546Sopenharmony_ci} 654bf215546Sopenharmony_ci 655bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 656bf215546Sopenharmony_civ3dv_CmdEndQuery(VkCommandBuffer commandBuffer, 657bf215546Sopenharmony_ci VkQueryPool queryPool, 658bf215546Sopenharmony_ci uint32_t query) 659bf215546Sopenharmony_ci{ 660bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer); 661bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_query_pool, pool, queryPool); 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci v3dv_cmd_buffer_end_query(cmd_buffer, pool, query); 664bf215546Sopenharmony_ci} 665bf215546Sopenharmony_ci 666bf215546Sopenharmony_civoid 667bf215546Sopenharmony_civ3dv_reset_query_pools(struct v3dv_device *device, 668bf215546Sopenharmony_ci struct v3dv_query_pool *pool, 669bf215546Sopenharmony_ci uint32_t first, 670bf215546Sopenharmony_ci uint32_t count) 671bf215546Sopenharmony_ci{ 672bf215546Sopenharmony_ci mtx_lock(&device->query_mutex); 673bf215546Sopenharmony_ci 674bf215546Sopenharmony_ci for (uint32_t i = first; i < first + count; i++) { 675bf215546Sopenharmony_ci assert(i < pool->query_count); 676bf215546Sopenharmony_ci struct v3dv_query *q = &pool->queries[i]; 677bf215546Sopenharmony_ci q->maybe_available = false; 678bf215546Sopenharmony_ci switch (pool->query_type) { 679bf215546Sopenharmony_ci case VK_QUERY_TYPE_OCCLUSION: { 680bf215546Sopenharmony_ci const uint8_t *q_addr = ((uint8_t *) q->bo->map) + q->offset; 681bf215546Sopenharmony_ci uint32_t *counter = (uint32_t *) q_addr; 682bf215546Sopenharmony_ci *counter = 0; 683bf215546Sopenharmony_ci break; 684bf215546Sopenharmony_ci } 685bf215546Sopenharmony_ci case VK_QUERY_TYPE_TIMESTAMP: 686bf215546Sopenharmony_ci q->value = 0; 687bf215546Sopenharmony_ci break; 688bf215546Sopenharmony_ci case VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR: 689bf215546Sopenharmony_ci kperfmon_destroy(device, pool, i); 690bf215546Sopenharmony_ci kperfmon_create(device, pool, i); 691bf215546Sopenharmony_ci if (vk_sync_reset(&device->vk, q->perf.last_job_sync) != VK_SUCCESS) 692bf215546Sopenharmony_ci fprintf(stderr, "Failed to reset sync"); 693bf215546Sopenharmony_ci break; 694bf215546Sopenharmony_ci default: 695bf215546Sopenharmony_ci unreachable("Unsupported query type"); 696bf215546Sopenharmony_ci } 697bf215546Sopenharmony_ci } 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci mtx_unlock(&device->query_mutex); 700bf215546Sopenharmony_ci} 701bf215546Sopenharmony_ci 702bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 703bf215546Sopenharmony_civ3dv_ResetQueryPool(VkDevice _device, 704bf215546Sopenharmony_ci VkQueryPool queryPool, 705bf215546Sopenharmony_ci uint32_t firstQuery, 706bf215546Sopenharmony_ci uint32_t queryCount) 707bf215546Sopenharmony_ci{ 708bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_device, device, _device); 709bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_query_pool, pool, queryPool); 710bf215546Sopenharmony_ci 711bf215546Sopenharmony_ci v3dv_reset_query_pools(device, pool, firstQuery, queryCount); 712bf215546Sopenharmony_ci} 713bf215546Sopenharmony_ci 714bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 715bf215546Sopenharmony_civ3dv_EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR( 716bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 717bf215546Sopenharmony_ci uint32_t queueFamilyIndex, 718bf215546Sopenharmony_ci uint32_t *pCounterCount, 719bf215546Sopenharmony_ci VkPerformanceCounterKHR *pCounters, 720bf215546Sopenharmony_ci VkPerformanceCounterDescriptionKHR *pCounterDescriptions) 721bf215546Sopenharmony_ci{ 722bf215546Sopenharmony_ci uint32_t desc_count = *pCounterCount; 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkPerformanceCounterKHR, 725bf215546Sopenharmony_ci out, pCounters, pCounterCount); 726bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkPerformanceCounterDescriptionKHR, 727bf215546Sopenharmony_ci out_desc, pCounterDescriptions, &desc_count); 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_ci for (int i = 0; i < ARRAY_SIZE(v3dv_counters); i++) { 730bf215546Sopenharmony_ci vk_outarray_append_typed(VkPerformanceCounterKHR, &out, counter) { 731bf215546Sopenharmony_ci counter->unit = VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR; 732bf215546Sopenharmony_ci counter->scope = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR; 733bf215546Sopenharmony_ci counter->storage = VK_PERFORMANCE_COUNTER_STORAGE_UINT64_KHR; 734bf215546Sopenharmony_ci 735bf215546Sopenharmony_ci unsigned char sha1_result[20]; 736bf215546Sopenharmony_ci _mesa_sha1_compute(v3dv_counters[i][1], strlen(v3dv_counters[i][1]), 737bf215546Sopenharmony_ci sha1_result); 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_ci memcpy(counter->uuid, sha1_result, sizeof(counter->uuid)); 740bf215546Sopenharmony_ci } 741bf215546Sopenharmony_ci 742bf215546Sopenharmony_ci vk_outarray_append_typed(VkPerformanceCounterDescriptionKHR, 743bf215546Sopenharmony_ci &out_desc, desc) { 744bf215546Sopenharmony_ci desc->flags = 0; 745bf215546Sopenharmony_ci snprintf(desc->name, sizeof(desc->name), "%s", 746bf215546Sopenharmony_ci v3dv_counters[i][1]); 747bf215546Sopenharmony_ci snprintf(desc->category, sizeof(desc->category), "%s", 748bf215546Sopenharmony_ci v3dv_counters[i][0]); 749bf215546Sopenharmony_ci snprintf(desc->description, sizeof(desc->description), "%s", 750bf215546Sopenharmony_ci v3dv_counters[i][2]); 751bf215546Sopenharmony_ci } 752bf215546Sopenharmony_ci } 753bf215546Sopenharmony_ci 754bf215546Sopenharmony_ci return vk_outarray_status(&out); 755bf215546Sopenharmony_ci} 756bf215546Sopenharmony_ci 757bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 758bf215546Sopenharmony_civ3dv_GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR( 759bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 760bf215546Sopenharmony_ci const VkQueryPoolPerformanceCreateInfoKHR *pPerformanceQueryCreateInfo, 761bf215546Sopenharmony_ci uint32_t *pNumPasses) 762bf215546Sopenharmony_ci{ 763bf215546Sopenharmony_ci *pNumPasses = DIV_ROUND_UP(pPerformanceQueryCreateInfo->counterIndexCount, 764bf215546Sopenharmony_ci DRM_V3D_MAX_PERF_COUNTERS); 765bf215546Sopenharmony_ci} 766bf215546Sopenharmony_ci 767bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 768bf215546Sopenharmony_civ3dv_AcquireProfilingLockKHR( 769bf215546Sopenharmony_ci VkDevice _device, 770bf215546Sopenharmony_ci const VkAcquireProfilingLockInfoKHR *pInfo) 771bf215546Sopenharmony_ci{ 772bf215546Sopenharmony_ci return VK_SUCCESS; 773bf215546Sopenharmony_ci} 774bf215546Sopenharmony_ci 775bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 776bf215546Sopenharmony_civ3dv_ReleaseProfilingLockKHR(VkDevice device) 777bf215546Sopenharmony_ci{ 778bf215546Sopenharmony_ci} 779