diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2004-06-10 12:48:07 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2004-06-10 12:48:07 +0000 |
commit | 41b58954e1742493452b91d9ecdb761db5de3bed (patch) | |
tree | f170cda67626d1a0d4e7e51ea502553b0f144077 /src/mesa/drivers/dri/i915/i830_texblend.c | |
parent | d7f76c7c8830882d849b42777ca601859ffac15a (diff) |
New driver for i915 as well as older i830/i845/i865 chipsets.
Diffstat (limited to 'src/mesa/drivers/dri/i915/i830_texblend.c')
-rw-r--r-- | src/mesa/drivers/dri/i915/i830_texblend.c | 1058 |
1 files changed, 1058 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i915/i830_texblend.c b/src/mesa/drivers/dri/i915/i830_texblend.c new file mode 100644 index 0000000000..e30b2dfd13 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i830_texblend.c @@ -0,0 +1,1058 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + **************************************************************************/ + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" +#include "texformat.h" +#include "texstore.h" + +#include "mm.h" + +#include "intel_screen.h" +#include "intel_ioctl.h" +#include "intel_tex.h" + +#include "i830_context.h" +#include "i830_reg.h" + + +/* ================================================================ + * Texture combine functions + */ +static GLuint pass_through( GLuint *state, GLuint blendUnit ) +{ + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + + return 4; +} + +static GLuint emit_factor( GLuint blendUnit, GLuint *state, GLuint count, + const GLfloat *factor ) +{ + GLubyte r, g, b, a; + GLuint col; + + if (0) + fprintf(stderr, "emit constant %d: %.2f %.2f %.2f %.2f\n", + blendUnit, factor[0], factor[1], factor[2], factor[3]); + + UNCLAMPED_FLOAT_TO_UBYTE(r, factor[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, factor[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, factor[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, factor[3]); + + col = ((a << 24) | (r << 16) | (g << 8) | b); + + state[count++] = _3DSTATE_COLOR_FACTOR_N_CMD(blendUnit); + state[count++] = col; + + return count; +} + + +static __inline__ GLuint GetTexelOp(GLint unit) +{ + switch(unit) { + case 0: return TEXBLENDARG_TEXEL0; + case 1: return TEXBLENDARG_TEXEL1; + case 2: return TEXBLENDARG_TEXEL2; + case 3: return TEXBLENDARG_TEXEL3; + default: return TEXBLENDARG_TEXEL0; + } +} + + +GLuint i830SetBlend_GL1_2(i830ContextPtr i830, int blendUnit, + GLenum envMode, GLenum format, GLuint texel_op, + GLuint *state, const GLfloat *factor) +{ + if(INTEL_DEBUG&DEBUG_TEXTURE) + fprintf(stderr, "%s %s %s texel_op(0x%x)\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(format), + _mesa_lookup_enum_by_nr(envMode), + texel_op); + + switch(envMode) { + case GL_REPLACE: + switch(format) { + case GL_ALPHA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + return 4; + + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return 4; + + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + return 4; + + default: + /* Always set to passthru if something is funny */ + return pass_through( state, blendUnit ); + } + + case GL_MODULATE: + switch(format) { + case GL_ALPHA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return 5; + + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return 5; + + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return 6; + + default: + /* Always set to passthru if something is funny */ + return pass_through( state, blendUnit ); + } + + case GL_DECAL: + switch(format) { + case GL_RGB: + case GL_YCBCR_MESA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return 4; + + case GL_RGBA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_BLEND); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_REPLICATE_ALPHA | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return 6; + default: + /* Always set to passthru if something is funny */ + return pass_through( state, blendUnit ); + } + + case GL_BLEND: + switch(format) { + case GL_ALPHA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return 5; + + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_BLEND); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_FACTOR_N); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return emit_factor( blendUnit, state, 6, factor ); + + case GL_INTENSITY: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_BLEND); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_BLEND); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_FACTOR_N); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[6] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_FACTOR_N); + state[7] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return emit_factor( blendUnit, state, 8, factor ); + + + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_BLEND); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_FACTOR_N); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[6] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return emit_factor( blendUnit, state, 7, factor ); + + default: + /* Always set to passthru if something is funny */ + return pass_through( state, blendUnit ); + } + + case GL_ADD: + switch(format) { + case GL_ALPHA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return 5; + + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ADD); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return 5; + + case GL_INTENSITY: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ADD); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ADD); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return 6; + + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ADD); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_MODULATE); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + texel_op); + state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + return 6; + + default: + /* Always set to passthru if something is funny */ + return pass_through( state, blendUnit ); + } + + default: + /* Always set to passthru if something is funny */ + return pass_through( state, blendUnit ); + } +} + +static GLuint i830SetTexEnvCombine(i830ContextPtr i830, + const struct gl_texture_unit *texUnit, + GLint blendUnit, + GLuint texel_op, + GLuint *state, + const GLfloat *factor ) +{ + GLuint blendop; + GLuint ablendop; + GLuint args_RGB[3]; + GLuint args_A[3]; + GLuint rgb_shift; + GLuint alpha_shift; + GLboolean need_factor = 0; + int i; + + if(INTEL_DEBUG&DEBUG_TEXTURE) + fprintf(stderr, "%s\n", __FUNCTION__); + + + /* 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; + } + + + switch(texUnit->Combine.ModeRGB) { + case GL_REPLACE: + blendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + blendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + blendop = TEXBLENDOP_ADD; + break; + case GL_ADD_SIGNED: + blendop = TEXBLENDOP_ADDSIGNED; + break; + case GL_INTERPOLATE: + blendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT: + blendop = TEXBLENDOP_SUBTRACT; + break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGB: + blendop = TEXBLENDOP_DOT3; + break; + case GL_DOT3_RGBA_EXT: + case GL_DOT3_RGBA: + blendop = TEXBLENDOP_DOT3; + break; + default: + return pass_through( state, blendUnit ); + } + + blendop |= (rgb_shift << TEXOP_SCALE_SHIFT); + + + /* Handle RGB args */ + for(i = 0; i < 3; i++) { + switch(texUnit->Combine.SourceRGB[i]) { + case GL_TEXTURE: + args_RGB[i] = texel_op; + break; + case GL_CONSTANT: + args_RGB[i] = TEXBLENDARG_FACTOR_N; + need_factor = 1; + break; + case GL_PRIMARY_COLOR: + args_RGB[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_RGB[i] = TEXBLENDARG_CURRENT; + break; + default: + return pass_through( state, blendUnit ); + } + + switch(texUnit->Combine.OperandRGB[i]) { + case GL_SRC_COLOR: + args_RGB[i] |= 0; + break; + case GL_ONE_MINUS_SRC_COLOR: + args_RGB[i] |= TEXBLENDARG_INV_ARG; + break; + case GL_SRC_ALPHA: + args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | + TEXBLENDARG_INV_ARG); + break; + default: + return pass_through( state, blendUnit ); + } + } + + + /* Need to knobble the alpha calculations of TEXBLENDOP_DOT4 to + * match the spec. Can't use DOT3 as it won't propogate values + * into alpha as required: + * + * Note - the global factor is set up with alpha == .5, so + * the alpha part of the DOT4 calculation should be zero. + */ + if ( texUnit->Combine.ModeRGB == GL_DOT3_RGBA_EXT || + texUnit->Combine.ModeRGB == GL_DOT3_RGBA ) { + ablendop = TEXBLENDOP_DOT4; + args_A[0] = TEXBLENDARG_FACTOR; /* the global factor */ + args_A[1] = TEXBLENDARG_FACTOR; + args_A[2] = TEXBLENDARG_FACTOR; + } + else { + switch(texUnit->Combine.ModeA) { + case GL_REPLACE: + ablendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + ablendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + ablendop = TEXBLENDOP_ADD; + break; + case GL_ADD_SIGNED: + ablendop = TEXBLENDOP_ADDSIGNED; + break; + case GL_INTERPOLATE: + ablendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT: + ablendop = TEXBLENDOP_SUBTRACT; + break; + default: + return pass_through( state, blendUnit ); + } + + + ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT); + + /* Handle A args */ + for(i = 0; i < 3; i++) { + switch(texUnit->Combine.SourceA[i]) { + case GL_TEXTURE: + args_A[i] = texel_op; + break; + case GL_CONSTANT: + args_A[i] = TEXBLENDARG_FACTOR_N; + need_factor = 1; + break; + case GL_PRIMARY_COLOR: + args_A[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_A[i] = TEXBLENDARG_CURRENT; + break; + default: + return pass_through( state, blendUnit ); + } + + switch(texUnit->Combine.OperandA[i]) { + case GL_SRC_ALPHA: + args_A[i] |= 0; + break; + case GL_ONE_MINUS_SRC_ALPHA: + args_A[i] |= TEXBLENDARG_INV_ARG; + break; + default: + return pass_through( state, blendUnit ); + } + } + } + + + + /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */ + /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */ + /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */ + + /* When we render we need to figure out which is the last really enabled + * tex unit, and put last stage on it + */ + + + /* Build color pipeline */ + + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_MODIFY_PARMS | + blendop); + state[1] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + args_RGB[0]); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + args_RGB[1]); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + args_RGB[2]); + + /* Build Alpha pipeline */ + state[4] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_MODIFY_PARMS | + ablendop); + state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + args_A[0]); + state[6] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + args_A[1]); + state[7] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG0 | + TEXBLENDARG_MODIFY_PARMS | + args_A[2]); + + + if (need_factor) + return emit_factor( blendUnit, state, 8, factor ); + else + return 8; +} + + +static void emit_texblend( i830ContextPtr i830, GLuint unit, GLuint blendUnit, + GLboolean last_stage ) +{ + struct gl_texture_unit *texUnit = &i830->intel.ctx.Texture.Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; + GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; + + + if (0) fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit); + + /* Update i830->state.TexBlend + */ + if (texUnit->EnvMode == GL_COMBINE) { + tmp_sz = i830SetTexEnvCombine(i830, texUnit, blendUnit, + GetTexelOp(unit), tmp, + texUnit->EnvColor ); + } + else { + tmp_sz = i830SetBlend_GL1_2(i830, blendUnit, texUnit->EnvMode, + t->intel.image[0][0].internalFormat, + GetTexelOp(unit), tmp, + texUnit->EnvColor ); + } + + if (last_stage) + tmp[0] |= TEXOP_LAST_STAGE; + + if (tmp_sz != i830->state.TexBlendWordsUsed[blendUnit] || + memcmp( tmp, i830->state.TexBlend[blendUnit], tmp_sz * sizeof(GLuint))) { + + I830_STATECHANGE( i830, I830_UPLOAD_TEXBLEND(blendUnit) ); + memcpy( i830->state.TexBlend[blendUnit], tmp, tmp_sz * sizeof(GLuint)); + i830->state.TexBlendWordsUsed[blendUnit] = tmp_sz; + } + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(blendUnit), GL_TRUE); +} + +static void emit_passthrough( i830ContextPtr i830 ) +{ + GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; + GLuint unit = 0; + + tmp_sz = pass_through( tmp, unit ); + tmp[0] |= TEXOP_LAST_STAGE; + + if (tmp_sz != i830->state.TexBlendWordsUsed[unit] || + memcmp( tmp, i830->state.TexBlend[unit], tmp_sz * sizeof(GLuint))) { + + I830_STATECHANGE( i830, I830_UPLOAD_TEXBLEND(unit) ); + memcpy( i830->state.TexBlend[unit], tmp, tmp_sz * sizeof(GLuint)); + i830->state.TexBlendWordsUsed[unit] = tmp_sz; + } + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(unit), GL_TRUE); +} + +void i830EmitTextureBlend( i830ContextPtr i830 ) +{ + GLcontext *ctx = &i830->intel.ctx; + GLuint unit, last_stage = 0, blendunit = 0; + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND_ALL, GL_FALSE); + + if (ctx->Texture._EnabledUnits) { + for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++) + if (ctx->Texture.Unit[unit]._ReallyEnabled) + last_stage = unit; + + for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++) + if (ctx->Texture.Unit[unit]._ReallyEnabled) + emit_texblend( i830, unit, blendunit++, last_stage == unit ); + } + else { + emit_passthrough( i830 ); + } +} + |