コード例 #1
0
/* Copy a block of pixels from one surface to another. */
static void r300_resource_copy_region(struct pipe_context *pipe,
                                      struct pipe_resource *dst,
                                      unsigned dst_level,
                                      unsigned dstx, unsigned dsty, unsigned dstz,
                                      struct pipe_resource *src,
                                      unsigned src_level,
                                      const struct pipe_box *src_box)
{
    enum pipe_format old_format = dst->format;
    enum pipe_format new_format = old_format;
    boolean is_depth;
    if (!pipe->screen->is_format_supported(pipe->screen,
                                           old_format, src->target,
                                           src->nr_samples,
                                           PIPE_BIND_RENDER_TARGET |
                                           PIPE_BIND_SAMPLER_VIEW, 0) &&
        util_format_is_plain(old_format)) {
        switch (util_format_get_blocksize(old_format)) {
            case 1:
                new_format = PIPE_FORMAT_I8_UNORM;
                break;
            case 2:
                new_format = PIPE_FORMAT_B4G4R4A4_UNORM;
                break;
            case 4:
                new_format = PIPE_FORMAT_B8G8R8A8_UNORM;
                break;
            case 8:
                new_format = PIPE_FORMAT_R16G16B16A16_UNORM;
                break;
            default:
                debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n"
                             "r300: surface_copy: Software fallback doesn't work for tiled textures.\n",
                             util_format_short_name(old_format));
        }
    }

    is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
    if (is_depth) {
        r300_flush_depth_stencil(pipe, src, src_level, src_box->z);
    }
    if (old_format != new_format) {
        r300_texture_reinterpret_format(pipe->screen,
                                        dst, new_format);
        r300_texture_reinterpret_format(pipe->screen,
                                        src, new_format);
    }

    r300_hw_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
                        src, src_level, src_box);

    if (old_format != new_format) {
        r300_texture_reinterpret_format(pipe->screen,
                                        dst, old_format);
        r300_texture_reinterpret_format(pipe->screen,
                                        src, old_format);
    }
}
コード例 #2
0
ファイル: r300_blit.c プロジェクト: mlankhorst/Mesa-3D
/* Copy a block of pixels from one surface to another. */
static void r300_resource_copy_region(struct pipe_context *pipe,
                                      struct pipe_resource *dst,
                                      unsigned dst_level,
                                      unsigned dstx, unsigned dsty, unsigned dstz,
                                      struct pipe_resource *src,
                                      unsigned src_level,
                                      const struct pipe_box *src_box)
{
    struct r300_context *r300 = r300_context(pipe);
    struct pipe_framebuffer_state *fb =
        (struct pipe_framebuffer_state*)r300->fb_state.state;
    struct pipe_resource old_src = *src;
    struct pipe_resource old_dst = *dst;
    struct pipe_resource new_src = old_src;
    struct pipe_resource new_dst = old_dst;
    const struct util_format_description *desc =
            util_format_description(dst->format);
    struct pipe_box box;

    /* Fallback for buffers. */
    if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
        util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
                                  src, src_level, src_box);
        return;
    }

    if (r300->zmask_in_use && !r300->locked_zbuffer) {
        if (fb->zsbuf->texture == src ||
            fb->zsbuf->texture == dst) {
            r300_decompress_zmask(r300);
        }
    }

    /* Handle non-renderable plain formats. */
    if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
        (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB ||
         !pipe->screen->is_format_supported(pipe->screen,
                                            src->format, src->target,
                                            src->nr_samples,
                                            PIPE_BIND_SAMPLER_VIEW) ||
         !pipe->screen->is_format_supported(pipe->screen,
                                            dst->format, dst->target,
                                            dst->nr_samples,
                                            PIPE_BIND_RENDER_TARGET))) {
        switch (util_format_get_blocksize(old_dst.format)) {
            case 1:
                new_dst.format = PIPE_FORMAT_I8_UNORM;
                break;
            case 2:
                new_dst.format = PIPE_FORMAT_B4G4R4A4_UNORM;
                break;
            case 4:
                new_dst.format = PIPE_FORMAT_B8G8R8A8_UNORM;
                break;
            case 8:
                new_dst.format = PIPE_FORMAT_R16G16B16A16_UNORM;
                break;
            default:
                debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n"
                             "r300: surface_copy: Software fallback doesn't work for tiled textures.\n",
                             util_format_short_name(dst->format));
        }
        new_src.format = new_dst.format;
    }

    /* Handle compressed formats. */
    if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC ||
        desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
        switch (util_format_get_blocksize(old_dst.format)) {
        case 8:
            /* 1 pixel = 4 bits,
             * we set 1 pixel = 2 bytes ===> 4 times larger pixels. */
            new_dst.format = PIPE_FORMAT_B4G4R4A4_UNORM;
            break;
        case 16:
            /* 1 pixel = 8 bits,
             * we set 1 pixel = 4 bytes ===> 4 times larger pixels. */
            new_dst.format = PIPE_FORMAT_B8G8R8A8_UNORM;
            break;
        }

        /* Since the pixels are 4 times larger, we must decrease
         * the image size and the coordinates 4 times. */
        new_src.format = new_dst.format;
        new_dst.height0 = (new_dst.height0 + 3) / 4;
        new_src.height0 = (new_src.height0 + 3) / 4;
        dsty /= 4;
        box = *src_box;
        box.y /= 4;
        box.height = (box.height + 3) / 4;
        src_box = &box;
    }

    if (old_src.format != new_src.format)
        r300_resource_set_properties(pipe->screen, src, &new_src);
    if (old_dst.format != new_dst.format)
        r300_resource_set_properties(pipe->screen, dst, &new_dst);

    r300_hw_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
                        src, src_level, src_box);

    if (old_src.format != new_src.format)
        r300_resource_set_properties(pipe->screen, src, &old_src);
    if (old_dst.format != new_dst.format)
        r300_resource_set_properties(pipe->screen, dst, &old_dst);
}