wined3d: Prepare pbuffer code for WGL transition.

This commit is contained in:
Roderick Colenbrander 2007-08-06 20:53:20 +02:00 committed by Alexandre Julliard
parent 107ff2057d
commit 58275065a1
3 changed files with 26 additions and 265 deletions

View file

@ -108,86 +108,6 @@ static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, Display *disp
return This->contexts[This->numContexts - 1];
}
/* Returns an array of compatible FBconfig(s).
* The array must be freed with XFree. Requires ENTER_GL()
*/
static GLXFBConfig* pbuffer_find_fbconfigs(
IWineD3DDeviceImpl* This,
IWineD3DSurfaceImpl* RenderSurface,
Display *display) {
GLXFBConfig* cfgs = NULL;
int nCfgs = 0;
int attribs[256];
int nAttribs = 0;
IWineD3DSurface *StencilSurface = This->stencilBufferTarget;
WINED3DFORMAT BackBufferFormat = RenderSurface->resource.format;
WINED3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? ((IWineD3DSurfaceImpl *) StencilSurface)->resource.format : 0;
/* TODO:
* if StencilSurface == NULL && zBufferTarget != NULL then switch the zbuffer off,
* it StencilSurface != NULL && zBufferTarget == NULL switch it on
*/
#define PUSH1(att) attribs[nAttribs++] = (att);
#define PUSH2(att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
/* PUSH2(GLX_BIND_TO_TEXTURE_RGBA_ATI, True); examples of this are few and far between (but I've got a nice working one!)*/
PUSH2(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT);
PUSH2(GLX_X_RENDERABLE, TRUE);
PUSH2(GLX_DOUBLEBUFFER, TRUE);
TRACE("calling makeglcfg\n");
D3DFmtMakeGlCfg(BackBufferFormat, StencilBufferFormat, attribs, &nAttribs, FALSE /* alternate */);
PUSH1(None);
TRACE("calling chooseFGConfig\n");
cfgs = glXChooseFBConfig(display,
DefaultScreen(display),
attribs, &nCfgs);
if (cfgs == NULL) {
/* OK we didn't find the exact config, so use any reasonable match */
/* TODO: fill in the 'requested' and 'current' depths, and make sure that's
why we failed. */
static BOOL show_message = TRUE;
if (show_message) {
ERR("Failed to find exact match, finding alternative but you may "
"suffer performance issues, try changing xfree's depth to match the requested depth\n");
show_message = FALSE;
}
nAttribs = 0;
PUSH2(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT);
/* PUSH2(GLX_X_RENDERABLE, TRUE); */
PUSH2(GLX_RENDER_TYPE, GLX_RGBA_BIT);
PUSH2(GLX_DOUBLEBUFFER, FALSE);
TRACE("calling makeglcfg\n");
D3DFmtMakeGlCfg(BackBufferFormat, StencilBufferFormat, attribs, &nAttribs, TRUE /* alternate */);
PUSH1(None);
cfgs = glXChooseFBConfig(display,
DefaultScreen(display),
attribs, &nCfgs);
}
if (cfgs == NULL) {
ERR("Could not get a valid FBConfig for (%u,%s)/(%u,%s)\n",
BackBufferFormat, debug_d3dformat(BackBufferFormat),
StencilBufferFormat, debug_d3dformat(StencilBufferFormat));
} else {
#ifdef EXTRA_TRACES
int i;
for (i = 0; i < nCfgs; ++i) {
TRACE("for (%u,%s)/(%u,%s) found config[%d]@%p\n", BackBufferFormat,
debug_d3dformat(BackBufferFormat), StencilBufferFormat,
debug_d3dformat(StencilBufferFormat), i, cfgs[i]);
}
#endif
}
#undef PUSH1
#undef PUSH2
return cfgs;
}
/*****************************************************************************
* CreateContext
*
@ -203,7 +123,6 @@ static GLXFBConfig* pbuffer_find_fbconfigs(
WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, Display *display, Window win) {
Drawable drawable = win, oldDrawable;
XVisualInfo *visinfo = NULL;
GLXFBConfig *cfgs = NULL;
GLXContext ctx = NULL, oldCtx;
WineD3DContext *ret = NULL;
int s;
@ -211,37 +130,52 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
TRACE("(%p): Creating a %s context for render target %p\n", This, win ? "onscreen" : "offscreen", target);
if(!win) {
long int visualid;
int attribs[256];
int nAttribs = 0;
int i;
int val;
int index = -1;
TRACE("Creating a pBuffer drawable for the new context\n");
cfgs = pbuffer_find_fbconfigs(This, target, display);
if(!cfgs) {
ERR("Cannot find a frame buffer configuration for the pbuffer\n");
goto out;
}
attribs[nAttribs++] = GLX_PBUFFER_WIDTH;
attribs[nAttribs++] = target->currentDesc.Width;
attribs[nAttribs++] = GLX_PBUFFER_HEIGHT;
attribs[nAttribs++] = target->currentDesc.Height;
attribs[nAttribs++] = None;
visinfo = glXGetVisualFromFBConfig(display, cfgs[0]);
visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
TRACE("Found x visual ID : %ld\n", visualid);
/* Search for the fbconfig that corresponds to Wine's default X visual */
for(i=0; i < This->adapter->nCfgs; i++)
{
glXGetFBConfigAttrib(display, This->adapter->cfgs[i], GLX_VISUAL_ID, &val);
/* We have found the fbconfig :) */
if(val == visualid) {
index = i;
break;
}
}
if(index == -1) {
ERR("Cannot find an fbconfig corresponding to visualid=%lx\n", visualid);
goto out;
}
visinfo = glXGetVisualFromFBConfig(display, This->adapter->cfgs[index]);
if(!visinfo) {
ERR("Cannot find a visual for the pbuffer\n");
goto out;
}
drawable = glXCreatePbuffer(display, cfgs[0], attribs);
drawable = glXCreatePbuffer(display, This->adapter->cfgs[index], attribs);
if(!drawable) {
ERR("Cannot create a pbuffer\n");
goto out;
}
XFree(cfgs);
cfgs = NULL;
} else {
/* Create an onscreen target */
XVisualInfo template;
@ -396,7 +330,6 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
out:
if(visinfo) XFree(visinfo);
if(cfgs) XFree(cfgs);
return ret;
}

View file

@ -2464,176 +2464,6 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords)
checkGLcall("glLoadMatrixf(mat)");
}
#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
/* Convertes a D3D format into a OpenGL configuration format */
int D3DFmtMakeGlCfg(WINED3DFORMAT BackBufferFormat, WINED3DFORMAT StencilBufferFormat, int *attribs, int* nAttribs, BOOL alternate){
#define PUSH1(att) attribs[(*nAttribs)++] = (att);
#define PUSH2(att,value) attribs[(*nAttribs)++] = (att); attribs[(*nAttribs)++] = (value);
/*We need to do some Card specific stuff in here at some point,
D3D now supports floating point format buffers, and there are a number of different OpelGl ways of managing these e.g.
GLX_ATI_pixel_format_float
*/
switch (BackBufferFormat) {
/* color buffer */
case WINED3DFMT_P8:
PUSH2(GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT);
PUSH2(GLX_BUFFER_SIZE, 8);
PUSH2(GLX_DOUBLEBUFFER, TRUE);
break;
case WINED3DFMT_R3G3B2:
PUSH2(GLX_RENDER_TYPE, GLX_RGBA_BIT);
PUSH2(GLX_RED_SIZE, 3);
PUSH2(GLX_GREEN_SIZE, 3);
PUSH2(GLX_BLUE_SIZE, 2);
break;
case WINED3DFMT_A1R5G5B5:
PUSH2(GLX_ALPHA_SIZE, 1);
case WINED3DFMT_X1R5G5B5:
PUSH2(GLX_RED_SIZE, 5);
PUSH2(GLX_GREEN_SIZE, 5);
PUSH2(GLX_BLUE_SIZE, 5);
break;
case WINED3DFMT_R5G6B5:
PUSH2(GLX_RED_SIZE, 5);
PUSH2(GLX_GREEN_SIZE, 6);
PUSH2(GLX_BLUE_SIZE, 5);
break;
case WINED3DFMT_A4R4G4B4:
PUSH2(GLX_ALPHA_SIZE, 4);
case WINED3DFMT_X4R4G4B4:
PUSH2(GLX_RED_SIZE, 4);
PUSH2(GLX_GREEN_SIZE, 4);
PUSH2(GLX_BLUE_SIZE, 4);
break;
case WINED3DFMT_A8R8G8B8:
PUSH2(GLX_ALPHA_SIZE, 8);
case WINED3DFMT_R8G8B8:
case WINED3DFMT_X8R8G8B8:
PUSH2(GLX_RED_SIZE, 8);
PUSH2(GLX_GREEN_SIZE, 8);
PUSH2(GLX_BLUE_SIZE, 8);
break;
case WINED3DFMT_A2R10G10B10:
PUSH2(GLX_ALPHA_SIZE, 2);
PUSH2(GLX_RED_SIZE, 10);
PUSH2(GLX_GREEN_SIZE, 10);
PUSH2(GLX_BLUE_SIZE, 10);
break;
case WINED3DFMT_A16B16G16R16:
PUSH2(GLX_ALPHA_SIZE, 16);
PUSH2(GLX_RED_SIZE, 16);
PUSH2(GLX_GREEN_SIZE, 16);
PUSH2(GLX_BLUE_SIZE, 16);
break;
default:
FIXME("Unsupported color format: %s\n", debug_d3dformat(BackBufferFormat));
break;
}
if(!alternate){
switch (StencilBufferFormat) {
case 0:
break;
case WINED3DFMT_D16_LOCKABLE:
case WINED3DFMT_D16:
PUSH2(GLX_DEPTH_SIZE, 16);
break;
case WINED3DFMT_D15S1:
PUSH2(GLX_DEPTH_SIZE, 15);
PUSH2(GLX_STENCIL_SIZE, 1);
/*Does openGl support a 1bit stencil?, I've seen it used elsewhere
e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
break;
case WINED3DFMT_D24X8:
PUSH2(GLX_DEPTH_SIZE, 24);
break;
case WINED3DFMT_D24X4S4:
PUSH2(GLX_DEPTH_SIZE, 24);
PUSH2(GLX_STENCIL_SIZE, 4);
break;
case WINED3DFMT_D24S8:
PUSH2(GLX_DEPTH_SIZE, 24);
PUSH2(GLX_STENCIL_SIZE, 8);
break;
case WINED3DFMT_D24FS8:
PUSH2(GLX_DEPTH_SIZE, 24);
PUSH2(GLX_STENCIL_SIZE, 8);
break;
case WINED3DFMT_D32:
PUSH2(GLX_DEPTH_SIZE, 32);
break;
default:
FIXME("Unsupported stencil format: %s\n", debug_d3dformat(StencilBufferFormat));
break;
}
} else { /* it the device doesn't support the 'exact' format, try to find something close */
switch (StencilBufferFormat) {
case 0:
break;
case WINED3DFMT_D16_LOCKABLE:
case WINED3DFMT_D16:
PUSH2(GLX_DEPTH_SIZE, 1);
break;
case WINED3DFMT_D15S1:
PUSH2(GLX_DEPTH_SIZE, 1);
PUSH2(GLX_STENCIL_SIZE, 1);
/*Does openGl support a 1bit stencil?, I've seen it used elsewhere
e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
break;
case WINED3DFMT_D24X8:
PUSH2(GLX_DEPTH_SIZE, 1);
break;
case WINED3DFMT_D24X4S4:
PUSH2(GLX_DEPTH_SIZE, 1);
PUSH2(GLX_STENCIL_SIZE, 1);
break;
case WINED3DFMT_D24S8:
PUSH2(GLX_DEPTH_SIZE, 1);
PUSH2(GLX_STENCIL_SIZE, 1);
break;
case WINED3DFMT_D24FS8:
PUSH2(GLX_DEPTH_SIZE, 1);
PUSH2(GLX_STENCIL_SIZE, 1);
break;
case WINED3DFMT_D32:
PUSH2(GLX_DEPTH_SIZE, 1);
break;
default:
FIXME("Unsupported stencil format: %s\n", debug_d3dformat(StencilBufferFormat));
break;
}
}
return *nAttribs;
}
#undef GLINFO_LOCATION
/* DirectDraw stuff */
WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
switch(depth) {

View file

@ -1481,8 +1481,6 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords)
void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height);
GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain);
int D3DFmtMakeGlCfg(WINED3DFORMAT BackBufferFormat, WINED3DFORMAT StencilBufferFormat, int *attribs, int* nAttribs, BOOL alternate);
/* Math utils */
void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2);