1e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt/*
2e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * Copyright © 2014-2015 Broadcom
3e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt *
4e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
5e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * copy of this software and associated documentation files (the "Software"),
6e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * to deal in the Software without restriction, including without limitation
7e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * and/or sell copies of the Software, and to permit persons to whom the
9e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * Software is furnished to do so, subject to the following conditions:
10e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt *
11e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * The above copyright notice and this permission notice (including the next
12e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * paragraph) shall be included in all copies or substantial portions of the
13e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * Software.
14e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt *
15e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * IN THE SOFTWARE.
22e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt */
23e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt
24e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt/** @file vc4_job.c
25e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt *
26e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * Functions for submitting VC4 render jobs to the kernel.
27e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt */
28e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt
29e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt#include <xf86drm.h>
30e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt#include "vc4_context.h"
31f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt#include "util/hash_table.h"
32e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt
33f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtstatic void
34f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtremove_from_ht(struct hash_table *ht, void *key)
35e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt{
36f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        struct hash_entry *entry = _mesa_hash_table_search(ht, key);
37f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        _mesa_hash_table_remove(ht, entry);
38e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt}
39e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt
40f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtstatic void
41f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvc4_job_free(struct vc4_context *vc4, struct vc4_job *job)
42e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt{
439688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        struct vc4_bo **referenced_bos = job->bo_pointers.base;
449688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        for (int i = 0; i < cl_offset(&job->bo_handles) / 4; i++) {
45e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt                vc4_bo_unreference(&referenced_bos[i]);
46e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt        }
479688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt
48f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        remove_from_ht(vc4->jobs, &job->key);
499688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt
50f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (job->color_write) {
51f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                remove_from_ht(vc4->write_jobs, job->color_write->texture);
52f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                pipe_surface_reference(&job->color_write, NULL);
53f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        }
54f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (job->msaa_color_write) {
55f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                remove_from_ht(vc4->write_jobs, job->msaa_color_write->texture);
56f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                pipe_surface_reference(&job->msaa_color_write, NULL);
57f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        }
58f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (job->zs_write) {
59f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                remove_from_ht(vc4->write_jobs, job->zs_write->texture);
60f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                pipe_surface_reference(&job->zs_write, NULL);
61f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        }
62f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (job->msaa_zs_write) {
63f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                remove_from_ht(vc4->write_jobs, job->msaa_zs_write->texture);
64f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                pipe_surface_reference(&job->msaa_zs_write, NULL);
65f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        }
66f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
67f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        pipe_surface_reference(&job->color_read, NULL);
68f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        pipe_surface_reference(&job->zs_read, NULL);
69f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
70f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (vc4->job == job)
71f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                vc4->job = NULL;
72f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
73f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        ralloc_free(job);
74f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt}
75f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
76f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtstatic struct vc4_job *
77f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvc4_job_create(struct vc4_context *vc4)
78f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt{
79f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        struct vc4_job *job = rzalloc(vc4, struct vc4_job);
80f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
81f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        vc4_init_cl(job, &job->bcl);
82f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        vc4_init_cl(job, &job->shader_rec);
83f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        vc4_init_cl(job, &job->uniforms);
84f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        vc4_init_cl(job, &job->bo_handles);
85f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        vc4_init_cl(job, &job->bo_pointers);
869688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt
879688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        job->draw_min_x = ~0;
889688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        job->draw_min_y = ~0;
899688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        job->draw_max_x = 0;
909688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        job->draw_max_y = 0;
919688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt
92f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        return job;
93f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt}
94f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
95f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvoid
96f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvc4_flush_jobs_writing_resource(struct vc4_context *vc4,
97f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                struct pipe_resource *prsc)
98f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt{
99f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        struct hash_entry *entry = _mesa_hash_table_search(vc4->write_jobs,
100f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                                           prsc);
101f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (entry) {
102f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                struct vc4_job *job = entry->data;
103f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                vc4_job_submit(vc4, job);
104f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        }
105f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt}
106f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
107f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvoid
108f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvc4_flush_jobs_reading_resource(struct vc4_context *vc4,
109f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                struct pipe_resource *prsc)
110f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt{
111f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        struct vc4_resource *rsc = vc4_resource(prsc);
112f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
113f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        vc4_flush_jobs_writing_resource(vc4, prsc);
114f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
115f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        struct hash_entry *entry;
116f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        hash_table_foreach(vc4->jobs, entry) {
117f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                struct vc4_job *job = entry->data;
118f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
119f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                struct vc4_bo **referenced_bos = job->bo_pointers.base;
120f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                for (int i = 0; i < cl_offset(&job->bo_handles) / 4; i++) {
121f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        if (referenced_bos[i] == rsc->bo) {
122f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                vc4_job_submit(vc4, job);
123f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                continue;
124f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        }
125f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                }
126f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
127f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                /* Also check for the Z/color buffers, since the references to
128f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                 * those are only added immediately before submit.
129f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                 */
130f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                if (job->color_read && !(job->cleared & PIPE_CLEAR_COLOR)) {
131f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        struct vc4_resource *ctex =
132f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                vc4_resource(job->color_read->texture);
133f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        if (ctex->bo == rsc->bo) {
134f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                vc4_job_submit(vc4, job);
135f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                continue;
136f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        }
137f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                }
138f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
139f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                if (job->zs_read && !(job->cleared &
140f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                      (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
141f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        struct vc4_resource *ztex =
142f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                vc4_resource(job->zs_read->texture);
143f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        if (ztex->bo == rsc->bo) {
144f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                vc4_job_submit(vc4, job);
145f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                continue;
146f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        }
147f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                }
148f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        }
149f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt}
150f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
151f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt/**
152f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt * Returns a vc4_job struture for tracking V3D rendering to a particular FBO.
153f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt *
154f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt * If we've already started rendering to this FBO, then return old same job,
155f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt * otherwise make a new one.  If we're beginning rendering to an FBO, make
156f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt * sure that any previous reads of the FBO (or writes to its color/Z surfaces)
157f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt * have been flushed.
158f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt */
159f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtstruct vc4_job *
160f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvc4_get_job(struct vc4_context *vc4,
161f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt            struct pipe_surface *cbuf, struct pipe_surface *zsbuf)
162f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt{
163f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        /* Return the existing job for this FBO if we have one */
164f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        struct vc4_job_key local_key = {.cbuf = cbuf, .zsbuf = zsbuf};
165f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        struct hash_entry *entry = _mesa_hash_table_search(vc4->jobs,
166f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                                           &local_key);
167f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (entry)
168f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                return entry->data;
169f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
170f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        /* Creating a new job.  Make sure that any previous jobs reading or
171f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt         * writing these buffers are flushed.
172f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt         */
173f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (cbuf)
174f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                vc4_flush_jobs_reading_resource(vc4, cbuf->texture);
175f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (zsbuf)
176f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                vc4_flush_jobs_reading_resource(vc4, zsbuf->texture);
177f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
178f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        struct vc4_job *job = vc4_job_create(vc4);
179f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
180f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (cbuf) {
181f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                if (cbuf->texture->nr_samples > 1) {
182f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        job->msaa = true;
183f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        pipe_surface_reference(&job->msaa_color_write, cbuf);
184f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                } else {
185f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        pipe_surface_reference(&job->color_write, cbuf);
186f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                }
187f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        }
188f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
189f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (zsbuf) {
190f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                if (zsbuf->texture->nr_samples > 1) {
191f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        job->msaa = true;
192f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        pipe_surface_reference(&job->msaa_zs_write, zsbuf);
193f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                } else {
194f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        pipe_surface_reference(&job->zs_write, zsbuf);
195f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                }
196f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        }
197f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
198f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (job->msaa) {
199f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                job->tile_width = 32;
200f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                job->tile_height = 32;
201f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        } else {
202f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                job->tile_width = 64;
203f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                job->tile_height = 64;
204f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        }
205f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
206f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (cbuf)
207f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                _mesa_hash_table_insert(vc4->write_jobs, cbuf->texture, job);
208f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (zsbuf)
209f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                _mesa_hash_table_insert(vc4->write_jobs, zsbuf->texture, job);
210f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
211f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        job->key.cbuf = cbuf;
212f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        job->key.zsbuf = zsbuf;
213f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        _mesa_hash_table_insert(vc4->jobs, &job->key, job);
214f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
215f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        return job;
216f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt}
217f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
218f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtstruct vc4_job *
219f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvc4_get_job_for_fbo(struct vc4_context *vc4)
220f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt{
221f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (vc4->job)
222f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                return vc4->job;
223f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
224f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        struct pipe_surface *cbuf = vc4->framebuffer.cbufs[0];
225f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        struct pipe_surface *zsbuf = vc4->framebuffer.zsbuf;
226f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        struct vc4_job *job = vc4_get_job(vc4, cbuf, zsbuf);
227f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
228f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        /* The dirty flags are tracking what's been updated while vc4->job has
229f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt         * been bound, so set them all to ~0 when switching between jobs.  We
230f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt         * also need to reset all state at the start of rendering.
231f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt         */
232f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        vc4->dirty = ~0;
233f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
234f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        /* Set up the read surfaces in the job.  If they aren't actually
235f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt         * getting read (due to a clear starting the frame), job->cleared will
236f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt         * mask out the read.
237f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt         */
238f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        pipe_surface_reference(&job->color_read, cbuf);
239f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        pipe_surface_reference(&job->zs_read, zsbuf);
240f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
241f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        /* If we're binding to uninitialized buffers, no need to load their
242f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt         * contents before drawing.
243f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt         */
244f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (cbuf) {
245f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                struct vc4_resource *rsc = vc4_resource(cbuf->texture);
246f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                if (!rsc->writes)
247f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        job->cleared |= PIPE_CLEAR_COLOR0;
248f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        }
249f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
250f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        if (zsbuf) {
251f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                struct vc4_resource *rsc = vc4_resource(zsbuf->texture);
252f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                if (!rsc->writes)
253f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                        job->cleared |= PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL;
254f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        }
255f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
256f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        job->draw_tiles_x = DIV_ROUND_UP(vc4->framebuffer.width,
257f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                         job->tile_width);
258f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        job->draw_tiles_y = DIV_ROUND_UP(vc4->framebuffer.height,
259f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                         job->tile_height);
260f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
261f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        vc4->job = job;
262f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
263f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        return job;
264e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt}
265e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt
2669adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholtstatic void
2679688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholtvc4_submit_setup_rcl_surface(struct vc4_job *job,
2689adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt                             struct drm_vc4_submit_rcl_surface *submit_surf,
2699adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt                             struct pipe_surface *psurf,
2709adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt                             bool is_depth, bool is_write)
2719adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt{
2729adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt        struct vc4_surface *surf = vc4_surface(psurf);
2739adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
274f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt        if (!surf)
2759adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt                return;
2769adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
2779adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt        struct vc4_resource *rsc = vc4_resource(psurf->texture);
2789688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit_surf->hindex = vc4_gem_hindex(job, rsc->bo);
2799adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt        submit_surf->offset = surf->offset;
2809adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
281f2cf2a63f1211642ca20b73ad5f23c60cc3fa703Eric Anholt        if (psurf->texture->nr_samples <= 1) {
282edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                if (is_depth) {
283edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                        submit_surf->bits =
284edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_ZS,
285edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                              VC4_LOADSTORE_TILE_BUFFER_BUFFER);
286edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt
287edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                } else {
288edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                        submit_surf->bits =
289edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_COLOR,
290edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                              VC4_LOADSTORE_TILE_BUFFER_BUFFER) |
291edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                VC4_SET_FIELD(vc4_rt_format_is_565(psurf->format) ?
292edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                              VC4_LOADSTORE_TILE_BUFFER_BGR565 :
293edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                              VC4_LOADSTORE_TILE_BUFFER_RGBA8888,
294edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                              VC4_LOADSTORE_TILE_BUFFER_FORMAT);
295edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                }
296edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                submit_surf->bits |=
297edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                        VC4_SET_FIELD(surf->tiling,
298edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                      VC4_LOADSTORE_TILE_BUFFER_TILING);
2999adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt        } else {
300edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                assert(!is_write);
301edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                submit_surf->flags |= VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES;
3029adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt        }
3039adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
3049adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt        if (is_write)
3059adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt                rsc->writes++;
3069adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt}
3079adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
3089adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholtstatic void
3099688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholtvc4_submit_setup_rcl_render_config_surface(struct vc4_job *job,
310568d3a8e32109200cc12549d18118b7660be628bEric Anholt                                           struct drm_vc4_submit_rcl_surface *submit_surf,
311568d3a8e32109200cc12549d18118b7660be628bEric Anholt                                           struct pipe_surface *psurf)
3129adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt{
3139adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt        struct vc4_surface *surf = vc4_surface(psurf);
3149adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
315f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt        if (!surf)
3169adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt                return;
3179adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
3189adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt        struct vc4_resource *rsc = vc4_resource(psurf->texture);
3199688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit_surf->hindex = vc4_gem_hindex(job, rsc->bo);
3209adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt        submit_surf->offset = surf->offset;
3219adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
322f2cf2a63f1211642ca20b73ad5f23c60cc3fa703Eric Anholt        if (psurf->texture->nr_samples <= 1) {
323edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                submit_surf->bits =
324edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                        VC4_SET_FIELD(vc4_rt_format_is_565(surf->base.format) ?
325edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                      VC4_RENDER_CONFIG_FORMAT_BGR565 :
326edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                      VC4_RENDER_CONFIG_FORMAT_RGBA8888,
327edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                      VC4_RENDER_CONFIG_FORMAT) |
328edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                        VC4_SET_FIELD(surf->tiling,
329edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                      VC4_RENDER_CONFIG_MEMORY_FORMAT);
330edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt        }
331edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt
332edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt        rsc->writes++;
333edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt}
334edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt
335edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholtstatic void
3369688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholtvc4_submit_setup_rcl_msaa_surface(struct vc4_job *job,
337edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                  struct drm_vc4_submit_rcl_surface *submit_surf,
338edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                                  struct pipe_surface *psurf)
339edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt{
340edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt        struct vc4_surface *surf = vc4_surface(psurf);
341edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt
342f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt        if (!surf)
343edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                return;
3449adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
345edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt        struct vc4_resource *rsc = vc4_resource(psurf->texture);
3469688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit_surf->hindex = vc4_gem_hindex(job, rsc->bo);
347edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt        submit_surf->offset = surf->offset;
348edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt        submit_surf->bits = 0;
3499adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt        rsc->writes++;
3509adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt}
3519adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
352e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt/**
353e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt * Submits the job to the kernel and then reinitializes it.
354e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt */
355e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholtvoid
3569688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholtvc4_job_submit(struct vc4_context *vc4, struct vc4_job *job)
357e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt{
3589688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        if (!job->needs_flush)
359f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                goto done;
360774a556b6dc0d49f9f29c438349a66e69062e6e4Eric Anholt
361774a556b6dc0d49f9f29c438349a66e69062e6e4Eric Anholt        /* The RCL setup would choke if the draw bounds cause no drawing, so
362774a556b6dc0d49f9f29c438349a66e69062e6e4Eric Anholt         * just drop the drawing if that's the case.
363774a556b6dc0d49f9f29c438349a66e69062e6e4Eric Anholt         */
3649688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        if (job->draw_max_x <= job->draw_min_x ||
3659688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt            job->draw_max_y <= job->draw_min_y) {
366f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                goto done;
367774a556b6dc0d49f9f29c438349a66e69062e6e4Eric Anholt        }
368774a556b6dc0d49f9f29c438349a66e69062e6e4Eric Anholt
369e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt        if (vc4_debug & VC4_DEBUG_CL) {
370e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt                fprintf(stderr, "BCL:\n");
3719688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt                vc4_dump_cl(job->bcl.base, cl_offset(&job->bcl), false);
372e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt        }
373e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt
3749688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        if (cl_offset(&job->bcl) > 0) {
3750ef1b32ebbcf9ad6316021a1059ba7d6a65b9588Eric Anholt                /* Increment the semaphore indicating that binning is done and
3760ef1b32ebbcf9ad6316021a1059ba7d6a65b9588Eric Anholt                 * unblocking the render thread.  Note that this doesn't act
3770ef1b32ebbcf9ad6316021a1059ba7d6a65b9588Eric Anholt                 * until the FLUSH completes.
3780ef1b32ebbcf9ad6316021a1059ba7d6a65b9588Eric Anholt                 */
3799688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt                cl_ensure_space(&job->bcl, 8);
3809688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt                struct vc4_cl_out *bcl = cl_start(&job->bcl);
3810ef1b32ebbcf9ad6316021a1059ba7d6a65b9588Eric Anholt                cl_u8(&bcl, VC4_PACKET_INCREMENT_SEMAPHORE);
3820ef1b32ebbcf9ad6316021a1059ba7d6a65b9588Eric Anholt                /* The FLUSH caps all of our bin lists with a
3830ef1b32ebbcf9ad6316021a1059ba7d6a65b9588Eric Anholt                 * VC4_PACKET_RETURN.
3840ef1b32ebbcf9ad6316021a1059ba7d6a65b9588Eric Anholt                 */
3850ef1b32ebbcf9ad6316021a1059ba7d6a65b9588Eric Anholt                cl_u8(&bcl, VC4_PACKET_FLUSH);
3869688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt                cl_end(&job->bcl, bcl);
3870ef1b32ebbcf9ad6316021a1059ba7d6a65b9588Eric Anholt        }
388f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt        struct drm_vc4_submit_cl submit = {
389f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                .color_read.hindex = ~0,
390f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                .zs_read.hindex = ~0,
391f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                .color_write.hindex = ~0,
392f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                .msaa_color_write.hindex = ~0,
393f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                .zs_write.hindex = ~0,
394f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                .msaa_zs_write.hindex = ~0,
395f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt        };
396e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt
3979688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        cl_ensure_space(&job->bo_handles, 6 * sizeof(uint32_t));
3989688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        cl_ensure_space(&job->bo_pointers, 6 * sizeof(struct vc4_bo *));
3999adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
400f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt        if (job->resolve & PIPE_CLEAR_COLOR) {
401f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                if (!(job->cleared & PIPE_CLEAR_COLOR)) {
402f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                        vc4_submit_setup_rcl_surface(job, &submit.color_read,
403f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                                                     job->color_read,
404f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                                                     false, false);
405f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                }
406f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                vc4_submit_setup_rcl_render_config_surface(job,
407f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                                                           &submit.color_write,
408f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                                                           job->color_write);
409f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                vc4_submit_setup_rcl_msaa_surface(job,
410f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                                                  &submit.msaa_color_write,
411f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                                                  job->msaa_color_write);
412f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt        }
413f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt        if (job->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
414f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                if (!(job->cleared & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
415f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                        vc4_submit_setup_rcl_surface(job, &submit.zs_read,
416f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                                                     job->zs_read, true, false);
417f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                }
418f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                vc4_submit_setup_rcl_surface(job, &submit.zs_write,
419f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                                             job->zs_write, true, true);
420f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                vc4_submit_setup_rcl_msaa_surface(job, &submit.msaa_zs_write,
421f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt                                                  job->msaa_zs_write);
422f473348468ae1c68e7ef8eaf29f2cc51d17fbec7Eric Anholt        }
423edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt
4249688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        if (job->msaa) {
425edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                /* This bit controls how many pixels the general
426edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                 * (i.e. subsampled) loads/stores are iterating over
427edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                 * (multisample loads replicate out to the other samples).
428edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                 */
429edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                submit.color_write.bits |= VC4_RENDER_CONFIG_MS_MODE_4X;
430edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                /* Controls whether color_write's
431edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                 * VC4_PACKET_STORE_MS_TILE_BUFFER does 4x decimation
432edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                 */
433edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt                submit.color_write.bits |= VC4_RENDER_CONFIG_DECIMATE_MODE_4X;
434edfd4d853a0d26bc0cde811de7b20116db7e66fcEric Anholt        }
4359adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
4369688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.bo_handles = (uintptr_t)job->bo_handles.base;
4379688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.bo_handle_count = cl_offset(&job->bo_handles) / 4;
4389688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.bin_cl = (uintptr_t)job->bcl.base;
4399688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.bin_cl_size = cl_offset(&job->bcl);
4409688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.shader_rec = (uintptr_t)job->shader_rec.base;
4419688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.shader_rec_size = cl_offset(&job->shader_rec);
4429688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.shader_rec_count = job->shader_rec_count;
4439688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.uniforms = (uintptr_t)job->uniforms.base;
4449688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.uniforms_size = cl_offset(&job->uniforms);
4459688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt
4469688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        assert(job->draw_min_x != ~0 && job->draw_min_y != ~0);
4479688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.min_x_tile = job->draw_min_x / job->tile_width;
4489688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.min_y_tile = job->draw_min_y / job->tile_height;
4499688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.max_x_tile = (job->draw_max_x - 1) / job->tile_width;
4509688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.max_y_tile = (job->draw_max_y - 1) / job->tile_height;
4519688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.width = job->draw_width;
4529688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        submit.height = job->draw_height;
4539688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt        if (job->cleared) {
4549adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt                submit.flags |= VC4_SUBMIT_CL_USE_CLEAR_COLOR;
4559688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt                submit.clear_color[0] = job->clear_color[0];
4569688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt                submit.clear_color[1] = job->clear_color[1];
4579688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt                submit.clear_z = job->clear_depth;
4589688166bd9c3e12c74c55b857ad0dbb62b28da9eEric Anholt                submit.clear_s = job->clear_stencil;
4599adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt        }
4609adcd2d80aceec90b9c3712b53d8e7839dc5634bEric Anholt
461e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt        if (!(vc4_debug & VC4_DEBUG_NORAST)) {
462e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt                int ret;
463e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt
464e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt#ifndef USE_VC4_SIMULATOR
465e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt                ret = drmIoctl(vc4->fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit);
466e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt#else
467f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                ret = vc4_simulator_flush(vc4, &submit, job);
468e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt#endif
46902bcb443ee39cec1b61e5ba3e466471f3668f536Eric Anholt                static bool warned = false;
47002bcb443ee39cec1b61e5ba3e466471f3668f536Eric Anholt                if (ret && !warned) {
47102bcb443ee39cec1b61e5ba3e466471f3668f536Eric Anholt                        fprintf(stderr, "Draw call returned %s.  "
47202bcb443ee39cec1b61e5ba3e466471f3668f536Eric Anholt                                        "Expect corruption.\n", strerror(errno));
47302bcb443ee39cec1b61e5ba3e466471f3668f536Eric Anholt                        warned = true;
4742a449ce7c961f3269f9a37ddf4fe340fc170c609Eric Anholt                } else if (!ret) {
4752a449ce7c961f3269f9a37ddf4fe340fc170c609Eric Anholt                        vc4->last_emit_seqno = submit.seqno;
476e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt                }
477e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt        }
478e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt
4793fba517bdd03551f7c7ff21dfe1896c677cbccdaEric Anholt        if (vc4->last_emit_seqno - vc4->screen->finished_seqno > 5) {
4803fba517bdd03551f7c7ff21dfe1896c677cbccdaEric Anholt                if (!vc4_wait_seqno(vc4->screen,
4813fba517bdd03551f7c7ff21dfe1896c677cbccdaEric Anholt                                    vc4->last_emit_seqno - 5,
4823fba517bdd03551f7c7ff21dfe1896c677cbccdaEric Anholt                                    PIPE_TIMEOUT_INFINITE,
4833fba517bdd03551f7c7ff21dfe1896c677cbccdaEric Anholt                                    "job throttling")) {
4843fba517bdd03551f7c7ff21dfe1896c677cbccdaEric Anholt                        fprintf(stderr, "Job throttling failed\n");
4853fba517bdd03551f7c7ff21dfe1896c677cbccdaEric Anholt                }
4863fba517bdd03551f7c7ff21dfe1896c677cbccdaEric Anholt        }
4873fba517bdd03551f7c7ff21dfe1896c677cbccdaEric Anholt
488e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt        if (vc4_debug & VC4_DEBUG_ALWAYS_SYNC) {
489e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt                if (!vc4_wait_seqno(vc4->screen, vc4->last_emit_seqno,
490ab80519b3cd08401dff2d07343064a27f32b33caEric Anholt                                    PIPE_TIMEOUT_INFINITE, "sync")) {
491e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt                        fprintf(stderr, "Wait failed.\n");
492e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt                        abort();
493e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt                }
494e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt        }
495e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt
496f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtdone:
497f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        vc4_job_free(vc4, job);
498f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt}
499f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
500f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtstatic bool
501f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvc4_job_compare(const void *a, const void *b)
502f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt{
503f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        return memcmp(a, b, sizeof(struct vc4_job_key)) == 0;
504f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt}
505f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
506f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtstatic uint32_t
507f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvc4_job_hash(const void *key)
508f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt{
509f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        return _mesa_hash_data(key, sizeof(struct vc4_job_key));
510f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt}
511f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
512f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvoid
513f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholtvc4_job_init(struct vc4_context *vc4)
514f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt{
515f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        vc4->jobs = _mesa_hash_table_create(vc4,
516f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                            vc4_job_hash,
517f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                            vc4_job_compare);
518f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt        vc4->write_jobs = _mesa_hash_table_create(vc4,
519f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                                  _mesa_hash_pointer,
520f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt                                                  _mesa_key_pointer_equal);
521e214a596352e67c89ce379a1e5a060dbc1ce31e1Eric Anholt}
522f597ac3966405934e13a9aaa18c73211b5a40c7cEric Anholt
523