i965: Fix handling of drawing to MESA_FORMAT_XRGB8888

It turns out that 965 and friends cannot actually render to an xRGB
surfaces.  Instead, the surface has to be RGBA with writes to alpha
disabled and the blend function modified to always use 1.0 for
destination alpha.
This commit is contained in:
Ian Romanick 2009-12-08 21:13:05 -08:00
parent 4f2b2032f4
commit eadd9b8e16
2 changed files with 48 additions and 3 deletions

View File

@ -34,6 +34,7 @@
#include "brw_state.h"
#include "brw_defines.h"
#include "brw_util.h"
#include "intel_fbo.h"
#include "main/macros.h"
#include "main/enums.h"
@ -89,6 +90,28 @@ struct brw_cc_unit_key {
GLenum depth_func;
};
/**
* Modify blend function to force destination alpha to 1.0
*
* If \c function specifies a blend function that uses destination alpha,
* replace it with a function that hard-wires destination alpha to 1.0. This
* is used when rendering to xRGB targets.
*/
static GLenum
fix_xRGB_alpha(GLenum function)
{
switch (function) {
case GL_DST_ALPHA:
return GL_ONE;
case GL_ONE_MINUS_DST_ALPHA:
case GL_SRC_ALPHA_SATURATE:
return GL_ZERO;
}
return function;
}
static void
cc_unit_populate_key(struct brw_context *brw, struct brw_cc_unit_key *key)
{
@ -132,6 +155,17 @@ cc_unit_populate_key(struct brw_context *brw, struct brw_cc_unit_key *key)
key->blend_dst_rgb = ctx->Color.BlendDstRGB;
key->blend_src_a = ctx->Color.BlendSrcA;
key->blend_dst_a = ctx->Color.BlendDstA;
/* If the renderbuffer is XRGB, we have to frob the blend function to
* force the destination alpha to 1.0. This means replacing GL_DST_ALPHA
* with GL_ONE and GL_ONE_MINUS_DST_ALPAH with GL_ZERO.
*/
if (ctx->Visual.alphaBits == 0) {
key->blend_src_rgb = fix_xRGB_alpha(key->blend_src_rgb);
key->blend_src_a = fix_xRGB_alpha(key->blend_src_a);
key->blend_dst_rgb = fix_xRGB_alpha(key->blend_dst_rgb);
key->blend_dst_a = fix_xRGB_alpha(key->blend_dst_a);
}
}
key->alpha_enabled = ctx->Color.AlphaEnabled;

View File

@ -538,11 +538,15 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
key.surface_type = BRW_SURFACE_2D;
switch (irb->Base.Format) {
/* XRGB and ARGB are treated the same here because the chips in this
* family cannot render to XRGB targets. This means that we have to
* mask writes to alpha (ala glColorMask) and reconfigure the alpha
* blending hardware to use GL_ONE (or GL_ZERO) for cases where
* GL_DST_ALPHA (or GL_ONE_MINUS_DST_ALPHA) is used.
*/
case MESA_FORMAT_ARGB8888:
key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
break;
case MESA_FORMAT_XRGB8888:
key.surface_format = BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
break;
case MESA_FORMAT_RGB565:
key.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
@ -579,6 +583,13 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
/* _NEW_COLOR */
memcpy(key.color_mask, ctx->Color.ColorMask,
sizeof(key.color_mask));
/* As mentioned above, disable writes to the alpha component when the
* renderbuffer is XRGB.
*/
if (ctx->Visual.alphaBits == 0)
key.color_mask[3] = GL_FALSE;
key.color_blend = (!ctx->Color._LogicOpEnabled &&
ctx->Color.BlendEnabled);