michael@0: #include "precompiled.h" michael@0: // michael@0: // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: // michael@0: michael@0: // Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl. michael@0: michael@0: michael@0: #include "libGLESv2/renderer/Query9.h" michael@0: #include "libGLESv2/main.h" michael@0: #include "libGLESv2/renderer/renderer9_utils.h" michael@0: #include "libGLESv2/renderer/Renderer9.h" michael@0: michael@0: namespace rx michael@0: { michael@0: michael@0: Query9::Query9(rx::Renderer9 *renderer, GLenum type) : QueryImpl(type) michael@0: { michael@0: mRenderer = renderer; michael@0: mQuery = NULL; michael@0: } michael@0: michael@0: Query9::~Query9() michael@0: { michael@0: if (mQuery) michael@0: { michael@0: mQuery->Release(); michael@0: mQuery = NULL; michael@0: } michael@0: } michael@0: michael@0: void Query9::begin() michael@0: { michael@0: if (mQuery == NULL) michael@0: { michael@0: if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery))) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); michael@0: ASSERT(SUCCEEDED(result)); michael@0: } michael@0: michael@0: void Query9::end() michael@0: { michael@0: if (mQuery == NULL) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: HRESULT result = mQuery->Issue(D3DISSUE_END); michael@0: ASSERT(SUCCEEDED(result)); michael@0: michael@0: mStatus = GL_FALSE; michael@0: mResult = GL_FALSE; michael@0: } michael@0: michael@0: GLuint Query9::getResult() michael@0: { michael@0: if (mQuery != NULL) michael@0: { michael@0: while (!testQuery()) michael@0: { michael@0: Sleep(0); michael@0: // explicitly check for device loss michael@0: // some drivers seem to return S_FALSE even if the device is lost michael@0: // instead of D3DERR_DEVICELOST like they should michael@0: if (mRenderer->testDeviceLost(true)) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, 0); michael@0: } michael@0: } michael@0: } michael@0: michael@0: return mResult; michael@0: } michael@0: michael@0: GLboolean Query9::isResultAvailable() michael@0: { michael@0: if (mQuery != NULL) michael@0: { michael@0: testQuery(); michael@0: } michael@0: michael@0: return mStatus; michael@0: } michael@0: michael@0: GLboolean Query9::testQuery() michael@0: { michael@0: if (mQuery != NULL && mStatus != GL_TRUE) michael@0: { michael@0: DWORD numPixels = 0; michael@0: michael@0: HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH); michael@0: if (hres == S_OK) michael@0: { michael@0: mStatus = GL_TRUE; michael@0: michael@0: switch (getType()) michael@0: { michael@0: case GL_ANY_SAMPLES_PASSED_EXT: michael@0: case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: michael@0: mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; michael@0: break; michael@0: default: michael@0: ASSERT(false); michael@0: } michael@0: } michael@0: else if (d3d9::isDeviceLostError(hres)) michael@0: { michael@0: mRenderer->notifyDeviceLost(); michael@0: return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); michael@0: } michael@0: michael@0: return mStatus; michael@0: } michael@0: michael@0: return GL_TRUE; // prevent blocking when query is null michael@0: } michael@0: michael@0: }