From c6532875493ffe7de9c37924c70ebf6d0472e23d Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Sat, 17 Mar 2012 10:48:23 +0800 Subject: [PATCH] i915: set SPRITE_POINT_ENABLE bit correctly When SPRITE_POINT_ENABLE bit is set, the texture coord would be replaced, and this is only needed when we called something like glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE). And more, we currently handle varying inputs as texture coord, we would be careful when setting this bit and set it just when needed, or you will find the value of varying input is not right and changed. Thus we do set SPRITE_POINT_ENABLE bit only when all enabled tex coord units need do CoordReplace. Or fallback is needed to make sure the rendering is right. With handling the bit setup at i915_update_sprite_point_enable(), we don't need the relative code at i915Enable then. This patch would _really_ fix the webglc point-size.html test case and of course, not regress piglit point-sprite and glean-pointSprite testcase. NOTE: This is a candidate for stable release branches. v2: fallback just when all enabled tex coord units need do CoordReplace (Eric) v3: move the sprite point validate code at I915InvalidateState (Eric) v4: sprite point enable bit update based on _NEW_PROGRAM, too add relative _NEW-state comments to show what state is being used(Eric) Signed-off-by: Yuanhan Liu --- src/mesa/drivers/dri/i915/i915_context.c | 2 + src/mesa/drivers/dri/i915/i915_context.h | 2 + src/mesa/drivers/dri/i915/i915_state.c | 55 ++++++++++++++++++------ src/mesa/drivers/dri/i915/intel_tris.c | 1 + 4 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index 36563ef6f3f..dc322929fbd 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -76,6 +76,8 @@ i915InvalidateState(struct gl_context * ctx, GLuint new_state) i915_update_provoking_vertex(ctx); if (new_state & (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)) i915_update_program(ctx); + if (new_state & (_NEW_PROGRAM | _NEW_POINT)) + i915_update_sprite_point_enable(ctx); } diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h index 81671371151..70374658ec8 100644 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -40,6 +40,7 @@ #define I915_FALLBACK_POINT_SMOOTH 0x80000 #define I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN 0x100000 #define I915_FALLBACK_DRAW_OFFSET 0x200000 +#define I915_FALLBACK_COORD_REPLACE 0x400000 #define I915_UPLOAD_CTX 0x1 #define I915_UPLOAD_BUFFERS 0x2 @@ -338,6 +339,7 @@ extern void i915InitStateFunctions(struct dd_function_table *functions); extern void i915InitState(struct i915_context *i915); extern void i915_update_stencil(struct gl_context * ctx); extern void i915_update_provoking_vertex(struct gl_context *ctx); +extern void i915_update_sprite_point_enable(struct gl_context *ctx); /*====================================================================== diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 756001ff6e6..94c7327830b 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -652,6 +652,48 @@ i915PointParameterfv(struct gl_context * ctx, GLenum pname, const GLfloat *param } } +void +i915_update_sprite_point_enable(struct gl_context *ctx) +{ + struct intel_context *intel = intel_context(ctx); + /* _NEW_PROGRAM */ + struct i915_fragment_program *p = + (struct i915_fragment_program *) ctx->FragmentProgram._Current; + const GLbitfield64 inputsRead = p->FragProg.Base.InputsRead; + struct i915_context *i915 = i915_context(ctx); + GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; + int i; + GLuint coord_replace_bits = 0x0; + GLuint tex_coord_unit_bits = 0x0; + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + /* _NEW_POINT */ + if (ctx->Point.CoordReplace[i] && ctx->Point.PointSprite) + coord_replace_bits |= (1 << i); + if (inputsRead & FRAG_BIT_TEX(i)) + tex_coord_unit_bits |= (1 << i); + } + + /* + * Here we can't enable the SPRITE_POINT_ENABLE bit when the mis-match + * of tex_coord_unit_bits and coord_replace_bits, or this will make all + * the other non-point-sprite coords(like varying inputs, as we now use + * tex coord to implement varying inputs) be replaced to value (0, 0)-(1, 1). + * + * Thus, do fallback when needed. + */ + FALLBACK(intel, I915_FALLBACK_COORD_REPLACE, + coord_replace_bits && coord_replace_bits != tex_coord_unit_bits); + + s4 &= ~S4_SPRITE_POINT_ENABLE; + s4 |= (coord_replace_bits && coord_replace_bits == tex_coord_unit_bits) ? + S4_SPRITE_POINT_ENABLE : 0; + if (s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { + i915->state.Ctx[I915_CTXREG_LIS4] = s4; + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + } +} + /* ============================================================= * Color masks @@ -869,18 +911,7 @@ i915Enable(struct gl_context * ctx, GLenum cap, GLboolean state) 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. - */ - dw = i915->state.Ctx[I915_CTXREG_LIS4]; - if (state) - dw |= S4_SPRITE_POINT_ENABLE; - else - dw &= ~S4_SPRITE_POINT_ENABLE; - if (dw != i915->state.Ctx[I915_CTXREG_LIS4]) { - i915->state.Ctx[I915_CTXREG_LIS4] = dw; - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - } + /* Handle it at i915_update_sprite_point_enable () */ break; case GL_POINT_SMOOTH: diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index c802d7231d0..cf67d743004 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -1188,6 +1188,7 @@ static char *fallbackStrings[] = { [19] = "Smooth point", [20] = "point sprite coord origin", [21] = "depth/color drawing offset", + [22] = "coord replace(SPRITE POINT ENABLE)", }; -- 2.30.2