sync with tizen_2.2
[sdk/emulator/qemu.git] / gl / mesa / src / mesa / drivers / dri / radeon / radeon_tex_copy.c
1 /*
2  * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
3  *
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a 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, sublicense, 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
16  * portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  */
27
28 #include "radeon_common.h"
29 #include "radeon_texture.h"
30
31 #include "main/enums.h"
32 #include "main/image.h"
33 #include "main/teximage.h"
34 #include "main/texstate.h"
35 #include "drivers/common/meta.h"
36
37 #include "radeon_mipmap_tree.h"
38
39 static GLboolean
40 do_copy_texsubimage(struct gl_context *ctx,
41                     struct radeon_tex_obj *tobj,
42                     radeon_texture_image *timg,
43                     GLint dstx, GLint dsty,
44                     struct radeon_renderbuffer *rrb,
45                     GLint x, GLint y,
46                     GLsizei width, GLsizei height)
47 {
48     radeonContextPtr radeon = RADEON_CONTEXT(ctx);
49     const GLuint face = timg->base.Base.Face;
50     const GLuint level = timg->base.Base.Level;
51     unsigned src_bpp;
52     unsigned dst_bpp;
53     gl_format src_mesaformat;
54     gl_format dst_mesaformat;
55     unsigned flip_y;
56
57     if (!radeon->vtbl.blit) {
58         return GL_FALSE;
59     }
60
61     // This is software renderbuffer, fallback to swrast
62     if (!rrb) {
63         return GL_FALSE;
64     }
65
66     if (_mesa_get_format_bits(timg->base.Base.TexFormat, GL_DEPTH_BITS) > 0) {
67         /* copying depth values */
68         flip_y = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Type == GL_NONE;
69     } else {
70         /* copying color */
71         flip_y = ctx->ReadBuffer->Attachment[BUFFER_COLOR0].Type == GL_NONE;
72     }
73
74     if (!timg->mt) {
75         radeon_validate_texture_miptree(ctx, &tobj->base);
76     }
77
78     assert(rrb->bo);
79     assert(timg->mt);
80     assert(timg->mt->bo);
81     assert(timg->base.Base.Width >= dstx + width);
82     assert(timg->base.Base.Height >= dsty + height);
83
84     intptr_t src_offset = rrb->draw_offset;
85     intptr_t dst_offset = radeon_miptree_image_offset(timg->mt, face, level);
86
87     if (0) {
88         fprintf(stderr, "%s: copying to face %d, level %d\n",
89                 __FUNCTION__, face, level);
90         fprintf(stderr, "to: x %d, y %d, offset %d\n", dstx, dsty, (uint32_t) dst_offset);
91         fprintf(stderr, "from (%dx%d) width %d, height %d, offset %d, pitch %d\n",
92                 x, y, rrb->base.Base.Width, rrb->base.Base.Height, (uint32_t) src_offset, rrb->pitch/rrb->cpp);
93         fprintf(stderr, "src size %d, dst size %d\n", rrb->bo->size, timg->mt->bo->size);
94
95     }
96
97     src_mesaformat = rrb->base.Base.Format;
98     dst_mesaformat = timg->base.Base.TexFormat;
99     src_bpp = _mesa_get_format_bytes(src_mesaformat);
100     dst_bpp = _mesa_get_format_bytes(dst_mesaformat);
101     if (!radeon->vtbl.check_blit(dst_mesaformat, rrb->pitch / rrb->cpp)) {
102             /* depth formats tend to be special */
103             if (_mesa_get_format_bits(dst_mesaformat, GL_DEPTH_BITS) > 0)
104                     return GL_FALSE;
105
106             if (src_bpp != dst_bpp)
107                     return GL_FALSE;
108
109             switch (dst_bpp) {
110             case 2:
111                     src_mesaformat = MESA_FORMAT_RGB565;
112                     dst_mesaformat = MESA_FORMAT_RGB565;
113                     break;
114             case 4:
115                     src_mesaformat = MESA_FORMAT_ARGB8888;
116                     dst_mesaformat = MESA_FORMAT_ARGB8888;
117                     break;
118             case 1:
119                     src_mesaformat = MESA_FORMAT_A8;
120                     dst_mesaformat = MESA_FORMAT_A8;
121                     break;
122             default:
123                     return GL_FALSE;
124             }
125     }
126
127     /* blit from src buffer to texture */
128     return radeon->vtbl.blit(ctx, rrb->bo, src_offset, src_mesaformat, rrb->pitch/rrb->cpp,
129                              rrb->base.Base.Width, rrb->base.Base.Height, x, y,
130                              timg->mt->bo, dst_offset, dst_mesaformat,
131                              timg->mt->levels[level].rowstride / dst_bpp,
132                              timg->base.Base.Width, timg->base.Base.Height,
133                              dstx, dsty, width, height, flip_y);
134 }
135
136 void
137 radeonCopyTexSubImage2D(struct gl_context *ctx,
138                         struct gl_texture_image *texImage,
139                         GLint xoffset, GLint yoffset,
140                         struct gl_renderbuffer *rb,
141                         GLint x, GLint y,
142                         GLsizei width, GLsizei height)
143 {
144     radeonContextPtr radeon = RADEON_CONTEXT(ctx);
145     radeon_prepare_render(radeon);
146
147     if (!do_copy_texsubimage(ctx,
148                              radeon_tex_obj(texImage->TexObject),
149                              (radeon_texture_image *)texImage,
150                              xoffset, yoffset,
151                              radeon_renderbuffer(rb),                                                        x, y, width, height)) {
152
153         radeon_print(RADEON_FALLBACKS, RADEON_NORMAL,
154                      "Falling back to sw for glCopyTexSubImage2D\n");
155
156         _mesa_meta_CopyTexSubImage2D(ctx, texImage,
157                                      xoffset, yoffset,
158                                      rb, x, y, width, height);
159     }
160 }