x11drv/opengl: Pixel format rewrite.
This commit is contained in:
parent
e73890a72c
commit
59dc73b911
|
@ -200,6 +200,67 @@ inline static Font get_font( HDC hdc )
|
|||
return font;
|
||||
}
|
||||
|
||||
/* GLX can advertise dozens of different pixelformats including offscreen and onscreen ones.
|
||||
* In our WGL implementation we only support a subset of these formats namely the format of
|
||||
* Wine's main visual and offscreen formats (if they are available).
|
||||
* This function converts a WGL format to its corresponding GLX one. It returns the index (zero-based)
|
||||
* into the GLX FB config table and it returns the number of supported WGL formats in fmt_count.
|
||||
*/
|
||||
BOOL ConvertPixelFormatWGLtoGLX(Display *display, int iPixelFormat, int *fmt_index, int *fmt_count)
|
||||
{
|
||||
int res = FALSE;
|
||||
int i = 0;
|
||||
GLXFBConfig* cfgs = NULL;
|
||||
int nCfgs = 0;
|
||||
int tmp_fmt_id = 0;
|
||||
int tmp_vis_id = 0;
|
||||
int nFormats = 1; /* Start at 1 as we allways have a main visual */
|
||||
VisualID visualid = 0;
|
||||
|
||||
/* Request to look up the format of the main visual when iPixelFormat = 1 */
|
||||
if(iPixelFormat == 1) visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
|
||||
|
||||
/* As mentioned in various parts of the code only the format of the main visual can be used for onscreen rendering.
|
||||
* Next to this format there are also so called offscreen rendering formats (used for pbuffers) which can be supported
|
||||
* because they don't need a visual. Below we use glXGetFBConfigs instead of glXChooseFBConfig to enumerate the fb configurations
|
||||
* bas this call lists both types of formats instead of only onscreen ones. */
|
||||
cfgs = wine_glx.p_glXGetFBConfigs(display, DefaultScreen(display), &nCfgs);
|
||||
if (NULL == cfgs || 0 == nCfgs) {
|
||||
ERR("glXChooseFBConfig returns NULL\n");
|
||||
if(cfgs != NULL) XFree(cfgs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Find the requested offscreen format and count the number of offscreen formats */
|
||||
for(i=0; i<nCfgs; i++) {
|
||||
wine_glx.p_glXGetFBConfigAttrib(display, cfgs[i], GLX_VISUAL_ID, &tmp_vis_id);
|
||||
wine_glx.p_glXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &tmp_fmt_id);
|
||||
|
||||
/* We are looking up the GLX index of our main visual and have found it :) */
|
||||
if(iPixelFormat == 1 && visualid == tmp_vis_id) {
|
||||
*fmt_index = i;
|
||||
TRACE("Found FBCONFIG_ID 0x%x at index %d for VISUAL_ID 0x%x\n", tmp_fmt_id, *fmt_index, tmp_vis_id);
|
||||
res = TRUE;
|
||||
}
|
||||
/* We found an offscreen rendering format :) */
|
||||
else if(tmp_vis_id == 0) {
|
||||
nFormats++;
|
||||
TRACE("Checking offscreen format FBCONFIG_ID 0x%x at index %d\n", tmp_fmt_id, i);
|
||||
|
||||
if(iPixelFormat == nFormats) {
|
||||
*fmt_index = i;
|
||||
TRACE("Found offscreen format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", tmp_fmt_id, iPixelFormat, i);
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
*fmt_count = nFormats;
|
||||
TRACE("Number of offscreen formats: %d; returning index: %d\n", *fmt_count, *fmt_index);
|
||||
|
||||
if(cfgs != NULL) XFree(cfgs);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* wglCreateContext (OPENGL32.@)
|
||||
|
@ -207,26 +268,21 @@ inline static Font get_font( HDC hdc )
|
|||
HGLRC WINAPI wglCreateContext(HDC hdc)
|
||||
{
|
||||
Wine_GLContext *ret;
|
||||
int num;
|
||||
XVisualInfo template;
|
||||
XVisualInfo *vis = NULL;
|
||||
Display *display = get_display( hdc );
|
||||
int hdcPF = GetPixelFormat(hdc);
|
||||
int hdcPF = 1; /* We can only use the Wine's main visual which has an index of 1 */
|
||||
int tmp = 0;
|
||||
int fmt_index = 0;
|
||||
GLXFBConfig cur_cfg;
|
||||
|
||||
TRACE("(%p)->(PF:%d)\n", hdc, hdcPF);
|
||||
|
||||
/* First, get the visual in use by the X11DRV */
|
||||
if (!display) return 0;
|
||||
template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
|
||||
vis = XGetVisualInfo(display, VisualIDMask, &template, &num);
|
||||
|
||||
if (vis == NULL) {
|
||||
ERR("NULL visual !!!\n");
|
||||
/* Need to set errors here */
|
||||
return NULL;
|
||||
}
|
||||
if (0 >= hdcPF) {
|
||||
/* We can only render using the iPixelFormat (1) of Wine's Main visual, we need to get the correspondig GLX format.
|
||||
* If this fails something is very wrong on the system. */
|
||||
if(!ConvertPixelFormatWGLtoGLX(display, hdcPF, &tmp, &fmt_index)) {
|
||||
ERR("Cannot get FB Config for main iPixelFormat 1, expect problems!\n");
|
||||
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -242,12 +298,12 @@ HGLRC WINAPI wglCreateContext(HDC hdc)
|
|||
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
|
||||
return NULL;
|
||||
}
|
||||
if (nCfgs_fmt < hdcPF) {
|
||||
ERR("(%p): unexpected pixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, hdcPF, nCfgs_fmt);
|
||||
if (nCfgs_fmt < fmt_index) {
|
||||
ERR("(%p): unexpected pixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, fmt_index, nCfgs_fmt);
|
||||
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
|
||||
return NULL;
|
||||
}
|
||||
cur_cfg = cfgs_fmt[hdcPF - 1];
|
||||
cur_cfg = cfgs_fmt[fmt_index];
|
||||
gl_test = wine_glx.p_glXGetFBConfigAttrib(display, cur_cfg, GLX_FBCONFIG_ID, &value);
|
||||
if (gl_test) {
|
||||
ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
|
||||
|
|
|
@ -616,6 +616,8 @@ GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLa
|
|||
int hTest;
|
||||
int tmp;
|
||||
int curGLXAttr = 0;
|
||||
int nWGLFormats = 0;
|
||||
int fmt_index = 0;
|
||||
|
||||
TRACE("(%p, %d, %d, %d, %p, %p)\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues);
|
||||
|
||||
|
@ -630,13 +632,20 @@ GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLa
|
|||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* Convert the WGL pixelformat to a GLX one, if this fails then most likely the iPixelFormat isn't supoprted.
|
||||
* We don't have to fail yet as a program can specify an invaled iPixelFormat (lets say 0) if it wants to query
|
||||
* the number of supported WGL formats. Whether the iPixelFormat is valid is handled in the for-loop below. */
|
||||
if(!ConvertPixelFormatWGLtoGLX(display, iPixelFormat, &fmt_index, &nWGLFormats)) {
|
||||
ERR("Unable to convert iPixelFormat %d to a GLX one, expect problems!\n", iPixelFormat);
|
||||
}
|
||||
|
||||
for (i = 0; i < nAttributes; ++i) {
|
||||
const int curWGLAttr = piAttributes[i];
|
||||
TRACE("pAttr[%d] = %x\n", i, curWGLAttr);
|
||||
|
||||
switch (curWGLAttr) {
|
||||
case WGL_NUMBER_PIXEL_FORMATS_ARB:
|
||||
piValues[i] = nCfgs;
|
||||
piValues[i] = nWGLFormats;
|
||||
continue ;
|
||||
|
||||
case WGL_SUPPORT_OPENGL_ARB:
|
||||
|
@ -661,8 +670,10 @@ GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLa
|
|||
|
||||
case WGL_TRANSPARENT_ARB:
|
||||
curGLXAttr = GLX_TRANSPARENT_TYPE;
|
||||
if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
|
||||
curCfg = cfgs[iPixelFormat - 1];
|
||||
/* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of
|
||||
* supported WGLFormats and also check if the GLX fmt_index is valid. */
|
||||
if((iPixelFormat > nWGLFormats) || (fmt_index > nCfgs)) goto pix_error;
|
||||
curCfg = cfgs[fmt_index];
|
||||
hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
|
||||
if (hTest) goto get_error;
|
||||
piValues[i] = GL_FALSE;
|
||||
|
@ -671,8 +682,10 @@ GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLa
|
|||
|
||||
case WGL_PIXEL_TYPE_ARB:
|
||||
curGLXAttr = GLX_RENDER_TYPE;
|
||||
if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
|
||||
curCfg = cfgs[iPixelFormat - 1];
|
||||
/* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of
|
||||
* supported WGLFormats and also check if the GLX fmt_index is valid. */
|
||||
if((iPixelFormat > nWGLFormats) || (fmt_index > nCfgs)) goto pix_error;
|
||||
curCfg = cfgs[fmt_index];
|
||||
hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
|
||||
if (hTest) goto get_error;
|
||||
TRACE("WGL_PIXEL_TYPE_ARB: GLX_RENDER_TYPE = 0x%x\n", tmp);
|
||||
|
@ -688,8 +701,10 @@ GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLa
|
|||
|
||||
case WGL_COLOR_BITS_ARB:
|
||||
/** see ConvertAttribWGLtoGLX for explain */
|
||||
if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
|
||||
curCfg = cfgs[iPixelFormat - 1];
|
||||
/* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of
|
||||
* supported WGLFormats and also check if the GLX fmt_index is valid. */
|
||||
if((iPixelFormat > nWGLFormats) || (fmt_index > nCfgs)) goto pix_error;
|
||||
curCfg = cfgs[fmt_index];
|
||||
hTest = glXGetFBConfigAttrib(display, curCfg, GLX_BUFFER_SIZE, piValues + i);
|
||||
if (hTest) goto get_error;
|
||||
TRACE("WGL_COLOR_BITS_ARB: GLX_BUFFER_SIZE = %d\n", piValues[i]);
|
||||
|
@ -714,8 +729,10 @@ GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLa
|
|||
continue ;
|
||||
}
|
||||
curGLXAttr = GLX_RENDER_TYPE;
|
||||
if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
|
||||
curCfg = cfgs[iPixelFormat - 1];
|
||||
/* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of
|
||||
* supported WGLFormats and also check if the GLX fmt_index is valid. */
|
||||
if((iPixelFormat > nWGLFormats) || (fmt_index > nCfgs)) goto pix_error;
|
||||
curCfg = cfgs[fmt_index];
|
||||
hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
|
||||
if (hTest) goto get_error;
|
||||
if (GLX_COLOR_INDEX_BIT == tmp) {
|
||||
|
@ -779,8 +796,10 @@ GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLa
|
|||
}
|
||||
|
||||
if (0 != curGLXAttr) {
|
||||
if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
|
||||
curCfg = cfgs[iPixelFormat - 1];
|
||||
/* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of
|
||||
* supported WGLFormats and also check if the GLX fmt_index is valid. */
|
||||
if((iPixelFormat > 0) && ((iPixelFormat > nWGLFormats) || (fmt_index > nCfgs))) goto pix_error;
|
||||
curCfg = cfgs[fmt_index];
|
||||
hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, piValues + i);
|
||||
if (hTest) goto get_error;
|
||||
} else {
|
||||
|
@ -815,6 +834,10 @@ GLboolean WINAPI wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, cons
|
|||
int gl_test = 0;
|
||||
int attribs[256];
|
||||
int nAttribs = 0;
|
||||
GLboolean res = FALSE;
|
||||
|
||||
/* We need the visualid to check if the format is suitable */
|
||||
VisualID visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
|
||||
|
||||
GLXFBConfig* cfgs = NULL;
|
||||
int nCfgs = 0;
|
||||
|
@ -825,8 +848,10 @@ GLboolean WINAPI wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, cons
|
|||
int nCfgs_fmt = 0;
|
||||
UINT it_fmt;
|
||||
int tmp_fmt_id;
|
||||
int tmp_vis_id;
|
||||
|
||||
int pfmt_it = 0;
|
||||
int offscreen_index = 1; /* Start at one because we allways have a main visual at iPixelFormat=1 */
|
||||
|
||||
TRACE("(%p, %p, %p, %d, %p, %p): hackish\n", hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats);
|
||||
if (NULL != pfAttribFList) {
|
||||
|
@ -840,12 +865,14 @@ GLboolean WINAPI wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, cons
|
|||
}
|
||||
PUSH1(attribs, None);
|
||||
|
||||
/* Search for FB configurations matching the requirements in attribs */
|
||||
cfgs = glXChooseFBConfig(display, DefaultScreen(display), attribs, &nCfgs);
|
||||
if (NULL == cfgs) {
|
||||
WARN("Compatible Pixel Format not found\n");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* Get a list of all FB configurations */
|
||||
cfgs_fmt = glXGetFBConfigs(display, DefaultScreen(display), &nCfgs_fmt);
|
||||
if (NULL == cfgs_fmt) {
|
||||
ERR("Failed to get All FB Configs\n");
|
||||
|
@ -853,21 +880,60 @@ GLboolean WINAPI wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, cons
|
|||
return GL_FALSE;
|
||||
}
|
||||
|
||||
for (it = 0; it < nMaxFormats && it < nCfgs; ++it) {
|
||||
/* Loop through all matching formats and check if they are suitable.
|
||||
* Note that this function should at max return nMaxFormats different formats */
|
||||
for (it = 0; pfmt_it < nMaxFormats && it < nCfgs; ++it) {
|
||||
gl_test = glXGetFBConfigAttrib(display, cfgs[it], GLX_FBCONFIG_ID, &fmt_id);
|
||||
if (gl_test) {
|
||||
ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
|
||||
continue ;
|
||||
}
|
||||
|
||||
gl_test = glXGetFBConfigAttrib(display, cfgs[it], GLX_VISUAL_ID, &tmp_vis_id);
|
||||
if (gl_test) {
|
||||
ERR("Failed to retrieve VISUAL_ID from GLXFBConfig, expect problems.\n");
|
||||
continue ;
|
||||
}
|
||||
|
||||
/* When the visualid of the GLXFBConfig matches the one of the main visual we have found our
|
||||
* only supported onscreen rendering format. This format has a WGL index of 1. */
|
||||
if(tmp_vis_id == visualid) {
|
||||
piFormats[pfmt_it] = 1;
|
||||
++pfmt_it;
|
||||
res = GL_TRUE;
|
||||
TRACE("Found compatible GLXFBConfig 0x%x with WGL index 1\n", fmt_id);
|
||||
continue;
|
||||
}
|
||||
/* Only continue with this loop for offscreen rendering formats (visualid = 0) */
|
||||
else if(tmp_vis_id != 0) {
|
||||
TRACE("Discarded GLXFBConfig %0x with VisualID %x because the visualid is not the same as our main visual (%lx)\n", fmt_id, tmp_vis_id, visualid);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find the index of the found format in the whole format table */
|
||||
for (it_fmt = 0; it_fmt < nCfgs_fmt; ++it_fmt) {
|
||||
gl_test = glXGetFBConfigAttrib(display, cfgs_fmt[it_fmt], GLX_FBCONFIG_ID, &tmp_fmt_id);
|
||||
if (gl_test) {
|
||||
ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
|
||||
continue ;
|
||||
}
|
||||
gl_test = glXGetFBConfigAttrib(display, cfgs[it], GLX_VISUAL_ID, &tmp_vis_id);
|
||||
if (gl_test) {
|
||||
ERR("Failed to retrieve VISUAL_ID from GLXFBConfig, expect problems.\n");
|
||||
continue ;
|
||||
}
|
||||
/* The format of Wine's main visual is stored at index 1 of our WGL format table.
|
||||
* At higher indices we store offscreen rendering formats (visualid=0). Below we calculate
|
||||
* the index of the offscreen format. We do this by counting the number of offscreen formats
|
||||
* which we see upto reaching our target format. */
|
||||
if(tmp_vis_id == 0)
|
||||
offscreen_index++;
|
||||
|
||||
/* We have found the format in the table (note the format is offscreen) */
|
||||
if (fmt_id == tmp_fmt_id) {
|
||||
int tmp;
|
||||
piFormats[pfmt_it] = it_fmt + 1;
|
||||
|
||||
piFormats[pfmt_it] = offscreen_index + 1; /* Add 1 to get a one-based index */
|
||||
++pfmt_it;
|
||||
glXGetFBConfigAttrib(display, cfgs_fmt[it_fmt], GLX_ALPHA_SIZE, &tmp);
|
||||
TRACE("ALPHA_SIZE of FBCONFIG_ID(%d/%d) found as '%d'\n", it_fmt + 1, nCfgs_fmt, tmp);
|
||||
|
@ -897,13 +963,14 @@ HPBUFFERARB WINAPI wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, in
|
|||
int nCfgs = 0;
|
||||
int attribs[256];
|
||||
unsigned nAttribs = 0;
|
||||
int fmt_index = 0;
|
||||
|
||||
TRACE("(%p, %d, %d, %d, %p)\n", hdc, iPixelFormat, iWidth, iHeight, piAttribList);
|
||||
|
||||
if (0 >= iPixelFormat) {
|
||||
ERR("(%p): unexpected iPixelFormat(%d) <= 0, returns NULL\n", hdc, iPixelFormat);
|
||||
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
|
||||
return NULL; /* unespected error */
|
||||
return NULL; /* unexpected error */
|
||||
}
|
||||
|
||||
cfgs = glXGetFBConfigs(display, DefaultScreen(display), &nCfgs);
|
||||
|
@ -911,24 +978,25 @@ HPBUFFERARB WINAPI wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, in
|
|||
if (NULL == cfgs || 0 == nCfgs) {
|
||||
ERR("(%p): Cannot get FB Configs for iPixelFormat(%d), returns NULL\n", hdc, iPixelFormat);
|
||||
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
|
||||
return NULL; /* unespected error */
|
||||
return NULL; /* unexpected error */
|
||||
}
|
||||
if (nCfgs < iPixelFormat) {
|
||||
|
||||
/* Convert the WGL pixelformat to a GLX format, if it fails then the format is invalid */
|
||||
if(!ConvertPixelFormatWGLtoGLX(display, iPixelFormat, &fmt_index, &nCfgs)) {
|
||||
ERR("(%p): unexpected iPixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, iPixelFormat, nCfgs);
|
||||
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
|
||||
goto create_failed; /* unespected error */
|
||||
goto create_failed; /* unexpected error */
|
||||
}
|
||||
|
||||
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLPBuffer));
|
||||
if (NULL == object) {
|
||||
SetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
||||
goto create_failed; /* unespected error */
|
||||
goto create_failed; /* unexpected error */
|
||||
}
|
||||
object->hdc = hdc;
|
||||
object->display = display;
|
||||
object->width = iWidth;
|
||||
object->height = iHeight;
|
||||
object->pixelFormat = iPixelFormat;
|
||||
|
||||
nAttribs = ConvertAttribWGLtoGLX(piAttribList, attribs, object);
|
||||
if (-1 == nAttribs) {
|
||||
|
@ -937,7 +1005,6 @@ HPBUFFERARB WINAPI wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, in
|
|||
}
|
||||
PUSH2(attribs, GLX_PBUFFER_WIDTH, iWidth);
|
||||
PUSH2(attribs, GLX_PBUFFER_HEIGHT, iHeight);
|
||||
|
||||
while (0 != *piAttribList) {
|
||||
int attr_v;
|
||||
switch (*piAttribList) {
|
||||
|
@ -1063,12 +1130,11 @@ HPBUFFERARB WINAPI wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, in
|
|||
}
|
||||
|
||||
PUSH1(attribs, None);
|
||||
|
||||
object->drawable = glXCreatePbuffer(display, cfgs[iPixelFormat - 1], attribs);
|
||||
object->drawable = glXCreatePbuffer(display, cfgs[fmt_index], attribs);
|
||||
TRACE("new Pbuffer drawable as %p\n", (void*) object->drawable);
|
||||
if (!object->drawable) {
|
||||
SetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
||||
goto create_failed; /* unespected error */
|
||||
goto create_failed; /* unexpected error */
|
||||
}
|
||||
TRACE("->(%p)\n", object);
|
||||
|
||||
|
@ -1092,7 +1158,10 @@ HDC WINAPI wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
|
|||
return NULL;
|
||||
}
|
||||
hDC = CreateCompatibleDC(object->hdc);
|
||||
SetPixelFormat(hDC, object->pixelFormat, NULL);
|
||||
|
||||
/* The function wglGetPbufferDCARB returns a DC to which the pbuffer can be connected.
|
||||
* We only support one onscreen rendering format (the one from the main visual), so use that. */
|
||||
SetPixelFormat(hDC, 1, NULL);
|
||||
set_drawable(hDC, object->drawable); /* works ?? */
|
||||
TRACE("(%p)->(%p)\n", hPbuffer, hDC);
|
||||
return hDC;
|
||||
|
|
|
@ -29,6 +29,9 @@ typedef void* (*glXGetProcAddressARB_t)(const GLubyte *);
|
|||
void wgl_ext_initialize_extensions(Display *display, int screen, glXGetProcAddressARB_t proc, const char* disabled_extensions);
|
||||
void wgl_ext_finalize_extensions(void);
|
||||
|
||||
/* Used to convert between WGL and GLX pixel formats in wglMakeCurrent and some WGL extensions */
|
||||
BOOL ConvertPixelFormatWGLtoGLX(Display *display, int iPixelFormat, int *fmt_index, int *fmt_count);
|
||||
|
||||
typedef struct {
|
||||
const char *func_name;
|
||||
void *func_address;
|
||||
|
|
|
@ -172,10 +172,42 @@ sym_not_found:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#define TEST_AND_ADD1(t,a) if (t) att_list[att_pos++] = (a)
|
||||
#define TEST_AND_ADD2(t,a,b) if (t) { att_list[att_pos++] = (a); att_list[att_pos++] = (b); }
|
||||
#define NULL_TEST_AND_ADD2(tv,a,b) att_list[att_pos++] = (a); att_list[att_pos++] = ((tv) == 0 ? 0 : (b))
|
||||
#define ADD2(a,b) att_list[att_pos++] = (a); att_list[att_pos++] = (b)
|
||||
static BOOL get_fbconfig_from_main_visual(int *fmt_id, int *fmt_index)
|
||||
{
|
||||
int nCfgs = 0;
|
||||
int tmp_fmt_id = 0;
|
||||
int tmp_vis_id = 0;
|
||||
int i = 0;
|
||||
GLXFBConfig* cfgs = NULL;
|
||||
|
||||
/* Retrieve the visualid from our main visual */
|
||||
VisualID visualid = XVisualIDFromVisual(visual);
|
||||
|
||||
cfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), NULL, &nCfgs);
|
||||
if (NULL == cfgs || 0 == nCfgs) {
|
||||
ERR("glXChooseFBConfig returns NULL (glError: %d)\n", pglGetError());
|
||||
if(cfgs != NULL) XFree(cfgs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Walk through all FB configurations to retrieve the FB configuration matching our visual */
|
||||
for(i=0; i<nCfgs; i++) {
|
||||
pglXGetFBConfigAttrib(gdi_display, cfgs[i], GLX_FBCONFIG_ID, &tmp_fmt_id);
|
||||
pglXGetFBConfigAttrib(gdi_display, cfgs[i], GLX_VISUAL_ID, &tmp_vis_id);
|
||||
if(tmp_vis_id == visualid) {
|
||||
*fmt_id = tmp_fmt_id;
|
||||
*fmt_index = i + 1; /* Use a one based index, iPixelFormat uses that too */
|
||||
TRACE("Found FBCONFIG_ID 0x%x at index %d for VISUAL_ID 0x%x\n", *fmt_id, *fmt_index, tmp_vis_id);
|
||||
if(cfgs != NULL) XFree(cfgs);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
ERR("Can't find a matching FBCONFIG_ID for VISUAL_ID 0x%lx!\n", visualid);
|
||||
|
||||
if(cfgs != NULL) XFree(cfgs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* X11DRV_ChoosePixelFormat
|
||||
|
@ -184,141 +216,104 @@ sym_not_found:
|
|||
*/
|
||||
int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
|
||||
const PIXELFORMATDESCRIPTOR *ppfd) {
|
||||
int att_list[64];
|
||||
int att_pos = 0;
|
||||
int att_pos_fac = 0;
|
||||
GLXFBConfig* cfgs = NULL;
|
||||
int ret = 0;
|
||||
int nCfgs = 0;
|
||||
int fmt_id = 0;
|
||||
int fmt_index = 0;
|
||||
|
||||
if (!has_opengl()) {
|
||||
ERR("No libGL on this box - disabling OpenGL support !\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (TRACE_ON(opengl)) {
|
||||
TRACE("(%p,%p)\n", physDev, ppfd);
|
||||
|
||||
dump_PIXELFORMATDESCRIPTOR((const PIXELFORMATDESCRIPTOR *) ppfd);
|
||||
}
|
||||
|
||||
/* Now, build the request to GLX */
|
||||
|
||||
if (ppfd->iPixelType == PFD_TYPE_COLORINDEX) {
|
||||
ADD2(GLX_BUFFER_SIZE, ppfd->cColorBits);
|
||||
}
|
||||
if (ppfd->iPixelType == PFD_TYPE_RGBA) {
|
||||
ADD2(GLX_RENDER_TYPE, GLX_RGBA_BIT);
|
||||
if (ppfd->dwFlags & PFD_DEPTH_DONTCARE) {
|
||||
ADD2(GLX_DEPTH_SIZE, GLX_DONT_CARE);
|
||||
} else {
|
||||
if (32 == ppfd->cDepthBits) {
|
||||
/**
|
||||
* for 32 bpp depth buffers force to use 24.
|
||||
* needed as some drivers don't support 32bpp
|
||||
*/
|
||||
TEST_AND_ADD2(ppfd->cDepthBits, GLX_DEPTH_SIZE, 24);
|
||||
} else {
|
||||
TEST_AND_ADD2(ppfd->cDepthBits, GLX_DEPTH_SIZE, ppfd->cDepthBits);
|
||||
}
|
||||
}
|
||||
if (32 == ppfd->cColorBits) {
|
||||
ADD2(GLX_RED_SIZE, 8);
|
||||
ADD2(GLX_GREEN_SIZE, 8);
|
||||
ADD2(GLX_BLUE_SIZE, 8);
|
||||
ADD2(GLX_ALPHA_SIZE, 8);
|
||||
} else {
|
||||
ADD2(GLX_BUFFER_SIZE, ppfd->cColorBits);
|
||||
/* Some broken apps try to ask for more than 8 bits of alpha */
|
||||
TEST_AND_ADD2(ppfd->cAlphaBits, GLX_ALPHA_SIZE, min(ppfd->cAlphaBits,8));
|
||||
}
|
||||
}
|
||||
TEST_AND_ADD2(ppfd->cStencilBits, GLX_STENCIL_SIZE, ppfd->cStencilBits);
|
||||
TEST_AND_ADD2(ppfd->cAuxBuffers, GLX_AUX_BUFFERS, ppfd->cAuxBuffers);
|
||||
|
||||
/* These flags are not supported yet...
|
||||
ADD2(GLX_ACCUM_SIZE, ppfd->cAccumBits);
|
||||
*/
|
||||
|
||||
/** facultative flags now */
|
||||
att_pos_fac = att_pos;
|
||||
if (ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) {
|
||||
ADD2(GLX_DOUBLEBUFFER, GLX_DONT_CARE);
|
||||
} else {
|
||||
ADD2(GLX_DOUBLEBUFFER, (ppfd->dwFlags & PFD_DOUBLEBUFFER) ? TRUE : FALSE);
|
||||
}
|
||||
if (ppfd->dwFlags & PFD_STEREO_DONTCARE) {
|
||||
ADD2(GLX_STEREO, GLX_DONT_CARE);
|
||||
} else {
|
||||
ADD2(GLX_STEREO, (ppfd->dwFlags & PFD_STEREO) ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
/** Attributes List End */
|
||||
att_list[att_pos] = None;
|
||||
|
||||
wine_tsx11_lock();
|
||||
{
|
||||
int nCfgs = 0;
|
||||
int gl_test = 0;
|
||||
int fmt_id;
|
||||
if(!visual) {
|
||||
ERR("Can't get an opengl visual!\n");
|
||||
goto choose_exit;
|
||||
}
|
||||
|
||||
GLXFBConfig* cfgs_fmt = NULL;
|
||||
int nCfgs_fmt = 0;
|
||||
int tmp_fmt_id;
|
||||
UINT it_fmt;
|
||||
/* Get a list containing all supported FB configurations */
|
||||
cfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), NULL, &nCfgs);
|
||||
if (NULL == cfgs || 0 == nCfgs) {
|
||||
ERR("glXChooseFBConfig returns NULL (glError: %d)\n", pglGetError());
|
||||
goto choose_exit;
|
||||
}
|
||||
|
||||
cfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), att_list, &nCfgs);
|
||||
/**
|
||||
* if we have facultative flags and we failed, try without
|
||||
* as MSDN said
|
||||
*
|
||||
* see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/opengl/ntopnglr_2qb8.asp
|
||||
*/
|
||||
if ((NULL == cfgs || 0 == nCfgs) && att_pos > att_pos_fac) {
|
||||
att_list[att_pos_fac] = None;
|
||||
cfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), att_list, &nCfgs);
|
||||
}
|
||||
/* In case an fbconfig was found, check if it matches to the requirements of the ppfd */
|
||||
if(!get_fbconfig_from_main_visual(&fmt_id, &fmt_index)) {
|
||||
ERR("Can't find a matching FBCONFIG_ID for VISUAL_ID 0x%lx!\n", visual->visualid);
|
||||
} else {
|
||||
int dwFlags = 0;
|
||||
int iPixelType = 0;
|
||||
int value = 0;
|
||||
|
||||
if (NULL == cfgs || 0 == nCfgs) {
|
||||
ERR("glXChooseFBConfig returns NULL (glError: %d)\n", pglGetError());
|
||||
ret = 0;
|
||||
goto choose_exit;
|
||||
}
|
||||
|
||||
gl_test = pglXGetFBConfigAttrib(gdi_display, cfgs[0], GLX_FBCONFIG_ID, &fmt_id);
|
||||
if (gl_test) {
|
||||
ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
|
||||
ret = 0;
|
||||
goto choose_exit;
|
||||
}
|
||||
|
||||
cfgs_fmt = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs_fmt);
|
||||
if (NULL == cfgs_fmt) {
|
||||
ERR("Failed to get All FB Configs\n");
|
||||
ret = 0;
|
||||
/* Pixel type */
|
||||
pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_RENDER_TYPE, &value);
|
||||
if (value & GLX_RGBA_BIT)
|
||||
iPixelType = PFD_TYPE_RGBA;
|
||||
else
|
||||
iPixelType = PFD_TYPE_COLORINDEX;
|
||||
|
||||
if (ppfd->iPixelType != iPixelType) {
|
||||
goto choose_exit;
|
||||
}
|
||||
|
||||
for (it_fmt = 0; it_fmt < nCfgs_fmt; ++it_fmt) {
|
||||
gl_test = pglXGetFBConfigAttrib(gdi_display, cfgs_fmt[it_fmt], GLX_FBCONFIG_ID, &tmp_fmt_id);
|
||||
if (gl_test) {
|
||||
ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
|
||||
XFree(cfgs_fmt);
|
||||
ret = 0;
|
||||
goto choose_exit;
|
||||
}
|
||||
if (fmt_id == tmp_fmt_id) {
|
||||
ret = it_fmt + 1;
|
||||
break ;
|
||||
/* Doublebuffer */
|
||||
pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_DOUBLEBUFFER, &value); if (value) dwFlags |= PFD_DOUBLEBUFFER;
|
||||
if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE)) {
|
||||
if ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (dwFlags & PFD_DOUBLEBUFFER)) {
|
||||
goto choose_exit;
|
||||
}
|
||||
}
|
||||
if (it_fmt == nCfgs_fmt) {
|
||||
ERR("Failed to get valid fmt for FBCONFIG_ID(%d)\n", fmt_id);
|
||||
ret = 0;
|
||||
|
||||
/* Stereo */
|
||||
pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_STEREO, &value); if (value) dwFlags |= PFD_STEREO;
|
||||
if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE)) {
|
||||
if ((ppfd->dwFlags & PFD_STEREO) != (dwFlags & PFD_STEREO)) {
|
||||
goto choose_exit;
|
||||
}
|
||||
}
|
||||
XFree(cfgs_fmt);
|
||||
|
||||
/* Alpha bits */
|
||||
pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_ALPHA_SIZE, &value);
|
||||
if (ppfd->iPixelType==PFD_TYPE_RGBA && ppfd->cAlphaBits && !value) {
|
||||
goto choose_exit;
|
||||
}
|
||||
|
||||
/* Depth bits */
|
||||
pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_DEPTH_SIZE, &value);
|
||||
if (ppfd->cDepthBits && !value) {
|
||||
goto choose_exit;
|
||||
}
|
||||
|
||||
/* Stencil bits */
|
||||
pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_STENCIL_SIZE, &value);
|
||||
if (ppfd->cStencilBits && !value) {
|
||||
goto choose_exit;
|
||||
}
|
||||
|
||||
/* Aux buffers */
|
||||
pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_AUX_BUFFERS, &value);
|
||||
if (ppfd->cAuxBuffers && !value) {
|
||||
goto choose_exit;
|
||||
}
|
||||
|
||||
/* When we pass all the checks we have found a matching format :) */
|
||||
ret = 1;
|
||||
TRACE("Succesfully found a matching mode, returning index: %d\n", ret);
|
||||
}
|
||||
|
||||
choose_exit:
|
||||
if(!ret)
|
||||
TRACE("No matching mode was found returning 0\n");
|
||||
|
||||
if (NULL != cfgs) XFree(cfgs);
|
||||
wine_tsx11_unlock();
|
||||
return ret;
|
||||
|
@ -358,6 +353,14 @@ int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev,
|
|||
return 0; /* unespected error */
|
||||
}
|
||||
|
||||
/* This function allways reports the total number of supported pixel formats.
|
||||
* At the moment we only support the pixel format corresponding to the main
|
||||
* visual which got created at x11drv initialization. More formats could be
|
||||
* supported if there was a way to recreate x11 windows in x11drv.
|
||||
* Because we only support one format nCfgs needs to be set to 1.
|
||||
*/
|
||||
nCfgs = 1;
|
||||
|
||||
if (ppfd == NULL) {
|
||||
/* The application is only querying the number of visuals */
|
||||
wine_tsx11_lock();
|
||||
|
@ -377,6 +380,12 @@ int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Retrieve the index in the FBConfig table corresponding to the visual ID from the main visual */
|
||||
if(!get_fbconfig_from_main_visual(&value, &iPixelFormat)) {
|
||||
ERR("Can't find a valid pixel format index from the main visual, expect problems!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = nCfgs;
|
||||
cur = cfgs[iPixelFormat - 1];
|
||||
|
||||
|
@ -481,6 +490,15 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
|
|||
const PIXELFORMATDESCRIPTOR *ppfd) {
|
||||
TRACE("(%p,%d,%p)\n", physDev, iPixelFormat, ppfd);
|
||||
|
||||
/* At the moment we only support the pixelformat corresponding to the main
|
||||
* x11drv visual which got created at x11drv initialization. More formats
|
||||
* can be supported if there was a way to recreate x11 windows in x11drv
|
||||
*/
|
||||
if(iPixelFormat != 1) {
|
||||
TRACE("Invalid iPixelFormat: %d\n", iPixelFormat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
physDev->current_pf = iPixelFormat;
|
||||
|
||||
if (TRACE_ON(opengl)) {
|
||||
|
@ -490,6 +508,11 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
|
|||
int value;
|
||||
int gl_test = 0;
|
||||
|
||||
if(!get_fbconfig_from_main_visual(&value, &iPixelFormat)) {
|
||||
ERR("Can't find a valid pixel format index from the main visual, expect problems!\n");
|
||||
return TRUE; /* Return true because the SetPixelFormat stuff itself passed */
|
||||
}
|
||||
|
||||
/*
|
||||
* How to test if hdc current drawable is compatible (visual/FBConfig) ?
|
||||
*
|
||||
|
@ -530,17 +553,15 @@ static XID create_glxpixmap(X11DRV_PDEVICE *physDev)
|
|||
XVisualInfo *vis;
|
||||
XVisualInfo template;
|
||||
int num;
|
||||
GLXFBConfig *cfgs;
|
||||
|
||||
wine_tsx11_lock();
|
||||
cfgs = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &num);
|
||||
pglXGetFBConfigAttrib(gdi_display, cfgs[physDev->current_pf - 1], GLX_VISUAL_ID, (int *)&template.visualid);
|
||||
|
||||
/* Retrieve the visualid from our main visual which is the only visual we can use */
|
||||
template.visualid = XVisualIDFromVisual(visual);
|
||||
vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num);
|
||||
|
||||
ret = pglXCreateGLXPixmap(gdi_display, vis, physDev->bitmap->pixmap);
|
||||
XFree(vis);
|
||||
XFree(cfgs);
|
||||
wine_tsx11_unlock();
|
||||
TRACE("return %lx\n", ret);
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue