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
)
35 float z
, rhw
, r
, g
, b
;
39 (-(int)width
/ 3) << 4, // X in 12.4 fixed point
40 (-(int)height
/ 3) << 4, // Y in 12.4 fixed point
43 1.0f
, // Varying 0 (Red)
44 0.0f
, // Varying 1 (Green)
45 0.0f
, // Varying 2 (Blue)
48 // Vertex: bottom left, Green
49 (width
/ 3) << 4, // X in 12.4 fixed point
50 (-(int)height
/ 3) << 4, // Y in 12.4 fixed point
53 0.0f
, // Varying 0 (Red)
54 1.0f
, // Varying 1 (Green)
55 0.0f
, // Varying 2 (Blue)
59 // Vertex: bottom right, Blue
60 (width
/ 3) << 4, // X in 12.4 fixed point
61 (height
/ 3) << 4, // Y in 12.4 fixed point
64 0.0f
, // Varying 0 (Red)
65 0.0f
, // Varying 1 (Green)
66 1.0f
, // Varying 2 (Blue)
70 return vc4_bo_alloc_mem(vc4
->screen
, verts
, sizeof(verts
), "verts");
72 static struct vc4_bo
*
73 get_ibo(struct vc4_context
*vc4
)
75 static const uint8_t indices
[] = { 0, 1, 2 };
77 return vc4_bo_alloc_mem(vc4
->screen
, indices
, sizeof(indices
), "indices");
81 vc4_rcl_tile_calls(struct vc4_context
*vc4
,
82 uint32_t xtiles
, uint32_t ytiles
,
83 struct vc4_bo
*tile_alloc
)
85 for (int x
= 0; x
< xtiles
; x
++) {
86 for (int y
= 0; y
< ytiles
; y
++) {
87 cl_u8(&vc4
->rcl
, VC4_PACKET_TILE_COORDINATES
);
91 cl_start_reloc(&vc4
->rcl
, 1);
92 cl_u8(&vc4
->rcl
, VC4_PACKET_BRANCH_TO_SUB_LIST
);
93 cl_reloc(vc4
, &vc4
->rcl
, tile_alloc
,
94 (y
* xtiles
+ x
) * 32);
96 if (x
== xtiles
- 1 && y
== ytiles
- 1) {
98 VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF
);
101 VC4_PACKET_STORE_MS_TILE_BUFFER
);
108 vc4_draw_vbo(struct pipe_context
*pctx
, const struct pipe_draw_info
*info
)
110 struct vc4_context
*vc4
= vc4_context(pctx
);
111 uint32_t width
= vc4
->framebuffer
.width
;
112 uint32_t height
= vc4
->framebuffer
.height
;
113 uint32_t tilew
= align(width
, 64) / 64;
114 uint32_t tileh
= align(height
, 64) / 64;
115 struct vc4_bo
*tile_alloc
= vc4_bo_alloc(vc4
->screen
,
116 32 * tilew
* tileh
, "tilea");
117 struct vc4_bo
*tile_state
= vc4_bo_alloc(vc4
->screen
,
118 48 * tilew
* tileh
, "tilestate");
119 struct vc4_bo
*ibo
= get_ibo(vc4
);
121 struct vc4_bo
*fs_uniform
= vc4_bo_alloc(vc4
->screen
, 0x1000, "fsu");
122 struct vc4_bo
*vbo
= get_vbo(vc4
, width
, height
);
124 vc4
->needs_flush
= true;
126 // Tile state data is 48 bytes per tile, I think it can be thrown away
127 // as soon as binning is finished.
128 cl_start_reloc(&vc4
->bcl
, 2);
129 cl_u8(&vc4
->bcl
, VC4_PACKET_TILE_BINNING_MODE_CONFIG
);
130 cl_reloc(vc4
, &vc4
->bcl
, tile_alloc
, 0);
131 cl_u32(&vc4
->bcl
, 0x8000); /* tile allocation memory size */
132 cl_reloc(vc4
, &vc4
->bcl
, tile_state
, 0);
133 cl_u8(&vc4
->bcl
, tilew
);
134 cl_u8(&vc4
->bcl
, tileh
);
135 cl_u8(&vc4
->bcl
, VC4_BIN_CONFIG_AUTO_INIT_TSDA
);
137 cl_u8(&vc4
->bcl
, VC4_PACKET_START_TILE_BINNING
);
139 cl_u8(&vc4
->bcl
, VC4_PACKET_PRIMITIVE_LIST_FORMAT
);
140 cl_u8(&vc4
->bcl
, 0x32); // 16 bit triangle
142 vc4_emit_state(pctx
);
144 /* the actual draw call. */
145 cl_u8(&vc4
->bcl
, VC4_PACKET_NV_SHADER_STATE
);
146 #ifndef USE_VC4_SIMULATOR
147 cl_u32(&vc4
->bcl
, 0); /* offset into shader_rec */
149 cl_u32(&vc4
->bcl
, simpenrose_hw_addr(vc4
->shader_rec
.next
));
152 cl_start_reloc(&vc4
->bcl
, 1);
153 cl_u8(&vc4
->bcl
, VC4_PACKET_GL_INDEXED_PRIMITIVE
);
154 cl_u8(&vc4
->bcl
, 0x04); // 8bit index, trinagles
155 cl_u32(&vc4
->bcl
, 3); // Length
156 cl_reloc(vc4
, &vc4
->bcl
, ibo
, 0);
157 cl_u32(&vc4
->bcl
, 2); // Maximum index
159 cl_u8(&vc4
->bcl
, VC4_PACKET_FLUSH_ALL
);
160 cl_u8(&vc4
->bcl
, VC4_PACKET_NOP
);
161 cl_u8(&vc4
->bcl
, VC4_PACKET_HALT
);
164 cl_start_shader_reloc(&vc4
->shader_rec
, 3);
166 cl_u8(&vc4
->shader_rec
, 0);
167 cl_u8(&vc4
->shader_rec
, 6*4); // stride
168 cl_u8(&vc4
->shader_rec
, 0xcc); // num uniforms (not used)
169 cl_u8(&vc4
->shader_rec
, 3); // num varyings
170 cl_reloc(vc4
, &vc4
->shader_rec
, vc4
->prog
.fs
->bo
, 0);
171 cl_reloc(vc4
, &vc4
->shader_rec
, fs_uniform
, 0);
172 cl_reloc(vc4
, &vc4
->shader_rec
, vbo
, 0);
174 vc4
->shader_rec_count
++;
176 cl_u8(&vc4
->rcl
, VC4_PACKET_CLEAR_COLORS
);
177 cl_u32(&vc4
->rcl
, 0xff000000); // Opaque Black
178 cl_u32(&vc4
->rcl
, 0xff000000); // 32 bit clear colours need to be repeated twice
179 cl_u32(&vc4
->rcl
, 0);
182 struct vc4_surface
*csurf
= vc4_surface(vc4
->framebuffer
.cbufs
[0]);
183 struct vc4_resource
*ctex
= vc4_resource(csurf
->base
.texture
);
185 cl_start_reloc(&vc4
->rcl
, 1);
186 cl_u8(&vc4
->rcl
, VC4_PACKET_TILE_RENDERING_MODE_CONFIG
);
187 cl_reloc(vc4
, &vc4
->rcl
, ctex
->bo
, csurf
->offset
);
188 cl_u16(&vc4
->rcl
, width
);
189 cl_u16(&vc4
->rcl
, height
);
190 cl_u8(&vc4
->rcl
, (VC4_RENDER_CONFIG_MEMORY_FORMAT_LINEAR
|
191 VC4_RENDER_CONFIG_FORMAT_RGBA8888
));
194 // Do a store of the first tile to force the tile buffer to be cleared
195 /* XXX: I think these two packets may be unnecessary. */
196 cl_u8(&vc4
->rcl
, VC4_PACKET_TILE_COORDINATES
);
200 cl_u8(&vc4
->rcl
, VC4_PACKET_STORE_TILE_BUFFER_GENERAL
);
201 cl_u16(&vc4
->rcl
, 0); // Store nothing (just clear)
202 cl_u32(&vc4
->rcl
, 0); // no address is needed
204 vc4_rcl_tile_calls(vc4
, tilew
, tileh
, tile_alloc
);
210 vc4_clear(struct pipe_context
*pctx
, unsigned buffers
,
211 const union pipe_color_union
*color
, double depth
, unsigned stencil
)
213 struct vc4_context
*vc4
= vc4_context(pctx
);
215 vc4
->needs_flush
= true;
219 vc4_clear_render_target(struct pipe_context
*pctx
, struct pipe_surface
*ps
,
220 const union pipe_color_union
*color
,
221 unsigned x
, unsigned y
, unsigned w
, unsigned h
)
223 fprintf(stderr
, "unimpl: clear RT\n");
227 vc4_clear_depth_stencil(struct pipe_context
*pctx
, struct pipe_surface
*ps
,
228 unsigned buffers
, double depth
, unsigned stencil
,
229 unsigned x
, unsigned y
, unsigned w
, unsigned h
)
231 fprintf(stderr
, "unimpl: clear DS\n");
235 vc4_draw_init(struct pipe_context
*pctx
)
237 pctx
->draw_vbo
= vc4_draw_vbo
;
238 pctx
->clear
= vc4_clear
;
239 pctx
->clear_render_target
= vc4_clear_render_target
;
240 pctx
->clear_depth_stencil
= vc4_clear_depth_stencil
;