Path: blob/21.2-virgl/src/gallium/targets/libgl-gdi/libgl_gdi.c
4565 views
/**************************************************************************1*2* Copyright 2009-2010 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL16* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,17* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR18* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE19* USE OR OTHER DEALINGS IN THE SOFTWARE.20*21* The above copyright notice and this permission notice (including the22* next paragraph) shall be included in all copies or substantial portions23* of the Software.24*25*26**************************************************************************/2728/**29* @file30* Softpipe/LLVMpipe support.31*32* @author Jose Fonseca <[email protected]>33*/343536#include <windows.h>3738#include "util/u_debug.h"39#include "util/debug.h"40#include "stw_winsys.h"41#include "stw_device.h"42#include "gdi/gdi_sw_winsys.h"43#include "pipe/p_screen.h"44#include "pipe/p_context.h"4546#ifdef GALLIUM_SOFTPIPE47#include "softpipe/sp_texture.h"48#include "softpipe/sp_screen.h"49#include "softpipe/sp_public.h"50#endif5152#ifdef GALLIUM_LLVMPIPE53#include "llvmpipe/lp_texture.h"54#include "llvmpipe/lp_screen.h"55#include "llvmpipe/lp_public.h"56#endif5758#ifdef GALLIUM_SWR59#include "swr/swr_public.h"60#endif61#ifdef GALLIUM_D3D1262#include "d3d12/wgl/d3d12_wgl_public.h"63#endif6465#ifdef GALLIUM_ZINK66#include "zink/zink_public.h"67#endif6869#ifdef GALLIUM_LLVMPIPE70static boolean use_llvmpipe = FALSE;71#endif72#ifdef GALLIUM_SWR73static boolean use_swr = FALSE;74#endif75#ifdef GALLIUM_D3D1276static boolean use_d3d12 = FALSE;77#endif78#ifdef GALLIUM_ZINK79static boolean use_zink = FALSE;80#endif8182static struct pipe_screen *83gdi_screen_create_by_name(HDC hDC, const char* driver, struct sw_winsys *winsys)84{85struct pipe_screen* screen = NULL;8687#ifdef GALLIUM_LLVMPIPE88if (strcmp(driver, "llvmpipe") == 0) {89screen = llvmpipe_create_screen(winsys);90if (screen)91use_llvmpipe = TRUE;92}93#endif94#ifdef GALLIUM_SWR95if (strcmp(driver, "swr") == 0) {96screen = swr_create_screen(winsys);97if (screen)98use_swr = TRUE;99}100#endif101#ifdef GALLIUM_D3D12102if (strcmp(driver, "d3d12") == 0) {103screen = d3d12_wgl_create_screen(winsys, hDC);104if (screen)105use_d3d12 = TRUE;106}107#endif108#ifdef GALLIUM_ZINK109if (strcmp(driver, "zink") == 0) {110screen = zink_create_screen(winsys);111if (screen)112use_zink = TRUE;113}114#endif115#ifdef GALLIUM_SOFTPIPE116if (strcmp(driver, "softpipe") == 0) {117screen = softpipe_create_screen(winsys);118}119#endif120121return screen;122}123124static struct pipe_screen *125gdi_screen_create(HDC hDC)126{127struct sw_winsys *winsys;128UNUSED bool sw_only = env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false);129130winsys = gdi_create_sw_winsys();131if (!winsys)132return NULL;133134const char *const drivers[] = {135debug_get_option("GALLIUM_DRIVER", ""),136#ifdef GALLIUM_D3D12137sw_only ? "" : "d3d12",138#endif139#if defined(GALLIUM_LLVMPIPE)140"llvmpipe",141#endif142#if GALLIUM_SWR143"swr",144#endif145#if defined(GALLIUM_SOFTPIPE)146"softpipe",147#endif148};149150/* If the default driver screen creation fails, fall back to the next option in the151* sorted list. Don't do this if GALLIUM_DRIVER is specified.152*/153for (unsigned i = 0; i < ARRAY_SIZE(drivers); ++i) {154struct pipe_screen* screen = gdi_screen_create_by_name(hDC, drivers[i], winsys);155if (screen)156return screen;157if (i == 0 && drivers[i][0] != '\0')158break;159}160161winsys->destroy(winsys);162return NULL;163}164165166static void167gdi_present(struct pipe_screen *screen,168struct pipe_context *ctx,169struct pipe_resource *res,170HDC hDC)171{172/* This will fail if any interposing layer (trace, debug, etc) has173* been introduced between the gallium frontends and the pipe driver.174*175* Ideally this would get replaced with a call to176* pipe_screen::flush_frontbuffer().177*178* Failing that, it may be necessary for intervening layers to wrap179* other structs such as this stw_winsys as well...180*/181182struct sw_winsys *winsys = NULL;183struct sw_displaytarget *dt = NULL;184185#ifdef GALLIUM_LLVMPIPE186if (use_llvmpipe) {187winsys = llvmpipe_screen(screen)->winsys;188dt = llvmpipe_resource(res)->dt;189gdi_sw_display(winsys, dt, hDC);190return;191}192#endif193194#ifdef GALLIUM_SWR195if (use_swr) {196swr_gdi_swap(screen, ctx, res, hDC);197return;198}199#endif200201#ifdef GALLIUM_D3D12202if (use_d3d12) {203d3d12_wgl_present(screen, ctx, res, hDC);204return;205}206#endif207208#ifdef GALLIUM_ZINK209if (use_zink) {210screen->flush_frontbuffer(screen, ctx, res, 0, 0, hDC, NULL);211return;212}213#endif214215#ifdef GALLIUM_SOFTPIPE216winsys = softpipe_screen(screen)->winsys,217dt = softpipe_resource(res)->dt,218gdi_sw_display(winsys, dt, hDC);219#endif220}221222223#if WINVER >= 0xA00224static boolean225gdi_get_adapter_luid(struct pipe_screen* screen,226HDC hDC,227LUID* adapter_luid)228{229if (!stw_dev || !stw_dev->callbacks.pfnGetAdapterLuid)230return false;231232stw_dev->callbacks.pfnGetAdapterLuid(hDC, adapter_luid);233return true;234}235#endif236237238static unsigned239gdi_get_pfd_flags(struct pipe_screen *screen)240{241#ifdef GALLIUM_D3D12242if (use_d3d12)243return d3d12_wgl_get_pfd_flags(screen);244#endif245return stw_pfd_gdi_support;246}247248249static struct stw_winsys_framebuffer *250gdi_create_framebuffer(struct pipe_screen *screen,251HDC hDC,252int iPixelFormat)253{254#ifdef GALLIUM_D3D12255if (use_d3d12)256return d3d12_wgl_create_framebuffer(screen, hDC, iPixelFormat);257#endif258return NULL;259}260261262static const struct stw_winsys stw_winsys = {263&gdi_screen_create,264&gdi_present,265#if WINVER >= 0xA00266&gdi_get_adapter_luid,267#else268NULL, /* get_adapter_luid */269#endif270NULL, /* shared_surface_open */271NULL, /* shared_surface_close */272NULL, /* compose */273&gdi_get_pfd_flags,274&gdi_create_framebuffer,275};276277278EXTERN_C BOOL WINAPI279DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);280281282BOOL WINAPI283DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)284{285switch (fdwReason) {286case DLL_PROCESS_ATTACH:287stw_init(&stw_winsys);288stw_init_thread();289break;290291case DLL_THREAD_ATTACH:292stw_init_thread();293break;294295case DLL_THREAD_DETACH:296stw_cleanup_thread();297break;298299case DLL_PROCESS_DETACH:300if (lpvReserved == NULL) {301// We're being unloaded from the process.302stw_cleanup_thread();303stw_cleanup();304} else {305// Process itself is terminating, and all threads and modules are306// being detached.307//308// The order threads (including llvmpipe rasterizer threads) are309// destroyed can not be relied up, so it's not safe to cleanup.310//311// However global destructors (e.g., LLVM's) will still be called, and312// if Microsoft OPENGL32.DLL's DllMain is called after us, it will313// still try to invoke DrvDeleteContext to destroys all outstanding,314// so set stw_dev to NULL to return immediately if that happens.315stw_dev = NULL;316}317break;318}319return TRUE;320}321322323