1/* 2 * Copyright © Microsoft Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 25#include <windows.h> 26 27#include "util/u_debug.h" 28#include "stw_winsys.h" 29#include "stw_device.h" 30#include "gdi/gdi_sw_winsys.h" 31 32#include "softpipe/sp_texture.h" 33#include "softpipe/sp_screen.h" 34#include "softpipe/sp_public.h" 35 36#ifndef GALLIUM_D3D12 37#error "This file must be compiled only with the D3D12 driver" 38#endif 39#include "d3d12/wgl/d3d12_wgl_public.h" 40 41static struct pipe_screen * 42gdi_screen_create(HDC hDC) 43{ 44 struct pipe_screen *screen = NULL; 45 struct sw_winsys *winsys; 46 47 winsys = gdi_create_sw_winsys(); 48 if(!winsys) 49 goto no_winsys; 50 51 screen = d3d12_wgl_create_screen( winsys, hDC ); 52 53 if(!screen) 54 goto no_screen; 55 56 return screen; 57 58no_screen: 59 winsys->destroy(winsys); 60no_winsys: 61 return NULL; 62} 63 64 65static void 66gdi_present(struct pipe_screen *screen, 67 struct pipe_context *context, 68 struct pipe_resource *res, 69 HDC hDC) 70{ 71 d3d12_wgl_present(screen, context, res, hDC); 72} 73 74 75static boolean 76gdi_get_adapter_luid(struct pipe_screen *screen, 77 HDC hDC, 78 LUID *adapter_luid) 79{ 80 if (!stw_dev || !stw_dev->callbacks.pfnGetAdapterLuid) 81 return false; 82 83 stw_dev->callbacks.pfnGetAdapterLuid(hDC, adapter_luid); 84 return true; 85} 86 87 88static unsigned 89gdi_get_pfd_flags(struct pipe_screen *screen) 90{ 91 return d3d12_wgl_get_pfd_flags(screen); 92} 93 94 95static struct stw_winsys_framebuffer * 96gdi_create_framebuffer(struct pipe_screen *screen, 97 HWND hWnd, 98 int iPixelFormat) 99{ 100 return d3d12_wgl_create_framebuffer(screen, hWnd, iPixelFormat); 101} 102 103static const char * 104get_name(void) 105{ 106 return "d3d12"; 107} 108 109static const struct stw_winsys stw_winsys = { 110 &gdi_screen_create, 111 &gdi_present, 112 &gdi_get_adapter_luid, 113 NULL, /* shared_surface_open */ 114 NULL, /* shared_surface_close */ 115 NULL, /* compose */ 116 &gdi_get_pfd_flags, 117 &gdi_create_framebuffer, 118 &get_name, 119}; 120 121 122EXTERN_C BOOL WINAPI 123DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); 124 125 126BOOL WINAPI 127DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 128{ 129 switch (fdwReason) { 130 case DLL_PROCESS_ATTACH: 131 stw_init(&stw_winsys); 132 stw_init_thread(); 133 break; 134 135 case DLL_THREAD_ATTACH: 136 stw_init_thread(); 137 break; 138 139 case DLL_THREAD_DETACH: 140 stw_cleanup_thread(); 141 break; 142 143 case DLL_PROCESS_DETACH: 144 if (lpvReserved == NULL) { 145 // We're being unloaded from the process. 146 stw_cleanup_thread(); 147 stw_cleanup(); 148 } else { 149 // Process itself is terminating, and all threads and modules are 150 // being detached. 151 // 152 // The order threads (including llvmpipe rasterizer threads) are 153 // destroyed can not be relied up, so it's not safe to cleanup. 154 // 155 // However global destructors (e.g., LLVM's) will still be called, and 156 // if Microsoft OPENGL32.DLL's DllMain is called after us, it will 157 // still try to invoke DrvDeleteContext to destroys all outstanding, 158 // so set stw_dev to NULL to return immediately if that happens. 159 stw_dev = NULL; 160 } 161 break; 162 } 163 return TRUE; 164} 165