1/**************************************************************************
2 *
3 * Copyright 2010 Luca Barbieri
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "software"), to deal in the software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the software, and to
10 * permit persons to whom the software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 **************************************************************************/
26
27#include "d3d1xstutil.h"
28#include "galliumd3d10_1.h"
29#include <dxgi.h>
30#include "pipe/p_screen.h"
31#include "pipe/p_context.h"
32
33HRESULT D3D10CreateDevice1(
34	IDXGIAdapter *adapter,
35	D3D10_DRIVER_TYPE driver_type,
36	HMODULE software,
37	unsigned flags,
38	D3D10_FEATURE_LEVEL1 hardware_level,
39	unsigned sdk_version,
40	ID3D10Device1 **out_device
41)
42{
43	HRESULT hr;
44	ComPtr<IDXGIAdapter1> adapter_to_release;
45	if(!adapter)
46	{
47		ComPtr<IDXGIFactory1> factory;
48		hr = CreateDXGIFactory1(IID_IDXGIFactory1, (void**)&factory);
49		if(!SUCCEEDED(hr))
50			return hr;
51		hr = factory->EnumAdapters1(0, &adapter_to_release);
52		if(!SUCCEEDED(hr))
53			return hr;
54		adapter = adapter_to_release.p;
55	}
56	ComPtr<IGalliumAdapter> gallium_adapter;
57	hr = adapter->QueryInterface(IID_IGalliumAdapter, (void**)&gallium_adapter);
58	if(!SUCCEEDED(hr))
59		return hr;
60	struct pipe_screen* screen;
61	// TODO: what should D3D_DRIVER_TYPE_SOFTWARE return? fast or reference?
62	if(driver_type == D3D10_DRIVER_TYPE_REFERENCE)
63		screen = gallium_adapter->GetGalliumReferenceSoftwareScreen();
64	else if(driver_type == D3D10_DRIVER_TYPE_SOFTWARE || driver_type == D3D10_DRIVER_TYPE_WARP)
65		screen = gallium_adapter->GetGalliumFastSoftwareScreen();
66	else
67		screen = gallium_adapter->GetGalliumScreen();
68	if(!screen)
69		return E_FAIL;
70	struct pipe_context* context = screen->context_create(screen, 0);
71	if(!context)
72		return E_FAIL;
73	ComPtr<ID3D10Device1> device;
74	hr = GalliumD3D10DeviceCreate1(screen, context, TRUE, flags, adapter, &device);
75	if(!SUCCEEDED(hr))
76	{
77		context->destroy(context);
78		return hr;
79	}
80	if(out_device)
81		*out_device = device.steal();
82	return S_OK;
83}
84
85HRESULT WINAPI D3D10CreateDeviceAndSwapChain1(
86	IDXGIAdapter* adapter,
87	D3D10_DRIVER_TYPE driver_type,
88	HMODULE software,
89	unsigned flags,
90	D3D10_FEATURE_LEVEL1 hardware_level,
91	unsigned sdk_version,
92	DXGI_SWAP_CHAIN_DESC* swap_chain_desc,
93	IDXGISwapChain** out_swap_chain,
94	ID3D10Device1** out_device
95)
96{
97	ComPtr<ID3D10Device1> dev;
98	HRESULT hr;
99	hr = D3D10CreateDevice1(adapter, driver_type, software, flags, hardware_level, sdk_version, &dev);
100	if(!SUCCEEDED(hr))
101		return hr;
102	if(out_swap_chain)
103	{
104		ComPtr<IDXGIFactory> factory;
105		ComPtr<IDXGIDevice> dxgi_device;
106		ComPtr<IDXGIAdapter> adapter;
107		hr = dev->QueryInterface(IID_IDXGIDevice, (void**)&dxgi_device);
108		if(!SUCCEEDED(hr))
109			return hr;
110
111		hr = dxgi_device->GetAdapter(&adapter);
112		if(!SUCCEEDED(hr))
113			return hr;
114
115		adapter->GetParent(IID_IDXGIFactory, (void**)&factory);
116		hr = factory->CreateSwapChain(dev.p, (DXGI_SWAP_CHAIN_DESC*)swap_chain_desc, out_swap_chain);
117		if(!SUCCEEDED(hr))
118			return hr;
119	}
120	if(out_device)
121		*out_device = dev.steal();
122	return hr;
123}
124
125HRESULT D3D10CreateDevice(
126	IDXGIAdapter *adapter,
127	D3D10_DRIVER_TYPE driver_type,
128	HMODULE software,
129	unsigned flags,
130	unsigned sdk_version,
131	ID3D10Device **out_device
132)
133{
134	return D3D10CreateDevice1(adapter, driver_type, software, flags, D3D10_FEATURE_LEVEL_10_0, sdk_version, (ID3D10Device1**)out_device);
135}
136
137HRESULT WINAPI D3D10CreateDeviceAndSwapChain(
138	IDXGIAdapter* adapter,
139	D3D10_DRIVER_TYPE driver_type,
140	HMODULE software,
141	unsigned flags,
142	unsigned sdk_version,
143	DXGI_SWAP_CHAIN_DESC* swap_chain_desc,
144	IDXGISwapChain** out_swap_chain,
145	ID3D10Device** out_device
146)
147{
148	return D3D10CreateDeviceAndSwapChain1(adapter, driver_type, software, flags, D3D10_FEATURE_LEVEL_10_0, sdk_version, swap_chain_desc, out_swap_chain, (ID3D10Device1**)out_device);
149}
150