3d83d76d88e79a1c1cd02f1e65aa92216cad2ba5
[mesa.git] / src / gallium / drivers / zink / zink_query.c
1
2 #include "zink_context.h"
3 #include "zink_screen.h"
4
5 #include "util/u_memory.h"
6 #include "util/u_dump.h"
7
8 struct zink_query {
9 VkQueryPool queryPool;
10 VkQueryType vkqtype;
11 bool use_64bit;
12 bool precise;
13 };
14
15 static VkQueryType
16 convert_query_type(unsigned query_type, bool *use_64bit, bool *precise)
17 {
18 *use_64bit = false;
19 *precise = false;
20 switch (query_type) {
21 case PIPE_QUERY_OCCLUSION_COUNTER:
22 *precise = true;
23 *use_64bit = true;
24 case PIPE_QUERY_OCCLUSION_PREDICATE:
25 case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
26 return VK_QUERY_TYPE_OCCLUSION;
27 case PIPE_QUERY_TIMESTAMP:
28 *use_64bit = true;
29 return VK_QUERY_TYPE_TIMESTAMP;
30 case PIPE_QUERY_PIPELINE_STATISTICS:
31 return VK_QUERY_TYPE_PIPELINE_STATISTICS;
32 default:
33 debug_printf("unknown query: %s\n",
34 util_str_query_type(query_type, true));
35 unreachable("zink: unknown query type");
36 }
37 }
38
39 static struct pipe_query *
40 zink_create_query(struct pipe_context *pctx,
41 unsigned query_type, unsigned index)
42 {
43 struct zink_screen *screen = zink_screen(pctx->screen);
44 struct zink_query *query = CALLOC_STRUCT(zink_query);
45 VkQueryPoolCreateInfo pool_create = {};
46
47 if (!query)
48 return NULL;
49
50 query->vkqtype = convert_query_type(query_type, &query->use_64bit, &query->precise);
51 if (query->vkqtype == -1)
52 return NULL;
53
54 pool_create.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
55 pool_create.queryType = query->vkqtype;
56 pool_create.queryCount = 1;
57
58 VkResult status = vkCreateQueryPool(screen->dev, &pool_create, NULL, &query->queryPool);
59 if (status != VK_SUCCESS) {
60 FREE(query);
61 return NULL;
62 }
63 return (struct pipe_query *)query;
64 }
65
66 static void
67 zink_destroy_query(struct pipe_context *pctx,
68 struct pipe_query *q)
69 {
70 struct zink_screen *screen = zink_screen(pctx->screen);
71 struct zink_query *query = CALLOC_STRUCT(zink_query);
72
73 vkDestroyQueryPool(screen->dev, query->queryPool, NULL);
74 }
75
76 static bool
77 zink_begin_query(struct pipe_context *pctx,
78 struct pipe_query *q)
79 {
80 struct zink_context *ctx = zink_context(pctx);
81 struct zink_query *query = (struct zink_query *)q;
82
83 if (query->vkqtype == VK_QUERY_TYPE_TIMESTAMP)
84 return true;
85
86 VkQueryControlFlags flags = 0;
87 if (query->precise)
88 flags |= VK_QUERY_CONTROL_PRECISE_BIT;
89
90 struct zink_batch *batch = zink_curr_batch(ctx);
91 vkCmdBeginQuery(batch->cmdbuf, query->queryPool, 0, flags);
92
93 return true;
94 }
95
96 static bool
97 zink_end_query(struct pipe_context *pctx,
98 struct pipe_query *q)
99 {
100 struct zink_context *ctx = zink_context(pctx);
101 struct zink_query *query = (struct zink_query *)q;
102
103 struct zink_batch *batch = zink_curr_batch(ctx);
104 if (query->vkqtype == VK_QUERY_TYPE_TIMESTAMP)
105 vkCmdWriteTimestamp(batch->cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
106 query->queryPool, 0);
107 else
108 vkCmdEndQuery(batch->cmdbuf, query->queryPool, 0);
109 return true;
110 }
111
112 static bool
113 zink_get_query_result(struct pipe_context *pctx,
114 struct pipe_query *q,
115 bool wait,
116 union pipe_query_result *result)
117 {
118 struct zink_screen *screen = zink_screen(pctx->screen);
119 struct zink_query *query = (struct zink_query *)q;
120 VkQueryResultFlagBits flags = 0;
121
122 pctx->flush(pctx, NULL, 0);
123
124 if (wait)
125 flags |= VK_QUERY_RESULT_WAIT_BIT;
126
127 if (query->use_64bit)
128 flags |= VK_QUERY_RESULT_64_BIT;
129
130 VkResult status = vkGetQueryPoolResults(screen->dev, query->queryPool,
131 0, 1, sizeof(*result), result,
132 0, flags);
133 return status == VK_SUCCESS;
134 }
135
136 void
137 zink_context_query_init(struct pipe_context *pctx)
138 {
139 pctx->create_query = zink_create_query;
140 pctx->destroy_query = zink_destroy_query;
141 pctx->begin_query = zink_begin_query;
142 pctx->end_query = zink_end_query;
143 pctx->get_query_result = zink_get_query_result;
144 }