Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/panfrost/lib/pan_shader.h
4560 views
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 FROM,
20
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
* SOFTWARE.
22
*
23
*/
24
25
#ifndef __PAN_SHADER_H__
26
#define __PAN_SHADER_H__
27
28
#include "compiler/nir/nir.h"
29
#include "panfrost/util/pan_ir.h"
30
31
#include "pan_device.h"
32
#include "midgard_pack.h"
33
34
struct panfrost_device;
35
36
const nir_shader_compiler_options *
37
pan_shader_get_compiler_options(const struct panfrost_device *dev);
38
39
void
40
pan_shader_compile(const struct panfrost_device *dev,
41
nir_shader *nir,
42
const struct panfrost_compile_inputs *inputs,
43
struct util_dynarray *binary,
44
struct pan_shader_info *info);
45
46
static inline void
47
pan_shader_prepare_midgard_rsd(const struct pan_shader_info *info,
48
struct MALI_RENDERER_STATE *rsd)
49
{
50
assert((info->push.count & 3) == 0);
51
52
rsd->properties.midgard.uniform_count = info->push.count / 4;
53
rsd->properties.midgard.shader_has_side_effects = info->writes_global;
54
rsd->properties.midgard.fp_mode = MALI_FP_MODE_GL_INF_NAN_ALLOWED;
55
56
/* For fragment shaders, work register count, early-z, reads at draw-time */
57
58
if (info->stage != MESA_SHADER_FRAGMENT) {
59
rsd->properties.midgard.work_register_count = info->work_reg_count;
60
} else {
61
rsd->properties.midgard.shader_reads_tilebuffer =
62
info->fs.outputs_read;
63
64
/* However, forcing early-z in the shader overrides draw-time */
65
rsd->properties.midgard.force_early_z =
66
info->fs.early_fragment_tests;
67
}
68
}
69
70
/* Classify a shader into the following pixel kill categories:
71
*
72
* (force early, strong early): no side effects/depth/stencil/coverage writes (force)
73
* (weak early, weak early): no side effects/depth/stencil/coverage writes
74
* (weak early, force late): no side effects/depth/stencil writes
75
* (force late, weak early): side effects but no depth/stencil/coverage writes
76
* (force late, force early): only run for side effects
77
* (force late, force late): depth/stencil writes
78
*
79
* Note that discard is considered a coverage write. TODO: what about
80
* alpha-to-coverage?
81
* */
82
83
#define SET_PIXEL_KILL(kill, update) do { \
84
rsd->properties.bifrost.pixel_kill_operation = MALI_PIXEL_KILL_## kill; \
85
rsd->properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_## update; \
86
} while(0)
87
88
static inline void
89
pan_shader_classify_pixel_kill_coverage(const struct pan_shader_info *info,
90
struct MALI_RENDERER_STATE *rsd)
91
{
92
bool force_early = info->fs.early_fragment_tests;
93
bool sidefx = info->writes_global;
94
bool coverage = info->fs.writes_coverage || info->fs.can_discard;
95
bool depth = info->fs.writes_depth;
96
bool stencil = info->fs.writes_stencil;
97
98
rsd->properties.bifrost.shader_modifies_coverage = coverage;
99
100
if (force_early)
101
SET_PIXEL_KILL(FORCE_EARLY, STRONG_EARLY);
102
else if (depth || stencil || (sidefx && coverage))
103
SET_PIXEL_KILL(FORCE_LATE, FORCE_LATE);
104
else if (sidefx)
105
SET_PIXEL_KILL(FORCE_LATE, WEAK_EARLY);
106
else if (coverage)
107
SET_PIXEL_KILL(WEAK_EARLY, FORCE_LATE);
108
else
109
SET_PIXEL_KILL(WEAK_EARLY, WEAK_EARLY);
110
}
111
112
#undef SET_PIXEL_KILL
113
114
static inline void
115
pan_shader_prepare_bifrost_rsd(const struct panfrost_device *dev,
116
const struct pan_shader_info *info,
117
struct MALI_RENDERER_STATE *rsd)
118
{
119
unsigned fau_count = DIV_ROUND_UP(info->push.count, 2);
120
rsd->preload.uniform_count = fau_count;
121
122
if (dev->arch == 7) {
123
rsd->properties.bifrost.shader_register_allocation =
124
(info->work_reg_count <= 32) ?
125
MALI_SHADER_REGISTER_ALLOCATION_32_PER_THREAD :
126
MALI_SHADER_REGISTER_ALLOCATION_64_PER_THREAD;
127
}
128
129
switch (info->stage) {
130
case MESA_SHADER_VERTEX:
131
rsd->preload.vertex.vertex_id = true;
132
rsd->preload.vertex.instance_id = true;
133
break;
134
135
case MESA_SHADER_FRAGMENT:
136
pan_shader_classify_pixel_kill_coverage(info, rsd);
137
138
if (dev->arch > 6) {
139
rsd->properties.bifrost.shader_wait_dependency_6 = info->bifrost.wait_6;
140
rsd->properties.bifrost.shader_wait_dependency_7 = info->bifrost.wait_7;
141
}
142
143
rsd->properties.bifrost.allow_forward_pixel_to_be_killed =
144
!info->fs.sidefx;
145
146
rsd->preload.fragment.fragment_position = info->fs.reads_frag_coord;
147
rsd->preload.fragment.coverage = true;
148
rsd->preload.fragment.primitive_flags = info->fs.reads_face;
149
150
/* Contains sample ID and sample mask. Sample position and
151
* helper invocation are expressed in terms of the above, so
152
* preload for those too */
153
rsd->preload.fragment.sample_mask_id =
154
info->fs.reads_sample_id |
155
info->fs.reads_sample_pos |
156
info->fs.reads_sample_mask_in |
157
info->fs.reads_helper_invocation |
158
info->fs.sample_shading;
159
160
rsd->message_preload_1 = info->bifrost.messages[0];
161
rsd->message_preload_2 = info->bifrost.messages[1];
162
break;
163
164
case MESA_SHADER_COMPUTE:
165
rsd->preload.compute.local_invocation_xy = true;
166
rsd->preload.compute.local_invocation_z = true;
167
rsd->preload.compute.work_group_x = true;
168
rsd->preload.compute.work_group_y = true;
169
rsd->preload.compute.work_group_z = true;
170
rsd->preload.compute.global_invocation_x = true;
171
rsd->preload.compute.global_invocation_y = true;
172
rsd->preload.compute.global_invocation_z = true;
173
break;
174
175
default:
176
unreachable("TODO");
177
}
178
}
179
180
static inline void
181
pan_shader_prepare_rsd(const struct panfrost_device *dev,
182
const struct pan_shader_info *shader_info,
183
mali_ptr shader_ptr,
184
struct MALI_RENDERER_STATE *rsd)
185
{
186
if (!pan_is_bifrost(dev))
187
shader_ptr |= shader_info->midgard.first_tag;
188
189
rsd->shader.shader = shader_ptr;
190
rsd->shader.attribute_count = shader_info->attribute_count;
191
rsd->shader.varying_count = shader_info->varyings.input_count +
192
shader_info->varyings.output_count;
193
rsd->shader.texture_count = shader_info->texture_count;
194
rsd->shader.sampler_count = shader_info->sampler_count;
195
rsd->properties.shader_contains_barrier = shader_info->contains_barrier;
196
rsd->properties.uniform_buffer_count = shader_info->ubo_count;
197
198
if (shader_info->stage == MESA_SHADER_FRAGMENT) {
199
rsd->properties.shader_contains_barrier |=
200
shader_info->fs.helper_invocations;
201
rsd->properties.stencil_from_shader =
202
shader_info->fs.writes_stencil;
203
rsd->properties.depth_source =
204
shader_info->fs.writes_depth ?
205
MALI_DEPTH_SOURCE_SHADER :
206
MALI_DEPTH_SOURCE_FIXED_FUNCTION;
207
208
/* This also needs to be set if the API forces per-sample
209
* shading, but that'll just got ORed in */
210
rsd->multisample_misc.evaluate_per_sample =
211
shader_info->fs.sample_shading;
212
}
213
214
if (pan_is_bifrost(dev))
215
pan_shader_prepare_bifrost_rsd(dev, shader_info, rsd);
216
else
217
pan_shader_prepare_midgard_rsd(shader_info, rsd);
218
}
219
220
#endif
221
222