17255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora/*
27255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
37255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora *
47255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * All Rights Reserved.
57255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora *
67255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * Permission is hereby granted, free of charge, to any person obtaining
77255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * a copy of this software and associated documentation files (the
87255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * "Software"), to deal in the Software without restriction, including
97255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * without limitation the rights to use, copy, modify, merge, publish,
107255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * distribute, sublicense, and/or sell copies of the Software, and to
117255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * permit persons to whom the Software is furnished to do so, subject to
127255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * the following conditions:
137255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora *
147255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * The above copyright notice and this permission notice (including the
157255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * next paragraph) shall be included in all copies or substantial
167255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * portions of the Software.
177255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora *
187255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
197255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
207255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
217255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
227255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
237255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
247255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
257255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora *
267255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora */
277255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
287255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora#include "radeon_common.h"
298a4d7393bd8a752eba2ee687c1c3e2df5c82745dMaciej Cencora#include "radeon_texture.h"
307255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
31abc847c20da92e52f29da40c6dd014f5caf46d8bMaciej Cencora#include "main/enums.h"
327255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora#include "main/image.h"
337255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora#include "main/teximage.h"
347255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora#include "main/texstate.h"
357255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora#include "drivers/common/meta.h"
367255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
377255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora#include "radeon_mipmap_tree.h"
387255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
397255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencorastatic GLboolean
40f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdo_copy_texsubimage(struct gl_context *ctx,
417255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora                    struct radeon_tex_obj *tobj,
427255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora                    radeon_texture_image *timg,
437255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora                    GLint dstx, GLint dsty,
4456b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul                    struct radeon_renderbuffer *rrb,
457255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora                    GLint x, GLint y,
467255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora                    GLsizei width, GLsizei height)
477255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora{
488a4d7393bd8a752eba2ee687c1c3e2df5c82745dMaciej Cencora    radeonContextPtr radeon = RADEON_CONTEXT(ctx);
4956b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul    const GLuint face = timg->base.Base.Face;
5056b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul    const GLuint level = timg->base.Base.Level;
513594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher    unsigned src_bpp;
523594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher    unsigned dst_bpp;
533594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher    gl_format src_mesaformat;
543594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher    gl_format dst_mesaformat;
55a68e8a4eaadfe2a1e4999d5e378c7d9fa99dc656Maciej Cencora    unsigned flip_y;
567255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
578ccd83ab921380953a0e5cebd941444f85c23ed1Maciej Cencora    if (!radeon->vtbl.blit) {
588ccd83ab921380953a0e5cebd941444f85c23ed1Maciej Cencora        return GL_FALSE;
598ccd83ab921380953a0e5cebd941444f85c23ed1Maciej Cencora    }
608ccd83ab921380953a0e5cebd941444f85c23ed1Maciej Cencora
6156b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul    // This is software renderbuffer, fallback to swrast
6256b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul    if (!rrb) {
6356b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul        return GL_FALSE;
6456b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul    }
6556b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul
66abdfa0b4f1e5ae0bd3d71ae7099b6bb7c2bfae71Brian Paul    if (_mesa_get_format_bits(timg->base.Base.TexFormat, GL_DEPTH_BITS) > 0) {
6756b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul        /* copying depth values */
68a68e8a4eaadfe2a1e4999d5e378c7d9fa99dc656Maciej Cencora        flip_y = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Type == GL_NONE;
697255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora    } else {
702750809b2e9a7d24d83d01f0a1d5bb5dce027b4cBrian Paul        /* copying color */
71a68e8a4eaadfe2a1e4999d5e378c7d9fa99dc656Maciej Cencora        flip_y = ctx->ReadBuffer->Attachment[BUFFER_COLOR0].Type == GL_NONE;
727255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora    }
737255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
74cd5f167353f16fb4f5b349002625b704f3e23778Maciej Cencora    if (!timg->mt) {
756f6bd8aedcf2b2f0e1ca9a1fa7ded1cb1f5a88edPauli Nieminen        radeon_validate_texture_miptree(ctx, &tobj->base.Sampler, &tobj->base);
76cd5f167353f16fb4f5b349002625b704f3e23778Maciej Cencora    }
77cd5f167353f16fb4f5b349002625b704f3e23778Maciej Cencora
781a8a230a61289392e8300901dfabd7911799cbc3Maciej Cencora    assert(rrb->bo);
79d3004d9156e261d81adcae31d55a4b782433cd6bVinson Lee    assert(timg->mt);
80cd5f167353f16fb4f5b349002625b704f3e23778Maciej Cencora    assert(timg->mt->bo);
81abdfa0b4f1e5ae0bd3d71ae7099b6bb7c2bfae71Brian Paul    assert(timg->base.Base.Width >= dstx + width);
82abdfa0b4f1e5ae0bd3d71ae7099b6bb7c2bfae71Brian Paul    assert(timg->base.Base.Height >= dsty + height);
837255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
844b6dee08652706d02939844fe209cddbae8966e4Maciej Cencora    intptr_t src_offset = rrb->draw_offset;
8556b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul    intptr_t dst_offset = radeon_miptree_image_offset(timg->mt, face, level);
867255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
87784cca9fa527de771754d76545970f78094b9adfMaciej Cencora    if (0) {
887255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora        fprintf(stderr, "%s: copying to face %d, level %d\n",
8956b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul                __FUNCTION__, face, level);
907255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora        fprintf(stderr, "to: x %d, y %d, offset %d\n", dstx, dsty, (uint32_t) dst_offset);
91a1428868a66ab70a762ad863dafa00c3099f3d8aMaciej Cencora        fprintf(stderr, "from (%dx%d) width %d, height %d, offset %d, pitch %d\n",
92c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul                x, y, rrb->base.Base.Width, rrb->base.Base.Height, (uint32_t) src_offset, rrb->pitch/rrb->cpp);
93cd5f167353f16fb4f5b349002625b704f3e23778Maciej Cencora        fprintf(stderr, "src size %d, dst size %d\n", rrb->bo->size, timg->mt->bo->size);
947255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
957255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora    }
967255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
97c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul    src_mesaformat = rrb->base.Base.Format;
98abdfa0b4f1e5ae0bd3d71ae7099b6bb7c2bfae71Brian Paul    dst_mesaformat = timg->base.Base.TexFormat;
993594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher    src_bpp = _mesa_get_format_bytes(src_mesaformat);
1003594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher    dst_bpp = _mesa_get_format_bytes(dst_mesaformat);
101b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie    if (!radeon->vtbl.check_blit(dst_mesaformat, rrb->pitch / rrb->cpp)) {
102ffd625d4aaf145eb28fc76617e95ffc3fdfd54ccAlex Deucher	    /* depth formats tend to be special */
103ffd625d4aaf145eb28fc76617e95ffc3fdfd54ccAlex Deucher	    if (_mesa_get_format_bits(dst_mesaformat, GL_DEPTH_BITS) > 0)
104ffd625d4aaf145eb28fc76617e95ffc3fdfd54ccAlex Deucher		    return GL_FALSE;
105ffd625d4aaf145eb28fc76617e95ffc3fdfd54ccAlex Deucher
1063594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher	    if (src_bpp != dst_bpp)
1073594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher		    return GL_FALSE;
1083594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher
1093594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher	    switch (dst_bpp) {
1103594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher	    case 2:
1113594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher		    src_mesaformat = MESA_FORMAT_RGB565;
1123594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher		    dst_mesaformat = MESA_FORMAT_RGB565;
1133594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher		    break;
1143594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher	    case 4:
1153594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher		    src_mesaformat = MESA_FORMAT_ARGB8888;
1163594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher		    dst_mesaformat = MESA_FORMAT_ARGB8888;
1173594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher		    break;
1183594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher	    case 1:
1193594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher		    src_mesaformat = MESA_FORMAT_A8;
1203594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher		    dst_mesaformat = MESA_FORMAT_A8;
1213594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher		    break;
1223594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher	    default:
1233594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher		    return GL_FALSE;
1243594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher	    }
1253594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher    }
1263594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher
1277255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora    /* blit from src buffer to texture */
1283594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher    return radeon->vtbl.blit(ctx, rrb->bo, src_offset, src_mesaformat, rrb->pitch/rrb->cpp,
129c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul                             rrb->base.Base.Width, rrb->base.Base.Height, x, y,
1303594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher                             timg->mt->bo, dst_offset, dst_mesaformat,
1313594bf233d16ceb21e97fcdfb57ea45cb0c5e41bAlex Deucher                             timg->mt->levels[level].rowstride / dst_bpp,
132e7349a55f75e8d1155684b5ad0f9dede55eb8549Eric Anholt                             timg->base.Base.Width, timg->base.Base.Height,
133a68e8a4eaadfe2a1e4999d5e378c7d9fa99dc656Maciej Cencora                             dstx, dsty, width, height, flip_y);
1347255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora}
1357255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
1368a4d7393bd8a752eba2ee687c1c3e2df5c82745dMaciej Cencoravoid
137cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian PaulradeonCopyTexSubImage(struct gl_context *ctx, GLuint dims,
138cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul                      struct gl_texture_image *texImage,
139cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul                      GLint xoffset, GLint yoffset, GLint zoffset,
140cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul                      struct gl_renderbuffer *rb,
141cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul                      GLint x, GLint y,
142cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul                      GLsizei width, GLsizei height)
1437255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora{
144646d2e9fbc41bf49075013009e9583bec4a51168Mario Kleiner    radeonContextPtr radeon = RADEON_CONTEXT(ctx);
145646d2e9fbc41bf49075013009e9583bec4a51168Mario Kleiner    radeon_prepare_render(radeon);
146646d2e9fbc41bf49075013009e9583bec4a51168Mario Kleiner
147cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul    if (dims != 2 || !do_copy_texsubimage(ctx,
14856b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul                             radeon_tex_obj(texImage->TexObject),
14956b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul                             (radeon_texture_image *)texImage,
15056b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul                             xoffset, yoffset,
15156b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul                             radeon_renderbuffer(rb),                                                        x, y, width, height)) {
1527255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
153abc847c20da92e52f29da40c6dd014f5caf46d8bMaciej Cencora        radeon_print(RADEON_FALLBACKS, RADEON_NORMAL,
154abc847c20da92e52f29da40c6dd014f5caf46d8bMaciej Cencora                     "Falling back to sw for glCopyTexSubImage2D\n");
1557255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora
156cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul        _mesa_meta_CopyTexSubImage(ctx, dims, texImage,
157cd9ab2584f5e2a5eb0e96a948e6aedc9a33c886dBrian Paul                                   xoffset, yoffset, zoffset,
15856b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul                                     rb, x, y, width, height);
1597255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora    }
1607255a5486dcb3acd5d7d267b9f546aff38685555Maciej Cencora}
161