1 // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef VK_QUERY_POOL_HPP_
16 #define VK_QUERY_POOL_HPP_
17
18 #include "VkObject.hpp"
19
20 #include "marl/event.h"
21 #include "marl/waitgroup.h"
22
23 #include <atomic>
24 #include <condition_variable>
25 #include <mutex>
26
27 namespace vk {
28
29 class Query
30 {
31 public:
32 Query(VkQueryType type);
33
34 enum State
35 {
36 UNAVAILABLE,
37 ACTIVE,
38 FINISHED
39 };
40
41 struct Data
42 {
43 State state; // The current query state.
44 int64_t value; // The current query value.
45 };
46
47 // reset() sets the state of the Query to UNAVAILABLE, sets the type to
48 // INVALID_TYPE and clears the query value.
49 // reset() must not be called while the query is in the ACTIVE state.
50 void reset();
51
52 // start() begins a query task which is closed with a call to finish().
53 // Query tasks can be nested.
54 // start() sets the state to ACTIVE.
55 void start();
56
57 // finish() ends a query task begun with a call to start().
58 // Once all query tasks are complete the query will transition to the
59 // FINISHED state.
60 // finish() must only be called when in the ACTIVE state.
61 void finish();
62
63 // wait() blocks until the query reaches the FINISHED state.
64 void wait();
65
66 // getData() returns the current query state and value.
67 Data getData() const;
68
69 // getType() returns the type of query.
70 VkQueryType getType() const;
71
72 // set() replaces the current query value with val.
73 void set(int64_t val);
74
75 // add() adds val to the current query value.
76 void add(int64_t val);
77
78 private:
79 marl::WaitGroup wg;
80 marl::Event finished;
81 std::atomic<State> state;
82 std::atomic<VkQueryType> type;
83 std::atomic<int64_t> value;
84 };
85
86 class QueryPool : public Object<QueryPool, VkQueryPool>
87 {
88 public:
89 QueryPool(const VkQueryPoolCreateInfo *pCreateInfo, void *mem);
90 void destroy(const VkAllocationCallbacks *pAllocator);
91
92 static size_t ComputeRequiredAllocationSize(const VkQueryPoolCreateInfo *pCreateInfo);
93
94 VkResult getResults(uint32_t firstQuery, uint32_t queryCount, size_t dataSize,
95 void *pData, VkDeviceSize stride, VkQueryResultFlags flags) const;
96 void begin(uint32_t query, VkQueryControlFlags flags);
97 void end(uint32_t query);
98 void reset(uint32_t firstQuery, uint32_t queryCount);
99
100 void writeTimestamp(uint32_t query);
101
getQuery(uint32_t query) const102 inline Query *getQuery(uint32_t query) const { return &(pool[query]); }
103
104 private:
105 Query *pool;
106 VkQueryType type;
107 uint32_t count;
108 };
109
Cast(VkQueryPool object)110 static inline QueryPool *Cast(VkQueryPool object)
111 {
112 return QueryPool::Cast(object);
113 }
114
115 } // namespace vk
116
117 #endif // VK_QUERY_POOL_HPP_
118