<div dir="ltr">On 5 June 2013 10:14, Eric Anholt <span dir="ltr"><<a href="mailto:eric@anholt.net" target="_blank">eric@anholt.net</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Intel had brokenness here, and I'd like to continue moving Mesa toward<br>
hiding 1D_ARRAY's ridiculousness inside of the core, like we did with<br>
MapTextureImage. Fixes copyteximage 1D_ARRAY on intel.<br>
<br>
There's still an impedance mismatch in meta when falling back to read and<br>
texsubimage, since texsubimage expects coordinates into 1D_ARRAY as<br>
(width, slice, 0) instead of (width, 0, slice).<br>
---<br>
src/mesa/drivers/common/meta.c | 13 ++++++--<br>
src/mesa/drivers/common/meta.h | 2 +-<br>
src/mesa/drivers/dri/intel/intel_tex_copy.c | 7 +++--<br>
src/mesa/drivers/dri/radeon/radeon_tex_copy.c | 6 ++--<br>
src/mesa/main/dd.h | 7 ++++-<br>
src/mesa/main/teximage.c | 42 ++++++++++++++++++++++----<br>
src/mesa/state_tracker/st_cb_texture.c | 43 +++++----------------------<br>
7 files changed, 68 insertions(+), 52 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c<br>
index 1250bd3..2bf42c0 100644<br>
--- a/src/mesa/drivers/common/meta.c<br>
+++ b/src/mesa/drivers/common/meta.c<br>
@@ -3851,9 +3851,16 @@ _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims,<br>
*/<br>
_mesa_meta_begin(ctx, MESA_META_PIXEL_STORE);<br>
<br>
- ctx->Driver.TexSubImage(ctx, dims, texImage,<br>
- xoffset, yoffset, zoffset, width, height, 1,<br>
- format, type, buf, &ctx->Unpack);<br>
+ if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {<br>
+ assert(yoffset == 0);<br>
+ ctx->Driver.TexSubImage(ctx, dims, texImage,<br>
+ xoffset, zoffset, 0, width, 1, 1,<br>
+ format, type, buf, &ctx->Unpack);<br>
+ } else {<br>
+ ctx->Driver.TexSubImage(ctx, dims, texImage,<br>
+ xoffset, yoffset, zoffset, width, height, 1,<br>
+ format, type, buf, &ctx->Unpack);<br>
+ } <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
_mesa_meta_end(ctx);<br>
<br>
diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h<br>
index 823be14..1639e4a 100644<br>
--- a/src/mesa/drivers/common/meta.h<br>
+++ b/src/mesa/drivers/common/meta.h<br>
@@ -117,7 +117,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,<br>
extern void<br>
_mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims,<br>
struct gl_texture_image *texImage,<br>
- GLint xoffset, GLint yoffset, GLint zoffset,<br>
+ GLint xoffset, GLint yoffset, GLint slice,<br>
struct gl_renderbuffer *rb,<br>
GLint x, GLint y,<br>
GLsizei width, GLsizei height);<br>
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c<br>
index d8e65ba..3ab66d9 100644<br>
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c<br>
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c<br>
@@ -135,13 +135,14 @@ intel_copy_texsubimage(struct intel_context *intel,<br>
static void<br>
intelCopyTexSubImage(struct gl_context *ctx, GLuint dims,<br>
struct gl_texture_image *texImage,<br>
- GLint xoffset, GLint yoffset, GLint zoffset,<br>
+ GLint xoffset, GLint yoffset, GLint slice,<br>
struct gl_renderbuffer *rb,<br>
GLint x, GLint y,<br>
GLsizei width, GLsizei height)<br>
{<br>
struct intel_context *intel = intel_context(ctx);<br>
- if (dims != 3) {<br>
+<br>
+ if (slice == 0) {<br>
#ifndef I915<br>
/* Try BLORP first. It can handle almost everything. */<br>
if (brw_blorp_copytexsubimage(intel, rb, texImage, x, y,<br>
@@ -160,7 +161,7 @@ intelCopyTexSubImage(struct gl_context *ctx, GLuint dims,<br>
/* Finally, fall back to meta. This will likely be slow. */<br>
perf_debug("%s - fallback to swrast\n", __FUNCTION__);<br>
_mesa_meta_CopyTexSubImage(ctx, dims, texImage,<br>
- xoffset, yoffset, zoffset,<br>
+ xoffset, yoffset, slice,<br>
rb, x, y, width, height);<br>
}<br>
<br>
diff --git a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c<br>
index a6c406b..675eb78 100644<br>
--- a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c<br>
+++ b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c<br>
@@ -136,7 +136,7 @@ do_copy_texsubimage(struct gl_context *ctx,<br>
void<br>
radeonCopyTexSubImage(struct gl_context *ctx, GLuint dims,<br>
struct gl_texture_image *texImage,<br>
- GLint xoffset, GLint yoffset, GLint zoffset,<br>
+ GLint xoffset, GLint yoffset, GLint slice,<br>
struct gl_renderbuffer *rb,<br>
GLint x, GLint y,<br>
GLsizei width, GLsizei height)<br>
@@ -144,7 +144,7 @@ radeonCopyTexSubImage(struct gl_context *ctx, GLuint dims,<br>
radeonContextPtr radeon = RADEON_CONTEXT(ctx);<br>
radeon_prepare_render(radeon);<br>
<br>
- if (dims != 2 || !do_copy_texsubimage(ctx,<br>
+ if (slice != 0 || !do_copy_texsubimage(ctx,<br>
radeon_tex_obj(texImage->TexObject),<br>
(radeon_texture_image *)texImage,<br>
xoffset, yoffset,<br>
@@ -154,7 +154,7 @@ radeonCopyTexSubImage(struct gl_context *ctx, GLuint dims,<br>
"Falling back to sw for glCopyTexSubImage2D\n");<br>
<br>
_mesa_meta_CopyTexSubImage(ctx, dims, texImage,<br>
- xoffset, yoffset, zoffset,<br>
+ xoffset, yoffset, slice,<br>
rb, x, y, width, height);<br>
}<br>
}<br>
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h<br>
index 13c7a83..846d5d0 100644<br>
--- a/src/mesa/main/dd.h<br>
+++ b/src/mesa/main/dd.h<br>
@@ -249,10 +249,15 @@ struct dd_function_table {<br>
<br>
/**<br>
* Called by glCopyTex[Sub]Image[123]D().<br>
+ *<br>
+ * In the case of 1D array textures, the driver will be called to copy each<br>
+ * appropriate scanline from the rb to each destination slice. For 3D or<br>
+ * other array textures, only one slice may be copied, but @slice may be<br>
+ * nonzero.<br></blockquote><div><br></div><div>I'm having trouble following this comment, especially the second sentence. Would this be clearer?<br><br></div><div>"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."<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
*/<br>
void (*CopyTexSubImage)(struct gl_context *ctx, GLuint dims,<br>
struct gl_texture_image *texImage,<br>
- GLint xoffset, GLint yoffset, GLint zoffset,<br>
+ GLint xoffset, GLint yoffset, GLint slice,<br>
struct gl_renderbuffer *rb,<br>
GLint x, GLint y,<br>
GLsizei width, GLsizei height);<br>
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c<br>
index 9aaa63f..edd8019 100644<br>
--- a/src/mesa/main/teximage.c<br>
+++ b/src/mesa/main/teximage.c<br>
@@ -3428,6 +3428,37 @@ get_copy_tex_image_source(struct gl_context *ctx, gl_format texFormat)<br>
}<br>
}<br>
<br>
+static void<br>
+copytexsubimage_by_slice(struct gl_context *ctx,<br>
+ struct gl_texture_image *texImage,<br>
+ GLuint dims,<br>
+ GLint xoffset, GLint yoffset, GLint zoffset,<br>
+ struct gl_renderbuffer *rb,<br>
+ GLint x, GLint y,<br>
+ GLsizei width, GLsizei height)<br>
+{<br>
+ if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {<br>
+ int slice;<br>
+<br>
+ /* For 1D arrays, we copy each scanline of the source rectangle into the<br>
+ * next array slice.<br>
+ */<br>
+ assert(zoffset == 0);<br>
+<br>
+ for (slice = 0; slice < height; slice++) {<br>
+ if (yoffset + slice >= texImage->Height)<br>
+ break;<br></blockquote><div><br></div><div>Shouldn't the error check in error_check_subtexture_dimensions() prevent this from ever occurring? If so, I think this should be an assertion.<br><br></div><div>
Both of these comments are minor, so in any case, this patch is<br><br></div><div>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+ ctx->Driver.CopyTexSubImage(ctx, 2, texImage,<br>
+ xoffset, 0, yoffset + slice,<br>
+ rb, x, y, width, 1);<br>
+ }<br>
+ } else {<br>
+ ctx->Driver.CopyTexSubImage(ctx, dims, texImage,<br>
+ xoffset, yoffset, zoffset,<br>
+ rb, x, y, width, height);<br>
+ }<br>
+}<br>
<br>
<br>
/**<br>
@@ -3516,8 +3547,9 @@ copyteximage(struct gl_context *ctx, GLuint dims,<br>
struct gl_renderbuffer *srcRb =<br>
get_copy_tex_image_source(ctx, texImage->TexFormat);<br>
<br>
- ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ,<br>
- srcRb, srcX, srcY, width, height);<br>
+ copytexsubimage_by_slice(ctx, texImage, dims,<br>
+ dstX, dstY, dstZ,<br>
+ srcRb, srcX, srcY, width, height);<br>
}<br>
<br>
check_gen_mipmap(ctx, target, texObj, level);<br>
@@ -3609,9 +3641,9 @@ copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,<br>
struct gl_renderbuffer *srcRb =<br>
get_copy_tex_image_source(ctx, texImage->TexFormat);<br>
<br>
- ctx->Driver.CopyTexSubImage(ctx, dims, texImage,<br>
- xoffset, yoffset, zoffset,<br>
- srcRb, x, y, width, height);<br>
+ copytexsubimage_by_slice(ctx, texImage, dims,<br>
+ xoffset, yoffset, zoffset,<br>
+ srcRb, x, y, width, height);<br>
<br>
check_gen_mipmap(ctx, target, texObj, level);<br>
<br>
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c<br>
index 56dbe85..68c334e 100644<br>
--- a/src/mesa/state_tracker/st_cb_texture.c<br>
+++ b/src/mesa/state_tracker/st_cb_texture.c<br>
@@ -1133,7 +1133,7 @@ fallback_copy_texsubimage(struct gl_context *ctx,<br>
struct st_renderbuffer *strb,<br>
struct st_texture_image *stImage,<br>
GLenum baseFormat,<br>
- GLint destX, GLint destY, GLint destZ,<br>
+ GLint destX, GLint destY, GLint slice,<br>
GLint srcX, GLint srcY,<br>
GLsizei width, GLsizei height)<br>
{<br>
@@ -1154,14 +1154,6 @@ fallback_copy_texsubimage(struct gl_context *ctx,<br>
srcY = strb->Base.Height - srcY - height;<br>
}<br>
<br>
- if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {<br>
- /* Move y/height to z/depth for 1D array textures. */<br>
- destZ = destY;<br>
- destY = 0;<br>
- dst_depth = dst_height;<br>
- dst_height = 1;<br>
- }<br>
-<br>
map = pipe_transfer_map(pipe,<br>
strb->texture,<br>
strb->rtt_level,<br>
@@ -1178,7 +1170,7 @@ fallback_copy_texsubimage(struct gl_context *ctx,<br>
transfer_usage = PIPE_TRANSFER_WRITE;<br>
<br>
texDest = st_texture_image_map(st, stImage, transfer_usage,<br>
- destX, destY, destZ,<br>
+ destX, destY, slice,<br>
dst_width, dst_height, dst_depth);<br>
<br>
if (baseFormat == GL_DEPTH_COMPONENT ||<br>
@@ -1292,7 +1284,7 @@ fallback_copy_texsubimage(struct gl_context *ctx,<br>
static void<br>
st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,<br>
struct gl_texture_image *texImage,<br>
- GLint destX, GLint destY, GLint destZ,<br>
+ GLint destX, GLint destY, GLint slice,<br>
struct gl_renderbuffer *rb,<br>
GLint srcX, GLint srcY, GLsizei width, GLsizei height)<br>
{<br>
@@ -1306,7 +1298,7 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,<br>
enum pipe_format dst_format;<br>
GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);<br>
unsigned bind;<br>
- GLint srcY0, srcY1, yStep;<br>
+ GLint srcY0, srcY1;<br>
<br>
if (!strb || !strb->surface || !stImage->pt) {<br>
debug_printf("%s: null strb or stImage\n", __FUNCTION__);<br>
@@ -1351,12 +1343,10 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,<br>
if (do_flip) {<br>
srcY1 = strb->Base.Height - srcY - height;<br>
srcY0 = srcY1 + height;<br>
- yStep = -1;<br>
}<br>
else {<br>
srcY0 = srcY;<br>
srcY1 = srcY0 + height;<br>
- yStep = 1;<br>
}<br>
<br>
/* Blit the texture.<br>
@@ -1377,39 +1367,20 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,<br>
blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level;<br>
blit.dst.box.x = destX;<br>
blit.dst.box.y = destY;<br>
- blit.dst.box.z = stImage->base.Face + destZ;<br>
+ blit.dst.box.z = stImage->base.Face + slice;<br>
blit.dst.box.width = width;<br>
blit.dst.box.height = height;<br>
blit.dst.box.depth = 1;<br>
blit.mask = st_get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat);<br>
blit.filter = PIPE_TEX_FILTER_NEAREST;<br>
-<br>
- /* 1D array textures need special treatment.<br>
- * Blit rows from the source to layers in the destination. */<br>
- if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {<br>
- int y, layer;<br>
-<br>
- for (y = srcY0, layer = 0; layer < height; y += yStep, layer++) {<br>
- blit.src.box.y = y;<br>
- blit.src.box.height = 1;<br>
- blit.dst.box.y = 0;<br>
- blit.dst.box.height = 1;<br>
- blit.dst.box.z = destY + layer;<br>
-<br>
- pipe->blit(pipe, &blit);<br>
- }<br>
- }<br>
- else {<br>
- /* All the other texture targets. */<br>
- pipe->blit(pipe, &blit);<br>
- }<br>
+ pipe->blit(pipe, &blit);<br>
return;<br>
<br>
fallback:<br>
/* software fallback */<br>
fallback_copy_texsubimage(ctx,<br>
strb, stImage, texImage->_BaseFormat,<br>
- destX, destY, destZ,<br>
+ destX, destY, slice,<br>
srcX, srcY, width, height);<br>
}<br>
<span><font color="#888888"><br>
--<br>
1.8.3.rc0<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>