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