Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_query.c
4565 views
1
/*
2
* Copyright © 2019 Red Hat.
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include "lvp_private.h"
25
#include "pipe/p_context.h"
26
27
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateQueryPool(
28
VkDevice _device,
29
const VkQueryPoolCreateInfo* pCreateInfo,
30
const VkAllocationCallbacks* pAllocator,
31
VkQueryPool* pQueryPool)
32
{
33
LVP_FROM_HANDLE(lvp_device, device, _device);
34
35
enum pipe_query_type pipeq;
36
switch (pCreateInfo->queryType) {
37
case VK_QUERY_TYPE_OCCLUSION:
38
pipeq = PIPE_QUERY_OCCLUSION_COUNTER;
39
break;
40
case VK_QUERY_TYPE_TIMESTAMP:
41
pipeq = PIPE_QUERY_TIMESTAMP;
42
break;
43
case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT:
44
pipeq = PIPE_QUERY_SO_STATISTICS;
45
break;
46
case VK_QUERY_TYPE_PIPELINE_STATISTICS:
47
pipeq = PIPE_QUERY_PIPELINE_STATISTICS;
48
break;
49
default:
50
return VK_ERROR_FEATURE_NOT_PRESENT;
51
}
52
struct lvp_query_pool *pool;
53
uint32_t pool_size = sizeof(*pool) + pCreateInfo->queryCount * sizeof(struct pipe_query *);
54
55
pool = vk_zalloc2(&device->vk.alloc, pAllocator,
56
pool_size, 8,
57
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
58
if (!pool)
59
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
60
61
vk_object_base_init(&device->vk, &pool->base,
62
VK_OBJECT_TYPE_QUERY_POOL);
63
pool->type = pCreateInfo->queryType;
64
pool->count = pCreateInfo->queryCount;
65
pool->base_type = pipeq;
66
pool->pipeline_stats = pCreateInfo->pipelineStatistics;
67
68
*pQueryPool = lvp_query_pool_to_handle(pool);
69
return VK_SUCCESS;
70
}
71
72
VKAPI_ATTR void VKAPI_CALL lvp_DestroyQueryPool(
73
VkDevice _device,
74
VkQueryPool _pool,
75
const VkAllocationCallbacks* pAllocator)
76
{
77
LVP_FROM_HANDLE(lvp_device, device, _device);
78
LVP_FROM_HANDLE(lvp_query_pool, pool, _pool);
79
80
if (!pool)
81
return;
82
83
for (unsigned i = 0; i < pool->count; i++)
84
if (pool->queries[i])
85
device->queue.ctx->destroy_query(device->queue.ctx, pool->queries[i]);
86
vk_object_base_finish(&pool->base);
87
vk_free2(&device->vk.alloc, pAllocator, pool);
88
}
89
90
VKAPI_ATTR VkResult VKAPI_CALL lvp_GetQueryPoolResults(
91
VkDevice _device,
92
VkQueryPool queryPool,
93
uint32_t firstQuery,
94
uint32_t queryCount,
95
size_t dataSize,
96
void* pData,
97
VkDeviceSize stride,
98
VkQueryResultFlags flags)
99
{
100
LVP_FROM_HANDLE(lvp_device, device, _device);
101
LVP_FROM_HANDLE(lvp_query_pool, pool, queryPool);
102
VkResult vk_result = VK_SUCCESS;
103
104
lvp_DeviceWaitIdle(_device);
105
106
for (unsigned i = firstQuery; i < firstQuery + queryCount; i++) {
107
uint8_t *dptr = (uint8_t *)((char *)pData + (stride * (i - firstQuery)));
108
union pipe_query_result result;
109
bool ready = false;
110
if (pool->queries[i]) {
111
ready = device->queue.ctx->get_query_result(device->queue.ctx,
112
pool->queries[i],
113
(flags & VK_QUERY_RESULT_WAIT_BIT),
114
&result);
115
} else {
116
result.u64 = 0;
117
}
118
119
if (!ready && !(flags & VK_QUERY_RESULT_PARTIAL_BIT))
120
vk_result = VK_NOT_READY;
121
if (flags & VK_QUERY_RESULT_64_BIT) {
122
if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) {
123
if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
124
uint32_t mask = pool->pipeline_stats;
125
uint64_t *pstats = (uint64_t *)&result.pipeline_statistics;
126
while (mask) {
127
uint32_t i = u_bit_scan(&mask);
128
129
*(uint64_t *)dptr = pstats[i];
130
dptr += 8;
131
}
132
} else if (pool->type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) {
133
*(uint64_t *)dptr = result.so_statistics.num_primitives_written;
134
dptr += 8;
135
*(uint64_t *)dptr = result.so_statistics.primitives_storage_needed;
136
dptr += 8;
137
} else {
138
*(uint64_t *)dptr = result.u64;
139
dptr += 8;
140
}
141
} else {
142
if (pool->type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT)
143
dptr += 16;
144
else
145
dptr += 8;
146
}
147
148
} else {
149
if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) {
150
if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
151
uint32_t mask = pool->pipeline_stats;
152
uint64_t *pstats = (uint64_t *)&result.pipeline_statistics;
153
while (mask) {
154
uint32_t i = u_bit_scan(&mask);
155
156
if (pstats[i] > UINT32_MAX)
157
*(uint32_t *)dptr = UINT32_MAX;
158
else
159
*(uint32_t *)dptr = pstats[i];
160
dptr += 4;
161
}
162
} else if (pool->type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) {
163
if (result.so_statistics.num_primitives_written > UINT32_MAX)
164
*(uint32_t *)dptr = UINT32_MAX;
165
else
166
*(uint32_t *)dptr = (uint32_t)result.so_statistics.num_primitives_written;
167
dptr += 4;
168
if (result.so_statistics.primitives_storage_needed > UINT32_MAX)
169
*(uint32_t *)dptr = UINT32_MAX;
170
else
171
*(uint32_t *)dptr = (uint32_t)result.so_statistics.primitives_storage_needed;
172
dptr += 4;
173
} else {
174
if (result.u64 > UINT32_MAX)
175
*(uint32_t *)dptr = UINT32_MAX;
176
else
177
*(uint32_t *)dptr = result.u32;
178
dptr += 4;
179
}
180
} else
181
if (pool->type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT)
182
dptr += 8;
183
else
184
dptr += 4;
185
}
186
187
if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
188
if (flags & VK_QUERY_RESULT_64_BIT)
189
*(uint64_t *)dptr = ready;
190
else
191
*(uint32_t *)dptr = ready;
192
}
193
}
194
return vk_result;
195
}
196
197
VKAPI_ATTR void VKAPI_CALL lvp_ResetQueryPool(
198
VkDevice _device,
199
VkQueryPool queryPool,
200
uint32_t firstQuery,
201
uint32_t queryCount)
202
{
203
LVP_FROM_HANDLE(lvp_device, device, _device);
204
LVP_FROM_HANDLE(lvp_query_pool, pool, queryPool);
205
206
for (uint32_t i = 0; i < queryCount; i++) {
207
uint32_t idx = i + firstQuery;
208
209
if (pool->queries[idx]) {
210
device->queue.ctx->destroy_query(device->queue.ctx, pool->queries[idx]);
211
pool->queries[idx] = NULL;
212
}
213
}
214
}
215
216