freedreno/a6xx: fix hangs with newer sqe fw
[mesa.git] / src / gallium / drivers / v3d / v3d_job.c
index 9ab8e5107a72f1d5498e006f49f7835e3455bb60..73546adfc667363c8d81c1973162893a418eb0ef 100644 (file)
 #include "util/set.h"
 #include "broadcom/clif/clif_dump.h"
 
-static void
-remove_from_ht(struct hash_table *ht, void *key)
-{
-        struct hash_entry *entry = _mesa_hash_table_search(ht, key);
-        _mesa_hash_table_remove(ht, entry);
-}
-
 static void
 v3d_job_free(struct v3d_context *v3d, struct v3d_job *job)
 {
-        struct set_entry *entry;
-
         set_foreach(job->bos, entry) {
                 struct v3d_bo *bo = (struct v3d_bo *)entry->key;
                 v3d_bo_unreference(&bo);
         }
 
-        remove_from_ht(v3d->jobs, &job->key);
+        _mesa_hash_table_remove_key(v3d->jobs, &job->key);
 
         if (job->write_prscs) {
-                struct set_entry *entry;
-
                 set_foreach(job->write_prscs, entry) {
                         const struct pipe_resource *prsc = entry->key;
 
-                        remove_from_ht(v3d->write_jobs, (void *)prsc);
+                        _mesa_hash_table_remove_key(v3d->write_jobs, prsc);
                 }
         }
 
-        for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++) {
+        for (int i = 0; i < V3D_MAX_DRAW_BUFFERS; i++) {
                 if (job->cbufs[i]) {
-                        remove_from_ht(v3d->write_jobs, job->cbufs[i]->texture);
+                        _mesa_hash_table_remove_key(v3d->write_jobs,
+                                                    job->cbufs[i]->texture);
                         pipe_surface_reference(&job->cbufs[i], NULL);
                 }
         }
         if (job->zsbuf) {
                 struct v3d_resource *rsc = v3d_resource(job->zsbuf->texture);
                 if (rsc->separate_stencil)
-                        remove_from_ht(v3d->write_jobs,
-                                       &rsc->separate_stencil->base);
+                        _mesa_hash_table_remove_key(v3d->write_jobs,
+                                                    &rsc->separate_stencil->base);
 
-                remove_from_ht(v3d->write_jobs, job->zsbuf->texture);
+                _mesa_hash_table_remove_key(v3d->write_jobs,
+                                            job->zsbuf->texture);
                 pipe_surface_reference(&job->zsbuf, NULL);
         }
 
@@ -175,7 +166,6 @@ v3d_flush_jobs_reading_resource(struct v3d_context *v3d,
 
         v3d_flush_jobs_writing_resource(v3d, prsc);
 
-        struct hash_entry *entry;
         hash_table_foreach(v3d->jobs, entry) {
                 struct v3d_job *job = entry->data;
 
@@ -209,7 +199,7 @@ v3d_job_set_tile_buffer_size(struct v3d_job *job)
                 tile_size_index++;
 
         int max_bpp = RENDER_TARGET_MAXIMUM_32BPP;
-        for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++) {
+        for (int i = 0; i < V3D_MAX_DRAW_BUFFERS; i++) {
                 if (job->cbufs[i]) {
                         struct v3d_surface *surf = v3d_surface(job->cbufs[i]);
                         max_bpp = MAX2(max_bpp, surf->internal_bpp);
@@ -227,7 +217,7 @@ v3d_job_set_tile_buffer_size(struct v3d_job *job)
 /**
  * Returns a v3d_job struture for tracking V3D rendering to a particular FBO.
  *
- * If we've already started rendering to this FBO, then return old same job,
+ * If we've already started rendering to this FBO, then return the same job,
  * otherwise make a new one.  If we're beginning rendering to an FBO, make
  * sure that any previous reads of the FBO (or writes to its color/Z surfaces)
  * have been flushed.
@@ -256,7 +246,7 @@ v3d_get_job(struct v3d_context *v3d,
          */
         struct v3d_job *job = v3d_job_create(v3d);
 
-        for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++) {
+        for (int i = 0; i < V3D_MAX_DRAW_BUFFERS; i++) {
                 if (cbufs[i]) {
                         v3d_flush_jobs_reading_resource(v3d, cbufs[i]->texture);
                         pipe_surface_reference(&job->cbufs[i], cbufs[i]);
@@ -272,9 +262,7 @@ v3d_get_job(struct v3d_context *v3d,
                         job->msaa = true;
         }
 
-        v3d_job_set_tile_buffer_size(job);
-
-        for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++) {
+        for (int i = 0; i < V3D_MAX_DRAW_BUFFERS; i++) {
                 if (cbufs[i])
                         _mesa_hash_table_insert(v3d->write_jobs,
                                                 cbufs[i]->texture, job);
@@ -308,6 +296,11 @@ v3d_get_job_for_fbo(struct v3d_context *v3d)
         struct pipe_surface *zsbuf = v3d->framebuffer.zsbuf;
         struct v3d_job *job = v3d_get_job(v3d, cbufs, zsbuf);
 
+        if (v3d->framebuffer.samples >= 1)
+                job->msaa = true;
+
+        v3d_job_set_tile_buffer_size(job);
+
         /* The dirty flags are tracking what's been updated while v3d->job has
          * been bound, so set them all to ~0 when switching between jobs.  We
          * also need to reset all state at the start of rendering.
@@ -341,44 +334,30 @@ v3d_get_job_for_fbo(struct v3d_context *v3d)
         return job;
 }
 
-static bool
-v3d_clif_dump_lookup(void *data, uint32_t addr, void **vaddr)
-{
-        struct v3d_job *job = data;
-        struct set_entry *entry;
-
-        set_foreach(job->bos, entry) {
-                struct v3d_bo *bo = (void *)entry->key;
-
-                if (addr >= bo->offset &&
-                    addr < bo->offset + bo->size) {
-                        v3d_bo_map(bo);
-                        *vaddr = bo->map + addr - bo->offset;
-                        return true;
-                }
-        }
-
-        return false;
-}
-
 static void
 v3d_clif_dump(struct v3d_context *v3d, struct v3d_job *job)
 {
-        if (!(V3D_DEBUG & V3D_DEBUG_CL))
+        if (!(V3D_DEBUG & (V3D_DEBUG_CL | V3D_DEBUG_CLIF)))
                 return;
 
         struct clif_dump *clif = clif_dump_init(&v3d->screen->devinfo,
-                                                stderr, v3d_clif_dump_lookup,
-                                                job);
+                                                stderr,
+                                                V3D_DEBUG & V3D_DEBUG_CL);
 
-        fprintf(stderr, "BCL: 0x%08x..0x%08x\n",
-                job->submit.bcl_start, job->submit.bcl_end);
+        set_foreach(job->bos, entry) {
+                struct v3d_bo *bo = (void *)entry->key;
+                char *name = ralloc_asprintf(NULL, "%s_0x%x",
+                                             bo->name, bo->offset);
+
+                v3d_bo_map(bo);
+                clif_dump_add_bo(clif, name, bo->offset, bo->size, bo->map);
+
+                ralloc_free(name);
+        }
 
-        clif_dump_add_cl(clif, job->submit.bcl_start, job->submit.bcl_end);
+        clif_dump(clif, &job->submit);
 
-        fprintf(stderr, "RCL: 0x%08x..0x%08x\n",
-                job->submit.rcl_start, job->submit.rcl_end);
-        clif_dump_add_cl(clif, job->submit.rcl_start, job->submit.rcl_end);
+        clif_dump_destroy(clif);
 }
 
 /**
@@ -404,7 +383,15 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job)
                         v3d33_bcl_epilogue(v3d, job);
         }
 
+        /* While the RCL will implicitly depend on the last RCL to have
+         * finished, we also need to block on any previous TFU job we may have
+         * dispatched.
+         */
+        job->submit.in_sync_rcl = v3d->out_sync;
+
+        /* Update the sync object for the last rendering by our context. */
         job->submit.out_sync = v3d->out_sync;
+
         job->submit.bcl_end = job->bcl.bo->offset + cl_offset(&job->bcl);
         job->submit.rcl_end = job->rcl.bo->offset + cl_offset(&job->rcl);
 
@@ -425,11 +412,7 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job)
         if (!(V3D_DEBUG & V3D_DEBUG_NORAST)) {
                 int ret;
 
-#ifndef USE_V3D_SIMULATOR
-                ret = drmIoctl(v3d->fd, DRM_IOCTL_V3D_SUBMIT_CL, &job->submit);
-#else
-                ret = v3d_simulator_flush(v3d, &job->submit, job);
-#endif
+                ret = v3d_ioctl(v3d->fd, DRM_IOCTL_V3D_SUBMIT_CL, &job->submit);
                 static bool warned = false;
                 if (ret && !warned) {
                         fprintf(stderr, "Draw call returned %s.  "