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:
@@ -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
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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(
|
||||
|
@@ -33,10 +33,25 @@
|
||||
#include "softpipe/sp_public.h"
|
||||
#include "sw/gdi/gdi_sw_winsys.h"
|
||||
|
||||
#include "winddk_compat.h"
|
||||
#include <d3dkmthk.h>
|
||||
|
||||
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;
|
||||
|
||||
|
@@ -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 : [
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
};
|
@@ -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
|
||||
|
Reference in New Issue
Block a user