• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 Rob Clark <robclark@freedesktop.org>
3  * Copyright © 2018 Google, Inc.
4  * SPDX-License-Identifier: MIT
5  *
6  * Authors:
7  *    Rob Clark <robclark@freedesktop.org>
8  */
9 
10 #define FD_BO_NO_HARDPIN 1
11 
12 #include "freedreno_query_acc.h"
13 #include "freedreno_state.h"
14 
15 #include "fd6_barrier.h"
16 #include "fd6_blend.h"
17 #include "fd6_blitter.h"
18 #include "fd6_compute.h"
19 #include "fd6_context.h"
20 #include "fd6_draw.h"
21 #include "fd6_emit.h"
22 #include "fd6_gmem.h"
23 #include "fd6_image.h"
24 #include "fd6_pack.h"
25 #include "fd6_program.h"
26 #include "fd6_query.h"
27 #include "fd6_rasterizer.h"
28 #include "fd6_resource.h"
29 #include "fd6_texture.h"
30 #include "fd6_zsa.h"
31 
32 static void
fd6_context_destroy(struct pipe_context * pctx)33 fd6_context_destroy(struct pipe_context *pctx) in_dt
34 {
35    struct fd6_context *fd6_ctx = fd6_context(fd_context(pctx));
36 
37    fd6_descriptor_set_invalidate(&fd6_ctx->cs_descriptor_set);
38    for (unsigned i = 0; i < ARRAY_SIZE(fd6_ctx->descriptor_sets); i++)
39       fd6_descriptor_set_invalidate(&fd6_ctx->descriptor_sets[i]);
40 
41    if (fd6_ctx->streamout_disable_stateobj)
42       fd_ringbuffer_del(fd6_ctx->streamout_disable_stateobj);
43 
44    if (fd6_ctx->sample_locations_disable_stateobj)
45       fd_ringbuffer_del(fd6_ctx->sample_locations_disable_stateobj);
46 
47    if (fd6_ctx->preamble)
48       fd_ringbuffer_del(fd6_ctx->preamble);
49 
50    if (fd6_ctx->restore)
51       fd_ringbuffer_del(fd6_ctx->restore);
52 
53    fd_context_destroy(pctx);
54 
55    if (fd6_ctx->vsc_draw_strm)
56       fd_bo_del(fd6_ctx->vsc_draw_strm);
57    if (fd6_ctx->vsc_prim_strm)
58       fd_bo_del(fd6_ctx->vsc_prim_strm);
59    fd_bo_del(fd6_ctx->control_mem);
60 
61    fd_context_cleanup_common_vbos(&fd6_ctx->base);
62 
63    fd6_texture_fini(pctx);
64 
65    free(fd6_ctx);
66 }
67 
68 static void *
fd6_vertex_state_create(struct pipe_context * pctx,unsigned num_elements,const struct pipe_vertex_element * elements)69 fd6_vertex_state_create(struct pipe_context *pctx, unsigned num_elements,
70                         const struct pipe_vertex_element *elements)
71 {
72    struct fd_context *ctx = fd_context(pctx);
73 
74    struct fd6_vertex_stateobj *state = CALLOC_STRUCT(fd6_vertex_stateobj);
75    memcpy(state->base.pipe, elements, sizeof(*elements) * num_elements);
76    state->base.num_elements = num_elements;
77    state->stateobj =
78       fd_ringbuffer_new_object(ctx->pipe, 4 * (num_elements * 4 + 1));
79    struct fd_ringbuffer *ring = state->stateobj;
80 
81    OUT_PKT4(ring, REG_A6XX_VFD_DECODE(0), 2 * num_elements);
82    for (int32_t i = 0; i < num_elements; i++) {
83       const struct pipe_vertex_element *elem = &elements[i];
84       enum pipe_format pfmt = (enum pipe_format)elem->src_format;
85       enum a6xx_format fmt = fd6_vertex_format(pfmt);
86       bool isint = util_format_is_pure_integer(pfmt);
87       assert(fmt != FMT6_NONE);
88 
89       OUT_RING(ring, A6XX_VFD_DECODE_INSTR_IDX(elem->vertex_buffer_index) |
90                         A6XX_VFD_DECODE_INSTR_OFFSET(elem->src_offset) |
91                         A6XX_VFD_DECODE_INSTR_FORMAT(fmt) |
92                         COND(elem->instance_divisor,
93                              A6XX_VFD_DECODE_INSTR_INSTANCED) |
94                         A6XX_VFD_DECODE_INSTR_SWAP(fd6_vertex_swap(pfmt)) |
95                         A6XX_VFD_DECODE_INSTR_UNK30 |
96                         COND(!isint, A6XX_VFD_DECODE_INSTR_FLOAT));
97       OUT_RING(ring,
98                MAX2(1, elem->instance_divisor)); /* VFD_DECODE[j].STEP_RATE */
99    }
100 
101    for (int32_t i = 0; i < num_elements; i++) {
102       const struct pipe_vertex_element *elem = &elements[i];
103 
104       OUT_PKT4(ring, REG_A6XX_VFD_FETCH_STRIDE(elem->vertex_buffer_index), 1);
105       OUT_RING(ring, elem->src_stride);
106    }
107 
108    return state;
109 }
110 
111 static void
fd6_vertex_state_delete(struct pipe_context * pctx,void * hwcso)112 fd6_vertex_state_delete(struct pipe_context *pctx, void *hwcso)
113 {
114    struct fd6_vertex_stateobj *so = (struct fd6_vertex_stateobj *)hwcso;
115 
116    fd_ringbuffer_del(so->stateobj);
117    FREE(hwcso);
118 }
119 
120 static void
validate_surface(struct pipe_context * pctx,struct pipe_surface * psurf)121 validate_surface(struct pipe_context *pctx, struct pipe_surface *psurf)
122    assert_dt
123 {
124    fd6_validate_format(fd_context(pctx), fd_resource(psurf->texture),
125                        psurf->format);
126 }
127 
128 static void
fd6_set_framebuffer_state(struct pipe_context * pctx,const struct pipe_framebuffer_state * pfb)129 fd6_set_framebuffer_state(struct pipe_context *pctx,
130                           const struct pipe_framebuffer_state *pfb)
131    in_dt
132 {
133    if (pfb->zsbuf)
134       validate_surface(pctx, pfb->zsbuf);
135 
136    for (unsigned i = 0; i < pfb->nr_cbufs; i++) {
137       if (!pfb->cbufs[i])
138          continue;
139       validate_surface(pctx, pfb->cbufs[i]);
140    }
141 
142    fd_set_framebuffer_state(pctx, pfb);
143 }
144 
145 
146 static void
setup_state_map(struct fd_context * ctx)147 setup_state_map(struct fd_context *ctx)
148 {
149    STATIC_ASSERT(FD6_GROUP_NON_GROUP < 32);
150 
151    fd_context_add_map(ctx, FD_DIRTY_VTXSTATE, BIT(FD6_GROUP_VTXSTATE));
152    fd_context_add_map(ctx, FD_DIRTY_VTXBUF, BIT(FD6_GROUP_VBO));
153    fd_context_add_map(ctx, FD_DIRTY_ZSA | FD_DIRTY_RASTERIZER,
154                       BIT(FD6_GROUP_ZSA));
155    fd_context_add_map(ctx, FD_DIRTY_ZSA | FD_DIRTY_BLEND | FD_DIRTY_PROG,
156                       BIT(FD6_GROUP_LRZ));
157    fd_context_add_map(ctx, FD_DIRTY_PROG | FD_DIRTY_RASTERIZER_CLIP_PLANE_ENABLE,
158                       BIT(FD6_GROUP_PROG) | BIT(FD6_GROUP_PROG_KEY));
159    fd_context_add_map(ctx, FD_DIRTY_RASTERIZER | FD_DIRTY_MIN_SAMPLES | FD_DIRTY_FRAMEBUFFER,
160                       BIT(FD6_GROUP_PROG_KEY));
161    if (ctx->screen->driconf.dual_color_blend_by_location) {
162       fd_context_add_map(ctx, FD_DIRTY_BLEND_DUAL,
163                          BIT(FD6_GROUP_PROG_KEY));
164    }
165    fd_context_add_map(ctx, FD_DIRTY_RASTERIZER, BIT(FD6_GROUP_RASTERIZER));
166    fd_context_add_map(ctx,
167                       FD_DIRTY_FRAMEBUFFER | FD_DIRTY_RASTERIZER_DISCARD |
168                          FD_DIRTY_PROG | FD_DIRTY_BLEND_DUAL,
169                       BIT(FD6_GROUP_PROG_FB_RAST));
170    fd_context_add_map(ctx, FD_DIRTY_BLEND | FD_DIRTY_SAMPLE_MASK,
171                       BIT(FD6_GROUP_BLEND));
172    fd_context_add_map(ctx, FD_DIRTY_SAMPLE_LOCATIONS, BIT(FD6_GROUP_SAMPLE_LOCATIONS));
173    fd_context_add_map(ctx, FD_DIRTY_BLEND_COLOR, BIT(FD6_GROUP_BLEND_COLOR));
174    fd_context_add_map(ctx, FD_DIRTY_PROG | FD_DIRTY_CONST,
175                       BIT(FD6_GROUP_CONST));
176    fd_context_add_map(ctx, FD_DIRTY_STREAMOUT, BIT(FD6_GROUP_SO));
177    fd_context_add_map(ctx, FD_DIRTY_BLEND_COHERENT,
178       BIT(FD6_GROUP_PRIM_MODE_SYSMEM) | BIT(FD6_GROUP_PRIM_MODE_GMEM));
179 
180    fd_context_add_shader_map(ctx, PIPE_SHADER_VERTEX, FD_DIRTY_SHADER_TEX,
181                              BIT(FD6_GROUP_VS_TEX));
182    fd_context_add_shader_map(ctx, PIPE_SHADER_TESS_CTRL, FD_DIRTY_SHADER_TEX,
183                              BIT(FD6_GROUP_HS_TEX));
184    fd_context_add_shader_map(ctx, PIPE_SHADER_TESS_EVAL, FD_DIRTY_SHADER_TEX,
185                              BIT(FD6_GROUP_DS_TEX));
186    fd_context_add_shader_map(ctx, PIPE_SHADER_GEOMETRY, FD_DIRTY_SHADER_TEX,
187                              BIT(FD6_GROUP_GS_TEX));
188    fd_context_add_shader_map(ctx, PIPE_SHADER_FRAGMENT, FD_DIRTY_SHADER_TEX,
189                              BIT(FD6_GROUP_FS_TEX));
190    fd_context_add_shader_map(ctx, PIPE_SHADER_COMPUTE, FD_DIRTY_SHADER_TEX,
191                              BIT(FD6_GROUP_CS_TEX));
192 
193    fd_context_add_shader_map(ctx, PIPE_SHADER_VERTEX,
194                              FD_DIRTY_SHADER_SSBO | FD_DIRTY_SHADER_IMAGE,
195                              BIT(FD6_GROUP_VS_BINDLESS));
196    fd_context_add_shader_map(ctx, PIPE_SHADER_TESS_CTRL,
197                              FD_DIRTY_SHADER_SSBO | FD_DIRTY_SHADER_IMAGE,
198                              BIT(FD6_GROUP_HS_BINDLESS));
199    fd_context_add_shader_map(ctx, PIPE_SHADER_TESS_EVAL,
200                              FD_DIRTY_SHADER_SSBO | FD_DIRTY_SHADER_IMAGE,
201                              BIT(FD6_GROUP_DS_BINDLESS));
202    fd_context_add_shader_map(ctx, PIPE_SHADER_GEOMETRY,
203                              FD_DIRTY_SHADER_SSBO | FD_DIRTY_SHADER_IMAGE,
204                              BIT(FD6_GROUP_GS_BINDLESS));
205    /* NOTE: FD6_GROUP_FS_BINDLESS has a weak dependency on the program
206     * state (ie. it needs to be re-generated with fb-read descriptor
207     * patched in) but this special case is handled in fd6_emit_3d_state()
208     */
209    fd_context_add_shader_map(ctx, PIPE_SHADER_FRAGMENT,
210                              FD_DIRTY_SHADER_SSBO | FD_DIRTY_SHADER_IMAGE,
211                              BIT(FD6_GROUP_FS_BINDLESS));
212    fd_context_add_shader_map(ctx, PIPE_SHADER_COMPUTE,
213                              FD_DIRTY_SHADER_SSBO | FD_DIRTY_SHADER_IMAGE,
214                              BIT(FD6_GROUP_CS_BINDLESS));
215    fd_context_add_shader_map(ctx, PIPE_SHADER_FRAGMENT,
216                              FD_DIRTY_SHADER_PROG,
217                              BIT(FD6_GROUP_PRIM_MODE_SYSMEM) | BIT(FD6_GROUP_PRIM_MODE_GMEM));
218 
219    /* NOTE: scissor enabled bit is part of rasterizer state, but
220     * fd_rasterizer_state_bind() will mark scissor dirty if needed:
221     */
222    fd_context_add_map(ctx, FD_DIRTY_SCISSOR | FD_DIRTY_PROG,
223                       BIT(FD6_GROUP_SCISSOR));
224 
225    /* Stuff still emit in IB2
226     *
227     * NOTE: viewport state doesn't seem to change frequently, so possibly
228     * move it into FD6_GROUP_RASTERIZER?
229     */
230    fd_context_add_map(
231       ctx, FD_DIRTY_STENCIL_REF | FD_DIRTY_VIEWPORT | FD_DIRTY_RASTERIZER | FD_DIRTY_PROG,
232       BIT(FD6_GROUP_NON_GROUP));
233 }
234 
235 template <chip CHIP>
236 struct pipe_context *
fd6_context_create(struct pipe_screen * pscreen,void * priv,unsigned flags)237 fd6_context_create(struct pipe_screen *pscreen, void *priv,
238                    unsigned flags) disable_thread_safety_analysis
239 {
240    struct fd_screen *screen = fd_screen(pscreen);
241    struct fd6_context *fd6_ctx = CALLOC_STRUCT(fd6_context);
242    struct pipe_context *pctx;
243 
244    if (!fd6_ctx)
245       return NULL;
246 
247    pctx = &fd6_ctx->base.base;
248    pctx->screen = pscreen;
249 
250    fd6_ctx->base.flags = flags;
251    fd6_ctx->base.dev = fd_device_ref(screen->dev);
252    fd6_ctx->base.screen = fd_screen(pscreen);
253    fd6_ctx->base.last.key = &fd6_ctx->last_key;
254 
255    pctx->destroy = fd6_context_destroy;
256    pctx->create_blend_state = fd6_blend_state_create;
257    pctx->create_rasterizer_state = fd6_rasterizer_state_create;
258    pctx->create_depth_stencil_alpha_state = fd6_zsa_state_create<CHIP>;
259    pctx->create_vertex_elements_state = fd6_vertex_state_create;
260 
261    fd6_draw_init<CHIP>(pctx);
262    fd6_compute_init<CHIP>(pctx);
263    fd6_gmem_init<CHIP>(pctx);
264    fd6_texture_init(pctx);
265    fd6_prog_init<CHIP>(pctx);
266    fd6_query_context_init<CHIP>(pctx);
267 
268    setup_state_map(&fd6_ctx->base);
269 
270    pctx = fd_context_init(&fd6_ctx->base, pscreen, priv, flags);
271    if (!pctx) {
272       free(fd6_ctx);
273       return NULL;
274    }
275 
276    pctx->set_framebuffer_state = fd6_set_framebuffer_state;
277 
278    /* after fd_context_init() to override set_shader_images() */
279    fd6_image_init(pctx);
280 
281    /* after fd_context_init() to override memory_barrier/texture_barrier(): */
282    fd6_barrier_init(pctx);
283 
284    util_blitter_set_texture_multisample(fd6_ctx->base.blitter, true);
285 
286    pctx->delete_vertex_elements_state = fd6_vertex_state_delete;
287 
288    /* fd_context_init overwrites delete_rasterizer_state, so set this
289     * here. */
290    pctx->delete_rasterizer_state = fd6_rasterizer_state_delete;
291    pctx->delete_blend_state = fd6_blend_state_delete;
292    pctx->delete_depth_stencil_alpha_state = fd6_zsa_state_delete;
293 
294    /* initial sizes for VSC buffers (or rather the per-pipe sizes
295     * which is used to derive entire buffer size:
296     */
297    fd6_ctx->vsc_draw_strm_pitch = 0x440;
298    fd6_ctx->vsc_prim_strm_pitch = 0x1040;
299 
300    fd6_ctx->control_mem =
301       fd_bo_new(screen->dev, 0x1000, 0, "control");
302 
303    fd_context_add_private_bo(&fd6_ctx->base, fd6_ctx->control_mem);
304 
305    memset(fd_bo_map(fd6_ctx->control_mem), 0, sizeof(struct fd6_control));
306 
307    fd_context_setup_common_vbos(&fd6_ctx->base);
308 
309    fd6_blitter_init<CHIP>(pctx);
310 
311    struct fd_ringbuffer *ring =
312       fd_ringbuffer_new_object(fd6_ctx->base.pipe, 6 * 4);
313 
314    OUT_REG(ring, A6XX_GRAS_SAMPLE_CONFIG());
315    OUT_REG(ring, A6XX_RB_SAMPLE_CONFIG());
316    OUT_REG(ring, A6XX_SP_TP_SAMPLE_CONFIG());
317 
318    fd6_ctx->sample_locations_disable_stateobj = ring;
319 
320    fd6_ctx->preamble = fd6_build_preemption_preamble<CHIP>(&fd6_ctx->base);
321 
322    ring = fd_ringbuffer_new_object(fd6_ctx->base.pipe, 0x1000);
323    fd6_emit_static_regs<CHIP>(&fd6_ctx->base, ring);
324    fd6_ctx->restore = ring;
325 
326    return fd_context_init_tc(pctx, flags);
327 }
328 FD_GENX(fd6_context_create);
329