[Beignet] [PATCH 1/5] Add some functions to support event in intel gpgpu.
Yang Rong
rong.r.yang at intel.com
Mon Aug 5 22:37:25 PDT 2013
Now runtime prepare command batch first, if can't flush this command
immediately, call cl_gpgpu_event_pending to append the command to event,
when the command batch's wait events completed, than call cl_gpgpu_event_resume
to flush.
Signed-off-by: Yang Rong <rong.r.yang at intel.com>
---
src/cl_driver.h | 24 +++++++++++
src/cl_driver_defs.c | 5 +++
src/intel/intel_gpgpu.c | 104 +++++++++++++++++++++++++++++++++++++++++++----
3 files changed, 124 insertions(+), 9 deletions(-)
diff --git a/src/cl_driver.h b/src/cl_driver.h
index 212beb3..c129246 100644
--- a/src/cl_driver.h
+++ b/src/cl_driver.h
@@ -46,6 +46,9 @@ typedef struct _cl_driver *cl_driver;
/* Encapsulates the gpgpu stream of commands */
typedef struct _cl_gpgpu *cl_gpgpu;
+/* Encapsulates the event of a command stream */
+typedef struct _cl_gpgpu_event *cl_gpgpu_event;
+
typedef struct _cl_context_prop *cl_context_prop;
typedef struct _cl_sampler *cl_sampler;
@@ -175,6 +178,27 @@ extern cl_gpgpu_batch_end_cb *cl_gpgpu_batch_end;
typedef void (cl_gpgpu_flush_cb)(cl_gpgpu);
extern cl_gpgpu_flush_cb *cl_gpgpu_flush;
+/* new a event for a batch buffer */
+typedef cl_gpgpu_event (cl_gpgpu_event_new_cb)(cl_gpgpu);
+extern cl_gpgpu_event_new_cb *cl_gpgpu_event_new;
+
+/* new a event for a batch buffer */
+typedef int (cl_gpgpu_event_update_status_cb)(cl_gpgpu_event, int);
+extern cl_gpgpu_event_update_status_cb *cl_gpgpu_event_update_status;
+
+/* new a event for a batch buffer */
+typedef void (cl_gpgpu_event_pending_cb)(cl_gpgpu, cl_gpgpu_event);
+extern cl_gpgpu_event_pending_cb *cl_gpgpu_event_pending;
+
+/* new a event for a batch buffer */
+typedef void (cl_gpgpu_event_resume_cb)(cl_gpgpu_event);
+extern cl_gpgpu_event_resume_cb *cl_gpgpu_event_resume;
+
+/* new a event for a batch buffer */
+typedef void (cl_gpgpu_event_delete_cb)(cl_gpgpu_event);
+extern cl_gpgpu_event_delete_cb *cl_gpgpu_event_delete;
+
+
/* Will spawn all threads */
typedef void (cl_gpgpu_walker_cb)(cl_gpgpu,
uint32_t simd_sz,
diff --git a/src/cl_driver_defs.c b/src/cl_driver_defs.c
index 4952288..2bcc49d 100644
--- a/src/cl_driver_defs.c
+++ b/src/cl_driver_defs.c
@@ -62,4 +62,9 @@ LOCAL cl_gpgpu_batch_end_cb *cl_gpgpu_batch_end = NULL;
LOCAL cl_gpgpu_flush_cb *cl_gpgpu_flush = NULL;
LOCAL cl_gpgpu_walker_cb *cl_gpgpu_walker = NULL;
LOCAL cl_gpgpu_bind_sampler_cb *cl_gpgpu_bind_sampler = NULL;
+LOCAL cl_gpgpu_event_new_cb *cl_gpgpu_event_new = NULL;
+LOCAL cl_gpgpu_event_update_status_cb *cl_gpgpu_event_update_status = NULL;
+LOCAL cl_gpgpu_event_pending_cb *cl_gpgpu_event_pending = NULL;
+LOCAL cl_gpgpu_event_resume_cb *cl_gpgpu_event_resume = NULL;
+LOCAL cl_gpgpu_event_delete_cb *cl_gpgpu_event_delete = NULL;
diff --git a/src/intel/intel_gpgpu.c b/src/intel/intel_gpgpu.c
index 2791fbe..9ae0037 100644
--- a/src/intel/intel_gpgpu.c
+++ b/src/intel/intel_gpgpu.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright © 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
@@ -57,6 +57,12 @@ typedef struct surface_heap {
char surface[256][sizeof(gen6_surface_state_t)];
} surface_heap_t;
+typedef struct intel_event {
+ intel_batchbuffer_t *batch;
+ drm_intel_bo* buffer;
+ int status;
+} intel_event_t;
+
#define MAX_IF_DESC 32
/* We can bind only a limited number of buffers */
@@ -104,8 +110,8 @@ typedef struct intel_gpgpu intel_gpgpu_t;
static void
intel_gpgpu_sync(intel_gpgpu_t *gpgpu)
{
- if (gpgpu->batch->last_bo)
- drm_intel_bo_wait_rendering(gpgpu->batch->last_bo);
+ if (gpgpu->batch->last_bo)
+ drm_intel_bo_wait_rendering(gpgpu->batch->last_bo);
}
static void
@@ -215,7 +221,7 @@ intel_gpgpu_load_vfe_state(intel_gpgpu_t *gpgpu)
}
static void
-intel_gpgpu_load_constant_buffer(intel_gpgpu_t *gpgpu)
+intel_gpgpu_load_constant_buffer(intel_gpgpu_t *gpgpu)
{
BEGIN_BATCH(gpgpu->batch, 4);
OUT_BATCH(gpgpu->batch, CMD(2,0,1) | (4 - 2)); /* length-2 */
@@ -233,7 +239,7 @@ intel_gpgpu_load_constant_buffer(intel_gpgpu_t *gpgpu)
}
static void
-intel_gpgpu_load_idrt(intel_gpgpu_t *gpgpu)
+intel_gpgpu_load_idrt(intel_gpgpu_t *gpgpu)
{
BEGIN_BATCH(gpgpu->batch, 4);
OUT_BATCH(gpgpu->batch, CMD(2,0,2) | (4 - 2)); /* length-2 */
@@ -246,7 +252,7 @@ intel_gpgpu_load_idrt(intel_gpgpu_t *gpgpu)
static const uint32_t gpgpu_l3_config_reg1[] = {
0x00080040, 0x02040040, 0x00800040, 0x01000038,
0x02000030, 0x01000038, 0x00000038, 0x00000040,
- 0x0A140091, 0x09100091, 0x08900091, 0x08900091
+ 0x0A140091, 0x09100091, 0x08900091, 0x08900091
};
static const uint32_t gpgpu_l3_config_reg2[] = {
@@ -394,7 +400,7 @@ intel_gpgpu_state_init(intel_gpgpu_t *gpgpu,
/* surface state */
if(gpgpu->surface_heap_b.bo)
dri_bo_unreference(gpgpu->surface_heap_b.bo);
- bo = dri_bo_alloc(bufmgr,
+ bo = dri_bo_alloc(bufmgr,
"SURFACE_HEAP",
sizeof(surface_heap_t),
32);
@@ -406,7 +412,7 @@ intel_gpgpu_state_init(intel_gpgpu_t *gpgpu,
/* Interface descriptor remap table */
if(gpgpu->idrt_b.bo)
dri_bo_unreference(gpgpu->idrt_b.bo);
- bo = dri_bo_alloc(bufmgr,
+ bo = dri_bo_alloc(bufmgr,
"IDRT",
MAX_IF_DESC * sizeof(struct gen6_interface_descriptor),
32);
@@ -421,7 +427,7 @@ intel_gpgpu_state_init(intel_gpgpu_t *gpgpu,
/* sampler state */
if (gpgpu->sampler_state_b.bo)
dri_bo_unreference(gpgpu->sampler_state_b.bo);
- bo = dri_bo_alloc(gpgpu->drv->bufmgr,
+ bo = dri_bo_alloc(gpgpu->drv->bufmgr,
"SAMPLER_STATE",
GEN_MAX_SAMPLERS * sizeof(gen6_sampler_state_t),
32);
@@ -803,6 +809,81 @@ intel_gpgpu_walker(intel_gpgpu_t *gpgpu,
ADVANCE_BATCH(gpgpu->batch);
}
+static intel_event_t*
+intel_gpgpu_event_new(intel_gpgpu_t *gpgpu)
+{
+ intel_event_t *event = NULL;
+ TRY_ALLOC_NO_ERR (event, CALLOC(intel_event_t));
+
+ event->status = 0;
+ event->batch = NULL;
+ event->buffer = gpgpu->batch->buffer;
+ if(event->buffer != NULL)
+ drm_intel_bo_reference(event->buffer);
+
+exit:
+ return event;
+error:
+ cl_free(event);
+ event = NULL;
+ goto exit;
+}
+
+static int
+intel_gpgpu_event_update_status(intel_event_t *event, int wait)
+{
+ if(event->status == 1)
+ return event->status;
+
+ if (event->buffer &&
+ event->batch == NULL && //have flushed
+ !drm_intel_bo_busy(event->buffer)) {
+ event->status = 1;
+ drm_intel_bo_unreference(event->buffer);
+ event->buffer = NULL;
+ return event->status;
+ }
+
+ if(wait == 0)
+ return event->status;
+
+ if (event->buffer) {
+ drm_intel_bo_wait_rendering(event->buffer);
+ event->status = 1;
+ drm_intel_bo_unreference(event->buffer);
+ event->buffer = NULL;
+ }
+ return event->status;
+}
+
+static void
+intel_gpgpu_event_pending(intel_gpgpu_t *gpgpu, intel_event_t *event)
+{
+ assert(event->buffer);
+ event->batch = intel_batchbuffer_new(gpgpu->drv);
+ assert(event->batch);
+ *event->batch = *gpgpu->batch;
+ if(event->batch->buffer)
+ drm_intel_bo_reference(event->batch->buffer);
+}
+
+static void
+intel_gpgpu_event_resume(intel_event_t *event)
+{
+ assert(event->batch);
+ intel_batchbuffer_flush(event->batch);
+ intel_batchbuffer_delete(event->batch);
+ event->batch = NULL;
+}
+
+static void
+intel_gpgpu_event_delete(intel_event_t *event)
+{
+ if(event->buffer)
+ drm_intel_bo_unreference(event->buffer);
+ cl_free(event);
+}
+
LOCAL void
intel_set_gpgpu_callbacks(void)
{
@@ -823,5 +904,10 @@ intel_set_gpgpu_callbacks(void)
cl_gpgpu_flush = (cl_gpgpu_flush_cb *) intel_gpgpu_flush;
cl_gpgpu_walker = (cl_gpgpu_walker_cb *) intel_gpgpu_walker;
cl_gpgpu_bind_sampler = (cl_gpgpu_bind_sampler_cb *) intel_gpgpu_bind_sampler;
+ cl_gpgpu_event_new = (cl_gpgpu_event_new_cb *)intel_gpgpu_event_new;
+ cl_gpgpu_event_update_status = (cl_gpgpu_event_update_status_cb *)intel_gpgpu_event_update_status;
+ cl_gpgpu_event_pending = (cl_gpgpu_event_pending_cb *)intel_gpgpu_event_pending;
+ cl_gpgpu_event_resume = (cl_gpgpu_event_resume_cb *)intel_gpgpu_event_resume;
+ cl_gpgpu_event_delete = (cl_gpgpu_event_delete_cb *)intel_gpgpu_event_delete;
}
--
1.7.10.4
More information about the Beignet
mailing list