1c2c66affSColin Finck /* 2c2c66affSColin Finck * IDirect3DDevice8 implementation 3c2c66affSColin Finck * 4c2c66affSColin Finck * Copyright 2002-2004 Jason Edmeades 5c2c66affSColin Finck * Copyright 2004 Christian Costa 6c2c66affSColin Finck * 7c2c66affSColin Finck * This library is free software; you can redistribute it and/or 8c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public 9c2c66affSColin Finck * License as published by the Free Software Foundation; either 10c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version. 11c2c66affSColin Finck * 12c2c66affSColin Finck * This library is distributed in the hope that it will be useful, 13c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 14c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15c2c66affSColin Finck * Lesser General Public License for more details. 16c2c66affSColin Finck * 17c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public 18c2c66affSColin Finck * License along with this library; if not, write to the Free Software 19c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20c2c66affSColin Finck */ 21c2c66affSColin Finck 22c2c66affSColin Finck #include "d3d8_private.h" 23c2c66affSColin Finck 24c2c66affSColin Finck static void STDMETHODCALLTYPE d3d8_null_wined3d_object_destroyed(void *parent) {} 25c2c66affSColin Finck 26c2c66affSColin Finck static const struct wined3d_parent_ops d3d8_null_wined3d_parent_ops = 27c2c66affSColin Finck { 28c2c66affSColin Finck d3d8_null_wined3d_object_destroyed, 29c2c66affSColin Finck }; 30c2c66affSColin Finck 31c2c66affSColin Finck D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) 32c2c66affSColin Finck { 33c2c66affSColin Finck BYTE *c = (BYTE *)&format; 34c2c66affSColin Finck 35c2c66affSColin Finck /* Don't translate FOURCC formats */ 36c2c66affSColin Finck if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format; 37c2c66affSColin Finck 38c2c66affSColin Finck switch(format) 39c2c66affSColin Finck { 40c2c66affSColin Finck case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN; 41c2c66affSColin Finck case WINED3DFMT_B8G8R8_UNORM: return D3DFMT_R8G8B8; 42c2c66affSColin Finck case WINED3DFMT_B8G8R8A8_UNORM: return D3DFMT_A8R8G8B8; 43c2c66affSColin Finck case WINED3DFMT_B8G8R8X8_UNORM: return D3DFMT_X8R8G8B8; 44c2c66affSColin Finck case WINED3DFMT_B5G6R5_UNORM: return D3DFMT_R5G6B5; 45c2c66affSColin Finck case WINED3DFMT_B5G5R5X1_UNORM: return D3DFMT_X1R5G5B5; 46c2c66affSColin Finck case WINED3DFMT_B5G5R5A1_UNORM: return D3DFMT_A1R5G5B5; 47c2c66affSColin Finck case WINED3DFMT_B4G4R4A4_UNORM: return D3DFMT_A4R4G4B4; 48c2c66affSColin Finck case WINED3DFMT_B2G3R3_UNORM: return D3DFMT_R3G3B2; 49c2c66affSColin Finck case WINED3DFMT_A8_UNORM: return D3DFMT_A8; 50c2c66affSColin Finck case WINED3DFMT_B2G3R3A8_UNORM: return D3DFMT_A8R3G3B2; 51c2c66affSColin Finck case WINED3DFMT_B4G4R4X4_UNORM: return D3DFMT_X4R4G4B4; 52c2c66affSColin Finck case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10; 53c2c66affSColin Finck case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16; 54c2c66affSColin Finck case WINED3DFMT_P8_UINT_A8_UNORM: return D3DFMT_A8P8; 55c2c66affSColin Finck case WINED3DFMT_P8_UINT: return D3DFMT_P8; 56c2c66affSColin Finck case WINED3DFMT_L8_UNORM: return D3DFMT_L8; 57c2c66affSColin Finck case WINED3DFMT_L8A8_UNORM: return D3DFMT_A8L8; 58c2c66affSColin Finck case WINED3DFMT_L4A4_UNORM: return D3DFMT_A4L4; 59c2c66affSColin Finck case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8; 60c2c66affSColin Finck case WINED3DFMT_R5G5_SNORM_L6_UNORM: return D3DFMT_L6V5U5; 61c2c66affSColin Finck case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: return D3DFMT_X8L8V8U8; 62c2c66affSColin Finck case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8; 63c2c66affSColin Finck case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16; 64c2c66affSColin Finck case WINED3DFMT_R10G11B11_SNORM: return D3DFMT_W11V11U10; 65c2c66affSColin Finck case WINED3DFMT_R10G10B10_SNORM_A2_UNORM: return D3DFMT_A2W10V10U10; 66c2c66affSColin Finck case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE; 67c2c66affSColin Finck case WINED3DFMT_D32_UNORM: return D3DFMT_D32; 68c2c66affSColin Finck case WINED3DFMT_S1_UINT_D15_UNORM: return D3DFMT_D15S1; 69c2c66affSColin Finck case WINED3DFMT_D24_UNORM_S8_UINT: return D3DFMT_D24S8; 70c2c66affSColin Finck case WINED3DFMT_X8D24_UNORM: return D3DFMT_D24X8; 71c2c66affSColin Finck case WINED3DFMT_S4X4_UINT_D24_UNORM: return D3DFMT_D24X4S4; 72c2c66affSColin Finck case WINED3DFMT_D16_UNORM: return D3DFMT_D16; 73c2c66affSColin Finck case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16; 74c2c66affSColin Finck case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32; 75c2c66affSColin Finck default: 76c2c66affSColin Finck FIXME("Unhandled wined3d format %#x.\n", format); 77c2c66affSColin Finck return D3DFMT_UNKNOWN; 78c2c66affSColin Finck } 79c2c66affSColin Finck } 80c2c66affSColin Finck 81c2c66affSColin Finck enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) 82c2c66affSColin Finck { 83c2c66affSColin Finck BYTE *c = (BYTE *)&format; 84c2c66affSColin Finck 85c2c66affSColin Finck /* Don't translate FOURCC formats */ 86c2c66affSColin Finck if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format; 87c2c66affSColin Finck 88c2c66affSColin Finck switch(format) 89c2c66affSColin Finck { 90c2c66affSColin Finck case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN; 91c2c66affSColin Finck case D3DFMT_R8G8B8: return WINED3DFMT_B8G8R8_UNORM; 92c2c66affSColin Finck case D3DFMT_A8R8G8B8: return WINED3DFMT_B8G8R8A8_UNORM; 93c2c66affSColin Finck case D3DFMT_X8R8G8B8: return WINED3DFMT_B8G8R8X8_UNORM; 94c2c66affSColin Finck case D3DFMT_R5G6B5: return WINED3DFMT_B5G6R5_UNORM; 95c2c66affSColin Finck case D3DFMT_X1R5G5B5: return WINED3DFMT_B5G5R5X1_UNORM; 96c2c66affSColin Finck case D3DFMT_A1R5G5B5: return WINED3DFMT_B5G5R5A1_UNORM; 97c2c66affSColin Finck case D3DFMT_A4R4G4B4: return WINED3DFMT_B4G4R4A4_UNORM; 98c2c66affSColin Finck case D3DFMT_R3G3B2: return WINED3DFMT_B2G3R3_UNORM; 99c2c66affSColin Finck case D3DFMT_A8: return WINED3DFMT_A8_UNORM; 100c2c66affSColin Finck case D3DFMT_A8R3G3B2: return WINED3DFMT_B2G3R3A8_UNORM; 101c2c66affSColin Finck case D3DFMT_X4R4G4B4: return WINED3DFMT_B4G4R4X4_UNORM; 102c2c66affSColin Finck case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM; 103c2c66affSColin Finck case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM; 104c2c66affSColin Finck case D3DFMT_A8P8: return WINED3DFMT_P8_UINT_A8_UNORM; 105c2c66affSColin Finck case D3DFMT_P8: return WINED3DFMT_P8_UINT; 106c2c66affSColin Finck case D3DFMT_L8: return WINED3DFMT_L8_UNORM; 107c2c66affSColin Finck case D3DFMT_A8L8: return WINED3DFMT_L8A8_UNORM; 108c2c66affSColin Finck case D3DFMT_A4L4: return WINED3DFMT_L4A4_UNORM; 109c2c66affSColin Finck case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM; 110c2c66affSColin Finck case D3DFMT_L6V5U5: return WINED3DFMT_R5G5_SNORM_L6_UNORM; 111c2c66affSColin Finck case D3DFMT_X8L8V8U8: return WINED3DFMT_R8G8_SNORM_L8X8_UNORM; 112c2c66affSColin Finck case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM; 113c2c66affSColin Finck case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM; 114c2c66affSColin Finck case D3DFMT_W11V11U10: return WINED3DFMT_R10G11B11_SNORM; 115c2c66affSColin Finck case D3DFMT_A2W10V10U10: return WINED3DFMT_R10G10B10_SNORM_A2_UNORM; 116c2c66affSColin Finck case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE; 117c2c66affSColin Finck case D3DFMT_D32: return WINED3DFMT_D32_UNORM; 118c2c66affSColin Finck case D3DFMT_D15S1: return WINED3DFMT_S1_UINT_D15_UNORM; 119c2c66affSColin Finck case D3DFMT_D24S8: return WINED3DFMT_D24_UNORM_S8_UINT; 120c2c66affSColin Finck case D3DFMT_D24X8: return WINED3DFMT_X8D24_UNORM; 121c2c66affSColin Finck case D3DFMT_D24X4S4: return WINED3DFMT_S4X4_UINT_D24_UNORM; 122c2c66affSColin Finck case D3DFMT_D16: return WINED3DFMT_D16_UNORM; 123c2c66affSColin Finck case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT; 124c2c66affSColin Finck case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT; 125c2c66affSColin Finck default: 126c2c66affSColin Finck FIXME("Unhandled D3DFORMAT %#x.\n", format); 127c2c66affSColin Finck return WINED3DFMT_UNKNOWN; 128c2c66affSColin Finck } 129c2c66affSColin Finck } 130c2c66affSColin Finck 131c2c66affSColin Finck static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count) 132c2c66affSColin Finck { 133c2c66affSColin Finck switch (primitive_type) 134c2c66affSColin Finck { 135c2c66affSColin Finck case D3DPT_POINTLIST: 136c2c66affSColin Finck return primitive_count; 137c2c66affSColin Finck 138c2c66affSColin Finck case D3DPT_LINELIST: 139c2c66affSColin Finck return primitive_count * 2; 140c2c66affSColin Finck 141c2c66affSColin Finck case D3DPT_LINESTRIP: 142c2c66affSColin Finck return primitive_count + 1; 143c2c66affSColin Finck 144c2c66affSColin Finck case D3DPT_TRIANGLELIST: 145c2c66affSColin Finck return primitive_count * 3; 146c2c66affSColin Finck 147c2c66affSColin Finck case D3DPT_TRIANGLESTRIP: 148c2c66affSColin Finck case D3DPT_TRIANGLEFAN: 149c2c66affSColin Finck return primitive_count + 2; 150c2c66affSColin Finck 151c2c66affSColin Finck default: 152c2c66affSColin Finck FIXME("Unhandled primitive type %#x.\n", primitive_type); 153c2c66affSColin Finck return 0; 154c2c66affSColin Finck } 155c2c66affSColin Finck } 156c2c66affSColin Finck 157c2c66affSColin Finck static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters, 158c2c66affSColin Finck const struct wined3d_swapchain_desc *swapchain_desc) 159c2c66affSColin Finck { 160c2c66affSColin Finck present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width; 161c2c66affSColin Finck present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height; 162c2c66affSColin Finck present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc->backbuffer_format); 163c2c66affSColin Finck present_parameters->BackBufferCount = swapchain_desc->backbuffer_count; 164c2c66affSColin Finck present_parameters->MultiSampleType = swapchain_desc->multisample_type; 165c2c66affSColin Finck present_parameters->SwapEffect = swapchain_desc->swap_effect; 166c2c66affSColin Finck present_parameters->hDeviceWindow = swapchain_desc->device_window; 167c2c66affSColin Finck present_parameters->Windowed = swapchain_desc->windowed; 168c2c66affSColin Finck present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil; 169c2c66affSColin Finck present_parameters->AutoDepthStencilFormat 170c2c66affSColin Finck = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format); 171c2c66affSColin Finck present_parameters->Flags = swapchain_desc->flags & D3DPRESENTFLAGS_MASK; 172c2c66affSColin Finck present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate; 173c2c66affSColin Finck present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval; 174c2c66affSColin Finck } 175c2c66affSColin Finck 176c2c66affSColin Finck static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc, 177c2c66affSColin Finck const D3DPRESENT_PARAMETERS *present_parameters) 178c2c66affSColin Finck { 179c2c66affSColin Finck if (!present_parameters->SwapEffect || present_parameters->SwapEffect > D3DSWAPEFFECT_COPY_VSYNC) 180c2c66affSColin Finck { 181c2c66affSColin Finck WARN("Invalid swap effect %u passed.\n", present_parameters->SwapEffect); 182c2c66affSColin Finck return FALSE; 183c2c66affSColin Finck } 184c2c66affSColin Finck if (present_parameters->BackBufferCount > 3 185c2c66affSColin Finck || ((present_parameters->SwapEffect == D3DSWAPEFFECT_COPY 186c2c66affSColin Finck || present_parameters->SwapEffect == D3DSWAPEFFECT_COPY_VSYNC) 187c2c66affSColin Finck && present_parameters->BackBufferCount > 1)) 188c2c66affSColin Finck { 189c2c66affSColin Finck WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount); 190c2c66affSColin Finck return FALSE; 191c2c66affSColin Finck } 192c2c66affSColin Finck 193c2c66affSColin Finck swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth; 194c2c66affSColin Finck swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight; 195c2c66affSColin Finck swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat); 196c2c66affSColin Finck swapchain_desc->backbuffer_count = max(1, present_parameters->BackBufferCount); 197c2c66affSColin Finck swapchain_desc->multisample_type = present_parameters->MultiSampleType; 198c2c66affSColin Finck swapchain_desc->multisample_quality = 0; /* d3d9 only */ 199c2c66affSColin Finck swapchain_desc->swap_effect = present_parameters->SwapEffect; 200c2c66affSColin Finck swapchain_desc->device_window = present_parameters->hDeviceWindow; 201c2c66affSColin Finck swapchain_desc->windowed = present_parameters->Windowed; 202c2c66affSColin Finck swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil; 203c2c66affSColin Finck swapchain_desc->auto_depth_stencil_format 204c2c66affSColin Finck = wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat); 205c2c66affSColin Finck swapchain_desc->flags 206c2c66affSColin Finck = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH; 207c2c66affSColin Finck swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz; 208c2c66affSColin Finck swapchain_desc->swap_interval = present_parameters->FullScreen_PresentationInterval; 209c2c66affSColin Finck swapchain_desc->auto_restore_display_mode = TRUE; 210c2c66affSColin Finck 211c2c66affSColin Finck if (present_parameters->Flags & ~D3DPRESENTFLAGS_MASK) 212c2c66affSColin Finck FIXME("Unhandled flags %#x.\n", present_parameters->Flags & ~D3DPRESENTFLAGS_MASK); 213c2c66affSColin Finck 214c2c66affSColin Finck return TRUE; 215c2c66affSColin Finck } 216c2c66affSColin Finck 217c2c66affSColin Finck void d3dcaps_from_wined3dcaps(D3DCAPS8 *caps, const WINED3DCAPS *wined3d_caps) 218c2c66affSColin Finck { 219c2c66affSColin Finck caps->DeviceType = (D3DDEVTYPE)wined3d_caps->DeviceType; 220c2c66affSColin Finck caps->AdapterOrdinal = wined3d_caps->AdapterOrdinal; 221c2c66affSColin Finck caps->Caps = wined3d_caps->Caps; 222c2c66affSColin Finck caps->Caps2 = wined3d_caps->Caps2; 223c2c66affSColin Finck caps->Caps3 = wined3d_caps->Caps3; 224c2c66affSColin Finck caps->PresentationIntervals = wined3d_caps->PresentationIntervals; 225c2c66affSColin Finck caps->CursorCaps = wined3d_caps->CursorCaps; 226c2c66affSColin Finck caps->DevCaps = wined3d_caps->DevCaps; 227c2c66affSColin Finck caps->PrimitiveMiscCaps = wined3d_caps->PrimitiveMiscCaps; 228c2c66affSColin Finck caps->RasterCaps = wined3d_caps->RasterCaps; 229c2c66affSColin Finck caps->ZCmpCaps = wined3d_caps->ZCmpCaps; 230c2c66affSColin Finck caps->SrcBlendCaps = wined3d_caps->SrcBlendCaps; 231c2c66affSColin Finck caps->DestBlendCaps = wined3d_caps->DestBlendCaps; 232c2c66affSColin Finck caps->AlphaCmpCaps = wined3d_caps->AlphaCmpCaps; 233c2c66affSColin Finck caps->ShadeCaps = wined3d_caps->ShadeCaps; 234c2c66affSColin Finck caps->TextureCaps = wined3d_caps->TextureCaps; 235c2c66affSColin Finck caps->TextureFilterCaps = wined3d_caps->TextureFilterCaps; 236c2c66affSColin Finck caps->CubeTextureFilterCaps = wined3d_caps->CubeTextureFilterCaps; 237c2c66affSColin Finck caps->VolumeTextureFilterCaps = wined3d_caps->VolumeTextureFilterCaps; 238c2c66affSColin Finck caps->TextureAddressCaps = wined3d_caps->TextureAddressCaps; 239c2c66affSColin Finck caps->VolumeTextureAddressCaps = wined3d_caps->VolumeTextureAddressCaps; 240c2c66affSColin Finck caps->LineCaps = wined3d_caps->LineCaps; 241c2c66affSColin Finck caps->MaxTextureWidth = wined3d_caps->MaxTextureWidth; 242c2c66affSColin Finck caps->MaxTextureHeight = wined3d_caps->MaxTextureHeight; 243c2c66affSColin Finck caps->MaxVolumeExtent = wined3d_caps->MaxVolumeExtent; 244c2c66affSColin Finck caps->MaxTextureRepeat = wined3d_caps->MaxTextureRepeat; 245c2c66affSColin Finck caps->MaxTextureAspectRatio = wined3d_caps->MaxTextureAspectRatio; 246c2c66affSColin Finck caps->MaxAnisotropy = wined3d_caps->MaxAnisotropy; 247c2c66affSColin Finck caps->MaxVertexW = wined3d_caps->MaxVertexW; 248c2c66affSColin Finck caps->GuardBandLeft = wined3d_caps->GuardBandLeft; 249c2c66affSColin Finck caps->GuardBandTop = wined3d_caps->GuardBandTop; 250c2c66affSColin Finck caps->GuardBandRight = wined3d_caps->GuardBandRight; 251c2c66affSColin Finck caps->GuardBandBottom = wined3d_caps->GuardBandBottom; 252c2c66affSColin Finck caps->ExtentsAdjust = wined3d_caps->ExtentsAdjust; 253c2c66affSColin Finck caps->StencilCaps = wined3d_caps->StencilCaps; 254c2c66affSColin Finck caps->FVFCaps = wined3d_caps->FVFCaps; 255c2c66affSColin Finck caps->TextureOpCaps = wined3d_caps->TextureOpCaps; 256c2c66affSColin Finck caps->MaxTextureBlendStages = wined3d_caps->MaxTextureBlendStages; 257c2c66affSColin Finck caps->MaxSimultaneousTextures = wined3d_caps->MaxSimultaneousTextures; 258c2c66affSColin Finck caps->VertexProcessingCaps = wined3d_caps->VertexProcessingCaps; 259c2c66affSColin Finck caps->MaxActiveLights = wined3d_caps->MaxActiveLights; 260c2c66affSColin Finck caps->MaxUserClipPlanes = wined3d_caps->MaxUserClipPlanes; 261c2c66affSColin Finck caps->MaxVertexBlendMatrices = wined3d_caps->MaxVertexBlendMatrices; 262c2c66affSColin Finck caps->MaxVertexBlendMatrixIndex = wined3d_caps->MaxVertexBlendMatrixIndex; 263c2c66affSColin Finck caps->MaxPointSize = wined3d_caps->MaxPointSize; 264c2c66affSColin Finck caps->MaxPrimitiveCount = wined3d_caps->MaxPrimitiveCount; 265c2c66affSColin Finck caps->MaxVertexIndex = wined3d_caps->MaxVertexIndex; 266c2c66affSColin Finck caps->MaxStreams = wined3d_caps->MaxStreams; 267c2c66affSColin Finck caps->MaxStreamStride = wined3d_caps->MaxStreamStride; 268c2c66affSColin Finck caps->VertexShaderVersion = wined3d_caps->VertexShaderVersion; 269c2c66affSColin Finck caps->MaxVertexShaderConst = wined3d_caps->MaxVertexShaderConst; 270c2c66affSColin Finck caps->PixelShaderVersion = wined3d_caps->PixelShaderVersion; 271c2c66affSColin Finck caps->MaxPixelShaderValue = wined3d_caps->PixelShader1xMaxValue; 272c2c66affSColin Finck 273c2c66affSColin Finck /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */ 274c2c66affSColin Finck if (caps->PixelShaderVersion) 275c2c66affSColin Finck caps->PixelShaderVersion = D3DPS_VERSION(1, 4); 276c2c66affSColin Finck else 277c2c66affSColin Finck caps->PixelShaderVersion = D3DPS_VERSION(0, 0); 278c2c66affSColin Finck if (caps->VertexShaderVersion) 279c2c66affSColin Finck caps->VertexShaderVersion = D3DVS_VERSION(1, 1); 280c2c66affSColin Finck else 281c2c66affSColin Finck caps->VertexShaderVersion = D3DVS_VERSION(0, 0); 282c2c66affSColin Finck caps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst); 283c2c66affSColin Finck 284c2c66affSColin Finck caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED; 285c2c66affSColin Finck } 286c2c66affSColin Finck 287c2c66affSColin Finck /* Handle table functions */ 288c2c66affSColin Finck static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object, enum d3d8_handle_type type) 289c2c66affSColin Finck { 290c2c66affSColin Finck struct d3d8_handle_entry *entry; 291c2c66affSColin Finck 292c2c66affSColin Finck if (t->free_entries) 293c2c66affSColin Finck { 294c2c66affSColin Finck DWORD index = t->free_entries - t->entries; 295c2c66affSColin Finck /* Use a free handle */ 296c2c66affSColin Finck entry = t->free_entries; 297c2c66affSColin Finck if (entry->type != D3D8_HANDLE_FREE) 298c2c66affSColin Finck { 299c2c66affSColin Finck ERR("Handle %u(%p) is in the free list, but has type %#x.\n", index, entry, entry->type); 300c2c66affSColin Finck return D3D8_INVALID_HANDLE; 301c2c66affSColin Finck } 302c2c66affSColin Finck t->free_entries = entry->object; 303c2c66affSColin Finck entry->object = object; 304c2c66affSColin Finck entry->type = type; 305c2c66affSColin Finck 306c2c66affSColin Finck return index; 307c2c66affSColin Finck } 308c2c66affSColin Finck 309c2c66affSColin Finck if (!(t->entry_count < t->table_size)) 310c2c66affSColin Finck { 311c2c66affSColin Finck /* Grow the table */ 312c2c66affSColin Finck UINT new_size = t->table_size + (t->table_size >> 1); 313c2c66affSColin Finck struct d3d8_handle_entry *new_entries = HeapReAlloc(GetProcessHeap(), 314c2c66affSColin Finck 0, t->entries, new_size * sizeof(*t->entries)); 315c2c66affSColin Finck if (!new_entries) 316c2c66affSColin Finck { 317c2c66affSColin Finck ERR("Failed to grow the handle table.\n"); 318c2c66affSColin Finck return D3D8_INVALID_HANDLE; 319c2c66affSColin Finck } 320c2c66affSColin Finck t->entries = new_entries; 321c2c66affSColin Finck t->table_size = new_size; 322c2c66affSColin Finck } 323c2c66affSColin Finck 324c2c66affSColin Finck entry = &t->entries[t->entry_count]; 325c2c66affSColin Finck entry->object = object; 326c2c66affSColin Finck entry->type = type; 327c2c66affSColin Finck 328c2c66affSColin Finck return t->entry_count++; 329c2c66affSColin Finck } 330c2c66affSColin Finck 331c2c66affSColin Finck static void *d3d8_free_handle(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type) 332c2c66affSColin Finck { 333c2c66affSColin Finck struct d3d8_handle_entry *entry; 334c2c66affSColin Finck void *object; 335c2c66affSColin Finck 336c2c66affSColin Finck if (handle == D3D8_INVALID_HANDLE || handle >= t->entry_count) 337c2c66affSColin Finck { 338c2c66affSColin Finck WARN("Invalid handle %u passed.\n", handle); 339c2c66affSColin Finck return NULL; 340c2c66affSColin Finck } 341c2c66affSColin Finck 342c2c66affSColin Finck entry = &t->entries[handle]; 343c2c66affSColin Finck if (entry->type != type) 344c2c66affSColin Finck { 345c2c66affSColin Finck WARN("Handle %u(%p) is not of type %#x.\n", handle, entry, type); 346c2c66affSColin Finck return NULL; 347c2c66affSColin Finck } 348c2c66affSColin Finck 349c2c66affSColin Finck object = entry->object; 350c2c66affSColin Finck entry->object = t->free_entries; 351c2c66affSColin Finck entry->type = D3D8_HANDLE_FREE; 352c2c66affSColin Finck t->free_entries = entry; 353c2c66affSColin Finck 354c2c66affSColin Finck return object; 355c2c66affSColin Finck } 356c2c66affSColin Finck 357c2c66affSColin Finck static void *d3d8_get_object(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type) 358c2c66affSColin Finck { 359c2c66affSColin Finck struct d3d8_handle_entry *entry; 360c2c66affSColin Finck 361c2c66affSColin Finck if (handle == D3D8_INVALID_HANDLE || handle >= t->entry_count) 362c2c66affSColin Finck { 363c2c66affSColin Finck WARN("Invalid handle %u passed.\n", handle); 364c2c66affSColin Finck return NULL; 365c2c66affSColin Finck } 366c2c66affSColin Finck 367c2c66affSColin Finck entry = &t->entries[handle]; 368c2c66affSColin Finck if (entry->type != type) 369c2c66affSColin Finck { 370c2c66affSColin Finck WARN("Handle %u(%p) is not of type %#x.\n", handle, entry, type); 371c2c66affSColin Finck return NULL; 372c2c66affSColin Finck } 373c2c66affSColin Finck 374c2c66affSColin Finck return entry->object; 375c2c66affSColin Finck } 376c2c66affSColin Finck 377c2c66affSColin Finck static HRESULT WINAPI d3d8_device_QueryInterface(IDirect3DDevice8 *iface, REFIID riid, void **out) 378c2c66affSColin Finck { 379c2c66affSColin Finck TRACE("iface %p, riid %s, out %p.\n", 380c2c66affSColin Finck iface, debugstr_guid(riid), out); 381c2c66affSColin Finck 382c2c66affSColin Finck if (IsEqualGUID(riid, &IID_IDirect3DDevice8) 383c2c66affSColin Finck || IsEqualGUID(riid, &IID_IUnknown)) 384c2c66affSColin Finck { 385c2c66affSColin Finck IDirect3DDevice8_AddRef(iface); 386c2c66affSColin Finck *out = iface; 387c2c66affSColin Finck return S_OK; 388c2c66affSColin Finck } 389c2c66affSColin Finck 390c2c66affSColin Finck WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 391c2c66affSColin Finck 392c2c66affSColin Finck *out = NULL; 393c2c66affSColin Finck return E_NOINTERFACE; 394c2c66affSColin Finck } 395c2c66affSColin Finck 396c2c66affSColin Finck static ULONG WINAPI d3d8_device_AddRef(IDirect3DDevice8 *iface) 397c2c66affSColin Finck { 398c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 399c2c66affSColin Finck ULONG ref = InterlockedIncrement(&device->ref); 400c2c66affSColin Finck 401c2c66affSColin Finck TRACE("%p increasing refcount to %u.\n", iface, ref); 402c2c66affSColin Finck 403c2c66affSColin Finck return ref; 404c2c66affSColin Finck } 405c2c66affSColin Finck 406c2c66affSColin Finck static ULONG WINAPI d3d8_device_Release(IDirect3DDevice8 *iface) 407c2c66affSColin Finck { 408c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 409c2c66affSColin Finck ULONG ref; 410c2c66affSColin Finck 411c2c66affSColin Finck if (device->inDestruction) 412c2c66affSColin Finck return 0; 413c2c66affSColin Finck 414c2c66affSColin Finck ref = InterlockedDecrement(&device->ref); 415c2c66affSColin Finck 416c2c66affSColin Finck TRACE("%p decreasing refcount to %u.\n", iface, ref); 417c2c66affSColin Finck 418c2c66affSColin Finck if (!ref) 419c2c66affSColin Finck { 420c2c66affSColin Finck IDirect3D8 *parent = device->d3d_parent; 421c2c66affSColin Finck unsigned i; 422c2c66affSColin Finck 423c2c66affSColin Finck TRACE("Releasing wined3d device %p.\n", device->wined3d_device); 424c2c66affSColin Finck 425c2c66affSColin Finck wined3d_mutex_lock(); 426c2c66affSColin Finck 427c2c66affSColin Finck device->inDestruction = TRUE; 428c2c66affSColin Finck 429c2c66affSColin Finck for (i = 0; i < device->numConvertedDecls; ++i) 430c2c66affSColin Finck { 431c2c66affSColin Finck d3d8_vertex_declaration_destroy(device->decls[i].declaration); 432c2c66affSColin Finck } 433c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, device->decls); 434c2c66affSColin Finck 435c2c66affSColin Finck if (device->vertex_buffer) 436c2c66affSColin Finck wined3d_buffer_decref(device->vertex_buffer); 437c2c66affSColin Finck if (device->index_buffer) 438c2c66affSColin Finck wined3d_buffer_decref(device->index_buffer); 439c2c66affSColin Finck 440c2c66affSColin Finck wined3d_device_uninit_3d(device->wined3d_device); 441c2c66affSColin Finck wined3d_device_release_focus_window(device->wined3d_device); 442c2c66affSColin Finck wined3d_device_decref(device->wined3d_device); 443c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, device->handle_table.entries); 444c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, device); 445c2c66affSColin Finck 446c2c66affSColin Finck wined3d_mutex_unlock(); 447c2c66affSColin Finck 448c2c66affSColin Finck IDirect3D8_Release(parent); 449c2c66affSColin Finck } 450c2c66affSColin Finck return ref; 451c2c66affSColin Finck } 452c2c66affSColin Finck 453c2c66affSColin Finck static HRESULT WINAPI d3d8_device_TestCooperativeLevel(IDirect3DDevice8 *iface) 454c2c66affSColin Finck { 455c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 456c2c66affSColin Finck 457c2c66affSColin Finck TRACE("iface %p.\n", iface); 458c2c66affSColin Finck 459c2c66affSColin Finck TRACE("device state: %#x.\n", device->device_state); 460c2c66affSColin Finck 461c2c66affSColin Finck switch (device->device_state) 462c2c66affSColin Finck { 463c2c66affSColin Finck default: 464c2c66affSColin Finck case D3D8_DEVICE_STATE_OK: 465c2c66affSColin Finck return D3D_OK; 466c2c66affSColin Finck case D3D8_DEVICE_STATE_LOST: 467c2c66affSColin Finck return D3DERR_DEVICELOST; 468c2c66affSColin Finck case D3D8_DEVICE_STATE_NOT_RESET: 469c2c66affSColin Finck return D3DERR_DEVICENOTRESET; 470c2c66affSColin Finck } 471c2c66affSColin Finck } 472c2c66affSColin Finck 473c2c66affSColin Finck static UINT WINAPI d3d8_device_GetAvailableTextureMem(IDirect3DDevice8 *iface) 474c2c66affSColin Finck { 475c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 476c2c66affSColin Finck UINT ret; 477c2c66affSColin Finck 478c2c66affSColin Finck TRACE("iface %p.\n", iface); 479c2c66affSColin Finck 480c2c66affSColin Finck wined3d_mutex_lock(); 481c2c66affSColin Finck ret = wined3d_device_get_available_texture_mem(device->wined3d_device); 482c2c66affSColin Finck wined3d_mutex_unlock(); 483c2c66affSColin Finck 484c2c66affSColin Finck return ret; 485c2c66affSColin Finck } 486c2c66affSColin Finck 487c2c66affSColin Finck static HRESULT WINAPI d3d8_device_ResourceManagerDiscardBytes(IDirect3DDevice8 *iface, DWORD byte_count) 488c2c66affSColin Finck { 489c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 490c2c66affSColin Finck 491c2c66affSColin Finck TRACE("iface %p, byte_count %u.\n", iface, byte_count); 492c2c66affSColin Finck 493c2c66affSColin Finck if (byte_count) 494c2c66affSColin Finck FIXME("Byte count ignored.\n"); 495c2c66affSColin Finck 496c2c66affSColin Finck wined3d_mutex_lock(); 497c2c66affSColin Finck wined3d_device_evict_managed_resources(device->wined3d_device); 498c2c66affSColin Finck wined3d_mutex_unlock(); 499c2c66affSColin Finck 500c2c66affSColin Finck return D3D_OK; 501c2c66affSColin Finck } 502c2c66affSColin Finck 503c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetDirect3D(IDirect3DDevice8 *iface, IDirect3D8 **d3d8) 504c2c66affSColin Finck { 505c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 506c2c66affSColin Finck 507c2c66affSColin Finck TRACE("iface %p, d3d8 %p.\n", iface, d3d8); 508c2c66affSColin Finck 509c2c66affSColin Finck if (!d3d8) 510c2c66affSColin Finck return D3DERR_INVALIDCALL; 511c2c66affSColin Finck 512c2c66affSColin Finck return IDirect3D8_QueryInterface(device->d3d_parent, &IID_IDirect3D8, (void **)d3d8); 513c2c66affSColin Finck } 514c2c66affSColin Finck 515c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetDeviceCaps(IDirect3DDevice8 *iface, D3DCAPS8 *caps) 516c2c66affSColin Finck { 517c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 518c2c66affSColin Finck WINED3DCAPS wined3d_caps; 519c2c66affSColin Finck HRESULT hr; 520c2c66affSColin Finck 521c2c66affSColin Finck TRACE("iface %p, caps %p.\n", iface, caps); 522c2c66affSColin Finck 523c2c66affSColin Finck if (!caps) 524c2c66affSColin Finck return D3DERR_INVALIDCALL; 525c2c66affSColin Finck 526c2c66affSColin Finck wined3d_mutex_lock(); 527c2c66affSColin Finck hr = wined3d_device_get_device_caps(device->wined3d_device, &wined3d_caps); 528c2c66affSColin Finck wined3d_mutex_unlock(); 529c2c66affSColin Finck 530c2c66affSColin Finck d3dcaps_from_wined3dcaps(caps, &wined3d_caps); 531c2c66affSColin Finck 532c2c66affSColin Finck return hr; 533c2c66affSColin Finck } 534c2c66affSColin Finck 535c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetDisplayMode(IDirect3DDevice8 *iface, D3DDISPLAYMODE *mode) 536c2c66affSColin Finck { 537c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 538c2c66affSColin Finck struct wined3d_display_mode wined3d_mode; 539c2c66affSColin Finck HRESULT hr; 540c2c66affSColin Finck 541c2c66affSColin Finck TRACE("iface %p, mode %p.\n", iface, mode); 542c2c66affSColin Finck 543c2c66affSColin Finck wined3d_mutex_lock(); 544c2c66affSColin Finck hr = wined3d_device_get_display_mode(device->wined3d_device, 0, &wined3d_mode, NULL); 545c2c66affSColin Finck wined3d_mutex_unlock(); 546c2c66affSColin Finck 547c2c66affSColin Finck if (SUCCEEDED(hr)) 548c2c66affSColin Finck { 549c2c66affSColin Finck mode->Width = wined3d_mode.width; 550c2c66affSColin Finck mode->Height = wined3d_mode.height; 551c2c66affSColin Finck mode->RefreshRate = wined3d_mode.refresh_rate; 552c2c66affSColin Finck mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id); 553c2c66affSColin Finck } 554c2c66affSColin Finck 555c2c66affSColin Finck return hr; 556c2c66affSColin Finck } 557c2c66affSColin Finck 558c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetCreationParameters(IDirect3DDevice8 *iface, 559c2c66affSColin Finck D3DDEVICE_CREATION_PARAMETERS *parameters) 560c2c66affSColin Finck { 561c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 562c2c66affSColin Finck 563c2c66affSColin Finck TRACE("iface %p, parameters %p.\n", iface, parameters); 564c2c66affSColin Finck 565c2c66affSColin Finck wined3d_mutex_lock(); 566c2c66affSColin Finck wined3d_device_get_creation_parameters(device->wined3d_device, 567c2c66affSColin Finck (struct wined3d_device_creation_parameters *)parameters); 568c2c66affSColin Finck wined3d_mutex_unlock(); 569c2c66affSColin Finck 570c2c66affSColin Finck return D3D_OK; 571c2c66affSColin Finck } 572c2c66affSColin Finck 573c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetCursorProperties(IDirect3DDevice8 *iface, 574c2c66affSColin Finck UINT hotspot_x, UINT hotspot_y, IDirect3DSurface8 *bitmap) 575c2c66affSColin Finck { 576c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 577c2c66affSColin Finck struct d3d8_surface *bitmap_impl = unsafe_impl_from_IDirect3DSurface8(bitmap); 578c2c66affSColin Finck HRESULT hr; 579c2c66affSColin Finck 580c2c66affSColin Finck TRACE("iface %p, hotspot_x %u, hotspot_y %u, bitmap %p.\n", 581c2c66affSColin Finck iface, hotspot_x, hotspot_y, bitmap); 582c2c66affSColin Finck 583c2c66affSColin Finck if (!bitmap) 584c2c66affSColin Finck { 585c2c66affSColin Finck WARN("No cursor bitmap, returning D3DERR_INVALIDCALL.\n"); 586c2c66affSColin Finck return D3DERR_INVALIDCALL; 587c2c66affSColin Finck } 588c2c66affSColin Finck 589c2c66affSColin Finck wined3d_mutex_lock(); 590c2c66affSColin Finck hr = wined3d_device_set_cursor_properties(device->wined3d_device, 591c2c66affSColin Finck hotspot_x, hotspot_y, bitmap_impl->wined3d_texture, bitmap_impl->sub_resource_idx); 592c2c66affSColin Finck wined3d_mutex_unlock(); 593c2c66affSColin Finck 594c2c66affSColin Finck return hr; 595c2c66affSColin Finck } 596c2c66affSColin Finck 597c2c66affSColin Finck static void WINAPI d3d8_device_SetCursorPosition(IDirect3DDevice8 *iface, UINT x, UINT y, DWORD flags) 598c2c66affSColin Finck { 599c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 600c2c66affSColin Finck 601c2c66affSColin Finck TRACE("iface %p, x %u, y %u, flags %#x.\n", iface, x, y, flags); 602c2c66affSColin Finck 603c2c66affSColin Finck wined3d_mutex_lock(); 604c2c66affSColin Finck wined3d_device_set_cursor_position(device->wined3d_device, x, y, flags); 605c2c66affSColin Finck wined3d_mutex_unlock(); 606c2c66affSColin Finck } 607c2c66affSColin Finck 608c2c66affSColin Finck static BOOL WINAPI d3d8_device_ShowCursor(IDirect3DDevice8 *iface, BOOL show) 609c2c66affSColin Finck { 610c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 611c2c66affSColin Finck BOOL ret; 612c2c66affSColin Finck 613c2c66affSColin Finck TRACE("iface %p, show %#x.\n", iface, show); 614c2c66affSColin Finck 615c2c66affSColin Finck wined3d_mutex_lock(); 616c2c66affSColin Finck ret = wined3d_device_show_cursor(device->wined3d_device, show); 617c2c66affSColin Finck wined3d_mutex_unlock(); 618c2c66affSColin Finck 619c2c66affSColin Finck return ret; 620c2c66affSColin Finck } 621c2c66affSColin Finck 622c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *iface, 623c2c66affSColin Finck D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain8 **swapchain) 624c2c66affSColin Finck { 625c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 626c2c66affSColin Finck struct wined3d_swapchain_desc desc; 627c2c66affSColin Finck struct d3d8_swapchain *object; 628c2c66affSColin Finck UINT i, count; 629c2c66affSColin Finck HRESULT hr; 630c2c66affSColin Finck 631c2c66affSColin Finck TRACE("iface %p, present_parameters %p, swapchain %p.\n", 632c2c66affSColin Finck iface, present_parameters, swapchain); 633c2c66affSColin Finck 634c2c66affSColin Finck if (!present_parameters->Windowed) 635c2c66affSColin Finck { 636c2c66affSColin Finck WARN("Trying to create an additional fullscreen swapchain, returning D3DERR_INVALIDCALL.\n"); 637c2c66affSColin Finck return D3DERR_INVALIDCALL; 638c2c66affSColin Finck } 639c2c66affSColin Finck 640c2c66affSColin Finck wined3d_mutex_lock(); 641c2c66affSColin Finck count = wined3d_device_get_swapchain_count(device->wined3d_device); 642c2c66affSColin Finck for (i = 0; i < count; ++i) 643c2c66affSColin Finck { 644c2c66affSColin Finck struct wined3d_swapchain *wined3d_swapchain; 645c2c66affSColin Finck 646c2c66affSColin Finck wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, i); 647c2c66affSColin Finck wined3d_swapchain_get_desc(wined3d_swapchain, &desc); 648c2c66affSColin Finck 649c2c66affSColin Finck if (!desc.windowed) 650c2c66affSColin Finck { 651c2c66affSColin Finck wined3d_mutex_unlock(); 652c2c66affSColin Finck WARN("Trying to create an additional swapchain in fullscreen mode, returning D3DERR_INVALIDCALL.\n"); 653c2c66affSColin Finck return D3DERR_INVALIDCALL; 654c2c66affSColin Finck } 655c2c66affSColin Finck } 656c2c66affSColin Finck wined3d_mutex_unlock(); 657c2c66affSColin Finck 658c2c66affSColin Finck if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters)) 659c2c66affSColin Finck return D3DERR_INVALIDCALL; 660c2c66affSColin Finck if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, &object))) 661c2c66affSColin Finck *swapchain = &object->IDirect3DSwapChain8_iface; 662c2c66affSColin Finck present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc); 663c2c66affSColin Finck 664c2c66affSColin Finck return hr; 665c2c66affSColin Finck } 666c2c66affSColin Finck 667c2c66affSColin Finck static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) 668c2c66affSColin Finck { 669c2c66affSColin Finck struct wined3d_resource_desc desc; 670c2c66affSColin Finck IDirect3DBaseTexture8 *texture; 671c2c66affSColin Finck struct d3d8_surface *surface; 672c2c66affSColin Finck IUnknown *parent; 673c2c66affSColin Finck 674c2c66affSColin Finck wined3d_resource_get_desc(resource, &desc); 675c2c66affSColin Finck if (desc.pool != WINED3D_POOL_DEFAULT) 676c2c66affSColin Finck return D3D_OK; 677c2c66affSColin Finck 678c2c66affSColin Finck if (desc.resource_type != WINED3D_RTYPE_TEXTURE_2D) 679c2c66affSColin Finck { 680c2c66affSColin Finck WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource); 681c2c66affSColin Finck return D3DERR_DEVICELOST; 682c2c66affSColin Finck } 683c2c66affSColin Finck 684c2c66affSColin Finck parent = wined3d_resource_get_parent(resource); 685c2c66affSColin Finck if (parent && SUCCEEDED(IUnknown_QueryInterface(parent, &IID_IDirect3DBaseTexture8, (void **)&texture))) 686c2c66affSColin Finck { 687c2c66affSColin Finck IDirect3DBaseTexture8_Release(texture); 688c2c66affSColin Finck WARN("Texture %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", texture, resource); 689c2c66affSColin Finck return D3DERR_DEVICELOST; 690c2c66affSColin Finck } 691c2c66affSColin Finck 692c2c66affSColin Finck surface = wined3d_texture_get_sub_resource_parent(wined3d_texture_from_resource(resource), 0); 693c2c66affSColin Finck if (!surface->resource.refcount) 694c2c66affSColin Finck return D3D_OK; 695c2c66affSColin Finck 696c2c66affSColin Finck WARN("Surface %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface); 697c2c66affSColin Finck return D3DERR_DEVICELOST; 698c2c66affSColin Finck } 699c2c66affSColin Finck 700c2c66affSColin Finck static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, 701c2c66affSColin Finck D3DPRESENT_PARAMETERS *present_parameters) 702c2c66affSColin Finck { 703c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 704c2c66affSColin Finck struct wined3d_swapchain_desc swapchain_desc; 705c2c66affSColin Finck HRESULT hr; 706c2c66affSColin Finck 707c2c66affSColin Finck TRACE("iface %p, present_parameters %p.\n", iface, present_parameters); 708c2c66affSColin Finck 709c2c66affSColin Finck if (device->device_state == D3D8_DEVICE_STATE_LOST) 710c2c66affSColin Finck { 711c2c66affSColin Finck WARN("App not active, returning D3DERR_DEVICELOST.\n"); 712c2c66affSColin Finck return D3DERR_DEVICELOST; 713c2c66affSColin Finck } 714c2c66affSColin Finck if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters)) 715c2c66affSColin Finck return D3DERR_INVALIDCALL; 716c2c66affSColin Finck 717c2c66affSColin Finck wined3d_mutex_lock(); 718c2c66affSColin Finck 719c2c66affSColin Finck if (device->vertex_buffer) 720c2c66affSColin Finck { 721c2c66affSColin Finck wined3d_buffer_decref(device->vertex_buffer); 722c2c66affSColin Finck device->vertex_buffer = NULL; 723c2c66affSColin Finck device->vertex_buffer_size = 0; 724c2c66affSColin Finck } 725c2c66affSColin Finck if (device->index_buffer) 726c2c66affSColin Finck { 727c2c66affSColin Finck wined3d_buffer_decref(device->index_buffer); 728c2c66affSColin Finck device->index_buffer = NULL; 729c2c66affSColin Finck device->index_buffer_size = 0; 730c2c66affSColin Finck } 731c2c66affSColin Finck 732c2c66affSColin Finck if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc, 733c2c66affSColin Finck NULL, reset_enum_callback, TRUE))) 734c2c66affSColin Finck { 735c2c66affSColin Finck present_parameters->BackBufferCount = swapchain_desc.backbuffer_count; 736c2c66affSColin Finck wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0); 737*e6c95b14SAmine Khaldi wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, 738*e6c95b14SAmine Khaldi !!swapchain_desc.enable_auto_depth_stencil); 739c2c66affSColin Finck device->device_state = D3D8_DEVICE_STATE_OK; 740c2c66affSColin Finck } 741c2c66affSColin Finck else 742c2c66affSColin Finck { 743c2c66affSColin Finck device->device_state = D3D8_DEVICE_STATE_NOT_RESET; 744c2c66affSColin Finck } 745c2c66affSColin Finck wined3d_mutex_unlock(); 746c2c66affSColin Finck 747c2c66affSColin Finck return hr; 748c2c66affSColin Finck } 749c2c66affSColin Finck 750c2c66affSColin Finck static HRESULT WINAPI d3d8_device_Present(IDirect3DDevice8 *iface, const RECT *src_rect, 751c2c66affSColin Finck const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region) 752c2c66affSColin Finck { 753c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 754c2c66affSColin Finck 755c2c66affSColin Finck TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n", 756c2c66affSColin Finck iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, dirty_region); 757c2c66affSColin Finck 758c2c66affSColin Finck /* Fraps does not hook IDirect3DDevice8::Present regardless of the hotpatch 759c2c66affSColin Finck * attribute. It only hooks IDirect3DSwapChain8::Present. Yet it properly 760c2c66affSColin Finck * shows a framerate on Windows in applications that only call the device 761c2c66affSColin Finck * method, like e.g. the dx8 sdk samples. The conclusion is that native 762c2c66affSColin Finck * calls the swapchain's public method from the device. */ 763c2c66affSColin Finck return IDirect3DSwapChain8_Present(&device->implicit_swapchain->IDirect3DSwapChain8_iface, 764c2c66affSColin Finck src_rect, dst_rect, dst_window_override, dirty_region); 765c2c66affSColin Finck } 766c2c66affSColin Finck 767c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetBackBuffer(IDirect3DDevice8 *iface, 768c2c66affSColin Finck UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface8 **backbuffer) 769c2c66affSColin Finck { 770c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 771c2c66affSColin Finck struct wined3d_swapchain *wined3d_swapchain; 772c2c66affSColin Finck struct wined3d_texture *wined3d_texture; 773c2c66affSColin Finck struct d3d8_surface *surface_impl; 774c2c66affSColin Finck 775c2c66affSColin Finck TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n", 776c2c66affSColin Finck iface, backbuffer_idx, backbuffer_type, backbuffer); 777c2c66affSColin Finck 778c2c66affSColin Finck /* backbuffer_type is ignored by native. */ 779c2c66affSColin Finck 780c2c66affSColin Finck /* No need to check for backbuffer == NULL, Windows crashes in that case. */ 781c2c66affSColin Finck wined3d_mutex_lock(); 782c2c66affSColin Finck 783c2c66affSColin Finck wined3d_swapchain = device->implicit_swapchain->wined3d_swapchain; 784c2c66affSColin Finck if (!(wined3d_texture = wined3d_swapchain_get_back_buffer(wined3d_swapchain, backbuffer_idx))) 785c2c66affSColin Finck { 786c2c66affSColin Finck wined3d_mutex_unlock(); 787c2c66affSColin Finck *backbuffer = NULL; 788c2c66affSColin Finck return D3DERR_INVALIDCALL; 789c2c66affSColin Finck } 790c2c66affSColin Finck 791c2c66affSColin Finck surface_impl = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0); 792c2c66affSColin Finck *backbuffer = &surface_impl->IDirect3DSurface8_iface; 793c2c66affSColin Finck IDirect3DSurface8_AddRef(*backbuffer); 794c2c66affSColin Finck 795c2c66affSColin Finck wined3d_mutex_unlock(); 796c2c66affSColin Finck return D3D_OK; 797c2c66affSColin Finck } 798c2c66affSColin Finck 799c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetRasterStatus(IDirect3DDevice8 *iface, D3DRASTER_STATUS *raster_status) 800c2c66affSColin Finck { 801c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 802c2c66affSColin Finck HRESULT hr; 803c2c66affSColin Finck 804c2c66affSColin Finck TRACE("iface %p, raster_status %p.\n", iface, raster_status); 805c2c66affSColin Finck 806c2c66affSColin Finck wined3d_mutex_lock(); 807c2c66affSColin Finck hr = wined3d_device_get_raster_status(device->wined3d_device, 0, (struct wined3d_raster_status *)raster_status); 808c2c66affSColin Finck wined3d_mutex_unlock(); 809c2c66affSColin Finck 810c2c66affSColin Finck return hr; 811c2c66affSColin Finck } 812c2c66affSColin Finck 813c2c66affSColin Finck static void WINAPI d3d8_device_SetGammaRamp(IDirect3DDevice8 *iface, DWORD flags, const D3DGAMMARAMP *ramp) 814c2c66affSColin Finck { 815c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 816c2c66affSColin Finck 817c2c66affSColin Finck TRACE("iface %p, flags %#x, ramp %p.\n", iface, flags, ramp); 818c2c66affSColin Finck 819c2c66affSColin Finck /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */ 820c2c66affSColin Finck wined3d_mutex_lock(); 821c2c66affSColin Finck wined3d_device_set_gamma_ramp(device->wined3d_device, 0, flags, (const struct wined3d_gamma_ramp *)ramp); 822c2c66affSColin Finck wined3d_mutex_unlock(); 823c2c66affSColin Finck } 824c2c66affSColin Finck 825c2c66affSColin Finck static void WINAPI d3d8_device_GetGammaRamp(IDirect3DDevice8 *iface, D3DGAMMARAMP *ramp) 826c2c66affSColin Finck { 827c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 828c2c66affSColin Finck 829c2c66affSColin Finck TRACE("iface %p, ramp %p.\n", iface, ramp); 830c2c66affSColin Finck 831c2c66affSColin Finck /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */ 832c2c66affSColin Finck wined3d_mutex_lock(); 833c2c66affSColin Finck wined3d_device_get_gamma_ramp(device->wined3d_device, 0, (struct wined3d_gamma_ramp *)ramp); 834c2c66affSColin Finck wined3d_mutex_unlock(); 835c2c66affSColin Finck } 836c2c66affSColin Finck 837c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreateTexture(IDirect3DDevice8 *iface, 838c2c66affSColin Finck UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, 839c2c66affSColin Finck D3DPOOL pool, IDirect3DTexture8 **texture) 840c2c66affSColin Finck { 841c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 842c2c66affSColin Finck struct d3d8_texture *object; 843c2c66affSColin Finck HRESULT hr; 844c2c66affSColin Finck 845c2c66affSColin Finck TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n", 846c2c66affSColin Finck iface, width, height, levels, usage, format, pool, texture); 847c2c66affSColin Finck 848c2c66affSColin Finck if (!format) 849c2c66affSColin Finck return D3DERR_INVALIDCALL; 850c2c66affSColin Finck 851c2c66affSColin Finck *texture = NULL; 852c2c66affSColin Finck object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 853c2c66affSColin Finck if (!object) 854c2c66affSColin Finck return D3DERR_OUTOFVIDEOMEMORY; 855c2c66affSColin Finck 856c2c66affSColin Finck hr = texture_init(object, device, width, height, levels, usage, format, pool); 857c2c66affSColin Finck if (FAILED(hr)) 858c2c66affSColin Finck { 859c2c66affSColin Finck WARN("Failed to initialize texture, hr %#x.\n", hr); 860c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, object); 861c2c66affSColin Finck return hr; 862c2c66affSColin Finck } 863c2c66affSColin Finck 864c2c66affSColin Finck TRACE("Created texture %p.\n", object); 865c2c66affSColin Finck *texture = (IDirect3DTexture8 *)&object->IDirect3DBaseTexture8_iface; 866c2c66affSColin Finck 867c2c66affSColin Finck return D3D_OK; 868c2c66affSColin Finck } 869c2c66affSColin Finck 870c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreateVolumeTexture(IDirect3DDevice8 *iface, 871c2c66affSColin Finck UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, 872c2c66affSColin Finck D3DPOOL pool, IDirect3DVolumeTexture8 **texture) 873c2c66affSColin Finck { 874c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 875c2c66affSColin Finck struct d3d8_texture *object; 876c2c66affSColin Finck HRESULT hr; 877c2c66affSColin Finck 878c2c66affSColin Finck TRACE("iface %p, width %u, height %u, depth %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n", 879c2c66affSColin Finck iface, width, height, depth, levels, usage, format, pool, texture); 880c2c66affSColin Finck 881c2c66affSColin Finck if (!format) 882c2c66affSColin Finck return D3DERR_INVALIDCALL; 883c2c66affSColin Finck 884c2c66affSColin Finck *texture = NULL; 885c2c66affSColin Finck object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 886c2c66affSColin Finck if (!object) 887c2c66affSColin Finck return D3DERR_OUTOFVIDEOMEMORY; 888c2c66affSColin Finck 889c2c66affSColin Finck hr = volumetexture_init(object, device, width, height, depth, levels, usage, format, pool); 890c2c66affSColin Finck if (FAILED(hr)) 891c2c66affSColin Finck { 892c2c66affSColin Finck WARN("Failed to initialize volume texture, hr %#x.\n", hr); 893c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, object); 894c2c66affSColin Finck return hr; 895c2c66affSColin Finck } 896c2c66affSColin Finck 897c2c66affSColin Finck TRACE("Created volume texture %p.\n", object); 898c2c66affSColin Finck *texture = (IDirect3DVolumeTexture8 *)&object->IDirect3DBaseTexture8_iface; 899c2c66affSColin Finck 900c2c66affSColin Finck return D3D_OK; 901c2c66affSColin Finck } 902c2c66affSColin Finck 903c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreateCubeTexture(IDirect3DDevice8 *iface, UINT edge_length, 904c2c66affSColin Finck UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture8 **texture) 905c2c66affSColin Finck { 906c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 907c2c66affSColin Finck struct d3d8_texture *object; 908c2c66affSColin Finck HRESULT hr; 909c2c66affSColin Finck 910c2c66affSColin Finck TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n", 911c2c66affSColin Finck iface, edge_length, levels, usage, format, pool, texture); 912c2c66affSColin Finck 913c2c66affSColin Finck if (!format) 914c2c66affSColin Finck return D3DERR_INVALIDCALL; 915c2c66affSColin Finck 916c2c66affSColin Finck *texture = NULL; 917c2c66affSColin Finck object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 918c2c66affSColin Finck if (!object) 919c2c66affSColin Finck return D3DERR_OUTOFVIDEOMEMORY; 920c2c66affSColin Finck 921c2c66affSColin Finck hr = cubetexture_init(object, device, edge_length, levels, usage, format, pool); 922c2c66affSColin Finck if (FAILED(hr)) 923c2c66affSColin Finck { 924c2c66affSColin Finck WARN("Failed to initialize cube texture, hr %#x.\n", hr); 925c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, object); 926c2c66affSColin Finck return hr; 927c2c66affSColin Finck } 928c2c66affSColin Finck 929c2c66affSColin Finck TRACE("Created cube texture %p.\n", object); 930c2c66affSColin Finck *texture = (IDirect3DCubeTexture8 *)&object->IDirect3DBaseTexture8_iface; 931c2c66affSColin Finck 932c2c66affSColin Finck return hr; 933c2c66affSColin Finck } 934c2c66affSColin Finck 935c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreateVertexBuffer(IDirect3DDevice8 *iface, UINT size, 936c2c66affSColin Finck DWORD usage, DWORD fvf, D3DPOOL pool, IDirect3DVertexBuffer8 **buffer) 937c2c66affSColin Finck { 938c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 939c2c66affSColin Finck struct d3d8_vertexbuffer *object; 940c2c66affSColin Finck HRESULT hr; 941c2c66affSColin Finck 942c2c66affSColin Finck TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p.\n", 943c2c66affSColin Finck iface, size, usage, fvf, pool, buffer); 944c2c66affSColin Finck 945c2c66affSColin Finck object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 946c2c66affSColin Finck if (!object) 947c2c66affSColin Finck return D3DERR_OUTOFVIDEOMEMORY; 948c2c66affSColin Finck 949c2c66affSColin Finck hr = vertexbuffer_init(object, device, size, usage, fvf, pool); 950c2c66affSColin Finck if (FAILED(hr)) 951c2c66affSColin Finck { 952c2c66affSColin Finck WARN("Failed to initialize vertex buffer, hr %#x.\n", hr); 953c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, object); 954c2c66affSColin Finck return hr; 955c2c66affSColin Finck } 956c2c66affSColin Finck 957c2c66affSColin Finck TRACE("Created vertex buffer %p.\n", object); 958c2c66affSColin Finck *buffer = &object->IDirect3DVertexBuffer8_iface; 959c2c66affSColin Finck 960c2c66affSColin Finck return D3D_OK; 961c2c66affSColin Finck } 962c2c66affSColin Finck 963c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreateIndexBuffer(IDirect3DDevice8 *iface, UINT size, 964c2c66affSColin Finck DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer8 **buffer) 965c2c66affSColin Finck { 966c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 967c2c66affSColin Finck struct d3d8_indexbuffer *object; 968c2c66affSColin Finck HRESULT hr; 969c2c66affSColin Finck 970c2c66affSColin Finck TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p.\n", 971c2c66affSColin Finck iface, size, usage, format, pool, buffer); 972c2c66affSColin Finck 973c2c66affSColin Finck object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 974c2c66affSColin Finck if (!object) 975c2c66affSColin Finck return D3DERR_OUTOFVIDEOMEMORY; 976c2c66affSColin Finck 977c2c66affSColin Finck hr = indexbuffer_init(object, device, size, usage, format, pool); 978c2c66affSColin Finck if (FAILED(hr)) 979c2c66affSColin Finck { 980c2c66affSColin Finck WARN("Failed to initialize index buffer, hr %#x.\n", hr); 981c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, object); 982c2c66affSColin Finck return hr; 983c2c66affSColin Finck } 984c2c66affSColin Finck 985c2c66affSColin Finck TRACE("Created index buffer %p.\n", object); 986c2c66affSColin Finck *buffer = &object->IDirect3DIndexBuffer8_iface; 987c2c66affSColin Finck 988c2c66affSColin Finck return D3D_OK; 989c2c66affSColin Finck } 990c2c66affSColin Finck 991c2c66affSColin Finck static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width, UINT height, 992c2c66affSColin Finck D3DFORMAT format, DWORD flags, IDirect3DSurface8 **surface, UINT usage, D3DPOOL pool, 993c2c66affSColin Finck D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality) 994c2c66affSColin Finck { 995c2c66affSColin Finck struct wined3d_resource_desc desc; 996c2c66affSColin Finck struct d3d8_surface *surface_impl; 997c2c66affSColin Finck struct wined3d_texture *texture; 998c2c66affSColin Finck HRESULT hr; 999c2c66affSColin Finck 1000c2c66affSColin Finck TRACE("device %p, width %u, height %u, format %#x, flags %#x, surface %p, " 1001c2c66affSColin Finck "usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n", 1002c2c66affSColin Finck device, width, height, format, flags, surface, 1003c2c66affSColin Finck usage, pool, multisample_type, multisample_quality); 1004c2c66affSColin Finck 1005c2c66affSColin Finck desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; 1006c2c66affSColin Finck desc.format = wined3dformat_from_d3dformat(format); 1007c2c66affSColin Finck desc.multisample_type = multisample_type; 1008c2c66affSColin Finck desc.multisample_quality = multisample_quality; 1009c2c66affSColin Finck desc.usage = usage & WINED3DUSAGE_MASK; 1010c2c66affSColin Finck desc.pool = pool; 1011c2c66affSColin Finck desc.width = width; 1012c2c66affSColin Finck desc.height = height; 1013c2c66affSColin Finck desc.depth = 1; 1014c2c66affSColin Finck desc.size = 0; 1015c2c66affSColin Finck 1016c2c66affSColin Finck wined3d_mutex_lock(); 1017c2c66affSColin Finck 1018c2c66affSColin Finck if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc, 1019c2c66affSColin Finck 1, 1, flags, NULL, NULL, &d3d8_null_wined3d_parent_ops, &texture))) 1020c2c66affSColin Finck { 1021c2c66affSColin Finck wined3d_mutex_unlock(); 1022c2c66affSColin Finck WARN("Failed to create texture, hr %#x.\n", hr); 1023c2c66affSColin Finck return hr; 1024c2c66affSColin Finck } 1025c2c66affSColin Finck 1026c2c66affSColin Finck surface_impl = wined3d_texture_get_sub_resource_parent(texture, 0); 1027c2c66affSColin Finck surface_impl->parent_device = &device->IDirect3DDevice8_iface; 1028c2c66affSColin Finck *surface = &surface_impl->IDirect3DSurface8_iface; 1029c2c66affSColin Finck IDirect3DSurface8_AddRef(*surface); 1030c2c66affSColin Finck wined3d_texture_decref(texture); 1031c2c66affSColin Finck 1032c2c66affSColin Finck wined3d_mutex_unlock(); 1033c2c66affSColin Finck 1034c2c66affSColin Finck return D3D_OK; 1035c2c66affSColin Finck } 1036c2c66affSColin Finck 1037c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreateRenderTarget(IDirect3DDevice8 *iface, UINT width, 1038c2c66affSColin Finck UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, BOOL lockable, 1039c2c66affSColin Finck IDirect3DSurface8 **surface) 1040c2c66affSColin Finck { 1041c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1042c2c66affSColin Finck DWORD flags = 0; 1043c2c66affSColin Finck 1044c2c66affSColin Finck TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, lockable %#x, surface %p.\n", 1045c2c66affSColin Finck iface, width, height, format, multisample_type, lockable, surface); 1046c2c66affSColin Finck 1047c2c66affSColin Finck if (!format) 1048c2c66affSColin Finck return D3DERR_INVALIDCALL; 1049c2c66affSColin Finck 1050c2c66affSColin Finck *surface = NULL; 1051c2c66affSColin Finck if (lockable) 1052c2c66affSColin Finck flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; 1053c2c66affSColin Finck 1054c2c66affSColin Finck return d3d8_device_create_surface(device, width, height, format, flags, surface, 1055c2c66affSColin Finck D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, 0); 1056c2c66affSColin Finck } 1057c2c66affSColin Finck 1058c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreateDepthStencilSurface(IDirect3DDevice8 *iface, 1059c2c66affSColin Finck UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, 1060c2c66affSColin Finck IDirect3DSurface8 **surface) 1061c2c66affSColin Finck { 1062c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1063c2c66affSColin Finck 1064c2c66affSColin Finck TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, surface %p.\n", 1065c2c66affSColin Finck iface, width, height, format, multisample_type, surface); 1066c2c66affSColin Finck 1067c2c66affSColin Finck if (!format) 1068c2c66affSColin Finck return D3DERR_INVALIDCALL; 1069c2c66affSColin Finck 1070c2c66affSColin Finck *surface = NULL; 1071c2c66affSColin Finck 1072c2c66affSColin Finck /* TODO: Verify that Discard is false */ 1073c2c66affSColin Finck return d3d8_device_create_surface(device, width, height, format, WINED3D_TEXTURE_CREATE_MAPPABLE, 1074c2c66affSColin Finck surface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, 0); 1075c2c66affSColin Finck } 1076c2c66affSColin Finck 1077c2c66affSColin Finck /* IDirect3DDevice8Impl::CreateImageSurface returns surface with pool type SYSTEMMEM */ 1078c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreateImageSurface(IDirect3DDevice8 *iface, UINT width, 1079c2c66affSColin Finck UINT height, D3DFORMAT format, IDirect3DSurface8 **surface) 1080c2c66affSColin Finck { 1081c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1082c2c66affSColin Finck 1083c2c66affSColin Finck TRACE("iface %p, width %u, height %u, format %#x, surface %p.\n", 1084c2c66affSColin Finck iface, width, height, format, surface); 1085c2c66affSColin Finck 1086c2c66affSColin Finck *surface = NULL; 1087c2c66affSColin Finck 1088c2c66affSColin Finck return d3d8_device_create_surface(device, width, height, format, WINED3D_TEXTURE_CREATE_MAPPABLE, 1089c2c66affSColin Finck surface, 0, D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, 0); 1090c2c66affSColin Finck } 1091c2c66affSColin Finck 1092c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface, 1093c2c66affSColin Finck IDirect3DSurface8 *src_surface, const RECT *src_rects, UINT rect_count, 1094c2c66affSColin Finck IDirect3DSurface8 *dst_surface, const POINT *dst_points) 1095c2c66affSColin Finck { 1096c2c66affSColin Finck struct d3d8_surface *src = unsafe_impl_from_IDirect3DSurface8(src_surface); 1097c2c66affSColin Finck struct d3d8_surface *dst = unsafe_impl_from_IDirect3DSurface8(dst_surface); 1098c2c66affSColin Finck enum wined3d_format_id src_format, dst_format; 1099c2c66affSColin Finck struct wined3d_sub_resource_desc wined3d_desc; 1100c2c66affSColin Finck UINT src_w, src_h; 1101c2c66affSColin Finck 1102c2c66affSColin Finck TRACE("iface %p, src_surface %p, src_rects %p, rect_count %u, dst_surface %p, dst_points %p.\n", 1103c2c66affSColin Finck iface, src_surface, src_rects, rect_count, dst_surface, dst_points); 1104c2c66affSColin Finck 1105c2c66affSColin Finck /* Check that the source texture is in WINED3D_POOL_SYSTEM_MEM and the 1106c2c66affSColin Finck * destination texture is in WINED3D_POOL_DEFAULT. */ 1107c2c66affSColin Finck 1108c2c66affSColin Finck wined3d_mutex_lock(); 1109c2c66affSColin Finck wined3d_texture_get_sub_resource_desc(src->wined3d_texture, src->sub_resource_idx, &wined3d_desc); 1110c2c66affSColin Finck if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL) 1111c2c66affSColin Finck { 1112c2c66affSColin Finck WARN("Source %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", src_surface); 1113c2c66affSColin Finck wined3d_mutex_unlock(); 1114c2c66affSColin Finck return D3DERR_INVALIDCALL; 1115c2c66affSColin Finck } 1116c2c66affSColin Finck src_format = wined3d_desc.format; 1117c2c66affSColin Finck src_w = wined3d_desc.width; 1118c2c66affSColin Finck src_h = wined3d_desc.height; 1119c2c66affSColin Finck 1120c2c66affSColin Finck wined3d_texture_get_sub_resource_desc(dst->wined3d_texture, dst->sub_resource_idx, &wined3d_desc); 1121c2c66affSColin Finck if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL) 1122c2c66affSColin Finck { 1123c2c66affSColin Finck WARN("Destination %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", dst_surface); 1124c2c66affSColin Finck wined3d_mutex_unlock(); 1125c2c66affSColin Finck return D3DERR_INVALIDCALL; 1126c2c66affSColin Finck } 1127c2c66affSColin Finck dst_format = wined3d_desc.format; 1128c2c66affSColin Finck 1129c2c66affSColin Finck /* Check that the source and destination formats match */ 1130c2c66affSColin Finck if (src_format != dst_format) 1131c2c66affSColin Finck { 1132c2c66affSColin Finck WARN("Source %p format must match the destination %p format, returning D3DERR_INVALIDCALL.\n", 1133c2c66affSColin Finck src_surface, dst_surface); 1134c2c66affSColin Finck wined3d_mutex_unlock(); 1135c2c66affSColin Finck return D3DERR_INVALIDCALL; 1136c2c66affSColin Finck } 1137c2c66affSColin Finck 1138c2c66affSColin Finck /* Quick if complete copy ... */ 1139c2c66affSColin Finck if (!rect_count && !src_rects && !dst_points) 1140c2c66affSColin Finck { 1141c2c66affSColin Finck RECT rect = {0, 0, src_w, src_h}; 1142c2c66affSColin Finck wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &rect, 1143c2c66affSColin Finck src->wined3d_texture, src->sub_resource_idx, &rect, 0, NULL, WINED3D_TEXF_POINT); 1144c2c66affSColin Finck } 1145c2c66affSColin Finck else 1146c2c66affSColin Finck { 1147c2c66affSColin Finck unsigned int i; 1148c2c66affSColin Finck /* Copy rect by rect */ 1149c2c66affSColin Finck if (src_rects && dst_points) 1150c2c66affSColin Finck { 1151c2c66affSColin Finck for (i = 0; i < rect_count; ++i) 1152c2c66affSColin Finck { 1153c2c66affSColin Finck UINT w = src_rects[i].right - src_rects[i].left; 1154c2c66affSColin Finck UINT h = src_rects[i].bottom - src_rects[i].top; 1155c2c66affSColin Finck RECT dst_rect = {dst_points[i].x, dst_points[i].y, 1156c2c66affSColin Finck dst_points[i].x + w, dst_points[i].y + h}; 1157c2c66affSColin Finck 1158c2c66affSColin Finck wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &dst_rect, 1159c2c66affSColin Finck src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT); 1160c2c66affSColin Finck } 1161c2c66affSColin Finck } 1162c2c66affSColin Finck else 1163c2c66affSColin Finck { 1164c2c66affSColin Finck for (i = 0; i < rect_count; ++i) 1165c2c66affSColin Finck { 1166c2c66affSColin Finck UINT w = src_rects[i].right - src_rects[i].left; 1167c2c66affSColin Finck UINT h = src_rects[i].bottom - src_rects[i].top; 1168c2c66affSColin Finck RECT dst_rect = {0, 0, w, h}; 1169c2c66affSColin Finck 1170c2c66affSColin Finck wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &dst_rect, 1171c2c66affSColin Finck src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT); 1172c2c66affSColin Finck } 1173c2c66affSColin Finck } 1174c2c66affSColin Finck } 1175c2c66affSColin Finck wined3d_mutex_unlock(); 1176c2c66affSColin Finck 1177c2c66affSColin Finck return WINED3D_OK; 1178c2c66affSColin Finck } 1179c2c66affSColin Finck 1180c2c66affSColin Finck static HRESULT WINAPI d3d8_device_UpdateTexture(IDirect3DDevice8 *iface, 1181c2c66affSColin Finck IDirect3DBaseTexture8 *src_texture, IDirect3DBaseTexture8 *dst_texture) 1182c2c66affSColin Finck { 1183c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1184c2c66affSColin Finck struct d3d8_texture *src_impl, *dst_impl; 1185c2c66affSColin Finck HRESULT hr; 1186c2c66affSColin Finck 1187c2c66affSColin Finck TRACE("iface %p, src_texture %p, dst_texture %p.\n", iface, src_texture, dst_texture); 1188c2c66affSColin Finck 1189c2c66affSColin Finck src_impl = unsafe_impl_from_IDirect3DBaseTexture8(src_texture); 1190c2c66affSColin Finck dst_impl = unsafe_impl_from_IDirect3DBaseTexture8(dst_texture); 1191c2c66affSColin Finck 1192c2c66affSColin Finck wined3d_mutex_lock(); 1193c2c66affSColin Finck hr = wined3d_device_update_texture(device->wined3d_device, 1194c2c66affSColin Finck src_impl->wined3d_texture, dst_impl->wined3d_texture); 1195c2c66affSColin Finck wined3d_mutex_unlock(); 1196c2c66affSColin Finck 1197c2c66affSColin Finck return hr; 1198c2c66affSColin Finck } 1199c2c66affSColin Finck 1200c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetFrontBuffer(IDirect3DDevice8 *iface, IDirect3DSurface8 *dst_surface) 1201c2c66affSColin Finck { 1202c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1203c2c66affSColin Finck struct d3d8_surface *dst_impl = unsafe_impl_from_IDirect3DSurface8(dst_surface); 1204c2c66affSColin Finck HRESULT hr; 1205c2c66affSColin Finck 1206c2c66affSColin Finck TRACE("iface %p, dst_surface %p.\n", iface, dst_surface); 1207c2c66affSColin Finck 1208c2c66affSColin Finck if (!dst_surface) 1209c2c66affSColin Finck { 1210c2c66affSColin Finck WARN("Invalid destination surface passed.\n"); 1211c2c66affSColin Finck return D3DERR_INVALIDCALL; 1212c2c66affSColin Finck } 1213c2c66affSColin Finck 1214c2c66affSColin Finck wined3d_mutex_lock(); 1215c2c66affSColin Finck hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchain->wined3d_swapchain, 1216c2c66affSColin Finck dst_impl->wined3d_texture, dst_impl->sub_resource_idx); 1217c2c66affSColin Finck wined3d_mutex_unlock(); 1218c2c66affSColin Finck 1219c2c66affSColin Finck return hr; 1220c2c66affSColin Finck } 1221c2c66affSColin Finck 1222c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface, 1223c2c66affSColin Finck IDirect3DSurface8 *render_target, IDirect3DSurface8 *depth_stencil) 1224c2c66affSColin Finck { 1225c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1226c2c66affSColin Finck struct d3d8_surface *rt_impl = unsafe_impl_from_IDirect3DSurface8(render_target); 1227c2c66affSColin Finck struct d3d8_surface *ds_impl = unsafe_impl_from_IDirect3DSurface8(depth_stencil); 1228c2c66affSColin Finck struct wined3d_rendertarget_view *original_dsv, *rtv; 1229c2c66affSColin Finck HRESULT hr = D3D_OK; 1230c2c66affSColin Finck 1231c2c66affSColin Finck TRACE("iface %p, render_target %p, depth_stencil %p.\n", iface, render_target, depth_stencil); 1232c2c66affSColin Finck 1233c2c66affSColin Finck if (rt_impl && d3d8_surface_get_device(rt_impl) != device) 1234c2c66affSColin Finck { 1235c2c66affSColin Finck WARN("Render target surface does not match device.\n"); 1236c2c66affSColin Finck return D3DERR_INVALIDCALL; 1237c2c66affSColin Finck } 1238c2c66affSColin Finck 1239c2c66affSColin Finck wined3d_mutex_lock(); 1240c2c66affSColin Finck 1241c2c66affSColin Finck if (ds_impl) 1242c2c66affSColin Finck { 1243c2c66affSColin Finck struct wined3d_sub_resource_desc ds_desc, rt_desc; 1244c2c66affSColin Finck struct wined3d_rendertarget_view *original_rtv; 1245c2c66affSColin Finck struct d3d8_surface *original_surface; 1246c2c66affSColin Finck 1247c2c66affSColin Finck /* If no render target is passed in check the size against the current RT */ 1248c2c66affSColin Finck if (!render_target) 1249c2c66affSColin Finck { 1250c2c66affSColin Finck if (!(original_rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) 1251c2c66affSColin Finck { 1252c2c66affSColin Finck wined3d_mutex_unlock(); 1253c2c66affSColin Finck return D3DERR_NOTFOUND; 1254c2c66affSColin Finck } 1255c2c66affSColin Finck original_surface = wined3d_rendertarget_view_get_sub_resource_parent(original_rtv); 1256c2c66affSColin Finck wined3d_texture_get_sub_resource_desc(original_surface->wined3d_texture, 1257c2c66affSColin Finck original_surface->sub_resource_idx, &rt_desc); 1258c2c66affSColin Finck } 1259c2c66affSColin Finck else 1260c2c66affSColin Finck wined3d_texture_get_sub_resource_desc(rt_impl->wined3d_texture, 1261c2c66affSColin Finck rt_impl->sub_resource_idx, &rt_desc); 1262c2c66affSColin Finck 1263c2c66affSColin Finck wined3d_texture_get_sub_resource_desc(ds_impl->wined3d_texture, ds_impl->sub_resource_idx, &ds_desc); 1264c2c66affSColin Finck 1265c2c66affSColin Finck if (ds_desc.width < rt_desc.width || ds_desc.height < rt_desc.height) 1266c2c66affSColin Finck { 1267c2c66affSColin Finck WARN("Depth stencil is smaller than the render target, returning D3DERR_INVALIDCALL\n"); 1268c2c66affSColin Finck wined3d_mutex_unlock(); 1269c2c66affSColin Finck return D3DERR_INVALIDCALL; 1270c2c66affSColin Finck } 1271c2c66affSColin Finck if (ds_desc.multisample_type != rt_desc.multisample_type 1272c2c66affSColin Finck || ds_desc.multisample_quality != rt_desc.multisample_quality) 1273c2c66affSColin Finck { 1274c2c66affSColin Finck WARN("Multisample settings do not match, returning D3DERR_INVALIDCALL\n"); 1275c2c66affSColin Finck wined3d_mutex_unlock(); 1276c2c66affSColin Finck return D3DERR_INVALIDCALL; 1277c2c66affSColin Finck } 1278c2c66affSColin Finck } 1279c2c66affSColin Finck 1280c2c66affSColin Finck original_dsv = wined3d_device_get_depth_stencil_view(device->wined3d_device); 1281c2c66affSColin Finck rtv = ds_impl ? d3d8_surface_acquire_rendertarget_view(ds_impl) : NULL; 1282c2c66affSColin Finck wined3d_device_set_depth_stencil_view(device->wined3d_device, rtv); 1283c2c66affSColin Finck d3d8_surface_release_rendertarget_view(ds_impl, rtv); 1284c2c66affSColin Finck rtv = render_target ? d3d8_surface_acquire_rendertarget_view(rt_impl) : NULL; 1285c2c66affSColin Finck if (render_target && FAILED(hr = wined3d_device_set_rendertarget_view(device->wined3d_device, 0, rtv, TRUE))) 1286c2c66affSColin Finck wined3d_device_set_depth_stencil_view(device->wined3d_device, original_dsv); 1287c2c66affSColin Finck d3d8_surface_release_rendertarget_view(rt_impl, rtv); 1288c2c66affSColin Finck 1289c2c66affSColin Finck wined3d_mutex_unlock(); 1290c2c66affSColin Finck 1291c2c66affSColin Finck return hr; 1292c2c66affSColin Finck } 1293c2c66affSColin Finck 1294c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetRenderTarget(IDirect3DDevice8 *iface, IDirect3DSurface8 **render_target) 1295c2c66affSColin Finck { 1296c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1297c2c66affSColin Finck struct wined3d_rendertarget_view *wined3d_rtv; 1298c2c66affSColin Finck struct d3d8_surface *surface_impl; 1299c2c66affSColin Finck HRESULT hr; 1300c2c66affSColin Finck 1301c2c66affSColin Finck TRACE("iface %p, render_target %p.\n", iface, render_target); 1302c2c66affSColin Finck 1303c2c66affSColin Finck if (!render_target) 1304c2c66affSColin Finck return D3DERR_INVALIDCALL; 1305c2c66affSColin Finck 1306c2c66affSColin Finck wined3d_mutex_lock(); 1307c2c66affSColin Finck if ((wined3d_rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) 1308c2c66affSColin Finck { 1309c2c66affSColin Finck /* We want the sub resource parent here, since the view itself may be 1310c2c66affSColin Finck * internal to wined3d and may not have a parent. */ 1311c2c66affSColin Finck surface_impl = wined3d_rendertarget_view_get_sub_resource_parent(wined3d_rtv); 1312c2c66affSColin Finck *render_target = &surface_impl->IDirect3DSurface8_iface; 1313c2c66affSColin Finck IDirect3DSurface8_AddRef(*render_target); 1314c2c66affSColin Finck hr = D3D_OK; 1315c2c66affSColin Finck } 1316c2c66affSColin Finck else 1317c2c66affSColin Finck { 1318c2c66affSColin Finck ERR("Failed to get wined3d render target.\n"); 1319c2c66affSColin Finck *render_target = NULL; 1320c2c66affSColin Finck hr = D3DERR_NOTFOUND; 1321c2c66affSColin Finck } 1322c2c66affSColin Finck wined3d_mutex_unlock(); 1323c2c66affSColin Finck 1324c2c66affSColin Finck return hr; 1325c2c66affSColin Finck } 1326c2c66affSColin Finck 1327c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetDepthStencilSurface(IDirect3DDevice8 *iface, IDirect3DSurface8 **depth_stencil) 1328c2c66affSColin Finck { 1329c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1330c2c66affSColin Finck struct wined3d_rendertarget_view *wined3d_dsv; 1331c2c66affSColin Finck struct d3d8_surface *surface_impl; 1332c2c66affSColin Finck HRESULT hr = D3D_OK; 1333c2c66affSColin Finck 1334c2c66affSColin Finck TRACE("iface %p, depth_stencil %p.\n", iface, depth_stencil); 1335c2c66affSColin Finck 1336c2c66affSColin Finck if (!depth_stencil) 1337c2c66affSColin Finck return D3DERR_INVALIDCALL; 1338c2c66affSColin Finck 1339c2c66affSColin Finck wined3d_mutex_lock(); 1340c2c66affSColin Finck if ((wined3d_dsv = wined3d_device_get_depth_stencil_view(device->wined3d_device))) 1341c2c66affSColin Finck { 1342c2c66affSColin Finck /* We want the sub resource parent here, since the view itself may be 1343c2c66affSColin Finck * internal to wined3d and may not have a parent. */ 1344c2c66affSColin Finck surface_impl = wined3d_rendertarget_view_get_sub_resource_parent(wined3d_dsv); 1345c2c66affSColin Finck *depth_stencil = &surface_impl->IDirect3DSurface8_iface; 1346c2c66affSColin Finck IDirect3DSurface8_AddRef(*depth_stencil); 1347c2c66affSColin Finck } 1348c2c66affSColin Finck else 1349c2c66affSColin Finck { 1350c2c66affSColin Finck hr = D3DERR_NOTFOUND; 1351c2c66affSColin Finck *depth_stencil = NULL; 1352c2c66affSColin Finck } 1353c2c66affSColin Finck wined3d_mutex_unlock(); 1354c2c66affSColin Finck 1355c2c66affSColin Finck return hr; 1356c2c66affSColin Finck } 1357c2c66affSColin Finck 1358c2c66affSColin Finck static HRESULT WINAPI d3d8_device_BeginScene(IDirect3DDevice8 *iface) 1359c2c66affSColin Finck { 1360c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1361c2c66affSColin Finck HRESULT hr; 1362c2c66affSColin Finck 1363c2c66affSColin Finck TRACE("iface %p.\n", iface); 1364c2c66affSColin Finck 1365c2c66affSColin Finck wined3d_mutex_lock(); 1366c2c66affSColin Finck hr = wined3d_device_begin_scene(device->wined3d_device); 1367c2c66affSColin Finck wined3d_mutex_unlock(); 1368c2c66affSColin Finck 1369c2c66affSColin Finck return hr; 1370c2c66affSColin Finck } 1371c2c66affSColin Finck 1372c2c66affSColin Finck static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_device_EndScene(IDirect3DDevice8 *iface) 1373c2c66affSColin Finck { 1374c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1375c2c66affSColin Finck HRESULT hr; 1376c2c66affSColin Finck 1377c2c66affSColin Finck TRACE("iface %p.\n", iface); 1378c2c66affSColin Finck 1379c2c66affSColin Finck wined3d_mutex_lock(); 1380c2c66affSColin Finck hr = wined3d_device_end_scene(device->wined3d_device); 1381c2c66affSColin Finck wined3d_mutex_unlock(); 1382c2c66affSColin Finck 1383c2c66affSColin Finck return hr; 1384c2c66affSColin Finck } 1385c2c66affSColin Finck 1386c2c66affSColin Finck static HRESULT WINAPI d3d8_device_Clear(IDirect3DDevice8 *iface, DWORD rect_count, 1387c2c66affSColin Finck const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil) 1388c2c66affSColin Finck { 1389c2c66affSColin Finck const struct wined3d_color c = 1390c2c66affSColin Finck { 1391c2c66affSColin Finck ((color >> 16) & 0xff) / 255.0f, 1392c2c66affSColin Finck ((color >> 8) & 0xff) / 255.0f, 1393c2c66affSColin Finck (color & 0xff) / 255.0f, 1394c2c66affSColin Finck ((color >> 24) & 0xff) / 255.0f, 1395c2c66affSColin Finck }; 1396c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1397c2c66affSColin Finck HRESULT hr; 1398c2c66affSColin Finck 1399c2c66affSColin Finck TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n", 1400c2c66affSColin Finck iface, rect_count, rects, flags, color, z, stencil); 1401c2c66affSColin Finck 1402c2c66affSColin Finck if (rect_count && !rects) 1403c2c66affSColin Finck { 1404c2c66affSColin Finck WARN("count %u with NULL rects.\n", rect_count); 1405c2c66affSColin Finck rect_count = 0; 1406c2c66affSColin Finck } 1407c2c66affSColin Finck 1408c2c66affSColin Finck wined3d_mutex_lock(); 1409c2c66affSColin Finck hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil); 1410c2c66affSColin Finck wined3d_mutex_unlock(); 1411c2c66affSColin Finck 1412c2c66affSColin Finck return hr; 1413c2c66affSColin Finck } 1414c2c66affSColin Finck 1415c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetTransform(IDirect3DDevice8 *iface, 1416c2c66affSColin Finck D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix) 1417c2c66affSColin Finck { 1418c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1419c2c66affSColin Finck 1420c2c66affSColin Finck TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); 1421c2c66affSColin Finck 1422c2c66affSColin Finck /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */ 1423c2c66affSColin Finck wined3d_mutex_lock(); 1424c2c66affSColin Finck wined3d_device_set_transform(device->wined3d_device, state, (const struct wined3d_matrix *)matrix); 1425c2c66affSColin Finck wined3d_mutex_unlock(); 1426c2c66affSColin Finck 1427c2c66affSColin Finck return D3D_OK; 1428c2c66affSColin Finck } 1429c2c66affSColin Finck 1430c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetTransform(IDirect3DDevice8 *iface, 1431c2c66affSColin Finck D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix) 1432c2c66affSColin Finck { 1433c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1434c2c66affSColin Finck 1435c2c66affSColin Finck TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); 1436c2c66affSColin Finck 1437c2c66affSColin Finck /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */ 1438c2c66affSColin Finck wined3d_mutex_lock(); 1439c2c66affSColin Finck wined3d_device_get_transform(device->wined3d_device, state, (struct wined3d_matrix *)matrix); 1440c2c66affSColin Finck wined3d_mutex_unlock(); 1441c2c66affSColin Finck 1442c2c66affSColin Finck return D3D_OK; 1443c2c66affSColin Finck } 1444c2c66affSColin Finck 1445c2c66affSColin Finck static HRESULT WINAPI d3d8_device_MultiplyTransform(IDirect3DDevice8 *iface, 1446c2c66affSColin Finck D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix) 1447c2c66affSColin Finck { 1448c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1449c2c66affSColin Finck 1450c2c66affSColin Finck TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); 1451c2c66affSColin Finck 1452c2c66affSColin Finck /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */ 1453c2c66affSColin Finck wined3d_mutex_lock(); 1454c2c66affSColin Finck wined3d_device_multiply_transform(device->wined3d_device, state, (const struct wined3d_matrix *)matrix); 1455c2c66affSColin Finck wined3d_mutex_unlock(); 1456c2c66affSColin Finck 1457c2c66affSColin Finck return D3D_OK; 1458c2c66affSColin Finck } 1459c2c66affSColin Finck 1460c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3DVIEWPORT8 *viewport) 1461c2c66affSColin Finck { 1462c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1463c2c66affSColin Finck struct wined3d_viewport vp; 1464c2c66affSColin Finck 1465c2c66affSColin Finck TRACE("iface %p, viewport %p.\n", iface, viewport); 1466c2c66affSColin Finck 1467c2c66affSColin Finck vp.x = viewport->X; 1468c2c66affSColin Finck vp.y = viewport->Y; 1469c2c66affSColin Finck vp.width = viewport->Width; 1470c2c66affSColin Finck vp.height = viewport->Height; 1471c2c66affSColin Finck vp.min_z = viewport->MinZ; 1472c2c66affSColin Finck vp.max_z = viewport->MaxZ; 1473c2c66affSColin Finck 1474c2c66affSColin Finck wined3d_mutex_lock(); 1475c2c66affSColin Finck wined3d_device_set_viewport(device->wined3d_device, &vp); 1476c2c66affSColin Finck wined3d_mutex_unlock(); 1477c2c66affSColin Finck 1478c2c66affSColin Finck return D3D_OK; 1479c2c66affSColin Finck } 1480c2c66affSColin Finck 1481c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetViewport(IDirect3DDevice8 *iface, D3DVIEWPORT8 *viewport) 1482c2c66affSColin Finck { 1483c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1484c2c66affSColin Finck struct wined3d_viewport wined3d_viewport; 1485c2c66affSColin Finck 1486c2c66affSColin Finck TRACE("iface %p, viewport %p.\n", iface, viewport); 1487c2c66affSColin Finck 1488c2c66affSColin Finck wined3d_mutex_lock(); 1489c2c66affSColin Finck wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport); 1490c2c66affSColin Finck wined3d_mutex_unlock(); 1491c2c66affSColin Finck 1492c2c66affSColin Finck viewport->X = wined3d_viewport.x; 1493c2c66affSColin Finck viewport->Y = wined3d_viewport.y; 1494c2c66affSColin Finck viewport->Width = wined3d_viewport.width; 1495c2c66affSColin Finck viewport->Height = wined3d_viewport.height; 1496c2c66affSColin Finck viewport->MinZ = wined3d_viewport.min_z; 1497c2c66affSColin Finck viewport->MaxZ = wined3d_viewport.max_z; 1498c2c66affSColin Finck 1499c2c66affSColin Finck return D3D_OK; 1500c2c66affSColin Finck } 1501c2c66affSColin Finck 1502c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetMaterial(IDirect3DDevice8 *iface, const D3DMATERIAL8 *material) 1503c2c66affSColin Finck { 1504c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1505c2c66affSColin Finck 1506c2c66affSColin Finck TRACE("iface %p, material %p.\n", iface, material); 1507c2c66affSColin Finck 1508c2c66affSColin Finck /* Note: D3DMATERIAL8 is compatible with struct wined3d_material. */ 1509c2c66affSColin Finck wined3d_mutex_lock(); 1510c2c66affSColin Finck wined3d_device_set_material(device->wined3d_device, (const struct wined3d_material *)material); 1511c2c66affSColin Finck wined3d_mutex_unlock(); 1512c2c66affSColin Finck 1513c2c66affSColin Finck return D3D_OK; 1514c2c66affSColin Finck } 1515c2c66affSColin Finck 1516c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetMaterial(IDirect3DDevice8 *iface, D3DMATERIAL8 *material) 1517c2c66affSColin Finck { 1518c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1519c2c66affSColin Finck 1520c2c66affSColin Finck TRACE("iface %p, material %p.\n", iface, material); 1521c2c66affSColin Finck 1522c2c66affSColin Finck /* Note: D3DMATERIAL8 is compatible with struct wined3d_material. */ 1523c2c66affSColin Finck wined3d_mutex_lock(); 1524c2c66affSColin Finck wined3d_device_get_material(device->wined3d_device, (struct wined3d_material *)material); 1525c2c66affSColin Finck wined3d_mutex_unlock(); 1526c2c66affSColin Finck 1527c2c66affSColin Finck return D3D_OK; 1528c2c66affSColin Finck } 1529c2c66affSColin Finck 1530c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetLight(IDirect3DDevice8 *iface, DWORD index, const D3DLIGHT8 *light) 1531c2c66affSColin Finck { 1532c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1533c2c66affSColin Finck HRESULT hr; 1534c2c66affSColin Finck 1535c2c66affSColin Finck TRACE("iface %p, index %u, light %p.\n", iface, index, light); 1536c2c66affSColin Finck 1537c2c66affSColin Finck /* Note: D3DLIGHT8 is compatible with struct wined3d_light. */ 1538c2c66affSColin Finck wined3d_mutex_lock(); 1539c2c66affSColin Finck hr = wined3d_device_set_light(device->wined3d_device, index, (const struct wined3d_light *)light); 1540c2c66affSColin Finck wined3d_mutex_unlock(); 1541c2c66affSColin Finck 1542c2c66affSColin Finck return hr; 1543c2c66affSColin Finck } 1544c2c66affSColin Finck 1545c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetLight(IDirect3DDevice8 *iface, DWORD index, D3DLIGHT8 *light) 1546c2c66affSColin Finck { 1547c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1548c2c66affSColin Finck HRESULT hr; 1549c2c66affSColin Finck 1550c2c66affSColin Finck TRACE("iface %p, index %u, light %p.\n", iface, index, light); 1551c2c66affSColin Finck 1552c2c66affSColin Finck /* Note: D3DLIGHT8 is compatible with struct wined3d_light. */ 1553c2c66affSColin Finck wined3d_mutex_lock(); 1554c2c66affSColin Finck hr = wined3d_device_get_light(device->wined3d_device, index, (struct wined3d_light *)light); 1555c2c66affSColin Finck wined3d_mutex_unlock(); 1556c2c66affSColin Finck 1557c2c66affSColin Finck return hr; 1558c2c66affSColin Finck } 1559c2c66affSColin Finck 1560c2c66affSColin Finck static HRESULT WINAPI d3d8_device_LightEnable(IDirect3DDevice8 *iface, DWORD index, BOOL enable) 1561c2c66affSColin Finck { 1562c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1563c2c66affSColin Finck HRESULT hr; 1564c2c66affSColin Finck 1565c2c66affSColin Finck TRACE("iface %p, index %u, enable %#x.\n", iface, index, enable); 1566c2c66affSColin Finck 1567c2c66affSColin Finck wined3d_mutex_lock(); 1568c2c66affSColin Finck hr = wined3d_device_set_light_enable(device->wined3d_device, index, enable); 1569c2c66affSColin Finck wined3d_mutex_unlock(); 1570c2c66affSColin Finck 1571c2c66affSColin Finck return hr; 1572c2c66affSColin Finck } 1573c2c66affSColin Finck 1574c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetLightEnable(IDirect3DDevice8 *iface, DWORD index, BOOL *enable) 1575c2c66affSColin Finck { 1576c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1577c2c66affSColin Finck HRESULT hr; 1578c2c66affSColin Finck 1579c2c66affSColin Finck TRACE("iface %p, index %u, enable %p.\n", iface, index, enable); 1580c2c66affSColin Finck 1581c2c66affSColin Finck wined3d_mutex_lock(); 1582c2c66affSColin Finck hr = wined3d_device_get_light_enable(device->wined3d_device, index, enable); 1583c2c66affSColin Finck wined3d_mutex_unlock(); 1584c2c66affSColin Finck 1585c2c66affSColin Finck return hr; 1586c2c66affSColin Finck } 1587c2c66affSColin Finck 1588c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetClipPlane(IDirect3DDevice8 *iface, DWORD index, const float *plane) 1589c2c66affSColin Finck { 1590c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1591c2c66affSColin Finck HRESULT hr; 1592c2c66affSColin Finck 1593c2c66affSColin Finck TRACE("iface %p, index %u, plane %p.\n", iface, index, plane); 1594c2c66affSColin Finck 1595c2c66affSColin Finck wined3d_mutex_lock(); 1596c2c66affSColin Finck hr = wined3d_device_set_clip_plane(device->wined3d_device, index, (const struct wined3d_vec4 *)plane); 1597c2c66affSColin Finck wined3d_mutex_unlock(); 1598c2c66affSColin Finck 1599c2c66affSColin Finck return hr; 1600c2c66affSColin Finck } 1601c2c66affSColin Finck 1602c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetClipPlane(IDirect3DDevice8 *iface, DWORD index, float *plane) 1603c2c66affSColin Finck { 1604c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1605c2c66affSColin Finck HRESULT hr; 1606c2c66affSColin Finck 1607c2c66affSColin Finck TRACE("iface %p, index %u, plane %p.\n", iface, index, plane); 1608c2c66affSColin Finck 1609c2c66affSColin Finck wined3d_mutex_lock(); 1610c2c66affSColin Finck hr = wined3d_device_get_clip_plane(device->wined3d_device, index, (struct wined3d_vec4 *)plane); 1611c2c66affSColin Finck wined3d_mutex_unlock(); 1612c2c66affSColin Finck 1613c2c66affSColin Finck return hr; 1614c2c66affSColin Finck } 1615c2c66affSColin Finck 1616c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetRenderState(IDirect3DDevice8 *iface, 1617c2c66affSColin Finck D3DRENDERSTATETYPE state, DWORD value) 1618c2c66affSColin Finck { 1619c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1620c2c66affSColin Finck 1621c2c66affSColin Finck TRACE("iface %p, state %#x, value %#x.\n", iface, state, value); 1622c2c66affSColin Finck 1623c2c66affSColin Finck wined3d_mutex_lock(); 1624c2c66affSColin Finck switch (state) 1625c2c66affSColin Finck { 1626c2c66affSColin Finck case D3DRS_ZBIAS: 1627c2c66affSColin Finck wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_DEPTHBIAS, value); 1628c2c66affSColin Finck break; 1629c2c66affSColin Finck 1630c2c66affSColin Finck default: 1631c2c66affSColin Finck wined3d_device_set_render_state(device->wined3d_device, state, value); 1632c2c66affSColin Finck } 1633c2c66affSColin Finck wined3d_mutex_unlock(); 1634c2c66affSColin Finck 1635c2c66affSColin Finck return D3D_OK; 1636c2c66affSColin Finck } 1637c2c66affSColin Finck 1638c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetRenderState(IDirect3DDevice8 *iface, 1639c2c66affSColin Finck D3DRENDERSTATETYPE state, DWORD *value) 1640c2c66affSColin Finck { 1641c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1642c2c66affSColin Finck 1643c2c66affSColin Finck TRACE("iface %p, state %#x, value %p.\n", iface, state, value); 1644c2c66affSColin Finck 1645c2c66affSColin Finck wined3d_mutex_lock(); 1646c2c66affSColin Finck switch (state) 1647c2c66affSColin Finck { 1648c2c66affSColin Finck case D3DRS_ZBIAS: 1649c2c66affSColin Finck *value = wined3d_device_get_render_state(device->wined3d_device, WINED3D_RS_DEPTHBIAS); 1650c2c66affSColin Finck break; 1651c2c66affSColin Finck 1652c2c66affSColin Finck default: 1653c2c66affSColin Finck *value = wined3d_device_get_render_state(device->wined3d_device, state); 1654c2c66affSColin Finck } 1655c2c66affSColin Finck wined3d_mutex_unlock(); 1656c2c66affSColin Finck 1657c2c66affSColin Finck return D3D_OK; 1658c2c66affSColin Finck } 1659c2c66affSColin Finck 1660c2c66affSColin Finck static HRESULT WINAPI d3d8_device_BeginStateBlock(IDirect3DDevice8 *iface) 1661c2c66affSColin Finck { 1662c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1663c2c66affSColin Finck HRESULT hr; 1664c2c66affSColin Finck 1665c2c66affSColin Finck TRACE("iface %p.\n", iface); 1666c2c66affSColin Finck 1667c2c66affSColin Finck wined3d_mutex_lock(); 1668c2c66affSColin Finck hr = wined3d_device_begin_stateblock(device->wined3d_device); 1669c2c66affSColin Finck wined3d_mutex_unlock(); 1670c2c66affSColin Finck 1671c2c66affSColin Finck return hr; 1672c2c66affSColin Finck } 1673c2c66affSColin Finck 1674c2c66affSColin Finck static HRESULT WINAPI d3d8_device_EndStateBlock(IDirect3DDevice8 *iface, DWORD *token) 1675c2c66affSColin Finck { 1676c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1677c2c66affSColin Finck struct wined3d_stateblock *stateblock; 1678c2c66affSColin Finck HRESULT hr; 1679c2c66affSColin Finck 1680c2c66affSColin Finck TRACE("iface %p, token %p.\n", iface, token); 1681c2c66affSColin Finck 1682c2c66affSColin Finck /* Tell wineD3D to endstateblock before anything else (in case we run out 1683c2c66affSColin Finck * of memory later and cause locking problems) 1684c2c66affSColin Finck */ 1685c2c66affSColin Finck wined3d_mutex_lock(); 1686c2c66affSColin Finck hr = wined3d_device_end_stateblock(device->wined3d_device, &stateblock); 1687c2c66affSColin Finck if (FAILED(hr)) 1688c2c66affSColin Finck { 1689c2c66affSColin Finck WARN("Failed to end the state block, %#x.\n", hr); 1690c2c66affSColin Finck wined3d_mutex_unlock(); 1691c2c66affSColin Finck return hr; 1692c2c66affSColin Finck } 1693c2c66affSColin Finck 1694c2c66affSColin Finck *token = d3d8_allocate_handle(&device->handle_table, stateblock, D3D8_HANDLE_SB); 1695c2c66affSColin Finck wined3d_mutex_unlock(); 1696c2c66affSColin Finck 1697c2c66affSColin Finck if (*token == D3D8_INVALID_HANDLE) 1698c2c66affSColin Finck { 1699c2c66affSColin Finck ERR("Failed to create a handle\n"); 1700c2c66affSColin Finck wined3d_mutex_lock(); 1701c2c66affSColin Finck wined3d_stateblock_decref(stateblock); 1702c2c66affSColin Finck wined3d_mutex_unlock(); 1703c2c66affSColin Finck return E_FAIL; 1704c2c66affSColin Finck } 1705c2c66affSColin Finck ++*token; 1706c2c66affSColin Finck 1707c2c66affSColin Finck TRACE("Returning %#x (%p).\n", *token, stateblock); 1708c2c66affSColin Finck 1709c2c66affSColin Finck return hr; 1710c2c66affSColin Finck } 1711c2c66affSColin Finck 1712c2c66affSColin Finck static HRESULT WINAPI d3d8_device_ApplyStateBlock(IDirect3DDevice8 *iface, DWORD token) 1713c2c66affSColin Finck { 1714c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1715c2c66affSColin Finck struct wined3d_stateblock *stateblock; 1716c2c66affSColin Finck 1717c2c66affSColin Finck TRACE("iface %p, token %#x.\n", iface, token); 1718c2c66affSColin Finck 1719c2c66affSColin Finck if (!token) 1720c2c66affSColin Finck return D3D_OK; 1721c2c66affSColin Finck 1722c2c66affSColin Finck wined3d_mutex_lock(); 1723c2c66affSColin Finck stateblock = d3d8_get_object(&device->handle_table, token - 1, D3D8_HANDLE_SB); 1724c2c66affSColin Finck if (!stateblock) 1725c2c66affSColin Finck { 1726c2c66affSColin Finck WARN("Invalid handle (%#x) passed.\n", token); 1727c2c66affSColin Finck wined3d_mutex_unlock(); 1728c2c66affSColin Finck return D3DERR_INVALIDCALL; 1729c2c66affSColin Finck } 1730c2c66affSColin Finck wined3d_stateblock_apply(stateblock); 1731c2c66affSColin Finck wined3d_mutex_unlock(); 1732c2c66affSColin Finck 1733c2c66affSColin Finck return D3D_OK; 1734c2c66affSColin Finck } 1735c2c66affSColin Finck 1736c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CaptureStateBlock(IDirect3DDevice8 *iface, DWORD token) 1737c2c66affSColin Finck { 1738c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1739c2c66affSColin Finck struct wined3d_stateblock *stateblock; 1740c2c66affSColin Finck 1741c2c66affSColin Finck TRACE("iface %p, token %#x.\n", iface, token); 1742c2c66affSColin Finck 1743c2c66affSColin Finck wined3d_mutex_lock(); 1744c2c66affSColin Finck stateblock = d3d8_get_object(&device->handle_table, token - 1, D3D8_HANDLE_SB); 1745c2c66affSColin Finck if (!stateblock) 1746c2c66affSColin Finck { 1747c2c66affSColin Finck WARN("Invalid handle (%#x) passed.\n", token); 1748c2c66affSColin Finck wined3d_mutex_unlock(); 1749c2c66affSColin Finck return D3DERR_INVALIDCALL; 1750c2c66affSColin Finck } 1751c2c66affSColin Finck wined3d_stateblock_capture(stateblock); 1752c2c66affSColin Finck wined3d_mutex_unlock(); 1753c2c66affSColin Finck 1754c2c66affSColin Finck return D3D_OK; 1755c2c66affSColin Finck } 1756c2c66affSColin Finck 1757c2c66affSColin Finck static HRESULT WINAPI d3d8_device_DeleteStateBlock(IDirect3DDevice8 *iface, DWORD token) 1758c2c66affSColin Finck { 1759c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1760c2c66affSColin Finck struct wined3d_stateblock *stateblock; 1761c2c66affSColin Finck 1762c2c66affSColin Finck TRACE("iface %p, token %#x.\n", iface, token); 1763c2c66affSColin Finck 1764c2c66affSColin Finck wined3d_mutex_lock(); 1765c2c66affSColin Finck stateblock = d3d8_free_handle(&device->handle_table, token - 1, D3D8_HANDLE_SB); 1766c2c66affSColin Finck 1767c2c66affSColin Finck if (!stateblock) 1768c2c66affSColin Finck { 1769c2c66affSColin Finck WARN("Invalid handle (%#x) passed.\n", token); 1770c2c66affSColin Finck wined3d_mutex_unlock(); 1771c2c66affSColin Finck return D3DERR_INVALIDCALL; 1772c2c66affSColin Finck } 1773c2c66affSColin Finck 1774c2c66affSColin Finck if (wined3d_stateblock_decref(stateblock)) 1775c2c66affSColin Finck { 1776c2c66affSColin Finck ERR("Stateblock %p has references left, this shouldn't happen.\n", stateblock); 1777c2c66affSColin Finck } 1778c2c66affSColin Finck wined3d_mutex_unlock(); 1779c2c66affSColin Finck 1780c2c66affSColin Finck return D3D_OK; 1781c2c66affSColin Finck } 1782c2c66affSColin Finck 1783c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreateStateBlock(IDirect3DDevice8 *iface, 1784c2c66affSColin Finck D3DSTATEBLOCKTYPE type, DWORD *handle) 1785c2c66affSColin Finck { 1786c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1787c2c66affSColin Finck struct wined3d_stateblock *stateblock; 1788c2c66affSColin Finck HRESULT hr; 1789c2c66affSColin Finck 1790c2c66affSColin Finck TRACE("iface %p, type %#x, handle %p.\n", iface, type, handle); 1791c2c66affSColin Finck 1792c2c66affSColin Finck if (type != D3DSBT_ALL 1793c2c66affSColin Finck && type != D3DSBT_PIXELSTATE 1794c2c66affSColin Finck && type != D3DSBT_VERTEXSTATE) 1795c2c66affSColin Finck { 1796c2c66affSColin Finck WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL\n"); 1797c2c66affSColin Finck return D3DERR_INVALIDCALL; 1798c2c66affSColin Finck } 1799c2c66affSColin Finck 1800c2c66affSColin Finck wined3d_mutex_lock(); 1801c2c66affSColin Finck hr = wined3d_stateblock_create(device->wined3d_device, (enum wined3d_stateblock_type)type, &stateblock); 1802c2c66affSColin Finck if (FAILED(hr)) 1803c2c66affSColin Finck { 1804c2c66affSColin Finck wined3d_mutex_unlock(); 1805c2c66affSColin Finck ERR("Failed to create the state block, hr %#x\n", hr); 1806c2c66affSColin Finck return hr; 1807c2c66affSColin Finck } 1808c2c66affSColin Finck 1809c2c66affSColin Finck *handle = d3d8_allocate_handle(&device->handle_table, stateblock, D3D8_HANDLE_SB); 1810c2c66affSColin Finck wined3d_mutex_unlock(); 1811c2c66affSColin Finck 1812c2c66affSColin Finck if (*handle == D3D8_INVALID_HANDLE) 1813c2c66affSColin Finck { 1814c2c66affSColin Finck ERR("Failed to allocate a handle.\n"); 1815c2c66affSColin Finck wined3d_mutex_lock(); 1816c2c66affSColin Finck wined3d_stateblock_decref(stateblock); 1817c2c66affSColin Finck wined3d_mutex_unlock(); 1818c2c66affSColin Finck return E_FAIL; 1819c2c66affSColin Finck } 1820c2c66affSColin Finck ++*handle; 1821c2c66affSColin Finck 1822c2c66affSColin Finck TRACE("Returning %#x (%p).\n", *handle, stateblock); 1823c2c66affSColin Finck 1824c2c66affSColin Finck return hr; 1825c2c66affSColin Finck } 1826c2c66affSColin Finck 1827c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetClipStatus(IDirect3DDevice8 *iface, const D3DCLIPSTATUS8 *clip_status) 1828c2c66affSColin Finck { 1829c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1830c2c66affSColin Finck HRESULT hr; 1831c2c66affSColin Finck 1832c2c66affSColin Finck TRACE("iface %p, clip_status %p.\n", iface, clip_status); 1833c2c66affSColin Finck /* FIXME: Verify that D3DCLIPSTATUS8 ~= struct wined3d_clip_status. */ 1834c2c66affSColin Finck 1835c2c66affSColin Finck wined3d_mutex_lock(); 1836c2c66affSColin Finck hr = wined3d_device_set_clip_status(device->wined3d_device, (const struct wined3d_clip_status *)clip_status); 1837c2c66affSColin Finck wined3d_mutex_unlock(); 1838c2c66affSColin Finck 1839c2c66affSColin Finck return hr; 1840c2c66affSColin Finck } 1841c2c66affSColin Finck 1842c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetClipStatus(IDirect3DDevice8 *iface, D3DCLIPSTATUS8 *clip_status) 1843c2c66affSColin Finck { 1844c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1845c2c66affSColin Finck HRESULT hr; 1846c2c66affSColin Finck 1847c2c66affSColin Finck TRACE("iface %p, clip_status %p.\n", iface, clip_status); 1848c2c66affSColin Finck 1849c2c66affSColin Finck wined3d_mutex_lock(); 1850c2c66affSColin Finck hr = wined3d_device_get_clip_status(device->wined3d_device, (struct wined3d_clip_status *)clip_status); 1851c2c66affSColin Finck wined3d_mutex_unlock(); 1852c2c66affSColin Finck 1853c2c66affSColin Finck return hr; 1854c2c66affSColin Finck } 1855c2c66affSColin Finck 1856c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetTexture(IDirect3DDevice8 *iface, DWORD stage, IDirect3DBaseTexture8 **texture) 1857c2c66affSColin Finck { 1858c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1859c2c66affSColin Finck struct wined3d_texture *wined3d_texture; 1860c2c66affSColin Finck struct d3d8_texture *texture_impl; 1861c2c66affSColin Finck 1862c2c66affSColin Finck TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); 1863c2c66affSColin Finck 1864c2c66affSColin Finck if (!texture) 1865c2c66affSColin Finck return D3DERR_INVALIDCALL; 1866c2c66affSColin Finck 1867c2c66affSColin Finck wined3d_mutex_lock(); 1868c2c66affSColin Finck if ((wined3d_texture = wined3d_device_get_texture(device->wined3d_device, stage))) 1869c2c66affSColin Finck { 1870c2c66affSColin Finck texture_impl = wined3d_texture_get_parent(wined3d_texture); 1871c2c66affSColin Finck *texture = &texture_impl->IDirect3DBaseTexture8_iface; 1872c2c66affSColin Finck IDirect3DBaseTexture8_AddRef(*texture); 1873c2c66affSColin Finck } 1874c2c66affSColin Finck else 1875c2c66affSColin Finck { 1876c2c66affSColin Finck *texture = NULL; 1877c2c66affSColin Finck } 1878c2c66affSColin Finck wined3d_mutex_unlock(); 1879c2c66affSColin Finck 1880c2c66affSColin Finck return D3D_OK; 1881c2c66affSColin Finck } 1882c2c66affSColin Finck 1883c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetTexture(IDirect3DDevice8 *iface, DWORD stage, IDirect3DBaseTexture8 *texture) 1884c2c66affSColin Finck { 1885c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1886c2c66affSColin Finck struct d3d8_texture *texture_impl; 1887c2c66affSColin Finck HRESULT hr; 1888c2c66affSColin Finck 1889c2c66affSColin Finck TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture); 1890c2c66affSColin Finck 1891c2c66affSColin Finck texture_impl = unsafe_impl_from_IDirect3DBaseTexture8(texture); 1892c2c66affSColin Finck 1893c2c66affSColin Finck wined3d_mutex_lock(); 1894c2c66affSColin Finck hr = wined3d_device_set_texture(device->wined3d_device, stage, 1895c2c66affSColin Finck texture_impl ? texture_impl->wined3d_texture : NULL); 1896c2c66affSColin Finck wined3d_mutex_unlock(); 1897c2c66affSColin Finck 1898c2c66affSColin Finck return hr; 1899c2c66affSColin Finck } 1900c2c66affSColin Finck 1901c2c66affSColin Finck static const struct tss_lookup 1902c2c66affSColin Finck { 1903c2c66affSColin Finck BOOL sampler_state; 1904c2c66affSColin Finck union 1905c2c66affSColin Finck { 1906c2c66affSColin Finck enum wined3d_texture_stage_state texture_state; 1907c2c66affSColin Finck enum wined3d_sampler_state sampler_state; 1908c2c66affSColin Finck } u; 1909c2c66affSColin Finck } 1910c2c66affSColin Finck tss_lookup[] = 1911c2c66affSColin Finck { 1912c2c66affSColin Finck {FALSE, {WINED3D_TSS_INVALID}}, /* 0, unused */ 1913c2c66affSColin Finck {FALSE, {WINED3D_TSS_COLOR_OP}}, /* 1, D3DTSS_COLOROP */ 1914c2c66affSColin Finck {FALSE, {WINED3D_TSS_COLOR_ARG1}}, /* 2, D3DTSS_COLORARG1 */ 1915c2c66affSColin Finck {FALSE, {WINED3D_TSS_COLOR_ARG2}}, /* 3, D3DTSS_COLORARG2 */ 1916c2c66affSColin Finck {FALSE, {WINED3D_TSS_ALPHA_OP}}, /* 4, D3DTSS_ALPHAOP */ 1917c2c66affSColin Finck {FALSE, {WINED3D_TSS_ALPHA_ARG1}}, /* 5, D3DTSS_ALPHAARG1 */ 1918c2c66affSColin Finck {FALSE, {WINED3D_TSS_ALPHA_ARG2}}, /* 6, D3DTSS_ALPHAARG2 */ 1919c2c66affSColin Finck {FALSE, {WINED3D_TSS_BUMPENV_MAT00}}, /* 7, D3DTSS_BUMPENVMAT00 */ 1920c2c66affSColin Finck {FALSE, {WINED3D_TSS_BUMPENV_MAT01}}, /* 8, D3DTSS_BUMPENVMAT01 */ 1921c2c66affSColin Finck {FALSE, {WINED3D_TSS_BUMPENV_MAT10}}, /* 9, D3DTSS_BUMPENVMAT10 */ 1922c2c66affSColin Finck {FALSE, {WINED3D_TSS_BUMPENV_MAT11}}, /* 10, D3DTSS_BUMPENVMAT11 */ 1923c2c66affSColin Finck {FALSE, {WINED3D_TSS_TEXCOORD_INDEX}}, /* 11, D3DTSS_TEXCOORDINDEX */ 1924c2c66affSColin Finck {FALSE, {WINED3D_TSS_INVALID}}, /* 12, unused */ 1925c2c66affSColin Finck {TRUE, {WINED3D_SAMP_ADDRESS_U}}, /* 13, D3DTSS_ADDRESSU */ 1926c2c66affSColin Finck {TRUE, {WINED3D_SAMP_ADDRESS_V}}, /* 14, D3DTSS_ADDRESSV */ 1927c2c66affSColin Finck {TRUE, {WINED3D_SAMP_BORDER_COLOR}}, /* 15, D3DTSS_BORDERCOLOR */ 1928c2c66affSColin Finck {TRUE, {WINED3D_SAMP_MAG_FILTER}}, /* 16, D3DTSS_MAGFILTER */ 1929c2c66affSColin Finck {TRUE, {WINED3D_SAMP_MIN_FILTER}}, /* 17, D3DTSS_MINFILTER */ 1930c2c66affSColin Finck {TRUE, {WINED3D_SAMP_MIP_FILTER}}, /* 18, D3DTSS_MIPFILTER */ 1931c2c66affSColin Finck {TRUE, {WINED3D_SAMP_MIPMAP_LOD_BIAS}}, /* 19, D3DTSS_MIPMAPLODBIAS */ 1932c2c66affSColin Finck {TRUE, {WINED3D_SAMP_MAX_MIP_LEVEL}}, /* 20, D3DTSS_MAXMIPLEVEL */ 1933c2c66affSColin Finck {TRUE, {WINED3D_SAMP_MAX_ANISOTROPY}}, /* 21, D3DTSS_MAXANISOTROPY */ 1934c2c66affSColin Finck {FALSE, {WINED3D_TSS_BUMPENV_LSCALE}}, /* 22, D3DTSS_BUMPENVLSCALE */ 1935c2c66affSColin Finck {FALSE, {WINED3D_TSS_BUMPENV_LOFFSET}}, /* 23, D3DTSS_BUMPENVLOFFSET */ 1936c2c66affSColin Finck {FALSE, {WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS}}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */ 1937c2c66affSColin Finck {TRUE, {WINED3D_SAMP_ADDRESS_W}}, /* 25, D3DTSS_ADDRESSW */ 1938c2c66affSColin Finck {FALSE, {WINED3D_TSS_COLOR_ARG0}}, /* 26, D3DTSS_COLORARG0 */ 1939c2c66affSColin Finck {FALSE, {WINED3D_TSS_ALPHA_ARG0}}, /* 27, D3DTSS_ALPHAARG0 */ 1940c2c66affSColin Finck {FALSE, {WINED3D_TSS_RESULT_ARG}}, /* 28, D3DTSS_RESULTARG */ 1941c2c66affSColin Finck }; 1942c2c66affSColin Finck 1943c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetTextureStageState(IDirect3DDevice8 *iface, 1944c2c66affSColin Finck DWORD stage, D3DTEXTURESTAGESTATETYPE Type, DWORD *value) 1945c2c66affSColin Finck { 1946c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1947c2c66affSColin Finck const struct tss_lookup *l; 1948c2c66affSColin Finck 1949c2c66affSColin Finck TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, stage, Type, value); 1950c2c66affSColin Finck 1951c2c66affSColin Finck if (Type >= sizeof(tss_lookup) / sizeof(*tss_lookup)) 1952c2c66affSColin Finck { 1953c2c66affSColin Finck WARN("Invalid Type %#x passed.\n", Type); 1954c2c66affSColin Finck return D3D_OK; 1955c2c66affSColin Finck } 1956c2c66affSColin Finck 1957c2c66affSColin Finck l = &tss_lookup[Type]; 1958c2c66affSColin Finck 1959c2c66affSColin Finck wined3d_mutex_lock(); 1960c2c66affSColin Finck if (l->sampler_state) 1961c2c66affSColin Finck *value = wined3d_device_get_sampler_state(device->wined3d_device, stage, l->u.sampler_state); 1962c2c66affSColin Finck else 1963c2c66affSColin Finck *value = wined3d_device_get_texture_stage_state(device->wined3d_device, stage, l->u.texture_state); 1964c2c66affSColin Finck wined3d_mutex_unlock(); 1965c2c66affSColin Finck 1966c2c66affSColin Finck return D3D_OK; 1967c2c66affSColin Finck } 1968c2c66affSColin Finck 1969c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetTextureStageState(IDirect3DDevice8 *iface, 1970c2c66affSColin Finck DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value) 1971c2c66affSColin Finck { 1972c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1973c2c66affSColin Finck const struct tss_lookup *l; 1974c2c66affSColin Finck 1975c2c66affSColin Finck TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, stage, type, value); 1976c2c66affSColin Finck 1977c2c66affSColin Finck if (type >= sizeof(tss_lookup) / sizeof(*tss_lookup)) 1978c2c66affSColin Finck { 1979c2c66affSColin Finck WARN("Invalid type %#x passed.\n", type); 1980c2c66affSColin Finck return D3D_OK; 1981c2c66affSColin Finck } 1982c2c66affSColin Finck 1983c2c66affSColin Finck l = &tss_lookup[type]; 1984c2c66affSColin Finck 1985c2c66affSColin Finck wined3d_mutex_lock(); 1986c2c66affSColin Finck if (l->sampler_state) 1987c2c66affSColin Finck wined3d_device_set_sampler_state(device->wined3d_device, stage, l->u.sampler_state, value); 1988c2c66affSColin Finck else 1989c2c66affSColin Finck wined3d_device_set_texture_stage_state(device->wined3d_device, stage, l->u.texture_state, value); 1990c2c66affSColin Finck wined3d_mutex_unlock(); 1991c2c66affSColin Finck 1992c2c66affSColin Finck return D3D_OK; 1993c2c66affSColin Finck } 1994c2c66affSColin Finck 1995c2c66affSColin Finck static HRESULT WINAPI d3d8_device_ValidateDevice(IDirect3DDevice8 *iface, DWORD *pass_count) 1996c2c66affSColin Finck { 1997c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 1998c2c66affSColin Finck HRESULT hr; 1999c2c66affSColin Finck 2000c2c66affSColin Finck TRACE("iface %p, pass_count %p.\n", iface, pass_count); 2001c2c66affSColin Finck 2002c2c66affSColin Finck wined3d_mutex_lock(); 2003c2c66affSColin Finck hr = wined3d_device_validate_device(device->wined3d_device, pass_count); 2004c2c66affSColin Finck wined3d_mutex_unlock(); 2005c2c66affSColin Finck 2006c2c66affSColin Finck return hr; 2007c2c66affSColin Finck } 2008c2c66affSColin Finck 2009c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetInfo(IDirect3DDevice8 *iface, 2010c2c66affSColin Finck DWORD info_id, void *info, DWORD info_size) 2011c2c66affSColin Finck { 2012c2c66affSColin Finck FIXME("iface %p, info_id %#x, info %p, info_size %u stub!\n", iface, info_id, info, info_size); 2013c2c66affSColin Finck 2014c2c66affSColin Finck return D3D_OK; 2015c2c66affSColin Finck } 2016c2c66affSColin Finck 2017c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetPaletteEntries(IDirect3DDevice8 *iface, 2018c2c66affSColin Finck UINT palette_idx, const PALETTEENTRY *entries) 2019c2c66affSColin Finck { 2020c2c66affSColin Finck WARN("iface %p, palette_idx %u, entries %p unimplemented\n", iface, palette_idx, entries); 2021c2c66affSColin Finck 2022c2c66affSColin Finck /* GPUs stopped supporting palettized textures with the Shader Model 1 generation. Wined3d 2023c2c66affSColin Finck * does not have a d3d8/9-style palette API */ 2024c2c66affSColin Finck 2025c2c66affSColin Finck return D3D_OK; 2026c2c66affSColin Finck } 2027c2c66affSColin Finck 2028c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetPaletteEntries(IDirect3DDevice8 *iface, 2029c2c66affSColin Finck UINT palette_idx, PALETTEENTRY *entries) 2030c2c66affSColin Finck { 2031c2c66affSColin Finck FIXME("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, palette_idx, entries); 2032c2c66affSColin Finck 2033c2c66affSColin Finck return D3DERR_INVALIDCALL; 2034c2c66affSColin Finck } 2035c2c66affSColin Finck 2036c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetCurrentTexturePalette(IDirect3DDevice8 *iface, UINT palette_idx) 2037c2c66affSColin Finck { 2038c2c66affSColin Finck WARN("iface %p, palette_idx %u unimplemented.\n", iface, palette_idx); 2039c2c66affSColin Finck 2040c2c66affSColin Finck return D3D_OK; 2041c2c66affSColin Finck } 2042c2c66affSColin Finck 2043c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetCurrentTexturePalette(IDirect3DDevice8 *iface, UINT *palette_idx) 2044c2c66affSColin Finck { 2045c2c66affSColin Finck FIXME("iface %p, palette_idx %p unimplemented.\n", iface, palette_idx); 2046c2c66affSColin Finck 2047c2c66affSColin Finck return D3DERR_INVALIDCALL; 2048c2c66affSColin Finck } 2049c2c66affSColin Finck 2050c2c66affSColin Finck static HRESULT WINAPI d3d8_device_DrawPrimitive(IDirect3DDevice8 *iface, 2051c2c66affSColin Finck D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count) 2052c2c66affSColin Finck { 2053c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2054c2c66affSColin Finck HRESULT hr; 2055c2c66affSColin Finck 2056c2c66affSColin Finck TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n", 2057c2c66affSColin Finck iface, primitive_type, start_vertex, primitive_count); 2058c2c66affSColin Finck 2059c2c66affSColin Finck wined3d_mutex_lock(); 2060c2c66affSColin Finck wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); 2061c2c66affSColin Finck hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, 2062c2c66affSColin Finck vertex_count_from_primitive_count(primitive_type, primitive_count)); 2063c2c66affSColin Finck wined3d_mutex_unlock(); 2064c2c66affSColin Finck 2065c2c66affSColin Finck return hr; 2066c2c66affSColin Finck } 2067c2c66affSColin Finck 2068c2c66affSColin Finck static HRESULT WINAPI d3d8_device_DrawIndexedPrimitive(IDirect3DDevice8 *iface, 2069c2c66affSColin Finck D3DPRIMITIVETYPE primitive_type, UINT min_vertex_idx, UINT vertex_count, 2070c2c66affSColin Finck UINT start_idx, UINT primitive_count) 2071c2c66affSColin Finck { 2072c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2073c2c66affSColin Finck HRESULT hr; 2074c2c66affSColin Finck 2075c2c66affSColin Finck TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, start_idx %u, primitive_count %u.\n", 2076c2c66affSColin Finck iface, primitive_type, min_vertex_idx, vertex_count, start_idx, primitive_count); 2077c2c66affSColin Finck 2078c2c66affSColin Finck wined3d_mutex_lock(); 2079c2c66affSColin Finck wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); 2080c2c66affSColin Finck hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, 2081c2c66affSColin Finck vertex_count_from_primitive_count(primitive_type, primitive_count)); 2082c2c66affSColin Finck wined3d_mutex_unlock(); 2083c2c66affSColin Finck 2084c2c66affSColin Finck return hr; 2085c2c66affSColin Finck } 2086c2c66affSColin Finck 2087c2c66affSColin Finck /* The caller is responsible for wined3d locking */ 2088c2c66affSColin Finck static HRESULT d3d8_device_prepare_vertex_buffer(struct d3d8_device *device, UINT min_size) 2089c2c66affSColin Finck { 2090c2c66affSColin Finck HRESULT hr; 2091c2c66affSColin Finck 2092c2c66affSColin Finck if (device->vertex_buffer_size < min_size || !device->vertex_buffer) 2093c2c66affSColin Finck { 2094c2c66affSColin Finck UINT size = max(device->vertex_buffer_size * 2, min_size); 2095c2c66affSColin Finck struct wined3d_buffer *buffer; 2096c2c66affSColin Finck 2097c2c66affSColin Finck TRACE("Growing vertex buffer to %u bytes\n", size); 2098c2c66affSColin Finck 2099c2c66affSColin Finck hr = wined3d_buffer_create_vb(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, 2100c2c66affSColin Finck WINED3D_POOL_DEFAULT, NULL, &d3d8_null_wined3d_parent_ops, &buffer); 2101c2c66affSColin Finck if (FAILED(hr)) 2102c2c66affSColin Finck { 2103c2c66affSColin Finck ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x\n", device, hr); 2104c2c66affSColin Finck return hr; 2105c2c66affSColin Finck } 2106c2c66affSColin Finck 2107c2c66affSColin Finck if (device->vertex_buffer) 2108c2c66affSColin Finck wined3d_buffer_decref(device->vertex_buffer); 2109c2c66affSColin Finck 2110c2c66affSColin Finck device->vertex_buffer = buffer; 2111c2c66affSColin Finck device->vertex_buffer_size = size; 2112c2c66affSColin Finck device->vertex_buffer_pos = 0; 2113c2c66affSColin Finck } 2114c2c66affSColin Finck return D3D_OK; 2115c2c66affSColin Finck } 2116c2c66affSColin Finck 2117c2c66affSColin Finck static HRESULT WINAPI d3d8_device_DrawPrimitiveUP(IDirect3DDevice8 *iface, 2118c2c66affSColin Finck D3DPRIMITIVETYPE primitive_type, UINT primitive_count, const void *data, 2119c2c66affSColin Finck UINT stride) 2120c2c66affSColin Finck { 2121c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2122c2c66affSColin Finck HRESULT hr; 2123c2c66affSColin Finck UINT vtx_count = vertex_count_from_primitive_count(primitive_type, primitive_count); 2124c2c66affSColin Finck struct wined3d_map_desc wined3d_map_desc; 2125c2c66affSColin Finck struct wined3d_box wined3d_box = {0}; 2126c2c66affSColin Finck UINT size = vtx_count * stride; 2127c2c66affSColin Finck struct wined3d_resource *vb; 2128c2c66affSColin Finck UINT vb_pos, align; 2129c2c66affSColin Finck 2130c2c66affSColin Finck TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n", 2131c2c66affSColin Finck iface, primitive_type, primitive_count, data, stride); 2132c2c66affSColin Finck 2133c2c66affSColin Finck if (!primitive_count) 2134c2c66affSColin Finck { 2135c2c66affSColin Finck WARN("primitive_count is 0, returning D3D_OK\n"); 2136c2c66affSColin Finck return D3D_OK; 2137c2c66affSColin Finck } 2138c2c66affSColin Finck 2139c2c66affSColin Finck wined3d_mutex_lock(); 2140c2c66affSColin Finck hr = d3d8_device_prepare_vertex_buffer(device, size); 2141c2c66affSColin Finck if (FAILED(hr)) 2142c2c66affSColin Finck goto done; 2143c2c66affSColin Finck 2144c2c66affSColin Finck vb_pos = device->vertex_buffer_pos; 2145c2c66affSColin Finck align = vb_pos % stride; 2146c2c66affSColin Finck if (align) align = stride - align; 2147c2c66affSColin Finck if (vb_pos + size + align > device->vertex_buffer_size) 2148c2c66affSColin Finck vb_pos = 0; 2149c2c66affSColin Finck else 2150c2c66affSColin Finck vb_pos += align; 2151c2c66affSColin Finck 2152c2c66affSColin Finck wined3d_box.left = vb_pos; 2153c2c66affSColin Finck wined3d_box.right = vb_pos + size; 2154c2c66affSColin Finck vb = wined3d_buffer_get_resource(device->vertex_buffer); 2155c2c66affSColin Finck if (FAILED(wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, 2156c2c66affSColin Finck vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) 2157c2c66affSColin Finck goto done; 2158c2c66affSColin Finck memcpy(wined3d_map_desc.data, data, size); 2159c2c66affSColin Finck wined3d_resource_unmap(vb, 0); 2160c2c66affSColin Finck device->vertex_buffer_pos = vb_pos + size; 2161c2c66affSColin Finck 2162c2c66affSColin Finck hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, stride); 2163c2c66affSColin Finck if (FAILED(hr)) 2164c2c66affSColin Finck goto done; 2165c2c66affSColin Finck 2166c2c66affSColin Finck wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); 2167c2c66affSColin Finck hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count); 2168c2c66affSColin Finck wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0); 2169c2c66affSColin Finck 2170c2c66affSColin Finck done: 2171c2c66affSColin Finck wined3d_mutex_unlock(); 2172c2c66affSColin Finck return hr; 2173c2c66affSColin Finck } 2174c2c66affSColin Finck 2175c2c66affSColin Finck /* The caller is responsible for wined3d locking */ 2176c2c66affSColin Finck static HRESULT d3d8_device_prepare_index_buffer(struct d3d8_device *device, UINT min_size) 2177c2c66affSColin Finck { 2178c2c66affSColin Finck HRESULT hr; 2179c2c66affSColin Finck 2180c2c66affSColin Finck if (device->index_buffer_size < min_size || !device->index_buffer) 2181c2c66affSColin Finck { 2182c2c66affSColin Finck UINT size = max(device->index_buffer_size * 2, min_size); 2183c2c66affSColin Finck struct wined3d_buffer *buffer; 2184c2c66affSColin Finck 2185c2c66affSColin Finck TRACE("Growing index buffer to %u bytes\n", size); 2186c2c66affSColin Finck 2187c2c66affSColin Finck hr = wined3d_buffer_create_ib(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, 2188c2c66affSColin Finck WINED3D_POOL_DEFAULT, NULL, &d3d8_null_wined3d_parent_ops, &buffer); 2189c2c66affSColin Finck if (FAILED(hr)) 2190c2c66affSColin Finck { 2191c2c66affSColin Finck ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x\n", device, hr); 2192c2c66affSColin Finck return hr; 2193c2c66affSColin Finck } 2194c2c66affSColin Finck 2195c2c66affSColin Finck if (device->index_buffer) 2196c2c66affSColin Finck wined3d_buffer_decref(device->index_buffer); 2197c2c66affSColin Finck 2198c2c66affSColin Finck device->index_buffer = buffer; 2199c2c66affSColin Finck device->index_buffer_size = size; 2200c2c66affSColin Finck device->index_buffer_pos = 0; 2201c2c66affSColin Finck } 2202c2c66affSColin Finck return D3D_OK; 2203c2c66affSColin Finck } 2204c2c66affSColin Finck 2205c2c66affSColin Finck static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface, 2206c2c66affSColin Finck D3DPRIMITIVETYPE primitive_type, UINT min_vertex_idx, UINT vertex_count, 2207c2c66affSColin Finck UINT primitive_count, const void *index_data, D3DFORMAT index_format, 2208c2c66affSColin Finck const void *vertex_data, UINT vertex_stride) 2209c2c66affSColin Finck { 2210c2c66affSColin Finck UINT idx_count = vertex_count_from_primitive_count(primitive_type, primitive_count); 2211c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2212c2c66affSColin Finck UINT idx_fmt_size = index_format == D3DFMT_INDEX16 ? 2 : 4; 2213c2c66affSColin Finck UINT vtx_size = vertex_count * vertex_stride; 2214c2c66affSColin Finck UINT idx_size = idx_count * idx_fmt_size; 2215c2c66affSColin Finck struct wined3d_map_desc wined3d_map_desc; 2216c2c66affSColin Finck struct wined3d_box wined3d_box = {0}; 2217c2c66affSColin Finck struct wined3d_resource *ib, *vb; 2218c2c66affSColin Finck UINT vb_pos, ib_pos, align; 2219c2c66affSColin Finck HRESULT hr; 2220c2c66affSColin Finck 2221c2c66affSColin Finck TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, primitive_count %u, " 2222c2c66affSColin Finck "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n", 2223c2c66affSColin Finck iface, primitive_type, min_vertex_idx, vertex_count, primitive_count, 2224c2c66affSColin Finck index_data, index_format, vertex_data, vertex_stride); 2225c2c66affSColin Finck 2226c2c66affSColin Finck if (!primitive_count) 2227c2c66affSColin Finck { 2228c2c66affSColin Finck WARN("primitive_count is 0, returning D3D_OK\n"); 2229c2c66affSColin Finck return D3D_OK; 2230c2c66affSColin Finck } 2231c2c66affSColin Finck 2232c2c66affSColin Finck wined3d_mutex_lock(); 2233c2c66affSColin Finck 2234c2c66affSColin Finck hr = d3d8_device_prepare_vertex_buffer(device, vtx_size); 2235c2c66affSColin Finck if (FAILED(hr)) 2236c2c66affSColin Finck goto done; 2237c2c66affSColin Finck 2238c2c66affSColin Finck vb_pos = device->vertex_buffer_pos; 2239c2c66affSColin Finck align = vb_pos % vertex_stride; 2240c2c66affSColin Finck if (align) align = vertex_stride - align; 2241c2c66affSColin Finck if (vb_pos + vtx_size + align > device->vertex_buffer_size) 2242c2c66affSColin Finck vb_pos = 0; 2243c2c66affSColin Finck else 2244c2c66affSColin Finck vb_pos += align; 2245c2c66affSColin Finck 2246c2c66affSColin Finck wined3d_box.left = vb_pos; 2247c2c66affSColin Finck wined3d_box.right = vb_pos + vtx_size; 2248c2c66affSColin Finck vb = wined3d_buffer_get_resource(device->vertex_buffer); 2249c2c66affSColin Finck if (FAILED(hr = wined3d_resource_map(vb, 0, &wined3d_map_desc, &wined3d_box, 2250c2c66affSColin Finck vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) 2251c2c66affSColin Finck goto done; 2252c2c66affSColin Finck memcpy(wined3d_map_desc.data, (char *)vertex_data + min_vertex_idx * vertex_stride, vtx_size); 2253c2c66affSColin Finck wined3d_resource_unmap(vb, 0); 2254c2c66affSColin Finck device->vertex_buffer_pos = vb_pos + vtx_size; 2255c2c66affSColin Finck 2256c2c66affSColin Finck hr = d3d8_device_prepare_index_buffer(device, idx_size); 2257c2c66affSColin Finck if (FAILED(hr)) 2258c2c66affSColin Finck goto done; 2259c2c66affSColin Finck 2260c2c66affSColin Finck ib_pos = device->index_buffer_pos; 2261c2c66affSColin Finck align = ib_pos % idx_fmt_size; 2262c2c66affSColin Finck if (align) align = idx_fmt_size - align; 2263c2c66affSColin Finck if (ib_pos + idx_size + align > device->index_buffer_size) 2264c2c66affSColin Finck ib_pos = 0; 2265c2c66affSColin Finck else 2266c2c66affSColin Finck ib_pos += align; 2267c2c66affSColin Finck 2268c2c66affSColin Finck wined3d_box.left = ib_pos; 2269c2c66affSColin Finck wined3d_box.right = ib_pos + idx_size; 2270c2c66affSColin Finck ib = wined3d_buffer_get_resource(device->index_buffer); 2271c2c66affSColin Finck if (FAILED(hr = wined3d_resource_map(ib, 0, &wined3d_map_desc, &wined3d_box, 2272c2c66affSColin Finck ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD))) 2273c2c66affSColin Finck goto done; 2274c2c66affSColin Finck memcpy(wined3d_map_desc.data, index_data, idx_size); 2275c2c66affSColin Finck wined3d_resource_unmap(ib, 0); 2276c2c66affSColin Finck device->index_buffer_pos = ib_pos + idx_size; 2277c2c66affSColin Finck 2278c2c66affSColin Finck hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, vertex_stride); 2279c2c66affSColin Finck if (FAILED(hr)) 2280c2c66affSColin Finck goto done; 2281c2c66affSColin Finck 2282c2c66affSColin Finck wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, 2283c2c66affSColin Finck wined3dformat_from_d3dformat(index_format), 0); 2284c2c66affSColin Finck wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride - min_vertex_idx); 2285c2c66affSColin Finck 2286c2c66affSColin Finck wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); 2287c2c66affSColin Finck hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count); 2288c2c66affSColin Finck 2289c2c66affSColin Finck wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0); 2290c2c66affSColin Finck wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0); 2291c2c66affSColin Finck wined3d_device_set_base_vertex_index(device->wined3d_device, 0); 2292c2c66affSColin Finck 2293c2c66affSColin Finck done: 2294c2c66affSColin Finck wined3d_mutex_unlock(); 2295c2c66affSColin Finck return hr; 2296c2c66affSColin Finck } 2297c2c66affSColin Finck 2298c2c66affSColin Finck static HRESULT WINAPI d3d8_device_ProcessVertices(IDirect3DDevice8 *iface, UINT src_start_idx, 2299c2c66affSColin Finck UINT dst_idx, UINT vertex_count, IDirect3DVertexBuffer8 *dst_buffer, DWORD flags) 2300c2c66affSColin Finck { 2301c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2302c2c66affSColin Finck struct d3d8_vertexbuffer *dst = unsafe_impl_from_IDirect3DVertexBuffer8(dst_buffer); 2303c2c66affSColin Finck HRESULT hr; 2304c2c66affSColin Finck 2305c2c66affSColin Finck TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, flags %#x.\n", 2306c2c66affSColin Finck iface, src_start_idx, dst_idx, vertex_count, dst_buffer, flags); 2307c2c66affSColin Finck 2308c2c66affSColin Finck wined3d_mutex_lock(); 2309c2c66affSColin Finck hr = wined3d_device_process_vertices(device->wined3d_device, src_start_idx, dst_idx, 2310c2c66affSColin Finck vertex_count, dst->wined3d_buffer, NULL, flags, dst->fvf); 2311c2c66affSColin Finck wined3d_mutex_unlock(); 2312c2c66affSColin Finck 2313c2c66affSColin Finck return hr; 2314c2c66affSColin Finck } 2315c2c66affSColin Finck 2316c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreateVertexShader(IDirect3DDevice8 *iface, 2317c2c66affSColin Finck const DWORD *declaration, const DWORD *byte_code, DWORD *shader, DWORD usage) 2318c2c66affSColin Finck { 2319c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2320c2c66affSColin Finck struct d3d8_vertex_shader *object; 2321c2c66affSColin Finck DWORD shader_handle; 2322c2c66affSColin Finck DWORD handle; 2323c2c66affSColin Finck HRESULT hr; 2324c2c66affSColin Finck 2325c2c66affSColin Finck TRACE("iface %p, declaration %p, byte_code %p, shader %p, usage %#x.\n", 2326c2c66affSColin Finck iface, declaration, byte_code, shader, usage); 2327c2c66affSColin Finck 2328c2c66affSColin Finck object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 2329c2c66affSColin Finck if (!object) 2330c2c66affSColin Finck { 2331c2c66affSColin Finck *shader = 0; 2332c2c66affSColin Finck return E_OUTOFMEMORY; 2333c2c66affSColin Finck } 2334c2c66affSColin Finck 2335c2c66affSColin Finck wined3d_mutex_lock(); 2336c2c66affSColin Finck handle = d3d8_allocate_handle(&device->handle_table, object, D3D8_HANDLE_VS); 2337c2c66affSColin Finck wined3d_mutex_unlock(); 2338c2c66affSColin Finck if (handle == D3D8_INVALID_HANDLE) 2339c2c66affSColin Finck { 2340c2c66affSColin Finck ERR("Failed to allocate vertex shader handle.\n"); 2341c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, object); 2342c2c66affSColin Finck *shader = 0; 2343c2c66affSColin Finck return E_OUTOFMEMORY; 2344c2c66affSColin Finck } 2345c2c66affSColin Finck 2346c2c66affSColin Finck shader_handle = handle + VS_HIGHESTFIXEDFXF + 1; 2347c2c66affSColin Finck 2348c2c66affSColin Finck hr = d3d8_vertex_shader_init(object, device, declaration, byte_code, shader_handle, usage); 2349c2c66affSColin Finck if (FAILED(hr)) 2350c2c66affSColin Finck { 2351c2c66affSColin Finck WARN("Failed to initialize vertex shader, hr %#x.\n", hr); 2352c2c66affSColin Finck wined3d_mutex_lock(); 2353c2c66affSColin Finck d3d8_free_handle(&device->handle_table, handle, D3D8_HANDLE_VS); 2354c2c66affSColin Finck wined3d_mutex_unlock(); 2355c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, object); 2356c2c66affSColin Finck *shader = 0; 2357c2c66affSColin Finck return hr; 2358c2c66affSColin Finck } 2359c2c66affSColin Finck 2360c2c66affSColin Finck TRACE("Created vertex shader %p (handle %#x).\n", object, shader_handle); 2361c2c66affSColin Finck *shader = shader_handle; 2362c2c66affSColin Finck 2363c2c66affSColin Finck return D3D_OK; 2364c2c66affSColin Finck } 2365c2c66affSColin Finck 2366c2c66affSColin Finck static struct d3d8_vertex_declaration *d3d8_device_get_fvf_declaration(struct d3d8_device *device, DWORD fvf) 2367c2c66affSColin Finck { 2368c2c66affSColin Finck struct d3d8_vertex_declaration *d3d8_declaration; 2369c2c66affSColin Finck struct FvfToDecl *convertedDecls = device->decls; 2370c2c66affSColin Finck int p, low, high; /* deliberately signed */ 2371c2c66affSColin Finck HRESULT hr; 2372c2c66affSColin Finck 2373c2c66affSColin Finck TRACE("Searching for declaration for fvf %08x... ", fvf); 2374c2c66affSColin Finck 2375c2c66affSColin Finck low = 0; 2376c2c66affSColin Finck high = device->numConvertedDecls - 1; 2377c2c66affSColin Finck while (low <= high) 2378c2c66affSColin Finck { 2379c2c66affSColin Finck p = (low + high) >> 1; 2380c2c66affSColin Finck TRACE("%d ", p); 2381c2c66affSColin Finck 2382c2c66affSColin Finck if (convertedDecls[p].fvf == fvf) 2383c2c66affSColin Finck { 2384c2c66affSColin Finck TRACE("found %p\n", convertedDecls[p].declaration); 2385c2c66affSColin Finck return convertedDecls[p].declaration; 2386c2c66affSColin Finck } 2387c2c66affSColin Finck 2388c2c66affSColin Finck if (convertedDecls[p].fvf < fvf) 2389c2c66affSColin Finck low = p + 1; 2390c2c66affSColin Finck else 2391c2c66affSColin Finck high = p - 1; 2392c2c66affSColin Finck } 2393c2c66affSColin Finck TRACE("not found. Creating and inserting at position %d.\n", low); 2394c2c66affSColin Finck 2395c2c66affSColin Finck if (!(d3d8_declaration = HeapAlloc(GetProcessHeap(), 0, sizeof(*d3d8_declaration)))) 2396c2c66affSColin Finck return NULL; 2397c2c66affSColin Finck 2398c2c66affSColin Finck if (FAILED(hr = d3d8_vertex_declaration_init_fvf(d3d8_declaration, device, fvf))) 2399c2c66affSColin Finck { 2400c2c66affSColin Finck WARN("Failed to initialize vertex declaration, hr %#x.\n", hr); 2401c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, d3d8_declaration); 2402c2c66affSColin Finck return NULL; 2403c2c66affSColin Finck } 2404c2c66affSColin Finck 2405c2c66affSColin Finck if (device->declArraySize == device->numConvertedDecls) 2406c2c66affSColin Finck { 2407c2c66affSColin Finck UINT grow = device->declArraySize / 2; 2408c2c66affSColin Finck 2409c2c66affSColin Finck convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls, 2410c2c66affSColin Finck sizeof(*convertedDecls) * (device->numConvertedDecls + grow)); 2411c2c66affSColin Finck if (!convertedDecls) 2412c2c66affSColin Finck { 2413c2c66affSColin Finck d3d8_vertex_declaration_destroy(d3d8_declaration); 2414c2c66affSColin Finck return NULL; 2415c2c66affSColin Finck } 2416c2c66affSColin Finck device->decls = convertedDecls; 2417c2c66affSColin Finck device->declArraySize += grow; 2418c2c66affSColin Finck } 2419c2c66affSColin Finck 2420c2c66affSColin Finck memmove(convertedDecls + low + 1, convertedDecls + low, 2421c2c66affSColin Finck sizeof(*convertedDecls) * (device->numConvertedDecls - low)); 2422c2c66affSColin Finck convertedDecls[low].declaration = d3d8_declaration; 2423c2c66affSColin Finck convertedDecls[low].fvf = fvf; 2424c2c66affSColin Finck ++device->numConvertedDecls; 2425c2c66affSColin Finck 2426c2c66affSColin Finck TRACE("Returning %p. %u decls in array.\n", d3d8_declaration, device->numConvertedDecls); 2427c2c66affSColin Finck 2428c2c66affSColin Finck return d3d8_declaration; 2429c2c66affSColin Finck } 2430c2c66affSColin Finck 2431c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetVertexShader(IDirect3DDevice8 *iface, DWORD shader) 2432c2c66affSColin Finck { 2433c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2434c2c66affSColin Finck struct d3d8_vertex_shader *shader_impl; 2435c2c66affSColin Finck 2436c2c66affSColin Finck TRACE("iface %p, shader %#x.\n", iface, shader); 2437c2c66affSColin Finck 2438c2c66affSColin Finck if (VS_HIGHESTFIXEDFXF >= shader) 2439c2c66affSColin Finck { 2440c2c66affSColin Finck TRACE("Setting FVF, %#x\n", shader); 2441c2c66affSColin Finck 2442c2c66affSColin Finck wined3d_mutex_lock(); 2443c2c66affSColin Finck wined3d_device_set_vertex_declaration(device->wined3d_device, 2444c2c66affSColin Finck d3d8_device_get_fvf_declaration(device, shader)->wined3d_vertex_declaration); 2445c2c66affSColin Finck wined3d_device_set_vertex_shader(device->wined3d_device, NULL); 2446c2c66affSColin Finck wined3d_mutex_unlock(); 2447c2c66affSColin Finck 2448c2c66affSColin Finck return D3D_OK; 2449c2c66affSColin Finck } 2450c2c66affSColin Finck 2451c2c66affSColin Finck TRACE("Setting shader\n"); 2452c2c66affSColin Finck 2453c2c66affSColin Finck wined3d_mutex_lock(); 2454c2c66affSColin Finck if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS))) 2455c2c66affSColin Finck { 2456c2c66affSColin Finck WARN("Invalid handle (%#x) passed.\n", shader); 2457c2c66affSColin Finck wined3d_mutex_unlock(); 2458c2c66affSColin Finck 2459c2c66affSColin Finck return D3DERR_INVALIDCALL; 2460c2c66affSColin Finck } 2461c2c66affSColin Finck 2462c2c66affSColin Finck wined3d_device_set_vertex_declaration(device->wined3d_device, 2463c2c66affSColin Finck shader_impl->vertex_declaration->wined3d_vertex_declaration); 2464c2c66affSColin Finck wined3d_device_set_vertex_shader(device->wined3d_device, shader_impl->wined3d_shader); 2465c2c66affSColin Finck wined3d_mutex_unlock(); 2466c2c66affSColin Finck 2467c2c66affSColin Finck return D3D_OK; 2468c2c66affSColin Finck } 2469c2c66affSColin Finck 2470c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetVertexShader(IDirect3DDevice8 *iface, DWORD *shader) 2471c2c66affSColin Finck { 2472c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2473c2c66affSColin Finck struct wined3d_vertex_declaration *wined3d_declaration; 2474c2c66affSColin Finck struct d3d8_vertex_declaration *d3d8_declaration; 2475c2c66affSColin Finck 2476c2c66affSColin Finck TRACE("iface %p, shader %p.\n", iface, shader); 2477c2c66affSColin Finck 2478c2c66affSColin Finck wined3d_mutex_lock(); 2479c2c66affSColin Finck if ((wined3d_declaration = wined3d_device_get_vertex_declaration(device->wined3d_device))) 2480c2c66affSColin Finck { 2481c2c66affSColin Finck d3d8_declaration = wined3d_vertex_declaration_get_parent(wined3d_declaration); 2482c2c66affSColin Finck *shader = d3d8_declaration->shader_handle; 2483c2c66affSColin Finck } 2484c2c66affSColin Finck else 2485c2c66affSColin Finck { 2486c2c66affSColin Finck *shader = 0; 2487c2c66affSColin Finck } 2488c2c66affSColin Finck wined3d_mutex_unlock(); 2489c2c66affSColin Finck 2490c2c66affSColin Finck TRACE("Returning %#x.\n", *shader); 2491c2c66affSColin Finck 2492c2c66affSColin Finck return D3D_OK; 2493c2c66affSColin Finck } 2494c2c66affSColin Finck 2495c2c66affSColin Finck static HRESULT WINAPI d3d8_device_DeleteVertexShader(IDirect3DDevice8 *iface, DWORD shader) 2496c2c66affSColin Finck { 2497c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2498c2c66affSColin Finck struct d3d8_vertex_shader *shader_impl; 2499c2c66affSColin Finck 2500c2c66affSColin Finck TRACE("iface %p, shader %#x.\n", iface, shader); 2501c2c66affSColin Finck 2502c2c66affSColin Finck wined3d_mutex_lock(); 2503c2c66affSColin Finck if (!(shader_impl = d3d8_free_handle(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS))) 2504c2c66affSColin Finck { 2505c2c66affSColin Finck WARN("Invalid handle (%#x) passed.\n", shader); 2506c2c66affSColin Finck wined3d_mutex_unlock(); 2507c2c66affSColin Finck 2508c2c66affSColin Finck return D3DERR_INVALIDCALL; 2509c2c66affSColin Finck } 2510c2c66affSColin Finck 2511c2c66affSColin Finck if (shader_impl->wined3d_shader 2512c2c66affSColin Finck && wined3d_device_get_vertex_shader(device->wined3d_device) == shader_impl->wined3d_shader) 2513c2c66affSColin Finck IDirect3DDevice8_SetVertexShader(iface, 0); 2514c2c66affSColin Finck 2515c2c66affSColin Finck wined3d_mutex_unlock(); 2516c2c66affSColin Finck 2517c2c66affSColin Finck d3d8_vertex_shader_destroy(shader_impl); 2518c2c66affSColin Finck 2519c2c66affSColin Finck return D3D_OK; 2520c2c66affSColin Finck } 2521c2c66affSColin Finck 2522c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetVertexShaderConstant(IDirect3DDevice8 *iface, 2523c2c66affSColin Finck DWORD start_register, const void *data, DWORD count) 2524c2c66affSColin Finck { 2525c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2526c2c66affSColin Finck HRESULT hr; 2527c2c66affSColin Finck 2528c2c66affSColin Finck TRACE("iface %p, start_register %u, data %p, count %u.\n", 2529c2c66affSColin Finck iface, start_register, data, count); 2530c2c66affSColin Finck 2531c2c66affSColin Finck if (start_register + count > D3D8_MAX_VERTEX_SHADER_CONSTANTF) 2532c2c66affSColin Finck { 2533c2c66affSColin Finck WARN("Trying to access %u constants, but d3d8 only supports %u\n", 2534c2c66affSColin Finck start_register + count, D3D8_MAX_VERTEX_SHADER_CONSTANTF); 2535c2c66affSColin Finck return D3DERR_INVALIDCALL; 2536c2c66affSColin Finck } 2537c2c66affSColin Finck 2538c2c66affSColin Finck wined3d_mutex_lock(); 2539c2c66affSColin Finck hr = wined3d_device_set_vs_consts_f(device->wined3d_device, start_register, count, data); 2540c2c66affSColin Finck wined3d_mutex_unlock(); 2541c2c66affSColin Finck 2542c2c66affSColin Finck return hr; 2543c2c66affSColin Finck } 2544c2c66affSColin Finck 2545c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetVertexShaderConstant(IDirect3DDevice8 *iface, 2546c2c66affSColin Finck DWORD start_register, void *data, DWORD count) 2547c2c66affSColin Finck { 2548c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2549c2c66affSColin Finck HRESULT hr; 2550c2c66affSColin Finck 2551c2c66affSColin Finck TRACE("iface %p, start_register %u, data %p, count %u.\n", 2552c2c66affSColin Finck iface, start_register, data, count); 2553c2c66affSColin Finck 2554c2c66affSColin Finck if (start_register + count > D3D8_MAX_VERTEX_SHADER_CONSTANTF) 2555c2c66affSColin Finck { 2556c2c66affSColin Finck WARN("Trying to access %u constants, but d3d8 only supports %u\n", 2557c2c66affSColin Finck start_register + count, D3D8_MAX_VERTEX_SHADER_CONSTANTF); 2558c2c66affSColin Finck return D3DERR_INVALIDCALL; 2559c2c66affSColin Finck } 2560c2c66affSColin Finck 2561c2c66affSColin Finck wined3d_mutex_lock(); 2562c2c66affSColin Finck hr = wined3d_device_get_vs_consts_f(device->wined3d_device, start_register, count, data); 2563c2c66affSColin Finck wined3d_mutex_unlock(); 2564c2c66affSColin Finck 2565c2c66affSColin Finck return hr; 2566c2c66affSColin Finck } 2567c2c66affSColin Finck 2568c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetVertexShaderDeclaration(IDirect3DDevice8 *iface, 2569c2c66affSColin Finck DWORD shader, void *data, DWORD *data_size) 2570c2c66affSColin Finck { 2571c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2572c2c66affSColin Finck struct d3d8_vertex_declaration *declaration; 2573c2c66affSColin Finck struct d3d8_vertex_shader *shader_impl; 2574c2c66affSColin Finck 2575c2c66affSColin Finck TRACE("iface %p, shader %#x, data %p, data_size %p.\n", 2576c2c66affSColin Finck iface, shader, data, data_size); 2577c2c66affSColin Finck 2578c2c66affSColin Finck wined3d_mutex_lock(); 2579c2c66affSColin Finck shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS); 2580c2c66affSColin Finck wined3d_mutex_unlock(); 2581c2c66affSColin Finck 2582c2c66affSColin Finck if (!shader_impl) 2583c2c66affSColin Finck { 2584c2c66affSColin Finck WARN("Invalid handle (%#x) passed.\n", shader); 2585c2c66affSColin Finck return D3DERR_INVALIDCALL; 2586c2c66affSColin Finck } 2587c2c66affSColin Finck declaration = shader_impl->vertex_declaration; 2588c2c66affSColin Finck 2589c2c66affSColin Finck if (!data) 2590c2c66affSColin Finck { 2591c2c66affSColin Finck *data_size = declaration->elements_size; 2592c2c66affSColin Finck return D3D_OK; 2593c2c66affSColin Finck } 2594c2c66affSColin Finck 2595c2c66affSColin Finck /* MSDN claims that if *data_size is smaller than the required size 2596c2c66affSColin Finck * we should write the required size and return D3DERR_MOREDATA. 2597c2c66affSColin Finck * That's not actually true. */ 2598c2c66affSColin Finck if (*data_size < declaration->elements_size) 2599c2c66affSColin Finck return D3DERR_INVALIDCALL; 2600c2c66affSColin Finck 2601c2c66affSColin Finck memcpy(data, declaration->elements, declaration->elements_size); 2602c2c66affSColin Finck 2603c2c66affSColin Finck return D3D_OK; 2604c2c66affSColin Finck } 2605c2c66affSColin Finck 2606c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetVertexShaderFunction(IDirect3DDevice8 *iface, 2607c2c66affSColin Finck DWORD shader, void *data, DWORD *data_size) 2608c2c66affSColin Finck { 2609c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2610c2c66affSColin Finck struct d3d8_vertex_shader *shader_impl = NULL; 2611c2c66affSColin Finck HRESULT hr; 2612c2c66affSColin Finck 2613c2c66affSColin Finck TRACE("iface %p, shader %#x, data %p, data_size %p.\n", 2614c2c66affSColin Finck iface, shader, data, data_size); 2615c2c66affSColin Finck 2616c2c66affSColin Finck wined3d_mutex_lock(); 2617c2c66affSColin Finck if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS))) 2618c2c66affSColin Finck { 2619c2c66affSColin Finck WARN("Invalid handle (%#x) passed.\n", shader); 2620c2c66affSColin Finck wined3d_mutex_unlock(); 2621c2c66affSColin Finck 2622c2c66affSColin Finck return D3DERR_INVALIDCALL; 2623c2c66affSColin Finck } 2624c2c66affSColin Finck 2625c2c66affSColin Finck if (!shader_impl->wined3d_shader) 2626c2c66affSColin Finck { 2627c2c66affSColin Finck wined3d_mutex_unlock(); 2628c2c66affSColin Finck *data_size = 0; 2629c2c66affSColin Finck return D3D_OK; 2630c2c66affSColin Finck } 2631c2c66affSColin Finck 2632c2c66affSColin Finck hr = wined3d_shader_get_byte_code(shader_impl->wined3d_shader, data, data_size); 2633c2c66affSColin Finck wined3d_mutex_unlock(); 2634c2c66affSColin Finck 2635c2c66affSColin Finck return hr; 2636c2c66affSColin Finck } 2637c2c66affSColin Finck 2638c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetIndices(IDirect3DDevice8 *iface, 2639c2c66affSColin Finck IDirect3DIndexBuffer8 *buffer, UINT base_vertex_idx) 2640c2c66affSColin Finck { 2641c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2642c2c66affSColin Finck struct d3d8_indexbuffer *ib = unsafe_impl_from_IDirect3DIndexBuffer8(buffer); 2643c2c66affSColin Finck 2644c2c66affSColin Finck TRACE("iface %p, buffer %p, base_vertex_idx %u.\n", iface, buffer, base_vertex_idx); 2645c2c66affSColin Finck 2646c2c66affSColin Finck /* WineD3D takes an INT(due to d3d9), but d3d8 uses UINTs. Do I have to add a check here that 2647c2c66affSColin Finck * the UINT doesn't cause an overflow in the INT? It seems rather unlikely because such large 2648c2c66affSColin Finck * vertex buffers can't be created to address them with an index that requires the 32nd bit 2649c2c66affSColin Finck * (4 Byte minimum vertex size * 2^31-1 -> 8 gb buffer. The index sign would be the least 2650c2c66affSColin Finck * problem) 2651c2c66affSColin Finck */ 2652c2c66affSColin Finck wined3d_mutex_lock(); 2653c2c66affSColin Finck wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx); 2654c2c66affSColin Finck wined3d_device_set_index_buffer(device->wined3d_device, 2655c2c66affSColin Finck ib ? ib->wined3d_buffer : NULL, ib ? ib->format : WINED3DFMT_UNKNOWN, 0); 2656c2c66affSColin Finck wined3d_mutex_unlock(); 2657c2c66affSColin Finck 2658c2c66affSColin Finck return D3D_OK; 2659c2c66affSColin Finck } 2660c2c66affSColin Finck 2661c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetIndices(IDirect3DDevice8 *iface, 2662c2c66affSColin Finck IDirect3DIndexBuffer8 **buffer, UINT *base_vertex_index) 2663c2c66affSColin Finck { 2664c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2665c2c66affSColin Finck enum wined3d_format_id wined3d_format; 2666c2c66affSColin Finck struct wined3d_buffer *wined3d_buffer; 2667c2c66affSColin Finck struct d3d8_indexbuffer *buffer_impl; 2668c2c66affSColin Finck 2669c2c66affSColin Finck TRACE("iface %p, buffer %p, base_vertex_index %p.\n", iface, buffer, base_vertex_index); 2670c2c66affSColin Finck 2671c2c66affSColin Finck if (!buffer) 2672c2c66affSColin Finck return D3DERR_INVALIDCALL; 2673c2c66affSColin Finck 2674c2c66affSColin Finck /* The case from UINT to INT is safe because d3d8 will never set negative values */ 2675c2c66affSColin Finck wined3d_mutex_lock(); 2676c2c66affSColin Finck *base_vertex_index = wined3d_device_get_base_vertex_index(device->wined3d_device); 2677c2c66affSColin Finck if ((wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &wined3d_format, NULL))) 2678c2c66affSColin Finck { 2679c2c66affSColin Finck buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); 2680c2c66affSColin Finck *buffer = &buffer_impl->IDirect3DIndexBuffer8_iface; 2681c2c66affSColin Finck IDirect3DIndexBuffer8_AddRef(*buffer); 2682c2c66affSColin Finck } 2683c2c66affSColin Finck else 2684c2c66affSColin Finck { 2685c2c66affSColin Finck *buffer = NULL; 2686c2c66affSColin Finck } 2687c2c66affSColin Finck wined3d_mutex_unlock(); 2688c2c66affSColin Finck 2689c2c66affSColin Finck return D3D_OK; 2690c2c66affSColin Finck } 2691c2c66affSColin Finck 2692c2c66affSColin Finck static HRESULT WINAPI d3d8_device_CreatePixelShader(IDirect3DDevice8 *iface, 2693c2c66affSColin Finck const DWORD *byte_code, DWORD *shader) 2694c2c66affSColin Finck { 2695c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2696c2c66affSColin Finck struct d3d8_pixel_shader *object; 2697c2c66affSColin Finck DWORD shader_handle; 2698c2c66affSColin Finck DWORD handle; 2699c2c66affSColin Finck HRESULT hr; 2700c2c66affSColin Finck 2701c2c66affSColin Finck TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader); 2702c2c66affSColin Finck 2703c2c66affSColin Finck if (!shader) 2704c2c66affSColin Finck return D3DERR_INVALIDCALL; 2705c2c66affSColin Finck 2706c2c66affSColin Finck object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); 2707c2c66affSColin Finck if (!object) 2708c2c66affSColin Finck return E_OUTOFMEMORY; 2709c2c66affSColin Finck 2710c2c66affSColin Finck wined3d_mutex_lock(); 2711c2c66affSColin Finck handle = d3d8_allocate_handle(&device->handle_table, object, D3D8_HANDLE_PS); 2712c2c66affSColin Finck wined3d_mutex_unlock(); 2713c2c66affSColin Finck if (handle == D3D8_INVALID_HANDLE) 2714c2c66affSColin Finck { 2715c2c66affSColin Finck ERR("Failed to allocate pixel shader handle.\n"); 2716c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, object); 2717c2c66affSColin Finck return E_OUTOFMEMORY; 2718c2c66affSColin Finck } 2719c2c66affSColin Finck 2720c2c66affSColin Finck shader_handle = handle + VS_HIGHESTFIXEDFXF + 1; 2721c2c66affSColin Finck 2722c2c66affSColin Finck hr = d3d8_pixel_shader_init(object, device, byte_code, shader_handle); 2723c2c66affSColin Finck if (FAILED(hr)) 2724c2c66affSColin Finck { 2725c2c66affSColin Finck WARN("Failed to initialize pixel shader, hr %#x.\n", hr); 2726c2c66affSColin Finck wined3d_mutex_lock(); 2727c2c66affSColin Finck d3d8_free_handle(&device->handle_table, handle, D3D8_HANDLE_PS); 2728c2c66affSColin Finck wined3d_mutex_unlock(); 2729c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, object); 2730c2c66affSColin Finck *shader = 0; 2731c2c66affSColin Finck return hr; 2732c2c66affSColin Finck } 2733c2c66affSColin Finck 2734c2c66affSColin Finck TRACE("Created pixel shader %p (handle %#x).\n", object, shader_handle); 2735c2c66affSColin Finck *shader = shader_handle; 2736c2c66affSColin Finck 2737c2c66affSColin Finck return D3D_OK; 2738c2c66affSColin Finck } 2739c2c66affSColin Finck 2740c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetPixelShader(IDirect3DDevice8 *iface, DWORD shader) 2741c2c66affSColin Finck { 2742c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2743c2c66affSColin Finck struct d3d8_pixel_shader *shader_impl; 2744c2c66affSColin Finck 2745c2c66affSColin Finck TRACE("iface %p, shader %#x.\n", iface, shader); 2746c2c66affSColin Finck 2747c2c66affSColin Finck wined3d_mutex_lock(); 2748c2c66affSColin Finck 2749c2c66affSColin Finck if (!shader) 2750c2c66affSColin Finck { 2751c2c66affSColin Finck wined3d_device_set_pixel_shader(device->wined3d_device, NULL); 2752c2c66affSColin Finck wined3d_mutex_unlock(); 2753c2c66affSColin Finck return D3D_OK; 2754c2c66affSColin Finck } 2755c2c66affSColin Finck 2756c2c66affSColin Finck if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS))) 2757c2c66affSColin Finck { 2758c2c66affSColin Finck WARN("Invalid handle (%#x) passed.\n", shader); 2759c2c66affSColin Finck wined3d_mutex_unlock(); 2760c2c66affSColin Finck return D3DERR_INVALIDCALL; 2761c2c66affSColin Finck } 2762c2c66affSColin Finck 2763c2c66affSColin Finck TRACE("Setting shader %p.\n", shader_impl); 2764c2c66affSColin Finck wined3d_device_set_pixel_shader(device->wined3d_device, shader_impl->wined3d_shader); 2765c2c66affSColin Finck wined3d_mutex_unlock(); 2766c2c66affSColin Finck 2767c2c66affSColin Finck return D3D_OK; 2768c2c66affSColin Finck } 2769c2c66affSColin Finck 2770c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetPixelShader(IDirect3DDevice8 *iface, DWORD *shader) 2771c2c66affSColin Finck { 2772c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2773c2c66affSColin Finck struct wined3d_shader *object; 2774c2c66affSColin Finck 2775c2c66affSColin Finck TRACE("iface %p, shader %p.\n", iface, shader); 2776c2c66affSColin Finck 2777c2c66affSColin Finck if (!shader) 2778c2c66affSColin Finck return D3DERR_INVALIDCALL; 2779c2c66affSColin Finck 2780c2c66affSColin Finck wined3d_mutex_lock(); 2781c2c66affSColin Finck if ((object = wined3d_device_get_pixel_shader(device->wined3d_device))) 2782c2c66affSColin Finck { 2783c2c66affSColin Finck struct d3d8_pixel_shader *d3d8_shader; 2784c2c66affSColin Finck d3d8_shader = wined3d_shader_get_parent(object); 2785c2c66affSColin Finck *shader = d3d8_shader->handle; 2786c2c66affSColin Finck } 2787c2c66affSColin Finck else 2788c2c66affSColin Finck { 2789c2c66affSColin Finck *shader = 0; 2790c2c66affSColin Finck } 2791c2c66affSColin Finck wined3d_mutex_unlock(); 2792c2c66affSColin Finck 2793c2c66affSColin Finck TRACE("Returning %#x.\n", *shader); 2794c2c66affSColin Finck 2795c2c66affSColin Finck return D3D_OK; 2796c2c66affSColin Finck } 2797c2c66affSColin Finck 2798c2c66affSColin Finck static HRESULT WINAPI d3d8_device_DeletePixelShader(IDirect3DDevice8 *iface, DWORD shader) 2799c2c66affSColin Finck { 2800c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2801c2c66affSColin Finck struct d3d8_pixel_shader *shader_impl; 2802c2c66affSColin Finck 2803c2c66affSColin Finck TRACE("iface %p, shader %#x.\n", iface, shader); 2804c2c66affSColin Finck 2805c2c66affSColin Finck wined3d_mutex_lock(); 2806c2c66affSColin Finck 2807c2c66affSColin Finck if (!(shader_impl = d3d8_free_handle(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS))) 2808c2c66affSColin Finck { 2809c2c66affSColin Finck WARN("Invalid handle (%#x) passed.\n", shader); 2810c2c66affSColin Finck wined3d_mutex_unlock(); 2811c2c66affSColin Finck return D3DERR_INVALIDCALL; 2812c2c66affSColin Finck } 2813c2c66affSColin Finck 2814c2c66affSColin Finck if (wined3d_device_get_pixel_shader(device->wined3d_device) == shader_impl->wined3d_shader) 2815c2c66affSColin Finck IDirect3DDevice8_SetPixelShader(iface, 0); 2816c2c66affSColin Finck 2817c2c66affSColin Finck wined3d_mutex_unlock(); 2818c2c66affSColin Finck 2819c2c66affSColin Finck d3d8_pixel_shader_destroy(shader_impl); 2820c2c66affSColin Finck 2821c2c66affSColin Finck return D3D_OK; 2822c2c66affSColin Finck } 2823c2c66affSColin Finck 2824c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetPixelShaderConstant(IDirect3DDevice8 *iface, 2825c2c66affSColin Finck DWORD start_register, const void *data, DWORD count) 2826c2c66affSColin Finck { 2827c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2828c2c66affSColin Finck HRESULT hr; 2829c2c66affSColin Finck 2830c2c66affSColin Finck TRACE("iface %p, start_register %u, data %p, count %u.\n", 2831c2c66affSColin Finck iface, start_register, data, count); 2832c2c66affSColin Finck 2833c2c66affSColin Finck wined3d_mutex_lock(); 2834c2c66affSColin Finck hr = wined3d_device_set_ps_consts_f(device->wined3d_device, start_register, count, data); 2835c2c66affSColin Finck wined3d_mutex_unlock(); 2836c2c66affSColin Finck 2837c2c66affSColin Finck return hr; 2838c2c66affSColin Finck } 2839c2c66affSColin Finck 2840c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetPixelShaderConstant(IDirect3DDevice8 *iface, 2841c2c66affSColin Finck DWORD start_register, void *data, DWORD count) 2842c2c66affSColin Finck { 2843c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2844c2c66affSColin Finck HRESULT hr; 2845c2c66affSColin Finck 2846c2c66affSColin Finck TRACE("iface %p, start_register %u, data %p, count %u.\n", 2847c2c66affSColin Finck iface, start_register, data, count); 2848c2c66affSColin Finck 2849c2c66affSColin Finck wined3d_mutex_lock(); 2850c2c66affSColin Finck hr = wined3d_device_get_ps_consts_f(device->wined3d_device, start_register, count, data); 2851c2c66affSColin Finck wined3d_mutex_unlock(); 2852c2c66affSColin Finck 2853c2c66affSColin Finck return hr; 2854c2c66affSColin Finck } 2855c2c66affSColin Finck 2856c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetPixelShaderFunction(IDirect3DDevice8 *iface, 2857c2c66affSColin Finck DWORD shader, void *data, DWORD *data_size) 2858c2c66affSColin Finck { 2859c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2860c2c66affSColin Finck struct d3d8_pixel_shader *shader_impl = NULL; 2861c2c66affSColin Finck HRESULT hr; 2862c2c66affSColin Finck 2863c2c66affSColin Finck TRACE("iface %p, shader %#x, data %p, data_size %p.\n", 2864c2c66affSColin Finck iface, shader, data, data_size); 2865c2c66affSColin Finck 2866c2c66affSColin Finck wined3d_mutex_lock(); 2867c2c66affSColin Finck if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS))) 2868c2c66affSColin Finck { 2869c2c66affSColin Finck WARN("Invalid handle (%#x) passed.\n", shader); 2870c2c66affSColin Finck wined3d_mutex_unlock(); 2871c2c66affSColin Finck 2872c2c66affSColin Finck return D3DERR_INVALIDCALL; 2873c2c66affSColin Finck } 2874c2c66affSColin Finck 2875c2c66affSColin Finck hr = wined3d_shader_get_byte_code(shader_impl->wined3d_shader, data, data_size); 2876c2c66affSColin Finck wined3d_mutex_unlock(); 2877c2c66affSColin Finck 2878c2c66affSColin Finck return hr; 2879c2c66affSColin Finck } 2880c2c66affSColin Finck 2881c2c66affSColin Finck static HRESULT WINAPI d3d8_device_DrawRectPatch(IDirect3DDevice8 *iface, UINT handle, 2882c2c66affSColin Finck const float *segment_count, const D3DRECTPATCH_INFO *patch_info) 2883c2c66affSColin Finck { 2884c2c66affSColin Finck FIXME("iface %p, handle %#x, segment_count %p, patch_info %p unimplemented.\n", 2885c2c66affSColin Finck iface, handle, segment_count, patch_info); 2886c2c66affSColin Finck return D3D_OK; 2887c2c66affSColin Finck } 2888c2c66affSColin Finck 2889c2c66affSColin Finck static HRESULT WINAPI d3d8_device_DrawTriPatch(IDirect3DDevice8 *iface, UINT handle, 2890c2c66affSColin Finck const float *segment_count, const D3DTRIPATCH_INFO *patch_info) 2891c2c66affSColin Finck { 2892c2c66affSColin Finck FIXME("iface %p, handle %#x, segment_count %p, patch_info %p unimplemented.\n", 2893c2c66affSColin Finck iface, handle, segment_count, patch_info); 2894c2c66affSColin Finck return D3D_OK; 2895c2c66affSColin Finck } 2896c2c66affSColin Finck 2897c2c66affSColin Finck static HRESULT WINAPI d3d8_device_DeletePatch(IDirect3DDevice8 *iface, UINT handle) 2898c2c66affSColin Finck { 2899c2c66affSColin Finck FIXME("iface %p, handle %#x unimplemented.\n", iface, handle); 2900c2c66affSColin Finck return D3DERR_INVALIDCALL; 2901c2c66affSColin Finck } 2902c2c66affSColin Finck 2903c2c66affSColin Finck static HRESULT WINAPI d3d8_device_SetStreamSource(IDirect3DDevice8 *iface, 2904c2c66affSColin Finck UINT stream_idx, IDirect3DVertexBuffer8 *buffer, UINT stride) 2905c2c66affSColin Finck { 2906c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2907c2c66affSColin Finck struct d3d8_vertexbuffer *buffer_impl = unsafe_impl_from_IDirect3DVertexBuffer8(buffer); 2908c2c66affSColin Finck HRESULT hr; 2909c2c66affSColin Finck 2910c2c66affSColin Finck TRACE("iface %p, stream_idx %u, buffer %p, stride %u.\n", 2911c2c66affSColin Finck iface, stream_idx, buffer, stride); 2912c2c66affSColin Finck 2913c2c66affSColin Finck wined3d_mutex_lock(); 2914c2c66affSColin Finck hr = wined3d_device_set_stream_source(device->wined3d_device, stream_idx, 2915c2c66affSColin Finck buffer_impl ? buffer_impl->wined3d_buffer : NULL, 0, stride); 2916c2c66affSColin Finck wined3d_mutex_unlock(); 2917c2c66affSColin Finck 2918c2c66affSColin Finck return hr; 2919c2c66affSColin Finck } 2920c2c66affSColin Finck 2921c2c66affSColin Finck static HRESULT WINAPI d3d8_device_GetStreamSource(IDirect3DDevice8 *iface, 2922c2c66affSColin Finck UINT stream_idx, IDirect3DVertexBuffer8 **buffer, UINT *stride) 2923c2c66affSColin Finck { 2924c2c66affSColin Finck struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); 2925c2c66affSColin Finck struct d3d8_vertexbuffer *buffer_impl; 2926c2c66affSColin Finck struct wined3d_buffer *wined3d_buffer = NULL; 2927c2c66affSColin Finck HRESULT hr; 2928c2c66affSColin Finck 2929c2c66affSColin Finck TRACE("iface %p, stream_idx %u, buffer %p, stride %p.\n", 2930c2c66affSColin Finck iface, stream_idx, buffer, stride); 2931c2c66affSColin Finck 2932c2c66affSColin Finck if (!buffer) 2933c2c66affSColin Finck return D3DERR_INVALIDCALL; 2934c2c66affSColin Finck 2935c2c66affSColin Finck wined3d_mutex_lock(); 2936c2c66affSColin Finck hr = wined3d_device_get_stream_source(device->wined3d_device, stream_idx, &wined3d_buffer, 0, stride); 2937c2c66affSColin Finck if (SUCCEEDED(hr) && wined3d_buffer) 2938c2c66affSColin Finck { 2939c2c66affSColin Finck buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); 2940c2c66affSColin Finck *buffer = &buffer_impl->IDirect3DVertexBuffer8_iface; 2941c2c66affSColin Finck IDirect3DVertexBuffer8_AddRef(*buffer); 2942c2c66affSColin Finck } 2943c2c66affSColin Finck else 2944c2c66affSColin Finck { 2945c2c66affSColin Finck if (FAILED(hr)) 2946c2c66affSColin Finck ERR("Failed to get wined3d stream source, hr %#x.\n", hr); 2947c2c66affSColin Finck *buffer = NULL; 2948c2c66affSColin Finck } 2949c2c66affSColin Finck wined3d_mutex_unlock(); 2950c2c66affSColin Finck 2951c2c66affSColin Finck return hr; 2952c2c66affSColin Finck } 2953c2c66affSColin Finck 2954c2c66affSColin Finck static const struct IDirect3DDevice8Vtbl d3d8_device_vtbl = 2955c2c66affSColin Finck { 2956c2c66affSColin Finck d3d8_device_QueryInterface, 2957c2c66affSColin Finck d3d8_device_AddRef, 2958c2c66affSColin Finck d3d8_device_Release, 2959c2c66affSColin Finck d3d8_device_TestCooperativeLevel, 2960c2c66affSColin Finck d3d8_device_GetAvailableTextureMem, 2961c2c66affSColin Finck d3d8_device_ResourceManagerDiscardBytes, 2962c2c66affSColin Finck d3d8_device_GetDirect3D, 2963c2c66affSColin Finck d3d8_device_GetDeviceCaps, 2964c2c66affSColin Finck d3d8_device_GetDisplayMode, 2965c2c66affSColin Finck d3d8_device_GetCreationParameters, 2966c2c66affSColin Finck d3d8_device_SetCursorProperties, 2967c2c66affSColin Finck d3d8_device_SetCursorPosition, 2968c2c66affSColin Finck d3d8_device_ShowCursor, 2969c2c66affSColin Finck d3d8_device_CreateAdditionalSwapChain, 2970c2c66affSColin Finck d3d8_device_Reset, 2971c2c66affSColin Finck d3d8_device_Present, 2972c2c66affSColin Finck d3d8_device_GetBackBuffer, 2973c2c66affSColin Finck d3d8_device_GetRasterStatus, 2974c2c66affSColin Finck d3d8_device_SetGammaRamp, 2975c2c66affSColin Finck d3d8_device_GetGammaRamp, 2976c2c66affSColin Finck d3d8_device_CreateTexture, 2977c2c66affSColin Finck d3d8_device_CreateVolumeTexture, 2978c2c66affSColin Finck d3d8_device_CreateCubeTexture, 2979c2c66affSColin Finck d3d8_device_CreateVertexBuffer, 2980c2c66affSColin Finck d3d8_device_CreateIndexBuffer, 2981c2c66affSColin Finck d3d8_device_CreateRenderTarget, 2982c2c66affSColin Finck d3d8_device_CreateDepthStencilSurface, 2983c2c66affSColin Finck d3d8_device_CreateImageSurface, 2984c2c66affSColin Finck d3d8_device_CopyRects, 2985c2c66affSColin Finck d3d8_device_UpdateTexture, 2986c2c66affSColin Finck d3d8_device_GetFrontBuffer, 2987c2c66affSColin Finck d3d8_device_SetRenderTarget, 2988c2c66affSColin Finck d3d8_device_GetRenderTarget, 2989c2c66affSColin Finck d3d8_device_GetDepthStencilSurface, 2990c2c66affSColin Finck d3d8_device_BeginScene, 2991c2c66affSColin Finck d3d8_device_EndScene, 2992c2c66affSColin Finck d3d8_device_Clear, 2993c2c66affSColin Finck d3d8_device_SetTransform, 2994c2c66affSColin Finck d3d8_device_GetTransform, 2995c2c66affSColin Finck d3d8_device_MultiplyTransform, 2996c2c66affSColin Finck d3d8_device_SetViewport, 2997c2c66affSColin Finck d3d8_device_GetViewport, 2998c2c66affSColin Finck d3d8_device_SetMaterial, 2999c2c66affSColin Finck d3d8_device_GetMaterial, 3000c2c66affSColin Finck d3d8_device_SetLight, 3001c2c66affSColin Finck d3d8_device_GetLight, 3002c2c66affSColin Finck d3d8_device_LightEnable, 3003c2c66affSColin Finck d3d8_device_GetLightEnable, 3004c2c66affSColin Finck d3d8_device_SetClipPlane, 3005c2c66affSColin Finck d3d8_device_GetClipPlane, 3006c2c66affSColin Finck d3d8_device_SetRenderState, 3007c2c66affSColin Finck d3d8_device_GetRenderState, 3008c2c66affSColin Finck d3d8_device_BeginStateBlock, 3009c2c66affSColin Finck d3d8_device_EndStateBlock, 3010c2c66affSColin Finck d3d8_device_ApplyStateBlock, 3011c2c66affSColin Finck d3d8_device_CaptureStateBlock, 3012c2c66affSColin Finck d3d8_device_DeleteStateBlock, 3013c2c66affSColin Finck d3d8_device_CreateStateBlock, 3014c2c66affSColin Finck d3d8_device_SetClipStatus, 3015c2c66affSColin Finck d3d8_device_GetClipStatus, 3016c2c66affSColin Finck d3d8_device_GetTexture, 3017c2c66affSColin Finck d3d8_device_SetTexture, 3018c2c66affSColin Finck d3d8_device_GetTextureStageState, 3019c2c66affSColin Finck d3d8_device_SetTextureStageState, 3020c2c66affSColin Finck d3d8_device_ValidateDevice, 3021c2c66affSColin Finck d3d8_device_GetInfo, 3022c2c66affSColin Finck d3d8_device_SetPaletteEntries, 3023c2c66affSColin Finck d3d8_device_GetPaletteEntries, 3024c2c66affSColin Finck d3d8_device_SetCurrentTexturePalette, 3025c2c66affSColin Finck d3d8_device_GetCurrentTexturePalette, 3026c2c66affSColin Finck d3d8_device_DrawPrimitive, 3027c2c66affSColin Finck d3d8_device_DrawIndexedPrimitive, 3028c2c66affSColin Finck d3d8_device_DrawPrimitiveUP, 3029c2c66affSColin Finck d3d8_device_DrawIndexedPrimitiveUP, 3030c2c66affSColin Finck d3d8_device_ProcessVertices, 3031c2c66affSColin Finck d3d8_device_CreateVertexShader, 3032c2c66affSColin Finck d3d8_device_SetVertexShader, 3033c2c66affSColin Finck d3d8_device_GetVertexShader, 3034c2c66affSColin Finck d3d8_device_DeleteVertexShader, 3035c2c66affSColin Finck d3d8_device_SetVertexShaderConstant, 3036c2c66affSColin Finck d3d8_device_GetVertexShaderConstant, 3037c2c66affSColin Finck d3d8_device_GetVertexShaderDeclaration, 3038c2c66affSColin Finck d3d8_device_GetVertexShaderFunction, 3039c2c66affSColin Finck d3d8_device_SetStreamSource, 3040c2c66affSColin Finck d3d8_device_GetStreamSource, 3041c2c66affSColin Finck d3d8_device_SetIndices, 3042c2c66affSColin Finck d3d8_device_GetIndices, 3043c2c66affSColin Finck d3d8_device_CreatePixelShader, 3044c2c66affSColin Finck d3d8_device_SetPixelShader, 3045c2c66affSColin Finck d3d8_device_GetPixelShader, 3046c2c66affSColin Finck d3d8_device_DeletePixelShader, 3047c2c66affSColin Finck d3d8_device_SetPixelShaderConstant, 3048c2c66affSColin Finck d3d8_device_GetPixelShaderConstant, 3049c2c66affSColin Finck d3d8_device_GetPixelShaderFunction, 3050c2c66affSColin Finck d3d8_device_DrawRectPatch, 3051c2c66affSColin Finck d3d8_device_DrawTriPatch, 3052c2c66affSColin Finck d3d8_device_DeletePatch, 3053c2c66affSColin Finck }; 3054c2c66affSColin Finck 3055c2c66affSColin Finck static inline struct d3d8_device *device_from_device_parent(struct wined3d_device_parent *device_parent) 3056c2c66affSColin Finck { 3057c2c66affSColin Finck return CONTAINING_RECORD(device_parent, struct d3d8_device, device_parent); 3058c2c66affSColin Finck } 3059c2c66affSColin Finck 3060c2c66affSColin Finck static void CDECL device_parent_wined3d_device_created(struct wined3d_device_parent *device_parent, 3061c2c66affSColin Finck struct wined3d_device *device) 3062c2c66affSColin Finck { 3063c2c66affSColin Finck TRACE("device_parent %p, device %p\n", device_parent, device); 3064c2c66affSColin Finck } 3065c2c66affSColin Finck 3066c2c66affSColin Finck static void CDECL device_parent_mode_changed(struct wined3d_device_parent *device_parent) 3067c2c66affSColin Finck { 3068c2c66affSColin Finck TRACE("device_parent %p.\n", device_parent); 3069c2c66affSColin Finck } 3070c2c66affSColin Finck 3071c2c66affSColin Finck static void CDECL device_parent_activate(struct wined3d_device_parent *device_parent, BOOL activate) 3072c2c66affSColin Finck { 3073c2c66affSColin Finck struct d3d8_device *device = device_from_device_parent(device_parent); 3074c2c66affSColin Finck 3075c2c66affSColin Finck TRACE("device_parent %p, activate %#x.\n", device_parent, activate); 3076c2c66affSColin Finck 3077c2c66affSColin Finck if (!activate) 3078c2c66affSColin Finck InterlockedCompareExchange(&device->device_state, D3D8_DEVICE_STATE_LOST, D3D8_DEVICE_STATE_OK); 3079c2c66affSColin Finck else 3080c2c66affSColin Finck InterlockedCompareExchange(&device->device_state, D3D8_DEVICE_STATE_NOT_RESET, D3D8_DEVICE_STATE_LOST); 3081c2c66affSColin Finck } 3082c2c66affSColin Finck 3083c2c66affSColin Finck static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent, 3084c2c66affSColin Finck struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, 3085c2c66affSColin Finck void **parent, const struct wined3d_parent_ops **parent_ops) 3086c2c66affSColin Finck { 3087c2c66affSColin Finck struct d3d8_surface *d3d_surface; 3088c2c66affSColin Finck 3089c2c66affSColin Finck TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", 3090c2c66affSColin Finck device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); 3091c2c66affSColin Finck 3092c2c66affSColin Finck if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface)))) 3093c2c66affSColin Finck return E_OUTOFMEMORY; 3094c2c66affSColin Finck 3095c2c66affSColin Finck surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); 3096c2c66affSColin Finck *parent = d3d_surface; 3097c2c66affSColin Finck TRACE("Created surface %p.\n", d3d_surface); 3098c2c66affSColin Finck 3099c2c66affSColin Finck return D3D_OK; 3100c2c66affSColin Finck } 3101c2c66affSColin Finck 3102c2c66affSColin Finck static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent, 3103c2c66affSColin Finck struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, 3104c2c66affSColin Finck void **parent, const struct wined3d_parent_ops **parent_ops) 3105c2c66affSColin Finck { 3106c2c66affSColin Finck struct d3d8_volume *d3d_volume; 3107c2c66affSColin Finck 3108c2c66affSColin Finck TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", 3109c2c66affSColin Finck device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops); 3110c2c66affSColin Finck 3111c2c66affSColin Finck if (!(d3d_volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_volume)))) 3112c2c66affSColin Finck return E_OUTOFMEMORY; 3113c2c66affSColin Finck 3114c2c66affSColin Finck volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops); 3115c2c66affSColin Finck *parent = d3d_volume; 3116c2c66affSColin Finck TRACE("Created volume %p.\n", d3d_volume); 3117c2c66affSColin Finck 3118c2c66affSColin Finck return D3D_OK; 3119c2c66affSColin Finck } 3120c2c66affSColin Finck 3121c2c66affSColin Finck static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent, 3122c2c66affSColin Finck void *container_parent, const struct wined3d_resource_desc *desc, DWORD texture_flags, 3123c2c66affSColin Finck struct wined3d_texture **texture) 3124c2c66affSColin Finck { 3125c2c66affSColin Finck struct d3d8_device *device = device_from_device_parent(device_parent); 3126c2c66affSColin Finck struct d3d8_surface *d3d_surface; 3127c2c66affSColin Finck HRESULT hr; 3128c2c66affSColin Finck 3129c2c66affSColin Finck TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n", 3130c2c66affSColin Finck device_parent, container_parent, desc, texture_flags, texture); 3131c2c66affSColin Finck 3132c2c66affSColin Finck if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1, 3133c2c66affSColin Finck texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, &device->IDirect3DDevice8_iface, 3134c2c66affSColin Finck &d3d8_null_wined3d_parent_ops, texture))) 3135c2c66affSColin Finck { 3136c2c66affSColin Finck WARN("Failed to create texture, hr %#x.\n", hr); 3137c2c66affSColin Finck return hr; 3138c2c66affSColin Finck } 3139c2c66affSColin Finck 3140c2c66affSColin Finck d3d_surface = wined3d_texture_get_sub_resource_parent(*texture, 0); 3141c2c66affSColin Finck d3d_surface->parent_device = &device->IDirect3DDevice8_iface; 3142c2c66affSColin Finck 3143c2c66affSColin Finck return hr; 3144c2c66affSColin Finck } 3145c2c66affSColin Finck 3146c2c66affSColin Finck static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent, 3147c2c66affSColin Finck struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain) 3148c2c66affSColin Finck { 3149c2c66affSColin Finck struct d3d8_device *device = device_from_device_parent(device_parent); 3150c2c66affSColin Finck struct d3d8_swapchain *d3d_swapchain; 3151c2c66affSColin Finck HRESULT hr; 3152c2c66affSColin Finck 3153c2c66affSColin Finck TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain); 3154c2c66affSColin Finck 3155c2c66affSColin Finck if (FAILED(hr = d3d8_swapchain_create(device, desc, &d3d_swapchain))) 3156c2c66affSColin Finck { 3157c2c66affSColin Finck WARN("Failed to create swapchain, hr %#x.\n", hr); 3158c2c66affSColin Finck *swapchain = NULL; 3159c2c66affSColin Finck return hr; 3160c2c66affSColin Finck } 3161c2c66affSColin Finck 3162c2c66affSColin Finck *swapchain = d3d_swapchain->wined3d_swapchain; 3163c2c66affSColin Finck wined3d_swapchain_incref(*swapchain); 3164c2c66affSColin Finck IDirect3DSwapChain8_Release(&d3d_swapchain->IDirect3DSwapChain8_iface); 3165c2c66affSColin Finck 3166c2c66affSColin Finck return hr; 3167c2c66affSColin Finck } 3168c2c66affSColin Finck 3169c2c66affSColin Finck static const struct wined3d_device_parent_ops d3d8_wined3d_device_parent_ops = 3170c2c66affSColin Finck { 3171c2c66affSColin Finck device_parent_wined3d_device_created, 3172c2c66affSColin Finck device_parent_mode_changed, 3173c2c66affSColin Finck device_parent_activate, 3174c2c66affSColin Finck device_parent_surface_created, 3175c2c66affSColin Finck device_parent_volume_created, 3176c2c66affSColin Finck device_parent_create_swapchain_texture, 3177c2c66affSColin Finck device_parent_create_swapchain, 3178c2c66affSColin Finck }; 3179c2c66affSColin Finck 3180c2c66affSColin Finck static void setup_fpu(void) 3181c2c66affSColin Finck { 3182c2c66affSColin Finck #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) 3183c2c66affSColin Finck WORD cw; 3184c2c66affSColin Finck __asm__ volatile ("fnstcw %0" : "=m" (cw)); 3185c2c66affSColin Finck cw = (cw & ~0xf3f) | 0x3f; 3186c2c66affSColin Finck __asm__ volatile ("fldcw %0" : : "m" (cw)); 3187c2c66affSColin Finck #elif defined(__i386__) && defined(_MSC_VER) 3188c2c66affSColin Finck WORD cw; 3189c2c66affSColin Finck __asm fnstcw cw; 3190c2c66affSColin Finck cw = (cw & ~0xf3f) | 0x3f; 3191c2c66affSColin Finck __asm fldcw cw; 3192c2c66affSColin Finck #else 3193c2c66affSColin Finck FIXME("FPU setup not implemented for this platform.\n"); 3194c2c66affSColin Finck #endif 3195c2c66affSColin Finck } 3196c2c66affSColin Finck 3197c2c66affSColin Finck HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wined3d *wined3d, UINT adapter, 3198c2c66affSColin Finck D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters) 3199c2c66affSColin Finck { 3200c2c66affSColin Finck struct wined3d_swapchain_desc swapchain_desc; 3201c2c66affSColin Finck struct wined3d_swapchain *wined3d_swapchain; 3202c2c66affSColin Finck HRESULT hr; 3203c2c66affSColin Finck 3204c2c66affSColin Finck device->IDirect3DDevice8_iface.lpVtbl = &d3d8_device_vtbl; 3205c2c66affSColin Finck device->device_parent.ops = &d3d8_wined3d_device_parent_ops; 3206c2c66affSColin Finck device->ref = 1; 3207c2c66affSColin Finck device->handle_table.entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 3208c2c66affSColin Finck D3D8_INITIAL_HANDLE_TABLE_SIZE * sizeof(*device->handle_table.entries)); 3209c2c66affSColin Finck if (!device->handle_table.entries) 3210c2c66affSColin Finck { 3211c2c66affSColin Finck ERR("Failed to allocate handle table memory.\n"); 3212c2c66affSColin Finck return E_OUTOFMEMORY; 3213c2c66affSColin Finck } 3214c2c66affSColin Finck device->handle_table.table_size = D3D8_INITIAL_HANDLE_TABLE_SIZE; 3215c2c66affSColin Finck 3216c2c66affSColin Finck if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu(); 3217c2c66affSColin Finck 3218c2c66affSColin Finck wined3d_mutex_lock(); 3219c2c66affSColin Finck hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4, 3220c2c66affSColin Finck &device->device_parent, &device->wined3d_device); 3221c2c66affSColin Finck if (FAILED(hr)) 3222c2c66affSColin Finck { 3223c2c66affSColin Finck WARN("Failed to create wined3d device, hr %#x.\n", hr); 3224c2c66affSColin Finck wined3d_mutex_unlock(); 3225c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, device->handle_table.entries); 3226c2c66affSColin Finck return hr; 3227c2c66affSColin Finck } 3228c2c66affSColin Finck 3229c2c66affSColin Finck if (!parameters->Windowed) 3230c2c66affSColin Finck { 3231c2c66affSColin Finck HWND device_window = parameters->hDeviceWindow; 3232c2c66affSColin Finck 3233c2c66affSColin Finck if (!focus_window) 3234c2c66affSColin Finck focus_window = device_window; 3235c2c66affSColin Finck if (FAILED(hr = wined3d_device_acquire_focus_window(device->wined3d_device, focus_window))) 3236c2c66affSColin Finck { 3237c2c66affSColin Finck ERR("Failed to acquire focus window, hr %#x.\n", hr); 3238c2c66affSColin Finck wined3d_device_decref(device->wined3d_device); 3239c2c66affSColin Finck wined3d_mutex_unlock(); 3240c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, device->handle_table.entries); 3241c2c66affSColin Finck return hr; 3242c2c66affSColin Finck } 3243c2c66affSColin Finck 3244c2c66affSColin Finck if (!device_window) 3245c2c66affSColin Finck device_window = focus_window; 3246c2c66affSColin Finck wined3d_device_setup_fullscreen_window(device->wined3d_device, device_window, 3247c2c66affSColin Finck parameters->BackBufferWidth, 3248c2c66affSColin Finck parameters->BackBufferHeight); 3249c2c66affSColin Finck } 3250c2c66affSColin Finck 3251c2c66affSColin Finck if (flags & D3DCREATE_MULTITHREADED) 3252c2c66affSColin Finck wined3d_device_set_multithreaded(device->wined3d_device); 3253c2c66affSColin Finck 3254c2c66affSColin Finck if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, parameters)) 3255c2c66affSColin Finck { 3256c2c66affSColin Finck wined3d_device_release_focus_window(device->wined3d_device); 3257c2c66affSColin Finck wined3d_device_decref(device->wined3d_device); 3258c2c66affSColin Finck wined3d_mutex_unlock(); 3259c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, device->handle_table.entries); 3260c2c66affSColin Finck return D3DERR_INVALIDCALL; 3261c2c66affSColin Finck } 3262c2c66affSColin Finck 3263*e6c95b14SAmine Khaldi if (FAILED(hr = wined3d_device_init_3d(device->wined3d_device, &swapchain_desc))) 3264c2c66affSColin Finck { 3265c2c66affSColin Finck WARN("Failed to initialize 3D, hr %#x.\n", hr); 3266c2c66affSColin Finck wined3d_device_release_focus_window(device->wined3d_device); 3267c2c66affSColin Finck wined3d_device_decref(device->wined3d_device); 3268c2c66affSColin Finck wined3d_mutex_unlock(); 3269c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, device->handle_table.entries); 3270c2c66affSColin Finck return hr; 3271c2c66affSColin Finck } 3272c2c66affSColin Finck 3273*e6c95b14SAmine Khaldi wined3d_device_set_render_state(device->wined3d_device, 3274*e6c95b14SAmine Khaldi WINED3D_RS_ZENABLE, !!swapchain_desc.enable_auto_depth_stencil); 3275c2c66affSColin Finck wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0); 3276c2c66affSColin Finck wined3d_mutex_unlock(); 3277c2c66affSColin Finck 3278c2c66affSColin Finck present_parameters_from_wined3d_swapchain_desc(parameters, &swapchain_desc); 3279c2c66affSColin Finck 3280c2c66affSColin Finck device->declArraySize = 16; 3281c2c66affSColin Finck device->decls = HeapAlloc(GetProcessHeap(), 0, device->declArraySize * sizeof(*device->decls)); 3282c2c66affSColin Finck if (!device->decls) 3283c2c66affSColin Finck { 3284c2c66affSColin Finck ERR("Failed to allocate FVF vertex declaration map memory.\n"); 3285c2c66affSColin Finck hr = E_OUTOFMEMORY; 3286c2c66affSColin Finck goto err; 3287c2c66affSColin Finck } 3288c2c66affSColin Finck 3289c2c66affSColin Finck wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, 0); 3290c2c66affSColin Finck device->implicit_swapchain = wined3d_swapchain_get_parent(wined3d_swapchain); 3291c2c66affSColin Finck 3292c2c66affSColin Finck device->d3d_parent = &parent->IDirect3D8_iface; 3293c2c66affSColin Finck IDirect3D8_AddRef(device->d3d_parent); 3294c2c66affSColin Finck 3295c2c66affSColin Finck return D3D_OK; 3296c2c66affSColin Finck 3297c2c66affSColin Finck err: 3298c2c66affSColin Finck wined3d_mutex_lock(); 3299c2c66affSColin Finck wined3d_device_uninit_3d(device->wined3d_device); 3300c2c66affSColin Finck wined3d_device_release_focus_window(device->wined3d_device); 3301c2c66affSColin Finck wined3d_device_decref(device->wined3d_device); 3302c2c66affSColin Finck wined3d_mutex_unlock(); 3303c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, device->handle_table.entries); 3304c2c66affSColin Finck return hr; 3305c2c66affSColin Finck } 3306