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