summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/vc4/kernel/vc4_drv.h2
-rw-r--r--src/gallium/drivers/vc4/kernel/vc4_validate.c77
-rw-r--r--src/gallium/drivers/vc4/vc4_context.c14
3 files changed, 87 insertions, 6 deletions
diff --git a/src/gallium/drivers/vc4/kernel/vc4_drv.h b/src/gallium/drivers/vc4/kernel/vc4_drv.h
index b0eb3f031c5..81ffa03a6fa 100644
--- a/src/gallium/drivers/vc4/kernel/vc4_drv.h
+++ b/src/gallium/drivers/vc4/kernel/vc4_drv.h
@@ -82,6 +82,8 @@ struct exec_info {
bool found_tile_binning_mode_config_packet;
bool found_tile_rendering_mode_config_packet;
bool found_start_tile_binning_packet;
+ bool found_increment_semaphore_packet;
+ bool found_wait_on_semaphore_packet;
uint8_t bin_tiles_x, bin_tiles_y;
uint32_t fb_width, fb_height;
uint32_t tile_alloc_init_block_size;
diff --git a/src/gallium/drivers/vc4/kernel/vc4_validate.c b/src/gallium/drivers/vc4/kernel/vc4_validate.c
index 8b04eb99195..ba6e46f2041 100644
--- a/src/gallium/drivers/vc4/kernel/vc4_validate.c
+++ b/src/gallium/drivers/vc4/kernel/vc4_validate.c
@@ -203,6 +203,18 @@ check_tex_size(struct exec_info *exec, struct drm_gem_cma_object *fbo,
}
static int
+validate_flush_all(VALIDATE_ARGS)
+{
+ if (exec->found_increment_semaphore_packet) {
+ DRM_ERROR("VC4_PACKET_FLUSH_ALL after "
+ "VC4_PACKET_INCREMENT_SEMAPHORE\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
validate_start_tile_binning(VALIDATE_ARGS)
{
if (exec->found_start_tile_binning_packet) {
@@ -220,6 +232,41 @@ validate_start_tile_binning(VALIDATE_ARGS)
}
static int
+validate_increment_semaphore(VALIDATE_ARGS)
+{
+ if (exec->found_increment_semaphore_packet) {
+ DRM_ERROR("Duplicate VC4_PACKET_INCREMENT_SEMAPHORE\n");
+ return -EINVAL;
+ }
+ exec->found_increment_semaphore_packet = true;
+
+ /* Once we've found the semaphore increment, there should be one FLUSH
+ * then the end of the command list. The FLUSH actually triggers the
+ * increment, so we only need to make sure there
+ */
+
+ return 0;
+}
+
+static int
+validate_wait_on_semaphore(VALIDATE_ARGS)
+{
+ if (exec->found_wait_on_semaphore_packet) {
+ DRM_ERROR("Duplicate VC4_PACKET_WAIT_ON_SEMAPHORE\n");
+ return -EINVAL;
+ }
+ exec->found_wait_on_semaphore_packet = true;
+
+ if (!exec->found_increment_semaphore_packet) {
+ DRM_ERROR("VC4_PACKET_WAIT_ON_SEMAPHORE without "
+ "VC4_PACKET_INCREMENT_SEMAPHORE\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
validate_branch_to_sublist(VALIDATE_ARGS)
{
struct drm_gem_cma_object *target;
@@ -233,6 +280,11 @@ validate_branch_to_sublist(VALIDATE_ARGS)
return -EINVAL;
}
+ if (!exec->found_wait_on_semaphore_packet) {
+ DRM_ERROR("Jumping to tile alloc before binning finished.\n");
+ return -EINVAL;
+ }
+
offset = *(uint32_t *)(untrusted + 0);
if (offset % exec->tile_alloc_init_block_size ||
offset / exec->tile_alloc_init_block_size >
@@ -322,6 +374,11 @@ validate_indexed_prim_list(VALIDATE_ARGS)
uint32_t index_size = (*(uint8_t *)(untrusted + 0) >> 4) ? 2 : 1;
struct vc4_shader_state *shader_state;
+ if (exec->found_increment_semaphore_packet) {
+ DRM_ERROR("Drawing after VC4_PACKET_INCREMENT_SEMAPHORE\n");
+ return -EINVAL;
+ }
+
/* Check overflow condition */
if (exec->shader_state_count == 0) {
DRM_ERROR("shader state must precede primitives\n");
@@ -355,6 +412,11 @@ validate_gl_array_primitive(VALIDATE_ARGS)
uint32_t max_index;
struct vc4_shader_state *shader_state;
+ if (exec->found_increment_semaphore_packet) {
+ DRM_ERROR("Drawing after VC4_PACKET_INCREMENT_SEMAPHORE\n");
+ return -EINVAL;
+ }
+
/* Check overflow condition */
if (exec->shader_state_count == 0) {
DRM_ERROR("shader state must precede primitives\n");
@@ -600,10 +662,10 @@ static const struct cmd_info {
[VC4_PACKET_HALT] = { 1, 1, 1, "halt", NULL },
[VC4_PACKET_NOP] = { 1, 1, 1, "nop", NULL },
[VC4_PACKET_FLUSH] = { 1, 1, 1, "flush", NULL },
- [VC4_PACKET_FLUSH_ALL] = { 1, 0, 1, "flush all state", NULL },
+ [VC4_PACKET_FLUSH_ALL] = { 1, 0, 1, "flush all state", validate_flush_all },
[VC4_PACKET_START_TILE_BINNING] = { 1, 0, 1, "start tile binning", validate_start_tile_binning },
- [VC4_PACKET_INCREMENT_SEMAPHORE] = { 1, 0, 1, "increment semaphore", NULL },
- [VC4_PACKET_WAIT_ON_SEMAPHORE] = { 1, 1, 1, "wait on semaphore", NULL },
+ [VC4_PACKET_INCREMENT_SEMAPHORE] = { 1, 0, 1, "increment semaphore", validate_increment_semaphore },
+ [VC4_PACKET_WAIT_ON_SEMAPHORE] = { 0, 1, 1, "wait on semaphore", validate_wait_on_semaphore },
/* BRANCH_TO_SUB_LIST is actually supported in the binner as well, but
* we only use it from the render CL in order to jump into the tile
* allocation BO.
@@ -737,6 +799,15 @@ vc4_validate_cl(struct drm_device *dev,
DRM_ERROR("Render CL missing VC4_PACKET_TILE_RENDERING_MODE_CONFIG\n");
return -EINVAL;
}
+
+ /* Make sure that they actually consumed the semaphore
+ * increment from the bin CL. Otherwise a later submit would
+ * have render execute immediately.
+ */
+ if (!exec->found_wait_on_semaphore_packet) {
+ DRM_ERROR("Render CL missing VC4_PACKET_WAIT_ON_SEMAPHORE\n");
+ return -EINVAL;
+ }
exec->ct1ea = exec->ct1ca + dst_offset;
}
diff --git a/src/gallium/drivers/vc4/vc4_context.c b/src/gallium/drivers/vc4/vc4_context.c
index b1f0f353fcc..a6becaf73fc 100644
--- a/src/gallium/drivers/vc4/vc4_context.c
+++ b/src/gallium/drivers/vc4/vc4_context.c
@@ -203,6 +203,12 @@ vc4_setup_rcl(struct vc4_context *vc4)
*/
vc4_tile_coordinates(vc4, x, y, &coords_emitted);
+ /* Wait for the binner before jumping to the first
+ * tile's lists.
+ */
+ if (x == 0 && y == 0)
+ cl_u8(&vc4->rcl, VC4_PACKET_WAIT_ON_SEMAPHORE);
+
cl_start_reloc(&vc4->rcl, 1);
cl_u8(&vc4->rcl, VC4_PACKET_BRANCH_TO_SUB_LIST);
cl_reloc(vc4, &vc4->rcl, vc4->tile_alloc,
@@ -269,12 +275,14 @@ vc4_flush(struct pipe_context *pctx)
if (!vc4->needs_flush)
return;
+ /* Increment the semaphore indicating that binning is done and
+ * unblocking the render thread. Note that this doesn't act until the
+ * FLUSH completes.
+ */
+ cl_u8(&vc4->bcl, VC4_PACKET_INCREMENT_SEMAPHORE);
/* The FLUSH caps all of our bin lists with a VC4_PACKET_RETURN. */
cl_u8(&vc4->bcl, VC4_PACKET_FLUSH);
- cl_u8(&vc4->bcl, VC4_PACKET_NOP);
- cl_u8(&vc4->bcl, VC4_PACKET_HALT);
-
vc4_setup_rcl(vc4);
if (vc4_debug & VC4_DEBUG_CL) {