blob: 7d3478611a05030c95471156d61e3cb3c572981a [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
Nicolas Capensee16f0d2015-07-16 17:40:10 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// 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
Nicolas Capensee16f0d2015-07-16 17:40:10 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
Nicolas Capensee16f0d2015-07-16 17:40:10 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// 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.
Nicolas Capensee16f0d2015-07-16 17:40:10 -040014
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
24namespace D3D9
25{
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
Nicolas Capensb663f712016-04-18 12:02:39 -040038 for(unsigned int level = 0; level < sw::MIPMAP_LEVELS; level++)
Nicolas Capensee16f0d2015-07-16 17:40:10 -040039 {
40 if(level < this->levels)
Nicolas Capensb663f712016-04-18 12:02:39 -040041 {
Nicolas Capensee16f0d2015-07-16 17:40:10 -040042 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
56 Direct3DCubeTexture9::~Direct3DCubeTexture9()
57 {
Nicolas Capensee16f0d2015-07-16 17:40:10 -040058 for(unsigned int face = 0; face < 6; face++)
59 {
Nicolas Capensb663f712016-04-18 12:02:39 -040060 for(int level = 0; level < sw::MIPMAP_LEVELS; level++)
Nicolas Capensee16f0d2015-07-16 17:40:10 -040061 {
62 if(surfaceLevel[face][level])
63 {
64 surfaceLevel[face][level]->unbind();
65 surfaceLevel[face][level] = 0;
66 }
67 }
68 }
Nicolas Capensee16f0d2015-07-16 17:40:10 -040069 }
70
71 long Direct3DCubeTexture9::QueryInterface(const IID &iid, void **object)
72 {
73 CriticalSection cs(device);
74
75 TRACE("");
76
77 if(iid == IID_IDirect3DCubeTexture9 ||
78 iid == IID_IDirect3DBaseTexture9 ||
79 iid == IID_IDirect3DResource9 ||
80 iid == IID_IUnknown)
81 {
82 AddRef();
83 *object = this;
84
85 return S_OK;
86 }
87
88 *object = 0;
89
90 return NOINTERFACE(iid);
91 }
92
93 unsigned long Direct3DCubeTexture9::AddRef()
94 {
95 TRACE("");
96
97 return Direct3DBaseTexture9::AddRef();
98 }
99
100 unsigned long Direct3DCubeTexture9::Release()
101 {
102 TRACE("");
103
104 return Direct3DBaseTexture9::Release();
105 }
106
107 long Direct3DCubeTexture9::FreePrivateData(const GUID &guid)
108 {
109 CriticalSection cs(device);
110
111 TRACE("");
112
113 return Direct3DBaseTexture9::FreePrivateData(guid);
114 }
115
116 long Direct3DCubeTexture9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
117 {
118 CriticalSection cs(device);
119
120 TRACE("");
121
122 return Direct3DBaseTexture9::GetPrivateData(guid, data, size);
123 }
124
125 void Direct3DCubeTexture9::PreLoad()
126 {
127 CriticalSection cs(device);
128
129 TRACE("");
130
131 Direct3DBaseTexture9::PreLoad();
132 }
133
134 long Direct3DCubeTexture9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
135 {
136 CriticalSection cs(device);
137
138 TRACE("");
139
140 return Direct3DBaseTexture9::SetPrivateData(guid, data, size, flags);
141 }
142
143 long Direct3DCubeTexture9::GetDevice(IDirect3DDevice9 **device)
144 {
145 CriticalSection cs(this->device);
146
147 TRACE("");
148
149 return Direct3DBaseTexture9::GetDevice(device);
150 }
151
152 unsigned long Direct3DCubeTexture9::SetPriority(unsigned long newPriority)
153 {
154 CriticalSection cs(device);
155
156 TRACE("");
157
158 return Direct3DBaseTexture9::SetPriority(newPriority);
159 }
160
161 unsigned long Direct3DCubeTexture9::GetPriority()
162 {
163 CriticalSection cs(device);
164
165 TRACE("");
166
167 return Direct3DBaseTexture9::GetPriority();
168 }
169
170 D3DRESOURCETYPE Direct3DCubeTexture9::GetType()
171 {
172 CriticalSection cs(device);
173
174 TRACE("");
175
176 return Direct3DBaseTexture9::GetType();
177 }
178
179 void Direct3DCubeTexture9::GenerateMipSubLevels()
180 {
181 CriticalSection cs(device);
182
183 TRACE("");
184
185 if(!(usage & D3DUSAGE_AUTOGENMIPMAP))
186 {
187 return;
188 }
189
190 resource->lock(sw::PUBLIC);
191
192 for(unsigned int face = 0; face < 6; face++)
193 {
Nicolas Capens73e18c12017-11-28 13:31:35 -0500194 if(!surfaceLevel[face][0]->hasDirtyContents())
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400195 {
196 continue;
197 }
198
199 for(unsigned int i = 0; i < levels - 1; i++)
200 {
201 device->stretchRect(surfaceLevel[face][i], 0, surfaceLevel[face][i + 1], 0, GetAutoGenFilterType());
202 }
203
Nicolas Capens73e18c12017-11-28 13:31:35 -0500204 surfaceLevel[face][0]->markContentsClean();
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400205 }
206
207 resource->unlock();
208 }
209
210 D3DTEXTUREFILTERTYPE Direct3DCubeTexture9::GetAutoGenFilterType()
211 {
212 CriticalSection cs(device);
213
214 TRACE("");
215
216 return Direct3DBaseTexture9::GetAutoGenFilterType();
217 }
218
219 unsigned long Direct3DCubeTexture9::GetLevelCount()
220 {
221 CriticalSection cs(device);
222
223 TRACE("");
224
225 return Direct3DBaseTexture9::GetLevelCount();
226 }
227
228 unsigned long Direct3DCubeTexture9::GetLOD()
229 {
230 CriticalSection cs(device);
231
232 TRACE("");
233
234 return Direct3DBaseTexture9::GetLOD();
235 }
236
237 long Direct3DCubeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType)
238 {
239 CriticalSection cs(device);
240
241 TRACE("");
242
243 return Direct3DBaseTexture9::SetAutoGenFilterType(filterType);
244 }
245
246 unsigned long Direct3DCubeTexture9::SetLOD(unsigned long newLOD)
247 {
248 CriticalSection cs(device);
249
250 TRACE("");
251
252 return Direct3DBaseTexture9::SetLOD(newLOD);
253 }
254
255 long Direct3DCubeTexture9::AddDirtyRect(D3DCUBEMAP_FACES face, const RECT *dirtyRect)
256 {
257 CriticalSection cs(device);
258
259 TRACE("");
260
261 // UNIMPLEMENTED();
262
263 return D3D_OK;
264 }
265
266 long Direct3DCubeTexture9::GetCubeMapSurface(D3DCUBEMAP_FACES face, unsigned int level, IDirect3DSurface9 **cubeMapSurface)
267 {
268 CriticalSection cs(device);
269
270 TRACE("");
271
272 *cubeMapSurface = 0;
273
274 if(face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level])
275 {
276 return INVALIDCALL();
277 }
278
279 surfaceLevel[face][level]->AddRef();
280 *cubeMapSurface = surfaceLevel[face][level];
281
282 return D3D_OK;
283 }
284
285 long Direct3DCubeTexture9::GetLevelDesc(unsigned int level, D3DSURFACE_DESC *description)
286 {
287 CriticalSection cs(device);
288
289 TRACE("");
290
291 if(!description || level >= GetLevelCount() || !surfaceLevel[0][level])
292 {
293 return INVALIDCALL();
294 }
295
296 return surfaceLevel[0][level]->GetDesc(description);
297 }
298
299 long Direct3DCubeTexture9::LockRect(D3DCUBEMAP_FACES face, unsigned int level, D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags)
300 {
301 CriticalSection cs(device);
302
303 TRACE("");
304
305 if(!lockedRect || face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level])
306 {
307 return INVALIDCALL();
308 }
309
310 return surfaceLevel[face][level]->LockRect(lockedRect, rect, flags);
311 }
312
313 long Direct3DCubeTexture9::UnlockRect(D3DCUBEMAP_FACES face, unsigned int level)
314 {
315 CriticalSection cs(device);
316
317 TRACE("");
318
319 if(face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level])
320 {
321 return INVALIDCALL();
322 }
323
324 return surfaceLevel[face][level]->UnlockRect();
325 }
326
327 Direct3DSurface9 *Direct3DCubeTexture9::getInternalCubeMapSurface(D3DCUBEMAP_FACES face, unsigned int level)
328 {
329 return surfaceLevel[face][level];
330 }
331}