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