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