Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1 | /* |
| 2 | * © Copyright 2018 Alyssa Rosenzweig |
Alyssa Rosenzweig | 5ff7973 | 2019-08-06 16:43:28 -0700 | [diff] [blame] | 3 | * Copyright © 2014-2017 Broadcom |
Alyssa Rosenzweig | f714eab | 2019-08-07 10:11:28 -0700 | [diff] [blame] | 4 | * Copyright (C) 2017 Intel Corporation |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 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 | |
Boris Brezillon | 154cb72 | 2019-09-14 09:58:55 +0200 | [diff] [blame] | 30 | #include "pan_bo.h" |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 31 | #include "pan_context.h" |
Vasily Khoruzhick | 53d6bb9 | 2020-03-03 21:31:51 -0800 | [diff] [blame] | 32 | #include "pan_minmax_cache.h" |
Tomeu Vizoso | 6887ff4 | 2019-11-28 10:21:06 +0100 | [diff] [blame] | 33 | #include "panfrost-quirks.h" |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 34 | |
| 35 | #include "util/macros.h" |
Eric Anholt | 882ca6d | 2019-06-27 15:05:31 -0700 | [diff] [blame] | 36 | #include "util/format/u_format.h" |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 37 | #include "util/u_inlines.h" |
| 38 | #include "util/u_upload_mgr.h" |
| 39 | #include "util/u_memory.h" |
Alyssa Rosenzweig | 89b02bf | 2019-04-13 00:10:20 +0000 | [diff] [blame] | 40 | #include "util/u_vbuf.h" |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 41 | #include "util/half_float.h" |
Alyssa Rosenzweig | e008d4f | 2019-04-14 22:42:44 +0000 | [diff] [blame] | 42 | #include "util/u_helpers.h" |
Eric Anholt | 882ca6d | 2019-06-27 15:05:31 -0700 | [diff] [blame] | 43 | #include "util/format/u_format.h" |
Alyssa Rosenzweig | 72fc06d | 2019-08-08 07:10:24 -0700 | [diff] [blame] | 44 | #include "util/u_prim.h" |
Alyssa Rosenzweig | 7f54812 | 2019-06-26 15:59:29 -0700 | [diff] [blame] | 45 | #include "util/u_prim_restart.h" |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 46 | #include "indices/u_primconvert.h" |
| 47 | #include "tgsi/tgsi_parse.h" |
Alyssa Rosenzweig | 4647999 | 2019-07-31 15:49:13 -0700 | [diff] [blame] | 48 | #include "tgsi/tgsi_from_mesa.h" |
Alyssa Rosenzweig | 31f5a43 | 2019-05-02 02:27:04 +0000 | [diff] [blame] | 49 | #include "util/u_math.h" |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 50 | |
| 51 | #include "pan_screen.h" |
| 52 | #include "pan_blending.h" |
| 53 | #include "pan_blend_shaders.h" |
Boris Brezillon | a72bab1 | 2020-03-05 09:30:58 +0100 | [diff] [blame] | 54 | #include "pan_cmdstream.h" |
Tomeu Vizoso | 97f2d04 | 2019-03-08 15:24:57 +0100 | [diff] [blame] | 55 | #include "pan_util.h" |
Icecream95 | cf2c5a5 | 2020-01-23 10:32:18 +1300 | [diff] [blame] | 56 | #include "pandecode/decode.h" |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 57 | |
Alyssa Rosenzweig | b0e915b | 2019-12-09 11:00:42 -0500 | [diff] [blame] | 58 | struct midgard_tiler_descriptor |
Boris Brezillon | aa851a6 | 2019-09-01 10:30:39 +0200 | [diff] [blame] | 59 | panfrost_emit_midg_tiler(struct panfrost_batch *batch, unsigned vertex_count) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 60 | { |
Alyssa Rosenzweig | ca8c625 | 2020-03-23 18:44:21 -0400 | [diff] [blame] | 61 | struct panfrost_device *device = pan_device(batch->ctx->base.screen); |
| 62 | bool hierarchy = !(device->quirks & MIDGARD_NO_HIER_TILING); |
Vinson Lee | de2e5f6 | 2019-11-27 23:37:00 -0800 | [diff] [blame] | 63 | struct midgard_tiler_descriptor t = {0}; |
Boris Brezillon | aa851a6 | 2019-09-01 10:30:39 +0200 | [diff] [blame] | 64 | unsigned height = batch->key.height; |
| 65 | unsigned width = batch->key.width; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 66 | |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 67 | t.hierarchy_mask = |
Alyssa Rosenzweig | 9fb0904 | 2019-11-27 08:31:16 -0500 | [diff] [blame] | 68 | panfrost_choose_hierarchy_mask(width, height, vertex_count, hierarchy); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 69 | |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 70 | /* Compute the polygon header size and use that to offset the body */ |
| 71 | |
| 72 | unsigned header_size = panfrost_tiler_header_size( |
Alyssa Rosenzweig | 9fb0904 | 2019-11-27 08:31:16 -0500 | [diff] [blame] | 73 | width, height, t.hierarchy_mask, hierarchy); |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 74 | |
Alyssa Rosenzweig | f5c2934 | 2019-08-19 14:30:53 -0700 | [diff] [blame] | 75 | t.polygon_list_size = panfrost_tiler_full_size( |
Alyssa Rosenzweig | 9fb0904 | 2019-11-27 08:31:16 -0500 | [diff] [blame] | 76 | width, height, t.hierarchy_mask, hierarchy); |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 77 | |
| 78 | /* Sanity check */ |
| 79 | |
Alyssa Rosenzweig | 9fb0904 | 2019-11-27 08:31:16 -0500 | [diff] [blame] | 80 | if (vertex_count) { |
Boris Brezillon | 1e483a8 | 2019-09-14 19:18:51 +0200 | [diff] [blame] | 81 | struct panfrost_bo *tiler_heap; |
| 82 | |
| 83 | tiler_heap = panfrost_batch_get_tiler_heap(batch); |
Boris Brezillon | 2c52699 | 2019-09-05 21:41:26 +0200 | [diff] [blame] | 84 | t.polygon_list = panfrost_batch_get_polygon_list(batch, |
| 85 | header_size + |
| 86 | t.polygon_list_size); |
Alyssa Rosenzweig | f5c2934 | 2019-08-19 14:30:53 -0700 | [diff] [blame] | 87 | |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 88 | |
| 89 | /* Allow the entire tiler heap */ |
Boris Brezillon | 1e483a8 | 2019-09-14 19:18:51 +0200 | [diff] [blame] | 90 | t.heap_start = tiler_heap->gpu; |
| 91 | t.heap_end = tiler_heap->gpu + tiler_heap->size; |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 92 | } else { |
Boris Brezillon | 1e483a8 | 2019-09-14 19:18:51 +0200 | [diff] [blame] | 93 | struct panfrost_bo *tiler_dummy; |
| 94 | |
| 95 | tiler_dummy = panfrost_batch_get_tiler_dummy(batch); |
Alyssa Rosenzweig | 9fb0904 | 2019-11-27 08:31:16 -0500 | [diff] [blame] | 96 | header_size = MALI_TILER_MINIMUM_HEADER_SIZE; |
Boris Brezillon | 1e483a8 | 2019-09-14 19:18:51 +0200 | [diff] [blame] | 97 | |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 98 | /* The tiler is disabled, so don't allow the tiler heap */ |
Boris Brezillon | 1e483a8 | 2019-09-14 19:18:51 +0200 | [diff] [blame] | 99 | t.heap_start = tiler_dummy->gpu; |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 100 | t.heap_end = t.heap_start; |
| 101 | |
| 102 | /* Use a dummy polygon list */ |
Boris Brezillon | 1e483a8 | 2019-09-14 19:18:51 +0200 | [diff] [blame] | 103 | t.polygon_list = tiler_dummy->gpu; |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 104 | |
Alyssa Rosenzweig | 897110a | 2019-08-19 14:47:50 -0700 | [diff] [blame] | 105 | /* Disable the tiler */ |
Alyssa Rosenzweig | 9fb0904 | 2019-11-27 08:31:16 -0500 | [diff] [blame] | 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; |
Tomeu Vizoso | 6469c1a | 2019-10-29 15:42:03 +0100 | [diff] [blame] | 111 | |
Alyssa Rosenzweig | adf716d | 2019-12-05 09:06:53 -0500 | [diff] [blame] | 112 | /* We don't have a WRITE_VALUE job, so write the polygon list manually */ |
Tomeu Vizoso | 6469c1a | 2019-10-29 15:42:03 +0100 | [diff] [blame] | 113 | uint32_t *polygon_list_body = (uint32_t *) (tiler_dummy->cpu + header_size); |
| 114 | polygon_list_body[0] = 0xa0000000; /* TODO: Just that? */ |
| 115 | } |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 116 | } |
| 117 | |
| 118 | t.polygon_list_body = |
| 119 | t.polygon_list + header_size; |
| 120 | |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 121 | return t; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 122 | } |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 123 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 124 | static void |
| 125 | panfrost_clear( |
| 126 | struct pipe_context *pipe, |
| 127 | unsigned buffers, |
Mike Blumenkrantz | 1c8bcad | 2020-03-24 12:02:51 -0400 | [diff] [blame^] | 128 | const struct pipe_scissor_state *scissor_state, |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 129 | const union pipe_color_union *color, |
| 130 | double depth, unsigned stencil) |
| 131 | { |
| 132 | struct panfrost_context *ctx = pan_context(pipe); |
Boris Brezillon | c138ca8 | 2019-09-19 15:52:02 +0200 | [diff] [blame] | 133 | |
| 134 | /* TODO: panfrost_get_fresh_batch_for_fbo() instantiates a new batch if |
| 135 | * the existing batch targeting this FBO has draws. We could probably |
| 136 | * avoid that by replacing plain clears by quad-draws with a specific |
| 137 | * color/depth/stencil value, thus avoiding the generation of extra |
Alyssa Rosenzweig | adf716d | 2019-12-05 09:06:53 -0500 | [diff] [blame] | 138 | * fragment jobs. |
Boris Brezillon | c138ca8 | 2019-09-19 15:52:02 +0200 | [diff] [blame] | 139 | */ |
| 140 | struct panfrost_batch *batch = panfrost_get_fresh_batch_for_fbo(ctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 141 | |
Boris Brezillon | 0eec73a | 2019-09-14 18:40:23 +0200 | [diff] [blame] | 142 | panfrost_batch_add_fbo_bos(batch); |
Boris Brezillon | 12d8a17 | 2019-09-05 21:41:28 +0200 | [diff] [blame] | 143 | panfrost_batch_clear(batch, buffers, color, depth, stencil); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 144 | } |
| 145 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 146 | /* Reset per-frame context, called on context initialisation as well as after |
| 147 | * flushing a frame */ |
| 148 | |
Boris Brezillon | 6ddfd37 | 2019-09-05 20:47:45 +0200 | [diff] [blame] | 149 | void |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 150 | panfrost_invalidate_frame(struct panfrost_context *ctx) |
| 151 | { |
Alyssa Rosenzweig | 72fc06d | 2019-08-08 07:10:24 -0700 | [diff] [blame] | 152 | /* TODO: When does this need to be handled? */ |
| 153 | ctx->active_queries = true; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 154 | } |
| 155 | |
Boris Brezillon | a0402f7 | 2020-03-05 17:24:39 +0100 | [diff] [blame] | 156 | bool |
Alyssa Rosenzweig | 89b02bf | 2019-04-13 00:10:20 +0000 | [diff] [blame] | 157 | panfrost_writes_point_size(struct panfrost_context *ctx) |
| 158 | { |
Alyssa Rosenzweig | ac6aa93 | 2019-07-31 14:13:30 -0700 | [diff] [blame] | 159 | assert(ctx->shader[PIPE_SHADER_VERTEX]); |
Boris Brezillon | b28f4bb | 2020-03-05 10:46:39 +0100 | [diff] [blame] | 160 | struct panfrost_shader_state *vs = panfrost_get_shader_state(ctx, PIPE_SHADER_VERTEX); |
Alyssa Rosenzweig | 89b02bf | 2019-04-13 00:10:20 +0000 | [diff] [blame] | 161 | |
Boris Brezillon | 093da77 | 2020-03-06 11:43:38 +0100 | [diff] [blame] | 162 | return vs->writes_point_size && ctx->active_prim == PIPE_PRIM_POINTS; |
Alyssa Rosenzweig | 89b02bf | 2019-04-13 00:10:20 +0000 | [diff] [blame] | 163 | } |
| 164 | |
Boris Brezillon | 046c154 | 2020-03-05 21:48:09 +0100 | [diff] [blame] | 165 | void |
Boris Brezillon | dcc0b1f | 2020-03-05 19:32:01 +0100 | [diff] [blame] | 166 | panfrost_vertex_state_upd_attr_offs(struct panfrost_context *ctx, |
Tomeu Vizoso | 7b10d4e | 2020-04-08 10:55:28 +0200 | [diff] [blame] | 167 | struct mali_vertex_tiler_postfix *vertex_postfix) |
Alyssa Rosenzweig | 31d9caa | 2019-04-15 04:08:46 +0000 | [diff] [blame] | 168 | { |
Boris Brezillon | dcc0b1f | 2020-03-05 19:32:01 +0100 | [diff] [blame] | 169 | if (!ctx->vertex) |
| 170 | return; |
| 171 | |
Alyssa Rosenzweig | 31d9caa | 2019-04-15 04:08:46 +0000 | [diff] [blame] | 172 | struct panfrost_vertex_state *so = ctx->vertex; |
| 173 | |
Alyssa Rosenzweig | 31d9caa | 2019-04-15 04:08:46 +0000 | [diff] [blame] | 174 | /* Fixup offsets for the second pass. Recall that the hardware |
| 175 | * calculates attribute addresses as: |
| 176 | * |
| 177 | * addr = base + (stride * vtx) + src_offset; |
| 178 | * |
| 179 | * However, on Mali, base must be aligned to 64-bytes, so we |
| 180 | * instead let: |
| 181 | * |
| 182 | * base' = base & ~63 = base - (base & 63) |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 183 | * |
Alyssa Rosenzweig | 31d9caa | 2019-04-15 04:08:46 +0000 | [diff] [blame] | 184 | * To compensate when using base' (see emit_vertex_data), we have |
| 185 | * to adjust src_offset by the masked off piece: |
| 186 | * |
| 187 | * addr' = base' + (stride * vtx) + (src_offset + (base & 63)) |
| 188 | * = base - (base & 63) + (stride * vtx) + src_offset + (base & 63) |
| 189 | * = base + (stride * vtx) + src_offset |
| 190 | * = addr; |
| 191 | * |
| 192 | * QED. |
| 193 | */ |
| 194 | |
Tomeu Vizoso | 7b10d4e | 2020-04-08 10:55:28 +0200 | [diff] [blame] | 195 | unsigned start = vertex_postfix->offset_start; |
Alyssa Rosenzweig | 8d74749 | 2019-06-27 14:13:10 -0700 | [diff] [blame] | 196 | |
Alyssa Rosenzweig | 31d9caa | 2019-04-15 04:08:46 +0000 | [diff] [blame] | 197 | for (unsigned i = 0; i < so->num_elements; ++i) { |
| 198 | unsigned vbi = so->pipe[i].vertex_buffer_index; |
Alyssa Rosenzweig | 8d74749 | 2019-06-27 14:13:10 -0700 | [diff] [blame] | 199 | struct pipe_vertex_buffer *buf = &ctx->vertex_buffers[vbi]; |
Alyssa Rosenzweig | 31d9caa | 2019-04-15 04:08:46 +0000 | [diff] [blame] | 200 | |
Alyssa Rosenzweig | 027944c | 2020-02-16 16:41:29 -0500 | [diff] [blame] | 201 | /* Adjust by the masked off bits of the offset. Make sure we |
| 202 | * read src_offset from so->hw (which is not GPU visible) |
| 203 | * rather than target (which is) due to caching effects */ |
| 204 | |
Boris Brezillon | 128820b | 2020-03-05 19:22:26 +0100 | [diff] [blame] | 205 | unsigned src_offset = so->pipe[i].src_offset; |
Boris Brezillon | b692ab0 | 2020-03-05 19:26:03 +0100 | [diff] [blame] | 206 | |
| 207 | /* BOs aligned to 4k so guaranteed aligned to 64 */ |
| 208 | src_offset += (buf->buffer_offset & 63); |
Alyssa Rosenzweig | 8d74749 | 2019-06-27 14:13:10 -0700 | [diff] [blame] | 209 | |
| 210 | /* Also, somewhat obscurely per-instance data needs to be |
| 211 | * offset in response to a delayed start in an indexed draw */ |
| 212 | |
Alyssa Rosenzweig | be691ca | 2019-12-19 14:00:24 -0500 | [diff] [blame] | 213 | if (so->pipe[i].instance_divisor && ctx->instance_count > 1 && start) |
Alyssa Rosenzweig | 027944c | 2020-02-16 16:41:29 -0500 | [diff] [blame] | 214 | src_offset -= buf->stride * start; |
| 215 | |
Boris Brezillon | 575f62e | 2020-03-05 19:48:30 +0100 | [diff] [blame] | 216 | so->hw[i].src_offset = src_offset; |
Alyssa Rosenzweig | 31d9caa | 2019-04-15 04:08:46 +0000 | [diff] [blame] | 217 | } |
Boris Brezillon | dcc0b1f | 2020-03-05 19:32:01 +0100 | [diff] [blame] | 218 | } |
| 219 | |
Alyssa Rosenzweig | 5d60be4 | 2019-06-20 16:16:07 -0700 | [diff] [blame] | 220 | /* Compute number of UBOs active (more specifically, compute the highest UBO |
Alyssa Rosenzweig | 4c6d751 | 2019-06-20 16:21:48 -0700 | [diff] [blame] | 221 | * number addressable -- if there are gaps, include them in the count anyway). |
| 222 | * We always include UBO #0 in the count, since we *need* uniforms enabled for |
| 223 | * sysvals. */ |
Alyssa Rosenzweig | 5d60be4 | 2019-06-20 16:16:07 -0700 | [diff] [blame] | 224 | |
Boris Brezillon | 0b735a2 | 2020-03-05 09:46:42 +0100 | [diff] [blame] | 225 | unsigned |
Alyssa Rosenzweig | 5d60be4 | 2019-06-20 16:16:07 -0700 | [diff] [blame] | 226 | panfrost_ubo_count(struct panfrost_context *ctx, enum pipe_shader_type stage) |
| 227 | { |
Alyssa Rosenzweig | 4c6d751 | 2019-06-20 16:21:48 -0700 | [diff] [blame] | 228 | unsigned mask = ctx->constant_buffer[stage].enabled_mask | 1; |
Alyssa Rosenzweig | 5d60be4 | 2019-06-20 16:16:07 -0700 | [diff] [blame] | 229 | return 32 - __builtin_clz(mask); |
| 230 | } |
| 231 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 232 | /* The entire frame is in memory -- send it off to the kernel! */ |
| 233 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 234 | void |
| 235 | panfrost_flush( |
| 236 | struct pipe_context *pipe, |
| 237 | struct pipe_fence_handle **fence, |
| 238 | unsigned flags) |
| 239 | { |
| 240 | struct panfrost_context *ctx = pan_context(pipe); |
Boris Brezillon | b5d8f9b | 2019-09-15 18:23:10 +0200 | [diff] [blame] | 241 | struct util_dynarray fences; |
| 242 | |
| 243 | /* We must collect the fences before the flush is done, otherwise we'll |
| 244 | * lose track of them. |
| 245 | */ |
| 246 | if (fence) { |
| 247 | util_dynarray_init(&fences, NULL); |
Boris Brezillon | a45984b | 2019-09-15 19:15:16 +0200 | [diff] [blame] | 248 | hash_table_foreach(ctx->batches, hentry) { |
| 249 | struct panfrost_batch *batch = hentry->data; |
| 250 | |
| 251 | panfrost_batch_fence_reference(batch->out_sync); |
| 252 | util_dynarray_append(&fences, |
| 253 | struct panfrost_batch_fence *, |
| 254 | batch->out_sync); |
| 255 | } |
Boris Brezillon | b5d8f9b | 2019-09-15 18:23:10 +0200 | [diff] [blame] | 256 | } |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 257 | |
Boris Brezillon | a45984b | 2019-09-15 19:15:16 +0200 | [diff] [blame] | 258 | /* Submit all pending jobs */ |
| 259 | panfrost_flush_all_batches(ctx, false); |
Boris Brezillon | 2fc91a1 | 2019-09-05 19:14:25 +0200 | [diff] [blame] | 260 | |
| 261 | if (fence) { |
Boris Brezillon | b5d8f9b | 2019-09-15 18:23:10 +0200 | [diff] [blame] | 262 | struct panfrost_fence *f = panfrost_fence_create(ctx, &fences); |
Boris Brezillon | 2fc91a1 | 2019-09-05 19:14:25 +0200 | [diff] [blame] | 263 | pipe->screen->fence_reference(pipe->screen, fence, NULL); |
| 264 | *fence = (struct pipe_fence_handle *)f; |
Boris Brezillon | b5d8f9b | 2019-09-15 18:23:10 +0200 | [diff] [blame] | 265 | |
| 266 | util_dynarray_foreach(&fences, struct panfrost_batch_fence *, fence) |
| 267 | panfrost_batch_fence_unreference(*fence); |
| 268 | |
| 269 | util_dynarray_fini(&fences); |
Boris Brezillon | 2fc91a1 | 2019-09-05 19:14:25 +0200 | [diff] [blame] | 270 | } |
Icecream95 | cf2c5a5 | 2020-01-23 10:32:18 +1300 | [diff] [blame] | 271 | |
| 272 | if (pan_debug & PAN_DBG_TRACE) |
| 273 | pandecode_next_frame(); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 274 | } |
| 275 | |
| 276 | #define DEFINE_CASE(c) case PIPE_PRIM_##c: return MALI_##c; |
| 277 | |
| 278 | static int |
| 279 | g2m_draw_mode(enum pipe_prim_type mode) |
| 280 | { |
| 281 | switch (mode) { |
| 282 | DEFINE_CASE(POINTS); |
| 283 | DEFINE_CASE(LINES); |
| 284 | DEFINE_CASE(LINE_LOOP); |
| 285 | DEFINE_CASE(LINE_STRIP); |
| 286 | DEFINE_CASE(TRIANGLES); |
| 287 | DEFINE_CASE(TRIANGLE_STRIP); |
| 288 | DEFINE_CASE(TRIANGLE_FAN); |
| 289 | DEFINE_CASE(QUADS); |
| 290 | DEFINE_CASE(QUAD_STRIP); |
| 291 | DEFINE_CASE(POLYGON); |
| 292 | |
| 293 | default: |
Alyssa Rosenzweig | c65271c | 2019-05-16 23:42:33 +0000 | [diff] [blame] | 294 | unreachable("Invalid draw mode"); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 295 | } |
| 296 | } |
| 297 | |
| 298 | #undef DEFINE_CASE |
| 299 | |
Alyssa Rosenzweig | 9865b79 | 2019-06-17 09:26:34 -0700 | [diff] [blame] | 300 | static bool |
| 301 | panfrost_scissor_culls_everything(struct panfrost_context *ctx) |
| 302 | { |
| 303 | const struct pipe_scissor_state *ss = &ctx->scissor; |
| 304 | |
| 305 | /* Check if we're scissoring at all */ |
| 306 | |
Boris Brezillon | 443e530 | 2019-06-26 11:16:31 +0200 | [diff] [blame] | 307 | if (!(ctx->rasterizer && ctx->rasterizer->base.scissor)) |
Alyssa Rosenzweig | 9865b79 | 2019-06-17 09:26:34 -0700 | [diff] [blame] | 308 | return false; |
| 309 | |
Alyssa Rosenzweig | 124f6b5 | 2019-06-24 14:13:20 -0700 | [diff] [blame] | 310 | return (ss->minx == ss->maxx) || (ss->miny == ss->maxy); |
Alyssa Rosenzweig | 9865b79 | 2019-06-17 09:26:34 -0700 | [diff] [blame] | 311 | } |
| 312 | |
Alyssa Rosenzweig | 72fc06d | 2019-08-08 07:10:24 -0700 | [diff] [blame] | 313 | /* Count generated primitives (when there is no geom/tess shaders) for |
| 314 | * transform feedback */ |
| 315 | |
| 316 | static void |
| 317 | panfrost_statistics_record( |
| 318 | struct panfrost_context *ctx, |
| 319 | const struct pipe_draw_info *info) |
| 320 | { |
| 321 | if (!ctx->active_queries) |
| 322 | return; |
| 323 | |
| 324 | uint32_t prims = u_prims_for_vertices(info->mode, info->count); |
| 325 | ctx->prims_generated += prims; |
| 326 | |
Alyssa Rosenzweig | 42f0aae | 2019-08-30 17:37:22 -0700 | [diff] [blame] | 327 | if (!ctx->streamout.num_targets) |
Alyssa Rosenzweig | 72fc06d | 2019-08-08 07:10:24 -0700 | [diff] [blame] | 328 | return; |
| 329 | |
| 330 | ctx->tf_prims_generated += prims; |
| 331 | } |
| 332 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 333 | static void |
Boris Brezillon | 13881a4 | 2020-03-05 21:55:01 +0100 | [diff] [blame] | 334 | panfrost_update_streamout_offsets(struct panfrost_context *ctx) |
| 335 | { |
| 336 | for (unsigned i = 0; i < ctx->streamout.num_targets; ++i) { |
| 337 | unsigned count; |
| 338 | |
| 339 | count = u_stream_outputs_for_vertices(ctx->active_prim, |
| 340 | ctx->vertex_count); |
| 341 | ctx->streamout.offsets[i] += count; |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | static void |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 346 | panfrost_draw_vbo( |
| 347 | struct pipe_context *pipe, |
| 348 | const struct pipe_draw_info *info) |
| 349 | { |
| 350 | struct panfrost_context *ctx = pan_context(pipe); |
| 351 | |
Alyssa Rosenzweig | 9865b79 | 2019-06-17 09:26:34 -0700 | [diff] [blame] | 352 | /* First of all, check the scissor to see if anything is drawn at all. |
| 353 | * If it's not, we drop the draw (mostly a conformance issue; |
| 354 | * well-behaved apps shouldn't hit this) */ |
| 355 | |
| 356 | if (panfrost_scissor_culls_everything(ctx)) |
| 357 | return; |
| 358 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 359 | int mode = info->mode; |
| 360 | |
Alyssa Rosenzweig | 7f54812 | 2019-06-26 15:59:29 -0700 | [diff] [blame] | 361 | /* Fallback unsupported restart index */ |
| 362 | unsigned primitive_index = (1 << (info->index_size * 8)) - 1; |
| 363 | |
| 364 | if (info->primitive_restart && info->index_size |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 365 | && info->restart_index != primitive_index) { |
Alyssa Rosenzweig | 7f54812 | 2019-06-26 15:59:29 -0700 | [diff] [blame] | 366 | util_draw_vbo_without_prim_restart(pipe, info); |
| 367 | return; |
| 368 | } |
| 369 | |
Alyssa Rosenzweig | 85e2bb5 | 2019-02-08 02:28:12 +0000 | [diff] [blame] | 370 | /* Fallback for unsupported modes */ |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 371 | |
Alyssa Rosenzweig | 27b6264 | 2019-08-21 09:40:11 -0700 | [diff] [blame] | 372 | assert(ctx->rasterizer != NULL); |
| 373 | |
Alyssa Rosenzweig | 7c02c4f | 2019-03-15 02:13:34 +0000 | [diff] [blame] | 374 | if (!(ctx->draw_modes & (1 << mode))) { |
Alyssa Rosenzweig | 27b6264 | 2019-08-21 09:40:11 -0700 | [diff] [blame] | 375 | if (mode == PIPE_PRIM_QUADS && info->count == 4 && !ctx->rasterizer->base.flatshade) { |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 376 | mode = PIPE_PRIM_TRIANGLE_FAN; |
| 377 | } else { |
| 378 | if (info->count < 4) { |
| 379 | /* Degenerate case? */ |
| 380 | return; |
| 381 | } |
| 382 | |
| 383 | util_primconvert_save_rasterizer_state(ctx->primconvert, &ctx->rasterizer->base); |
| 384 | util_primconvert_draw_vbo(ctx->primconvert, info); |
| 385 | return; |
| 386 | } |
| 387 | } |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 388 | |
Alyssa Rosenzweig | 59c9623 | 2019-02-25 05:32:16 +0000 | [diff] [blame] | 389 | /* Now that we have a guaranteed terminating path, find the job. |
| 390 | * Assignment commented out to prevent unused warning */ |
| 391 | |
Boris Brezillon | 251e685 | 2020-03-06 08:57:31 +0100 | [diff] [blame] | 392 | struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx); |
| 393 | |
| 394 | panfrost_batch_add_fbo_bos(batch); |
| 395 | panfrost_batch_set_requirements(batch); |
Alyssa Rosenzweig | 59c9623 | 2019-02-25 05:32:16 +0000 | [diff] [blame] | 396 | |
Rohan Garg | 16edd56 | 2019-07-17 18:50:13 +0200 | [diff] [blame] | 397 | /* Take into account a negative bias */ |
| 398 | ctx->vertex_count = info->count + abs(info->index_bias); |
Alyssa Rosenzweig | 8d74749 | 2019-06-27 14:13:10 -0700 | [diff] [blame] | 399 | ctx->instance_count = info->instance_count; |
Alyssa Rosenzweig | 7c29588 | 2019-08-08 08:16:09 -0700 | [diff] [blame] | 400 | ctx->active_prim = info->mode; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 401 | |
Tomeu Vizoso | 7b10d4e | 2020-04-08 10:55:28 +0200 | [diff] [blame] | 402 | struct mali_vertex_tiler_prefix vertex_prefix, tiler_prefix; |
| 403 | struct mali_vertex_tiler_postfix vertex_postfix, tiler_postfix; |
| 404 | union midgard_primitive_size primitive_size; |
Boris Brezillon | 5d9995e | 2020-03-06 08:02:14 +0100 | [diff] [blame] | 405 | unsigned vertex_count; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 406 | |
Tomeu Vizoso | 7b10d4e | 2020-04-08 10:55:28 +0200 | [diff] [blame] | 407 | panfrost_vt_init(ctx, PIPE_SHADER_VERTEX, &vertex_prefix, &vertex_postfix); |
| 408 | panfrost_vt_init(ctx, PIPE_SHADER_FRAGMENT, &tiler_prefix, &tiler_postfix); |
Boris Brezillon | d66ef69 | 2020-03-06 11:31:06 +0100 | [diff] [blame] | 409 | |
Tomeu Vizoso | 7b10d4e | 2020-04-08 10:55:28 +0200 | [diff] [blame] | 410 | panfrost_vt_set_draw_info(ctx, info, g2m_draw_mode(mode), |
| 411 | &vertex_postfix, &tiler_prefix, |
| 412 | &tiler_postfix, &vertex_count, |
| 413 | &ctx->padded_count); |
Alyssa Rosenzweig | 0e4c321 | 2019-03-31 04:26:48 +0000 | [diff] [blame] | 414 | |
Alyssa Rosenzweig | 72fc06d | 2019-08-08 07:10:24 -0700 | [diff] [blame] | 415 | panfrost_statistics_record(ctx, info); |
| 416 | |
Alyssa Rosenzweig | c9b164f | 2019-06-27 08:29:06 -0700 | [diff] [blame] | 417 | /* Dispatch "compute jobs" for the vertex/tiler pair as (1, |
| 418 | * vertex_count, 1) */ |
| 419 | |
Tomeu Vizoso | 7b10d4e | 2020-04-08 10:55:28 +0200 | [diff] [blame] | 420 | panfrost_pack_work_groups_fused(&vertex_prefix, &tiler_prefix, |
Boris Brezillon | b1a6a15 | 2020-03-06 11:46:39 +0100 | [diff] [blame] | 421 | 1, vertex_count, info->instance_count, |
| 422 | 1, 1, 1); |
Alyssa Rosenzweig | c9b164f | 2019-06-27 08:29:06 -0700 | [diff] [blame] | 423 | |
Boris Brezillon | 251e685 | 2020-03-06 08:57:31 +0100 | [diff] [blame] | 424 | /* Emit all sort of descriptors. */ |
Tomeu Vizoso | 7b10d4e | 2020-04-08 10:55:28 +0200 | [diff] [blame] | 425 | panfrost_emit_vertex_data(batch, &vertex_postfix); |
Boris Brezillon | 836686d | 2020-03-06 09:45:31 +0100 | [diff] [blame] | 426 | panfrost_emit_varying_descriptor(batch, |
Boris Brezillon | 251e685 | 2020-03-06 08:57:31 +0100 | [diff] [blame] | 427 | ctx->padded_count * |
Boris Brezillon | 836686d | 2020-03-06 09:45:31 +0100 | [diff] [blame] | 428 | ctx->instance_count, |
Tomeu Vizoso | 7b10d4e | 2020-04-08 10:55:28 +0200 | [diff] [blame] | 429 | &vertex_postfix, &tiler_postfix, |
| 430 | &primitive_size); |
| 431 | panfrost_emit_shader_meta(batch, PIPE_SHADER_VERTEX, &vertex_postfix); |
| 432 | panfrost_emit_shader_meta(batch, PIPE_SHADER_FRAGMENT, &tiler_postfix); |
| 433 | panfrost_emit_vertex_attr_meta(batch, &vertex_postfix); |
| 434 | panfrost_emit_sampler_descriptors(batch, PIPE_SHADER_VERTEX, &vertex_postfix); |
| 435 | panfrost_emit_sampler_descriptors(batch, PIPE_SHADER_FRAGMENT, &tiler_postfix); |
| 436 | panfrost_emit_texture_descriptors(batch, PIPE_SHADER_VERTEX, &vertex_postfix); |
| 437 | panfrost_emit_texture_descriptors(batch, PIPE_SHADER_FRAGMENT, &tiler_postfix); |
| 438 | panfrost_emit_const_buf(batch, PIPE_SHADER_VERTEX, &vertex_postfix); |
| 439 | panfrost_emit_const_buf(batch, PIPE_SHADER_FRAGMENT, &tiler_postfix); |
| 440 | panfrost_emit_viewport(batch, &tiler_postfix); |
| 441 | |
| 442 | panfrost_vt_update_primitive_size(ctx, &tiler_prefix, &primitive_size); |
Boris Brezillon | 251e685 | 2020-03-06 08:57:31 +0100 | [diff] [blame] | 443 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 444 | /* Fire off the draw itself */ |
Tomeu Vizoso | 7b10d4e | 2020-04-08 10:55:28 +0200 | [diff] [blame] | 445 | panfrost_emit_vertex_tiler_jobs(batch, &vertex_prefix, &vertex_postfix, |
| 446 | &tiler_prefix, &tiler_postfix, |
| 447 | &primitive_size); |
Boris Brezillon | 251e685 | 2020-03-06 08:57:31 +0100 | [diff] [blame] | 448 | |
| 449 | /* Adjust the batch stack size based on the new shader stack sizes. */ |
| 450 | panfrost_batch_adjust_stack_size(batch); |
Alyssa Rosenzweig | 7c29588 | 2019-08-08 08:16:09 -0700 | [diff] [blame] | 451 | |
| 452 | /* Increment transform feedback offsets */ |
Boris Brezillon | 13881a4 | 2020-03-05 21:55:01 +0100 | [diff] [blame] | 453 | panfrost_update_streamout_offsets(ctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 454 | } |
| 455 | |
| 456 | /* CSO state */ |
| 457 | |
| 458 | static void |
| 459 | panfrost_generic_cso_delete(struct pipe_context *pctx, void *hwcso) |
| 460 | { |
| 461 | free(hwcso); |
| 462 | } |
| 463 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 464 | static void * |
| 465 | panfrost_create_rasterizer_state( |
| 466 | struct pipe_context *pctx, |
| 467 | const struct pipe_rasterizer_state *cso) |
| 468 | { |
| 469 | struct panfrost_rasterizer *so = CALLOC_STRUCT(panfrost_rasterizer); |
| 470 | |
| 471 | so->base = *cso; |
| 472 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 473 | return so; |
| 474 | } |
| 475 | |
| 476 | static void |
| 477 | panfrost_bind_rasterizer_state( |
| 478 | struct pipe_context *pctx, |
| 479 | void *hwcso) |
| 480 | { |
| 481 | struct panfrost_context *ctx = pan_context(pctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 482 | |
Alyssa Rosenzweig | d3160a6 | 2020-02-18 10:08:51 -0500 | [diff] [blame] | 483 | ctx->rasterizer = hwcso; |
| 484 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 485 | if (!hwcso) |
| 486 | return; |
| 487 | |
Alyssa Rosenzweig | 8305766 | 2019-07-11 07:02:26 -0700 | [diff] [blame] | 488 | /* Gauranteed with the core GL call, so don't expose ARB_polygon_offset */ |
| 489 | assert(ctx->rasterizer->base.offset_clamp == 0.0); |
| 490 | |
Alyssa Rosenzweig | be03060 | 2019-06-24 11:01:05 -0700 | [diff] [blame] | 491 | /* Point sprites are emulated */ |
| 492 | |
Boris Brezillon | b28f4bb | 2020-03-05 10:46:39 +0100 | [diff] [blame] | 493 | struct panfrost_shader_state *variant = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT); |
Alyssa Rosenzweig | f35f373 | 2019-06-24 11:53:58 -0700 | [diff] [blame] | 494 | |
| 495 | if (ctx->rasterizer->base.sprite_coord_enable || (variant && variant->point_sprite_mask)) |
Alyssa Rosenzweig | ac6aa93 | 2019-07-31 14:13:30 -0700 | [diff] [blame] | 496 | ctx->base.bind_fs_state(&ctx->base, ctx->shader[PIPE_SHADER_FRAGMENT]); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 497 | } |
| 498 | |
| 499 | static void * |
| 500 | panfrost_create_vertex_elements_state( |
| 501 | struct pipe_context *pctx, |
| 502 | unsigned num_elements, |
| 503 | const struct pipe_vertex_element *elements) |
| 504 | { |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 505 | struct panfrost_vertex_state *so = CALLOC_STRUCT(panfrost_vertex_state); |
| 506 | |
| 507 | so->num_elements = num_elements; |
| 508 | memcpy(so->pipe, elements, sizeof(*elements) * num_elements); |
| 509 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 510 | for (int i = 0; i < num_elements; ++i) { |
Alyssa Rosenzweig | 8d74749 | 2019-06-27 14:13:10 -0700 | [diff] [blame] | 511 | so->hw[i].index = i; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 512 | |
| 513 | enum pipe_format fmt = elements[i].src_format; |
| 514 | const struct util_format_description *desc = util_format_description(fmt); |
| 515 | so->hw[i].unknown1 = 0x2; |
Icecream95 | b4cc116 | 2020-04-26 19:19:23 +1200 | [diff] [blame] | 516 | so->hw[i].swizzle = panfrost_translate_swizzle_4(desc->swizzle); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 517 | |
| 518 | so->hw[i].format = panfrost_find_format(desc); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 519 | } |
| 520 | |
Boris Brezillon | 4a2ee61 | 2020-03-05 19:40:15 +0100 | [diff] [blame] | 521 | /* Let's also prepare vertex builtins */ |
| 522 | so->hw[PAN_VERTEX_ID].format = MALI_R32UI; |
| 523 | so->hw[PAN_VERTEX_ID].swizzle = panfrost_get_default_swizzle(1); |
| 524 | so->hw[PAN_INSTANCE_ID].format = MALI_R32UI; |
| 525 | so->hw[PAN_INSTANCE_ID].swizzle = panfrost_get_default_swizzle(1); |
| 526 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 527 | return so; |
| 528 | } |
| 529 | |
| 530 | static void |
| 531 | panfrost_bind_vertex_elements_state( |
| 532 | struct pipe_context *pctx, |
| 533 | void *hwcso) |
| 534 | { |
| 535 | struct panfrost_context *ctx = pan_context(pctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 536 | ctx->vertex = hwcso; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 537 | } |
| 538 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 539 | static void * |
| 540 | panfrost_create_shader_state( |
| 541 | struct pipe_context *pctx, |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 542 | const struct pipe_shader_state *cso, |
| 543 | enum pipe_shader_type stage) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 544 | { |
| 545 | struct panfrost_shader_variants *so = CALLOC_STRUCT(panfrost_shader_variants); |
| 546 | so->base = *cso; |
| 547 | |
| 548 | /* Token deep copy to prevent memory corruption */ |
| 549 | |
| 550 | if (cso->type == PIPE_SHADER_IR_TGSI) |
| 551 | so->base.tokens = tgsi_dup_tokens(so->base.tokens); |
| 552 | |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 553 | /* Precompile for shader-db if we need to */ |
| 554 | if (unlikely((pan_debug & PAN_DBG_PRECOMPILE) && cso->type == PIPE_SHADER_IR_NIR)) { |
| 555 | struct panfrost_context *ctx = pan_context(pctx); |
| 556 | |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 557 | struct panfrost_shader_state state; |
| 558 | uint64_t outputs_written; |
| 559 | |
Boris Brezillon | b02f97c | 2020-03-05 16:20:18 +0100 | [diff] [blame] | 560 | panfrost_shader_compile(ctx, PIPE_SHADER_IR_NIR, |
| 561 | so->base.ir.nir, |
| 562 | tgsi_processor_to_shader_stage(stage), |
| 563 | &state, &outputs_written); |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 564 | } |
| 565 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 566 | return so; |
| 567 | } |
| 568 | |
| 569 | static void |
| 570 | panfrost_delete_shader_state( |
| 571 | struct pipe_context *pctx, |
| 572 | void *so) |
| 573 | { |
Alyssa Rosenzweig | acc52ff | 2019-02-14 04:00:19 +0000 | [diff] [blame] | 574 | struct panfrost_shader_variants *cso = (struct panfrost_shader_variants *) so; |
| 575 | |
| 576 | if (cso->base.type == PIPE_SHADER_IR_TGSI) { |
Tomeu Vizoso | 97f2d04 | 2019-03-08 15:24:57 +0100 | [diff] [blame] | 577 | DBG("Deleting TGSI shader leaks duplicated tokens\n"); |
Alyssa Rosenzweig | acc52ff | 2019-02-14 04:00:19 +0000 | [diff] [blame] | 578 | } |
| 579 | |
Tomeu Vizoso | 950b5fc5 | 2019-08-01 16:45:50 +0200 | [diff] [blame] | 580 | for (unsigned i = 0; i < cso->variant_count; ++i) { |
| 581 | struct panfrost_shader_state *shader_state = &cso->variants[i]; |
Boris Brezillon | e15ab93 | 2019-09-14 10:35:47 +0200 | [diff] [blame] | 582 | panfrost_bo_unreference(shader_state->bo); |
Tomeu Vizoso | 950b5fc5 | 2019-08-01 16:45:50 +0200 | [diff] [blame] | 583 | shader_state->bo = NULL; |
| 584 | } |
Icecream95 | d8a3501 | 2020-01-12 14:19:25 +1300 | [diff] [blame] | 585 | free(cso->variants); |
Tomeu Vizoso | 950b5fc5 | 2019-08-01 16:45:50 +0200 | [diff] [blame] | 586 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 587 | free(so); |
| 588 | } |
| 589 | |
| 590 | static void * |
| 591 | panfrost_create_sampler_state( |
| 592 | struct pipe_context *pctx, |
| 593 | const struct pipe_sampler_state *cso) |
| 594 | { |
| 595 | struct panfrost_sampler_state *so = CALLOC_STRUCT(panfrost_sampler_state); |
Tomeu Vizoso | d3eb23a | 2020-04-17 14:23:39 +0200 | [diff] [blame] | 596 | struct panfrost_device *device = pan_device(pctx->screen); |
| 597 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 598 | so->base = *cso; |
| 599 | |
Tomeu Vizoso | d3eb23a | 2020-04-17 14:23:39 +0200 | [diff] [blame] | 600 | if (device->quirks & IS_BIFROST) |
| 601 | panfrost_sampler_desc_init_bifrost(cso, &so->bifrost_hw); |
| 602 | else |
| 603 | panfrost_sampler_desc_init(cso, &so->midgard_hw); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 604 | |
| 605 | return so; |
| 606 | } |
| 607 | |
| 608 | static void |
| 609 | panfrost_bind_sampler_states( |
| 610 | struct pipe_context *pctx, |
| 611 | enum pipe_shader_type shader, |
| 612 | unsigned start_slot, unsigned num_sampler, |
| 613 | void **sampler) |
| 614 | { |
| 615 | assert(start_slot == 0); |
| 616 | |
| 617 | struct panfrost_context *ctx = pan_context(pctx); |
| 618 | |
| 619 | /* XXX: Should upload, not just copy? */ |
| 620 | ctx->sampler_count[shader] = num_sampler; |
| 621 | memcpy(ctx->samplers[shader], sampler, num_sampler * sizeof (void *)); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 622 | } |
| 623 | |
| 624 | static bool |
Alyssa Rosenzweig | 9ab8d31 | 2019-06-14 10:12:38 -0700 | [diff] [blame] | 625 | panfrost_variant_matches( |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 626 | struct panfrost_context *ctx, |
| 627 | struct panfrost_shader_state *variant, |
| 628 | enum pipe_shader_type type) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 629 | { |
Alyssa Rosenzweig | be03060 | 2019-06-24 11:01:05 -0700 | [diff] [blame] | 630 | struct pipe_rasterizer_state *rasterizer = &ctx->rasterizer->base; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 631 | struct pipe_alpha_state *alpha = &ctx->depth_stencil->alpha; |
| 632 | |
Alyssa Rosenzweig | 9ab8d31 | 2019-06-14 10:12:38 -0700 | [diff] [blame] | 633 | bool is_fragment = (type == PIPE_SHADER_FRAGMENT); |
| 634 | |
| 635 | if (is_fragment && (alpha->enabled || variant->alpha_state.enabled)) { |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 636 | /* Make sure enable state is at least the same */ |
| 637 | if (alpha->enabled != variant->alpha_state.enabled) { |
| 638 | return false; |
| 639 | } |
| 640 | |
| 641 | /* Check that the contents of the test are the same */ |
| 642 | bool same_func = alpha->func == variant->alpha_state.func; |
| 643 | bool same_ref = alpha->ref_value == variant->alpha_state.ref_value; |
| 644 | |
| 645 | if (!(same_func && same_ref)) { |
| 646 | return false; |
| 647 | } |
| 648 | } |
Alyssa Rosenzweig | be03060 | 2019-06-24 11:01:05 -0700 | [diff] [blame] | 649 | |
| 650 | if (is_fragment && rasterizer && (rasterizer->sprite_coord_enable | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 651 | variant->point_sprite_mask)) { |
Alyssa Rosenzweig | be03060 | 2019-06-24 11:01:05 -0700 | [diff] [blame] | 652 | /* Ensure the same varyings are turned to point sprites */ |
| 653 | if (rasterizer->sprite_coord_enable != variant->point_sprite_mask) |
| 654 | return false; |
| 655 | |
| 656 | /* Ensure the orientation is correct */ |
| 657 | bool upper_left = |
| 658 | rasterizer->sprite_coord_mode == |
| 659 | PIPE_SPRITE_COORD_UPPER_LEFT; |
| 660 | |
| 661 | if (variant->point_sprite_upper_left != upper_left) |
| 662 | return false; |
| 663 | } |
| 664 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 665 | /* Otherwise, we're good to go */ |
| 666 | return true; |
| 667 | } |
| 668 | |
Alyssa Rosenzweig | f714eab | 2019-08-07 10:11:28 -0700 | [diff] [blame] | 669 | /** |
| 670 | * Fix an uncompiled shader's stream output info, and produce a bitmask |
| 671 | * of which VARYING_SLOT_* are captured for stream output. |
| 672 | * |
| 673 | * Core Gallium stores output->register_index as a "slot" number, where |
| 674 | * slots are assigned consecutively to all outputs in info->outputs_written. |
| 675 | * This naive packing of outputs doesn't work for us - we too have slots, |
| 676 | * but the layout is defined by the VUE map, which we won't have until we |
| 677 | * compile a specific shader variant. So, we remap these and simply store |
| 678 | * VARYING_SLOT_* in our copy's output->register_index fields. |
| 679 | * |
| 680 | * We then produce a bitmask of outputs which are used for SO. |
| 681 | * |
| 682 | * Implementation from iris. |
| 683 | */ |
| 684 | |
| 685 | static uint64_t |
| 686 | update_so_info(struct pipe_stream_output_info *so_info, |
| 687 | uint64_t outputs_written) |
| 688 | { |
| 689 | uint64_t so_outputs = 0; |
Vinson Lee | de2e5f6 | 2019-11-27 23:37:00 -0800 | [diff] [blame] | 690 | uint8_t reverse_map[64] = {0}; |
Alyssa Rosenzweig | f714eab | 2019-08-07 10:11:28 -0700 | [diff] [blame] | 691 | unsigned slot = 0; |
| 692 | |
| 693 | while (outputs_written) |
| 694 | reverse_map[slot++] = u_bit_scan64(&outputs_written); |
| 695 | |
| 696 | for (unsigned i = 0; i < so_info->num_outputs; i++) { |
| 697 | struct pipe_stream_output *output = &so_info->output[i]; |
| 698 | |
| 699 | /* Map Gallium's condensed "slots" back to real VARYING_SLOT_* enums */ |
| 700 | output->register_index = reverse_map[output->register_index]; |
| 701 | |
| 702 | so_outputs |= 1ull << output->register_index; |
| 703 | } |
| 704 | |
| 705 | return so_outputs; |
| 706 | } |
| 707 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 708 | static void |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 709 | panfrost_bind_shader_state( |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 710 | struct pipe_context *pctx, |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 711 | void *hwcso, |
| 712 | enum pipe_shader_type type) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 713 | { |
| 714 | struct panfrost_context *ctx = pan_context(pctx); |
Alyssa Rosenzweig | 3113be3 | 2019-07-31 14:15:19 -0700 | [diff] [blame] | 715 | ctx->shader[type] = hwcso; |
| 716 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 717 | if (!hwcso) return; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 718 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 719 | /* Match the appropriate variant */ |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 720 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 721 | signed variant = -1; |
| 722 | struct panfrost_shader_variants *variants = (struct panfrost_shader_variants *) hwcso; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 723 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 724 | for (unsigned i = 0; i < variants->variant_count; ++i) { |
Alyssa Rosenzweig | 9ab8d31 | 2019-06-14 10:12:38 -0700 | [diff] [blame] | 725 | if (panfrost_variant_matches(ctx, &variants->variants[i], type)) { |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 726 | variant = i; |
| 727 | break; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 728 | } |
| 729 | } |
| 730 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 731 | if (variant == -1) { |
| 732 | /* No variant matched, so create a new one */ |
| 733 | variant = variants->variant_count++; |
Icecream95 | d8a3501 | 2020-01-12 14:19:25 +1300 | [diff] [blame] | 734 | |
| 735 | if (variants->variant_count > variants->variant_space) { |
| 736 | unsigned old_space = variants->variant_space; |
| 737 | |
| 738 | variants->variant_space *= 2; |
| 739 | if (variants->variant_space == 0) |
| 740 | variants->variant_space = 1; |
| 741 | |
| 742 | /* Arbitrary limit to stop runaway programs from |
| 743 | * creating an unbounded number of shader variants. */ |
| 744 | assert(variants->variant_space < 1024); |
| 745 | |
| 746 | unsigned msize = sizeof(struct panfrost_shader_state); |
| 747 | variants->variants = realloc(variants->variants, |
| 748 | variants->variant_space * msize); |
| 749 | |
| 750 | memset(&variants->variants[old_space], 0, |
| 751 | (variants->variant_space - old_space) * msize); |
| 752 | } |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 753 | |
Alyssa Rosenzweig | be03060 | 2019-06-24 11:01:05 -0700 | [diff] [blame] | 754 | struct panfrost_shader_state *v = |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 755 | &variants->variants[variant]; |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 756 | |
Alyssa Rosenzweig | be03060 | 2019-06-24 11:01:05 -0700 | [diff] [blame] | 757 | if (type == PIPE_SHADER_FRAGMENT) { |
| 758 | v->alpha_state = ctx->depth_stencil->alpha; |
| 759 | |
| 760 | if (ctx->rasterizer) { |
| 761 | v->point_sprite_mask = ctx->rasterizer->base.sprite_coord_enable; |
| 762 | v->point_sprite_upper_left = |
| 763 | ctx->rasterizer->base.sprite_coord_mode == |
| 764 | PIPE_SPRITE_COORD_UPPER_LEFT; |
| 765 | } |
| 766 | } |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 767 | } |
| 768 | |
| 769 | /* Select this variant */ |
| 770 | variants->active_variant = variant; |
| 771 | |
| 772 | struct panfrost_shader_state *shader_state = &variants->variants[variant]; |
Alyssa Rosenzweig | 9ab8d31 | 2019-06-14 10:12:38 -0700 | [diff] [blame] | 773 | assert(panfrost_variant_matches(ctx, shader_state, type)); |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 774 | |
| 775 | /* We finally have a variant, so compile it */ |
| 776 | |
| 777 | if (!shader_state->compiled) { |
Alyssa Rosenzweig | 5b0a1a4 | 2019-08-07 10:26:12 -0700 | [diff] [blame] | 778 | uint64_t outputs_written = 0; |
| 779 | |
Boris Brezillon | b02f97c | 2020-03-05 16:20:18 +0100 | [diff] [blame] | 780 | panfrost_shader_compile(ctx, variants->base.type, |
| 781 | variants->base.type == PIPE_SHADER_IR_NIR ? |
| 782 | variants->base.ir.nir : |
| 783 | variants->base.tokens, |
| 784 | tgsi_processor_to_shader_stage(type), |
| 785 | shader_state, |
Alyssa Rosenzweig | 5b0a1a4 | 2019-08-07 10:26:12 -0700 | [diff] [blame] | 786 | &outputs_written); |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 787 | |
| 788 | shader_state->compiled = true; |
Alyssa Rosenzweig | e7a05a6 | 2019-08-07 10:33:15 -0700 | [diff] [blame] | 789 | |
| 790 | /* Fixup the stream out information, since what Gallium returns |
| 791 | * normally is mildly insane */ |
| 792 | |
| 793 | shader_state->stream_output = variants->base.stream_output; |
| 794 | shader_state->so_mask = |
| 795 | update_so_info(&shader_state->stream_output, outputs_written); |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 796 | } |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 797 | } |
| 798 | |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 799 | static void * |
| 800 | panfrost_create_vs_state(struct pipe_context *pctx, const struct pipe_shader_state *hwcso) |
| 801 | { |
| 802 | return panfrost_create_shader_state(pctx, hwcso, PIPE_SHADER_VERTEX); |
| 803 | } |
| 804 | |
| 805 | static void * |
| 806 | panfrost_create_fs_state(struct pipe_context *pctx, const struct pipe_shader_state *hwcso) |
| 807 | { |
| 808 | return panfrost_create_shader_state(pctx, hwcso, PIPE_SHADER_FRAGMENT); |
| 809 | } |
| 810 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 811 | static void |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 812 | panfrost_bind_vs_state(struct pipe_context *pctx, void *hwcso) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 813 | { |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 814 | panfrost_bind_shader_state(pctx, hwcso, PIPE_SHADER_VERTEX); |
| 815 | } |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 816 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 817 | static void |
| 818 | panfrost_bind_fs_state(struct pipe_context *pctx, void *hwcso) |
| 819 | { |
| 820 | panfrost_bind_shader_state(pctx, hwcso, PIPE_SHADER_FRAGMENT); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 821 | } |
| 822 | |
| 823 | static void |
| 824 | panfrost_set_vertex_buffers( |
| 825 | struct pipe_context *pctx, |
| 826 | unsigned start_slot, |
| 827 | unsigned num_buffers, |
| 828 | const struct pipe_vertex_buffer *buffers) |
| 829 | { |
| 830 | struct panfrost_context *ctx = pan_context(pctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 831 | |
Alyssa Rosenzweig | e008d4f | 2019-04-14 22:42:44 +0000 | [diff] [blame] | 832 | util_set_vertex_buffers_mask(ctx->vertex_buffers, &ctx->vb_mask, buffers, start_slot, num_buffers); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 833 | } |
| 834 | |
| 835 | static void |
| 836 | panfrost_set_constant_buffer( |
| 837 | struct pipe_context *pctx, |
| 838 | enum pipe_shader_type shader, uint index, |
| 839 | const struct pipe_constant_buffer *buf) |
| 840 | { |
| 841 | struct panfrost_context *ctx = pan_context(pctx); |
| 842 | struct panfrost_constant_buffer *pbuf = &ctx->constant_buffer[shader]; |
| 843 | |
Alyssa Rosenzweig | ca2caf0 | 2019-06-20 16:07:57 -0700 | [diff] [blame] | 844 | util_copy_constant_buffer(&pbuf->cb[index], buf); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 845 | |
Alyssa Rosenzweig | ca2caf0 | 2019-06-20 16:07:57 -0700 | [diff] [blame] | 846 | unsigned mask = (1 << index); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 847 | |
Alyssa Rosenzweig | ca2caf0 | 2019-06-20 16:07:57 -0700 | [diff] [blame] | 848 | if (unlikely(!buf)) { |
| 849 | pbuf->enabled_mask &= ~mask; |
| 850 | pbuf->dirty_mask &= ~mask; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 851 | return; |
| 852 | } |
| 853 | |
Alyssa Rosenzweig | ca2caf0 | 2019-06-20 16:07:57 -0700 | [diff] [blame] | 854 | pbuf->enabled_mask |= mask; |
| 855 | pbuf->dirty_mask |= mask; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 856 | } |
| 857 | |
| 858 | static void |
| 859 | panfrost_set_stencil_ref( |
| 860 | struct pipe_context *pctx, |
| 861 | const struct pipe_stencil_ref *ref) |
| 862 | { |
| 863 | struct panfrost_context *ctx = pan_context(pctx); |
| 864 | ctx->stencil_ref = *ref; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 865 | } |
| 866 | |
Alyssa Rosenzweig | 83c02a5 | 2019-06-17 14:26:08 -0700 | [diff] [blame] | 867 | static enum mali_texture_type |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 868 | panfrost_translate_texture_type(enum pipe_texture_target t) { |
| 869 | switch (t) |
| 870 | { |
| 871 | case PIPE_BUFFER: |
Alyssa Rosenzweig | 0ae72df | 2019-08-16 10:26:03 -0700 | [diff] [blame] | 872 | case PIPE_TEXTURE_1D: |
| 873 | case PIPE_TEXTURE_1D_ARRAY: |
| 874 | return MALI_TEX_1D; |
Alyssa Rosenzweig | 83c02a5 | 2019-06-17 14:26:08 -0700 | [diff] [blame] | 875 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 876 | case PIPE_TEXTURE_2D: |
| 877 | case PIPE_TEXTURE_2D_ARRAY: |
| 878 | case PIPE_TEXTURE_RECT: |
| 879 | return MALI_TEX_2D; |
Alyssa Rosenzweig | 83c02a5 | 2019-06-17 14:26:08 -0700 | [diff] [blame] | 880 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 881 | case PIPE_TEXTURE_3D: |
| 882 | return MALI_TEX_3D; |
Alyssa Rosenzweig | 83c02a5 | 2019-06-17 14:26:08 -0700 | [diff] [blame] | 883 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 884 | case PIPE_TEXTURE_CUBE: |
| 885 | case PIPE_TEXTURE_CUBE_ARRAY: |
| 886 | return MALI_TEX_CUBE; |
Alyssa Rosenzweig | 83c02a5 | 2019-06-17 14:26:08 -0700 | [diff] [blame] | 887 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 888 | default: |
| 889 | unreachable("Unknown target"); |
Alyssa Rosenzweig | 83c02a5 | 2019-06-17 14:26:08 -0700 | [diff] [blame] | 890 | } |
| 891 | } |
| 892 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 893 | static struct pipe_sampler_view * |
| 894 | panfrost_create_sampler_view( |
| 895 | struct pipe_context *pctx, |
| 896 | struct pipe_resource *texture, |
| 897 | const struct pipe_sampler_view *template) |
| 898 | { |
Alyssa Rosenzweig | ca8c625 | 2020-03-23 18:44:21 -0400 | [diff] [blame] | 899 | struct panfrost_device *device = pan_device(pctx->screen); |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 900 | struct panfrost_sampler_view *so = rzalloc(pctx, struct panfrost_sampler_view); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 901 | |
| 902 | pipe_reference(NULL, &texture->reference); |
| 903 | |
| 904 | struct panfrost_resource *prsrc = (struct panfrost_resource *) texture; |
Alyssa Rosenzweig | 81b1053 | 2019-05-14 23:18:18 +0000 | [diff] [blame] | 905 | assert(prsrc->bo); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 906 | |
| 907 | so->base = *template; |
| 908 | so->base.texture = texture; |
| 909 | so->base.reference.count = 1; |
| 910 | so->base.context = pctx; |
| 911 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 912 | unsigned char user_swizzle[4] = { |
| 913 | template->swizzle_r, |
| 914 | template->swizzle_g, |
| 915 | template->swizzle_b, |
| 916 | template->swizzle_a |
| 917 | }; |
| 918 | |
Alyssa Rosenzweig | 67a34ac | 2019-06-14 16:26:49 -0700 | [diff] [blame] | 919 | /* In the hardware, array_size refers specifically to array textures, |
| 920 | * whereas in Gallium, it also covers cubemaps */ |
| 921 | |
| 922 | unsigned array_size = texture->array_size; |
| 923 | |
Alyssa Rosenzweig | 0ad17f5 | 2019-06-24 14:39:37 -0700 | [diff] [blame] | 924 | if (template->target == PIPE_TEXTURE_CUBE) { |
Alyssa Rosenzweig | 67a34ac | 2019-06-14 16:26:49 -0700 | [diff] [blame] | 925 | /* TODO: Cubemap arrays */ |
| 926 | assert(array_size == 6); |
Alyssa Rosenzweig | eb3c097 | 2019-06-21 17:27:05 -0700 | [diff] [blame] | 927 | array_size /= 6; |
Alyssa Rosenzweig | 67a34ac | 2019-06-14 16:26:49 -0700 | [diff] [blame] | 928 | } |
| 929 | |
Alyssa Rosenzweig | b929565 | 2020-02-18 14:20:16 -0500 | [diff] [blame] | 930 | enum mali_texture_type type = |
| 931 | panfrost_translate_texture_type(template->target); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 932 | |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 933 | if (device->quirks & IS_BIFROST) { |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 934 | const struct util_format_description *desc = |
| 935 | util_format_description(template->format); |
| 936 | unsigned char composed_swizzle[4]; |
| 937 | util_format_compose_swizzles(desc->swizzle, user_swizzle, composed_swizzle); |
| 938 | |
| 939 | unsigned size = panfrost_estimate_texture_payload_size( |
| 940 | template->u.tex.first_level, |
| 941 | template->u.tex.last_level, |
| 942 | template->u.tex.first_layer, |
| 943 | template->u.tex.last_layer, |
| 944 | type, prsrc->layout); |
| 945 | |
| 946 | so->bifrost_bo = pan_bo_create(device, size, 0); |
| 947 | |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 948 | so->bifrost_descriptor = rzalloc(pctx, struct bifrost_texture_descriptor); |
| 949 | panfrost_new_texture_bifrost( |
| 950 | so->bifrost_descriptor, |
| 951 | texture->width0, texture->height0, |
| 952 | texture->depth0, array_size, |
| 953 | template->format, |
| 954 | type, prsrc->layout, |
| 955 | template->u.tex.first_level, |
| 956 | template->u.tex.last_level, |
| 957 | template->u.tex.first_layer, |
| 958 | template->u.tex.last_layer, |
| 959 | prsrc->cubemap_stride, |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 960 | panfrost_translate_swizzle_4(composed_swizzle), |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 961 | prsrc->bo->gpu, |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 962 | prsrc->slices, |
| 963 | so->bifrost_bo); |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 964 | } else { |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 965 | unsigned size = panfrost_estimate_texture_payload_size( |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 966 | template->u.tex.first_level, |
| 967 | template->u.tex.last_level, |
| 968 | template->u.tex.first_layer, |
| 969 | template->u.tex.last_layer, |
| 970 | type, prsrc->layout); |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 971 | size += sizeof(struct mali_texture_descriptor); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 972 | |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 973 | so->midgard_bo = pan_bo_create(device, size, 0); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 974 | |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 975 | panfrost_new_texture( |
| 976 | so->midgard_bo->cpu, |
| 977 | texture->width0, texture->height0, |
| 978 | texture->depth0, array_size, |
| 979 | template->format, |
| 980 | type, prsrc->layout, |
| 981 | template->u.tex.first_level, |
| 982 | template->u.tex.last_level, |
| 983 | template->u.tex.first_layer, |
| 984 | template->u.tex.last_layer, |
| 985 | prsrc->cubemap_stride, |
| 986 | panfrost_translate_swizzle_4(user_swizzle), |
| 987 | prsrc->bo->gpu, |
| 988 | prsrc->slices); |
| 989 | } |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 990 | |
| 991 | return (struct pipe_sampler_view *) so; |
| 992 | } |
| 993 | |
| 994 | static void |
| 995 | panfrost_set_sampler_views( |
| 996 | struct pipe_context *pctx, |
| 997 | enum pipe_shader_type shader, |
| 998 | unsigned start_slot, unsigned num_views, |
| 999 | struct pipe_sampler_view **views) |
| 1000 | { |
| 1001 | struct panfrost_context *ctx = pan_context(pctx); |
Tomeu Vizoso | 5dfe412 | 2019-12-12 08:43:12 +0100 | [diff] [blame] | 1002 | unsigned new_nr = 0; |
| 1003 | unsigned i; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1004 | |
| 1005 | assert(start_slot == 0); |
| 1006 | |
Tomeu Vizoso | 5dfe412 | 2019-12-12 08:43:12 +0100 | [diff] [blame] | 1007 | for (i = 0; i < num_views; ++i) { |
Alyssa Rosenzweig | 0219b99 | 2019-06-11 14:21:14 -0700 | [diff] [blame] | 1008 | if (views[i]) |
| 1009 | new_nr = i + 1; |
Tomeu Vizoso | 5dfe412 | 2019-12-12 08:43:12 +0100 | [diff] [blame] | 1010 | pipe_sampler_view_reference((struct pipe_sampler_view **)&ctx->sampler_views[shader][i], |
| 1011 | views[i]); |
Alyssa Rosenzweig | 0219b99 | 2019-06-11 14:21:14 -0700 | [diff] [blame] | 1012 | } |
| 1013 | |
Tomeu Vizoso | 5dfe412 | 2019-12-12 08:43:12 +0100 | [diff] [blame] | 1014 | for (; i < ctx->sampler_view_count[shader]; i++) { |
| 1015 | pipe_sampler_view_reference((struct pipe_sampler_view **)&ctx->sampler_views[shader][i], |
| 1016 | NULL); |
| 1017 | } |
Alyssa Rosenzweig | 0219b99 | 2019-06-11 14:21:14 -0700 | [diff] [blame] | 1018 | ctx->sampler_view_count[shader] = new_nr; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1019 | } |
| 1020 | |
| 1021 | static void |
| 1022 | panfrost_sampler_view_destroy( |
| 1023 | struct pipe_context *pctx, |
Alyssa Rosenzweig | b929565 | 2020-02-18 14:20:16 -0500 | [diff] [blame] | 1024 | struct pipe_sampler_view *pview) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1025 | { |
Alyssa Rosenzweig | b929565 | 2020-02-18 14:20:16 -0500 | [diff] [blame] | 1026 | struct panfrost_sampler_view *view = (struct panfrost_sampler_view *) pview; |
| 1027 | |
| 1028 | pipe_resource_reference(&pview->texture, NULL); |
Tomeu Vizoso | d3eb23a | 2020-04-17 14:23:39 +0200 | [diff] [blame] | 1029 | panfrost_bo_unreference(view->midgard_bo); |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 1030 | panfrost_bo_unreference(view->bifrost_bo); |
Tomeu Vizoso | d3eb23a | 2020-04-17 14:23:39 +0200 | [diff] [blame] | 1031 | if (view->bifrost_descriptor) |
| 1032 | ralloc_free(view->bifrost_descriptor); |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1033 | ralloc_free(view); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1034 | } |
| 1035 | |
Alyssa Rosenzweig | 4e736b8 | 2019-08-01 10:31:35 -0700 | [diff] [blame] | 1036 | static void |
| 1037 | panfrost_set_shader_buffers( |
| 1038 | struct pipe_context *pctx, |
| 1039 | enum pipe_shader_type shader, |
| 1040 | unsigned start, unsigned count, |
| 1041 | const struct pipe_shader_buffer *buffers, |
| 1042 | unsigned writable_bitmask) |
| 1043 | { |
| 1044 | struct panfrost_context *ctx = pan_context(pctx); |
| 1045 | |
| 1046 | util_set_shader_buffers_mask(ctx->ssbo[shader], &ctx->ssbo_mask[shader], |
| 1047 | buffers, start, count); |
| 1048 | } |
| 1049 | |
Alyssa Rosenzweig | 5ad00fb | 2019-07-15 14:15:24 -0700 | [diff] [blame] | 1050 | /* Hints that a framebuffer should use AFBC where possible */ |
| 1051 | |
| 1052 | static void |
| 1053 | panfrost_hint_afbc( |
Alyssa Rosenzweig | ca8c625 | 2020-03-23 18:44:21 -0400 | [diff] [blame] | 1054 | struct panfrost_device *device, |
Alyssa Rosenzweig | 5ad00fb | 2019-07-15 14:15:24 -0700 | [diff] [blame] | 1055 | const struct pipe_framebuffer_state *fb) |
| 1056 | { |
| 1057 | /* AFBC implemenation incomplete; hide it */ |
| 1058 | if (!(pan_debug & PAN_DBG_AFBC)) return; |
| 1059 | |
| 1060 | /* Hint AFBC to the resources bound to each color buffer */ |
| 1061 | |
| 1062 | for (unsigned i = 0; i < fb->nr_cbufs; ++i) { |
| 1063 | struct pipe_surface *surf = fb->cbufs[i]; |
| 1064 | struct panfrost_resource *rsrc = pan_resource(surf->texture); |
Alyssa Rosenzweig | ca8c625 | 2020-03-23 18:44:21 -0400 | [diff] [blame] | 1065 | panfrost_resource_hint_layout(device, rsrc, MALI_TEXTURE_AFBC, 1); |
Alyssa Rosenzweig | 5ad00fb | 2019-07-15 14:15:24 -0700 | [diff] [blame] | 1066 | } |
| 1067 | |
| 1068 | /* Also hint it to the depth buffer */ |
| 1069 | |
| 1070 | if (fb->zsbuf) { |
| 1071 | struct panfrost_resource *rsrc = pan_resource(fb->zsbuf->texture); |
Alyssa Rosenzweig | ca8c625 | 2020-03-23 18:44:21 -0400 | [diff] [blame] | 1072 | panfrost_resource_hint_layout(device, rsrc, MALI_TEXTURE_AFBC, 1); |
Alyssa Rosenzweig | 5ad00fb | 2019-07-15 14:15:24 -0700 | [diff] [blame] | 1073 | } |
| 1074 | } |
| 1075 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1076 | static void |
| 1077 | panfrost_set_framebuffer_state(struct pipe_context *pctx, |
| 1078 | const struct pipe_framebuffer_state *fb) |
| 1079 | { |
| 1080 | struct panfrost_context *ctx = pan_context(pctx); |
| 1081 | |
Alyssa Rosenzweig | ca8c625 | 2020-03-23 18:44:21 -0400 | [diff] [blame] | 1082 | panfrost_hint_afbc(pan_device(pctx->screen), fb); |
Alyssa Rosenzweig | 629c736 | 2019-07-18 11:05:01 -0700 | [diff] [blame] | 1083 | util_copy_framebuffer_state(&ctx->pipe_framebuffer, fb); |
Boris Brezillon | 1ac33aa | 2019-09-15 20:33:13 +0200 | [diff] [blame] | 1084 | ctx->batch = NULL; |
| 1085 | panfrost_invalidate_frame(ctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1086 | } |
| 1087 | |
| 1088 | static void * |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1089 | panfrost_create_depth_stencil_state(struct pipe_context *pipe, |
| 1090 | const struct pipe_depth_stencil_alpha_state *depth_stencil) |
| 1091 | { |
| 1092 | return mem_dup(depth_stencil, sizeof(*depth_stencil)); |
| 1093 | } |
| 1094 | |
| 1095 | static void |
| 1096 | panfrost_bind_depth_stencil_state(struct pipe_context *pipe, |
| 1097 | void *cso) |
| 1098 | { |
| 1099 | struct panfrost_context *ctx = pan_context(pipe); |
| 1100 | struct pipe_depth_stencil_alpha_state *depth_stencil = cso; |
| 1101 | ctx->depth_stencil = depth_stencil; |
| 1102 | |
| 1103 | if (!depth_stencil) |
| 1104 | return; |
| 1105 | |
| 1106 | /* Alpha does not exist in the hardware (it's not in ES3), so it's |
| 1107 | * emulated in the fragment shader */ |
| 1108 | |
| 1109 | if (depth_stencil->alpha.enabled) { |
| 1110 | /* We need to trigger a new shader (maybe) */ |
Alyssa Rosenzweig | ac6aa93 | 2019-07-31 14:13:30 -0700 | [diff] [blame] | 1111 | ctx->base.bind_fs_state(&ctx->base, ctx->shader[PIPE_SHADER_FRAGMENT]); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1112 | } |
| 1113 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1114 | /* Bounds test not implemented */ |
| 1115 | assert(!depth_stencil->depth.bounds_test); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1116 | } |
| 1117 | |
| 1118 | static void |
| 1119 | panfrost_delete_depth_stencil_state(struct pipe_context *pipe, void *depth) |
| 1120 | { |
| 1121 | free( depth ); |
| 1122 | } |
| 1123 | |
| 1124 | static void |
| 1125 | panfrost_set_sample_mask(struct pipe_context *pipe, |
| 1126 | unsigned sample_mask) |
| 1127 | { |
| 1128 | } |
| 1129 | |
| 1130 | static void |
| 1131 | panfrost_set_clip_state(struct pipe_context *pipe, |
| 1132 | const struct pipe_clip_state *clip) |
| 1133 | { |
| 1134 | //struct panfrost_context *panfrost = pan_context(pipe); |
| 1135 | } |
| 1136 | |
| 1137 | static void |
| 1138 | panfrost_set_viewport_states(struct pipe_context *pipe, |
| 1139 | unsigned start_slot, |
| 1140 | unsigned num_viewports, |
| 1141 | const struct pipe_viewport_state *viewports) |
| 1142 | { |
| 1143 | struct panfrost_context *ctx = pan_context(pipe); |
| 1144 | |
| 1145 | assert(start_slot == 0); |
| 1146 | assert(num_viewports == 1); |
| 1147 | |
| 1148 | ctx->pipe_viewport = *viewports; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1149 | } |
| 1150 | |
| 1151 | static void |
| 1152 | panfrost_set_scissor_states(struct pipe_context *pipe, |
| 1153 | unsigned start_slot, |
| 1154 | unsigned num_scissors, |
| 1155 | const struct pipe_scissor_state *scissors) |
| 1156 | { |
| 1157 | struct panfrost_context *ctx = pan_context(pipe); |
| 1158 | |
| 1159 | assert(start_slot == 0); |
| 1160 | assert(num_scissors == 1); |
| 1161 | |
| 1162 | ctx->scissor = *scissors; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1163 | } |
| 1164 | |
| 1165 | static void |
| 1166 | panfrost_set_polygon_stipple(struct pipe_context *pipe, |
| 1167 | const struct pipe_poly_stipple *stipple) |
| 1168 | { |
| 1169 | //struct panfrost_context *panfrost = pan_context(pipe); |
| 1170 | } |
| 1171 | |
| 1172 | static void |
| 1173 | panfrost_set_active_query_state(struct pipe_context *pipe, |
Ilia Mirkin | 0e30c6b | 2019-07-04 11:41:41 -0400 | [diff] [blame] | 1174 | bool enable) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1175 | { |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1176 | struct panfrost_context *ctx = pan_context(pipe); |
| 1177 | ctx->active_queries = enable; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1178 | } |
| 1179 | |
| 1180 | static void |
| 1181 | panfrost_destroy(struct pipe_context *pipe) |
| 1182 | { |
| 1183 | struct panfrost_context *panfrost = pan_context(pipe); |
| 1184 | |
| 1185 | if (panfrost->blitter) |
| 1186 | util_blitter_destroy(panfrost->blitter); |
Tomeu Vizoso | 756f7b9 | 2019-03-08 10:27:07 +0100 | [diff] [blame] | 1187 | |
Alyssa Rosenzweig | 7005c0d | 2019-06-23 11:05:10 -0700 | [diff] [blame] | 1188 | if (panfrost->blitter_wallpaper) |
| 1189 | util_blitter_destroy(panfrost->blitter_wallpaper); |
| 1190 | |
Boris Brezillon | b60ed3c | 2019-11-06 15:52:45 +0100 | [diff] [blame] | 1191 | util_unreference_framebuffer_state(&panfrost->pipe_framebuffer); |
Boris Brezillon | 8c8e4fd | 2019-11-06 15:49:43 +0100 | [diff] [blame] | 1192 | u_upload_destroy(pipe->stream_uploader); |
| 1193 | |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1194 | ralloc_free(pipe); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1195 | } |
| 1196 | |
| 1197 | static struct pipe_query * |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1198 | panfrost_create_query(struct pipe_context *pipe, |
| 1199 | unsigned type, |
| 1200 | unsigned index) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1201 | { |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1202 | struct panfrost_query *q = rzalloc(pipe, struct panfrost_query); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1203 | |
| 1204 | q->type = type; |
| 1205 | q->index = index; |
| 1206 | |
| 1207 | return (struct pipe_query *) q; |
| 1208 | } |
| 1209 | |
| 1210 | static void |
| 1211 | panfrost_destroy_query(struct pipe_context *pipe, struct pipe_query *q) |
| 1212 | { |
Urja Rannikko | dff99ce | 2019-10-22 12:05:07 +0000 | [diff] [blame] | 1213 | struct panfrost_query *query = (struct panfrost_query *) q; |
| 1214 | |
| 1215 | if (query->bo) { |
| 1216 | panfrost_bo_unreference(query->bo); |
| 1217 | query->bo = NULL; |
| 1218 | } |
| 1219 | |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1220 | ralloc_free(q); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1221 | } |
| 1222 | |
Ilia Mirkin | 0e30c6b | 2019-07-04 11:41:41 -0400 | [diff] [blame] | 1223 | static bool |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1224 | panfrost_begin_query(struct pipe_context *pipe, struct pipe_query *q) |
| 1225 | { |
| 1226 | struct panfrost_context *ctx = pan_context(pipe); |
| 1227 | struct panfrost_query *query = (struct panfrost_query *) q; |
| 1228 | |
| 1229 | switch (query->type) { |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1230 | case PIPE_QUERY_OCCLUSION_COUNTER: |
| 1231 | case PIPE_QUERY_OCCLUSION_PREDICATE: |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1232 | case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: |
Urja Rannikko | dff99ce | 2019-10-22 12:05:07 +0000 | [diff] [blame] | 1233 | /* Allocate a bo for the query results to be stored */ |
| 1234 | if (!query->bo) { |
Alyssa Rosenzweig | 0f65f00 | 2020-03-23 19:36:46 -0400 | [diff] [blame] | 1235 | query->bo = pan_bo_create( |
Alyssa Rosenzweig | ca8c625 | 2020-03-23 18:44:21 -0400 | [diff] [blame] | 1236 | pan_device(ctx->base.screen), |
Urja Rannikko | dff99ce | 2019-10-22 12:05:07 +0000 | [diff] [blame] | 1237 | sizeof(unsigned), 0); |
| 1238 | } |
| 1239 | |
| 1240 | unsigned *result = (unsigned *)query->bo->cpu; |
| 1241 | *result = 0; /* Default to 0 if nothing at all drawn. */ |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1242 | ctx->occlusion_query = query; |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1243 | break; |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1244 | |
| 1245 | /* Geometry statistics are computed in the driver. XXX: geom/tess |
| 1246 | * shaders.. */ |
| 1247 | |
| 1248 | case PIPE_QUERY_PRIMITIVES_GENERATED: |
| 1249 | query->start = ctx->prims_generated; |
| 1250 | break; |
| 1251 | case PIPE_QUERY_PRIMITIVES_EMITTED: |
| 1252 | query->start = ctx->tf_prims_generated; |
| 1253 | break; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1254 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1255 | default: |
Tomeu Vizoso | d902e23 | 2020-01-06 10:48:20 +0100 | [diff] [blame] | 1256 | DBG("Skipping query %u\n", query->type); |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1257 | break; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1258 | } |
| 1259 | |
| 1260 | return true; |
| 1261 | } |
| 1262 | |
| 1263 | static bool |
| 1264 | panfrost_end_query(struct pipe_context *pipe, struct pipe_query *q) |
| 1265 | { |
| 1266 | struct panfrost_context *ctx = pan_context(pipe); |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1267 | struct panfrost_query *query = (struct panfrost_query *) q; |
| 1268 | |
| 1269 | switch (query->type) { |
| 1270 | case PIPE_QUERY_OCCLUSION_COUNTER: |
| 1271 | case PIPE_QUERY_OCCLUSION_PREDICATE: |
| 1272 | case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: |
| 1273 | ctx->occlusion_query = NULL; |
| 1274 | break; |
| 1275 | case PIPE_QUERY_PRIMITIVES_GENERATED: |
| 1276 | query->end = ctx->prims_generated; |
| 1277 | break; |
| 1278 | case PIPE_QUERY_PRIMITIVES_EMITTED: |
| 1279 | query->end = ctx->tf_prims_generated; |
| 1280 | break; |
| 1281 | } |
| 1282 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1283 | return true; |
| 1284 | } |
| 1285 | |
Ilia Mirkin | 0e30c6b | 2019-07-04 11:41:41 -0400 | [diff] [blame] | 1286 | static bool |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1287 | panfrost_get_query_result(struct pipe_context *pipe, |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1288 | struct pipe_query *q, |
Ilia Mirkin | 0e30c6b | 2019-07-04 11:41:41 -0400 | [diff] [blame] | 1289 | bool wait, |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1290 | union pipe_query_result *vresult) |
| 1291 | { |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1292 | struct panfrost_query *query = (struct panfrost_query *) q; |
Boris Brezillon | a45984b | 2019-09-15 19:15:16 +0200 | [diff] [blame] | 1293 | struct panfrost_context *ctx = pan_context(pipe); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1294 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1295 | |
| 1296 | switch (query->type) { |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1297 | case PIPE_QUERY_OCCLUSION_COUNTER: |
| 1298 | case PIPE_QUERY_OCCLUSION_PREDICATE: |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1299 | case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: |
| 1300 | /* Flush first */ |
Boris Brezillon | a45984b | 2019-09-15 19:15:16 +0200 | [diff] [blame] | 1301 | panfrost_flush_all_batches(ctx, true); |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1302 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1303 | /* Read back the query results */ |
Urja Rannikko | dff99ce | 2019-10-22 12:05:07 +0000 | [diff] [blame] | 1304 | unsigned *result = (unsigned *) query->bo->cpu; |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1305 | unsigned passed = *result; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1306 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1307 | if (query->type == PIPE_QUERY_OCCLUSION_COUNTER) { |
| 1308 | vresult->u64 = passed; |
| 1309 | } else { |
| 1310 | vresult->b = !!passed; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1311 | } |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1312 | |
| 1313 | break; |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1314 | |
| 1315 | case PIPE_QUERY_PRIMITIVES_GENERATED: |
| 1316 | case PIPE_QUERY_PRIMITIVES_EMITTED: |
Boris Brezillon | a45984b | 2019-09-15 19:15:16 +0200 | [diff] [blame] | 1317 | panfrost_flush_all_batches(ctx, true); |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1318 | vresult->u64 = query->end - query->start; |
| 1319 | break; |
| 1320 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1321 | default: |
Alyssa Rosenzweig | 42f0aae | 2019-08-30 17:37:22 -0700 | [diff] [blame] | 1322 | DBG("Skipped query get %u\n", query->type); |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1323 | break; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1324 | } |
| 1325 | |
| 1326 | return true; |
| 1327 | } |
| 1328 | |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1329 | static struct pipe_stream_output_target * |
| 1330 | panfrost_create_stream_output_target(struct pipe_context *pctx, |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1331 | struct pipe_resource *prsc, |
| 1332 | unsigned buffer_offset, |
| 1333 | unsigned buffer_size) |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1334 | { |
| 1335 | struct pipe_stream_output_target *target; |
| 1336 | |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1337 | target = rzalloc(pctx, struct pipe_stream_output_target); |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1338 | |
| 1339 | if (!target) |
| 1340 | return NULL; |
| 1341 | |
| 1342 | pipe_reference_init(&target->reference, 1); |
| 1343 | pipe_resource_reference(&target->buffer, prsc); |
| 1344 | |
| 1345 | target->context = pctx; |
| 1346 | target->buffer_offset = buffer_offset; |
| 1347 | target->buffer_size = buffer_size; |
| 1348 | |
| 1349 | return target; |
| 1350 | } |
| 1351 | |
| 1352 | static void |
| 1353 | panfrost_stream_output_target_destroy(struct pipe_context *pctx, |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1354 | struct pipe_stream_output_target *target) |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1355 | { |
| 1356 | pipe_resource_reference(&target->buffer, NULL); |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1357 | ralloc_free(target); |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1358 | } |
| 1359 | |
| 1360 | static void |
| 1361 | panfrost_set_stream_output_targets(struct pipe_context *pctx, |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1362 | unsigned num_targets, |
| 1363 | struct pipe_stream_output_target **targets, |
| 1364 | const unsigned *offsets) |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1365 | { |
Alyssa Rosenzweig | 5ff7973 | 2019-08-06 16:43:28 -0700 | [diff] [blame] | 1366 | struct panfrost_context *ctx = pan_context(pctx); |
| 1367 | struct panfrost_streamout *so = &ctx->streamout; |
| 1368 | |
| 1369 | assert(num_targets <= ARRAY_SIZE(so->targets)); |
| 1370 | |
| 1371 | for (unsigned i = 0; i < num_targets; i++) { |
| 1372 | if (offsets[i] != -1) |
| 1373 | so->offsets[i] = offsets[i]; |
| 1374 | |
| 1375 | pipe_so_target_reference(&so->targets[i], targets[i]); |
| 1376 | } |
| 1377 | |
| 1378 | for (unsigned i = 0; i < so->num_targets; i++) |
| 1379 | pipe_so_target_reference(&so->targets[i], NULL); |
| 1380 | |
| 1381 | so->num_targets = num_targets; |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1382 | } |
| 1383 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1384 | struct pipe_context * |
| 1385 | panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags) |
| 1386 | { |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1387 | struct panfrost_context *ctx = rzalloc(screen, struct panfrost_context); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1388 | struct pipe_context *gallium = (struct pipe_context *) ctx; |
Tomeu Vizoso | 756f7b9 | 2019-03-08 10:27:07 +0100 | [diff] [blame] | 1389 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1390 | gallium->screen = screen; |
| 1391 | |
| 1392 | gallium->destroy = panfrost_destroy; |
| 1393 | |
| 1394 | gallium->set_framebuffer_state = panfrost_set_framebuffer_state; |
| 1395 | |
| 1396 | gallium->flush = panfrost_flush; |
| 1397 | gallium->clear = panfrost_clear; |
| 1398 | gallium->draw_vbo = panfrost_draw_vbo; |
| 1399 | |
| 1400 | gallium->set_vertex_buffers = panfrost_set_vertex_buffers; |
| 1401 | gallium->set_constant_buffer = panfrost_set_constant_buffer; |
Alyssa Rosenzweig | 4e736b8 | 2019-08-01 10:31:35 -0700 | [diff] [blame] | 1402 | gallium->set_shader_buffers = panfrost_set_shader_buffers; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1403 | |
| 1404 | gallium->set_stencil_ref = panfrost_set_stencil_ref; |
| 1405 | |
| 1406 | gallium->create_sampler_view = panfrost_create_sampler_view; |
| 1407 | gallium->set_sampler_views = panfrost_set_sampler_views; |
| 1408 | gallium->sampler_view_destroy = panfrost_sampler_view_destroy; |
| 1409 | |
| 1410 | gallium->create_rasterizer_state = panfrost_create_rasterizer_state; |
| 1411 | gallium->bind_rasterizer_state = panfrost_bind_rasterizer_state; |
| 1412 | gallium->delete_rasterizer_state = panfrost_generic_cso_delete; |
| 1413 | |
| 1414 | gallium->create_vertex_elements_state = panfrost_create_vertex_elements_state; |
| 1415 | gallium->bind_vertex_elements_state = panfrost_bind_vertex_elements_state; |
Alyssa Rosenzweig | 81d3262 | 2019-05-17 00:14:49 +0000 | [diff] [blame] | 1416 | gallium->delete_vertex_elements_state = panfrost_generic_cso_delete; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1417 | |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 1418 | gallium->create_fs_state = panfrost_create_fs_state; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1419 | gallium->delete_fs_state = panfrost_delete_shader_state; |
| 1420 | gallium->bind_fs_state = panfrost_bind_fs_state; |
| 1421 | |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 1422 | gallium->create_vs_state = panfrost_create_vs_state; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1423 | gallium->delete_vs_state = panfrost_delete_shader_state; |
| 1424 | gallium->bind_vs_state = panfrost_bind_vs_state; |
| 1425 | |
| 1426 | gallium->create_sampler_state = panfrost_create_sampler_state; |
| 1427 | gallium->delete_sampler_state = panfrost_generic_cso_delete; |
| 1428 | gallium->bind_sampler_states = panfrost_bind_sampler_states; |
| 1429 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1430 | gallium->create_depth_stencil_alpha_state = panfrost_create_depth_stencil_state; |
| 1431 | gallium->bind_depth_stencil_alpha_state = panfrost_bind_depth_stencil_state; |
| 1432 | gallium->delete_depth_stencil_alpha_state = panfrost_delete_depth_stencil_state; |
| 1433 | |
| 1434 | gallium->set_sample_mask = panfrost_set_sample_mask; |
| 1435 | |
| 1436 | gallium->set_clip_state = panfrost_set_clip_state; |
| 1437 | gallium->set_viewport_states = panfrost_set_viewport_states; |
| 1438 | gallium->set_scissor_states = panfrost_set_scissor_states; |
| 1439 | gallium->set_polygon_stipple = panfrost_set_polygon_stipple; |
| 1440 | gallium->set_active_query_state = panfrost_set_active_query_state; |
| 1441 | |
| 1442 | gallium->create_query = panfrost_create_query; |
| 1443 | gallium->destroy_query = panfrost_destroy_query; |
| 1444 | gallium->begin_query = panfrost_begin_query; |
| 1445 | gallium->end_query = panfrost_end_query; |
| 1446 | gallium->get_query_result = panfrost_get_query_result; |
| 1447 | |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1448 | gallium->create_stream_output_target = panfrost_create_stream_output_target; |
| 1449 | gallium->stream_output_target_destroy = panfrost_stream_output_target_destroy; |
| 1450 | gallium->set_stream_output_targets = panfrost_set_stream_output_targets; |
| 1451 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1452 | panfrost_resource_context_init(gallium); |
Alyssa Rosenzweig | 46396af | 2019-07-05 15:40:08 -0700 | [diff] [blame] | 1453 | panfrost_blend_context_init(gallium); |
Alyssa Rosenzweig | a8fc40a | 2019-07-23 08:28:23 -0700 | [diff] [blame] | 1454 | panfrost_compute_context_init(gallium); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1455 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1456 | /* XXX: leaks */ |
| 1457 | gallium->stream_uploader = u_upload_create_default(gallium); |
| 1458 | gallium->const_uploader = gallium->stream_uploader; |
| 1459 | assert(gallium->stream_uploader); |
| 1460 | |
Alyssa Rosenzweig | 85e2bb5 | 2019-02-08 02:28:12 +0000 | [diff] [blame] | 1461 | /* Midgard supports ES modes, plus QUADS/QUAD_STRIPS/POLYGON */ |
| 1462 | ctx->draw_modes = (1 << (PIPE_PRIM_POLYGON + 1)) - 1; |
| 1463 | |
| 1464 | ctx->primconvert = util_primconvert_create(gallium, ctx->draw_modes); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1465 | |
| 1466 | ctx->blitter = util_blitter_create(gallium); |
Alyssa Rosenzweig | 7005c0d | 2019-06-23 11:05:10 -0700 | [diff] [blame] | 1467 | ctx->blitter_wallpaper = util_blitter_create(gallium); |
| 1468 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1469 | assert(ctx->blitter); |
Alyssa Rosenzweig | 7005c0d | 2019-06-23 11:05:10 -0700 | [diff] [blame] | 1470 | assert(ctx->blitter_wallpaper); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1471 | |
| 1472 | /* Prepare for render! */ |
| 1473 | |
Boris Brezillon | 2c52699 | 2019-09-05 21:41:26 +0200 | [diff] [blame] | 1474 | panfrost_batch_init(ctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1475 | panfrost_invalidate_frame(ctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1476 | |
| 1477 | return gallium; |
| 1478 | } |