X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fintel_copy_image.c;h=1ca6003cd126d778d34e4fceb4315c7c9e9a25b0;hb=22d9a4824baf0bf89bb8e39025ad01fecb213888;hp=08b7623e63dc88e309874d974fade8e7f1e2bf70;hpb=f709a0845792540544982740fa47be672825ee8a;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/intel_copy_image.c b/src/mesa/drivers/dri/i965/intel_copy_image.c index 08b7623e63d..1ca6003cd12 100644 --- a/src/mesa/drivers/dri/i965/intel_copy_image.c +++ b/src/mesa/drivers/dri/i965/intel_copy_image.c @@ -25,6 +25,7 @@ * Jason Ekstrand */ +#include "brw_blorp.h" #include "intel_fbo.h" #include "intel_tex.h" #include "intel_blit.h" @@ -48,6 +49,9 @@ copy_image_with_blitter(struct brw_context *brw, if (src_mt->num_samples > 0 || dst_mt->num_samples > 0) return false; + if (src_mt->format == MESA_FORMAT_S_UINT8) + return false; + /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics * Data Size Limitations): * @@ -140,9 +144,9 @@ copy_image_with_memcpy(struct brw_context *brw, _mesa_get_format_block_size(src_mt->format, &src_bw, &src_bh); assert(src_width % src_bw == 0); - assert(src_height % src_bw == 0); + assert(src_height % src_bh == 0); assert(src_x % src_bw == 0); - assert(src_y % src_bw == 0); + assert(src_y % src_bh == 0); /* If we are on the same miptree, same level, and same slice, then * intel_miptree_map won't let us map it twice. We have to do things a @@ -153,7 +157,7 @@ copy_image_with_memcpy(struct brw_context *brw, if (same_slice) { assert(dst_x % src_bw == 0); - assert(dst_y % src_bw == 0); + assert(dst_y % src_bh == 0); map_x1 = MIN2(src_x, dst_x); map_y1 = MIN2(src_y, dst_y); @@ -198,72 +202,41 @@ copy_image_with_memcpy(struct brw_context *brw, } } - static void -intel_copy_image_sub_data(struct gl_context *ctx, - struct gl_texture_image *src_image, - struct gl_renderbuffer *src_renderbuffer, - int src_x, int src_y, int src_z, - struct gl_texture_image *dst_image, - struct gl_renderbuffer *dst_renderbuffer, - int dst_x, int dst_y, int dst_z, - int src_width, int src_height) +copy_miptrees(struct brw_context *brw, + struct intel_mipmap_tree *src_mt, + int src_x, int src_y, int src_z, unsigned src_level, + struct intel_mipmap_tree *dst_mt, + int dst_x, int dst_y, int dst_z, unsigned dst_level, + int src_width, int src_height) { - struct brw_context *brw = brw_context(ctx); - struct intel_mipmap_tree *src_mt, *dst_mt; - unsigned src_level, dst_level; - GLuint bw, bh; - - if (_mesa_meta_CopyImageSubData_uncompressed(ctx, - src_image, src_renderbuffer, - src_x, src_y, src_z, - dst_image, dst_renderbuffer, - dst_x, dst_y, dst_z, - src_width, src_height)) { + struct gl_context *ctx = &brw->ctx; + unsigned bw, bh; + + if (brw->gen >= 6 && + brw->format_supported_as_render_target[dst_mt->format] && + !_mesa_is_format_compressed(src_mt->format)) { + + /* We'll use the destination format for both images */ + mesa_format format = dst_mt->format; + + brw_blorp_blit_miptrees(brw, + src_mt, src_level, src_z, format, SWIZZLE_XYZW, + dst_mt, dst_level, dst_z, format, + src_x, src_y, + src_x + src_width, src_y + src_height, + dst_x, dst_y, + dst_x + src_width, dst_y + src_height, + GL_NEAREST, false, false, /* mirror */ + false, false); return; } - if (src_image) { - src_mt = intel_texture_image(src_image)->mt; - } else { - assert(src_renderbuffer); - src_mt = intel_renderbuffer(src_renderbuffer)->mt; - src_image = src_renderbuffer->TexImage; - } - - if (dst_image) { - dst_mt = intel_texture_image(dst_image)->mt; - } else { - assert(dst_renderbuffer); - dst_mt = intel_renderbuffer(dst_renderbuffer)->mt; - dst_image = dst_renderbuffer->TexImage; - } - if (src_mt->num_samples > 0 || dst_mt->num_samples > 0) { - _mesa_problem(ctx, "Failed to copy multisampled texture with meta path\n"); + _mesa_problem(ctx, "Failed to copy multisampled texture with BLORP\n"); return; } - if (src_image) { - src_level = src_image->Level + src_image->TexObject->MinLevel; - - /* Cube maps actually have different images per face */ - if (src_image->TexObject->Target == GL_TEXTURE_CUBE_MAP) - src_z = src_image->Face; - } else { - src_level = 0; - } - - if (dst_image) { - dst_level = dst_image->Level + dst_image->TexObject->MinLevel; - - /* Cube maps actually have different images per face */ - if (dst_image->TexObject->Target == GL_TEXTURE_CUBE_MAP) - dst_z = dst_image->Face; - } else { - dst_level = 0; - } - /* We are now going to try and copy the texture using the blitter. If * that fails, we will fall back mapping the texture and using memcpy. * In either case, we need to do a full resolve. @@ -306,6 +279,83 @@ intel_copy_image_sub_data(struct gl_context *ctx, src_width, src_height); } +static void +intel_copy_image_sub_data(struct gl_context *ctx, + struct gl_texture_image *src_image, + struct gl_renderbuffer *src_renderbuffer, + int src_x, int src_y, int src_z, + struct gl_texture_image *dst_image, + struct gl_renderbuffer *dst_renderbuffer, + int dst_x, int dst_y, int dst_z, + int src_width, int src_height) +{ + struct brw_context *brw = brw_context(ctx); + struct intel_mipmap_tree *src_mt, *dst_mt; + unsigned src_level, dst_level; + + if (brw->gen < 6 && + _mesa_meta_CopyImageSubData_uncompressed(ctx, + src_image, src_renderbuffer, + src_x, src_y, src_z, + dst_image, dst_renderbuffer, + dst_x, dst_y, dst_z, + src_width, src_height)) { + return; + } + + if (src_image) { + src_mt = intel_texture_image(src_image)->mt; + src_level = src_image->Level + src_image->TexObject->MinLevel; + + /* Cube maps actually have different images per face */ + if (src_image->TexObject->Target == GL_TEXTURE_CUBE_MAP) + src_z = src_image->Face; + + src_z += src_image->TexObject->MinLayer; + } else { + assert(src_renderbuffer); + src_mt = intel_renderbuffer(src_renderbuffer)->mt; + src_image = src_renderbuffer->TexImage; + src_level = 0; + } + + if (dst_image) { + dst_mt = intel_texture_image(dst_image)->mt; + + dst_level = dst_image->Level + dst_image->TexObject->MinLevel; + + /* Cube maps actually have different images per face */ + if (dst_image->TexObject->Target == GL_TEXTURE_CUBE_MAP) + dst_z = dst_image->Face; + + dst_z += dst_image->TexObject->MinLayer; + } else { + assert(dst_renderbuffer); + dst_mt = intel_renderbuffer(dst_renderbuffer)->mt; + dst_image = dst_renderbuffer->TexImage; + dst_level = 0; + } + + copy_miptrees(brw, src_mt, src_x, src_y, src_z, src_level, + dst_mt, dst_x, dst_y, dst_z, dst_level, + src_width, src_height); + + /* CopyImage only works for equal formats, texture view equivalence + * classes, and a couple special cases for compressed textures. + * + * Notably, GL_DEPTH_STENCIL does not appear in any equivalence + * classes, so we know the formats must be the same, and thus both + * will either have stencil, or not. They can't be mismatched. + */ + assert((src_mt->stencil_mt != NULL) == (dst_mt->stencil_mt != NULL)); + + if (dst_mt->stencil_mt) { + copy_miptrees(brw, src_mt->stencil_mt, src_x, src_y, src_z, src_level, + dst_mt->stencil_mt, dst_x, dst_y, dst_z, dst_level, + src_width, src_height); + } +} + void intelInitCopyImageFuncs(struct dd_function_table *functions) {