diff options
author | Dave Airlie <[email protected]> | 2018-10-03 00:57:41 +0100 |
---|---|---|
committer | Erik Faye-Lund <[email protected]> | 2019-10-28 08:51:43 +0000 |
commit | 6d96578912cd509a8d91912feacaa8a0169b7d90 (patch) | |
tree | aed183923a4f05a1667eefe288bd87844cf851aa /src/gallium/drivers/zink/zink_query.c | |
parent | b533de12a5aab989b52573ced8a9fc7e6c15e330 (diff) |
zink: query support (v2)
This at least passes piglit occlusion_query test for me here now.
Acked-by: Jordan Justen <[email protected]>
Diffstat (limited to 'src/gallium/drivers/zink/zink_query.c')
-rw-r--r-- | src/gallium/drivers/zink/zink_query.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/src/gallium/drivers/zink/zink_query.c b/src/gallium/drivers/zink/zink_query.c new file mode 100644 index 00000000000..65babe5d763 --- /dev/null +++ b/src/gallium/drivers/zink/zink_query.c @@ -0,0 +1,147 @@ + +#include "zink_context.h" +#include "zink_screen.h" + +#include "util/u_memory.h" +struct zink_query { + VkQueryPool queryPool; + VkQueryType vkqtype; + bool use_64bit; + bool precise; +}; + +static VkQueryType +convert_query_type(unsigned query_type, bool *use_64bit, bool *precise) +{ + *use_64bit = false; + *precise = false; + switch (query_type) { + case PIPE_QUERY_OCCLUSION_COUNTER: + *precise = true; + *use_64bit = true; + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: + return VK_QUERY_TYPE_OCCLUSION; + case PIPE_QUERY_TIMESTAMP: + *use_64bit = true; + return VK_QUERY_TYPE_TIMESTAMP; + case PIPE_QUERY_PIPELINE_STATISTICS: + return VK_QUERY_TYPE_PIPELINE_STATISTICS; + default: + fprintf(stderr, "zink: unknown query type\n"); + return -1; + } +} + +static struct pipe_query * +zink_create_query(struct pipe_context *pctx, + unsigned query_type, unsigned index) +{ + struct zink_screen *screen = zink_screen(pctx->screen); + struct zink_query *query = CALLOC_STRUCT(zink_query); + VkQueryPoolCreateInfo pool_create = {}; + + if (!query) + return NULL; + + query->vkqtype = convert_query_type(query_type, &query->use_64bit, &query->precise); + if (query->vkqtype == -1) + return NULL; + + pool_create.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; + pool_create.queryType = query->vkqtype; + pool_create.queryCount = 1; + + VkResult status = vkCreateQueryPool(screen->dev, &pool_create, NULL, &query->queryPool); + if (status != VK_SUCCESS) { + FREE(query); + return NULL; + } + return (struct pipe_query *)query; +} + +static void +zink_destroy_query(struct pipe_context *pctx, + struct pipe_query *q) +{ + struct zink_screen *screen = zink_screen(pctx->screen); + struct zink_query *query = CALLOC_STRUCT(zink_query); + + vkDestroyQueryPool(screen->dev, query->queryPool, NULL); +} + +static bool +zink_begin_query(struct pipe_context *pctx, + struct pipe_query *q) +{ + struct zink_context *ctx = zink_context(pctx); + struct zink_query *query = (struct zink_query *)q; + + struct zink_cmdbuf *cmdbuf = zink_start_cmdbuf(ctx); + if (!cmdbuf) + return false; + + if (query->vkqtype == VK_QUERY_TYPE_TIMESTAMP) + return true; + + VkQueryControlFlags flags = 0; + if (query->precise) + flags |= VK_QUERY_CONTROL_PRECISE_BIT; + + vkCmdBeginQuery(cmdbuf->cmdbuf, query->queryPool, 0, flags); + + return true; +} + +static bool +zink_end_query(struct pipe_context *pctx, + struct pipe_query *q) +{ + struct zink_context *ctx = zink_context(pctx); + struct zink_query *query = (struct zink_query *)q; + + struct zink_cmdbuf *cmdbuf = zink_start_cmdbuf(ctx); + if (!cmdbuf) + return false; + + if (query->vkqtype == VK_QUERY_TYPE_TIMESTAMP) + vkCmdWriteTimestamp(cmdbuf->cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + query->queryPool, 0); + else + vkCmdEndQuery(cmdbuf->cmdbuf, query->queryPool, 0); + return true; +} + +static bool +zink_get_query_result(struct pipe_context *pctx, + struct pipe_query *q, + bool wait, + union pipe_query_result *result) +{ + struct zink_screen *screen = zink_screen(pctx->screen); + struct zink_query *query = (struct zink_query *)q; + VkQueryResultFlagBits flags = 0; + + pctx->flush(pctx, NULL, 0); + + if (wait) + flags |= VK_QUERY_RESULT_WAIT_BIT; + + if (query->use_64bit) + flags |= VK_QUERY_RESULT_64_BIT; + + VkResult status = vkGetQueryPoolResults(screen->dev, query->queryPool, + 0, 1, sizeof(*result), result, + 0, flags); + return status == VK_SUCCESS; +} + +void +zink_context_query_init(struct pipe_context *pctx) +{ + pctx->create_query = zink_create_query; + pctx->destroy_query = zink_destroy_query; + pctx->begin_query = zink_begin_query; + pctx->end_query = zink_end_query; + pctx->get_query_result = zink_get_query_result; +} |