1 /* 2 * IDirect3DDevice9 implementation 3 * 4 * Copyright 2002-2005 Jason Edmeades 5 * Copyright 2002-2005 Raphael Junqueira 6 * Copyright 2005 Oliver Stieber 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 21 */ 22 23 #include "d3d9_private.h" 24 25 #include <winuser.h> 26 27 static void STDMETHODCALLTYPE d3d9_null_wined3d_object_destroyed(void *parent) {} 28 29 const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops = 30 { 31 d3d9_null_wined3d_object_destroyed, 32 }; 33 34 D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) 35 { 36 BYTE *c = (BYTE *)&format; 37 38 /* Don't translate FOURCC formats */ 39 if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format; 40 41 switch(format) 42 { 43 case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN; 44 case WINED3DFMT_B8G8R8_UNORM: return D3DFMT_R8G8B8; 45 case WINED3DFMT_B8G8R8A8_UNORM: return D3DFMT_A8R8G8B8; 46 case WINED3DFMT_B8G8R8X8_UNORM: return D3DFMT_X8R8G8B8; 47 case WINED3DFMT_B5G6R5_UNORM: return D3DFMT_R5G6B5; 48 case WINED3DFMT_B5G5R5X1_UNORM: return D3DFMT_X1R5G5B5; 49 case WINED3DFMT_B5G5R5A1_UNORM: return D3DFMT_A1R5G5B5; 50 case WINED3DFMT_B4G4R4A4_UNORM: return D3DFMT_A4R4G4B4; 51 case WINED3DFMT_B2G3R3_UNORM: return D3DFMT_R3G3B2; 52 case WINED3DFMT_A8_UNORM: return D3DFMT_A8; 53 case WINED3DFMT_B2G3R3A8_UNORM: return D3DFMT_A8R3G3B2; 54 case WINED3DFMT_B4G4R4X4_UNORM: return D3DFMT_X4R4G4B4; 55 case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10; 56 case WINED3DFMT_R8G8B8A8_UNORM: return D3DFMT_A8B8G8R8; 57 case WINED3DFMT_R8G8B8X8_UNORM: return D3DFMT_X8B8G8R8; 58 case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16; 59 case WINED3DFMT_B10G10R10A2_UNORM: return D3DFMT_A2R10G10B10; 60 case WINED3DFMT_R16G16B16A16_UNORM: return D3DFMT_A16B16G16R16; 61 case WINED3DFMT_P8_UINT_A8_UNORM: return D3DFMT_A8P8; 62 case WINED3DFMT_P8_UINT: return D3DFMT_P8; 63 case WINED3DFMT_L8_UNORM: return D3DFMT_L8; 64 case WINED3DFMT_L8A8_UNORM: return D3DFMT_A8L8; 65 case WINED3DFMT_L4A4_UNORM: return D3DFMT_A4L4; 66 case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8; 67 case WINED3DFMT_R5G5_SNORM_L6_UNORM: return D3DFMT_L6V5U5; 68 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: return D3DFMT_X8L8V8U8; 69 case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8; 70 case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16; 71 case WINED3DFMT_R10G10B10_SNORM_A2_UNORM: return D3DFMT_A2W10V10U10; 72 case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE; 73 case WINED3DFMT_D32_UNORM: return D3DFMT_D32; 74 case WINED3DFMT_S1_UINT_D15_UNORM: return D3DFMT_D15S1; 75 case WINED3DFMT_D24_UNORM_S8_UINT: return D3DFMT_D24S8; 76 case WINED3DFMT_X8D24_UNORM: return D3DFMT_D24X8; 77 case WINED3DFMT_S4X4_UINT_D24_UNORM: return D3DFMT_D24X4S4; 78 case WINED3DFMT_D16_UNORM: return D3DFMT_D16; 79 case WINED3DFMT_L16_UNORM: return D3DFMT_L16; 80 case WINED3DFMT_D32_FLOAT: return D3DFMT_D32F_LOCKABLE; 81 case WINED3DFMT_S8_UINT_D24_FLOAT: return D3DFMT_D24FS8; 82 case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16; 83 case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32; 84 case WINED3DFMT_R16G16B16A16_SNORM: return D3DFMT_Q16W16V16U16; 85 case WINED3DFMT_R16_FLOAT: return D3DFMT_R16F; 86 case WINED3DFMT_R16G16_FLOAT: return D3DFMT_G16R16F; 87 case WINED3DFMT_R16G16B16A16_FLOAT: return D3DFMT_A16B16G16R16F; 88 case WINED3DFMT_R32_FLOAT: return D3DFMT_R32F; 89 case WINED3DFMT_R32G32_FLOAT: return D3DFMT_G32R32F; 90 case WINED3DFMT_R32G32B32A32_FLOAT: return D3DFMT_A32B32G32R32F; 91 case WINED3DFMT_R8G8_SNORM_Cx: return D3DFMT_CxV8U8; 92 default: 93 FIXME("Unhandled wined3d format %#x.\n", format); 94 return D3DFMT_UNKNOWN; 95 } 96 } 97 98 enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) 99 { 100 BYTE *c = (BYTE *)&format; 101 102 /* Don't translate FOURCC formats */ 103 if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format; 104 105 switch(format) 106 { 107 case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN; 108 case D3DFMT_R8G8B8: return WINED3DFMT_B8G8R8_UNORM; 109 case D3DFMT_A8R8G8B8: return WINED3DFMT_B8G8R8A8_UNORM; 110 case D3DFMT_X8R8G8B8: return WINED3DFMT_B8G8R8X8_UNORM; 111 case D3DFMT_R5G6B5: return WINED3DFMT_B5G6R5_UNORM; 112 case D3DFMT_X1R5G5B5: return WINED3DFMT_B5G5R5X1_UNORM; 113 case D3DFMT_A1R5G5B5: return WINED3DFMT_B5G5R5A1_UNORM; 114 case D3DFMT_A4R4G4B4: return WINED3DFMT_B4G4R4A4_UNORM; 115 case D3DFMT_R3G3B2: return WINED3DFMT_B2G3R3_UNORM; 116 case D3DFMT_A8: return WINED3DFMT_A8_UNORM; 117 case D3DFMT_A8R3G3B2: return WINED3DFMT_B2G3R3A8_UNORM; 118 case D3DFMT_X4R4G4B4: return WINED3DFMT_B4G4R4X4_UNORM; 119 case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM; 120 case D3DFMT_A8B8G8R8: return WINED3DFMT_R8G8B8A8_UNORM; 121 case D3DFMT_X8B8G8R8: return WINED3DFMT_R8G8B8X8_UNORM; 122 case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM; 123 case D3DFMT_A2R10G10B10: return WINED3DFMT_B10G10R10A2_UNORM; 124 case D3DFMT_A16B16G16R16: return WINED3DFMT_R16G16B16A16_UNORM; 125 case D3DFMT_A8P8: return WINED3DFMT_P8_UINT_A8_UNORM; 126 case D3DFMT_P8: return WINED3DFMT_P8_UINT; 127 case D3DFMT_L8: return WINED3DFMT_L8_UNORM; 128 case D3DFMT_A8L8: return WINED3DFMT_L8A8_UNORM; 129 case D3DFMT_A4L4: return WINED3DFMT_L4A4_UNORM; 130 case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM; 131 case D3DFMT_L6V5U5: return WINED3DFMT_R5G5_SNORM_L6_UNORM; 132 case D3DFMT_X8L8V8U8: return WINED3DFMT_R8G8_SNORM_L8X8_UNORM; 133 case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM; 134 case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM; 135 case D3DFMT_A2W10V10U10: return WINED3DFMT_R10G10B10_SNORM_A2_UNORM; 136 case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE; 137 case D3DFMT_D32: return WINED3DFMT_D32_UNORM; 138 case D3DFMT_D15S1: return WINED3DFMT_S1_UINT_D15_UNORM; 139 case D3DFMT_D24S8: return WINED3DFMT_D24_UNORM_S8_UINT; 140 case D3DFMT_D24X8: return WINED3DFMT_X8D24_UNORM; 141 case D3DFMT_D24X4S4: return WINED3DFMT_S4X4_UINT_D24_UNORM; 142 case D3DFMT_D16: return WINED3DFMT_D16_UNORM; 143 case D3DFMT_L16: return WINED3DFMT_L16_UNORM; 144 case D3DFMT_D32F_LOCKABLE: return WINED3DFMT_D32_FLOAT; 145 case D3DFMT_D24FS8: return WINED3DFMT_S8_UINT_D24_FLOAT; 146 case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT; 147 case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT; 148 case D3DFMT_Q16W16V16U16: return WINED3DFMT_R16G16B16A16_SNORM; 149 case D3DFMT_R16F: return WINED3DFMT_R16_FLOAT; 150 case D3DFMT_G16R16F: return WINED3DFMT_R16G16_FLOAT; 151 case D3DFMT_A16B16G16R16F: return WINED3DFMT_R16G16B16A16_FLOAT; 152 case D3DFMT_R32F: return WINED3DFMT_R32_FLOAT; 153 case D3DFMT_G32R32F: return WINED3DFMT_R32G32_FLOAT; 154 case D3DFMT_A32B32G32R32F: return WINED3DFMT_R32G32B32A32_FLOAT; 155 case D3DFMT_CxV8U8: return WINED3DFMT_R8G8_SNORM_Cx; 156 default: 157 FIXME("Unhandled D3DFORMAT %#x.\n", format); 158 return WINED3DFMT_UNKNOWN; 159 } 160 } 161 162 static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count) 163 { 164 switch (primitive_type) 165 { 166 case D3DPT_POINTLIST: 167 return primitive_count; 168 169 case D3DPT_LINELIST: 170 return primitive_count * 2; 171 172 case D3DPT_LINESTRIP: 173 return primitive_count + 1; 174 175 case D3DPT_TRIANGLELIST: 176 return primitive_count * 3; 177 178 case D3DPT_TRIANGLESTRIP: 179 case D3DPT_TRIANGLEFAN: 180 return primitive_count + 2; 181 182 default: 183 FIXME("Unhandled primitive type %#x.\n", primitive_type); 184 return 0; 185 } 186 } 187 188 void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters, 189 const struct wined3d_swapchain_desc *swapchain_desc) 190 { 191 present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width; 192 present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height; 193 present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc->backbuffer_format); 194 present_parameters->BackBufferCount = swapchain_desc->backbuffer_count; 195 present_parameters->MultiSampleType = swapchain_desc->multisample_type; 196 present_parameters->MultiSampleQuality = swapchain_desc->multisample_quality; 197 present_parameters->SwapEffect = swapchain_desc->swap_effect; 198 present_parameters->hDeviceWindow = swapchain_desc->device_window; 199 present_parameters->Windowed = swapchain_desc->windowed; 200 present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil; 201 present_parameters->AutoDepthStencilFormat 202 = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format); 203 present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK; 204 present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate; 205 present_parameters->PresentationInterval = swapchain_desc->swap_interval; 206 } 207 208 static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc, 209 const D3DPRESENT_PARAMETERS *present_parameters, BOOL extended) 210 { 211 D3DSWAPEFFECT highest_swapeffect = extended ? D3DSWAPEFFECT_FLIPEX : D3DSWAPEFFECT_COPY; 212 UINT highest_bb_count = extended ? 30 : 3; 213 214 if (!present_parameters->SwapEffect || present_parameters->SwapEffect > highest_swapeffect) 215 { 216 WARN("Invalid swap effect %u passed.\n", present_parameters->SwapEffect); 217 return FALSE; 218 } 219 if (present_parameters->BackBufferCount > highest_bb_count 220 || (present_parameters->SwapEffect == D3DSWAPEFFECT_COPY 221 && present_parameters->BackBufferCount > 1)) 222 { 223 WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount); 224 return FALSE; 225 } 226 227 swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth; 228 swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight; 229 swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat); 230 swapchain_desc->backbuffer_count = max(1, present_parameters->BackBufferCount); 231 swapchain_desc->multisample_type = present_parameters->MultiSampleType; 232 swapchain_desc->multisample_quality = present_parameters->MultiSampleQuality; 233 swapchain_desc->swap_effect = present_parameters->SwapEffect; 234 swapchain_desc->device_window = present_parameters->hDeviceWindow; 235 swapchain_desc->windowed = present_parameters->Windowed; 236 swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil; 237 swapchain_desc->auto_depth_stencil_format 238 = wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat); 239 swapchain_desc->flags 240 = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; 241 swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz; 242 swapchain_desc->swap_interval = present_parameters->PresentationInterval; 243 swapchain_desc->auto_restore_display_mode = TRUE; 244 245 if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK) 246 FIXME("Unhandled flags %#x.\n", present_parameters->Flags & ~D3DPRESENTFLAGS_MASK); 247 248 return TRUE; 249 } 250 251 void d3dcaps_from_wined3dcaps(D3DCAPS9 *caps, const WINED3DCAPS *wined3d_caps) 252 { 253 static const DWORD ps_minor_version[] = {0, 4, 0, 0}; 254 static const DWORD vs_minor_version[] = {0, 1, 0, 0}; 255 static const DWORD texture_filter_caps = 256 D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFANISOTROPIC | 257 D3DPTFILTERCAPS_MINFPYRAMIDALQUAD | D3DPTFILTERCAPS_MINFGAUSSIANQUAD| 258 D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | 259 D3DPTFILTERCAPS_MAGFLINEAR |D3DPTFILTERCAPS_MAGFANISOTROPIC|D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD| 260 D3DPTFILTERCAPS_MAGFGAUSSIANQUAD; 261 262 caps->DeviceType = (D3DDEVTYPE)wined3d_caps->DeviceType; 263 caps->AdapterOrdinal = wined3d_caps->AdapterOrdinal; 264 caps->Caps = wined3d_caps->Caps; 265 caps->Caps2 = wined3d_caps->Caps2; 266 caps->Caps3 = wined3d_caps->Caps3; 267 caps->PresentationIntervals = wined3d_caps->PresentationIntervals; 268 caps->CursorCaps = wined3d_caps->CursorCaps; 269 caps->DevCaps = wined3d_caps->DevCaps; 270 caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps; 271 caps->RasterCaps = wined3d_caps->RasterCaps; 272 caps->ZCmpCaps = wined3d_caps->ZCmpCaps; 273 caps->SrcBlendCaps = wined3d_caps->SrcBlendCaps; 274 caps->DestBlendCaps = wined3d_caps->DestBlendCaps; 275 caps->AlphaCmpCaps = wined3d_caps->AlphaCmpCaps; 276 caps->ShadeCaps = wined3d_caps->ShadeCaps; 277 caps->TextureCaps = wined3d_caps->TextureCaps; 278 caps->TextureFilterCaps = wined3d_caps->TextureFilterCaps; 279 caps->CubeTextureFilterCaps = wined3d_caps->CubeTextureFilterCaps; 280 caps->VolumeTextureFilterCaps = wined3d_caps->VolumeTextureFilterCaps; 281 caps->TextureAddressCaps = wined3d_caps->TextureAddressCaps; 282 caps->VolumeTextureAddressCaps = wined3d_caps->VolumeTextureAddressCaps; 283 caps->LineCaps = wined3d_caps->LineCaps; 284 caps->MaxTextureWidth = wined3d_caps->MaxTextureWidth; 285 caps->MaxTextureHeight = wined3d_caps->MaxTextureHeight; 286 caps->MaxVolumeExtent = wined3d_caps->MaxVolumeExtent; 287 caps->MaxTextureRepeat = wined3d_caps->MaxTextureRepeat; 288 caps->MaxTextureAspectRatio = wined3d_caps->MaxTextureAspectRatio; 289 caps->MaxAnisotropy = wined3d_caps->MaxAnisotropy; 290 caps->MaxVertexW = wined3d_caps->MaxVertexW; 291 caps->GuardBandLeft = wined3d_caps->GuardBandLeft; 292 caps->GuardBandTop = wined3d_caps->GuardBandTop; 293 caps->GuardBandRight = wined3d_caps->GuardBandRight; 294 caps->GuardBandBottom = wined3d_caps->GuardBandBottom; 295 caps->ExtentsAdjust = wined3d_caps->ExtentsAdjust; 296 caps->StencilCaps = wined3d_caps->StencilCaps; 297 caps->FVFCaps = wined3d_caps->FVFCaps; 298 caps->TextureOpCaps = wined3d_caps->TextureOpCaps; 299 caps->MaxTextureBlendStages = wined3d_caps->MaxTextureBlendStages; 300 caps->MaxSimultaneousTextures = wined3d_caps->MaxSimultaneousTextures; 301 caps->VertexProcessingCaps = wined3d_caps->VertexProcessingCaps; 302 caps->MaxActiveLights = wined3d_caps->MaxActiveLights; 303 caps->MaxUserClipPlanes = wined3d_caps->MaxUserClipPlanes; 304 caps->MaxVertexBlendMatrices = wined3d_caps->MaxVertexBlendMatrices; 305 caps->MaxVertexBlendMatrixIndex = wined3d_caps->MaxVertexBlendMatrixIndex; 306 caps->MaxPointSize = wined3d_caps->MaxPointSize; 307 caps->MaxPrimitiveCount = wined3d_caps->MaxPrimitiveCount; 308 caps->MaxVertexIndex = wined3d_caps->MaxVertexIndex; 309 caps->MaxStreams = wined3d_caps->MaxStreams; 310 caps->MaxStreamStride = wined3d_caps->MaxStreamStride; 311 caps->VertexShaderVersion = wined3d_caps->VertexShaderVersion; 312 caps->MaxVertexShaderConst = wined3d_caps->MaxVertexShaderConst; 313 caps->PixelShaderVersion = wined3d_caps->PixelShaderVersion; 314 caps->PixelShader1xMaxValue = wined3d_caps->PixelShader1xMaxValue; 315 caps->DevCaps2 = wined3d_caps->DevCaps2; 316 caps->MaxNpatchTessellationLevel = wined3d_caps->MaxNpatchTessellationLevel; 317 caps->MasterAdapterOrdinal = wined3d_caps->MasterAdapterOrdinal; 318 caps->AdapterOrdinalInGroup = wined3d_caps->AdapterOrdinalInGroup; 319 caps->NumberOfAdaptersInGroup = wined3d_caps->NumberOfAdaptersInGroup; 320 caps->DeclTypes = wined3d_caps->DeclTypes; 321 caps->NumSimultaneousRTs = wined3d_caps->NumSimultaneousRTs; 322 caps->StretchRectFilterCaps = wined3d_caps->StretchRectFilterCaps; 323 caps->VS20Caps.Caps = wined3d_caps->VS20Caps.caps; 324 caps->VS20Caps.DynamicFlowControlDepth = wined3d_caps->VS20Caps.dynamic_flow_control_depth; 325 caps->VS20Caps.NumTemps = wined3d_caps->VS20Caps.temp_count; 326 caps->VS20Caps.StaticFlowControlDepth = wined3d_caps->VS20Caps.static_flow_control_depth; 327 caps->PS20Caps.Caps = wined3d_caps->PS20Caps.caps; 328 caps->PS20Caps.DynamicFlowControlDepth = wined3d_caps->PS20Caps.dynamic_flow_control_depth; 329 caps->PS20Caps.NumTemps = wined3d_caps->PS20Caps.temp_count; 330 caps->PS20Caps.StaticFlowControlDepth = wined3d_caps->PS20Caps.static_flow_control_depth; 331 caps->PS20Caps.NumInstructionSlots = wined3d_caps->PS20Caps.instruction_slot_count; 332 caps->VertexTextureFilterCaps = wined3d_caps->VertexTextureFilterCaps; 333 caps->MaxVShaderInstructionsExecuted = wined3d_caps->MaxVShaderInstructionsExecuted; 334 caps->MaxPShaderInstructionsExecuted = wined3d_caps->MaxPShaderInstructionsExecuted; 335 caps->MaxVertexShader30InstructionSlots = wined3d_caps->MaxVertexShader30InstructionSlots; 336 caps->MaxPixelShader30InstructionSlots = wined3d_caps->MaxPixelShader30InstructionSlots; 337 338 /* Some functionality is implemented in d3d9.dll, not wined3d.dll. Add the needed caps. */ 339 caps->DevCaps2 |= D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES; 340 341 /* Filter wined3d caps. */ 342 caps->TextureFilterCaps &= texture_filter_caps; 343 caps->CubeTextureFilterCaps &= texture_filter_caps; 344 caps->VolumeTextureFilterCaps &= texture_filter_caps; 345 346 caps->DevCaps &= 347 D3DDEVCAPS_EXECUTESYSTEMMEMORY | D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | 348 D3DDEVCAPS_TLVERTEXVIDEOMEMORY | D3DDEVCAPS_TEXTURESYSTEMMEMORY| D3DDEVCAPS_TEXTUREVIDEOMEMORY | 349 D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_TEXTURENONLOCALVIDMEM| 350 D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_SEPARATETEXTUREMEMORIES | 351 D3DDEVCAPS_DRAWPRIMITIVES2EX | D3DDEVCAPS_HWTRANSFORMANDLIGHT| D3DDEVCAPS_CANBLTSYSTONONLOCAL | 352 D3DDEVCAPS_HWRASTERIZATION | D3DDEVCAPS_PUREDEVICE | D3DDEVCAPS_QUINTICRTPATCHES | 353 D3DDEVCAPS_RTPATCHES | D3DDEVCAPS_RTPATCHHANDLEZERO | D3DDEVCAPS_NPATCHES; 354 355 caps->ShadeCaps &= 356 D3DPSHADECAPS_COLORGOURAUDRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB | 357 D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_FOGGOURAUD; 358 359 caps->RasterCaps &= 360 D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_FOGVERTEX | 361 D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR | 362 D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER | 363 D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE | 364 D3DPRASTERCAPS_SCISSORTEST | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS | 365 D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_MULTISAMPLE_TOGGLE; 366 367 caps->DevCaps2 &= 368 D3DDEVCAPS2_STREAMOFFSET | D3DDEVCAPS2_DMAPNPATCH | D3DDEVCAPS2_ADAPTIVETESSRTPATCH | 369 D3DDEVCAPS2_ADAPTIVETESSNPATCH | D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES | 370 D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH| D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET; 371 372 caps->Caps2 &= 373 D3DCAPS2_FULLSCREENGAMMA | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_RESERVED | 374 D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_CANAUTOGENMIPMAP; 375 376 caps->VertexProcessingCaps &= 377 D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_DIRECTIONALLIGHTS | 378 D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER | D3DVTXPCAPS_TWEENING | 379 D3DVTXPCAPS_TEXGEN_SPHEREMAP | D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER; 380 381 caps->TextureCaps &= 382 D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA | 383 D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | 384 D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | 385 D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP | 386 D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP | 387 D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV; 388 389 caps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst); 390 caps->NumSimultaneousRTs = min(D3D9_MAX_SIMULTANEOUS_RENDERTARGETS, caps->NumSimultaneousRTs); 391 392 if (caps->PixelShaderVersion > 3) 393 { 394 caps->PixelShaderVersion = D3DPS_VERSION(3, 0); 395 } 396 else 397 { 398 DWORD major = caps->PixelShaderVersion; 399 caps->PixelShaderVersion = D3DPS_VERSION(major, ps_minor_version[major]); 400 } 401 402 if (caps->VertexShaderVersion > 3) 403 { 404 caps->VertexShaderVersion = D3DVS_VERSION(3, 0); 405 } 406 else 407 { 408 DWORD major = caps->VertexShaderVersion; 409 caps->VertexShaderVersion = D3DVS_VERSION(major, vs_minor_version[major]); 410 } 411 } 412 413 static HRESULT WINAPI d3d9_device_QueryInterface(IDirect3DDevice9Ex *iface, REFIID riid, void **out) 414 { 415 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 416 417 if (IsEqualGUID(riid, &IID_IDirect3DDevice9) 418 || IsEqualGUID(riid, &IID_IUnknown)) 419 { 420 IDirect3DDevice9Ex_AddRef(iface); 421 *out = iface; 422 return S_OK; 423 } 424 425 if (IsEqualGUID(riid, &IID_IDirect3DDevice9Ex)) 426 { 427 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 428 429 /* Find out if the creating d3d9 interface was created with Direct3DCreate9Ex. 430 * It doesn't matter with which function the device was created. */ 431 if (!device->d3d_parent->extended) 432 { 433 WARN("IDirect3D9 instance wasn't created with CreateDirect3D9Ex, returning E_NOINTERFACE.\n"); 434 *out = NULL; 435 return E_NOINTERFACE; 436 } 437 438 IDirect3DDevice9Ex_AddRef(iface); 439 *out = iface; 440 return S_OK; 441 } 442 443 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 444 445 *out = NULL; 446 return E_NOINTERFACE; 447 } 448 449 static ULONG WINAPI d3d9_device_AddRef(IDirect3DDevice9Ex *iface) 450 { 451 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 452 ULONG refcount = InterlockedIncrement(&device->refcount); 453 454 TRACE("%p increasing refcount to %u.\n", iface, refcount); 455 456 return refcount; 457 } 458 459 static ULONG WINAPI DECLSPEC_HOTPATCH d3d9_device_Release(IDirect3DDevice9Ex *iface) 460 { 461 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 462 ULONG refcount; 463 464 if (device->in_destruction) 465 return 0; 466 467 refcount = InterlockedDecrement(&device->refcount); 468 469 TRACE("%p decreasing refcount to %u.\n", iface, refcount); 470 471 if (!refcount) 472 { 473 unsigned i; 474 device->in_destruction = TRUE; 475 476 wined3d_mutex_lock(); 477 for (i = 0; i < device->fvf_decl_count; ++i) 478 { 479 wined3d_vertex_declaration_decref(device->fvf_decls[i].decl); 480 } 481 HeapFree(GetProcessHeap(), 0, device->fvf_decls); 482 483 if (device->vertex_buffer) 484 wined3d_buffer_decref(device->vertex_buffer); 485 if (device->index_buffer) 486 wined3d_buffer_decref(device->index_buffer); 487 488 HeapFree(GetProcessHeap(), 0, device->implicit_swapchains); 489 490 wined3d_device_uninit_3d(device->wined3d_device); 491 wined3d_device_release_focus_window(device->wined3d_device); 492 wined3d_device_decref(device->wined3d_device); 493 wined3d_mutex_unlock(); 494 495 IDirect3D9Ex_Release(&device->d3d_parent->IDirect3D9Ex_iface); 496 497 HeapFree(GetProcessHeap(), 0, device); 498 } 499 500 return refcount; 501 } 502 503 static HRESULT WINAPI d3d9_device_TestCooperativeLevel(IDirect3DDevice9Ex *iface) 504 { 505 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 506 507 TRACE("iface %p.\n", iface); 508 509 TRACE("device state: %#x.\n", device->device_state); 510 511 if (device->d3d_parent->extended) 512 return D3D_OK; 513 514 switch (device->device_state) 515 { 516 default: 517 case D3D9_DEVICE_STATE_OK: 518 return D3D_OK; 519 case D3D9_DEVICE_STATE_LOST: 520 return D3DERR_DEVICELOST; 521 case D3D9_DEVICE_STATE_NOT_RESET: 522 return D3DERR_DEVICENOTRESET; 523 } 524 } 525 526 static UINT WINAPI d3d9_device_GetAvailableTextureMem(IDirect3DDevice9Ex *iface) 527 { 528 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 529 UINT ret; 530 531 TRACE("iface %p.\n", iface); 532 533 wined3d_mutex_lock(); 534 ret = wined3d_device_get_available_texture_mem(device->wined3d_device); 535 wined3d_mutex_unlock(); 536 537 return ret; 538 } 539 540 static HRESULT WINAPI d3d9_device_EvictManagedResources(IDirect3DDevice9Ex *iface) 541 { 542 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 543 544 TRACE("iface %p.\n", iface); 545 546 wined3d_mutex_lock(); 547 wined3d_device_evict_managed_resources(device->wined3d_device); 548 wined3d_mutex_unlock(); 549 550 return D3D_OK; 551 } 552 553 static HRESULT WINAPI d3d9_device_GetDirect3D(IDirect3DDevice9Ex *iface, IDirect3D9 **d3d9) 554 { 555 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 556 557 TRACE("iface %p, d3d9 %p.\n", iface, d3d9); 558 559 if (!d3d9) 560 return D3DERR_INVALIDCALL; 561 562 return IDirect3D9Ex_QueryInterface(&device->d3d_parent->IDirect3D9Ex_iface, &IID_IDirect3D9, (void **)d3d9); 563 } 564 565 static HRESULT WINAPI d3d9_device_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCAPS9 *caps) 566 { 567 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 568 WINED3DCAPS wined3d_caps; 569 HRESULT hr; 570 571 TRACE("iface %p, caps %p.\n", iface, caps); 572 573 if (!caps) 574 return D3DERR_INVALIDCALL; 575 576 memset(caps, 0, sizeof(*caps)); 577 578 wined3d_mutex_lock(); 579 hr = wined3d_device_get_device_caps(device->wined3d_device, &wined3d_caps); 580 wined3d_mutex_unlock(); 581 582 d3dcaps_from_wined3dcaps(caps, &wined3d_caps); 583 584 return hr; 585 } 586 587 static HRESULT WINAPI d3d9_device_GetDisplayMode(IDirect3DDevice9Ex *iface, UINT swapchain, D3DDISPLAYMODE *mode) 588 { 589 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 590 struct wined3d_display_mode wined3d_mode; 591 HRESULT hr; 592 593 TRACE("iface %p, swapchain %u, mode %p.\n", iface, swapchain, mode); 594 595 wined3d_mutex_lock(); 596 hr = wined3d_device_get_display_mode(device->wined3d_device, swapchain, &wined3d_mode, NULL); 597 wined3d_mutex_unlock(); 598 599 if (SUCCEEDED(hr)) 600 { 601 mode->Width = wined3d_mode.width; 602 mode->Height = wined3d_mode.height; 603 mode->RefreshRate = wined3d_mode.refresh_rate; 604 mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id); 605 } 606 607 return hr; 608 } 609 610 static HRESULT WINAPI d3d9_device_GetCreationParameters(IDirect3DDevice9Ex *iface, 611 D3DDEVICE_CREATION_PARAMETERS *parameters) 612 { 613 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 614 615 TRACE("iface %p, parameters %p.\n", iface, parameters); 616 617 wined3d_mutex_lock(); 618 wined3d_device_get_creation_parameters(device->wined3d_device, 619 (struct wined3d_device_creation_parameters *)parameters); 620 wined3d_mutex_unlock(); 621 622 return D3D_OK; 623 } 624 625 static HRESULT WINAPI d3d9_device_SetCursorProperties(IDirect3DDevice9Ex *iface, 626 UINT hotspot_x, UINT hotspot_y, IDirect3DSurface9 *bitmap) 627 { 628 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 629 struct d3d9_surface *bitmap_impl = unsafe_impl_from_IDirect3DSurface9(bitmap); 630 HRESULT hr; 631 632 TRACE("iface %p, hotspot_x %u, hotspot_y %u, bitmap %p.\n", 633 iface, hotspot_x, hotspot_y, bitmap); 634 635 if (!bitmap) 636 { 637 WARN("No cursor bitmap, returning D3DERR_INVALIDCALL.\n"); 638 return D3DERR_INVALIDCALL; 639 } 640 641 wined3d_mutex_lock(); 642 hr = wined3d_device_set_cursor_properties(device->wined3d_device, 643 hotspot_x, hotspot_y, bitmap_impl->wined3d_texture, bitmap_impl->sub_resource_idx); 644 wined3d_mutex_unlock(); 645 646 return hr; 647 } 648 649 static void WINAPI d3d9_device_SetCursorPosition(IDirect3DDevice9Ex *iface, int x, int y, DWORD flags) 650 { 651 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 652 653 TRACE("iface %p, x %u, y %u, flags %#x.\n", iface, x, y, flags); 654 655 wined3d_mutex_lock(); 656 wined3d_device_set_cursor_position(device->wined3d_device, x, y, flags); 657 wined3d_mutex_unlock(); 658 } 659 660 static BOOL WINAPI d3d9_device_ShowCursor(IDirect3DDevice9Ex *iface, BOOL show) 661 { 662 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 663 BOOL ret; 664 665 TRACE("iface %p, show %#x.\n", iface, show); 666 667 wined3d_mutex_lock(); 668 ret = wined3d_device_show_cursor(device->wined3d_device, show); 669 wined3d_mutex_unlock(); 670 671 return ret; 672 } 673 674 static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_CreateAdditionalSwapChain(IDirect3DDevice9Ex *iface, 675 D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain9 **swapchain) 676 { 677 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 678 struct wined3d_swapchain_desc desc; 679 struct d3d9_swapchain *object; 680 UINT i, count; 681 HRESULT hr; 682 683 TRACE("iface %p, present_parameters %p, swapchain %p.\n", 684 iface, present_parameters, swapchain); 685 686 if (!present_parameters->Windowed) 687 { 688 WARN("Trying to create an additional fullscreen swapchain, returning D3DERR_INVALIDCALL.\n"); 689 return D3DERR_INVALIDCALL; 690 } 691 692 wined3d_mutex_lock(); 693 count = wined3d_device_get_swapchain_count(device->wined3d_device); 694 for (i = 0; i < count; ++i) 695 { 696 struct wined3d_swapchain *wined3d_swapchain; 697 698 wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, i); 699 wined3d_swapchain_get_desc(wined3d_swapchain, &desc); 700 701 if (!desc.windowed) 702 { 703 wined3d_mutex_unlock(); 704 WARN("Trying to create an additional swapchain in fullscreen mode, returning D3DERR_INVALIDCALL.\n"); 705 return D3DERR_INVALIDCALL; 706 } 707 } 708 wined3d_mutex_unlock(); 709 710 if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters, 711 device->d3d_parent->extended)) 712 return D3DERR_INVALIDCALL; 713 if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object))) 714 *swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface; 715 present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc); 716 717 return hr; 718 } 719 720 static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_GetSwapChain(IDirect3DDevice9Ex *iface, 721 UINT swapchain_idx, IDirect3DSwapChain9 **swapchain) 722 { 723 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 724 HRESULT hr; 725 726 TRACE("iface %p, swapchain_idx %u, swapchain %p.\n", iface, swapchain_idx, swapchain); 727 728 wined3d_mutex_lock(); 729 if (swapchain_idx < device->implicit_swapchain_count) 730 { 731 *swapchain = (IDirect3DSwapChain9 *)&device->implicit_swapchains[swapchain_idx]->IDirect3DSwapChain9Ex_iface; 732 IDirect3DSwapChain9Ex_AddRef(*swapchain); 733 hr = D3D_OK; 734 } 735 else 736 { 737 *swapchain = NULL; 738 hr = D3DERR_INVALIDCALL; 739 } 740 wined3d_mutex_unlock(); 741 742 return hr; 743 } 744 745 static UINT WINAPI d3d9_device_GetNumberOfSwapChains(IDirect3DDevice9Ex *iface) 746 { 747 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 748 UINT count; 749 750 TRACE("iface %p.\n", iface); 751 752 wined3d_mutex_lock(); 753 count = wined3d_device_get_swapchain_count(device->wined3d_device); 754 wined3d_mutex_unlock(); 755 756 return count; 757 } 758 759 static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) 760 { 761 struct wined3d_resource_desc desc; 762 IDirect3DBaseTexture9 *texture; 763 struct d3d9_surface *surface; 764 IUnknown *parent; 765 766 wined3d_resource_get_desc(resource, &desc); 767 if (desc.pool != WINED3D_POOL_DEFAULT) 768 return D3D_OK; 769 770 if (desc.resource_type != WINED3D_RTYPE_TEXTURE_2D) 771 { 772 WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource); 773 return D3DERR_INVALIDCALL; 774 } 775 776 parent = wined3d_resource_get_parent(resource); 777 if (parent && SUCCEEDED(IUnknown_QueryInterface(parent, &IID_IDirect3DBaseTexture9, (void **)&texture))) 778 { 779 IDirect3DBaseTexture9_Release(texture); 780 WARN("Texture %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", texture, resource); 781 return D3DERR_INVALIDCALL; 782 } 783 784 surface = wined3d_texture_get_sub_resource_parent(wined3d_texture_from_resource(resource), 0); 785 if (!surface->resource.refcount) 786 return D3D_OK; 787 788 WARN("Surface %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface); 789 return D3DERR_INVALIDCALL; 790 } 791 792 static HRESULT d3d9_device_get_swapchains(struct d3d9_device *device) 793 { 794 UINT i, new_swapchain_count = wined3d_device_get_swapchain_count(device->wined3d_device); 795 struct wined3d_swapchain *wined3d_swapchain; 796 797 if (!(device->implicit_swapchains = HeapAlloc(GetProcessHeap(), 0, 798 new_swapchain_count * sizeof(*device->implicit_swapchains)))) 799 return E_OUTOFMEMORY; 800 801 for (i = 0; i < new_swapchain_count; ++i) 802 { 803 wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, i); 804 device->implicit_swapchains[i] = wined3d_swapchain_get_parent(wined3d_swapchain); 805 } 806 device->implicit_swapchain_count = new_swapchain_count; 807 808 return D3D_OK; 809 } 810 811 static HRESULT d3d9_device_reset(struct d3d9_device *device, 812 D3DPRESENT_PARAMETERS *present_parameters, D3DDISPLAYMODEEX *mode) 813 { 814 BOOL extended = device->d3d_parent->extended; 815 struct wined3d_swapchain_desc swapchain_desc; 816 struct wined3d_display_mode wined3d_mode; 817 HRESULT hr; 818 819 820 if (!extended && device->device_state == D3D9_DEVICE_STATE_LOST) 821 { 822 WARN("App not active, returning D3DERR_DEVICELOST.\n"); 823 return D3DERR_DEVICELOST; 824 } 825 826 if (mode) 827 { 828 wined3d_mode.width = mode->Width; 829 wined3d_mode.height = mode->Height; 830 wined3d_mode.refresh_rate = mode->RefreshRate; 831 wined3d_mode.format_id = wined3dformat_from_d3dformat(mode->Format); 832 wined3d_mode.scanline_ordering = mode->ScanLineOrdering; 833 } 834 835 if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters, extended)) 836 return D3DERR_INVALIDCALL; 837 838 wined3d_mutex_lock(); 839 840 if (device->vertex_buffer) 841 { 842 wined3d_buffer_decref(device->vertex_buffer); 843 device->vertex_buffer = NULL; 844 device->vertex_buffer_size = 0; 845 } 846 847 if (device->index_buffer) 848 { 849 wined3d_buffer_decref(device->index_buffer); 850 device->index_buffer = NULL; 851 device->index_buffer_size = 0; 852 } 853 854 if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc, 855 mode ? &wined3d_mode : NULL, reset_enum_callback, !extended))) 856 { 857 HeapFree(GetProcessHeap(), 0, device->implicit_swapchains); 858 859 if (!extended) 860 { 861 wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, 862 !!swapchain_desc.enable_auto_depth_stencil); 863 } 864 865 if (FAILED(hr = d3d9_device_get_swapchains(device))) 866 { 867 device->device_state = D3D9_DEVICE_STATE_NOT_RESET; 868 } 869 else 870 { 871 wined3d_swapchain_get_desc(device->implicit_swapchains[0]->wined3d_swapchain, &swapchain_desc); 872 present_parameters->BackBufferWidth = swapchain_desc.backbuffer_width; 873 present_parameters->BackBufferHeight = swapchain_desc.backbuffer_height; 874 present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc.backbuffer_format); 875 present_parameters->BackBufferCount = swapchain_desc.backbuffer_count; 876 877 device->device_state = D3D9_DEVICE_STATE_OK; 878 } 879 } 880 else if (!extended) 881 { 882 device->device_state = D3D9_DEVICE_STATE_NOT_RESET; 883 } 884 885 wined3d_mutex_unlock(); 886 887 return hr; 888 } 889 890 static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Reset(IDirect3DDevice9Ex *iface, 891 D3DPRESENT_PARAMETERS *present_parameters) 892 { 893 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 894 895 TRACE("iface %p, present_parameters %p.\n", iface, present_parameters); 896 897 return d3d9_device_reset(device, present_parameters, NULL); 898 } 899 900 static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex *iface, 901 const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region) 902 { 903 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 904 UINT i; 905 HRESULT hr; 906 907 TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n", 908 iface, src_rect, dst_rect, dst_window_override, dirty_region); 909 910 if (device->device_state != D3D9_DEVICE_STATE_OK) 911 return device->d3d_parent->extended ? S_PRESENT_OCCLUDED : D3DERR_DEVICELOST; 912 913 if (dirty_region) 914 FIXME("Ignoring dirty_region %p.\n", dirty_region); 915 916 wined3d_mutex_lock(); 917 for (i = 0; i < device->implicit_swapchain_count; ++i) 918 { 919 if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, 920 src_rect, dst_rect, dst_window_override, 0))) 921 { 922 wined3d_mutex_unlock(); 923 return hr; 924 } 925 } 926 wined3d_mutex_unlock(); 927 928 return D3D_OK; 929 } 930 931 static HRESULT WINAPI d3d9_device_GetBackBuffer(IDirect3DDevice9Ex *iface, UINT swapchain, 932 UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer) 933 { 934 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 935 HRESULT hr; 936 937 TRACE("iface %p, swapchain %u, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n", 938 iface, swapchain, backbuffer_idx, backbuffer_type, backbuffer); 939 940 /* backbuffer_type is ignored by native. */ 941 942 /* No need to check for backbuffer == NULL, Windows crashes in that case. */ 943 *backbuffer = NULL; 944 945 wined3d_mutex_lock(); 946 if (swapchain >= device->implicit_swapchain_count) 947 { 948 wined3d_mutex_unlock(); 949 WARN("Swapchain index %u is out of range, returning D3DERR_INVALIDCALL.\n", swapchain); 950 return D3DERR_INVALIDCALL; 951 } 952 953 hr = IDirect3DSwapChain9Ex_GetBackBuffer(&device->implicit_swapchains[swapchain]->IDirect3DSwapChain9Ex_iface, 954 backbuffer_idx, backbuffer_type, backbuffer); 955 wined3d_mutex_unlock(); 956 957 return hr; 958 } 959 960 static HRESULT WINAPI d3d9_device_GetRasterStatus(IDirect3DDevice9Ex *iface, 961 UINT swapchain, D3DRASTER_STATUS *raster_status) 962 { 963 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 964 HRESULT hr; 965 966 TRACE("iface %p, swapchain %u, raster_status %p.\n", iface, swapchain, raster_status); 967 968 wined3d_mutex_lock(); 969 hr = wined3d_device_get_raster_status(device->wined3d_device, 970 swapchain, (struct wined3d_raster_status *)raster_status); 971 wined3d_mutex_unlock(); 972 973 return hr; 974 } 975 976 static HRESULT WINAPI d3d9_device_SetDialogBoxMode(IDirect3DDevice9Ex *iface, BOOL enable) 977 { 978 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 979 HRESULT hr; 980 981 TRACE("iface %p, enable %#x.\n", iface, enable); 982 983 wined3d_mutex_lock(); 984 hr = wined3d_device_set_dialog_box_mode(device->wined3d_device, enable); 985 wined3d_mutex_unlock(); 986 987 return hr; 988 } 989 990 static void WINAPI d3d9_device_SetGammaRamp(IDirect3DDevice9Ex *iface, 991 UINT swapchain, DWORD flags, const D3DGAMMARAMP *ramp) 992 { 993 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 994 995 TRACE("iface %p, swapchain %u, flags %#x, ramp %p.\n", iface, swapchain, flags, ramp); 996 997 /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */ 998 wined3d_mutex_lock(); 999 wined3d_device_set_gamma_ramp(device->wined3d_device, swapchain, flags, (const struct wined3d_gamma_ramp *)ramp); 1000 wined3d_mutex_unlock(); 1001 } 1002 1003 static void WINAPI d3d9_device_GetGammaRamp(IDirect3DDevice9Ex *iface, UINT swapchain, D3DGAMMARAMP *ramp) 1004 { 1005 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1006 1007 TRACE("iface %p, swapchain %u, ramp %p.\n", iface, swapchain, ramp); 1008 1009 /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */ 1010 wined3d_mutex_lock(); 1011 wined3d_device_get_gamma_ramp(device->wined3d_device, swapchain, (struct wined3d_gamma_ramp *)ramp); 1012 wined3d_mutex_unlock(); 1013 } 1014 1015 static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface, 1016 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, 1017 D3DPOOL pool, IDirect3DTexture9 **texture, HANDLE *shared_handle) 1018 { 1019 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1020 struct d3d9_texture *object; 1021 BOOL set_mem = FALSE; 1022 HRESULT hr; 1023 1024 TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n", 1025 iface, width, height, levels, usage, format, pool, texture, shared_handle); 1026 1027 *texture = NULL; 1028 if (shared_handle) 1029 { 1030 if (!device->d3d_parent->extended) 1031 { 1032 WARN("Trying to create a shared or user memory texture on a non-ex device.\n"); 1033 return E_NOTIMPL; 1034 } 1035 1036 if (pool == D3DPOOL_SYSTEMMEM) 1037 { 1038 if (levels != 1) 1039 return D3DERR_INVALIDCALL; 1040 set_mem = TRUE; 1041 } 1042 else 1043 { 1044 if (pool != D3DPOOL_DEFAULT) 1045 { 1046 WARN("Trying to create a shared texture in pool %#x.\n", pool); 1047 return D3DERR_INVALIDCALL; 1048 } 1049 FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); 1050 } 1051 } 1052 1053 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 1054 if (!object) 1055 return D3DERR_OUTOFVIDEOMEMORY; 1056 1057 hr = texture_init(object, device, width, height, levels, usage, format, pool); 1058 if (FAILED(hr)) 1059 { 1060 WARN("Failed to initialize texture, hr %#x.\n", hr); 1061 HeapFree(GetProcessHeap(), 0, object); 1062 return hr; 1063 } 1064 1065 if (set_mem) 1066 wined3d_texture_update_desc(object->wined3d_texture, width, height, 1067 wined3dformat_from_d3dformat(format), WINED3D_MULTISAMPLE_NONE, 0, 1068 *shared_handle, 0); 1069 1070 TRACE("Created texture %p.\n", object); 1071 *texture = (IDirect3DTexture9 *)&object->IDirect3DBaseTexture9_iface; 1072 1073 return D3D_OK; 1074 } 1075 1076 static HRESULT WINAPI d3d9_device_CreateVolumeTexture(IDirect3DDevice9Ex *iface, 1077 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, 1078 D3DPOOL pool, IDirect3DVolumeTexture9 **texture, HANDLE *shared_handle) 1079 { 1080 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1081 struct d3d9_texture *object; 1082 HRESULT hr; 1083 1084 TRACE("iface %p, width %u, height %u, depth %u, levels %u, " 1085 "usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n", 1086 iface, width, height, depth, levels, 1087 usage, format, pool, texture, shared_handle); 1088 1089 *texture = NULL; 1090 if (shared_handle) 1091 { 1092 if (!device->d3d_parent->extended) 1093 { 1094 WARN("Trying to create a shared volume texture on a non-ex device.\n"); 1095 return E_NOTIMPL; 1096 } 1097 1098 if (pool != D3DPOOL_DEFAULT) 1099 { 1100 WARN("Trying to create a shared volume texture in pool %#x.\n", pool); 1101 return D3DERR_INVALIDCALL; 1102 } 1103 FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); 1104 } 1105 1106 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 1107 if (!object) 1108 return D3DERR_OUTOFVIDEOMEMORY; 1109 1110 hr = volumetexture_init(object, device, width, height, depth, levels, usage, format, pool); 1111 if (FAILED(hr)) 1112 { 1113 WARN("Failed to initialize volume texture, hr %#x.\n", hr); 1114 HeapFree(GetProcessHeap(), 0, object); 1115 return hr; 1116 } 1117 1118 TRACE("Created volume texture %p.\n", object); 1119 *texture = (IDirect3DVolumeTexture9 *)&object->IDirect3DBaseTexture9_iface; 1120 1121 return D3D_OK; 1122 } 1123 1124 static HRESULT WINAPI d3d9_device_CreateCubeTexture(IDirect3DDevice9Ex *iface, 1125 UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, 1126 IDirect3DCubeTexture9 **texture, HANDLE *shared_handle) 1127 { 1128 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1129 struct d3d9_texture *object; 1130 HRESULT hr; 1131 1132 TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n", 1133 iface, edge_length, levels, usage, format, pool, texture, shared_handle); 1134 1135 *texture = NULL; 1136 if (shared_handle) 1137 { 1138 if (!device->d3d_parent->extended) 1139 { 1140 WARN("Trying to create a shared cube texture on a non-ex device.\n"); 1141 return E_NOTIMPL; 1142 } 1143 1144 if (pool != D3DPOOL_DEFAULT) 1145 { 1146 WARN("Trying to create a shared cube texture in pool %#x.\n", pool); 1147 return D3DERR_INVALIDCALL; 1148 } 1149 FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); 1150 } 1151 1152 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 1153 if (!object) 1154 return D3DERR_OUTOFVIDEOMEMORY; 1155 1156 hr = cubetexture_init(object, device, edge_length, levels, usage, format, pool); 1157 if (FAILED(hr)) 1158 { 1159 WARN("Failed to initialize cube texture, hr %#x.\n", hr); 1160 HeapFree(GetProcessHeap(), 0, object); 1161 return hr; 1162 } 1163 1164 TRACE("Created cube texture %p.\n", object); 1165 *texture = (IDirect3DCubeTexture9 *)&object->IDirect3DBaseTexture9_iface; 1166 1167 return D3D_OK; 1168 } 1169 1170 static HRESULT WINAPI d3d9_device_CreateVertexBuffer(IDirect3DDevice9Ex *iface, UINT size, 1171 DWORD usage, DWORD fvf, D3DPOOL pool, IDirect3DVertexBuffer9 **buffer, 1172 HANDLE *shared_handle) 1173 { 1174 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1175 struct d3d9_vertexbuffer *object; 1176 HRESULT hr; 1177 1178 TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p, shared_handle %p.\n", 1179 iface, size, usage, fvf, pool, buffer, shared_handle); 1180 1181 if (shared_handle) 1182 { 1183 if (!device->d3d_parent->extended) 1184 { 1185 WARN("Trying to create a shared vertex buffer on a non-ex device.\n"); 1186 return E_NOTIMPL; 1187 } 1188 1189 if (pool != D3DPOOL_DEFAULT) 1190 { 1191 WARN("Trying to create a shared vertex buffer in pool %#x.\n", pool); 1192 return D3DERR_NOTAVAILABLE; 1193 } 1194 FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); 1195 } 1196 1197 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 1198 if (!object) 1199 return D3DERR_OUTOFVIDEOMEMORY; 1200 1201 hr = vertexbuffer_init(object, device, size, usage, fvf, pool); 1202 if (FAILED(hr)) 1203 { 1204 WARN("Failed to initialize vertex buffer, hr %#x.\n", hr); 1205 HeapFree(GetProcessHeap(), 0, object); 1206 return hr; 1207 } 1208 1209 TRACE("Created vertex buffer %p.\n", object); 1210 *buffer = &object->IDirect3DVertexBuffer9_iface; 1211 1212 return D3D_OK; 1213 } 1214 1215 static HRESULT WINAPI d3d9_device_CreateIndexBuffer(IDirect3DDevice9Ex *iface, UINT size, 1216 DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **buffer, 1217 HANDLE *shared_handle) 1218 { 1219 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1220 struct d3d9_indexbuffer *object; 1221 HRESULT hr; 1222 1223 TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p, shared_handle %p.\n", 1224 iface, size, usage, format, pool, buffer, shared_handle); 1225 1226 if (shared_handle) 1227 { 1228 if (!device->d3d_parent->extended) 1229 { 1230 WARN("Trying to create a shared index buffer on a non-ex device.\n"); 1231 return E_NOTIMPL; 1232 } 1233 1234 if (pool != D3DPOOL_DEFAULT) 1235 { 1236 WARN("Trying to create a shared index buffer in pool %#x.\n", pool); 1237 return D3DERR_NOTAVAILABLE; 1238 } 1239 FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); 1240 } 1241 1242 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 1243 if (!object) 1244 return D3DERR_OUTOFVIDEOMEMORY; 1245 1246 hr = indexbuffer_init(object, device, size, usage, format, pool); 1247 if (FAILED(hr)) 1248 { 1249 WARN("Failed to initialize index buffer, hr %#x.\n", hr); 1250 HeapFree(GetProcessHeap(), 0, object); 1251 return hr; 1252 } 1253 1254 TRACE("Created index buffer %p.\n", object); 1255 *buffer = &object->IDirect3DIndexBuffer9_iface; 1256 1257 return D3D_OK; 1258 } 1259 1260 static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width, UINT height, 1261 D3DFORMAT format, DWORD flags, IDirect3DSurface9 **surface, UINT usage, D3DPOOL pool, 1262 D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, void *user_mem) 1263 { 1264 struct wined3d_resource_desc desc; 1265 struct d3d9_surface *surface_impl; 1266 struct wined3d_texture *texture; 1267 HRESULT hr; 1268 1269 TRACE("device %p, width %u, height %u, format %#x, flags %#x, surface %p.\n" 1270 "usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n", 1271 device, width, height, format, flags, surface, usage, pool, 1272 multisample_type, multisample_quality); 1273 1274 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; 1275 desc.format = wined3dformat_from_d3dformat(format); 1276 desc.multisample_type = multisample_type; 1277 desc.multisample_quality = multisample_quality; 1278 desc.usage = usage & WINED3DUSAGE_MASK; 1279 desc.pool = pool; 1280 desc.width = width; 1281 desc.height = height; 1282 desc.depth = 1; 1283 desc.size = 0; 1284 1285 if (is_gdi_compat_wined3dformat(desc.format)) 1286 flags |= WINED3D_TEXTURE_CREATE_GET_DC; 1287 1288 wined3d_mutex_lock(); 1289 1290 if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc, 1291 1, 1, flags, NULL, NULL, &d3d9_null_wined3d_parent_ops, &texture))) 1292 { 1293 wined3d_mutex_unlock(); 1294 WARN("Failed to create texture, hr %#x.\n", hr); 1295 if (hr == WINED3DERR_NOTAVAILABLE) 1296 hr = D3DERR_INVALIDCALL; 1297 return hr; 1298 } 1299 1300 surface_impl = wined3d_texture_get_sub_resource_parent(texture, 0); 1301 surface_impl->parent_device = &device->IDirect3DDevice9Ex_iface; 1302 *surface = &surface_impl->IDirect3DSurface9_iface; 1303 IDirect3DSurface9_AddRef(*surface); 1304 1305 if (user_mem) 1306 wined3d_texture_update_desc(texture, width, height, 1307 desc.format, multisample_type, multisample_quality, user_mem, 0); 1308 1309 wined3d_texture_decref(texture); 1310 1311 wined3d_mutex_unlock(); 1312 1313 return D3D_OK; 1314 } 1315 1316 BOOL is_gdi_compat_wined3dformat(enum wined3d_format_id format) 1317 { 1318 switch (format) 1319 { 1320 case WINED3DFMT_B8G8R8A8_UNORM: 1321 case WINED3DFMT_B8G8R8X8_UNORM: 1322 case WINED3DFMT_B5G6R5_UNORM: 1323 case WINED3DFMT_B5G5R5X1_UNORM: 1324 case WINED3DFMT_B5G5R5A1_UNORM: 1325 case WINED3DFMT_B8G8R8_UNORM: 1326 return TRUE; 1327 default: 1328 return FALSE; 1329 } 1330 } 1331 1332 static HRESULT WINAPI d3d9_device_CreateRenderTarget(IDirect3DDevice9Ex *iface, UINT width, UINT height, 1333 D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, 1334 BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle) 1335 { 1336 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1337 DWORD flags = 0; 1338 1339 TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n" 1340 "lockable %#x, surface %p, shared_handle %p.\n", 1341 iface, width, height, format, multisample_type, multisample_quality, 1342 lockable, surface, shared_handle); 1343 1344 *surface = NULL; 1345 if (shared_handle) 1346 { 1347 if (!device->d3d_parent->extended) 1348 { 1349 WARN("Trying to create a shared render target on a non-ex device.\n"); 1350 return E_NOTIMPL; 1351 } 1352 1353 FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); 1354 } 1355 1356 if (lockable) 1357 flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; 1358 1359 return d3d9_device_create_surface(device, width, height, format, flags, surface, 1360 D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); 1361 } 1362 1363 static HRESULT WINAPI d3d9_device_CreateDepthStencilSurface(IDirect3DDevice9Ex *iface, UINT width, UINT height, 1364 D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, 1365 BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle) 1366 { 1367 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1368 DWORD flags = WINED3D_TEXTURE_CREATE_MAPPABLE; 1369 1370 TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n" 1371 "discard %#x, surface %p, shared_handle %p.\n", 1372 iface, width, height, format, multisample_type, multisample_quality, 1373 discard, surface, shared_handle); 1374 1375 *surface = NULL; 1376 if (shared_handle) 1377 { 1378 if (!device->d3d_parent->extended) 1379 { 1380 WARN("Trying to create a shared depth stencil on a non-ex device.\n"); 1381 return E_NOTIMPL; 1382 } 1383 1384 FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); 1385 } 1386 1387 if (discard) 1388 flags |= WINED3D_TEXTURE_CREATE_DISCARD; 1389 1390 return d3d9_device_create_surface(device, width, height, format, flags, surface, 1391 D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); 1392 } 1393 1394 1395 static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex *iface, 1396 IDirect3DSurface9 *src_surface, const RECT *src_rect, 1397 IDirect3DSurface9 *dst_surface, const POINT *dst_point) 1398 { 1399 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1400 struct d3d9_surface *src = unsafe_impl_from_IDirect3DSurface9(src_surface); 1401 struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(dst_surface); 1402 struct wined3d_sub_resource_desc src_desc, dst_desc; 1403 struct wined3d_box src_box; 1404 HRESULT hr; 1405 1406 TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_point %p.\n", 1407 iface, src_surface, src_rect, dst_surface, dst_point); 1408 1409 wined3d_mutex_lock(); 1410 1411 wined3d_texture_get_sub_resource_desc(src->wined3d_texture, src->sub_resource_idx, &src_desc); 1412 wined3d_texture_get_sub_resource_desc(dst->wined3d_texture, dst->sub_resource_idx, &dst_desc); 1413 if (src_desc.format != dst_desc.format) 1414 { 1415 wined3d_mutex_unlock(); 1416 WARN("Surface formats (%#x/%#x) don't match.\n", 1417 d3dformat_from_wined3dformat(src_desc.format), 1418 d3dformat_from_wined3dformat(dst_desc.format)); 1419 return D3DERR_INVALIDCALL; 1420 } 1421 1422 if (src_rect) 1423 wined3d_box_set(&src_box, src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1); 1424 else 1425 wined3d_box_set(&src_box, 0, 0, src_desc.width, src_desc.height, 0, 1); 1426 1427 hr = wined3d_device_copy_sub_resource_region(device->wined3d_device, 1428 wined3d_texture_get_resource(dst->wined3d_texture), dst->sub_resource_idx, dst_point ? dst_point->x : 0, 1429 dst_point ? dst_point->y : 0, 0, wined3d_texture_get_resource(src->wined3d_texture), 1430 src->sub_resource_idx, &src_box); 1431 wined3d_mutex_unlock(); 1432 1433 if (FAILED(hr)) 1434 return D3DERR_INVALIDCALL; 1435 1436 return hr; 1437 } 1438 1439 static HRESULT WINAPI d3d9_device_UpdateTexture(IDirect3DDevice9Ex *iface, 1440 IDirect3DBaseTexture9 *src_texture, IDirect3DBaseTexture9 *dst_texture) 1441 { 1442 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1443 struct d3d9_texture *src_impl, *dst_impl; 1444 HRESULT hr; 1445 1446 TRACE("iface %p, src_texture %p, dst_texture %p.\n", iface, src_texture, dst_texture); 1447 1448 src_impl = unsafe_impl_from_IDirect3DBaseTexture9(src_texture); 1449 dst_impl = unsafe_impl_from_IDirect3DBaseTexture9(dst_texture); 1450 1451 wined3d_mutex_lock(); 1452 hr = wined3d_device_update_texture(device->wined3d_device, 1453 src_impl->wined3d_texture, dst_impl->wined3d_texture); 1454 wined3d_mutex_unlock(); 1455 1456 return hr; 1457 } 1458 1459 static HRESULT WINAPI d3d9_device_GetRenderTargetData(IDirect3DDevice9Ex *iface, 1460 IDirect3DSurface9 *render_target, IDirect3DSurface9 *dst_surface) 1461 { 1462 struct d3d9_surface *rt_impl = unsafe_impl_from_IDirect3DSurface9(render_target); 1463 struct d3d9_surface *dst_impl = unsafe_impl_from_IDirect3DSurface9(dst_surface); 1464 struct wined3d_sub_resource_desc wined3d_desc; 1465 RECT dst_rect, src_rect; 1466 HRESULT hr; 1467 1468 TRACE("iface %p, render_target %p, dst_surface %p.\n", iface, render_target, dst_surface); 1469 1470 if (!render_target || !dst_surface) 1471 return D3DERR_INVALIDCALL; 1472 1473 wined3d_mutex_lock(); 1474 wined3d_texture_get_sub_resource_desc(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &wined3d_desc); 1475 SetRect(&dst_rect, 0, 0, wined3d_desc.width, wined3d_desc.height); 1476 1477 wined3d_texture_get_sub_resource_desc(rt_impl->wined3d_texture, rt_impl->sub_resource_idx, &wined3d_desc); 1478 SetRect(&src_rect, 0, 0, wined3d_desc.width, wined3d_desc.height); 1479 1480 /* TODO: Check surface sizes, pools, etc. */ 1481 if (wined3d_desc.multisample_type) 1482 hr = D3DERR_INVALIDCALL; 1483 else 1484 hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect, 1485 rt_impl->wined3d_texture, rt_impl->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT); 1486 wined3d_mutex_unlock(); 1487 1488 return hr; 1489 } 1490 1491 static HRESULT WINAPI d3d9_device_GetFrontBufferData(IDirect3DDevice9Ex *iface, 1492 UINT swapchain, IDirect3DSurface9 *dst_surface) 1493 { 1494 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1495 struct d3d9_surface *dst_impl = unsafe_impl_from_IDirect3DSurface9(dst_surface); 1496 HRESULT hr = D3DERR_INVALIDCALL; 1497 1498 TRACE("iface %p, swapchain %u, dst_surface %p.\n", iface, swapchain, dst_surface); 1499 1500 wined3d_mutex_lock(); 1501 if (swapchain < device->implicit_swapchain_count) 1502 hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchains[swapchain]->wined3d_swapchain, 1503 dst_impl->wined3d_texture, dst_impl->sub_resource_idx); 1504 wined3d_mutex_unlock(); 1505 1506 return hr; 1507 } 1508 1509 static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect3DSurface9 *src_surface, 1510 const RECT *src_rect, IDirect3DSurface9 *dst_surface, const RECT *dst_rect, D3DTEXTUREFILTERTYPE filter) 1511 { 1512 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1513 struct d3d9_surface *src = unsafe_impl_from_IDirect3DSurface9(src_surface); 1514 struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(dst_surface); 1515 struct wined3d_sub_resource_desc src_desc, dst_desc; 1516 HRESULT hr = D3DERR_INVALIDCALL; 1517 RECT d, s; 1518 1519 TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n", 1520 iface, src_surface, src_rect, dst_surface, dst_rect, filter); 1521 1522 wined3d_mutex_lock(); 1523 wined3d_texture_get_sub_resource_desc(dst->wined3d_texture, dst->sub_resource_idx, &dst_desc); 1524 if (!dst_rect) 1525 { 1526 SetRect(&d, 0, 0, dst_desc.width, dst_desc.height); 1527 dst_rect = &d; 1528 } 1529 1530 wined3d_texture_get_sub_resource_desc(src->wined3d_texture, src->sub_resource_idx, &src_desc); 1531 if (!src_rect) 1532 { 1533 SetRect(&s, 0, 0, src_desc.width, src_desc.height); 1534 src_rect = &s; 1535 } 1536 1537 if (src_desc.usage & WINED3DUSAGE_DEPTHSTENCIL) 1538 { 1539 if (device->in_scene) 1540 { 1541 WARN("Rejecting depth / stencil blit while in scene.\n"); 1542 goto done; 1543 } 1544 1545 if (src_rect->left || src_rect->top || src_rect->right != src_desc.width 1546 || src_rect->bottom != src_desc.height) 1547 { 1548 WARN("Rejecting depth / stencil blit with invalid source rect %s.\n", 1549 wine_dbgstr_rect(src_rect)); 1550 goto done; 1551 } 1552 1553 if (dst_rect->left || dst_rect->top || dst_rect->right != dst_desc.width 1554 || dst_rect->bottom != dst_desc.height) 1555 { 1556 WARN("Rejecting depth / stencil blit with invalid destination rect %s.\n", 1557 wine_dbgstr_rect(dst_rect)); 1558 goto done; 1559 } 1560 1561 if (src_desc.width != dst_desc.width || src_desc.height != dst_desc.height) 1562 { 1563 WARN("Rejecting depth / stencil blit with mismatched surface sizes.\n"); 1564 goto done; 1565 } 1566 } 1567 1568 hr = wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, dst_rect, 1569 src->wined3d_texture, src->sub_resource_idx, src_rect, 0, NULL, filter); 1570 if (hr == WINEDDERR_INVALIDRECT) 1571 hr = D3DERR_INVALIDCALL; 1572 1573 done: 1574 wined3d_mutex_unlock(); 1575 return hr; 1576 } 1577 1578 static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface, 1579 IDirect3DSurface9 *surface, const RECT *rect, D3DCOLOR color) 1580 { 1581 const struct wined3d_color c = 1582 { 1583 ((color >> 16) & 0xff) / 255.0f, 1584 ((color >> 8) & 0xff) / 255.0f, 1585 (color & 0xff) / 255.0f, 1586 ((color >> 24) & 0xff) / 255.0f, 1587 }; 1588 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1589 struct d3d9_surface *surface_impl = unsafe_impl_from_IDirect3DSurface9(surface); 1590 struct wined3d_sub_resource_desc desc; 1591 struct wined3d_rendertarget_view *rtv; 1592 HRESULT hr; 1593 1594 TRACE("iface %p, surface %p, rect %p, color 0x%08x.\n", iface, surface, rect, color); 1595 1596 wined3d_mutex_lock(); 1597 1598 if (FAILED(wined3d_texture_get_sub_resource_desc(surface_impl->wined3d_texture, 1599 surface_impl->sub_resource_idx, &desc))) 1600 { 1601 wined3d_mutex_unlock(); 1602 return D3DERR_INVALIDCALL; 1603 } 1604 1605 if (desc.pool != WINED3D_POOL_DEFAULT) 1606 { 1607 wined3d_mutex_unlock(); 1608 WARN("Colorfill is not allowed on surfaces in pool %#x, returning D3DERR_INVALIDCALL.\n", desc.pool); 1609 return D3DERR_INVALIDCALL; 1610 } 1611 if ((desc.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_TEXTURE)) == WINED3DUSAGE_TEXTURE) 1612 { 1613 wined3d_mutex_unlock(); 1614 WARN("Colorfill is not allowed on non-RT textures, returning D3DERR_INVALIDCALL.\n"); 1615 return D3DERR_INVALIDCALL; 1616 } 1617 if (desc.usage & WINED3DUSAGE_DEPTHSTENCIL) 1618 { 1619 wined3d_mutex_unlock(); 1620 WARN("Colorfill is not allowed on depth stencil surfaces, returning D3DERR_INVALIDCALL.\n"); 1621 return D3DERR_INVALIDCALL; 1622 } 1623 1624 rtv = d3d9_surface_acquire_rendertarget_view(surface_impl); 1625 hr = wined3d_device_clear_rendertarget_view(device->wined3d_device, 1626 rtv, rect, WINED3DCLEAR_TARGET, &c, 0.0f, 0); 1627 d3d9_surface_release_rendertarget_view(surface_impl, rtv); 1628 1629 wined3d_mutex_unlock(); 1630 1631 return hr; 1632 } 1633 1634 static HRESULT WINAPI d3d9_device_CreateOffscreenPlainSurface(IDirect3DDevice9Ex *iface, 1635 UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, 1636 HANDLE *shared_handle) 1637 { 1638 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1639 void *user_mem = NULL; 1640 1641 TRACE("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p.\n", 1642 iface, width, height, format, pool, surface, shared_handle); 1643 1644 *surface = NULL; 1645 if (pool == D3DPOOL_MANAGED) 1646 { 1647 WARN("Attempting to create a managed offscreen plain surface.\n"); 1648 return D3DERR_INVALIDCALL; 1649 } 1650 1651 if (shared_handle) 1652 { 1653 if (!device->d3d_parent->extended) 1654 { 1655 WARN("Trying to create a shared or user memory surface on a non-ex device.\n"); 1656 return E_NOTIMPL; 1657 } 1658 1659 if (pool == D3DPOOL_SYSTEMMEM) 1660 user_mem = *shared_handle; 1661 else 1662 { 1663 if (pool != D3DPOOL_DEFAULT) 1664 { 1665 WARN("Trying to create a shared surface in pool %#x.\n", pool); 1666 return D3DERR_INVALIDCALL; 1667 } 1668 FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); 1669 } 1670 } 1671 1672 /* FIXME: Offscreen surfaces are supposed to be always lockable, 1673 * regardless of the pool they're created in. Should we set dynamic usage 1674 * here? */ 1675 return d3d9_device_create_surface(device, width, height, format, 1676 WINED3D_TEXTURE_CREATE_MAPPABLE, surface, 0, pool, D3DMULTISAMPLE_NONE, 0, user_mem); 1677 } 1678 1679 static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWORD idx, IDirect3DSurface9 *surface) 1680 { 1681 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1682 struct d3d9_surface *surface_impl = unsafe_impl_from_IDirect3DSurface9(surface); 1683 struct wined3d_rendertarget_view *rtv; 1684 HRESULT hr; 1685 1686 TRACE("iface %p, idx %u, surface %p.\n", iface, idx, surface); 1687 1688 if (idx >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS) 1689 { 1690 WARN("Invalid index %u specified.\n", idx); 1691 return D3DERR_INVALIDCALL; 1692 } 1693 1694 if (!idx && !surface_impl) 1695 { 1696 WARN("Trying to set render target 0 to NULL.\n"); 1697 return D3DERR_INVALIDCALL; 1698 } 1699 1700 if (surface_impl && d3d9_surface_get_device(surface_impl) != device) 1701 { 1702 WARN("Render target surface does not match device.\n"); 1703 return D3DERR_INVALIDCALL; 1704 } 1705 1706 wined3d_mutex_lock(); 1707 rtv = surface_impl ? d3d9_surface_acquire_rendertarget_view(surface_impl) : NULL; 1708 hr = wined3d_device_set_rendertarget_view(device->wined3d_device, idx, rtv, TRUE); 1709 d3d9_surface_release_rendertarget_view(surface_impl, rtv); 1710 wined3d_mutex_unlock(); 1711 1712 return hr; 1713 } 1714 1715 static HRESULT WINAPI d3d9_device_GetRenderTarget(IDirect3DDevice9Ex *iface, DWORD idx, IDirect3DSurface9 **surface) 1716 { 1717 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1718 struct wined3d_rendertarget_view *wined3d_rtv; 1719 struct d3d9_surface *surface_impl; 1720 HRESULT hr = D3D_OK; 1721 1722 TRACE("iface %p, idx %u, surface %p.\n", iface, idx, surface); 1723 1724 if (!surface) 1725 return D3DERR_INVALIDCALL; 1726 1727 if (idx >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS) 1728 { 1729 WARN("Invalid index %u specified.\n", idx); 1730 return D3DERR_INVALIDCALL; 1731 } 1732 1733 wined3d_mutex_lock(); 1734 if ((wined3d_rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, idx))) 1735 { 1736 /* We want the sub resource parent here, since the view itself may be 1737 * internal to wined3d and may not have a parent. */ 1738 surface_impl = wined3d_rendertarget_view_get_sub_resource_parent(wined3d_rtv); 1739 *surface = &surface_impl->IDirect3DSurface9_iface; 1740 IDirect3DSurface9_AddRef(*surface); 1741 } 1742 else 1743 { 1744 hr = D3DERR_NOTFOUND; 1745 *surface = NULL; 1746 } 1747 wined3d_mutex_unlock(); 1748 1749 return hr; 1750 } 1751 1752 static HRESULT WINAPI d3d9_device_SetDepthStencilSurface(IDirect3DDevice9Ex *iface, IDirect3DSurface9 *depth_stencil) 1753 { 1754 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1755 struct d3d9_surface *ds_impl = unsafe_impl_from_IDirect3DSurface9(depth_stencil); 1756 struct wined3d_rendertarget_view *rtv; 1757 1758 TRACE("iface %p, depth_stencil %p.\n", iface, depth_stencil); 1759 1760 wined3d_mutex_lock(); 1761 rtv = ds_impl ? d3d9_surface_acquire_rendertarget_view(ds_impl) : NULL; 1762 wined3d_device_set_depth_stencil_view(device->wined3d_device, rtv); 1763 d3d9_surface_release_rendertarget_view(ds_impl, rtv); 1764 wined3d_mutex_unlock(); 1765 1766 return D3D_OK; 1767 } 1768 1769 static HRESULT WINAPI d3d9_device_GetDepthStencilSurface(IDirect3DDevice9Ex *iface, IDirect3DSurface9 **depth_stencil) 1770 { 1771 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1772 struct wined3d_rendertarget_view *wined3d_dsv; 1773 struct d3d9_surface *surface_impl; 1774 HRESULT hr = D3D_OK; 1775 1776 TRACE("iface %p, depth_stencil %p.\n", iface, depth_stencil); 1777 1778 if (!depth_stencil) 1779 return D3DERR_INVALIDCALL; 1780 1781 wined3d_mutex_lock(); 1782 if ((wined3d_dsv = wined3d_device_get_depth_stencil_view(device->wined3d_device))) 1783 { 1784 /* We want the sub resource parent here, since the view itself may be 1785 * internal to wined3d and may not have a parent. */ 1786 surface_impl = wined3d_rendertarget_view_get_sub_resource_parent(wined3d_dsv); 1787 *depth_stencil = &surface_impl->IDirect3DSurface9_iface; 1788 IDirect3DSurface9_AddRef(*depth_stencil); 1789 } 1790 else 1791 { 1792 hr = D3DERR_NOTFOUND; 1793 *depth_stencil = NULL; 1794 } 1795 wined3d_mutex_unlock(); 1796 1797 return hr; 1798 } 1799 1800 static HRESULT WINAPI d3d9_device_BeginScene(IDirect3DDevice9Ex *iface) 1801 { 1802 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1803 HRESULT hr; 1804 1805 TRACE("iface %p.\n", iface); 1806 1807 wined3d_mutex_lock(); 1808 if (SUCCEEDED(hr = wined3d_device_begin_scene(device->wined3d_device))) 1809 device->in_scene = TRUE; 1810 wined3d_mutex_unlock(); 1811 1812 return hr; 1813 } 1814 1815 static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_EndScene(IDirect3DDevice9Ex *iface) 1816 { 1817 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1818 HRESULT hr; 1819 1820 TRACE("iface %p.\n", iface); 1821 1822 wined3d_mutex_lock(); 1823 if (SUCCEEDED(hr = wined3d_device_end_scene(device->wined3d_device))) 1824 device->in_scene = FALSE; 1825 wined3d_mutex_unlock(); 1826 1827 return hr; 1828 } 1829 1830 static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_count, 1831 const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil) 1832 { 1833 const struct wined3d_color c = 1834 { 1835 ((color >> 16) & 0xff) / 255.0f, 1836 ((color >> 8) & 0xff) / 255.0f, 1837 (color & 0xff) / 255.0f, 1838 ((color >> 24) & 0xff) / 255.0f, 1839 }; 1840 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1841 HRESULT hr; 1842 1843 TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n", 1844 iface, rect_count, rects, flags, color, z, stencil); 1845 1846 if (rect_count && !rects) 1847 { 1848 WARN("count %u with NULL rects.\n", rect_count); 1849 rect_count = 0; 1850 } 1851 1852 wined3d_mutex_lock(); 1853 hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil); 1854 wined3d_mutex_unlock(); 1855 1856 return hr; 1857 } 1858 1859 static HRESULT WINAPI d3d9_device_SetTransform(IDirect3DDevice9Ex *iface, 1860 D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix) 1861 { 1862 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1863 1864 TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); 1865 1866 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */ 1867 wined3d_mutex_lock(); 1868 wined3d_device_set_transform(device->wined3d_device, state, (const struct wined3d_matrix *)matrix); 1869 wined3d_mutex_unlock(); 1870 1871 return D3D_OK; 1872 } 1873 1874 static HRESULT WINAPI d3d9_device_GetTransform(IDirect3DDevice9Ex *iface, 1875 D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix) 1876 { 1877 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1878 1879 TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); 1880 1881 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */ 1882 wined3d_mutex_lock(); 1883 wined3d_device_get_transform(device->wined3d_device, state, (struct wined3d_matrix *)matrix); 1884 wined3d_mutex_unlock(); 1885 1886 return D3D_OK; 1887 } 1888 1889 static HRESULT WINAPI d3d9_device_MultiplyTransform(IDirect3DDevice9Ex *iface, 1890 D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix) 1891 { 1892 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1893 1894 TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); 1895 1896 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */ 1897 wined3d_mutex_lock(); 1898 wined3d_device_multiply_transform(device->wined3d_device, state, (const struct wined3d_matrix *)matrix); 1899 wined3d_mutex_unlock(); 1900 1901 return D3D_OK; 1902 } 1903 1904 static HRESULT WINAPI d3d9_device_SetViewport(IDirect3DDevice9Ex *iface, const D3DVIEWPORT9 *viewport) 1905 { 1906 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1907 struct wined3d_viewport vp; 1908 1909 TRACE("iface %p, viewport %p.\n", iface, viewport); 1910 1911 vp.x = viewport->X; 1912 vp.y = viewport->Y; 1913 vp.width = viewport->Width; 1914 vp.height = viewport->Height; 1915 vp.min_z = viewport->MinZ; 1916 vp.max_z = viewport->MaxZ; 1917 1918 wined3d_mutex_lock(); 1919 wined3d_device_set_viewport(device->wined3d_device, &vp); 1920 wined3d_mutex_unlock(); 1921 1922 return D3D_OK; 1923 } 1924 1925 static HRESULT WINAPI d3d9_device_GetViewport(IDirect3DDevice9Ex *iface, D3DVIEWPORT9 *viewport) 1926 { 1927 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1928 struct wined3d_viewport wined3d_viewport; 1929 1930 TRACE("iface %p, viewport %p.\n", iface, viewport); 1931 1932 wined3d_mutex_lock(); 1933 wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport); 1934 wined3d_mutex_unlock(); 1935 1936 viewport->X = wined3d_viewport.x; 1937 viewport->Y = wined3d_viewport.y; 1938 viewport->Width = wined3d_viewport.width; 1939 viewport->Height = wined3d_viewport.height; 1940 viewport->MinZ = wined3d_viewport.min_z; 1941 viewport->MaxZ = wined3d_viewport.max_z; 1942 1943 return D3D_OK; 1944 } 1945 1946 static HRESULT WINAPI d3d9_device_SetMaterial(IDirect3DDevice9Ex *iface, const D3DMATERIAL9 *material) 1947 { 1948 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1949 1950 TRACE("iface %p, material %p.\n", iface, material); 1951 1952 /* Note: D3DMATERIAL9 is compatible with struct wined3d_material. */ 1953 wined3d_mutex_lock(); 1954 wined3d_device_set_material(device->wined3d_device, (const struct wined3d_material *)material); 1955 wined3d_mutex_unlock(); 1956 1957 return D3D_OK; 1958 } 1959 1960 static HRESULT WINAPI d3d9_device_GetMaterial(IDirect3DDevice9Ex *iface, D3DMATERIAL9 *material) 1961 { 1962 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1963 1964 TRACE("iface %p, material %p.\n", iface, material); 1965 1966 /* Note: D3DMATERIAL9 is compatible with struct wined3d_material. */ 1967 wined3d_mutex_lock(); 1968 wined3d_device_get_material(device->wined3d_device, (struct wined3d_material *)material); 1969 wined3d_mutex_unlock(); 1970 1971 return D3D_OK; 1972 } 1973 1974 static HRESULT WINAPI d3d9_device_SetLight(IDirect3DDevice9Ex *iface, DWORD index, const D3DLIGHT9 *light) 1975 { 1976 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1977 HRESULT hr; 1978 1979 TRACE("iface %p, index %u, light %p.\n", iface, index, light); 1980 1981 /* Note: D3DLIGHT9 is compatible with struct wined3d_light. */ 1982 wined3d_mutex_lock(); 1983 hr = wined3d_device_set_light(device->wined3d_device, index, (const struct wined3d_light *)light); 1984 wined3d_mutex_unlock(); 1985 1986 return hr; 1987 } 1988 1989 static HRESULT WINAPI d3d9_device_GetLight(IDirect3DDevice9Ex *iface, DWORD index, D3DLIGHT9 *light) 1990 { 1991 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 1992 HRESULT hr; 1993 1994 TRACE("iface %p, index %u, light %p.\n", iface, index, light); 1995 1996 /* Note: D3DLIGHT9 is compatible with struct wined3d_light. */ 1997 wined3d_mutex_lock(); 1998 hr = wined3d_device_get_light(device->wined3d_device, index, (struct wined3d_light *)light); 1999 wined3d_mutex_unlock(); 2000 2001 return hr; 2002 } 2003 2004 static HRESULT WINAPI d3d9_device_LightEnable(IDirect3DDevice9Ex *iface, DWORD index, BOOL enable) 2005 { 2006 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2007 HRESULT hr; 2008 2009 TRACE("iface %p, index %u, enable %#x.\n", iface, index, enable); 2010 2011 wined3d_mutex_lock(); 2012 hr = wined3d_device_set_light_enable(device->wined3d_device, index, enable); 2013 wined3d_mutex_unlock(); 2014 2015 return hr; 2016 } 2017 2018 static HRESULT WINAPI d3d9_device_GetLightEnable(IDirect3DDevice9Ex *iface, DWORD index, BOOL *enable) 2019 { 2020 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2021 HRESULT hr; 2022 2023 TRACE("iface %p, index %u, enable %p.\n", iface, index, enable); 2024 2025 wined3d_mutex_lock(); 2026 hr = wined3d_device_get_light_enable(device->wined3d_device, index, enable); 2027 wined3d_mutex_unlock(); 2028 2029 return hr; 2030 } 2031 2032 static HRESULT WINAPI d3d9_device_SetClipPlane(IDirect3DDevice9Ex *iface, DWORD index, const float *plane) 2033 { 2034 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2035 HRESULT hr; 2036 2037 TRACE("iface %p, index %u, plane %p.\n", iface, index, plane); 2038 2039 index = min(index, device->max_user_clip_planes - 1); 2040 2041 wined3d_mutex_lock(); 2042 hr = wined3d_device_set_clip_plane(device->wined3d_device, index, (const struct wined3d_vec4 *)plane); 2043 wined3d_mutex_unlock(); 2044 2045 return hr; 2046 } 2047 2048 static HRESULT WINAPI d3d9_device_GetClipPlane(IDirect3DDevice9Ex *iface, DWORD index, float *plane) 2049 { 2050 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2051 HRESULT hr; 2052 2053 TRACE("iface %p, index %u, plane %p.\n", iface, index, plane); 2054 2055 index = min(index, device->max_user_clip_planes - 1); 2056 2057 wined3d_mutex_lock(); 2058 hr = wined3d_device_get_clip_plane(device->wined3d_device, index, (struct wined3d_vec4 *)plane); 2059 wined3d_mutex_unlock(); 2060 2061 return hr; 2062 } 2063 2064 static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_SetRenderState(IDirect3DDevice9Ex *iface, 2065 D3DRENDERSTATETYPE state, DWORD value) 2066 { 2067 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2068 2069 TRACE("iface %p, state %#x, value %#x.\n", iface, state, value); 2070 2071 wined3d_mutex_lock(); 2072 wined3d_device_set_render_state(device->wined3d_device, state, value); 2073 wined3d_mutex_unlock(); 2074 2075 return D3D_OK; 2076 } 2077 2078 static HRESULT WINAPI d3d9_device_GetRenderState(IDirect3DDevice9Ex *iface, 2079 D3DRENDERSTATETYPE state, DWORD *value) 2080 { 2081 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2082 2083 TRACE("iface %p, state %#x, value %p.\n", iface, state, value); 2084 2085 wined3d_mutex_lock(); 2086 *value = wined3d_device_get_render_state(device->wined3d_device, state); 2087 wined3d_mutex_unlock(); 2088 2089 return D3D_OK; 2090 } 2091 2092 static HRESULT WINAPI d3d9_device_CreateStateBlock(IDirect3DDevice9Ex *iface, 2093 D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateblock) 2094 { 2095 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2096 struct d3d9_stateblock *object; 2097 HRESULT hr; 2098 2099 TRACE("iface %p, type %#x, stateblock %p.\n", iface, type, stateblock); 2100 2101 if (type != D3DSBT_ALL && type != D3DSBT_PIXELSTATE && type != D3DSBT_VERTEXSTATE) 2102 { 2103 WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL.\n"); 2104 return D3DERR_INVALIDCALL; 2105 } 2106 2107 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 2108 if (!object) 2109 return E_OUTOFMEMORY; 2110 2111 hr = stateblock_init(object, device, type, NULL); 2112 if (FAILED(hr)) 2113 { 2114 WARN("Failed to initialize stateblock, hr %#x.\n", hr); 2115 HeapFree(GetProcessHeap(), 0, object); 2116 return hr; 2117 } 2118 2119 TRACE("Created stateblock %p.\n", object); 2120 *stateblock = &object->IDirect3DStateBlock9_iface; 2121 2122 return D3D_OK; 2123 } 2124 2125 static HRESULT WINAPI d3d9_device_BeginStateBlock(IDirect3DDevice9Ex *iface) 2126 { 2127 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2128 HRESULT hr; 2129 2130 TRACE("iface %p.\n", iface); 2131 2132 wined3d_mutex_lock(); 2133 hr = wined3d_device_begin_stateblock(device->wined3d_device); 2134 wined3d_mutex_unlock(); 2135 2136 return hr; 2137 } 2138 2139 static HRESULT WINAPI d3d9_device_EndStateBlock(IDirect3DDevice9Ex *iface, IDirect3DStateBlock9 **stateblock) 2140 { 2141 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2142 struct wined3d_stateblock *wined3d_stateblock; 2143 struct d3d9_stateblock *object; 2144 HRESULT hr; 2145 2146 TRACE("iface %p, stateblock %p.\n", iface, stateblock); 2147 2148 wined3d_mutex_lock(); 2149 hr = wined3d_device_end_stateblock(device->wined3d_device, &wined3d_stateblock); 2150 wined3d_mutex_unlock(); 2151 if (FAILED(hr)) 2152 { 2153 WARN("Failed to end the state block, hr %#x.\n", hr); 2154 return hr; 2155 } 2156 2157 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 2158 if (!object) 2159 { 2160 wined3d_mutex_lock(); 2161 wined3d_stateblock_decref(wined3d_stateblock); 2162 wined3d_mutex_unlock(); 2163 return E_OUTOFMEMORY; 2164 } 2165 2166 hr = stateblock_init(object, device, 0, wined3d_stateblock); 2167 if (FAILED(hr)) 2168 { 2169 WARN("Failed to initialize stateblock, hr %#x.\n", hr); 2170 wined3d_mutex_lock(); 2171 wined3d_stateblock_decref(wined3d_stateblock); 2172 wined3d_mutex_unlock(); 2173 HeapFree(GetProcessHeap(), 0, object); 2174 return hr; 2175 } 2176 2177 TRACE("Created stateblock %p.\n", object); 2178 *stateblock = &object->IDirect3DStateBlock9_iface; 2179 2180 return D3D_OK; 2181 } 2182 2183 static HRESULT WINAPI d3d9_device_SetClipStatus(IDirect3DDevice9Ex *iface, const D3DCLIPSTATUS9 *clip_status) 2184 { 2185 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2186 HRESULT hr; 2187 2188 TRACE("iface %p, clip_status %p.\n", iface, clip_status); 2189 2190 wined3d_mutex_lock(); 2191 hr = wined3d_device_set_clip_status(device->wined3d_device, (const struct wined3d_clip_status *)clip_status); 2192 wined3d_mutex_unlock(); 2193 2194 return hr; 2195 } 2196 2197 static HRESULT WINAPI d3d9_device_GetClipStatus(IDirect3DDevice9Ex *iface, D3DCLIPSTATUS9 *clip_status) 2198 { 2199 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2200 HRESULT hr; 2201 2202 TRACE("iface %p, clip_status %p.\n", iface, clip_status); 2203 2204 wined3d_mutex_lock(); 2205 hr = wined3d_device_get_clip_status(device->wined3d_device, (struct wined3d_clip_status *)clip_status); 2206 wined3d_mutex_unlock(); 2207 2208 return hr; 2209 } 2210 2211 static HRESULT WINAPI d3d9_device_GetTexture(IDirect3DDevice9Ex *iface, DWORD stage, IDirect3DBaseTexture9 **texture) 2212 { 2213 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2214 struct wined3d_texture *wined3d_texture = NULL; 2215 struct d3d9_texture *texture_impl; 2216 2217 TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); 2218 2219 if (!texture) 2220 return D3DERR_INVALIDCALL; 2221 2222 wined3d_mutex_lock(); 2223 if ((wined3d_texture = wined3d_device_get_texture(device->wined3d_device, stage))) 2224 { 2225 texture_impl = wined3d_texture_get_parent(wined3d_texture); 2226 *texture = &texture_impl->IDirect3DBaseTexture9_iface; 2227 IDirect3DBaseTexture9_AddRef(*texture); 2228 } 2229 else 2230 { 2231 *texture = NULL; 2232 } 2233 wined3d_mutex_unlock(); 2234 2235 return D3D_OK; 2236 } 2237 2238 static HRESULT WINAPI d3d9_device_SetTexture(IDirect3DDevice9Ex *iface, DWORD stage, IDirect3DBaseTexture9 *texture) 2239 { 2240 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2241 struct d3d9_texture *texture_impl; 2242 HRESULT hr; 2243 2244 TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); 2245 2246 texture_impl = unsafe_impl_from_IDirect3DBaseTexture9(texture); 2247 2248 wined3d_mutex_lock(); 2249 hr = wined3d_device_set_texture(device->wined3d_device, stage, 2250 texture_impl ? texture_impl->wined3d_texture : NULL); 2251 wined3d_mutex_unlock(); 2252 2253 return hr; 2254 } 2255 2256 static const enum wined3d_texture_stage_state tss_lookup[] = 2257 { 2258 WINED3D_TSS_INVALID, /* 0, unused */ 2259 WINED3D_TSS_COLOR_OP, /* 1, D3DTSS_COLOROP */ 2260 WINED3D_TSS_COLOR_ARG1, /* 2, D3DTSS_COLORARG1 */ 2261 WINED3D_TSS_COLOR_ARG2, /* 3, D3DTSS_COLORARG2 */ 2262 WINED3D_TSS_ALPHA_OP, /* 4, D3DTSS_ALPHAOP */ 2263 WINED3D_TSS_ALPHA_ARG1, /* 5, D3DTSS_ALPHAARG1 */ 2264 WINED3D_TSS_ALPHA_ARG2, /* 6, D3DTSS_ALPHAARG2 */ 2265 WINED3D_TSS_BUMPENV_MAT00, /* 7, D3DTSS_BUMPENVMAT00 */ 2266 WINED3D_TSS_BUMPENV_MAT01, /* 8, D3DTSS_BUMPENVMAT01 */ 2267 WINED3D_TSS_BUMPENV_MAT10, /* 9, D3DTSS_BUMPENVMAT10 */ 2268 WINED3D_TSS_BUMPENV_MAT11, /* 10, D3DTSS_BUMPENVMAT11 */ 2269 WINED3D_TSS_TEXCOORD_INDEX, /* 11, D3DTSS_TEXCOORDINDEX */ 2270 WINED3D_TSS_INVALID, /* 12, unused */ 2271 WINED3D_TSS_INVALID, /* 13, unused */ 2272 WINED3D_TSS_INVALID, /* 14, unused */ 2273 WINED3D_TSS_INVALID, /* 15, unused */ 2274 WINED3D_TSS_INVALID, /* 16, unused */ 2275 WINED3D_TSS_INVALID, /* 17, unused */ 2276 WINED3D_TSS_INVALID, /* 18, unused */ 2277 WINED3D_TSS_INVALID, /* 19, unused */ 2278 WINED3D_TSS_INVALID, /* 20, unused */ 2279 WINED3D_TSS_INVALID, /* 21, unused */ 2280 WINED3D_TSS_BUMPENV_LSCALE, /* 22, D3DTSS_BUMPENVLSCALE */ 2281 WINED3D_TSS_BUMPENV_LOFFSET, /* 23, D3DTSS_BUMPENVLOFFSET */ 2282 WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */ 2283 WINED3D_TSS_INVALID, /* 25, unused */ 2284 WINED3D_TSS_COLOR_ARG0, /* 26, D3DTSS_COLORARG0 */ 2285 WINED3D_TSS_ALPHA_ARG0, /* 27, D3DTSS_ALPHAARG0 */ 2286 WINED3D_TSS_RESULT_ARG, /* 28, D3DTSS_RESULTARG */ 2287 WINED3D_TSS_INVALID, /* 29, unused */ 2288 WINED3D_TSS_INVALID, /* 30, unused */ 2289 WINED3D_TSS_INVALID, /* 31, unused */ 2290 WINED3D_TSS_CONSTANT, /* 32, D3DTSS_CONSTANT */ 2291 }; 2292 2293 static HRESULT WINAPI d3d9_device_GetTextureStageState(IDirect3DDevice9Ex *iface, 2294 DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD *value) 2295 { 2296 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2297 2298 TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, stage, state, value); 2299 2300 if (state >= sizeof(tss_lookup) / sizeof(*tss_lookup)) 2301 { 2302 WARN("Invalid state %#x passed.\n", state); 2303 return D3D_OK; 2304 } 2305 2306 wined3d_mutex_lock(); 2307 *value = wined3d_device_get_texture_stage_state(device->wined3d_device, stage, tss_lookup[state]); 2308 wined3d_mutex_unlock(); 2309 2310 return D3D_OK; 2311 } 2312 2313 static HRESULT WINAPI d3d9_device_SetTextureStageState(IDirect3DDevice9Ex *iface, 2314 DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD value) 2315 { 2316 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2317 2318 TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, stage, state, value); 2319 2320 if (state >= sizeof(tss_lookup) / sizeof(*tss_lookup)) 2321 { 2322 WARN("Invalid state %#x passed.\n", state); 2323 return D3D_OK; 2324 } 2325 2326 wined3d_mutex_lock(); 2327 wined3d_device_set_texture_stage_state(device->wined3d_device, stage, tss_lookup[state], value); 2328 wined3d_mutex_unlock(); 2329 2330 return D3D_OK; 2331 } 2332 2333 static HRESULT WINAPI d3d9_device_GetSamplerState(IDirect3DDevice9Ex *iface, 2334 DWORD sampler, D3DSAMPLERSTATETYPE state, DWORD *value) 2335 { 2336 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2337 2338 TRACE("iface %p, sampler %u, state %#x, value %p.\n", iface, sampler, state, value); 2339 2340 wined3d_mutex_lock(); 2341 *value = wined3d_device_get_sampler_state(device->wined3d_device, sampler, state); 2342 wined3d_mutex_unlock(); 2343 2344 return D3D_OK; 2345 } 2346 2347 static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_SetSamplerState(IDirect3DDevice9Ex *iface, 2348 DWORD sampler, D3DSAMPLERSTATETYPE state, DWORD value) 2349 { 2350 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2351 2352 TRACE("iface %p, sampler %u, state %#x, value %#x.\n", iface, sampler, state, value); 2353 2354 wined3d_mutex_lock(); 2355 wined3d_device_set_sampler_state(device->wined3d_device, sampler, state, value); 2356 wined3d_mutex_unlock(); 2357 2358 return D3D_OK; 2359 } 2360 2361 static HRESULT WINAPI d3d9_device_ValidateDevice(IDirect3DDevice9Ex *iface, DWORD *pass_count) 2362 { 2363 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2364 HRESULT hr; 2365 2366 TRACE("iface %p, pass_count %p.\n", iface, pass_count); 2367 2368 wined3d_mutex_lock(); 2369 hr = wined3d_device_validate_device(device->wined3d_device, pass_count); 2370 wined3d_mutex_unlock(); 2371 2372 return hr; 2373 } 2374 2375 static HRESULT WINAPI d3d9_device_SetPaletteEntries(IDirect3DDevice9Ex *iface, 2376 UINT palette_idx, const PALETTEENTRY *entries) 2377 { 2378 WARN("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, palette_idx, entries); 2379 2380 /* The d3d9 palette API is non-functional on Windows. Getters and setters are implemented, 2381 * and some drivers allow the creation of P8 surfaces. These surfaces can be copied to 2382 * other P8 surfaces with StretchRect, but cannot be converted to (A)RGB. 2383 * 2384 * Some older(dx7) cards may have support for P8 textures, but games cannot rely on this. */ 2385 return D3D_OK; 2386 } 2387 2388 static HRESULT WINAPI d3d9_device_GetPaletteEntries(IDirect3DDevice9Ex *iface, 2389 UINT palette_idx, PALETTEENTRY *entries) 2390 { 2391 FIXME("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, palette_idx, entries); 2392 2393 return D3DERR_INVALIDCALL; 2394 } 2395 2396 static HRESULT WINAPI d3d9_device_SetCurrentTexturePalette(IDirect3DDevice9Ex *iface, UINT palette_idx) 2397 { 2398 WARN("iface %p, palette_idx %u unimplemented.\n", iface, palette_idx); 2399 2400 return D3D_OK; 2401 } 2402 2403 static HRESULT WINAPI d3d9_device_GetCurrentTexturePalette(IDirect3DDevice9Ex *iface, UINT *palette_idx) 2404 { 2405 FIXME("iface %p, palette_idx %p.\n", iface, palette_idx); 2406 2407 return D3DERR_INVALIDCALL; 2408 } 2409 2410 static HRESULT WINAPI d3d9_device_SetScissorRect(IDirect3DDevice9Ex *iface, const RECT *rect) 2411 { 2412 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2413 2414 TRACE("iface %p, rect %p.\n", iface, rect); 2415 2416 wined3d_mutex_lock(); 2417 wined3d_device_set_scissor_rect(device->wined3d_device, rect); 2418 wined3d_mutex_unlock(); 2419 2420 return D3D_OK; 2421 } 2422 2423 static HRESULT WINAPI d3d9_device_GetScissorRect(IDirect3DDevice9Ex *iface, RECT *rect) 2424 { 2425 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2426 2427 TRACE("iface %p, rect %p.\n", iface, rect); 2428 2429 wined3d_mutex_lock(); 2430 wined3d_device_get_scissor_rect(device->wined3d_device, rect); 2431 wined3d_mutex_unlock(); 2432 2433 return D3D_OK; 2434 } 2435 2436 static HRESULT WINAPI d3d9_device_SetSoftwareVertexProcessing(IDirect3DDevice9Ex *iface, BOOL software) 2437 { 2438 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2439 2440 TRACE("iface %p, software %#x.\n", iface, software); 2441 2442 wined3d_mutex_lock(); 2443 wined3d_device_set_software_vertex_processing(device->wined3d_device, software); 2444 wined3d_mutex_unlock(); 2445 2446 return D3D_OK; 2447 } 2448 2449 static BOOL WINAPI d3d9_device_GetSoftwareVertexProcessing(IDirect3DDevice9Ex *iface) 2450 { 2451 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2452 BOOL ret; 2453 2454 TRACE("iface %p.\n", iface); 2455 2456 wined3d_mutex_lock(); 2457 ret = wined3d_device_get_software_vertex_processing(device->wined3d_device); 2458 wined3d_mutex_unlock(); 2459 2460 return ret; 2461 } 2462 2463 static HRESULT WINAPI d3d9_device_SetNPatchMode(IDirect3DDevice9Ex *iface, float segment_count) 2464 { 2465 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2466 HRESULT hr; 2467 2468 TRACE("iface %p, segment_count %.8e.\n", iface, segment_count); 2469 2470 wined3d_mutex_lock(); 2471 hr = wined3d_device_set_npatch_mode(device->wined3d_device, segment_count); 2472 wined3d_mutex_unlock(); 2473 2474 return hr; 2475 } 2476 2477 static float WINAPI d3d9_device_GetNPatchMode(IDirect3DDevice9Ex *iface) 2478 { 2479 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2480 float ret; 2481 2482 TRACE("iface %p.\n", iface); 2483 2484 wined3d_mutex_lock(); 2485 ret = wined3d_device_get_npatch_mode(device->wined3d_device); 2486 wined3d_mutex_unlock(); 2487 2488 return ret; 2489 } 2490 2491 static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface, 2492 D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count) 2493 { 2494 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2495 HRESULT hr; 2496 2497 TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n", 2498 iface, primitive_type, start_vertex, primitive_count); 2499 2500 wined3d_mutex_lock(); 2501 if (!device->has_vertex_declaration) 2502 { 2503 wined3d_mutex_unlock(); 2504 WARN("Called without a valid vertex declaration set.\n"); 2505 return D3DERR_INVALIDCALL; 2506 } 2507 wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); 2508 hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, 2509 vertex_count_from_primitive_count(primitive_type, primitive_count)); 2510 wined3d_mutex_unlock(); 2511 2512 return hr; 2513 } 2514 2515 static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface, 2516 D3DPRIMITIVETYPE primitive_type, INT base_vertex_idx, UINT min_vertex_idx, 2517 UINT vertex_count, UINT start_idx, UINT primitive_count) 2518 { 2519 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2520 HRESULT hr; 2521 2522 TRACE("iface %p, primitive_type %#x, base_vertex_idx %u, min_vertex_idx %u, " 2523 "vertex_count %u, start_idx %u, primitive_count %u.\n", 2524 iface, primitive_type, base_vertex_idx, min_vertex_idx, 2525 vertex_count, start_idx, primitive_count); 2526 2527 wined3d_mutex_lock(); 2528 if (!device->has_vertex_declaration) 2529 { 2530 wined3d_mutex_unlock(); 2531 WARN("Called without a valid vertex declaration set.\n"); 2532 return D3DERR_INVALIDCALL; 2533 } 2534 wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx); 2535 wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); 2536 hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, 2537 vertex_count_from_primitive_count(primitive_type, primitive_count)); 2538 wined3d_mutex_unlock(); 2539 2540 return hr; 2541 } 2542 2543 /* The caller is responsible for wined3d locking */ 2544 static HRESULT d3d9_device_prepare_vertex_buffer(struct d3d9_device *device, UINT min_size) 2545 { 2546 HRESULT hr; 2547 2548 if (device->vertex_buffer_size < min_size || !device->vertex_buffer) 2549 { 2550 UINT size = max(device->vertex_buffer_size * 2, min_size); 2551 struct wined3d_buffer *buffer; 2552 2553 TRACE("Growing vertex buffer to %u bytes.\n", size); 2554 2555 hr = wined3d_buffer_create_vb(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, 2556 WINED3D_POOL_DEFAULT, NULL, &d3d9_null_wined3d_parent_ops, &buffer); 2557 if (FAILED(hr)) 2558 { 2559 ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x.\n", device, hr); 2560 return hr; 2561 } 2562 2563 if (device->vertex_buffer) 2564 wined3d_buffer_decref(device->vertex_buffer); 2565 2566 device->vertex_buffer = buffer; 2567 device->vertex_buffer_size = size; 2568 device->vertex_buffer_pos = 0; 2569 } 2570 return D3D_OK; 2571 } 2572 2573 static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, 2574 D3DPRIMITIVETYPE primitive_type, UINT primitive_count, const void *data, UINT stride) 2575 { 2576 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2577 HRESULT hr; 2578 UINT vtx_count = vertex_count_from_primitive_count(primitive_type, primitive_count); 2579 struct wined3d_map_desc wined3d_map_desc; 2580 struct wined3d_box wined3d_box = {0}; 2581 UINT size = vtx_count * stride; 2582 struct wined3d_resource *vb; 2583 UINT vb_pos, align; 2584 2585 TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n", 2586 iface, primitive_type, primitive_count, data, stride); 2587 2588 if (!primitive_count) 2589 { 2590 WARN("primitive_count is 0, returning D3D_OK\n"); 2591 return D3D_OK; 2592 } 2593 2594 wined3d_mutex_lock(); 2595 2596 if (!device->has_vertex_declaration) 2597 { 2598 wined3d_mutex_unlock(); 2599 WARN("Called without a valid vertex declaration set.\n"); 2600 return D3DERR_INVALIDCALL; 2601 } 2602 2603 hr = d3d9_device_prepare_vertex_buffer(device, size); 2604 if (FAILED(hr)) 2605 goto done; 2606 2607 vb_pos = device->vertex_buffer_pos; 2608 align = vb_pos % stride; 2609 if (align) align = stride - align; 2610 if (vb_pos + size + align > device->vertex_buffer_size) 2611 vb_pos = 0; 2612 else 2613 vb_pos += align; 2614 2615 wined3d_box.left = vb_pos; 2616 wined3d_box.right = vb_pos + size; 2617 vb = wined3d_buffer_get_resource(device->vertex_buffer); 2618 if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, 2619 vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) 2620 goto done; 2621 memcpy(wined3d_map_desc.data, data, size); 2622 wined3d_resource_unmap(vb, 0); 2623 device->vertex_buffer_pos = vb_pos + size; 2624 2625 hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, stride); 2626 if (FAILED(hr)) 2627 goto done; 2628 2629 wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); 2630 hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count); 2631 wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0); 2632 2633 done: 2634 wined3d_mutex_unlock(); 2635 return hr; 2636 } 2637 2638 /* The caller is responsible for wined3d locking */ 2639 static HRESULT d3d9_device_prepare_index_buffer(struct d3d9_device *device, UINT min_size) 2640 { 2641 HRESULT hr; 2642 2643 if (device->index_buffer_size < min_size || !device->index_buffer) 2644 { 2645 UINT size = max(device->index_buffer_size * 2, min_size); 2646 struct wined3d_buffer *buffer; 2647 2648 TRACE("Growing index buffer to %u bytes.\n", size); 2649 2650 hr = wined3d_buffer_create_ib(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, 2651 WINED3D_POOL_DEFAULT, NULL, &d3d9_null_wined3d_parent_ops, &buffer); 2652 if (FAILED(hr)) 2653 { 2654 ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x.\n", device, hr); 2655 return hr; 2656 } 2657 2658 if (device->index_buffer) 2659 wined3d_buffer_decref(device->index_buffer); 2660 2661 device->index_buffer = buffer; 2662 device->index_buffer_size = size; 2663 device->index_buffer_pos = 0; 2664 } 2665 return D3D_OK; 2666 } 2667 2668 static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *iface, 2669 D3DPRIMITIVETYPE primitive_type, UINT min_vertex_idx, UINT vertex_count, 2670 UINT primitive_count, const void *index_data, D3DFORMAT index_format, 2671 const void *vertex_data, UINT vertex_stride) 2672 { 2673 UINT idx_count = vertex_count_from_primitive_count(primitive_type, primitive_count); 2674 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2675 UINT idx_fmt_size = index_format == D3DFMT_INDEX16 ? 2 : 4; 2676 UINT vtx_size = vertex_count * vertex_stride; 2677 UINT idx_size = idx_count * idx_fmt_size; 2678 struct wined3d_map_desc wined3d_map_desc; 2679 struct wined3d_box wined3d_box = {0}; 2680 struct wined3d_resource *ib, *vb; 2681 UINT vb_pos, ib_pos, align; 2682 HRESULT hr; 2683 2684 TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, primitive_count %u, " 2685 "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n", 2686 iface, primitive_type, min_vertex_idx, vertex_count, primitive_count, 2687 index_data, index_format, vertex_data, vertex_stride); 2688 2689 if (!primitive_count) 2690 { 2691 WARN("primitive_count is 0, returning D3D_OK.\n"); 2692 return D3D_OK; 2693 } 2694 2695 wined3d_mutex_lock(); 2696 2697 if (!device->has_vertex_declaration) 2698 { 2699 wined3d_mutex_unlock(); 2700 WARN("Called without a valid vertex declaration set.\n"); 2701 return D3DERR_INVALIDCALL; 2702 } 2703 2704 hr = d3d9_device_prepare_vertex_buffer(device, vtx_size); 2705 if (FAILED(hr)) 2706 goto done; 2707 2708 vb_pos = device->vertex_buffer_pos; 2709 align = vb_pos % vertex_stride; 2710 if (align) align = vertex_stride - align; 2711 if (vb_pos + vtx_size + align > device->vertex_buffer_size) 2712 vb_pos = 0; 2713 else 2714 vb_pos += align; 2715 2716 wined3d_box.left = vb_pos; 2717 wined3d_box.right = vb_pos + vtx_size; 2718 vb = wined3d_buffer_get_resource(device->vertex_buffer); 2719 if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, 2720 vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) 2721 goto done; 2722 memcpy(wined3d_map_desc.data, (char *)vertex_data + min_vertex_idx * vertex_stride, vtx_size); 2723 wined3d_resource_unmap(vb, 0); 2724 device->vertex_buffer_pos = vb_pos + vtx_size; 2725 2726 hr = d3d9_device_prepare_index_buffer(device, idx_size); 2727 if (FAILED(hr)) 2728 goto done; 2729 2730 ib_pos = device->index_buffer_pos; 2731 align = ib_pos % idx_fmt_size; 2732 if (align) align = idx_fmt_size - align; 2733 if (ib_pos + idx_size + align > device->index_buffer_size) 2734 ib_pos = 0; 2735 else 2736 ib_pos += align; 2737 2738 wined3d_box.left = ib_pos; 2739 wined3d_box.right = ib_pos + idx_size; 2740 ib = wined3d_buffer_get_resource(device->index_buffer); 2741 if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box, 2742 ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) 2743 goto done; 2744 memcpy(wined3d_map_desc.data, index_data, idx_size); 2745 wined3d_resource_unmap(ib, 0); 2746 device->index_buffer_pos = ib_pos + idx_size; 2747 2748 hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, vertex_stride); 2749 if (FAILED(hr)) 2750 goto done; 2751 2752 wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, 2753 wined3dformat_from_d3dformat(index_format), 0); 2754 wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride - min_vertex_idx); 2755 2756 wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); 2757 hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count); 2758 2759 wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0); 2760 wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0); 2761 wined3d_device_set_base_vertex_index(device->wined3d_device, 0); 2762 2763 done: 2764 wined3d_mutex_unlock(); 2765 return hr; 2766 } 2767 2768 static HRESULT WINAPI d3d9_device_ProcessVertices(IDirect3DDevice9Ex *iface, 2769 UINT src_start_idx, UINT dst_idx, UINT vertex_count, IDirect3DVertexBuffer9 *dst_buffer, 2770 IDirect3DVertexDeclaration9 *declaration, DWORD flags) 2771 { 2772 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2773 struct d3d9_vertexbuffer *dst_impl = unsafe_impl_from_IDirect3DVertexBuffer9(dst_buffer); 2774 struct d3d9_vertex_declaration *decl_impl = unsafe_impl_from_IDirect3DVertexDeclaration9(declaration); 2775 HRESULT hr; 2776 2777 TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, declaration %p, flags %#x.\n", 2778 iface, src_start_idx, dst_idx, vertex_count, dst_buffer, declaration, flags); 2779 2780 wined3d_mutex_lock(); 2781 hr = wined3d_device_process_vertices(device->wined3d_device, src_start_idx, dst_idx, vertex_count, 2782 dst_impl->wined3d_buffer, decl_impl ? decl_impl->wined3d_declaration : NULL, 2783 flags, dst_impl->fvf); 2784 wined3d_mutex_unlock(); 2785 2786 return hr; 2787 } 2788 2789 static HRESULT WINAPI d3d9_device_CreateVertexDeclaration(IDirect3DDevice9Ex *iface, 2790 const D3DVERTEXELEMENT9 *elements, IDirect3DVertexDeclaration9 **declaration) 2791 { 2792 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2793 struct d3d9_vertex_declaration *object; 2794 HRESULT hr; 2795 2796 TRACE("iface %p, elements %p, declaration %p.\n", iface, elements, declaration); 2797 2798 if (!declaration) 2799 { 2800 WARN("Caller passed a NULL declaration, returning D3DERR_INVALIDCALL.\n"); 2801 return D3DERR_INVALIDCALL; 2802 } 2803 2804 if (SUCCEEDED(hr = d3d9_vertex_declaration_create(device, elements, &object))) 2805 *declaration = &object->IDirect3DVertexDeclaration9_iface; 2806 2807 return hr; 2808 } 2809 2810 static HRESULT WINAPI d3d9_device_SetVertexDeclaration(IDirect3DDevice9Ex *iface, 2811 IDirect3DVertexDeclaration9 *declaration) 2812 { 2813 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2814 struct d3d9_vertex_declaration *decl_impl = unsafe_impl_from_IDirect3DVertexDeclaration9(declaration); 2815 2816 TRACE("iface %p, declaration %p.\n", iface, declaration); 2817 2818 wined3d_mutex_lock(); 2819 wined3d_device_set_vertex_declaration(device->wined3d_device, 2820 decl_impl ? decl_impl->wined3d_declaration : NULL); 2821 device->has_vertex_declaration = !!decl_impl; 2822 wined3d_mutex_unlock(); 2823 2824 return D3D_OK; 2825 } 2826 2827 static HRESULT WINAPI d3d9_device_GetVertexDeclaration(IDirect3DDevice9Ex *iface, 2828 IDirect3DVertexDeclaration9 **declaration) 2829 { 2830 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2831 struct wined3d_vertex_declaration *wined3d_declaration; 2832 struct d3d9_vertex_declaration *declaration_impl; 2833 2834 TRACE("iface %p, declaration %p.\n", iface, declaration); 2835 2836 if (!declaration) return D3DERR_INVALIDCALL; 2837 2838 wined3d_mutex_lock(); 2839 if ((wined3d_declaration = wined3d_device_get_vertex_declaration(device->wined3d_device))) 2840 { 2841 declaration_impl = wined3d_vertex_declaration_get_parent(wined3d_declaration); 2842 *declaration = &declaration_impl->IDirect3DVertexDeclaration9_iface; 2843 IDirect3DVertexDeclaration9_AddRef(*declaration); 2844 } 2845 else 2846 { 2847 *declaration = NULL; 2848 } 2849 wined3d_mutex_unlock(); 2850 2851 TRACE("Returning %p.\n", *declaration); 2852 return D3D_OK; 2853 } 2854 2855 static struct wined3d_vertex_declaration *device_get_fvf_declaration(struct d3d9_device *device, DWORD fvf) 2856 { 2857 struct wined3d_vertex_declaration *wined3d_declaration; 2858 struct fvf_declaration *fvf_decls = device->fvf_decls; 2859 struct d3d9_vertex_declaration *d3d9_declaration; 2860 D3DVERTEXELEMENT9 *elements; 2861 int p, low, high; /* deliberately signed */ 2862 HRESULT hr; 2863 2864 TRACE("Searching for declaration for fvf %08x... ", fvf); 2865 2866 low = 0; 2867 high = device->fvf_decl_count - 1; 2868 while (low <= high) 2869 { 2870 p = (low + high) >> 1; 2871 TRACE("%d ", p); 2872 2873 if (fvf_decls[p].fvf == fvf) 2874 { 2875 TRACE("found %p.\n", fvf_decls[p].decl); 2876 return fvf_decls[p].decl; 2877 } 2878 2879 if (fvf_decls[p].fvf < fvf) 2880 low = p + 1; 2881 else 2882 high = p - 1; 2883 } 2884 TRACE("not found. Creating and inserting at position %d.\n", low); 2885 2886 if (FAILED(hr = vdecl_convert_fvf(fvf, &elements))) 2887 return NULL; 2888 2889 hr = d3d9_vertex_declaration_create(device, elements, &d3d9_declaration); 2890 HeapFree(GetProcessHeap(), 0, elements); 2891 if (FAILED(hr)) 2892 return NULL; 2893 2894 if (device->fvf_decl_size == device->fvf_decl_count) 2895 { 2896 UINT grow = max(device->fvf_decl_size / 2, 8); 2897 2898 fvf_decls = HeapReAlloc(GetProcessHeap(), 0, fvf_decls, sizeof(*fvf_decls) * (device->fvf_decl_size + grow)); 2899 if (!fvf_decls) 2900 { 2901 IDirect3DVertexDeclaration9_Release(&d3d9_declaration->IDirect3DVertexDeclaration9_iface); 2902 return NULL; 2903 } 2904 device->fvf_decls = fvf_decls; 2905 device->fvf_decl_size += grow; 2906 } 2907 2908 d3d9_declaration->fvf = fvf; 2909 wined3d_declaration = d3d9_declaration->wined3d_declaration; 2910 wined3d_vertex_declaration_incref(wined3d_declaration); 2911 IDirect3DVertexDeclaration9_Release(&d3d9_declaration->IDirect3DVertexDeclaration9_iface); 2912 2913 memmove(fvf_decls + low + 1, fvf_decls + low, sizeof(*fvf_decls) * (device->fvf_decl_count - low)); 2914 fvf_decls[low].decl = wined3d_declaration; 2915 fvf_decls[low].fvf = fvf; 2916 ++device->fvf_decl_count; 2917 2918 TRACE("Returning %p. %u declarations in array.\n", wined3d_declaration, device->fvf_decl_count); 2919 2920 return wined3d_declaration; 2921 } 2922 2923 static HRESULT WINAPI d3d9_device_SetFVF(IDirect3DDevice9Ex *iface, DWORD fvf) 2924 { 2925 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2926 struct wined3d_vertex_declaration *decl; 2927 2928 TRACE("iface %p, fvf %#x.\n", iface, fvf); 2929 2930 if (!fvf) 2931 { 2932 WARN("%#x is not a valid FVF.\n", fvf); 2933 return D3D_OK; 2934 } 2935 2936 wined3d_mutex_lock(); 2937 if (!(decl = device_get_fvf_declaration(device, fvf))) 2938 { 2939 wined3d_mutex_unlock(); 2940 ERR("Failed to create a vertex declaration for fvf %#x.\n", fvf); 2941 return D3DERR_DRIVERINTERNALERROR; 2942 } 2943 2944 wined3d_device_set_vertex_declaration(device->wined3d_device, decl); 2945 device->has_vertex_declaration = TRUE; 2946 wined3d_mutex_unlock(); 2947 2948 return D3D_OK; 2949 } 2950 2951 static HRESULT WINAPI d3d9_device_GetFVF(IDirect3DDevice9Ex *iface, DWORD *fvf) 2952 { 2953 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2954 struct wined3d_vertex_declaration *wined3d_declaration; 2955 struct d3d9_vertex_declaration *d3d9_declaration; 2956 2957 TRACE("iface %p, fvf %p.\n", iface, fvf); 2958 2959 wined3d_mutex_lock(); 2960 if ((wined3d_declaration = wined3d_device_get_vertex_declaration(device->wined3d_device))) 2961 { 2962 d3d9_declaration = wined3d_vertex_declaration_get_parent(wined3d_declaration); 2963 *fvf = d3d9_declaration->fvf; 2964 } 2965 else 2966 { 2967 *fvf = 0; 2968 } 2969 wined3d_mutex_unlock(); 2970 2971 TRACE("Returning FVF %#x.\n", *fvf); 2972 2973 return D3D_OK; 2974 } 2975 2976 static HRESULT WINAPI d3d9_device_CreateVertexShader(IDirect3DDevice9Ex *iface, 2977 const DWORD *byte_code, IDirect3DVertexShader9 **shader) 2978 { 2979 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 2980 struct d3d9_vertexshader *object; 2981 HRESULT hr; 2982 2983 TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader); 2984 2985 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 2986 if (!object) 2987 return E_OUTOFMEMORY; 2988 2989 hr = vertexshader_init(object, device, byte_code); 2990 if (FAILED(hr)) 2991 { 2992 WARN("Failed to initialize vertex shader, hr %#x.\n", hr); 2993 HeapFree(GetProcessHeap(), 0, object); 2994 return hr; 2995 } 2996 2997 TRACE("Created vertex shader %p.\n", object); 2998 *shader = &object->IDirect3DVertexShader9_iface; 2999 3000 return D3D_OK; 3001 } 3002 3003 static HRESULT WINAPI d3d9_device_SetVertexShader(IDirect3DDevice9Ex *iface, IDirect3DVertexShader9 *shader) 3004 { 3005 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3006 struct d3d9_vertexshader *shader_obj = unsafe_impl_from_IDirect3DVertexShader9(shader); 3007 3008 TRACE("iface %p, shader %p.\n", iface, shader); 3009 3010 wined3d_mutex_lock(); 3011 wined3d_device_set_vertex_shader(device->wined3d_device, 3012 shader_obj ? shader_obj->wined3d_shader : NULL); 3013 wined3d_mutex_unlock(); 3014 3015 return D3D_OK; 3016 } 3017 3018 static HRESULT WINAPI d3d9_device_GetVertexShader(IDirect3DDevice9Ex *iface, IDirect3DVertexShader9 **shader) 3019 { 3020 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3021 struct d3d9_vertexshader *shader_impl; 3022 struct wined3d_shader *wined3d_shader; 3023 3024 TRACE("iface %p, shader %p.\n", iface, shader); 3025 3026 wined3d_mutex_lock(); 3027 if ((wined3d_shader = wined3d_device_get_vertex_shader(device->wined3d_device))) 3028 { 3029 shader_impl = wined3d_shader_get_parent(wined3d_shader); 3030 *shader = &shader_impl->IDirect3DVertexShader9_iface; 3031 IDirect3DVertexShader9_AddRef(*shader); 3032 } 3033 else 3034 { 3035 *shader = NULL; 3036 } 3037 wined3d_mutex_unlock(); 3038 3039 TRACE("Returning %p.\n", *shader); 3040 3041 return D3D_OK; 3042 } 3043 3044 static HRESULT WINAPI d3d9_device_SetVertexShaderConstantF(IDirect3DDevice9Ex *iface, 3045 UINT reg_idx, const float *data, UINT count) 3046 { 3047 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3048 HRESULT hr; 3049 3050 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3051 3052 if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF) 3053 { 3054 WARN("Trying to access %u constants, but d3d9 only supports %u\n", 3055 reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF); 3056 return D3DERR_INVALIDCALL; 3057 } 3058 3059 wined3d_mutex_lock(); 3060 hr = wined3d_device_set_vs_consts_f(device->wined3d_device, 3061 reg_idx, count, (const struct wined3d_vec4 *)data); 3062 wined3d_mutex_unlock(); 3063 3064 return hr; 3065 } 3066 3067 static HRESULT WINAPI d3d9_device_GetVertexShaderConstantF(IDirect3DDevice9Ex *iface, 3068 UINT reg_idx, float *data, UINT count) 3069 { 3070 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3071 HRESULT hr; 3072 3073 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3074 3075 if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF) 3076 { 3077 WARN("Trying to access %u constants, but d3d9 only supports %u\n", 3078 reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF); 3079 return D3DERR_INVALIDCALL; 3080 } 3081 3082 wined3d_mutex_lock(); 3083 hr = wined3d_device_get_vs_consts_f(device->wined3d_device, 3084 reg_idx, count, (struct wined3d_vec4 *)data); 3085 wined3d_mutex_unlock(); 3086 3087 return hr; 3088 } 3089 3090 static HRESULT WINAPI d3d9_device_SetVertexShaderConstantI(IDirect3DDevice9Ex *iface, 3091 UINT reg_idx, const int *data, UINT count) 3092 { 3093 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3094 HRESULT hr; 3095 3096 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3097 3098 wined3d_mutex_lock(); 3099 hr = wined3d_device_set_vs_consts_i(device->wined3d_device, 3100 reg_idx, count, (const struct wined3d_ivec4 *)data); 3101 wined3d_mutex_unlock(); 3102 3103 return hr; 3104 } 3105 3106 static HRESULT WINAPI d3d9_device_GetVertexShaderConstantI(IDirect3DDevice9Ex *iface, 3107 UINT reg_idx, int *data, UINT count) 3108 { 3109 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3110 HRESULT hr; 3111 3112 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3113 3114 wined3d_mutex_lock(); 3115 hr = wined3d_device_get_vs_consts_i(device->wined3d_device, 3116 reg_idx, count, (struct wined3d_ivec4 *)data); 3117 wined3d_mutex_unlock(); 3118 3119 return hr; 3120 } 3121 3122 static HRESULT WINAPI d3d9_device_SetVertexShaderConstantB(IDirect3DDevice9Ex *iface, 3123 UINT reg_idx, const BOOL *data, UINT count) 3124 { 3125 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3126 HRESULT hr; 3127 3128 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3129 3130 wined3d_mutex_lock(); 3131 hr = wined3d_device_set_vs_consts_b(device->wined3d_device, reg_idx, count, data); 3132 wined3d_mutex_unlock(); 3133 3134 return hr; 3135 } 3136 3137 static HRESULT WINAPI d3d9_device_GetVertexShaderConstantB(IDirect3DDevice9Ex *iface, 3138 UINT reg_idx, BOOL *data, UINT count) 3139 { 3140 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3141 HRESULT hr; 3142 3143 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3144 3145 wined3d_mutex_lock(); 3146 hr = wined3d_device_get_vs_consts_b(device->wined3d_device, reg_idx, count, data); 3147 wined3d_mutex_unlock(); 3148 3149 return hr; 3150 } 3151 3152 static HRESULT WINAPI d3d9_device_SetStreamSource(IDirect3DDevice9Ex *iface, 3153 UINT stream_idx, IDirect3DVertexBuffer9 *buffer, UINT offset, UINT stride) 3154 { 3155 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3156 struct d3d9_vertexbuffer *buffer_impl = unsafe_impl_from_IDirect3DVertexBuffer9(buffer); 3157 HRESULT hr; 3158 3159 TRACE("iface %p, stream_idx %u, buffer %p, offset %u, stride %u.\n", 3160 iface, stream_idx, buffer, offset, stride); 3161 3162 wined3d_mutex_lock(); 3163 hr = wined3d_device_set_stream_source(device->wined3d_device, stream_idx, 3164 buffer_impl ? buffer_impl->wined3d_buffer : NULL, offset, stride); 3165 wined3d_mutex_unlock(); 3166 3167 return hr; 3168 } 3169 3170 static HRESULT WINAPI d3d9_device_GetStreamSource(IDirect3DDevice9Ex *iface, 3171 UINT stream_idx, IDirect3DVertexBuffer9 **buffer, UINT *offset, UINT *stride) 3172 { 3173 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3174 struct d3d9_vertexbuffer *buffer_impl; 3175 struct wined3d_buffer *wined3d_buffer; 3176 HRESULT hr; 3177 3178 TRACE("iface %p, stream_idx %u, buffer %p, offset %p, stride %p.\n", 3179 iface, stream_idx, buffer, offset, stride); 3180 3181 if (!buffer) 3182 return D3DERR_INVALIDCALL; 3183 3184 wined3d_mutex_lock(); 3185 hr = wined3d_device_get_stream_source(device->wined3d_device, stream_idx, &wined3d_buffer, offset, stride); 3186 if (SUCCEEDED(hr) && wined3d_buffer) 3187 { 3188 buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); 3189 *buffer = &buffer_impl->IDirect3DVertexBuffer9_iface; 3190 IDirect3DVertexBuffer9_AddRef(*buffer); 3191 } 3192 else 3193 { 3194 if (FAILED(hr)) 3195 FIXME("Call to GetStreamSource failed %p %p\n", offset, stride); 3196 *buffer = NULL; 3197 } 3198 wined3d_mutex_unlock(); 3199 3200 return hr; 3201 } 3202 3203 static HRESULT WINAPI d3d9_device_SetStreamSourceFreq(IDirect3DDevice9Ex *iface, UINT stream_idx, UINT freq) 3204 { 3205 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3206 HRESULT hr; 3207 3208 TRACE("iface %p, stream_idx %u, freq %u.\n", iface, stream_idx, freq); 3209 3210 wined3d_mutex_lock(); 3211 hr = wined3d_device_set_stream_source_freq(device->wined3d_device, stream_idx, freq); 3212 wined3d_mutex_unlock(); 3213 3214 return hr; 3215 } 3216 3217 static HRESULT WINAPI d3d9_device_GetStreamSourceFreq(IDirect3DDevice9Ex *iface, UINT stream_idx, UINT *freq) 3218 { 3219 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3220 HRESULT hr; 3221 3222 TRACE("iface %p, stream_idx %u, freq %p.\n", iface, stream_idx, freq); 3223 3224 wined3d_mutex_lock(); 3225 hr = wined3d_device_get_stream_source_freq(device->wined3d_device, stream_idx, freq); 3226 wined3d_mutex_unlock(); 3227 3228 return hr; 3229 } 3230 3231 static HRESULT WINAPI d3d9_device_SetIndices(IDirect3DDevice9Ex *iface, IDirect3DIndexBuffer9 *buffer) 3232 { 3233 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3234 struct d3d9_indexbuffer *ib = unsafe_impl_from_IDirect3DIndexBuffer9(buffer); 3235 3236 TRACE("iface %p, buffer %p.\n", iface, buffer); 3237 3238 wined3d_mutex_lock(); 3239 wined3d_device_set_index_buffer(device->wined3d_device, 3240 ib ? ib->wined3d_buffer : NULL, ib ? ib->format : WINED3DFMT_UNKNOWN, 0); 3241 wined3d_mutex_unlock(); 3242 3243 return D3D_OK; 3244 } 3245 3246 static HRESULT WINAPI d3d9_device_GetIndices(IDirect3DDevice9Ex *iface, IDirect3DIndexBuffer9 **buffer) 3247 { 3248 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3249 enum wined3d_format_id wined3d_format; 3250 struct wined3d_buffer *wined3d_buffer; 3251 struct d3d9_indexbuffer *buffer_impl; 3252 3253 TRACE("iface %p, buffer %p.\n", iface, buffer); 3254 3255 if (!buffer) 3256 return D3DERR_INVALIDCALL; 3257 3258 wined3d_mutex_lock(); 3259 if ((wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &wined3d_format, NULL))) 3260 { 3261 buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); 3262 *buffer = &buffer_impl->IDirect3DIndexBuffer9_iface; 3263 IDirect3DIndexBuffer9_AddRef(*buffer); 3264 } 3265 else 3266 { 3267 *buffer = NULL; 3268 } 3269 wined3d_mutex_unlock(); 3270 3271 return D3D_OK; 3272 } 3273 3274 static HRESULT WINAPI d3d9_device_CreatePixelShader(IDirect3DDevice9Ex *iface, 3275 const DWORD *byte_code, IDirect3DPixelShader9 **shader) 3276 { 3277 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3278 struct d3d9_pixelshader *object; 3279 HRESULT hr; 3280 3281 TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader); 3282 3283 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 3284 if (!object) 3285 { 3286 FIXME("Failed to allocate pixel shader memory.\n"); 3287 return E_OUTOFMEMORY; 3288 } 3289 3290 hr = pixelshader_init(object, device, byte_code); 3291 if (FAILED(hr)) 3292 { 3293 WARN("Failed to initialize pixel shader, hr %#x.\n", hr); 3294 HeapFree(GetProcessHeap(), 0, object); 3295 return hr; 3296 } 3297 3298 TRACE("Created pixel shader %p.\n", object); 3299 *shader = &object->IDirect3DPixelShader9_iface; 3300 3301 return D3D_OK; 3302 } 3303 3304 static HRESULT WINAPI d3d9_device_SetPixelShader(IDirect3DDevice9Ex *iface, IDirect3DPixelShader9 *shader) 3305 { 3306 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3307 struct d3d9_pixelshader *shader_obj = unsafe_impl_from_IDirect3DPixelShader9(shader); 3308 3309 TRACE("iface %p, shader %p.\n", iface, shader); 3310 3311 wined3d_mutex_lock(); 3312 wined3d_device_set_pixel_shader(device->wined3d_device, 3313 shader_obj ? shader_obj->wined3d_shader : NULL); 3314 wined3d_mutex_unlock(); 3315 3316 return D3D_OK; 3317 } 3318 3319 static HRESULT WINAPI d3d9_device_GetPixelShader(IDirect3DDevice9Ex *iface, IDirect3DPixelShader9 **shader) 3320 { 3321 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3322 struct d3d9_pixelshader *shader_impl; 3323 struct wined3d_shader *wined3d_shader; 3324 3325 TRACE("iface %p, shader %p.\n", iface, shader); 3326 3327 if (!shader) return D3DERR_INVALIDCALL; 3328 3329 wined3d_mutex_lock(); 3330 if ((wined3d_shader = wined3d_device_get_pixel_shader(device->wined3d_device))) 3331 { 3332 shader_impl = wined3d_shader_get_parent(wined3d_shader); 3333 *shader = &shader_impl->IDirect3DPixelShader9_iface; 3334 IDirect3DPixelShader9_AddRef(*shader); 3335 } 3336 else 3337 { 3338 *shader = NULL; 3339 } 3340 wined3d_mutex_unlock(); 3341 3342 TRACE("Returning %p.\n", *shader); 3343 3344 return D3D_OK; 3345 } 3346 3347 static HRESULT WINAPI d3d9_device_SetPixelShaderConstantF(IDirect3DDevice9Ex *iface, 3348 UINT reg_idx, const float *data, UINT count) 3349 { 3350 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3351 HRESULT hr; 3352 3353 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3354 3355 wined3d_mutex_lock(); 3356 hr = wined3d_device_set_ps_consts_f(device->wined3d_device, 3357 reg_idx, count, (const struct wined3d_vec4 *)data); 3358 wined3d_mutex_unlock(); 3359 3360 return hr; 3361 } 3362 3363 static HRESULT WINAPI d3d9_device_GetPixelShaderConstantF(IDirect3DDevice9Ex *iface, 3364 UINT reg_idx, float *data, UINT count) 3365 { 3366 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3367 HRESULT hr; 3368 3369 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3370 3371 wined3d_mutex_lock(); 3372 hr = wined3d_device_get_ps_consts_f(device->wined3d_device, 3373 reg_idx, count, (struct wined3d_vec4 *)data); 3374 wined3d_mutex_unlock(); 3375 3376 return hr; 3377 } 3378 3379 static HRESULT WINAPI d3d9_device_SetPixelShaderConstantI(IDirect3DDevice9Ex *iface, 3380 UINT reg_idx, const int *data, UINT count) 3381 { 3382 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3383 HRESULT hr; 3384 3385 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3386 3387 wined3d_mutex_lock(); 3388 hr = wined3d_device_set_ps_consts_i(device->wined3d_device, 3389 reg_idx, count, (const struct wined3d_ivec4 *)data); 3390 wined3d_mutex_unlock(); 3391 3392 return hr; 3393 } 3394 3395 static HRESULT WINAPI d3d9_device_GetPixelShaderConstantI(IDirect3DDevice9Ex *iface, 3396 UINT reg_idx, int *data, UINT count) 3397 { 3398 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3399 HRESULT hr; 3400 3401 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3402 3403 wined3d_mutex_lock(); 3404 hr = wined3d_device_get_ps_consts_i(device->wined3d_device, 3405 reg_idx, count, (struct wined3d_ivec4 *)data); 3406 wined3d_mutex_unlock(); 3407 3408 return hr; 3409 } 3410 3411 static HRESULT WINAPI d3d9_device_SetPixelShaderConstantB(IDirect3DDevice9Ex *iface, 3412 UINT reg_idx, const BOOL *data, UINT count) 3413 { 3414 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3415 HRESULT hr; 3416 3417 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3418 3419 wined3d_mutex_lock(); 3420 hr = wined3d_device_set_ps_consts_b(device->wined3d_device, reg_idx, count, data); 3421 wined3d_mutex_unlock(); 3422 3423 return hr; 3424 } 3425 3426 static HRESULT WINAPI d3d9_device_GetPixelShaderConstantB(IDirect3DDevice9Ex *iface, 3427 UINT reg_idx, BOOL *data, UINT count) 3428 { 3429 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3430 HRESULT hr; 3431 3432 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count); 3433 3434 wined3d_mutex_lock(); 3435 hr = wined3d_device_get_ps_consts_b(device->wined3d_device, reg_idx, count, data); 3436 wined3d_mutex_unlock(); 3437 3438 return hr; 3439 } 3440 3441 static HRESULT WINAPI d3d9_device_DrawRectPatch(IDirect3DDevice9Ex *iface, UINT handle, 3442 const float *segment_count, const D3DRECTPATCH_INFO *patch_info) 3443 { 3444 FIXME("iface %p, handle %#x, segment_count %p, patch_info %p unimplemented.\n", 3445 iface, handle, segment_count, patch_info); 3446 return D3D_OK; 3447 } 3448 3449 static HRESULT WINAPI d3d9_device_DrawTriPatch(IDirect3DDevice9Ex *iface, UINT handle, 3450 const float *segment_count, const D3DTRIPATCH_INFO *patch_info) 3451 { 3452 FIXME("iface %p, handle %#x, segment_count %p, patch_info %p unimplemented.\n", 3453 iface, handle, segment_count, patch_info); 3454 return D3D_OK; 3455 } 3456 3457 static HRESULT WINAPI d3d9_device_DeletePatch(IDirect3DDevice9Ex *iface, UINT handle) 3458 { 3459 FIXME("iface %p, handle %#x unimplemented.\n", iface, handle); 3460 return D3DERR_INVALIDCALL; 3461 } 3462 3463 static HRESULT WINAPI d3d9_device_CreateQuery(IDirect3DDevice9Ex *iface, D3DQUERYTYPE type, IDirect3DQuery9 **query) 3464 { 3465 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3466 struct d3d9_query *object; 3467 HRESULT hr; 3468 3469 TRACE("iface %p, type %#x, query %p.\n", iface, type, query); 3470 3471 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 3472 if (!object) 3473 return E_OUTOFMEMORY; 3474 3475 hr = query_init(object, device, type); 3476 if (FAILED(hr)) 3477 { 3478 WARN("Failed to initialize query, hr %#x.\n", hr); 3479 HeapFree(GetProcessHeap(), 0, object); 3480 return hr; 3481 } 3482 3483 TRACE("Created query %p.\n", object); 3484 if (query) *query = &object->IDirect3DQuery9_iface; 3485 else IDirect3DQuery9_Release(&object->IDirect3DQuery9_iface); 3486 3487 return D3D_OK; 3488 } 3489 3490 static HRESULT WINAPI d3d9_device_SetConvolutionMonoKernel(IDirect3DDevice9Ex *iface, 3491 UINT width, UINT height, float *rows, float *columns) 3492 { 3493 FIXME("iface %p, width %u, height %u, rows %p, columns %p stub!\n", 3494 iface, width, height, rows, columns); 3495 3496 return E_NOTIMPL; 3497 } 3498 3499 static HRESULT WINAPI d3d9_device_ComposeRects(IDirect3DDevice9Ex *iface, 3500 IDirect3DSurface9 *src_surface, IDirect3DSurface9 *dst_surface, IDirect3DVertexBuffer9 *src_descs, 3501 UINT rect_count, IDirect3DVertexBuffer9 *dst_descs, D3DCOMPOSERECTSOP operation, INT offset_x, INT offset_y) 3502 { 3503 FIXME("iface %p, src_surface %p, dst_surface %p, src_descs %p, rect_count %u, " 3504 "dst_descs %p, operation %#x, offset_x %u, offset_y %u stub!\n", 3505 iface, src_surface, dst_surface, src_descs, rect_count, 3506 dst_descs, operation, offset_x, offset_y); 3507 3508 return E_NOTIMPL; 3509 } 3510 3511 static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_PresentEx(IDirect3DDevice9Ex *iface, 3512 const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, 3513 const RGNDATA *dirty_region, DWORD flags) 3514 { 3515 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3516 UINT i; 3517 HRESULT hr; 3518 3519 TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n", 3520 iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), 3521 dst_window_override, dirty_region, flags); 3522 3523 if (device->device_state != D3D9_DEVICE_STATE_OK) 3524 return S_PRESENT_OCCLUDED; 3525 3526 if (dirty_region) 3527 FIXME("Ignoring dirty_region %p.\n", dirty_region); 3528 3529 wined3d_mutex_lock(); 3530 for (i = 0; i < device->implicit_swapchain_count; ++i) 3531 { 3532 if (FAILED(hr = wined3d_swapchain_present(device->implicit_swapchains[i]->wined3d_swapchain, 3533 src_rect, dst_rect, dst_window_override, flags))) 3534 { 3535 wined3d_mutex_unlock(); 3536 return hr; 3537 } 3538 } 3539 wined3d_mutex_unlock(); 3540 3541 return D3D_OK; 3542 } 3543 3544 static HRESULT WINAPI d3d9_device_GetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT *priority) 3545 { 3546 FIXME("iface %p, priority %p stub!\n", iface, priority); 3547 3548 return E_NOTIMPL; 3549 } 3550 3551 static HRESULT WINAPI d3d9_device_SetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT priority) 3552 { 3553 FIXME("iface %p, priority %d stub!\n", iface, priority); 3554 3555 return E_NOTIMPL; 3556 } 3557 3558 static HRESULT WINAPI d3d9_device_WaitForVBlank(IDirect3DDevice9Ex *iface, UINT swapchain_idx) 3559 { 3560 FIXME("iface %p, swapchain_idx %u stub!\n", iface, swapchain_idx); 3561 3562 return E_NOTIMPL; 3563 } 3564 3565 static HRESULT WINAPI d3d9_device_CheckResourceResidency(IDirect3DDevice9Ex *iface, 3566 IDirect3DResource9 **resources, UINT32 resource_count) 3567 { 3568 FIXME("iface %p, resources %p, resource_count %u stub!\n", 3569 iface, resources, resource_count); 3570 3571 return E_NOTIMPL; 3572 } 3573 3574 static HRESULT WINAPI d3d9_device_SetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT max_latency) 3575 { 3576 TRACE("iface %p, max_latency %u.\n", iface, max_latency); 3577 3578 if (max_latency) 3579 FIXME("Ignoring max_latency %u.\n", max_latency); 3580 3581 return S_OK; 3582 } 3583 3584 static HRESULT WINAPI d3d9_device_GetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT *max_latency) 3585 { 3586 FIXME("iface %p, max_latency %p stub!\n", iface, max_latency); 3587 3588 *max_latency = 2; 3589 3590 return E_NOTIMPL; 3591 } 3592 3593 static HRESULT WINAPI d3d9_device_CheckDeviceState(IDirect3DDevice9Ex *iface, HWND dst_window) 3594 { 3595 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3596 struct wined3d_swapchain_desc swapchain_desc; 3597 3598 TRACE("iface %p, dst_window %p.\n", iface, dst_window); 3599 3600 wined3d_mutex_lock(); 3601 wined3d_swapchain_get_desc(device->implicit_swapchains[0]->wined3d_swapchain, &swapchain_desc); 3602 wined3d_mutex_unlock(); 3603 3604 if (swapchain_desc.windowed) 3605 return D3D_OK; 3606 3607 /* FIXME: This is actually supposed to check if any other device is in 3608 * fullscreen mode. */ 3609 if (dst_window != swapchain_desc.device_window) 3610 return device->device_state == D3D9_DEVICE_STATE_OK ? S_PRESENT_OCCLUDED : D3D_OK; 3611 3612 return device->device_state == D3D9_DEVICE_STATE_OK ? D3D_OK : S_PRESENT_OCCLUDED; 3613 } 3614 3615 static HRESULT WINAPI d3d9_device_CreateRenderTargetEx(IDirect3DDevice9Ex *iface, 3616 UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, 3617 BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage) 3618 { 3619 FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u, " 3620 "lockable %#x, surface %p, shared_handle %p, usage %#x stub!\n", 3621 iface, width, height, format, multisample_type, multisample_quality, 3622 lockable, surface, shared_handle, usage); 3623 3624 *surface = NULL; 3625 if (shared_handle) 3626 FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); 3627 3628 return E_NOTIMPL; 3629 } 3630 3631 static HRESULT WINAPI d3d9_device_CreateOffscreenPlainSurfaceEx(IDirect3DDevice9Ex *iface, 3632 UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, 3633 HANDLE *shared_handle, DWORD usage) 3634 { 3635 FIXME("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p, usage %#x stub!\n", 3636 iface, width, height, format, pool, surface, shared_handle, usage); 3637 3638 return E_NOTIMPL; 3639 } 3640 3641 static HRESULT WINAPI d3d9_device_CreateDepthStencilSurfaceEx(IDirect3DDevice9Ex *iface, 3642 UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, 3643 BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage) 3644 { 3645 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3646 DWORD flags = WINED3D_TEXTURE_CREATE_MAPPABLE; 3647 3648 TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u, " 3649 "discard %#x, surface %p, shared_handle %p, usage %#x.\n", 3650 iface, width, height, format, multisample_type, multisample_quality, 3651 discard, surface, shared_handle, usage); 3652 3653 if (usage & D3DUSAGE_DEPTHSTENCIL) 3654 { 3655 WARN("Invalid usage %#x.\n", usage); 3656 return D3DERR_INVALIDCALL; 3657 } 3658 3659 if (shared_handle) 3660 FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); 3661 3662 if (discard) 3663 flags |= WINED3D_TEXTURE_CREATE_DISCARD; 3664 3665 *surface = NULL; 3666 return d3d9_device_create_surface(device, width, height, format, flags, surface, 3667 D3DUSAGE_DEPTHSTENCIL | usage, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); 3668 } 3669 3670 static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_ResetEx(IDirect3DDevice9Ex *iface, 3671 D3DPRESENT_PARAMETERS *present_parameters, D3DDISPLAYMODEEX *mode) 3672 { 3673 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3674 3675 TRACE("iface %p, present_parameters %p, mode %p.\n", iface, present_parameters, mode); 3676 3677 if (!present_parameters->Windowed == !mode) 3678 { 3679 WARN("Mode can be passed if and only if Windowed is FALSE.\n"); 3680 return D3DERR_INVALIDCALL; 3681 } 3682 3683 if (mode && (mode->Width != present_parameters->BackBufferWidth 3684 || mode->Height != present_parameters->BackBufferHeight)) 3685 { 3686 WARN("Mode and back buffer mismatch (mode %ux%u, backbuffer %ux%u).\n", 3687 mode->Width, mode->Height, 3688 present_parameters->BackBufferWidth, present_parameters->BackBufferHeight); 3689 return D3DERR_INVALIDCALL; 3690 } 3691 3692 return d3d9_device_reset(device, present_parameters, mode); 3693 } 3694 3695 static HRESULT WINAPI d3d9_device_GetDisplayModeEx(IDirect3DDevice9Ex *iface, 3696 UINT swapchain_idx, D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation) 3697 { 3698 struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); 3699 struct wined3d_display_mode wined3d_mode; 3700 HRESULT hr; 3701 3702 TRACE("iface %p, swapchain_idx %u, mode %p, rotation %p.\n", 3703 iface, swapchain_idx, mode, rotation); 3704 3705 if (mode->Size != sizeof(*mode)) 3706 return D3DERR_INVALIDCALL; 3707 3708 wined3d_mutex_lock(); 3709 hr = wined3d_device_get_display_mode(device->wined3d_device, swapchain_idx, &wined3d_mode, 3710 (enum wined3d_display_rotation *)rotation); 3711 wined3d_mutex_unlock(); 3712 3713 if (SUCCEEDED(hr)) 3714 { 3715 mode->Width = wined3d_mode.width; 3716 mode->Height = wined3d_mode.height; 3717 mode->RefreshRate = wined3d_mode.refresh_rate; 3718 mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id); 3719 mode->ScanLineOrdering = wined3d_mode.scanline_ordering; 3720 } 3721 3722 return hr; 3723 } 3724 3725 static const struct IDirect3DDevice9ExVtbl d3d9_device_vtbl = 3726 { 3727 /* IUnknown */ 3728 d3d9_device_QueryInterface, 3729 d3d9_device_AddRef, 3730 d3d9_device_Release, 3731 /* IDirect3DDevice9 */ 3732 d3d9_device_TestCooperativeLevel, 3733 d3d9_device_GetAvailableTextureMem, 3734 d3d9_device_EvictManagedResources, 3735 d3d9_device_GetDirect3D, 3736 d3d9_device_GetDeviceCaps, 3737 d3d9_device_GetDisplayMode, 3738 d3d9_device_GetCreationParameters, 3739 d3d9_device_SetCursorProperties, 3740 d3d9_device_SetCursorPosition, 3741 d3d9_device_ShowCursor, 3742 d3d9_device_CreateAdditionalSwapChain, 3743 d3d9_device_GetSwapChain, 3744 d3d9_device_GetNumberOfSwapChains, 3745 d3d9_device_Reset, 3746 d3d9_device_Present, 3747 d3d9_device_GetBackBuffer, 3748 d3d9_device_GetRasterStatus, 3749 d3d9_device_SetDialogBoxMode, 3750 d3d9_device_SetGammaRamp, 3751 d3d9_device_GetGammaRamp, 3752 d3d9_device_CreateTexture, 3753 d3d9_device_CreateVolumeTexture, 3754 d3d9_device_CreateCubeTexture, 3755 d3d9_device_CreateVertexBuffer, 3756 d3d9_device_CreateIndexBuffer, 3757 d3d9_device_CreateRenderTarget, 3758 d3d9_device_CreateDepthStencilSurface, 3759 d3d9_device_UpdateSurface, 3760 d3d9_device_UpdateTexture, 3761 d3d9_device_GetRenderTargetData, 3762 d3d9_device_GetFrontBufferData, 3763 d3d9_device_StretchRect, 3764 d3d9_device_ColorFill, 3765 d3d9_device_CreateOffscreenPlainSurface, 3766 d3d9_device_SetRenderTarget, 3767 d3d9_device_GetRenderTarget, 3768 d3d9_device_SetDepthStencilSurface, 3769 d3d9_device_GetDepthStencilSurface, 3770 d3d9_device_BeginScene, 3771 d3d9_device_EndScene, 3772 d3d9_device_Clear, 3773 d3d9_device_SetTransform, 3774 d3d9_device_GetTransform, 3775 d3d9_device_MultiplyTransform, 3776 d3d9_device_SetViewport, 3777 d3d9_device_GetViewport, 3778 d3d9_device_SetMaterial, 3779 d3d9_device_GetMaterial, 3780 d3d9_device_SetLight, 3781 d3d9_device_GetLight, 3782 d3d9_device_LightEnable, 3783 d3d9_device_GetLightEnable, 3784 d3d9_device_SetClipPlane, 3785 d3d9_device_GetClipPlane, 3786 d3d9_device_SetRenderState, 3787 d3d9_device_GetRenderState, 3788 d3d9_device_CreateStateBlock, 3789 d3d9_device_BeginStateBlock, 3790 d3d9_device_EndStateBlock, 3791 d3d9_device_SetClipStatus, 3792 d3d9_device_GetClipStatus, 3793 d3d9_device_GetTexture, 3794 d3d9_device_SetTexture, 3795 d3d9_device_GetTextureStageState, 3796 d3d9_device_SetTextureStageState, 3797 d3d9_device_GetSamplerState, 3798 d3d9_device_SetSamplerState, 3799 d3d9_device_ValidateDevice, 3800 d3d9_device_SetPaletteEntries, 3801 d3d9_device_GetPaletteEntries, 3802 d3d9_device_SetCurrentTexturePalette, 3803 d3d9_device_GetCurrentTexturePalette, 3804 d3d9_device_SetScissorRect, 3805 d3d9_device_GetScissorRect, 3806 d3d9_device_SetSoftwareVertexProcessing, 3807 d3d9_device_GetSoftwareVertexProcessing, 3808 d3d9_device_SetNPatchMode, 3809 d3d9_device_GetNPatchMode, 3810 d3d9_device_DrawPrimitive, 3811 d3d9_device_DrawIndexedPrimitive, 3812 d3d9_device_DrawPrimitiveUP, 3813 d3d9_device_DrawIndexedPrimitiveUP, 3814 d3d9_device_ProcessVertices, 3815 d3d9_device_CreateVertexDeclaration, 3816 d3d9_device_SetVertexDeclaration, 3817 d3d9_device_GetVertexDeclaration, 3818 d3d9_device_SetFVF, 3819 d3d9_device_GetFVF, 3820 d3d9_device_CreateVertexShader, 3821 d3d9_device_SetVertexShader, 3822 d3d9_device_GetVertexShader, 3823 d3d9_device_SetVertexShaderConstantF, 3824 d3d9_device_GetVertexShaderConstantF, 3825 d3d9_device_SetVertexShaderConstantI, 3826 d3d9_device_GetVertexShaderConstantI, 3827 d3d9_device_SetVertexShaderConstantB, 3828 d3d9_device_GetVertexShaderConstantB, 3829 d3d9_device_SetStreamSource, 3830 d3d9_device_GetStreamSource, 3831 d3d9_device_SetStreamSourceFreq, 3832 d3d9_device_GetStreamSourceFreq, 3833 d3d9_device_SetIndices, 3834 d3d9_device_GetIndices, 3835 d3d9_device_CreatePixelShader, 3836 d3d9_device_SetPixelShader, 3837 d3d9_device_GetPixelShader, 3838 d3d9_device_SetPixelShaderConstantF, 3839 d3d9_device_GetPixelShaderConstantF, 3840 d3d9_device_SetPixelShaderConstantI, 3841 d3d9_device_GetPixelShaderConstantI, 3842 d3d9_device_SetPixelShaderConstantB, 3843 d3d9_device_GetPixelShaderConstantB, 3844 d3d9_device_DrawRectPatch, 3845 d3d9_device_DrawTriPatch, 3846 d3d9_device_DeletePatch, 3847 d3d9_device_CreateQuery, 3848 /* IDirect3DDevice9Ex */ 3849 d3d9_device_SetConvolutionMonoKernel, 3850 d3d9_device_ComposeRects, 3851 d3d9_device_PresentEx, 3852 d3d9_device_GetGPUThreadPriority, 3853 d3d9_device_SetGPUThreadPriority, 3854 d3d9_device_WaitForVBlank, 3855 d3d9_device_CheckResourceResidency, 3856 d3d9_device_SetMaximumFrameLatency, 3857 d3d9_device_GetMaximumFrameLatency, 3858 d3d9_device_CheckDeviceState, 3859 d3d9_device_CreateRenderTargetEx, 3860 d3d9_device_CreateOffscreenPlainSurfaceEx, 3861 d3d9_device_CreateDepthStencilSurfaceEx, 3862 d3d9_device_ResetEx, 3863 d3d9_device_GetDisplayModeEx, 3864 }; 3865 3866 static inline struct d3d9_device *device_from_device_parent(struct wined3d_device_parent *device_parent) 3867 { 3868 return CONTAINING_RECORD(device_parent, struct d3d9_device, device_parent); 3869 } 3870 3871 static void CDECL device_parent_wined3d_device_created(struct wined3d_device_parent *device_parent, 3872 struct wined3d_device *device) 3873 { 3874 TRACE("device_parent %p, device %p.\n", device_parent, device); 3875 } 3876 3877 static void CDECL device_parent_mode_changed(struct wined3d_device_parent *device_parent) 3878 { 3879 TRACE("device_parent %p.\n", device_parent); 3880 } 3881 3882 static void CDECL device_parent_activate(struct wined3d_device_parent *device_parent, BOOL activate) 3883 { 3884 struct d3d9_device *device = device_from_device_parent(device_parent); 3885 3886 TRACE("device_parent %p, activate %#x.\n", device_parent, activate); 3887 3888 if (!device->d3d_parent) 3889 return; 3890 3891 if (!activate) 3892 InterlockedCompareExchange(&device->device_state, D3D9_DEVICE_STATE_LOST, D3D9_DEVICE_STATE_OK); 3893 else if (device->d3d_parent->extended) 3894 InterlockedCompareExchange(&device->device_state, D3D9_DEVICE_STATE_OK, D3D9_DEVICE_STATE_LOST); 3895 else 3896 InterlockedCompareExchange(&device->device_state, D3D9_DEVICE_STATE_NOT_RESET, D3D9_DEVICE_STATE_LOST); 3897 } 3898 3899 static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent, 3900 struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, 3901 void **parent, const struct wined3d_parent_ops **parent_ops) 3902 { 3903 struct d3d9_surface *d3d_surface; 3904 3905 TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", 3906 device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); 3907 3908 if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface)))) 3909 return E_OUTOFMEMORY; 3910 3911 surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); 3912 *parent = d3d_surface; 3913 TRACE("Created surface %p.\n", d3d_surface); 3914 3915 return D3D_OK; 3916 } 3917 3918 static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent, 3919 struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, 3920 void **parent, const struct wined3d_parent_ops **parent_ops) 3921 { 3922 struct d3d9_volume *d3d_volume; 3923 3924 TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", 3925 device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); 3926 3927 if (!(d3d_volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_volume)))) 3928 return E_OUTOFMEMORY; 3929 3930 volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops); 3931 *parent = d3d_volume; 3932 TRACE("Created volume %p.\n", d3d_volume); 3933 3934 return D3D_OK; 3935 } 3936 3937 static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent, 3938 void *container_parent, const struct wined3d_resource_desc *desc, DWORD texture_flags, 3939 struct wined3d_texture **texture) 3940 { 3941 struct d3d9_device *device = device_from_device_parent(device_parent); 3942 struct d3d9_surface *d3d_surface; 3943 HRESULT hr; 3944 3945 TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n", 3946 device_parent, container_parent, desc, texture_flags, texture); 3947 3948 if (container_parent == device_parent) 3949 container_parent = &device->IDirect3DDevice9Ex_iface; 3950 3951 if (is_gdi_compat_wined3dformat(desc->format)) 3952 texture_flags |= WINED3D_TEXTURE_CREATE_GET_DC; 3953 3954 if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1, 3955 texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, container_parent, 3956 &d3d9_null_wined3d_parent_ops, texture))) 3957 { 3958 WARN("Failed to create texture, hr %#x.\n", hr); 3959 return hr; 3960 } 3961 3962 d3d_surface = wined3d_texture_get_sub_resource_parent(*texture, 0); 3963 d3d_surface->parent_device = &device->IDirect3DDevice9Ex_iface; 3964 3965 return hr; 3966 } 3967 3968 static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, 3969 struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) 3970 { 3971 struct d3d9_device *device = device_from_device_parent(device_parent); 3972 struct d3d9_swapchain *d3d_swapchain; 3973 HRESULT hr; 3974 3975 TRACE("device_parent %p, desc %p, swapchain %p\n", device_parent, desc, swapchain); 3976 3977 hr = d3d9_swapchain_create(device, desc, &d3d_swapchain); 3978 if (FAILED(hr)) 3979 { 3980 WARN("Failed to create swapchain, hr %#x.\n", hr); 3981 *swapchain = NULL; 3982 return hr; 3983 } 3984 3985 *swapchain = d3d_swapchain->wined3d_swapchain; 3986 wined3d_swapchain_incref(*swapchain); 3987 IDirect3DSwapChain9Ex_Release(&d3d_swapchain->IDirect3DSwapChain9Ex_iface); 3988 3989 return hr; 3990 } 3991 3992 static const struct wined3d_device_parent_ops d3d9_wined3d_device_parent_ops = 3993 { 3994 device_parent_wined3d_device_created, 3995 device_parent_mode_changed, 3996 device_parent_activate, 3997 device_parent_surface_created, 3998 device_parent_volume_created, 3999 device_parent_create_swapchain_texture, 4000 device_parent_create_swapchain, 4001 }; 4002 4003 static void setup_fpu(void) 4004 { 4005 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) 4006 WORD cw; 4007 __asm__ volatile ("fnstcw %0" : "=m" (cw)); 4008 cw = (cw & ~0xf3f) | 0x3f; 4009 __asm__ volatile ("fldcw %0" : : "m" (cw)); 4010 #elif defined(__i386__) && defined(_MSC_VER) 4011 WORD cw; 4012 __asm fnstcw cw; 4013 cw = (cw & ~0xf3f) | 0x3f; 4014 __asm fldcw cw; 4015 #else 4016 FIXME("FPU setup not implemented for this platform.\n"); 4017 #endif 4018 } 4019 4020 HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wined3d *wined3d, 4021 UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags, 4022 D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode) 4023 { 4024 struct wined3d_swapchain_desc *swapchain_desc; 4025 unsigned i, count = 1; 4026 WINED3DCAPS caps; 4027 HRESULT hr; 4028 4029 if (mode) 4030 FIXME("Ignoring display mode.\n"); 4031 4032 device->IDirect3DDevice9Ex_iface.lpVtbl = &d3d9_device_vtbl; 4033 device->device_parent.ops = &d3d9_wined3d_device_parent_ops; 4034 device->refcount = 1; 4035 4036 if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu(); 4037 4038 wined3d_mutex_lock(); 4039 if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4, 4040 &device->device_parent, &device->wined3d_device))) 4041 { 4042 WARN("Failed to create wined3d device, hr %#x.\n", hr); 4043 wined3d_mutex_unlock(); 4044 return hr; 4045 } 4046 4047 wined3d_get_device_caps(wined3d, adapter, device_type, &caps); 4048 device->max_user_clip_planes = caps.MaxUserClipPlanes; 4049 if (flags & D3DCREATE_ADAPTERGROUP_DEVICE) 4050 count = caps.NumberOfAdaptersInGroup; 4051 4052 if (flags & D3DCREATE_MULTITHREADED) 4053 wined3d_device_set_multithreaded(device->wined3d_device); 4054 4055 if (!parameters->Windowed) 4056 { 4057 if (!focus_window) 4058 focus_window = parameters->hDeviceWindow; 4059 if (FAILED(hr = wined3d_device_acquire_focus_window(device->wined3d_device, focus_window))) 4060 { 4061 ERR("Failed to acquire focus window, hr %#x.\n", hr); 4062 wined3d_device_decref(device->wined3d_device); 4063 wined3d_mutex_unlock(); 4064 return hr; 4065 } 4066 4067 for (i = 0; i < count; ++i) 4068 { 4069 HWND device_window = parameters[i].hDeviceWindow; 4070 4071 if (!device_window) device_window = focus_window; 4072 wined3d_device_setup_fullscreen_window(device->wined3d_device, device_window, 4073 parameters[i].BackBufferWidth, 4074 parameters[i].BackBufferHeight); 4075 } 4076 } 4077 4078 swapchain_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain_desc) * count); 4079 if (!swapchain_desc) 4080 { 4081 ERR("Failed to allocate wined3d parameters.\n"); 4082 wined3d_device_release_focus_window(device->wined3d_device); 4083 wined3d_device_decref(device->wined3d_device); 4084 wined3d_mutex_unlock(); 4085 return E_OUTOFMEMORY; 4086 } 4087 4088 for (i = 0; i < count; ++i) 4089 { 4090 if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc[i], ¶meters[i], 4091 parent->extended)) 4092 { 4093 wined3d_device_release_focus_window(device->wined3d_device); 4094 wined3d_device_decref(device->wined3d_device); 4095 HeapFree(GetProcessHeap(), 0, swapchain_desc); 4096 wined3d_mutex_unlock(); 4097 return D3DERR_INVALIDCALL; 4098 } 4099 } 4100 4101 if (FAILED(hr = wined3d_device_init_3d(device->wined3d_device, swapchain_desc))) 4102 { 4103 WARN("Failed to initialize 3D, hr %#x.\n", hr); 4104 wined3d_device_release_focus_window(device->wined3d_device); 4105 HeapFree(GetProcessHeap(), 0, swapchain_desc); 4106 wined3d_device_decref(device->wined3d_device); 4107 wined3d_mutex_unlock(); 4108 return hr; 4109 } 4110 4111 wined3d_device_set_render_state(device->wined3d_device, 4112 WINED3D_RS_ZENABLE, !!swapchain_desc->enable_auto_depth_stencil); 4113 4114 if (FAILED(hr = d3d9_device_get_swapchains(device))) 4115 { 4116 wined3d_device_uninit_3d(device->wined3d_device); 4117 wined3d_device_release_focus_window(device->wined3d_device); 4118 wined3d_device_decref(device->wined3d_device); 4119 wined3d_mutex_unlock(); 4120 return E_OUTOFMEMORY; 4121 } 4122 4123 for (i = 0; i < count; ++i) 4124 { 4125 present_parameters_from_wined3d_swapchain_desc(¶meters[i], &swapchain_desc[i]); 4126 } 4127 4128 wined3d_mutex_unlock(); 4129 4130 HeapFree(GetProcessHeap(), 0, swapchain_desc); 4131 4132 /* Initialize the converted declaration array. This creates a valid pointer 4133 * and when adding decls HeapReAlloc() can be used without further checking. */ 4134 device->fvf_decls = HeapAlloc(GetProcessHeap(), 0, 0); 4135 if (!device->fvf_decls) 4136 { 4137 ERR("Failed to allocate FVF vertex declaration map memory.\n"); 4138 wined3d_mutex_lock(); 4139 HeapFree(GetProcessHeap(), 0, device->implicit_swapchains); 4140 wined3d_device_uninit_3d(device->wined3d_device); 4141 wined3d_device_release_focus_window(device->wined3d_device); 4142 wined3d_device_decref(device->wined3d_device); 4143 wined3d_mutex_unlock(); 4144 return E_OUTOFMEMORY; 4145 } 4146 4147 IDirect3D9Ex_AddRef(&parent->IDirect3D9Ex_iface); 4148 device->d3d_parent = parent; 4149 4150 return D3D_OK; 4151 } 4152