xref: /aosp_15_r20/external/mesa3d/src/microsoft/vulkan/dzn_query.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © Microsoft Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "dzn_private.h"
25*61046927SAndroid Build Coastguard Worker #include "dzn_abi_helper.h"
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker #include "vk_alloc.h"
28*61046927SAndroid Build Coastguard Worker #include "vk_debug_report.h"
29*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker #include "util/os_time.h"
32*61046927SAndroid Build Coastguard Worker 
33*61046927SAndroid Build Coastguard Worker static D3D12_QUERY_HEAP_TYPE
dzn_query_pool_get_heap_type(VkQueryType in)34*61046927SAndroid Build Coastguard Worker dzn_query_pool_get_heap_type(VkQueryType in)
35*61046927SAndroid Build Coastguard Worker {
36*61046927SAndroid Build Coastguard Worker    switch (in) {
37*61046927SAndroid Build Coastguard Worker    case VK_QUERY_TYPE_OCCLUSION: return D3D12_QUERY_HEAP_TYPE_OCCLUSION;
38*61046927SAndroid Build Coastguard Worker    case VK_QUERY_TYPE_PIPELINE_STATISTICS: return D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS;
39*61046927SAndroid Build Coastguard Worker    case VK_QUERY_TYPE_TIMESTAMP: return D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
40*61046927SAndroid Build Coastguard Worker    default: unreachable("Unsupported query type");
41*61046927SAndroid Build Coastguard Worker    }
42*61046927SAndroid Build Coastguard Worker }
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker D3D12_QUERY_TYPE
dzn_query_pool_get_query_type(const struct dzn_query_pool * qpool,VkQueryControlFlags flags)45*61046927SAndroid Build Coastguard Worker dzn_query_pool_get_query_type(const struct dzn_query_pool *qpool,
46*61046927SAndroid Build Coastguard Worker                               VkQueryControlFlags flags)
47*61046927SAndroid Build Coastguard Worker {
48*61046927SAndroid Build Coastguard Worker    switch (qpool->heap_type) {
49*61046927SAndroid Build Coastguard Worker    case D3D12_QUERY_HEAP_TYPE_OCCLUSION:
50*61046927SAndroid Build Coastguard Worker       return flags & VK_QUERY_CONTROL_PRECISE_BIT ?
51*61046927SAndroid Build Coastguard Worker              D3D12_QUERY_TYPE_OCCLUSION : D3D12_QUERY_TYPE_BINARY_OCCLUSION;
52*61046927SAndroid Build Coastguard Worker    case D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS: return D3D12_QUERY_TYPE_PIPELINE_STATISTICS;
53*61046927SAndroid Build Coastguard Worker    case D3D12_QUERY_HEAP_TYPE_TIMESTAMP: return D3D12_QUERY_TYPE_TIMESTAMP;
54*61046927SAndroid Build Coastguard Worker    default: unreachable("Unsupported query type");
55*61046927SAndroid Build Coastguard Worker    }
56*61046927SAndroid Build Coastguard Worker }
57*61046927SAndroid Build Coastguard Worker 
58*61046927SAndroid Build Coastguard Worker static void
dzn_query_pool_destroy(struct dzn_query_pool * qpool,const VkAllocationCallbacks * alloc)59*61046927SAndroid Build Coastguard Worker dzn_query_pool_destroy(struct dzn_query_pool *qpool,
60*61046927SAndroid Build Coastguard Worker                        const VkAllocationCallbacks *alloc)
61*61046927SAndroid Build Coastguard Worker {
62*61046927SAndroid Build Coastguard Worker    if (!qpool)
63*61046927SAndroid Build Coastguard Worker       return;
64*61046927SAndroid Build Coastguard Worker 
65*61046927SAndroid Build Coastguard Worker    struct dzn_device *device = container_of(qpool->base.device, struct dzn_device, vk);
66*61046927SAndroid Build Coastguard Worker 
67*61046927SAndroid Build Coastguard Worker    if (qpool->collect_map)
68*61046927SAndroid Build Coastguard Worker       ID3D12Resource_Unmap(qpool->collect_buffer, 0, NULL);
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    if (qpool->collect_buffer)
71*61046927SAndroid Build Coastguard Worker       ID3D12Resource_Release(qpool->collect_buffer);
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker    if (qpool->resolve_buffer)
74*61046927SAndroid Build Coastguard Worker       ID3D12Resource_Release(qpool->resolve_buffer);
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker    if (qpool->heap)
77*61046927SAndroid Build Coastguard Worker       ID3D12QueryHeap_Release(qpool->heap);
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker    for (uint32_t q = 0; q < qpool->query_count; q++) {
80*61046927SAndroid Build Coastguard Worker       if (qpool->queries[q].fence)
81*61046927SAndroid Build Coastguard Worker          ID3D12Fence_Release(qpool->queries[q].fence);
82*61046927SAndroid Build Coastguard Worker    }
83*61046927SAndroid Build Coastguard Worker 
84*61046927SAndroid Build Coastguard Worker    mtx_destroy(&qpool->queries_lock);
85*61046927SAndroid Build Coastguard Worker    vk_object_base_finish(&qpool->base);
86*61046927SAndroid Build Coastguard Worker    vk_free2(&device->vk.alloc, alloc, qpool);
87*61046927SAndroid Build Coastguard Worker }
88*61046927SAndroid Build Coastguard Worker 
89*61046927SAndroid Build Coastguard Worker static VkResult
dzn_query_pool_create(struct dzn_device * device,const VkQueryPoolCreateInfo * info,const VkAllocationCallbacks * alloc,VkQueryPool * out)90*61046927SAndroid Build Coastguard Worker dzn_query_pool_create(struct dzn_device *device,
91*61046927SAndroid Build Coastguard Worker                       const VkQueryPoolCreateInfo *info,
92*61046927SAndroid Build Coastguard Worker                       const VkAllocationCallbacks *alloc,
93*61046927SAndroid Build Coastguard Worker                       VkQueryPool *out)
94*61046927SAndroid Build Coastguard Worker {
95*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC(ma);
96*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, struct dzn_query_pool, qpool, 1);
97*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, struct dzn_query, queries, info->queryCount);
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker    if (!vk_multialloc_zalloc2(&ma, &device->vk.alloc, alloc,
100*61046927SAndroid Build Coastguard Worker                               VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
101*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker    vk_object_base_init(&device->vk, &qpool->base, VK_OBJECT_TYPE_QUERY_POOL);
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker    mtx_init(&qpool->queries_lock, mtx_plain);
106*61046927SAndroid Build Coastguard Worker    qpool->query_count = info->queryCount;
107*61046927SAndroid Build Coastguard Worker    qpool->queries = queries;
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker    D3D12_QUERY_HEAP_DESC desc = { 0 };
110*61046927SAndroid Build Coastguard Worker    qpool->heap_type = desc.Type = dzn_query_pool_get_heap_type(info->queryType);
111*61046927SAndroid Build Coastguard Worker    desc.Count = info->queryCount;
112*61046927SAndroid Build Coastguard Worker    desc.NodeMask = 0;
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    HRESULT hres =
115*61046927SAndroid Build Coastguard Worker       ID3D12Device1_CreateQueryHeap(device->dev, &desc,
116*61046927SAndroid Build Coastguard Worker                                     &IID_ID3D12QueryHeap,
117*61046927SAndroid Build Coastguard Worker                                     (void **)&qpool->heap);
118*61046927SAndroid Build Coastguard Worker    if (FAILED(hres)) {
119*61046927SAndroid Build Coastguard Worker       dzn_query_pool_destroy(qpool, alloc);
120*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
121*61046927SAndroid Build Coastguard Worker    }
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker    switch (info->queryType) {
124*61046927SAndroid Build Coastguard Worker    case VK_QUERY_TYPE_OCCLUSION:
125*61046927SAndroid Build Coastguard Worker    case VK_QUERY_TYPE_TIMESTAMP:
126*61046927SAndroid Build Coastguard Worker       qpool->query_size = sizeof(uint64_t);
127*61046927SAndroid Build Coastguard Worker       break;
128*61046927SAndroid Build Coastguard Worker    case VK_QUERY_TYPE_PIPELINE_STATISTICS:
129*61046927SAndroid Build Coastguard Worker       qpool->pipeline_statistics = info->pipelineStatistics;
130*61046927SAndroid Build Coastguard Worker       qpool->query_size = sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS);
131*61046927SAndroid Build Coastguard Worker       break;
132*61046927SAndroid Build Coastguard Worker    default: unreachable("Unsupported query type");
133*61046927SAndroid Build Coastguard Worker    }
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    D3D12_HEAP_PROPERTIES hprops =
136*61046927SAndroid Build Coastguard Worker       dzn_ID3D12Device4_GetCustomHeapProperties(device->dev, 0, D3D12_HEAP_TYPE_DEFAULT);
137*61046927SAndroid Build Coastguard Worker    D3D12_RESOURCE_DESC rdesc = {
138*61046927SAndroid Build Coastguard Worker       .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
139*61046927SAndroid Build Coastguard Worker       .Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
140*61046927SAndroid Build Coastguard Worker       .Width = info->queryCount * qpool->query_size,
141*61046927SAndroid Build Coastguard Worker       .Height = 1,
142*61046927SAndroid Build Coastguard Worker       .DepthOrArraySize = 1,
143*61046927SAndroid Build Coastguard Worker       .MipLevels = 1,
144*61046927SAndroid Build Coastguard Worker       .Format = DXGI_FORMAT_UNKNOWN,
145*61046927SAndroid Build Coastguard Worker       .SampleDesc = { .Count = 1, .Quality = 0 },
146*61046927SAndroid Build Coastguard Worker       .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
147*61046927SAndroid Build Coastguard Worker       .Flags = D3D12_RESOURCE_FLAG_NONE,
148*61046927SAndroid Build Coastguard Worker    };
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker    hres = ID3D12Device1_CreateCommittedResource(device->dev, &hprops,
151*61046927SAndroid Build Coastguard Worker                                                 D3D12_HEAP_FLAG_NONE,
152*61046927SAndroid Build Coastguard Worker                                                 &rdesc,
153*61046927SAndroid Build Coastguard Worker                                                 D3D12_RESOURCE_STATE_COMMON,
154*61046927SAndroid Build Coastguard Worker                                                 NULL,
155*61046927SAndroid Build Coastguard Worker                                                 &IID_ID3D12Resource,
156*61046927SAndroid Build Coastguard Worker                                                 (void **)&qpool->resolve_buffer);
157*61046927SAndroid Build Coastguard Worker    if (FAILED(hres)) {
158*61046927SAndroid Build Coastguard Worker       dzn_query_pool_destroy(qpool, alloc);
159*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
160*61046927SAndroid Build Coastguard Worker    }
161*61046927SAndroid Build Coastguard Worker 
162*61046927SAndroid Build Coastguard Worker    hprops = dzn_ID3D12Device4_GetCustomHeapProperties(device->dev, 0,
163*61046927SAndroid Build Coastguard Worker                                                       D3D12_HEAP_TYPE_READBACK);
164*61046927SAndroid Build Coastguard Worker    rdesc.Width = info->queryCount * (qpool->query_size + sizeof(uint64_t));
165*61046927SAndroid Build Coastguard Worker    hres = ID3D12Device1_CreateCommittedResource(device->dev, &hprops,
166*61046927SAndroid Build Coastguard Worker                                                 D3D12_HEAP_FLAG_NONE,
167*61046927SAndroid Build Coastguard Worker                                                 &rdesc,
168*61046927SAndroid Build Coastguard Worker                                                 D3D12_RESOURCE_STATE_COMMON,
169*61046927SAndroid Build Coastguard Worker                                                 NULL,
170*61046927SAndroid Build Coastguard Worker                                                 &IID_ID3D12Resource,
171*61046927SAndroid Build Coastguard Worker                                                 (void **)&qpool->collect_buffer);
172*61046927SAndroid Build Coastguard Worker    if (FAILED(hres)) {
173*61046927SAndroid Build Coastguard Worker       dzn_query_pool_destroy(qpool, alloc);
174*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
175*61046927SAndroid Build Coastguard Worker    }
176*61046927SAndroid Build Coastguard Worker 
177*61046927SAndroid Build Coastguard Worker    hres = ID3D12Resource_Map(qpool->collect_buffer, 0, NULL, (void **)&qpool->collect_map);
178*61046927SAndroid Build Coastguard Worker    if (FAILED(hres)) {
179*61046927SAndroid Build Coastguard Worker       dzn_query_pool_destroy(qpool, alloc);
180*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
181*61046927SAndroid Build Coastguard Worker    }
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker    memset(qpool->collect_map, 0, rdesc.Width);
184*61046927SAndroid Build Coastguard Worker 
185*61046927SAndroid Build Coastguard Worker    *out = dzn_query_pool_to_handle(qpool);
186*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
187*61046927SAndroid Build Coastguard Worker }
188*61046927SAndroid Build Coastguard Worker 
189*61046927SAndroid Build Coastguard Worker uint32_t
dzn_query_pool_get_result_offset(const struct dzn_query_pool * qpool,uint32_t query)190*61046927SAndroid Build Coastguard Worker dzn_query_pool_get_result_offset(const struct dzn_query_pool *qpool, uint32_t query)
191*61046927SAndroid Build Coastguard Worker {
192*61046927SAndroid Build Coastguard Worker    return query * qpool->query_size;
193*61046927SAndroid Build Coastguard Worker }
194*61046927SAndroid Build Coastguard Worker 
195*61046927SAndroid Build Coastguard Worker uint32_t
dzn_query_pool_get_result_size(const struct dzn_query_pool * qpool,uint32_t query_count)196*61046927SAndroid Build Coastguard Worker dzn_query_pool_get_result_size(const struct dzn_query_pool *qpool, uint32_t query_count)
197*61046927SAndroid Build Coastguard Worker {
198*61046927SAndroid Build Coastguard Worker    return query_count * qpool->query_size;
199*61046927SAndroid Build Coastguard Worker }
200*61046927SAndroid Build Coastguard Worker 
201*61046927SAndroid Build Coastguard Worker uint32_t
dzn_query_pool_get_availability_offset(const struct dzn_query_pool * qpool,uint32_t query)202*61046927SAndroid Build Coastguard Worker dzn_query_pool_get_availability_offset(const struct dzn_query_pool *qpool, uint32_t query)
203*61046927SAndroid Build Coastguard Worker {
204*61046927SAndroid Build Coastguard Worker    return (qpool->query_count * qpool->query_size) + (sizeof(uint64_t) * query);
205*61046927SAndroid Build Coastguard Worker }
206*61046927SAndroid Build Coastguard Worker 
207*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
dzn_CreateQueryPool(VkDevice device,const VkQueryPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkQueryPool * pQueryPool)208*61046927SAndroid Build Coastguard Worker dzn_CreateQueryPool(VkDevice device,
209*61046927SAndroid Build Coastguard Worker                     const VkQueryPoolCreateInfo *pCreateInfo,
210*61046927SAndroid Build Coastguard Worker                     const VkAllocationCallbacks *pAllocator,
211*61046927SAndroid Build Coastguard Worker                     VkQueryPool *pQueryPool)
212*61046927SAndroid Build Coastguard Worker {
213*61046927SAndroid Build Coastguard Worker    return dzn_query_pool_create(dzn_device_from_handle(device),
214*61046927SAndroid Build Coastguard Worker                                 pCreateInfo, pAllocator, pQueryPool);
215*61046927SAndroid Build Coastguard Worker }
216*61046927SAndroid Build Coastguard Worker 
217*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
dzn_DestroyQueryPool(VkDevice device,VkQueryPool queryPool,const VkAllocationCallbacks * pAllocator)218*61046927SAndroid Build Coastguard Worker dzn_DestroyQueryPool(VkDevice device,
219*61046927SAndroid Build Coastguard Worker                      VkQueryPool queryPool,
220*61046927SAndroid Build Coastguard Worker                      const VkAllocationCallbacks *pAllocator)
221*61046927SAndroid Build Coastguard Worker {
222*61046927SAndroid Build Coastguard Worker    dzn_query_pool_destroy(dzn_query_pool_from_handle(queryPool), pAllocator);
223*61046927SAndroid Build Coastguard Worker }
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
dzn_ResetQueryPool(VkDevice device,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount)226*61046927SAndroid Build Coastguard Worker dzn_ResetQueryPool(VkDevice device,
227*61046927SAndroid Build Coastguard Worker                    VkQueryPool queryPool,
228*61046927SAndroid Build Coastguard Worker                    uint32_t firstQuery,
229*61046927SAndroid Build Coastguard Worker                    uint32_t queryCount)
230*61046927SAndroid Build Coastguard Worker {
231*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(dzn_query_pool, qpool, queryPool);
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker    mtx_lock(&qpool->queries_lock);
234*61046927SAndroid Build Coastguard Worker    for (uint32_t q = 0; q < queryCount; q++) {
235*61046927SAndroid Build Coastguard Worker       struct dzn_query *query = &qpool->queries[firstQuery + q];
236*61046927SAndroid Build Coastguard Worker 
237*61046927SAndroid Build Coastguard Worker       query->fence_value = 0;
238*61046927SAndroid Build Coastguard Worker       if (query->fence) {
239*61046927SAndroid Build Coastguard Worker          ID3D12Fence_Release(query->fence);
240*61046927SAndroid Build Coastguard Worker          query->fence = NULL;
241*61046927SAndroid Build Coastguard Worker       }
242*61046927SAndroid Build Coastguard Worker    }
243*61046927SAndroid Build Coastguard Worker    mtx_unlock(&qpool->queries_lock);
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker    memset((uint8_t *)qpool->collect_map + dzn_query_pool_get_result_offset(qpool, firstQuery),
246*61046927SAndroid Build Coastguard Worker           0, queryCount * qpool->query_size);
247*61046927SAndroid Build Coastguard Worker    memset((uint8_t *)qpool->collect_map + dzn_query_pool_get_availability_offset(qpool, firstQuery),
248*61046927SAndroid Build Coastguard Worker           0, queryCount * sizeof(uint64_t));
249*61046927SAndroid Build Coastguard Worker }
250*61046927SAndroid Build Coastguard Worker 
251*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
dzn_GetQueryPoolResults(VkDevice device,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount,size_t dataSize,void * pData,VkDeviceSize stride,VkQueryResultFlags flags)252*61046927SAndroid Build Coastguard Worker dzn_GetQueryPoolResults(VkDevice device,
253*61046927SAndroid Build Coastguard Worker                         VkQueryPool queryPool,
254*61046927SAndroid Build Coastguard Worker                         uint32_t firstQuery,
255*61046927SAndroid Build Coastguard Worker                         uint32_t queryCount,
256*61046927SAndroid Build Coastguard Worker                         size_t dataSize,
257*61046927SAndroid Build Coastguard Worker                         void *pData,
258*61046927SAndroid Build Coastguard Worker                         VkDeviceSize stride,
259*61046927SAndroid Build Coastguard Worker                         VkQueryResultFlags flags)
260*61046927SAndroid Build Coastguard Worker {
261*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(dzn_query_pool, qpool, queryPool);
262*61046927SAndroid Build Coastguard Worker 
263*61046927SAndroid Build Coastguard Worker    uint32_t step = (flags & VK_QUERY_RESULT_64_BIT) ?
264*61046927SAndroid Build Coastguard Worker                    sizeof(uint64_t) : sizeof(uint32_t);
265*61046927SAndroid Build Coastguard Worker    VkResult result = VK_SUCCESS;
266*61046927SAndroid Build Coastguard Worker 
267*61046927SAndroid Build Coastguard Worker    for (uint32_t q = 0; q < queryCount; q++) {
268*61046927SAndroid Build Coastguard Worker       struct dzn_query *query = &qpool->queries[q + firstQuery];
269*61046927SAndroid Build Coastguard Worker 
270*61046927SAndroid Build Coastguard Worker       uint8_t *dst_ptr = (uint8_t *)pData + (stride * q);
271*61046927SAndroid Build Coastguard Worker       uint8_t *src_ptr =
272*61046927SAndroid Build Coastguard Worker          (uint8_t *)qpool->collect_map +
273*61046927SAndroid Build Coastguard Worker          dzn_query_pool_get_result_offset(qpool, firstQuery + q);
274*61046927SAndroid Build Coastguard Worker       uint64_t available = 0;
275*61046927SAndroid Build Coastguard Worker 
276*61046927SAndroid Build Coastguard Worker       if (flags & VK_QUERY_RESULT_WAIT_BIT) {
277*61046927SAndroid Build Coastguard Worker          ID3D12Fence *query_fence = NULL;
278*61046927SAndroid Build Coastguard Worker          uint64_t query_fence_val = 0;
279*61046927SAndroid Build Coastguard Worker 
280*61046927SAndroid Build Coastguard Worker          while (true) {
281*61046927SAndroid Build Coastguard Worker             mtx_lock(&qpool->queries_lock);
282*61046927SAndroid Build Coastguard Worker             if (query->fence) {
283*61046927SAndroid Build Coastguard Worker                query_fence = query->fence;
284*61046927SAndroid Build Coastguard Worker                ID3D12Fence_AddRef(query_fence);
285*61046927SAndroid Build Coastguard Worker             }
286*61046927SAndroid Build Coastguard Worker             query_fence_val = query->fence_value;
287*61046927SAndroid Build Coastguard Worker             mtx_unlock(&qpool->queries_lock);
288*61046927SAndroid Build Coastguard Worker 
289*61046927SAndroid Build Coastguard Worker             if (query_fence)
290*61046927SAndroid Build Coastguard Worker                break;
291*61046927SAndroid Build Coastguard Worker 
292*61046927SAndroid Build Coastguard Worker             /* Check again in 10ms.
293*61046927SAndroid Build Coastguard Worker              * FIXME: decrease the polling period if it happens to hurt latency.
294*61046927SAndroid Build Coastguard Worker              */
295*61046927SAndroid Build Coastguard Worker             os_time_sleep(10 * 1000);
296*61046927SAndroid Build Coastguard Worker          }
297*61046927SAndroid Build Coastguard Worker 
298*61046927SAndroid Build Coastguard Worker          ID3D12Fence_SetEventOnCompletion(query_fence, query_fence_val, NULL);
299*61046927SAndroid Build Coastguard Worker          ID3D12Fence_Release(query_fence);
300*61046927SAndroid Build Coastguard Worker          available = UINT64_MAX;
301*61046927SAndroid Build Coastguard Worker       } else {
302*61046927SAndroid Build Coastguard Worker          ID3D12Fence *query_fence = NULL;
303*61046927SAndroid Build Coastguard Worker          mtx_lock(&qpool->queries_lock);
304*61046927SAndroid Build Coastguard Worker          if (query->fence) {
305*61046927SAndroid Build Coastguard Worker             query_fence = query->fence;
306*61046927SAndroid Build Coastguard Worker             ID3D12Fence_AddRef(query_fence);
307*61046927SAndroid Build Coastguard Worker          }
308*61046927SAndroid Build Coastguard Worker          uint64_t query_fence_val = query->fence_value;
309*61046927SAndroid Build Coastguard Worker          mtx_unlock(&qpool->queries_lock);
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker          if (query_fence) {
312*61046927SAndroid Build Coastguard Worker             if (ID3D12Fence_GetCompletedValue(query_fence) >= query_fence_val)
313*61046927SAndroid Build Coastguard Worker                available = UINT64_MAX;
314*61046927SAndroid Build Coastguard Worker             ID3D12Fence_Release(query_fence);
315*61046927SAndroid Build Coastguard Worker          }
316*61046927SAndroid Build Coastguard Worker       }
317*61046927SAndroid Build Coastguard Worker 
318*61046927SAndroid Build Coastguard Worker       if (qpool->heap_type != D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS) {
319*61046927SAndroid Build Coastguard Worker          if (available)
320*61046927SAndroid Build Coastguard Worker             memcpy(dst_ptr, src_ptr, step);
321*61046927SAndroid Build Coastguard Worker          else if (flags & VK_QUERY_RESULT_PARTIAL_BIT)
322*61046927SAndroid Build Coastguard Worker             memset(dst_ptr, 0, step);
323*61046927SAndroid Build Coastguard Worker 
324*61046927SAndroid Build Coastguard Worker          dst_ptr += step;
325*61046927SAndroid Build Coastguard Worker       } else {
326*61046927SAndroid Build Coastguard Worker          for (uint32_t c = 0; c < sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS) / sizeof(uint64_t); c++) {
327*61046927SAndroid Build Coastguard Worker             if (!(BITFIELD_BIT(c) & qpool->pipeline_statistics))
328*61046927SAndroid Build Coastguard Worker                continue;
329*61046927SAndroid Build Coastguard Worker 
330*61046927SAndroid Build Coastguard Worker             if (available)
331*61046927SAndroid Build Coastguard Worker                memcpy(dst_ptr, src_ptr + (c * sizeof(uint64_t)), step);
332*61046927SAndroid Build Coastguard Worker             else if (flags & VK_QUERY_RESULT_PARTIAL_BIT)
333*61046927SAndroid Build Coastguard Worker                memset(dst_ptr, 0, step);
334*61046927SAndroid Build Coastguard Worker 
335*61046927SAndroid Build Coastguard Worker             dst_ptr += step;
336*61046927SAndroid Build Coastguard Worker          }
337*61046927SAndroid Build Coastguard Worker       }
338*61046927SAndroid Build Coastguard Worker 
339*61046927SAndroid Build Coastguard Worker       if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
340*61046927SAndroid Build Coastguard Worker          memcpy(dst_ptr, &available, step);
341*61046927SAndroid Build Coastguard Worker 
342*61046927SAndroid Build Coastguard Worker       if (!available && !(flags & VK_QUERY_RESULT_PARTIAL_BIT))
343*61046927SAndroid Build Coastguard Worker          result = VK_NOT_READY;
344*61046927SAndroid Build Coastguard Worker    }
345*61046927SAndroid Build Coastguard Worker 
346*61046927SAndroid Build Coastguard Worker    return result;
347*61046927SAndroid Build Coastguard Worker }
348