• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 Collabora Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #include "pan_context.h"
25 #include "util/u_vbuf.h"
26 
27 void
panfrost_analyze_sysvals(struct panfrost_shader_state * ss)28 panfrost_analyze_sysvals(struct panfrost_shader_state *ss)
29 {
30         unsigned dirty = 0;
31         unsigned dirty_shader =
32                 PAN_DIRTY_STAGE_RENDERER | PAN_DIRTY_STAGE_CONST;
33 
34         for (unsigned i = 0; i < ss->info.sysvals.sysval_count; ++i) {
35                 switch (PAN_SYSVAL_TYPE(ss->info.sysvals.sysvals[i])) {
36                 case PAN_SYSVAL_VIEWPORT_SCALE:
37                 case PAN_SYSVAL_VIEWPORT_OFFSET:
38                         dirty |= PAN_DIRTY_VIEWPORT;
39                         break;
40 
41                 case PAN_SYSVAL_TEXTURE_SIZE:
42                         dirty_shader |= PAN_DIRTY_STAGE_TEXTURE;
43                         break;
44 
45                 case PAN_SYSVAL_SSBO:
46                         dirty_shader |= PAN_DIRTY_STAGE_SSBO;
47                         break;
48 
49                 case PAN_SYSVAL_SAMPLER:
50                         dirty_shader |= PAN_DIRTY_STAGE_SAMPLER;
51                         break;
52 
53                 case PAN_SYSVAL_IMAGE_SIZE:
54                         dirty_shader |= PAN_DIRTY_STAGE_IMAGE;
55                         break;
56 
57                 case PAN_SYSVAL_NUM_WORK_GROUPS:
58                 case PAN_SYSVAL_LOCAL_GROUP_SIZE:
59                 case PAN_SYSVAL_WORK_DIM:
60                 case PAN_SYSVAL_VERTEX_INSTANCE_OFFSETS:
61                         dirty |= PAN_DIRTY_PARAMS;
62                         break;
63 
64                 case PAN_SYSVAL_DRAWID:
65                         dirty |= PAN_DIRTY_DRAWID;
66                         break;
67 
68                 case PAN_SYSVAL_SAMPLE_POSITIONS:
69                 case PAN_SYSVAL_MULTISAMPLED:
70                 case PAN_SYSVAL_RT_CONVERSION:
71                         /* Nothing beyond the batch itself */
72                         break;
73                 default:
74                         unreachable("Invalid sysval");
75                 }
76         }
77 
78         ss->dirty_3d = dirty;
79         ss->dirty_shader = dirty_shader;
80 }
81 
82 /* Gets a GPU address for the associated index buffer. Only gauranteed to be
83  * good for the duration of the draw (transient), could last longer. Also get
84  * the bounds on the index buffer for the range accessed by the draw. We do
85  * these operations together because there are natural optimizations which
86  * require them to be together. */
87 
88 mali_ptr
panfrost_get_index_buffer_bounded(struct panfrost_batch * batch,const struct pipe_draw_info * info,const struct pipe_draw_start_count_bias * draw,unsigned * min_index,unsigned * max_index)89 panfrost_get_index_buffer_bounded(struct panfrost_batch *batch,
90                                   const struct pipe_draw_info *info,
91                                   const struct pipe_draw_start_count_bias *draw,
92                                   unsigned *min_index, unsigned *max_index)
93 {
94         struct panfrost_resource *rsrc = pan_resource(info->index.resource);
95         struct panfrost_context *ctx = batch->ctx;
96         off_t offset = draw->start * info->index_size;
97         bool needs_indices = true;
98         mali_ptr out = 0;
99 
100         if (info->index_bounds_valid) {
101                 *min_index = info->min_index;
102                 *max_index = info->max_index;
103                 needs_indices = false;
104         }
105 
106         if (!info->has_user_indices) {
107                 /* Only resources can be directly mapped */
108                 panfrost_batch_read_rsrc(batch, rsrc, PIPE_SHADER_VERTEX);
109                 out = rsrc->image.data.bo->ptr.gpu + offset;
110 
111                 /* Check the cache */
112                 needs_indices = !panfrost_minmax_cache_get(rsrc->index_cache,
113                                                            draw->start,
114                                                            draw->count,
115                                                            min_index,
116                                                            max_index);
117         } else {
118                 /* Otherwise, we need to upload to transient memory */
119                 const uint8_t *ibuf8 = (const uint8_t *) info->index.user;
120                 struct panfrost_ptr T =
121                         pan_pool_alloc_aligned(&batch->pool.base,
122                                                draw->count *
123                                                info->index_size,
124                                                info->index_size);
125 
126                 memcpy(T.cpu, ibuf8 + offset, draw->count * info->index_size);
127                 out = T.gpu;
128         }
129 
130         if (needs_indices) {
131                 /* Fallback */
132                 u_vbuf_get_minmax_index(&ctx->base, info, draw, min_index, max_index);
133 
134                 if (!info->has_user_indices)
135                         panfrost_minmax_cache_add(rsrc->index_cache,
136                                                   draw->start, draw->count,
137                                                   *min_index, *max_index);
138         }
139 
140         return out;
141 }
142 
143 
144