[PATCH 3/4] wined3d: Check resource types separately in check_fbo_compat.
Stefan Dösinger
stefan at codeweavers.com
Sat May 16 08:29:14 CDT 2015
---
dlls/wined3d/utils.c | 511 ++++++++++++++++++++++++++++++++-------------------
1 file changed, 327 insertions(+), 184 deletions(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 94ed858..f0eb4f4 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -1401,6 +1401,124 @@ static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
return TRUE;
}
+static GLenum wined3d_gl_type_to_enum(enum wined3d_gl_resource_type type)
+{
+ switch (type)
+ {
+ case WINED3D_GL_RES_TYPE_TEX_1D:
+ return GL_TEXTURE_1D;
+ case WINED3D_GL_RES_TYPE_TEX_2D:
+ return GL_TEXTURE_2D;
+ case WINED3D_GL_RES_TYPE_TEX_3D:
+ return GL_TEXTURE_3D;
+ case WINED3D_GL_RES_TYPE_TEX_CUBE:
+ return GL_TEXTURE_CUBE_MAP_ARB;
+ case WINED3D_GL_RES_TYPE_TEX_RECT:
+ return GL_TEXTURE_RECTANGLE_ARB;
+ case WINED3D_GL_RES_TYPE_BUFFER:
+ return GL_TEXTURE_2D; /* TODO: GL_TEXTURE_BUFFER. */
+ case WINED3D_GL_RES_TYPE_COUNT:
+ break;
+ }
+ ERR("Unexpected GL resource type %u.\n", type);
+ return 0;
+}
+
+static void delete_fbo_attachment(const struct wined3d_gl_info *gl_info,
+ enum wined3d_gl_resource_type d3d_type)
+{
+ switch (d3d_type)
+ {
+ case WINED3D_GL_RES_TYPE_TEX_1D:
+ gl_info->fbo_ops.glFramebufferTexture1D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_1D, 0, 0);
+ break;
+
+ case WINED3D_GL_RES_TYPE_TEX_2D:
+ case WINED3D_GL_RES_TYPE_TEX_RECT:
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ wined3d_gl_type_to_enum(d3d_type), 0, 0);
+ break;
+
+ case WINED3D_GL_RES_TYPE_TEX_3D:
+ gl_info->fbo_ops.glFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, 0, 0, 0);
+ break;
+
+ case WINED3D_GL_RES_TYPE_TEX_CUBE:
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, 0);
+ break;
+
+ case WINED3D_GL_RES_TYPE_BUFFER:
+ case WINED3D_GL_RES_TYPE_COUNT:
+ break;
+ }
+}
+
+/* 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)
{
@@ -1408,230 +1526,255 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined
* target, otherwise fall back to the render target internal.
*
* Try to stick to the standard format if possible, this limits precision differences. */
- GLenum status;
+ GLenum status, rt_internal = format->rtInternal;
GLuint tex;
+ enum wined3d_gl_resource_type type;
+ BOOL fallback_fmt_used = FALSE, regular_fmt_used = FALSE;
- 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);
+ for (type = 0; type < ARRAY_SIZE(format->flags); ++type)
+ {
+ if (type == WINED3D_GL_RES_TYPE_BUFFER)
+ continue;
- 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);
+ /* 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->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+ 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");
+ 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 (status == GL_FRAMEBUFFER_COMPLETE)
{
- 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));
- }
+ 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
{
- TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
- debug_d3dformat(format->id));
+ 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());
+ while (gl_info->gl_ops.gl.p_glGetError());
- gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
+ delete_fbo_attachment(gl_info, type);
+ create_and_bind_fbo_attachment(gl_info, type, tex, format->rtInternal,
+ format->glFormat, format->glType);
- 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);
+ status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ checkGLcall("Framebuffer format check");
- gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+ 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;
+ }
+ }
+ }
- status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
- checkGLcall("Framebuffer format check");
+ 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 (status == GL_FRAMEBUFFER_COMPLETE)
+ if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
+ || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
{
- TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
- debug_d3dformat(format->id));
+ 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");
}
- else
+
+ 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)
{
- FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
- debug_d3dformat(format->id));
- format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET);
+ 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);
+ 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;
- 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;
+ 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;
- 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");
- }
+ 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;
- 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);
+ case WINED3D_GL_RES_TYPE_BUFFER:
+ case WINED3D_GL_RES_TYPE_COUNT:
+ 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");
+ }
}
- else
+
+ if (format->glInternal != format->glGammaInternal)
{
- 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();
+ delete_fbo_attachment(gl_info, type);
+ create_and_bind_fbo_attachment(gl_info, type, tex, format->glGammaInternal,
+ format->glFormat, format->glType);
- 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)
+ status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ checkGLcall("Framebuffer format check");
+
+ if (status == GL_FRAMEBUFFER_COMPLETE)
{
- TRACE("Format doesn't support post-pixelshader blending.\n");
- TRACE("Color output: %#x\n", color);
- format_clear_flag(format, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING);
+ 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
{
- TRACE("Format supports post-pixelshader blending.\n");
- TRACE("Color output: %#x\n", color);
- format_set_flag(format, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING);
+ 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;
- 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));
- }
+ delete_fbo_attachment(gl_info, type);
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
}
- 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)
+ if (fallback_fmt_used && regular_fmt_used)
{
- case WINED3D_GL_RES_TYPE_TEX_1D:
- return GL_TEXTURE_1D;
- case WINED3D_GL_RES_TYPE_TEX_2D:
- return GL_TEXTURE_2D;
- case WINED3D_GL_RES_TYPE_TEX_3D:
- return GL_TEXTURE_3D;
- case WINED3D_GL_RES_TYPE_TEX_CUBE:
- return GL_TEXTURE_CUBE_MAP_ARB;
- case WINED3D_GL_RES_TYPE_TEX_RECT:
- return GL_TEXTURE_RECTANGLE_ARB;
- case WINED3D_GL_RES_TYPE_BUFFER:
- return GL_TEXTURE_2D; /* TODO: GL_TEXTURE_BUFFER. */
- case WINED3D_GL_RES_TYPE_COUNT:
- break;
+ 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);
}
- ERR("Unexpected GL resource type %u.\n", type);
- return 0;
}
static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format *format,
--
2.3.6
More information about the wine-patches
mailing list