vc4: Switch to actually generating vertex and fragment shader code from TGSI.
[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
94 vc4->needs_flush = true;
95
96 // Tile state data is 48 bytes per tile, I think it can be thrown away
97 // as soon as binning is finished.
98 cl_start_reloc(&vc4->bcl, 2);
99 cl_u8(&vc4->bcl, VC4_PACKET_TILE_BINNING_MODE_CONFIG);
100 cl_reloc(vc4, &vc4->bcl, tile_alloc, 0);
101 cl_u32(&vc4->bcl, 0x8000); /* tile allocation memory size */
102 cl_reloc(vc4, &vc4->bcl, tile_state, 0);
103 cl_u8(&vc4->bcl, tilew);
104 cl_u8(&vc4->bcl, tileh);
105 cl_u8(&vc4->bcl, VC4_BIN_CONFIG_AUTO_INIT_TSDA);
106
107 cl_u8(&vc4->bcl, VC4_PACKET_START_TILE_BINNING);
108
109 cl_u8(&vc4->bcl, VC4_PACKET_PRIMITIVE_LIST_FORMAT);
110 cl_u8(&vc4->bcl, 0x12); // 16 bit triangle
111
112 vc4_emit_state(pctx);
113
114 /* the actual draw call. */
115 uint32_t nr_attributes = 1;
116 cl_u8(&vc4->bcl, VC4_PACKET_GL_SHADER_STATE);
117 #ifndef USE_VC4_SIMULATOR
118 cl_u32(&vc4->bcl, nr_attributes & 0x7); /* offset into shader_rec */
119 #else
120 cl_u32(&vc4->bcl, simpenrose_hw_addr(vc4->shader_rec.next) |
121 (nr_attributes & 0x7));
122 #endif
123
124 cl_start_reloc(&vc4->bcl, 1);
125 cl_u8(&vc4->bcl, VC4_PACKET_GL_INDEXED_PRIMITIVE);
126 cl_u8(&vc4->bcl, 0x04); // 8bit index, trinagles
127 cl_u32(&vc4->bcl, 3); // Length
128 cl_reloc(vc4, &vc4->bcl, ibo, 0);
129 cl_u32(&vc4->bcl, 2); // Maximum index
130
131 cl_u8(&vc4->bcl, VC4_PACKET_FLUSH_ALL);
132 cl_u8(&vc4->bcl, VC4_PACKET_NOP);
133 cl_u8(&vc4->bcl, VC4_PACKET_HALT);
134
135 // Shader Record
136
137 struct vc4_bo *fs_ubo, *vs_ubo, *cs_ubo;
138 uint32_t fs_ubo_offset, vs_ubo_offset, cs_ubo_offset;
139 vc4_get_uniform_bo(vc4, vc4->prog.fs,
140 &vc4->constbuf[PIPE_SHADER_FRAGMENT],
141 0, &fs_ubo, &fs_ubo_offset);
142 vc4_get_uniform_bo(vc4, vc4->prog.vs,
143 &vc4->constbuf[PIPE_SHADER_VERTEX],
144 0, &vs_ubo, &vs_ubo_offset);
145 vc4_get_uniform_bo(vc4, vc4->prog.vs,
146 &vc4->constbuf[PIPE_SHADER_VERTEX],
147 1, &cs_ubo, &cs_ubo_offset);
148
149 cl_start_shader_reloc(&vc4->shader_rec, 7);
150 cl_u16(&vc4->shader_rec, VC4_SHADER_FLAG_ENABLE_CLIPPING);
151 cl_u8(&vc4->shader_rec, 0); /* fs num uniforms (unused) */
152 cl_u8(&vc4->shader_rec, 0); /* fs num varyings */
153 cl_reloc(vc4, &vc4->shader_rec, vc4->prog.fs->bo, 0);
154 cl_reloc(vc4, &vc4->shader_rec, fs_ubo, fs_ubo_offset);
155
156 cl_u16(&vc4->shader_rec, 0); /* vs num uniforms */
157 cl_u8(&vc4->shader_rec, 1); /* vs attribute array bitfield */
158 cl_u8(&vc4->shader_rec, 16); /* vs total attribute size */
159 cl_reloc(vc4, &vc4->shader_rec, vc4->prog.vs->bo, 0);
160 cl_reloc(vc4, &vc4->shader_rec, vs_ubo, vs_ubo_offset);
161
162 cl_u16(&vc4->shader_rec, 0); /* cs num uniforms */
163 cl_u8(&vc4->shader_rec, 1); /* cs attribute array bitfield */
164 cl_u8(&vc4->shader_rec, 16); /* vs total attribute size */
165 cl_reloc(vc4, &vc4->shader_rec, vc4->prog.vs->bo,
166 vc4->prog.vs->coord_shader_offset);
167 cl_reloc(vc4, &vc4->shader_rec, cs_ubo, cs_ubo_offset);
168
169 cl_reloc(vc4, &vc4->shader_rec, vbo, 0);
170 cl_u8(&vc4->shader_rec, 15); /* bytes - 1 in the attribute*/
171 cl_u8(&vc4->shader_rec, 16); /* attribute stride */
172 cl_u8(&vc4->shader_rec, 0); /* VS VPM offset */
173 cl_u8(&vc4->shader_rec, 0); /* CS VPM offset */
174
175 vc4->shader_rec_count++;
176
177 cl_u8(&vc4->rcl, VC4_PACKET_CLEAR_COLORS);
178 cl_u32(&vc4->rcl, 0xff000000); // Opaque Black
179 cl_u32(&vc4->rcl, 0xff000000); // 32 bit clear colours need to be repeated twice
180 cl_u32(&vc4->rcl, 0);
181 cl_u8(&vc4->rcl, 0);
182
183 struct vc4_surface *csurf = vc4_surface(vc4->framebuffer.cbufs[0]);
184 struct vc4_resource *ctex = vc4_resource(csurf->base.texture);
185
186 cl_start_reloc(&vc4->rcl, 1);
187 cl_u8(&vc4->rcl, VC4_PACKET_TILE_RENDERING_MODE_CONFIG);
188 cl_reloc(vc4, &vc4->rcl, ctex->bo, csurf->offset);
189 cl_u16(&vc4->rcl, width);
190 cl_u16(&vc4->rcl, height);
191 cl_u8(&vc4->rcl, (VC4_RENDER_CONFIG_MEMORY_FORMAT_LINEAR |
192 VC4_RENDER_CONFIG_FORMAT_RGBA8888));
193 cl_u8(&vc4->rcl, 0);
194
195 // Do a store of the first tile to force the tile buffer to be cleared
196 /* XXX: I think these two packets may be unnecessary. */
197 cl_u8(&vc4->rcl, VC4_PACKET_TILE_COORDINATES);
198 cl_u8(&vc4->rcl, 0);
199 cl_u8(&vc4->rcl, 0);
200
201 cl_u8(&vc4->rcl, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
202 cl_u16(&vc4->rcl, 0); // Store nothing (just clear)
203 cl_u32(&vc4->rcl, 0); // no address is needed
204
205 vc4_rcl_tile_calls(vc4, tilew, tileh, tile_alloc);
206
207 vc4_flush(pctx);
208 }
209
210 static void
211 vc4_clear(struct pipe_context *pctx, unsigned buffers,
212 const union pipe_color_union *color, double depth, unsigned stencil)
213 {
214 struct vc4_context *vc4 = vc4_context(pctx);
215
216 vc4->needs_flush = true;
217 }
218
219 static void
220 vc4_clear_render_target(struct pipe_context *pctx, struct pipe_surface *ps,
221 const union pipe_color_union *color,
222 unsigned x, unsigned y, unsigned w, unsigned h)
223 {
224 fprintf(stderr, "unimpl: clear RT\n");
225 }
226
227 static void
228 vc4_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *ps,
229 unsigned buffers, double depth, unsigned stencil,
230 unsigned x, unsigned y, unsigned w, unsigned h)
231 {
232 fprintf(stderr, "unimpl: clear DS\n");
233 }
234
235 void
236 vc4_draw_init(struct pipe_context *pctx)
237 {
238 pctx->draw_vbo = vc4_draw_vbo;
239 pctx->clear = vc4_clear;
240 pctx->clear_render_target = vc4_clear_render_target;
241 pctx->clear_depth_stencil = vc4_clear_depth_stencil;
242 }