17ec681f3Smrg/*
27ec681f3Smrg * Copyright © Microsoft Corporation
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice (including the next
127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg * Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
217ec681f3Smrg * IN THE SOFTWARE.
227ec681f3Smrg */
237ec681f3Smrg
247ec681f3Smrg
257ec681f3Smrg#include <windows.h>
267ec681f3Smrg
277ec681f3Smrg#include "util/u_debug.h"
287ec681f3Smrg#include "stw_winsys.h"
297ec681f3Smrg#include "stw_device.h"
307ec681f3Smrg#include "gdi/gdi_sw_winsys.h"
317ec681f3Smrg
327ec681f3Smrg#include "softpipe/sp_texture.h"
337ec681f3Smrg#include "softpipe/sp_screen.h"
347ec681f3Smrg#include "softpipe/sp_public.h"
357ec681f3Smrg
367ec681f3Smrg#ifndef GALLIUM_D3D12
377ec681f3Smrg#error "This file must be compiled only with the D3D12 driver"
387ec681f3Smrg#endif
397ec681f3Smrg#include "d3d12/wgl/d3d12_wgl_public.h"
407ec681f3Smrg
417ec681f3Smrgstatic struct pipe_screen *
427ec681f3Smrggdi_screen_create(HDC hDC)
437ec681f3Smrg{
447ec681f3Smrg   struct pipe_screen *screen = NULL;
457ec681f3Smrg   struct sw_winsys *winsys;
467ec681f3Smrg
477ec681f3Smrg   winsys = gdi_create_sw_winsys();
487ec681f3Smrg   if(!winsys)
497ec681f3Smrg      goto no_winsys;
507ec681f3Smrg
517ec681f3Smrg   screen = d3d12_wgl_create_screen( winsys, hDC );
527ec681f3Smrg
537ec681f3Smrg   if(!screen)
547ec681f3Smrg      goto no_screen;
557ec681f3Smrg
567ec681f3Smrg   return screen;
577ec681f3Smrg
587ec681f3Smrgno_screen:
597ec681f3Smrg   winsys->destroy(winsys);
607ec681f3Smrgno_winsys:
617ec681f3Smrg   return NULL;
627ec681f3Smrg}
637ec681f3Smrg
647ec681f3Smrg
657ec681f3Smrgstatic void
667ec681f3Smrggdi_present(struct pipe_screen *screen,
677ec681f3Smrg            struct pipe_context *context,
687ec681f3Smrg            struct pipe_resource *res,
697ec681f3Smrg            HDC hDC)
707ec681f3Smrg{
717ec681f3Smrg   d3d12_wgl_present(screen, context, res, hDC);
727ec681f3Smrg}
737ec681f3Smrg
747ec681f3Smrg
757ec681f3Smrgstatic boolean
767ec681f3Smrggdi_get_adapter_luid(struct pipe_screen *screen,
777ec681f3Smrg                     HDC hDC,
787ec681f3Smrg                     LUID *adapter_luid)
797ec681f3Smrg{
807ec681f3Smrg   if (!stw_dev || !stw_dev->callbacks.pfnGetAdapterLuid)
817ec681f3Smrg      return false;
827ec681f3Smrg
837ec681f3Smrg   stw_dev->callbacks.pfnGetAdapterLuid(hDC, adapter_luid);
847ec681f3Smrg   return true;
857ec681f3Smrg}
867ec681f3Smrg
877ec681f3Smrg
887ec681f3Smrgstatic unsigned
897ec681f3Smrggdi_get_pfd_flags(struct pipe_screen *screen)
907ec681f3Smrg{
917ec681f3Smrg   return d3d12_wgl_get_pfd_flags(screen);
927ec681f3Smrg}
937ec681f3Smrg
947ec681f3Smrg
957ec681f3Smrgstatic struct stw_winsys_framebuffer *
967ec681f3Smrggdi_create_framebuffer(struct pipe_screen *screen,
977ec681f3Smrg                       HWND hWnd,
987ec681f3Smrg                       int iPixelFormat)
997ec681f3Smrg{
1007ec681f3Smrg   return d3d12_wgl_create_framebuffer(screen, hWnd, iPixelFormat);
1017ec681f3Smrg}
1027ec681f3Smrg
1037ec681f3Smrgstatic const char *
1047ec681f3Smrgget_name(void)
1057ec681f3Smrg{
1067ec681f3Smrg   return "d3d12";
1077ec681f3Smrg}
1087ec681f3Smrg
1097ec681f3Smrgstatic const struct stw_winsys stw_winsys = {
1107ec681f3Smrg   &gdi_screen_create,
1117ec681f3Smrg   &gdi_present,
1127ec681f3Smrg   &gdi_get_adapter_luid,
1137ec681f3Smrg   NULL, /* shared_surface_open */
1147ec681f3Smrg   NULL, /* shared_surface_close */
1157ec681f3Smrg   NULL, /* compose */
1167ec681f3Smrg   &gdi_get_pfd_flags,
1177ec681f3Smrg   &gdi_create_framebuffer,
1187ec681f3Smrg   &get_name,
1197ec681f3Smrg};
1207ec681f3Smrg
1217ec681f3Smrg
1227ec681f3SmrgEXTERN_C BOOL WINAPI
1237ec681f3SmrgDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
1247ec681f3Smrg
1257ec681f3Smrg
1267ec681f3SmrgBOOL WINAPI
1277ec681f3SmrgDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1287ec681f3Smrg{
1297ec681f3Smrg   switch (fdwReason) {
1307ec681f3Smrg   case DLL_PROCESS_ATTACH:
1317ec681f3Smrg      stw_init(&stw_winsys);
1327ec681f3Smrg      stw_init_thread();
1337ec681f3Smrg      break;
1347ec681f3Smrg
1357ec681f3Smrg   case DLL_THREAD_ATTACH:
1367ec681f3Smrg      stw_init_thread();
1377ec681f3Smrg      break;
1387ec681f3Smrg
1397ec681f3Smrg   case DLL_THREAD_DETACH:
1407ec681f3Smrg      stw_cleanup_thread();
1417ec681f3Smrg      break;
1427ec681f3Smrg
1437ec681f3Smrg   case DLL_PROCESS_DETACH:
1447ec681f3Smrg      if (lpvReserved == NULL) {
1457ec681f3Smrg         // We're being unloaded from the process.
1467ec681f3Smrg         stw_cleanup_thread();
1477ec681f3Smrg         stw_cleanup();
1487ec681f3Smrg      } else {
1497ec681f3Smrg         // Process itself is terminating, and all threads and modules are
1507ec681f3Smrg         // being detached.
1517ec681f3Smrg         //
1527ec681f3Smrg         // The order threads (including llvmpipe rasterizer threads) are
1537ec681f3Smrg         // destroyed can not be relied up, so it's not safe to cleanup.
1547ec681f3Smrg         //
1557ec681f3Smrg         // However global destructors (e.g., LLVM's) will still be called, and
1567ec681f3Smrg         // if Microsoft OPENGL32.DLL's DllMain is called after us, it will
1577ec681f3Smrg         // still try to invoke DrvDeleteContext to destroys all outstanding,
1587ec681f3Smrg         // so set stw_dev to NULL to return immediately if that happens.
1597ec681f3Smrg         stw_dev = NULL;
1607ec681f3Smrg      }
1617ec681f3Smrg      break;
1627ec681f3Smrg   }
1637ec681f3Smrg   return TRUE;
1647ec681f3Smrg}
165