opengl: render_texture

- better render_texture emulation (using pbuffers)
- support GLX_ATI_render_texture for render_texture
This commit is contained in:
Raphael Junqueira 2005-12-08 12:45:07 +01:00 committed by Alexandre Julliard
parent 7bca41a739
commit 1399edb092
2 changed files with 419 additions and 108 deletions

View File

@ -46,6 +46,7 @@ enum x11drv_escape_codes
X11DRV_GET_DISPLAY, /* get X11 display for a DC */ X11DRV_GET_DISPLAY, /* get X11 display for a DC */
X11DRV_GET_DRAWABLE, /* get current drawable for a DC */ X11DRV_GET_DRAWABLE, /* get current drawable for a DC */
X11DRV_GET_FONT, /* get current X font for a DC */ X11DRV_GET_FONT, /* get current X font for a DC */
X11DRV_SET_DRAWABLE, /* set current drawable for a DC */
}; };
void (*wine_tsx11_lock_ptr)(void) = NULL; void (*wine_tsx11_lock_ptr)(void) = NULL;
@ -160,15 +161,15 @@ inline static Font get_font( HDC hdc )
*/ */
HGLRC WINAPI wglCreateContext(HDC hdc) HGLRC WINAPI wglCreateContext(HDC hdc)
{ {
XVisualInfo *vis;
Wine_GLContext *ret; Wine_GLContext *ret;
int num; int num;
XVisualInfo template; XVisualInfo template;
XVisualInfo *vis = NULL;
Display *display = get_display( hdc ); Display *display = get_display( hdc );
int hdcPF = GetPixelFormat(hdc); int hdcPF = GetPixelFormat(hdc);
GLXFBConfig cur_cfg; GLXFBConfig cur_cfg;
TRACE("(%p)\n", hdc); TRACE("(%p)->(PF:%d)\n", hdc, hdcPF);
/* First, get the visual in use by the X11DRV */ /* First, get the visual in use by the X11DRV */
if (!display) return 0; if (!display) return 0;
@ -217,8 +218,9 @@ HGLRC WINAPI wglCreateContext(HDC hdc)
LEAVE_GL(); LEAVE_GL();
ret->hdc = hdc; ret->hdc = hdc;
ret->display = display; ret->display = display;
ret->vis = vis;
ret->fb_conf = cur_cfg; ret->fb_conf = cur_cfg;
/*ret->vis = vis;*/
ret->vis = glXGetVisualFromFBConfig(display, cur_cfg);
TRACE(" creating context %p (GL context creation delayed)\n", ret); TRACE(" creating context %p (GL context creation delayed)\n", ret);
return (HGLRC) ret; return (HGLRC) ret;
@ -477,8 +479,47 @@ BOOL WINAPI wglMakeCurrent(HDC hdc,
Wine_GLContext *ctx = (Wine_GLContext *) hglrc; Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
Drawable drawable = get_drawable( hdc ); Drawable drawable = get_drawable( hdc );
if (ctx->ctx == NULL) { if (ctx->ctx == NULL) {
ctx->ctx = glXCreateContext(ctx->display, ctx->vis, NULL, True); int tmp;
TRACE(" created a delayed OpenGL context (%p) for %p\n", ctx->ctx, ctx->vis); int draw_vis_id, ctx_vis_id;
VisualID visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
TRACE(" desktop VISUAL_ID is 0x%x\n", (unsigned int) visualid);
TRACE(" drawable %p have :\n", (void*) drawable);
glXQueryDrawable(ctx->display, drawable, GLX_FBCONFIG_ID, (unsigned int*) &tmp);
TRACE(" - FBCONFIG_ID as 0x%x\n", tmp);
glXQueryDrawable(ctx->display, drawable, GLX_VISUAL_ID, (unsigned int*) &tmp);
TRACE(" - VISUAL_ID as 0x%x\n", tmp);
draw_vis_id = tmp;
glXQueryDrawable(ctx->display, drawable, GLX_WIDTH, (unsigned int*) &tmp);
TRACE(" - WIDTH as %d\n", tmp);
glXQueryDrawable(ctx->display, drawable, GLX_HEIGHT, (unsigned int*) &tmp);
TRACE(" - HEIGHT as %d\n", tmp);
TRACE(" Context %p have (vis:%p):\n", ctx, ctx->vis);
glXGetFBConfigAttrib(ctx->display, ctx->fb_conf, GLX_FBCONFIG_ID, &tmp);
TRACE(" - FBCONFIG_ID 0x%x\n", tmp);
glXGetFBConfigAttrib(ctx->display, ctx->fb_conf, GLX_VISUAL_ID, &tmp);
TRACE(" - VISUAL_ID 0x%x\n", tmp);
ctx_vis_id = tmp;
if (draw_vis_id == visualid && draw_vis_id != ctx_vis_id) {
/**
* Inherits from root window so reuse desktop visual
*/
XVisualInfo template;
XVisualInfo *vis;
int num;
template.visualid = visualid;
vis = XGetVisualInfo(ctx->display, VisualIDMask, &template, &num);
TRACE(" Creating GLX Context\n");
ctx->ctx = glXCreateContext(ctx->display, vis, NULL, True);
} else {
TRACE(" Creating GLX Context\n");
ctx->ctx = glXCreateContext(ctx->display, ctx->vis, NULL, True);
}
TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
} }
TRACE(" make current for dis %p, drawable %p, ctx %p\n", ctx->display, (void*) drawable, ctx->ctx); TRACE(" make current for dis %p, drawable %p, ctx %p\n", ctx->display, (void*) drawable, ctx->ctx);
ret = glXMakeCurrent(ctx->display, drawable, ctx->ctx); ret = glXMakeCurrent(ctx->display, drawable, ctx->ctx);

View File

@ -130,19 +130,36 @@ Bool (*p_glXBindTexImageARB)(Display *dpy, GLXPbuffer pbuffer, int buffer);
Bool (*p_glXReleaseTexImageARB)(Display *dpy, GLXPbuffer pbuffer, int buffer); Bool (*p_glXReleaseTexImageARB)(Display *dpy, GLXPbuffer pbuffer, int buffer);
Bool (*p_glXDrawableAttribARB)(Display *dpy, GLXDrawable draw, const int *attribList); Bool (*p_glXDrawableAttribARB)(Display *dpy, GLXDrawable draw, const int *attribList);
int use_render_texture_emulation = 0; int use_render_texture_emulation = 0;
int use_render_texture_ati = 0;
BOOL query_function_render_texture(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions, BOOL query_function_render_texture(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions,
const char* glx_version, const char *glx_extensions, const char* glx_version, const char *glx_extensions,
const char *server_glx_extensions, const char *client_glx_extensions) const char *server_glx_extensions, const char *client_glx_extensions)
{ {
BOOL bTest = (0 <= strcmp("1.3", glx_version) || NULL != strstr(glx_extensions, "GLX_SGIX_pbuffer")); BOOL bTest = FALSE;
if (NULL != strstr(glx_extensions, "GLX_ATI_render_texture")) {
p_glXBindTexImageARB = proc( (const GLubyte *) "glXBindTexImageARB");
p_glXReleaseTexImageARB = proc( (const GLubyte *) "glXReleaseTexImageARB");
p_glXDrawableAttribARB = proc( (const GLubyte *) "glXDrawableAttribARB");
bTest = (NULL != p_glXBindTexImageARB && NULL != p_glXReleaseTexImageARB && NULL != p_glXDrawableAttribARB);
}
if (bTest) {
TRACE("Active WGL_render_texture: found GLX_ATI_render_texture extensions\n");
use_render_texture_ati = 1;
return bTest;
}
bTest = (0 <= strcmp("1.3", glx_version) || NULL != strstr(glx_extensions, "GLX_SGIX_pbuffer"));
if (bTest) { if (bTest) {
if (NULL != strstr(glx_extensions, "GLX_ARB_render_texture")) { if (NULL != strstr(glx_extensions, "GLX_ARB_render_texture")) {
p_glXBindTexImageARB = proc( (const GLubyte *) "glXBindTexImageARB"); p_glXBindTexImageARB = proc( (const GLubyte *) "glXBindTexImageARB");
p_glXReleaseTexImageARB = proc( (const GLubyte *) "glXReleaseTexImageARB"); p_glXReleaseTexImageARB = proc( (const GLubyte *) "glXReleaseTexImageARB");
p_glXDrawableAttribARB = proc( (const GLubyte *) "glXDrawableAttribARB"); p_glXDrawableAttribARB = proc( (const GLubyte *) "glXDrawableAttribARB");
TRACE("glXBindTexImageARB found as %p\n", p_glXBindTexImageARB);
TRACE("glXReleaseTexImageARB found as %p\n", p_glXReleaseTexImageARB);
TRACE("glXDrawableAttribARB found as %p\n", p_glXDrawableAttribARB);
bTest = (NULL != p_glXBindTexImageARB && NULL != p_glXReleaseTexImageARB && NULL != p_glXDrawableAttribARB); bTest = (NULL != p_glXBindTexImageARB && NULL != p_glXReleaseTexImageARB && NULL != p_glXDrawableAttribARB);
} else { } else {
use_render_texture_emulation = 0; TRACE("Active WGL_render_texture: emulation using pbuffers\n");
use_render_texture_emulation = 1;
} }
} }
return bTest; return bTest;
@ -216,6 +233,10 @@ typedef struct wine_glpbuffer {
GLuint texture_bind_target; GLuint texture_bind_target;
GLuint texture; GLuint texture;
int texture_level; int texture_level;
HDC prev_hdc;
HGLRC prev_ctx;
HDC render_hdc;
HGLRC render_ctx;
} Wine_GLPBuffer; } Wine_GLPBuffer;
#define PUSH1(attribs,att) attribs[nAttribs++] = (att); #define PUSH1(attribs,att) attribs[nAttribs++] = (att);
@ -327,16 +348,69 @@ typedef struct wine_glpbuffer {
#define WGL_AUX8_ARB 0x208F #define WGL_AUX8_ARB 0x208F
#define WGL_AUX9_ARB 0x2090 #define WGL_AUX9_ARB 0x2090
/**
* WGL_ATI_pixel_format_float / WGL_ARB_color_buffer_float
*/
#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
#define GL_RGBA_FLOAT_MODE_ATI 0x8820
#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835
#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A
#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B
#define GL_CLAMP_READ_COLOR_ARB 0x891C
/** GLX_ATI_pixel_format_float */
#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100
/** GLX_ARB_pixel_format_float */
#define GLX_RGBA_FLOAT_BIT 0x00000004
#define GLX_RGBA_FLOAT_TYPE 0x20B9
/** GLX_ATI_render_texture */
#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800
#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801
#define GLX_TEXTURE_FORMAT_ATI 0x9802
#define GLX_TEXTURE_TARGET_ATI 0x9803
#define GLX_MIPMAP_TEXTURE_ATI 0x9804
#define GLX_TEXTURE_RGB_ATI 0x9805
#define GLX_TEXTURE_RGBA_ATI 0x9806
#define GLX_NO_TEXTURE_ATI 0x9807
#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808
#define GLX_TEXTURE_1D_ATI 0x9809
#define GLX_TEXTURE_2D_ATI 0x980A
#define GLX_MIPMAP_LEVEL_ATI 0x980B
#define GLX_CUBE_MAP_FACE_ATI 0x980C
#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D
#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E
#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F
#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810
#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811
#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812
#define GLX_FRONT_LEFT_ATI 0x9813
#define GLX_FRONT_RIGHT_ATI 0x9814
#define GLX_BACK_LEFT_ATI 0x9815
#define GLX_BACK_RIGHT_ATI 0x9816
#define GLX_AUX0_ATI 0x9817
#define GLX_AUX1_ATI 0x9818
#define GLX_AUX2_ATI 0x9819
#define GLX_AUX3_ATI 0x981A
#define GLX_AUX4_ATI 0x981B
#define GLX_AUX5_ATI 0x981C
#define GLX_AUX6_ATI 0x981D
#define GLX_AUX7_ATI 0x981E
#define GLX_AUX8_ATI 0x981F
#define GLX_AUX9_ATI 0x9820
#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821
#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822
#if 0 /* not used yet */ #if 0 /* not used yet */
static unsigned ConvertAttribGLXtoWGL(const int* iWGLAttr, int* oGLXAttr) { static int ConvertAttribGLXtoWGL(const int* iWGLAttr, int* oGLXAttr) {
unsigned nAttribs = 0; int nAttribs = 0;
FIXME("not yet implemented!\n"); FIXME("not yet implemented!\n");
return nAttribs; return nAttribs;
} }
#endif #endif
static unsigned ConvertAttribWGLtoGLX(const int* iWGLAttr, int* oGLXAttr, Wine_GLPBuffer* pbuf) { static int ConvertAttribWGLtoGLX(const int* iWGLAttr, int* oGLXAttr, Wine_GLPBuffer* pbuf) {
unsigned nAttribs = 0; int nAttribs = 0;
unsigned cur = 0; unsigned cur = 0;
int pop; int pop;
int isColor = 0; int isColor = 0;
@ -391,8 +465,9 @@ static unsigned ConvertAttribWGLtoGLX(const int* iWGLAttr, int* oGLXAttr, Wine_G
case WGL_PIXEL_TYPE_ARB: case WGL_PIXEL_TYPE_ARB:
pop = iWGLAttr[++cur]; pop = iWGLAttr[++cur];
switch (pop) { switch (pop) {
case WGL_TYPE_RGBA_ARB: pop = GLX_RGBA_BIT; break ;
case WGL_TYPE_COLORINDEX_ARB: pop = GLX_COLOR_INDEX_BIT; isColor = 1; break ; case WGL_TYPE_COLORINDEX_ARB: pop = GLX_COLOR_INDEX_BIT; isColor = 1; break ;
case WGL_TYPE_RGBA_ARB: pop = GLX_RGBA_BIT; break ;
case WGL_TYPE_RGBA_FLOAT_ATI: pop = GLX_RGBA_FLOAT_ATI_BIT; break ;
default: default:
ERR("unexpected PixelType(%x)\n", pop); ERR("unexpected PixelType(%x)\n", pop);
pop = 0; pop = 0;
@ -402,12 +477,37 @@ static unsigned ConvertAttribWGLtoGLX(const int* iWGLAttr, int* oGLXAttr, Wine_G
break; break;
case WGL_SUPPORT_GDI_ARB: case WGL_SUPPORT_GDI_ARB:
case WGL_DRAW_TO_WINDOW_ARB: pop = iWGLAttr[++cur];
PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop);
TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur, pop);
break;
case WGL_DRAW_TO_BITMAP_ARB: case WGL_DRAW_TO_BITMAP_ARB:
pop = iWGLAttr[++cur];
PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop);
TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur, pop);
if (pop) {
PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT);
TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_PIXMAP_BIT\n", cur);
}
break;
case WGL_DRAW_TO_WINDOW_ARB:
pop = iWGLAttr[++cur];
if (pop) {
PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT);
TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_WINDOW_BIT\n", cur);
}
break;
case WGL_DRAW_TO_PBUFFER_ARB: case WGL_DRAW_TO_PBUFFER_ARB:
pop = iWGLAttr[++cur]; pop = iWGLAttr[++cur];
PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop); PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop);
TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur, pop); TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur, pop);
if (pop) {
PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT);
TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_PBUFFER_BIT\n", cur);
}
break; break;
case WGL_ACCELERATION_ARB: case WGL_ACCELERATION_ARB:
@ -439,13 +539,31 @@ static unsigned ConvertAttribWGLtoGLX(const int* iWGLAttr, int* oGLXAttr, Wine_G
case WGL_TEXTURE_TARGET_ARB: case WGL_TEXTURE_TARGET_ARB:
case WGL_MIPMAP_TEXTURE_ARB: case WGL_MIPMAP_TEXTURE_ARB:
TRACE("WGL_render_texture Attributes: %x as %x\n", iWGLAttr[cur], iWGLAttr[cur + 1]); TRACE("WGL_render_texture Attributes: %x as %x\n", iWGLAttr[cur], iWGLAttr[cur + 1]);
pop = iWGLAttr[++cur];
if (NULL == pbuf) { if (NULL == pbuf) {
ERR("trying to use GLX_Pbuffer Attributes without Pbuffer (was %x)\n", iWGLAttr[cur]); ERR("trying to use GLX_Pbuffer Attributes without Pbuffer (was %x)\n", iWGLAttr[cur]);
} }
if (!use_render_texture_emulation) { if (use_render_texture_ati) {
ERR("trying to use WGL_render_texture Attributes without support (was %x)\n", iWGLAttr[cur]); /** nothing to do here */
} }
else if (!use_render_texture_emulation) {
if (WGL_NO_TEXTURE_ARB != pop) {
ERR("trying to use WGL_render_texture Attributes without support (was %x)\n", iWGLAttr[cur]);
return -1; /** error: don't support it */
} else {
PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop);
PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT);
}
}
break ;
case WGL_BIND_TO_TEXTURE_RGB_ARB:
case WGL_BIND_TO_TEXTURE_RGBA_ARB:
pop = iWGLAttr[++cur]; pop = iWGLAttr[++cur];
/** cannot be converted, see direct handling on
* - wglGetPixelFormatAttribivARB
* TODO: wglChoosePixelFormat
*/
break ; break ;
default: default:
@ -557,25 +675,57 @@ GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLa
curCfg = cfgs[iPixelFormat - 1]; curCfg = cfgs[iPixelFormat - 1];
hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp); hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
if (hTest) goto get_error; if (hTest) goto get_error;
switch (tmp) { TRACE("WGL_PIXEL_TYPE_ARB: GLX_RENDER_TYPE = 0x%x\n", tmp);
case GLX_RGBA_BIT: piValues[i] = WGL_TYPE_RGBA_ARB; break; if (tmp & GLX_RGBA_BIT) { piValues[i] = WGL_TYPE_RGBA_ARB; }
case GLX_COLOR_INDEX_BIT: piValues[i] = WGL_TYPE_COLORINDEX_ARB; break ; else if (tmp & GLX_COLOR_INDEX_BIT) { piValues[i] = WGL_TYPE_COLORINDEX_ARB; }
default: else if (tmp & GLX_RGBA_FLOAT_BIT) { piValues[i] = WGL_TYPE_RGBA_FLOAT_ATI; }
else if (tmp & GLX_RGBA_FLOAT_ATI_BIT) { piValues[i] = WGL_TYPE_RGBA_FLOAT_ATI; }
else {
ERR("unexpected RenderType(%x)\n", tmp); ERR("unexpected RenderType(%x)\n", tmp);
piValues[i] = WGL_TYPE_RGBA_ARB; piValues[i] = WGL_TYPE_RGBA_ARB;
} }
continue ; continue ;
case WGL_COLOR_BITS_ARB: case WGL_COLOR_BITS_ARB:
/** see ConvertAttribWGLtoGLX for explain */ /** see ConvertAttribWGLtoGLX for explain */
if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error; if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
curCfg = cfgs[iPixelFormat - 1]; curCfg = cfgs[iPixelFormat - 1];
hTest = glXGetFBConfigAttrib(display, curCfg, GLX_BUFFER_SIZE, piValues + i); hTest = glXGetFBConfigAttrib(display, curCfg, GLX_BUFFER_SIZE, piValues + i);
if (hTest) goto get_error; if (hTest) goto get_error;
TRACE("WGL_COLOR_BITS_ARB: GLX_BUFFER_SIZE = %d\n", piValues[i]);
hTest = glXGetFBConfigAttrib(display, curCfg, GLX_ALPHA_SIZE, &tmp); hTest = glXGetFBConfigAttrib(display, curCfg, GLX_ALPHA_SIZE, &tmp);
if (hTest) goto get_error; if (hTest) goto get_error;
TRACE("WGL_COLOR_BITS_ARB: GLX_ALPHA_SIZE = %d\n", tmp);
piValues[i] = piValues[i] - tmp; piValues[i] = piValues[i] - tmp;
break; continue ;
case WGL_BIND_TO_TEXTURE_RGB_ARB:
if (use_render_texture_ati) {
curGLXAttr = GLX_BIND_TO_TEXTURE_RGB_ATI;
break;
}
case WGL_BIND_TO_TEXTURE_RGBA_ARB:
if (use_render_texture_ati) {
curGLXAttr = GLX_BIND_TO_TEXTURE_RGBA_ATI;
break;
}
if (!use_render_texture_emulation) {
piValues[i] = GL_FALSE;
continue ;
}
curGLXAttr = GLX_RENDER_TYPE;
if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
curCfg = cfgs[iPixelFormat - 1];
hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
if (hTest) goto get_error;
if (GLX_COLOR_INDEX_BIT == tmp) {
piValues[i] = GL_FALSE;
continue ;
}
hTest = glXGetFBConfigAttrib(display, curCfg, GLX_DRAWABLE_TYPE, &tmp);
if (hTest) goto get_error;
piValues[i] = (tmp & GLX_PBUFFER_BIT) ? GL_TRUE : GL_FALSE;
continue ;
case WGL_BLUE_BITS_ARB: case WGL_BLUE_BITS_ARB:
curGLXAttr = GLX_BLUE_SIZE; curGLXAttr = GLX_BLUE_SIZE;
@ -624,24 +774,6 @@ GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLa
curGLXAttr = GLX_SAMPLES_ARB; curGLXAttr = GLX_SAMPLES_ARB;
break; break;
case WGL_BIND_TO_TEXTURE_RGB_ARB:
case WGL_BIND_TO_TEXTURE_RGBA_ARB:
if (!use_render_texture_emulation) {
piValues[i] = GL_FALSE;
continue ;
}
curGLXAttr = GLX_RENDER_TYPE;
if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
curCfg = cfgs[iPixelFormat - 1];
hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
if (hTest) goto get_error;
if (GLX_COLOR_INDEX_BIT == tmp) {
piValues[i] = GL_FALSE;
continue ;
}
curGLXAttr = GLX_X_RENDERABLE;
break;
default: default:
FIXME("unsupported %x WGL Attribute\n", curWGLAttr); FIXME("unsupported %x WGL Attribute\n", curWGLAttr);
} }
@ -682,7 +814,7 @@ GLboolean WINAPI wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, cons
Display* display = get_display( hdc ); Display* display = get_display( hdc );
int gl_test = 0; int gl_test = 0;
int attribs[256]; int attribs[256];
unsigned nAttribs = 0; int nAttribs = 0;
GLXFBConfig* cfgs = NULL; GLXFBConfig* cfgs = NULL;
int nCfgs = 0; int nCfgs = 0;
@ -702,6 +834,10 @@ GLboolean WINAPI wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, cons
} }
nAttribs = ConvertAttribWGLtoGLX(piAttribIList, attribs, NULL); nAttribs = ConvertAttribWGLtoGLX(piAttribIList, attribs, NULL);
if (-1 == nAttribs) {
WARN("Cannot convert WGL to GLX attributes\n");
return GL_FALSE;
}
PUSH1(attribs, None); PUSH1(attribs, None);
cfgs = glXChooseFBConfig(display, DefaultScreen(display), attribs, &nCfgs); cfgs = glXChooseFBConfig(display, DefaultScreen(display), attribs, &nCfgs);
@ -734,7 +870,7 @@ GLboolean WINAPI wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, cons
piFormats[pfmt_it] = it_fmt + 1; piFormats[pfmt_it] = it_fmt + 1;
++pfmt_it; ++pfmt_it;
glXGetFBConfigAttrib(display, cfgs_fmt[it_fmt], GLX_ALPHA_SIZE, &tmp); glXGetFBConfigAttrib(display, cfgs_fmt[it_fmt], GLX_ALPHA_SIZE, &tmp);
TRACE("for FBCONFIG_ID(%d/%d) found '%d'\n", it_fmt + 1, nCfgs_fmt, tmp); TRACE("ALPHA_SIZE of FBCONFIG_ID(%d/%d) found as '%d'\n", it_fmt + 1, nCfgs_fmt, tmp);
break ; break ;
} }
} }
@ -795,93 +931,139 @@ HPBUFFERARB WINAPI wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, in
object->pixelFormat = iPixelFormat; object->pixelFormat = iPixelFormat;
nAttribs = ConvertAttribWGLtoGLX(piAttribList, attribs, object); nAttribs = ConvertAttribWGLtoGLX(piAttribList, attribs, object);
if (-1 == nAttribs) {
WARN("Cannot convert WGL to GLX attributes\n");
goto create_failed;
}
PUSH2(attribs, GLX_PBUFFER_WIDTH, iWidth); PUSH2(attribs, GLX_PBUFFER_WIDTH, iWidth);
PUSH2(attribs, GLX_PBUFFER_HEIGHT, iHeight); PUSH2(attribs, GLX_PBUFFER_HEIGHT, iHeight);
PUSH1(attribs, None);
while (0 != *piAttribList) { while (0 != *piAttribList) {
int attr_v; int attr_v;
switch (*piAttribList) { switch (*piAttribList) {
case WGL_TEXTURE_FORMAT_ARB: { case WGL_TEXTURE_FORMAT_ARB: {
if (!use_render_texture_emulation) {
SetLastError(ERROR_INVALID_DATA);
goto create_failed;
}
++piAttribList; ++piAttribList;
attr_v = *piAttribList; attr_v = *piAttribList;
TRACE("WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x\n", attr_v); TRACE("WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x\n", attr_v);
switch (attr_v) { if (use_render_texture_ati) {
case WGL_TEXTURE_RGB_ARB: int type = 0;
case WGL_TEXTURE_RGBA_ARB: switch (attr_v) {
case WGL_NO_TEXTURE_ARB: case WGL_NO_TEXTURE_ARB: type = GLX_NO_TEXTURE_ATI; break ;
break; case WGL_TEXTURE_RGB_ARB: type = GLX_TEXTURE_RGB_ATI; break ;
default: case WGL_TEXTURE_RGBA_ARB: type = GLX_TEXTURE_RGBA_ATI; break ;
SetLastError(ERROR_INVALID_DATA); default:
goto create_failed; SetLastError(ERROR_INVALID_DATA);
goto create_failed;
}
object->use_render_texture = 1;
PUSH2(attribs, GLX_TEXTURE_FORMAT_ATI, type);
} else {
if (WGL_NO_TEXTURE_ARB == attr_v) {
object->use_render_texture = 0;
} else {
if (!use_render_texture_emulation) {
SetLastError(ERROR_INVALID_DATA);
goto create_failed;
}
switch (attr_v) {
case WGL_TEXTURE_RGB_ARB:
object->use_render_texture = GL_RGB;
break;
case WGL_TEXTURE_RGBA_ARB:
object->use_render_texture = GL_RGBA;
break;
default:
SetLastError(ERROR_INVALID_DATA);
goto create_failed;
}
}
} }
break; break;
} }
case WGL_TEXTURE_TARGET_ARB: { case WGL_TEXTURE_TARGET_ARB: {
if (!use_render_texture_emulation) {
SetLastError(ERROR_INVALID_DATA);
goto create_failed;
}
++piAttribList; ++piAttribList;
attr_v = *piAttribList; attr_v = *piAttribList;
TRACE("WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x\n", attr_v); TRACE("WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x\n", attr_v);
switch (attr_v) { if (use_render_texture_ati) {
case WGL_TEXTURE_CUBE_MAP_ARB: { int type = 0;
if (iWidth != iHeight) { switch (attr_v) {
case WGL_NO_TEXTURE_ARB: type = GLX_NO_TEXTURE_ATI; break ;
case WGL_TEXTURE_CUBE_MAP_ARB: type = GLX_TEXTURE_CUBE_MAP_ATI; break ;
case WGL_TEXTURE_1D_ARB: type = GLX_TEXTURE_1D_ATI; break ;
case WGL_TEXTURE_2D_ARB: type = GLX_TEXTURE_2D_ATI; break ;
default:
SetLastError(ERROR_INVALID_DATA); SetLastError(ERROR_INVALID_DATA);
goto create_failed; goto create_failed;
} }
object->texture_target = GL_TEXTURE_CUBE_MAP; PUSH2(attribs, GLX_TEXTURE_TARGET_ATI, type);
object->texture_bind_target = GL_TEXTURE_CUBE_MAP; } else {
break; if (WGL_NO_TEXTURE_ARB == attr_v) {
} object->texture_target = 0;
case WGL_TEXTURE_1D_ARB: { } else {
if (1 != iHeight) { if (!use_render_texture_emulation) {
SetLastError(ERROR_INVALID_DATA); SetLastError(ERROR_INVALID_DATA);
goto create_failed; goto create_failed;
}
switch (attr_v) {
case WGL_TEXTURE_CUBE_MAP_ARB: {
if (iWidth != iHeight) {
SetLastError(ERROR_INVALID_DATA);
goto create_failed;
}
object->texture_target = GL_TEXTURE_CUBE_MAP;
object->texture_bind_target = GL_TEXTURE_CUBE_MAP;
break;
}
case WGL_TEXTURE_1D_ARB: {
if (1 != iHeight) {
SetLastError(ERROR_INVALID_DATA);
goto create_failed;
}
object->texture_target = GL_TEXTURE_1D;
object->texture_bind_target = GL_TEXTURE_1D;
break;
}
case WGL_TEXTURE_2D_ARB: {
object->texture_target = GL_TEXTURE_2D;
object->texture_bind_target = GL_TEXTURE_2D;
break;
}
default:
SetLastError(ERROR_INVALID_DATA);
goto create_failed;
}
} }
object->texture_target = GL_TEXTURE_1D;
object->texture_bind_target = GL_TEXTURE_1D;
break;
}
case WGL_TEXTURE_2D_ARB: {
object->texture_target = GL_TEXTURE_2D;
object->texture_bind_target = GL_TEXTURE_2D;
break;
}
case WGL_NO_TEXTURE_ARB:
break;
default:
SetLastError(ERROR_INVALID_DATA);
goto create_failed;
} }
break; break;
} }
case WGL_MIPMAP_TEXTURE_ARB: { case WGL_MIPMAP_TEXTURE_ARB: {
if (!use_render_texture_emulation) {
SetLastError(ERROR_INVALID_DATA);
goto create_failed;
}
++piAttribList; ++piAttribList;
attr_v = *piAttribList; attr_v = *piAttribList;
TRACE("WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x\n", attr_v); TRACE("WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x\n", attr_v);
if (0 != attr_v) { if (use_render_texture_ati) {
SetLastError(ERROR_INVALID_DATA); PUSH2(attribs, GLX_MIPMAP_TEXTURE_ATI, attr_v);
goto create_failed; } else {
if (!use_render_texture_emulation) {
SetLastError(ERROR_INVALID_DATA);
goto create_failed;
}
/*
if (0 != attr_v) {
SetLastError(ERROR_INVALID_DATA);
goto create_failed;
}
*/
} }
break ; break ;
} }
} }
++piAttribList; ++piAttribList;
} }
PUSH1(attribs, None);
object->drawable = glXCreatePbuffer(display, cfgs[iPixelFormat - 1], attribs); object->drawable = glXCreatePbuffer(display, cfgs[iPixelFormat - 1], attribs);
TRACE("new Pbuffer drawable as %p\n", (void*) object->drawable); TRACE("new Pbuffer drawable as %p\n", (void*) object->drawable);
if (!object->drawable) { if (!object->drawable) {
@ -910,6 +1092,7 @@ HDC WINAPI wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
return NULL; return NULL;
} }
hDC = CreateCompatibleDC(object->hdc); hDC = CreateCompatibleDC(object->hdc);
SetPixelFormat(hDC, object->pixelFormat, NULL);
set_drawable(hDC, object->drawable); /* works ?? */ set_drawable(hDC, object->drawable); /* works ?? */
TRACE("(%p)->(%p)\n", hPbuffer, hDC); TRACE("(%p)->(%p)\n", hPbuffer, hDC);
return hDC; return hDC;
@ -956,17 +1139,69 @@ GLboolean WINAPI wglQueryPbufferARB(HPBUFFERARB hPbuffer, int iAttribute, int *p
break; break;
case WGL_TEXTURE_FORMAT_ARB: case WGL_TEXTURE_FORMAT_ARB:
if (use_render_texture_ati) {
unsigned int tmp;
int type = WGL_NO_TEXTURE_ARB;
glXQueryDrawable(object->display, object->drawable, GLX_TEXTURE_FORMAT_ATI, &tmp);
switch (tmp) {
case GLX_NO_TEXTURE_ATI: type = WGL_NO_TEXTURE_ARB; break ;
case GLX_TEXTURE_RGB_ATI: type = WGL_TEXTURE_RGB_ARB; break ;
case GLX_TEXTURE_RGBA_ATI: type = WGL_TEXTURE_RGBA_ARB; break ;
}
*piValue = type;
} else {
if (!object->use_render_texture) {
*piValue = WGL_NO_TEXTURE_ARB;
} else {
if (!use_render_texture_emulation) {
SetLastError(ERROR_INVALID_HANDLE);
return GL_FALSE;
}
if (GL_RGBA == object->use_render_texture) {
*piValue = WGL_TEXTURE_RGBA_ARB;
} else {
*piValue = WGL_TEXTURE_RGB_ARB;
}
}
}
break;
case WGL_TEXTURE_TARGET_ARB: case WGL_TEXTURE_TARGET_ARB:
if (use_render_texture_ati) {
unsigned int tmp;
int type = WGL_NO_TEXTURE_ARB;
glXQueryDrawable(object->display, object->drawable, GLX_TEXTURE_TARGET_ATI, &tmp);
switch (tmp) {
case GLX_NO_TEXTURE_ATI: type = WGL_NO_TEXTURE_ARB; break ;
case GLX_TEXTURE_CUBE_MAP_ATI: type = WGL_TEXTURE_CUBE_MAP_ARB; break ;
case GLX_TEXTURE_1D_ATI: type = WGL_TEXTURE_1D_ARB; break ;
case GLX_TEXTURE_2D_ATI: type = WGL_TEXTURE_2D_ARB; break ;
}
*piValue = type;
} else {
if (!object->texture_target) {
*piValue = WGL_NO_TEXTURE_ARB;
} else {
if (!use_render_texture_emulation) {
SetLastError(ERROR_INVALID_DATA);
return GL_FALSE;
}
switch (object->texture_target) {
case GL_TEXTURE_1D: *piValue = WGL_TEXTURE_CUBE_MAP_ARB; break;
case GL_TEXTURE_2D: *piValue = WGL_TEXTURE_1D_ARB; break;
case GL_TEXTURE_CUBE_MAP: *piValue = WGL_TEXTURE_2D_ARB; break;
}
}
}
break;
case WGL_MIPMAP_TEXTURE_ARB: case WGL_MIPMAP_TEXTURE_ARB:
if (!object->use_render_texture) { if (use_render_texture_ati) {
SetLastError(ERROR_INVALID_HANDLE); glXQueryDrawable(object->display, object->drawable, GLX_MIPMAP_TEXTURE_ATI, (unsigned int*) piValue);
return GL_FALSE; } else {
*piValue = GL_FALSE; /** don't support that */
FIXME("unsupported WGL_ARB_render_texture attribute query for 0x%x\n", iAttribute);
} }
if (!use_render_texture_emulation) {
SetLastError(ERROR_INVALID_DATA);
return GL_FALSE; /** how to FIX ? */
}
FIXME("unsupported WGL_ARB_render_texture attribute query for 0x%x\n", iAttribute);
break; break;
default: default:
@ -989,7 +1224,29 @@ GLboolean WINAPI wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
SetLastError(ERROR_INVALID_HANDLE); SetLastError(ERROR_INVALID_HANDLE);
return GL_FALSE; return GL_FALSE;
} }
if (1 == use_render_texture_emulation) { if (!use_render_texture_ati && 1 == use_render_texture_emulation) {
int do_init = 0;
GLint prev_binded_tex;
glGetIntegerv(object->texture_target, &prev_binded_tex);
if (NULL == object->render_ctx) {
object->render_hdc = wglGetPbufferDCARB(hPbuffer);
object->render_ctx = wglCreateContext(object->render_hdc);
do_init = 1;
}
object->prev_hdc = wglGetCurrentDC();
object->prev_ctx = wglGetCurrentContext();
wglMakeCurrent(object->render_hdc, object->render_ctx);
/*
if (do_init) {
glBindTexture(object->texture_target, object->texture);
if (GL_RGBA == object->use_render_texture) {
glTexImage2D(object->texture_target, 0, GL_RGBA8, object->width, object->height, 0, GL_RGBA, GL_FLOAT, NULL);
} else {
glTexImage2D(object->texture_target, 0, GL_RGB8, object->width, object->height, 0, GL_RGB, GL_FLOAT, NULL);
}
}
*/
object->texture = prev_binded_tex;
return GL_TRUE; return GL_TRUE;
} }
if (NULL != p_glXBindTexImageARB) { if (NULL != p_glXBindTexImageARB) {
@ -1010,16 +1267,26 @@ GLboolean WINAPI wglReleaseTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
SetLastError(ERROR_INVALID_HANDLE); SetLastError(ERROR_INVALID_HANDLE);
return GL_FALSE; return GL_FALSE;
} }
if (1 == use_render_texture_emulation) { if (!use_render_texture_ati && 1 == use_render_texture_emulation) {
/*
GLint prev_binded_tex; GLint prev_binded_tex;
glGetIntegerv(object->texture_target, &prev_binded_tex); glGetIntegerv(object->texture_target, &prev_binded_tex);
glBindTexture(object->texture_target, object->texture);
if (GL_TEXTURE_1D == object->texture_target) { if (GL_TEXTURE_1D == object->texture_target) {
glCopyTexSubImage1D(object->texture_bind_target, object->texture_level, 0, 0, 0, object->width); glCopyTexSubImage1D(object->texture_target, object->texture_level, 0, 0, 0, object->width);
} else { } else {
glCopyTexSubImage2D(object->texture_bind_target, object->texture_level, 0, 0, 0, 0, object->width, object->height); glCopyTexSubImage2D(object->texture_target, object->texture_level, 0, 0, 0, 0, object->width, object->height);
} }
glBindTexture(object->texture_target, prev_binded_tex); glBindTexture(object->texture_target, prev_binded_tex);
SwapBuffers(object->render_hdc);
*/
glBindTexture(object->texture_target, object->texture);
if (GL_TEXTURE_1D == object->texture_target) {
glCopyTexSubImage1D(object->texture_target, object->texture_level, 0, 0, 0, object->width);
} else {
glCopyTexSubImage2D(object->texture_target, object->texture_level, 0, 0, 0, 0, object->width, object->height);
}
wglMakeCurrent(object->prev_hdc, object->prev_ctx);
return GL_TRUE; return GL_TRUE;
} }
if (NULL != p_glXReleaseTexImageARB) { if (NULL != p_glXReleaseTexImageARB) {
@ -1040,10 +1307,13 @@ GLboolean WINAPI wglSetPbufferAttribARB(HPBUFFERARB hPbuffer, const int *piAttri
SetLastError(ERROR_INVALID_HANDLE); SetLastError(ERROR_INVALID_HANDLE);
return GL_FALSE; return GL_FALSE;
} }
if (1 == use_render_texture_emulation) { if (!use_render_texture_ati && 1 == use_render_texture_emulation) {
return GL_TRUE; return GL_TRUE;
} }
if (NULL != p_glXDrawableAttribARB) { if (NULL != p_glXDrawableAttribARB) {
if (use_render_texture_ati) {
FIXME("Need conversion for GLX_ATI_render_texture\n");
}
return p_glXDrawableAttribARB(object->display, object->drawable, piAttribList); return p_glXDrawableAttribARB(object->display, object->drawable, piAttribList);
} }
return GL_FALSE; return GL_FALSE;