xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/metal/QueryMtl.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright (c) 2020 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // QueryMtl.h:
7 //    Defines the class interface for QueryMtl, implementing QueryImpl.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_METAL_QUERYMTL_H_
11 #define LIBANGLE_RENDERER_METAL_QUERYMTL_H_
12 
13 #include "libANGLE/renderer/QueryImpl.h"
14 #include "libANGLE/renderer/metal/mtl_common.h"
15 #include "libANGLE/renderer/metal/mtl_resources.h"
16 
17 namespace rx
18 {
19 
20 class ContextMtl;
21 
22 // The class represents offset(s) allocated in the visiblity buffer for an occlusion query.
23 // See doc/OcclusionQuery.md.
24 // An occlusion query might have more than one offsets allocated, but all of them must be adjacent
25 // to each other. Multiple offsets typically allocated when the query is paused and resumed during
26 // viewport clear emulation with draw operations. In such case, Metal doesn't allow an offset to
27 // be reused in a render pass, hence multiple offsets will be allocated, and their values will
28 // be accumulated.
29 class VisibilityBufferOffsetsMtl
30 {
31   public:
clear()32     void clear() { mStartOffset = mNumOffsets = 0; }
empty()33     bool empty() const { return mNumOffsets == 0; }
size()34     uint32_t size() const { return mNumOffsets; }
35 
36     // Return last offset
back()37     uint32_t back() const
38     {
39         ASSERT(!empty());
40         return mStartOffset + (mNumOffsets - 1) * mtl::kOcclusionQueryResultSize;
41     }
42 
front()43     uint32_t front() const
44     {
45         ASSERT(!empty());
46         return mStartOffset;
47     }
48 
setStartOffset(uint32_t offset)49     void setStartOffset(uint32_t offset)
50     {
51         ASSERT(empty());
52         mStartOffset = offset;
53         mNumOffsets  = 1;
54     }
addOffset()55     void addOffset()
56     {
57         ASSERT(!empty());
58         mNumOffsets++;
59     }
60 
61   private:
62     uint32_t mStartOffset = 0;
63     uint32_t mNumOffsets  = 0;
64 };
65 
66 class QueryMtl : public QueryImpl
67 {
68   public:
69     QueryMtl(gl::QueryType type);
70     ~QueryMtl() override;
71 
72     void onDestroy(const gl::Context *context) override;
73 
74     angle::Result begin(const gl::Context *context) override;
75     angle::Result end(const gl::Context *context) override;
76     angle::Result queryCounter(const gl::Context *context) override;
77     angle::Result getResult(const gl::Context *context, GLint *params) override;
78     angle::Result getResult(const gl::Context *context, GLuint *params) override;
79     angle::Result getResult(const gl::Context *context, GLint64 *params) override;
80     angle::Result getResult(const gl::Context *context, GLuint64 *params) override;
81     angle::Result isResultAvailable(const gl::Context *context, bool *available) override;
82 
83     // Get allocated offsets in the render pass's occlusion query pool.
getAllocatedVisibilityOffsets()84     const VisibilityBufferOffsetsMtl &getAllocatedVisibilityOffsets() const
85     {
86         return mVisibilityBufferOffsets;
87     }
88     // Set first allocated offset in the render pass's occlusion query pool.
setFirstAllocatedVisibilityOffset(uint32_t off)89     void setFirstAllocatedVisibilityOffset(uint32_t off)
90     {
91         mVisibilityBufferOffsets.setStartOffset(off);
92     }
93     // Add more offset allocated for the occlusion query
addAllocatedVisibilityOffset()94     void addAllocatedVisibilityOffset() { mVisibilityBufferOffsets.addOffset(); }
95 
clearAllocatedVisibilityOffsets()96     void clearAllocatedVisibilityOffsets() { mVisibilityBufferOffsets.clear(); }
97     // Returns the buffer containing the final occlusion query result.
getVisibilityResultBuffer()98     const mtl::BufferRef &getVisibilityResultBuffer() const { return mVisibilityResultBuffer; }
99     // Reset the occlusion query result stored in buffer to zero
100     void resetVisibilityResult(ContextMtl *contextMtl);
101     void onTransformFeedbackEnd(const gl::Context *context);
102 
103     // If the timestamp query is still active upon context switch,
104     // must set/unset the active timestamp query entry on the command
105     // queue.
106     void onContextMakeCurrent(const gl::Context *context);
107     void onContextUnMakeCurrent(const gl::Context *context);
108 
109   private:
110     template <typename T>
111     angle::Result waitAndGetResult(const gl::Context *context, T *params);
112 
113     // List of offsets in the render pass's occlusion query pool buffer allocated for this query
114     VisibilityBufferOffsetsMtl mVisibilityBufferOffsets;
115     mtl::BufferRef mVisibilityResultBuffer;
116 
117     size_t mTransformFeedbackPrimitivesDrawn = 0;
118 
119     uint64_t mTimeElapsedEntry = 0;
120 };
121 
122 }  // namespace rx
123 
124 #endif /* LIBANGLE_RENDERER_METAL_QUERYMTL_H_ */
125