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