aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/extras/Mesa/src/mesa/drivers/dri/i915/i915_texprog.c
diff options
context:
space:
mode:
authorReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
committerReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
commitf4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch)
tree2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/extras/Mesa/src/mesa/drivers/dri/i915/i915_texprog.c
parenta840692edc9c6d19cd7c057f68e39c7d95eb767d (diff)
downloadnx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.gz
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.bz2
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.zip
Imported nx-X11-3.1.0-1.tar.gznx-X11/3.1.0-1
Summary: Imported nx-X11-3.1.0-1.tar.gz Keywords: Imported nx-X11-3.1.0-1.tar.gz into Git repository
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/dri/i915/i915_texprog.c')
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/dri/i915/i915_texprog.c668
1 files changed, 668 insertions, 0 deletions
diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i915/i915_texprog.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i915/i915_texprog.c
new file mode 100644
index 000000000..3eaf53d7d
--- /dev/null
+++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i915/i915_texprog.c
@@ -0,0 +1,668 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <strings.h>
+
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+
+#include "tnl/t_context.h"
+#include "intel_batchbuffer.h"
+
+#include "i915_reg.h"
+#include "i915_context.h"
+#include "i915_program.h"
+
+static GLuint translate_tex_src_bit( struct i915_fragment_program *p,
+ GLubyte bit )
+{
+ switch (bit) {
+ case TEXTURE_1D_BIT: return D0_SAMPLE_TYPE_2D;
+ case TEXTURE_2D_BIT: return D0_SAMPLE_TYPE_2D;
+ case TEXTURE_RECT_BIT: return D0_SAMPLE_TYPE_2D;
+ case TEXTURE_3D_BIT: return D0_SAMPLE_TYPE_VOLUME;
+ case TEXTURE_CUBE_BIT: return D0_SAMPLE_TYPE_CUBE;
+ default: i915_program_error(p, "TexSrcBit"); return 0;
+ }
+}
+
+static GLuint get_source( struct i915_fragment_program *p,
+ GLenum src, GLuint unit )
+{
+ switch (src) {
+ case GL_TEXTURE:
+ if (p->src_texture == UREG_BAD) {
+
+ /* TODO: Use D0_CHANNEL_XY where possible.
+ */
+ GLuint dim = translate_tex_src_bit( p, p->ctx->Texture.Unit[unit]._ReallyEnabled);
+ GLuint sampler = i915_emit_decl(p, REG_TYPE_S, unit, dim);
+ GLuint texcoord = i915_emit_decl(p, REG_TYPE_T, unit, D0_CHANNEL_ALL);
+ GLuint tmp = i915_get_temp( p );
+ GLuint op = T0_TEXLD;
+
+ if (p->VB->TexCoordPtr[unit]->size == 4)
+ op = T0_TEXLDP;
+
+ p->src_texture = i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL,
+ sampler, texcoord, op );
+ }
+
+ return p->src_texture;
+
+ /* Crossbar: */
+ case GL_TEXTURE0:
+ case GL_TEXTURE1:
+ case GL_TEXTURE2:
+ case GL_TEXTURE3:
+ case GL_TEXTURE4:
+ case GL_TEXTURE5:
+ case GL_TEXTURE6:
+ case GL_TEXTURE7: {
+ return UREG_BAD;
+ }
+
+ case GL_CONSTANT:
+ return i915_emit_const4fv( p, p->ctx->Texture.Unit[unit].EnvColor );
+ case GL_PRIMARY_COLOR:
+ return i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL);
+ case GL_PREVIOUS:
+ default:
+ i915_emit_decl(p,
+ GET_UREG_TYPE(p->src_previous),
+ GET_UREG_NR(p->src_previous), D0_CHANNEL_ALL);
+ return p->src_previous;
+ }
+}
+
+
+static GLuint emit_combine_source( struct i915_fragment_program *p,
+ GLuint mask,
+ GLuint unit,
+ GLenum source,
+ GLenum operand )
+{
+ GLuint arg, src;
+
+ src = get_source(p, source, unit);
+
+ switch (operand) {
+ case GL_ONE_MINUS_SRC_COLOR:
+ /* Get unused tmp,
+ * Emit tmp = 1.0 + arg.-x-y-z-w
+ */
+ arg = i915_get_temp( p );
+ return i915_emit_arith( p, A0_ADD, arg, mask, 0,
+ swizzle(src, ONE, ONE, ONE, ONE ),
+ negate(src, 1,1,1,1), 0);
+
+ case GL_SRC_ALPHA:
+ if (mask == A0_DEST_CHANNEL_W)
+ return src;
+ else
+ return swizzle( src, W, W, W, W );
+ case GL_ONE_MINUS_SRC_ALPHA:
+ /* Get unused tmp,
+ * Emit tmp = 1.0 + arg.-w-w-w-w
+ */
+ arg = i915_get_temp( p );
+ return i915_emit_arith( p, A0_ADD, arg, mask, 0,
+ swizzle(src, ONE, ONE, ONE, ONE ),
+ negate( swizzle(src,W,W,W,W), 1,1,1,1), 0);
+ case GL_SRC_COLOR:
+ default:
+ return src;
+ }
+}
+
+
+
+static int nr_args( GLenum mode )
+{
+ switch (mode) {
+ case GL_REPLACE: return 1;
+ case GL_MODULATE: return 2;
+ case GL_ADD: return 2;
+ case GL_ADD_SIGNED: return 2;
+ case GL_INTERPOLATE: return 3;
+ case GL_SUBTRACT: return 2;
+ case GL_DOT3_RGB_EXT: return 2;
+ case GL_DOT3_RGBA_EXT: return 2;
+ case GL_DOT3_RGB: return 2;
+ case GL_DOT3_RGBA: return 2;
+ default: return 0;
+ }
+}
+
+
+static GLboolean args_match( struct gl_texture_unit *texUnit )
+{
+ int i, nr = nr_args(texUnit->Combine.ModeRGB);
+
+ for (i = 0 ; i < nr ; i++) {
+ if (texUnit->Combine.SourceA[i] != texUnit->Combine.SourceRGB[i])
+ return GL_FALSE;
+
+ switch(texUnit->Combine.OperandA[i]) {
+ case GL_SRC_ALPHA:
+ switch(texUnit->Combine.OperandRGB[i]) {
+ case GL_SRC_COLOR:
+ case GL_SRC_ALPHA:
+ break;
+ default:
+ return GL_FALSE;
+ }
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ switch(texUnit->Combine.OperandRGB[i]) {
+ case GL_ONE_MINUS_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ break;
+ default:
+ return GL_FALSE;
+ }
+ break;
+ default:
+ return GL_FALSE; /* impossible */
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+static GLuint emit_combine( struct i915_fragment_program *p,
+ GLuint dest,
+ GLuint mask,
+ GLuint saturate,
+ GLuint unit,
+ GLenum mode,
+ const GLenum *source,
+ const GLenum *operand)
+{
+ int tmp, src[3], nr = nr_args(mode);
+ int i;
+
+ for (i = 0; i < nr; i++)
+ src[i] = emit_combine_source( p, mask, unit, source[i], operand[i] );
+
+ switch (mode) {
+ case GL_REPLACE:
+ if (mask == A0_DEST_CHANNEL_ALL && !saturate)
+ return src[0];
+ else
+ return i915_emit_arith( p, A0_MOV, dest, mask, saturate, src[0], 0, 0 );
+ case GL_MODULATE:
+ return i915_emit_arith( p, A0_MUL, dest, mask, saturate,
+ src[0], src[1], 0 );
+ case GL_ADD:
+ return i915_emit_arith( p, A0_ADD, dest, mask, saturate,
+ src[0], src[1], 0 );
+ case GL_ADD_SIGNED:
+ /* tmp = arg0 + arg1
+ * result = tmp + -.5
+ */
+ tmp = i915_emit_const1f(p, .5);
+ tmp = negate(swizzle(tmp,X,X,X,X),1,1,1,1);
+ i915_emit_arith( p, A0_ADD, dest, mask, 0, src[0], src[1], 0 );
+ i915_emit_arith( p, A0_ADD, dest, mask, saturate, dest, tmp, 0 );
+ return dest;
+ case GL_INTERPOLATE: /* TWO INSTRUCTIONS */
+ /* Arg0 * (Arg2) + Arg1 * (1-Arg2)
+ *
+ * Arg0*Arg2 + Arg1 - Arg1Arg2
+ *
+ * tmp = Arg0*Arg2 + Arg1,
+ * result = (-Arg1)Arg2 + tmp
+ */
+ tmp = i915_get_temp( p );
+ i915_emit_arith( p, A0_MAD, tmp, mask, 0, src[0], src[2], src[1] );
+ i915_emit_arith( p, A0_MAD, dest, mask, saturate,
+ negate(src[1], 1,1,1,1), src[2], tmp );
+ return dest;
+ case GL_SUBTRACT:
+ /* negate src[1] */
+ return i915_emit_arith( p, A0_ADD, dest, mask, saturate, src[0],
+ negate(src[1],1,1,1,1), 0 );
+
+ case GL_DOT3_RGBA:
+ case GL_DOT3_RGBA_EXT:
+ case GL_DOT3_RGB_EXT:
+ case GL_DOT3_RGB: {
+ GLuint tmp0 = i915_get_temp( p );
+ GLuint tmp1 = i915_get_temp( p );
+ GLuint neg1 = negate(swizzle(i915_emit_const1f(p, 1),X,X,X,X), 1,1,1,1);
+ GLuint two = swizzle(i915_emit_const1f(p, 2),X,X,X,X);
+ i915_emit_arith( p, A0_MAD, tmp0, A0_DEST_CHANNEL_ALL, 0,
+ two, src[0], neg1);
+ if (src[0] == src[1])
+ tmp1 = tmp0;
+ else
+ i915_emit_arith( p, A0_MAD, tmp1, A0_DEST_CHANNEL_ALL, 0,
+ two, src[1], neg1);
+ i915_emit_arith( p, A0_DP3, dest, mask, saturate, tmp0, tmp1, 0);
+ return dest;
+ }
+
+ default:
+ return src[0];
+ }
+}
+
+static GLuint get_dest( struct i915_fragment_program *p, int unit )
+{
+ if (p->ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+ return i915_get_temp( p );
+ else if (unit != p->last_tex_stage)
+ return i915_get_temp( p );
+ else
+ return UREG(REG_TYPE_OC, 0);
+}
+
+
+
+static GLuint emit_texenv( struct i915_fragment_program *p, int unit )
+{
+ struct gl_texture_unit *texUnit = &p->ctx->Texture.Unit[unit];
+ GLenum envMode = texUnit->EnvMode;
+ struct gl_texture_object *tObj = texUnit->_Current;
+ GLenum format = tObj->Image[0][tObj->BaseLevel]->Format;
+ GLuint saturate = unit < p->last_tex_stage ? A0_DEST_SATURATE : 0;
+
+ switch(envMode) {
+ case GL_BLEND: {
+ const int cf = get_source(p, GL_PREVIOUS, unit);
+ const int cc = get_source(p, GL_CONSTANT, unit);
+ const int cs = get_source(p, GL_TEXTURE, unit);
+ const int out = get_dest(p, unit);
+
+ if (format == GL_INTENSITY) {
+ /* cv = cf(1 - cs) + cc.cs
+ * cv = cf - cf.cs + cc.cs
+ */
+ /* u[2] = MAD( -cf * cs + cf )
+ * cv = MAD( cc * cs + u[2] )
+ */
+
+ i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0,
+ negate(cf,1,1,1,1), cs, cf );
+
+ i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
+ cc, cs, out );
+
+ return out;
+ } else {
+ /* cv = cf(1 - cs) + cc.cs
+ * cv = cf - cf.cs + cc.cs
+ * av = af.as
+ */
+ /* u[2] = MAD( cf.-x-y-zw * cs.xyzw + cf.xyz0 )
+ * oC = MAD( cc.xyz0 * cs.xyz0 + u[2].xyzw )
+ */
+ i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0,
+ negate(cf,1,1,1,0),
+ cs,
+ swizzle(cf,X,Y,Z,ZERO) );
+
+
+ i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
+ swizzle(cc,X,Y,Z,ZERO),
+ swizzle(cs,X,Y,Z,ZERO),
+ out );
+
+ return out;
+ }
+ }
+
+ case GL_DECAL: {
+ if (format == GL_RGB ||
+ format == GL_RGBA) {
+ int cf = get_source( p, GL_PREVIOUS, unit );
+ int cs = get_source( p, GL_TEXTURE, unit );
+ int out = get_dest(p, unit);
+
+ /* cv = cf(1-as) + cs.as
+ * cv = cf.(-as) + cf + cs.as
+ * av = af
+ */
+
+ /* u[2] = mad( cf.xyzw * cs.-w-w-w1 + cf.xyz0 )
+ * oc = mad( cs.xyz0 * cs.www0 + u[2].xyzw )
+ */
+ i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0,
+ cf,
+ negate(swizzle(cs,W,W,W,ONE),1,1,1,0),
+ swizzle(cf,X,Y,Z,ZERO) );
+
+ i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
+ swizzle(cs,X,Y,Z,ZERO),
+ swizzle(cs,W,W,W,ZERO),
+ out );
+ return out;
+ }
+ else {
+ return get_source( p, GL_PREVIOUS, unit );
+ }
+ }
+
+ case GL_REPLACE: {
+ const int cs = get_source( p, GL_TEXTURE, unit ); /* saturated */
+ switch (format) {
+ case GL_ALPHA: {
+ const int cf = get_source( p, GL_PREVIOUS, unit ); /* saturated */
+ i915_emit_arith( p, A0_MOV, cs, A0_DEST_CHANNEL_XYZ, 0, cf, 0, 0 );
+ return cs;
+ }
+ case GL_RGB:
+ case GL_LUMINANCE: {
+ const int cf = get_source( p, GL_PREVIOUS, unit ); /* saturated */
+ i915_emit_arith( p, A0_MOV, cs, A0_DEST_CHANNEL_W, 0, cf, 0, 0 );
+ return cs;
+ }
+ default:
+ return cs;
+ }
+ }
+
+ case GL_MODULATE: {
+ const int cf = get_source( p, GL_PREVIOUS, unit );
+ const int cs = get_source( p, GL_TEXTURE, unit );
+ const int out = get_dest(p, unit);
+ switch (format) {
+ case GL_ALPHA:
+ i915_emit_arith( p, A0_MUL, out, A0_DEST_CHANNEL_ALL, saturate,
+ swizzle(cs, ONE, ONE, ONE, W), cf, 0 );
+ break;
+ default:
+ i915_emit_arith( p, A0_MUL, out, A0_DEST_CHANNEL_ALL, saturate,
+ cs, cf, 0 );
+ break;
+ }
+ return out;
+ }
+ case GL_ADD: {
+ int cf = get_source( p, GL_PREVIOUS, unit );
+ int cs = get_source( p, GL_TEXTURE, unit );
+ const int out = get_dest( p, unit );
+
+ if (format == GL_INTENSITY) {
+ /* output-color.rgba = add( incoming, u[1] )
+ */
+ i915_emit_arith( p, A0_ADD, out, A0_DEST_CHANNEL_ALL, saturate,
+ cs, cf, 0 );
+ return out;
+ }
+ else {
+ /* cv.xyz = cf.xyz + cs.xyz
+ * cv.w = cf.w * cs.w
+ *
+ * cv.xyzw = MAD( cf.111w * cs.xyzw + cf.xyz0 )
+ */
+ i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
+ swizzle(cf,ONE,ONE,ONE,W),
+ cs,
+ swizzle(cf,X,Y,Z,ZERO) );
+ return out;
+ }
+ break;
+ }
+ case GL_COMBINE: {
+ GLuint rgb_shift, alpha_shift, out, shift;
+ GLuint dest = get_dest(p, unit);
+
+ /* The EXT version of the DOT3 extension does not support the
+ * scale factor, but the ARB version (and the version in OpenGL
+ * 1.3) does.
+ */
+ switch (texUnit->Combine.ModeRGB) {
+ case GL_DOT3_RGB_EXT:
+ alpha_shift = texUnit->Combine.ScaleShiftA;
+ rgb_shift = 0;
+ break;
+
+ case GL_DOT3_RGBA_EXT:
+ alpha_shift = 0;
+ rgb_shift = 0;
+ break;
+
+ default:
+ rgb_shift = texUnit->Combine.ScaleShiftRGB;
+ alpha_shift = texUnit->Combine.ScaleShiftA;
+ break;
+ }
+
+
+ /* Emit the RGB and A combine ops
+ */
+ if (texUnit->Combine.ModeRGB == texUnit->Combine.ModeA &&
+ args_match( texUnit )) {
+ out = emit_combine( p, dest, A0_DEST_CHANNEL_ALL, saturate,
+ unit,
+ texUnit->Combine.ModeRGB,
+ texUnit->Combine.SourceRGB,
+ texUnit->Combine.OperandRGB );
+ }
+ else if (texUnit->Combine.ModeRGB == GL_DOT3_RGBA_EXT ||
+ texUnit->Combine.ModeRGB == GL_DOT3_RGBA) {
+
+ out = emit_combine( p, dest, A0_DEST_CHANNEL_ALL, saturate,
+ unit,
+ texUnit->Combine.ModeRGB,
+ texUnit->Combine.SourceRGB,
+ texUnit->Combine.OperandRGB );
+ }
+ else {
+ /* Need to do something to stop from re-emitting identical
+ * argument calculations here:
+ */
+ out = emit_combine( p, dest, A0_DEST_CHANNEL_XYZ, saturate,
+ unit,
+ texUnit->Combine.ModeRGB,
+ texUnit->Combine.SourceRGB,
+ texUnit->Combine.OperandRGB );
+ out = emit_combine( p, dest, A0_DEST_CHANNEL_W, saturate,
+ unit,
+ texUnit->Combine.ModeA,
+ texUnit->Combine.SourceA,
+ texUnit->Combine.OperandA );
+ }
+
+ /* Deal with the final shift:
+ */
+ if (alpha_shift || rgb_shift) {
+ if (rgb_shift == alpha_shift) {
+ shift = i915_emit_const1f(p, 1<<rgb_shift);
+ shift = swizzle(shift,X,X,X,X);
+ }
+ else {
+ shift = i915_emit_const2f(p, 1<<rgb_shift, 1<<alpha_shift);
+ shift = swizzle(shift,X,X,X,Y);
+ }
+ return i915_emit_arith( p, A0_MUL, dest, A0_DEST_CHANNEL_ALL,
+ saturate, out, shift, 0 );
+ }
+
+ return out;
+ }
+
+ default:
+ return get_source(p, GL_PREVIOUS, 0);
+ }
+}
+
+static void emit_program_fini( struct i915_fragment_program *p )
+{
+ int cf = get_source( p, GL_PREVIOUS, 0 );
+ int out = UREG( REG_TYPE_OC, 0 );
+
+ if (p->ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
+ /* Emit specular add.
+ */
+ GLuint s = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_ALL);
+ i915_emit_arith( p, A0_ADD, out, A0_DEST_CHANNEL_ALL, 0, cf,
+ swizzle(s, X,Y,Z,ZERO), 0 );
+ }
+ else if (cf != out) {
+ /* Will wind up in here if no texture enabled or a couple of
+ * other scenarios (GL_REPLACE for instance).
+ */
+ i915_emit_arith( p, A0_MOV, out, A0_DEST_CHANNEL_ALL, 0, cf, 0, 0 );
+ }
+}
+
+
+static void i915EmitTextureProgram( i915ContextPtr i915 )
+{
+ GLcontext *ctx = &i915->intel.ctx;
+ struct i915_fragment_program *p = &i915->tex_program;
+ GLuint unit;
+
+ if (0) fprintf(stderr, "%s\n", __FUNCTION__);
+
+ i915_init_program( i915, p );
+
+ if (ctx->Texture._EnabledUnits) {
+ for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++)
+ if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ p->last_tex_stage = unit;
+ }
+
+ for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++)
+ if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ p->src_previous = emit_texenv( p, unit );
+ p->src_texture = UREG_BAD;
+ p->temp_flag = 0xffff000;
+ p->temp_flag |= 1 << GET_UREG_NR(p->src_previous);
+ }
+ }
+
+ emit_program_fini( p );
+
+ i915_fini_program( p );
+ i915_upload_program( i915, p );
+
+ p->translated = 1;
+}
+
+
+void i915ValidateTextureProgram( i915ContextPtr i915 )
+{
+ intelContextPtr intel = &i915->intel;
+ GLcontext *ctx = &intel->ctx;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ GLuint index = tnl->render_inputs;
+ int i, offset;
+ GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK;
+ GLuint s2 = S2_TEXCOORD_NONE;
+
+ /* Important:
+ */
+ VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
+ intel->vertex_attr_count = 0;
+ intel->coloroffset = 0;
+ intel->specoffset = 0;
+ offset = 0;
+
+ if (i915->vertex_fog == I915_FOG_PIXEL) {
+ EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16 );
+ index &= ~_TNL_BIT_FOG;
+ }
+ else if (index & _TNL_BITS_TEX_ANY) {
+ EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16 );
+ }
+ else {
+ EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12 );
+ }
+
+ /* How undefined is undefined? */
+ if (index & _TNL_BIT_POINTSIZE) {
+ EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, S4_VFMT_POINT_WIDTH, 4 );
+ }
+
+ intel->coloroffset = offset / 4;
+ EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4 );
+
+ if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
+ if (index & _TNL_BIT_COLOR1) {
+ intel->specoffset = offset / 4;
+ EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3 );
+ } else
+ EMIT_PAD( 3 );
+
+ if (index & _TNL_BIT_FOG)
+ EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1 );
+ else
+ EMIT_PAD( 1 );
+ }
+
+ if (index & _TNL_BITS_TEX_ANY) {
+ for (i = 0; i < 8; i++) {
+ if (index & _TNL_BIT_TEX(i)) {
+ int sz = VB->TexCoordPtr[i]->size;
+
+ s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
+ s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
+
+ EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_SZ(sz), 0, sz * 4 );
+ }
+ }
+ }
+
+ /* Only need to change the vertex emit code if there has been a
+ * statechange to a new hardware vertex format:
+ */
+ if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] ||
+ s4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
+
+ I915_STATECHANGE( i915, I915_UPLOAD_CTX );
+
+ i915->tex_program.translated = 0;
+
+ /* Must do this *after* statechange, so as not to affect
+ * buffered vertices reliant on the old state:
+ */
+ intel->vertex_size = _tnl_install_attrs( ctx,
+ intel->vertex_attrs,
+ intel->vertex_attr_count,
+ intel->ViewportMatrix.m, 0 );
+
+ intel->vertex_size >>= 2;
+
+ i915->state.Ctx[I915_CTXREG_LIS2] = s2;
+ i915->state.Ctx[I915_CTXREG_LIS4] = s4;
+
+ assert(intel->vtbl.check_vertex_size( intel, intel->vertex_size ));
+ }
+
+ if (!i915->tex_program.translated ||
+ i915->last_ReallyEnabled != ctx->Texture._EnabledUnits) {
+ i915EmitTextureProgram( i915 );
+ i915->last_ReallyEnabled = ctx->Texture._EnabledUnits;
+ }
+}