panvk_varyings.h revision 7ec681f3
1/*
2 * Copyright (C) 2021 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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#ifndef PANVK_VARYINGS_H
25#define PANVK_VARYINGS_H
26
27#include "util/bitset.h"
28#include "util/format/u_format.h"
29
30#include "compiler/shader_enums.h"
31#include "panfrost-job.h"
32
33#include "pan_pool.h"
34
35struct pan_pool;
36struct panvk_device;
37
38enum panvk_varying_buf_id {
39   PANVK_VARY_BUF_GENERAL,
40   PANVK_VARY_BUF_POSITION,
41   PANVK_VARY_BUF_PSIZ,
42   PANVK_VARY_BUF_PNTCOORD,
43   PANVK_VARY_BUF_FRAGCOORD,
44
45   /* Keep last */
46   PANVK_VARY_BUF_MAX,
47};
48
49struct panvk_varying {
50   unsigned buf;
51   unsigned offset;
52   enum pipe_format format;
53};
54
55struct panvk_varying_buf {
56   mali_ptr address;
57   void *cpu;
58   unsigned stride;
59   unsigned size;
60};
61
62struct panvk_varyings_info {
63   struct panvk_varying varying[VARYING_SLOT_MAX];
64   BITSET_DECLARE(active, VARYING_SLOT_MAX);
65   struct panvk_varying_buf buf[VARYING_SLOT_MAX];
66   struct {
67      unsigned count;
68      gl_varying_slot loc[VARYING_SLOT_MAX];
69   } stage[MESA_SHADER_STAGES];
70   unsigned buf_mask;
71};
72
73static inline unsigned
74panvk_varying_buf_index(const struct panvk_varyings_info *varyings,
75                        enum panvk_varying_buf_id b)
76{
77   return util_bitcount(varyings->buf_mask & BITFIELD_MASK(b));
78}
79
80static inline enum panvk_varying_buf_id
81panvk_varying_buf_id(bool fs, gl_varying_slot loc)
82{
83   switch (loc) {
84   case VARYING_SLOT_POS:
85      return fs ? PANVK_VARY_BUF_FRAGCOORD : PANVK_VARY_BUF_POSITION;
86   case VARYING_SLOT_PSIZ:
87      return PANVK_VARY_BUF_PSIZ;
88   case VARYING_SLOT_PNTC:
89      return PANVK_VARY_BUF_PNTCOORD;
90   default:
91      return PANVK_VARY_BUF_GENERAL;
92   }
93}
94
95static inline bool
96panvk_varying_is_builtin(gl_shader_stage stage, gl_varying_slot loc)
97{
98   bool fs = stage == MESA_SHADER_FRAGMENT;
99
100   switch (loc) {
101   case VARYING_SLOT_POS:
102   case VARYING_SLOT_PNTC:
103      return fs;
104   default:
105      return false;
106   }
107}
108
109#if defined(PAN_ARCH) && PAN_ARCH <= 5
110static inline enum mali_attribute_special
111panvk_varying_special_buf_id(enum panvk_varying_buf_id buf_id)
112{
113   switch (buf_id) {
114   case PANVK_VARY_BUF_PNTCOORD:
115      return MALI_ATTRIBUTE_SPECIAL_POINT_COORD;
116   case PANVK_VARY_BUF_FRAGCOORD:
117      return MALI_ATTRIBUTE_SPECIAL_FRAG_COORD;
118   default:
119      return 0;
120   }
121}
122#endif
123
124static inline unsigned
125panvk_varying_size(const struct panvk_varyings_info *varyings,
126                   gl_varying_slot loc)
127{
128   switch (loc) {
129   case VARYING_SLOT_POS:
130      return sizeof(float) * 4;
131   case VARYING_SLOT_PSIZ:
132      return sizeof(uint16_t);
133   default:
134      return util_format_get_blocksize(varyings->varying[loc].format);
135   }
136}
137
138#ifdef PAN_ARCH
139static inline unsigned
140panvk_varyings_buf_count(struct panvk_varyings_info *varyings)
141{
142   return util_bitcount(varyings->buf_mask) + (PAN_ARCH >= 6 ? 1 : 0);
143}
144#endif
145
146static inline void
147panvk_varyings_alloc(struct panvk_varyings_info *varyings,
148                     struct pan_pool *varying_mem_pool,
149                     unsigned vertex_count)
150{
151   for (unsigned i = 0; i < PANVK_VARY_BUF_MAX; i++) {
152      if (!(varyings->buf_mask & (1 << i))) continue;
153
154      unsigned buf_idx = panvk_varying_buf_index(varyings, i);
155      unsigned size = varyings->buf[buf_idx].stride * vertex_count;
156      if (!size)
157         continue;
158
159      struct panfrost_ptr ptr =
160         pan_pool_alloc_aligned(varying_mem_pool, size, 64);
161
162      varyings->buf[buf_idx].size = size;
163      varyings->buf[buf_idx].address = ptr.gpu;
164      varyings->buf[buf_idx].cpu = ptr.cpu;
165   }
166}
167
168#endif
169