• 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 #include "Direct3DQuery9.hpp"
16 
17 #include "Direct3DDevice9.hpp"
18 #include "Timer.hpp"
19 #include "Renderer.hpp"
20 #include "Debug.hpp"
21 
22 #include <assert.h>
23 
24 namespace D3D9
25 {
Direct3DQuery9(Direct3DDevice9 * device,D3DQUERYTYPE type)26 	Direct3DQuery9::Direct3DQuery9(Direct3DDevice9 *device, D3DQUERYTYPE type) : device(device), type(type)
27 	{
28 		if(type == D3DQUERYTYPE_OCCLUSION)
29 		{
30 			query = new sw::Query(sw::Query::FRAGMENTS_PASSED);
31 		}
32 		else
33 		{
34 			query = 0;
35 		}
36 	}
37 
~Direct3DQuery9()38 	Direct3DQuery9::~Direct3DQuery9()
39 	{
40 		if(query)
41 		{
42 			device->removeQuery(query);
43 
44 			delete query;
45 		}
46 	}
47 
QueryInterface(const IID & iid,void ** object)48 	long Direct3DQuery9::QueryInterface(const IID &iid, void **object)
49 	{
50 		CriticalSection cs(device);
51 
52 		TRACE("");
53 
54 		if(iid == IID_IDirect3DQuery9 ||
55 		   iid == IID_IUnknown)
56 		{
57 			AddRef();
58 			*object = this;
59 
60 			return S_OK;
61 		}
62 
63 		*object = 0;
64 
65 		return NOINTERFACE(iid);
66 	}
67 
AddRef()68 	unsigned long Direct3DQuery9::AddRef()
69 	{
70 		TRACE("");
71 
72 		return Unknown::AddRef();
73 	}
74 
Release()75 	unsigned long Direct3DQuery9::Release()
76 	{
77 		TRACE("");
78 
79 		return Unknown::Release();
80 	}
81 
GetDevice(IDirect3DDevice9 ** device)82 	long __stdcall Direct3DQuery9::GetDevice(IDirect3DDevice9 **device)
83 	{
84 		CriticalSection cs(this->device);
85 
86 		TRACE("");
87 
88 		if(!device)
89 		{
90 			return INVALIDCALL();
91 		}
92 
93 		this->device->AddRef();
94 		*device = this->device;
95 
96 		return D3D_OK;
97 	}
98 
GetType()99 	D3DQUERYTYPE Direct3DQuery9::GetType()
100 	{
101 		CriticalSection cs(device);
102 
103 		return type;
104 	}
105 
GetDataSize()106 	unsigned long Direct3DQuery9::GetDataSize()
107 	{
108 		CriticalSection cs(device);
109 
110 		TRACE("");
111 
112 		switch(type)
113 		{
114 		case D3DQUERYTYPE_VCACHE:				return sizeof(D3DDEVINFO_VCACHE);
115 		case D3DQUERYTYPE_RESOURCEMANAGER:		return sizeof(D3DDEVINFO_RESOURCEMANAGER);
116 		case D3DQUERYTYPE_VERTEXSTATS:			return sizeof(D3DDEVINFO_D3DVERTEXSTATS);
117 		case D3DQUERYTYPE_EVENT:				return sizeof(BOOL);
118 		case D3DQUERYTYPE_OCCLUSION:			return sizeof(DWORD);
119 		case D3DQUERYTYPE_TIMESTAMP:			return sizeof(UINT64);
120 		case D3DQUERYTYPE_TIMESTAMPDISJOINT:	return sizeof(BOOL);
121 		case D3DQUERYTYPE_TIMESTAMPFREQ:		return sizeof(UINT64);
122 		case D3DQUERYTYPE_PIPELINETIMINGS:		return sizeof(D3DDEVINFO_D3D9PIPELINETIMINGS);
123 		case D3DQUERYTYPE_INTERFACETIMINGS:		return sizeof(D3DDEVINFO_D3D9INTERFACETIMINGS);
124 		case D3DQUERYTYPE_VERTEXTIMINGS:		return sizeof(D3DDEVINFO_D3D9STAGETIMINGS);
125 		case D3DQUERYTYPE_PIXELTIMINGS:			return sizeof(D3DDEVINFO_D3D9PIPELINETIMINGS);
126 		case D3DQUERYTYPE_BANDWIDTHTIMINGS:		return sizeof(D3DDEVINFO_D3D9BANDWIDTHTIMINGS);
127 		case D3DQUERYTYPE_CACHEUTILIZATION:		return sizeof(D3DDEVINFO_D3D9CACHEUTILIZATION);
128 		default:
129 			ASSERT(false);
130 		}
131 
132 		return D3D_OK;
133 	}
134 
Issue(unsigned long flags)135 	long Direct3DQuery9::Issue(unsigned long flags)
136 	{
137 		CriticalSection cs(device);
138 
139 		TRACE("");
140 
141 		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END)
142 		{
143 			return INVALIDCALL();
144 		}
145 
146 		switch(type)
147 		{
148 		case D3DQUERYTYPE_VCACHE:				if(flags != D3DISSUE_END) return INVALIDCALL(); break;
149 		case D3DQUERYTYPE_RESOURCEMANAGER:		if(flags != D3DISSUE_END) return INVALIDCALL(); break;
150 		case D3DQUERYTYPE_VERTEXSTATS:			if(flags != D3DISSUE_END) return INVALIDCALL(); break;
151 		case D3DQUERYTYPE_EVENT:
152 			if(flags == D3DISSUE_END)
153 			{
154 			//	device->renderer->synchronize();   // FIXME
155 			}
156 			else return INVALIDCALL();
157 			break;
158 		case D3DQUERYTYPE_OCCLUSION:
159 			if(flags == D3DISSUE_BEGIN)
160 			{
161 				query->begin();
162 				device->addQuery(query);
163 				device->setOcclusionEnabled(true);
164 			}
165 			else   // flags == D3DISSUE_END
166 			{
167 				query->end();
168 				device->removeQuery(query);
169 				device->setOcclusionEnabled(false);
170 			}
171 			break;
172 		case D3DQUERYTYPE_TIMESTAMP:			if(flags != D3DISSUE_END) return INVALIDCALL(); break;
173 		case D3DQUERYTYPE_TIMESTAMPDISJOINT:	if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
174 		case D3DQUERYTYPE_TIMESTAMPFREQ:		if(flags != D3DISSUE_END) return INVALIDCALL(); break;
175 		case D3DQUERYTYPE_PIPELINETIMINGS:		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
176 		case D3DQUERYTYPE_INTERFACETIMINGS:		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
177 		case D3DQUERYTYPE_VERTEXTIMINGS:		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
178 		case D3DQUERYTYPE_PIXELTIMINGS:			if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
179 		case D3DQUERYTYPE_BANDWIDTHTIMINGS:		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
180 		case D3DQUERYTYPE_CACHEUTILIZATION:		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
181 		default:
182 			ASSERT(false);
183 		}
184 
185 		return D3D_OK;
186 	}
187 
GetData(void * data,unsigned long size,unsigned long flags)188 	long Direct3DQuery9::GetData(void *data, unsigned long size, unsigned long flags)
189 	{
190 		CriticalSection cs(device);
191 
192 		TRACE("void *data = %p, unsigned long size = %d, unsigned long flags = %d", data, size, flags);
193 
194 		if(query && query->building)
195 		{
196 			return INVALIDCALL();
197 		}
198 
199 		bool signaled = !query || query->reference == 0;
200 
201 		if(size && signaled)
202 		{
203 			if(!data)
204 			{
205 				return INVALIDCALL();
206 			}
207 
208 			// FIXME: Check size
209 
210 			switch(type)
211 			{
212 			case D3DQUERYTYPE_VCACHE:
213 				{
214 					D3DDEVINFO_VCACHE vcache;
215 
216 					vcache.Pattern = 'CACH';
217 					vcache.OptMethod = 1;   // Vertex-cache based optimization
218 					vcache.CacheSize = 16;
219 					vcache.MagicNumber = 8;
220 
221 					*(D3DDEVINFO_VCACHE*)data = vcache;
222 				}
223 				break;
224 			case D3DQUERYTYPE_RESOURCEMANAGER:		UNIMPLEMENTED(); break;
225 			case D3DQUERYTYPE_VERTEXSTATS:			UNIMPLEMENTED(); break;
226 			case D3DQUERYTYPE_EVENT:				*(BOOL*)data = TRUE; break;                       // FIXME
227 			case D3DQUERYTYPE_OCCLUSION:
228 				*(DWORD*)data = query->data;
229 				break;
230 			case D3DQUERYTYPE_TIMESTAMP:			*(UINT64*)data = sw::Timer::counter(); break;     // FIXME: Verify behaviour
231 			case D3DQUERYTYPE_TIMESTAMPDISJOINT:	*(BOOL*)data = FALSE; break;                      // FIXME: Verify behaviour
232 			case D3DQUERYTYPE_TIMESTAMPFREQ:		*(UINT64*)data = sw::Timer::frequency(); break;   // FIXME: Verify behaviour
233 			case D3DQUERYTYPE_PIPELINETIMINGS:		UNIMPLEMENTED(); break;
234 			case D3DQUERYTYPE_INTERFACETIMINGS:		UNIMPLEMENTED(); break;
235 			case D3DQUERYTYPE_VERTEXTIMINGS:		UNIMPLEMENTED(); break;
236 			case D3DQUERYTYPE_PIXELTIMINGS:			UNIMPLEMENTED(); break;
237 			case D3DQUERYTYPE_BANDWIDTHTIMINGS:		UNIMPLEMENTED(); break;
238 			case D3DQUERYTYPE_CACHEUTILIZATION:		UNIMPLEMENTED(); break;
239 			default:
240 				ASSERT(false);
241 			}
242 		}
243 
244 		return signaled ? S_OK : S_FALSE;
245 	}
246 }
247