1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © Microsoft Corporation 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 "dzn_private.h" 25bf215546Sopenharmony_ci#include "dzn_abi_helper.h" 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "vk_alloc.h" 28bf215546Sopenharmony_ci#include "vk_debug_report.h" 29bf215546Sopenharmony_ci#include "vk_util.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "os_time.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_cistatic D3D12_QUERY_HEAP_TYPE 34bf215546Sopenharmony_cidzn_query_pool_get_heap_type(VkQueryType in) 35bf215546Sopenharmony_ci{ 36bf215546Sopenharmony_ci switch (in) { 37bf215546Sopenharmony_ci case VK_QUERY_TYPE_OCCLUSION: return D3D12_QUERY_HEAP_TYPE_OCCLUSION; 38bf215546Sopenharmony_ci case VK_QUERY_TYPE_PIPELINE_STATISTICS: return D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS; 39bf215546Sopenharmony_ci case VK_QUERY_TYPE_TIMESTAMP: return D3D12_QUERY_HEAP_TYPE_TIMESTAMP; 40bf215546Sopenharmony_ci default: unreachable("Unsupported query type"); 41bf215546Sopenharmony_ci } 42bf215546Sopenharmony_ci} 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ciD3D12_QUERY_TYPE 45bf215546Sopenharmony_cidzn_query_pool_get_query_type(const struct dzn_query_pool *qpool, 46bf215546Sopenharmony_ci VkQueryControlFlags flags) 47bf215546Sopenharmony_ci{ 48bf215546Sopenharmony_ci switch (qpool->heap_type) { 49bf215546Sopenharmony_ci case D3D12_QUERY_HEAP_TYPE_OCCLUSION: 50bf215546Sopenharmony_ci return flags & VK_QUERY_CONTROL_PRECISE_BIT ? 51bf215546Sopenharmony_ci D3D12_QUERY_TYPE_OCCLUSION : D3D12_QUERY_TYPE_BINARY_OCCLUSION; 52bf215546Sopenharmony_ci case D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS: return D3D12_QUERY_TYPE_PIPELINE_STATISTICS; 53bf215546Sopenharmony_ci case D3D12_QUERY_HEAP_TYPE_TIMESTAMP: return D3D12_QUERY_TYPE_TIMESTAMP; 54bf215546Sopenharmony_ci default: unreachable("Unsupported query type"); 55bf215546Sopenharmony_ci } 56bf215546Sopenharmony_ci} 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_cistatic void 59bf215546Sopenharmony_cidzn_query_pool_destroy(struct dzn_query_pool *qpool, 60bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc) 61bf215546Sopenharmony_ci{ 62bf215546Sopenharmony_ci if (!qpool) 63bf215546Sopenharmony_ci return; 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci struct dzn_device *device = container_of(qpool->base.device, struct dzn_device, vk); 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci if (qpool->collect_map) 68bf215546Sopenharmony_ci ID3D12Resource_Unmap(qpool->collect_buffer, 0, NULL); 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci if (qpool->collect_buffer) 71bf215546Sopenharmony_ci ID3D12Resource_Release(qpool->collect_buffer); 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci if (qpool->resolve_buffer) 74bf215546Sopenharmony_ci ID3D12Resource_Release(qpool->resolve_buffer); 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci if (qpool->heap) 77bf215546Sopenharmony_ci ID3D12QueryHeap_Release(qpool->heap); 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci for (uint32_t q = 0; q < qpool->query_count; q++) { 80bf215546Sopenharmony_ci if (qpool->queries[q].fence) 81bf215546Sopenharmony_ci ID3D12Fence_Release(qpool->queries[q].fence); 82bf215546Sopenharmony_ci } 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci mtx_destroy(&qpool->queries_lock); 85bf215546Sopenharmony_ci vk_object_base_finish(&qpool->base); 86bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, alloc, qpool); 87bf215546Sopenharmony_ci} 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_cistatic VkResult 90bf215546Sopenharmony_cidzn_query_pool_create(struct dzn_device *device, 91bf215546Sopenharmony_ci const VkQueryPoolCreateInfo *info, 92bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 93bf215546Sopenharmony_ci VkQueryPool *out) 94bf215546Sopenharmony_ci{ 95bf215546Sopenharmony_ci VK_MULTIALLOC(ma); 96bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, struct dzn_query_pool, qpool, 1); 97bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, struct dzn_query, queries, info->queryCount); 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci if (!vk_multialloc_zalloc2(&ma, &device->vk.alloc, alloc, 100bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) 101bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &qpool->base, VK_OBJECT_TYPE_QUERY_POOL); 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci mtx_init(&qpool->queries_lock, mtx_plain); 106bf215546Sopenharmony_ci qpool->query_count = info->queryCount; 107bf215546Sopenharmony_ci qpool->queries = queries; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci D3D12_QUERY_HEAP_DESC desc = { 0 }; 110bf215546Sopenharmony_ci qpool->heap_type = desc.Type = dzn_query_pool_get_heap_type(info->queryType); 111bf215546Sopenharmony_ci desc.Count = info->queryCount; 112bf215546Sopenharmony_ci desc.NodeMask = 0; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci HRESULT hres = 115bf215546Sopenharmony_ci ID3D12Device1_CreateQueryHeap(device->dev, &desc, 116bf215546Sopenharmony_ci &IID_ID3D12QueryHeap, 117bf215546Sopenharmony_ci (void **)&qpool->heap); 118bf215546Sopenharmony_ci if (FAILED(hres)) { 119bf215546Sopenharmony_ci dzn_query_pool_destroy(qpool, alloc); 120bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 121bf215546Sopenharmony_ci } 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci switch (info->queryType) { 124bf215546Sopenharmony_ci case VK_QUERY_TYPE_OCCLUSION: 125bf215546Sopenharmony_ci case VK_QUERY_TYPE_TIMESTAMP: 126bf215546Sopenharmony_ci qpool->query_size = sizeof(uint64_t); 127bf215546Sopenharmony_ci break; 128bf215546Sopenharmony_ci case VK_QUERY_TYPE_PIPELINE_STATISTICS: 129bf215546Sopenharmony_ci qpool->pipeline_statistics = info->pipelineStatistics; 130bf215546Sopenharmony_ci qpool->query_size = sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS); 131bf215546Sopenharmony_ci break; 132bf215546Sopenharmony_ci default: unreachable("Unsupported query type"); 133bf215546Sopenharmony_ci } 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci D3D12_HEAP_PROPERTIES hprops = 136bf215546Sopenharmony_ci dzn_ID3D12Device2_GetCustomHeapProperties(device->dev, 0, D3D12_HEAP_TYPE_DEFAULT); 137bf215546Sopenharmony_ci D3D12_RESOURCE_DESC rdesc = { 138bf215546Sopenharmony_ci .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER, 139bf215546Sopenharmony_ci .Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, 140bf215546Sopenharmony_ci .Width = info->queryCount * qpool->query_size, 141bf215546Sopenharmony_ci .Height = 1, 142bf215546Sopenharmony_ci .DepthOrArraySize = 1, 143bf215546Sopenharmony_ci .MipLevels = 1, 144bf215546Sopenharmony_ci .Format = DXGI_FORMAT_UNKNOWN, 145bf215546Sopenharmony_ci .SampleDesc = { .Count = 1, .Quality = 0 }, 146bf215546Sopenharmony_ci .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR, 147bf215546Sopenharmony_ci .Flags = D3D12_RESOURCE_FLAG_NONE, 148bf215546Sopenharmony_ci }; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci hres = ID3D12Device1_CreateCommittedResource(device->dev, &hprops, 151bf215546Sopenharmony_ci D3D12_HEAP_FLAG_NONE, 152bf215546Sopenharmony_ci &rdesc, 153bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_COPY_DEST, 154bf215546Sopenharmony_ci NULL, 155bf215546Sopenharmony_ci &IID_ID3D12Resource, 156bf215546Sopenharmony_ci (void **)&qpool->resolve_buffer); 157bf215546Sopenharmony_ci if (FAILED(hres)) { 158bf215546Sopenharmony_ci dzn_query_pool_destroy(qpool, alloc); 159bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 160bf215546Sopenharmony_ci } 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci hprops = dzn_ID3D12Device2_GetCustomHeapProperties(device->dev, 0, 163bf215546Sopenharmony_ci D3D12_HEAP_TYPE_READBACK); 164bf215546Sopenharmony_ci rdesc.Width = info->queryCount * (qpool->query_size + sizeof(uint64_t)); 165bf215546Sopenharmony_ci hres = ID3D12Device1_CreateCommittedResource(device->dev, &hprops, 166bf215546Sopenharmony_ci D3D12_HEAP_FLAG_NONE, 167bf215546Sopenharmony_ci &rdesc, 168bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_COPY_DEST, 169bf215546Sopenharmony_ci NULL, 170bf215546Sopenharmony_ci &IID_ID3D12Resource, 171bf215546Sopenharmony_ci (void **)&qpool->collect_buffer); 172bf215546Sopenharmony_ci if (FAILED(hres)) { 173bf215546Sopenharmony_ci dzn_query_pool_destroy(qpool, alloc); 174bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 175bf215546Sopenharmony_ci } 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci hres = ID3D12Resource_Map(qpool->collect_buffer, 0, NULL, (void **)&qpool->collect_map); 178bf215546Sopenharmony_ci if (FAILED(hres)) { 179bf215546Sopenharmony_ci dzn_query_pool_destroy(qpool, alloc); 180bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 181bf215546Sopenharmony_ci } 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci memset(qpool->collect_map, 0, rdesc.Width); 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci *out = dzn_query_pool_to_handle(qpool); 186bf215546Sopenharmony_ci return VK_SUCCESS; 187bf215546Sopenharmony_ci} 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ciuint32_t 190bf215546Sopenharmony_cidzn_query_pool_get_result_offset(const struct dzn_query_pool *qpool, uint32_t query) 191bf215546Sopenharmony_ci{ 192bf215546Sopenharmony_ci return query * qpool->query_size; 193bf215546Sopenharmony_ci} 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ciuint32_t 196bf215546Sopenharmony_cidzn_query_pool_get_result_size(const struct dzn_query_pool *qpool, uint32_t query_count) 197bf215546Sopenharmony_ci{ 198bf215546Sopenharmony_ci return query_count * qpool->query_size; 199bf215546Sopenharmony_ci} 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ciuint32_t 202bf215546Sopenharmony_cidzn_query_pool_get_availability_offset(const struct dzn_query_pool *qpool, uint32_t query) 203bf215546Sopenharmony_ci{ 204bf215546Sopenharmony_ci return (qpool->query_count * qpool->query_size) + (sizeof(uint64_t) * query); 205bf215546Sopenharmony_ci} 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 208bf215546Sopenharmony_cidzn_CreateQueryPool(VkDevice device, 209bf215546Sopenharmony_ci const VkQueryPoolCreateInfo *pCreateInfo, 210bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 211bf215546Sopenharmony_ci VkQueryPool *pQueryPool) 212bf215546Sopenharmony_ci{ 213bf215546Sopenharmony_ci return dzn_query_pool_create(dzn_device_from_handle(device), 214bf215546Sopenharmony_ci pCreateInfo, pAllocator, pQueryPool); 215bf215546Sopenharmony_ci} 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 218bf215546Sopenharmony_cidzn_DestroyQueryPool(VkDevice device, 219bf215546Sopenharmony_ci VkQueryPool queryPool, 220bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 221bf215546Sopenharmony_ci{ 222bf215546Sopenharmony_ci dzn_query_pool_destroy(dzn_query_pool_from_handle(queryPool), pAllocator); 223bf215546Sopenharmony_ci} 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 226bf215546Sopenharmony_cidzn_ResetQueryPool(VkDevice device, 227bf215546Sopenharmony_ci VkQueryPool queryPool, 228bf215546Sopenharmony_ci uint32_t firstQuery, 229bf215546Sopenharmony_ci uint32_t queryCount) 230bf215546Sopenharmony_ci{ 231bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_query_pool, qpool, queryPool); 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci mtx_lock(&qpool->queries_lock); 234bf215546Sopenharmony_ci for (uint32_t q = 0; q < queryCount; q++) { 235bf215546Sopenharmony_ci struct dzn_query *query = &qpool->queries[firstQuery + q]; 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci query->fence_value = 0; 238bf215546Sopenharmony_ci if (query->fence) { 239bf215546Sopenharmony_ci ID3D12Fence_Release(query->fence); 240bf215546Sopenharmony_ci query->fence = NULL; 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci } 243bf215546Sopenharmony_ci mtx_lock(&qpool->queries_lock); 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci memset((uint8_t *)qpool->collect_map + dzn_query_pool_get_result_offset(qpool, firstQuery), 246bf215546Sopenharmony_ci 0, queryCount * qpool->query_size); 247bf215546Sopenharmony_ci memset((uint8_t *)qpool->collect_map + dzn_query_pool_get_availability_offset(qpool, firstQuery), 248bf215546Sopenharmony_ci 0, queryCount * sizeof(uint64_t)); 249bf215546Sopenharmony_ci} 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 252bf215546Sopenharmony_cidzn_GetQueryPoolResults(VkDevice device, 253bf215546Sopenharmony_ci VkQueryPool queryPool, 254bf215546Sopenharmony_ci uint32_t firstQuery, 255bf215546Sopenharmony_ci uint32_t queryCount, 256bf215546Sopenharmony_ci size_t dataSize, 257bf215546Sopenharmony_ci void *pData, 258bf215546Sopenharmony_ci VkDeviceSize stride, 259bf215546Sopenharmony_ci VkQueryResultFlags flags) 260bf215546Sopenharmony_ci{ 261bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_query_pool, qpool, queryPool); 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci uint32_t step = (flags & VK_QUERY_RESULT_64_BIT) ? 264bf215546Sopenharmony_ci sizeof(uint64_t) : sizeof(uint32_t); 265bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci for (uint32_t q = 0; q < queryCount; q++) { 268bf215546Sopenharmony_ci struct dzn_query *query = &qpool->queries[q + firstQuery]; 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ci uint8_t *dst_ptr = (uint8_t *)pData + (stride * q); 271bf215546Sopenharmony_ci uint8_t *src_ptr = 272bf215546Sopenharmony_ci (uint8_t *)qpool->collect_map + 273bf215546Sopenharmony_ci dzn_query_pool_get_result_offset(qpool, firstQuery + q); 274bf215546Sopenharmony_ci uint64_t available = 0; 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci if (flags & VK_QUERY_RESULT_WAIT_BIT) { 277bf215546Sopenharmony_ci ID3D12Fence *query_fence = NULL; 278bf215546Sopenharmony_ci uint64_t query_fence_val = 0; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci while (true) { 281bf215546Sopenharmony_ci mtx_lock(&qpool->queries_lock); 282bf215546Sopenharmony_ci if (query->fence) { 283bf215546Sopenharmony_ci query_fence = query->fence; 284bf215546Sopenharmony_ci ID3D12Fence_AddRef(query_fence); 285bf215546Sopenharmony_ci } 286bf215546Sopenharmony_ci query_fence_val = query->fence_value; 287bf215546Sopenharmony_ci mtx_unlock(&qpool->queries_lock); 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci if (query_fence) 290bf215546Sopenharmony_ci break; 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci /* Check again in 10ms. 293bf215546Sopenharmony_ci * FIXME: decrease the polling period if it happens to hurt latency. 294bf215546Sopenharmony_ci */ 295bf215546Sopenharmony_ci os_time_sleep(10 * 1000); 296bf215546Sopenharmony_ci } 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci ID3D12Fence_SetEventOnCompletion(query_fence, query_fence_val, NULL); 299bf215546Sopenharmony_ci ID3D12Fence_Release(query_fence); 300bf215546Sopenharmony_ci available = UINT64_MAX; 301bf215546Sopenharmony_ci } else { 302bf215546Sopenharmony_ci ID3D12Fence *query_fence = NULL; 303bf215546Sopenharmony_ci mtx_lock(&qpool->queries_lock); 304bf215546Sopenharmony_ci if (query->fence) { 305bf215546Sopenharmony_ci query_fence = query->fence; 306bf215546Sopenharmony_ci ID3D12Fence_AddRef(query_fence); 307bf215546Sopenharmony_ci } 308bf215546Sopenharmony_ci uint64_t query_fence_val = query->fence_value; 309bf215546Sopenharmony_ci mtx_unlock(&qpool->queries_lock); 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci if (query_fence) { 312bf215546Sopenharmony_ci if (ID3D12Fence_GetCompletedValue(query_fence) >= query_fence_val) 313bf215546Sopenharmony_ci available = UINT64_MAX; 314bf215546Sopenharmony_ci ID3D12Fence_Release(query_fence); 315bf215546Sopenharmony_ci } 316bf215546Sopenharmony_ci } 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci if (qpool->heap_type != D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS) { 319bf215546Sopenharmony_ci if (available) 320bf215546Sopenharmony_ci memcpy(dst_ptr, src_ptr, step); 321bf215546Sopenharmony_ci else if (flags & VK_QUERY_RESULT_PARTIAL_BIT) 322bf215546Sopenharmony_ci memset(dst_ptr, 0, step); 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci dst_ptr += step; 325bf215546Sopenharmony_ci } else { 326bf215546Sopenharmony_ci for (uint32_t c = 0; c < sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS) / sizeof(uint64_t); c++) { 327bf215546Sopenharmony_ci if (!(BITFIELD_BIT(c) & qpool->pipeline_statistics)) 328bf215546Sopenharmony_ci continue; 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_ci if (available) 331bf215546Sopenharmony_ci memcpy(dst_ptr, src_ptr + (c * sizeof(uint64_t)), step); 332bf215546Sopenharmony_ci else if (flags & VK_QUERY_RESULT_PARTIAL_BIT) 333bf215546Sopenharmony_ci memset(dst_ptr, 0, step); 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci dst_ptr += step; 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci } 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) 340bf215546Sopenharmony_ci memcpy(dst_ptr, &available, step); 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ci if (!available && !(flags & VK_QUERY_RESULT_PARTIAL_BIT)) 343bf215546Sopenharmony_ci result = VK_NOT_READY; 344bf215546Sopenharmony_ci } 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci return result; 347bf215546Sopenharmony_ci} 348