wined3d: Check resource types separately in check_fbo_compat.

This commit is contained in:
Stefan Dösinger 2015-05-22 10:11:21 +02:00 committed by Alexandre Julliard
parent c5a029f82e
commit bd658a15b9
1 changed files with 333 additions and 210 deletions

View File

@ -1401,216 +1401,6 @@ static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
return TRUE; return TRUE;
} }
/* Context activation is done by the caller. */
static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
{
/* Check if the default internal format is supported as a frame buffer
* target, otherwise fall back to the render target internal.
*
* Try to stick to the standard format if possible, this limits precision differences. */
GLenum status;
GLuint tex;
while (gl_info->gl_ops.gl.p_glGetError());
gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
format->glFormat, format->glType, NULL);
gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
checkGLcall("Framebuffer format check");
if (status == GL_FRAMEBUFFER_COMPLETE)
{
TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
format_set_flag(format, WINED3DFMT_FLAG_FBO_ATTACHABLE);
format->rtInternal = format->glInternal;
}
else
{
if (!format->rtInternal)
{
if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_RENDERTARGET)
{
FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
" and no fallback specified.\n", debug_d3dformat(format->id));
format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET);
}
else
{
TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
}
format->rtInternal = format->glInternal;
}
else
{
TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
debug_d3dformat(format->id));
while (gl_info->gl_ops.gl.p_glGetError());
gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
format->glFormat, format->glType, NULL);
gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
checkGLcall("Framebuffer format check");
if (status == GL_FRAMEBUFFER_COMPLETE)
{
TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
debug_d3dformat(format->id));
}
else
{
FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
debug_d3dformat(format->id));
format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET);
}
}
}
if (status == GL_FRAMEBUFFER_COMPLETE
&& ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
|| !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
&& format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
&& format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
&& (format->red_size || format->alpha_size))
{
DWORD readback[16 * 16], color, r_range, a_range;
BYTE r, a;
BOOL match = TRUE;
GLuint rb;
if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
|| gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
{
gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
checkGLcall("RB attachment");
}
gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
{
while (gl_info->gl_ops.gl.p_glGetError());
TRACE("Format doesn't support post-pixelshader blending.\n");
format_clear_flag(format, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING);
}
else
{
gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
gl_info->gl_ops.gl.p_glLoadIdentity();
gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
gl_info->gl_ops.gl.p_glLoadIdentity();
gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* Draw a full-black quad */
gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
gl_info->gl_ops.gl.p_glEnd();
gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
/* Draw a half-transparent red quad */
gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
gl_info->gl_ops.gl.p_glEnd();
gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
/* Rebinding texture to workaround a fglrx bug. */
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
checkGLcall("Post-pixelshader blending check");
color = readback[7 * 16 + 7];
a = color >> 24;
r = (color & 0x00ff0000) >> 16;
r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
match = FALSE;
else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
match = FALSE;
if (!match)
{
TRACE("Format doesn't support post-pixelshader blending.\n");
TRACE("Color output: %#x\n", color);
format_clear_flag(format, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING);
}
else
{
TRACE("Format supports post-pixelshader blending.\n");
TRACE("Color output: %#x\n", color);
format_set_flag(format, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING);
}
}
if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
|| gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
{
gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
checkGLcall("RB cleanup");
}
}
if (format->glInternal != format->glGammaInternal)
{
gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
format->glFormat, format->glType, NULL);
gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
checkGLcall("Framebuffer format check");
if (status == GL_FRAMEBUFFER_COMPLETE)
{
TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
format_set_flag(format, WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB);
}
else
{
WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
}
}
else if (status == GL_FRAMEBUFFER_COMPLETE)
format_set_flag(format, WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB);
gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
}
static GLenum wined3d_gl_type_to_enum(enum wined3d_gl_resource_type type) static GLenum wined3d_gl_type_to_enum(enum wined3d_gl_resource_type type)
{ {
switch (type) switch (type)
@ -1634,6 +1424,339 @@ static GLenum wined3d_gl_type_to_enum(enum wined3d_gl_resource_type type)
return 0; return 0;
} }
static void delete_fbo_attachment(const struct wined3d_gl_info *gl_info)
{
gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, 0, 0);
}
/* Context activation is done by the caller. */
static void create_and_bind_fbo_attachment(const struct wined3d_gl_info *gl_info,
enum wined3d_gl_resource_type d3d_type, GLuint tex, GLenum internal, GLenum format, GLenum type)
{
switch (d3d_type)
{
case WINED3D_GL_RES_TYPE_TEX_1D:
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, tex);
gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, internal, 16, 0, format, type, NULL);
gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl_info->fbo_ops.glFramebufferTexture1D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_1D, tex, 0);
break;
case WINED3D_GL_RES_TYPE_TEX_2D:
case WINED3D_GL_RES_TYPE_TEX_RECT:
gl_info->gl_ops.gl.p_glBindTexture(wined3d_gl_type_to_enum(d3d_type), tex);
gl_info->gl_ops.gl.p_glTexImage2D(wined3d_gl_type_to_enum(d3d_type), 0, internal, 16, 16, 0,
format, type, NULL);
gl_info->gl_ops.gl.p_glTexParameteri(wined3d_gl_type_to_enum(d3d_type), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl_info->gl_ops.gl.p_glTexParameteri(wined3d_gl_type_to_enum(d3d_type), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
wined3d_gl_type_to_enum(d3d_type), tex, 0);
break;
case WINED3D_GL_RES_TYPE_TEX_3D:
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, tex);
GL_EXTCALL(glTexImage3D)(GL_TEXTURE_3D, 0, internal, 16, 16, 16, 0,
format, type, NULL);
gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl_info->fbo_ops.glFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_3D, tex, 0, 0);
break;
case WINED3D_GL_RES_TYPE_TEX_CUBE:
gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, tex);
gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, internal, 16, 16, 0,
format, type, NULL);
gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, internal, 16, 16, 0,
format, type, NULL);
gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, internal, 16, 16, 0,
format, type, NULL);
gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, internal, 16, 16, 0,
format, type, NULL);
gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, internal, 16, 16, 0,
format, type, NULL);
gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, internal, 16, 16, 0,
format, type, NULL);
gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, tex, 0);
break;
case WINED3D_GL_RES_TYPE_BUFFER:
case WINED3D_GL_RES_TYPE_COUNT:
break;
}
}
/* Context activation is done by the caller. */
static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
{
/* Check if the default internal format is supported as a frame buffer
* target, otherwise fall back to the render target internal.
*
* Try to stick to the standard format if possible, this limits precision differences. */
GLenum status, rt_internal = format->rtInternal;
GLuint tex;
enum wined3d_gl_resource_type type;
BOOL fallback_fmt_used = FALSE, regular_fmt_used = FALSE;
gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
for (type = 0; type < ARRAY_SIZE(format->flags); ++type)
{
if (type == WINED3D_GL_RES_TYPE_BUFFER)
continue;
/* Ideally we'd skip all formats already known not to work on textures
* by checking for WINED3DFMT_FLAG_TEXTURE here. However, we want to
* know if we can attach WINED3DFMT_P8_UINT textures to FBOs, and this
* format never has WINED3DFMT_FLAG_TEXTURE set. Instead, swallow GL
* errors generated by invalid formats. */
gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
create_and_bind_fbo_attachment(gl_info, type, tex, format->glInternal,
format->glFormat, format->glType);
while (gl_info->gl_ops.gl.p_glGetError());
status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
checkGLcall("Framebuffer format check");
if (status == GL_FRAMEBUFFER_COMPLETE)
{
TRACE("Format %s is supported as FBO color attachment, type %u.\n",
debug_d3dformat(format->id), type);
format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
format->rtInternal = format->glInternal;
regular_fmt_used = TRUE;
}
else
{
if (!rt_internal)
{
if (format->flags[type] & WINED3DFMT_FLAG_RENDERTARGET)
{
FIXME("Format %s with rendertarget flag is not supported as FBO color attachment (type %u),"
" and no fallback specified.\n", debug_d3dformat(format->id), type);
format->flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET;
}
else
{
TRACE("Format %s is not supported as FBO color attachment, type %u.\n",
debug_d3dformat(format->id), type);
}
format->rtInternal = format->glInternal;
}
else
{
TRACE("Format %s is not supported as FBO color attachment (type %u),"
" trying rtInternal format as fallback.\n", debug_d3dformat(format->id), type);
while (gl_info->gl_ops.gl.p_glGetError());
delete_fbo_attachment(gl_info);
create_and_bind_fbo_attachment(gl_info, type, tex, format->rtInternal,
format->glFormat, format->glType);
status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
checkGLcall("Framebuffer format check");
if (status == GL_FRAMEBUFFER_COMPLETE)
{
TRACE("Format %s rtInternal format is supported as FBO color attachment, type %u.\n",
debug_d3dformat(format->id), type);
fallback_fmt_used = TRUE;
}
else
{
FIXME("Format %s rtInternal format is not supported as FBO color attachment, type %u.\n",
debug_d3dformat(format->id), type);
format->flags[type] &= ~WINED3DFMT_FLAG_RENDERTARGET;
}
}
}
if (status == GL_FRAMEBUFFER_COMPLETE
&& ((format->flags[type] & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
|| !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
&& format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
&& format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
&& (format->red_size || format->alpha_size))
{
DWORD readback[16 * 16 * 16], color, r_range, a_range;
BYTE r, a;
BOOL match = TRUE;
GLuint rb;
if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
|| gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
{
gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
if (type == WINED3D_GL_RES_TYPE_TEX_1D)
gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 1);
else
gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
checkGLcall("RB attachment");
}
gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
{
while (gl_info->gl_ops.gl.p_glGetError());
TRACE("Format %s doesn't support post-pixelshader blending, type %u.\n",
debug_d3dformat(format->id), type);
format->flags[type] &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
}
else
{
gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
if (type == WINED3D_GL_RES_TYPE_TEX_1D)
gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
else
gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
gl_info->gl_ops.gl.p_glLoadIdentity();
gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
gl_info->gl_ops.gl.p_glLoadIdentity();
gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* Draw a full-black quad */
gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
gl_info->gl_ops.gl.p_glEnd();
gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
/* Draw a half-transparent red quad */
gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
gl_info->gl_ops.gl.p_glEnd();
gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
/* Rebinding texture to workaround a fglrx bug. */
gl_info->gl_ops.gl.p_glBindTexture(wined3d_gl_type_to_enum(type), tex);
switch (type)
{
case WINED3D_GL_RES_TYPE_TEX_1D:
gl_info->gl_ops.gl.p_glGetTexImage(wined3d_gl_type_to_enum(type), 0, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, readback);
color = readback[7];
break;
case WINED3D_GL_RES_TYPE_TEX_2D:
case WINED3D_GL_RES_TYPE_TEX_3D:
case WINED3D_GL_RES_TYPE_TEX_RECT:
gl_info->gl_ops.gl.p_glGetTexImage(wined3d_gl_type_to_enum(type), 0, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, readback);
color = readback[7 * 16 + 7];
break;
case WINED3D_GL_RES_TYPE_TEX_CUBE:
gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, readback);
color = readback[7 * 16 + 7];
break;
case WINED3D_GL_RES_TYPE_BUFFER:
case WINED3D_GL_RES_TYPE_COUNT:
color = 0;
break;
}
checkGLcall("Post-pixelshader blending check");
a = color >> 24;
r = (color & 0x00ff0000) >> 16;
r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
match = FALSE;
else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
match = FALSE;
if (!match)
{
TRACE("Format %s doesn't support post-pixelshader blending, type %u.\n",
debug_d3dformat(format->id), type);
TRACE("Color output: %#x\n", color);
format->flags[type] &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
}
else
{
TRACE("Format %s supports post-pixelshader blending, type %u.\n",
debug_d3dformat(format->id), type);
TRACE("Color output: %#x\n", color);
format->flags[type] |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
}
}
if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
|| gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
{
gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
checkGLcall("RB cleanup");
}
}
if (format->glInternal != format->glGammaInternal)
{
delete_fbo_attachment(gl_info);
create_and_bind_fbo_attachment(gl_info, type, tex, format->glGammaInternal,
format->glFormat, format->glType);
status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
checkGLcall("Framebuffer format check");
if (status == GL_FRAMEBUFFER_COMPLETE)
{
TRACE("Format %s's sRGB format is FBO attachable, type %u.\n",
debug_d3dformat(format->id), type);
format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
}
else
{
WARN("Format %s's sRGB format is not FBO attachable, type %u.\n",
debug_d3dformat(format->id), type);
}
}
else if (status == GL_FRAMEBUFFER_COMPLETE)
format->flags[type] |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
delete_fbo_attachment(gl_info);
gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
}
if (fallback_fmt_used && regular_fmt_used)
{
FIXME("Format %s needs different render target formats for different resource types.\n",
debug_d3dformat(format->id));
format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FBO_ATTACHABLE
| WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING);
}
}
static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format *format, static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format *format,
GLint internal, GLenum pname, DWORD flag, const char *string) GLint internal, GLenum pname, DWORD flag, const char *string)
{ {