lavapipe: enable pipeline stats queries

These pass CTS, but I think are missing some stuff CTS doesn't test.

This is one of the base Vulkan 1.0 features and I'd like to support
it for conformance.

Cc: "20.3" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7705>
This commit is contained in:
Dave Airlie 2020-11-13 17:06:31 +10:00
parent 4263162839
commit 87c70f1984
3 changed files with 44 additions and 10 deletions

View File

@ -319,7 +319,7 @@ void lvp_GetPhysicalDeviceFeatures(
.textureCompressionASTC_LDR = false, .textureCompressionASTC_LDR = false,
.textureCompressionBC = true, .textureCompressionBC = true,
.occlusionQueryPrecise = 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), .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), .fragmentStoresAndAtomics = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) != 0),
.shaderTessellationAndGeometryPointSize = true, .shaderTessellationAndGeometryPointSize = true,

View File

@ -562,6 +562,7 @@ struct lvp_query_pool {
struct vk_object_base base; struct vk_object_base base;
VkQueryType type; VkQueryType type;
uint32_t count; uint32_t count;
VkQueryPipelineStatisticFlags pipeline_stats;
enum pipe_query_type base_type; enum pipe_query_type base_type;
struct pipe_query *queries[0]; struct pipe_query *queries[0];
}; };

View File

@ -40,6 +40,9 @@ VkResult lvp_CreateQueryPool(
case VK_QUERY_TYPE_TIMESTAMP: case VK_QUERY_TYPE_TIMESTAMP:
pipeq = PIPE_QUERY_TIMESTAMP; pipeq = PIPE_QUERY_TIMESTAMP;
break; break;
case VK_QUERY_TYPE_PIPELINE_STATISTICS:
pipeq = PIPE_QUERY_PIPELINE_STATISTICS;
break;
default: default:
return VK_ERROR_FEATURE_NOT_PRESENT; return VK_ERROR_FEATURE_NOT_PRESENT;
} }
@ -57,6 +60,7 @@ VkResult lvp_CreateQueryPool(
pool->type = pCreateInfo->queryType; pool->type = pCreateInfo->queryType;
pool->count = pCreateInfo->queryCount; pool->count = pCreateInfo->queryCount;
pool->base_type = pipeq; pool->base_type = pipeq;
pool->pipeline_stats = pCreateInfo->pipelineStatistics;
*pQueryPool = lvp_query_pool_to_handle(pool); *pQueryPool = lvp_query_pool_to_handle(pool);
return VK_SUCCESS; return VK_SUCCESS;
@ -112,17 +116,46 @@ VkResult lvp_GetQueryPoolResults(
if (!ready && !(flags & VK_QUERY_RESULT_PARTIAL_BIT)) if (!ready && !(flags & VK_QUERY_RESULT_PARTIAL_BIT))
vk_result = VK_NOT_READY; vk_result = VK_NOT_READY;
if (flags & VK_QUERY_RESULT_64_BIT) { if (flags & VK_QUERY_RESULT_64_BIT) {
if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) {
*(uint64_t *)dptr = result.u64; if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
dptr += 8; 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 { } else {
if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) { if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) {
if (result.u64 > UINT32_MAX) if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
*(uint32_t *)dptr = UINT32_MAX; uint32_t mask = pool->pipeline_stats;
else uint64_t *pstats = (uint64_t *)&result.pipeline_statistics;
*(uint32_t *)dptr = result.u32; while (mask) {
} uint32_t i = u_bit_scan(&mask);
dptr += 4;
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) { if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {