wgl: Add support for Xbox GDK.
This patch is comprised of three main changes: - Add a "shim" for GDI, since Xbox doesn't expose this library - New framebuffer file, to support the Xbox "windowing" system - Implement a custom WndProc hook for Xbox, since SetWindowsHookEx isn't supported either Other than that, it's similar to the previous Xbox commits which mostly disable Win32-specific logic. Co-authored-by: Ethan Lee <flibitijibibo@gmail.com> Co-authored-by: David Jacewicz <david.jacewicz@protonmail.com> Co-authored-by: tieuchanlong <tieuchanlong@gmail.com> Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19022>
This commit is contained in:
@@ -25,27 +25,33 @@ if not with_shared_glapi
|
||||
_c_args_wgl += '-D_GLAPI_NO_EXPORTS'
|
||||
endif
|
||||
|
||||
files_libwgl = files(
|
||||
'stw_context.c',
|
||||
'stw_device.c',
|
||||
'stw_ext_context.c',
|
||||
'stw_ext_extensionsstring.c',
|
||||
'stw_ext_interop.c',
|
||||
'stw_ext_pbuffer.c',
|
||||
'stw_ext_pixelformat.c',
|
||||
'stw_ext_rendertexture.c',
|
||||
'stw_ext_swapinterval.c',
|
||||
'stw_framebuffer.c',
|
||||
'stw_getprocaddress.c',
|
||||
'stw_image.c',
|
||||
'stw_nopfuncs.c',
|
||||
'stw_nopfuncs.h',
|
||||
'stw_pixelformat.c',
|
||||
'stw_st.c',
|
||||
'stw_tls.c',
|
||||
)
|
||||
|
||||
if target_machine.system().startswith('Gaming.Xbox')
|
||||
files_libwgl += files('stw_gdishim.c')
|
||||
endif
|
||||
|
||||
libwgl = static_library(
|
||||
'wgl',
|
||||
files(
|
||||
'stw_context.c',
|
||||
'stw_device.c',
|
||||
'stw_ext_context.c',
|
||||
'stw_ext_extensionsstring.c',
|
||||
'stw_ext_interop.c',
|
||||
'stw_ext_pbuffer.c',
|
||||
'stw_ext_pixelformat.c',
|
||||
'stw_ext_rendertexture.c',
|
||||
'stw_ext_swapinterval.c',
|
||||
'stw_framebuffer.c',
|
||||
'stw_getprocaddress.c',
|
||||
'stw_image.c',
|
||||
'stw_nopfuncs.c',
|
||||
'stw_nopfuncs.h',
|
||||
'stw_pixelformat.c',
|
||||
'stw_st.c',
|
||||
'stw_tls.c',
|
||||
),
|
||||
files_libwgl,
|
||||
c_args : [
|
||||
'-D_GDI32_', # prevent wgl* being declared __declspec(dllimport)
|
||||
_c_args_wgl
|
||||
|
@@ -42,6 +42,7 @@
|
||||
#include "util/u_atomic.h"
|
||||
#include "hud/hud_context.h"
|
||||
|
||||
#include "stw_gdishim.h"
|
||||
#include "gldrv.h"
|
||||
#include "stw_device.h"
|
||||
#include "stw_winsys.h"
|
||||
|
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include <stw_gdishim.h>
|
||||
#include <gldrv.h>
|
||||
|
||||
struct hud_context;
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include "stw_device.h"
|
||||
#include "stw_winsys.h"
|
||||
#include "stw_pixelformat.h"
|
||||
#include "stw_gdishim.h"
|
||||
#include "gldrv.h"
|
||||
#include "stw_tls.h"
|
||||
#include "stw_framebuffer.h"
|
||||
@@ -72,6 +73,7 @@ stw_get_param(struct pipe_frontend_screen *fscreen,
|
||||
static int
|
||||
get_refresh_rate(void)
|
||||
{
|
||||
#ifndef _GAMING_XBOX
|
||||
DEVMODE devModes;
|
||||
|
||||
if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devModes)) {
|
||||
@@ -82,6 +84,9 @@ get_refresh_rate(void)
|
||||
/* reasonable default */
|
||||
return 60;
|
||||
}
|
||||
#else
|
||||
return 60;
|
||||
#endif /* _GAMING_XBOX */
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include "util/u_dynarray.h"
|
||||
#include "util/xmlconfig.h"
|
||||
#include <GL/gl.h>
|
||||
#include "stw_gdishim.h"
|
||||
#include "gldrv.h"
|
||||
#include "stw_pixelformat.h"
|
||||
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include <GL/gl.h>
|
||||
#include <GL/wglext.h>
|
||||
|
||||
#include "stw_gdishim.h"
|
||||
#include "gldrv.h"
|
||||
#include "stw_context.h"
|
||||
#include "stw_device.h"
|
||||
|
@@ -48,6 +48,7 @@
|
||||
static LRESULT CALLBACK
|
||||
WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
#ifndef _GAMING_XBOX
|
||||
MINMAXINFO *pMMI;
|
||||
switch (uMsg) {
|
||||
case WM_GETMINMAXINFO:
|
||||
@@ -61,6 +62,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif /* _GAMING_XBOX */
|
||||
|
||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
@@ -78,8 +80,10 @@ stw_pbuffer_create(const struct stw_pixelformat_info *pfi, int iWidth, int iHeig
|
||||
WNDCLASS wc;
|
||||
memset(&wc, 0, sizeof wc);
|
||||
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
|
||||
#ifndef _GAMING_XBOX
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
#endif
|
||||
wc.lpfnWndProc = WndProc;
|
||||
wc.lpszClassName = "wglpbuffer";
|
||||
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "stw_gdishim.h"
|
||||
#include "gldrv.h"
|
||||
#include "stw_context.h"
|
||||
#include "stw_device.h"
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "frontend/api.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include "stw_gdishim.h"
|
||||
#include "gldrv.h"
|
||||
#include "stw_framebuffer.h"
|
||||
#include "stw_device.h"
|
||||
@@ -178,11 +179,13 @@ stw_framebuffer_get_size(struct stw_framebuffer *fb)
|
||||
|
||||
client_pos.x = 0;
|
||||
client_pos.y = 0;
|
||||
#ifndef _GAMING_XBOX
|
||||
if (ClientToScreen(fb->hWnd, &client_pos) &&
|
||||
GetWindowRect(fb->hWnd, &window_rect)) {
|
||||
fb->client_rect.left = client_pos.x - window_rect.left;
|
||||
fb->client_rect.top = client_pos.y - window_rect.top;
|
||||
}
|
||||
#endif
|
||||
|
||||
fb->client_rect.right = fb->client_rect.left + fb->width;
|
||||
fb->client_rect.bottom = fb->client_rect.top + fb->height;
|
||||
@@ -204,6 +207,7 @@ stw_framebuffer_get_size(struct stw_framebuffer *fb)
|
||||
}
|
||||
|
||||
|
||||
#ifndef _GAMING_XBOX
|
||||
/**
|
||||
* @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx
|
||||
* @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx
|
||||
@@ -263,6 +267,40 @@ stw_call_window_proc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
|
||||
}
|
||||
#else
|
||||
LRESULT CALLBACK
|
||||
stw_call_window_proc_xbox(HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
WNDPROC prev_wndproc = NULL;
|
||||
|
||||
/* We check that the stw_dev object is initialized before we try to do
|
||||
* anything with it. Otherwise, in multi-threaded programs there's a
|
||||
* chance of executing this code before the stw_dev object is fully
|
||||
* initialized.
|
||||
*/
|
||||
if (stw_dev && stw_dev->initialized) {
|
||||
if (message == WM_DESTROY) {
|
||||
stw_lock_framebuffers(stw_dev);
|
||||
struct stw_framebuffer *fb = stw_framebuffer_from_hwnd_locked(hWnd);
|
||||
if (fb) {
|
||||
struct stw_context *current_context = stw_current_context();
|
||||
struct st_context *st = current_context &&
|
||||
current_context->current_framebuffer == fb ? current_context->st : NULL;
|
||||
prev_wndproc = fb->prev_wndproc;
|
||||
stw_framebuffer_release_locked(fb, st);
|
||||
}
|
||||
stw_unlock_framebuffers(stw_dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass the parameters up the chain, if applicable */
|
||||
if (prev_wndproc)
|
||||
return prev_wndproc(hWnd, message, wParam, lParam);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* _GAMING_XBOX */
|
||||
|
||||
|
||||
/**
|
||||
@@ -286,6 +324,10 @@ stw_framebuffer_create(HWND hWnd, const struct stw_pixelformat_info *pfi, enum s
|
||||
fb->winsys_framebuffer =
|
||||
stw_dev->stw_winsys->create_framebuffer(stw_dev->screen, hWnd, pfi->iPixelFormat);
|
||||
|
||||
#ifdef _GAMING_XBOX
|
||||
fb->prev_wndproc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)&stw_call_window_proc_xbox);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We often need a displayable pixel format to make GDI happy. Set it
|
||||
* here (always 1, i.e., out first pixel format) where appropriate.
|
||||
|
@@ -132,6 +132,11 @@ struct stw_framebuffer
|
||||
int swap_interval;
|
||||
int64_t prev_swap_time;
|
||||
|
||||
#ifdef _GAMING_XBOX
|
||||
/* For the WndProc hook chain */
|
||||
WNDPROC prev_wndproc;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This is protected by stw_device::fb_mutex, not the mutex above.
|
||||
*
|
||||
|
75
src/gallium/frontends/wgl/stw_gdishim.c
Normal file
75
src/gallium/frontends/wgl/stw_gdishim.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Certain Win32-like platforms (i.e. Xbox GDK) do not support the GDI library.
|
||||
* stw_gdishim acts as a shim layer to provide the APIs required for gallium.
|
||||
*/
|
||||
|
||||
#include "stw_gdishim.h"
|
||||
#include "stw_pixelformat.h"
|
||||
#include "stw_framebuffer.h"
|
||||
|
||||
int GetPixelFormat(HDC hdc)
|
||||
{
|
||||
return stw_pixelformat_get(hdc);
|
||||
}
|
||||
|
||||
int DescribePixelFormat(
|
||||
HDC hdc,
|
||||
int iPixelFormat,
|
||||
UINT nBytes,
|
||||
LPPIXELFORMATDESCRIPTOR ppfd
|
||||
)
|
||||
{
|
||||
if (iPixelFormat >= stw_pixelformat_get_count(hdc))
|
||||
return 0;
|
||||
|
||||
const struct stw_pixelformat_info* info = stw_pixelformat_get_info(iPixelFormat);
|
||||
memcpy(ppfd, &info->pfd, nBytes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL SetPixelFormat(
|
||||
HDC hdc,
|
||||
int format,
|
||||
const PIXELFORMATDESCRIPTOR* ppfd
|
||||
)
|
||||
{
|
||||
// TODO: can we support this?
|
||||
#if 0
|
||||
struct stw_framebuffer* fb;
|
||||
|
||||
fb = stw_framebuffer_from_hdc(hdc);
|
||||
if (fb && fb->pfi) {
|
||||
fb->pfi->iPixelFormat = format;
|
||||
stw_framebuffer_unlock(fb);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void StretchDIBits(HDC hdc, unsigned int xDest, unsigned int yDest, unsigned int DestWidth, unsigned int DestHeight, unsigned int xSrc, unsigned int ySrc, unsigned int SrcWidth, unsigned int SrcHeight, void* lpBits, void* lpbmi, unsigned int iUsage, DWORD rop)
|
||||
{
|
||||
|
||||
}
|
152
src/gallium/frontends/wgl/stw_gdishim.h
Normal file
152
src/gallium/frontends/wgl/stw_gdishim.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Certain Win32-like platforms (i.e. Xbox GDK) do not support the GDI library.
|
||||
* stw_gdishim acts as a shim layer to provide the APIs required for gallium.
|
||||
*/
|
||||
|
||||
#ifndef STW_GDISHIM_H
|
||||
#define STW_GDISHIM_H
|
||||
|
||||
#ifdef _GAMING_XBOX
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* Handles */
|
||||
typedef void* HMONITOR;
|
||||
|
||||
/* Stubs */
|
||||
#define WindowFromDC(hdc) (HWND)hdc
|
||||
#define GetDC(hwnd) (HDC)hwnd
|
||||
#define ReleaseDC(hwnd, hdc) 1
|
||||
|
||||
void StretchDIBits(HDC hdc, unsigned int xDest, unsigned int yDest, unsigned int DestWidth, unsigned int DestHeight, unsigned int xSrc, unsigned int ySrc, unsigned int SrcWidth, unsigned int SrcHeight, void* lpBits, void* lpbmi, unsigned int iUsage, DWORD rop);
|
||||
|
||||
/* Layer plane descriptor */
|
||||
typedef struct tagLAYERPLANEDESCRIPTOR { // lpd
|
||||
WORD nSize;
|
||||
WORD nVersion;
|
||||
DWORD dwFlags;
|
||||
BYTE iPixelType;
|
||||
BYTE cColorBits;
|
||||
BYTE cRedBits;
|
||||
BYTE cRedShift;
|
||||
BYTE cGreenBits;
|
||||
BYTE cGreenShift;
|
||||
BYTE cBlueBits;
|
||||
BYTE cBlueShift;
|
||||
BYTE cAlphaBits;
|
||||
BYTE cAlphaShift;
|
||||
BYTE cAccumBits;
|
||||
BYTE cAccumRedBits;
|
||||
BYTE cAccumGreenBits;
|
||||
BYTE cAccumBlueBits;
|
||||
BYTE cAccumAlphaBits;
|
||||
BYTE cDepthBits;
|
||||
BYTE cStencilBits;
|
||||
BYTE cAuxBuffers;
|
||||
BYTE iLayerPlane;
|
||||
BYTE bReserved;
|
||||
COLORREF crTransparent;
|
||||
} LAYERPLANEDESCRIPTOR, * PLAYERPLANEDESCRIPTOR, FAR* LPLAYERPLANEDESCRIPTOR;
|
||||
|
||||
/* WGL */
|
||||
typedef struct _WGLSWAP
|
||||
{
|
||||
HDC hdc;
|
||||
UINT uiFlags;
|
||||
} WGLSWAP;
|
||||
|
||||
#define WGL_SWAPMULTIPLE_MAX 16
|
||||
|
||||
WINGDIAPI DWORD WINAPI
|
||||
wglSwapMultipleBuffers(UINT n,
|
||||
CONST WGLSWAP* ps);
|
||||
|
||||
WINGDIAPI BOOL WINAPI wglDeleteContext(HGLRC);
|
||||
|
||||
/* wglSwapLayerBuffers flags */
|
||||
#define WGL_SWAP_MAIN_PLANE 0x00000001
|
||||
|
||||
/* Pixel format descriptor */
|
||||
typedef struct tagPIXELFORMATDESCRIPTOR
|
||||
{
|
||||
WORD nSize;
|
||||
WORD nVersion;
|
||||
DWORD dwFlags;
|
||||
BYTE iPixelType;
|
||||
BYTE cColorBits;
|
||||
BYTE cRedBits;
|
||||
BYTE cRedShift;
|
||||
BYTE cGreenBits;
|
||||
BYTE cGreenShift;
|
||||
BYTE cBlueBits;
|
||||
BYTE cBlueShift;
|
||||
BYTE cAlphaBits;
|
||||
BYTE cAlphaShift;
|
||||
BYTE cAccumBits;
|
||||
BYTE cAccumRedBits;
|
||||
BYTE cAccumGreenBits;
|
||||
BYTE cAccumBlueBits;
|
||||
BYTE cAccumAlphaBits;
|
||||
BYTE cDepthBits;
|
||||
BYTE cStencilBits;
|
||||
BYTE cAuxBuffers;
|
||||
BYTE iLayerType;
|
||||
BYTE bReserved;
|
||||
DWORD dwLayerMask;
|
||||
DWORD dwVisibleMask;
|
||||
DWORD dwDamageMask;
|
||||
} PIXELFORMATDESCRIPTOR, * PPIXELFORMATDESCRIPTOR, FAR* LPPIXELFORMATDESCRIPTOR;
|
||||
|
||||
/* Bitmap Info */
|
||||
typedef struct tagRGBQUAD {
|
||||
BYTE rgbBlue;
|
||||
BYTE rgbGreen;
|
||||
BYTE rgbRed;
|
||||
BYTE rgbReserved;
|
||||
} RGBQUAD;
|
||||
|
||||
typedef struct tagBITMAPINFO {
|
||||
BITMAPINFOHEADER bmiHeader;
|
||||
RGBQUAD bmiColors[1];
|
||||
} BITMAPINFO, * LPBITMAPINFO, * PBITMAPINFO;
|
||||
|
||||
/* Glyph Info */
|
||||
|
||||
typedef struct tagGLYPHMETRICSFLOAT {
|
||||
FLOAT gmfBlackBoxX;
|
||||
FLOAT gmfBlackBoxY;
|
||||
#ifndef _GAMING_XBOX
|
||||
POINTFLOAT gmfptGlyphOrigin;
|
||||
#else
|
||||
FLOAT gmfptGlyphOriginX;
|
||||
FLOAT gmfptGlyphOriginY;
|
||||
#endif
|
||||
FLOAT gmfCellIncX;
|
||||
FLOAT gmfCellIncY;
|
||||
} GLYPHMETRICSFLOAT, *PGLYPHMETRICSFLOAT, *LPGLYPHMETRICSFLOAT;
|
||||
|
||||
#endif /* _GAMING_XBOX */
|
||||
|
||||
#endif /* STW_PIXELFORMAT_H */
|
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "glapi/glapi.h"
|
||||
#include "stw_device.h"
|
||||
#include "stw_gdishim.h"
|
||||
#include "gldrv.h"
|
||||
#include "stw_nopfuncs.h"
|
||||
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include "stw_gdishim.h"
|
||||
#include "gldrv.h"
|
||||
#include "stw_device.h"
|
||||
#include "stw_framebuffer.h"
|
||||
|
@@ -73,6 +73,7 @@ stw_tls_init(void)
|
||||
* XXX: Except for the current thread since it there is an explicit
|
||||
* stw_tls_init_thread() call for it later on.
|
||||
*/
|
||||
#ifndef _GAMING_XBOX
|
||||
if (1) {
|
||||
DWORD dwCurrentProcessId = GetCurrentProcessId();
|
||||
DWORD dwCurrentThreadId = GetCurrentThreadId();
|
||||
@@ -103,6 +104,7 @@ stw_tls_init(void)
|
||||
CloseHandle(hSnapshot);
|
||||
}
|
||||
}
|
||||
#endif /* _GAMING_XBOX */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -127,10 +129,14 @@ stw_tls_data_create(DWORD dwThreadId)
|
||||
|
||||
data->dwThreadId = dwThreadId;
|
||||
|
||||
#ifndef _GAMING_XBOX
|
||||
data->hCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC,
|
||||
stw_call_window_proc,
|
||||
NULL,
|
||||
dwThreadId);
|
||||
#else
|
||||
data->hCallWndProcHook = NULL;
|
||||
#endif
|
||||
if (data->hCallWndProcHook == NULL) {
|
||||
goto no_hook;
|
||||
}
|
||||
@@ -161,10 +167,12 @@ stw_tls_data_destroy(struct stw_tls_data *data)
|
||||
debug_printf("%s(0x%04lx)\n", __func__, data->dwThreadId);
|
||||
}
|
||||
|
||||
#ifndef _GAMING_XBOX
|
||||
if (data->hCallWndProcHook) {
|
||||
UnhookWindowsHookEx(data->hCallWndProcHook);
|
||||
data->hCallWndProcHook = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
@@ -42,6 +42,7 @@
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include "util/u_debug.h"
|
||||
#include "stw_gdishim.h"
|
||||
#include "gldrv.h"
|
||||
#include "stw_context.h"
|
||||
#include "stw_pixelformat.h"
|
||||
@@ -223,6 +224,7 @@ wglUseFontBitmapsW(
|
||||
DWORD count,
|
||||
DWORD listBase )
|
||||
{
|
||||
#ifndef _GAMING_XBOX
|
||||
GLYPHMETRICS gm;
|
||||
MAT2 tra;
|
||||
FIXED one, minus_one, zero;
|
||||
@@ -273,6 +275,9 @@ wglUseFontBitmapsW(
|
||||
free(buffer);
|
||||
|
||||
return result;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif /* _GAMING_XBOX */
|
||||
}
|
||||
|
||||
WINGDIAPI BOOL APIENTRY
|
||||
|
294
src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer_xbox.cpp
Normal file
294
src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer_xbox.cpp
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "d3d12_wgl_public.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <windows.h>
|
||||
#include <wrl.h>
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "frontend/api.h"
|
||||
#include "frontend/winsys_handle.h"
|
||||
|
||||
#include "stw_device.h"
|
||||
#include "stw_pixelformat.h"
|
||||
#include "stw_winsys.h"
|
||||
|
||||
#include "d3d12/d3d12_format.h"
|
||||
#include "d3d12/d3d12_resource.h"
|
||||
#include "d3d12/d3d12_screen.h"
|
||||
|
||||
constexpr uint32_t num_buffers = 2;
|
||||
static int current_backbuffer_index = 0;
|
||||
static bool has_signaled_first_time = false;
|
||||
static int cached_interval = 1;
|
||||
|
||||
struct d3d12_wgl_framebuffer {
|
||||
struct stw_winsys_framebuffer base;
|
||||
|
||||
struct d3d12_screen *screen;
|
||||
enum pipe_format pformat;
|
||||
ID3D12Resource *images[num_buffers];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvs[num_buffers];
|
||||
ID3D12DescriptorHeap *rtvHeap;
|
||||
pipe_resource *buffers[num_buffers];
|
||||
};
|
||||
|
||||
static struct d3d12_wgl_framebuffer*
|
||||
d3d12_wgl_framebuffer(struct stw_winsys_framebuffer *fb)
|
||||
{
|
||||
return (struct d3d12_wgl_framebuffer *) fb;
|
||||
}
|
||||
|
||||
static void
|
||||
d3d12_wgl_framebuffer_destroy(struct stw_winsys_framebuffer *fb,
|
||||
pipe_context *ctx)
|
||||
{
|
||||
struct d3d12_wgl_framebuffer *framebuffer = d3d12_wgl_framebuffer(fb);
|
||||
struct pipe_fence_handle *fence = NULL;
|
||||
|
||||
if (ctx) {
|
||||
/* Ensure all resources are flushed */
|
||||
ctx->flush(ctx, &fence, PIPE_FLUSH_HINT_FINISH);
|
||||
if (fence) {
|
||||
ctx->screen->fence_finish(ctx->screen, ctx, fence, PIPE_TIMEOUT_INFINITE);
|
||||
ctx->screen->fence_reference(ctx->screen, &fence, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
framebuffer->rtvHeap->Release();
|
||||
for (int i = 0; i < num_buffers; ++i) {
|
||||
if (framebuffer->buffers[i]) {
|
||||
d3d12_resource_release(d3d12_resource(framebuffer->buffers[i]));
|
||||
pipe_resource_reference(&framebuffer->buffers[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
delete framebuffer;
|
||||
}
|
||||
|
||||
static void
|
||||
d3d12_wgl_framebuffer_resize(stw_winsys_framebuffer *fb,
|
||||
pipe_context *ctx,
|
||||
pipe_resource *templ)
|
||||
{
|
||||
struct d3d12_wgl_framebuffer *framebuffer = d3d12_wgl_framebuffer(fb);
|
||||
|
||||
if (framebuffer->rtvHeap == NULL) {
|
||||
D3D12_DESCRIPTOR_HEAP_DESC descHeapDesc = {};
|
||||
descHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
descHeapDesc.NumDescriptors = num_buffers;
|
||||
framebuffer->screen->dev->CreateDescriptorHeap(&descHeapDesc,
|
||||
IID_PPV_ARGS(&framebuffer->rtvHeap));
|
||||
}
|
||||
|
||||
// Release the old images
|
||||
for (int i = 0; i < num_buffers; i++) {
|
||||
if (framebuffer->buffers[i]) {
|
||||
d3d12_resource_release(d3d12_resource(framebuffer->buffers[i]));
|
||||
pipe_resource_reference(&framebuffer->buffers[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_HEAP_PROPERTIES heapProps = {};
|
||||
heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
|
||||
D3D12_RESOURCE_DESC resDesc;
|
||||
resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
resDesc.Width = templ->width0;
|
||||
resDesc.Height = templ->height0;
|
||||
resDesc.Alignment = 0;
|
||||
resDesc.DepthOrArraySize = 1;
|
||||
resDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
resDesc.Format = d3d12_get_format(templ->format);
|
||||
resDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
resDesc.MipLevels = 1;
|
||||
resDesc.SampleDesc.Count = 1;
|
||||
resDesc.SampleDesc.Quality = 0;
|
||||
|
||||
D3D12_CLEAR_VALUE optimizedClearValue = {};
|
||||
optimizedClearValue.Format = resDesc.Format;
|
||||
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {};
|
||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||
rtvDesc.Format = resDesc.Format;
|
||||
rtvDesc.Texture2D.MipSlice = 0;
|
||||
rtvDesc.Texture2D.PlaneSlice = 0;
|
||||
|
||||
for (int i = 0; i < num_buffers; i++) {
|
||||
if (FAILED(framebuffer->screen->dev->CreateCommittedResource(
|
||||
&heapProps,
|
||||
D3D12_HEAP_FLAG_ALLOW_DISPLAY,
|
||||
&resDesc,
|
||||
D3D12_RESOURCE_STATE_PRESENT,
|
||||
&optimizedClearValue,
|
||||
IID_PPV_ARGS(&framebuffer->images[i])
|
||||
))) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
framebuffer->rtvs[i].ptr =
|
||||
framebuffer->rtvHeap->GetCPUDescriptorHandleForHeapStart().ptr +
|
||||
((int64_t)i * framebuffer->screen->dev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV));
|
||||
|
||||
framebuffer->screen->dev->CreateRenderTargetView(
|
||||
framebuffer->images[i],
|
||||
&rtvDesc,
|
||||
framebuffer->rtvs[i]
|
||||
);
|
||||
}
|
||||
|
||||
framebuffer->pformat = templ->format;
|
||||
}
|
||||
|
||||
static boolean
|
||||
d3d12_wgl_framebuffer_present(stw_winsys_framebuffer *fb, int interval)
|
||||
{
|
||||
auto framebuffer = d3d12_wgl_framebuffer(fb);
|
||||
D3D12XBOX_PRESENT_PLANE_PARAMETERS planeParams = {};
|
||||
planeParams.Token = framebuffer->screen->frame_token;
|
||||
planeParams.ResourceCount = 1;
|
||||
planeParams.ppResources = &framebuffer->images[current_backbuffer_index];
|
||||
|
||||
D3D12XBOX_PRESENT_PARAMETERS presentParams = {};
|
||||
presentParams.Flags = (interval == 0) ?
|
||||
D3D12XBOX_PRESENT_FLAG_IMMEDIATE :
|
||||
D3D12XBOX_PRESENT_FLAG_NONE;
|
||||
|
||||
if (cached_interval != interval) {
|
||||
framebuffer->screen->dev->SetFrameIntervalX(
|
||||
nullptr,
|
||||
D3D12XBOX_FRAME_INTERVAL_60_HZ,
|
||||
interval,
|
||||
D3D12XBOX_FRAME_INTERVAL_FLAG_NONE
|
||||
);
|
||||
cached_interval = interval;
|
||||
}
|
||||
|
||||
framebuffer->screen->cmdqueue->PresentX(1, &planeParams, &presentParams);
|
||||
|
||||
current_backbuffer_index = !current_backbuffer_index;
|
||||
|
||||
framebuffer->screen->frame_token = D3D12XBOX_FRAME_PIPELINE_TOKEN_NULL;
|
||||
framebuffer->screen->dev->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE,
|
||||
nullptr, D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE,
|
||||
&framebuffer->screen->frame_token);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct pipe_resource*
|
||||
d3d12_wgl_framebuffer_get_resource(struct stw_winsys_framebuffer *pframebuffer,
|
||||
st_attachment_type statt)
|
||||
{
|
||||
auto framebuffer = d3d12_wgl_framebuffer(pframebuffer);
|
||||
auto pscreen = &framebuffer->screen->base;
|
||||
|
||||
UINT index = current_backbuffer_index;
|
||||
if (statt == ST_ATTACHMENT_FRONT_LEFT)
|
||||
index = !index;
|
||||
|
||||
if (framebuffer->buffers[index]) {
|
||||
pipe_reference(NULL, &framebuffer->buffers[index]->reference);
|
||||
return framebuffer->buffers[index];
|
||||
}
|
||||
|
||||
ID3D12Resource *res = framebuffer->images[index];
|
||||
|
||||
struct winsys_handle handle;
|
||||
memset(&handle, 0, sizeof(handle));
|
||||
handle.type = WINSYS_HANDLE_TYPE_D3D12_RES;
|
||||
handle.format = framebuffer->pformat;
|
||||
handle.com_obj = res;
|
||||
|
||||
D3D12_RESOURCE_DESC res_desc = GetDesc(res);
|
||||
|
||||
struct pipe_resource templ;
|
||||
memset(&templ, 0, sizeof(templ));
|
||||
templ.target = PIPE_TEXTURE_2D;
|
||||
templ.format = framebuffer->pformat;
|
||||
templ.width0 = res_desc.Width;
|
||||
templ.height0 = res_desc.Height;
|
||||
templ.depth0 = 1;
|
||||
templ.array_size = res_desc.DepthOrArraySize;
|
||||
templ.nr_samples = res_desc.SampleDesc.Count;
|
||||
templ.last_level = res_desc.MipLevels - 1;
|
||||
templ.bind = PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_RENDER_TARGET;
|
||||
templ.usage = PIPE_USAGE_DEFAULT;
|
||||
templ.flags = 0;
|
||||
|
||||
pipe_resource_reference(&framebuffer->buffers[index],
|
||||
pscreen->resource_from_handle(pscreen, &templ, &handle,
|
||||
PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE));
|
||||
return framebuffer->buffers[index];
|
||||
}
|
||||
|
||||
struct stw_winsys_framebuffer*
|
||||
d3d12_wgl_create_framebuffer(struct pipe_screen *screen,
|
||||
HWND hWnd,
|
||||
int iPixelFormat)
|
||||
{
|
||||
const struct stw_pixelformat_info *pfi =
|
||||
stw_pixelformat_get_info(iPixelFormat);
|
||||
if (!(pfi->pfd.dwFlags & PFD_DOUBLEBUFFER) ||
|
||||
(pfi->pfd.dwFlags & PFD_SUPPORT_GDI))
|
||||
return NULL;
|
||||
|
||||
struct d3d12_wgl_framebuffer *fb = CALLOC_STRUCT(d3d12_wgl_framebuffer);
|
||||
if (!fb)
|
||||
return NULL;
|
||||
|
||||
new (fb) struct d3d12_wgl_framebuffer();
|
||||
|
||||
fb->screen = d3d12_screen(screen);
|
||||
fb->images[0] = NULL;
|
||||
fb->images[1] = NULL;
|
||||
fb->rtvHeap = NULL;
|
||||
fb->base.destroy = d3d12_wgl_framebuffer_destroy;
|
||||
fb->base.resize = d3d12_wgl_framebuffer_resize;
|
||||
fb->base.present = d3d12_wgl_framebuffer_present;
|
||||
fb->base.get_resource = d3d12_wgl_framebuffer_get_resource;
|
||||
|
||||
// Xbox applications must manually handle Suspend/Resume events on the Command Queue.
|
||||
// To allow the application to access the queue, we store a pointer in the HWND's user data.
|
||||
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) fb->screen->cmdqueue);
|
||||
|
||||
// Schedule the frame interval and origin frame event
|
||||
fb->screen->dev->SetFrameIntervalX(
|
||||
nullptr,
|
||||
D3D12XBOX_FRAME_INTERVAL_60_HZ,
|
||||
cached_interval,
|
||||
D3D12XBOX_FRAME_INTERVAL_FLAG_NONE
|
||||
);
|
||||
fb->screen->dev->ScheduleFrameEventX(
|
||||
D3D12XBOX_FRAME_EVENT_ORIGIN,
|
||||
0,
|
||||
nullptr,
|
||||
D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE
|
||||
);
|
||||
|
||||
return &fb->base;
|
||||
}
|
@@ -19,10 +19,16 @@
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
|
||||
files_libd3d12winsys = files('d3d12_wgl_winsys.c')
|
||||
if target_machine.system().startswith('Gaming.Xbox')
|
||||
files_libd3d12winsys += files('d3d12_wgl_framebuffer_xbox.cpp')
|
||||
else
|
||||
files_libd3d12winsys += files('d3d12_wgl_framebuffer.cpp')
|
||||
endif
|
||||
|
||||
libd3d12winsys = static_library(
|
||||
'd3d12winsys',
|
||||
files('d3d12_wgl_framebuffer.cpp', 'd3d12_wgl_winsys.c'),
|
||||
files_libd3d12winsys,
|
||||
include_directories : [inc_src, inc_wgl, inc_include, inc_gallium, inc_gallium_aux, inc_gallium_drivers],
|
||||
dependencies : [dep_dxheaders, idep_nir_headers],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include "util/u_memory.h"
|
||||
#include "frontend/sw_winsys.h"
|
||||
#include "gdi_sw_winsys.h"
|
||||
#include "wgl/stw_gdishim.h"
|
||||
|
||||
|
||||
struct gdi_sw_displaytarget
|
||||
|
@@ -22,6 +22,6 @@ libwsgdi = static_library(
|
||||
'wsgdi',
|
||||
'gdi_sw_winsys.c',
|
||||
include_directories : [
|
||||
inc_src, inc_include, inc_gallium, inc_gallium_aux, inc_gallium_drivers,
|
||||
inc_src, inc_include, inc_gallium, inc_gallium_aux, inc_gallium_drivers, inc_frontends
|
||||
],
|
||||
)
|
||||
|
@@ -26,6 +26,7 @@ inc_gallium_aux = include_directories('gallium/auxiliary')
|
||||
inc_amd_common = include_directories('amd/common')
|
||||
inc_tool = include_directories('tool')
|
||||
inc_virtio_gpu = include_directories('virtio/virtio-gpu')
|
||||
inc_frontends = include_directories('gallium/frontends')
|
||||
pps_datasources = []
|
||||
pps_includes = []
|
||||
|
||||
|
Reference in New Issue
Block a user