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 "Direct3D9Ex.hpp" 16 17 #include "Direct3DDevice9Ex.hpp" 18 #include "Debug.hpp" 19 20 namespace sw 21 { 22 extern bool postBlendSRGB; 23 } 24 25 namespace D3D9 26 { Direct3D9Ex(int version,const HINSTANCE instance)27 Direct3D9Ex::Direct3D9Ex(int version, const HINSTANCE instance) : Direct3D9(version, instance) 28 { 29 d3d9ex = 0; 30 } 31 ~Direct3D9Ex()32 Direct3D9Ex::~Direct3D9Ex() 33 { 34 } 35 QueryInterface(const IID & iid,void ** object)36 long Direct3D9Ex::QueryInterface(const IID &iid, void **object) 37 { 38 TRACE("const IID &iid = 0x%0.8p, void **object = 0x%0.8p", iid, object); 39 40 if(iid == IID_IDirect3D9Ex || 41 iid == IID_IDirect3D9 || 42 iid == IID_IUnknown) 43 { 44 AddRef(); 45 *object = this; 46 47 return S_OK; 48 } 49 50 *object = 0; 51 52 return NOINTERFACE(iid); 53 } 54 AddRef()55 unsigned long Direct3D9Ex::AddRef() 56 { 57 TRACE("void"); 58 59 return Direct3D9::AddRef(); 60 } 61 Release()62 unsigned long Direct3D9Ex::Release() 63 { 64 TRACE("void"); 65 66 return Direct3D9::Release(); 67 } 68 RegisterSoftwareDevice(void * initializeFunction)69 long Direct3D9Ex::RegisterSoftwareDevice(void *initializeFunction) 70 { 71 TRACE("void *initializeFunction = 0x%0.8p", initializeFunction); 72 73 loadSystemD3D9ex(); 74 75 if(d3d9ex) 76 { 77 return d3d9ex->RegisterSoftwareDevice(initializeFunction); 78 } 79 else 80 { 81 return INVALIDCALL(); 82 } 83 } 84 GetAdapterCount()85 unsigned int Direct3D9Ex::GetAdapterCount() 86 { 87 TRACE("void"); 88 89 return Direct3D9::GetAdapterCount(); 90 } 91 GetAdapterIdentifier(unsigned int adapter,unsigned long flags,D3DADAPTER_IDENTIFIER9 * identifier)92 long Direct3D9Ex::GetAdapterIdentifier(unsigned int adapter, unsigned long flags, D3DADAPTER_IDENTIFIER9 *identifier) 93 { 94 TRACE("unsigned int adapter = %d, unsigned long flags = 0x%0.8X, D3DADAPTER_IDENTIFIER9 *identifier = 0x%0.8p", adapter, flags, identifier); 95 96 return Direct3D9::GetAdapterIdentifier(adapter, flags, identifier); 97 } 98 GetAdapterModeCount(unsigned int adapter,D3DFORMAT format)99 unsigned int Direct3D9Ex::GetAdapterModeCount(unsigned int adapter, D3DFORMAT format) 100 { 101 TRACE("unsigned int adapter = %d, D3DFORMAT format = %d", adapter, format); 102 103 return Direct3D9::GetAdapterModeCount(adapter, format); 104 } 105 EnumAdapterModes(unsigned int adapter,D3DFORMAT format,unsigned int index,D3DDISPLAYMODE * mode)106 long Direct3D9Ex::EnumAdapterModes(unsigned int adapter, D3DFORMAT format, unsigned int index, D3DDISPLAYMODE *mode) 107 { 108 TRACE("unsigned int adapter = %d, D3DFORMAT format = %d, unsigned int index = %d, D3DDISPLAYMODE *mode = 0x%0.8p", adapter, format, index, mode); 109 110 return Direct3D9::EnumAdapterModes(adapter, format, index, mode); 111 } 112 GetAdapterDisplayMode(unsigned int adapter,D3DDISPLAYMODE * mode)113 long Direct3D9Ex::GetAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode) 114 { 115 TRACE("unsigned int adapter = %d, D3DDISPLAYMODE *mode = 0x%0.8p", adapter, mode); 116 117 return Direct3D9::GetAdapterDisplayMode(adapter, mode); 118 } 119 CheckDeviceType(unsigned int adapter,D3DDEVTYPE checkType,D3DFORMAT displayFormat,D3DFORMAT backBufferFormat,int windowed)120 long Direct3D9Ex::CheckDeviceType(unsigned int adapter, D3DDEVTYPE checkType, D3DFORMAT displayFormat, D3DFORMAT backBufferFormat, int windowed) 121 { 122 TRACE("unsigned int adapter = %d, D3DDEVTYPE checkType = %d, D3DFORMAT displayFormat = %d, D3DFORMAT backBufferFormat = %d, int windowed = %d", adapter, checkType, displayFormat, backBufferFormat, windowed); 123 124 if(checkType != D3DDEVTYPE_HAL) 125 { 126 loadSystemD3D9ex(); 127 128 if(d3d9ex) 129 { 130 return d3d9ex->CheckDeviceType(adapter, checkType, displayFormat, backBufferFormat, windowed); 131 } 132 else 133 { 134 return CheckDeviceType(adapter, D3DDEVTYPE_HAL, displayFormat, backBufferFormat, windowed); 135 } 136 } 137 138 return Direct3D9::CheckDeviceType(adapter, checkType, displayFormat, backBufferFormat, windowed); 139 } 140 CheckDeviceFormat(unsigned int adapter,D3DDEVTYPE deviceType,D3DFORMAT adapterFormat,unsigned long usage,D3DRESOURCETYPE resourceType,D3DFORMAT checkFormat)141 long Direct3D9Ex::CheckDeviceFormat(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, unsigned long usage, D3DRESOURCETYPE resourceType, D3DFORMAT checkFormat) 142 { 143 TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT adapterFormat = %d, unsigned long usage = %d, D3DRESOURCETYPE resourceType = %d, D3DFORMAT checkFormat = %d", adapter, deviceType, adapterFormat, usage, resourceType, checkFormat); 144 145 if(deviceType != D3DDEVTYPE_HAL) 146 { 147 loadSystemD3D9ex(); 148 149 if(d3d9ex) 150 { 151 return d3d9ex->CheckDeviceFormat(adapter, deviceType, adapterFormat, usage, resourceType, checkFormat); 152 } 153 else 154 { 155 return CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, adapterFormat, usage, resourceType, checkFormat); 156 } 157 } 158 159 return Direct3D9::CheckDeviceFormat(adapter, deviceType, adapterFormat, usage, resourceType, checkFormat); 160 } 161 CheckDeviceMultiSampleType(unsigned int adapter,D3DDEVTYPE deviceType,D3DFORMAT surfaceFormat,int windowed,D3DMULTISAMPLE_TYPE multiSampleType,unsigned long * qualityLevels)162 long Direct3D9Ex::CheckDeviceMultiSampleType(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT surfaceFormat, int windowed, D3DMULTISAMPLE_TYPE multiSampleType, unsigned long *qualityLevels) 163 { 164 TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT surfaceFormat = %d, int windowed = %d, D3DMULTISAMPLE_TYPE multiSampleType = %d, unsigned long *qualityLevels = 0x%0.8p", adapter, deviceType, surfaceFormat, windowed, multiSampleType, qualityLevels); 165 166 if(deviceType != D3DDEVTYPE_HAL) 167 { 168 loadSystemD3D9ex(); 169 170 if(d3d9ex) 171 { 172 return d3d9ex->CheckDeviceMultiSampleType(adapter, deviceType, surfaceFormat, windowed, multiSampleType, qualityLevels); 173 } 174 else 175 { 176 return CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, surfaceFormat, windowed, multiSampleType, qualityLevels); 177 } 178 } 179 180 return Direct3D9::CheckDeviceMultiSampleType(adapter, deviceType, surfaceFormat, windowed, multiSampleType, qualityLevels); 181 } 182 CheckDepthStencilMatch(unsigned int adapter,D3DDEVTYPE deviceType,D3DFORMAT adapterFormat,D3DFORMAT renderTargetFormat,D3DFORMAT depthStencilFormat)183 long Direct3D9Ex::CheckDepthStencilMatch(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat) 184 { 185 TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT adapterFormat = %d, D3DFORMAT renderTargetFormat = %d, D3DFORMAT depthStencilFormat = %d", adapter, deviceType, adapterFormat, renderTargetFormat, depthStencilFormat); 186 187 return Direct3D9::CheckDepthStencilMatch(adapter, deviceType, adapterFormat, renderTargetFormat, depthStencilFormat); 188 } 189 CheckDeviceFormatConversion(unsigned int adapter,D3DDEVTYPE deviceType,D3DFORMAT sourceFormat,D3DFORMAT targetFormat)190 long Direct3D9Ex::CheckDeviceFormatConversion(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT sourceFormat, D3DFORMAT targetFormat) 191 { 192 TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT sourceFormat = %d, D3DFORMAT targetFormat = %d", adapter, deviceType, sourceFormat, targetFormat); 193 194 if(deviceType != D3DDEVTYPE_HAL) 195 { 196 loadSystemD3D9ex(); 197 198 if(d3d9ex) 199 { 200 return d3d9ex->CheckDeviceFormatConversion(adapter, deviceType, sourceFormat, targetFormat); 201 } 202 else 203 { 204 return CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, sourceFormat, targetFormat); 205 } 206 } 207 208 return D3D_OK; 209 } 210 GetDeviceCaps(unsigned int adapter,D3DDEVTYPE deviceType,D3DCAPS9 * capabilities)211 long Direct3D9Ex::GetDeviceCaps(unsigned int adapter, D3DDEVTYPE deviceType, D3DCAPS9 *capabilities) 212 { 213 TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DCAPS9 *capabilities = 0x%0.8p", adapter, deviceType, capabilities); 214 215 if(deviceType != D3DDEVTYPE_HAL) 216 { 217 loadSystemD3D9ex(); 218 219 if(d3d9ex) 220 { 221 return d3d9ex->GetDeviceCaps(adapter, deviceType, capabilities); 222 } 223 else 224 { 225 return GetDeviceCaps(adapter, D3DDEVTYPE_HAL, capabilities); 226 } 227 } 228 229 long result = Direct3D9::GetDeviceCaps(adapter, deviceType, capabilities); 230 231 if(sw::postBlendSRGB) 232 { 233 capabilities->PrimitiveMiscCaps |= D3DPMISCCAPS_POSTBLENDSRGBCONVERT; // Indicates device can perform conversion to sRGB after blending. 234 } 235 236 return result; 237 } 238 GetAdapterMonitor(unsigned int adapter)239 HMONITOR Direct3D9Ex::GetAdapterMonitor(unsigned int adapter) 240 { 241 TRACE("unsigned int adapter = %d", adapter); 242 243 return Direct3D9::GetAdapterMonitor(adapter); 244 } 245 CreateDevice(unsigned int adapter,D3DDEVTYPE deviceType,HWND focusWindow,unsigned long behaviorFlags,D3DPRESENT_PARAMETERS * presentParameters,IDirect3DDevice9 ** returnedDeviceInterface)246 long Direct3D9Ex::CreateDevice(unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviorFlags, D3DPRESENT_PARAMETERS *presentParameters, IDirect3DDevice9 **returnedDeviceInterface) 247 { 248 TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, HWND focusWindow = %d, unsigned long behaviorFlags = 0x%0.8X, D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, IDirect3DDevice9 **returnedDeviceInterface = 0x%0.8p", adapter, deviceType, focusWindow, behaviorFlags, presentParameters, returnedDeviceInterface); 249 250 if(!focusWindow || !presentParameters || !returnedDeviceInterface) 251 { 252 *returnedDeviceInterface = 0; 253 254 return INVALIDCALL(); 255 } 256 257 D3DDISPLAYMODEEX fullscreenDisplayMode = {0}; 258 fullscreenDisplayMode.Size = sizeof(D3DDISPLAYMODEEX); 259 fullscreenDisplayMode.Format = presentParameters->BackBufferFormat; 260 fullscreenDisplayMode.Width = presentParameters->BackBufferWidth; 261 fullscreenDisplayMode.Height = presentParameters->BackBufferHeight; 262 fullscreenDisplayMode.RefreshRate = presentParameters->FullScreen_RefreshRateInHz; 263 fullscreenDisplayMode.ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE; 264 265 return CreateDeviceEx(adapter, deviceType, focusWindow, behaviorFlags, presentParameters, presentParameters->Windowed ? 0 : &fullscreenDisplayMode, (IDirect3DDevice9Ex**)returnedDeviceInterface); 266 } 267 GetAdapterModeCountEx(unsigned int adapter,const D3DDISPLAYMODEFILTER * filter)268 unsigned int __stdcall Direct3D9Ex::GetAdapterModeCountEx(unsigned int adapter, const D3DDISPLAYMODEFILTER *filter) 269 { 270 TRACE("unsigned int adapter = %d, const D3DDISPLAYMODEFILTER *filter = 0x%0.8p", adapter, filter); 271 272 return Direct3D9::GetAdapterModeCount(adapter, filter->Format); // FIXME 273 } 274 EnumAdapterModesEx(unsigned int adapter,const D3DDISPLAYMODEFILTER * filter,unsigned int index,D3DDISPLAYMODEEX * modeEx)275 long __stdcall Direct3D9Ex::EnumAdapterModesEx(unsigned int adapter, const D3DDISPLAYMODEFILTER *filter, unsigned int index, D3DDISPLAYMODEEX *modeEx) 276 { 277 TRACE("unsigned int adapter = %d, const D3DDISPLAYMODEFILTER *filter = 0x%0.8p, unsigned int index = %d, D3DDISPLAYMODEEX *modeEx = 0x%0.8p", adapter, filter, index, modeEx); 278 279 D3DDISPLAYMODE mode; 280 281 mode.Format = modeEx->Format; 282 mode.Width = modeEx->Width; 283 mode.Height = modeEx->Height; 284 mode.RefreshRate = modeEx->RefreshRate; 285 286 return Direct3D9::EnumAdapterModes(adapter, filter->Format, index, &mode); // FIXME 287 } 288 GetAdapterDisplayModeEx(unsigned int adapter,D3DDISPLAYMODEEX * modeEx,D3DDISPLAYROTATION * rotation)289 long __stdcall Direct3D9Ex::GetAdapterDisplayModeEx(unsigned int adapter, D3DDISPLAYMODEEX *modeEx, D3DDISPLAYROTATION *rotation) 290 { 291 TRACE("unsigned int adapter = %d, D3DDISPLAYMODEEX *modeEx = 0x%0.8p, D3DDISPLAYROTATION *rotation = 0x%0.8p", adapter, modeEx, rotation); 292 293 D3DDISPLAYMODE mode; 294 295 mode.Format = modeEx->Format; 296 mode.Width = modeEx->Width; 297 mode.Height = modeEx->Height; 298 mode.RefreshRate = modeEx->RefreshRate; 299 300 return GetAdapterDisplayMode(adapter, &mode); // FIXME 301 } 302 CreateDeviceEx(unsigned int adapter,D3DDEVTYPE deviceType,HWND focusWindow,DWORD behaviorFlags,D3DPRESENT_PARAMETERS * presentParameters,D3DDISPLAYMODEEX * fullscreenDisplayMode,IDirect3DDevice9Ex ** returnedDeviceInterface)303 long __stdcall Direct3D9Ex::CreateDeviceEx(unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, DWORD behaviorFlags, D3DPRESENT_PARAMETERS *presentParameters, D3DDISPLAYMODEEX *fullscreenDisplayMode, IDirect3DDevice9Ex **returnedDeviceInterface) 304 { 305 TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, HWND focusWindow = %d, DWORD behaviorFlags = 0x%0.8X, D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, D3DDISPLAYMODEEX *fullscreenDisplayMode = 0x%0.8p, IDirect3DDevice9Ex **returnedDeviceInterface = 0x%0.8p", adapter, deviceType, focusWindow, behaviorFlags, presentParameters, fullscreenDisplayMode, returnedDeviceInterface); 306 307 if(deviceType != D3DDEVTYPE_HAL) 308 { 309 loadSystemD3D9ex(); 310 311 if(d3d9ex) 312 { 313 return d3d9ex->CreateDeviceEx(adapter, deviceType, focusWindow, behaviorFlags, presentParameters, fullscreenDisplayMode, returnedDeviceInterface); 314 } 315 else 316 { 317 CreateDeviceEx(adapter, deviceType, focusWindow, behaviorFlags, presentParameters, fullscreenDisplayMode, returnedDeviceInterface); 318 } 319 } 320 321 if(!focusWindow || !presentParameters || !returnedDeviceInterface) 322 { 323 *returnedDeviceInterface = 0; 324 325 return INVALIDCALL(); 326 } 327 328 *returnedDeviceInterface = new Direct3DDevice9Ex(instance, this, adapter, deviceType, focusWindow, behaviorFlags, presentParameters); 329 330 if(*returnedDeviceInterface) 331 { 332 (*returnedDeviceInterface)->AddRef(); 333 } 334 335 return D3D_OK; 336 } 337 GetAdapterLUID(unsigned int adapter,LUID * luid)338 long __stdcall Direct3D9Ex::GetAdapterLUID(unsigned int adapter, LUID *luid) 339 { 340 TRACE("unsigned int adapter = %d, LUID *luid = 0x%0.8p", adapter, luid); 341 342 if(adapter != D3DADAPTER_DEFAULT) 343 { 344 UNIMPLEMENTED(); 345 } 346 347 // FIXME: Should return a presistent id using AllocateLocallyUniqueId() 348 luid->LowPart = 0x0000001; 349 luid->HighPart = 0x0000000; 350 351 return D3D_OK; 352 } 353 loadSystemD3D9ex()354 void Direct3D9Ex::loadSystemD3D9ex() 355 { 356 if(d3d9ex) 357 { 358 return; 359 } 360 361 char d3d9Path[MAX_PATH + 16]; 362 GetSystemDirectory(d3d9Path, MAX_PATH); 363 strcat(d3d9Path, "\\d3d9.dll"); 364 d3d9Lib = LoadLibrary(d3d9Path); 365 366 if(d3d9Lib) 367 { 368 typedef IDirect3D9Ex* (__stdcall *DIRECT3DCREATE9EX)(unsigned int, IDirect3D9Ex**); 369 DIRECT3DCREATE9EX direct3DCreate9Ex = (DIRECT3DCREATE9EX)GetProcAddress(d3d9Lib, "Direct3DCreate9Ex"); 370 direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex); 371 } 372 } 373 } 374