winemac: Implement WGL_ARB_render_texture.

This commit is contained in:
Ken Thomases 2013-03-06 04:59:25 -06:00 committed by Alexandre Julliard
parent be7231bea3
commit 8bbf09b412
1 changed files with 327 additions and 2 deletions

View File

@ -72,6 +72,10 @@ struct wgl_pbuffer
{
CGLPBufferObj pbuffer;
int format;
BOOL no_texture;
int max_level;
GLint level;
GLenum face;
};
static CFMutableDictionaryRef dc_pbuffers;
@ -1315,7 +1319,8 @@ static void make_context_current(struct wgl_context *context, BOOL read)
macdrv_make_context_current(context->context, view);
else
{
CGLSetPBuffer(context->cglcontext, pbuffer->pbuffer, 0, 0, 0);
CGLSetPBuffer(context->cglcontext, pbuffer->pbuffer, pbuffer->face,
pbuffer->level, 0);
CGLSetCurrentContext(context->cglcontext);
}
}
@ -1408,6 +1413,81 @@ static void macdrv_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
}
/***********************************************************************
* macdrv_wglBindTexImageARB
*
* WGL_ARB_render_texture: wglBindTexImageARB
*/
static BOOL macdrv_wglBindTexImageARB(struct wgl_pbuffer *pbuffer, int iBuffer)
{
struct wgl_context *context = NtCurrentTeb()->glContext;
GLenum source;
CGLError err;
TRACE("pbuffer %p iBuffer 0x%x\n", pbuffer, iBuffer);
if (pbuffer->no_texture)
{
SetLastError(ERROR_INVALID_OPERATION);
return GL_FALSE;
}
if (!context->draw_view && context->draw_pbuffer == pbuffer)
opengl_funcs.gl.p_glFlush();
switch (iBuffer)
{
case WGL_FRONT_LEFT_ARB:
if (pixel_formats[pbuffer->format].stereo)
source = GL_FRONT_LEFT;
else
source = GL_FRONT;
break;
case WGL_FRONT_RIGHT_ARB:
source = GL_FRONT_RIGHT;
break;
case WGL_BACK_LEFT_ARB:
if (pixel_formats[pbuffer->format].stereo)
source = GL_BACK_LEFT;
else
source = GL_BACK;
break;
case WGL_BACK_RIGHT_ARB:
source = GL_BACK_RIGHT;
break;
case WGL_AUX0_ARB: source = GL_AUX0; break;
case WGL_AUX1_ARB: source = GL_AUX1; break;
case WGL_AUX2_ARB: source = GL_AUX2; break;
case WGL_AUX3_ARB: source = GL_AUX3; break;
case WGL_AUX4_ARB:
case WGL_AUX5_ARB:
case WGL_AUX6_ARB:
case WGL_AUX7_ARB:
case WGL_AUX8_ARB:
case WGL_AUX9_ARB:
FIXME("unsupported source buffer 0x%x\n", iBuffer);
SetLastError(ERROR_INVALID_DATA);
return GL_FALSE;
default:
WARN("unknown source buffer 0x%x\n", iBuffer);
SetLastError(ERROR_INVALID_DATA);
return GL_FALSE;
}
err = CGLTexImagePBuffer(context->cglcontext, pbuffer->pbuffer, source);
if (err != kCGLNoError)
{
WARN("CGLTexImagePBuffer failed with err %d %s\n", err, CGLErrorString(err));
SetLastError(ERROR_INVALID_OPERATION);
return GL_FALSE;
}
return GL_TRUE;
}
/***********************************************************************
* macdrv_wglChoosePixelFormatARB
*
@ -1623,9 +1703,13 @@ static BOOL macdrv_wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList,
break;
case WGL_DRAW_TO_PBUFFER_ARB:
case WGL_BIND_TO_TEXTURE_RGB_ARB:
case WGL_BIND_TO_TEXTURE_RGBA_ARB:
if (valid.pbuffer && (!pf.pbuffer != !value)) goto cant_match;
pf.pbuffer = (value != 0);
valid.pbuffer = 1;
if (attr == WGL_BIND_TO_TEXTURE_RGBA_ARB && !alpha_bits)
alpha_bits = 1;
break;
default:
@ -1704,6 +1788,8 @@ static struct wgl_pbuffer *macdrv_wglCreatePbufferARB(HDC hdc, int iPixelFormat,
const int *piAttribList)
{
struct wgl_pbuffer* pbuffer;
GLenum target = 0;
GLenum internalFormat = 0;
CGLError err;
TRACE("hdc %p iPixelFormat %d iWidth %d iHeight %d piAttribList %p\n",
@ -1730,6 +1816,70 @@ static struct wgl_pbuffer *macdrv_wglCreatePbufferARB(HDC hdc, int iPixelFormat,
FIXME("WGL_PBUFFER_LARGEST_ARB: %d; ignoring\n", value);
break;
case WGL_TEXTURE_FORMAT_ARB:
switch (value)
{
case WGL_TEXTURE_RGBA_ARB:
TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_TEXTURE_RGBA_ARB\n");
internalFormat = GL_RGBA;
break;
case WGL_TEXTURE_RGB_ARB:
TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_TEXTURE_RGB_ARB\n");
internalFormat = GL_RGB;
break;
case WGL_NO_TEXTURE_ARB:
TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_NO_TEXTURE_ARB\n");
internalFormat = 0;
break;
default:
WARN("unknown WGL_TEXTURE_FORMAT_ARB value 0x%x\n", value);
SetLastError(ERROR_INVALID_DATA);
goto done;
}
break;
case WGL_TEXTURE_TARGET_ARB:
pbuffer->face = 0;
switch (value)
{
case WGL_NO_TEXTURE_ARB:
TRACE("WGL_TEXTURE_TARGET_ARB: WGL_NO_TEXTURE_ARB\n");
target = 0;
break;
case WGL_TEXTURE_CUBE_MAP_ARB:
TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_CUBE_MAP_ARB\n");
target = GL_TEXTURE_CUBE_MAP;
pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
break;
case WGL_TEXTURE_1D_ARB:
FIXME("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_1D_ARB; not supported\n");
SetLastError(ERROR_NO_SYSTEM_RESOURCES);
goto done;
case WGL_TEXTURE_2D_ARB:
TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_2D_ARB\n");
target = GL_TEXTURE_2D;
break;
default:
WARN("unknown WGL_TEXTURE_TARGET_ARB value 0x%x\n", value);
SetLastError(ERROR_INVALID_DATA);
goto done;
}
break;
case WGL_MIPMAP_TEXTURE_ARB:
TRACE("WGL_MIPMAP_TEXTURE_ARB: %d\n", value);
pbuffer->max_level = 0;
if (value)
{
int size = min(iWidth, iHeight) / 2;
while (size)
{
pbuffer->max_level++;
size /= 2;
}
}
break;
default:
WARN("unknown attribute 0x%x\n", attr);
SetLastError(ERROR_INVALID_DATA);
@ -1737,7 +1887,15 @@ static struct wgl_pbuffer *macdrv_wglCreatePbufferARB(HDC hdc, int iPixelFormat,
}
}
err = CGLCreatePBuffer(iWidth, iHeight, GL_TEXTURE_RECTANGLE, GL_RGB, 0, &pbuffer->pbuffer);
if (!target || !internalFormat)
{
pbuffer->no_texture = TRUE;
/* no actual way to turn off ability to texture; use most permissive target */
target = GL_TEXTURE_RECTANGLE;
internalFormat = GL_RGB;
}
err = CGLCreatePBuffer(iWidth, iHeight, target, internalFormat, pbuffer->max_level, &pbuffer->pbuffer);
if (err != kCGLNoError)
{
WARN("CGLCreatePBuffer failed; err %d %s\n", err, CGLErrorString(err));
@ -2085,9 +2243,14 @@ static BOOL macdrv_wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int i
break;
case WGL_DRAW_TO_PBUFFER_ARB:
case WGL_BIND_TO_TEXTURE_RGB_ARB:
piValues[i] = pf->pbuffer ? GL_TRUE : GL_FALSE;
break;
case WGL_BIND_TO_TEXTURE_RGBA_ARB:
piValues[i] = (pf->pbuffer && color_modes[pf->color_mode].alpha_bits) ? GL_TRUE : GL_FALSE;
break;
case WGL_MAX_PBUFFER_WIDTH_ARB:
piValues[i] = gl_info.max_viewport_dims[0];
break;
@ -2304,6 +2467,65 @@ static BOOL macdrv_wglQueryPbufferARB(struct wgl_pbuffer *pbuffer, int iAttribut
/* Mac PBuffers can't be lost */
*piValue = GL_FALSE;
break;
case WGL_TEXTURE_FORMAT_ARB:
if (pbuffer->no_texture)
*piValue = WGL_NO_TEXTURE_ARB;
else switch (internalFormat)
{
case GL_RGBA:
*piValue = WGL_TEXTURE_RGBA_ARB;
break;
case GL_RGB:
default:
*piValue = WGL_TEXTURE_RGB_ARB;
break;
}
break;
case WGL_TEXTURE_TARGET_ARB:
if (pbuffer->no_texture)
*piValue = WGL_NO_TEXTURE_ARB;
else switch (target)
{
case GL_TEXTURE_CUBE_MAP:
*piValue = WGL_TEXTURE_CUBE_MAP_ARB;
break;
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE:
default:
*piValue = WGL_TEXTURE_2D_ARB;
break;
}
break;
case WGL_MIPMAP_TEXTURE_ARB:
*piValue = (pbuffer->max_level > 0);
break;
case WGL_MIPMAP_LEVEL_ARB:
*piValue = pbuffer->level;
break;
case WGL_CUBE_MAP_FACE_ARB:
switch (pbuffer->face)
{
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
default:
*piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
*piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
*piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
*piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
*piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
*piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB;
break;
}
break;
default:
WARN("invalid attribute 0x%x\n", iAttribute);
SetLastError(ERROR_INVALID_DATA);
@ -2344,6 +2566,104 @@ static int macdrv_wglReleasePbufferDCARB(struct wgl_pbuffer *pbuffer, HDC hdc)
}
/**********************************************************************
* macdrv_wglReleaseTexImageARB
*
* WGL_ARB_render_texture: wglReleaseTexImageARB
*/
static BOOL macdrv_wglReleaseTexImageARB(struct wgl_pbuffer *pbuffer, int iBuffer)
{
struct wgl_context *context = NtCurrentTeb()->glContext;
CGLError err;
TRACE("pbuffer %p iBuffer 0x%x; stub!\n", pbuffer, iBuffer);
if (pbuffer->no_texture)
{
SetLastError(ERROR_INVALID_OPERATION);
return GL_FALSE;
}
err = CGLTexImagePBuffer(context->cglcontext, pbuffer->pbuffer, GL_NONE);
if (err != kCGLNoError)
{
WARN("CGLTexImagePBuffer failed with err %d %s\n", err, CGLErrorString(err));
SetLastError(ERROR_INVALID_OPERATION);
return GL_FALSE;
}
return GL_TRUE;
}
/**********************************************************************
* macdrv_wglSetPbufferAttribARB
*
* WGL_ARB_render_texture: wglSetPbufferAttribARB
*/
static BOOL macdrv_wglSetPbufferAttribARB(struct wgl_pbuffer *pbuffer, const int *piAttribList)
{
struct wgl_context *context = NtCurrentTeb()->glContext;
TRACE("pbuffer %p piAttribList %p\n", pbuffer, piAttribList);
for ( ; piAttribList && *piAttribList; piAttribList += 2)
{
int attr = piAttribList[0];
int value = piAttribList[1];
switch (attr)
{
case WGL_MIPMAP_LEVEL_ARB:
TRACE("WGL_MIPMAP_LEVEL_ARB: %d\n", value);
pbuffer->level = value;
break;
case WGL_CUBE_MAP_FACE_ARB:
switch (value)
{
case WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB\n");
pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
break;
case WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB\n");
pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
break;
case WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB\n");
pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
break;
case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB\n");
pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
break;
case WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB\n");
pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
break;
case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB\n");
pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
break;
default:
WARN("unknown WGL_CUBE_MAP_FACE_ARB value 0x%x\n", value);
SetLastError(ERROR_INVALID_DATA);
return GL_FALSE;
}
break;
default:
WARN("invalide attribute 0x%x\n", attr);
SetLastError(ERROR_INVALID_DATA);
return GL_FALSE;
}
}
if (context && context->draw_pbuffer == pbuffer)
make_context_current(context, FALSE);
return GL_TRUE;
}
/**********************************************************************
* macdrv_wglSetPixelFormatWINE
*
@ -2401,6 +2721,11 @@ static void load_extensions(void)
opengl_funcs.ext.p_wglGetPbufferDCARB = macdrv_wglGetPbufferDCARB;
opengl_funcs.ext.p_wglQueryPbufferARB = macdrv_wglQueryPbufferARB;
opengl_funcs.ext.p_wglReleasePbufferDCARB = macdrv_wglReleasePbufferDCARB;
register_extension("WGL_ARB_render_texture");
opengl_funcs.ext.p_wglBindTexImageARB = macdrv_wglBindTexImageARB;
opengl_funcs.ext.p_wglReleaseTexImageARB = macdrv_wglReleaseTexImageARB;
opengl_funcs.ext.p_wglSetPbufferAttribARB = macdrv_wglSetPbufferAttribARB;
}
/* TODO: