192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri/**************************************************************************
292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Copyright 2010 Luca Barbieri
492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Permission is hereby granted, free of charge, to any person obtaining
692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * a copy of this software and associated documentation files (the
70525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri * "software"), to deal in the software without restriction, including
892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * without limitation the rights to use, copy, modify, merge, publish,
90525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri * distribute, sublicense, and/or sell copies of the software, and to
100525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri * permit persons to whom the software is furnished to do so, subject to
1192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * the following conditions:
1292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
1392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * The above copyright notice and this permission notice (including the
1492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * next paragraph) shall be included in all copies or substantial
150525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri * portions of the software.
1692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
1792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
2192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
2292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
2592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri **************************************************************************/
2692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
2792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include "d3d1xstutil.h"
2892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include "galliumd3d11.h"
2992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include <dxgi.h>
3092bc1111f3c5dd3616bd591129aebd3f4307e5b4Kai Wasserbäch#include "pipe/p_screen.h"
3192bc1111f3c5dd3616bd591129aebd3f4307e5b4Kai Wasserbäch#include "pipe/p_context.h"
3292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
336c598c78bd17642d731cf57b8369cc794f64ba2fLuca BarbieriHRESULT D3D11CreateDevice(
340525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	IDXGIAdapter *adapter,
350525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	D3D_DRIVER_TYPE driver_type,
360525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	HMODULE software,
370525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	unsigned flags,
380525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	const D3D_FEATURE_LEVEL *feature_levels,
390525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	unsigned num_feature_levels,
400525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	unsigned sdk_version,
410525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	ID3D11Device **out_device,
420525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	D3D_FEATURE_LEVEL *feature_level,
430525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	ID3D11DeviceContext **out_immediate_context
4492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri)
4592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
4692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	HRESULT hr;
4792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IDXGIAdapter1> adapter_to_release;
480525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	if(!adapter)
4992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
5092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		ComPtr<IDXGIFactory1> factory;
5192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = CreateDXGIFactory1(IID_IDXGIFactory1, (void**)&factory);
5292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
5392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return hr;
5492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = factory->EnumAdapters1(0, &adapter_to_release);
5592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
5692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return hr;
570525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		adapter = adapter_to_release.p;
5892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
5992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IGalliumAdapter> gallium_adapter;
600525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	hr = adapter->QueryInterface(IID_IGalliumAdapter, (void**)&gallium_adapter);
6192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(!SUCCEEDED(hr))
6292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return hr;
6392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_screen* screen;
6492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	// TODO: what should D3D_DRIVER_TYPE_SOFTWARE return? fast or reference?
650525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	if(driver_type == D3D_DRIVER_TYPE_REFERENCE)
6692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		screen = gallium_adapter->GetGalliumReferenceSoftwareScreen();
670525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	else if(driver_type == D3D_DRIVER_TYPE_SOFTWARE || driver_type == D3D_DRIVER_TYPE_WARP)
6892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		screen = gallium_adapter->GetGalliumFastSoftwareScreen();
6992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	else
7092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		screen = gallium_adapter->GetGalliumScreen();
7192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(!screen)
7292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return E_FAIL;
7392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_context* context = screen->context_create(screen, 0);
7492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(!context)
7592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return E_FAIL;
7692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<ID3D11Device> device;
770525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	hr = GalliumD3D11DeviceCreate(screen, context, TRUE, flags, adapter, &device);
7892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(!SUCCEEDED(hr))
7992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
8092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		context->destroy(context);
8192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return hr;
8292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
830525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	if(out_immediate_context)
840525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		device->GetImmediateContext(out_immediate_context);
850525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	if(feature_level)
860525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*feature_level = device->GetFeatureLevel();
870525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	if(out_device)
880525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*out_device = device.steal();
8992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	return S_OK;
9092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
9192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
9292617aeac109481258f0c3863d09c1b8903d438bLuca BarbieriHRESULT WINAPI D3D11CreateDeviceAndSwapChain(
930525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	IDXGIAdapter* adapter,
940525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	D3D_DRIVER_TYPE driver_type,
950525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	HMODULE software,
960525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	unsigned flags,
970525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	CONST D3D_FEATURE_LEVEL* feature_levels,
980525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	unsigned num_feature_levels,
990525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	unsigned sdk_version,
1008224256946619fb25278718bbf4703e3b9d60c93Luca Barbieri	CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,
1010525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	IDXGISwapChain** out_swap_chain,
1020525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	ID3D11Device** out_device,
1030525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	D3D_FEATURE_LEVEL* feature_level,
1040525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	ID3D11DeviceContext** out_immediate_context )
10592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
10692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<ID3D11Device> dev;
10792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<ID3D11DeviceContext> ctx;
10892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	HRESULT hr;
1090525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	hr = D3D11CreateDevice(adapter, driver_type, software, flags, feature_levels, num_feature_levels, sdk_version, (ID3D11Device**)&dev, feature_level, (ID3D11DeviceContext**)&ctx);
11092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(!SUCCEEDED(hr))
11192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return hr;
1120525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	if(out_swap_chain)
11392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
11492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		ComPtr<IDXGIFactory> factory;
11592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		ComPtr<IDXGIDevice> dxgi_device;
11692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		ComPtr<IDXGIAdapter> adapter;
11792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = dev->QueryInterface(IID_IDXGIDevice, (void**)&dxgi_device);
11892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
11992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return hr;
12092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
12192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = dxgi_device->GetAdapter(&adapter);
12292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
12392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return hr;
12492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
12592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		adapter->GetParent(IID_IDXGIFactory, (void**)&factory);
1260525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		hr = factory->CreateSwapChain(dev.p, (DXGI_SWAP_CHAIN_DESC*)pSwapChainDesc, out_swap_chain);
12792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
12892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return hr;
12992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
1300525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	if(out_device)
1310525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*out_device = dev.steal();
1320525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	if(out_immediate_context)
1330525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*out_immediate_context = ctx.steal();
13492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	return hr;
13592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
136