Home | History | Annotate | Download | only in D3D8
      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 "Direct3DSurface8.hpp"
     16 
     17 #include "Direct3DBaseTexture8.hpp"
     18 #include "Debug.hpp"
     19 
     20 #include <malloc.h>
     21 #include <assert.h>
     22 
     23 extern bool quadLayoutEnabled;
     24 
     25 namespace D3D8
     26 {
     27 	static sw::Resource *getParentResource(Unknown *container)
     28 	{
     29 		Direct3DBaseTexture8 *baseTexture = dynamic_cast<Direct3DBaseTexture8*>(container);
     30 
     31 		if(baseTexture)
     32 		{
     33 			return baseTexture->getResource();
     34 		}
     35 
     36 		return 0;
     37 	}
     38 
     39 	int sampleCount(D3DMULTISAMPLE_TYPE multiSample)
     40 	{
     41 		if(multiSample == D3DMULTISAMPLE_2_SAMPLES)
     42 		{
     43 			return 2;
     44 		}
     45 		else if(multiSample == D3DMULTISAMPLE_4_SAMPLES)
     46 		{
     47 			return 4;
     48 		}
     49 		else if(multiSample == D3DMULTISAMPLE_8_SAMPLES)
     50 		{
     51 			return 8;
     52 		}
     53 		else if(multiSample == D3DMULTISAMPLE_16_SAMPLES)
     54 		{
     55 			return 16;
     56 		}
     57 
     58 		return 1;
     59 	}
     60 
     61 	Direct3DSurface8::Direct3DSurface8(Direct3DDevice8 *device, Unknown *container, int width, int height, D3DFORMAT format, D3DPOOL pool, D3DMULTISAMPLE_TYPE multiSample, bool lockable, unsigned long usage) : Surface(getParentResource(container), width, height, sampleCount(multiSample), translateFormat(format), lockable, (usage & D3DUSAGE_RENDERTARGET) == D3DUSAGE_RENDERTARGET || (usage & D3DUSAGE_DEPTHSTENCIL) == D3DUSAGE_DEPTHSTENCIL), device(device), container(container), width(width), height(height), format(format), pool(pool), multiSample(multiSample), lockable(lockable), usage(usage)
     62 	{
     63 		parentTexture = dynamic_cast<Direct3DBaseTexture8*>(container);
     64 
     65 		resource = new Direct3DResource8(device, D3DRTYPE_SURFACE, memoryUsage(width, height, format));
     66 	}
     67 
     68 	Direct3DSurface8::~Direct3DSurface8()
     69 	{
     70 		resource->Release();
     71 	}
     72 
     73 	void *Direct3DSurface8::lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
     74 	{
     75 		return Surface::lockInternal(x, y, z, lock, client);
     76 	}
     77 
     78 	void Direct3DSurface8::unlockInternal()
     79 	{
     80 		Surface::unlockInternal();
     81 	}
     82 
     83 	long Direct3DSurface8::QueryInterface(const IID &iid, void **object)
     84 	{
     85 		TRACE("");
     86 
     87 		if(iid == IID_IDirect3DSurface8 ||
     88 		   iid == IID_IUnknown)
     89 		{
     90 			AddRef();
     91 			*object = this;
     92 
     93 			return S_OK;
     94 		}
     95 
     96 		*object = 0;
     97 
     98 		return NOINTERFACE(iid);
     99 	}
    100 
    101 	unsigned long Direct3DSurface8::AddRef()
    102 	{
    103 		TRACE("");
    104 
    105 		if(parentTexture)
    106 		{
    107 			return parentTexture->AddRef();
    108 		}
    109 
    110 		return Unknown::AddRef();
    111 	}
    112 
    113 	unsigned long Direct3DSurface8::Release()
    114 	{
    115 		TRACE("");
    116 
    117 		if(parentTexture)
    118 		{
    119 			return parentTexture->Release();
    120 		}
    121 
    122 		return Unknown::Release();
    123 	}
    124 
    125 	long Direct3DSurface8::FreePrivateData(const GUID &guid)
    126 	{
    127 		TRACE("");
    128 
    129 		return resource->FreePrivateData(guid);
    130 	}
    131 
    132 	long Direct3DSurface8::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
    133 	{
    134 		TRACE("");
    135 
    136 		return resource->GetPrivateData(guid, data, size);
    137 	}
    138 
    139 	long Direct3DSurface8::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
    140 	{
    141 		TRACE("");
    142 
    143 		return resource->SetPrivateData(guid, data, size, flags);
    144 	}
    145 
    146 	long Direct3DSurface8::GetDevice(IDirect3DDevice8 **device)
    147 	{
    148 		TRACE("");
    149 
    150 		return resource->GetDevice(device);
    151 	}
    152 
    153 	long Direct3DSurface8::LockRect(D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags)
    154 	{
    155 		TRACE("");
    156 
    157 		if(!lockedRect)
    158 		{
    159 			return INVALIDCALL();
    160 		}
    161 
    162 		lockedRect->Pitch = getExternalPitchB();
    163 
    164 		sw::Lock lock = sw::LOCK_READWRITE;
    165 
    166 		if(flags & D3DLOCK_DISCARD)
    167 		{
    168 			lock = sw::LOCK_DISCARD;
    169 		}
    170 
    171 		if(flags & D3DLOCK_READONLY)
    172 		{
    173 			lock = sw::LOCK_READONLY;
    174 		}
    175 
    176 		if(rect)
    177 		{
    178 			lockedRect->pBits = lockExternal(rect->left, rect->top, 0, lock, sw::PUBLIC);
    179 		}
    180 		else
    181 		{
    182 			lockedRect->pBits = lockExternal(0, 0, 0, lock, sw::PUBLIC);
    183 		}
    184 
    185 		unlockExternal();
    186 
    187 		return D3D_OK;
    188 	}
    189 
    190 	long Direct3DSurface8::UnlockRect()
    191 	{
    192 		TRACE("");
    193 
    194 		return D3D_OK;
    195 	}
    196 
    197 	long Direct3DSurface8::GetContainer(const IID &iid, void **container)
    198 	{
    199 		TRACE("");
    200 
    201 		if(!container)
    202 		{
    203 			return INVALIDCALL();
    204 		}
    205 
    206 		long result = this->container->QueryInterface(iid, container);
    207 
    208 		if(result == S_OK)
    209 		{
    210 			return D3D_OK;
    211 		}
    212 
    213 		return INVALIDCALL();
    214 	}
    215 
    216 	long Direct3DSurface8::GetDesc(D3DSURFACE_DESC *desc)
    217 	{
    218 		TRACE("");
    219 
    220 		if(!desc)
    221 		{
    222 			return INVALIDCALL();
    223 		}
    224 
    225 		desc->Format = format;
    226 		desc->Pool = pool;
    227 		desc->Type = D3DRTYPE_SURFACE;
    228 		desc->Height = height;
    229 		desc->Width = width;
    230 		desc->Size = size(getWidth(), getHeight(), getDepth(), getExternalFormat());
    231 		desc->MultiSampleType = multiSample;
    232 		desc->Usage = usage;
    233 
    234 		return D3D_OK;
    235 	}
    236 
    237 	sw::Format Direct3DSurface8::translateFormat(D3DFORMAT format)
    238 	{
    239 		switch(format)
    240 		{
    241 		case D3DFMT_DXT1:			return sw::FORMAT_DXT1;
    242 		case D3DFMT_DXT2:			return sw::FORMAT_DXT3;
    243 		case D3DFMT_DXT3:			return sw::FORMAT_DXT3;
    244 		case D3DFMT_DXT4:			return sw::FORMAT_DXT5;
    245 		case D3DFMT_DXT5:			return sw::FORMAT_DXT5;
    246 		case D3DFMT_R3G3B2:			return sw::FORMAT_R3G3B2;
    247 		case D3DFMT_A8R3G3B2:		return sw::FORMAT_A8R3G3B2;
    248 		case D3DFMT_X4R4G4B4:		return sw::FORMAT_X4R4G4B4;
    249 		case D3DFMT_A4R4G4B4:		return sw::FORMAT_A4R4G4B4;
    250 		case D3DFMT_A8R8G8B8:		return sw::FORMAT_A8R8G8B8;
    251 		case D3DFMT_G16R16:			return sw::FORMAT_G16R16;
    252 		case D3DFMT_A2B10G10R10:	return sw::FORMAT_A2B10G10R10;
    253 		case D3DFMT_P8:				return sw::FORMAT_P8;
    254 		case D3DFMT_A8P8:			return sw::FORMAT_A8P8;
    255 		case D3DFMT_A8:				return sw::FORMAT_A8;
    256 		case D3DFMT_R5G6B5:			return sw::FORMAT_R5G6B5;
    257 		case D3DFMT_X1R5G5B5:		return sw::FORMAT_X1R5G5B5;
    258 		case D3DFMT_A1R5G5B5:		return sw::FORMAT_A1R5G5B5;
    259 		case D3DFMT_R8G8B8:			return sw::FORMAT_R8G8B8;
    260 		case D3DFMT_X8R8G8B8:		return sw::FORMAT_X8R8G8B8;
    261 		case D3DFMT_V8U8:			return sw::FORMAT_V8U8;
    262 		case D3DFMT_L6V5U5:			return sw::FORMAT_L6V5U5;
    263 		case D3DFMT_Q8W8V8U8:		return sw::FORMAT_Q8W8V8U8;
    264 		case D3DFMT_X8L8V8U8:		return sw::FORMAT_X8L8V8U8;
    265 		case D3DFMT_A2W10V10U10:	return sw::FORMAT_A2W10V10U10;
    266 		case D3DFMT_V16U16:			return sw::FORMAT_V16U16;
    267 		case D3DFMT_L8:				return sw::FORMAT_L8;
    268 		case D3DFMT_A4L4:			return sw::FORMAT_A4L4;
    269 		case D3DFMT_A8L8:			return sw::FORMAT_A8L8;
    270 		case D3DFMT_D16:			return sw::FORMAT_D16;
    271 		case D3DFMT_D32:			return sw::FORMAT_D32;
    272 		case D3DFMT_D24X8:			return sw::FORMAT_D24X8;
    273 		case D3DFMT_D24S8:			return sw::FORMAT_D24S8;
    274 		default:
    275 			ASSERT(false);
    276 		}
    277 
    278 		return sw::FORMAT_NULL;
    279 	}
    280 
    281 	int Direct3DSurface8::bytes(D3DFORMAT format)
    282 	{
    283 		return Surface::bytes(translateFormat(format));
    284 	}
    285 
    286 	unsigned int Direct3DSurface8::memoryUsage(int width, int height, D3DFORMAT format)
    287 	{
    288 		return Surface::size(width, height, 1, translateFormat(format));
    289 	}
    290 }
    291