panfrost: Ignore BO start addr when adjusting src_offset
[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
229 /* Adjust by the masked off bits of the offset. Make sure we
230 * read src_offset from so->hw (which is not GPU visible)
231 * rather than target (which is) due to caching effects */
232
233 unsigned src_offset = so->pipe[i].src_offset;
234
235 /* BOs aligned to 4k so guaranteed aligned to 64 */
236 src_offset += (buf->buffer_offset & 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
727 return so;
728 }
729
730 static void
731 panfrost_bind_vertex_elements_state(
732 struct pipe_context *pctx,
733 void *hwcso)
734 {
735 struct panfrost_context *ctx = pan_context(pctx);
736 ctx->vertex = hwcso;
737 }
738
739 static void *
740 panfrost_create_shader_state(
741 struct pipe_context *pctx,
742 const struct pipe_shader_state *cso,
743 enum pipe_shader_type stage)
744 {
745 struct panfrost_shader_variants *so = CALLOC_STRUCT(panfrost_shader_variants);
746 so->base = *cso;
747
748 /* Token deep copy to prevent memory corruption */
749
750 if (cso->type == PIPE_SHADER_IR_TGSI)
751 so->base.tokens = tgsi_dup_tokens(so->base.tokens);
752
753 /* Precompile for shader-db if we need to */
754 if (unlikely((pan_debug & PAN_DBG_PRECOMPILE) && cso->type == PIPE_SHADER_IR_NIR)) {
755 struct panfrost_context *ctx = pan_context(pctx);
756
757 struct panfrost_shader_state state;
758 uint64_t outputs_written;
759
760 panfrost_shader_compile(ctx, PIPE_SHADER_IR_NIR,
761 so->base.ir.nir,
762 tgsi_processor_to_shader_stage(stage),
763 &state, &outputs_written);
764 }
765
766 return so;
767 }
768
769 static void
770 panfrost_delete_shader_state(
771 struct pipe_context *pctx,
772 void *so)
773 {
774 struct panfrost_shader_variants *cso = (struct panfrost_shader_variants *) so;
775
776 if (cso->base.type == PIPE_SHADER_IR_TGSI) {
777 DBG("Deleting TGSI shader leaks duplicated tokens\n");
778 }
779
780 for (unsigned i = 0; i < cso->variant_count; ++i) {
781 struct panfrost_shader_state *shader_state = &cso->variants[i];
782 panfrost_bo_unreference(shader_state->bo);
783 shader_state->bo = NULL;
784 }
785 free(cso->variants);
786
787 free(so);
788 }
789
790 static void *
791 panfrost_create_sampler_state(
792 struct pipe_context *pctx,
793 const struct pipe_sampler_state *cso)
794 {
795 struct panfrost_sampler_state *so = CALLOC_STRUCT(panfrost_sampler_state);
796 so->base = *cso;
797
798 panfrost_sampler_desc_init(cso, &so->hw);
799
800 return so;
801 }
802
803 static void
804 panfrost_bind_sampler_states(
805 struct pipe_context *pctx,
806 enum pipe_shader_type shader,
807 unsigned start_slot, unsigned num_sampler,
808 void **sampler)
809 {
810 assert(start_slot == 0);
811
812 struct panfrost_context *ctx = pan_context(pctx);
813
814 /* XXX: Should upload, not just copy? */
815 ctx->sampler_count[shader] = num_sampler;
816 memcpy(ctx->samplers[shader], sampler, num_sampler * sizeof (void *));
817 }
818
819 static bool
820 panfrost_variant_matches(
821 struct panfrost_context *ctx,
822 struct panfrost_shader_state *variant,
823 enum pipe_shader_type type)
824 {
825 struct pipe_rasterizer_state *rasterizer = &ctx->rasterizer->base;
826 struct pipe_alpha_state *alpha = &ctx->depth_stencil->alpha;
827
828 bool is_fragment = (type == PIPE_SHADER_FRAGMENT);
829
830 if (is_fragment && (alpha->enabled || variant->alpha_state.enabled)) {
831 /* Make sure enable state is at least the same */
832 if (alpha->enabled != variant->alpha_state.enabled) {
833 return false;
834 }
835
836 /* Check that the contents of the test are the same */
837 bool same_func = alpha->func == variant->alpha_state.func;
838 bool same_ref = alpha->ref_value == variant->alpha_state.ref_value;
839
840 if (!(same_func && same_ref)) {
841 return false;
842 }
843 }
844
845 if (is_fragment && rasterizer && (rasterizer->sprite_coord_enable |
846 variant->point_sprite_mask)) {
847 /* Ensure the same varyings are turned to point sprites */
848 if (rasterizer->sprite_coord_enable != variant->point_sprite_mask)
849 return false;
850
851 /* Ensure the orientation is correct */
852 bool upper_left =
853 rasterizer->sprite_coord_mode ==
854 PIPE_SPRITE_COORD_UPPER_LEFT;
855
856 if (variant->point_sprite_upper_left != upper_left)
857 return false;
858 }
859
860 /* Otherwise, we're good to go */
861 return true;
862 }
863
864 /**
865 * Fix an uncompiled shader's stream output info, and produce a bitmask
866 * of which VARYING_SLOT_* are captured for stream output.
867 *
868 * Core Gallium stores output->register_index as a "slot" number, where
869 * slots are assigned consecutively to all outputs in info->outputs_written.
870 * This naive packing of outputs doesn't work for us - we too have slots,
871 * but the layout is defined by the VUE map, which we won't have until we
872 * compile a specific shader variant. So, we remap these and simply store
873 * VARYING_SLOT_* in our copy's output->register_index fields.
874 *
875 * We then produce a bitmask of outputs which are used for SO.
876 *
877 * Implementation from iris.
878 */
879
880 static uint64_t
881 update_so_info(struct pipe_stream_output_info *so_info,
882 uint64_t outputs_written)
883 {
884 uint64_t so_outputs = 0;
885 uint8_t reverse_map[64] = {0};
886 unsigned slot = 0;
887
888 while (outputs_written)
889 reverse_map[slot++] = u_bit_scan64(&outputs_written);
890
891 for (unsigned i = 0; i < so_info->num_outputs; i++) {
892 struct pipe_stream_output *output = &so_info->output[i];
893
894 /* Map Gallium's condensed "slots" back to real VARYING_SLOT_* enums */
895 output->register_index = reverse_map[output->register_index];
896
897 so_outputs |= 1ull << output->register_index;
898 }
899
900 return so_outputs;
901 }
902
903 static void
904 panfrost_bind_shader_state(
905 struct pipe_context *pctx,
906 void *hwcso,
907 enum pipe_shader_type type)
908 {
909 struct panfrost_context *ctx = pan_context(pctx);
910 ctx->shader[type] = hwcso;
911
912 if (!hwcso) return;
913
914 /* Match the appropriate variant */
915
916 signed variant = -1;
917 struct panfrost_shader_variants *variants = (struct panfrost_shader_variants *) hwcso;
918
919 for (unsigned i = 0; i < variants->variant_count; ++i) {
920 if (panfrost_variant_matches(ctx, &variants->variants[i], type)) {
921 variant = i;
922 break;
923 }
924 }
925
926 if (variant == -1) {
927 /* No variant matched, so create a new one */
928 variant = variants->variant_count++;
929
930 if (variants->variant_count > variants->variant_space) {
931 unsigned old_space = variants->variant_space;
932
933 variants->variant_space *= 2;
934 if (variants->variant_space == 0)
935 variants->variant_space = 1;
936
937 /* Arbitrary limit to stop runaway programs from
938 * creating an unbounded number of shader variants. */
939 assert(variants->variant_space < 1024);
940
941 unsigned msize = sizeof(struct panfrost_shader_state);
942 variants->variants = realloc(variants->variants,
943 variants->variant_space * msize);
944
945 memset(&variants->variants[old_space], 0,
946 (variants->variant_space - old_space) * msize);
947 }
948
949 struct panfrost_shader_state *v =
950 &variants->variants[variant];
951
952 if (type == PIPE_SHADER_FRAGMENT) {
953 v->alpha_state = ctx->depth_stencil->alpha;
954
955 if (ctx->rasterizer) {
956 v->point_sprite_mask = ctx->rasterizer->base.sprite_coord_enable;
957 v->point_sprite_upper_left =
958 ctx->rasterizer->base.sprite_coord_mode ==
959 PIPE_SPRITE_COORD_UPPER_LEFT;
960 }
961 }
962 }
963
964 /* Select this variant */
965 variants->active_variant = variant;
966
967 struct panfrost_shader_state *shader_state = &variants->variants[variant];
968 assert(panfrost_variant_matches(ctx, shader_state, type));
969
970 /* We finally have a variant, so compile it */
971
972 if (!shader_state->compiled) {
973 uint64_t outputs_written = 0;
974
975 panfrost_shader_compile(ctx, variants->base.type,
976 variants->base.type == PIPE_SHADER_IR_NIR ?
977 variants->base.ir.nir :
978 variants->base.tokens,
979 tgsi_processor_to_shader_stage(type),
980 shader_state,
981 &outputs_written);
982
983 shader_state->compiled = true;
984
985 /* Fixup the stream out information, since what Gallium returns
986 * normally is mildly insane */
987
988 shader_state->stream_output = variants->base.stream_output;
989 shader_state->so_mask =
990 update_so_info(&shader_state->stream_output, outputs_written);
991 }
992 }
993
994 static void *
995 panfrost_create_vs_state(struct pipe_context *pctx, const struct pipe_shader_state *hwcso)
996 {
997 return panfrost_create_shader_state(pctx, hwcso, PIPE_SHADER_VERTEX);
998 }
999
1000 static void *
1001 panfrost_create_fs_state(struct pipe_context *pctx, const struct pipe_shader_state *hwcso)
1002 {
1003 return panfrost_create_shader_state(pctx, hwcso, PIPE_SHADER_FRAGMENT);
1004 }
1005
1006 static void
1007 panfrost_bind_vs_state(struct pipe_context *pctx, void *hwcso)
1008 {
1009 panfrost_bind_shader_state(pctx, hwcso, PIPE_SHADER_VERTEX);
1010 }
1011
1012 static void
1013 panfrost_bind_fs_state(struct pipe_context *pctx, void *hwcso)
1014 {
1015 panfrost_bind_shader_state(pctx, hwcso, PIPE_SHADER_FRAGMENT);
1016 }
1017
1018 static void
1019 panfrost_set_vertex_buffers(
1020 struct pipe_context *pctx,
1021 unsigned start_slot,
1022 unsigned num_buffers,
1023 const struct pipe_vertex_buffer *buffers)
1024 {
1025 struct panfrost_context *ctx = pan_context(pctx);
1026
1027 util_set_vertex_buffers_mask(ctx->vertex_buffers, &ctx->vb_mask, buffers, start_slot, num_buffers);
1028 }
1029
1030 static void
1031 panfrost_set_constant_buffer(
1032 struct pipe_context *pctx,
1033 enum pipe_shader_type shader, uint index,
1034 const struct pipe_constant_buffer *buf)
1035 {
1036 struct panfrost_context *ctx = pan_context(pctx);
1037 struct panfrost_constant_buffer *pbuf = &ctx->constant_buffer[shader];
1038
1039 util_copy_constant_buffer(&pbuf->cb[index], buf);
1040
1041 unsigned mask = (1 << index);
1042
1043 if (unlikely(!buf)) {
1044 pbuf->enabled_mask &= ~mask;
1045 pbuf->dirty_mask &= ~mask;
1046 return;
1047 }
1048
1049 pbuf->enabled_mask |= mask;
1050 pbuf->dirty_mask |= mask;
1051 }
1052
1053 static void
1054 panfrost_set_stencil_ref(
1055 struct pipe_context *pctx,
1056 const struct pipe_stencil_ref *ref)
1057 {
1058 struct panfrost_context *ctx = pan_context(pctx);
1059 ctx->stencil_ref = *ref;
1060 }
1061
1062 static enum mali_texture_type
1063 panfrost_translate_texture_type(enum pipe_texture_target t) {
1064 switch (t)
1065 {
1066 case PIPE_BUFFER:
1067 case PIPE_TEXTURE_1D:
1068 case PIPE_TEXTURE_1D_ARRAY:
1069 return MALI_TEX_1D;
1070
1071 case PIPE_TEXTURE_2D:
1072 case PIPE_TEXTURE_2D_ARRAY:
1073 case PIPE_TEXTURE_RECT:
1074 return MALI_TEX_2D;
1075
1076 case PIPE_TEXTURE_3D:
1077 return MALI_TEX_3D;
1078
1079 case PIPE_TEXTURE_CUBE:
1080 case PIPE_TEXTURE_CUBE_ARRAY:
1081 return MALI_TEX_CUBE;
1082
1083 default:
1084 unreachable("Unknown target");
1085 }
1086 }
1087
1088 static struct pipe_sampler_view *
1089 panfrost_create_sampler_view(
1090 struct pipe_context *pctx,
1091 struct pipe_resource *texture,
1092 const struct pipe_sampler_view *template)
1093 {
1094 struct panfrost_screen *screen = pan_screen(pctx->screen);
1095 struct panfrost_sampler_view *so = rzalloc(pctx, struct panfrost_sampler_view);
1096
1097 pipe_reference(NULL, &texture->reference);
1098
1099 struct panfrost_resource *prsrc = (struct panfrost_resource *) texture;
1100 assert(prsrc->bo);
1101
1102 so->base = *template;
1103 so->base.texture = texture;
1104 so->base.reference.count = 1;
1105 so->base.context = pctx;
1106
1107 unsigned char user_swizzle[4] = {
1108 template->swizzle_r,
1109 template->swizzle_g,
1110 template->swizzle_b,
1111 template->swizzle_a
1112 };
1113
1114 /* In the hardware, array_size refers specifically to array textures,
1115 * whereas in Gallium, it also covers cubemaps */
1116
1117 unsigned array_size = texture->array_size;
1118
1119 if (template->target == PIPE_TEXTURE_CUBE) {
1120 /* TODO: Cubemap arrays */
1121 assert(array_size == 6);
1122 array_size /= 6;
1123 }
1124
1125 enum mali_texture_type type =
1126 panfrost_translate_texture_type(template->target);
1127
1128 unsigned size = panfrost_estimate_texture_size(
1129 template->u.tex.first_level,
1130 template->u.tex.last_level,
1131 template->u.tex.first_layer,
1132 template->u.tex.last_layer,
1133 type, prsrc->layout);
1134
1135 so->bo = panfrost_bo_create(screen, size, 0);
1136
1137 panfrost_new_texture(
1138 so->bo->cpu,
1139 texture->width0, texture->height0,
1140 texture->depth0, array_size,
1141 template->format,
1142 type, prsrc->layout,
1143 template->u.tex.first_level,
1144 template->u.tex.last_level,
1145 template->u.tex.first_layer,
1146 template->u.tex.last_layer,
1147 prsrc->cubemap_stride,
1148 panfrost_translate_swizzle_4(user_swizzle),
1149 prsrc->bo->gpu,
1150 prsrc->slices);
1151
1152 return (struct pipe_sampler_view *) so;
1153 }
1154
1155 static void
1156 panfrost_set_sampler_views(
1157 struct pipe_context *pctx,
1158 enum pipe_shader_type shader,
1159 unsigned start_slot, unsigned num_views,
1160 struct pipe_sampler_view **views)
1161 {
1162 struct panfrost_context *ctx = pan_context(pctx);
1163 unsigned new_nr = 0;
1164 unsigned i;
1165
1166 assert(start_slot == 0);
1167
1168 for (i = 0; i < num_views; ++i) {
1169 if (views[i])
1170 new_nr = i + 1;
1171 pipe_sampler_view_reference((struct pipe_sampler_view **)&ctx->sampler_views[shader][i],
1172 views[i]);
1173 }
1174
1175 for (; i < ctx->sampler_view_count[shader]; i++) {
1176 pipe_sampler_view_reference((struct pipe_sampler_view **)&ctx->sampler_views[shader][i],
1177 NULL);
1178 }
1179 ctx->sampler_view_count[shader] = new_nr;
1180 }
1181
1182 static void
1183 panfrost_sampler_view_destroy(
1184 struct pipe_context *pctx,
1185 struct pipe_sampler_view *pview)
1186 {
1187 struct panfrost_sampler_view *view = (struct panfrost_sampler_view *) pview;
1188
1189 pipe_resource_reference(&pview->texture, NULL);
1190 panfrost_bo_unreference(view->bo);
1191 ralloc_free(view);
1192 }
1193
1194 static void
1195 panfrost_set_shader_buffers(
1196 struct pipe_context *pctx,
1197 enum pipe_shader_type shader,
1198 unsigned start, unsigned count,
1199 const struct pipe_shader_buffer *buffers,
1200 unsigned writable_bitmask)
1201 {
1202 struct panfrost_context *ctx = pan_context(pctx);
1203
1204 util_set_shader_buffers_mask(ctx->ssbo[shader], &ctx->ssbo_mask[shader],
1205 buffers, start, count);
1206 }
1207
1208 /* Hints that a framebuffer should use AFBC where possible */
1209
1210 static void
1211 panfrost_hint_afbc(
1212 struct panfrost_screen *screen,
1213 const struct pipe_framebuffer_state *fb)
1214 {
1215 /* AFBC implemenation incomplete; hide it */
1216 if (!(pan_debug & PAN_DBG_AFBC)) return;
1217
1218 /* Hint AFBC to the resources bound to each color buffer */
1219
1220 for (unsigned i = 0; i < fb->nr_cbufs; ++i) {
1221 struct pipe_surface *surf = fb->cbufs[i];
1222 struct panfrost_resource *rsrc = pan_resource(surf->texture);
1223 panfrost_resource_hint_layout(screen, rsrc, MALI_TEXTURE_AFBC, 1);
1224 }
1225
1226 /* Also hint it to the depth buffer */
1227
1228 if (fb->zsbuf) {
1229 struct panfrost_resource *rsrc = pan_resource(fb->zsbuf->texture);
1230 panfrost_resource_hint_layout(screen, rsrc, MALI_TEXTURE_AFBC, 1);
1231 }
1232 }
1233
1234 static void
1235 panfrost_set_framebuffer_state(struct pipe_context *pctx,
1236 const struct pipe_framebuffer_state *fb)
1237 {
1238 struct panfrost_context *ctx = pan_context(pctx);
1239
1240 panfrost_hint_afbc(pan_screen(pctx->screen), fb);
1241 util_copy_framebuffer_state(&ctx->pipe_framebuffer, fb);
1242 ctx->batch = NULL;
1243 panfrost_invalidate_frame(ctx);
1244 }
1245
1246 static void *
1247 panfrost_create_depth_stencil_state(struct pipe_context *pipe,
1248 const struct pipe_depth_stencil_alpha_state *depth_stencil)
1249 {
1250 return mem_dup(depth_stencil, sizeof(*depth_stencil));
1251 }
1252
1253 static void
1254 panfrost_bind_depth_stencil_state(struct pipe_context *pipe,
1255 void *cso)
1256 {
1257 struct panfrost_context *ctx = pan_context(pipe);
1258 struct pipe_depth_stencil_alpha_state *depth_stencil = cso;
1259 ctx->depth_stencil = depth_stencil;
1260
1261 if (!depth_stencil)
1262 return;
1263
1264 /* Alpha does not exist in the hardware (it's not in ES3), so it's
1265 * emulated in the fragment shader */
1266
1267 if (depth_stencil->alpha.enabled) {
1268 /* We need to trigger a new shader (maybe) */
1269 ctx->base.bind_fs_state(&ctx->base, ctx->shader[PIPE_SHADER_FRAGMENT]);
1270 }
1271
1272 /* Bounds test not implemented */
1273 assert(!depth_stencil->depth.bounds_test);
1274 }
1275
1276 static void
1277 panfrost_delete_depth_stencil_state(struct pipe_context *pipe, void *depth)
1278 {
1279 free( depth );
1280 }
1281
1282 static void
1283 panfrost_set_sample_mask(struct pipe_context *pipe,
1284 unsigned sample_mask)
1285 {
1286 }
1287
1288 static void
1289 panfrost_set_clip_state(struct pipe_context *pipe,
1290 const struct pipe_clip_state *clip)
1291 {
1292 //struct panfrost_context *panfrost = pan_context(pipe);
1293 }
1294
1295 static void
1296 panfrost_set_viewport_states(struct pipe_context *pipe,
1297 unsigned start_slot,
1298 unsigned num_viewports,
1299 const struct pipe_viewport_state *viewports)
1300 {
1301 struct panfrost_context *ctx = pan_context(pipe);
1302
1303 assert(start_slot == 0);
1304 assert(num_viewports == 1);
1305
1306 ctx->pipe_viewport = *viewports;
1307 }
1308
1309 static void
1310 panfrost_set_scissor_states(struct pipe_context *pipe,
1311 unsigned start_slot,
1312 unsigned num_scissors,
1313 const struct pipe_scissor_state *scissors)
1314 {
1315 struct panfrost_context *ctx = pan_context(pipe);
1316
1317 assert(start_slot == 0);
1318 assert(num_scissors == 1);
1319
1320 ctx->scissor = *scissors;
1321 }
1322
1323 static void
1324 panfrost_set_polygon_stipple(struct pipe_context *pipe,
1325 const struct pipe_poly_stipple *stipple)
1326 {
1327 //struct panfrost_context *panfrost = pan_context(pipe);
1328 }
1329
1330 static void
1331 panfrost_set_active_query_state(struct pipe_context *pipe,
1332 bool enable)
1333 {
1334 struct panfrost_context *ctx = pan_context(pipe);
1335 ctx->active_queries = enable;
1336 }
1337
1338 static void
1339 panfrost_destroy(struct pipe_context *pipe)
1340 {
1341 struct panfrost_context *panfrost = pan_context(pipe);
1342
1343 if (panfrost->blitter)
1344 util_blitter_destroy(panfrost->blitter);
1345
1346 if (panfrost->blitter_wallpaper)
1347 util_blitter_destroy(panfrost->blitter_wallpaper);
1348
1349 util_unreference_framebuffer_state(&panfrost->pipe_framebuffer);
1350 u_upload_destroy(pipe->stream_uploader);
1351
1352 ralloc_free(pipe);
1353 }
1354
1355 static struct pipe_query *
1356 panfrost_create_query(struct pipe_context *pipe,
1357 unsigned type,
1358 unsigned index)
1359 {
1360 struct panfrost_query *q = rzalloc(pipe, struct panfrost_query);
1361
1362 q->type = type;
1363 q->index = index;
1364
1365 return (struct pipe_query *) q;
1366 }
1367
1368 static void
1369 panfrost_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
1370 {
1371 struct panfrost_query *query = (struct panfrost_query *) q;
1372
1373 if (query->bo) {
1374 panfrost_bo_unreference(query->bo);
1375 query->bo = NULL;
1376 }
1377
1378 ralloc_free(q);
1379 }
1380
1381 static bool
1382 panfrost_begin_query(struct pipe_context *pipe, struct pipe_query *q)
1383 {
1384 struct panfrost_context *ctx = pan_context(pipe);
1385 struct panfrost_query *query = (struct panfrost_query *) q;
1386
1387 switch (query->type) {
1388 case PIPE_QUERY_OCCLUSION_COUNTER:
1389 case PIPE_QUERY_OCCLUSION_PREDICATE:
1390 case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
1391 /* Allocate a bo for the query results to be stored */
1392 if (!query->bo) {
1393 query->bo = panfrost_bo_create(
1394 pan_screen(ctx->base.screen),
1395 sizeof(unsigned), 0);
1396 }
1397
1398 unsigned *result = (unsigned *)query->bo->cpu;
1399 *result = 0; /* Default to 0 if nothing at all drawn. */
1400 ctx->occlusion_query = query;
1401 break;
1402
1403 /* Geometry statistics are computed in the driver. XXX: geom/tess
1404 * shaders.. */
1405
1406 case PIPE_QUERY_PRIMITIVES_GENERATED:
1407 query->start = ctx->prims_generated;
1408 break;
1409 case PIPE_QUERY_PRIMITIVES_EMITTED:
1410 query->start = ctx->tf_prims_generated;
1411 break;
1412
1413 default:
1414 DBG("Skipping query %u\n", query->type);
1415 break;
1416 }
1417
1418 return true;
1419 }
1420
1421 static bool
1422 panfrost_end_query(struct pipe_context *pipe, struct pipe_query *q)
1423 {
1424 struct panfrost_context *ctx = pan_context(pipe);
1425 struct panfrost_query *query = (struct panfrost_query *) q;
1426
1427 switch (query->type) {
1428 case PIPE_QUERY_OCCLUSION_COUNTER:
1429 case PIPE_QUERY_OCCLUSION_PREDICATE:
1430 case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
1431 ctx->occlusion_query = NULL;
1432 break;
1433 case PIPE_QUERY_PRIMITIVES_GENERATED:
1434 query->end = ctx->prims_generated;
1435 break;
1436 case PIPE_QUERY_PRIMITIVES_EMITTED:
1437 query->end = ctx->tf_prims_generated;
1438 break;
1439 }
1440
1441 return true;
1442 }
1443
1444 static bool
1445 panfrost_get_query_result(struct pipe_context *pipe,
1446 struct pipe_query *q,
1447 bool wait,
1448 union pipe_query_result *vresult)
1449 {
1450 struct panfrost_query *query = (struct panfrost_query *) q;
1451 struct panfrost_context *ctx = pan_context(pipe);
1452
1453
1454 switch (query->type) {
1455 case PIPE_QUERY_OCCLUSION_COUNTER:
1456 case PIPE_QUERY_OCCLUSION_PREDICATE:
1457 case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
1458 /* Flush first */
1459 panfrost_flush_all_batches(ctx, true);
1460
1461 /* Read back the query results */
1462 unsigned *result = (unsigned *) query->bo->cpu;
1463 unsigned passed = *result;
1464
1465 if (query->type == PIPE_QUERY_OCCLUSION_COUNTER) {
1466 vresult->u64 = passed;
1467 } else {
1468 vresult->b = !!passed;
1469 }
1470
1471 break;
1472
1473 case PIPE_QUERY_PRIMITIVES_GENERATED:
1474 case PIPE_QUERY_PRIMITIVES_EMITTED:
1475 panfrost_flush_all_batches(ctx, true);
1476 vresult->u64 = query->end - query->start;
1477 break;
1478
1479 default:
1480 DBG("Skipped query get %u\n", query->type);
1481 break;
1482 }
1483
1484 return true;
1485 }
1486
1487 static struct pipe_stream_output_target *
1488 panfrost_create_stream_output_target(struct pipe_context *pctx,
1489 struct pipe_resource *prsc,
1490 unsigned buffer_offset,
1491 unsigned buffer_size)
1492 {
1493 struct pipe_stream_output_target *target;
1494
1495 target = rzalloc(pctx, struct pipe_stream_output_target);
1496
1497 if (!target)
1498 return NULL;
1499
1500 pipe_reference_init(&target->reference, 1);
1501 pipe_resource_reference(&target->buffer, prsc);
1502
1503 target->context = pctx;
1504 target->buffer_offset = buffer_offset;
1505 target->buffer_size = buffer_size;
1506
1507 return target;
1508 }
1509
1510 static void
1511 panfrost_stream_output_target_destroy(struct pipe_context *pctx,
1512 struct pipe_stream_output_target *target)
1513 {
1514 pipe_resource_reference(&target->buffer, NULL);
1515 ralloc_free(target);
1516 }
1517
1518 static void
1519 panfrost_set_stream_output_targets(struct pipe_context *pctx,
1520 unsigned num_targets,
1521 struct pipe_stream_output_target **targets,
1522 const unsigned *offsets)
1523 {
1524 struct panfrost_context *ctx = pan_context(pctx);
1525 struct panfrost_streamout *so = &ctx->streamout;
1526
1527 assert(num_targets <= ARRAY_SIZE(so->targets));
1528
1529 for (unsigned i = 0; i < num_targets; i++) {
1530 if (offsets[i] != -1)
1531 so->offsets[i] = offsets[i];
1532
1533 pipe_so_target_reference(&so->targets[i], targets[i]);
1534 }
1535
1536 for (unsigned i = 0; i < so->num_targets; i++)
1537 pipe_so_target_reference(&so->targets[i], NULL);
1538
1539 so->num_targets = num_targets;
1540 }
1541
1542 struct pipe_context *
1543 panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
1544 {
1545 struct panfrost_context *ctx = rzalloc(screen, struct panfrost_context);
1546 struct pipe_context *gallium = (struct pipe_context *) ctx;
1547
1548 gallium->screen = screen;
1549
1550 gallium->destroy = panfrost_destroy;
1551
1552 gallium->set_framebuffer_state = panfrost_set_framebuffer_state;
1553
1554 gallium->flush = panfrost_flush;
1555 gallium->clear = panfrost_clear;
1556 gallium->draw_vbo = panfrost_draw_vbo;
1557
1558 gallium->set_vertex_buffers = panfrost_set_vertex_buffers;
1559 gallium->set_constant_buffer = panfrost_set_constant_buffer;
1560 gallium->set_shader_buffers = panfrost_set_shader_buffers;
1561
1562 gallium->set_stencil_ref = panfrost_set_stencil_ref;
1563
1564 gallium->create_sampler_view = panfrost_create_sampler_view;
1565 gallium->set_sampler_views = panfrost_set_sampler_views;
1566 gallium->sampler_view_destroy = panfrost_sampler_view_destroy;
1567
1568 gallium->create_rasterizer_state = panfrost_create_rasterizer_state;
1569 gallium->bind_rasterizer_state = panfrost_bind_rasterizer_state;
1570 gallium->delete_rasterizer_state = panfrost_generic_cso_delete;
1571
1572 gallium->create_vertex_elements_state = panfrost_create_vertex_elements_state;
1573 gallium->bind_vertex_elements_state = panfrost_bind_vertex_elements_state;
1574 gallium->delete_vertex_elements_state = panfrost_generic_cso_delete;
1575
1576 gallium->create_fs_state = panfrost_create_fs_state;
1577 gallium->delete_fs_state = panfrost_delete_shader_state;
1578 gallium->bind_fs_state = panfrost_bind_fs_state;
1579
1580 gallium->create_vs_state = panfrost_create_vs_state;
1581 gallium->delete_vs_state = panfrost_delete_shader_state;
1582 gallium->bind_vs_state = panfrost_bind_vs_state;
1583
1584 gallium->create_sampler_state = panfrost_create_sampler_state;
1585 gallium->delete_sampler_state = panfrost_generic_cso_delete;
1586 gallium->bind_sampler_states = panfrost_bind_sampler_states;
1587
1588 gallium->create_depth_stencil_alpha_state = panfrost_create_depth_stencil_state;
1589 gallium->bind_depth_stencil_alpha_state = panfrost_bind_depth_stencil_state;
1590 gallium->delete_depth_stencil_alpha_state = panfrost_delete_depth_stencil_state;
1591
1592 gallium->set_sample_mask = panfrost_set_sample_mask;
1593
1594 gallium->set_clip_state = panfrost_set_clip_state;
1595 gallium->set_viewport_states = panfrost_set_viewport_states;
1596 gallium->set_scissor_states = panfrost_set_scissor_states;
1597 gallium->set_polygon_stipple = panfrost_set_polygon_stipple;
1598 gallium->set_active_query_state = panfrost_set_active_query_state;
1599
1600 gallium->create_query = panfrost_create_query;
1601 gallium->destroy_query = panfrost_destroy_query;
1602 gallium->begin_query = panfrost_begin_query;
1603 gallium->end_query = panfrost_end_query;
1604 gallium->get_query_result = panfrost_get_query_result;
1605
1606 gallium->create_stream_output_target = panfrost_create_stream_output_target;
1607 gallium->stream_output_target_destroy = panfrost_stream_output_target_destroy;
1608 gallium->set_stream_output_targets = panfrost_set_stream_output_targets;
1609
1610 panfrost_resource_context_init(gallium);
1611 panfrost_blend_context_init(gallium);
1612 panfrost_compute_context_init(gallium);
1613
1614 /* XXX: leaks */
1615 gallium->stream_uploader = u_upload_create_default(gallium);
1616 gallium->const_uploader = gallium->stream_uploader;
1617 assert(gallium->stream_uploader);
1618
1619 /* Midgard supports ES modes, plus QUADS/QUAD_STRIPS/POLYGON */
1620 ctx->draw_modes = (1 << (PIPE_PRIM_POLYGON + 1)) - 1;
1621
1622 ctx->primconvert = util_primconvert_create(gallium, ctx->draw_modes);
1623
1624 ctx->blitter = util_blitter_create(gallium);
1625 ctx->blitter_wallpaper = util_blitter_create(gallium);
1626
1627 assert(ctx->blitter);
1628 assert(ctx->blitter_wallpaper);
1629
1630 /* Prepare for render! */
1631
1632 panfrost_batch_init(ctx);
1633 panfrost_emit_vertex_payload(ctx);
1634 panfrost_invalidate_frame(ctx);
1635
1636 return gallium;
1637 }