2 * Copyright © 2014-2015 Broadcom
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:
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
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
26 * Functions for submitting VC4 render jobs to the kernel.
30 #include "vc4_context.h"
33 vc4_job_init(struct vc4_context
*vc4
)
35 vc4_init_cl(vc4
, &vc4
->bcl
);
36 vc4_init_cl(vc4
, &vc4
->shader_rec
);
37 vc4_init_cl(vc4
, &vc4
->uniforms
);
38 vc4_init_cl(vc4
, &vc4
->bo_handles
);
39 vc4_init_cl(vc4
, &vc4
->bo_pointers
);
44 vc4_job_reset(struct vc4_context
*vc4
)
46 struct vc4_bo
**referenced_bos
= vc4
->bo_pointers
.base
;
47 for (int i
= 0; i
< cl_offset(&vc4
->bo_handles
) / 4; i
++) {
48 vc4_bo_unreference(&referenced_bos
[i
]);
50 vc4_reset_cl(&vc4
->bcl
);
51 vc4_reset_cl(&vc4
->shader_rec
);
52 vc4_reset_cl(&vc4
->uniforms
);
53 vc4_reset_cl(&vc4
->bo_handles
);
54 vc4_reset_cl(&vc4
->bo_pointers
);
55 vc4
->shader_rec_count
= 0;
57 vc4
->needs_flush
= false;
58 vc4
->draw_call_queued
= false;
60 /* We have no hardware context saved between our draw calls, so we
61 * need to flag the next draw as needing all state emitted. Emitting
62 * all state at the start of our draws is also what ensures that we
63 * return to the state we need after a previous tile has finished.
76 vc4_submit_setup_rcl_surface(struct vc4_context
*vc4
,
77 struct drm_vc4_submit_rcl_surface
*submit_surf
,
78 struct pipe_surface
*psurf
,
79 bool is_depth
, bool is_write
)
81 struct vc4_surface
*surf
= vc4_surface(psurf
);
84 submit_surf
->hindex
= ~0;
88 struct vc4_resource
*rsc
= vc4_resource(psurf
->texture
);
89 submit_surf
->hindex
= vc4_gem_hindex(vc4
, rsc
->bo
);
90 submit_surf
->offset
= surf
->offset
;
94 VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_ZS
,
95 VC4_LOADSTORE_TILE_BUFFER_BUFFER
);
99 VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_COLOR
,
100 VC4_LOADSTORE_TILE_BUFFER_BUFFER
) |
101 VC4_SET_FIELD(vc4_rt_format_is_565(psurf
->format
) ?
102 VC4_LOADSTORE_TILE_BUFFER_BGR565
:
103 VC4_LOADSTORE_TILE_BUFFER_RGBA8888
,
104 VC4_LOADSTORE_TILE_BUFFER_FORMAT
);
107 VC4_SET_FIELD(surf
->tiling
, VC4_LOADSTORE_TILE_BUFFER_TILING
);
114 vc4_submit_setup_ms_rcl_surface(struct vc4_context
*vc4
,
115 struct drm_vc4_submit_rcl_surface
*submit_surf
,
116 struct pipe_surface
*psurf
)
118 struct vc4_surface
*surf
= vc4_surface(psurf
);
121 submit_surf
->hindex
= ~0;
125 struct vc4_resource
*rsc
= vc4_resource(psurf
->texture
);
126 submit_surf
->hindex
= vc4_gem_hindex(vc4
, rsc
->bo
);
127 submit_surf
->offset
= surf
->offset
;
130 VC4_SET_FIELD(vc4_rt_format_is_565(surf
->base
.format
) ?
131 VC4_RENDER_CONFIG_FORMAT_BGR565
:
132 VC4_RENDER_CONFIG_FORMAT_RGBA8888
,
133 VC4_RENDER_CONFIG_FORMAT
) |
134 VC4_SET_FIELD(surf
->tiling
, VC4_RENDER_CONFIG_MEMORY_FORMAT
);
140 * Submits the job to the kernel and then reinitializes it.
143 vc4_job_submit(struct vc4_context
*vc4
)
145 if (vc4_debug
& VC4_DEBUG_CL
) {
146 fprintf(stderr
, "BCL:\n");
147 vc4_dump_cl(vc4
->bcl
.base
, cl_offset(&vc4
->bcl
), false);
150 struct drm_vc4_submit_cl submit
;
151 memset(&submit
, 0, sizeof(submit
));
153 cl_ensure_space(&vc4
->bo_handles
, 4 * sizeof(uint32_t));
154 cl_ensure_space(&vc4
->bo_pointers
, 4 * sizeof(struct vc4_bo
*));
156 vc4_submit_setup_rcl_surface(vc4
, &submit
.color_read
,
157 vc4
->color_read
, false, false);
158 vc4_submit_setup_ms_rcl_surface(vc4
, &submit
.color_ms_write
,
160 vc4_submit_setup_rcl_surface(vc4
, &submit
.zs_read
,
161 vc4
->zs_read
, true, false);
162 vc4_submit_setup_rcl_surface(vc4
, &submit
.zs_write
,
163 vc4
->zs_write
, true, true);
165 submit
.bo_handles
= (uintptr_t)vc4
->bo_handles
.base
;
166 submit
.bo_handle_count
= cl_offset(&vc4
->bo_handles
) / 4;
167 submit
.bin_cl
= (uintptr_t)vc4
->bcl
.base
;
168 submit
.bin_cl_size
= cl_offset(&vc4
->bcl
);
169 submit
.shader_rec
= (uintptr_t)vc4
->shader_rec
.base
;
170 submit
.shader_rec_size
= cl_offset(&vc4
->shader_rec
);
171 submit
.shader_rec_count
= vc4
->shader_rec_count
;
172 submit
.uniforms
= (uintptr_t)vc4
->uniforms
.base
;
173 submit
.uniforms_size
= cl_offset(&vc4
->uniforms
);
175 assert(vc4
->draw_min_x
!= ~0 && vc4
->draw_min_y
!= ~0);
176 submit
.min_x_tile
= vc4
->draw_min_x
/ 64;
177 submit
.min_y_tile
= vc4
->draw_min_y
/ 64;
178 submit
.max_x_tile
= (vc4
->draw_max_x
- 1) / 64;
179 submit
.max_y_tile
= (vc4
->draw_max_y
- 1) / 64;
180 submit
.width
= vc4
->draw_width
;
181 submit
.height
= vc4
->draw_height
;
183 submit
.flags
|= VC4_SUBMIT_CL_USE_CLEAR_COLOR
;
184 submit
.clear_color
[0] = vc4
->clear_color
[0];
185 submit
.clear_color
[1] = vc4
->clear_color
[1];
186 submit
.clear_z
= vc4
->clear_depth
;
187 submit
.clear_s
= vc4
->clear_stencil
;
190 if (!(vc4_debug
& VC4_DEBUG_NORAST
)) {
193 #ifndef USE_VC4_SIMULATOR
194 ret
= drmIoctl(vc4
->fd
, DRM_IOCTL_VC4_SUBMIT_CL
, &submit
);
196 ret
= vc4_simulator_flush(vc4
, &submit
);
199 fprintf(stderr
, "VC4 submit failed\n");
204 vc4
->last_emit_seqno
= submit
.seqno
;
206 if (vc4_debug
& VC4_DEBUG_ALWAYS_SYNC
) {
207 if (!vc4_wait_seqno(vc4
->screen
, vc4
->last_emit_seqno
,
208 PIPE_TIMEOUT_INFINITE
, "sync")) {
209 fprintf(stderr
, "Wait failed.\n");