dxgi_native.cpp revision 881c05aa1ec22bb229a0bceae372d68f9fc91431
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 "dxgi_private.h"
2892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieriextern "C" {
2992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include "native.h"
3092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include <util/u_format.h>
3192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include <util/u_inlines.h>
3292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include <util/u_simple_shaders.h>
3392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include <pipe/p_shader_tokens.h>
3492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
3592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include <iostream>
3692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include <memory>
3792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
3892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGIOutput;
3992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGIAdapter;
4092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGISwapChain;
4192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGIFactory;
4292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
4392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** ppSwapChain);
4492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* adapter, const struct native_platform* platform, void* dpy, IDXGIAdapter1** ppAdapter);
4592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** ppOutput);
4692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic void GalliumDXGISwapChainRevalidate(IDXGISwapChain* swap_chain);
4792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
4892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieritemplate<typename Base = IDXGIObject, typename Parent = IDXGIObject>
4992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGIObject : public GalliumPrivateDataComObject<Base>
5092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
5192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<Parent> parent;
5292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
5392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	GalliumDXGIObject(Parent* p_parent = 0)
5492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
5592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		this->parent = p_parent;
5692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
5792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
5892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE GetParent(
5992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri            __in  REFIID riid,
6092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri            __out  void **ppParent)
6192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
6292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return parent->QueryInterface(riid, ppParent);
6392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
6492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
6592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
66e7624e23a3a374896863f54fe30dafd0bff8a91aLuca BarbieriCOM_INTERFACE(IGalliumDXGIBackend, IUnknown)
67e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
68e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieristruct GalliumDXGIIdentityBackend : public GalliumComObject<IGalliumDXGIBackend>
6992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
70e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	virtual void * STDMETHODCALLTYPE BeginPresent(
71e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		HWND hwnd,
72e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		void** window,
73e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		RECT *rect,
74e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		RGNDATA **rgndata,
75e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		BOOL* preserve_aspect_ratio
76e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	)
77e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	{
78e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		*window = (void*)hwnd;
79e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		rect->left = 0;
80e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		rect->top = 0;
81e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		rect->right = INT_MAX;
82e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		rect->bottom = INT_MAX;
83e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		*rgndata = 0;
84e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
85e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		// yes, because we like things looking good
86e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		*preserve_aspect_ratio = TRUE;
87e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		return 0;
88e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	}
89e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
90e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	virtual void STDMETHODCALLTYPE EndPresent(
91e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		HWND hwnd,
92e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		void* present_cookie
93e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	)
94e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	{}
95e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri};
9692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
9792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGIFactory : public GalliumDXGIObject<IDXGIFactory1, IUnknown>
9892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
9992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        HWND associated_window;
10092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_platform* platform;
10192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* display;
102e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	ComPtr<IGalliumDXGIBackend> backend;
10392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* resolver_cookie;
10492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
105e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	GalliumDXGIFactory(const struct native_platform* platform, void* display, IGalliumDXGIBackend* p_backend)
106e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	: GalliumDXGIObject<IDXGIFactory1, IUnknown>((IUnknown*)NULL), platform(platform), display(display)
107e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	  {
108e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(p_backend)
109e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			backend = p_backend;
110e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		else
111e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			backend.reset(new GalliumDXGIIdentityBackend());
112e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	}
11392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
11492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE EnumAdapters(
11592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	UINT Adapter,
11692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	__out  IDXGIAdapter **ppAdapter)
11792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
11892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return EnumAdapters1(Adapter, (IDXGIAdapter1**)ppAdapter);
11992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
12092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
12192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE EnumAdapters1(
12292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	UINT Adapter,
12392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	__out  IDXGIAdapter1 **ppAdapter)
12492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
12592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	*ppAdapter = 0;
12692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(Adapter == 0)
12792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
12892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return GalliumDXGIAdapterCreate(this, platform, display, ppAdapter);
12992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
13092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#if 0
13192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// TODO: enable this
13292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	if(platform == native_get_x11_platform())
13392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	{
13492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        		unsigned nscreens = ScreenCount((Display*)display);
13592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        		if(Adapter < nscreens)
13692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        		{
13792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        			unsigned def_screen = DefaultScreen(display);
13892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        			if(Adapter <= def_screen)
13992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        				--Adapter;
14092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        			*ppAdapter = GalliumDXGIAdapterCreate(this, platform, display, Adapter);
14192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        			return S_OK;
14292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        		}
14392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	}
14492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
14592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return DXGI_ERROR_NOT_FOUND;
14692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
14792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
14892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        /* TODO: this is a mysterious underdocumented magic API
14992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri         * Can we have multiple windows associated?
15092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri         * Can we have multiple windows associated if we use multiple factories?
15192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri         * If so, what should GetWindowAssociation return?
15292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri         * If not, does a new swapchain steal the association?
15392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri         * Does this act for existing swapchains? For new swapchains?
15492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri         */
15592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(
15692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	HWND WindowHandle,
15792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	UINT Flags)
15892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
15992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	/* TODO: actually implement, for Wine, X11 and KMS*/
16092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	associated_window = WindowHandle;
16192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return S_OK;
16292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
16392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
16492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation(
16592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	__out  HWND *pWindowHandle)
16692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
16792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	*pWindowHandle = associated_window;
16892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return S_OK;
16992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
17092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
17192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE CreateSwapChain(
17292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	__in  IUnknown *pDevice,
17392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	__in  DXGI_SWAP_CHAIN_DESC *pDesc,
17492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	__out  IDXGISwapChain **ppSwapChain)
17592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
17692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return GalliumDXGISwapChainCreate(this, pDevice, *pDesc, ppSwapChain);
17792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
17892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
17992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter(
18092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri            HMODULE Module,
18192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri            __out  IDXGIAdapter **ppAdapter)
18292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
18392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	/* TODO: ignore the module, and just create a Gallium software screen */
18492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	*ppAdapter = 0;
18592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return E_NOTIMPL;
18692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
18792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
18892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        /* TODO: support hotplug */
18992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual BOOL STDMETHODCALLTYPE IsCurrent( void)
19092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
19192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return TRUE;
19292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
19392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
19492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
19592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGIAdapter
19692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	: public GalliumMultiComObject<
19792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		  GalliumDXGIObject<IDXGIAdapter1, GalliumDXGIFactory>,
19892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		  IGalliumAdapter>
19992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
20092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct native_display* display;
20192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_config** configs;
20292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	std::unordered_multimap<unsigned, unsigned> configs_by_pipe_format;
20392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	std::unordered_map<unsigned, unsigned> configs_by_native_visual_id;
20492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_connector** connectors;
20592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned num_configs;
20692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	DXGI_ADAPTER_DESC1 desc;
20792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	std::vector<ComPtr<IDXGIOutput> > outputs;
20892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	int num_outputs;
20992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct native_event_handler handler;
21092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
21192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	GalliumDXGIAdapter(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy)
21292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
21392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		this->parent = factory;
21492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
21592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		handler.invalid_surface = handle_invalid_surface;
21692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		handler.new_drm_screen = dxgi_loader_create_drm_screen;
21792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		handler.new_sw_screen = dxgi_loader_create_sw_screen;
21892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		display = platform->create_display(dpy, &handler, this);
21992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!display)
22092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			throw E_FAIL;
22192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&desc, 0, sizeof(desc));
22292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		std::string s = std::string("GalliumD3D on ") + display->screen->get_name(display->screen) + " by " + display->screen->get_vendor(display->screen);
22392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
22492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* hopefully no one will decide to use UTF-8 in Gallium name/vendor strings */
22592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		for(int i = 0; i < std::min((int)s.size(), 127); ++i)
22692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			desc.Description[i] = (WCHAR)s[i];
22792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
22892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// TODO: add an interface to get these; for now, return mid/low values
22992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.DedicatedVideoMemory = 256 << 20;
23092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.DedicatedSystemMemory = 256 << 20;
23192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.SharedSystemMemory = 1024 << 20;
23292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
23392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// TODO: we should actually use an unique ID instead
23492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*(void**)&desc.AdapterLuid = dpy;
23592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
23692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		configs = display->get_configs(display, (int*)&num_configs);
23792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		for(unsigned i = 0; i < num_configs; ++i)
23892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
23992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(configs[i]->window_bit)
24092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
24192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				configs_by_pipe_format.insert(std::make_pair(configs[i]->color_format, i));
24292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				configs_by_native_visual_id[configs[i]->native_visual_id] = i;
24392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
24492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
24592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
24692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		connectors = 0;
24792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		num_outputs = 0;
24892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
24992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(display->modeset)
25092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
25192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			int num_crtcs;
25292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
25392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			connectors = display->modeset->get_connectors(display, &num_outputs, &num_crtcs);
25492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!connectors)
25592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				num_outputs = 0;
25692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else if(!num_outputs)
25792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
25892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				free(connectors);
25992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				connectors = 0;
26092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
26192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
26292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!num_outputs)
26392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			num_outputs = 1;
26492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
26592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
26692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	static void handle_invalid_surface(struct native_display *ndpy, struct native_surface *nsurf, unsigned int seq_num)
26792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
26892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		GalliumDXGISwapChainRevalidate((IDXGISwapChain*)nsurf->user_data);
26992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
27092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
27192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	~GalliumDXGIAdapter()
27292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
2736ce098631abf465e89b12d10c4e6713b9c843422Luca Barbieri		display->destroy(display);
27492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		free(configs);
27592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		free(connectors);
27692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
27792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
27892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE EnumOutputs(
27992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	UINT Output,
28092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	__out  IDXGIOutput **ppOutput)
28192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
28292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	if(Output >= (unsigned)num_outputs)
28392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        		return DXGI_ERROR_NOT_FOUND;
28492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
28592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	if(connectors)
28692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	{
28792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        		std::ostringstream ss;
28892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        		ss << "Output #" << Output;
28992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return GalliumDXGIOutputCreate(this, ss.str(), connectors[Output], ppOutput);
29092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	}
29192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	else
29292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        		return GalliumDXGIOutputCreate(this, "Unique output", NULL, ppOutput);
29392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
29492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
29592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE GetDesc(
29692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	__out  DXGI_ADAPTER_DESC *pDesc)
29792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
29892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	memcpy(pDesc, &desc, sizeof(*pDesc));
29992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return S_OK;
30092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
30192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
30292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE GetDesc1(
30392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	__out  DXGI_ADAPTER_DESC1 *pDesc)
30492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
30592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	memcpy(pDesc, &desc, sizeof(*pDesc));
30692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return S_OK;
30792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
30892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
30992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport(
31092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri            __in  REFGUID InterfaceName,
31192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri            __out  LARGE_INTEGER *pUMDVersion)
31292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
31392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	// these number was taken from Windows 7 with Catalyst 10.8: its meaning is unclear
31492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	if(InterfaceName == IID_ID3D11Device || InterfaceName == IID_ID3D10Device1 || InterfaceName == IID_ID3D10Device)
31592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	{
31692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        		pUMDVersion->QuadPart = 0x00080011000a0411ULL;
31792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        		return S_OK;
31892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	}
31992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return DXGI_ERROR_UNSUPPORTED;
32092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
32192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
32292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        pipe_screen* STDMETHODCALLTYPE GetGalliumScreen()
32392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
32492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return display->screen;
32592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
32692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
32792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        pipe_screen* STDMETHODCALLTYPE GetGalliumReferenceSoftwareScreen()
32892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
32992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	// TODO: give a softpipe screen
33092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return display->screen;
33192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
33292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
33392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        pipe_screen* STDMETHODCALLTYPE GetGalliumFastSoftwareScreen()
33492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
33592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// TODO: give an llvmpipe screen
33692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return display->screen;
33792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
33892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
33992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
34092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
34192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGIOutput : public GalliumDXGIObject<IDXGIOutput, GalliumDXGIAdapter>
34292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
34392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	DXGI_OUTPUT_DESC desc;
34492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_mode** modes;
34592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	DXGI_MODE_DESC* dxgi_modes;
34692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned num_modes;
34792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_connector* connector;
34892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	DXGI_GAMMA_CONTROL* gamma;
34992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
35092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	GalliumDXGIOutput(GalliumDXGIAdapter* adapter, std::string name, const struct native_connector* connector = 0)
351b4b2091655676ec3b898d3ae7298192aa7f9147fLuca Barbieri	: GalliumDXGIObject<IDXGIOutput, GalliumDXGIAdapter>(adapter), connector(connector)
35292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
35392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&desc, 0, sizeof(desc));
35492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		for(unsigned i = 0; i < std::min(name.size(), sizeof(desc.DeviceName) - 1); ++i)
35592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			desc.DeviceName[i] = name[i];
35692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.AttachedToDesktop = TRUE;
35792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* TODO: should put an HMONITOR in desc.Monitor */
35892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
35992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		gamma = 0;
36092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		num_modes = 0;
36192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		modes = 0;
36292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(connector)
36392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
36492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			modes = parent->display->modeset->get_modes(parent->display, connector, (int*)&num_modes);
36592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(modes && num_modes)
36692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
36792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				dxgi_modes = new DXGI_MODE_DESC[num_modes];
36892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				for(unsigned i = 0; i < num_modes; ++i)
36992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				{
37092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].Width = modes[i]->width;
37192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].Height = modes[i]->height;
37292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].RefreshRate.Numerator = modes[i]->refresh_rate;
37392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].RefreshRate.Denominator = 1;
37492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
37592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
37692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				}
37792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
37892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else
37992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
38092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				if(modes)
38192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				{
38292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					free(modes);
38392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					modes = 0;
38492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				}
38592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				goto use_fake_mode;
38692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
38792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
38892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		else
38992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
39092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieriuse_fake_mode:
39192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes = new DXGI_MODE_DESC[1];
39292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].Width = 1920;
39392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].Height = 1200;
39492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].RefreshRate.Numerator = 60;
39592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].RefreshRate.Denominator = 1;
39692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
39792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
39892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
39992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
40092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
40192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	~GalliumDXGIOutput()
40292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
40392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		delete [] dxgi_modes;
40492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		free(modes);
40592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(gamma)
40692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			delete gamma;
40792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
40892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
40992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetDesc(
41092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__out  DXGI_OUTPUT_DESC *pDesc)
41192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
41292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*pDesc = desc;
41392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
41492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
41592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
41692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetDisplayModeList(
41792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		DXGI_FORMAT EnumFormat,
41892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		UINT Flags,
41992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__inout  UINT *pNumModes,
42092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__out_ecount_part_opt(*pNumModes,*pNumModes)  DXGI_MODE_DESC *pDesc)
42192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
42292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* TODO: should we return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE when we don't
42392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 * support modesetting instead of fake modes?
42492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 */
42592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe_format format = dxgi_to_pipe_format[EnumFormat];
42692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(parent->configs_by_pipe_format.count(format))
42792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
42892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!pDesc)
42992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
43092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				*pNumModes = num_modes;
43192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return S_OK;
43292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
43392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
43492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			unsigned copy_modes = std::min(num_modes, *pNumModes);
43592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			for(unsigned i = 0; i < copy_modes; ++i)
43692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
43792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				pDesc[i] = dxgi_modes[i];
43892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				pDesc[i].Format = EnumFormat;
43992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
44092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			*pNumModes = num_modes;
44192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
44292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(copy_modes < num_modes)
44392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return DXGI_ERROR_MORE_DATA;
44492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else
44592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return S_OK;
44692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
44792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		else
44892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
44992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			*pNumModes = 0;
45092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return S_OK;
45192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
45292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
45392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
45492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE FindClosestMatchingMode(
45592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__in  const DXGI_MODE_DESC *pModeToMatch,
45692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__out  DXGI_MODE_DESC *pClosestMatch,
45792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__in_opt  IUnknown *pConcernedDevice)
45892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
45992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* TODO: actually implement this */
46092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		DXGI_FORMAT dxgi_format = pModeToMatch->Format;
46192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		enum pipe_format format = dxgi_to_pipe_format[dxgi_format];
46292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		init_pipe_to_dxgi_format();
46392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!parent->configs_by_pipe_format.count(format))
46492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
46592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!pConcernedDevice)
46692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return E_FAIL;
46792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else
46892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
46992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				format = parent->configs[0]->color_format;
47092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				dxgi_format = pipe_to_dxgi_format[format];
47192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
47292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
47392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
47492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*pClosestMatch = dxgi_modes[0];
47592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pClosestMatch->Format = dxgi_format;
47692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
47792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
47892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
47992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE WaitForVBlank( void)
48092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
48192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
48292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
48392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
48492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE TakeOwnership(
48592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__in  IUnknown *pDevice,
48692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		BOOL Exclusive)
48792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
48892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
48992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
49092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
49192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual void STDMETHODCALLTYPE ReleaseOwnership( void)
49292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
49392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
49492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
49592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetGammaControlCapabilities(
49692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__out  DXGI_GAMMA_CONTROL_CAPABILITIES *pGammaCaps)
49792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
49892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(pGammaCaps, 0, sizeof(*pGammaCaps));
49992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
50092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
50192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
50292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE SetGammaControl(
50392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			__in  const DXGI_GAMMA_CONTROL *pArray)
50492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
50592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!gamma)
50692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			gamma = new DXGI_GAMMA_CONTROL;
50792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*gamma = *pArray;
50892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
50992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
51092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
51192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetGammaControl(
51292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			__out  DXGI_GAMMA_CONTROL *pArray)
51392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
51492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(gamma)
51592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			*pArray = *gamma;
51692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		else
51792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
51892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Scale.Red = 1;
51992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Scale.Green = 1;
52092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Scale.Blue = 1;
52192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Offset.Red = 0;
52292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Offset.Green = 0;
52392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Offset.Blue = 0;
52492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			for(unsigned i = 0; i <= 1024; ++i)
52592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				pArray->GammaCurve[i].Red = pArray->GammaCurve[i].Green = pArray->GammaCurve[i].Blue = (float)i / 1024.0;
52692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
52792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
52892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
52992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
53092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE SetDisplaySurface(
53192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__in  IDXGISurface *pScanoutSurface)
53292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
53392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return E_NOTIMPL;
53492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
53592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
53692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetDisplaySurfaceData(
53792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__in  IDXGISurface *pDestination)
53892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
53992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return E_NOTIMPL;
54092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
54192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
54292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(
54392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__out  DXGI_FRAME_STATISTICS *pStats)
54492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
54592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(pStats, 0, sizeof(*pStats));
54692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef _WIN32
54792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		QueryPerformanceCounter(&pStats->SyncQPCTime);
54892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
54992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return E_NOTIMPL;
55092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
55192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
55292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
55392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri/* Swap chain are rather complex, and Microsoft's documentation is rather
55492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * lacking. As far as I know, this is the most thorough publicly available
55592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * description of how swap chains work, based on multiple sources and
55692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * experimentation.
55792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
55892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * There are two modes (called "swap effects") that a swap chain can operate in:
55992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * discard and sequential.
56092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
56192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * In discard mode, things always look as if there is a single buffer, which
56292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * you can get with GetBuffers(0).
56392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * The 2D texture returned by GetBuffers(0) and can only be
56492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * used as a render target view and for resource copies, since no CPU access
56592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * flags are set and only the D3D11_BIND_RENDER_TARGET bind flag is set.
56692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * On Present, it is copied to the actual display
56792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * surface and the contents become undefined.
56892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * D3D may internally use multiple buffers, but you can't observe this, except
56992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * by looking at the buffer contents after Present (but those are undefined).
57092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * If it uses multiple buffers internally, then it will normally use BufferCount buffers
57192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * (this has latency implications).
57292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Discard mode seems to internally use a single buffer in windowed mode,
57392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * even if DWM is enabled, and BufferCount buffers in fullscreen mode.
57492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
57592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * In sequential mode, the runtime alllocates BufferCount buffers.
57692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * You can get each with GetBuffers(n).
57792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * GetBuffers(0) ALWAYS points to the backbuffer to be presented and has the
57892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * same usage constraints as the discard mode.
57992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * GetBuffer(n) with n > 0 points to resources that are identical to buffer 0, but
58092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * are classified as "read-only resources" (due to DXGI_USAGE_READ_ONLY),
58192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * meaning that you can't create render target views on them, or use them as
58292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * a CopyResource/CopySubresourceRegion  destination.
58392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * It appears the only valid operation is to use them as a source for CopyResource
58492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * and CopySubresourceRegion as well as just waiting for them to become
58592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * buffer 0 again.
58692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Buffer n - 1 is always displayed on screen.
58792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * When you call Present(), the contents of the buffers are rotated, so that buffer 0
58892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * goes to buffer n - 1, and is thus displayed, and buffer 1 goes to buffer 0, becomes
58992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * the accessible back buffer.
59092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * The resources themselves are NOT rotated, so that you can still render on the
59192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * same ID3D11Texture2D*, and views based on it, that you got before Present().
59292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
59392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Present seems to happen by either copying the relevant buffer into the window,
59492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * or alternatively making it the current one, either by programming the CRTC or
59592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * by sending the resource name to the DWM compositor.
59692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
59792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Hence, you can call GetBuffer(0) once and keep using the same ID3D11Texture2D*
59892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * and ID3D11RenderTargetView* (and other views if needed) you got from it.
59992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
60092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * If the window gets resized, DXGI will then "emulate" all successive presentations,
60192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * by using a stretched blit automatically.
60292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Thus, you should handle WM_SIZE and call ResizeBuffers to update the DXGI
60392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * swapchain buffers size to the new window size.
60492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Doing so requires you to release all GetBuffers() results and anything referencing
60592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * them, including views and Direct3D11 deferred context command lists (this is
60692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * documented).
60792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
60892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * How does Microsoft implement the rotation behavior?
60992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * It turns out that it does it by calling RotateResourceIdentitiesDXGI in the user-mode
61092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * DDI driver.
61192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * This will rotate the kernel buffer handle, or possibly rotate the GPU virtual memory
61292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * mappings.
61392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
61492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * The reason this is done by driver instead of by the runtime appears to be that
61592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * this is necessary to support driver-provided command list support, since otherwise
61692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * the command list would not always target the current backbuffer, since it would
61792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * be done at the driver level, while only the runtime knows about the rotation.
61892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
61992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * OK, so how do we implement this in Gallium?
62092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
62192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * There are three strategies:
62292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * 1. Use a single buffer, and always copy it to a window system provided buffer, or
62392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *    just give the buffer to the window system if it supports that
62492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * 2. Rotate the buffers in the D3D1x implementation, and recreate and rebind the views.
62592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *     Don't support driver-provided command lists
62692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * 3. Add this rotation functionality to the Gallium driver, with the idea that it would rotate
62792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *    remap GPU virtual memory, so that virtual address are unchanged, but the physical
62892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *    ones are rotated (so that pushbuffers remain valid).
62992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *    If the driver does not support this, either fall back to (1), or have a layer doing this,
63092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *    putting a deferred context layer over this intermediate layer.
63192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
63292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * (2) is not acceptable since it prevents an optimal implementation.
63392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *  (3) is the ideal solution, but it is complicated.
63492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
63592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Hence, we implement (1) for now, and will switch to (3) later.
63692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
63792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Note that (1) doesn't really work for DXGI_SWAP_EFFECT_SEQUENTIAL with more
63892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * than one buffer, so we just pretend we got asked for a single buffer in that case
63992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Fortunately, no one seems to rely on that, so we'll just not implement it at first, and
64092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * later perform the rotation with blits.
64192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Once we switch to (3), we'll just use real rotation to do it..
64292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
64392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * DXGI_SWAP_EFFECT_SEQUENTIAL with more than one buffer is of dubious use
64492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * anyway, since you can only render or write to buffer 0, and other buffers can apparently
64592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * be used only as sources for copies.
64692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * I was unable to find any code using it either in DirectX SDK examples, or on the web.
64792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
64892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * It seems the only reason you would use it is to not have to redraw from scratch, while
64992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * also possibly avoid a copy compared to BufferCount == 1, assuming that your
65092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * application is OK with having to redraw starting not from the last frame, but from
65192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * one/two/more frames behind it.
65292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
65392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * A better design would forbid the user specifying BufferCount explicitly, and
65492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * would instead let the application give an upper bound on how old the buffer can
65592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * become after presentation, with "infinite" being equivalent to discard.
65692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * The runtime would then tell the application with frame number the buffer switched to
65792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * after present.
65892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * In addition, in a better design, the application would be allowed to specify the
65992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * number of buffers available, having all them usable for rendering, so that things
66092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * like video players could efficiently decode frames in parallel.
66192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Present would in such a better design gain a way to specify the number of buffers
66292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * to present.
66392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
66492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Other miscellaneous info:
66592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * DXGI_PRESENT_DO_NOT_SEQUENCE causes DXGI to hold the frame for another
66692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * vblank interval without rotating the resource data.
66792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
66892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * References:
66992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * "DXGI Overview" in MSDN
67092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * IDXGISwapChain documentation on MSDN
67192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * "RotateResourceIdentitiesDXGI" on MSDN
67292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * http://forums.xna.com/forums/p/42362/266016.aspx
67392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri */
67492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
67592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic float quad_data[] = {
67692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	-1, -1, 0, 0,
67792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	-1, 1, 0, 1,
67892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	1, 1, 1, 1,
67992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	1, -1, 1, 0,
68092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
68192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
68292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct dxgi_blitter
68392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
68492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	pipe_context* pipe;
68592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool normalized;
68692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* fs;
68792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* vs;
68892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* sampler[2];
68992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* elements;
69092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* blend;
69192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* rasterizer;
69292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* zsa;
69392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_clip_state clip;
69492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_vertex_buffer vbuf;
69592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_draw_info draw;
69692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
69792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_blitter(pipe_context* pipe)
69892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	: pipe(pipe)
69992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
70092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		//normalized = !!pipe->screen->get_param(pipe, PIPE_CAP_NPOT_TEXTURES);
70192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// TODO: need to update buffer in unnormalized case
70292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		normalized = true;
70392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
70492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_rasterizer_state rs_state;
70592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&rs_state, 0, sizeof(rs_state));
70692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		rs_state.cull_face = PIPE_FACE_NONE;
70792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		rs_state.gl_rasterization_rules = 1;
70892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		rs_state.flatshade = 1;
70992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		rasterizer = pipe->create_rasterizer_state(pipe, &rs_state);
71092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
71192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_blend_state blendd;
712e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		memset(&blendd, 0, sizeof(blendd));
71392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		blendd.rt[0].colormask = PIPE_MASK_RGBA;
71492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		blend = pipe->create_blend_state(pipe, &blendd);
71592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
71692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_depth_stencil_alpha_state zsad;
71792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&zsad, 0, sizeof(zsad));
71892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		zsa = pipe->create_depth_stencil_alpha_state(pipe, &zsad);
71992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
72092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_vertex_element velem[2];
72192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&velem[0], 0, sizeof(velem[0]) * 2);
72292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		velem[0].src_offset = 0;
72392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		velem[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
72492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		velem[1].src_offset = 8;
72592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		velem[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
72692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		elements = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
72792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
72892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		for(unsigned stretch = 0; stretch < 2; ++stretch)
72992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
73092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			struct pipe_sampler_state sampler_state;
73192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			memset(&sampler_state, 0, sizeof(sampler_state));
73292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.min_img_filter = stretch ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
73392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.mag_img_filter = stretch ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
73492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
73592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
73692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
73792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.normalized_coords = normalized;
73892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
73992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler[stretch] = pipe->create_sampler_state(pipe, &sampler_state);
74092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
74192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
74292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		fs = util_make_fragment_tex_shader(pipe, normalized ? TGSI_TEXTURE_2D : TGSI_TEXTURE_RECT, TGSI_INTERPOLATE_LINEAR);
74392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
74492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		const unsigned semantic_names[] = { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC };
74592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		const unsigned semantic_indices[] = { 0, 0 };
74692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, semantic_indices);
74792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
74892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		vbuf.buffer = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER, sizeof(quad_data));
74992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		vbuf.buffer_offset = 0;
75092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		vbuf.max_index = ~0;
75192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		vbuf.stride = 4 * sizeof(float);
75292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe_buffer_write(pipe, vbuf.buffer, 0, sizeof(quad_data), quad_data);
75392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
75492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&clip, 0, sizeof(clip));
75592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
75692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&draw, 0, sizeof(draw));
75792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		draw.mode = PIPE_PRIM_QUADS;
75892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		draw.count = 4;
75992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		draw.instance_count = 1;
76092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		draw.max_index = ~0;
76192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
76292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
76392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void blit(struct pipe_surface* surf, struct pipe_sampler_view* view, unsigned x, unsigned y, unsigned w, unsigned h)
76492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
76592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_framebuffer_state fb;
76692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&fb, 0, sizeof(fb));
76792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		fb.nr_cbufs = 1;
76892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		fb.cbufs[0] = surf;
76992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		fb.width = surf->width;
77092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		fb.height = surf->height;
77192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
77292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_viewport_state viewport;
77392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		float half_width = w * 0.5f;
77492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		float half_height = h * 0.5f;
77592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.scale[0] = half_width;
77692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.scale[1] = half_height;
77792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.scale[2] = 1.0f;
77892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.scale[3] = 1.0f;
77992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.translate[0] = x + half_width;
78092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.translate[1] = y + half_height;
78192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.translate[2] = 0.0f;
78292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.translate[3] = 1.0f;
78392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
78492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		bool stretch = view->texture->width0 != w || view->texture->height0 != h;
78592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(pipe->render_condition)
78692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pipe->render_condition(pipe, 0, 0);
78792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->set_framebuffer_state(pipe, &fb);
78892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_fragment_sampler_states(pipe, 1, &sampler[stretch]);
78992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->set_viewport_state(pipe, &viewport);
79092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->set_clip_state(pipe, &clip);
79192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_rasterizer_state(pipe, rasterizer);
79292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_depth_stencil_alpha_state(pipe, zsa);
79392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_blend_state(pipe, blend);
79492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_vertex_elements_state(pipe, elements);
79592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->set_vertex_buffers(pipe, 1, &vbuf);
79692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_fs_state(pipe, fs);
79792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_vs_state(pipe, vs);
79892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(pipe->bind_gs_state)
79992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pipe->bind_gs_state(pipe, 0);
80092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(pipe->bind_stream_output_state)
80192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pipe->bind_stream_output_state(pipe, 0);
80292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->set_fragment_sampler_views(pipe, 1, &view);
80392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
80492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->draw_vbo(pipe, &draw);
80592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
80692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
80792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	~dxgi_blitter()
80892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
80992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_blend_state(pipe, blend);
81092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_rasterizer_state(pipe, rasterizer);
81192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_depth_stencil_alpha_state(pipe, zsa);
81292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_sampler_state(pipe, sampler[0]);
81392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_sampler_state(pipe, sampler[1]);
81492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_vertex_elements_state(pipe, elements);
81592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_vs_state(pipe, vs);
81692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_fs_state(pipe, fs);
81792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->screen->resource_destroy(pipe->screen, vbuf.buffer);
81892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
81992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
82092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
82192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDXGIFactory>
82292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
82392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IDXGIDevice>dxgi_device;
82492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IGalliumDevice>gallium_device;
82592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<GalliumDXGIAdapter> adapter;
82692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IDXGIOutput> target;
82792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
828e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	DXGI_SWAP_CHAIN_DESC desc;
829e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
83092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct native_surface* surface;
83192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_config* config;
83292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
833e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	void* window;
83492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_resource* resources[NUM_NATIVE_ATTACHMENTS];
83592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	int width;
83692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	int height;
83792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned seq_num;
83892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool ever_validated;
83992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool needs_validation;
84092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned present_count;
84192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
84292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IDXGISurface> buffer0;
84392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_resource* gallium_buffer0;
84492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_sampler_view* gallium_buffer0_view;
84592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
84692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_context* pipe;
84792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool owns_pipe;
84892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
84992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	BOOL fullscreen;
85092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
85192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	std::auto_ptr<dxgi_blitter> blitter;
85292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool formats_compatible;
85392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
85492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	GalliumDXGISwapChain(GalliumDXGIFactory* factory, IUnknown* p_device, const DXGI_SWAP_CHAIN_DESC& p_desc)
855e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	: GalliumDXGIObject<IDXGISwapChain, GalliumDXGIFactory>(factory), desc(p_desc), surface(0)
85692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
85792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		HRESULT hr;
85892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
85992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = p_device->QueryInterface(IID_IGalliumDevice, (void**)&gallium_device);
86092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
86192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			throw hr;
86292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
86392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = p_device->QueryInterface(IID_IDXGIDevice, (void**)&dxgi_device);
86492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
86592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			throw hr;
86692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
86792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = dxgi_device->GetAdapter((IDXGIAdapter**)&adapter);
86892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
86992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			throw hr;
87092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
871e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		memset(resources, 0, sizeof(resources));
872e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
873e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(desc.SwapEffect == DXGI_SWAP_EFFECT_SEQUENTIAL && desc.BufferCount != 1)
874e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		{
875e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			std::cerr << "Gallium DXGI: if DXGI_SWAP_EFFECT_SEQUENTIAL is specified, only BufferCount == 1 is implemented, but " << desc.BufferCount  << " was specified: ignoring this" << std::endl;
876e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			// change the returned desc, so that the application might perhaps notice what we did and react well
877e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			desc.BufferCount = 1;
878e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		}
879e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
880e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		pipe = gallium_device->GetGalliumContext();
881e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		owns_pipe = false;
882e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(!pipe)
883e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		{
884e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			pipe = adapter->display->screen->context_create(adapter->display->screen, 0);
885e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			owns_pipe = true;
886e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		}
887e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
888e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		blitter.reset(new dxgi_blitter(pipe));
889e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		window = 0;
890e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	}
891e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
892e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	void init_for_window()
893e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	{
894e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(surface)
895e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		{
896e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			surface->destroy(surface);
897e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			surface = 0;
898e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		}
89992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
90092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		unsigned config_num;
901e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(!strcmp(parent->platform->name, "X11"))
90292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
90392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			XWindowAttributes xwa;
904e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			XGetWindowAttributes((Display*)parent->display, (Window)window, &xwa);
90592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			config_num = adapter->configs_by_native_visual_id[xwa.visual->visualid];
90692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
90792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		else
90892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
90992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			enum pipe_format format = dxgi_to_pipe_format[desc.BufferDesc.Format];
91092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!adapter->configs_by_pipe_format.count(format))
91192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
91292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				if(adapter->configs_by_pipe_format.empty())
91392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					throw E_FAIL;
91492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				// TODO: choose the best match
91592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				format = (pipe_format)adapter->configs_by_pipe_format.begin()->first;
91692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
91792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			// TODO: choose the best config
91892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			config_num = adapter->configs_by_pipe_format.find(format)->second;
91992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
92092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
92192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		config = adapter->configs[config_num];
922e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		surface = adapter->display->create_window_surface(adapter->display, (EGLNativeWindowType)window, config);
92392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		surface->user_data = this;
92492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
92592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		width = 0;
92692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		height = 0;
92792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		seq_num = 0;
92892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		present_count = 0;
92992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		needs_validation = true;
93092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		ever_validated = false;
93192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
93292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		formats_compatible = util_is_format_compatible(
93392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				util_format_description(dxgi_to_pipe_format[desc.BufferDesc.Format]),
93492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				util_format_description(config->color_format));
93592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
93692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
93792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	~GalliumDXGISwapChain()
93892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
93992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(owns_pipe)
94092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pipe->destroy(pipe);
94192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
94292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
94392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        virtual HRESULT STDMETHODCALLTYPE GetDevice(
94492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri            __in  REFIID riid,
94592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri            __out  void **ppDevice)
94692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
94792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	return dxgi_device->QueryInterface(riid, ppDevice);
94892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
94992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
95092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        HRESULT create_buffer0()
95192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        {
95292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        	HRESULT hr;
95392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		ComPtr<IDXGISurface> new_buffer0;
95492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		DXGI_USAGE usage = DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT;
95592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD)
95692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			usage |= DXGI_USAGE_DISCARD_ON_PRESENT;
95792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// for our blitter
95892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		usage |= DXGI_USAGE_SHADER_INPUT;
95992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
96092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		DXGI_SURFACE_DESC surface_desc;
96192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		surface_desc.Format = desc.BufferDesc.Format;
96292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		surface_desc.Width = desc.BufferDesc.Width;
96392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		surface_desc.Height = desc.BufferDesc.Height;
96492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		surface_desc.SampleDesc = desc.SampleDesc;
96592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = dxgi_device->CreateSurface(&surface_desc, 1, usage, 0, &new_buffer0);
96692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
96792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return hr;
96892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
96992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		ComPtr<IGalliumResource> gallium_resource;
97092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = new_buffer0->QueryInterface(IID_IGalliumResource, (void**)&gallium_resource);
97192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
97292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return hr;
97392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
97492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_resource* new_gallium_buffer0 = gallium_resource->GetGalliumResource();
97592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!new_gallium_buffer0)
97692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return E_FAIL;
97792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
97892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		buffer0.reset(new_buffer0.steal());
97992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		gallium_buffer0 = new_gallium_buffer0;
98092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_sampler_view templat;
98192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&templat, 0, sizeof(templat));
98292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.texture = gallium_buffer0;
98392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.swizzle_r = 0;
98492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.swizzle_g = 1;
98592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.swizzle_b = 2;
98692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.swizzle_a = 3;
98792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.format = gallium_buffer0->format;
98892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		gallium_buffer0_view = pipe->create_sampler_view(pipe, gallium_buffer0, &templat);
98992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
99092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri        }
99192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
99292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool validate()
99392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
99492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		unsigned new_seq_num;
99592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		needs_validation = false;
99692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
997e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(!surface->validate(surface, (1 << NATIVE_ATTACHMENT_BACK_LEFT) | (1 << NATIVE_ATTACHMENT_FRONT_LEFT), &new_seq_num, resources, &width, &height))
99892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return false;
99992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
100092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!ever_validated || seq_num != new_seq_num)
100192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
100292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			seq_num = new_seq_num;
100392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			ever_validated = true;
100492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
100592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return true;
100692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
100792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
100892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE Present(
100992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		UINT SyncInterval,
101092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		UINT Flags)
101192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
101292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(Flags & DXGI_PRESENT_TEST)
101392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return S_OK;
101492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
101592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!buffer0)
101692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
101792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			HRESULT hr = create_buffer0();
101892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!SUCCEEDED(hr))
101992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return hr;
102092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
102192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1022e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		void* cur_window = 0;
1023e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		RECT rect;
1024e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		RGNDATA* rgndata;
1025e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		BOOL preserve_aspect_ratio;
1026e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		unsigned dst_w, dst_h;
1027e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		bool db;
1028e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		struct pipe_resource* dst;
1029e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		struct pipe_resource* src;
1030e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		struct pipe_surface* dst_surface;
1031e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
1032e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		void* present_cookie = parent->backend->BeginPresent(desc.OutputWindow, &cur_window, &rect, &rgndata, &preserve_aspect_ratio);
1033e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(!cur_window || rect.left >= rect.right || rect.top >= rect.bottom)
1034e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			goto end_present;
1035e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
1036e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(cur_window != window)
1037e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		{
1038e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			window = cur_window;
1039e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			init_for_window();
1040e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		}
1041e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
104292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(needs_validation)
104392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
104492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!validate())
104592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return DXGI_ERROR_DEVICE_REMOVED;
104692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
104792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1048e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		db = !!(config->buffer_mask & NATIVE_ATTACHMENT_BACK_LEFT);
1049e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dst = resources[db ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT];
1050e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		src = gallium_buffer0;
1051e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dst_surface = 0;
105292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
105392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* TODO: sharing the context for blitting won't work correctly if queries are active
105492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 * Hopefully no one is crazy enough to keep queries active while presenting, expecting
105592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 * sensible results.
105692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 * We could alternatively force using another context, but that might cause inefficiency issues
105792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 */
105892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1059e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if((unsigned)rect.right > dst->width0)
1060e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			rect.right = dst->width0;
1061e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if((unsigned)rect.bottom > dst->height0)
1062e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			rect.bottom = dst->height0;
1063e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(rect.left > rect.right)
1064e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			rect.left = rect.right;
1065e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(rect.top > rect.bottom)
1066e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			rect.top = rect.bottom;
106792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1068e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(rect.left >= rect.right && rect.top >= rect.bottom)
1069e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			goto end_present;
107092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1071e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dst_w = rect.right - rect.left;
1072e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dst_h = rect.bottom - rect.top;
1073e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
1074e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		// TODO: add support for rgndata
1075e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri//		if(preserve_aspect_ratio || !rgndata)
1076e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(1)
107792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
1078e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			unsigned blit_x, blit_y, blit_w, blit_h;
1079e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			float black[4] = {0, 0, 0, 0};
1080e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
1081e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(!formats_compatible || src->width0 != dst_w || src->height0 != dst_h)
1082e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				dst_surface = pipe->screen->get_tex_surface(pipe->screen, dst, 0, 0, 0, PIPE_BIND_RENDER_TARGET);
1083e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
1084e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(preserve_aspect_ratio)
1085e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			{
1086e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				int delta = src->width0 * dst_h - dst_w * src->height0;
1087e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				if(delta > 0)
1088e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				{
1089e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_w = dst_w;
1090e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_h = dst_w * src->height0 / src->width0;
1091e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				}
1092e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				else if(delta < 0)
1093e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				{
1094e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_w = dst_h * src->width0 / src->height0;
1095e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_h = dst_h;
1096e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				}
1097e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				else
1098e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				{
1099e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_w = dst_w;
1100e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_h = dst_h;
1101e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				}
110292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1103e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_x = (dst_w - blit_w) >> 1;
1104e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_y = (dst_h - blit_h) >> 1;
1105e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			}
1106e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			else
1107e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			{
1108e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_x = 0;
1109e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_y = 0;
1110e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_w = dst_w;
1111e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_h = dst_h;
1112e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			}
111392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1114e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(blit_x)
1115e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				pipe->clear_render_target(pipe, dst_surface, black, rect.left, rect.top, blit_x, dst_h);
1116e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(blit_y)
1117e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				pipe->clear_render_target(pipe, dst_surface, black, rect.left, rect.top, dst_w, blit_y);
111892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1119e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(formats_compatible && blit_w == src->width0 && blit_h == src->height0)
1120e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			{
1121e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				pipe_subresource sr;
1122e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				sr.face = 0;
1123e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				sr.level = 0;
1124e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				pipe->resource_copy_region(pipe, dst, sr, rect.left, rect.top, 0, src, sr, 0, 0, 0, blit_w, blit_h);
1125e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			}
1126e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			else
1127e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			{
1128e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blitter->blit(dst_surface, gallium_buffer0_view, rect.left + blit_x, rect.top + blit_y, blit_w, blit_h);
1129e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				if(!owns_pipe)
1130e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					gallium_device->RestoreGalliumState();
1131e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			}
113292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1133e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(blit_w != dst_w)
1134e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				pipe->clear_render_target(pipe, dst_surface, black, rect.left + blit_x + blit_w, rect.top, dst_w - blit_x - blit_w, dst_h);
1135e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(blit_h != dst_h)
1136e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				pipe->clear_render_target(pipe, dst_surface, black, rect.left, rect.top + blit_y + blit_h, dst_w, dst_h - blit_y - blit_h);
1137e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		}
113892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
113992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(dst_surface)
114092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pipe->screen->tex_surface_destroy(dst_surface);
114192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
114292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(db)
114392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
114492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!surface->swap_buffers(surface))
114592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return DXGI_ERROR_DEVICE_REMOVED;
114692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
114792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		else
114892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
114992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!surface->flush_frontbuffer(surface))
115092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return DXGI_ERROR_DEVICE_REMOVED;
115192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
115292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1153e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieriend_present:
1154e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		parent->backend->EndPresent(desc.OutputWindow, present_cookie);
1155e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
115692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		++present_count;
115792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
115892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
115992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
116092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetBuffer(
116192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		    UINT Buffer,
116292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		    __in  REFIID riid,
116392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		    __out  void **ppSurface)
116492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
116592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(Buffer > 0)
116692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
116792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(desc.SwapEffect == DXGI_SWAP_EFFECT_SEQUENTIAL)
116892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				std::cerr << "DXGI unimplemented: GetBuffer(n) with n > 0 not supported, returning buffer 0 instead!" << std::endl;
116992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else
117092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				std::cerr << "DXGI error: in GetBuffer(n), n must be 0 for DXGI_SWAP_EFFECT_DISCARD\n" << std::endl;
117192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
117292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
117392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!buffer0)
117492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
117592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			HRESULT hr = create_buffer0();
117692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!SUCCEEDED(hr))
117792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return hr;
117892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
117992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return buffer0->QueryInterface(riid, ppSurface);
118092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
118192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
118292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	/* TODO: implement somehow */
118392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE SetFullscreenState(
118492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		BOOL Fullscreen,
118592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__in_opt  IDXGIOutput *pTarget)
118692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
118792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		fullscreen = Fullscreen;
118892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		target = pTarget;
118992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
119092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
119192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
119292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetFullscreenState(
119392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__out  BOOL *pFullscreen,
119492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__out  IDXGIOutput **ppTarget)
119592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
119692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(pFullscreen)
119792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			*pFullscreen = fullscreen;
119892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(ppTarget)
119992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			*ppTarget = target.ref();
120092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
120192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
120292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
120392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetDesc(
120492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__out  DXGI_SWAP_CHAIN_DESC *pDesc)
120592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
120692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*pDesc = desc;
120792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
120892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
120992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
121092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE ResizeBuffers(
121192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		UINT BufferCount,
121292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		UINT Width,
121392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		UINT Height,
121492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		DXGI_FORMAT NewFormat,
121592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		UINT SwapChainFlags)
121692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
121792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(buffer0)
121892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
121992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			buffer0.p->AddRef();
122092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			ULONG v = buffer0.p->Release();
122192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			// we must fail if there are any references to buffer0 other than ours
122292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(v > 1)
122392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return E_FAIL;
122492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pipe_sampler_view_reference(&gallium_buffer0_view, 0);
122592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			buffer0 = (IUnknown*)NULL;
122692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			gallium_buffer0 = 0;
122792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
122892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
122992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(desc.SwapEffect != DXGI_SWAP_EFFECT_SEQUENTIAL)
123092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			desc.BufferCount = BufferCount;
123192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.BufferDesc.Format = NewFormat;
123292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.BufferDesc.Width = Width;
123392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.BufferDesc.Height = Height;
123492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.Flags = SwapChainFlags;
123592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
123692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
123792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
123892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE ResizeTarget(
123992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		const DXGI_MODE_DESC *pNewTargetParameters)
124092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
124192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* TODO: implement */
124292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
124392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
124492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
124592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetContainingOutput(
124692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			__out  IDXGIOutput **ppOutput)
124792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
124892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*ppOutput = adapter->outputs[0].ref();
124992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
125092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
125192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
125292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(
125392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			__out  DXGI_FRAME_STATISTICS *pStats)
125492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
125592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(pStats, 0, sizeof(*pStats));
125692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef _WIN32
125792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		QueryPerformanceCounter(&pStats->SyncQPCTime);
125892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
125992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pStats->PresentCount = present_count;
126092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pStats->PresentRefreshCount = present_count;
126192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pStats->SyncRefreshCount = present_count;
126292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
126392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
126492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
126592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount(
126692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__out  UINT *pLastPresentCount)
126792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
126892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*pLastPresentCount = present_count;
126992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
127092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
127192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
127292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
127392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic void GalliumDXGISwapChainRevalidate(IDXGISwapChain* swap_chain)
127492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
127592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	((GalliumDXGISwapChain*)swap_chain)->needs_validation = true;
127692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
127792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
127892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy, IDXGIAdapter1** pAdapter)
127992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
128092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	try
128192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
128292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*pAdapter = new GalliumDXGIAdapter(factory, platform, dpy);
128392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
128492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
128592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	catch(HRESULT hr)
128692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
128792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return hr;
128892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
128992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
129092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
129192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** pOutput)
129292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
129392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	try
129492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
129592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*pOutput = new GalliumDXGIOutput(adapter, name, connector);
129692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
129792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
129892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	catch(HRESULT hr)
129992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
130092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return hr;
130192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
130292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
130392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
130492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** pSwapChain)
130592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
130692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	try
130792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
130892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*pSwapChain = new GalliumDXGISwapChain(factory, device, desc);
130992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
131092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
131192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	catch(HRESULT hr)
131292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
131392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return hr;
131492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
131592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
131692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
131792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct dxgi_binding
131892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
131992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_platform* platform;
132092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* display;
1321e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	IGalliumDXGIBackend* backend;
132292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
132392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
132492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic dxgi_binding dxgi_default_binding;
132592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic __thread dxgi_binding dxgi_thread_binding;
132692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
132792617aeac109481258f0c3863d09c1b8903d438bLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIUseNothing()
132892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
132992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.platform = 0;
133092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.display = 0;
1331e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	if(dxgi_thread_binding.backend)
1332e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dxgi_thread_binding.backend->Release();
1333e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	dxgi_thread_binding.backend = 0;
133492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
133592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
133692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef GALLIUM_DXGI_USE_X11
1337e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIUseX11Display(Display* dpy, IGalliumDXGIBackend* backend)
133892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
1339e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	GalliumDXGIUseNothing();
134092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.platform = native_get_x11_platform();
134192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.display = dpy;
1342e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
1343e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	if(backend)
1344e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	{
1345e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dxgi_thread_binding.backend = backend;
1346e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		backend->AddRef();
1347e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	}
134892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
134992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
135092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1351e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri/*
135292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef GALLIUM_DXGI_USE_DRM
135392617aeac109481258f0c3863d09c1b8903d438bLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIUseDRMCard(int fd)
135492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
1355e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	GalliumDXGIUseNothing();
135692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.platform = native_get_drm_platform();
135792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.display = (void*)fd;
1358e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	dxgi_thread_binding.backend = 0;
135992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
136092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
136192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
136292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef GALLIUM_DXGI_USE_FBDEV
136392617aeac109481258f0c3863d09c1b8903d438bLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIUseFBDev(int fd)
136492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
1365e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	GalliumDXGIUseNothing();
136692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.platform = native_get_fbdev_platform();
136792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.display = (void*)fd;
1368e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	dxgi_thread_binding.backend = 0;
136992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
137092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
137192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
137292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef GALLIUM_DXGI_USE_GDI
137392617aeac109481258f0c3863d09c1b8903d438bLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIUseHDC(HDC hdc, PFNHWNDRESOLVER resolver, void* resolver_cookie)
137492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
1375e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	GalliumDXGIUseNothing();
137692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.platform = native_get_gdi_platform();
137792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.display = (void*)hdc;
1378e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	dxgi_thread_binding.backend = 0;
137992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
138092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
1381e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri*/
138292617aeac109481258f0c3863d09c1b8903d438bLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIMakeDefault()
138392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
1384881c05aa1ec22bb229a0bceae372d68f9fc91431Luca Barbieri	if(dxgi_default_binding.backend)
1385881c05aa1ec22bb229a0bceae372d68f9fc91431Luca Barbieri		dxgi_default_binding.backend->Release();
138692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_default_binding = dxgi_thread_binding;
1387881c05aa1ec22bb229a0bceae372d68f9fc91431Luca Barbieri	if(dxgi_default_binding.backend)
1388881c05aa1ec22bb229a0bceae372d68f9fc91431Luca Barbieri		dxgi_default_binding.backend->AddRef();
138992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
139092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
139192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri /* TODO: why did Microsoft add this? should we do something different for DXGI 1.0 and 1.1?
139292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri  * Or perhaps what they actually mean is "only create a single factory in your application"?
139392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri  * TODO: should we use a singleton here, so we never have multiple DXGI objects for the same thing? */
139492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri HRESULT STDMETHODCALLTYPE  CreateDXGIFactory1(
139592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__in   REFIID riid,
139692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		__out  void **ppFactory
139792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri)
139892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri {
139992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 GalliumDXGIFactory* factory;
140092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 *ppFactory = 0;
140192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 if(dxgi_thread_binding.platform)
1402e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		 factory = new GalliumDXGIFactory(dxgi_thread_binding.platform, dxgi_thread_binding.display, dxgi_thread_binding.backend);
140392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 else if(dxgi_default_binding.platform)
1404e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		 factory = new GalliumDXGIFactory(dxgi_default_binding.platform, dxgi_default_binding.display, dxgi_default_binding.backend);
140592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 else
1406e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		 factory = new GalliumDXGIFactory(native_get_x11_platform(), NULL, NULL);
140792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 HRESULT hres = factory->QueryInterface(riid, ppFactory);
140892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 factory->Release();
140992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 return hres;
141092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri }
141192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
141292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri HRESULT STDMETHODCALLTYPE  CreateDXGIFactory(
141392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 __in   REFIID riid,
141492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 __out  void **ppFactory
141592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri)
141692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri {
141792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 return CreateDXGIFactory1(riid, ppFactory);
141892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri }
1419