1 /*
2 * Copyright © 2019 Intel Corporation
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 shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23 /**
24 * @file elk_debug_recompiles.c
25 */
26
27 #include <stdio.h>
28
29 #include "elk_compiler.h"
30
31 static bool
key_debug(const struct elk_compiler * c,void * log,const char * name,int a,int b)32 key_debug(const struct elk_compiler *c, void *log,
33 const char *name, int a, int b)
34 {
35 if (a != b) {
36 elk_shader_perf_log(c, log, " %s %d->%d\n", name, a, b);
37 return true;
38 }
39 return false;
40 }
41
42 static bool
key_debug_float(const struct elk_compiler * c,void * log,const char * name,float a,float b)43 key_debug_float(const struct elk_compiler *c, void *log,
44 const char *name, float a, float b)
45 {
46 if (a != b) {
47 elk_shader_perf_log(c, log, " %s %f->%f\n", name, a, b);
48 return true;
49 }
50 return false;
51 }
52
53 #define check(name, field) \
54 key_debug(c, log, name, old_key->field, key->field)
55 #define check_float(name, field) \
56 key_debug_float(c, log, name, old_key->field, key->field)
57
58 static bool
debug_sampler_recompile(const struct elk_compiler * c,void * log,const struct elk_sampler_prog_key_data * old_key,const struct elk_sampler_prog_key_data * key)59 debug_sampler_recompile(const struct elk_compiler *c, void *log,
60 const struct elk_sampler_prog_key_data *old_key,
61 const struct elk_sampler_prog_key_data *key)
62 {
63 bool found = false;
64
65 found |= check("gather channel quirk", gather_channel_quirk_mask);
66
67 for (unsigned i = 0; i < ELK_MAX_SAMPLERS; i++) {
68 found |= check("EXT_texture_swizzle or DEPTH_TEXTURE_MODE", swizzles[i]);
69 found |= check("textureGather workarounds", gfx6_gather_wa[i]);
70 }
71
72 for (unsigned i = 0; i < 3; i++) {
73 found |= check("GL_CLAMP enabled on any texture unit", gl_clamp_mask[i]);
74 }
75
76 return found;
77 }
78
79 static bool
debug_base_recompile(const struct elk_compiler * c,void * log,const struct elk_base_prog_key * old_key,const struct elk_base_prog_key * key)80 debug_base_recompile(const struct elk_compiler *c, void *log,
81 const struct elk_base_prog_key *old_key,
82 const struct elk_base_prog_key *key)
83 {
84 return debug_sampler_recompile(c, log, &old_key->tex, &key->tex);
85 }
86
87 static void
debug_vs_recompile(const struct elk_compiler * c,void * log,const struct elk_vs_prog_key * old_key,const struct elk_vs_prog_key * key)88 debug_vs_recompile(const struct elk_compiler *c, void *log,
89 const struct elk_vs_prog_key *old_key,
90 const struct elk_vs_prog_key *key)
91 {
92 bool found = debug_base_recompile(c, log, &old_key->base, &key->base);
93
94 for (unsigned i = 0; i < VERT_ATTRIB_MAX; i++) {
95 found |= check("vertex attrib w/a flags", gl_attrib_wa_flags[i]);
96 }
97
98 found |= check("legacy user clipping", nr_userclip_plane_consts);
99 found |= check("copy edgeflag", copy_edgeflag);
100 found |= check("pointcoord replace", point_coord_replace);
101 found |= check("vertex color clamping", clamp_vertex_color);
102
103 if (!found) {
104 elk_shader_perf_log(c, log, " something else\n");
105 }
106 }
107
108 static void
debug_tcs_recompile(const struct elk_compiler * c,void * log,const struct elk_tcs_prog_key * old_key,const struct elk_tcs_prog_key * key)109 debug_tcs_recompile(const struct elk_compiler *c, void *log,
110 const struct elk_tcs_prog_key *old_key,
111 const struct elk_tcs_prog_key *key)
112 {
113 bool found = debug_base_recompile(c, log, &old_key->base, &key->base);
114
115 found |= check("input vertices", input_vertices);
116 found |= check("outputs written", outputs_written);
117 found |= check("patch outputs written", patch_outputs_written);
118 found |= check("tes primitive mode", _tes_primitive_mode);
119 found |= check("quads and equal_spacing workaround", quads_workaround);
120
121 if (!found) {
122 elk_shader_perf_log(c, log, " something else\n");
123 }
124 }
125
126 static void
debug_tes_recompile(const struct elk_compiler * c,void * log,const struct elk_tes_prog_key * old_key,const struct elk_tes_prog_key * key)127 debug_tes_recompile(const struct elk_compiler *c, void *log,
128 const struct elk_tes_prog_key *old_key,
129 const struct elk_tes_prog_key *key)
130 {
131 bool found = debug_base_recompile(c, log, &old_key->base, &key->base);
132
133 found |= check("inputs read", inputs_read);
134 found |= check("patch inputs read", patch_inputs_read);
135
136 if (!found) {
137 elk_shader_perf_log(c, log, " something else\n");
138 }
139 }
140
141 static void
debug_gs_recompile(const struct elk_compiler * c,void * log,const struct elk_gs_prog_key * old_key,const struct elk_gs_prog_key * key)142 debug_gs_recompile(const struct elk_compiler *c, void *log,
143 const struct elk_gs_prog_key *old_key,
144 const struct elk_gs_prog_key *key)
145 {
146 bool found = debug_base_recompile(c, log, &old_key->base, &key->base);
147
148 if (!found) {
149 elk_shader_perf_log(c, log, " something else\n");
150 }
151 }
152
153 static void
debug_fs_recompile(const struct elk_compiler * c,void * log,const struct elk_wm_prog_key * old_key,const struct elk_wm_prog_key * key)154 debug_fs_recompile(const struct elk_compiler *c, void *log,
155 const struct elk_wm_prog_key *old_key,
156 const struct elk_wm_prog_key *key)
157 {
158 bool found = false;
159
160 found |= check("alphatest, computed depth, depth test, or depth write",
161 iz_lookup);
162 found |= check("depth statistics", stats_wm);
163 found |= check("flat shading", flat_shade);
164 found |= check("number of color buffers", nr_color_regions);
165 found |= check("MRT alpha test", alpha_test_replicate_alpha);
166 found |= check("alpha to coverage", alpha_to_coverage);
167 found |= check("fragment color clamping", clamp_fragment_color);
168 found |= check("per-sample interpolation", persample_interp);
169 found |= check("multisampled FBO", multisample_fbo);
170 found |= check("line smoothing", line_aa);
171 found |= check("force dual color blending", force_dual_color_blend);
172 found |= check("coherent fb fetch", coherent_fb_fetch);
173 found |= check("ignore sample mask out", ignore_sample_mask_out);
174
175 found |= check("input slots valid", input_slots_valid);
176 found |= check("mrt alpha test function", alpha_test_func);
177 found |= check("mrt alpha test reference value", alpha_test_ref);
178
179 found |= debug_base_recompile(c, log, &old_key->base, &key->base);
180
181 if (!found) {
182 elk_shader_perf_log(c, log, " something else\n");
183 }
184 }
185
186 static void
debug_cs_recompile(const struct elk_compiler * c,void * log,const struct elk_cs_prog_key * old_key,const struct elk_cs_prog_key * key)187 debug_cs_recompile(const struct elk_compiler *c, void *log,
188 const struct elk_cs_prog_key *old_key,
189 const struct elk_cs_prog_key *key)
190 {
191 bool found = debug_base_recompile(c, log, &old_key->base, &key->base);
192
193 if (!found) {
194 elk_shader_perf_log(c, log, " something else\n");
195 }
196 }
197
198 void
elk_debug_key_recompile(const struct elk_compiler * c,void * log,gl_shader_stage stage,const struct elk_base_prog_key * old_key,const struct elk_base_prog_key * key)199 elk_debug_key_recompile(const struct elk_compiler *c, void *log,
200 gl_shader_stage stage,
201 const struct elk_base_prog_key *old_key,
202 const struct elk_base_prog_key *key)
203 {
204 if (!old_key) {
205 elk_shader_perf_log(c, log, " No previous compile found...\n");
206 return;
207 }
208
209 switch (stage) {
210 case MESA_SHADER_VERTEX:
211 debug_vs_recompile(c, log, (const struct elk_vs_prog_key *)old_key,
212 (const struct elk_vs_prog_key *)key);
213 break;
214 case MESA_SHADER_TESS_CTRL:
215 debug_tcs_recompile(c, log, (const struct elk_tcs_prog_key *)old_key,
216 (const struct elk_tcs_prog_key *)key);
217 break;
218 case MESA_SHADER_TESS_EVAL:
219 debug_tes_recompile(c, log, (const struct elk_tes_prog_key *)old_key,
220 (const struct elk_tes_prog_key *)key);
221 break;
222 case MESA_SHADER_GEOMETRY:
223 debug_gs_recompile(c, log, (const struct elk_gs_prog_key *)old_key,
224 (const struct elk_gs_prog_key *)key);
225 break;
226 case MESA_SHADER_FRAGMENT:
227 debug_fs_recompile(c, log, (const struct elk_wm_prog_key *)old_key,
228 (const struct elk_wm_prog_key *)key);
229 break;
230 case MESA_SHADER_COMPUTE:
231 debug_cs_recompile(c, log, (const struct elk_cs_prog_key *)old_key,
232 (const struct elk_cs_prog_key *)key);
233 break;
234 default:
235 break;
236 }
237 }
238