From 20555835b68c58b52d7954a0b237a9a331013e68 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 17 Dec 2008 14:54:46 -0700 Subject: mesa: updated comments --- src/mesa/main/mtypes.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 9b40d8fb6c..5ed73b7d0e 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -7,7 +7,7 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.3 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -1957,14 +1957,15 @@ struct gl_program_state */ struct gl_vertex_program_state { - GLboolean Enabled; /**< GL_VERTEX_PROGRAM_ARB/NV */ - GLboolean _Enabled; /**< Enabled and valid program? */ + GLboolean Enabled; /**< User-set GL_VERTEX_PROGRAM_ARB/NV flag */ + GLboolean _Enabled; /**< Enabled and _valid_ user program? */ GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */ GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */ - struct gl_vertex_program *Current; /**< user-bound vertex program */ + struct gl_vertex_program *Current; /**< User-bound vertex program */ - /** Currently enabled and valid program (including internal programs - * and compiled shader programs). + /** Currently enabled and valid vertex program (including internal programs, + * user-defined vertex programs and GLSL vertex shaders). + * This is the program we must use when rendering. */ struct gl_vertex_program *_Current; @@ -1998,12 +1999,12 @@ struct gl_vertex_program_state struct gl_fragment_program_state { GLboolean Enabled; /**< User-set fragment program enable flag */ - GLboolean _Enabled; /**< Fragment program enabled and valid? */ - GLboolean _Active; + GLboolean _Enabled; /**< Enabled and _valid_ user program? */ struct gl_fragment_program *Current; /**< User-bound fragment program */ - /** Currently enabled and valid program (including internal programs - * and compiled shader programs). + /** Currently enabled and valid fragment program (including internal programs, + * user-defined fragment programs and GLSL fragment shaders). + * This is the program we must use when rendering. */ struct gl_fragment_program *_Current; @@ -2012,6 +2013,7 @@ struct gl_fragment_program_state /** Should fixed-function texturing be implemented with a fragment prog? */ GLboolean _MaintainTexEnvProgram; GLboolean _UseTexEnvProgram; + GLboolean _Active; /**< Use internal texenv program? */ /** Program to emulate fixed-function texture env/combine (see above) */ struct gl_fragment_program *_TexEnvProgram; -- cgit v1.2.3 From 35aebf46679a6450b912b592b83badcfb523b79c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 17 Dec 2008 18:05:03 -0700 Subject: mesa: remove unneeded _mesa_reference_fragprog() call The subsequent if/else cases always call _mesa_reference_fragprog() anyway. --- src/mesa/main/state.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index e87a62f59d..df1d197858 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -190,8 +190,8 @@ update_program(GLcontext *ctx) /* * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current - * pointers to the programs that should be enabled/used. These will only - * be NULL if we need to use the fixed-function code. + * pointers to the programs that should be used for rendering. If either + * is NULL, use fixed-function code paths. * * These programs may come from several sources. The priority is as * follows: @@ -204,8 +204,6 @@ update_program(GLcontext *ctx) * come up, or matter. */ - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); - if (shProg && shProg->LinkStatus && shProg->FragmentProgram) { /* Use shader programs */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, -- cgit v1.2.3 From df73363ed1aa34cc0dc5feefb3933309591fa015 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 18 Dec 2008 10:07:45 +0800 Subject: i915: fix abort issue. (bug #19147) --- src/mesa/drivers/dri/i915/i830_vtbl.c | 15 +++++++++++++-- src/mesa/drivers/dri/i915/i915_vtbl.c | 13 +++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index 3b3ff2bced..8fc8aa5f90 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -297,7 +297,7 @@ i830_emit_invarient_state(struct intel_context *intel) { BATCH_LOCALS; - BEGIN_BATCH(40, IGNORE_CLIPRECTS); + BEGIN_BATCH(30, IGNORE_CLIPRECTS); OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); OUT_BATCH(0); @@ -491,8 +491,17 @@ i830_emit_state(struct intel_context *intel) } if (dirty & I830_UPLOAD_BUFFERS) { + GLuint count = 9; + DBG("I830_UPLOAD_BUFFERS:\n"); - BEGIN_BATCH(I830_DEST_SETUP_SIZE + 2, IGNORE_CLIPRECTS); + + if (state->depth_region) + count += 3; + + if (intel->constant_cliprect) + count += 6; + + BEGIN_BATCH(count, IGNORE_CLIPRECTS); OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR0]); OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]); OUT_RELOC(state->draw_region->buffer, @@ -557,6 +566,8 @@ i830_emit_state(struct intel_context *intel) OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S4]); OUT_BATCH(state->Tex[i][I830_TEXREG_MCS]); OUT_BATCH(state->Tex[i][I830_TEXREG_CUBE]); + + ADVANCE_BATCH(); } if (dirty & I830_UPLOAD_TEXBLEND(i)) { diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index e79c955d64..3f6d282d34 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -173,7 +173,7 @@ i915_emit_invarient_state(struct intel_context *intel) { BATCH_LOCALS; - BEGIN_BATCH(200, IGNORE_CLIPRECTS); + BEGIN_BATCH(20, IGNORE_CLIPRECTS); OUT_BATCH(_3DSTATE_AA_CMD | AA_LINE_ECAAR_WIDTH_ENABLE | @@ -376,9 +376,18 @@ i915_emit_state(struct intel_context *intel) } if (dirty & I915_UPLOAD_BUFFERS) { + GLuint count = 9; + if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); - BEGIN_BATCH(I915_DEST_SETUP_SIZE + 2, IGNORE_CLIPRECTS); + + if (state->depth_region) + count += 3; + + if (intel->constant_cliprect) + count += 6; + + BEGIN_BATCH(count, IGNORE_CLIPRECTS); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); OUT_RELOC(state->draw_region->buffer, -- cgit v1.2.3 From cb453244caa15342bf229ee5ae16a78d038b8bdc Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 18 Dec 2008 12:57:41 +0800 Subject: i915: check WRAP_T instead of WRAP_R for cube map texture. --- src/mesa/drivers/dri/i915/i915_texstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index d53e2cbd5a..adbb52a3a3 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -300,7 +300,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) */ if (tObj->Target == GL_TEXTURE_CUBE_MAP_ARB && (((ws != GL_CLAMP) && (ws != GL_CLAMP_TO_EDGE)) || - ((wr != GL_CLAMP) && (wr != GL_CLAMP_TO_EDGE)))) + ((wt != GL_CLAMP) && (wt != GL_CLAMP_TO_EDGE)))) return GL_FALSE; state[I915_TEXREG_SS3] = ss3; /* SS3_NORMALIZED_COORDS */ -- cgit v1.2.3 From d9b92b112fb64005c71edf1158f7dffabc4659bb Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 18 Dec 2008 18:45:32 +0100 Subject: glsl: Fix handling of nested parens in macro actual arguments. --- src/mesa/shader/slang/slang_preprocess.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/shader/slang/slang_preprocess.c b/src/mesa/shader/slang/slang_preprocess.c index 786f6467c9..7d971627f5 100644 --- a/src/mesa/shader/slang/slang_preprocess.c +++ b/src/mesa/shader/slang/slang_preprocess.c @@ -641,8 +641,10 @@ expand_symbol (expand_state *e, pp_symbol *symbol) SKIP_WHITE(e->input); /* Parse macro actual parameters. This can be anything, separated by a colon. - * TODO: What about nested/grouped parameters by parenthesis? */ + */ for (i = 0; i < symbol->parameters.count; i++) { + GLuint nested_paren_count = 0; /* track number of nested parentheses */ + if (*e->input == ')') { slang_info_log_error (e->state->elog, "preprocess error: unexpected ')'."); return GL_FALSE; @@ -650,8 +652,19 @@ expand_symbol (expand_state *e, pp_symbol *symbol) /* Eat all characters up to the comma or closing parentheses. */ pp_symbol_reset (&symbol->parameters.symbols[i]); - while (!IS_NULL(*e->input) && *e->input != ',' && *e->input != ')') + while (!IS_NULL(*e->input)) { + /* Exit loop only when all nested parens have been eaten. */ + if (nested_paren_count == 0 && (*e->input == ',' || *e->input == ')')) + break; + + /* Actually count nested parens here. */ + if (*e->input == '(') + nested_paren_count++; + else if (*e->input == ')') + nested_paren_count--; + slang_string_pushc (&symbol->parameters.symbols[i].replacement, *e->input++); + } /* If it was not the last paremeter, skip the comma. Otherwise, skip the * closing parentheses. */ -- cgit v1.2.3 From aa09e0a1d532d0de2e094957d0509a7f60ebeafa Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Dec 2008 18:23:51 -0800 Subject: mesa: Correct _mesa_clip_to_region() off-by-one. Note how if: x + width == xmax + 0: width -= 0 x + width == xmax + 1: width -= 0 x + width == xmax + 2: width -= 1 So, the function was clipping to [xmin, xmax+1), not [xmin, xmax) like it was supposed to. Same for ymax. --- src/mesa/main/image.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 4551b4a3b5..6b19fc8454 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -5152,7 +5152,7 @@ _mesa_clip_to_region(GLint xmin, GLint ymin, /* right clipping */ if (*x + *width > xmax) - *width -= (*x + *width - xmax - 1); + *width -= (*x + *width - xmax); if (*width <= 0) return GL_FALSE; @@ -5165,7 +5165,7 @@ _mesa_clip_to_region(GLint xmin, GLint ymin, /* top (or bottom) clipping */ if (*y + *height > ymax) - *height -= (*y + *height - ymax - 1); + *height -= (*y + *height - ymax); if (*height <= 0) return GL_FALSE; -- cgit v1.2.3 From d01c44aacaeabe1dd187163f9e204f40401698bc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Dec 2008 18:31:25 -0800 Subject: mesa: Clip copytexsubimage to read framebuffer bounds, not scissor region. --- src/mesa/main/image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 6b19fc8454..c205b4b766 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -5119,7 +5119,7 @@ _mesa_clip_copytexsubimage(const GLcontext *ctx, const struct gl_framebuffer *fb = ctx->ReadBuffer; const GLint srcX0 = *srcX, srcY0 = *srcY; - if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax, + if (_mesa_clip_to_region(0, 0, fb->Width, fb->Height, srcX, srcY, width, height)) { *destX = *destX + *srcX - srcX0; *destY = *destY + *srcY - srcY0; -- cgit v1.2.3 From 1e7785fe0721f66ca9523da0dc338d26256736bb Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Dec 2008 18:42:06 -0800 Subject: intel: Move copyteximage source clipping out of copytexsubimage. glCopyTexSubImage already gets the (correct) clipping for us, so it doesn't need the path. While moving the clipping out, replace the code with the mesa path to do the same job. --- src/mesa/drivers/dri/intel/intel_tex_copy.c | 109 ++++++++++++++++------------ 1 file changed, 61 insertions(+), 48 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index b893990d27..08437aa0e2 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -112,56 +112,47 @@ do_copy_texsubimage(struct intel_context *intel, intelImage->level); const GLint orig_x = x; const GLint orig_y = y; - const struct gl_framebuffer *fb = ctx->DrawBuffer; - - if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax, - &x, &y, &width, &height)) { - GLshort src_pitch; - - /* Update dst for clipped src. Need to also clip the source rect. - */ - dstx += x - orig_x; - dsty += y - orig_y; - - /* image_offset may be non-page-aligned, but that's illegal for tiling. + GLshort src_pitch; + + /* Update dst for clipped src. Need to also clip the source rect. */ + dstx += x - orig_x; + dsty += y - orig_y; + + /* image_offset may be non-page-aligned, but that's illegal for tiling. */ + assert(intelImage->mt->region->tiling == I915_TILING_NONE); + + if (ctx->ReadBuffer->Name == 0) { + /* reading from a window, adjust x, y */ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + y = dPriv->y + (dPriv->h - (y + height)); + x += dPriv->x; + + /* Invert the data coming from the source rectangle due to GL + * and hardware disagreeing on where y=0 is. + * + * It appears that our offsets and pitches get mangled + * appropriately by the hardware, and we don't need to adjust them + * on our own. */ - assert(intelImage->mt->region->tiling == I915_TILING_NONE); - - if (ctx->ReadBuffer->Name == 0) { - /* reading from a window, adjust x, y */ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - y = dPriv->y + (dPriv->h - (y + height)); - x += dPriv->x; - - /* Invert the data coming from the source rectangle due to GL - * and hardware disagreeing on where y=0 is. - * - * It appears that our offsets and pitches get mangled - * appropriately by the hardware, and we don't need to adjust them - * on our own. - */ - src_pitch = -src->pitch; - } - else { - /* reading from a FBO, y is already oriented the way we like */ - src_pitch = src->pitch; - } - - intelEmitCopyBlit(intel, - intelImage->mt->cpp, - src_pitch, - src->buffer, - 0, - src->tiling, - intelImage->mt->pitch, - intelImage->mt->region->buffer, - image_offset, - intelImage->mt->region->tiling, - x, y, dstx, dsty, width, height, - GL_COPY); + src_pitch = -src->pitch; + } else { + /* reading from a FBO, y is already oriented the way we like */ + src_pitch = src->pitch; } - } + intelEmitCopyBlit(intel, + intelImage->mt->cpp, + src_pitch, + src->buffer, + 0, + src->tiling, + intelImage->mt->pitch, + intelImage->mt->region->buffer, + image_offset, + intelImage->mt->region->tiling, + x, y, dstx, dsty, width, height, + GL_COPY); + } UNLOCK_HARDWARE(intel); @@ -188,6 +179,7 @@ intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, _mesa_select_tex_object(ctx, texUnit, target); struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texObj, target, level); + int srcx, srcy, dstx, dsty, height; if (border) goto fail; @@ -199,10 +191,20 @@ intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, width, border, GL_RGBA, CHAN_TYPE, NULL, &ctx->DefaultPacking, texObj, texImage); + srcx = x; + srcy = y; + dstx = 0; + dsty = 0; + height = 1; + if (!_mesa_clip_copytexsubimage(ctx, + &dstx, &dsty, + &srcx, &srcy, + &width, &height)) + return; if (!do_copy_texsubimage(intel_context(ctx), target, intel_texture_image(texImage), - internalFormat, 0, 0, x, y, width, 1)) + internalFormat, 0, 0, x, y, width, height)) goto fail; return; @@ -224,10 +226,21 @@ intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, _mesa_select_tex_object(ctx, texUnit, target); struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texObj, target, level); + int srcx, srcy, dstx, dsty; if (border) goto fail; + srcx = x; + srcy = y; + dstx = 0; + dsty = 0; + if (!_mesa_clip_copytexsubimage(ctx, + &dstx, &dsty, + &srcx, &srcy, + &width, &height)) + return; + /* Setup or redefine the texture object, mipmap tree and texture * image. Don't populate yet. */ -- cgit v1.2.3 From d091ebd4e41c88fe53db9d52842aaa20d23b995d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 17 Dec 2008 21:18:00 -0800 Subject: intel: don't clip to scissor-clipped read framebuffer bounds in copypixels. --- src/mesa/drivers/dri/intel/intel_pixel_copy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c index 61d1296c26..1505af2286 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c @@ -308,8 +308,8 @@ do_blit_copypixels(GLcontext * ctx, /* Clip to source buffer. */ orig_srcx = srcx; orig_srcy = srcy; - if (!_mesa_clip_to_region(read_fb->_Xmin, read_fb->_Ymin, - read_fb->_Xmax, read_fb->_Ymax, + if (!_mesa_clip_to_region(0, 0, + read_fb->Width, read_fb->Height, &srcx, &srcy, &width, &height)) goto out; /* Adjust dst coords for our post-clipped source origin */ -- cgit v1.2.3 From b9752a2bd615d136369af63ed3d45cc10adf21e7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 17 Dec 2008 21:18:20 -0800 Subject: intel: Update mesa state in blit operations that want post-scissor draw bounds. --- src/mesa/drivers/dri/intel/intel_pixel_bitmap.c | 4 ++++ src/mesa/drivers/dri/intel/intel_pixel_copy.c | 3 +++ 2 files changed, 7 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index e3ce1494e5..fd2ea7989e 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -32,6 +32,7 @@ #include "main/mtypes.h" #include "main/macros.h" #include "main/bufferobj.h" +#include "main/state.h" #include "swrast/swrast.h" #include "intel_screen.h" @@ -172,6 +173,9 @@ do_blit_bitmap( GLcontext *ctx, drm_clip_rect_t *cliprects; int x_off, y_off; + /* Update draw buffer bounds */ + _mesa_update_state(ctx); + if (!dst) return GL_FALSE; diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c index 1505af2286..447c6494e7 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c @@ -266,6 +266,9 @@ do_blit_copypixels(GLcontext * ctx, drm_clip_rect_t *cliprects; int x_off, y_off; + /* Update draw buffer bounds */ + _mesa_update_state(ctx); + /* Copypixels can be more than a straight copy. Ensure all the * extra operations are disabled: */ -- cgit v1.2.3 From e67350da34c6009edff50c160df27493cb363e1b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 17 Dec 2008 22:10:57 -0800 Subject: intel: Don't forget the source bitmap size when clipping the size we draw. --- src/mesa/drivers/dri/intel/intel_pixel_bitmap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index fd2ea7989e..f6713dbc7b 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -172,6 +172,8 @@ do_blit_bitmap( GLcontext *ctx, unsigned int num_cliprects; drm_clip_rect_t *cliprects; int x_off, y_off; + GLsizei bitmap_width = width; + GLsizei bitmap_height = height; /* Update draw buffer bounds */ _mesa_update_state(ctx); @@ -278,7 +280,7 @@ do_blit_bitmap( GLcontext *ctx, /* May need to adjust this when padding has been introduced in * sz above: */ - if (get_bitmap_rect(width, height, unpack, + if (get_bitmap_rect(bitmap_width, bitmap_height, unpack, bitmap, srcx + px, srcy + py, w, h, (GLubyte *)stipple, -- cgit v1.2.3 From 1db63713046efd49071aae448105df8a80e1e83d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Dec 2008 16:00:09 -0800 Subject: intel: Fix glBitmap top/bottom clipping. Bug #19139. --- src/mesa/drivers/dri/intel/intel_pixel_bitmap.c | 75 ++++++++++++------------- 1 file changed, 35 insertions(+), 40 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index f6713dbc7b..fb1a051cdc 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -150,8 +150,18 @@ static GLuint get_bitmap_rect(GLsizei width, GLsizei height, return count; } - - +/** + * Returns the low Y value of the vertical range given, flipped according to + * whether the framebuffer is or not. + */ +static inline int +y_flip(struct gl_framebuffer *fb, int y, int height) +{ + if (fb->Name != 0) + return y; + else + return fb->Height - y - height; +} /* * Render a bitmap. @@ -208,8 +218,6 @@ do_blit_bitmap( GLcontext *ctx, intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); if (num_cliprects != 0) { - drm_clip_rect_t dest_rect; - GLint srcx = 0, srcy = 0; GLuint i; GLint orig_dstx = dstx; GLint orig_dsty = dsty; @@ -220,45 +228,26 @@ do_blit_bitmap( GLcontext *ctx, &dstx, &dsty, &width, &height)) goto out; - /* Convert from GL to hardware coordinates. Transform original points - * along with it so that we can look at cliprects in hw coordinates and - * map back to points in the source space. - */ - if (fb->Name == 0) { - /* bitmap to a system framebuffer */ - dstx = x_off + dstx; - dsty = y_off + (fb->Height - dsty - height); - orig_dstx = x_off + orig_dstx; - orig_dsty = y_off + (fb->Height - orig_dsty - height); - } else { - /* bitmap to a user framebuffer object */ - dstx = x_off + dstx; - dsty = y_off + dsty; - orig_dstx = x_off + orig_dstx; - orig_dsty = y_off + orig_dsty; - } - - dest_rect.x1 = dstx; - dest_rect.y1 = dsty; - dest_rect.x2 = dstx + width; - dest_rect.y2 = dsty + height; + dstx = x_off + dstx; + dsty = y_off + y_flip(fb, dsty, height); for (i = 0; i < num_cliprects; i++) { - drm_clip_rect_t rect; - int box_w, box_h; + int box_x, box_y, box_w, box_h; GLint px, py; GLuint stipple[32]; - if (!intel_intersect_cliprects(&rect, &dest_rect, &cliprects[i])) - continue; + box_x = dstx; + box_y = dsty; + box_w = width; + box_h = height; - /* Now go back to GL coordinates to figure out what subset of - * the bitmap we are uploading for this cliprect: - */ - box_w = rect.x2 - rect.x1; - box_h = rect.y2 - rect.y1; - srcx = rect.x1 - orig_dstx; - srcy = rect.y1 - orig_dsty; + /* Clip to drawable cliprect */ + if (!_mesa_clip_to_region(cliprects[i].x1, + cliprects[i].y1, + cliprects[i].x2 - cliprects[i].x1, + cliprects[i].y2 - cliprects[i].y1, + &box_x, &box_y, &box_w, &box_h)) + continue; #define DY 32 #define DX 32 @@ -279,10 +268,16 @@ do_blit_bitmap( GLcontext *ctx, /* May need to adjust this when padding has been introduced in * sz above: + * + * Have to translate destination coordinates back into source + * coordinates. */ if (get_bitmap_rect(bitmap_width, bitmap_height, unpack, bitmap, - srcx + px, srcy + py, w, h, + -orig_dstx + (box_x + px - x_off), + -orig_dsty + y_flip(fb, + box_y + py - y_off, h), + w, h, (GLubyte *)stipple, 8, fb->Name == 0 ? GL_TRUE : GL_FALSE) == 0) @@ -299,8 +294,8 @@ do_blit_bitmap( GLcontext *ctx, dst->buffer, 0, dst->tiling, - rect.x1 + px, - rect.y2 - (py + h), + box_x + px, + box_y + py, w, h, logic_op); } -- cgit v1.2.3 From 962fa6bbc16abf2b9829bd0b761d9baa9d01fd1e Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 18 Dec 2008 14:11:06 -0800 Subject: GLSL: The LOG2 macro doesn't have enough precision It looks like the LOG2 macro only has 8 or 9 bits of precission, but the ARB_vertex_program spec says "accurate to at least 10 bits". --- src/mesa/shader/prog_execute.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 8163ae6a6f..a93733c085 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -963,7 +963,10 @@ _mesa_execute_program(GLcontext * ctx, { GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); - result[0] = result[1] = result[2] = result[3] = LOG2(a[0]); + /* The fast LOG2 macro doesn't meet the precision requirements. + */ + result[0] = result[1] = result[2] = result[3] = + (log(a[0]) * 1.442695F); store_vector4(inst, machine, result); } break; @@ -1022,7 +1025,11 @@ _mesa_execute_program(GLcontext * ctx, GLfloat mantissa = FREXPF(t[0], &exponent); q[0] = (GLfloat) (exponent - 1); q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */ - q[2] = (GLfloat) (q[0] + LOG2(q[1])); + + /* The fast LOG2 macro doesn't meet the precision + * requirements. + */ + q[2] = (log(t[0]) * 1.442695F); } } else { -- cgit v1.2.3 From 7e04272690e8d9deecc0bf71c37bfa4c321ae6ab Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 18 Dec 2008 14:13:26 -0800 Subject: 965 / GLSL: Use full precision for EXP instruction The partial precision mode doesn't have quite enough bits of precision to pass conformance tests. --- src/mesa/drivers/dri/i965/brw_vs_emit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 25b4ee85cb..4a9541378f 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -420,7 +420,7 @@ static void emit_exp_noalias( struct brw_vs_compile *c, BRW_MATH_FUNCTION_EXP, brw_writemask(dst, WRITEMASK_Z), brw_swizzle1(arg0, 0), - BRW_MATH_PRECISION_PARTIAL); + BRW_MATH_PRECISION_FULL); } if (dst.dw1.bits.writemask & WRITEMASK_W) { -- cgit v1.2.3 From a330933bb75c38148668637cd22b90d75d39506f Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 19 Dec 2008 12:58:01 -0800 Subject: Fix typeo in mipmap filter for GL_UNSIGNED_SHORT_1_5_5_5_REV --- src/mesa/main/mipmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 13d90e78fe..78d14b21c4 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -361,7 +361,7 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth, const GLint rowAr0 = rowA[j] & 0x1f; const GLint rowAr1 = rowA[k] & 0x1f; const GLint rowBr0 = rowB[j] & 0x1f; - const GLint rowBr1 = rowB[k] & 0xf; + const GLint rowBr1 = rowB[k] & 0x1f; const GLint rowAg0 = (rowA[j] >> 5) & 0x1f; const GLint rowAg1 = (rowA[k] >> 5) & 0x1f; const GLint rowBg0 = (rowB[j] >> 5) & 0x1f; -- cgit v1.2.3 From f83f5ec8f5f1159cfd0ec2596ceab725c073266e Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 19 Dec 2008 13:03:51 -0800 Subject: Add do_row_3d for mipmapping 3D textures Previously 3D textures were mipmapped using multiple passed through the 2D mipmap generation code. This had 3 disadvantages. First, the extra passes were slow. Second, this required the allocation of a temporary buffer to hold intermediate data. Third, and most important, the extra passes caused loss of additional bits due to integer division / bit-shifting. With this change, our mipmapgen conformance test passes for non-compressed texture formats. --- src/mesa/main/mipmap.c | 465 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 444 insertions(+), 21 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 78d14b21c4..9e051ace25 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -45,6 +45,67 @@ bytes_per_pixel(GLenum datatype, GLuint comps) } +/** + * \name Support macros for do_row and do_row_3d + * + * The macro madness is here for two reasons. First, it compacts the code + * slightly. Second, it makes it much easier to adjust the specifics of the + * filter to tune the rounding characteristics. + */ +/*@{*/ +#define DECLARE_ROW_POINTERS(t, e) \ + const t(*rowA)[e] = (const t(*)[e]) srcRowA; \ + const t(*rowB)[e] = (const t(*)[e]) srcRowB; \ + const t(*rowC)[e] = (const t(*)[e]) srcRowC; \ + const t(*rowD)[e] = (const t(*)[e]) srcRowD; \ + t(*dst)[e] = (t(*)[e]) dstRow + +#define DECLARE_ROW_POINTERS0(t) \ + const t *rowA = (const t *) srcRowA; \ + const t *rowB = (const t *) srcRowB; \ + const t *rowC = (const t *) srcRowC; \ + const t *rowD = (const t *) srcRowD; \ + t *dst = (t *) dstRow + +#define FILTER_SUM_3D(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \ + ((unsigned) Aj + (unsigned) Ak \ + + (unsigned) Bj + (unsigned) Bk \ + + (unsigned) Cj + (unsigned) Ck \ + + (unsigned) Dj + (unsigned) Dk \ + + 4) >> 3 + +#define FILTER_3D(e) \ + do { \ + dst[i][e] = FILTER_SUM_3D(rowA[j][e], rowA[k][e], \ + rowB[j][e], rowB[k][e], \ + rowC[j][e], rowC[k][e], \ + rowD[j][e], rowD[k][e]); \ + } while(0) + +#define FILTER_F_3D(e) \ + do { \ + dst[i][e] = (rowA[j][e] + rowA[k][e] \ + + rowB[j][e] + rowB[k][e] \ + + rowC[j][e] + rowC[k][e] \ + + rowD[j][e] + rowD[k][e]) * 0.125F; \ + } while(0) + +#define FILTER_HF_3D(e) \ + do { \ + const GLfloat aj = _mesa_half_to_float(rowA[j][e]); \ + const GLfloat ak = _mesa_half_to_float(rowA[k][e]); \ + const GLfloat bj = _mesa_half_to_float(rowB[j][e]); \ + const GLfloat bk = _mesa_half_to_float(rowB[k][e]); \ + const GLfloat cj = _mesa_half_to_float(rowC[j][e]); \ + const GLfloat ck = _mesa_half_to_float(rowC[k][e]); \ + const GLfloat dj = _mesa_half_to_float(rowD[j][e]); \ + const GLfloat dk = _mesa_half_to_float(rowD[k][e]); \ + dst[i][e] = _mesa_float_to_half((aj + ak + bj + bk + cj + ck + dj + dk) \ + * 0.125F); \ + } while(0) +/*@}*/ + + /** * Average together two rows of a source image to produce a single new * row in the dest image. It's legal for the two source rows to point @@ -412,6 +473,384 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth, } +/** + * Average together four rows of a source image to produce a single new + * row in the dest image. It's legal for the two source rows to point + * to the same data. The source width must be equal to either the + * dest width or two times the dest width. + * + * \param datatype GL pixel type \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, + * \c GL_FLOAT, etc. + * \param comps number of components per pixel (1..4) + * \param srcWidth Width of a row in the source data + * \param srcRowA Pointer to one of the rows of source data + * \param srcRowB Pointer to one of the rows of source data + * \param srcRowC Pointer to one of the rows of source data + * \param srcRowD Pointer to one of the rows of source data + * \param dstWidth Width of a row in the destination data + * \param srcRowA Pointer to the row of destination data + */ +static void +do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth, + const GLvoid *srcRowA, const GLvoid *srcRowB, + const GLvoid *srcRowC, const GLvoid *srcRowD, + GLint dstWidth, GLvoid *dstRow) +{ + const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1; + const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2; + GLuint i, j, k; + + ASSERT(comps >= 1); + ASSERT(comps <= 4); + + if ((datatype == GL_UNSIGNED_BYTE) && (comps == 4)) { + DECLARE_ROW_POINTERS(GLubyte, 4); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + FILTER_3D(2); + FILTER_3D(3); + } + } + else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 3)) { + DECLARE_ROW_POINTERS(GLubyte, 3); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + FILTER_3D(2); + } + } + else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 2)) { + DECLARE_ROW_POINTERS(GLubyte, 2); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + } + } + else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 1)) { + DECLARE_ROW_POINTERS(GLubyte, 1); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + } + } + else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 4)) { + DECLARE_ROW_POINTERS(GLushort, 4); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + FILTER_3D(2); + FILTER_3D(3); + } + } + else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 3)) { + DECLARE_ROW_POINTERS(GLushort, 3); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + FILTER_3D(2); + } + } + else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 2)) { + DECLARE_ROW_POINTERS(GLushort, 2); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + } + } + else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 1)) { + DECLARE_ROW_POINTERS(GLushort, 1); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + } + } + else if ((datatype == GL_FLOAT) && (comps == 4)) { + DECLARE_ROW_POINTERS(GLfloat, 4); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_F_3D(0); + FILTER_F_3D(1); + FILTER_F_3D(2); + FILTER_F_3D(3); + } + } + else if ((datatype == GL_FLOAT) && (comps == 3)) { + DECLARE_ROW_POINTERS(GLfloat, 3); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_F_3D(0); + FILTER_F_3D(1); + FILTER_F_3D(2); + } + } + else if ((datatype == GL_FLOAT) && (comps == 2)) { + DECLARE_ROW_POINTERS(GLfloat, 2); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_F_3D(0); + FILTER_F_3D(1); + } + } + else if ((datatype == GL_FLOAT) && (comps == 1)) { + DECLARE_ROW_POINTERS(GLfloat, 1); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_F_3D(0); + } + } + else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 4)) { + DECLARE_ROW_POINTERS(GLhalfARB, 4); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_HF_3D(0); + FILTER_HF_3D(1); + FILTER_HF_3D(2); + FILTER_HF_3D(3); + } + } + else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 3)) { + DECLARE_ROW_POINTERS(GLhalfARB, 4); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_HF_3D(0); + FILTER_HF_3D(1); + FILTER_HF_3D(2); + } + } + else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 2)) { + DECLARE_ROW_POINTERS(GLhalfARB, 4); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_HF_3D(0); + FILTER_HF_3D(1); + } + } + else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 1)) { + DECLARE_ROW_POINTERS(GLhalfARB, 4); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_HF_3D(0); + } + } + else if ((datatype == GL_UNSIGNED_INT) && (comps == 1)) { + const GLuint *rowA = (const GLuint *) srcRowA; + const GLuint *rowB = (const GLuint *) srcRowB; + const GLuint *rowC = (const GLuint *) srcRowC; + const GLuint *rowD = (const GLuint *) srcRowD; + GLfloat *dst = (GLfloat *) dstRow; + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + const uint64_t tmp = (((uint64_t) rowA[j] + (uint64_t) rowA[k]) + + ((uint64_t) rowB[j] + (uint64_t) rowB[k]) + + ((uint64_t) rowC[j] + (uint64_t) rowC[k]) + + ((uint64_t) rowD[j] + (uint64_t) rowD[k])); + dst[i] = (GLfloat)((double) tmp * 0.125); + } + } + else if ((datatype == GL_UNSIGNED_SHORT_5_6_5) && (comps == 3)) { + DECLARE_ROW_POINTERS0(GLushort); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0x1f; + const GLint rowAr1 = rowA[k] & 0x1f; + const GLint rowBr0 = rowB[j] & 0x1f; + const GLint rowBr1 = rowB[k] & 0x1f; + const GLint rowCr0 = rowC[j] & 0x1f; + const GLint rowCr1 = rowC[k] & 0x1f; + const GLint rowDr0 = rowD[j] & 0x1f; + const GLint rowDr1 = rowD[k] & 0x1f; + const GLint rowAg0 = (rowA[j] >> 5) & 0x3f; + const GLint rowAg1 = (rowA[k] >> 5) & 0x3f; + const GLint rowBg0 = (rowB[j] >> 5) & 0x3f; + const GLint rowBg1 = (rowB[k] >> 5) & 0x3f; + const GLint rowCg0 = (rowC[j] >> 5) & 0x3f; + const GLint rowCg1 = (rowC[k] >> 5) & 0x3f; + const GLint rowDg0 = (rowD[j] >> 5) & 0x3f; + const GLint rowDg1 = (rowD[k] >> 5) & 0x3f; + const GLint rowAb0 = (rowA[j] >> 11) & 0x1f; + const GLint rowAb1 = (rowA[k] >> 11) & 0x1f; + const GLint rowBb0 = (rowB[j] >> 11) & 0x1f; + const GLint rowBb1 = (rowB[k] >> 11) & 0x1f; + const GLint rowCb0 = (rowC[j] >> 11) & 0x1f; + const GLint rowCb1 = (rowC[k] >> 11) & 0x1f; + const GLint rowDb0 = (rowD[j] >> 11) & 0x1f; + const GLint rowDb1 = (rowD[k] >> 11) & 0x1f; + const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, + rowCr0, rowCr1, rowDr0, rowDr1); + const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, + rowCg0, rowCg1, rowDg0, rowDg1); + const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, + rowCb0, rowCb1, rowDb0, rowDb1); + dst[i] = (b << 11) | (g << 5) | r; + } + } + else if ((datatype == GL_UNSIGNED_SHORT_4_4_4_4) && (comps == 4)) { + DECLARE_ROW_POINTERS0(GLushort); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0xf; + const GLint rowAr1 = rowA[k] & 0xf; + const GLint rowBr0 = rowB[j] & 0xf; + const GLint rowBr1 = rowB[k] & 0xf; + const GLint rowCr0 = rowC[j] & 0xf; + const GLint rowCr1 = rowC[k] & 0xf; + const GLint rowDr0 = rowD[j] & 0xf; + const GLint rowDr1 = rowD[k] & 0xf; + const GLint rowAg0 = (rowA[j] >> 4) & 0xf; + const GLint rowAg1 = (rowA[k] >> 4) & 0xf; + const GLint rowBg0 = (rowB[j] >> 4) & 0xf; + const GLint rowBg1 = (rowB[k] >> 4) & 0xf; + const GLint rowCg0 = (rowC[j] >> 4) & 0xf; + const GLint rowCg1 = (rowC[k] >> 4) & 0xf; + const GLint rowDg0 = (rowD[j] >> 4) & 0xf; + const GLint rowDg1 = (rowD[k] >> 4) & 0xf; + const GLint rowAb0 = (rowA[j] >> 8) & 0xf; + const GLint rowAb1 = (rowA[k] >> 8) & 0xf; + const GLint rowBb0 = (rowB[j] >> 8) & 0xf; + const GLint rowBb1 = (rowB[k] >> 8) & 0xf; + const GLint rowCb0 = (rowC[j] >> 8) & 0xf; + const GLint rowCb1 = (rowC[k] >> 8) & 0xf; + const GLint rowDb0 = (rowD[j] >> 8) & 0xf; + const GLint rowDb1 = (rowD[k] >> 8) & 0xf; + const GLint rowAa0 = (rowA[j] >> 12) & 0xf; + const GLint rowAa1 = (rowA[k] >> 12) & 0xf; + const GLint rowBa0 = (rowB[j] >> 12) & 0xf; + const GLint rowBa1 = (rowB[k] >> 12) & 0xf; + const GLint rowCa0 = (rowC[j] >> 12) & 0xf; + const GLint rowCa1 = (rowC[k] >> 12) & 0xf; + const GLint rowDa0 = (rowD[j] >> 12) & 0xf; + const GLint rowDa1 = (rowD[k] >> 12) & 0xf; + const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, + rowCr0, rowCr1, rowDr0, rowDr1); + const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, + rowCg0, rowCg1, rowDg0, rowDg1); + const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, + rowCb0, rowCb1, rowDb0, rowDb1); + const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1, + rowCa0, rowCa1, rowDa0, rowDa1); + + dst[i] = (a << 12) | (b << 8) | (g << 4) | r; + } + } + else if ((datatype == GL_UNSIGNED_SHORT_1_5_5_5_REV) && (comps == 4)) { + DECLARE_ROW_POINTERS0(GLushort); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0x1f; + const GLint rowAr1 = rowA[k] & 0x1f; + const GLint rowBr0 = rowB[j] & 0x1f; + const GLint rowBr1 = rowB[k] & 0x1f; + const GLint rowCr0 = rowC[j] & 0x1f; + const GLint rowCr1 = rowC[k] & 0x1f; + const GLint rowDr0 = rowD[j] & 0x1f; + const GLint rowDr1 = rowD[k] & 0x1f; + const GLint rowAg0 = (rowA[j] >> 5) & 0x1f; + const GLint rowAg1 = (rowA[k] >> 5) & 0x1f; + const GLint rowBg0 = (rowB[j] >> 5) & 0x1f; + const GLint rowBg1 = (rowB[k] >> 5) & 0x1f; + const GLint rowCg0 = (rowC[j] >> 5) & 0x1f; + const GLint rowCg1 = (rowC[k] >> 5) & 0x1f; + const GLint rowDg0 = (rowD[j] >> 5) & 0x1f; + const GLint rowDg1 = (rowD[k] >> 5) & 0x1f; + const GLint rowAb0 = (rowA[j] >> 10) & 0x1f; + const GLint rowAb1 = (rowA[k] >> 10) & 0x1f; + const GLint rowBb0 = (rowB[j] >> 10) & 0x1f; + const GLint rowBb1 = (rowB[k] >> 10) & 0x1f; + const GLint rowCb0 = (rowC[j] >> 10) & 0x1f; + const GLint rowCb1 = (rowC[k] >> 10) & 0x1f; + const GLint rowDb0 = (rowD[j] >> 10) & 0x1f; + const GLint rowDb1 = (rowD[k] >> 10) & 0x1f; + const GLint rowAa0 = (rowA[j] >> 15) & 0x1; + const GLint rowAa1 = (rowA[k] >> 15) & 0x1; + const GLint rowBa0 = (rowB[j] >> 15) & 0x1; + const GLint rowBa1 = (rowB[k] >> 15) & 0x1; + const GLint rowCa0 = (rowC[j] >> 15) & 0x1; + const GLint rowCa1 = (rowC[k] >> 15) & 0x1; + const GLint rowDa0 = (rowD[j] >> 15) & 0x1; + const GLint rowDa1 = (rowD[k] >> 15) & 0x1; + const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, + rowCr0, rowCr1, rowDr0, rowDr1); + const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, + rowCg0, rowCg1, rowDg0, rowDg1); + const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, + rowCb0, rowCb1, rowDb0, rowDb1); + const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1, + rowCa0, rowCa1, rowDa0, rowDa1); + + dst[i] = (a << 15) | (b << 10) | (g << 5) | r; + } + } + else if ((datatype == GL_UNSIGNED_BYTE_3_3_2) && (comps == 3)) { + DECLARE_ROW_POINTERS0(GLushort); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0x3; + const GLint rowAr1 = rowA[k] & 0x3; + const GLint rowBr0 = rowB[j] & 0x3; + const GLint rowBr1 = rowB[k] & 0x3; + const GLint rowCr0 = rowC[j] & 0x3; + const GLint rowCr1 = rowC[k] & 0x3; + const GLint rowDr0 = rowD[j] & 0x3; + const GLint rowDr1 = rowD[k] & 0x3; + const GLint rowAg0 = (rowA[j] >> 2) & 0x7; + const GLint rowAg1 = (rowA[k] >> 2) & 0x7; + const GLint rowBg0 = (rowB[j] >> 2) & 0x7; + const GLint rowBg1 = (rowB[k] >> 2) & 0x7; + const GLint rowCg0 = (rowC[j] >> 2) & 0x7; + const GLint rowCg1 = (rowC[k] >> 2) & 0x7; + const GLint rowDg0 = (rowD[j] >> 2) & 0x7; + const GLint rowDg1 = (rowD[k] >> 2) & 0x7; + const GLint rowAb0 = (rowA[j] >> 5) & 0x7; + const GLint rowAb1 = (rowA[k] >> 5) & 0x7; + const GLint rowBb0 = (rowB[j] >> 5) & 0x7; + const GLint rowBb1 = (rowB[k] >> 5) & 0x7; + const GLint rowCb0 = (rowC[j] >> 5) & 0x7; + const GLint rowCb1 = (rowC[k] >> 5) & 0x7; + const GLint rowDb0 = (rowD[j] >> 5) & 0x7; + const GLint rowDb1 = (rowD[k] >> 5) & 0x7; + const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, + rowCr0, rowCr1, rowDr0, rowDr1); + const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, + rowCg0, rowCg1, rowDg0, rowDg1); + const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, + rowCb0, rowCb1, rowDb0, rowDb1); + dst[i] = (b << 5) | (g << 2) | r; + } + } + else { + _mesa_problem(NULL, "bad format in do_row()"); + } +} + + /* * These functions generate a 1/2-size mipmap image from a source image. * Texture borders are handled by copying or averaging the source image's @@ -544,7 +983,6 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, const GLint dstWidthNB = dstWidth - 2 * border; const GLint dstHeightNB = dstHeight - 2 * border; const GLint dstDepthNB = dstDepth - 2 * border; - GLvoid *tmpRowA, *tmpRowB; GLint img, row; GLint bytesPerSrcImage, bytesPerDstImage; GLint bytesPerSrcRow, bytesPerDstRow; @@ -552,15 +990,6 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, (void) srcDepthNB; /* silence warnings */ - /* Need two temporary row buffers */ - tmpRowA = _mesa_malloc(srcWidth * bpt); - if (!tmpRowA) - return; - tmpRowB = _mesa_malloc(srcWidth * bpt); - if (!tmpRowB) { - _mesa_free(tmpRowA); - return; - } bytesPerSrcImage = srcWidth * srcHeight * bpt; bytesPerDstImage = dstWidth * dstHeight * bpt; @@ -607,15 +1036,11 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, GLubyte *dstImgRow = imgDst; for (row = 0; row < dstHeightNB; row++) { - /* Average together two rows from first src image */ - do_row(datatype, comps, srcWidthNB, srcImgARowA, srcImgARowB, - srcWidthNB, tmpRowA); - /* Average together two rows from second src image */ - do_row(datatype, comps, srcWidthNB, srcImgBRowA, srcImgBRowB, - srcWidthNB, tmpRowB); - /* Average together the temp rows to make the final row */ - do_row(datatype, comps, srcWidthNB, tmpRowA, tmpRowB, - dstWidthNB, dstImgRow); + do_row_3D(datatype, comps, srcWidthNB, + srcImgARowA, srcImgARowB, + srcImgBRowA, srcImgBRowB, + dstWidthNB, dstImgRow); + /* advance to next rows */ srcImgARowA += bytesPerSrcRow + srcRowOffset; srcImgARowB += bytesPerSrcRow + srcRowOffset; @@ -625,8 +1050,6 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, } } - _mesa_free(tmpRowA); - _mesa_free(tmpRowB); /* Luckily we can leverage the make_2d_mipmap() function here! */ if (border > 0) { -- cgit v1.2.3