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