vc4: Start converting the driver to use vertex shaders.
[mesa.git] / src / gallium / drivers / vc4 / vc4_draw.c
1 /*
2 * Copyright (c) 2014 Scott Mansell
3 * Copyright © 2014 Broadcom
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 #include <stdio.h>
26
27 #include "vc4_context.h"
28 #include "vc4_resource.h"
29
30 static struct vc4_bo *
31 get_vbo(struct vc4_context *vc4, uint32_t width, uint32_t height)
32 {
33 struct {
34 float x, y, z, w;
35 } verts[] = {
36 { -1, -1, 1, 1 },
37 { 1, -1, 1, 1 },
38 { -1, 1, 1, 1 },
39 };
40
41 return vc4_bo_alloc_mem(vc4->screen, verts, sizeof(verts), "verts");
42 }
43 static struct vc4_bo *
44 get_ibo(struct vc4_context *vc4)
45 {
46 static const uint8_t indices[] = { 0, 1, 2 };
47
48 return vc4_bo_alloc_mem(vc4->screen, indices, sizeof(indices), "indices");
49 }
50
51 static void
52 vc4_rcl_tile_calls(struct vc4_context *vc4,
53 uint32_t xtiles, uint32_t ytiles,
54 struct vc4_bo *tile_alloc)
55 {
56 for (int x = 0; x < xtiles; x++) {
57 for (int y = 0; y < ytiles; y++) {
58 cl_u8(&vc4->rcl, VC4_PACKET_TILE_COORDINATES);
59 cl_u8(&vc4->rcl, x);
60 cl_u8(&vc4->rcl, y);
61
62 cl_start_reloc(&vc4->rcl, 1);
63 cl_u8(&vc4->rcl, VC4_PACKET_BRANCH_TO_SUB_LIST);
64 cl_reloc(vc4, &vc4->rcl, tile_alloc,
65 (y * xtiles + x) * 32);
66
67 if (x == xtiles - 1 && y == ytiles - 1) {
68 cl_u8(&vc4->rcl,
69 VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF);
70 } else {
71 cl_u8(&vc4->rcl,
72 VC4_PACKET_STORE_MS_TILE_BUFFER);
73 }
74 }
75 }
76 }
77
78 static void
79 vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
80 {
81 struct vc4_context *vc4 = vc4_context(pctx);
82 uint32_t width = vc4->framebuffer.width;
83 uint32_t height = vc4->framebuffer.height;
84 uint32_t tilew = align(width, 64) / 64;
85 uint32_t tileh = align(height, 64) / 64;
86 struct vc4_bo *tile_alloc = vc4_bo_alloc(vc4->screen,
87 32 * tilew * tileh, "tilea");
88 struct vc4_bo *tile_state = vc4_bo_alloc(vc4->screen,
89 48 * tilew * tileh, "tilestate");
90 struct vc4_bo *ibo = get_ibo(vc4);
91
92 struct vc4_bo *vbo = get_vbo(vc4, width, height);
93 static const uint32_t fs_uni[] = { 0 };
94 uint32_t vs_uni[] = {
95 fui(vc4->framebuffer.width * 16.0f / 2.0f),
96 fui(vc4->framebuffer.height * 16.0f / 2.0f),
97 };
98 uint32_t cs_uni[] = {
99 fui(vc4->framebuffer.width * 16.0f / 2.0f),
100 fui(vc4->framebuffer.height * 16.0f / 2.0f),
101 };
102 struct vc4_bo *fs_ubo = vc4_bo_alloc_mem(vc4->screen, fs_uni,
103 sizeof(fs_uni), "fs_ubo");
104 struct vc4_bo *vs_ubo = vc4_bo_alloc_mem(vc4->screen, vs_uni,
105 sizeof(vs_uni), "vs_ubo");
106 struct vc4_bo *cs_ubo = vc4_bo_alloc_mem(vc4->screen, cs_uni,
107 sizeof(cs_uni), "cs_ubo");
108
109 vc4->needs_flush = true;
110
111 // Tile state data is 48 bytes per tile, I think it can be thrown away
112 // as soon as binning is finished.
113 cl_start_reloc(&vc4->bcl, 2);
114 cl_u8(&vc4->bcl, VC4_PACKET_TILE_BINNING_MODE_CONFIG);
115 cl_reloc(vc4, &vc4->bcl, tile_alloc, 0);
116 cl_u32(&vc4->bcl, 0x8000); /* tile allocation memory size */
117 cl_reloc(vc4, &vc4->bcl, tile_state, 0);
118 cl_u8(&vc4->bcl, tilew);
119 cl_u8(&vc4->bcl, tileh);
120 cl_u8(&vc4->bcl, VC4_BIN_CONFIG_AUTO_INIT_TSDA);
121
122 cl_u8(&vc4->bcl, VC4_PACKET_START_TILE_BINNING);
123
124 cl_u8(&vc4->bcl, VC4_PACKET_PRIMITIVE_LIST_FORMAT);
125 cl_u8(&vc4->bcl, 0x12); // 16 bit triangle
126
127 vc4_emit_state(pctx);
128
129 /* the actual draw call. */
130 uint32_t nr_attributes = 1;
131 cl_u8(&vc4->bcl, VC4_PACKET_GL_SHADER_STATE);
132 #ifndef USE_VC4_SIMULATOR
133 cl_u32(&vc4->bcl, nr_attributes & 0x7); /* offset into shader_rec */
134 #else
135 cl_u32(&vc4->bcl, simpenrose_hw_addr(vc4->shader_rec.next) |
136 (nr_attributes & 0x7));
137 #endif
138
139 cl_start_reloc(&vc4->bcl, 1);
140 cl_u8(&vc4->bcl, VC4_PACKET_GL_INDEXED_PRIMITIVE);
141 cl_u8(&vc4->bcl, 0x04); // 8bit index, trinagles
142 cl_u32(&vc4->bcl, 3); // Length
143 cl_reloc(vc4, &vc4->bcl, ibo, 0);
144 cl_u32(&vc4->bcl, 2); // Maximum index
145
146 cl_u8(&vc4->bcl, VC4_PACKET_FLUSH_ALL);
147 cl_u8(&vc4->bcl, VC4_PACKET_NOP);
148 cl_u8(&vc4->bcl, VC4_PACKET_HALT);
149
150 // Shader Record
151
152 cl_start_shader_reloc(&vc4->shader_rec, 7);
153 cl_u16(&vc4->shader_rec, VC4_SHADER_FLAG_ENABLE_CLIPPING);
154 cl_u8(&vc4->shader_rec, 0); /* fs num uniforms (unused) */
155 cl_u8(&vc4->shader_rec, 0); /* fs num varyings */
156 cl_reloc(vc4, &vc4->shader_rec, vc4->prog.fs->bo, 0);
157 cl_reloc(vc4, &vc4->shader_rec, fs_ubo, 0);
158
159 cl_u16(&vc4->shader_rec, 0); /* vs num uniforms */
160 cl_u8(&vc4->shader_rec, 1); /* vs attribute array bitfield */
161 cl_u8(&vc4->shader_rec, 16); /* vs total attribute size */
162 cl_reloc(vc4, &vc4->shader_rec, vc4->prog.vs->bo, 0);
163 cl_reloc(vc4, &vc4->shader_rec, vs_ubo, 0);
164
165 cl_u16(&vc4->shader_rec, 0); /* cs num uniforms */
166 cl_u8(&vc4->shader_rec, 1); /* cs attribute array bitfield */
167 cl_u8(&vc4->shader_rec, 16); /* vs total attribute size */
168 cl_reloc(vc4, &vc4->shader_rec, vc4->prog.vs->bo,
169 vc4->prog.vs->coord_shader_offset);
170 cl_reloc(vc4, &vc4->shader_rec, cs_ubo, 0);
171
172 cl_reloc(vc4, &vc4->shader_rec, vbo, 0);
173 cl_u8(&vc4->shader_rec, 15); /* bytes - 1 in the attribute*/
174 cl_u8(&vc4->shader_rec, 16); /* attribute stride */
175 cl_u8(&vc4->shader_rec, 0); /* VS VPM offset */
176 cl_u8(&vc4->shader_rec, 0); /* CS VPM offset */
177
178 vc4->shader_rec_count++;
179
180 cl_u8(&vc4->rcl, VC4_PACKET_CLEAR_COLORS);
181 cl_u32(&vc4->rcl, 0xff000000); // Opaque Black
182 cl_u32(&vc4->rcl, 0xff000000); // 32 bit clear colours need to be repeated twice
183 cl_u32(&vc4->rcl, 0);
184 cl_u8(&vc4->rcl, 0);
185
186 struct vc4_surface *csurf = vc4_surface(vc4->framebuffer.cbufs[0]);
187 struct vc4_resource *ctex = vc4_resource(csurf->base.texture);
188
189 cl_start_reloc(&vc4->rcl, 1);
190 cl_u8(&vc4->rcl, VC4_PACKET_TILE_RENDERING_MODE_CONFIG);
191 cl_reloc(vc4, &vc4->rcl, ctex->bo, csurf->offset);
192 cl_u16(&vc4->rcl, width);
193 cl_u16(&vc4->rcl, height);
194 cl_u8(&vc4->rcl, (VC4_RENDER_CONFIG_MEMORY_FORMAT_LINEAR |
195 VC4_RENDER_CONFIG_FORMAT_RGBA8888));
196 cl_u8(&vc4->rcl, 0);
197
198 // Do a store of the first tile to force the tile buffer to be cleared
199 /* XXX: I think these two packets may be unnecessary. */
200 cl_u8(&vc4->rcl, VC4_PACKET_TILE_COORDINATES);
201 cl_u8(&vc4->rcl, 0);
202 cl_u8(&vc4->rcl, 0);
203
204 cl_u8(&vc4->rcl, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
205 cl_u16(&vc4->rcl, 0); // Store nothing (just clear)
206 cl_u32(&vc4->rcl, 0); // no address is needed
207
208 vc4_rcl_tile_calls(vc4, tilew, tileh, tile_alloc);
209
210 vc4_flush(pctx);
211 }
212
213 static void
214 vc4_clear(struct pipe_context *pctx, unsigned buffers,
215 const union pipe_color_union *color, double depth, unsigned stencil)
216 {
217 struct vc4_context *vc4 = vc4_context(pctx);
218
219 vc4->needs_flush = true;
220 }
221
222 static void
223 vc4_clear_render_target(struct pipe_context *pctx, struct pipe_surface *ps,
224 const union pipe_color_union *color,
225 unsigned x, unsigned y, unsigned w, unsigned h)
226 {
227 fprintf(stderr, "unimpl: clear RT\n");
228 }
229
230 static void
231 vc4_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *ps,
232 unsigned buffers, double depth, unsigned stencil,
233 unsigned x, unsigned y, unsigned w, unsigned h)
234 {
235 fprintf(stderr, "unimpl: clear DS\n");
236 }
237
238 void
239 vc4_draw_init(struct pipe_context *pctx)
240 {
241 pctx->draw_vbo = vc4_draw_vbo;
242 pctx->clear = vc4_clear;
243 pctx->clear_render_target = vc4_clear_render_target;
244 pctx->clear_depth_stencil = vc4_clear_depth_stencil;
245 }