static void i915_surface_copy_render(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 i915_context *i915 = i915_context(pipe); /* 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 (!util_blitter_is_copy_supported(i915->blitter, dst, src, PIPE_MASK_RGBAZS)) { util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); return; } i915_util_blitter_save_states(i915); util_blitter_copy_texture(i915->blitter, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box, PIPE_MASK_RGBAZS, TRUE); }
bool ilo_blitter_pipe_copy_resource(struct ilo_blitter *blitter, struct pipe_resource *dst, unsigned dst_level, unsigned dst_x, unsigned dst_y, unsigned dst_z, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { const unsigned mask = PIPE_MASK_RGBAZS; const bool copy_all_samples = true; /* not until we allow rendertargets to be buffers */ if (dst->target == PIPE_BUFFER || src->target == PIPE_BUFFER) return false; if (!util_blitter_is_copy_supported(blitter->pipe_blitter, dst, src, mask)) return false; ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_COPY, false); util_blitter_copy_texture(blitter->pipe_blitter, dst, dst_level, dst_x, dst_y, dst_z, src, src_level, src_box, mask, copy_all_samples); ilo_blitter_pipe_end(blitter); return true; }
/** * _copy_region using pipe (3d engine) */ static bool fd_blitter_pipe_copy_region(struct fd_context *ctx, 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) { /* not until we allow rendertargets to be buffers */ if (dst->target == PIPE_BUFFER || src->target == PIPE_BUFFER) return false; if (!util_blitter_is_copy_supported(ctx->blitter, dst, src)) return false; /* TODO we could discard if dst box covers dst level fully.. */ fd_blitter_pipe_begin(ctx, false, false, FD_STAGE_BLIT); util_blitter_copy_texture(ctx->blitter, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); fd_blitter_pipe_end(ctx); return true; }
static void r600_color_resolve(struct pipe_context *ctx, const struct pipe_resolve_info *info) { struct r600_context *rctx = (struct r600_context *)ctx; struct pipe_screen *screen = ctx->screen; struct pipe_resource *tmp, templ; struct pipe_box box; unsigned sample_mask = rctx->chip_class == CAYMAN ? ~0 : ((1ull << MAX2(1, info->src.res->nr_samples)) - 1); assert((info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA); if (is_simple_resolve(info)) { r600_blitter_begin(ctx, R600_COLOR_RESOLVE); util_blitter_custom_resolve_color(rctx->blitter, info->dst.res, info->dst.level, info->dst.layer, info->src.res, info->src.layer, sample_mask, rctx->custom_blend_resolve); r600_blitter_end(ctx); return; } /* resolve into a temporary texture, then blit */ templ.target = PIPE_TEXTURE_2D; templ.format = info->src.res->format; templ.width0 = info->src.res->width0; templ.height0 = info->src.res->height0; templ.depth0 = 1; templ.array_size = 1; templ.last_level = 0; templ.nr_samples = 0; templ.usage = PIPE_USAGE_STATIC; templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; templ.flags = 0; tmp = screen->resource_create(screen, &templ); /* XXX use scissor, so that only the needed part of the resource is resolved */ r600_blitter_begin(ctx, R600_COLOR_RESOLVE); util_blitter_custom_resolve_color(rctx->blitter, tmp, 0, 0, info->src.res, info->src.layer, sample_mask, rctx->custom_blend_resolve); r600_blitter_end(ctx); /* this is correct for upside-down blits too */ u_box_2d(info->src.x0, info->src.y0, info->src.x1 - info->src.x0, info->src.y1 - info->src.y0, &box); r600_blitter_begin(ctx, R600_COPY_TEXTURE); util_blitter_copy_texture(rctx->blitter, info->dst.res, info->dst.level, ~0, info->dst.x0, info->dst.y0, info->dst.layer, tmp, 0, 0, &box); r600_blitter_end(ctx); pipe_resource_reference(&tmp, NULL); }
/* Copy a block of pixels from one surface to another using HW. */ static void r600_hw_copy_region(struct pipe_context *ctx, 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 r600_context *rctx = (struct r600_context *)ctx; r600_blitter_begin(ctx, R600_COPY); util_blitter_copy_texture(rctx->blitter, dst, dst_level, ~0, dstx, dsty, dstz, src, src_level, 0, src_box); r600_blitter_end(ctx); }
/* Copy a block of pixels from one surface to another using HW. */ static void r300_hw_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); r300_blitter_begin(r300, R300_COPY); util_blitter_copy_texture(r300->blitter, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box, TRUE); r300_blitter_end(r300); }
static void i915_surface_copy_render(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 i915_context *i915 = i915_context(pipe); /* 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; } util_blitter_save_blend(i915->blitter, (void *)i915->blend); util_blitter_save_depth_stencil_alpha(i915->blitter, (void *)i915->depth_stencil); util_blitter_save_stencil_ref(i915->blitter, &i915->stencil_ref); util_blitter_save_rasterizer(i915->blitter, (void *)i915->rasterizer); util_blitter_save_fragment_shader(i915->blitter, i915->saved_fs); util_blitter_save_vertex_shader(i915->blitter, i915->saved_vs); util_blitter_save_viewport(i915->blitter, &i915->viewport); util_blitter_save_clip(i915->blitter, &i915->saved_clip); util_blitter_save_vertex_elements(i915->blitter, i915->saved_velems); util_blitter_save_vertex_buffers(i915->blitter, i915->saved_nr_vertex_buffers, i915->saved_vertex_buffers); util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); util_blitter_save_fragment_sampler_states(i915->blitter, i915->saved_nr_samplers, i915->saved_samplers); util_blitter_save_fragment_sampler_views(i915->blitter, i915->saved_nr_sampler_views, i915->saved_sampler_views); util_blitter_copy_texture(i915->blitter, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box, TRUE); }
static void r600_resource_copy_region(struct pipe_context *ctx, 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 r600_context *rctx = (struct r600_context *)ctx; struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src; struct texture_orig_info orig_info[2]; struct pipe_box sbox; const struct pipe_box *psbox = src_box; boolean restore_orig[2]; memset(orig_info, 0, sizeof(orig_info)); /* Fallback for buffers. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { util_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); return; } /* This must be done before entering u_blitter to avoid recursion. */ if (rsrc->is_depth && !rsrc->is_flushing_texture) { si_blit_decompress_depth_in_place(rctx, rsrc, src_level, src_level, src_box->z, src_box->z + src_box->depth - 1); } restore_orig[0] = restore_orig[1] = FALSE; if (util_format_is_compressed(src->format) && util_format_is_compressed(dst->format)) { r600_compressed_to_blittable(src, src_level, &orig_info[0]); restore_orig[0] = TRUE; sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y); sbox.z = src_box->z; sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height); sbox.depth = src_box->depth; psbox=&sbox; r600_compressed_to_blittable(dst, dst_level, &orig_info[1]); restore_orig[1] = TRUE; /* translate the dst box as well */ dstx = util_format_get_nblocksx(orig_info[1].format, dstx); dsty = util_format_get_nblocksy(orig_info[1].format, dsty); } else if (!util_blitter_is_copy_supported(rctx->blitter, dst, src, PIPE_MASK_RGBAZS)) { unsigned blocksize = util_format_get_blocksize(src->format); switch (blocksize) { case 1: r600_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8_UNORM); r600_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8_UNORM); break; case 4: r600_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8G8B8A8_UNORM); r600_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8G8B8A8_UNORM); break; default: fprintf(stderr, "Unhandled format %s with blocksize %u\n", util_format_short_name(src->format), blocksize); assert(0); } restore_orig[0] = TRUE; restore_orig[1] = TRUE; } r600_blitter_begin(ctx, R600_COPY); util_blitter_copy_texture(rctx->blitter, dst, dst_level, dstx, dsty, dstz, src, src_level, psbox, PIPE_MASK_RGBAZS, TRUE); r600_blitter_end(ctx); if (restore_orig[0]) r600_reset_blittable_to_orig(src, src_level, &orig_info[0]); if (restore_orig[1]) r600_reset_blittable_to_orig(dst, dst_level, &orig_info[1]); }
static void r600_resource_copy_region(struct pipe_context *ctx, 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 r600_context *rctx = (struct r600_context *)ctx; struct r600_texture *rsrc = (struct r600_texture*)src; struct texture_orig_info orig_info[2]; struct pipe_box sbox; const struct pipe_box *psbox = src_box; boolean restore_orig[2]; unsigned last_sample, i; memset(orig_info, 0, sizeof(orig_info)); /* Handle buffers first. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { r600_copy_buffer(ctx, dst, dstx, src, src_box); return; } assert(u_max_sample(dst) == u_max_sample(src)); last_sample = u_max_sample(dst); /* This must be done before entering u_blitter to avoid recursion. */ if (rsrc->is_depth && !rsrc->is_flushing_texture) { if (!r600_init_flushed_depth_texture(ctx, src, NULL)) return; /* error */ r600_blit_uncompress_depth(ctx, rsrc, NULL, src_level, src_level, src_box->z, src_box->z + src_box->depth - 1, 0, u_max_sample(src)); } restore_orig[0] = restore_orig[1] = FALSE; if (util_format_is_compressed(src->format) && util_format_is_compressed(dst->format)) { r600_compressed_to_blittable(src, src_level, &orig_info[0]); restore_orig[0] = TRUE; sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y); sbox.z = src_box->z; sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height); sbox.depth = src_box->depth; psbox = &sbox; r600_compressed_to_blittable(dst, dst_level, &orig_info[1]); restore_orig[1] = TRUE; /* translate the dst box as well */ dstx = util_format_get_nblocksx(orig_info[1].format, dstx); dsty = util_format_get_nblocksy(orig_info[1].format, dsty); } else if (!util_blitter_is_copy_supported(rctx->blitter, dst, src, PIPE_MASK_RGBAZS)) { if (util_format_is_subsampled_2x1_32bpp(src->format) && util_format_is_subsampled_2x1_32bpp(dst->format)) { r600_subsampled_2x1_32bpp_to_blittable(src, src_level, &orig_info[0]); r600_subsampled_2x1_32bpp_to_blittable(dst, dst_level, &orig_info[1]); sbox = *src_box; sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); psbox = &sbox; dstx = util_format_get_nblocksx(orig_info[1].format, dstx); } else { unsigned blocksize = util_format_get_blocksize(src->format); switch (blocksize) { case 1: r600_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8_UNORM); r600_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8_UNORM); break; case 4: r600_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8G8B8A8_UNORM); r600_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8G8B8A8_UNORM); break; default: fprintf(stderr, "Unhandled format %s with blocksize %u\n", util_format_short_name(src->format), blocksize); assert(0); } } restore_orig[0] = TRUE; restore_orig[1] = TRUE; } for (i = 0; i <= last_sample; i++) { r600_blitter_begin(ctx, R600_COPY_TEXTURE); util_blitter_copy_texture(rctx->blitter, dst, dst_level, 1 << i, dstx, dsty, dstz, src, src_level, i, psbox); r600_blitter_end(ctx); } if (restore_orig[0]) r600_reset_blittable_to_orig(src, src_level, &orig_info[0]); if (restore_orig[1]) r600_reset_blittable_to_orig(dst, dst_level, &orig_info[1]); }