mesa: implement EXT_texture_shared_exponent
swrast support done. There is no renderbuffer support in swrast, because it's not required by the extension. Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
@@ -502,6 +502,7 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
|
|||||||
ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
|
ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
|
||||||
ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
|
ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
|
||||||
ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
|
ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
|
||||||
|
ctx->Extensions.EXT_texture_shared_exponent = GL_TRUE;
|
||||||
#if FEATURE_EXT_texture_sRGB
|
#if FEATURE_EXT_texture_sRGB
|
||||||
ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
|
ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
|
||||||
ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE;
|
ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE;
|
||||||
|
@@ -418,6 +418,15 @@ _mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
|
|||||||
case GL_RG:
|
case GL_RG:
|
||||||
fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
|
fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
|
||||||
return;
|
return;
|
||||||
|
case GL_RGB:
|
||||||
|
switch (rb->Format) {
|
||||||
|
case MESA_FORMAT_RGB9_E5_FLOAT:
|
||||||
|
fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
|
||||||
|
return;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* render buffer format is supported by software rendering */
|
/* render buffer format is supported by software rendering */
|
||||||
;
|
;
|
||||||
@@ -1175,6 +1184,8 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
|
|||||||
case GL_INTENSITY32F_ARB:
|
case GL_INTENSITY32F_ARB:
|
||||||
return ctx->Extensions.ARB_texture_float &&
|
return ctx->Extensions.ARB_texture_float &&
|
||||||
ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0;
|
ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0;
|
||||||
|
case GL_RGB9_E5:
|
||||||
|
return ctx->Extensions.EXT_texture_shared_exponent ? GL_RGB : 0;
|
||||||
/* XXX add integer formats eventually */
|
/* XXX add integer formats eventually */
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -1072,7 +1072,16 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] =
|
|||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
0, 16, 0, 0, 0,
|
0, 16, 0, 0, 0,
|
||||||
1, 1, 2
|
1, 1, 2
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
MESA_FORMAT_RGB9_E5_FLOAT,
|
||||||
|
"MESA_FORMAT_RGB9_E5",
|
||||||
|
GL_RGB,
|
||||||
|
GL_FLOAT,
|
||||||
|
9, 9, 9, 0,
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
1, 1, 4
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1803,6 +1812,11 @@ _mesa_format_to_type_and_comps(gl_format format,
|
|||||||
*comps = 4;
|
*comps = 4;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case MESA_FORMAT_RGB9_E5_FLOAT:
|
||||||
|
*datatype = GL_UNSIGNED_INT_5_9_9_9_REV;
|
||||||
|
*comps = 3;
|
||||||
|
return;
|
||||||
|
|
||||||
case MESA_FORMAT_COUNT:
|
case MESA_FORMAT_COUNT:
|
||||||
assert(0);
|
assert(0);
|
||||||
return;
|
return;
|
||||||
|
@@ -206,6 +206,8 @@ typedef enum
|
|||||||
MESA_FORMAT_SIGNED_AL1616, /* AAAA AAAA AAAA AAAA LLLL LLLL LLLL LLLL */
|
MESA_FORMAT_SIGNED_AL1616, /* AAAA AAAA AAAA AAAA LLLL LLLL LLLL LLLL */
|
||||||
MESA_FORMAT_SIGNED_I16, /* IIII IIII IIII IIII */
|
MESA_FORMAT_SIGNED_I16, /* IIII IIII IIII IIII */
|
||||||
|
|
||||||
|
MESA_FORMAT_RGB9_E5_FLOAT,
|
||||||
|
|
||||||
MESA_FORMAT_COUNT
|
MESA_FORMAT_COUNT
|
||||||
} gl_format;
|
} gl_format;
|
||||||
|
|
||||||
|
@@ -82,6 +82,7 @@ _mesa_type_is_packed(GLenum type)
|
|||||||
case GL_UNSIGNED_SHORT_8_8_MESA:
|
case GL_UNSIGNED_SHORT_8_8_MESA:
|
||||||
case GL_UNSIGNED_SHORT_8_8_REV_MESA:
|
case GL_UNSIGNED_SHORT_8_8_REV_MESA:
|
||||||
case GL_UNSIGNED_INT_24_8_EXT:
|
case GL_UNSIGNED_INT_24_8_EXT:
|
||||||
|
case GL_UNSIGNED_INT_5_9_9_9_REV:
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,6 +223,8 @@ _mesa_sizeof_packed_type( GLenum type )
|
|||||||
return sizeof(GLushort);
|
return sizeof(GLushort);
|
||||||
case GL_UNSIGNED_INT_24_8_EXT:
|
case GL_UNSIGNED_INT_24_8_EXT:
|
||||||
return sizeof(GLuint);
|
return sizeof(GLuint);
|
||||||
|
case GL_UNSIGNED_INT_5_9_9_9_REV:
|
||||||
|
return sizeof(GLuint);
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -363,6 +366,11 @@ _mesa_bytes_per_pixel( GLenum format, GLenum type )
|
|||||||
return sizeof(GLuint);
|
return sizeof(GLuint);
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
case GL_UNSIGNED_INT_5_9_9_9_REV:
|
||||||
|
if (format == GL_RGB)
|
||||||
|
return sizeof(GLuint);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -458,6 +466,8 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
case GL_HALF_FLOAT_ARB:
|
case GL_HALF_FLOAT_ARB:
|
||||||
return ctx->Extensions.ARB_half_float_pixel;
|
return ctx->Extensions.ARB_half_float_pixel;
|
||||||
|
case GL_UNSIGNED_INT_5_9_9_9_REV:
|
||||||
|
return ctx->Extensions.EXT_texture_shared_exponent;
|
||||||
default:
|
default:
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
@@ -821,6 +831,7 @@ _mesa_is_color_format(GLenum format)
|
|||||||
case GL_INTENSITY_SNORM:
|
case GL_INTENSITY_SNORM:
|
||||||
case GL_INTENSITY8_SNORM:
|
case GL_INTENSITY8_SNORM:
|
||||||
case GL_INTENSITY16_SNORM:
|
case GL_INTENSITY16_SNORM:
|
||||||
|
case GL_RGB9_E5:
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
case GL_YCBCR_MESA: /* not considered to be RGB */
|
case GL_YCBCR_MESA: /* not considered to be RGB */
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
|
@@ -34,6 +34,8 @@
|
|||||||
#include "teximage.h"
|
#include "teximage.h"
|
||||||
#include "texstore.h"
|
#include "texstore.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "macros.h"
|
||||||
|
#include "rgb9e5.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -665,6 +667,25 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (datatype == GL_UNSIGNED_INT_5_9_9_9_REV && comps == 3) {
|
||||||
|
GLuint i, j, k;
|
||||||
|
const GLuint *rowA = (const GLuint*) srcRowA;
|
||||||
|
const GLuint *rowB = (const GLuint*) srcRowB;
|
||||||
|
GLuint *dst = (GLuint*)dstRow;
|
||||||
|
GLfloat res[3], rowAj[3], rowBj[3], rowAk[3], rowBk[3];
|
||||||
|
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
|
||||||
|
i++, j += colStride, k += colStride) {
|
||||||
|
rgb9e5_to_float3(rowA[j], rowAj);
|
||||||
|
rgb9e5_to_float3(rowB[j], rowBj);
|
||||||
|
rgb9e5_to_float3(rowA[k], rowAk);
|
||||||
|
rgb9e5_to_float3(rowB[k], rowBk);
|
||||||
|
res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0]) * 0.25F;
|
||||||
|
res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1]) * 0.25F;
|
||||||
|
res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2]) * 0.25F;
|
||||||
|
dst[i] = float3_to_rgb9e5(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
_mesa_problem(NULL, "bad format in do_row()");
|
_mesa_problem(NULL, "bad format in do_row()");
|
||||||
}
|
}
|
||||||
@@ -1245,6 +1266,34 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth,
|
|||||||
dst[i] = (a << 30) | (b << 20) | (g << 10) | r;
|
dst[i] = (a << 30) | (b << 20) | (g << 10) | r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (datatype == GL_UNSIGNED_INT_5_9_9_9_REV && comps == 3) {
|
||||||
|
DECLARE_ROW_POINTERS0(GLuint);
|
||||||
|
|
||||||
|
GLfloat res[3];
|
||||||
|
GLfloat rowAj[3], rowBj[3], rowCj[3], rowDj[3];
|
||||||
|
GLfloat rowAk[3], rowBk[3], rowCk[3], rowDk[3];
|
||||||
|
|
||||||
|
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
|
||||||
|
i++, j += colStride, k += colStride) {
|
||||||
|
rgb9e5_to_float3(rowA[j], rowAj);
|
||||||
|
rgb9e5_to_float3(rowB[j], rowBj);
|
||||||
|
rgb9e5_to_float3(rowC[j], rowCj);
|
||||||
|
rgb9e5_to_float3(rowD[j], rowDj);
|
||||||
|
rgb9e5_to_float3(rowA[k], rowAk);
|
||||||
|
rgb9e5_to_float3(rowB[k], rowBk);
|
||||||
|
rgb9e5_to_float3(rowC[k], rowCk);
|
||||||
|
rgb9e5_to_float3(rowD[k], rowDk);
|
||||||
|
res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0] +
|
||||||
|
rowCj[0] + rowCk[0] + rowDj[0] + rowDk[0]) * 0.125F;
|
||||||
|
res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1] +
|
||||||
|
rowCj[1] + rowCk[1] + rowDj[1] + rowDk[1]) * 0.125F;
|
||||||
|
res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2] +
|
||||||
|
rowCj[2] + rowCk[2] + rowDj[2] + rowDk[2]) * 0.125F;
|
||||||
|
dst[i] = float3_to_rgb9e5(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
_mesa_problem(NULL, "bad format in do_row()");
|
_mesa_problem(NULL, "bad format in do_row()");
|
||||||
}
|
}
|
||||||
|
@@ -37,6 +37,8 @@
|
|||||||
#include "mtypes.h"
|
#include "mtypes.h"
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
#include "pixeltransfer.h"
|
#include "pixeltransfer.h"
|
||||||
|
#include "imports.h"
|
||||||
|
#include "rgb9e5.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1892,6 +1894,14 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GL_UNSIGNED_INT_5_9_9_9_REV:
|
||||||
|
{
|
||||||
|
GLuint *dst = (GLuint *) dstAddr;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
dst[i] = float3_to_rgb9e5(rgba[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
_mesa_problem(ctx, "bad type in _mesa_pack_rgba_span_float");
|
_mesa_problem(ctx, "bad type in _mesa_pack_rgba_span_float");
|
||||||
return;
|
return;
|
||||||
@@ -2330,7 +2340,8 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
|
|||||||
srcType == GL_UNSIGNED_INT_8_8_8_8 ||
|
srcType == GL_UNSIGNED_INT_8_8_8_8 ||
|
||||||
srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
|
srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
|
||||||
srcType == GL_UNSIGNED_INT_10_10_10_2 ||
|
srcType == GL_UNSIGNED_INT_10_10_10_2 ||
|
||||||
srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
|
srcType == GL_UNSIGNED_INT_2_10_10_10_REV ||
|
||||||
|
srcType == GL_UNSIGNED_INT_5_9_9_9_REV);
|
||||||
|
|
||||||
get_component_mapping(srcFormat,
|
get_component_mapping(srcFormat,
|
||||||
&rSrc, &gSrc, &bSrc, &aSrc,
|
&rSrc, &gSrc, &bSrc, &aSrc,
|
||||||
@@ -2800,6 +2811,34 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GL_UNSIGNED_INT_5_9_9_9_REV:
|
||||||
|
if (swapBytes) {
|
||||||
|
const GLuint *uisrc = (const GLuint *) src;
|
||||||
|
GLuint i;
|
||||||
|
GLfloat f[3];
|
||||||
|
for (i = 0; i < n; i ++) {
|
||||||
|
GLuint p = uisrc[i];
|
||||||
|
SWAP4BYTE(p);
|
||||||
|
rgb9e5_to_float3(p, f);
|
||||||
|
rgba[i][rDst] = f[0];
|
||||||
|
rgba[i][gDst] = f[1];
|
||||||
|
rgba[i][bDst] = f[2];
|
||||||
|
rgba[i][aDst] = 1.0F;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const GLuint *uisrc = (const GLuint *) src;
|
||||||
|
GLuint i;
|
||||||
|
GLfloat f[3];
|
||||||
|
for (i = 0; i < n; i ++) {
|
||||||
|
rgb9e5_to_float3(uisrc[i], f);
|
||||||
|
rgba[i][rDst] = f[0];
|
||||||
|
rgba[i][gDst] = f[1];
|
||||||
|
rgba[i][bDst] = f[2];
|
||||||
|
rgba[i][aDst] = 1.0F;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
_mesa_problem(NULL, "bad srcType in extract float data");
|
_mesa_problem(NULL, "bad srcType in extract float data");
|
||||||
break;
|
break;
|
||||||
@@ -2902,7 +2941,8 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4],
|
|||||||
srcType == GL_UNSIGNED_INT_8_8_8_8 ||
|
srcType == GL_UNSIGNED_INT_8_8_8_8 ||
|
||||||
srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
|
srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
|
||||||
srcType == GL_UNSIGNED_INT_10_10_10_2 ||
|
srcType == GL_UNSIGNED_INT_10_10_10_2 ||
|
||||||
srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
|
srcType == GL_UNSIGNED_INT_2_10_10_10_REV ||
|
||||||
|
srcType == GL_UNSIGNED_INT_5_9_9_9_REV);
|
||||||
|
|
||||||
get_component_mapping(srcFormat,
|
get_component_mapping(srcFormat,
|
||||||
&rSrc, &gSrc, &bSrc, &aSrc,
|
&rSrc, &gSrc, &bSrc, &aSrc,
|
||||||
@@ -3266,6 +3306,35 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GL_UNSIGNED_INT_5_9_9_9_REV:
|
||||||
|
if (swapBytes) {
|
||||||
|
const GLuint *uisrc = (const GLuint *) src;
|
||||||
|
GLuint i;
|
||||||
|
float f[3];
|
||||||
|
for (i = 0; i < n; i ++) {
|
||||||
|
GLuint p = uisrc[i];
|
||||||
|
SWAP4BYTE(p);
|
||||||
|
rgb9e5_to_float3(p, f);
|
||||||
|
rgba[i][rDst] = clamp_float_to_uint(f[0]);
|
||||||
|
rgba[i][gDst] = clamp_float_to_uint(f[1]);
|
||||||
|
rgba[i][bDst] = clamp_float_to_uint(f[2]);
|
||||||
|
rgba[i][aDst] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const GLuint *uisrc = (const GLuint *) src;
|
||||||
|
GLuint i;
|
||||||
|
float f[3];
|
||||||
|
for (i = 0; i < n; i ++) {
|
||||||
|
GLuint p = uisrc[i];
|
||||||
|
rgb9e5_to_float3(p, f);
|
||||||
|
rgba[i][rDst] = clamp_float_to_uint(f[0]);
|
||||||
|
rgba[i][gDst] = clamp_float_to_uint(f[1]);
|
||||||
|
rgba[i][bDst] = clamp_float_to_uint(f[2]);
|
||||||
|
rgba[i][aDst] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
_mesa_problem(NULL, "bad srcType in extract uint data");
|
_mesa_problem(NULL, "bad srcType in extract uint data");
|
||||||
break;
|
break;
|
||||||
@@ -3345,7 +3414,8 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx,
|
|||||||
srcType == GL_UNSIGNED_INT_8_8_8_8 ||
|
srcType == GL_UNSIGNED_INT_8_8_8_8 ||
|
||||||
srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
|
srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
|
||||||
srcType == GL_UNSIGNED_INT_10_10_10_2 ||
|
srcType == GL_UNSIGNED_INT_10_10_10_2 ||
|
||||||
srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
|
srcType == GL_UNSIGNED_INT_2_10_10_10_REV ||
|
||||||
|
srcType == GL_UNSIGNED_INT_5_9_9_9_REV);
|
||||||
|
|
||||||
/* Try simple cases first */
|
/* Try simple cases first */
|
||||||
if (transferOps == 0) {
|
if (transferOps == 0) {
|
||||||
@@ -3667,7 +3737,8 @@ _mesa_unpack_color_span_float( struct gl_context *ctx,
|
|||||||
srcType == GL_UNSIGNED_INT_8_8_8_8 ||
|
srcType == GL_UNSIGNED_INT_8_8_8_8 ||
|
||||||
srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
|
srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
|
||||||
srcType == GL_UNSIGNED_INT_10_10_10_2 ||
|
srcType == GL_UNSIGNED_INT_10_10_10_2 ||
|
||||||
srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
|
srcType == GL_UNSIGNED_INT_2_10_10_10_REV ||
|
||||||
|
srcType == GL_UNSIGNED_INT_5_9_9_9_REV);
|
||||||
|
|
||||||
/* general solution, no special cases, yet */
|
/* general solution, no special cases, yet */
|
||||||
{
|
{
|
||||||
@@ -3873,7 +3944,8 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx,
|
|||||||
srcType == GL_UNSIGNED_INT_8_8_8_8 ||
|
srcType == GL_UNSIGNED_INT_8_8_8_8 ||
|
||||||
srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
|
srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
|
||||||
srcType == GL_UNSIGNED_INT_10_10_10_2 ||
|
srcType == GL_UNSIGNED_INT_10_10_10_2 ||
|
||||||
srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
|
srcType == GL_UNSIGNED_INT_2_10_10_10_REV ||
|
||||||
|
srcType == GL_UNSIGNED_INT_5_9_9_9_REV);
|
||||||
|
|
||||||
|
|
||||||
/* Extract image data as uint[4] pixels */
|
/* Extract image data as uint[4] pixels */
|
||||||
|
173
src/mesa/main/rgb9e5.h
Normal file
173
src/mesa/main/rgb9e5.h
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Marek Olšák <maraeo@gmail.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copied from EXT_texture_shared_exponent and edited. */
|
||||||
|
|
||||||
|
#ifndef RGB9E5_H
|
||||||
|
#define RGB9E5_H
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define RGB9E5_EXPONENT_BITS 5
|
||||||
|
#define RGB9E5_MANTISSA_BITS 9
|
||||||
|
#define RGB9E5_EXP_BIAS 15
|
||||||
|
#define RGB9E5_MAX_VALID_BIASED_EXP 31
|
||||||
|
|
||||||
|
#define MAX_RGB9E5_EXP (RGB9E5_MAX_VALID_BIASED_EXP - RGB9E5_EXP_BIAS)
|
||||||
|
#define RGB9E5_MANTISSA_VALUES (1<<RGB9E5_MANTISSA_BITS)
|
||||||
|
#define MAX_RGB9E5_MANTISSA (RGB9E5_MANTISSA_VALUES-1)
|
||||||
|
#define MAX_RGB9E5 (((float)MAX_RGB9E5_MANTISSA)/RGB9E5_MANTISSA_VALUES * (1<<MAX_RGB9E5_EXP))
|
||||||
|
#define EPSILON_RGB9E5 ((1.0/RGB9E5_MANTISSA_VALUES) / (1<<RGB9E5_EXP_BIAS))
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
unsigned int raw;
|
||||||
|
float value;
|
||||||
|
struct {
|
||||||
|
#if defined(MESA_BIG_ENDIAN) || defined(PIPE_ARCH_BIG_ENDIAN)
|
||||||
|
unsigned int negative:1;
|
||||||
|
unsigned int biasedexponent:8;
|
||||||
|
unsigned int mantissa:23;
|
||||||
|
#else
|
||||||
|
unsigned int mantissa:23;
|
||||||
|
unsigned int biasedexponent:8;
|
||||||
|
unsigned int negative:1;
|
||||||
|
#endif
|
||||||
|
} field;
|
||||||
|
} float754;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
unsigned int raw;
|
||||||
|
struct {
|
||||||
|
#if defined(MESA_BIG_ENDIAN) || defined(PIPE_ARCH_BIG_ENDIAN)
|
||||||
|
unsigned int biasedexponent:RGB9E5_EXPONENT_BITS;
|
||||||
|
unsigned int b:RGB9E5_MANTISSA_BITS;
|
||||||
|
unsigned int g:RGB9E5_MANTISSA_BITS;
|
||||||
|
unsigned int r:RGB9E5_MANTISSA_BITS;
|
||||||
|
#else
|
||||||
|
unsigned int r:RGB9E5_MANTISSA_BITS;
|
||||||
|
unsigned int g:RGB9E5_MANTISSA_BITS;
|
||||||
|
unsigned int b:RGB9E5_MANTISSA_BITS;
|
||||||
|
unsigned int biasedexponent:RGB9E5_EXPONENT_BITS;
|
||||||
|
#endif
|
||||||
|
} field;
|
||||||
|
} rgb9e5;
|
||||||
|
|
||||||
|
static INLINE float rgb9e5_ClampRange(float x)
|
||||||
|
{
|
||||||
|
if (x > 0.0) {
|
||||||
|
if (x >= MAX_RGB9E5) {
|
||||||
|
return MAX_RGB9E5;
|
||||||
|
} else {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* NaN gets here too since comparisons with NaN always fail! */
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE float rgb9e5_MaxOf3(float x, float y, float z)
|
||||||
|
{
|
||||||
|
if (x > y) {
|
||||||
|
return MAX2(x, z);
|
||||||
|
} else {
|
||||||
|
return MAX2(y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ok, FloorLog2 is not correct for the denorm and zero values, but we
|
||||||
|
are going to do a max of this value with the minimum rgb9e5 exponent
|
||||||
|
that will hide these problem cases. */
|
||||||
|
static INLINE int rgb9e5_FloorLog2(float x)
|
||||||
|
{
|
||||||
|
float754 f;
|
||||||
|
|
||||||
|
f.value = x;
|
||||||
|
return (f.field.biasedexponent - 127);
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE unsigned float3_to_rgb9e5(const float rgb[3])
|
||||||
|
{
|
||||||
|
rgb9e5 retval;
|
||||||
|
float maxrgb;
|
||||||
|
int rm, gm, bm;
|
||||||
|
float rc, gc, bc;
|
||||||
|
int exp_shared, maxm;
|
||||||
|
double denom;
|
||||||
|
|
||||||
|
rc = rgb9e5_ClampRange(rgb[0]);
|
||||||
|
gc = rgb9e5_ClampRange(rgb[1]);
|
||||||
|
bc = rgb9e5_ClampRange(rgb[2]);
|
||||||
|
|
||||||
|
maxrgb = rgb9e5_MaxOf3(rc, gc, bc);
|
||||||
|
exp_shared = MAX2(-RGB9E5_EXP_BIAS-1, rgb9e5_FloorLog2(maxrgb)) + 1 + RGB9E5_EXP_BIAS;
|
||||||
|
assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP);
|
||||||
|
assert(exp_shared >= 0);
|
||||||
|
/* This pow function could be replaced by a table. */
|
||||||
|
denom = pow(2, exp_shared - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS);
|
||||||
|
|
||||||
|
maxm = (int) floor(maxrgb / denom + 0.5);
|
||||||
|
if (maxm == MAX_RGB9E5_MANTISSA+1) {
|
||||||
|
denom *= 2;
|
||||||
|
exp_shared += 1;
|
||||||
|
assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP);
|
||||||
|
} else {
|
||||||
|
assert(maxm <= MAX_RGB9E5_MANTISSA);
|
||||||
|
}
|
||||||
|
|
||||||
|
rm = (int) floor(rc / denom + 0.5);
|
||||||
|
gm = (int) floor(gc / denom + 0.5);
|
||||||
|
bm = (int) floor(bc / denom + 0.5);
|
||||||
|
|
||||||
|
assert(rm <= MAX_RGB9E5_MANTISSA);
|
||||||
|
assert(gm <= MAX_RGB9E5_MANTISSA);
|
||||||
|
assert(bm <= MAX_RGB9E5_MANTISSA);
|
||||||
|
assert(rm >= 0);
|
||||||
|
assert(gm >= 0);
|
||||||
|
assert(bm >= 0);
|
||||||
|
|
||||||
|
retval.field.r = rm;
|
||||||
|
retval.field.g = gm;
|
||||||
|
retval.field.b = bm;
|
||||||
|
retval.field.biasedexponent = exp_shared;
|
||||||
|
|
||||||
|
return retval.raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE void rgb9e5_to_float3(unsigned rgb, float retval[3])
|
||||||
|
{
|
||||||
|
rgb9e5 v;
|
||||||
|
int exponent;
|
||||||
|
float scale;
|
||||||
|
|
||||||
|
v.raw = rgb;
|
||||||
|
exponent = v.field.biasedexponent - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS;
|
||||||
|
scale = (float) pow(2, exponent);
|
||||||
|
|
||||||
|
retval[0] = v.field.r * scale;
|
||||||
|
retval[1] = v.field.g * scale;
|
||||||
|
retval[2] = v.field.b * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -41,6 +41,7 @@
|
|||||||
#include "texcompress_rgtc.h"
|
#include "texcompress_rgtc.h"
|
||||||
#include "texfetch.h"
|
#include "texfetch.h"
|
||||||
#include "teximage.h"
|
#include "teximage.h"
|
||||||
|
#include "rgb9e5.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -898,6 +899,13 @@ texfetch_funcs[MESA_FORMAT_COUNT] =
|
|||||||
fetch_texel_3d_signed_i16,
|
fetch_texel_3d_signed_i16,
|
||||||
store_texel_signed_i16
|
store_texel_signed_i16
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MESA_FORMAT_RGB9_E5_FLOAT,
|
||||||
|
fetch_texel_1d_rgb9_e5,
|
||||||
|
fetch_texel_2d_rgb9_e5,
|
||||||
|
fetch_texel_3d_rgb9_e5,
|
||||||
|
store_texel_rgb9_e5
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2332,6 +2332,27 @@ static void store_texel_s8_z24(struct gl_texture_image *texImage,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* MESA_FORMAT_RGB9_E5 ******************************************************/
|
||||||
|
|
||||||
|
static void FETCH(rgb9_e5)( const struct gl_texture_image *texImage,
|
||||||
|
GLint i, GLint j, GLint k, GLfloat *texel )
|
||||||
|
{
|
||||||
|
const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
|
||||||
|
rgb9e5_to_float3(*src, texel);
|
||||||
|
texel[ACOMP] = 1.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DIM == 3
|
||||||
|
static void store_texel_rgb9_e5(struct gl_texture_image *texImage,
|
||||||
|
GLint i, GLint j, GLint k, const void *texel)
|
||||||
|
{
|
||||||
|
const GLfloat *src = (const GLfloat *) texel;
|
||||||
|
GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
|
||||||
|
*dst = float3_to_rgb9e5(src);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#undef TEXEL_ADDR
|
#undef TEXEL_ADDR
|
||||||
#undef DIM
|
#undef DIM
|
||||||
#undef FETCH
|
#undef FETCH
|
||||||
|
@@ -382,6 +382,16 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->Extensions.EXT_texture_shared_exponent) {
|
||||||
|
switch (internalFormat) {
|
||||||
|
case GL_RGB9_E5:
|
||||||
|
RETURN_IF_SUPPORTED(MESA_FORMAT_RGB9_E5_FLOAT);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
; /* fallthrough */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->Extensions.EXT_packed_depth_stencil) {
|
if (ctx->Extensions.EXT_packed_depth_stencil) {
|
||||||
switch (internalFormat) {
|
switch (internalFormat) {
|
||||||
case GL_DEPTH_STENCIL_EXT:
|
case GL_DEPTH_STENCIL_EXT:
|
||||||
|
@@ -979,11 +979,9 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_TEXTURE_SHARED_SIZE:
|
case GL_TEXTURE_SHARED_SIZE:
|
||||||
if (ctx->VersionMajor >= 3) {
|
if (ctx->VersionMajor >= 3 ||
|
||||||
/* XXX return number of exponent bits for shared exponent texture
|
ctx->Extensions.EXT_texture_shared_exponent) {
|
||||||
* formats, like GL_RGB9_E5.
|
*params = texFormat == MESA_FORMAT_RGB9_E5_FLOAT ? 5 : 0;
|
||||||
*/
|
|
||||||
*params = 0;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
goto invalid_pname;
|
goto invalid_pname;
|
||||||
|
@@ -70,6 +70,7 @@
|
|||||||
#include "teximage.h"
|
#include "teximage.h"
|
||||||
#include "texstore.h"
|
#include "texstore.h"
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
|
#include "rgb9e5.h"
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -4176,6 +4177,60 @@ _mesa_texstore_sla8(TEXSTORE_PARAMS)
|
|||||||
|
|
||||||
#endif /* FEATURE_EXT_texture_sRGB */
|
#endif /* FEATURE_EXT_texture_sRGB */
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
_mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
|
||||||
|
{
|
||||||
|
const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
|
||||||
|
|
||||||
|
ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT);
|
||||||
|
ASSERT(baseInternalFormat == GL_RGB);
|
||||||
|
|
||||||
|
if (!ctx->_ImageTransferState &&
|
||||||
|
!srcPacking->SwapBytes &&
|
||||||
|
srcFormat == GL_RGB &&
|
||||||
|
srcType == GL_UNSIGNED_INT_5_9_9_9_REV) {
|
||||||
|
/* simple memcpy path */
|
||||||
|
memcpy_texture(ctx, dims,
|
||||||
|
dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
|
||||||
|
dstRowStride,
|
||||||
|
dstImageOffsets,
|
||||||
|
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
|
||||||
|
srcAddr, srcPacking);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* general path */
|
||||||
|
const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
|
||||||
|
baseInternalFormat,
|
||||||
|
baseFormat,
|
||||||
|
srcWidth, srcHeight, srcDepth,
|
||||||
|
srcFormat, srcType, srcAddr,
|
||||||
|
srcPacking,
|
||||||
|
ctx->_ImageTransferState);
|
||||||
|
const GLfloat *srcRow = tempImage;
|
||||||
|
GLint bytesPerRow;
|
||||||
|
GLint img, row, col;
|
||||||
|
if (!tempImage)
|
||||||
|
return GL_FALSE;
|
||||||
|
bytesPerRow = srcWidth * 3 * sizeof(GLfloat);
|
||||||
|
for (img = 0; img < srcDepth; img++) {
|
||||||
|
GLubyte *dstRow = (GLubyte *) dstAddr
|
||||||
|
+ dstImageOffsets[dstZoffset + img] * 4
|
||||||
|
+ dstYoffset * dstRowStride
|
||||||
|
+ dstXoffset * 4;
|
||||||
|
for (row = 0; row < srcHeight; row++) {
|
||||||
|
GLuint *dstUI = (GLuint*)dstRow;
|
||||||
|
for (col = 0; col < srcWidth; col++) {
|
||||||
|
dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]);
|
||||||
|
}
|
||||||
|
dstRow += dstRowStride;
|
||||||
|
srcRow += srcWidth * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free((void *) tempImage);
|
||||||
|
}
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -4309,6 +4364,8 @@ texstore_funcs[MESA_FORMAT_COUNT] =
|
|||||||
{ MESA_FORMAT_SIGNED_L16, _mesa_texstore_snorm16 },
|
{ MESA_FORMAT_SIGNED_L16, _mesa_texstore_snorm16 },
|
||||||
{ MESA_FORMAT_SIGNED_AL1616, _mesa_texstore_snorm1616 },
|
{ MESA_FORMAT_SIGNED_AL1616, _mesa_texstore_snorm1616 },
|
||||||
{ MESA_FORMAT_SIGNED_I16, _mesa_texstore_snorm16 },
|
{ MESA_FORMAT_SIGNED_I16, _mesa_texstore_snorm16 },
|
||||||
|
|
||||||
|
{ MESA_FORMAT_RGB9_E5_FLOAT, _mesa_texstore_rgb9_e5 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user