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 "util/u_format.h"
28 #include "indices/u_primconvert.h"
30 #include "vc4_context.h"
31 #include "vc4_resource.h"
34 vc4_draw_vbo(struct pipe_context
*pctx
, const struct pipe_draw_info
*info
)
36 struct vc4_context
*vc4
= vc4_context(pctx
);
38 if (info
->mode
>= PIPE_PRIM_QUADS
) {
39 util_primconvert_save_index_buffer(vc4
->primconvert
, &vc4
->indexbuf
);
40 util_primconvert_save_rasterizer_state(vc4
->primconvert
, &vc4
->rasterizer
->base
);
41 util_primconvert_draw_vbo(vc4
->primconvert
, info
);
45 uint32_t width
= vc4
->framebuffer
.width
;
46 uint32_t height
= vc4
->framebuffer
.height
;
47 uint32_t tilew
= align(width
, 64) / 64;
48 uint32_t tileh
= align(height
, 64) / 64;
50 uint32_t tile_alloc_size
= 32 * tilew
* tileh
* 16;
51 uint32_t tile_state_size
= 48 * tilew
* tileh
;
52 if (!vc4
->tile_alloc
|| vc4
->tile_alloc
->size
< tile_alloc_size
) {
53 vc4_bo_unreference(&vc4
->tile_alloc
);
54 vc4
->tile_alloc
= vc4_bo_alloc(vc4
->screen
, tile_alloc_size
,
57 if (!vc4
->tile_state
|| vc4
->tile_state
->size
< tile_state_size
) {
58 vc4_bo_unreference(&vc4
->tile_state
);
59 vc4
->tile_state
= vc4_bo_alloc(vc4
->screen
, tile_state_size
,
63 vc4_update_compiled_shaders(vc4
);
65 vc4
->needs_flush
= true;
67 // Tile state data is 48 bytes per tile, I think it can be thrown away
68 // as soon as binning is finished.
69 cl_start_reloc(&vc4
->bcl
, 2);
70 cl_u8(&vc4
->bcl
, VC4_PACKET_TILE_BINNING_MODE_CONFIG
);
71 cl_reloc(vc4
, &vc4
->bcl
, vc4
->tile_alloc
, 0);
72 cl_u32(&vc4
->bcl
, vc4
->tile_alloc
->size
);
73 cl_reloc(vc4
, &vc4
->bcl
, vc4
->tile_state
, 0);
74 cl_u8(&vc4
->bcl
, tilew
);
75 cl_u8(&vc4
->bcl
, tileh
);
76 cl_u8(&vc4
->bcl
, VC4_BIN_CONFIG_AUTO_INIT_TSDA
);
78 cl_u8(&vc4
->bcl
, VC4_PACKET_START_TILE_BINNING
);
80 cl_u8(&vc4
->bcl
, VC4_PACKET_PRIMITIVE_LIST_FORMAT
);
81 cl_u8(&vc4
->bcl
, 0x12); // 16 bit triangle
85 /* the actual draw call. */
86 struct vc4_vertex_stateobj
*vtx
= vc4
->vtx
;
87 struct vc4_vertexbuf_stateobj
*vertexbuf
= &vc4
->vertexbuf
;
88 cl_u8(&vc4
->bcl
, VC4_PACKET_GL_SHADER_STATE
);
89 assert(vtx
->num_elements
<= 8);
90 /* Note that number of attributes == 0 in the packet means 8
91 * attributes. This field also contains the offset into shader_rec.
93 cl_u32(&vc4
->bcl
, vtx
->num_elements
& 0x7);
95 /* Note that the primitive type fields match with OpenGL/gallium
96 * definitions, up to but not including QUADS.
99 struct vc4_resource
*rsc
= vc4_resource(vc4
->indexbuf
.buffer
);
101 assert(vc4
->indexbuf
.index_size
== 1 ||
102 vc4
->indexbuf
.index_size
== 2);
104 cl_start_reloc(&vc4
->bcl
, 1);
105 cl_u8(&vc4
->bcl
, VC4_PACKET_GL_INDEXED_PRIMITIVE
);
108 (vc4
->indexbuf
.index_size
== 2 ?
109 VC4_INDEX_BUFFER_U16
:
110 VC4_INDEX_BUFFER_U8
));
111 cl_u32(&vc4
->bcl
, info
->count
);
112 cl_reloc(vc4
, &vc4
->bcl
, rsc
->bo
, vc4
->indexbuf
.offset
);
113 cl_u32(&vc4
->bcl
, info
->max_index
);
115 cl_u8(&vc4
->bcl
, VC4_PACKET_GL_ARRAY_PRIMITIVE
);
116 cl_u8(&vc4
->bcl
, info
->mode
);
117 cl_u32(&vc4
->bcl
, info
->count
);
118 cl_u32(&vc4
->bcl
, info
->start
);
123 vc4_write_uniforms(vc4
, vc4
->prog
.fs
,
124 &vc4
->constbuf
[PIPE_SHADER_FRAGMENT
],
127 vc4_write_uniforms(vc4
, vc4
->prog
.vs
,
128 &vc4
->constbuf
[PIPE_SHADER_VERTEX
],
131 vc4_write_uniforms(vc4
, vc4
->prog
.vs
,
132 &vc4
->constbuf
[PIPE_SHADER_VERTEX
],
136 cl_start_shader_reloc(&vc4
->shader_rec
, 3 + vtx
->num_elements
);
137 cl_u16(&vc4
->shader_rec
, VC4_SHADER_FLAG_ENABLE_CLIPPING
);
138 cl_u8(&vc4
->shader_rec
, 0); /* fs num uniforms (unused) */
139 cl_u8(&vc4
->shader_rec
, vc4
->prog
.fs
->num_inputs
);
140 cl_reloc(vc4
, &vc4
->shader_rec
, vc4
->prog
.fs
->bo
, 0);
141 cl_u32(&vc4
->shader_rec
, 0); /* UBO offset written by kernel */
143 cl_u16(&vc4
->shader_rec
, 0); /* vs num uniforms */
144 cl_u8(&vc4
->shader_rec
, (1 << vtx
->num_elements
) - 1); /* vs attribute array bitfield */
145 cl_u8(&vc4
->shader_rec
, 16 * vtx
->num_elements
); /* vs total attribute size */
146 cl_reloc(vc4
, &vc4
->shader_rec
, vc4
->prog
.vs
->bo
, 0);
147 cl_u32(&vc4
->shader_rec
, 0); /* UBO offset written by kernel */
149 cl_u16(&vc4
->shader_rec
, 0); /* cs num uniforms */
150 cl_u8(&vc4
->shader_rec
, (1 << vtx
->num_elements
) - 1); /* cs attribute array bitfield */
151 cl_u8(&vc4
->shader_rec
, 16 * vtx
->num_elements
); /* vs total attribute size */
152 cl_reloc(vc4
, &vc4
->shader_rec
, vc4
->prog
.vs
->bo
,
153 vc4
->prog
.vs
->coord_shader_offset
);
154 cl_u32(&vc4
->shader_rec
, 0); /* UBO offset written by kernel */
156 for (int i
= 0; i
< vtx
->num_elements
; i
++) {
157 struct pipe_vertex_element
*elem
= &vtx
->pipe
[i
];
158 struct pipe_vertex_buffer
*vb
=
159 &vertexbuf
->vb
[elem
->vertex_buffer_index
];
160 struct vc4_resource
*rsc
= vc4_resource(vb
->buffer
);
162 cl_reloc(vc4
, &vc4
->shader_rec
, rsc
->bo
,
163 vb
->buffer_offset
+ elem
->src_offset
);
164 cl_u8(&vc4
->shader_rec
,
165 util_format_get_blocksize(elem
->src_format
) - 1);
166 cl_u8(&vc4
->shader_rec
, vb
->stride
);
167 cl_u8(&vc4
->shader_rec
, i
* 16); /* VS VPM offset */
168 cl_u8(&vc4
->shader_rec
, i
* 16); /* CS VPM offset */
172 vc4
->shader_rec_count
++;
174 cl_u8(&vc4
->rcl
, VC4_PACKET_CLEAR_COLORS
);
175 cl_u32(&vc4
->rcl
, 0xff000000); // Opaque Black
176 cl_u32(&vc4
->rcl
, 0xff000000); // 32 bit clear colours need to be repeated twice
177 cl_u32(&vc4
->rcl
, 0);
180 struct vc4_surface
*csurf
= vc4_surface(vc4
->framebuffer
.cbufs
[0]);
181 struct vc4_resource
*ctex
= vc4_resource(csurf
->base
.texture
);
183 cl_start_reloc(&vc4
->rcl
, 1);
184 cl_u8(&vc4
->rcl
, VC4_PACKET_TILE_RENDERING_MODE_CONFIG
);
185 cl_reloc(vc4
, &vc4
->rcl
, ctex
->bo
, csurf
->offset
);
186 cl_u16(&vc4
->rcl
, width
);
187 cl_u16(&vc4
->rcl
, height
);
188 cl_u8(&vc4
->rcl
, (VC4_RENDER_CONFIG_MEMORY_FORMAT_LINEAR
|
189 VC4_RENDER_CONFIG_FORMAT_RGBA8888
));
192 // Do a store of the first tile to force the tile buffer to be cleared
193 /* XXX: I think these two packets may be unnecessary. */
195 cl_u8(&vc4
->rcl
, VC4_PACKET_TILE_COORDINATES
);
199 cl_u8(&vc4
->rcl
, VC4_PACKET_STORE_TILE_BUFFER_GENERAL
);
200 cl_u16(&vc4
->rcl
, 0); // Store nothing (just clear)
201 cl_u32(&vc4
->rcl
, 0); // no address is needed
208 vc4_clear(struct pipe_context
*pctx
, unsigned buffers
,
209 const union pipe_color_union
*color
, double depth
, unsigned stencil
)
211 struct vc4_context
*vc4
= vc4_context(pctx
);
213 vc4
->needs_flush
= true;
217 vc4_clear_render_target(struct pipe_context
*pctx
, struct pipe_surface
*ps
,
218 const union pipe_color_union
*color
,
219 unsigned x
, unsigned y
, unsigned w
, unsigned h
)
221 fprintf(stderr
, "unimpl: clear RT\n");
225 vc4_clear_depth_stencil(struct pipe_context
*pctx
, struct pipe_surface
*ps
,
226 unsigned buffers
, double depth
, unsigned stencil
,
227 unsigned x
, unsigned y
, unsigned w
, unsigned h
)
229 fprintf(stderr
, "unimpl: clear DS\n");
233 vc4_draw_init(struct pipe_context
*pctx
)
235 pctx
->draw_vbo
= vc4_draw_vbo
;
236 pctx
->clear
= vc4_clear
;
237 pctx
->clear_render_target
= vc4_clear_render_target
;
238 pctx
->clear_depth_stencil
= vc4_clear_depth_stencil
;