zink: query support (v2)

This at least passes piglit occlusion_query test for me here now.

Acked-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Dave Airlie 2018-10-03 00:57:41 +01:00 committed by Erik Faye-Lund
parent b533de12a5
commit 6d96578912
5 changed files with 159 additions and 0 deletions

View file

@ -28,6 +28,7 @@ files_libzink = files(
'zink_framebuffer.c',
'zink_pipeline.c',
'zink_program.c',
'zink_query.c',
'zink_render_pass.c',
'zink_resource.c',
'zink_screen.c',

View file

@ -1143,6 +1143,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
ctx->base.flush_resource = zink_flush_resource;
zink_context_surface_init(&ctx->base);
zink_context_resource_init(&ctx->base);
zink_context_query_init(&ctx->base);
slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);

View file

@ -104,4 +104,7 @@ zink_shader_stage(enum pipe_shader_type type);
struct pipe_context *
zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags);
void
zink_context_query_init(struct pipe_context *ctx);
#endif

View file

@ -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;
}

View file

@ -102,6 +102,10 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_MAX_RENDER_TARGETS:
return screen->props.limits.maxColorAttachments;
case PIPE_CAP_OCCLUSION_QUERY:
case PIPE_CAP_QUERY_TIME_ELAPSED:
return 1;
case PIPE_CAP_TEXTURE_SWIZZLE:
return 1;
@ -160,6 +164,9 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
return screen->props.limits.minUniformBufferOffsetAlignment;
case PIPE_CAP_QUERY_TIMESTAMP:
return 1;
case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
return screen->props.limits.minMemoryMapAlignment;