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