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 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 51 | #include "midgard_pack.h" |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 52 | #include "pan_screen.h" |
| 53 | #include "pan_blending.h" |
| 54 | #include "pan_blend_shaders.h" |
Boris Brezillon | a72bab1 | 2020-03-05 09:30:58 +0100 | [diff] [blame] | 55 | #include "pan_cmdstream.h" |
Tomeu Vizoso | 97f2d04 | 2019-03-08 15:24:57 +0100 | [diff] [blame] | 56 | #include "pan_util.h" |
Alyssa Rosenzweig | 1c62b55 | 2020-08-05 16:16:00 -0400 | [diff] [blame] | 57 | #include "decode.h" |
Icecream95 | d16d136 | 2020-07-07 15:06:08 +1200 | [diff] [blame] | 58 | #include "util/pan_lower_framebuffer.h" |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 59 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 60 | void |
| 61 | panfrost_emit_midg_tiler(struct panfrost_batch *batch, |
| 62 | struct mali_midgard_tiler_packed *tp, |
| 63 | unsigned vertex_count) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 64 | { |
Alyssa Rosenzweig | ca8c625 | 2020-03-23 18:44:21 -0400 | [diff] [blame] | 65 | struct panfrost_device *device = pan_device(batch->ctx->base.screen); |
| 66 | bool hierarchy = !(device->quirks & MIDGARD_NO_HIER_TILING); |
Boris Brezillon | aa851a6 | 2019-09-01 10:30:39 +0200 | [diff] [blame] | 67 | unsigned height = batch->key.height; |
| 68 | unsigned width = batch->key.width; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 69 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 70 | pan_pack(tp, MIDGARD_TILER, t) { |
| 71 | t.hierarchy_mask = |
| 72 | panfrost_choose_hierarchy_mask(width, height, |
| 73 | vertex_count, hierarchy); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 74 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 75 | /* Compute the polygon header size and use that to offset the body */ |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 76 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 77 | unsigned header_size = |
| 78 | panfrost_tiler_header_size(width, height, |
| 79 | t.hierarchy_mask, hierarchy); |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 80 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 81 | t.polygon_list_size = |
| 82 | panfrost_tiler_full_size(width, height, t.hierarchy_mask, |
| 83 | hierarchy); |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 84 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 85 | if (vertex_count) { |
| 86 | t.polygon_list = |
| 87 | panfrost_batch_get_polygon_list(batch, |
| 88 | header_size + |
| 89 | t.polygon_list_size); |
Alyssa Rosenzweig | f5c2934 | 2019-08-19 14:30:53 -0700 | [diff] [blame] | 90 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 91 | t.heap_start = device->tiler_heap->gpu; |
| 92 | t.heap_end = device->tiler_heap->gpu + |
| 93 | device->tiler_heap->size; |
| 94 | } else { |
| 95 | struct panfrost_bo *tiler_dummy; |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 96 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 97 | tiler_dummy = panfrost_batch_get_tiler_dummy(batch); |
| 98 | header_size = MALI_MIDGARD_TILER_MINIMUM_HEADER_SIZE; |
Boris Brezillon | 1e483a8 | 2019-09-14 19:18:51 +0200 | [diff] [blame] | 99 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 100 | /* The tiler is disabled, so don't allow the tiler heap */ |
| 101 | t.heap_start = tiler_dummy->gpu; |
| 102 | t.heap_end = t.heap_start; |
Boris Brezillon | 1e483a8 | 2019-09-14 19:18:51 +0200 | [diff] [blame] | 103 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 104 | /* Use a dummy polygon list */ |
| 105 | t.polygon_list = tiler_dummy->gpu; |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 106 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 107 | /* Disable the tiler */ |
| 108 | if (hierarchy) |
| 109 | t.hierarchy_mask |= MALI_MIDGARD_TILER_DISABLED; |
| 110 | else { |
| 111 | t.hierarchy_mask = MALI_MIDGARD_TILER_USER; |
| 112 | t.polygon_list_size = MALI_MIDGARD_TILER_MINIMUM_HEADER_SIZE + 4; |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 113 | |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 114 | /* We don't have a WRITE_VALUE job, so write the polygon list manually */ |
| 115 | uint32_t *polygon_list_body = (uint32_t *) (tiler_dummy->cpu + header_size); |
| 116 | polygon_list_body[0] = 0xa0000000; /* TODO: Just that? */ |
| 117 | } |
Tomeu Vizoso | 6469c1a | 2019-10-29 15:42:03 +0100 | [diff] [blame] | 118 | } |
Boris Brezillon | e855698 | 2020-09-05 18:16:37 +0200 | [diff] [blame] | 119 | t.polygon_list_body = t.polygon_list + header_size; |
Alyssa Rosenzweig | 31fc52a | 2019-07-10 07:22:19 -0700 | [diff] [blame] | 120 | } |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 121 | } |
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 | static void |
| 124 | panfrost_clear( |
| 125 | struct pipe_context *pipe, |
| 126 | unsigned buffers, |
Mike Blumenkrantz | 1c8bcad | 2020-03-24 12:02:51 -0400 | [diff] [blame] | 127 | const struct pipe_scissor_state *scissor_state, |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 128 | const union pipe_color_union *color, |
| 129 | double depth, unsigned stencil) |
| 130 | { |
| 131 | struct panfrost_context *ctx = pan_context(pipe); |
Boris Brezillon | c138ca8 | 2019-09-19 15:52:02 +0200 | [diff] [blame] | 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 |
Alyssa Rosenzweig | adf716d | 2019-12-05 09:06:53 -0500 | [diff] [blame] | 137 | * fragment jobs. |
Boris Brezillon | c138ca8 | 2019-09-19 15:52:02 +0200 | [diff] [blame] | 138 | */ |
| 139 | struct panfrost_batch *batch = panfrost_get_fresh_batch_for_fbo(ctx); |
Boris Brezillon | 12d8a17 | 2019-09-05 21:41:28 +0200 | [diff] [blame] | 140 | panfrost_batch_clear(batch, buffers, color, depth, stencil); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 141 | } |
| 142 | |
Boris Brezillon | a0402f7 | 2020-03-05 17:24:39 +0100 | [diff] [blame] | 143 | bool |
Alyssa Rosenzweig | 89b02bf | 2019-04-13 00:10:20 +0000 | [diff] [blame] | 144 | panfrost_writes_point_size(struct panfrost_context *ctx) |
| 145 | { |
Alyssa Rosenzweig | ac6aa93 | 2019-07-31 14:13:30 -0700 | [diff] [blame] | 146 | assert(ctx->shader[PIPE_SHADER_VERTEX]); |
Boris Brezillon | b28f4bb | 2020-03-05 10:46:39 +0100 | [diff] [blame] | 147 | 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] | 148 | |
Boris Brezillon | 093da77 | 2020-03-06 11:43:38 +0100 | [diff] [blame] | 149 | return vs->writes_point_size && ctx->active_prim == PIPE_PRIM_POINTS; |
Alyssa Rosenzweig | 89b02bf | 2019-04-13 00:10:20 +0000 | [diff] [blame] | 150 | } |
| 151 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 152 | /* The entire frame is in memory -- send it off to the kernel! */ |
| 153 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 154 | void |
| 155 | panfrost_flush( |
| 156 | struct pipe_context *pipe, |
| 157 | struct pipe_fence_handle **fence, |
| 158 | unsigned flags) |
| 159 | { |
| 160 | struct panfrost_context *ctx = pan_context(pipe); |
Alyssa Rosenzweig | ed1910d | 2020-07-07 16:15:45 -0400 | [diff] [blame] | 161 | struct panfrost_device *dev = pan_device(pipe->screen); |
Alyssa Rosenzweig | 64d6f56 | 2020-07-20 13:34:42 -0400 | [diff] [blame] | 162 | uint32_t syncobj = 0; |
Boris Brezillon | b5d8f9b | 2019-09-15 18:23:10 +0200 | [diff] [blame] | 163 | |
Alyssa Rosenzweig | 64d6f56 | 2020-07-20 13:34:42 -0400 | [diff] [blame] | 164 | if (fence) |
| 165 | drmSyncobjCreate(dev->fd, 0, &syncobj); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 166 | |
Boris Brezillon | a45984b | 2019-09-15 19:15:16 +0200 | [diff] [blame] | 167 | /* Submit all pending jobs */ |
Alyssa Rosenzweig | 64d6f56 | 2020-07-20 13:34:42 -0400 | [diff] [blame] | 168 | panfrost_flush_all_batches(ctx, syncobj); |
Boris Brezillon | 2fc91a1 | 2019-09-05 19:14:25 +0200 | [diff] [blame] | 169 | |
| 170 | if (fence) { |
Alyssa Rosenzweig | 64d6f56 | 2020-07-20 13:34:42 -0400 | [diff] [blame] | 171 | struct panfrost_fence *f = panfrost_fence_create(ctx, syncobj); |
Boris Brezillon | 2fc91a1 | 2019-09-05 19:14:25 +0200 | [diff] [blame] | 172 | pipe->screen->fence_reference(pipe->screen, fence, NULL); |
| 173 | *fence = (struct pipe_fence_handle *)f; |
| 174 | } |
Icecream95 | cf2c5a5 | 2020-01-23 10:32:18 +1300 | [diff] [blame] | 175 | |
Alyssa Rosenzweig | ed1910d | 2020-07-07 16:15:45 -0400 | [diff] [blame] | 176 | if (dev->debug & PAN_DBG_TRACE) |
Icecream95 | cf2c5a5 | 2020-01-23 10:32:18 +1300 | [diff] [blame] | 177 | pandecode_next_frame(); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 178 | } |
| 179 | |
Icecream95 | 391ad72 | 2020-07-10 11:19:07 +1200 | [diff] [blame] | 180 | static void |
| 181 | panfrost_texture_barrier(struct pipe_context *pipe, unsigned flags) |
| 182 | { |
| 183 | struct panfrost_context *ctx = pan_context(pipe); |
Alyssa Rosenzweig | 64d6f56 | 2020-07-20 13:34:42 -0400 | [diff] [blame] | 184 | panfrost_flush_all_batches(ctx, 0); |
Icecream95 | 391ad72 | 2020-07-10 11:19:07 +1200 | [diff] [blame] | 185 | } |
| 186 | |
Alyssa Rosenzweig | 32dbc80 | 2020-08-05 18:44:36 -0400 | [diff] [blame] | 187 | #define DEFINE_CASE(c) case PIPE_PRIM_##c: return MALI_DRAW_MODE_##c; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 188 | |
| 189 | static int |
Alyssa Rosenzweig | 3a4d930 | 2020-08-25 13:25:29 -0400 | [diff] [blame] | 190 | pan_draw_mode(enum pipe_prim_type mode) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 191 | { |
| 192 | switch (mode) { |
| 193 | DEFINE_CASE(POINTS); |
| 194 | DEFINE_CASE(LINES); |
| 195 | DEFINE_CASE(LINE_LOOP); |
| 196 | DEFINE_CASE(LINE_STRIP); |
| 197 | DEFINE_CASE(TRIANGLES); |
| 198 | DEFINE_CASE(TRIANGLE_STRIP); |
| 199 | DEFINE_CASE(TRIANGLE_FAN); |
| 200 | DEFINE_CASE(QUADS); |
| 201 | DEFINE_CASE(QUAD_STRIP); |
| 202 | DEFINE_CASE(POLYGON); |
| 203 | |
| 204 | default: |
Alyssa Rosenzweig | c65271c | 2019-05-16 23:42:33 +0000 | [diff] [blame] | 205 | unreachable("Invalid draw mode"); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 206 | } |
| 207 | } |
| 208 | |
| 209 | #undef DEFINE_CASE |
| 210 | |
Alyssa Rosenzweig | 9865b79 | 2019-06-17 09:26:34 -0700 | [diff] [blame] | 211 | static bool |
| 212 | panfrost_scissor_culls_everything(struct panfrost_context *ctx) |
| 213 | { |
| 214 | const struct pipe_scissor_state *ss = &ctx->scissor; |
| 215 | |
| 216 | /* Check if we're scissoring at all */ |
| 217 | |
Alyssa Rosenzweig | ec35159 | 2020-08-14 17:50:44 -0400 | [diff] [blame] | 218 | if (!ctx->rasterizer->base.scissor) |
Alyssa Rosenzweig | 9865b79 | 2019-06-17 09:26:34 -0700 | [diff] [blame] | 219 | return false; |
| 220 | |
Alyssa Rosenzweig | 124f6b5 | 2019-06-24 14:13:20 -0700 | [diff] [blame] | 221 | return (ss->minx == ss->maxx) || (ss->miny == ss->maxy); |
Alyssa Rosenzweig | 9865b79 | 2019-06-17 09:26:34 -0700 | [diff] [blame] | 222 | } |
| 223 | |
Alyssa Rosenzweig | 72fc06d | 2019-08-08 07:10:24 -0700 | [diff] [blame] | 224 | /* Count generated primitives (when there is no geom/tess shaders) for |
| 225 | * transform feedback */ |
| 226 | |
| 227 | static void |
| 228 | panfrost_statistics_record( |
| 229 | struct panfrost_context *ctx, |
| 230 | const struct pipe_draw_info *info) |
| 231 | { |
| 232 | if (!ctx->active_queries) |
| 233 | return; |
| 234 | |
| 235 | uint32_t prims = u_prims_for_vertices(info->mode, info->count); |
| 236 | ctx->prims_generated += prims; |
| 237 | |
Alyssa Rosenzweig | 42f0aae | 2019-08-30 17:37:22 -0700 | [diff] [blame] | 238 | if (!ctx->streamout.num_targets) |
Alyssa Rosenzweig | 72fc06d | 2019-08-08 07:10:24 -0700 | [diff] [blame] | 239 | return; |
| 240 | |
| 241 | ctx->tf_prims_generated += prims; |
| 242 | } |
| 243 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 244 | static void |
Boris Brezillon | 13881a4 | 2020-03-05 21:55:01 +0100 | [diff] [blame] | 245 | panfrost_update_streamout_offsets(struct panfrost_context *ctx) |
| 246 | { |
| 247 | for (unsigned i = 0; i < ctx->streamout.num_targets; ++i) { |
| 248 | unsigned count; |
| 249 | |
| 250 | count = u_stream_outputs_for_vertices(ctx->active_prim, |
| 251 | ctx->vertex_count); |
Ilia Mirkin | 4c050f2 | 2020-08-09 00:13:14 -0400 | [diff] [blame] | 252 | pan_so_target(ctx->streamout.targets[i])->offset += count; |
Boris Brezillon | 13881a4 | 2020-03-05 21:55:01 +0100 | [diff] [blame] | 253 | } |
| 254 | } |
| 255 | |
Alyssa Rosenzweig | 90cc815 | 2020-08-25 14:59:30 -0400 | [diff] [blame] | 256 | static inline void |
| 257 | pan_emit_draw_descs(struct panfrost_batch *batch, |
| 258 | struct MALI_DRAW *d, enum pipe_shader_type st) |
| 259 | { |
| 260 | d->offset_start = batch->ctx->offset_start; |
| 261 | d->instances = batch->ctx->instance_count > 1 ? |
| 262 | batch->ctx->padded_count : 1; |
| 263 | |
| 264 | d->uniform_buffers = panfrost_emit_const_buf(batch, st, &d->push_uniforms); |
| 265 | d->textures = panfrost_emit_texture_descriptors(batch, st); |
| 266 | d->samplers = panfrost_emit_sampler_descriptors(batch, st); |
| 267 | } |
| 268 | |
Alyssa Rosenzweig | b60d567 | 2020-08-25 16:59:14 -0400 | [diff] [blame] | 269 | static enum mali_index_type |
| 270 | panfrost_translate_index_size(unsigned size) |
| 271 | { |
| 272 | switch (size) { |
| 273 | case 1: return MALI_INDEX_TYPE_UINT8; |
| 274 | case 2: return MALI_INDEX_TYPE_UINT16; |
| 275 | case 4: return MALI_INDEX_TYPE_UINT32; |
| 276 | default: unreachable("Invalid index size"); |
| 277 | } |
| 278 | } |
| 279 | |
Boris Brezillon | 13881a4 | 2020-03-05 21:55:01 +0100 | [diff] [blame] | 280 | static void |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 281 | panfrost_draw_emit_vertex(struct panfrost_batch *batch, |
| 282 | const struct pipe_draw_info *info, |
| 283 | void *invocation_template, |
| 284 | mali_ptr shared_mem, mali_ptr vs_vary, |
| 285 | mali_ptr varyings, void *job) |
| 286 | { |
| 287 | struct panfrost_context *ctx = batch->ctx; |
| 288 | struct panfrost_device *device = pan_device(ctx->base.screen); |
| 289 | |
| 290 | void *section = |
| 291 | pan_section_ptr(job, COMPUTE_JOB, INVOCATION); |
| 292 | memcpy(section, invocation_template, MALI_INVOCATION_LENGTH); |
| 293 | |
| 294 | pan_section_pack(job, COMPUTE_JOB, PARAMETERS, cfg) { |
| 295 | cfg.job_task_split = 5; |
| 296 | } |
| 297 | |
| 298 | pan_section_pack(job, COMPUTE_JOB, DRAW, cfg) { |
| 299 | cfg.unknown_1 = (device->quirks & IS_BIFROST) ? 0x2 : 0x6; |
| 300 | cfg.state = panfrost_emit_compute_shader_meta(batch, PIPE_SHADER_VERTEX); |
| 301 | cfg.attributes = panfrost_emit_vertex_data(batch, &cfg.attribute_buffers); |
| 302 | cfg.varyings = vs_vary; |
| 303 | cfg.varying_buffers = varyings; |
| 304 | cfg.shared = shared_mem; |
| 305 | pan_emit_draw_descs(batch, &cfg, PIPE_SHADER_VERTEX); |
| 306 | } |
| 307 | } |
| 308 | |
| 309 | static void |
| 310 | panfrost_emit_primitive_size(struct panfrost_context *ctx, |
| 311 | bool points, mali_ptr size_array, |
| 312 | void *prim_size) |
| 313 | { |
| 314 | struct panfrost_rasterizer *rast = ctx->rasterizer; |
| 315 | |
| 316 | pan_pack(prim_size, PRIMITIVE_SIZE, cfg) { |
| 317 | if (panfrost_writes_point_size(ctx)) { |
| 318 | cfg.size_array = size_array; |
| 319 | } else { |
| 320 | cfg.constant = points ? |
| 321 | rast->base.point_size : |
| 322 | rast->base.line_width; |
| 323 | } |
| 324 | } |
| 325 | } |
| 326 | |
| 327 | static void |
| 328 | panfrost_draw_emit_tiler(struct panfrost_batch *batch, |
| 329 | const struct pipe_draw_info *info, |
| 330 | void *invocation_template, |
| 331 | mali_ptr shared_mem, mali_ptr indices, |
| 332 | mali_ptr fs_vary, mali_ptr varyings, |
| 333 | mali_ptr pos, mali_ptr psiz, void *job) |
| 334 | { |
| 335 | struct panfrost_context *ctx = batch->ctx; |
| 336 | struct pipe_rasterizer_state *rast = &ctx->rasterizer->base; |
| 337 | struct panfrost_device *device = pan_device(ctx->base.screen); |
| 338 | bool is_bifrost = device->quirks & IS_BIFROST; |
| 339 | |
| 340 | void *section = is_bifrost ? |
| 341 | pan_section_ptr(job, BIFROST_TILER_JOB, INVOCATION) : |
| 342 | pan_section_ptr(job, MIDGARD_TILER_JOB, INVOCATION); |
| 343 | memcpy(section, invocation_template, MALI_INVOCATION_LENGTH); |
| 344 | |
| 345 | section = is_bifrost ? |
| 346 | pan_section_ptr(job, BIFROST_TILER_JOB, PRIMITIVE) : |
| 347 | pan_section_ptr(job, MIDGARD_TILER_JOB, PRIMITIVE); |
| 348 | pan_pack(section, PRIMITIVE, cfg) { |
| 349 | cfg.draw_mode = pan_draw_mode(info->mode); |
| 350 | cfg.point_size_array = panfrost_writes_point_size(ctx); |
| 351 | cfg.first_provoking_vertex = rast->flatshade_first; |
| 352 | cfg.primitive_restart = info->primitive_restart; |
| 353 | cfg.unknown_3 = 6; |
| 354 | |
| 355 | if (info->index_size) { |
| 356 | cfg.index_type = panfrost_translate_index_size(info->index_size); |
| 357 | cfg.indices = indices; |
| 358 | cfg.base_vertex_offset = info->index_bias - ctx->offset_start; |
| 359 | cfg.index_count = info->count; |
| 360 | } else { |
| 361 | cfg.index_count = info->count_from_stream_output ? |
| 362 | pan_so_target(info->count_from_stream_output)->offset : |
| 363 | ctx->vertex_count; |
| 364 | } |
| 365 | } |
| 366 | |
| 367 | bool points = info->mode == PIPE_PRIM_POINTS; |
| 368 | void *prim_size = is_bifrost ? |
| 369 | pan_section_ptr(job, BIFROST_TILER_JOB, PRIMITIVE_SIZE) : |
| 370 | pan_section_ptr(job, MIDGARD_TILER_JOB, PRIMITIVE_SIZE); |
| 371 | |
Boris Brezillon | 2e9599b | 2020-09-25 10:27:33 +0200 | [diff] [blame] | 372 | if (is_bifrost) { |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 373 | panfrost_emit_primitive_size(ctx, points, psiz, prim_size); |
Boris Brezillon | 2e9599b | 2020-09-25 10:27:33 +0200 | [diff] [blame] | 374 | pan_section_pack(job, BIFROST_TILER_JOB, TILER, cfg) { |
| 375 | cfg.address = panfrost_batch_get_bifrost_tiler(batch, ~0); |
| 376 | } |
| 377 | pan_section_pack(job, BIFROST_TILER_JOB, PADDING, padding) {} |
| 378 | } |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 379 | |
| 380 | section = is_bifrost ? |
| 381 | pan_section_ptr(job, BIFROST_TILER_JOB, DRAW) : |
| 382 | pan_section_ptr(job, MIDGARD_TILER_JOB, DRAW); |
| 383 | pan_pack(section, DRAW, cfg) { |
| 384 | cfg.unknown_1 = (device->quirks & IS_BIFROST) ? 0x3 : 0x7; |
| 385 | cfg.front_face_ccw = rast->front_ccw; |
| 386 | cfg.cull_front_face = rast->cull_face & PIPE_FACE_FRONT; |
| 387 | cfg.cull_back_face = rast->cull_face & PIPE_FACE_BACK; |
| 388 | cfg.position = pos; |
| 389 | cfg.state = panfrost_emit_frag_shader_meta(batch); |
| 390 | cfg.viewport = panfrost_emit_viewport(batch); |
| 391 | cfg.varyings = fs_vary; |
| 392 | cfg.varying_buffers = varyings; |
| 393 | cfg.shared = shared_mem; |
| 394 | |
| 395 | pan_emit_draw_descs(batch, &cfg, PIPE_SHADER_FRAGMENT); |
| 396 | |
| 397 | if (ctx->occlusion_query) { |
| 398 | cfg.occlusion_query = MALI_OCCLUSION_MODE_PREDICATE; |
| 399 | cfg.occlusion = ctx->occlusion_query->bo->gpu; |
| 400 | panfrost_batch_add_bo(ctx->batch, ctx->occlusion_query->bo, |
| 401 | PAN_BO_ACCESS_SHARED | |
| 402 | PAN_BO_ACCESS_RW | |
| 403 | PAN_BO_ACCESS_FRAGMENT); |
| 404 | } |
| 405 | } |
| 406 | |
| 407 | if (!is_bifrost) |
| 408 | panfrost_emit_primitive_size(ctx, points, psiz, prim_size); |
| 409 | } |
| 410 | |
| 411 | static void |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 412 | panfrost_draw_vbo( |
| 413 | struct pipe_context *pipe, |
| 414 | const struct pipe_draw_info *info) |
| 415 | { |
| 416 | struct panfrost_context *ctx = pan_context(pipe); |
Alyssa Rosenzweig | 3f61da7 | 2020-08-25 13:03:59 -0400 | [diff] [blame] | 417 | struct panfrost_device *device = pan_device(ctx->base.screen); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 418 | |
Alyssa Rosenzweig | 9865b79 | 2019-06-17 09:26:34 -0700 | [diff] [blame] | 419 | /* First of all, check the scissor to see if anything is drawn at all. |
| 420 | * If it's not, we drop the draw (mostly a conformance issue; |
| 421 | * well-behaved apps shouldn't hit this) */ |
| 422 | |
| 423 | if (panfrost_scissor_culls_everything(ctx)) |
| 424 | return; |
| 425 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 426 | int mode = info->mode; |
| 427 | |
Alyssa Rosenzweig | 7f54812 | 2019-06-26 15:59:29 -0700 | [diff] [blame] | 428 | /* Fallback unsupported restart index */ |
| 429 | unsigned primitive_index = (1 << (info->index_size * 8)) - 1; |
| 430 | |
| 431 | if (info->primitive_restart && info->index_size |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 432 | && info->restart_index != primitive_index) { |
Alyssa Rosenzweig | 7f54812 | 2019-06-26 15:59:29 -0700 | [diff] [blame] | 433 | util_draw_vbo_without_prim_restart(pipe, info); |
| 434 | return; |
| 435 | } |
| 436 | |
Alyssa Rosenzweig | 85e2bb5 | 2019-02-08 02:28:12 +0000 | [diff] [blame] | 437 | /* Fallback for unsupported modes */ |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 438 | |
Alyssa Rosenzweig | 27b6264 | 2019-08-21 09:40:11 -0700 | [diff] [blame] | 439 | assert(ctx->rasterizer != NULL); |
| 440 | |
Alyssa Rosenzweig | 7c02c4f | 2019-03-15 02:13:34 +0000 | [diff] [blame] | 441 | if (!(ctx->draw_modes & (1 << mode))) { |
Alyssa Rosenzweig | 433fa39 | 2020-08-14 18:27:32 -0400 | [diff] [blame] | 442 | if (info->count < 4) { |
| 443 | /* Degenerate case? */ |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 444 | return; |
| 445 | } |
Alyssa Rosenzweig | 433fa39 | 2020-08-14 18:27:32 -0400 | [diff] [blame] | 446 | |
| 447 | util_primconvert_save_rasterizer_state(ctx->primconvert, &ctx->rasterizer->base); |
| 448 | util_primconvert_draw_vbo(ctx->primconvert, info); |
| 449 | return; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 450 | } |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 451 | |
Alyssa Rosenzweig | a2e4159 | 2020-08-14 18:31:05 -0400 | [diff] [blame] | 452 | /* Now that we have a guaranteed terminating path, find the job. */ |
Alyssa Rosenzweig | 59c9623 | 2019-02-25 05:32:16 +0000 | [diff] [blame] | 453 | |
Boris Brezillon | 251e685 | 2020-03-06 08:57:31 +0100 | [diff] [blame] | 454 | struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx); |
Boris Brezillon | 251e685 | 2020-03-06 08:57:31 +0100 | [diff] [blame] | 455 | panfrost_batch_set_requirements(batch); |
Alyssa Rosenzweig | 59c9623 | 2019-02-25 05:32:16 +0000 | [diff] [blame] | 456 | |
Rohan Garg | 16edd56 | 2019-07-17 18:50:13 +0200 | [diff] [blame] | 457 | /* Take into account a negative bias */ |
| 458 | ctx->vertex_count = info->count + abs(info->index_bias); |
Alyssa Rosenzweig | 8d74749 | 2019-06-27 14:13:10 -0700 | [diff] [blame] | 459 | ctx->instance_count = info->instance_count; |
Alyssa Rosenzweig | 7c29588 | 2019-08-08 08:16:09 -0700 | [diff] [blame] | 460 | ctx->active_prim = info->mode; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 461 | |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 462 | bool is_bifrost = device->quirks & IS_BIFROST; |
Boris Brezillon | 6b92303 | 2020-09-08 20:32:41 +0200 | [diff] [blame] | 463 | struct panfrost_transfer tiler = |
| 464 | panfrost_pool_alloc_aligned(&batch->pool, |
| 465 | is_bifrost ? |
| 466 | MALI_BIFROST_TILER_JOB_LENGTH : |
| 467 | MALI_MIDGARD_TILER_JOB_LENGTH, |
| 468 | 64); |
| 469 | struct panfrost_transfer vertex = |
| 470 | panfrost_pool_alloc_aligned(&batch->pool, |
| 471 | MALI_COMPUTE_JOB_LENGTH, |
| 472 | 64); |
| 473 | |
| 474 | unsigned vertex_count = ctx->vertex_count; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 475 | |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 476 | mali_ptr shared_mem = is_bifrost ? |
Alyssa Rosenzweig | 90cc815 | 2020-08-25 14:59:30 -0400 | [diff] [blame] | 477 | panfrost_vt_emit_shared_memory(batch) : |
| 478 | panfrost_batch_reserve_framebuffer(batch); |
Alyssa Rosenzweig | 3f61da7 | 2020-08-25 13:03:59 -0400 | [diff] [blame] | 479 | |
Alyssa Rosenzweig | b60d567 | 2020-08-25 16:59:14 -0400 | [diff] [blame] | 480 | unsigned min_index = 0, max_index = 0; |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 481 | mali_ptr indices = 0; |
Boris Brezillon | d66ef69 | 2020-03-06 11:31:06 +0100 | [diff] [blame] | 482 | |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 483 | if (info->index_size) { |
| 484 | indices = panfrost_get_index_buffer_bounded(ctx, info, |
| 485 | &min_index, |
| 486 | &max_index); |
Alyssa Rosenzweig | 3a4d930 | 2020-08-25 13:25:29 -0400 | [diff] [blame] | 487 | |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 488 | /* Use the corresponding values */ |
| 489 | vertex_count = max_index - min_index + 1; |
| 490 | ctx->offset_start = min_index + info->index_bias; |
| 491 | } else { |
| 492 | ctx->offset_start = info->start; |
Alyssa Rosenzweig | 3a4d930 | 2020-08-25 13:25:29 -0400 | [diff] [blame] | 493 | } |
| 494 | |
Alyssa Rosenzweig | 3a4d930 | 2020-08-25 13:25:29 -0400 | [diff] [blame] | 495 | /* Encode the padded vertex count */ |
| 496 | |
Alyssa Rosenzweig | 90cc815 | 2020-08-25 14:59:30 -0400 | [diff] [blame] | 497 | if (info->instance_count > 1) |
Alyssa Rosenzweig | 3a4d930 | 2020-08-25 13:25:29 -0400 | [diff] [blame] | 498 | ctx->padded_count = panfrost_padded_vertex_count(vertex_count); |
Alyssa Rosenzweig | 90cc815 | 2020-08-25 14:59:30 -0400 | [diff] [blame] | 499 | else |
Alyssa Rosenzweig | 3a4d930 | 2020-08-25 13:25:29 -0400 | [diff] [blame] | 500 | ctx->padded_count = vertex_count; |
Alyssa Rosenzweig | 0e4c321 | 2019-03-31 04:26:48 +0000 | [diff] [blame] | 501 | |
Alyssa Rosenzweig | 72fc06d | 2019-08-08 07:10:24 -0700 | [diff] [blame] | 502 | panfrost_statistics_record(ctx, info); |
| 503 | |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 504 | struct mali_invocation_packed invocation; |
Alyssa Rosenzweig | 02e768e | 2020-08-26 13:04:17 -0400 | [diff] [blame] | 505 | panfrost_pack_work_groups_compute(&invocation, |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 506 | 1, vertex_count, info->instance_count, |
| 507 | 1, 1, 1, true); |
Alyssa Rosenzweig | c9b164f | 2019-06-27 08:29:06 -0700 | [diff] [blame] | 508 | |
Boris Brezillon | 251e685 | 2020-03-06 08:57:31 +0100 | [diff] [blame] | 509 | /* Emit all sort of descriptors. */ |
Alyssa Rosenzweig | e5c77cb | 2020-08-25 13:37:22 -0400 | [diff] [blame] | 510 | mali_ptr varyings = 0, vs_vary = 0, fs_vary = 0, pos = 0, psiz = 0; |
Alyssa Rosenzweig | 8b5f9fc | 2020-08-25 12:03:17 -0400 | [diff] [blame] | 511 | |
Boris Brezillon | 836686d | 2020-03-06 09:45:31 +0100 | [diff] [blame] | 512 | panfrost_emit_varying_descriptor(batch, |
Boris Brezillon | 251e685 | 2020-03-06 08:57:31 +0100 | [diff] [blame] | 513 | ctx->padded_count * |
Boris Brezillon | 836686d | 2020-03-06 09:45:31 +0100 | [diff] [blame] | 514 | ctx->instance_count, |
Alyssa Rosenzweig | e5c77cb | 2020-08-25 13:37:22 -0400 | [diff] [blame] | 515 | &vs_vary, &fs_vary, &varyings, |
| 516 | &pos, &psiz); |
Tomeu Vizoso | 7b10d4e | 2020-04-08 10:55:28 +0200 | [diff] [blame] | 517 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 518 | /* Fire off the draw itself */ |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 519 | panfrost_draw_emit_vertex(batch, info, &invocation, shared_mem, |
Boris Brezillon | 6b92303 | 2020-09-08 20:32:41 +0200 | [diff] [blame] | 520 | vs_vary, varyings, vertex.cpu); |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 521 | panfrost_draw_emit_tiler(batch, info, &invocation, shared_mem, indices, |
Boris Brezillon | 6b92303 | 2020-09-08 20:32:41 +0200 | [diff] [blame] | 522 | fs_vary, varyings, pos, psiz, tiler.cpu); |
Boris Brezillon | d289209 | 2020-09-08 19:41:51 +0200 | [diff] [blame] | 523 | panfrost_emit_vertex_tiler_jobs(batch, &vertex, &tiler); |
Boris Brezillon | 251e685 | 2020-03-06 08:57:31 +0100 | [diff] [blame] | 524 | |
| 525 | /* Adjust the batch stack size based on the new shader stack sizes. */ |
| 526 | panfrost_batch_adjust_stack_size(batch); |
Alyssa Rosenzweig | 7c29588 | 2019-08-08 08:16:09 -0700 | [diff] [blame] | 527 | |
| 528 | /* Increment transform feedback offsets */ |
Boris Brezillon | 13881a4 | 2020-03-05 21:55:01 +0100 | [diff] [blame] | 529 | panfrost_update_streamout_offsets(ctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 530 | } |
| 531 | |
| 532 | /* CSO state */ |
| 533 | |
| 534 | static void |
| 535 | panfrost_generic_cso_delete(struct pipe_context *pctx, void *hwcso) |
| 536 | { |
| 537 | free(hwcso); |
| 538 | } |
| 539 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 540 | static void * |
| 541 | panfrost_create_rasterizer_state( |
| 542 | struct pipe_context *pctx, |
| 543 | const struct pipe_rasterizer_state *cso) |
| 544 | { |
| 545 | struct panfrost_rasterizer *so = CALLOC_STRUCT(panfrost_rasterizer); |
| 546 | |
| 547 | so->base = *cso; |
| 548 | |
Alyssa Rosenzweig | 1cf7a39 | 2020-08-14 18:34:56 -0400 | [diff] [blame] | 549 | /* Gauranteed with the core GL call, so don't expose ARB_polygon_offset */ |
| 550 | assert(cso->offset_clamp == 0.0); |
| 551 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 552 | return so; |
| 553 | } |
| 554 | |
| 555 | static void |
| 556 | panfrost_bind_rasterizer_state( |
| 557 | struct pipe_context *pctx, |
| 558 | void *hwcso) |
| 559 | { |
| 560 | struct panfrost_context *ctx = pan_context(pctx); |
Alyssa Rosenzweig | d3160a6 | 2020-02-18 10:08:51 -0500 | [diff] [blame] | 561 | ctx->rasterizer = hwcso; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 562 | } |
| 563 | |
| 564 | static void * |
| 565 | panfrost_create_vertex_elements_state( |
| 566 | struct pipe_context *pctx, |
| 567 | unsigned num_elements, |
| 568 | const struct pipe_vertex_element *elements) |
| 569 | { |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 570 | struct panfrost_vertex_state *so = CALLOC_STRUCT(panfrost_vertex_state); |
Tomeu Vizoso | c4400b0 | 2020-05-01 07:36:31 +0200 | [diff] [blame] | 571 | struct panfrost_device *dev = pan_device(pctx->screen); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 572 | |
| 573 | so->num_elements = num_elements; |
| 574 | memcpy(so->pipe, elements, sizeof(*elements) * num_elements); |
| 575 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 576 | for (int i = 0; i < num_elements; ++i) { |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 577 | enum pipe_format fmt = elements[i].src_format; |
| 578 | const struct util_format_description *desc = util_format_description(fmt); |
Alyssa Rosenzweig | 668ec24 | 2020-08-11 22:26:03 -0400 | [diff] [blame] | 579 | unsigned swizzle = 0; |
Tomeu Vizoso | c4400b0 | 2020-05-01 07:36:31 +0200 | [diff] [blame] | 580 | if (dev->quirks & HAS_SWIZZLES) |
Alyssa Rosenzweig | 668ec24 | 2020-08-11 22:26:03 -0400 | [diff] [blame] | 581 | swizzle = panfrost_translate_swizzle_4(desc->swizzle); |
Tomeu Vizoso | c4400b0 | 2020-05-01 07:36:31 +0200 | [diff] [blame] | 582 | else |
Alyssa Rosenzweig | 668ec24 | 2020-08-11 22:26:03 -0400 | [diff] [blame] | 583 | swizzle = panfrost_bifrost_swizzle(desc->nr_channels); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 584 | |
Alyssa Rosenzweig | 861e7dc | 2020-05-15 18:43:41 -0400 | [diff] [blame] | 585 | enum mali_format hw_format = panfrost_pipe_format_table[desc->format].hw; |
Alyssa Rosenzweig | 6caf789 | 2020-08-14 12:14:20 -0400 | [diff] [blame] | 586 | so->formats[i] = (hw_format << 12) | swizzle; |
Alyssa Rosenzweig | 861e7dc | 2020-05-15 18:43:41 -0400 | [diff] [blame] | 587 | assert(hw_format); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 588 | } |
| 589 | |
Boris Brezillon | 4a2ee61 | 2020-03-05 19:40:15 +0100 | [diff] [blame] | 590 | /* Let's also prepare vertex builtins */ |
Tomeu Vizoso | c4400b0 | 2020-05-01 07:36:31 +0200 | [diff] [blame] | 591 | if (dev->quirks & HAS_SWIZZLES) |
Alyssa Rosenzweig | 6caf789 | 2020-08-14 12:14:20 -0400 | [diff] [blame] | 592 | so->formats[PAN_VERTEX_ID] = (MALI_R32UI << 12) | panfrost_get_default_swizzle(1); |
Tomeu Vizoso | c4400b0 | 2020-05-01 07:36:31 +0200 | [diff] [blame] | 593 | else |
Alyssa Rosenzweig | 6caf789 | 2020-08-14 12:14:20 -0400 | [diff] [blame] | 594 | so->formats[PAN_VERTEX_ID] = (MALI_R32UI << 12) | panfrost_bifrost_swizzle(1); |
Tomeu Vizoso | c4400b0 | 2020-05-01 07:36:31 +0200 | [diff] [blame] | 595 | |
Tomeu Vizoso | c4400b0 | 2020-05-01 07:36:31 +0200 | [diff] [blame] | 596 | if (dev->quirks & HAS_SWIZZLES) |
Alyssa Rosenzweig | 6caf789 | 2020-08-14 12:14:20 -0400 | [diff] [blame] | 597 | so->formats[PAN_INSTANCE_ID] = (MALI_R32UI << 12) | panfrost_get_default_swizzle(1); |
Tomeu Vizoso | c4400b0 | 2020-05-01 07:36:31 +0200 | [diff] [blame] | 598 | else |
Alyssa Rosenzweig | 6caf789 | 2020-08-14 12:14:20 -0400 | [diff] [blame] | 599 | so->formats[PAN_INSTANCE_ID] = (MALI_R32UI << 12) | panfrost_bifrost_swizzle(1); |
Boris Brezillon | 4a2ee61 | 2020-03-05 19:40:15 +0100 | [diff] [blame] | 600 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 601 | return so; |
| 602 | } |
| 603 | |
| 604 | static void |
| 605 | panfrost_bind_vertex_elements_state( |
| 606 | struct pipe_context *pctx, |
| 607 | void *hwcso) |
| 608 | { |
| 609 | struct panfrost_context *ctx = pan_context(pctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 610 | ctx->vertex = hwcso; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 611 | } |
| 612 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 613 | static void * |
| 614 | panfrost_create_shader_state( |
| 615 | struct pipe_context *pctx, |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 616 | const struct pipe_shader_state *cso, |
| 617 | enum pipe_shader_type stage) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 618 | { |
| 619 | struct panfrost_shader_variants *so = CALLOC_STRUCT(panfrost_shader_variants); |
Alyssa Rosenzweig | ed1910d | 2020-07-07 16:15:45 -0400 | [diff] [blame] | 620 | struct panfrost_device *dev = pan_device(pctx->screen); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 621 | so->base = *cso; |
| 622 | |
| 623 | /* Token deep copy to prevent memory corruption */ |
| 624 | |
| 625 | if (cso->type == PIPE_SHADER_IR_TGSI) |
| 626 | so->base.tokens = tgsi_dup_tokens(so->base.tokens); |
| 627 | |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 628 | /* Precompile for shader-db if we need to */ |
Alyssa Rosenzweig | ed1910d | 2020-07-07 16:15:45 -0400 | [diff] [blame] | 629 | if (unlikely((dev->debug & PAN_DBG_PRECOMPILE) && cso->type == PIPE_SHADER_IR_NIR)) { |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 630 | struct panfrost_context *ctx = pan_context(pctx); |
| 631 | |
Alyssa Rosenzweig | da677a4 | 2020-08-24 16:51:12 -0400 | [diff] [blame] | 632 | struct panfrost_shader_state state = { 0 }; |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 633 | uint64_t outputs_written; |
| 634 | |
Boris Brezillon | b02f97c | 2020-03-05 16:20:18 +0100 | [diff] [blame] | 635 | panfrost_shader_compile(ctx, PIPE_SHADER_IR_NIR, |
| 636 | so->base.ir.nir, |
| 637 | tgsi_processor_to_shader_stage(stage), |
| 638 | &state, &outputs_written); |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 639 | } |
| 640 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 641 | return so; |
| 642 | } |
| 643 | |
| 644 | static void |
| 645 | panfrost_delete_shader_state( |
| 646 | struct pipe_context *pctx, |
| 647 | void *so) |
| 648 | { |
Alyssa Rosenzweig | acc52ff | 2019-02-14 04:00:19 +0000 | [diff] [blame] | 649 | struct panfrost_shader_variants *cso = (struct panfrost_shader_variants *) so; |
| 650 | |
| 651 | if (cso->base.type == PIPE_SHADER_IR_TGSI) { |
Alyssa Rosenzweig | ed1910d | 2020-07-07 16:15:45 -0400 | [diff] [blame] | 652 | /* TODO: leaks TGSI tokens! */ |
Alyssa Rosenzweig | acc52ff | 2019-02-14 04:00:19 +0000 | [diff] [blame] | 653 | } |
| 654 | |
Tomeu Vizoso | 950b5fc5 | 2019-08-01 16:45:50 +0200 | [diff] [blame] | 655 | for (unsigned i = 0; i < cso->variant_count; ++i) { |
| 656 | struct panfrost_shader_state *shader_state = &cso->variants[i]; |
Boris Brezillon | e15ab93 | 2019-09-14 10:35:47 +0200 | [diff] [blame] | 657 | panfrost_bo_unreference(shader_state->bo); |
Alyssa Rosenzweig | 1e4c49e | 2020-08-21 14:16:18 -0400 | [diff] [blame] | 658 | |
| 659 | if (shader_state->upload.rsrc) |
| 660 | pipe_resource_reference(&shader_state->upload.rsrc, NULL); |
| 661 | |
Tomeu Vizoso | 950b5fc5 | 2019-08-01 16:45:50 +0200 | [diff] [blame] | 662 | shader_state->bo = NULL; |
| 663 | } |
Icecream95 | d8a3501 | 2020-01-12 14:19:25 +1300 | [diff] [blame] | 664 | free(cso->variants); |
Tomeu Vizoso | 950b5fc5 | 2019-08-01 16:45:50 +0200 | [diff] [blame] | 665 | |
Alyssa Rosenzweig | 1e4c49e | 2020-08-21 14:16:18 -0400 | [diff] [blame] | 666 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 667 | free(so); |
| 668 | } |
| 669 | |
| 670 | static void * |
| 671 | panfrost_create_sampler_state( |
| 672 | struct pipe_context *pctx, |
| 673 | const struct pipe_sampler_state *cso) |
| 674 | { |
| 675 | struct panfrost_sampler_state *so = CALLOC_STRUCT(panfrost_sampler_state); |
Tomeu Vizoso | d3eb23a | 2020-04-17 14:23:39 +0200 | [diff] [blame] | 676 | struct panfrost_device *device = pan_device(pctx->screen); |
| 677 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 678 | so->base = *cso; |
| 679 | |
Tomeu Vizoso | d3eb23a | 2020-04-17 14:23:39 +0200 | [diff] [blame] | 680 | if (device->quirks & IS_BIFROST) |
Alyssa Rosenzweig | b10c3c8 | 2020-08-11 18:25:03 -0400 | [diff] [blame] | 681 | panfrost_sampler_desc_init_bifrost(cso, (struct mali_bifrost_sampler_packed *) &so->hw); |
Tomeu Vizoso | d3eb23a | 2020-04-17 14:23:39 +0200 | [diff] [blame] | 682 | else |
Alyssa Rosenzweig | f74186b | 2020-08-11 18:23:12 -0400 | [diff] [blame] | 683 | panfrost_sampler_desc_init(cso, &so->hw); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 684 | |
| 685 | return so; |
| 686 | } |
| 687 | |
| 688 | static void |
| 689 | panfrost_bind_sampler_states( |
| 690 | struct pipe_context *pctx, |
| 691 | enum pipe_shader_type shader, |
| 692 | unsigned start_slot, unsigned num_sampler, |
| 693 | void **sampler) |
| 694 | { |
| 695 | assert(start_slot == 0); |
| 696 | |
| 697 | struct panfrost_context *ctx = pan_context(pctx); |
| 698 | |
| 699 | /* XXX: Should upload, not just copy? */ |
| 700 | ctx->sampler_count[shader] = num_sampler; |
| 701 | memcpy(ctx->samplers[shader], sampler, num_sampler * sizeof (void *)); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 702 | } |
| 703 | |
| 704 | static bool |
Alyssa Rosenzweig | 9ab8d31 | 2019-06-14 10:12:38 -0700 | [diff] [blame] | 705 | panfrost_variant_matches( |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 706 | struct panfrost_context *ctx, |
| 707 | struct panfrost_shader_state *variant, |
| 708 | enum pipe_shader_type type) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 709 | { |
Alyssa Rosenzweig | b73b339 | 2020-06-01 20:52:59 -0400 | [diff] [blame] | 710 | struct panfrost_device *dev = pan_device(ctx->base.screen); |
Alyssa Rosenzweig | 9ab8d31 | 2019-06-14 10:12:38 -0700 | [diff] [blame] | 711 | |
Icecream95 | e603248 | 2020-07-06 19:41:28 +1200 | [diff] [blame] | 712 | if (variant->outputs_read) { |
| 713 | struct pipe_framebuffer_state *fb = &ctx->pipe_framebuffer; |
| 714 | |
| 715 | unsigned i; |
| 716 | BITSET_FOREACH_SET(i, &variant->outputs_read, 8) { |
| 717 | enum pipe_format fmt = PIPE_FORMAT_R8G8B8A8_UNORM; |
| 718 | |
| 719 | if ((fb->nr_cbufs > i) && fb->cbufs[i]) |
| 720 | fmt = fb->cbufs[i]->format; |
| 721 | |
Icecream95 | d16d136 | 2020-07-07 15:06:08 +1200 | [diff] [blame] | 722 | const struct util_format_description *desc = |
| 723 | util_format_description(fmt); |
| 724 | |
| 725 | if (pan_format_class_load(desc, dev->quirks) == PAN_FORMAT_NATIVE) |
| 726 | fmt = PIPE_FORMAT_NONE; |
| 727 | |
Icecream95 | e603248 | 2020-07-06 19:41:28 +1200 | [diff] [blame] | 728 | if (variant->rt_formats[i] != fmt) |
| 729 | return false; |
| 730 | } |
| 731 | } |
| 732 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 733 | /* Otherwise, we're good to go */ |
| 734 | return true; |
| 735 | } |
| 736 | |
Alyssa Rosenzweig | f714eab | 2019-08-07 10:11:28 -0700 | [diff] [blame] | 737 | /** |
| 738 | * Fix an uncompiled shader's stream output info, and produce a bitmask |
| 739 | * of which VARYING_SLOT_* are captured for stream output. |
| 740 | * |
| 741 | * Core Gallium stores output->register_index as a "slot" number, where |
| 742 | * slots are assigned consecutively to all outputs in info->outputs_written. |
| 743 | * This naive packing of outputs doesn't work for us - we too have slots, |
| 744 | * but the layout is defined by the VUE map, which we won't have until we |
| 745 | * compile a specific shader variant. So, we remap these and simply store |
| 746 | * VARYING_SLOT_* in our copy's output->register_index fields. |
| 747 | * |
| 748 | * We then produce a bitmask of outputs which are used for SO. |
| 749 | * |
| 750 | * Implementation from iris. |
| 751 | */ |
| 752 | |
| 753 | static uint64_t |
| 754 | update_so_info(struct pipe_stream_output_info *so_info, |
| 755 | uint64_t outputs_written) |
| 756 | { |
| 757 | uint64_t so_outputs = 0; |
Vinson Lee | de2e5f6 | 2019-11-27 23:37:00 -0800 | [diff] [blame] | 758 | uint8_t reverse_map[64] = {0}; |
Alyssa Rosenzweig | f714eab | 2019-08-07 10:11:28 -0700 | [diff] [blame] | 759 | unsigned slot = 0; |
| 760 | |
| 761 | while (outputs_written) |
| 762 | reverse_map[slot++] = u_bit_scan64(&outputs_written); |
| 763 | |
| 764 | for (unsigned i = 0; i < so_info->num_outputs; i++) { |
| 765 | struct pipe_stream_output *output = &so_info->output[i]; |
| 766 | |
| 767 | /* Map Gallium's condensed "slots" back to real VARYING_SLOT_* enums */ |
| 768 | output->register_index = reverse_map[output->register_index]; |
| 769 | |
| 770 | so_outputs |= 1ull << output->register_index; |
| 771 | } |
| 772 | |
| 773 | return so_outputs; |
| 774 | } |
| 775 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 776 | static void |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 777 | panfrost_bind_shader_state( |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 778 | struct pipe_context *pctx, |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 779 | void *hwcso, |
| 780 | enum pipe_shader_type type) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 781 | { |
| 782 | struct panfrost_context *ctx = pan_context(pctx); |
Alyssa Rosenzweig | b73b339 | 2020-06-01 20:52:59 -0400 | [diff] [blame] | 783 | struct panfrost_device *dev = pan_device(ctx->base.screen); |
Alyssa Rosenzweig | 3113be3 | 2019-07-31 14:15:19 -0700 | [diff] [blame] | 784 | ctx->shader[type] = hwcso; |
| 785 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 786 | if (!hwcso) return; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 787 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 788 | /* Match the appropriate variant */ |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 789 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 790 | signed variant = -1; |
| 791 | struct panfrost_shader_variants *variants = (struct panfrost_shader_variants *) hwcso; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 792 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 793 | for (unsigned i = 0; i < variants->variant_count; ++i) { |
Alyssa Rosenzweig | 9ab8d31 | 2019-06-14 10:12:38 -0700 | [diff] [blame] | 794 | if (panfrost_variant_matches(ctx, &variants->variants[i], type)) { |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 795 | variant = i; |
| 796 | break; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 797 | } |
| 798 | } |
| 799 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 800 | if (variant == -1) { |
| 801 | /* No variant matched, so create a new one */ |
| 802 | variant = variants->variant_count++; |
Icecream95 | d8a3501 | 2020-01-12 14:19:25 +1300 | [diff] [blame] | 803 | |
| 804 | if (variants->variant_count > variants->variant_space) { |
| 805 | unsigned old_space = variants->variant_space; |
| 806 | |
| 807 | variants->variant_space *= 2; |
| 808 | if (variants->variant_space == 0) |
| 809 | variants->variant_space = 1; |
| 810 | |
| 811 | /* Arbitrary limit to stop runaway programs from |
| 812 | * creating an unbounded number of shader variants. */ |
| 813 | assert(variants->variant_space < 1024); |
| 814 | |
| 815 | unsigned msize = sizeof(struct panfrost_shader_state); |
| 816 | variants->variants = realloc(variants->variants, |
| 817 | variants->variant_space * msize); |
| 818 | |
| 819 | memset(&variants->variants[old_space], 0, |
| 820 | (variants->variant_space - old_space) * msize); |
| 821 | } |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 822 | |
Alyssa Rosenzweig | be03060 | 2019-06-24 11:01:05 -0700 | [diff] [blame] | 823 | struct panfrost_shader_state *v = |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 824 | &variants->variants[variant]; |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 825 | |
Alyssa Rosenzweig | be03060 | 2019-06-24 11:01:05 -0700 | [diff] [blame] | 826 | if (type == PIPE_SHADER_FRAGMENT) { |
Icecream95 | 75018f6 | 2020-07-06 19:40:05 +1200 | [diff] [blame] | 827 | struct pipe_framebuffer_state *fb = &ctx->pipe_framebuffer; |
| 828 | for (unsigned i = 0; i < fb->nr_cbufs; ++i) { |
| 829 | enum pipe_format fmt = PIPE_FORMAT_R8G8B8A8_UNORM; |
| 830 | |
| 831 | if ((fb->nr_cbufs > i) && fb->cbufs[i]) |
| 832 | fmt = fb->cbufs[i]->format; |
| 833 | |
Icecream95 | d16d136 | 2020-07-07 15:06:08 +1200 | [diff] [blame] | 834 | const struct util_format_description *desc = |
| 835 | util_format_description(fmt); |
| 836 | |
| 837 | if (pan_format_class_load(desc, dev->quirks) == PAN_FORMAT_NATIVE) |
| 838 | fmt = PIPE_FORMAT_NONE; |
| 839 | |
Icecream95 | 75018f6 | 2020-07-06 19:40:05 +1200 | [diff] [blame] | 840 | v->rt_formats[i] = fmt; |
| 841 | } |
Alyssa Rosenzweig | be03060 | 2019-06-24 11:01:05 -0700 | [diff] [blame] | 842 | } |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 843 | } |
| 844 | |
| 845 | /* Select this variant */ |
| 846 | variants->active_variant = variant; |
| 847 | |
| 848 | struct panfrost_shader_state *shader_state = &variants->variants[variant]; |
Alyssa Rosenzweig | 9ab8d31 | 2019-06-14 10:12:38 -0700 | [diff] [blame] | 849 | assert(panfrost_variant_matches(ctx, shader_state, type)); |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 850 | |
| 851 | /* We finally have a variant, so compile it */ |
| 852 | |
| 853 | if (!shader_state->compiled) { |
Alyssa Rosenzweig | 5b0a1a4 | 2019-08-07 10:26:12 -0700 | [diff] [blame] | 854 | uint64_t outputs_written = 0; |
| 855 | |
Boris Brezillon | b02f97c | 2020-03-05 16:20:18 +0100 | [diff] [blame] | 856 | panfrost_shader_compile(ctx, variants->base.type, |
| 857 | variants->base.type == PIPE_SHADER_IR_NIR ? |
| 858 | variants->base.ir.nir : |
| 859 | variants->base.tokens, |
| 860 | tgsi_processor_to_shader_stage(type), |
| 861 | shader_state, |
Alyssa Rosenzweig | 5b0a1a4 | 2019-08-07 10:26:12 -0700 | [diff] [blame] | 862 | &outputs_written); |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 863 | |
| 864 | shader_state->compiled = true; |
Alyssa Rosenzweig | e7a05a6 | 2019-08-07 10:33:15 -0700 | [diff] [blame] | 865 | |
| 866 | /* Fixup the stream out information, since what Gallium returns |
| 867 | * normally is mildly insane */ |
| 868 | |
| 869 | shader_state->stream_output = variants->base.stream_output; |
| 870 | shader_state->so_mask = |
| 871 | update_so_info(&shader_state->stream_output, outputs_written); |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 872 | } |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 873 | } |
| 874 | |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 875 | static void * |
| 876 | panfrost_create_vs_state(struct pipe_context *pctx, const struct pipe_shader_state *hwcso) |
| 877 | { |
| 878 | return panfrost_create_shader_state(pctx, hwcso, PIPE_SHADER_VERTEX); |
| 879 | } |
| 880 | |
| 881 | static void * |
| 882 | panfrost_create_fs_state(struct pipe_context *pctx, const struct pipe_shader_state *hwcso) |
| 883 | { |
| 884 | return panfrost_create_shader_state(pctx, hwcso, PIPE_SHADER_FRAGMENT); |
| 885 | } |
| 886 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 887 | static void |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 888 | panfrost_bind_vs_state(struct pipe_context *pctx, void *hwcso) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 889 | { |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 890 | panfrost_bind_shader_state(pctx, hwcso, PIPE_SHADER_VERTEX); |
| 891 | } |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 892 | |
Alyssa Rosenzweig | 1acffb5 | 2019-06-04 23:48:17 +0000 | [diff] [blame] | 893 | static void |
| 894 | panfrost_bind_fs_state(struct pipe_context *pctx, void *hwcso) |
| 895 | { |
| 896 | panfrost_bind_shader_state(pctx, hwcso, PIPE_SHADER_FRAGMENT); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 897 | } |
| 898 | |
| 899 | static void |
| 900 | panfrost_set_vertex_buffers( |
| 901 | struct pipe_context *pctx, |
| 902 | unsigned start_slot, |
| 903 | unsigned num_buffers, |
| 904 | const struct pipe_vertex_buffer *buffers) |
| 905 | { |
| 906 | struct panfrost_context *ctx = pan_context(pctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 907 | |
Alyssa Rosenzweig | e008d4f | 2019-04-14 22:42:44 +0000 | [diff] [blame] | 908 | 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] | 909 | } |
| 910 | |
| 911 | static void |
| 912 | panfrost_set_constant_buffer( |
| 913 | struct pipe_context *pctx, |
| 914 | enum pipe_shader_type shader, uint index, |
| 915 | const struct pipe_constant_buffer *buf) |
| 916 | { |
| 917 | struct panfrost_context *ctx = pan_context(pctx); |
| 918 | struct panfrost_constant_buffer *pbuf = &ctx->constant_buffer[shader]; |
| 919 | |
Alyssa Rosenzweig | ca2caf0 | 2019-06-20 16:07:57 -0700 | [diff] [blame] | 920 | util_copy_constant_buffer(&pbuf->cb[index], buf); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 921 | |
Alyssa Rosenzweig | ca2caf0 | 2019-06-20 16:07:57 -0700 | [diff] [blame] | 922 | unsigned mask = (1 << index); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 923 | |
Alyssa Rosenzweig | ca2caf0 | 2019-06-20 16:07:57 -0700 | [diff] [blame] | 924 | if (unlikely(!buf)) { |
| 925 | pbuf->enabled_mask &= ~mask; |
| 926 | pbuf->dirty_mask &= ~mask; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 927 | return; |
| 928 | } |
| 929 | |
Alyssa Rosenzweig | ca2caf0 | 2019-06-20 16:07:57 -0700 | [diff] [blame] | 930 | pbuf->enabled_mask |= mask; |
| 931 | pbuf->dirty_mask |= mask; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 932 | } |
| 933 | |
| 934 | static void |
| 935 | panfrost_set_stencil_ref( |
| 936 | struct pipe_context *pctx, |
| 937 | const struct pipe_stencil_ref *ref) |
| 938 | { |
| 939 | struct panfrost_context *ctx = pan_context(pctx); |
| 940 | ctx->stencil_ref = *ref; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 941 | } |
| 942 | |
Icecream95 | 3baf10a | 2020-04-30 15:21:17 +1200 | [diff] [blame] | 943 | void |
| 944 | panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so, |
| 945 | struct pipe_context *pctx, |
| 946 | struct pipe_resource *texture) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 947 | { |
Alyssa Rosenzweig | ca8c625 | 2020-03-23 18:44:21 -0400 | [diff] [blame] | 948 | struct panfrost_device *device = pan_device(pctx->screen); |
Icecream95 | 3baf10a | 2020-04-30 15:21:17 +1200 | [diff] [blame] | 949 | struct panfrost_resource *prsrc = (struct panfrost_resource *)texture; |
Alyssa Rosenzweig | cce3d92 | 2020-07-09 16:34:00 -0400 | [diff] [blame] | 950 | enum pipe_format format = so->base.format; |
Alyssa Rosenzweig | 81b1053 | 2019-05-14 23:18:18 +0000 | [diff] [blame] | 951 | assert(prsrc->bo); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 952 | |
Alyssa Rosenzweig | cce3d92 | 2020-07-09 16:34:00 -0400 | [diff] [blame] | 953 | /* Format to access the stencil portion of a Z32_S8 texture */ |
Icecream95 | c1d3d39 | 2020-07-13 22:45:51 +1200 | [diff] [blame] | 954 | if (format == PIPE_FORMAT_X32_S8X24_UINT) { |
Alyssa Rosenzweig | cce3d92 | 2020-07-09 16:34:00 -0400 | [diff] [blame] | 955 | assert(prsrc->separate_stencil); |
| 956 | texture = &prsrc->separate_stencil->base; |
| 957 | prsrc = (struct panfrost_resource *)texture; |
| 958 | format = texture->format; |
| 959 | } |
| 960 | |
Icecream95 | c1d3d39 | 2020-07-13 22:45:51 +1200 | [diff] [blame] | 961 | const struct util_format_description *desc = util_format_description(format); |
| 962 | |
| 963 | bool fake_rgtc = !panfrost_supports_compressed_format(device, MALI_BC4_UNORM); |
| 964 | |
| 965 | if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC && fake_rgtc) { |
| 966 | if (desc->is_snorm) |
| 967 | format = PIPE_FORMAT_R8G8B8A8_SNORM; |
| 968 | else |
| 969 | format = PIPE_FORMAT_R8G8B8A8_UNORM; |
| 970 | desc = util_format_description(format); |
| 971 | } |
| 972 | |
Icecream95 | 65b3b08 | 2020-06-20 19:09:03 +1200 | [diff] [blame] | 973 | so->texture_bo = prsrc->bo->gpu; |
Alyssa Rosenzweig | 965537df | 2020-07-22 10:23:50 -0400 | [diff] [blame] | 974 | so->modifier = prsrc->modifier; |
Icecream95 | fafc305 | 2020-06-12 20:14:02 +1200 | [diff] [blame] | 975 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 976 | unsigned char user_swizzle[4] = { |
Icecream95 | 3baf10a | 2020-04-30 15:21:17 +1200 | [diff] [blame] | 977 | so->base.swizzle_r, |
| 978 | so->base.swizzle_g, |
| 979 | so->base.swizzle_b, |
| 980 | so->base.swizzle_a |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 981 | }; |
| 982 | |
Alyssa Rosenzweig | 67a34ac | 2019-06-14 16:26:49 -0700 | [diff] [blame] | 983 | /* In the hardware, array_size refers specifically to array textures, |
| 984 | * whereas in Gallium, it also covers cubemaps */ |
| 985 | |
| 986 | unsigned array_size = texture->array_size; |
Alyssa Rosenzweig | 0b5bc6e | 2020-06-30 15:41:24 -0400 | [diff] [blame] | 987 | unsigned depth = texture->depth0; |
Alyssa Rosenzweig | 67a34ac | 2019-06-14 16:26:49 -0700 | [diff] [blame] | 988 | |
Icecream95 | 3baf10a | 2020-04-30 15:21:17 +1200 | [diff] [blame] | 989 | if (so->base.target == PIPE_TEXTURE_CUBE) { |
Alyssa Rosenzweig | 67a34ac | 2019-06-14 16:26:49 -0700 | [diff] [blame] | 990 | /* TODO: Cubemap arrays */ |
| 991 | assert(array_size == 6); |
Alyssa Rosenzweig | eb3c097 | 2019-06-21 17:27:05 -0700 | [diff] [blame] | 992 | array_size /= 6; |
Alyssa Rosenzweig | 67a34ac | 2019-06-14 16:26:49 -0700 | [diff] [blame] | 993 | } |
| 994 | |
Alyssa Rosenzweig | 0b5bc6e | 2020-06-30 15:41:24 -0400 | [diff] [blame] | 995 | /* MSAA only supported for 2D textures (and 2D texture arrays via an |
| 996 | * extension currently unimplemented */ |
| 997 | |
| 998 | if (so->base.target == PIPE_TEXTURE_2D) { |
| 999 | assert(depth == 1); |
| 1000 | depth = texture->nr_samples; |
| 1001 | } else { |
| 1002 | /* MSAA only supported for 2D textures */ |
| 1003 | assert(texture->nr_samples <= 1); |
| 1004 | } |
| 1005 | |
Alyssa Rosenzweig | f008a63 | 2020-08-11 17:27:36 -0400 | [diff] [blame] | 1006 | enum mali_texture_dimension type = |
| 1007 | panfrost_translate_texture_dimension(so->base.target); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1008 | |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 1009 | if (device->quirks & IS_BIFROST) { |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 1010 | unsigned char composed_swizzle[4]; |
| 1011 | util_format_compose_swizzles(desc->swizzle, user_swizzle, composed_swizzle); |
| 1012 | |
| 1013 | unsigned size = panfrost_estimate_texture_payload_size( |
Icecream95 | 3baf10a | 2020-04-30 15:21:17 +1200 | [diff] [blame] | 1014 | so->base.u.tex.first_level, |
| 1015 | so->base.u.tex.last_level, |
| 1016 | so->base.u.tex.first_layer, |
| 1017 | so->base.u.tex.last_layer, |
Alyssa Rosenzweig | 6088891 | 2020-07-15 11:39:08 -0400 | [diff] [blame] | 1018 | texture->nr_samples, |
Alyssa Rosenzweig | 965537df | 2020-07-22 10:23:50 -0400 | [diff] [blame] | 1019 | type, prsrc->modifier); |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 1020 | |
Alyssa Rosenzweig | 1d88f07 | 2020-07-07 16:19:39 -0400 | [diff] [blame] | 1021 | so->bo = panfrost_bo_create(device, size, 0); |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 1022 | |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 1023 | panfrost_new_texture_bifrost( |
Boris Brezillon | fefb3e9 | 2020-09-23 11:08:02 +0200 | [diff] [blame^] | 1024 | device, |
Alyssa Rosenzweig | ad0b32c | 2020-08-06 18:12:28 -0400 | [diff] [blame] | 1025 | &so->bifrost_descriptor, |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 1026 | texture->width0, texture->height0, |
Alyssa Rosenzweig | 0b5bc6e | 2020-06-30 15:41:24 -0400 | [diff] [blame] | 1027 | depth, array_size, |
Alyssa Rosenzweig | cce3d92 | 2020-07-09 16:34:00 -0400 | [diff] [blame] | 1028 | format, |
Alyssa Rosenzweig | 965537df | 2020-07-22 10:23:50 -0400 | [diff] [blame] | 1029 | type, prsrc->modifier, |
Icecream95 | 3baf10a | 2020-04-30 15:21:17 +1200 | [diff] [blame] | 1030 | so->base.u.tex.first_level, |
| 1031 | so->base.u.tex.last_level, |
| 1032 | so->base.u.tex.first_layer, |
| 1033 | so->base.u.tex.last_layer, |
Alyssa Rosenzweig | 41c06de | 2020-06-30 16:43:32 -0400 | [diff] [blame] | 1034 | texture->nr_samples, |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 1035 | prsrc->cubemap_stride, |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 1036 | panfrost_translate_swizzle_4(composed_swizzle), |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 1037 | prsrc->bo->gpu, |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 1038 | prsrc->slices, |
Alyssa Rosenzweig | 32b171d | 2020-06-15 09:20:39 -0400 | [diff] [blame] | 1039 | so->bo); |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 1040 | } else { |
Alyssa Rosenzweig | a3d2936 | 2020-04-21 16:08:07 -0400 | [diff] [blame] | 1041 | unsigned size = panfrost_estimate_texture_payload_size( |
Icecream95 | 3baf10a | 2020-04-30 15:21:17 +1200 | [diff] [blame] | 1042 | so->base.u.tex.first_level, |
| 1043 | so->base.u.tex.last_level, |
| 1044 | so->base.u.tex.first_layer, |
| 1045 | so->base.u.tex.last_layer, |
Alyssa Rosenzweig | 6088891 | 2020-07-15 11:39:08 -0400 | [diff] [blame] | 1046 | texture->nr_samples, |
Alyssa Rosenzweig | 965537df | 2020-07-22 10:23:50 -0400 | [diff] [blame] | 1047 | type, prsrc->modifier); |
Alyssa Rosenzweig | f008a63 | 2020-08-11 17:27:36 -0400 | [diff] [blame] | 1048 | size += MALI_MIDGARD_TEXTURE_LENGTH; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1049 | |
Alyssa Rosenzweig | 1d88f07 | 2020-07-07 16:19:39 -0400 | [diff] [blame] | 1050 | so->bo = panfrost_bo_create(device, size, 0); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1051 | |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 1052 | panfrost_new_texture( |
Alyssa Rosenzweig | 32b171d | 2020-06-15 09:20:39 -0400 | [diff] [blame] | 1053 | so->bo->cpu, |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 1054 | texture->width0, texture->height0, |
Alyssa Rosenzweig | 0b5bc6e | 2020-06-30 15:41:24 -0400 | [diff] [blame] | 1055 | depth, array_size, |
Alyssa Rosenzweig | cce3d92 | 2020-07-09 16:34:00 -0400 | [diff] [blame] | 1056 | format, |
Alyssa Rosenzweig | 965537df | 2020-07-22 10:23:50 -0400 | [diff] [blame] | 1057 | type, prsrc->modifier, |
Icecream95 | 3baf10a | 2020-04-30 15:21:17 +1200 | [diff] [blame] | 1058 | so->base.u.tex.first_level, |
| 1059 | so->base.u.tex.last_level, |
| 1060 | so->base.u.tex.first_layer, |
| 1061 | so->base.u.tex.last_layer, |
Alyssa Rosenzweig | 41c06de | 2020-06-30 16:43:32 -0400 | [diff] [blame] | 1062 | texture->nr_samples, |
Tomeu Vizoso | e41894b | 2020-04-17 14:23:49 +0200 | [diff] [blame] | 1063 | prsrc->cubemap_stride, |
| 1064 | panfrost_translate_swizzle_4(user_swizzle), |
| 1065 | prsrc->bo->gpu, |
| 1066 | prsrc->slices); |
| 1067 | } |
Icecream95 | 3baf10a | 2020-04-30 15:21:17 +1200 | [diff] [blame] | 1068 | } |
| 1069 | |
| 1070 | static struct pipe_sampler_view * |
| 1071 | panfrost_create_sampler_view( |
| 1072 | struct pipe_context *pctx, |
| 1073 | struct pipe_resource *texture, |
| 1074 | const struct pipe_sampler_view *template) |
| 1075 | { |
| 1076 | struct panfrost_sampler_view *so = rzalloc(pctx, struct panfrost_sampler_view); |
| 1077 | |
| 1078 | pipe_reference(NULL, &texture->reference); |
| 1079 | |
| 1080 | so->base = *template; |
| 1081 | so->base.texture = texture; |
| 1082 | so->base.reference.count = 1; |
| 1083 | so->base.context = pctx; |
| 1084 | |
| 1085 | panfrost_create_sampler_view_bo(so, pctx, texture); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1086 | |
| 1087 | return (struct pipe_sampler_view *) so; |
| 1088 | } |
| 1089 | |
| 1090 | static void |
| 1091 | panfrost_set_sampler_views( |
| 1092 | struct pipe_context *pctx, |
| 1093 | enum pipe_shader_type shader, |
| 1094 | unsigned start_slot, unsigned num_views, |
| 1095 | struct pipe_sampler_view **views) |
| 1096 | { |
| 1097 | struct panfrost_context *ctx = pan_context(pctx); |
Tomeu Vizoso | 5dfe412 | 2019-12-12 08:43:12 +0100 | [diff] [blame] | 1098 | unsigned new_nr = 0; |
| 1099 | unsigned i; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1100 | |
| 1101 | assert(start_slot == 0); |
| 1102 | |
Tomeu Vizoso | 5dfe412 | 2019-12-12 08:43:12 +0100 | [diff] [blame] | 1103 | for (i = 0; i < num_views; ++i) { |
Alyssa Rosenzweig | 0219b99 | 2019-06-11 14:21:14 -0700 | [diff] [blame] | 1104 | if (views[i]) |
| 1105 | new_nr = i + 1; |
Tomeu Vizoso | 5dfe412 | 2019-12-12 08:43:12 +0100 | [diff] [blame] | 1106 | pipe_sampler_view_reference((struct pipe_sampler_view **)&ctx->sampler_views[shader][i], |
| 1107 | views[i]); |
Alyssa Rosenzweig | 0219b99 | 2019-06-11 14:21:14 -0700 | [diff] [blame] | 1108 | } |
| 1109 | |
Tomeu Vizoso | 5dfe412 | 2019-12-12 08:43:12 +0100 | [diff] [blame] | 1110 | for (; i < ctx->sampler_view_count[shader]; i++) { |
| 1111 | pipe_sampler_view_reference((struct pipe_sampler_view **)&ctx->sampler_views[shader][i], |
| 1112 | NULL); |
| 1113 | } |
Alyssa Rosenzweig | 0219b99 | 2019-06-11 14:21:14 -0700 | [diff] [blame] | 1114 | ctx->sampler_view_count[shader] = new_nr; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1115 | } |
| 1116 | |
| 1117 | static void |
| 1118 | panfrost_sampler_view_destroy( |
| 1119 | struct pipe_context *pctx, |
Alyssa Rosenzweig | b929565 | 2020-02-18 14:20:16 -0500 | [diff] [blame] | 1120 | struct pipe_sampler_view *pview) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1121 | { |
Alyssa Rosenzweig | b929565 | 2020-02-18 14:20:16 -0500 | [diff] [blame] | 1122 | struct panfrost_sampler_view *view = (struct panfrost_sampler_view *) pview; |
| 1123 | |
| 1124 | pipe_resource_reference(&pview->texture, NULL); |
Alyssa Rosenzweig | 32b171d | 2020-06-15 09:20:39 -0400 | [diff] [blame] | 1125 | panfrost_bo_unreference(view->bo); |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1126 | ralloc_free(view); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1127 | } |
| 1128 | |
Alyssa Rosenzweig | 4e736b8 | 2019-08-01 10:31:35 -0700 | [diff] [blame] | 1129 | static void |
| 1130 | panfrost_set_shader_buffers( |
| 1131 | struct pipe_context *pctx, |
| 1132 | enum pipe_shader_type shader, |
| 1133 | unsigned start, unsigned count, |
| 1134 | const struct pipe_shader_buffer *buffers, |
| 1135 | unsigned writable_bitmask) |
| 1136 | { |
| 1137 | struct panfrost_context *ctx = pan_context(pctx); |
| 1138 | |
| 1139 | util_set_shader_buffers_mask(ctx->ssbo[shader], &ctx->ssbo_mask[shader], |
| 1140 | buffers, start, count); |
| 1141 | } |
| 1142 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1143 | static void |
| 1144 | panfrost_set_framebuffer_state(struct pipe_context *pctx, |
| 1145 | const struct pipe_framebuffer_state *fb) |
| 1146 | { |
| 1147 | struct panfrost_context *ctx = pan_context(pctx); |
| 1148 | |
Alyssa Rosenzweig | 629c736 | 2019-07-18 11:05:01 -0700 | [diff] [blame] | 1149 | util_copy_framebuffer_state(&ctx->pipe_framebuffer, fb); |
Boris Brezillon | 1ac33aa | 2019-09-15 20:33:13 +0200 | [diff] [blame] | 1150 | ctx->batch = NULL; |
Alyssa Rosenzweig | b9869e0 | 2020-07-10 12:12:14 -0400 | [diff] [blame] | 1151 | |
| 1152 | /* We may need to generate a new variant if the fragment shader is |
| 1153 | * keyed to the framebuffer format (due to EXT_framebuffer_fetch) */ |
| 1154 | struct panfrost_shader_variants *fs = ctx->shader[PIPE_SHADER_FRAGMENT]; |
| 1155 | |
| 1156 | if (fs && fs->variant_count && fs->variants[fs->active_variant].outputs_read) |
| 1157 | ctx->base.bind_fs_state(&ctx->base, fs); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1158 | } |
| 1159 | |
Alyssa Rosenzweig | 6afd4ad | 2020-08-12 11:42:11 -0400 | [diff] [blame] | 1160 | static inline unsigned |
| 1161 | pan_pipe_to_stencil_op(enum pipe_stencil_op in) |
| 1162 | { |
| 1163 | switch (in) { |
| 1164 | case PIPE_STENCIL_OP_KEEP: return MALI_STENCIL_OP_KEEP; |
| 1165 | case PIPE_STENCIL_OP_ZERO: return MALI_STENCIL_OP_ZERO; |
| 1166 | case PIPE_STENCIL_OP_REPLACE: return MALI_STENCIL_OP_REPLACE; |
| 1167 | case PIPE_STENCIL_OP_INCR: return MALI_STENCIL_OP_INCR_SAT; |
| 1168 | case PIPE_STENCIL_OP_DECR: return MALI_STENCIL_OP_DECR_SAT; |
| 1169 | case PIPE_STENCIL_OP_INCR_WRAP: return MALI_STENCIL_OP_INCR_WRAP; |
| 1170 | case PIPE_STENCIL_OP_DECR_WRAP: return MALI_STENCIL_OP_DECR_WRAP; |
| 1171 | case PIPE_STENCIL_OP_INVERT: return MALI_STENCIL_OP_INVERT; |
| 1172 | default: unreachable("Invalid stencil op"); |
| 1173 | } |
| 1174 | } |
| 1175 | |
| 1176 | static inline void |
| 1177 | pan_pipe_to_stencil(const struct pipe_stencil_state *in, void *out) |
| 1178 | { |
| 1179 | pan_pack(out, STENCIL, cfg) { |
| 1180 | cfg.mask = in->valuemask; |
| 1181 | cfg.compare_function = panfrost_translate_compare_func(in->func); |
| 1182 | cfg.stencil_fail = pan_pipe_to_stencil_op(in->fail_op); |
| 1183 | cfg.depth_fail = pan_pipe_to_stencil_op(in->zfail_op); |
| 1184 | cfg.depth_pass = pan_pipe_to_stencil_op(in->zpass_op); |
| 1185 | } |
| 1186 | } |
| 1187 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1188 | static void * |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1189 | panfrost_create_depth_stencil_state(struct pipe_context *pipe, |
Alyssa Rosenzweig | 6afd4ad | 2020-08-12 11:42:11 -0400 | [diff] [blame] | 1190 | const struct pipe_depth_stencil_alpha_state *zsa) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1191 | { |
Alyssa Rosenzweig | 6afd4ad | 2020-08-12 11:42:11 -0400 | [diff] [blame] | 1192 | struct panfrost_zsa_state *so = CALLOC_STRUCT(panfrost_zsa_state); |
| 1193 | so->base = *zsa; |
| 1194 | |
| 1195 | pan_pipe_to_stencil(&zsa->stencil[0], &so->stencil_front); |
Alyssa Rosenzweig | 6afd4ad | 2020-08-12 11:42:11 -0400 | [diff] [blame] | 1196 | so->stencil_mask_front = zsa->stencil[0].writemask; |
| 1197 | |
Alyssa Rosenzweig | 1b377c2 | 2020-08-21 19:27:40 -0400 | [diff] [blame] | 1198 | if (zsa->stencil[1].enabled) { |
| 1199 | pan_pipe_to_stencil(&zsa->stencil[1], &so->stencil_back); |
Alyssa Rosenzweig | 6afd4ad | 2020-08-12 11:42:11 -0400 | [diff] [blame] | 1200 | so->stencil_mask_back = zsa->stencil[1].writemask; |
Alyssa Rosenzweig | 1b377c2 | 2020-08-21 19:27:40 -0400 | [diff] [blame] | 1201 | } else { |
| 1202 | so->stencil_back = so->stencil_front; |
Alyssa Rosenzweig | 6afd4ad | 2020-08-12 11:42:11 -0400 | [diff] [blame] | 1203 | so->stencil_mask_back = so->stencil_mask_front; |
Alyssa Rosenzweig | 1b377c2 | 2020-08-21 19:27:40 -0400 | [diff] [blame] | 1204 | } |
Alyssa Rosenzweig | 6afd4ad | 2020-08-12 11:42:11 -0400 | [diff] [blame] | 1205 | |
| 1206 | /* Alpha lowered by frontend */ |
| 1207 | assert(!zsa->alpha.enabled); |
| 1208 | |
| 1209 | /* TODO: Bounds test should be easy */ |
| 1210 | assert(!zsa->depth.bounds_test); |
| 1211 | |
| 1212 | return so; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1213 | } |
| 1214 | |
| 1215 | static void |
| 1216 | panfrost_bind_depth_stencil_state(struct pipe_context *pipe, |
| 1217 | void *cso) |
| 1218 | { |
| 1219 | struct panfrost_context *ctx = pan_context(pipe); |
Alyssa Rosenzweig | 7d328e7 | 2020-08-26 10:50:18 -0400 | [diff] [blame] | 1220 | ctx->depth_stencil = cso; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1221 | } |
| 1222 | |
| 1223 | static void |
| 1224 | panfrost_delete_depth_stencil_state(struct pipe_context *pipe, void *depth) |
| 1225 | { |
| 1226 | free( depth ); |
| 1227 | } |
| 1228 | |
| 1229 | static void |
| 1230 | panfrost_set_sample_mask(struct pipe_context *pipe, |
| 1231 | unsigned sample_mask) |
| 1232 | { |
Alyssa Rosenzweig | f23cdd4 | 2020-07-02 10:07:08 -0400 | [diff] [blame] | 1233 | struct panfrost_context *ctx = pan_context(pipe); |
| 1234 | ctx->sample_mask = sample_mask; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1235 | } |
| 1236 | |
| 1237 | static void |
Alyssa Rosenzweig | 8225604 | 2020-07-15 11:38:39 -0400 | [diff] [blame] | 1238 | panfrost_set_min_samples(struct pipe_context *pipe, |
| 1239 | unsigned min_samples) |
| 1240 | { |
| 1241 | struct panfrost_context *ctx = pan_context(pipe); |
| 1242 | ctx->min_samples = min_samples; |
| 1243 | } |
| 1244 | |
| 1245 | |
| 1246 | static void |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1247 | panfrost_set_clip_state(struct pipe_context *pipe, |
| 1248 | const struct pipe_clip_state *clip) |
| 1249 | { |
| 1250 | //struct panfrost_context *panfrost = pan_context(pipe); |
| 1251 | } |
| 1252 | |
| 1253 | static void |
| 1254 | panfrost_set_viewport_states(struct pipe_context *pipe, |
| 1255 | unsigned start_slot, |
| 1256 | unsigned num_viewports, |
| 1257 | const struct pipe_viewport_state *viewports) |
| 1258 | { |
| 1259 | struct panfrost_context *ctx = pan_context(pipe); |
| 1260 | |
| 1261 | assert(start_slot == 0); |
| 1262 | assert(num_viewports == 1); |
| 1263 | |
| 1264 | ctx->pipe_viewport = *viewports; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1265 | } |
| 1266 | |
| 1267 | static void |
| 1268 | panfrost_set_scissor_states(struct pipe_context *pipe, |
| 1269 | unsigned start_slot, |
| 1270 | unsigned num_scissors, |
| 1271 | const struct pipe_scissor_state *scissors) |
| 1272 | { |
| 1273 | struct panfrost_context *ctx = pan_context(pipe); |
| 1274 | |
| 1275 | assert(start_slot == 0); |
| 1276 | assert(num_scissors == 1); |
| 1277 | |
| 1278 | ctx->scissor = *scissors; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1279 | } |
| 1280 | |
| 1281 | static void |
| 1282 | panfrost_set_polygon_stipple(struct pipe_context *pipe, |
| 1283 | const struct pipe_poly_stipple *stipple) |
| 1284 | { |
| 1285 | //struct panfrost_context *panfrost = pan_context(pipe); |
| 1286 | } |
| 1287 | |
| 1288 | static void |
| 1289 | panfrost_set_active_query_state(struct pipe_context *pipe, |
Ilia Mirkin | 0e30c6b | 2019-07-04 11:41:41 -0400 | [diff] [blame] | 1290 | bool enable) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1291 | { |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1292 | struct panfrost_context *ctx = pan_context(pipe); |
| 1293 | ctx->active_queries = enable; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1294 | } |
| 1295 | |
| 1296 | static void |
| 1297 | panfrost_destroy(struct pipe_context *pipe) |
| 1298 | { |
| 1299 | struct panfrost_context *panfrost = pan_context(pipe); |
| 1300 | |
| 1301 | if (panfrost->blitter) |
| 1302 | util_blitter_destroy(panfrost->blitter); |
Tomeu Vizoso | 756f7b9 | 2019-03-08 10:27:07 +0100 | [diff] [blame] | 1303 | |
Alyssa Rosenzweig | 7005c0d | 2019-06-23 11:05:10 -0700 | [diff] [blame] | 1304 | if (panfrost->blitter_wallpaper) |
| 1305 | util_blitter_destroy(panfrost->blitter_wallpaper); |
| 1306 | |
Boris Brezillon | b60ed3c | 2019-11-06 15:52:45 +0100 | [diff] [blame] | 1307 | util_unreference_framebuffer_state(&panfrost->pipe_framebuffer); |
Boris Brezillon | 8c8e4fd | 2019-11-06 15:49:43 +0100 | [diff] [blame] | 1308 | u_upload_destroy(pipe->stream_uploader); |
Alyssa Rosenzweig | 8c14482 | 2020-08-21 13:42:55 -0400 | [diff] [blame] | 1309 | u_upload_destroy(panfrost->state_uploader); |
Boris Brezillon | 8c8e4fd | 2019-11-06 15:49:43 +0100 | [diff] [blame] | 1310 | |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1311 | ralloc_free(pipe); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1312 | } |
| 1313 | |
| 1314 | static struct pipe_query * |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1315 | panfrost_create_query(struct pipe_context *pipe, |
| 1316 | unsigned type, |
| 1317 | unsigned index) |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1318 | { |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1319 | struct panfrost_query *q = rzalloc(pipe, struct panfrost_query); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1320 | |
| 1321 | q->type = type; |
| 1322 | q->index = index; |
| 1323 | |
| 1324 | return (struct pipe_query *) q; |
| 1325 | } |
| 1326 | |
| 1327 | static void |
| 1328 | panfrost_destroy_query(struct pipe_context *pipe, struct pipe_query *q) |
| 1329 | { |
Urja Rannikko | dff99ce | 2019-10-22 12:05:07 +0000 | [diff] [blame] | 1330 | struct panfrost_query *query = (struct panfrost_query *) q; |
| 1331 | |
| 1332 | if (query->bo) { |
| 1333 | panfrost_bo_unreference(query->bo); |
| 1334 | query->bo = NULL; |
| 1335 | } |
| 1336 | |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1337 | ralloc_free(q); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1338 | } |
| 1339 | |
Ilia Mirkin | 0e30c6b | 2019-07-04 11:41:41 -0400 | [diff] [blame] | 1340 | static bool |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1341 | panfrost_begin_query(struct pipe_context *pipe, struct pipe_query *q) |
| 1342 | { |
| 1343 | struct panfrost_context *ctx = pan_context(pipe); |
| 1344 | struct panfrost_query *query = (struct panfrost_query *) q; |
| 1345 | |
| 1346 | switch (query->type) { |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1347 | case PIPE_QUERY_OCCLUSION_COUNTER: |
| 1348 | case PIPE_QUERY_OCCLUSION_PREDICATE: |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1349 | case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: |
Urja Rannikko | dff99ce | 2019-10-22 12:05:07 +0000 | [diff] [blame] | 1350 | /* Allocate a bo for the query results to be stored */ |
| 1351 | if (!query->bo) { |
Alyssa Rosenzweig | 1d88f07 | 2020-07-07 16:19:39 -0400 | [diff] [blame] | 1352 | query->bo = panfrost_bo_create( |
Alyssa Rosenzweig | ca8c625 | 2020-03-23 18:44:21 -0400 | [diff] [blame] | 1353 | pan_device(ctx->base.screen), |
Urja Rannikko | dff99ce | 2019-10-22 12:05:07 +0000 | [diff] [blame] | 1354 | sizeof(unsigned), 0); |
| 1355 | } |
| 1356 | |
| 1357 | unsigned *result = (unsigned *)query->bo->cpu; |
| 1358 | *result = 0; /* Default to 0 if nothing at all drawn. */ |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1359 | ctx->occlusion_query = query; |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1360 | break; |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1361 | |
| 1362 | /* Geometry statistics are computed in the driver. XXX: geom/tess |
| 1363 | * shaders.. */ |
| 1364 | |
| 1365 | case PIPE_QUERY_PRIMITIVES_GENERATED: |
| 1366 | query->start = ctx->prims_generated; |
| 1367 | break; |
| 1368 | case PIPE_QUERY_PRIMITIVES_EMITTED: |
| 1369 | query->start = ctx->tf_prims_generated; |
| 1370 | break; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1371 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1372 | default: |
Alyssa Rosenzweig | ed1910d | 2020-07-07 16:15:45 -0400 | [diff] [blame] | 1373 | /* TODO: timestamp queries, etc? */ |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1374 | break; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1375 | } |
| 1376 | |
| 1377 | return true; |
| 1378 | } |
| 1379 | |
| 1380 | static bool |
| 1381 | panfrost_end_query(struct pipe_context *pipe, struct pipe_query *q) |
| 1382 | { |
| 1383 | struct panfrost_context *ctx = pan_context(pipe); |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1384 | struct panfrost_query *query = (struct panfrost_query *) q; |
| 1385 | |
| 1386 | switch (query->type) { |
| 1387 | case PIPE_QUERY_OCCLUSION_COUNTER: |
| 1388 | case PIPE_QUERY_OCCLUSION_PREDICATE: |
| 1389 | case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: |
| 1390 | ctx->occlusion_query = NULL; |
| 1391 | break; |
| 1392 | case PIPE_QUERY_PRIMITIVES_GENERATED: |
| 1393 | query->end = ctx->prims_generated; |
| 1394 | break; |
| 1395 | case PIPE_QUERY_PRIMITIVES_EMITTED: |
| 1396 | query->end = ctx->tf_prims_generated; |
| 1397 | break; |
| 1398 | } |
| 1399 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1400 | return true; |
| 1401 | } |
| 1402 | |
Ilia Mirkin | 0e30c6b | 2019-07-04 11:41:41 -0400 | [diff] [blame] | 1403 | static bool |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1404 | panfrost_get_query_result(struct pipe_context *pipe, |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1405 | struct pipe_query *q, |
Ilia Mirkin | 0e30c6b | 2019-07-04 11:41:41 -0400 | [diff] [blame] | 1406 | bool wait, |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1407 | union pipe_query_result *vresult) |
| 1408 | { |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1409 | struct panfrost_query *query = (struct panfrost_query *) q; |
Boris Brezillon | a45984b | 2019-09-15 19:15:16 +0200 | [diff] [blame] | 1410 | struct panfrost_context *ctx = pan_context(pipe); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1411 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1412 | |
| 1413 | switch (query->type) { |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1414 | case PIPE_QUERY_OCCLUSION_COUNTER: |
| 1415 | case PIPE_QUERY_OCCLUSION_PREDICATE: |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1416 | case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: |
Icecream95 | 0ef168d | 2020-07-18 11:39:45 +1200 | [diff] [blame] | 1417 | panfrost_flush_batches_accessing_bo(ctx, query->bo, false); |
Icecream95 | 858cc13 | 2020-07-18 11:36:36 +1200 | [diff] [blame] | 1418 | panfrost_bo_wait(query->bo, INT64_MAX, false); |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1419 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1420 | /* Read back the query results */ |
Urja Rannikko | dff99ce | 2019-10-22 12:05:07 +0000 | [diff] [blame] | 1421 | unsigned *result = (unsigned *) query->bo->cpu; |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1422 | unsigned passed = *result; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1423 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1424 | if (query->type == PIPE_QUERY_OCCLUSION_COUNTER) { |
| 1425 | vresult->u64 = passed; |
| 1426 | } else { |
| 1427 | vresult->b = !!passed; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1428 | } |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1429 | |
| 1430 | break; |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1431 | |
| 1432 | case PIPE_QUERY_PRIMITIVES_GENERATED: |
| 1433 | case PIPE_QUERY_PRIMITIVES_EMITTED: |
Alyssa Rosenzweig | 64d6f56 | 2020-07-20 13:34:42 -0400 | [diff] [blame] | 1434 | panfrost_flush_all_batches(ctx, 0); |
Alyssa Rosenzweig | 7c224c1 | 2019-08-08 07:01:12 -0700 | [diff] [blame] | 1435 | vresult->u64 = query->end - query->start; |
| 1436 | break; |
| 1437 | |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1438 | default: |
Alyssa Rosenzweig | ed1910d | 2020-07-07 16:15:45 -0400 | [diff] [blame] | 1439 | /* TODO: more queries */ |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1440 | break; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1441 | } |
| 1442 | |
| 1443 | return true; |
| 1444 | } |
| 1445 | |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1446 | static struct pipe_stream_output_target * |
| 1447 | panfrost_create_stream_output_target(struct pipe_context *pctx, |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1448 | struct pipe_resource *prsc, |
| 1449 | unsigned buffer_offset, |
| 1450 | unsigned buffer_size) |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1451 | { |
| 1452 | struct pipe_stream_output_target *target; |
| 1453 | |
Ilia Mirkin | 4c050f2 | 2020-08-09 00:13:14 -0400 | [diff] [blame] | 1454 | target = &rzalloc(pctx, struct panfrost_streamout_target)->base; |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1455 | |
| 1456 | if (!target) |
| 1457 | return NULL; |
| 1458 | |
| 1459 | pipe_reference_init(&target->reference, 1); |
| 1460 | pipe_resource_reference(&target->buffer, prsc); |
| 1461 | |
| 1462 | target->context = pctx; |
| 1463 | target->buffer_offset = buffer_offset; |
| 1464 | target->buffer_size = buffer_size; |
| 1465 | |
| 1466 | return target; |
| 1467 | } |
| 1468 | |
| 1469 | static void |
| 1470 | panfrost_stream_output_target_destroy(struct pipe_context *pctx, |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1471 | struct pipe_stream_output_target *target) |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1472 | { |
| 1473 | pipe_resource_reference(&target->buffer, NULL); |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1474 | ralloc_free(target); |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1475 | } |
| 1476 | |
| 1477 | static void |
| 1478 | panfrost_set_stream_output_targets(struct pipe_context *pctx, |
Alyssa Rosenzweig | a2d0ea9 | 2019-07-10 10:10:31 -0700 | [diff] [blame] | 1479 | unsigned num_targets, |
| 1480 | struct pipe_stream_output_target **targets, |
| 1481 | const unsigned *offsets) |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1482 | { |
Alyssa Rosenzweig | 5ff7973 | 2019-08-06 16:43:28 -0700 | [diff] [blame] | 1483 | struct panfrost_context *ctx = pan_context(pctx); |
| 1484 | struct panfrost_streamout *so = &ctx->streamout; |
| 1485 | |
| 1486 | assert(num_targets <= ARRAY_SIZE(so->targets)); |
| 1487 | |
| 1488 | for (unsigned i = 0; i < num_targets; i++) { |
| 1489 | if (offsets[i] != -1) |
Ilia Mirkin | 4c050f2 | 2020-08-09 00:13:14 -0400 | [diff] [blame] | 1490 | pan_so_target(targets[i])->offset = offsets[i]; |
Alyssa Rosenzweig | 5ff7973 | 2019-08-06 16:43:28 -0700 | [diff] [blame] | 1491 | |
| 1492 | pipe_so_target_reference(&so->targets[i], targets[i]); |
| 1493 | } |
| 1494 | |
| 1495 | for (unsigned i = 0; i < so->num_targets; i++) |
| 1496 | pipe_so_target_reference(&so->targets[i], NULL); |
| 1497 | |
| 1498 | so->num_targets = num_targets; |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1499 | } |
| 1500 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1501 | struct pipe_context * |
| 1502 | panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags) |
| 1503 | { |
Tomeu Vizoso | 0fcf73b | 2019-06-18 14:24:57 +0200 | [diff] [blame] | 1504 | struct panfrost_context *ctx = rzalloc(screen, struct panfrost_context); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1505 | struct pipe_context *gallium = (struct pipe_context *) ctx; |
Alyssa Rosenzweig | 229084f | 2020-05-29 14:02:43 -0400 | [diff] [blame] | 1506 | struct panfrost_device *dev = pan_device(screen); |
Tomeu Vizoso | 756f7b9 | 2019-03-08 10:27:07 +0100 | [diff] [blame] | 1507 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1508 | gallium->screen = screen; |
| 1509 | |
| 1510 | gallium->destroy = panfrost_destroy; |
| 1511 | |
| 1512 | gallium->set_framebuffer_state = panfrost_set_framebuffer_state; |
| 1513 | |
| 1514 | gallium->flush = panfrost_flush; |
| 1515 | gallium->clear = panfrost_clear; |
| 1516 | gallium->draw_vbo = panfrost_draw_vbo; |
Icecream95 | 391ad72 | 2020-07-10 11:19:07 +1200 | [diff] [blame] | 1517 | gallium->texture_barrier = panfrost_texture_barrier; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1518 | |
| 1519 | gallium->set_vertex_buffers = panfrost_set_vertex_buffers; |
| 1520 | gallium->set_constant_buffer = panfrost_set_constant_buffer; |
Alyssa Rosenzweig | 4e736b8 | 2019-08-01 10:31:35 -0700 | [diff] [blame] | 1521 | gallium->set_shader_buffers = panfrost_set_shader_buffers; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1522 | |
| 1523 | gallium->set_stencil_ref = panfrost_set_stencil_ref; |
| 1524 | |
| 1525 | gallium->create_sampler_view = panfrost_create_sampler_view; |
| 1526 | gallium->set_sampler_views = panfrost_set_sampler_views; |
| 1527 | gallium->sampler_view_destroy = panfrost_sampler_view_destroy; |
| 1528 | |
| 1529 | gallium->create_rasterizer_state = panfrost_create_rasterizer_state; |
| 1530 | gallium->bind_rasterizer_state = panfrost_bind_rasterizer_state; |
| 1531 | gallium->delete_rasterizer_state = panfrost_generic_cso_delete; |
| 1532 | |
| 1533 | gallium->create_vertex_elements_state = panfrost_create_vertex_elements_state; |
| 1534 | gallium->bind_vertex_elements_state = panfrost_bind_vertex_elements_state; |
Alyssa Rosenzweig | 81d3262 | 2019-05-17 00:14:49 +0000 | [diff] [blame] | 1535 | gallium->delete_vertex_elements_state = panfrost_generic_cso_delete; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1536 | |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 1537 | gallium->create_fs_state = panfrost_create_fs_state; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1538 | gallium->delete_fs_state = panfrost_delete_shader_state; |
| 1539 | gallium->bind_fs_state = panfrost_bind_fs_state; |
| 1540 | |
Alyssa Rosenzweig | 271726e | 2019-12-13 15:13:02 -0500 | [diff] [blame] | 1541 | gallium->create_vs_state = panfrost_create_vs_state; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1542 | gallium->delete_vs_state = panfrost_delete_shader_state; |
| 1543 | gallium->bind_vs_state = panfrost_bind_vs_state; |
| 1544 | |
| 1545 | gallium->create_sampler_state = panfrost_create_sampler_state; |
| 1546 | gallium->delete_sampler_state = panfrost_generic_cso_delete; |
| 1547 | gallium->bind_sampler_states = panfrost_bind_sampler_states; |
| 1548 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1549 | gallium->create_depth_stencil_alpha_state = panfrost_create_depth_stencil_state; |
| 1550 | gallium->bind_depth_stencil_alpha_state = panfrost_bind_depth_stencil_state; |
| 1551 | gallium->delete_depth_stencil_alpha_state = panfrost_delete_depth_stencil_state; |
| 1552 | |
| 1553 | gallium->set_sample_mask = panfrost_set_sample_mask; |
Alyssa Rosenzweig | 8225604 | 2020-07-15 11:38:39 -0400 | [diff] [blame] | 1554 | gallium->set_min_samples = panfrost_set_min_samples; |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1555 | |
| 1556 | gallium->set_clip_state = panfrost_set_clip_state; |
| 1557 | gallium->set_viewport_states = panfrost_set_viewport_states; |
| 1558 | gallium->set_scissor_states = panfrost_set_scissor_states; |
| 1559 | gallium->set_polygon_stipple = panfrost_set_polygon_stipple; |
| 1560 | gallium->set_active_query_state = panfrost_set_active_query_state; |
| 1561 | |
| 1562 | gallium->create_query = panfrost_create_query; |
| 1563 | gallium->destroy_query = panfrost_destroy_query; |
| 1564 | gallium->begin_query = panfrost_begin_query; |
| 1565 | gallium->end_query = panfrost_end_query; |
| 1566 | gallium->get_query_result = panfrost_get_query_result; |
| 1567 | |
Alyssa Rosenzweig | f277bd3 | 2019-03-25 04:57:27 +0000 | [diff] [blame] | 1568 | gallium->create_stream_output_target = panfrost_create_stream_output_target; |
| 1569 | gallium->stream_output_target_destroy = panfrost_stream_output_target_destroy; |
| 1570 | gallium->set_stream_output_targets = panfrost_set_stream_output_targets; |
| 1571 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1572 | panfrost_resource_context_init(gallium); |
Alyssa Rosenzweig | 46396af | 2019-07-05 15:40:08 -0700 | [diff] [blame] | 1573 | panfrost_blend_context_init(gallium); |
Alyssa Rosenzweig | a8fc40a | 2019-07-23 08:28:23 -0700 | [diff] [blame] | 1574 | panfrost_compute_context_init(gallium); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1575 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1576 | gallium->stream_uploader = u_upload_create_default(gallium); |
| 1577 | gallium->const_uploader = gallium->stream_uploader; |
Alyssa Rosenzweig | 8c14482 | 2020-08-21 13:42:55 -0400 | [diff] [blame] | 1578 | |
| 1579 | ctx->state_uploader = u_upload_create(gallium, 4096, |
| 1580 | PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_DYNAMIC, 0); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1581 | |
Alyssa Rosenzweig | 229084f | 2020-05-29 14:02:43 -0400 | [diff] [blame] | 1582 | /* All of our GPUs support ES mode. Midgard supports additionally |
| 1583 | * QUADS/QUAD_STRIPS/POLYGON. Bifrost supports just QUADS. */ |
| 1584 | |
| 1585 | ctx->draw_modes = (1 << (PIPE_PRIM_QUADS + 1)) - 1; |
| 1586 | |
| 1587 | if (!(dev->quirks & IS_BIFROST)) { |
| 1588 | ctx->draw_modes |= (1 << PIPE_PRIM_QUAD_STRIP); |
| 1589 | ctx->draw_modes |= (1 << PIPE_PRIM_POLYGON); |
| 1590 | } |
Alyssa Rosenzweig | 85e2bb5 | 2019-02-08 02:28:12 +0000 | [diff] [blame] | 1591 | |
| 1592 | ctx->primconvert = util_primconvert_create(gallium, ctx->draw_modes); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1593 | |
| 1594 | ctx->blitter = util_blitter_create(gallium); |
Alyssa Rosenzweig | 7005c0d | 2019-06-23 11:05:10 -0700 | [diff] [blame] | 1595 | ctx->blitter_wallpaper = util_blitter_create(gallium); |
| 1596 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1597 | assert(ctx->blitter); |
Alyssa Rosenzweig | 7005c0d | 2019-06-23 11:05:10 -0700 | [diff] [blame] | 1598 | assert(ctx->blitter_wallpaper); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1599 | |
| 1600 | /* Prepare for render! */ |
| 1601 | |
Boris Brezillon | 2c52699 | 2019-09-05 21:41:26 +0200 | [diff] [blame] | 1602 | panfrost_batch_init(ctx); |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1603 | |
Alyssa Rosenzweig | 293f251 | 2020-07-09 13:42:25 -0400 | [diff] [blame] | 1604 | if (!(dev->quirks & IS_BIFROST)) { |
| 1605 | for (unsigned c = 0; c < PIPE_MAX_COLOR_BUFS; ++c) |
| 1606 | ctx->blit_blend.rt[c].shaders = _mesa_hash_table_u64_create(ctx); |
| 1607 | } |
| 1608 | |
Alyssa Rosenzweig | f23cdd4 | 2020-07-02 10:07:08 -0400 | [diff] [blame] | 1609 | /* By default mask everything on */ |
| 1610 | ctx->sample_mask = ~0; |
Alyssa Rosenzweig | 4b21c8b | 2020-08-14 18:22:36 -0400 | [diff] [blame] | 1611 | ctx->active_queries = true; |
Alyssa Rosenzweig | f23cdd4 | 2020-07-02 10:07:08 -0400 | [diff] [blame] | 1612 | |
Alyssa Rosenzweig | 7da251f | 2019-02-05 04:32:27 +0000 | [diff] [blame] | 1613 | return gallium; |
| 1614 | } |