1 //
2 // Copyright 2013 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
7 // Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl.
8
9 #include "libANGLE/renderer/d3d/d3d9/Query9.h"
10
11 #include "libANGLE/Context.h"
12 #include "libANGLE/renderer/d3d/d3d9/Context9.h"
13 #include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
14 #include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
15
16 #include <GLES2/gl2ext.h>
17
18 namespace rx
19 {
Query9(Renderer9 * renderer,gl::QueryType type)20 Query9::Query9(Renderer9 *renderer, gl::QueryType type)
21 : QueryImpl(type),
22 mGetDataAttemptCount(0),
23 mResult(GL_FALSE),
24 mQueryFinished(false),
25 mRenderer(renderer),
26 mQuery(nullptr)
27 {}
28
~Query9()29 Query9::~Query9()
30 {
31 SafeRelease(mQuery);
32 }
33
begin(const gl::Context * context)34 angle::Result Query9::begin(const gl::Context *context)
35 {
36 Context9 *context9 = GetImplAs<Context9>(context);
37
38 D3DQUERYTYPE d3dQueryType = gl_d3d9::ConvertQueryType(getType());
39 if (mQuery == nullptr)
40 {
41 HRESULT result = mRenderer->getDevice()->CreateQuery(d3dQueryType, &mQuery);
42 ANGLE_TRY_HR(context9, result, "Internal query creation failed");
43 }
44
45 if (d3dQueryType != D3DQUERYTYPE_EVENT)
46 {
47 HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
48 ASSERT(SUCCEEDED(result));
49 ANGLE_TRY_HR(context9, result, "Failed to begin internal query");
50 }
51
52 return angle::Result::Continue;
53 }
54
end(const gl::Context * context)55 angle::Result Query9::end(const gl::Context *context)
56 {
57 Context9 *context9 = GetImplAs<Context9>(context);
58 ASSERT(mQuery);
59
60 HRESULT result = mQuery->Issue(D3DISSUE_END);
61 ASSERT(SUCCEEDED(result));
62 ANGLE_TRY_HR(context9, result, "Failed to end internal query");
63 mQueryFinished = false;
64 mResult = GL_FALSE;
65
66 return angle::Result::Continue;
67 }
68
queryCounter(const gl::Context * context)69 angle::Result Query9::queryCounter(const gl::Context *context)
70 {
71 ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
72 }
73
74 template <typename T>
getResultBase(Context9 * context9,T * params)75 angle::Result Query9::getResultBase(Context9 *context9, T *params)
76 {
77 while (!mQueryFinished)
78 {
79 ANGLE_TRY(testQuery(context9));
80
81 if (!mQueryFinished)
82 {
83 Sleep(0);
84 }
85 }
86
87 ASSERT(mQueryFinished);
88 *params = static_cast<T>(mResult);
89 return angle::Result::Continue;
90 }
91
getResult(const gl::Context * context,GLint * params)92 angle::Result Query9::getResult(const gl::Context *context, GLint *params)
93 {
94 return getResultBase(GetImplAs<Context9>(context), params);
95 }
96
getResult(const gl::Context * context,GLuint * params)97 angle::Result Query9::getResult(const gl::Context *context, GLuint *params)
98 {
99 return getResultBase(GetImplAs<Context9>(context), params);
100 }
101
getResult(const gl::Context * context,GLint64 * params)102 angle::Result Query9::getResult(const gl::Context *context, GLint64 *params)
103 {
104 return getResultBase(GetImplAs<Context9>(context), params);
105 }
106
getResult(const gl::Context * context,GLuint64 * params)107 angle::Result Query9::getResult(const gl::Context *context, GLuint64 *params)
108 {
109 return getResultBase(GetImplAs<Context9>(context), params);
110 }
111
isResultAvailable(const gl::Context * context,bool * available)112 angle::Result Query9::isResultAvailable(const gl::Context *context, bool *available)
113 {
114 ANGLE_TRY(testQuery(GetImplAs<Context9>(context)));
115 *available = mQueryFinished;
116 return angle::Result::Continue;
117 }
118
testQuery(Context9 * context9)119 angle::Result Query9::testQuery(Context9 *context9)
120 {
121 if (!mQueryFinished)
122 {
123 ASSERT(mQuery);
124
125 HRESULT result = S_OK;
126 switch (getType())
127 {
128 case gl::QueryType::AnySamples:
129 case gl::QueryType::AnySamplesConservative:
130 {
131 DWORD numPixels = 0;
132 result = mQuery->GetData(&numPixels, sizeof(numPixels), D3DGETDATA_FLUSH);
133 if (result == S_OK)
134 {
135 mQueryFinished = true;
136 mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
137 }
138 break;
139 }
140
141 case gl::QueryType::CommandsCompleted:
142 {
143 BOOL completed = FALSE;
144 result = mQuery->GetData(&completed, sizeof(completed), D3DGETDATA_FLUSH);
145 if (result == S_OK)
146 {
147 mQueryFinished = true;
148 mResult = (completed == TRUE) ? GL_TRUE : GL_FALSE;
149 }
150 break;
151 }
152
153 default:
154 UNREACHABLE();
155 break;
156 }
157
158 if (!mQueryFinished)
159 {
160 ANGLE_TRY_HR(context9, result, "Failed to test get query result");
161
162 mGetDataAttemptCount++;
163 bool checkDeviceLost =
164 (mGetDataAttemptCount % kPollingD3DDeviceLostCheckFrequency) == 0;
165 if (checkDeviceLost && mRenderer->testDeviceLost())
166 {
167 ANGLE_TRY_HR(context9, D3DERR_DEVICELOST,
168 "Failed to test get query result, device is lost");
169 }
170 }
171 }
172
173 return angle::Result::Continue;
174 }
175
176 } // namespace rx
177