• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Query.cpp: Implements the es2::Query class
16 
17 #include "Query.h"
18 
19 #include "main.h"
20 #include "Common/Thread.hpp"
21 
22 namespace es2
23 {
24 
Query(GLuint name,GLenum type)25 Query::Query(GLuint name, GLenum type) : NamedObject(name)
26 {
27 	mQuery = nullptr;
28 	mStatus = GL_FALSE;
29 	mResult = GL_FALSE;
30 	mType = type;
31 }
32 
~Query()33 Query::~Query()
34 {
35 	mQuery->release();
36 }
37 
begin()38 void Query::begin()
39 {
40 	if(!mQuery)
41 	{
42 		sw::Query::Type type;
43 		switch(mType)
44 		{
45 		case GL_ANY_SAMPLES_PASSED_EXT:
46 		case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
47 			type = sw::Query::FRAGMENTS_PASSED;
48 			break;
49 		case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
50 			type = sw::Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
51 			break;
52 		default:
53 			UNREACHABLE(mType);
54 			return;
55 		}
56 
57 		mQuery = new sw::Query(type);
58 
59 		if(!mQuery)
60 		{
61 			return error(GL_OUT_OF_MEMORY);
62 		}
63 	}
64 
65 	Device *device = getDevice();
66 
67 	mQuery->begin();
68 	device->addQuery(mQuery);
69 	switch(mType)
70 	{
71 	case GL_ANY_SAMPLES_PASSED_EXT:
72 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
73 		device->setOcclusionEnabled(true);
74 		break;
75 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
76 		device->setTransformFeedbackQueryEnabled(true);
77 		break;
78 	default:
79 		ASSERT(false);
80 	}
81 }
82 
end()83 void Query::end()
84 {
85 	if(!mQuery)
86 	{
87 		return error(GL_INVALID_OPERATION);
88 	}
89 
90 	Device *device = getDevice();
91 
92 	mQuery->end();
93 	device->removeQuery(mQuery);
94 	switch(mType)
95 	{
96 	case GL_ANY_SAMPLES_PASSED_EXT:
97 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
98 		device->setOcclusionEnabled(false);
99 		break;
100 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
101 		device->setTransformFeedbackQueryEnabled(false);
102 		break;
103 	default:
104 		ASSERT(false);
105 	}
106 
107 	mStatus = GL_FALSE;
108 	mResult = GL_FALSE;
109 }
110 
getResult()111 GLuint Query::getResult()
112 {
113 	if(mQuery)
114 	{
115 		while(!testQuery())
116 		{
117 			sw::Thread::yield();
118 		}
119 	}
120 
121 	return (GLuint)mResult;
122 }
123 
isResultAvailable()124 GLboolean Query::isResultAvailable()
125 {
126 	if(mQuery)
127 	{
128 		testQuery();
129 	}
130 
131 	return mStatus;
132 }
133 
getType() const134 GLenum Query::getType() const
135 {
136 	return mType;
137 }
138 
testQuery()139 GLboolean Query::testQuery()
140 {
141 	if(mQuery != nullptr && mStatus != GL_TRUE)
142 	{
143 		if(!mQuery->building && mQuery->isReady())
144 		{
145 			unsigned int resultSum = mQuery->data;
146 			mStatus = GL_TRUE;
147 
148 			switch(mType)
149 			{
150 			case GL_ANY_SAMPLES_PASSED_EXT:
151 			case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
152 				mResult = (resultSum > 0) ? GL_TRUE : GL_FALSE;
153 				break;
154 			case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
155 				mResult = resultSum;
156 				break;
157 			default:
158 				ASSERT(false);
159 			}
160 		}
161 
162 		return mStatus;
163 	}
164 
165 	return GL_TRUE;   // Prevent blocking when query is nullptr
166 }
167 }
168