diff options
Diffstat (limited to 'mesalib/src/mesa/state_tracker/st_cb_texture.c')
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_texture.c | 222 |
1 files changed, 89 insertions, 133 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index c58a9df56..52f654d7d 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -214,56 +214,6 @@ st_UnmapTextureImage(struct gl_context *ctx, /** - * From linux kernel i386 header files, copes with odd sizes better - * than COPY_DWORDS would: - * XXX Put this in src/mesa/main/imports.h ??? - */ -#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) -static INLINE void * -__memcpy(void *to, const void *from, size_t n) -{ - int d0, d1, d2; - __asm__ __volatile__("rep ; movsl\n\t" - "testb $2,%b4\n\t" - "je 1f\n\t" - "movsw\n" - "1:\ttestb $1,%b4\n\t" - "je 2f\n\t" - "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) - :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) - :"memory"); - return (to); -} -#else -#define __memcpy(a,b,c) memcpy(a,b,c) -#endif - - -/** - * The system memcpy (at least on ubuntu 5.10) has problems copying - * to agp (writecombined) memory from a source which isn't 64-byte - * aligned - there is a 4x performance falloff. - * - * The x86 __memcpy is immune to this but is slightly slower - * (10%-ish) than the system memcpy. - * - * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but - * isn't much faster than x86_memcpy for agp copies. - * - * TODO: switch dynamically. - */ -static void * -do_memcpy(void *dest, const void *src, size_t n) -{ - if ((((unsigned long) src) & 63) || (((unsigned long) dest) & 63)) { - return __memcpy(dest, src, n); - } - else - return memcpy(dest, src, n); -} - - -/** * Return default texture resource binding bitmask for the given format. */ static GLuint @@ -1420,11 +1370,13 @@ st_copy_texsubimage(struct gl_context *ctx, struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; enum pipe_format dest_format, src_format; - GLboolean use_fallback = GL_TRUE; GLboolean matching_base_formats; GLuint format_writemask, sample_count; struct pipe_surface *dest_surface = NULL; GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); + struct pipe_surface surf_tmpl; + unsigned int dst_usage; + GLint srcY0, srcY1; /* make sure finalize_textures has been called? */ @@ -1472,99 +1424,105 @@ st_copy_texsubimage(struct gl_context *ctx, matching_base_formats = (_mesa_get_format_base_format(strb->Base.Format) == _mesa_get_format_base_format(texImage->TexFormat)); - format_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage); - if (ctx->_ImageTransferState == 0x0) { + if (ctx->_ImageTransferState) { + goto fallback; + } + + if (matching_base_formats && + src_format == dest_format && + !do_flip) { + /* use surface_copy() / blit */ + struct pipe_box src_box; + u_box_2d_zslice(srcX, srcY, strb->surface->u.tex.first_layer, + width, height, &src_box); + + /* for resource_copy_region(), y=0=top, always */ + pipe->resource_copy_region(pipe, + /* dest */ + stImage->pt, + stImage->base.Level, + destX, destY, destZ + stImage->base.Face, + /* src */ + strb->texture, + strb->surface->u.tex.level, + &src_box); + return; + } - if (matching_base_formats && - src_format == dest_format && - !do_flip) - { - /* use surface_copy() / blit */ - struct pipe_box src_box; - u_box_2d_zslice(srcX, srcY, strb->surface->u.tex.first_layer, - width, height, &src_box); - - /* for resource_copy_region(), y=0=top, always */ - pipe->resource_copy_region(pipe, - /* dest */ - stImage->pt, - stImage->base.Level, - destX, destY, destZ + stImage->base.Face, - /* src */ - strb->texture, - strb->surface->u.tex.level, - &src_box); - use_fallback = GL_FALSE; - } - else if (format_writemask && - texBaseFormat != GL_DEPTH_COMPONENT && - texBaseFormat != GL_DEPTH_STENCIL && - screen->is_format_supported(screen, src_format, - PIPE_TEXTURE_2D, sample_count, - PIPE_BIND_SAMPLER_VIEW) && - screen->is_format_supported(screen, dest_format, - PIPE_TEXTURE_2D, 0, - PIPE_BIND_RENDER_TARGET)) { - /* draw textured quad to do the copy */ - GLint srcY0, srcY1; - struct pipe_surface surf_tmpl; - memset(&surf_tmpl, 0, sizeof(surf_tmpl)); - surf_tmpl.format = util_format_linear(stImage->pt->format); - surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; - surf_tmpl.u.tex.level = stImage->base.Level; - surf_tmpl.u.tex.first_layer = stImage->base.Face + destZ; - surf_tmpl.u.tex.last_layer = stImage->base.Face + destZ; - - dest_surface = pipe->create_surface(pipe, stImage->pt, - &surf_tmpl); - - if (do_flip) { - srcY1 = strb->Base.Height - srcY - height; - srcY0 = srcY1 + height; - } - else { - srcY0 = srcY; - srcY1 = srcY0 + height; - } + if (texBaseFormat == GL_DEPTH_STENCIL) { + goto fallback; + } - /* Disable conditional rendering. */ - if (st->render_condition) { - pipe->render_condition(pipe, NULL, 0); - } + if (texBaseFormat == GL_DEPTH_COMPONENT) { + format_writemask = TGSI_WRITEMASK_XYZW; + dst_usage = PIPE_BIND_DEPTH_STENCIL; + } + else { + format_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage); + dst_usage = PIPE_BIND_RENDER_TARGET; + } - util_blit_pixels_writemask(st->blit, - strb->texture, - strb->surface->u.tex.level, - srcX, srcY0, - srcX + width, srcY1, - strb->surface->u.tex.first_layer, - dest_surface, - destX, destY, - destX + width, destY + height, - 0.0, PIPE_TEX_MIPFILTER_NEAREST, - format_writemask); - - /* Restore conditional rendering state. */ - if (st->render_condition) { - pipe->render_condition(pipe, st->render_condition, - st->condition_mode); - } + if (!format_writemask || + !screen->is_format_supported(screen, src_format, + PIPE_TEXTURE_2D, sample_count, + PIPE_BIND_SAMPLER_VIEW) || + !screen->is_format_supported(screen, dest_format, + PIPE_TEXTURE_2D, 0, + dst_usage)) { + goto fallback; + } - use_fallback = GL_FALSE; - } + if (do_flip) { + srcY1 = strb->Base.Height - srcY - height; + srcY0 = srcY1 + height; + } + else { + srcY0 = srcY; + srcY1 = srcY0 + height; + } + + /* Disable conditional rendering. */ + if (st->render_condition) { + pipe->render_condition(pipe, NULL, 0); + } + + memset(&surf_tmpl, 0, sizeof(surf_tmpl)); + surf_tmpl.format = util_format_linear(stImage->pt->format); + surf_tmpl.usage = dst_usage; + surf_tmpl.u.tex.level = stImage->base.Level; + surf_tmpl.u.tex.first_layer = stImage->base.Face + destZ; + surf_tmpl.u.tex.last_layer = stImage->base.Face + destZ; + + dest_surface = pipe->create_surface(pipe, stImage->pt, + &surf_tmpl); + util_blit_pixels_writemask(st->blit, + strb->texture, + strb->surface->u.tex.level, + srcX, srcY0, + srcX + width, srcY1, + strb->surface->u.tex.first_layer, + dest_surface, + destX, destY, + destX + width, destY + height, + 0.0, PIPE_TEX_MIPFILTER_NEAREST, + format_writemask); + pipe_surface_reference(&dest_surface, NULL); - if (dest_surface) - pipe_surface_reference(&dest_surface, NULL); + /* Restore conditional rendering state. */ + if (st->render_condition) { + pipe->render_condition(pipe, st->render_condition, + st->condition_mode); } - if (use_fallback) { + return; + +fallback: /* software fallback */ fallback_copy_texsubimage(ctx, target, level, strb, stImage, texBaseFormat, destX, destY, destZ, srcX, srcY, width, height); - } } @@ -1937,8 +1895,6 @@ st_init_texture_functions(struct dd_function_table *functions) functions->MapTextureImage = st_MapTextureImage; functions->UnmapTextureImage = st_UnmapTextureImage; - functions->TextureMemCpy = do_memcpy; - /* XXX Temporary until we can query pipe's texture sizes */ functions->TestProxyTexImage = _mesa_test_proxy_teximage; |