st/mesa: need to translate clear color according to surface's base format

When clearing a GL_LUMINANCE_ALPHA buffer, for example, we need to convert
the clear color (R,G,B,A) to (R,R,R,A).  We were doing this for texture border
colors but not renderbuffers.  Move the translation function to st_format.c
and share it.

This fixes the piglit fbo-clear-formats test.

NOTE: This is a candidate for the 7.9 and 7.10 branches.
This commit is contained in:
Brian Paul 2011-02-21 16:54:23 -07:00
parent c966c6980c
commit e2d108ec82
4 changed files with 75 additions and 47 deletions

View file

@ -36,6 +36,7 @@
#include "st_context.h"
#include "st_cb_texture.h"
#include "st_format.h"
#include "st_atom.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@ -117,49 +118,6 @@ gl_filter_to_img_filter(GLenum filter)
}
static void
xlate_border_color(const GLfloat *colorIn, GLenum baseFormat, GLfloat *colorOut)
{
switch (baseFormat) {
case GL_RED:
colorOut[0] = colorIn[0];
colorOut[1] = 0.0F;
colorOut[2] = 0.0F;
colorOut[3] = 1.0F;
break;
case GL_RG:
colorOut[0] = colorIn[0];
colorOut[1] = colorIn[1];
colorOut[2] = 0.0F;
colorOut[3] = 1.0F;
break;
case GL_RGB:
colorOut[0] = colorIn[0];
colorOut[1] = colorIn[1];
colorOut[2] = colorIn[2];
colorOut[3] = 1.0F;
break;
case GL_ALPHA:
colorOut[0] = colorOut[1] = colorOut[2] = 0.0;
colorOut[3] = colorIn[3];
break;
case GL_LUMINANCE:
colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
colorOut[3] = 1.0;
break;
case GL_LUMINANCE_ALPHA:
colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
colorOut[3] = colorIn[3];
break;
case GL_INTENSITY:
colorOut[0] = colorOut[1] = colorOut[2] = colorOut[3] = colorIn[0];
break;
default:
COPY_4V(colorOut, colorIn);
}
}
static void
update_samplers(struct st_context *st)
{
@ -223,7 +181,7 @@ update_samplers(struct st_context *st)
assert(sampler->min_lod <= sampler->max_lod);
}
xlate_border_color(texobj->BorderColor.f,
st_translate_color(texobj->BorderColor.f,
teximg ? teximg->_BaseFormat : GL_RGBA,
sampler->border_color);

View file

@ -42,6 +42,7 @@
#include "st_cb_accum.h"
#include "st_cb_clear.h"
#include "st_cb_fbo.h"
#include "st_format.h"
#include "st_program.h"
#include "pipe/p_context.h"
@ -204,6 +205,7 @@ clear_with_quad(struct gl_context *ctx,
const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
float clearColor[4];
/*
printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__,
@ -298,9 +300,12 @@ clear_with_quad(struct gl_context *ctx,
cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
/* draw quad matching scissor rect (XXX verify coord round-off) */
draw_quad(st, x0, y0, x1, y1,
(GLfloat) ctx->Depth.Clear, ctx->Color.ClearColor);
st_translate_color(ctx->Color.ClearColor,
ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
clearColor);
/* draw quad matching scissor rect */
draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, clearColor);
/* Restore pipe state */
cso_restore_blend(st->cso_context);
@ -541,12 +546,19 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
* required from the visual. Hence fix this up to avoid potential
* read-modify-write in the driver.
*/
float clearColor[4];
if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) &&
((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
(depthRb == stencilRb) &&
(ctx->DrawBuffer->Visual.depthBits == 0 ||
ctx->DrawBuffer->Visual.stencilBits == 0))
clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
st_translate_color(ctx->Color.ClearColor,
ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
clearColor);
st->pipe->clear(st->pipe, clear_buffers, ctx->Color.ClearColor,
ctx->Depth.Clear, ctx->Stencil.Clear);
}

View file

@ -1095,3 +1095,55 @@ st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2)
return GL_FALSE;
}
/**
* This is used for translating texture border color and the clear
* color. For example, the clear color is interpreted according to
* the renderbuffer's base format. For example, if clearing a
* GL_LUMINANCE buffer, ClearColor[0] = luminance and ClearColor[1] =
* alpha. Similarly for texture border colors.
*/
void
st_translate_color(const GLfloat colorIn[4], GLenum baseFormat,
GLfloat colorOut[4])
{
switch (baseFormat) {
case GL_RED:
colorOut[0] = colorIn[0];
colorOut[1] = 0.0F;
colorOut[2] = 0.0F;
colorOut[3] = 1.0F;
break;
case GL_RG:
colorOut[0] = colorIn[0];
colorOut[1] = colorIn[1];
colorOut[2] = 0.0F;
colorOut[3] = 1.0F;
break;
case GL_RGB:
colorOut[0] = colorIn[0];
colorOut[1] = colorIn[1];
colorOut[2] = colorIn[2];
colorOut[3] = 1.0F;
break;
case GL_ALPHA:
colorOut[0] = colorOut[1] = colorOut[2] = 0.0;
colorOut[3] = colorIn[3];
break;
case GL_LUMINANCE:
colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
colorOut[3] = 1.0;
break;
case GL_LUMINANCE_ALPHA:
colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
colorOut[3] = colorIn[3];
break;
case GL_INTENSITY:
colorOut[0] = colorOut[1] = colorOut[2] = colorOut[3] = colorIn[0];
break;
default:
COPY_4V(colorOut, colorIn);
}
}

View file

@ -77,4 +77,10 @@ st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type);
extern GLboolean
st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2);
extern void
st_translate_color(const GLfloat colorIn[4], GLenum baseFormat,
GLfloat colorOut[4]);
#endif /* ST_FORMAT_H */