blob: c04327cce506060e978c1a8de2776eeb11c7f02e [file] [log] [blame]
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00001//
2// Copyright (c) 2012 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// Query.cpp: Implements the gl::Query class
8
9#include "libGLESv2/Query.h"
10
11#include "libGLESv2/main.h"
12
13namespace gl
14{
15
daniel@transgaming.com76d3e6e2012-10-31 19:55:33 +000016Query::Query(rx::Renderer9 *renderer, GLuint id, GLenum type) : RefCountObject(id)
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000017{
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000018 mRenderer = renderer;
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000019 mQuery = NULL;
20 mStatus = GL_FALSE;
21 mResult = GL_FALSE;
22 mType = type;
23}
24
25Query::~Query()
26{
27 if (mQuery != NULL)
28 {
29 mQuery->Release();
30 mQuery = NULL;
31 }
32}
33
34void Query::begin()
35{
36 if (mQuery == NULL)
37 {
daniel@transgaming.com621ce052012-10-31 17:52:29 +000038 // D3D9_REPLACE
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000039 if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery)))
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000040 {
41 return error(GL_OUT_OF_MEMORY);
42 }
43 }
44
45 HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
46 ASSERT(SUCCEEDED(result));
47}
48
49void Query::end()
50{
51 if (mQuery == NULL)
52 {
53 return error(GL_INVALID_OPERATION);
54 }
55
56 HRESULT result = mQuery->Issue(D3DISSUE_END);
57 ASSERT(SUCCEEDED(result));
58
59 mStatus = GL_FALSE;
60 mResult = GL_FALSE;
61}
62
63GLuint Query::getResult()
64{
65 if (mQuery != NULL)
66 {
67 while (!testQuery())
68 {
69 Sleep(0);
70 // explicitly check for device loss
71 // some drivers seem to return S_FALSE even if the device is lost
72 // instead of D3DERR_DEVICELOST like they should
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +000073 if (mRenderer->testDeviceLost(true))
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000074 {
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000075 return error(GL_OUT_OF_MEMORY, 0);
76 }
77 }
78 }
79
80 return (GLuint)mResult;
81}
82
83GLboolean Query::isResultAvailable()
84{
85 if (mQuery != NULL)
86 {
87 testQuery();
88 }
89
90 return mStatus;
91}
92
93GLenum Query::getType() const
94{
95 return mType;
96}
97
98GLboolean Query::testQuery()
99{
100 if (mQuery != NULL && mStatus != GL_TRUE)
101 {
102 DWORD numPixels = 0;
103
104 HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH);
105 if (hres == S_OK)
106 {
107 mStatus = GL_TRUE;
108
109 switch (mType)
110 {
111 case GL_ANY_SAMPLES_PASSED_EXT:
112 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
113 mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
114 break;
115 default:
116 ASSERT(false);
117 }
118 }
119 else if (checkDeviceLost(hres))
120 {
121 return error(GL_OUT_OF_MEMORY, GL_TRUE);
122 }
123
124 return mStatus;
125 }
126
127 return GL_TRUE; // prevent blocking when query is null
128}
129}