#include "i830_context.h"
#include "i830_reg.h"
-static void i830StencilFunc(GLcontext *ctx, GLenum func, GLint ref,
- GLuint mask)
+static void
+i830StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref,
+ GLuint mask)
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
- int test = 0;
+ int test = intel_translate_compare_func(func);
mask = mask & 0xff;
fprintf(stderr, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(func), ref, mask);
- switch(func) {
- case GL_NEVER:
- test = COMPAREFUNC_NEVER;
- break;
- case GL_LESS:
- test = COMPAREFUNC_LESS;
- break;
- case GL_LEQUAL:
- test = COMPAREFUNC_LEQUAL;
- break;
- case GL_GREATER:
- test = COMPAREFUNC_GREATER;
- break;
- case GL_GEQUAL:
- test = COMPAREFUNC_GEQUAL;
- break;
- case GL_NOTEQUAL:
- test = COMPAREFUNC_NOTEQUAL;
- break;
- case GL_EQUAL:
- test = COMPAREFUNC_EQUAL;
- break;
- case GL_ALWAYS:
- test = COMPAREFUNC_ALWAYS;
- break;
- default:
- return;
- }
I830_STATECHANGE(i830, I830_UPLOAD_CTX);
i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
STENCIL_TEST_FUNC(test));
}
-static void i830StencilMask(GLcontext *ctx, GLuint mask)
+static void
+i830StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
STENCIL_WRITE_MASK(mask));
}
-static void i830StencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
- GLenum zpass)
+static void
+i830StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail,
+ GLenum zpass)
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
int fop, dfop, dpop;
static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
- int test = 0;
+ int test = intel_translate_compare_func(func);
GLubyte refByte;
GLuint refInt;
UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref);
refInt = (GLuint)refByte;
- switch(func) {
- case GL_NEVER:
- test = COMPAREFUNC_NEVER;
- break;
- case GL_LESS:
- test = COMPAREFUNC_LESS;
- break;
- case GL_LEQUAL:
- test = COMPAREFUNC_LEQUAL;
- break;
- case GL_GREATER:
- test = COMPAREFUNC_GREATER;
- break;
- case GL_GEQUAL:
- test = COMPAREFUNC_GEQUAL;
- break;
- case GL_NOTEQUAL:
- test = COMPAREFUNC_NOTEQUAL;
- break;
- case GL_EQUAL:
- test = COMPAREFUNC_EQUAL;
- break;
- case GL_ALWAYS:
- test = COMPAREFUNC_ALWAYS;
- break;
- default:
- return;
- }
-
I830_STATECHANGE(i830, I830_UPLOAD_CTX);
i830->state.Ctx[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK;
i830->state.Ctx[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC |
ALPHA_REF_VALUE(refInt));
}
-/* This function makes sure that the proper enables are
- * set for LogicOp, Independant Alpha Blend, and Blending.
- * It needs to be called from numerous places where we
+/**
+ * Makes sure that the proper enables are set for LogicOp, Independant Alpha
+ * Blend, and Blending. It needs to be called from numerous places where we
* could change the LogicOp or Independant Alpha Blend without subsequent
* calls to glEnable.
+ *
+ * \todo
+ * This function is substantially different from the old i830-specific driver.
+ * I'm not sure which is correct.
*/
static void i830EvalLogicOpBlendState(GLcontext *ctx)
{
i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = (a<<24) | (r<<16) | (g<<8) | b;
}
-static void i830BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB,
- GLenum modeA)
+/**
+ * Sets both the blend equation (called "function" in i830 docs) and the
+ * blend function (called "factor" in i830 docs). This is done in a single
+ * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
+ * change the interpretation of the blend function.
+ */
+static void i830_set_blend_state( GLcontext * ctx )
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
- int func = ENABLE_ALPHA_BLENDFUNC;
+ int funcA;
+ int funcRGB;
+ int eqnA;
+ int eqnRGB;
+ int iab;
+ int s1;
- assert( modeRGB == modeA );
- if (INTEL_DEBUG&DEBUG_DRI)
- fprintf(stderr, "%s %s\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr(modeRGB));
+ funcRGB = SRC_BLND_FACT( intel_translate_blend_factor( ctx->Color.BlendSrcRGB ) )
+ | DST_BLND_FACT( intel_translate_blend_factor( ctx->Color.BlendDstRGB ) );
- /* This will catch a logicop blend equation */
- i830EvalLogicOpBlendState(ctx);
-
- switch(modeRGB) {
- case GL_FUNC_ADD:
- func |= BLENDFUNC_ADD;
+ switch(ctx->Color.BlendEquationRGB) {
+ case GL_FUNC_ADD:
+ eqnRGB = BLENDFUNC_ADD;
break;
- case GL_MIN:
- func |= BLENDFUNC_MIN;
+ case GL_MIN:
+ eqnRGB = BLENDFUNC_MIN;
+ funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
break;
case GL_MAX:
- func |= BLENDFUNC_MAX;
+ eqnRGB = BLENDFUNC_MAX;
+ funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
break;
case GL_FUNC_SUBTRACT:
- func |= BLENDFUNC_SUB;
+ eqnRGB = BLENDFUNC_SUB;
break;
- case GL_FUNC_REVERSE_SUBTRACT:
- func |= BLENDFUNC_RVRSE_SUB;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ eqnRGB = BLENDFUNC_RVRSE_SUB;
break;
- case GL_LOGIC_OP:
- default: return;
- }
-
- I830_STATECHANGE(i830, I830_UPLOAD_CTX);
- i830->state.Ctx[I830_CTXREG_STATE1] &= ~BLENDFUNC_MASK;
- i830->state.Ctx[I830_CTXREG_STATE1] |= func;
-}
-
-
-
-static int translate_blend_factor( GLenum factor )
-{
- switch(factor) {
- case GL_ZERO:
- return BLENDFACT_ZERO;
- case GL_SRC_ALPHA:
- return BLENDFACT_SRC_ALPHA;
- case GL_ONE:
- return BLENDFACT_ONE;
- case GL_SRC_COLOR:
- return BLENDFACT_SRC_COLR;
- case GL_ONE_MINUS_SRC_COLOR:
- return BLENDFACT_INV_SRC_COLR;
- case GL_DST_COLOR:
- return BLENDFACT_DST_COLR;
- case GL_ONE_MINUS_DST_COLOR:
- return BLENDFACT_INV_DST_COLR;
- case GL_ONE_MINUS_SRC_ALPHA:
- return BLENDFACT_INV_SRC_ALPHA;
- case GL_DST_ALPHA:
- return BLENDFACT_DST_ALPHA;
- case GL_ONE_MINUS_DST_ALPHA:
- return BLENDFACT_INV_DST_ALPHA;
- case GL_SRC_ALPHA_SATURATE:
- return BLENDFACT_SRC_ALPHA_SATURATE;
- case GL_CONSTANT_COLOR:
- return BLENDFACT_CONST_COLOR;
- case GL_ONE_MINUS_CONSTANT_COLOR:
- return BLENDFACT_INV_CONST_COLOR;
- case GL_CONSTANT_ALPHA:
- return BLENDFACT_CONST_ALPHA;
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- return BLENDFACT_INV_CONST_ALPHA;
default:
- return BLENDFACT_ZERO;
+ fprintf( stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
+ __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB );
+ return;
}
-}
-
-static void i830BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB,
- GLenum dfactorRGB, GLenum sfactorA,
- GLenum dfactorA )
-{
- i830ContextPtr i830 = I830_CONTEXT(ctx);
- int iab = i830->state.Ctx[I830_CTXREG_IALPHAB];
- int s1 = i830->state.Ctx[I830_CTXREG_STATE1];
-
- if (INTEL_DEBUG&DEBUG_DRI)
- fprintf(stderr, "%s\n", __FUNCTION__);
- iab &= ~(SRC_DST_ABLEND_MASK|ENABLE_INDPT_ALPHA_BLEND);
- s1 &= ~SRC_DST_BLND_MASK;
-
- iab |= (ENABLE_SRC_ABLEND_FACTOR|ENABLE_DST_ABLEND_FACTOR);
- s1 |= (ENABLE_SRC_BLND_FACTOR|ENABLE_DST_BLND_FACTOR);
+ funcA = SRC_ABLEND_FACT( intel_translate_blend_factor( ctx->Color.BlendSrcA ) )
+ | DST_ABLEND_FACT( intel_translate_blend_factor( ctx->Color.BlendDstA ) );
- if (ctx->Color.BlendEquationRGB == GL_MIN ||
- ctx->Color.BlendEquationRGB == GL_MAX) {
- sfactorA = sfactorRGB = dfactorA = dfactorRGB = GL_ONE;
+ switch(ctx->Color.BlendEquationA) {
+ case GL_FUNC_ADD:
+ eqnA = BLENDFUNC_ADD;
+ break;
+ case GL_MIN:
+ eqnA = BLENDFUNC_MIN;
+ funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
+ break;
+ case GL_MAX:
+ eqnA = BLENDFUNC_MAX;
+ funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
+ break;
+ case GL_FUNC_SUBTRACT:
+ eqnA = BLENDFUNC_SUB;
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ eqnA = BLENDFUNC_RVRSE_SUB;
+ break;
+ default:
+ fprintf( stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n",
+ __FUNCTION__, __LINE__, ctx->Color.BlendEquationA );
+ return;
}
- iab |= SRC_ABLEND_FACT(translate_blend_factor(sfactorA));
- iab |= DST_ABLEND_FACT(translate_blend_factor(dfactorA));
- s1 |= SRC_BLND_FACT(translate_blend_factor(sfactorRGB));
- s1 |= DST_BLND_FACT(translate_blend_factor(dfactorRGB));
+ iab = eqnA | funcA
+ | _3DSTATE_INDPT_ALPHA_BLEND_CMD
+ | ENABLE_SRC_ABLEND_FACTOR | ENABLE_DST_ABLEND_FACTOR
+ | ENABLE_ALPHA_BLENDFUNC;
+ s1 = eqnRGB | funcRGB
+ | _3DSTATE_MODES_1_CMD
+ | ENABLE_SRC_BLND_FACTOR | ENABLE_DST_BLND_FACTOR
+ | ENABLE_COLR_BLND_FUNC;
- if (sfactorA != sfactorRGB || dfactorA != dfactorRGB)
+ if ( (eqnA | funcA) != (eqnRGB | funcRGB) )
iab |= ENABLE_INDPT_ALPHA_BLEND;
else
iab |= DISABLE_INDPT_ALPHA_BLEND;
i830->state.Ctx[I830_CTXREG_IALPHAB] = iab;
i830->state.Ctx[I830_CTXREG_STATE1] = s1;
}
+
+ /* This will catch a logicop blend equation. It will also ensure
+ * independant alpha blend is really in the correct state (either enabled
+ * or disabled) if blending is already enabled.
+ */
+
+ i830EvalLogicOpBlendState(ctx);
+
+ if (0) {
+ fprintf(stderr, "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n",
+ __FUNCTION__, __LINE__,
+ i830->state.Ctx[I830_CTXREG_STATE1],
+ i830->state.Ctx[I830_CTXREG_IALPHAB],
+ (ctx->Color.BlendEnabled) ? "en" : "dis");
+ }
+}
+
+
+static void i830BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB,
+ GLenum modeA)
+{
+ if (INTEL_DEBUG&DEBUG_DRI)
+ fprintf(stderr, "%s -> %s, %s\n", __FUNCTION__,
+ _mesa_lookup_enum_by_nr(modeRGB),
+ _mesa_lookup_enum_by_nr(modeA));
+
+ (void) modeRGB;
+ (void) modeA;
+ i830_set_blend_state( ctx );
+}
+
+
+static void i830BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB,
+ GLenum dfactorRGB, GLenum sfactorA,
+ GLenum dfactorA )
+{
+ if (INTEL_DEBUG&DEBUG_DRI)
+ fprintf(stderr, "%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__,
+ _mesa_lookup_enum_by_nr(sfactorRGB),
+ _mesa_lookup_enum_by_nr(dfactorRGB),
+ _mesa_lookup_enum_by_nr(sfactorA),
+ _mesa_lookup_enum_by_nr(dfactorA));
+
+ (void) sfactorRGB;
+ (void) dfactorRGB;
+ (void) sfactorA;
+ (void) dfactorA;
+ i830_set_blend_state( ctx );
}
static void i830DepthFunc(GLcontext *ctx, GLenum func)
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
- int test = 0;
+ int test = intel_translate_compare_func(func);
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
- switch(func) {
- case GL_NEVER:
- test = COMPAREFUNC_NEVER;
- break;
- case GL_LESS:
- test = COMPAREFUNC_LESS;
- break;
- case GL_LEQUAL:
- test = COMPAREFUNC_LEQUAL;
- break;
- case GL_GREATER:
- test = COMPAREFUNC_GREATER;
- break;
- case GL_GEQUAL:
- test = COMPAREFUNC_GEQUAL;
- break;
- case GL_NOTEQUAL:
- test = COMPAREFUNC_NOTEQUAL;
- break;
- case GL_EQUAL:
- test = COMPAREFUNC_EQUAL;
- break;
- case GL_ALWAYS:
- test = COMPAREFUNC_ALWAYS;
- break;
- default: return;
- }
-
I830_STATECHANGE(i830, I830_UPLOAD_CTX);
i830->state.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK;
i830->state.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC |
static void i830LogicOp(GLcontext *ctx, GLenum opcode)
{
i830ContextPtr i830 = I830_CONTEXT(ctx);
- int tmp = 0;
+ int tmp = intel_translate_logic_op( opcode );
if (INTEL_DEBUG&DEBUG_DRI)
fprintf(stderr, "%s\n", __FUNCTION__);
- /* FIXME: This should be a look-up table, like the r200 driver. */
- switch(opcode) {
- case GL_CLEAR:
- tmp = LOGICOP_CLEAR;
- break;
- case GL_AND:
- tmp = LOGICOP_AND;
- break;
- case GL_AND_REVERSE:
- tmp = LOGICOP_AND_RVRSE;
- break;
- case GL_COPY:
- tmp = LOGICOP_COPY;
- break;
- case GL_COPY_INVERTED:
- tmp = LOGICOP_COPY_INV;
- break;
- case GL_AND_INVERTED:
- tmp = LOGICOP_AND_INV;
- break;
- case GL_NOOP:
- tmp = LOGICOP_NOOP;
- break;
- case GL_XOR:
- tmp = LOGICOP_XOR;
- break;
- case GL_OR:
- tmp = LOGICOP_OR;
- break;
- case GL_OR_INVERTED:
- tmp = LOGICOP_OR_INV;
- break;
- case GL_NOR:
- tmp = LOGICOP_NOR;
- break;
- case GL_EQUIV:
- tmp = LOGICOP_EQUIV;
- break;
- case GL_INVERT:
- tmp = LOGICOP_INV;
- break;
- case GL_OR_REVERSE:
- tmp = LOGICOP_OR_RVRSE;
- break;
- case GL_NAND:
- tmp = LOGICOP_NAND;
- break;
- case GL_SET:
- tmp = LOGICOP_SET;
- break;
- default:
- return;
- }
-
I830_STATECHANGE(i830, I830_UPLOAD_CTX);
i830->state.Ctx[I830_CTXREG_STATE4] &= ~LOGICOP_MASK;
i830->state.Ctx[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp);
i830->state.Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
i830->state.Buffer[I830_DESTREG_CBUFADDR1] =
(BUF_3D_ID_COLOR_BACK |
- BUF_3D_PITCH(screen->frontPitch * screen->cpp) |
+ BUF_3D_PITCH(screen->front.pitch * screen->cpp) |
BUF_3D_USE_FENCE);
i830->state.Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
i830->state.Buffer[I830_DESTREG_DBUFADDR1] =
(BUF_3D_ID_DEPTH |
- BUF_3D_PITCH(screen->depthPitch * screen->cpp) |
+ BUF_3D_PITCH(screen->depth.pitch * screen->cpp) |
BUF_3D_USE_FENCE);
- i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depthOffset;
+ i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depth.offset;
i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
functions->PolygonStipple = i830PolygonStipple;
functions->Scissor = i830Scissor;
functions->ShadeModel = i830ShadeModel;
- functions->StencilFunc = i830StencilFunc;
- functions->StencilMask = i830StencilMask;
- functions->StencilOp = i830StencilOp;
+ functions->StencilFuncSeparate = i830StencilFuncSeparate;
+ functions->StencilMaskSeparate = i830StencilMaskSeparate;
+ functions->StencilOpSeparate = i830StencilOpSeparate;
}
void i830InitState( i830ContextPtr i830 )