mesa: add support for ATI_envmap_bumpmap

add new entrypoints, new texture format, etc
translate in texenvprogram.c for drivers using the mesa-generated tex env
fragment program
also handled in swrast, but not tested (cannot work due to negative texel
results not handled correctly)
This commit is contained in:
Roland Scheidegger
2009-03-12 15:01:16 +01:00
parent b7d841b59e
commit 114152e068
24 changed files with 906 additions and 24 deletions

View File

@@ -11681,6 +11681,56 @@
<enum name="DEPTH_STENCIL_TO_BGRA_NV" value="0x886F"/>
</category>
<category name="GL_ATI_envmap_bumpmap" number="244">
<enum name="BUMP_ROT_MATRIX_ATI" count="4" value="0x8775">
<size name="TexBumpParameterfv"/>
<size name="TexBumpParameteriv"/>
<size name="GetTexBumpParameterfv" mode="get"/>
<size name="GetTexBumpParameteriv" mode="get"/>
</enum>
<enum name="BUMP_ROT_MATRIX_SIZE_ATI" count="1" value="0x8776">
<size name="GetTexBumpParameterfv" mode="get"/>
<size name="GetTexBumpParameteriv" mode="get"/>
</enum>
<enum name="BUMP_NUM_TEX_UNITS_ATI" count="1" value="0x8777">
<size name="GetTexBumpParameterfv" mode="get"/>
<size name="GetTexBumpParameteriv" mode="get"/>
</enum>
<enum name="BUMP_TEX_UNITS_ATI" count="-1" value="0x8778">
<size name="GetTexBumpParameterfv" mode="get"/>
<size name="GetTexBumpParameteriv" mode="get"/>
</enum>
<enum name="DUDV_ATI" value="0x8779"/>
<enum name="DU8DV8_ATI" value="0x877A"/>
<enum name="BUMP_ENVMAP_ATI" value="0x877B"/>
<enum name="BUMP_TARGET_ATI" count="1" value="0x877C">
<size name="TexEnviv"/>
<size name="TexEnvfv"/>
<size name="GetTexEnviv" mode="get"/>
<size name="GetTexEnvfv" mode="get"/>
</enum>
<function name="TexBumpParameterfvATI" offset="assign">
<param name="pname" type="GLenum"/>
<param name="param" type="const GLfloat *" variable_param="pname"/>
<glx ignore="true"/>
</function>
<function name="TexBumpParameterivATI" offset="assign">
<param name="pname" type="GLenum"/>
<param name="param" type="const GLint *" variable_param="pname"/>
<glx ignore="true"/>
</function>
<function name="GetTexBumpParameterfvATI" offset="assign">
<param name="pname" type="GLenum"/>
<param name="param" type="GLfloat *" variable_param="pname"/>
<glx ignore="true"/>
</function>
<function name="GetTexBumpParameterivATI" offset="assign">
<param name="pname" type="GLenum"/>
<param name="param" type="GLint *" variable_param="pname"/>
<glx ignore="true"/>
</function>
</category>
<category name="GL_ATI_fragment_shader" number="245">
<function name="GenFragmentShadersATI" offset="assign">
<return type="GLuint"/>

View File

@@ -839,6 +839,12 @@ _mesa_init_exec_table(struct _glapi_table *exec)
SET_SetFragmentShaderConstantATI(exec, _mesa_SetFragmentShaderConstantATI);
#endif
/* GL_ATI_envmap_bumpmap */
SET_GetTexBumpParameterivATI(exec, _mesa_GetTexBumpParameterivATI);
SET_GetTexBumpParameterfvATI(exec, _mesa_GetTexBumpParameterfvATI);
SET_TexBumpParameterivATI(exec, _mesa_TexBumpParameterivATI);
SET_TexBumpParameterfvATI(exec, _mesa_TexBumpParameterfvATI);
#if FEATURE_EXT_framebuffer_object
SET_IsRenderbufferEXT(exec, _mesa_IsRenderbufferEXT);
SET_BindRenderbufferEXT(exec, _mesa_BindRenderbufferEXT);

View File

@@ -232,7 +232,8 @@
#define MAX_COLOR_ATTACHMENTS 8
/*@}*/
/** For GL_ATI_envmap_bump - support bump mapping on first 8 units */
#define SUPPORTED_ATI_BUMP_UNITS 0xff
/**
* \name Mesa-specific parameters

View File

@@ -589,6 +589,9 @@ _mesa_init_constants(GLcontext *ctx)
/* GL_ARB_framebuffer_object */
ctx->Const.MaxSamples = 0;
/* GL_ATI_envmap_bumpmap */
ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS;
/* sanity checks */
ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits,
ctx->Const.MaxTextureCoordUnits));

View File

@@ -320,6 +320,8 @@ typedef enum
/* GL_ARB_draw_buffers */
OPCODE_DRAW_BUFFERS_ARB,
/* GL_ATI_fragment_shader */
OPCODE_TEX_BUMP_PARAMETER_ATI,
/* GL_ATI_fragment_shader */
OPCODE_BIND_FRAGMENT_SHADER_ATI,
OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI,
/* OpenGL 2.0 */
@@ -4803,6 +4805,36 @@ save_DrawBuffersARB(GLsizei count, const GLenum * buffers)
}
}
static void GLAPIENTRY
save_TexBumpParameterfvATI(GLenum pname, const GLfloat *param)
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_BUMP_PARAMETER_ATI, 5);
if (n) {
n[1].ui = pname;
n[2].f = param[0];
n[3].f = param[1];
n[4].f = param[2];
n[5].f = param[3];
}
if (ctx->ExecuteFlag) {
CALL_TexBumpParameterfvATI(ctx->Exec, (pname, param));
}
}
static void GLAPIENTRY
save_TexBumpParameterivATI(GLenum pname, const GLint *param)
{
GLfloat p[4];
p[0] = INT_TO_FLOAT(param[0]);
p[1] = INT_TO_FLOAT(param[1]);
p[2] = INT_TO_FLOAT(param[2]);
p[3] = INT_TO_FLOAT(param[3]);
save_TexBumpParameterfvATI(pname, p);
}
#if FEATURE_ATI_fragment_shader
static void GLAPIENTRY
save_BindFragmentShaderATI(GLuint id)
@@ -6505,6 +6537,16 @@ execute_list(GLcontext *ctx, GLuint list)
n[9].i, n[10].e));
break;
#endif
case OPCODE_TEX_BUMP_PARAMETER_ATI:
{
GLfloat values[4];
GLuint i, pname = n[1].ui;
for (i = 0; i < 4; i++)
values[i] = n[1 + i].f;
CALL_TexBumpParameterfvATI(ctx->Exec, (pname, values));
}
break;
#if FEATURE_ATI_fragment_shader
case OPCODE_BIND_FRAGMENT_SHADER_ATI:
CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i));
@@ -8043,6 +8085,10 @@ _mesa_init_dlist_table(struct _glapi_table *table)
SET_VertexAttribPointerNV(table, _mesa_VertexAttribPointerNV);
#endif
/* 244. GL_ATI_envmap_bumpmap */
SET_TexBumpParameterivATI(table, save_TexBumpParameterivATI);
SET_TexBumpParameterfvATI(table, save_TexBumpParameterfvATI);
/* 245. GL_ATI_fragment_shader */
#if FEATURE_ATI_fragment_shader
SET_BindFragmentShaderATI(table, save_BindFragmentShaderATI);

View File

@@ -137,6 +137,7 @@ static const struct {
{ ON, "GL_APPLE_packed_pixels", F(APPLE_packed_pixels) },
{ OFF, "GL_APPLE_vertex_array_object", F(APPLE_vertex_array_object) },
{ OFF, "GL_ATI_blend_equation_separate", F(EXT_blend_equation_separate) },
{ OFF, "GL_ATI_envmap_bumpmap", F(ATI_envmap_bumpmap) },
{ OFF, "GL_ATI_texture_env_combine3", F(ATI_texture_env_combine3)},
{ OFF, "GL_ATI_texture_mirror_once", F(ATI_texture_mirror_once)},
{ OFF, "GL_ATI_fragment_shader", F(ATI_fragment_shader)},
@@ -229,6 +230,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
/*ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;*/
#endif
ctx->Extensions.APPLE_vertex_array_object = GL_TRUE;
ctx->Extensions.ATI_envmap_bumpmap = GL_TRUE;
#if FEATURE_ATI_fragment_shader
ctx->Extensions.ATI_fragment_shader = GL_TRUE;
#endif

View File

@@ -293,6 +293,8 @@ _mesa_components_in_format( GLenum format )
return 2;
case GL_DEPTH_STENCIL_EXT:
return 2;
case GL_DUDV_ATI:
return 2;
default:
return -1;
}
@@ -503,6 +505,20 @@ _mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type )
return GL_TRUE;
else
return GL_FALSE;
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
switch (type) {
case GL_BYTE:
case GL_UNSIGNED_BYTE:
case GL_SHORT:
case GL_UNSIGNED_SHORT:
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
return GL_TRUE;
default:
return GL_FALSE;
}
default:
; /* fall-through */
}
@@ -1674,8 +1690,19 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
GLfloat luminance[MAX_WIDTH];
const GLint comps = _mesa_components_in_format(dstFormat);
GLuint i;
if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
/* 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 (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] */
transferOps |= IMAGE_CLAMP_BIT;
}
@@ -1774,6 +1801,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
}
break;
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
for (i=0;i<n;i++) {
dst[i*2+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
dst[i*2+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
}
break;
default:
_mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
}
@@ -1847,6 +1881,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
}
break;
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
for (i=0;i<n;i++) {
dst[i*2+0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
dst[i*2+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
}
break;
default:
_mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
}
@@ -1920,6 +1961,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][RCOMP]);
}
break;
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
for (i=0;i<n;i++) {
dst[i*2+0] = FLOAT_TO_USHORT(rgba[i][RCOMP]);
dst[i*2+1] = FLOAT_TO_USHORT(rgba[i][GCOMP]);
}
break;
default:
_mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
}
@@ -1993,6 +2041,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
}
break;
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
for (i=0;i<n;i++) {
dst[i*2+0] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
dst[i*2+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
}
break;
default:
_mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
}
@@ -2066,6 +2121,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
dst[i*4+3] = FLOAT_TO_UINT(rgba[i][RCOMP]);
}
break;
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
for (i=0;i<n;i++) {
dst[i*2+0] = FLOAT_TO_UINT(rgba[i][RCOMP]);
dst[i*2+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
}
break;
default:
_mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
}
@@ -2139,6 +2201,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
dst[i*4+3] = FLOAT_TO_INT(rgba[i][RCOMP]);
}
break;
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
for (i=0;i<n;i++) {
dst[i*2+0] = FLOAT_TO_INT(rgba[i][RCOMP]);
dst[i*2+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
}
break;
default:
_mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
}
@@ -2212,6 +2281,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
dst[i*4+3] = rgba[i][RCOMP];
}
break;
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
for (i=0;i<n;i++) {
dst[i*2+0] = rgba[i][RCOMP];
dst[i*2+1] = rgba[i][GCOMP];
}
break;
default:
_mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
}
@@ -2285,6 +2361,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
dst[i*4+3] = _mesa_float_to_half(rgba[i][RCOMP]);
}
break;
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
for (i=0;i<n;i++) {
dst[i*2+0] = _mesa_float_to_half(rgba[i][RCOMP]);
dst[i*2+1] = _mesa_float_to_half(rgba[i][GCOMP]);
}
break;
default:
_mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
}
@@ -2834,7 +2917,8 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
srcFormat == GL_BGR ||
srcFormat == GL_RGBA ||
srcFormat == GL_BGRA ||
srcFormat == GL_ABGR_EXT);
srcFormat == GL_ABGR_EXT ||
srcFormat == GL_DUDV_ATI);
ASSERT(srcType == GL_UNSIGNED_BYTE ||
srcType == GL_BYTE ||
@@ -2949,6 +3033,13 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
aComp = 0;
stride = 4;
break;
case GL_DUDV_ATI:
redIndex = 0;
greenIndex = 1;
blueIndex = -1;
alphaIndex = -1;
stride = 2;
break;
default:
_mesa_problem(NULL, "bad srcFormat in extract float data");
return;
@@ -3877,6 +3968,62 @@ _mesa_unpack_color_span_float( GLcontext *ctx,
}
}
/**
* Similar to _mesa_unpack_color_span_float(), but for dudv data instead of rgba,
* directly return GLbyte data, no transfer ops apply.
*/
void
_mesa_unpack_dudv_span_byte( GLcontext *ctx,
GLuint n, GLenum dstFormat, GLbyte dest[],
GLenum srcFormat, GLenum srcType,
const GLvoid *source,
const struct gl_pixelstore_attrib *srcPacking,
GLbitfield transferOps )
{
ASSERT(dstFormat == GL_DUDV_ATI);
ASSERT(srcFormat == GL_DUDV_ATI);
ASSERT(srcType == GL_UNSIGNED_BYTE ||
srcType == GL_BYTE ||
srcType == GL_UNSIGNED_SHORT ||
srcType == GL_SHORT ||
srcType == GL_UNSIGNED_INT ||
srcType == GL_INT ||
srcType == GL_HALF_FLOAT_ARB ||
srcType == GL_FLOAT);
/* general solution */
{
GLint dstComponents;
GLfloat rgba[MAX_WIDTH][4];
dstComponents = _mesa_components_in_format( dstFormat );
/* source & dest image formats should have been error checked by now */
assert(dstComponents > 0);
/*
* Extract image data and convert to RGBA floats
*/
assert(n <= MAX_WIDTH);
extract_float_rgba(n, rgba, srcFormat, srcType, source,
srcPacking->SwapBytes);
/* Now determine which color channels we need to produce.
* And determine the dest index (offset) within each color tuple.
*/
/* Now pack results in the requested dstFormat */
GLbyte *dst = dest;
GLuint i;
for (i = 0; i < n; i++) {
/* not sure - need clamp[-1,1] here? */
dst[0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
dst[1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
dst += dstComponents;
}
}
}
/*
* Unpack a row of color index data from a client buffer according to

View File

@@ -198,6 +198,13 @@ _mesa_unpack_color_span_float( GLcontext *ctx,
const struct gl_pixelstore_attrib *srcPacking,
GLbitfield transferOps );
extern void
_mesa_unpack_dudv_span_byte( GLcontext *ctx,
GLuint n, GLenum dstFormat, GLbyte dest[],
GLenum srcFormat, GLenum srcType,
const GLvoid *source,
const struct gl_pixelstore_attrib *srcPacking,
GLbitfield transferOps );
extern void
_mesa_unpack_index_span( const GLcontext *ctx, GLuint n,

View File

@@ -54,13 +54,16 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
#define FLOAT_TO_BYTE(X) ( (((GLint) (255.0F * (X))) - 1) / 2 )
/** Convert GLushort in [0,65536] 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))
/** Convert GLfloat in [0.0,1.0] to GLushort in [0, 65535] */
#define FLOAT_TO_USHORT(X) ((GLuint) ((X) * 65535.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))
/** Convert GLfloat in [0.0,1.0] to GLshort in [-32768,32767] */
/** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767] */
#define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 )

View File

@@ -85,7 +85,7 @@ bytes_per_pixel(GLenum datatype, GLuint comps)
rowC[j][e], rowC[k][e], \
rowD[j][e], rowD[k][e]); \
} while(0)
#define FILTER_F_3D(e) \
do { \
dst[i][e] = (rowA[j][e] + rowA[k][e] \
@@ -226,7 +226,6 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
}
}
else if (datatype == GL_FLOAT && comps == 4) {
GLuint i, j, k;
const GLfloat(*rowA)[4] = (const GLfloat(*)[4]) srcRowA;
@@ -471,6 +470,17 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
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 {
_mesa_problem(NULL, "bad format in do_row()");
}

View File

@@ -1390,6 +1390,8 @@ struct gl_texture_unit
GLbitfield _GenFlags; /**< Bitwise-OR of Gen[STRQ]._ModeBit */
GLfloat LodBias; /**< for biasing mipmap levels */
GLenum BumpTarget;
GLfloat RotMatrix[4]; /* 2x2 matrix */
/**
* \name GL_EXT_texture_env_combine
@@ -2388,6 +2390,8 @@ struct gl_constants
GLuint MaxSamples; /**< GL_ARB_framebuffer_object */
GLuint MaxVarying; /**< Number of float[4] varying parameters */
GLbitfield SupportedBumpUnits; /**> units supporting GL_ATI_envmap_bumpmap as targets */
};
@@ -2484,6 +2488,7 @@ struct gl_extensions
GLboolean APPLE_client_storage;
GLboolean APPLE_packed_pixels;
GLboolean APPLE_vertex_array_object;
GLboolean ATI_envmap_bumpmap;
GLboolean ATI_texture_mirror_once;
GLboolean ATI_texture_env_combine3;
GLboolean ATI_fragment_shader;

View File

@@ -142,7 +142,11 @@ set_combiner_mode(GLcontext *ctx,
case GL_MODULATE_ADD_ATI:
case GL_MODULATE_SIGNED_ADD_ATI:
case GL_MODULATE_SUBTRACT_ATI:
legal =ctx->Extensions.ATI_texture_env_combine3;
legal = ctx->Extensions.ATI_texture_env_combine3;
break;
case GL_BUMP_ENVMAP_ATI:
legal = (ctx->Extensions.ATI_envmap_bumpmap &&
pname == GL_COMBINE_RGB);
break;
default:
legal = GL_FALSE;
@@ -500,6 +504,26 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
case GL_ALPHA_SCALE:
set_combiner_scale(ctx, texUnit, pname, param[0]);
break;
case GL_BUMP_TARGET_ATI:
if (!ctx->Extensions.ATI_envmap_bumpmap) {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
return;
}
if (((GLenum) (GLint) param[0] < GL_TEXTURE0) ||
((GLenum) (GLint) param[0] > GL_TEXTURE31)) {
/* spec doesn't say this but it seems logical */
_mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param=0x%x)", (GLenum) (GLint) param[0]);
return;
}
if (!((1 << ((GLenum) (GLint) param[0] - GL_TEXTURE0)) & ctx->Const.SupportedBumpUnits)) {
_mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", (GLenum) (GLint) param[0]);
return;
}
else {
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texUnit->BumpTarget = (GLenum) (GLint) param[0];
}
break;
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
return;
@@ -735,6 +759,16 @@ get_texenvi(GLcontext *ctx, const struct gl_texture_unit *texUnit,
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
}
break;
case GL_BUMP_TARGET_ATI:
/* spec doesn't say so, but I think this should be queryable */
if (ctx->Extensions.ATI_envmap_bumpmap) {
return texUnit->BumpTarget;
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
}
break;
default:
;
}
@@ -874,4 +908,142 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
}
}
/* why does ATI_envmap_bumpmap require new entrypoints? Should just
reuse TexEnv ones... */
void GLAPIENTRY
_mesa_TexBumpParameterivATI( GLenum pname, const GLint *param )
{
GLfloat p[4];
if (pname == GL_BUMP_ROT_MATRIX_ATI) {
/* hope that conversion is correct here */
p[0] = INT_TO_FLOAT( param[0] );
p[1] = INT_TO_FLOAT( param[1] );
p[2] = INT_TO_FLOAT( param[2] );
p[3] = INT_TO_FLOAT( param[3] );
}
else {
p[0] = (GLfloat) param[0];
p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */
}
_mesa_TexBumpParameterfvATI( pname, p );
}
void GLAPIENTRY
_mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param )
{
struct gl_texture_unit *texUnit;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
/* should return error if extension not supported? */
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
if (pname == GL_BUMP_ROT_MATRIX_ATI) {
if (TEST_EQ_4V(param, texUnit->RotMatrix))
return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
COPY_4FV(texUnit->RotMatrix, param);
}
else {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexBumpParameter(pname)" );
return;
}
/* Drivers might want to know about this, instead of dedicated function
just shove it into TexEnv where it really belongs anyway */
if (ctx->Driver.TexEnv) {
(*ctx->Driver.TexEnv)( ctx, 0, pname, param );
}
}
void GLAPIENTRY
_mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param )
{
const struct gl_texture_unit *texUnit;
GLint i;
GLint temp = 0;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
/* should return error if extension not supported? */
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
if (pname == GL_BUMP_ROT_MATRIX_SIZE_ATI) {
/* spec leaves open to support larger matrices.
Don't think anyone would ever want to use it
(and apps almost certainly would not understand it and
thus fail to submit matrices correctly) so hardcode this. */
*param = 4;
}
else if (pname == GL_BUMP_ROT_MATRIX_ATI) {
/* hope that conversion is correct here */
param[0] = FLOAT_TO_INT(texUnit->RotMatrix[0]);
param[1] = FLOAT_TO_INT(texUnit->RotMatrix[1]);
param[2] = FLOAT_TO_INT(texUnit->RotMatrix[2]);
param[3] = FLOAT_TO_INT(texUnit->RotMatrix[3]);
}
else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) {
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Const.SupportedBumpUnits & (1 << i)) {
temp++;
}
}
*param = temp;
}
else if (pname == GL_BUMP_TEX_UNITS_ATI) {
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Const.SupportedBumpUnits & (1 << i)) {
*param++ = i + GL_TEXTURE0;
}
}
}
else {
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexBumpParameter(pname)" );
return;
}
}
void GLAPIENTRY
_mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param )
{
const struct gl_texture_unit *texUnit;
GLint i;
GLint temp = 0;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
/* should return error if extension not supported? */
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
if (pname == GL_BUMP_ROT_MATRIX_SIZE_ATI) {
/* spec leaves open to support larger matrices.
Don't think anyone would ever want to use it
(and apps might not understand it) so hardcode this. */
*param = (GLfloat) 4;
}
else if (pname == GL_BUMP_ROT_MATRIX_ATI) {
param[0] = texUnit->RotMatrix[0];
param[1] = texUnit->RotMatrix[1];
param[2] = texUnit->RotMatrix[2];
param[3] = texUnit->RotMatrix[3];
}
else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) {
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Const.SupportedBumpUnits & (1 << i)) {
temp++;
}
}
*param = (GLfloat) temp;
}
else if (pname == GL_BUMP_TEX_UNITS_ATI) {
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Const.SupportedBumpUnits & (1 << i)) {
*param++ = (GLfloat) (i + GL_TEXTURE0);
}
}
}
else {
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexBumpParameter(pname)" );
return;
}
}

View File

@@ -48,5 +48,16 @@ _mesa_TexEnvi( GLenum target, GLenum pname, GLint param );
extern void GLAPIENTRY
_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param );
extern void GLAPIENTRY
_mesa_TexBumpParameterivATI( GLenum pname, const GLint *param );
extern void GLAPIENTRY
_mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param );
extern void GLAPIENTRY
_mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param );
extern void GLAPIENTRY
_mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param );
#endif /* TEXENV_H */

View File

@@ -94,11 +94,11 @@ struct state_key {
GLuint ScaleShiftA:2;
GLuint NumArgsRGB:3;
GLuint ModeRGB:4;
GLuint ModeRGB:5;
struct mode_opt OptRGB[MAX_TERMS];
GLuint NumArgsA:3;
GLuint ModeA:4;
GLuint ModeA:5;
struct mode_opt OptA[MAX_TERMS];
} unit[8];
};
@@ -194,7 +194,8 @@ static GLuint translate_source( GLenum src )
#define MODE_MODULATE_SUBTRACT_ATI 12 /* r = a0 * a2 - a1 */
#define MODE_ADD_PRODUCTS 13 /* r = a0 * a1 + a2 * a3 */
#define MODE_ADD_PRODUCTS_SIGNED 14 /* r = a0 * a1 + a2 * a3 - 0.5 */
#define MODE_UNKNOWN 15
#define MODE_BUMP_ENVMAP_ATI 15 /* special */
#define MODE_UNKNOWN 16
/**
* Translate GL combiner state into a MODE_x value
@@ -223,6 +224,7 @@ static GLuint translate_mode( GLenum envMode, GLenum mode )
case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI;
case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI;
case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI;
case GL_BUMP_ENVMAP_ATI: return MODE_BUMP_ENVMAP_ATI;
default:
assert(0);
return MODE_UNKNOWN;
@@ -383,7 +385,7 @@ static void make_state_key( GLcontext *ctx, struct state_key *key )
translate_mode(texUnit->EnvMode, texUnit->_CurrentCombine->ModeRGB);
key->unit[i].ModeA =
translate_mode(texUnit->EnvMode, texUnit->_CurrentCombine->ModeA);
key->unit[i].ScaleShiftRGB = texUnit->_CurrentCombine->ScaleShiftRGB;
key->unit[i].ScaleShiftA = texUnit->_CurrentCombine->ScaleShiftA;
@@ -397,8 +399,18 @@ static void make_state_key( GLcontext *ctx, struct state_key *key )
key->unit[i].OptA[j].Source =
translate_source(texUnit->_CurrentCombine->SourceA[j]);
}
if (key->unit[i].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
/* requires some special translation */
key->unit[i].NumArgsRGB = 2;
key->unit[i].ScaleShiftRGB = 0;
key->unit[i].OptRGB[0].Operand = OPR_SRC_COLOR;
key->unit[i].OptRGB[0].Source = SRC_TEXTURE;
key->unit[i].OptRGB[1].Operand = OPR_SRC_COLOR;
key->unit[i].OptRGB[1].Source = texUnit->BumpTarget - GL_TEXTURE0 + SRC_TEXTURE0;
}
}
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
key->separate_specular = 1;
inputs_referenced |= FRAG_BIT_COL1;
@@ -464,6 +476,11 @@ struct texenv_fragment_program {
* else undef.
*/
struct ureg texcoord_tex[MAX_TEXTURE_COORD_UNITS];
/* Reg containing texcoord for a texture unit,
* needed for bump mapping, else undef.
*/
struct ureg src_previous; /**< Reg containing color from previous
* stage. May need to be decl'd.
*/
@@ -756,6 +773,7 @@ static struct ureg emit_texld( struct texenv_fragment_program *p,
*/
reserve_temp(p, dest);
#if 0
/* Is this a texture indirection?
*/
if ((coord.file == PROGRAM_TEMPORARY &&
@@ -767,6 +785,7 @@ static struct ureg emit_texld( struct texenv_fragment_program *p,
p->alu_temps = 0;
assert(0); /* KW: texture env crossbar */
}
#endif
return dest;
}
@@ -1052,6 +1071,10 @@ static struct ureg emit_combine( struct texenv_fragment_program *p,
emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef );
}
return dest;
case MODE_BUMP_ENVMAP_ATI:
/* special - not handled here */
assert(0);
return src[0];
default:
assert(0);
return src[0];
@@ -1074,6 +1097,10 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
if (!key->unit[unit].enabled) {
return get_source(p, SRC_PREVIOUS, 0);
}
if (key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
/* this isn't really a env stage delivering a color and handled elsewhere */
return get_source(p, SRC_PREVIOUS, 0);
}
switch (key->unit[unit].ModeRGB) {
case MODE_DOT3_RGB_EXT:
@@ -1163,9 +1190,17 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit )
{
if (is_undef(p->src_texture[unit])) {
GLuint texTarget = p->state->unit[unit].source_index;
struct ureg texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit);
struct ureg texcoord;
struct ureg tmp = get_tex_temp( p );
if (is_undef(p->texcoord_tex[unit])) {
texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit);
}
else {
/* might want to reuse this reg for tex output actually */
texcoord = p->texcoord_tex[unit];
}
if (texTarget == TEXTURE_UNKNOWN_INDEX)
program_error(p, "TexSrcBit");
@@ -1233,7 +1268,7 @@ load_texunit_sources( struct texenv_fragment_program *p, int unit )
GLuint i;
for (i = 0; i < key->unit[unit].NumArgsRGB; i++) {
load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit);
load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit );
}
for (i = 0; i < key->unit[unit].NumArgsA; i++) {
@@ -1243,6 +1278,40 @@ load_texunit_sources( struct texenv_fragment_program *p, int unit )
return GL_TRUE;
}
/**
* Generate instructions for loading bump map textures.
*/
static GLboolean
load_texunit_bumpmap( struct texenv_fragment_program *p, int unit )
{
struct state_key *key = p->state;
GLuint bumpedUnitNr = key->unit[unit].OptRGB[1].Source - SRC_TEXTURE0;
struct ureg texcDst, bumpMapRes;
struct ureg constdudvcolor = register_const4f(p, 0.0, 0.0, 0.0, 1.0);
struct ureg texcSrc = register_input(p, FRAG_ATTRIB_TEX0 + bumpedUnitNr);
struct ureg rotMat0 = register_param3( p, STATE_INTERNAL, STATE_ROT_MATRIX_0, unit );
struct ureg rotMat1 = register_param3( p, STATE_INTERNAL, STATE_ROT_MATRIX_1, unit );
load_texenv_source( p, unit + SRC_TEXTURE0, unit );
bumpMapRes = get_source(p, key->unit[unit].OptRGB[0].Source, unit);
texcDst = get_tex_temp( p );
p->texcoord_tex[bumpedUnitNr] = texcDst;
/* apply rot matrix and add coords to be available in next phase */
/* dest = (Arg0.xxxx * rotMat0 + Arg1) + (Arg0.yyyy * rotMat1) */
/* note only 2 coords are affected the rest are left unchanged (mul by 0) */
emit_arith( p, OPCODE_MAD, texcDst, WRITEMASK_XYZW, 0,
swizzle1(bumpMapRes, SWIZZLE_X), rotMat0, texcSrc );
emit_arith( p, OPCODE_MAD, texcDst, WRITEMASK_XYZW, 0,
swizzle1(bumpMapRes, SWIZZLE_Y), rotMat1, texcDst );
/* move 0,0,0,1 into bumpmap src if someone (crossbar) is foolish
enough to access this later, should optimize away */
emit_arith( p, OPCODE_MOV, bumpMapRes, WRITEMASK_XYZW, 0, constdudvcolor, undef, undef );
return GL_TRUE;
}
/**
* Generate a new fragment program which implements the context's
@@ -1267,7 +1336,7 @@ create_new_program(GLcontext *ctx, struct state_key *key,
*/
p.program->Base.Instructions = instBuffer;
p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB;
p.program->Base.NumTexIndirections = 1; /* correct? */
p.program->Base.NumTexIndirections = 1;
p.program->Base.NumTexInstructions = 0;
p.program->Base.NumAluInstructions = 0;
p.program->Base.String = NULL;
@@ -1280,8 +1349,10 @@ create_new_program(GLcontext *ctx, struct state_key *key,
p.program->Base.InputsRead = 0;
p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLOR;
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++)
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
p.src_texture[unit] = undef;
p.texcoord_tex[unit] = undef;
}
p.src_previous = undef;
p.half = undef;
@@ -1292,6 +1363,16 @@ create_new_program(GLcontext *ctx, struct state_key *key,
release_temps(ctx, &p);
if (key->enabled_units) {
GLboolean needbumpstage = GL_FALSE;
/* Zeroth pass - bump map textures first */
for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++)
if (key->unit[unit].enabled && key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
needbumpstage = GL_TRUE;
load_texunit_bumpmap( &p, unit );
}
if (needbumpstage)
p.program->Base.NumTexIndirections++;
/* First pass - to support texture_env_crossbar, first identify
* all referenced texture sources and emit texld instructions
* for each:

View File

@@ -696,6 +696,33 @@ const struct gl_texture_format _mesa_texformat_intensity_float16 = {
store_texel_intensity_f16 /* StoreTexel */
};
const struct gl_texture_format _mesa_texformat_dudv8 = {
MESA_FORMAT_DUDV8, /* MesaFormat */
GL_DUDV_ATI, /* BaseFormat */
/* FIXME: spec doesn't say since that parameter didn't exist then,
but this should be something like SIGNED_NORMALIZED */
GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
/* maybe should add dudvBits field, but spec seems to be
lacking the ability to query with GetTexLevelParameter anyway */
0, /* RedBits */
0, /* GreenBits */
0, /* BlueBits */
0, /* AlphaBits */
0, /* LuminanceBits */
0, /* IntensityBits */
0, /* IndexBits */
0, /* DepthBits */
0, /* StencilBits */
2, /* TexelBytes */
_mesa_texstore_dudv8, /* StoreTexImageFunc */
NULL, /* FetchTexel1D */
NULL, /* FetchTexel2D */
NULL, /* FetchTexel3D */
NULL, /* FetchTexel1Df */
fetch_texel_2d_dudv8, /* FetchTexel2Df */
NULL, /* FetchTexel3Df */
NULL /* StoreTexel */
};
/*@}*/
@@ -1634,6 +1661,16 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
}
}
if (ctx->Extensions.ATI_envmap_bumpmap) {
switch (internalFormat) {
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
return &_mesa_texformat_dudv8;
default:
; /* fallthrough */
}
}
#if FEATURE_EXT_texture_sRGB
if (ctx->Extensions.EXT_texture_sRGB) {
switch (internalFormat) {
@@ -1778,6 +1815,11 @@ _mesa_format_to_type_and_comps(const struct gl_texture_format *format,
*comps = 1;
return;
case MESA_FORMAT_DUDV8:
*datatype = GL_BYTE;
*comps = 2;
return;
#if FEATURE_EXT_texture_sRGB
case MESA_FORMAT_SRGB8:
*datatype = GL_UNSIGNED_BYTE;

View File

@@ -161,7 +161,14 @@ enum _format {
MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32,
MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16,
MESA_FORMAT_INTENSITY_FLOAT32,
MESA_FORMAT_INTENSITY_FLOAT16
MESA_FORMAT_INTENSITY_FLOAT16,
/*@}*/
/**
* \name Signed fixed point texture formats.
*/
/*@{*/
MESA_FORMAT_DUDV8
/*@}*/
};
@@ -209,6 +216,11 @@ extern const struct gl_texture_format _mesa_texformat_intensity_float32;
extern const struct gl_texture_format _mesa_texformat_intensity_float16;
/*@}*/
/** Signed fixed point texture formats */
/*@{*/
extern const struct gl_texture_format _mesa_texformat_dudv8;
/*@}*/
/** \name Assorted hardware-friendly formats */
/*@{*/
extern const struct gl_texture_format _mesa_texformat_rgba8888;

View File

@@ -1269,7 +1269,7 @@ static void FETCH(sl8)(const struct gl_texture_image *texImage,
texel[RCOMP] =
texel[GCOMP] =
texel[BCOMP] = nonlinear_to_linear(src[0]);
texel[ACOMP] = CHAN_MAX;
texel[ACOMP] = 1.0F;
}
#if DIM == 3
@@ -1308,7 +1308,22 @@ static void store_texel_sla8(struct gl_texture_image *texImage,
#endif /* FEATURE_EXT_texture_sRGB */
#if DIM == 2
/* MESA_FORMAT_DUDV8 ********************************************************/
/* this format by definition produces 0,0,0,1 as rgba values,
however we'll return the dudv values as rg and fix up elsewhere */
static void FETCH(dudv8)(const struct gl_texture_image *texImage,
GLint i, GLint j, GLint k, GLfloat *texel )
{
const GLbyte *src = TEXEL_ADDR(GLbyte, texImage, i, j, k, 2);
texel[RCOMP] = BYTE_TO_FLOAT(src[0]);
texel[GCOMP] = BYTE_TO_FLOAT(src[1]);
texel[BCOMP] = 0;
texel[ACOMP] = 0;
}
#endif
/* MESA_FORMAT_YCBCR *********************************************************/

View File

@@ -339,6 +339,17 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
}
}
if (ctx->Extensions.ATI_envmap_bumpmap) {
switch (internalFormat) {
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
return GL_DUDV_ATI;
default:
; /* fallthrough */
}
}
if (ctx->Extensions.EXT_packed_depth_stencil) {
switch (internalFormat) {
case GL_DEPTH_STENCIL_EXT:
@@ -568,6 +579,20 @@ is_depthstencil_format(GLenum format)
}
}
/**
* Test if the given image format is a dudv format.
*/
static GLboolean
is_dudv_format(GLenum format)
{
switch (format) {
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
return GL_TRUE;
default:
return GL_FALSE;
}
}
/**
@@ -1539,7 +1564,8 @@ texture_error_check( GLcontext *ctx, GLenum target,
(is_index_format(internalFormat) && !indexFormat) ||
(is_depth_format(internalFormat) != is_depth_format(format)) ||
(is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) ||
(is_depthstencil_format(internalFormat) != is_depthstencil_format(format))) {
(is_depthstencil_format(internalFormat) != is_depthstencil_format(format)) ||
(is_dudv_format(internalFormat) != is_dudv_format(format))) {
if (!isProxy)
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTexImage(internalFormat/format)");
@@ -2273,6 +2299,12 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
return;
}
if (!ctx->Extensions.ATI_envmap_bumpmap
&& is_dudv_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return;
}
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -2313,6 +2345,11 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
goto out;
}
else if (is_dudv_format(format)
&& !is_dudv_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
goto out;
}
if (ctx->Pack.BufferObj->Name) {
/* packing texture image into a PBO */

View File

@@ -95,6 +95,11 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
/* GL_EXT_texture_env_combine */
dst->Texture.Unit[u].Combine = src->Texture.Unit[u].Combine;
/* GL_ATI_envmap_bumpmap - need this? */
dst->Texture.Unit[u].BumpTarget = src->Texture.Unit[u].BumpTarget;
COPY_4V(dst->Texture.Unit[u].RotMatrix, src->Texture.Unit[u].RotMatrix);
/* copy texture object bindings, not contents of texture objects */
_mesa_lock_context_textures(dst);
@@ -411,6 +416,10 @@ update_tex_combine(GLcontext *ctx, struct gl_texture_unit *texUnit)
case GL_MODULATE_SUBTRACT_ATI:
combine->_NumArgsRGB = 3;
break;
case GL_BUMP_ENVMAP_ATI:
/* no real arguments for this case */
combine->_NumArgsRGB = 0;
break;
default:
combine->_NumArgsRGB = 0;
_mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
@@ -682,6 +691,7 @@ init_texture_unit( GLcontext *ctx, GLuint unit )
texUnit->Combine = default_combine_state;
texUnit->_EnvMode = default_combine_state;
texUnit->_CurrentCombine = & texUnit->_EnvMode;
texUnit->BumpTarget = GL_TEXTURE0;
texUnit->TexGenEnabled = 0x0;
texUnit->GenS.Mode = GL_EYE_LINEAR;
@@ -702,6 +712,16 @@ init_texture_unit( GLcontext *ctx, GLuint unit )
ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
/* no mention of this in spec, but maybe id matrix expected? */
ASSIGN_4V( texUnit->RotMatrix, 1.0, 0.0, 0.0, 1.0 );
/* initialize current texture object ptrs to the shared default objects */
for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {

View File

@@ -2471,6 +2471,95 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
return GL_TRUE;
}
GLboolean
_mesa_texstore_dudv8(TEXSTORE_PARAMS)
{
const GLboolean littleEndian = _mesa_little_endian();
ASSERT(dstFormat == &_mesa_texformat_dudv8);
ASSERT(dstFormat->TexelBytes == 2);
ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
ASSERT((srcFormat == GL_DU8DV8_ATI) ||
(srcFormat == GL_DUDV_ATI));
ASSERT(baseInternalFormat == GL_DUDV_ATI);
if (!srcPacking->SwapBytes && 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 (srcType == GL_BYTE) {
GLubyte dstmap[4];
/* dstmap - how to swizzle from RGBA to dst format:
*/
if (littleEndian) {
dstmap[0] = 0;
dstmap[1] = 3;
}
else {
dstmap[0] = 3;
dstmap[1] = 0;
}
dstmap[2] = ZERO; /* ? */
dstmap[3] = ONE; /* ? */
_mesa_swizzle_ubyte_image(ctx, dims,
GL_LUMINANCE_ALPHA, /* hack */
GL_UNSIGNED_BYTE, /* hack */
GL_LUMINANCE_ALPHA, /* hack */
dstmap, 2,
dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageOffsets,
srcWidth, srcHeight, srcDepth, srcAddr,
srcPacking);
}
else {
/* general path - note this is defined for 2d textures only */
const GLint components = _mesa_components_in_format(baseInternalFormat);
const GLint srcStride = _mesa_image_row_stride(srcPacking,
srcWidth, srcFormat, srcType);
GLbyte *tempImage, *dst, *src;
GLint row;
tempImage = (GLbyte *) _mesa_malloc(srcWidth * srcHeight * srcDepth
* components * sizeof(GLbyte));
if (!tempImage)
return GL_FALSE;
src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
srcWidth, srcHeight,
srcFormat, srcType,
0, 0, 0);
dst = tempImage;
for (row = 0; row < srcHeight; row++) {
_mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
dst, srcFormat, srcType, src,
srcPacking, 0);
dst += srcWidth * components;
src += srcStride;
}
src = tempImage;
dst = (GLbyte *) dstAddr
+ dstYoffset * dstRowStride
+ dstXoffset * dstFormat->TexelBytes;
for (row = 0; row < srcHeight; row++) {
memcpy(dst, src, srcWidth * dstFormat->TexelBytes);
dst += dstRowStride;
src += srcWidth * dstFormat->TexelBytes;
}
_mesa_free((void *) tempImage);
}
return GL_TRUE;
}
/**
@@ -3882,7 +3971,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
GLint col;
GLbitfield transferOps = 0x0;
if (type == GL_FLOAT &&
if (type == GL_FLOAT && texImage->TexFormat->BaseFormat != GL_DUDV_ATI &&
((ctx->Color.ClampReadColor == GL_TRUE) ||
(ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB &&
texImage->TexFormat->DataType != GL_FLOAT)))

View File

@@ -78,7 +78,7 @@ extern GLboolean _mesa_texstore_sargb8(TEXSTORE_PARAMS);
extern GLboolean _mesa_texstore_sl8(TEXSTORE_PARAMS);
extern GLboolean _mesa_texstore_sla8(TEXSTORE_PARAMS);
#endif
extern GLboolean _mesa_texstore_dudv8(TEXSTORE_PARAMS);
extern GLchan *
_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,

View File

@@ -506,6 +506,26 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
}
}
return;
case STATE_ROT_MATRIX_0:
{
const int unit = (int) state[2];
GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix;
value[0] = rotMat22[0];
value[1] = rotMat22[2];
value[2] = 0.0;
value[3] = 0.0;
}
break;
case STATE_ROT_MATRIX_1:
{
const int unit = (int) state[2];
GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix;
value[0] = rotMat22[1];
value[1] = rotMat22[3];
value[2] = 0.0;
value[3] = 0.0;
}
break;
/* XXX: make sure new tokens added here are also handled in the
* _mesa_program_state_flags() switch, below.
@@ -591,6 +611,8 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
case STATE_TEXRECT_SCALE:
case STATE_SHADOW_AMBIENT:
case STATE_ROT_MATRIX_0:
case STATE_ROT_MATRIX_1:
return _NEW_TEXTURE;
case STATE_FOG_PARAMS_OPTIMIZED:
return _NEW_FOG;
@@ -806,6 +828,12 @@ append_token(char *dst, gl_state_index k)
case STATE_SHADOW_AMBIENT:
append(dst, "CompareFailValue");
break;
case STATE_ROT_MATRIX_0:
append(dst, "rotMatrixRow0");
break;
case STATE_ROT_MATRIX_1:
append(dst, "rotMatrixRow1");
break;
default:
/* probably STATE_INTERNAL_DRIVER+i (driver private state) */
append(dst, "driverState");

View File

@@ -117,6 +117,8 @@ typedef enum gl_state_index_ {
STATE_PCM_SCALE, /**< Post color matrix RGBA scale */
STATE_PCM_BIAS, /**< Post color matrix RGBA bias */
STATE_SHADOW_AMBIENT, /**< ARB_shadow_ambient fail value; token[2] is texture unit index */
STATE_ROT_MATRIX_0, /**< ATI_envmap_bumpmap, rot matrix row 0 */
STATE_ROT_MATRIX_1, /**< ATI_envmap_bumpmap, rot matrix row 1 */
STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */
} gl_state_index;

View File

@@ -591,6 +591,25 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
}
}
break;
case GL_BUMP_ENVMAP_ATI:
{
/* this produces a fixed rgba color, and the coord calc is done elsewhere */
for (i = 0; i < n; i++) {
/* rgba result is 0,0,0,1 */
#if CHAN_TYPE == GL_FLOAT
rgba[i][RCOMP] = 0.0;
rgba[i][GCOMP] = 0.0;
rgba[i][BCOMP] = 0.0;
rgba[i][ACOMP] = 1.0;
#else
rgba[i][RCOMP] = 0;
rgba[i][GCOMP] = 0;
rgba[i][BCOMP] = 0;
rgba[i][ACOMP] = CHAN_MAX;
#endif
}
}
return; /* no alpha processing */
default:
_mesa_problem(ctx, "invalid combine mode");
}
@@ -1218,12 +1237,86 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span )
if (swrast->_AnyTextureCombine)
MEMCPY(primary_rgba, span->array->rgba, 4 * span->end * sizeof(GLchan));
/* First must sample all bump maps */
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled &&
ctx->Texture.Unit[unit]._CurrentCombine->ModeRGB == GL_BUMP_ENVMAP_ATI) {
const GLfloat (*texcoords)[4]
= (const GLfloat (*)[4])
span->array->attribs[FRAG_ATTRIB_TEX0 + unit];
GLfloat (*targetcoords)[4]
= (GLfloat (*)[4])
span->array->attribs[FRAG_ATTRIB_TEX0 +
ctx->Texture.Unit[unit].BumpTarget - GL_TEXTURE0];
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
const struct gl_texture_object *curObj = texUnit->_Current;
GLfloat *lambda = span->array->lambda[unit];
GLchan (*texels)[4] = (GLchan (*)[4])
(swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLchan)));
GLuint i;
GLfloat rotMatrix00 = ctx->Texture.Unit[unit].RotMatrix[0];
GLfloat rotMatrix01 = ctx->Texture.Unit[unit].RotMatrix[1];
GLfloat rotMatrix10 = ctx->Texture.Unit[unit].RotMatrix[2];
GLfloat rotMatrix11 = ctx->Texture.Unit[unit].RotMatrix[3];
/* adjust texture lod (lambda) */
if (span->arrayMask & SPAN_LAMBDA) {
if (texUnit->LodBias + curObj->LodBias != 0.0F) {
/* apply LOD bias, but don't clamp yet */
const GLfloat bias = CLAMP(texUnit->LodBias + curObj->LodBias,
-ctx->Const.MaxTextureLodBias,
ctx->Const.MaxTextureLodBias);
GLuint i;
for (i = 0; i < span->end; i++) {
lambda[i] += bias;
}
}
if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) {
/* apply LOD clamping to lambda */
const GLfloat min = curObj->MinLod;
const GLfloat max = curObj->MaxLod;
GLuint i;
for (i = 0; i < span->end; i++) {
GLfloat l = lambda[i];
lambda[i] = CLAMP(l, min, max);
}
}
}
/* Sample the texture (span->end = number of fragments) */
swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end,
texcoords, lambda, texels );
/* manipulate the span values of the bump target
not sure this can work correctly even ignoring
the problem that channel is unsigned */
for (i = 0; i < span->end; i++) {
#if CHAN_TYPE == GL_FLOAT
targetcoords[i][0] += (texels[i][0] * rotMatrix00 + texels[i][1] *
rotMatrix01) / targetcoords[i][3];
targetcoords[i][1] += (texels[i][0] * rotMatrix10 + texels[i][1] *
rotMatrix11) / targetcoords[i][3];
#else
targetcoords[i][0] += (CHAN_TO_FLOAT(texels[i][1]) * rotMatrix00 +
CHAN_TO_FLOAT(texels[i][1]) * rotMatrix01) /
targetcoords[i][3];
targetcoords[i][1] += (CHAN_TO_FLOAT(texels[i][0]) * rotMatrix10 +
CHAN_TO_FLOAT(texels[i][1]) * rotMatrix11) /
targetcoords[i][3];
#endif
}
}
}
/*
* Must do all texture sampling before combining in order to
* accomodate GL_ARB_texture_env_crossbar.
*/
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
if (ctx->Texture.Unit[unit]._ReallyEnabled &&
ctx->Texture.Unit[unit]._CurrentCombine->ModeRGB != GL_BUMP_ENVMAP_ATI) {
const GLfloat (*texcoords)[4]
= (const GLfloat (*)[4])
span->array->attribs[FRAG_ATTRIB_TEX0 + unit];