st/mesa: ensure that all pixel paths operation on linear RGB data, not sRGB

Before, we were converting between linear/sRGB in glReadPixels,
glDrawPixels, glAccum, etc if the renderbuffer was an sRGB texture.
Those all need to operate on pixel values as-is without conversion.

Also, when setting up render-to-texture, if the texture is sRGB the
pipe_surface view must be linear RGB.  This will change when we
support GL_ARB_framebuffer_sRGB.

This fixes http://bugs.freedesktop.org/show_bug.cgi?id=33353
This commit is contained in:
Brian Paul 2011-01-22 18:28:20 -07:00
parent 4c9ad084c1
commit 9d380f487a
5 changed files with 39 additions and 18 deletions

View File

@ -42,6 +42,7 @@
#include "st_texture.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "util/u_format.h"
#include "util/u_inlines.h"
#include "util/u_tile.h"
@ -146,7 +147,9 @@ accum_accum(struct st_context *st, GLfloat value,
buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
pipe_get_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
util_format_linear(color_strb->texture->format),
buf);
switch (acc_strb->format) {
case PIPE_FORMAT_R16G16B16A16_SNORM:
@ -183,7 +186,6 @@ accum_load(struct st_context *st, GLfloat value,
GLubyte *data = acc_strb->data;
GLfloat *buf;
if (ST_DEBUG & DEBUG_FALLBACK)
debug_printf("%s: fallback processing\n", __FUNCTION__);
@ -194,7 +196,9 @@ accum_load(struct st_context *st, GLfloat value,
buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
pipe_get_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
util_format_linear(color_strb->texture->format),
buf);
switch (acc_strb->format) {
case PIPE_FORMAT_R16G16B16A16_SNORM:
@ -232,6 +236,7 @@ accum_return(struct gl_context *ctx, GLfloat value,
size_t stride = acc_strb->stride;
const GLubyte *data = acc_strb->data;
GLfloat *buf;
enum pipe_format format = util_format_linear(color_strb->texture->format);
if (ST_DEBUG & DEBUG_FALLBACK)
debug_printf("%s: fallback processing\n", __FUNCTION__);
@ -250,7 +255,8 @@ accum_return(struct gl_context *ctx, GLfloat value,
width, height);
if (usage & PIPE_TRANSFER_READ)
pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
pipe_get_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
format, buf);
switch (acc_strb->format) {
case PIPE_FORMAT_R16G16B16A16_SNORM:
@ -279,7 +285,8 @@ accum_return(struct gl_context *ctx, GLfloat value,
_mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
}
pipe_put_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
pipe_put_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
format, buf);
free(buf);
pipe->transfer_destroy(pipe, color_trans);

View File

@ -1302,9 +1302,13 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
if (type == GL_COLOR) {
/* alternate path using get/put_tile() */
GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
pipe_get_tile_rgba(pipe, ptRead, readX, readY, readW, readH, buf);
pipe_put_tile_rgba(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
readW, readH, buf);
enum pipe_format readFormat, drawFormat;
readFormat = util_format_linear(rbRead->texture->format);
drawFormat = util_format_linear(pt->format);
pipe_get_tile_rgba_format(pipe, ptRead, readX, readY, readW, readH,
readFormat, buf);
pipe_put_tile_rgba_format(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
readW, readH, drawFormat, buf);
free(buf);
}
else {

View File

@ -390,7 +390,7 @@ st_render_texture(struct gl_context *ctx,
/* new surface for rendering into the texture */
memset(&surf_tmpl, 0, sizeof(surf_tmpl));
surf_tmpl.format = strb->texture->format;
surf_tmpl.format = util_format_linear(strb->texture->format);
surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
surf_tmpl.u.tex.level = strb->rtt_level;
surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;

View File

@ -41,6 +41,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "util/u_format.h"
#include "util/u_inlines.h"
#include "util/u_tile.h"
@ -336,6 +337,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
struct st_renderbuffer *strb;
struct gl_pixelstore_attrib clippedPacking = *pack;
struct pipe_transfer *trans;
enum pipe_format pformat;
assert(ctx->ReadBuffer->Width > 0);
@ -421,6 +423,9 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
yStep = 1;
}
/* possibly convert sRGB format to linear RGB format */
pformat = util_format_linear(trans->resource->format);
if (ST_DEBUG & DEBUG_FALLBACK)
debug_printf("%s: fallback processing\n", __FUNCTION__);
@ -435,8 +440,8 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width,
format, type);
if (trans->resource->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
trans->resource->format == PIPE_FORMAT_Z24X8_UNORM) {
if (pformat == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
pformat == PIPE_FORMAT_Z24X8_UNORM) {
if (format == GL_DEPTH_COMPONENT) {
for (i = 0; i < height; i++) {
GLuint ztemp[MAX_WIDTH];
@ -467,8 +472,8 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
}
}
}
else if (trans->resource->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM ||
trans->resource->format == PIPE_FORMAT_X8Z24_UNORM) {
else if (pformat == PIPE_FORMAT_S8_USCALED_Z24_UNORM ||
pformat == PIPE_FORMAT_X8Z24_UNORM) {
if (format == GL_DEPTH_COMPONENT) {
for (i = 0; i < height; i++) {
GLuint ztemp[MAX_WIDTH];
@ -494,7 +499,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
}
}
}
else if (trans->resource->format == PIPE_FORMAT_Z16_UNORM) {
else if (pformat == PIPE_FORMAT_Z16_UNORM) {
for (i = 0; i < height; i++) {
GLushort ztemp[MAX_WIDTH];
GLfloat zfloat[MAX_WIDTH];
@ -509,7 +514,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
dst += dstStride;
}
}
else if (trans->resource->format == PIPE_FORMAT_Z32_UNORM) {
else if (pformat == PIPE_FORMAT_Z32_UNORM) {
for (i = 0; i < height; i++) {
GLuint ztemp[MAX_WIDTH];
GLfloat zfloat[MAX_WIDTH];
@ -528,7 +533,8 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
/* RGBA format */
/* Do a row at a time to flip image data vertically */
for (i = 0; i < height; i++) {
pipe_get_tile_rgba(pipe, trans, 0, y, width, 1, df);
pipe_get_tile_rgba_format(pipe, trans, 0, y, width, 1,
pformat, df);
y += yStep;
df += dfStride;
if (!dfStride) {

View File

@ -918,6 +918,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
else {
/* format translation via floats */
GLuint row;
enum pipe_format format = util_format_linear(dst_texture->format);
for (row = 0; row < height; row++) {
const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */
GLfloat rgba[4 * MAX_WIDTH];
@ -928,7 +929,8 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
debug_printf("%s: fallback format translation\n", __FUNCTION__);
/* get float[4] rgba row from surface */
pipe_get_tile_rgba(pipe, tex_xfer, 0, row, width, 1, rgba);
pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1,
format, rgba);
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
type, dest, &ctx->Pack, transferOps);
@ -1387,7 +1389,9 @@ fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level,
/* XXX this usually involves a lot of int/float conversion.
* try to avoid that someday.
*/
pipe_get_tile_rgba(pipe, src_trans, 0, 0, width, height, tempSrc);
pipe_get_tile_rgba_format(pipe, src_trans, 0, 0, width, height,
util_format_linear(strb->texture->format),
tempSrc);
/* Store into texture memory.
* Note that this does some special things such as pixel transfer