nvk: Remove delta handling from query pool

Now that we reset counters, we do not need to handle delta for anything.

Signed-off-by: Mary Guillemard <mary@mary.zone>
Reviewed-by: Mel Henning <mhenning@darkrefraction.com>
This commit is contained in:
Mary Guillemard 2026-05-03 17:29:46 +02:00
parent 1a8e75f56a
commit 75f8980579
2 changed files with 60 additions and 88 deletions

View file

@ -34,9 +34,7 @@ nvk_copy_queries(uint64_t pool_addr, uint available_stride,
} else { } else {
if (write_results) { if (write_results) {
for (uint r = 0; r < report_count; ++r) { for (uint r = 0; r < report_count; ++r) {
uint delta = report[(r * 2) + 1].value - report[r * 2].value; vk_write_query(dst_addr + dst_offset, r, flags, report[r].value);
vk_write_query(dst_addr + dst_offset, r, flags, delta);
} }
} }
} }

View file

@ -76,14 +76,8 @@ nvk_CreateQueryPool(VkDevice device,
else else
pool->layout = NVK_QUERY_POOL_LAYOUT_SEPARATE; pool->layout = NVK_QUERY_POOL_LAYOUT_SEPARATE;
uint32_t reports_per_query; /* Everything is a single query per report */
if (pool->vk.query_type == VK_QUERY_TYPE_TIMESTAMP) { uint32_t reports_per_query = vk_query_pool_report_count(&pool->vk);
/* Timestamps are just a single timestamp */
reports_per_query = 1;
} else {
/* Everything else is two queries because we have to compute a delta */
reports_per_query = 2 * vk_query_pool_report_count(&pool->vk);
}
uint64_t mem_size = 0; uint64_t mem_size = 0;
switch (pool->layout) { switch (pool->layout) {
@ -532,17 +526,50 @@ nvk_cmd_clear_report_value(struct nvk_cmd_buffer *cmd,
} }
} }
static void VKAPI_ATTR void VKAPI_CALL
nvk_cmd_begin_end_query(struct nvk_cmd_buffer *cmd, nvk_CmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer,
struct nvk_query_pool *pool, VkQueryPool queryPool,
uint32_t query, uint32_t index, uint32_t query,
bool end) VkQueryControlFlags flags,
uint32_t index)
{ {
VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer);
VK_FROM_HANDLE(nvk_query_pool, pool, queryPool);
/* From the Vulkan 1.4.350 spec, vkCmdBeginQuery:
*
* VUID-vkCmdBeginQuery-queryPool-01922
*
* "queryPool must have been created with a queryType that differs from
* that of any queries that are active within commandBuffer"
*
* and
*
* "After beginning a query, that query is considered active within the
* command buffer it was called in until that same query is ended.
* Queries active in a primary command buffer when secondary command
* buffers are executed are considered active for those secondary command
* buffers."
*
* This means we will never have two queries with the same type active and
* can rely on cleaning counters.
*/
nvk_cmd_clear_report_value(cmd, pool);
}
VKAPI_ATTR void VKAPI_CALL
nvk_CmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer,
VkQueryPool queryPool,
uint32_t query,
uint32_t index)
{
VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer);
VK_FROM_HANDLE(nvk_query_pool, pool, queryPool);
const struct nvk_device *dev = nvk_cmd_buffer_device(cmd); const struct nvk_device *dev = nvk_cmd_buffer_device(cmd);
const struct nvk_physical_device *pdev = nvk_device_physical(dev); const struct nvk_physical_device *pdev = nvk_device_physical(dev);
uint64_t report_addr = nvk_query_report_addr(pool, query) + uint64_t report_addr = nvk_query_report_addr(pool, query);
end * sizeof(struct nvk_query_report);
switch (pool->vk.query_type) { switch (pool->vk.query_type) {
case VK_QUERY_TYPE_OCCLUSION: { case VK_QUERY_TYPE_OCCLUSION: {
@ -596,7 +623,7 @@ nvk_cmd_begin_end_query(struct nvk_cmd_buffer *cmd,
}); });
} }
report_addr += 2 * sizeof(struct nvk_query_report); report_addr += sizeof(struct nvk_query_report);
stats_left &= ~sq->flag; stats_left &= ~sq->flag;
} }
break; break;
@ -621,7 +648,7 @@ nvk_cmd_begin_end_query(struct nvk_cmd_buffer *cmd,
.sub_report = index, .sub_report = index,
.flush_disable = true, .flush_disable = true,
}); });
report_addr += 2 * sizeof(struct nvk_query_report); report_addr += sizeof(struct nvk_query_report);
} }
break; break;
} }
@ -648,66 +675,21 @@ nvk_cmd_begin_end_query(struct nvk_cmd_buffer *cmd,
UNREACHABLE("Unsupported query type"); UNREACHABLE("Unsupported query type");
} }
if (end) {
struct nv_push *p = nvk_cmd_buffer_push(cmd, 7);
P_IMMD(p, NV9097, FLUSH_PENDING_WRITES, 0);
uint64_t available_addr = nvk_query_available_addr(pool, query); struct nv_push *p = nvk_cmd_buffer_push(cmd, 7);
P_MTHD(p, NV9097, SET_REPORT_SEMAPHORE_A); P_IMMD(p, NV9097, FLUSH_PENDING_WRITES, 0);
P_NV9097_SET_REPORT_SEMAPHORE_A(p, available_addr >> 32);
P_NV9097_SET_REPORT_SEMAPHORE_B(p, available_addr);
P_NV9097_SET_REPORT_SEMAPHORE_C(p, 1);
P_NV9097_SET_REPORT_SEMAPHORE_D(p, {
.operation = OPERATION_RELEASE,
.release = RELEASE_AFTER_ALL_PRECEEDING_WRITES_COMPLETE,
.pipeline_location = PIPELINE_LOCATION_ALL,
.structure_size = STRUCTURE_SIZE_ONE_WORD,
});
}
}
VKAPI_ATTR void VKAPI_CALL uint64_t available_addr = nvk_query_available_addr(pool, query);
nvk_CmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, P_MTHD(p, NV9097, SET_REPORT_SEMAPHORE_A);
VkQueryPool queryPool, P_NV9097_SET_REPORT_SEMAPHORE_A(p, available_addr >> 32);
uint32_t query, P_NV9097_SET_REPORT_SEMAPHORE_B(p, available_addr);
VkQueryControlFlags flags, P_NV9097_SET_REPORT_SEMAPHORE_C(p, 1);
uint32_t index) P_NV9097_SET_REPORT_SEMAPHORE_D(p, {
{ .operation = OPERATION_RELEASE,
VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer); .release = RELEASE_AFTER_ALL_PRECEEDING_WRITES_COMPLETE,
VK_FROM_HANDLE(nvk_query_pool, pool, queryPool); .pipeline_location = PIPELINE_LOCATION_ALL,
.structure_size = STRUCTURE_SIZE_ONE_WORD,
/* From the Vulkan 1.4.350 spec, vkCmdBeginQuery: });
*
* VUID-vkCmdBeginQuery-queryPool-01922
*
* "queryPool must have been created with a queryType that differs from
* that of any queries that are active within commandBuffer"
*
* and
*
* "After beginning a query, that query is considered active within the
* command buffer it was called in until that same query is ended.
* Queries active in a primary command buffer when secondary command
* buffers are executed are considered active for those secondary command
* buffers."
*
* This means we will never have two queries with the same type active and
* can rely on cleaning counters.
*/
nvk_cmd_clear_report_value(cmd, pool);
nvk_cmd_begin_end_query(cmd, pool, query, index, false);
}
VKAPI_ATTR void VKAPI_CALL
nvk_CmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer,
VkQueryPool queryPool,
uint32_t query,
uint32_t index)
{
VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer);
VK_FROM_HANDLE(nvk_query_pool, pool, queryPool);
nvk_cmd_begin_end_query(cmd, pool, query, index, true);
/* From the Vulkan spec: /* From the Vulkan spec:
* *
@ -775,14 +757,6 @@ cpu_write_query_result(void *dst, uint32_t idx,
} }
} }
static void
cpu_get_query_delta(void *dst, const struct nvk_query_report *src,
uint32_t idx, VkQueryResultFlags flags)
{
uint64_t delta = src[idx * 2 + 1].value - src[idx * 2].value;
cpu_write_query_result(dst, idx, flags, delta);
}
VKAPI_ATTR VkResult VKAPI_CALL VKAPI_ATTR VkResult VKAPI_CALL
nvk_GetQueryPoolResults(VkDevice device, nvk_GetQueryPoolResults(VkDevice device,
VkQueryPool queryPool, VkQueryPool queryPool,
@ -831,10 +805,10 @@ nvk_GetQueryPoolResults(VkDevice device,
if (write_results) if (write_results)
cpu_write_query_result(dst, 0, flags, src->timestamp); cpu_write_query_result(dst, 0, flags, src->timestamp);
} else { } else {
/* For everything else, we have to compute deltas */ /* For everything else, we can just write it */
if (write_results) { if (write_results) {
for (uint32_t j = 0; j < report_count; j++) for (uint32_t j = 0; j < report_count; j++)
cpu_get_query_delta(dst, src, j, flags); cpu_write_query_result(dst, j, flags, src[j].value);
} }
} }