1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/************************************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2010 Luca Barbieri 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a copy of this software and associated documentation files (the 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sublicense, and/or sell copies of the Software, and to 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * portions of the Software. 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/ 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "dxgi_private.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" { 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "native.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_simple_shaders.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_shader_tokens.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <iostream> 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <memory> 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumDXGIOutput; 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumDXGIAdapter; 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumDXGISwapChain; 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumDXGIFactory; 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** out_swap_chain); 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* adapter, const struct native_platform* platform, void* dpy, IDXGIAdapter1** out_adapter); 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** out_output); 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void GalliumDXGISwapChainRevalidate(IDXGISwapChain* swap_chain); 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<typename Base = IDXGIObject, typename Parent = IDXGIObject> 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumDXGIObject : public GalliumPrivateDataComObject<Base> 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ComPtr<Parent> parent; 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIObject(Parent* p_parent = 0) 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->parent = p_parent; 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetParent( 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org REFIID riid, 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void **out_parent) 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return parent->QueryInterface(riid, out_parent); 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCOM_INTERFACE(IGalliumDXGIBackend, IUnknown) 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// TODO: somehow check whether the window is fully obscured or not 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumDXGIIdentityBackend : public GalliumComObject<IGalliumDXGIBackend> 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE BeginPresent( 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HWND hwnd, 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void** present_cookie, 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void** window, 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RECT *rect, 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RGNDATA **rgndata, 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BOOL* preserve_aspect_ratio 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *window = (void*)hwnd; 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rect->left = 0; 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rect->top = 0; 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rect->right = INT_MAX; 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rect->bottom = INT_MAX; 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *rgndata = 0; 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // yes, because we like things looking good 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *preserve_aspect_ratio = TRUE; 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *present_cookie = 0; 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void STDMETHODCALLTYPE EndPresent( 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HWND hwnd, 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* present_cookie 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {} 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE TestPresent(HWND hwnd) 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetPresentSize( 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HWND hwnd, 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned* width, 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned* height 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *width = 0; 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *height = 0; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// TODO: maybe install an X11 error hook, so we can return errors properly 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumDXGIX11IdentityBackend : public GalliumDXGIIdentityBackend 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Display* dpy; 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIX11IdentityBackend(Display* dpy) 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : dpy(dpy) 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {} 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetPresentSize( 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HWND hwnd, 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned* width, 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned* height 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org XWindowAttributes xwa; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org XGetWindowAttributes(dpy, (Window)hwnd, &xwa); 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *width = xwa.width; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *height = xwa.height; 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumDXGIFactory : public GalliumDXGIObject<IDXGIFactory1, IUnknown> 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HWND associated_window; 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct native_platform* platform; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* display; 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ComPtr<IGalliumDXGIBackend> backend; 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* resolver_cookie; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIFactory(const struct native_platform* platform, void* display, IGalliumDXGIBackend* p_backend) 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : GalliumDXGIObject<IDXGIFactory1, IUnknown>((IUnknown*)NULL), platform(platform), display(display) 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(p_backend) 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org backend = p_backend; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if(!strcmp(platform->name, "X11")) 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org backend.reset(new GalliumDXGIX11IdentityBackend((Display*)display)); 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org backend.reset(new GalliumDXGIIdentityBackend()); 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE EnumAdapters( 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT adapter, 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IDXGIAdapter **out_adapter) 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return EnumAdapters1(adapter, (IDXGIAdapter1**)out_adapter); 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE EnumAdapters1( 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT adapter, 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IDXGIAdapter1 **out_adapter) 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_adapter = 0; 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(adapter == 0) 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GalliumDXGIAdapterCreate(this, platform, display, out_adapter); 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: enable this 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(platform == native_get_x11_platform()) 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned nscreens = ScreenCount((Display*)display); 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(adapter < nscreens) 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned def_screen = DefaultScreen(display); 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(adapter <= def_screen) 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org --adapter; 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_adapter = GalliumDXGIAdapterCreate(this, platform, display, adapter); 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DXGI_ERROR_NOT_FOUND; 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: this is a mysterious underdocumented magic API 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Can we have multiple windows associated? 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Can we have multiple windows associated if we use multiple factories? 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If so, what should GetWindowAssociation return? 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If not, does a new swapchain steal the association? 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Does this act for existing swapchains? For new swapchains? 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation( 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HWND window_handle, 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT flags) 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: actually implement, for Wine, X11 and KMS*/ 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org associated_window = window_handle; 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HWND *pwindow_handle) 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *pwindow_handle = associated_window; 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IUnknown *device, 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_SWAP_CHAIN_DESC *desc, 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IDXGISwapChain **out_swap_chain) 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GalliumDXGISwapChainCreate(this, device, *desc, out_swap_chain); 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HMODULE module, 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IDXGIAdapter **out_adapter) 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: ignore the module, and just create a Gallium software screen */ 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_adapter = 0; 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return E_NOTIMPL; 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: support hotplug */ 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual BOOL STDMETHODCALLTYPE IsCurrent( void) 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TRUE; 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumDXGIAdapter 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : public GalliumMultiComObject< 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIObject<IDXGIAdapter1, GalliumDXGIFactory>, 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IGalliumAdapter> 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct native_display* display; 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct native_config** configs; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::unordered_multimap<unsigned, unsigned> configs_by_pipe_format; 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::unordered_map<unsigned, unsigned> configs_by_native_visual_id; 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct native_connector** connectors; 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned num_configs; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_ADAPTER_DESC1 desc; 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::vector<ComPtr<IDXGIOutput> > outputs; 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int num_outputs; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIAdapter(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy) 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->parent = factory; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org display = platform->create_display(dpy, FALSE); 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!display) 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org display = platform->create_display(dpy, TRUE); 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (display) { 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org display->user_data = this; 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!display->init_screen(display)) { 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org display->destroy(display); 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org display = NULL; 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!display) 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org throw E_FAIL; 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&desc, 0, sizeof(desc)); 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string s = std::string("GalliumD3D on ") + display->screen->get_name(display->screen) + " by " + display->screen->get_vendor(display->screen); 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* hopefully no one will decide to use UTF-8 in Gallium name/vendor strings */ 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(int i = 0; i < std::min((int)s.size(), 127); ++i) 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.Description[i] = (WCHAR)s[i]; 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: add an interface to get these; for now, return mid/low values 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.DedicatedVideoMemory = 256 << 20; 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.DedicatedSystemMemory = 256 << 20; 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.SharedSystemMemory = 1024 << 20; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: we should actually use an unique ID instead 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *(void**)&desc.AdapterLuid = dpy; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org configs = display->get_configs(display, (int*)&num_configs); 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned i = 0; i < num_configs; ++i) 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(configs[i]->window_bit) 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org configs_by_pipe_format.insert(std::make_pair(configs[i]->color_format, i)); 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org configs_by_native_visual_id[configs[i]->native_visual_id] = i; 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org connectors = 0; 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_outputs = 0; 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(display->modeset) 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int num_crtcs; 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org connectors = display->modeset->get_connectors(display, &num_outputs, &num_crtcs); 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!connectors) 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_outputs = 0; 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if(!num_outputs) 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(connectors); 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org connectors = 0; 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!num_outputs) 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_outputs = 1; 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void handle_invalid_surface(struct native_display *ndpy, struct native_surface *nsurf, unsigned int seq_num) 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGISwapChainRevalidate((IDXGISwapChain*)nsurf->user_data); 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ~GalliumDXGIAdapter() 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org display->destroy(display); 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(configs); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(connectors); 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE EnumOutputs( 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT output, 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IDXGIOutput **out_output) 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(output >= (unsigned)num_outputs) 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DXGI_ERROR_NOT_FOUND; 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(connectors) 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::ostringstream ss; 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ss << "output #" << output; 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GalliumDXGIOutputCreate(this, ss.str(), connectors[output], out_output); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GalliumDXGIOutputCreate(this, "Unique output", NULL, out_output); 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetDesc( 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_ADAPTER_DESC *desc) 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(desc, &desc, sizeof(*desc)); 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetDesc1( 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_ADAPTER_DESC1 *desc) 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(desc, &desc, sizeof(*desc)); 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport( 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org REFGUID interface_name, 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LARGE_INTEGER *u_m_d_version) 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // these number was taken from Windows 7 with Catalyst 10.8: its meaning is unclear 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(interface_name == IID_ID3D11Device || interface_name == IID_ID3D10Device1 || interface_name == IID_ID3D10Device) 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org u_m_d_version->QuadPart = 0x00080011000a0411ULL; 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DXGI_ERROR_UNSUPPORTED; 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_screen* STDMETHODCALLTYPE GetGalliumScreen() 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return display->screen; 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_screen* STDMETHODCALLTYPE GetGalliumReferenceSoftwareScreen() 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: give a softpipe screen 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return display->screen; 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_screen* STDMETHODCALLTYPE GetGalliumFastSoftwareScreen() 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: give an llvmpipe screen 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return display->screen; 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumDXGIOutput : public GalliumDXGIObject<IDXGIOutput, GalliumDXGIAdapter> 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_OUTPUT_DESC desc; 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct native_mode** modes; 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_MODE_DESC* dxgi_modes; 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned num_modes; 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct native_connector* connector; 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_GAMMA_CONTROL* gamma; 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIOutput(GalliumDXGIAdapter* adapter, std::string name, const struct native_connector* connector = 0) 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : GalliumDXGIObject<IDXGIOutput, GalliumDXGIAdapter>(adapter), connector(connector) 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&desc, 0, sizeof(desc)); 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned i = 0; i < std::min(name.size(), sizeof(desc.DeviceName) - 1); ++i) 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.DeviceName[i] = name[i]; 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.AttachedToDesktop = TRUE; 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: should put an HMONITOR in desc.Monitor */ 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gamma = 0; 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_modes = 0; 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modes = 0; 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(connector) 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modes = parent->display->modeset->get_modes(parent->display, connector, (int*)&num_modes); 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(modes && num_modes) 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes = new DXGI_MODE_DESC[num_modes]; 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned i = 0; i < num_modes; ++i) 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[i].Width = modes[i]->width; 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[i].Height = modes[i]->height; 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[i].RefreshRate.Numerator = modes[i]->refresh_rate; 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[i].RefreshRate.Denominator = 1; 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[i].Scaling = DXGI_MODE_SCALING_UNSPECIFIED; 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[i].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(modes) 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(modes); 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modes = 0; 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto use_fake_mode; 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orguse_fake_mode: 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes = new DXGI_MODE_DESC[1]; 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[0].Width = 1920; 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[0].Height = 1200; 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[0].RefreshRate.Numerator = 60; 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[0].RefreshRate.Denominator = 1; 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[0].Scaling = DXGI_MODE_SCALING_UNSPECIFIED; 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_modes[0].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ~GalliumDXGIOutput() 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete [] dxgi_modes; 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(modes); 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(gamma) 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete gamma; 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetDesc( 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_OUTPUT_DESC *out_desc) 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_desc = desc; 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetDisplayModeList( 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_FORMAT enum_format, 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT flags, 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT *pcount, 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_MODE_DESC *desc) 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: should we return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE when we don't 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * support modesetting instead of fake modes? 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_format format = dxgi_to_pipe_format[enum_format]; 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(parent->configs_by_pipe_format.count(format)) 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!desc) 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *pcount = num_modes; 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned copy_modes = std::min(num_modes, *pcount); 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned i = 0; i < copy_modes; ++i) 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc[i] = dxgi_modes[i]; 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc[i].Format = enum_format; 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *pcount = num_modes; 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(copy_modes < num_modes) 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DXGI_ERROR_MORE_DATA; 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *pcount = 0; 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE FindClosestMatchingMode( 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const DXGI_MODE_DESC *pModeToMatch, 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_MODE_DESC *closest_match, 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IUnknown *concerned_device) 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: actually implement this */ 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_FORMAT dxgi_format = pModeToMatch->Format; 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum pipe_format format = dxgi_to_pipe_format[dxgi_format]; 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org init_pipe_to_dxgi_format(); 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!parent->configs_by_pipe_format.count(format)) 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!concerned_device) 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return E_FAIL; 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format = parent->configs[0]->color_format; 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_format = pipe_to_dxgi_format[format]; 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *closest_match = dxgi_modes[0]; 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org closest_match->Format = dxgi_format; 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE WaitForVBlank( void) 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE TakeOwnership( 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IUnknown *device, 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BOOL exclusive) 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void STDMETHODCALLTYPE ReleaseOwnership( void) 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetGammaControlCapabilities( 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps) 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(gamma_caps, 0, sizeof(*gamma_caps)); 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE SetGammaControl( 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const DXGI_GAMMA_CONTROL *pArray) 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!gamma) 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gamma = new DXGI_GAMMA_CONTROL; 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *gamma = *pArray; 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetGammaControl( 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_GAMMA_CONTROL *pArray) 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(gamma) 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *pArray = *gamma; 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pArray->Scale.Red = 1; 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pArray->Scale.Green = 1; 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pArray->Scale.Blue = 1; 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pArray->Offset.Red = 0; 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pArray->Offset.Green = 0; 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pArray->Offset.Blue = 0; 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned i = 0; i <= 1024; ++i) 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pArray->GammaCurve[i].Red = pArray->GammaCurve[i].Green = pArray->GammaCurve[i].Blue = (float)i / 1024.0; 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE SetDisplaySurface( 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IDXGISurface *scanout_surface) 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return E_NOTIMPL; 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetDisplaySurfaceData( 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IDXGISurface *destination) 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return E_NOTIMPL; 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics( 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_FRAME_STATISTICS *stats) 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(stats, 0, sizeof(*stats)); 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef _WIN32 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QueryPerformanceCounter(&stats->SyncQPCTime); 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return E_NOTIMPL; 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Swap chain are rather complex, and Microsoft's documentation is rather 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * lacking. As far as I know, this is the most thorough publicly available 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * description of how swap chains work, based on multiple sources and 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * experimentation. 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * There are two modes (called "swap effects") that a swap chain can operate in: 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * discard and sequential. 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In discard mode, things always look as if there is a single buffer, which 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * you can get with GetBuffers(0). 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The 2D texture returned by GetBuffers(0) and can only be 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * used as a render target view and for resource copies, since no CPU access 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * flags are set and only the D3D11_BIND_RENDER_TARGET bind flag is set. 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * On Present, it is copied to the actual display 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * surface and the contents become undefined. 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * D3D may internally use multiple buffers, but you can't observe this, except 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * by looking at the buffer contents after Present (but those are undefined). 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If it uses multiple buffers internally, then it will normally use buffer_count buffers 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (this has latency implications). 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Discard mode seems to internally use a single buffer in windowed mode, 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * even if DWM is enabled, and buffer_count buffers in fullscreen mode. 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In sequential mode, the runtime alllocates buffer_count buffers. 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * You can get each with GetBuffers(n). 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GetBuffers(0) ALWAYS points to the backbuffer to be presented and has the 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * same usage constraints as the discard mode. 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GetBuffer(n) with n > 0 points to resources that are identical to buffer 0, but 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * are classified as "read-only resources" (due to DXGI_USAGE_READ_ONLY), 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * meaning that you can't create render target views on them, or use them as 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a CopyResource/CopySubresourceRegion destination. 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It appears the only valid operation is to use them as a source for CopyResource 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and CopySubresourceRegion as well as just waiting for them to become 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * buffer 0 again. 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Buffer n - 1 is always displayed on screen. 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * When you call Present(), the contents of the buffers are rotated, so that buffer 0 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * goes to buffer n - 1, and is thus displayed, and buffer 1 goes to buffer 0, becomes 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the accessible back buffer. 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The resources themselves are NOT rotated, so that you can still render on the 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * same ID3D11Texture2D*, and views based on it, that you got before Present(). 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Present seems to happen by either copying the relevant buffer into the window, 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or alternatively making it the current one, either by programming the CRTC or 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * by sending the resource name to the DWM compositor. 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Hence, you can call GetBuffer(0) once and keep using the same ID3D11Texture2D* 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and ID3D11RenderTargetView* (and other views if needed) you got from it. 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the window gets resized, DXGI will then "emulate" all successive presentations, 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * by using a stretched blit automatically. 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Thus, you should handle WM_SIZE and call ResizeBuffers to update the DXGI 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * swapchain buffers size to the new window size. 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Doing so requires you to release all GetBuffers() results and anything referencing 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * them, including views and Direct3D11 deferred context command lists (this is 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * documented). 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * How does Microsoft implement the rotation behavior? 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It turns out that it does it by calling RotateResourceIdentitiesDXGI in the user-mode 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DDI driver. 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This will rotate the kernel buffer handle, or possibly rotate the GPU virtual memory 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * mappings. 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The reason this is done by driver instead of by the runtime appears to be that 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this is necessary to support driver-provided command list support, since otherwise 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the command list would not always target the current backbuffer, since it would 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * be done at the driver level, while only the runtime knows about the rotation. 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OK, so how do we implement this in Gallium? 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * There are three strategies: 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1. Use a single buffer, and always copy it to a window system provided buffer, or 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * just give the buffer to the window system if it supports that 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2. Rotate the buffers in the D3D1x implementation, and recreate and rebind the views. 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Don't support driver-provided command lists 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3. Add this rotation functionality to the Gallium driver, with the idea that it would rotate 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * remap GPU virtual memory, so that virtual address are unchanged, but the physical 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ones are rotated (so that pushbuffers remain valid). 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the driver does not support this, either fall back to (1), or have a layer doing this, 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * putting a deferred context layer over this intermediate layer. 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (2) is not acceptable since it prevents an optimal implementation. 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (3) is the ideal solution, but it is complicated. 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Hence, we implement (1) for now, and will switch to (3) later. 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that (1) doesn't really work for DXGI_SWAP_EFFECT_SEQUENTIAL with more 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * than one buffer, so we just pretend we got asked for a single buffer in that case 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fortunately, no one seems to rely on that, so we'll just not implement it at first, and 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * later perform the rotation with blits. 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Once we switch to (3), we'll just use real rotation to do it.. 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DXGI_SWAP_EFFECT_SEQUENTIAL with more than one buffer is of dubious use 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * anyway, since you can only render or write to buffer 0, and other buffers can apparently 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * be used only as sources for copies. 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * I was unable to find any code using it either in DirectX SDK examples, or on the web. 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It seems the only reason you would use it is to not have to redraw from scratch, while 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * also possibly avoid a copy compared to buffer_count == 1, assuming that your 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * application is OK with having to redraw starting not from the last frame, but from 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * one/two/more frames behind it. 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * A better design would forbid the user specifying buffer_count explicitly, and 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * would instead let the application give an upper bound on how old the buffer can 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * become after presentation, with "infinite" being equivalent to discard. 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The runtime would then tell the application with frame number the buffer switched to 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * after present. 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In addition, in a better design, the application would be allowed to specify the 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * number of buffers available, having all them usable for rendering, so that things 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * like video players could efficiently decode frames in parallel. 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Present would in such a better design gain a way to specify the number of buffers 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to present. 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Other miscellaneous info: 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DXGI_PRESENT_DO_NOT_SEQUENCE causes DXGI to hold the frame for another 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vblank interval without rotating the resource data. 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * References: 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "DXGI Overview" in MSDN 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IDXGISwapChain documentation on MSDN 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "RotateResourceIdentitiesDXGI" on MSDN 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * http://forums.xna.com/forums/p/42362/266016.aspx 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic float quad_data[] = { 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, -1, 0, 0, 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, 1, 0, 1, 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1, 1, 1, 1, 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1, -1, 1, 0, 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct dxgi_blitter 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_context* pipe; 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool normalized; 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* fs; 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* vs; 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* sampler[2]; 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* elements; 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* blend; 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* rasterizer; 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* zsa; 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_clip_state clip; 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_vertex_buffer vbuf; 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_draw_info draw; 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_blitter(pipe_context* pipe) 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : pipe(pipe) 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //normalized = !!pipe->screen->get_param(pipe, PIPE_CAP_NPOT_TEXTURES); 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: need to update buffer in unnormalized case 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org normalized = true; 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_rasterizer_state rs_state; 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&rs_state, 0, sizeof(rs_state)); 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rs_state.cull_face = PIPE_FACE_NONE; 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rs_state.gl_rasterization_rules = 1; 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rs_state.depth_clip = 1; 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rs_state.flatshade = 1; 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rasterizer = pipe->create_rasterizer_state(pipe, &rs_state); 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_blend_state blendd; 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&blendd, 0, sizeof(blendd)); 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blendd.rt[0].colormask = PIPE_MASK_RGBA; 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blend = pipe->create_blend_state(pipe, &blendd); 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_depth_stencil_alpha_state zsad; 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&zsad, 0, sizeof(zsad)); 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org zsa = pipe->create_depth_stencil_alpha_state(pipe, &zsad); 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_vertex_element velem[2]; 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&velem[0], 0, sizeof(velem[0]) * 2); 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org velem[0].src_offset = 0; 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org velem[0].src_format = PIPE_FORMAT_R32G32_FLOAT; 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org velem[1].src_offset = 8; 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org velem[1].src_format = PIPE_FORMAT_R32G32_FLOAT; 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org elements = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned stretch = 0; stretch < 2; ++stretch) 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_sampler_state sampler_state; 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&sampler_state, 0, sizeof(sampler_state)); 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sampler_state.min_img_filter = stretch ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST; 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sampler_state.mag_img_filter = stretch ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST; 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sampler_state.normalized_coords = normalized; 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sampler[stretch] = pipe->create_sampler_state(pipe, &sampler_state); 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fs = util_make_fragment_tex_shader(pipe, normalized ? TGSI_TEXTURE_2D : TGSI_TEXTURE_RECT, TGSI_INTERPOLATE_LINEAR); 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned semantic_names[] = { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC }; 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned semantic_indices[] = { 0, 0 }; 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, semantic_indices); 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vbuf.buffer = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER, 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PIPE_USAGE_STREAM, sizeof(quad_data)); 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vbuf.buffer_offset = 0; 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vbuf.stride = 4 * sizeof(float); 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_buffer_write(pipe, vbuf.buffer, 0, sizeof(quad_data), quad_data); 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&clip, 0, sizeof(clip)); 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&draw, 0, sizeof(draw)); 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org draw.mode = PIPE_PRIM_QUADS; 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org draw.count = 4; 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org draw.instance_count = 1; 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org draw.max_index = ~0; 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void blit(struct pipe_surface* surf, struct pipe_sampler_view* view, unsigned x, unsigned y, unsigned w, unsigned h) 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_framebuffer_state fb; 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&fb, 0, sizeof(fb)); 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb.nr_cbufs = 1; 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb.cbufs[0] = surf; 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb.width = surf->width; 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb.height = surf->height; 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_viewport_state viewport; 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float half_width = w * 0.5f; 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float half_height = h * 0.5f; 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org viewport.scale[0] = half_width; 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org viewport.scale[1] = half_height; 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org viewport.scale[2] = 1.0f; 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org viewport.scale[3] = 1.0f; 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org viewport.translate[0] = x + half_width; 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org viewport.translate[1] = y + half_height; 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org viewport.translate[2] = 0.0f; 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org viewport.translate[3] = 1.0f; 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool stretch = view->texture->width0 != w || view->texture->height0 != h; 835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(pipe->render_condition) 836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->render_condition(pipe, 0, 0); 837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->set_framebuffer_state(pipe, &fb); 838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->bind_fragment_sampler_states(pipe, 1, &sampler[stretch]); 839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->set_viewport_state(pipe, &viewport); 840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->set_clip_state(pipe, &clip); 841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->bind_rasterizer_state(pipe, rasterizer); 842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->bind_depth_stencil_alpha_state(pipe, zsa); 843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->bind_blend_state(pipe, blend); 844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->bind_vertex_elements_state(pipe, elements); 845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->set_vertex_buffers(pipe, 1, &vbuf); 846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->bind_fs_state(pipe, fs); 847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->bind_vs_state(pipe, vs); 848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(pipe->bind_gs_state) 849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->bind_gs_state(pipe, 0); 850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(pipe->set_stream_output_targets) 851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->set_stream_output_targets(pipe, 0, NULL, 0); 852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->set_fragment_sampler_views(pipe, 1, &view); 853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->draw_vbo(pipe, &draw); 855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ~dxgi_blitter() 858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->delete_blend_state(pipe, blend); 860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->delete_rasterizer_state(pipe, rasterizer); 861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->delete_depth_stencil_alpha_state(pipe, zsa); 862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->delete_sampler_state(pipe, sampler[0]); 863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->delete_sampler_state(pipe, sampler[1]); 864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->delete_vertex_elements_state(pipe, elements); 865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->delete_vs_state(pipe, vs); 866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->delete_fs_state(pipe, fs); 867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->screen->resource_destroy(pipe->screen, vbuf.buffer); 868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDXGIFactory> 872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ComPtr<IDXGIDevice>dxgi_device; 874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ComPtr<IGalliumDevice>gallium_device; 875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ComPtr<GalliumDXGIAdapter> adapter; 876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ComPtr<IDXGIOutput> target; 877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_SWAP_CHAIN_DESC desc; 879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct native_surface* surface; 881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct native_config* config; 882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* window; 884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource* resources[NUM_NATIVE_ATTACHMENTS]; 885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int width; 886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int height; 887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned seq_num; 888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool ever_validated; 889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool needs_validation; 890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned present_count; 891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ComPtr<IDXGISurface> buffer0; 893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource* gallium_buffer0; 894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_sampler_view* gallium_buffer0_view; 895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_context* pipe; 897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool owns_pipe; 898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BOOL fullscreen; 900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::auto_ptr<dxgi_blitter> blitter; 902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool formats_compatible; 903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGISwapChain(GalliumDXGIFactory* factory, IUnknown* p_device, const DXGI_SWAP_CHAIN_DESC& p_desc) 905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : GalliumDXGIObject<IDXGISwapChain, GalliumDXGIFactory>(factory), desc(p_desc), surface(0) 906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HRESULT hr; 908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hr = p_device->QueryInterface(IID_IGalliumDevice, (void**)&gallium_device); 910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!SUCCEEDED(hr)) 911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org throw hr; 912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hr = p_device->QueryInterface(IID_IDXGIDevice, (void**)&dxgi_device); 914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!SUCCEEDED(hr)) 915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org throw hr; 916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hr = dxgi_device->GetAdapter((IDXGIAdapter**)&adapter); 918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!SUCCEEDED(hr)) 919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org throw hr; 920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(resources, 0, sizeof(resources)); 922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(desc.SwapEffect == DXGI_SWAP_EFFECT_SEQUENTIAL && desc.BufferCount != 1) 924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::cerr << "Gallium DXGI: if DXGI_SWAP_EFFECT_SEQUENTIAL is specified, only buffer_count == 1 is implemented, but " << desc.BufferCount << " was specified: ignoring this" << std::endl; 926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // change the returned desc, so that the application might perhaps notice what we did and react well 927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.BufferCount = 1; 928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe = gallium_device->GetGalliumContext(); 931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org owns_pipe = false; 932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!pipe) 933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe = adapter->display->screen->context_create(adapter->display->screen, 0); 935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org owns_pipe = true; 936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blitter.reset(new dxgi_blitter(pipe)); 939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org window = 0; 940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hr = resolve_zero_width_height(true); 942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!SUCCEEDED(hr)) 943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org throw hr; 944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void init_for_window() 947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(surface) 949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org surface->destroy(surface); 951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org surface = 0; 952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned config_num; 955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!strcmp(parent->platform->name, "X11")) 956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org XWindowAttributes xwa; 958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org XGetWindowAttributes((Display*)parent->display, (Window)window, &xwa); 959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(adapter->configs_by_native_visual_id.count(xwa.visual->visualid)); 960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org config_num = adapter->configs_by_native_visual_id[xwa.visual->visualid]; 961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum pipe_format format = dxgi_to_pipe_format[desc.BufferDesc.Format]; 965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!adapter->configs_by_pipe_format.count(format)) 966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(adapter->configs_by_pipe_format.empty()) 968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org throw E_FAIL; 969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: choose the best match 970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format = (pipe_format)adapter->configs_by_pipe_format.begin()->first; 971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: choose the best config 973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org config_num = adapter->configs_by_pipe_format.find(format)->second; 974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org config = adapter->configs[config_num]; 977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org surface = adapter->display->create_window_surface(adapter->display, (EGLNativeWindowType)window, config); 978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org surface->user_data = this; 979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width = 0; 981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org height = 0; 982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org seq_num = 0; 983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org present_count = 0; 984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org needs_validation = true; 985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ever_validated = false; 986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org formats_compatible = util_is_format_compatible( 988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org util_format_description(dxgi_to_pipe_format[desc.BufferDesc.Format]), 989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org util_format_description(config->color_format)); 990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ~GalliumDXGISwapChain() 993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(owns_pipe) 995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->destroy(pipe); 996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetDevice( 999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org REFIID riid, 1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void **pdevice) 1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return dxgi_device->QueryInterface(riid, pdevice); 1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HRESULT create_buffer0() 1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HRESULT hr; 1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ComPtr<IDXGISurface> new_buffer0; 1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_USAGE usage = DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT; 1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD) 1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usage |= DXGI_USAGE_DISCARD_ON_PRESENT; 1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // for our blitter 1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usage |= DXGI_USAGE_SHADER_INPUT; 1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_SURFACE_DESC surface_desc; 1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org surface_desc.Format = desc.BufferDesc.Format; 1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org surface_desc.Width = desc.BufferDesc.Width; 1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org surface_desc.Height = desc.BufferDesc.Height; 1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org surface_desc.SampleDesc = desc.SampleDesc; 1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hr = dxgi_device->CreateSurface(&surface_desc, 1, usage, 0, &new_buffer0); 1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!SUCCEEDED(hr)) 1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return hr; 1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ComPtr<IGalliumResource> gallium_resource; 1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hr = new_buffer0->QueryInterface(IID_IGalliumResource, (void**)&gallium_resource); 1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!SUCCEEDED(hr)) 1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return hr; 1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource* new_gallium_buffer0 = gallium_resource->GetGalliumResource(); 1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!new_gallium_buffer0) 1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return E_FAIL; 1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer0.reset(new_buffer0.steal()); 1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gallium_buffer0 = new_gallium_buffer0; 1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_sampler_view templat; 1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&templat, 0, sizeof(templat)); 1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org templat.texture = gallium_buffer0; 1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org templat.swizzle_r = 0; 1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org templat.swizzle_g = 1; 1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org templat.swizzle_b = 2; 1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org templat.swizzle_a = 3; 1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org templat.format = gallium_buffer0->format; 1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gallium_buffer0_view = pipe->create_sampler_view(pipe, gallium_buffer0, &templat); 1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool validate() 1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned new_seq_num; 1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org needs_validation = false; 1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!surface->validate(surface, (1 << NATIVE_ATTACHMENT_BACK_LEFT) | (1 << NATIVE_ATTACHMENT_FRONT_LEFT), &new_seq_num, resources, &width, &height)) 1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!ever_validated || seq_num != new_seq_num) 1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org seq_num = new_seq_num; 1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ever_validated = true; 1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HRESULT resolve_zero_width_height(bool force = false) 1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!force && desc.BufferDesc.Width && desc.BufferDesc.Height) 1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned width, height; 1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HRESULT hr = parent->backend->GetPresentSize(desc.OutputWindow, &width, &height); 1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!SUCCEEDED(hr)) 1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return hr; 1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // On Windows, 8 is used, and a debug message saying so gets printed 1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!width) 1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width = 8; 1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!height) 1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org height = 8; 1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!desc.BufferDesc.Width) 1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.BufferDesc.Width = width; 1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!desc.BufferDesc.Height) 1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.BufferDesc.Height = height; 1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE Present( 1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT sync_interval, 1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT flags) 1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HRESULT hr; 1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(flags & DXGI_PRESENT_TEST) 1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return parent->backend->TestPresent(desc.OutputWindow); 1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!buffer0) 1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HRESULT hr = create_buffer0(); 1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!SUCCEEDED(hr)) 1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return hr; 1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* cur_window = 0; 1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RECT rect; 1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RGNDATA* rgndata; 1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BOOL preserve_aspect_ratio; 1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned dst_w, dst_h; 1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool db; 1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource* dst; 1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource* src; 1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_surface* dst_surface; 1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct native_present_control ctrl; 1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* present_cookie; 1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hr = parent->backend->BeginPresent(desc.OutputWindow, &present_cookie, &cur_window, &rect, &rgndata, &preserve_aspect_ratio); 1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(hr != S_OK) 1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return hr; 1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!cur_window || rect.left >= rect.right || rect.top >= rect.bottom) 1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto end_present; 1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(cur_window != window) 1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org window = cur_window; 1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org init_for_window(); 1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(needs_validation) 1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!validate()) 1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DXGI_ERROR_DEVICE_REMOVED; 1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org db = !!(config->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)); 1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst = resources[db ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT]; 1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src = gallium_buffer0; 1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_surface = 0; 1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(src); 1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(dst); 1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: sharing the context for blitting won't work correctly if queries are active 1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Hopefully no one is crazy enough to keep queries active while presenting, expecting 1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * sensible results. 1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We could alternatively force using another context, but that might cause inefficiency issues 1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if((unsigned)rect.right > dst->width0) 1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rect.right = dst->width0; 1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if((unsigned)rect.bottom > dst->height0) 1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rect.bottom = dst->height0; 1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(rect.left > rect.right) 1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rect.left = rect.right; 1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(rect.top > rect.bottom) 1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rect.top = rect.bottom; 1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(rect.left >= rect.right && rect.top >= rect.bottom) 1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto end_present; 1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_w = rect.right - rect.left; 1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_h = rect.bottom - rect.top; 1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: add support for rgndata 1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// if(preserve_aspect_ratio || !rgndata) 1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(1) 1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned blit_x, blit_y, blit_w, blit_h; 1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static const union pipe_color_union black = { { 0, 0, 0, 0 } }; 1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!formats_compatible || src->width0 != dst_w || src->height0 != dst_h) { 1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_surface templat; 1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org templat.usage = PIPE_BIND_RENDER_TARGET; 1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org templat.format = dst->format; 1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org templat.u.tex.level = 0; 1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org templat.u.tex.first_layer = 0; 1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org templat.u.tex.last_layer = 0; 1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_surface = pipe->create_surface(pipe, dst, &templat); 1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(preserve_aspect_ratio) 1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int delta = src->width0 * dst_h - dst_w * src->height0; 1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(delta > 0) 1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_w = dst_w; 1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_h = dst_w * src->height0 / src->width0; 1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if(delta < 0) 1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_w = dst_h * src->width0 / src->height0; 1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_h = dst_h; 1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_w = dst_w; 1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_h = dst_h; 1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_x = (dst_w - blit_w) >> 1; 1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_y = (dst_h - blit_h) >> 1; 1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_x = 0; 1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_y = 0; 1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_w = dst_w; 1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blit_h = dst_h; 1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(blit_x) 1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->clear_render_target(pipe, dst_surface, &black, rect.left, rect.top, blit_x, dst_h); 1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(blit_y) 1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->clear_render_target(pipe, dst_surface, &black, rect.left, rect.top, dst_w, blit_y); 1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(formats_compatible && blit_w == src->width0 && blit_h == src->height0) 1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_box box; 1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org box.x = box.y = box.z = 0; 1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org box.width = blit_w; 1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org box.height = blit_h; 1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org box.depth = 1; 1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->resource_copy_region(pipe, dst, 0, rect.left, rect.top, 0, src, 0, &box); 1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blitter->blit(dst_surface, gallium_buffer0_view, rect.left + blit_x, rect.top + blit_y, blit_w, blit_h); 1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!owns_pipe) 1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gallium_device->RestoreGalliumState(); 1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(blit_w != dst_w) 1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->clear_render_target(pipe, dst_surface, &black, rect.left + blit_x + blit_w, rect.top, dst_w - blit_x - blit_w, dst_h); 1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(blit_h != dst_h) 1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->clear_render_target(pipe, dst_surface, &black, rect.left, rect.top + blit_y + blit_h, dst_w, dst_h - blit_y - blit_h); 1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(dst_surface) 1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->surface_destroy(pipe, dst_surface); 1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->flush(pipe, 0); 1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&ctrl, 0, sizeof(ctrl)); 1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctrl.natt = (db) ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT; 1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!surface->present(surface, &ctrl)) 1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DXGI_ERROR_DEVICE_REMOVED; 1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgend_present: 1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org parent->backend->EndPresent(desc.OutputWindow, present_cookie); 1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++present_count; 1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetBuffer( 1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT Buffer, 1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org REFIID riid, 1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void **ppSurface) 1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(Buffer > 0) 1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(desc.SwapEffect == DXGI_SWAP_EFFECT_SEQUENTIAL) 1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::cerr << "DXGI unimplemented: GetBuffer(n) with n > 0 not supported, returning buffer 0 instead!" << std::endl; 1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::cerr << "DXGI error: in GetBuffer(n), n must be 0 for DXGI_SWAP_EFFECT_DISCARD\n" << std::endl; 1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!buffer0) 1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HRESULT hr = create_buffer0(); 1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!SUCCEEDED(hr)) 1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return hr; 1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return buffer0->QueryInterface(riid, ppSurface); 1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: implement somehow */ 1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE SetFullscreenState( 1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BOOL fullscreen, 1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IDXGIOutput *target) 1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fullscreen = fullscreen; 1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target = target; 1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetFullscreenState( 1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BOOL *out_fullscreen, 1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IDXGIOutput **out_target) 1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(out_fullscreen) 1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_fullscreen = fullscreen; 1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(out_target) 1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_target = target.ref(); 1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetDesc( 1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_SWAP_CHAIN_DESC *out_desc) 1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_desc = desc; 1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE ResizeBuffers( 1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT buffer_count, 1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT width, 1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT height, 1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_FORMAT new_format, 1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT swap_chain_flags) 1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(buffer0) 1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer0.p->AddRef(); 1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ULONG v = buffer0.p->Release(); 1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // we must fail if there are any references to buffer0 other than ours 1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(v > 1) 1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return E_FAIL; 1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_sampler_view_reference(&gallium_buffer0_view, 0); 1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer0 = (IUnknown*)NULL; 1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gallium_buffer0 = 0; 1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(desc.SwapEffect != DXGI_SWAP_EFFECT_SEQUENTIAL) 1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.BufferCount = buffer_count; 1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.BufferDesc.Format = new_format; 1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.BufferDesc.Width = width; 1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.BufferDesc.Height = height; 1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org desc.Flags = swap_chain_flags; 1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return resolve_zero_width_height(); 1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE ResizeTarget( 1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const DXGI_MODE_DESC *out_new_target_parameters) 1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: implement */ 1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetContainingOutput( 1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IDXGIOutput **out_output) 1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_output = adapter->outputs[0].ref(); 1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics( 1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DXGI_FRAME_STATISTICS *out_stats) 1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(out_stats, 0, sizeof(*out_stats)); 1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef _WIN32 1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QueryPerformanceCounter(&out_stats->SyncQPCTime); 1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org out_stats->PresentCount = present_count; 1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org out_stats->PresentRefreshCount = present_count; 1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org out_stats->SyncRefreshCount = present_count; 1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount( 1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UINT *last_present_count) 1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *last_present_count = present_count; 1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void GalliumDXGISwapChainRevalidate(IDXGISwapChain* swap_chain) 1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ((GalliumDXGISwapChain*)swap_chain)->needs_validation = true; 1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy, IDXGIAdapter1** out_adapter) 1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org try 1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_adapter = new GalliumDXGIAdapter(factory, platform, dpy); 1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org catch(HRESULT hr) 1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return hr; 1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** out_output) 1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org try 1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_output = new GalliumDXGIOutput(adapter, name, connector); 1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org catch(HRESULT hr) 1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return hr; 1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** out_swap_chain) 1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org try 1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_swap_chain = new GalliumDXGISwapChain(factory, device, desc); 1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return S_OK; 1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org catch(HRESULT hr) 1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return hr; 1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct dxgi_binding 1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct native_platform* platform; 1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* display; 1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IGalliumDXGIBackend* backend; 1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic dxgi_binding dxgi_default_binding; 1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic __thread dxgi_binding dxgi_thread_binding; 1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct native_event_handler dxgi_event_handler = { 1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIAdapter::handle_invalid_surface, 1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_loader_create_drm_screen, 1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_loader_create_sw_screen 1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid STDMETHODCALLTYPE GalliumDXGIUseNothing() 1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.platform = 0; 1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.display = 0; 1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(dxgi_thread_binding.backend) 1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.backend->Release(); 1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.backend = 0; 1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef GALLIUM_DXGI_USE_X11 1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid STDMETHODCALLTYPE GalliumDXGIUseX11Display(Display* dpy, IGalliumDXGIBackend* backend) 1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIUseNothing(); 1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.platform = native_get_x11_platform(&dxgi_event_handler); 1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.display = dpy; 1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(backend) 1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.backend = backend; 1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org backend->AddRef(); 1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef GALLIUM_DXGI_USE_DRM 1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid STDMETHODCALLTYPE GalliumDXGIUseDRMCard(int fd) 1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIUseNothing(); 1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.platform = native_get_drm_platform(&dxgi_event_handler); 1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.display = (void*)fd; 1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.backend = 0; 1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef GALLIUM_DXGI_USE_FBDEV 1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid STDMETHODCALLTYPE GalliumDXGIUseFBDev(int fd) 1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIUseNothing(); 1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.platform = native_get_fbdev_platform(&dxgi_event_handler); 1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.display = (void*)fd; 1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.backend = 0; 1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef GALLIUM_DXGI_USE_GDI 1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid STDMETHODCALLTYPE GalliumDXGIUseHDC(HDC hdc, PFNHWNDRESOLVER resolver, void* resolver_cookie) 1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIUseNothing(); 1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.platform = native_get_gdi_platform(&dxgi_event_handler); 1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.display = (void*)hdc; 1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_thread_binding.backend = 0; 1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*/ 1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid STDMETHODCALLTYPE GalliumDXGIMakeDefault() 1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(dxgi_default_binding.backend) 1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_default_binding.backend->Release(); 1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_default_binding = dxgi_thread_binding; 1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(dxgi_default_binding.backend) 1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dxgi_default_binding.backend->AddRef(); 1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: why did Microsoft add this? should we do something different for DXGI 1.0 and 1.1? 1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Or perhaps what they actually mean is "only create a single factory in your application"? 1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TODO: should we use a singleton here, so we never have multiple DXGI objects for the same thing? */ 1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HRESULT STDMETHODCALLTYPE CreateDXGIFactory1( 1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org REFIID riid, 1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void **out_factory 1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org) 1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GalliumDXGIFactory* factory; 1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *out_factory = 0; 1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(dxgi_thread_binding.platform) 1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org factory = new GalliumDXGIFactory(dxgi_thread_binding.platform, dxgi_thread_binding.display, dxgi_thread_binding.backend); 1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if(dxgi_default_binding.platform) 1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org factory = new GalliumDXGIFactory(dxgi_default_binding.platform, dxgi_default_binding.display, dxgi_default_binding.backend); 1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org factory = new GalliumDXGIFactory(native_get_x11_platform(&dxgi_event_handler), NULL, NULL); 1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HRESULT hres = factory->QueryInterface(riid, out_factory); 1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org factory->Release(); 1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return hres; 1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HRESULT STDMETHODCALLTYPE CreateDXGIFactory( 1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org REFIID riid, 1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void **out_factor 1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org) 1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return CreateDXGIFactory1(riid, out_factor); 1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1516