clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name opt_dead_builtin_varyings.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/third_party/rust/glslopt -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/root/firefox-clang/third_party/rust/glslopt -resource-dir /usr/lib/llvm-21/lib/clang/21 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I glsl-optimizer/include -I glsl-optimizer/src/mesa -I glsl-optimizer/src/mapi -I glsl-optimizer/src/compiler -I glsl-optimizer/src/compiler/glsl -I glsl-optimizer/src/gallium/auxiliary -I glsl-optimizer/src/gallium/include -I glsl-optimizer/src -I glsl-optimizer/src/util -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -D MOZILLA_CONFIG_H -D __STDC_FORMAT_MACROS -D _GNU_SOURCE -D HAVE_ENDIAN_H -D HAVE_PTHREAD -D HAVE_TIMESPEC_GET -D MOZ_INCLUDE_MOZALLOC_H -D mozilla_throw_gcc_h -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-06-30-093548-1913035-1 -x c++ glsl-optimizer/src/compiler/glsl/opt_dead_builtin_varyings.cpp
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 | |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | |
| 32 | |
| 33 | |
| 34 | |
| 35 | |
| 36 | |
| 37 | |
| 38 | |
| 39 | |
| 40 | |
| 41 | |
| 42 | |
| 43 | |
| 44 | |
| 45 | |
| 46 | |
| 47 | |
| 48 | |
| 49 | #include "ir.h" |
| 50 | #include "ir_rvalue_visitor.h" |
| 51 | #include "ir_optimization.h" |
| 52 | #include "ir_print_visitor.h" |
| 53 | #include "compiler/glsl_types.h" |
| 54 | #include "link_varyings.h" |
| 55 | #include "main/mtypes.h" |
| 56 | #include "util/u_string.h" |
| 57 | |
| 58 | namespace { |
| 59 | |
| 60 | |
| 61 | |
| 62 | |
| 63 | class varying_info_visitor : public ir_hierarchical_visitor { |
| 64 | public: |
| 65 | |
| 66 | varying_info_visitor(ir_variable_mode mode, bool find_frag_outputs = false) |
| 67 | : lower_texcoord_array(true), |
| 6 | | The value 1 is assigned to 'producer_info.lower_texcoord_array', which participates in a condition later | |
|
| 68 | texcoord_array(NULL), |
| 69 | texcoord_usage(0), |
| 70 | find_frag_outputs(find_frag_outputs), |
| 71 | lower_fragdata_array(true), |
| 72 | fragdata_array(NULL), |
| 73 | fragdata_usage(0), |
| 74 | color_usage(0), |
| 75 | tfeedback_color_usage(0), |
| 76 | fog(NULL), |
| 77 | has_fog(false), |
| 78 | tfeedback_has_fog(false), |
| 79 | mode(mode) |
| 80 | { |
| 81 | memset(color, 0, sizeof(color)); |
| 82 | memset(backcolor, 0, sizeof(backcolor)); |
| 83 | } |
| 84 | |
| 85 | virtual ir_visitor_status visit_enter(ir_dereference_array *ir) |
| 86 | { |
| 87 | ir_variable *var = ir->variable_referenced(); |
| 88 | |
| 89 | if (!var || var->data.mode != this->mode || !var->type->is_array() || |
| 90 | !is_gl_identifier(var->name)) |
| 91 | return visit_continue; |
| 92 | |
| 93 | |
| 94 | |
| 95 | |
| 96 | if (this->find_frag_outputs && strcmp(var->name, "gl_FragData") == 0) { |
| 97 | this->fragdata_array = var; |
| 98 | |
| 99 | ir_constant *index = ir->array_index->as_constant(); |
| 100 | if (index == NULL) { |
| 101 | |
| 102 | this->fragdata_usage |= (1 << var->type->array_size()) - 1; |
| 103 | this->lower_fragdata_array = false; |
| 104 | } |
| 105 | else { |
| 106 | this->fragdata_usage |= 1 << index->get_uint_component(0); |
| 107 | |
| 108 | |
| 109 | |
| 110 | |
| 111 | |
| 112 | if (var->type->gl_type != GL_FLOAT && |
| 113 | var->type->gl_type != GL_FLOAT_VEC2 && |
| 114 | var->type->gl_type != GL_FLOAT_VEC3 && |
| 115 | var->type->gl_type != GL_FLOAT_VEC4) |
| 116 | this->lower_fragdata_array = false; |
| 117 | } |
| 118 | |
| 119 | |
| 120 | return visit_continue_with_parent; |
| 121 | } |
| 122 | |
| 123 | if (!this->find_frag_outputs && var->data.location == VARYING_SLOT_TEX0) { |
| 124 | this->texcoord_array = var; |
| 125 | |
| 126 | ir_constant *index = ir->array_index->as_constant(); |
| 127 | if (index == NULL) { |
| 128 | |
| 129 | |
| 130 | this->texcoord_usage |= (1 << var->type->array_size()) - 1; |
| 131 | this->lower_texcoord_array = false; |
| 132 | } |
| 133 | else { |
| 134 | this->texcoord_usage |= 1 << index->get_uint_component(0); |
| 135 | } |
| 136 | |
| 137 | |
| 138 | return visit_continue_with_parent; |
| 139 | } |
| 140 | |
| 141 | return visit_continue; |
| 142 | } |
| 143 | |
| 144 | virtual ir_visitor_status visit(ir_dereference_variable *ir) |
| 145 | { |
| 146 | ir_variable *var = ir->variable_referenced(); |
| 147 | |
| 148 | if (var->data.mode != this->mode || !var->type->is_array()) |
| 149 | return visit_continue; |
| 150 | |
| 151 | if (this->find_frag_outputs && var->data.location == FRAG_RESULT_DATA0 && |
| 152 | var->data.index == 0) { |
| 153 | |
| 154 | this->fragdata_usage |= (1 << var->type->array_size()) - 1; |
| 155 | this->lower_fragdata_array = false; |
| 156 | return visit_continue; |
| 157 | } |
| 158 | |
| 159 | if (!this->find_frag_outputs && var->data.location == VARYING_SLOT_TEX0) { |
| 160 | |
| 161 | |
| 162 | |
| 163 | this->texcoord_usage |= (1 << var->type->array_size()) - 1; |
| 164 | this->lower_texcoord_array = false; |
| 165 | } |
| 166 | return visit_continue; |
| 167 | } |
| 168 | |
| 169 | virtual ir_visitor_status visit(ir_variable *var) |
| 170 | { |
| 171 | if (var->data.mode != this->mode) |
| 172 | return visit_continue; |
| 173 | |
| 174 | |
| 175 | if (this->find_frag_outputs) |
| 176 | return visit_continue; |
| 177 | |
| 178 | |
| 179 | switch (var->data.location) { |
| 180 | case VARYING_SLOT_COL0: |
| 181 | this->color[0] = var; |
| 182 | this->color_usage |= 1; |
| 183 | break; |
| 184 | case VARYING_SLOT_COL1: |
| 185 | this->color[1] = var; |
| 186 | this->color_usage |= 2; |
| 187 | break; |
| 188 | case VARYING_SLOT_BFC0: |
| 189 | this->backcolor[0] = var; |
| 190 | this->color_usage |= 1; |
| 191 | break; |
| 192 | case VARYING_SLOT_BFC1: |
| 193 | this->backcolor[1] = var; |
| 194 | this->color_usage |= 2; |
| 195 | break; |
| 196 | case VARYING_SLOT_FOGC: |
| 197 | this->fog = var; |
| 198 | this->has_fog = true; |
| 199 | break; |
| 200 | } |
| 201 | |
| 202 | return visit_continue; |
| 203 | } |
| 204 | |
| 205 | void get(exec_list *ir, |
| 206 | unsigned num_tfeedback_decls, |
| 207 | tfeedback_decl *tfeedback_decls) |
| 208 | { |
| 209 | |
| 210 | for (unsigned i = 0; i < num_tfeedback_decls; i++) { |
| 211 | if (!tfeedback_decls[i].is_varying()) |
| 212 | continue; |
| 213 | |
| 214 | unsigned location = tfeedback_decls[i].get_location(); |
| 215 | |
| 216 | switch (location) { |
| 217 | case VARYING_SLOT_COL0: |
| 218 | case VARYING_SLOT_BFC0: |
| 219 | this->tfeedback_color_usage |= 1; |
| 220 | break; |
| 221 | case VARYING_SLOT_COL1: |
| 222 | case VARYING_SLOT_BFC1: |
| 223 | this->tfeedback_color_usage |= 2; |
| 224 | break; |
| 225 | case VARYING_SLOT_FOGC: |
| 226 | this->tfeedback_has_fog = true; |
| 227 | break; |
| 228 | default: |
| 229 | if (location >= VARYING_SLOT_TEX0 && |
| 230 | location <= VARYING_SLOT_TEX7) { |
| 231 | this->lower_texcoord_array = false; |
| 232 | } |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | |
| 237 | visit_list_elements(this, ir); |
| 238 | |
| 239 | if (!this->texcoord_array) { |
| 240 | this->lower_texcoord_array = false; |
| 241 | } |
| 242 | if (!this->fragdata_array) { |
| 243 | this->lower_fragdata_array = false; |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | bool lower_texcoord_array; |
| 248 | ir_variable *texcoord_array; |
| 249 | unsigned texcoord_usage; |
| 250 | |
| 251 | bool find_frag_outputs; |
| 252 | bool lower_fragdata_array; |
| 253 | ir_variable *fragdata_array; |
| 254 | unsigned fragdata_usage; |
| 255 | |
| 256 | ir_variable *color[2]; |
| 257 | ir_variable *backcolor[2]; |
| 258 | unsigned color_usage; |
| 259 | unsigned tfeedback_color_usage; |
| 260 | |
| 261 | ir_variable *fog; |
| 262 | bool has_fog; |
| 263 | bool tfeedback_has_fog; |
| 264 | |
| 265 | ir_variable_mode mode; |
| 266 | }; |
| 267 | |
| 268 | |
| 269 | |
| 270 | |
| 271 | |
| 272 | |
| 273 | |
| 274 | |
| 275 | |
| 276 | class replace_varyings_visitor : public ir_rvalue_visitor { |
| 277 | public: |
| 278 | replace_varyings_visitor(struct gl_linked_shader *sha, |
| 279 | const varying_info_visitor *info, |
| 280 | unsigned external_texcoord_usage, |
| 281 | unsigned external_color_usage, |
| 282 | bool external_has_fog) |
| 283 | : shader(sha), info(info), new_fog(NULL) |
| 12 | | Null pointer value stored to field 'shader' | |
|
| 284 | { |
| 285 | void *const ctx = shader->ir; |
| 13 | | Access to field 'ir' results in a dereference of a null pointer (loaded from field 'shader') |
|
| 286 | |
| 287 | memset(this->new_fragdata, 0, sizeof(this->new_fragdata)); |
| 288 | memset(this->new_texcoord, 0, sizeof(this->new_texcoord)); |
| 289 | memset(this->new_color, 0, sizeof(this->new_color)); |
| 290 | memset(this->new_backcolor, 0, sizeof(this->new_backcolor)); |
| 291 | |
| 292 | const char *mode_str = |
| 293 | info->mode == ir_var_shader_in ? "in" : "out"; |
| 294 | |
| 295 | |
| 296 | |
| 297 | |
| 298 | |
| 299 | |
| 300 | |
| 301 | if (info->lower_texcoord_array) { |
| 302 | prepare_array(shader->ir, this->new_texcoord, |
| 303 | ARRAY_SIZE(this->new_texcoord), |
| 304 | VARYING_SLOT_TEX0, "TexCoord", mode_str, |
| 305 | info->texcoord_usage, external_texcoord_usage); |
| 306 | } |
| 307 | |
| 308 | |
| 309 | if (info->lower_fragdata_array) { |
| 310 | prepare_array(shader->ir, this->new_fragdata, |
| 311 | ARRAY_SIZE(this->new_fragdata), |
| 312 | FRAG_RESULT_DATA0, "FragData", mode_str, |
| 313 | info->fragdata_usage, (1 << MAX_DRAW_BUFFERS) - 1); |
| 314 | } |
| 315 | |
| 316 | |
| 317 | |
| 318 | |
| 319 | external_color_usage |= info->tfeedback_color_usage; |
| 320 | |
| 321 | for (int i = 0; i < 2; i++) { |
| 322 | char name[32]; |
| 323 | |
| 324 | if (!(external_color_usage & (1 << i))) { |
| 325 | if (info->color[i]) { |
| 326 | snprintf(name, 32, "gl_%s_FrontColor%i_dummy", mode_str, i); |
| 327 | this->new_color[i] = |
| 328 | new (ctx) ir_variable(glsl_type::vec4_type, name, |
| 329 | ir_var_temporary); |
| 330 | } |
| 331 | |
| 332 | if (info->backcolor[i]) { |
| 333 | snprintf(name, 32, "gl_%s_BackColor%i_dummy", mode_str, i); |
| 334 | this->new_backcolor[i] = |
| 335 | new (ctx) ir_variable(glsl_type::vec4_type, name, |
| 336 | ir_var_temporary); |
| 337 | } |
| 338 | } |
| 339 | } |
| 340 | |
| 341 | if (!external_has_fog && !info->tfeedback_has_fog && |
| 342 | info->fog) { |
| 343 | char name[32]; |
| 344 | |
| 345 | snprintf(name, 32, "gl_%s_FogFragCoord_dummy", mode_str); |
| 346 | this->new_fog = new (ctx) ir_variable(glsl_type::float_type, name, |
| 347 | ir_var_temporary); |
| 348 | } |
| 349 | |
| 350 | |
| 351 | visit_list_elements(this, shader->ir); |
| 352 | } |
| 353 | |
| 354 | void prepare_array(exec_list *ir, |
| 355 | ir_variable **new_var, |
| 356 | int max_elements, unsigned start_location, |
| 357 | const char *var_name, const char *mode_str, |
| 358 | unsigned usage, unsigned external_usage) |
| 359 | { |
| 360 | void *const ctx = ir; |
| 361 | |
| 362 | for (int i = max_elements-1; i >= 0; i--) { |
| 363 | if (usage & (1 << i)) { |
| 364 | char name[32]; |
| 365 | |
| 366 | if (!(external_usage & (1 << i))) { |
| 367 | |
| 368 | |
| 369 | snprintf(name, 32, "gl_%s_%s%i_dummy", mode_str, var_name, i); |
| 370 | new_var[i] = |
| 371 | new (ctx) ir_variable(glsl_type::vec4_type, name, |
| 372 | ir_var_temporary); |
| 373 | } |
| 374 | else { |
| 375 | snprintf(name, 32, "gl_%s_%s%i", mode_str, var_name, i); |
| 376 | new_var[i] = |
| 377 | new(ctx) ir_variable(glsl_type::vec4_type, name, |
| 378 | this->info->mode); |
| 379 | new_var[i]->data.location = start_location + i; |
| 380 | new_var[i]->data.explicit_location = true; |
| 381 | new_var[i]->data.explicit_index = 0; |
| 382 | } |
| 383 | |
| 384 | ir->get_head_raw()->insert_before(new_var[i]); |
| 385 | } |
| 386 | } |
| 387 | } |
| 388 | |
| 389 | virtual ir_visitor_status visit(ir_variable *var) |
| 390 | { |
| 391 | |
| 392 | if (this->info->lower_texcoord_array && |
| 393 | var == this->info->texcoord_array) { |
| 394 | var->remove(); |
| 395 | } |
| 396 | |
| 397 | |
| 398 | if (this->info->lower_fragdata_array && |
| 399 | var == this->info->fragdata_array) { |
| 400 | |
| 401 | |
| 402 | if (!shader->fragdata_arrays) |
| 403 | shader->fragdata_arrays = new (shader) exec_list; |
| 404 | |
| 405 | shader->fragdata_arrays->push_tail(var->clone(shader, NULL)); |
| 406 | |
| 407 | var->remove(); |
| 408 | } |
| 409 | |
| 410 | |
| 411 | for (int i = 0; i < 2; i++) { |
| 412 | if (var == this->info->color[i] && this->new_color[i]) { |
| 413 | var->replace_with(this->new_color[i]); |
| 414 | } |
| 415 | if (var == this->info->backcolor[i] && |
| 416 | this->new_backcolor[i]) { |
| 417 | var->replace_with(this->new_backcolor[i]); |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | if (var == this->info->fog && this->new_fog) { |
| 422 | var->replace_with(this->new_fog); |
| 423 | } |
| 424 | |
| 425 | return visit_continue; |
| 426 | } |
| 427 | |
| 428 | virtual void handle_rvalue(ir_rvalue **rvalue) |
| 429 | { |
| 430 | if (!*rvalue) |
| 431 | return; |
| 432 | |
| 433 | void *ctx = ralloc_parent(*rvalue); |
| 434 | |
| 435 | |
| 436 | |
| 437 | |
| 438 | if (this->info->lower_texcoord_array) { |
| 439 | |
| 440 | ir_dereference_array *const da = (*rvalue)->as_dereference_array(); |
| 441 | |
| 442 | if (da && da->variable_referenced() == |
| 443 | this->info->texcoord_array) { |
| 444 | unsigned i = da->array_index->as_constant()->get_uint_component(0); |
| 445 | |
| 446 | *rvalue = new(ctx) ir_dereference_variable(this->new_texcoord[i]); |
| 447 | return; |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | |
| 452 | if (this->info->lower_fragdata_array) { |
| 453 | |
| 454 | ir_dereference_array *const da = (*rvalue)->as_dereference_array(); |
| 455 | |
| 456 | if (da && da->variable_referenced() == this->info->fragdata_array) { |
| 457 | unsigned i = da->array_index->as_constant()->get_uint_component(0); |
| 458 | |
| 459 | *rvalue = new(ctx) ir_dereference_variable(this->new_fragdata[i]); |
| 460 | return; |
| 461 | } |
| 462 | } |
| 463 | |
| 464 | |
| 465 | ir_dereference_variable *const dv = (*rvalue)->as_dereference_variable(); |
| 466 | if (!dv) |
| 467 | return; |
| 468 | |
| 469 | ir_variable *var = dv->variable_referenced(); |
| 470 | |
| 471 | for (int i = 0; i < 2; i++) { |
| 472 | if (var == this->info->color[i] && this->new_color[i]) { |
| 473 | *rvalue = new(ctx) ir_dereference_variable(this->new_color[i]); |
| 474 | return; |
| 475 | } |
| 476 | if (var == this->info->backcolor[i] && |
| 477 | this->new_backcolor[i]) { |
| 478 | *rvalue = new(ctx) ir_dereference_variable(this->new_backcolor[i]); |
| 479 | return; |
| 480 | } |
| 481 | } |
| 482 | |
| 483 | if (var == this->info->fog && this->new_fog) { |
| 484 | *rvalue = new(ctx) ir_dereference_variable(this->new_fog); |
| 485 | } |
| 486 | } |
| 487 | |
| 488 | virtual ir_visitor_status visit_leave(ir_assignment *ir) |
| 489 | { |
| 490 | handle_rvalue(&ir->rhs); |
| 491 | handle_rvalue(&ir->condition); |
| 492 | |
| 493 | |
| 494 | ir_rvalue *lhs = ir->lhs; |
| 495 | |
| 496 | handle_rvalue(&lhs); |
| 497 | if (lhs != ir->lhs) { |
| 498 | ir->set_lhs(lhs); |
| 499 | } |
| 500 | |
| 501 | return visit_continue; |
| 502 | } |
| 503 | |
| 504 | private: |
| 505 | struct gl_linked_shader *shader; |
| 506 | const varying_info_visitor *info; |
| 507 | ir_variable *new_fragdata[MAX_DRAW_BUFFERS]; |
| 508 | ir_variable *new_texcoord[MAX_TEXTURE_COORD_UNITS]; |
| 509 | ir_variable *new_color[2]; |
| 510 | ir_variable *new_backcolor[2]; |
| 511 | ir_variable *new_fog; |
| 512 | }; |
| 513 | |
| 514 | } |
| 515 | |
| 516 | static void |
| 517 | lower_texcoord_array(struct gl_linked_shader *shader, const varying_info_visitor *info) |
| 518 | { |
| 519 | replace_varyings_visitor(shader, info, |
| 520 | (1 << MAX_TEXTURE_COORD_UNITS) - 1, |
| 521 | 1 | 2, true); |
| 522 | } |
| 523 | |
| 524 | static void |
| 525 | lower_fragdata_array(struct gl_linked_shader *shader) |
| 526 | { |
| 527 | varying_info_visitor info(ir_var_shader_out, true); |
| 528 | info.get(shader->ir, 0, NULL); |
| 529 | |
| 530 | replace_varyings_visitor(shader, &info, 0, 0, 0); |
| 531 | } |
| 532 | |
| 533 | |
| 534 | void |
| 535 | do_dead_builtin_varyings(struct gl_context *ctx, |
| 536 | gl_linked_shader *producer, |
| 537 | gl_linked_shader *consumer, |
| 538 | unsigned num_tfeedback_decls, |
| 539 | tfeedback_decl *tfeedback_decls) |
| 540 | { |
| 541 | |
| 542 | if (consumer && consumer->Stage == MESA_SHADER_FRAGMENT && |
| 1 | Assuming 'consumer' is null | |
|
| 543 | !ctx->Const.ShaderCompilerOptions[MESA_SHADER_FRAGMENT].NirOptions) { |
| 544 | lower_fragdata_array(consumer); |
| 545 | } |
| 546 | |
| 547 | |
| 548 | |
| 549 | |
| 550 | if (ctx->API == API_OPENGL_CORE || |
| 2 | | Assuming field 'API' is not equal to API_OPENGL_CORE | |
|
| |
| 551 | ctx->API == API_OPENGLES2) { |
| 3 | | Assuming field 'API' is not equal to API_OPENGLES2 | |
|
| 552 | return; |
| 553 | } |
| 554 | |
| 555 | |
| 556 | varying_info_visitor producer_info(ir_var_shader_out); |
| 5 | | Calling constructor for 'varying_info_visitor' | |
|
| 7 | | Returning from constructor for 'varying_info_visitor' | |
|
| 557 | varying_info_visitor consumer_info(ir_var_shader_in); |
| 558 | |
| 559 | if (producer) { |
| 8 | | Assuming 'producer' is null | |
|
| |
| 560 | producer_info.get(producer->ir, num_tfeedback_decls, tfeedback_decls); |
| 561 | |
| 562 | if (producer->Stage == MESA_SHADER_TESS_CTRL) |
| 563 | producer_info.lower_texcoord_array = false; |
| 564 | |
| 565 | if (!consumer) { |
| 566 | |
| 567 | if (producer_info.lower_texcoord_array) { |
| 568 | lower_texcoord_array(producer, &producer_info); |
| 569 | } |
| 570 | return; |
| 571 | } |
| 572 | } |
| 573 | |
| 574 | if (consumer) { |
| 575 | consumer_info.get(consumer->ir, 0, NULL); |
| 576 | |
| 577 | if (consumer->Stage != MESA_SHADER_FRAGMENT) |
| 578 | consumer_info.lower_texcoord_array = false; |
| 579 | |
| 580 | if (!producer) { |
| 581 | |
| 582 | if (consumer_info.lower_texcoord_array) { |
| 583 | lower_texcoord_array(consumer, &consumer_info); |
| 584 | } |
| 585 | return; |
| 586 | } |
| 587 | } |
| 588 | |
| 589 | |
| 590 | if (producer_info.lower_texcoord_array || |
| 591 | producer_info.color_usage || |
| 592 | producer_info.has_fog) { |
| 593 | replace_varyings_visitor(producer, |
| 10 | | Passing null pointer value via 1st parameter 'sha' | |
|
| 11 | | Calling constructor for 'replace_varyings_visitor' | |
|
| 594 | &producer_info, |
| 595 | consumer_info.texcoord_usage, |
| 596 | consumer_info.color_usage, |
| 597 | consumer_info.has_fog); |
| 598 | } |
| 599 | |
| 600 | |
| 601 | |
| 602 | |
| 603 | |
| 604 | |
| 605 | |
| 606 | if (consumer->Stage == MESA_SHADER_FRAGMENT) { |
| 607 | producer_info.texcoord_usage = (1 << MAX_TEXTURE_COORD_UNITS) - 1; |
| 608 | } |
| 609 | |
| 610 | |
| 611 | if (consumer_info.lower_texcoord_array || |
| 612 | consumer_info.color_usage || |
| 613 | consumer_info.has_fog) { |
| 614 | replace_varyings_visitor(consumer, |
| 615 | &consumer_info, |
| 616 | producer_info.texcoord_usage, |
| 617 | producer_info.color_usage, |
| 618 | producer_info.has_fog); |
| 619 | } |
| 620 | } |