+ struct vc4_resource *rsc = vc4_resource(prsc);
+
+ vc4_flush_jobs_writing_resource(vc4, prsc);
+
+ struct hash_entry *entry;
+ hash_table_foreach(vc4->jobs, entry) {
+ struct vc4_job *job = entry->data;
+
+ struct vc4_bo **referenced_bos = job->bo_pointers.base;
+ bool found = false;
+ for (int i = 0; i < cl_offset(&job->bo_handles) / 4; i++) {
+ if (referenced_bos[i] == rsc->bo) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ vc4_job_submit(vc4, job);
+ continue;
+ }
+
+ /* Also check for the Z/color buffers, since the references to
+ * those are only added immediately before submit.
+ */
+ if (job->color_read && !(job->cleared & PIPE_CLEAR_COLOR)) {
+ struct vc4_resource *ctex =
+ vc4_resource(job->color_read->texture);
+ if (ctex->bo == rsc->bo) {
+ vc4_job_submit(vc4, job);
+ continue;
+ }
+ }
+
+ if (job->zs_read && !(job->cleared &
+ (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
+ struct vc4_resource *ztex =
+ vc4_resource(job->zs_read->texture);
+ if (ztex->bo == rsc->bo) {
+ vc4_job_submit(vc4, job);
+ continue;
+ }
+ }
+ }
+}
+
+/**
+ * Returns a vc4_job struture for tracking V3D rendering to a particular FBO.
+ *
+ * If we've already started rendering to this FBO, then return old 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.
+ */
+struct vc4_job *
+vc4_get_job(struct vc4_context *vc4,
+ struct pipe_surface *cbuf, struct pipe_surface *zsbuf)
+{
+ /* Return the existing job for this FBO if we have one */
+ struct vc4_job_key local_key = {.cbuf = cbuf, .zsbuf = zsbuf};
+ struct hash_entry *entry = _mesa_hash_table_search(vc4->jobs,
+ &local_key);
+ if (entry)
+ return entry->data;
+
+ /* Creating a new job. Make sure that any previous jobs reading or
+ * writing these buffers are flushed.
+ */
+ if (cbuf)
+ vc4_flush_jobs_reading_resource(vc4, cbuf->texture);
+ if (zsbuf)
+ vc4_flush_jobs_reading_resource(vc4, zsbuf->texture);
+
+ struct vc4_job *job = vc4_job_create(vc4);
+
+ if (cbuf) {
+ if (cbuf->texture->nr_samples > 1) {
+ job->msaa = true;
+ pipe_surface_reference(&job->msaa_color_write, cbuf);
+ } else {
+ pipe_surface_reference(&job->color_write, cbuf);
+ }
+ }
+
+ if (zsbuf) {
+ if (zsbuf->texture->nr_samples > 1) {
+ job->msaa = true;
+ pipe_surface_reference(&job->msaa_zs_write, zsbuf);
+ } else {
+ pipe_surface_reference(&job->zs_write, zsbuf);
+ }
+ }
+
+ if (job->msaa) {
+ job->tile_width = 32;
+ job->tile_height = 32;
+ } else {
+ job->tile_width = 64;
+ job->tile_height = 64;