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"
3092bc1111f3c5dd3616bd591129aebd3f4307e5b4Kai Wasserbäch#include "util/u_format.h"
3192bc1111f3c5dd3616bd591129aebd3f4307e5b4Kai Wasserbäch#include "util/u_inlines.h"
3292bc1111f3c5dd3616bd591129aebd3f4307e5b4Kai Wasserbäch#include "util/u_simple_shaders.h"
3392bc1111f3c5dd3616bd591129aebd3f4307e5b4Kai Wasserbäch#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
430525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieristatic HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** out_swap_chain);
440525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieristatic HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* adapter, const struct native_platform* platform, void* dpy, IDXGIAdapter1** out_adapter);
450525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieristatic HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** out_output);
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
586c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetParent(
598224256946619fb25278718bbf4703e3b9d60c93Luca Barbieri		REFIID riid,
600525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		void **out_parent)
616c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
620525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		return parent->QueryInterface(riid, out_parent);
636c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
6492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
6592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
66e7624e23a3a374896863f54fe30dafd0bff8a91aLuca BarbieriCOM_INTERFACE(IGalliumDXGIBackend, IUnknown)
67e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
68f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri// TODO: somehow check whether the window is fully obscured or not
69e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieristruct GalliumDXGIIdentityBackend : public GalliumComObject<IGalliumDXGIBackend>
7092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
71f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	virtual HRESULT STDMETHODCALLTYPE BeginPresent(
72e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		HWND hwnd,
73f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		void** present_cookie,
74e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		void** window,
75e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		RECT *rect,
76e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		RGNDATA **rgndata,
77e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		BOOL* preserve_aspect_ratio
78e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	)
79e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	{
80e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		*window = (void*)hwnd;
81e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		rect->left = 0;
82e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		rect->top = 0;
83e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		rect->right = INT_MAX;
84e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		rect->bottom = INT_MAX;
85e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		*rgndata = 0;
86e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
87e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		// yes, because we like things looking good
88e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		*preserve_aspect_ratio = TRUE;
89f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		*present_cookie = 0;
90f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		return S_OK;
91e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	}
92e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
93e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	virtual void STDMETHODCALLTYPE EndPresent(
94e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		HWND hwnd,
95e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		void* present_cookie
96e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	)
97e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	{}
98f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
99f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	virtual HRESULT STDMETHODCALLTYPE TestPresent(HWND hwnd)
100f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	{
101f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		return S_OK;
102f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	}
103f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
104f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri        virtual HRESULT STDMETHODCALLTYPE GetPresentSize(
105f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri                HWND hwnd,
106f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri                unsigned* width,
107f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri                unsigned* height
108f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri        )
109f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri        {
110f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri                *width = 0;
111f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri                *height = 0;
112f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri                return S_OK;
113f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri        }
114f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri};
115f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
116f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri// TODO: maybe install an X11 error hook, so we can return errors properly
117f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieristruct GalliumDXGIX11IdentityBackend : public GalliumDXGIIdentityBackend
118f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri{
119f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	Display* dpy;
120f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
121f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	GalliumDXGIX11IdentityBackend(Display* dpy)
122f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	: dpy(dpy)
123f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	{}
124f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
125f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetPresentSize(
126f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		HWND hwnd,
127f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		unsigned* width,
128f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		unsigned* height
129f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	)
130f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri        {
131f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		XWindowAttributes xwa;
132f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		XGetWindowAttributes(dpy, (Window)hwnd, &xwa);
133f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		*width = xwa.width;
134f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		*height = xwa.height;
135f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		return S_OK;
136f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri        }
137e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri};
13892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
13992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGIFactory : public GalliumDXGIObject<IDXGIFactory1, IUnknown>
14092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
1416c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	HWND associated_window;
14292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_platform* platform;
14392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* display;
144e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	ComPtr<IGalliumDXGIBackend> backend;
14592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* resolver_cookie;
14692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
147e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	GalliumDXGIFactory(const struct native_platform* platform, void* display, IGalliumDXGIBackend* p_backend)
148e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	: GalliumDXGIObject<IDXGIFactory1, IUnknown>((IUnknown*)NULL), platform(platform), display(display)
1496c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	 {
150e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(p_backend)
151e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			backend = p_backend;
152f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		else if(!strcmp(platform->name, "X11"))
153f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri			backend.reset(new GalliumDXGIX11IdentityBackend((Display*)display));
154e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		else
155e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			backend.reset(new GalliumDXGIIdentityBackend());
156e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	}
15792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1586c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE EnumAdapters(
1590525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT adapter,
1600525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IDXGIAdapter **out_adapter)
16192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
1620525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		return EnumAdapters1(adapter, (IDXGIAdapter1**)out_adapter);
16392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
16492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1656c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE EnumAdapters1(
1660525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT adapter,
1670525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IDXGIAdapter1 **out_adapter)
1686c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
1690525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*out_adapter = 0;
1700525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		if(adapter == 0)
17192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
1720525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			return GalliumDXGIAdapterCreate(this, platform, display, out_adapter);
17392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
17492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#if 0
17592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// TODO: enable this
1766c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		if(platform == native_get_x11_platform())
1776c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		{
1786c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri			unsigned nscreens = ScreenCount((Display*)display);
1790525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			if(adapter < nscreens)
1806c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri			{
1816c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri				unsigned def_screen = DefaultScreen(display);
1820525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri				if(adapter <= def_screen)
1830525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri					--adapter;
1840525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri				*out_adapter = GalliumDXGIAdapterCreate(this, platform, display, adapter);
1856c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri				return S_OK;
1866c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri			}
1876c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		}
18892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
18992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return DXGI_ERROR_NOT_FOUND;
1906c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
1916c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri
1926c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	/* TODO: this is a mysterious underdocumented magic API
1936c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	 * Can we have multiple windows associated?
1946c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	 * Can we have multiple windows associated if we use multiple factories?
1956c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	 * If so, what should GetWindowAssociation return?
1966c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	 * If not, does a new swapchain steal the association?
1976c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	 * Does this act for existing swapchains? For new swapchains?
1986c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	 */
1996c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(
2000525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		HWND window_handle,
2010525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT flags)
2026c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
2036c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		/* TODO: actually implement, for Wine, X11 and KMS*/
2040525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		associated_window = window_handle;
2056c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		return S_OK;
2066c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
2076c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri
2086c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation(
2090525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		HWND *pwindow_handle)
2106c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
2110525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*pwindow_handle = associated_window;
2126c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		return S_OK;
2136c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
2146c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri
2156c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE CreateSwapChain(
2160525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IUnknown *device,
2170525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_SWAP_CHAIN_DESC *desc,
2180525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IDXGISwapChain **out_swap_chain)
2196c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
2200525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		return GalliumDXGISwapChainCreate(this, device, *desc, out_swap_chain);
2216c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
2226c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri
2236c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter(
2240525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		HMODULE module,
2250525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IDXGIAdapter **out_adapter)
2266c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
2276c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		/* TODO: ignore the module, and just create a Gallium software screen */
2280525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*out_adapter = 0;
2296c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		return E_NOTIMPL;
2306c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
2316c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri
2326c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	/* TODO: support hotplug */
2336c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual BOOL STDMETHODCALLTYPE IsCurrent( void)
2346c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
2356c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		return TRUE;
2366c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
23792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
23892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
23992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGIAdapter
24092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	: public GalliumMultiComObject<
2416c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		 GalliumDXGIObject<IDXGIAdapter1, GalliumDXGIFactory>,
2426c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		 IGalliumAdapter>
24392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
24492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct native_display* display;
24592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_config** configs;
24692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	std::unordered_multimap<unsigned, unsigned> configs_by_pipe_format;
24792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	std::unordered_map<unsigned, unsigned> configs_by_native_visual_id;
24892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_connector** connectors;
24992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned num_configs;
25092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	DXGI_ADAPTER_DESC1 desc;
25192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	std::vector<ComPtr<IDXGIOutput> > outputs;
25292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	int num_outputs;
25392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
25492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	GalliumDXGIAdapter(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy)
25592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
25692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		this->parent = factory;
25792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
2583a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu		display = platform->create_display(dpy, FALSE);
25992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!display)
2603a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu                   display = platform->create_display(dpy, TRUE);
2613a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu                if (display) {
2623a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu                   display->user_data = this;
2633a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu                   if (!display->init_screen(display)) {
2643a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu                      display->destroy(display);
2653a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu                      display = NULL;
2663a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu                   }
2673a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu                }
268326332a130baa732805489565ed806ce344cc1f6Chia-I Wu                if(!display)
26992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			throw E_FAIL;
27092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&desc, 0, sizeof(desc));
27192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		std::string s = std::string("GalliumD3D on ") + display->screen->get_name(display->screen) + " by " + display->screen->get_vendor(display->screen);
27292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
27392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* hopefully no one will decide to use UTF-8 in Gallium name/vendor strings */
27492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		for(int i = 0; i < std::min((int)s.size(), 127); ++i)
27592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			desc.Description[i] = (WCHAR)s[i];
27692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
27792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// TODO: add an interface to get these; for now, return mid/low values
27892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.DedicatedVideoMemory = 256 << 20;
27992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.DedicatedSystemMemory = 256 << 20;
28092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.SharedSystemMemory = 1024 << 20;
28192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
28292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// TODO: we should actually use an unique ID instead
28392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*(void**)&desc.AdapterLuid = dpy;
28492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
28592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		configs = display->get_configs(display, (int*)&num_configs);
28692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		for(unsigned i = 0; i < num_configs; ++i)
28792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
28892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(configs[i]->window_bit)
28992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
29092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				configs_by_pipe_format.insert(std::make_pair(configs[i]->color_format, i));
29192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				configs_by_native_visual_id[configs[i]->native_visual_id] = i;
29292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
29392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
29492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
29592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		connectors = 0;
29692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		num_outputs = 0;
29792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
29892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(display->modeset)
29992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
30092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			int num_crtcs;
30192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
30292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			connectors = display->modeset->get_connectors(display, &num_outputs, &num_crtcs);
30392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!connectors)
30492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				num_outputs = 0;
30592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else if(!num_outputs)
30692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
30792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				free(connectors);
30892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				connectors = 0;
30992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
31092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
31192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!num_outputs)
31292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			num_outputs = 1;
31392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
31492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
31592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	static void handle_invalid_surface(struct native_display *ndpy, struct native_surface *nsurf, unsigned int seq_num)
31692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
31792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		GalliumDXGISwapChainRevalidate((IDXGISwapChain*)nsurf->user_data);
31892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
31992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
32092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	~GalliumDXGIAdapter()
32192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
3226ce098631abf465e89b12d10c4e6713b9c843422Luca Barbieri		display->destroy(display);
32392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		free(configs);
32492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		free(connectors);
32592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
32692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
3276c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE EnumOutputs(
3280525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT output,
3290525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IDXGIOutput **out_output)
33092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
3310525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		if(output >= (unsigned)num_outputs)
3326c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri			return DXGI_ERROR_NOT_FOUND;
33392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
3346c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		if(connectors)
3356c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		{
3366c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri			std::ostringstream ss;
3370525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			ss << "output #" << output;
3380525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			return GalliumDXGIOutputCreate(this, ss.str(), connectors[output], out_output);
3396c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		}
3406c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		else
3410525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			return GalliumDXGIOutputCreate(this, "Unique output", NULL, out_output);
3426c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
3436c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri
3446c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetDesc(
3450525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_ADAPTER_DESC *desc)
3466c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
3470525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		memcpy(desc, &desc, sizeof(*desc));
3486c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		return S_OK;
34992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
35092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
3516c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetDesc1(
3520525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_ADAPTER_DESC1 *desc)
3536c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
3540525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		memcpy(desc, &desc, sizeof(*desc));
3556c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		return S_OK;
3566c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
3576c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri
3586c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport(
3590525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		REFGUID interface_name,
3600525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		LARGE_INTEGER *u_m_d_version)
3616c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
3626c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		// these number was taken from Windows 7 with Catalyst 10.8: its meaning is unclear
3630525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		if(interface_name == IID_ID3D11Device || interface_name == IID_ID3D10Device1 || interface_name == IID_ID3D10Device)
3646c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		{
3650525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			u_m_d_version->QuadPart = 0x00080011000a0411ULL;
3666c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri			return S_OK;
3676c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		}
3686c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		return DXGI_ERROR_UNSUPPORTED;
3696c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
3706c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri
3716c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	pipe_screen* STDMETHODCALLTYPE GetGalliumScreen()
3726c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
3736c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		return display->screen;
3746c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
3756c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri
3766c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	pipe_screen* STDMETHODCALLTYPE GetGalliumReferenceSoftwareScreen()
3776c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
3786c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		// TODO: give a softpipe screen
3796c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		return display->screen;
3806c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
3816c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri
3826c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	pipe_screen* STDMETHODCALLTYPE GetGalliumFastSoftwareScreen()
38392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
38492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// TODO: give an llvmpipe screen
38592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return display->screen;
38692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
38792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
38892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
38992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
39092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGIOutput : public GalliumDXGIObject<IDXGIOutput, GalliumDXGIAdapter>
39192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
39292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	DXGI_OUTPUT_DESC desc;
39392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_mode** modes;
39492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	DXGI_MODE_DESC* dxgi_modes;
39592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned num_modes;
39692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_connector* connector;
39792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	DXGI_GAMMA_CONTROL* gamma;
39892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
39992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	GalliumDXGIOutput(GalliumDXGIAdapter* adapter, std::string name, const struct native_connector* connector = 0)
400b4b2091655676ec3b898d3ae7298192aa7f9147fLuca Barbieri	: GalliumDXGIObject<IDXGIOutput, GalliumDXGIAdapter>(adapter), connector(connector)
40192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
40292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&desc, 0, sizeof(desc));
40392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		for(unsigned i = 0; i < std::min(name.size(), sizeof(desc.DeviceName) - 1); ++i)
40492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			desc.DeviceName[i] = name[i];
40592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		desc.AttachedToDesktop = TRUE;
40692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* TODO: should put an HMONITOR in desc.Monitor */
40792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
40892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		gamma = 0;
40992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		num_modes = 0;
41092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		modes = 0;
41192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(connector)
41292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
41392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			modes = parent->display->modeset->get_modes(parent->display, connector, (int*)&num_modes);
41492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(modes && num_modes)
41592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
41692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				dxgi_modes = new DXGI_MODE_DESC[num_modes];
41792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				for(unsigned i = 0; i < num_modes; ++i)
41892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				{
41992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].Width = modes[i]->width;
42092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].Height = modes[i]->height;
42192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].RefreshRate.Numerator = modes[i]->refresh_rate;
42292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].RefreshRate.Denominator = 1;
42392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
42492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dxgi_modes[i].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
42592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				}
42692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
42792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else
42892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
42992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				if(modes)
43092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				{
43192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					free(modes);
43292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					modes = 0;
43392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				}
43492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				goto use_fake_mode;
43592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
43692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
43792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		else
43892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
43992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieriuse_fake_mode:
44092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes = new DXGI_MODE_DESC[1];
44192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].Width = 1920;
44292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].Height = 1200;
44392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].RefreshRate.Numerator = 60;
44492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].RefreshRate.Denominator = 1;
44592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
44692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			dxgi_modes[0].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
44792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
44892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
44992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
45092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	~GalliumDXGIOutput()
45192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
45292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		delete [] dxgi_modes;
45392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		free(modes);
45492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(gamma)
45592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			delete gamma;
45692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
45792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
45892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetDesc(
4590525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_OUTPUT_DESC *out_desc)
46092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
4610525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*out_desc = desc;
46292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
46392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
46492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
46592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetDisplayModeList(
4660525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_FORMAT enum_format,
4670525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT flags,
4680525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT *pcount,
4690525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_MODE_DESC *desc)
47092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
47192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* TODO: should we return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE when we don't
47292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 * support modesetting instead of fake modes?
47392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 */
4740525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		pipe_format format = dxgi_to_pipe_format[enum_format];
47592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(parent->configs_by_pipe_format.count(format))
47692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
4770525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			if(!desc)
47892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
4790525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri				*pcount = num_modes;
48092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return S_OK;
48192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
48292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
4830525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			unsigned copy_modes = std::min(num_modes, *pcount);
48492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			for(unsigned i = 0; i < copy_modes; ++i)
48592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
4860525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri				desc[i] = dxgi_modes[i];
4870525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri				desc[i].Format = enum_format;
48892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
4890525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			*pcount = num_modes;
49092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
49192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(copy_modes < num_modes)
49292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return DXGI_ERROR_MORE_DATA;
49392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else
49492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return S_OK;
49592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
49692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		else
49792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
4980525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			*pcount = 0;
49992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return S_OK;
50092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
50192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
50292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
50392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE FindClosestMatchingMode(
5048224256946619fb25278718bbf4703e3b9d60c93Luca Barbieri		const DXGI_MODE_DESC *pModeToMatch,
5050525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_MODE_DESC *closest_match,
5060525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IUnknown *concerned_device)
50792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
50892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* TODO: actually implement this */
50992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		DXGI_FORMAT dxgi_format = pModeToMatch->Format;
51092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		enum pipe_format format = dxgi_to_pipe_format[dxgi_format];
51192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		init_pipe_to_dxgi_format();
51292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!parent->configs_by_pipe_format.count(format))
51392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
5140525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			if(!concerned_device)
51592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return E_FAIL;
51692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else
51792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
51892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				format = parent->configs[0]->color_format;
51992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				dxgi_format = pipe_to_dxgi_format[format];
52092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
52192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
52292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
5230525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*closest_match = dxgi_modes[0];
5240525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		closest_match->Format = dxgi_format;
52592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
52692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
52792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
52892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE WaitForVBlank( void)
52992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
53092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
53192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
53292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
53392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE TakeOwnership(
5340525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IUnknown *device,
5350525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		BOOL exclusive)
53692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
53792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
53892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
53992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
54092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual void STDMETHODCALLTYPE ReleaseOwnership( void)
54192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
54292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
54392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
54492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetGammaControlCapabilities(
5450525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps)
54692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
5470525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		memset(gamma_caps, 0, sizeof(*gamma_caps));
54892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
54992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
55092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
55192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE SetGammaControl(
5528224256946619fb25278718bbf4703e3b9d60c93Luca Barbieri			const DXGI_GAMMA_CONTROL *pArray)
55392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
55492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!gamma)
55592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			gamma = new DXGI_GAMMA_CONTROL;
55692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*gamma = *pArray;
55792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
55892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
55992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
56092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetGammaControl(
5618224256946619fb25278718bbf4703e3b9d60c93Luca Barbieri			DXGI_GAMMA_CONTROL *pArray)
56292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
56392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(gamma)
56492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			*pArray = *gamma;
56592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		else
56692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
56792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Scale.Red = 1;
56892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Scale.Green = 1;
56992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Scale.Blue = 1;
57092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Offset.Red = 0;
57192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Offset.Green = 0;
57292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pArray->Offset.Blue = 0;
57392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			for(unsigned i = 0; i <= 1024; ++i)
57492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				pArray->GammaCurve[i].Red = pArray->GammaCurve[i].Green = pArray->GammaCurve[i].Blue = (float)i / 1024.0;
57592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
57692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
57792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
57892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
57992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE SetDisplaySurface(
5800525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IDXGISurface *scanout_surface)
58192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
58292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return E_NOTIMPL;
58392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
58492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
58592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetDisplaySurfaceData(
5860525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IDXGISurface *destination)
58792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
58892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return E_NOTIMPL;
58992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
59092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
59192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(
5920525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_FRAME_STATISTICS *stats)
59392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
5940525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		memset(stats, 0, sizeof(*stats));
59592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef _WIN32
5960525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		QueryPerformanceCounter(&stats->SyncQPCTime);
59792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
59892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return E_NOTIMPL;
59992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
60092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
60192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
60292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri/* Swap chain are rather complex, and Microsoft's documentation is rather
60392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * lacking. As far as I know, this is the most thorough publicly available
60492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * description of how swap chains work, based on multiple sources and
60592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * experimentation.
60692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
60792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * There are two modes (called "swap effects") that a swap chain can operate in:
60892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * discard and sequential.
60992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
61092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * In discard mode, things always look as if there is a single buffer, which
61192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * you can get with GetBuffers(0).
61292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * The 2D texture returned by GetBuffers(0) and can only be
61392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * used as a render target view and for resource copies, since no CPU access
61492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * flags are set and only the D3D11_BIND_RENDER_TARGET bind flag is set.
61592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * On Present, it is copied to the actual display
61692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * surface and the contents become undefined.
61792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * D3D may internally use multiple buffers, but you can't observe this, except
61892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * by looking at the buffer contents after Present (but those are undefined).
6190525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri * If it uses multiple buffers internally, then it will normally use buffer_count buffers
62092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * (this has latency implications).
62192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Discard mode seems to internally use a single buffer in windowed mode,
6220525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri * even if DWM is enabled, and buffer_count buffers in fullscreen mode.
62392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
6240525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri * In sequential mode, the runtime alllocates buffer_count buffers.
62592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * You can get each with GetBuffers(n).
62692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * GetBuffers(0) ALWAYS points to the backbuffer to be presented and has the
62792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * same usage constraints as the discard mode.
62892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * GetBuffer(n) with n > 0 points to resources that are identical to buffer 0, but
62992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * are classified as "read-only resources" (due to DXGI_USAGE_READ_ONLY),
63092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * meaning that you can't create render target views on them, or use them as
6316c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri * a CopyResource/CopySubresourceRegion destination.
63292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * It appears the only valid operation is to use them as a source for CopyResource
63392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * and CopySubresourceRegion as well as just waiting for them to become
63492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * buffer 0 again.
63592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Buffer n - 1 is always displayed on screen.
63692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * When you call Present(), the contents of the buffers are rotated, so that buffer 0
63792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * goes to buffer n - 1, and is thus displayed, and buffer 1 goes to buffer 0, becomes
63892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * the accessible back buffer.
63992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * The resources themselves are NOT rotated, so that you can still render on the
64092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * same ID3D11Texture2D*, and views based on it, that you got before Present().
64192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
64292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Present seems to happen by either copying the relevant buffer into the window,
64392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * or alternatively making it the current one, either by programming the CRTC or
64492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * by sending the resource name to the DWM compositor.
64592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
64692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Hence, you can call GetBuffer(0) once and keep using the same ID3D11Texture2D*
64792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * and ID3D11RenderTargetView* (and other views if needed) you got from it.
64892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
64992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * If the window gets resized, DXGI will then "emulate" all successive presentations,
65092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * by using a stretched blit automatically.
65192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Thus, you should handle WM_SIZE and call ResizeBuffers to update the DXGI
65292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * swapchain buffers size to the new window size.
65392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Doing so requires you to release all GetBuffers() results and anything referencing
65492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * them, including views and Direct3D11 deferred context command lists (this is
65592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * documented).
65692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
65792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * How does Microsoft implement the rotation behavior?
65892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * It turns out that it does it by calling RotateResourceIdentitiesDXGI in the user-mode
65992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * DDI driver.
66092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * This will rotate the kernel buffer handle, or possibly rotate the GPU virtual memory
66192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * mappings.
66292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
66392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * The reason this is done by driver instead of by the runtime appears to be that
66492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * this is necessary to support driver-provided command list support, since otherwise
66592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * the command list would not always target the current backbuffer, since it would
66692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * be done at the driver level, while only the runtime knows about the rotation.
66792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
66892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * OK, so how do we implement this in Gallium?
66992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
67092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * There are three strategies:
67192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * 1. Use a single buffer, and always copy it to a window system provided buffer, or
6726c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri *	just give the buffer to the window system if it supports that
67392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * 2. Rotate the buffers in the D3D1x implementation, and recreate and rebind the views.
6746c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri *	 Don't support driver-provided command lists
67592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * 3. Add this rotation functionality to the Gallium driver, with the idea that it would rotate
6766c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri *	remap GPU virtual memory, so that virtual address are unchanged, but the physical
6776c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri *	ones are rotated (so that pushbuffers remain valid).
6786c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri *	If the driver does not support this, either fall back to (1), or have a layer doing this,
6796c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri *	putting a deferred context layer over this intermediate layer.
68092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
68192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * (2) is not acceptable since it prevents an optimal implementation.
6826c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri * (3) is the ideal solution, but it is complicated.
68392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
68492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Hence, we implement (1) for now, and will switch to (3) later.
68592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
68692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Note that (1) doesn't really work for DXGI_SWAP_EFFECT_SEQUENTIAL with more
68792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * than one buffer, so we just pretend we got asked for a single buffer in that case
68892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Fortunately, no one seems to rely on that, so we'll just not implement it at first, and
68992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * later perform the rotation with blits.
69092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Once we switch to (3), we'll just use real rotation to do it..
69192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
69292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * DXGI_SWAP_EFFECT_SEQUENTIAL with more than one buffer is of dubious use
69392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * anyway, since you can only render or write to buffer 0, and other buffers can apparently
69492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * be used only as sources for copies.
69592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * I was unable to find any code using it either in DirectX SDK examples, or on the web.
69692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
69792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * It seems the only reason you would use it is to not have to redraw from scratch, while
6980525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri * also possibly avoid a copy compared to buffer_count == 1, assuming that your
69992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * application is OK with having to redraw starting not from the last frame, but from
70092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * one/two/more frames behind it.
70192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
7020525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri * A better design would forbid the user specifying buffer_count explicitly, and
70392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * would instead let the application give an upper bound on how old the buffer can
70492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * become after presentation, with "infinite" being equivalent to discard.
70592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * The runtime would then tell the application with frame number the buffer switched to
70692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * after present.
70792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * In addition, in a better design, the application would be allowed to specify the
70892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * number of buffers available, having all them usable for rendering, so that things
70992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * like video players could efficiently decode frames in parallel.
71092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Present would in such a better design gain a way to specify the number of buffers
71192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * to present.
71292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
71392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Other miscellaneous info:
71492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * DXGI_PRESENT_DO_NOT_SEQUENCE causes DXGI to hold the frame for another
71592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * vblank interval without rotating the resource data.
71692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
71792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * References:
71892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * "DXGI Overview" in MSDN
71992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * IDXGISwapChain documentation on MSDN
72092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * "RotateResourceIdentitiesDXGI" on MSDN
72192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * http://forums.xna.com/forums/p/42362/266016.aspx
72292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri */
72392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
72492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic float quad_data[] = {
72592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	-1, -1, 0, 0,
72692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	-1, 1, 0, 1,
72792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	1, 1, 1, 1,
72892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	1, -1, 1, 0,
72992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
73092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
73192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct dxgi_blitter
73292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
73392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	pipe_context* pipe;
73492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool normalized;
73592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* fs;
73692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* vs;
73792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* sampler[2];
73892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* elements;
73992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* blend;
74092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* rasterizer;
74192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* zsa;
74292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_clip_state clip;
74392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_vertex_buffer vbuf;
74492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_draw_info draw;
74592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
74692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_blitter(pipe_context* pipe)
74792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	: pipe(pipe)
74892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
74992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		//normalized = !!pipe->screen->get_param(pipe, PIPE_CAP_NPOT_TEXTURES);
75092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// TODO: need to update buffer in unnormalized case
75192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		normalized = true;
75292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
75392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_rasterizer_state rs_state;
75492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&rs_state, 0, sizeof(rs_state));
75592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		rs_state.cull_face = PIPE_FACE_NONE;
75692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		rs_state.gl_rasterization_rules = 1;
757dc4c821f0817a3db716f965692fb701079f66340Marek Olšák		rs_state.depth_clip = 1;
75892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		rs_state.flatshade = 1;
75992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		rasterizer = pipe->create_rasterizer_state(pipe, &rs_state);
76092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
76192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_blend_state blendd;
762e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		memset(&blendd, 0, sizeof(blendd));
76392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		blendd.rt[0].colormask = PIPE_MASK_RGBA;
76492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		blend = pipe->create_blend_state(pipe, &blendd);
76592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
76692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_depth_stencil_alpha_state zsad;
76792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&zsad, 0, sizeof(zsad));
76892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		zsa = pipe->create_depth_stencil_alpha_state(pipe, &zsad);
76992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
77092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_vertex_element velem[2];
77192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&velem[0], 0, sizeof(velem[0]) * 2);
77292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		velem[0].src_offset = 0;
77392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		velem[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
77492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		velem[1].src_offset = 8;
77592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		velem[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
77692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		elements = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
77792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
77892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		for(unsigned stretch = 0; stretch < 2; ++stretch)
77992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
78092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			struct pipe_sampler_state sampler_state;
78192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			memset(&sampler_state, 0, sizeof(sampler_state));
78292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.min_img_filter = stretch ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
78392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.mag_img_filter = stretch ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
78492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
78592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
78692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
78792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler_state.normalized_coords = normalized;
78892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
78992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			sampler[stretch] = pipe->create_sampler_state(pipe, &sampler_state);
79092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
79192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
79292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		fs = util_make_fragment_tex_shader(pipe, normalized ? TGSI_TEXTURE_2D : TGSI_TEXTURE_RECT, TGSI_INTERPOLATE_LINEAR);
79392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
79492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		const unsigned semantic_names[] = { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC };
79592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		const unsigned semantic_indices[] = { 0, 0 };
79692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, semantic_indices);
79792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
798eafb7f234d11a290b00dcaf5492b9bdad1cf5148Marek Olšák		vbuf.buffer = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER,
799eafb7f234d11a290b00dcaf5492b9bdad1cf5148Marek Olšák						 PIPE_USAGE_STREAM, sizeof(quad_data));
80092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		vbuf.buffer_offset = 0;
80192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		vbuf.stride = 4 * sizeof(float);
80292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe_buffer_write(pipe, vbuf.buffer, 0, sizeof(quad_data), quad_data);
80392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
80492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&clip, 0, sizeof(clip));
80592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
80692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&draw, 0, sizeof(draw));
80792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		draw.mode = PIPE_PRIM_QUADS;
80892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		draw.count = 4;
80992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		draw.instance_count = 1;
81092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		draw.max_index = ~0;
81192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
81292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
81392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void blit(struct pipe_surface* surf, struct pipe_sampler_view* view, unsigned x, unsigned y, unsigned w, unsigned h)
81492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
81592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_framebuffer_state fb;
81692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&fb, 0, sizeof(fb));
81792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		fb.nr_cbufs = 1;
81892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		fb.cbufs[0] = surf;
81992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		fb.width = surf->width;
82092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		fb.height = surf->height;
82192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
82292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_viewport_state viewport;
82392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		float half_width = w * 0.5f;
82492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		float half_height = h * 0.5f;
82592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.scale[0] = half_width;
82692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.scale[1] = half_height;
82792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.scale[2] = 1.0f;
82892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.scale[3] = 1.0f;
82992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.translate[0] = x + half_width;
83092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.translate[1] = y + half_height;
83192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.translate[2] = 0.0f;
83292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		viewport.translate[3] = 1.0f;
83392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
83492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		bool stretch = view->texture->width0 != w || view->texture->height0 != h;
83592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(pipe->render_condition)
83692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pipe->render_condition(pipe, 0, 0);
83792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->set_framebuffer_state(pipe, &fb);
83892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_fragment_sampler_states(pipe, 1, &sampler[stretch]);
83992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->set_viewport_state(pipe, &viewport);
84092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->set_clip_state(pipe, &clip);
84192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_rasterizer_state(pipe, rasterizer);
84292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_depth_stencil_alpha_state(pipe, zsa);
84392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_blend_state(pipe, blend);
84492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_vertex_elements_state(pipe, elements);
84592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->set_vertex_buffers(pipe, 1, &vbuf);
84692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_fs_state(pipe, fs);
84792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->bind_vs_state(pipe, vs);
84892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(pipe->bind_gs_state)
84992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pipe->bind_gs_state(pipe, 0);
85014193da589275969be31dbdb3280bb48cd24d0c0Christoph Bumiller		if(pipe->set_stream_output_targets)
85114193da589275969be31dbdb3280bb48cd24d0c0Christoph Bumiller			pipe->set_stream_output_targets(pipe, 0, NULL, 0);
85292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->set_fragment_sampler_views(pipe, 1, &view);
85392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
85492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->draw_vbo(pipe, &draw);
85592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
85692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
85792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	~dxgi_blitter()
85892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
85992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_blend_state(pipe, blend);
86092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_rasterizer_state(pipe, rasterizer);
86192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_depth_stencil_alpha_state(pipe, zsa);
86292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_sampler_state(pipe, sampler[0]);
86392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_sampler_state(pipe, sampler[1]);
86492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_vertex_elements_state(pipe, elements);
86592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_vs_state(pipe, vs);
86692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->delete_fs_state(pipe, fs);
86792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		pipe->screen->resource_destroy(pipe->screen, vbuf.buffer);
86892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
86992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
87092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
87192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDXGIFactory>
87292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
87392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IDXGIDevice>dxgi_device;
87492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IGalliumDevice>gallium_device;
87592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<GalliumDXGIAdapter> adapter;
87692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IDXGIOutput> target;
87792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
878e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	DXGI_SWAP_CHAIN_DESC desc;
879e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
88092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct native_surface* surface;
88192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_config* config;
88292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
883e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	void* window;
88492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_resource* resources[NUM_NATIVE_ATTACHMENTS];
88592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	int width;
88692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	int height;
88792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned seq_num;
88892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool ever_validated;
88992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool needs_validation;
89092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned present_count;
89192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
89292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	ComPtr<IDXGISurface> buffer0;
89392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_resource* gallium_buffer0;
89492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_sampler_view* gallium_buffer0_view;
89592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
89692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	struct pipe_context* pipe;
89792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool owns_pipe;
89892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
89992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	BOOL fullscreen;
90092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
90192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	std::auto_ptr<dxgi_blitter> blitter;
90292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool formats_compatible;
90392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
90492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	GalliumDXGISwapChain(GalliumDXGIFactory* factory, IUnknown* p_device, const DXGI_SWAP_CHAIN_DESC& p_desc)
905e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	: GalliumDXGIObject<IDXGISwapChain, GalliumDXGIFactory>(factory), desc(p_desc), surface(0)
90692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
90792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		HRESULT hr;
90892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
90992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = p_device->QueryInterface(IID_IGalliumDevice, (void**)&gallium_device);
91092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
91192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			throw hr;
91292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
91392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = p_device->QueryInterface(IID_IDXGIDevice, (void**)&dxgi_device);
91492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
91592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			throw hr;
91692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
91792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = dxgi_device->GetAdapter((IDXGIAdapter**)&adapter);
91892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
91992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			throw hr;
92092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
921e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		memset(resources, 0, sizeof(resources));
922e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
923e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(desc.SwapEffect == DXGI_SWAP_EFFECT_SEQUENTIAL && desc.BufferCount != 1)
924e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		{
9250525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			std::cerr << "Gallium DXGI: if DXGI_SWAP_EFFECT_SEQUENTIAL is specified, only buffer_count == 1 is implemented, but " << desc.BufferCount << " was specified: ignoring this" << std::endl;
926e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			// change the returned desc, so that the application might perhaps notice what we did and react well
927e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			desc.BufferCount = 1;
928e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		}
929e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
930e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		pipe = gallium_device->GetGalliumContext();
931e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		owns_pipe = false;
932e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(!pipe)
933e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		{
934e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			pipe = adapter->display->screen->context_create(adapter->display->screen, 0);
935e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			owns_pipe = true;
936e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		}
937e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
938e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		blitter.reset(new dxgi_blitter(pipe));
939e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		window = 0;
940f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
941f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		hr = resolve_zero_width_height(true);
942f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		if(!SUCCEEDED(hr))
943f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri			throw hr;
944e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	}
945e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
946e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	void init_for_window()
947e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	{
948e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(surface)
949e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		{
950e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			surface->destroy(surface);
951e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			surface = 0;
952e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		}
95392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
95492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		unsigned config_num;
955e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(!strcmp(parent->platform->name, "X11"))
95692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
95792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			XWindowAttributes xwa;
958e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			XGetWindowAttributes((Display*)parent->display, (Window)window, &xwa);
959db1fbb1efc10ee4853c3fbdf63567e62fdde7447Luca Barbieri			assert(adapter->configs_by_native_visual_id.count(xwa.visual->visualid));
96092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			config_num = adapter->configs_by_native_visual_id[xwa.visual->visualid];
96192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
96292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		else
96392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
96492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			enum pipe_format format = dxgi_to_pipe_format[desc.BufferDesc.Format];
96592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!adapter->configs_by_pipe_format.count(format))
96692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
96792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				if(adapter->configs_by_pipe_format.empty())
96892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					throw E_FAIL;
96992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				// TODO: choose the best match
97092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				format = (pipe_format)adapter->configs_by_pipe_format.begin()->first;
97192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
97292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			// TODO: choose the best config
97392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			config_num = adapter->configs_by_pipe_format.find(format)->second;
97492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
97592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
97692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		config = adapter->configs[config_num];
977e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		surface = adapter->display->create_window_surface(adapter->display, (EGLNativeWindowType)window, config);
97892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		surface->user_data = this;
97992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
98092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		width = 0;
98192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		height = 0;
98292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		seq_num = 0;
98392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		present_count = 0;
98492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		needs_validation = true;
98592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		ever_validated = false;
98692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
98792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		formats_compatible = util_is_format_compatible(
98892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				util_format_description(dxgi_to_pipe_format[desc.BufferDesc.Format]),
98992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				util_format_description(config->color_format));
99092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
99192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
99292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	~GalliumDXGISwapChain()
99392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
99492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(owns_pipe)
99592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pipe->destroy(pipe);
99692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
99792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
9986c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetDevice(
9998224256946619fb25278718bbf4703e3b9d60c93Luca Barbieri		REFIID riid,
10000525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		void **pdevice)
10016c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
10020525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		return dxgi_device->QueryInterface(riid, pdevice);
10036c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
100492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
10056c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	HRESULT create_buffer0()
10066c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	{
10076c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri		HRESULT hr;
100892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		ComPtr<IDXGISurface> new_buffer0;
100992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		DXGI_USAGE usage = DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT;
101092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD)
101192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			usage |= DXGI_USAGE_DISCARD_ON_PRESENT;
101292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		// for our blitter
101392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		usage |= DXGI_USAGE_SHADER_INPUT;
101492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
101592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		DXGI_SURFACE_DESC surface_desc;
101692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		surface_desc.Format = desc.BufferDesc.Format;
101792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		surface_desc.Width = desc.BufferDesc.Width;
101892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		surface_desc.Height = desc.BufferDesc.Height;
101992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		surface_desc.SampleDesc = desc.SampleDesc;
102092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = dxgi_device->CreateSurface(&surface_desc, 1, usage, 0, &new_buffer0);
102192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
102292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return hr;
102392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
102492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		ComPtr<IGalliumResource> gallium_resource;
102592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		hr = new_buffer0->QueryInterface(IID_IGalliumResource, (void**)&gallium_resource);
102692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!SUCCEEDED(hr))
102792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return hr;
102892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
102992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_resource* new_gallium_buffer0 = gallium_resource->GetGalliumResource();
103092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!new_gallium_buffer0)
103192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return E_FAIL;
103292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
103392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		buffer0.reset(new_buffer0.steal());
103492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		gallium_buffer0 = new_gallium_buffer0;
103592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		struct pipe_sampler_view templat;
103692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		memset(&templat, 0, sizeof(templat));
103792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.texture = gallium_buffer0;
103892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.swizzle_r = 0;
103992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.swizzle_g = 1;
104092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.swizzle_b = 2;
104192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.swizzle_a = 3;
104292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		templat.format = gallium_buffer0->format;
104392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		gallium_buffer0_view = pipe->create_sampler_view(pipe, gallium_buffer0, &templat);
104492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
10456c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri	}
104692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
104792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	bool validate()
104892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
104992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		unsigned new_seq_num;
105092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		needs_validation = false;
105192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1052e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(!surface->validate(surface, (1 << NATIVE_ATTACHMENT_BACK_LEFT) | (1 << NATIVE_ATTACHMENT_FRONT_LEFT), &new_seq_num, resources, &width, &height))
105392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return false;
105492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
105592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!ever_validated || seq_num != new_seq_num)
105692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
105792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			seq_num = new_seq_num;
105892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			ever_validated = true;
105992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
106092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return true;
106192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
106292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1063f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	HRESULT resolve_zero_width_height(bool force = false)
1064f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	{
1065f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		if(!force && desc.BufferDesc.Width && desc.BufferDesc.Height)
1066f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri			return S_OK;
1067f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
1068f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		unsigned width, height;
1069f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		HRESULT hr = parent->backend->GetPresentSize(desc.OutputWindow, &width, &height);
1070f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		if(!SUCCEEDED(hr))
1071f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri			return hr;
1072f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
1073f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		// On Windows, 8 is used, and a debug message saying so gets printed
1074f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		if(!width)
1075f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri			width = 8;
1076f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		if(!height)
1077f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri			height = 8;
1078f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
1079f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		if(!desc.BufferDesc.Width)
1080f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri			desc.BufferDesc.Width = width;
1081f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		if(!desc.BufferDesc.Height)
1082f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri			desc.BufferDesc.Height = height;
1083f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		return S_OK;
1084f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri	}
1085f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
108692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE Present(
10870525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT sync_interval,
10880525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT flags)
108992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
1090f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		HRESULT hr;
10910525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		if(flags & DXGI_PRESENT_TEST)
1092f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri			return parent->backend->TestPresent(desc.OutputWindow);
109392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
109492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!buffer0)
109592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
109692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			HRESULT hr = create_buffer0();
109792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!SUCCEEDED(hr))
109892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return hr;
109992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
110092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1101e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		void* cur_window = 0;
1102e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		RECT rect;
1103e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		RGNDATA* rgndata;
1104e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		BOOL preserve_aspect_ratio;
1105e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		unsigned dst_w, dst_h;
1106e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		bool db;
1107e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		struct pipe_resource* dst;
1108e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		struct pipe_resource* src;
1109e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		struct pipe_surface* dst_surface;
11108adaed934727f9efa61686ffe0f528d40c693862Chia-I Wu		struct native_present_control ctrl;
1111e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
1112f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		void* present_cookie;
1113f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		hr = parent->backend->BeginPresent(desc.OutputWindow, &present_cookie, &cur_window, &rect, &rgndata, &preserve_aspect_ratio);
1114f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		if(hr != S_OK)
1115f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri			return hr;
1116f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
1117e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(!cur_window || rect.left >= rect.right || rect.top >= rect.bottom)
1118e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			goto end_present;
1119e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
1120e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(cur_window != window)
1121e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		{
1122e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			window = cur_window;
1123e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			init_for_window();
1124e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		}
1125e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
112692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(needs_validation)
112792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
112892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!validate())
112992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return DXGI_ERROR_DEVICE_REMOVED;
113092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
113192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
113254ee7721a142f57c932f77e6a33af6874320cdc0Luca Barbieri		db = !!(config->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT));
1133e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dst = resources[db ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT];
1134e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		src = gallium_buffer0;
1135e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dst_surface = 0;
113692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1137f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		assert(src);
1138f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		assert(dst);
1139f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri
114092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* TODO: sharing the context for blitting won't work correctly if queries are active
114192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 * Hopefully no one is crazy enough to keep queries active while presenting, expecting
114292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 * sensible results.
114392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 * We could alternatively force using another context, but that might cause inefficiency issues
114492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		 */
114592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1146e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if((unsigned)rect.right > dst->width0)
1147e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			rect.right = dst->width0;
1148e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if((unsigned)rect.bottom > dst->height0)
1149e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			rect.bottom = dst->height0;
1150e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(rect.left > rect.right)
1151e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			rect.left = rect.right;
1152e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(rect.top > rect.bottom)
1153e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			rect.top = rect.bottom;
115492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1155e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(rect.left >= rect.right && rect.top >= rect.bottom)
1156e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			goto end_present;
115792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1158e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dst_w = rect.right - rect.left;
1159e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dst_h = rect.bottom - rect.top;
1160e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
1161e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		// TODO: add support for rgndata
1162e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri//		if(preserve_aspect_ratio || !rgndata)
1163e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		if(1)
116492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
1165e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			unsigned blit_x, blit_y, blit_w, blit_h;
11665def3b7be142cfc6bbb1534bd0557c5f324de8c0Christoph Bumiller			static const union pipe_color_union black = { { 0, 0, 0, 0 } };
1167e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
11684c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger			if(!formats_compatible || src->width0 != dst_w || src->height0 != dst_h) {
11694c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				struct pipe_surface templat;
11704c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				templat.usage = PIPE_BIND_RENDER_TARGET;
11714c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				templat.format = dst->format;
11724c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				templat.u.tex.level = 0;
11734c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				templat.u.tex.first_layer = 0;
11744c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				templat.u.tex.last_layer = 0;
11754c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				dst_surface = pipe->create_surface(pipe, dst, &templat);
11764c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger			}
1177e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
1178e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(preserve_aspect_ratio)
1179e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			{
1180e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				int delta = src->width0 * dst_h - dst_w * src->height0;
1181e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				if(delta > 0)
1182e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				{
1183e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_w = dst_w;
1184e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_h = dst_w * src->height0 / src->width0;
1185e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				}
1186e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				else if(delta < 0)
1187e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				{
1188e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_w = dst_h * src->width0 / src->height0;
1189e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_h = dst_h;
1190e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				}
1191e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				else
1192e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				{
1193e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_w = dst_w;
1194e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					blit_h = dst_h;
1195e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				}
119692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1197e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_x = (dst_w - blit_w) >> 1;
1198e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_y = (dst_h - blit_h) >> 1;
1199e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			}
1200e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			else
1201e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			{
1202e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_x = 0;
1203e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_y = 0;
1204e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_w = dst_w;
1205e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blit_h = dst_h;
1206e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			}
120792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1208e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(blit_x)
12096dd284f7c8fac22f64c13fdf9909094f5ec59086Dave Airlie				pipe->clear_render_target(pipe, dst_surface, &black, rect.left, rect.top, blit_x, dst_h);
1210e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(blit_y)
12116dd284f7c8fac22f64c13fdf9909094f5ec59086Dave Airlie				pipe->clear_render_target(pipe, dst_surface, &black, rect.left, rect.top, dst_w, blit_y);
121292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1213e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(formats_compatible && blit_w == src->width0 && blit_h == src->height0)
1214e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			{
12154c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				pipe_box box;
12165d70b5d10b30ffb715f54f870df6e6eb04acdf45Christoph Bumiller				box.x = box.y = box.z = 0;
12174c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				box.width = blit_w;
12184c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				box.height = blit_h;
12195d70b5d10b30ffb715f54f870df6e6eb04acdf45Christoph Bumiller				box.depth = 1;
12204c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger				pipe->resource_copy_region(pipe, dst, 0, rect.left, rect.top, 0, src, 0, &box);
1221e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			}
1222e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			else
1223e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			{
1224e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				blitter->blit(dst_surface, gallium_buffer0_view, rect.left + blit_x, rect.top + blit_y, blit_w, blit_h);
1225e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri				if(!owns_pipe)
1226e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri					gallium_device->RestoreGalliumState();
1227e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			}
122892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1229e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(blit_w != dst_w)
12306dd284f7c8fac22f64c13fdf9909094f5ec59086Dave Airlie				pipe->clear_render_target(pipe, dst_surface, &black, rect.left + blit_x + blit_w, rect.top, dst_w - blit_x - blit_w, dst_h);
1231e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri			if(blit_h != dst_h)
12326dd284f7c8fac22f64c13fdf9909094f5ec59086Dave Airlie				pipe->clear_render_target(pipe, dst_surface, &black, rect.left, rect.top + blit_y + blit_h, dst_w, dst_h - blit_y - blit_h);
1233e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		}
123492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
123592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(dst_surface)
12364c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger			pipe->surface_destroy(pipe, dst_surface);
123792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
12387e02303497237cde958c28608477d0c355a8038bMarek Olšák                pipe->flush(pipe, 0);
1239681f87e09bc278924a19fc960809556e607886f1Luca Barbieri
12408adaed934727f9efa61686ffe0f528d40c693862Chia-I Wu		memset(&ctrl, 0, sizeof(ctrl));
12418adaed934727f9efa61686ffe0f528d40c693862Chia-I Wu		ctrl.natt = (db) ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT;
12428adaed934727f9efa61686ffe0f528d40c693862Chia-I Wu		if(!surface->present(surface, &ctrl))
1243250d81da256fc919544f8c97b4e2364d3795f6c0Chia-I Wu			return DXGI_ERROR_DEVICE_REMOVED;
124492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1245e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieriend_present:
1246e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		parent->backend->EndPresent(desc.OutputWindow, present_cookie);
1247e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
124892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		++present_count;
124992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
125092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
125192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
125292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetBuffer(
12536c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri			UINT Buffer,
12548224256946619fb25278718bbf4703e3b9d60c93Luca Barbieri			REFIID riid,
12558224256946619fb25278718bbf4703e3b9d60c93Luca Barbieri			void **ppSurface)
125692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
125792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(Buffer > 0)
125892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
125992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(desc.SwapEffect == DXGI_SWAP_EFFECT_SEQUENTIAL)
126092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				std::cerr << "DXGI unimplemented: GetBuffer(n) with n > 0 not supported, returning buffer 0 instead!" << std::endl;
126192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else
126292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				std::cerr << "DXGI error: in GetBuffer(n), n must be 0 for DXGI_SWAP_EFFECT_DISCARD\n" << std::endl;
126392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
126492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
126592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(!buffer0)
126692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
126792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			HRESULT hr = create_buffer0();
126892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(!SUCCEEDED(hr))
126992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return hr;
127092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
127192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return buffer0->QueryInterface(riid, ppSurface);
127292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
127392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
127492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	/* TODO: implement somehow */
127592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE SetFullscreenState(
12760525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		BOOL fullscreen,
12770525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IDXGIOutput *target)
127892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
12790525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		fullscreen = fullscreen;
12800525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		target = target;
128192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
128292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
128392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
128492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetFullscreenState(
12850525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		BOOL *out_fullscreen,
12860525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IDXGIOutput **out_target)
128792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
12880525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		if(out_fullscreen)
12890525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			*out_fullscreen = fullscreen;
12900525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		if(out_target)
12910525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			*out_target = target.ref();
129292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
129392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
129492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
129592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetDesc(
12960525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_SWAP_CHAIN_DESC *out_desc)
129792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
12980525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*out_desc = desc;
129992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
130092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
130192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
130292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE ResizeBuffers(
13030525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT buffer_count,
13040525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT width,
13050525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT height,
13060525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_FORMAT new_format,
13070525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT swap_chain_flags)
130892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
130992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(buffer0)
131092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
131192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			buffer0.p->AddRef();
131292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			ULONG v = buffer0.p->Release();
131392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			// we must fail if there are any references to buffer0 other than ours
131492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(v > 1)
131592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				return E_FAIL;
131692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			pipe_sampler_view_reference(&gallium_buffer0_view, 0);
131792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			buffer0 = (IUnknown*)NULL;
131892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			gallium_buffer0 = 0;
131992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
132092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
132192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(desc.SwapEffect != DXGI_SWAP_EFFECT_SEQUENTIAL)
13220525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri			desc.BufferCount = buffer_count;
13230525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		desc.BufferDesc.Format = new_format;
13240525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		desc.BufferDesc.Width = width;
13250525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		desc.BufferDesc.Height = height;
13260525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		desc.Flags = swap_chain_flags;
1327f976cd0c9ead6a5e63146c11823770176c149a12Luca Barbieri		return resolve_zero_width_height();
132892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
132992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
133092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE ResizeTarget(
13310525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		const DXGI_MODE_DESC *out_new_target_parameters)
133292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
133392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		/* TODO: implement */
133492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
133592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
133692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
133792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetContainingOutput(
13380525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		IDXGIOutput **out_output)
133992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
13400525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*out_output = adapter->outputs[0].ref();
134192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
134292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
134392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
134492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(
13450525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		DXGI_FRAME_STATISTICS *out_stats)
134692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
13470525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		memset(out_stats, 0, sizeof(*out_stats));
134892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef _WIN32
13490525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		QueryPerformanceCounter(&out_stats->SyncQPCTime);
135092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
13510525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		out_stats->PresentCount = present_count;
13520525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		out_stats->PresentRefreshCount = present_count;
13530525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		out_stats->SyncRefreshCount = present_count;
135492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
135592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
135692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
135792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount(
13580525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		UINT *last_present_count)
135992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
13600525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*last_present_count = present_count;
136192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
136292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
136392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
136492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
136592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic void GalliumDXGISwapChainRevalidate(IDXGISwapChain* swap_chain)
136692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
136792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	((GalliumDXGISwapChain*)swap_chain)->needs_validation = true;
136892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
136992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
13700525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieristatic HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy, IDXGIAdapter1** out_adapter)
137192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
137292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	try
137392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
13740525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*out_adapter = new GalliumDXGIAdapter(factory, platform, dpy);
137592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
137692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
137792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	catch(HRESULT hr)
137892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
137992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return hr;
138092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
138192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
138292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
13830525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieristatic HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** out_output)
138492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
138592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	try
138692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
13870525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*out_output = new GalliumDXGIOutput(adapter, name, connector);
138892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
138992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
139092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	catch(HRESULT hr)
139192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
139292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return hr;
139392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
139492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
139592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
13960525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieristatic HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** out_swap_chain)
139792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
139892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	try
139992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
14000525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		*out_swap_chain = new GalliumDXGISwapChain(factory, device, desc);
140192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return S_OK;
140292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
140392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	catch(HRESULT hr)
140492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
140592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return hr;
140692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
140792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
140892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
140992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristruct dxgi_binding
141092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
141192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const struct native_platform* platform;
141292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void* display;
1413e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	IGalliumDXGIBackend* backend;
141492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
141592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
141692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic dxgi_binding dxgi_default_binding;
141792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieristatic __thread dxgi_binding dxgi_thread_binding;
14183a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wustatic const struct native_event_handler dxgi_event_handler = {
14193a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu   GalliumDXGIAdapter::handle_invalid_surface,
14203a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu   dxgi_loader_create_drm_screen,
14213a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu   dxgi_loader_create_sw_screen
14223a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu};
142392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
142492617aeac109481258f0c3863d09c1b8903d438bLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIUseNothing()
142592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
142692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.platform = 0;
142792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.display = 0;
1428e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	if(dxgi_thread_binding.backend)
1429e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dxgi_thread_binding.backend->Release();
1430e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	dxgi_thread_binding.backend = 0;
143192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
143292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
143392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef GALLIUM_DXGI_USE_X11
1434e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIUseX11Display(Display* dpy, IGalliumDXGIBackend* backend)
143592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
1436e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	GalliumDXGIUseNothing();
14373a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu	dxgi_thread_binding.platform = native_get_x11_platform(&dxgi_event_handler);
143892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.display = dpy;
1439e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri
1440e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	if(backend)
1441e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	{
1442e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		dxgi_thread_binding.backend = backend;
1443e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		backend->AddRef();
1444e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	}
144592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
144692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
144792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
1448e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri/*
144992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef GALLIUM_DXGI_USE_DRM
145092617aeac109481258f0c3863d09c1b8903d438bLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIUseDRMCard(int fd)
145192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
1452e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	GalliumDXGIUseNothing();
14533a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu	dxgi_thread_binding.platform = native_get_drm_platform(&dxgi_event_handler);
145492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.display = (void*)fd;
1455e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	dxgi_thread_binding.backend = 0;
145692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
145792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
145892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
145992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef GALLIUM_DXGI_USE_FBDEV
146092617aeac109481258f0c3863d09c1b8903d438bLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIUseFBDev(int fd)
146192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
1462e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	GalliumDXGIUseNothing();
14633a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu	dxgi_thread_binding.platform = native_get_fbdev_platform(&dxgi_event_handler);
146492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.display = (void*)fd;
1465e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	dxgi_thread_binding.backend = 0;
146692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
146792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
146892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
146992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#ifdef GALLIUM_DXGI_USE_GDI
147092617aeac109481258f0c3863d09c1b8903d438bLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIUseHDC(HDC hdc, PFNHWNDRESOLVER resolver, void* resolver_cookie)
147192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
1472e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	GalliumDXGIUseNothing();
14733a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu	dxgi_thread_binding.platform = native_get_gdi_platform(&dxgi_event_handler);
147492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_thread_binding.display = (void*)hdc;
1475e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri	dxgi_thread_binding.backend = 0;
147692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
147792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
1478e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri*/
147992617aeac109481258f0c3863d09c1b8903d438bLuca Barbierivoid STDMETHODCALLTYPE GalliumDXGIMakeDefault()
148092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
1481881c05aa1ec22bb229a0bceae372d68f9fc91431Luca Barbieri	if(dxgi_default_binding.backend)
1482881c05aa1ec22bb229a0bceae372d68f9fc91431Luca Barbieri		dxgi_default_binding.backend->Release();
148392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	dxgi_default_binding = dxgi_thread_binding;
1484881c05aa1ec22bb229a0bceae372d68f9fc91431Luca Barbieri	if(dxgi_default_binding.backend)
1485881c05aa1ec22bb229a0bceae372d68f9fc91431Luca Barbieri		dxgi_default_binding.backend->AddRef();
148692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
148792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
148892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri /* TODO: why did Microsoft add this? should we do something different for DXGI 1.0 and 1.1?
14896c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri * Or perhaps what they actually mean is "only create a single factory in your application"?
14906c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri * TODO: should we use a singleton here, so we never have multiple DXGI objects for the same thing? */
14916c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri HRESULT STDMETHODCALLTYPE CreateDXGIFactory1(
14928224256946619fb25278718bbf4703e3b9d60c93Luca Barbieri		REFIID riid,
14930525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		void **out_factory
149492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri)
149592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri {
149692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 GalliumDXGIFactory* factory;
14970525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	 *out_factory = 0;
149892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 if(dxgi_thread_binding.platform)
1499e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		 factory = new GalliumDXGIFactory(dxgi_thread_binding.platform, dxgi_thread_binding.display, dxgi_thread_binding.backend);
150092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 else if(dxgi_default_binding.platform)
1501e7624e23a3a374896863f54fe30dafd0bff8a91aLuca Barbieri		 factory = new GalliumDXGIFactory(dxgi_default_binding.platform, dxgi_default_binding.display, dxgi_default_binding.backend);
150292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 else
15033a07d9594a60dd84464b30b2d9ffdfc4f219bc5bChia-I Wu		 factory = new GalliumDXGIFactory(native_get_x11_platform(&dxgi_event_handler), NULL, NULL);
15040525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	 HRESULT hres = factory->QueryInterface(riid, out_factory);
150592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 factory->Release();
150692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	 return hres;
150792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri }
150892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
15096c598c78bd17642d731cf57b8369cc794f64ba2fLuca Barbieri HRESULT STDMETHODCALLTYPE CreateDXGIFactory(
15108224256946619fb25278718bbf4703e3b9d60c93Luca Barbieri		 REFIID riid,
15110525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri		 void **out_factor
151292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri)
151392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri {
15140525384c11a6bc95f9fc8f621ea22e13355c2ac8Luca Barbieri	 return CreateDXGIFactory1(riid, out_factor);
151592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri }
1516