aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/state_tracker/st_cb_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/state_tracker/st_cb_texture.c')
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c222
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;