summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2014-07-28 09:50:31 +0800
committerChia-I Wu <[email protected]>2014-07-28 22:57:22 +0800
commit0a0e57b0705925d2350b79a32d007d29980499d6 (patch)
treee7b2d002a24f3b4102de743bbada2467517cdeaf /src/gallium
parentb02e993d8c73cef9bb6241622c7f9a513cdb6ad4 (diff)
ilo: enable persistent and coherent transfers
Enable PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT and reorder caps a bit.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/ilo/ilo_resource.c17
-rw-r--r--src/gallium/drivers/ilo/ilo_screen.c10
-rw-r--r--src/gallium/drivers/ilo/ilo_transfer.c16
3 files changed, 35 insertions, 8 deletions
diff --git a/src/gallium/drivers/ilo/ilo_resource.c b/src/gallium/drivers/ilo/ilo_resource.c
index 182bb60d301..c812c19279d 100644
--- a/src/gallium/drivers/ilo/ilo_resource.c
+++ b/src/gallium/drivers/ilo/ilo_resource.c
@@ -710,7 +710,7 @@ tex_layout_init_hiz(struct tex_layout *layout)
}
}
-static void
+static bool
tex_layout_init(struct tex_layout *layout,
struct pipe_screen *screen,
const struct pipe_resource *templ,
@@ -732,12 +732,22 @@ tex_layout_init(struct tex_layout *layout,
tex_layout_init_alignments(layout);
tex_layout_init_qpitch(layout);
+ if (templ->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) {
+ /* require on-the-fly tiling/untiling or format conversion */
+ if (layout->separate_stencil ||
+ layout->format == PIPE_FORMAT_S8_UINT ||
+ layout->format != templ->format)
+ return false;
+ }
+
if (slices) {
int lv;
for (lv = 0; lv <= templ->last_level; lv++)
layout->levels[lv].slices = slices[lv];
}
+
+ return true;
}
static void
@@ -1344,7 +1354,10 @@ tex_create(struct pipe_screen *screen,
tex->imported = (handle != NULL);
- tex_layout_init(&layout, screen, templ, tex->slices);
+ if (!tex_layout_init(&layout, screen, templ, tex->slices)) {
+ tex_destroy(tex);
+ return NULL;
+ }
switch (templ->target) {
case PIPE_TEXTURE_1D:
diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c
index f4968f9bc3c..09980dd20f2 100644
--- a/src/gallium/drivers/ilo/ilo_screen.c
+++ b/src/gallium/drivers/ilo/ilo_screen.c
@@ -362,10 +362,6 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param)
return ILO_MAX_SO_BINDINGS / ILO_MAX_SO_BUFFERS;
case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
return ILO_MAX_SO_BINDINGS;
- case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
- case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
- case PIPE_CAP_MAX_VERTEX_STREAMS:
- return 0;
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
if (is->dev.gen >= ILO_GEN(7))
return is->dev.has_gen7_sol_reset;
@@ -424,14 +420,20 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
return true;
case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
+ case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
+ case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
case PIPE_CAP_TEXTURE_GATHER_SM5:
+ return 0;
case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+ return true;
case PIPE_CAP_FAKE_SW_MSAA:
case PIPE_CAP_TEXTURE_QUERY_LOD:
case PIPE_CAP_SAMPLE_SHADING:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
+ case PIPE_CAP_MAX_VERTEX_STREAMS:
+ case PIPE_CAP_DRAW_INDIRECT:
return 0;
default:
diff --git a/src/gallium/drivers/ilo/ilo_transfer.c b/src/gallium/drivers/ilo/ilo_transfer.c
index 4d6706309be..0f1347b70a3 100644
--- a/src/gallium/drivers/ilo/ilo_transfer.c
+++ b/src/gallium/drivers/ilo/ilo_transfer.c
@@ -57,6 +57,15 @@
* synchronization at all on mapping.
* - When PIPE_TRANSFER_MAP_DIRECTLY is set, no staging area is allowed.
* - When PIPE_TRANSFER_DONTBLOCK is set, we should fail if we have to block.
+ * - When PIPE_TRANSFER_PERSISTENT is set, GPU may access the buffer while it
+ * is mapped. Synchronization is done by defining memory barriers,
+ * explicitly via memory_barrier() or implicitly via
+ * transfer_flush_region(), as well as GPU fences.
+ * - When PIPE_TRANSFER_COHERENT is set, updates by either CPU or GPU should
+ * be made visible to the other side immediately. Since the kernel flushes
+ * GPU caches at the end of each batch buffer, CPU always sees GPU updates.
+ * We could use a coherent mapping to make all persistent mappings
+ * coherent.
*
* These also apply to textures, except that we may additionally need to do
* format conversion or tiling/untiling.
@@ -90,7 +99,7 @@ resource_get_transfer_method(struct pipe_resource *res, unsigned usage,
need_convert = false;
if (need_convert) {
- if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
+ if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_PERSISTENT))
return false;
*method = m;
@@ -104,6 +113,8 @@ resource_get_transfer_method(struct pipe_resource *res, unsigned usage,
m = ILO_TRANSFER_MAP_GTT; /* to have a linear view */
else if (is->dev.has_llc)
m = ILO_TRANSFER_MAP_CPU; /* fast and mostly coherent */
+ else if (usage & PIPE_TRANSFER_PERSISTENT)
+ m = ILO_TRANSFER_MAP_GTT; /* for coherency */
else if (usage & PIPE_TRANSFER_READ)
m = ILO_TRANSFER_MAP_CPU; /* gtt read is too slow */
else
@@ -146,7 +157,8 @@ usage_allows_staging_bo(unsigned usage)
PIPE_TRANSFER_DISCARD_RANGE |
PIPE_TRANSFER_FLUSH_EXPLICIT);
const unsigned reasons_against = (PIPE_TRANSFER_READ |
- PIPE_TRANSFER_MAP_DIRECTLY);
+ PIPE_TRANSFER_MAP_DIRECTLY |
+ PIPE_TRANSFER_PERSISTENT);
return (usage & can_writeback) && !(usage & reasons_against);
}