blob: 703d9e09568ae6ae6bbe5d01999a927f050daf77 [file] [log] [blame]
Nicolas Capensee16f0d2015-07-16 17:40:10 -04001// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2011 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12#include "Direct3DQuery9.hpp"
13
14#include "Direct3DDevice9.hpp"
15#include "Timer.hpp"
16#include "Renderer.hpp"
17#include "Debug.hpp"
18
19#include <assert.h>
20
21namespace D3D9
22{
23 Direct3DQuery9::Direct3DQuery9(Direct3DDevice9 *device, D3DQUERYTYPE type) : device(device), type(type)
24 {
25 if(type == D3DQUERYTYPE_OCCLUSION)
26 {
Alexis Hetu16116cb2016-03-02 15:59:51 -050027 query = new sw::Query(sw::Query::FRAGMENTS_PASSED);
Nicolas Capensee16f0d2015-07-16 17:40:10 -040028 }
29 else
30 {
31 query = 0;
32 }
33 }
34
35 Direct3DQuery9::~Direct3DQuery9()
36 {
37 if(query)
38 {
39 device->removeQuery(query);
40
41 delete query;
42 }
43 }
44
45 long Direct3DQuery9::QueryInterface(const IID &iid, void **object)
46 {
47 CriticalSection cs(device);
48
49 TRACE("");
50
51 if(iid == IID_IDirect3DQuery9 ||
52 iid == IID_IUnknown)
53 {
54 AddRef();
55 *object = this;
56
57 return S_OK;
58 }
59
60 *object = 0;
61
62 return NOINTERFACE(iid);
63 }
64
65 unsigned long Direct3DQuery9::AddRef()
66 {
67 TRACE("");
68
69 return Unknown::AddRef();
70 }
71
72 unsigned long Direct3DQuery9::Release()
73 {
74 TRACE("");
75
76 return Unknown::Release();
77 }
78
79 long __stdcall Direct3DQuery9::GetDevice(IDirect3DDevice9 **device)
80 {
81 CriticalSection cs(this->device);
82
83 TRACE("");
84
85 if(!device)
86 {
87 return INVALIDCALL();
88 }
89
90 this->device->AddRef();
91 *device = this->device;
92
93 return D3D_OK;
94 }
95
96 D3DQUERYTYPE Direct3DQuery9::GetType()
97 {
98 CriticalSection cs(device);
99
100 return type;
101 }
102
103 unsigned long Direct3DQuery9::GetDataSize()
104 {
105 CriticalSection cs(device);
106
107 TRACE("");
108
109 switch(type)
110 {
111 case D3DQUERYTYPE_VCACHE: return sizeof(D3DDEVINFO_VCACHE);
112 case D3DQUERYTYPE_RESOURCEMANAGER: return sizeof(D3DDEVINFO_RESOURCEMANAGER);
113 case D3DQUERYTYPE_VERTEXSTATS: return sizeof(D3DDEVINFO_D3DVERTEXSTATS);
114 case D3DQUERYTYPE_EVENT: return sizeof(BOOL);
115 case D3DQUERYTYPE_OCCLUSION: return sizeof(DWORD);
116 case D3DQUERYTYPE_TIMESTAMP: return sizeof(UINT64);
117 case D3DQUERYTYPE_TIMESTAMPDISJOINT: return sizeof(BOOL);
118 case D3DQUERYTYPE_TIMESTAMPFREQ: return sizeof(UINT64);
119 case D3DQUERYTYPE_PIPELINETIMINGS: return sizeof(D3DDEVINFO_D3D9PIPELINETIMINGS);
120 case D3DQUERYTYPE_INTERFACETIMINGS: return sizeof(D3DDEVINFO_D3D9INTERFACETIMINGS);
121 case D3DQUERYTYPE_VERTEXTIMINGS: return sizeof(D3DDEVINFO_D3D9STAGETIMINGS);
122 case D3DQUERYTYPE_PIXELTIMINGS: return sizeof(D3DDEVINFO_D3D9PIPELINETIMINGS);
123 case D3DQUERYTYPE_BANDWIDTHTIMINGS: return sizeof(D3DDEVINFO_D3D9BANDWIDTHTIMINGS);
124 case D3DQUERYTYPE_CACHEUTILIZATION: return sizeof(D3DDEVINFO_D3D9CACHEUTILIZATION);
125 default:
126 ASSERT(false);
127 }
128
129 return D3D_OK;
130 }
131
132 long Direct3DQuery9::Issue(unsigned long flags)
133 {
134 CriticalSection cs(device);
135
136 TRACE("");
137
138 if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END)
139 {
140 return INVALIDCALL();
141 }
142
143 switch(type)
144 {
145 case D3DQUERYTYPE_VCACHE: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
146 case D3DQUERYTYPE_RESOURCEMANAGER: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
147 case D3DQUERYTYPE_VERTEXSTATS: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
148 case D3DQUERYTYPE_EVENT:
149 if(flags == D3DISSUE_END)
150 {
151 // device->renderer->synchronize(); // FIXME
152 }
153 else return INVALIDCALL();
154 break;
155 case D3DQUERYTYPE_OCCLUSION:
156 if(flags == D3DISSUE_BEGIN)
157 {
158 query->begin();
159 device->addQuery(query);
160 device->setOcclusionEnabled(true);
161 }
162 else // flags == D3DISSUE_END
163 {
164 query->end();
165 device->removeQuery(query);
166 device->setOcclusionEnabled(false);
167 }
168 break;
169 case D3DQUERYTYPE_TIMESTAMP: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
170 case D3DQUERYTYPE_TIMESTAMPDISJOINT: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
171 case D3DQUERYTYPE_TIMESTAMPFREQ: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
172 case D3DQUERYTYPE_PIPELINETIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
173 case D3DQUERYTYPE_INTERFACETIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
174 case D3DQUERYTYPE_VERTEXTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
175 case D3DQUERYTYPE_PIXELTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
176 case D3DQUERYTYPE_BANDWIDTHTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
177 case D3DQUERYTYPE_CACHEUTILIZATION: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
178 default:
179 ASSERT(false);
180 }
181
182 return D3D_OK;
183 }
184
185 long Direct3DQuery9::GetData(void *data, unsigned long size, unsigned long flags)
186 {
187 CriticalSection cs(device);
188
189 TRACE("void *data = %p, unsigned long size = %d, unsigned long flags = %d", data, size, flags);
190
191 if(query && query->building)
192 {
193 return INVALIDCALL();
194 }
195
196 bool signaled = !query || query->reference == 0;
197
198 if(size && signaled)
199 {
200 if(!data)
201 {
202 return INVALIDCALL();
203 }
204
205 // FIXME: Check size
206
207 switch(type)
208 {
209 case D3DQUERYTYPE_VCACHE:
210 {
211 D3DDEVINFO_VCACHE vcache;
212
213 vcache.Pattern = 'CACH';
214 vcache.OptMethod = 1; // Vertex-cache based optimization
215 vcache.CacheSize = 16;
216 vcache.MagicNumber = 8;
217
218 *(D3DDEVINFO_VCACHE*)data = vcache;
219 }
220 break;
221 case D3DQUERYTYPE_RESOURCEMANAGER: UNIMPLEMENTED(); break;
222 case D3DQUERYTYPE_VERTEXSTATS: UNIMPLEMENTED(); break;
223 case D3DQUERYTYPE_EVENT: *(BOOL*)data = TRUE; break; // FIXME
224 case D3DQUERYTYPE_OCCLUSION:
225 *(DWORD*)data = query->data;
226 break;
227 case D3DQUERYTYPE_TIMESTAMP: *(UINT64*)data = sw::Timer::counter(); break; // FIXME: Verify behaviour
228 case D3DQUERYTYPE_TIMESTAMPDISJOINT: *(BOOL*)data = FALSE; break; // FIXME: Verify behaviour
229 case D3DQUERYTYPE_TIMESTAMPFREQ: *(UINT64*)data = sw::Timer::frequency(); break; // FIXME: Verify behaviour
230 case D3DQUERYTYPE_PIPELINETIMINGS: UNIMPLEMENTED(); break;
231 case D3DQUERYTYPE_INTERFACETIMINGS: UNIMPLEMENTED(); break;
232 case D3DQUERYTYPE_VERTEXTIMINGS: UNIMPLEMENTED(); break;
233 case D3DQUERYTYPE_PIXELTIMINGS: UNIMPLEMENTED(); break;
234 case D3DQUERYTYPE_BANDWIDTHTIMINGS: UNIMPLEMENTED(); break;
235 case D3DQUERYTYPE_CACHEUTILIZATION: UNIMPLEMENTED(); break;
236 default:
237 ASSERT(false);
238 }
239 }
240
241 return signaled ? S_OK : S_FALSE;
242 }
243}