X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi915%2Fi915_state.c;h=c814f8d532e7a47f44cdda83f1cd798ac48e5673;hb=4fb2daf42c8171579cdc18605c5ceeb1963f8b31;hp=d6c3e90d96248a344c9f4e52f4d913c71b46ce19;hpb=41b58954e1742493452b91d9ecdb761db5de3bed;p=mesa.git diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index d6c3e90d962..91b228d52b9 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -3,152 +3,181 @@ * 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 "glheader.h" -#include "context.h" -#include "macros.h" -#include "enums.h" -#include "dd.h" +#include "main/glheader.h" +#include "main/context.h" +#include "main/macros.h" +#include "main/enums.h" +#include "main/dd.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "texmem.h" +#include "drivers/common/driverfuncs.h" + +#include "intel_fbo.h" #include "intel_screen.h" #include "intel_batchbuffer.h" +#include "intel_buffers.h" #include "i915_context.h" #include "i915_reg.h" -static int translate_compare_func( GLenum func ) -{ - switch(func) { - case GL_NEVER: - return COMPAREFUNC_NEVER; - case GL_LESS: - return COMPAREFUNC_LESS; - case GL_LEQUAL: - return COMPAREFUNC_LEQUAL; - case GL_GREATER: - return COMPAREFUNC_GREATER; - case GL_GEQUAL: - return COMPAREFUNC_GEQUAL; - case GL_NOTEQUAL: - return COMPAREFUNC_NOTEQUAL; - case GL_EQUAL: - return COMPAREFUNC_EQUAL; - case GL_ALWAYS: - default: - return COMPAREFUNC_ALWAYS; - } -} - +#define FILE_DEBUG_FLAG DEBUG_STATE -static void i915StencilFunc(GLcontext *ctx, GLenum func, GLint ref, - GLuint mask) +void +i915_update_stencil(GLcontext * ctx) { - i915ContextPtr i915 = I915_CONTEXT(ctx); - int test = translate_compare_func( func ); + struct i915_context *i915 = I915_CONTEXT(ctx); + GLuint front_ref, front_writemask, front_mask; + GLenum front_func, front_fail, front_pass_z_fail, front_pass_z_pass; + GLuint back_ref, back_writemask, back_mask; + GLenum back_func, back_fail, back_pass_z_fail, back_pass_z_pass; - mask = mask & 0xff; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(func), ref, mask); + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + /* The 915 considers CW to be "front" for two-sided stencil, so choose + * appropriately. + */ + /* _NEW_POLYGON | _NEW_STENCIL */ + if (ctx->Polygon.FrontFace == GL_CW) { + front_ref = ctx->Stencil.Ref[0]; + front_mask = ctx->Stencil.ValueMask[0]; + front_writemask = ctx->Stencil.WriteMask[0]; + front_func = ctx->Stencil.Function[0]; + front_fail = ctx->Stencil.FailFunc[0]; + front_pass_z_fail = ctx->Stencil.ZFailFunc[0]; + front_pass_z_pass = ctx->Stencil.ZPassFunc[0]; + back_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace]; + back_mask = ctx->Stencil.ValueMask[ctx->Stencil._BackFace]; + back_writemask = ctx->Stencil.WriteMask[ctx->Stencil._BackFace]; + back_func = ctx->Stencil.Function[ctx->Stencil._BackFace]; + back_fail = ctx->Stencil.FailFunc[ctx->Stencil._BackFace]; + back_pass_z_fail = ctx->Stencil.ZFailFunc[ctx->Stencil._BackFace]; + back_pass_z_pass = ctx->Stencil.ZPassFunc[ctx->Stencil._BackFace]; + } else { + front_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace]; + front_mask = ctx->Stencil.ValueMask[ctx->Stencil._BackFace]; + front_writemask = ctx->Stencil.WriteMask[ctx->Stencil._BackFace]; + front_func = ctx->Stencil.Function[ctx->Stencil._BackFace]; + front_fail = ctx->Stencil.FailFunc[ctx->Stencil._BackFace]; + front_pass_z_fail = ctx->Stencil.ZFailFunc[ctx->Stencil._BackFace]; + front_pass_z_pass = ctx->Stencil.ZPassFunc[ctx->Stencil._BackFace]; + back_ref = ctx->Stencil.Ref[0]; + back_mask = ctx->Stencil.ValueMask[0]; + back_writemask = ctx->Stencil.WriteMask[0]; + back_func = ctx->Stencil.Function[0]; + back_fail = ctx->Stencil.FailFunc[0]; + back_pass_z_fail = ctx->Stencil.ZFailFunc[0]; + back_pass_z_pass = ctx->Stencil.ZPassFunc[0]; + } - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + /* Set front state. */ + i915->state.Ctx[I915_CTXREG_STATE4] &= ~(MODE4_ENABLE_STENCIL_TEST_MASK | + MODE4_ENABLE_STENCIL_WRITE_MASK); i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(mask)); + ENABLE_STENCIL_WRITE_MASK | + STENCIL_TEST_MASK(front_mask) | + STENCIL_WRITE_MASK(front_writemask)); i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | - S5_STENCIL_TEST_FUNC_MASK); - - i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) | - (test << S5_STENCIL_TEST_FUNC_SHIFT)); + S5_STENCIL_TEST_FUNC_MASK | + S5_STENCIL_FAIL_MASK | + S5_STENCIL_PASS_Z_FAIL_MASK | + S5_STENCIL_PASS_Z_PASS_MASK); + + i915->state.Ctx[I915_CTXREG_LIS5] |= + (front_ref << S5_STENCIL_REF_SHIFT) | + (intel_translate_compare_func(front_func) << S5_STENCIL_TEST_FUNC_SHIFT) | + (intel_translate_stencil_op(front_fail) << S5_STENCIL_FAIL_SHIFT) | + (intel_translate_stencil_op(front_pass_z_fail) << + S5_STENCIL_PASS_Z_FAIL_SHIFT) | + (intel_translate_stencil_op(front_pass_z_pass) << + S5_STENCIL_PASS_Z_PASS_SHIFT); + + /* Set back state if different from front. */ + if (ctx->Stencil._TestTwoSide) { + i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] &= + ~(BFO_STENCIL_REF_MASK | + BFO_STENCIL_TEST_MASK | + BFO_STENCIL_FAIL_MASK | + BFO_STENCIL_PASS_Z_FAIL_MASK | + BFO_STENCIL_PASS_Z_PASS_MASK); + i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] |= BFO_STENCIL_TWO_SIDE | + (back_ref << BFO_STENCIL_REF_SHIFT) | + (intel_translate_compare_func(back_func) << BFO_STENCIL_TEST_SHIFT) | + (intel_translate_stencil_op(back_fail) << BFO_STENCIL_FAIL_SHIFT) | + (intel_translate_stencil_op(back_pass_z_fail) << + BFO_STENCIL_PASS_Z_FAIL_SHIFT) | + (intel_translate_stencil_op(back_pass_z_pass) << + BFO_STENCIL_PASS_Z_PASS_SHIFT); + + i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] &= + ~(BFM_STENCIL_TEST_MASK_MASK | + BFM_STENCIL_WRITE_MASK_MASK); + i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] |= + BFM_STENCIL_TEST_MASK(back_mask) | + BFM_STENCIL_WRITE_MASK(back_writemask); + } else { + i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] &= ~BFO_STENCIL_TWO_SIDE; + } } -static void i915StencilMask(GLcontext *ctx, GLuint mask) +static void +i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, + GLuint mask) { - i915ContextPtr i915 = I915_CONTEXT(ctx); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask); - - mask = mask & 0xff; - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(mask)); } -static int translate_stencil_op( GLenum op ) +static void +i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) { - switch(op) { - case GL_KEEP: - return STENCILOP_KEEP; - case GL_ZERO: - return STENCILOP_ZERO; - case GL_REPLACE: - return STENCILOP_REPLACE; - case GL_INCR: - return STENCILOP_INCRSAT; - case GL_DECR: - return STENCILOP_DECRSAT; - case GL_INCR_WRAP: - return STENCILOP_INCR; - case GL_DECR_WRAP: - return STENCILOP_DECR; - case GL_INVERT: - return STENCILOP_INVERT; - default: - return 0; - } } -static void i915StencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, - GLenum zpass) +static void +i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, + GLenum zpass) { - i915ContextPtr i915 = I915_CONTEXT(ctx); - int fop = translate_stencil_op(fail); - int dfop = translate_stencil_op(zfail); - int dpop = translate_stencil_op(zpass); - - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(fail), - _mesa_lookup_enum_by_nr(zfail), - _mesa_lookup_enum_by_nr(zpass)); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | - S5_STENCIL_PASS_Z_FAIL_MASK | - S5_STENCIL_PASS_Z_PASS_MASK); - - i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) | - (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) | - (dpop << S5_STENCIL_PASS_Z_PASS_SHIFT)); } -static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +static void +i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) { - i915ContextPtr i915 = I915_CONTEXT(ctx); - int test = translate_compare_func( func ); + struct i915_context *i915 = I915_CONTEXT(ctx); + int test = intel_translate_compare_func(func); GLubyte refByte; UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | - S6_ALPHA_REF_MASK); + S6_ALPHA_REF_MASK); i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | - (((GLuint)refByte) << S6_ALPHA_REF_SHIFT)); + (((GLuint) refByte) << + S6_ALPHA_REF_SHIFT)); } /* This function makes sure that the proper enables are @@ -157,80 +186,47 @@ static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) * could change the LogicOp or Independant Alpha Blend without subsequent * calls to glEnable. */ -static void i915EvalLogicOpBlendState(GLcontext *ctx) +static void +i915EvalLogicOpBlendState(GLcontext * ctx) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (ctx->Color._LogicOpEnabled) { + if (RGBA_LOGICOP_ENABLED(ctx)) { i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE; i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; - } else { + } + else { i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE; if (ctx->Color.BlendEnabled) { - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; - } else { - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; + } + else { + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; } } } -static void i915BlendColor(GLcontext *ctx, const GLfloat color[4]) +static void +i915BlendColor(GLcontext * ctx, const GLfloat color[4]) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); GLubyte r, g, b, a; - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - + DBG("%s\n", __FUNCTION__); + UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = (a<<24) | (r<<16) | (g<<8) | b; + i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = + (a << 24) | (r << 16) | (g << 8) | b; } -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; - } -} #define DST_BLND_FACT(f) ((f)<state.Ctx[I915_CTXREG_IAB] & - ~(IAB_SRC_FACTOR_MASK | - IAB_DST_FACTOR_MASK | - (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | - IAB_ENABLE)); - - GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & - ~(S6_CBUF_SRC_BLEND_FACT_MASK | - S6_CBUF_DST_BLEND_FACT_MASK | - S6_CBUF_BLEND_FUNC_MASK)); + struct i915_context *i915 = I915_CONTEXT(ctx); + GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] & + ~(IAB_SRC_FACTOR_MASK | + IAB_DST_FACTOR_MASK | + (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE)); + + GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & + ~(S6_CBUF_SRC_BLEND_FACT_MASK | + S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK)); GLuint eqRGB = ctx->Color.BlendEquationRGB; GLuint eqA = ctx->Color.BlendEquationA; @@ -280,15 +282,15 @@ static void i915UpdateBlendState( GLcontext *ctx ) srcA = dstA = GL_ONE; } - lis6 |= SRC_BLND_FACT(translate_blend_factor(srcRGB)); - lis6 |= DST_BLND_FACT(translate_blend_factor(dstRGB)); - lis6 |= translate_blend_equation( eqRGB ) << S6_CBUF_BLEND_FUNC_SHIFT; + lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)); + lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB)); + lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT; - iab |= SRC_ABLND_FACT(translate_blend_factor(srcA)); - iab |= DST_ABLND_FACT(translate_blend_factor(dstA)); - iab |= translate_blend_equation( eqA ) << IAB_FUNC_SHIFT; + iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA)); + iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA)); + iab |= translate_blend_equation(eqA) << IAB_FUNC_SHIFT; - if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) + if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) iab |= IAB_ENABLE; if (iab != i915->state.Ctx[I915_CTXREG_IAB] || @@ -303,41 +305,41 @@ static void i915UpdateBlendState( GLcontext *ctx ) } -static void i915BlendFuncSeparate(GLcontext *ctx, GLenum srcRGB, - GLenum dstRGB, GLenum srcA, - GLenum dstA ) -{ - i915UpdateBlendState( ctx ); +static void +i915BlendFuncSeparate(GLcontext * ctx, GLenum srcRGB, + GLenum dstRGB, GLenum srcA, GLenum dstA) +{ + i915UpdateBlendState(ctx); } -static void i915BlendEquationSeparate(GLcontext *ctx, GLenum eqRGB, - GLenum eqA) +static void +i915BlendEquationSeparate(GLcontext * ctx, GLenum eqRGB, GLenum eqA) { - i915UpdateBlendState( ctx ); + i915UpdateBlendState(ctx); } -static void i915DepthFunc(GLcontext *ctx, GLenum func) +static void +i915DepthFunc(GLcontext * ctx, GLenum func) { - i915ContextPtr i915 = I915_CONTEXT(ctx); - int test = translate_compare_func( func ); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); + struct i915_context *i915 = I915_CONTEXT(ctx); + int test = intel_translate_compare_func(func); + DBG("%s\n", __FUNCTION__); + I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT; } -static void i915DepthMask(GLcontext *ctx, GLboolean flag) +static void +i915DepthMask(GLcontext * ctx, GLboolean flag) { - i915ContextPtr i915 = I915_CONTEXT(ctx); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag); + struct i915_context *i915 = I915_CONTEXT(ctx); + DBG("%s flag (%d)\n", __FUNCTION__, flag); + I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (flag && ctx->Depth.Test) @@ -346,20 +348,80 @@ static void i915DepthMask(GLcontext *ctx, GLboolean flag) i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE; } + + +/** + * Update the viewport transformation matrix. Depends on: + * - viewport pos/size + * - depthrange + * - window pos/size or FBO size + */ +void +intelCalcViewport(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; + GLfloat *m = intel->ViewportMatrix.m; + GLfloat yScale, yBias; + + if (ctx->DrawBuffer->Name) { + /* User created FBO */ + /* y=0=bottom */ + yScale = 1.0; + yBias = 0.0; + } + else { + /* window buffer, y=0=top */ + yScale = -1.0; + yBias = ctx->DrawBuffer->Height; + } + + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX]; + + m[MAT_SY] = v[MAT_SY] * yScale; + m[MAT_TY] = v[MAT_TY] * yScale + yBias; + + m[MAT_SZ] = v[MAT_SZ] * depthScale; + m[MAT_TZ] = v[MAT_TZ] * depthScale; +} + + +/** Called from ctx->Driver.Viewport() */ +static void +i915Viewport(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + intelCalcViewport(ctx); + + intel_viewport(ctx, x, y, width, height); +} + + +/** Called from ctx->Driver.DepthRange() */ +static void +i915DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) +{ + intelCalcViewport(ctx); +} + + /* ============================================================= * Polygon stipple * * The i915 supports a 4x4 stipple natively, GL wants 32x32. * Fortunately stipple is usually a repeating pattern. */ -static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask ) +static void +i915PolygonStipple(GLcontext * ctx, const GLubyte * mask) { - i915ContextPtr i915 = I915_CONTEXT(ctx); - const GLubyte *m = mask; + struct i915_context *i915 = I915_CONTEXT(ctx); + const GLubyte *m; GLubyte p[4]; - int i,j,k; + int i, j, k; int active = (ctx->Polygon.StippleFlag && - i915->intel.reduced_primitive == GL_TRIANGLES); + i915->intel.reduced_primitive == GL_TRIANGLES); GLuint newMask; if (active) { @@ -367,23 +429,32 @@ static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask ) i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; } - p[0] = mask[12] & 0xf; p[0] |= p[0] << 4; - p[1] = mask[8] & 0xf; p[1] |= p[1] << 4; - p[2] = mask[4] & 0xf; p[2] |= p[2] << 4; - p[3] = mask[0] & 0xf; p[3] |= p[3] << 4; - - for (k = 0 ; k < 8 ; k++) - for (j = 3 ; j >= 0; j--) - for (i = 0 ; i < 4 ; i++, m++) - if (*m != p[j]) { - i915->intel.hw_stipple = 0; - return; - } + /* Use the already unpacked stipple data from the context rather than the + * uninterpreted mask passed in. + */ + mask = (const GLubyte *)ctx->PolygonStipple; + m = mask; + + p[0] = mask[12] & 0xf; + p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; + p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; + p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; + p[3] |= p[3] << 4; + + for (k = 0; k < 8; k++) + for (j = 3; j >= 0; j--) + for (i = 0; i < 4; i++, m++) + if (*m != p[j]) { + i915->intel.hw_stipple = 0; + return; + } newMask = (((p[0] & 0xf) << 0) | - ((p[1] & 0xf) << 4) | - ((p[2] & 0xf) << 8) | - ((p[3] & 0xf) << 12)); + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); if (newMask == 0xffff || newMask == 0x0) { @@ -404,102 +475,54 @@ static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask ) /* ============================================================= * Hardware clipping */ -static void i915Scissor(GLcontext *ctx, GLint x, GLint y, - GLsizei w, GLsizei h) +static void +i915Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) { - i915ContextPtr i915 = I915_CONTEXT(ctx); - intelScreenPrivate *screen = i915->intel.intelScreen; + struct i915_context *i915 = I915_CONTEXT(ctx); int x1, y1, x2, y2; - if (!i915->intel.driDrawable) + if (!ctx->DrawBuffer) return; - x1 = x; - y1 = i915->intel.driDrawable->h - (y + h); - x2 = x + w - 1; - y2 = y1 + h - 1; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__, - x, y, w, h); - - if (x1 < 0) x1 = 0; - if (y1 < 0) y1 = 0; - if (x2 < 0) x2 = 0; - if (y2 < 0) y2 = 0; - - if (x2 >= screen->width) x2 = screen->width-1; - if (y2 >= screen->height) y2 = screen->height-1; - if (x1 >= screen->width) x1 = screen->width-1; - if (y1 >= screen->height) y1 = screen->height-1; + DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + if (ctx->DrawBuffer->Name == 0) { + x1 = x; + y1 = ctx->DrawBuffer->Height - (y + h); + x2 = x + w - 1; + y2 = y1 + h - 1; + DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + else { + /* FBO - not inverted + */ + x1 = x; + y1 = y; + x2 = x + w - 1; + y2 = y + h - 1; + DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + + x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); + y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); + x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); + y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); + + DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); } -static void i915LogicOp(GLcontext *ctx, GLenum opcode) +static void +i915LogicOp(GLcontext * ctx, GLenum opcode) { - i915ContextPtr i915 = I915_CONTEXT(ctx); - int tmp = 0; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - 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; - } + struct i915_context *i915 = I915_CONTEXT(ctx); + int tmp = intel_translate_logic_op(opcode); + DBG("%s\n", __FUNCTION__); + I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK; i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); @@ -507,13 +530,14 @@ static void i915LogicOp(GLcontext *ctx, GLenum opcode) -static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused) +static void +i915CullFaceFrontFace(GLcontext * ctx, GLenum unused) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); GLuint mode; - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); + DBG("%s %d\n", __FUNCTION__, + ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0); if (!ctx->Polygon.CullFlag) { mode = S4_CULLMODE_NONE; @@ -521,10 +545,12 @@ static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused) else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { mode = S4_CULLMODE_CW; + if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); if (ctx->Polygon.CullFaceMode == GL_FRONT) - mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); if (ctx->Polygon.FrontFace != GL_CCW) - mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); } else { mode = S4_CULLMODE_BOTH; @@ -535,17 +561,17 @@ static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused) i915->state.Ctx[I915_CTXREG_LIS4] |= mode; } -static void i915LineWidth( GLcontext *ctx, GLfloat widthf ) +static void +i915LineWidth(GLcontext * ctx, GLfloat widthf) { - i915ContextPtr i915 = I915_CONTEXT( ctx ); + struct i915_context *i915 = I915_CONTEXT(ctx); int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; int width; - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - width = (int)(widthf * 2); - CLAMP_SELF(width, 1, 0xf); + DBG("%s\n", __FUNCTION__); + + width = (int) (widthf * 2); + width = CLAMP(width, 1, 0xf); lis4 |= width << S4_LINE_WIDTH_SHIFT; if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { @@ -554,16 +580,16 @@ static void i915LineWidth( GLcontext *ctx, GLfloat widthf ) } } -static void i915PointSize(GLcontext *ctx, GLfloat size) +static void +i915PointSize(GLcontext * ctx, GLfloat size) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; - GLint point_size = (int)size; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); + GLint point_size = (int) round(size); - CLAMP_SELF(point_size, 1, 255); + DBG("%s\n", __FUNCTION__); + + point_size = CLAMP(point_size, 1, 255); lis4 |= point_size << S4_POINT_WIDTH_SHIFT; if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { @@ -573,24 +599,46 @@ static void i915PointSize(GLcontext *ctx, GLfloat size) } +static void +i915PointParameterfv(GLcontext * ctx, GLenum pname, const GLfloat *params) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (pname) { + case GL_POINT_SPRITE_COORD_ORIGIN: + /* This could be supported, but it would require modifying the fragment + * program to invert the y component of the texture coordinate by + * inserting a 'SUB tc.y, {1.0}.xxxx, tc' instruction. + */ + FALLBACK(&i915->intel, I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN, + (params[0] != GL_UPPER_LEFT)); + break; + } +} + + /* ============================================================= * Color masks */ -static void i915ColorMask(GLcontext *ctx, - GLboolean r, GLboolean g, - GLboolean b, GLboolean a) +static void +i915ColorMask(GLcontext * ctx, + GLboolean r, GLboolean g, GLboolean b, GLboolean a) { - i915ContextPtr i915 = I915_CONTEXT( ctx ); + struct i915_context *i915 = I915_CONTEXT(ctx); GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a); + DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, + a); - if (!r) tmp |= S5_WRITEDISABLE_RED; - if (!g) tmp |= S5_WRITEDISABLE_GREEN; - if (!b) tmp |= S5_WRITEDISABLE_BLUE; - if (!a) tmp |= S5_WRITEDISABLE_ALPHA; + if (!r) + tmp |= S5_WRITEDISABLE_RED; + if (!g) + tmp |= S5_WRITEDISABLE_GREEN; + if (!b) + tmp |= S5_WRITEDISABLE_BLUE; + if (!a) + tmp |= S5_WRITEDISABLE_ALPHA; if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) { I915_STATECHANGE(i915, I915_UPLOAD_CTX); @@ -598,170 +646,174 @@ static void i915ColorMask(GLcontext *ctx, } } -static void update_specular( GLcontext *ctx ) +static void +update_specular(GLcontext * ctx) { /* A hack to trigger the rebuild of the fragment program. */ - INTEL_CONTEXT(ctx)->NewGLState |= _NEW_TEXTURE; - I915_CONTEXT(ctx)->tex_program.translated = 0; + intel_context(ctx)->NewGLState |= _NEW_TEXTURE; } -static void i915LightModelfv(GLcontext *ctx, GLenum pname, - const GLfloat *param) +static void +i915LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param) { - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - + DBG("%s\n", __FUNCTION__); + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { - update_specular( ctx ); + update_specular(ctx); } } -static void i915ShadeModel(GLcontext *ctx, GLenum mode) +static void +i915ShadeModel(GLcontext * ctx, GLenum mode) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (mode == GL_SMOOTH) { - i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA | - S4_FLATSHADE_COLOR | - S4_FLATSHADE_SPECULAR); - } else { - i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA | - S4_FLATSHADE_COLOR | - S4_FLATSHADE_SPECULAR); + i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA | + S4_FLATSHADE_COLOR | + S4_FLATSHADE_SPECULAR); + } + else { + i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA | + S4_FLATSHADE_COLOR | + S4_FLATSHADE_SPECULAR); } } /* ============================================================= * Fog */ -static void update_fog( GLcontext *ctx ) +void +i915_update_fog(GLcontext * ctx) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); GLenum mode; GLboolean enabled; GLboolean try_pixel_fog; - - if (ctx->FragmentProgram.Enabled && ctx->FragmentProgram.Current) { + + if (ctx->FragmentProgram._Current) { /* Pull in static fog state from program */ - - mode = ctx->FragmentProgram.Current->FogOption; + mode = ctx->FragmentProgram._Current->FogOption; enabled = (mode != GL_NONE); - try_pixel_fog = 1; + try_pixel_fog = 0; } else { enabled = ctx->Fog.Enabled; mode = ctx->Fog.Mode; - - try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT && - ctx->Hint.Fog == GL_NICEST && - 0); /* XXX - DISABLE -- Need ortho fallback */ +#if 0 + /* XXX - DISABLED -- Need ortho fallback */ + try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT + && ctx->Hint.Fog == GL_NICEST); +#else + try_pixel_fog = 0; +#endif } if (!enabled) { i915->vertex_fog = I915_FOG_NONE; } else if (try_pixel_fog) { - I915_STATECHANGE(i915, I915_UPLOAD_FOG); i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; i915->vertex_fog = I915_FOG_PIXEL; - + switch (mode) { case GL_LINEAR: - if (ctx->Fog.End <= ctx->Fog.Start) { - /* XXX - this won't work with fragment programs. Need to - * either fallback or append fog instructions to end of - * program in the case of linear fog. - */ - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; - i915->vertex_fog = I915_FOG_VERTEX; - } - else { - GLfloat c1 = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start); - GLfloat c2 = 1.0/(ctx->Fog.End-ctx->Fog.Start); - - i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK; - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR; - i915->state.Fog[I915_FOGREG_MODE1] |= - ((GLuint)(c1 * FMC1_C1_ONE)) & FMC1_C1_MASK; - - if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { - i915->state.Fog[I915_FOGREG_MODE2] = (GLuint)(c2 * FMC2_C2_ONE); - } - else { - union { float f; int i; } fi; - fi.f = c2; - i915->state.Fog[I915_FOGREG_MODE2] = fi.i; - } - } - break; + if (ctx->Fog.End <= ctx->Fog.Start) { + /* XXX - this won't work with fragment programs. Need to + * either fallback or append fog instructions to end of + * program in the case of linear fog. + */ + printf("vertex fog!\n"); + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; + i915->vertex_fog = I915_FOG_VERTEX; + } + else { + GLfloat c2 = 1.0 / (ctx->Fog.End - ctx->Fog.Start); + GLfloat c1 = ctx->Fog.End * c2; + + i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK; + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR; + i915->state.Fog[I915_FOGREG_MODE1] |= + ((GLuint) (c1 * FMC1_C1_ONE)) & FMC1_C1_MASK; + + if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { + i915->state.Fog[I915_FOGREG_MODE2] + = (GLuint) (c2 * FMC2_C2_ONE); + } + else { + fi_type fi; + fi.f = c2; + i915->state.Fog[I915_FOGREG_MODE2] = fi.i; + } + } + break; case GL_EXP: - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP; - break; + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP; + break; case GL_EXP2: - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2; - break; + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2; + break; default: - break; + break; } } - else /* if (i915->vertex_fog != I915_FOG_VERTEX) */ { + else { /* if (i915->vertex_fog != I915_FOG_VERTEX) */ I915_STATECHANGE(i915, I915_UPLOAD_FOG); i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; i915->vertex_fog = I915_FOG_VERTEX; } - { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled); - if (enabled) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; - } + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled); + if (enabled) + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; - if (enabled) { - _tnl_allow_vertex_fog( ctx, (i915->vertex_fog == I915_FOG_VERTEX) ); - _tnl_allow_pixel_fog( ctx, (i915->vertex_fog != I915_FOG_VERTEX) ); - } + /* Always enable pixel fog. Vertex fog using fog coord will conflict + * with fog code appended onto fragment program. + */ + _tnl_allow_vertex_fog( ctx, 0 ); + _tnl_allow_pixel_fog( ctx, 1 ); } -static void i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) +static void +i915Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); switch (pname) { - case GL_FOG_COORDINATE_SOURCE_EXT: + case GL_FOG_COORDINATE_SOURCE_EXT: case GL_FOG_MODE: case GL_FOG_START: - case GL_FOG_END: - update_fog( ctx ); + case GL_FOG_END: break; case GL_FOG_DENSITY: I915_STATECHANGE(i915, I915_UPLOAD_FOG); if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { - i915->state.Fog[I915_FOGREG_MODE3] = (GLuint)(ctx->Fog.Density * - FMC3_D_ONE); + i915->state.Fog[I915_FOGREG_MODE3] = + (GLuint) (ctx->Fog.Density * FMC3_D_ONE); } else { - union { float f; int i; } fi; - fi.f = ctx->Fog.Density; - i915->state.Fog[I915_FOGREG_MODE3] = fi.i; + fi_type fi; + fi.f = ctx->Fog.Density; + i915->state.Fog[I915_FOGREG_MODE3] = fi.i; } break; - case GL_FOG_COLOR: + case GL_FOG_COLOR: I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_COLOR] = - (_3DSTATE_FOG_COLOR_CMD | - ((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) | - ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) | - ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0)); + i915->state.Fog[I915_FOGREG_COLOR] = + (_3DSTATE_FOG_COLOR_CMD | + ((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | + ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | + ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); break; default: @@ -769,11 +821,11 @@ static void i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) } } -static void i915Hint(GLcontext *ctx, GLenum target, GLenum state) +static void +i915Hint(GLcontext * ctx, GLenum target, GLenum state) { switch (target) { case GL_FOG_HINT: - update_fog( ctx ); break; default: break; @@ -783,25 +835,26 @@ static void i915Hint(GLcontext *ctx, GLenum target, GLenum state) /* ============================================================= */ -static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state) +static void +i915Enable(GLcontext * ctx, GLenum cap, GLboolean state) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); - switch(cap) { + switch (cap) { case GL_TEXTURE_2D: break; case GL_LIGHTING: case GL_COLOR_SUM: - update_specular( ctx ); + update_specular(ctx); break; case GL_ALPHA_TEST: I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (state) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE; else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE; break; case GL_BLEND: @@ -813,52 +866,50 @@ static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state) /* Logicop doesn't seem to work at 16bpp: */ - if (i915->intel.intelScreen->cpp == 2) - FALLBACK( &i915->intel, I915_FALLBACK_LOGICOP, state ); + if (ctx->Visual.rgbBits == 16) + FALLBACK(&i915->intel, I915_FALLBACK_LOGICOP, state); break; case GL_FRAGMENT_PROGRAM_ARB: - update_fog( ctx ); break; case GL_DITHER: I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (state) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE; break; case GL_DEPTH_TEST: I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (state) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE; else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE; - i915DepthMask( ctx, ctx->Depth.Mask ); + i915DepthMask(ctx, ctx->Depth.Mask); break; case GL_SCISSOR_TEST: I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); if (state) - i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | - ENABLE_SCISSOR_RECT); + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); else - i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | - DISABLE_SCISSOR_RECT); + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); break; case GL_LINE_SMOOTH: I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (state) - i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE; else - i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE; break; case GL_FOG: - update_fog( ctx ); break; case GL_CULL_FACE: @@ -866,16 +917,25 @@ static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state) break; case GL_STENCIL_TEST: - if (i915->intel.hw_stencil) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - } else { - FALLBACK( &i915->intel, I915_FALLBACK_STENCIL, state ); + { + GLboolean hw_stencil = GL_FALSE; + if (ctx->DrawBuffer) { + struct intel_renderbuffer *irbStencil + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); + hw_stencil = (irbStencil && irbStencil->region); + } + if (hw_stencil) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + else + i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + } + else { + FALLBACK(&i915->intel, I915_FALLBACK_STENCIL, state); + } } break; @@ -884,27 +944,42 @@ static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state) * I'll do more testing later to find out exactly which hardware * supports it. Disabled for now. */ - if (i915->intel.hw_stipple && - i915->intel.reduced_primitive == GL_TRIANGLES) - { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - if (state) - i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; - else - i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; + if (i915->intel.hw_stipple && + i915->intel.reduced_primitive == GL_TRIANGLES) { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + if (state) + i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; + else + i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; } break; + case GL_POLYGON_SMOOTH: + break; + + case GL_POINT_SPRITE: + /* This state change is handled in i915_reduced_primitive_state because + * the hardware bit should only be set when rendering points. + */ + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS4] |= S4_SPRITE_POINT_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_SPRITE_POINT_ENABLE; + break; + + case GL_POINT_SMOOTH: + break; + default: ; } } -static void i915_init_packets( i915ContextPtr i915 ) +static void +i915_init_packets(struct i915_context *i915) { - intelScreenPrivate *screen = i915->intel.intelScreen; - /* Zero all state */ memset(&i915->state, 0, sizeof(i915->state)); @@ -914,41 +989,48 @@ static void i915_init_packets( i915ContextPtr i915 ) /* Probably don't want to upload all this stuff every time one * piece changes. */ - i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | - I1_LOAD_S(2) | - I1_LOAD_S(4) | - I1_LOAD_S(5) | - I1_LOAD_S(6) | - (4)); + i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(2) | + I1_LOAD_S(4) | + I1_LOAD_S(5) | I1_LOAD_S(6) | (3)); i915->state.Ctx[I915_CTXREG_LIS2] = 0; i915->state.Ctx[I915_CTXREG_LIS4] = 0; i915->state.Ctx[I915_CTXREG_LIS5] = 0; - if (screen->cpp == 2) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; + if (i915->intel.ctx.Visual.rgbBits == 16) + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE | - (2 << S6_TRISTRIP_PV_SHIFT)); + (2 << S6_TRISTRIP_PV_SHIFT)); i915->state.Ctx[I915_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | - LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff) | - ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(0xff)); - - - i915->state.Ctx[I915_CTXREG_IAB] = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | - IAB_MODIFY_ENABLE | - IAB_MODIFY_FUNC | - IAB_MODIFY_SRC_FACTOR | - IAB_MODIFY_DST_FACTOR); - - i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD; + ENABLE_LOGIC_OP_FUNC | + LOGIC_OP_FUNC(LOGICOP_COPY) | + ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff) | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(0xff)); + + i915->state.Ctx[I915_CTXREG_IAB] = + (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | + IAB_MODIFY_FUNC | IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR); + + i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] = + _3DSTATE_CONST_BLEND_COLOR_CMD; i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0; + i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] = + _3DSTATE_BACKFACE_STENCIL_MASKS | + BFM_ENABLE_STENCIL_TEST_MASK | + BFM_ENABLE_STENCIL_WRITE_MASK | + (0xff << BFM_STENCIL_WRITE_MASK_SHIFT) | + (0xff << BFM_STENCIL_TEST_MASK_SHIFT); + i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] = + _3DSTATE_BACKFACE_STENCIL_OPS | + BFO_ENABLE_STENCIL_REF | + BFO_ENABLE_STENCIL_FUNCS | + BFO_ENABLE_STENCIL_TWO_SIDE; } { @@ -961,72 +1043,83 @@ static void i915_init_packets( i915ContextPtr i915 ) I915_STATECHANGE(i915, I915_UPLOAD_FOG); i915->state.Fog[I915_FOGREG_MODE0] = _3DSTATE_FOG_MODE_CMD; i915->state.Fog[I915_FOGREG_MODE1] = (FMC1_FOGFUNC_MODIFY_ENABLE | - FMC1_FOGFUNC_VERTEX | - FMC1_FOGINDEX_MODIFY_ENABLE | - FMC1_FOGINDEX_W | - FMC1_C1_C2_MODIFY_ENABLE | - FMC1_DENSITY_MODIFY_ENABLE); + FMC1_FOGFUNC_VERTEX | + FMC1_FOGINDEX_MODIFY_ENABLE | + FMC1_FOGINDEX_W | + FMC1_C1_C2_MODIFY_ENABLE | + FMC1_DENSITY_MODIFY_ENABLE); i915->state.Fog[I915_FOGREG_COLOR] = _3DSTATE_FOG_COLOR_CMD; } - { - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); - i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - i915->state.Buffer[I915_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(screen->frontPitch * screen->cpp) | - BUF_3D_USE_FENCE); - - - i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - i915->state.Buffer[I915_DESTREG_DBUFADDR1] = - (BUF_3D_ID_DEPTH | - BUF_3D_PITCH(screen->depthPitch * screen->cpp) | - BUF_3D_USE_FENCE); - i915->state.Buffer[I915_DESTREG_DBUFADDR2] = screen->depthOffset; - - i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; - switch (screen->fbFormat) { - case DV_PF_555: - case DV_PF_565: - i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - DITHER_FULL_ALWAYS | - screen->fbFormat | - DEPTH_FRMT_16_FIXED); - break; - case DV_PF_8888: - i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - screen->fbFormat | - DEPTH_FRMT_24_FIXED_8_OTHER); - break; - } - i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | - DISABLE_SCISSOR_RECT); + /* scissor */ + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; i915->state.Buffer[I915_DESTREG_SR1] = 0; i915->state.Buffer[I915_DESTREG_SR2] = 0; } + i915->state.RasterRules[I915_RASTER_RULES] = _3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D; + +#if 0 + { + I915_STATECHANGE(i915, I915_UPLOAD_DEFAULTS); + i915->state.Default[I915_DEFREG_C0] = _3DSTATE_DEFAULT_DIFFUSE; + i915->state.Default[I915_DEFREG_C1] = 0; + i915->state.Default[I915_DEFREG_S0] = _3DSTATE_DEFAULT_SPECULAR; + i915->state.Default[I915_DEFREG_S1] = 0; + i915->state.Default[I915_DEFREG_Z0] = _3DSTATE_DEFAULT_Z; + i915->state.Default[I915_DEFREG_Z1] = 0; + } +#endif + /* These will be emitted every at the head of every buffer, unless * we get hardware contexts working. */ - i915->state.active = (I915_UPLOAD_PROGRAM | - I915_UPLOAD_STIPPLE | - I915_UPLOAD_CTX | - I915_UPLOAD_BUFFERS); + i915->state.active = (I915_UPLOAD_PROGRAM | + I915_UPLOAD_STIPPLE | + I915_UPLOAD_CTX | + I915_UPLOAD_BUFFERS | + I915_UPLOAD_INVARIENT | + I915_UPLOAD_RASTER_RULES); +} + +void +i915_update_provoking_vertex(GLcontext * ctx) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_TRISTRIP_PV_MASK); + + I915_STATECHANGE(i915, I915_UPLOAD_RASTER_RULES); + i915->state.RasterRules[I915_RASTER_RULES] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK | + TRI_FAN_PROVOKE_VRTX_MASK); + + /* _NEW_LIGHT */ + if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) { + i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2)); + i915->state.Ctx[I915_CTXREG_LIS6] |= (2 << S6_TRISTRIP_PV_SHIFT); + } else { + i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(0) | + TRI_FAN_PROVOKE_VRTX(1)); + i915->state.Ctx[I915_CTXREG_LIS6] |= (0 << S6_TRISTRIP_PV_SHIFT); + } } -void i915InitStateFunctions( struct dd_function_table *functions ) +void +i915InitStateFunctions(struct dd_function_table *functions) { functions->AlphaFunc = i915AlphaFunc; functions->BlendColor = i915BlendColor; @@ -1044,30 +1137,24 @@ void i915InitStateFunctions( struct dd_function_table *functions ) functions->LineWidth = i915LineWidth; functions->LogicOpcode = i915LogicOp; functions->PointSize = i915PointSize; + functions->PointParameterfv = i915PointParameterfv; functions->PolygonStipple = i915PolygonStipple; functions->Scissor = i915Scissor; functions->ShadeModel = i915ShadeModel; - functions->StencilFunc = i915StencilFunc; - functions->StencilMask = i915StencilMask; - functions->StencilOp = i915StencilOp; + functions->StencilFuncSeparate = i915StencilFuncSeparate; + functions->StencilMaskSeparate = i915StencilMaskSeparate; + functions->StencilOpSeparate = i915StencilOpSeparate; + functions->DepthRange = i915DepthRange; + functions->Viewport = i915Viewport; } -void i915InitState( i915ContextPtr i915 ) +void +i915InitState(struct i915_context *i915) { GLcontext *ctx = &i915->intel.ctx; - i915_init_packets( i915 ); + i915_init_packets(i915); - intelInitState( ctx ); - - memcpy( &i915->initial, &i915->state, sizeof(i915->state) ); - i915->current = &i915->state; + _mesa_init_driver_state(ctx); } - - - - - - -