HRESULT d3d10_texture2d_init(struct d3d10_texture2d *texture, struct d3d10_device *device, const D3D10_TEXTURE2D_DESC *desc) { struct wined3d_resource_desc wined3d_desc; HRESULT hr; texture->ID3D10Texture2D_iface.lpVtbl = &d3d10_texture2d_vtbl; texture->refcount = 1; texture->desc = *desc; if (desc->MipLevels == 1 && desc->ArraySize == 1) { IWineDXGIDevice *wine_device; hr = ID3D10Device_QueryInterface(&device->ID3D10Device_iface, &IID_IWineDXGIDevice, (void **)&wine_device); if (FAILED(hr)) { ERR("Device should implement IWineDXGIDevice\n"); return E_FAIL; } hr = IWineDXGIDevice_create_surface(wine_device, NULL, 0, NULL, (IUnknown *)&texture->ID3D10Texture2D_iface, (void **)&texture->dxgi_surface); IWineDXGIDevice_Release(wine_device); if (FAILED(hr)) { ERR("Failed to create DXGI surface, returning %#x\n", hr); return hr; } } if (desc->ArraySize != 1) FIXME("Array textures not implemented.\n"); if (desc->SampleDesc.Count > 1) FIXME("Multisampled textures not implemented.\n"); wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE; wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); wined3d_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = desc->SampleDesc.Quality; wined3d_desc.usage = wined3d_usage_from_d3d10core(desc->BindFlags, desc->Usage); wined3d_desc.pool = WINED3D_POOL_DEFAULT; wined3d_desc.width = desc->Width; wined3d_desc.height = desc->Height; wined3d_desc.depth = 1; wined3d_desc.size = 0; if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, desc->MipLevels, 0, texture, &d3d10_texture2d_wined3d_parent_ops, &texture->wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); if (texture->dxgi_surface) IUnknown_Release(texture->dxgi_surface); return hr; } texture->desc.MipLevels = wined3d_texture_get_level_count(texture->wined3d_texture); return S_OK; }
static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *iface, IUnknown *device, DXGI_SWAP_CHAIN_DESC *desc, IDXGISwapChain **swapchain) { struct wined3d_swapchain *wined3d_swapchain; struct wined3d_swapchain_desc wined3d_desc; IWineDXGIDevice *dxgi_device; HRESULT hr; FIXME("iface %p, device %p, desc %p, swapchain %p partial stub!\n", iface, device, desc, swapchain); hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device); if (FAILED(hr)) { ERR("This is not the device we're looking for\n"); return hr; } if (!desc->OutputWindow) { FIXME("No output window, should use factory output window\n"); } FIXME("Ignoring SwapEffect and Flags\n"); wined3d_desc.backbuffer_width = desc->BufferDesc.Width; wined3d_desc.backbuffer_height = desc->BufferDesc.Height; wined3d_desc.backbuffer_format = wined3dformat_from_dxgi_format(desc->BufferDesc.Format); wined3d_desc.backbuffer_count = desc->BufferCount; if (desc->SampleDesc.Count > 1) { wined3d_desc.multisample_type = desc->SampleDesc.Count; wined3d_desc.multisample_quality = desc->SampleDesc.Quality; } else { wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = 0; } wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; wined3d_desc.device_window = desc->OutputWindow; wined3d_desc.windowed = desc->Windowed; wined3d_desc.enable_auto_depth_stencil = FALSE; wined3d_desc.auto_depth_stencil_format = 0; wined3d_desc.flags = 0; /* WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL? */ wined3d_desc.refresh_rate = dxgi_rational_to_uint(&desc->BufferDesc.RefreshRate); wined3d_desc.swap_interval = WINED3DPRESENT_INTERVAL_DEFAULT; hr = IWineDXGIDevice_create_swapchain(dxgi_device, &wined3d_desc, &wined3d_swapchain); IWineDXGIDevice_Release(dxgi_device); if (FAILED(hr)) { WARN("Failed to create swapchain, hr %#x.\n", hr); return hr; } *swapchain = wined3d_swapchain_get_parent(wined3d_swapchain); return S_OK; }
HRESULT d3d10_texture2d_init(struct d3d10_texture2d *texture, struct d3d10_device *device, const D3D10_TEXTURE2D_DESC *desc) { HRESULT hr; texture->ID3D10Texture2D_iface.lpVtbl = &d3d10_texture2d_vtbl; texture->refcount = 1; texture->desc = *desc; if (desc->MipLevels == 1 && desc->ArraySize == 1) { IWineDXGIDevice *wine_device; hr = ID3D10Device_QueryInterface(&device->ID3D10Device_iface, &IID_IWineDXGIDevice, (void **)&wine_device); if (FAILED(hr)) { ERR("Device should implement IWineDXGIDevice\n"); return E_FAIL; } hr = IWineDXGIDevice_create_surface(wine_device, NULL, 0, NULL, (IUnknown *)&texture->ID3D10Texture2D_iface, (void **)&texture->dxgi_surface); IWineDXGIDevice_Release(wine_device); if (FAILED(hr)) { ERR("Failed to create DXGI surface, returning %#x\n", hr); return hr; } } FIXME("Implement DXGI<->wined3d usage conversion\n"); if (desc->ArraySize != 1) FIXME("Array textures not implemented.\n"); if (desc->SampleDesc.Count > 1) FIXME("Multisampled textures not implemented.\n"); hr = wined3d_texture_create_2d(device->wined3d_device, desc->Width, desc->Height, desc->MipLevels, desc->Usage, wined3dformat_from_dxgi_format(desc->Format), WINED3D_POOL_DEFAULT, texture, &d3d10_texture2d_wined3d_parent_ops, &texture->wined3d_texture); if (FAILED(hr)) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); if (texture->dxgi_surface) IDXGISurface_Release(texture->dxgi_surface); return hr; } return S_OK; }
HRESULT d3d10_texture2d_init(struct d3d10_texture2d *texture, struct d3d10_device *device, const D3D10_TEXTURE2D_DESC *desc) { HRESULT hr; texture->ID3D10Texture2D_iface.lpVtbl = &d3d10_texture2d_vtbl; texture->refcount = 1; texture->desc = *desc; if (desc->MipLevels == 1 && desc->ArraySize == 1) { IWineDXGIDevice *wine_device; hr = ID3D10Device_QueryInterface(&device->ID3D10Device_iface, &IID_IWineDXGIDevice, (void **)&wine_device); if (FAILED(hr)) { ERR("Device should implement IWineDXGIDevice\n"); return E_FAIL; } hr = IWineDXGIDevice_create_surface(wine_device, NULL, 0, NULL, (IUnknown *)&texture->ID3D10Texture2D_iface, (void **)&texture->dxgi_surface); IWineDXGIDevice_Release(wine_device); if (FAILED(hr)) { ERR("Failed to create DXGI surface, returning %#x\n", hr); return hr; } FIXME("Implement DXGI<->wined3d usage conversion\n"); hr = wined3d_surface_create(device->wined3d_device, desc->Width, desc->Height, wined3dformat_from_dxgi_format(desc->Format), 0, desc->Usage, WINED3DPOOL_DEFAULT, desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3DMULTISAMPLE_NONE, desc->SampleDesc.Quality, SURFACE_OPENGL, 0, texture, &d3d10_texture2d_wined3d_parent_ops, &texture->wined3d_surface); if (FAILED(hr)) { ERR("CreateSurface failed, returning %#x\n", hr); IDXGISurface_Release(texture->dxgi_surface); return hr; } } return S_OK; }
static HRESULT d3d_texture2d_init(struct d3d_texture2d *texture, struct d3d_device *device, const D3D11_TEXTURE2D_DESC *desc, const D3D11_SUBRESOURCE_DATA *data) { struct wined3d_resource_desc wined3d_desc; unsigned int levels; HRESULT hr; texture->ID3D11Texture2D_iface.lpVtbl = &d3d11_texture2d_vtbl; texture->ID3D10Texture2D_iface.lpVtbl = &d3d10_texture2d_vtbl; texture->refcount = 1; wined3d_mutex_lock(); wined3d_private_store_init(&texture->private_store); texture->desc = *desc; if (desc->ArraySize != 1) FIXME("Array textures not implemented.\n"); if (desc->SampleDesc.Count > 1) FIXME("Multisampled textures not implemented.\n"); wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE; wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); wined3d_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = desc->SampleDesc.Quality; wined3d_desc.usage = wined3d_usage_from_d3d11(desc->BindFlags, desc->Usage); wined3d_desc.pool = WINED3D_POOL_DEFAULT; wined3d_desc.width = desc->Width; wined3d_desc.height = desc->Height; wined3d_desc.depth = 1; wined3d_desc.size = 0; levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(desc->Width, desc->Height)) + 1; if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, levels, 0, (struct wined3d_sub_resource_data *)data, texture, &d3d_texture2d_wined3d_parent_ops, &texture->wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); wined3d_private_store_cleanup(&texture->private_store); wined3d_mutex_unlock(); return hr; } texture->desc.MipLevels = levels; if (desc->MipLevels == 1 && desc->ArraySize == 1) { IWineDXGIDevice *wine_device; if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice, (void **)&wine_device))) { ERR("Device should implement IWineDXGIDevice.\n"); wined3d_texture_decref(texture->wined3d_texture); wined3d_mutex_unlock(); return E_FAIL; } hr = IWineDXGIDevice_create_surface(wine_device, wined3d_texture_get_resource(texture->wined3d_texture), 0, NULL, (IUnknown *)&texture->ID3D10Texture2D_iface, (void **)&texture->dxgi_surface); IWineDXGIDevice_Release(wine_device); if (FAILED(hr)) { ERR("Failed to create DXGI surface, returning %#x\n", hr); texture->dxgi_surface = NULL; wined3d_texture_decref(texture->wined3d_texture); wined3d_mutex_unlock(); return hr; } } wined3d_mutex_unlock(); texture->device = &device->ID3D11Device_iface; ID3D11Device_AddRef(texture->device); return S_OK; }
static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *iface, IUnknown *device, DXGI_SWAP_CHAIN_DESC *desc, IDXGISwapChain **swapchain) { struct wined3d_swapchain *wined3d_swapchain; struct wined3d_swapchain_desc wined3d_desc; IWineDXGIDevice *dxgi_device; HRESULT hr; UINT min_buffer_count; FIXME("iface %p, device %p, desc %p, swapchain %p partial stub!\n", iface, device, desc, swapchain); switch (desc->SwapEffect) { case DXGI_SWAP_EFFECT_DISCARD: case DXGI_SWAP_EFFECT_SEQUENTIAL: min_buffer_count = 1; break; case DXGI_SWAP_EFFECT_FLIP_DISCARD: case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL: min_buffer_count = 2; break; default: WARN("Invalid swap effect %u used, returning DXGI_ERROR_INVALID_CALL.\n", desc->SwapEffect); return DXGI_ERROR_INVALID_CALL; } if (desc->BufferCount < min_buffer_count || desc->BufferCount > 16) { WARN("BufferCount is %u, returning DXGI_ERROR_INVALID_CALL.\n", desc->BufferCount); return DXGI_ERROR_INVALID_CALL; } if (!desc->OutputWindow) { FIXME("No output window, should use factory output window\n"); } hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device); if (FAILED(hr)) { ERR("This is not the device we're looking for\n"); return hr; } FIXME("Ignoring SwapEffect and Flags\n"); wined3d_desc.backbuffer_width = desc->BufferDesc.Width; wined3d_desc.backbuffer_height = desc->BufferDesc.Height; wined3d_desc.backbuffer_format = wined3dformat_from_dxgi_format(desc->BufferDesc.Format); wined3d_desc.backbuffer_count = desc->BufferCount; wined3d_sample_desc_from_dxgi(&wined3d_desc.multisample_type, &wined3d_desc.multisample_quality, &desc->SampleDesc); wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; wined3d_desc.device_window = desc->OutputWindow; wined3d_desc.windowed = desc->Windowed; wined3d_desc.enable_auto_depth_stencil = FALSE; wined3d_desc.auto_depth_stencil_format = 0; wined3d_desc.flags = 0; /* WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL? */ wined3d_desc.refresh_rate = dxgi_rational_to_uint(&desc->BufferDesc.RefreshRate); wined3d_desc.swap_interval = WINED3DPRESENT_INTERVAL_DEFAULT; wined3d_desc.auto_restore_display_mode = TRUE; hr = IWineDXGIDevice_create_swapchain(dxgi_device, &wined3d_desc, FALSE, &wined3d_swapchain); IWineDXGIDevice_Release(dxgi_device); if (FAILED(hr)) { WARN("Failed to create swapchain, hr %#x.\n", hr); return hr; } wined3d_mutex_lock(); *swapchain = wined3d_swapchain_get_parent(wined3d_swapchain); wined3d_mutex_unlock(); return S_OK; }
/* TODO: The DXGI swapchain desc is a bit nicer than WINED3DPRESENT_PARAMETERS, * change wined3d to use a structure more similar to DXGI. */ static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IWineDXGIFactory *iface, IUnknown *device, DXGI_SWAP_CHAIN_DESC *desc, IDXGISwapChain **swapchain) { WINED3DPRESENT_PARAMETERS present_parameters; IWineD3DSwapChain *wined3d_swapchain; IWineD3DDevice *wined3d_device; IWineDXGIDevice *dxgi_device; UINT count; HRESULT hr; FIXME("iface %p, device %p, desc %p, swapchain %p partial stub!\n", iface, device, desc, swapchain); hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device); if (FAILED(hr)) { ERR("This is not the device we're looking for\n"); return hr; } wined3d_device = IWineDXGIDevice_get_wined3d_device(dxgi_device); IWineDXGIDevice_Release(dxgi_device); count = IWineD3DDevice_GetNumberOfSwapChains(wined3d_device); if (count) { FIXME("Only a single swapchain supported.\n"); IWineD3DDevice_Release(wined3d_device); return E_FAIL; } if (!desc->OutputWindow) { FIXME("No output window, should use factory output window\n"); } FIXME("Ignoring SwapEffect and Flags\n"); present_parameters.BackBufferWidth = desc->BufferDesc.Width; present_parameters.BackBufferHeight = desc->BufferDesc.Height; present_parameters.BackBufferFormat = wined3dformat_from_dxgi_format(desc->BufferDesc.Format); present_parameters.BackBufferCount = desc->BufferCount; if (desc->SampleDesc.Count > 1) { present_parameters.MultiSampleType = desc->SampleDesc.Count; present_parameters.MultiSampleQuality = desc->SampleDesc.Quality; } else { present_parameters.MultiSampleType = WINED3DMULTISAMPLE_NONE; present_parameters.MultiSampleQuality = 0; } present_parameters.SwapEffect = WINED3DSWAPEFFECT_DISCARD; present_parameters.hDeviceWindow = desc->OutputWindow; present_parameters.Windowed = desc->Windowed; present_parameters.EnableAutoDepthStencil = FALSE; present_parameters.AutoDepthStencilFormat = 0; present_parameters.Flags = 0; /* WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL? */ present_parameters.FullScreen_RefreshRateInHz = desc->BufferDesc.RefreshRate.Numerator / desc->BufferDesc.RefreshRate.Denominator; present_parameters.PresentationInterval = WINED3DPRESENT_INTERVAL_DEFAULT; hr = IWineD3DDevice_Init3D(wined3d_device, &present_parameters); if (FAILED(hr)) { WARN("Failed to initialize 3D, returning %#x\n", hr); IWineD3DDevice_Release(wined3d_device); return hr; } hr = IWineD3DDevice_GetSwapChain(wined3d_device, 0, &wined3d_swapchain); IWineD3DDevice_Release(wined3d_device); if (FAILED(hr)) { WARN("Failed to get swapchain, returning %#x\n", hr); return hr; } hr = IWineD3DSwapChain_GetParent(wined3d_swapchain, (IUnknown **)swapchain); IUnknown_Release(wined3d_swapchain); if (FAILED(hr)) { WARN("Failed to get swapchain, returning %#x\n", hr); return hr; } /* FIXME? The swapchain is created with refcount 1 by the wined3d device, * but the wined3d device can't hold a real reference. */ IUnknown_Release(*swapchain); TRACE("Created IDXGISwapChain %p\n", *swapchain); return S_OK; }
static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChainForHwnd(IWineDXGIFactory *iface, IUnknown *device, HWND window, const DXGI_SWAP_CHAIN_DESC1 *desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc, IDXGIOutput *output, IDXGISwapChain1 **swapchain) { ID3D12CommandQueue *command_queue; unsigned int min_buffer_count; IWineDXGIDevice *dxgi_device; HRESULT hr; TRACE("iface %p, device %p, window %p, desc %p, fullscreen_desc %p, output %p, swapchain %p.\n", iface, device, window, desc, fullscreen_desc, output, swapchain); if (!device || !window || !desc || !swapchain) { WARN("Invalid pointer.\n"); return DXGI_ERROR_INVALID_CALL; } if (desc->Stereo) { FIXME("Stereo swapchains are not supported.\n"); return DXGI_ERROR_UNSUPPORTED; } switch (desc->SwapEffect) { case DXGI_SWAP_EFFECT_DISCARD: case DXGI_SWAP_EFFECT_SEQUENTIAL: min_buffer_count = 1; break; case DXGI_SWAP_EFFECT_FLIP_DISCARD: case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL: min_buffer_count = 2; if (desc->SampleDesc.Count != 1 || desc->SampleDesc.Quality) { WARN("Invalid sample desc %u, %u for swap effect %#x.\n", desc->SampleDesc.Count, desc->SampleDesc.Quality, desc->SwapEffect); return DXGI_ERROR_INVALID_CALL; } break; default: WARN("Invalid swap effect %u used.\n", desc->SwapEffect); return DXGI_ERROR_INVALID_CALL; } if (desc->BufferCount < min_buffer_count || desc->BufferCount > DXGI_MAX_SWAP_CHAIN_BUFFERS) { WARN("BufferCount is %u.\n", desc->BufferCount); return DXGI_ERROR_INVALID_CALL; } if (output) FIXME("Ignoring output %p.\n", output); if (SUCCEEDED(IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device))) { hr = d3d11_swapchain_create(dxgi_device, window, desc, fullscreen_desc, swapchain); IWineDXGIDevice_Release(dxgi_device); return hr; } if (SUCCEEDED(IUnknown_QueryInterface(device, &IID_ID3D12CommandQueue, (void **)&command_queue))) { hr = d3d12_swapchain_create(iface, command_queue, window, desc, fullscreen_desc, swapchain); ID3D12CommandQueue_Release(command_queue); return hr; } ERR("This is not the device we're looking for.\n"); return DXGI_ERROR_UNSUPPORTED; }