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