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