2 #include "zink_context.h"
3 #include "zink_screen.h"
5 #include "util/u_memory.h"
6 #include "util/u_dump.h"
9 enum pipe_query_type type
;
10 VkQueryPool queryPool
;
17 convert_query_type(unsigned query_type
, bool *use_64bit
, bool *precise
)
22 case PIPE_QUERY_OCCLUSION_COUNTER
:
25 case PIPE_QUERY_OCCLUSION_PREDICATE
:
26 case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE
:
27 return VK_QUERY_TYPE_OCCLUSION
;
28 case PIPE_QUERY_TIMESTAMP
:
30 return VK_QUERY_TYPE_TIMESTAMP
;
31 case PIPE_QUERY_PIPELINE_STATISTICS
:
32 return VK_QUERY_TYPE_PIPELINE_STATISTICS
;
34 debug_printf("unknown query: %s\n",
35 util_str_query_type(query_type
, true));
36 unreachable("zink: unknown query type");
40 static struct pipe_query
*
41 zink_create_query(struct pipe_context
*pctx
,
42 unsigned query_type
, unsigned index
)
44 struct zink_screen
*screen
= zink_screen(pctx
->screen
);
45 struct zink_query
*query
= CALLOC_STRUCT(zink_query
);
46 VkQueryPoolCreateInfo pool_create
= {};
51 query
->type
= query_type
;
52 query
->vkqtype
= convert_query_type(query_type
, &query
->use_64bit
, &query
->precise
);
53 if (query
->vkqtype
== -1)
56 pool_create
.sType
= VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO
;
57 pool_create
.queryType
= query
->vkqtype
;
58 pool_create
.queryCount
= 1;
60 VkResult status
= vkCreateQueryPool(screen
->dev
, &pool_create
, NULL
, &query
->queryPool
);
61 if (status
!= VK_SUCCESS
) {
65 return (struct pipe_query
*)query
;
69 zink_destroy_query(struct pipe_context
*pctx
,
72 struct zink_screen
*screen
= zink_screen(pctx
->screen
);
73 struct zink_query
*query
= CALLOC_STRUCT(zink_query
);
75 vkDestroyQueryPool(screen
->dev
, query
->queryPool
, NULL
);
79 zink_begin_query(struct pipe_context
*pctx
,
82 struct zink_context
*ctx
= zink_context(pctx
);
83 struct zink_query
*query
= (struct zink_query
*)q
;
85 if (query
->vkqtype
== VK_QUERY_TYPE_TIMESTAMP
)
88 VkQueryControlFlags flags
= 0;
90 flags
|= VK_QUERY_CONTROL_PRECISE_BIT
;
92 struct zink_batch
*batch
= zink_curr_batch(ctx
);
93 vkCmdBeginQuery(batch
->cmdbuf
, query
->queryPool
, 0, flags
);
99 zink_end_query(struct pipe_context
*pctx
,
100 struct pipe_query
*q
)
102 struct zink_context
*ctx
= zink_context(pctx
);
103 struct zink_query
*query
= (struct zink_query
*)q
;
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);
110 vkCmdEndQuery(batch
->cmdbuf
, query
->queryPool
, 0);
115 zink_get_query_result(struct pipe_context
*pctx
,
116 struct pipe_query
*q
,
118 union pipe_query_result
*result
)
120 struct zink_screen
*screen
= zink_screen(pctx
->screen
);
121 struct zink_query
*query
= (struct zink_query
*)q
;
122 VkQueryResultFlagBits flags
= 0;
124 pctx
->flush(pctx
, NULL
, 0);
127 flags
|= VK_QUERY_RESULT_WAIT_BIT
;
129 if (query
->use_64bit
)
130 flags
|= VK_QUERY_RESULT_64_BIT
;
132 if (vkGetQueryPoolResults(screen
->dev
, query
->queryPool
,
133 0, 1, sizeof(*result
), result
,
134 0, flags
) != VK_SUCCESS
)
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;
154 zink_context_query_init(struct pipe_context
*pctx
)
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
;