gallium: add usage parameter to pipe_buffer_create
[mesa.git] / src / gallium / state_trackers / d3d1x / dxgi / src / dxgi_native.cpp
index 41c8f29847e4905ccf2af11a3cb477af485b2784..2e45f3f43e97be64ae08a34cc4309bbd416209d4 100644 (file)
@@ -40,9 +40,9 @@ struct GalliumDXGIAdapter;
 struct GalliumDXGISwapChain;
 struct GalliumDXGIFactory;
 
-static HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** ppSwapChain);
-static HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* adapter, const struct native_platform* platform, void* dpy, IDXGIAdapter1** ppAdapter);
-static HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** ppOutput);
+static HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** out_swap_chain);
+static HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* adapter, const struct native_platform* platform, void* dpy, IDXGIAdapter1** out_adapter);
+static HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** out_output);
 static void GalliumDXGISwapChainRevalidate(IDXGISwapChain* swap_chain);
 
 template<typename Base = IDXGIObject, typename Parent = IDXGIObject>
@@ -55,116 +55,191 @@ struct GalliumDXGIObject : public GalliumPrivateDataComObject<Base>
                this->parent = p_parent;
        }
 
-        virtual HRESULT STDMETHODCALLTYPE GetParent(
-            __in  REFIID riid,
-            __out  void **ppParent)
+       virtual HRESULT STDMETHODCALLTYPE GetParent(
+               REFIID riid,
+               void **out_parent)
+       {
+               return parent->QueryInterface(riid, out_parent);
+       }
+};
+
+COM_INTERFACE(IGalliumDXGIBackend, IUnknown)
+
+// TODO: somehow check whether the window is fully obscured or not
+struct GalliumDXGIIdentityBackend : public GalliumComObject<IGalliumDXGIBackend>
+{
+       virtual HRESULT STDMETHODCALLTYPE BeginPresent(
+               HWND hwnd,
+               void** present_cookie,
+               void** window,
+               RECT *rect,
+               RGNDATA **rgndata,
+               BOOL* preserve_aspect_ratio
+       )
+       {
+               *window = (void*)hwnd;
+               rect->left = 0;
+               rect->top = 0;
+               rect->right = INT_MAX;
+               rect->bottom = INT_MAX;
+               *rgndata = 0;
+
+               // yes, because we like things looking good
+               *preserve_aspect_ratio = TRUE;
+               *present_cookie = 0;
+               return S_OK;
+       }
+
+       virtual void STDMETHODCALLTYPE EndPresent(
+               HWND hwnd,
+               void* present_cookie
+       )
+       {}
+
+       virtual HRESULT STDMETHODCALLTYPE TestPresent(HWND hwnd)
+       {
+               return S_OK;
+       }
+
+        virtual HRESULT STDMETHODCALLTYPE GetPresentSize(
+                HWND hwnd,
+                unsigned* width,
+                unsigned* height
+        )
         {
-               return parent->QueryInterface(riid, ppParent);
+                *width = 0;
+                *height = 0;
+                return S_OK;
         }
 };
 
-static void* STDMETHODCALLTYPE identity_resolver(void* cookie, HWND hwnd)
+// TODO: maybe install an X11 error hook, so we can return errors properly
+struct GalliumDXGIX11IdentityBackend : public GalliumDXGIIdentityBackend
 {
-       return (void*)hwnd;
-}
+       Display* dpy;
+
+       GalliumDXGIX11IdentityBackend(Display* dpy)
+       : dpy(dpy)
+       {}
+
+       virtual HRESULT STDMETHODCALLTYPE GetPresentSize(
+               HWND hwnd,
+               unsigned* width,
+               unsigned* height
+       )
+        {
+               XWindowAttributes xwa;
+               XGetWindowAttributes(dpy, (Window)hwnd, &xwa);
+               *width = xwa.width;
+               *height = xwa.height;
+               return S_OK;
+        }
+};
 
 struct GalliumDXGIFactory : public GalliumDXGIObject<IDXGIFactory1, IUnknown>
 {
-        HWND associated_window;
+       HWND associated_window;
        const struct native_platform* platform;
        void* display;
-       PFNHWNDRESOLVER resolver;
+       ComPtr<IGalliumDXGIBackend> backend;
        void* resolver_cookie;
 
-        GalliumDXGIFactory(const struct native_platform* platform, void* display, PFNHWNDRESOLVER resolver, void* resolver_cookie)
-        : GalliumDXGIObject<IDXGIFactory1, IUnknown>((IUnknown*)NULL), platform(platform), display(display), resolver(resolver ? resolver : identity_resolver), resolver_cookie(resolver_cookie)
-        {}
+       GalliumDXGIFactory(const struct native_platform* platform, void* display, IGalliumDXGIBackend* p_backend)
+       : GalliumDXGIObject<IDXGIFactory1, IUnknown>((IUnknown*)NULL), platform(platform), display(display)
+        {
+               if(p_backend)
+                       backend = p_backend;
+               else if(!strcmp(platform->name, "X11"))
+                       backend.reset(new GalliumDXGIX11IdentityBackend((Display*)display));
+               else
+                       backend.reset(new GalliumDXGIIdentityBackend());
+       }
 
-        virtual HRESULT STDMETHODCALLTYPE EnumAdapters(
-               UINT Adapter,
-               __out  IDXGIAdapter **ppAdapter)
+       virtual HRESULT STDMETHODCALLTYPE EnumAdapters(
+               UINT adapter,
+               IDXGIAdapter **out_adapter)
        {
-               return EnumAdapters1(Adapter, (IDXGIAdapter1**)ppAdapter);
+               return EnumAdapters1(adapter, (IDXGIAdapter1**)out_adapter);
        }
 
-        virtual HRESULT STDMETHODCALLTYPE EnumAdapters1(
-               UINT Adapter,
-               __out  IDXGIAdapter1 **ppAdapter)
-        {
-               *ppAdapter = 0;
-               if(Adapter == 0)
+       virtual HRESULT STDMETHODCALLTYPE EnumAdapters1(
+               UINT adapter,
+               IDXGIAdapter1 **out_adapter)
+       {
+               *out_adapter = 0;
+               if(adapter == 0)
                {
-                       return GalliumDXGIAdapterCreate(this, platform, display, ppAdapter);
+                       return GalliumDXGIAdapterCreate(this, platform, display, out_adapter);
                }
 #if 0
                // TODO: enable this
-               if(platform == native_get_x11_platform())
-               {
-                       unsigned nscreens = ScreenCount((Display*)display);
-                       if(Adapter < nscreens)
-                       {
-                               unsigned def_screen = DefaultScreen(display);
-                               if(Adapter <= def_screen)
-                                       --Adapter;
-                               *ppAdapter = GalliumDXGIAdapterCreate(this, platform, display, Adapter);
-                               return S_OK;
-                       }
-               }
+               if(platform == native_get_x11_platform())
+               {
+                       unsigned nscreens = ScreenCount((Display*)display);
+                       if(adapter < nscreens)
+                       {
+                               unsigned def_screen = DefaultScreen(display);
+                               if(adapter <= def_screen)
+                                       --adapter;
+                               *out_adapter = GalliumDXGIAdapterCreate(this, platform, display, adapter);
+                               return S_OK;
+                       }
+               }
 #endif
                return DXGI_ERROR_NOT_FOUND;
-        }
+       }
 
-        /* TODO: this is a mysterious underdocumented magic API
-         * Can we have multiple windows associated?
-         * Can we have multiple windows associated if we use multiple factories?
-         * If so, what should GetWindowAssociation return?
-         * If not, does a new swapchain steal the association?
-         * Does this act for existing swapchains? For new swapchains?
-         */
-        virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(
-               HWND WindowHandle,
-               UINT Flags)
-        {
-               /* TODO: actually implement, for Wine, X11 and KMS*/
-               associated_window = WindowHandle;
-               return S_OK;
-        }
+       /* TODO: this is a mysterious underdocumented magic API
+        * Can we have multiple windows associated?
+        * Can we have multiple windows associated if we use multiple factories?
+        * If so, what should GetWindowAssociation return?
+        * If not, does a new swapchain steal the association?
+        * Does this act for existing swapchains? For new swapchains?
+        */
+       virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(
+               HWND window_handle,
+               UINT flags)
+       {
+               /* TODO: actually implement, for Wine, X11 and KMS*/
+               associated_window = window_handle;
+               return S_OK;
+       }
 
-        virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation(
-               __out  HWND *pWindowHandle)
-        {
-               *pWindowHandle = associated_window;
-               return S_OK;
-        }
+       virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation(
+               HWND *pwindow_handle)
+       {
+               *pwindow_handle = associated_window;
+               return S_OK;
+       }
 
-        virtual HRESULT STDMETHODCALLTYPE CreateSwapChain(
-               __in  IUnknown *pDevice,
-               __in  DXGI_SWAP_CHAIN_DESC *pDesc,
-               __out  IDXGISwapChain **ppSwapChain)
-        {
-               return GalliumDXGISwapChainCreate(this, pDevice, *pDesc, ppSwapChain);
-        }
+       virtual HRESULT STDMETHODCALLTYPE CreateSwapChain(
+               IUnknown *device,
+               DXGI_SWAP_CHAIN_DESC *desc,
+               IDXGISwapChain **out_swap_chain)
+       {
+               return GalliumDXGISwapChainCreate(this, device, *desc, out_swap_chain);
+       }
 
-        virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter(
-            HMODULE Module,
-            __out  IDXGIAdapter **ppAdapter)
-        {
-               /* TODO: ignore the module, and just create a Gallium software screen */
-               *ppAdapter = 0;
-               return E_NOTIMPL;
-        }
+       virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter(
+               HMODULE module,
+               IDXGIAdapter **out_adapter)
+       {
+               /* TODO: ignore the module, and just create a Gallium software screen */
+               *out_adapter = 0;
+               return E_NOTIMPL;
+       }
 
-        /* TODO: support hotplug */
-        virtual BOOL STDMETHODCALLTYPE IsCurrent( void)
-        {
-               return TRUE;
-        }
+       /* TODO: support hotplug */
+       virtual BOOL STDMETHODCALLTYPE IsCurrent( void)
+       {
+               return TRUE;
+       }
 };
 
 struct GalliumDXGIAdapter
        : public GalliumMultiComObject<
-                 GalliumDXGIObject<IDXGIAdapter1, GalliumDXGIFactory>,
-                 IGalliumAdapter>
+                GalliumDXGIObject<IDXGIAdapter1, GalliumDXGIFactory>,
+                IGalliumAdapter>
 {
        struct native_display* display;
        const struct native_config** configs;
@@ -181,11 +256,16 @@ struct GalliumDXGIAdapter
        {
                this->parent = factory;
 
+                /* FIXME handler should be static */
                handler.invalid_surface = handle_invalid_surface;
                handler.new_drm_screen = dxgi_loader_create_drm_screen;
                handler.new_sw_screen = dxgi_loader_create_sw_screen;
-               display = platform->create_display(dpy, &handler, this);
+               platform->set_event_handler(&handler);
+
+               display = platform->create_display(dpy, FALSE, this);
                if(!display)
+                   display = platform->create_display(dpy, TRUE, this);
+                if(!display)
                        throw E_FAIL;
                memset(&desc, 0, sizeof(desc));
                std::string s = std::string("GalliumD3D on ") + display->screen->get_name(display->screen) + " by " + display->screen->get_vendor(display->screen);
@@ -239,66 +319,67 @@ struct GalliumDXGIAdapter
 
        ~GalliumDXGIAdapter()
        {
+               display->destroy(display);
                free(configs);
                free(connectors);
        }
 
-        virtual HRESULT STDMETHODCALLTYPE EnumOutputs(
-               UINT Output,
-               __out  IDXGIOutput **ppOutput)
+       virtual HRESULT STDMETHODCALLTYPE EnumOutputs(
+               UINT output,
+               IDXGIOutput **out_output)
        {
-               if(Output >= (unsigned)num_outputs)
-                       return DXGI_ERROR_NOT_FOUND;
-
-               if(connectors)
-               {
-                       std::ostringstream ss;
-                       ss << "Output #" << Output;
-                       return GalliumDXGIOutputCreate(this, ss.str(), connectors[Output], ppOutput);
-               }
-               else
-                       return GalliumDXGIOutputCreate(this, "Unique output", NULL, ppOutput);
+               if(output >= (unsigned)num_outputs)
+                       return DXGI_ERROR_NOT_FOUND;
+
+               if(connectors)
+               {
+                       std::ostringstream ss;
+                       ss << "output #" << output;
+                       return GalliumDXGIOutputCreate(this, ss.str(), connectors[output], out_output);
+               }
+               else
+                       return GalliumDXGIOutputCreate(this, "Unique output", NULL, out_output);
        }
 
-        virtual HRESULT STDMETHODCALLTYPE GetDesc(
-               __out  DXGI_ADAPTER_DESC *pDesc)
-        {
-               memcpy(pDesc, &desc, sizeof(*pDesc));
-               return S_OK;
-        }
+       virtual HRESULT STDMETHODCALLTYPE GetDesc(
+               DXGI_ADAPTER_DESC *desc)
+       {
+               memcpy(desc, &desc, sizeof(*desc));
+               return S_OK;
+       }
 
-        virtual HRESULT STDMETHODCALLTYPE GetDesc1(
-               __out  DXGI_ADAPTER_DESC1 *pDesc)
-        {
-               memcpy(pDesc, &desc, sizeof(*pDesc));
-               return S_OK;
-        }
+       virtual HRESULT STDMETHODCALLTYPE GetDesc1(
+               DXGI_ADAPTER_DESC1 *desc)
+       {
+               memcpy(desc, &desc, sizeof(*desc));
+               return S_OK;
+       }
 
-        virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport(
-            __in  REFGUID InterfaceName,
-            __out  LARGE_INTEGER *pUMDVersion)
-        {
-               // these number was taken from Windows 7 with Catalyst 10.8: its meaning is unclear
-               if(InterfaceName == IID_ID3D11Device || InterfaceName == IID_ID3D10Device1 || InterfaceName == IID_ID3D10Device)
-               {
-                       pUMDVersion->QuadPart = 0x00080011000a0411ULL;
-                       return S_OK;
-               }
-               return DXGI_ERROR_UNSUPPORTED;
-        }
+       virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport(
+               REFGUID interface_name,
+               LARGE_INTEGER *u_m_d_version)
+       {
+               // these number was taken from Windows 7 with Catalyst 10.8: its meaning is unclear
+               if(interface_name == IID_ID3D11Device || interface_name == IID_ID3D10Device1 || interface_name == IID_ID3D10Device)
+               {
+                       u_m_d_version->QuadPart = 0x00080011000a0411ULL;
+                       return S_OK;
+               }
+               return DXGI_ERROR_UNSUPPORTED;
+       }
 
-        pipe_screen* STDMETHODCALLTYPE GetGalliumScreen()
-        {
-               return display->screen;
-        }
+       pipe_screen* STDMETHODCALLTYPE GetGalliumScreen()
+       {
+               return display->screen;
+       }
 
-        pipe_screen* STDMETHODCALLTYPE GetGalliumReferenceSoftwareScreen()
-        {
-               // TODO: give a softpipe screen
-               return display->screen;
-        }
+       pipe_screen* STDMETHODCALLTYPE GetGalliumReferenceSoftwareScreen()
+       {
+               // TODO: give a softpipe screen
+               return display->screen;
+       }
 
-        pipe_screen* STDMETHODCALLTYPE GetGalliumFastSoftwareScreen()
+       pipe_screen* STDMETHODCALLTYPE GetGalliumFastSoftwareScreen()
        {
                // TODO: give an llvmpipe screen
                return display->screen;
@@ -375,37 +456,37 @@ use_fake_mode:
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetDesc(
-               __out  DXGI_OUTPUT_DESC *pDesc)
+               DXGI_OUTPUT_DESC *out_desc)
        {
-               *pDesc = desc;
+               *out_desc = desc;
                return S_OK;
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetDisplayModeList(
-               DXGI_FORMAT EnumFormat,
-               UINT Flags,
-               __inout  UINT *pNumModes,
-               __out_ecount_part_opt(*pNumModes,*pNumModes)  DXGI_MODE_DESC *pDesc)
+               DXGI_FORMAT enum_format,
+               UINT flags,
+               UINT *pcount,
+               DXGI_MODE_DESC *desc)
        {
                /* TODO: should we return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE when we don't
                 * support modesetting instead of fake modes?
                 */
-               pipe_format format = dxgi_to_pipe_format[EnumFormat];
+               pipe_format format = dxgi_to_pipe_format[enum_format];
                if(parent->configs_by_pipe_format.count(format))
                {
-                       if(!pDesc)
+                       if(!desc)
                        {
-                               *pNumModes = num_modes;
+                               *pcount = num_modes;
                                return S_OK;
                        }
 
-                       unsigned copy_modes = std::min(num_modes, *pNumModes);
+                       unsigned copy_modes = std::min(num_modes, *pcount);
                        for(unsigned i = 0; i < copy_modes; ++i)
                        {
-                               pDesc[i] = dxgi_modes[i];
-                               pDesc[i].Format = EnumFormat;
+                               desc[i] = dxgi_modes[i];
+                               desc[i].Format = enum_format;
                        }
-                       *pNumModes = num_modes;
+                       *pcount = num_modes;
 
                        if(copy_modes < num_modes)
                                return DXGI_ERROR_MORE_DATA;
@@ -414,15 +495,15 @@ use_fake_mode:
                }
                else
                {
-                       *pNumModes = 0;
+                       *pcount = 0;
                        return S_OK;
                }
        }
 
        virtual HRESULT STDMETHODCALLTYPE FindClosestMatchingMode(
-               __in  const DXGI_MODE_DESC *pModeToMatch,
-               __out  DXGI_MODE_DESC *pClosestMatch,
-               __in_opt  IUnknown *pConcernedDevice)
+               const DXGI_MODE_DESC *pModeToMatch,
+               DXGI_MODE_DESC *closest_match,
+               IUnknown *concerned_device)
        {
                /* TODO: actually implement this */
                DXGI_FORMAT dxgi_format = pModeToMatch->Format;
@@ -430,7 +511,7 @@ use_fake_mode:
                init_pipe_to_dxgi_format();
                if(!parent->configs_by_pipe_format.count(format))
                {
-                       if(!pConcernedDevice)
+                       if(!concerned_device)
                                return E_FAIL;
                        else
                        {
@@ -439,8 +520,8 @@ use_fake_mode:
                        }
                }
 
-               *pClosestMatch = dxgi_modes[0];
-               pClosestMatch->Format = dxgi_format;
+               *closest_match = dxgi_modes[0];
+               closest_match->Format = dxgi_format;
                return S_OK;
        }
 
@@ -450,8 +531,8 @@ use_fake_mode:
        }
 
        virtual HRESULT STDMETHODCALLTYPE TakeOwnership(
-               __in  IUnknown *pDevice,
-               BOOL Exclusive)
+               IUnknown *device,
+               BOOL exclusive)
        {
                return S_OK;
        }
@@ -461,14 +542,14 @@ use_fake_mode:
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetGammaControlCapabilities(
-               __out  DXGI_GAMMA_CONTROL_CAPABILITIES *pGammaCaps)
+               DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps)
        {
-               memset(pGammaCaps, 0, sizeof(*pGammaCaps));
+               memset(gamma_caps, 0, sizeof(*gamma_caps));
                return S_OK;
        }
 
        virtual HRESULT STDMETHODCALLTYPE SetGammaControl(
-                       __in  const DXGI_GAMMA_CONTROL *pArray)
+                       const DXGI_GAMMA_CONTROL *pArray)
        {
                if(!gamma)
                        gamma = new DXGI_GAMMA_CONTROL;
@@ -477,7 +558,7 @@ use_fake_mode:
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetGammaControl(
-                       __out  DXGI_GAMMA_CONTROL *pArray)
+                       DXGI_GAMMA_CONTROL *pArray)
        {
                if(gamma)
                        *pArray = *gamma;
@@ -496,23 +577,23 @@ use_fake_mode:
        }
 
        virtual HRESULT STDMETHODCALLTYPE SetDisplaySurface(
-               __in  IDXGISurface *pScanoutSurface)
+               IDXGISurface *scanout_surface)
        {
                return E_NOTIMPL;
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetDisplaySurfaceData(
-               __in  IDXGISurface *pDestination)
+               IDXGISurface *destination)
        {
                return E_NOTIMPL;
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(
-               __out  DXGI_FRAME_STATISTICS *pStats)
+               DXGI_FRAME_STATISTICS *stats)
        {
-               memset(pStats, 0, sizeof(*pStats));
+               memset(stats, 0, sizeof(*stats));
 #ifdef _WIN32
-               QueryPerformanceCounter(&pStats->SyncQPCTime);
+               QueryPerformanceCounter(&stats->SyncQPCTime);
 #endif
                return E_NOTIMPL;
        }
@@ -535,19 +616,19 @@ use_fake_mode:
  * surface and the contents become undefined.
  * D3D may internally use multiple buffers, but you can't observe this, except
  * by looking at the buffer contents after Present (but those are undefined).
- * If it uses multiple buffers internally, then it will normally use BufferCount buffers
+ * If it uses multiple buffers internally, then it will normally use buffer_count buffers
  * (this has latency implications).
  * Discard mode seems to internally use a single buffer in windowed mode,
- * even if DWM is enabled, and BufferCount buffers in fullscreen mode.
+ * even if DWM is enabled, and buffer_count buffers in fullscreen mode.
  *
- * In sequential mode, the runtime alllocates BufferCount buffers.
+ * In sequential mode, the runtime alllocates buffer_count buffers.
  * You can get each with GetBuffers(n).
  * GetBuffers(0) ALWAYS points to the backbuffer to be presented and has the
  * same usage constraints as the discard mode.
  * GetBuffer(n) with n > 0 points to resources that are identical to buffer 0, but
  * are classified as "read-only resources" (due to DXGI_USAGE_READ_ONLY),
  * meaning that you can't create render target views on them, or use them as
- * a CopyResource/CopySubresourceRegion  destination.
+ * a CopyResource/CopySubresourceRegion destination.
  * It appears the only valid operation is to use them as a source for CopyResource
  * and CopySubresourceRegion as well as just waiting for them to become
  * buffer 0 again.
@@ -588,17 +669,17 @@ use_fake_mode:
  *
  * There are three strategies:
  * 1. Use a single buffer, and always copy it to a window system provided buffer, or
- *    just give the buffer to the window system if it supports that
+ *     just give the buffer to the window system if it supports that
  * 2. Rotate the buffers in the D3D1x implementation, and recreate and rebind the views.
- *     Don't support driver-provided command lists
+ *      Don't support driver-provided command lists
  * 3. Add this rotation functionality to the Gallium driver, with the idea that it would rotate
- *    remap GPU virtual memory, so that virtual address are unchanged, but the physical
- *    ones are rotated (so that pushbuffers remain valid).
- *    If the driver does not support this, either fall back to (1), or have a layer doing this,
- *    putting a deferred context layer over this intermediate layer.
+ *     remap GPU virtual memory, so that virtual address are unchanged, but the physical
+ *     ones are rotated (so that pushbuffers remain valid).
+ *     If the driver does not support this, either fall back to (1), or have a layer doing this,
+ *     putting a deferred context layer over this intermediate layer.
  *
  * (2) is not acceptable since it prevents an optimal implementation.
- *  (3) is the ideal solution, but it is complicated.
+ * (3) is the ideal solution, but it is complicated.
  *
  * Hence, we implement (1) for now, and will switch to (3) later.
  *
@@ -614,11 +695,11 @@ use_fake_mode:
  * I was unable to find any code using it either in DirectX SDK examples, or on the web.
  *
  * It seems the only reason you would use it is to not have to redraw from scratch, while
- * also possibly avoid a copy compared to BufferCount == 1, assuming that your
+ * also possibly avoid a copy compared to buffer_count == 1, assuming that your
  * application is OK with having to redraw starting not from the last frame, but from
  * one/two/more frames behind it.
  *
- * A better design would forbid the user specifying BufferCount explicitly, and
+ * A better design would forbid the user specifying buffer_count explicitly, and
  * would instead let the application give an upper bound on how old the buffer can
  * become after presentation, with "infinite" being equivalent to discard.
  * The runtime would then tell the application with frame number the buffer switched to
@@ -677,6 +758,7 @@ struct dxgi_blitter
                rasterizer = pipe->create_rasterizer_state(pipe, &rs_state);
 
                struct pipe_blend_state blendd;
+               memset(&blendd, 0, sizeof(blendd));
                blendd.rt[0].colormask = PIPE_MASK_RGBA;
                blend = pipe->create_blend_state(pipe, &blendd);
 
@@ -712,9 +794,9 @@ struct dxgi_blitter
                const unsigned semantic_indices[] = { 0, 0 };
                vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, semantic_indices);
 
-               vbuf.buffer = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER, sizeof(quad_data));
+               vbuf.buffer = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER,
+                                                PIPE_USAGE_STREAM, sizeof(quad_data));
                vbuf.buffer_offset = 0;
-               vbuf.max_index = ~0;
                vbuf.stride = 4 * sizeof(float);
                pipe_buffer_write(pipe, vbuf.buffer, 0, sizeof(quad_data), quad_data);
 
@@ -792,9 +874,12 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
        ComPtr<GalliumDXGIAdapter> adapter;
        ComPtr<IDXGIOutput> target;
 
+       DXGI_SWAP_CHAIN_DESC desc;
+
        struct native_surface* surface;
        const struct native_config* config;
 
+       void* window;
        struct pipe_resource* resources[NUM_NATIVE_ATTACHMENTS];
        int width;
        int height;
@@ -807,8 +892,6 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
        struct pipe_resource* gallium_buffer0;
        struct pipe_sampler_view* gallium_buffer0_view;
 
-       DXGI_SWAP_CHAIN_DESC desc;
-
        struct pipe_context* pipe;
        bool owns_pipe;
 
@@ -818,7 +901,7 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
        bool formats_compatible;
 
        GalliumDXGISwapChain(GalliumDXGIFactory* factory, IUnknown* p_device, const DXGI_SWAP_CHAIN_DESC& p_desc)
-       : GalliumDXGIObject<IDXGISwapChain, GalliumDXGIFactory>(factory), desc(p_desc)
+       : GalliumDXGIObject<IDXGISwapChain, GalliumDXGIFactory>(factory), desc(p_desc), surface(0)
        {
                HRESULT hr;
 
@@ -834,13 +917,45 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
                if(!SUCCEEDED(hr))
                        throw hr;
 
-               void* win = factory->resolver(factory->resolver_cookie, desc.OutputWindow);
+               memset(resources, 0, sizeof(resources));
+
+               if(desc.SwapEffect == DXGI_SWAP_EFFECT_SEQUENTIAL && desc.BufferCount != 1)
+               {
+                       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;
+                       // change the returned desc, so that the application might perhaps notice what we did and react well
+                       desc.BufferCount = 1;
+               }
+
+               pipe = gallium_device->GetGalliumContext();
+               owns_pipe = false;
+               if(!pipe)
+               {
+                       pipe = adapter->display->screen->context_create(adapter->display->screen, 0);
+                       owns_pipe = true;
+               }
+
+               blitter.reset(new dxgi_blitter(pipe));
+               window = 0;
+
+               hr = resolve_zero_width_height(true);
+               if(!SUCCEEDED(hr))
+                       throw hr;
+       }
+
+       void init_for_window()
+       {
+               if(surface)
+               {
+                       surface->destroy(surface);
+                       surface = 0;
+               }
 
                unsigned config_num;
-               if(!strcmp(factory->platform->name, "X11"))
+               if(!strcmp(parent->platform->name, "X11"))
                {
                        XWindowAttributes xwa;
-                       XGetWindowAttributes((Display*)factory->display, (Window)win, &xwa);
+                       XGetWindowAttributes((Display*)parent->display, (Window)window, &xwa);
+                       assert(adapter->configs_by_native_visual_id.count(xwa.visual->visualid));
                        config_num = adapter->configs_by_native_visual_id[xwa.visual->visualid];
                }
                else
@@ -858,7 +973,7 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
                }
 
                config = adapter->configs[config_num];
-               surface = adapter->display->create_window_surface(adapter->display, (EGLNativeWindowType)win, config);
+               surface = adapter->display->create_window_surface(adapter->display, (EGLNativeWindowType)window, config);
                surface->user_data = this;
 
                width = 0;
@@ -868,23 +983,6 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
                needs_validation = true;
                ever_validated = false;
 
-               if(desc.SwapEffect == DXGI_SWAP_EFFECT_SEQUENTIAL && desc.BufferCount != 1)
-               {
-                       std::cerr << "Gallium DXGI: if DXGI_SWAP_EFFECT_SEQUENTIAL is specified, only BufferCount == 1 is implemented, but " << desc.BufferCount  << " was specified: ignoring this" << std::endl;
-                       // change the returned desc, so that the application might perhaps notice what we did and react well
-                       desc.BufferCount = 1;
-               }
-
-               pipe = gallium_device->GetGalliumContext();
-               owns_pipe = false;
-               if(!pipe)
-               {
-                       pipe = adapter->display->screen->context_create(adapter->display->screen, 0);
-                       owns_pipe = true;
-               }
-
-               blitter.reset(new dxgi_blitter(pipe));
-
                formats_compatible = util_is_format_compatible(
                                util_format_description(dxgi_to_pipe_format[desc.BufferDesc.Format]),
                                util_format_description(config->color_format));
@@ -896,16 +994,16 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
                        pipe->destroy(pipe);
        }
 
-        virtual HRESULT STDMETHODCALLTYPE GetDevice(
-            __in  REFIID riid,
-            __out  void **ppDevice)
-        {
-               return dxgi_device->QueryInterface(riid, ppDevice);
-        }
+       virtual HRESULT STDMETHODCALLTYPE GetDevice(
+               REFIID riid,
+               void **pdevice)
+       {
+               return dxgi_device->QueryInterface(riid, pdevice);
+       }
 
-        HRESULT create_buffer0()
-        {
-               HRESULT hr;
+       HRESULT create_buffer0()
+       {
+               HRESULT hr;
                ComPtr<IDXGISurface> new_buffer0;
                DXGI_USAGE usage = DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT;
                if(desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD)
@@ -943,14 +1041,14 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
                templat.format = gallium_buffer0->format;
                gallium_buffer0_view = pipe->create_sampler_view(pipe, gallium_buffer0, &templat);
                return S_OK;
-        }
+       }
 
        bool validate()
        {
                unsigned new_seq_num;
                needs_validation = false;
 
-               if(!surface->validate(surface, 1 << NATIVE_ATTACHMENT_BACK_LEFT, &new_seq_num, resources, &width, &height))
+               if(!surface->validate(surface, (1 << NATIVE_ATTACHMENT_BACK_LEFT) | (1 << NATIVE_ATTACHMENT_FRONT_LEFT), &new_seq_num, resources, &width, &height))
                        return false;
 
                if(!ever_validated || seq_num != new_seq_num)
@@ -961,13 +1059,37 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
                return true;
        }
 
-       virtual HRESULT STDMETHODCALLTYPE Present(
-               UINT SyncInterval,
-               UINT Flags)
+       HRESULT resolve_zero_width_height(bool force = false)
        {
-               if(Flags & DXGI_PRESENT_TEST)
+               if(!force && desc.BufferDesc.Width && desc.BufferDesc.Height)
                        return S_OK;
 
+               unsigned width, height;
+               HRESULT hr = parent->backend->GetPresentSize(desc.OutputWindow, &width, &height);
+               if(!SUCCEEDED(hr))
+                       return hr;
+
+               // On Windows, 8 is used, and a debug message saying so gets printed
+               if(!width)
+                       width = 8;
+               if(!height)
+                       height = 8;
+
+               if(!desc.BufferDesc.Width)
+                       desc.BufferDesc.Width = width;
+               if(!desc.BufferDesc.Height)
+                       desc.BufferDesc.Height = height;
+               return S_OK;
+       }
+
+       virtual HRESULT STDMETHODCALLTYPE Present(
+               UINT sync_interval,
+               UINT flags)
+       {
+               HRESULT hr;
+               if(flags & DXGI_PRESENT_TEST)
+                       return parent->backend->TestPresent(desc.OutputWindow);
+
                if(!buffer0)
                {
                        HRESULT hr = create_buffer0();
@@ -975,16 +1097,44 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
                                return hr;
                }
 
+               void* cur_window = 0;
+               RECT rect;
+               RGNDATA* rgndata;
+               BOOL preserve_aspect_ratio;
+               unsigned dst_w, dst_h;
+               bool db;
+               struct pipe_resource* dst;
+               struct pipe_resource* src;
+               struct pipe_surface* dst_surface;
+               enum native_attachment att;
+
+               void* present_cookie;
+               hr = parent->backend->BeginPresent(desc.OutputWindow, &present_cookie, &cur_window, &rect, &rgndata, &preserve_aspect_ratio);
+               if(hr != S_OK)
+                       return hr;
+
+               if(!cur_window || rect.left >= rect.right || rect.top >= rect.bottom)
+                       goto end_present;
+
+               if(cur_window != window)
+               {
+                       window = cur_window;
+                       init_for_window();
+               }
+
                if(needs_validation)
                {
                        if(!validate())
                                return DXGI_ERROR_DEVICE_REMOVED;
                }
 
-               bool db = !!(config->buffer_mask & NATIVE_ATTACHMENT_BACK_LEFT);
-               struct pipe_resource* dst = resources[db ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT];
-               struct pipe_resource* src = gallium_buffer0;
-               struct pipe_surface* dst_surface = 0;
+               db = !!(config->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT));
+               dst = resources[db ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT];
+               src = gallium_buffer0;
+               dst_surface = 0;
+
+               assert(src);
+               assert(dst);
 
                /* TODO: sharing the context for blitting won't work correctly if queries are active
                 * Hopefully no one is crazy enough to keep queries active while presenting, expecting
@@ -992,81 +1142,115 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
                 * We could alternatively force using another context, but that might cause inefficiency issues
                 */
 
-               /* Windows DXGI does not scale in an aspect-preserving way, but we do this
-                * by default, since we can and it's usually what you want
-                */
-               unsigned blit_x, blit_y, blit_w, blit_h;
-               float black[4] = {0, 0, 0, 0};
+               if((unsigned)rect.right > dst->width0)
+                       rect.right = dst->width0;
+               if((unsigned)rect.bottom > dst->height0)
+                       rect.bottom = dst->height0;
+               if(rect.left > rect.right)
+                       rect.left = rect.right;
+               if(rect.top > rect.bottom)
+                       rect.top = rect.bottom;
 
-               if(!formats_compatible || src->width0 != dst->width0 || dst->width0 != src->width0)
-                       dst_surface = pipe->screen->get_tex_surface(pipe->screen, dst, 0, 0, 0, PIPE_BIND_RENDER_TARGET);
+               if(rect.left >= rect.right && rect.top >= rect.bottom)
+                       goto end_present;
 
-               int delta = src->width0 * dst->height0 - dst->width0 * src->height0;
-               if(delta > 0)
-               {
-                       blit_w = dst->width0;
-                       blit_h = dst->width0 * src->height0 / src->width0;
-               }
-               else if(delta < 0)
-               {
-                       blit_w = dst->height0 * src->width0 / src->height0;
-                       blit_h = dst->height0;
-               }
-               else
+               dst_w = rect.right - rect.left;
+               dst_h = rect.bottom - rect.top;
+
+               // TODO: add support for rgndata
+//             if(preserve_aspect_ratio || !rgndata)
+               if(1)
                {
-                       blit_w = dst->width0;
-                       blit_h = dst->height0;
-               }
+                       unsigned blit_x, blit_y, blit_w, blit_h;
+                       float black[4] = {0, 0, 0, 0};
+
+                       if(!formats_compatible || src->width0 != dst_w || src->height0 != dst_h) {
+                               struct pipe_surface templat;
+                               templat.usage = PIPE_BIND_RENDER_TARGET;
+                               templat.format = dst->format;
+                               templat.u.tex.level = 0;
+                               templat.u.tex.first_layer = 0;
+                               templat.u.tex.last_layer = 0;
+                               dst_surface = pipe->create_surface(pipe, dst, &templat);
+                       }
 
-               blit_x = (dst->width0 - blit_w) >> 1;
-               blit_y = (dst->height0 - blit_h) >> 1;
+                       if(preserve_aspect_ratio)
+                       {
+                               int delta = src->width0 * dst_h - dst_w * src->height0;
+                               if(delta > 0)
+                               {
+                                       blit_w = dst_w;
+                                       blit_h = dst_w * src->height0 / src->width0;
+                               }
+                               else if(delta < 0)
+                               {
+                                       blit_w = dst_h * src->width0 / src->height0;
+                                       blit_h = dst_h;
+                               }
+                               else
+                               {
+                                       blit_w = dst_w;
+                                       blit_h = dst_h;
+                               }
 
-               if(blit_x)
-                       pipe->clear_render_target(pipe, dst_surface, black, 0, 0, blit_x, dst->height0);
-               if(blit_y)
-                       pipe->clear_render_target(pipe, dst_surface, black, 0, 0, dst->width0, blit_y);
+                               blit_x = (dst_w - blit_w) >> 1;
+                               blit_y = (dst_h - blit_h) >> 1;
+                       }
+                       else
+                       {
+                               blit_x = 0;
+                               blit_y = 0;
+                               blit_w = dst_w;
+                               blit_h = dst_h;
+                       }
 
-               if(formats_compatible && blit_w == src->width0 && blit_h == src->height0)
-               {
-                       pipe_subresource sr;
-                       sr.face = 0;
-                       sr.level = 0;
-                       pipe->resource_copy_region(pipe, dst, sr, 0, 0, 0, src, sr, 0, 0, 0, blit_w, blit_h);
-               }
-               else
-               {
-                       blitter->blit(dst_surface, gallium_buffer0_view, blit_x, blit_y, blit_w, blit_h);
-                       if(!owns_pipe)
-                               gallium_device->RestoreGalliumState();
-               }
+                       if(blit_x)
+                               pipe->clear_render_target(pipe, dst_surface, black, rect.left, rect.top, blit_x, dst_h);
+                       if(blit_y)
+                               pipe->clear_render_target(pipe, dst_surface, black, rect.left, rect.top, dst_w, blit_y);
 
-               if(blit_w != dst->width0)
-                       pipe->clear_render_target(pipe, dst_surface, black, blit_x + blit_w, 0, dst->width0 - blit_x - blit_w, dst->height0);
-               if(blit_h != dst->height0)
-                       pipe->clear_render_target(pipe, dst_surface, black, 0, blit_y + blit_h, dst->width0, dst->height0 - blit_y - blit_h);
+                       if(formats_compatible && blit_w == src->width0 && blit_h == src->height0)
+                       {
+                               pipe_box box;
+                               box.x = box.y = box.z;
+                               box.width = blit_w;
+                               box.height = blit_h;
+                               box.z = 1;
+                               pipe->resource_copy_region(pipe, dst, 0, rect.left, rect.top, 0, src, 0, &box);
+                       }
+                       else
+                       {
+                               blitter->blit(dst_surface, gallium_buffer0_view, rect.left + blit_x, rect.top + blit_y, blit_w, blit_h);
+                               if(!owns_pipe)
+                                       gallium_device->RestoreGalliumState();
+                       }
+
+                       if(blit_w != dst_w)
+                               pipe->clear_render_target(pipe, dst_surface, black, rect.left + blit_x + blit_w, rect.top, dst_w - blit_x - blit_w, dst_h);
+                       if(blit_h != dst_h)
+                               pipe->clear_render_target(pipe, dst_surface, black, rect.left, rect.top + blit_y + blit_h, dst_w, dst_h - blit_y - blit_h);
+               }
 
                if(dst_surface)
-                       pipe->screen->tex_surface_destroy(dst_surface);
+                       pipe->surface_destroy(pipe, dst_surface);
 
-               if(db)
-               {
-                       if(!surface->swap_buffers(surface))
-                               return DXGI_ERROR_DEVICE_REMOVED;
-               }
-               else
-               {
-                       if(!surface->flush_frontbuffer(surface))
-                               return DXGI_ERROR_DEVICE_REMOVED;
-               }
+               pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, 0);
+
+               att = (db) ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT;
+               if(!surface->present(surface, att, FALSE, 0))
+                       return DXGI_ERROR_DEVICE_REMOVED;
+
+end_present:
+               parent->backend->EndPresent(desc.OutputWindow, present_cookie);
 
                ++present_count;
                return S_OK;
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetBuffer(
-                   UINT Buffer,
-                   __in  REFIID riid,
-                   __out  void **ppSurface)
+                       UINT Buffer,
+                       REFIID riid,
+                       void **ppSurface)
        {
                if(Buffer > 0)
                {
@@ -1087,38 +1271,38 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
 
        /* TODO: implement somehow */
        virtual HRESULT STDMETHODCALLTYPE SetFullscreenState(
-               BOOL Fullscreen,
-               __in_opt  IDXGIOutput *pTarget)
+               BOOL fullscreen,
+               IDXGIOutput *target)
        {
-               fullscreen = Fullscreen;
-               target = pTarget;
+               fullscreen = fullscreen;
+               target = target;
                return S_OK;
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetFullscreenState(
-               __out  BOOL *pFullscreen,
-               __out  IDXGIOutput **ppTarget)
+               BOOL *out_fullscreen,
+               IDXGIOutput **out_target)
        {
-               if(pFullscreen)
-                       *pFullscreen = fullscreen;
-               if(ppTarget)
-                       *ppTarget = target.ref();
+               if(out_fullscreen)
+                       *out_fullscreen = fullscreen;
+               if(out_target)
+                       *out_target = target.ref();
                return S_OK;
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetDesc(
-               __out  DXGI_SWAP_CHAIN_DESC *pDesc)
+               DXGI_SWAP_CHAIN_DESC *out_desc)
        {
-               *pDesc = desc;
+               *out_desc = desc;
                return S_OK;
        }
 
        virtual HRESULT STDMETHODCALLTYPE ResizeBuffers(
-               UINT BufferCount,
-               UINT Width,
-               UINT Height,
-               DXGI_FORMAT NewFormat,
-               UINT SwapChainFlags)
+               UINT buffer_count,
+               UINT width,
+               UINT height,
+               DXGI_FORMAT new_format,
+               UINT swap_chain_flags)
        {
                if(buffer0)
                {
@@ -1133,45 +1317,45 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
                }
 
                if(desc.SwapEffect != DXGI_SWAP_EFFECT_SEQUENTIAL)
-                       desc.BufferCount = BufferCount;
-               desc.BufferDesc.Format = NewFormat;
-               desc.BufferDesc.Width = Width;
-               desc.BufferDesc.Height = Height;
-               desc.Flags = SwapChainFlags;
-               return S_OK;
+                       desc.BufferCount = buffer_count;
+               desc.BufferDesc.Format = new_format;
+               desc.BufferDesc.Width = width;
+               desc.BufferDesc.Height = height;
+               desc.Flags = swap_chain_flags;
+               return resolve_zero_width_height();
        }
 
        virtual HRESULT STDMETHODCALLTYPE ResizeTarget(
-               const DXGI_MODE_DESC *pNewTargetParameters)
+               const DXGI_MODE_DESC *out_new_target_parameters)
        {
                /* TODO: implement */
                return S_OK;
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetContainingOutput(
-                       __out  IDXGIOutput **ppOutput)
+               IDXGIOutput **out_output)
        {
-               *ppOutput = adapter->outputs[0].ref();
+               *out_output = adapter->outputs[0].ref();
                return S_OK;
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(
-                       __out  DXGI_FRAME_STATISTICS *pStats)
+               DXGI_FRAME_STATISTICS *out_stats)
        {
-               memset(pStats, 0, sizeof(*pStats));
+               memset(out_stats, 0, sizeof(*out_stats));
 #ifdef _WIN32
-               QueryPerformanceCounter(&pStats->SyncQPCTime);
+               QueryPerformanceCounter(&out_stats->SyncQPCTime);
 #endif
-               pStats->PresentCount = present_count;
-               pStats->PresentRefreshCount = present_count;
-               pStats->SyncRefreshCount = present_count;
+               out_stats->PresentCount = present_count;
+               out_stats->PresentRefreshCount = present_count;
+               out_stats->SyncRefreshCount = present_count;
                return S_OK;
        }
 
        virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount(
-               __out  UINT *pLastPresentCount)
+               UINT *last_present_count)
        {
-               *pLastPresentCount = present_count;
+               *last_present_count = present_count;
                return S_OK;
        }
 };
@@ -1181,11 +1365,11 @@ static void GalliumDXGISwapChainRevalidate(IDXGISwapChain* swap_chain)
        ((GalliumDXGISwapChain*)swap_chain)->needs_validation = true;
 }
 
-static HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy, IDXGIAdapter1** pAdapter)
+static HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy, IDXGIAdapter1** out_adapter)
 {
        try
        {
-               *pAdapter = new GalliumDXGIAdapter(factory, platform, dpy);
+               *out_adapter = new GalliumDXGIAdapter(factory, platform, dpy);
                return S_OK;
        }
        catch(HRESULT hr)
@@ -1194,11 +1378,11 @@ static HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* factory, const struc
        }
 }
 
-static HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** pOutput)
+static HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** out_output)
 {
        try
        {
-               *pOutput = new GalliumDXGIOutput(adapter, name, connector);
+               *out_output = new GalliumDXGIOutput(adapter, name, connector);
                return S_OK;
        }
        catch(HRESULT hr)
@@ -1207,11 +1391,11 @@ static HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::s
        }
 }
 
-static HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** pSwapChain)
+static HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** out_swap_chain)
 {
        try
        {
-               *pSwapChain = new GalliumDXGISwapChain(factory, device, desc);
+               *out_swap_chain = new GalliumDXGISwapChain(factory, device, desc);
                return S_OK;
        }
        catch(HRESULT hr)
@@ -1224,8 +1408,7 @@ struct dxgi_binding
 {
        const struct native_platform* platform;
        void* display;
-       PFNHWNDRESOLVER resolver;
-       void* resolver_cookie;
+       IGalliumDXGIBackend* backend;
 };
 
 static dxgi_binding dxgi_default_binding;
@@ -1235,80 +1418,91 @@ void STDMETHODCALLTYPE GalliumDXGIUseNothing()
 {
        dxgi_thread_binding.platform = 0;
        dxgi_thread_binding.display = 0;
-       dxgi_thread_binding.resolver = 0;
-       dxgi_thread_binding.resolver_cookie = 0;
+       if(dxgi_thread_binding.backend)
+               dxgi_thread_binding.backend->Release();
+       dxgi_thread_binding.backend = 0;
 }
 
 #ifdef GALLIUM_DXGI_USE_X11
-void STDMETHODCALLTYPE GalliumDXGIUseX11Display(Display* dpy, PFNHWNDRESOLVER resolver, void* resolver_cookie)
+void STDMETHODCALLTYPE GalliumDXGIUseX11Display(Display* dpy, IGalliumDXGIBackend* backend)
 {
+       GalliumDXGIUseNothing();
        dxgi_thread_binding.platform = native_get_x11_platform();
        dxgi_thread_binding.display = dpy;
-       dxgi_thread_binding.resolver = resolver;
-       dxgi_thread_binding.resolver_cookie = resolver_cookie;
+
+       if(backend)
+       {
+               dxgi_thread_binding.backend = backend;
+               backend->AddRef();
+       }
 }
 #endif
 
+/*
 #ifdef GALLIUM_DXGI_USE_DRM
 void STDMETHODCALLTYPE GalliumDXGIUseDRMCard(int fd)
 {
+       GalliumDXGIUseNothing();
        dxgi_thread_binding.platform = native_get_drm_platform();
        dxgi_thread_binding.display = (void*)fd;
-       dxgi_thread_binding.resolver = 0;
-       dxgi_thread_binding.resolver_cookie = 0;
+       dxgi_thread_binding.backend = 0;
 }
 #endif
 
 #ifdef GALLIUM_DXGI_USE_FBDEV
 void STDMETHODCALLTYPE GalliumDXGIUseFBDev(int fd)
 {
+       GalliumDXGIUseNothing();
        dxgi_thread_binding.platform = native_get_fbdev_platform();
        dxgi_thread_binding.display = (void*)fd;
-       dxgi_thread_binding.resolver = 0;
-       dxgi_thread_binding.resolver_cookie = 0;
+       dxgi_thread_binding.backend = 0;
 }
 #endif
 
 #ifdef GALLIUM_DXGI_USE_GDI
 void STDMETHODCALLTYPE GalliumDXGIUseHDC(HDC hdc, PFNHWNDRESOLVER resolver, void* resolver_cookie)
 {
+       GalliumDXGIUseNothing();
        dxgi_thread_binding.platform = native_get_gdi_platform();
        dxgi_thread_binding.display = (void*)hdc;
-       dxgi_thread_binding.resolver = resolver;
-       dxgi_thread_binding.resolver_cookie = resolver_cookie;
+       dxgi_thread_binding.backend = 0;
 }
 #endif
-
+*/
 void STDMETHODCALLTYPE GalliumDXGIMakeDefault()
 {
+       if(dxgi_default_binding.backend)
+               dxgi_default_binding.backend->Release();
        dxgi_default_binding = dxgi_thread_binding;
+       if(dxgi_default_binding.backend)
+               dxgi_default_binding.backend->AddRef();
 }
 
  /* TODO: why did Microsoft add this? should we do something different for DXGI 1.0 and 1.1?
 * Or perhaps what they actually mean is "only create a single factory in your application"?
 * TODO: should we use a singleton here, so we never have multiple DXGI objects for the same thing? */
- HRESULT STDMETHODCALLTYPE  CreateDXGIFactory1(
-               __in   REFIID riid,
-               __out  void **ppFactory
+ * Or perhaps what they actually mean is "only create a single factory in your application"?
+ * TODO: should we use a singleton here, so we never have multiple DXGI objects for the same thing? */
+ HRESULT STDMETHODCALLTYPE CreateDXGIFactory1(
+               REFIID riid,
+               void **out_factory
 )
  {
         GalliumDXGIFactory* factory;
-        *ppFactory = 0;
+        *out_factory = 0;
         if(dxgi_thread_binding.platform)
-                factory = new GalliumDXGIFactory(dxgi_thread_binding.platform, dxgi_thread_binding.display, dxgi_thread_binding.resolver, dxgi_thread_binding.resolver_cookie);
+                factory = new GalliumDXGIFactory(dxgi_thread_binding.platform, dxgi_thread_binding.display, dxgi_thread_binding.backend);
         else if(dxgi_default_binding.platform)
-                factory = new GalliumDXGIFactory(dxgi_default_binding.platform, dxgi_default_binding.display, dxgi_default_binding.resolver, dxgi_default_binding.resolver_cookie);
+                factory = new GalliumDXGIFactory(dxgi_default_binding.platform, dxgi_default_binding.display, dxgi_default_binding.backend);
         else
-                factory = new GalliumDXGIFactory(native_get_x11_platform(), NULL, NULL, NULL);
-        HRESULT hres = factory->QueryInterface(riid, ppFactory);
+                factory = new GalliumDXGIFactory(native_get_x11_platform(), NULL, NULL);
+        HRESULT hres = factory->QueryInterface(riid, out_factory);
         factory->Release();
         return hres;
  }
 
- HRESULT STDMETHODCALLTYPE  CreateDXGIFactory(
-                __in   REFIID riid,
-                __out  void **ppFactory
+ HRESULT STDMETHODCALLTYPE CreateDXGIFactory(
+                REFIID riid,
+                void **out_factor
 )
  {
-        return CreateDXGIFactory1(riid, ppFactory);
+        return CreateDXGIFactory1(riid, out_factor);
  }