1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2009-2010 VMware, Inc. 4848b8605Smrg * All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the 8848b8605Smrg * "Software"), to deal in the Software without restriction, including 9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 12848b8605Smrg * the following conditions: 13848b8605Smrg * 14848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 17848b8605Smrg * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 18848b8605Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19848b8605Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20848b8605Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. 21848b8605Smrg * 22848b8605Smrg * The above copyright notice and this permission notice (including the 23848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 24848b8605Smrg * of the Software. 25848b8605Smrg * 26848b8605Smrg * 27848b8605Smrg **************************************************************************/ 28848b8605Smrg 29848b8605Smrg/** 30848b8605Smrg * @file 31848b8605Smrg * Softpipe/LLVMpipe support. 32848b8605Smrg * 33848b8605Smrg * @author Jose Fonseca <jfonseca@vmware.com> 34848b8605Smrg */ 35848b8605Smrg 36848b8605Smrg 37848b8605Smrg#include <windows.h> 38848b8605Smrg 39848b8605Smrg#include "util/u_debug.h" 40848b8605Smrg#include "stw_winsys.h" 41b8e80941Smrg#include "stw_device.h" 42848b8605Smrg#include "gdi/gdi_sw_winsys.h" 43848b8605Smrg 44848b8605Smrg#include "softpipe/sp_texture.h" 45848b8605Smrg#include "softpipe/sp_screen.h" 46848b8605Smrg#include "softpipe/sp_public.h" 47848b8605Smrg 48848b8605Smrg#ifdef HAVE_LLVMPIPE 49848b8605Smrg#include "llvmpipe/lp_texture.h" 50848b8605Smrg#include "llvmpipe/lp_screen.h" 51848b8605Smrg#include "llvmpipe/lp_public.h" 52848b8605Smrg#endif 53848b8605Smrg 54b8e80941Smrg#ifdef HAVE_SWR 55b8e80941Smrg#include "swr/swr_public.h" 56b8e80941Smrg#endif 57848b8605Smrg 58848b8605Smrgstatic boolean use_llvmpipe = FALSE; 59b8e80941Smrgstatic boolean use_swr = FALSE; 60848b8605Smrg 61848b8605Smrgstatic struct pipe_screen * 62848b8605Smrggdi_screen_create(void) 63848b8605Smrg{ 64848b8605Smrg const char *default_driver; 65848b8605Smrg const char *driver; 66848b8605Smrg struct pipe_screen *screen = NULL; 67848b8605Smrg struct sw_winsys *winsys; 68848b8605Smrg 69848b8605Smrg winsys = gdi_create_sw_winsys(); 70848b8605Smrg if(!winsys) 71848b8605Smrg goto no_winsys; 72848b8605Smrg 73848b8605Smrg#ifdef HAVE_LLVMPIPE 74848b8605Smrg default_driver = "llvmpipe"; 75b8e80941Smrg#elif HAVE_SWR 76b8e80941Smrg default_driver = "swr"; 77848b8605Smrg#else 78848b8605Smrg default_driver = "softpipe"; 79848b8605Smrg#endif 80848b8605Smrg 81848b8605Smrg driver = debug_get_option("GALLIUM_DRIVER", default_driver); 82848b8605Smrg 83848b8605Smrg#ifdef HAVE_LLVMPIPE 84848b8605Smrg if (strcmp(driver, "llvmpipe") == 0) { 85848b8605Smrg screen = llvmpipe_create_screen( winsys ); 86b8e80941Smrg if (screen) 87b8e80941Smrg use_llvmpipe = TRUE; 88848b8605Smrg } 89848b8605Smrg#endif 90b8e80941Smrg#ifdef HAVE_SWR 91b8e80941Smrg if (strcmp(driver, "swr") == 0) { 92b8e80941Smrg screen = swr_create_screen( winsys ); 93b8e80941Smrg if (screen) 94b8e80941Smrg use_swr = TRUE; 95b8e80941Smrg } 96b8e80941Smrg#endif 97b8e80941Smrg (void) driver; 98848b8605Smrg 99848b8605Smrg if (screen == NULL) { 100848b8605Smrg screen = softpipe_create_screen( winsys ); 101848b8605Smrg } 102848b8605Smrg 103848b8605Smrg if(!screen) 104848b8605Smrg goto no_screen; 105848b8605Smrg 106848b8605Smrg return screen; 107848b8605Smrg 108848b8605Smrgno_screen: 109848b8605Smrg winsys->destroy(winsys); 110848b8605Smrgno_winsys: 111848b8605Smrg return NULL; 112848b8605Smrg} 113848b8605Smrg 114848b8605Smrg 115848b8605Smrgstatic void 116848b8605Smrggdi_present(struct pipe_screen *screen, 117848b8605Smrg struct pipe_resource *res, 118848b8605Smrg HDC hDC) 119848b8605Smrg{ 120848b8605Smrg /* This will fail if any interposing layer (trace, debug, etc) has 121848b8605Smrg * been introduced between the state-trackers and the pipe driver. 122848b8605Smrg * 123848b8605Smrg * Ideally this would get replaced with a call to 124848b8605Smrg * pipe_screen::flush_frontbuffer(). 125848b8605Smrg * 126848b8605Smrg * Failing that, it may be necessary for intervening layers to wrap 127848b8605Smrg * other structs such as this stw_winsys as well... 128848b8605Smrg */ 129848b8605Smrg 130848b8605Smrg struct sw_winsys *winsys = NULL; 131848b8605Smrg struct sw_displaytarget *dt = NULL; 132848b8605Smrg 133848b8605Smrg#ifdef HAVE_LLVMPIPE 134848b8605Smrg if (use_llvmpipe) { 135848b8605Smrg winsys = llvmpipe_screen(screen)->winsys; 136848b8605Smrg dt = llvmpipe_resource(res)->dt; 137848b8605Smrg gdi_sw_display(winsys, dt, hDC); 138848b8605Smrg return; 139848b8605Smrg } 140848b8605Smrg#endif 141848b8605Smrg 142b8e80941Smrg#ifdef HAVE_SWR 143b8e80941Smrg if (use_swr) { 144b8e80941Smrg swr_gdi_swap(screen, res, hDC); 145b8e80941Smrg return; 146b8e80941Smrg } 147b8e80941Smrg#endif 148b8e80941Smrg 149848b8605Smrg winsys = softpipe_screen(screen)->winsys, 150848b8605Smrg dt = softpipe_resource(res)->dt, 151848b8605Smrg gdi_sw_display(winsys, dt, hDC); 152848b8605Smrg} 153848b8605Smrg 154848b8605Smrg 155848b8605Smrgstatic const struct stw_winsys stw_winsys = { 156848b8605Smrg &gdi_screen_create, 157848b8605Smrg &gdi_present, 158848b8605Smrg NULL, /* get_adapter_luid */ 159848b8605Smrg NULL, /* shared_surface_open */ 160848b8605Smrg NULL, /* shared_surface_close */ 161848b8605Smrg NULL /* compose */ 162848b8605Smrg}; 163848b8605Smrg 164848b8605Smrg 165b8e80941SmrgEXTERN_C BOOL WINAPI 166b8e80941SmrgDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); 167b8e80941Smrg 168b8e80941Smrg 169848b8605SmrgBOOL WINAPI 170b8e80941SmrgDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 171848b8605Smrg{ 172848b8605Smrg switch (fdwReason) { 173848b8605Smrg case DLL_PROCESS_ATTACH: 174848b8605Smrg stw_init(&stw_winsys); 175848b8605Smrg stw_init_thread(); 176848b8605Smrg break; 177848b8605Smrg 178848b8605Smrg case DLL_THREAD_ATTACH: 179848b8605Smrg stw_init_thread(); 180848b8605Smrg break; 181848b8605Smrg 182848b8605Smrg case DLL_THREAD_DETACH: 183848b8605Smrg stw_cleanup_thread(); 184848b8605Smrg break; 185848b8605Smrg 186848b8605Smrg case DLL_PROCESS_DETACH: 187b8e80941Smrg if (lpvReserved == NULL) { 188b8e80941Smrg // We're being unloaded from the process. 189848b8605Smrg stw_cleanup_thread(); 190848b8605Smrg stw_cleanup(); 191b8e80941Smrg } else { 192b8e80941Smrg // Process itself is terminating, and all threads and modules are 193b8e80941Smrg // being detached. 194b8e80941Smrg // 195b8e80941Smrg // The order threads (including llvmpipe rasterizer threads) are 196b8e80941Smrg // destroyed can not be relied up, so it's not safe to cleanup. 197b8e80941Smrg // 198b8e80941Smrg // However global destructors (e.g., LLVM's) will still be called, and 199b8e80941Smrg // if Microsoft OPENGL32.DLL's DllMain is called after us, it will 200b8e80941Smrg // still try to invoke DrvDeleteContext to destroys all outstanding, 201b8e80941Smrg // so set stw_dev to NULL to return immediately if that happens. 202b8e80941Smrg stw_dev = NULL; 203848b8605Smrg } 204848b8605Smrg break; 205848b8605Smrg } 206848b8605Smrg return TRUE; 207848b8605Smrg} 208