Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/panfrost/lib/pan_shader.c
4560 views
1
/*
2
* Copyright (C) 2018 Alyssa Rosenzweig
3
* Copyright (C) 2019-2021 Collabora, Ltd.
4
*
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
* and/or sell copies of the Software, and to permit persons to whom the
10
* Software is furnished to do so, subject to the following conditions:
11
*
12
* The above copyright notice and this permission notice (including the next
13
* paragraph) shall be included in all copies or substantial portions of the
14
* Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
* SOFTWARE.
23
*/
24
25
#include "pan_device.h"
26
#include "pan_shader.h"
27
28
#include "panfrost/midgard/midgard_compile.h"
29
#include "panfrost/bifrost/bifrost_compile.h"
30
31
const nir_shader_compiler_options *
32
pan_shader_get_compiler_options(const struct panfrost_device *dev)
33
{
34
if (pan_is_bifrost(dev))
35
return &bifrost_nir_options;
36
37
return &midgard_nir_options;
38
}
39
40
static enum pipe_format
41
varying_format(nir_alu_type t, unsigned ncomps)
42
{
43
#define VARYING_FORMAT(ntype, nsz, ptype, psz) \
44
{ \
45
.type = nir_type_ ## ntype ## nsz, \
46
.formats = { \
47
PIPE_FORMAT_R ## psz ## _ ## ptype, \
48
PIPE_FORMAT_R ## psz ## G ## psz ## _ ## ptype, \
49
PIPE_FORMAT_R ## psz ## G ## psz ## B ## psz ## _ ## ptype, \
50
PIPE_FORMAT_R ## psz ## G ## psz ## B ## psz ## A ## psz ## _ ## ptype, \
51
} \
52
}
53
54
static const struct {
55
nir_alu_type type;
56
enum pipe_format formats[4];
57
} conv[] = {
58
VARYING_FORMAT(float, 32, FLOAT, 32),
59
VARYING_FORMAT(int, 32, SINT, 32),
60
VARYING_FORMAT(uint, 32, UINT, 32),
61
VARYING_FORMAT(float, 16, FLOAT, 16),
62
VARYING_FORMAT(int, 16, SINT, 16),
63
VARYING_FORMAT(uint, 16, UINT, 16),
64
VARYING_FORMAT(int, 8, SINT, 8),
65
VARYING_FORMAT(uint, 8, UINT, 8),
66
VARYING_FORMAT(bool, 32, UINT, 32),
67
VARYING_FORMAT(bool, 16, UINT, 16),
68
VARYING_FORMAT(bool, 8, UINT, 8),
69
VARYING_FORMAT(bool, 1, UINT, 8),
70
};
71
#undef VARYING_FORMAT
72
73
assert(ncomps > 0 && ncomps <= ARRAY_SIZE(conv[0].formats));
74
75
for (unsigned i = 0; i < ARRAY_SIZE(conv); i++) {
76
if (conv[i].type == t)
77
return conv[i].formats[ncomps - 1];
78
}
79
80
return PIPE_FORMAT_NONE;
81
}
82
83
static void
84
collect_varyings(nir_shader *s, nir_variable_mode varying_mode,
85
struct pan_shader_varying *varyings,
86
unsigned *varying_count, bool is_bifrost)
87
{
88
*varying_count = 0;
89
90
unsigned comps[MAX_VARYING] = { 0 };
91
92
nir_foreach_variable_with_modes(var, s, varying_mode) {
93
unsigned loc = var->data.driver_location;
94
const struct glsl_type *column =
95
glsl_without_array_or_matrix(var->type);
96
unsigned chan = glsl_get_components(column);
97
98
/* If we have a fractional location added, we need to increase the size
99
* so it will fit, i.e. a vec3 in YZW requires us to allocate a vec4.
100
* We could do better but this is an edge case as it is, normally
101
* packed varyings will be aligned.
102
*/
103
chan += var->data.location_frac;
104
comps[loc] = MAX2(comps[loc], chan);
105
}
106
107
nir_foreach_variable_with_modes(var, s, varying_mode) {
108
unsigned loc = var->data.driver_location;
109
unsigned sz = glsl_count_attribute_slots(var->type, FALSE);
110
const struct glsl_type *column =
111
glsl_without_array_or_matrix(var->type);
112
enum glsl_base_type base_type = glsl_get_base_type(column);
113
unsigned chan = comps[loc];
114
115
nir_alu_type type = nir_get_nir_type_for_glsl_base_type(base_type);
116
type = nir_alu_type_get_base_type(type);
117
118
/* Can't do type conversion since GLSL IR packs in funny ways */
119
if (is_bifrost && var->data.interpolation == INTERP_MODE_FLAT)
120
type = nir_type_uint;
121
122
/* Demote to fp16 where possible. int16 varyings are TODO as the hw
123
* will saturate instead of wrap which is not conformant, so we need to
124
* insert i2i16/u2u16 instructions before the st_vary_32i/32u to get
125
* the intended behaviour.
126
*/
127
if (type == nir_type_float &&
128
(var->data.precision == GLSL_PRECISION_MEDIUM ||
129
var->data.precision == GLSL_PRECISION_LOW) &&
130
!s->info.has_transform_feedback_varyings) {
131
type |= 16;
132
} else {
133
type |= 32;
134
}
135
136
enum pipe_format format = varying_format(type, chan);
137
assert(format != PIPE_FORMAT_NONE);
138
139
for (int c = 0; c < sz; ++c) {
140
varyings[loc + c].location = var->data.location + c;
141
varyings[loc + c].format = format;
142
}
143
144
*varying_count = MAX2(*varying_count, loc + sz);
145
}
146
}
147
148
static enum mali_bifrost_register_file_format
149
bifrost_blend_type_from_nir(nir_alu_type nir_type)
150
{
151
switch(nir_type) {
152
case 0: /* Render target not in use */
153
return 0;
154
case nir_type_float16:
155
return MALI_BIFROST_REGISTER_FILE_FORMAT_F16;
156
case nir_type_float32:
157
return MALI_BIFROST_REGISTER_FILE_FORMAT_F32;
158
case nir_type_int32:
159
return MALI_BIFROST_REGISTER_FILE_FORMAT_I32;
160
case nir_type_uint32:
161
return MALI_BIFROST_REGISTER_FILE_FORMAT_U32;
162
case nir_type_int16:
163
return MALI_BIFROST_REGISTER_FILE_FORMAT_I16;
164
case nir_type_uint16:
165
return MALI_BIFROST_REGISTER_FILE_FORMAT_U16;
166
default:
167
unreachable("Unsupported blend shader type for NIR alu type");
168
return 0;
169
}
170
}
171
172
void
173
pan_shader_compile(const struct panfrost_device *dev,
174
nir_shader *s,
175
const struct panfrost_compile_inputs *inputs,
176
struct util_dynarray *binary,
177
struct pan_shader_info *info)
178
{
179
memset(info, 0, sizeof(*info));
180
181
if (pan_is_bifrost(dev))
182
bifrost_compile_shader_nir(s, inputs, binary, info);
183
else
184
midgard_compile_shader_nir(s, inputs, binary, info);
185
186
info->stage = s->info.stage;
187
info->contains_barrier = s->info.uses_memory_barrier ||
188
s->info.uses_control_barrier;
189
info->separable = s->info.separate_shader;
190
191
switch (info->stage) {
192
case MESA_SHADER_VERTEX:
193
info->attribute_count = util_bitcount64(s->info.inputs_read);
194
195
bool vertex_id = BITSET_TEST(s->info.system_values_read,
196
SYSTEM_VALUE_VERTEX_ID_ZERO_BASE);
197
if (vertex_id && !pan_is_bifrost(dev))
198
info->attribute_count = MAX2(info->attribute_count, PAN_VERTEX_ID + 1);
199
200
bool instance_id = BITSET_TEST(s->info.system_values_read,
201
SYSTEM_VALUE_INSTANCE_ID);
202
if (instance_id && !pan_is_bifrost(dev))
203
info->attribute_count = MAX2(info->attribute_count, PAN_INSTANCE_ID + 1);
204
205
info->vs.writes_point_size =
206
s->info.outputs_written & (1 << VARYING_SLOT_PSIZ);
207
collect_varyings(s, nir_var_shader_out, info->varyings.output,
208
&info->varyings.output_count, pan_is_bifrost(dev));
209
break;
210
case MESA_SHADER_FRAGMENT:
211
if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
212
info->fs.writes_depth = true;
213
if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL))
214
info->fs.writes_stencil = true;
215
if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK))
216
info->fs.writes_coverage = true;
217
218
info->fs.outputs_read = s->info.outputs_read >> FRAG_RESULT_DATA0;
219
info->fs.outputs_written = s->info.outputs_written >> FRAG_RESULT_DATA0;
220
221
/* EXT_shader_framebuffer_fetch requires per-sample */
222
info->fs.sample_shading = s->info.fs.uses_sample_shading ||
223
info->fs.outputs_read;
224
225
info->fs.can_discard = s->info.fs.uses_discard;
226
info->fs.helper_invocations = s->info.fs.needs_quad_helper_invocations;
227
info->fs.early_fragment_tests = s->info.fs.early_fragment_tests;
228
229
/* List of reasons we need to execute frag shaders when things
230
* are masked off */
231
232
info->fs.sidefx = s->info.writes_memory ||
233
s->info.fs.uses_discard ||
234
s->info.fs.uses_demote;
235
236
/* With suitable ZSA/blend, is early-z possible? */
237
info->fs.can_early_z =
238
!info->fs.sidefx &&
239
!info->fs.writes_depth &&
240
!info->fs.writes_stencil &&
241
!info->fs.writes_coverage;
242
243
/* Similiarly with suitable state, is FPK possible? */
244
info->fs.can_fpk =
245
!info->fs.writes_depth &&
246
!info->fs.writes_stencil &&
247
!info->fs.writes_coverage &&
248
!info->fs.can_discard &&
249
!info->fs.outputs_read;
250
251
info->fs.reads_frag_coord =
252
(s->info.inputs_read & (1 << VARYING_SLOT_POS)) ||
253
BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_FRAG_COORD);
254
info->fs.reads_point_coord =
255
s->info.inputs_read & (1 << VARYING_SLOT_PNTC);
256
info->fs.reads_face =
257
(s->info.inputs_read & (1 << VARYING_SLOT_FACE)) ||
258
BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_FRONT_FACE);
259
info->fs.reads_sample_id =
260
BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_SAMPLE_ID);
261
info->fs.reads_sample_pos =
262
BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_SAMPLE_POS);
263
info->fs.reads_sample_mask_in =
264
BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_SAMPLE_MASK_IN);
265
info->fs.reads_helper_invocation =
266
BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_HELPER_INVOCATION);
267
collect_varyings(s, nir_var_shader_in, info->varyings.input,
268
&info->varyings.input_count, pan_is_bifrost(dev));
269
break;
270
case MESA_SHADER_COMPUTE:
271
info->wls_size = s->info.shared_size;
272
break;
273
default:
274
unreachable("Unknown shader state");
275
}
276
277
info->outputs_written = s->info.outputs_written;
278
279
/* Sysvals have dedicated UBO */
280
if (info->sysvals.sysval_count)
281
info->ubo_count = MAX2(s->info.num_ubos + 1, inputs->sysval_ubo + 1);
282
else
283
info->ubo_count = s->info.num_ubos;
284
285
info->attribute_count += util_last_bit(s->info.images_used);
286
info->writes_global = s->info.writes_memory;
287
288
info->sampler_count = info->texture_count = BITSET_LAST_BIT(s->info.textures_used);
289
290
/* This is "redundant" information, but is needed in a draw-time hot path */
291
if (pan_is_bifrost(dev)) {
292
for (unsigned i = 0; i < ARRAY_SIZE(info->bifrost.blend); ++i) {
293
info->bifrost.blend[i].format =
294
bifrost_blend_type_from_nir(info->bifrost.blend[i].type);
295
}
296
}
297
}
298
299