panfrost: Add an helper to emit a pair of vertex/tiler jobs
[mesa.git] / src / gallium / drivers / panfrost / pan_context.c
1 /*
2 * © Copyright 2018 Alyssa Rosenzweig
3 * Copyright © 2014-2017 Broadcom
4 * Copyright (C) 2017 Intel Corporation
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 */
26
27 #include <sys/poll.h>
28 #include <errno.h>
29
30 #include "pan_bo.h"
31 #include "pan_context.h"
32 #include "pan_minmax_cache.h"
33 #include "panfrost-quirks.h"
34
35 #include "util/macros.h"
36 #include "util/format/u_format.h"
37 #include "util/u_inlines.h"
38 #include "util/u_upload_mgr.h"
39 #include "util/u_memory.h"
40 #include "util/u_vbuf.h"
41 #include "util/half_float.h"
42 #include "util/u_helpers.h"
43 #include "util/format/u_format.h"
44 #include "util/u_prim.h"
45 #include "util/u_prim_restart.h"
46 #include "indices/u_primconvert.h"
47 #include "tgsi/tgsi_parse.h"
48 #include "tgsi/tgsi_from_mesa.h"
49 #include "util/u_math.h"
50
51 #include "pan_screen.h"
52 #include "pan_blending.h"
53 #include "pan_blend_shaders.h"
54 #include "pan_cmdstream.h"
55 #include "pan_util.h"
56 #include "pandecode/decode.h"
57
58 struct midgard_tiler_descriptor
59 panfrost_emit_midg_tiler(struct panfrost_batch *batch, unsigned vertex_count)
60 {
61 struct panfrost_screen *screen = pan_screen(batch->ctx->base.screen);
62 bool hierarchy = !(screen->quirks & MIDGARD_NO_HIER_TILING);
63 struct midgard_tiler_descriptor t = {0};
64 unsigned height = batch->key.height;
65 unsigned width = batch->key.width;
66
67 t.hierarchy_mask =
68 panfrost_choose_hierarchy_mask(width, height, vertex_count, hierarchy);
69
70 /* Compute the polygon header size and use that to offset the body */
71
72 unsigned header_size = panfrost_tiler_header_size(
73 width, height, t.hierarchy_mask, hierarchy);
74
75 t.polygon_list_size = panfrost_tiler_full_size(
76 width, height, t.hierarchy_mask, hierarchy);
77
78 /* Sanity check */
79
80 if (vertex_count) {
81 struct panfrost_bo *tiler_heap;
82
83 tiler_heap = panfrost_batch_get_tiler_heap(batch);
84 t.polygon_list = panfrost_batch_get_polygon_list(batch,
85 header_size +
86 t.polygon_list_size);
87
88
89 /* Allow the entire tiler heap */
90 t.heap_start = tiler_heap->gpu;
91 t.heap_end = tiler_heap->gpu + tiler_heap->size;
92 } else {
93 struct panfrost_bo *tiler_dummy;
94
95 tiler_dummy = panfrost_batch_get_tiler_dummy(batch);
96 header_size = MALI_TILER_MINIMUM_HEADER_SIZE;
97
98 /* The tiler is disabled, so don't allow the tiler heap */
99 t.heap_start = tiler_dummy->gpu;
100 t.heap_end = t.heap_start;
101
102 /* Use a dummy polygon list */
103 t.polygon_list = tiler_dummy->gpu;
104
105 /* Disable the tiler */
106 if (hierarchy)
107 t.hierarchy_mask |= MALI_TILER_DISABLED;
108 else {
109 t.hierarchy_mask = MALI_TILER_USER;
110 t.polygon_list_size = MALI_TILER_MINIMUM_HEADER_SIZE + 4;
111
112 /* We don't have a WRITE_VALUE job, so write the polygon list manually */
113 uint32_t *polygon_list_body = (uint32_t *) (tiler_dummy->cpu + header_size);
114 polygon_list_body[0] = 0xa0000000; /* TODO: Just that? */
115 }
116 }
117
118 t.polygon_list_body =
119 t.polygon_list + header_size;
120
121 return t;
122 }
123
124 static void
125 panfrost_clear(
126 struct pipe_context *pipe,
127 unsigned buffers,
128 const union pipe_color_union *color,
129 double depth, unsigned stencil)
130 {
131 struct panfrost_context *ctx = pan_context(pipe);
132
133 /* TODO: panfrost_get_fresh_batch_for_fbo() instantiates a new batch if
134 * the existing batch targeting this FBO has draws. We could probably
135 * avoid that by replacing plain clears by quad-draws with a specific
136 * color/depth/stencil value, thus avoiding the generation of extra
137 * fragment jobs.
138 */
139 struct panfrost_batch *batch = panfrost_get_fresh_batch_for_fbo(ctx);
140
141 panfrost_batch_add_fbo_bos(batch);
142 panfrost_batch_clear(batch, buffers, color, depth, stencil);
143 }
144
145 /* Reset per-frame context, called on context initialisation as well as after
146 * flushing a frame */
147
148 void
149 panfrost_invalidate_frame(struct panfrost_context *ctx)
150 {
151 for (unsigned i = 0; i < PIPE_SHADER_TYPES; ++i)
152 ctx->payloads[i].postfix.shared_memory = 0;
153
154 /* TODO: When does this need to be handled? */
155 ctx->active_queries = true;
156 }
157
158 /* In practice, every field of these payloads should be configurable
159 * arbitrarily, which means these functions are basically catch-all's for
160 * as-of-yet unwavering unknowns */
161
162 static void
163 panfrost_emit_vertex_payload(struct panfrost_context *ctx)
164 {
165 /* 0x2 bit clear on 32-bit T6XX */
166
167 struct midgard_payload_vertex_tiler payload = {
168 .gl_enables = 0x4 | 0x2,
169 };
170
171 /* Vertex and compute are closely coupled, so share a payload */
172
173 memcpy(&ctx->payloads[PIPE_SHADER_VERTEX], &payload, sizeof(payload));
174 memcpy(&ctx->payloads[PIPE_SHADER_COMPUTE], &payload, sizeof(payload));
175 }
176
177 bool
178 panfrost_writes_point_size(struct panfrost_context *ctx)
179 {
180 assert(ctx->shader[PIPE_SHADER_VERTEX]);
181 struct panfrost_shader_state *vs = panfrost_get_shader_state(ctx, PIPE_SHADER_VERTEX);
182
183 return vs->writes_point_size && ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.draw_mode == MALI_POINTS;
184 }
185
186 /* Stage the attribute descriptors so we can adjust src_offset
187 * to let BOs align nicely */
188
189 static void
190 panfrost_stage_attributes(struct panfrost_context *ctx)
191 {
192 struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
193 struct panfrost_vertex_state *so = ctx->vertex;
194
195 size_t sz = sizeof(struct mali_attr_meta) * PAN_MAX_ATTRIBUTE;
196 struct panfrost_transfer transfer = panfrost_allocate_transient(batch, sz);
197 struct mali_attr_meta *target = (struct mali_attr_meta *) transfer.cpu;
198
199 /* Copy as-is for the first pass */
200 memcpy(target, so->hw, sz);
201
202 /* Fixup offsets for the second pass. Recall that the hardware
203 * calculates attribute addresses as:
204 *
205 * addr = base + (stride * vtx) + src_offset;
206 *
207 * However, on Mali, base must be aligned to 64-bytes, so we
208 * instead let:
209 *
210 * base' = base & ~63 = base - (base & 63)
211 *
212 * To compensate when using base' (see emit_vertex_data), we have
213 * to adjust src_offset by the masked off piece:
214 *
215 * addr' = base' + (stride * vtx) + (src_offset + (base & 63))
216 * = base - (base & 63) + (stride * vtx) + src_offset + (base & 63)
217 * = base + (stride * vtx) + src_offset
218 * = addr;
219 *
220 * QED.
221 */
222
223 unsigned start = ctx->payloads[PIPE_SHADER_VERTEX].offset_start;
224
225 for (unsigned i = 0; i < so->num_elements; ++i) {
226 unsigned vbi = so->pipe[i].vertex_buffer_index;
227 struct pipe_vertex_buffer *buf = &ctx->vertex_buffers[vbi];
228 struct panfrost_resource *rsrc = (struct panfrost_resource *) (buf->buffer.resource);
229 mali_ptr addr = rsrc->bo->gpu + buf->buffer_offset;
230
231 /* Adjust by the masked off bits of the offset. Make sure we
232 * read src_offset from so->hw (which is not GPU visible)
233 * rather than target (which is) due to caching effects */
234
235 unsigned src_offset = so->hw[i].src_offset;
236 src_offset += (addr & 63);
237
238 /* Also, somewhat obscurely per-instance data needs to be
239 * offset in response to a delayed start in an indexed draw */
240
241 if (so->pipe[i].instance_divisor && ctx->instance_count > 1 && start)
242 src_offset -= buf->stride * start;
243
244 target[i].src_offset = src_offset;
245 }
246
247 /* Let's also include vertex builtins */
248
249 struct mali_attr_meta builtin = {
250 .format = MALI_R32UI,
251 .swizzle = panfrost_get_default_swizzle(1)
252 };
253
254 /* See mali_attr_meta specification for the magic number */
255
256 builtin.index = so->vertexid_index;
257 memcpy(&target[PAN_VERTEX_ID], &builtin, 4);
258
259 builtin.index = so->vertexid_index + 1;
260 memcpy(&target[PAN_INSTANCE_ID], &builtin, 4);
261
262 ctx->payloads[PIPE_SHADER_VERTEX].postfix.attribute_meta = transfer.gpu;
263 }
264
265 /* Compute number of UBOs active (more specifically, compute the highest UBO
266 * number addressable -- if there are gaps, include them in the count anyway).
267 * We always include UBO #0 in the count, since we *need* uniforms enabled for
268 * sysvals. */
269
270 unsigned
271 panfrost_ubo_count(struct panfrost_context *ctx, enum pipe_shader_type stage)
272 {
273 unsigned mask = ctx->constant_buffer[stage].enabled_mask | 1;
274 return 32 - __builtin_clz(mask);
275 }
276
277 /* Go through dirty flags and actualise them in the cmdstream. */
278
279 static void
280 panfrost_emit_for_draw(struct panfrost_context *ctx)
281 {
282 struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
283
284 panfrost_batch_add_fbo_bos(batch);
285
286 for (int i = 0; i <= PIPE_SHADER_FRAGMENT; ++i)
287 panfrost_vt_attach_framebuffer(ctx, &ctx->payloads[i]);
288
289 panfrost_emit_vertex_data(batch);
290
291 /* Varyings emitted for -all- geometry */
292 unsigned total_count = ctx->padded_count * ctx->instance_count;
293 panfrost_emit_varying_descriptor(ctx, total_count);
294
295 panfrost_batch_set_requirements(batch);
296
297 panfrost_vt_update_rasterizer(ctx, &ctx->payloads[PIPE_SHADER_FRAGMENT]);
298 panfrost_vt_update_occlusion_query(ctx, &ctx->payloads[PIPE_SHADER_FRAGMENT]);
299
300 panfrost_emit_shader_meta(batch, PIPE_SHADER_VERTEX,
301 &ctx->payloads[PIPE_SHADER_VERTEX]);
302 panfrost_emit_shader_meta(batch, PIPE_SHADER_FRAGMENT,
303 &ctx->payloads[PIPE_SHADER_FRAGMENT]);
304
305 /* We stage to transient, so always dirty.. */
306 if (ctx->vertex)
307 panfrost_stage_attributes(ctx);
308
309 for (int i = 0; i <= PIPE_SHADER_FRAGMENT; ++i) {
310 panfrost_emit_sampler_descriptors(batch, i, &ctx->payloads[i]);
311 panfrost_emit_texture_descriptors(batch, i, &ctx->payloads[i]);
312 panfrost_emit_const_buf(batch, i, &ctx->payloads[i]);
313 }
314
315 /* TODO: Upload the viewport somewhere more appropriate */
316
317 panfrost_emit_viewport(batch, &ctx->payloads[PIPE_SHADER_FRAGMENT]);
318 }
319
320 /* Corresponds to exactly one draw, but does not submit anything */
321
322 static void
323 panfrost_queue_draw(struct panfrost_context *ctx)
324 {
325 /* Handle dirty flags now */
326 panfrost_emit_for_draw(ctx);
327
328 struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
329
330 panfrost_emit_vertex_tiler_jobs(batch,
331 &ctx->payloads[PIPE_SHADER_VERTEX],
332 &ctx->payloads[PIPE_SHADER_FRAGMENT]);
333 panfrost_batch_adjust_stack_size(batch);
334 }
335
336 /* The entire frame is in memory -- send it off to the kernel! */
337
338 void
339 panfrost_flush(
340 struct pipe_context *pipe,
341 struct pipe_fence_handle **fence,
342 unsigned flags)
343 {
344 struct panfrost_context *ctx = pan_context(pipe);
345 struct util_dynarray fences;
346
347 /* We must collect the fences before the flush is done, otherwise we'll
348 * lose track of them.
349 */
350 if (fence) {
351 util_dynarray_init(&fences, NULL);
352 hash_table_foreach(ctx->batches, hentry) {
353 struct panfrost_batch *batch = hentry->data;
354
355 panfrost_batch_fence_reference(batch->out_sync);
356 util_dynarray_append(&fences,
357 struct panfrost_batch_fence *,
358 batch->out_sync);
359 }
360 }
361
362 /* Submit all pending jobs */
363 panfrost_flush_all_batches(ctx, false);
364
365 if (fence) {
366 struct panfrost_fence *f = panfrost_fence_create(ctx, &fences);
367 pipe->screen->fence_reference(pipe->screen, fence, NULL);
368 *fence = (struct pipe_fence_handle *)f;
369
370 util_dynarray_foreach(&fences, struct panfrost_batch_fence *, fence)
371 panfrost_batch_fence_unreference(*fence);
372
373 util_dynarray_fini(&fences);
374 }
375
376 if (pan_debug & PAN_DBG_TRACE)
377 pandecode_next_frame();
378 }
379
380 #define DEFINE_CASE(c) case PIPE_PRIM_##c: return MALI_##c;
381
382 static int
383 g2m_draw_mode(enum pipe_prim_type mode)
384 {
385 switch (mode) {
386 DEFINE_CASE(POINTS);
387 DEFINE_CASE(LINES);
388 DEFINE_CASE(LINE_LOOP);
389 DEFINE_CASE(LINE_STRIP);
390 DEFINE_CASE(TRIANGLES);
391 DEFINE_CASE(TRIANGLE_STRIP);
392 DEFINE_CASE(TRIANGLE_FAN);
393 DEFINE_CASE(QUADS);
394 DEFINE_CASE(QUAD_STRIP);
395 DEFINE_CASE(POLYGON);
396
397 default:
398 unreachable("Invalid draw mode");
399 }
400 }
401
402 #undef DEFINE_CASE
403
404 static unsigned
405 panfrost_translate_index_size(unsigned size)
406 {
407 switch (size) {
408 case 1:
409 return MALI_DRAW_INDEXED_UINT8;
410
411 case 2:
412 return MALI_DRAW_INDEXED_UINT16;
413
414 case 4:
415 return MALI_DRAW_INDEXED_UINT32;
416
417 default:
418 unreachable("Invalid index size");
419 }
420 }
421
422 /* Gets a GPU address for the associated index buffer. Only gauranteed to be
423 * good for the duration of the draw (transient), could last longer. Also get
424 * the bounds on the index buffer for the range accessed by the draw. We do
425 * these operations together because there are natural optimizations which
426 * require them to be together. */
427
428 static mali_ptr
429 panfrost_get_index_buffer_bounded(struct panfrost_context *ctx, const struct pipe_draw_info *info, unsigned *min_index, unsigned *max_index)
430 {
431 struct panfrost_resource *rsrc = (struct panfrost_resource *) (info->index.resource);
432
433 off_t offset = info->start * info->index_size;
434 struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
435 mali_ptr out = 0;
436
437 bool needs_indices = true;
438
439 if (info->max_index != ~0u) {
440 *min_index = info->min_index;
441 *max_index = info->max_index;
442 needs_indices = false;
443 }
444
445 if (!info->has_user_indices) {
446 /* Only resources can be directly mapped */
447 panfrost_batch_add_bo(batch, rsrc->bo,
448 PAN_BO_ACCESS_SHARED |
449 PAN_BO_ACCESS_READ |
450 PAN_BO_ACCESS_VERTEX_TILER);
451 out = rsrc->bo->gpu + offset;
452
453 /* Check the cache */
454 needs_indices = !panfrost_minmax_cache_get(rsrc->index_cache, info->start, info->count,
455 min_index, max_index);
456 } else {
457 /* Otherwise, we need to upload to transient memory */
458 const uint8_t *ibuf8 = (const uint8_t *) info->index.user;
459 out = panfrost_upload_transient(batch, ibuf8 + offset, info->count * info->index_size);
460 }
461
462 if (needs_indices) {
463 /* Fallback */
464 u_vbuf_get_minmax_index(&ctx->base, info, min_index, max_index);
465
466 if (!info->has_user_indices) {
467 panfrost_minmax_cache_add(rsrc->index_cache, info->start, info->count,
468 *min_index, *max_index);
469 }
470 }
471
472
473 return out;
474 }
475
476 static bool
477 panfrost_scissor_culls_everything(struct panfrost_context *ctx)
478 {
479 const struct pipe_scissor_state *ss = &ctx->scissor;
480
481 /* Check if we're scissoring at all */
482
483 if (!(ctx->rasterizer && ctx->rasterizer->base.scissor))
484 return false;
485
486 return (ss->minx == ss->maxx) || (ss->miny == ss->maxy);
487 }
488
489 /* Count generated primitives (when there is no geom/tess shaders) for
490 * transform feedback */
491
492 static void
493 panfrost_statistics_record(
494 struct panfrost_context *ctx,
495 const struct pipe_draw_info *info)
496 {
497 if (!ctx->active_queries)
498 return;
499
500 uint32_t prims = u_prims_for_vertices(info->mode, info->count);
501 ctx->prims_generated += prims;
502
503 if (!ctx->streamout.num_targets)
504 return;
505
506 ctx->tf_prims_generated += prims;
507 }
508
509 static void
510 panfrost_draw_vbo(
511 struct pipe_context *pipe,
512 const struct pipe_draw_info *info)
513 {
514 struct panfrost_context *ctx = pan_context(pipe);
515
516 /* First of all, check the scissor to see if anything is drawn at all.
517 * If it's not, we drop the draw (mostly a conformance issue;
518 * well-behaved apps shouldn't hit this) */
519
520 if (panfrost_scissor_culls_everything(ctx))
521 return;
522
523 int mode = info->mode;
524
525 /* Fallback unsupported restart index */
526 unsigned primitive_index = (1 << (info->index_size * 8)) - 1;
527
528 if (info->primitive_restart && info->index_size
529 && info->restart_index != primitive_index) {
530 util_draw_vbo_without_prim_restart(pipe, info);
531 return;
532 }
533
534 /* Fallback for unsupported modes */
535
536 assert(ctx->rasterizer != NULL);
537
538 if (!(ctx->draw_modes & (1 << mode))) {
539 if (mode == PIPE_PRIM_QUADS && info->count == 4 && !ctx->rasterizer->base.flatshade) {
540 mode = PIPE_PRIM_TRIANGLE_FAN;
541 } else {
542 if (info->count < 4) {
543 /* Degenerate case? */
544 return;
545 }
546
547 util_primconvert_save_rasterizer_state(ctx->primconvert, &ctx->rasterizer->base);
548 util_primconvert_draw_vbo(ctx->primconvert, info);
549 return;
550 }
551 }
552
553 ctx->payloads[PIPE_SHADER_VERTEX].offset_start = info->start;
554 ctx->payloads[PIPE_SHADER_FRAGMENT].offset_start = info->start;
555
556 /* Now that we have a guaranteed terminating path, find the job.
557 * Assignment commented out to prevent unused warning */
558
559 /* struct panfrost_batch *batch = */ panfrost_get_batch_for_fbo(ctx);
560
561 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.draw_mode = g2m_draw_mode(mode);
562
563 /* Take into account a negative bias */
564 ctx->vertex_count = info->count + abs(info->index_bias);
565 ctx->instance_count = info->instance_count;
566 ctx->active_prim = info->mode;
567
568 /* For non-indexed draws, they're the same */
569 unsigned vertex_count = ctx->vertex_count;
570
571 unsigned draw_flags = 0;
572
573 /* The draw flags interpret how primitive size is interpreted */
574
575 if (panfrost_writes_point_size(ctx))
576 draw_flags |= MALI_DRAW_VARYING_SIZE;
577
578 if (info->primitive_restart)
579 draw_flags |= MALI_DRAW_PRIMITIVE_RESTART_FIXED_INDEX;
580
581 /* These doesn't make much sense */
582
583 draw_flags |= 0x3000;
584
585 if (ctx->rasterizer && ctx->rasterizer->base.flatshade_first)
586 draw_flags |= MALI_DRAW_FLATSHADE_FIRST;
587
588 panfrost_statistics_record(ctx, info);
589
590 if (info->index_size) {
591 unsigned min_index = 0, max_index = 0;
592 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.indices =
593 panfrost_get_index_buffer_bounded(ctx, info, &min_index, &max_index);
594
595 /* Use the corresponding values */
596 vertex_count = max_index - min_index + 1;
597 ctx->payloads[PIPE_SHADER_VERTEX].offset_start = min_index + info->index_bias;
598 ctx->payloads[PIPE_SHADER_FRAGMENT].offset_start = min_index + info->index_bias;
599
600 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.offset_bias_correction = -min_index;
601 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.index_count = MALI_POSITIVE(info->count);
602
603 draw_flags |= panfrost_translate_index_size(info->index_size);
604 } else {
605 /* Index count == vertex count, if no indexing is applied, as
606 * if it is internally indexed in the expected order */
607
608 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.offset_bias_correction = 0;
609 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.index_count = MALI_POSITIVE(ctx->vertex_count);
610
611 /* Reverse index state */
612 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.indices = (mali_ptr) 0;
613 }
614
615 /* Dispatch "compute jobs" for the vertex/tiler pair as (1,
616 * vertex_count, 1) */
617
618 panfrost_pack_work_groups_fused(
619 &ctx->payloads[PIPE_SHADER_VERTEX].prefix,
620 &ctx->payloads[PIPE_SHADER_FRAGMENT].prefix,
621 1, vertex_count, info->instance_count,
622 1, 1, 1);
623
624 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.unknown_draw = draw_flags;
625
626 /* Encode the padded vertex count */
627
628 if (info->instance_count > 1) {
629 ctx->padded_count = panfrost_padded_vertex_count(vertex_count);
630
631 unsigned shift = __builtin_ctz(ctx->padded_count);
632 unsigned k = ctx->padded_count >> (shift + 1);
633
634 ctx->payloads[PIPE_SHADER_VERTEX].instance_shift = shift;
635 ctx->payloads[PIPE_SHADER_FRAGMENT].instance_shift = shift;
636
637 ctx->payloads[PIPE_SHADER_VERTEX].instance_odd = k;
638 ctx->payloads[PIPE_SHADER_FRAGMENT].instance_odd = k;
639 } else {
640 ctx->padded_count = vertex_count;
641
642 /* Reset instancing state */
643 ctx->payloads[PIPE_SHADER_VERTEX].instance_shift = 0;
644 ctx->payloads[PIPE_SHADER_VERTEX].instance_odd = 0;
645 ctx->payloads[PIPE_SHADER_FRAGMENT].instance_shift = 0;
646 ctx->payloads[PIPE_SHADER_FRAGMENT].instance_odd = 0;
647 }
648
649 /* Fire off the draw itself */
650 panfrost_queue_draw(ctx);
651
652 /* Increment transform feedback offsets */
653
654 for (unsigned i = 0; i < ctx->streamout.num_targets; ++i) {
655 unsigned output_count = u_stream_outputs_for_vertices(
656 ctx->active_prim, ctx->vertex_count);
657
658 ctx->streamout.offsets[i] += output_count;
659 }
660 }
661
662 /* CSO state */
663
664 static void
665 panfrost_generic_cso_delete(struct pipe_context *pctx, void *hwcso)
666 {
667 free(hwcso);
668 }
669
670 static void *
671 panfrost_create_rasterizer_state(
672 struct pipe_context *pctx,
673 const struct pipe_rasterizer_state *cso)
674 {
675 struct panfrost_rasterizer *so = CALLOC_STRUCT(panfrost_rasterizer);
676
677 so->base = *cso;
678
679 return so;
680 }
681
682 static void
683 panfrost_bind_rasterizer_state(
684 struct pipe_context *pctx,
685 void *hwcso)
686 {
687 struct panfrost_context *ctx = pan_context(pctx);
688
689 ctx->rasterizer = hwcso;
690
691 if (!hwcso)
692 return;
693
694 /* Gauranteed with the core GL call, so don't expose ARB_polygon_offset */
695 assert(ctx->rasterizer->base.offset_clamp == 0.0);
696
697 /* Point sprites are emulated */
698
699 struct panfrost_shader_state *variant = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT);
700
701 if (ctx->rasterizer->base.sprite_coord_enable || (variant && variant->point_sprite_mask))
702 ctx->base.bind_fs_state(&ctx->base, ctx->shader[PIPE_SHADER_FRAGMENT]);
703 }
704
705 static void *
706 panfrost_create_vertex_elements_state(
707 struct pipe_context *pctx,
708 unsigned num_elements,
709 const struct pipe_vertex_element *elements)
710 {
711 struct panfrost_vertex_state *so = CALLOC_STRUCT(panfrost_vertex_state);
712
713 so->num_elements = num_elements;
714 memcpy(so->pipe, elements, sizeof(*elements) * num_elements);
715
716 for (int i = 0; i < num_elements; ++i) {
717 so->hw[i].index = i;
718
719 enum pipe_format fmt = elements[i].src_format;
720 const struct util_format_description *desc = util_format_description(fmt);
721 so->hw[i].unknown1 = 0x2;
722 so->hw[i].swizzle = panfrost_get_default_swizzle(desc->nr_channels);
723
724 so->hw[i].format = panfrost_find_format(desc);
725
726 /* The field itself should probably be shifted over */
727 so->hw[i].src_offset = elements[i].src_offset;
728 }
729
730 return so;
731 }
732
733 static void
734 panfrost_bind_vertex_elements_state(
735 struct pipe_context *pctx,
736 void *hwcso)
737 {
738 struct panfrost_context *ctx = pan_context(pctx);
739 ctx->vertex = hwcso;
740 }
741
742 static void *
743 panfrost_create_shader_state(
744 struct pipe_context *pctx,
745 const struct pipe_shader_state *cso,
746 enum pipe_shader_type stage)
747 {
748 struct panfrost_shader_variants *so = CALLOC_STRUCT(panfrost_shader_variants);
749 so->base = *cso;
750
751 /* Token deep copy to prevent memory corruption */
752
753 if (cso->type == PIPE_SHADER_IR_TGSI)
754 so->base.tokens = tgsi_dup_tokens(so->base.tokens);
755
756 /* Precompile for shader-db if we need to */
757 if (unlikely((pan_debug & PAN_DBG_PRECOMPILE) && cso->type == PIPE_SHADER_IR_NIR)) {
758 struct panfrost_context *ctx = pan_context(pctx);
759
760 struct panfrost_shader_state state;
761 uint64_t outputs_written;
762
763 panfrost_shader_compile(ctx, PIPE_SHADER_IR_NIR,
764 so->base.ir.nir,
765 tgsi_processor_to_shader_stage(stage),
766 &state, &outputs_written);
767 }
768
769 return so;
770 }
771
772 static void
773 panfrost_delete_shader_state(
774 struct pipe_context *pctx,
775 void *so)
776 {
777 struct panfrost_shader_variants *cso = (struct panfrost_shader_variants *) so;
778
779 if (cso->base.type == PIPE_SHADER_IR_TGSI) {
780 DBG("Deleting TGSI shader leaks duplicated tokens\n");
781 }
782
783 for (unsigned i = 0; i < cso->variant_count; ++i) {
784 struct panfrost_shader_state *shader_state = &cso->variants[i];
785 panfrost_bo_unreference(shader_state->bo);
786 shader_state->bo = NULL;
787 }
788 free(cso->variants);
789
790 free(so);
791 }
792
793 static void *
794 panfrost_create_sampler_state(
795 struct pipe_context *pctx,
796 const struct pipe_sampler_state *cso)
797 {
798 struct panfrost_sampler_state *so = CALLOC_STRUCT(panfrost_sampler_state);
799 so->base = *cso;
800
801 panfrost_sampler_desc_init(cso, &so->hw);
802
803 return so;
804 }
805
806 static void
807 panfrost_bind_sampler_states(
808 struct pipe_context *pctx,
809 enum pipe_shader_type shader,
810 unsigned start_slot, unsigned num_sampler,
811 void **sampler)
812 {
813 assert(start_slot == 0);
814
815 struct panfrost_context *ctx = pan_context(pctx);
816
817 /* XXX: Should upload, not just copy? */
818 ctx->sampler_count[shader] = num_sampler;
819 memcpy(ctx->samplers[shader], sampler, num_sampler * sizeof (void *));
820 }
821
822 static bool
823 panfrost_variant_matches(
824 struct panfrost_context *ctx,
825 struct panfrost_shader_state *variant,
826 enum pipe_shader_type type)
827 {
828 struct pipe_rasterizer_state *rasterizer = &ctx->rasterizer->base;
829 struct pipe_alpha_state *alpha = &ctx->depth_stencil->alpha;
830
831 bool is_fragment = (type == PIPE_SHADER_FRAGMENT);
832
833 if (is_fragment && (alpha->enabled || variant->alpha_state.enabled)) {
834 /* Make sure enable state is at least the same */
835 if (alpha->enabled != variant->alpha_state.enabled) {
836 return false;
837 }
838
839 /* Check that the contents of the test are the same */
840 bool same_func = alpha->func == variant->alpha_state.func;
841 bool same_ref = alpha->ref_value == variant->alpha_state.ref_value;
842
843 if (!(same_func && same_ref)) {
844 return false;
845 }
846 }
847
848 if (is_fragment && rasterizer && (rasterizer->sprite_coord_enable |
849 variant->point_sprite_mask)) {
850 /* Ensure the same varyings are turned to point sprites */
851 if (rasterizer->sprite_coord_enable != variant->point_sprite_mask)
852 return false;
853
854 /* Ensure the orientation is correct */
855 bool upper_left =
856 rasterizer->sprite_coord_mode ==
857 PIPE_SPRITE_COORD_UPPER_LEFT;
858
859 if (variant->point_sprite_upper_left != upper_left)
860 return false;
861 }
862
863 /* Otherwise, we're good to go */
864 return true;
865 }
866
867 /**
868 * Fix an uncompiled shader's stream output info, and produce a bitmask
869 * of which VARYING_SLOT_* are captured for stream output.
870 *
871 * Core Gallium stores output->register_index as a "slot" number, where
872 * slots are assigned consecutively to all outputs in info->outputs_written.
873 * This naive packing of outputs doesn't work for us - we too have slots,
874 * but the layout is defined by the VUE map, which we won't have until we
875 * compile a specific shader variant. So, we remap these and simply store
876 * VARYING_SLOT_* in our copy's output->register_index fields.
877 *
878 * We then produce a bitmask of outputs which are used for SO.
879 *
880 * Implementation from iris.
881 */
882
883 static uint64_t
884 update_so_info(struct pipe_stream_output_info *so_info,
885 uint64_t outputs_written)
886 {
887 uint64_t so_outputs = 0;
888 uint8_t reverse_map[64] = {0};
889 unsigned slot = 0;
890
891 while (outputs_written)
892 reverse_map[slot++] = u_bit_scan64(&outputs_written);
893
894 for (unsigned i = 0; i < so_info->num_outputs; i++) {
895 struct pipe_stream_output *output = &so_info->output[i];
896
897 /* Map Gallium's condensed "slots" back to real VARYING_SLOT_* enums */
898 output->register_index = reverse_map[output->register_index];
899
900 so_outputs |= 1ull << output->register_index;
901 }
902
903 return so_outputs;
904 }
905
906 static void
907 panfrost_bind_shader_state(
908 struct pipe_context *pctx,
909 void *hwcso,
910 enum pipe_shader_type type)
911 {
912 struct panfrost_context *ctx = pan_context(pctx);
913 ctx->shader[type] = hwcso;
914
915 if (!hwcso) return;
916
917 /* Match the appropriate variant */
918
919 signed variant = -1;
920 struct panfrost_shader_variants *variants = (struct panfrost_shader_variants *) hwcso;
921
922 for (unsigned i = 0; i < variants->variant_count; ++i) {
923 if (panfrost_variant_matches(ctx, &variants->variants[i], type)) {
924 variant = i;
925 break;
926 }
927 }
928
929 if (variant == -1) {
930 /* No variant matched, so create a new one */
931 variant = variants->variant_count++;
932
933 if (variants->variant_count > variants->variant_space) {
934 unsigned old_space = variants->variant_space;
935
936 variants->variant_space *= 2;
937 if (variants->variant_space == 0)
938 variants->variant_space = 1;
939
940 /* Arbitrary limit to stop runaway programs from
941 * creating an unbounded number of shader variants. */
942 assert(variants->variant_space < 1024);
943
944 unsigned msize = sizeof(struct panfrost_shader_state);
945 variants->variants = realloc(variants->variants,
946 variants->variant_space * msize);
947
948 memset(&variants->variants[old_space], 0,
949 (variants->variant_space - old_space) * msize);
950 }
951
952 struct panfrost_shader_state *v =
953 &variants->variants[variant];
954
955 if (type == PIPE_SHADER_FRAGMENT) {
956 v->alpha_state = ctx->depth_stencil->alpha;
957
958 if (ctx->rasterizer) {
959 v->point_sprite_mask = ctx->rasterizer->base.sprite_coord_enable;
960 v->point_sprite_upper_left =
961 ctx->rasterizer->base.sprite_coord_mode ==
962 PIPE_SPRITE_COORD_UPPER_LEFT;
963 }
964 }
965 }
966
967 /* Select this variant */
968 variants->active_variant = variant;
969
970 struct panfrost_shader_state *shader_state = &variants->variants[variant];
971 assert(panfrost_variant_matches(ctx, shader_state, type));
972
973 /* We finally have a variant, so compile it */
974
975 if (!shader_state->compiled) {
976 uint64_t outputs_written = 0;
977
978 panfrost_shader_compile(ctx, variants->base.type,
979 variants->base.type == PIPE_SHADER_IR_NIR ?
980 variants->base.ir.nir :
981 variants->base.tokens,
982 tgsi_processor_to_shader_stage(type),
983 shader_state,
984 &outputs_written);
985
986 shader_state->compiled = true;
987
988 /* Fixup the stream out information, since what Gallium returns
989 * normally is mildly insane */
990
991 shader_state->stream_output = variants->base.stream_output;
992 shader_state->so_mask =
993 update_so_info(&shader_state->stream_output, outputs_written);
994 }
995 }
996
997 static void *
998 panfrost_create_vs_state(struct pipe_context *pctx, const struct pipe_shader_state *hwcso)
999 {
1000 return panfrost_create_shader_state(pctx, hwcso, PIPE_SHADER_VERTEX);
1001 }
1002
1003 static void *
1004 panfrost_create_fs_state(struct pipe_context *pctx, const struct pipe_shader_state *hwcso)
1005 {
1006 return panfrost_create_shader_state(pctx, hwcso, PIPE_SHADER_FRAGMENT);
1007 }
1008
1009 static void
1010 panfrost_bind_vs_state(struct pipe_context *pctx, void *hwcso)
1011 {
1012 panfrost_bind_shader_state(pctx, hwcso, PIPE_SHADER_VERTEX);
1013 }
1014
1015 static void
1016 panfrost_bind_fs_state(struct pipe_context *pctx, void *hwcso)
1017 {
1018 panfrost_bind_shader_state(pctx, hwcso, PIPE_SHADER_FRAGMENT);
1019 }
1020
1021 static void
1022 panfrost_set_vertex_buffers(
1023 struct pipe_context *pctx,
1024 unsigned start_slot,
1025 unsigned num_buffers,
1026 const struct pipe_vertex_buffer *buffers)
1027 {
1028 struct panfrost_context *ctx = pan_context(pctx);
1029
1030 util_set_vertex_buffers_mask(ctx->vertex_buffers, &ctx->vb_mask, buffers, start_slot, num_buffers);
1031 }
1032
1033 static void
1034 panfrost_set_constant_buffer(
1035 struct pipe_context *pctx,
1036 enum pipe_shader_type shader, uint index,
1037 const struct pipe_constant_buffer *buf)
1038 {
1039 struct panfrost_context *ctx = pan_context(pctx);
1040 struct panfrost_constant_buffer *pbuf = &ctx->constant_buffer[shader];
1041
1042 util_copy_constant_buffer(&pbuf->cb[index], buf);
1043
1044 unsigned mask = (1 << index);
1045
1046 if (unlikely(!buf)) {
1047 pbuf->enabled_mask &= ~mask;
1048 pbuf->dirty_mask &= ~mask;
1049 return;
1050 }
1051
1052 pbuf->enabled_mask |= mask;
1053 pbuf->dirty_mask |= mask;
1054 }
1055
1056 static void
1057 panfrost_set_stencil_ref(
1058 struct pipe_context *pctx,
1059 const struct pipe_stencil_ref *ref)
1060 {
1061 struct panfrost_context *ctx = pan_context(pctx);
1062 ctx->stencil_ref = *ref;
1063 }
1064
1065 static enum mali_texture_type
1066 panfrost_translate_texture_type(enum pipe_texture_target t) {
1067 switch (t)
1068 {
1069 case PIPE_BUFFER:
1070 case PIPE_TEXTURE_1D:
1071 case PIPE_TEXTURE_1D_ARRAY:
1072 return MALI_TEX_1D;
1073
1074 case PIPE_TEXTURE_2D:
1075 case PIPE_TEXTURE_2D_ARRAY:
1076 case PIPE_TEXTURE_RECT:
1077 return MALI_TEX_2D;
1078
1079 case PIPE_TEXTURE_3D:
1080 return MALI_TEX_3D;
1081
1082 case PIPE_TEXTURE_CUBE:
1083 case PIPE_TEXTURE_CUBE_ARRAY:
1084 return MALI_TEX_CUBE;
1085
1086 default:
1087 unreachable("Unknown target");
1088 }
1089 }
1090
1091 static struct pipe_sampler_view *
1092 panfrost_create_sampler_view(
1093 struct pipe_context *pctx,
1094 struct pipe_resource *texture,
1095 const struct pipe_sampler_view *template)
1096 {
1097 struct panfrost_screen *screen = pan_screen(pctx->screen);
1098 struct panfrost_sampler_view *so = rzalloc(pctx, struct panfrost_sampler_view);
1099
1100 pipe_reference(NULL, &texture->reference);
1101
1102 struct panfrost_resource *prsrc = (struct panfrost_resource *) texture;
1103 assert(prsrc->bo);
1104
1105 so->base = *template;
1106 so->base.texture = texture;
1107 so->base.reference.count = 1;
1108 so->base.context = pctx;
1109
1110 unsigned char user_swizzle[4] = {
1111 template->swizzle_r,
1112 template->swizzle_g,
1113 template->swizzle_b,
1114 template->swizzle_a
1115 };
1116
1117 /* In the hardware, array_size refers specifically to array textures,
1118 * whereas in Gallium, it also covers cubemaps */
1119
1120 unsigned array_size = texture->array_size;
1121
1122 if (template->target == PIPE_TEXTURE_CUBE) {
1123 /* TODO: Cubemap arrays */
1124 assert(array_size == 6);
1125 array_size /= 6;
1126 }
1127
1128 enum mali_texture_type type =
1129 panfrost_translate_texture_type(template->target);
1130
1131 unsigned size = panfrost_estimate_texture_size(
1132 template->u.tex.first_level,
1133 template->u.tex.last_level,
1134 template->u.tex.first_layer,
1135 template->u.tex.last_layer,
1136 type, prsrc->layout);
1137
1138 so->bo = panfrost_bo_create(screen, size, 0);
1139
1140 panfrost_new_texture(
1141 so->bo->cpu,
1142 texture->width0, texture->height0,
1143 texture->depth0, array_size,
1144 template->format,
1145 type, prsrc->layout,
1146 template->u.tex.first_level,
1147 template->u.tex.last_level,
1148 template->u.tex.first_layer,
1149 template->u.tex.last_layer,
1150 prsrc->cubemap_stride,
1151 panfrost_translate_swizzle_4(user_swizzle),
1152 prsrc->bo->gpu,
1153 prsrc->slices);
1154
1155 return (struct pipe_sampler_view *) so;
1156 }
1157
1158 static void
1159 panfrost_set_sampler_views(
1160 struct pipe_context *pctx,
1161 enum pipe_shader_type shader,
1162 unsigned start_slot, unsigned num_views,
1163 struct pipe_sampler_view **views)
1164 {
1165 struct panfrost_context *ctx = pan_context(pctx);
1166 unsigned new_nr = 0;
1167 unsigned i;
1168
1169 assert(start_slot == 0);
1170
1171 for (i = 0; i < num_views; ++i) {
1172 if (views[i])
1173 new_nr = i + 1;
1174 pipe_sampler_view_reference((struct pipe_sampler_view **)&ctx->sampler_views[shader][i],
1175 views[i]);
1176 }
1177
1178 for (; i < ctx->sampler_view_count[shader]; i++) {
1179 pipe_sampler_view_reference((struct pipe_sampler_view **)&ctx->sampler_views[shader][i],
1180 NULL);
1181 }
1182 ctx->sampler_view_count[shader] = new_nr;
1183 }
1184
1185 static void
1186 panfrost_sampler_view_destroy(
1187 struct pipe_context *pctx,
1188 struct pipe_sampler_view *pview)
1189 {
1190 struct panfrost_sampler_view *view = (struct panfrost_sampler_view *) pview;
1191
1192 pipe_resource_reference(&pview->texture, NULL);
1193 panfrost_bo_unreference(view->bo);
1194 ralloc_free(view);
1195 }
1196
1197 static void
1198 panfrost_set_shader_buffers(
1199 struct pipe_context *pctx,
1200 enum pipe_shader_type shader,
1201 unsigned start, unsigned count,
1202 const struct pipe_shader_buffer *buffers,
1203 unsigned writable_bitmask)
1204 {
1205 struct panfrost_context *ctx = pan_context(pctx);
1206
1207 util_set_shader_buffers_mask(ctx->ssbo[shader], &ctx->ssbo_mask[shader],
1208 buffers, start, count);
1209 }
1210
1211 /* Hints that a framebuffer should use AFBC where possible */
1212
1213 static void
1214 panfrost_hint_afbc(
1215 struct panfrost_screen *screen,
1216 const struct pipe_framebuffer_state *fb)
1217 {
1218 /* AFBC implemenation incomplete; hide it */
1219 if (!(pan_debug & PAN_DBG_AFBC)) return;
1220
1221 /* Hint AFBC to the resources bound to each color buffer */
1222
1223 for (unsigned i = 0; i < fb->nr_cbufs; ++i) {
1224 struct pipe_surface *surf = fb->cbufs[i];
1225 struct panfrost_resource *rsrc = pan_resource(surf->texture);
1226 panfrost_resource_hint_layout(screen, rsrc, MALI_TEXTURE_AFBC, 1);
1227 }
1228
1229 /* Also hint it to the depth buffer */
1230
1231 if (fb->zsbuf) {
1232 struct panfrost_resource *rsrc = pan_resource(fb->zsbuf->texture);
1233 panfrost_resource_hint_layout(screen, rsrc, MALI_TEXTURE_AFBC, 1);
1234 }
1235 }
1236
1237 static void
1238 panfrost_set_framebuffer_state(struct pipe_context *pctx,
1239 const struct pipe_framebuffer_state *fb)
1240 {
1241 struct panfrost_context *ctx = pan_context(pctx);
1242
1243 panfrost_hint_afbc(pan_screen(pctx->screen), fb);
1244 util_copy_framebuffer_state(&ctx->pipe_framebuffer, fb);
1245 ctx->batch = NULL;
1246 panfrost_invalidate_frame(ctx);
1247 }
1248
1249 static void *
1250 panfrost_create_depth_stencil_state(struct pipe_context *pipe,
1251 const struct pipe_depth_stencil_alpha_state *depth_stencil)
1252 {
1253 return mem_dup(depth_stencil, sizeof(*depth_stencil));
1254 }
1255
1256 static void
1257 panfrost_bind_depth_stencil_state(struct pipe_context *pipe,
1258 void *cso)
1259 {
1260 struct panfrost_context *ctx = pan_context(pipe);
1261 struct pipe_depth_stencil_alpha_state *depth_stencil = cso;
1262 ctx->depth_stencil = depth_stencil;
1263
1264 if (!depth_stencil)
1265 return;
1266
1267 /* Alpha does not exist in the hardware (it's not in ES3), so it's
1268 * emulated in the fragment shader */
1269
1270 if (depth_stencil->alpha.enabled) {
1271 /* We need to trigger a new shader (maybe) */
1272 ctx->base.bind_fs_state(&ctx->base, ctx->shader[PIPE_SHADER_FRAGMENT]);
1273 }
1274
1275 /* Bounds test not implemented */
1276 assert(!depth_stencil->depth.bounds_test);
1277 }
1278
1279 static void
1280 panfrost_delete_depth_stencil_state(struct pipe_context *pipe, void *depth)
1281 {
1282 free( depth );
1283 }
1284
1285 static void
1286 panfrost_set_sample_mask(struct pipe_context *pipe,
1287 unsigned sample_mask)
1288 {
1289 }
1290
1291 static void
1292 panfrost_set_clip_state(struct pipe_context *pipe,
1293 const struct pipe_clip_state *clip)
1294 {
1295 //struct panfrost_context *panfrost = pan_context(pipe);
1296 }
1297
1298 static void
1299 panfrost_set_viewport_states(struct pipe_context *pipe,
1300 unsigned start_slot,
1301 unsigned num_viewports,
1302 const struct pipe_viewport_state *viewports)
1303 {
1304 struct panfrost_context *ctx = pan_context(pipe);
1305
1306 assert(start_slot == 0);
1307 assert(num_viewports == 1);
1308
1309 ctx->pipe_viewport = *viewports;
1310 }
1311
1312 static void
1313 panfrost_set_scissor_states(struct pipe_context *pipe,
1314 unsigned start_slot,
1315 unsigned num_scissors,
1316 const struct pipe_scissor_state *scissors)
1317 {
1318 struct panfrost_context *ctx = pan_context(pipe);
1319
1320 assert(start_slot == 0);
1321 assert(num_scissors == 1);
1322
1323 ctx->scissor = *scissors;
1324 }
1325
1326 static void
1327 panfrost_set_polygon_stipple(struct pipe_context *pipe,
1328 const struct pipe_poly_stipple *stipple)
1329 {
1330 //struct panfrost_context *panfrost = pan_context(pipe);
1331 }
1332
1333 static void
1334 panfrost_set_active_query_state(struct pipe_context *pipe,
1335 bool enable)
1336 {
1337 struct panfrost_context *ctx = pan_context(pipe);
1338 ctx->active_queries = enable;
1339 }
1340
1341 static void
1342 panfrost_destroy(struct pipe_context *pipe)
1343 {
1344 struct panfrost_context *panfrost = pan_context(pipe);
1345
1346 if (panfrost->blitter)
1347 util_blitter_destroy(panfrost->blitter);
1348
1349 if (panfrost->blitter_wallpaper)
1350 util_blitter_destroy(panfrost->blitter_wallpaper);
1351
1352 util_unreference_framebuffer_state(&panfrost->pipe_framebuffer);
1353 u_upload_destroy(pipe->stream_uploader);
1354
1355 ralloc_free(pipe);
1356 }
1357
1358 static struct pipe_query *
1359 panfrost_create_query(struct pipe_context *pipe,
1360 unsigned type,
1361 unsigned index)
1362 {
1363 struct panfrost_query *q = rzalloc(pipe, struct panfrost_query);
1364
1365 q->type = type;
1366 q->index = index;
1367
1368 return (struct pipe_query *) q;
1369 }
1370
1371 static void
1372 panfrost_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
1373 {
1374 struct panfrost_query *query = (struct panfrost_query *) q;
1375
1376 if (query->bo) {
1377 panfrost_bo_unreference(query->bo);
1378 query->bo = NULL;
1379 }
1380
1381 ralloc_free(q);
1382 }
1383
1384 static bool
1385 panfrost_begin_query(struct pipe_context *pipe, struct pipe_query *q)
1386 {
1387 struct panfrost_context *ctx = pan_context(pipe);
1388 struct panfrost_query *query = (struct panfrost_query *) q;
1389
1390 switch (query->type) {
1391 case PIPE_QUERY_OCCLUSION_COUNTER:
1392 case PIPE_QUERY_OCCLUSION_PREDICATE:
1393 case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
1394 /* Allocate a bo for the query results to be stored */
1395 if (!query->bo) {
1396 query->bo = panfrost_bo_create(
1397 pan_screen(ctx->base.screen),
1398 sizeof(unsigned), 0);
1399 }
1400
1401 unsigned *result = (unsigned *)query->bo->cpu;
1402 *result = 0; /* Default to 0 if nothing at all drawn. */
1403 ctx->occlusion_query = query;
1404 break;
1405
1406 /* Geometry statistics are computed in the driver. XXX: geom/tess
1407 * shaders.. */
1408
1409 case PIPE_QUERY_PRIMITIVES_GENERATED:
1410 query->start = ctx->prims_generated;
1411 break;
1412 case PIPE_QUERY_PRIMITIVES_EMITTED:
1413 query->start = ctx->tf_prims_generated;
1414 break;
1415
1416 default:
1417 DBG("Skipping query %u\n", query->type);
1418 break;
1419 }
1420
1421 return true;
1422 }
1423
1424 static bool
1425 panfrost_end_query(struct pipe_context *pipe, struct pipe_query *q)
1426 {
1427 struct panfrost_context *ctx = pan_context(pipe);
1428 struct panfrost_query *query = (struct panfrost_query *) q;
1429
1430 switch (query->type) {
1431 case PIPE_QUERY_OCCLUSION_COUNTER:
1432 case PIPE_QUERY_OCCLUSION_PREDICATE:
1433 case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
1434 ctx->occlusion_query = NULL;
1435 break;
1436 case PIPE_QUERY_PRIMITIVES_GENERATED:
1437 query->end = ctx->prims_generated;
1438 break;
1439 case PIPE_QUERY_PRIMITIVES_EMITTED:
1440 query->end = ctx->tf_prims_generated;
1441 break;
1442 }
1443
1444 return true;
1445 }
1446
1447 static bool
1448 panfrost_get_query_result(struct pipe_context *pipe,
1449 struct pipe_query *q,
1450 bool wait,
1451 union pipe_query_result *vresult)
1452 {
1453 struct panfrost_query *query = (struct panfrost_query *) q;
1454 struct panfrost_context *ctx = pan_context(pipe);
1455
1456
1457 switch (query->type) {
1458 case PIPE_QUERY_OCCLUSION_COUNTER:
1459 case PIPE_QUERY_OCCLUSION_PREDICATE:
1460 case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
1461 /* Flush first */
1462 panfrost_flush_all_batches(ctx, true);
1463
1464 /* Read back the query results */
1465 unsigned *result = (unsigned *) query->bo->cpu;
1466 unsigned passed = *result;
1467
1468 if (query->type == PIPE_QUERY_OCCLUSION_COUNTER) {
1469 vresult->u64 = passed;
1470 } else {
1471 vresult->b = !!passed;
1472 }
1473
1474 break;
1475
1476 case PIPE_QUERY_PRIMITIVES_GENERATED:
1477 case PIPE_QUERY_PRIMITIVES_EMITTED:
1478 panfrost_flush_all_batches(ctx, true);
1479 vresult->u64 = query->end - query->start;
1480 break;
1481
1482 default:
1483 DBG("Skipped query get %u\n", query->type);
1484 break;
1485 }
1486
1487 return true;
1488 }
1489
1490 static struct pipe_stream_output_target *
1491 panfrost_create_stream_output_target(struct pipe_context *pctx,
1492 struct pipe_resource *prsc,
1493 unsigned buffer_offset,
1494 unsigned buffer_size)
1495 {
1496 struct pipe_stream_output_target *target;
1497
1498 target = rzalloc(pctx, struct pipe_stream_output_target);
1499
1500 if (!target)
1501 return NULL;
1502
1503 pipe_reference_init(&target->reference, 1);
1504 pipe_resource_reference(&target->buffer, prsc);
1505
1506 target->context = pctx;
1507 target->buffer_offset = buffer_offset;
1508 target->buffer_size = buffer_size;
1509
1510 return target;
1511 }
1512
1513 static void
1514 panfrost_stream_output_target_destroy(struct pipe_context *pctx,
1515 struct pipe_stream_output_target *target)
1516 {
1517 pipe_resource_reference(&target->buffer, NULL);
1518 ralloc_free(target);
1519 }
1520
1521 static void
1522 panfrost_set_stream_output_targets(struct pipe_context *pctx,
1523 unsigned num_targets,
1524 struct pipe_stream_output_target **targets,
1525 const unsigned *offsets)
1526 {
1527 struct panfrost_context *ctx = pan_context(pctx);
1528 struct panfrost_streamout *so = &ctx->streamout;
1529
1530 assert(num_targets <= ARRAY_SIZE(so->targets));
1531
1532 for (unsigned i = 0; i < num_targets; i++) {
1533 if (offsets[i] != -1)
1534 so->offsets[i] = offsets[i];
1535
1536 pipe_so_target_reference(&so->targets[i], targets[i]);
1537 }
1538
1539 for (unsigned i = 0; i < so->num_targets; i++)
1540 pipe_so_target_reference(&so->targets[i], NULL);
1541
1542 so->num_targets = num_targets;
1543 }
1544
1545 struct pipe_context *
1546 panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
1547 {
1548 struct panfrost_context *ctx = rzalloc(screen, struct panfrost_context);
1549 struct pipe_context *gallium = (struct pipe_context *) ctx;
1550
1551 gallium->screen = screen;
1552
1553 gallium->destroy = panfrost_destroy;
1554
1555 gallium->set_framebuffer_state = panfrost_set_framebuffer_state;
1556
1557 gallium->flush = panfrost_flush;
1558 gallium->clear = panfrost_clear;
1559 gallium->draw_vbo = panfrost_draw_vbo;
1560
1561 gallium->set_vertex_buffers = panfrost_set_vertex_buffers;
1562 gallium->set_constant_buffer = panfrost_set_constant_buffer;
1563 gallium->set_shader_buffers = panfrost_set_shader_buffers;
1564
1565 gallium->set_stencil_ref = panfrost_set_stencil_ref;
1566
1567 gallium->create_sampler_view = panfrost_create_sampler_view;
1568 gallium->set_sampler_views = panfrost_set_sampler_views;
1569 gallium->sampler_view_destroy = panfrost_sampler_view_destroy;
1570
1571 gallium->create_rasterizer_state = panfrost_create_rasterizer_state;
1572 gallium->bind_rasterizer_state = panfrost_bind_rasterizer_state;
1573 gallium->delete_rasterizer_state = panfrost_generic_cso_delete;
1574
1575 gallium->create_vertex_elements_state = panfrost_create_vertex_elements_state;
1576 gallium->bind_vertex_elements_state = panfrost_bind_vertex_elements_state;
1577 gallium->delete_vertex_elements_state = panfrost_generic_cso_delete;
1578
1579 gallium->create_fs_state = panfrost_create_fs_state;
1580 gallium->delete_fs_state = panfrost_delete_shader_state;
1581 gallium->bind_fs_state = panfrost_bind_fs_state;
1582
1583 gallium->create_vs_state = panfrost_create_vs_state;
1584 gallium->delete_vs_state = panfrost_delete_shader_state;
1585 gallium->bind_vs_state = panfrost_bind_vs_state;
1586
1587 gallium->create_sampler_state = panfrost_create_sampler_state;
1588 gallium->delete_sampler_state = panfrost_generic_cso_delete;
1589 gallium->bind_sampler_states = panfrost_bind_sampler_states;
1590
1591 gallium->create_depth_stencil_alpha_state = panfrost_create_depth_stencil_state;
1592 gallium->bind_depth_stencil_alpha_state = panfrost_bind_depth_stencil_state;
1593 gallium->delete_depth_stencil_alpha_state = panfrost_delete_depth_stencil_state;
1594
1595 gallium->set_sample_mask = panfrost_set_sample_mask;
1596
1597 gallium->set_clip_state = panfrost_set_clip_state;
1598 gallium->set_viewport_states = panfrost_set_viewport_states;
1599 gallium->set_scissor_states = panfrost_set_scissor_states;
1600 gallium->set_polygon_stipple = panfrost_set_polygon_stipple;
1601 gallium->set_active_query_state = panfrost_set_active_query_state;
1602
1603 gallium->create_query = panfrost_create_query;
1604 gallium->destroy_query = panfrost_destroy_query;
1605 gallium->begin_query = panfrost_begin_query;
1606 gallium->end_query = panfrost_end_query;
1607 gallium->get_query_result = panfrost_get_query_result;
1608
1609 gallium->create_stream_output_target = panfrost_create_stream_output_target;
1610 gallium->stream_output_target_destroy = panfrost_stream_output_target_destroy;
1611 gallium->set_stream_output_targets = panfrost_set_stream_output_targets;
1612
1613 panfrost_resource_context_init(gallium);
1614 panfrost_blend_context_init(gallium);
1615 panfrost_compute_context_init(gallium);
1616
1617 /* XXX: leaks */
1618 gallium->stream_uploader = u_upload_create_default(gallium);
1619 gallium->const_uploader = gallium->stream_uploader;
1620 assert(gallium->stream_uploader);
1621
1622 /* Midgard supports ES modes, plus QUADS/QUAD_STRIPS/POLYGON */
1623 ctx->draw_modes = (1 << (PIPE_PRIM_POLYGON + 1)) - 1;
1624
1625 ctx->primconvert = util_primconvert_create(gallium, ctx->draw_modes);
1626
1627 ctx->blitter = util_blitter_create(gallium);
1628 ctx->blitter_wallpaper = util_blitter_create(gallium);
1629
1630 assert(ctx->blitter);
1631 assert(ctx->blitter_wallpaper);
1632
1633 /* Prepare for render! */
1634
1635 panfrost_batch_init(ctx);
1636 panfrost_emit_vertex_payload(ctx);
1637 panfrost_invalidate_frame(ctx);
1638
1639 return gallium;
1640 }