Home | History | Annotate | Download | only in D3D9
      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 {
     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 
     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)
     80 		: 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)
     81 	{
     82 		parentTexture = dynamic_cast<Direct3DBaseTexture9*>(container);
     83 	}
     84 
     85 	Direct3DSurface9::~Direct3DSurface9()
     86 	{
     87 	}
     88 
     89 	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 
     99 	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 		{
    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 		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;
    397 		case D3DFMT_DF24:			return sw::FORMAT_DF24S8;
    398 		case D3DFMT_DF16:			return sw::FORMAT_DF16S8;
    399 		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 
    412 	unsigned int Direct3DSurface9::memoryUsage(int width, int height, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, D3DFORMAT format)
    413 	{
    414 		return Surface::size(width, height, 1, 0, sampleCount(multiSample, quality), translateFormat(format));
    415 	}
    416 }
    417