Merge branch 'tex_combine4'

This commit is contained in:
Brian Paul 2009-01-23 17:39:44 -07:00
commit cba5ce1665
8 changed files with 814 additions and 626 deletions

View File

@ -388,6 +388,7 @@ static const struct dri_extension card_extensions[] = {
{ "GL_MESA_ycbcr_texture", NULL },
{ "GL_NV_blend_square", NULL },
{ "GL_NV_point_sprite", GL_NV_point_sprite_functions },
{ "GL_NV_texture_env_combine4", NULL },
{ "GL_NV_vertex_program", GL_NV_vertex_program_functions },
{ "GL_NV_vertex_program1_1", NULL },
{ "GL_SGIS_generate_mipmap", NULL },

View File

@ -155,6 +155,7 @@ static const struct {
{ OFF, "GL_NV_fragment_program", F(NV_fragment_program) },
{ ON, "GL_NV_light_max_exponent", F(NV_light_max_exponent) },
{ OFF, "GL_NV_point_sprite", F(NV_point_sprite) },
{ OFF, "GL_NV_texture_env_combine4", F(NV_texture_env_combine4) },
{ OFF, "GL_NV_texture_rectangle", F(NV_texture_rectangle) },
{ ON, "GL_NV_texgen_reflection", F(NV_texgen_reflection) },
{ OFF, "GL_NV_vertex_program", F(NV_vertex_program) },
@ -284,6 +285,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
ctx->Extensions.NV_blend_square = GL_TRUE;
/*ctx->Extensions.NV_light_max_exponent = GL_TRUE;*/
ctx->Extensions.NV_point_sprite = GL_TRUE;
ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
ctx->Extensions.NV_texture_rectangle = GL_TRUE;
/*ctx->Extensions.NV_texgen_reflection = GL_TRUE;*/
#if FEATURE_NV_vertex_program

View File

@ -1468,23 +1468,20 @@ struct gl_texture_object
/**
* Texture combine environment state.
*
* \todo
* If GL_NV_texture_env_combine4 is ever supported, the arrays in this
* structure will need to be expanded for 4 elements.
* Up to four combiner sources are possible with GL_NV_texture_env_combine4.
*/
struct gl_tex_env_combine_state
{
GLenum ModeRGB; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
GLenum ModeA; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
GLenum SourceRGB[3]; /**< GL_PRIMARY_COLOR, GL_TEXTURE, etc. */
GLenum SourceA[3]; /**< GL_PRIMARY_COLOR, GL_TEXTURE, etc. */
GLenum OperandRGB[3]; /**< SRC_COLOR, ONE_MINUS_SRC_COLOR, etc */
GLenum OperandA[3]; /**< SRC_ALPHA, ONE_MINUS_SRC_ALPHA, etc */
GLenum SourceRGB[4]; /**< GL_PRIMARY_COLOR, GL_TEXTURE, etc. */
GLenum SourceA[4]; /**< GL_PRIMARY_COLOR, GL_TEXTURE, etc. */
GLenum OperandRGB[4]; /**< SRC_COLOR, ONE_MINUS_SRC_COLOR, etc */
GLenum OperandA[4]; /**< SRC_ALPHA, ONE_MINUS_SRC_ALPHA, etc */
GLuint ScaleShiftRGB; /**< 0, 1 or 2 */
GLuint ScaleShiftA; /**< 0, 1 or 2 */
GLuint _NumArgsRGB; /**< Number of inputs used for the combine mode. */
GLuint _NumArgsA; /**< Number of inputs used for the combine mode. */
GLuint _NumArgsRGB; /**< Number of inputs used for the RGB combiner */
GLuint _NumArgsA; /**< Number of inputs used for the A combiner */
};
@ -2649,6 +2646,7 @@ struct gl_extensions
GLboolean NV_light_max_exponent;
GLboolean NV_point_sprite;
GLboolean NV_texgen_reflection;
GLboolean NV_texture_env_combine4;
GLboolean NV_texture_rectangle;
GLboolean NV_vertex_program;
GLboolean NV_vertex_program1_1;

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
* Copyright 2009 VMware, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@ -38,6 +39,9 @@
#include "texenvprogram.h"
#define MAX_TERMS 4
/*
* Note on texture units:
*
@ -89,13 +93,13 @@ struct state_key {
GLuint ScaleShiftRGB:2;
GLuint ScaleShiftA:2;
GLuint NumArgsRGB:2;
GLuint NumArgsRGB:3;
GLuint ModeRGB:4;
struct mode_opt OptRGB[3];
struct mode_opt OptRGB[MAX_TERMS];
GLuint NumArgsA:2;
GLuint NumArgsA:3;
GLuint ModeA:4;
struct mode_opt OptA[3];
struct mode_opt OptA[MAX_TERMS];
} unit[8];
};
@ -131,7 +135,9 @@ static GLuint translate_operand( GLenum operand )
case GL_ONE_MINUS_SRC_ALPHA: return OPR_ONE_MINUS_SRC_ALPHA;
case GL_ZERO: return OPR_ZERO;
case GL_ONE: return OPR_ONE;
default: return OPR_UNKNOWN;
default:
assert(0);
return OPR_UNKNOWN;
}
}
@ -147,6 +153,7 @@ static GLuint translate_operand( GLenum operand )
#define SRC_CONSTANT 9
#define SRC_PRIMARY_COLOR 10
#define SRC_PREVIOUS 11
#define SRC_ZERO 12
#define SRC_UNKNOWN 15
static GLuint translate_source( GLenum src )
@ -164,32 +171,49 @@ static GLuint translate_source( GLenum src )
case GL_CONSTANT: return SRC_CONSTANT;
case GL_PRIMARY_COLOR: return SRC_PRIMARY_COLOR;
case GL_PREVIOUS: return SRC_PREVIOUS;
default: return SRC_UNKNOWN;
case GL_ZERO:
return SRC_ZERO;
default:
assert(0);
return SRC_UNKNOWN;
}
}
#define MODE_REPLACE 0
#define MODE_MODULATE 1
#define MODE_ADD 2
#define MODE_ADD_SIGNED 3
#define MODE_INTERPOLATE 4
#define MODE_SUBTRACT 5
#define MODE_DOT3_RGB 6
#define MODE_DOT3_RGB_EXT 7
#define MODE_DOT3_RGBA 8
#define MODE_DOT3_RGBA_EXT 9
#define MODE_MODULATE_ADD_ATI 10
#define MODE_MODULATE_SIGNED_ADD_ATI 11
#define MODE_MODULATE_SUBTRACT_ATI 12
#define MODE_UNKNOWN 15
#define MODE_REPLACE 0 /* r = a0 */
#define MODE_MODULATE 1 /* r = a0 * a1 */
#define MODE_ADD 2 /* r = a0 + a1 */
#define MODE_ADD_SIGNED 3 /* r = a0 + a1 - 0.5 */
#define MODE_INTERPOLATE 4 /* r = a0 * a2 + a1 * (1 - a2) */
#define MODE_SUBTRACT 5 /* r = a0 - a1 */
#define MODE_DOT3_RGB 6 /* r = a0 . a1 */
#define MODE_DOT3_RGB_EXT 7 /* r = a0 . a1 */
#define MODE_DOT3_RGBA 8 /* r = a0 . a1 */
#define MODE_DOT3_RGBA_EXT 9 /* r = a0 . a1 */
#define MODE_MODULATE_ADD_ATI 10 /* r = a0 * a2 + a1 */
#define MODE_MODULATE_SIGNED_ADD_ATI 11 /* r = a0 * a2 + a1 - 0.5 */
#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
static GLuint translate_mode( GLenum mode )
/**
* Translate GL combiner state into a MODE_x value
*/
static GLuint translate_mode( GLenum envMode, GLenum mode )
{
switch (mode) {
case GL_REPLACE: return MODE_REPLACE;
case GL_MODULATE: return MODE_MODULATE;
case GL_ADD: return MODE_ADD;
case GL_ADD_SIGNED: return MODE_ADD_SIGNED;
case GL_ADD:
if (envMode == GL_COMBINE4_NV)
return MODE_ADD_PRODUCTS;
else
return MODE_ADD;
case GL_ADD_SIGNED:
if (envMode == GL_COMBINE4_NV)
return MODE_ADD_PRODUCTS_SIGNED;
else
return MODE_ADD_SIGNED;
case GL_INTERPOLATE: return MODE_INTERPOLATE;
case GL_SUBTRACT: return MODE_SUBTRACT;
case GL_DOT3_RGB: return MODE_DOT3_RGB;
@ -199,7 +223,9 @@ static GLuint translate_mode( 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;
default: return MODE_UNKNOWN;
default:
assert(0);
return MODE_UNKNOWN;
}
}
@ -212,7 +238,11 @@ static GLuint translate_tex_src_bit( GLbitfield bit )
case TEXTURE_RECT_BIT: return TEXTURE_RECT_INDEX;
case TEXTURE_3D_BIT: return TEXTURE_3D_INDEX;
case TEXTURE_CUBE_BIT: return TEXTURE_CUBE_INDEX;
default: return TEXTURE_UNKNOWN_INDEX;
case TEXTURE_1D_ARRAY_BIT: return TEXTURE_1D_ARRAY_INDEX;
case TEXTURE_2D_ARRAY_BIT: return TEXTURE_2D_ARRAY_INDEX;
default:
assert(0);
return TEXTURE_UNKNOWN_INDEX;
}
}
@ -248,14 +278,14 @@ static void make_state_key( GLcontext *ctx, struct state_key *key )
key->unit[i].NumArgsA = texUnit->_CurrentCombine->_NumArgsA;
key->unit[i].ModeRGB =
translate_mode(texUnit->_CurrentCombine->ModeRGB);
translate_mode(texUnit->EnvMode, texUnit->_CurrentCombine->ModeRGB);
key->unit[i].ModeA =
translate_mode(texUnit->_CurrentCombine->ModeA);
translate_mode(texUnit->EnvMode, texUnit->_CurrentCombine->ModeA);
key->unit[i].ScaleShiftRGB = texUnit->_CurrentCombine->ScaleShiftRGB;
key->unit[i].ScaleShiftA = texUnit->_CurrentCombine->ScaleShiftA;
for (j=0;j<3;j++) {
for (j = 0; j < MAX_TERMS; j++) {
key->unit[i].OptRGB[j].Operand =
translate_operand(texUnit->_CurrentCombine->OperandRGB[j]);
key->unit[i].OptA[j].Operand =
@ -677,12 +707,17 @@ static struct ureg get_source( struct texenv_fragment_program *p,
case SRC_PRIMARY_COLOR:
return register_input(p, FRAG_ATTRIB_COL0);
case SRC_ZERO:
return get_zero(p);
case SRC_PREVIOUS:
default:
if (is_undef(p->src_previous))
return register_input(p, FRAG_ATTRIB_COL0);
else
return p->src_previous;
default:
assert(0);
}
}
@ -723,7 +758,9 @@ static struct ureg emit_combine_source( struct texenv_fragment_program *p,
case OPR_ONE:
return get_one(p);
case OPR_SRC_COLOR:
return src;
default:
assert(0);
return src;
}
}
@ -772,10 +809,12 @@ static struct ureg emit_combine( struct texenv_fragment_program *p,
GLuint mode,
const struct mode_opt *opt)
{
struct ureg src[3];
struct ureg src[MAX_TERMS];
struct ureg tmp, half;
GLuint i;
assert(nr <= MAX_TERMS);
tmp = undef; /* silence warning (bug 5318) */
for (i = 0; i < nr; i++)
@ -851,7 +890,26 @@ static struct ureg emit_combine( struct texenv_fragment_program *p,
/* Arg0 * Arg2 - Arg1 */
emit_arith( p, OPCODE_MAD, dest, mask, 0, src[0], src[2], negate(src[1]) );
return dest;
case MODE_ADD_PRODUCTS:
/* Arg0 * Arg1 + Arg2 * Arg3 */
{
struct ureg tmp0 = get_temp(p);
emit_arith( p, OPCODE_MUL, tmp0, mask, 0, src[0], src[1], undef );
emit_arith( p, OPCODE_MAD, dest, mask, saturate, src[2], src[3], tmp0 );
}
return dest;
case MODE_ADD_PRODUCTS_SIGNED:
/* Arg0 * Arg1 + Arg2 * Arg3 - 0.5 */
{
struct ureg tmp0 = get_temp(p);
half = get_half(p);
emit_arith( p, OPCODE_MUL, tmp0, mask, 0, src[0], src[1], undef );
emit_arith( p, OPCODE_MAD, tmp0, mask, 0, src[2], src[3], tmp0 );
emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef );
}
return dest;
default:
assert(0);
return src[0];
}
}
@ -1007,6 +1065,7 @@ static GLboolean load_texenv_source( struct texenv_fragment_program *p,
break;
default:
/* not a texture src - do nothing */
break;
}

View File

@ -53,10 +53,10 @@
*/
static const struct gl_tex_env_combine_state default_combine_state = {
GL_MODULATE, GL_MODULATE,
{ GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
{ GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
{ GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA },
{ GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
{ GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
{ GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
{ GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_ALPHA },
{ GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
0, 0,
2, 2
};
@ -551,7 +551,8 @@ update_texture_state( GLcontext *ctx )
if (texUnit->_ReallyEnabled)
ctx->Texture._EnabledUnits |= (1 << unit);
if (texUnit->EnvMode == GL_COMBINE) {
if (texUnit->EnvMode == GL_COMBINE ||
texUnit->EnvMode == GL_COMBINE4_NV) {
texUnit->_CurrentCombine = & texUnit->Combine;
}
else {
@ -572,9 +573,14 @@ update_texture_state( GLcontext *ctx )
case GL_REPLACE:
texUnit->_CurrentCombine->_NumArgsRGB = 1;
break;
case GL_MODULATE:
case GL_ADD:
case GL_ADD_SIGNED:
if (texUnit->EnvMode == GL_COMBINE4_NV)
texUnit->_CurrentCombine->_NumArgsRGB = 4;
else
texUnit->_CurrentCombine->_NumArgsRGB = 2;
break;
case GL_MODULATE:
case GL_SUBTRACT:
case GL_DOT3_RGB:
case GL_DOT3_RGBA:
@ -598,9 +604,14 @@ update_texture_state( GLcontext *ctx )
case GL_REPLACE:
texUnit->_CurrentCombine->_NumArgsA = 1;
break;
case GL_MODULATE:
case GL_ADD:
case GL_ADD_SIGNED:
if (texUnit->EnvMode == GL_COMBINE4_NV)
texUnit->_CurrentCombine->_NumArgsA = 4;
else
texUnit->_CurrentCombine->_NumArgsA = 2;
break;
case GL_MODULATE:
case GL_SUBTRACT:
texUnit->_CurrentCombine->_NumArgsA = 2;
break;

View File

@ -1,8 +1,9 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.1
* Version: 7.5
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -66,9 +67,9 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
GLchan (*rgba)[4] )
{
const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]);
const GLchan (*argRGB [3])[4];
const GLchan (*argA [3])[4];
const GLuint RGBshift = textureUnit->_CurrentCombine->ScaleShiftRGB;
const GLchan (*argRGB [4])[4];
const GLchan (*argA [4])[4];
const GLint RGBshift = textureUnit->_CurrentCombine->ScaleShiftRGB;
const GLuint Ashift = textureUnit->_CurrentCombine->ScaleShiftA;
#if CHAN_TYPE == GL_FLOAT
const GLchan RGBmult = (GLfloat) (1 << RGBshift);
@ -80,7 +81,7 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
static const GLchan zero[4] = { 0, 0, 0, 0 };
const GLuint numColorArgs = textureUnit->_CurrentCombine->_NumArgsRGB;
const GLuint numAlphaArgs = textureUnit->_CurrentCombine->_NumArgsA;
GLchan ccolor[3][MAX_WIDTH][4];
GLchan ccolor[4][MAX_WIDTH][4];
GLuint i, j;
ASSERT(ctx->Extensions.EXT_texture_env_combine ||
@ -98,7 +99,7 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
*/
/*
* Do operand setup for up to 3 operands. Loop over the terms.
* Do operand setup for up to 4 operands. Loop over the terms.
*/
for (j = 0; j < numColorArgs; j++) {
const GLenum srcRGB = textureUnit->_CurrentCombine->SourceRGB[j];
@ -295,7 +296,36 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
}
break;
case GL_ADD:
{
if (textureUnit->EnvMode == GL_COMBINE4_NV) {
/* (a * b) + (c * d) */
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
const GLchan (*arg3)[4] = (const GLchan (*)[4]) argRGB[3];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] +
arg2[i][RCOMP] * arg3[i][RCOMP]) * RGBmult;
rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] +
arg2[i][GCOMP] * arg3[i][GCOMP]) * RGBmult;
rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] +
arg2[i][BCOMP] * arg3[i][BCOMP]) * RGBmult;
#else
const GLint shift = CHAN_BITS - RGBshift;
GLint r = (PROD(arg0[i][RCOMP], arg1[i][RCOMP]) >> shift) +
(PROD(arg2[i][RCOMP], arg3[i][RCOMP]) >> shift);
GLint g = (PROD(arg0[i][GCOMP], arg1[i][GCOMP]) >> shift) +
(PROD(arg2[i][GCOMP], arg3[i][GCOMP]) >> shift);
GLint b = (PROD(arg0[i][BCOMP], arg1[i][BCOMP]) >> shift) +
(PROD(arg2[i][BCOMP], arg3[i][BCOMP]) >> shift);
rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
#endif
}
}
else {
/* 2-term addition */
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
for (i = 0; i < n; i++) {
@ -315,7 +345,37 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
}
break;
case GL_ADD_SIGNED:
{
if (textureUnit->EnvMode == GL_COMBINE4_NV) {
/* (a * b) + (c * d) - 0.5 */
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
const GLchan (*arg3)[4] = (const GLchan (*)[4]) argRGB[3];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] *
arg2[i][RCOMP] + arg3[i][RCOMP] - 0.5) * RGBmult;
rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] *
arg2[i][GCOMP] + arg3[i][GCOMP] - 0.5) * RGBmult;
rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] *
arg2[i][BCOMP] + arg3[i][BCOMP] - 0.5) * RGBmult;
#else
GLint r = (((PROD(arg0[i][RCOMP], arg1[i][RCOMP]) +
PROD(arg2[i][RCOMP], arg3[i][RCOMP])) >> CHAN_BITS) - half)
<< RGBshift;
GLint g = (((PROD(arg0[i][GCOMP], arg1[i][GCOMP]) +
PROD(arg2[i][GCOMP], arg3[i][GCOMP])) >> CHAN_BITS) - half)
<< RGBshift;
GLint b = (((PROD(arg0[i][BCOMP], arg1[i][BCOMP]) +
PROD(arg2[i][BCOMP], arg3[i][BCOMP])) >> CHAN_BITS) - half)
<< RGBshift;
rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
#endif
}
}
else {
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
for (i = 0; i < n; i++) {
@ -324,9 +384,9 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5) * RGBmult;
rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5) * RGBmult;
#else
GLint r = (GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP] -half;
GLint g = (GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP] -half;
GLint b = (GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP] -half;
GLint r = (GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP] - half;
GLint g = (GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP] - half;
GLint b = (GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP] - half;
r = (r < 0) ? 0 : r << RGBshift;
g = (g < 0) ? 0 : g << RGBshift;
b = (b < 0) ? 0 : b << RGBshift;
@ -573,9 +633,28 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
}
break;
case GL_ADD:
{
if (textureUnit->EnvMode == GL_COMBINE4_NV) {
/* (a * b) + (c * d) */
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
const GLchan (*arg3)[4] = (const GLchan (*)[4]) argA[3];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] +
arg2[i][ACOMP] * arg3[i][ACOMP]) * Amult;
#else
const GLint shift = CHAN_BITS - Ashift;
GLint a = (PROD(arg0[i][ACOMP], arg1[i][ACOMP]) >> shift) +
(PROD(arg2[i][ACOMP], arg3[i][ACOMP]) >> shift);
rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
#endif
}
}
else {
/* two-term add */
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * Amult;
@ -587,7 +666,27 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
}
break;
case GL_ADD_SIGNED:
{
if (textureUnit->EnvMode == GL_COMBINE4_NV) {
/* (a * b) + (c * d) - 0.5 */
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
const GLchan (*arg3)[4] = (const GLchan (*)[4]) argA[3];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] +
arg2[i][ACOMP] * arg3[i][ACOMP] -
0.5) * Amult;
#else
GLint a = (((PROD(arg0[i][ACOMP], arg1[i][ACOMP]) +
PROD(arg2[i][ACOMP], arg3[i][ACOMP])) >> CHAN_BITS) - half)
<< Ashift;
rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
#endif
}
}
else {
/* a + b - 0.5 */
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
for (i = 0; i < n; i++) {
@ -596,7 +695,7 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
#else
GLint a = (GLint) arg0[i][ACOMP] + (GLint) arg1[i][ACOMP] -half;
a = (a < 0) ? 0 : a << Ashift;
rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
#endif
}
}

View File

@ -1070,7 +1070,8 @@ _swrast_choose_triangle( GLcontext *ctx )
&& minFilter == magFilter
&& ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
&& !swrast->_FogEnabled
&& ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) {
&& ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT
&& ctx->Texture.Unit[0].EnvMode != GL_COMBINE4_NV) {
if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) {
if (minFilter == GL_NEAREST
&& format == MESA_FORMAT_RGB