summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-10-03 00:57:41 +0100
committerErik Faye-Lund <erik.faye-lund@collabora.com>2019-10-28 08:51:43 +0000
commit6d96578912cd509a8d91912feacaa8a0169b7d90 (patch)
treeaed183923a4f05a1667eefe288bd87844cf851aa
parentb533de12a5aab989b52573ced8a9fc7e6c15e330 (diff)
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>
-rw-r--r--src/gallium/drivers/zink/meson.build1
-rw-r--r--src/gallium/drivers/zink/zink_context.c1
-rw-r--r--src/gallium/drivers/zink/zink_context.h3
-rw-r--r--src/gallium/drivers/zink/zink_query.c147
-rw-r--r--src/gallium/drivers/zink/zink_screen.c7
5 files changed, 159 insertions, 0 deletions
diff --git a/src/gallium/drivers/zink/meson.build b/src/gallium/drivers/zink/meson.build
index 75edc36ca68..1552696d8fe 100644
--- a/src/gallium/drivers/zink/meson.build
+++ b/src/gallium/drivers/zink/meson.build
@@ -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',
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 5b3f2d5263d..2ce780ce9ff 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -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);
diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h
index d2d669e927d..69e2fdd797e 100644
--- a/src/gallium/drivers/zink/zink_context.h
+++ b/src/gallium/drivers/zink/zink_context.h
@@ -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
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;
+}
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index b50f2f5d030..88b2d5088d4 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -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;