diff options
Diffstat (limited to 'src/gallium/drivers/r600/r600_texture.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_texture.c | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 0f6773962b9..85da0930242 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -70,7 +70,7 @@ static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600 struct pipe_resource *texture = transfer->resource; struct pipe_box sbox; - u_box_origin_2d(transfer->box.width, transfer->box.height, &sbox); + u_box_3d(0, 0, 0, transfer->box.width, transfer->box.height, transfer->box.depth, &sbox); ctx->resource_copy_region(ctx, texture, transfer->level, transfer->box.x, transfer->box.y, transfer->box.z, @@ -722,7 +722,6 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, { struct r600_context *rctx = (struct r600_context*)ctx; struct r600_texture *rtex = (struct r600_texture*)texture; - struct pipe_resource resource; struct r600_transfer *trans; boolean use_staging_texture = FALSE; enum pipe_format format = texture->format; @@ -793,40 +792,51 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, 0, 0); trans->transfer.stride = staging_depth->surface.level[level].pitch_bytes; + trans->transfer.layer_stride = staging_depth->surface.level[level].slice_size; trans->offset = r600_texture_get_offset(staging_depth, level, box->z); trans->staging = (struct r600_resource*)staging_depth; } else if (use_staging_texture) { - resource.target = PIPE_TEXTURE_2D; + struct pipe_resource resource; + struct r600_texture *staging; + + memset(&resource, 0, sizeof(resource)); resource.format = texture->format; resource.width0 = box->width; resource.height0 = box->height; resource.depth0 = 1; resource.array_size = 1; - resource.last_level = 0; - resource.nr_samples = 0; resource.usage = PIPE_USAGE_STAGING; - resource.bind = 0; resource.flags = R600_RESOURCE_FLAG_TRANSFER; - /* For texture reading, the temporary (detiled) texture is used as - * a render target when blitting from a tiled texture. */ - if (usage & PIPE_TRANSFER_READ) { - resource.bind |= PIPE_BIND_RENDER_TARGET; - } - /* For texture writing, the temporary texture is used as a sampler - * when blitting into a tiled texture. */ - if (usage & PIPE_TRANSFER_WRITE) { - resource.bind |= PIPE_BIND_SAMPLER_VIEW; + + /* We must set the correct texture target and dimensions if needed for a 3D transfer. */ + if (box->depth > 1 && u_max_layer(texture, level) > 0) + resource.target = texture->target; + else + resource.target = PIPE_TEXTURE_2D; + + switch (resource.target) { + case PIPE_TEXTURE_1D_ARRAY: + case PIPE_TEXTURE_2D_ARRAY: + case PIPE_TEXTURE_CUBE_ARRAY: + resource.array_size = box->depth; + break; + case PIPE_TEXTURE_3D: + resource.depth0 = box->depth; + break; + default:; } + + /* Create the temporary texture. */ - trans->staging = (struct r600_resource*)ctx->screen->resource_create(ctx->screen, &resource); - if (trans->staging == NULL) { + staging = (struct r600_texture*)ctx->screen->resource_create(ctx->screen, &resource); + if (staging == NULL) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); FREE(trans); return NULL; } - - trans->transfer.stride = - ((struct r600_texture *)trans->staging)->surface.level[0].pitch_bytes; + trans->staging = &staging->resource; + trans->transfer.stride = staging->surface.level[0].pitch_bytes; + trans->transfer.layer_stride = staging->surface.level[0].slice_size; if (usage & PIPE_TRANSFER_READ) { r600_copy_to_staging_texture(ctx, trans); /* Always referenced in the blit. */ @@ -839,9 +849,9 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, } if (trans->staging) { - buf = ((struct r600_resource *)trans->staging)->cs_buf; + buf = trans->staging->cs_buf; } else { - buf = ((struct r600_resource *)texture)->cs_buf; + buf = rtex->resource.cs_buf; } if (rtex->is_depth || !trans->staging) |