1 /**************************************************************************
2 *
3 * Copyright (C) 2014 Red Hat Inc.
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 shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR 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
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 **************************************************************************/
24
25 #include "tgsi/tgsi_info.h"
26 #include "tgsi/tgsi_iterate.h"
27 #include "tgsi/tgsi_scan.h"
28 #include "util/u_memory.h"
29 #include "util/u_math.h"
30 #include <string.h>
31 #include <stdio.h>
32 #include <math.h>
33 #include <errno.h>
34 #include "vrend_shader.h"
35 #include "vrend_debug.h"
36
37 #include "vrend_strbuf.h"
38
39 /* start convert of tgsi to glsl */
40
41 #define INVARI_PREFIX "invariant"
42
43 #define SHADER_REQ_NONE 0
44 #define SHADER_REQ_SAMPLER_RECT (1ULL << 0)
45 #define SHADER_REQ_CUBE_ARRAY (1ULL << 1)
46 #define SHADER_REQ_INTS (1ULL << 2)
47 #define SHADER_REQ_SAMPLER_MS (1ULL << 3)
48 #define SHADER_REQ_INSTANCE_ID (1ULL << 4)
49 #define SHADER_REQ_LODQ (1ULL << 5)
50 #define SHADER_REQ_TXQ_LEVELS (1ULL << 6)
51 #define SHADER_REQ_TG4 (1ULL << 7)
52 #define SHADER_REQ_VIEWPORT_IDX (1ULL << 8)
53 #define SHADER_REQ_STENCIL_EXPORT (1ULL << 9)
54 #define SHADER_REQ_LAYER (1ULL << 10)
55 #define SHADER_REQ_SAMPLE_SHADING (1ULL << 11)
56 #define SHADER_REQ_GPU_SHADER5 (1ULL << 12)
57 #define SHADER_REQ_DERIVATIVE_CONTROL (1ULL << 13)
58 #define SHADER_REQ_FP64 (1ULL << 14)
59 #define SHADER_REQ_IMAGE_LOAD_STORE (1ULL << 15)
60 #define SHADER_REQ_ES31_COMPAT (1ULL << 16)
61 #define SHADER_REQ_IMAGE_SIZE (1ULL << 17)
62 #define SHADER_REQ_TXQS (1ULL << 18)
63 #define SHADER_REQ_FBFETCH (1ULL << 19)
64 #define SHADER_REQ_SHADER_CLOCK (1ULL << 20)
65 #define SHADER_REQ_PSIZE (1ULL << 21)
66 #define SHADER_REQ_IMAGE_ATOMIC (1ULL << 22)
67 #define SHADER_REQ_CLIP_DISTANCE (1ULL << 23)
68 #define SHADER_REQ_ENHANCED_LAYOUTS (1ULL << 24)
69 #define SHADER_REQ_SEPERATE_SHADER_OBJECTS (1ULL << 25)
70 #define SHADER_REQ_ARRAYS_OF_ARRAYS (1ULL << 26)
71 #define SHADER_REQ_SHADER_INTEGER_FUNC (1ULL << 27)
72 #define SHADER_REQ_SHADER_ATOMIC_FLOAT (1ULL << 28)
73 #define SHADER_REQ_NV_IMAGE_FORMATS (1ULL << 29)
74 #define SHADER_REQ_CONSERVATIVE_DEPTH (1ULL << 30)
75 #define SHADER_REQ_SAMPLER_BUF (1ULL << 31)
76 #define SHADER_REQ_GEOMETRY_SHADER (1ULL << 32)
77 #define SHADER_REQ_BLEND_EQUATION_ADVANCED (1ULL << 33)
78 #define SHADER_REQ_EXPLICIT_ATTRIB_LOCATION (1ULL << 34)
79 #define SHADER_REQ_SHADER_NOPERSPECTIVE_INTERPOLATION (1ULL << 35)
80 #define SHADER_REQ_TEXTURE_SHADOW_LOD (1ULL << 36)
81
82 #define FRONT_COLOR_EMITTED (1 << 0)
83 #define BACK_COLOR_EMITTED (1 << 1);
84
85 #define MAX_VARYING 32
86
87 enum vrend_sysval_uniform {
88 UNIFORM_WINSYS_ADJUST_Y,
89 UNIFORM_CLIP_PLANE,
90 UNIFORM_ALPHA_REF_VAL,
91 UNIFORM_PSTIPPLE_SAMPLER,
92 };
93
94 enum vec_type {
95 VEC_FLOAT = 0,
96 VEC_INT = 1,
97 VEC_UINT = 2
98 };
99
100 struct vrend_shader_sampler {
101 int tgsi_sampler_type;
102 enum tgsi_return_type tgsi_sampler_return;
103 };
104
105 struct vrend_shader_table {
106 uint64_t key;
107 const char *string;
108 };
109
110 struct vrend_shader_image {
111 struct tgsi_declaration_image decl;
112 enum tgsi_return_type image_return;
113 bool vflag;
114 bool coherent;
115 };
116
117 #define MAX_IMMEDIATE 1024
118 struct immed {
119 enum tgsi_imm_type type;
120 union imm {
121 uint32_t ui;
122 int32_t i;
123 float f;
124 } val[4];
125 };
126
127 struct vrend_temp_range {
128 int first;
129 int last;
130 int array_id;
131 bool precise_result;
132 };
133
134 struct vrend_shader_io {
135 char glsl_name[128];
136 struct vrend_shader_io *overlapping_array;
137 unsigned sid : 16;
138 unsigned first : 16;
139 unsigned last : 16;
140 unsigned array_id : 10;
141 enum tgsi_interpolate_mode interpolate : 4;
142 enum tgsi_interpolate_loc location : 2;
143
144 unsigned array_offset : 8;
145 enum tgsi_semantic name : 8;
146 unsigned stream : 2;
147 unsigned usage_mask : 4;
148 enum vec_type type : 2;
149 unsigned num_components : 3;
150
151 bool invariant : 1;
152 bool precise : 1;
153 bool glsl_predefined_no_emit : 1;
154 bool glsl_no_index : 1;
155 bool glsl_gl_block : 1;
156 bool override_no_wm : 1;
157 bool is_int : 1;
158 bool fbfetch_used : 1;
159 bool needs_override : 1;
160 };
161
162 struct vrend_io_range {
163 struct vrend_shader_io io;
164 bool used;
165 };
166
167 struct vrend_glsl_strbufs {
168 int indent_level;
169 uint8_t required_sysval_uniform_decls;
170 struct vrend_strbuf glsl_main;
171 struct vrend_strbuf glsl_hdr;
172 struct vrend_strbuf glsl_ver_ext;
173 };
174
175 struct vrend_interface_bits {
176 uint64_t outputs_expected_mask;
177 uint64_t inputs_emitted_mask;
178 uint64_t outputs_emitted_mask;
179 };
180
181 struct vrend_generic_ios {
182 struct vrend_interface_bits match;
183 struct vrend_io_range input_range;
184 struct vrend_io_range output_range;
185 };
186
187 struct vrend_texcoord_ios {
188 struct vrend_interface_bits match;
189 };
190
191 struct vrend_patch_ios {
192 struct vrend_io_range input_range;
193 struct vrend_io_range output_range;
194 };
195
196 struct dump_ctx {
197 struct tgsi_iterate_context iter;
198 const struct vrend_shader_cfg *cfg;
199 struct tgsi_shader_info info;
200 enum tgsi_processor_type prog_type;
201 int size;
202 struct vrend_glsl_strbufs glsl_strbufs;
203 uint instno;
204
205 struct vrend_strbuf src_bufs[4];
206 struct vrend_strbuf dst_bufs[3];
207
208 uint32_t num_interps;
209 uint32_t num_inputs;
210 uint32_t attrib_input_mask;
211 struct vrend_shader_io inputs[64];
212 uint32_t num_outputs;
213 struct vrend_shader_io outputs[64];
214 uint8_t front_back_color_emitted_flags[64];
215 uint32_t num_system_values;
216 struct vrend_shader_io system_values[32];
217
218 bool guest_sent_io_arrays;
219 struct vrend_texcoord_ios texcoord_ios;
220 struct vrend_generic_ios generic_ios;
221 struct vrend_patch_ios patch_ios;
222
223 uint32_t num_temp_ranges;
224 struct vrend_temp_range *temp_ranges;
225
226 struct vrend_shader_sampler samplers[32];
227 uint32_t samplers_used;
228
229 uint32_t ssbo_used_mask;
230 uint32_t ssbo_atomic_mask;
231 uint32_t ssbo_array_base;
232 uint32_t ssbo_atomic_array_base;
233 uint32_t ssbo_integer_mask;
234 uint8_t ssbo_memory_qualifier[32];
235
236 struct vrend_shader_image images[32];
237 uint32_t images_used_mask;
238
239 struct vrend_array *image_arrays;
240 uint32_t num_image_arrays;
241
242 struct vrend_array *sampler_arrays;
243 uint32_t num_sampler_arrays;
244
245 uint32_t fog_input_mask;
246 uint32_t fog_output_mask;
247
248 int num_consts;
249 int num_imm;
250 struct immed imm[MAX_IMMEDIATE];
251
252 uint32_t req_local_mem;
253 bool integer_memory;
254
255 uint32_t ubo_base;
256 uint32_t ubo_used_mask;
257 int ubo_sizes[32];
258 uint32_t num_address;
259
260 uint32_t num_abo;
261 int abo_idx[32];
262 int abo_sizes[32];
263 int abo_offsets[32];
264
265 uint64_t shader_req_bits;
266 uint64_t patches_emitted_mask;
267
268 struct pipe_stream_output_info *so;
269 char **so_names;
270 bool write_so_outputs[PIPE_MAX_SO_OUTPUTS];
271 bool write_all_cbufs;
272 uint32_t shadow_samp_mask;
273
274 bool fs_lower_left_origin, fs_integer_pixel_center;
275 int fs_depth_layout;
276 uint32_t fs_blend_equation_advanced;
277
278 bool separable_program;
279
280 int gs_in_prim, gs_out_prim, gs_max_out_verts;
281 int gs_num_invocations;
282
283 const struct vrend_shader_key *key;
284 int num_in_clip_dist;
285 int num_out_clip_dist;
286 int fs_uses_clipdist_input;
287 int glsl_ver_required;
288 int color_in_mask;
289 int color_out_mask;
290 /* only used when cull is enabled */
291 uint8_t num_cull_dist_prop, num_clip_dist_prop;
292 bool has_pervertex;
293 bool front_face_emitted;
294
295 bool has_clipvertex;
296 bool has_clipvertex_so;
297 bool write_mul_utemp;
298 bool write_mul_itemp;
299 bool has_sample_input;
300 bool has_noperspective;
301 bool early_depth_stencil;
302 bool has_file_memory;
303 bool force_color_two_side;
304 bool gles_use_tex_query_level;
305 bool has_pointsize_input;
306 bool has_pointsize_output;
307
308 bool has_input_arrays;
309 bool has_output_arrays;
310
311 int tcs_vertices_out;
312 int tes_prim_mode;
313 int tes_spacing;
314 int tes_vertex_order;
315 int tes_point_mode;
316 bool is_last_vertex_stage;
317 bool require_dummy_value;
318
319 uint16_t local_cs_block_size[3];
320 };
321
322 static const struct vrend_shader_table shader_req_table[] = {
323 { SHADER_REQ_SAMPLER_RECT, "ARB_texture_rectangle" },
324 { SHADER_REQ_CUBE_ARRAY, "ARB_texture_cube_map_array" },
325 { SHADER_REQ_INTS, "ARB_shader_bit_encoding" },
326 { SHADER_REQ_SAMPLER_MS, "ARB_texture_multisample" },
327 { SHADER_REQ_INSTANCE_ID, "ARB_draw_instanced" },
328 { SHADER_REQ_LODQ, "ARB_texture_query_lod" },
329 { SHADER_REQ_TXQ_LEVELS, "ARB_texture_query_levels" },
330 { SHADER_REQ_TG4, "ARB_texture_gather" },
331 { SHADER_REQ_VIEWPORT_IDX, "ARB_viewport_array" },
332 { SHADER_REQ_STENCIL_EXPORT, "ARB_shader_stencil_export" },
333 { SHADER_REQ_LAYER, "ARB_fragment_layer_viewport" },
334 { SHADER_REQ_SAMPLE_SHADING, "ARB_sample_shading" },
335 { SHADER_REQ_GPU_SHADER5, "ARB_gpu_shader5" },
336 { SHADER_REQ_DERIVATIVE_CONTROL, "ARB_derivative_control" },
337 { SHADER_REQ_FP64, "ARB_gpu_shader_fp64" },
338 { SHADER_REQ_IMAGE_LOAD_STORE, "ARB_shader_image_load_store" },
339 { SHADER_REQ_ES31_COMPAT, "ARB_ES3_1_compatibility" },
340 { SHADER_REQ_IMAGE_SIZE, "ARB_shader_image_size" },
341 { SHADER_REQ_TXQS, "ARB_shader_texture_image_samples" },
342 { SHADER_REQ_FBFETCH, "EXT_shader_framebuffer_fetch" },
343 { SHADER_REQ_SHADER_CLOCK, "ARB_shader_clock" },
344 { SHADER_REQ_SHADER_INTEGER_FUNC, "MESA_shader_integer_functions" },
345 { SHADER_REQ_SHADER_ATOMIC_FLOAT, "NV_shader_atomic_float"},
346 { SHADER_REQ_CONSERVATIVE_DEPTH, "ARB_conservative_depth"},
347 {SHADER_REQ_BLEND_EQUATION_ADVANCED, "KHR_blend_equation_advanced"},
348 { SHADER_REQ_TEXTURE_SHADOW_LOD, "EXT_texture_shadow_lod"},
349 };
350
351 enum vrend_type_qualifier {
352 TYPE_CONVERSION_NONE = 0,
353 FLOAT = 1,
354 VEC2 = 2,
355 VEC3 = 3,
356 VEC4 = 4,
357 INT = 5,
358 IVEC2 = 6,
359 IVEC3 = 7,
360 IVEC4 = 8,
361 UINT = 9,
362 UVEC2 = 10,
363 UVEC3 = 11,
364 UVEC4 = 12,
365 FLOAT_BITS_TO_UINT = 13,
366 UINT_BITS_TO_FLOAT = 14,
367 FLOAT_BITS_TO_INT = 15,
368 INT_BITS_TO_FLOAT = 16,
369 DOUBLE = 17,
370 DVEC2 = 18,
371 };
372
373 struct dest_info {
374 enum vrend_type_qualifier dtypeprefix;
375 enum vrend_type_qualifier dstconv;
376 enum vrend_type_qualifier udstconv;
377 enum vrend_type_qualifier idstconv;
378 bool dst_override_no_wm[2];
379 int32_t dest_index;
380 };
381
382 struct source_info {
383 enum vrend_type_qualifier svec4;
384 int32_t sreg_index;
385 bool tg4_has_component;
386 bool override_no_wm[3];
387 bool override_no_cast[3];
388 int imm_value;
389 };
390
391 static const struct vrend_shader_table conversion_table[] =
392 {
393 {TYPE_CONVERSION_NONE, ""},
394 {FLOAT, "float"},
395 {VEC2, "vec2"},
396 {VEC3, "vec3"},
397 {VEC4, "vec4"},
398 {INT, "int"},
399 {IVEC2, "ivec2"},
400 {IVEC3, "ivec3"},
401 {IVEC4, "ivec4"},
402 {UINT, "uint"},
403 {UVEC2, "uvec2"},
404 {UVEC3, "uvec3"},
405 {UVEC4, "uvec4"},
406 {FLOAT_BITS_TO_UINT, "floatBitsToUint"},
407 {UINT_BITS_TO_FLOAT, "uintBitsToFloat"},
408 {FLOAT_BITS_TO_INT, "floatBitsToInt"},
409 {INT_BITS_TO_FLOAT, "intBitsToFloat"},
410 {DOUBLE, "double"},
411 {DVEC2, "dvec2"},
412 };
413
414 enum io_type {
415 io_in,
416 io_out
417 };
418
419 enum io_decl_type {
420 decl_plain,
421 decl_block
422 };
423
424 static
425 void vrend_shader_write_io_as_src(struct vrend_strbuf *buf,
426 const char *arrayname,
427 const struct vrend_shader_io *io,
428 const struct tgsi_full_src_register *src,
429 enum io_decl_type decl_type);
430
431 static
432 void vrend_shader_write_io_as_dst(struct vrend_strbuf *buf,
433 const char *arrayname,
434 const struct vrend_shader_io *io,
435 const struct tgsi_full_dst_register *src,
436 enum io_decl_type decl_type);
437
438 /* We prefer arrays of arrays, but if this is not available then TCS, GEOM, and TES
439 * inputs must be blocks, but FS input should not because interpolateAt* doesn't
440 * support dereferencing block members. */
prefer_generic_io_block(const struct dump_ctx * ctx,enum io_type io)441 static inline bool prefer_generic_io_block(const struct dump_ctx *ctx, enum io_type io)
442 {
443 if (ctx->cfg->has_arrays_of_arrays && !ctx->cfg->use_gles)
444 return false;
445
446 switch (ctx->prog_type) {
447 case TGSI_PROCESSOR_FRAGMENT:
448 return false;
449
450 case TGSI_PROCESSOR_TESS_CTRL:
451 return true;
452
453 case TGSI_PROCESSOR_TESS_EVAL:
454 return io == io_in ? true : (ctx->key->gs_present ? true : false);
455
456 case TGSI_PROCESSOR_GEOMETRY:
457 return io == io_in;
458
459 case TGSI_PROCESSOR_VERTEX:
460 if (io == io_in)
461 return false;
462 return (ctx->key->gs_present || ctx->key->tes_present);
463
464 default:
465 return false;
466 }
467 }
468
get_string(enum vrend_type_qualifier key)469 static inline const char *get_string(enum vrend_type_qualifier key)
470 {
471 if (key >= ARRAY_SIZE(conversion_table)) {
472 printf("Unable to find the correct conversion\n");
473 return conversion_table[TYPE_CONVERSION_NONE].string;
474 }
475
476 return conversion_table[key].string;
477 }
478
get_wm_string(unsigned wm)479 static inline const char *get_wm_string(unsigned wm)
480 {
481 switch(wm) {
482 case TGSI_WRITEMASK_NONE:
483 return "";
484 case TGSI_WRITEMASK_X:
485 return ".x";
486 case TGSI_WRITEMASK_XY:
487 return ".xy";
488 case TGSI_WRITEMASK_XYZ:
489 return ".xyz";
490 case TGSI_WRITEMASK_W:
491 return ".w";
492 default:
493 printf("Unable to unknown writemask\n");
494 return "";
495 }
496 }
497
get_swizzle_string(uint8_t swizzle)498 static inline const char *get_swizzle_string(uint8_t swizzle)
499 {
500 switch (swizzle) {
501 case PIPE_SWIZZLE_RED: return ".x";
502 case PIPE_SWIZZLE_GREEN: return ".y";
503 case PIPE_SWIZZLE_BLUE: return ".z";
504 case PIPE_SWIZZLE_ALPHA: return ".w";
505 case PIPE_SWIZZLE_ZERO:
506 case PIPE_SWIZZLE_ONE: return ".0";
507 default:
508 assert(0);
509 return "";
510 }
511 }
512
513 const char *get_internalformat_string(int virgl_format, enum tgsi_return_type *stype);
514
tgsi_proc_to_prefix(int shader_type)515 static inline const char *tgsi_proc_to_prefix(int shader_type)
516 {
517 switch (shader_type) {
518 case TGSI_PROCESSOR_VERTEX: return "vs";
519 case TGSI_PROCESSOR_FRAGMENT: return "fs";
520 case TGSI_PROCESSOR_GEOMETRY: return "gs";
521 case TGSI_PROCESSOR_TESS_CTRL: return "tc";
522 case TGSI_PROCESSOR_TESS_EVAL: return "te";
523 case TGSI_PROCESSOR_COMPUTE: return "cs";
524 default:
525 return NULL;
526 };
527 }
528
prim_to_name(int prim)529 static inline const char *prim_to_name(int prim)
530 {
531 switch (prim) {
532 case PIPE_PRIM_POINTS: return "points";
533 case PIPE_PRIM_LINES: return "lines";
534 case PIPE_PRIM_LINE_STRIP: return "line_strip";
535 case PIPE_PRIM_LINES_ADJACENCY: return "lines_adjacency";
536 case PIPE_PRIM_TRIANGLES: return "triangles";
537 case PIPE_PRIM_TRIANGLE_STRIP: return "triangle_strip";
538 case PIPE_PRIM_TRIANGLES_ADJACENCY: return "triangles_adjacency";
539 case PIPE_PRIM_QUADS: return "quads";
540 default: return "UNKNOWN";
541 };
542 }
543
prim_to_tes_name(int prim)544 static inline const char *prim_to_tes_name(int prim)
545 {
546 switch (prim) {
547 case PIPE_PRIM_QUADS: return "quads";
548 case PIPE_PRIM_TRIANGLES: return "triangles";
549 case PIPE_PRIM_LINES: return "isolines";
550 default: return "UNKNOWN";
551 }
552 }
553
blend_to_name(enum gl_advanced_blend_mode blend)554 static inline const char *blend_to_name(enum gl_advanced_blend_mode blend)
555 {
556 switch (blend) {
557 case BLEND_MULTIPLY: return "multiply";
558 case BLEND_SCREEN: return "screen";
559 case BLEND_OVERLAY: return "overlay";
560 case BLEND_DARKEN: return "darken";
561 case BLEND_LIGHTEN: return "lighten";
562 case BLEND_COLORDODGE: return "colordodge";
563 case BLEND_COLORBURN: return "colorburn";
564 case BLEND_HARDLIGHT: return "hardlight";
565 case BLEND_SOFTLIGHT: return "softlight";
566 case BLEND_DIFFERENCE: return "difference";
567 case BLEND_EXCLUSION: return "exclusion";
568 case BLEND_HSL_HUE: return "hsl_hue";
569 case BLEND_HSL_SATURATION: return "hsl_saturation";
570 case BLEND_HSL_COLOR: return "hsl_color";
571 case BLEND_HSL_LUMINOSITY: return "hsl_luminosity";
572 case BLEND_ALL: return "all_equations";
573 default: return "UNKNOWN";
574 };
575 }
576
get_spacing_string(int spacing)577 static const char *get_spacing_string(int spacing)
578 {
579 switch (spacing) {
580 case PIPE_TESS_SPACING_FRACTIONAL_ODD:
581 return "fractional_odd_spacing";
582 case PIPE_TESS_SPACING_FRACTIONAL_EVEN:
583 return "fractional_even_spacing";
584 case PIPE_TESS_SPACING_EQUAL:
585 default:
586 return "equal_spacing";
587 }
588 }
589
gs_input_prim_to_size(int prim)590 static inline int gs_input_prim_to_size(int prim)
591 {
592 switch (prim) {
593 case PIPE_PRIM_POINTS: return 1;
594 case PIPE_PRIM_LINES: return 2;
595 case PIPE_PRIM_LINES_ADJACENCY: return 4;
596 case PIPE_PRIM_TRIANGLES: return 3;
597 case PIPE_PRIM_TRIANGLES_ADJACENCY: return 6;
598 default: return -1;
599 };
600 }
601
fs_emit_layout(const struct dump_ctx * ctx)602 static inline bool fs_emit_layout(const struct dump_ctx *ctx)
603 {
604 if (ctx->fs_integer_pixel_center)
605 return true;
606
607 /* if fs_lower_left_origin is 0 and lower_left_origin is 0 - emit origin_upper_left,
608 if fs_lower_left_origin is 0 and lower_left_origin is 1 - emit nothing (lower)
609 if fs_lower_left_origin is 1 and lower_left_origin is 0 - emit nothing (lower)
610 if fs_lower_left_origin is 1 and lower_left_origin is 1 - emit origin_upper_left */
611 return ctx->fs_lower_left_origin == ctx->key->fs.lower_left_origin;
612 }
613
get_stage_input_name_prefix(const struct dump_ctx * ctx,int processor)614 static const char *get_stage_input_name_prefix(const struct dump_ctx *ctx, int processor)
615 {
616 const char *name_prefix;
617 switch (processor) {
618 case TGSI_PROCESSOR_FRAGMENT:
619 if (ctx->key->gs_present)
620 name_prefix = "gso";
621 else if (ctx->key->tes_present)
622 name_prefix = "teo";
623 else
624 name_prefix = "vso";
625 break;
626 case TGSI_PROCESSOR_GEOMETRY:
627 if (ctx->key->tes_present)
628 name_prefix = "teo";
629 else
630 name_prefix = "vso";
631 break;
632 case TGSI_PROCESSOR_TESS_EVAL:
633 if (ctx->key->tcs_present)
634 name_prefix = "tco";
635 else
636 name_prefix = "vso";
637 break;
638 case TGSI_PROCESSOR_TESS_CTRL:
639 name_prefix = "vso";
640 break;
641 case TGSI_PROCESSOR_VERTEX:
642 default:
643 name_prefix = "in";
644 break;
645 }
646 return name_prefix;
647 }
648
get_stage_output_name_prefix(int processor)649 static const char *get_stage_output_name_prefix(int processor)
650 {
651 const char *name_prefix;
652 switch (processor) {
653 case TGSI_PROCESSOR_FRAGMENT:
654 name_prefix = "fsout";
655 break;
656 case TGSI_PROCESSOR_GEOMETRY:
657 name_prefix = "gso";
658 break;
659 case TGSI_PROCESSOR_VERTEX:
660 name_prefix = "vso";
661 break;
662 case TGSI_PROCESSOR_TESS_CTRL:
663 name_prefix = "tco";
664 break;
665 case TGSI_PROCESSOR_TESS_EVAL:
666 name_prefix = "teo";
667 break;
668 default:
669 name_prefix = "out";
670 break;
671 }
672 return name_prefix;
673 }
674
require_glsl_ver(const struct dump_ctx * ctx,int glsl_ver)675 static int require_glsl_ver(const struct dump_ctx *ctx, int glsl_ver)
676 {
677 return glsl_ver > ctx->glsl_ver_required ? glsl_ver : ctx->glsl_ver_required;
678 }
679
emit_indent(struct vrend_glsl_strbufs * glsl_strbufs)680 static void emit_indent(struct vrend_glsl_strbufs *glsl_strbufs)
681 {
682 if (glsl_strbufs->indent_level > 0) {
683 /* very high levels of indentation doesn't improve readability */
684 int indent_level = MIN2(glsl_strbufs->indent_level, 15);
685 char buf[16];
686 memset(buf, '\t', indent_level);
687 buf[indent_level] = '\0';
688 strbuf_append(&glsl_strbufs->glsl_main, buf);
689 }
690 }
691
emit_buf(struct vrend_glsl_strbufs * glsl_strbufs,const char * buf)692 static void emit_buf(struct vrend_glsl_strbufs *glsl_strbufs, const char *buf)
693 {
694 emit_indent(glsl_strbufs);
695 strbuf_append(&glsl_strbufs->glsl_main, buf);
696 }
697
indent_buf(struct vrend_glsl_strbufs * glsl_strbufs)698 static void indent_buf(struct vrend_glsl_strbufs *glsl_strbufs)
699 {
700 glsl_strbufs->indent_level++;
701 }
702
outdent_buf(struct vrend_glsl_strbufs * glsl_strbufs)703 static void outdent_buf(struct vrend_glsl_strbufs *glsl_strbufs)
704 {
705 if (glsl_strbufs->indent_level <= 0) {
706 strbuf_set_error(&glsl_strbufs->glsl_main);
707 return;
708 }
709 glsl_strbufs->indent_level--;
710 }
711
set_buf_error(struct vrend_glsl_strbufs * glsl_strbufs)712 static void set_buf_error(struct vrend_glsl_strbufs *glsl_strbufs)
713 {
714 strbuf_set_error(&glsl_strbufs->glsl_main);
715 }
716
717 __attribute__((format(printf, 2, 3)))
emit_buff(struct vrend_glsl_strbufs * glsl_strbufs,const char * fmt,...)718 static void emit_buff(struct vrend_glsl_strbufs *glsl_strbufs, const char *fmt, ...)
719 {
720 va_list va;
721 va_start(va, fmt);
722 emit_indent(glsl_strbufs);
723 strbuf_vappendf(&glsl_strbufs->glsl_main, fmt, va);
724 va_end(va);
725 }
726
emit_hdr(struct vrend_glsl_strbufs * glsl_strbufs,const char * buf)727 static void emit_hdr(struct vrend_glsl_strbufs *glsl_strbufs, const char *buf)
728 {
729 strbuf_append(&glsl_strbufs->glsl_hdr, buf);
730 }
731
set_hdr_error(struct vrend_glsl_strbufs * glsl_strbufs)732 static void set_hdr_error(struct vrend_glsl_strbufs *glsl_strbufs)
733 {
734 strbuf_set_error(&glsl_strbufs->glsl_hdr);
735 }
736
737 __attribute__((format(printf, 2, 3)))
emit_hdrf(struct vrend_glsl_strbufs * glsl_strbufs,const char * fmt,...)738 static void emit_hdrf(struct vrend_glsl_strbufs *glsl_strbufs, const char *fmt, ...)
739 {
740 va_list va;
741 va_start(va, fmt);
742 strbuf_vappendf(&glsl_strbufs->glsl_hdr, fmt, va);
743 va_end(va);
744 }
745
emit_ver_ext(struct vrend_glsl_strbufs * glsl_strbufs,const char * buf)746 static void emit_ver_ext(struct vrend_glsl_strbufs *glsl_strbufs, const char *buf)
747 {
748 strbuf_append(&glsl_strbufs->glsl_ver_ext, buf);
749 }
750
751 __attribute__((format(printf, 2, 3)))
emit_ver_extf(struct vrend_glsl_strbufs * glsl_strbufs,const char * fmt,...)752 static void emit_ver_extf(struct vrend_glsl_strbufs *glsl_strbufs, const char *fmt, ...)
753 {
754 va_list va;
755 va_start(va, fmt);
756 strbuf_vappendf(&glsl_strbufs->glsl_ver_ext, fmt, va);
757 va_end(va);
758 }
759
allocate_temp_range(struct vrend_temp_range ** temp_ranges,uint32_t * num_temp_ranges,int first,int last,int array_id)760 static bool allocate_temp_range(struct vrend_temp_range **temp_ranges, uint32_t *num_temp_ranges, int first, int last,
761 int array_id)
762 {
763 int idx = *num_temp_ranges;
764
765 if (array_id > 0) {
766
767 *temp_ranges = realloc(*temp_ranges, sizeof(struct vrend_temp_range) * (idx + 1));
768 if (!*temp_ranges)
769 return false;
770
771 (*temp_ranges)[idx].first = first;
772 (*temp_ranges)[idx].last = last;
773 (*temp_ranges)[idx].array_id = array_id;
774 (*temp_ranges)[idx].precise_result = false;
775 (*num_temp_ranges)++;
776 } else {
777 int ntemps = last - first + 1;
778 *temp_ranges = realloc(*temp_ranges, sizeof(struct vrend_temp_range) * (idx + ntemps));
779 for (int i = 0; i < ntemps; ++i) {
780 (*temp_ranges)[idx + i].first = first + i;
781 (*temp_ranges)[idx + i].last = first + i;
782 (*temp_ranges)[idx + i].array_id = 0;
783 (*temp_ranges)[idx + i].precise_result = false;
784 }
785 (*num_temp_ranges) += ntemps;
786
787
788 }
789 return true;
790 }
791
find_temp_range(const struct dump_ctx * ctx,int index)792 static struct vrend_temp_range *find_temp_range(const struct dump_ctx *ctx, int index)
793 {
794 uint32_t i;
795 for (i = 0; i < ctx->num_temp_ranges; i++) {
796 if (index >= ctx->temp_ranges[i].first &&
797 index <= ctx->temp_ranges[i].last)
798 return &ctx->temp_ranges[i];
799 }
800 return NULL;
801 }
802
samplertype_is_shadow(int sampler_type)803 static bool samplertype_is_shadow(int sampler_type)
804 {
805 switch (sampler_type) {
806 case TGSI_TEXTURE_SHADOW1D:
807 case TGSI_TEXTURE_SHADOW1D_ARRAY:
808 case TGSI_TEXTURE_SHADOW2D:
809 case TGSI_TEXTURE_SHADOWRECT:
810 case TGSI_TEXTURE_SHADOW2D_ARRAY:
811 case TGSI_TEXTURE_SHADOWCUBE:
812 case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
813 return true;
814 default:
815 return false;
816 }
817 }
818
samplertype_to_req_bits(int sampler_type)819 static uint32_t samplertype_to_req_bits(int sampler_type)
820 {
821
822 switch (sampler_type) {
823 case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
824 case TGSI_TEXTURE_CUBE_ARRAY:
825 return SHADER_REQ_CUBE_ARRAY;
826 case TGSI_TEXTURE_2D_MSAA:
827 case TGSI_TEXTURE_2D_ARRAY_MSAA:
828 return SHADER_REQ_SAMPLER_MS;
829 case TGSI_TEXTURE_BUFFER:
830 return SHADER_REQ_SAMPLER_BUF;
831 case TGSI_TEXTURE_SHADOWRECT:
832 case TGSI_TEXTURE_RECT:
833 return SHADER_REQ_SAMPLER_RECT;
834 default:
835 return 0;
836 }
837 }
838
839 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
add_images(struct dump_ctx * ctx,int first,int last,const struct tgsi_declaration_image * img_decl)840 static bool add_images(struct dump_ctx *ctx, int first, int last,
841 const struct tgsi_declaration_image *img_decl)
842 {
843 int i;
844
845 const struct util_format_description *descr = util_format_description(img_decl->Format);
846 if (descr->nr_channels == 2 &&
847 descr->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
848 descr->swizzle[1] == UTIL_FORMAT_SWIZZLE_Y &&
849 descr->swizzle[2] == UTIL_FORMAT_SWIZZLE_0 &&
850 descr->swizzle[3] == UTIL_FORMAT_SWIZZLE_1) {
851 ctx->shader_req_bits |= SHADER_REQ_NV_IMAGE_FORMATS;
852 } else if (img_decl->Format == PIPE_FORMAT_R11G11B10_FLOAT ||
853 img_decl->Format == PIPE_FORMAT_R10G10B10A2_UINT ||
854 img_decl->Format == PIPE_FORMAT_R10G10B10A2_UNORM ||
855 img_decl->Format == PIPE_FORMAT_R16G16B16A16_UNORM||
856 img_decl->Format == PIPE_FORMAT_R16G16B16A16_SNORM)
857 ctx->shader_req_bits |= SHADER_REQ_NV_IMAGE_FORMATS;
858 else if (descr->nr_channels == 1 &&
859 descr->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
860 descr->swizzle[1] == UTIL_FORMAT_SWIZZLE_0 &&
861 descr->swizzle[2] == UTIL_FORMAT_SWIZZLE_0 &&
862 descr->swizzle[3] == UTIL_FORMAT_SWIZZLE_1 &&
863 (descr->channel[0].size == 8 || descr->channel[0].size ==16))
864 ctx->shader_req_bits |= SHADER_REQ_NV_IMAGE_FORMATS;
865
866 for (i = first; i <= last; i++) {
867 ctx->images[i].decl = *img_decl;
868 ctx->images[i].vflag = false;
869 ctx->images_used_mask |= (1 << i);
870
871 if (!samplertype_is_shadow(ctx->images[i].decl.Resource))
872 ctx->shader_req_bits |= samplertype_to_req_bits(ctx->images[i].decl.Resource);
873 }
874
875 if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
876 if (ctx->num_image_arrays) {
877 struct vrend_array *last_array = &ctx->image_arrays[ctx->num_image_arrays - 1];
878 /*
879 * If this set of images is consecutive to the last array,
880 * and has compatible return and decls, then increase the array size.
881 */
882 if ((last_array->first + last_array->array_size == first) &&
883 !memcmp(&ctx->images[last_array->first].decl, &ctx->images[first].decl, sizeof(ctx->images[first].decl)) &&
884 ctx->images[last_array->first].image_return == ctx->images[first].image_return) {
885 last_array->array_size += last - first + 1;
886 return true;
887 }
888 }
889
890 /* allocate a new image array for this range of images */
891 ctx->num_image_arrays++;
892 ctx->image_arrays = realloc(ctx->image_arrays, sizeof(struct vrend_array) * ctx->num_image_arrays);
893 if (!ctx->image_arrays)
894 return false;
895 ctx->image_arrays[ctx->num_image_arrays - 1].first = first;
896 ctx->image_arrays[ctx->num_image_arrays - 1].array_size = last - first + 1;
897 }
898 return true;
899 }
900
901 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
add_sampler_array(struct dump_ctx * ctx,int first,int last)902 static bool add_sampler_array(struct dump_ctx *ctx, int first, int last)
903 {
904 int idx = ctx->num_sampler_arrays;
905 ctx->num_sampler_arrays++;
906 ctx->sampler_arrays = realloc(ctx->sampler_arrays, sizeof(struct vrend_array) * ctx->num_sampler_arrays);
907 if (!ctx->sampler_arrays)
908 return false;
909
910 ctx->sampler_arrays[idx].first = first;
911 ctx->sampler_arrays[idx].array_size = last - first + 1;
912 return true;
913 }
914
lookup_sampler_array(const struct dump_ctx * ctx,int index)915 static int lookup_sampler_array(const struct dump_ctx *ctx, int index)
916 {
917 uint32_t i;
918 for (i = 0; i < ctx->num_sampler_arrays; i++) {
919 int last = ctx->sampler_arrays[i].first + ctx->sampler_arrays[i].array_size - 1;
920 if (index >= ctx->sampler_arrays[i].first &&
921 index <= last) {
922 return ctx->sampler_arrays[i].first;
923 }
924 }
925 return -1;
926 }
927
vrend_shader_lookup_sampler_array(const struct vrend_shader_info * sinfo,int index)928 int vrend_shader_lookup_sampler_array(const struct vrend_shader_info *sinfo, int index)
929 {
930 int i;
931 for (i = 0; i < sinfo->num_sampler_arrays; i++) {
932 int last = sinfo->sampler_arrays[i].first + sinfo->sampler_arrays[i].array_size - 1;
933 if (index >= sinfo->sampler_arrays[i].first &&
934 index <= last) {
935 return sinfo->sampler_arrays[i].first;
936 }
937 }
938 return -1;
939 }
940
941 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
add_samplers(struct dump_ctx * ctx,int first,int last,int sview_type,enum tgsi_return_type sview_rtype)942 static bool add_samplers(struct dump_ctx *ctx, int first, int last, int sview_type, enum tgsi_return_type sview_rtype)
943 {
944 if (sview_rtype == TGSI_RETURN_TYPE_SINT ||
945 sview_rtype == TGSI_RETURN_TYPE_UINT)
946 ctx->shader_req_bits |= SHADER_REQ_INTS;
947
948 for (int i = first; i <= last; i++) {
949 ctx->samplers[i].tgsi_sampler_return = sview_rtype;
950 ctx->samplers[i].tgsi_sampler_type = sview_type;
951 }
952
953 if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
954 if (ctx->num_sampler_arrays) {
955 struct vrend_array *last_array = &ctx->sampler_arrays[ctx->num_sampler_arrays - 1];
956 if ((last_array->first + last_array->array_size == first) &&
957 ctx->samplers[last_array->first].tgsi_sampler_type == sview_type &&
958 ctx->samplers[last_array->first].tgsi_sampler_return == sview_rtype) {
959 last_array->array_size += last - first + 1;
960 return true;
961 }
962 }
963
964 /* allocate a new image array for this range of images */
965 return add_sampler_array(ctx, first, last);
966 }
967 return true;
968 }
969
970 typedef enum
971 {
972 VARYING_SLOT_POS,
973 VARYING_SLOT_COL0, /* COL0 and COL1 must be contiguous */
974 VARYING_SLOT_COL1,
975 VARYING_SLOT_FOGC,
976 VARYING_SLOT_TEX0, /* TEX0-TEX7 must be contiguous */
977 VARYING_SLOT_TEX1,
978 VARYING_SLOT_TEX2,
979 VARYING_SLOT_TEX3,
980 VARYING_SLOT_TEX4,
981 VARYING_SLOT_TEX5,
982 VARYING_SLOT_TEX6,
983 VARYING_SLOT_TEX7,
984 VARYING_SLOT_PSIZ, /* Does not appear in FS */
985 VARYING_SLOT_BFC0, /* Does not appear in FS */
986 VARYING_SLOT_BFC1, /* Does not appear in FS */
987 VARYING_SLOT_EDGE, /* Does not appear in FS */
988 VARYING_SLOT_CLIP_VERTEX, /* Does not appear in FS */
989 VARYING_SLOT_CLIP_DIST0,
990 VARYING_SLOT_CLIP_DIST1,
991 VARYING_SLOT_CULL_DIST0,
992 VARYING_SLOT_CULL_DIST1,
993 VARYING_SLOT_PRIMITIVE_ID, /* Does not appear in VS */
994 VARYING_SLOT_LAYER, /* Appears as VS or GS output */
995 VARYING_SLOT_VIEWPORT, /* Appears as VS or GS output */
996 VARYING_SLOT_FACE, /* FS only */
997 VARYING_SLOT_PNTC, /* FS only */
998 VARYING_SLOT_TESS_LEVEL_OUTER, /* Only appears as TCS output. */
999 VARYING_SLOT_TESS_LEVEL_INNER, /* Only appears as TCS output. */
1000 VARYING_SLOT_BOUNDING_BOX0, /* Only appears as TCS output. */
1001 VARYING_SLOT_BOUNDING_BOX1, /* Only appears as TCS output. */
1002 VARYING_SLOT_VIEW_INDEX,
1003 VARYING_SLOT_VIEWPORT_MASK, /* Does not appear in FS */
1004 VARYING_SLOT_PRIMITIVE_SHADING_RATE = VARYING_SLOT_FACE, /* Does not appear in FS. */
1005
1006 VARYING_SLOT_PRIMITIVE_COUNT = VARYING_SLOT_TESS_LEVEL_OUTER, /* Only appears in MESH. */
1007 VARYING_SLOT_PRIMITIVE_INDICES = VARYING_SLOT_TESS_LEVEL_INNER, /* Only appears in MESH. */
1008 VARYING_SLOT_TASK_COUNT = VARYING_SLOT_BOUNDING_BOX0, /* Only appears in TASK. */
1009
1010 VARYING_SLOT_VAR0 = 32, /* First generic varying slot */
1011 /* the remaining are simply for the benefit of gl_varying_slot_name()
1012 * and not to be construed as an upper bound:
1013 */
1014 VARYING_SLOT_VAR1,
1015 VARYING_SLOT_VAR2,
1016 VARYING_SLOT_VAR3,
1017 VARYING_SLOT_VAR4,
1018 VARYING_SLOT_VAR5,
1019 VARYING_SLOT_VAR6,
1020 VARYING_SLOT_VAR7,
1021 VARYING_SLOT_VAR8,
1022 VARYING_SLOT_VAR9,
1023 VARYING_SLOT_VAR10,
1024 VARYING_SLOT_VAR11,
1025 VARYING_SLOT_VAR12,
1026 VARYING_SLOT_VAR13,
1027 VARYING_SLOT_VAR14,
1028 VARYING_SLOT_VAR15,
1029 VARYING_SLOT_VAR16,
1030 VARYING_SLOT_VAR17,
1031 VARYING_SLOT_VAR18,
1032 VARYING_SLOT_VAR19,
1033 VARYING_SLOT_VAR20,
1034 VARYING_SLOT_VAR21,
1035 VARYING_SLOT_VAR22,
1036 VARYING_SLOT_VAR23,
1037 VARYING_SLOT_VAR24,
1038 VARYING_SLOT_VAR25,
1039 VARYING_SLOT_VAR26,
1040 VARYING_SLOT_VAR27,
1041 VARYING_SLOT_VAR28,
1042 VARYING_SLOT_VAR29,
1043 VARYING_SLOT_VAR30,
1044 VARYING_SLOT_VAR31,
1045 /* Account for the shift without CAP_TEXCOORD in mesa*/
1046 VARYING_SLOT_PATCH0 = VARYING_SLOT_VAR31 + 9
1047 } gl_varying_slot;
1048
1049 static uint32_t
varying_bit_from_semantic_and_index(enum tgsi_semantic semantic,int index)1050 varying_bit_from_semantic_and_index(enum tgsi_semantic semantic, int index)
1051 {
1052 switch (semantic) {
1053 case TGSI_SEMANTIC_POSITION:
1054 return VARYING_SLOT_POS;
1055 case TGSI_SEMANTIC_COLOR:
1056 if (index == 0)
1057 return VARYING_SLOT_COL0;
1058 else
1059 return VARYING_SLOT_COL1;
1060 case TGSI_SEMANTIC_BCOLOR:
1061 if (index == 0)
1062 return VARYING_SLOT_BFC0;
1063 else
1064 return VARYING_SLOT_BFC1;
1065 case TGSI_SEMANTIC_FOG:
1066 return VARYING_SLOT_FOGC;
1067 case TGSI_SEMANTIC_PSIZE:
1068 return VARYING_SLOT_PSIZ;
1069 case TGSI_SEMANTIC_GENERIC:
1070 return VARYING_SLOT_VAR0 + index;
1071 case TGSI_SEMANTIC_FACE:
1072 return VARYING_SLOT_FACE;
1073 case TGSI_SEMANTIC_EDGEFLAG:
1074 return VARYING_SLOT_EDGE;
1075 case TGSI_SEMANTIC_PRIMID:
1076 return VARYING_SLOT_PRIMITIVE_ID;
1077 case TGSI_SEMANTIC_CLIPDIST:
1078 if (index == 0)
1079 return VARYING_SLOT_CLIP_DIST0;
1080 else
1081 return VARYING_SLOT_CLIP_DIST1;
1082 case TGSI_SEMANTIC_CLIPVERTEX:
1083 return VARYING_SLOT_CLIP_VERTEX;
1084 case TGSI_SEMANTIC_TEXCOORD:
1085 assert(index < 8);
1086 return (VARYING_SLOT_TEX0 + index);
1087 case TGSI_SEMANTIC_PCOORD:
1088 return VARYING_SLOT_PNTC;
1089 case TGSI_SEMANTIC_VIEWPORT_INDEX:
1090 return VARYING_SLOT_VIEWPORT;
1091 case TGSI_SEMANTIC_LAYER:
1092 return VARYING_SLOT_LAYER;
1093 case TGSI_SEMANTIC_TESSINNER:
1094 return VARYING_SLOT_TESS_LEVEL_INNER;
1095 case TGSI_SEMANTIC_TESSOUTER:
1096 return VARYING_SLOT_TESS_LEVEL_OUTER;
1097 case TGSI_SEMANTIC_PATCH:
1098 return VARYING_SLOT_PATCH0 + index;
1099 default:
1100 vrend_printf("Warning: Bad TGSI semantic: %d/%d\n", semantic, index);
1101 return 0;
1102 }
1103 }
1104
lookup_image_array_ptr(const struct dump_ctx * ctx,int index)1105 static struct vrend_array *lookup_image_array_ptr(const struct dump_ctx *ctx, int index)
1106 {
1107 uint32_t i;
1108 for (i = 0; i < ctx->num_image_arrays; i++) {
1109 if (index >= ctx->image_arrays[i].first &&
1110 index <= ctx->image_arrays[i].first + ctx->image_arrays[i].array_size - 1) {
1111 return &ctx->image_arrays[i];
1112 }
1113 }
1114 return NULL;
1115 }
1116
lookup_image_array(const struct dump_ctx * ctx,int index)1117 static int lookup_image_array(const struct dump_ctx *ctx, int index)
1118 {
1119 struct vrend_array *image = lookup_image_array_ptr(ctx, index);
1120 return image ? image->first : -1;
1121 }
1122
1123 static boolean
iter_decls(struct tgsi_iterate_context * iter,struct tgsi_full_declaration * decl)1124 iter_decls(struct tgsi_iterate_context *iter,
1125 struct tgsi_full_declaration *decl)
1126 {
1127 struct dump_ctx *ctx = (struct dump_ctx *)iter;
1128 switch (decl->Declaration.File) {
1129 case TGSI_FILE_INPUT:
1130 /* Tag used semantic fog inputs */
1131 if (decl->Semantic.Name == TGSI_SEMANTIC_FOG) {
1132 ctx->fog_input_mask |= (1 << decl->Semantic.Index);
1133 }
1134
1135 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT) {
1136 for (uint32_t j = 0; j < ctx->num_inputs; j++) {
1137 if (ctx->inputs[j].name == decl->Semantic.Name &&
1138 ctx->inputs[j].sid == decl->Semantic.Index &&
1139 ctx->inputs[j].first == decl->Range.First)
1140 return true;
1141 }
1142 ctx->inputs[ctx->num_inputs].name = decl->Semantic.Name;
1143 ctx->inputs[ctx->num_inputs].first = decl->Range.First;
1144 ctx->inputs[ctx->num_inputs].last = decl->Range.Last;
1145 ctx->num_inputs++;
1146 }
1147 break;
1148
1149 case TGSI_FILE_OUTPUT:
1150 if (decl->Semantic.Name == TGSI_SEMANTIC_FOG) {
1151 ctx->fog_output_mask |= (1 << decl->Semantic.Index);
1152 }
1153 break;
1154
1155 default:
1156 break;
1157 }
1158 return true;
1159 }
1160
logiop_require_inout(const struct vrend_shader_key * key)1161 static bool logiop_require_inout(const struct vrend_shader_key *key)
1162 {
1163 if (!key->fs.logicop_enabled)
1164 return false;
1165
1166 switch (key->fs.logicop_func) {
1167 case PIPE_LOGICOP_CLEAR:
1168 case PIPE_LOGICOP_SET:
1169 case PIPE_LOGICOP_COPY:
1170 case PIPE_LOGICOP_COPY_INVERTED:
1171 return false;
1172 default:
1173 return true;
1174 }
1175 }
1176
get_type(uint32_t signed_int_mask,uint32_t unsigned_int_mask,int bit)1177 static enum vec_type get_type(uint32_t signed_int_mask,
1178 uint32_t unsigned_int_mask,
1179 int bit)
1180 {
1181 if (signed_int_mask & (1 << bit))
1182 return VEC_INT;
1183 else if (unsigned_int_mask & (1 << bit))
1184 return VEC_UINT;
1185 else
1186 return VEC_FLOAT;
1187 }
1188
1189 static struct vrend_shader_io *
find_overlapping_io(struct vrend_shader_io io[static64],uint32_t num_io,const struct tgsi_full_declaration * decl)1190 find_overlapping_io(struct vrend_shader_io io[static 64],
1191 uint32_t num_io,
1192 const struct tgsi_full_declaration *decl)
1193 {
1194 for (uint32_t j = 0; j < num_io - 1; j++) {
1195 if (io[j].interpolate == decl->Interp.Interpolate &&
1196 io[j].name == decl->Semantic.Name &&
1197 ((io[j].first <= decl->Range.First &&
1198 io[j].last > decl->Range.First) ||
1199 (io[j].first < decl->Range.Last &&
1200 io[j].last >= decl->Range.Last))) {
1201 return &io[j];
1202 }
1203 }
1204 return NULL;
1205 }
1206
1207 static void
map_overlapping_io_array(struct vrend_shader_io io[static64],struct vrend_shader_io * new_io,uint32_t num_io,const struct tgsi_full_declaration * decl)1208 map_overlapping_io_array(struct vrend_shader_io io[static 64],
1209 struct vrend_shader_io *new_io,
1210 uint32_t num_io,
1211 const struct tgsi_full_declaration *decl)
1212 {
1213 struct vrend_shader_io *overlap_io = find_overlapping_io(io, num_io, decl);
1214 if (overlap_io && !overlap_io->needs_override) {
1215 int delta = new_io->first - overlap_io->first;
1216 if (delta >= 0) {
1217 new_io->array_offset = delta;
1218 new_io->overlapping_array = overlap_io;
1219 overlap_io->last = MAX2(overlap_io->last, new_io->last);
1220 } else if (delta < 0) {
1221 overlap_io->overlapping_array = new_io;
1222 overlap_io->array_offset = -delta;
1223 new_io->last = MAX2(overlap_io->last, new_io->last);
1224 }
1225 overlap_io->usage_mask |= new_io->usage_mask;
1226 new_io->usage_mask = overlap_io->usage_mask;
1227 }
1228 }
1229
1230 static boolean
iter_declaration(struct tgsi_iterate_context * iter,struct tgsi_full_declaration * decl)1231 iter_declaration(struct tgsi_iterate_context *iter,
1232 struct tgsi_full_declaration *decl)
1233 {
1234 struct dump_ctx *ctx = (struct dump_ctx *)iter;
1235 int i;
1236 int color_offset = 0;
1237 const char *name_prefix;
1238 bool add_two_side = false;
1239
1240 switch (decl->Declaration.File) {
1241 case TGSI_FILE_INPUT:
1242 for (uint32_t j = 0; j < ctx->num_inputs; j++) {
1243 if (ctx->inputs[j].name == decl->Semantic.Name &&
1244 ctx->inputs[j].sid == decl->Semantic.Index &&
1245 ctx->inputs[j].first == decl->Range.First &&
1246 ((!decl->Declaration.Array && ctx->inputs[j].array_id == 0) ||
1247 (ctx->inputs[j].array_id == decl->Array.ArrayID))) {
1248 return true;
1249 }
1250 }
1251
1252 i = ctx->num_inputs++;
1253 if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) {
1254 vrend_printf( "Number of inputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->inputs));
1255 return false;
1256 }
1257
1258 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
1259 ctx->attrib_input_mask |= (1 << decl->Range.First);
1260 ctx->inputs[i].type = get_type(ctx->key->vs.attrib_signed_int_bitmask,
1261 ctx->key->vs.attrib_unsigned_int_bitmask,
1262 decl->Range.First);
1263 }
1264 ctx->inputs[i].name = decl->Semantic.Name;
1265 ctx->inputs[i].sid = decl->Semantic.Index;
1266 ctx->inputs[i].interpolate = decl->Interp.Interpolate;
1267 ctx->inputs[i].location = decl->Interp.Location;
1268 ctx->inputs[i].first = decl->Range.First;
1269 ctx->inputs[i].last = decl->Range.Last;
1270 ctx->inputs[i].array_id = decl->Declaration.Array ? decl->Array.ArrayID : 0;
1271 ctx->inputs[i].usage_mask = decl->Declaration.UsageMask;
1272 ctx->inputs[i].num_components = 4;
1273
1274 ctx->inputs[i].glsl_predefined_no_emit = false;
1275 ctx->inputs[i].glsl_no_index = false;
1276 ctx->inputs[i].override_no_wm = ctx->inputs[i].num_components == 1;
1277 ctx->inputs[i].glsl_gl_block = false;
1278 ctx->inputs[i].overlapping_array = NULL;
1279
1280 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1281 if (decl->Interp.Location == TGSI_INTERPOLATE_LOC_SAMPLE) {
1282 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
1283 ctx->has_sample_input = true;
1284 }
1285 if (decl->Interp.Interpolate == TGSI_INTERPOLATE_LINEAR && ctx->cfg->use_gles &&
1286 ctx->cfg->has_nopersective) {
1287 ctx->shader_req_bits |= SHADER_REQ_SHADER_NOPERSPECTIVE_INTERPOLATION;
1288 ctx->has_noperspective = true;
1289 }
1290 }
1291
1292 map_overlapping_io_array(ctx->inputs, &ctx->inputs[i], ctx->num_inputs, decl);
1293
1294 if (!ctx->inputs[i].glsl_predefined_no_emit) {
1295
1296 /* If the output of the previous shader contained arrays we
1297 * have to check whether a non-array input here should be part
1298 * of an array */
1299 for (uint32_t j = 0; j < ctx->key->in_arrays.num_arrays; j++) {
1300 const struct vrend_shader_io_array *array = &ctx->key->in_arrays.layout[j];
1301
1302 if (array->name == decl->Semantic.Name &&
1303 array->sid <= decl->Semantic.Index &&
1304 array->sid + array->size >= decl->Semantic.Index) {
1305 ctx->inputs[i].sid = array->sid;
1306 ctx->inputs[i].last = MAX2(ctx->inputs[i].first + array->size, ctx->inputs[i].last);
1307 break;
1308 }
1309 }
1310 }
1311
1312 if (ctx->inputs[i].first != ctx->inputs[i].last)
1313 ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
1314
1315 name_prefix = get_stage_input_name_prefix(ctx, iter->processor.Processor);
1316
1317 switch (ctx->inputs[i].name) {
1318 case TGSI_SEMANTIC_COLOR:
1319 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1320 if (ctx->glsl_ver_required < 140) {
1321 if (decl->Semantic.Index == 0)
1322 name_prefix = "gl_Color";
1323 else if (decl->Semantic.Index == 1)
1324 name_prefix = "gl_SecondaryColor";
1325 else
1326 vrend_printf( "got illegal color semantic index %d\n", decl->Semantic.Index);
1327 ctx->inputs[i].glsl_no_index = true;
1328 } else {
1329 if (ctx->key->color_two_side) {
1330 int j = ctx->num_inputs++;
1331 if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) {
1332 vrend_printf( "Number of inputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->inputs));
1333 return false;
1334 }
1335
1336 ctx->inputs[j].name = TGSI_SEMANTIC_BCOLOR;
1337 ctx->inputs[j].sid = decl->Semantic.Index;
1338 ctx->inputs[j].interpolate = decl->Interp.Interpolate;
1339 ctx->inputs[j].location = decl->Interp.Location;
1340 ctx->inputs[j].first = decl->Range.First;
1341 ctx->inputs[j].last = decl->Range.Last;
1342 ctx->inputs[j].glsl_predefined_no_emit = false;
1343 ctx->inputs[j].glsl_no_index = false;
1344 ctx->inputs[j].override_no_wm = false;
1345
1346 ctx->color_in_mask |= (1 << decl->Semantic.Index);
1347
1348 if (ctx->front_face_emitted == false) {
1349 int k = ctx->num_inputs++;
1350 if (ctx->num_inputs >= ARRAY_SIZE(ctx->inputs)) {
1351 vrend_printf( "Number of inputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->inputs));
1352 return false;
1353 }
1354
1355 ctx->inputs[k].name = TGSI_SEMANTIC_FACE;
1356 ctx->inputs[k].sid = 0;
1357 ctx->inputs[k].interpolate = TGSI_INTERPOLATE_CONSTANT;
1358 ctx->inputs[k].location = TGSI_INTERPOLATE_LOC_CENTER;
1359 ctx->inputs[k].first = 0;
1360 ctx->inputs[k].override_no_wm = false;
1361 ctx->inputs[k].glsl_predefined_no_emit = true;
1362 ctx->inputs[k].glsl_no_index = true;
1363 }
1364 add_two_side = true;
1365 }
1366 }
1367 }
1368 break;
1369 case TGSI_SEMANTIC_PRIMID:
1370 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
1371 name_prefix = "gl_PrimitiveIDIn";
1372 ctx->inputs[i].glsl_predefined_no_emit = true;
1373 ctx->inputs[i].glsl_no_index = true;
1374 ctx->inputs[i].override_no_wm = true;
1375 ctx->shader_req_bits |= SHADER_REQ_INTS;
1376 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1377 name_prefix = "gl_PrimitiveID";
1378 ctx->inputs[i].glsl_predefined_no_emit = true;
1379 ctx->inputs[i].glsl_no_index = true;
1380 ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
1381 ctx->shader_req_bits |= SHADER_REQ_GEOMETRY_SHADER;
1382 }
1383 break;
1384 case TGSI_SEMANTIC_VIEWPORT_INDEX:
1385 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1386 ctx->inputs[i].glsl_predefined_no_emit = true;
1387 ctx->inputs[i].glsl_no_index = true;
1388 ctx->inputs[i].is_int = true;
1389 ctx->inputs[i].type = VEC_INT;
1390 ctx->inputs[i].override_no_wm = true;
1391 name_prefix = "gl_ViewportIndex";
1392 if (ctx->glsl_ver_required >= 140)
1393 ctx->shader_req_bits |= SHADER_REQ_LAYER;
1394 if (ctx->cfg->use_gles)
1395 ctx->shader_req_bits |= SHADER_REQ_VIEWPORT_IDX;
1396 }
1397 break;
1398 case TGSI_SEMANTIC_LAYER:
1399 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1400 name_prefix = "gl_Layer";
1401 ctx->inputs[i].glsl_predefined_no_emit = true;
1402 ctx->inputs[i].glsl_no_index = true;
1403 ctx->inputs[i].is_int = true;
1404 ctx->inputs[i].type = VEC_INT;
1405 ctx->inputs[i].override_no_wm = true;
1406 ctx->shader_req_bits |= SHADER_REQ_LAYER;
1407 }
1408 break;
1409 case TGSI_SEMANTIC_PSIZE:
1410 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
1411 iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
1412 iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
1413 name_prefix = "gl_PointSize";
1414 ctx->inputs[i].glsl_predefined_no_emit = true;
1415 ctx->inputs[i].glsl_no_index = true;
1416 ctx->inputs[i].override_no_wm = true;
1417 ctx->inputs[i].glsl_gl_block = true;
1418 ctx->shader_req_bits |= SHADER_REQ_PSIZE;
1419 ctx->has_pointsize_input = true;
1420 }
1421 break;
1422 case TGSI_SEMANTIC_CLIPDIST:
1423 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
1424 iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
1425 iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
1426 name_prefix = "gl_ClipDistance";
1427 ctx->inputs[i].glsl_predefined_no_emit = true;
1428 ctx->inputs[i].glsl_no_index = true;
1429 ctx->inputs[i].glsl_gl_block = true;
1430 ctx->num_in_clip_dist += 4 * (ctx->inputs[i].last - ctx->inputs[i].first + 1);
1431 ctx->shader_req_bits |= SHADER_REQ_CLIP_DISTANCE;
1432 if (ctx->inputs[i].last != ctx->inputs[i].first)
1433 ctx->guest_sent_io_arrays = true;
1434 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1435 name_prefix = "gl_ClipDistance";
1436 ctx->inputs[i].glsl_predefined_no_emit = true;
1437 ctx->inputs[i].glsl_no_index = true;
1438 ctx->num_in_clip_dist += 4 * (ctx->inputs[i].last - ctx->inputs[i].first + 1);
1439 ctx->shader_req_bits |= SHADER_REQ_CLIP_DISTANCE;
1440 if (ctx->inputs[i].last != ctx->inputs[i].first)
1441 ctx->guest_sent_io_arrays = true;
1442 }
1443 break;
1444 case TGSI_SEMANTIC_POSITION:
1445 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
1446 iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
1447 iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
1448 name_prefix = "gl_Position";
1449 ctx->inputs[i].glsl_predefined_no_emit = true;
1450 ctx->inputs[i].glsl_no_index = true;
1451 ctx->inputs[i].glsl_gl_block = true;
1452 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1453 if (ctx->cfg->use_gles && ctx->fs_integer_pixel_center) {
1454 name_prefix = "(gl_FragCoord - vec4(0.5, 0.5, 0.0, 0.0))";
1455 } else
1456 name_prefix = "gl_FragCoord";
1457 ctx->inputs[i].glsl_predefined_no_emit = true;
1458 ctx->inputs[i].glsl_no_index = true;
1459 }
1460 break;
1461 case TGSI_SEMANTIC_FACE:
1462 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1463 if (ctx->front_face_emitted) {
1464 ctx->num_inputs--;
1465 return true;
1466 }
1467 name_prefix = "gl_FrontFacing";
1468 ctx->inputs[i].glsl_predefined_no_emit = true;
1469 ctx->inputs[i].glsl_no_index = true;
1470 ctx->front_face_emitted = true;
1471 }
1472 break;
1473 case TGSI_SEMANTIC_PCOORD:
1474 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1475 if (ctx->cfg->use_gles) {
1476 name_prefix = "vec4(gl_PointCoord.x, mix(1.0 - gl_PointCoord.y, gl_PointCoord.y, clamp(winsys_adjust_y, 0.0, 1.0)), 0.0, 1.0)";
1477 ctx->glsl_strbufs.required_sysval_uniform_decls |= BIT(UNIFORM_WINSYS_ADJUST_Y);
1478 } else
1479 name_prefix = "vec4(gl_PointCoord, 0.0, 1.0)";
1480 ctx->inputs[i].glsl_predefined_no_emit = true;
1481 ctx->inputs[i].glsl_no_index = true;
1482 ctx->inputs[i].num_components = 4;
1483 ctx->inputs[i].usage_mask = 0xf;
1484 }
1485 break;
1486 case TGSI_SEMANTIC_PATCH:
1487 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL)
1488 name_prefix = "patch";
1489 /* fallthrough */
1490 case TGSI_SEMANTIC_GENERIC:
1491 case TGSI_SEMANTIC_TEXCOORD:
1492 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1493 if (ctx->key->fs.coord_replace & (1 << ctx->inputs[i].sid)) {
1494 if (ctx->cfg->use_gles) {
1495 name_prefix = "vec4(gl_PointCoord.x, mix(1.0 - gl_PointCoord.y, gl_PointCoord.y, clamp(winsys_adjust_y, 0.0, 1.0)), 0.0, 1.0)";
1496 ctx->glsl_strbufs.required_sysval_uniform_decls |= BIT(UNIFORM_WINSYS_ADJUST_Y);
1497 } else
1498 name_prefix = "vec4(gl_PointCoord, 0.0, 1.0)";
1499 ctx->inputs[i].glsl_predefined_no_emit = true;
1500 ctx->inputs[i].glsl_no_index = true;
1501 ctx->inputs[i].num_components = 4;
1502 ctx->inputs[i].usage_mask = 0xf;
1503 break;
1504 }
1505 }
1506 if (ctx->inputs[i].first != ctx->inputs[i].last ||
1507 ctx->inputs[i].array_id > 0) {
1508 ctx->guest_sent_io_arrays = true;
1509 if (!ctx->cfg->use_gles &&
1510 (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
1511 ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
1512 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL)) {
1513 ctx->shader_req_bits |= SHADER_REQ_ARRAYS_OF_ARRAYS;
1514 }
1515 }
1516 break;
1517 default:
1518 vrend_printf("unhandled input semantic: %x\n", ctx->inputs[i].name);
1519 break;
1520 }
1521
1522 if (ctx->inputs[i].glsl_no_index)
1523 snprintf(ctx->inputs[i].glsl_name, 128, "%s", name_prefix);
1524 else {
1525 if (ctx->inputs[i].name == TGSI_SEMANTIC_FOG){
1526 ctx->inputs[i].usage_mask = 0xf;
1527 ctx->inputs[i].num_components = 4;
1528 ctx->inputs[i].override_no_wm = false;
1529 snprintf(ctx->inputs[i].glsl_name, 128, "%s_f%d", name_prefix, ctx->inputs[i].sid);
1530 } else if (ctx->inputs[i].name == TGSI_SEMANTIC_COLOR)
1531 snprintf(ctx->inputs[i].glsl_name, 128, "%s_c%d", name_prefix, ctx->inputs[i].sid);
1532 else if (ctx->inputs[i].name == TGSI_SEMANTIC_BCOLOR)
1533 snprintf(ctx->inputs[i].glsl_name, 128, "%s_bc%d", name_prefix, ctx->inputs[i].sid);
1534 else if (ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC)
1535 snprintf(ctx->inputs[i].glsl_name, 128, "%s_g%d", name_prefix, ctx->inputs[i].sid);
1536 else if (ctx->inputs[i].name == TGSI_SEMANTIC_PATCH)
1537 snprintf(ctx->inputs[i].glsl_name, 128, "%s%d", name_prefix, ctx->inputs[i].sid);
1538 else if (ctx->inputs[i].name == TGSI_SEMANTIC_TEXCOORD)
1539 snprintf(ctx->inputs[i].glsl_name, 64, "%s_t%d", name_prefix, ctx->inputs[i].sid);
1540 else
1541 snprintf(ctx->inputs[i].glsl_name, 128, "%s_%d", name_prefix, ctx->inputs[i].first);
1542 }
1543 if (add_two_side) {
1544 snprintf(ctx->inputs[i + 1].glsl_name, 128, "%s_bc%d", name_prefix, ctx->inputs[i + 1].sid);
1545 if (!ctx->front_face_emitted) {
1546 snprintf(ctx->inputs[i + 2].glsl_name, 128, "%s", "gl_FrontFacing");
1547 ctx->front_face_emitted = true;
1548 }
1549 }
1550 break;
1551 case TGSI_FILE_OUTPUT:
1552 for (uint32_t j = 0; j < ctx->num_outputs; j++) {
1553 if (ctx->outputs[j].name == decl->Semantic.Name &&
1554 ctx->outputs[j].sid == decl->Semantic.Index &&
1555 ctx->outputs[j].first == decl->Range.First &&
1556 ((!decl->Declaration.Array && ctx->outputs[j].array_id == 0) ||
1557 (ctx->outputs[j].array_id == decl->Array.ArrayID)))
1558 return true;
1559 }
1560 i = ctx->num_outputs++;
1561 if (ctx->num_outputs > ARRAY_SIZE(ctx->outputs)) {
1562 vrend_printf( "Number of outputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->outputs));
1563 return false;
1564 }
1565
1566 ctx->outputs[i].name = decl->Semantic.Name;
1567 ctx->outputs[i].sid = decl->Semantic.Index;
1568 ctx->outputs[i].interpolate = decl->Interp.Interpolate;
1569 ctx->outputs[i].invariant = decl->Declaration.Invariant;
1570 ctx->outputs[i].precise = false;
1571 ctx->outputs[i].first = decl->Range.First;
1572 ctx->outputs[i].last = decl->Range.Last;
1573 ctx->outputs[i].array_id = decl->Declaration.Array ? decl->Array.ArrayID : 0;
1574 ctx->outputs[i].usage_mask = decl->Declaration.UsageMask;
1575 ctx->outputs[i].num_components = 4;
1576 ctx->outputs[i].glsl_predefined_no_emit = false;
1577 ctx->outputs[i].glsl_no_index = false;
1578 ctx->outputs[i].override_no_wm = ctx->outputs[i].num_components == 1;
1579 ctx->outputs[i].is_int = false;
1580 ctx->outputs[i].fbfetch_used = false;
1581 ctx->outputs[i].overlapping_array = NULL;
1582
1583 map_overlapping_io_array(ctx->outputs, &ctx->outputs[i], ctx->num_outputs, decl);
1584
1585 name_prefix = get_stage_output_name_prefix(iter->processor.Processor);
1586
1587 switch (ctx->outputs[i].name) {
1588 case TGSI_SEMANTIC_POSITION:
1589 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX ||
1590 iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
1591 iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
1592 iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
1593 if (ctx->outputs[i].first > 0)
1594 vrend_printf("Illegal position input\n");
1595 name_prefix = "gl_Position";
1596 ctx->outputs[i].glsl_predefined_no_emit = true;
1597 ctx->outputs[i].glsl_no_index = true;
1598 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL)
1599 ctx->outputs[i].glsl_gl_block = true;
1600 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1601 name_prefix = "gl_FragDepth";
1602 ctx->outputs[i].glsl_predefined_no_emit = true;
1603 ctx->outputs[i].glsl_no_index = true;
1604 ctx->outputs[i].override_no_wm = true;
1605 }
1606 break;
1607 case TGSI_SEMANTIC_STENCIL:
1608 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1609 name_prefix = "gl_FragStencilRefARB";
1610 ctx->outputs[i].glsl_predefined_no_emit = true;
1611 ctx->outputs[i].glsl_no_index = true;
1612 ctx->outputs[i].override_no_wm = true;
1613 ctx->outputs[i].is_int = true;
1614 ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_STENCIL_EXPORT);
1615 }
1616 break;
1617 case TGSI_SEMANTIC_CLIPDIST:
1618 ctx->shader_req_bits |= SHADER_REQ_CLIP_DISTANCE;
1619 name_prefix = "gl_ClipDistance";
1620 ctx->outputs[i].glsl_predefined_no_emit = true;
1621 ctx->outputs[i].glsl_no_index = true;
1622 ctx->num_out_clip_dist += 4 * (ctx->outputs[i].last - ctx->outputs[i].first + 1);
1623 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX &&
1624 (ctx->key->gs_present || ctx->key->tcs_present))
1625 ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
1626 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL)
1627 ctx->outputs[i].glsl_gl_block = true;
1628 if (ctx->outputs[i].last != ctx->outputs[i].first)
1629 ctx->guest_sent_io_arrays = true;
1630 break;
1631 case TGSI_SEMANTIC_CLIPVERTEX:
1632 ctx->outputs[i].override_no_wm = true;
1633 ctx->outputs[i].invariant = false;
1634 if (ctx->glsl_ver_required >= 140) {
1635 ctx->has_clipvertex = true;
1636 name_prefix = get_stage_output_name_prefix(iter->processor.Processor);
1637 } else {
1638 name_prefix = "gl_ClipVertex";
1639 ctx->outputs[i].glsl_predefined_no_emit = true;
1640 ctx->outputs[i].glsl_no_index = true;
1641 }
1642 break;
1643 case TGSI_SEMANTIC_SAMPLEMASK:
1644 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1645 ctx->outputs[i].glsl_predefined_no_emit = true;
1646 ctx->outputs[i].glsl_no_index = true;
1647 ctx->outputs[i].override_no_wm = true;
1648 ctx->outputs[i].is_int = true;
1649 ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_SAMPLE_SHADING);
1650 name_prefix = "gl_SampleMask";
1651 break;
1652 }
1653 break;
1654 case TGSI_SEMANTIC_COLOR:
1655 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1656 ctx->outputs[i].type = get_type(ctx->key->fs.cbufs_signed_int_bitmask,
1657 ctx->key->fs.cbufs_unsigned_int_bitmask,
1658 ctx->outputs[i].sid);
1659 name_prefix = ctx->key->fs.logicop_enabled ? "fsout_tmp" : "fsout";
1660 } else {
1661 if (ctx->glsl_ver_required < 140) {
1662 ctx->outputs[i].glsl_no_index = true;
1663 if (ctx->outputs[i].sid == 0)
1664 name_prefix = "gl_FrontColor";
1665 else if (ctx->outputs[i].sid == 1)
1666 name_prefix = "gl_FrontSecondaryColor";
1667 } else {
1668 ctx->color_out_mask |= (1 << decl->Semantic.Index);
1669 }
1670 }
1671 ctx->outputs[i].override_no_wm = false;
1672 break;
1673 case TGSI_SEMANTIC_BCOLOR:
1674 if (ctx->glsl_ver_required < 140) {
1675 ctx->outputs[i].glsl_no_index = true;
1676 if (ctx->outputs[i].sid == 0)
1677 name_prefix = "gl_BackColor";
1678 else if (ctx->outputs[i].sid == 1)
1679 name_prefix = "gl_BackSecondaryColor";
1680 } else {
1681 ctx->outputs[i].override_no_wm = false;
1682 ctx->color_out_mask |= (1 << decl->Semantic.Index) << 2;
1683 }
1684 break;
1685 case TGSI_SEMANTIC_PSIZE:
1686 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX ||
1687 iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
1688 iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
1689 iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
1690 ctx->outputs[i].glsl_predefined_no_emit = true;
1691 ctx->outputs[i].glsl_no_index = true;
1692 ctx->outputs[i].override_no_wm = true;
1693 ctx->shader_req_bits |= SHADER_REQ_PSIZE;
1694 name_prefix = "gl_PointSize";
1695 ctx->has_pointsize_output = true;
1696 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL)
1697 ctx->outputs[i].glsl_gl_block = true;
1698 }
1699 break;
1700 case TGSI_SEMANTIC_LAYER:
1701 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
1702 ctx->outputs[i].glsl_predefined_no_emit = true;
1703 ctx->outputs[i].glsl_no_index = true;
1704 ctx->outputs[i].override_no_wm = true;
1705 ctx->outputs[i].is_int = true;
1706 name_prefix = "gl_Layer";
1707 }
1708 break;
1709 case TGSI_SEMANTIC_PRIMID:
1710 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
1711 ctx->outputs[i].glsl_predefined_no_emit = true;
1712 ctx->outputs[i].glsl_no_index = true;
1713 ctx->outputs[i].override_no_wm = true;
1714 ctx->outputs[i].is_int = true;
1715 name_prefix = "gl_PrimitiveID";
1716 }
1717 break;
1718 case TGSI_SEMANTIC_VIEWPORT_INDEX:
1719 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
1720 ctx->outputs[i].glsl_predefined_no_emit = true;
1721 ctx->outputs[i].glsl_no_index = true;
1722 ctx->outputs[i].override_no_wm = true;
1723 ctx->outputs[i].is_int = true;
1724 name_prefix = "gl_ViewportIndex";
1725 if (ctx->glsl_ver_required >= 140 || ctx->cfg->use_gles)
1726 ctx->shader_req_bits |= SHADER_REQ_VIEWPORT_IDX;
1727 }
1728 break;
1729 case TGSI_SEMANTIC_TESSOUTER:
1730 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL) {
1731 ctx->outputs[i].glsl_predefined_no_emit = true;
1732 ctx->outputs[i].glsl_no_index = true;
1733 ctx->outputs[i].override_no_wm = true;
1734 name_prefix = "gl_TessLevelOuter";
1735 }
1736 break;
1737 case TGSI_SEMANTIC_TESSINNER:
1738 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL) {
1739 ctx->outputs[i].glsl_predefined_no_emit = true;
1740 ctx->outputs[i].glsl_no_index = true;
1741 ctx->outputs[i].override_no_wm = true;
1742 name_prefix = "gl_TessLevelInner";
1743 }
1744 break;
1745 case TGSI_SEMANTIC_PATCH:
1746 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL)
1747 name_prefix = "patch";
1748 /* fallthrough */
1749 case TGSI_SEMANTIC_GENERIC:
1750 case TGSI_SEMANTIC_TEXCOORD:
1751 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX)
1752 if (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC)
1753 color_offset = -1;
1754
1755 if (ctx->outputs[i].first != ctx->outputs[i].last ||
1756 ctx->outputs[i].array_id > 0) {
1757 ctx->guest_sent_io_arrays = true;
1758
1759 if (!ctx->cfg->use_gles &&
1760 (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
1761 ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
1762 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL)) {
1763 ctx->shader_req_bits |= SHADER_REQ_ARRAYS_OF_ARRAYS;
1764 }
1765 }
1766 break;
1767 default:
1768 vrend_printf("unhandled output semantic: %x\n", ctx->outputs[i].name);
1769 break;
1770 }
1771
1772 if (ctx->outputs[i].glsl_no_index)
1773 snprintf(ctx->outputs[i].glsl_name, 64, "%s", name_prefix);
1774 else {
1775 if (ctx->outputs[i].name == TGSI_SEMANTIC_FOG) {
1776 ctx->outputs[i].usage_mask = 0xf;
1777 ctx->outputs[i].num_components = 4;
1778 ctx->outputs[i].override_no_wm = false;
1779 snprintf(ctx->outputs[i].glsl_name, 64, "%s_f%d", name_prefix, ctx->outputs[i].sid);
1780 } else if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR)
1781 snprintf(ctx->outputs[i].glsl_name, 64, "%s_c%d", name_prefix, ctx->outputs[i].sid);
1782 else if (ctx->outputs[i].name == TGSI_SEMANTIC_BCOLOR)
1783 snprintf(ctx->outputs[i].glsl_name, 64, "%s_bc%d", name_prefix, ctx->outputs[i].sid);
1784 else if (ctx->outputs[i].name == TGSI_SEMANTIC_PATCH)
1785 snprintf(ctx->outputs[i].glsl_name, 64, "%s%d", name_prefix, ctx->outputs[i].sid);
1786 else if (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC)
1787 snprintf(ctx->outputs[i].glsl_name, 64, "%s_g%d", name_prefix, ctx->outputs[i].sid);
1788 else if (ctx->outputs[i].name == TGSI_SEMANTIC_TEXCOORD)
1789 snprintf(ctx->outputs[i].glsl_name, 64, "%s_t%d", name_prefix, ctx->outputs[i].sid);
1790 else
1791 snprintf(ctx->outputs[i].glsl_name, 64, "%s_%d", name_prefix, ctx->outputs[i].first + color_offset);
1792
1793 }
1794 break;
1795 case TGSI_FILE_TEMPORARY:
1796 if (!allocate_temp_range(&ctx->temp_ranges, &ctx->num_temp_ranges, decl->Range.First, decl->Range.Last,
1797 decl->Array.ArrayID))
1798 return false;
1799 break;
1800 case TGSI_FILE_SAMPLER:
1801 ctx->samplers_used |= (1 << decl->Range.Last);
1802 break;
1803 case TGSI_FILE_SAMPLER_VIEW:
1804 if (decl->Range.Last >= ARRAY_SIZE(ctx->samplers)) {
1805 vrend_printf( "Sampler view exceeded, max is %lu\n", ARRAY_SIZE(ctx->samplers));
1806 return false;
1807 }
1808 if (!add_samplers(ctx, decl->Range.First, decl->Range.Last, decl->SamplerView.Resource, decl->SamplerView.ReturnTypeX))
1809 return false;
1810 break;
1811 case TGSI_FILE_IMAGE:
1812 ctx->shader_req_bits |= SHADER_REQ_IMAGE_LOAD_STORE;
1813 if (decl->Range.Last >= ARRAY_SIZE(ctx->images)) {
1814 vrend_printf( "Image view exceeded, max is %lu\n", ARRAY_SIZE(ctx->images));
1815 return false;
1816 }
1817 if (!add_images(ctx, decl->Range.First, decl->Range.Last, &decl->Image))
1818 return false;
1819 break;
1820 case TGSI_FILE_BUFFER:
1821 if (decl->Range.First >= 32) {
1822 vrend_printf( "Buffer view exceeded, max is 32\n");
1823 return false;
1824 }
1825 ctx->ssbo_used_mask |= (1 << decl->Range.First);
1826 if (decl->Declaration.Atomic) {
1827 if (decl->Range.First < ctx->ssbo_atomic_array_base)
1828 ctx->ssbo_atomic_array_base = decl->Range.First;
1829 ctx->ssbo_atomic_mask |= (1 << decl->Range.First);
1830 } else {
1831 if (decl->Range.First < ctx->ssbo_array_base)
1832 ctx->ssbo_array_base = decl->Range.First;
1833 }
1834 break;
1835 case TGSI_FILE_CONSTANT:
1836 if (decl->Declaration.Dimension && decl->Dim.Index2D != 0) {
1837 if (decl->Dim.Index2D > 31) {
1838 vrend_printf( "Number of uniforms exceeded, max is 32\n");
1839 return false;
1840 }
1841 if (ctx->ubo_used_mask & (1 << decl->Dim.Index2D)) {
1842 vrend_printf( "UBO #%d is already defined\n", decl->Dim.Index2D);
1843 return false;
1844 }
1845 ctx->ubo_used_mask |= (1 << decl->Dim.Index2D);
1846 ctx->ubo_sizes[decl->Dim.Index2D] = decl->Range.Last + 1;
1847 } else {
1848 /* if we have a normal single const set then ubo base should be 1 */
1849 ctx->ubo_base = 1;
1850 if (decl->Range.Last) {
1851 if (decl->Range.Last + 1 > ctx->num_consts)
1852 ctx->num_consts = decl->Range.Last + 1;
1853 } else
1854 ctx->num_consts++;
1855 }
1856 break;
1857 case TGSI_FILE_ADDRESS:
1858 ctx->num_address = decl->Range.Last + 1;
1859 break;
1860 case TGSI_FILE_SYSTEM_VALUE:
1861 i = ctx->num_system_values++;
1862 if (ctx->num_system_values > ARRAY_SIZE(ctx->system_values)) {
1863 vrend_printf( "Number of system values exceeded, max is %lu\n", ARRAY_SIZE(ctx->system_values));
1864 return false;
1865 }
1866
1867 ctx->system_values[i].name = decl->Semantic.Name;
1868 ctx->system_values[i].sid = decl->Semantic.Index;
1869 ctx->system_values[i].glsl_predefined_no_emit = true;
1870 ctx->system_values[i].glsl_no_index = true;
1871 ctx->system_values[i].override_no_wm = true;
1872 ctx->system_values[i].first = decl->Range.First;
1873 if (decl->Semantic.Name == TGSI_SEMANTIC_INSTANCEID) {
1874 name_prefix = "gl_InstanceID";
1875 ctx->shader_req_bits |= SHADER_REQ_INSTANCE_ID | SHADER_REQ_INTS;
1876 } else if (decl->Semantic.Name == TGSI_SEMANTIC_VERTEXID) {
1877 name_prefix = "gl_VertexID";
1878 ctx->shader_req_bits |= SHADER_REQ_INTS;
1879 } else if (decl->Semantic.Name == TGSI_SEMANTIC_HELPER_INVOCATION) {
1880 name_prefix = "gl_HelperInvocation";
1881 ctx->shader_req_bits |= SHADER_REQ_ES31_COMPAT;
1882 } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEID) {
1883 name_prefix = "gl_SampleID";
1884 ctx->shader_req_bits |= (SHADER_REQ_SAMPLE_SHADING | SHADER_REQ_INTS);
1885 } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEPOS) {
1886 name_prefix = "gl_SamplePosition";
1887 ctx->shader_req_bits |= SHADER_REQ_SAMPLE_SHADING;
1888 } else if (decl->Semantic.Name == TGSI_SEMANTIC_INVOCATIONID) {
1889 name_prefix = "gl_InvocationID";
1890 ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_GPU_SHADER5);
1891 } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEMASK) {
1892 name_prefix = "gl_SampleMaskIn[0]";
1893 ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_GPU_SHADER5);
1894 } else if (decl->Semantic.Name == TGSI_SEMANTIC_PRIMID) {
1895 name_prefix = "gl_PrimitiveID";
1896 ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_GPU_SHADER5);
1897 } else if (decl->Semantic.Name == TGSI_SEMANTIC_TESSCOORD) {
1898 name_prefix = "gl_TessCoord";
1899 ctx->system_values[i].override_no_wm = false;
1900 } else if (decl->Semantic.Name == TGSI_SEMANTIC_VERTICESIN) {
1901 ctx->shader_req_bits |= SHADER_REQ_INTS;
1902 name_prefix = "gl_PatchVerticesIn";
1903 } else if (decl->Semantic.Name == TGSI_SEMANTIC_TESSOUTER) {
1904 name_prefix = "gl_TessLevelOuter";
1905 } else if (decl->Semantic.Name == TGSI_SEMANTIC_TESSINNER) {
1906 name_prefix = "gl_TessLevelInner";
1907 } else if (decl->Semantic.Name == TGSI_SEMANTIC_THREAD_ID) {
1908 name_prefix = "gl_LocalInvocationID";
1909 ctx->system_values[i].override_no_wm = false;
1910 } else if (decl->Semantic.Name == TGSI_SEMANTIC_BLOCK_ID) {
1911 name_prefix = "gl_WorkGroupID";
1912 ctx->system_values[i].override_no_wm = false;
1913 } else if (decl->Semantic.Name == TGSI_SEMANTIC_GRID_SIZE) {
1914 name_prefix = "gl_NumWorkGroups";
1915 ctx->system_values[i].override_no_wm = false;
1916 } else {
1917 vrend_printf( "unsupported system value %d\n", decl->Semantic.Name);
1918 name_prefix = "unknown";
1919 }
1920 snprintf(ctx->system_values[i].glsl_name, 64, "%s", name_prefix);
1921 break;
1922 case TGSI_FILE_MEMORY:
1923 ctx->has_file_memory = true;
1924 break;
1925 case TGSI_FILE_HW_ATOMIC:
1926 if (ctx->num_abo >= ARRAY_SIZE(ctx->abo_idx)) {
1927 vrend_printf( "Number of atomic counter buffers exceeded, max is %lu\n", ARRAY_SIZE(ctx->abo_idx));
1928 return false;
1929 }
1930 ctx->abo_idx[ctx->num_abo] = decl->Dim.Index2D;
1931 ctx->abo_sizes[ctx->num_abo] = decl->Range.Last - decl->Range.First + 1;
1932 ctx->abo_offsets[ctx->num_abo] = decl->Range.First;
1933 ctx->num_abo++;
1934 break;
1935 default:
1936 vrend_printf("unsupported file %d declaration\n", decl->Declaration.File);
1937 break;
1938 }
1939
1940 return true;
1941 }
1942
1943 static boolean
iter_property(struct tgsi_iterate_context * iter,struct tgsi_full_property * prop)1944 iter_property(struct tgsi_iterate_context *iter,
1945 struct tgsi_full_property *prop)
1946 {
1947 struct dump_ctx *ctx = (struct dump_ctx *) iter;
1948
1949 switch (prop->Property.PropertyName) {
1950 case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
1951 if (prop->u[0].Data == 1)
1952 ctx->write_all_cbufs = true;
1953 break;
1954 case TGSI_PROPERTY_FS_COORD_ORIGIN:
1955 ctx->fs_lower_left_origin = prop->u[0].Data ? true : false;
1956 break;
1957 case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
1958 ctx->fs_integer_pixel_center = prop->u[0].Data ? true : false;
1959 break;
1960 case TGSI_PROPERTY_FS_DEPTH_LAYOUT:
1961 /* If the host doesn't support this, then we can savely ignore this,
1962 * we only lost an opportunity to optimize */
1963 if (ctx->cfg->has_conservative_depth) {
1964 ctx->shader_req_bits |= SHADER_REQ_CONSERVATIVE_DEPTH;
1965 ctx->fs_depth_layout = prop->u[0].Data;
1966 }
1967 break;
1968 case TGSI_PROPERTY_GS_INPUT_PRIM:
1969 ctx->gs_in_prim = prop->u[0].Data;
1970 break;
1971 case TGSI_PROPERTY_GS_OUTPUT_PRIM:
1972 ctx->gs_out_prim = prop->u[0].Data;
1973 break;
1974 case TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES:
1975 ctx->gs_max_out_verts = prop->u[0].Data;
1976 break;
1977 case TGSI_PROPERTY_GS_INVOCATIONS:
1978 ctx->gs_num_invocations = prop->u[0].Data;
1979 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
1980 break;
1981 case TGSI_PROPERTY_NUM_CLIPDIST_ENABLED:
1982 ctx->shader_req_bits |= SHADER_REQ_CLIP_DISTANCE;
1983 ctx->num_clip_dist_prop = prop->u[0].Data;
1984 break;
1985 case TGSI_PROPERTY_NUM_CULLDIST_ENABLED:
1986 ctx->num_cull_dist_prop = prop->u[0].Data;
1987 break;
1988 case TGSI_PROPERTY_TCS_VERTICES_OUT:
1989 ctx->tcs_vertices_out = prop->u[0].Data;
1990 break;
1991 case TGSI_PROPERTY_TES_PRIM_MODE:
1992 ctx->tes_prim_mode = prop->u[0].Data;
1993 break;
1994 case TGSI_PROPERTY_TES_SPACING:
1995 ctx->tes_spacing = prop->u[0].Data;
1996 break;
1997 case TGSI_PROPERTY_TES_VERTEX_ORDER_CW:
1998 ctx->tes_vertex_order = prop->u[0].Data;
1999 break;
2000 case TGSI_PROPERTY_TES_POINT_MODE:
2001 ctx->tes_point_mode = prop->u[0].Data;
2002 break;
2003 case TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL:
2004 ctx->early_depth_stencil = prop->u[0].Data > 0;
2005 if (ctx->early_depth_stencil) {
2006 ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
2007 ctx->shader_req_bits |= SHADER_REQ_IMAGE_LOAD_STORE;
2008 }
2009 break;
2010 case TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH:
2011 ctx->local_cs_block_size[0] = prop->u[0].Data;
2012 break;
2013 case TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT:
2014 ctx->local_cs_block_size[1] = prop->u[0].Data;
2015 break;
2016 case TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH:
2017 ctx->local_cs_block_size[2] = prop->u[0].Data;
2018 break;
2019 case TGSI_PROPERTY_FS_BLEND_EQUATION_ADVANCED:
2020 ctx->fs_blend_equation_advanced = prop->u[0].Data;
2021 if (!ctx->cfg->use_gles || ctx->cfg->glsl_version < 320) {
2022 ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
2023 ctx->shader_req_bits |= SHADER_REQ_BLEND_EQUATION_ADVANCED;
2024 }
2025 break;
2026 case TGSI_PROPERTY_SEPARABLE_PROGRAM:
2027 /* GLES is very strict in how separable shaders interfaces should be matched.
2028 * It doesn't allow, for example, inputs without matching outputs. So, we just
2029 * disable separable shaders for GLES. */
2030 if (!ctx->cfg->use_gles) {
2031 ctx->separable_program = prop->u[0].Data;
2032 ctx->shader_req_bits |= SHADER_REQ_SEPERATE_SHADER_OBJECTS;
2033 ctx->shader_req_bits |= SHADER_REQ_EXPLICIT_ATTRIB_LOCATION;
2034 }
2035 break;
2036 default:
2037 vrend_printf("unhandled property: %x\n", prop->Property.PropertyName);
2038 return false;
2039 }
2040
2041 return true;
2042 }
2043
2044 static boolean
iter_immediate(struct tgsi_iterate_context * iter,struct tgsi_full_immediate * imm)2045 iter_immediate(struct tgsi_iterate_context *iter,
2046 struct tgsi_full_immediate *imm)
2047 {
2048 struct dump_ctx *ctx = (struct dump_ctx *) iter;
2049 int i;
2050 uint32_t first = ctx->num_imm;
2051
2052 if (first >= ARRAY_SIZE(ctx->imm)) {
2053 vrend_printf( "Number of immediates exceeded, max is: %lu\n", ARRAY_SIZE(ctx->imm));
2054 return false;
2055 }
2056
2057 ctx->imm[first].type = imm->Immediate.DataType;
2058 for (i = 0; i < 4; i++) {
2059 if (imm->Immediate.DataType == TGSI_IMM_FLOAT32) {
2060 ctx->imm[first].val[i].f = imm->u[i].Float;
2061 } else if (imm->Immediate.DataType == TGSI_IMM_UINT32 ||
2062 imm->Immediate.DataType == TGSI_IMM_FLOAT64) {
2063 ctx->shader_req_bits |= SHADER_REQ_INTS;
2064 ctx->imm[first].val[i].ui = imm->u[i].Uint;
2065 } else if (imm->Immediate.DataType == TGSI_IMM_INT32) {
2066 ctx->shader_req_bits |= SHADER_REQ_INTS;
2067 ctx->imm[first].val[i].i = imm->u[i].Int;
2068 }
2069 }
2070 ctx->num_imm++;
2071 return true;
2072 }
2073
get_swiz_char(int swiz)2074 static char get_swiz_char(int swiz)
2075 {
2076 switch(swiz){
2077 case TGSI_SWIZZLE_X: return 'x';
2078 case TGSI_SWIZZLE_Y: return 'y';
2079 case TGSI_SWIZZLE_Z: return 'z';
2080 case TGSI_SWIZZLE_W: return 'w';
2081 default: return 0;
2082 }
2083 }
2084
emit_cbuf_writes(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2085 static void emit_cbuf_writes(const struct dump_ctx *ctx,
2086 struct vrend_glsl_strbufs *glsl_strbufs)
2087 {
2088 int i;
2089
2090 for (i = ctx->num_outputs; i < ctx->cfg->max_draw_buffers; i++) {
2091 emit_buff(glsl_strbufs, "fsout_c%d = fsout_c0;\n", i);
2092 }
2093 }
2094
emit_a8_swizzle(struct vrend_glsl_strbufs * glsl_strbufs)2095 static void emit_a8_swizzle(struct vrend_glsl_strbufs *glsl_strbufs)
2096 {
2097 emit_buf(glsl_strbufs, "fsout_c0.x = fsout_c0.w;\n");
2098 }
2099
2100 static const char *atests[PIPE_FUNC_ALWAYS + 1] = {
2101 "false",
2102 "<",
2103 "==",
2104 "<=",
2105 ">",
2106 "!=",
2107 ">=",
2108 "true"
2109 };
2110
emit_alpha_test(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2111 static void emit_alpha_test(const struct dump_ctx *ctx,
2112 struct vrend_glsl_strbufs *glsl_strbufs)
2113 {
2114 char comp_buf[128];
2115
2116 if (!ctx->num_outputs)
2117 return;
2118
2119 if (!ctx->write_all_cbufs) {
2120 /* only emit alpha stanza if first output is 0 */
2121 if (ctx->outputs[0].sid != 0)
2122 return;
2123 }
2124 switch (ctx->key->alpha_test) {
2125 case PIPE_FUNC_NEVER:
2126 case PIPE_FUNC_ALWAYS:
2127 snprintf(comp_buf, 128, "%s", atests[ctx->key->alpha_test]);
2128 break;
2129 case PIPE_FUNC_LESS:
2130 case PIPE_FUNC_EQUAL:
2131 case PIPE_FUNC_LEQUAL:
2132 case PIPE_FUNC_GREATER:
2133 case PIPE_FUNC_NOTEQUAL:
2134 case PIPE_FUNC_GEQUAL:
2135 snprintf(comp_buf, 128, "%s %s alpha_ref_val", "fsout_c0.w", atests[ctx->key->alpha_test]);
2136 glsl_strbufs->required_sysval_uniform_decls |= BIT(UNIFORM_ALPHA_REF_VAL);
2137 break;
2138 default:
2139 vrend_printf( "invalid alpha-test: %x\n", ctx->key->alpha_test);
2140 set_buf_error(glsl_strbufs);
2141 return;
2142 }
2143
2144 emit_buff(glsl_strbufs, "if (!(%s)) {\n\tdiscard;\n}\n", comp_buf);
2145 }
2146
emit_pstipple_pass(struct vrend_glsl_strbufs * glsl_strbufs)2147 static void emit_pstipple_pass(struct vrend_glsl_strbufs *glsl_strbufs)
2148 {
2149 static_assert(VREND_POLYGON_STIPPLE_SIZE == 32,
2150 "According to the spec stipple size must be 32");
2151
2152 const int mask = VREND_POLYGON_STIPPLE_SIZE - 1;
2153
2154 emit_buf(glsl_strbufs, "{\n");
2155 emit_buff(glsl_strbufs, " int spx = int(gl_FragCoord.x) & %d;\n", mask);
2156 emit_buff(glsl_strbufs, " int spy = int(gl_FragCoord.y) & %d;\n", mask);
2157 emit_buf(glsl_strbufs, " stip_temp = stipple_pattern[spy] & (0x80000000u >> spx);\n");
2158 emit_buf(glsl_strbufs, " if (stip_temp == 0u) {\n discard;\n }\n");
2159 emit_buf(glsl_strbufs, "}\n");
2160 glsl_strbufs->required_sysval_uniform_decls |= BIT(UNIFORM_PSTIPPLE_SAMPLER);
2161 }
2162
emit_color_select(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2163 static void emit_color_select(const struct dump_ctx *ctx,
2164 struct vrend_glsl_strbufs *glsl_strbufs)
2165 {
2166 if (!ctx->key->color_two_side || !(ctx->color_in_mask & 0x3))
2167 return;
2168
2169 const char *name_prefix = get_stage_input_name_prefix(ctx, ctx->prog_type);
2170 if (ctx->color_in_mask & 1)
2171 emit_buff(glsl_strbufs, "realcolor0 = gl_FrontFacing ? %s_c0 : %s_bc0;\n",
2172 name_prefix, name_prefix);
2173
2174 if (ctx->color_in_mask & 2)
2175 emit_buff(glsl_strbufs, "realcolor1 = gl_FrontFacing ? %s_c1 : %s_bc1;\n",
2176 name_prefix, name_prefix);
2177 }
2178
emit_prescale(struct vrend_glsl_strbufs * glsl_strbufs)2179 static void emit_prescale(struct vrend_glsl_strbufs *glsl_strbufs)
2180 {
2181 emit_buf(glsl_strbufs, "gl_Position.y = gl_Position.y * winsys_adjust_y;\n");
2182 glsl_strbufs->required_sysval_uniform_decls |= BIT(UNIFORM_WINSYS_ADJUST_Y);
2183 }
2184
2185 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
prepare_so_movs(struct dump_ctx * ctx)2186 static void prepare_so_movs(struct dump_ctx *ctx)
2187 {
2188 uint32_t i;
2189 for (i = 0; i < ctx->so->num_outputs; i++) {
2190 ctx->write_so_outputs[i] = true;
2191 if (ctx->so->output[i].start_component != 0)
2192 continue;
2193 if (ctx->so->output[i].num_components != 4)
2194 continue;
2195 if (ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_CLIPDIST)
2196 continue;
2197 if (ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_POSITION)
2198 continue;
2199
2200 ctx->outputs[ctx->so->output[i].register_index].stream = ctx->so->output[i].stream;
2201 if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY && ctx->so->output[i].stream)
2202 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
2203
2204 ctx->write_so_outputs[i] = false;
2205 }
2206 }
2207
get_io_slot(const struct vrend_shader_io * slots,unsigned nslots,int idx)2208 static const struct vrend_shader_io *get_io_slot(const struct vrend_shader_io *slots, unsigned nslots, int idx)
2209 {
2210 const struct vrend_shader_io *result = slots;
2211 for (unsigned i = 0; i < nslots; ++i, ++result) {
2212 if ((result->first <= idx) && (result->last >= idx))
2213 return result;
2214 }
2215 assert(0 && "Output not found");
2216 return NULL;
2217 }
2218
2219 static inline void
get_blockname(char outvar[64],const char * stage_prefix,const struct vrend_shader_io * io)2220 get_blockname(char outvar[64], const char *stage_prefix, const struct vrend_shader_io *io)
2221 {
2222 snprintf(outvar, 64, "block_%sg%d", stage_prefix, io->sid);
2223 }
2224
2225 static inline void
get_blockvarname(char outvar[64],const char * stage_prefix,const struct vrend_shader_io * io,const char * postfix)2226 get_blockvarname(char outvar[64], const char *stage_prefix, const struct vrend_shader_io *io, const char *postfix)
2227 {
2228 snprintf(outvar, 64, "%sg%d%s", stage_prefix, io->first, postfix);
2229 }
2230
get_so_name(const struct dump_ctx * ctx,bool from_block,const struct vrend_shader_io * output,int index,char out_var[255],char * wm)2231 static void get_so_name(const struct dump_ctx *ctx, bool from_block, const struct vrend_shader_io *output, int index, char out_var[255], char *wm)
2232 {
2233 if (output->first == output->last ||
2234 (output->name != TGSI_SEMANTIC_GENERIC &&
2235 output->name != TGSI_SEMANTIC_TEXCOORD))
2236 snprintf(out_var, 255, "%s%s", output->glsl_name, wm);
2237 else {
2238 if ((output->name == TGSI_SEMANTIC_GENERIC) && prefer_generic_io_block(ctx, io_out)) {
2239 char blockname[64];
2240 const char *stage_prefix = get_stage_output_name_prefix(ctx->prog_type);
2241 if (from_block)
2242 get_blockname(blockname, stage_prefix, output);
2243 else
2244 get_blockvarname(blockname, stage_prefix, output, "");
2245 snprintf(out_var, 255, "%s.%s[%d]%s", blockname, output->glsl_name, index - output->first, wm);
2246 } else {
2247 snprintf(out_var, 255, "%s[%d]%s", output->glsl_name, index - output->first, wm);
2248 }
2249 }
2250 }
2251
emit_so_movs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,bool * has_clipvertex_so)2252 static void emit_so_movs(const struct dump_ctx *ctx,
2253 struct vrend_glsl_strbufs *glsl_strbufs,
2254 bool *has_clipvertex_so)
2255 {
2256 uint32_t i, j;
2257 char outtype[15] = "";
2258 char writemask[6];
2259
2260 if (ctx->so->num_outputs >= PIPE_MAX_SO_OUTPUTS) {
2261 vrend_printf( "Num outputs exceeded, max is %u\n", PIPE_MAX_SO_OUTPUTS);
2262 set_buf_error(glsl_strbufs);
2263 return;
2264 }
2265
2266 for (i = 0; i < ctx->so->num_outputs; i++) {
2267 const struct vrend_shader_io *output = get_io_slot(&ctx->outputs[0], ctx->num_outputs, ctx->so->output[i].register_index);
2268 if (ctx->so->output[i].start_component != 0) {
2269 int wm_idx = 0;
2270 writemask[wm_idx++] = '.';
2271 for (j = 0; j < ctx->so->output[i].num_components; j++) {
2272 unsigned idx = ctx->so->output[i].start_component + j;
2273 if (idx >= 4)
2274 break;
2275 if (idx <= 2)
2276 writemask[wm_idx++] = 'x' + idx;
2277 else
2278 writemask[wm_idx++] = 'w';
2279 }
2280 writemask[wm_idx] = '\0';
2281 } else
2282 writemask[0] = 0;
2283
2284 if (!ctx->write_so_outputs[i]) {
2285 if (ctx->so_names[i])
2286 free(ctx->so_names[i]);
2287 if (ctx->so->output[i].register_index > ctx->num_outputs)
2288 ctx->so_names[i] = NULL;
2289 else if (output->name == TGSI_SEMANTIC_CLIPVERTEX && ctx->has_clipvertex) {
2290 ctx->so_names[i] = strdup("clipv_tmp");
2291 *has_clipvertex_so = true;
2292 } else {
2293 char out_var[255];
2294 const struct vrend_shader_io *used_output_io = output;
2295 if (output->name == TGSI_SEMANTIC_GENERIC && ctx->generic_ios.output_range.used) {
2296 used_output_io = &ctx->generic_ios.output_range.io;
2297 } else if (output->name == TGSI_SEMANTIC_PATCH && ctx->patch_ios.output_range.used) {
2298 used_output_io = &ctx->patch_ios.output_range.io;
2299 }
2300 get_so_name(ctx, true, used_output_io, ctx->so->output[i].register_index, out_var, "");
2301 ctx->so_names[i] = strdup(out_var);
2302 }
2303 } else {
2304 char ntemp[8];
2305 snprintf(ntemp, 8, "tfout%d", i);
2306 ctx->so_names[i] = strdup(ntemp);
2307 }
2308 if (ctx->so->output[i].num_components == 1) {
2309 if (output->is_int)
2310 snprintf(outtype, 15, "intBitsToFloat");
2311 else
2312 snprintf(outtype, 15, "float");
2313 } else
2314 snprintf(outtype, 15, "vec%d", ctx->so->output[i].num_components);
2315
2316 if (ctx->so->output[i].register_index >= 255)
2317 continue;
2318
2319 if (output->name == TGSI_SEMANTIC_CLIPDIST) {
2320 if (output->first == output->last)
2321 emit_buff(glsl_strbufs, "tfout%d = %s(clip_dist_temp[%d]%s);\n", i, outtype, output->sid,
2322 writemask);
2323 else
2324 emit_buff(glsl_strbufs, "tfout%d = %s(clip_dist_temp[%d]%s);\n", i, outtype,
2325 output->sid + ctx->so->output[i].register_index - output->first,
2326 writemask);
2327 } else {
2328 if (ctx->write_so_outputs[i]) {
2329 char out_var[255];
2330 if (ctx->so->output[i].need_temp || ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
2331 output->glsl_predefined_no_emit) {
2332 get_so_name(ctx, false, output, ctx->so->output[i].register_index, out_var, writemask);
2333 emit_buff(glsl_strbufs, "tfout%d = %s(%s);\n", i, outtype, out_var);
2334 } else {
2335 get_so_name(ctx, true, output, ctx->so->output[i].register_index, out_var, writemask);
2336 free(ctx->so_names[i]);
2337 ctx->so_names[i] = strdup(out_var);
2338 }
2339 }
2340 }
2341 }
2342 }
2343
emit_clip_dist_movs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2344 static void emit_clip_dist_movs(const struct dump_ctx *ctx,
2345 struct vrend_glsl_strbufs *glsl_strbufs)
2346 {
2347 int i;
2348 bool has_prop = (ctx->num_clip_dist_prop + ctx->num_cull_dist_prop) > 0;
2349 int num_clip = has_prop ? ctx->num_clip_dist_prop : ctx->key->num_out_clip;
2350 int num_cull = has_prop ? ctx->num_cull_dist_prop : ctx->key->num_out_cull;
2351
2352
2353 int num_clip_cull = num_cull + num_clip;
2354 if (ctx->num_out_clip_dist && !num_clip_cull)
2355 num_clip = ctx->num_out_clip_dist;
2356
2357 int ndists;
2358 const char *prefix="";
2359
2360 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL)
2361 prefix = "gl_out[gl_InvocationID].";
2362
2363 if (ctx->num_out_clip_dist == 0 &&
2364 ctx->is_last_vertex_stage &&
2365 ctx->num_outputs + 2 <= MAX_VARYING) {
2366 emit_buff(glsl_strbufs, "if (clip_plane_enabled) {\n");
2367 for (i = 0; i < 8; i++) {
2368 emit_buff(glsl_strbufs, " %sgl_ClipDistance[%d] = dot(%s, clipp[%d]);\n",
2369 prefix, i, ctx->has_clipvertex ? "clipv_tmp" : "gl_Position", i);
2370 }
2371 emit_buff(glsl_strbufs, "}\n");
2372 glsl_strbufs->required_sysval_uniform_decls |= BIT(UNIFORM_CLIP_PLANE);
2373 }
2374 ndists = ctx->num_out_clip_dist;
2375 if (has_prop)
2376 ndists = num_clip + num_cull;
2377 for (i = 0; i < ndists; i++) {
2378 int clipidx = i < 4 ? 0 : 1;
2379 char swiz = i & 3;
2380 char wm = 0;
2381 switch (swiz) {
2382 default:
2383 case 0: wm = 'x'; break;
2384 case 1: wm = 'y'; break;
2385 case 2: wm = 'z'; break;
2386 case 3: wm = 'w'; break;
2387 }
2388 bool is_cull = false;
2389 const char *clip_cull = "Clip";
2390
2391 if (i >= num_clip) {
2392 if (i < ndists) {
2393 is_cull = true;
2394 clip_cull = "Cull";
2395 } else {
2396 clip_cull = "ERROR";
2397 }
2398 }
2399
2400 emit_buff(glsl_strbufs, "%sgl_%sDistance[%d] = clip_dist_temp[%d].%c;\n", prefix, clip_cull,
2401 is_cull ? i - num_clip : i, clipidx, wm);
2402 }
2403 }
2404
emit_fog_fixup_hdr(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2405 static void emit_fog_fixup_hdr(const struct dump_ctx *ctx,
2406 struct vrend_glsl_strbufs *glsl_strbufs)
2407 {
2408 uint32_t fixup_mask = ctx->key->vs.fog_fixup_mask;
2409 int semantic;
2410 const char *prefix = get_stage_output_name_prefix(TGSI_PROCESSOR_VERTEX);
2411
2412 while (fixup_mask) {
2413 semantic = ffs(fixup_mask) - 1;
2414
2415 emit_hdrf(glsl_strbufs, "out vec4 %s_f%d;\n", prefix, semantic);
2416 fixup_mask &= (~(1 << semantic));
2417 }
2418 }
2419
emit_fog_fixup_write(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2420 static void emit_fog_fixup_write(const struct dump_ctx *ctx,
2421 struct vrend_glsl_strbufs *glsl_strbufs)
2422 {
2423 uint32_t fixup_mask = ctx->key->vs.fog_fixup_mask;
2424 int semantic;
2425 const char *prefix = get_stage_output_name_prefix(TGSI_PROCESSOR_VERTEX);
2426
2427 while (fixup_mask) {
2428 semantic = ffs(fixup_mask) - 1;
2429
2430 /*
2431 * Force unwritten fog outputs to 0,0,0,1
2432 */
2433 emit_buff(glsl_strbufs, "%s_f%d = vec4(0.0, 0.0, 0.0, 1.0);\n",
2434 prefix, semantic);
2435 fixup_mask &= (~(1 << semantic));
2436 }
2437 }
2438
2439 #define emit_arit_op2(op) emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((%s %s %s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], op, srcs[1], writemask)
2440 #define emit_op1(op) emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(%s(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), op, srcs[0], writemask)
2441 #define emit_compare(op) emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((%s(%s(%s), %s(%s))))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), op, get_string(sinfo.svec4), srcs[0], get_string(sinfo.svec4), srcs[1], writemask)
2442
2443 #define emit_ucompare(op) emit_buff(&ctx->glsl_strbufs, "%s = %s(uintBitsToFloat(%s(%s(%s(%s), %s(%s))%s) * %s(0xffffffff)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.udstconv), op, get_string(sinfo.svec4), srcs[0], get_string(sinfo.svec4), srcs[1], writemask, get_string(dinfo.udstconv))
2444
handle_vertex_proc_exit(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,bool * has_clipvertex_so)2445 static void handle_vertex_proc_exit(const struct dump_ctx *ctx,
2446 struct vrend_glsl_strbufs *glsl_strbufs,
2447 bool *has_clipvertex_so)
2448 {
2449 if (ctx->so && !ctx->key->gs_present && !ctx->key->tes_present)
2450 emit_so_movs(ctx, glsl_strbufs, has_clipvertex_so);
2451
2452 if (ctx->cfg->has_cull_distance)
2453 emit_clip_dist_movs(ctx, glsl_strbufs);
2454
2455 if (!ctx->key->gs_present && !ctx->key->tes_present)
2456 emit_prescale(glsl_strbufs);
2457
2458 if (ctx->key->vs.fog_fixup_mask)
2459 emit_fog_fixup_write(ctx, glsl_strbufs);
2460 }
2461
emit_fragment_logicop(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2462 static void emit_fragment_logicop(const struct dump_ctx *ctx,
2463 struct vrend_glsl_strbufs *glsl_strbufs)
2464 {
2465 char src[PIPE_MAX_COLOR_BUFS][64];
2466 char src_fb[PIPE_MAX_COLOR_BUFS][64];
2467 double scale[PIPE_MAX_COLOR_BUFS];
2468 int mask[PIPE_MAX_COLOR_BUFS];
2469
2470 struct vrend_strbuf full_op_buf[PIPE_MAX_COLOR_BUFS];
2471 for (int i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
2472 strbuf_alloc(&full_op_buf[i], 134);
2473 }
2474
2475
2476 for (unsigned i = 0; i < ctx->num_outputs; i++) {
2477 mask[i] = (1 << ctx->key->fs.surface_component_bits[i]) - 1;
2478 scale[i] = mask[i];
2479 switch (ctx->key->fs.logicop_func) {
2480 case PIPE_LOGICOP_INVERT:
2481 snprintf(src_fb[i], ARRAY_SIZE(src_fb[i]),
2482 "ivec4(%f * fsout_c%d + 0.5)", scale[i], i);
2483 break;
2484 case PIPE_LOGICOP_NOR:
2485 case PIPE_LOGICOP_AND_INVERTED:
2486 case PIPE_LOGICOP_AND_REVERSE:
2487 case PIPE_LOGICOP_XOR:
2488 case PIPE_LOGICOP_NAND:
2489 case PIPE_LOGICOP_AND:
2490 case PIPE_LOGICOP_EQUIV:
2491 case PIPE_LOGICOP_OR_INVERTED:
2492 case PIPE_LOGICOP_OR_REVERSE:
2493 case PIPE_LOGICOP_OR:
2494 snprintf(src_fb[i], ARRAY_SIZE(src_fb[i]),
2495 "ivec4(%f * fsout_c%d + 0.5)", scale[i], i);
2496 /* fallthrough */
2497 case PIPE_LOGICOP_COPY_INVERTED:
2498 snprintf(src[i], ARRAY_SIZE(src[i]),
2499 "ivec4(%f * fsout_tmp_c%d + 0.5)", scale[i], i);
2500 break;
2501 case PIPE_LOGICOP_COPY:
2502 case PIPE_LOGICOP_NOOP:
2503 case PIPE_LOGICOP_CLEAR:
2504 case PIPE_LOGICOP_SET:
2505 break;
2506 }
2507 }
2508
2509 for (unsigned i = 0; i < ctx->num_outputs; i++) {
2510 switch (ctx->key->fs.logicop_func) {
2511 case PIPE_LOGICOP_CLEAR:
2512 strbuf_fmt(&full_op_buf[i], "%s", "vec4(0)");
2513 break;
2514 case PIPE_LOGICOP_NOOP:
2515 strbuf_fmt(&full_op_buf[i], "%s", "");
2516 break;
2517 case PIPE_LOGICOP_SET:
2518 strbuf_fmt(&full_op_buf[i], "%s", "vec4(1)");
2519 break;
2520 case PIPE_LOGICOP_COPY:
2521 strbuf_fmt(&full_op_buf[i], "fsout_tmp_c%d", i);
2522 break;
2523 case PIPE_LOGICOP_COPY_INVERTED:
2524 strbuf_fmt(&full_op_buf[i], "~%s", src[i]);
2525 break;
2526 case PIPE_LOGICOP_INVERT:
2527 strbuf_fmt(&full_op_buf[i], "~%s", src_fb[i]);
2528 break;
2529 case PIPE_LOGICOP_AND:
2530 strbuf_fmt(&full_op_buf[i], "%s & %s", src[i], src_fb[i]);
2531 break;
2532 case PIPE_LOGICOP_NAND:
2533 strbuf_fmt(&full_op_buf[i], "~( %s & %s )", src[i], src_fb[i]);
2534 break;
2535 case PIPE_LOGICOP_NOR:
2536 strbuf_fmt(&full_op_buf[i], "~( %s | %s )", src[i], src_fb[i]);
2537 break;
2538 case PIPE_LOGICOP_AND_INVERTED:
2539 strbuf_fmt(&full_op_buf[i], "~%s & %s", src[i], src_fb[i]);
2540 break;
2541 case PIPE_LOGICOP_AND_REVERSE:
2542 strbuf_fmt(&full_op_buf[i], "%s & ~%s", src[i], src_fb[i]);
2543 break;
2544 case PIPE_LOGICOP_XOR:
2545 strbuf_fmt(&full_op_buf[i], "%s ^%s", src[i], src_fb[i]);
2546 break;
2547 case PIPE_LOGICOP_EQUIV:
2548 strbuf_fmt(&full_op_buf[i], "~( %s ^ %s )", src[i], src_fb[i]);
2549 break;
2550 case PIPE_LOGICOP_OR_INVERTED:
2551 strbuf_fmt(&full_op_buf[i], "~%s | %s", src[i], src_fb[i]);
2552 break;
2553 case PIPE_LOGICOP_OR_REVERSE:
2554 strbuf_fmt(&full_op_buf[i], "%s | ~%s", src[i], src_fb[i]);
2555 break;
2556 case PIPE_LOGICOP_OR:
2557 strbuf_fmt(&full_op_buf[i], "%s | %s", src[i], src_fb[i]);
2558 break;
2559 }
2560 }
2561
2562 for (unsigned i = 0; i < ctx->num_outputs; i++) {
2563 switch (ctx->key->fs.logicop_func) {
2564 case PIPE_LOGICOP_NOOP:
2565 break;
2566 case PIPE_LOGICOP_COPY:
2567 case PIPE_LOGICOP_CLEAR:
2568 case PIPE_LOGICOP_SET:
2569 emit_buff(glsl_strbufs, "fsout_c%d = %s;\n", i, full_op_buf[i].buf);
2570 break;
2571 default:
2572 emit_buff(glsl_strbufs, "fsout_c%d = vec4((%s) & %d) / %f;\n", i, full_op_buf[i].buf, mask[i], scale[i]);
2573 }
2574 }
2575 }
2576
emit_cbuf_swizzle(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2577 static void emit_cbuf_swizzle(const struct dump_ctx *ctx,
2578 struct vrend_glsl_strbufs *glsl_strbufs)
2579 {
2580 int cbuf_id = 0;
2581 for (uint i = 0; i < ctx->num_outputs; i++) {
2582 if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR) {
2583 if (ctx->key->fs.swizzle_output_rgb_to_bgr & (1 << cbuf_id)) {
2584 emit_buff(glsl_strbufs, "fsout_c%d = fsout_c%d.zyxw;\n", cbuf_id, cbuf_id);
2585 }
2586 ++cbuf_id;
2587 }
2588 }
2589 }
2590
emit_cbuf_colorspace_convert(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2591 static void emit_cbuf_colorspace_convert(const struct dump_ctx *ctx,
2592 struct vrend_glsl_strbufs *glsl_strbufs)
2593 {
2594 for (uint i = 0; i < ctx->num_outputs; i++) {
2595 if (ctx->key->fs.needs_manual_srgb_encode_bitmask & (1 << i)) {
2596 emit_buff(glsl_strbufs,
2597 "{\n"
2598 " vec3 temp = fsout_c%d.xyz;\n"
2599 " bvec3 thresh = lessThanEqual(temp, vec3(0.0031308));\n"
2600 " vec3 a = temp * vec3(12.92);\n"
2601 " vec3 b = ( vec3(1.055) * pow(temp, vec3(1.0/2.4)) ) - vec3(0.055);\n"
2602 " fsout_c%d.xyz = mix(b, a, thresh);\n"
2603 "}\n"
2604 , i, i);
2605 }
2606 }
2607 }
2608
handle_fragment_proc_exit(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2609 static void handle_fragment_proc_exit(const struct dump_ctx *ctx,
2610 struct vrend_glsl_strbufs *glsl_strbufs)
2611 {
2612 if (ctx->key->pstipple_enabled)
2613 emit_pstipple_pass(glsl_strbufs);
2614
2615 if (ctx->key->fs.cbufs_are_a8_bitmask)
2616 emit_a8_swizzle(glsl_strbufs);
2617
2618 if (ctx->key->add_alpha_test)
2619 emit_alpha_test(ctx, glsl_strbufs);
2620
2621
2622 if (ctx->key->fs.logicop_enabled)
2623 emit_fragment_logicop(ctx, glsl_strbufs);
2624
2625 if (ctx->key->fs.swizzle_output_rgb_to_bgr)
2626 emit_cbuf_swizzle(ctx, glsl_strbufs);
2627
2628 if (ctx->key->fs.needs_manual_srgb_encode_bitmask)
2629 emit_cbuf_colorspace_convert(ctx, glsl_strbufs);
2630
2631 if (ctx->write_all_cbufs)
2632 emit_cbuf_writes(ctx, glsl_strbufs);
2633
2634 }
2635
2636 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
set_texture_reqs(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,uint32_t sreg_index)2637 static void set_texture_reqs(struct dump_ctx *ctx,
2638 const struct tgsi_full_instruction *inst,
2639 uint32_t sreg_index)
2640 {
2641 if (sreg_index >= ARRAY_SIZE(ctx->samplers)) {
2642 vrend_printf( "Sampler view exceeded, max is %lu\n", ARRAY_SIZE(ctx->samplers));
2643 set_buf_error(&ctx->glsl_strbufs);
2644 return;
2645 }
2646 ctx->samplers[sreg_index].tgsi_sampler_type = inst->Texture.Texture;
2647
2648 ctx->shader_req_bits |= samplertype_to_req_bits(inst->Texture.Texture);
2649
2650 if (ctx->cfg->glsl_version >= 140)
2651 if (ctx->shader_req_bits & (SHADER_REQ_SAMPLER_RECT |
2652 SHADER_REQ_SAMPLER_BUF))
2653 ctx->glsl_ver_required = require_glsl_ver(ctx, 140);
2654 }
2655
2656 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
2657
2658 /* size queries are pretty much separate */
emit_txq(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,uint32_t sreg_index,const char * srcs[4],const char * dst,const char * writemask)2659 static void emit_txq(struct dump_ctx *ctx,
2660 const struct tgsi_full_instruction *inst,
2661 uint32_t sreg_index,
2662 const char *srcs[4],
2663 const char *dst,
2664 const char *writemask)
2665 {
2666 unsigned twm = TGSI_WRITEMASK_NONE;
2667 char bias[128] = "";
2668 const int sampler_index = 1;
2669 enum vrend_type_qualifier dtypeprefix = INT_BITS_TO_FLOAT;
2670
2671 set_texture_reqs(ctx, inst, sreg_index);
2672
2673 /* No LOD for these texture types, but on GLES we emulate RECT by using
2674 * a normal 2D texture, so we have to give LOD 0 */
2675 switch (inst->Texture.Texture) {
2676 case TGSI_TEXTURE_RECT:
2677 case TGSI_TEXTURE_SHADOWRECT:
2678 if (ctx->cfg->use_gles) {
2679 snprintf(bias, 128, ", 0");
2680 break;
2681 }
2682 /* fallthrough */
2683 case TGSI_TEXTURE_BUFFER:
2684 case TGSI_TEXTURE_2D_MSAA:
2685 case TGSI_TEXTURE_2D_ARRAY_MSAA:
2686 break;
2687 default:
2688 snprintf(bias, 128, ", int(%s.x)", srcs[0]);
2689 }
2690
2691 /* need to emit a textureQueryLevels */
2692 if (inst->Dst[0].Register.WriteMask & 0x8) {
2693
2694 if (inst->Texture.Texture != TGSI_TEXTURE_BUFFER &&
2695 inst->Texture.Texture != TGSI_TEXTURE_RECT &&
2696 inst->Texture.Texture != TGSI_TEXTURE_2D_MSAA &&
2697 inst->Texture.Texture != TGSI_TEXTURE_2D_ARRAY_MSAA) {
2698 ctx->shader_req_bits |= SHADER_REQ_TXQ_LEVELS;
2699 if (inst->Dst[0].Register.WriteMask & 0x7)
2700 twm = TGSI_WRITEMASK_W;
2701
2702 if (!ctx->cfg->use_gles) {
2703 emit_buff(&ctx->glsl_strbufs, "%s%s = %s(textureQueryLevels(%s));\n", dst,
2704 get_wm_string(twm), get_string(dtypeprefix),
2705 srcs[sampler_index]);
2706 } else {
2707 const struct tgsi_full_src_register *src = &inst->Src[1];
2708
2709 int gles_sampler_index = 0;
2710 for (int i = 0; i < src->Register.Index; ++i) {
2711 if (ctx->samplers_used & (1 << i))
2712 ++gles_sampler_index;
2713 }
2714
2715 char sampler_str[64];
2716
2717 if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER) && src->Register.Indirect) {
2718 snprintf(sampler_str, sizeof(sampler_str), "addr%d+%d", src->Indirect.Index, gles_sampler_index);
2719 } else {
2720 snprintf(sampler_str, sizeof(sampler_str), "%d", gles_sampler_index);
2721 }
2722 emit_buff(&ctx->glsl_strbufs, "%s%s = %s(%s_texlod[%s]);\n", dst, get_wm_string(twm),
2723 get_string(dtypeprefix), tgsi_proc_to_prefix(ctx->info.processor),
2724 sampler_str);
2725 ctx->gles_use_tex_query_level = true;
2726 }
2727 }
2728
2729 if (inst->Dst[0].Register.WriteMask & 0x7) {
2730 switch (inst->Texture.Texture) {
2731 case TGSI_TEXTURE_1D:
2732 case TGSI_TEXTURE_BUFFER:
2733 case TGSI_TEXTURE_SHADOW1D:
2734 twm = TGSI_WRITEMASK_X;
2735 break;
2736 case TGSI_TEXTURE_1D_ARRAY:
2737 case TGSI_TEXTURE_SHADOW1D_ARRAY:
2738 case TGSI_TEXTURE_2D:
2739 case TGSI_TEXTURE_SHADOW2D:
2740 case TGSI_TEXTURE_RECT:
2741 case TGSI_TEXTURE_SHADOWRECT:
2742 case TGSI_TEXTURE_CUBE:
2743 case TGSI_TEXTURE_SHADOWCUBE:
2744 case TGSI_TEXTURE_2D_MSAA:
2745 twm = TGSI_WRITEMASK_XY;
2746 break;
2747 case TGSI_TEXTURE_3D:
2748 case TGSI_TEXTURE_2D_ARRAY:
2749 case TGSI_TEXTURE_SHADOW2D_ARRAY:
2750 case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
2751 case TGSI_TEXTURE_CUBE_ARRAY:
2752 case TGSI_TEXTURE_2D_ARRAY_MSAA:
2753 twm = TGSI_WRITEMASK_XYZ;
2754 break;
2755 }
2756 }
2757 }
2758
2759 if (inst->Dst[0].Register.WriteMask & 0x7) {
2760 char wm_buffer[16];
2761 bool txq_returns_vec = (inst->Texture.Texture != TGSI_TEXTURE_BUFFER) &&
2762 (ctx->cfg->use_gles ||
2763 (inst->Texture.Texture != TGSI_TEXTURE_1D &&
2764 inst->Texture.Texture != TGSI_TEXTURE_SHADOW1D));
2765
2766 if (ctx->cfg->use_gles &&
2767 (inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY ||
2768 inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY)) {
2769 snprintf(wm_buffer, sizeof(wm_buffer), ".xz%s", writemask);
2770 writemask = wm_buffer;
2771 }
2772
2773 emit_buff(&ctx->glsl_strbufs, "%s%s = %s(textureSize(%s%s))%s;\n", dst,
2774 get_wm_string(twm), get_string(dtypeprefix),
2775 srcs[sampler_index], bias, txq_returns_vec ? writemask : "");
2776 }
2777 }
2778
2779 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
2780 /* sample queries are pretty much separate */
emit_txqs(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,uint32_t sreg_index,const char * srcs[4],const char * dst)2781 static void emit_txqs(struct dump_ctx *ctx,
2782 const struct tgsi_full_instruction *inst,
2783 uint32_t sreg_index,
2784 const char *srcs[4],
2785 const char *dst)
2786 {
2787 const int sampler_index = 0;
2788 enum vrend_type_qualifier dtypeprefix = INT_BITS_TO_FLOAT;
2789
2790 ctx->shader_req_bits |= SHADER_REQ_TXQS;
2791 set_texture_reqs(ctx, inst, sreg_index);
2792
2793 if (inst->Texture.Texture != TGSI_TEXTURE_2D_MSAA &&
2794 inst->Texture.Texture != TGSI_TEXTURE_2D_ARRAY_MSAA) {
2795 set_buf_error(&ctx->glsl_strbufs);
2796 return;
2797 }
2798
2799 emit_buff(&ctx->glsl_strbufs, "%s = %s(textureSamples(%s));\n", dst,
2800 get_string(dtypeprefix), srcs[sampler_index]);
2801 }
2802
get_tex_inst_ext(const struct tgsi_full_instruction * inst)2803 static const char *get_tex_inst_ext(const struct tgsi_full_instruction *inst)
2804 {
2805 switch (inst->Instruction.Opcode) {
2806 case TGSI_OPCODE_TXP:
2807 if (inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
2808 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY ||
2809 inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY)
2810 return "";
2811 else if (inst->Texture.NumOffsets == 1)
2812 return "ProjOffset";
2813 else
2814 return "Proj";
2815 case TGSI_OPCODE_TXL:
2816 case TGSI_OPCODE_TXL2:
2817 if (inst->Texture.NumOffsets == 1)
2818 return "LodOffset";
2819 else
2820 return "Lod";
2821 case TGSI_OPCODE_TXD:
2822 if (inst->Texture.NumOffsets == 1)
2823 return "GradOffset";
2824 else
2825 return "Grad";
2826 case TGSI_OPCODE_TG4:
2827 if (inst->Texture.NumOffsets == 4)
2828 return "GatherOffsets";
2829 else if (inst->Texture.NumOffsets == 1)
2830 return "GatherOffset";
2831 else
2832 return "Gather";
2833 default:
2834 if (inst->Texture.NumOffsets == 1)
2835 return "Offset";
2836 else
2837 return "";
2838 }
2839 }
2840
2841 static void
get_temp(const struct dump_ctx * ctx,bool indirect_dim,int dim,int reg,char buf[static64],bool * require_dummy_value)2842 get_temp(const struct dump_ctx *ctx,
2843 bool indirect_dim, int dim, int reg,
2844 char buf[static 64], bool *require_dummy_value)
2845 {
2846 struct vrend_temp_range *range = find_temp_range(ctx, reg);
2847 if (range) {
2848 if (indirect_dim) {
2849 snprintf(buf, 64, "temp%d[addr%d + %d]", range->first, dim, reg - range->first);
2850 } else {
2851 if (range->array_id > 0) {
2852 snprintf(buf, 64, "temp%d[%d]", range->first, reg - range->first);
2853 } else {
2854 snprintf(buf, 64, "temp%d", reg);
2855 }
2856 }
2857 } else {
2858 snprintf(buf, 64, "dummy_value");
2859 *require_dummy_value = true;
2860 }
2861 }
2862
fill_offset_buffer(const struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,struct vrend_strbuf * offset_buf,bool * require_dummy_value)2863 static bool fill_offset_buffer(const struct dump_ctx *ctx,
2864 const struct tgsi_full_instruction *inst,
2865 struct vrend_strbuf *offset_buf,
2866 bool *require_dummy_value)
2867 {
2868 if (inst->TexOffsets[0].File == TGSI_FILE_IMMEDIATE) {
2869 const struct immed *imd = &ctx->imm[inst->TexOffsets[0].Index];
2870 switch (inst->Texture.Texture) {
2871 case TGSI_TEXTURE_1D:
2872 case TGSI_TEXTURE_1D_ARRAY:
2873 case TGSI_TEXTURE_SHADOW1D:
2874 case TGSI_TEXTURE_SHADOW1D_ARRAY:
2875 if (!ctx->cfg->use_gles)
2876 strbuf_appendf(offset_buf, ", int(%d)", imd->val[inst->TexOffsets[0].SwizzleX].i);
2877 else
2878 strbuf_appendf(offset_buf, ", ivec2(%d, 0)", imd->val[inst->TexOffsets[0].SwizzleX].i);
2879 break;
2880 case TGSI_TEXTURE_RECT:
2881 case TGSI_TEXTURE_SHADOWRECT:
2882 case TGSI_TEXTURE_2D:
2883 case TGSI_TEXTURE_2D_ARRAY:
2884 case TGSI_TEXTURE_SHADOW2D:
2885 case TGSI_TEXTURE_SHADOW2D_ARRAY:
2886 strbuf_appendf(offset_buf, ", ivec2(%d, %d)", imd->val[inst->TexOffsets[0].SwizzleX].i, imd->val[inst->TexOffsets[0].SwizzleY].i);
2887 break;
2888 case TGSI_TEXTURE_3D:
2889 strbuf_appendf(offset_buf, ", ivec3(%d, %d, %d)", imd->val[inst->TexOffsets[0].SwizzleX].i, imd->val[inst->TexOffsets[0].SwizzleY].i,
2890 imd->val[inst->TexOffsets[0].SwizzleZ].i);
2891 break;
2892 default:
2893 vrend_printf( "unhandled texture: %x\n", inst->Texture.Texture);
2894 return false;
2895 }
2896 } else if (inst->TexOffsets[0].File == TGSI_FILE_TEMPORARY) {
2897 char temp_buf[64];
2898 get_temp(ctx, false, 0, inst->TexOffsets[0].Index, temp_buf, require_dummy_value);
2899 switch (inst->Texture.Texture) {
2900 case TGSI_TEXTURE_1D:
2901 case TGSI_TEXTURE_1D_ARRAY:
2902 case TGSI_TEXTURE_SHADOW1D:
2903 case TGSI_TEXTURE_SHADOW1D_ARRAY:
2904
2905 strbuf_appendf(offset_buf, ", int(floatBitsToInt(%s.%c))",
2906 temp_buf,
2907 get_swiz_char(inst->TexOffsets[0].SwizzleX));
2908 break;
2909 case TGSI_TEXTURE_RECT:
2910 case TGSI_TEXTURE_SHADOWRECT:
2911 case TGSI_TEXTURE_2D:
2912 case TGSI_TEXTURE_2D_ARRAY:
2913 case TGSI_TEXTURE_SHADOW2D:
2914 case TGSI_TEXTURE_SHADOW2D_ARRAY:
2915 strbuf_appendf(offset_buf, ", ivec2(floatBitsToInt(%s.%c), floatBitsToInt(%s.%c))",
2916 temp_buf,
2917 get_swiz_char(inst->TexOffsets[0].SwizzleX),
2918 temp_buf,
2919 get_swiz_char(inst->TexOffsets[0].SwizzleY));
2920 break;
2921 case TGSI_TEXTURE_3D:
2922 strbuf_appendf(offset_buf, ", ivec3(floatBitsToInt(%s.%c), floatBitsToInt(%s.%c), floatBitsToInt(%s.%c)",
2923 temp_buf,
2924 get_swiz_char(inst->TexOffsets[0].SwizzleX),
2925 temp_buf,
2926 get_swiz_char(inst->TexOffsets[0].SwizzleY),
2927 temp_buf,
2928 get_swiz_char(inst->TexOffsets[0].SwizzleZ));
2929 break;
2930 default:
2931 vrend_printf( "unhandled texture: %x\n", inst->Texture.Texture);
2932 return false;
2933 break;
2934 }
2935 } else if (inst->TexOffsets[0].File == TGSI_FILE_INPUT) {
2936 for (uint32_t j = 0; j < ctx->num_inputs; j++) {
2937 if (ctx->inputs[j].first != inst->TexOffsets[0].Index)
2938 continue;
2939 switch (inst->Texture.Texture) {
2940 case TGSI_TEXTURE_1D:
2941 case TGSI_TEXTURE_1D_ARRAY:
2942 case TGSI_TEXTURE_SHADOW1D:
2943 case TGSI_TEXTURE_SHADOW1D_ARRAY:
2944 strbuf_appendf(offset_buf, ", int(floatBitsToInt(%s.%c))",
2945 ctx->inputs[j].glsl_name,
2946 get_swiz_char(inst->TexOffsets[0].SwizzleX));
2947 break;
2948 case TGSI_TEXTURE_RECT:
2949 case TGSI_TEXTURE_SHADOWRECT:
2950 case TGSI_TEXTURE_2D:
2951 case TGSI_TEXTURE_2D_ARRAY:
2952 case TGSI_TEXTURE_SHADOW2D:
2953 case TGSI_TEXTURE_SHADOW2D_ARRAY:
2954 strbuf_appendf(offset_buf, ", ivec2(floatBitsToInt(%s.%c), floatBitsToInt(%s.%c))",
2955 ctx->inputs[j].glsl_name,
2956 get_swiz_char(inst->TexOffsets[0].SwizzleX),
2957 ctx->inputs[j].glsl_name,
2958 get_swiz_char(inst->TexOffsets[0].SwizzleY));
2959 break;
2960 case TGSI_TEXTURE_3D:
2961 strbuf_appendf(offset_buf, ", ivec3(floatBitsToInt(%s.%c), floatBitsToInt(%s.%c), floatBitsToInt(%s.%c)",
2962 ctx->inputs[j].glsl_name,
2963 get_swiz_char(inst->TexOffsets[0].SwizzleX),
2964 ctx->inputs[j].glsl_name,
2965 get_swiz_char(inst->TexOffsets[0].SwizzleY),
2966 ctx->inputs[j].glsl_name,
2967 get_swiz_char(inst->TexOffsets[0].SwizzleZ));
2968 break;
2969 default:
2970 vrend_printf( "unhandled texture: %x\n", inst->Texture.Texture);
2971 return false;
2972 break;
2973 }
2974 }
2975 }
2976 return true;
2977 }
2978
2979 static void
emit_lodq(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,const struct source_info * sinfo,const struct dest_info * dinfo,const char * srcs[4],const char * dst,const char * writemask)2980 emit_lodq(struct dump_ctx *ctx,
2981 const struct tgsi_full_instruction *inst,
2982 const struct source_info *sinfo,
2983 const struct dest_info *dinfo,
2984 const char *srcs[4],
2985 const char *dst,
2986 const char *writemask)
2987 {
2988 ctx->shader_req_bits |= SHADER_REQ_LODQ;
2989
2990 set_texture_reqs(ctx, inst, sinfo->sreg_index);
2991
2992 emit_buff(&ctx->glsl_strbufs, "%s = %s(textureQueryLOD(%s, ",
2993 dst, get_string(dinfo->dstconv), srcs[1]);
2994
2995 switch (inst->Texture.Texture) {
2996 case TGSI_TEXTURE_1D:
2997 case TGSI_TEXTURE_1D_ARRAY:
2998 case TGSI_TEXTURE_SHADOW1D:
2999 case TGSI_TEXTURE_SHADOW1D_ARRAY:
3000 if (ctx->cfg->use_gles)
3001 emit_buff(&ctx->glsl_strbufs, "vec2(%s.x, 0)", srcs[0]);
3002 else
3003 emit_buff(&ctx->glsl_strbufs, "%s.x", srcs[0]);
3004 break;
3005 case TGSI_TEXTURE_2D:
3006 case TGSI_TEXTURE_2D_ARRAY:
3007 case TGSI_TEXTURE_2D_MSAA:
3008 case TGSI_TEXTURE_2D_ARRAY_MSAA:
3009 case TGSI_TEXTURE_RECT:
3010 case TGSI_TEXTURE_SHADOW2D:
3011 case TGSI_TEXTURE_SHADOW2D_ARRAY:
3012 case TGSI_TEXTURE_SHADOWRECT:
3013 emit_buff(&ctx->glsl_strbufs, "%s.xy", srcs[0]);
3014 break;
3015 case TGSI_TEXTURE_3D:
3016 case TGSI_TEXTURE_CUBE:
3017 case TGSI_TEXTURE_SHADOWCUBE:
3018 case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
3019 case TGSI_TEXTURE_CUBE_ARRAY:
3020 emit_buff(&ctx->glsl_strbufs, "%s.xyz", srcs[0]);
3021 break;
3022 default:
3023 emit_buff(&ctx->glsl_strbufs, "%s", srcs[0]);
3024 break;
3025 }
3026
3027 emit_buff(&ctx->glsl_strbufs, ")%s);\n", writemask);
3028 }
3029
3030 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
translate_tex(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,const struct source_info * sinfo,const struct dest_info * dinfo,const char * srcs[4],const char * dst,const char * writemask)3031 static void translate_tex(struct dump_ctx *ctx,
3032 const struct tgsi_full_instruction *inst,
3033 const struct source_info *sinfo,
3034 const struct dest_info *dinfo,
3035 const char *srcs[4],
3036 const char *dst,
3037 const char *writemask)
3038 {
3039 enum vrend_type_qualifier txfi = TYPE_CONVERSION_NONE;
3040 const char *src_swizzle;
3041 enum vrend_type_qualifier dtypeprefix = TYPE_CONVERSION_NONE;
3042 bool is_shad;
3043
3044 int sampler_index = 1;
3045 const char *tex_ext;
3046
3047 struct vrend_strbuf bias_buf;
3048 struct vrend_strbuf offset_buf;
3049
3050 strbuf_alloc(&bias_buf, 128);
3051 strbuf_alloc(&offset_buf, 128);
3052
3053 set_texture_reqs(ctx, inst, sinfo->sreg_index);
3054 is_shad = samplertype_is_shadow(inst->Texture.Texture);
3055
3056 switch (ctx->samplers[sinfo->sreg_index].tgsi_sampler_return) {
3057 case TGSI_RETURN_TYPE_SINT:
3058 /* if dstconv isn't an int */
3059 if (dinfo->dstconv != INT)
3060 dtypeprefix = INT_BITS_TO_FLOAT;
3061 break;
3062 case TGSI_RETURN_TYPE_UINT:
3063 /* if dstconv isn't an int */
3064 if (dinfo->dstconv != INT)
3065 dtypeprefix = UINT_BITS_TO_FLOAT;
3066 break;
3067 default:
3068 break;
3069 }
3070
3071 switch (inst->Texture.Texture) {
3072 case TGSI_TEXTURE_1D:
3073 case TGSI_TEXTURE_BUFFER:
3074 if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3075 src_swizzle = "";
3076 else
3077 src_swizzle = ".x";
3078 txfi = INT;
3079 break;
3080 case TGSI_TEXTURE_1D_ARRAY:
3081 src_swizzle = ".xy";
3082 txfi = IVEC2;
3083 break;
3084 case TGSI_TEXTURE_2D:
3085 case TGSI_TEXTURE_RECT:
3086 if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3087 src_swizzle = "";
3088 else
3089 src_swizzle = ".xy";
3090 txfi = IVEC2;
3091 break;
3092 case TGSI_TEXTURE_SHADOW1D:
3093 case TGSI_TEXTURE_SHADOW2D:
3094 case TGSI_TEXTURE_SHADOW1D_ARRAY:
3095 case TGSI_TEXTURE_SHADOWRECT:
3096 case TGSI_TEXTURE_3D:
3097 if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3098 src_swizzle = "";
3099 else if (inst->Instruction.Opcode == TGSI_OPCODE_TG4)
3100 src_swizzle = ".xy";
3101 else
3102 src_swizzle = ".xyz";
3103 txfi = IVEC3;
3104 break;
3105 case TGSI_TEXTURE_CUBE:
3106 case TGSI_TEXTURE_2D_ARRAY:
3107 src_swizzle = ".xyz";
3108 txfi = IVEC3;
3109 break;
3110 case TGSI_TEXTURE_2D_MSAA:
3111 src_swizzle = ".xy";
3112 txfi = IVEC2;
3113 break;
3114 case TGSI_TEXTURE_2D_ARRAY_MSAA:
3115 src_swizzle = ".xyz";
3116 txfi = IVEC3;
3117 break;
3118
3119 case TGSI_TEXTURE_SHADOWCUBE:
3120 case TGSI_TEXTURE_SHADOW2D_ARRAY:
3121 case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
3122 case TGSI_TEXTURE_CUBE_ARRAY:
3123 default:
3124 if (inst->Instruction.Opcode == TGSI_OPCODE_TG4 &&
3125 inst->Texture.Texture != TGSI_TEXTURE_CUBE_ARRAY &&
3126 inst->Texture.Texture != TGSI_TEXTURE_SHADOWCUBE_ARRAY)
3127 src_swizzle = ".xyz";
3128 else
3129 src_swizzle = "";
3130 txfi = TYPE_CONVERSION_NONE;
3131 break;
3132 }
3133
3134 switch (inst->Instruction.Opcode) {
3135 case TGSI_OPCODE_TEX2:
3136 sampler_index = 2;
3137 if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
3138 strbuf_appendf(&bias_buf, ", %s.x", srcs[1]);
3139 break;
3140 case TGSI_OPCODE_TXB2:
3141 case TGSI_OPCODE_TXL2:
3142 sampler_index = 2;
3143 strbuf_appendf(&bias_buf, ", %s.x", srcs[1]);
3144 if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
3145 strbuf_appendf(&bias_buf, ", %s.y", srcs[1]);
3146 break;
3147 case TGSI_OPCODE_TXB:
3148 case TGSI_OPCODE_TXL:
3149 /* On GLES we emulate the 1D array by using a 2D array, for this
3150 * there is no shadow lookup with bias unless EXT_texture_shadow_lod is used.
3151 * To avoid that compiling an invalid shader results in a crash we ignore
3152 * the bias value */
3153 if (!(ctx->cfg->use_gles && !ctx->cfg->has_texture_shadow_lod &&
3154 TGSI_TEXTURE_SHADOW1D_ARRAY == inst->Texture.Texture))
3155 strbuf_appendf(&bias_buf, ", %s.w", srcs[0]);
3156 break;
3157 case TGSI_OPCODE_TXF:
3158 if (inst->Texture.Texture == TGSI_TEXTURE_1D ||
3159 inst->Texture.Texture == TGSI_TEXTURE_2D ||
3160 inst->Texture.Texture == TGSI_TEXTURE_2D_MSAA ||
3161 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY_MSAA ||
3162 inst->Texture.Texture == TGSI_TEXTURE_3D ||
3163 inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY ||
3164 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY)
3165 strbuf_appendf(&bias_buf, ", int(%s.w)", srcs[0]);
3166 break;
3167 case TGSI_OPCODE_TXD:
3168 sampler_index = 3;
3169 switch (inst->Texture.Texture) {
3170 case TGSI_TEXTURE_1D:
3171 case TGSI_TEXTURE_SHADOW1D:
3172 case TGSI_TEXTURE_1D_ARRAY:
3173 case TGSI_TEXTURE_SHADOW1D_ARRAY:
3174 if (ctx->cfg->use_gles)
3175 strbuf_appendf(&bias_buf, ", vec2(%s.x, 0), vec2(%s.x, 0)", srcs[1], srcs[2]);
3176 else
3177 strbuf_appendf(&bias_buf, ", %s.x, %s.x", srcs[1], srcs[2]);
3178 break;
3179 case TGSI_TEXTURE_2D:
3180 case TGSI_TEXTURE_SHADOW2D:
3181 case TGSI_TEXTURE_2D_ARRAY:
3182 case TGSI_TEXTURE_SHADOW2D_ARRAY:
3183 case TGSI_TEXTURE_RECT:
3184 case TGSI_TEXTURE_SHADOWRECT:
3185 strbuf_appendf(&bias_buf, ", %s.xy, %s.xy", srcs[1], srcs[2]);
3186 break;
3187 case TGSI_TEXTURE_3D:
3188 case TGSI_TEXTURE_CUBE:
3189 case TGSI_TEXTURE_SHADOWCUBE:
3190 case TGSI_TEXTURE_CUBE_ARRAY:
3191 strbuf_appendf(&bias_buf, ", %s.xyz, %s.xyz", srcs[1], srcs[2]);
3192 break;
3193 default:
3194 strbuf_appendf(&bias_buf, ", %s, %s", srcs[1], srcs[2]);
3195 break;
3196 }
3197 break;
3198 case TGSI_OPCODE_TG4:
3199 sampler_index = 2;
3200 ctx->shader_req_bits |= SHADER_REQ_TG4;
3201 if (!ctx->cfg->use_gles) {
3202 if (inst->Texture.NumOffsets > 1 || is_shad || (ctx->shader_req_bits & SHADER_REQ_SAMPLER_RECT))
3203 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3204 }
3205 if (inst->Texture.NumOffsets == 1) {
3206 if (inst->TexOffsets[0].File != TGSI_FILE_IMMEDIATE)
3207 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3208 }
3209 if (is_shad) {
3210 if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
3211 inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY)
3212 strbuf_appendf(&bias_buf, ", %s.w", srcs[0]);
3213 else if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
3214 strbuf_appendf(&bias_buf, ", %s.x", srcs[1]);
3215 else
3216 strbuf_appendf(&bias_buf, ", %s.z", srcs[0]);
3217 } else if (sinfo->tg4_has_component) {
3218 if (inst->Texture.NumOffsets == 0) {
3219 if (inst->Texture.Texture == TGSI_TEXTURE_2D ||
3220 inst->Texture.Texture == TGSI_TEXTURE_RECT ||
3221 inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
3222 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY ||
3223 inst->Texture.Texture == TGSI_TEXTURE_CUBE_ARRAY)
3224 strbuf_appendf(&bias_buf, ", int(%s)", srcs[1]);
3225 } else if (inst->Texture.NumOffsets) {
3226 if (inst->Texture.Texture == TGSI_TEXTURE_2D ||
3227 inst->Texture.Texture == TGSI_TEXTURE_RECT ||
3228 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY)
3229 strbuf_appendf(&bias_buf, ", int(%s)", srcs[1]);
3230 }
3231 }
3232 break;
3233 default:
3234 ;
3235 }
3236
3237 tex_ext = get_tex_inst_ext(inst);
3238
3239 const char *bias = bias_buf.buf;
3240 const char *offset = offset_buf.buf;
3241
3242 // EXT_texture_shadow_lod defines a few more functions handling bias
3243 if (bias &&
3244 (inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY ||
3245 inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
3246 inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY))
3247 ctx->shader_req_bits |= SHADER_REQ_TEXTURE_SHADOW_LOD;
3248
3249 // EXT_texture_shadow_lod also adds the missing textureOffset for 2DArrayShadow in GLES
3250 if ((bias || offset) && ctx->cfg->use_gles &&
3251 (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY ||
3252 inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY))
3253 ctx->shader_req_bits |= SHADER_REQ_TEXTURE_SHADOW_LOD;
3254
3255 if (inst->Texture.NumOffsets == 1) {
3256 if (inst->TexOffsets[0].Index >= (int)ARRAY_SIZE(ctx->imm)) {
3257 vrend_printf( "Immediate exceeded, max is %lu\n", ARRAY_SIZE(ctx->imm));
3258 set_buf_error(&ctx->glsl_strbufs);
3259 goto cleanup;
3260 }
3261
3262 if (!fill_offset_buffer(ctx, inst, &offset_buf, &ctx->require_dummy_value)) {
3263 set_buf_error(&ctx->glsl_strbufs);
3264 goto cleanup;
3265 }
3266
3267 if (inst->Instruction.Opcode == TGSI_OPCODE_TXL || inst->Instruction.Opcode == TGSI_OPCODE_TXL2 || inst->Instruction.Opcode == TGSI_OPCODE_TXD || (inst->Instruction.Opcode == TGSI_OPCODE_TG4 && is_shad)) {
3268 offset = bias_buf.buf;
3269 bias = offset_buf.buf;
3270 }
3271 }
3272
3273 char buf[255];
3274 const char *new_srcs[4] = { buf, srcs[1], srcs[2], srcs[3] };
3275
3276 /* We have to unnormalize the coordinate for all but the texel fetch instruction */
3277 if (inst->Instruction.Opcode != TGSI_OPCODE_TXF &&
3278 vrend_shader_sampler_views_mask_get(ctx->key->sampler_views_emulated_rect_mask, sinfo->sreg_index)) {
3279
3280 const char *bias = "";
3281
3282 /* No LOD for these texture types, but on GLES we emulate RECT by using
3283 * a normal 2D texture, so we have to give LOD 0 */
3284 switch (inst->Texture.Texture) {
3285 case TGSI_TEXTURE_BUFFER:
3286 case TGSI_TEXTURE_2D_MSAA:
3287 case TGSI_TEXTURE_2D_ARRAY_MSAA:
3288 break;
3289 case TGSI_TEXTURE_RECT:
3290 case TGSI_TEXTURE_SHADOWRECT:
3291 if (!ctx->cfg->use_gles)
3292 break;
3293 /* fallthrough */
3294 default:
3295 bias = ", 0";
3296 }
3297
3298 switch (inst->Instruction.Opcode) {
3299 case TGSI_OPCODE_TXP:
3300 snprintf(buf, 255, "vec4(%s)/vec4(textureSize(%s%s), 1, 1)", srcs[0], srcs[sampler_index], bias);
3301 break;
3302
3303 case TGSI_OPCODE_TG4:
3304 snprintf(buf, 255, "%s.xy/vec2(textureSize(%s%s))", srcs[0], srcs[sampler_index], bias);
3305 break;
3306
3307 default:
3308 /* Non TG4 ops have the compare value in the z components */
3309 if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWRECT) {
3310 snprintf(buf, 255, "vec3(%s.xy/vec2(textureSize(%s%s)), %s.z)", srcs[0], srcs[sampler_index], bias, srcs[0]);
3311 } else
3312 snprintf(buf, 255, "%s.xy/vec2(textureSize(%s%s))", srcs[0], srcs[sampler_index], bias);
3313 }
3314 srcs = new_srcs;
3315 }
3316
3317 if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) {
3318 if (ctx->cfg->use_gles &&
3319 (inst->Texture.Texture == TGSI_TEXTURE_1D ||
3320 inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY ||
3321 inst->Texture.Texture == TGSI_TEXTURE_RECT)) {
3322 if (inst->Texture.Texture == TGSI_TEXTURE_1D)
3323 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texelFetch%s(%s, ivec2(%s(%s%s), 0)%s%s)%s));\n",
3324 dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3325 tex_ext, srcs[sampler_index], get_string(txfi),
3326 srcs[0], src_swizzle, bias, offset,
3327 dinfo->dst_override_no_wm[0] ? "" : writemask);
3328 else if (inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY) {
3329 /* the y coordinate must go into the z element and the y must be zero */
3330 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texelFetch%s(%s, ivec3(%s(%s%s), 0).xzy%s%s)%s));\n",
3331 dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3332 tex_ext, srcs[sampler_index], get_string(txfi),
3333 srcs[0], src_swizzle, bias, offset,
3334 dinfo->dst_override_no_wm[0] ? "" : writemask);
3335 } else {
3336 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texelFetch%s(%s, %s(%s%s), 0%s)%s));\n",
3337 dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3338 tex_ext, srcs[sampler_index], get_string(txfi),
3339 srcs[0], src_swizzle, offset,
3340 dinfo->dst_override_no_wm[0] ? "" : writemask);
3341 }
3342 } else {
3343
3344 /* To inject the swizzle for texturebufffers with emulated formats do
3345 *
3346 * {
3347 * vec4 val = texelFetch( )
3348 * val = vec4(0/1/swizzle_x, ...);
3349 * dest.writemask = val.writemask;
3350 * }
3351 *
3352 */
3353 emit_buff(&ctx->glsl_strbufs, "{\n vec4 val = %s(texelFetch%s(%s, %s(%s%s)%s%s));\n",
3354 get_string(dtypeprefix),
3355 tex_ext, srcs[sampler_index], get_string(txfi),
3356 srcs[0], src_swizzle, bias, offset);
3357
3358 if (vrend_shader_sampler_views_mask_get(ctx->key->sampler_views_lower_swizzle_mask, sinfo->sreg_index)) {
3359 int16_t packed_swizzles = ctx->key->tex_swizzle[sinfo->sreg_index];
3360 emit_buff(&ctx->glsl_strbufs, " val = vec4(");
3361
3362 for (int i = 0; i < 4; ++i) {
3363 if (i > 0)
3364 emit_buff(&ctx->glsl_strbufs, ", ");
3365
3366 int swz = (packed_swizzles >> (i * 3)) & 7;
3367 switch (swz) {
3368 case PIPE_SWIZZLE_ZERO : emit_buf(&ctx->glsl_strbufs, "0.0"); break;
3369 case PIPE_SWIZZLE_ONE :
3370 switch (dtypeprefix) {
3371 case UINT_BITS_TO_FLOAT:
3372 emit_buf(&ctx->glsl_strbufs, "uintBitsToFloat(1u)");
3373 break;
3374 case INT_BITS_TO_FLOAT:
3375 emit_buf(&ctx->glsl_strbufs, "intBitsToFloat(1)");
3376 break;
3377 default:
3378 emit_buf(&ctx->glsl_strbufs, "1.0");
3379 break;
3380 }
3381 break;
3382 default:
3383 emit_buff(&ctx->glsl_strbufs, "val%s", get_swizzle_string(swz));
3384 }
3385 }
3386
3387 emit_buff(&ctx->glsl_strbufs, ");\n");
3388 }
3389
3390 emit_buff(&ctx->glsl_strbufs, " %s = val%s;\n}\n",
3391 dst, dinfo->dst_override_no_wm[0] ? "" : writemask);
3392 }
3393 } else if ((ctx->cfg->glsl_version < 140 && (ctx->shader_req_bits & SHADER_REQ_SAMPLER_RECT)) &&
3394 !vrend_shader_sampler_views_mask_get(ctx->key->sampler_views_emulated_rect_mask, sinfo->sreg_index)) {
3395 /* rect is special in GLSL 1.30 */
3396 if (inst->Texture.Texture == TGSI_TEXTURE_RECT)
3397 emit_buff(&ctx->glsl_strbufs, "%s = texture2DRect(%s, %s.xy)%s;\n",
3398 dst, srcs[sampler_index], srcs[0], writemask);
3399 else if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWRECT)
3400 emit_buff(&ctx->glsl_strbufs, "%s = shadow2DRect(%s, %s.xyz)%s;\n",
3401 dst, srcs[sampler_index], srcs[0], writemask);
3402 } else if (is_shad && inst->Instruction.Opcode != TGSI_OPCODE_TG4) { /* TGSI returns 1.0 in alpha */
3403 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3404 const struct tgsi_full_src_register *src = &inst->Src[sampler_index];
3405
3406 if (ctx->cfg->use_gles &&
3407 (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D ||
3408 inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY)) {
3409 if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D) {
3410 if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3411 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(vec4(texture%s(%s, vec4(%s%s.xzw, 0).xwyz %s%s)) * %sshadmask%d + %sshadadd%d)%s));\n",
3412 dst, get_string(dinfo->dstconv),
3413 get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3414 srcs[0], src_swizzle, offset, bias,
3415 cname, src->Register.Index,
3416 cname, src->Register.Index, writemask);
3417 else
3418 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(vec4(texture%s(%s, vec3(%s%s.xz, 0).xzy %s%s)) * %sshadmask%d + %sshadadd%d)%s));\n",
3419 dst, get_string(dinfo->dstconv),
3420 get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3421 srcs[0], src_swizzle, offset, bias,
3422 cname, src->Register.Index,
3423 cname, src->Register.Index, writemask);
3424 } else if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY) {
3425 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(vec4(texture%s(%s, vec4(%s%s, 0).xwyz %s%s)) * %sshadmask%d + %sshadadd%d)%s));\n",
3426 dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3427 tex_ext, srcs[sampler_index], srcs[0],
3428 src_swizzle, offset, bias, cname,
3429 src->Register.Index, cname,
3430 src->Register.Index, writemask);
3431 }
3432 } else
3433 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(vec4(texture%s(%s, %s%s%s%s)) * %sshadmask%d + %sshadadd%d)%s));\n",
3434 dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3435 tex_ext, srcs[sampler_index], srcs[0],
3436 src_swizzle, offset, bias,
3437 cname, src->Register.Index,
3438 cname, src->Register.Index, writemask);
3439 } else {
3440 /* OpenGL ES do not support 1D texture
3441 * so we use a 2D texture with a parameter set to 0.5
3442 */
3443 if (ctx->cfg->use_gles &&
3444 (inst->Texture.Texture == TGSI_TEXTURE_1D ||
3445 inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY)) {
3446 if (inst->Texture.Texture == TGSI_TEXTURE_1D) {
3447 if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3448 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texture%s(%s, vec3(%s.xw, 0).xzy %s%s)%s));\n",
3449 dst, get_string(dinfo->dstconv),
3450 get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3451 srcs[0], offset, bias,
3452 dinfo->dst_override_no_wm[0] ? "" : writemask);
3453 else
3454 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texture%s(%s, vec2(%s%s, 0.5) %s%s)%s));\n",
3455 dst, get_string(dinfo->dstconv),
3456 get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3457 srcs[0], src_swizzle, offset, bias,
3458 dinfo->dst_override_no_wm[0] ? "" : writemask);
3459 } else if (inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY) {
3460 if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3461 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texture%s(%s, vec3(%s.x / %s.w, 0, %s.y) %s%s)%s));\n",
3462 dst, get_string(dinfo->dstconv),
3463 get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3464 srcs[0], srcs[0], srcs[0], offset, bias,
3465 dinfo->dst_override_no_wm[0] ? "" : writemask);
3466 else
3467 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texture%s(%s, vec3(%s%s, 0).xzy %s%s)%s));\n",
3468 dst, get_string(dinfo->dstconv),
3469 get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3470 srcs[0], src_swizzle, offset, bias,
3471 dinfo->dst_override_no_wm[0] ? "" : writemask);
3472 }
3473 } else {
3474 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texture%s(%s, %s%s%s%s)%s));\n",
3475 dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3476 tex_ext, srcs[sampler_index], srcs[0], src_swizzle,
3477 offset, bias, dinfo->dst_override_no_wm[0] ? "" : writemask);
3478 }
3479 }
3480
3481 cleanup:
3482 strbuf_free(&offset_buf);
3483 strbuf_free(&bias_buf);
3484 }
3485
3486 static void
create_swizzled_clipdist(const struct dump_ctx * ctx,struct vrend_strbuf * result,const struct tgsi_full_src_register * src,int input_idx,bool gl_in,const char * stypeprefix,const char * prefix,const char * arrayname,int offset)3487 create_swizzled_clipdist(const struct dump_ctx *ctx,
3488 struct vrend_strbuf *result,
3489 const struct tgsi_full_src_register *src,
3490 int input_idx,
3491 bool gl_in,
3492 const char *stypeprefix,
3493 const char *prefix,
3494 const char *arrayname, int offset)
3495 {
3496 char clipdistvec[4][80] = { 0, };
3497
3498 char clip_indirect[32] = "";
3499
3500 bool has_prop = (ctx->num_cull_dist_prop + ctx->num_clip_dist_prop) > 0;
3501 int num_culls = has_prop ? ctx->num_cull_dist_prop : ctx->key->num_out_cull;
3502 int num_clips = has_prop ? ctx->num_clip_dist_prop : ctx->key->num_out_clip;
3503
3504 int num_clip_cull = num_culls + num_clips;
3505 if (ctx->num_in_clip_dist && !num_clip_cull)
3506 num_clips = ctx->num_in_clip_dist;
3507
3508 int base_idx = ctx->inputs[input_idx].sid * 4;
3509
3510 // This doesn't work for indirect adressing
3511 int base_offset = (src->Register.Index - offset) * 4;
3512
3513 /* With arrays enabled , but only when gl_ClipDistance or gl_CullDistance are emitted (>4)
3514 * then we need to add indirect addressing */
3515 if (src->Register.Indirect && ((num_clips > 4 && base_idx < num_clips) || num_culls > 4))
3516 snprintf(clip_indirect, 32, "4*addr%d +", src->Indirect.Index);
3517 else if (src->Register.Index != offset)
3518 snprintf(clip_indirect, 32, "4*%d +", src->Register.Index - offset);
3519
3520 for (unsigned cc = 0; cc < 4; cc++) {
3521 const char *cc_name = ctx->inputs[input_idx].glsl_name;
3522 int idx = base_idx;
3523 if (cc == 0)
3524 idx += src->Register.SwizzleX;
3525 else if (cc == 1)
3526 idx += src->Register.SwizzleY;
3527 else if (cc == 2)
3528 idx += src->Register.SwizzleZ;
3529 else if (cc == 3)
3530 idx += src->Register.SwizzleW;
3531
3532 if (num_culls) {
3533 if (idx + base_offset >= num_clips) {
3534 idx -= num_clips;
3535 cc_name = "gl_CullDistance";
3536 }
3537 }
3538
3539 if (gl_in)
3540 snprintf(clipdistvec[cc], 80, "%sgl_in%s.%s[%s %d]", prefix, arrayname, cc_name, clip_indirect, idx);
3541 else
3542 snprintf(clipdistvec[cc], 80, "%s%s%s[%s %d]", prefix, arrayname, cc_name, clip_indirect, idx);
3543 }
3544 strbuf_fmt(result, "%s(vec4(%s,%s,%s,%s))", stypeprefix, clipdistvec[0], clipdistvec[1], clipdistvec[2], clipdistvec[3]);
3545 }
3546
3547 static
load_clipdist_fs(const struct dump_ctx * ctx,struct vrend_strbuf * result,const struct tgsi_full_src_register * src,int input_idx,const char * stypeprefix,int offset)3548 void load_clipdist_fs(const struct dump_ctx *ctx,
3549 struct vrend_strbuf *result,
3550 const struct tgsi_full_src_register *src,
3551 int input_idx,
3552 const char *stypeprefix,
3553 int offset)
3554 {
3555 char clip_indirect[32] = "";
3556
3557 char swz[5] = {
3558 get_swiz_char(src->Register.SwizzleX),
3559 get_swiz_char(src->Register.SwizzleY),
3560 get_swiz_char(src->Register.SwizzleZ),
3561 get_swiz_char(src->Register.SwizzleW),
3562 0
3563 };
3564
3565 int base_idx = ctx->inputs[input_idx].sid;
3566
3567 /* With arrays enabled , but only when gl_ClipDistance or gl_CullDistance are emitted (>4)
3568 * then we need to add indirect addressing */
3569 if (src->Register.Indirect)
3570 snprintf(clip_indirect, 32, "addr%d + %d", src->Indirect.Index, base_idx);
3571 else
3572 snprintf(clip_indirect, 32, "%d + %d", src->Register.Index - offset, base_idx);
3573
3574 strbuf_fmt(result, "%s(clip_dist_temp[%s].%s)", stypeprefix, clip_indirect, swz);
3575 }
3576
3577
get_coord_prefix(int resource,bool * is_ms,bool use_gles)3578 static enum vrend_type_qualifier get_coord_prefix(int resource, bool *is_ms, bool use_gles)
3579 {
3580 switch(resource) {
3581 case TGSI_TEXTURE_1D:
3582 return use_gles ? IVEC2: INT;
3583 case TGSI_TEXTURE_BUFFER:
3584 return INT;
3585 case TGSI_TEXTURE_1D_ARRAY:
3586 return use_gles ? IVEC3: IVEC2;
3587 case TGSI_TEXTURE_2D:
3588 case TGSI_TEXTURE_RECT:
3589 return IVEC2;
3590 case TGSI_TEXTURE_3D:
3591 case TGSI_TEXTURE_CUBE:
3592 case TGSI_TEXTURE_2D_ARRAY:
3593 case TGSI_TEXTURE_CUBE_ARRAY:
3594 return IVEC3;
3595 case TGSI_TEXTURE_2D_MSAA:
3596 *is_ms = true;
3597 return IVEC2;
3598 case TGSI_TEXTURE_2D_ARRAY_MSAA:
3599 *is_ms = true;
3600 return IVEC3;
3601 default:
3602 return TYPE_CONVERSION_NONE;
3603 }
3604 }
3605
is_integer_memory(const struct dump_ctx * ctx,enum tgsi_file_type file_type,uint32_t index)3606 static bool is_integer_memory(const struct dump_ctx *ctx, enum tgsi_file_type file_type, uint32_t index)
3607 {
3608 switch(file_type) {
3609 case TGSI_FILE_BUFFER:
3610 return !!(ctx->ssbo_integer_mask & (1 << index));
3611 case TGSI_FILE_MEMORY:
3612 return ctx->integer_memory;
3613 default:
3614 vrend_printf( "Invalid file type");
3615 }
3616
3617 return false;
3618 }
3619
set_image_qualifier(struct vrend_shader_image images[],uint32_t image_used_mask,const struct tgsi_full_instruction * inst,uint32_t reg_index,bool indirect)3620 static void set_image_qualifier(struct vrend_shader_image images[],
3621 uint32_t image_used_mask,
3622 const struct tgsi_full_instruction *inst,
3623 uint32_t reg_index, bool indirect)
3624 {
3625 if (inst->Memory.Qualifier == TGSI_MEMORY_COHERENT) {
3626 if (indirect) {
3627 while (image_used_mask)
3628 images[u_bit_scan(&image_used_mask)].coherent = true;
3629 } else
3630 images[reg_index].coherent = true;
3631 }
3632 }
3633
set_memory_qualifier(uint8_t ssbo_memory_qualifier[],uint32_t ssbo_used_mask,const struct tgsi_full_instruction * inst,uint32_t reg_index,bool indirect)3634 static void set_memory_qualifier(uint8_t ssbo_memory_qualifier[],
3635 uint32_t ssbo_used_mask,
3636 const struct tgsi_full_instruction *inst,
3637 uint32_t reg_index, bool indirect)
3638 {
3639 if (inst->Memory.Qualifier == TGSI_MEMORY_COHERENT) {
3640 if (indirect) {
3641 while (ssbo_used_mask)
3642 ssbo_memory_qualifier[u_bit_scan(&ssbo_used_mask)] = TGSI_MEMORY_COHERENT;
3643 } else
3644 ssbo_memory_qualifier[reg_index] = TGSI_MEMORY_COHERENT;
3645 }
3646 }
3647
emit_store_mem(struct vrend_glsl_strbufs * glsl_strbufs,const char * dst,int writemask,const char * srcs[4],const char * conversion)3648 static void emit_store_mem(struct vrend_glsl_strbufs *glsl_strbufs, const char *dst, int writemask,
3649 const char *srcs[4], const char *conversion)
3650 {
3651 static const char swizzle_char[] = "xyzw";
3652 for (int i = 0; i < 4; ++i) {
3653 if (writemask & (1 << i)) {
3654 emit_buff(glsl_strbufs, "%s[(uint(floatBitsToUint(%s)) >> 2) + %du] = %s(%s).%c;\n",
3655 dst, srcs[0], i, conversion, srcs[1], swizzle_char[i]);
3656 }
3657 }
3658 }
3659
3660 static void
translate_store(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,uint8_t ssbo_memory_qualifier[],struct vrend_shader_image images[],const struct tgsi_full_instruction * inst,struct source_info * sinfo,const char * srcs[4],const struct dest_info * dinfo,const char * dst)3661 translate_store(const struct dump_ctx *ctx,
3662 struct vrend_glsl_strbufs *glsl_strbufs,
3663 uint8_t ssbo_memory_qualifier[],
3664 struct vrend_shader_image images[],
3665 const struct tgsi_full_instruction *inst,
3666 struct source_info *sinfo,
3667 const char *srcs[4],
3668 const struct dest_info *dinfo,
3669 const char *dst)
3670 {
3671 const struct tgsi_full_dst_register *dst_reg = &inst->Dst[0];
3672
3673 assert(dinfo->dest_index >= 0);
3674 if (dst_reg->Register.File == TGSI_FILE_IMAGE) {
3675
3676 /* bail out if we want to write to a non-existing image */
3677 if (!((1 << dinfo->dest_index) & ctx->images_used_mask))
3678 return;
3679
3680 set_image_qualifier(images, ctx->images_used_mask, inst, inst->Src[0].Register.Index, inst->Src[0].Register.Indirect);
3681
3682 bool is_ms = false;
3683 enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx->images[dst_reg->Register.Index].decl.Resource, &is_ms, ctx->cfg->use_gles);
3684 enum tgsi_return_type itype;
3685 char ms_str[32] = "";
3686 enum vrend_type_qualifier stypeprefix = TYPE_CONVERSION_NONE;
3687 const char *conversion = sinfo->override_no_cast[0] ? "" : get_string(FLOAT_BITS_TO_INT);
3688 get_internalformat_string(inst->Memory.Format, &itype);
3689 if (is_ms) {
3690 snprintf(ms_str, 32, "int(%s.w),", srcs[0]);
3691 }
3692 switch (itype) {
3693 case TGSI_RETURN_TYPE_UINT:
3694 stypeprefix = FLOAT_BITS_TO_UINT;
3695 break;
3696 case TGSI_RETURN_TYPE_SINT:
3697 stypeprefix = FLOAT_BITS_TO_INT;
3698 break;
3699 default:
3700 break;
3701 }
3702 if (!ctx->cfg->use_gles || !dst_reg->Register.Indirect) {
3703 emit_buff(glsl_strbufs, "imageStore(%s,%s(%s(%s)),%s%s(%s));\n",
3704 dst, get_string(coord_prefix), conversion, srcs[0],
3705 ms_str, get_string(stypeprefix), srcs[1]);
3706 } else {
3707 struct vrend_array *image = lookup_image_array_ptr(ctx, dst_reg->Register.Index);
3708 if (image) {
3709 int basearrayidx = image->first;
3710 int array_size = image->array_size;
3711 emit_buff(glsl_strbufs, "switch (addr%d + %d) {\n", dst_reg->Indirect.Index,
3712 dst_reg->Register.Index - basearrayidx);
3713 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3714
3715 for (int i = 0; i < array_size; ++i) {
3716 emit_buff(glsl_strbufs, "case %d: imageStore(%simg%d[%d],%s(%s(%s)),%s%s(%s)); break;\n",
3717 i, cname, basearrayidx, i, get_string(coord_prefix),
3718 conversion, srcs[0], ms_str, get_string(stypeprefix),
3719 srcs[1]);
3720 }
3721 emit_buff(glsl_strbufs, "}\n");
3722 }
3723 }
3724 } else if (dst_reg->Register.File == TGSI_FILE_BUFFER ||
3725 dst_reg->Register.File == TGSI_FILE_MEMORY) {
3726 enum vrend_type_qualifier dtypeprefix;
3727 set_memory_qualifier(ssbo_memory_qualifier, ctx->ssbo_used_mask, inst, dst_reg->Register.Index,
3728 dst_reg->Register.Indirect);
3729 dtypeprefix = is_integer_memory(ctx, dst_reg->Register.File, dst_reg->Register.Index) ?
3730 FLOAT_BITS_TO_INT : FLOAT_BITS_TO_UINT;
3731 const char *conversion = sinfo->override_no_cast[1] ? "" : get_string(dtypeprefix);
3732
3733 if (!ctx->cfg->use_gles || !dst_reg->Register.Indirect) {
3734 emit_store_mem(glsl_strbufs, dst, dst_reg->Register.WriteMask, srcs,
3735 conversion);
3736 } else {
3737 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3738 bool atomic_ssbo = ctx->ssbo_atomic_mask & (1 << dst_reg->Register.Index);
3739 int base = atomic_ssbo ? ctx->ssbo_atomic_array_base : ctx->ssbo_array_base;
3740 uint32_t mask = ctx->ssbo_used_mask;
3741 int start, array_count;
3742 u_bit_scan_consecutive_range(&mask, &start, &array_count);
3743 int basearrayidx = lookup_image_array(ctx, dst_reg->Register.Index);
3744 emit_buff(glsl_strbufs, "switch (addr%d + %d) {\n", dst_reg->Indirect.Index,
3745 dst_reg->Register.Index - base);
3746
3747 for (int i = 0; i < array_count; ++i) {
3748 char dst_tmp[128];
3749 emit_buff(glsl_strbufs, "case %d:\n", i);
3750 snprintf(dst_tmp, 128, "%simg%d[%d]", cname, basearrayidx, i);
3751 emit_store_mem(glsl_strbufs, dst_tmp, dst_reg->Register.WriteMask, srcs,
3752 conversion);
3753 emit_buff(glsl_strbufs, "break;\n");
3754 }
3755 emit_buf(glsl_strbufs, "}\n");
3756 }
3757 }
3758 }
3759
emit_load_mem(struct vrend_glsl_strbufs * glsl_strbufs,const char * dst,int writemask,const char * conversion,const char * atomic_op,const char * src0,const char * atomic_src)3760 static void emit_load_mem(struct vrend_glsl_strbufs *glsl_strbufs, const char *dst, int writemask,
3761 const char *conversion, const char *atomic_op, const char *src0,
3762 const char *atomic_src)
3763 {
3764 static const char swizzle_char[] = "xyzw";
3765 for (int i = 0; i < 4; ++i) {
3766 if (writemask & (1 << i)) {
3767 emit_buff(glsl_strbufs, "%s.%c = (%s(%s(%s[ssbo_addr_temp + %du]%s)));\n", dst,
3768 swizzle_char[i], conversion, atomic_op, src0, i, atomic_src);
3769 }
3770 }
3771 }
3772
3773 static bool
translate_load(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,uint8_t ssbo_memory_qualifier[],struct vrend_shader_image images[],const struct tgsi_full_instruction * inst,struct source_info * sinfo,struct dest_info * dinfo,const char * srcs[4],const char * dst,const char * writemask)3774 translate_load(const struct dump_ctx *ctx,
3775 struct vrend_glsl_strbufs *glsl_strbufs,
3776 uint8_t ssbo_memory_qualifier[],
3777 struct vrend_shader_image images[],
3778 const struct tgsi_full_instruction *inst,
3779 struct source_info *sinfo,
3780 struct dest_info *dinfo,
3781 const char *srcs[4],
3782 const char *dst,
3783 const char *writemask)
3784 {
3785 const struct tgsi_full_src_register *src = &inst->Src[0];
3786 if (src->Register.File == TGSI_FILE_IMAGE) {
3787
3788 /* Bail out if we want to load from an image that is not actually used */
3789 assert(sinfo->sreg_index >= 0);
3790 if (!((1 << sinfo->sreg_index) & ctx->images_used_mask))
3791 return false;
3792
3793 set_image_qualifier(images, ctx->images_used_mask, inst, inst->Src[0].Register.Index, inst->Src[0].Register.Indirect);
3794
3795
3796 bool is_ms = false;
3797 enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx->images[sinfo->sreg_index].decl.Resource, &is_ms, ctx->cfg->use_gles);
3798 enum vrend_type_qualifier dtypeprefix = TYPE_CONVERSION_NONE;
3799 const char *conversion = sinfo->override_no_cast[1] ? "" : get_string(FLOAT_BITS_TO_INT);
3800 enum tgsi_return_type itype;
3801 get_internalformat_string(ctx->images[sinfo->sreg_index].decl.Format, &itype);
3802 char ms_str[32] = "";
3803 const char *wm = dinfo->dst_override_no_wm[0] ? "" : writemask;
3804 if (is_ms) {
3805 snprintf(ms_str, 32, ", int(%s.w)", srcs[1]);
3806 }
3807 switch (itype) {
3808 case TGSI_RETURN_TYPE_UINT:
3809 dtypeprefix = UINT_BITS_TO_FLOAT;
3810 break;
3811 case TGSI_RETURN_TYPE_SINT:
3812 dtypeprefix = INT_BITS_TO_FLOAT;
3813 break;
3814 default:
3815 break;
3816 }
3817
3818 /* On GL WR translates to writable, but on GLES we translate this to writeonly
3819 * because for most formats one has to specify one or the other, so if we have an
3820 * image with the TGSI WR specification, and read from it, we drop the Writable flag.
3821 * For the images that allow RW this is of no consequence, and for the others a write
3822 * access will fail instead of the read access, but this doesn't constitue a regression
3823 * because we couldn't do both, read and write, anyway. */
3824 if (ctx->cfg->use_gles && ctx->images[sinfo->sreg_index].decl.Writable &&
3825 (ctx->images[sinfo->sreg_index].decl.Format != PIPE_FORMAT_R32_FLOAT) &&
3826 (ctx->images[sinfo->sreg_index].decl.Format != PIPE_FORMAT_R32_SINT) &&
3827 (ctx->images[sinfo->sreg_index].decl.Format != PIPE_FORMAT_R32_UINT))
3828 images[sinfo->sreg_index].decl.Writable = 0;
3829
3830 if (!ctx->cfg->use_gles || !inst->Src[0].Register.Indirect) {
3831 emit_buff(glsl_strbufs, "%s = %s(imageLoad(%s, %s(%s(%s))%s)%s);\n",
3832 dst, get_string(dtypeprefix),
3833 srcs[0], get_string(coord_prefix), conversion, srcs[1],
3834 ms_str, wm);
3835 } else {
3836 char src[32] = "";
3837 struct vrend_array *image = lookup_image_array_ptr(ctx, inst->Src[0].Register.Index);
3838 if (image) {
3839 int basearrayidx = image->first;
3840 int array_size = image->array_size;
3841 emit_buff(glsl_strbufs, "switch (addr%d + %d) {\n", inst->Src[0].Indirect.Index, inst->Src[0].Register.Index - basearrayidx);
3842 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3843
3844 for (int i = 0; i < array_size; ++i) {
3845 snprintf(src, 32, "%simg%d[%d]", cname, basearrayidx, i);
3846 emit_buff(glsl_strbufs, "case %d: %s = %s(imageLoad(%s, %s(%s(%s))%s)%s);break;\n",
3847 i, dst, get_string(dtypeprefix),
3848 src, get_string(coord_prefix), conversion, srcs[1],
3849 ms_str, wm);
3850 }
3851 emit_buff(glsl_strbufs, "}\n");
3852 }
3853 }
3854 } else if (src->Register.File == TGSI_FILE_BUFFER ||
3855 src->Register.File == TGSI_FILE_MEMORY) {
3856 char mydst[255], atomic_op[9], atomic_src[10];
3857 enum vrend_type_qualifier dtypeprefix;
3858
3859 set_memory_qualifier(ssbo_memory_qualifier, ctx->ssbo_used_mask, inst, inst->Src[0].Register.Index, inst->Src[0].Register.Indirect);
3860
3861 const char *d = dst;
3862 char *md = mydst;
3863 unsigned i = 0;
3864 while ((i < sizeof(mydst) - 1) && *d && *d != '.')
3865 *md++ = *d++;
3866 *md = 0;
3867
3868 emit_buff(glsl_strbufs, "ssbo_addr_temp = uint(floatBitsToUint(%s)) >> 2;\n", srcs[1]);
3869
3870 atomic_op[0] = atomic_src[0] = '\0';
3871 if (ctx->ssbo_atomic_mask & (1 << src->Register.Index)) {
3872 /* Emulate atomicCounter with atomicOr. */
3873 strcpy(atomic_op, "atomicOr");
3874 strcpy(atomic_src, ", uint(0)");
3875 }
3876
3877 dtypeprefix = (is_integer_memory(ctx, src->Register.File, src->Register.Index)) ? INT_BITS_TO_FLOAT : UINT_BITS_TO_FLOAT;
3878
3879 if (!ctx->cfg->use_gles || !inst->Src[0].Register.Indirect) {
3880 emit_load_mem(glsl_strbufs, mydst, inst->Dst[0].Register.WriteMask, get_string(dtypeprefix), atomic_op, srcs[0], atomic_src);
3881 } else {
3882 char src[128] = "";
3883 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3884 bool atomic_ssbo = ctx->ssbo_atomic_mask & (1 << inst->Src[0].Register.Index);
3885 const char *atomic_str = atomic_ssbo ? "atomic" : "";
3886 uint base = atomic_ssbo ? ctx->ssbo_atomic_array_base : ctx->ssbo_array_base;
3887 int start, array_count;
3888 uint32_t mask = ctx->ssbo_used_mask;
3889 u_bit_scan_consecutive_range(&mask, &start, &array_count);
3890
3891 emit_buff(glsl_strbufs, "switch (addr%d + %d) {\n", inst->Src[0].Indirect.Index, inst->Src[0].Register.Index - base);
3892 for (int i = 0; i < array_count; ++i) {
3893 emit_buff(glsl_strbufs, "case %d:\n", i);
3894 snprintf(src, 128,"%sssboarr%s[%d].%sssbocontents%d", cname, atomic_str, i, cname, base);
3895 emit_load_mem(glsl_strbufs, mydst, inst->Dst[0].Register.WriteMask, get_string(dtypeprefix), atomic_op, src, atomic_src);
3896 emit_buff(glsl_strbufs, " break;\n");
3897 }
3898 emit_buf(glsl_strbufs, "}\n");
3899 }
3900 } else if (src->Register.File == TGSI_FILE_HW_ATOMIC) {
3901 emit_buff(glsl_strbufs, "%s = uintBitsToFloat(atomicCounter(%s));\n", dst, srcs[0]);
3902 }
3903 return true;
3904 }
3905
get_atomic_opname(int tgsi_opcode,bool * is_cas)3906 static const char *get_atomic_opname(int tgsi_opcode, bool *is_cas)
3907 {
3908 const char *opname;
3909 *is_cas = false;
3910 switch (tgsi_opcode) {
3911 case TGSI_OPCODE_ATOMUADD:
3912 opname = "Add";
3913 break;
3914 case TGSI_OPCODE_ATOMXCHG:
3915 opname = "Exchange";
3916 break;
3917 case TGSI_OPCODE_ATOMCAS:
3918 opname = "CompSwap";
3919 *is_cas = true;
3920 break;
3921 case TGSI_OPCODE_ATOMAND:
3922 opname = "And";
3923 break;
3924 case TGSI_OPCODE_ATOMOR:
3925 opname = "Or";
3926 break;
3927 case TGSI_OPCODE_ATOMXOR:
3928 opname = "Xor";
3929 break;
3930 case TGSI_OPCODE_ATOMUMIN:
3931 opname = "Min";
3932 break;
3933 case TGSI_OPCODE_ATOMUMAX:
3934 opname = "Max";
3935 break;
3936 case TGSI_OPCODE_ATOMIMIN:
3937 opname = "Min";
3938 break;
3939 case TGSI_OPCODE_ATOMIMAX:
3940 opname = "Max";
3941 break;
3942 default:
3943 vrend_printf( "illegal atomic opcode");
3944 return NULL;
3945 }
3946 return opname;
3947 }
3948
3949 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
3950 static void
translate_resq(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,const char * srcs[4],const char * dst,const char * writemask)3951 translate_resq(struct dump_ctx *ctx, const struct tgsi_full_instruction *inst,
3952 const char *srcs[4], const char *dst, const char *writemask)
3953 {
3954 const struct tgsi_full_src_register *src = &inst->Src[0];
3955
3956 if (src->Register.File == TGSI_FILE_IMAGE) {
3957 if (inst->Dst[0].Register.WriteMask & 0x8) {
3958 ctx->shader_req_bits |= SHADER_REQ_TXQS | SHADER_REQ_INTS;
3959 emit_buff(&ctx->glsl_strbufs, "%s = %s(imageSamples(%s));\n",
3960 dst, get_string(INT_BITS_TO_FLOAT), srcs[0]);
3961 }
3962 if (inst->Dst[0].Register.WriteMask & 0x7) {
3963 const char *swizzle_mask = (ctx->cfg->use_gles && inst->Memory.Texture == TGSI_TEXTURE_1D_ARRAY) ?
3964 ".xz" : "";
3965 ctx->shader_req_bits |= SHADER_REQ_IMAGE_SIZE | SHADER_REQ_INTS;
3966 bool skip_emit_writemask = inst->Memory.Texture == TGSI_TEXTURE_BUFFER ||
3967 (!ctx->cfg->use_gles && inst->Memory.Texture == TGSI_TEXTURE_1D);
3968
3969 emit_buff(&ctx->glsl_strbufs, "%s = %s(imageSize(%s)%s%s);\n",
3970 dst, get_string(INT_BITS_TO_FLOAT), srcs[0],
3971 swizzle_mask, skip_emit_writemask ? "" : writemask);
3972 }
3973 } else if (src->Register.File == TGSI_FILE_BUFFER) {
3974 emit_buff(&ctx->glsl_strbufs, "%s = %s(int(%s.length()) << 2);\n",
3975 dst, get_string(INT_BITS_TO_FLOAT), srcs[0]);
3976 }
3977 }
3978
3979 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
3980 static void
translate_atomic(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,struct source_info * sinfo,const char * srcs[4],char * dst)3981 translate_atomic(struct dump_ctx *ctx,
3982 const struct tgsi_full_instruction *inst,
3983 struct source_info *sinfo,
3984 const char *srcs[4],
3985 char *dst)
3986 {
3987 const struct tgsi_full_src_register *src = &inst->Src[0];
3988 const char *opname;
3989 enum vrend_type_qualifier stypeprefix = TYPE_CONVERSION_NONE;
3990 enum vrend_type_qualifier dtypeprefix = TYPE_CONVERSION_NONE;
3991 enum vrend_type_qualifier stypecast = TYPE_CONVERSION_NONE;
3992 bool is_cas;
3993 char cas_str[128] = "";
3994
3995 if (src->Register.File == TGSI_FILE_IMAGE) {
3996 enum tgsi_return_type itype;
3997 get_internalformat_string(ctx->images[sinfo->sreg_index].decl.Format, &itype);
3998 switch (itype) {
3999 default:
4000 case TGSI_RETURN_TYPE_UINT:
4001 stypeprefix = FLOAT_BITS_TO_UINT;
4002 dtypeprefix = UINT_BITS_TO_FLOAT;
4003 stypecast = UINT;
4004 break;
4005 case TGSI_RETURN_TYPE_SINT:
4006 stypeprefix = FLOAT_BITS_TO_INT;
4007 dtypeprefix = INT_BITS_TO_FLOAT;
4008 stypecast = INT;
4009 break;
4010 case TGSI_RETURN_TYPE_FLOAT:
4011 if (ctx->cfg->has_es31_compat)
4012 ctx->shader_req_bits |= SHADER_REQ_ES31_COMPAT;
4013 else
4014 ctx->shader_req_bits |= SHADER_REQ_SHADER_ATOMIC_FLOAT;
4015 stypecast = FLOAT;
4016 break;
4017 }
4018 } else {
4019 stypeprefix = FLOAT_BITS_TO_UINT;
4020 dtypeprefix = UINT_BITS_TO_FLOAT;
4021 stypecast = UINT;
4022 }
4023
4024 opname = get_atomic_opname(inst->Instruction.Opcode, &is_cas);
4025 if (!opname) {
4026 set_buf_error(&ctx->glsl_strbufs);
4027 return;
4028 }
4029
4030 if (is_cas)
4031 snprintf(cas_str, 128, ", %s(%s(%s))", get_string(stypecast), get_string(stypeprefix), srcs[3]);
4032
4033 if (src->Register.File == TGSI_FILE_IMAGE) {
4034 bool is_ms = false;
4035 enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx->images[sinfo->sreg_index].decl.Resource, &is_ms, ctx->cfg->use_gles);
4036 const char *conversion = sinfo->override_no_cast[1] ? "" : get_string(FLOAT_BITS_TO_INT);
4037 char ms_str[32] = "";
4038 if (is_ms) {
4039 snprintf(ms_str, 32, ", int(%s.w)", srcs[1]);
4040 }
4041
4042 if (!ctx->cfg->use_gles || !inst->Src[0].Register.Indirect) {
4043 emit_buff(&ctx->glsl_strbufs, "%s = %s(imageAtomic%s(%s, %s(%s(%s))%s, %s(%s(%s))%s));\n",
4044 dst, get_string(dtypeprefix), opname, srcs[0],
4045 get_string(coord_prefix), conversion, srcs[1], ms_str,
4046 get_string(stypecast), get_string(stypeprefix), srcs[2],
4047 cas_str);
4048 } else {
4049 char src[32] = "";
4050 struct vrend_array *image = lookup_image_array_ptr(ctx, inst->Src[0].Register.Index);
4051 if (image) {
4052 int basearrayidx = image->first;
4053 int array_size = image->array_size;
4054 emit_buff(&ctx->glsl_strbufs, "switch (addr%d + %d) {\n", inst->Src[0].Indirect.Index, inst->Src[0].Register.Index - basearrayidx);
4055 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4056
4057 for (int i = 0; i < array_size; ++i) {
4058 snprintf(src, 32, "%simg%d[%d]", cname, basearrayidx, i);
4059 emit_buff(&ctx->glsl_strbufs, "case %d: %s = %s(imageAtomic%s(%s, %s(%s(%s))%s, %s(%s(%s))%s));\n",
4060 i, dst, get_string(dtypeprefix), opname, src,
4061 get_string(coord_prefix), conversion, srcs[1],
4062 ms_str, get_string(stypecast),
4063 get_string(stypeprefix), srcs[2], cas_str);
4064 }
4065 emit_buff(&ctx->glsl_strbufs, "}\n");
4066 }
4067 }
4068 ctx->shader_req_bits |= SHADER_REQ_IMAGE_ATOMIC;
4069 }
4070 if (src->Register.File == TGSI_FILE_BUFFER || src->Register.File == TGSI_FILE_MEMORY) {
4071 enum vrend_type_qualifier type;
4072 if ((is_integer_memory(ctx, src->Register.File, src->Register.Index))) {
4073 type = INT;
4074 dtypeprefix = INT_BITS_TO_FLOAT;
4075 stypeprefix = FLOAT_BITS_TO_INT;
4076 } else {
4077 type = UINT;
4078 dtypeprefix = UINT_BITS_TO_FLOAT;
4079 stypeprefix = FLOAT_BITS_TO_UINT;
4080 }
4081
4082 if (is_cas)
4083 snprintf(cas_str, sizeof(cas_str), ", %s(%s(%s))", get_string(type), get_string(stypeprefix), srcs[3]);
4084
4085 emit_buff(&ctx->glsl_strbufs, "%s = %s(atomic%s(%s[int(floatBitsToInt(%s)) >> 2], %s(%s(%s).x)%s));\n",
4086 dst, get_string(dtypeprefix), opname, srcs[0], srcs[1],
4087 get_string(type), get_string(stypeprefix), srcs[2], cas_str);
4088 }
4089 if(src->Register.File == TGSI_FILE_HW_ATOMIC) {
4090 if (sinfo->imm_value == -1)
4091 emit_buff(&ctx->glsl_strbufs, "%s = %s(atomicCounterDecrement(%s) + 1u);\n",
4092 dst, get_string(dtypeprefix), srcs[0]);
4093 else if (sinfo->imm_value == 1)
4094 emit_buff(&ctx->glsl_strbufs, "%s = %s(atomicCounterIncrement(%s));\n",
4095 dst, get_string(dtypeprefix), srcs[0]);
4096 else
4097 emit_buff(&ctx->glsl_strbufs, "%s = %s(atomicCounter%sARB(%s, floatBitsToUint(%s).x%s));\n",
4098 dst, get_string(dtypeprefix), opname, srcs[0], srcs[2],
4099 cas_str);
4100 }
4101
4102 }
4103
reswizzle_dest(const struct vrend_shader_io * io,const struct tgsi_full_dst_register * dst_reg,char * reswizzled,const char * writemask)4104 static const char *reswizzle_dest(const struct vrend_shader_io *io, const struct tgsi_full_dst_register *dst_reg,
4105 char *reswizzled, const char *writemask)
4106 {
4107 if (io->usage_mask != 0xf) {
4108 if (io->num_components > 1) {
4109 const int wm = dst_reg->Register.WriteMask;
4110 int k = 1;
4111 reswizzled[0] = '.';
4112 for (int i = 0; i < io->num_components; ++i) {
4113 if (wm & (1 << i))
4114 reswizzled[k++] = get_swiz_char(i);
4115 }
4116 reswizzled[k] = 0;
4117 }
4118 writemask = reswizzled;
4119 }
4120 return writemask;
4121 }
4122
get_destination_info_generic(const struct dump_ctx * ctx,const struct tgsi_full_dst_register * dst_reg,const struct vrend_shader_io * io,const char * writemask,struct vrend_strbuf * result)4123 static void get_destination_info_generic(const struct dump_ctx *ctx,
4124 const struct tgsi_full_dst_register *dst_reg,
4125 const struct vrend_shader_io *io,
4126 const char *writemask,
4127 struct vrend_strbuf *result)
4128 {
4129 const char *blkarray = (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL) ? "[gl_InvocationID]" : "";
4130 const char *stage_prefix = get_stage_output_name_prefix(ctx->prog_type);
4131 const char *wm = io->override_no_wm ? "" : writemask;
4132 char reswizzled[6] = "";
4133 char outvarname[64];
4134
4135 wm = reswizzle_dest(io, dst_reg, reswizzled, writemask);
4136
4137 strbuf_reset(result);
4138
4139 enum io_decl_type decl_type = decl_plain;
4140 if (io->first != io->last && prefer_generic_io_block(ctx, io_out)) {
4141 get_blockvarname(outvarname, stage_prefix, io, blkarray);
4142 blkarray = outvarname;
4143 decl_type = decl_block;
4144 }
4145 vrend_shader_write_io_as_dst(result, blkarray, io, dst_reg, decl_type);
4146 strbuf_appendf(result, "%s", wm);
4147 }
4148
4149 static
find_io_index(int num_io,struct vrend_shader_io * io,int index)4150 int find_io_index(int num_io, struct vrend_shader_io *io, int index)
4151 {
4152 for (int j = 0; j < num_io; j++) {
4153 if (io[j].first <= index &&
4154 io[j].last >= index) {
4155 return j;
4156 }
4157 }
4158 return -1;
4159 }
4160
4161 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
4162 static bool
get_destination_info(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,struct dest_info * dinfo,struct vrend_strbuf dst_bufs[3],char fp64_dsts[3][255],char * writemask)4163 get_destination_info(struct dump_ctx *ctx,
4164 const struct tgsi_full_instruction *inst,
4165 struct dest_info *dinfo,
4166 struct vrend_strbuf dst_bufs[3],
4167 char fp64_dsts[3][255],
4168 char *writemask)
4169 {
4170 const struct tgsi_full_dst_register *dst_reg;
4171 enum tgsi_opcode_type dtype = tgsi_opcode_infer_dst_type(inst->Instruction.Opcode);
4172
4173 if (dtype == TGSI_TYPE_SIGNED || dtype == TGSI_TYPE_UNSIGNED)
4174 ctx->shader_req_bits |= SHADER_REQ_INTS;
4175
4176 if (dtype == TGSI_TYPE_DOUBLE) {
4177 /* we need the uvec2 conversion for doubles */
4178 ctx->shader_req_bits |= SHADER_REQ_INTS | SHADER_REQ_FP64;
4179 }
4180
4181 if (inst->Instruction.Opcode == TGSI_OPCODE_TXQ) {
4182 dinfo->dtypeprefix = INT_BITS_TO_FLOAT;
4183 } else {
4184 switch (dtype) {
4185 case TGSI_TYPE_UNSIGNED:
4186 dinfo->dtypeprefix = UINT_BITS_TO_FLOAT;
4187 break;
4188 case TGSI_TYPE_SIGNED:
4189 dinfo->dtypeprefix = INT_BITS_TO_FLOAT;
4190 break;
4191 default:
4192 break;
4193 }
4194 }
4195
4196 for (uint32_t i = 0; i < inst->Instruction.NumDstRegs; i++) {
4197 char fp64_writemask[6] = "";
4198 dst_reg = &inst->Dst[i];
4199 dinfo->dst_override_no_wm[i] = false;
4200 if (dst_reg->Register.WriteMask != TGSI_WRITEMASK_XYZW) {
4201 int wm_idx = 0, dbl_wm_idx = 0;
4202 writemask[wm_idx++] = '.';
4203 fp64_writemask[dbl_wm_idx++] = '.';
4204
4205 if (dst_reg->Register.WriteMask & 0x1)
4206 writemask[wm_idx++] = 'x';
4207 if (dst_reg->Register.WriteMask & 0x2)
4208 writemask[wm_idx++] = 'y';
4209 if (dst_reg->Register.WriteMask & 0x4)
4210 writemask[wm_idx++] = 'z';
4211 if (dst_reg->Register.WriteMask & 0x8)
4212 writemask[wm_idx++] = 'w';
4213
4214 if (dtype == TGSI_TYPE_DOUBLE) {
4215 if (dst_reg->Register.WriteMask & 0x3)
4216 fp64_writemask[dbl_wm_idx++] = 'x';
4217 if (dst_reg->Register.WriteMask & 0xc)
4218 fp64_writemask[dbl_wm_idx++] = 'y';
4219 }
4220
4221 if (dtype == TGSI_TYPE_DOUBLE) {
4222 if (dbl_wm_idx == 2)
4223 dinfo->dstconv = DOUBLE;
4224 else
4225 dinfo->dstconv = DVEC2;
4226 } else {
4227 dinfo->dstconv = FLOAT + wm_idx - 2;
4228 dinfo->udstconv = UINT + wm_idx - 2;
4229 dinfo->idstconv = INT + wm_idx - 2;
4230 }
4231 } else {
4232 if (dtype == TGSI_TYPE_DOUBLE)
4233 dinfo->dstconv = DVEC2;
4234 else
4235 dinfo->dstconv = VEC4;
4236 dinfo->udstconv = UVEC4;
4237 dinfo->idstconv = IVEC4;
4238 }
4239
4240 if (dst_reg->Register.File == TGSI_FILE_OUTPUT) {
4241 int j = find_io_index(ctx->num_outputs, ctx->outputs,
4242 dst_reg->Register.Index);
4243
4244 if (j < 0)
4245 return false;
4246
4247 struct vrend_shader_io *output = &ctx->outputs[j];
4248
4249 if (inst->Instruction.Precise) {
4250 if (!output->invariant && output->name != TGSI_SEMANTIC_CLIPVERTEX &&
4251 ctx->cfg->has_gpu_shader5) {
4252 output->precise = true;
4253 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
4254 }
4255 }
4256
4257 if (ctx->glsl_ver_required >= 140 && output->name == TGSI_SEMANTIC_CLIPVERTEX) {
4258 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL) {
4259 strbuf_fmt(&dst_bufs[i], "%s[gl_InvocationID]", output->glsl_name);
4260 } else {
4261 strbuf_fmt(&dst_bufs[i], "%s", ctx->is_last_vertex_stage ? "clipv_tmp" : output->glsl_name);
4262 }
4263 } else if (output->name == TGSI_SEMANTIC_CLIPDIST) {
4264 char clip_indirect[32] = "";
4265 if (output->first != output->last) {
4266 if (dst_reg->Register.Indirect)
4267 snprintf(clip_indirect, sizeof(clip_indirect), "+ addr%d", dst_reg->Indirect.Index);
4268 else
4269 snprintf(clip_indirect, sizeof(clip_indirect), "+ %d", dst_reg->Register.Index - output->first);
4270 }
4271 strbuf_fmt(&dst_bufs[i], "clip_dist_temp[%d %s]%s", output->sid, clip_indirect, writemask);
4272 } else if (output->name == TGSI_SEMANTIC_TESSOUTER ||
4273 output->name == TGSI_SEMANTIC_TESSINNER ||
4274 output->name == TGSI_SEMANTIC_SAMPLEMASK) {
4275 int idx;
4276 switch (dst_reg->Register.WriteMask) {
4277 case 0x1: idx = 0; break;
4278 case 0x2: idx = 1; break;
4279 case 0x4: idx = 2; break;
4280 case 0x8: idx = 3; break;
4281 default:
4282 idx = 0;
4283 break;
4284 }
4285 strbuf_fmt(&dst_bufs[i], "%s[%d]", output->glsl_name, idx);
4286 if (output->is_int) {
4287 dinfo->dtypeprefix = FLOAT_BITS_TO_INT;
4288 dinfo->dstconv = INT;
4289 }
4290 } else {
4291 if (output->glsl_gl_block) {
4292 strbuf_fmt(&dst_bufs[i], "gl_out[%s].%s%s",
4293 ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ? "gl_InvocationID" : "0",
4294 output->glsl_name,
4295 output->override_no_wm ? "" : writemask);
4296 } else if (output->name == TGSI_SEMANTIC_GENERIC) {
4297 struct vrend_shader_io *io = ctx->generic_ios.output_range.used ? &ctx->generic_ios.output_range.io : output;
4298 get_destination_info_generic(ctx, dst_reg, io, writemask, &dst_bufs[i]);
4299 dinfo->dst_override_no_wm[i] = output->override_no_wm;
4300 } else if (output->name == TGSI_SEMANTIC_TEXCOORD) {
4301 get_destination_info_generic(ctx, dst_reg, output, writemask, &dst_bufs[i]);
4302 dinfo->dst_override_no_wm[i] = output->override_no_wm;
4303 } else if (output->name == TGSI_SEMANTIC_PATCH) {
4304 struct vrend_shader_io *io = ctx->patch_ios.output_range.used ? &ctx->patch_ios.output_range.io : output;
4305 char reswizzled[6] = "";
4306 const char *wm = reswizzle_dest(io, dst_reg, reswizzled, writemask);
4307 strbuf_reset(&dst_bufs[i]);
4308 vrend_shader_write_io_as_dst(&dst_bufs[i], "", io, dst_reg, decl_plain);
4309 if (!output->override_no_wm)
4310 strbuf_appendf(&dst_bufs[i], "%s", wm);
4311 dinfo->dst_override_no_wm[i] = output->override_no_wm;
4312 } else {
4313 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL) {
4314 strbuf_fmt(&dst_bufs[i], "%s[gl_InvocationID]%s", output->glsl_name, output->override_no_wm ? "" : writemask);
4315 } else {
4316 strbuf_fmt(&dst_bufs[i], "%s%s", output->glsl_name, output->override_no_wm ? "" : writemask);
4317 }
4318 dinfo->dst_override_no_wm[i] = output->override_no_wm;
4319 }
4320 if (output->is_int) {
4321 if (dinfo->dtypeprefix == TYPE_CONVERSION_NONE)
4322 dinfo->dtypeprefix = FLOAT_BITS_TO_INT;
4323 dinfo->dstconv = INT;
4324 }
4325 else if (output->type == VEC_UINT) {
4326 if (dinfo->dtypeprefix == TYPE_CONVERSION_NONE)
4327 dinfo->dtypeprefix = FLOAT_BITS_TO_UINT;
4328 dinfo->dstconv = dinfo->udstconv;
4329 }
4330 else if (output->type == VEC_INT) {
4331 if (dinfo->dtypeprefix == TYPE_CONVERSION_NONE)
4332 dinfo->dtypeprefix = FLOAT_BITS_TO_INT;
4333 dinfo->dstconv = dinfo->idstconv;
4334 }
4335 if (output->name == TGSI_SEMANTIC_PSIZE) {
4336 dinfo->dstconv = FLOAT;
4337 break;
4338 }
4339 }
4340 }
4341 else if (dst_reg->Register.File == TGSI_FILE_TEMPORARY) {
4342 char temp_buf[64];
4343 get_temp(ctx, dst_reg->Register.Indirect, 0, dst_reg->Register.Index,
4344 temp_buf, &ctx->require_dummy_value);
4345 strbuf_fmt(&dst_bufs[i], "%s%s", temp_buf, writemask);
4346 if (inst->Instruction.Precise) {
4347 struct vrend_temp_range *range = find_temp_range(ctx, dst_reg->Register.Index);
4348 if (range && ctx->cfg->has_gpu_shader5) {
4349 range->precise_result = true;
4350 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
4351 }
4352 }
4353 }
4354 else if (dst_reg->Register.File == TGSI_FILE_IMAGE) {
4355 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4356 if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
4357 int basearrayidx = lookup_image_array(ctx, dst_reg->Register.Index);
4358 if (dst_reg->Register.Indirect) {
4359 assert(dst_reg->Indirect.File == TGSI_FILE_ADDRESS);
4360 strbuf_fmt(&dst_bufs[i], "%simg%d[addr%d + %d]", cname, basearrayidx, dst_reg->Indirect.Index, dst_reg->Register.Index - basearrayidx);
4361 } else
4362 strbuf_fmt(&dst_bufs[i], "%simg%d[%d]", cname, basearrayidx, dst_reg->Register.Index - basearrayidx);
4363 } else
4364 strbuf_fmt(&dst_bufs[i], "%simg%d", cname, dst_reg->Register.Index);
4365 dinfo->dest_index = dst_reg->Register.Index;
4366 } else if (dst_reg->Register.File == TGSI_FILE_BUFFER) {
4367 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4368 if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
4369 bool atomic_ssbo = ctx->ssbo_atomic_mask & (1 << dst_reg->Register.Index);
4370 const char *atomic_str = atomic_ssbo ? "atomic" : "";
4371 int base = atomic_ssbo ? ctx->ssbo_atomic_array_base : ctx->ssbo_array_base;
4372 if (dst_reg->Register.Indirect) {
4373 strbuf_fmt(&dst_bufs[i], "%sssboarr%s[addr%d+%d].%sssbocontents%d", cname, atomic_str, dst_reg->Indirect.Index, dst_reg->Register.Index - base, cname, base);
4374 } else
4375 strbuf_fmt(&dst_bufs[i], "%sssboarr%s[%d].%sssbocontents%d", cname, atomic_str, dst_reg->Register.Index - base, cname, base);
4376 } else
4377 strbuf_fmt(&dst_bufs[i], "%sssbocontents%d", cname, dst_reg->Register.Index);
4378 dinfo->dest_index = dst_reg->Register.Index;
4379 } else if (dst_reg->Register.File == TGSI_FILE_MEMORY) {
4380 strbuf_fmt(&dst_bufs[i], "values");
4381 } else if (dst_reg->Register.File == TGSI_FILE_ADDRESS) {
4382 strbuf_fmt(&dst_bufs[i], "addr%d", dst_reg->Register.Index);
4383 }
4384
4385 if (dtype == TGSI_TYPE_DOUBLE) {
4386 strcpy(fp64_dsts[i], dst_bufs[i].buf);
4387 strbuf_fmt(&dst_bufs[i], "fp64_dst[%d]%s", i, fp64_writemask);
4388 writemask[0] = 0;
4389 }
4390
4391 }
4392
4393 return true;
4394 }
4395
shift_swizzles(const struct vrend_shader_io * io,const struct tgsi_full_src_register * src,int swz_offset,char * swizzle_shifted,const char * swizzle)4396 static const char *shift_swizzles(const struct vrend_shader_io *io, const struct tgsi_full_src_register *src,
4397 int swz_offset, char *swizzle_shifted, const char *swizzle)
4398 {
4399 if (io->usage_mask != 0xf && swizzle[0]) {
4400 if (io->num_components > 1) {
4401 swizzle_shifted[swz_offset++] = '.';
4402 for (int i = 0; i < 4; ++i) {
4403 switch (i) {
4404 case 0: swizzle_shifted[swz_offset++] = get_swiz_char(src->Register.SwizzleX);
4405 break;
4406 case 1: swizzle_shifted[swz_offset++] = get_swiz_char(src->Register.SwizzleY);
4407 break;
4408 case 2: swizzle_shifted[swz_offset++] = src->Register.SwizzleZ < io->num_components ?
4409 get_swiz_char(src->Register.SwizzleZ) : 'x';
4410 break;
4411 case 3: swizzle_shifted[swz_offset++] = src->Register.SwizzleW < io->num_components ?
4412 get_swiz_char(src->Register.SwizzleW) : 'x';
4413 }
4414 }
4415 swizzle_shifted[swz_offset] = 0;
4416 }
4417 swizzle = swizzle_shifted;
4418 }
4419 return swizzle;
4420 }
4421
get_source_info_generic(const struct dump_ctx * ctx,enum io_type iot,enum vrend_type_qualifier srcstypeprefix,const char * prefix,const struct tgsi_full_src_register * src,const struct vrend_shader_io * io,const char * arrayname,const char * swizzle,struct vrend_strbuf * result)4422 static void get_source_info_generic(const struct dump_ctx *ctx,
4423 enum io_type iot,
4424 enum vrend_type_qualifier srcstypeprefix,
4425 const char *prefix,
4426 const struct tgsi_full_src_register *src,
4427 const struct vrend_shader_io *io,
4428 const char *arrayname,
4429 const char *swizzle,
4430 struct vrend_strbuf *result)
4431 {
4432 int swz_offset = 0;
4433 char swizzle_shifted[6] = "";
4434 char outvarname[64];
4435
4436 if (swizzle[0] == ')') {
4437 swizzle_shifted[swz_offset++] = ')';
4438 swizzle_shifted[swz_offset] = 0;
4439 }
4440
4441 /* This IO element is not using all vector elements, so we have to shift the swizzle names */
4442 swizzle = shift_swizzles(io, src, swz_offset, swizzle_shifted, swizzle);
4443
4444 strbuf_fmt(result, "%s(%s", get_string(srcstypeprefix), prefix);
4445
4446 enum io_decl_type decl_type = decl_plain;
4447
4448 if ((io->first != io->last || io->overlapping_array) &&
4449 prefer_generic_io_block(ctx, iot)) {
4450
4451 const struct vrend_shader_io *array = io->overlapping_array ?
4452 io->overlapping_array : io;
4453
4454 const char *stage_prefix = iot == io_in ?
4455 get_stage_input_name_prefix(ctx, ctx->prog_type) :
4456 get_stage_output_name_prefix(ctx->prog_type);
4457 get_blockvarname(outvarname, stage_prefix, array, arrayname);
4458 arrayname = outvarname;
4459 decl_type = decl_block;
4460 }
4461
4462 vrend_shader_write_io_as_src(result, arrayname, io, src, decl_type);
4463 strbuf_appendf(result, "%s)", io->is_int ? "" : swizzle);
4464 }
4465
get_source_info_patch(enum vrend_type_qualifier srcstypeprefix,const char * prefix,const struct tgsi_full_src_register * src,const struct vrend_shader_io * io,const char * arrayname,const char * swizzle,struct vrend_strbuf * result)4466 static void get_source_info_patch(enum vrend_type_qualifier srcstypeprefix,
4467 const char *prefix,
4468 const struct tgsi_full_src_register *src,
4469 const struct vrend_shader_io *io,
4470 const char *arrayname,
4471 const char *swizzle,
4472 struct vrend_strbuf *result)
4473 {
4474 int swz_offset = 0;
4475 char swizzle_shifted[7] = "";
4476 if (swizzle[0] == ')') {
4477 swizzle_shifted[swz_offset++] = ')';
4478 swizzle_shifted[swz_offset] = 0;
4479 }
4480
4481 swizzle = shift_swizzles(io, src, swz_offset, swizzle_shifted, swizzle);
4482
4483 strbuf_fmt(result, "%s(%s", get_string(srcstypeprefix), prefix);
4484 vrend_shader_write_io_as_src(result, io->last == io->first ? arrayname : "", io, src, decl_plain);
4485 strbuf_appendf(result, "%s)", io->is_int ? "" : swizzle);
4486 }
4487
get_tesslevel_as_source(struct vrend_strbuf * src_buf,const char * prefix,const char * name,const struct tgsi_src_register * reg)4488 static void get_tesslevel_as_source(struct vrend_strbuf *src_buf, const char *prefix,
4489 const char *name, const struct tgsi_src_register *reg)
4490 {
4491 strbuf_fmt(src_buf, "%s(vec4(%s[%d], %s[%d], %s[%d], %s[%d]))",
4492 prefix,
4493 name, reg->SwizzleX,
4494 name, reg->SwizzleY,
4495 name, reg->SwizzleZ,
4496 name, reg->SwizzleW);
4497 }
4498
get_source_swizzle(const struct tgsi_full_src_register * src,char swizzle[8])4499 static void get_source_swizzle(const struct tgsi_full_src_register *src, char swizzle[8])
4500 {
4501 if (src->Register.SwizzleX != TGSI_SWIZZLE_X ||
4502 src->Register.SwizzleY != TGSI_SWIZZLE_Y ||
4503 src->Register.SwizzleZ != TGSI_SWIZZLE_Z ||
4504 src->Register.SwizzleW != TGSI_SWIZZLE_W) {
4505 *swizzle++ = '.';
4506 *swizzle++ = get_swiz_char(src->Register.SwizzleX);
4507 *swizzle++ = get_swiz_char(src->Register.SwizzleY);
4508 *swizzle++ = get_swiz_char(src->Register.SwizzleZ);
4509 *swizzle++ = get_swiz_char(src->Register.SwizzleW);
4510 }
4511
4512 *swizzle++ = 0;
4513 }
4514
4515 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
4516 static bool
get_source_info(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,struct source_info * sinfo,struct vrend_strbuf srcs[4],char src_swizzle0[16])4517 get_source_info(struct dump_ctx *ctx,
4518 const struct tgsi_full_instruction *inst,
4519 struct source_info *sinfo,
4520 struct vrend_strbuf srcs[4], char src_swizzle0[16])
4521 {
4522 bool stprefix = false;
4523
4524 enum vrend_type_qualifier stypeprefix = TYPE_CONVERSION_NONE;
4525 enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(inst->Instruction.Opcode);
4526
4527 if (stype == TGSI_TYPE_SIGNED || stype == TGSI_TYPE_UNSIGNED)
4528 ctx->shader_req_bits |= SHADER_REQ_INTS;
4529 if (stype == TGSI_TYPE_DOUBLE)
4530 ctx->shader_req_bits |= SHADER_REQ_INTS | SHADER_REQ_FP64;
4531
4532 switch (stype) {
4533 case TGSI_TYPE_DOUBLE:
4534 stypeprefix = FLOAT_BITS_TO_UINT;
4535 sinfo->svec4 = DVEC2;
4536 stprefix = true;
4537 break;
4538 case TGSI_TYPE_UNSIGNED:
4539 stypeprefix = FLOAT_BITS_TO_UINT;
4540 sinfo->svec4 = UVEC4;
4541 stprefix = true;
4542 break;
4543 case TGSI_TYPE_SIGNED:
4544 stypeprefix = FLOAT_BITS_TO_INT;
4545 sinfo->svec4 = IVEC4;
4546 stprefix = true;
4547 break;
4548 default:
4549 break;
4550 }
4551
4552 for (uint32_t i = 0; i < inst->Instruction.NumSrcRegs; i++) {
4553 const struct tgsi_full_src_register *src = &inst->Src[i];
4554 struct vrend_strbuf *src_buf = &srcs[i];
4555 char swizzle[16] = "";
4556 char *swizzle_writer = swizzle;
4557 char prefix[6] = "";
4558 char arrayname[16] = "";
4559 char fp64_src[255];
4560 int swz_idx = 0, pre_idx = 0;
4561 boolean isfloatabsolute = src->Register.Absolute && stype != TGSI_TYPE_DOUBLE;
4562
4563 sinfo->override_no_wm[i] = false;
4564 sinfo->override_no_cast[i] = false;
4565
4566 if (src->Register.Negate)
4567 prefix[pre_idx++] = '-';
4568 if (isfloatabsolute)
4569 strcpy(&prefix[pre_idx++], "abs(");
4570
4571 if (src->Register.Dimension) {
4572 if (src->Dimension.Indirect) {
4573 assert(src->DimIndirect.File == TGSI_FILE_ADDRESS);
4574 sprintf(arrayname, "[addr%d]", src->DimIndirect.Index);
4575 } else
4576 sprintf(arrayname, "[%d]", src->Dimension.Index);
4577 }
4578
4579 /* These instructions don't support swizzles in the first parameter
4580 * pass the swizzle to the caller instead */
4581 if ((inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE ||
4582 inst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET ||
4583 inst->Instruction.Opcode == TGSI_OPCODE_INTERP_CENTROID) &&
4584 i == 0) {
4585 swizzle_writer = src_swizzle0;
4586 }
4587
4588 if (isfloatabsolute)
4589 swizzle_writer[swz_idx++] = ')';
4590
4591 get_source_swizzle(src, swizzle_writer + swz_idx);
4592
4593 if (src->Register.File == TGSI_FILE_INPUT) {
4594 int j = find_io_index(ctx->num_inputs, ctx->inputs, src->Register.Index);
4595 if (j < 0)
4596 return false;
4597
4598 struct vrend_shader_io *input = &ctx->inputs[j];
4599
4600 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX) {
4601 if (ctx->key->vs.attrib_zyxw_bitmask & (1 << input->first)) {
4602 swizzle_writer[swz_idx++] = '.';
4603 swizzle_writer[swz_idx++] = 'z';
4604 swizzle_writer[swz_idx++] = 'y';
4605 swizzle_writer[swz_idx++] = 'x';
4606 swizzle_writer[swz_idx++] = 'w';
4607 }
4608 get_source_swizzle(src, swizzle_writer + swz_idx);
4609 }
4610
4611 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT &&
4612 ctx->key->color_two_side && input->name == TGSI_SEMANTIC_COLOR)
4613 strbuf_fmt(src_buf, "%s(%s%s%d%s%s)", get_string(stypeprefix), prefix, "realcolor", input->sid, arrayname, swizzle);
4614 else if (input->glsl_gl_block) {
4615 /* GS input clipdist requires a conversion */
4616 if (input->name == TGSI_SEMANTIC_CLIPDIST) {
4617 create_swizzled_clipdist(ctx, src_buf, src, j, true, get_string(stypeprefix), prefix, arrayname, input->first);
4618 } else {
4619 strbuf_fmt(src_buf, "%s(vec4(%sgl_in%s.%s)%s)", get_string(stypeprefix), prefix, arrayname, input->glsl_name, swizzle);
4620 }
4621 }
4622 else if (input->name == TGSI_SEMANTIC_PRIMID)
4623 strbuf_fmt(src_buf, "%s(vec4(intBitsToFloat(%s)))", get_string(stypeprefix), input->glsl_name);
4624 else if (input->name == TGSI_SEMANTIC_FACE)
4625 strbuf_fmt(src_buf, "%s(%s ? 1.0 : -1.0)", get_string(stypeprefix), input->glsl_name);
4626 else if (input->name == TGSI_SEMANTIC_CLIPDIST) {
4627 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT)
4628 load_clipdist_fs(ctx, src_buf, src, j, get_string(stypeprefix), input->first);
4629 else
4630 create_swizzled_clipdist(ctx, src_buf, src, j, false, get_string(stypeprefix), prefix, arrayname, input->first);
4631 } else if (input->name == TGSI_SEMANTIC_TESSOUTER ||
4632 input->name == TGSI_SEMANTIC_TESSINNER) {
4633 get_tesslevel_as_source(src_buf, prefix, input->glsl_name, &src->Register);
4634 } else {
4635 enum vrend_type_qualifier srcstypeprefix = stypeprefix;
4636 if (input->type != VEC_FLOAT) {
4637 if (stype == TGSI_TYPE_UNSIGNED)
4638 srcstypeprefix = UVEC4;
4639 else if (stype == TGSI_TYPE_SIGNED)
4640 srcstypeprefix = IVEC4;
4641 else if (input->type == VEC_INT)
4642 srcstypeprefix = INT_BITS_TO_FLOAT;
4643 else // input->type == VEC_UINT
4644 srcstypeprefix = UINT_BITS_TO_FLOAT;
4645 }
4646
4647 if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1) {
4648 strbuf_fmt(src_buf, "floatBitsToInt(%s%s%s%s)", prefix, input->glsl_name, arrayname, swizzle);
4649 } else if (input->name == TGSI_SEMANTIC_GENERIC) {
4650 get_source_info_generic(ctx, io_in, srcstypeprefix, prefix, src,
4651 &ctx->inputs[j], arrayname, swizzle, src_buf);
4652 } else if (input->name == TGSI_SEMANTIC_TEXCOORD) {
4653 get_source_info_generic(ctx, io_in, srcstypeprefix, prefix, src,
4654 &ctx->inputs[j], arrayname, swizzle, src_buf);
4655 } else if (input->name == TGSI_SEMANTIC_PATCH) {
4656 get_source_info_patch(srcstypeprefix, prefix, src,
4657 &ctx->inputs[j], arrayname, swizzle, src_buf);
4658 } else if (input->name == TGSI_SEMANTIC_POSITION && ctx->prog_type == TGSI_PROCESSOR_VERTEX &&
4659 input->first != input->last) {
4660 if (src->Register.Indirect)
4661 strbuf_fmt(src_buf, "%s(%s%s%s[addr%d + %d]%s)", get_string(srcstypeprefix), prefix, input->glsl_name, arrayname,
4662 src->Indirect.Index, src->Register.Index, input->is_int ? "" : swizzle);
4663 else
4664 strbuf_fmt(src_buf, "%s(%s%s%s[%d]%s)", get_string(srcstypeprefix), prefix, input->glsl_name, arrayname,
4665 src->Register.Index, input->is_int ? "" : swizzle);
4666 } else
4667 strbuf_fmt(src_buf, "%s(%s%s%s%s)", get_string(srcstypeprefix), prefix, input->glsl_name, arrayname, input->is_int ? "" : swizzle);
4668 }
4669 sinfo->override_no_wm[i] = input->override_no_wm;
4670 } else if (src->Register.File == TGSI_FILE_OUTPUT) {
4671 int j = find_io_index(ctx->num_outputs, ctx->outputs, src->Register.Index);
4672 if (j < 0)
4673 return false;
4674
4675 struct vrend_shader_io *output = &ctx->outputs[j];
4676
4677 if (inst->Instruction.Opcode == TGSI_OPCODE_FBFETCH) {
4678 output->fbfetch_used = true;
4679 ctx->shader_req_bits |= SHADER_REQ_FBFETCH;
4680 }
4681
4682 enum vrend_type_qualifier srcstypeprefix = stypeprefix;
4683 if (stype == TGSI_TYPE_UNSIGNED && output->is_int)
4684 srcstypeprefix = TYPE_CONVERSION_NONE;
4685 if (output->glsl_gl_block) {
4686 if (output->name == TGSI_SEMANTIC_CLIPDIST) {
4687 char clip_indirect[32] = "";
4688 if (output->first != output->last) {
4689 if (src->Register.Indirect)
4690 snprintf(clip_indirect, sizeof(clip_indirect), "+ addr%d", src->Indirect.Index);
4691 else
4692 snprintf(clip_indirect, sizeof(clip_indirect), "+ %d", src->Register.Index - output->first);
4693 }
4694 strbuf_fmt(src_buf, "clip_dist_temp[%d%s]", output->sid, clip_indirect);
4695 }
4696 } else if (output->name == TGSI_SEMANTIC_GENERIC) {
4697 struct vrend_shader_io *io = ctx->generic_ios.output_range.used ? &ctx->generic_ios.output_range.io : &ctx->outputs[j];
4698 get_source_info_generic(ctx, io_out, srcstypeprefix, prefix, src, io, arrayname, swizzle, src_buf);
4699 } else if (output->name == TGSI_SEMANTIC_PATCH) {
4700 struct vrend_shader_io *io = ctx->patch_ios.output_range.used ? &ctx->patch_ios.output_range.io : &ctx->outputs[j];
4701 get_source_info_patch(srcstypeprefix, prefix, src, io, arrayname, swizzle, src_buf);
4702 } else if (output->name == TGSI_SEMANTIC_TESSOUTER ||
4703 output->name == TGSI_SEMANTIC_TESSINNER) {
4704 get_tesslevel_as_source(src_buf, prefix, output->glsl_name, &src->Register);
4705 } else {
4706 strbuf_fmt(src_buf, "%s(%s%s%s%s)", get_string(srcstypeprefix), prefix, output->glsl_name, arrayname, output->is_int ? "" : swizzle);
4707 }
4708 sinfo->override_no_wm[i] = output->override_no_wm;
4709 } else if (src->Register.File == TGSI_FILE_TEMPORARY) {
4710 struct vrend_temp_range *range = find_temp_range(ctx, src->Register.Index);
4711 if (!range)
4712 return false;
4713 if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1) {
4714 stprefix = true;
4715 stypeprefix = FLOAT_BITS_TO_INT;
4716 }
4717 char temp_buf[64];
4718 get_temp(ctx, src->Register.Indirect, src->Indirect.Index, src->Register.Index,
4719 temp_buf, &ctx->require_dummy_value);
4720 strbuf_fmt(src_buf, "%s%c%s%s%s%c", get_string(stypeprefix), stprefix ? '(' : ' ', prefix, temp_buf, swizzle, stprefix ? ')' : ' ');
4721 } else if (src->Register.File == TGSI_FILE_CONSTANT) {
4722 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4723 int dim = 0;
4724 if (src->Register.Dimension && src->Dimension.Index != 0) {
4725 dim = src->Dimension.Index;
4726 if (src->Dimension.Indirect) {
4727 assert(src->DimIndirect.File == TGSI_FILE_ADDRESS);
4728 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
4729 if (src->Register.Indirect) {
4730 assert(src->Indirect.File == TGSI_FILE_ADDRESS);
4731 strbuf_fmt(src_buf, "%s(%s%suboarr[addr%d].ubocontents[addr%d + %d]%s)", get_string(stypeprefix), prefix, cname, src->DimIndirect.Index, src->Indirect.Index, src->Register.Index, swizzle);
4732 } else
4733 strbuf_fmt(src_buf, "%s(%s%suboarr[addr%d].ubocontents[%d]%s)", get_string(stypeprefix), prefix, cname, src->DimIndirect.Index, src->Register.Index, swizzle);
4734 } else {
4735 if (ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT)) {
4736 if (src->Register.Indirect) {
4737 strbuf_fmt(src_buf, "%s(%s%suboarr[%d].ubocontents[addr%d + %d]%s)", get_string(stypeprefix), prefix, cname, dim - ctx->ubo_base, src->Indirect.Index, src->Register.Index, swizzle);
4738 } else
4739 strbuf_fmt(src_buf, "%s(%s%suboarr[%d].ubocontents[%d]%s)", get_string(stypeprefix), prefix, cname, dim - ctx->ubo_base, src->Register.Index, swizzle);
4740 } else {
4741 if (src->Register.Indirect) {
4742 strbuf_fmt(src_buf, "%s(%s%subo%dcontents[addr0 + %d]%s)", get_string(stypeprefix), prefix, cname, dim, src->Register.Index, swizzle);
4743 } else
4744 strbuf_fmt(src_buf, "%s(%s%subo%dcontents[%d]%s)", get_string(stypeprefix), prefix, cname, dim, src->Register.Index, swizzle);
4745 }
4746 }
4747 } else {
4748 enum vrend_type_qualifier csp = TYPE_CONVERSION_NONE;
4749 ctx->shader_req_bits |= SHADER_REQ_INTS;
4750 if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1)
4751 csp = IVEC4;
4752 else if (stype == TGSI_TYPE_FLOAT || stype == TGSI_TYPE_UNTYPED)
4753 csp = UINT_BITS_TO_FLOAT;
4754 else if (stype == TGSI_TYPE_SIGNED)
4755 csp = IVEC4;
4756
4757 if (src->Register.Indirect) {
4758 strbuf_fmt(src_buf, "%s%s(%sconst%d[addr0 + %d]%s)", prefix, get_string(csp), cname, dim, src->Register.Index, swizzle);
4759 } else
4760 strbuf_fmt(src_buf, "%s%s(%sconst%d[%d]%s)", prefix, get_string(csp), cname, dim, src->Register.Index, swizzle);
4761 }
4762 } else if (src->Register.File == TGSI_FILE_SAMPLER) {
4763 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4764 if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
4765 int basearrayidx = lookup_sampler_array(ctx, src->Register.Index);
4766 if (src->Register.Indirect) {
4767 strbuf_fmt(src_buf, "%ssamp%d[addr%d+%d]%s", cname, basearrayidx, src->Indirect.Index, src->Register.Index - basearrayidx, swizzle);
4768 } else {
4769 strbuf_fmt(src_buf, "%ssamp%d[%d]%s", cname, basearrayidx, src->Register.Index - basearrayidx, swizzle);
4770 }
4771 } else {
4772 strbuf_fmt(src_buf, "%ssamp%d%s", cname, src->Register.Index, swizzle);
4773 }
4774 sinfo->sreg_index = src->Register.Index;
4775 } else if (src->Register.File == TGSI_FILE_IMAGE) {
4776 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4777 if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
4778 int basearrayidx = lookup_image_array(ctx, src->Register.Index);
4779 if (src->Register.Indirect) {
4780 assert(src->Indirect.File == TGSI_FILE_ADDRESS);
4781 strbuf_fmt(src_buf, "%simg%d[addr%d + %d]", cname, basearrayidx, src->Indirect.Index, src->Register.Index - basearrayidx);
4782 } else
4783 strbuf_fmt(src_buf, "%simg%d[%d]", cname, basearrayidx, src->Register.Index - basearrayidx);
4784 } else
4785 strbuf_fmt(src_buf, "%simg%d%s", cname, src->Register.Index, swizzle);
4786 sinfo->sreg_index = src->Register.Index;
4787 } else if (src->Register.File == TGSI_FILE_BUFFER) {
4788 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4789 if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
4790 bool atomic_ssbo = ctx->ssbo_atomic_mask & (1 << src->Register.Index);
4791 const char *atomic_str = atomic_ssbo ? "atomic" : "";
4792 int base = atomic_ssbo ? ctx->ssbo_atomic_array_base : ctx->ssbo_array_base;
4793 if (src->Register.Indirect) {
4794 strbuf_fmt(src_buf, "%sssboarr%s[addr%d+%d].%sssbocontents%d%s", cname, atomic_str, src->Indirect.Index, src->Register.Index - base, cname, base, swizzle);
4795 } else {
4796 strbuf_fmt(src_buf, "%sssboarr%s[%d].%sssbocontents%d%s", cname, atomic_str, src->Register.Index - base, cname, base, swizzle);
4797 }
4798 } else {
4799 strbuf_fmt(src_buf, "%sssbocontents%d%s", cname, src->Register.Index, swizzle);
4800 }
4801 sinfo->sreg_index = src->Register.Index;
4802 } else if (src->Register.File == TGSI_FILE_MEMORY) {
4803 strbuf_fmt(src_buf, "values");
4804 sinfo->sreg_index = src->Register.Index;
4805 } else if (src->Register.File == TGSI_FILE_IMMEDIATE) {
4806 if (src->Register.Index >= (int)ARRAY_SIZE(ctx->imm)) {
4807 vrend_printf( "Immediate exceeded, max is %lu\n", ARRAY_SIZE(ctx->imm));
4808 return false;
4809 }
4810 struct immed *imd = &ctx->imm[src->Register.Index];
4811 int idx = src->Register.SwizzleX;
4812 char temp[48];
4813 enum vrend_type_qualifier vtype = VEC4;
4814 enum vrend_type_qualifier imm_stypeprefix = stypeprefix;
4815
4816 if ((inst->Instruction.Opcode == TGSI_OPCODE_TG4 && i == 1) ||
4817 (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1))
4818 stype = TGSI_TYPE_SIGNED;
4819
4820 if (imd->type == TGSI_IMM_UINT32 || imd->type == TGSI_IMM_INT32) {
4821 if (imd->type == TGSI_IMM_UINT32)
4822 vtype = UVEC4;
4823 else
4824 vtype = IVEC4;
4825
4826 if (stype == TGSI_TYPE_UNSIGNED && imd->type == TGSI_IMM_INT32)
4827 imm_stypeprefix = UVEC4;
4828 else if (stype == TGSI_TYPE_SIGNED && imd->type == TGSI_IMM_UINT32)
4829 imm_stypeprefix = IVEC4;
4830 else if (stype == TGSI_TYPE_FLOAT || stype == TGSI_TYPE_UNTYPED) {
4831 if (imd->type == TGSI_IMM_INT32)
4832 imm_stypeprefix = INT_BITS_TO_FLOAT;
4833 else
4834 imm_stypeprefix = UINT_BITS_TO_FLOAT;
4835 } else if (stype == TGSI_TYPE_UNSIGNED || stype == TGSI_TYPE_SIGNED)
4836 imm_stypeprefix = TYPE_CONVERSION_NONE;
4837 } else if (imd->type == TGSI_IMM_FLOAT64) {
4838 vtype = UVEC4;
4839 if (stype == TGSI_TYPE_DOUBLE)
4840 imm_stypeprefix = TYPE_CONVERSION_NONE;
4841 else
4842 imm_stypeprefix = UINT_BITS_TO_FLOAT;
4843 }
4844
4845 /* build up a vec4 of immediates */
4846 strbuf_fmt(src_buf, "%s%s(%s(", prefix,
4847 get_string(imm_stypeprefix), get_string(vtype));
4848
4849 for (uint32_t j = 0; j < 4; j++) {
4850 if (j == 0)
4851 idx = src->Register.SwizzleX;
4852 else if (j == 1)
4853 idx = src->Register.SwizzleY;
4854 else if (j == 2)
4855 idx = src->Register.SwizzleZ;
4856 else if (j == 3)
4857 idx = src->Register.SwizzleW;
4858
4859 if (inst->Instruction.Opcode == TGSI_OPCODE_TG4 && i == 1 && j == 0) {
4860 if (imd->val[idx].ui > 0) {
4861 sinfo->tg4_has_component = true;
4862 if (!ctx->cfg->use_gles)
4863 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
4864 }
4865 }
4866
4867 switch (imd->type) {
4868 case TGSI_IMM_FLOAT32:
4869 if (isinf(imd->val[idx].f) || isnan(imd->val[idx].f)) {
4870 ctx->shader_req_bits |= SHADER_REQ_INTS;
4871 snprintf(temp, 48, "uintBitsToFloat(%uU)", imd->val[idx].ui);
4872 } else
4873 snprintf(temp, 25, "%.8g", imd->val[idx].f);
4874 break;
4875 case TGSI_IMM_UINT32:
4876 snprintf(temp, 25, "%uU", imd->val[idx].ui);
4877 break;
4878 case TGSI_IMM_INT32:
4879 snprintf(temp, 25, "%d", imd->val[idx].i);
4880 sinfo->imm_value = imd->val[idx].i;
4881 break;
4882 case TGSI_IMM_FLOAT64:
4883 snprintf(temp, 48, "%uU", imd->val[idx].ui);
4884 break;
4885 default:
4886 vrend_printf( "unhandled imm type: %x\n", imd->type);
4887 return false;
4888 }
4889 strbuf_append(src_buf, temp);
4890 if (j < 3)
4891 strbuf_append(src_buf, ",");
4892 else {
4893 snprintf(temp, 4, "))%c", isfloatabsolute ? ')' : 0);
4894 strbuf_append(src_buf, temp);
4895 }
4896 }
4897 } else if (src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
4898 for (uint32_t j = 0; j < ctx->num_system_values; j++)
4899 if (ctx->system_values[j].first == src->Register.Index) {
4900 if (ctx->system_values[j].name == TGSI_SEMANTIC_VERTEXID ||
4901 ctx->system_values[j].name == TGSI_SEMANTIC_INSTANCEID ||
4902 ctx->system_values[j].name == TGSI_SEMANTIC_PRIMID ||
4903 ctx->system_values[j].name == TGSI_SEMANTIC_VERTICESIN ||
4904 ctx->system_values[j].name == TGSI_SEMANTIC_INVOCATIONID ||
4905 ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEID) {
4906 if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1)
4907 strbuf_fmt(src_buf, "ivec4(%s)", ctx->system_values[j].glsl_name);
4908 else
4909 strbuf_fmt(src_buf, "%s(vec4(intBitsToFloat(%s)))", get_string(stypeprefix), ctx->system_values[j].glsl_name);
4910 } else if (ctx->system_values[j].name == TGSI_SEMANTIC_HELPER_INVOCATION) {
4911 strbuf_fmt(src_buf, "uvec4(%s)", ctx->system_values[j].glsl_name);
4912 } else if (ctx->system_values[j].name == TGSI_SEMANTIC_TESSINNER ||
4913 ctx->system_values[j].name == TGSI_SEMANTIC_TESSOUTER) {
4914 strbuf_fmt(src_buf, "%s(vec4(%s[%d], %s[%d], %s[%d], %s[%d]))",
4915 prefix,
4916 ctx->system_values[j].glsl_name, src->Register.SwizzleX,
4917 ctx->system_values[j].glsl_name, src->Register.SwizzleY,
4918 ctx->system_values[j].glsl_name, src->Register.SwizzleZ,
4919 ctx->system_values[j].glsl_name, src->Register.SwizzleW);
4920 } else if (ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEPOS) {
4921 /* gl_SamplePosition is a vec2, but TGSI_SEMANTIC_SAMPLEPOS
4922 * is a vec4 with z = w = 0
4923 */
4924 const char *components[4] = {
4925 "gl_SamplePosition.x", "gl_SamplePosition.y", "0.0", "0.0"
4926 };
4927 strbuf_fmt(src_buf, "%s(vec4(%s, %s, %s, %s))",
4928 prefix,
4929 components[src->Register.SwizzleX],
4930 components[src->Register.SwizzleY],
4931 components[src->Register.SwizzleZ],
4932 components[src->Register.SwizzleW]);
4933 } else if (ctx->system_values[j].name == TGSI_SEMANTIC_TESSCOORD) {
4934 strbuf_fmt(src_buf, "%s(vec4(%s.%c, %s.%c, %s.%c, %s.%c))",
4935 prefix,
4936 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleX),
4937 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleY),
4938 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleZ),
4939 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleW));
4940 } else if (ctx->system_values[j].name == TGSI_SEMANTIC_GRID_SIZE ||
4941 ctx->system_values[j].name == TGSI_SEMANTIC_THREAD_ID ||
4942 ctx->system_values[j].name == TGSI_SEMANTIC_BLOCK_ID) {
4943 enum vrend_type_qualifier mov_conv = TYPE_CONVERSION_NONE;
4944 if (inst->Instruction.Opcode == TGSI_OPCODE_MOV &&
4945 inst->Dst[0].Register.File == TGSI_FILE_TEMPORARY)
4946 mov_conv = UINT_BITS_TO_FLOAT;
4947 strbuf_fmt(src_buf, "%s(uvec4(%s.%c, %s.%c, %s.%c, %s.%c))", get_string(mov_conv),
4948 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleX),
4949 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleY),
4950 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleZ),
4951 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleW));
4952 sinfo->override_no_cast[i] = true;
4953 } else if (ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEMASK) {
4954 const char *vec_type = "ivec4";
4955 enum vrend_type_qualifier srcstypeprefix = TYPE_CONVERSION_NONE;
4956 if (stypeprefix == TYPE_CONVERSION_NONE)
4957 srcstypeprefix = INT_BITS_TO_FLOAT;
4958 else if (stype == TGSI_TYPE_UNSIGNED)
4959 vec_type = "uvec4";
4960
4961 ctx->shader_req_bits |= SHADER_REQ_SAMPLE_SHADING | SHADER_REQ_INTS;
4962 strbuf_fmt(src_buf, "%s(%s(%s, %s, %s, %s))",
4963 get_string(srcstypeprefix),
4964 vec_type,
4965 src->Register.SwizzleX == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0",
4966 src->Register.SwizzleY == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0",
4967 src->Register.SwizzleZ == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0",
4968 src->Register.SwizzleW == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0");
4969 } else
4970 strbuf_fmt(src_buf, "%s%s", prefix, ctx->system_values[j].glsl_name);
4971 sinfo->override_no_wm[i] = ctx->system_values[j].override_no_wm;
4972 break;
4973 }
4974 } else if (src->Register.File == TGSI_FILE_HW_ATOMIC) {
4975 for (uint32_t j = 0; j < ctx->num_abo; j++) {
4976 if (src->Dimension.Index == ctx->abo_idx[j] &&
4977 src->Register.Index >= ctx->abo_offsets[j] &&
4978 src->Register.Index < ctx->abo_offsets[j] + ctx->abo_sizes[j]) {
4979 int abo_idx = ctx->abo_idx[j];
4980 int abo_offset = ctx->abo_offsets[j] * 4;
4981 if (ctx->abo_sizes[j] > 1) {
4982 int offset = src->Register.Index - ctx->abo_offsets[j];
4983 if (src->Register.Indirect) {
4984 assert(src->Indirect.File == TGSI_FILE_ADDRESS);
4985 strbuf_fmt(src_buf, "ac%d_%d[addr%d + %d]", abo_idx, abo_offset, src->Indirect.Index, offset);
4986 } else
4987 strbuf_fmt(src_buf, "ac%d_%d[%d]", abo_idx, abo_offset, offset);
4988 } else
4989 strbuf_fmt(src_buf, "ac%d_%d", abo_idx, abo_offset);
4990 break;
4991 }
4992 }
4993 sinfo->sreg_index = src->Register.Index;
4994 }
4995
4996 if (stype == TGSI_TYPE_DOUBLE) {
4997 boolean isabsolute = src->Register.Absolute;
4998 strcpy(fp64_src, src_buf->buf);
4999 strbuf_fmt(src_buf, "fp64_src[%d]", i);
5000 emit_buff(&ctx->glsl_strbufs, "%s.x = %spackDouble2x32(uvec2(%s%s))%s;\n", src_buf->buf, isabsolute ? "abs(" : "", fp64_src, swizzle, isabsolute ? ")" : "");
5001 }
5002 }
5003
5004 return true;
5005 }
5006
rewrite_1d_image_coordinate(struct vrend_strbuf * src,const struct tgsi_full_instruction * inst)5007 static bool rewrite_1d_image_coordinate(struct vrend_strbuf *src, const struct tgsi_full_instruction *inst)
5008 {
5009 if (inst->Src[0].Register.File == TGSI_FILE_IMAGE &&
5010 (inst->Memory.Texture == TGSI_TEXTURE_1D ||
5011 inst->Memory.Texture == TGSI_TEXTURE_1D_ARRAY)) {
5012
5013 /* duplicate src */
5014 size_t len = strbuf_get_len(src);
5015 char *buf = malloc(len);
5016 if (!buf)
5017 return false;
5018 strncpy(buf, src->buf, len);
5019
5020 if (inst->Memory.Texture == TGSI_TEXTURE_1D)
5021 strbuf_fmt(src, "vec2(vec4(%s).x, 0)", buf);
5022 else if (inst->Memory.Texture == TGSI_TEXTURE_1D_ARRAY)
5023 strbuf_fmt(src, "vec3(%s.xy, 0).xzy", buf);
5024
5025 free(buf);
5026 }
5027 return true;
5028 }
5029
5030 /* We have indirect IO access, but the guest actually send separate values, so
5031 * now we have to emulate arrays by putting IO values into arrays according
5032 * to semantic. Only join elements that are consecutive. */
5033 static int
make_array_from_semantic(struct vrend_shader_io * io,int start_index,int num_entries,enum tgsi_semantic semantic)5034 make_array_from_semantic(struct vrend_shader_io *io, int start_index,
5035 int num_entries, enum tgsi_semantic semantic)
5036 {
5037 struct vrend_shader_io *io_out_range = &io[start_index];
5038
5039 int last_sid = io_out_range->sid;
5040 for (int i = start_index + 1; i < num_entries; ++i) {
5041 if (io[i].name == semantic && (io[i].sid - last_sid == 1)) {
5042 io[i].glsl_predefined_no_emit = true;
5043 last_sid = io[i].sid;
5044 io[i].array_offset = io[i].sid - io_out_range->sid;
5045 io_out_range->last = io_out_range->first + io[i].array_offset;
5046 io[i].overlapping_array = io_out_range;
5047 } else {
5048 break;
5049 }
5050 }
5051 return io_out_range->last + 1;
5052 }
5053
5054 static bool
collapse_vars_to_arrays(struct vrend_shader_io * io,int num_entries,enum tgsi_semantic semantic)5055 collapse_vars_to_arrays(struct vrend_shader_io *io,
5056 int num_entries,
5057 enum tgsi_semantic semantic)
5058 {
5059
5060 bool retval = 0;
5061 int start_index = 0;
5062 while (start_index < num_entries) {
5063 if (io[start_index].name == semantic && !io[start_index].glsl_predefined_no_emit) {
5064 int new_start_index = make_array_from_semantic(io, start_index, num_entries, semantic);
5065 retval |= io[start_index].first != io[start_index].last;
5066 start_index = new_start_index;
5067 } else {
5068 ++start_index;
5069 }
5070 }
5071
5072 io->num_components = 4;
5073 io->usage_mask = 0xf;
5074 return retval;
5075 }
5076
5077 static void
rewrite_io_ranged(struct dump_ctx * ctx)5078 rewrite_io_ranged(struct dump_ctx *ctx)
5079 {
5080 if ((ctx->info.indirect_files & (1 << TGSI_FILE_INPUT)) ||
5081 ctx->key->require_input_arrays) {
5082
5083 bool generic_array = collapse_vars_to_arrays(ctx->inputs, ctx->num_inputs,
5084 TGSI_SEMANTIC_GENERIC);
5085 bool patch_array = collapse_vars_to_arrays(ctx->inputs, ctx->num_inputs,
5086 TGSI_SEMANTIC_PATCH);
5087
5088 ctx->has_input_arrays = generic_array || patch_array;
5089
5090 if (prefer_generic_io_block(ctx, io_in))
5091 ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
5092 }
5093
5094 if ((ctx->info.indirect_files & (1 << TGSI_FILE_OUTPUT)) ||
5095 ctx->key->require_output_arrays) {
5096
5097 bool generic_array = collapse_vars_to_arrays(ctx->outputs, ctx->num_outputs,
5098 TGSI_SEMANTIC_GENERIC);
5099 bool patch_array = collapse_vars_to_arrays(ctx->outputs, ctx->num_outputs,
5100 TGSI_SEMANTIC_PATCH);
5101
5102 ctx->has_output_arrays = generic_array || patch_array;
5103
5104 if (prefer_generic_io_block(ctx, io_out))
5105 ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
5106 }
5107
5108 if ((ctx->has_output_arrays || ctx->has_input_arrays)
5109 && ctx->cfg->has_arrays_of_arrays && !ctx->cfg->use_gles)
5110 ctx->shader_req_bits |= SHADER_REQ_ARRAYS_OF_ARRAYS;
5111
5112 }
5113
5114 static
rewrite_vs_pos_array(struct dump_ctx * ctx)5115 void rewrite_vs_pos_array(struct dump_ctx *ctx)
5116 {
5117 int range_start = 0xffff;
5118 int range_end = 0;
5119 int io_idx = 0;
5120
5121 for (uint i = 0; i < ctx->num_inputs; ++i) {
5122 if (ctx->inputs[i].name == TGSI_SEMANTIC_POSITION) {
5123 ctx->inputs[i].glsl_predefined_no_emit = true;
5124 if (ctx->inputs[i].first < range_start) {
5125 io_idx = i;
5126 range_start = ctx->inputs[i].first;
5127 }
5128 if (ctx->inputs[i].last > range_end)
5129 range_end = ctx->inputs[i].last;
5130 }
5131 }
5132
5133 if (range_start != range_end) {
5134 ctx->inputs[io_idx].first = range_start;
5135 ctx->inputs[io_idx].last = range_end;
5136 ctx->inputs[io_idx].glsl_predefined_no_emit = false;
5137 ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
5138 }
5139 }
5140
5141
5142 static
emit_fs_clipdistance_load(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)5143 void emit_fs_clipdistance_load(const struct dump_ctx *ctx,
5144 struct vrend_glsl_strbufs *glsl_strbufs)
5145 {
5146 int i;
5147
5148 if (!ctx->fs_uses_clipdist_input)
5149 return;
5150
5151 int prev_num = ctx->key->num_in_clip + ctx->key->num_in_cull;
5152 int ndists;
5153 const char *prefix="";
5154
5155 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL)
5156 prefix = "gl_out[gl_InvocationID].";
5157
5158 ndists = ctx->num_in_clip_dist;
5159 if (prev_num > 0)
5160 ndists = prev_num;
5161
5162 for (i = 0; i < ndists; i++) {
5163 int clipidx = i < 4 ? 0 : 1;
5164 char swiz = i & 3;
5165 char wm = 0;
5166 switch (swiz) {
5167 default:
5168 case 0: wm = 'x'; break;
5169 case 1: wm = 'y'; break;
5170 case 2: wm = 'z'; break;
5171 case 3: wm = 'w'; break;
5172 }
5173 bool is_cull = false;
5174 if (prev_num > 0) {
5175 if (i >= ctx->key->num_in_clip && i < prev_num)
5176 is_cull = true;
5177 }
5178 const char *clip_cull = is_cull ? "Cull" : "Clip";
5179 emit_buff(glsl_strbufs, "clip_dist_temp[%d].%c = %sgl_%sDistance[%d];\n", clipidx, wm, prefix, clip_cull,
5180 is_cull ? i - ctx->key->num_in_clip : i);
5181 }
5182 }
5183
5184 static
renumber_io_arrays(unsigned nio,struct vrend_shader_io * io)5185 void renumber_io_arrays(unsigned nio, struct vrend_shader_io *io)
5186 {
5187 int next_array_id = 1;
5188 for (unsigned i = 0; i < nio; ++i) {
5189 if (io[i].name != TGSI_SEMANTIC_GENERIC &&
5190 io[i].name != TGSI_SEMANTIC_PATCH)
5191 continue;
5192 if (io[i].array_id > 0)
5193 io[i].array_id = next_array_id++;
5194 }
5195 }
5196
5197 // TODO Consider exposing non-const ctx-> members as args to make *ctx const
handle_io_arrays(struct dump_ctx * ctx)5198 static void handle_io_arrays(struct dump_ctx *ctx)
5199 {
5200 /* If the guest sent real IO arrays then we declare them individually,
5201 * and have to do some work to deal with overlapping values, regions and
5202 * enhanced layouts */
5203 if (ctx->guest_sent_io_arrays) {
5204
5205 /* Array ID numbering is not ordered accross shaders, so do
5206 * some renumbering for generics and patches. */
5207 renumber_io_arrays(ctx->num_inputs, ctx->inputs);
5208 renumber_io_arrays(ctx->num_outputs, ctx->outputs);
5209
5210 } else {
5211 /* The guest didn't send real arrays, do we might have to add a big array
5212 * for all generic and another for patch inputs */
5213 rewrite_io_ranged(ctx);
5214 }
5215 }
5216
5217 static int
compare_shader_io(const void * vlhs,const void * vrhs)5218 compare_shader_io(const void *vlhs, const void *vrhs)
5219 {
5220 struct vrend_shader_io *lhs = (struct vrend_shader_io *)vlhs;
5221 struct vrend_shader_io *rhs = (struct vrend_shader_io *)vrhs;
5222
5223 if (lhs->name < rhs->name)
5224 return -1;
5225 if (lhs->name > rhs->name)
5226 return 1;
5227 return lhs->sid - rhs->sid;
5228 }
5229
5230 static void
add_missing_semantic_inputs(struct vrend_shader_io * inputs,int * num_inputs,int * next_location,uint64_t sids_missing,const char * prefix,char * type_prefix,enum tgsi_semantic name,const struct vrend_shader_key * key)5231 add_missing_semantic_inputs(struct vrend_shader_io *inputs, int *num_inputs,
5232 int *next_location, uint64_t sids_missing,
5233 const char *prefix, char *type_prefix,
5234 enum tgsi_semantic name,
5235 const struct vrend_shader_key *key)
5236 {
5237
5238 while (sids_missing) {
5239 int sid = u_bit_scan64(&sids_missing);
5240 struct vrend_shader_io *io = &inputs[*num_inputs];
5241 io->sid = sid;
5242 io->last = io->first = *next_location;
5243 io->name = name;
5244 io->type = VEC_FLOAT;
5245 uint32_t sids_added = 1 << sid;
5246
5247
5248 for (uint32_t j = 0; j < key->in_arrays.num_arrays; j++) {
5249 const struct vrend_shader_io_array *array = &key->in_arrays.layout[j];
5250 if (array->name == name &&
5251 array->sid <= sid &&
5252 array->sid + array->size >= sid) {
5253 io->last = io->first + array->size;
5254 io->sid = array->sid;
5255 sids_added = ((1u << array->size) - 1) << sid;
5256 break;
5257 }
5258 }
5259
5260 (*next_location) += io->last - io->first + 1;
5261
5262 sids_missing &= ~sids_added;
5263
5264 snprintf(io->glsl_name, 128, "%s%s%d", prefix, type_prefix, sid);
5265 (*num_inputs)++;
5266 }
5267 }
5268
5269 static int
add_missing_inputs(const struct dump_ctx * ctx,struct vrend_shader_io * inputs,int num_inputs)5270 add_missing_inputs(const struct dump_ctx *ctx, struct vrend_shader_io *inputs,
5271 int num_inputs)
5272 {
5273 uint64_t generics_declared = 0;
5274 uint64_t patches_declared = 0;
5275 uint8_t texcoord_declared = 0;
5276
5277 int next_location = 0;
5278 for (int i = 0; i < num_inputs; ++i) {
5279 int offset = 0;
5280 for (int k = inputs[i].first; k <= inputs[i].last; ++k, ++offset) {
5281 int sid = inputs[i].sid + offset;
5282 switch (inputs[i].name) {
5283 case TGSI_SEMANTIC_GENERIC:
5284 generics_declared |= 1ull << sid;
5285 break;
5286 case TGSI_SEMANTIC_PATCH:
5287 patches_declared |= 1ull << sid;
5288 break;
5289 case TGSI_SEMANTIC_TEXCOORD:
5290 texcoord_declared |= 1ull << sid;
5291 break;
5292 default:
5293 ;
5294 }
5295 }
5296 if (next_location < inputs[i].last)
5297 next_location = inputs[i].last;
5298 }
5299 ++next_location;
5300
5301 uint64_t generics_missing = ctx->key->in_generic_expected_mask & ~generics_declared;
5302 uint64_t patches_missing = ctx->key->in_patch_expected_mask & ~patches_declared;
5303 uint64_t texcoord_missing = ctx->key->in_texcoord_expected_mask & ~texcoord_declared;
5304
5305 const char *prefix = get_stage_input_name_prefix(ctx, ctx->prog_type);
5306 add_missing_semantic_inputs(inputs, &num_inputs, &next_location,
5307 generics_missing, prefix, "_g",
5308 TGSI_SEMANTIC_GENERIC, ctx->key);
5309 add_missing_semantic_inputs(inputs, &num_inputs, &next_location,
5310 texcoord_missing, prefix, "_t",
5311 TGSI_SEMANTIC_TEXCOORD, ctx->key);
5312 add_missing_semantic_inputs(inputs, &num_inputs, &next_location,
5313 patches_missing, "patch", "",
5314 TGSI_SEMANTIC_PATCH, ctx->key);
5315
5316 qsort(inputs, num_inputs, sizeof(struct vrend_shader_io),
5317 compare_shader_io);
5318 return num_inputs;
5319 }
5320
5321 static boolean
iter_instruction(struct tgsi_iterate_context * iter,struct tgsi_full_instruction * inst)5322 iter_instruction(struct tgsi_iterate_context *iter,
5323 struct tgsi_full_instruction *inst)
5324 {
5325 struct dump_ctx *ctx = (struct dump_ctx *)iter;
5326 struct dest_info dinfo = { 0 };
5327 struct source_info sinfo = { 0 };
5328 const char *srcs[4];
5329 char *dsts[3];
5330 char fp64_dsts[3][255];
5331 uint instno = ctx->instno++;
5332 char writemask[6] = "";
5333 char src_swizzle0[16];
5334
5335 sinfo.svec4 = VEC4;
5336
5337 if (ctx->prog_type == (enum tgsi_processor_type) -1)
5338 ctx->prog_type = iter->processor.Processor;
5339
5340 if (instno == 0) {
5341 if (ctx->prog_type != TGSI_PROCESSOR_VERTEX)
5342 ctx->num_inputs = add_missing_inputs(ctx, ctx->inputs, ctx->num_inputs);
5343 handle_io_arrays(ctx);
5344
5345 /* Vertex shader inputs are not send as arrays, but the access may still be
5346 * indirect. so we have to deal with that */
5347 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX &&
5348 ctx->info.indirect_files & (1 << TGSI_FILE_INPUT)) {
5349 rewrite_vs_pos_array(ctx);
5350 }
5351
5352 emit_buf(&ctx->glsl_strbufs, "void main(void)\n{\n");
5353 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
5354 emit_color_select(ctx, &ctx->glsl_strbufs);
5355 if (ctx->fs_uses_clipdist_input)
5356 emit_fs_clipdistance_load(ctx, &ctx->glsl_strbufs);
5357 }
5358 if (ctx->so)
5359 prepare_so_movs(ctx);
5360
5361 /* GLES doesn't allow invariant specifiers on inputs, but on GL with
5362 * GLSL < 4.30 it is required to match the output of the previous stage */
5363 if (!ctx->cfg->use_gles) {
5364 for (unsigned i = 0; i < ctx->num_inputs; ++i) {
5365 uint32_t bit_pos = varying_bit_from_semantic_and_index(ctx->inputs[i].name, ctx->inputs[i].sid);
5366 uint32_t slot = bit_pos / 32;
5367 uint32_t bit = 1u << (bit_pos & 0x1f);
5368 if (ctx->key->force_invariant_inputs[slot] & bit)
5369 ctx->inputs[i].invariant = 1;
5370 else
5371 ctx->inputs[i].invariant = 0;
5372 }
5373 }
5374 }
5375
5376 if (!get_destination_info(ctx, inst, &dinfo, ctx->dst_bufs, fp64_dsts, writemask))
5377 return false;
5378
5379 if (!get_source_info(ctx, inst, &sinfo, ctx->src_bufs, src_swizzle0))
5380 return false;
5381
5382 for (size_t i = 0; i < ARRAY_SIZE(srcs); ++i)
5383 srcs[i] = ctx->src_bufs[i].buf;
5384
5385 for (size_t i = 0; i < ARRAY_SIZE(dsts); ++i)
5386 dsts[i] = ctx->dst_bufs[i].buf;
5387
5388 switch (inst->Instruction.Opcode) {
5389 case TGSI_OPCODE_SQRT:
5390 case TGSI_OPCODE_DSQRT:
5391 emit_buff(&ctx->glsl_strbufs, "%s = sqrt(vec4(%s))%s;\n", dsts[0], srcs[0], writemask);
5392 break;
5393 case TGSI_OPCODE_LRP:
5394 emit_buff(&ctx->glsl_strbufs, "%s = mix(vec4(%s), vec4(%s), vec4(%s))%s;\n", dsts[0], srcs[2], srcs[1], srcs[0], writemask);
5395 break;
5396 case TGSI_OPCODE_DP2:
5397 emit_buff(&ctx->glsl_strbufs, "%s = %s(dot(vec2(%s), vec2(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5398 break;
5399 case TGSI_OPCODE_DP3:
5400 emit_buff(&ctx->glsl_strbufs, "%s = %s(dot(vec3(%s), vec3(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5401 break;
5402 case TGSI_OPCODE_DP4:
5403 emit_buff(&ctx->glsl_strbufs, "%s = %s(dot(vec4(%s), vec4(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5404 break;
5405 case TGSI_OPCODE_DPH:
5406 emit_buff(&ctx->glsl_strbufs, "%s = %s(dot(vec4(vec3(%s), 1.0), vec4(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5407 break;
5408 case TGSI_OPCODE_MAX:
5409 case TGSI_OPCODE_DMAX:
5410 case TGSI_OPCODE_IMAX:
5411 case TGSI_OPCODE_UMAX:
5412 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(max(%s, %s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5413 break;
5414 case TGSI_OPCODE_MIN:
5415 case TGSI_OPCODE_DMIN:
5416 case TGSI_OPCODE_IMIN:
5417 case TGSI_OPCODE_UMIN:
5418 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(min(%s, %s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5419 break;
5420 case TGSI_OPCODE_ABS:
5421 case TGSI_OPCODE_IABS:
5422 case TGSI_OPCODE_DABS:
5423 emit_op1("abs");
5424 break;
5425 case TGSI_OPCODE_KILL_IF:
5426 emit_buff(&ctx->glsl_strbufs, "if (any(lessThan(%s, vec4(0.0))))\ndiscard;\n", srcs[0]);
5427 break;
5428 case TGSI_OPCODE_IF:
5429 case TGSI_OPCODE_UIF:
5430 emit_buff(&ctx->glsl_strbufs, "if (bool(%s.x)) {\n", srcs[0]);
5431 indent_buf(&ctx->glsl_strbufs);
5432 break;
5433 case TGSI_OPCODE_ELSE:
5434 outdent_buf(&ctx->glsl_strbufs);
5435 emit_buf(&ctx->glsl_strbufs, "} else {\n");
5436 indent_buf(&ctx->glsl_strbufs);
5437 break;
5438 case TGSI_OPCODE_ENDIF:
5439 emit_buf(&ctx->glsl_strbufs, "}\n");
5440 outdent_buf(&ctx->glsl_strbufs);
5441 break;
5442 case TGSI_OPCODE_KILL:
5443 emit_buff(&ctx->glsl_strbufs, "discard;\n");
5444 break;
5445 case TGSI_OPCODE_DST:
5446 emit_buff(&ctx->glsl_strbufs, "%s = vec4(1.0, %s.y * %s.y, %s.z, %s.w);\n", dsts[0],
5447 srcs[0], srcs[1], srcs[0], srcs[1]);
5448 break;
5449 case TGSI_OPCODE_LIT:
5450 emit_buff(&ctx->glsl_strbufs, "%s = %s(vec4(1.0, max(%s.x, 0.0), step(0.0, %s.x) * pow(max(0.0, %s.y), clamp(%s.w, -128.0, 128.0)), 1.0)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[0], srcs[0], srcs[0], writemask);
5451 break;
5452 case TGSI_OPCODE_EX2:
5453 emit_op1("exp2");
5454 break;
5455 case TGSI_OPCODE_LG2:
5456 emit_op1("log2");
5457 break;
5458 case TGSI_OPCODE_EXP:
5459 emit_buff(&ctx->glsl_strbufs, "%s = %s(vec4(pow(2.0, floor(%s.x)), %s.x - floor(%s.x), exp2(%s.x), 1.0)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[0], srcs[0], srcs[0], writemask);
5460 break;
5461 case TGSI_OPCODE_LOG:
5462 emit_buff(&ctx->glsl_strbufs, "%s = %s(vec4(floor(log2(%s.x)), %s.x / pow(2.0, floor(log2(%s.x))), log2(%s.x), 1.0)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[0], srcs[0], srcs[0], writemask);
5463 break;
5464 case TGSI_OPCODE_COS:
5465 emit_op1("cos");
5466 break;
5467 case TGSI_OPCODE_SIN:
5468 emit_op1("sin");
5469 break;
5470 case TGSI_OPCODE_SCS:
5471 emit_buff(&ctx->glsl_strbufs, "%s = %s(vec4(cos(%s.x), sin(%s.x), 0, 1)%s);\n", dsts[0], get_string(dinfo.dstconv),
5472 srcs[0], srcs[0], writemask);
5473 break;
5474 case TGSI_OPCODE_DDX:
5475 emit_op1("dFdx");
5476 break;
5477 case TGSI_OPCODE_DDY:
5478 emit_op1("dFdy");
5479 break;
5480 case TGSI_OPCODE_DDX_FINE:
5481 ctx->shader_req_bits |= SHADER_REQ_DERIVATIVE_CONTROL;
5482 emit_op1("dFdxFine");
5483 break;
5484 case TGSI_OPCODE_DDY_FINE:
5485 ctx->shader_req_bits |= SHADER_REQ_DERIVATIVE_CONTROL;
5486 emit_op1("dFdyFine");
5487 break;
5488 case TGSI_OPCODE_RCP:
5489 emit_buff(&ctx->glsl_strbufs, "%s = %s(1.0/(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5490 break;
5491 case TGSI_OPCODE_DRCP:
5492 emit_buff(&ctx->glsl_strbufs, "%s = %s(1.0LF/(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5493 break;
5494 case TGSI_OPCODE_FLR:
5495 case TGSI_OPCODE_DFLR:
5496 emit_op1("floor");
5497 break;
5498 case TGSI_OPCODE_ROUND:
5499 case TGSI_OPCODE_DROUND:
5500 // There is no TGSI OPCODE for roundEven, prefer roundEven
5501 // so roundEven in guest gets translated to roundEven.
5502 if ((ctx->cfg->use_gles && ctx->cfg->glsl_version >= 300) ||
5503 ctx->cfg->glsl_version >= 400)
5504 emit_op1("roundEven");
5505 else
5506 emit_op1("round");
5507 break;
5508 case TGSI_OPCODE_ISSG:
5509 emit_op1("sign");
5510 break;
5511 case TGSI_OPCODE_CEIL:
5512 case TGSI_OPCODE_DCEIL:
5513 emit_op1("ceil");
5514 break;
5515 case TGSI_OPCODE_FRC:
5516 case TGSI_OPCODE_DFRAC:
5517 emit_op1("fract");
5518 break;
5519 case TGSI_OPCODE_TRUNC:
5520 case TGSI_OPCODE_DTRUNC:
5521 emit_op1("trunc");
5522 break;
5523 case TGSI_OPCODE_SSG:
5524 case TGSI_OPCODE_DSSG:
5525 emit_op1("sign");
5526 break;
5527 case TGSI_OPCODE_RSQ:
5528 case TGSI_OPCODE_DRSQ:
5529 emit_buff(&ctx->glsl_strbufs, "%s = %s(inversesqrt(%s.x));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5530 break;
5531 case TGSI_OPCODE_FBFETCH:
5532 case TGSI_OPCODE_MOV:
5533 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(%s%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], sinfo.override_no_wm[0] ? "" : writemask);
5534 break;
5535 case TGSI_OPCODE_ADD:
5536 case TGSI_OPCODE_DADD:
5537 emit_arit_op2("+");
5538 break;
5539 case TGSI_OPCODE_UADD:
5540 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(uvec4(%s) + uvec4(%s))%s);\n", dsts[0],
5541 get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5542 break;
5543 case TGSI_OPCODE_SUB:
5544 emit_arit_op2("-");
5545 break;
5546 case TGSI_OPCODE_MUL:
5547 case TGSI_OPCODE_DMUL:
5548 emit_arit_op2("*");
5549 break;
5550 case TGSI_OPCODE_DIV:
5551 case TGSI_OPCODE_DDIV:
5552 emit_arit_op2("/");
5553 break;
5554 case TGSI_OPCODE_UMUL:
5555 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((uvec4(%s) * uvec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5556 break;
5557 case TGSI_OPCODE_UMOD:
5558 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((uvec4(%s) %% uvec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5559 break;
5560 case TGSI_OPCODE_IDIV:
5561 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((ivec4(%s) / ivec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5562 break;
5563 case TGSI_OPCODE_UDIV:
5564 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((uvec4(%s) / uvec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5565 break;
5566 case TGSI_OPCODE_ISHR:
5567 case TGSI_OPCODE_USHR:
5568 emit_arit_op2(">>");
5569 break;
5570 case TGSI_OPCODE_SHL:
5571 emit_arit_op2("<<");
5572 break;
5573 case TGSI_OPCODE_MAD:
5574 emit_buff(&ctx->glsl_strbufs, "%s = %s((%s * %s + %s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1], srcs[2], writemask);
5575 break;
5576 case TGSI_OPCODE_UMAD:
5577 case TGSI_OPCODE_DMAD:
5578 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((%s * %s + %s)%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], srcs[2], writemask);
5579 break;
5580 case TGSI_OPCODE_OR:
5581 emit_arit_op2("|");
5582 break;
5583 case TGSI_OPCODE_AND:
5584 emit_arit_op2("&");
5585 break;
5586 case TGSI_OPCODE_XOR:
5587 emit_arit_op2("^");
5588 break;
5589 case TGSI_OPCODE_MOD:
5590 emit_arit_op2("%");
5591 break;
5592 case TGSI_OPCODE_TEX:
5593 case TGSI_OPCODE_TEX2:
5594 case TGSI_OPCODE_TXB:
5595 case TGSI_OPCODE_TXL:
5596 case TGSI_OPCODE_TXB2:
5597 case TGSI_OPCODE_TXL2:
5598 case TGSI_OPCODE_TXD:
5599 case TGSI_OPCODE_TXF:
5600 case TGSI_OPCODE_TG4:
5601 case TGSI_OPCODE_TXP:
5602 translate_tex(ctx, inst, &sinfo, &dinfo, srcs, dsts[0], writemask);
5603 break;
5604 case TGSI_OPCODE_LODQ:
5605 emit_lodq(ctx, inst, &sinfo, &dinfo, srcs, dsts[0], writemask);
5606 break;
5607 case TGSI_OPCODE_TXQ:
5608 emit_txq(ctx, inst, sinfo.sreg_index, srcs, dsts[0], writemask);
5609 break;
5610 case TGSI_OPCODE_TXQS:
5611 emit_txqs(ctx, inst, sinfo.sreg_index, srcs, dsts[0]);
5612 break;
5613 case TGSI_OPCODE_I2F:
5614 emit_buff(&ctx->glsl_strbufs, "%s = %s(ivec4(%s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], writemask);
5615 break;
5616 case TGSI_OPCODE_I2D:
5617 emit_buff(&ctx->glsl_strbufs, "%s = %s(ivec4(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5618 break;
5619 case TGSI_OPCODE_D2F:
5620 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5621 break;
5622 case TGSI_OPCODE_U2F:
5623 emit_buff(&ctx->glsl_strbufs, "%s = %s(uvec4(%s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], writemask);
5624 break;
5625 case TGSI_OPCODE_U2D:
5626 emit_buff(&ctx->glsl_strbufs, "%s = %s(uvec4(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5627 break;
5628 case TGSI_OPCODE_F2I:
5629 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(ivec4(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], writemask);
5630 break;
5631 case TGSI_OPCODE_D2I:
5632 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(%s(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), get_string(dinfo.idstconv), srcs[0]);
5633 break;
5634 case TGSI_OPCODE_F2U:
5635 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(uvec4(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], writemask);
5636 break;
5637 case TGSI_OPCODE_D2U:
5638 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(%s(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), get_string(dinfo.udstconv), srcs[0]);
5639 break;
5640 case TGSI_OPCODE_F2D:
5641 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
5642 break;
5643 case TGSI_OPCODE_NOT:
5644 emit_buff(&ctx->glsl_strbufs, "%s = %s(uintBitsToFloat(~(uvec4(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5645 break;
5646 case TGSI_OPCODE_INEG:
5647 emit_buff(&ctx->glsl_strbufs, "%s = %s(intBitsToFloat(-(ivec4(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5648 break;
5649 case TGSI_OPCODE_DNEG:
5650 emit_buff(&ctx->glsl_strbufs, "%s = %s(-%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5651 break;
5652 case TGSI_OPCODE_SEQ:
5653 emit_compare("equal");
5654 break;
5655 case TGSI_OPCODE_USEQ:
5656 case TGSI_OPCODE_FSEQ:
5657 case TGSI_OPCODE_DSEQ:
5658 if (inst->Instruction.Opcode == TGSI_OPCODE_DSEQ)
5659 strcpy(writemask, ".x");
5660 emit_ucompare("equal");
5661 break;
5662 case TGSI_OPCODE_SLT:
5663 emit_compare("lessThan");
5664 break;
5665 case TGSI_OPCODE_SLE:
5666 emit_compare("lessThanEqual");
5667 break;
5668 case TGSI_OPCODE_SGT:
5669 emit_compare("greaterThan");
5670 break;
5671 case TGSI_OPCODE_ISLT:
5672 case TGSI_OPCODE_USLT:
5673 case TGSI_OPCODE_FSLT:
5674 case TGSI_OPCODE_DSLT:
5675 if (inst->Instruction.Opcode == TGSI_OPCODE_DSLT)
5676 strcpy(writemask, ".x");
5677 emit_ucompare("lessThan");
5678 break;
5679 case TGSI_OPCODE_SNE:
5680 emit_compare("notEqual");
5681 break;
5682 case TGSI_OPCODE_USNE:
5683 case TGSI_OPCODE_FSNE:
5684 case TGSI_OPCODE_DSNE:
5685 if (inst->Instruction.Opcode == TGSI_OPCODE_DSNE)
5686 strcpy(writemask, ".x");
5687 emit_ucompare("notEqual");
5688 break;
5689 case TGSI_OPCODE_SGE:
5690 emit_compare("greaterThanEqual");
5691 break;
5692 case TGSI_OPCODE_ISGE:
5693 case TGSI_OPCODE_USGE:
5694 case TGSI_OPCODE_FSGE:
5695 case TGSI_OPCODE_DSGE:
5696 if (inst->Instruction.Opcode == TGSI_OPCODE_DSGE)
5697 strcpy(writemask, ".x");
5698 emit_ucompare("greaterThanEqual");
5699 break;
5700 case TGSI_OPCODE_POW:
5701 emit_buff(&ctx->glsl_strbufs, "%s = %s(pow(%s, %s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5702 break;
5703 case TGSI_OPCODE_CMP:
5704 emit_buff(&ctx->glsl_strbufs, "%s = mix(%s, %s, greaterThanEqual(%s, vec4(0.0)))%s;\n", dsts[0], srcs[1], srcs[2], srcs[0], writemask);
5705 break;
5706 case TGSI_OPCODE_UCMP:
5707 emit_buff(&ctx->glsl_strbufs, "%s = mix(%s, %s, notEqual(floatBitsToUint(%s), uvec4(0.0)))%s;\n", dsts[0], srcs[2], srcs[1], srcs[0], writemask);
5708 break;
5709 case TGSI_OPCODE_END:
5710 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
5711 handle_vertex_proc_exit(ctx, &ctx->glsl_strbufs, &ctx->has_clipvertex_so);
5712 } else if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL && ctx->cfg->has_cull_distance) {
5713 emit_clip_dist_movs(ctx, &ctx->glsl_strbufs);
5714 } else if (iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL && ctx->cfg->has_cull_distance) {
5715 if (ctx->so && !ctx->key->gs_present)
5716 emit_so_movs(ctx, &ctx->glsl_strbufs, &ctx->has_clipvertex_so);
5717 emit_clip_dist_movs(ctx, &ctx->glsl_strbufs);
5718 if (!ctx->key->gs_present) {
5719 emit_prescale(&ctx->glsl_strbufs);
5720 }
5721 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
5722 handle_fragment_proc_exit(ctx, &ctx->glsl_strbufs);
5723 }
5724 emit_buf(&ctx->glsl_strbufs, "}\n");
5725 break;
5726 case TGSI_OPCODE_RET:
5727 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
5728 handle_vertex_proc_exit(ctx, &ctx->glsl_strbufs, &ctx->has_clipvertex_so);
5729 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
5730 handle_fragment_proc_exit(ctx, &ctx->glsl_strbufs);
5731 }
5732 emit_buf(&ctx->glsl_strbufs, "return;\n");
5733 break;
5734 case TGSI_OPCODE_ARL:
5735 emit_buff(&ctx->glsl_strbufs, "%s = int(floor(%s)%s);\n", dsts[0], srcs[0], writemask);
5736 break;
5737 case TGSI_OPCODE_UARL:
5738 emit_buff(&ctx->glsl_strbufs, "%s = int(%s);\n", dsts[0], srcs[0]);
5739 break;
5740 case TGSI_OPCODE_XPD:
5741 emit_buff(&ctx->glsl_strbufs, "%s = %s(cross(vec3(%s), vec3(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5742 break;
5743 case TGSI_OPCODE_BGNLOOP:
5744 emit_buf(&ctx->glsl_strbufs, "do {\n");
5745 indent_buf(&ctx->glsl_strbufs);
5746 break;
5747 case TGSI_OPCODE_ENDLOOP:
5748 outdent_buf(&ctx->glsl_strbufs);
5749 emit_buf(&ctx->glsl_strbufs, "} while(true);\n");
5750 break;
5751 case TGSI_OPCODE_BRK:
5752 emit_buf(&ctx->glsl_strbufs, "break;\n");
5753 break;
5754 case TGSI_OPCODE_EMIT: {
5755 struct immed *imd = &ctx->imm[(inst->Src[0].Register.Index)];
5756 if (ctx->so && ctx->key->gs_present)
5757 emit_so_movs(ctx, &ctx->glsl_strbufs, &ctx->has_clipvertex_so);
5758 if (ctx->cfg->has_cull_distance && ctx->key->gs.emit_clip_distance)
5759 emit_clip_dist_movs(ctx, &ctx->glsl_strbufs);
5760 emit_prescale(&ctx->glsl_strbufs);
5761 if (imd->val[inst->Src[0].Register.SwizzleX].ui > 0) {
5762 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5763 emit_buff(&ctx->glsl_strbufs, "EmitStreamVertex(%d);\n", imd->val[inst->Src[0].Register.SwizzleX].ui);
5764 } else
5765 emit_buf(&ctx->glsl_strbufs, "EmitVertex();\n");
5766 break;
5767 }
5768 case TGSI_OPCODE_ENDPRIM: {
5769 struct immed *imd = &ctx->imm[(inst->Src[0].Register.Index)];
5770 if (imd->val[inst->Src[0].Register.SwizzleX].ui > 0) {
5771 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5772 emit_buff(&ctx->glsl_strbufs, "EndStreamPrimitive(%d);\n", imd->val[inst->Src[0].Register.SwizzleX].ui);
5773 } else
5774 emit_buf(&ctx->glsl_strbufs, "EndPrimitive();\n");
5775 break;
5776 }
5777 case TGSI_OPCODE_INTERP_CENTROID:
5778 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(interpolateAtCentroid(%s)%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], src_swizzle0);
5779 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5780 break;
5781 case TGSI_OPCODE_INTERP_SAMPLE:
5782 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(interpolateAtSample(%s, %s.x)%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], src_swizzle0);
5783 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5784 break;
5785 case TGSI_OPCODE_INTERP_OFFSET:
5786 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(interpolateAtOffset(%s, %s.xy)%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], src_swizzle0);
5787 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5788 break;
5789 case TGSI_OPCODE_UMUL_HI:
5790 emit_buff(&ctx->glsl_strbufs, "umulExtended(%s, %s, umul_temp, mul_utemp);\n", srcs[0], srcs[1]);
5791 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(umul_temp%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), writemask);
5792 if (!ctx->cfg->use_gles) {
5793 if (ctx->cfg->has_gpu_shader5)
5794 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5795 else
5796 ctx->shader_req_bits |= SHADER_REQ_SHADER_INTEGER_FUNC;
5797 }
5798 ctx->write_mul_utemp = true;
5799 break;
5800 case TGSI_OPCODE_IMUL_HI:
5801 emit_buff(&ctx->glsl_strbufs, "imulExtended(%s, %s, imul_temp, mul_itemp);\n", srcs[0], srcs[1]);
5802 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(imul_temp%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), writemask);
5803 if (!ctx->cfg->use_gles) {
5804 if (ctx->cfg->has_gpu_shader5)
5805 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5806 else
5807 ctx->shader_req_bits |= SHADER_REQ_SHADER_INTEGER_FUNC;
5808 }
5809 ctx->write_mul_itemp = true;
5810 break;
5811
5812 case TGSI_OPCODE_IBFE:
5813 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(bitfieldExtract(%s, int(%s.x), int(%s.x))));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], srcs[2]);
5814 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5815 break;
5816 case TGSI_OPCODE_UBFE:
5817 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(bitfieldExtract(%s, int(%s.x), int(%s.x))));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], srcs[2]);
5818 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5819 break;
5820 case TGSI_OPCODE_BFI:
5821 emit_buff(&ctx->glsl_strbufs, "%s = %s(uintBitsToFloat(bitfieldInsert(%s, %s, int(%s), int(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1], srcs[2], srcs[3]);
5822 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5823 break;
5824 case TGSI_OPCODE_BREV:
5825 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(bitfieldReverse(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
5826 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5827 break;
5828 case TGSI_OPCODE_POPC:
5829 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(bitCount(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
5830 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5831 break;
5832 case TGSI_OPCODE_LSB:
5833 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(findLSB(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
5834 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5835 break;
5836 case TGSI_OPCODE_IMSB:
5837 case TGSI_OPCODE_UMSB:
5838 emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(findMSB(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
5839 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5840 break;
5841 case TGSI_OPCODE_BARRIER:
5842 emit_buf(&ctx->glsl_strbufs, "barrier();\n");
5843 break;
5844 case TGSI_OPCODE_MEMBAR: {
5845 struct immed *imd = &ctx->imm[(inst->Src[0].Register.Index)];
5846 uint32_t val = imd->val[inst->Src[0].Register.SwizzleX].ui;
5847 uint32_t all_val = (TGSI_MEMBAR_SHADER_BUFFER |
5848 TGSI_MEMBAR_ATOMIC_BUFFER |
5849 TGSI_MEMBAR_SHADER_IMAGE |
5850 TGSI_MEMBAR_SHARED);
5851
5852 if (val & TGSI_MEMBAR_THREAD_GROUP) {
5853 emit_buf(&ctx->glsl_strbufs, "groupMemoryBarrier();\n");
5854 } else {
5855 if ((val & all_val) == all_val) {
5856 emit_buf(&ctx->glsl_strbufs, "memoryBarrier();\n");
5857 ctx->shader_req_bits |= SHADER_REQ_IMAGE_LOAD_STORE;
5858 } else {
5859 if (val & TGSI_MEMBAR_SHADER_BUFFER) {
5860 emit_buf(&ctx->glsl_strbufs, "memoryBarrierBuffer();\n");
5861 }
5862 if (val & TGSI_MEMBAR_ATOMIC_BUFFER) {
5863 emit_buf(&ctx->glsl_strbufs, "memoryBarrierAtomicCounter();\n");
5864 }
5865 if (val & TGSI_MEMBAR_SHADER_IMAGE) {
5866 emit_buf(&ctx->glsl_strbufs, "memoryBarrierImage();\n");
5867 }
5868 if (val & TGSI_MEMBAR_SHARED) {
5869 emit_buf(&ctx->glsl_strbufs, "memoryBarrierShared();\n");
5870 }
5871 }
5872 }
5873 break;
5874 }
5875 case TGSI_OPCODE_STORE:
5876 if (ctx->cfg->use_gles) {
5877 if (!rewrite_1d_image_coordinate(ctx->src_bufs + 1, inst))
5878 return false;
5879 srcs[1] = ctx->src_bufs[1].buf;
5880 }
5881 /* Don't try to write to dest with a negative index. */
5882 if (dinfo.dest_index >= 0)
5883 translate_store(ctx, &ctx->glsl_strbufs, ctx->ssbo_memory_qualifier, ctx->images,
5884 inst, &sinfo, srcs, &dinfo, dsts[0]);
5885 break;
5886 case TGSI_OPCODE_LOAD:
5887 if (ctx->cfg->use_gles) {
5888 if (!rewrite_1d_image_coordinate(ctx->src_bufs + 1, inst))
5889 return false;
5890 srcs[1] = ctx->src_bufs[1].buf;
5891 }
5892 /* Replace an obvious out-of-bounds load with loading zero. */
5893 if (sinfo.sreg_index < 0 ||
5894 !translate_load(ctx, &ctx->glsl_strbufs, ctx->ssbo_memory_qualifier, ctx->images,
5895 inst, &sinfo, &dinfo, srcs, dsts[0], writemask)) {
5896 emit_buff(&ctx->glsl_strbufs, "%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n", dsts[0], writemask);
5897 }
5898 break;
5899 case TGSI_OPCODE_ATOMUADD:
5900 case TGSI_OPCODE_ATOMXCHG:
5901 case TGSI_OPCODE_ATOMCAS:
5902 case TGSI_OPCODE_ATOMAND:
5903 case TGSI_OPCODE_ATOMOR:
5904 case TGSI_OPCODE_ATOMXOR:
5905 case TGSI_OPCODE_ATOMUMIN:
5906 case TGSI_OPCODE_ATOMUMAX:
5907 case TGSI_OPCODE_ATOMIMIN:
5908 case TGSI_OPCODE_ATOMIMAX:
5909 if (ctx->cfg->use_gles) {
5910 if (!rewrite_1d_image_coordinate(ctx->src_bufs + 1, inst))
5911 return false;
5912 srcs[1] = ctx->src_bufs[1].buf;
5913 }
5914 translate_atomic(ctx, inst, &sinfo, srcs, dsts[0]);
5915 break;
5916 case TGSI_OPCODE_RESQ:
5917 translate_resq(ctx, inst, srcs, dsts[0], writemask);
5918 break;
5919 case TGSI_OPCODE_CLOCK:
5920 ctx->shader_req_bits |= SHADER_REQ_SHADER_CLOCK;
5921 emit_buff(&ctx->glsl_strbufs, "%s = uintBitsToFloat(clock2x32ARB());\n", dsts[0]);
5922 break;
5923 default:
5924 vrend_printf("failed to convert opcode %d\n", inst->Instruction.Opcode);
5925 break;
5926 }
5927
5928 for (uint32_t i = 0; i < 1; i++) {
5929 enum tgsi_opcode_type dtype = tgsi_opcode_infer_dst_type(inst->Instruction.Opcode);
5930 if (dtype == TGSI_TYPE_DOUBLE) {
5931 emit_buff(&ctx->glsl_strbufs, "%s = uintBitsToFloat(unpackDouble2x32(%s));\n", fp64_dsts[0], dsts[0]);
5932 }
5933 }
5934 if (inst->Instruction.Saturate) {
5935 emit_buff(&ctx->glsl_strbufs, "%s = clamp(%s, 0.0, 1.0);\n", dsts[0], dsts[0]);
5936 }
5937
5938 if (strbuf_get_error(&ctx->glsl_strbufs.glsl_main))
5939 return false;
5940 return true;
5941 }
5942
5943 static boolean
prolog(struct tgsi_iterate_context * iter)5944 prolog(struct tgsi_iterate_context *iter)
5945 {
5946 struct dump_ctx *ctx = (struct dump_ctx *)iter;
5947
5948 if (ctx->prog_type == (enum tgsi_processor_type) -1)
5949 ctx->prog_type = iter->processor.Processor;
5950
5951 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX &&
5952 ctx->key->gs_present)
5953 ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
5954
5955 return true;
5956 }
5957
emit_ext(struct vrend_glsl_strbufs * glsl_strbufs,const char * name,const char * verb)5958 static void emit_ext(struct vrend_glsl_strbufs *glsl_strbufs, const char *name,
5959 const char *verb)
5960 {
5961 emit_ver_extf(glsl_strbufs, "#extension GL_%s : %s\n", name, verb);
5962 }
5963
emit_header(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)5964 static void emit_header(const struct dump_ctx *ctx, struct vrend_glsl_strbufs *glsl_strbufs)
5965 {
5966 if (ctx->cfg->use_gles) {
5967 emit_ver_extf(glsl_strbufs, "#version %d es\n", ctx->cfg->glsl_version);
5968
5969 if ((ctx->shader_req_bits & SHADER_REQ_CLIP_DISTANCE) ||
5970 (ctx->cfg->has_cull_distance && ctx->num_out_clip_dist == 0)) {
5971 emit_ext(glsl_strbufs, "EXT_clip_cull_distance", "require");
5972 }
5973
5974 if (ctx->shader_req_bits & SHADER_REQ_SAMPLER_MS)
5975 emit_ext(glsl_strbufs, "OES_texture_storage_multisample_2d_array", "require");
5976
5977 if (ctx->shader_req_bits & SHADER_REQ_CONSERVATIVE_DEPTH)
5978 emit_ext(glsl_strbufs, "EXT_conservative_depth", "require");
5979
5980 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT) {
5981 if (ctx->shader_req_bits & SHADER_REQ_FBFETCH)
5982 emit_ext(glsl_strbufs, "EXT_shader_framebuffer_fetch", "require");
5983 if (ctx->shader_req_bits & SHADER_REQ_BLEND_EQUATION_ADVANCED)
5984 emit_ext(glsl_strbufs, "KHR_blend_equation_advanced", "require");
5985 if (ctx->cfg->has_dual_src_blend)
5986 emit_ext(glsl_strbufs, "EXT_blend_func_extended", "require");
5987 }
5988
5989 if (ctx->shader_req_bits & SHADER_REQ_VIEWPORT_IDX)
5990 emit_ext(glsl_strbufs, "OES_viewport_array", "require");
5991
5992 if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY) {
5993 emit_ext(glsl_strbufs, "EXT_geometry_shader", "require");
5994 if (ctx->shader_req_bits & SHADER_REQ_PSIZE)
5995 emit_ext(glsl_strbufs, "OES_geometry_point_size", "enable");
5996 }
5997
5998 if (ctx->shader_req_bits & SHADER_REQ_NV_IMAGE_FORMATS)
5999 emit_ext(glsl_strbufs, "NV_image_formats", "require");
6000
6001 if (ctx->shader_req_bits & SHADER_REQ_SEPERATE_SHADER_OBJECTS)
6002 emit_ext(glsl_strbufs, "EXT_separate_shader_objects", "require");
6003
6004 if ((ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
6005 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL)) {
6006 if (ctx->cfg->glsl_version < 320)
6007 emit_ext(glsl_strbufs, "OES_tessellation_shader", "require");
6008 emit_ext(glsl_strbufs, "OES_tessellation_point_size", "enable");
6009 }
6010
6011 if (ctx->cfg->glsl_version < 320) {
6012 if (ctx->shader_req_bits & SHADER_REQ_SAMPLER_BUF)
6013 emit_ext(glsl_strbufs, "EXT_texture_buffer", "require");
6014 if (prefer_generic_io_block(ctx, io_in) || prefer_generic_io_block(ctx, io_out)) {
6015 emit_ext(glsl_strbufs, "OES_shader_io_blocks", "require");
6016 }
6017 if (ctx->shader_req_bits & SHADER_REQ_SAMPLE_SHADING)
6018 emit_ext(glsl_strbufs, "OES_sample_variables", "require");
6019 if (ctx->shader_req_bits & SHADER_REQ_GPU_SHADER5) {
6020 emit_ext(glsl_strbufs, "OES_gpu_shader5", "require");
6021 emit_ext(glsl_strbufs, "OES_shader_multisample_interpolation",
6022 "require");
6023 }
6024 if (ctx->shader_req_bits & SHADER_REQ_CUBE_ARRAY)
6025 emit_ext(glsl_strbufs, "OES_texture_cube_map_array", "require");
6026 if (ctx->shader_req_bits & SHADER_REQ_LAYER)
6027 emit_ext(glsl_strbufs, "EXT_geometry_shader", "require");
6028 if (ctx->shader_req_bits & SHADER_REQ_IMAGE_ATOMIC)
6029 emit_ext(glsl_strbufs, "OES_shader_image_atomic", "require");
6030
6031 if (ctx->shader_req_bits & SHADER_REQ_GEOMETRY_SHADER)
6032 emit_ext(glsl_strbufs, "EXT_geometry_shader", "require");
6033 }
6034
6035 if (logiop_require_inout(ctx->key)) {
6036 if (ctx->cfg->has_fbfetch_coherent)
6037 emit_ext(glsl_strbufs, "EXT_shader_framebuffer_fetch", "require");
6038 else
6039 emit_ext(glsl_strbufs, "EXT_shader_framebuffer_fetch_non_coherent", "require");
6040
6041 }
6042
6043 if (ctx->shader_req_bits & SHADER_REQ_TEXTURE_SHADOW_LOD)
6044 emit_ext(glsl_strbufs, "EXT_texture_shadow_lod", "require");
6045
6046 if (ctx->shader_req_bits & SHADER_REQ_LODQ)
6047 emit_ext(glsl_strbufs, "EXT_texture_query_lod", "require");
6048
6049 if (ctx->shader_req_bits & SHADER_REQ_SHADER_NOPERSPECTIVE_INTERPOLATION)
6050 emit_ext(glsl_strbufs, "NV_shader_noperspective_interpolation", "require");
6051
6052 emit_hdr(glsl_strbufs, "precision highp float;\n");
6053 emit_hdr(glsl_strbufs, "precision highp int;\n");
6054 } else {
6055 if (ctx->prog_type == TGSI_PROCESSOR_COMPUTE) {
6056 emit_ver_ext(glsl_strbufs, "#version 330\n");
6057 emit_ext(glsl_strbufs, "ARB_compute_shader", "require");
6058 } else {
6059 if (ctx->glsl_ver_required > 150)
6060 emit_ver_extf(glsl_strbufs, "#version %d\n", ctx->glsl_ver_required);
6061 else if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
6062 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL ||
6063 ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
6064 ctx->glsl_ver_required == 150)
6065 emit_ver_ext(glsl_strbufs, "#version 150\n");
6066 else if (ctx->glsl_ver_required == 140)
6067 emit_ver_ext(glsl_strbufs, "#version 140\n");
6068 else
6069 emit_ver_ext(glsl_strbufs, "#version 130\n");
6070 }
6071
6072 if (ctx->shader_req_bits & SHADER_REQ_ENHANCED_LAYOUTS)
6073 emit_ext(glsl_strbufs, "ARB_enhanced_layouts", "require");
6074
6075 if (ctx->shader_req_bits & SHADER_REQ_SEPERATE_SHADER_OBJECTS)
6076 emit_ext(glsl_strbufs, "ARB_separate_shader_objects", "require");
6077
6078 if (ctx->shader_req_bits & SHADER_REQ_EXPLICIT_ATTRIB_LOCATION)
6079 emit_ext(glsl_strbufs, "ARB_explicit_attrib_location", "require");
6080
6081 if (ctx->shader_req_bits & SHADER_REQ_ARRAYS_OF_ARRAYS)
6082 emit_ext(glsl_strbufs, "ARB_arrays_of_arrays", "require");
6083
6084 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
6085 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL)
6086 emit_ext(glsl_strbufs, "ARB_tessellation_shader", "require");
6087
6088 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX && ctx->cfg->use_explicit_locations)
6089 emit_ext(glsl_strbufs, "ARB_explicit_attrib_location", "require");
6090 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && fs_emit_layout(ctx))
6091 emit_ext(glsl_strbufs, "ARB_fragment_coord_conventions", "require");
6092
6093 if (ctx->ubo_used_mask)
6094 emit_ext(glsl_strbufs, "ARB_uniform_buffer_object", "require");
6095
6096 if (ctx->num_cull_dist_prop || ctx->key->num_in_cull || ctx->key->num_out_cull)
6097 emit_ext(glsl_strbufs, "ARB_cull_distance", "require");
6098 if (ctx->ssbo_used_mask)
6099 emit_ext(glsl_strbufs, "ARB_shader_storage_buffer_object", "require");
6100
6101 if (ctx->num_abo) {
6102 emit_ext(glsl_strbufs, "ARB_shader_atomic_counters", "require");
6103 emit_ext(glsl_strbufs, "ARB_shader_atomic_counter_ops", "require");
6104 }
6105
6106 for (uint32_t i = 0; i < ARRAY_SIZE(shader_req_table); i++) {
6107 if (shader_req_table[i].key == SHADER_REQ_SAMPLER_RECT && ctx->glsl_ver_required >= 140)
6108 continue;
6109
6110 if (ctx->shader_req_bits & shader_req_table[i].key) {
6111 emit_ext(glsl_strbufs, shader_req_table[i].string, "require");
6112 }
6113 }
6114 }
6115 }
6116
vrend_shader_samplerreturnconv(enum tgsi_return_type type)6117 char vrend_shader_samplerreturnconv(enum tgsi_return_type type)
6118 {
6119 switch (type) {
6120 case TGSI_RETURN_TYPE_SINT:
6121 return 'i';
6122 case TGSI_RETURN_TYPE_UINT:
6123 return 'u';
6124 default:
6125 return ' ';
6126 }
6127 }
6128
vrend_shader_samplertypeconv(bool use_gles,int sampler_type)6129 const char *vrend_shader_samplertypeconv(bool use_gles, int sampler_type)
6130 {
6131 switch (sampler_type) {
6132 case TGSI_TEXTURE_BUFFER: return "Buffer";
6133 case TGSI_TEXTURE_1D:
6134 if (!use_gles)
6135 return "1D";
6136 /* fallthrough */
6137 case TGSI_TEXTURE_2D: return "2D";
6138 case TGSI_TEXTURE_3D: return "3D";
6139 case TGSI_TEXTURE_CUBE: return "Cube";
6140 case TGSI_TEXTURE_RECT: return use_gles ? "2D" : "2DRect";
6141 case TGSI_TEXTURE_SHADOW1D:
6142 if (!use_gles) {
6143 return "1DShadow";
6144 }
6145 /* fallthrough */
6146 case TGSI_TEXTURE_SHADOW2D: return "2DShadow";
6147 case TGSI_TEXTURE_SHADOWRECT:
6148 return (!use_gles) ? "2DRectShadow" : "2DShadow";
6149 case TGSI_TEXTURE_1D_ARRAY:
6150 if (!use_gles)
6151 return "1DArray";
6152 /* fallthrough */
6153 case TGSI_TEXTURE_2D_ARRAY: return "2DArray";
6154 case TGSI_TEXTURE_SHADOW1D_ARRAY:
6155 if (!use_gles) {
6156 return "1DArrayShadow";
6157 }
6158 /* fallthrough */
6159 case TGSI_TEXTURE_SHADOW2D_ARRAY: return "2DArrayShadow";
6160 case TGSI_TEXTURE_SHADOWCUBE: return "CubeShadow";
6161 case TGSI_TEXTURE_CUBE_ARRAY: return "CubeArray";
6162 case TGSI_TEXTURE_SHADOWCUBE_ARRAY: return "CubeArrayShadow";
6163 case TGSI_TEXTURE_2D_MSAA: return "2DMS";
6164 case TGSI_TEXTURE_2D_ARRAY_MSAA: return "2DMSArray";
6165 default: return NULL;
6166 }
6167 }
6168
get_interp_string(const struct vrend_shader_cfg * cfg,enum tgsi_interpolate_mode interpolate,bool flatshade)6169 static const char *get_interp_string(const struct vrend_shader_cfg *cfg, enum tgsi_interpolate_mode interpolate, bool flatshade)
6170 {
6171 switch (interpolate) {
6172 case TGSI_INTERPOLATE_LINEAR:
6173 if (cfg->has_nopersective)
6174 return "noperspective ";
6175 else
6176 return "";
6177 case TGSI_INTERPOLATE_PERSPECTIVE:
6178 return "smooth ";
6179 case TGSI_INTERPOLATE_CONSTANT:
6180 return "flat ";
6181 case TGSI_INTERPOLATE_COLOR:
6182 if (flatshade)
6183 return "flat ";
6184 /* fallthrough */
6185 default:
6186 return "";
6187 }
6188 }
6189
get_aux_string(enum tgsi_interpolate_loc location)6190 static const char *get_aux_string(enum tgsi_interpolate_loc location)
6191 {
6192 switch (location) {
6193 case TGSI_INTERPOLATE_LOC_CENTER:
6194 default:
6195 return "";
6196 case TGSI_INTERPOLATE_LOC_CENTROID:
6197 return "centroid ";
6198 case TGSI_INTERPOLATE_LOC_SAMPLE:
6199 return "sample ";
6200 }
6201 }
6202
emit_sampler_decl(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,uint32_t * shadow_samp_mask,uint32_t i,uint32_t range,const struct vrend_shader_sampler * sampler)6203 static void emit_sampler_decl(const struct dump_ctx *ctx,
6204 struct vrend_glsl_strbufs *glsl_strbufs,
6205 uint32_t *shadow_samp_mask,
6206 uint32_t i, uint32_t range,
6207 const struct vrend_shader_sampler *sampler)
6208 {
6209 char ptc;
6210 bool is_shad;
6211 const char *sname, *precision, *stc;
6212
6213 sname = tgsi_proc_to_prefix(ctx->prog_type);
6214
6215 precision = (ctx->cfg->use_gles) ? "highp" : "";
6216
6217 ptc = vrend_shader_samplerreturnconv(sampler->tgsi_sampler_return);
6218 stc = vrend_shader_samplertypeconv(ctx->cfg->use_gles, sampler->tgsi_sampler_type);
6219 is_shad = samplertype_is_shadow(sampler->tgsi_sampler_type);
6220
6221 if (range)
6222 emit_hdrf(glsl_strbufs, "uniform %s %csampler%s %ssamp%d[%d];\n", precision, ptc, stc, sname, i, range);
6223 else
6224 emit_hdrf(glsl_strbufs, "uniform %s %csampler%s %ssamp%d;\n", precision, ptc, stc, sname, i);
6225
6226 if (is_shad) {
6227 emit_hdrf(glsl_strbufs, "uniform %s vec4 %sshadmask%d;\n", precision, sname, i);
6228 emit_hdrf(glsl_strbufs, "uniform %s vec4 %sshadadd%d;\n", precision, sname, i);
6229 *shadow_samp_mask |= (1 << i);
6230 }
6231 }
6232
get_internalformat_string(int virgl_format,enum tgsi_return_type * stype)6233 const char *get_internalformat_string(int virgl_format, enum tgsi_return_type *stype)
6234 {
6235 switch (virgl_format) {
6236 case PIPE_FORMAT_R11G11B10_FLOAT:
6237 *stype = TGSI_RETURN_TYPE_FLOAT;
6238 return "r11f_g11f_b10f";
6239 case PIPE_FORMAT_R10G10B10A2_UNORM:
6240 *stype = TGSI_RETURN_TYPE_UNORM;
6241 return "rgb10_a2";
6242 case PIPE_FORMAT_R10G10B10A2_UINT:
6243 *stype = TGSI_RETURN_TYPE_UINT;
6244 return "rgb10_a2ui";
6245 case PIPE_FORMAT_R8_UNORM:
6246 *stype = TGSI_RETURN_TYPE_UNORM;
6247 return "r8";
6248 case PIPE_FORMAT_R8_SNORM:
6249 *stype = TGSI_RETURN_TYPE_SNORM;
6250 return "r8_snorm";
6251 case PIPE_FORMAT_R8_UINT:
6252 *stype = TGSI_RETURN_TYPE_UINT;
6253 return "r8ui";
6254 case PIPE_FORMAT_R8_SINT:
6255 *stype = TGSI_RETURN_TYPE_SINT;
6256 return "r8i";
6257 case PIPE_FORMAT_R8G8_UNORM:
6258 *stype = TGSI_RETURN_TYPE_UNORM;
6259 return "rg8";
6260 case PIPE_FORMAT_R8G8_SNORM:
6261 *stype = TGSI_RETURN_TYPE_SNORM;
6262 return "rg8_snorm";
6263 case PIPE_FORMAT_R8G8_UINT:
6264 *stype = TGSI_RETURN_TYPE_UINT;
6265 return "rg8ui";
6266 case PIPE_FORMAT_R8G8_SINT:
6267 *stype = TGSI_RETURN_TYPE_SINT;
6268 return "rg8i";
6269 case PIPE_FORMAT_R8G8B8A8_UNORM:
6270 *stype = TGSI_RETURN_TYPE_UNORM;
6271 return "rgba8";
6272 case PIPE_FORMAT_R8G8B8A8_SNORM:
6273 *stype = TGSI_RETURN_TYPE_SNORM;
6274 return "rgba8_snorm";
6275 case PIPE_FORMAT_R8G8B8A8_UINT:
6276 *stype = TGSI_RETURN_TYPE_UINT;
6277 return "rgba8ui";
6278 case PIPE_FORMAT_R8G8B8A8_SINT:
6279 *stype = TGSI_RETURN_TYPE_SINT;
6280 return "rgba8i";
6281 case PIPE_FORMAT_R16_UNORM:
6282 *stype = TGSI_RETURN_TYPE_UNORM;
6283 return "r16";
6284 case PIPE_FORMAT_R16_SNORM:
6285 *stype = TGSI_RETURN_TYPE_SNORM;
6286 return "r16_snorm";
6287 case PIPE_FORMAT_R16_UINT:
6288 *stype = TGSI_RETURN_TYPE_UINT;
6289 return "r16ui";
6290 case PIPE_FORMAT_R16_SINT:
6291 *stype = TGSI_RETURN_TYPE_SINT;
6292 return "r16i";
6293 case PIPE_FORMAT_R16_FLOAT:
6294 *stype = TGSI_RETURN_TYPE_FLOAT;
6295 return "r16f";
6296 case PIPE_FORMAT_R16G16_UNORM:
6297 *stype = TGSI_RETURN_TYPE_UNORM;
6298 return "rg16";
6299 case PIPE_FORMAT_R16G16_SNORM:
6300 *stype = TGSI_RETURN_TYPE_SNORM;
6301 return "rg16_snorm";
6302 case PIPE_FORMAT_R16G16_UINT:
6303 *stype = TGSI_RETURN_TYPE_UINT;
6304 return "rg16ui";
6305 case PIPE_FORMAT_R16G16_SINT:
6306 *stype = TGSI_RETURN_TYPE_SINT;
6307 return "rg16i";
6308 case PIPE_FORMAT_R16G16_FLOAT:
6309 *stype = TGSI_RETURN_TYPE_FLOAT;
6310 return "rg16f";
6311 case PIPE_FORMAT_R16G16B16A16_UNORM:
6312 *stype = TGSI_RETURN_TYPE_UNORM;
6313 return "rgba16";
6314 case PIPE_FORMAT_R16G16B16A16_SNORM:
6315 *stype = TGSI_RETURN_TYPE_SNORM;
6316 return "rgba16_snorm";
6317 case PIPE_FORMAT_R16G16B16A16_FLOAT:
6318 *stype = TGSI_RETURN_TYPE_FLOAT;
6319 return "rgba16f";
6320 case PIPE_FORMAT_R32_FLOAT:
6321 *stype = TGSI_RETURN_TYPE_FLOAT;
6322 return "r32f";
6323 case PIPE_FORMAT_R32_UINT:
6324 *stype = TGSI_RETURN_TYPE_UINT;
6325 return "r32ui";
6326 case PIPE_FORMAT_R32_SINT:
6327 *stype = TGSI_RETURN_TYPE_SINT;
6328 return "r32i";
6329 case PIPE_FORMAT_R32G32_FLOAT:
6330 *stype = TGSI_RETURN_TYPE_FLOAT;
6331 return "rg32f";
6332 case PIPE_FORMAT_R32G32_UINT:
6333 *stype = TGSI_RETURN_TYPE_UINT;
6334 return "rg32ui";
6335 case PIPE_FORMAT_R32G32_SINT:
6336 *stype = TGSI_RETURN_TYPE_SINT;
6337 return "rg32i";
6338 case PIPE_FORMAT_R32G32B32A32_FLOAT:
6339 *stype = TGSI_RETURN_TYPE_FLOAT;
6340 return "rgba32f";
6341 case PIPE_FORMAT_R32G32B32A32_UINT:
6342 *stype = TGSI_RETURN_TYPE_UINT;
6343 return "rgba32ui";
6344 case PIPE_FORMAT_R16G16B16A16_UINT:
6345 *stype = TGSI_RETURN_TYPE_UINT;
6346 return "rgba16ui";
6347 case PIPE_FORMAT_R16G16B16A16_SINT:
6348 *stype = TGSI_RETURN_TYPE_SINT;
6349 return "rgba16i";
6350 case PIPE_FORMAT_R32G32B32A32_SINT:
6351 *stype = TGSI_RETURN_TYPE_SINT;
6352 return "rgba32i";
6353 case PIPE_FORMAT_NONE:
6354 *stype = TGSI_RETURN_TYPE_UNORM;
6355 return "";
6356 default:
6357 *stype = TGSI_RETURN_TYPE_UNORM;
6358 vrend_printf( "illegal format %d\n", virgl_format);
6359 return "";
6360 }
6361 }
6362
emit_image_decl(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,uint32_t i,uint32_t range,const struct vrend_shader_image * image)6363 static void emit_image_decl(const struct dump_ctx *ctx,
6364 struct vrend_glsl_strbufs *glsl_strbufs,
6365 uint32_t i, uint32_t range,
6366 const struct vrend_shader_image *image)
6367 {
6368 char ptc;
6369 const char *sname, *stc, *formatstr;
6370 enum tgsi_return_type itype;
6371 const char *volatile_str = image->vflag ? "volatile " : "";
6372 const char *coherent_str = image->coherent ? "coherent " : "";
6373 const char *precision = ctx->cfg->use_gles ? "highp " : "";
6374 const char *access = "";
6375 formatstr = get_internalformat_string(image->decl.Format, &itype);
6376 ptc = vrend_shader_samplerreturnconv(itype);
6377 sname = tgsi_proc_to_prefix(ctx->prog_type);
6378 stc = vrend_shader_samplertypeconv(ctx->cfg->use_gles, image->decl.Resource);
6379
6380
6381 /* From ARB_shader_image_load_store:
6382 Any image variable used for shader loads or atomic memory operations must
6383 be declared with a format layout qualifier matching the format of its
6384 associated image unit, ... Otherwise, the access is considered to
6385 involve a format mismatch, ... Image variables used exclusively for
6386 image stores need not include a format layout qualifier, but any declared
6387 qualifier must match the image unit format to avoid a format mismatch. */
6388 bool require_format_specifer = true;
6389 if (!image->decl.Writable) {
6390 access = "readonly ";
6391 } else if (!image->decl.Format ||
6392 (ctx->cfg->use_gles &&
6393 (image->decl.Format != PIPE_FORMAT_R32_FLOAT) &&
6394 (image->decl.Format != PIPE_FORMAT_R32_SINT) &&
6395 (image->decl.Format != PIPE_FORMAT_R32_UINT))) {
6396 access = "writeonly ";
6397 require_format_specifer = formatstr[0] != '\0';
6398 }
6399
6400 if (ctx->cfg->use_gles) { /* TODO: enable on OpenGL 4.2 and up also */
6401 emit_hdrf(glsl_strbufs, "layout(binding=%d%s%s) ",
6402 i, formatstr[0] != '\0' ? ", " : ", rgba32f", formatstr);
6403 } else if (require_format_specifer) {
6404 emit_hdrf(glsl_strbufs, "layout(%s) ",
6405 formatstr[0] != '\0' ? formatstr : "rgba32f");
6406 }
6407
6408 if (range)
6409 emit_hdrf(glsl_strbufs, "%s%s%suniform %s%cimage%s %simg%d[%d];\n",
6410 access, volatile_str, coherent_str, precision, ptc, stc, sname, i, range);
6411 else
6412 emit_hdrf(glsl_strbufs, "%s%s%suniform %s%cimage%s %simg%d;\n",
6413 access, volatile_str, coherent_str, precision, ptc, stc, sname, i);
6414 }
6415
emit_ios_common(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,uint32_t * shadow_samp_mask)6416 static int emit_ios_common(const struct dump_ctx *ctx,
6417 struct vrend_glsl_strbufs *glsl_strbufs,
6418 uint32_t *shadow_samp_mask)
6419 {
6420 uint i;
6421 const char *sname = tgsi_proc_to_prefix(ctx->prog_type);
6422 int glsl_ver_required = ctx->glsl_ver_required;
6423
6424 for (i = 0; i < ctx->num_temp_ranges; i++) {
6425 const char *precise = ctx->temp_ranges[i].precise_result ? "precise" : "";
6426 if (ctx->temp_ranges[i].array_id > 0) {
6427 emit_hdrf(glsl_strbufs, "%s vec4 temp%d[%d];\n", precise, ctx->temp_ranges[i].first,
6428 ctx->temp_ranges[i].last - ctx->temp_ranges[i].first + 1);
6429 } else {
6430 emit_hdrf(glsl_strbufs, "%s vec4 temp%d;\n", precise, ctx->temp_ranges[i].first);
6431 }
6432 }
6433
6434 if (ctx->require_dummy_value)
6435 emit_hdr(glsl_strbufs, "vec4 dummy_value = vec4(0.0, 0.0, 0.0, 0.0);\n");
6436
6437 if (ctx->write_mul_utemp) {
6438 emit_hdr(glsl_strbufs, "uvec4 mul_utemp;\n");
6439 emit_hdr(glsl_strbufs, "uvec4 umul_temp;\n");
6440 }
6441
6442 if (ctx->write_mul_itemp) {
6443 emit_hdr(glsl_strbufs, "ivec4 mul_itemp;\n");
6444 emit_hdr(glsl_strbufs, "ivec4 imul_temp;\n");
6445 }
6446
6447 if (ctx->ssbo_used_mask || ctx->has_file_memory) {
6448 emit_hdr(glsl_strbufs, "uint ssbo_addr_temp;\n");
6449 }
6450
6451 if (ctx->shader_req_bits & SHADER_REQ_FP64) {
6452 emit_hdr(glsl_strbufs, "dvec2 fp64_dst[3];\n");
6453 emit_hdr(glsl_strbufs, "dvec2 fp64_src[4];\n");
6454 }
6455
6456 for (i = 0; i < ctx->num_address; i++) {
6457 emit_hdrf(glsl_strbufs, "int addr%d;\n", i);
6458 }
6459 if (ctx->num_consts) {
6460 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
6461 emit_hdrf(glsl_strbufs, "uniform uvec4 %sconst0[%d];\n", cname, ctx->num_consts);
6462 }
6463
6464 if (ctx->ubo_used_mask) {
6465 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
6466
6467 if (ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT)) {
6468 glsl_ver_required = require_glsl_ver(ctx, 150);
6469 int first = ffs(ctx->ubo_used_mask) - 1;
6470 unsigned num_ubo = util_bitcount(ctx->ubo_used_mask);
6471 emit_hdrf(glsl_strbufs, "uniform %subo { vec4 ubocontents[%d]; } %suboarr[%d];\n", cname, ctx->ubo_sizes[first], cname, num_ubo);
6472 } else {
6473 unsigned mask = ctx->ubo_used_mask;
6474 while (mask) {
6475 uint32_t i = u_bit_scan(&mask);
6476 emit_hdrf(glsl_strbufs, "uniform %subo%d { vec4 %subo%dcontents[%d]; };\n", cname, i, cname, i, ctx->ubo_sizes[i]);
6477 }
6478 }
6479 }
6480
6481 if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
6482 for (i = 0; i < ctx->num_sampler_arrays; i++) {
6483 uint32_t first = ctx->sampler_arrays[i].first;
6484 uint32_t range = ctx->sampler_arrays[i].array_size;
6485
6486 emit_sampler_decl(ctx, glsl_strbufs, shadow_samp_mask, first, range, ctx->samplers + first);
6487 }
6488 } else {
6489 uint nsamp = util_last_bit(ctx->samplers_used);
6490 for (i = 0; i < nsamp; i++) {
6491
6492 if ((ctx->samplers_used & (1 << i)) == 0)
6493 continue;
6494
6495 emit_sampler_decl(ctx, glsl_strbufs, shadow_samp_mask, i, 0, ctx->samplers + i);
6496 }
6497 }
6498
6499 if (ctx->cfg->use_gles && ctx->gles_use_tex_query_level)
6500 emit_hdrf(glsl_strbufs, "uniform int %s_texlod[%d];\n", tgsi_proc_to_prefix(ctx->info.processor),
6501 util_bitcount(ctx->samplers_used));
6502
6503 if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
6504 for (i = 0; i < ctx->num_image_arrays; i++) {
6505 uint32_t first = ctx->image_arrays[i].first;
6506 uint32_t range = ctx->image_arrays[i].array_size;
6507 emit_image_decl(ctx, glsl_strbufs, first, range, ctx->images + first);
6508 }
6509 } else {
6510 uint32_t mask = ctx->images_used_mask;
6511 while (mask) {
6512 i = u_bit_scan(&mask);
6513 emit_image_decl(ctx, glsl_strbufs, i, 0, ctx->images + i);
6514 }
6515 }
6516
6517 for (i = 0; i < ctx->num_abo; i++){
6518 emit_hdrf(glsl_strbufs, "layout (binding = %d, offset = %d) uniform atomic_uint ac%d_%d", ctx->abo_idx[i], ctx->abo_offsets[i] * 4, ctx->abo_idx[i], ctx->abo_offsets[i] * 4);
6519 if (ctx->abo_sizes[i] > 1)
6520 emit_hdrf(glsl_strbufs, "[%d]", ctx->abo_sizes[i]);
6521 emit_hdrf(glsl_strbufs, ";\n");
6522 }
6523
6524 if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
6525 uint32_t mask = ctx->ssbo_used_mask;
6526 while (mask) {
6527 int start, count;
6528 u_bit_scan_consecutive_range(&mask, &start, &count);
6529 const char *atomic = (ctx->ssbo_atomic_mask & (1 << start)) ? "atomic" : "";
6530 emit_hdrf(glsl_strbufs, "layout (binding = %d, std430) buffer %sssbo%d { uint %sssbocontents%d[]; } %sssboarr%s[%d];\n", start, sname, start, sname, start, sname, atomic, count);
6531 }
6532 } else {
6533 uint32_t mask = ctx->ssbo_used_mask;
6534 while (mask) {
6535 uint32_t id = u_bit_scan(&mask);
6536 enum vrend_type_qualifier type = (ctx->ssbo_integer_mask & (1 << id)) ? INT : UINT;
6537 char *coherent = ctx->ssbo_memory_qualifier[id] == TGSI_MEMORY_COHERENT ? "coherent" : "";
6538 emit_hdrf(glsl_strbufs, "layout (binding = %d, std430) %s buffer %sssbo%d { %s %sssbocontents%d[]; };\n", id, coherent, sname, id,
6539 get_string(type), sname, id);
6540 }
6541 }
6542
6543 return glsl_ver_required;
6544 }
6545
emit_ios_streamout(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)6546 static void emit_ios_streamout(const struct dump_ctx *ctx,
6547 struct vrend_glsl_strbufs *glsl_strbufs)
6548 {
6549 if (ctx->so) {
6550 char outtype[6] = "";
6551 for (uint i = 0; i < ctx->so->num_outputs; i++) {
6552 if (!ctx->write_so_outputs[i])
6553 continue;
6554 if (ctx->so->output[i].num_components == 1)
6555 snprintf(outtype, 6, "float");
6556 else
6557 snprintf(outtype, 6, "vec%d", ctx->so->output[i].num_components);
6558
6559 if (ctx->so->output[i].stream && ctx->prog_type == TGSI_PROCESSOR_GEOMETRY)
6560 emit_hdrf(glsl_strbufs, "layout (stream=%d) out %s tfout%d;\n", ctx->so->output[i].stream, outtype, i);
6561 else {
6562 const struct vrend_shader_io *output = get_io_slot(&ctx->outputs[0], ctx->num_outputs,
6563 ctx->so->output[i].register_index);
6564 if (ctx->so->output[i].need_temp || output->name == TGSI_SEMANTIC_CLIPDIST ||
6565 ctx->prog_type == TGSI_PROCESSOR_GEOMETRY || output->glsl_predefined_no_emit) {
6566
6567 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL)
6568 emit_hdrf(glsl_strbufs, "out %s tfout%d[];\n", outtype, i);
6569 else
6570 emit_hdrf(glsl_strbufs, "out %s tfout%d;\n", outtype, i);
6571 }
6572 }
6573 }
6574 }
6575 }
6576
emit_ios_indirect_generics_output(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,const char * postfix)6577 static void emit_ios_indirect_generics_output(const struct dump_ctx *ctx,
6578 struct vrend_glsl_strbufs *glsl_strbufs,
6579 const char *postfix)
6580 {
6581 if (ctx->generic_ios.output_range.used) {
6582 int size = ctx->generic_ios.output_range.io.last -
6583 ctx->generic_ios.output_range.io.first + 1;
6584 char array_handle[32] = "";
6585 if (size > 1)
6586 snprintf(array_handle, sizeof(array_handle), "[%d]", size);
6587
6588 if (prefer_generic_io_block(ctx, io_out)) {
6589 char blockname[64];
6590 const char *stage_prefix = get_stage_output_name_prefix(ctx->prog_type);
6591 get_blockname(blockname, stage_prefix, &ctx->generic_ios.output_range.io);
6592
6593 char blockvarame[64];
6594 get_blockvarname(blockvarame, stage_prefix, &ctx->generic_ios.output_range.io, postfix);
6595
6596 emit_hdrf(glsl_strbufs, "out %s {\n vec4 %s%s; \n} %s;\n", blockname,
6597 ctx->generic_ios.output_range.io.glsl_name, array_handle, blockvarame);
6598 } else
6599 emit_hdrf(glsl_strbufs, "out vec4 %s%s%s;\n",
6600 ctx->generic_ios.output_range.io.glsl_name,
6601 postfix,
6602 array_handle);
6603 }
6604 }
6605
emit_ios_indirect_generics_input(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,const char * postfix)6606 static void emit_ios_indirect_generics_input(const struct dump_ctx *ctx,
6607 struct vrend_glsl_strbufs *glsl_strbufs,
6608 const char *postfix)
6609 {
6610 if (ctx->generic_ios.input_range.used) {
6611 int size = ctx->generic_ios.input_range.io.last -
6612 ctx->generic_ios.input_range.io.first + 1;
6613 char array_handle[32] = "";
6614 if (size > 1)
6615 snprintf(array_handle, sizeof(array_handle), "[%d]", size);
6616
6617 assert(size < 256 && size >= 0);
6618
6619 if (prefer_generic_io_block(ctx, io_in)) {
6620
6621 char blockname[64];
6622 char blockvarame[64];
6623 const char *stage_prefix = get_stage_input_name_prefix(ctx, ctx->prog_type);
6624
6625 get_blockname(blockname, stage_prefix, &ctx->generic_ios.input_range.io);
6626 get_blockvarname(blockvarame, stage_prefix, &ctx->generic_ios.input_range.io,
6627 postfix);
6628
6629 emit_hdrf(glsl_strbufs, "in %s {\n vec4 %s%s; \n} %s;\n",
6630 blockname, ctx->generic_ios.input_range.io.glsl_name,
6631 array_handle, blockvarame);
6632 } else
6633 emit_hdrf(glsl_strbufs, "in vec4 %s%s%s;\n",
6634 ctx->generic_ios.input_range.io.glsl_name,
6635 postfix,
6636 array_handle);
6637 }
6638 }
6639
6640 static void
emit_ios_generic(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,enum io_type iot,const char * prefix,const struct vrend_shader_io * io,const char * inout,const char * postfix)6641 emit_ios_generic(const struct dump_ctx *ctx,
6642 struct vrend_glsl_strbufs *glsl_strbufs,
6643 struct vrend_generic_ios *generic_ios,
6644 struct vrend_texcoord_ios *texcoord_ios,
6645 enum io_type iot, const char *prefix,
6646 const struct vrend_shader_io *io, const char *inout,
6647 const char *postfix)
6648 {
6649 const char *atype[3] = {
6650 " vec4", "ivec4", "uvec4"
6651 };
6652
6653 const char *t = atype[io->type];
6654
6655 char layout[128] = "";
6656
6657 if (io->overlapping_array)
6658 return;
6659
6660 if (ctx->separable_program && io->name == TGSI_SEMANTIC_GENERIC &&
6661 !(ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && strcmp(inout, "in") != 0)) {
6662 snprintf(layout, sizeof(layout), "layout(location = %d) ", 31 - io->sid);
6663 }
6664
6665 if (io->first == io->last) {
6666 emit_hdr(glsl_strbufs, layout);
6667 /* ugly leave spaces to patch interp in later */
6668 emit_hdrf(glsl_strbufs, "%s%s %s %s %s %s%s;\n",
6669 io->precise ? "precise" : "",
6670 io->invariant ? "invariant" : "",
6671 prefix,
6672 inout,
6673 t,
6674 io->glsl_name,
6675 postfix);
6676
6677 if (io->name == TGSI_SEMANTIC_GENERIC) {
6678 assert(io->sid < 64);
6679 if (iot == io_in) {
6680 generic_ios->match.inputs_emitted_mask |= 1ull << io->sid;
6681 } else {
6682 generic_ios->match.outputs_emitted_mask |= 1ull << io->sid;
6683 }
6684 } else if (io->name == TGSI_SEMANTIC_TEXCOORD) {
6685 assert(io->sid < 8);
6686 if (iot == io_in) {
6687 texcoord_ios->match.inputs_emitted_mask |= 1ull << io->sid;
6688 } else {
6689 texcoord_ios->match.outputs_emitted_mask |= 1ull << io->sid;
6690 }
6691 }
6692
6693 } else {
6694 int array_size = io->last - io->first + 1;
6695 if (prefer_generic_io_block(ctx, iot)) {
6696 const char *stage_prefix = iot == io_in ? get_stage_input_name_prefix(ctx, ctx->prog_type):
6697 get_stage_output_name_prefix(ctx->prog_type);
6698
6699 char blockname[64];
6700 get_blockname(blockname, stage_prefix, io);
6701
6702 char blockvarame[64];
6703 get_blockvarname(blockvarame, stage_prefix, io, postfix);
6704
6705 emit_hdrf(glsl_strbufs, "%s %s {\n", inout, blockname);
6706 emit_hdr(glsl_strbufs, layout);
6707 emit_hdrf(glsl_strbufs, "%s%s\n%s %s %s[%d]; \n} %s;\n",
6708 io->precise ? "precise" : "",
6709 io->invariant ? "invariant" : "",
6710 prefix,
6711 t,
6712 io->glsl_name,
6713 array_size,
6714 blockvarame);
6715 } else {
6716 emit_hdr(glsl_strbufs, layout);
6717 emit_hdrf(glsl_strbufs, "%s%s\n%s %s %s %s%s[%d];\n",
6718 io->precise ? "precise" : "",
6719 io->invariant ? "invariant" : "",
6720 prefix,
6721 inout,
6722 t,
6723 io->glsl_name,
6724 postfix,
6725 array_size);
6726
6727 uint64_t mask = ((1ull << array_size) - 1) << io->sid;
6728 if (io->name == TGSI_SEMANTIC_GENERIC) {
6729 assert(io->sid + array_size < 64);
6730 if (iot == io_in) {
6731 generic_ios->match.inputs_emitted_mask |= mask;
6732 } else {
6733 generic_ios->match.outputs_emitted_mask |= mask;
6734 }
6735 } else if (io->name == TGSI_SEMANTIC_TEXCOORD) {
6736 assert(io->sid + array_size < 8);
6737 if (iot == io_in) {
6738 texcoord_ios->match.inputs_emitted_mask |= mask;
6739 } else {
6740 texcoord_ios->match.outputs_emitted_mask |= mask;
6741 }
6742 }
6743 }
6744 }
6745 }
6746
6747 typedef bool (*can_emit_generic_callback)(const struct vrend_shader_io *io);
6748
6749 /* Front and back color of the same semantic ID must have the same interpolator
6750 * specifiers, and it may happen, that one or the other shader doesn't define
6751 * both, front and back color, so always compare these two as COLOR. */
6752 static inline
get_semantic_to_compare(enum tgsi_semantic name)6753 enum tgsi_semantic get_semantic_to_compare(enum tgsi_semantic name)
6754 {
6755 switch (name) {
6756 case TGSI_SEMANTIC_COLOR:
6757 case TGSI_SEMANTIC_BCOLOR:
6758 return TGSI_SEMANTIC_COLOR;
6759 default:
6760 return name;
6761 }
6762 }
6763
6764 static const char *
get_interpolator_prefix(struct vrend_strbuf * buf,uint32_t * num_interps,const struct vrend_shader_cfg * cfg,const struct vrend_shader_io * io,const struct vrend_fs_shader_info * fs_info,bool flatshade)6765 get_interpolator_prefix(struct vrend_strbuf *buf, uint32_t *num_interps,
6766 const struct vrend_shader_cfg *cfg, const struct vrend_shader_io *io,
6767 const struct vrend_fs_shader_info *fs_info, bool flatshade)
6768 {
6769 if (io->name == TGSI_SEMANTIC_GENERIC ||
6770 io->name == TGSI_SEMANTIC_TEXCOORD ||
6771 io->name == TGSI_SEMANTIC_COLOR ||
6772 io->name == TGSI_SEMANTIC_BCOLOR) {
6773 (*num_interps)++;
6774 enum tgsi_semantic name = get_semantic_to_compare(io->name);
6775
6776 for (int j = 0; j < fs_info->num_interps; ++j) {
6777 if (get_semantic_to_compare(fs_info->interpinfo[j].semantic_name) == name &&
6778 fs_info->interpinfo[j].semantic_index == io->sid) {
6779 strbuf_fmt(buf, "%s %s",
6780 get_interp_string(cfg, fs_info->interpinfo[j].interpolate, flatshade),
6781 get_aux_string(fs_info->interpinfo[j].location));
6782 return buf->buf;
6783 }
6784 }
6785 }
6786 return "";
6787 }
6788
6789 static void
emit_ios_generic_outputs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint8_t front_back_color_emitted_flags[],bool * force_color_two_side,uint32_t * num_interps,const can_emit_generic_callback can_emit_generic)6790 emit_ios_generic_outputs(const struct dump_ctx *ctx,
6791 struct vrend_glsl_strbufs *glsl_strbufs,
6792 struct vrend_generic_ios *generic_ios,
6793 struct vrend_texcoord_ios *texcoord_ios,
6794 uint8_t front_back_color_emitted_flags[],
6795 bool *force_color_two_side,
6796 uint32_t *num_interps,
6797 const can_emit_generic_callback can_emit_generic)
6798 {
6799 uint32_t i;
6800 uint64_t fc_emitted = 0;
6801 uint64_t bc_emitted = 0;
6802
6803 char buffer[64];
6804 struct vrend_strbuf buf;
6805 strbuf_alloc_fixed(&buf, buffer, sizeof(buffer));
6806
6807 for (i = 0; i < ctx->num_outputs; i++) {
6808
6809 if (!ctx->outputs[i].glsl_predefined_no_emit) {
6810 /* GS stream outputs are handled separately */
6811 if (!can_emit_generic(&ctx->outputs[i]))
6812 continue;
6813
6814 /* It is save to use buf here even though it is declared outside the loop, because
6815 * when written it is reset, and the content is used within the iteration */
6816 const char *prefix = get_interpolator_prefix(&buf, num_interps, ctx->cfg, &ctx->outputs[i],
6817 &ctx->key->fs_info, ctx->key->flatshade);
6818
6819 if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR) {
6820 front_back_color_emitted_flags[ctx->outputs[i].sid] |= FRONT_COLOR_EMITTED;
6821 fc_emitted |= 1ull << ctx->outputs[i].sid;
6822 }
6823
6824 if (ctx->outputs[i].name == TGSI_SEMANTIC_BCOLOR) {
6825 front_back_color_emitted_flags[ctx->outputs[i].sid] |= BACK_COLOR_EMITTED;
6826 bc_emitted |= 1ull << ctx->outputs[i].sid;
6827 }
6828
6829 emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios,
6830 io_out, prefix, &ctx->outputs[i],
6831 ctx->outputs[i].fbfetch_used ? "inout" : "out", "");
6832 } else if (ctx->outputs[i].invariant || ctx->outputs[i].precise) {
6833 emit_hdrf(glsl_strbufs, "%s%s;\n",
6834 ctx->outputs[i].precise ? "precise " :
6835 (ctx->outputs[i].invariant ? "invariant " : ""),
6836 ctx->outputs[i].glsl_name);
6837 }
6838 }
6839
6840 /* If a back color emitted without a corresponding front color, then
6841 * we have to force two side coloring, because the FS shader might expect
6842 * a front color too. */
6843 if (bc_emitted & ~fc_emitted)
6844 *force_color_two_side = 1;
6845 }
6846
6847 static uint64_t
emit_ios_patch(struct vrend_glsl_strbufs * glsl_strbufs,const char * prefix,const struct vrend_shader_io * io,const char * inout,int size,bool emit_location)6848 emit_ios_patch(struct vrend_glsl_strbufs *glsl_strbufs,
6849 const char *prefix, const struct vrend_shader_io *io,
6850 const char *inout, int size, bool emit_location)
6851 {
6852 uint64_t emitted_patches = 0;
6853
6854 /* We start these locations from 32 and proceed downwards, to avoid
6855 * conflicting with generic IO locations. */
6856 if (emit_location)
6857 emit_hdrf(glsl_strbufs, "layout(location = %d) ", io->sid);
6858
6859 if (io->last == io->first) {
6860 emit_hdrf(glsl_strbufs, "%s %s vec4 %s;\n", prefix, inout, io->glsl_name);
6861 emitted_patches |= 1ul << io->sid;
6862 } else {
6863 emit_hdrf(glsl_strbufs, "%s %s vec4 %s[%d];\n", prefix, inout,
6864 io->glsl_name, size);
6865 uint64_t mask = (1ul << size) - 1;
6866 emitted_patches |= mask << io->sid;
6867 }
6868 return emitted_patches;
6869 }
6870
6871 static bool
can_emit_generic_default(UNUSED const struct vrend_shader_io * io)6872 can_emit_generic_default(UNUSED const struct vrend_shader_io *io)
6873 {
6874 return true;
6875 }
6876
emit_ios_vs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint32_t * num_interps,uint8_t front_back_color_emitted_flags[],bool * force_color_two_side)6877 static void emit_ios_vs(const struct dump_ctx *ctx,
6878 struct vrend_glsl_strbufs *glsl_strbufs,
6879 struct vrend_generic_ios *generic_ios,
6880 struct vrend_texcoord_ios *texcoord_ios,
6881 uint32_t *num_interps,
6882 uint8_t front_back_color_emitted_flags[],
6883 bool *force_color_two_side)
6884 {
6885 uint32_t i;
6886
6887 for (i = 0; i < ctx->num_inputs; i++) {
6888 char postfix[32] = "";
6889 if (!ctx->inputs[i].glsl_predefined_no_emit) {
6890 if (ctx->cfg->use_explicit_locations) {
6891 emit_hdrf(glsl_strbufs, "layout(location=%d) ", ctx->inputs[i].first);
6892 }
6893 if (ctx->inputs[i].first != ctx->inputs[i].last)
6894 snprintf(postfix, sizeof(postfix), "[%d]", ctx->inputs[i].last - ctx->inputs[i].first + 1);
6895 const char *vtype[3] = {"vec4", "ivec4", "uvec4"};
6896 emit_hdrf(glsl_strbufs, "in %s %s%s;\n",
6897 vtype[ctx->inputs[i].type], ctx->inputs[i].glsl_name, postfix);
6898 }
6899 }
6900
6901 emit_ios_indirect_generics_output(ctx, glsl_strbufs, "");
6902
6903 emit_ios_generic_outputs(ctx, glsl_strbufs, generic_ios, texcoord_ios,
6904 front_back_color_emitted_flags, force_color_two_side,
6905 num_interps, can_emit_generic_default);
6906
6907 if (ctx->key->color_two_side || ctx->force_color_two_side) {
6908 bool fcolor_emitted, bcolor_emitted;
6909
6910 enum tgsi_interpolate_mode interpolators[2] = {TGSI_INTERPOLATE_COLOR, TGSI_INTERPOLATE_COLOR};
6911 enum tgsi_interpolate_loc interp_loc[2] = { TGSI_INTERPOLATE_LOC_CENTER, TGSI_INTERPOLATE_LOC_CENTER};
6912 for (int k = 0; k < ctx->key->fs_info.num_interps; k++) {
6913 const struct vrend_interp_info *interp_info = &ctx->key->fs_info.interpinfo[k];
6914 if (interp_info->semantic_name == TGSI_SEMANTIC_COLOR ||
6915 interp_info->semantic_name == TGSI_SEMANTIC_BCOLOR) {
6916 interpolators[interp_info->semantic_index] = interp_info->interpolate;
6917 interp_loc[interp_info->semantic_index] = interp_info->location;
6918 }
6919 }
6920
6921 for (i = 0; i < ctx->num_outputs; i++) {
6922 if (ctx->outputs[i].sid >= 2)
6923 continue;
6924
6925 fcolor_emitted = bcolor_emitted = false;
6926
6927 fcolor_emitted = front_back_color_emitted_flags[ctx->outputs[i].sid] & FRONT_COLOR_EMITTED;
6928 bcolor_emitted = front_back_color_emitted_flags[ctx->outputs[i].sid] & BACK_COLOR_EMITTED;
6929
6930 if (fcolor_emitted && !bcolor_emitted) {
6931 emit_hdrf(glsl_strbufs, "%s %s out vec4 vso_bc%d;\n",
6932 get_interp_string(ctx->cfg, interpolators[ctx->outputs[i].sid], ctx->key->flatshade),
6933 get_aux_string(interp_loc[ctx->outputs[i].sid]),
6934 ctx->outputs[i].sid);
6935 front_back_color_emitted_flags[ctx->outputs[i].sid] |= BACK_COLOR_EMITTED;
6936 }
6937 if (bcolor_emitted && !fcolor_emitted) {
6938 emit_hdrf(glsl_strbufs, "%s %s out vec4 vso_c%d;\n",
6939 get_interp_string(ctx->cfg, interpolators[ctx->outputs[i].sid], ctx->key->flatshade),
6940 get_aux_string(interp_loc[ctx->outputs[i].sid]),
6941 ctx->outputs[i].sid);
6942 front_back_color_emitted_flags[ctx->outputs[i].sid] |= FRONT_COLOR_EMITTED;
6943 }
6944 }
6945 }
6946
6947 if (ctx->key->vs.fog_fixup_mask)
6948 emit_fog_fixup_hdr(ctx, glsl_strbufs);
6949
6950 if (ctx->has_clipvertex && ctx->is_last_vertex_stage) {
6951 emit_hdrf(glsl_strbufs, "%svec4 clipv_tmp;\n", ctx->has_clipvertex_so ? "out " : "");
6952 }
6953
6954 char cull_buf[64] = "";
6955 char clip_buf[64] = "";
6956
6957 if (ctx->cfg->has_cull_distance && (ctx->num_out_clip_dist || ctx->is_last_vertex_stage)) {
6958 int num_clip_dists = ctx->num_clip_dist_prop ? ctx->num_clip_dist_prop : 0;
6959 int num_cull_dists = ctx->num_cull_dist_prop ? ctx->num_cull_dist_prop : 0;
6960
6961 int num_clip_cull = num_clip_dists + num_cull_dists;
6962 if (ctx->num_out_clip_dist && !num_clip_cull)
6963 num_clip_dists = ctx->num_out_clip_dist;
6964
6965 if (num_clip_dists)
6966 snprintf(clip_buf, 64, "out float gl_ClipDistance[%d];\n", num_clip_dists);
6967 if (num_cull_dists)
6968 snprintf(cull_buf, 64, "out float gl_CullDistance[%d];\n", num_cull_dists);
6969
6970 if (ctx->is_last_vertex_stage) {
6971 emit_hdrf(glsl_strbufs, "%s%s", clip_buf, cull_buf);
6972 }
6973
6974 emit_hdr(glsl_strbufs, "vec4 clip_dist_temp[2];\n");
6975 }
6976
6977 const char *psize_buf = ctx->has_pointsize_output ? "out float gl_PointSize;\n" : "";
6978
6979 if (!ctx->is_last_vertex_stage && ctx->key->use_pervertex_in) {
6980 emit_hdrf(glsl_strbufs, "out gl_PerVertex {\n vec4 gl_Position;\n %s%s%s};\n", clip_buf, cull_buf, psize_buf);
6981 }
6982 }
6983
get_depth_layout(int depth_layout)6984 static const char *get_depth_layout(int depth_layout)
6985 {
6986 const char *dl[4] = {
6987 "depth_any",
6988 "depth_greater",
6989 "depth_less",
6990 "depth_unchanged"
6991 };
6992
6993 if (depth_layout < 1 || depth_layout > TGSI_FS_DEPTH_LAYOUT_UNCHANGED)
6994 return NULL;
6995 return dl[depth_layout -1];
6996 }
6997
emit_ios_fs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint32_t * num_interps)6998 static void emit_ios_fs(const struct dump_ctx *ctx,
6999 struct vrend_glsl_strbufs *glsl_strbufs,
7000 struct vrend_generic_ios *generic_ios,
7001 struct vrend_texcoord_ios *texcoord_ios,
7002 uint32_t *num_interps
7003 )
7004 {
7005 uint32_t i;
7006
7007 if (fs_emit_layout(ctx)) {
7008 bool upper_left = ctx->fs_lower_left_origin == ctx->key->fs.lower_left_origin;
7009 char comma = (upper_left && ctx->fs_integer_pixel_center) ? ',' : ' ';
7010
7011 if (!ctx->cfg->use_gles)
7012 emit_hdrf(glsl_strbufs, "layout(%s%c%s) in vec4 gl_FragCoord;\n",
7013 upper_left ? "origin_upper_left" : "",
7014 comma,
7015 ctx->fs_integer_pixel_center ? "pixel_center_integer" : "");
7016 }
7017 if (ctx->early_depth_stencil) {
7018 emit_hdr(glsl_strbufs, "layout(early_fragment_tests) in;\n");
7019 }
7020
7021 emit_ios_indirect_generics_input(ctx, glsl_strbufs, "");
7022
7023 for (i = 0; i < ctx->num_inputs; i++) {
7024 if (!ctx->inputs[i].glsl_predefined_no_emit) {
7025 const char *prefix = "";
7026 const char *auxprefix = "";
7027
7028 if (ctx->cfg->use_gles) {
7029 if (ctx->inputs[i].name == TGSI_SEMANTIC_COLOR) {
7030 if (!(ctx->key->fs.available_color_in_bits & (1 << ctx->inputs[i].sid))) {
7031 emit_hdrf(glsl_strbufs, "vec4 %s = vec4(0.0, 0.0, 0.0, 0.0);\n",
7032 ctx->inputs[i].glsl_name);
7033 continue;
7034 }
7035 }
7036
7037 if (ctx->inputs[i].name == TGSI_SEMANTIC_BCOLOR) {
7038 if (!(ctx->key->fs.available_color_in_bits & (1 << ctx->inputs[i].sid) << 2)) {
7039 emit_hdrf(glsl_strbufs, "vec4 %s = vec4(0.0, 0.0, 0.0, 0.0);\n",
7040 ctx->inputs[i].glsl_name);
7041 continue;
7042 }
7043 }
7044 }
7045
7046 if (ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC ||
7047 ctx->inputs[i].name == TGSI_SEMANTIC_COLOR ||
7048 ctx->inputs[i].name == TGSI_SEMANTIC_BCOLOR) {
7049 prefix = get_interp_string(ctx->cfg, ctx->inputs[i].interpolate, ctx->key->flatshade);
7050 if (!prefix)
7051 prefix = "";
7052 auxprefix = get_aux_string(ctx->inputs[i].location);
7053 (*num_interps)++;
7054 }
7055
7056 char prefixes[64];
7057 snprintf(prefixes, sizeof(prefixes), "%s %s", prefix, auxprefix);
7058 emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios, io_in, prefixes, &ctx->inputs[i], "in", "");
7059 }
7060 }
7061
7062 if (ctx->key->color_two_side) {
7063 if (ctx->color_in_mask & 1)
7064 emit_hdr(glsl_strbufs, "vec4 realcolor0;\n");
7065 if (ctx->color_in_mask & 2)
7066 emit_hdr(glsl_strbufs, "vec4 realcolor1;\n");
7067 }
7068
7069 unsigned choices = ctx->fs_blend_equation_advanced;
7070 while (choices) {
7071 enum gl_advanced_blend_mode choice = (enum gl_advanced_blend_mode)u_bit_scan(&choices);
7072 emit_hdrf(glsl_strbufs, "layout(blend_support_%s) out;\n", blend_to_name(choice));
7073 }
7074
7075 if (ctx->write_all_cbufs) {
7076 const char* type = "vec4";
7077 if (ctx->key->fs.cbufs_unsigned_int_bitmask)
7078 type = "uvec4";
7079 else if (ctx->key->fs.cbufs_signed_int_bitmask)
7080 type = "ivec4";
7081
7082 for (i = 0; i < (uint32_t)ctx->cfg->max_draw_buffers; i++) {
7083 if (ctx->cfg->use_gles) {
7084 if (ctx->key->fs.logicop_enabled)
7085 emit_hdrf(glsl_strbufs, "%s fsout_tmp_c%d;\n", type, i);
7086
7087 if (logiop_require_inout(ctx->key)) {
7088 const char *noncoherent = ctx->cfg->has_fbfetch_coherent ? "" : ", noncoherent";
7089 emit_hdrf(glsl_strbufs, "layout (location=%d%s) inout highp %s fsout_c%d;\n", i, noncoherent, type, i);
7090 } else
7091 emit_hdrf(glsl_strbufs, "layout (location=%d) out %s fsout_c%d;\n", i,
7092 type, i);
7093 } else
7094 emit_hdrf(glsl_strbufs, "out %s fsout_c%d;\n", type, i);
7095 }
7096 } else {
7097 for (i = 0; i < ctx->num_outputs; i++) {
7098
7099 if (!ctx->outputs[i].glsl_predefined_no_emit) {
7100 char prefix[64] = "";
7101
7102 if (ctx->cfg->use_gles &&
7103 ctx->outputs[i].name == TGSI_SEMANTIC_COLOR &&
7104 !ctx->cfg->has_dual_src_blend)
7105 sprintf(prefix, "layout(location = %d)", ctx->outputs[i].sid);
7106
7107 emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios, io_out, prefix, &ctx->outputs[i],
7108 ctx->outputs[i].fbfetch_used ? "inout" : "out", "");
7109
7110 } else if (ctx->outputs[i].invariant || ctx->outputs[i].precise) {
7111 emit_hdrf(glsl_strbufs, "%s%s;\n",
7112 ctx->outputs[i].precise ? "precise " :
7113 (ctx->outputs[i].invariant ? "invariant " : ""),
7114 ctx->outputs[i].glsl_name);
7115 }
7116 }
7117 }
7118
7119 if (ctx->fs_depth_layout) {
7120 const char *depth_layout = get_depth_layout(ctx->fs_depth_layout);
7121 if (depth_layout)
7122 emit_hdrf(glsl_strbufs, "layout (%s) out float gl_FragDepth;\n", depth_layout);
7123 }
7124
7125 if (ctx->num_in_clip_dist) {
7126 if (ctx->key->num_in_clip) {
7127 emit_hdrf(glsl_strbufs, "in float gl_ClipDistance[%d];\n", ctx->key->num_in_clip);
7128 } else if (ctx->num_in_clip_dist > 4 && !ctx->key->num_in_cull) {
7129 emit_hdrf(glsl_strbufs, "in float gl_ClipDistance[%d];\n", ctx->num_in_clip_dist);
7130 }
7131
7132 if (ctx->key->num_in_cull) {
7133 emit_hdrf(glsl_strbufs, "in float gl_CullDistance[%d];\n", ctx->key->num_in_cull);
7134 }
7135 if(ctx->fs_uses_clipdist_input)
7136 emit_hdr(glsl_strbufs, "vec4 clip_dist_temp[2];\n");
7137 }
7138 }
7139
7140 static bool
can_emit_generic_geom(const struct vrend_shader_io * io)7141 can_emit_generic_geom(const struct vrend_shader_io *io)
7142 {
7143 return io->stream == 0;
7144 }
7145
emit_ios_per_vertex_in(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,bool * has_pervertex)7146 static void emit_ios_per_vertex_in(const struct dump_ctx *ctx,
7147 struct vrend_glsl_strbufs *glsl_strbufs,
7148 bool *has_pervertex)
7149 {
7150 char clip_var[64] = "";
7151 char cull_var[64] = "";
7152
7153 if (ctx->num_in_clip_dist) {
7154 int clip_dist, cull_dist;
7155
7156 clip_dist = ctx->key->num_in_clip;
7157 cull_dist = ctx->key->num_in_cull;
7158
7159 int num_clip_cull = clip_dist + cull_dist;
7160 if (ctx->num_in_clip_dist && !num_clip_cull)
7161 clip_dist = ctx->num_in_clip_dist;
7162
7163 if (clip_dist)
7164 snprintf(clip_var, 64, "float gl_ClipDistance[%d];\n", clip_dist);
7165 if (cull_dist)
7166 snprintf(cull_var, 64, "float gl_CullDistance[%d];\n", cull_dist);
7167
7168 (*has_pervertex) = true;
7169 emit_hdrf(glsl_strbufs, "in gl_PerVertex {\n vec4 gl_Position; \n %s%s%s\n} gl_in[];\n",
7170 clip_var, cull_var, ctx->has_pointsize_input ? "float gl_PointSize;\n" : "");
7171
7172 }
7173
7174 }
7175
7176
emit_ios_per_vertex_out(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,const char * instance_var)7177 static void emit_ios_per_vertex_out(const struct dump_ctx *ctx,
7178 struct vrend_glsl_strbufs *glsl_strbufs, const char *instance_var)
7179 {
7180 int clip_dist = ctx->num_clip_dist_prop ? ctx->num_clip_dist_prop : ctx->key->num_out_clip;
7181 int cull_dist = ctx->num_cull_dist_prop ? ctx->num_cull_dist_prop : ctx->key->num_out_cull;
7182 int num_clip_cull = clip_dist + cull_dist;
7183
7184 if (ctx->num_out_clip_dist && !num_clip_cull)
7185 clip_dist = ctx->num_out_clip_dist;
7186
7187 if (ctx->key->use_pervertex_in) {
7188 char clip_var[64] = "", cull_var[64] = "";
7189 if (cull_dist)
7190 snprintf(cull_var, 64, "float gl_CullDistance[%d];\n", cull_dist);
7191
7192 if (clip_dist)
7193 snprintf(clip_var, 64, "float gl_ClipDistance[%d];\n", clip_dist);
7194
7195 emit_hdrf(glsl_strbufs, "out gl_PerVertex {\n vec4 gl_Position; \n %s%s%s\n} %s;\n",
7196 clip_var, cull_var,
7197 ctx->has_pointsize_output ? "float gl_PointSize;\n" : "",
7198 instance_var);
7199 }
7200
7201 if (clip_dist + cull_dist > 0)
7202 emit_hdr(glsl_strbufs, "vec4 clip_dist_temp[2];\n");
7203
7204 }
7205
emit_ios_geom(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint8_t front_back_color_emitted_flags[],uint32_t * num_interps,bool * has_pervertex,bool * force_color_two_side)7206 static void emit_ios_geom(const struct dump_ctx *ctx,
7207 struct vrend_glsl_strbufs *glsl_strbufs,
7208 struct vrend_generic_ios *generic_ios,
7209 struct vrend_texcoord_ios *texcoord_ios,
7210 uint8_t front_back_color_emitted_flags[],
7211 uint32_t *num_interps,
7212 bool *has_pervertex,
7213 bool *force_color_two_side)
7214 {
7215 uint32_t i;
7216 char invocbuf[25];
7217
7218 if (ctx->gs_num_invocations)
7219 snprintf(invocbuf, 25, ", invocations = %d", ctx->gs_num_invocations);
7220
7221 emit_hdrf(glsl_strbufs, "layout(%s%s) in;\n", prim_to_name(ctx->gs_in_prim),
7222 ctx->gs_num_invocations > 1 ? invocbuf : "");
7223 emit_hdrf(glsl_strbufs, "layout(%s, max_vertices = %d) out;\n", prim_to_name(ctx->gs_out_prim), ctx->gs_max_out_verts);
7224
7225
7226 for (i = 0; i < ctx->num_inputs; i++) {
7227 if (!ctx->inputs[i].glsl_predefined_no_emit) {
7228 char postfix[64];
7229 snprintf(postfix, sizeof(postfix), "[%d]", gs_input_prim_to_size(ctx->gs_in_prim));
7230 emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios,
7231 io_in, "", &ctx->inputs[i], "in", postfix);
7232 }
7233 }
7234
7235 for (i = 0; i < ctx->num_outputs; i++) {
7236 if (!ctx->outputs[i].glsl_predefined_no_emit) {
7237 if (!ctx->outputs[i].stream)
7238 continue;
7239
7240 const char *prefix = "";
7241 if (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC ||
7242 ctx->outputs[i].name == TGSI_SEMANTIC_COLOR ||
7243 ctx->outputs[i].name == TGSI_SEMANTIC_BCOLOR) {
7244 (*num_interps)++;
7245 }
7246
7247 emit_hdrf(glsl_strbufs, "layout (stream = %d) %s%s%sout vec4 %s;\n", ctx->outputs[i].stream, prefix,
7248 ctx->outputs[i].precise ? "precise " : "",
7249 ctx->outputs[i].invariant ? "invariant " : "",
7250 ctx->outputs[i].glsl_name);
7251 }
7252 }
7253
7254 emit_ios_indirect_generics_output(ctx, glsl_strbufs, "");
7255
7256 emit_ios_generic_outputs(ctx, glsl_strbufs, generic_ios, texcoord_ios,
7257 front_back_color_emitted_flags, force_color_two_side,
7258 num_interps, can_emit_generic_geom);
7259
7260 emit_ios_per_vertex_in(ctx, glsl_strbufs, has_pervertex);
7261
7262 if (ctx->has_clipvertex) {
7263 emit_hdrf(glsl_strbufs, "%svec4 clipv_tmp;\n", ctx->has_clipvertex_so ? "out " : "");
7264 }
7265
7266 if (ctx->num_out_clip_dist) {
7267 bool has_clip_or_cull_prop = ctx->num_clip_dist_prop + ctx->num_cull_dist_prop > 0;
7268
7269 int num_clip_dists = has_clip_or_cull_prop ? ctx->num_clip_dist_prop :
7270 (ctx->num_out_clip_dist ? ctx->num_out_clip_dist : 8);
7271 int num_cull_dists = has_clip_or_cull_prop ? ctx->num_cull_dist_prop : 0;
7272
7273 char cull_buf[64] = "";
7274 char clip_buf[64] = "";
7275
7276 if (num_clip_dists)
7277 snprintf(clip_buf, 64, "out float gl_ClipDistance[%d];\n", num_clip_dists);
7278 if (num_cull_dists)
7279 snprintf(cull_buf, 64, "out float gl_CullDistance[%d];\n", num_cull_dists);
7280
7281 emit_hdrf(glsl_strbufs, "%s%s\n", clip_buf, cull_buf);
7282 emit_hdrf(glsl_strbufs, "vec4 clip_dist_temp[2];\n");
7283 }
7284 }
7285
7286
emit_ios_tcs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint64_t * emitted_out_patches_mask,bool * has_pervertex)7287 static void emit_ios_tcs(const struct dump_ctx *ctx,
7288 struct vrend_glsl_strbufs *glsl_strbufs,
7289 struct vrend_generic_ios *generic_ios,
7290 struct vrend_texcoord_ios *texcoord_ios,
7291 uint64_t *emitted_out_patches_mask,
7292 bool *has_pervertex)
7293 {
7294 uint32_t i;
7295
7296 emit_ios_indirect_generics_input(ctx, glsl_strbufs, "[]");
7297
7298 for (i = 0; i < ctx->num_inputs; i++) {
7299 if (!ctx->inputs[i].glsl_predefined_no_emit) {
7300 if (ctx->inputs[i].name == TGSI_SEMANTIC_PATCH) {
7301 emit_ios_patch(glsl_strbufs, "", &ctx->inputs[i], "in",
7302 ctx->inputs[i].last - ctx->inputs[i].first + 1,
7303 ctx->separable_program);
7304 } else
7305 emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios, io_in, "", &ctx->inputs[i], "in", "[]");
7306 }
7307 }
7308
7309 uint64_t emitted_patches = 0;
7310
7311 emit_hdrf(glsl_strbufs, "layout(vertices = %d) out;\n", ctx->tcs_vertices_out);
7312
7313 if (ctx->patch_ios.output_range.used)
7314 emitted_patches |= emit_ios_patch(glsl_strbufs, "patch", &ctx->patch_ios.output_range.io, "out",
7315 ctx->patch_ios.output_range.io.last - ctx->patch_ios.output_range.io.first + 1,
7316 ctx->separable_program);
7317
7318 for (i = 0; i < ctx->num_outputs; i++) {
7319 if (!ctx->outputs[i].glsl_predefined_no_emit) {
7320 if (ctx->outputs[i].name == TGSI_SEMANTIC_PATCH) {
7321
7322 emitted_patches |= emit_ios_patch(glsl_strbufs, "patch", &ctx->outputs[i], "out",
7323 ctx->outputs[i].last - ctx->outputs[i].first + 1,
7324 ctx->separable_program);
7325 } else
7326 emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios, io_out, "", &ctx->outputs[i], "out", "[]");
7327 } else if (ctx->outputs[i].invariant || ctx->outputs[i].precise) {
7328 emit_hdrf(glsl_strbufs, "%s%s;\n",
7329 ctx->outputs[i].precise ? "precise " :
7330 (ctx->outputs[i].invariant ? "invariant " : ""),
7331 ctx->outputs[i].glsl_name);
7332 }
7333 }
7334
7335 emit_ios_per_vertex_in(ctx, glsl_strbufs, has_pervertex);
7336 emit_ios_per_vertex_out(ctx, glsl_strbufs, " gl_out[]");
7337
7338 *emitted_out_patches_mask = emitted_patches;
7339 }
7340
emit_ios_tes(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint8_t front_back_color_emitted_flags[],uint32_t * num_interps,bool * has_pervertex,bool * force_color_two_side)7341 static void emit_ios_tes(const struct dump_ctx *ctx,
7342 struct vrend_glsl_strbufs *glsl_strbufs,
7343 struct vrend_generic_ios *generic_ios,
7344 struct vrend_texcoord_ios *texcoord_ios,
7345 uint8_t front_back_color_emitted_flags[],
7346 uint32_t *num_interps,
7347 bool *has_pervertex,
7348 bool *force_color_two_side)
7349 {
7350 uint32_t i;
7351
7352 if (ctx->patch_ios.input_range.used)
7353 emit_ios_patch(glsl_strbufs, "patch", &ctx->patch_ios.input_range.io, "in",
7354 ctx->patch_ios.input_range.io.last -
7355 ctx->patch_ios.input_range.io.first + 1,
7356 ctx->separable_program);
7357
7358 if (generic_ios->input_range.used)
7359 emit_ios_indirect_generics_input(ctx, glsl_strbufs, "[]");
7360
7361 for (i = 0; i < ctx->num_inputs; i++) {
7362 if (!ctx->inputs[i].glsl_predefined_no_emit) {
7363 if (ctx->inputs[i].name == TGSI_SEMANTIC_PATCH)
7364 emit_ios_patch(glsl_strbufs, "patch", &ctx->inputs[i], "in",
7365 ctx->inputs[i].last - ctx->inputs[i].first + 1,
7366 ctx->separable_program);
7367 else
7368 emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios, io_in, "", &ctx->inputs[i], "in", "[]");
7369 }
7370 }
7371
7372 emit_hdrf(glsl_strbufs, "layout(%s, %s, %s%s) in;\n",
7373 prim_to_tes_name(ctx->tes_prim_mode),
7374 get_spacing_string(ctx->tes_spacing),
7375 ctx->tes_vertex_order ? "cw" : "ccw",
7376 ctx->tes_point_mode ? ", point_mode" : "");
7377
7378 emit_ios_indirect_generics_output(ctx, glsl_strbufs, "");
7379
7380 emit_ios_generic_outputs(ctx, glsl_strbufs, generic_ios, texcoord_ios,
7381 front_back_color_emitted_flags, force_color_two_side,
7382 num_interps, can_emit_generic_default);
7383
7384 emit_ios_per_vertex_in(ctx, glsl_strbufs, has_pervertex);
7385 emit_ios_per_vertex_out(ctx, glsl_strbufs, "");
7386
7387 if (ctx->has_clipvertex && !ctx->key->gs_present) {
7388 emit_hdrf(glsl_strbufs, "%svec4 clipv_tmp;\n", ctx->has_clipvertex_so ? "out " : "");
7389 }
7390
7391 }
7392
7393
emit_ios_cs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)7394 static void emit_ios_cs(const struct dump_ctx *ctx,
7395 struct vrend_glsl_strbufs *glsl_strbufs)
7396 {
7397 emit_hdrf(glsl_strbufs, "layout (local_size_x = %d, local_size_y = %d, local_size_z = %d) in;\n",
7398 ctx->local_cs_block_size[0], ctx->local_cs_block_size[1], ctx->local_cs_block_size[2]);
7399
7400 if (ctx->req_local_mem) {
7401 enum vrend_type_qualifier type = ctx->integer_memory ? INT : UINT;
7402 emit_hdrf(glsl_strbufs, "shared %s values[%d];\n", get_string(type), ctx->req_local_mem / 4);
7403 }
7404 }
7405
emit_interp_info(struct vrend_glsl_strbufs * glsl_strbufs,const struct vrend_shader_cfg * cfg,const struct vrend_fs_shader_info * fs_info,enum tgsi_semantic semantic,int sid,bool flatshade)7406 static void emit_interp_info(struct vrend_glsl_strbufs *glsl_strbufs,
7407 const struct vrend_shader_cfg *cfg,
7408 const struct vrend_fs_shader_info *fs_info,
7409 enum tgsi_semantic semantic, int sid, bool flatshade)
7410 {
7411 for (int j = 0; j < fs_info->num_interps; ++j) {
7412 if (fs_info->interpinfo[j].semantic_name == semantic &&
7413 fs_info->interpinfo[j].semantic_index == sid) {
7414 emit_hdrf(glsl_strbufs, "%s %s ",
7415 get_interp_string(cfg, fs_info->interpinfo[j].interpolate, flatshade),
7416 get_aux_string(fs_info->interpinfo[j].location));
7417 break;
7418 }
7419 }
7420 }
7421
7422 struct sematic_info {
7423 enum tgsi_semantic name;
7424 const char prefix;
7425 };
7426
emit_match_interfaces(struct vrend_glsl_strbufs * glsl_strbufs,const struct dump_ctx * ctx,const struct vrend_interface_bits * match,const struct sematic_info * semantic)7427 static void emit_match_interfaces(struct vrend_glsl_strbufs *glsl_strbufs,
7428 const struct dump_ctx *ctx,
7429 const struct vrend_interface_bits *match,
7430 const struct sematic_info *semantic)
7431 {
7432 uint64_t mask = (match->outputs_expected_mask | match->outputs_emitted_mask)
7433 ^ match->outputs_emitted_mask;
7434
7435 while (mask) {
7436 int i = u_bit_scan64(&mask);
7437 emit_interp_info(glsl_strbufs, ctx->cfg, &ctx->key->fs_info,
7438 semantic->name, i, ctx->key->flatshade);
7439
7440 if (semantic->name == TGSI_SEMANTIC_GENERIC && ctx->separable_program)
7441 emit_hdrf(glsl_strbufs, "layout(location=%d) ", i);
7442
7443 emit_hdrf(glsl_strbufs, "out vec4 %s_%c%d%s;\n",
7444 get_stage_output_name_prefix(ctx->prog_type),
7445 semantic->prefix, i,
7446 ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ? "[]" : "");
7447 }
7448 }
7449
emit_ios(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint64_t * patches_emitted_mask,uint8_t front_back_color_emitted_flags[],uint32_t * num_interps,bool * has_pervertex,bool * force_color_two_side,uint32_t * shadow_samp_mask)7450 static int emit_ios(const struct dump_ctx *ctx,
7451 struct vrend_glsl_strbufs *glsl_strbufs,
7452 struct vrend_generic_ios *generic_ios,
7453 struct vrend_texcoord_ios *texcoord_ios,
7454 uint64_t *patches_emitted_mask,
7455 uint8_t front_back_color_emitted_flags[],
7456 uint32_t *num_interps,
7457 bool *has_pervertex,
7458 bool *force_color_two_side,
7459 uint32_t *shadow_samp_mask)
7460 {
7461 *num_interps = 0;
7462 int glsl_ver_required = ctx->glsl_ver_required;
7463
7464 if (ctx->so && ctx->so->num_outputs >= PIPE_MAX_SO_OUTPUTS) {
7465 vrend_printf( "Num outputs exceeded, max is %u\n", PIPE_MAX_SO_OUTPUTS);
7466 set_hdr_error(glsl_strbufs);
7467 return glsl_ver_required;
7468 }
7469
7470 switch (ctx->prog_type) {
7471 case TGSI_PROCESSOR_VERTEX:
7472 emit_ios_vs(ctx, glsl_strbufs, generic_ios, texcoord_ios, num_interps, front_back_color_emitted_flags, force_color_two_side);
7473 break;
7474 case TGSI_PROCESSOR_FRAGMENT:
7475 emit_ios_fs(ctx, glsl_strbufs, generic_ios, texcoord_ios, num_interps);
7476 break;
7477 case TGSI_PROCESSOR_GEOMETRY:
7478 emit_ios_geom(ctx, glsl_strbufs, generic_ios, texcoord_ios, front_back_color_emitted_flags, num_interps, has_pervertex, force_color_two_side);
7479 break;
7480 case TGSI_PROCESSOR_TESS_CTRL:
7481 emit_ios_tcs(ctx, glsl_strbufs, generic_ios, texcoord_ios, patches_emitted_mask, has_pervertex);
7482 break;
7483 case TGSI_PROCESSOR_TESS_EVAL:
7484 emit_ios_tes(ctx, glsl_strbufs, generic_ios, texcoord_ios, front_back_color_emitted_flags, num_interps, has_pervertex, force_color_two_side);
7485 break;
7486 case TGSI_PROCESSOR_COMPUTE:
7487 emit_ios_cs(ctx, glsl_strbufs);
7488 break;
7489 default:
7490 vrend_printf("Unknown shader processor %d\n", ctx->prog_type);
7491 set_hdr_error(glsl_strbufs);
7492 return glsl_ver_required;
7493 }
7494
7495 const struct sematic_info generic = {TGSI_SEMANTIC_GENERIC, 'g'};
7496 const struct sematic_info texcoord = {TGSI_SEMANTIC_TEXCOORD, 't'};
7497
7498 emit_match_interfaces(glsl_strbufs, ctx, &generic_ios->match, &generic);
7499 emit_match_interfaces(glsl_strbufs, ctx, &texcoord_ios->match, &texcoord);
7500
7501 emit_ios_streamout(ctx, glsl_strbufs);
7502 glsl_ver_required = emit_ios_common(ctx, glsl_strbufs, shadow_samp_mask);
7503
7504 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT &&
7505 ctx->key->pstipple_enabled) {
7506 emit_hdr(glsl_strbufs, "uint stip_temp;\n");
7507 }
7508
7509 return glsl_ver_required;
7510 }
7511
fill_fragment_interpolants(const struct dump_ctx * ctx,struct vrend_fs_shader_info * fs_info)7512 static boolean fill_fragment_interpolants(const struct dump_ctx *ctx, struct vrend_fs_shader_info *fs_info)
7513 {
7514 uint32_t i, index = 0;
7515
7516 for (i = 0; i < ctx->num_inputs; i++) {
7517 if (ctx->inputs[i].glsl_predefined_no_emit)
7518 continue;
7519
7520 if (ctx->inputs[i].name != TGSI_SEMANTIC_GENERIC &&
7521 ctx->inputs[i].name != TGSI_SEMANTIC_COLOR)
7522 continue;
7523
7524 if (index >= ctx->num_interps) {
7525 vrend_printf( "mismatch in number of interps %d %d\n", index, ctx->num_interps);
7526 return true;
7527 }
7528 fs_info->interpinfo[index].semantic_name = ctx->inputs[i].name;
7529 fs_info->interpinfo[index].semantic_index = ctx->inputs[i].sid;
7530 fs_info->interpinfo[index].interpolate = ctx->inputs[i].interpolate;
7531 fs_info->interpinfo[index].location = ctx->inputs[i].location;
7532 index++;
7533 }
7534 return true;
7535 }
7536
fill_interpolants(const struct dump_ctx * ctx,struct vrend_variable_shader_info * sinfo)7537 static boolean fill_interpolants(const struct dump_ctx *ctx, struct vrend_variable_shader_info *sinfo)
7538 {
7539 if (!ctx->num_interps)
7540 return true;
7541 if (ctx->prog_type != TGSI_PROCESSOR_FRAGMENT)
7542 return true;
7543
7544 return fill_fragment_interpolants(ctx, &sinfo->fs_info);
7545 }
7546
analyze_instruction(struct tgsi_iterate_context * iter,struct tgsi_full_instruction * inst)7547 static boolean analyze_instruction(struct tgsi_iterate_context *iter,
7548 struct tgsi_full_instruction *inst)
7549 {
7550 struct dump_ctx *ctx = (struct dump_ctx *)iter;
7551 uint32_t opcode = inst->Instruction.Opcode;
7552 if (opcode == TGSI_OPCODE_ATOMIMIN || opcode == TGSI_OPCODE_ATOMIMAX) {
7553 const struct tgsi_full_src_register *src = &inst->Src[0];
7554 if (src->Register.File == TGSI_FILE_BUFFER)
7555 ctx->ssbo_integer_mask |= 1 << src->Register.Index;
7556 if (src->Register.File == TGSI_FILE_MEMORY)
7557 ctx->integer_memory = true;
7558 }
7559
7560 if (!ctx->fs_uses_clipdist_input && (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT)) {
7561 for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) {
7562 if (inst->Src[i].Register.File == TGSI_FILE_INPUT) {
7563 int idx = inst->Src[i].Register.Index;
7564 for (unsigned j = 0; j < ctx->num_inputs; ++j) {
7565 if (ctx->inputs[j].first <= idx && ctx->inputs[j].last >= idx &&
7566 ctx->inputs[j].name == TGSI_SEMANTIC_CLIPDIST) {
7567 ctx->fs_uses_clipdist_input = true;
7568 break;
7569 }
7570 }
7571 }
7572 }
7573 }
7574
7575
7576 return true;
7577 }
7578
fill_var_sinfo(const struct dump_ctx * ctx,struct vrend_variable_shader_info * sinfo)7579 static void fill_var_sinfo(const struct dump_ctx *ctx, struct vrend_variable_shader_info *sinfo)
7580 {
7581 sinfo->num_ucp = ctx->is_last_vertex_stage ? VIRGL_NUM_CLIP_PLANES : 0;
7582 sinfo->fs_info.has_sample_input = ctx->has_sample_input;
7583 sinfo->fs_info.has_noperspective = ctx->has_noperspective;
7584 sinfo->fs_info.num_interps = ctx->num_interps;
7585 sinfo->fs_info.glsl_ver = ctx->glsl_ver_required;
7586 bool has_prop = (ctx->num_clip_dist_prop + ctx->num_cull_dist_prop) > 0;
7587
7588 sinfo->num_in_clip = has_prop ? ctx->num_clip_dist_prop : ctx->key->num_in_clip;
7589 sinfo->num_in_cull = has_prop ? ctx->num_cull_dist_prop : ctx->key->num_in_cull;
7590 sinfo->num_out_clip = has_prop ? ctx->num_clip_dist_prop : ctx->key->num_out_clip;
7591 sinfo->num_out_cull = has_prop ? ctx->num_cull_dist_prop : ctx->key->num_out_cull;
7592 sinfo->legacy_color_bits = ctx->color_out_mask;
7593 }
7594
fill_sinfo(const struct dump_ctx * ctx,struct vrend_shader_info * sinfo)7595 static void fill_sinfo(const struct dump_ctx *ctx, struct vrend_shader_info *sinfo)
7596 {
7597 sinfo->use_pervertex_in = ctx->has_pervertex;
7598 sinfo->samplers_used_mask = ctx->samplers_used;
7599 sinfo->images_used_mask = ctx->images_used_mask;
7600 sinfo->num_consts = ctx->num_consts;
7601 sinfo->ubo_used_mask = ctx->ubo_used_mask;
7602 sinfo->fog_input_mask = ctx->fog_input_mask;
7603 sinfo->fog_output_mask = ctx->fog_output_mask;
7604
7605 sinfo->ssbo_used_mask = ctx->ssbo_used_mask;
7606
7607 sinfo->ubo_indirect = !!(ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT));
7608
7609 sinfo->has_output_arrays = ctx->has_output_arrays;
7610 sinfo->has_input_arrays = ctx->has_input_arrays;
7611
7612 sinfo->out_generic_emitted_mask = ctx->generic_ios.match.outputs_emitted_mask;
7613 sinfo->out_texcoord_emitted_mask = ctx->texcoord_ios.match.outputs_emitted_mask;
7614 sinfo->out_patch_emitted_mask = ctx->patches_emitted_mask;
7615
7616 sinfo->num_inputs = ctx->num_inputs;
7617 sinfo->num_outputs = ctx->num_outputs;
7618 sinfo->shadow_samp_mask = ctx->shadow_samp_mask;
7619 sinfo->gs_out_prim = ctx->gs_out_prim;
7620 sinfo->tes_prim = ctx->tes_prim_mode;
7621 sinfo->tes_point_mode = ctx->tes_point_mode;
7622 sinfo->fs_blend_equation_advanced = ctx->fs_blend_equation_advanced;
7623 sinfo->separable_program = ctx->separable_program;
7624
7625 if (sinfo->so_names || ctx->so_names) {
7626 if (sinfo->so_names) {
7627 for (unsigned i = 0; i < sinfo->so_info.num_outputs; ++i)
7628 free(sinfo->so_names[i]);
7629 free(sinfo->so_names);
7630 }
7631 }
7632
7633 /* Record information about the layout of generics and patches for apssing it
7634 * to the next shader stage. mesa/tgsi doesn't provide this information for
7635 * TCS, TES, and GEOM shaders.
7636 */
7637 for(unsigned i = 0; i < ctx->num_outputs; i++) {
7638 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT) {
7639 if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR)
7640 sinfo->fs_output_layout[i] = ctx->outputs[i].sid;
7641 else
7642 sinfo->fs_output_layout[i] = -1;
7643 }
7644 }
7645
7646 sinfo->so_names = ctx->so_names;
7647 sinfo->attrib_input_mask = ctx->attrib_input_mask;
7648 if (sinfo->sampler_arrays)
7649 free(sinfo->sampler_arrays);
7650 sinfo->sampler_arrays = ctx->sampler_arrays;
7651 sinfo->num_sampler_arrays = ctx->num_sampler_arrays;
7652 if (sinfo->image_arrays)
7653 free(sinfo->image_arrays);
7654 sinfo->image_arrays = ctx->image_arrays;
7655 sinfo->num_image_arrays = ctx->num_image_arrays;
7656 sinfo->in_generic_emitted_mask = ctx->generic_ios.match.inputs_emitted_mask;
7657 sinfo->in_texcoord_emitted_mask = ctx->texcoord_ios.match.inputs_emitted_mask;
7658
7659 for (unsigned i = 0; i < ctx->num_outputs; ++i) {
7660 if (ctx->outputs[i].invariant) {
7661 uint32_t bit_pos = varying_bit_from_semantic_and_index(ctx->outputs[i].name, ctx->outputs[i].sid);
7662 uint32_t slot = bit_pos / 32;
7663 uint32_t bit = 1u << (bit_pos & 0x1f);
7664 sinfo->invariant_outputs[slot] |= bit;
7665 }
7666 }
7667 sinfo->gles_use_tex_query_level = ctx->gles_use_tex_query_level;
7668
7669 if (ctx->guest_sent_io_arrays) {
7670 sinfo->output_arrays.num_arrays = 0;
7671 for (unsigned i = 0; i < ctx->num_outputs; ++i) {
7672 const struct vrend_shader_io *io = &ctx->outputs[i];
7673 if (io->array_id > 0) {
7674 struct vrend_shader_io_array *array =
7675 &sinfo->output_arrays.layout[sinfo->output_arrays.num_arrays];
7676 array->sid = io->sid;
7677 array->size = io->last - io->first;
7678 array->name = io->name;
7679 array->array_id = io->array_id;
7680 ++sinfo->output_arrays.num_arrays;
7681 }
7682 }
7683 }
7684 }
7685
allocate_strbuffers(struct vrend_glsl_strbufs * glsl_strbufs)7686 static bool allocate_strbuffers(struct vrend_glsl_strbufs* glsl_strbufs)
7687 {
7688 if (!strbuf_alloc(&glsl_strbufs->glsl_main, 4096))
7689 return false;
7690
7691 if (strbuf_get_error(&glsl_strbufs->glsl_main))
7692 return false;
7693
7694 if (!strbuf_alloc(&glsl_strbufs->glsl_hdr, 1024))
7695 return false;
7696
7697 if (!strbuf_alloc(&glsl_strbufs->glsl_ver_ext, 1024))
7698 return false;
7699
7700 return true;
7701 }
7702
set_strbuffers(const struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_strarray * shader)7703 static void set_strbuffers(const struct vrend_glsl_strbufs* glsl_strbufs,
7704 struct vrend_strarray *shader)
7705 {
7706 strarray_addstrbuf(shader, &glsl_strbufs->glsl_ver_ext);
7707 strarray_addstrbuf(shader, &glsl_strbufs->glsl_hdr);
7708 strarray_addstrbuf(shader, &glsl_strbufs->glsl_main);
7709 }
7710
emit_required_sysval_uniforms(struct vrend_strbuf * block,uint32_t mask)7711 static void emit_required_sysval_uniforms(struct vrend_strbuf *block, uint32_t mask)
7712 {
7713 if (!mask)
7714 return;
7715
7716 strbuf_append(block, "layout (std140) uniform VirglBlock {\n");
7717 strbuf_append(block, "\tvec4 clipp[8];\n");
7718 strbuf_appendf(block, "\tuint stipple_pattern[%d];\n", VREND_POLYGON_STIPPLE_SIZE);
7719 strbuf_append(block, "\tfloat winsys_adjust_y;\n");
7720 strbuf_append(block, "\tfloat alpha_ref_val;\n");
7721 strbuf_append(block, "\tbool clip_plane_enabled;\n");
7722 strbuf_append(block, "};\n");
7723
7724 }
7725
compare_sid(const void * lhs,const void * rhs)7726 static int compare_sid(const void *lhs, const void *rhs)
7727 {
7728 const struct vrend_shader_io *l = (struct vrend_shader_io *)lhs;
7729 const struct vrend_shader_io *r = (struct vrend_shader_io *)rhs;
7730
7731 if (l->name != r->name)
7732 return l->name - r->name;
7733
7734 return l->sid - r->sid;
7735 }
7736
7737 struct sso_scan_ctx {
7738 struct tgsi_iterate_context iter;
7739 const struct vrend_shader_cfg *cfg;
7740 uint8_t max_generic_in_sid;
7741 uint8_t max_patch_in_sid;
7742 uint8_t max_generic_out_sid;
7743 uint8_t max_patch_out_sid;
7744 bool separable_program;
7745 bool unsupported_io;
7746 };
7747
7748 static boolean
iter_prop_for_separable(struct tgsi_iterate_context * iter,struct tgsi_full_property * prop)7749 iter_prop_for_separable(struct tgsi_iterate_context *iter,
7750 struct tgsi_full_property *prop)
7751 {
7752 struct sso_scan_ctx *ctx = (struct sso_scan_ctx *) iter;
7753
7754 if (prop->Property.PropertyName == TGSI_PROPERTY_SEPARABLE_PROGRAM)
7755 ctx->separable_program = prop->u[0].Data != 0;
7756 return true;
7757 }
7758
7759 static boolean
iter_decl_for_overlap(struct tgsi_iterate_context * iter,struct tgsi_full_declaration * decl)7760 iter_decl_for_overlap(struct tgsi_iterate_context *iter,
7761 struct tgsi_full_declaration *decl)
7762 {
7763 struct sso_scan_ctx *ctx = (struct sso_scan_ctx *) iter;
7764
7765 /* VS inputs and FS outputs are of no interest
7766 * when it comes to IO matching */
7767 if (decl->Declaration.File == TGSI_FILE_INPUT &&
7768 iter->processor.Processor == TGSI_PROCESSOR_VERTEX)
7769 return true;
7770
7771 if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
7772 iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT)
7773 return true;
7774
7775 switch (decl->Semantic.Name) {
7776 case TGSI_SEMANTIC_PATCH:
7777 if (decl->Declaration.File == TGSI_FILE_INPUT) {
7778 if (ctx->max_patch_in_sid < decl->Semantic.Index)
7779 ctx->max_patch_in_sid = decl->Semantic.Index;
7780 } else {
7781 if (ctx->max_patch_out_sid < decl->Semantic.Index)
7782 ctx->max_patch_out_sid = decl->Semantic.Index;
7783 }
7784 break;
7785 case TGSI_SEMANTIC_GENERIC:
7786 if (decl->Declaration.File == TGSI_FILE_INPUT) {
7787 if (ctx->max_generic_in_sid < decl->Semantic.Index)
7788 ctx->max_generic_in_sid = decl->Semantic.Index;
7789 } else {
7790 if (ctx->max_generic_out_sid < decl->Semantic.Index)
7791 ctx->max_generic_out_sid = decl->Semantic.Index;
7792 }
7793 break;
7794 case TGSI_SEMANTIC_COLOR:
7795 case TGSI_SEMANTIC_CLIPVERTEX:
7796 case TGSI_SEMANTIC_BCOLOR:
7797 case TGSI_SEMANTIC_TEXCOORD:
7798 case TGSI_SEMANTIC_FOG:
7799 /* These are semantics that need to be matched by name and since we can't
7800 * guarantee that they exist in all the stages of separable shaders
7801 * we can't emit the shader as SSO */
7802 ctx->unsupported_io = true;
7803 break;
7804 default:
7805 ;
7806 }
7807 return true;
7808 }
7809
7810
vrend_shader_query_separable_program(const struct tgsi_token * tokens,const struct vrend_shader_cfg * cfg)7811 bool vrend_shader_query_separable_program(const struct tgsi_token *tokens,
7812 const struct vrend_shader_cfg *cfg)
7813 {
7814 struct sso_scan_ctx ctx = {0};
7815 ctx.cfg = cfg;
7816 ctx.iter.iterate_property = iter_prop_for_separable;
7817 ctx.iter.iterate_declaration = iter_decl_for_overlap;
7818 tgsi_iterate_shader(tokens, &ctx.iter);
7819
7820 /* Since we have to match by location, and have to handle generics and patches
7821 * at in the limited range of 32 locations, we have to make sure that the
7822 * the generics range and the patch range don't overlap. In addition, to
7823 * work around that radeonsi doesn't support patch locations above 30 we have
7824 * to check that limit too. */
7825 bool supports_separable = !ctx.unsupported_io &&
7826 (ctx.max_generic_in_sid + ctx.max_patch_in_sid < MAX_VARYING) &&
7827 (ctx.max_generic_out_sid + ctx.max_patch_out_sid < MAX_VARYING) &&
7828 (ctx.max_patch_in_sid < ctx.cfg->max_shader_patch_varyings) &&
7829 (ctx.max_patch_out_sid < ctx.cfg->max_shader_patch_varyings);
7830 return ctx.separable_program && supports_separable;
7831 }
7832
vrend_convert_shader(const struct vrend_context * rctx,const struct vrend_shader_cfg * cfg,const struct tgsi_token * tokens,uint32_t req_local_mem,const struct vrend_shader_key * key,struct vrend_shader_info * sinfo,struct vrend_variable_shader_info * var_sinfo,struct vrend_strarray * shader)7833 bool vrend_convert_shader(const struct vrend_context *rctx,
7834 const struct vrend_shader_cfg *cfg,
7835 const struct tgsi_token *tokens,
7836 uint32_t req_local_mem,
7837 const struct vrend_shader_key *key,
7838 struct vrend_shader_info *sinfo,
7839 struct vrend_variable_shader_info *var_sinfo,
7840 struct vrend_strarray *shader)
7841 {
7842 struct dump_ctx ctx;
7843 boolean bret;
7844
7845 memset(&ctx, 0, sizeof(struct dump_ctx));
7846 ctx.cfg = cfg;
7847
7848 /* First pass to deal with edge cases. */
7849 ctx.iter.iterate_declaration = iter_decls;
7850 ctx.iter.iterate_instruction = analyze_instruction;
7851 bret = tgsi_iterate_shader(tokens, &ctx.iter);
7852 if (bret == false)
7853 return false;
7854
7855 ctx.is_last_vertex_stage =
7856 (ctx.iter.processor.Processor == TGSI_PROCESSOR_GEOMETRY) ||
7857 (ctx.iter.processor.Processor == TGSI_PROCESSOR_TESS_EVAL && !key->gs_present) ||
7858 (ctx.iter.processor.Processor == TGSI_PROCESSOR_VERTEX && !key->gs_present && !key->tes_present);
7859
7860 ctx.num_inputs = 0;
7861 ctx.iter.prolog = prolog;
7862 ctx.iter.iterate_instruction = iter_instruction;
7863 ctx.iter.iterate_declaration = iter_declaration;
7864 ctx.iter.iterate_immediate = iter_immediate;
7865 ctx.iter.iterate_property = iter_property;
7866 ctx.iter.epilog = NULL;
7867 ctx.key = key;
7868 ctx.cfg = cfg;
7869 ctx.prog_type = -1;
7870 ctx.num_image_arrays = 0;
7871 ctx.image_arrays = NULL;
7872 ctx.num_sampler_arrays = 0;
7873 ctx.sampler_arrays = NULL;
7874 ctx.ssbo_array_base = 0xffffffff;
7875 ctx.ssbo_atomic_array_base = 0xffffffff;
7876 ctx.has_sample_input = false;
7877 ctx.req_local_mem = req_local_mem;
7878 ctx.guest_sent_io_arrays = false;
7879 ctx.generic_ios.match.outputs_expected_mask = key->out_generic_expected_mask;
7880 ctx.texcoord_ios.match.outputs_expected_mask = key->out_texcoord_expected_mask;
7881
7882 tgsi_scan_shader(tokens, &ctx.info);
7883 /* if we are in core profile mode we should use GLSL 1.40 */
7884 if (cfg->use_core_profile && cfg->glsl_version >= 140)
7885 ctx.glsl_ver_required = require_glsl_ver(&ctx, 140);
7886
7887 if (sinfo->so_info.num_outputs) {
7888 ctx.so = &sinfo->so_info;
7889 ctx.so_names = calloc(sinfo->so_info.num_outputs, sizeof(char *));
7890 if (!ctx.so_names)
7891 goto fail;
7892 } else
7893 ctx.so_names = NULL;
7894
7895 if (ctx.info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT))
7896 ctx.glsl_ver_required = require_glsl_ver(&ctx, 150);
7897
7898 if (ctx.info.indirect_files & (1 << TGSI_FILE_BUFFER) ||
7899 ctx.info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
7900 ctx.glsl_ver_required = require_glsl_ver(&ctx, 150);
7901 ctx.shader_req_bits |= SHADER_REQ_GPU_SHADER5;
7902 }
7903 if (ctx.info.indirect_files & (1 << TGSI_FILE_SAMPLER))
7904 ctx.shader_req_bits |= SHADER_REQ_GPU_SHADER5;
7905
7906 if (!allocate_strbuffers(&ctx.glsl_strbufs))
7907 goto fail;
7908
7909 bret = tgsi_iterate_shader(tokens, &ctx.iter);
7910 if (bret == false)
7911 goto fail;
7912
7913 /* If we need a sysvalue UBO then we require GLSL 1.40 */
7914 if (ctx.glsl_strbufs.required_sysval_uniform_decls)
7915 ctx.glsl_ver_required = require_glsl_ver(&ctx, 140);
7916
7917 if (!ctx.cfg->use_gles &&
7918 ( key->in_arrays.num_arrays > 0 ) &&
7919 (ctx.prog_type == TGSI_PROCESSOR_GEOMETRY ||
7920 ctx.prog_type == TGSI_PROCESSOR_TESS_CTRL ||
7921 ctx.prog_type == TGSI_PROCESSOR_TESS_EVAL)) {
7922 ctx.shader_req_bits |= SHADER_REQ_ARRAYS_OF_ARRAYS;
7923 }
7924
7925 for (size_t i = 0; i < ARRAY_SIZE(ctx.src_bufs); ++i)
7926 strbuf_free(ctx.src_bufs + i);
7927
7928 for (size_t i = 0; i < ARRAY_SIZE(ctx.dst_bufs); ++i)
7929 strbuf_free(ctx.dst_bufs + i);
7930
7931 if (ctx.prog_type == TGSI_PROCESSOR_FRAGMENT)
7932 qsort(ctx.outputs, ctx.num_outputs, sizeof(struct vrend_shader_io), compare_sid);
7933
7934 const struct vrend_fs_shader_info *fs_info = &key->fs_info;
7935
7936 if (fs_info->num_interps && fs_info->has_sample_input &&
7937 ((cfg->use_gles && cfg->glsl_version < 320) ||
7938 cfg->glsl_version >= 320)) {
7939 ctx.shader_req_bits |= SHADER_REQ_GPU_SHADER5;
7940 }
7941
7942 if (fs_info->num_interps && fs_info->has_noperspective &&
7943 cfg->use_gles) {
7944 ctx.shader_req_bits |= SHADER_REQ_SHADER_NOPERSPECTIVE_INTERPOLATION;
7945 }
7946
7947 emit_header(&ctx, &ctx.glsl_strbufs);
7948 ctx.glsl_ver_required = emit_ios(&ctx, &ctx.glsl_strbufs, &ctx.generic_ios,
7949 &ctx.texcoord_ios, &ctx.patches_emitted_mask,
7950 ctx.front_back_color_emitted_flags,
7951 &ctx.num_interps, &ctx.has_pervertex,
7952 &ctx.force_color_two_side,
7953 &ctx.shadow_samp_mask);
7954
7955 if (strbuf_get_error(&ctx.glsl_strbufs.glsl_hdr))
7956 goto fail;
7957
7958 bret = fill_interpolants(&ctx, var_sinfo);
7959 if (bret == false)
7960 goto fail;
7961
7962 free(ctx.temp_ranges);
7963
7964 fill_sinfo(&ctx, sinfo);
7965 fill_var_sinfo(&ctx, var_sinfo);
7966
7967 emit_required_sysval_uniforms (&ctx.glsl_strbufs.glsl_hdr,
7968 ctx.glsl_strbufs.required_sysval_uniform_decls);
7969 set_strbuffers(&ctx.glsl_strbufs, shader);
7970
7971 VREND_DEBUG(dbg_shader_glsl, rctx, "GLSL:");
7972 VREND_DEBUG_EXT(dbg_shader_glsl, rctx, strarray_dump(shader));
7973 VREND_DEBUG(dbg_shader_glsl, rctx, "\n");
7974
7975 return true;
7976 fail:
7977 strbuf_free(&ctx.glsl_strbufs.glsl_main);
7978 strbuf_free(&ctx.glsl_strbufs.glsl_hdr);
7979 strbuf_free(&ctx.glsl_strbufs.glsl_ver_ext);
7980 free(ctx.so_names);
7981 free(ctx.temp_ranges);
7982 return false;
7983 }
7984
7985 static boolean
iter_vs_declaration(struct tgsi_iterate_context * iter,struct tgsi_full_declaration * decl)7986 iter_vs_declaration(struct tgsi_iterate_context *iter,
7987 struct tgsi_full_declaration *decl)
7988 {
7989 struct dump_ctx *ctx = (struct dump_ctx *)iter;
7990
7991 const char *shader_in_prefix = "vso";
7992 const char *shader_out_prefix = "tco";
7993 const char *name_prefix = "";
7994 unsigned i;
7995
7996 // Generate a shader that passes through all VS outputs
7997 if (decl->Declaration.File == TGSI_FILE_OUTPUT) {
7998 for (uint32_t j = 0; j < ctx->num_inputs; j++) {
7999 if (ctx->inputs[j].name == decl->Semantic.Name &&
8000 ctx->inputs[j].sid == decl->Semantic.Index &&
8001 ctx->inputs[j].first == decl->Range.First &&
8002 ctx->inputs[j].usage_mask == decl->Declaration.UsageMask &&
8003 ((!decl->Declaration.Array && ctx->inputs[j].array_id == 0) ||
8004 (ctx->inputs[j].array_id == decl->Array.ArrayID)))
8005 return true;
8006 }
8007 i = ctx->num_inputs++;
8008
8009 ctx->inputs[i].name = decl->Semantic.Name;
8010 ctx->inputs[i].sid = decl->Semantic.Index;
8011 ctx->inputs[i].interpolate = decl->Interp.Interpolate;
8012 ctx->inputs[i].location = decl->Interp.Location;
8013 ctx->inputs[i].first = decl->Range.First;
8014 ctx->inputs[i].last = decl->Range.Last;
8015 ctx->inputs[i].array_id = decl->Declaration.Array ? decl->Array.ArrayID : 0;
8016 ctx->inputs[i].usage_mask = decl->Declaration.UsageMask;
8017 ctx->inputs[i].num_components = 4;
8018 ctx->inputs[i].glsl_predefined_no_emit = false;
8019 ctx->inputs[i].glsl_no_index = false;
8020 ctx->inputs[i].override_no_wm = ctx->inputs[i].num_components == 1;
8021 ctx->inputs[i].glsl_gl_block = false;
8022
8023 switch (ctx->inputs[i].name) {
8024 case TGSI_SEMANTIC_PSIZE:
8025 name_prefix = "gl_PointSize";
8026 ctx->inputs[i].glsl_predefined_no_emit = true;
8027 ctx->inputs[i].glsl_no_index = true;
8028 ctx->inputs[i].override_no_wm = true;
8029 ctx->inputs[i].glsl_gl_block = true;
8030 ctx->shader_req_bits |= SHADER_REQ_PSIZE;
8031 break;
8032
8033 case TGSI_SEMANTIC_CLIPDIST:
8034 name_prefix = "gl_ClipDistance";
8035 ctx->inputs[i].glsl_predefined_no_emit = true;
8036 ctx->inputs[i].glsl_no_index = true;
8037 ctx->inputs[i].glsl_gl_block = true;
8038 ctx->num_in_clip_dist += 4 * (ctx->inputs[i].last - ctx->inputs[i].first + 1);
8039 ctx->shader_req_bits |= SHADER_REQ_CLIP_DISTANCE;
8040 if (ctx->inputs[i].last != ctx->inputs[i].first)
8041 ctx->guest_sent_io_arrays = true;
8042 break;
8043
8044 case TGSI_SEMANTIC_POSITION:
8045 name_prefix = "gl_Position";
8046 ctx->inputs[i].glsl_predefined_no_emit = true;
8047 ctx->inputs[i].glsl_no_index = true;
8048 ctx->inputs[i].glsl_gl_block = true;
8049 break;
8050
8051 case TGSI_SEMANTIC_PATCH:
8052 case TGSI_SEMANTIC_GENERIC:
8053 if (ctx->inputs[i].first != ctx->inputs[i].last ||
8054 ctx->inputs[i].array_id > 0) {
8055 ctx->guest_sent_io_arrays = true;
8056 if (!ctx->cfg->use_gles)
8057 ctx->shader_req_bits |= SHADER_REQ_ARRAYS_OF_ARRAYS;
8058 }
8059 break;
8060 default:
8061 break;
8062 }
8063
8064 memcpy(&ctx->outputs[i], &ctx->inputs[i], sizeof(struct vrend_shader_io));
8065
8066 if (ctx->inputs[i].glsl_no_index) {
8067 snprintf(ctx->inputs[i].glsl_name, 128, "%s", name_prefix);
8068 snprintf(ctx->outputs[i].glsl_name, 128, "%s", name_prefix);
8069 } else {
8070 if (ctx->inputs[i].name == TGSI_SEMANTIC_FOG){
8071 ctx->inputs[i].usage_mask = 0xf;
8072 ctx->inputs[i].num_components = 4;
8073 ctx->inputs[i].override_no_wm = false;
8074 snprintf(ctx->inputs[i].glsl_name, 64, "%s_f%d", shader_in_prefix, ctx->inputs[i].sid);
8075 snprintf(ctx->outputs[i].glsl_name, 64, "%s_f%d", shader_out_prefix, ctx->inputs[i].sid);
8076 } else if (ctx->inputs[i].name == TGSI_SEMANTIC_COLOR) {
8077 snprintf(ctx->inputs[i].glsl_name, 64, "%s_c%d", shader_in_prefix, ctx->inputs[i].sid);
8078 snprintf(ctx->outputs[i].glsl_name, 64, "%s_c%d", shader_out_prefix, ctx->inputs[i].sid);
8079 } else if (ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC) {
8080 snprintf(ctx->inputs[i].glsl_name, 64, "%s_g%d", shader_in_prefix, ctx->inputs[i].sid);
8081 snprintf(ctx->outputs[i].glsl_name, 64, "%s_g%d", shader_out_prefix, ctx->inputs[i].sid);
8082 } else {
8083 snprintf(ctx->outputs[i].glsl_name, 64, "%s_%d", shader_in_prefix, ctx->inputs[i].first);
8084 snprintf(ctx->inputs[i].glsl_name, 64, "%s_%d", shader_out_prefix, ctx->inputs[i].first);
8085 }
8086 }
8087 }
8088 return true;
8089 }
8090
vrend_shader_create_passthrough_tcs(const struct vrend_context * rctx,const struct vrend_shader_cfg * cfg,const struct tgsi_token * vs_tokens,const struct vrend_shader_key * key,const float tess_factors[6],struct vrend_shader_info * sinfo,struct vrend_strarray * shader,int vertices_per_patch)8091 bool vrend_shader_create_passthrough_tcs(const struct vrend_context *rctx,
8092 const struct vrend_shader_cfg *cfg,
8093 const struct tgsi_token *vs_tokens,
8094 const struct vrend_shader_key *key,
8095 const float tess_factors[6],
8096 struct vrend_shader_info *sinfo,
8097 struct vrend_strarray *shader,
8098 int vertices_per_patch)
8099 {
8100 struct dump_ctx ctx;
8101
8102 memset(&ctx, 0, sizeof(struct dump_ctx));
8103
8104 ctx.prog_type = TGSI_PROCESSOR_TESS_CTRL;
8105 ctx.cfg = cfg;
8106 ctx.key = key;
8107 ctx.iter.iterate_declaration = iter_vs_declaration;
8108 ctx.ssbo_array_base = 0xffffffff;
8109 ctx.ssbo_atomic_array_base = 0xffffffff;
8110 ctx.has_sample_input = false;
8111
8112 if (!allocate_strbuffers(&ctx.glsl_strbufs))
8113 goto fail;
8114
8115 tgsi_iterate_shader(vs_tokens, &ctx.iter);
8116
8117 /* What is the default on GL? */
8118 ctx.tcs_vertices_out = vertices_per_patch;
8119
8120 ctx.num_outputs = ctx.num_inputs;
8121
8122 handle_io_arrays(&ctx);
8123
8124 emit_header(&ctx, &ctx.glsl_strbufs);
8125 ctx.glsl_ver_required = emit_ios(&ctx, &ctx.glsl_strbufs, &ctx.generic_ios,
8126 &ctx.texcoord_ios, &ctx.patches_emitted_mask,
8127 ctx.front_back_color_emitted_flags,
8128 &ctx.num_interps, &ctx.has_pervertex,
8129 &ctx.force_color_two_side,
8130 &ctx.shadow_samp_mask);
8131
8132 emit_buf(&ctx.glsl_strbufs, "void main() {\n");
8133
8134 for (unsigned int i = 0; i < ctx.num_inputs; ++i) {
8135 const char *out_prefix = "";
8136 const char *in_prefix = "";
8137
8138 const char *postfix = "";
8139
8140 if (ctx.inputs[i].glsl_gl_block) {
8141 out_prefix = "gl_out[gl_InvocationID].";
8142 in_prefix = "gl_in[gl_InvocationID].";
8143 } else {
8144 postfix = "[gl_InvocationID]";
8145 }
8146
8147 if (ctx.inputs[i].first == ctx.inputs[i].last) {
8148 emit_buff(&ctx.glsl_strbufs, "%s%s%s = %s%s%s;\n",
8149 out_prefix, ctx.outputs[i].glsl_name, postfix,
8150 in_prefix, ctx.inputs[i].glsl_name, postfix);
8151 } else {
8152 unsigned size = ctx.inputs[i].last == ctx.inputs[i].first + 1;
8153 for (unsigned int k = 0; k < size; ++k) {
8154 emit_buff(&ctx.glsl_strbufs, "%s%s%s[%d] = %s%s%s[%d];\n",
8155 out_prefix, ctx.outputs[i].glsl_name, postfix, k,
8156 in_prefix, ctx.inputs[i].glsl_name, postfix, k);
8157 }
8158 }
8159 }
8160
8161 for (int i = 0; i < 4; ++i)
8162 emit_buff(&ctx.glsl_strbufs, "gl_TessLevelOuter[%d] = %f;\n", i, tess_factors[i]);
8163
8164 for (int i = 0; i < 2; ++i)
8165 emit_buff(&ctx.glsl_strbufs, "gl_TessLevelInner[%d] = %f;\n", i, tess_factors[i + 4]);
8166
8167 emit_buf(&ctx.glsl_strbufs, "}\n");
8168
8169 fill_sinfo(&ctx, sinfo);
8170 emit_required_sysval_uniforms (&ctx.glsl_strbufs.glsl_hdr,
8171 ctx.glsl_strbufs.required_sysval_uniform_decls);
8172 set_strbuffers(&ctx.glsl_strbufs, shader);
8173
8174 VREND_DEBUG(dbg_shader_glsl, rctx, "GLSL:");
8175 VREND_DEBUG_EXT(dbg_shader_glsl, rctx, strarray_dump(shader));
8176 VREND_DEBUG(dbg_shader_glsl, rctx, "\n");
8177
8178 return true;
8179 fail:
8180 strbuf_free(&ctx.glsl_strbufs.glsl_main);
8181 strbuf_free(&ctx.glsl_strbufs.glsl_hdr);
8182 strbuf_free(&ctx.glsl_strbufs.glsl_ver_ext);
8183 free(ctx.so_names);
8184 free(ctx.temp_ranges);
8185 return false;
8186 }
8187
8188 static
vrend_shader_write_io_as_src(struct vrend_strbuf * result,const char * array_or_varname,const struct vrend_shader_io * io,const struct tgsi_full_src_register * src,enum io_decl_type decl_type)8189 void vrend_shader_write_io_as_src(struct vrend_strbuf *result,
8190 const char *array_or_varname,
8191 const struct vrend_shader_io *io,
8192 const struct tgsi_full_src_register *src,
8193 enum io_decl_type decl_type)
8194 {
8195
8196
8197 if (io->first == io->last && !io->overlapping_array) {
8198 strbuf_appendf(result, "%s%s", io->glsl_name, array_or_varname);
8199 } else {
8200 const struct vrend_shader_io *base = io->overlapping_array ? io->overlapping_array : io;
8201 const int offset = src->Register.Index - io->first + io->array_offset;
8202
8203 if (decl_type == decl_block) {
8204 if (src->Register.Indirect)
8205 strbuf_appendf(result, "%s.%s[addr%d + %d]", array_or_varname, base->glsl_name,
8206 src->Indirect.Index, offset);
8207 else
8208 strbuf_appendf(result, "%s.%s[%d]", array_or_varname, base->glsl_name, offset);
8209 } else {
8210 if (src->Register.Indirect)
8211 strbuf_appendf(result, "%s%s[addr%d + %d]", base->glsl_name,
8212 array_or_varname, src->Indirect.Index, offset);
8213 else
8214 strbuf_appendf(result, "%s%s[%d]", base->glsl_name,
8215 array_or_varname, offset);
8216 }
8217 }
8218 }
8219
8220 static
vrend_shader_write_io_as_dst(struct vrend_strbuf * result,const char * array_or_varname,const struct vrend_shader_io * io,const struct tgsi_full_dst_register * src,enum io_decl_type decl_type)8221 void vrend_shader_write_io_as_dst(struct vrend_strbuf *result,
8222 const char *array_or_varname,
8223 const struct vrend_shader_io *io,
8224 const struct tgsi_full_dst_register *src,
8225 enum io_decl_type decl_type)
8226 {
8227
8228 if (io->first == io->last) {
8229 if (io->overlapping_array)
8230 strbuf_appendf(result, "%s%s[%d]", io->overlapping_array->glsl_name,
8231 array_or_varname, io->array_offset);
8232 else
8233 strbuf_appendf(result, "%s%s", io->glsl_name, array_or_varname);
8234 } else {
8235 const struct vrend_shader_io *base = io->overlapping_array ? io->overlapping_array : io;
8236 const int offset = src->Register.Index - io->first + io->array_offset;
8237
8238 if (decl_type == decl_block) {
8239 if (src->Register.Indirect)
8240 strbuf_appendf(result, "%s.%s[addr%d + %d]", array_or_varname, base->glsl_name,
8241 src->Indirect.Index, offset);
8242 else
8243 strbuf_appendf(result, "%s.%s[%d]", array_or_varname, base->glsl_name, offset);
8244 } else {
8245 if (src->Register.Indirect)
8246 strbuf_appendf(result, "%s%s[addr%d + %d]", base->glsl_name,
8247 array_or_varname, src->Indirect.Index, offset);
8248 else
8249 strbuf_appendf(result, "%s%s[%d]", base->glsl_name,
8250 array_or_varname, offset);
8251 }
8252 }
8253 }
8254
vrend_shader_needs_alpha_func(const struct vrend_shader_key * key)8255 bool vrend_shader_needs_alpha_func(const struct vrend_shader_key *key) {
8256 if (!key->add_alpha_test)
8257 return false;
8258 switch (key->alpha_test) {
8259 default:
8260 return false;
8261 case PIPE_FUNC_LESS:
8262 case PIPE_FUNC_EQUAL:
8263 case PIPE_FUNC_LEQUAL:
8264 case PIPE_FUNC_GREATER:
8265 case PIPE_FUNC_NOTEQUAL:
8266 case PIPE_FUNC_GEQUAL:
8267 return true;
8268 }
8269 }
8270
8271