002801875a233ad558581030a7c07f86556d1733
[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 static void
187 panfrost_vertex_state_upd_attr_offs(struct panfrost_context *ctx,
188 struct midgard_payload_vertex_tiler *vp)
189 {
190 if (!ctx->vertex)
191 return;
192
193 struct panfrost_vertex_state *so = ctx->vertex;
194
195 /* Fixup offsets for the second pass. Recall that the hardware
196 * calculates attribute addresses as:
197 *
198 * addr = base + (stride * vtx) + src_offset;
199 *
200 * However, on Mali, base must be aligned to 64-bytes, so we
201 * instead let:
202 *
203 * base' = base & ~63 = base - (base & 63)
204 *
205 * To compensate when using base' (see emit_vertex_data), we have
206 * to adjust src_offset by the masked off piece:
207 *
208 * addr' = base' + (stride * vtx) + (src_offset + (base & 63))
209 * = base - (base & 63) + (stride * vtx) + src_offset + (base & 63)
210 * = base + (stride * vtx) + src_offset
211 * = addr;
212 *
213 * QED.
214 */
215
216 unsigned start = vp->offset_start;
217
218 for (unsigned i = 0; i < so->num_elements; ++i) {
219 unsigned vbi = so->pipe[i].vertex_buffer_index;
220 struct pipe_vertex_buffer *buf = &ctx->vertex_buffers[vbi];
221
222 /* Adjust by the masked off bits of the offset. Make sure we
223 * read src_offset from so->hw (which is not GPU visible)
224 * rather than target (which is) due to caching effects */
225
226 unsigned src_offset = so->pipe[i].src_offset;
227
228 /* BOs aligned to 4k so guaranteed aligned to 64 */
229 src_offset += (buf->buffer_offset & 63);
230
231 /* Also, somewhat obscurely per-instance data needs to be
232 * offset in response to a delayed start in an indexed draw */
233
234 if (so->pipe[i].instance_divisor && ctx->instance_count > 1 && start)
235 src_offset -= buf->stride * start;
236
237 so->hw[i].src_offset = src_offset;
238 }
239 }
240
241 /* Stage the attribute descriptors so we can adjust src_offset
242 * to let BOs align nicely */
243
244 static void
245 panfrost_stage_attributes(struct panfrost_context *ctx)
246 {
247 struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
248 struct panfrost_vertex_state *so = ctx->vertex;
249
250 /* Update src_offsets before copying to the GPU buffer. */
251
252 panfrost_vertex_state_upd_attr_offs(ctx,
253 &ctx->payloads[PIPE_SHADER_VERTEX]);
254
255 mali_ptr out = panfrost_upload_transient(batch, so->hw,
256 sizeof(*so->hw) *
257 PAN_MAX_ATTRIBUTE);
258
259 ctx->payloads[PIPE_SHADER_VERTEX].postfix.attribute_meta = out;
260 }
261
262 /* Compute number of UBOs active (more specifically, compute the highest UBO
263 * number addressable -- if there are gaps, include them in the count anyway).
264 * We always include UBO #0 in the count, since we *need* uniforms enabled for
265 * sysvals. */
266
267 unsigned
268 panfrost_ubo_count(struct panfrost_context *ctx, enum pipe_shader_type stage)
269 {
270 unsigned mask = ctx->constant_buffer[stage].enabled_mask | 1;
271 return 32 - __builtin_clz(mask);
272 }
273
274 /* Go through dirty flags and actualise them in the cmdstream. */
275
276 static void
277 panfrost_emit_for_draw(struct panfrost_context *ctx)
278 {
279 struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
280
281 panfrost_batch_add_fbo_bos(batch);
282
283 for (int i = 0; i <= PIPE_SHADER_FRAGMENT; ++i)
284 panfrost_vt_attach_framebuffer(ctx, &ctx->payloads[i]);
285
286 panfrost_emit_vertex_data(batch);
287
288 /* Varyings emitted for -all- geometry */
289 unsigned total_count = ctx->padded_count * ctx->instance_count;
290 panfrost_emit_varying_descriptor(ctx, total_count);
291
292 panfrost_batch_set_requirements(batch);
293
294 panfrost_vt_update_rasterizer(ctx, &ctx->payloads[PIPE_SHADER_FRAGMENT]);
295 panfrost_vt_update_occlusion_query(ctx, &ctx->payloads[PIPE_SHADER_FRAGMENT]);
296
297 panfrost_emit_shader_meta(batch, PIPE_SHADER_VERTEX,
298 &ctx->payloads[PIPE_SHADER_VERTEX]);
299 panfrost_emit_shader_meta(batch, PIPE_SHADER_FRAGMENT,
300 &ctx->payloads[PIPE_SHADER_FRAGMENT]);
301
302 /* We stage to transient, so always dirty.. */
303 if (ctx->vertex)
304 panfrost_stage_attributes(ctx);
305
306 for (int i = 0; i <= PIPE_SHADER_FRAGMENT; ++i) {
307 panfrost_emit_sampler_descriptors(batch, i, &ctx->payloads[i]);
308 panfrost_emit_texture_descriptors(batch, i, &ctx->payloads[i]);
309 panfrost_emit_const_buf(batch, i, &ctx->payloads[i]);
310 }
311
312 /* TODO: Upload the viewport somewhere more appropriate */
313
314 panfrost_emit_viewport(batch, &ctx->payloads[PIPE_SHADER_FRAGMENT]);
315 }
316
317 /* Corresponds to exactly one draw, but does not submit anything */
318
319 static void
320 panfrost_queue_draw(struct panfrost_context *ctx)
321 {
322 /* Handle dirty flags now */
323 panfrost_emit_for_draw(ctx);
324
325 struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
326
327 panfrost_emit_vertex_tiler_jobs(batch,
328 &ctx->payloads[PIPE_SHADER_VERTEX],
329 &ctx->payloads[PIPE_SHADER_FRAGMENT]);
330 panfrost_batch_adjust_stack_size(batch);
331 }
332
333 /* The entire frame is in memory -- send it off to the kernel! */
334
335 void
336 panfrost_flush(
337 struct pipe_context *pipe,
338 struct pipe_fence_handle **fence,
339 unsigned flags)
340 {
341 struct panfrost_context *ctx = pan_context(pipe);
342 struct util_dynarray fences;
343
344 /* We must collect the fences before the flush is done, otherwise we'll
345 * lose track of them.
346 */
347 if (fence) {
348 util_dynarray_init(&fences, NULL);
349 hash_table_foreach(ctx->batches, hentry) {
350 struct panfrost_batch *batch = hentry->data;
351
352 panfrost_batch_fence_reference(batch->out_sync);
353 util_dynarray_append(&fences,
354 struct panfrost_batch_fence *,
355 batch->out_sync);
356 }
357 }
358
359 /* Submit all pending jobs */
360 panfrost_flush_all_batches(ctx, false);
361
362 if (fence) {
363 struct panfrost_fence *f = panfrost_fence_create(ctx, &fences);
364 pipe->screen->fence_reference(pipe->screen, fence, NULL);
365 *fence = (struct pipe_fence_handle *)f;
366
367 util_dynarray_foreach(&fences, struct panfrost_batch_fence *, fence)
368 panfrost_batch_fence_unreference(*fence);
369
370 util_dynarray_fini(&fences);
371 }
372
373 if (pan_debug & PAN_DBG_TRACE)
374 pandecode_next_frame();
375 }
376
377 #define DEFINE_CASE(c) case PIPE_PRIM_##c: return MALI_##c;
378
379 static int
380 g2m_draw_mode(enum pipe_prim_type mode)
381 {
382 switch (mode) {
383 DEFINE_CASE(POINTS);
384 DEFINE_CASE(LINES);
385 DEFINE_CASE(LINE_LOOP);
386 DEFINE_CASE(LINE_STRIP);
387 DEFINE_CASE(TRIANGLES);
388 DEFINE_CASE(TRIANGLE_STRIP);
389 DEFINE_CASE(TRIANGLE_FAN);
390 DEFINE_CASE(QUADS);
391 DEFINE_CASE(QUAD_STRIP);
392 DEFINE_CASE(POLYGON);
393
394 default:
395 unreachable("Invalid draw mode");
396 }
397 }
398
399 #undef DEFINE_CASE
400
401 static unsigned
402 panfrost_translate_index_size(unsigned size)
403 {
404 switch (size) {
405 case 1:
406 return MALI_DRAW_INDEXED_UINT8;
407
408 case 2:
409 return MALI_DRAW_INDEXED_UINT16;
410
411 case 4:
412 return MALI_DRAW_INDEXED_UINT32;
413
414 default:
415 unreachable("Invalid index size");
416 }
417 }
418
419 /* Gets a GPU address for the associated index buffer. Only gauranteed to be
420 * good for the duration of the draw (transient), could last longer. Also get
421 * the bounds on the index buffer for the range accessed by the draw. We do
422 * these operations together because there are natural optimizations which
423 * require them to be together. */
424
425 static mali_ptr
426 panfrost_get_index_buffer_bounded(struct panfrost_context *ctx, const struct pipe_draw_info *info, unsigned *min_index, unsigned *max_index)
427 {
428 struct panfrost_resource *rsrc = (struct panfrost_resource *) (info->index.resource);
429
430 off_t offset = info->start * info->index_size;
431 struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
432 mali_ptr out = 0;
433
434 bool needs_indices = true;
435
436 if (info->max_index != ~0u) {
437 *min_index = info->min_index;
438 *max_index = info->max_index;
439 needs_indices = false;
440 }
441
442 if (!info->has_user_indices) {
443 /* Only resources can be directly mapped */
444 panfrost_batch_add_bo(batch, rsrc->bo,
445 PAN_BO_ACCESS_SHARED |
446 PAN_BO_ACCESS_READ |
447 PAN_BO_ACCESS_VERTEX_TILER);
448 out = rsrc->bo->gpu + offset;
449
450 /* Check the cache */
451 needs_indices = !panfrost_minmax_cache_get(rsrc->index_cache, info->start, info->count,
452 min_index, max_index);
453 } else {
454 /* Otherwise, we need to upload to transient memory */
455 const uint8_t *ibuf8 = (const uint8_t *) info->index.user;
456 out = panfrost_upload_transient(batch, ibuf8 + offset, info->count * info->index_size);
457 }
458
459 if (needs_indices) {
460 /* Fallback */
461 u_vbuf_get_minmax_index(&ctx->base, info, min_index, max_index);
462
463 if (!info->has_user_indices) {
464 panfrost_minmax_cache_add(rsrc->index_cache, info->start, info->count,
465 *min_index, *max_index);
466 }
467 }
468
469
470 return out;
471 }
472
473 static bool
474 panfrost_scissor_culls_everything(struct panfrost_context *ctx)
475 {
476 const struct pipe_scissor_state *ss = &ctx->scissor;
477
478 /* Check if we're scissoring at all */
479
480 if (!(ctx->rasterizer && ctx->rasterizer->base.scissor))
481 return false;
482
483 return (ss->minx == ss->maxx) || (ss->miny == ss->maxy);
484 }
485
486 /* Count generated primitives (when there is no geom/tess shaders) for
487 * transform feedback */
488
489 static void
490 panfrost_statistics_record(
491 struct panfrost_context *ctx,
492 const struct pipe_draw_info *info)
493 {
494 if (!ctx->active_queries)
495 return;
496
497 uint32_t prims = u_prims_for_vertices(info->mode, info->count);
498 ctx->prims_generated += prims;
499
500 if (!ctx->streamout.num_targets)
501 return;
502
503 ctx->tf_prims_generated += prims;
504 }
505
506 static void
507 panfrost_draw_vbo(
508 struct pipe_context *pipe,
509 const struct pipe_draw_info *info)
510 {
511 struct panfrost_context *ctx = pan_context(pipe);
512
513 /* First of all, check the scissor to see if anything is drawn at all.
514 * If it's not, we drop the draw (mostly a conformance issue;
515 * well-behaved apps shouldn't hit this) */
516
517 if (panfrost_scissor_culls_everything(ctx))
518 return;
519
520 int mode = info->mode;
521
522 /* Fallback unsupported restart index */
523 unsigned primitive_index = (1 << (info->index_size * 8)) - 1;
524
525 if (info->primitive_restart && info->index_size
526 && info->restart_index != primitive_index) {
527 util_draw_vbo_without_prim_restart(pipe, info);
528 return;
529 }
530
531 /* Fallback for unsupported modes */
532
533 assert(ctx->rasterizer != NULL);
534
535 if (!(ctx->draw_modes & (1 << mode))) {
536 if (mode == PIPE_PRIM_QUADS && info->count == 4 && !ctx->rasterizer->base.flatshade) {
537 mode = PIPE_PRIM_TRIANGLE_FAN;
538 } else {
539 if (info->count < 4) {
540 /* Degenerate case? */
541 return;
542 }
543
544 util_primconvert_save_rasterizer_state(ctx->primconvert, &ctx->rasterizer->base);
545 util_primconvert_draw_vbo(ctx->primconvert, info);
546 return;
547 }
548 }
549
550 ctx->payloads[PIPE_SHADER_VERTEX].offset_start = info->start;
551 ctx->payloads[PIPE_SHADER_FRAGMENT].offset_start = info->start;
552
553 /* Now that we have a guaranteed terminating path, find the job.
554 * Assignment commented out to prevent unused warning */
555
556 /* struct panfrost_batch *batch = */ panfrost_get_batch_for_fbo(ctx);
557
558 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.draw_mode = g2m_draw_mode(mode);
559
560 /* Take into account a negative bias */
561 ctx->vertex_count = info->count + abs(info->index_bias);
562 ctx->instance_count = info->instance_count;
563 ctx->active_prim = info->mode;
564
565 /* For non-indexed draws, they're the same */
566 unsigned vertex_count = ctx->vertex_count;
567
568 unsigned draw_flags = 0;
569
570 /* The draw flags interpret how primitive size is interpreted */
571
572 if (panfrost_writes_point_size(ctx))
573 draw_flags |= MALI_DRAW_VARYING_SIZE;
574
575 if (info->primitive_restart)
576 draw_flags |= MALI_DRAW_PRIMITIVE_RESTART_FIXED_INDEX;
577
578 /* These doesn't make much sense */
579
580 draw_flags |= 0x3000;
581
582 if (ctx->rasterizer && ctx->rasterizer->base.flatshade_first)
583 draw_flags |= MALI_DRAW_FLATSHADE_FIRST;
584
585 panfrost_statistics_record(ctx, info);
586
587 if (info->index_size) {
588 unsigned min_index = 0, max_index = 0;
589 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.indices =
590 panfrost_get_index_buffer_bounded(ctx, info, &min_index, &max_index);
591
592 /* Use the corresponding values */
593 vertex_count = max_index - min_index + 1;
594 ctx->payloads[PIPE_SHADER_VERTEX].offset_start = min_index + info->index_bias;
595 ctx->payloads[PIPE_SHADER_FRAGMENT].offset_start = min_index + info->index_bias;
596
597 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.offset_bias_correction = -min_index;
598 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.index_count = MALI_POSITIVE(info->count);
599
600 draw_flags |= panfrost_translate_index_size(info->index_size);
601 } else {
602 /* Index count == vertex count, if no indexing is applied, as
603 * if it is internally indexed in the expected order */
604
605 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.offset_bias_correction = 0;
606 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.index_count = MALI_POSITIVE(ctx->vertex_count);
607
608 /* Reverse index state */
609 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.indices = (mali_ptr) 0;
610 }
611
612 /* Dispatch "compute jobs" for the vertex/tiler pair as (1,
613 * vertex_count, 1) */
614
615 panfrost_pack_work_groups_fused(
616 &ctx->payloads[PIPE_SHADER_VERTEX].prefix,
617 &ctx->payloads[PIPE_SHADER_FRAGMENT].prefix,
618 1, vertex_count, info->instance_count,
619 1, 1, 1);
620
621 ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.unknown_draw = draw_flags;
622
623 /* Encode the padded vertex count */
624
625 if (info->instance_count > 1) {
626 ctx->padded_count = panfrost_padded_vertex_count(vertex_count);
627
628 unsigned shift = __builtin_ctz(ctx->padded_count);
629 unsigned k = ctx->padded_count >> (shift + 1);
630
631 ctx->payloads[PIPE_SHADER_VERTEX].instance_shift = shift;
632 ctx->payloads[PIPE_SHADER_FRAGMENT].instance_shift = shift;
633
634 ctx->payloads[PIPE_SHADER_VERTEX].instance_odd = k;
635 ctx->payloads[PIPE_SHADER_FRAGMENT].instance_odd = k;
636 } else {
637 ctx->padded_count = vertex_count;
638
639 /* Reset instancing state */
640 ctx->payloads[PIPE_SHADER_VERTEX].instance_shift = 0;
641 ctx->payloads[PIPE_SHADER_VERTEX].instance_odd = 0;
642 ctx->payloads[PIPE_SHADER_FRAGMENT].instance_shift = 0;
643 ctx->payloads[PIPE_SHADER_FRAGMENT].instance_odd = 0;
644 }
645
646 /* Fire off the draw itself */
647 panfrost_queue_draw(ctx);
648
649 /* Increment transform feedback offsets */
650
651 for (unsigned i = 0; i < ctx->streamout.num_targets; ++i) {
652 unsigned output_count = u_stream_outputs_for_vertices(
653 ctx->active_prim, ctx->vertex_count);
654
655 ctx->streamout.offsets[i] += output_count;
656 }
657 }
658
659 /* CSO state */
660
661 static void
662 panfrost_generic_cso_delete(struct pipe_context *pctx, void *hwcso)
663 {
664 free(hwcso);
665 }
666
667 static void *
668 panfrost_create_rasterizer_state(
669 struct pipe_context *pctx,
670 const struct pipe_rasterizer_state *cso)
671 {
672 struct panfrost_rasterizer *so = CALLOC_STRUCT(panfrost_rasterizer);
673
674 so->base = *cso;
675
676 return so;
677 }
678
679 static void
680 panfrost_bind_rasterizer_state(
681 struct pipe_context *pctx,
682 void *hwcso)
683 {
684 struct panfrost_context *ctx = pan_context(pctx);
685
686 ctx->rasterizer = hwcso;
687
688 if (!hwcso)
689 return;
690
691 /* Gauranteed with the core GL call, so don't expose ARB_polygon_offset */
692 assert(ctx->rasterizer->base.offset_clamp == 0.0);
693
694 /* Point sprites are emulated */
695
696 struct panfrost_shader_state *variant = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT);
697
698 if (ctx->rasterizer->base.sprite_coord_enable || (variant && variant->point_sprite_mask))
699 ctx->base.bind_fs_state(&ctx->base, ctx->shader[PIPE_SHADER_FRAGMENT]);
700 }
701
702 static void *
703 panfrost_create_vertex_elements_state(
704 struct pipe_context *pctx,
705 unsigned num_elements,
706 const struct pipe_vertex_element *elements)
707 {
708 struct panfrost_vertex_state *so = CALLOC_STRUCT(panfrost_vertex_state);
709
710 so->num_elements = num_elements;
711 memcpy(so->pipe, elements, sizeof(*elements) * num_elements);
712
713 for (int i = 0; i < num_elements; ++i) {
714 so->hw[i].index = i;
715
716 enum pipe_format fmt = elements[i].src_format;
717 const struct util_format_description *desc = util_format_description(fmt);
718 so->hw[i].unknown1 = 0x2;
719 so->hw[i].swizzle = panfrost_get_default_swizzle(desc->nr_channels);
720
721 so->hw[i].format = panfrost_find_format(desc);
722 }
723
724 /* Let's also prepare vertex builtins */
725 so->hw[PAN_VERTEX_ID].format = MALI_R32UI;
726 so->hw[PAN_VERTEX_ID].swizzle = panfrost_get_default_swizzle(1);
727 so->hw[PAN_INSTANCE_ID].format = MALI_R32UI;
728 so->hw[PAN_INSTANCE_ID].swizzle = panfrost_get_default_swizzle(1);
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 }