1 /**************************************************************************
2  *
3  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 #include "main/mtypes.h"
29 #include "main/enums.h"
30 #include "main/image.h"
31 #include "main/teximage.h"
32 #include "main/texstate.h"
33 #include "main/fbobject.h"
34 
35 #include "drivers/common/meta.h"
36 
37 #include "intel_screen.h"
38 #include "intel_context.h"
39 #include "intel_mipmap_tree.h"
40 #include "intel_regions.h"
41 #include "intel_fbo.h"
42 #include "intel_tex.h"
43 #include "intel_blit.h"
44 
45 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
46 
47 
48 bool
intel_copy_texsubimage(struct intel_context * intel,struct intel_texture_image * intelImage,GLint dstx,GLint dsty,struct intel_renderbuffer * irb,GLint x,GLint y,GLsizei width,GLsizei height)49 intel_copy_texsubimage(struct intel_context *intel,
50                        struct intel_texture_image *intelImage,
51                        GLint dstx, GLint dsty,
52                        struct intel_renderbuffer *irb,
53                        GLint x, GLint y, GLsizei width, GLsizei height)
54 {
55    struct gl_context *ctx = &intel->ctx;
56    struct intel_region *region;
57    const GLenum internalFormat = intelImage->base.Base.InternalFormat;
58    bool copy_supported = false;
59    bool copy_supported_with_alpha_override = false;
60 
61    intel_prepare_render(intel);
62 
63    if (!intelImage->mt || !irb || !irb->mt) {
64       if (unlikely(INTEL_DEBUG & DEBUG_PERF))
65 	 fprintf(stderr, "%s fail %p %p (0x%08x)\n",
66 		 __FUNCTION__, intelImage->mt, irb, internalFormat);
67       return false;
68    } else {
69       region = irb->mt->region;
70       assert(region);
71    }
72 
73    copy_supported = intelImage->base.Base.TexFormat == intel_rb_format(irb);
74 
75    /* Converting ARGB8888 to XRGB8888 is trivial: ignore the alpha bits */
76    if (intel_rb_format(irb) == MESA_FORMAT_ARGB8888 &&
77        intelImage->base.Base.TexFormat == MESA_FORMAT_XRGB8888) {
78       copy_supported = true;
79    }
80 
81    /* Converting XRGB8888 to ARGB8888 requires setting the alpha bits to 1.0 */
82    if (intel_rb_format(irb) == MESA_FORMAT_XRGB8888 &&
83        intelImage->base.Base.TexFormat == MESA_FORMAT_ARGB8888) {
84       copy_supported_with_alpha_override = true;
85    }
86 
87    if (!copy_supported && !copy_supported_with_alpha_override) {
88       if (unlikely(INTEL_DEBUG & DEBUG_PERF))
89 	 fprintf(stderr, "%s mismatched formats %s, %s\n",
90 		 __FUNCTION__,
91 		 _mesa_get_format_name(intelImage->base.Base.TexFormat),
92 		 _mesa_get_format_name(intel_rb_format(irb)));
93       return false;
94    }
95 
96    {
97       GLuint image_x, image_y;
98       GLshort src_pitch;
99 
100       /* get dest x/y in destination texture */
101       intel_miptree_get_image_offset(intelImage->mt,
102 				     intelImage->base.Base.Level,
103 				     intelImage->base.Base.Face,
104 				     0,
105 				     &image_x, &image_y);
106 
107       /* The blitter can't handle Y-tiled buffers. */
108       if (intelImage->mt->region->tiling == I915_TILING_Y) {
109 	 return false;
110       }
111 
112       if (_mesa_is_winsys_fbo(ctx->ReadBuffer)) {
113 	 /* Flip vertical orientation for system framebuffers */
114 	 y = ctx->ReadBuffer->Height - (y + height);
115 	 src_pitch = -region->pitch;
116       } else {
117 	 /* reading from a FBO, y is already oriented the way we like */
118 	 src_pitch = region->pitch;
119       }
120 
121       /* blit from src buffer to texture */
122       if (!intelEmitCopyBlit(intel,
123 			     intelImage->mt->cpp,
124 			     src_pitch,
125 			     region->bo,
126 			     0,
127 			     region->tiling,
128 			     intelImage->mt->region->pitch,
129 			     intelImage->mt->region->bo,
130 			     0,
131 			     intelImage->mt->region->tiling,
132 			     irb->draw_x + x, irb->draw_y + y,
133 			     image_x + dstx, image_y + dsty,
134 			     width, height,
135 			     GL_COPY)) {
136 	 return false;
137       }
138    }
139 
140    if (copy_supported_with_alpha_override)
141       intel_set_teximage_alpha_to_one(ctx, intelImage);
142 
143    return true;
144 }
145 
146 
147 static void
intelCopyTexSubImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLint xoffset,GLint yoffset,GLint zoffset,struct gl_renderbuffer * rb,GLint x,GLint y,GLsizei width,GLsizei height)148 intelCopyTexSubImage(struct gl_context *ctx, GLuint dims,
149                      struct gl_texture_image *texImage,
150                      GLint xoffset, GLint yoffset, GLint zoffset,
151                      struct gl_renderbuffer *rb,
152                      GLint x, GLint y,
153                      GLsizei width, GLsizei height)
154 {
155    if (dims == 3 || !intel_copy_texsubimage(intel_context(ctx),
156                                intel_texture_image(texImage),
157                                xoffset, yoffset,
158                                intel_renderbuffer(rb), x, y, width, height)) {
159       fallback_debug("%s - fallback to swrast\n", __FUNCTION__);
160       _mesa_meta_CopyTexSubImage(ctx, dims, texImage,
161                                  xoffset, yoffset, zoffset,
162                                  rb, x, y, width, height);
163    }
164 }
165 
166 
167 void
intelInitTextureCopyImageFuncs(struct dd_function_table * functions)168 intelInitTextureCopyImageFuncs(struct dd_function_table *functions)
169 {
170    functions->CopyTexSubImage = intelCopyTexSubImage;
171 }
172