1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
3 | #include "BsGLOcclusionQuery.h" |
4 | #include "BsGLCommandBuffer.h" |
5 | #include "Math/BsMath.h" |
6 | #include "Profiling/BsRenderStats.h" |
7 | |
8 | namespace bs { namespace ct |
9 | { |
10 | GLOcclusionQuery::GLOcclusionQuery(bool binary, UINT32 deviceIdx) |
11 | :OcclusionQuery(binary) |
12 | { |
13 | assert(deviceIdx == 0 && "Multiple GPUs not supported natively on OpenGL." ); |
14 | |
15 | glGenQueries(1, &mQueryObj); |
16 | BS_CHECK_GL_ERROR(); |
17 | |
18 | BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query); |
19 | } |
20 | |
21 | GLOcclusionQuery::~GLOcclusionQuery() |
22 | { |
23 | glDeleteQueries(1, &mQueryObj); |
24 | BS_CHECK_GL_ERROR(); |
25 | |
26 | BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query); |
27 | } |
28 | |
29 | void GLOcclusionQuery::begin(const SPtr<CommandBuffer>& cb) |
30 | { |
31 | auto execute = [&]() |
32 | { |
33 | glBeginQuery(mBinary ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED, mQueryObj); |
34 | BS_CHECK_GL_ERROR(); |
35 | |
36 | mNumSamples = 0; |
37 | mEndIssued = false; |
38 | setActive(true); |
39 | }; |
40 | |
41 | if (cb == nullptr) |
42 | execute(); |
43 | else |
44 | { |
45 | SPtr<GLCommandBuffer> glCB = std::static_pointer_cast<GLCommandBuffer>(cb); |
46 | glCB->queueCommand(execute); |
47 | } |
48 | } |
49 | |
50 | void GLOcclusionQuery::end(const SPtr<CommandBuffer>& cb) |
51 | { |
52 | auto execute = [&]() |
53 | { |
54 | glEndQuery(mBinary ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED); |
55 | BS_CHECK_GL_ERROR(); |
56 | |
57 | mEndIssued = true; |
58 | mFinalized = false; |
59 | }; |
60 | |
61 | if (cb == nullptr) |
62 | execute(); |
63 | else |
64 | { |
65 | SPtr<GLCommandBuffer> glCB = std::static_pointer_cast<GLCommandBuffer>(cb); |
66 | glCB->queueCommand(execute); |
67 | } |
68 | } |
69 | |
70 | bool GLOcclusionQuery::isReady() const |
71 | { |
72 | if (!mEndIssued) |
73 | return false; |
74 | |
75 | GLint done = 0; |
76 | glGetQueryObjectiv(mQueryObj, GL_QUERY_RESULT_AVAILABLE, &done); |
77 | BS_CHECK_GL_ERROR(); |
78 | |
79 | return done == GL_TRUE; |
80 | } |
81 | |
82 | UINT32 GLOcclusionQuery::getNumSamples() |
83 | { |
84 | if (!mFinalized && isReady()) |
85 | { |
86 | finalize(); |
87 | } |
88 | |
89 | return mNumSamples; |
90 | } |
91 | |
92 | void GLOcclusionQuery::finalize() |
93 | { |
94 | mFinalized = true; |
95 | |
96 | if (mBinary) |
97 | { |
98 | GLuint anyPassed = GL_FALSE; |
99 | glGetQueryObjectuiv(mQueryObj, GL_QUERY_RESULT, &anyPassed); |
100 | BS_CHECK_GL_ERROR(); |
101 | |
102 | mNumSamples = anyPassed == GL_TRUE ? 1 : 0; |
103 | } |
104 | else |
105 | { |
106 | GLuint numSamples = 0; |
107 | glGetQueryObjectuiv(mQueryObj, GL_QUERY_RESULT, &numSamples); |
108 | BS_CHECK_GL_ERROR(); |
109 | |
110 | mNumSamples = (UINT32)numSamples; |
111 | } |
112 | } |
113 | }} |