mesa: add new signed rgba texture format
This is a (partial) backport of the signed texture format support in OGL 3.1. Since it wasn't promoted from an existing extension roll our own.
This commit is contained in:
214
docs/MESA_texture_signed_rgba.spec
Normal file
214
docs/MESA_texture_signed_rgba.spec
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
Name
|
||||||
|
|
||||||
|
MESA_texture_signed_rgba
|
||||||
|
|
||||||
|
Name Strings
|
||||||
|
|
||||||
|
GL_MESA_texture_signed_rgba
|
||||||
|
|
||||||
|
Contact
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Notice
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IP Status
|
||||||
|
|
||||||
|
No known IP issues
|
||||||
|
|
||||||
|
Status
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Version
|
||||||
|
|
||||||
|
0.3, 2009-03-24
|
||||||
|
|
||||||
|
Number
|
||||||
|
|
||||||
|
Not assigned ?
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
|
||||||
|
Written based on the wording of the OpenGL 2.0 specification.
|
||||||
|
|
||||||
|
This extension trivially interacts with ARB_texture_float.
|
||||||
|
This extension shares some language with ARB_texture_compression_rgtc
|
||||||
|
but does not depend on it.
|
||||||
|
|
||||||
|
Overview
|
||||||
|
|
||||||
|
OpenGL prior to 3.1 does not support any signed texture formats.
|
||||||
|
ARB_texture_compression_rgtc introduces some compressed red and
|
||||||
|
red_green signed formats but no uncompressed ones, which might
|
||||||
|
still be useful. NV_texture_shader adds signed texture formats,
|
||||||
|
but also a lot of functionality which has been superceded by fragment
|
||||||
|
shaders.
|
||||||
|
It is usually possible to get the same functionality
|
||||||
|
using a unsigned format by doing scale and bias in a shader, but this
|
||||||
|
is undesirable since modern hardware has direct support for this.
|
||||||
|
This extension adds a signed 4-channel texture format by backporting
|
||||||
|
the relevant features from OpenGL 3.1, as a means to support this in
|
||||||
|
OpenGL implementations only supporting older versions.
|
||||||
|
|
||||||
|
Issues
|
||||||
|
|
||||||
|
1) What should this extension be called?
|
||||||
|
|
||||||
|
RESOLVED: MESA_texture_signed_rgba seems reasonable.
|
||||||
|
The rgba part is there because only 4 channel format is supported.
|
||||||
|
|
||||||
|
|
||||||
|
2) Should the full set of signed formats (alpha, luminance, rgb, etc.)
|
||||||
|
be supported?
|
||||||
|
|
||||||
|
RESOLVED: NO. To keep this extension simple, only add the most
|
||||||
|
universal format, rgba. alpha/luminance can't be trivially supported
|
||||||
|
since OpenGL 3.1 does not support them any longer, and there is some
|
||||||
|
implied dependency on ARB_texture_rg for red/red_green formats so
|
||||||
|
avoid all this. Likewise, only 8 bits per channel is supported.
|
||||||
|
|
||||||
|
|
||||||
|
3) Should this extension use new enums for the texture formats?
|
||||||
|
|
||||||
|
RESOLVED: NO. Same enums as those used in OpenGL 3.1.
|
||||||
|
|
||||||
|
|
||||||
|
4) How are signed integer values mapped to floating-point values?
|
||||||
|
|
||||||
|
RESOLVED: Same as described in issue 5) of
|
||||||
|
ARB_texture_compression_rgtc (quote):
|
||||||
|
A signed 8-bit two's complement value X is computed to
|
||||||
|
a floating-point value Xf with the formula:
|
||||||
|
|
||||||
|
{ X / 127.0, X > -128
|
||||||
|
Xf = {
|
||||||
|
{ -1.0, X == -128
|
||||||
|
|
||||||
|
This conversion means -1, 0, and +1 are all exactly representable,
|
||||||
|
however -128 and -127 both map to -1.0. Mapping -128 to -1.0
|
||||||
|
avoids the numerical awkwardness of have a representable value
|
||||||
|
slightly more negative than -1.0.
|
||||||
|
|
||||||
|
This conversion is intentionally NOT the "byte" conversion listed
|
||||||
|
in Table 2.9 for component conversions. That conversion says:
|
||||||
|
|
||||||
|
Xf = (2*X + 1) / 255.0
|
||||||
|
|
||||||
|
The Table 2.9 conversion is incapable of exactly representing
|
||||||
|
zero.
|
||||||
|
|
||||||
|
(Difference to ARB_texture_compression_rgtc):
|
||||||
|
This is the same mapping as OpenGL 3.1 uses.
|
||||||
|
This is also different to what NV_texture_shader used.
|
||||||
|
The above mapping should be considered the reference, but there
|
||||||
|
is some leeway so other mappings are allowed for implementations which
|
||||||
|
cannot do this. Particulary the mapping given in NV_texture_shader or
|
||||||
|
the standard OpenGL byte/float mapping is considered acceptable too, as
|
||||||
|
might be a mapping which represents -1.0 by -128, 0.0 by 0 and 1.0 by
|
||||||
|
127 (that is, uses different scale factors for negative and positive
|
||||||
|
numbers).
|
||||||
|
Also, it is ok to store incoming GL_BYTE user data as-is, without
|
||||||
|
converting to GL_FLOAT (using the standard OpenGL float/byte mapping)
|
||||||
|
and converting back (using the mapping described here).
|
||||||
|
Other than those subtle issues there are no other non-standard
|
||||||
|
conversions used, so when using for instance CopyTexImage2D with
|
||||||
|
a framebuffer clamped to [0,1] all converted numbers will be in the range
|
||||||
|
[0, 127] (and not scaled and biased).
|
||||||
|
|
||||||
|
|
||||||
|
5) How will signed components resulting from RGBA8_SNORM texture
|
||||||
|
fetches interact with fragment coloring?
|
||||||
|
|
||||||
|
RESOLVED: Same as described in issue 6) of
|
||||||
|
ARB_texture_compression_rgtc (quote):
|
||||||
|
The specification language for this extension is silent
|
||||||
|
about clamping behavior leaving this to the core specification
|
||||||
|
and other extensions. The clamping or lack of clamping is left
|
||||||
|
to the core specification and other extensions.
|
||||||
|
|
||||||
|
For assembly program extensions supporting texture fetches
|
||||||
|
(ARB_fragment_program, NV_fragment_program, NV_vertex_program3,
|
||||||
|
etc.) or the OpenGL Shading Language, these signed formats will
|
||||||
|
appear as expected with unclamped signed components as a result
|
||||||
|
of a texture fetch instruction.
|
||||||
|
|
||||||
|
If ARB_color_buffer_float is supported, its clamping controls
|
||||||
|
will apply.
|
||||||
|
|
||||||
|
NV_texture_shader extension, if supported, adds support for
|
||||||
|
fixed-point textures with signed components and relaxed the
|
||||||
|
fixed-function texture environment clamping appropriately. If the
|
||||||
|
NV_texture_shader extension is supported, its specified behavior
|
||||||
|
for the texture environment applies where intermediate values
|
||||||
|
are clamped to [-1,1] unless stated otherwise as in the case
|
||||||
|
of explicitly clamped to [0,1] for GL_COMBINE. or clamping the
|
||||||
|
linear interpolation weight to [0,1] for GL_DECAL and GL_BLEND.
|
||||||
|
|
||||||
|
Otherwise, the conventional core texture environment clamps
|
||||||
|
incoming, intermediate, and output color components to [0,1].
|
||||||
|
|
||||||
|
This implies that the conventional texture environment
|
||||||
|
functionality of unextended OpenGL 1.5 or OpenGL 2.0 without
|
||||||
|
using GLSL (and with none of the extensions referred to above)
|
||||||
|
is unable to make proper use of the signed texture formats added
|
||||||
|
by this extension because the conventional texture environment
|
||||||
|
requires texture source colors to be clamped to [0,1]. Texture
|
||||||
|
filtering of these signed formats would be still signed, but
|
||||||
|
negative values generated post-filtering would be clamped to
|
||||||
|
zero by the core texture environment functionality. The
|
||||||
|
expectation is clearly that this extension would be co-implemented
|
||||||
|
with one of the previously referred to extensions or used with
|
||||||
|
GLSL for the new signed formats to be useful.
|
||||||
|
|
||||||
|
|
||||||
|
6) Should the RGBA_SNORM tokens also be accepted by CopyTexImage
|
||||||
|
functions?
|
||||||
|
|
||||||
|
RESOLVED: YES.
|
||||||
|
|
||||||
|
|
||||||
|
7) What to do with GetTexParameter if ARB_texture_float is supported,
|
||||||
|
in particular what datatype should this return for TEXTURE_RED_TYPE_ARB,
|
||||||
|
TEXTURE_GREEN_TYPE_ARB, TEXTURE_BLUE_TYPE_ARB, TEXTURE_ALPHA_TYPE_ARB?
|
||||||
|
|
||||||
|
RESOLVED: ARB_texture_float states type is either NONE,
|
||||||
|
UNSIGNED_NORMALIZED_ARB, or FLOAT. This extension adds a new enum,
|
||||||
|
SIGNED_NORMALIZED, which will be returned accordingly. This is the
|
||||||
|
same behaviour as in OpenGL 3.1.
|
||||||
|
|
||||||
|
|
||||||
|
New Tokens
|
||||||
|
|
||||||
|
|
||||||
|
Accepted by the <internalformat> parameter of
|
||||||
|
TexImage1D, TexImage2D, TexImage3D, CopyTexImage1D, and CopyTexImage2D:
|
||||||
|
|
||||||
|
RGBA_SNORM 0x8F93
|
||||||
|
RGBA8_SNORM 0x8F97
|
||||||
|
|
||||||
|
Returned by the <params> parameter of GetTexLevelParameter:
|
||||||
|
|
||||||
|
SIGNED_NORMALIZED 0x8F9C
|
||||||
|
|
||||||
|
|
||||||
|
Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization):
|
||||||
|
|
||||||
|
-- Section 3.8.1, Texture Image Specification
|
||||||
|
|
||||||
|
Add to Table 3.16 (page 154): Sized internal formats
|
||||||
|
|
||||||
|
Sized Base R G B A L I D
|
||||||
|
Internal Format Internal Format bits bits bits bits bits bits bits
|
||||||
|
--------------- --------------- ---- ---- ---- ---- ---- ---- ----
|
||||||
|
RGBA8_SNORM RGBA 8 8 8 8 0 0 0
|
||||||
|
|
||||||
|
|
||||||
|
Dependencies on ARB_texture_float extension:
|
||||||
|
|
||||||
|
If ARB_texture_float is supported, GetTexParameter queries with <value>
|
||||||
|
of TEXTURE_RED_TYPE_ARB, TEXTURE_GREEN_TYPE_ARB, TEXTURE_BLUE_TYPE_ARB or
|
||||||
|
TEXTURE_ALPHA_TYPE_ARB return SIGNED_NORMALIZED if
|
||||||
|
the base internal format is RGBA_SNORM.
|
@@ -24,6 +24,7 @@ The specifications follow.
|
|||||||
<LI><A HREF="MESA_resize_buffers.spec">MESA_resize_buffers.spec</A>
|
<LI><A HREF="MESA_resize_buffers.spec">MESA_resize_buffers.spec</A>
|
||||||
<LI><A HREF="MESA_set_3dfx_mode.spec">MESA_set_3dfx_mode.spec</A>
|
<LI><A HREF="MESA_set_3dfx_mode.spec">MESA_set_3dfx_mode.spec</A>
|
||||||
<LI><A HREF="MESA_sprite_point.spec">MESA_sprite_point.spec</A> (obsolete)
|
<LI><A HREF="MESA_sprite_point.spec">MESA_sprite_point.spec</A> (obsolete)
|
||||||
|
<LI><A HREF="MESA_texture_signed_rgba.spec">MESA_texture_signed_rgba.spec</A>
|
||||||
<LI><A HREF="MESA_trace.spec">MESA_trace.spec</A> (obsolete)
|
<LI><A HREF="MESA_trace.spec">MESA_trace.spec</A> (obsolete)
|
||||||
<LI><A HREF="MESA_window_pos.spec">MESA_window_pos.spec</A>
|
<LI><A HREF="MESA_window_pos.spec">MESA_window_pos.spec</A>
|
||||||
<LI><A HREF="MESA_ycbcr_texture.spec">MESA_ycbcr_texture.spec</A>
|
<LI><A HREF="MESA_ycbcr_texture.spec">MESA_ycbcr_texture.spec</A>
|
||||||
|
@@ -12326,6 +12326,12 @@
|
|||||||
</function>
|
</function>
|
||||||
</category>
|
</category>
|
||||||
|
|
||||||
|
<category name="GL_MESA_texture_signed_rgba">
|
||||||
|
<enum name="SIGNED_NORMALIZED" value="0x8F9C"/>
|
||||||
|
<enum name="RGBA_SNORM" value="0x8F93"/>
|
||||||
|
<enum name="RGBA8_SNORM" value="0x8F97"/>
|
||||||
|
</category>
|
||||||
|
|
||||||
<category name="GL_MESA_shader_debug">
|
<category name="GL_MESA_shader_debug">
|
||||||
<enum name="DEBUG_OBJECT_MESA" value="0x8759"/>
|
<enum name="DEBUG_OBJECT_MESA" value="0x8759"/>
|
||||||
<enum name="DEBUG_PRINT_MESA" value="0x875A"/>
|
<enum name="DEBUG_PRINT_MESA" value="0x875A"/>
|
||||||
|
@@ -718,7 +718,7 @@ _mesa_GetColorTable( GLenum target, GLenum format,
|
|||||||
}
|
}
|
||||||
|
|
||||||
_mesa_pack_rgba_span_float(ctx, table->Size, rgba,
|
_mesa_pack_rgba_span_float(ctx, table->Size, rgba,
|
||||||
format, type, data, &ctx->Pack, 0x0);
|
format, type, data, &ctx->Pack, 0x0, GL_FALSE);
|
||||||
|
|
||||||
if (ctx->Pack.BufferObj->Name) {
|
if (ctx->Pack.BufferObj->Name) {
|
||||||
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
|
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
|
||||||
|
@@ -626,7 +626,7 @@ _mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
|
|||||||
row, 0);
|
row, 0);
|
||||||
GLfloat (*src)[4] = (GLfloat (*)[4]) (filter->Filter + row * filter->Width * 4);
|
GLfloat (*src)[4] = (GLfloat (*)[4]) (filter->Filter + row * filter->Width * 4);
|
||||||
_mesa_pack_rgba_span_float(ctx, filter->Width, src,
|
_mesa_pack_rgba_span_float(ctx, filter->Width, src,
|
||||||
format, type, dst, &ctx->Pack, 0x0);
|
format, type, dst, &ctx->Pack, 0x0, GL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->Pack.BufferObj->Name) {
|
if (ctx->Pack.BufferObj->Name) {
|
||||||
@@ -836,7 +836,7 @@ _mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
|
|||||||
format, type, 0);
|
format, type, 0);
|
||||||
_mesa_pack_rgba_span_float(ctx, filter->Width,
|
_mesa_pack_rgba_span_float(ctx, filter->Width,
|
||||||
(GLfloat (*)[4]) filter->Filter,
|
(GLfloat (*)[4]) filter->Filter,
|
||||||
format, type, dst, &ctx->Pack, 0x0);
|
format, type, dst, &ctx->Pack, 0x0, GL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Column filter */
|
/* Column filter */
|
||||||
@@ -845,7 +845,7 @@ _mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
|
|||||||
format, type, 0);
|
format, type, 0);
|
||||||
GLfloat (*src)[4] = (GLfloat (*)[4]) (filter->Filter + colStart);
|
GLfloat (*src)[4] = (GLfloat (*)[4]) (filter->Filter + colStart);
|
||||||
_mesa_pack_rgba_span_float(ctx, filter->Height, src,
|
_mesa_pack_rgba_span_float(ctx, filter->Height, src,
|
||||||
format, type, dst, &ctx->Pack, 0x0);
|
format, type, dst, &ctx->Pack, 0x0, GL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) span; /* unused at this time */
|
(void) span; /* unused at this time */
|
||||||
|
@@ -150,6 +150,7 @@ static const struct {
|
|||||||
{ OFF, "GL_MESA_packed_depth_stencil", F(MESA_packed_depth_stencil) },
|
{ OFF, "GL_MESA_packed_depth_stencil", F(MESA_packed_depth_stencil) },
|
||||||
{ OFF, "GL_MESA_resize_buffers", F(MESA_resize_buffers) },
|
{ OFF, "GL_MESA_resize_buffers", F(MESA_resize_buffers) },
|
||||||
{ OFF, "GL_MESA_texture_array", F(MESA_texture_array) },
|
{ OFF, "GL_MESA_texture_array", F(MESA_texture_array) },
|
||||||
|
{ OFF, "GL_MESA_texture_signed_rgba", F(MESA_texture_signed_rgba) },
|
||||||
{ OFF, "GL_MESA_ycbcr_texture", F(MESA_ycbcr_texture) },
|
{ OFF, "GL_MESA_ycbcr_texture", F(MESA_ycbcr_texture) },
|
||||||
{ ON, "GL_MESA_window_pos", F(ARB_window_pos) },
|
{ ON, "GL_MESA_window_pos", F(ARB_window_pos) },
|
||||||
{ OFF, "GL_NV_blend_square", F(NV_blend_square) },
|
{ OFF, "GL_NV_blend_square", F(NV_blend_square) },
|
||||||
|
@@ -684,7 +684,7 @@ _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvo
|
|||||||
minmax[1][BCOMP] = CLAMP(ctx->MinMax.Max[BCOMP], 0.0F, 1.0F);
|
minmax[1][BCOMP] = CLAMP(ctx->MinMax.Max[BCOMP], 0.0F, 1.0F);
|
||||||
minmax[1][ACOMP] = CLAMP(ctx->MinMax.Max[ACOMP], 0.0F, 1.0F);
|
minmax[1][ACOMP] = CLAMP(ctx->MinMax.Max[ACOMP], 0.0F, 1.0F);
|
||||||
_mesa_pack_rgba_span_float(ctx, 2, minmax,
|
_mesa_pack_rgba_span_float(ctx, 2, minmax,
|
||||||
format, type, values, &ctx->Pack, 0x0);
|
format, type, values, &ctx->Pack, 0x0, GL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->Pack.BufferObj->Name) {
|
if (ctx->Pack.BufferObj->Name) {
|
||||||
|
@@ -1686,24 +1686,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
|
|||||||
GLenum dstFormat, GLenum dstType,
|
GLenum dstFormat, GLenum dstType,
|
||||||
GLvoid *dstAddr,
|
GLvoid *dstAddr,
|
||||||
const struct gl_pixelstore_attrib *dstPacking,
|
const struct gl_pixelstore_attrib *dstPacking,
|
||||||
GLbitfield transferOps)
|
GLbitfield transferOps, GLboolean noClamp)
|
||||||
{
|
{
|
||||||
GLfloat luminance[MAX_WIDTH];
|
GLfloat luminance[MAX_WIDTH];
|
||||||
const GLint comps = _mesa_components_in_format(dstFormat);
|
const GLint comps = _mesa_components_in_format(dstFormat);
|
||||||
GLuint i;
|
GLuint i;
|
||||||
/* clamping only applies to colors, not the dudv values, but still need
|
|
||||||
it if converting to unsigned values (which doesn't make much sense) */
|
if ((!noClamp) && (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE)) {
|
||||||
if (dstFormat == GL_DUDV_ATI || dstFormat == GL_DU8DV8_ATI) {
|
|
||||||
switch (dstType) {
|
|
||||||
case GL_UNSIGNED_BYTE:
|
|
||||||
case GL_UNSIGNED_SHORT:
|
|
||||||
case GL_UNSIGNED_INT:
|
|
||||||
transferOps |= IMAGE_CLAMP_BIT;
|
|
||||||
break;
|
|
||||||
/* actually might want clamp to [-1,1] otherwise but shouldn't matter? */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
|
|
||||||
/* need to clamp to [0, 1] */
|
/* need to clamp to [0, 1] */
|
||||||
transferOps |= IMAGE_CLAMP_BIT;
|
transferOps |= IMAGE_CLAMP_BIT;
|
||||||
}
|
}
|
||||||
|
@@ -178,7 +178,7 @@ extern void
|
|||||||
_mesa_pack_rgba_span_float( GLcontext *ctx, GLuint n, GLfloat rgba[][4],
|
_mesa_pack_rgba_span_float( GLcontext *ctx, GLuint n, GLfloat rgba[][4],
|
||||||
GLenum dstFormat, GLenum dstType, GLvoid *dstAddr,
|
GLenum dstFormat, GLenum dstType, GLvoid *dstAddr,
|
||||||
const struct gl_pixelstore_attrib *dstPacking,
|
const struct gl_pixelstore_attrib *dstPacking,
|
||||||
GLbitfield transferOps );
|
GLbitfield transferOps, GLboolean noClamp );
|
||||||
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
|
@@ -54,12 +54,20 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
|
|||||||
#define FLOAT_TO_BYTE(X) ( (((GLint) (255.0F * (X))) - 1) / 2 )
|
#define FLOAT_TO_BYTE(X) ( (((GLint) (255.0F * (X))) - 1) / 2 )
|
||||||
|
|
||||||
|
|
||||||
|
/** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0], texture/fb data */
|
||||||
|
#define BYTE_TO_FLOAT_TEX(B) ((B) == -128 ? -1.0 : (B) * (1.0F/127.0F))
|
||||||
|
|
||||||
|
/** Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127], texture/fb data */
|
||||||
|
#define FLOAT_TO_BYTE_TEX(X) ( (GLint) (127.0F * (X)) )
|
||||||
|
|
||||||
|
|
||||||
/** Convert GLushort in [0,65535] to GLfloat in [0.0,1.0] */
|
/** Convert GLushort in [0,65535] to GLfloat in [0.0,1.0] */
|
||||||
#define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F))
|
#define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F))
|
||||||
|
|
||||||
/** Convert GLfloat in [0.0,1.0] to GLushort in [0, 65535] */
|
/** Convert GLfloat in [0.0,1.0] to GLushort in [0, 65535] */
|
||||||
#define FLOAT_TO_USHORT(X) ((GLuint) ((X) * 65535.0))
|
#define FLOAT_TO_USHORT(X) ((GLuint) ((X) * 65535.0))
|
||||||
|
|
||||||
|
|
||||||
/** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
|
/** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
|
||||||
#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
|
#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
|
||||||
|
|
||||||
@@ -67,6 +75,13 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
|
|||||||
#define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 )
|
#define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 )
|
||||||
|
|
||||||
|
|
||||||
|
/** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0], texture/fb data */
|
||||||
|
#define SHORT_TO_FLOAT_TEX(S) ((S) == -32768 ? -1.0 : (S) * (1.0F/32767.0F))
|
||||||
|
|
||||||
|
/** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767], texture/fb data */
|
||||||
|
#define FLOAT_TO_SHORT_TEX(X) ( (GLint) (32767.0F * (X)) )
|
||||||
|
|
||||||
|
|
||||||
/** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
|
/** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
|
||||||
#define UINT_TO_FLOAT(U) ((GLfloat) (U) * (1.0F / 4294967295.0F))
|
#define UINT_TO_FLOAT(U) ((GLfloat) (U) * (1.0F / 4294967295.0F))
|
||||||
|
|
||||||
@@ -85,6 +100,13 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
|
|||||||
#define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) )
|
#define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) )
|
||||||
|
|
||||||
|
|
||||||
|
/** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0], texture/fb data */
|
||||||
|
#define INT_TO_FLOAT_TEX(I) ((I) == -2147483648 ? -1.0 : (I) * (1.0F/2147483647.0))
|
||||||
|
|
||||||
|
/** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647], texture/fb data */
|
||||||
|
#define FLOAT_TO_INT_TEX(X) ( (GLint) (2147483647.0F * (X)) )
|
||||||
|
|
||||||
|
|
||||||
#define BYTE_TO_UBYTE(b) ((GLubyte) ((b) < 0 ? 0 : (GLubyte) (b)))
|
#define BYTE_TO_UBYTE(b) ((GLubyte) ((b) < 0 ? 0 : (GLubyte) (b)))
|
||||||
#define SHORT_TO_UBYTE(s) ((GLubyte) ((s) < 0 ? 0 : (GLubyte) ((s) >> 7)))
|
#define SHORT_TO_UBYTE(s) ((GLubyte) ((s) < 0 ? 0 : (GLubyte) ((s) >> 7)))
|
||||||
#define USHORT_TO_UBYTE(s) ((GLubyte) ((s) >> 8))
|
#define USHORT_TO_UBYTE(s) ((GLubyte) ((s) >> 8))
|
||||||
|
@@ -86,6 +86,21 @@ bytes_per_pixel(GLenum datatype, GLuint comps)
|
|||||||
rowD[j][e], rowD[k][e]); \
|
rowD[j][e], rowD[k][e]); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define FILTER_SUM_3D_SIGNED(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \
|
||||||
|
(Aj + Ak \
|
||||||
|
+ Bj + Bk \
|
||||||
|
+ Cj + Ck \
|
||||||
|
+ Dj + Dk \
|
||||||
|
+ 4) / 8
|
||||||
|
|
||||||
|
#define FILTER_3D_SIGNED(e) \
|
||||||
|
do { \
|
||||||
|
dst[i][e] = FILTER_SUM_3D_SIGNED(rowA[j][e], rowA[k][e], \
|
||||||
|
rowB[j][e], rowB[k][e], \
|
||||||
|
rowC[j][e], rowC[k][e], \
|
||||||
|
rowD[j][e], rowD[k][e]); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#define FILTER_F_3D(e) \
|
#define FILTER_F_3D(e) \
|
||||||
do { \
|
do { \
|
||||||
dst[i][e] = (rowA[j][e] + rowA[k][e] \
|
dst[i][e] = (rowA[j][e] + rowA[k][e] \
|
||||||
@@ -180,6 +195,53 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (datatype == GL_BYTE && comps == 4) {
|
||||||
|
GLuint i, j, k;
|
||||||
|
const GLbyte(*rowA)[4] = (const GLbyte(*)[4]) srcRowA;
|
||||||
|
const GLbyte(*rowB)[4] = (const GLbyte(*)[4]) srcRowB;
|
||||||
|
GLbyte(*dst)[4] = (GLbyte(*)[4]) dstRow;
|
||||||
|
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
|
||||||
|
i++, j += colStride, k += colStride) {
|
||||||
|
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
|
||||||
|
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
|
||||||
|
dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
|
||||||
|
dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (datatype == GL_BYTE && comps == 3) {
|
||||||
|
GLuint i, j, k;
|
||||||
|
const GLbyte(*rowA)[3] = (const GLbyte(*)[3]) srcRowA;
|
||||||
|
const GLbyte(*rowB)[3] = (const GLbyte(*)[3]) srcRowB;
|
||||||
|
GLbyte(*dst)[3] = (GLbyte(*)[3]) dstRow;
|
||||||
|
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
|
||||||
|
i++, j += colStride, k += colStride) {
|
||||||
|
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
|
||||||
|
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
|
||||||
|
dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (datatype == GL_BYTE && comps == 2) {
|
||||||
|
GLuint i, j, k;
|
||||||
|
const GLbyte(*rowA)[2] = (const GLbyte(*)[2]) srcRowA;
|
||||||
|
const GLbyte(*rowB)[2] = (const GLbyte(*)[2]) srcRowB;
|
||||||
|
GLbyte(*dst)[2] = (GLbyte(*)[2]) dstRow;
|
||||||
|
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
|
||||||
|
i++, j += colStride, k += colStride) {
|
||||||
|
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
|
||||||
|
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (datatype == GL_BYTE && comps == 1) {
|
||||||
|
GLuint i, j, k;
|
||||||
|
const GLbyte *rowA = (const GLbyte *) srcRowA;
|
||||||
|
const GLbyte *rowB = (const GLbyte *) srcRowB;
|
||||||
|
GLbyte *dst = (GLbyte *) dstRow;
|
||||||
|
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
|
||||||
|
i++, j += colStride, k += colStride) {
|
||||||
|
dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else if (datatype == GL_UNSIGNED_SHORT && comps == 4) {
|
else if (datatype == GL_UNSIGNED_SHORT && comps == 4) {
|
||||||
GLuint i, j, k;
|
GLuint i, j, k;
|
||||||
const GLushort(*rowA)[4] = (const GLushort(*)[4]) srcRowA;
|
const GLushort(*rowA)[4] = (const GLushort(*)[4]) srcRowA;
|
||||||
@@ -470,17 +532,6 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
|
|||||||
dst[i] = (blue << 5) | (green << 2) | red;
|
dst[i] = (blue << 5) | (green << 2) | red;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (datatype == GL_BYTE && comps == 2) {
|
|
||||||
GLuint i, j, k;
|
|
||||||
const GLbyte(*rowA)[2] = (const GLbyte(*)[2]) srcRowA;
|
|
||||||
const GLbyte(*rowB)[2] = (const GLbyte(*)[2]) srcRowB;
|
|
||||||
GLbyte(*dst)[2] = (GLbyte(*)[2]) dstRow;
|
|
||||||
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
|
|
||||||
i++, j += colStride, k += colStride) {
|
|
||||||
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2;
|
|
||||||
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
_mesa_problem(NULL, "bad format in do_row()");
|
_mesa_problem(NULL, "bad format in do_row()");
|
||||||
}
|
}
|
||||||
@@ -555,6 +606,44 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth,
|
|||||||
FILTER_3D(0);
|
FILTER_3D(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((datatype == GL_BYTE) && (comps == 4)) {
|
||||||
|
DECLARE_ROW_POINTERS(GLbyte, 4);
|
||||||
|
|
||||||
|
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
|
||||||
|
i++, j += colStride, k += colStride) {
|
||||||
|
FILTER_3D_SIGNED(0);
|
||||||
|
FILTER_3D_SIGNED(1);
|
||||||
|
FILTER_3D_SIGNED(2);
|
||||||
|
FILTER_3D_SIGNED(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((datatype == GL_BYTE) && (comps == 3)) {
|
||||||
|
DECLARE_ROW_POINTERS(GLbyte, 3);
|
||||||
|
|
||||||
|
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
|
||||||
|
i++, j += colStride, k += colStride) {
|
||||||
|
FILTER_3D_SIGNED(0);
|
||||||
|
FILTER_3D_SIGNED(1);
|
||||||
|
FILTER_3D_SIGNED(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((datatype == GL_BYTE) && (comps == 2)) {
|
||||||
|
DECLARE_ROW_POINTERS(GLbyte, 2);
|
||||||
|
|
||||||
|
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
|
||||||
|
i++, j += colStride, k += colStride) {
|
||||||
|
FILTER_3D_SIGNED(0);
|
||||||
|
FILTER_3D_SIGNED(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((datatype == GL_BYTE) && (comps == 1)) {
|
||||||
|
DECLARE_ROW_POINTERS(GLbyte, 1);
|
||||||
|
|
||||||
|
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
|
||||||
|
i++, j += colStride, k += colStride) {
|
||||||
|
FILTER_3D_SIGNED(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 4)) {
|
else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 4)) {
|
||||||
DECLARE_ROW_POINTERS(GLushort, 4);
|
DECLARE_ROW_POINTERS(GLushort, 4);
|
||||||
|
|
||||||
|
@@ -2503,6 +2503,7 @@ struct gl_extensions
|
|||||||
GLboolean MESA_resize_buffers;
|
GLboolean MESA_resize_buffers;
|
||||||
GLboolean MESA_ycbcr_texture;
|
GLboolean MESA_ycbcr_texture;
|
||||||
GLboolean MESA_texture_array;
|
GLboolean MESA_texture_array;
|
||||||
|
GLboolean MESA_texture_signed_rgba;
|
||||||
GLboolean NV_blend_square;
|
GLboolean NV_blend_square;
|
||||||
GLboolean NV_fragment_program;
|
GLboolean NV_fragment_program;
|
||||||
GLboolean NV_light_max_exponent;
|
GLboolean NV_light_max_exponent;
|
||||||
|
@@ -699,9 +699,7 @@ const struct gl_texture_format _mesa_texformat_intensity_float16 = {
|
|||||||
const struct gl_texture_format _mesa_texformat_dudv8 = {
|
const struct gl_texture_format _mesa_texformat_dudv8 = {
|
||||||
MESA_FORMAT_DUDV8, /* MesaFormat */
|
MESA_FORMAT_DUDV8, /* MesaFormat */
|
||||||
GL_DUDV_ATI, /* BaseFormat */
|
GL_DUDV_ATI, /* BaseFormat */
|
||||||
/* FIXME: spec doesn't say since that parameter didn't exist then,
|
GL_SIGNED_NORMALIZED, /* DataType */
|
||||||
but this should be something like SIGNED_NORMALIZED */
|
|
||||||
GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
|
|
||||||
/* maybe should add dudvBits field, but spec seems to be
|
/* maybe should add dudvBits field, but spec seems to be
|
||||||
lacking the ability to query with GetTexLevelParameter anyway */
|
lacking the ability to query with GetTexLevelParameter anyway */
|
||||||
0, /* RedBits */
|
0, /* RedBits */
|
||||||
@@ -724,6 +722,30 @@ const struct gl_texture_format _mesa_texformat_dudv8 = {
|
|||||||
NULL /* StoreTexel */
|
NULL /* StoreTexel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct gl_texture_format _mesa_texformat_signed_rgba8888 = {
|
||||||
|
MESA_FORMAT_SIGNED_RGBA8888, /* MesaFormat */
|
||||||
|
GL_RGBA, /* BaseFormat */
|
||||||
|
GL_SIGNED_NORMALIZED, /* DataType */
|
||||||
|
8, /* RedBits */
|
||||||
|
8, /* GreenBits */
|
||||||
|
8, /* BlueBits */
|
||||||
|
8, /* AlphaBits */
|
||||||
|
0, /* LuminanceBits */
|
||||||
|
0, /* IntensityBits */
|
||||||
|
0, /* IndexBits */
|
||||||
|
0, /* DepthBits */
|
||||||
|
0, /* StencilBits */
|
||||||
|
4, /* TexelBytes */
|
||||||
|
_mesa_texstore_signed_rgba8888, /* StoreTexImageFunc */
|
||||||
|
NULL, /* FetchTexel1D */
|
||||||
|
NULL, /* FetchTexel2D */
|
||||||
|
NULL, /* FetchTexel3D */
|
||||||
|
fetch_texel_1d_signed_rgba8888, /* FetchTexel1Df */
|
||||||
|
fetch_texel_2d_signed_rgba8888, /* FetchTexel2Df */
|
||||||
|
fetch_texel_3d_signed_rgba8888, /* FetchTexel3Df */
|
||||||
|
store_texel_signed_rgba8888 /* StoreTexel */
|
||||||
|
};
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
@@ -1671,6 +1693,17 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->Extensions.MESA_texture_signed_rgba) {
|
||||||
|
switch (internalFormat) {
|
||||||
|
case GL_RGBA_SNORM:
|
||||||
|
case GL_RGBA8_SNORM:
|
||||||
|
return &_mesa_texformat_signed_rgba8888;
|
||||||
|
default:
|
||||||
|
; /* fallthrough */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if FEATURE_EXT_texture_sRGB
|
#if FEATURE_EXT_texture_sRGB
|
||||||
if (ctx->Extensions.EXT_texture_sRGB) {
|
if (ctx->Extensions.EXT_texture_sRGB) {
|
||||||
switch (internalFormat) {
|
switch (internalFormat) {
|
||||||
@@ -1820,6 +1853,11 @@ _mesa_format_to_type_and_comps(const struct gl_texture_format *format,
|
|||||||
*comps = 2;
|
*comps = 2;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case MESA_FORMAT_SIGNED_RGBA8888:
|
||||||
|
*datatype = GL_BYTE;
|
||||||
|
*comps = 4;
|
||||||
|
return;
|
||||||
|
|
||||||
#if FEATURE_EXT_texture_sRGB
|
#if FEATURE_EXT_texture_sRGB
|
||||||
case MESA_FORMAT_SRGB8:
|
case MESA_FORMAT_SRGB8:
|
||||||
*datatype = GL_UNSIGNED_BYTE;
|
*datatype = GL_UNSIGNED_BYTE;
|
||||||
|
@@ -168,7 +168,8 @@ enum _format {
|
|||||||
* \name Signed fixed point texture formats.
|
* \name Signed fixed point texture formats.
|
||||||
*/
|
*/
|
||||||
/*@{*/
|
/*@{*/
|
||||||
MESA_FORMAT_DUDV8
|
MESA_FORMAT_DUDV8,
|
||||||
|
MESA_FORMAT_SIGNED_RGBA8888
|
||||||
/*@}*/
|
/*@}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -219,6 +220,7 @@ extern const struct gl_texture_format _mesa_texformat_intensity_float16;
|
|||||||
/** Signed fixed point texture formats */
|
/** Signed fixed point texture formats */
|
||||||
/*@{*/
|
/*@{*/
|
||||||
extern const struct gl_texture_format _mesa_texformat_dudv8;
|
extern const struct gl_texture_format _mesa_texformat_dudv8;
|
||||||
|
extern const struct gl_texture_format _mesa_texformat_signed_rgba8888;
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
/** \name Assorted hardware-friendly formats */
|
/** \name Assorted hardware-friendly formats */
|
||||||
|
@@ -1321,6 +1321,28 @@ static void FETCH(dudv8)(const struct gl_texture_image *texImage,
|
|||||||
texel[ACOMP] = 0;
|
texel[ACOMP] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* MESA_FORMAT_SIGNED_ARGB8888 ***********************************************/
|
||||||
|
|
||||||
|
static void FETCH(signed_rgba8888)( const struct gl_texture_image *texImage,
|
||||||
|
GLint i, GLint j, GLint k, GLfloat *texel )
|
||||||
|
{
|
||||||
|
const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
|
||||||
|
texel[RCOMP] = BYTE_TO_FLOAT_TEX( (s >> 24) );
|
||||||
|
texel[GCOMP] = BYTE_TO_FLOAT_TEX( (s >> 16) & 0xff );
|
||||||
|
texel[BCOMP] = BYTE_TO_FLOAT_TEX( (s >> 8) & 0xff );
|
||||||
|
texel[ACOMP] = BYTE_TO_FLOAT_TEX( (s ) & 0xff );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DIM == 3
|
||||||
|
static void store_texel_signed_rgba8888(struct gl_texture_image *texImage,
|
||||||
|
GLint i, GLint j, GLint k, const void *texel)
|
||||||
|
{
|
||||||
|
const GLbyte *rgba = (const GLbyte *) texel;
|
||||||
|
GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
|
||||||
|
*dst = PACK_COLOR_8888(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP], rgba[ACOMP]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* MESA_FORMAT_YCBCR *********************************************************/
|
/* MESA_FORMAT_YCBCR *********************************************************/
|
||||||
|
|
||||||
|
@@ -349,6 +349,15 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->Extensions.MESA_texture_signed_rgba) {
|
||||||
|
switch (internalFormat) {
|
||||||
|
case GL_RGBA_SNORM:
|
||||||
|
case GL_RGBA8_SNORM:
|
||||||
|
return GL_RGBA;
|
||||||
|
default:
|
||||||
|
; /* fallthrough */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->Extensions.EXT_packed_depth_stencil) {
|
if (ctx->Extensions.EXT_packed_depth_stencil) {
|
||||||
switch (internalFormat) {
|
switch (internalFormat) {
|
||||||
@@ -502,6 +511,10 @@ _mesa_is_color_format(GLenum format)
|
|||||||
case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
|
case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
|
||||||
#endif /* FEATURE_EXT_texture_sRGB */
|
#endif /* FEATURE_EXT_texture_sRGB */
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
|
/* signed texture formats */
|
||||||
|
case GL_RGBA_SNORM:
|
||||||
|
case GL_RGBA8_SNORM:
|
||||||
|
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 */
|
||||||
default:
|
default:
|
||||||
|
@@ -417,7 +417,7 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
|
|||||||
(GLfloat (*)[4]) src,
|
(GLfloat (*)[4]) src,
|
||||||
logicalBaseFormat, GL_FLOAT,
|
logicalBaseFormat, GL_FLOAT,
|
||||||
dst, &ctx->DefaultPacking,
|
dst, &ctx->DefaultPacking,
|
||||||
postConvTransferOps);
|
postConvTransferOps, GL_FALSE);
|
||||||
src += convWidth * 4;
|
src += convWidth * 4;
|
||||||
dst += convWidth * logComponents;
|
dst += convWidth * logComponents;
|
||||||
}
|
}
|
||||||
@@ -798,6 +798,7 @@ static const GLubyte *
|
|||||||
type_mapping( GLenum srcType )
|
type_mapping( GLenum srcType )
|
||||||
{
|
{
|
||||||
switch (srcType) {
|
switch (srcType) {
|
||||||
|
case GL_BYTE:
|
||||||
case GL_UNSIGNED_BYTE:
|
case GL_UNSIGNED_BYTE:
|
||||||
return map_identity;
|
return map_identity;
|
||||||
case GL_UNSIGNED_INT_8_8_8_8:
|
case GL_UNSIGNED_INT_8_8_8_8:
|
||||||
@@ -819,6 +820,7 @@ byteswap_mapping( GLboolean swapBytes,
|
|||||||
return map_identity;
|
return map_identity;
|
||||||
|
|
||||||
switch (srcType) {
|
switch (srcType) {
|
||||||
|
case GL_BYTE:
|
||||||
case GL_UNSIGNED_BYTE:
|
case GL_UNSIGNED_BYTE:
|
||||||
return map_identity;
|
return map_identity;
|
||||||
case GL_UNSIGNED_INT_8_8_8_8:
|
case GL_UNSIGNED_INT_8_8_8_8:
|
||||||
@@ -2561,6 +2563,99 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS)
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
|
||||||
|
*/
|
||||||
|
GLboolean
|
||||||
|
_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
|
||||||
|
{
|
||||||
|
const GLboolean littleEndian = _mesa_little_endian();
|
||||||
|
|
||||||
|
ASSERT(dstFormat == &_mesa_texformat_signed_rgba8888);
|
||||||
|
ASSERT(dstFormat->TexelBytes == 4);
|
||||||
|
|
||||||
|
if (!ctx->_ImageTransferState &&
|
||||||
|
!srcPacking->SwapBytes &&
|
||||||
|
dstFormat == &_mesa_texformat_signed_rgba8888 &&
|
||||||
|
baseInternalFormat == GL_RGBA &&
|
||||||
|
((srcFormat == GL_RGBA && srcType == GL_BYTE && !littleEndian) ||
|
||||||
|
(srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) {
|
||||||
|
/* simple memcpy path */
|
||||||
|
memcpy_texture(ctx, dims,
|
||||||
|
dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
|
||||||
|
dstRowStride,
|
||||||
|
dstImageOffsets,
|
||||||
|
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
|
||||||
|
srcAddr, srcPacking);
|
||||||
|
}
|
||||||
|
else if (!ctx->_ImageTransferState &&
|
||||||
|
(srcType == GL_BYTE) &&
|
||||||
|
can_swizzle(baseInternalFormat) &&
|
||||||
|
can_swizzle(srcFormat)) {
|
||||||
|
|
||||||
|
GLubyte dstmap[4];
|
||||||
|
|
||||||
|
/* dstmap - how to swizzle from RGBA to dst format:
|
||||||
|
*/
|
||||||
|
if (littleEndian && dstFormat == &_mesa_texformat_signed_rgba8888) {
|
||||||
|
dstmap[3] = 0;
|
||||||
|
dstmap[2] = 1;
|
||||||
|
dstmap[1] = 2;
|
||||||
|
dstmap[0] = 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dstmap[3] = 3;
|
||||||
|
dstmap[2] = 2;
|
||||||
|
dstmap[1] = 1;
|
||||||
|
dstmap[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_mesa_swizzle_ubyte_image(ctx, dims,
|
||||||
|
srcFormat,
|
||||||
|
srcType,
|
||||||
|
baseInternalFormat,
|
||||||
|
dstmap, 4,
|
||||||
|
dstAddr, dstXoffset, dstYoffset, dstZoffset,
|
||||||
|
dstRowStride, dstImageOffsets,
|
||||||
|
srcWidth, srcHeight, srcDepth, srcAddr,
|
||||||
|
srcPacking);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* general path */
|
||||||
|
const GLfloat *tempImage = make_temp_float_image(ctx, dims,
|
||||||
|
baseInternalFormat,
|
||||||
|
dstFormat->BaseFormat,
|
||||||
|
srcWidth, srcHeight, srcDepth,
|
||||||
|
srcFormat, srcType, srcAddr,
|
||||||
|
srcPacking);
|
||||||
|
const GLfloat *srcRow = tempImage;
|
||||||
|
GLint img, row, col;
|
||||||
|
if (!tempImage)
|
||||||
|
return GL_FALSE;
|
||||||
|
_mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
|
||||||
|
for (img = 0; img < srcDepth; img++) {
|
||||||
|
GLubyte *dstRow = (GLubyte *) dstAddr
|
||||||
|
+ dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
|
||||||
|
+ dstYoffset * dstRowStride
|
||||||
|
+ dstXoffset * dstFormat->TexelBytes;
|
||||||
|
for (row = 0; row < srcHeight; row++) {
|
||||||
|
GLuint *dstUI = (GLuint *) dstRow;
|
||||||
|
if (dstFormat == &_mesa_texformat_signed_rgba8888) {
|
||||||
|
for (col = 0; col < srcWidth; col++) {
|
||||||
|
dstUI[col] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
|
||||||
|
FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
|
||||||
|
FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
|
||||||
|
FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
|
||||||
|
srcRow += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dstRow += dstRowStride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_mesa_free((void *) tempImage);
|
||||||
|
}
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a combined depth/stencil texture image.
|
* Store a combined depth/stencil texture image.
|
||||||
@@ -3820,6 +3915,21 @@ linear_to_nonlinear(GLfloat cl)
|
|||||||
|
|
||||||
#endif /* FEATURE_EXT_texture_sRGB */
|
#endif /* FEATURE_EXT_texture_sRGB */
|
||||||
|
|
||||||
|
static INLINE GLboolean
|
||||||
|
type_with_negative_values(GLenum type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case GL_BYTE:
|
||||||
|
case GL_SHORT:
|
||||||
|
case GL_INT:
|
||||||
|
case GL_FLOAT:
|
||||||
|
case GL_HALF_FLOAT_ARB:
|
||||||
|
return GL_TRUE;
|
||||||
|
default:
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the software fallback for Driver.GetTexImage().
|
* This is the software fallback for Driver.GetTexImage().
|
||||||
* All error checking will have been done before this routine is called.
|
* All error checking will have been done before this routine is called.
|
||||||
@@ -3962,7 +4072,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
|
|||||||
}
|
}
|
||||||
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
|
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
|
||||||
format, type, dest,
|
format, type, dest,
|
||||||
&ctx->Pack, transferOps /*image xfer ops*/);
|
&ctx->Pack, transferOps, GL_TRUE);
|
||||||
}
|
}
|
||||||
#endif /* FEATURE_EXT_texture_sRGB */
|
#endif /* FEATURE_EXT_texture_sRGB */
|
||||||
else {
|
else {
|
||||||
@@ -3971,10 +4081,13 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
|
|||||||
GLint col;
|
GLint col;
|
||||||
GLbitfield transferOps = 0x0;
|
GLbitfield transferOps = 0x0;
|
||||||
|
|
||||||
if (type == GL_FLOAT && texImage->TexFormat->BaseFormat != GL_DUDV_ATI &&
|
/* clamp does not apply to GetTexImage (final conversion)?
|
||||||
((ctx->Color.ClampReadColor == GL_TRUE) ||
|
Looks like we need clamp though when going from format containing
|
||||||
(ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB &&
|
negative values to unsigned format */
|
||||||
texImage->TexFormat->DataType != GL_FLOAT)))
|
|
||||||
|
if (!type_with_negative_values(type) &&
|
||||||
|
(texImage->TexFormat->DataType == GL_FLOAT ||
|
||||||
|
texImage->TexFormat->DataType == GL_SIGNED_NORMALIZED))
|
||||||
transferOps |= IMAGE_CLAMP_BIT;
|
transferOps |= IMAGE_CLAMP_BIT;
|
||||||
|
|
||||||
for (col = 0; col < width; col++) {
|
for (col = 0; col < width; col++) {
|
||||||
@@ -4001,7 +4114,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
|
|||||||
}
|
}
|
||||||
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
|
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
|
||||||
format, type, dest,
|
format, type, dest,
|
||||||
&ctx->Pack, transferOps /*image xfer ops*/);
|
&ctx->Pack, transferOps, GL_TRUE);
|
||||||
} /* format */
|
} /* format */
|
||||||
} /* row */
|
} /* row */
|
||||||
} /* img */
|
} /* img */
|
||||||
|
@@ -79,6 +79,7 @@ extern GLboolean _mesa_texstore_sl8(TEXSTORE_PARAMS);
|
|||||||
extern GLboolean _mesa_texstore_sla8(TEXSTORE_PARAMS);
|
extern GLboolean _mesa_texstore_sla8(TEXSTORE_PARAMS);
|
||||||
#endif
|
#endif
|
||||||
extern GLboolean _mesa_texstore_dudv8(TEXSTORE_PARAMS);
|
extern GLboolean _mesa_texstore_dudv8(TEXSTORE_PARAMS);
|
||||||
|
extern GLboolean _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS);
|
||||||
|
|
||||||
extern GLchan *
|
extern GLchan *
|
||||||
_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
|
_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
|
||||||
|
@@ -486,7 +486,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
|
|||||||
df += dfStride;
|
df += dfStride;
|
||||||
if (!dfStride) {
|
if (!dfStride) {
|
||||||
_mesa_pack_rgba_span_float(ctx, width, temp, format, type, dst,
|
_mesa_pack_rgba_span_float(ctx, width, temp, format, type, dst,
|
||||||
&clippedPacking, transferOps);
|
&clippedPacking, transferOps, GL_FALSE);
|
||||||
dst += dstStride;
|
dst += dstStride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -396,7 +396,7 @@ read_rgba_pixels( GLcontext *ctx,
|
|||||||
format, type, row, 0);
|
format, type, row, 0);
|
||||||
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) src,
|
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) src,
|
||||||
format, type, dest, packing,
|
format, type, dest, packing,
|
||||||
transferOps & IMAGE_POST_CONVOLUTION_BITS);
|
transferOps & IMAGE_POST_CONVOLUTION_BITS, GL_FALSE);
|
||||||
src += width * 4;
|
src += width * 4;
|
||||||
}
|
}
|
||||||
_mesa_free(convImage);
|
_mesa_free(convImage);
|
||||||
@@ -441,7 +441,7 @@ read_rgba_pixels( GLcontext *ctx,
|
|||||||
|
|
||||||
/* pack the row of RGBA pixels into user's buffer */
|
/* pack the row of RGBA pixels into user's buffer */
|
||||||
_mesa_pack_rgba_span_float(ctx, width, rgba, format, type, dst,
|
_mesa_pack_rgba_span_float(ctx, width, rgba, format, type, dst,
|
||||||
packing, transferOps);
|
packing, transferOps, GL_FALSE);
|
||||||
|
|
||||||
dst += dstStride;
|
dst += dstStride;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user