1 /*
2  * Copyright 2003 VMware, Inc.
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 #include "main/mtypes.h"
27 #include "main/enums.h"
28 #include "main/image.h"
29 #include "main/teximage.h"
30 #include "main/texobj.h"
31 #include "main/texstate.h"
32 #include "main/fbobject.h"
33 
34 #include "drivers/common/meta.h"
35 
36 #include "intel_screen.h"
37 #include "intel_mipmap_tree.h"
38 #include "intel_fbo.h"
39 #include "intel_tex.h"
40 #include "intel_blit.h"
41 #include "brw_context.h"
42 
43 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
44 
45 
46 static bool
intel_copy_texsubimage(struct brw_context * brw,struct intel_texture_image * intelImage,GLint dstx,GLint dsty,GLint slice,struct intel_renderbuffer * irb,GLint x,GLint y,GLsizei width,GLsizei height)47 intel_copy_texsubimage(struct brw_context *brw,
48                        struct intel_texture_image *intelImage,
49                        GLint dstx, GLint dsty, GLint slice,
50                        struct intel_renderbuffer *irb,
51                        GLint x, GLint y, GLsizei width, GLsizei height)
52 {
53    const GLenum internalFormat = intelImage->base.Base.InternalFormat;
54 
55    if (!intelImage->mt || !irb || !irb->mt) {
56       if (unlikely(INTEL_DEBUG & DEBUG_PERF))
57 	 fprintf(stderr, "%s fail %p %p (0x%08x)\n",
58 		 __func__, intelImage->mt, irb, internalFormat);
59       return false;
60    }
61 
62    /* No pixel transfer operations (zoom, bias, mapping), just a blit */
63    if (brw->ctx._ImageTransferState)
64       return false;
65 
66    intel_prepare_render(brw);
67 
68    /* glCopyTexSubImage() can be called on a multisampled renderbuffer (if
69     * that renderbuffer is associated with the window system framebuffer),
70     * however the hardware blitter can't handle this case, so fall back to
71     * meta (which can, since it uses ReadPixels).
72     */
73    if (irb->Base.Base.NumSamples != 0)
74       return false;
75 
76    /* glCopyTexSubImage() can't be called on a multisampled texture. */
77    assert(intelImage->base.Base.NumSamples == 0);
78 
79    /* account for view parameters and face index */
80    int dst_level = intelImage->base.Base.Level +
81                    intelImage->base.Base.TexObject->MinLevel;
82    int dst_slice = slice + intelImage->base.Base.Face +
83                    intelImage->base.Base.TexObject->MinLayer;
84 
85    /* blit from src buffer to texture */
86    return intel_miptree_blit(brw,
87                              irb->mt, irb->mt_level, irb->mt_layer,
88                              x, y, irb->Base.Base.Name == 0,
89                              intelImage->mt, dst_level, dst_slice,
90                              dstx, dsty, false,
91                              width, height, GL_COPY);
92 }
93 
94 
95 static void
intelCopyTexSubImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLint xoffset,GLint yoffset,GLint slice,struct gl_renderbuffer * rb,GLint x,GLint y,GLsizei width,GLsizei height)96 intelCopyTexSubImage(struct gl_context *ctx, GLuint dims,
97                      struct gl_texture_image *texImage,
98                      GLint xoffset, GLint yoffset, GLint slice,
99                      struct gl_renderbuffer *rb,
100                      GLint x, GLint y,
101                      GLsizei width, GLsizei height)
102 {
103    struct brw_context *brw = brw_context(ctx);
104 
105    /* Try BLORP first.  It can handle almost everything. */
106    if (brw_blorp_copytexsubimage(brw, rb, texImage, slice, x, y,
107                                  xoffset, yoffset, width, height))
108       return;
109 
110    /* Next, try the BLT engine. */
111    if (intel_copy_texsubimage(brw,
112                               intel_texture_image(texImage),
113                               xoffset, yoffset, slice,
114                               intel_renderbuffer(rb), x, y, width, height)) {
115       return;
116    }
117 
118    /* Finally, fall back to meta.  This will likely be slow. */
119    perf_debug("%s - fallback to swrast\n", __func__);
120    _mesa_meta_CopyTexSubImage(ctx, dims, texImage,
121                               xoffset, yoffset, slice,
122                               rb, x, y, width, height);
123 }
124 
125 
126 void
intelInitTextureCopyImageFuncs(struct dd_function_table * functions)127 intelInitTextureCopyImageFuncs(struct dd_function_table *functions)
128 {
129    functions->CopyTexSubImage = intelCopyTexSubImage;
130 }
131