On 31.07.2014 21:28, Jason Ekstrand wrote: > This, together with the meta path, provides a almost-complete implemetation > of ARB_copy_image. The only case that won't work is if one of the textures > is compressed and has a pitch greater than INT16_MAX. I think that's good > enough to justify turning on the extension. > > Signed-off-by: Jason Ekstrand <jason.ekstr...@intel.com> > --- > src/mesa/drivers/dri/i965/Makefile.sources | 1 + > src/mesa/drivers/dri/i965/brw_context.c | 1 + > src/mesa/drivers/dri/i965/intel_copy_image.c | 172 > +++++++++++++++++++++++++++ > src/mesa/drivers/dri/i965/intel_extensions.c | 1 + > src/mesa/drivers/dri/i965/intel_tex.h | 2 + > 5 files changed, 177 insertions(+) > create mode 100644 src/mesa/drivers/dri/i965/intel_copy_image.c > > diff --git a/src/mesa/drivers/dri/i965/Makefile.sources > b/src/mesa/drivers/dri/i965/Makefile.sources > index e235679..f8327b7 100644 > --- a/src/mesa/drivers/dri/i965/Makefile.sources > +++ b/src/mesa/drivers/dri/i965/Makefile.sources > @@ -8,6 +8,7 @@ i965_FILES = \ > intel_blit.c \ > intel_buffer_objects.c \ > intel_buffers.c \ > + intel_copy_image.c \ > intel_debug.c \ > intel_extensions.c \ > intel_fbo.c \ > diff --git a/src/mesa/drivers/dri/i965/brw_context.c > b/src/mesa/drivers/dri/i965/brw_context.c > index c47ad36..9658590 100644 > --- a/src/mesa/drivers/dri/i965/brw_context.c > +++ b/src/mesa/drivers/dri/i965/brw_context.c > @@ -245,6 +245,7 @@ brw_init_driver_functions(struct brw_context *brw, > intelInitTextureImageFuncs(functions); > intelInitTextureSubImageFuncs(functions); > intelInitTextureCopyImageFuncs(functions); > + intelInitCopyImageFuncs(functions); > intelInitClearFuncs(functions); > intelInitBufferFuncs(functions); > intelInitPixelFuncs(functions); > diff --git a/src/mesa/drivers/dri/i965/intel_copy_image.c > b/src/mesa/drivers/dri/i965/intel_copy_image.c > new file mode 100644 > index 0000000..073b492 > --- /dev/null > +++ b/src/mesa/drivers/dri/i965/intel_copy_image.c > @@ -0,0 +1,172 @@ > +/* > + * Mesa 3-D graphics library > + * > + * Copyright (C) 2014 Intel Corporation All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included > + * in all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: > + * Jason Ekstrand <jason.ekstr...@intel.com> > + */ > + > +#include "intel_tex.h" > +#include "intel_blit.h" > +#include "intel_mipmap_tree.h" > +#include "main/formats.h" > +#include "drivers/common/meta.h" > + > +static bool > +copy_image_with_blitter(struct brw_context *brw, > + struct intel_mipmap_tree *src_mt, int src_level, > + int src_x, int src_y, int src_z, > + struct intel_mipmap_tree *dst_mt, int dst_level, > + int dst_x, int dst_y, int dst_z, > + int src_width, int src_height) > +{ > + GLuint bw, bh; > + int cpp; > + > + /* The blitter doesn't understand multisampling at all. */ > + if (src_mt->num_samples > 0 || dst_mt->num_samples > 0) > + return false; > + > + /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics > + * Data Size Limitations): > + * > + * The BLT engine is capable of transferring very large quantities of > + * graphics data. Any graphics data read from and written to the > + * destination is permitted to represent a number of pixels that > + * occupies up to 65,536 scan lines and up to 32,768 bytes per scan > line > + * at the destination. The maximum number of pixels that may be > + * represented per scan line’s worth of graphics data depends on the > + * color depth. > + * > + * Furthermore, intelEmitCopyBlit (which is called below) uses a signed > + * 16-bit integer to represent buffer pitch, so it can only handle buffer > + * pitches < 32k. > + * > + * As a result of these two limitations, we can only use the blitter to do > + * this copy when the miptree's pitch is less than 32k. > + */ > + if (src_mt->pitch >= 32768 || > + dst_mt->pitch >= 32768) { > + perf_debug("Falling back due to >=32k pitch\n"); > + return false; > + } > + > + if (_mesa_is_format_compressed(src_mt->format)) { > + _mesa_get_format_block_size(src_mt->format, &bw, &bh); > + > + assert(src_x % bw == 0); > + assert(src_y % bw == 0); > + assert(src_width % bw == 0); > + assert(src_height % bw == 0); > + > + src_x /= (int)bw; > + src_y /= (int)bw; > + src_width /= (int)bw; > + src_height /= (int)bw; > + > + cpp = _mesa_get_format_bytes(src_mt->format); > + } else { > + cpp = src_mt->cpp; > + } > + > + if (_mesa_is_format_compressed(dst_mt->format)) { > + _mesa_get_format_block_size(dst_mt->format, &bw, &bh); > + > + assert(dst_x % bw == 0); > + assert(dst_y % bw == 0); > + > + dst_x /= (int)bw; > + dst_y /= (int)bw; > + } > + > + uint32_t src_image_x, src_image_y; > + intel_miptree_get_image_offset(src_mt, src_level, src_z, > + &src_image_x, &src_image_y); > + src_x += src_image_x; > + src_y += src_image_y; > + > + uint32_t dst_image_x, dst_image_y; > + intel_miptree_get_image_offset(dst_mt, dst_level, dst_z, > + &dst_image_x, &dst_image_y); > + dst_x += dst_image_x; > + dst_y += dst_image_y; > + > + return intelEmitCopyBlit(brw, > + cpp, > + src_mt->pitch, > + src_mt->bo, src_mt->offset, > + src_mt->tiling, > + dst_mt->pitch, > + dst_mt->bo, dst_mt->offset, > + dst_mt->tiling, > + src_x, src_y, > + dst_x, dst_y, > + src_width, src_height, > + GL_COPY); > +} > + > +static void > +intel_copy_image_sub_data(struct gl_context *ctx, > + struct gl_texture_image *src_image, > + int src_x, int src_y, int src_z, > + struct gl_texture_image *dst_image, > + int dst_x, int dst_y, int dst_z, > + int src_width, int src_height) > +{ > + struct brw_context *brw = brw_context(ctx); > + struct intel_texture_image *intel_src_image = > intel_texture_image(src_image); > + struct intel_texture_image *intel_dst_image = > intel_texture_image(dst_image); > + > + if (_mesa_meta_CopyImageSubData_uncompressed(ctx, > + src_image, src_x, src_y, > src_z, > + dst_image, dst_x, dst_y, > dst_z, > + src_width, src_height)) { > + return; > + } > + > + /* Cube maps actually have different images per face */ > + if (src_image->TexObject->Target == GL_TEXTURE_CUBE_MAP) > + src_z = src_image->Face; > + if (dst_image->TexObject->Target == GL_TEXTURE_CUBE_MAP) > + dst_z = dst_image->Face; > + > + intel_miptree_all_slices_resolve_hiz(brw, intel_src_image->mt); > + intel_miptree_all_slices_resolve_depth(brw, intel_src_image->mt); > + intel_miptree_resolve_color(brw, intel_src_image->mt); > + > + intel_miptree_all_slices_resolve_hiz(brw, intel_dst_image->mt); > + intel_miptree_all_slices_resolve_depth(brw, intel_dst_image->mt); > + intel_miptree_resolve_color(brw, intel_dst_image->mt); > + > + if (copy_image_with_blitter(brw, intel_src_image->mt, src_image->Level, > + src_x, src_y, src_z, > + intel_dst_image->mt, src_image->Level, > + dst_x, dst_y, dst_z, > + src_width, src_height)) > + return;
above "if" and "return" unnecessary? > +} > + > +void > +intelInitCopyImageFuncs(struct dd_function_table *functions) > +{ > + functions->CopyImageSubData = intel_copy_image_sub_data; > +} > diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c > b/src/mesa/drivers/dri/i965/intel_extensions.c > index 4ee8636..5d71db5 100644 > --- a/src/mesa/drivers/dri/i965/intel_extensions.c > +++ b/src/mesa/drivers/dri/i965/intel_extensions.c > @@ -164,6 +164,7 @@ intelInitExtensions(struct gl_context *ctx) > > ctx->Extensions.ARB_buffer_storage = true; > ctx->Extensions.ARB_clear_texture = true; > + ctx->Extensions.ARB_copy_image = true; > ctx->Extensions.ARB_depth_buffer_float = true; > ctx->Extensions.ARB_depth_clamp = true; > ctx->Extensions.ARB_depth_texture = true; > diff --git a/src/mesa/drivers/dri/i965/intel_tex.h > b/src/mesa/drivers/dri/i965/intel_tex.h > index a9f2db6..27f7f11 100644 > --- a/src/mesa/drivers/dri/i965/intel_tex.h > +++ b/src/mesa/drivers/dri/i965/intel_tex.h > @@ -42,6 +42,8 @@ void intelInitTextureSubImageFuncs(struct dd_function_table > *functions); > > void intelInitTextureCopyImageFuncs(struct dd_function_table *functions); > > +void intelInitCopyImageFuncs(struct dd_function_table *functions); > + > void intelSetTexBuffer(__DRIcontext *pDRICtx, > GLint target, __DRIdrawable *pDraw); > void intelSetTexBuffer2(__DRIcontext *pDRICtx, > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev