1 /* Copyright (c) 2015-2021 The Khronos Group Inc.
2 * Copyright (c) 2015-2021 Valve Corporation
3 * Copyright (c) 2015-2021 LunarG, Inc.
4 * Copyright (C) 2015-2021 Google Inc.
5 * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * Author: Courtney Goeltzenleuchter <courtneygo@google.com>
20 * Author: Tobin Ehlis <tobine@google.com>
21 * Author: Chris Forbes <chrisf@ijw.co.nz>
22 * Author: Mark Lobodzinski <mark@lunarg.com>
23 * Author: Dave Houlton <daveh@lunarg.com>
24 * Author: John Zulauf <jzulauf@lunarg.com>
25 * Author: Tobias Hector <tobias.hector@amd.com>
26 */
27 #pragma once
28 #include "base_node.h"
29 #include "hash_vk_types.h"
30
31 enum QueryState {
32 QUERYSTATE_UNKNOWN, // Initial state.
33 QUERYSTATE_RESET, // After resetting.
34 QUERYSTATE_RUNNING, // Query running.
35 QUERYSTATE_ENDED, // Query ended but results may not be available.
36 QUERYSTATE_AVAILABLE, // Results available.
37 };
38
39 class QUERY_POOL_STATE : public BASE_NODE {
40 public:
QUERY_POOL_STATE(VkQueryPool qp,const VkQueryPoolCreateInfo * pCreateInfo,uint32_t index_count,uint32_t n_perf_pass,bool has_cb,bool has_rb)41 QUERY_POOL_STATE(VkQueryPool qp, const VkQueryPoolCreateInfo *pCreateInfo, uint32_t index_count, uint32_t n_perf_pass,
42 bool has_cb, bool has_rb)
43 : BASE_NODE(qp, kVulkanObjectTypeQueryPool),
44 createInfo(*pCreateInfo),
45 has_perf_scope_command_buffer(has_cb),
46 has_perf_scope_render_pass(has_rb),
47 n_performance_passes(n_perf_pass),
48 perf_counter_index_count(index_count),
49 query_states_(pCreateInfo->queryCount) {
50 for (uint32_t i = 0; i < pCreateInfo->queryCount; ++i) {
51 auto perf_size = n_perf_pass > 0 ? n_perf_pass : 1;
52 query_states_[i].reserve(perf_size);
53 for (uint32_t p = 0; p < perf_size; p++) {
54 query_states_[i].emplace_back(QUERYSTATE_UNKNOWN);
55 }
56 }
57 }
58
pool()59 VkQueryPool pool() const { return handle_.Cast<VkQueryPool>(); }
60
SetQueryState(uint32_t query,uint32_t perf_pass,QueryState state)61 void SetQueryState(uint32_t query, uint32_t perf_pass, QueryState state) {
62 assert(query < query_states_.size());
63 assert((n_performance_passes == 0 && perf_pass == 0) || (perf_pass < n_performance_passes));
64 query_states_[query][perf_pass] = state;
65 }
GetQueryState(uint32_t query,uint32_t perf_pass)66 QueryState GetQueryState(uint32_t query, uint32_t perf_pass) const {
67 assert(query < query_states_.size());
68 assert((n_performance_passes == 0 && perf_pass == 0) || (perf_pass < n_performance_passes));
69 return query_states_[query][perf_pass];
70 }
71
72 const VkQueryPoolCreateInfo createInfo;
73
74 const bool has_perf_scope_command_buffer;
75 const bool has_perf_scope_render_pass;
76 const uint32_t n_performance_passes;
77 const uint32_t perf_counter_index_count;
78
79 private:
80 std::vector<small_vector<QueryState, 1>> query_states_;
81 };
82
83 struct QueryObject {
84 VkQueryPool pool;
85 uint32_t query;
86 // These next two fields are *not* used in hash or comparison, they are effectively a data payload
87 uint32_t index; // must be zero if !indexed
88 uint32_t perf_pass;
89 bool indexed;
90 // Command index in the command buffer where the end of the query was
91 // recorded (equal to the number of commands in the command buffer before
92 // the end of the query).
93 uint64_t endCommandIndex;
94
QueryObjectQueryObject95 QueryObject(VkQueryPool pool_, uint32_t query_)
96 : pool(pool_), query(query_), index(0), perf_pass(0), indexed(false), endCommandIndex(0) {}
QueryObjectQueryObject97 QueryObject(VkQueryPool pool_, uint32_t query_, uint32_t index_)
98 : pool(pool_), query(query_), index(index_), perf_pass(0), indexed(true), endCommandIndex(0) {}
QueryObjectQueryObject99 QueryObject(const QueryObject &obj)
100 : pool(obj.pool),
101 query(obj.query),
102 index(obj.index),
103 perf_pass(obj.perf_pass),
104 indexed(obj.indexed),
105 endCommandIndex(obj.endCommandIndex) {}
QueryObjectQueryObject106 QueryObject(const QueryObject &obj, uint32_t perf_pass_)
107 : pool(obj.pool),
108 query(obj.query),
109 index(obj.index),
110 perf_pass(perf_pass_),
111 indexed(obj.indexed),
112 endCommandIndex(obj.endCommandIndex) {}
113 bool operator<(const QueryObject &rhs) const {
114 return (pool == rhs.pool) ? ((query == rhs.query) ? (perf_pass < rhs.perf_pass) : (query < rhs.query)) : pool < rhs.pool;
115 }
116 };
117
118 inline bool operator==(const QueryObject &query1, const QueryObject &query2) {
119 return ((query1.pool == query2.pool) && (query1.query == query2.query) && (query1.perf_pass == query2.perf_pass));
120 }
121
122 typedef std::map<QueryObject, QueryState> QueryMap;
123
124 enum QueryResultType {
125 QUERYRESULT_UNKNOWN,
126 QUERYRESULT_NO_DATA,
127 QUERYRESULT_SOME_DATA,
128 QUERYRESULT_WAIT_ON_RESET,
129 QUERYRESULT_WAIT_ON_RUNNING,
130 };
131
string_QueryResultType(QueryResultType result_type)132 inline const char *string_QueryResultType(QueryResultType result_type) {
133 switch (result_type) {
134 case QUERYRESULT_UNKNOWN:
135 return "query may be in an unknown state";
136 case QUERYRESULT_NO_DATA:
137 return "query may return no data";
138 case QUERYRESULT_SOME_DATA:
139 return "query will return some data or availability bit";
140 case QUERYRESULT_WAIT_ON_RESET:
141 return "waiting on a query that has been reset and not issued yet";
142 case QUERYRESULT_WAIT_ON_RUNNING:
143 return "waiting on a query that has not ended yet";
144 }
145 assert(false);
146 return "UNKNOWN QUERY STATE"; // Unreachable.
147 }
148
149 namespace std {
150 template <>
151 struct hash<QueryObject> {
152 size_t operator()(QueryObject query) const throw() {
153 return hash<uint64_t>()((uint64_t)(query.pool)) ^
154 hash<uint64_t>()(static_cast<uint64_t>(query.query) | (static_cast<uint64_t>(query.perf_pass) << 32));
155 }
156 };
157
158 } // namespace std
159