wined3d: Check resource types separately in check_fbo_compat.
This commit is contained in:
parent
c5a029f82e
commit
bd658a15b9
|
@ -1401,216 +1401,6 @@ static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
|
|||
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)
|
||||
{
|
||||
switch (type)
|
||||
|
@ -1634,6 +1424,339 @@ static GLenum wined3d_gl_type_to_enum(enum wined3d_gl_resource_type type)
|
|||
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,
|
||||
GLint internal, GLenum pname, DWORD flag, const char *string)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue