blob: 8dfa3a82ba67259e50ddbe708b1c137fce586586 [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 "Direct3DSurface9.hpp"
16
17#include "Direct3DDevice9.hpp"
18#include "Direct3DBaseTexture9.hpp"
19#include "Capabilities.hpp"
20#include "Resource.hpp"
21#include "Debug.hpp"
22
23#include <malloc.h>
24#include <assert.h>
25
26extern bool quadLayoutEnabled;
27
28namespace D3D9
29{
30 sw::Resource *getParentResource(Unknown *container)
31 {
32 Direct3DBaseTexture9 *baseTexture = dynamic_cast<Direct3DBaseTexture9*>(container);
33
34 if(baseTexture)
35 {
36 return baseTexture->getResource();
37 }
38
39 return 0;
40 }
41
42 int sampleCount(D3DMULTISAMPLE_TYPE multiSample, unsigned int quality)
43 {
44 if(multiSample == D3DMULTISAMPLE_NONMASKABLE)
45 {
46 switch(quality)
47 {
48 case 0: return 2;
49 case 1: return 4;
50 case 2: return 8;
51 case 3: return 16;
52 }
53 }
54 else if(multiSample == D3DMULTISAMPLE_2_SAMPLES)
55 {
56 return 2;
57 }
58 else if(multiSample == D3DMULTISAMPLE_4_SAMPLES)
59 {
60 return 4;
61 }
62 else if(multiSample == D3DMULTISAMPLE_8_SAMPLES)
63 {
64 return 8;
65 }
66 else if(multiSample == D3DMULTISAMPLE_16_SAMPLES)
67 {
68 return 16;
69 }
70
71 return 1;
72 }
73
74 bool isLockable(D3DPOOL pool, unsigned long usage, bool lockableOverride)
75 {
76 return (pool != D3DPOOL_DEFAULT) || (usage & D3DUSAGE_DYNAMIC) || lockableOverride;
77 }
78
Alexis Hetu9c6d5222016-11-29 17:02:14 -050079 Direct3DSurface9::Direct3DSurface9(Direct3DDevice9 *device, Unknown *container, int width, int height, D3DFORMAT format, D3DPOOL pool, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, bool lockableOverride, unsigned long usage)
Nicolas Capensbfa23b32017-12-11 10:06:37 -050080 : Direct3DResource9(device, D3DRTYPE_SURFACE, pool, memoryUsage(width, height, multiSample, quality, format)), Surface(getParentResource(container), width, height, 1, 0, sampleCount(multiSample, quality), translateFormat(format), isLockable(pool, usage, lockableOverride), (usage & D3DUSAGE_RENDERTARGET) || (usage & D3DUSAGE_DEPTHSTENCIL)), container(container), width(width), height(height), format(format), pool(pool), multiSample(multiSample), quality(quality), lockable(isLockable(pool, usage, lockableOverride)), usage(usage)
Nicolas Capensee16f0d2015-07-16 17:40:10 -040081 {
82 parentTexture = dynamic_cast<Direct3DBaseTexture9*>(container);
83 }
84
85 Direct3DSurface9::~Direct3DSurface9()
86 {
87 }
88
Nicolas Capens3b9e1ea2017-06-12 12:43:48 -040089 void *Direct3DSurface9::lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
90 {
91 return Surface::lockInternal(x, y, z, lock, client);
92 }
93
94 void Direct3DSurface9::unlockInternal()
95 {
96 Surface::unlockInternal();
97 }
98
Nicolas Capensee16f0d2015-07-16 17:40:10 -040099 long Direct3DSurface9::QueryInterface(const IID &iid, void **object)
100 {
101 CriticalSection cs(device);
102
103 TRACE("");
104
105 if(iid == IID_IDirect3DSurface9 ||
106 iid == IID_IDirect3DResource9 ||
107 iid == IID_IUnknown)
108 {
109 AddRef();
110 *object = this;
111
112 return S_OK;
113 }
114
115 *object = 0;
116
117 return NOINTERFACE(iid);
118 }
119
120 unsigned long Direct3DSurface9::AddRef()
121 {
122 TRACE("");
123
124 if(parentTexture)
125 {
126 return parentTexture->AddRef();
127 }
128
129 return Direct3DResource9::AddRef();
130 }
131
132 unsigned long Direct3DSurface9::Release()
133 {
134 TRACE("");
135
136 if(parentTexture)
137 {
138 return parentTexture->Release();
139 }
140
141 return Direct3DResource9::Release();
142 }
143
144 long Direct3DSurface9::FreePrivateData(const GUID &guid)
145 {
146 CriticalSection cs(device);
147
148 TRACE("");
149
150 return Direct3DResource9::FreePrivateData(guid);
151 }
152
153 long Direct3DSurface9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
154 {
155 CriticalSection cs(device);
156
157 TRACE("");
158
159 return Direct3DResource9::GetPrivateData(guid, data, size);
160 }
161
162 void Direct3DSurface9::PreLoad()
163 {
164 CriticalSection cs(device);
165
166 TRACE("");
167
168 Direct3DResource9::PreLoad();
169 }
170
171 long Direct3DSurface9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
172 {
173 CriticalSection cs(device);
174
175 TRACE("");
176
177 return Direct3DResource9::SetPrivateData(guid, data, size, flags);
178 }
179
180 long Direct3DSurface9::GetDevice(IDirect3DDevice9 **device)
181 {
182 CriticalSection cs(this->device);
183
184 TRACE("");
185
186 return Direct3DResource9::GetDevice(device);
187 }
188
189 unsigned long Direct3DSurface9::SetPriority(unsigned long newPriority)
190 {
191 CriticalSection cs(device);
192
193 TRACE("");
194
195 return Direct3DResource9::SetPriority(newPriority);
196 }
197
198 unsigned long Direct3DSurface9::GetPriority()
199 {
200 CriticalSection cs(device);
201
202 TRACE("");
203
204 return Direct3DResource9::GetPriority();
205 }
206
207 D3DRESOURCETYPE Direct3DSurface9::GetType()
208 {
209 CriticalSection cs(device);
210
211 TRACE("");
212
213 return Direct3DResource9::GetType();
214 }
215
216 long Direct3DSurface9::GetDC(HDC *deviceContext)
217 {
218 CriticalSection cs(device);
219
220 TRACE("");
221
222 if(!deviceContext)
223 {
224 return INVALIDCALL();
225 }
226
227 UNIMPLEMENTED();
228
229 return D3D_OK;
230 }
231
232 long Direct3DSurface9::ReleaseDC(HDC deviceContext)
233 {
234 CriticalSection cs(device);
235
236 TRACE("");
237
238 UNIMPLEMENTED();
239
240 return D3D_OK;
241 }
242
243 long Direct3DSurface9::LockRect(D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags)
244 {
245 CriticalSection cs(device);
246
247 TRACE("D3DLOCKED_RECT *lockedRect = 0x%0.8p, const RECT *rect = 0x%0.8p, unsigned long flags = %d", lockedRect, rect, flags);
248
249 if(!lockedRect)
250 {
251 return INVALIDCALL();
252 }
253
254 lockedRect->Pitch = 0;
255 lockedRect->pBits = 0;
256
257 if(!lockable)
258 {
259 return INVALIDCALL();
260 }
261
262 lockedRect->Pitch = getExternalPitchB();
263
264 sw::Lock lock = sw::LOCK_READWRITE;
265
266 if(flags & D3DLOCK_DISCARD)
267 {
268 lock = sw::LOCK_DISCARD;
269 }
270
271 if(flags & D3DLOCK_READONLY)
272 {
273 lock = sw::LOCK_READONLY;
274 }
275
276 if(rect)
277 {
278 lockedRect->pBits = lockExternal(rect->left, rect->top, 0, lock, sw::PUBLIC);
279 }
280 else
281 {
282 lockedRect->pBits = lockExternal(0, 0, 0, lock, sw::PUBLIC);
283 }
284
285 return D3D_OK;
286 }
287
288 long Direct3DSurface9::UnlockRect()
289 {
290 CriticalSection cs(device);
291
292 TRACE("");
293
294 unlockExternal();
295
296 return D3D_OK;
297 }
298
299 long Direct3DSurface9::GetContainer(const IID &iid, void **container)
300 {
301 CriticalSection cs(device);
302
303 TRACE("");
304
305 if(!container)
306 {
307 return INVALIDCALL();
308 }
309
310 long result = this->container->QueryInterface(iid, container);
311
312 if(result == S_OK)
313 {
314 return D3D_OK;
315 }
316
317 return INVALIDCALL();
318 }
319
320 long Direct3DSurface9::GetDesc(D3DSURFACE_DESC *description)
321 {
322 CriticalSection cs(device);
323
324 TRACE("");
325
326 if(!description)
327 {
328 return INVALIDCALL();
329 }
330
331 description->Format = format;
332 description->Pool = pool;
333 description->Type = D3DRTYPE_SURFACE;
334 description->Height = height;
335 description->Width = width;
336 description->MultiSampleType = multiSample;
337 description->MultiSampleQuality = quality;
338 description->Usage = usage;
339
340 return D3D_OK;
341 }
342
343 sw::Format Direct3DSurface9::translateFormat(D3DFORMAT format)
344 {
345 switch(format)
346 {
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400347 case D3DFMT_NULL: return sw::FORMAT_NULL;
348 case D3DFMT_DXT1: return sw::FORMAT_DXT1;
349 case D3DFMT_DXT2: return sw::FORMAT_DXT3;
350 case D3DFMT_DXT3: return sw::FORMAT_DXT3;
351 case D3DFMT_DXT4: return sw::FORMAT_DXT5;
352 case D3DFMT_DXT5: return sw::FORMAT_DXT5;
353 case D3DFMT_ATI1: return sw::FORMAT_ATI1;
354 case D3DFMT_ATI2: return sw::FORMAT_ATI2;
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400355 case D3DFMT_R3G3B2: return sw::FORMAT_R3G3B2;
356 case D3DFMT_A8R3G3B2: return sw::FORMAT_A8R3G3B2;
357 case D3DFMT_X4R4G4B4: return sw::FORMAT_X4R4G4B4;
358 case D3DFMT_A4R4G4B4: return sw::FORMAT_A4R4G4B4;
359 case D3DFMT_A8R8G8B8: return sw::FORMAT_A8R8G8B8;
360 case D3DFMT_A8B8G8R8: return sw::FORMAT_A8B8G8R8;
361 case D3DFMT_G16R16: return sw::FORMAT_G16R16;
362 case D3DFMT_A2R10G10B10: return sw::FORMAT_A2R10G10B10;
363 case D3DFMT_A2B10G10R10: return sw::FORMAT_A2B10G10R10;
364 case D3DFMT_A16B16G16R16: return sw::FORMAT_A16B16G16R16;
365 case D3DFMT_P8: return sw::FORMAT_P8;
366 case D3DFMT_A8P8: return sw::FORMAT_A8P8;
367 case D3DFMT_A8: return sw::FORMAT_A8;
368 case D3DFMT_R5G6B5: return sw::FORMAT_R5G6B5;
369 case D3DFMT_X1R5G5B5: return sw::FORMAT_X1R5G5B5;
370 case D3DFMT_A1R5G5B5: return sw::FORMAT_A1R5G5B5;
371 case D3DFMT_R8G8B8: return sw::FORMAT_R8G8B8;
372 case D3DFMT_X8R8G8B8: return sw::FORMAT_X8R8G8B8;
373 case D3DFMT_X8B8G8R8: return sw::FORMAT_X8B8G8R8;
374 case D3DFMT_V8U8: return sw::FORMAT_V8U8;
375 case D3DFMT_L6V5U5: return sw::FORMAT_L6V5U5;
376 case D3DFMT_Q8W8V8U8: return sw::FORMAT_Q8W8V8U8;
377 case D3DFMT_X8L8V8U8: return sw::FORMAT_X8L8V8U8;
378 case D3DFMT_A2W10V10U10: return sw::FORMAT_A2W10V10U10;
379 case D3DFMT_V16U16: return sw::FORMAT_V16U16;
380 case D3DFMT_Q16W16V16U16: return sw::FORMAT_Q16W16V16U16;
381 case D3DFMT_L8: return sw::FORMAT_L8;
382 case D3DFMT_A4L4: return sw::FORMAT_A4L4;
383 case D3DFMT_L16: return sw::FORMAT_L16;
384 case D3DFMT_A8L8: return sw::FORMAT_A8L8;
385 case D3DFMT_R16F: return sw::FORMAT_R16F;
386 case D3DFMT_G16R16F: return sw::FORMAT_G16R16F;
387 case D3DFMT_A16B16G16R16F: return sw::FORMAT_A16B16G16R16F;
388 case D3DFMT_R32F: return sw::FORMAT_R32F;
389 case D3DFMT_G32R32F: return sw::FORMAT_G32R32F;
390 case D3DFMT_A32B32G32R32F: return sw::FORMAT_A32B32G32R32F;
391 case D3DFMT_D16: return sw::FORMAT_D16;
392 case D3DFMT_D32: return sw::FORMAT_D32;
393 case D3DFMT_D24X8: return sw::FORMAT_D24X8;
394 case D3DFMT_D24S8: return sw::FORMAT_D24S8;
395 case D3DFMT_D24FS8: return sw::FORMAT_D24FS8;
396 case D3DFMT_D32F_LOCKABLE: return sw::FORMAT_D32F_LOCKABLE;
Nicolas Capens66839432015-07-17 11:45:49 -0400397 case D3DFMT_DF24: return sw::FORMAT_DF24S8;
398 case D3DFMT_DF16: return sw::FORMAT_DF16S8;
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400399 case D3DFMT_INTZ: return sw::FORMAT_INTZ;
400 default:
401 ASSERT(false);
402 }
403
404 return sw::FORMAT_NULL;
405 }
406
407 int Direct3DSurface9::bytes(D3DFORMAT format)
408 {
409 return Surface::bytes(translateFormat(format));
410 }
411
Nicolas Capensbfa23b32017-12-11 10:06:37 -0500412 unsigned int Direct3DSurface9::memoryUsage(int width, int height, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, D3DFORMAT format)
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400413 {
Nicolas Capensbfa23b32017-12-11 10:06:37 -0500414 return Surface::size(width, height, 1, 0, sampleCount(multiSample, quality), translateFormat(format));
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400415 }
416}