diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c index 893c8a6af67..45734f95880 100644 --- a/src/gallium/frontends/lavapipe/lvp_device.c +++ b/src/gallium/frontends/lavapipe/lvp_device.c @@ -319,7 +319,7 @@ void lvp_GetPhysicalDeviceFeatures( .textureCompressionASTC_LDR = false, .textureCompressionBC = true, .occlusionQueryPrecise = true, - .pipelineStatisticsQuery = false, + .pipelineStatisticsQuery = true, .vertexPipelineStoresAndAtomics = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) != 0), .fragmentStoresAndAtomics = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) != 0), .shaderTessellationAndGeometryPointSize = true, diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h index e4300875bca..700875292d0 100644 --- a/src/gallium/frontends/lavapipe/lvp_private.h +++ b/src/gallium/frontends/lavapipe/lvp_private.h @@ -562,6 +562,7 @@ struct lvp_query_pool { struct vk_object_base base; VkQueryType type; uint32_t count; + VkQueryPipelineStatisticFlags pipeline_stats; enum pipe_query_type base_type; struct pipe_query *queries[0]; }; diff --git a/src/gallium/frontends/lavapipe/lvp_query.c b/src/gallium/frontends/lavapipe/lvp_query.c index f549fe1b89e..f807234ffb2 100644 --- a/src/gallium/frontends/lavapipe/lvp_query.c +++ b/src/gallium/frontends/lavapipe/lvp_query.c @@ -40,6 +40,9 @@ VkResult lvp_CreateQueryPool( case VK_QUERY_TYPE_TIMESTAMP: pipeq = PIPE_QUERY_TIMESTAMP; break; + case VK_QUERY_TYPE_PIPELINE_STATISTICS: + pipeq = PIPE_QUERY_PIPELINE_STATISTICS; + break; default: return VK_ERROR_FEATURE_NOT_PRESENT; } @@ -57,6 +60,7 @@ VkResult lvp_CreateQueryPool( pool->type = pCreateInfo->queryType; pool->count = pCreateInfo->queryCount; pool->base_type = pipeq; + pool->pipeline_stats = pCreateInfo->pipelineStatistics; *pQueryPool = lvp_query_pool_to_handle(pool); return VK_SUCCESS; @@ -112,17 +116,46 @@ VkResult lvp_GetQueryPoolResults( if (!ready && !(flags & VK_QUERY_RESULT_PARTIAL_BIT)) vk_result = VK_NOT_READY; if (flags & VK_QUERY_RESULT_64_BIT) { - if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) - *(uint64_t *)dptr = result.u64; - dptr += 8; + if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) { + if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) { + uint32_t mask = pool->pipeline_stats; + uint64_t *pstats = (uint64_t *)&result.pipeline_statistics; + while (mask) { + uint32_t i = u_bit_scan(&mask); + + *(uint64_t *)dptr = pstats[i]; + dptr += 8; + } + } else { + *(uint64_t *)dptr = result.u64; + dptr += 8; + } + } else + dptr += stride; + } else { if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) { - if (result.u64 > UINT32_MAX) - *(uint32_t *)dptr = UINT32_MAX; - else - *(uint32_t *)dptr = result.u32; - } - dptr += 4; + if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) { + uint32_t mask = pool->pipeline_stats; + uint64_t *pstats = (uint64_t *)&result.pipeline_statistics; + while (mask) { + uint32_t i = u_bit_scan(&mask); + + if (pstats[i] > UINT32_MAX) + *(uint32_t *)dptr = UINT32_MAX; + else + *(uint32_t *)dptr = pstats[i]; + dptr += 4; + } + } else { + if (result.u64 > UINT32_MAX) + *(uint32_t *)dptr = UINT32_MAX; + else + *(uint32_t *)dptr = result.u32; + dptr += 4; + } + } else + dptr += stride; } if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {