diff --git a/include/meson.build b/include/meson.build index a955ac71073..6a05d03fae2 100644 --- a/include/meson.build +++ b/include/meson.build @@ -20,6 +20,7 @@ inc_include = [include_directories('.')] inc_d3d9 = include_directories('D3D9') +inc_winddk = include_directories('winddk') # Most things assume that Android headers are in the default include # path when compiling for Android so add the stub headers to diff --git a/src/gallium/auxiliary/vl/vl_winsys_win32.c b/src/gallium/auxiliary/vl/vl_winsys_win32.c index 349e610ba69..8f92ddbde5f 100644 --- a/src/gallium/auxiliary/vl/vl_winsys_win32.c +++ b/src/gallium/auxiliary/vl/vl_winsys_win32.c @@ -58,7 +58,7 @@ vl_win32_screen_create(LUID *adapter) if (!vscreen) return NULL; - struct sw_winsys* winsys = gdi_create_sw_winsys(); + struct sw_winsys* winsys = gdi_create_sw_winsys(gdi_sw_acquire_hdc_by_value, gdi_sw_release_hdc_by_value); if (!winsys) goto release_pipe; @@ -91,7 +91,7 @@ vl_win32_screen_create_from_d3d12_device(IUnknown* d3d12_device) if (!vscreen) return NULL; - struct sw_winsys* winsys = gdi_create_sw_winsys(); + struct sw_winsys* winsys = gdi_create_sw_winsys(gdi_sw_acquire_hdc_by_value, gdi_sw_release_hdc_by_value); if (!winsys) goto release_pipe; diff --git a/src/gallium/frontends/d3d10umd/meson.build b/src/gallium/frontends/d3d10umd/meson.build index 28c27f0cf8e..bcfe8c24fd5 100644 --- a/src/gallium/frontends/d3d10umd/meson.build +++ b/src/gallium/frontends/d3d10umd/meson.build @@ -5,8 +5,6 @@ if cc.get_argument_syntax() == 'gcc' _c_args_d3d10umd += '-Wno-unknown-pragmas' endif -inc_winddk = include_directories('../../../../include/winddk') - libd3d10umd = static_library( 'd3d10umd', files( diff --git a/src/gallium/targets/d3d10sw/d3d10_gdi.c b/src/gallium/targets/d3d10sw/d3d10_gdi.c index f5a22e50c39..14f1458ba53 100644 --- a/src/gallium/targets/d3d10sw/d3d10_gdi.c +++ b/src/gallium/targets/d3d10sw/d3d10_gdi.c @@ -33,10 +33,25 @@ #include "softpipe/sp_public.h" #include "sw/gdi/gdi_sw_winsys.h" +#include "winddk_compat.h" +#include extern struct pipe_screen * d3d10_create_screen(void); +HDC d3d10_gdi_acquire_hdc(void *winsys_drawable_handle) { + D3DKMT_PRESENT *pPresentInfo = (D3DKMT_PRESENT *)winsys_drawable_handle; + + HWND hWnd = pPresentInfo->hWindow; + return GetDC(hWnd); +} + +void d3d10_gdi_release_hdc(void *winsys_drawable_handle, HDC hDC) { + D3DKMT_PRESENT *pPresentInfo = (D3DKMT_PRESENT *)winsys_drawable_handle; + + HWND hWnd = pPresentInfo->hWindow; + ReleaseDC(hWnd, hDC); +} struct pipe_screen * d3d10_create_screen(void) @@ -46,7 +61,7 @@ d3d10_create_screen(void) struct pipe_screen *screen = NULL; struct sw_winsys *winsys; - winsys = gdi_create_sw_winsys(); + winsys = gdi_create_sw_winsys(d3d10_gdi_acquire_hdc, d3d10_gdi_release_hdc); if(!winsys) goto no_winsys; diff --git a/src/gallium/targets/d3d10sw/meson.build b/src/gallium/targets/d3d10sw/meson.build index 727a807f1ba..5fe2f5fa39d 100644 --- a/src/gallium/targets/d3d10sw/meson.build +++ b/src/gallium/targets/d3d10sw/meson.build @@ -31,7 +31,7 @@ libd3d10sw = shared_library( ['d3d10_gdi.c'], vs_module_defs : d3d10_sw_def, include_directories : [ - inc_include, inc_src, inc_gallium, inc_gallium_aux, inc_d3d10umd, inc_gallium_winsys, inc_gallium_winsys_sw, inc_gallium_drivers, + inc_include, inc_src, inc_gallium, inc_gallium_aux, inc_d3d10umd, inc_gallium_winsys, inc_gallium_winsys_sw, inc_gallium_drivers, inc_winddk ], link_whole : [libd3d10umd], link_with : [ diff --git a/src/gallium/targets/wgl/wgl.c b/src/gallium/targets/wgl/wgl.c index f57ee0cd471..5e895ef3100 100644 --- a/src/gallium/targets/wgl/wgl.c +++ b/src/gallium/targets/wgl/wgl.c @@ -116,7 +116,7 @@ wgl_screen_create(HDC hDC) struct sw_winsys *winsys; UNUSED bool sw_only = debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false); - winsys = gdi_create_sw_winsys(); + winsys = gdi_create_sw_winsys(gdi_sw_acquire_hdc_by_value, gdi_sw_release_hdc_by_value); if (!winsys) return NULL; diff --git a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c index 1f0d0086f81..13224a6bd9e 100644 --- a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c +++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c @@ -61,6 +61,12 @@ struct gdi_sw_displaytarget BITMAPV5HEADER bmi; }; +struct gdi_sw_winsys { + struct sw_winsys base; + + HDC (*acquire_hdc)(void *winsys_drawable_handle); + void (*release_hdc)(void *winsys_drawable_handle, HDC hdc); +}; /** Cast wrapper */ static inline struct gdi_sw_displaytarget * @@ -70,6 +76,14 @@ gdi_sw_displaytarget( struct sw_displaytarget *buf ) } +/** Cast wrapper */ +static inline struct gdi_sw_winsys * +gdi_sw_winsys( struct sw_winsys *buf ) +{ + return (struct gdi_sw_winsys *)buf; +} + + static bool gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws, unsigned tex_usage, @@ -235,16 +249,16 @@ gdi_sw_display( struct sw_winsys *winsys, } static void -gdi_sw_displaytarget_display(struct sw_winsys *winsys, +gdi_sw_displaytarget_display(struct sw_winsys *_winsys, struct sw_displaytarget *dt, void *context_private, struct pipe_box *box) { - /* nasty: - */ - HDC hDC = (HDC)context_private; + struct gdi_sw_winsys *winsys = gdi_sw_winsys(_winsys); + HDC hDC = winsys->acquire_hdc(context_private); - gdi_sw_display(winsys, dt, hDC); + gdi_sw_display(_winsys, dt, hDC); + winsys->release_hdc(context_private, hDC); } @@ -255,24 +269,37 @@ gdi_sw_destroy(struct sw_winsys *winsys) } struct sw_winsys * -gdi_create_sw_winsys(void) +gdi_create_sw_winsys( + HDC (*acquire_hdc)(void *winsys_drawable_handle), + void (*release_hdc)(void *winsys_drawable_handle, HDC hdc)) { - static struct sw_winsys *winsys; + static struct gdi_sw_winsys *winsys; - winsys = CALLOC_STRUCT(sw_winsys); + winsys = CALLOC_STRUCT(gdi_sw_winsys); if(!winsys) return NULL; - winsys->destroy = gdi_sw_destroy; - winsys->is_displaytarget_format_supported = gdi_sw_is_displaytarget_format_supported; - winsys->displaytarget_create = gdi_sw_displaytarget_create; - winsys->displaytarget_from_handle = gdi_sw_displaytarget_from_handle; - winsys->displaytarget_get_handle = gdi_sw_displaytarget_get_handle; - winsys->displaytarget_map = gdi_sw_displaytarget_map; - winsys->displaytarget_unmap = gdi_sw_displaytarget_unmap; - winsys->displaytarget_display = gdi_sw_displaytarget_display; - winsys->displaytarget_destroy = gdi_sw_displaytarget_destroy; + winsys->acquire_hdc = acquire_hdc; + winsys->release_hdc = release_hdc; - return winsys; + winsys->base.destroy = gdi_sw_destroy; + winsys->base.is_displaytarget_format_supported = gdi_sw_is_displaytarget_format_supported; + winsys->base.displaytarget_create = gdi_sw_displaytarget_create; + winsys->base.displaytarget_from_handle = gdi_sw_displaytarget_from_handle; + winsys->base.displaytarget_get_handle = gdi_sw_displaytarget_get_handle; + winsys->base.displaytarget_map = gdi_sw_displaytarget_map; + winsys->base.displaytarget_unmap = gdi_sw_displaytarget_unmap; + winsys->base.displaytarget_display = gdi_sw_displaytarget_display; + winsys->base.displaytarget_destroy = gdi_sw_displaytarget_destroy; + + return &winsys->base; } + +HDC gdi_sw_acquire_hdc_by_value(void *context_private) { + return (HDC)context_private; +}; + +void gdi_sw_release_hdc_by_value(void *context_private, HDC hdc) { + // Nothing to do +}; \ No newline at end of file diff --git a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h index 1fc1d9bcdec..0b4641e445a 100644 --- a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h +++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h @@ -11,6 +11,15 @@ void gdi_sw_display( struct sw_winsys *winsys, HDC hDC ); struct sw_winsys * -gdi_create_sw_winsys(void); +gdi_create_sw_winsys( + /* Following functions are used to acquire HDC to draw on + * from winsys_drawable_handle argument of screen->flush_frontbuffer + */ + HDC (*acquire_hdc)(void *winsys_drawable_handle), + void (*release_hdc)(void *winsys_drawable_handle, HDC hdc) +); +/* Used when winsys_drawable_handle is HDC itself */ +HDC gdi_sw_acquire_hdc_by_value(void *context_private); +void gdi_sw_release_hdc_by_value(void *context_private, HDC hdc); #endif