xref: /aosp_15_r20/external/virglrenderer/src/vrend_shader.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
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