vc4: Separate out a bit of code for submitting jobs to the kernel.
authorEric Anholt <eric@anholt.net>
Mon, 6 Apr 2015 19:58:51 +0000 (12:58 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 14 Apr 2015 06:20:45 +0000 (23:20 -0700)
I want to be able to have multiple jobs being set up at the same time (for
example, a render job to do a little fixup blit in the course of doing a
render to the main FBO).

src/gallium/drivers/vc4/Makefile.sources
src/gallium/drivers/vc4/vc4_context.c
src/gallium/drivers/vc4/vc4_context.h
src/gallium/drivers/vc4/vc4_job.c [new file with mode: 0644]

index ec0f25ca34aaadde07f16fc15d7af6f082b6abaa..62cd0e00d900d2b971da578a80c34bc663e34f2a 100644 (file)
@@ -11,6 +11,7 @@ C_SOURCES := \
        vc4_emit.c \
        vc4_fence.c \
        vc4_formats.c \
+       vc4_job.c \
        vc4_opt_algebraic.c \
        vc4_opt_constant_folding.c \
        vc4_opt_copy_propagation.c \
index daa5ba5d4c619131488c78b3f6313e47cb63b2cb..b394c186efbc7e8618a51192f6ca8bc1774a27e4 100644 (file)
@@ -296,40 +296,6 @@ vc4_setup_rcl(struct vc4_context *vc4)
                 ztex->writes++;
 }
 
-static void
-vc4_draw_reset(struct vc4_context *vc4)
-{
-        struct vc4_bo **referenced_bos = vc4->bo_pointers.base;
-        for (int i = 0; i < (vc4->bo_handles.next -
-                             vc4->bo_handles.base) / 4; i++) {
-                vc4_bo_unreference(&referenced_bos[i]);
-        }
-        vc4_reset_cl(&vc4->bcl);
-        vc4_reset_cl(&vc4->rcl);
-        vc4_reset_cl(&vc4->shader_rec);
-        vc4_reset_cl(&vc4->uniforms);
-        vc4_reset_cl(&vc4->bo_handles);
-        vc4_reset_cl(&vc4->bo_pointers);
-        vc4->shader_rec_count = 0;
-
-        vc4->needs_flush = false;
-        vc4->draw_call_queued = false;
-
-        /* We have no hardware context saved between our draw calls, so we
-         * need to flag the next draw as needing all state emitted.  Emitting
-         * all state at the start of our draws is also what ensures that we
-         * return to the state we need after a previous tile has finished.
-         */
-        vc4->dirty = ~0;
-        vc4->resolve = 0;
-        vc4->cleared = 0;
-
-        vc4->draw_min_x = ~0;
-        vc4->draw_min_y = ~0;
-        vc4->draw_max_x = 0;
-        vc4->draw_max_y = 0;
-}
-
 void
 vc4_flush(struct pipe_context *pctx)
 {
@@ -343,7 +309,7 @@ vc4_flush(struct pipe_context *pctx)
          */
         if (vc4->draw_max_x <= vc4->draw_min_x ||
             vc4->draw_max_y <= vc4->draw_min_y) {
-                vc4_draw_reset(vc4);
+                vc4_job_reset(vc4);
                 return;
         }
 
@@ -358,54 +324,7 @@ vc4_flush(struct pipe_context *pctx)
 
         vc4_setup_rcl(vc4);
 
-        if (vc4_debug & VC4_DEBUG_CL) {
-                fprintf(stderr, "BCL:\n");
-                vc4_dump_cl(vc4->bcl.base, vc4->bcl.next - vc4->bcl.base, false);
-                fprintf(stderr, "RCL:\n");
-                vc4_dump_cl(vc4->rcl.base, vc4->rcl.next - vc4->rcl.base, true);
-        }
-
-        struct drm_vc4_submit_cl submit;
-        memset(&submit, 0, sizeof(submit));
-
-        submit.bo_handles = (uintptr_t)vc4->bo_handles.base;
-        submit.bo_handle_count = (vc4->bo_handles.next -
-                                  vc4->bo_handles.base) / 4;
-        submit.bin_cl = (uintptr_t)vc4->bcl.base;
-        submit.bin_cl_size = vc4->bcl.next - vc4->bcl.base;
-        submit.render_cl = (uintptr_t)vc4->rcl.base;
-        submit.render_cl_size = vc4->rcl.next - vc4->rcl.base;
-        submit.shader_rec = (uintptr_t)vc4->shader_rec.base;
-        submit.shader_rec_size = vc4->shader_rec.next - vc4->shader_rec.base;
-        submit.shader_rec_count = vc4->shader_rec_count;
-        submit.uniforms = (uintptr_t)vc4->uniforms.base;
-        submit.uniforms_size = vc4->uniforms.next - vc4->uniforms.base;
-
-        if (!(vc4_debug & VC4_DEBUG_NORAST)) {
-                int ret;
-
-#ifndef USE_VC4_SIMULATOR
-                ret = drmIoctl(vc4->fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit);
-#else
-                ret = vc4_simulator_flush(vc4, &submit);
-#endif
-                if (ret) {
-                        fprintf(stderr, "VC4 submit failed\n");
-                        abort();
-                }
-        }
-
-        vc4->last_emit_seqno = submit.seqno;
-
-        if (vc4_debug & VC4_DEBUG_ALWAYS_SYNC) {
-                if (!vc4_wait_seqno(vc4->screen, vc4->last_emit_seqno,
-                                    PIPE_TIMEOUT_INFINITE)) {
-                        fprintf(stderr, "Wait failed.\n");
-                        abort();
-                }
-        }
-
-        vc4_draw_reset(vc4);
+        vc4_job_submit(vc4);
 }
 
 static void
@@ -532,13 +451,7 @@ vc4_context_create(struct pipe_screen *pscreen, void *priv)
         vc4_query_init(pctx);
         vc4_resource_context_init(pctx);
 
-        vc4_init_cl(vc4, &vc4->bcl);
-        vc4_init_cl(vc4, &vc4->rcl);
-        vc4_init_cl(vc4, &vc4->shader_rec);
-        vc4_init_cl(vc4, &vc4->uniforms);
-        vc4_init_cl(vc4, &vc4->bo_handles);
-        vc4_init_cl(vc4, &vc4->bo_pointers);
-        vc4_draw_reset(vc4);
+        vc4_job_init(vc4);
 
         vc4->fd = screen->fd;
 
index fa1cc43ccd6f71874a534eb7b81d727e9e64d5c7..72d655e4cc27bc8168de8e9e1550501d90c0b358 100644 (file)
@@ -326,6 +326,9 @@ void vc4_write_uniforms(struct vc4_context *vc4,
                         struct vc4_texture_stateobj *texstate);
 
 void vc4_flush(struct pipe_context *pctx);
+void vc4_job_init(struct vc4_context *vc4);
+void vc4_job_submit(struct vc4_context *vc4);
+void vc4_job_reset(struct vc4_context *vc4);
 bool vc4_cl_references_bo(struct pipe_context *pctx, struct vc4_bo *bo);
 void vc4_emit_state(struct pipe_context *pctx);
 void vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c);
diff --git a/src/gallium/drivers/vc4/vc4_job.c b/src/gallium/drivers/vc4/vc4_job.c
new file mode 100644 (file)
index 0000000..7603716
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright © 2014-2015 Broadcom
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** @file vc4_job.c
+ *
+ * Functions for submitting VC4 render jobs to the kernel.
+ */
+
+#include <xf86drm.h>
+#include "vc4_context.h"
+
+void
+vc4_job_init(struct vc4_context *vc4)
+{
+        vc4_init_cl(vc4, &vc4->bcl);
+        vc4_init_cl(vc4, &vc4->rcl);
+        vc4_init_cl(vc4, &vc4->shader_rec);
+        vc4_init_cl(vc4, &vc4->uniforms);
+        vc4_init_cl(vc4, &vc4->bo_handles);
+        vc4_init_cl(vc4, &vc4->bo_pointers);
+        vc4_job_reset(vc4);
+}
+
+void
+vc4_job_reset(struct vc4_context *vc4)
+{
+        struct vc4_bo **referenced_bos = vc4->bo_pointers.base;
+        for (int i = 0; i < (vc4->bo_handles.next -
+                             vc4->bo_handles.base) / 4; i++) {
+                vc4_bo_unreference(&referenced_bos[i]);
+        }
+        vc4_reset_cl(&vc4->bcl);
+        vc4_reset_cl(&vc4->rcl);
+        vc4_reset_cl(&vc4->shader_rec);
+        vc4_reset_cl(&vc4->uniforms);
+        vc4_reset_cl(&vc4->bo_handles);
+        vc4_reset_cl(&vc4->bo_pointers);
+        vc4->shader_rec_count = 0;
+
+        vc4->needs_flush = false;
+        vc4->draw_call_queued = false;
+
+        /* We have no hardware context saved between our draw calls, so we
+         * need to flag the next draw as needing all state emitted.  Emitting
+         * all state at the start of our draws is also what ensures that we
+         * return to the state we need after a previous tile has finished.
+         */
+        vc4->dirty = ~0;
+        vc4->resolve = 0;
+        vc4->cleared = 0;
+
+        vc4->draw_min_x = ~0;
+        vc4->draw_min_y = ~0;
+        vc4->draw_max_x = 0;
+        vc4->draw_max_y = 0;
+}
+
+/**
+ * Submits the job to the kernel and then reinitializes it.
+ */
+void
+vc4_job_submit(struct vc4_context *vc4)
+{
+        if (vc4_debug & VC4_DEBUG_CL) {
+                fprintf(stderr, "BCL:\n");
+                vc4_dump_cl(vc4->bcl.base, vc4->bcl.next - vc4->bcl.base, false);
+                fprintf(stderr, "RCL:\n");
+                vc4_dump_cl(vc4->rcl.base, vc4->rcl.next - vc4->rcl.base, true);
+        }
+
+        struct drm_vc4_submit_cl submit;
+        memset(&submit, 0, sizeof(submit));
+
+        submit.bo_handles = (uintptr_t)vc4->bo_handles.base;
+        submit.bo_handle_count = (vc4->bo_handles.next -
+                                  vc4->bo_handles.base) / 4;
+        submit.bin_cl = (uintptr_t)vc4->bcl.base;
+        submit.bin_cl_size = vc4->bcl.next - vc4->bcl.base;
+        submit.render_cl = (uintptr_t)vc4->rcl.base;
+        submit.render_cl_size = vc4->rcl.next - vc4->rcl.base;
+        submit.shader_rec = (uintptr_t)vc4->shader_rec.base;
+        submit.shader_rec_size = vc4->shader_rec.next - vc4->shader_rec.base;
+        submit.shader_rec_count = vc4->shader_rec_count;
+        submit.uniforms = (uintptr_t)vc4->uniforms.base;
+        submit.uniforms_size = vc4->uniforms.next - vc4->uniforms.base;
+
+        if (!(vc4_debug & VC4_DEBUG_NORAST)) {
+                int ret;
+
+#ifndef USE_VC4_SIMULATOR
+                ret = drmIoctl(vc4->fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit);
+#else
+                ret = vc4_simulator_flush(vc4, &submit);
+#endif
+                if (ret) {
+                        fprintf(stderr, "VC4 submit failed\n");
+                        abort();
+                }
+        }
+
+        vc4->last_emit_seqno = submit.seqno;
+
+        if (vc4_debug & VC4_DEBUG_ALWAYS_SYNC) {
+                if (!vc4_wait_seqno(vc4->screen, vc4->last_emit_seqno,
+                                    PIPE_TIMEOUT_INFINITE)) {
+                        fprintf(stderr, "Wait failed.\n");
+                        abort();
+                }
+        }
+
+        vc4_job_reset(vc4);
+}