1/************************************************************************** 2 * 3 * Copyright 2009-2010 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 * 26 * 27 **************************************************************************/ 28 29/** 30 * @file 31 * Softpipe/LLVMpipe support. 32 * 33 * @author Jose Fonseca <jfonseca@vmware.com> 34 */ 35 36 37#include <windows.h> 38 39#include "util/u_debug.h" 40#include "stw_winsys.h" 41#include "gdi/gdi_sw_winsys.h" 42 43#include "softpipe/sp_texture.h" 44#include "softpipe/sp_screen.h" 45#include "softpipe/sp_public.h" 46 47#ifdef HAVE_LLVMPIPE 48#include "llvmpipe/lp_texture.h" 49#include "llvmpipe/lp_screen.h" 50#include "llvmpipe/lp_public.h" 51#endif 52 53 54static boolean use_llvmpipe = FALSE; 55 56 57static struct pipe_screen * 58gdi_screen_create(void) 59{ 60 const char *default_driver; 61 const char *driver; 62 struct pipe_screen *screen = NULL; 63 struct sw_winsys *winsys; 64 65 winsys = gdi_create_sw_winsys(); 66 if(!winsys) 67 goto no_winsys; 68 69#ifdef HAVE_LLVMPIPE 70 default_driver = "llvmpipe"; 71#else 72 default_driver = "softpipe"; 73#endif 74 75 driver = debug_get_option("GALLIUM_DRIVER", default_driver); 76 77#ifdef HAVE_LLVMPIPE 78 if (strcmp(driver, "llvmpipe") == 0) { 79 screen = llvmpipe_create_screen( winsys ); 80 } 81#endif 82 83 if (screen == NULL) { 84 screen = softpipe_create_screen( winsys ); 85 } else { 86 use_llvmpipe = TRUE; 87 } 88 89 if(!screen) 90 goto no_screen; 91 92 return screen; 93 94no_screen: 95 winsys->destroy(winsys); 96no_winsys: 97 return NULL; 98} 99 100 101static void 102gdi_present(struct pipe_screen *screen, 103 struct pipe_resource *res, 104 HDC hDC) 105{ 106 /* This will fail if any interposing layer (trace, debug, etc) has 107 * been introduced between the state-trackers and the pipe driver. 108 * 109 * Ideally this would get replaced with a call to 110 * pipe_screen::flush_frontbuffer(). 111 * 112 * Failing that, it may be necessary for intervening layers to wrap 113 * other structs such as this stw_winsys as well... 114 */ 115 116 struct sw_winsys *winsys = NULL; 117 struct sw_displaytarget *dt = NULL; 118 119#ifdef HAVE_LLVMPIPE 120 if (use_llvmpipe) { 121 winsys = llvmpipe_screen(screen)->winsys; 122 dt = llvmpipe_resource(res)->dt; 123 gdi_sw_display(winsys, dt, hDC); 124 return; 125 } 126#endif 127 128 winsys = softpipe_screen(screen)->winsys, 129 dt = softpipe_resource(res)->dt, 130 gdi_sw_display(winsys, dt, hDC); 131} 132 133 134static const struct stw_winsys stw_winsys = { 135 &gdi_screen_create, 136 &gdi_present, 137 NULL, /* get_adapter_luid */ 138 NULL, /* shared_surface_open */ 139 NULL, /* shared_surface_close */ 140 NULL /* compose */ 141}; 142 143 144BOOL WINAPI 145DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) 146{ 147 switch (fdwReason) { 148 case DLL_PROCESS_ATTACH: 149 stw_init(&stw_winsys); 150 stw_init_thread(); 151 break; 152 153 case DLL_THREAD_ATTACH: 154 stw_init_thread(); 155 break; 156 157 case DLL_THREAD_DETACH: 158 stw_cleanup_thread(); 159 break; 160 161 case DLL_PROCESS_DETACH: 162 stw_cleanup_thread(); 163 stw_cleanup(); 164 break; 165 } 166 return TRUE; 167} 168