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