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