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 "Direct3DCubeTexture9.hpp"
16 
17 #include "Direct3DDevice9.hpp"
18 #include "Direct3DSurface9.hpp"
19 #include "Resource.hpp"
20 #include "Debug.hpp"
21 
22 #include <assert.h>
23 
24 namespace D3D9
25 {
Direct3DCubeTexture9(Direct3DDevice9 * device,unsigned int edgeLength,unsigned int levels,unsigned long usage,D3DFORMAT format,D3DPOOL pool)26 	Direct3DCubeTexture9::Direct3DCubeTexture9(Direct3DDevice9 *device, unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool) : Direct3DBaseTexture9(device, D3DRTYPE_CUBETEXTURE, format, pool, levels, usage), edgeLength(edgeLength)
27 	{
28 		if(levels == 0)
29 		{
30 			this->levels = sw::log2(sw::max((int)edgeLength, 1)) + 1;
31 		}
32 
33 		for(unsigned int face = 0; face < 6; face++)
34 		{
35 			int width = edgeLength;
36 			int height = edgeLength;
37 
38 			for(unsigned int level = 0; level < sw::MIPMAP_LEVELS; level++)
39 			{
40 				if(level < this->levels)
41 				{
42 					surfaceLevel[face][level] = new Direct3DSurface9(device, this, width, height, format, pool, D3DMULTISAMPLE_NONE, 0, false, usage);
43 					surfaceLevel[face][level]->bind();
44 				}
45 				else
46 				{
47 					surfaceLevel[face][level] = 0;
48 				}
49 
50 				width = sw::max(1, width / 2);
51 				height = sw::max(1, height / 2);
52 			}
53 		}
54 	}
55 
~Direct3DCubeTexture9()56 	Direct3DCubeTexture9::~Direct3DCubeTexture9()
57 	{
58 		resource->lock(sw::DESTRUCT);
59 
60 		for(unsigned int face = 0; face < 6; face++)
61 		{
62 			for(int level = 0; level < sw::MIPMAP_LEVELS; level++)
63 			{
64 				if(surfaceLevel[face][level])
65 				{
66 					surfaceLevel[face][level]->unbind();
67 					surfaceLevel[face][level] = 0;
68 				}
69 			}
70 		}
71 
72 		resource->unlock();
73 	}
74 
QueryInterface(const IID & iid,void ** object)75 	long Direct3DCubeTexture9::QueryInterface(const IID &iid, void **object)
76 	{
77 		CriticalSection cs(device);
78 
79 		TRACE("");
80 
81 		if(iid == IID_IDirect3DCubeTexture9 ||
82 		   iid == IID_IDirect3DBaseTexture9 ||
83 		   iid == IID_IDirect3DResource9 ||
84 		   iid == IID_IUnknown)
85 		{
86 			AddRef();
87 			*object = this;
88 
89 			return S_OK;
90 		}
91 
92 		*object = 0;
93 
94 		return NOINTERFACE(iid);
95 	}
96 
AddRef()97 	unsigned long Direct3DCubeTexture9::AddRef()
98 	{
99 		TRACE("");
100 
101 		return Direct3DBaseTexture9::AddRef();
102 	}
103 
Release()104 	unsigned long Direct3DCubeTexture9::Release()
105 	{
106 		TRACE("");
107 
108 		return Direct3DBaseTexture9::Release();
109 	}
110 
FreePrivateData(const GUID & guid)111 	long Direct3DCubeTexture9::FreePrivateData(const GUID &guid)
112 	{
113 		CriticalSection cs(device);
114 
115 		TRACE("");
116 
117 		return Direct3DBaseTexture9::FreePrivateData(guid);
118 	}
119 
GetPrivateData(const GUID & guid,void * data,unsigned long * size)120 	long Direct3DCubeTexture9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
121 	{
122 		CriticalSection cs(device);
123 
124 		TRACE("");
125 
126 		return Direct3DBaseTexture9::GetPrivateData(guid, data, size);
127 	}
128 
PreLoad()129 	void Direct3DCubeTexture9::PreLoad()
130 	{
131 		CriticalSection cs(device);
132 
133 		TRACE("");
134 
135 		Direct3DBaseTexture9::PreLoad();
136 	}
137 
SetPrivateData(const GUID & guid,const void * data,unsigned long size,unsigned long flags)138 	long Direct3DCubeTexture9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
139 	{
140 		CriticalSection cs(device);
141 
142 		TRACE("");
143 
144 		return Direct3DBaseTexture9::SetPrivateData(guid, data, size, flags);
145 	}
146 
GetDevice(IDirect3DDevice9 ** device)147 	long Direct3DCubeTexture9::GetDevice(IDirect3DDevice9 **device)
148 	{
149 		CriticalSection cs(this->device);
150 
151 		TRACE("");
152 
153 		return Direct3DBaseTexture9::GetDevice(device);
154 	}
155 
SetPriority(unsigned long newPriority)156 	unsigned long Direct3DCubeTexture9::SetPriority(unsigned long newPriority)
157 	{
158 		CriticalSection cs(device);
159 
160 		TRACE("");
161 
162 		return Direct3DBaseTexture9::SetPriority(newPriority);
163 	}
164 
GetPriority()165 	unsigned long Direct3DCubeTexture9::GetPriority()
166 	{
167 		CriticalSection cs(device);
168 
169 		TRACE("");
170 
171 		return Direct3DBaseTexture9::GetPriority();
172 	}
173 
GetType()174 	D3DRESOURCETYPE Direct3DCubeTexture9::GetType()
175 	{
176 		CriticalSection cs(device);
177 
178 		TRACE("");
179 
180 		return Direct3DBaseTexture9::GetType();
181 	}
182 
GenerateMipSubLevels()183 	void Direct3DCubeTexture9::GenerateMipSubLevels()
184 	{
185 		CriticalSection cs(device);
186 
187 		TRACE("");
188 
189 		if(!(usage & D3DUSAGE_AUTOGENMIPMAP))
190 		{
191 			return;
192 		}
193 
194 		resource->lock(sw::PUBLIC);
195 
196 		for(unsigned int face = 0; face < 6; face++)
197 		{
198 			if(!surfaceLevel[face][0]->hasDirtyMipmaps())
199 			{
200 				continue;
201 			}
202 
203 			for(unsigned int i = 0; i < levels - 1; i++)
204 			{
205 				device->stretchRect(surfaceLevel[face][i], 0, surfaceLevel[face][i + 1], 0, GetAutoGenFilterType());
206 			}
207 
208 			surfaceLevel[face][0]->cleanMipmaps();
209 		}
210 
211 		resource->unlock();
212 	}
213 
GetAutoGenFilterType()214 	D3DTEXTUREFILTERTYPE Direct3DCubeTexture9::GetAutoGenFilterType()
215 	{
216 		CriticalSection cs(device);
217 
218 		TRACE("");
219 
220 		return Direct3DBaseTexture9::GetAutoGenFilterType();
221 	}
222 
GetLevelCount()223 	unsigned long Direct3DCubeTexture9::GetLevelCount()
224 	{
225 		CriticalSection cs(device);
226 
227 		TRACE("");
228 
229 		return Direct3DBaseTexture9::GetLevelCount();
230 	}
231 
GetLOD()232 	unsigned long Direct3DCubeTexture9::GetLOD()
233 	{
234 		CriticalSection cs(device);
235 
236 		TRACE("");
237 
238 		return Direct3DBaseTexture9::GetLOD();
239 	}
240 
SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType)241 	long Direct3DCubeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType)
242 	{
243 		CriticalSection cs(device);
244 
245 		TRACE("");
246 
247 		return Direct3DBaseTexture9::SetAutoGenFilterType(filterType);
248 	}
249 
SetLOD(unsigned long newLOD)250 	unsigned long Direct3DCubeTexture9::SetLOD(unsigned long newLOD)
251 	{
252 		CriticalSection cs(device);
253 
254 		TRACE("");
255 
256 		return Direct3DBaseTexture9::SetLOD(newLOD);
257 	}
258 
AddDirtyRect(D3DCUBEMAP_FACES face,const RECT * dirtyRect)259 	long Direct3DCubeTexture9::AddDirtyRect(D3DCUBEMAP_FACES face, const RECT *dirtyRect)
260 	{
261 		CriticalSection cs(device);
262 
263 		TRACE("");
264 
265 	//	UNIMPLEMENTED();
266 
267 		return D3D_OK;
268 	}
269 
GetCubeMapSurface(D3DCUBEMAP_FACES face,unsigned int level,IDirect3DSurface9 ** cubeMapSurface)270 	long Direct3DCubeTexture9::GetCubeMapSurface(D3DCUBEMAP_FACES face, unsigned int level, IDirect3DSurface9 **cubeMapSurface)
271 	{
272 		CriticalSection cs(device);
273 
274 		TRACE("");
275 
276 		*cubeMapSurface = 0;
277 
278 		if(face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level])
279 		{
280 			return INVALIDCALL();
281 		}
282 
283 		surfaceLevel[face][level]->AddRef();
284 		*cubeMapSurface = surfaceLevel[face][level];
285 
286 		return D3D_OK;
287 	}
288 
GetLevelDesc(unsigned int level,D3DSURFACE_DESC * description)289 	long Direct3DCubeTexture9::GetLevelDesc(unsigned int level, D3DSURFACE_DESC *description)
290 	{
291 		CriticalSection cs(device);
292 
293 		TRACE("");
294 
295 		if(!description || level >= GetLevelCount() || !surfaceLevel[0][level])
296 		{
297 			return INVALIDCALL();
298 		}
299 
300 		return surfaceLevel[0][level]->GetDesc(description);
301 	}
302 
LockRect(D3DCUBEMAP_FACES face,unsigned int level,D3DLOCKED_RECT * lockedRect,const RECT * rect,unsigned long flags)303 	long Direct3DCubeTexture9::LockRect(D3DCUBEMAP_FACES face, unsigned int level, D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags)
304 	{
305 		CriticalSection cs(device);
306 
307 		TRACE("");
308 
309 		if(!lockedRect || face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level])
310 		{
311 			return INVALIDCALL();
312 		}
313 
314 		return surfaceLevel[face][level]->LockRect(lockedRect, rect, flags);
315 	}
316 
UnlockRect(D3DCUBEMAP_FACES face,unsigned int level)317 	long Direct3DCubeTexture9::UnlockRect(D3DCUBEMAP_FACES face, unsigned int level)
318 	{
319 		CriticalSection cs(device);
320 
321 		TRACE("");
322 
323 		if(face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level])
324 		{
325 			return INVALIDCALL();
326 		}
327 
328 		return surfaceLevel[face][level]->UnlockRect();
329 	}
330 
getInternalCubeMapSurface(D3DCUBEMAP_FACES face,unsigned int level)331 	Direct3DSurface9 *Direct3DCubeTexture9::getInternalCubeMapSurface(D3DCUBEMAP_FACES face, unsigned int level)
332 	{
333 		return surfaceLevel[face][level];
334 	}
335 }