Query9.cpp (4848B)
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 { 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 29 Query9::~Query9() 30 { 31 SafeRelease(mQuery); 32 } 33 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 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 69 angle::Result Query9::queryCounter(const gl::Context *context) 70 { 71 ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context)); 72 } 73 74 template <typename T> 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 92 angle::Result Query9::getResult(const gl::Context *context, GLint *params) 93 { 94 return getResultBase(GetImplAs<Context9>(context), params); 95 } 96 97 angle::Result Query9::getResult(const gl::Context *context, GLuint *params) 98 { 99 return getResultBase(GetImplAs<Context9>(context), params); 100 } 101 102 angle::Result Query9::getResult(const gl::Context *context, GLint64 *params) 103 { 104 return getResultBase(GetImplAs<Context9>(context), params); 105 } 106 107 angle::Result Query9::getResult(const gl::Context *context, GLuint64 *params) 108 { 109 return getResultBase(GetImplAs<Context9>(context), params); 110 } 111 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 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