};
/* Convenience cast wrapper. */
-static INLINE struct r300_transfer*
+static inline struct r300_transfer*
r300_transfer(struct pipe_transfer* transfer)
{
return (struct r300_transfer*)transfer;
struct r300_transfer *r300transfer)
{
struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
- struct pipe_resource *tex = transfer->resource;
+ struct pipe_resource *src = transfer->resource;
+ struct pipe_resource *dst = &r300transfer->linear_texture->b.b;
+
+ if (src->nr_samples <= 1) {
+ ctx->resource_copy_region(ctx, dst, 0, 0, 0, 0,
+ src, transfer->level, &transfer->box);
+ } else {
+ /* Resolve the resource. */
+ struct pipe_blit_info blit;
+
+ memset(&blit, 0, sizeof(blit));
+ blit.src.resource = src;
+ blit.src.format = src->format;
+ blit.src.level = transfer->level;
+ blit.src.box = transfer->box;
+ blit.dst.resource = dst;
+ blit.dst.format = dst->format;
+ blit.dst.box.width = transfer->box.width;
+ blit.dst.box.height = transfer->box.height;
+ blit.dst.box.depth = transfer->box.depth;
+ blit.mask = PIPE_MASK_RGBA;
+ blit.filter = PIPE_TEX_FILTER_NEAREST;
- ctx->resource_copy_region(ctx, &r300transfer->linear_texture->b.b, 0,
- 0, 0, 0,
- tex, transfer->level, &transfer->box);
+ ctx->blit(ctx, &blit);
+ }
}
/* Copy a detiled texture to a tiled one. */
struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
struct pipe_resource *tex = transfer->resource;
struct pipe_box src_box;
- u_box_origin_2d(transfer->box.width, transfer->box.height, &src_box);
+
+ u_box_3d(0, 0, 0,
+ transfer->box.width, transfer->box.height, transfer->box.depth,
+ &src_box);
ctx->resource_copy_region(ctx, tex, transfer->level,
transfer->box.x, transfer->box.y, transfer->box.z,
struct r300_context *r300 = r300_context(ctx);
struct r300_resource *tex = r300_resource(texture);
struct r300_transfer *trans;
- struct pipe_resource base;
boolean referenced_cs, referenced_hw;
enum pipe_format format = tex->b.b.format;
char *map;
referenced_hw = TRUE;
} else {
referenced_hw =
- r300->rws->buffer_is_busy(tex->buf, RADEON_USAGE_READWRITE);
+ !r300->rws->buffer_wait(tex->buf, 0, RADEON_USAGE_READWRITE);
}
trans = CALLOC_STRUCT(r300_transfer);
if (tex->tex.microtile || tex->tex.macrotile[level] ||
(referenced_hw && !(usage & PIPE_TRANSFER_READ) &&
r300_is_blit_supported(texture->format))) {
+ struct pipe_resource base;
+
if (r300->blitter->running) {
fprintf(stderr, "r300: ERROR: Blitter recursion in texture_get_transfer.\n");
os_break();
base.usage = PIPE_USAGE_STAGING;
base.flags = R300_RESOURCE_FLAG_TRANSFER;
+ /* We must set the correct texture target and dimensions if needed for a 3D transfer. */
+ if (box->depth > 1 && util_max_layer(texture, level) > 0) {
+ base.target = texture->target;
+
+ if (base.target == PIPE_TEXTURE_3D) {
+ base.depth0 = util_next_power_of_two(box->depth);
+ }
+ }
+
/* Create the temporary texture. */
trans->linear_texture = r300_resource(
ctx->screen->resource_create(ctx->screen,
/* Set the stride. */
trans->transfer.stride =
trans->linear_texture->tex.stride_in_bytes[0];
+ trans->transfer.layer_stride =
+ trans->linear_texture->tex.layer_size_in_bytes[0];
if (usage & PIPE_TRANSFER_READ) {
/* We cannot map a tiled texture directly because the data is
} else {
/* Unpipelined transfer. */
trans->transfer.stride = tex->tex.stride_in_bytes[level];
+ trans->transfer.layer_stride = tex->tex.layer_size_in_bytes[level];
trans->offset = r300_texture_get_offset(tex, level, box->z);
if (referenced_cs &&
struct r300_resource *tex = r300_resource(transfer->resource);
if (trans->linear_texture) {
- rws->buffer_unmap(trans->linear_texture->cs_buf);
-
if (transfer->usage & PIPE_TRANSFER_WRITE) {
r300_copy_into_tiled_texture(ctx, trans);
}
pipe_resource_reference(
(struct pipe_resource**)&trans->linear_texture, NULL);
- } else {
- rws->buffer_unmap(tex->cs_buf);
}
FREE(transfer);
}