summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2016-04-14 03:34:53 +0200
committerGrigori Goronzy <greg@chown.ath.cx>2016-04-14 20:34:40 +0200
commit84af31fa07f1d2d4a13a109cb8cd3204a2e2b289 (patch)
tree715e74edabbfb181cc72c98636f05a1df8014f8c
parent8fcf13ecd3a8968ebb84a587ae188a29ec60f380 (diff)
winsys/amdgpu: add support for const IB
v2: use the correct IB to update request (Bas Nieuwenhuizen)
-rw-r--r--src/gallium/drivers/radeon/radeon_winsys.h18
-rw-r--r--src/gallium/winsys/amdgpu/drm/amdgpu_cs.c48
-rw-r--r--src/gallium/winsys/amdgpu/drm/amdgpu_cs.h9
3 files changed, 70 insertions, 5 deletions
diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h
index aa94df6936..04ce2fbf96 100644
--- a/src/gallium/drivers/radeon/radeon_winsys.h
+++ b/src/gallium/drivers/radeon/radeon_winsys.h
@@ -603,6 +603,24 @@ struct radeon_winsys {
void *flush_ctx);
/**
+ * Add a constant engine IB to a graphics CS. This makes the graphics CS
+ * from "cs_create" a group of two IBs that share a buffer list and are
+ * flushed together.
+ *
+ * The returned constant CS is only a stream for writing packets to the new
+ * IB. Calling other winsys functions with it is not allowed, not even
+ * "cs_destroy".
+ *
+ * In order to add buffers and check memory usage, use the graphics CS.
+ * In order to flush it, use the graphics CS, which will flush both IBs.
+ * Destroying the graphics CS will destroy both of them.
+ *
+ * \param cs The graphics CS from "cs_create" that will hold the buffer
+ * list and will be used for flushing.
+ */
+ struct radeon_winsys_cs *(*cs_add_const_ib)(struct radeon_winsys_cs *cs);
+
+ /**
* Destroy a command stream.
*
* \param cs A command stream to destroy.
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
index b0fe8b91b1..b0c80c64ff 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
@@ -350,19 +350,39 @@ amdgpu_cs_create(struct radeon_winsys_ctx *rwctx,
return NULL;
}
- if (!amdgpu_get_new_ib(&ctx->ws->base, &cs->main, &cs->ib)) {
+ if (!amdgpu_get_new_ib(&ctx->ws->base, &cs->main, &cs->ib[IB_MAIN])) {
amdgpu_destroy_cs_context(cs);
FREE(cs);
return NULL;
}
cs->request.number_of_ibs = 1;
- cs->request.ibs = &cs->ib;
+ cs->request.ibs = &cs->ib[IB_MAIN];
p_atomic_inc(&ctx->ws->num_cs);
return &cs->main.base;
}
+static struct radeon_winsys_cs *
+amdgpu_cs_add_const_ib(struct radeon_winsys_cs *rcs)
+{
+ struct amdgpu_cs *cs = (struct amdgpu_cs*)rcs;
+ struct amdgpu_winsys *ws = cs->ctx->ws;
+
+ /* only one const IB can be added */
+ if (cs->ring_type != RING_GFX || cs->const_ib.ib_mapped)
+ return NULL;
+
+ if (!amdgpu_get_new_ib(&ws->base, &cs->const_ib, &cs->ib[IB_CONST]))
+ return NULL;
+
+ cs->request.number_of_ibs = 2;
+ cs->request.ibs = &cs->ib[IB_CONST];
+ cs->ib[IB_CONST].flags = AMDGPU_IB_FLAG_CE;
+
+ return &cs->const_ib.base;
+}
+
#define OUT_CS(cs, value) (cs)->buf[(cs)->cdw++] = (value)
int amdgpu_lookup_buffer(struct amdgpu_cs *cs, struct amdgpu_winsys_bo *bo)
@@ -621,6 +641,12 @@ static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
/* pad GFX ring to 8 DWs to meet CP fetch alignment requirements */
while (rcs->cdw & 7)
OUT_CS(rcs, 0xffff1000); /* type3 nop packet */
+
+ /* Also pad the const IB. */
+ /* TODO: is this the correct packet for the const IB? */
+ if (cs->const_ib.ib_mapped)
+ while (!cs->const_ib.base.cdw || (cs->const_ib.base.cdw & 7))
+ OUT_CS(&cs->const_ib.base, 0xffff1000); /* type3 nop packet */
break;
case RING_UVD:
while (rcs->cdw & 15)
@@ -637,6 +663,10 @@ static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
amdgpu_cs_add_buffer(rcs, cs->main.big_ib_buffer,
RADEON_USAGE_READ, 0, RADEON_PRIO_IB1);
+ if (cs->const_ib.ib_mapped)
+ amdgpu_cs_add_buffer(rcs, cs->const_ib.big_ib_buffer,
+ RADEON_USAGE_READ, 0, RADEON_PRIO_IB1);
+
/* If the CS is not empty or overflowed.... */
if (cs->main.base.cdw && cs->main.base.cdw <= cs->main.base.max_dw && !debug_get_option_noop()) {
int r;
@@ -677,9 +707,14 @@ static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
goto cleanup;
}
- cs->ib.size = cs->main.base.cdw;
+ cs->ib[IB_MAIN].size = cs->main.base.cdw;
cs->main.used_ib_space += cs->main.base.cdw * 4;
+ if (cs->const_ib.ib_mapped) {
+ cs->ib[IB_CONST].size = cs->const_ib.base.cdw;
+ cs->const_ib.used_ib_space += cs->const_ib.base.cdw * 4;
+ }
+
amdgpu_cs_do_submission(cs, fence);
/* Cleanup. */
@@ -689,7 +724,10 @@ static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
cleanup:
amdgpu_cs_context_cleanup(cs);
- amdgpu_get_new_ib(&ws->base, &cs->main, &cs->ib);
+
+ amdgpu_get_new_ib(&ws->base, &cs->main, &cs->ib[IB_MAIN]);
+ if (cs->const_ib.ib_mapped)
+ amdgpu_get_new_ib(&ws->base, &cs->const_ib, &cs->ib[IB_CONST]);
ws->num_cs_flushes++;
}
@@ -701,6 +739,7 @@ static void amdgpu_cs_destroy(struct radeon_winsys_cs *rcs)
amdgpu_destroy_cs_context(cs);
p_atomic_dec(&cs->ctx->ws->num_cs);
pb_reference(&cs->main.big_ib_buffer, NULL);
+ pb_reference(&cs->const_ib.big_ib_buffer, NULL);
FREE(cs);
}
@@ -720,6 +759,7 @@ void amdgpu_cs_init_functions(struct amdgpu_winsys *ws)
ws->base.ctx_destroy = amdgpu_ctx_destroy;
ws->base.ctx_query_reset_status = amdgpu_ctx_query_reset_status;
ws->base.cs_create = amdgpu_cs_create;
+ ws->base.cs_add_const_ib = amdgpu_cs_add_const_ib;
ws->base.cs_destroy = amdgpu_cs_destroy;
ws->base.cs_add_buffer = amdgpu_cs_add_buffer;
ws->base.cs_lookup_buffer = amdgpu_cs_lookup_buffer;
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
index 888b85b77b..020a05aa1b 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
@@ -59,8 +59,15 @@ struct amdgpu_ib {
unsigned used_ib_space;
};
+enum {
+ IB_CONST = 0, /* the const IB must be first */
+ IB_MAIN = 1,
+ IB_NUM
+};
+
struct amdgpu_cs {
struct amdgpu_ib main; /* must be first because this is inherited */
+ struct amdgpu_ib const_ib; /* optional constant engine IB */
struct amdgpu_ctx *ctx;
/* Flush CS. */
@@ -70,7 +77,7 @@ struct amdgpu_cs {
/* amdgpu_cs_submit parameters */
enum ring_type ring_type;
struct amdgpu_cs_request request;
- struct amdgpu_cs_ib_info ib;
+ struct amdgpu_cs_ib_info ib[IB_NUM];
/* Buffers. */
unsigned max_num_buffers;