dxgid3d11.cpp revision 92617aeac109481258f0c3863d09c1b8903d438b
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
792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * "Software"), to deal in the Software without restriction, including
892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * without limitation the rights to use, copy, modify, merge, publish,
992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * distribute, sublicense, and/or sell copies of the Software, and to
1092617aeac109481258f0c3863d09c1b8903d438bLuca 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
1592617aeac109481258f0c3863d09c1b8903d438bLuca 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>
3092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include <pipe/p_screen.h>
3192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include <pipe/p_context.h>
3292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
3392617aeac109481258f0c3863d09c1b8903d438bLuca BarbieriHRESULT  D3D11CreateDevice(
3492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__in_opt   IDXGIAdapter *pAdapter,
3592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__in   D3D_DRIVER_TYPE DriverType,
3692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__in   HMODULE Software,
3792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__in   unsigned Flags,
3892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__in_ecount_opt( FeatureLevels )  const D3D_FEATURE_LEVEL *pFeatureLevels,
3992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__in   unsigned FeatureLevels,
4092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__in   unsigned SDKVersion,
4192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__out_opt  ID3D11Device **ppDevice,
4292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__out_opt  D3D_FEATURE_LEVEL *pFeatureLevel,
4392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__out_opt  ID3D11DeviceContext **ppImmediateContext
4492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri)
4592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
4692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	HRESULT hr;
4792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IDXGIAdapter1> adapter_to_release;
4892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(!pAdapter)
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;
5792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pAdapter = adapter_to_release.p;
5892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
5992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IGalliumAdapter> gallium_adapter;
6092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	hr = pAdapter->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?
6592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(DriverType == D3D_DRIVER_TYPE_REFERENCE)
6692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		screen = gallium_adapter->GetGalliumReferenceSoftwareScreen();
6792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	else if(DriverType == D3D_DRIVER_TYPE_SOFTWARE || DriverType == 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;
7792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	hr = GalliumD3D11DeviceCreate(screen, context, TRUE, Flags, pAdapter, &device);
7892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(!SUCCEEDED(hr))
7992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
8092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		context->destroy(context);
8192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return hr;
8292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
8392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(ppImmediateContext)
8492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		device->GetImmediateContext(ppImmediateContext);
8592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(pFeatureLevel)
8692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*pFeatureLevel = device->GetFeatureLevel();
8792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(ppDevice)
8892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*ppDevice = device.steal();
8992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	return S_OK;
9092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
9192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
9292617aeac109481258f0c3863d09c1b8903d438bLuca BarbieriHRESULT WINAPI D3D11CreateDeviceAndSwapChain(
9392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__in_opt IDXGIAdapter* pAdapter,
9492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	D3D_DRIVER_TYPE DriverType,
9592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	HMODULE Software,
9692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned Flags,
9792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels,
9892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned FeatureLevels,
9992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned SDKVersion,
10092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,
10192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__out_opt IDXGISwapChain** ppSwapChain,
10292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__out_opt ID3D11Device** ppDevice,
10392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__out_opt D3D_FEATURE_LEVEL* pFeatureLevel,
10492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	__out_opt ID3D11DeviceContext** ppImmediateContext )
10592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
10692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<ID3D11Device> dev;
10792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<ID3D11DeviceContext> ctx;
10892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	HRESULT hr;
10992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	hr = D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, (ID3D11Device**)&dev, pFeatureLevel, (ID3D11DeviceContext**)&ctx);
11092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(!SUCCEEDED(hr))
11192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return hr;
11292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(ppSwapChain)
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);
12692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = factory->CreateSwapChain(dev.p, (DXGI_SWAP_CHAIN_DESC*)pSwapChainDesc, ppSwapChain);
12792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
12892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return hr;
12992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
13092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(ppDevice)
13192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*ppDevice = dev.steal();
13292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(ppImmediateContext)
13392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*ppImmediateContext = ctx.steal();
13492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	return hr;
13592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
136