diff options
author | Alan Hourihane <alanh@tungstengraphics.com> | 2008-12-08 14:29:50 +0000 |
---|---|---|
committer | Alan Hourihane <alanh@tungstengraphics.com> | 2008-12-08 14:29:50 +0000 |
commit | 33a1f495d4bb19288680b9812c6ec1235302d215 (patch) | |
tree | d47067fe24d530c660b75ee80cdcec72f10d9ed0 /src/mesa | |
parent | bcd5dda4358a5e47551278477bd00d2c63415c44 (diff) | |
parent | bdc8ac4426f00eaafbe8ca0d356563efe390294d (diff) |
Merge commit 'origin/master' into gallium-0.2
Conflicts:
progs/glsl/Makefile
Diffstat (limited to 'src/mesa')
24 files changed, 811 insertions, 702 deletions
diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c index 467abe4d7c..410052b3c2 100644 --- a/src/mesa/drivers/dri/i915/intel_render.c +++ b/src/mesa/drivers/dri/i915/intel_render.c @@ -117,6 +117,26 @@ intelDmaPrimitive(struct intel_context *intel, GLenum prim) intel_set_prim(intel, hw_prim[prim]); } +static inline GLuint intel_get_vb_max(struct intel_context *intel) +{ + GLuint ret; + + if (intel->intelScreen->no_vbo) + ret = intel->batch->size - 1500; + else + ret = INTEL_VB_SIZE; + ret /= (intel->vertex_size * 4); + return ret; +} + +static inline GLuint intel_get_current_max(struct intel_context *intel) +{ + + if (intel->intelScreen->no_vbo) + return intel_get_vb_max(intel); + else + return (INTEL_VB_SIZE - intel->prim.current_offset) / (intel->vertex_size * 4); +} #define LOCAL_VARS struct intel_context *intel = intel_context(ctx) #define INIT( prim ) \ @@ -126,9 +146,8 @@ do { \ #define FLUSH() INTEL_FIREVERTICES(intel) -#define GET_SUBSEQUENT_VB_MAX_VERTS() (INTEL_VB_SIZE / (intel->vertex_size * 4)) -#define GET_CURRENT_VB_MAX_VERTS() \ - ((INTEL_VB_SIZE - intel->prim.current_offset) / (intel->vertex_size * 4)) +#define GET_SUBSEQUENT_VB_MAX_VERTS() intel_get_vb_max(intel) +#define GET_CURRENT_VB_MAX_VERTS() intel_get_current_max(intel) #define ALLOC_VERTS(nr) intel_get_prim_space(intel, nr) diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index 797d6c5858..c4708dc7ab 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -61,9 +61,101 @@ static void intelRenderPrimitive(GLcontext * ctx, GLenum prim); static void intelRasterPrimitive(GLcontext * ctx, GLenum rprim, GLuint hwprim); +static void +intel_flush_inline_primitive(struct intel_context *intel) +{ + GLuint used = intel->batch->ptr - intel->prim.start_ptr; + + assert(intel->prim.primitive != ~0); + +/* _mesa_printf("/\n"); */ + + if (used < 8) + goto do_discard; + + *(int *) intel->prim.start_ptr = (_3DPRIMITIVE | + intel->prim.primitive | (used / 4 - 2)); + + goto finished; + + do_discard: + intel->batch->ptr -= used; + + finished: + intel->prim.primitive = ~0; + intel->prim.start_ptr = 0; + intel->prim.flush = 0; +} + +static void intel_start_inline(struct intel_context *intel, uint32_t prim) +{ + BATCH_LOCALS; + uint32_t batch_flags = LOOP_CLIPRECTS; + + intel_wait_flips(intel); + intel->vtbl.emit_state(intel); + + intel->no_batch_wrap = GL_TRUE; + + /*_mesa_printf("%s *", __progname);*/ + + /* Emit a slot which will be filled with the inline primitive + * command later. + */ + BEGIN_BATCH(2, batch_flags); + OUT_BATCH(0); + + assert((intel->batch->dirty_state & (1<<1)) == 0); + + intel->prim.start_ptr = intel->batch->ptr; + intel->prim.primitive = prim; + intel->prim.flush = intel_flush_inline_primitive; + + OUT_BATCH(0); + ADVANCE_BATCH(); + + intel->no_batch_wrap = GL_FALSE; +/* _mesa_printf(">"); */ +} + +static void intel_wrap_inline(struct intel_context *intel) +{ + GLuint prim = intel->prim.primitive; + + intel_flush_inline_primitive(intel); + intel_batchbuffer_flush(intel->batch); + intel_start_inline(intel, prim); /* ??? */ +} + +static GLuint *intel_extend_inline(struct intel_context *intel, GLuint dwords) +{ + GLuint sz = dwords * sizeof(GLuint); + GLuint *ptr; + + assert(intel->prim.flush == intel_flush_inline_primitive); + + if (intel_batchbuffer_space(intel->batch) < sz) + intel_wrap_inline(intel); + +/* _mesa_printf("."); */ + + intel->vtbl.assert_not_dirty(intel); + + ptr = (GLuint *) intel->batch->ptr; + intel->batch->ptr += sz; + + return ptr; +} + /** Sets the primitive type for a primitive sequence, flushing as needed. */ void intel_set_prim(struct intel_context *intel, uint32_t prim) { + /* if we have no VBOs */ + + if (intel->intelScreen->no_vbo) { + intel_start_inline(intel, prim); + return; + } if (prim != intel->prim.primitive) { INTEL_FIREVERTICES(intel); intel->prim.primitive = prim; @@ -75,6 +167,10 @@ uint32_t *intel_get_prim_space(struct intel_context *intel, unsigned int count) { uint32_t *addr; + if (intel->intelScreen->no_vbo) { + return intel_extend_inline(intel, count * intel->vertex_size); + } + /* Check for space in the existing VB */ if (intel->prim.vb_bo == NULL || (intel->prim.current_offset + @@ -155,7 +251,7 @@ void intel_flush_prim(struct intel_context *intel) #if 0 printf("emitting %d..%d=%d vertices size %d\n", offset, - intel->prim.current_offset, intel->prim.count, + intel->prim.current_offset, count, intel->vertex_size * 4); #endif diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index e3904be977..77980109cd 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -133,16 +133,16 @@ struct brw_context; #define BRW_NEW_PSP 0x800 #define BRW_NEW_METAOPS 0x1000 #define BRW_NEW_FENCE 0x2000 -#define BRW_NEW_LOCK 0x4000 -#define BRW_NEW_INDICES 0x8000 -#define BRW_NEW_VERTICES 0x10000 +#define BRW_NEW_INDICES 0x4000 +#define BRW_NEW_VERTICES 0x8000 /** * Used for any batch entry with a relocated pointer that will be used * by any 3D rendering. */ -#define BRW_NEW_BATCH 0x8000 +#define BRW_NEW_BATCH 0x10000 /** brw->depth_region updated */ -#define BRW_NEW_DEPTH_BUFFER 0x10000 +#define BRW_NEW_DEPTH_BUFFER 0x20000 +#define BRW_NEW_NR_SURFACES 0x40000 struct brw_state_flags { /** State update flags signalled by mesa internals */ @@ -158,7 +158,6 @@ struct brw_state_flags { struct brw_vertex_program { struct gl_vertex_program program; GLuint id; - GLuint param_state; /* flags indicating state tracked by params */ }; @@ -166,7 +165,6 @@ struct brw_vertex_program { struct brw_fragment_program { struct gl_fragment_program program; GLuint id; - GLuint param_state; /* flags indicating state tracked by params */ }; diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index c7bac7b0c5..fbf473abf6 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -184,8 +184,8 @@ static void prepare_constant_buffer(struct brw_context *brw) * function will also be called whenever fp or vp changes. */ brw->curbe.tracked_state.dirty.mesa = (_NEW_TRANSFORM|_NEW_PROJECTION); - brw->curbe.tracked_state.dirty.mesa |= vp->param_state; - brw->curbe.tracked_state.dirty.mesa |= fp->param_state; + brw->curbe.tracked_state.dirty.mesa |= vp->program.Base.Parameters->StateFlags; + brw->curbe.tracked_state.dirty.mesa |= fp->program.Base.Parameters->StateFlags; if (sz == 0) { diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index f893dd6742..c3a26fc82e 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -49,7 +49,7 @@ #define FILE_DEBUG_FLAG DEBUG_BATCH -static GLuint hw_prim[GL_POLYGON+1] = { +static GLuint prim_to_hw_prim[GL_POLYGON+1] = { _3DPRIM_POINTLIST, _3DPRIM_LINELIST, _3DPRIM_LINELOOP, @@ -103,12 +103,9 @@ static GLuint brw_set_prim(struct brw_context *brw, GLenum prim) brw->intel.reduced_primitive = reduced_prim[prim]; brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE; } - - brw_validate_state(brw); - brw_upload_state(brw); } - return hw_prim[prim]; + return prim_to_hw_prim[prim]; } @@ -123,9 +120,9 @@ static GLuint trim(GLenum prim, GLuint length) } -static void brw_emit_prim( struct brw_context *brw, - const struct _mesa_prim *prim ) - +static void brw_emit_prim(struct brw_context *brw, + const struct _mesa_prim *prim, + uint32_t hw_prim) { struct brw_3d_primitive prim_packet; @@ -136,7 +133,7 @@ static void brw_emit_prim( struct brw_context *brw, prim_packet.header.opcode = CMD_3D_PRIM; prim_packet.header.length = sizeof(prim_packet)/4 - 2; prim_packet.header.pad = 0; - prim_packet.header.topology = brw_set_prim(brw, prim->mode); + prim_packet.header.topology = hw_prim; prim_packet.header.indexed = prim->indexed; prim_packet.verts_per_instance = trim(prim->mode, prim->count); @@ -258,11 +255,15 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, struct brw_context *brw = brw_context(ctx); GLboolean retval = GL_FALSE; GLboolean warn = GL_FALSE; + GLboolean first_time = GL_TRUE; GLuint i; if (ctx->NewState) _mesa_update_state( ctx ); + if (check_fallbacks(brw, prim, nr_prims)) + return GL_FALSE; + brw_validate_textures( brw ); /* Bind all inputs, derive varying and size information: @@ -275,6 +276,7 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, brw->vb.min_index = min_index; brw->vb.max_index = max_index; brw->state.dirty.brw |= BRW_NEW_VERTICES; + /* Have to validate state quite late. Will rebuild tnl_program, * which depends on varying information. * @@ -289,59 +291,58 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, return GL_TRUE; } - /* Flush the batch if it's approaching full, so that we don't wrap while - * we've got validated state that needs to be in the same batch as the - * primitives. This fraction is just a guess (minimal full state plus - * a primitive is around 512 bytes), and would be better if we had - * an upper bound of how much we might emit in a single - * brw_try_draw_prims(). - */ - intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4, - LOOP_CLIPRECTS); - { - /* Set the first primitive early, ahead of validate_state: + for (i = 0; i < nr_prims; i++) { + uint32_t hw_prim; + + /* Flush the batch if it's approaching full, so that we don't wrap while + * we've got validated state that needs to be in the same batch as the + * primitives. This fraction is just a guess (minimal full state plus + * a primitive is around 512 bytes), and would be better if we had + * an upper bound of how much we might emit in a single + * brw_try_draw_prims(). */ - brw_set_prim(brw, prim[0].mode); + intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4, + LOOP_CLIPRECTS); - brw_validate_state( brw ); + hw_prim = brw_set_prim(brw, prim[i].mode); - /* Various fallback checks: - */ - if (brw->intel.Fallback) - goto out; + if (first_time || (brw->state.dirty.brw & BRW_NEW_PRIMITIVE)) { + first_time = GL_FALSE; - if (check_fallbacks( brw, prim, nr_prims )) - goto out; + /* Various fallback checks: */ + if (brw->intel.Fallback) + goto out; - /* Check that we can fit our state in with our existing batchbuffer, or - * flush otherwise. - */ - if (dri_bufmgr_check_aperture_space(brw->state.validated_bos, - brw->state.validated_bo_count)) { - static GLboolean warned; - intel_batchbuffer_flush(intel->batch); - - /* Validate the state after we flushed the batch (which would have - * changed the set of dirty state). If we still fail to - * check_aperture, warn of what's happening, but attempt to continue - * on since it may succeed anyway, and the user would probably rather - * see a failure and a warning than a fallback. - */ brw_validate_state(brw); - if (!warned && - dri_bufmgr_check_aperture_space(brw->state.validated_bos, + + /* Check that we can fit our state in with our existing batchbuffer, or + * flush otherwise. + */ + if (dri_bufmgr_check_aperture_space(brw->state.validated_bos, brw->state.validated_bo_count)) { - warn = GL_TRUE; - warned = GL_TRUE; + static GLboolean warned; + intel_batchbuffer_flush(intel->batch); + + /* Validate the state after we flushed the batch (which would have + * changed the set of dirty state). If we still fail to + * check_aperture, warn of what's happening, but attempt to continue + * on since it may succeed anyway, and the user would probably rather + * see a failure and a warning than a fallback. + */ + brw_validate_state(brw); + if (!warned && + dri_bufmgr_check_aperture_space(brw->state.validated_bos, + brw->state.validated_bo_count)) { + warn = GL_TRUE; + warned = GL_TRUE; + } } - } - - brw_upload_state(brw); - for (i = 0; i < nr_prims; i++) { - brw_emit_prim(brw, &prim[i]); + brw_upload_state(brw); } + brw_emit_prim(brw, &prim[i], hw_prim); + retval = GL_TRUE; } diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index c38610b24e..a18dee85e8 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -117,7 +117,6 @@ static void brwProgramStringNotify( GLcontext *ctx, if (p == fp) brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM; p->id = brw->program_id++; - p->param_state = p->program.Base.Parameters->StateFlags; } else if (target == GL_VERTEX_PROGRAM_ARB) { struct brw_context *brw = brw_context(ctx); @@ -129,7 +128,6 @@ static void brwProgramStringNotify( GLcontext *ctx, _mesa_insert_mvp_code(ctx, &p->program); } p->id = brw->program_id++; - p->param_state = p->program.Base.Parameters->StateFlags; /* Also tell tnl about it: */ diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 7a642bd2a8..5124535f2a 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -181,6 +181,118 @@ brw_clear_validated_bos(struct brw_context *brw) brw->state.validated_bo_count = 0; } +struct dirty_bit_map { + uint32_t bit; + char *name; + uint32_t count; +}; + +#define DEFINE_BIT(name) {name, #name, 0} + +static struct dirty_bit_map mesa_bits[] = { + DEFINE_BIT(_NEW_MODELVIEW), + DEFINE_BIT(_NEW_PROJECTION), + DEFINE_BIT(_NEW_TEXTURE_MATRIX), + DEFINE_BIT(_NEW_COLOR_MATRIX), + DEFINE_BIT(_NEW_ACCUM), + DEFINE_BIT(_NEW_COLOR), + DEFINE_BIT(_NEW_DEPTH), + DEFINE_BIT(_NEW_EVAL), + DEFINE_BIT(_NEW_FOG), + DEFINE_BIT(_NEW_HINT), + DEFINE_BIT(_NEW_LIGHT), + DEFINE_BIT(_NEW_LINE), + DEFINE_BIT(_NEW_PIXEL), + DEFINE_BIT(_NEW_POINT), + DEFINE_BIT(_NEW_POLYGON), + DEFINE_BIT(_NEW_POLYGONSTIPPLE), + DEFINE_BIT(_NEW_SCISSOR), + DEFINE_BIT(_NEW_STENCIL), + DEFINE_BIT(_NEW_TEXTURE), + DEFINE_BIT(_NEW_TRANSFORM), + DEFINE_BIT(_NEW_VIEWPORT), + DEFINE_BIT(_NEW_PACKUNPACK), + DEFINE_BIT(_NEW_ARRAY), + DEFINE_BIT(_NEW_RENDERMODE), + DEFINE_BIT(_NEW_BUFFERS), + DEFINE_BIT(_NEW_MULTISAMPLE), + DEFINE_BIT(_NEW_TRACK_MATRIX), + DEFINE_BIT(_NEW_PROGRAM), + {0, 0, 0} +}; + +static struct dirty_bit_map brw_bits[] = { + DEFINE_BIT(BRW_NEW_URB_FENCE), + DEFINE_BIT(BRW_NEW_FRAGMENT_PROGRAM), + DEFINE_BIT(BRW_NEW_VERTEX_PROGRAM), + DEFINE_BIT(BRW_NEW_INPUT_DIMENSIONS), + DEFINE_BIT(BRW_NEW_CURBE_OFFSETS), + DEFINE_BIT(BRW_NEW_REDUCED_PRIMITIVE), + DEFINE_BIT(BRW_NEW_PRIMITIVE), + DEFINE_BIT(BRW_NEW_CONTEXT), + DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS), + DEFINE_BIT(BRW_NEW_INPUT_VARYING), + DEFINE_BIT(BRW_NEW_PSP), + DEFINE_BIT(BRW_NEW_METAOPS), + DEFINE_BIT(BRW_NEW_FENCE), + DEFINE_BIT(BRW_NEW_INDICES), + DEFINE_BIT(BRW_NEW_VERTICES), + DEFINE_BIT(BRW_NEW_BATCH), + DEFINE_BIT(BRW_NEW_DEPTH_BUFFER), + {0, 0, 0} +}; + +static struct dirty_bit_map cache_bits[] = { + DEFINE_BIT(CACHE_NEW_CC_VP), + DEFINE_BIT(CACHE_NEW_CC_UNIT), + DEFINE_BIT(CACHE_NEW_WM_PROG), + DEFINE_BIT(CACHE_NEW_SAMPLER_DEFAULT_COLOR), + DEFINE_BIT(CACHE_NEW_SAMPLER), + DEFINE_BIT(CACHE_NEW_WM_UNIT), + DEFINE_BIT(CACHE_NEW_SF_PROG), + DEFINE_BIT(CACHE_NEW_SF_VP), + DEFINE_BIT(CACHE_NEW_SF_UNIT), + DEFINE_BIT(CACHE_NEW_VS_UNIT), + DEFINE_BIT(CACHE_NEW_VS_PROG), + DEFINE_BIT(CACHE_NEW_GS_UNIT), + DEFINE_BIT(CACHE_NEW_GS_PROG), + DEFINE_BIT(CACHE_NEW_CLIP_VP), + DEFINE_BIT(CACHE_NEW_CLIP_UNIT), + DEFINE_BIT(CACHE_NEW_CLIP_PROG), + DEFINE_BIT(CACHE_NEW_SURFACE), + DEFINE_BIT(CACHE_NEW_SURF_BIND), + {0, 0, 0} +}; + + +static void +brw_update_dirty_count(struct dirty_bit_map *bit_map, int32_t bits) +{ + int i; + + for (i = 0; i < 32; i++) { + if (bit_map[i].bit == 0) + return; + + if (bit_map[i].bit & bits) + bit_map[i].count++; + } +} + +static void +brw_print_dirty_count(struct dirty_bit_map *bit_map, int32_t bits) +{ + int i; + + for (i = 0; i < 32; i++) { + if (bit_map[i].bit == 0) + return; + + fprintf(stderr, "0x%08x: %12d (%s)\n", + bit_map[i].bit, bit_map[i].count, bit_map[i].name); + } +} + /*********************************************************************** * Emit all state: */ @@ -246,6 +358,7 @@ void brw_upload_state(struct brw_context *brw) { struct brw_state_flags *state = &brw->state.dirty; int i; + static int dirty_count = 0; brw_clear_validated_bos(brw); @@ -301,6 +414,18 @@ void brw_upload_state(struct brw_context *brw) } } + if (INTEL_DEBUG & DEBUG_STATE) { + brw_update_dirty_count(mesa_bits, state->mesa); + brw_update_dirty_count(brw_bits, state->brw); + brw_update_dirty_count(cache_bits, state->cache); + if (dirty_count++ % 1000 == 0) { + brw_print_dirty_count(mesa_bits, state->mesa); + brw_print_dirty_count(brw_bits, state->brw); + brw_print_dirty_count(cache_bits, state->cache); + fprintf(stderr, "\n"); + } + } + if (!brw->intel.Fallback) memset(state, 0, sizeof(*state)); } diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index 2d4c81274e..f7293ef423 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -171,8 +171,6 @@ static void brw_note_unlock( struct intel_context *intel ) struct brw_context *brw = brw_context(&intel->ctx); brw_state_cache_check_size(brw); - - brw_context(&intel->ctx)->state.dirty.brw |= BRW_NEW_LOCK; } diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 361312c2ca..bad76793af 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -230,12 +230,6 @@ static void brw_wm_populate_key( struct brw_context *brw, lookup |= IZ_STENCIL_WRITE_ENABLE_BIT; } - /* XXX: when should this be disabled? - */ - if (1) - lookup |= IZ_EARLY_DEPTH_TEST_BIT; - - line_aa = AA_NEVER; /* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */ diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 896390c17b..ded079695e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -49,8 +49,7 @@ #define IZ_DEPTH_TEST_ENABLE_BIT 0x8 #define IZ_STENCIL_WRITE_ENABLE_BIT 0x10 #define IZ_STENCIL_TEST_ENABLE_BIT 0x20 -#define IZ_EARLY_DEPTH_TEST_BIT 0x40 -#define IZ_BIT_MAX 0x80 +#define IZ_BIT_MAX 0x40 #define AA_NEVER 0 #define AA_SOMETIMES 1 diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index d3e926c328..7f7b957cbe 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -426,10 +426,6 @@ static struct prog_src_register search_or_add_param5(struct brw_wm_compile *c, idx = _mesa_add_state_reference( paramList, tokens ); - /* Recalculate state dependency: - */ - c->fp->param_state = paramList->StateFlags; - return src_reg(PROGRAM_STATE_VAR, idx); } diff --git a/src/mesa/drivers/dri/i965/brw_wm_iz.c b/src/mesa/drivers/dri/i965/brw_wm_iz.c index 0bb5d5ba83..bd60ac9b31 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_iz.c +++ b/src/mesa/drivers/dri/i965/brw_wm_iz.c @@ -52,70 +52,6 @@ const struct { { { P, 0, 0, 0, 0 }, { P, 0, 0, 0, 0 }, - { C, 0, 1, 0, 0 }, - { C, 0, 1, 0, 0 }, - { C, 1, 1, 0, 0 }, - { C, 1, 1, 0, 0 }, - { C, 0, 1, 0, 0 }, - { C, 0, 1, 0, 0 }, - { C, 1, 1, 1, 0 }, - { C, 1, 1, 1, 0 }, - { C, 0, 1, 1, 0 }, - { C, 0, 1, 1, 0 }, - { C, 1, 1, 1, 0 }, - { C, 1, 1, 1, 0 }, - { C, 0, 1, 1, 0 }, - { C, 0, 1, 1, 0 }, - { P, 0, 0, 0, 0 }, - { P, 0, 0, 0, 0 }, - { C, 0, 1, 0, 0 }, - { C, 0, 1, 0, 0 }, - { C, 1, 1, 0, 0 }, - { C, 1, 1, 0, 0 }, - { C, 0, 1, 0, 0 }, - { C, 0, 1, 0, 0 }, - { C, 1, 1, 1, 0 }, - { C, 1, 1, 1, 0 }, - { C, 0, 1, 1, 0 }, - { C, 0, 1, 1, 0 }, - { C, 1, 1, 1, 0 }, - { C, 1, 1, 1, 0 }, - { C, 0, 1, 1, 0 }, - { C, 0, 1, 1, 0 }, - { C, 0, 0, 0, 1 }, - { C, 0, 0, 0, 1 }, - { C, 0, 1, 0, 1 }, - { C, 0, 1, 0, 1 }, - { C, 1, 1, 0, 1 }, - { C, 1, 1, 0, 1 }, - { C, 0, 1, 0, 1 }, - { C, 0, 1, 0, 1 }, - { C, 1, 1, 1, 1 }, - { C, 1, 1, 1, 1 }, - { C, 0, 1, 1, 1 }, - { C, 0, 1, 1, 1 }, - { C, 1, 1, 1, 1 }, - { C, 1, 1, 1, 1 }, - { C, 0, 1, 1, 1 }, - { C, 0, 1, 1, 1 }, - { C, 0, 0, 0, 1 }, - { C, 0, 0, 0, 1 }, - { C, 0, 1, 0, 1 }, - { C, 0, 1, 0, 1 }, - { C, 1, 1, 0, 1 }, - { C, 1, 1, 0, 1 }, - { C, 0, 1, 0, 1 }, - { C, 0, 1, 0, 1 }, - { C, 1, 1, 1, 1 }, - { C, 1, 1, 1, 1 }, - { C, 0, 1, 1, 1 }, - { C, 0, 1, 1, 1 }, - { C, 1, 1, 1, 1 }, - { C, 1, 1, 1, 1 }, - { C, 0, 1, 1, 1 }, - { C, 0, 1, 1, 1 }, - { P, 0, 0, 0, 0 }, - { P, 0, 0, 0, 0 }, { P, 0, 0, 0, 0 }, { P, 0, 0, 0, 0 }, { P, 0, 0, 0, 0 }, diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index fd461618bc..5302405eda 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -88,7 +88,7 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key) /* BRW_NEW_CURBE_OFFSETS */ key->curbe_offset = brw->curbe.wm_start; - /* CACHE_NEW_SURFACE */ + /* BRW_NEW_NR_SURFACEs */ key->nr_surfaces = brw->wm.nr_surfaces; /* CACHE_NEW_SAMPLER */ @@ -281,10 +281,9 @@ const struct brw_tracked_state brw_wm_unit = { .brw = (BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_CURBE_OFFSETS | - BRW_NEW_LOCK), + BRW_NEW_NR_SURFACES), - .cache = (CACHE_NEW_SURFACE | - CACHE_NEW_WM_PROG | + .cache = (CACHE_NEW_WM_PROG | CACHE_NEW_SAMPLER) }, .prepare = upload_wm_unit, diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 3790b50c97..63e14cc390 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -438,6 +438,7 @@ static void prepare_wm_surfaces(struct brw_context *brw ) GLcontext *ctx = &brw->intel.ctx; struct intel_context *intel = &brw->intel; GLuint i; + int old_nr_surfaces; if (brw->state.nr_draw_regions > 1) { for (i = 0; i < brw->state.nr_draw_regions; i++) { @@ -448,6 +449,7 @@ static void prepare_wm_surfaces(struct brw_context *brw ) brw_update_region_surface(brw, brw->state.draw_regions[0], 0, GL_TRUE); } + old_nr_surfaces = brw->wm.nr_surfaces; brw->wm.nr_surfaces = MAX_DRAW_BUFFERS; for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { @@ -473,6 +475,9 @@ static void prepare_wm_surfaces(struct brw_context *brw ) dri_bo_unreference(brw->wm.bind_bo); brw->wm.bind_bo = brw_wm_get_binding_table(brw); + + if (brw->wm.nr_surfaces != old_nr_surfaces) + brw->state.dirty.brw |= BRW_NEW_NR_SURFACES; } diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 60028f090a..ee43ed7e83 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -184,6 +184,7 @@ struct intel_context GLuint id; uint32_t primitive; /**< Current hardware primitive type */ void (*flush) (struct intel_context *); + GLubyte *start_ptr; /**< for i8xx */ dri_bo *vb_bo; uint8_t *vb; unsigned int start_offset; /**< Byte offset of primitive sequence */ diff --git a/src/mesa/drivers/dri/intel/intel_reg.h b/src/mesa/drivers/dri/intel/intel_reg.h index 68d8a05b83..57ac8f0cc1 100644 --- a/src/mesa/drivers/dri/intel/intel_reg.h +++ b/src/mesa/drivers/dri/intel/intel_reg.h @@ -71,14 +71,14 @@ /** @{ * 915 definitions */ -#define S0_VB_OFFSET_MASK 0xffffffc +#define S0_VB_OFFSET_MASK 0xffffffc0 #define S0_AUTO_CACHE_INV_DISABLE (1<<0) /** @} */ /** @{ * 830 definitions */ -#define S0_VB_OFFSET_MASK_830 0xffffff8 +#define S0_VB_OFFSET_MASK_830 0xffffff80 #define S0_VB_PITCH_SHIFT_830 1 #define S0_VB_ENABLE_830 (1<<0) /** @} */ diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index cf09fad745..61b55b97b5 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -461,6 +461,7 @@ intelCreateContext(const __GLcontextModes * mesaVis, sharedContextPrivate); } } else { + intelScreen->no_vbo = GL_TRUE; return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); } #else diff --git a/src/mesa/drivers/dri/intel/intel_screen.h b/src/mesa/drivers/dri/intel/intel_screen.h index fc913da5bf..91f0d6d1ae 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.h +++ b/src/mesa/drivers/dri/intel/intel_screen.h @@ -77,6 +77,7 @@ typedef struct GLboolean no_hw; + GLboolean no_vbo; int ttm; dri_bufmgr *bufmgr; diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index 36446efde7..dd932aebc9 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -98,7 +98,9 @@ do_copy_texsubimage(struct intel_context *intel, get_teximage_source(intel, internalFormat); if (!intelImage->mt || !src) { - DBG("%s fail %p %p\n", __FUNCTION__, intelImage->mt, src); + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "%s fail %p %p\n", + __FUNCTION__, intelImage->mt, src); return GL_FALSE; } diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index c7db435506..d3aee196c7 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -2004,7 +2004,7 @@ save_Lightfv(GLenum light, GLenum pname, const GLfloat *params) Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_LIGHT, 6); - if (OPCODE_LIGHT) { + if (n) { GLint i, nParams; n[1].e = light; n[2].e = pname; diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 95bf1165f4..aa5b172123 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 7.1 + * Version: 7.3 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * @@ -297,6 +297,15 @@ _mesa_enable_sw_extensions(GLcontext *ctx) #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE; #endif +#if FEATURE_texture_fxt1 + _mesa_enable_extension(ctx, "GL_3DFX_texture_compression_FXT1"); +#endif +#if FEATURE_texture_s3tc + if (ctx->Mesa_DXTn) { + _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + _mesa_enable_extension(ctx, "GL_S3_s3tc"); + } +#endif } diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index 5ad936419b..0653407048 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -151,8 +151,6 @@ _mesa_compressed_texture_size( GLcontext *ctx, /* Textures smaller than 8x4 will effectively be made into 8x4 and * take 16 bytes. */ - if (size < 16) - size = 16; return size; #endif #if FEATURE_texture_s3tc @@ -166,8 +164,6 @@ _mesa_compressed_texture_size( GLcontext *ctx, /* Textures smaller than 4x4 will effectively be made into 4x4 and * take 8 bytes. */ - if (size < 8) - size = 8; return size; case MESA_FORMAT_RGBA_DXT3: case MESA_FORMAT_RGBA_DXT5: @@ -179,8 +175,6 @@ _mesa_compressed_texture_size( GLcontext *ctx, /* Textures smaller than 4x4 will effectively be made into 4x4 and * take 16 bytes. */ - if (size < 16) - size = 16; return size; #endif default: diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index 88fca19835..8d29acac8b 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -632,7 +632,7 @@ append(char *dst, const char *src) /** - * Convert token 'k' to a string, append it only 'dst' string. + * Convert token 'k' to a string, append it onto 'dst' string. */ static void append_token(char *dst, gl_state_index k) @@ -807,7 +807,8 @@ append_token(char *dst, gl_state_index k) append(dst, "ShadowAmbient"); break; default: - ; + /* probably STATE_INTERNAL_DRIVER+i (driver private state) */ + append(dst, "driverState"); } } diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c index 9e44fba3da..6b1dfd5d50 100644 --- a/src/mesa/swrast/s_texfilter.c +++ b/src/mesa/swrast/s_texfilter.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 7.0.3 + * Version: 7.3 * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2008 Brian Paul 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"), @@ -33,6 +33,16 @@ #include "s_texfilter.h" +/* + * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes + * see 1-pixel bands of improperly weighted linear-filtered textures. + * The tests/texwrap.c demo is a good test. + * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. + * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). + */ +#define FRAC(f) ((f) - IFLOOR(f)) + + /** * Constants for integer linear interpolation. */ @@ -223,257 +233,271 @@ lerp_rgba_3d(GLchan result[4], GLfloat a, GLfloat b, GLfloat c, * Used to compute texel locations for linear sampling. * Input: * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER - * S = texcoord in [0,1] - * SIZE = width (or height or depth) of texture + * s = texcoord in [0,1] + * size = width (or height or depth) of texture * Output: - * U = texcoord in [0, width] - * I0, I1 = two nearest texel indexes + * i0, i1 = returns two nearest texel indexes + * weight = returns blend factor between texels */ -#define COMPUTE_LINEAR_TEXEL_LOCATIONS(wrapMode, S, U, SIZE, I0, I1) \ -{ \ - switch (wrapMode) { \ - case GL_REPEAT: \ - U = S * SIZE - 0.5F; \ - if (img->_IsPowerOfTwo) { \ - I0 = IFLOOR(U) & (SIZE - 1); \ - I1 = (I0 + 1) & (SIZE - 1); \ - } \ - else { \ - I0 = REMAINDER(IFLOOR(U), SIZE); \ - I1 = REMAINDER(I0 + 1, SIZE); \ - } \ - break; \ - case GL_CLAMP_TO_EDGE: \ - if (S <= 0.0F) \ - U = 0.0F; \ - else if (S >= 1.0F) \ - U = (GLfloat) SIZE; \ - else \ - U = S * SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - if (I0 < 0) \ - I0 = 0; \ - if (I1 >= (GLint) SIZE) \ - I1 = SIZE - 1; \ - break; \ - case GL_CLAMP_TO_BORDER: \ - { \ - const GLfloat min = -1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - if (S <= min) \ - U = min * SIZE; \ - else if (S >= max) \ - U = max * SIZE; \ - else \ - U = S * SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - } \ - break; \ - case GL_MIRRORED_REPEAT: \ - { \ - const GLint flr = IFLOOR(S); \ - if (flr & 1) \ - U = 1.0F - (S - (GLfloat) flr); /* flr is odd */ \ - else \ - U = S - (GLfloat) flr; /* flr is even */ \ - U = (U * SIZE) - 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - if (I0 < 0) \ - I0 = 0; \ - if (I1 >= (GLint) SIZE) \ - I1 = SIZE - 1; \ - } \ - break; \ - case GL_MIRROR_CLAMP_EXT: \ - U = FABSF(S); \ - if (U >= 1.0F) \ - U = (GLfloat) SIZE; \ - else \ - U *= SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - break; \ - case GL_MIRROR_CLAMP_TO_EDGE_EXT: \ - U = FABSF(S); \ - if (U >= 1.0F) \ - U = (GLfloat) SIZE; \ - else \ - U *= SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - if (I0 < 0) \ - I0 = 0; \ - if (I1 >= (GLint) SIZE) \ - I1 = SIZE - 1; \ - break; \ - case GL_MIRROR_CLAMP_TO_BORDER_EXT: \ - { \ - const GLfloat min = -1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - U = FABSF(S); \ - if (U <= min) \ - U = min * SIZE; \ - else if (U >= max) \ - U = max * SIZE; \ - else \ - U *= SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - } \ - break; \ - case GL_CLAMP: \ - if (S <= 0.0F) \ - U = 0.0F; \ - else if (S >= 1.0F) \ - U = (GLfloat) SIZE; \ - else \ - U = S * SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - break; \ - default: \ - _mesa_problem(ctx, "Bad wrap mode"); \ - return; \ - } \ +static INLINE void +linear_texel_locations(GLenum wrapMode, + const struct gl_texture_image *img, + GLint size, GLfloat s, + GLint *i0, GLint *i1, GLfloat *weight) +{ + GLfloat u; + switch (wrapMode) { + case GL_REPEAT: + u = s * size - 0.5F; + if (img->_IsPowerOfTwo) { + *i0 = IFLOOR(u) & (size - 1); + *i1 = (*i0 + 1) & (size - 1); + } + else { + *i0 = REMAINDER(IFLOOR(u), size); + *i1 = REMAINDER(*i0 + 1, size); + } + break; + case GL_CLAMP_TO_EDGE: + if (s <= 0.0F) + u = 0.0F; + else if (s >= 1.0F) + u = (GLfloat) size; + else + u = s * size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + if (*i0 < 0) + *i0 = 0; + if (*i1 >= (GLint) size) + *i1 = size - 1; + break; + case GL_CLAMP_TO_BORDER: + { + const GLfloat min = -1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + if (s <= min) + u = min * size; + else if (s >= max) + u = max * size; + else + u = s * size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + } + break; + case GL_MIRRORED_REPEAT: + { + const GLint flr = IFLOOR(s); + if (flr & 1) + u = 1.0F - (s - (GLfloat) flr); + else + u = s - (GLfloat) flr; + u = (u * size) - 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + if (*i0 < 0) + *i0 = 0; + if (*i1 >= (GLint) size) + *i1 = size - 1; + } + break; + case GL_MIRROR_CLAMP_EXT: + u = FABSF(s); + if (u >= 1.0F) + u = (GLfloat) size; + else + u *= size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + break; + case GL_MIRROR_CLAMP_TO_EDGE_EXT: + u = FABSF(s); + if (u >= 1.0F) + u = (GLfloat) size; + else + u *= size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + if (*i0 < 0) + *i0 = 0; + if (*i1 >= (GLint) size) + *i1 = size - 1; + break; + case GL_MIRROR_CLAMP_TO_BORDER_EXT: + { + const GLfloat min = -1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + u = FABSF(s); + if (u <= min) + u = min * size; + else if (u >= max) + u = max * size; + else + u *= size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + } + break; + case GL_CLAMP: + if (s <= 0.0F) + u = 0.0F; + else if (s >= 1.0F) + u = (GLfloat) size; + else + u = s * size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + break; + default: + _mesa_problem(NULL, "Bad wrap mode"); + u = 0.0F; + } + *weight = FRAC(u); } /** * Used to compute texel location for nearest sampling. */ -#define COMPUTE_NEAREST_TEXEL_LOCATION(wrapMode, S, SIZE, I) \ -{ \ - switch (wrapMode) { \ - case GL_REPEAT: \ - /* s limited to [0,1) */ \ - /* i limited to [0,size-1] */ \ - I = IFLOOR(S * SIZE); \ - if (img->_IsPowerOfTwo) \ - I &= (SIZE - 1); \ - else \ - I = REMAINDER(I, SIZE); \ - break; \ - case GL_CLAMP_TO_EDGE: \ - { \ - /* s limited to [min,max] */ \ - /* i limited to [0, size-1] */ \ - const GLfloat min = 1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - if (S < min) \ - I = 0; \ - else if (S > max) \ - I = SIZE - 1; \ - else \ - I = IFLOOR(S * SIZE); \ - } \ - break; \ - case GL_CLAMP_TO_BORDER: \ - { \ - /* s limited to [min,max] */ \ - /* i limited to [-1, size] */ \ - const GLfloat min = -1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - if (S <= min) \ - I = -1; \ - else if (S >= max) \ - I = SIZE; \ - else \ - I = IFLOOR(S * SIZE); \ - } \ - break; \ - case GL_MIRRORED_REPEAT: \ - { \ - const GLfloat min = 1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - const GLint flr = IFLOOR(S); \ - GLfloat u; \ - if (flr & 1) \ - u = 1.0F - (S - (GLfloat) flr); /* flr is odd */ \ - else \ - u = S - (GLfloat) flr; /* flr is even */ \ - if (u < min) \ - I = 0; \ - else if (u > max) \ - I = SIZE - 1; \ - else \ - I = IFLOOR(u * SIZE); \ - } \ - break; \ - case GL_MIRROR_CLAMP_EXT: \ - { \ - /* s limited to [0,1] */ \ - /* i limited to [0,size-1] */ \ - const GLfloat u = FABSF(S); \ - if (u <= 0.0F) \ - I = 0; \ - else if (u >= 1.0F) \ - I = SIZE - 1; \ - else \ - I = IFLOOR(u * SIZE); \ - } \ - break; \ - case GL_MIRROR_CLAMP_TO_EDGE_EXT: \ - { \ - /* s limited to [min,max] */ \ - /* i limited to [0, size-1] */ \ - const GLfloat min = 1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - const GLfloat u = FABSF(S); \ - if (u < min) \ - I = 0; \ - else if (u > max) \ - I = SIZE - 1; \ - else \ - I = IFLOOR(u * SIZE); \ - } \ - break; \ - case GL_MIRROR_CLAMP_TO_BORDER_EXT: \ - { \ - /* s limited to [min,max] */ \ - /* i limited to [0, size-1] */ \ - const GLfloat min = -1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - const GLfloat u = FABSF(S); \ - if (u < min) \ - I = -1; \ - else if (u > max) \ - I = SIZE; \ - else \ - I = IFLOOR(u * SIZE); \ - } \ - break; \ - case GL_CLAMP: \ - /* s limited to [0,1] */ \ - /* i limited to [0,size-1] */ \ - if (S <= 0.0F) \ - I = 0; \ - else if (S >= 1.0F) \ - I = SIZE - 1; \ - else \ - I = IFLOOR(S * SIZE); \ - break; \ - default: \ - _mesa_problem(ctx, "Bad wrap mode"); \ - return; \ - } \ +static INLINE GLint +nearest_texel_location(GLenum wrapMode, + const struct gl_texture_image *img, + GLint size, GLfloat s) +{ + GLint i; + + switch (wrapMode) { + case GL_REPEAT: + /* s limited to [0,1) */ + /* i limited to [0,size-1] */ + i = IFLOOR(s * size); + if (img->_IsPowerOfTwo) + i &= (size - 1); + else + i = REMAINDER(i, size); + return i; + case GL_CLAMP_TO_EDGE: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const GLfloat min = 1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + if (s < min) + i = 0; + else if (s > max) + i = size - 1; + else + i = IFLOOR(s * size); + } + return i; + case GL_CLAMP_TO_BORDER: + { + /* s limited to [min,max] */ + /* i limited to [-1, size] */ + const GLfloat min = -1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + if (s <= min) + i = -1; + else if (s >= max) + i = size; + else + i = IFLOOR(s * size); + } + return i; + case GL_MIRRORED_REPEAT: + { + const GLfloat min = 1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + const GLint flr = IFLOOR(s); + GLfloat u; + if (flr & 1) + u = 1.0F - (s - (GLfloat) flr); + else + u = s - (GLfloat) flr; + if (u < min) + i = 0; + else if (u > max) + i = size - 1; + else + i = IFLOOR(u * size); + } + return i; + case GL_MIRROR_CLAMP_EXT: + { + /* s limited to [0,1] */ + /* i limited to [0,size-1] */ + const GLfloat u = FABSF(s); + if (u <= 0.0F) + i = 0; + else if (u >= 1.0F) + i = size - 1; + else + i = IFLOOR(u * size); + } + return i; + case GL_MIRROR_CLAMP_TO_EDGE_EXT: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const GLfloat min = 1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + const GLfloat u = FABSF(s); + if (u < min) + i = 0; + else if (u > max) + i = size - 1; + else + i = IFLOOR(u * size); + } + return i; + case GL_MIRROR_CLAMP_TO_BORDER_EXT: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const GLfloat min = -1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + const GLfloat u = FABSF(s); + if (u < min) + i = -1; + else if (u > max) + i = size; + else + i = IFLOOR(u * size); + } + return i; + case GL_CLAMP: + /* s limited to [0,1] */ + /* i limited to [0,size-1] */ + if (s <= 0.0F) + i = 0; + else if (s >= 1.0F) + i = size - 1; + else + i = IFLOOR(s * size); + return i; + default: + _mesa_problem(NULL, "Bad wrap mode"); + return 0; + } } /* Power of two image sizes only */ -#define COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(S, U, SIZE, I0, I1) \ -{ \ - U = S * SIZE - 0.5F; \ - I0 = IFLOOR(U) & (SIZE - 1); \ - I1 = (I0 + 1) & (SIZE - 1); \ +static INLINE void +linear_repeat_texel_location(GLuint size, GLfloat s, + GLint *i0, GLint *i1, GLfloat *weight) +{ + GLfloat u = s * size - 0.5F; + *i0 = IFLOOR(u) & (size - 1); + *i1 = (*i0 + 1) & (size - 1); + *weight = FRAC(u); } @@ -516,17 +540,6 @@ nearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) /* - * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes - * see 1-pixel bands of improperly weighted linear-filtered textures. - * The tests/texwrap.c demo is a good test. - * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. - * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). - */ -#define FRAC(f) ((f) - IFLOOR(f)) - - - -/* * Bitflags for texture border color sampling. */ #define I0BIT 1 @@ -538,7 +551,7 @@ nearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) -/* +/** * The lambda[] array values are always monotonic. Either the whole span * will be minified, magnified, or split between the two. This function * determines the subranges in [0, n-1] that are to be minified or magnified. @@ -651,10 +664,10 @@ compute_min_mag_ranges(const struct gl_texture_object *tObj, /* 1-D Texture Sampling Functions */ /**********************************************************************/ -/* +/** * Return the texture sample for coordinate (s) using GL_NEAREST filter. */ -static void +static INLINE void sample_1d_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, @@ -662,7 +675,7 @@ sample_1d_nearest(GLcontext *ctx, { const GLint width = img->Width2; /* without border, power of two */ GLint i; - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i); + i = nearest_texel_location(tObj->WrapS, img, width, texcoord[0]); /* skip over the border, if any */ i += img->Border; if (i < 0 || i >= (GLint) img->Width) { @@ -675,10 +688,10 @@ sample_1d_nearest(GLcontext *ctx, } -/* +/** * Return the texture sample for coordinate (s) using GL_LINEAR filter. */ -static void +static INLINE void sample_1d_linear(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, @@ -686,12 +699,11 @@ sample_1d_linear(GLcontext *ctx, { const GLint width = img->Width2; GLint i0, i1; - GLfloat u; GLbitfield useBorderColor = 0x0; GLfloat a; GLchan t0[4], t1[4]; /* texels */ - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1); + linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); if (img->Border) { i0 += img->Border; @@ -716,7 +728,6 @@ sample_1d_linear(GLcontext *ctx, img->FetchTexelc(img, i1, 0, 0, t1); } - a = FRAC(u); lerp_rgba(rgba, a, t0, t1); } @@ -776,7 +787,6 @@ sample_1d_nearest_mipmap_linear(GLcontext *ctx, } - static void sample_1d_linear_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, @@ -802,7 +812,7 @@ sample_1d_linear_mipmap_linear(GLcontext *ctx, } - +/** Sample 1D texture, nearest filtering for both min/magnification */ static void sample_nearest_1d( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -812,13 +822,13 @@ sample_nearest_1d( GLcontext *ctx, GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_1d_nearest(ctx, tObj, image, texcoords[i], rgba[i]); } } - +/** Sample 1D texture, linear filtering for both min/magnification */ static void sample_linear_1d( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -828,17 +838,13 @@ sample_linear_1d( GLcontext *ctx, GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_1d_linear(ctx, tObj, image, texcoords[i], rgba[i]); } } -/* - * Given an (s) texture coordinate and lambda (level of detail) value, - * return a texture sample. - * - */ +/** Sample 1D texture, using lambda to choose between min/magnification */ static void sample_lambda_1d( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -915,7 +921,7 @@ sample_lambda_1d( GLcontext *ctx, /**********************************************************************/ -/* +/** * Return the texture sample for coordinate (s,t) using GL_NEAREST filter. */ static INLINE void @@ -930,8 +936,8 @@ sample_2d_nearest(GLcontext *ctx, GLint i, j; (void) ctx; - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j); + i = nearest_texel_location(tObj->WrapS, img, width, texcoord[0]); + j = nearest_texel_location(tObj->WrapT, img, height, texcoord[1]); /* skip over the border, if any */ i += img->Border; @@ -947,7 +953,6 @@ sample_2d_nearest(GLcontext *ctx, } - /** * Return the texture sample for coordinate (s,t) using GL_LINEAR filter. * New sampling code contributed by Lynn Quam <quam@ai.sri.com>. @@ -963,12 +968,11 @@ sample_2d_linear(GLcontext *ctx, const GLint height = img->Height2; GLint i0, j0, i1, j1; GLbitfield useBorderColor = 0x0; - GLfloat u, v; GLfloat a, b; GLchan t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1); + linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); + linear_texel_locations(tObj->WrapT, img, height, texcoord[1], &j0, &j1, &b); if (img->Border) { i0 += img->Border; @@ -1009,13 +1013,11 @@ sample_2d_linear(GLcontext *ctx, img->FetchTexelc(img, i1, j1, 0, t11); } - a = FRAC(u); - b = FRAC(v); lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); } -/* +/** * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT. * We don't have to worry about the texture border. */ @@ -1029,8 +1031,7 @@ sample_2d_linear_repeat(GLcontext *ctx, const GLint width = img->Width2; const GLint height = img->Height2; GLint i0, j0, i1, j1; - GLfloat u, v; - GLfloat a, b; + GLfloat wi, wj; GLchan t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ (void) ctx; @@ -1041,21 +1042,18 @@ sample_2d_linear_repeat(GLcontext *ctx, ASSERT(img->TexFormat->BaseFormat != GL_COLOR_INDEX); ASSERT(img->_IsPowerOfTwo); - COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[0], u, width, i0, i1); - COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[1], v, height, j0, j1); + linear_repeat_texel_location(width, texcoord[0], &i0, &i1, &wi); + linear_repeat_texel_location(height, texcoord[1], &j0, &j1, &wj); img->FetchTexelc(img, i0, j0, 0, t00); img->FetchTexelc(img, i1, j0, 0, t10); img->FetchTexelc(img, i0, j1, 0, t01); img->FetchTexelc(img, i1, j1, 0, t11); - a = FRAC(u); - b = FRAC(v); - lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); + lerp_rgba_2d(rgba, wi, wj, t00, t10, t01, t11); } - static void sample_2d_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, @@ -1070,7 +1068,6 @@ sample_2d_nearest_mipmap_nearest(GLcontext *ctx, } - static void sample_2d_linear_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, @@ -1086,7 +1083,6 @@ sample_2d_linear_mipmap_nearest(GLcontext *ctx, } - static void sample_2d_nearest_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, @@ -1112,8 +1108,6 @@ sample_2d_nearest_mipmap_linear(GLcontext *ctx, } - -/* Trilinear filtering */ static void sample_2d_linear_mipmap_linear( GLcontext *ctx, const struct gl_texture_object *tObj, @@ -1140,10 +1134,10 @@ sample_2d_linear_mipmap_linear( GLcontext *ctx, static void -sample_2d_linear_mipmap_linear_repeat( GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +sample_2d_linear_mipmap_linear_repeat(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoord[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1158,35 +1152,38 @@ sample_2d_linear_mipmap_linear_repeat( GLcontext *ctx, else { GLchan t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); - sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); - sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); + sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level ], + texcoord[i], t0); + sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level+1], + texcoord[i], t1); lerp_rgba(rgba[i], f, t0, t1); } } } +/** Sample 2D texture, nearest filtering for both min/magnification */ static void -sample_nearest_2d( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +sample_nearest_2d(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_2d_nearest(ctx, tObj, image, texcoords[i], rgba[i]); } } - +/** Sample 2D texture, linear filtering for both min/magnification */ static void -sample_linear_2d( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +sample_linear_2d(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -1195,19 +1192,19 @@ sample_linear_2d( GLcontext *ctx, tObj->WrapT == GL_REPEAT && image->_IsPowerOfTwo && image->Border == 0) { - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_2d_linear_repeat(ctx, tObj, image, texcoords[i], rgba[i]); } } else { - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_2d_linear(ctx, tObj, image, texcoords[i], rgba[i]); } } } -/* +/** * Optimized 2-D texture sampling: * S and T wrap mode == GL_REPEAT * GL_NEAREST min/mag filter @@ -1216,10 +1213,10 @@ sample_linear_2d( GLcontext *ctx, * Format = GL_RGB */ static void -opt_sample_rgb_2d( GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +opt_sample_rgb_2d(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; const GLfloat width = (GLfloat) img->Width; @@ -1248,7 +1245,7 @@ opt_sample_rgb_2d( GLcontext *ctx, } -/* +/** * Optimized 2-D texture sampling: * S and T wrap mode == GL_REPEAT * GL_NEAREST min/mag filter @@ -1257,10 +1254,10 @@ opt_sample_rgb_2d( GLcontext *ctx, * Format = GL_RGBA */ static void -opt_sample_rgba_2d( GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +opt_sample_rgba_2d(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; const GLfloat width = (GLfloat) img->Width; @@ -1287,15 +1284,12 @@ opt_sample_rgba_2d( GLcontext *ctx, } -/* - * Given an array of texture coordinate and lambda (level of detail) - * values, return an array of texture sample. - */ +/** Sample 2D texture, using lambda to choose between min/magnification */ static void -sample_lambda_2d( GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +sample_lambda_2d(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel]; GLuint minStart, minEnd; /* texels with minification */ @@ -1409,10 +1403,10 @@ sample_lambda_2d( GLcontext *ctx, /* 3-D Texture Sampling Functions */ /**********************************************************************/ -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. */ -static void +static INLINE void sample_3d_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, @@ -1425,9 +1419,9 @@ sample_3d_nearest(GLcontext *ctx, GLint i, j, k; (void) ctx; - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapR, texcoord[2], depth, k); + i = nearest_texel_location(tObj->WrapS, img, width, texcoord[0]); + j = nearest_texel_location(tObj->WrapT, img, height, texcoord[1]); + k = nearest_texel_location(tObj->WrapR, img, depth, texcoord[2]); if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height || @@ -1441,8 +1435,7 @@ sample_3d_nearest(GLcontext *ctx, } - -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. */ static void @@ -1457,14 +1450,13 @@ sample_3d_linear(GLcontext *ctx, const GLint depth = img->Depth2; GLint i0, j0, k0, i1, j1, k1; GLbitfield useBorderColor = 0x0; - GLfloat u, v, w; GLfloat a, b, c; GLchan t000[4], t010[4], t001[4], t011[4]; GLchan t100[4], t110[4], t101[4], t111[4]; - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapR, texcoord[2], w, depth, k0, k1); + linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); + linear_texel_locations(tObj->WrapT, img, height, texcoord[1], &j0, &j1, &b); + linear_texel_locations(tObj->WrapR, img, depth, texcoord[2], &k0, &k1, &c); if (img->Border) { i0 += img->Border; @@ -1536,14 +1528,10 @@ sample_3d_linear(GLcontext *ctx, } /* trilinear interpolation of samples */ - a = FRAC(u); - b = FRAC(v); - c = FRAC(w); lerp_rgba_3d(rgba, a, b, c, t000, t100, t010, t110, t001, t101, t011, t111); } - static void sample_3d_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, @@ -1623,6 +1611,7 @@ sample_3d_linear_mipmap_linear(GLcontext *ctx, } +/** Sample 3D texture, nearest filtering for both min/magnification */ static void sample_nearest_3d(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -1632,37 +1621,34 @@ sample_nearest_3d(GLcontext *ctx, GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_3d_nearest(ctx, tObj, image, texcoords[i], rgba[i]); } } - +/** Sample 3D texture, linear filtering for both min/magnification */ static void -sample_linear_3d( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +sample_linear_3d(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_3d_linear(ctx, tObj, image, texcoords[i], rgba[i]); } } -/* - * Given an (s,t,r) texture coordinate and lambda (level of detail) value, - * return a texture sample. - */ +/** Sample 3D texture, using lambda to choose between min/magnification */ static void -sample_lambda_3d( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4] ) +sample_lambda_3d(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) { GLuint minStart, minEnd; /* texels with minification */ GLuint magStart, magEnd; /* texels with magnification */ @@ -1951,11 +1937,12 @@ sample_cube_linear_mipmap_linear(GLcontext *ctx, } +/** Sample cube texture, using lambda to choose between min/magnification */ static void -sample_lambda_cube( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) +sample_lambda_cube(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) { GLuint minStart, minEnd; /* texels with minification */ GLuint magStart, magEnd; /* texels with magnification */ @@ -2031,50 +2018,56 @@ sample_lambda_cube( GLcontext *ctx, static INLINE GLint clamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max) { - if (wrapMode == GL_CLAMP) { + switch (wrapMode) { + case GL_CLAMP: return IFLOOR( CLAMP(coord, 0.0F, max - 1) ); - } - else if (wrapMode == GL_CLAMP_TO_EDGE) { + case GL_CLAMP_TO_EDGE: return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) ); - } - else { + case GL_CLAMP_TO_BORDER: return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) ); + default: + _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_nearest"); + return 0; } } -/* +/** * As above, but GL_LINEAR filtering. */ static INLINE void clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, - GLint *i0out, GLint *i1out) + GLint *i0out, GLint *i1out, GLfloat *weight) { GLfloat fcol; GLint i0, i1; - if (wrapMode == GL_CLAMP) { + switch (wrapMode) { + case GL_CLAMP: /* Not exactly what the spec says, but it matches NVIDIA output */ fcol = CLAMP(coord - 0.5F, 0.0, max-1); i0 = IFLOOR(fcol); i1 = i0 + 1; - } - else if (wrapMode == GL_CLAMP_TO_EDGE) { + break; + case GL_CLAMP_TO_EDGE: fcol = CLAMP(coord, 0.5F, max - 0.5F); fcol -= 0.5F; i0 = IFLOOR(fcol); i1 = i0 + 1; if (i1 > max - 1) i1 = max - 1; - } - else { - ASSERT(wrapMode == GL_CLAMP_TO_BORDER); + break; + case GL_CLAMP_TO_BORDER: fcol = CLAMP(coord, -0.5F, max + 0.5F); fcol -= 0.5F; i0 = IFLOOR(fcol); i1 = i0 + 1; + default: + _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear"); + i0 = i1 = 0; } *i0out = i0; *i1out = i1; + *weight = FRAC(fcol); } @@ -2085,10 +2078,8 @@ sample_nearest_rect(GLcontext *ctx, GLchan rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][0]; - const GLfloat width = (GLfloat) img->Width; - const GLfloat height = (GLfloat) img->Height; - const GLint width_minus_1 = img->Width - 1; - const GLint height_minus_1 = img->Height - 1; + const GLint width = img->Width; + const GLint height = img->Height; GLuint i; (void) ctx; @@ -2106,7 +2097,7 @@ sample_nearest_rect(GLcontext *ctx, GLint row, col; col = clamp_rect_coord_nearest(tObj->WrapS, texcoords[i][0], width); row = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height); - if (col < 0 || col > width_minus_1 || row < 0 || row > height_minus_1) + if (col < 0 || col >= width || row < 0 || row >= height) COPY_CHAN4(rgba[i], tObj->_BorderChan); else img->FetchTexelc(img, col, row, 0, rgba[i]); @@ -2121,10 +2112,8 @@ sample_linear_rect(GLcontext *ctx, const GLfloat lambda[], GLchan rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][0]; - const GLfloat width = (GLfloat) img->Width; - const GLfloat height = (GLfloat) img->Height; - const GLint width_minus_1 = img->Width - 1; - const GLint height_minus_1 = img->Height - 1; + const GLint width = img->Width; + const GLint height = img->Height; GLuint i; (void) ctx; @@ -2138,64 +2127,22 @@ sample_linear_rect(GLcontext *ctx, tObj->WrapT == GL_CLAMP_TO_BORDER); ASSERT(img->TexFormat->BaseFormat != GL_COLOR_INDEX); - /* XXX lots of opportunity for optimization in this loop */ for (i = 0; i < n; i++) { - GLfloat frow, fcol; GLint i0, j0, i1, j1; GLchan t00[4], t01[4], t10[4], t11[4]; GLfloat a, b; GLbitfield useBorderColor = 0x0; - /* NOTE: we DO NOT use [0, 1] texture coordinates! */ - if (tObj->WrapS == GL_CLAMP) { - /* Not exactly what the spec says, but it matches NVIDIA output */ - fcol = CLAMP(texcoords[i][0] - 0.5F, 0.0, width_minus_1); - i0 = IFLOOR(fcol); - i1 = i0 + 1; - } - else if (tObj->WrapS == GL_CLAMP_TO_EDGE) { - fcol = CLAMP(texcoords[i][0], 0.5F, width - 0.5F); - fcol -= 0.5F; - i0 = IFLOOR(fcol); - i1 = i0 + 1; - if (i1 > width_minus_1) - i1 = width_minus_1; - } - else { - ASSERT(tObj->WrapS == GL_CLAMP_TO_BORDER); - fcol = CLAMP(texcoords[i][0], -0.5F, width + 0.5F); - fcol -= 0.5F; - i0 = IFLOOR(fcol); - i1 = i0 + 1; - } - - if (tObj->WrapT == GL_CLAMP) { - /* Not exactly what the spec says, but it matches NVIDIA output */ - frow = CLAMP(texcoords[i][1] - 0.5F, 0.0, width_minus_1); - j0 = IFLOOR(frow); - j1 = j0 + 1; - } - else if (tObj->WrapT == GL_CLAMP_TO_EDGE) { - frow = CLAMP(texcoords[i][1], 0.5F, height - 0.5F); - frow -= 0.5F; - j0 = IFLOOR(frow); - j1 = j0 + 1; - if (j1 > height_minus_1) - j1 = height_minus_1; - } - else { - ASSERT(tObj->WrapT == GL_CLAMP_TO_BORDER); - frow = CLAMP(texcoords[i][1], -0.5F, height + 0.5F); - frow -= 0.5F; - j0 = IFLOOR(frow); - j1 = j0 + 1; - } + clamp_rect_coord_linear(tObj->WrapS, texcoords[i][0], width, + &i0, &i1, &a); + clamp_rect_coord_linear(tObj->WrapT, texcoords[i][1], height, + &j0, &j1, &b); /* compute integer rows/columns */ - if (i0 < 0 || i0 > width_minus_1) useBorderColor |= I0BIT; - if (i1 < 0 || i1 > width_minus_1) useBorderColor |= I1BIT; - if (j0 < 0 || j0 > height_minus_1) useBorderColor |= J0BIT; - if (j1 < 0 || j1 > height_minus_1) useBorderColor |= J1BIT; + if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; + if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; + if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; + if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; /* get four texel samples */ if (useBorderColor & (I0BIT | J0BIT)) @@ -2218,20 +2165,17 @@ sample_linear_rect(GLcontext *ctx, else img->FetchTexelc(img, i1, j1, 0, t11); - /* compute interpolants */ - a = FRAC(fcol); - b = FRAC(frow); - lerp_rgba_2d(rgba[i], a, b, t00, t10, t01, t11); } } +/** Sample Rect texture, using lambda to choose between min/magnification */ static void -sample_lambda_rect( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) +sample_lambda_rect(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) { GLuint minStart, minEnd, magStart, magEnd; @@ -2243,22 +2187,22 @@ sample_lambda_rect( GLcontext *ctx, if (minStart < minEnd) { if (tObj->MinFilter == GL_NEAREST) { - sample_nearest_rect( ctx, tObj, minEnd - minStart, - texcoords + minStart, NULL, rgba + minStart); + sample_nearest_rect(ctx, tObj, minEnd - minStart, + texcoords + minStart, NULL, rgba + minStart); } else { - sample_linear_rect( ctx, tObj, minEnd - minStart, - texcoords + minStart, NULL, rgba + minStart); + sample_linear_rect(ctx, tObj, minEnd - minStart, + texcoords + minStart, NULL, rgba + minStart); } } if (magStart < magEnd) { if (tObj->MagFilter == GL_NEAREST) { - sample_nearest_rect( ctx, tObj, magEnd - magStart, - texcoords + magStart, NULL, rgba + magStart); + sample_nearest_rect(ctx, tObj, magEnd - magStart, + texcoords + magStart, NULL, rgba + magStart); } else { - sample_linear_rect( ctx, tObj, magEnd - magStart, - texcoords + magStart, NULL, rgba + magStart); + sample_linear_rect(ctx, tObj, magEnd - magStart, + texcoords + magStart, NULL, rgba + magStart); } } } @@ -2269,7 +2213,7 @@ sample_lambda_rect( GLcontext *ctx, /* 2D Texture Array Sampling Functions */ /**********************************************************************/ -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. */ static void @@ -2286,8 +2230,8 @@ sample_2d_array_nearest(GLcontext *ctx, GLint array; (void) ctx; - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j); + i = nearest_texel_location(tObj->WrapS, img, width, texcoord[0]); + j = nearest_texel_location(tObj->WrapT, img, height, texcoord[1]); array = clamp_rect_coord_nearest(tObj->WrapR, texcoord[2], depth); if (i < 0 || i >= (GLint) img->Width || @@ -2302,8 +2246,7 @@ sample_2d_array_nearest(GLcontext *ctx, } - -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. */ static void @@ -2319,12 +2262,11 @@ sample_2d_array_linear(GLcontext *ctx, GLint i0, j0, i1, j1; GLint array; GLbitfield useBorderColor = 0x0; - GLfloat u, v; GLfloat a, b; GLchan t00[4], t01[4], t10[4], t11[4]; - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1); + linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); + linear_texel_locations(tObj->WrapT, img, height, texcoord[1], &j0, &j1, &b); array = clamp_rect_coord_nearest(tObj->WrapR, texcoord[2], depth); if (array < 0 || array >= depth) { @@ -2372,19 +2314,16 @@ sample_2d_array_linear(GLcontext *ctx, } /* trilinear interpolation of samples */ - a = FRAC(u); - b = FRAC(v); lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); } } - static void sample_2d_array_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4] ) + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; for (i = 0; i < n; i++) { @@ -2428,8 +2367,10 @@ sample_2d_array_nearest_mipmap_linear(GLcontext *ctx, else { GLchan t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); - sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); - sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); + sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level ], + texcoord[i], t0); + sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level+1], + texcoord[i], t1); lerp_rgba(rgba[i], f, t0, t1); } } @@ -2438,9 +2379,9 @@ sample_2d_array_nearest_mipmap_linear(GLcontext *ctx, static void sample_2d_array_linear_mipmap_linear(GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoord[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -2453,30 +2394,34 @@ sample_2d_array_linear_mipmap_linear(GLcontext *ctx, else { GLchan t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); - sample_2d_array_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); - sample_2d_array_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); + sample_2d_array_linear(ctx, tObj, tObj->Image[0][level ], + texcoord[i], t0); + sample_2d_array_linear(ctx, tObj, tObj->Image[0][level+1], + texcoord[i], t1); lerp_rgba(rgba[i], f, t0, t1); } } } +/** Sample 2D Array texture, nearest filtering for both min/magnification */ static void sample_nearest_2d_array(GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_2d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]); } } +/** Sample 2D Array texture, linear filtering for both min/magnification */ static void sample_linear_2d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -2486,16 +2431,13 @@ sample_linear_2d_array(GLcontext *ctx, GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_2d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]); } } -/* - * Given an (s,t,r) texture coordinate and lambda (level of detail) value, - * return a texture sample. - */ +/** Sample 2D Array texture, using lambda to choose between min/magnification */ static void sample_lambda_2d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -2525,8 +2467,10 @@ sample_lambda_2d_array(GLcontext *ctx, texcoords[i], rgba[i]); break; case GL_NEAREST_MIPMAP_NEAREST: - sample_2d_array_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); + sample_2d_array_nearest_mipmap_nearest(ctx, tObj, m, + texcoords + minStart, + lambda + minStart, + rgba + minStart); break; case GL_LINEAR_MIPMAP_NEAREST: sample_2d_array_linear_mipmap_nearest(ctx, tObj, m, @@ -2535,8 +2479,10 @@ sample_lambda_2d_array(GLcontext *ctx, rgba + minStart); break; case GL_NEAREST_MIPMAP_LINEAR: - sample_2d_array_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); + sample_2d_array_nearest_mipmap_linear(ctx, tObj, m, + texcoords + minStart, + lambda + minStart, + rgba + minStart); break; case GL_LINEAR_MIPMAP_LINEAR: sample_2d_array_linear_mipmap_linear(ctx, tObj, m, @@ -2577,7 +2523,7 @@ sample_lambda_2d_array(GLcontext *ctx, /* 1D Texture Array Sampling Functions */ /**********************************************************************/ -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. */ static void @@ -2593,7 +2539,7 @@ sample_1d_array_nearest(GLcontext *ctx, GLint array; (void) ctx; - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i); + i = nearest_texel_location(tObj->WrapS, img, width, texcoord[0]); array = clamp_rect_coord_nearest(tObj->WrapT, texcoord[1], height); if (i < 0 || i >= (GLint) img->Width || @@ -2607,8 +2553,7 @@ sample_1d_array_nearest(GLcontext *ctx, } - -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. */ static void @@ -2623,11 +2568,10 @@ sample_1d_array_linear(GLcontext *ctx, GLint i0, i1; GLint array; GLbitfield useBorderColor = 0x0; - GLfloat u; GLfloat a; GLchan t0[4], t1[4]; - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1); + linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); array = clamp_rect_coord_nearest(tObj->WrapT, texcoord[1], height); if (img->Border) { @@ -2657,17 +2601,15 @@ sample_1d_array_linear(GLcontext *ctx, } /* bilinear interpolation of samples */ - a = FRAC(u); lerp_rgba(rgba, a, t0, t1); } - static void sample_1d_array_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4] ) + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; for (i = 0; i < n; i++) { @@ -2721,9 +2663,9 @@ sample_1d_array_nearest_mipmap_linear(GLcontext *ctx, static void sample_1d_array_linear_mipmap_linear(GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoord[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -2744,22 +2686,23 @@ sample_1d_array_linear_mipmap_linear(GLcontext *ctx, } +/** Sample 1D Array texture, nearest filtering for both min/magnification */ static void sample_nearest_1d_array(GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_1d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]); } } - +/** Sample 1D Array texture, linear filtering for both min/magnification */ static void sample_linear_1d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -2769,16 +2712,13 @@ sample_linear_1d_array(GLcontext *ctx, GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_1d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]); } } -/* - * Given an (s,t,r) texture coordinate and lambda (level of detail) value, - * return a texture sample. - */ +/** Sample 1D Array texture, using lambda to choose between min/magnification */ static void sample_lambda_1d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -2854,9 +2794,7 @@ sample_lambda_1d_array(GLcontext *ctx, } - - -/* +/** * Sample a shadow/depth texture. */ static void @@ -2906,31 +2844,32 @@ sample_depth_texture( GLcontext *ctx, break; case GL_TEXTURE_1D: - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0], - width, col); + col = nearest_texel_location(tObj->WrapS, img, width, + texcoords[i][0]); row = 0; slice = 0; break; case GL_TEXTURE_2D: - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0], - width, col); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoords[i][1], - height, row); + col = nearest_texel_location(tObj->WrapS, img, width, + texcoords[i][0]); + row = nearest_texel_location(tObj->WrapT, img, height, + texcoords[i][1]); slice = 0; break; case GL_TEXTURE_1D_ARRAY_EXT: - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0], - width, col); + col = nearest_texel_location(tObj->WrapS, img, width, + texcoords[i][0]); row = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height); slice = 0; + break; case GL_TEXTURE_2D_ARRAY_EXT: - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0], - width, col); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoords[i][1], - height, row); + col = nearest_texel_location(tObj->WrapS, img, width, + texcoords[i][0]); + row = nearest_texel_location(tObj->WrapT, img, height, + texcoords[i][1]); slice = clamp_rect_coord_nearest(tObj->WrapR, texcoords[i][2], depth); break; } @@ -3007,39 +2946,40 @@ sample_depth_texture( GLcontext *ctx, GLfloat depth00, depth01, depth10, depth11; GLint i0, i1, j0, j1; GLint slice; - GLfloat u, v; + GLfloat a, b; GLuint useBorderTexel; switch (tObj->Target) { case GL_TEXTURE_RECTANGLE_ARB: clamp_rect_coord_linear(tObj->WrapS, texcoords[i][0], - width, &i0, &i1); + width, &i0, &i1, &a); clamp_rect_coord_linear(tObj->WrapT, texcoords[i][1], - height, &j0, &j1); + height, &j0, &j1, &b); slice = 0; break; case GL_TEXTURE_1D: case GL_TEXTURE_2D: - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0], - u, width, i0, i1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoords[i][1], - v, height,j0, j1); + linear_texel_locations(tObj->WrapS, img, width, + texcoords[i][0], &i0, &i1, &a); + linear_texel_locations(tObj->WrapT, img, height, + texcoords[i][1], &j0, &j1, &b); slice = 0; break; case GL_TEXTURE_1D_ARRAY_EXT: - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0], - u, width, i0, i1); + linear_texel_locations(tObj->WrapS, img, width, + texcoords[i][0], &i0, &i1, &a); j0 = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height); j1 = j0; slice = 0; + break; case GL_TEXTURE_2D_ARRAY_EXT: - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0], - u, width, i0, i1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoords[i][1], - v, height,j0, j1); + linear_texel_locations(tObj->WrapS, img, width, + texcoords[i][0], &i0, &i1, &a); + linear_texel_locations(tObj->WrapT, img, height, + texcoords[i][1], &j0, &j1, &b); slice = clamp_rect_coord_nearest(tObj->WrapR, texcoords[i][2], depth); break; } @@ -3103,8 +3043,6 @@ sample_depth_texture( GLcontext *ctx, if (0) { /* compute a single weighted depth sample and do one comparison */ - const GLfloat a = FRAC(u + 1.0F); - const GLfloat b = FRAC(v + 1.0F); const GLfloat depthSample = lerp_2d(a, b, depth00, depth10, depth01, depth11); if ((depthSample <= texcoords[i][compare_coord] && function == GL_LEQUAL) || @@ -3175,8 +3113,6 @@ sample_depth_texture( GLcontext *ctx, case GL_NONE: /* ordinary bilinear filtering */ { - const GLfloat a = FRAC(u + 1.0F); - const GLfloat b = FRAC(v + 1.0F); const GLfloat depthSample = lerp_2d(a, b, depth00, depth10, depth01, depth11); CLAMPED_FLOAT_TO_CHAN(result, depthSample); @@ -3270,10 +3206,10 @@ sample_depth_texture2(const GLcontext *ctx, GLint col, row, ii, jj, imin, imax, jmin, jmax, samples, count; GLfloat w; GLchan lum; - COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, texcoords[i][0], - width, col); - COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, texcoords[i][1], - height, row); + col = nearest_texel_location(texObj->WrapS, img, width, + texcoords[i][0]); + row = nearest_texel_location(texObj->WrapT, img, height, + texcoords[i][1]); imin = col - K; imax = col + K; |