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:
parent
4c9ad084c1
commit
9d380f487a
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue