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