xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/vc4/vc4_context.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2014 Broadcom
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include <xf86drm.h>
25 #include <err.h>
26 
27 #include "pipe/p_defines.h"
28 #include "util/ralloc.h"
29 #include "util/u_inlines.h"
30 #include "util/u_memory.h"
31 #include "util/u_blitter.h"
32 #include "util/u_upload_mgr.h"
33 #include "pipe/p_screen.h"
34 
35 #include "vc4_screen.h"
36 #include "vc4_context.h"
37 #include "vc4_resource.h"
38 
39 void
vc4_flush(struct pipe_context * pctx)40 vc4_flush(struct pipe_context *pctx)
41 {
42         struct vc4_context *vc4 = vc4_context(pctx);
43 
44         hash_table_foreach(vc4->jobs, entry) {
45                 struct vc4_job *job = entry->data;
46                 vc4_job_submit(vc4, job);
47         }
48 }
49 
50 static void
vc4_pipe_flush(struct pipe_context * pctx,struct pipe_fence_handle ** fence,unsigned flags)51 vc4_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
52                unsigned flags)
53 {
54         struct vc4_context *vc4 = vc4_context(pctx);
55 
56         vc4_flush(pctx);
57 
58         if (fence) {
59                 struct pipe_screen *screen = pctx->screen;
60                 int fd = -1;
61 
62                 if (flags & PIPE_FLUSH_FENCE_FD) {
63                         /* The vc4_fence takes ownership of the returned fd. */
64                         drmSyncobjExportSyncFile(vc4->fd, vc4->job_syncobj,
65                                                  &fd);
66                 }
67 
68                 struct vc4_fence *f = vc4_fence_create(vc4->screen,
69                                                        vc4->last_emit_seqno,
70                                                        fd);
71                 screen->fence_reference(screen, fence, NULL);
72                 *fence = (struct pipe_fence_handle *)f;
73         }
74 }
75 
76 /* We can't flush the texture cache within rendering a tile, so we have to
77  * flush all rendering to the kernel so that the next job reading from the
78  * tile gets a flushed cache.
79  */
80 static void
vc4_texture_barrier(struct pipe_context * pctx,unsigned flags)81 vc4_texture_barrier(struct pipe_context *pctx, unsigned flags)
82 {
83         vc4_flush(pctx);
84 }
85 
86 static void
vc4_invalidate_resource(struct pipe_context * pctx,struct pipe_resource * prsc)87 vc4_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
88 {
89         struct vc4_context *vc4 = vc4_context(pctx);
90         struct vc4_resource *rsc = vc4_resource(prsc);
91 
92         rsc->initialized_buffers = 0;
93 
94         struct hash_entry *entry = _mesa_hash_table_search(vc4->write_jobs,
95                                                            prsc);
96         if (!entry)
97                 return;
98 
99         struct vc4_job *job = entry->data;
100         if (job->key.zsbuf && job->key.zsbuf->texture == prsc)
101                 job->resolve &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL);
102 }
103 
104 static void
vc4_context_destroy(struct pipe_context * pctx)105 vc4_context_destroy(struct pipe_context *pctx)
106 {
107         struct vc4_context *vc4 = vc4_context(pctx);
108 
109         vc4_flush(pctx);
110 
111         if (vc4->blitter)
112                 util_blitter_destroy(vc4->blitter);
113 
114         if (vc4->uploader)
115                 u_upload_destroy(vc4->uploader);
116 
117         slab_destroy_child(&vc4->transfer_pool);
118 
119         util_unreference_framebuffer_state(&vc4->framebuffer);
120 
121         if (vc4->yuv_linear_blit_vs)
122                 pctx->delete_vs_state(pctx, vc4->yuv_linear_blit_vs);
123         if (vc4->yuv_linear_blit_fs_8bit)
124                 pctx->delete_fs_state(pctx, vc4->yuv_linear_blit_fs_8bit);
125         if (vc4->yuv_linear_blit_fs_16bit)
126                 pctx->delete_fs_state(pctx, vc4->yuv_linear_blit_fs_16bit);
127 
128         vc4_program_fini(pctx);
129 
130         if (vc4->screen->has_syncobj) {
131                 drmSyncobjDestroy(vc4->fd, vc4->job_syncobj);
132                 drmSyncobjDestroy(vc4->fd, vc4->in_syncobj);
133         }
134         if (vc4->in_fence_fd >= 0)
135                 close(vc4->in_fence_fd);
136 
137         ralloc_free(vc4);
138 }
139 
140 struct pipe_context *
vc4_context_create(struct pipe_screen * pscreen,void * priv,unsigned flags)141 vc4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
142 {
143         struct vc4_screen *screen = vc4_screen(pscreen);
144         struct vc4_context *vc4;
145         int err;
146 
147         /* Prevent dumping of the shaders built during context setup. */
148         uint32_t saved_shaderdb_flag = vc4_mesa_debug & VC4_DEBUG_SHADERDB;
149         vc4_mesa_debug &= ~VC4_DEBUG_SHADERDB;
150 
151         vc4 = rzalloc(NULL, struct vc4_context);
152         if (!vc4)
153                 return NULL;
154         struct pipe_context *pctx = &vc4->base;
155 
156         vc4->screen = screen;
157 
158         pctx->screen = pscreen;
159         pctx->priv = priv;
160         pctx->destroy = vc4_context_destroy;
161         pctx->flush = vc4_pipe_flush;
162         pctx->set_debug_callback = u_default_set_debug_callback;
163         pctx->invalidate_resource = vc4_invalidate_resource;
164         pctx->texture_barrier = vc4_texture_barrier;
165 
166         vc4_draw_init(pctx);
167         vc4_state_init(pctx);
168         vc4_program_init(pctx);
169         vc4_query_init(pctx);
170         vc4_resource_context_init(pctx);
171 
172         vc4->fd = screen->fd;
173 
174         err = vc4_job_init(vc4);
175         if (err)
176                 goto fail;
177 
178         err = vc4_fence_context_init(vc4);
179         if (err)
180                 goto fail;
181 
182         slab_create_child(&vc4->transfer_pool, &screen->transfer_pool);
183 
184 	vc4->uploader = u_upload_create_default(&vc4->base);
185 	vc4->base.stream_uploader = vc4->uploader;
186 	vc4->base.const_uploader = vc4->uploader;
187 
188 	vc4->blitter = util_blitter_create(pctx);
189         if (!vc4->blitter)
190                 goto fail;
191 
192         vc4_mesa_debug |= saved_shaderdb_flag;
193 
194         vc4->sample_mask = (1 << VC4_MAX_SAMPLES) - 1;
195 
196         return &vc4->base;
197 
198 fail:
199         pctx->destroy(pctx);
200         return NULL;
201 }
202