winsys/gdi: Custom acquisition of hDC

In d3d10umd it is required to pass D3DKMT_PRESENT in
context_private of flush_frontbuffer, but wgl passes HDC in it.
To accomidate this when gdi_sw_winsys is created functions that
acquire and release hdc from context_private are passed.

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Reviewed-by: Feng Jiang <jiangfeng@kylinos.cn>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27333>
This commit is contained in:
Max R
2024-01-29 13:06:17 +03:00
committed by Marge Bot
parent be4b1c2639
commit 2b5e257690
8 changed files with 76 additions and 26 deletions

View File

@@ -20,6 +20,7 @@
inc_include = [include_directories('.')] inc_include = [include_directories('.')]
inc_d3d9 = include_directories('D3D9') inc_d3d9 = include_directories('D3D9')
inc_winddk = include_directories('winddk')
# Most things assume that Android headers are in the default include # Most things assume that Android headers are in the default include
# path when compiling for Android so add the stub headers to # path when compiling for Android so add the stub headers to

View File

@@ -58,7 +58,7 @@ vl_win32_screen_create(LUID *adapter)
if (!vscreen) if (!vscreen)
return NULL; 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) if (!winsys)
goto release_pipe; goto release_pipe;
@@ -91,7 +91,7 @@ vl_win32_screen_create_from_d3d12_device(IUnknown* d3d12_device)
if (!vscreen) if (!vscreen)
return NULL; 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) if (!winsys)
goto release_pipe; goto release_pipe;

View File

@@ -5,8 +5,6 @@ if cc.get_argument_syntax() == 'gcc'
_c_args_d3d10umd += '-Wno-unknown-pragmas' _c_args_d3d10umd += '-Wno-unknown-pragmas'
endif endif
inc_winddk = include_directories('../../../../include/winddk')
libd3d10umd = static_library( libd3d10umd = static_library(
'd3d10umd', 'd3d10umd',
files( files(

View File

@@ -33,10 +33,25 @@
#include "softpipe/sp_public.h" #include "softpipe/sp_public.h"
#include "sw/gdi/gdi_sw_winsys.h" #include "sw/gdi/gdi_sw_winsys.h"
#include "winddk_compat.h"
#include <d3dkmthk.h>
extern struct pipe_screen * extern struct pipe_screen *
d3d10_create_screen(void); 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 * struct pipe_screen *
d3d10_create_screen(void) d3d10_create_screen(void)
@@ -46,7 +61,7 @@ d3d10_create_screen(void)
struct pipe_screen *screen = NULL; struct pipe_screen *screen = NULL;
struct sw_winsys *winsys; struct sw_winsys *winsys;
winsys = gdi_create_sw_winsys(); winsys = gdi_create_sw_winsys(d3d10_gdi_acquire_hdc, d3d10_gdi_release_hdc);
if(!winsys) if(!winsys)
goto no_winsys; goto no_winsys;

View File

@@ -31,7 +31,7 @@ libd3d10sw = shared_library(
['d3d10_gdi.c'], ['d3d10_gdi.c'],
vs_module_defs : d3d10_sw_def, vs_module_defs : d3d10_sw_def,
include_directories : [ 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_whole : [libd3d10umd],
link_with : [ link_with : [

View File

@@ -116,7 +116,7 @@ wgl_screen_create(HDC hDC)
struct sw_winsys *winsys; struct sw_winsys *winsys;
UNUSED bool sw_only = debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false); 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) if (!winsys)
return NULL; return NULL;

View File

@@ -61,6 +61,12 @@ struct gdi_sw_displaytarget
BITMAPV5HEADER bmi; 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 */ /** Cast wrapper */
static inline struct gdi_sw_displaytarget * 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 static bool
gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws, gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
unsigned tex_usage, unsigned tex_usage,
@@ -235,16 +249,16 @@ gdi_sw_display( struct sw_winsys *winsys,
} }
static void static void
gdi_sw_displaytarget_display(struct sw_winsys *winsys, gdi_sw_displaytarget_display(struct sw_winsys *_winsys,
struct sw_displaytarget *dt, struct sw_displaytarget *dt,
void *context_private, void *context_private,
struct pipe_box *box) struct pipe_box *box)
{ {
/* nasty: struct gdi_sw_winsys *winsys = gdi_sw_winsys(_winsys);
*/ HDC hDC = winsys->acquire_hdc(context_private);
HDC hDC = (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 * 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) if(!winsys)
return NULL; return NULL;
winsys->destroy = gdi_sw_destroy; winsys->acquire_hdc = acquire_hdc;
winsys->is_displaytarget_format_supported = gdi_sw_is_displaytarget_format_supported; winsys->release_hdc = release_hdc;
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;
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
};

View File

@@ -11,6 +11,15 @@ void gdi_sw_display( struct sw_winsys *winsys,
HDC hDC ); HDC hDC );
struct sw_winsys * 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 #endif