[PATCH 1/2] drm/vc4: Add a mechanism to easily extend CL submissions
Boris Brezillon
boris.brezillon at free-electrons.com
Thu Dec 7 15:43:07 UTC 2017
The number of attributes/objects you can pass to the
DRM_IOCTL_VC4_SUBMIT_CL ioctl is limited by the drm_vc4_submit_cl struct
size.
Add a mechanism to easily pass extra attributes when submitting a CL to
the V3D engine.
Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
drivers/gpu/drm/vc4/vc4_drv.c | 1 +
drivers/gpu/drm/vc4/vc4_drv.h | 2 ++
drivers/gpu/drm/vc4/vc4_gem.c | 60 +++++++++++++++++++++++++++++++-
include/uapi/drm/vc4_drm.h | 81 +++++++++++++++++++++++++++++++++++++------
4 files changed, 133 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index e3c29729da2e..5c62013f8ca3 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -101,6 +101,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
case DRM_VC4_PARAM_SUPPORTS_THREADED_FS:
case DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER:
case DRM_VC4_PARAM_SUPPORTS_MADVISE:
+ case DRM_VC4_PARAM_SUPPORTS_EXTENDED_CL:
args->value = true;
break;
default:
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 9c0d380c96f2..3c54cc386443 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -318,6 +318,8 @@ struct vc4_exec_info {
/* Kernel-space copy of the ioctl arguments */
struct drm_vc4_submit_cl *args;
+ uint32_t nchunks;
+ union drm_vc4_submit_cl_chunk *chunks;
/* This is the array of BOs that were looked up at the start of exec.
* Command validation will use indices into this array.
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 6c32c89a83a9..06976c61422a 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -920,6 +920,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
}
mutex_unlock(&vc4->power_lock);
+ kfree(exec->chunks);
kfree(exec);
}
@@ -1048,6 +1049,27 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data,
return ret;
}
+static int
+vc4_parse_cl_chunk(struct vc4_dev *vc4, struct vc4_exec_info *exec,
+ const union drm_vc4_submit_cl_chunk *chunk)
+{
+ switch(chunk->dummy.type) {
+ case VC4_BIN_CL_CHUNK:
+ /* Update bin_cl related fields so that we don't have to patch
+ * existing vc4_get_bcl() logic to support the BIN_CL
+ * chunk.
+ */
+ exec->args->bin_cl = chunk->bin.ptr;
+ exec->args->bin_cl_size = chunk->bin.size;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/**
* vc4_submit_cl_ioctl() - Submits a job (frame) to the VC4.
* @dev: DRM device
@@ -1073,11 +1095,18 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
if ((args->flags & ~(VC4_SUBMIT_CL_USE_CLEAR_COLOR |
VC4_SUBMIT_CL_FIXED_RCL_ORDER |
VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X |
- VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y)) != 0) {
+ VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y |
+ VC4_SUBMIT_CL_EXTENDED)) != 0) {
DRM_DEBUG("Unknown flags: 0x%02x\n", args->flags);
return -EINVAL;
}
+ if ((args->flags & VC4_SUBMIT_CL_EXTENDED) &&
+ !args->num_cl_chunks) {
+ DRM_DEBUG("CL_EXTENDED flag set but no chunks provided\n");
+ return -EINVAL;
+ }
+
exec = kcalloc(1, sizeof(*exec), GFP_KERNEL);
if (!exec) {
DRM_ERROR("malloc failure on exec struct\n");
@@ -1103,6 +1132,35 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
if (ret)
goto fail;
+ if (args->flags & VC4_SUBMIT_CL_EXTENDED) {
+ uint32_t i;
+
+ ret = -ENOMEM;
+ exec->nchunks = args->num_cl_chunks;
+ exec->chunks = kcalloc(exec->nchunks, sizeof(*exec->chunks),
+ GFP_KERNEL);
+ if (!exec->chunks)
+ goto fail;
+
+ if (copy_from_user(exec->chunks,
+ u64_to_user_ptr(args->cl_chunks),
+ exec->nchunks *
+ sizeof(*exec->chunks)))
+ goto fail;
+
+ /* Reset ->bin_cl fields so that if no BIN_CL chunk is
+ * passed, vc4_get_bcl() is skipped.
+ */
+ exec->args->bin_cl = 0;
+ exec->args->bin_cl_size = 0;
+ for (i = 0; i < exec->nchunks; i++) {
+ ret = vc4_parse_cl_chunk(vc4, exec,
+ &exec->chunks[i]);
+ if (ret)
+ goto fail;
+ }
+ }
+
if (exec->args->bin_cl_size != 0) {
ret = vc4_get_bcl(dev, exec);
if (ret)
diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h
index 52263b575bdc..ddcaa72da82a 100644
--- a/include/uapi/drm/vc4_drm.h
+++ b/include/uapi/drm/vc4_drm.h
@@ -70,6 +70,50 @@ struct drm_vc4_submit_rcl_surface {
};
/**
+ * @VC4_BIN_CL_CHUNK: binner CL chunk
+ */
+enum {
+ VC4_BIN_CL_CHUNK,
+};
+
+/**
+ * struct drm_vc4_submit_cl_chunk - dummy chunk
+ * @type: extension type
+ * @pad: unused, should be set to zero
+ *
+ * Meant to be used for chunks that do not require extra parameters.
+ */
+struct drm_vc4_submit_cl_dummy_chunk {
+ __u32 type;
+ __u32 pad[3];
+};
+
+/**
+ * struct drm_vc4_submit_cl_bin_chunk - binner CL chunk
+ *
+ * @type: extention type, should be set to %VC4_BIN_CL_CHUNK
+ * @size: size in bytes of the binner CL
+ * @ptr: userspace pointer to the binner CL
+ */
+struct drm_vc4_submit_cl_bin_chunk {
+ __u32 type;
+ __u32 size;
+ __u64 ptr;
+};
+
+/**
+ * union drm_vc4_submit_cl_chunk - CL chunk
+ *
+ * CL chunks allow us to easily extend the set of arguments one can pass
+ * to the submit CL ioctl without having to add new ioctls/struct everytime
+ * we run out of free fields in the drm_vc4_submit_cl struct.
+ */
+union drm_vc4_submit_cl_chunk {
+ struct drm_vc4_submit_cl_dummy_chunk dummy;
+ struct drm_vc4_submit_cl_bin_chunk bin;
+};
+
+/**
* struct drm_vc4_submit_cl - ioctl argument for submitting commands to the 3D
* engine.
*
@@ -83,14 +127,23 @@ struct drm_vc4_submit_rcl_surface {
* BO.
*/
struct drm_vc4_submit_cl {
- /* Pointer to the binner command list.
- *
- * This is the first set of commands executed, which runs the
- * coordinate shader to determine where primitives land on the screen,
- * then writes out the state updates and draw calls necessary per tile
- * to the tile allocation BO.
- */
- __u64 bin_cl;
+ union {
+ /* Pointer to the binner command list.
+ *
+ * This is the first set of commands executed, which runs the
+ * coordinate shader to determine where primitives land on
+ * the screen, then writes out the state updates and draw calls
+ * necessary per tile to the tile allocation BO.
+ */
+ __u64 bin_cl;
+
+ /* Pointer to an array of CL chunks.
+ *
+ * This is now the preferred way of passing optional attributes
+ * when submitting a job.
+ */
+ __u64 cl_chunks;
+ };
/* Pointer to the shader records.
*
@@ -120,8 +173,14 @@ struct drm_vc4_submit_cl {
__u64 uniforms;
__u64 bo_handles;
- /* Size in bytes of the binner command list. */
- __u32 bin_cl_size;
+ union {
+ /* Size in bytes of the binner command list. */
+ __u32 bin_cl_size;
+
+ /* Number of entries in the CL extension array. */
+ __u32 num_cl_chunks;
+ };
+
/* Size in bytes of the set of shader records. */
__u32 shader_rec_size;
/* Number of shader records.
@@ -167,6 +226,7 @@ struct drm_vc4_submit_cl {
#define VC4_SUBMIT_CL_FIXED_RCL_ORDER (1 << 1)
#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X (1 << 2)
#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y (1 << 3)
+#define VC4_SUBMIT_CL_EXTENDED (1 << 4)
__u32 flags;
/* Returned value of the seqno of this render job (for the
@@ -308,6 +368,7 @@ struct drm_vc4_get_hang_state {
#define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5
#define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6
#define DRM_VC4_PARAM_SUPPORTS_MADVISE 7
+#define DRM_VC4_PARAM_SUPPORTS_EXTENDED_CL 8
struct drm_vc4_get_param {
__u32 param;
--
2.11.0
More information about the dri-devel
mailing list