summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/ilo/ilo_resource.c
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2014-07-28 09:28:05 +0800
committerChia-I Wu <[email protected]>2014-07-28 22:57:22 +0800
commit7395432f2e792f8719b03bb39b0cf5cba8ba583b (patch)
tree4a6a726b1aad0db6f8e48463cf13db5c5f6985e8 /src/gallium/drivers/ilo/ilo_resource.c
parent0a0e57b0705925d2350b79a32d007d29980499d6 (diff)
ilo: try unblocking a transfer with a staging bo
When mapping a busy resource with PIPE_TRANSFER_DISCARD_RANGE or PIPE_TRANSFER_FLUSH_EXPLICIT, we can avoid blocking by allocating and mapping a staging bo, and emit pipelined copies at proper places. Since the staging bo is never bound to GPU, we give it packed layout to save space.
Diffstat (limited to 'src/gallium/drivers/ilo/ilo_resource.c')
-rw-r--r--src/gallium/drivers/ilo/ilo_resource.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/src/gallium/drivers/ilo/ilo_resource.c b/src/gallium/drivers/ilo/ilo_resource.c
index c812c19279d..812ccafa93b 100644
--- a/src/gallium/drivers/ilo/ilo_resource.c
+++ b/src/gallium/drivers/ilo/ilo_resource.c
@@ -1279,15 +1279,14 @@ tex_apply_layout(struct ilo_texture *tex,
const struct winsys_handle *handle)
{
tex->bo_format = layout->format;
+ tex->block_width = layout->block_width;
+ tex->block_height = layout->block_height;
+ tex->block_size = layout->block_size;
tex->tiling = layout->tiling;
tex->bo_stride = layout->bo_stride;
tex->bo_height = layout->bo_height;
- tex->block_width = layout->block_width;
- tex->block_height = layout->block_height;
- tex->block_size = layout->block_size;
-
tex->halign_8 = (layout->align_i == 8);
tex->valign_4 = (layout->align_j == 4);
tex->array_spacing_full = layout->array_spacing_full;
@@ -1315,6 +1314,44 @@ tex_apply_layout(struct ilo_texture *tex,
return true;
}
+/**
+ * The texutre is for transfer only. We can define our own layout to save
+ * space.
+ */
+static bool
+tex_apply_transfer_layout(struct ilo_texture *tex)
+{
+ const struct pipe_resource *templ = &tex->base;
+ const unsigned num_slices = (templ->target == PIPE_TEXTURE_3D) ?
+ templ->depth0 : templ->array_size;
+ unsigned slice_width, slice_height, i;
+
+ assert(templ->last_level == 0);
+
+ tex->bo_format = templ->format;
+ tex->block_width = util_format_get_blockwidth(templ->format);
+ tex->block_height = util_format_get_blockheight(templ->format);
+ tex->block_size = util_format_get_blocksize(templ->format);
+
+ assert(util_is_power_of_two(tex->block_width) &&
+ util_is_power_of_two(tex->block_height));
+
+ /* use packed layout */
+ slice_width = align(templ->width0, tex->block_width);
+ slice_height = align(templ->height0, tex->block_height);
+ for (i = 0; i < num_slices; i++) {
+ tex->slices[0][i].x = 0;
+ tex->slices[0][i].y = slice_height * i;
+ }
+
+ tex->tiling = INTEL_TILING_NONE;
+ tex->bo_stride = (slice_width / tex->block_width) * tex->block_size;
+ tex->bo_stride = align(tex->bo_stride, 64);
+ tex->bo_height = (slice_height / tex->block_height) * num_slices;
+
+ return tex_create_bo(tex);
+}
+
static void
tex_destroy(struct ilo_texture *tex)
{
@@ -1338,6 +1375,7 @@ tex_create(struct pipe_screen *screen,
{
struct tex_layout layout;
struct ilo_texture *tex;
+ bool transfer_only;
tex = CALLOC_STRUCT(ilo_texture);
if (!tex)
@@ -1354,6 +1392,18 @@ tex_create(struct pipe_screen *screen,
tex->imported = (handle != NULL);
+ /* use transfer layout when the texture is never bound to GPU */
+ transfer_only = !(templ->bind & ~(PIPE_BIND_TRANSFER_WRITE |
+ PIPE_BIND_TRANSFER_READ));
+ if (transfer_only && templ->last_level == 0) {
+ if (!tex_apply_transfer_layout(tex)) {
+ tex_destroy(tex);
+ return NULL;
+ }
+
+ return &tex->base;
+ }
+
if (!tex_layout_init(&layout, screen, templ, tex->slices)) {
tex_destroy(tex);
return NULL;