From: Eric Anholt Date: Mon, 3 Jun 2013 22:12:49 +0000 (-0700) Subject: mesa: Hide weirdness of 1D_ARRAY textures from Driver.CopyTexSubImage(). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b65b1c3148ad7ebaaca422bc572dead0864dcd6a;p=mesa.git mesa: Hide weirdness of 1D_ARRAY textures from Driver.CopyTexSubImage(). Intel had brokenness here, and I'd like to continue moving Mesa toward hiding 1D_ARRAY's ridiculousness inside of the core, like we did with MapTextureImage. Fixes copyteximage 1D_ARRAY on intel. There's still an impedance mismatch in meta when falling back to read and texsubimage, since texsubimage expects coordinates into 1D_ARRAY as (width, slice, 0) instead of (width, 0, slice). v2: Fix offset of scanline reads from the source. (Thanks Brian!), replace dd.h comment with Paul's text and replace early exit with an assert. Reviewed-by: Brian Paul (v1) Reviewed-by: Kenneth Graunke (v1) Reviewed-by: Paul Berry (v1) --- diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index ce5b87b0be1..f7dd06aebf0 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -3851,9 +3851,16 @@ _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, */ _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE); - ctx->Driver.TexSubImage(ctx, dims, texImage, - xoffset, yoffset, zoffset, width, height, 1, - format, type, buf, &ctx->Unpack); + if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { + assert(yoffset == 0); + ctx->Driver.TexSubImage(ctx, dims, texImage, + xoffset, zoffset, 0, width, 1, 1, + format, type, buf, &ctx->Unpack); + } else { + ctx->Driver.TexSubImage(ctx, dims, texImage, + xoffset, yoffset, zoffset, width, height, 1, + format, type, buf, &ctx->Unpack); + } _mesa_meta_end(ctx); diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h index a3617f4fad8..53d7b8ab5a8 100644 --- a/src/mesa/drivers/common/meta.h +++ b/src/mesa/drivers/common/meta.h @@ -116,7 +116,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, extern void _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, + GLint xoffset, GLint yoffset, GLint slice, struct gl_renderbuffer *rb, GLint x, GLint y, GLsizei width, GLsizei height); diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index d8e65baad5b..3ab66d97b54 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -135,13 +135,14 @@ intel_copy_texsubimage(struct intel_context *intel, static void intelCopyTexSubImage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, + GLint xoffset, GLint yoffset, GLint slice, struct gl_renderbuffer *rb, GLint x, GLint y, GLsizei width, GLsizei height) { struct intel_context *intel = intel_context(ctx); - if (dims != 3) { + + if (slice == 0) { #ifndef I915 /* Try BLORP first. It can handle almost everything. */ if (brw_blorp_copytexsubimage(intel, rb, texImage, x, y, @@ -160,7 +161,7 @@ intelCopyTexSubImage(struct gl_context *ctx, GLuint dims, /* Finally, fall back to meta. This will likely be slow. */ perf_debug("%s - fallback to swrast\n", __FUNCTION__); _mesa_meta_CopyTexSubImage(ctx, dims, texImage, - xoffset, yoffset, zoffset, + xoffset, yoffset, slice, rb, x, y, width, height); } diff --git a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c index a6c406b2bff..675eb78ec5c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c @@ -136,7 +136,7 @@ do_copy_texsubimage(struct gl_context *ctx, void radeonCopyTexSubImage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, + GLint xoffset, GLint yoffset, GLint slice, struct gl_renderbuffer *rb, GLint x, GLint y, GLsizei width, GLsizei height) @@ -144,7 +144,7 @@ radeonCopyTexSubImage(struct gl_context *ctx, GLuint dims, radeonContextPtr radeon = RADEON_CONTEXT(ctx); radeon_prepare_render(radeon); - if (dims != 2 || !do_copy_texsubimage(ctx, + if (slice != 0 || !do_copy_texsubimage(ctx, radeon_tex_obj(texImage->TexObject), (radeon_texture_image *)texImage, xoffset, yoffset, @@ -154,7 +154,7 @@ radeonCopyTexSubImage(struct gl_context *ctx, GLuint dims, "Falling back to sw for glCopyTexSubImage2D\n"); _mesa_meta_CopyTexSubImage(ctx, dims, texImage, - xoffset, yoffset, zoffset, + xoffset, yoffset, slice, rb, x, y, width, height); } } diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 6d564b25274..e2519780ab2 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -248,10 +248,16 @@ struct dd_function_table { /** * Called by glCopyTex[Sub]Image[123]D(). + * + * This function should copy a rectangular region in the rb to a single + * destination slice, specified by @slice. In the case of 1D array + * textures (where one GL call can potentially affect multiple destination + * slices), core mesa takes care of calling this function multiple times, + * once for each scanline to be copied. */ void (*CopyTexSubImage)(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, + GLint xoffset, GLint yoffset, GLint slice, struct gl_renderbuffer *rb, GLint x, GLint y, GLsizei width, GLsizei height); diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 6f7fbc0d2a1..5226687ff92 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -3429,6 +3429,35 @@ get_copy_tex_image_source(struct gl_context *ctx, gl_format texFormat) } } +static void +copytexsubimage_by_slice(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLuint dims, + GLint xoffset, GLint yoffset, GLint zoffset, + struct gl_renderbuffer *rb, + GLint x, GLint y, + GLsizei width, GLsizei height) +{ + if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { + int slice; + + /* For 1D arrays, we copy each scanline of the source rectangle into the + * next array slice. + */ + assert(zoffset == 0); + + for (slice = 0; slice < height; slice++) { + assert(yoffset + slice < texImage->Height); + ctx->Driver.CopyTexSubImage(ctx, 2, texImage, + xoffset, 0, yoffset + slice, + rb, x, y + slice, width, 1); + } + } else { + ctx->Driver.CopyTexSubImage(ctx, dims, texImage, + xoffset, yoffset, zoffset, + rb, x, y, width, height); + } +} /** @@ -3517,8 +3546,9 @@ copyteximage(struct gl_context *ctx, GLuint dims, struct gl_renderbuffer *srcRb = get_copy_tex_image_source(ctx, texImage->TexFormat); - ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ, - srcRb, srcX, srcY, width, height); + copytexsubimage_by_slice(ctx, texImage, dims, + dstX, dstY, dstZ, + srcRb, srcX, srcY, width, height); } check_gen_mipmap(ctx, target, texObj, level); @@ -3610,9 +3640,9 @@ copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, struct gl_renderbuffer *srcRb = get_copy_tex_image_source(ctx, texImage->TexFormat); - ctx->Driver.CopyTexSubImage(ctx, dims, texImage, - xoffset, yoffset, zoffset, - srcRb, x, y, width, height); + copytexsubimage_by_slice(ctx, texImage, dims, + xoffset, yoffset, zoffset, + srcRb, x, y, width, height); check_gen_mipmap(ctx, target, texObj, level); diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 56dbe85c03a..68c334ed8a0 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1133,7 +1133,7 @@ fallback_copy_texsubimage(struct gl_context *ctx, struct st_renderbuffer *strb, struct st_texture_image *stImage, GLenum baseFormat, - GLint destX, GLint destY, GLint destZ, + GLint destX, GLint destY, GLint slice, GLint srcX, GLint srcY, GLsizei width, GLsizei height) { @@ -1154,14 +1154,6 @@ fallback_copy_texsubimage(struct gl_context *ctx, srcY = strb->Base.Height - srcY - height; } - if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) { - /* Move y/height to z/depth for 1D array textures. */ - destZ = destY; - destY = 0; - dst_depth = dst_height; - dst_height = 1; - } - map = pipe_transfer_map(pipe, strb->texture, strb->rtt_level, @@ -1178,7 +1170,7 @@ fallback_copy_texsubimage(struct gl_context *ctx, transfer_usage = PIPE_TRANSFER_WRITE; texDest = st_texture_image_map(st, stImage, transfer_usage, - destX, destY, destZ, + destX, destY, slice, dst_width, dst_height, dst_depth); if (baseFormat == GL_DEPTH_COMPONENT || @@ -1292,7 +1284,7 @@ fallback_copy_texsubimage(struct gl_context *ctx, static void st_CopyTexSubImage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint destX, GLint destY, GLint destZ, + GLint destX, GLint destY, GLint slice, struct gl_renderbuffer *rb, GLint srcX, GLint srcY, GLsizei width, GLsizei height) { @@ -1306,7 +1298,7 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims, enum pipe_format dst_format; GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); unsigned bind; - GLint srcY0, srcY1, yStep; + GLint srcY0, srcY1; if (!strb || !strb->surface || !stImage->pt) { debug_printf("%s: null strb or stImage\n", __FUNCTION__); @@ -1351,12 +1343,10 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims, if (do_flip) { srcY1 = strb->Base.Height - srcY - height; srcY0 = srcY1 + height; - yStep = -1; } else { srcY0 = srcY; srcY1 = srcY0 + height; - yStep = 1; } /* Blit the texture. @@ -1377,39 +1367,20 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims, blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level; blit.dst.box.x = destX; blit.dst.box.y = destY; - blit.dst.box.z = stImage->base.Face + destZ; + blit.dst.box.z = stImage->base.Face + slice; blit.dst.box.width = width; blit.dst.box.height = height; blit.dst.box.depth = 1; blit.mask = st_get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat); blit.filter = PIPE_TEX_FILTER_NEAREST; - - /* 1D array textures need special treatment. - * Blit rows from the source to layers in the destination. */ - if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { - int y, layer; - - for (y = srcY0, layer = 0; layer < height; y += yStep, layer++) { - blit.src.box.y = y; - blit.src.box.height = 1; - blit.dst.box.y = 0; - blit.dst.box.height = 1; - blit.dst.box.z = destY + layer; - - pipe->blit(pipe, &blit); - } - } - else { - /* All the other texture targets. */ - pipe->blit(pipe, &blit); - } + pipe->blit(pipe, &blit); return; fallback: /* software fallback */ fallback_copy_texsubimage(ctx, strb, stImage, texImage->_BaseFormat, - destX, destY, destZ, + destX, destY, slice, srcX, srcY, width, height); }