2 * Copyright (c) 2014 Scott Mansell
3 * Copyright © 2014 Broadcom
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:
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
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
27 #include "vc4_context.h"
28 #include "vc4_resource.h"
30 static struct vc4_bo
*
31 get_vbo(struct vc4_context
*vc4
, uint32_t width
, uint32_t height
)
41 return vc4_bo_alloc_mem(vc4
->screen
, verts
, sizeof(verts
), "verts");
43 static struct vc4_bo
*
44 get_ibo(struct vc4_context
*vc4
)
46 static const uint8_t indices
[] = { 0, 1, 2 };
48 return vc4_bo_alloc_mem(vc4
->screen
, indices
, sizeof(indices
), "indices");
52 vc4_rcl_tile_calls(struct vc4_context
*vc4
,
53 uint32_t xtiles
, uint32_t ytiles
,
54 struct vc4_bo
*tile_alloc
)
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
);
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);
67 if (x
== xtiles
- 1 && y
== ytiles
- 1) {
69 VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF
);
72 VC4_PACKET_STORE_MS_TILE_BUFFER
);
79 vc4_draw_vbo(struct pipe_context
*pctx
, const struct pipe_draw_info
*info
)
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
);
92 struct vc4_bo
*vbo
= get_vbo(vc4
, width
, height
);
93 static const uint32_t fs_uni
[] = { 0 };
95 fui(vc4
->framebuffer
.width
* 16.0f
/ 2.0f
),
96 fui(vc4
->framebuffer
.height
* 16.0f
/ 2.0f
),
99 fui(vc4
->framebuffer
.width
* 16.0f
/ 2.0f
),
100 fui(vc4
->framebuffer
.height
* 16.0f
/ 2.0f
),
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");
109 vc4
->needs_flush
= true;
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
);
122 cl_u8(&vc4
->bcl
, VC4_PACKET_START_TILE_BINNING
);
124 cl_u8(&vc4
->bcl
, VC4_PACKET_PRIMITIVE_LIST_FORMAT
);
125 cl_u8(&vc4
->bcl
, 0x12); // 16 bit triangle
127 vc4_emit_state(pctx
);
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 */
135 cl_u32(&vc4
->bcl
, simpenrose_hw_addr(vc4
->shader_rec
.next
) |
136 (nr_attributes
& 0x7));
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
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
);
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);
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);
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);
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 */
178 vc4
->shader_rec_count
++;
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);
186 struct vc4_surface
*csurf
= vc4_surface(vc4
->framebuffer
.cbufs
[0]);
187 struct vc4_resource
*ctex
= vc4_resource(csurf
->base
.texture
);
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
));
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
);
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
208 vc4_rcl_tile_calls(vc4
, tilew
, tileh
, tile_alloc
);
214 vc4_clear(struct pipe_context
*pctx
, unsigned buffers
,
215 const union pipe_color_union
*color
, double depth
, unsigned stencil
)
217 struct vc4_context
*vc4
= vc4_context(pctx
);
219 vc4
->needs_flush
= true;
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
)
227 fprintf(stderr
, "unimpl: clear RT\n");
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
)
235 fprintf(stderr
, "unimpl: clear DS\n");
239 vc4_draw_init(struct pipe_context
*pctx
)
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
;