xref: /aosp_15_r20/external/virglrenderer/src/vrend_shader.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
1*bbecb9d1SAndroid Build Coastguard Worker /**************************************************************************
2*bbecb9d1SAndroid Build Coastguard Worker  *
3*bbecb9d1SAndroid Build Coastguard Worker  * Copyright (C) 2014 Red Hat Inc.
4*bbecb9d1SAndroid Build Coastguard Worker  *
5*bbecb9d1SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
6*bbecb9d1SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
7*bbecb9d1SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
8*bbecb9d1SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*bbecb9d1SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
10*bbecb9d1SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
11*bbecb9d1SAndroid Build Coastguard Worker  *
12*bbecb9d1SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included
13*bbecb9d1SAndroid Build Coastguard Worker  * in all copies or substantial portions of the Software.
14*bbecb9d1SAndroid Build Coastguard Worker  *
15*bbecb9d1SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16*bbecb9d1SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*bbecb9d1SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*bbecb9d1SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19*bbecb9d1SAndroid Build Coastguard Worker  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20*bbecb9d1SAndroid Build Coastguard Worker  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21*bbecb9d1SAndroid Build Coastguard Worker  * OTHER DEALINGS IN THE SOFTWARE.
22*bbecb9d1SAndroid Build Coastguard Worker  *
23*bbecb9d1SAndroid Build Coastguard Worker  **************************************************************************/
24*bbecb9d1SAndroid Build Coastguard Worker 
25*bbecb9d1SAndroid Build Coastguard Worker #include "tgsi/tgsi_info.h"
26*bbecb9d1SAndroid Build Coastguard Worker #include "tgsi/tgsi_iterate.h"
27*bbecb9d1SAndroid Build Coastguard Worker #include "tgsi/tgsi_scan.h"
28*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_memory.h"
29*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_math.h"
30*bbecb9d1SAndroid Build Coastguard Worker #include <string.h>
31*bbecb9d1SAndroid Build Coastguard Worker #include <stdio.h>
32*bbecb9d1SAndroid Build Coastguard Worker #include <math.h>
33*bbecb9d1SAndroid Build Coastguard Worker #include <errno.h>
34*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_shader.h"
35*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_debug.h"
36*bbecb9d1SAndroid Build Coastguard Worker 
37*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_strbuf.h"
38*bbecb9d1SAndroid Build Coastguard Worker 
39*bbecb9d1SAndroid Build Coastguard Worker /* start convert of tgsi to glsl */
40*bbecb9d1SAndroid Build Coastguard Worker 
41*bbecb9d1SAndroid Build Coastguard Worker #define INVARI_PREFIX "invariant"
42*bbecb9d1SAndroid Build Coastguard Worker 
43*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_NONE 0
44*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_SAMPLER_RECT       (1ULL << 0)
45*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_CUBE_ARRAY         (1ULL << 1)
46*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_INTS               (1ULL << 2)
47*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_SAMPLER_MS         (1ULL << 3)
48*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_INSTANCE_ID        (1ULL << 4)
49*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_LODQ               (1ULL << 5)
50*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_TXQ_LEVELS         (1ULL << 6)
51*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_TG4                (1ULL << 7)
52*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_VIEWPORT_IDX       (1ULL << 8)
53*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_STENCIL_EXPORT     (1ULL << 9)
54*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_LAYER              (1ULL << 10)
55*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_SAMPLE_SHADING     (1ULL << 11)
56*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_GPU_SHADER5        (1ULL << 12)
57*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_DERIVATIVE_CONTROL (1ULL << 13)
58*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_FP64               (1ULL << 14)
59*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_IMAGE_LOAD_STORE   (1ULL << 15)
60*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_ES31_COMPAT        (1ULL << 16)
61*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_IMAGE_SIZE         (1ULL << 17)
62*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_TXQS               (1ULL << 18)
63*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_FBFETCH            (1ULL << 19)
64*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_SHADER_CLOCK       (1ULL << 20)
65*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_PSIZE              (1ULL << 21)
66*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_IMAGE_ATOMIC       (1ULL << 22)
67*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_CLIP_DISTANCE      (1ULL << 23)
68*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_ENHANCED_LAYOUTS   (1ULL << 24)
69*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_SEPERATE_SHADER_OBJECTS (1ULL << 25)
70*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_ARRAYS_OF_ARRAYS  (1ULL << 26)
71*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_SHADER_INTEGER_FUNC (1ULL << 27)
72*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_SHADER_ATOMIC_FLOAT (1ULL << 28)
73*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_NV_IMAGE_FORMATS    (1ULL << 29)
74*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_CONSERVATIVE_DEPTH  (1ULL << 30)
75*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_SAMPLER_BUF        (1ULL << 31)
76*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_GEOMETRY_SHADER    (1ULL << 32)
77*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_BLEND_EQUATION_ADVANCED (1ULL << 33)
78*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_EXPLICIT_ATTRIB_LOCATION (1ULL << 34)
79*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_SHADER_NOPERSPECTIVE_INTERPOLATION (1ULL << 35)
80*bbecb9d1SAndroid Build Coastguard Worker #define SHADER_REQ_TEXTURE_SHADOW_LOD (1ULL << 36)
81*bbecb9d1SAndroid Build Coastguard Worker 
82*bbecb9d1SAndroid Build Coastguard Worker #define FRONT_COLOR_EMITTED (1 << 0)
83*bbecb9d1SAndroid Build Coastguard Worker #define BACK_COLOR_EMITTED  (1 << 1);
84*bbecb9d1SAndroid Build Coastguard Worker 
85*bbecb9d1SAndroid Build Coastguard Worker #define MAX_VARYING 32
86*bbecb9d1SAndroid Build Coastguard Worker 
87*bbecb9d1SAndroid Build Coastguard Worker enum vrend_sysval_uniform {
88*bbecb9d1SAndroid Build Coastguard Worker    UNIFORM_WINSYS_ADJUST_Y,
89*bbecb9d1SAndroid Build Coastguard Worker    UNIFORM_CLIP_PLANE,
90*bbecb9d1SAndroid Build Coastguard Worker    UNIFORM_ALPHA_REF_VAL,
91*bbecb9d1SAndroid Build Coastguard Worker    UNIFORM_PSTIPPLE_SAMPLER,
92*bbecb9d1SAndroid Build Coastguard Worker };
93*bbecb9d1SAndroid Build Coastguard Worker 
94*bbecb9d1SAndroid Build Coastguard Worker enum vec_type {
95*bbecb9d1SAndroid Build Coastguard Worker    VEC_FLOAT = 0,
96*bbecb9d1SAndroid Build Coastguard Worker    VEC_INT = 1,
97*bbecb9d1SAndroid Build Coastguard Worker    VEC_UINT = 2
98*bbecb9d1SAndroid Build Coastguard Worker };
99*bbecb9d1SAndroid Build Coastguard Worker 
100*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_sampler {
101*bbecb9d1SAndroid Build Coastguard Worker    int tgsi_sampler_type;
102*bbecb9d1SAndroid Build Coastguard Worker    enum tgsi_return_type tgsi_sampler_return;
103*bbecb9d1SAndroid Build Coastguard Worker };
104*bbecb9d1SAndroid Build Coastguard Worker 
105*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_table {
106*bbecb9d1SAndroid Build Coastguard Worker    uint64_t key;
107*bbecb9d1SAndroid Build Coastguard Worker    const char *string;
108*bbecb9d1SAndroid Build Coastguard Worker };
109*bbecb9d1SAndroid Build Coastguard Worker 
110*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_image {
111*bbecb9d1SAndroid Build Coastguard Worker    struct tgsi_declaration_image decl;
112*bbecb9d1SAndroid Build Coastguard Worker    enum tgsi_return_type image_return;
113*bbecb9d1SAndroid Build Coastguard Worker    bool vflag;
114*bbecb9d1SAndroid Build Coastguard Worker    bool coherent;
115*bbecb9d1SAndroid Build Coastguard Worker };
116*bbecb9d1SAndroid Build Coastguard Worker 
117*bbecb9d1SAndroid Build Coastguard Worker #define MAX_IMMEDIATE 1024
118*bbecb9d1SAndroid Build Coastguard Worker struct immed {
119*bbecb9d1SAndroid Build Coastguard Worker    enum tgsi_imm_type type;
120*bbecb9d1SAndroid Build Coastguard Worker    union imm {
121*bbecb9d1SAndroid Build Coastguard Worker       uint32_t ui;
122*bbecb9d1SAndroid Build Coastguard Worker       int32_t i;
123*bbecb9d1SAndroid Build Coastguard Worker       float f;
124*bbecb9d1SAndroid Build Coastguard Worker    } val[4];
125*bbecb9d1SAndroid Build Coastguard Worker };
126*bbecb9d1SAndroid Build Coastguard Worker 
127*bbecb9d1SAndroid Build Coastguard Worker struct vrend_temp_range {
128*bbecb9d1SAndroid Build Coastguard Worker    int first;
129*bbecb9d1SAndroid Build Coastguard Worker    int last;
130*bbecb9d1SAndroid Build Coastguard Worker    int array_id;
131*bbecb9d1SAndroid Build Coastguard Worker    bool precise_result;
132*bbecb9d1SAndroid Build Coastguard Worker };
133*bbecb9d1SAndroid Build Coastguard Worker 
134*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_io {
135*bbecb9d1SAndroid Build Coastguard Worker    char glsl_name[128];
136*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_shader_io *overlapping_array;
137*bbecb9d1SAndroid Build Coastguard Worker    unsigned sid : 16;
138*bbecb9d1SAndroid Build Coastguard Worker    unsigned first : 16;
139*bbecb9d1SAndroid Build Coastguard Worker    unsigned last : 16;
140*bbecb9d1SAndroid Build Coastguard Worker    unsigned array_id : 10;
141*bbecb9d1SAndroid Build Coastguard Worker    enum tgsi_interpolate_mode interpolate : 4;
142*bbecb9d1SAndroid Build Coastguard Worker    enum tgsi_interpolate_loc location : 2;
143*bbecb9d1SAndroid Build Coastguard Worker 
144*bbecb9d1SAndroid Build Coastguard Worker    unsigned array_offset : 8;
145*bbecb9d1SAndroid Build Coastguard Worker    enum tgsi_semantic name : 8;
146*bbecb9d1SAndroid Build Coastguard Worker    unsigned stream : 2;
147*bbecb9d1SAndroid Build Coastguard Worker    unsigned usage_mask : 4;
148*bbecb9d1SAndroid Build Coastguard Worker    enum vec_type type : 2;
149*bbecb9d1SAndroid Build Coastguard Worker    unsigned num_components : 3;
150*bbecb9d1SAndroid Build Coastguard Worker 
151*bbecb9d1SAndroid Build Coastguard Worker    bool invariant : 1;
152*bbecb9d1SAndroid Build Coastguard Worker    bool precise : 1;
153*bbecb9d1SAndroid Build Coastguard Worker    bool glsl_predefined_no_emit : 1;
154*bbecb9d1SAndroid Build Coastguard Worker    bool glsl_no_index : 1;
155*bbecb9d1SAndroid Build Coastguard Worker    bool glsl_gl_block : 1;
156*bbecb9d1SAndroid Build Coastguard Worker    bool override_no_wm : 1;
157*bbecb9d1SAndroid Build Coastguard Worker    bool is_int : 1;
158*bbecb9d1SAndroid Build Coastguard Worker    bool fbfetch_used : 1;
159*bbecb9d1SAndroid Build Coastguard Worker    bool needs_override : 1;
160*bbecb9d1SAndroid Build Coastguard Worker };
161*bbecb9d1SAndroid Build Coastguard Worker 
162*bbecb9d1SAndroid Build Coastguard Worker struct vrend_io_range {
163*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_shader_io io;
164*bbecb9d1SAndroid Build Coastguard Worker    bool used;
165*bbecb9d1SAndroid Build Coastguard Worker };
166*bbecb9d1SAndroid Build Coastguard Worker 
167*bbecb9d1SAndroid Build Coastguard Worker struct vrend_glsl_strbufs {
168*bbecb9d1SAndroid Build Coastguard Worker    int indent_level;
169*bbecb9d1SAndroid Build Coastguard Worker    uint8_t required_sysval_uniform_decls;
170*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_strbuf glsl_main;
171*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_strbuf glsl_hdr;
172*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_strbuf glsl_ver_ext;
173*bbecb9d1SAndroid Build Coastguard Worker };
174*bbecb9d1SAndroid Build Coastguard Worker 
175*bbecb9d1SAndroid Build Coastguard Worker struct vrend_interface_bits {
176*bbecb9d1SAndroid Build Coastguard Worker    uint64_t outputs_expected_mask;
177*bbecb9d1SAndroid Build Coastguard Worker    uint64_t inputs_emitted_mask;
178*bbecb9d1SAndroid Build Coastguard Worker    uint64_t outputs_emitted_mask;
179*bbecb9d1SAndroid Build Coastguard Worker };
180*bbecb9d1SAndroid Build Coastguard Worker 
181*bbecb9d1SAndroid Build Coastguard Worker struct vrend_generic_ios {
182*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_interface_bits match;
183*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_io_range input_range;
184*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_io_range output_range;
185*bbecb9d1SAndroid Build Coastguard Worker };
186*bbecb9d1SAndroid Build Coastguard Worker 
187*bbecb9d1SAndroid Build Coastguard Worker struct vrend_texcoord_ios {
188*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_interface_bits match;
189*bbecb9d1SAndroid Build Coastguard Worker };
190*bbecb9d1SAndroid Build Coastguard Worker 
191*bbecb9d1SAndroid Build Coastguard Worker struct vrend_patch_ios {
192*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_io_range input_range;
193*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_io_range output_range;
194*bbecb9d1SAndroid Build Coastguard Worker };
195*bbecb9d1SAndroid Build Coastguard Worker 
196*bbecb9d1SAndroid Build Coastguard Worker struct dump_ctx {
197*bbecb9d1SAndroid Build Coastguard Worker    struct tgsi_iterate_context iter;
198*bbecb9d1SAndroid Build Coastguard Worker    const struct vrend_shader_cfg *cfg;
199*bbecb9d1SAndroid Build Coastguard Worker    struct tgsi_shader_info info;
200*bbecb9d1SAndroid Build Coastguard Worker    enum tgsi_processor_type prog_type;
201*bbecb9d1SAndroid Build Coastguard Worker    int size;
202*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_glsl_strbufs glsl_strbufs;
203*bbecb9d1SAndroid Build Coastguard Worker    uint instno;
204*bbecb9d1SAndroid Build Coastguard Worker 
205*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_strbuf src_bufs[4];
206*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_strbuf dst_bufs[3];
207*bbecb9d1SAndroid Build Coastguard Worker 
208*bbecb9d1SAndroid Build Coastguard Worker    uint32_t num_interps;
209*bbecb9d1SAndroid Build Coastguard Worker    uint32_t num_inputs;
210*bbecb9d1SAndroid Build Coastguard Worker    uint32_t attrib_input_mask;
211*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_shader_io inputs[64];
212*bbecb9d1SAndroid Build Coastguard Worker    uint32_t num_outputs;
213*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_shader_io outputs[64];
214*bbecb9d1SAndroid Build Coastguard Worker    uint8_t front_back_color_emitted_flags[64];
215*bbecb9d1SAndroid Build Coastguard Worker    uint32_t num_system_values;
216*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_shader_io system_values[32];
217*bbecb9d1SAndroid Build Coastguard Worker 
218*bbecb9d1SAndroid Build Coastguard Worker    bool guest_sent_io_arrays;
219*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_texcoord_ios texcoord_ios;
220*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_generic_ios generic_ios;
221*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_patch_ios patch_ios;
222*bbecb9d1SAndroid Build Coastguard Worker 
223*bbecb9d1SAndroid Build Coastguard Worker    uint32_t num_temp_ranges;
224*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_temp_range *temp_ranges;
225*bbecb9d1SAndroid Build Coastguard Worker 
226*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_shader_sampler samplers[32];
227*bbecb9d1SAndroid Build Coastguard Worker    uint32_t samplers_used;
228*bbecb9d1SAndroid Build Coastguard Worker 
229*bbecb9d1SAndroid Build Coastguard Worker    uint32_t ssbo_used_mask;
230*bbecb9d1SAndroid Build Coastguard Worker    uint32_t ssbo_atomic_mask;
231*bbecb9d1SAndroid Build Coastguard Worker    uint32_t ssbo_array_base;
232*bbecb9d1SAndroid Build Coastguard Worker    uint32_t ssbo_atomic_array_base;
233*bbecb9d1SAndroid Build Coastguard Worker    uint32_t ssbo_integer_mask;
234*bbecb9d1SAndroid Build Coastguard Worker    uint8_t ssbo_memory_qualifier[32];
235*bbecb9d1SAndroid Build Coastguard Worker 
236*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_shader_image images[32];
237*bbecb9d1SAndroid Build Coastguard Worker    uint32_t images_used_mask;
238*bbecb9d1SAndroid Build Coastguard Worker 
239*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_array *image_arrays;
240*bbecb9d1SAndroid Build Coastguard Worker    uint32_t num_image_arrays;
241*bbecb9d1SAndroid Build Coastguard Worker 
242*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_array *sampler_arrays;
243*bbecb9d1SAndroid Build Coastguard Worker    uint32_t num_sampler_arrays;
244*bbecb9d1SAndroid Build Coastguard Worker 
245*bbecb9d1SAndroid Build Coastguard Worker    uint32_t fog_input_mask;
246*bbecb9d1SAndroid Build Coastguard Worker    uint32_t fog_output_mask;
247*bbecb9d1SAndroid Build Coastguard Worker 
248*bbecb9d1SAndroid Build Coastguard Worker    int num_consts;
249*bbecb9d1SAndroid Build Coastguard Worker    int num_imm;
250*bbecb9d1SAndroid Build Coastguard Worker    struct immed imm[MAX_IMMEDIATE];
251*bbecb9d1SAndroid Build Coastguard Worker 
252*bbecb9d1SAndroid Build Coastguard Worker    uint32_t req_local_mem;
253*bbecb9d1SAndroid Build Coastguard Worker    bool integer_memory;
254*bbecb9d1SAndroid Build Coastguard Worker 
255*bbecb9d1SAndroid Build Coastguard Worker    uint32_t ubo_base;
256*bbecb9d1SAndroid Build Coastguard Worker    uint32_t ubo_used_mask;
257*bbecb9d1SAndroid Build Coastguard Worker    int ubo_sizes[32];
258*bbecb9d1SAndroid Build Coastguard Worker    uint32_t num_address;
259*bbecb9d1SAndroid Build Coastguard Worker 
260*bbecb9d1SAndroid Build Coastguard Worker    uint32_t num_abo;
261*bbecb9d1SAndroid Build Coastguard Worker    int abo_idx[32];
262*bbecb9d1SAndroid Build Coastguard Worker    int abo_sizes[32];
263*bbecb9d1SAndroid Build Coastguard Worker    int abo_offsets[32];
264*bbecb9d1SAndroid Build Coastguard Worker 
265*bbecb9d1SAndroid Build Coastguard Worker    uint64_t shader_req_bits;
266*bbecb9d1SAndroid Build Coastguard Worker    uint64_t patches_emitted_mask;
267*bbecb9d1SAndroid Build Coastguard Worker 
268*bbecb9d1SAndroid Build Coastguard Worker    struct pipe_stream_output_info *so;
269*bbecb9d1SAndroid Build Coastguard Worker    char **so_names;
270*bbecb9d1SAndroid Build Coastguard Worker    bool write_so_outputs[PIPE_MAX_SO_OUTPUTS];
271*bbecb9d1SAndroid Build Coastguard Worker    bool write_all_cbufs;
272*bbecb9d1SAndroid Build Coastguard Worker    uint32_t shadow_samp_mask;
273*bbecb9d1SAndroid Build Coastguard Worker 
274*bbecb9d1SAndroid Build Coastguard Worker    bool fs_lower_left_origin, fs_integer_pixel_center;
275*bbecb9d1SAndroid Build Coastguard Worker    int fs_depth_layout;
276*bbecb9d1SAndroid Build Coastguard Worker    uint32_t fs_blend_equation_advanced;
277*bbecb9d1SAndroid Build Coastguard Worker 
278*bbecb9d1SAndroid Build Coastguard Worker    bool separable_program;
279*bbecb9d1SAndroid Build Coastguard Worker 
280*bbecb9d1SAndroid Build Coastguard Worker    int gs_in_prim, gs_out_prim, gs_max_out_verts;
281*bbecb9d1SAndroid Build Coastguard Worker    int gs_num_invocations;
282*bbecb9d1SAndroid Build Coastguard Worker 
283*bbecb9d1SAndroid Build Coastguard Worker    const struct vrend_shader_key *key;
284*bbecb9d1SAndroid Build Coastguard Worker    int num_in_clip_dist;
285*bbecb9d1SAndroid Build Coastguard Worker    int num_out_clip_dist;
286*bbecb9d1SAndroid Build Coastguard Worker    int fs_uses_clipdist_input;
287*bbecb9d1SAndroid Build Coastguard Worker    int glsl_ver_required;
288*bbecb9d1SAndroid Build Coastguard Worker    int color_in_mask;
289*bbecb9d1SAndroid Build Coastguard Worker    int color_out_mask;
290*bbecb9d1SAndroid Build Coastguard Worker    /* only used when cull is enabled */
291*bbecb9d1SAndroid Build Coastguard Worker    uint8_t num_cull_dist_prop, num_clip_dist_prop;
292*bbecb9d1SAndroid Build Coastguard Worker    bool has_pervertex;
293*bbecb9d1SAndroid Build Coastguard Worker    bool front_face_emitted;
294*bbecb9d1SAndroid Build Coastguard Worker 
295*bbecb9d1SAndroid Build Coastguard Worker    bool has_clipvertex;
296*bbecb9d1SAndroid Build Coastguard Worker    bool has_clipvertex_so;
297*bbecb9d1SAndroid Build Coastguard Worker    bool write_mul_utemp;
298*bbecb9d1SAndroid Build Coastguard Worker    bool write_mul_itemp;
299*bbecb9d1SAndroid Build Coastguard Worker    bool has_sample_input;
300*bbecb9d1SAndroid Build Coastguard Worker    bool has_noperspective;
301*bbecb9d1SAndroid Build Coastguard Worker    bool early_depth_stencil;
302*bbecb9d1SAndroid Build Coastguard Worker    bool has_file_memory;
303*bbecb9d1SAndroid Build Coastguard Worker    bool force_color_two_side;
304*bbecb9d1SAndroid Build Coastguard Worker    bool gles_use_tex_query_level;
305*bbecb9d1SAndroid Build Coastguard Worker    bool has_pointsize_input;
306*bbecb9d1SAndroid Build Coastguard Worker    bool has_pointsize_output;
307*bbecb9d1SAndroid Build Coastguard Worker 
308*bbecb9d1SAndroid Build Coastguard Worker    bool has_input_arrays;
309*bbecb9d1SAndroid Build Coastguard Worker    bool has_output_arrays;
310*bbecb9d1SAndroid Build Coastguard Worker 
311*bbecb9d1SAndroid Build Coastguard Worker    int tcs_vertices_out;
312*bbecb9d1SAndroid Build Coastguard Worker    int tes_prim_mode;
313*bbecb9d1SAndroid Build Coastguard Worker    int tes_spacing;
314*bbecb9d1SAndroid Build Coastguard Worker    int tes_vertex_order;
315*bbecb9d1SAndroid Build Coastguard Worker    int tes_point_mode;
316*bbecb9d1SAndroid Build Coastguard Worker    bool is_last_vertex_stage;
317*bbecb9d1SAndroid Build Coastguard Worker    bool require_dummy_value;
318*bbecb9d1SAndroid Build Coastguard Worker 
319*bbecb9d1SAndroid Build Coastguard Worker    uint16_t local_cs_block_size[3];
320*bbecb9d1SAndroid Build Coastguard Worker };
321*bbecb9d1SAndroid Build Coastguard Worker 
322*bbecb9d1SAndroid Build Coastguard Worker static const struct vrend_shader_table shader_req_table[] = {
323*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_SAMPLER_RECT, "ARB_texture_rectangle" },
324*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_CUBE_ARRAY, "ARB_texture_cube_map_array" },
325*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_INTS, "ARB_shader_bit_encoding" },
326*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_SAMPLER_MS, "ARB_texture_multisample" },
327*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_INSTANCE_ID, "ARB_draw_instanced" },
328*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_LODQ, "ARB_texture_query_lod" },
329*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_TXQ_LEVELS, "ARB_texture_query_levels" },
330*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_TG4, "ARB_texture_gather" },
331*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_VIEWPORT_IDX, "ARB_viewport_array" },
332*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_STENCIL_EXPORT, "ARB_shader_stencil_export" },
333*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_LAYER, "ARB_fragment_layer_viewport" },
334*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_SAMPLE_SHADING, "ARB_sample_shading" },
335*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_GPU_SHADER5, "ARB_gpu_shader5" },
336*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_DERIVATIVE_CONTROL, "ARB_derivative_control" },
337*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_FP64, "ARB_gpu_shader_fp64" },
338*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_IMAGE_LOAD_STORE, "ARB_shader_image_load_store" },
339*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_ES31_COMPAT, "ARB_ES3_1_compatibility" },
340*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_IMAGE_SIZE, "ARB_shader_image_size" },
341*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_TXQS, "ARB_shader_texture_image_samples" },
342*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_FBFETCH, "EXT_shader_framebuffer_fetch" },
343*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_SHADER_CLOCK, "ARB_shader_clock" },
344*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_SHADER_INTEGER_FUNC, "MESA_shader_integer_functions" },
345*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_SHADER_ATOMIC_FLOAT, "NV_shader_atomic_float"},
346*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_CONSERVATIVE_DEPTH, "ARB_conservative_depth"},
347*bbecb9d1SAndroid Build Coastguard Worker     {SHADER_REQ_BLEND_EQUATION_ADVANCED, "KHR_blend_equation_advanced"},
348*bbecb9d1SAndroid Build Coastguard Worker     { SHADER_REQ_TEXTURE_SHADOW_LOD, "EXT_texture_shadow_lod"},
349*bbecb9d1SAndroid Build Coastguard Worker };
350*bbecb9d1SAndroid Build Coastguard Worker 
351*bbecb9d1SAndroid Build Coastguard Worker enum vrend_type_qualifier {
352*bbecb9d1SAndroid Build Coastguard Worker    TYPE_CONVERSION_NONE = 0,
353*bbecb9d1SAndroid Build Coastguard Worker    FLOAT = 1,
354*bbecb9d1SAndroid Build Coastguard Worker    VEC2 = 2,
355*bbecb9d1SAndroid Build Coastguard Worker    VEC3 = 3,
356*bbecb9d1SAndroid Build Coastguard Worker    VEC4 = 4,
357*bbecb9d1SAndroid Build Coastguard Worker    INT = 5,
358*bbecb9d1SAndroid Build Coastguard Worker    IVEC2 = 6,
359*bbecb9d1SAndroid Build Coastguard Worker    IVEC3 = 7,
360*bbecb9d1SAndroid Build Coastguard Worker    IVEC4 = 8,
361*bbecb9d1SAndroid Build Coastguard Worker    UINT = 9,
362*bbecb9d1SAndroid Build Coastguard Worker    UVEC2 = 10,
363*bbecb9d1SAndroid Build Coastguard Worker    UVEC3 = 11,
364*bbecb9d1SAndroid Build Coastguard Worker    UVEC4 = 12,
365*bbecb9d1SAndroid Build Coastguard Worker    FLOAT_BITS_TO_UINT = 13,
366*bbecb9d1SAndroid Build Coastguard Worker    UINT_BITS_TO_FLOAT = 14,
367*bbecb9d1SAndroid Build Coastguard Worker    FLOAT_BITS_TO_INT = 15,
368*bbecb9d1SAndroid Build Coastguard Worker    INT_BITS_TO_FLOAT = 16,
369*bbecb9d1SAndroid Build Coastguard Worker    DOUBLE = 17,
370*bbecb9d1SAndroid Build Coastguard Worker    DVEC2 = 18,
371*bbecb9d1SAndroid Build Coastguard Worker };
372*bbecb9d1SAndroid Build Coastguard Worker 
373*bbecb9d1SAndroid Build Coastguard Worker struct dest_info {
374*bbecb9d1SAndroid Build Coastguard Worker   enum vrend_type_qualifier dtypeprefix;
375*bbecb9d1SAndroid Build Coastguard Worker   enum vrend_type_qualifier dstconv;
376*bbecb9d1SAndroid Build Coastguard Worker   enum vrend_type_qualifier udstconv;
377*bbecb9d1SAndroid Build Coastguard Worker   enum vrend_type_qualifier idstconv;
378*bbecb9d1SAndroid Build Coastguard Worker   bool dst_override_no_wm[2];
379*bbecb9d1SAndroid Build Coastguard Worker   int32_t dest_index;
380*bbecb9d1SAndroid Build Coastguard Worker };
381*bbecb9d1SAndroid Build Coastguard Worker 
382*bbecb9d1SAndroid Build Coastguard Worker struct source_info {
383*bbecb9d1SAndroid Build Coastguard Worker    enum vrend_type_qualifier svec4;
384*bbecb9d1SAndroid Build Coastguard Worker    int32_t sreg_index;
385*bbecb9d1SAndroid Build Coastguard Worker    bool tg4_has_component;
386*bbecb9d1SAndroid Build Coastguard Worker    bool override_no_wm[3];
387*bbecb9d1SAndroid Build Coastguard Worker    bool override_no_cast[3];
388*bbecb9d1SAndroid Build Coastguard Worker    int imm_value;
389*bbecb9d1SAndroid Build Coastguard Worker };
390*bbecb9d1SAndroid Build Coastguard Worker 
391*bbecb9d1SAndroid Build Coastguard Worker static const struct vrend_shader_table conversion_table[] =
392*bbecb9d1SAndroid Build Coastguard Worker {
393*bbecb9d1SAndroid Build Coastguard Worker    {TYPE_CONVERSION_NONE, ""},
394*bbecb9d1SAndroid Build Coastguard Worker    {FLOAT, "float"},
395*bbecb9d1SAndroid Build Coastguard Worker    {VEC2, "vec2"},
396*bbecb9d1SAndroid Build Coastguard Worker    {VEC3, "vec3"},
397*bbecb9d1SAndroid Build Coastguard Worker    {VEC4, "vec4"},
398*bbecb9d1SAndroid Build Coastguard Worker    {INT, "int"},
399*bbecb9d1SAndroid Build Coastguard Worker    {IVEC2, "ivec2"},
400*bbecb9d1SAndroid Build Coastguard Worker    {IVEC3, "ivec3"},
401*bbecb9d1SAndroid Build Coastguard Worker    {IVEC4, "ivec4"},
402*bbecb9d1SAndroid Build Coastguard Worker    {UINT, "uint"},
403*bbecb9d1SAndroid Build Coastguard Worker    {UVEC2, "uvec2"},
404*bbecb9d1SAndroid Build Coastguard Worker    {UVEC3, "uvec3"},
405*bbecb9d1SAndroid Build Coastguard Worker    {UVEC4, "uvec4"},
406*bbecb9d1SAndroid Build Coastguard Worker    {FLOAT_BITS_TO_UINT, "floatBitsToUint"},
407*bbecb9d1SAndroid Build Coastguard Worker    {UINT_BITS_TO_FLOAT, "uintBitsToFloat"},
408*bbecb9d1SAndroid Build Coastguard Worker    {FLOAT_BITS_TO_INT, "floatBitsToInt"},
409*bbecb9d1SAndroid Build Coastguard Worker    {INT_BITS_TO_FLOAT, "intBitsToFloat"},
410*bbecb9d1SAndroid Build Coastguard Worker    {DOUBLE, "double"},
411*bbecb9d1SAndroid Build Coastguard Worker    {DVEC2, "dvec2"},
412*bbecb9d1SAndroid Build Coastguard Worker };
413*bbecb9d1SAndroid Build Coastguard Worker 
414*bbecb9d1SAndroid Build Coastguard Worker enum io_type {
415*bbecb9d1SAndroid Build Coastguard Worker    io_in,
416*bbecb9d1SAndroid Build Coastguard Worker    io_out
417*bbecb9d1SAndroid Build Coastguard Worker };
418*bbecb9d1SAndroid Build Coastguard Worker 
419*bbecb9d1SAndroid Build Coastguard Worker enum io_decl_type {
420*bbecb9d1SAndroid Build Coastguard Worker    decl_plain,
421*bbecb9d1SAndroid Build Coastguard Worker    decl_block
422*bbecb9d1SAndroid Build Coastguard Worker };
423*bbecb9d1SAndroid Build Coastguard Worker 
424*bbecb9d1SAndroid Build Coastguard Worker static
425*bbecb9d1SAndroid Build Coastguard Worker void vrend_shader_write_io_as_src(struct vrend_strbuf *buf,
426*bbecb9d1SAndroid Build Coastguard Worker                                   const  char *arrayname,
427*bbecb9d1SAndroid Build Coastguard Worker                                   const struct vrend_shader_io *io,
428*bbecb9d1SAndroid Build Coastguard Worker                                   const struct tgsi_full_src_register *src,
429*bbecb9d1SAndroid Build Coastguard Worker                                   enum io_decl_type decl_type);
430*bbecb9d1SAndroid Build Coastguard Worker 
431*bbecb9d1SAndroid Build Coastguard Worker static
432*bbecb9d1SAndroid Build Coastguard Worker void vrend_shader_write_io_as_dst(struct vrend_strbuf *buf,
433*bbecb9d1SAndroid Build Coastguard Worker                                   const  char *arrayname,
434*bbecb9d1SAndroid Build Coastguard Worker                                   const struct vrend_shader_io *io,
435*bbecb9d1SAndroid Build Coastguard Worker                                   const struct tgsi_full_dst_register *src,
436*bbecb9d1SAndroid Build Coastguard Worker                                   enum io_decl_type decl_type);
437*bbecb9d1SAndroid Build Coastguard Worker 
438*bbecb9d1SAndroid Build Coastguard Worker /* We prefer arrays of arrays, but if this is not available then TCS, GEOM, and TES
439*bbecb9d1SAndroid Build Coastguard Worker  * inputs must be blocks, but FS input should not because interpolateAt* doesn't
440*bbecb9d1SAndroid Build Coastguard Worker  * support dereferencing block members. */
prefer_generic_io_block(const struct dump_ctx * ctx,enum io_type io)441*bbecb9d1SAndroid Build Coastguard Worker static inline bool prefer_generic_io_block(const struct dump_ctx *ctx, enum io_type io)
442*bbecb9d1SAndroid Build Coastguard Worker {
443*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->cfg->has_arrays_of_arrays && !ctx->cfg->use_gles)
444*bbecb9d1SAndroid Build Coastguard Worker       return false;
445*bbecb9d1SAndroid Build Coastguard Worker 
446*bbecb9d1SAndroid Build Coastguard Worker    switch (ctx->prog_type) {
447*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_FRAGMENT:
448*bbecb9d1SAndroid Build Coastguard Worker       return false;
449*bbecb9d1SAndroid Build Coastguard Worker 
450*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_TESS_CTRL:
451*bbecb9d1SAndroid Build Coastguard Worker       return true;
452*bbecb9d1SAndroid Build Coastguard Worker 
453*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_TESS_EVAL:
454*bbecb9d1SAndroid Build Coastguard Worker       return io == io_in ?  true : (ctx->key->gs_present ? true : false);
455*bbecb9d1SAndroid Build Coastguard Worker 
456*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_GEOMETRY:
457*bbecb9d1SAndroid Build Coastguard Worker       return io == io_in;
458*bbecb9d1SAndroid Build Coastguard Worker 
459*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_VERTEX:
460*bbecb9d1SAndroid Build Coastguard Worker       if (io == io_in)
461*bbecb9d1SAndroid Build Coastguard Worker          return false;
462*bbecb9d1SAndroid Build Coastguard Worker       return (ctx->key->gs_present || ctx->key->tes_present);
463*bbecb9d1SAndroid Build Coastguard Worker 
464*bbecb9d1SAndroid Build Coastguard Worker    default:
465*bbecb9d1SAndroid Build Coastguard Worker       return false;
466*bbecb9d1SAndroid Build Coastguard Worker    }
467*bbecb9d1SAndroid Build Coastguard Worker }
468*bbecb9d1SAndroid Build Coastguard Worker 
get_string(enum vrend_type_qualifier key)469*bbecb9d1SAndroid Build Coastguard Worker static inline const char *get_string(enum vrend_type_qualifier key)
470*bbecb9d1SAndroid Build Coastguard Worker {
471*bbecb9d1SAndroid Build Coastguard Worker    if (key >= ARRAY_SIZE(conversion_table)) {
472*bbecb9d1SAndroid Build Coastguard Worker       printf("Unable to find the correct conversion\n");
473*bbecb9d1SAndroid Build Coastguard Worker       return conversion_table[TYPE_CONVERSION_NONE].string;
474*bbecb9d1SAndroid Build Coastguard Worker    }
475*bbecb9d1SAndroid Build Coastguard Worker 
476*bbecb9d1SAndroid Build Coastguard Worker    return conversion_table[key].string;
477*bbecb9d1SAndroid Build Coastguard Worker }
478*bbecb9d1SAndroid Build Coastguard Worker 
get_wm_string(unsigned wm)479*bbecb9d1SAndroid Build Coastguard Worker static inline const char *get_wm_string(unsigned wm)
480*bbecb9d1SAndroid Build Coastguard Worker {
481*bbecb9d1SAndroid Build Coastguard Worker    switch(wm) {
482*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_WRITEMASK_NONE:
483*bbecb9d1SAndroid Build Coastguard Worker       return "";
484*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_WRITEMASK_X:
485*bbecb9d1SAndroid Build Coastguard Worker       return ".x";
486*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_WRITEMASK_XY:
487*bbecb9d1SAndroid Build Coastguard Worker       return ".xy";
488*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_WRITEMASK_XYZ:
489*bbecb9d1SAndroid Build Coastguard Worker       return ".xyz";
490*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_WRITEMASK_W:
491*bbecb9d1SAndroid Build Coastguard Worker       return ".w";
492*bbecb9d1SAndroid Build Coastguard Worker    default:
493*bbecb9d1SAndroid Build Coastguard Worker       printf("Unable to unknown writemask\n");
494*bbecb9d1SAndroid Build Coastguard Worker       return "";
495*bbecb9d1SAndroid Build Coastguard Worker    }
496*bbecb9d1SAndroid Build Coastguard Worker }
497*bbecb9d1SAndroid Build Coastguard Worker 
get_swizzle_string(uint8_t swizzle)498*bbecb9d1SAndroid Build Coastguard Worker static inline const char *get_swizzle_string(uint8_t swizzle)
499*bbecb9d1SAndroid Build Coastguard Worker {
500*bbecb9d1SAndroid Build Coastguard Worker    switch (swizzle) {
501*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_SWIZZLE_RED: return ".x";
502*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_SWIZZLE_GREEN: return ".y";
503*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_SWIZZLE_BLUE: return ".z";
504*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_SWIZZLE_ALPHA: return ".w";
505*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_SWIZZLE_ZERO:
506*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_SWIZZLE_ONE: return ".0";
507*bbecb9d1SAndroid Build Coastguard Worker    default:
508*bbecb9d1SAndroid Build Coastguard Worker       assert(0);
509*bbecb9d1SAndroid Build Coastguard Worker       return "";
510*bbecb9d1SAndroid Build Coastguard Worker    }
511*bbecb9d1SAndroid Build Coastguard Worker }
512*bbecb9d1SAndroid Build Coastguard Worker 
513*bbecb9d1SAndroid Build Coastguard Worker const char *get_internalformat_string(int virgl_format, enum tgsi_return_type *stype);
514*bbecb9d1SAndroid Build Coastguard Worker 
tgsi_proc_to_prefix(int shader_type)515*bbecb9d1SAndroid Build Coastguard Worker static inline const char *tgsi_proc_to_prefix(int shader_type)
516*bbecb9d1SAndroid Build Coastguard Worker {
517*bbecb9d1SAndroid Build Coastguard Worker    switch (shader_type) {
518*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_VERTEX: return "vs";
519*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_FRAGMENT: return "fs";
520*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_GEOMETRY: return "gs";
521*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_TESS_CTRL: return "tc";
522*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_TESS_EVAL: return "te";
523*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_COMPUTE: return "cs";
524*bbecb9d1SAndroid Build Coastguard Worker    default:
525*bbecb9d1SAndroid Build Coastguard Worker       return NULL;
526*bbecb9d1SAndroid Build Coastguard Worker    };
527*bbecb9d1SAndroid Build Coastguard Worker }
528*bbecb9d1SAndroid Build Coastguard Worker 
prim_to_name(int prim)529*bbecb9d1SAndroid Build Coastguard Worker static inline const char *prim_to_name(int prim)
530*bbecb9d1SAndroid Build Coastguard Worker {
531*bbecb9d1SAndroid Build Coastguard Worker    switch (prim) {
532*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_POINTS: return "points";
533*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_LINES: return "lines";
534*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_LINE_STRIP: return "line_strip";
535*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_LINES_ADJACENCY: return "lines_adjacency";
536*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_TRIANGLES: return "triangles";
537*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_TRIANGLE_STRIP: return "triangle_strip";
538*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_TRIANGLES_ADJACENCY: return "triangles_adjacency";
539*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_QUADS: return "quads";
540*bbecb9d1SAndroid Build Coastguard Worker    default: return "UNKNOWN";
541*bbecb9d1SAndroid Build Coastguard Worker    };
542*bbecb9d1SAndroid Build Coastguard Worker }
543*bbecb9d1SAndroid Build Coastguard Worker 
prim_to_tes_name(int prim)544*bbecb9d1SAndroid Build Coastguard Worker static inline const char *prim_to_tes_name(int prim)
545*bbecb9d1SAndroid Build Coastguard Worker {
546*bbecb9d1SAndroid Build Coastguard Worker    switch (prim) {
547*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_QUADS: return "quads";
548*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_TRIANGLES: return "triangles";
549*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_LINES: return "isolines";
550*bbecb9d1SAndroid Build Coastguard Worker    default: return "UNKNOWN";
551*bbecb9d1SAndroid Build Coastguard Worker    }
552*bbecb9d1SAndroid Build Coastguard Worker }
553*bbecb9d1SAndroid Build Coastguard Worker 
blend_to_name(enum gl_advanced_blend_mode blend)554*bbecb9d1SAndroid Build Coastguard Worker static inline const char *blend_to_name(enum gl_advanced_blend_mode blend)
555*bbecb9d1SAndroid Build Coastguard Worker {
556*bbecb9d1SAndroid Build Coastguard Worker    switch (blend) {
557*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_MULTIPLY: return "multiply";
558*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_SCREEN: return "screen";
559*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_OVERLAY: return "overlay";
560*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_DARKEN: return "darken";
561*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_LIGHTEN: return "lighten";
562*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_COLORDODGE: return "colordodge";
563*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_COLORBURN: return "colorburn";
564*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_HARDLIGHT: return "hardlight";
565*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_SOFTLIGHT: return "softlight";
566*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_DIFFERENCE: return "difference";
567*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_EXCLUSION: return "exclusion";
568*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_HSL_HUE: return "hsl_hue";
569*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_HSL_SATURATION: return "hsl_saturation";
570*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_HSL_COLOR: return "hsl_color";
571*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_HSL_LUMINOSITY: return "hsl_luminosity";
572*bbecb9d1SAndroid Build Coastguard Worker    case BLEND_ALL: return "all_equations";
573*bbecb9d1SAndroid Build Coastguard Worker    default: return "UNKNOWN";
574*bbecb9d1SAndroid Build Coastguard Worker    };
575*bbecb9d1SAndroid Build Coastguard Worker }
576*bbecb9d1SAndroid Build Coastguard Worker 
get_spacing_string(int spacing)577*bbecb9d1SAndroid Build Coastguard Worker static const char *get_spacing_string(int spacing)
578*bbecb9d1SAndroid Build Coastguard Worker {
579*bbecb9d1SAndroid Build Coastguard Worker    switch (spacing) {
580*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_TESS_SPACING_FRACTIONAL_ODD:
581*bbecb9d1SAndroid Build Coastguard Worker       return "fractional_odd_spacing";
582*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_TESS_SPACING_FRACTIONAL_EVEN:
583*bbecb9d1SAndroid Build Coastguard Worker       return "fractional_even_spacing";
584*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_TESS_SPACING_EQUAL:
585*bbecb9d1SAndroid Build Coastguard Worker    default:
586*bbecb9d1SAndroid Build Coastguard Worker       return "equal_spacing";
587*bbecb9d1SAndroid Build Coastguard Worker    }
588*bbecb9d1SAndroid Build Coastguard Worker }
589*bbecb9d1SAndroid Build Coastguard Worker 
gs_input_prim_to_size(int prim)590*bbecb9d1SAndroid Build Coastguard Worker static inline int gs_input_prim_to_size(int prim)
591*bbecb9d1SAndroid Build Coastguard Worker {
592*bbecb9d1SAndroid Build Coastguard Worker    switch (prim) {
593*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_POINTS: return 1;
594*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_LINES: return 2;
595*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_LINES_ADJACENCY: return 4;
596*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_TRIANGLES: return 3;
597*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_PRIM_TRIANGLES_ADJACENCY: return 6;
598*bbecb9d1SAndroid Build Coastguard Worker    default: return -1;
599*bbecb9d1SAndroid Build Coastguard Worker    };
600*bbecb9d1SAndroid Build Coastguard Worker }
601*bbecb9d1SAndroid Build Coastguard Worker 
fs_emit_layout(const struct dump_ctx * ctx)602*bbecb9d1SAndroid Build Coastguard Worker static inline bool fs_emit_layout(const struct dump_ctx *ctx)
603*bbecb9d1SAndroid Build Coastguard Worker {
604*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->fs_integer_pixel_center)
605*bbecb9d1SAndroid Build Coastguard Worker       return true;
606*bbecb9d1SAndroid Build Coastguard Worker 
607*bbecb9d1SAndroid Build Coastguard Worker    /* if fs_lower_left_origin is 0 and lower_left_origin is 0 - emit origin_upper_left,
608*bbecb9d1SAndroid Build Coastguard Worker       if fs_lower_left_origin is 0 and lower_left_origin is 1 - emit nothing (lower)
609*bbecb9d1SAndroid Build Coastguard Worker       if fs_lower_left_origin is 1 and lower_left_origin is 0 - emit nothing (lower)
610*bbecb9d1SAndroid Build Coastguard Worker       if fs_lower_left_origin is 1 and lower_left_origin is 1 - emit origin_upper_left */
611*bbecb9d1SAndroid Build Coastguard Worker    return ctx->fs_lower_left_origin == ctx->key->fs.lower_left_origin;
612*bbecb9d1SAndroid Build Coastguard Worker }
613*bbecb9d1SAndroid Build Coastguard Worker 
get_stage_input_name_prefix(const struct dump_ctx * ctx,int processor)614*bbecb9d1SAndroid Build Coastguard Worker static const char *get_stage_input_name_prefix(const struct dump_ctx *ctx, int processor)
615*bbecb9d1SAndroid Build Coastguard Worker {
616*bbecb9d1SAndroid Build Coastguard Worker    const char *name_prefix;
617*bbecb9d1SAndroid Build Coastguard Worker    switch (processor) {
618*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_FRAGMENT:
619*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->key->gs_present)
620*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gso";
621*bbecb9d1SAndroid Build Coastguard Worker       else if (ctx->key->tes_present)
622*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "teo";
623*bbecb9d1SAndroid Build Coastguard Worker       else
624*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "vso";
625*bbecb9d1SAndroid Build Coastguard Worker       break;
626*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_GEOMETRY:
627*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->key->tes_present)
628*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "teo";
629*bbecb9d1SAndroid Build Coastguard Worker       else
630*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "vso";
631*bbecb9d1SAndroid Build Coastguard Worker       break;
632*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_TESS_EVAL:
633*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->key->tcs_present)
634*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "tco";
635*bbecb9d1SAndroid Build Coastguard Worker       else
636*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "vso";
637*bbecb9d1SAndroid Build Coastguard Worker       break;
638*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_TESS_CTRL:
639*bbecb9d1SAndroid Build Coastguard Worker        name_prefix = "vso";
640*bbecb9d1SAndroid Build Coastguard Worker        break;
641*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_VERTEX:
642*bbecb9d1SAndroid Build Coastguard Worker    default:
643*bbecb9d1SAndroid Build Coastguard Worker       name_prefix = "in";
644*bbecb9d1SAndroid Build Coastguard Worker       break;
645*bbecb9d1SAndroid Build Coastguard Worker    }
646*bbecb9d1SAndroid Build Coastguard Worker    return name_prefix;
647*bbecb9d1SAndroid Build Coastguard Worker }
648*bbecb9d1SAndroid Build Coastguard Worker 
get_stage_output_name_prefix(int processor)649*bbecb9d1SAndroid Build Coastguard Worker static const char *get_stage_output_name_prefix(int processor)
650*bbecb9d1SAndroid Build Coastguard Worker {
651*bbecb9d1SAndroid Build Coastguard Worker    const char *name_prefix;
652*bbecb9d1SAndroid Build Coastguard Worker    switch (processor) {
653*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_FRAGMENT:
654*bbecb9d1SAndroid Build Coastguard Worker       name_prefix = "fsout";
655*bbecb9d1SAndroid Build Coastguard Worker       break;
656*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_GEOMETRY:
657*bbecb9d1SAndroid Build Coastguard Worker       name_prefix = "gso";
658*bbecb9d1SAndroid Build Coastguard Worker       break;
659*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_VERTEX:
660*bbecb9d1SAndroid Build Coastguard Worker       name_prefix = "vso";
661*bbecb9d1SAndroid Build Coastguard Worker       break;
662*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_TESS_CTRL:
663*bbecb9d1SAndroid Build Coastguard Worker       name_prefix = "tco";
664*bbecb9d1SAndroid Build Coastguard Worker       break;
665*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_TESS_EVAL:
666*bbecb9d1SAndroid Build Coastguard Worker       name_prefix = "teo";
667*bbecb9d1SAndroid Build Coastguard Worker       break;
668*bbecb9d1SAndroid Build Coastguard Worker    default:
669*bbecb9d1SAndroid Build Coastguard Worker       name_prefix = "out";
670*bbecb9d1SAndroid Build Coastguard Worker       break;
671*bbecb9d1SAndroid Build Coastguard Worker    }
672*bbecb9d1SAndroid Build Coastguard Worker    return name_prefix;
673*bbecb9d1SAndroid Build Coastguard Worker }
674*bbecb9d1SAndroid Build Coastguard Worker 
require_glsl_ver(const struct dump_ctx * ctx,int glsl_ver)675*bbecb9d1SAndroid Build Coastguard Worker static int require_glsl_ver(const struct dump_ctx *ctx, int glsl_ver)
676*bbecb9d1SAndroid Build Coastguard Worker {
677*bbecb9d1SAndroid Build Coastguard Worker    return glsl_ver > ctx->glsl_ver_required ? glsl_ver : ctx->glsl_ver_required;
678*bbecb9d1SAndroid Build Coastguard Worker }
679*bbecb9d1SAndroid Build Coastguard Worker 
emit_indent(struct vrend_glsl_strbufs * glsl_strbufs)680*bbecb9d1SAndroid Build Coastguard Worker static void emit_indent(struct vrend_glsl_strbufs *glsl_strbufs)
681*bbecb9d1SAndroid Build Coastguard Worker {
682*bbecb9d1SAndroid Build Coastguard Worker    if (glsl_strbufs->indent_level > 0) {
683*bbecb9d1SAndroid Build Coastguard Worker       /* very high levels of indentation doesn't improve readability */
684*bbecb9d1SAndroid Build Coastguard Worker       int indent_level = MIN2(glsl_strbufs->indent_level, 15);
685*bbecb9d1SAndroid Build Coastguard Worker       char buf[16];
686*bbecb9d1SAndroid Build Coastguard Worker       memset(buf, '\t', indent_level);
687*bbecb9d1SAndroid Build Coastguard Worker       buf[indent_level] = '\0';
688*bbecb9d1SAndroid Build Coastguard Worker       strbuf_append(&glsl_strbufs->glsl_main, buf);
689*bbecb9d1SAndroid Build Coastguard Worker    }
690*bbecb9d1SAndroid Build Coastguard Worker }
691*bbecb9d1SAndroid Build Coastguard Worker 
emit_buf(struct vrend_glsl_strbufs * glsl_strbufs,const char * buf)692*bbecb9d1SAndroid Build Coastguard Worker static void emit_buf(struct vrend_glsl_strbufs *glsl_strbufs, const char *buf)
693*bbecb9d1SAndroid Build Coastguard Worker {
694*bbecb9d1SAndroid Build Coastguard Worker    emit_indent(glsl_strbufs);
695*bbecb9d1SAndroid Build Coastguard Worker    strbuf_append(&glsl_strbufs->glsl_main, buf);
696*bbecb9d1SAndroid Build Coastguard Worker }
697*bbecb9d1SAndroid Build Coastguard Worker 
indent_buf(struct vrend_glsl_strbufs * glsl_strbufs)698*bbecb9d1SAndroid Build Coastguard Worker static void indent_buf(struct vrend_glsl_strbufs *glsl_strbufs)
699*bbecb9d1SAndroid Build Coastguard Worker {
700*bbecb9d1SAndroid Build Coastguard Worker    glsl_strbufs->indent_level++;
701*bbecb9d1SAndroid Build Coastguard Worker }
702*bbecb9d1SAndroid Build Coastguard Worker 
outdent_buf(struct vrend_glsl_strbufs * glsl_strbufs)703*bbecb9d1SAndroid Build Coastguard Worker static void outdent_buf(struct vrend_glsl_strbufs *glsl_strbufs)
704*bbecb9d1SAndroid Build Coastguard Worker {
705*bbecb9d1SAndroid Build Coastguard Worker    if (glsl_strbufs->indent_level <= 0) {
706*bbecb9d1SAndroid Build Coastguard Worker       strbuf_set_error(&glsl_strbufs->glsl_main);
707*bbecb9d1SAndroid Build Coastguard Worker       return;
708*bbecb9d1SAndroid Build Coastguard Worker    }
709*bbecb9d1SAndroid Build Coastguard Worker    glsl_strbufs->indent_level--;
710*bbecb9d1SAndroid Build Coastguard Worker }
711*bbecb9d1SAndroid Build Coastguard Worker 
set_buf_error(struct vrend_glsl_strbufs * glsl_strbufs)712*bbecb9d1SAndroid Build Coastguard Worker static void set_buf_error(struct vrend_glsl_strbufs *glsl_strbufs)
713*bbecb9d1SAndroid Build Coastguard Worker {
714*bbecb9d1SAndroid Build Coastguard Worker    strbuf_set_error(&glsl_strbufs->glsl_main);
715*bbecb9d1SAndroid Build Coastguard Worker }
716*bbecb9d1SAndroid Build Coastguard Worker 
717*bbecb9d1SAndroid Build Coastguard Worker __attribute__((format(printf, 2, 3)))
emit_buff(struct vrend_glsl_strbufs * glsl_strbufs,const char * fmt,...)718*bbecb9d1SAndroid Build Coastguard Worker static void emit_buff(struct vrend_glsl_strbufs *glsl_strbufs, const char *fmt, ...)
719*bbecb9d1SAndroid Build Coastguard Worker {
720*bbecb9d1SAndroid Build Coastguard Worker    va_list va;
721*bbecb9d1SAndroid Build Coastguard Worker    va_start(va, fmt);
722*bbecb9d1SAndroid Build Coastguard Worker    emit_indent(glsl_strbufs);
723*bbecb9d1SAndroid Build Coastguard Worker    strbuf_vappendf(&glsl_strbufs->glsl_main, fmt, va);
724*bbecb9d1SAndroid Build Coastguard Worker    va_end(va);
725*bbecb9d1SAndroid Build Coastguard Worker }
726*bbecb9d1SAndroid Build Coastguard Worker 
emit_hdr(struct vrend_glsl_strbufs * glsl_strbufs,const char * buf)727*bbecb9d1SAndroid Build Coastguard Worker static void emit_hdr(struct vrend_glsl_strbufs *glsl_strbufs, const char *buf)
728*bbecb9d1SAndroid Build Coastguard Worker {
729*bbecb9d1SAndroid Build Coastguard Worker    strbuf_append(&glsl_strbufs->glsl_hdr, buf);
730*bbecb9d1SAndroid Build Coastguard Worker }
731*bbecb9d1SAndroid Build Coastguard Worker 
set_hdr_error(struct vrend_glsl_strbufs * glsl_strbufs)732*bbecb9d1SAndroid Build Coastguard Worker static void set_hdr_error(struct vrend_glsl_strbufs *glsl_strbufs)
733*bbecb9d1SAndroid Build Coastguard Worker {
734*bbecb9d1SAndroid Build Coastguard Worker    strbuf_set_error(&glsl_strbufs->glsl_hdr);
735*bbecb9d1SAndroid Build Coastguard Worker }
736*bbecb9d1SAndroid Build Coastguard Worker 
737*bbecb9d1SAndroid Build Coastguard Worker __attribute__((format(printf, 2, 3)))
emit_hdrf(struct vrend_glsl_strbufs * glsl_strbufs,const char * fmt,...)738*bbecb9d1SAndroid Build Coastguard Worker static void emit_hdrf(struct vrend_glsl_strbufs *glsl_strbufs, const char *fmt, ...)
739*bbecb9d1SAndroid Build Coastguard Worker {
740*bbecb9d1SAndroid Build Coastguard Worker    va_list va;
741*bbecb9d1SAndroid Build Coastguard Worker    va_start(va, fmt);
742*bbecb9d1SAndroid Build Coastguard Worker    strbuf_vappendf(&glsl_strbufs->glsl_hdr, fmt, va);
743*bbecb9d1SAndroid Build Coastguard Worker    va_end(va);
744*bbecb9d1SAndroid Build Coastguard Worker }
745*bbecb9d1SAndroid Build Coastguard Worker 
emit_ver_ext(struct vrend_glsl_strbufs * glsl_strbufs,const char * buf)746*bbecb9d1SAndroid Build Coastguard Worker static void emit_ver_ext(struct vrend_glsl_strbufs *glsl_strbufs, const char *buf)
747*bbecb9d1SAndroid Build Coastguard Worker {
748*bbecb9d1SAndroid Build Coastguard Worker    strbuf_append(&glsl_strbufs->glsl_ver_ext, buf);
749*bbecb9d1SAndroid Build Coastguard Worker }
750*bbecb9d1SAndroid Build Coastguard Worker 
751*bbecb9d1SAndroid Build Coastguard Worker __attribute__((format(printf, 2, 3)))
emit_ver_extf(struct vrend_glsl_strbufs * glsl_strbufs,const char * fmt,...)752*bbecb9d1SAndroid Build Coastguard Worker static void emit_ver_extf(struct vrend_glsl_strbufs *glsl_strbufs, const char *fmt, ...)
753*bbecb9d1SAndroid Build Coastguard Worker {
754*bbecb9d1SAndroid Build Coastguard Worker    va_list va;
755*bbecb9d1SAndroid Build Coastguard Worker    va_start(va, fmt);
756*bbecb9d1SAndroid Build Coastguard Worker    strbuf_vappendf(&glsl_strbufs->glsl_ver_ext, fmt, va);
757*bbecb9d1SAndroid Build Coastguard Worker    va_end(va);
758*bbecb9d1SAndroid Build Coastguard Worker }
759*bbecb9d1SAndroid Build Coastguard Worker 
allocate_temp_range(struct vrend_temp_range ** temp_ranges,uint32_t * num_temp_ranges,int first,int last,int array_id)760*bbecb9d1SAndroid Build Coastguard Worker static bool allocate_temp_range(struct vrend_temp_range **temp_ranges, uint32_t *num_temp_ranges, int first, int last,
761*bbecb9d1SAndroid Build Coastguard Worker                                 int array_id)
762*bbecb9d1SAndroid Build Coastguard Worker {
763*bbecb9d1SAndroid Build Coastguard Worker    int idx = *num_temp_ranges;
764*bbecb9d1SAndroid Build Coastguard Worker 
765*bbecb9d1SAndroid Build Coastguard Worker    if (array_id > 0) {
766*bbecb9d1SAndroid Build Coastguard Worker 
767*bbecb9d1SAndroid Build Coastguard Worker       *temp_ranges = realloc(*temp_ranges, sizeof(struct vrend_temp_range) * (idx + 1));
768*bbecb9d1SAndroid Build Coastguard Worker       if (!*temp_ranges)
769*bbecb9d1SAndroid Build Coastguard Worker          return false;
770*bbecb9d1SAndroid Build Coastguard Worker 
771*bbecb9d1SAndroid Build Coastguard Worker       (*temp_ranges)[idx].first = first;
772*bbecb9d1SAndroid Build Coastguard Worker       (*temp_ranges)[idx].last = last;
773*bbecb9d1SAndroid Build Coastguard Worker       (*temp_ranges)[idx].array_id = array_id;
774*bbecb9d1SAndroid Build Coastguard Worker       (*temp_ranges)[idx].precise_result = false;
775*bbecb9d1SAndroid Build Coastguard Worker       (*num_temp_ranges)++;
776*bbecb9d1SAndroid Build Coastguard Worker    } else {
777*bbecb9d1SAndroid Build Coastguard Worker       int ntemps = last - first + 1;
778*bbecb9d1SAndroid Build Coastguard Worker       *temp_ranges = realloc(*temp_ranges, sizeof(struct vrend_temp_range) * (idx + ntemps));
779*bbecb9d1SAndroid Build Coastguard Worker       for (int i = 0; i < ntemps; ++i) {
780*bbecb9d1SAndroid Build Coastguard Worker          (*temp_ranges)[idx + i].first = first + i;
781*bbecb9d1SAndroid Build Coastguard Worker          (*temp_ranges)[idx + i].last = first + i;
782*bbecb9d1SAndroid Build Coastguard Worker          (*temp_ranges)[idx + i].array_id = 0;
783*bbecb9d1SAndroid Build Coastguard Worker          (*temp_ranges)[idx + i].precise_result = false;
784*bbecb9d1SAndroid Build Coastguard Worker       }
785*bbecb9d1SAndroid Build Coastguard Worker       (*num_temp_ranges) += ntemps;
786*bbecb9d1SAndroid Build Coastguard Worker 
787*bbecb9d1SAndroid Build Coastguard Worker 
788*bbecb9d1SAndroid Build Coastguard Worker    }
789*bbecb9d1SAndroid Build Coastguard Worker    return true;
790*bbecb9d1SAndroid Build Coastguard Worker }
791*bbecb9d1SAndroid Build Coastguard Worker 
find_temp_range(const struct dump_ctx * ctx,int index)792*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_temp_range *find_temp_range(const struct dump_ctx *ctx, int index)
793*bbecb9d1SAndroid Build Coastguard Worker {
794*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
795*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_temp_ranges; i++) {
796*bbecb9d1SAndroid Build Coastguard Worker       if (index >= ctx->temp_ranges[i].first &&
797*bbecb9d1SAndroid Build Coastguard Worker           index <= ctx->temp_ranges[i].last)
798*bbecb9d1SAndroid Build Coastguard Worker          return &ctx->temp_ranges[i];
799*bbecb9d1SAndroid Build Coastguard Worker    }
800*bbecb9d1SAndroid Build Coastguard Worker    return NULL;
801*bbecb9d1SAndroid Build Coastguard Worker }
802*bbecb9d1SAndroid Build Coastguard Worker 
samplertype_is_shadow(int sampler_type)803*bbecb9d1SAndroid Build Coastguard Worker static bool samplertype_is_shadow(int sampler_type)
804*bbecb9d1SAndroid Build Coastguard Worker {
805*bbecb9d1SAndroid Build Coastguard Worker    switch (sampler_type) {
806*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW1D:
807*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW1D_ARRAY:
808*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW2D:
809*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWRECT:
810*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW2D_ARRAY:
811*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWCUBE:
812*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
813*bbecb9d1SAndroid Build Coastguard Worker       return true;
814*bbecb9d1SAndroid Build Coastguard Worker    default:
815*bbecb9d1SAndroid Build Coastguard Worker       return false;
816*bbecb9d1SAndroid Build Coastguard Worker    }
817*bbecb9d1SAndroid Build Coastguard Worker }
818*bbecb9d1SAndroid Build Coastguard Worker 
samplertype_to_req_bits(int sampler_type)819*bbecb9d1SAndroid Build Coastguard Worker static uint32_t samplertype_to_req_bits(int sampler_type)
820*bbecb9d1SAndroid Build Coastguard Worker {
821*bbecb9d1SAndroid Build Coastguard Worker 
822*bbecb9d1SAndroid Build Coastguard Worker    switch (sampler_type) {
823*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
824*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_CUBE_ARRAY:
825*bbecb9d1SAndroid Build Coastguard Worker       return SHADER_REQ_CUBE_ARRAY;
826*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_MSAA:
827*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_ARRAY_MSAA:
828*bbecb9d1SAndroid Build Coastguard Worker       return SHADER_REQ_SAMPLER_MS;
829*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_BUFFER:
830*bbecb9d1SAndroid Build Coastguard Worker       return SHADER_REQ_SAMPLER_BUF;
831*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWRECT:
832*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_RECT:
833*bbecb9d1SAndroid Build Coastguard Worker       return SHADER_REQ_SAMPLER_RECT;
834*bbecb9d1SAndroid Build Coastguard Worker    default:
835*bbecb9d1SAndroid Build Coastguard Worker       return 0;
836*bbecb9d1SAndroid Build Coastguard Worker    }
837*bbecb9d1SAndroid Build Coastguard Worker }
838*bbecb9d1SAndroid Build Coastguard Worker 
839*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
add_images(struct dump_ctx * ctx,int first,int last,const struct tgsi_declaration_image * img_decl)840*bbecb9d1SAndroid Build Coastguard Worker static bool add_images(struct dump_ctx *ctx, int first, int last,
841*bbecb9d1SAndroid Build Coastguard Worker                        const struct tgsi_declaration_image *img_decl)
842*bbecb9d1SAndroid Build Coastguard Worker {
843*bbecb9d1SAndroid Build Coastguard Worker    int i;
844*bbecb9d1SAndroid Build Coastguard Worker 
845*bbecb9d1SAndroid Build Coastguard Worker    const struct util_format_description *descr = util_format_description(img_decl->Format);
846*bbecb9d1SAndroid Build Coastguard Worker    if (descr->nr_channels == 2 &&
847*bbecb9d1SAndroid Build Coastguard Worker        descr->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
848*bbecb9d1SAndroid Build Coastguard Worker        descr->swizzle[1] == UTIL_FORMAT_SWIZZLE_Y &&
849*bbecb9d1SAndroid Build Coastguard Worker        descr->swizzle[2] == UTIL_FORMAT_SWIZZLE_0 &&
850*bbecb9d1SAndroid Build Coastguard Worker        descr->swizzle[3] == UTIL_FORMAT_SWIZZLE_1) {
851*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_NV_IMAGE_FORMATS;
852*bbecb9d1SAndroid Build Coastguard Worker    } else if (img_decl->Format == PIPE_FORMAT_R11G11B10_FLOAT ||
853*bbecb9d1SAndroid Build Coastguard Worker               img_decl->Format == PIPE_FORMAT_R10G10B10A2_UINT ||
854*bbecb9d1SAndroid Build Coastguard Worker               img_decl->Format == PIPE_FORMAT_R10G10B10A2_UNORM ||
855*bbecb9d1SAndroid Build Coastguard Worker               img_decl->Format == PIPE_FORMAT_R16G16B16A16_UNORM||
856*bbecb9d1SAndroid Build Coastguard Worker               img_decl->Format == PIPE_FORMAT_R16G16B16A16_SNORM)
857*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_NV_IMAGE_FORMATS;
858*bbecb9d1SAndroid Build Coastguard Worker    else if (descr->nr_channels == 1 &&
859*bbecb9d1SAndroid Build Coastguard Worker             descr->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
860*bbecb9d1SAndroid Build Coastguard Worker             descr->swizzle[1] == UTIL_FORMAT_SWIZZLE_0 &&
861*bbecb9d1SAndroid Build Coastguard Worker             descr->swizzle[2] == UTIL_FORMAT_SWIZZLE_0 &&
862*bbecb9d1SAndroid Build Coastguard Worker             descr->swizzle[3] == UTIL_FORMAT_SWIZZLE_1 &&
863*bbecb9d1SAndroid Build Coastguard Worker             (descr->channel[0].size == 8 || descr->channel[0].size ==16))
864*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_NV_IMAGE_FORMATS;
865*bbecb9d1SAndroid Build Coastguard Worker 
866*bbecb9d1SAndroid Build Coastguard Worker    for (i = first; i <= last; i++) {
867*bbecb9d1SAndroid Build Coastguard Worker       ctx->images[i].decl = *img_decl;
868*bbecb9d1SAndroid Build Coastguard Worker       ctx->images[i].vflag = false;
869*bbecb9d1SAndroid Build Coastguard Worker       ctx->images_used_mask |= (1 << i);
870*bbecb9d1SAndroid Build Coastguard Worker 
871*bbecb9d1SAndroid Build Coastguard Worker       if (!samplertype_is_shadow(ctx->images[i].decl.Resource))
872*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= samplertype_to_req_bits(ctx->images[i].decl.Resource);
873*bbecb9d1SAndroid Build Coastguard Worker    }
874*bbecb9d1SAndroid Build Coastguard Worker 
875*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
876*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->num_image_arrays) {
877*bbecb9d1SAndroid Build Coastguard Worker          struct vrend_array *last_array = &ctx->image_arrays[ctx->num_image_arrays - 1];
878*bbecb9d1SAndroid Build Coastguard Worker          /*
879*bbecb9d1SAndroid Build Coastguard Worker           * If this set of images is consecutive to the last array,
880*bbecb9d1SAndroid Build Coastguard Worker           * and has compatible return and decls, then increase the array size.
881*bbecb9d1SAndroid Build Coastguard Worker           */
882*bbecb9d1SAndroid Build Coastguard Worker          if ((last_array->first + last_array->array_size == first) &&
883*bbecb9d1SAndroid Build Coastguard Worker              !memcmp(&ctx->images[last_array->first].decl, &ctx->images[first].decl, sizeof(ctx->images[first].decl)) &&
884*bbecb9d1SAndroid Build Coastguard Worker              ctx->images[last_array->first].image_return == ctx->images[first].image_return) {
885*bbecb9d1SAndroid Build Coastguard Worker             last_array->array_size += last - first + 1;
886*bbecb9d1SAndroid Build Coastguard Worker             return true;
887*bbecb9d1SAndroid Build Coastguard Worker          }
888*bbecb9d1SAndroid Build Coastguard Worker       }
889*bbecb9d1SAndroid Build Coastguard Worker 
890*bbecb9d1SAndroid Build Coastguard Worker       /* allocate a new image array for this range of images */
891*bbecb9d1SAndroid Build Coastguard Worker       ctx->num_image_arrays++;
892*bbecb9d1SAndroid Build Coastguard Worker       ctx->image_arrays = realloc(ctx->image_arrays, sizeof(struct vrend_array) * ctx->num_image_arrays);
893*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->image_arrays)
894*bbecb9d1SAndroid Build Coastguard Worker          return false;
895*bbecb9d1SAndroid Build Coastguard Worker       ctx->image_arrays[ctx->num_image_arrays - 1].first = first;
896*bbecb9d1SAndroid Build Coastguard Worker       ctx->image_arrays[ctx->num_image_arrays - 1].array_size = last - first + 1;
897*bbecb9d1SAndroid Build Coastguard Worker    }
898*bbecb9d1SAndroid Build Coastguard Worker    return true;
899*bbecb9d1SAndroid Build Coastguard Worker }
900*bbecb9d1SAndroid Build Coastguard Worker 
901*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
add_sampler_array(struct dump_ctx * ctx,int first,int last)902*bbecb9d1SAndroid Build Coastguard Worker static bool add_sampler_array(struct dump_ctx *ctx, int first, int last)
903*bbecb9d1SAndroid Build Coastguard Worker {
904*bbecb9d1SAndroid Build Coastguard Worker    int idx = ctx->num_sampler_arrays;
905*bbecb9d1SAndroid Build Coastguard Worker    ctx->num_sampler_arrays++;
906*bbecb9d1SAndroid Build Coastguard Worker    ctx->sampler_arrays = realloc(ctx->sampler_arrays, sizeof(struct vrend_array) * ctx->num_sampler_arrays);
907*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx->sampler_arrays)
908*bbecb9d1SAndroid Build Coastguard Worker       return false;
909*bbecb9d1SAndroid Build Coastguard Worker 
910*bbecb9d1SAndroid Build Coastguard Worker    ctx->sampler_arrays[idx].first = first;
911*bbecb9d1SAndroid Build Coastguard Worker    ctx->sampler_arrays[idx].array_size = last - first + 1;
912*bbecb9d1SAndroid Build Coastguard Worker    return true;
913*bbecb9d1SAndroid Build Coastguard Worker }
914*bbecb9d1SAndroid Build Coastguard Worker 
lookup_sampler_array(const struct dump_ctx * ctx,int index)915*bbecb9d1SAndroid Build Coastguard Worker static int lookup_sampler_array(const struct dump_ctx *ctx, int index)
916*bbecb9d1SAndroid Build Coastguard Worker {
917*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
918*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_sampler_arrays; i++) {
919*bbecb9d1SAndroid Build Coastguard Worker       int last = ctx->sampler_arrays[i].first + ctx->sampler_arrays[i].array_size - 1;
920*bbecb9d1SAndroid Build Coastguard Worker       if (index >= ctx->sampler_arrays[i].first &&
921*bbecb9d1SAndroid Build Coastguard Worker           index <= last) {
922*bbecb9d1SAndroid Build Coastguard Worker          return ctx->sampler_arrays[i].first;
923*bbecb9d1SAndroid Build Coastguard Worker       }
924*bbecb9d1SAndroid Build Coastguard Worker    }
925*bbecb9d1SAndroid Build Coastguard Worker    return -1;
926*bbecb9d1SAndroid Build Coastguard Worker }
927*bbecb9d1SAndroid Build Coastguard Worker 
vrend_shader_lookup_sampler_array(const struct vrend_shader_info * sinfo,int index)928*bbecb9d1SAndroid Build Coastguard Worker int vrend_shader_lookup_sampler_array(const struct vrend_shader_info *sinfo, int index)
929*bbecb9d1SAndroid Build Coastguard Worker {
930*bbecb9d1SAndroid Build Coastguard Worker    int i;
931*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < sinfo->num_sampler_arrays; i++) {
932*bbecb9d1SAndroid Build Coastguard Worker       int last = sinfo->sampler_arrays[i].first + sinfo->sampler_arrays[i].array_size - 1;
933*bbecb9d1SAndroid Build Coastguard Worker       if (index >= sinfo->sampler_arrays[i].first &&
934*bbecb9d1SAndroid Build Coastguard Worker           index <= last) {
935*bbecb9d1SAndroid Build Coastguard Worker          return sinfo->sampler_arrays[i].first;
936*bbecb9d1SAndroid Build Coastguard Worker       }
937*bbecb9d1SAndroid Build Coastguard Worker    }
938*bbecb9d1SAndroid Build Coastguard Worker    return -1;
939*bbecb9d1SAndroid Build Coastguard Worker }
940*bbecb9d1SAndroid Build Coastguard Worker 
941*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
add_samplers(struct dump_ctx * ctx,int first,int last,int sview_type,enum tgsi_return_type sview_rtype)942*bbecb9d1SAndroid Build Coastguard Worker static bool add_samplers(struct dump_ctx *ctx, int first, int last, int sview_type, enum tgsi_return_type sview_rtype)
943*bbecb9d1SAndroid Build Coastguard Worker {
944*bbecb9d1SAndroid Build Coastguard Worker    if (sview_rtype == TGSI_RETURN_TYPE_SINT ||
945*bbecb9d1SAndroid Build Coastguard Worker        sview_rtype == TGSI_RETURN_TYPE_UINT)
946*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_INTS;
947*bbecb9d1SAndroid Build Coastguard Worker 
948*bbecb9d1SAndroid Build Coastguard Worker    for (int i = first; i <= last; i++) {
949*bbecb9d1SAndroid Build Coastguard Worker       ctx->samplers[i].tgsi_sampler_return = sview_rtype;
950*bbecb9d1SAndroid Build Coastguard Worker       ctx->samplers[i].tgsi_sampler_type = sview_type;
951*bbecb9d1SAndroid Build Coastguard Worker    }
952*bbecb9d1SAndroid Build Coastguard Worker 
953*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
954*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->num_sampler_arrays) {
955*bbecb9d1SAndroid Build Coastguard Worker          struct vrend_array *last_array = &ctx->sampler_arrays[ctx->num_sampler_arrays - 1];
956*bbecb9d1SAndroid Build Coastguard Worker          if ((last_array->first + last_array->array_size == first) &&
957*bbecb9d1SAndroid Build Coastguard Worker              ctx->samplers[last_array->first].tgsi_sampler_type == sview_type &&
958*bbecb9d1SAndroid Build Coastguard Worker              ctx->samplers[last_array->first].tgsi_sampler_return == sview_rtype) {
959*bbecb9d1SAndroid Build Coastguard Worker             last_array->array_size += last - first + 1;
960*bbecb9d1SAndroid Build Coastguard Worker             return true;
961*bbecb9d1SAndroid Build Coastguard Worker          }
962*bbecb9d1SAndroid Build Coastguard Worker       }
963*bbecb9d1SAndroid Build Coastguard Worker 
964*bbecb9d1SAndroid Build Coastguard Worker       /* allocate a new image array for this range of images */
965*bbecb9d1SAndroid Build Coastguard Worker       return add_sampler_array(ctx, first, last);
966*bbecb9d1SAndroid Build Coastguard Worker    }
967*bbecb9d1SAndroid Build Coastguard Worker    return true;
968*bbecb9d1SAndroid Build Coastguard Worker }
969*bbecb9d1SAndroid Build Coastguard Worker 
970*bbecb9d1SAndroid Build Coastguard Worker typedef enum
971*bbecb9d1SAndroid Build Coastguard Worker {
972*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_POS,
973*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_COL0, /* COL0 and COL1 must be contiguous */
974*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_COL1,
975*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_FOGC,
976*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_TEX0, /* TEX0-TEX7 must be contiguous */
977*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_TEX1,
978*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_TEX2,
979*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_TEX3,
980*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_TEX4,
981*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_TEX5,
982*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_TEX6,
983*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_TEX7,
984*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_PSIZ, /* Does not appear in FS */
985*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_BFC0, /* Does not appear in FS */
986*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_BFC1, /* Does not appear in FS */
987*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_EDGE, /* Does not appear in FS */
988*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_CLIP_VERTEX, /* Does not appear in FS */
989*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_CLIP_DIST0,
990*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_CLIP_DIST1,
991*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_CULL_DIST0,
992*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_CULL_DIST1,
993*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_PRIMITIVE_ID, /* Does not appear in VS */
994*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_LAYER, /* Appears as VS or GS output */
995*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VIEWPORT, /* Appears as VS or GS output */
996*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_FACE, /* FS only */
997*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_PNTC, /* FS only */
998*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_TESS_LEVEL_OUTER, /* Only appears as TCS output. */
999*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_TESS_LEVEL_INNER, /* Only appears as TCS output. */
1000*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_BOUNDING_BOX0, /* Only appears as TCS output. */
1001*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_BOUNDING_BOX1, /* Only appears as TCS output. */
1002*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VIEW_INDEX,
1003*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VIEWPORT_MASK, /* Does not appear in FS */
1004*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_PRIMITIVE_SHADING_RATE = VARYING_SLOT_FACE, /* Does not appear in FS. */
1005*bbecb9d1SAndroid Build Coastguard Worker 
1006*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_PRIMITIVE_COUNT = VARYING_SLOT_TESS_LEVEL_OUTER, /* Only appears in MESH. */
1007*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_PRIMITIVE_INDICES = VARYING_SLOT_TESS_LEVEL_INNER, /* Only appears in MESH. */
1008*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_TASK_COUNT = VARYING_SLOT_BOUNDING_BOX0, /* Only appears in TASK. */
1009*bbecb9d1SAndroid Build Coastguard Worker 
1010*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR0 = 32, /* First generic varying slot */
1011*bbecb9d1SAndroid Build Coastguard Worker    /* the remaining are simply for the benefit of gl_varying_slot_name()
1012*bbecb9d1SAndroid Build Coastguard Worker     * and not to be construed as an upper bound:
1013*bbecb9d1SAndroid Build Coastguard Worker     */
1014*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR1,
1015*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR2,
1016*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR3,
1017*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR4,
1018*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR5,
1019*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR6,
1020*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR7,
1021*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR8,
1022*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR9,
1023*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR10,
1024*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR11,
1025*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR12,
1026*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR13,
1027*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR14,
1028*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR15,
1029*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR16,
1030*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR17,
1031*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR18,
1032*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR19,
1033*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR20,
1034*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR21,
1035*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR22,
1036*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR23,
1037*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR24,
1038*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR25,
1039*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR26,
1040*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR27,
1041*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR28,
1042*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR29,
1043*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR30,
1044*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_VAR31,
1045*bbecb9d1SAndroid Build Coastguard Worker    /* Account for the shift without CAP_TEXCOORD in mesa*/
1046*bbecb9d1SAndroid Build Coastguard Worker    VARYING_SLOT_PATCH0 = VARYING_SLOT_VAR31 + 9
1047*bbecb9d1SAndroid Build Coastguard Worker } gl_varying_slot;
1048*bbecb9d1SAndroid Build Coastguard Worker 
1049*bbecb9d1SAndroid Build Coastguard Worker static uint32_t
varying_bit_from_semantic_and_index(enum tgsi_semantic semantic,int index)1050*bbecb9d1SAndroid Build Coastguard Worker varying_bit_from_semantic_and_index(enum tgsi_semantic semantic, int index)
1051*bbecb9d1SAndroid Build Coastguard Worker {
1052*bbecb9d1SAndroid Build Coastguard Worker    switch (semantic) {
1053*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_POSITION:
1054*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_POS;
1055*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_COLOR:
1056*bbecb9d1SAndroid Build Coastguard Worker       if (index == 0)
1057*bbecb9d1SAndroid Build Coastguard Worker          return VARYING_SLOT_COL0;
1058*bbecb9d1SAndroid Build Coastguard Worker       else
1059*bbecb9d1SAndroid Build Coastguard Worker          return VARYING_SLOT_COL1;
1060*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_BCOLOR:
1061*bbecb9d1SAndroid Build Coastguard Worker       if (index == 0)
1062*bbecb9d1SAndroid Build Coastguard Worker          return VARYING_SLOT_BFC0;
1063*bbecb9d1SAndroid Build Coastguard Worker       else
1064*bbecb9d1SAndroid Build Coastguard Worker          return VARYING_SLOT_BFC1;
1065*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_FOG:
1066*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_FOGC;
1067*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PSIZE:
1068*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_PSIZ;
1069*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_GENERIC:
1070*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_VAR0 + index;
1071*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_FACE:
1072*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_FACE;
1073*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_EDGEFLAG:
1074*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_EDGE;
1075*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PRIMID:
1076*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_PRIMITIVE_ID;
1077*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_CLIPDIST:
1078*bbecb9d1SAndroid Build Coastguard Worker       if (index == 0)
1079*bbecb9d1SAndroid Build Coastguard Worker          return VARYING_SLOT_CLIP_DIST0;
1080*bbecb9d1SAndroid Build Coastguard Worker       else
1081*bbecb9d1SAndroid Build Coastguard Worker          return VARYING_SLOT_CLIP_DIST1;
1082*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_CLIPVERTEX:
1083*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_CLIP_VERTEX;
1084*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_TEXCOORD:
1085*bbecb9d1SAndroid Build Coastguard Worker       assert(index < 8);
1086*bbecb9d1SAndroid Build Coastguard Worker       return (VARYING_SLOT_TEX0 + index);
1087*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PCOORD:
1088*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_PNTC;
1089*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_VIEWPORT_INDEX:
1090*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_VIEWPORT;
1091*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_LAYER:
1092*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_LAYER;
1093*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_TESSINNER:
1094*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_TESS_LEVEL_INNER;
1095*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_TESSOUTER:
1096*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_TESS_LEVEL_OUTER;
1097*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PATCH:
1098*bbecb9d1SAndroid Build Coastguard Worker       return VARYING_SLOT_PATCH0 + index;
1099*bbecb9d1SAndroid Build Coastguard Worker    default:
1100*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf("Warning: Bad TGSI semantic: %d/%d\n", semantic, index);
1101*bbecb9d1SAndroid Build Coastguard Worker       return 0;
1102*bbecb9d1SAndroid Build Coastguard Worker    }
1103*bbecb9d1SAndroid Build Coastguard Worker }
1104*bbecb9d1SAndroid Build Coastguard Worker 
lookup_image_array_ptr(const struct dump_ctx * ctx,int index)1105*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_array *lookup_image_array_ptr(const struct dump_ctx *ctx, int index)
1106*bbecb9d1SAndroid Build Coastguard Worker {
1107*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
1108*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_image_arrays; i++) {
1109*bbecb9d1SAndroid Build Coastguard Worker       if (index >= ctx->image_arrays[i].first &&
1110*bbecb9d1SAndroid Build Coastguard Worker           index <= ctx->image_arrays[i].first + ctx->image_arrays[i].array_size - 1) {
1111*bbecb9d1SAndroid Build Coastguard Worker          return &ctx->image_arrays[i];
1112*bbecb9d1SAndroid Build Coastguard Worker       }
1113*bbecb9d1SAndroid Build Coastguard Worker    }
1114*bbecb9d1SAndroid Build Coastguard Worker    return NULL;
1115*bbecb9d1SAndroid Build Coastguard Worker }
1116*bbecb9d1SAndroid Build Coastguard Worker 
lookup_image_array(const struct dump_ctx * ctx,int index)1117*bbecb9d1SAndroid Build Coastguard Worker static int lookup_image_array(const struct dump_ctx *ctx, int index)
1118*bbecb9d1SAndroid Build Coastguard Worker {
1119*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_array *image = lookup_image_array_ptr(ctx, index);
1120*bbecb9d1SAndroid Build Coastguard Worker    return image ? image->first : -1;
1121*bbecb9d1SAndroid Build Coastguard Worker }
1122*bbecb9d1SAndroid Build Coastguard Worker 
1123*bbecb9d1SAndroid Build Coastguard Worker static boolean
iter_decls(struct tgsi_iterate_context * iter,struct tgsi_full_declaration * decl)1124*bbecb9d1SAndroid Build Coastguard Worker iter_decls(struct tgsi_iterate_context *iter,
1125*bbecb9d1SAndroid Build Coastguard Worker            struct tgsi_full_declaration *decl)
1126*bbecb9d1SAndroid Build Coastguard Worker {
1127*bbecb9d1SAndroid Build Coastguard Worker    struct dump_ctx *ctx = (struct dump_ctx *)iter;
1128*bbecb9d1SAndroid Build Coastguard Worker    switch (decl->Declaration.File) {
1129*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_INPUT:
1130*bbecb9d1SAndroid Build Coastguard Worker       /* Tag used semantic fog inputs */
1131*bbecb9d1SAndroid Build Coastguard Worker       if (decl->Semantic.Name == TGSI_SEMANTIC_FOG) {
1132*bbecb9d1SAndroid Build Coastguard Worker          ctx->fog_input_mask |= (1 << decl->Semantic.Index);
1133*bbecb9d1SAndroid Build Coastguard Worker       }
1134*bbecb9d1SAndroid Build Coastguard Worker 
1135*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT) {
1136*bbecb9d1SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < ctx->num_inputs; j++) {
1137*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->inputs[j].name == decl->Semantic.Name &&
1138*bbecb9d1SAndroid Build Coastguard Worker                 ctx->inputs[j].sid == decl->Semantic.Index &&
1139*bbecb9d1SAndroid Build Coastguard Worker                 ctx->inputs[j].first == decl->Range.First)
1140*bbecb9d1SAndroid Build Coastguard Worker                   return true;
1141*bbecb9d1SAndroid Build Coastguard Worker          }
1142*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[ctx->num_inputs].name = decl->Semantic.Name;
1143*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[ctx->num_inputs].first = decl->Range.First;
1144*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[ctx->num_inputs].last = decl->Range.Last;
1145*bbecb9d1SAndroid Build Coastguard Worker          ctx->num_inputs++;
1146*bbecb9d1SAndroid Build Coastguard Worker       }
1147*bbecb9d1SAndroid Build Coastguard Worker       break;
1148*bbecb9d1SAndroid Build Coastguard Worker 
1149*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_OUTPUT:
1150*bbecb9d1SAndroid Build Coastguard Worker       if (decl->Semantic.Name == TGSI_SEMANTIC_FOG) {
1151*bbecb9d1SAndroid Build Coastguard Worker          ctx->fog_output_mask |= (1 << decl->Semantic.Index);
1152*bbecb9d1SAndroid Build Coastguard Worker       }
1153*bbecb9d1SAndroid Build Coastguard Worker       break;
1154*bbecb9d1SAndroid Build Coastguard Worker 
1155*bbecb9d1SAndroid Build Coastguard Worker    default:
1156*bbecb9d1SAndroid Build Coastguard Worker       break;
1157*bbecb9d1SAndroid Build Coastguard Worker    }
1158*bbecb9d1SAndroid Build Coastguard Worker    return true;
1159*bbecb9d1SAndroid Build Coastguard Worker }
1160*bbecb9d1SAndroid Build Coastguard Worker 
logiop_require_inout(const struct vrend_shader_key * key)1161*bbecb9d1SAndroid Build Coastguard Worker static bool logiop_require_inout(const struct vrend_shader_key *key)
1162*bbecb9d1SAndroid Build Coastguard Worker {
1163*bbecb9d1SAndroid Build Coastguard Worker    if (!key->fs.logicop_enabled)
1164*bbecb9d1SAndroid Build Coastguard Worker       return false;
1165*bbecb9d1SAndroid Build Coastguard Worker 
1166*bbecb9d1SAndroid Build Coastguard Worker    switch (key->fs.logicop_func) {
1167*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_LOGICOP_CLEAR:
1168*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_LOGICOP_SET:
1169*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_LOGICOP_COPY:
1170*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_LOGICOP_COPY_INVERTED:
1171*bbecb9d1SAndroid Build Coastguard Worker       return false;
1172*bbecb9d1SAndroid Build Coastguard Worker    default:
1173*bbecb9d1SAndroid Build Coastguard Worker       return true;
1174*bbecb9d1SAndroid Build Coastguard Worker    }
1175*bbecb9d1SAndroid Build Coastguard Worker }
1176*bbecb9d1SAndroid Build Coastguard Worker 
get_type(uint32_t signed_int_mask,uint32_t unsigned_int_mask,int bit)1177*bbecb9d1SAndroid Build Coastguard Worker static enum vec_type get_type(uint32_t signed_int_mask,
1178*bbecb9d1SAndroid Build Coastguard Worker                               uint32_t unsigned_int_mask,
1179*bbecb9d1SAndroid Build Coastguard Worker                               int bit)
1180*bbecb9d1SAndroid Build Coastguard Worker {
1181*bbecb9d1SAndroid Build Coastguard Worker    if (signed_int_mask & (1 << bit))
1182*bbecb9d1SAndroid Build Coastguard Worker       return VEC_INT;
1183*bbecb9d1SAndroid Build Coastguard Worker    else if (unsigned_int_mask & (1 << bit))
1184*bbecb9d1SAndroid Build Coastguard Worker       return VEC_UINT;
1185*bbecb9d1SAndroid Build Coastguard Worker    else
1186*bbecb9d1SAndroid Build Coastguard Worker       return VEC_FLOAT;
1187*bbecb9d1SAndroid Build Coastguard Worker }
1188*bbecb9d1SAndroid Build Coastguard Worker 
1189*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_shader_io *
find_overlapping_io(struct vrend_shader_io io[static64],uint32_t num_io,const struct tgsi_full_declaration * decl)1190*bbecb9d1SAndroid Build Coastguard Worker find_overlapping_io(struct vrend_shader_io io[static 64],
1191*bbecb9d1SAndroid Build Coastguard Worker                     uint32_t num_io,
1192*bbecb9d1SAndroid Build Coastguard Worker                     const struct tgsi_full_declaration *decl)
1193*bbecb9d1SAndroid Build Coastguard Worker {
1194*bbecb9d1SAndroid Build Coastguard Worker    for (uint32_t j = 0; j < num_io - 1; j++) {
1195*bbecb9d1SAndroid Build Coastguard Worker       if (io[j].interpolate == decl->Interp.Interpolate &&
1196*bbecb9d1SAndroid Build Coastguard Worker           io[j].name == decl->Semantic.Name &&
1197*bbecb9d1SAndroid Build Coastguard Worker           ((io[j].first <= decl->Range.First &&
1198*bbecb9d1SAndroid Build Coastguard Worker             io[j].last > decl->Range.First) ||
1199*bbecb9d1SAndroid Build Coastguard Worker            (io[j].first < decl->Range.Last &&
1200*bbecb9d1SAndroid Build Coastguard Worker             io[j].last >= decl->Range.Last))) {
1201*bbecb9d1SAndroid Build Coastguard Worker          return &io[j];
1202*bbecb9d1SAndroid Build Coastguard Worker       }
1203*bbecb9d1SAndroid Build Coastguard Worker    }
1204*bbecb9d1SAndroid Build Coastguard Worker    return NULL;
1205*bbecb9d1SAndroid Build Coastguard Worker }
1206*bbecb9d1SAndroid Build Coastguard Worker 
1207*bbecb9d1SAndroid Build Coastguard Worker static void
map_overlapping_io_array(struct vrend_shader_io io[static64],struct vrend_shader_io * new_io,uint32_t num_io,const struct tgsi_full_declaration * decl)1208*bbecb9d1SAndroid Build Coastguard Worker map_overlapping_io_array(struct vrend_shader_io io[static 64],
1209*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_shader_io *new_io,
1210*bbecb9d1SAndroid Build Coastguard Worker                          uint32_t num_io,
1211*bbecb9d1SAndroid Build Coastguard Worker                          const struct tgsi_full_declaration *decl)
1212*bbecb9d1SAndroid Build Coastguard Worker {
1213*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_shader_io *overlap_io = find_overlapping_io(io, num_io, decl);
1214*bbecb9d1SAndroid Build Coastguard Worker    if (overlap_io && !overlap_io->needs_override) {
1215*bbecb9d1SAndroid Build Coastguard Worker       int delta = new_io->first - overlap_io->first;
1216*bbecb9d1SAndroid Build Coastguard Worker       if (delta >= 0) {
1217*bbecb9d1SAndroid Build Coastguard Worker          new_io->array_offset = delta;
1218*bbecb9d1SAndroid Build Coastguard Worker          new_io->overlapping_array = overlap_io;
1219*bbecb9d1SAndroid Build Coastguard Worker          overlap_io->last = MAX2(overlap_io->last, new_io->last);
1220*bbecb9d1SAndroid Build Coastguard Worker       } else if (delta < 0) {
1221*bbecb9d1SAndroid Build Coastguard Worker          overlap_io->overlapping_array = new_io;
1222*bbecb9d1SAndroid Build Coastguard Worker          overlap_io->array_offset = -delta;
1223*bbecb9d1SAndroid Build Coastguard Worker          new_io->last = MAX2(overlap_io->last, new_io->last);
1224*bbecb9d1SAndroid Build Coastguard Worker       }
1225*bbecb9d1SAndroid Build Coastguard Worker       overlap_io->usage_mask |= new_io->usage_mask;
1226*bbecb9d1SAndroid Build Coastguard Worker       new_io->usage_mask = overlap_io->usage_mask;
1227*bbecb9d1SAndroid Build Coastguard Worker    }
1228*bbecb9d1SAndroid Build Coastguard Worker }
1229*bbecb9d1SAndroid Build Coastguard Worker 
1230*bbecb9d1SAndroid Build Coastguard Worker static boolean
iter_declaration(struct tgsi_iterate_context * iter,struct tgsi_full_declaration * decl)1231*bbecb9d1SAndroid Build Coastguard Worker iter_declaration(struct tgsi_iterate_context *iter,
1232*bbecb9d1SAndroid Build Coastguard Worker                  struct tgsi_full_declaration *decl)
1233*bbecb9d1SAndroid Build Coastguard Worker {
1234*bbecb9d1SAndroid Build Coastguard Worker    struct dump_ctx *ctx = (struct dump_ctx *)iter;
1235*bbecb9d1SAndroid Build Coastguard Worker    int i;
1236*bbecb9d1SAndroid Build Coastguard Worker    int color_offset = 0;
1237*bbecb9d1SAndroid Build Coastguard Worker    const char *name_prefix;
1238*bbecb9d1SAndroid Build Coastguard Worker    bool add_two_side = false;
1239*bbecb9d1SAndroid Build Coastguard Worker 
1240*bbecb9d1SAndroid Build Coastguard Worker    switch (decl->Declaration.File) {
1241*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_INPUT:
1242*bbecb9d1SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < ctx->num_inputs; j++) {
1243*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[j].name == decl->Semantic.Name &&
1244*bbecb9d1SAndroid Build Coastguard Worker              ctx->inputs[j].sid == decl->Semantic.Index &&
1245*bbecb9d1SAndroid Build Coastguard Worker              ctx->inputs[j].first == decl->Range.First &&
1246*bbecb9d1SAndroid Build Coastguard Worker              ((!decl->Declaration.Array && ctx->inputs[j].array_id == 0) ||
1247*bbecb9d1SAndroid Build Coastguard Worker               (ctx->inputs[j].array_id  == decl->Array.ArrayID))) {
1248*bbecb9d1SAndroid Build Coastguard Worker             return true;
1249*bbecb9d1SAndroid Build Coastguard Worker          }
1250*bbecb9d1SAndroid Build Coastguard Worker       }
1251*bbecb9d1SAndroid Build Coastguard Worker 
1252*bbecb9d1SAndroid Build Coastguard Worker       i = ctx->num_inputs++;
1253*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) {
1254*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "Number of inputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->inputs));
1255*bbecb9d1SAndroid Build Coastguard Worker          return false;
1256*bbecb9d1SAndroid Build Coastguard Worker       }
1257*bbecb9d1SAndroid Build Coastguard Worker 
1258*bbecb9d1SAndroid Build Coastguard Worker       if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
1259*bbecb9d1SAndroid Build Coastguard Worker          ctx->attrib_input_mask |= (1 << decl->Range.First);
1260*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].type = get_type(ctx->key->vs.attrib_signed_int_bitmask,
1261*bbecb9d1SAndroid Build Coastguard Worker                                         ctx->key->vs.attrib_unsigned_int_bitmask,
1262*bbecb9d1SAndroid Build Coastguard Worker                                         decl->Range.First);
1263*bbecb9d1SAndroid Build Coastguard Worker       }
1264*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].name = decl->Semantic.Name;
1265*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].sid = decl->Semantic.Index;
1266*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].interpolate = decl->Interp.Interpolate;
1267*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].location = decl->Interp.Location;
1268*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].first = decl->Range.First;
1269*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].last = decl->Range.Last;
1270*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].array_id = decl->Declaration.Array ? decl->Array.ArrayID : 0;
1271*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].usage_mask = decl->Declaration.UsageMask;
1272*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].num_components = 4;
1273*bbecb9d1SAndroid Build Coastguard Worker 
1274*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].glsl_predefined_no_emit = false;
1275*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].glsl_no_index = false;
1276*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].override_no_wm = ctx->inputs[i].num_components == 1;
1277*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].glsl_gl_block = false;
1278*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].overlapping_array = NULL;
1279*bbecb9d1SAndroid Build Coastguard Worker 
1280*bbecb9d1SAndroid Build Coastguard Worker       if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1281*bbecb9d1SAndroid Build Coastguard Worker          if (decl->Interp.Location == TGSI_INTERPOLATE_LOC_SAMPLE) {
1282*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
1283*bbecb9d1SAndroid Build Coastguard Worker             ctx->has_sample_input = true;
1284*bbecb9d1SAndroid Build Coastguard Worker          }
1285*bbecb9d1SAndroid Build Coastguard Worker          if (decl->Interp.Interpolate == TGSI_INTERPOLATE_LINEAR && ctx->cfg->use_gles &&
1286*bbecb9d1SAndroid Build Coastguard Worker              ctx->cfg->has_nopersective) {
1287*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_SHADER_NOPERSPECTIVE_INTERPOLATION;
1288*bbecb9d1SAndroid Build Coastguard Worker             ctx->has_noperspective = true;
1289*bbecb9d1SAndroid Build Coastguard Worker          }
1290*bbecb9d1SAndroid Build Coastguard Worker       }
1291*bbecb9d1SAndroid Build Coastguard Worker 
1292*bbecb9d1SAndroid Build Coastguard Worker       map_overlapping_io_array(ctx->inputs, &ctx->inputs[i], ctx->num_inputs, decl);
1293*bbecb9d1SAndroid Build Coastguard Worker 
1294*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->inputs[i].glsl_predefined_no_emit) {
1295*bbecb9d1SAndroid Build Coastguard Worker 
1296*bbecb9d1SAndroid Build Coastguard Worker          /* If the output of the previous shader contained arrays we
1297*bbecb9d1SAndroid Build Coastguard Worker           * have to check whether a non-array input here should be part
1298*bbecb9d1SAndroid Build Coastguard Worker           * of an array */
1299*bbecb9d1SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < ctx->key->in_arrays.num_arrays; j++) {
1300*bbecb9d1SAndroid Build Coastguard Worker             const struct vrend_shader_io_array *array = &ctx->key->in_arrays.layout[j];
1301*bbecb9d1SAndroid Build Coastguard Worker 
1302*bbecb9d1SAndroid Build Coastguard Worker             if (array->name == decl->Semantic.Name &&
1303*bbecb9d1SAndroid Build Coastguard Worker                 array->sid <= decl->Semantic.Index &&
1304*bbecb9d1SAndroid Build Coastguard Worker                 array->sid + array->size >= decl->Semantic.Index) {
1305*bbecb9d1SAndroid Build Coastguard Worker                ctx->inputs[i].sid = array->sid;
1306*bbecb9d1SAndroid Build Coastguard Worker                ctx->inputs[i].last = MAX2(ctx->inputs[i].first + array->size, ctx->inputs[i].last);
1307*bbecb9d1SAndroid Build Coastguard Worker                break;
1308*bbecb9d1SAndroid Build Coastguard Worker             }
1309*bbecb9d1SAndroid Build Coastguard Worker          }
1310*bbecb9d1SAndroid Build Coastguard Worker       }
1311*bbecb9d1SAndroid Build Coastguard Worker 
1312*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->inputs[i].first != ctx->inputs[i].last)
1313*bbecb9d1SAndroid Build Coastguard Worker          ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
1314*bbecb9d1SAndroid Build Coastguard Worker 
1315*bbecb9d1SAndroid Build Coastguard Worker       name_prefix = get_stage_input_name_prefix(ctx, iter->processor.Processor);
1316*bbecb9d1SAndroid Build Coastguard Worker 
1317*bbecb9d1SAndroid Build Coastguard Worker       switch (ctx->inputs[i].name) {
1318*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_COLOR:
1319*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1320*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->glsl_ver_required < 140) {
1321*bbecb9d1SAndroid Build Coastguard Worker                if (decl->Semantic.Index == 0)
1322*bbecb9d1SAndroid Build Coastguard Worker                   name_prefix = "gl_Color";
1323*bbecb9d1SAndroid Build Coastguard Worker                else if (decl->Semantic.Index == 1)
1324*bbecb9d1SAndroid Build Coastguard Worker                   name_prefix = "gl_SecondaryColor";
1325*bbecb9d1SAndroid Build Coastguard Worker                else
1326*bbecb9d1SAndroid Build Coastguard Worker                   vrend_printf( "got illegal color semantic index %d\n", decl->Semantic.Index);
1327*bbecb9d1SAndroid Build Coastguard Worker                ctx->inputs[i].glsl_no_index = true;
1328*bbecb9d1SAndroid Build Coastguard Worker             } else {
1329*bbecb9d1SAndroid Build Coastguard Worker                if (ctx->key->color_two_side) {
1330*bbecb9d1SAndroid Build Coastguard Worker                   int j = ctx->num_inputs++;
1331*bbecb9d1SAndroid Build Coastguard Worker                   if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) {
1332*bbecb9d1SAndroid Build Coastguard Worker                      vrend_printf( "Number of inputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->inputs));
1333*bbecb9d1SAndroid Build Coastguard Worker                      return false;
1334*bbecb9d1SAndroid Build Coastguard Worker                   }
1335*bbecb9d1SAndroid Build Coastguard Worker 
1336*bbecb9d1SAndroid Build Coastguard Worker                   ctx->inputs[j].name = TGSI_SEMANTIC_BCOLOR;
1337*bbecb9d1SAndroid Build Coastguard Worker                   ctx->inputs[j].sid = decl->Semantic.Index;
1338*bbecb9d1SAndroid Build Coastguard Worker                   ctx->inputs[j].interpolate = decl->Interp.Interpolate;
1339*bbecb9d1SAndroid Build Coastguard Worker                   ctx->inputs[j].location = decl->Interp.Location;
1340*bbecb9d1SAndroid Build Coastguard Worker                   ctx->inputs[j].first = decl->Range.First;
1341*bbecb9d1SAndroid Build Coastguard Worker                   ctx->inputs[j].last = decl->Range.Last;
1342*bbecb9d1SAndroid Build Coastguard Worker                   ctx->inputs[j].glsl_predefined_no_emit = false;
1343*bbecb9d1SAndroid Build Coastguard Worker                   ctx->inputs[j].glsl_no_index = false;
1344*bbecb9d1SAndroid Build Coastguard Worker                   ctx->inputs[j].override_no_wm = false;
1345*bbecb9d1SAndroid Build Coastguard Worker 
1346*bbecb9d1SAndroid Build Coastguard Worker                   ctx->color_in_mask |= (1 << decl->Semantic.Index);
1347*bbecb9d1SAndroid Build Coastguard Worker 
1348*bbecb9d1SAndroid Build Coastguard Worker                   if (ctx->front_face_emitted == false) {
1349*bbecb9d1SAndroid Build Coastguard Worker                      int k = ctx->num_inputs++;
1350*bbecb9d1SAndroid Build Coastguard Worker                      if (ctx->num_inputs >= ARRAY_SIZE(ctx->inputs)) {
1351*bbecb9d1SAndroid Build Coastguard Worker                         vrend_printf( "Number of inputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->inputs));
1352*bbecb9d1SAndroid Build Coastguard Worker                         return false;
1353*bbecb9d1SAndroid Build Coastguard Worker                      }
1354*bbecb9d1SAndroid Build Coastguard Worker 
1355*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[k].name = TGSI_SEMANTIC_FACE;
1356*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[k].sid = 0;
1357*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[k].interpolate = TGSI_INTERPOLATE_CONSTANT;
1358*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[k].location = TGSI_INTERPOLATE_LOC_CENTER;
1359*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[k].first = 0;
1360*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[k].override_no_wm = false;
1361*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[k].glsl_predefined_no_emit = true;
1362*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[k].glsl_no_index = true;
1363*bbecb9d1SAndroid Build Coastguard Worker                   }
1364*bbecb9d1SAndroid Build Coastguard Worker                   add_two_side = true;
1365*bbecb9d1SAndroid Build Coastguard Worker                }
1366*bbecb9d1SAndroid Build Coastguard Worker             }
1367*bbecb9d1SAndroid Build Coastguard Worker          }
1368*bbecb9d1SAndroid Build Coastguard Worker          break;
1369*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_PRIMID:
1370*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
1371*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_PrimitiveIDIn";
1372*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_predefined_no_emit = true;
1373*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_no_index = true;
1374*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].override_no_wm = true;
1375*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_INTS;
1376*bbecb9d1SAndroid Build Coastguard Worker          } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1377*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_PrimitiveID";
1378*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_predefined_no_emit = true;
1379*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_no_index = true;
1380*bbecb9d1SAndroid Build Coastguard Worker             ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
1381*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_GEOMETRY_SHADER;
1382*bbecb9d1SAndroid Build Coastguard Worker          }
1383*bbecb9d1SAndroid Build Coastguard Worker          break;
1384*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_VIEWPORT_INDEX:
1385*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1386*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_predefined_no_emit = true;
1387*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_no_index = true;
1388*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].is_int = true;
1389*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].type = VEC_INT;
1390*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].override_no_wm = true;
1391*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_ViewportIndex";
1392*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->glsl_ver_required >= 140)
1393*bbecb9d1SAndroid Build Coastguard Worker                ctx->shader_req_bits |= SHADER_REQ_LAYER;
1394*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->cfg->use_gles)
1395*bbecb9d1SAndroid Build Coastguard Worker                ctx->shader_req_bits |= SHADER_REQ_VIEWPORT_IDX;
1396*bbecb9d1SAndroid Build Coastguard Worker          }
1397*bbecb9d1SAndroid Build Coastguard Worker          break;
1398*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_LAYER:
1399*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1400*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_Layer";
1401*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_predefined_no_emit = true;
1402*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_no_index = true;
1403*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].is_int = true;
1404*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].type = VEC_INT;
1405*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].override_no_wm = true;
1406*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_LAYER;
1407*bbecb9d1SAndroid Build Coastguard Worker          }
1408*bbecb9d1SAndroid Build Coastguard Worker          break;
1409*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_PSIZE:
1410*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
1411*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
1412*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
1413*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_PointSize";
1414*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_predefined_no_emit = true;
1415*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_no_index = true;
1416*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].override_no_wm = true;
1417*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_gl_block = true;
1418*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_PSIZE;
1419*bbecb9d1SAndroid Build Coastguard Worker             ctx->has_pointsize_input = true;
1420*bbecb9d1SAndroid Build Coastguard Worker          }
1421*bbecb9d1SAndroid Build Coastguard Worker          break;
1422*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_CLIPDIST:
1423*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
1424*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
1425*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
1426*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_ClipDistance";
1427*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_predefined_no_emit = true;
1428*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_no_index = true;
1429*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_gl_block = true;
1430*bbecb9d1SAndroid Build Coastguard Worker             ctx->num_in_clip_dist += 4 * (ctx->inputs[i].last - ctx->inputs[i].first + 1);
1431*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_CLIP_DISTANCE;
1432*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->inputs[i].last != ctx->inputs[i].first)
1433*bbecb9d1SAndroid Build Coastguard Worker                ctx->guest_sent_io_arrays = true;
1434*bbecb9d1SAndroid Build Coastguard Worker          } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1435*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_ClipDistance";
1436*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_predefined_no_emit = true;
1437*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_no_index = true;
1438*bbecb9d1SAndroid Build Coastguard Worker             ctx->num_in_clip_dist += 4 * (ctx->inputs[i].last - ctx->inputs[i].first + 1);
1439*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_CLIP_DISTANCE;
1440*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->inputs[i].last != ctx->inputs[i].first)
1441*bbecb9d1SAndroid Build Coastguard Worker                ctx->guest_sent_io_arrays = true;
1442*bbecb9d1SAndroid Build Coastguard Worker          }
1443*bbecb9d1SAndroid Build Coastguard Worker          break;
1444*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_POSITION:
1445*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
1446*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
1447*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
1448*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_Position";
1449*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_predefined_no_emit = true;
1450*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_no_index = true;
1451*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_gl_block = true;
1452*bbecb9d1SAndroid Build Coastguard Worker          } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1453*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->cfg->use_gles && ctx->fs_integer_pixel_center) {
1454*bbecb9d1SAndroid Build Coastguard Worker                name_prefix = "(gl_FragCoord - vec4(0.5, 0.5, 0.0, 0.0))";
1455*bbecb9d1SAndroid Build Coastguard Worker             } else
1456*bbecb9d1SAndroid Build Coastguard Worker                name_prefix = "gl_FragCoord";
1457*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_predefined_no_emit = true;
1458*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_no_index = true;
1459*bbecb9d1SAndroid Build Coastguard Worker          }
1460*bbecb9d1SAndroid Build Coastguard Worker          break;
1461*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_FACE:
1462*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1463*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->front_face_emitted) {
1464*bbecb9d1SAndroid Build Coastguard Worker                ctx->num_inputs--;
1465*bbecb9d1SAndroid Build Coastguard Worker                return true;
1466*bbecb9d1SAndroid Build Coastguard Worker             }
1467*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_FrontFacing";
1468*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_predefined_no_emit = true;
1469*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_no_index = true;
1470*bbecb9d1SAndroid Build Coastguard Worker             ctx->front_face_emitted = true;
1471*bbecb9d1SAndroid Build Coastguard Worker          }
1472*bbecb9d1SAndroid Build Coastguard Worker          break;
1473*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_PCOORD:
1474*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1475*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->cfg->use_gles) {
1476*bbecb9d1SAndroid Build Coastguard Worker                name_prefix = "vec4(gl_PointCoord.x, mix(1.0 - gl_PointCoord.y, gl_PointCoord.y, clamp(winsys_adjust_y, 0.0, 1.0)), 0.0, 1.0)";
1477*bbecb9d1SAndroid Build Coastguard Worker                ctx->glsl_strbufs.required_sysval_uniform_decls |= BIT(UNIFORM_WINSYS_ADJUST_Y);
1478*bbecb9d1SAndroid Build Coastguard Worker             } else
1479*bbecb9d1SAndroid Build Coastguard Worker                name_prefix = "vec4(gl_PointCoord, 0.0, 1.0)";
1480*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_predefined_no_emit = true;
1481*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].glsl_no_index = true;
1482*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].num_components = 4;
1483*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].usage_mask = 0xf;
1484*bbecb9d1SAndroid Build Coastguard Worker          }
1485*bbecb9d1SAndroid Build Coastguard Worker          break;
1486*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_PATCH:
1487*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL)
1488*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "patch";
1489*bbecb9d1SAndroid Build Coastguard Worker          /* fallthrough */
1490*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_GENERIC:
1491*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_TEXCOORD:
1492*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1493*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->key->fs.coord_replace & (1 << ctx->inputs[i].sid)) {
1494*bbecb9d1SAndroid Build Coastguard Worker                if (ctx->cfg->use_gles) {
1495*bbecb9d1SAndroid Build Coastguard Worker                   name_prefix = "vec4(gl_PointCoord.x, mix(1.0 - gl_PointCoord.y, gl_PointCoord.y, clamp(winsys_adjust_y, 0.0, 1.0)), 0.0, 1.0)";
1496*bbecb9d1SAndroid Build Coastguard Worker                   ctx->glsl_strbufs.required_sysval_uniform_decls |= BIT(UNIFORM_WINSYS_ADJUST_Y);
1497*bbecb9d1SAndroid Build Coastguard Worker                } else
1498*bbecb9d1SAndroid Build Coastguard Worker                   name_prefix = "vec4(gl_PointCoord, 0.0, 1.0)";
1499*bbecb9d1SAndroid Build Coastguard Worker                ctx->inputs[i].glsl_predefined_no_emit = true;
1500*bbecb9d1SAndroid Build Coastguard Worker                ctx->inputs[i].glsl_no_index = true;
1501*bbecb9d1SAndroid Build Coastguard Worker                ctx->inputs[i].num_components = 4;
1502*bbecb9d1SAndroid Build Coastguard Worker                ctx->inputs[i].usage_mask = 0xf;
1503*bbecb9d1SAndroid Build Coastguard Worker                break;
1504*bbecb9d1SAndroid Build Coastguard Worker             }
1505*bbecb9d1SAndroid Build Coastguard Worker          }
1506*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[i].first != ctx->inputs[i].last ||
1507*bbecb9d1SAndroid Build Coastguard Worker              ctx->inputs[i].array_id > 0) {
1508*bbecb9d1SAndroid Build Coastguard Worker             ctx->guest_sent_io_arrays = true;
1509*bbecb9d1SAndroid Build Coastguard Worker             if (!ctx->cfg->use_gles &&
1510*bbecb9d1SAndroid Build Coastguard Worker                 (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
1511*bbecb9d1SAndroid Build Coastguard Worker                  ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
1512*bbecb9d1SAndroid Build Coastguard Worker                  ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL)) {
1513*bbecb9d1SAndroid Build Coastguard Worker                ctx->shader_req_bits |= SHADER_REQ_ARRAYS_OF_ARRAYS;
1514*bbecb9d1SAndroid Build Coastguard Worker             }
1515*bbecb9d1SAndroid Build Coastguard Worker          }
1516*bbecb9d1SAndroid Build Coastguard Worker          break;
1517*bbecb9d1SAndroid Build Coastguard Worker       default:
1518*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf("unhandled input semantic: %x\n", ctx->inputs[i].name);
1519*bbecb9d1SAndroid Build Coastguard Worker          break;
1520*bbecb9d1SAndroid Build Coastguard Worker       }
1521*bbecb9d1SAndroid Build Coastguard Worker 
1522*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->inputs[i].glsl_no_index)
1523*bbecb9d1SAndroid Build Coastguard Worker          snprintf(ctx->inputs[i].glsl_name, 128, "%s", name_prefix);
1524*bbecb9d1SAndroid Build Coastguard Worker       else {
1525*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[i].name == TGSI_SEMANTIC_FOG){
1526*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].usage_mask = 0xf;
1527*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].num_components = 4;
1528*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].override_no_wm = false;
1529*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i].glsl_name, 128, "%s_f%d", name_prefix, ctx->inputs[i].sid);
1530*bbecb9d1SAndroid Build Coastguard Worker          } else if (ctx->inputs[i].name == TGSI_SEMANTIC_COLOR)
1531*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i].glsl_name, 128, "%s_c%d", name_prefix, ctx->inputs[i].sid);
1532*bbecb9d1SAndroid Build Coastguard Worker          else if (ctx->inputs[i].name == TGSI_SEMANTIC_BCOLOR)
1533*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i].glsl_name, 128, "%s_bc%d", name_prefix, ctx->inputs[i].sid);
1534*bbecb9d1SAndroid Build Coastguard Worker          else if (ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC)
1535*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i].glsl_name, 128, "%s_g%d", name_prefix, ctx->inputs[i].sid);
1536*bbecb9d1SAndroid Build Coastguard Worker          else if (ctx->inputs[i].name == TGSI_SEMANTIC_PATCH)
1537*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i].glsl_name, 128, "%s%d", name_prefix, ctx->inputs[i].sid);
1538*bbecb9d1SAndroid Build Coastguard Worker          else if (ctx->inputs[i].name == TGSI_SEMANTIC_TEXCOORD)
1539*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i].glsl_name, 64, "%s_t%d", name_prefix, ctx->inputs[i].sid);
1540*bbecb9d1SAndroid Build Coastguard Worker          else
1541*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i].glsl_name, 128, "%s_%d", name_prefix, ctx->inputs[i].first);
1542*bbecb9d1SAndroid Build Coastguard Worker       }
1543*bbecb9d1SAndroid Build Coastguard Worker       if (add_two_side) {
1544*bbecb9d1SAndroid Build Coastguard Worker          snprintf(ctx->inputs[i + 1].glsl_name, 128, "%s_bc%d", name_prefix, ctx->inputs[i + 1].sid);
1545*bbecb9d1SAndroid Build Coastguard Worker          if (!ctx->front_face_emitted) {
1546*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i + 2].glsl_name, 128, "%s", "gl_FrontFacing");
1547*bbecb9d1SAndroid Build Coastguard Worker             ctx->front_face_emitted = true;
1548*bbecb9d1SAndroid Build Coastguard Worker          }
1549*bbecb9d1SAndroid Build Coastguard Worker       }
1550*bbecb9d1SAndroid Build Coastguard Worker       break;
1551*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_OUTPUT:
1552*bbecb9d1SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < ctx->num_outputs; j++) {
1553*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->outputs[j].name == decl->Semantic.Name &&
1554*bbecb9d1SAndroid Build Coastguard Worker              ctx->outputs[j].sid == decl->Semantic.Index &&
1555*bbecb9d1SAndroid Build Coastguard Worker              ctx->outputs[j].first == decl->Range.First &&
1556*bbecb9d1SAndroid Build Coastguard Worker              ((!decl->Declaration.Array && ctx->outputs[j].array_id == 0) ||
1557*bbecb9d1SAndroid Build Coastguard Worker               (ctx->outputs[j].array_id  == decl->Array.ArrayID)))
1558*bbecb9d1SAndroid Build Coastguard Worker             return true;
1559*bbecb9d1SAndroid Build Coastguard Worker       }
1560*bbecb9d1SAndroid Build Coastguard Worker       i = ctx->num_outputs++;
1561*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->num_outputs > ARRAY_SIZE(ctx->outputs)) {
1562*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "Number of outputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->outputs));
1563*bbecb9d1SAndroid Build Coastguard Worker          return false;
1564*bbecb9d1SAndroid Build Coastguard Worker       }
1565*bbecb9d1SAndroid Build Coastguard Worker 
1566*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].name = decl->Semantic.Name;
1567*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].sid = decl->Semantic.Index;
1568*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].interpolate = decl->Interp.Interpolate;
1569*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].invariant = decl->Declaration.Invariant;
1570*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].precise = false;
1571*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].first = decl->Range.First;
1572*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].last = decl->Range.Last;
1573*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].array_id = decl->Declaration.Array ? decl->Array.ArrayID : 0;
1574*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].usage_mask = decl->Declaration.UsageMask;
1575*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].num_components = 4;
1576*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].glsl_predefined_no_emit = false;
1577*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].glsl_no_index = false;
1578*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].override_no_wm = ctx->outputs[i].num_components == 1;
1579*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].is_int = false;
1580*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].fbfetch_used = false;
1581*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[i].overlapping_array = NULL;
1582*bbecb9d1SAndroid Build Coastguard Worker 
1583*bbecb9d1SAndroid Build Coastguard Worker       map_overlapping_io_array(ctx->outputs, &ctx->outputs[i], ctx->num_outputs, decl);
1584*bbecb9d1SAndroid Build Coastguard Worker 
1585*bbecb9d1SAndroid Build Coastguard Worker       name_prefix = get_stage_output_name_prefix(iter->processor.Processor);
1586*bbecb9d1SAndroid Build Coastguard Worker 
1587*bbecb9d1SAndroid Build Coastguard Worker       switch (ctx->outputs[i].name) {
1588*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_POSITION:
1589*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX ||
1590*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
1591*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
1592*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
1593*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->outputs[i].first > 0)
1594*bbecb9d1SAndroid Build Coastguard Worker                vrend_printf("Illegal position input\n");
1595*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_Position";
1596*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_predefined_no_emit = true;
1597*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1598*bbecb9d1SAndroid Build Coastguard Worker             if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL)
1599*bbecb9d1SAndroid Build Coastguard Worker                ctx->outputs[i].glsl_gl_block = true;
1600*bbecb9d1SAndroid Build Coastguard Worker          } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1601*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_FragDepth";
1602*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_predefined_no_emit = true;
1603*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1604*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].override_no_wm = true;
1605*bbecb9d1SAndroid Build Coastguard Worker          }
1606*bbecb9d1SAndroid Build Coastguard Worker          break;
1607*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_STENCIL:
1608*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1609*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_FragStencilRefARB";
1610*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_predefined_no_emit = true;
1611*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1612*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].override_no_wm = true;
1613*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].is_int = true;
1614*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_STENCIL_EXPORT);
1615*bbecb9d1SAndroid Build Coastguard Worker          }
1616*bbecb9d1SAndroid Build Coastguard Worker          break;
1617*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_CLIPDIST:
1618*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_CLIP_DISTANCE;
1619*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_ClipDistance";
1620*bbecb9d1SAndroid Build Coastguard Worker          ctx->outputs[i].glsl_predefined_no_emit = true;
1621*bbecb9d1SAndroid Build Coastguard Worker          ctx->outputs[i].glsl_no_index = true;
1622*bbecb9d1SAndroid Build Coastguard Worker          ctx->num_out_clip_dist += 4 * (ctx->outputs[i].last - ctx->outputs[i].first + 1);
1623*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX &&
1624*bbecb9d1SAndroid Build Coastguard Worker              (ctx->key->gs_present || ctx->key->tcs_present))
1625*bbecb9d1SAndroid Build Coastguard Worker             ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
1626*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL)
1627*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_gl_block = true;
1628*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->outputs[i].last != ctx->outputs[i].first)
1629*bbecb9d1SAndroid Build Coastguard Worker             ctx->guest_sent_io_arrays = true;
1630*bbecb9d1SAndroid Build Coastguard Worker          break;
1631*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_CLIPVERTEX:
1632*bbecb9d1SAndroid Build Coastguard Worker          ctx->outputs[i].override_no_wm = true;
1633*bbecb9d1SAndroid Build Coastguard Worker          ctx->outputs[i].invariant = false;
1634*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->glsl_ver_required >= 140) {
1635*bbecb9d1SAndroid Build Coastguard Worker             ctx->has_clipvertex = true;
1636*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = get_stage_output_name_prefix(iter->processor.Processor);
1637*bbecb9d1SAndroid Build Coastguard Worker          } else {
1638*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_ClipVertex";
1639*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_predefined_no_emit = true;
1640*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1641*bbecb9d1SAndroid Build Coastguard Worker          }
1642*bbecb9d1SAndroid Build Coastguard Worker          break;
1643*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_SAMPLEMASK:
1644*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1645*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_predefined_no_emit = true;
1646*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1647*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].override_no_wm = true;
1648*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].is_int = true;
1649*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_SAMPLE_SHADING);
1650*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_SampleMask";
1651*bbecb9d1SAndroid Build Coastguard Worker             break;
1652*bbecb9d1SAndroid Build Coastguard Worker          }
1653*bbecb9d1SAndroid Build Coastguard Worker          break;
1654*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_COLOR:
1655*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
1656*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].type = get_type(ctx->key->fs.cbufs_signed_int_bitmask,
1657*bbecb9d1SAndroid Build Coastguard Worker                                             ctx->key->fs.cbufs_unsigned_int_bitmask,
1658*bbecb9d1SAndroid Build Coastguard Worker                                             ctx->outputs[i].sid);
1659*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = ctx->key->fs.logicop_enabled ? "fsout_tmp" : "fsout";
1660*bbecb9d1SAndroid Build Coastguard Worker          } else {
1661*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->glsl_ver_required < 140) {
1662*bbecb9d1SAndroid Build Coastguard Worker                ctx->outputs[i].glsl_no_index = true;
1663*bbecb9d1SAndroid Build Coastguard Worker                if (ctx->outputs[i].sid == 0)
1664*bbecb9d1SAndroid Build Coastguard Worker                   name_prefix = "gl_FrontColor";
1665*bbecb9d1SAndroid Build Coastguard Worker                else if (ctx->outputs[i].sid == 1)
1666*bbecb9d1SAndroid Build Coastguard Worker                   name_prefix = "gl_FrontSecondaryColor";
1667*bbecb9d1SAndroid Build Coastguard Worker             } else {
1668*bbecb9d1SAndroid Build Coastguard Worker                       ctx->color_out_mask |= (1 << decl->Semantic.Index);
1669*bbecb9d1SAndroid Build Coastguard Worker             }
1670*bbecb9d1SAndroid Build Coastguard Worker          }
1671*bbecb9d1SAndroid Build Coastguard Worker          ctx->outputs[i].override_no_wm = false;
1672*bbecb9d1SAndroid Build Coastguard Worker          break;
1673*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_BCOLOR:
1674*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->glsl_ver_required < 140) {
1675*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1676*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->outputs[i].sid == 0)
1677*bbecb9d1SAndroid Build Coastguard Worker                name_prefix = "gl_BackColor";
1678*bbecb9d1SAndroid Build Coastguard Worker             else if (ctx->outputs[i].sid == 1)
1679*bbecb9d1SAndroid Build Coastguard Worker                name_prefix = "gl_BackSecondaryColor";
1680*bbecb9d1SAndroid Build Coastguard Worker          } else {
1681*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].override_no_wm = false;
1682*bbecb9d1SAndroid Build Coastguard Worker             ctx->color_out_mask |= (1 << decl->Semantic.Index) << 2;
1683*bbecb9d1SAndroid Build Coastguard Worker          }
1684*bbecb9d1SAndroid Build Coastguard Worker          break;
1685*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_PSIZE:
1686*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX ||
1687*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
1688*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
1689*bbecb9d1SAndroid Build Coastguard Worker              iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
1690*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_predefined_no_emit = true;
1691*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1692*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].override_no_wm = true;
1693*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_PSIZE;
1694*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_PointSize";
1695*bbecb9d1SAndroid Build Coastguard Worker             ctx->has_pointsize_output = true;
1696*bbecb9d1SAndroid Build Coastguard Worker             if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL)
1697*bbecb9d1SAndroid Build Coastguard Worker                ctx->outputs[i].glsl_gl_block = true;
1698*bbecb9d1SAndroid Build Coastguard Worker          }
1699*bbecb9d1SAndroid Build Coastguard Worker          break;
1700*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_LAYER:
1701*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
1702*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_predefined_no_emit = true;
1703*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1704*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].override_no_wm = true;
1705*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].is_int = true;
1706*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_Layer";
1707*bbecb9d1SAndroid Build Coastguard Worker          }
1708*bbecb9d1SAndroid Build Coastguard Worker          break;
1709*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_PRIMID:
1710*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
1711*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_predefined_no_emit = true;
1712*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1713*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].override_no_wm = true;
1714*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].is_int = true;
1715*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_PrimitiveID";
1716*bbecb9d1SAndroid Build Coastguard Worker          }
1717*bbecb9d1SAndroid Build Coastguard Worker          break;
1718*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_VIEWPORT_INDEX:
1719*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
1720*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_predefined_no_emit = true;
1721*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1722*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].override_no_wm = true;
1723*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].is_int = true;
1724*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_ViewportIndex";
1725*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->glsl_ver_required >= 140 || ctx->cfg->use_gles)
1726*bbecb9d1SAndroid Build Coastguard Worker                ctx->shader_req_bits |= SHADER_REQ_VIEWPORT_IDX;
1727*bbecb9d1SAndroid Build Coastguard Worker          }
1728*bbecb9d1SAndroid Build Coastguard Worker          break;
1729*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_TESSOUTER:
1730*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL) {
1731*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_predefined_no_emit = true;
1732*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1733*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].override_no_wm = true;
1734*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_TessLevelOuter";
1735*bbecb9d1SAndroid Build Coastguard Worker          }
1736*bbecb9d1SAndroid Build Coastguard Worker          break;
1737*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_TESSINNER:
1738*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL) {
1739*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_predefined_no_emit = true;
1740*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].glsl_no_index = true;
1741*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].override_no_wm = true;
1742*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "gl_TessLevelInner";
1743*bbecb9d1SAndroid Build Coastguard Worker          }
1744*bbecb9d1SAndroid Build Coastguard Worker          break;
1745*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_PATCH:
1746*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL)
1747*bbecb9d1SAndroid Build Coastguard Worker             name_prefix = "patch";
1748*bbecb9d1SAndroid Build Coastguard Worker          /* fallthrough */
1749*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_GENERIC:
1750*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_TEXCOORD:
1751*bbecb9d1SAndroid Build Coastguard Worker          if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX)
1752*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC)
1753*bbecb9d1SAndroid Build Coastguard Worker                color_offset = -1;
1754*bbecb9d1SAndroid Build Coastguard Worker 
1755*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->outputs[i].first != ctx->outputs[i].last ||
1756*bbecb9d1SAndroid Build Coastguard Worker              ctx->outputs[i].array_id > 0) {
1757*bbecb9d1SAndroid Build Coastguard Worker             ctx->guest_sent_io_arrays = true;
1758*bbecb9d1SAndroid Build Coastguard Worker 
1759*bbecb9d1SAndroid Build Coastguard Worker             if (!ctx->cfg->use_gles &&
1760*bbecb9d1SAndroid Build Coastguard Worker                 (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
1761*bbecb9d1SAndroid Build Coastguard Worker                  ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
1762*bbecb9d1SAndroid Build Coastguard Worker                  ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL)) {
1763*bbecb9d1SAndroid Build Coastguard Worker                ctx->shader_req_bits |= SHADER_REQ_ARRAYS_OF_ARRAYS;
1764*bbecb9d1SAndroid Build Coastguard Worker             }
1765*bbecb9d1SAndroid Build Coastguard Worker          }
1766*bbecb9d1SAndroid Build Coastguard Worker          break;
1767*bbecb9d1SAndroid Build Coastguard Worker       default:
1768*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf("unhandled output semantic: %x\n", ctx->outputs[i].name);
1769*bbecb9d1SAndroid Build Coastguard Worker          break;
1770*bbecb9d1SAndroid Build Coastguard Worker       }
1771*bbecb9d1SAndroid Build Coastguard Worker 
1772*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->outputs[i].glsl_no_index)
1773*bbecb9d1SAndroid Build Coastguard Worker          snprintf(ctx->outputs[i].glsl_name, 64, "%s", name_prefix);
1774*bbecb9d1SAndroid Build Coastguard Worker       else {
1775*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->outputs[i].name == TGSI_SEMANTIC_FOG) {
1776*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].usage_mask = 0xf;
1777*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].num_components = 4;
1778*bbecb9d1SAndroid Build Coastguard Worker             ctx->outputs[i].override_no_wm = false;
1779*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->outputs[i].glsl_name, 64, "%s_f%d", name_prefix, ctx->outputs[i].sid);
1780*bbecb9d1SAndroid Build Coastguard Worker          } else if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR)
1781*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->outputs[i].glsl_name, 64, "%s_c%d", name_prefix, ctx->outputs[i].sid);
1782*bbecb9d1SAndroid Build Coastguard Worker          else if (ctx->outputs[i].name == TGSI_SEMANTIC_BCOLOR)
1783*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->outputs[i].glsl_name, 64, "%s_bc%d", name_prefix, ctx->outputs[i].sid);
1784*bbecb9d1SAndroid Build Coastguard Worker          else if (ctx->outputs[i].name == TGSI_SEMANTIC_PATCH)
1785*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->outputs[i].glsl_name, 64, "%s%d", name_prefix, ctx->outputs[i].sid);
1786*bbecb9d1SAndroid Build Coastguard Worker          else if (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC)
1787*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->outputs[i].glsl_name, 64, "%s_g%d", name_prefix, ctx->outputs[i].sid);
1788*bbecb9d1SAndroid Build Coastguard Worker          else if (ctx->outputs[i].name == TGSI_SEMANTIC_TEXCOORD)
1789*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->outputs[i].glsl_name, 64, "%s_t%d", name_prefix, ctx->outputs[i].sid);
1790*bbecb9d1SAndroid Build Coastguard Worker          else
1791*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->outputs[i].glsl_name, 64, "%s_%d", name_prefix, ctx->outputs[i].first + color_offset);
1792*bbecb9d1SAndroid Build Coastguard Worker 
1793*bbecb9d1SAndroid Build Coastguard Worker       }
1794*bbecb9d1SAndroid Build Coastguard Worker       break;
1795*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_TEMPORARY:
1796*bbecb9d1SAndroid Build Coastguard Worker       if (!allocate_temp_range(&ctx->temp_ranges, &ctx->num_temp_ranges, decl->Range.First, decl->Range.Last,
1797*bbecb9d1SAndroid Build Coastguard Worker                                decl->Array.ArrayID))
1798*bbecb9d1SAndroid Build Coastguard Worker          return false;
1799*bbecb9d1SAndroid Build Coastguard Worker       break;
1800*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_SAMPLER:
1801*bbecb9d1SAndroid Build Coastguard Worker       ctx->samplers_used |= (1 << decl->Range.Last);
1802*bbecb9d1SAndroid Build Coastguard Worker       break;
1803*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_SAMPLER_VIEW:
1804*bbecb9d1SAndroid Build Coastguard Worker       if (decl->Range.Last >= ARRAY_SIZE(ctx->samplers)) {
1805*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "Sampler view exceeded, max is %lu\n", ARRAY_SIZE(ctx->samplers));
1806*bbecb9d1SAndroid Build Coastguard Worker          return false;
1807*bbecb9d1SAndroid Build Coastguard Worker       }
1808*bbecb9d1SAndroid Build Coastguard Worker       if (!add_samplers(ctx, decl->Range.First, decl->Range.Last, decl->SamplerView.Resource, decl->SamplerView.ReturnTypeX))
1809*bbecb9d1SAndroid Build Coastguard Worker          return false;
1810*bbecb9d1SAndroid Build Coastguard Worker       break;
1811*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_IMAGE:
1812*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_IMAGE_LOAD_STORE;
1813*bbecb9d1SAndroid Build Coastguard Worker       if (decl->Range.Last >= ARRAY_SIZE(ctx->images)) {
1814*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "Image view exceeded, max is %lu\n", ARRAY_SIZE(ctx->images));
1815*bbecb9d1SAndroid Build Coastguard Worker          return false;
1816*bbecb9d1SAndroid Build Coastguard Worker       }
1817*bbecb9d1SAndroid Build Coastguard Worker       if (!add_images(ctx, decl->Range.First, decl->Range.Last, &decl->Image))
1818*bbecb9d1SAndroid Build Coastguard Worker          return false;
1819*bbecb9d1SAndroid Build Coastguard Worker       break;
1820*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_BUFFER:
1821*bbecb9d1SAndroid Build Coastguard Worker       if (decl->Range.First >= 32) {
1822*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "Buffer view exceeded, max is 32\n");
1823*bbecb9d1SAndroid Build Coastguard Worker          return false;
1824*bbecb9d1SAndroid Build Coastguard Worker       }
1825*bbecb9d1SAndroid Build Coastguard Worker       ctx->ssbo_used_mask |= (1 << decl->Range.First);
1826*bbecb9d1SAndroid Build Coastguard Worker       if (decl->Declaration.Atomic) {
1827*bbecb9d1SAndroid Build Coastguard Worker          if (decl->Range.First < ctx->ssbo_atomic_array_base)
1828*bbecb9d1SAndroid Build Coastguard Worker             ctx->ssbo_atomic_array_base = decl->Range.First;
1829*bbecb9d1SAndroid Build Coastguard Worker          ctx->ssbo_atomic_mask |= (1 << decl->Range.First);
1830*bbecb9d1SAndroid Build Coastguard Worker       } else {
1831*bbecb9d1SAndroid Build Coastguard Worker          if (decl->Range.First < ctx->ssbo_array_base)
1832*bbecb9d1SAndroid Build Coastguard Worker             ctx->ssbo_array_base = decl->Range.First;
1833*bbecb9d1SAndroid Build Coastguard Worker       }
1834*bbecb9d1SAndroid Build Coastguard Worker       break;
1835*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_CONSTANT:
1836*bbecb9d1SAndroid Build Coastguard Worker       if (decl->Declaration.Dimension && decl->Dim.Index2D != 0) {
1837*bbecb9d1SAndroid Build Coastguard Worker          if (decl->Dim.Index2D > 31) {
1838*bbecb9d1SAndroid Build Coastguard Worker             vrend_printf( "Number of uniforms exceeded, max is 32\n");
1839*bbecb9d1SAndroid Build Coastguard Worker             return false;
1840*bbecb9d1SAndroid Build Coastguard Worker          }
1841*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->ubo_used_mask & (1 << decl->Dim.Index2D)) {
1842*bbecb9d1SAndroid Build Coastguard Worker             vrend_printf( "UBO #%d is already defined\n", decl->Dim.Index2D);
1843*bbecb9d1SAndroid Build Coastguard Worker             return false;
1844*bbecb9d1SAndroid Build Coastguard Worker          }
1845*bbecb9d1SAndroid Build Coastguard Worker          ctx->ubo_used_mask |= (1 << decl->Dim.Index2D);
1846*bbecb9d1SAndroid Build Coastguard Worker          ctx->ubo_sizes[decl->Dim.Index2D] = decl->Range.Last + 1;
1847*bbecb9d1SAndroid Build Coastguard Worker       } else {
1848*bbecb9d1SAndroid Build Coastguard Worker          /* if we have a normal single const set then ubo base should be 1 */
1849*bbecb9d1SAndroid Build Coastguard Worker          ctx->ubo_base = 1;
1850*bbecb9d1SAndroid Build Coastguard Worker          if (decl->Range.Last) {
1851*bbecb9d1SAndroid Build Coastguard Worker             if (decl->Range.Last + 1 > ctx->num_consts)
1852*bbecb9d1SAndroid Build Coastguard Worker                ctx->num_consts = decl->Range.Last + 1;
1853*bbecb9d1SAndroid Build Coastguard Worker          } else
1854*bbecb9d1SAndroid Build Coastguard Worker             ctx->num_consts++;
1855*bbecb9d1SAndroid Build Coastguard Worker       }
1856*bbecb9d1SAndroid Build Coastguard Worker       break;
1857*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_ADDRESS:
1858*bbecb9d1SAndroid Build Coastguard Worker       ctx->num_address = decl->Range.Last + 1;
1859*bbecb9d1SAndroid Build Coastguard Worker       break;
1860*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_SYSTEM_VALUE:
1861*bbecb9d1SAndroid Build Coastguard Worker       i = ctx->num_system_values++;
1862*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->num_system_values > ARRAY_SIZE(ctx->system_values)) {
1863*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "Number of system values exceeded, max is %lu\n", ARRAY_SIZE(ctx->system_values));
1864*bbecb9d1SAndroid Build Coastguard Worker          return false;
1865*bbecb9d1SAndroid Build Coastguard Worker       }
1866*bbecb9d1SAndroid Build Coastguard Worker 
1867*bbecb9d1SAndroid Build Coastguard Worker       ctx->system_values[i].name = decl->Semantic.Name;
1868*bbecb9d1SAndroid Build Coastguard Worker       ctx->system_values[i].sid = decl->Semantic.Index;
1869*bbecb9d1SAndroid Build Coastguard Worker       ctx->system_values[i].glsl_predefined_no_emit = true;
1870*bbecb9d1SAndroid Build Coastguard Worker       ctx->system_values[i].glsl_no_index = true;
1871*bbecb9d1SAndroid Build Coastguard Worker       ctx->system_values[i].override_no_wm = true;
1872*bbecb9d1SAndroid Build Coastguard Worker       ctx->system_values[i].first = decl->Range.First;
1873*bbecb9d1SAndroid Build Coastguard Worker       if (decl->Semantic.Name == TGSI_SEMANTIC_INSTANCEID) {
1874*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_InstanceID";
1875*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_INSTANCE_ID | SHADER_REQ_INTS;
1876*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_VERTEXID) {
1877*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_VertexID";
1878*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_INTS;
1879*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_HELPER_INVOCATION) {
1880*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_HelperInvocation";
1881*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_ES31_COMPAT;
1882*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEID) {
1883*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_SampleID";
1884*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= (SHADER_REQ_SAMPLE_SHADING | SHADER_REQ_INTS);
1885*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEPOS) {
1886*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_SamplePosition";
1887*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_SAMPLE_SHADING;
1888*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_INVOCATIONID) {
1889*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_InvocationID";
1890*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_GPU_SHADER5);
1891*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEMASK) {
1892*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_SampleMaskIn[0]";
1893*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_GPU_SHADER5);
1894*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_PRIMID) {
1895*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_PrimitiveID";
1896*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_GPU_SHADER5);
1897*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_TESSCOORD) {
1898*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_TessCoord";
1899*bbecb9d1SAndroid Build Coastguard Worker          ctx->system_values[i].override_no_wm = false;
1900*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_VERTICESIN) {
1901*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_INTS;
1902*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_PatchVerticesIn";
1903*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_TESSOUTER) {
1904*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_TessLevelOuter";
1905*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_TESSINNER) {
1906*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_TessLevelInner";
1907*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_THREAD_ID) {
1908*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_LocalInvocationID";
1909*bbecb9d1SAndroid Build Coastguard Worker          ctx->system_values[i].override_no_wm = false;
1910*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_BLOCK_ID) {
1911*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_WorkGroupID";
1912*bbecb9d1SAndroid Build Coastguard Worker          ctx->system_values[i].override_no_wm = false;
1913*bbecb9d1SAndroid Build Coastguard Worker       } else if (decl->Semantic.Name == TGSI_SEMANTIC_GRID_SIZE) {
1914*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_NumWorkGroups";
1915*bbecb9d1SAndroid Build Coastguard Worker          ctx->system_values[i].override_no_wm = false;
1916*bbecb9d1SAndroid Build Coastguard Worker       } else {
1917*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "unsupported system value %d\n", decl->Semantic.Name);
1918*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "unknown";
1919*bbecb9d1SAndroid Build Coastguard Worker       }
1920*bbecb9d1SAndroid Build Coastguard Worker       snprintf(ctx->system_values[i].glsl_name, 64, "%s", name_prefix);
1921*bbecb9d1SAndroid Build Coastguard Worker       break;
1922*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_MEMORY:
1923*bbecb9d1SAndroid Build Coastguard Worker       ctx->has_file_memory = true;
1924*bbecb9d1SAndroid Build Coastguard Worker       break;
1925*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_HW_ATOMIC:
1926*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->num_abo >= ARRAY_SIZE(ctx->abo_idx)) {
1927*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "Number of atomic counter buffers exceeded, max is %lu\n", ARRAY_SIZE(ctx->abo_idx));
1928*bbecb9d1SAndroid Build Coastguard Worker          return false;
1929*bbecb9d1SAndroid Build Coastguard Worker       }
1930*bbecb9d1SAndroid Build Coastguard Worker       ctx->abo_idx[ctx->num_abo] = decl->Dim.Index2D;
1931*bbecb9d1SAndroid Build Coastguard Worker       ctx->abo_sizes[ctx->num_abo] = decl->Range.Last - decl->Range.First + 1;
1932*bbecb9d1SAndroid Build Coastguard Worker       ctx->abo_offsets[ctx->num_abo] = decl->Range.First;
1933*bbecb9d1SAndroid Build Coastguard Worker       ctx->num_abo++;
1934*bbecb9d1SAndroid Build Coastguard Worker       break;
1935*bbecb9d1SAndroid Build Coastguard Worker    default:
1936*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf("unsupported file %d declaration\n", decl->Declaration.File);
1937*bbecb9d1SAndroid Build Coastguard Worker       break;
1938*bbecb9d1SAndroid Build Coastguard Worker    }
1939*bbecb9d1SAndroid Build Coastguard Worker 
1940*bbecb9d1SAndroid Build Coastguard Worker    return true;
1941*bbecb9d1SAndroid Build Coastguard Worker }
1942*bbecb9d1SAndroid Build Coastguard Worker 
1943*bbecb9d1SAndroid Build Coastguard Worker static boolean
iter_property(struct tgsi_iterate_context * iter,struct tgsi_full_property * prop)1944*bbecb9d1SAndroid Build Coastguard Worker iter_property(struct tgsi_iterate_context *iter,
1945*bbecb9d1SAndroid Build Coastguard Worker               struct tgsi_full_property *prop)
1946*bbecb9d1SAndroid Build Coastguard Worker {
1947*bbecb9d1SAndroid Build Coastguard Worker    struct dump_ctx *ctx = (struct dump_ctx *) iter;
1948*bbecb9d1SAndroid Build Coastguard Worker 
1949*bbecb9d1SAndroid Build Coastguard Worker    switch (prop->Property.PropertyName) {
1950*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
1951*bbecb9d1SAndroid Build Coastguard Worker       if (prop->u[0].Data == 1)
1952*bbecb9d1SAndroid Build Coastguard Worker          ctx->write_all_cbufs = true;
1953*bbecb9d1SAndroid Build Coastguard Worker       break;
1954*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_FS_COORD_ORIGIN:
1955*bbecb9d1SAndroid Build Coastguard Worker       ctx->fs_lower_left_origin = prop->u[0].Data ? true : false;
1956*bbecb9d1SAndroid Build Coastguard Worker       break;
1957*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
1958*bbecb9d1SAndroid Build Coastguard Worker       ctx->fs_integer_pixel_center = prop->u[0].Data ? true : false;
1959*bbecb9d1SAndroid Build Coastguard Worker       break;
1960*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_FS_DEPTH_LAYOUT:
1961*bbecb9d1SAndroid Build Coastguard Worker       /* If the host doesn't support this, then we can savely ignore this,
1962*bbecb9d1SAndroid Build Coastguard Worker        * we only lost an opportunity to optimize */
1963*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->has_conservative_depth) {
1964*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_CONSERVATIVE_DEPTH;
1965*bbecb9d1SAndroid Build Coastguard Worker          ctx->fs_depth_layout = prop->u[0].Data;
1966*bbecb9d1SAndroid Build Coastguard Worker       }
1967*bbecb9d1SAndroid Build Coastguard Worker       break;
1968*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_GS_INPUT_PRIM:
1969*bbecb9d1SAndroid Build Coastguard Worker       ctx->gs_in_prim = prop->u[0].Data;
1970*bbecb9d1SAndroid Build Coastguard Worker       break;
1971*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_GS_OUTPUT_PRIM:
1972*bbecb9d1SAndroid Build Coastguard Worker       ctx->gs_out_prim = prop->u[0].Data;
1973*bbecb9d1SAndroid Build Coastguard Worker       break;
1974*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES:
1975*bbecb9d1SAndroid Build Coastguard Worker       ctx->gs_max_out_verts = prop->u[0].Data;
1976*bbecb9d1SAndroid Build Coastguard Worker       break;
1977*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_GS_INVOCATIONS:
1978*bbecb9d1SAndroid Build Coastguard Worker       ctx->gs_num_invocations = prop->u[0].Data;
1979*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
1980*bbecb9d1SAndroid Build Coastguard Worker       break;
1981*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_NUM_CLIPDIST_ENABLED:
1982*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_CLIP_DISTANCE;
1983*bbecb9d1SAndroid Build Coastguard Worker       ctx->num_clip_dist_prop = prop->u[0].Data;
1984*bbecb9d1SAndroid Build Coastguard Worker       break;
1985*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_NUM_CULLDIST_ENABLED:
1986*bbecb9d1SAndroid Build Coastguard Worker       ctx->num_cull_dist_prop = prop->u[0].Data;
1987*bbecb9d1SAndroid Build Coastguard Worker       break;
1988*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_TCS_VERTICES_OUT:
1989*bbecb9d1SAndroid Build Coastguard Worker       ctx->tcs_vertices_out = prop->u[0].Data;
1990*bbecb9d1SAndroid Build Coastguard Worker       break;
1991*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_TES_PRIM_MODE:
1992*bbecb9d1SAndroid Build Coastguard Worker       ctx->tes_prim_mode = prop->u[0].Data;
1993*bbecb9d1SAndroid Build Coastguard Worker       break;
1994*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_TES_SPACING:
1995*bbecb9d1SAndroid Build Coastguard Worker       ctx->tes_spacing = prop->u[0].Data;
1996*bbecb9d1SAndroid Build Coastguard Worker       break;
1997*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_TES_VERTEX_ORDER_CW:
1998*bbecb9d1SAndroid Build Coastguard Worker       ctx->tes_vertex_order = prop->u[0].Data;
1999*bbecb9d1SAndroid Build Coastguard Worker       break;
2000*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_TES_POINT_MODE:
2001*bbecb9d1SAndroid Build Coastguard Worker       ctx->tes_point_mode = prop->u[0].Data;
2002*bbecb9d1SAndroid Build Coastguard Worker       break;
2003*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL:
2004*bbecb9d1SAndroid Build Coastguard Worker       ctx->early_depth_stencil = prop->u[0].Data > 0;
2005*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->early_depth_stencil) {
2006*bbecb9d1SAndroid Build Coastguard Worker          ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
2007*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_IMAGE_LOAD_STORE;
2008*bbecb9d1SAndroid Build Coastguard Worker       }
2009*bbecb9d1SAndroid Build Coastguard Worker       break;
2010*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH:
2011*bbecb9d1SAndroid Build Coastguard Worker       ctx->local_cs_block_size[0] = prop->u[0].Data;
2012*bbecb9d1SAndroid Build Coastguard Worker       break;
2013*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT:
2014*bbecb9d1SAndroid Build Coastguard Worker       ctx->local_cs_block_size[1] = prop->u[0].Data;
2015*bbecb9d1SAndroid Build Coastguard Worker       break;
2016*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH:
2017*bbecb9d1SAndroid Build Coastguard Worker       ctx->local_cs_block_size[2] = prop->u[0].Data;
2018*bbecb9d1SAndroid Build Coastguard Worker       break;
2019*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_FS_BLEND_EQUATION_ADVANCED:
2020*bbecb9d1SAndroid Build Coastguard Worker       ctx->fs_blend_equation_advanced = prop->u[0].Data;
2021*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles || ctx->cfg->glsl_version < 320) {
2022*bbecb9d1SAndroid Build Coastguard Worker          ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
2023*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_BLEND_EQUATION_ADVANCED;
2024*bbecb9d1SAndroid Build Coastguard Worker       }
2025*bbecb9d1SAndroid Build Coastguard Worker       break;
2026*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROPERTY_SEPARABLE_PROGRAM:
2027*bbecb9d1SAndroid Build Coastguard Worker       /* GLES is very strict in how separable shaders interfaces should be matched.
2028*bbecb9d1SAndroid Build Coastguard Worker        * It doesn't allow, for example, inputs without matching outputs. So, we just
2029*bbecb9d1SAndroid Build Coastguard Worker        * disable separable shaders for GLES. */
2030*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles) {
2031*bbecb9d1SAndroid Build Coastguard Worker           ctx->separable_program = prop->u[0].Data;
2032*bbecb9d1SAndroid Build Coastguard Worker           ctx->shader_req_bits |= SHADER_REQ_SEPERATE_SHADER_OBJECTS;
2033*bbecb9d1SAndroid Build Coastguard Worker           ctx->shader_req_bits |= SHADER_REQ_EXPLICIT_ATTRIB_LOCATION;
2034*bbecb9d1SAndroid Build Coastguard Worker       }
2035*bbecb9d1SAndroid Build Coastguard Worker       break;
2036*bbecb9d1SAndroid Build Coastguard Worker    default:
2037*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf("unhandled property: %x\n", prop->Property.PropertyName);
2038*bbecb9d1SAndroid Build Coastguard Worker       return false;
2039*bbecb9d1SAndroid Build Coastguard Worker    }
2040*bbecb9d1SAndroid Build Coastguard Worker 
2041*bbecb9d1SAndroid Build Coastguard Worker    return true;
2042*bbecb9d1SAndroid Build Coastguard Worker }
2043*bbecb9d1SAndroid Build Coastguard Worker 
2044*bbecb9d1SAndroid Build Coastguard Worker static boolean
iter_immediate(struct tgsi_iterate_context * iter,struct tgsi_full_immediate * imm)2045*bbecb9d1SAndroid Build Coastguard Worker iter_immediate(struct tgsi_iterate_context *iter,
2046*bbecb9d1SAndroid Build Coastguard Worker                struct tgsi_full_immediate *imm)
2047*bbecb9d1SAndroid Build Coastguard Worker {
2048*bbecb9d1SAndroid Build Coastguard Worker    struct dump_ctx *ctx = (struct dump_ctx *) iter;
2049*bbecb9d1SAndroid Build Coastguard Worker    int i;
2050*bbecb9d1SAndroid Build Coastguard Worker    uint32_t first = ctx->num_imm;
2051*bbecb9d1SAndroid Build Coastguard Worker 
2052*bbecb9d1SAndroid Build Coastguard Worker    if (first >= ARRAY_SIZE(ctx->imm)) {
2053*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf( "Number of immediates exceeded, max is: %lu\n", ARRAY_SIZE(ctx->imm));
2054*bbecb9d1SAndroid Build Coastguard Worker       return false;
2055*bbecb9d1SAndroid Build Coastguard Worker    }
2056*bbecb9d1SAndroid Build Coastguard Worker 
2057*bbecb9d1SAndroid Build Coastguard Worker    ctx->imm[first].type = imm->Immediate.DataType;
2058*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < 4; i++) {
2059*bbecb9d1SAndroid Build Coastguard Worker       if (imm->Immediate.DataType == TGSI_IMM_FLOAT32) {
2060*bbecb9d1SAndroid Build Coastguard Worker          ctx->imm[first].val[i].f = imm->u[i].Float;
2061*bbecb9d1SAndroid Build Coastguard Worker       } else if (imm->Immediate.DataType == TGSI_IMM_UINT32 ||
2062*bbecb9d1SAndroid Build Coastguard Worker                  imm->Immediate.DataType == TGSI_IMM_FLOAT64) {
2063*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_INTS;
2064*bbecb9d1SAndroid Build Coastguard Worker          ctx->imm[first].val[i].ui = imm->u[i].Uint;
2065*bbecb9d1SAndroid Build Coastguard Worker       } else if (imm->Immediate.DataType == TGSI_IMM_INT32) {
2066*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_INTS;
2067*bbecb9d1SAndroid Build Coastguard Worker          ctx->imm[first].val[i].i = imm->u[i].Int;
2068*bbecb9d1SAndroid Build Coastguard Worker       }
2069*bbecb9d1SAndroid Build Coastguard Worker    }
2070*bbecb9d1SAndroid Build Coastguard Worker    ctx->num_imm++;
2071*bbecb9d1SAndroid Build Coastguard Worker    return true;
2072*bbecb9d1SAndroid Build Coastguard Worker }
2073*bbecb9d1SAndroid Build Coastguard Worker 
get_swiz_char(int swiz)2074*bbecb9d1SAndroid Build Coastguard Worker static char get_swiz_char(int swiz)
2075*bbecb9d1SAndroid Build Coastguard Worker {
2076*bbecb9d1SAndroid Build Coastguard Worker    switch(swiz){
2077*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SWIZZLE_X: return 'x';
2078*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SWIZZLE_Y: return 'y';
2079*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SWIZZLE_Z: return 'z';
2080*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SWIZZLE_W: return 'w';
2081*bbecb9d1SAndroid Build Coastguard Worker    default: return 0;
2082*bbecb9d1SAndroid Build Coastguard Worker    }
2083*bbecb9d1SAndroid Build Coastguard Worker }
2084*bbecb9d1SAndroid Build Coastguard Worker 
emit_cbuf_writes(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2085*bbecb9d1SAndroid Build Coastguard Worker static void emit_cbuf_writes(const struct dump_ctx *ctx,
2086*bbecb9d1SAndroid Build Coastguard Worker                              struct vrend_glsl_strbufs *glsl_strbufs)
2087*bbecb9d1SAndroid Build Coastguard Worker {
2088*bbecb9d1SAndroid Build Coastguard Worker    int i;
2089*bbecb9d1SAndroid Build Coastguard Worker 
2090*bbecb9d1SAndroid Build Coastguard Worker    for (i = ctx->num_outputs; i < ctx->cfg->max_draw_buffers; i++) {
2091*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(glsl_strbufs, "fsout_c%d = fsout_c0;\n", i);
2092*bbecb9d1SAndroid Build Coastguard Worker    }
2093*bbecb9d1SAndroid Build Coastguard Worker }
2094*bbecb9d1SAndroid Build Coastguard Worker 
emit_a8_swizzle(struct vrend_glsl_strbufs * glsl_strbufs)2095*bbecb9d1SAndroid Build Coastguard Worker static void emit_a8_swizzle(struct vrend_glsl_strbufs *glsl_strbufs)
2096*bbecb9d1SAndroid Build Coastguard Worker {
2097*bbecb9d1SAndroid Build Coastguard Worker    emit_buf(glsl_strbufs, "fsout_c0.x = fsout_c0.w;\n");
2098*bbecb9d1SAndroid Build Coastguard Worker }
2099*bbecb9d1SAndroid Build Coastguard Worker 
2100*bbecb9d1SAndroid Build Coastguard Worker static const char *atests[PIPE_FUNC_ALWAYS + 1] = {
2101*bbecb9d1SAndroid Build Coastguard Worker    "false",
2102*bbecb9d1SAndroid Build Coastguard Worker    "<",
2103*bbecb9d1SAndroid Build Coastguard Worker    "==",
2104*bbecb9d1SAndroid Build Coastguard Worker    "<=",
2105*bbecb9d1SAndroid Build Coastguard Worker    ">",
2106*bbecb9d1SAndroid Build Coastguard Worker    "!=",
2107*bbecb9d1SAndroid Build Coastguard Worker    ">=",
2108*bbecb9d1SAndroid Build Coastguard Worker    "true"
2109*bbecb9d1SAndroid Build Coastguard Worker };
2110*bbecb9d1SAndroid Build Coastguard Worker 
emit_alpha_test(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2111*bbecb9d1SAndroid Build Coastguard Worker static void emit_alpha_test(const struct dump_ctx *ctx,
2112*bbecb9d1SAndroid Build Coastguard Worker                             struct vrend_glsl_strbufs *glsl_strbufs)
2113*bbecb9d1SAndroid Build Coastguard Worker {
2114*bbecb9d1SAndroid Build Coastguard Worker    char comp_buf[128];
2115*bbecb9d1SAndroid Build Coastguard Worker 
2116*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx->num_outputs)
2117*bbecb9d1SAndroid Build Coastguard Worker       return;
2118*bbecb9d1SAndroid Build Coastguard Worker 
2119*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx->write_all_cbufs) {
2120*bbecb9d1SAndroid Build Coastguard Worker       /* only emit alpha stanza if first output is 0 */
2121*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->outputs[0].sid != 0)
2122*bbecb9d1SAndroid Build Coastguard Worker          return;
2123*bbecb9d1SAndroid Build Coastguard Worker    }
2124*bbecb9d1SAndroid Build Coastguard Worker    switch (ctx->key->alpha_test) {
2125*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_NEVER:
2126*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_ALWAYS:
2127*bbecb9d1SAndroid Build Coastguard Worker       snprintf(comp_buf, 128, "%s", atests[ctx->key->alpha_test]);
2128*bbecb9d1SAndroid Build Coastguard Worker       break;
2129*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_LESS:
2130*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_EQUAL:
2131*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_LEQUAL:
2132*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_GREATER:
2133*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_NOTEQUAL:
2134*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_GEQUAL:
2135*bbecb9d1SAndroid Build Coastguard Worker       snprintf(comp_buf, 128, "%s %s alpha_ref_val", "fsout_c0.w", atests[ctx->key->alpha_test]);
2136*bbecb9d1SAndroid Build Coastguard Worker       glsl_strbufs->required_sysval_uniform_decls |= BIT(UNIFORM_ALPHA_REF_VAL);
2137*bbecb9d1SAndroid Build Coastguard Worker       break;
2138*bbecb9d1SAndroid Build Coastguard Worker    default:
2139*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf( "invalid alpha-test: %x\n", ctx->key->alpha_test);
2140*bbecb9d1SAndroid Build Coastguard Worker       set_buf_error(glsl_strbufs);
2141*bbecb9d1SAndroid Build Coastguard Worker       return;
2142*bbecb9d1SAndroid Build Coastguard Worker    }
2143*bbecb9d1SAndroid Build Coastguard Worker 
2144*bbecb9d1SAndroid Build Coastguard Worker    emit_buff(glsl_strbufs, "if (!(%s)) {\n\tdiscard;\n}\n", comp_buf);
2145*bbecb9d1SAndroid Build Coastguard Worker }
2146*bbecb9d1SAndroid Build Coastguard Worker 
emit_pstipple_pass(struct vrend_glsl_strbufs * glsl_strbufs)2147*bbecb9d1SAndroid Build Coastguard Worker static void emit_pstipple_pass(struct vrend_glsl_strbufs *glsl_strbufs)
2148*bbecb9d1SAndroid Build Coastguard Worker {
2149*bbecb9d1SAndroid Build Coastguard Worker    static_assert(VREND_POLYGON_STIPPLE_SIZE == 32,
2150*bbecb9d1SAndroid Build Coastguard Worker          "According to the spec stipple size must be 32");
2151*bbecb9d1SAndroid Build Coastguard Worker 
2152*bbecb9d1SAndroid Build Coastguard Worker    const int mask = VREND_POLYGON_STIPPLE_SIZE - 1;
2153*bbecb9d1SAndroid Build Coastguard Worker 
2154*bbecb9d1SAndroid Build Coastguard Worker    emit_buf(glsl_strbufs, "{\n");
2155*bbecb9d1SAndroid Build Coastguard Worker    emit_buff(glsl_strbufs, "   int spx = int(gl_FragCoord.x) & %d;\n", mask);
2156*bbecb9d1SAndroid Build Coastguard Worker    emit_buff(glsl_strbufs, "   int spy = int(gl_FragCoord.y) & %d;\n", mask);
2157*bbecb9d1SAndroid Build Coastguard Worker    emit_buf(glsl_strbufs, "   stip_temp = stipple_pattern[spy] & (0x80000000u >> spx);\n");
2158*bbecb9d1SAndroid Build Coastguard Worker    emit_buf(glsl_strbufs, "   if (stip_temp == 0u) {\n      discard;\n   }\n");
2159*bbecb9d1SAndroid Build Coastguard Worker    emit_buf(glsl_strbufs, "}\n");
2160*bbecb9d1SAndroid Build Coastguard Worker    glsl_strbufs->required_sysval_uniform_decls |= BIT(UNIFORM_PSTIPPLE_SAMPLER);
2161*bbecb9d1SAndroid Build Coastguard Worker }
2162*bbecb9d1SAndroid Build Coastguard Worker 
emit_color_select(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2163*bbecb9d1SAndroid Build Coastguard Worker static void emit_color_select(const struct dump_ctx *ctx,
2164*bbecb9d1SAndroid Build Coastguard Worker                               struct vrend_glsl_strbufs *glsl_strbufs)
2165*bbecb9d1SAndroid Build Coastguard Worker {
2166*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx->key->color_two_side || !(ctx->color_in_mask & 0x3))
2167*bbecb9d1SAndroid Build Coastguard Worker       return;
2168*bbecb9d1SAndroid Build Coastguard Worker 
2169*bbecb9d1SAndroid Build Coastguard Worker    const char *name_prefix = get_stage_input_name_prefix(ctx, ctx->prog_type);
2170*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->color_in_mask & 1)
2171*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(glsl_strbufs, "realcolor0 = gl_FrontFacing ? %s_c0 : %s_bc0;\n",
2172*bbecb9d1SAndroid Build Coastguard Worker                name_prefix, name_prefix);
2173*bbecb9d1SAndroid Build Coastguard Worker 
2174*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->color_in_mask & 2)
2175*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(glsl_strbufs, "realcolor1 = gl_FrontFacing ? %s_c1 : %s_bc1;\n",
2176*bbecb9d1SAndroid Build Coastguard Worker                 name_prefix, name_prefix);
2177*bbecb9d1SAndroid Build Coastguard Worker }
2178*bbecb9d1SAndroid Build Coastguard Worker 
emit_prescale(struct vrend_glsl_strbufs * glsl_strbufs)2179*bbecb9d1SAndroid Build Coastguard Worker static void emit_prescale(struct vrend_glsl_strbufs *glsl_strbufs)
2180*bbecb9d1SAndroid Build Coastguard Worker {
2181*bbecb9d1SAndroid Build Coastguard Worker    emit_buf(glsl_strbufs, "gl_Position.y = gl_Position.y * winsys_adjust_y;\n");
2182*bbecb9d1SAndroid Build Coastguard Worker    glsl_strbufs->required_sysval_uniform_decls |= BIT(UNIFORM_WINSYS_ADJUST_Y);
2183*bbecb9d1SAndroid Build Coastguard Worker }
2184*bbecb9d1SAndroid Build Coastguard Worker 
2185*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
prepare_so_movs(struct dump_ctx * ctx)2186*bbecb9d1SAndroid Build Coastguard Worker static void prepare_so_movs(struct dump_ctx *ctx)
2187*bbecb9d1SAndroid Build Coastguard Worker {
2188*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
2189*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->so->num_outputs; i++) {
2190*bbecb9d1SAndroid Build Coastguard Worker       ctx->write_so_outputs[i] = true;
2191*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->so->output[i].start_component != 0)
2192*bbecb9d1SAndroid Build Coastguard Worker          continue;
2193*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->so->output[i].num_components != 4)
2194*bbecb9d1SAndroid Build Coastguard Worker          continue;
2195*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_CLIPDIST)
2196*bbecb9d1SAndroid Build Coastguard Worker          continue;
2197*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_POSITION)
2198*bbecb9d1SAndroid Build Coastguard Worker          continue;
2199*bbecb9d1SAndroid Build Coastguard Worker 
2200*bbecb9d1SAndroid Build Coastguard Worker       ctx->outputs[ctx->so->output[i].register_index].stream = ctx->so->output[i].stream;
2201*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY && ctx->so->output[i].stream)
2202*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
2203*bbecb9d1SAndroid Build Coastguard Worker 
2204*bbecb9d1SAndroid Build Coastguard Worker       ctx->write_so_outputs[i] = false;
2205*bbecb9d1SAndroid Build Coastguard Worker    }
2206*bbecb9d1SAndroid Build Coastguard Worker }
2207*bbecb9d1SAndroid Build Coastguard Worker 
get_io_slot(const struct vrend_shader_io * slots,unsigned nslots,int idx)2208*bbecb9d1SAndroid Build Coastguard Worker static const struct vrend_shader_io *get_io_slot(const struct vrend_shader_io *slots, unsigned nslots, int idx)
2209*bbecb9d1SAndroid Build Coastguard Worker {
2210*bbecb9d1SAndroid Build Coastguard Worker    const struct vrend_shader_io *result = slots;
2211*bbecb9d1SAndroid Build Coastguard Worker    for (unsigned i = 0; i < nslots; ++i, ++result) {
2212*bbecb9d1SAndroid Build Coastguard Worker       if ((result->first <=  idx) && (result->last >=  idx))
2213*bbecb9d1SAndroid Build Coastguard Worker          return result;
2214*bbecb9d1SAndroid Build Coastguard Worker    }
2215*bbecb9d1SAndroid Build Coastguard Worker    assert(0 && "Output not found");
2216*bbecb9d1SAndroid Build Coastguard Worker    return NULL;
2217*bbecb9d1SAndroid Build Coastguard Worker }
2218*bbecb9d1SAndroid Build Coastguard Worker 
2219*bbecb9d1SAndroid Build Coastguard Worker static inline void
get_blockname(char outvar[64],const char * stage_prefix,const struct vrend_shader_io * io)2220*bbecb9d1SAndroid Build Coastguard Worker get_blockname(char outvar[64], const char *stage_prefix, const struct vrend_shader_io *io)
2221*bbecb9d1SAndroid Build Coastguard Worker {
2222*bbecb9d1SAndroid Build Coastguard Worker    snprintf(outvar, 64, "block_%sg%d", stage_prefix, io->sid);
2223*bbecb9d1SAndroid Build Coastguard Worker }
2224*bbecb9d1SAndroid Build Coastguard Worker 
2225*bbecb9d1SAndroid Build Coastguard Worker static inline void
get_blockvarname(char outvar[64],const char * stage_prefix,const struct vrend_shader_io * io,const char * postfix)2226*bbecb9d1SAndroid Build Coastguard Worker get_blockvarname(char outvar[64], const char *stage_prefix, const struct vrend_shader_io *io, const char *postfix)
2227*bbecb9d1SAndroid Build Coastguard Worker {
2228*bbecb9d1SAndroid Build Coastguard Worker    snprintf(outvar, 64, "%sg%d%s", stage_prefix, io->first, postfix);
2229*bbecb9d1SAndroid Build Coastguard Worker }
2230*bbecb9d1SAndroid Build Coastguard Worker 
get_so_name(const struct dump_ctx * ctx,bool from_block,const struct vrend_shader_io * output,int index,char out_var[255],char * wm)2231*bbecb9d1SAndroid Build Coastguard Worker static void get_so_name(const struct dump_ctx *ctx, bool from_block, const struct vrend_shader_io *output, int index, char out_var[255], char *wm)
2232*bbecb9d1SAndroid Build Coastguard Worker {
2233*bbecb9d1SAndroid Build Coastguard Worker    if (output->first == output->last ||
2234*bbecb9d1SAndroid Build Coastguard Worker        (output->name != TGSI_SEMANTIC_GENERIC &&
2235*bbecb9d1SAndroid Build Coastguard Worker         output->name != TGSI_SEMANTIC_TEXCOORD))
2236*bbecb9d1SAndroid Build Coastguard Worker       snprintf(out_var, 255, "%s%s", output->glsl_name, wm);
2237*bbecb9d1SAndroid Build Coastguard Worker    else {
2238*bbecb9d1SAndroid Build Coastguard Worker       if ((output->name == TGSI_SEMANTIC_GENERIC) && prefer_generic_io_block(ctx, io_out)) {
2239*bbecb9d1SAndroid Build Coastguard Worker          char blockname[64];
2240*bbecb9d1SAndroid Build Coastguard Worker          const char *stage_prefix = get_stage_output_name_prefix(ctx->prog_type);
2241*bbecb9d1SAndroid Build Coastguard Worker          if (from_block)
2242*bbecb9d1SAndroid Build Coastguard Worker             get_blockname(blockname, stage_prefix, output);
2243*bbecb9d1SAndroid Build Coastguard Worker          else
2244*bbecb9d1SAndroid Build Coastguard Worker             get_blockvarname(blockname, stage_prefix, output, "");
2245*bbecb9d1SAndroid Build Coastguard Worker          snprintf(out_var, 255, "%s.%s[%d]%s",  blockname, output->glsl_name, index - output->first, wm);
2246*bbecb9d1SAndroid Build Coastguard Worker       } else {
2247*bbecb9d1SAndroid Build Coastguard Worker          snprintf(out_var, 255, "%s[%d]%s",  output->glsl_name, index - output->first, wm);
2248*bbecb9d1SAndroid Build Coastguard Worker       }
2249*bbecb9d1SAndroid Build Coastguard Worker    }
2250*bbecb9d1SAndroid Build Coastguard Worker }
2251*bbecb9d1SAndroid Build Coastguard Worker 
emit_so_movs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,bool * has_clipvertex_so)2252*bbecb9d1SAndroid Build Coastguard Worker static void emit_so_movs(const struct dump_ctx *ctx,
2253*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_glsl_strbufs *glsl_strbufs,
2254*bbecb9d1SAndroid Build Coastguard Worker                          bool *has_clipvertex_so)
2255*bbecb9d1SAndroid Build Coastguard Worker {
2256*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i, j;
2257*bbecb9d1SAndroid Build Coastguard Worker    char outtype[15] = "";
2258*bbecb9d1SAndroid Build Coastguard Worker    char writemask[6];
2259*bbecb9d1SAndroid Build Coastguard Worker 
2260*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->so->num_outputs >= PIPE_MAX_SO_OUTPUTS) {
2261*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf( "Num outputs exceeded, max is %u\n", PIPE_MAX_SO_OUTPUTS);
2262*bbecb9d1SAndroid Build Coastguard Worker       set_buf_error(glsl_strbufs);
2263*bbecb9d1SAndroid Build Coastguard Worker       return;
2264*bbecb9d1SAndroid Build Coastguard Worker    }
2265*bbecb9d1SAndroid Build Coastguard Worker 
2266*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->so->num_outputs; i++) {
2267*bbecb9d1SAndroid Build Coastguard Worker       const struct vrend_shader_io *output = get_io_slot(&ctx->outputs[0], ctx->num_outputs, ctx->so->output[i].register_index);
2268*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->so->output[i].start_component != 0) {
2269*bbecb9d1SAndroid Build Coastguard Worker          int wm_idx = 0;
2270*bbecb9d1SAndroid Build Coastguard Worker          writemask[wm_idx++] = '.';
2271*bbecb9d1SAndroid Build Coastguard Worker          for (j = 0; j < ctx->so->output[i].num_components; j++) {
2272*bbecb9d1SAndroid Build Coastguard Worker             unsigned idx = ctx->so->output[i].start_component + j;
2273*bbecb9d1SAndroid Build Coastguard Worker             if (idx >= 4)
2274*bbecb9d1SAndroid Build Coastguard Worker                break;
2275*bbecb9d1SAndroid Build Coastguard Worker             if (idx <= 2)
2276*bbecb9d1SAndroid Build Coastguard Worker                writemask[wm_idx++] = 'x' + idx;
2277*bbecb9d1SAndroid Build Coastguard Worker             else
2278*bbecb9d1SAndroid Build Coastguard Worker                writemask[wm_idx++] = 'w';
2279*bbecb9d1SAndroid Build Coastguard Worker          }
2280*bbecb9d1SAndroid Build Coastguard Worker          writemask[wm_idx] = '\0';
2281*bbecb9d1SAndroid Build Coastguard Worker       } else
2282*bbecb9d1SAndroid Build Coastguard Worker          writemask[0] = 0;
2283*bbecb9d1SAndroid Build Coastguard Worker 
2284*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->write_so_outputs[i]) {
2285*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->so_names[i])
2286*bbecb9d1SAndroid Build Coastguard Worker             free(ctx->so_names[i]);
2287*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->so->output[i].register_index > ctx->num_outputs)
2288*bbecb9d1SAndroid Build Coastguard Worker             ctx->so_names[i] = NULL;
2289*bbecb9d1SAndroid Build Coastguard Worker          else if (output->name == TGSI_SEMANTIC_CLIPVERTEX && ctx->has_clipvertex) {
2290*bbecb9d1SAndroid Build Coastguard Worker             ctx->so_names[i] = strdup("clipv_tmp");
2291*bbecb9d1SAndroid Build Coastguard Worker             *has_clipvertex_so = true;
2292*bbecb9d1SAndroid Build Coastguard Worker          } else {
2293*bbecb9d1SAndroid Build Coastguard Worker             char out_var[255];
2294*bbecb9d1SAndroid Build Coastguard Worker             const struct vrend_shader_io *used_output_io = output;
2295*bbecb9d1SAndroid Build Coastguard Worker             if (output->name == TGSI_SEMANTIC_GENERIC && ctx->generic_ios.output_range.used) {
2296*bbecb9d1SAndroid Build Coastguard Worker                used_output_io = &ctx->generic_ios.output_range.io;
2297*bbecb9d1SAndroid Build Coastguard Worker             } else if (output->name == TGSI_SEMANTIC_PATCH && ctx->patch_ios.output_range.used) {
2298*bbecb9d1SAndroid Build Coastguard Worker                used_output_io = &ctx->patch_ios.output_range.io;
2299*bbecb9d1SAndroid Build Coastguard Worker             }
2300*bbecb9d1SAndroid Build Coastguard Worker             get_so_name(ctx, true, used_output_io, ctx->so->output[i].register_index, out_var, "");
2301*bbecb9d1SAndroid Build Coastguard Worker             ctx->so_names[i] = strdup(out_var);
2302*bbecb9d1SAndroid Build Coastguard Worker          }
2303*bbecb9d1SAndroid Build Coastguard Worker       } else {
2304*bbecb9d1SAndroid Build Coastguard Worker          char ntemp[8];
2305*bbecb9d1SAndroid Build Coastguard Worker          snprintf(ntemp, 8, "tfout%d", i);
2306*bbecb9d1SAndroid Build Coastguard Worker          ctx->so_names[i] = strdup(ntemp);
2307*bbecb9d1SAndroid Build Coastguard Worker       }
2308*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->so->output[i].num_components == 1) {
2309*bbecb9d1SAndroid Build Coastguard Worker          if (output->is_int)
2310*bbecb9d1SAndroid Build Coastguard Worker             snprintf(outtype, 15, "intBitsToFloat");
2311*bbecb9d1SAndroid Build Coastguard Worker          else
2312*bbecb9d1SAndroid Build Coastguard Worker             snprintf(outtype, 15, "float");
2313*bbecb9d1SAndroid Build Coastguard Worker       } else
2314*bbecb9d1SAndroid Build Coastguard Worker          snprintf(outtype, 15, "vec%d", ctx->so->output[i].num_components);
2315*bbecb9d1SAndroid Build Coastguard Worker 
2316*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->so->output[i].register_index >= 255)
2317*bbecb9d1SAndroid Build Coastguard Worker          continue;
2318*bbecb9d1SAndroid Build Coastguard Worker 
2319*bbecb9d1SAndroid Build Coastguard Worker       if (output->name == TGSI_SEMANTIC_CLIPDIST) {
2320*bbecb9d1SAndroid Build Coastguard Worker          if (output->first == output->last)
2321*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(glsl_strbufs, "tfout%d = %s(clip_dist_temp[%d]%s);\n", i, outtype, output->sid,
2322*bbecb9d1SAndroid Build Coastguard Worker                       writemask);
2323*bbecb9d1SAndroid Build Coastguard Worker          else
2324*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(glsl_strbufs, "tfout%d = %s(clip_dist_temp[%d]%s);\n", i, outtype,
2325*bbecb9d1SAndroid Build Coastguard Worker                       output->sid + ctx->so->output[i].register_index - output->first,
2326*bbecb9d1SAndroid Build Coastguard Worker                       writemask);
2327*bbecb9d1SAndroid Build Coastguard Worker       } else {
2328*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->write_so_outputs[i]) {
2329*bbecb9d1SAndroid Build Coastguard Worker             char out_var[255];
2330*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->so->output[i].need_temp || ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
2331*bbecb9d1SAndroid Build Coastguard Worker                 output->glsl_predefined_no_emit) {
2332*bbecb9d1SAndroid Build Coastguard Worker                get_so_name(ctx, false, output, ctx->so->output[i].register_index, out_var, writemask);
2333*bbecb9d1SAndroid Build Coastguard Worker                emit_buff(glsl_strbufs, "tfout%d = %s(%s);\n", i, outtype, out_var);
2334*bbecb9d1SAndroid Build Coastguard Worker             } else {
2335*bbecb9d1SAndroid Build Coastguard Worker                get_so_name(ctx, true, output, ctx->so->output[i].register_index, out_var, writemask);
2336*bbecb9d1SAndroid Build Coastguard Worker                free(ctx->so_names[i]);
2337*bbecb9d1SAndroid Build Coastguard Worker                ctx->so_names[i] = strdup(out_var);
2338*bbecb9d1SAndroid Build Coastguard Worker             }
2339*bbecb9d1SAndroid Build Coastguard Worker          }
2340*bbecb9d1SAndroid Build Coastguard Worker       }
2341*bbecb9d1SAndroid Build Coastguard Worker    }
2342*bbecb9d1SAndroid Build Coastguard Worker }
2343*bbecb9d1SAndroid Build Coastguard Worker 
emit_clip_dist_movs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2344*bbecb9d1SAndroid Build Coastguard Worker static void emit_clip_dist_movs(const struct dump_ctx *ctx,
2345*bbecb9d1SAndroid Build Coastguard Worker                                 struct vrend_glsl_strbufs *glsl_strbufs)
2346*bbecb9d1SAndroid Build Coastguard Worker {
2347*bbecb9d1SAndroid Build Coastguard Worker    int i;
2348*bbecb9d1SAndroid Build Coastguard Worker    bool has_prop = (ctx->num_clip_dist_prop + ctx->num_cull_dist_prop) > 0;
2349*bbecb9d1SAndroid Build Coastguard Worker    int num_clip = has_prop ? ctx->num_clip_dist_prop : ctx->key->num_out_clip;
2350*bbecb9d1SAndroid Build Coastguard Worker    int num_cull = has_prop ? ctx->num_cull_dist_prop : ctx->key->num_out_cull;
2351*bbecb9d1SAndroid Build Coastguard Worker 
2352*bbecb9d1SAndroid Build Coastguard Worker 
2353*bbecb9d1SAndroid Build Coastguard Worker    int num_clip_cull = num_cull + num_clip;
2354*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->num_out_clip_dist && !num_clip_cull)
2355*bbecb9d1SAndroid Build Coastguard Worker       num_clip = ctx->num_out_clip_dist;
2356*bbecb9d1SAndroid Build Coastguard Worker 
2357*bbecb9d1SAndroid Build Coastguard Worker    int ndists;
2358*bbecb9d1SAndroid Build Coastguard Worker    const char *prefix="";
2359*bbecb9d1SAndroid Build Coastguard Worker 
2360*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL)
2361*bbecb9d1SAndroid Build Coastguard Worker       prefix = "gl_out[gl_InvocationID].";
2362*bbecb9d1SAndroid Build Coastguard Worker 
2363*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->num_out_clip_dist == 0 &&
2364*bbecb9d1SAndroid Build Coastguard Worker        ctx->is_last_vertex_stage &&
2365*bbecb9d1SAndroid Build Coastguard Worker        ctx->num_outputs + 2 <= MAX_VARYING) {
2366*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(glsl_strbufs, "if (clip_plane_enabled) {\n");
2367*bbecb9d1SAndroid Build Coastguard Worker       for (i = 0; i < 8; i++) {
2368*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(glsl_strbufs, "  %sgl_ClipDistance[%d] = dot(%s, clipp[%d]);\n",
2369*bbecb9d1SAndroid Build Coastguard Worker                    prefix, i, ctx->has_clipvertex ? "clipv_tmp" : "gl_Position", i);
2370*bbecb9d1SAndroid Build Coastguard Worker       }
2371*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(glsl_strbufs, "}\n");
2372*bbecb9d1SAndroid Build Coastguard Worker       glsl_strbufs->required_sysval_uniform_decls |= BIT(UNIFORM_CLIP_PLANE);
2373*bbecb9d1SAndroid Build Coastguard Worker    }
2374*bbecb9d1SAndroid Build Coastguard Worker    ndists = ctx->num_out_clip_dist;
2375*bbecb9d1SAndroid Build Coastguard Worker    if (has_prop)
2376*bbecb9d1SAndroid Build Coastguard Worker       ndists = num_clip + num_cull;
2377*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ndists; i++) {
2378*bbecb9d1SAndroid Build Coastguard Worker       int clipidx = i < 4 ? 0 : 1;
2379*bbecb9d1SAndroid Build Coastguard Worker       char swiz = i & 3;
2380*bbecb9d1SAndroid Build Coastguard Worker       char wm = 0;
2381*bbecb9d1SAndroid Build Coastguard Worker       switch (swiz) {
2382*bbecb9d1SAndroid Build Coastguard Worker       default:
2383*bbecb9d1SAndroid Build Coastguard Worker       case 0: wm = 'x'; break;
2384*bbecb9d1SAndroid Build Coastguard Worker       case 1: wm = 'y'; break;
2385*bbecb9d1SAndroid Build Coastguard Worker       case 2: wm = 'z'; break;
2386*bbecb9d1SAndroid Build Coastguard Worker       case 3: wm = 'w'; break;
2387*bbecb9d1SAndroid Build Coastguard Worker       }
2388*bbecb9d1SAndroid Build Coastguard Worker       bool is_cull = false;
2389*bbecb9d1SAndroid Build Coastguard Worker       const char *clip_cull = "Clip";
2390*bbecb9d1SAndroid Build Coastguard Worker 
2391*bbecb9d1SAndroid Build Coastguard Worker       if (i >= num_clip) {
2392*bbecb9d1SAndroid Build Coastguard Worker          if (i < ndists) {
2393*bbecb9d1SAndroid Build Coastguard Worker             is_cull = true;
2394*bbecb9d1SAndroid Build Coastguard Worker             clip_cull = "Cull";
2395*bbecb9d1SAndroid Build Coastguard Worker          } else {
2396*bbecb9d1SAndroid Build Coastguard Worker             clip_cull = "ERROR";
2397*bbecb9d1SAndroid Build Coastguard Worker          }
2398*bbecb9d1SAndroid Build Coastguard Worker       }
2399*bbecb9d1SAndroid Build Coastguard Worker 
2400*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(glsl_strbufs, "%sgl_%sDistance[%d] = clip_dist_temp[%d].%c;\n", prefix, clip_cull,
2401*bbecb9d1SAndroid Build Coastguard Worker                is_cull ? i - num_clip : i, clipidx, wm);
2402*bbecb9d1SAndroid Build Coastguard Worker    }
2403*bbecb9d1SAndroid Build Coastguard Worker }
2404*bbecb9d1SAndroid Build Coastguard Worker 
emit_fog_fixup_hdr(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2405*bbecb9d1SAndroid Build Coastguard Worker static void emit_fog_fixup_hdr(const struct dump_ctx *ctx,
2406*bbecb9d1SAndroid Build Coastguard Worker                                struct vrend_glsl_strbufs *glsl_strbufs)
2407*bbecb9d1SAndroid Build Coastguard Worker {
2408*bbecb9d1SAndroid Build Coastguard Worker    uint32_t fixup_mask = ctx->key->vs.fog_fixup_mask;
2409*bbecb9d1SAndroid Build Coastguard Worker    int semantic;
2410*bbecb9d1SAndroid Build Coastguard Worker    const char *prefix = get_stage_output_name_prefix(TGSI_PROCESSOR_VERTEX);
2411*bbecb9d1SAndroid Build Coastguard Worker 
2412*bbecb9d1SAndroid Build Coastguard Worker    while (fixup_mask) {
2413*bbecb9d1SAndroid Build Coastguard Worker       semantic = ffs(fixup_mask) - 1;
2414*bbecb9d1SAndroid Build Coastguard Worker 
2415*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "out vec4 %s_f%d;\n", prefix, semantic);
2416*bbecb9d1SAndroid Build Coastguard Worker       fixup_mask &= (~(1 << semantic));
2417*bbecb9d1SAndroid Build Coastguard Worker    }
2418*bbecb9d1SAndroid Build Coastguard Worker }
2419*bbecb9d1SAndroid Build Coastguard Worker 
emit_fog_fixup_write(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2420*bbecb9d1SAndroid Build Coastguard Worker static void emit_fog_fixup_write(const struct dump_ctx *ctx,
2421*bbecb9d1SAndroid Build Coastguard Worker                                  struct vrend_glsl_strbufs *glsl_strbufs)
2422*bbecb9d1SAndroid Build Coastguard Worker {
2423*bbecb9d1SAndroid Build Coastguard Worker    uint32_t fixup_mask = ctx->key->vs.fog_fixup_mask;
2424*bbecb9d1SAndroid Build Coastguard Worker    int semantic;
2425*bbecb9d1SAndroid Build Coastguard Worker    const char *prefix = get_stage_output_name_prefix(TGSI_PROCESSOR_VERTEX);
2426*bbecb9d1SAndroid Build Coastguard Worker 
2427*bbecb9d1SAndroid Build Coastguard Worker    while (fixup_mask) {
2428*bbecb9d1SAndroid Build Coastguard Worker       semantic = ffs(fixup_mask) - 1;
2429*bbecb9d1SAndroid Build Coastguard Worker 
2430*bbecb9d1SAndroid Build Coastguard Worker       /*
2431*bbecb9d1SAndroid Build Coastguard Worker       *  Force unwritten fog outputs to 0,0,0,1
2432*bbecb9d1SAndroid Build Coastguard Worker       */
2433*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(glsl_strbufs, "%s_f%d = vec4(0.0, 0.0, 0.0, 1.0);\n",
2434*bbecb9d1SAndroid Build Coastguard Worker                prefix, semantic);
2435*bbecb9d1SAndroid Build Coastguard Worker       fixup_mask &= (~(1 << semantic));
2436*bbecb9d1SAndroid Build Coastguard Worker    }
2437*bbecb9d1SAndroid Build Coastguard Worker }
2438*bbecb9d1SAndroid Build Coastguard Worker 
2439*bbecb9d1SAndroid Build Coastguard Worker #define emit_arit_op2(op) emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((%s %s %s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], op, srcs[1], writemask)
2440*bbecb9d1SAndroid Build Coastguard Worker #define emit_op1(op) emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(%s(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), op, srcs[0], writemask)
2441*bbecb9d1SAndroid Build Coastguard Worker #define emit_compare(op) emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((%s(%s(%s), %s(%s))))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), op, get_string(sinfo.svec4), srcs[0], get_string(sinfo.svec4), srcs[1], writemask)
2442*bbecb9d1SAndroid Build Coastguard Worker 
2443*bbecb9d1SAndroid Build Coastguard Worker #define emit_ucompare(op) emit_buff(&ctx->glsl_strbufs, "%s = %s(uintBitsToFloat(%s(%s(%s(%s), %s(%s))%s) * %s(0xffffffff)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.udstconv), op, get_string(sinfo.svec4), srcs[0], get_string(sinfo.svec4), srcs[1], writemask, get_string(dinfo.udstconv))
2444*bbecb9d1SAndroid Build Coastguard Worker 
handle_vertex_proc_exit(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,bool * has_clipvertex_so)2445*bbecb9d1SAndroid Build Coastguard Worker static void handle_vertex_proc_exit(const struct dump_ctx *ctx,
2446*bbecb9d1SAndroid Build Coastguard Worker                                     struct vrend_glsl_strbufs *glsl_strbufs,
2447*bbecb9d1SAndroid Build Coastguard Worker                                     bool *has_clipvertex_so)
2448*bbecb9d1SAndroid Build Coastguard Worker {
2449*bbecb9d1SAndroid Build Coastguard Worker     if (ctx->so && !ctx->key->gs_present && !ctx->key->tes_present)
2450*bbecb9d1SAndroid Build Coastguard Worker        emit_so_movs(ctx, glsl_strbufs, has_clipvertex_so);
2451*bbecb9d1SAndroid Build Coastguard Worker 
2452*bbecb9d1SAndroid Build Coastguard Worker     if (ctx->cfg->has_cull_distance)
2453*bbecb9d1SAndroid Build Coastguard Worker        emit_clip_dist_movs(ctx, glsl_strbufs);
2454*bbecb9d1SAndroid Build Coastguard Worker 
2455*bbecb9d1SAndroid Build Coastguard Worker     if (!ctx->key->gs_present && !ctx->key->tes_present)
2456*bbecb9d1SAndroid Build Coastguard Worker        emit_prescale(glsl_strbufs);
2457*bbecb9d1SAndroid Build Coastguard Worker 
2458*bbecb9d1SAndroid Build Coastguard Worker     if (ctx->key->vs.fog_fixup_mask)
2459*bbecb9d1SAndroid Build Coastguard Worker        emit_fog_fixup_write(ctx, glsl_strbufs);
2460*bbecb9d1SAndroid Build Coastguard Worker }
2461*bbecb9d1SAndroid Build Coastguard Worker 
emit_fragment_logicop(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2462*bbecb9d1SAndroid Build Coastguard Worker static void emit_fragment_logicop(const struct dump_ctx *ctx,
2463*bbecb9d1SAndroid Build Coastguard Worker                                   struct vrend_glsl_strbufs *glsl_strbufs)
2464*bbecb9d1SAndroid Build Coastguard Worker {
2465*bbecb9d1SAndroid Build Coastguard Worker    char src[PIPE_MAX_COLOR_BUFS][64];
2466*bbecb9d1SAndroid Build Coastguard Worker    char src_fb[PIPE_MAX_COLOR_BUFS][64];
2467*bbecb9d1SAndroid Build Coastguard Worker    double scale[PIPE_MAX_COLOR_BUFS];
2468*bbecb9d1SAndroid Build Coastguard Worker    int mask[PIPE_MAX_COLOR_BUFS];
2469*bbecb9d1SAndroid Build Coastguard Worker 
2470*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_strbuf full_op_buf[PIPE_MAX_COLOR_BUFS];
2471*bbecb9d1SAndroid Build Coastguard Worker    for (int i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
2472*bbecb9d1SAndroid Build Coastguard Worker       strbuf_alloc(&full_op_buf[i], 134);
2473*bbecb9d1SAndroid Build Coastguard Worker    }
2474*bbecb9d1SAndroid Build Coastguard Worker 
2475*bbecb9d1SAndroid Build Coastguard Worker 
2476*bbecb9d1SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ctx->num_outputs; i++) {
2477*bbecb9d1SAndroid Build Coastguard Worker       mask[i] = (1 << ctx->key->fs.surface_component_bits[i]) - 1;
2478*bbecb9d1SAndroid Build Coastguard Worker       scale[i] = mask[i];
2479*bbecb9d1SAndroid Build Coastguard Worker       switch (ctx->key->fs.logicop_func) {
2480*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_INVERT:
2481*bbecb9d1SAndroid Build Coastguard Worker          snprintf(src_fb[i], ARRAY_SIZE(src_fb[i]),
2482*bbecb9d1SAndroid Build Coastguard Worker                   "ivec4(%f * fsout_c%d + 0.5)", scale[i], i);
2483*bbecb9d1SAndroid Build Coastguard Worker          break;
2484*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_NOR:
2485*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_AND_INVERTED:
2486*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_AND_REVERSE:
2487*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_XOR:
2488*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_NAND:
2489*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_AND:
2490*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_EQUIV:
2491*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_OR_INVERTED:
2492*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_OR_REVERSE:
2493*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_OR:
2494*bbecb9d1SAndroid Build Coastguard Worker          snprintf(src_fb[i], ARRAY_SIZE(src_fb[i]),
2495*bbecb9d1SAndroid Build Coastguard Worker                   "ivec4(%f * fsout_c%d + 0.5)", scale[i], i);
2496*bbecb9d1SAndroid Build Coastguard Worker          /* fallthrough */
2497*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_COPY_INVERTED:
2498*bbecb9d1SAndroid Build Coastguard Worker          snprintf(src[i], ARRAY_SIZE(src[i]),
2499*bbecb9d1SAndroid Build Coastguard Worker                   "ivec4(%f * fsout_tmp_c%d + 0.5)", scale[i], i);
2500*bbecb9d1SAndroid Build Coastguard Worker          break;
2501*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_COPY:
2502*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_NOOP:
2503*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_CLEAR:
2504*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_SET:
2505*bbecb9d1SAndroid Build Coastguard Worker          break;
2506*bbecb9d1SAndroid Build Coastguard Worker       }
2507*bbecb9d1SAndroid Build Coastguard Worker    }
2508*bbecb9d1SAndroid Build Coastguard Worker 
2509*bbecb9d1SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ctx->num_outputs; i++) {
2510*bbecb9d1SAndroid Build Coastguard Worker       switch (ctx->key->fs.logicop_func) {
2511*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_CLEAR:
2512*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "%s", "vec4(0)");
2513*bbecb9d1SAndroid Build Coastguard Worker          break;
2514*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_NOOP:
2515*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "%s", "");
2516*bbecb9d1SAndroid Build Coastguard Worker          break;
2517*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_SET:
2518*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "%s", "vec4(1)");
2519*bbecb9d1SAndroid Build Coastguard Worker          break;
2520*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_COPY:
2521*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "fsout_tmp_c%d", i);
2522*bbecb9d1SAndroid Build Coastguard Worker          break;
2523*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_COPY_INVERTED:
2524*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "~%s", src[i]);
2525*bbecb9d1SAndroid Build Coastguard Worker          break;
2526*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_INVERT:
2527*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "~%s", src_fb[i]);
2528*bbecb9d1SAndroid Build Coastguard Worker          break;
2529*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_AND:
2530*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "%s & %s", src[i], src_fb[i]);
2531*bbecb9d1SAndroid Build Coastguard Worker          break;
2532*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_NAND:
2533*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "~( %s & %s )", src[i], src_fb[i]);
2534*bbecb9d1SAndroid Build Coastguard Worker          break;
2535*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_NOR:
2536*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "~( %s | %s )", src[i], src_fb[i]);
2537*bbecb9d1SAndroid Build Coastguard Worker          break;
2538*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_AND_INVERTED:
2539*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "~%s & %s", src[i], src_fb[i]);
2540*bbecb9d1SAndroid Build Coastguard Worker          break;
2541*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_AND_REVERSE:
2542*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "%s & ~%s", src[i], src_fb[i]);
2543*bbecb9d1SAndroid Build Coastguard Worker          break;
2544*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_XOR:
2545*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "%s ^%s", src[i], src_fb[i]);
2546*bbecb9d1SAndroid Build Coastguard Worker          break;
2547*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_EQUIV:
2548*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "~( %s ^ %s )", src[i], src_fb[i]);
2549*bbecb9d1SAndroid Build Coastguard Worker          break;
2550*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_OR_INVERTED:
2551*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "~%s | %s", src[i], src_fb[i]);
2552*bbecb9d1SAndroid Build Coastguard Worker          break;
2553*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_OR_REVERSE:
2554*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "%s | ~%s", src[i], src_fb[i]);
2555*bbecb9d1SAndroid Build Coastguard Worker          break;
2556*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_OR:
2557*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&full_op_buf[i], "%s | %s", src[i], src_fb[i]);
2558*bbecb9d1SAndroid Build Coastguard Worker          break;
2559*bbecb9d1SAndroid Build Coastguard Worker       }
2560*bbecb9d1SAndroid Build Coastguard Worker    }
2561*bbecb9d1SAndroid Build Coastguard Worker 
2562*bbecb9d1SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ctx->num_outputs; i++) {
2563*bbecb9d1SAndroid Build Coastguard Worker       switch (ctx->key->fs.logicop_func) {
2564*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_NOOP:
2565*bbecb9d1SAndroid Build Coastguard Worker          break;
2566*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_COPY:
2567*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_CLEAR:
2568*bbecb9d1SAndroid Build Coastguard Worker       case PIPE_LOGICOP_SET:
2569*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(glsl_strbufs, "fsout_c%d = %s;\n", i, full_op_buf[i].buf);
2570*bbecb9d1SAndroid Build Coastguard Worker          break;
2571*bbecb9d1SAndroid Build Coastguard Worker       default:
2572*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(glsl_strbufs, "fsout_c%d = vec4((%s) & %d) / %f;\n", i, full_op_buf[i].buf, mask[i], scale[i]);
2573*bbecb9d1SAndroid Build Coastguard Worker       }
2574*bbecb9d1SAndroid Build Coastguard Worker    }
2575*bbecb9d1SAndroid Build Coastguard Worker }
2576*bbecb9d1SAndroid Build Coastguard Worker 
emit_cbuf_swizzle(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2577*bbecb9d1SAndroid Build Coastguard Worker static void emit_cbuf_swizzle(const struct dump_ctx *ctx,
2578*bbecb9d1SAndroid Build Coastguard Worker                               struct vrend_glsl_strbufs *glsl_strbufs)
2579*bbecb9d1SAndroid Build Coastguard Worker {
2580*bbecb9d1SAndroid Build Coastguard Worker    int cbuf_id = 0;
2581*bbecb9d1SAndroid Build Coastguard Worker    for (uint i = 0; i < ctx->num_outputs; i++) {
2582*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR) {
2583*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->key->fs.swizzle_output_rgb_to_bgr & (1 << cbuf_id)) {
2584*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(glsl_strbufs, "fsout_c%d = fsout_c%d.zyxw;\n", cbuf_id, cbuf_id);
2585*bbecb9d1SAndroid Build Coastguard Worker          }
2586*bbecb9d1SAndroid Build Coastguard Worker          ++cbuf_id;
2587*bbecb9d1SAndroid Build Coastguard Worker       }
2588*bbecb9d1SAndroid Build Coastguard Worker    }
2589*bbecb9d1SAndroid Build Coastguard Worker }
2590*bbecb9d1SAndroid Build Coastguard Worker 
emit_cbuf_colorspace_convert(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2591*bbecb9d1SAndroid Build Coastguard Worker static void emit_cbuf_colorspace_convert(const struct dump_ctx *ctx,
2592*bbecb9d1SAndroid Build Coastguard Worker                                          struct vrend_glsl_strbufs *glsl_strbufs)
2593*bbecb9d1SAndroid Build Coastguard Worker {
2594*bbecb9d1SAndroid Build Coastguard Worker    for (uint i = 0; i < ctx->num_outputs; i++) {
2595*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->key->fs.needs_manual_srgb_encode_bitmask & (1 << i)) {
2596*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(glsl_strbufs,
2597*bbecb9d1SAndroid Build Coastguard Worker                    "{\n"
2598*bbecb9d1SAndroid Build Coastguard Worker                    "   vec3 temp = fsout_c%d.xyz;\n"
2599*bbecb9d1SAndroid Build Coastguard Worker                    "   bvec3 thresh = lessThanEqual(temp, vec3(0.0031308));\n"
2600*bbecb9d1SAndroid Build Coastguard Worker                    "   vec3 a = temp * vec3(12.92);\n"
2601*bbecb9d1SAndroid Build Coastguard Worker                    "   vec3 b = ( vec3(1.055) * pow(temp, vec3(1.0/2.4)) ) - vec3(0.055);\n"
2602*bbecb9d1SAndroid Build Coastguard Worker                    "   fsout_c%d.xyz = mix(b, a, thresh);\n"
2603*bbecb9d1SAndroid Build Coastguard Worker                    "}\n"
2604*bbecb9d1SAndroid Build Coastguard Worker                    , i, i);
2605*bbecb9d1SAndroid Build Coastguard Worker       }
2606*bbecb9d1SAndroid Build Coastguard Worker    }
2607*bbecb9d1SAndroid Build Coastguard Worker }
2608*bbecb9d1SAndroid Build Coastguard Worker 
handle_fragment_proc_exit(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)2609*bbecb9d1SAndroid Build Coastguard Worker static void handle_fragment_proc_exit(const struct dump_ctx *ctx,
2610*bbecb9d1SAndroid Build Coastguard Worker                                       struct vrend_glsl_strbufs *glsl_strbufs)
2611*bbecb9d1SAndroid Build Coastguard Worker {
2612*bbecb9d1SAndroid Build Coastguard Worker     if (ctx->key->pstipple_enabled)
2613*bbecb9d1SAndroid Build Coastguard Worker        emit_pstipple_pass(glsl_strbufs);
2614*bbecb9d1SAndroid Build Coastguard Worker 
2615*bbecb9d1SAndroid Build Coastguard Worker     if (ctx->key->fs.cbufs_are_a8_bitmask)
2616*bbecb9d1SAndroid Build Coastguard Worker        emit_a8_swizzle(glsl_strbufs);
2617*bbecb9d1SAndroid Build Coastguard Worker 
2618*bbecb9d1SAndroid Build Coastguard Worker     if (ctx->key->add_alpha_test)
2619*bbecb9d1SAndroid Build Coastguard Worker        emit_alpha_test(ctx, glsl_strbufs);
2620*bbecb9d1SAndroid Build Coastguard Worker 
2621*bbecb9d1SAndroid Build Coastguard Worker 
2622*bbecb9d1SAndroid Build Coastguard Worker     if (ctx->key->fs.logicop_enabled)
2623*bbecb9d1SAndroid Build Coastguard Worker        emit_fragment_logicop(ctx, glsl_strbufs);
2624*bbecb9d1SAndroid Build Coastguard Worker 
2625*bbecb9d1SAndroid Build Coastguard Worker     if (ctx->key->fs.swizzle_output_rgb_to_bgr)
2626*bbecb9d1SAndroid Build Coastguard Worker        emit_cbuf_swizzle(ctx, glsl_strbufs);
2627*bbecb9d1SAndroid Build Coastguard Worker 
2628*bbecb9d1SAndroid Build Coastguard Worker     if (ctx->key->fs.needs_manual_srgb_encode_bitmask)
2629*bbecb9d1SAndroid Build Coastguard Worker        emit_cbuf_colorspace_convert(ctx, glsl_strbufs);
2630*bbecb9d1SAndroid Build Coastguard Worker 
2631*bbecb9d1SAndroid Build Coastguard Worker     if (ctx->write_all_cbufs)
2632*bbecb9d1SAndroid Build Coastguard Worker        emit_cbuf_writes(ctx, glsl_strbufs);
2633*bbecb9d1SAndroid Build Coastguard Worker 
2634*bbecb9d1SAndroid Build Coastguard Worker }
2635*bbecb9d1SAndroid Build Coastguard Worker 
2636*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
set_texture_reqs(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,uint32_t sreg_index)2637*bbecb9d1SAndroid Build Coastguard Worker static void set_texture_reqs(struct dump_ctx *ctx,
2638*bbecb9d1SAndroid Build Coastguard Worker                              const struct tgsi_full_instruction *inst,
2639*bbecb9d1SAndroid Build Coastguard Worker                              uint32_t sreg_index)
2640*bbecb9d1SAndroid Build Coastguard Worker {
2641*bbecb9d1SAndroid Build Coastguard Worker    if (sreg_index >= ARRAY_SIZE(ctx->samplers)) {
2642*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf( "Sampler view exceeded, max is %lu\n", ARRAY_SIZE(ctx->samplers));
2643*bbecb9d1SAndroid Build Coastguard Worker       set_buf_error(&ctx->glsl_strbufs);
2644*bbecb9d1SAndroid Build Coastguard Worker       return;
2645*bbecb9d1SAndroid Build Coastguard Worker    }
2646*bbecb9d1SAndroid Build Coastguard Worker    ctx->samplers[sreg_index].tgsi_sampler_type = inst->Texture.Texture;
2647*bbecb9d1SAndroid Build Coastguard Worker 
2648*bbecb9d1SAndroid Build Coastguard Worker    ctx->shader_req_bits |= samplertype_to_req_bits(inst->Texture.Texture);
2649*bbecb9d1SAndroid Build Coastguard Worker 
2650*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->cfg->glsl_version >= 140)
2651*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & (SHADER_REQ_SAMPLER_RECT |
2652*bbecb9d1SAndroid Build Coastguard Worker                                   SHADER_REQ_SAMPLER_BUF))
2653*bbecb9d1SAndroid Build Coastguard Worker          ctx->glsl_ver_required = require_glsl_ver(ctx, 140);
2654*bbecb9d1SAndroid Build Coastguard Worker }
2655*bbecb9d1SAndroid Build Coastguard Worker 
2656*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
2657*bbecb9d1SAndroid Build Coastguard Worker 
2658*bbecb9d1SAndroid Build Coastguard Worker /* size queries are pretty much separate */
emit_txq(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,uint32_t sreg_index,const char * srcs[4],const char * dst,const char * writemask)2659*bbecb9d1SAndroid Build Coastguard Worker static void emit_txq(struct dump_ctx *ctx,
2660*bbecb9d1SAndroid Build Coastguard Worker                      const struct tgsi_full_instruction *inst,
2661*bbecb9d1SAndroid Build Coastguard Worker                      uint32_t sreg_index,
2662*bbecb9d1SAndroid Build Coastguard Worker                      const char *srcs[4],
2663*bbecb9d1SAndroid Build Coastguard Worker                      const char *dst,
2664*bbecb9d1SAndroid Build Coastguard Worker                      const char *writemask)
2665*bbecb9d1SAndroid Build Coastguard Worker {
2666*bbecb9d1SAndroid Build Coastguard Worker    unsigned twm = TGSI_WRITEMASK_NONE;
2667*bbecb9d1SAndroid Build Coastguard Worker    char bias[128] = "";
2668*bbecb9d1SAndroid Build Coastguard Worker    const int sampler_index = 1;
2669*bbecb9d1SAndroid Build Coastguard Worker    enum vrend_type_qualifier dtypeprefix = INT_BITS_TO_FLOAT;
2670*bbecb9d1SAndroid Build Coastguard Worker 
2671*bbecb9d1SAndroid Build Coastguard Worker    set_texture_reqs(ctx, inst, sreg_index);
2672*bbecb9d1SAndroid Build Coastguard Worker 
2673*bbecb9d1SAndroid Build Coastguard Worker    /* No LOD for these texture types, but on GLES we emulate RECT by using
2674*bbecb9d1SAndroid Build Coastguard Worker     * a normal 2D texture, so we have to give LOD 0 */
2675*bbecb9d1SAndroid Build Coastguard Worker    switch (inst->Texture.Texture) {
2676*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_RECT:
2677*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWRECT:
2678*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->use_gles) {
2679*bbecb9d1SAndroid Build Coastguard Worker          snprintf(bias, 128, ", 0");
2680*bbecb9d1SAndroid Build Coastguard Worker          break;
2681*bbecb9d1SAndroid Build Coastguard Worker       }
2682*bbecb9d1SAndroid Build Coastguard Worker       /* fallthrough */
2683*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_BUFFER:
2684*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_MSAA:
2685*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_ARRAY_MSAA:
2686*bbecb9d1SAndroid Build Coastguard Worker       break;
2687*bbecb9d1SAndroid Build Coastguard Worker    default:
2688*bbecb9d1SAndroid Build Coastguard Worker       snprintf(bias, 128, ", int(%s.x)", srcs[0]);
2689*bbecb9d1SAndroid Build Coastguard Worker    }
2690*bbecb9d1SAndroid Build Coastguard Worker 
2691*bbecb9d1SAndroid Build Coastguard Worker    /* need to emit a textureQueryLevels */
2692*bbecb9d1SAndroid Build Coastguard Worker    if (inst->Dst[0].Register.WriteMask & 0x8) {
2693*bbecb9d1SAndroid Build Coastguard Worker 
2694*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Texture.Texture != TGSI_TEXTURE_BUFFER &&
2695*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture != TGSI_TEXTURE_RECT &&
2696*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture != TGSI_TEXTURE_2D_MSAA &&
2697*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture != TGSI_TEXTURE_2D_ARRAY_MSAA) {
2698*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_TXQ_LEVELS;
2699*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Dst[0].Register.WriteMask & 0x7)
2700*bbecb9d1SAndroid Build Coastguard Worker             twm = TGSI_WRITEMASK_W;
2701*bbecb9d1SAndroid Build Coastguard Worker 
2702*bbecb9d1SAndroid Build Coastguard Worker          if (!ctx->cfg->use_gles) {
2703*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(&ctx->glsl_strbufs, "%s%s = %s(textureQueryLevels(%s));\n", dst,
2704*bbecb9d1SAndroid Build Coastguard Worker                       get_wm_string(twm), get_string(dtypeprefix),
2705*bbecb9d1SAndroid Build Coastguard Worker                       srcs[sampler_index]);
2706*bbecb9d1SAndroid Build Coastguard Worker          } else {
2707*bbecb9d1SAndroid Build Coastguard Worker             const struct tgsi_full_src_register *src = &inst->Src[1];
2708*bbecb9d1SAndroid Build Coastguard Worker 
2709*bbecb9d1SAndroid Build Coastguard Worker             int gles_sampler_index = 0;
2710*bbecb9d1SAndroid Build Coastguard Worker             for (int i = 0; i < src->Register.Index; ++i) {
2711*bbecb9d1SAndroid Build Coastguard Worker                if (ctx->samplers_used & (1 << i))
2712*bbecb9d1SAndroid Build Coastguard Worker                   ++gles_sampler_index;
2713*bbecb9d1SAndroid Build Coastguard Worker             }
2714*bbecb9d1SAndroid Build Coastguard Worker 
2715*bbecb9d1SAndroid Build Coastguard Worker             char sampler_str[64];
2716*bbecb9d1SAndroid Build Coastguard Worker 
2717*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER) && src->Register.Indirect) {
2718*bbecb9d1SAndroid Build Coastguard Worker                snprintf(sampler_str, sizeof(sampler_str), "addr%d+%d", src->Indirect.Index, gles_sampler_index);
2719*bbecb9d1SAndroid Build Coastguard Worker             } else {
2720*bbecb9d1SAndroid Build Coastguard Worker                snprintf(sampler_str, sizeof(sampler_str), "%d", gles_sampler_index);
2721*bbecb9d1SAndroid Build Coastguard Worker             }
2722*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(&ctx->glsl_strbufs, "%s%s = %s(%s_texlod[%s]);\n", dst, get_wm_string(twm),
2723*bbecb9d1SAndroid Build Coastguard Worker                       get_string(dtypeprefix), tgsi_proc_to_prefix(ctx->info.processor),
2724*bbecb9d1SAndroid Build Coastguard Worker                       sampler_str);
2725*bbecb9d1SAndroid Build Coastguard Worker             ctx->gles_use_tex_query_level = true;
2726*bbecb9d1SAndroid Build Coastguard Worker          }
2727*bbecb9d1SAndroid Build Coastguard Worker       }
2728*bbecb9d1SAndroid Build Coastguard Worker 
2729*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Dst[0].Register.WriteMask & 0x7) {
2730*bbecb9d1SAndroid Build Coastguard Worker          switch (inst->Texture.Texture) {
2731*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_1D:
2732*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_BUFFER:
2733*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOW1D:
2734*bbecb9d1SAndroid Build Coastguard Worker             twm = TGSI_WRITEMASK_X;
2735*bbecb9d1SAndroid Build Coastguard Worker             break;
2736*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_1D_ARRAY:
2737*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOW1D_ARRAY:
2738*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_2D:
2739*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOW2D:
2740*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_RECT:
2741*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOWRECT:
2742*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_CUBE:
2743*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOWCUBE:
2744*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_2D_MSAA:
2745*bbecb9d1SAndroid Build Coastguard Worker             twm = TGSI_WRITEMASK_XY;
2746*bbecb9d1SAndroid Build Coastguard Worker             break;
2747*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_3D:
2748*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_2D_ARRAY:
2749*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOW2D_ARRAY:
2750*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
2751*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_CUBE_ARRAY:
2752*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_2D_ARRAY_MSAA:
2753*bbecb9d1SAndroid Build Coastguard Worker             twm = TGSI_WRITEMASK_XYZ;
2754*bbecb9d1SAndroid Build Coastguard Worker             break;
2755*bbecb9d1SAndroid Build Coastguard Worker          }
2756*bbecb9d1SAndroid Build Coastguard Worker       }
2757*bbecb9d1SAndroid Build Coastguard Worker    }
2758*bbecb9d1SAndroid Build Coastguard Worker 
2759*bbecb9d1SAndroid Build Coastguard Worker    if (inst->Dst[0].Register.WriteMask & 0x7) {
2760*bbecb9d1SAndroid Build Coastguard Worker       char wm_buffer[16];
2761*bbecb9d1SAndroid Build Coastguard Worker       bool txq_returns_vec = (inst->Texture.Texture != TGSI_TEXTURE_BUFFER) &&
2762*bbecb9d1SAndroid Build Coastguard Worker                              (ctx->cfg->use_gles ||
2763*bbecb9d1SAndroid Build Coastguard Worker                               (inst->Texture.Texture != TGSI_TEXTURE_1D &&
2764*bbecb9d1SAndroid Build Coastguard Worker                                inst->Texture.Texture != TGSI_TEXTURE_SHADOW1D));
2765*bbecb9d1SAndroid Build Coastguard Worker 
2766*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->use_gles &&
2767*bbecb9d1SAndroid Build Coastguard Worker           (inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY ||
2768*bbecb9d1SAndroid Build Coastguard Worker            inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY)) {
2769*bbecb9d1SAndroid Build Coastguard Worker          snprintf(wm_buffer, sizeof(wm_buffer), ".xz%s", writemask);
2770*bbecb9d1SAndroid Build Coastguard Worker          writemask = wm_buffer;
2771*bbecb9d1SAndroid Build Coastguard Worker       }
2772*bbecb9d1SAndroid Build Coastguard Worker 
2773*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s%s = %s(textureSize(%s%s))%s;\n", dst,
2774*bbecb9d1SAndroid Build Coastguard Worker                 get_wm_string(twm), get_string(dtypeprefix),
2775*bbecb9d1SAndroid Build Coastguard Worker                 srcs[sampler_index], bias, txq_returns_vec ? writemask : "");
2776*bbecb9d1SAndroid Build Coastguard Worker    }
2777*bbecb9d1SAndroid Build Coastguard Worker }
2778*bbecb9d1SAndroid Build Coastguard Worker 
2779*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
2780*bbecb9d1SAndroid Build Coastguard Worker /* sample queries are pretty much separate */
emit_txqs(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,uint32_t sreg_index,const char * srcs[4],const char * dst)2781*bbecb9d1SAndroid Build Coastguard Worker static void emit_txqs(struct dump_ctx *ctx,
2782*bbecb9d1SAndroid Build Coastguard Worker                       const struct tgsi_full_instruction *inst,
2783*bbecb9d1SAndroid Build Coastguard Worker                       uint32_t sreg_index,
2784*bbecb9d1SAndroid Build Coastguard Worker                       const char *srcs[4],
2785*bbecb9d1SAndroid Build Coastguard Worker                       const char *dst)
2786*bbecb9d1SAndroid Build Coastguard Worker {
2787*bbecb9d1SAndroid Build Coastguard Worker    const int sampler_index = 0;
2788*bbecb9d1SAndroid Build Coastguard Worker    enum vrend_type_qualifier dtypeprefix = INT_BITS_TO_FLOAT;
2789*bbecb9d1SAndroid Build Coastguard Worker 
2790*bbecb9d1SAndroid Build Coastguard Worker    ctx->shader_req_bits |= SHADER_REQ_TXQS;
2791*bbecb9d1SAndroid Build Coastguard Worker    set_texture_reqs(ctx, inst, sreg_index);
2792*bbecb9d1SAndroid Build Coastguard Worker 
2793*bbecb9d1SAndroid Build Coastguard Worker    if (inst->Texture.Texture != TGSI_TEXTURE_2D_MSAA &&
2794*bbecb9d1SAndroid Build Coastguard Worker        inst->Texture.Texture != TGSI_TEXTURE_2D_ARRAY_MSAA) {
2795*bbecb9d1SAndroid Build Coastguard Worker       set_buf_error(&ctx->glsl_strbufs);
2796*bbecb9d1SAndroid Build Coastguard Worker       return;
2797*bbecb9d1SAndroid Build Coastguard Worker    }
2798*bbecb9d1SAndroid Build Coastguard Worker 
2799*bbecb9d1SAndroid Build Coastguard Worker    emit_buff(&ctx->glsl_strbufs, "%s = %s(textureSamples(%s));\n", dst,
2800*bbecb9d1SAndroid Build Coastguard Worker             get_string(dtypeprefix), srcs[sampler_index]);
2801*bbecb9d1SAndroid Build Coastguard Worker }
2802*bbecb9d1SAndroid Build Coastguard Worker 
get_tex_inst_ext(const struct tgsi_full_instruction * inst)2803*bbecb9d1SAndroid Build Coastguard Worker static const char *get_tex_inst_ext(const struct tgsi_full_instruction *inst)
2804*bbecb9d1SAndroid Build Coastguard Worker {
2805*bbecb9d1SAndroid Build Coastguard Worker    switch (inst->Instruction.Opcode) {
2806*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXP:
2807*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
2808*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY ||
2809*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY)
2810*bbecb9d1SAndroid Build Coastguard Worker          return "";
2811*bbecb9d1SAndroid Build Coastguard Worker       else if (inst->Texture.NumOffsets == 1)
2812*bbecb9d1SAndroid Build Coastguard Worker          return "ProjOffset";
2813*bbecb9d1SAndroid Build Coastguard Worker       else
2814*bbecb9d1SAndroid Build Coastguard Worker          return "Proj";
2815*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXL:
2816*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXL2:
2817*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Texture.NumOffsets == 1)
2818*bbecb9d1SAndroid Build Coastguard Worker          return "LodOffset";
2819*bbecb9d1SAndroid Build Coastguard Worker       else
2820*bbecb9d1SAndroid Build Coastguard Worker          return "Lod";
2821*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXD:
2822*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Texture.NumOffsets == 1)
2823*bbecb9d1SAndroid Build Coastguard Worker          return "GradOffset";
2824*bbecb9d1SAndroid Build Coastguard Worker       else
2825*bbecb9d1SAndroid Build Coastguard Worker          return "Grad";
2826*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TG4:
2827*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Texture.NumOffsets == 4)
2828*bbecb9d1SAndroid Build Coastguard Worker          return "GatherOffsets";
2829*bbecb9d1SAndroid Build Coastguard Worker       else if (inst->Texture.NumOffsets == 1)
2830*bbecb9d1SAndroid Build Coastguard Worker          return "GatherOffset";
2831*bbecb9d1SAndroid Build Coastguard Worker       else
2832*bbecb9d1SAndroid Build Coastguard Worker          return "Gather";
2833*bbecb9d1SAndroid Build Coastguard Worker    default:
2834*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Texture.NumOffsets == 1)
2835*bbecb9d1SAndroid Build Coastguard Worker          return "Offset";
2836*bbecb9d1SAndroid Build Coastguard Worker       else
2837*bbecb9d1SAndroid Build Coastguard Worker          return  "";
2838*bbecb9d1SAndroid Build Coastguard Worker    }
2839*bbecb9d1SAndroid Build Coastguard Worker }
2840*bbecb9d1SAndroid Build Coastguard Worker 
2841*bbecb9d1SAndroid Build Coastguard Worker static void
get_temp(const struct dump_ctx * ctx,bool indirect_dim,int dim,int reg,char buf[static64],bool * require_dummy_value)2842*bbecb9d1SAndroid Build Coastguard Worker get_temp(const struct dump_ctx *ctx,
2843*bbecb9d1SAndroid Build Coastguard Worker          bool indirect_dim, int dim, int reg,
2844*bbecb9d1SAndroid Build Coastguard Worker          char buf[static 64], bool *require_dummy_value)
2845*bbecb9d1SAndroid Build Coastguard Worker {
2846*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_temp_range *range = find_temp_range(ctx, reg);
2847*bbecb9d1SAndroid Build Coastguard Worker    if (range) {
2848*bbecb9d1SAndroid Build Coastguard Worker       if (indirect_dim) {
2849*bbecb9d1SAndroid Build Coastguard Worker          snprintf(buf, 64, "temp%d[addr%d + %d]", range->first, dim, reg - range->first);
2850*bbecb9d1SAndroid Build Coastguard Worker       } else {
2851*bbecb9d1SAndroid Build Coastguard Worker          if (range->array_id > 0) {
2852*bbecb9d1SAndroid Build Coastguard Worker             snprintf(buf, 64, "temp%d[%d]", range->first, reg - range->first);
2853*bbecb9d1SAndroid Build Coastguard Worker          } else {
2854*bbecb9d1SAndroid Build Coastguard Worker             snprintf(buf, 64, "temp%d", reg);
2855*bbecb9d1SAndroid Build Coastguard Worker          }
2856*bbecb9d1SAndroid Build Coastguard Worker       }
2857*bbecb9d1SAndroid Build Coastguard Worker    } else {
2858*bbecb9d1SAndroid Build Coastguard Worker       snprintf(buf, 64, "dummy_value");
2859*bbecb9d1SAndroid Build Coastguard Worker       *require_dummy_value = true;
2860*bbecb9d1SAndroid Build Coastguard Worker    }
2861*bbecb9d1SAndroid Build Coastguard Worker }
2862*bbecb9d1SAndroid Build Coastguard Worker 
fill_offset_buffer(const struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,struct vrend_strbuf * offset_buf,bool * require_dummy_value)2863*bbecb9d1SAndroid Build Coastguard Worker static bool fill_offset_buffer(const struct dump_ctx *ctx,
2864*bbecb9d1SAndroid Build Coastguard Worker                                const struct tgsi_full_instruction *inst,
2865*bbecb9d1SAndroid Build Coastguard Worker                                struct vrend_strbuf *offset_buf,
2866*bbecb9d1SAndroid Build Coastguard Worker                                bool *require_dummy_value)
2867*bbecb9d1SAndroid Build Coastguard Worker {
2868*bbecb9d1SAndroid Build Coastguard Worker    if (inst->TexOffsets[0].File == TGSI_FILE_IMMEDIATE) {
2869*bbecb9d1SAndroid Build Coastguard Worker       const struct immed *imd = &ctx->imm[inst->TexOffsets[0].Index];
2870*bbecb9d1SAndroid Build Coastguard Worker       switch (inst->Texture.Texture) {
2871*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_1D:
2872*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_1D_ARRAY:
2873*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW1D:
2874*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW1D_ARRAY:
2875*bbecb9d1SAndroid Build Coastguard Worker          if (!ctx->cfg->use_gles)
2876*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(offset_buf, ", int(%d)", imd->val[inst->TexOffsets[0].SwizzleX].i);
2877*bbecb9d1SAndroid Build Coastguard Worker          else
2878*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(offset_buf, ", ivec2(%d, 0)", imd->val[inst->TexOffsets[0].SwizzleX].i);
2879*bbecb9d1SAndroid Build Coastguard Worker          break;
2880*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_RECT:
2881*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOWRECT:
2882*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_2D:
2883*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_2D_ARRAY:
2884*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW2D:
2885*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW2D_ARRAY:
2886*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(offset_buf, ", ivec2(%d, %d)", imd->val[inst->TexOffsets[0].SwizzleX].i, imd->val[inst->TexOffsets[0].SwizzleY].i);
2887*bbecb9d1SAndroid Build Coastguard Worker          break;
2888*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_3D:
2889*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(offset_buf, ", ivec3(%d, %d, %d)", imd->val[inst->TexOffsets[0].SwizzleX].i, imd->val[inst->TexOffsets[0].SwizzleY].i,
2890*bbecb9d1SAndroid Build Coastguard Worker                   imd->val[inst->TexOffsets[0].SwizzleZ].i);
2891*bbecb9d1SAndroid Build Coastguard Worker          break;
2892*bbecb9d1SAndroid Build Coastguard Worker       default:
2893*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "unhandled texture: %x\n", inst->Texture.Texture);
2894*bbecb9d1SAndroid Build Coastguard Worker          return false;
2895*bbecb9d1SAndroid Build Coastguard Worker       }
2896*bbecb9d1SAndroid Build Coastguard Worker    } else if (inst->TexOffsets[0].File == TGSI_FILE_TEMPORARY) {
2897*bbecb9d1SAndroid Build Coastguard Worker       char temp_buf[64];
2898*bbecb9d1SAndroid Build Coastguard Worker       get_temp(ctx, false, 0, inst->TexOffsets[0].Index, temp_buf, require_dummy_value);
2899*bbecb9d1SAndroid Build Coastguard Worker       switch (inst->Texture.Texture) {
2900*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_1D:
2901*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_1D_ARRAY:
2902*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW1D:
2903*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW1D_ARRAY:
2904*bbecb9d1SAndroid Build Coastguard Worker 
2905*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(offset_buf, ", int(floatBitsToInt(%s.%c))",
2906*bbecb9d1SAndroid Build Coastguard Worker                   temp_buf,
2907*bbecb9d1SAndroid Build Coastguard Worker                   get_swiz_char(inst->TexOffsets[0].SwizzleX));
2908*bbecb9d1SAndroid Build Coastguard Worker          break;
2909*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_RECT:
2910*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOWRECT:
2911*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_2D:
2912*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_2D_ARRAY:
2913*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW2D:
2914*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW2D_ARRAY:
2915*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(offset_buf, ", ivec2(floatBitsToInt(%s.%c), floatBitsToInt(%s.%c))",
2916*bbecb9d1SAndroid Build Coastguard Worker                   temp_buf,
2917*bbecb9d1SAndroid Build Coastguard Worker                   get_swiz_char(inst->TexOffsets[0].SwizzleX),
2918*bbecb9d1SAndroid Build Coastguard Worker                   temp_buf,
2919*bbecb9d1SAndroid Build Coastguard Worker                   get_swiz_char(inst->TexOffsets[0].SwizzleY));
2920*bbecb9d1SAndroid Build Coastguard Worker             break;
2921*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_3D:
2922*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(offset_buf, ", ivec3(floatBitsToInt(%s.%c), floatBitsToInt(%s.%c), floatBitsToInt(%s.%c)",
2923*bbecb9d1SAndroid Build Coastguard Worker                   temp_buf,
2924*bbecb9d1SAndroid Build Coastguard Worker                   get_swiz_char(inst->TexOffsets[0].SwizzleX),
2925*bbecb9d1SAndroid Build Coastguard Worker                   temp_buf,
2926*bbecb9d1SAndroid Build Coastguard Worker                   get_swiz_char(inst->TexOffsets[0].SwizzleY),
2927*bbecb9d1SAndroid Build Coastguard Worker                   temp_buf,
2928*bbecb9d1SAndroid Build Coastguard Worker                   get_swiz_char(inst->TexOffsets[0].SwizzleZ));
2929*bbecb9d1SAndroid Build Coastguard Worker          break;
2930*bbecb9d1SAndroid Build Coastguard Worker       default:
2931*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "unhandled texture: %x\n", inst->Texture.Texture);
2932*bbecb9d1SAndroid Build Coastguard Worker          return false;
2933*bbecb9d1SAndroid Build Coastguard Worker          break;
2934*bbecb9d1SAndroid Build Coastguard Worker       }
2935*bbecb9d1SAndroid Build Coastguard Worker    } else if (inst->TexOffsets[0].File == TGSI_FILE_INPUT) {
2936*bbecb9d1SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < ctx->num_inputs; j++) {
2937*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[j].first != inst->TexOffsets[0].Index)
2938*bbecb9d1SAndroid Build Coastguard Worker             continue;
2939*bbecb9d1SAndroid Build Coastguard Worker          switch (inst->Texture.Texture) {
2940*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_1D:
2941*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_1D_ARRAY:
2942*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOW1D:
2943*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOW1D_ARRAY:
2944*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(offset_buf, ", int(floatBitsToInt(%s.%c))",
2945*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[j].glsl_name,
2946*bbecb9d1SAndroid Build Coastguard Worker                      get_swiz_char(inst->TexOffsets[0].SwizzleX));
2947*bbecb9d1SAndroid Build Coastguard Worker             break;
2948*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_RECT:
2949*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOWRECT:
2950*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_2D:
2951*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_2D_ARRAY:
2952*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOW2D:
2953*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_SHADOW2D_ARRAY:
2954*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(offset_buf, ", ivec2(floatBitsToInt(%s.%c), floatBitsToInt(%s.%c))",
2955*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[j].glsl_name,
2956*bbecb9d1SAndroid Build Coastguard Worker                      get_swiz_char(inst->TexOffsets[0].SwizzleX),
2957*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[j].glsl_name,
2958*bbecb9d1SAndroid Build Coastguard Worker                      get_swiz_char(inst->TexOffsets[0].SwizzleY));
2959*bbecb9d1SAndroid Build Coastguard Worker             break;
2960*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_TEXTURE_3D:
2961*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(offset_buf, ", ivec3(floatBitsToInt(%s.%c), floatBitsToInt(%s.%c), floatBitsToInt(%s.%c)",
2962*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[j].glsl_name,
2963*bbecb9d1SAndroid Build Coastguard Worker                      get_swiz_char(inst->TexOffsets[0].SwizzleX),
2964*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[j].glsl_name,
2965*bbecb9d1SAndroid Build Coastguard Worker                      get_swiz_char(inst->TexOffsets[0].SwizzleY),
2966*bbecb9d1SAndroid Build Coastguard Worker                      ctx->inputs[j].glsl_name,
2967*bbecb9d1SAndroid Build Coastguard Worker                      get_swiz_char(inst->TexOffsets[0].SwizzleZ));
2968*bbecb9d1SAndroid Build Coastguard Worker             break;
2969*bbecb9d1SAndroid Build Coastguard Worker          default:
2970*bbecb9d1SAndroid Build Coastguard Worker             vrend_printf( "unhandled texture: %x\n", inst->Texture.Texture);
2971*bbecb9d1SAndroid Build Coastguard Worker             return false;
2972*bbecb9d1SAndroid Build Coastguard Worker             break;
2973*bbecb9d1SAndroid Build Coastguard Worker          }
2974*bbecb9d1SAndroid Build Coastguard Worker       }
2975*bbecb9d1SAndroid Build Coastguard Worker    }
2976*bbecb9d1SAndroid Build Coastguard Worker    return true;
2977*bbecb9d1SAndroid Build Coastguard Worker }
2978*bbecb9d1SAndroid Build Coastguard Worker 
2979*bbecb9d1SAndroid Build Coastguard Worker static void
emit_lodq(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,const struct source_info * sinfo,const struct dest_info * dinfo,const char * srcs[4],const char * dst,const char * writemask)2980*bbecb9d1SAndroid Build Coastguard Worker emit_lodq(struct dump_ctx *ctx,
2981*bbecb9d1SAndroid Build Coastguard Worker           const struct tgsi_full_instruction *inst,
2982*bbecb9d1SAndroid Build Coastguard Worker           const struct source_info *sinfo,
2983*bbecb9d1SAndroid Build Coastguard Worker           const struct dest_info *dinfo,
2984*bbecb9d1SAndroid Build Coastguard Worker           const char *srcs[4],
2985*bbecb9d1SAndroid Build Coastguard Worker           const char *dst,
2986*bbecb9d1SAndroid Build Coastguard Worker           const char *writemask)
2987*bbecb9d1SAndroid Build Coastguard Worker {
2988*bbecb9d1SAndroid Build Coastguard Worker    ctx->shader_req_bits |= SHADER_REQ_LODQ;
2989*bbecb9d1SAndroid Build Coastguard Worker 
2990*bbecb9d1SAndroid Build Coastguard Worker    set_texture_reqs(ctx, inst, sinfo->sreg_index);
2991*bbecb9d1SAndroid Build Coastguard Worker 
2992*bbecb9d1SAndroid Build Coastguard Worker    emit_buff(&ctx->glsl_strbufs, "%s = %s(textureQueryLOD(%s, ",
2993*bbecb9d1SAndroid Build Coastguard Worker           dst, get_string(dinfo->dstconv), srcs[1]);
2994*bbecb9d1SAndroid Build Coastguard Worker 
2995*bbecb9d1SAndroid Build Coastguard Worker    switch (inst->Texture.Texture) {
2996*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_1D:
2997*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_1D_ARRAY:
2998*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW1D:
2999*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW1D_ARRAY:
3000*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->use_gles)
3001*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "vec2(%s.x, 0)", srcs[0]);
3002*bbecb9d1SAndroid Build Coastguard Worker       else
3003*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s.x", srcs[0]);
3004*bbecb9d1SAndroid Build Coastguard Worker       break;
3005*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D:
3006*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_ARRAY:
3007*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_MSAA:
3008*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_ARRAY_MSAA:
3009*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_RECT:
3010*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW2D:
3011*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW2D_ARRAY:
3012*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWRECT:
3013*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s.xy", srcs[0]);
3014*bbecb9d1SAndroid Build Coastguard Worker       break;
3015*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_3D:
3016*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_CUBE:
3017*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWCUBE:
3018*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
3019*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_CUBE_ARRAY:
3020*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s.xyz", srcs[0]);
3021*bbecb9d1SAndroid Build Coastguard Worker       break;
3022*bbecb9d1SAndroid Build Coastguard Worker    default:
3023*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s", srcs[0]);
3024*bbecb9d1SAndroid Build Coastguard Worker       break;
3025*bbecb9d1SAndroid Build Coastguard Worker    }
3026*bbecb9d1SAndroid Build Coastguard Worker 
3027*bbecb9d1SAndroid Build Coastguard Worker    emit_buff(&ctx->glsl_strbufs, ")%s);\n", writemask);
3028*bbecb9d1SAndroid Build Coastguard Worker }
3029*bbecb9d1SAndroid Build Coastguard Worker 
3030*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
translate_tex(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,const struct source_info * sinfo,const struct dest_info * dinfo,const char * srcs[4],const char * dst,const char * writemask)3031*bbecb9d1SAndroid Build Coastguard Worker static void translate_tex(struct dump_ctx *ctx,
3032*bbecb9d1SAndroid Build Coastguard Worker                           const struct tgsi_full_instruction *inst,
3033*bbecb9d1SAndroid Build Coastguard Worker                           const struct source_info *sinfo,
3034*bbecb9d1SAndroid Build Coastguard Worker                           const struct dest_info *dinfo,
3035*bbecb9d1SAndroid Build Coastguard Worker                           const char *srcs[4],
3036*bbecb9d1SAndroid Build Coastguard Worker                           const char *dst,
3037*bbecb9d1SAndroid Build Coastguard Worker                           const char *writemask)
3038*bbecb9d1SAndroid Build Coastguard Worker {
3039*bbecb9d1SAndroid Build Coastguard Worker    enum vrend_type_qualifier txfi = TYPE_CONVERSION_NONE;
3040*bbecb9d1SAndroid Build Coastguard Worker    const char *src_swizzle;
3041*bbecb9d1SAndroid Build Coastguard Worker    enum vrend_type_qualifier dtypeprefix = TYPE_CONVERSION_NONE;
3042*bbecb9d1SAndroid Build Coastguard Worker    bool is_shad;
3043*bbecb9d1SAndroid Build Coastguard Worker 
3044*bbecb9d1SAndroid Build Coastguard Worker    int sampler_index = 1;
3045*bbecb9d1SAndroid Build Coastguard Worker    const char *tex_ext;
3046*bbecb9d1SAndroid Build Coastguard Worker 
3047*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_strbuf bias_buf;
3048*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_strbuf offset_buf;
3049*bbecb9d1SAndroid Build Coastguard Worker 
3050*bbecb9d1SAndroid Build Coastguard Worker    strbuf_alloc(&bias_buf, 128);
3051*bbecb9d1SAndroid Build Coastguard Worker    strbuf_alloc(&offset_buf, 128);
3052*bbecb9d1SAndroid Build Coastguard Worker 
3053*bbecb9d1SAndroid Build Coastguard Worker    set_texture_reqs(ctx, inst, sinfo->sreg_index);
3054*bbecb9d1SAndroid Build Coastguard Worker    is_shad = samplertype_is_shadow(inst->Texture.Texture);
3055*bbecb9d1SAndroid Build Coastguard Worker 
3056*bbecb9d1SAndroid Build Coastguard Worker    switch (ctx->samplers[sinfo->sreg_index].tgsi_sampler_return) {
3057*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_RETURN_TYPE_SINT:
3058*bbecb9d1SAndroid Build Coastguard Worker       /* if dstconv isn't an int */
3059*bbecb9d1SAndroid Build Coastguard Worker       if (dinfo->dstconv != INT)
3060*bbecb9d1SAndroid Build Coastguard Worker          dtypeprefix = INT_BITS_TO_FLOAT;
3061*bbecb9d1SAndroid Build Coastguard Worker       break;
3062*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_RETURN_TYPE_UINT:
3063*bbecb9d1SAndroid Build Coastguard Worker       /* if dstconv isn't an int */
3064*bbecb9d1SAndroid Build Coastguard Worker       if (dinfo->dstconv != INT)
3065*bbecb9d1SAndroid Build Coastguard Worker          dtypeprefix = UINT_BITS_TO_FLOAT;
3066*bbecb9d1SAndroid Build Coastguard Worker       break;
3067*bbecb9d1SAndroid Build Coastguard Worker    default:
3068*bbecb9d1SAndroid Build Coastguard Worker       break;
3069*bbecb9d1SAndroid Build Coastguard Worker    }
3070*bbecb9d1SAndroid Build Coastguard Worker 
3071*bbecb9d1SAndroid Build Coastguard Worker    switch (inst->Texture.Texture) {
3072*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_1D:
3073*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_BUFFER:
3074*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3075*bbecb9d1SAndroid Build Coastguard Worker          src_swizzle = "";
3076*bbecb9d1SAndroid Build Coastguard Worker       else
3077*bbecb9d1SAndroid Build Coastguard Worker          src_swizzle = ".x";
3078*bbecb9d1SAndroid Build Coastguard Worker       txfi = INT;
3079*bbecb9d1SAndroid Build Coastguard Worker       break;
3080*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_1D_ARRAY:
3081*bbecb9d1SAndroid Build Coastguard Worker       src_swizzle = ".xy";
3082*bbecb9d1SAndroid Build Coastguard Worker       txfi = IVEC2;
3083*bbecb9d1SAndroid Build Coastguard Worker       break;
3084*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D:
3085*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_RECT:
3086*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3087*bbecb9d1SAndroid Build Coastguard Worker          src_swizzle = "";
3088*bbecb9d1SAndroid Build Coastguard Worker       else
3089*bbecb9d1SAndroid Build Coastguard Worker          src_swizzle = ".xy";
3090*bbecb9d1SAndroid Build Coastguard Worker       txfi = IVEC2;
3091*bbecb9d1SAndroid Build Coastguard Worker       break;
3092*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW1D:
3093*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW2D:
3094*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW1D_ARRAY:
3095*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWRECT:
3096*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_3D:
3097*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3098*bbecb9d1SAndroid Build Coastguard Worker          src_swizzle = "";
3099*bbecb9d1SAndroid Build Coastguard Worker       else if (inst->Instruction.Opcode == TGSI_OPCODE_TG4)
3100*bbecb9d1SAndroid Build Coastguard Worker          src_swizzle = ".xy";
3101*bbecb9d1SAndroid Build Coastguard Worker       else
3102*bbecb9d1SAndroid Build Coastguard Worker          src_swizzle = ".xyz";
3103*bbecb9d1SAndroid Build Coastguard Worker       txfi = IVEC3;
3104*bbecb9d1SAndroid Build Coastguard Worker       break;
3105*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_CUBE:
3106*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_ARRAY:
3107*bbecb9d1SAndroid Build Coastguard Worker       src_swizzle = ".xyz";
3108*bbecb9d1SAndroid Build Coastguard Worker       txfi = IVEC3;
3109*bbecb9d1SAndroid Build Coastguard Worker       break;
3110*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_MSAA:
3111*bbecb9d1SAndroid Build Coastguard Worker       src_swizzle = ".xy";
3112*bbecb9d1SAndroid Build Coastguard Worker       txfi = IVEC2;
3113*bbecb9d1SAndroid Build Coastguard Worker       break;
3114*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_ARRAY_MSAA:
3115*bbecb9d1SAndroid Build Coastguard Worker       src_swizzle = ".xyz";
3116*bbecb9d1SAndroid Build Coastguard Worker       txfi = IVEC3;
3117*bbecb9d1SAndroid Build Coastguard Worker       break;
3118*bbecb9d1SAndroid Build Coastguard Worker 
3119*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWCUBE:
3120*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW2D_ARRAY:
3121*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
3122*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_CUBE_ARRAY:
3123*bbecb9d1SAndroid Build Coastguard Worker    default:
3124*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Instruction.Opcode == TGSI_OPCODE_TG4 &&
3125*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture != TGSI_TEXTURE_CUBE_ARRAY &&
3126*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture != TGSI_TEXTURE_SHADOWCUBE_ARRAY)
3127*bbecb9d1SAndroid Build Coastguard Worker          src_swizzle = ".xyz";
3128*bbecb9d1SAndroid Build Coastguard Worker       else
3129*bbecb9d1SAndroid Build Coastguard Worker          src_swizzle = "";
3130*bbecb9d1SAndroid Build Coastguard Worker       txfi = TYPE_CONVERSION_NONE;
3131*bbecb9d1SAndroid Build Coastguard Worker       break;
3132*bbecb9d1SAndroid Build Coastguard Worker    }
3133*bbecb9d1SAndroid Build Coastguard Worker 
3134*bbecb9d1SAndroid Build Coastguard Worker    switch (inst->Instruction.Opcode) {
3135*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TEX2:
3136*bbecb9d1SAndroid Build Coastguard Worker       sampler_index = 2;
3137*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
3138*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(&bias_buf, ", %s.x", srcs[1]);
3139*bbecb9d1SAndroid Build Coastguard Worker       break;
3140*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXB2:
3141*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXL2:
3142*bbecb9d1SAndroid Build Coastguard Worker       sampler_index = 2;
3143*bbecb9d1SAndroid Build Coastguard Worker       strbuf_appendf(&bias_buf, ", %s.x", srcs[1]);
3144*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
3145*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(&bias_buf, ", %s.y", srcs[1]);
3146*bbecb9d1SAndroid Build Coastguard Worker       break;
3147*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXB:
3148*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXL:
3149*bbecb9d1SAndroid Build Coastguard Worker       /* On GLES we emulate the 1D array by using a 2D array, for this
3150*bbecb9d1SAndroid Build Coastguard Worker        * there is no shadow lookup with bias unless EXT_texture_shadow_lod is used.
3151*bbecb9d1SAndroid Build Coastguard Worker        * To avoid that compiling an invalid shader results in a crash we ignore
3152*bbecb9d1SAndroid Build Coastguard Worker        * the bias value */
3153*bbecb9d1SAndroid Build Coastguard Worker       if (!(ctx->cfg->use_gles && !ctx->cfg->has_texture_shadow_lod &&
3154*bbecb9d1SAndroid Build Coastguard Worker             TGSI_TEXTURE_SHADOW1D_ARRAY == inst->Texture.Texture))
3155*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(&bias_buf, ", %s.w", srcs[0]);
3156*bbecb9d1SAndroid Build Coastguard Worker       break;
3157*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXF:
3158*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Texture.Texture == TGSI_TEXTURE_1D ||
3159*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture == TGSI_TEXTURE_2D ||
3160*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture == TGSI_TEXTURE_2D_MSAA ||
3161*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY_MSAA ||
3162*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture == TGSI_TEXTURE_3D ||
3163*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY ||
3164*bbecb9d1SAndroid Build Coastguard Worker           inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY)
3165*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(&bias_buf, ", int(%s.w)", srcs[0]);
3166*bbecb9d1SAndroid Build Coastguard Worker       break;
3167*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXD:
3168*bbecb9d1SAndroid Build Coastguard Worker       sampler_index = 3;
3169*bbecb9d1SAndroid Build Coastguard Worker       switch (inst->Texture.Texture) {
3170*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_1D:
3171*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW1D:
3172*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_1D_ARRAY:
3173*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW1D_ARRAY:
3174*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->cfg->use_gles)
3175*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(&bias_buf, ", vec2(%s.x, 0), vec2(%s.x, 0)", srcs[1], srcs[2]);
3176*bbecb9d1SAndroid Build Coastguard Worker          else
3177*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(&bias_buf, ", %s.x, %s.x", srcs[1], srcs[2]);
3178*bbecb9d1SAndroid Build Coastguard Worker          break;
3179*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_2D:
3180*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW2D:
3181*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_2D_ARRAY:
3182*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOW2D_ARRAY:
3183*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_RECT:
3184*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOWRECT:
3185*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(&bias_buf, ", %s.xy, %s.xy", srcs[1], srcs[2]);
3186*bbecb9d1SAndroid Build Coastguard Worker          break;
3187*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_3D:
3188*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_CUBE:
3189*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOWCUBE:
3190*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_CUBE_ARRAY:
3191*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(&bias_buf, ", %s.xyz, %s.xyz", srcs[1], srcs[2]);
3192*bbecb9d1SAndroid Build Coastguard Worker          break;
3193*bbecb9d1SAndroid Build Coastguard Worker       default:
3194*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(&bias_buf, ", %s, %s", srcs[1], srcs[2]);
3195*bbecb9d1SAndroid Build Coastguard Worker          break;
3196*bbecb9d1SAndroid Build Coastguard Worker       }
3197*bbecb9d1SAndroid Build Coastguard Worker       break;
3198*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TG4:
3199*bbecb9d1SAndroid Build Coastguard Worker       sampler_index = 2;
3200*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_TG4;
3201*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles) {
3202*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Texture.NumOffsets > 1 || is_shad || (ctx->shader_req_bits & SHADER_REQ_SAMPLER_RECT))
3203*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3204*bbecb9d1SAndroid Build Coastguard Worker       }
3205*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Texture.NumOffsets == 1) {
3206*bbecb9d1SAndroid Build Coastguard Worker          if (inst->TexOffsets[0].File != TGSI_FILE_IMMEDIATE)
3207*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3208*bbecb9d1SAndroid Build Coastguard Worker       }
3209*bbecb9d1SAndroid Build Coastguard Worker       if (is_shad) {
3210*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
3211*bbecb9d1SAndroid Build Coastguard Worker              inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY)
3212*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(&bias_buf, ", %s.w", srcs[0]);
3213*bbecb9d1SAndroid Build Coastguard Worker          else if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
3214*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(&bias_buf, ", %s.x", srcs[1]);
3215*bbecb9d1SAndroid Build Coastguard Worker          else
3216*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(&bias_buf, ", %s.z", srcs[0]);
3217*bbecb9d1SAndroid Build Coastguard Worker       } else if (sinfo->tg4_has_component) {
3218*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Texture.NumOffsets == 0) {
3219*bbecb9d1SAndroid Build Coastguard Worker             if (inst->Texture.Texture == TGSI_TEXTURE_2D ||
3220*bbecb9d1SAndroid Build Coastguard Worker                 inst->Texture.Texture == TGSI_TEXTURE_RECT ||
3221*bbecb9d1SAndroid Build Coastguard Worker                 inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
3222*bbecb9d1SAndroid Build Coastguard Worker                 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY ||
3223*bbecb9d1SAndroid Build Coastguard Worker                 inst->Texture.Texture == TGSI_TEXTURE_CUBE_ARRAY)
3224*bbecb9d1SAndroid Build Coastguard Worker                strbuf_appendf(&bias_buf, ", int(%s)", srcs[1]);
3225*bbecb9d1SAndroid Build Coastguard Worker          } else if (inst->Texture.NumOffsets) {
3226*bbecb9d1SAndroid Build Coastguard Worker             if (inst->Texture.Texture == TGSI_TEXTURE_2D ||
3227*bbecb9d1SAndroid Build Coastguard Worker                 inst->Texture.Texture == TGSI_TEXTURE_RECT ||
3228*bbecb9d1SAndroid Build Coastguard Worker                 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY)
3229*bbecb9d1SAndroid Build Coastguard Worker                strbuf_appendf(&bias_buf, ", int(%s)", srcs[1]);
3230*bbecb9d1SAndroid Build Coastguard Worker          }
3231*bbecb9d1SAndroid Build Coastguard Worker       }
3232*bbecb9d1SAndroid Build Coastguard Worker       break;
3233*bbecb9d1SAndroid Build Coastguard Worker    default:
3234*bbecb9d1SAndroid Build Coastguard Worker       ;
3235*bbecb9d1SAndroid Build Coastguard Worker    }
3236*bbecb9d1SAndroid Build Coastguard Worker 
3237*bbecb9d1SAndroid Build Coastguard Worker    tex_ext = get_tex_inst_ext(inst);
3238*bbecb9d1SAndroid Build Coastguard Worker 
3239*bbecb9d1SAndroid Build Coastguard Worker    const char *bias = bias_buf.buf;
3240*bbecb9d1SAndroid Build Coastguard Worker    const char *offset = offset_buf.buf;
3241*bbecb9d1SAndroid Build Coastguard Worker 
3242*bbecb9d1SAndroid Build Coastguard Worker    // EXT_texture_shadow_lod defines a few more functions handling bias
3243*bbecb9d1SAndroid Build Coastguard Worker    if (bias &&
3244*bbecb9d1SAndroid Build Coastguard Worker        (inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY ||
3245*bbecb9d1SAndroid Build Coastguard Worker         inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
3246*bbecb9d1SAndroid Build Coastguard Worker         inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY))
3247*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_TEXTURE_SHADOW_LOD;
3248*bbecb9d1SAndroid Build Coastguard Worker 
3249*bbecb9d1SAndroid Build Coastguard Worker    // EXT_texture_shadow_lod also adds the missing textureOffset for 2DArrayShadow in GLES
3250*bbecb9d1SAndroid Build Coastguard Worker    if ((bias || offset) && ctx->cfg->use_gles &&
3251*bbecb9d1SAndroid Build Coastguard Worker        (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY ||
3252*bbecb9d1SAndroid Build Coastguard Worker         inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY))
3253*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_TEXTURE_SHADOW_LOD;
3254*bbecb9d1SAndroid Build Coastguard Worker 
3255*bbecb9d1SAndroid Build Coastguard Worker    if (inst->Texture.NumOffsets == 1) {
3256*bbecb9d1SAndroid Build Coastguard Worker       if (inst->TexOffsets[0].Index >= (int)ARRAY_SIZE(ctx->imm)) {
3257*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "Immediate exceeded, max is %lu\n", ARRAY_SIZE(ctx->imm));
3258*bbecb9d1SAndroid Build Coastguard Worker          set_buf_error(&ctx->glsl_strbufs);
3259*bbecb9d1SAndroid Build Coastguard Worker          goto cleanup;
3260*bbecb9d1SAndroid Build Coastguard Worker       }
3261*bbecb9d1SAndroid Build Coastguard Worker 
3262*bbecb9d1SAndroid Build Coastguard Worker       if (!fill_offset_buffer(ctx, inst, &offset_buf, &ctx->require_dummy_value)) {
3263*bbecb9d1SAndroid Build Coastguard Worker          set_buf_error(&ctx->glsl_strbufs);
3264*bbecb9d1SAndroid Build Coastguard Worker          goto cleanup;
3265*bbecb9d1SAndroid Build Coastguard Worker       }
3266*bbecb9d1SAndroid Build Coastguard Worker 
3267*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Instruction.Opcode == TGSI_OPCODE_TXL || inst->Instruction.Opcode == TGSI_OPCODE_TXL2 || inst->Instruction.Opcode == TGSI_OPCODE_TXD || (inst->Instruction.Opcode == TGSI_OPCODE_TG4 && is_shad)) {
3268*bbecb9d1SAndroid Build Coastguard Worker          offset = bias_buf.buf;
3269*bbecb9d1SAndroid Build Coastguard Worker          bias = offset_buf.buf;
3270*bbecb9d1SAndroid Build Coastguard Worker       }
3271*bbecb9d1SAndroid Build Coastguard Worker    }
3272*bbecb9d1SAndroid Build Coastguard Worker 
3273*bbecb9d1SAndroid Build Coastguard Worker    char buf[255];
3274*bbecb9d1SAndroid Build Coastguard Worker    const char *new_srcs[4] = { buf, srcs[1], srcs[2], srcs[3] };
3275*bbecb9d1SAndroid Build Coastguard Worker 
3276*bbecb9d1SAndroid Build Coastguard Worker    /* We have to unnormalize the coordinate for all but the texel fetch instruction */
3277*bbecb9d1SAndroid Build Coastguard Worker    if (inst->Instruction.Opcode != TGSI_OPCODE_TXF &&
3278*bbecb9d1SAndroid Build Coastguard Worker        vrend_shader_sampler_views_mask_get(ctx->key->sampler_views_emulated_rect_mask, sinfo->sreg_index)) {
3279*bbecb9d1SAndroid Build Coastguard Worker 
3280*bbecb9d1SAndroid Build Coastguard Worker       const char *bias = "";
3281*bbecb9d1SAndroid Build Coastguard Worker 
3282*bbecb9d1SAndroid Build Coastguard Worker       /* No LOD for these texture types, but on GLES we emulate RECT by using
3283*bbecb9d1SAndroid Build Coastguard Worker        * a normal 2D texture, so we have to give LOD 0 */
3284*bbecb9d1SAndroid Build Coastguard Worker       switch (inst->Texture.Texture) {
3285*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_BUFFER:
3286*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_2D_MSAA:
3287*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_2D_ARRAY_MSAA:
3288*bbecb9d1SAndroid Build Coastguard Worker          break;
3289*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_RECT:
3290*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TEXTURE_SHADOWRECT:
3291*bbecb9d1SAndroid Build Coastguard Worker          if (!ctx->cfg->use_gles)
3292*bbecb9d1SAndroid Build Coastguard Worker             break;
3293*bbecb9d1SAndroid Build Coastguard Worker          /* fallthrough */
3294*bbecb9d1SAndroid Build Coastguard Worker       default:
3295*bbecb9d1SAndroid Build Coastguard Worker          bias = ", 0";
3296*bbecb9d1SAndroid Build Coastguard Worker       }
3297*bbecb9d1SAndroid Build Coastguard Worker 
3298*bbecb9d1SAndroid Build Coastguard Worker       switch (inst->Instruction.Opcode) {
3299*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_OPCODE_TXP:
3300*bbecb9d1SAndroid Build Coastguard Worker          snprintf(buf, 255, "vec4(%s)/vec4(textureSize(%s%s), 1, 1)", srcs[0], srcs[sampler_index], bias);
3301*bbecb9d1SAndroid Build Coastguard Worker          break;
3302*bbecb9d1SAndroid Build Coastguard Worker 
3303*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_OPCODE_TG4:
3304*bbecb9d1SAndroid Build Coastguard Worker          snprintf(buf, 255, "%s.xy/vec2(textureSize(%s%s))", srcs[0], srcs[sampler_index], bias);
3305*bbecb9d1SAndroid Build Coastguard Worker          break;
3306*bbecb9d1SAndroid Build Coastguard Worker 
3307*bbecb9d1SAndroid Build Coastguard Worker       default:
3308*bbecb9d1SAndroid Build Coastguard Worker          /* Non TG4 ops have the compare value in the z components */
3309*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWRECT) {
3310*bbecb9d1SAndroid Build Coastguard Worker             snprintf(buf, 255, "vec3(%s.xy/vec2(textureSize(%s%s)), %s.z)", srcs[0], srcs[sampler_index], bias, srcs[0]);
3311*bbecb9d1SAndroid Build Coastguard Worker          } else
3312*bbecb9d1SAndroid Build Coastguard Worker             snprintf(buf, 255, "%s.xy/vec2(textureSize(%s%s))", srcs[0], srcs[sampler_index], bias);
3313*bbecb9d1SAndroid Build Coastguard Worker       }
3314*bbecb9d1SAndroid Build Coastguard Worker       srcs = new_srcs;
3315*bbecb9d1SAndroid Build Coastguard Worker    }
3316*bbecb9d1SAndroid Build Coastguard Worker 
3317*bbecb9d1SAndroid Build Coastguard Worker    if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) {
3318*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->use_gles &&
3319*bbecb9d1SAndroid Build Coastguard Worker           (inst->Texture.Texture == TGSI_TEXTURE_1D ||
3320*bbecb9d1SAndroid Build Coastguard Worker            inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY ||
3321*bbecb9d1SAndroid Build Coastguard Worker            inst->Texture.Texture == TGSI_TEXTURE_RECT)) {
3322*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Texture.Texture == TGSI_TEXTURE_1D)
3323*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texelFetch%s(%s, ivec2(%s(%s%s), 0)%s%s)%s));\n",
3324*bbecb9d1SAndroid Build Coastguard Worker                       dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3325*bbecb9d1SAndroid Build Coastguard Worker                       tex_ext, srcs[sampler_index], get_string(txfi),
3326*bbecb9d1SAndroid Build Coastguard Worker                       srcs[0], src_swizzle, bias, offset,
3327*bbecb9d1SAndroid Build Coastguard Worker                       dinfo->dst_override_no_wm[0] ? "" : writemask);
3328*bbecb9d1SAndroid Build Coastguard Worker          else if (inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY) {
3329*bbecb9d1SAndroid Build Coastguard Worker             /* the y coordinate must go into the z element and the y must be zero */
3330*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texelFetch%s(%s, ivec3(%s(%s%s), 0).xzy%s%s)%s));\n",
3331*bbecb9d1SAndroid Build Coastguard Worker                       dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3332*bbecb9d1SAndroid Build Coastguard Worker                       tex_ext, srcs[sampler_index], get_string(txfi),
3333*bbecb9d1SAndroid Build Coastguard Worker                       srcs[0], src_swizzle, bias, offset,
3334*bbecb9d1SAndroid Build Coastguard Worker                       dinfo->dst_override_no_wm[0] ? "" : writemask);
3335*bbecb9d1SAndroid Build Coastguard Worker          } else {
3336*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texelFetch%s(%s, %s(%s%s), 0%s)%s));\n",
3337*bbecb9d1SAndroid Build Coastguard Worker                       dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3338*bbecb9d1SAndroid Build Coastguard Worker                       tex_ext, srcs[sampler_index], get_string(txfi),
3339*bbecb9d1SAndroid Build Coastguard Worker                       srcs[0], src_swizzle, offset,
3340*bbecb9d1SAndroid Build Coastguard Worker                       dinfo->dst_override_no_wm[0] ? "" : writemask);
3341*bbecb9d1SAndroid Build Coastguard Worker          }
3342*bbecb9d1SAndroid Build Coastguard Worker       } else {
3343*bbecb9d1SAndroid Build Coastguard Worker 
3344*bbecb9d1SAndroid Build Coastguard Worker          /* To inject the swizzle for texturebufffers with emulated formats do
3345*bbecb9d1SAndroid Build Coastguard Worker           *
3346*bbecb9d1SAndroid Build Coastguard Worker           * {
3347*bbecb9d1SAndroid Build Coastguard Worker           *    vec4 val = texelFetch( )
3348*bbecb9d1SAndroid Build Coastguard Worker           *    val = vec4(0/1/swizzle_x, ...);
3349*bbecb9d1SAndroid Build Coastguard Worker           *    dest.writemask = val.writemask;
3350*bbecb9d1SAndroid Build Coastguard Worker           * }
3351*bbecb9d1SAndroid Build Coastguard Worker           *
3352*bbecb9d1SAndroid Build Coastguard Worker           */
3353*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "{\n  vec4 val = %s(texelFetch%s(%s, %s(%s%s)%s%s));\n",
3354*bbecb9d1SAndroid Build Coastguard Worker                    get_string(dtypeprefix),
3355*bbecb9d1SAndroid Build Coastguard Worker                    tex_ext, srcs[sampler_index], get_string(txfi),
3356*bbecb9d1SAndroid Build Coastguard Worker                    srcs[0], src_swizzle, bias, offset);
3357*bbecb9d1SAndroid Build Coastguard Worker 
3358*bbecb9d1SAndroid Build Coastguard Worker          if (vrend_shader_sampler_views_mask_get(ctx->key->sampler_views_lower_swizzle_mask, sinfo->sreg_index)) {
3359*bbecb9d1SAndroid Build Coastguard Worker             int16_t  packed_swizzles = ctx->key->tex_swizzle[sinfo->sreg_index];
3360*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(&ctx->glsl_strbufs,  "   val = vec4(");
3361*bbecb9d1SAndroid Build Coastguard Worker 
3362*bbecb9d1SAndroid Build Coastguard Worker             for (int i = 0; i < 4; ++i) {
3363*bbecb9d1SAndroid Build Coastguard Worker                if (i > 0)
3364*bbecb9d1SAndroid Build Coastguard Worker                   emit_buff(&ctx->glsl_strbufs,  ", ");
3365*bbecb9d1SAndroid Build Coastguard Worker 
3366*bbecb9d1SAndroid Build Coastguard Worker                int swz = (packed_swizzles >> (i * 3)) & 7;
3367*bbecb9d1SAndroid Build Coastguard Worker                switch (swz) {
3368*bbecb9d1SAndroid Build Coastguard Worker                case PIPE_SWIZZLE_ZERO : emit_buf(&ctx->glsl_strbufs,  "0.0"); break;
3369*bbecb9d1SAndroid Build Coastguard Worker                case PIPE_SWIZZLE_ONE :
3370*bbecb9d1SAndroid Build Coastguard Worker                   switch (dtypeprefix) {
3371*bbecb9d1SAndroid Build Coastguard Worker                   case UINT_BITS_TO_FLOAT:
3372*bbecb9d1SAndroid Build Coastguard Worker                      emit_buf(&ctx->glsl_strbufs,  "uintBitsToFloat(1u)");
3373*bbecb9d1SAndroid Build Coastguard Worker                      break;
3374*bbecb9d1SAndroid Build Coastguard Worker                   case INT_BITS_TO_FLOAT:
3375*bbecb9d1SAndroid Build Coastguard Worker                      emit_buf(&ctx->glsl_strbufs,  "intBitsToFloat(1)");
3376*bbecb9d1SAndroid Build Coastguard Worker                      break;
3377*bbecb9d1SAndroid Build Coastguard Worker                   default:
3378*bbecb9d1SAndroid Build Coastguard Worker                      emit_buf(&ctx->glsl_strbufs,  "1.0");
3379*bbecb9d1SAndroid Build Coastguard Worker                      break;
3380*bbecb9d1SAndroid Build Coastguard Worker                   }
3381*bbecb9d1SAndroid Build Coastguard Worker                   break;
3382*bbecb9d1SAndroid Build Coastguard Worker                default:
3383*bbecb9d1SAndroid Build Coastguard Worker                   emit_buff(&ctx->glsl_strbufs,  "val%s", get_swizzle_string(swz));
3384*bbecb9d1SAndroid Build Coastguard Worker                }
3385*bbecb9d1SAndroid Build Coastguard Worker             }
3386*bbecb9d1SAndroid Build Coastguard Worker 
3387*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(&ctx->glsl_strbufs,  ");\n");
3388*bbecb9d1SAndroid Build Coastguard Worker          }
3389*bbecb9d1SAndroid Build Coastguard Worker 
3390*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "  %s  = val%s;\n}\n",
3391*bbecb9d1SAndroid Build Coastguard Worker                    dst, dinfo->dst_override_no_wm[0] ? "" : writemask);
3392*bbecb9d1SAndroid Build Coastguard Worker       }
3393*bbecb9d1SAndroid Build Coastguard Worker    } else if ((ctx->cfg->glsl_version < 140 && (ctx->shader_req_bits & SHADER_REQ_SAMPLER_RECT)) &&
3394*bbecb9d1SAndroid Build Coastguard Worker               !vrend_shader_sampler_views_mask_get(ctx->key->sampler_views_emulated_rect_mask, sinfo->sreg_index)) {
3395*bbecb9d1SAndroid Build Coastguard Worker       /* rect is special in GLSL 1.30 */
3396*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Texture.Texture == TGSI_TEXTURE_RECT)
3397*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = texture2DRect(%s, %s.xy)%s;\n",
3398*bbecb9d1SAndroid Build Coastguard Worker                    dst, srcs[sampler_index], srcs[0], writemask);
3399*bbecb9d1SAndroid Build Coastguard Worker       else if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWRECT)
3400*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = shadow2DRect(%s, %s.xyz)%s;\n",
3401*bbecb9d1SAndroid Build Coastguard Worker                    dst, srcs[sampler_index], srcs[0], writemask);
3402*bbecb9d1SAndroid Build Coastguard Worker    } else if (is_shad && inst->Instruction.Opcode != TGSI_OPCODE_TG4) { /* TGSI returns 1.0 in alpha */
3403*bbecb9d1SAndroid Build Coastguard Worker       const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3404*bbecb9d1SAndroid Build Coastguard Worker       const struct tgsi_full_src_register *src = &inst->Src[sampler_index];
3405*bbecb9d1SAndroid Build Coastguard Worker 
3406*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->use_gles &&
3407*bbecb9d1SAndroid Build Coastguard Worker           (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D ||
3408*bbecb9d1SAndroid Build Coastguard Worker            inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY)) {
3409*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D) {
3410*bbecb9d1SAndroid Build Coastguard Worker             if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3411*bbecb9d1SAndroid Build Coastguard Worker                emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(vec4(texture%s(%s, vec4(%s%s.xzw, 0).xwyz %s%s)) * %sshadmask%d + %sshadadd%d)%s));\n",
3412*bbecb9d1SAndroid Build Coastguard Worker                          dst, get_string(dinfo->dstconv),
3413*bbecb9d1SAndroid Build Coastguard Worker                          get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3414*bbecb9d1SAndroid Build Coastguard Worker                          srcs[0], src_swizzle, offset, bias,
3415*bbecb9d1SAndroid Build Coastguard Worker                          cname, src->Register.Index,
3416*bbecb9d1SAndroid Build Coastguard Worker                          cname, src->Register.Index, writemask);
3417*bbecb9d1SAndroid Build Coastguard Worker             else
3418*bbecb9d1SAndroid Build Coastguard Worker                emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(vec4(texture%s(%s, vec3(%s%s.xz, 0).xzy %s%s)) * %sshadmask%d + %sshadadd%d)%s));\n",
3419*bbecb9d1SAndroid Build Coastguard Worker                          dst, get_string(dinfo->dstconv),
3420*bbecb9d1SAndroid Build Coastguard Worker                          get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3421*bbecb9d1SAndroid Build Coastguard Worker                          srcs[0], src_swizzle, offset, bias,
3422*bbecb9d1SAndroid Build Coastguard Worker                          cname, src->Register.Index,
3423*bbecb9d1SAndroid Build Coastguard Worker                          cname, src->Register.Index, writemask);
3424*bbecb9d1SAndroid Build Coastguard Worker          } else if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY) {
3425*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(vec4(texture%s(%s, vec4(%s%s, 0).xwyz %s%s)) * %sshadmask%d + %sshadadd%d)%s));\n",
3426*bbecb9d1SAndroid Build Coastguard Worker                       dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3427*bbecb9d1SAndroid Build Coastguard Worker                       tex_ext, srcs[sampler_index], srcs[0],
3428*bbecb9d1SAndroid Build Coastguard Worker                       src_swizzle, offset, bias, cname,
3429*bbecb9d1SAndroid Build Coastguard Worker                       src->Register.Index, cname,
3430*bbecb9d1SAndroid Build Coastguard Worker                       src->Register.Index, writemask);
3431*bbecb9d1SAndroid Build Coastguard Worker          }
3432*bbecb9d1SAndroid Build Coastguard Worker       } else
3433*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(vec4(texture%s(%s, %s%s%s%s)) * %sshadmask%d + %sshadadd%d)%s));\n",
3434*bbecb9d1SAndroid Build Coastguard Worker                    dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3435*bbecb9d1SAndroid Build Coastguard Worker                    tex_ext, srcs[sampler_index], srcs[0],
3436*bbecb9d1SAndroid Build Coastguard Worker                    src_swizzle, offset, bias,
3437*bbecb9d1SAndroid Build Coastguard Worker                    cname, src->Register.Index,
3438*bbecb9d1SAndroid Build Coastguard Worker                    cname, src->Register.Index, writemask);
3439*bbecb9d1SAndroid Build Coastguard Worker    } else {
3440*bbecb9d1SAndroid Build Coastguard Worker       /* OpenGL ES do not support 1D texture
3441*bbecb9d1SAndroid Build Coastguard Worker        * so we use a 2D texture with a parameter set to 0.5
3442*bbecb9d1SAndroid Build Coastguard Worker        */
3443*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->use_gles &&
3444*bbecb9d1SAndroid Build Coastguard Worker           (inst->Texture.Texture == TGSI_TEXTURE_1D ||
3445*bbecb9d1SAndroid Build Coastguard Worker            inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY)) {
3446*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Texture.Texture == TGSI_TEXTURE_1D) {
3447*bbecb9d1SAndroid Build Coastguard Worker             if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3448*bbecb9d1SAndroid Build Coastguard Worker                emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texture%s(%s, vec3(%s.xw, 0).xzy %s%s)%s));\n",
3449*bbecb9d1SAndroid Build Coastguard Worker                          dst, get_string(dinfo->dstconv),
3450*bbecb9d1SAndroid Build Coastguard Worker                          get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3451*bbecb9d1SAndroid Build Coastguard Worker                          srcs[0], offset, bias,
3452*bbecb9d1SAndroid Build Coastguard Worker                          dinfo->dst_override_no_wm[0] ? "" : writemask);
3453*bbecb9d1SAndroid Build Coastguard Worker             else
3454*bbecb9d1SAndroid Build Coastguard Worker                emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texture%s(%s, vec2(%s%s, 0.5) %s%s)%s));\n",
3455*bbecb9d1SAndroid Build Coastguard Worker                          dst, get_string(dinfo->dstconv),
3456*bbecb9d1SAndroid Build Coastguard Worker                          get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3457*bbecb9d1SAndroid Build Coastguard Worker                          srcs[0], src_swizzle, offset, bias,
3458*bbecb9d1SAndroid Build Coastguard Worker                          dinfo->dst_override_no_wm[0] ? "" : writemask);
3459*bbecb9d1SAndroid Build Coastguard Worker          } else if (inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY) {
3460*bbecb9d1SAndroid Build Coastguard Worker             if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
3461*bbecb9d1SAndroid Build Coastguard Worker                emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texture%s(%s, vec3(%s.x / %s.w, 0, %s.y) %s%s)%s));\n",
3462*bbecb9d1SAndroid Build Coastguard Worker                          dst, get_string(dinfo->dstconv),
3463*bbecb9d1SAndroid Build Coastguard Worker                          get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3464*bbecb9d1SAndroid Build Coastguard Worker                          srcs[0], srcs[0], srcs[0], offset, bias,
3465*bbecb9d1SAndroid Build Coastguard Worker                          dinfo->dst_override_no_wm[0] ? "" : writemask);
3466*bbecb9d1SAndroid Build Coastguard Worker             else
3467*bbecb9d1SAndroid Build Coastguard Worker                emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texture%s(%s, vec3(%s%s, 0).xzy %s%s)%s));\n",
3468*bbecb9d1SAndroid Build Coastguard Worker                          dst, get_string(dinfo->dstconv),
3469*bbecb9d1SAndroid Build Coastguard Worker                          get_string(dtypeprefix), tex_ext, srcs[sampler_index],
3470*bbecb9d1SAndroid Build Coastguard Worker                          srcs[0], src_swizzle, offset, bias,
3471*bbecb9d1SAndroid Build Coastguard Worker                          dinfo->dst_override_no_wm[0] ? "" : writemask);
3472*bbecb9d1SAndroid Build Coastguard Worker          }
3473*bbecb9d1SAndroid Build Coastguard Worker       } else {
3474*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texture%s(%s, %s%s%s%s)%s));\n",
3475*bbecb9d1SAndroid Build Coastguard Worker                    dst, get_string(dinfo->dstconv), get_string(dtypeprefix),
3476*bbecb9d1SAndroid Build Coastguard Worker                    tex_ext, srcs[sampler_index], srcs[0], src_swizzle,
3477*bbecb9d1SAndroid Build Coastguard Worker                    offset, bias, dinfo->dst_override_no_wm[0] ? "" : writemask);
3478*bbecb9d1SAndroid Build Coastguard Worker       }
3479*bbecb9d1SAndroid Build Coastguard Worker    }
3480*bbecb9d1SAndroid Build Coastguard Worker 
3481*bbecb9d1SAndroid Build Coastguard Worker cleanup:
3482*bbecb9d1SAndroid Build Coastguard Worker    strbuf_free(&offset_buf);
3483*bbecb9d1SAndroid Build Coastguard Worker    strbuf_free(&bias_buf);
3484*bbecb9d1SAndroid Build Coastguard Worker }
3485*bbecb9d1SAndroid Build Coastguard Worker 
3486*bbecb9d1SAndroid Build Coastguard Worker static void
create_swizzled_clipdist(const struct dump_ctx * ctx,struct vrend_strbuf * result,const struct tgsi_full_src_register * src,int input_idx,bool gl_in,const char * stypeprefix,const char * prefix,const char * arrayname,int offset)3487*bbecb9d1SAndroid Build Coastguard Worker create_swizzled_clipdist(const struct dump_ctx *ctx,
3488*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_strbuf *result,
3489*bbecb9d1SAndroid Build Coastguard Worker                          const struct tgsi_full_src_register *src,
3490*bbecb9d1SAndroid Build Coastguard Worker                          int input_idx,
3491*bbecb9d1SAndroid Build Coastguard Worker                          bool gl_in,
3492*bbecb9d1SAndroid Build Coastguard Worker                          const char *stypeprefix,
3493*bbecb9d1SAndroid Build Coastguard Worker                          const char *prefix,
3494*bbecb9d1SAndroid Build Coastguard Worker                          const char *arrayname, int offset)
3495*bbecb9d1SAndroid Build Coastguard Worker {
3496*bbecb9d1SAndroid Build Coastguard Worker    char clipdistvec[4][80] = { 0, };
3497*bbecb9d1SAndroid Build Coastguard Worker 
3498*bbecb9d1SAndroid Build Coastguard Worker    char clip_indirect[32] = "";
3499*bbecb9d1SAndroid Build Coastguard Worker 
3500*bbecb9d1SAndroid Build Coastguard Worker    bool has_prop = (ctx->num_cull_dist_prop + ctx->num_clip_dist_prop) > 0;
3501*bbecb9d1SAndroid Build Coastguard Worker    int num_culls = has_prop ? ctx->num_cull_dist_prop : ctx->key->num_out_cull;
3502*bbecb9d1SAndroid Build Coastguard Worker    int num_clips = has_prop ? ctx->num_clip_dist_prop : ctx->key->num_out_clip;
3503*bbecb9d1SAndroid Build Coastguard Worker 
3504*bbecb9d1SAndroid Build Coastguard Worker    int num_clip_cull = num_culls + num_clips;
3505*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->num_in_clip_dist && !num_clip_cull)
3506*bbecb9d1SAndroid Build Coastguard Worker       num_clips = ctx->num_in_clip_dist;
3507*bbecb9d1SAndroid Build Coastguard Worker 
3508*bbecb9d1SAndroid Build Coastguard Worker    int base_idx = ctx->inputs[input_idx].sid * 4;
3509*bbecb9d1SAndroid Build Coastguard Worker 
3510*bbecb9d1SAndroid Build Coastguard Worker    // This doesn't work for indirect adressing
3511*bbecb9d1SAndroid Build Coastguard Worker    int base_offset = (src->Register.Index - offset) * 4;
3512*bbecb9d1SAndroid Build Coastguard Worker 
3513*bbecb9d1SAndroid Build Coastguard Worker    /* With arrays enabled , but only when gl_ClipDistance or gl_CullDistance are emitted (>4)
3514*bbecb9d1SAndroid Build Coastguard Worker     * then we need to add indirect addressing */
3515*bbecb9d1SAndroid Build Coastguard Worker    if (src->Register.Indirect && ((num_clips > 4 && base_idx < num_clips) || num_culls > 4))
3516*bbecb9d1SAndroid Build Coastguard Worker       snprintf(clip_indirect, 32, "4*addr%d +", src->Indirect.Index);
3517*bbecb9d1SAndroid Build Coastguard Worker    else if (src->Register.Index != offset)
3518*bbecb9d1SAndroid Build Coastguard Worker       snprintf(clip_indirect, 32, "4*%d +", src->Register.Index - offset);
3519*bbecb9d1SAndroid Build Coastguard Worker 
3520*bbecb9d1SAndroid Build Coastguard Worker    for (unsigned cc = 0; cc < 4; cc++) {
3521*bbecb9d1SAndroid Build Coastguard Worker       const char *cc_name = ctx->inputs[input_idx].glsl_name;
3522*bbecb9d1SAndroid Build Coastguard Worker       int idx = base_idx;
3523*bbecb9d1SAndroid Build Coastguard Worker       if (cc == 0)
3524*bbecb9d1SAndroid Build Coastguard Worker          idx += src->Register.SwizzleX;
3525*bbecb9d1SAndroid Build Coastguard Worker       else if (cc == 1)
3526*bbecb9d1SAndroid Build Coastguard Worker          idx += src->Register.SwizzleY;
3527*bbecb9d1SAndroid Build Coastguard Worker       else if (cc == 2)
3528*bbecb9d1SAndroid Build Coastguard Worker          idx += src->Register.SwizzleZ;
3529*bbecb9d1SAndroid Build Coastguard Worker       else if (cc == 3)
3530*bbecb9d1SAndroid Build Coastguard Worker          idx += src->Register.SwizzleW;
3531*bbecb9d1SAndroid Build Coastguard Worker 
3532*bbecb9d1SAndroid Build Coastguard Worker       if (num_culls) {
3533*bbecb9d1SAndroid Build Coastguard Worker          if (idx + base_offset >= num_clips) {
3534*bbecb9d1SAndroid Build Coastguard Worker             idx -= num_clips;
3535*bbecb9d1SAndroid Build Coastguard Worker             cc_name = "gl_CullDistance";
3536*bbecb9d1SAndroid Build Coastguard Worker          }
3537*bbecb9d1SAndroid Build Coastguard Worker       }
3538*bbecb9d1SAndroid Build Coastguard Worker 
3539*bbecb9d1SAndroid Build Coastguard Worker       if (gl_in)
3540*bbecb9d1SAndroid Build Coastguard Worker          snprintf(clipdistvec[cc], 80, "%sgl_in%s.%s[%s %d]", prefix, arrayname, cc_name, clip_indirect,  idx);
3541*bbecb9d1SAndroid Build Coastguard Worker       else
3542*bbecb9d1SAndroid Build Coastguard Worker          snprintf(clipdistvec[cc], 80, "%s%s%s[%s %d]", prefix, arrayname, cc_name, clip_indirect, idx);
3543*bbecb9d1SAndroid Build Coastguard Worker    }
3544*bbecb9d1SAndroid Build Coastguard Worker    strbuf_fmt(result, "%s(vec4(%s,%s,%s,%s))", stypeprefix, clipdistvec[0], clipdistvec[1], clipdistvec[2], clipdistvec[3]);
3545*bbecb9d1SAndroid Build Coastguard Worker }
3546*bbecb9d1SAndroid Build Coastguard Worker 
3547*bbecb9d1SAndroid Build Coastguard Worker static
load_clipdist_fs(const struct dump_ctx * ctx,struct vrend_strbuf * result,const struct tgsi_full_src_register * src,int input_idx,const char * stypeprefix,int offset)3548*bbecb9d1SAndroid Build Coastguard Worker void load_clipdist_fs(const struct dump_ctx *ctx,
3549*bbecb9d1SAndroid Build Coastguard Worker                       struct vrend_strbuf *result,
3550*bbecb9d1SAndroid Build Coastguard Worker                       const struct tgsi_full_src_register *src,
3551*bbecb9d1SAndroid Build Coastguard Worker                       int input_idx,
3552*bbecb9d1SAndroid Build Coastguard Worker                       const char *stypeprefix,
3553*bbecb9d1SAndroid Build Coastguard Worker                       int offset)
3554*bbecb9d1SAndroid Build Coastguard Worker {
3555*bbecb9d1SAndroid Build Coastguard Worker    char clip_indirect[32] = "";
3556*bbecb9d1SAndroid Build Coastguard Worker 
3557*bbecb9d1SAndroid Build Coastguard Worker    char swz[5] = {
3558*bbecb9d1SAndroid Build Coastguard Worker       get_swiz_char(src->Register.SwizzleX),
3559*bbecb9d1SAndroid Build Coastguard Worker       get_swiz_char(src->Register.SwizzleY),
3560*bbecb9d1SAndroid Build Coastguard Worker       get_swiz_char(src->Register.SwizzleZ),
3561*bbecb9d1SAndroid Build Coastguard Worker       get_swiz_char(src->Register.SwizzleW),
3562*bbecb9d1SAndroid Build Coastguard Worker       0
3563*bbecb9d1SAndroid Build Coastguard Worker    };
3564*bbecb9d1SAndroid Build Coastguard Worker 
3565*bbecb9d1SAndroid Build Coastguard Worker    int base_idx = ctx->inputs[input_idx].sid;
3566*bbecb9d1SAndroid Build Coastguard Worker 
3567*bbecb9d1SAndroid Build Coastguard Worker    /* With arrays enabled , but only when gl_ClipDistance or gl_CullDistance are emitted (>4)
3568*bbecb9d1SAndroid Build Coastguard Worker     * then we need to add indirect addressing */
3569*bbecb9d1SAndroid Build Coastguard Worker    if (src->Register.Indirect)
3570*bbecb9d1SAndroid Build Coastguard Worker       snprintf(clip_indirect, 32, "addr%d + %d", src->Indirect.Index, base_idx);
3571*bbecb9d1SAndroid Build Coastguard Worker    else
3572*bbecb9d1SAndroid Build Coastguard Worker       snprintf(clip_indirect, 32, "%d + %d", src->Register.Index - offset, base_idx);
3573*bbecb9d1SAndroid Build Coastguard Worker 
3574*bbecb9d1SAndroid Build Coastguard Worker    strbuf_fmt(result, "%s(clip_dist_temp[%s].%s)", stypeprefix, clip_indirect, swz);
3575*bbecb9d1SAndroid Build Coastguard Worker }
3576*bbecb9d1SAndroid Build Coastguard Worker 
3577*bbecb9d1SAndroid Build Coastguard Worker 
get_coord_prefix(int resource,bool * is_ms,bool use_gles)3578*bbecb9d1SAndroid Build Coastguard Worker static enum vrend_type_qualifier get_coord_prefix(int resource, bool *is_ms, bool use_gles)
3579*bbecb9d1SAndroid Build Coastguard Worker {
3580*bbecb9d1SAndroid Build Coastguard Worker    switch(resource) {
3581*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_1D:
3582*bbecb9d1SAndroid Build Coastguard Worker       return use_gles ? IVEC2: INT;
3583*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_BUFFER:
3584*bbecb9d1SAndroid Build Coastguard Worker       return INT;
3585*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_1D_ARRAY:
3586*bbecb9d1SAndroid Build Coastguard Worker       return use_gles ? IVEC3: IVEC2;
3587*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D:
3588*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_RECT:
3589*bbecb9d1SAndroid Build Coastguard Worker       return IVEC2;
3590*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_3D:
3591*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_CUBE:
3592*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_ARRAY:
3593*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_CUBE_ARRAY:
3594*bbecb9d1SAndroid Build Coastguard Worker       return IVEC3;
3595*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_MSAA:
3596*bbecb9d1SAndroid Build Coastguard Worker       *is_ms = true;
3597*bbecb9d1SAndroid Build Coastguard Worker       return IVEC2;
3598*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_ARRAY_MSAA:
3599*bbecb9d1SAndroid Build Coastguard Worker       *is_ms = true;
3600*bbecb9d1SAndroid Build Coastguard Worker       return IVEC3;
3601*bbecb9d1SAndroid Build Coastguard Worker    default:
3602*bbecb9d1SAndroid Build Coastguard Worker       return TYPE_CONVERSION_NONE;
3603*bbecb9d1SAndroid Build Coastguard Worker    }
3604*bbecb9d1SAndroid Build Coastguard Worker }
3605*bbecb9d1SAndroid Build Coastguard Worker 
is_integer_memory(const struct dump_ctx * ctx,enum tgsi_file_type file_type,uint32_t index)3606*bbecb9d1SAndroid Build Coastguard Worker static bool is_integer_memory(const struct dump_ctx *ctx, enum tgsi_file_type file_type, uint32_t index)
3607*bbecb9d1SAndroid Build Coastguard Worker {
3608*bbecb9d1SAndroid Build Coastguard Worker    switch(file_type) {
3609*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_BUFFER:
3610*bbecb9d1SAndroid Build Coastguard Worker       return !!(ctx->ssbo_integer_mask & (1 << index));
3611*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_FILE_MEMORY:
3612*bbecb9d1SAndroid Build Coastguard Worker       return ctx->integer_memory;
3613*bbecb9d1SAndroid Build Coastguard Worker    default:
3614*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf( "Invalid file type");
3615*bbecb9d1SAndroid Build Coastguard Worker    }
3616*bbecb9d1SAndroid Build Coastguard Worker 
3617*bbecb9d1SAndroid Build Coastguard Worker    return false;
3618*bbecb9d1SAndroid Build Coastguard Worker }
3619*bbecb9d1SAndroid Build Coastguard Worker 
set_image_qualifier(struct vrend_shader_image images[],uint32_t image_used_mask,const struct tgsi_full_instruction * inst,uint32_t reg_index,bool indirect)3620*bbecb9d1SAndroid Build Coastguard Worker static void set_image_qualifier(struct vrend_shader_image images[],
3621*bbecb9d1SAndroid Build Coastguard Worker                                 uint32_t image_used_mask,
3622*bbecb9d1SAndroid Build Coastguard Worker                                 const struct tgsi_full_instruction *inst,
3623*bbecb9d1SAndroid Build Coastguard Worker                                 uint32_t reg_index, bool indirect)
3624*bbecb9d1SAndroid Build Coastguard Worker {
3625*bbecb9d1SAndroid Build Coastguard Worker    if (inst->Memory.Qualifier == TGSI_MEMORY_COHERENT) {
3626*bbecb9d1SAndroid Build Coastguard Worker       if (indirect) {
3627*bbecb9d1SAndroid Build Coastguard Worker          while (image_used_mask)
3628*bbecb9d1SAndroid Build Coastguard Worker             images[u_bit_scan(&image_used_mask)].coherent = true;
3629*bbecb9d1SAndroid Build Coastguard Worker       } else
3630*bbecb9d1SAndroid Build Coastguard Worker          images[reg_index].coherent = true;
3631*bbecb9d1SAndroid Build Coastguard Worker    }
3632*bbecb9d1SAndroid Build Coastguard Worker }
3633*bbecb9d1SAndroid Build Coastguard Worker 
set_memory_qualifier(uint8_t ssbo_memory_qualifier[],uint32_t ssbo_used_mask,const struct tgsi_full_instruction * inst,uint32_t reg_index,bool indirect)3634*bbecb9d1SAndroid Build Coastguard Worker static void set_memory_qualifier(uint8_t ssbo_memory_qualifier[],
3635*bbecb9d1SAndroid Build Coastguard Worker                                  uint32_t ssbo_used_mask,
3636*bbecb9d1SAndroid Build Coastguard Worker                                  const struct tgsi_full_instruction *inst,
3637*bbecb9d1SAndroid Build Coastguard Worker                                  uint32_t reg_index, bool indirect)
3638*bbecb9d1SAndroid Build Coastguard Worker {
3639*bbecb9d1SAndroid Build Coastguard Worker    if (inst->Memory.Qualifier == TGSI_MEMORY_COHERENT) {
3640*bbecb9d1SAndroid Build Coastguard Worker       if (indirect) {
3641*bbecb9d1SAndroid Build Coastguard Worker          while (ssbo_used_mask)
3642*bbecb9d1SAndroid Build Coastguard Worker             ssbo_memory_qualifier[u_bit_scan(&ssbo_used_mask)] = TGSI_MEMORY_COHERENT;
3643*bbecb9d1SAndroid Build Coastguard Worker       } else
3644*bbecb9d1SAndroid Build Coastguard Worker          ssbo_memory_qualifier[reg_index] = TGSI_MEMORY_COHERENT;
3645*bbecb9d1SAndroid Build Coastguard Worker    }
3646*bbecb9d1SAndroid Build Coastguard Worker }
3647*bbecb9d1SAndroid Build Coastguard Worker 
emit_store_mem(struct vrend_glsl_strbufs * glsl_strbufs,const char * dst,int writemask,const char * srcs[4],const char * conversion)3648*bbecb9d1SAndroid Build Coastguard Worker static void emit_store_mem(struct vrend_glsl_strbufs *glsl_strbufs, const char *dst, int writemask,
3649*bbecb9d1SAndroid Build Coastguard Worker                            const char *srcs[4], const char *conversion)
3650*bbecb9d1SAndroid Build Coastguard Worker {
3651*bbecb9d1SAndroid Build Coastguard Worker    static const char swizzle_char[] = "xyzw";
3652*bbecb9d1SAndroid Build Coastguard Worker    for (int i = 0; i < 4; ++i) {
3653*bbecb9d1SAndroid Build Coastguard Worker       if (writemask & (1 << i)) {
3654*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(glsl_strbufs, "%s[(uint(floatBitsToUint(%s)) >> 2) + %du] = %s(%s).%c;\n",
3655*bbecb9d1SAndroid Build Coastguard Worker                    dst, srcs[0], i, conversion, srcs[1], swizzle_char[i]);
3656*bbecb9d1SAndroid Build Coastguard Worker       }
3657*bbecb9d1SAndroid Build Coastguard Worker    }
3658*bbecb9d1SAndroid Build Coastguard Worker }
3659*bbecb9d1SAndroid Build Coastguard Worker 
3660*bbecb9d1SAndroid Build Coastguard Worker static void
translate_store(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,uint8_t ssbo_memory_qualifier[],struct vrend_shader_image images[],const struct tgsi_full_instruction * inst,struct source_info * sinfo,const char * srcs[4],const struct dest_info * dinfo,const char * dst)3661*bbecb9d1SAndroid Build Coastguard Worker translate_store(const struct dump_ctx *ctx,
3662*bbecb9d1SAndroid Build Coastguard Worker                 struct vrend_glsl_strbufs *glsl_strbufs,
3663*bbecb9d1SAndroid Build Coastguard Worker                 uint8_t ssbo_memory_qualifier[],
3664*bbecb9d1SAndroid Build Coastguard Worker                 struct vrend_shader_image images[],
3665*bbecb9d1SAndroid Build Coastguard Worker                 const struct tgsi_full_instruction *inst,
3666*bbecb9d1SAndroid Build Coastguard Worker                 struct source_info *sinfo,
3667*bbecb9d1SAndroid Build Coastguard Worker                 const char *srcs[4],
3668*bbecb9d1SAndroid Build Coastguard Worker                 const struct dest_info *dinfo,
3669*bbecb9d1SAndroid Build Coastguard Worker                 const char *dst)
3670*bbecb9d1SAndroid Build Coastguard Worker {
3671*bbecb9d1SAndroid Build Coastguard Worker    const struct tgsi_full_dst_register *dst_reg = &inst->Dst[0];
3672*bbecb9d1SAndroid Build Coastguard Worker 
3673*bbecb9d1SAndroid Build Coastguard Worker    assert(dinfo->dest_index >= 0);
3674*bbecb9d1SAndroid Build Coastguard Worker    if (dst_reg->Register.File == TGSI_FILE_IMAGE) {
3675*bbecb9d1SAndroid Build Coastguard Worker 
3676*bbecb9d1SAndroid Build Coastguard Worker       /* bail out if we want to write to a non-existing image */
3677*bbecb9d1SAndroid Build Coastguard Worker       if (!((1 << dinfo->dest_index) & ctx->images_used_mask))
3678*bbecb9d1SAndroid Build Coastguard Worker             return;
3679*bbecb9d1SAndroid Build Coastguard Worker 
3680*bbecb9d1SAndroid Build Coastguard Worker       set_image_qualifier(images, ctx->images_used_mask, inst, inst->Src[0].Register.Index, inst->Src[0].Register.Indirect);
3681*bbecb9d1SAndroid Build Coastguard Worker 
3682*bbecb9d1SAndroid Build Coastguard Worker       bool is_ms = false;
3683*bbecb9d1SAndroid Build Coastguard Worker       enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx->images[dst_reg->Register.Index].decl.Resource, &is_ms, ctx->cfg->use_gles);
3684*bbecb9d1SAndroid Build Coastguard Worker       enum tgsi_return_type itype;
3685*bbecb9d1SAndroid Build Coastguard Worker       char ms_str[32] = "";
3686*bbecb9d1SAndroid Build Coastguard Worker       enum vrend_type_qualifier stypeprefix = TYPE_CONVERSION_NONE;
3687*bbecb9d1SAndroid Build Coastguard Worker       const char *conversion = sinfo->override_no_cast[0] ? "" : get_string(FLOAT_BITS_TO_INT);
3688*bbecb9d1SAndroid Build Coastguard Worker       get_internalformat_string(inst->Memory.Format, &itype);
3689*bbecb9d1SAndroid Build Coastguard Worker       if (is_ms) {
3690*bbecb9d1SAndroid Build Coastguard Worker          snprintf(ms_str, 32, "int(%s.w),", srcs[0]);
3691*bbecb9d1SAndroid Build Coastguard Worker       }
3692*bbecb9d1SAndroid Build Coastguard Worker       switch (itype) {
3693*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_RETURN_TYPE_UINT:
3694*bbecb9d1SAndroid Build Coastguard Worker          stypeprefix = FLOAT_BITS_TO_UINT;
3695*bbecb9d1SAndroid Build Coastguard Worker          break;
3696*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_RETURN_TYPE_SINT:
3697*bbecb9d1SAndroid Build Coastguard Worker          stypeprefix = FLOAT_BITS_TO_INT;
3698*bbecb9d1SAndroid Build Coastguard Worker          break;
3699*bbecb9d1SAndroid Build Coastguard Worker       default:
3700*bbecb9d1SAndroid Build Coastguard Worker          break;
3701*bbecb9d1SAndroid Build Coastguard Worker       }
3702*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles || !dst_reg->Register.Indirect) {
3703*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(glsl_strbufs, "imageStore(%s,%s(%s(%s)),%s%s(%s));\n",
3704*bbecb9d1SAndroid Build Coastguard Worker                    dst, get_string(coord_prefix), conversion, srcs[0],
3705*bbecb9d1SAndroid Build Coastguard Worker                    ms_str, get_string(stypeprefix), srcs[1]);
3706*bbecb9d1SAndroid Build Coastguard Worker       } else {
3707*bbecb9d1SAndroid Build Coastguard Worker          struct vrend_array *image = lookup_image_array_ptr(ctx, dst_reg->Register.Index);
3708*bbecb9d1SAndroid Build Coastguard Worker          if (image) {
3709*bbecb9d1SAndroid Build Coastguard Worker             int basearrayidx = image->first;
3710*bbecb9d1SAndroid Build Coastguard Worker             int array_size = image->array_size;
3711*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(glsl_strbufs, "switch (addr%d + %d) {\n", dst_reg->Indirect.Index,
3712*bbecb9d1SAndroid Build Coastguard Worker                       dst_reg->Register.Index - basearrayidx);
3713*bbecb9d1SAndroid Build Coastguard Worker             const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3714*bbecb9d1SAndroid Build Coastguard Worker 
3715*bbecb9d1SAndroid Build Coastguard Worker             for (int i = 0; i < array_size; ++i) {
3716*bbecb9d1SAndroid Build Coastguard Worker                emit_buff(glsl_strbufs, "case %d: imageStore(%simg%d[%d],%s(%s(%s)),%s%s(%s)); break;\n",
3717*bbecb9d1SAndroid Build Coastguard Worker                          i, cname, basearrayidx, i, get_string(coord_prefix),
3718*bbecb9d1SAndroid Build Coastguard Worker                          conversion, srcs[0], ms_str, get_string(stypeprefix),
3719*bbecb9d1SAndroid Build Coastguard Worker                          srcs[1]);
3720*bbecb9d1SAndroid Build Coastguard Worker             }
3721*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(glsl_strbufs, "}\n");
3722*bbecb9d1SAndroid Build Coastguard Worker          }
3723*bbecb9d1SAndroid Build Coastguard Worker       }
3724*bbecb9d1SAndroid Build Coastguard Worker    } else if (dst_reg->Register.File == TGSI_FILE_BUFFER ||
3725*bbecb9d1SAndroid Build Coastguard Worker               dst_reg->Register.File == TGSI_FILE_MEMORY) {
3726*bbecb9d1SAndroid Build Coastguard Worker       enum vrend_type_qualifier dtypeprefix;
3727*bbecb9d1SAndroid Build Coastguard Worker       set_memory_qualifier(ssbo_memory_qualifier, ctx->ssbo_used_mask, inst, dst_reg->Register.Index,
3728*bbecb9d1SAndroid Build Coastguard Worker                            dst_reg->Register.Indirect);
3729*bbecb9d1SAndroid Build Coastguard Worker       dtypeprefix = is_integer_memory(ctx, dst_reg->Register.File, dst_reg->Register.Index) ?
3730*bbecb9d1SAndroid Build Coastguard Worker                     FLOAT_BITS_TO_INT : FLOAT_BITS_TO_UINT;
3731*bbecb9d1SAndroid Build Coastguard Worker       const char *conversion = sinfo->override_no_cast[1] ? "" : get_string(dtypeprefix);
3732*bbecb9d1SAndroid Build Coastguard Worker 
3733*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles || !dst_reg->Register.Indirect) {
3734*bbecb9d1SAndroid Build Coastguard Worker          emit_store_mem(glsl_strbufs, dst, dst_reg->Register.WriteMask, srcs,
3735*bbecb9d1SAndroid Build Coastguard Worker                         conversion);
3736*bbecb9d1SAndroid Build Coastguard Worker       } else {
3737*bbecb9d1SAndroid Build Coastguard Worker          const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3738*bbecb9d1SAndroid Build Coastguard Worker          bool atomic_ssbo = ctx->ssbo_atomic_mask & (1 << dst_reg->Register.Index);
3739*bbecb9d1SAndroid Build Coastguard Worker          int base = atomic_ssbo ? ctx->ssbo_atomic_array_base : ctx->ssbo_array_base;
3740*bbecb9d1SAndroid Build Coastguard Worker          uint32_t mask = ctx->ssbo_used_mask;
3741*bbecb9d1SAndroid Build Coastguard Worker          int start, array_count;
3742*bbecb9d1SAndroid Build Coastguard Worker          u_bit_scan_consecutive_range(&mask, &start, &array_count);
3743*bbecb9d1SAndroid Build Coastguard Worker          int basearrayidx = lookup_image_array(ctx, dst_reg->Register.Index);
3744*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(glsl_strbufs, "switch (addr%d + %d) {\n", dst_reg->Indirect.Index,
3745*bbecb9d1SAndroid Build Coastguard Worker                    dst_reg->Register.Index - base);
3746*bbecb9d1SAndroid Build Coastguard Worker 
3747*bbecb9d1SAndroid Build Coastguard Worker          for (int i = 0; i < array_count; ++i)  {
3748*bbecb9d1SAndroid Build Coastguard Worker             char dst_tmp[128];
3749*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(glsl_strbufs, "case %d:\n", i);
3750*bbecb9d1SAndroid Build Coastguard Worker             snprintf(dst_tmp, 128, "%simg%d[%d]", cname, basearrayidx, i);
3751*bbecb9d1SAndroid Build Coastguard Worker             emit_store_mem(glsl_strbufs, dst_tmp, dst_reg->Register.WriteMask, srcs,
3752*bbecb9d1SAndroid Build Coastguard Worker                            conversion);
3753*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(glsl_strbufs, "break;\n");
3754*bbecb9d1SAndroid Build Coastguard Worker          }
3755*bbecb9d1SAndroid Build Coastguard Worker          emit_buf(glsl_strbufs, "}\n");
3756*bbecb9d1SAndroid Build Coastguard Worker       }
3757*bbecb9d1SAndroid Build Coastguard Worker    }
3758*bbecb9d1SAndroid Build Coastguard Worker }
3759*bbecb9d1SAndroid Build Coastguard Worker 
emit_load_mem(struct vrend_glsl_strbufs * glsl_strbufs,const char * dst,int writemask,const char * conversion,const char * atomic_op,const char * src0,const char * atomic_src)3760*bbecb9d1SAndroid Build Coastguard Worker static void emit_load_mem(struct vrend_glsl_strbufs *glsl_strbufs, const char *dst, int writemask,
3761*bbecb9d1SAndroid Build Coastguard Worker                           const char *conversion, const char *atomic_op, const char *src0,
3762*bbecb9d1SAndroid Build Coastguard Worker                           const char *atomic_src)
3763*bbecb9d1SAndroid Build Coastguard Worker {
3764*bbecb9d1SAndroid Build Coastguard Worker    static const char swizzle_char[] = "xyzw";
3765*bbecb9d1SAndroid Build Coastguard Worker    for (int i = 0; i < 4; ++i) {
3766*bbecb9d1SAndroid Build Coastguard Worker       if (writemask & (1 << i)) {
3767*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(glsl_strbufs, "%s.%c = (%s(%s(%s[ssbo_addr_temp + %du]%s)));\n", dst,
3768*bbecb9d1SAndroid Build Coastguard Worker                    swizzle_char[i], conversion, atomic_op, src0, i, atomic_src);
3769*bbecb9d1SAndroid Build Coastguard Worker       }
3770*bbecb9d1SAndroid Build Coastguard Worker    }
3771*bbecb9d1SAndroid Build Coastguard Worker }
3772*bbecb9d1SAndroid Build Coastguard Worker 
3773*bbecb9d1SAndroid Build Coastguard Worker static bool
translate_load(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,uint8_t ssbo_memory_qualifier[],struct vrend_shader_image images[],const struct tgsi_full_instruction * inst,struct source_info * sinfo,struct dest_info * dinfo,const char * srcs[4],const char * dst,const char * writemask)3774*bbecb9d1SAndroid Build Coastguard Worker translate_load(const struct dump_ctx *ctx,
3775*bbecb9d1SAndroid Build Coastguard Worker                struct vrend_glsl_strbufs *glsl_strbufs,
3776*bbecb9d1SAndroid Build Coastguard Worker                uint8_t ssbo_memory_qualifier[],
3777*bbecb9d1SAndroid Build Coastguard Worker                struct vrend_shader_image images[],
3778*bbecb9d1SAndroid Build Coastguard Worker                const struct tgsi_full_instruction *inst,
3779*bbecb9d1SAndroid Build Coastguard Worker                struct source_info *sinfo,
3780*bbecb9d1SAndroid Build Coastguard Worker                struct dest_info *dinfo,
3781*bbecb9d1SAndroid Build Coastguard Worker                const char *srcs[4],
3782*bbecb9d1SAndroid Build Coastguard Worker                const char *dst,
3783*bbecb9d1SAndroid Build Coastguard Worker                const char *writemask)
3784*bbecb9d1SAndroid Build Coastguard Worker {
3785*bbecb9d1SAndroid Build Coastguard Worker    const struct tgsi_full_src_register *src = &inst->Src[0];
3786*bbecb9d1SAndroid Build Coastguard Worker    if (src->Register.File == TGSI_FILE_IMAGE) {
3787*bbecb9d1SAndroid Build Coastguard Worker 
3788*bbecb9d1SAndroid Build Coastguard Worker       /* Bail out if we want to load from an image that is not actually used */
3789*bbecb9d1SAndroid Build Coastguard Worker       assert(sinfo->sreg_index >= 0);
3790*bbecb9d1SAndroid Build Coastguard Worker       if (!((1 << sinfo->sreg_index) & ctx->images_used_mask))
3791*bbecb9d1SAndroid Build Coastguard Worker             return false;
3792*bbecb9d1SAndroid Build Coastguard Worker 
3793*bbecb9d1SAndroid Build Coastguard Worker       set_image_qualifier(images, ctx->images_used_mask, inst, inst->Src[0].Register.Index, inst->Src[0].Register.Indirect);
3794*bbecb9d1SAndroid Build Coastguard Worker 
3795*bbecb9d1SAndroid Build Coastguard Worker 
3796*bbecb9d1SAndroid Build Coastguard Worker       bool is_ms = false;
3797*bbecb9d1SAndroid Build Coastguard Worker       enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx->images[sinfo->sreg_index].decl.Resource, &is_ms, ctx->cfg->use_gles);
3798*bbecb9d1SAndroid Build Coastguard Worker       enum vrend_type_qualifier dtypeprefix = TYPE_CONVERSION_NONE;
3799*bbecb9d1SAndroid Build Coastguard Worker       const char *conversion = sinfo->override_no_cast[1] ? "" : get_string(FLOAT_BITS_TO_INT);
3800*bbecb9d1SAndroid Build Coastguard Worker       enum tgsi_return_type itype;
3801*bbecb9d1SAndroid Build Coastguard Worker       get_internalformat_string(ctx->images[sinfo->sreg_index].decl.Format, &itype);
3802*bbecb9d1SAndroid Build Coastguard Worker       char ms_str[32] = "";
3803*bbecb9d1SAndroid Build Coastguard Worker       const char *wm = dinfo->dst_override_no_wm[0] ? "" : writemask;
3804*bbecb9d1SAndroid Build Coastguard Worker       if (is_ms) {
3805*bbecb9d1SAndroid Build Coastguard Worker          snprintf(ms_str, 32, ", int(%s.w)", srcs[1]);
3806*bbecb9d1SAndroid Build Coastguard Worker       }
3807*bbecb9d1SAndroid Build Coastguard Worker       switch (itype) {
3808*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_RETURN_TYPE_UINT:
3809*bbecb9d1SAndroid Build Coastguard Worker          dtypeprefix = UINT_BITS_TO_FLOAT;
3810*bbecb9d1SAndroid Build Coastguard Worker          break;
3811*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_RETURN_TYPE_SINT:
3812*bbecb9d1SAndroid Build Coastguard Worker          dtypeprefix = INT_BITS_TO_FLOAT;
3813*bbecb9d1SAndroid Build Coastguard Worker          break;
3814*bbecb9d1SAndroid Build Coastguard Worker       default:
3815*bbecb9d1SAndroid Build Coastguard Worker          break;
3816*bbecb9d1SAndroid Build Coastguard Worker       }
3817*bbecb9d1SAndroid Build Coastguard Worker 
3818*bbecb9d1SAndroid Build Coastguard Worker       /* On GL WR translates to writable, but on GLES we translate this to writeonly
3819*bbecb9d1SAndroid Build Coastguard Worker        * because for most formats one has to specify one or the other, so if we have an
3820*bbecb9d1SAndroid Build Coastguard Worker        * image with the TGSI WR specification, and read from it, we drop the Writable flag.
3821*bbecb9d1SAndroid Build Coastguard Worker        * For the images that allow RW this is of no consequence, and for the others a write
3822*bbecb9d1SAndroid Build Coastguard Worker        * access will fail instead of the read access, but this doesn't constitue a regression
3823*bbecb9d1SAndroid Build Coastguard Worker        * because we couldn't do both, read and write, anyway. */
3824*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->use_gles && ctx->images[sinfo->sreg_index].decl.Writable &&
3825*bbecb9d1SAndroid Build Coastguard Worker           (ctx->images[sinfo->sreg_index].decl.Format != PIPE_FORMAT_R32_FLOAT) &&
3826*bbecb9d1SAndroid Build Coastguard Worker           (ctx->images[sinfo->sreg_index].decl.Format != PIPE_FORMAT_R32_SINT) &&
3827*bbecb9d1SAndroid Build Coastguard Worker           (ctx->images[sinfo->sreg_index].decl.Format != PIPE_FORMAT_R32_UINT))
3828*bbecb9d1SAndroid Build Coastguard Worker          images[sinfo->sreg_index].decl.Writable = 0;
3829*bbecb9d1SAndroid Build Coastguard Worker 
3830*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles || !inst->Src[0].Register.Indirect) {
3831*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(glsl_strbufs, "%s = %s(imageLoad(%s, %s(%s(%s))%s)%s);\n",
3832*bbecb9d1SAndroid Build Coastguard Worker                dst, get_string(dtypeprefix),
3833*bbecb9d1SAndroid Build Coastguard Worker                srcs[0], get_string(coord_prefix), conversion, srcs[1],
3834*bbecb9d1SAndroid Build Coastguard Worker                ms_str, wm);
3835*bbecb9d1SAndroid Build Coastguard Worker       } else {
3836*bbecb9d1SAndroid Build Coastguard Worker          char src[32] = "";
3837*bbecb9d1SAndroid Build Coastguard Worker          struct vrend_array *image = lookup_image_array_ptr(ctx, inst->Src[0].Register.Index);
3838*bbecb9d1SAndroid Build Coastguard Worker          if (image) {
3839*bbecb9d1SAndroid Build Coastguard Worker             int basearrayidx = image->first;
3840*bbecb9d1SAndroid Build Coastguard Worker             int array_size = image->array_size;
3841*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(glsl_strbufs, "switch (addr%d + %d) {\n", inst->Src[0].Indirect.Index, inst->Src[0].Register.Index - basearrayidx);
3842*bbecb9d1SAndroid Build Coastguard Worker             const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3843*bbecb9d1SAndroid Build Coastguard Worker 
3844*bbecb9d1SAndroid Build Coastguard Worker             for (int i = 0; i < array_size; ++i) {
3845*bbecb9d1SAndroid Build Coastguard Worker                snprintf(src, 32, "%simg%d[%d]", cname, basearrayidx, i);
3846*bbecb9d1SAndroid Build Coastguard Worker                emit_buff(glsl_strbufs, "case %d: %s = %s(imageLoad(%s, %s(%s(%s))%s)%s);break;\n",
3847*bbecb9d1SAndroid Build Coastguard Worker                          i, dst, get_string(dtypeprefix),
3848*bbecb9d1SAndroid Build Coastguard Worker                          src, get_string(coord_prefix), conversion, srcs[1],
3849*bbecb9d1SAndroid Build Coastguard Worker                          ms_str, wm);
3850*bbecb9d1SAndroid Build Coastguard Worker             }
3851*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(glsl_strbufs, "}\n");
3852*bbecb9d1SAndroid Build Coastguard Worker          }
3853*bbecb9d1SAndroid Build Coastguard Worker       }
3854*bbecb9d1SAndroid Build Coastguard Worker    } else if (src->Register.File == TGSI_FILE_BUFFER ||
3855*bbecb9d1SAndroid Build Coastguard Worker               src->Register.File == TGSI_FILE_MEMORY) {
3856*bbecb9d1SAndroid Build Coastguard Worker       char mydst[255], atomic_op[9], atomic_src[10];
3857*bbecb9d1SAndroid Build Coastguard Worker       enum vrend_type_qualifier dtypeprefix;
3858*bbecb9d1SAndroid Build Coastguard Worker 
3859*bbecb9d1SAndroid Build Coastguard Worker       set_memory_qualifier(ssbo_memory_qualifier, ctx->ssbo_used_mask, inst, inst->Src[0].Register.Index, inst->Src[0].Register.Indirect);
3860*bbecb9d1SAndroid Build Coastguard Worker 
3861*bbecb9d1SAndroid Build Coastguard Worker       const char *d = dst;
3862*bbecb9d1SAndroid Build Coastguard Worker       char *md = mydst;
3863*bbecb9d1SAndroid Build Coastguard Worker       unsigned i = 0;
3864*bbecb9d1SAndroid Build Coastguard Worker       while ((i < sizeof(mydst) - 1) && *d && *d != '.')
3865*bbecb9d1SAndroid Build Coastguard Worker          *md++ = *d++;
3866*bbecb9d1SAndroid Build Coastguard Worker       *md = 0;
3867*bbecb9d1SAndroid Build Coastguard Worker 
3868*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(glsl_strbufs, "ssbo_addr_temp = uint(floatBitsToUint(%s)) >> 2;\n", srcs[1]);
3869*bbecb9d1SAndroid Build Coastguard Worker 
3870*bbecb9d1SAndroid Build Coastguard Worker       atomic_op[0] = atomic_src[0] = '\0';
3871*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->ssbo_atomic_mask & (1 << src->Register.Index)) {
3872*bbecb9d1SAndroid Build Coastguard Worker          /* Emulate atomicCounter with atomicOr. */
3873*bbecb9d1SAndroid Build Coastguard Worker          strcpy(atomic_op, "atomicOr");
3874*bbecb9d1SAndroid Build Coastguard Worker          strcpy(atomic_src, ", uint(0)");
3875*bbecb9d1SAndroid Build Coastguard Worker       }
3876*bbecb9d1SAndroid Build Coastguard Worker 
3877*bbecb9d1SAndroid Build Coastguard Worker       dtypeprefix = (is_integer_memory(ctx, src->Register.File, src->Register.Index)) ? INT_BITS_TO_FLOAT : UINT_BITS_TO_FLOAT;
3878*bbecb9d1SAndroid Build Coastguard Worker 
3879*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles || !inst->Src[0].Register.Indirect) {
3880*bbecb9d1SAndroid Build Coastguard Worker          emit_load_mem(glsl_strbufs, mydst, inst->Dst[0].Register.WriteMask, get_string(dtypeprefix), atomic_op, srcs[0], atomic_src);
3881*bbecb9d1SAndroid Build Coastguard Worker       } else {
3882*bbecb9d1SAndroid Build Coastguard Worker          char src[128] = "";
3883*bbecb9d1SAndroid Build Coastguard Worker          const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3884*bbecb9d1SAndroid Build Coastguard Worker          bool atomic_ssbo = ctx->ssbo_atomic_mask & (1 << inst->Src[0].Register.Index);
3885*bbecb9d1SAndroid Build Coastguard Worker          const char *atomic_str = atomic_ssbo ? "atomic" : "";
3886*bbecb9d1SAndroid Build Coastguard Worker          uint base = atomic_ssbo ? ctx->ssbo_atomic_array_base : ctx->ssbo_array_base;
3887*bbecb9d1SAndroid Build Coastguard Worker          int start, array_count;
3888*bbecb9d1SAndroid Build Coastguard Worker          uint32_t mask = ctx->ssbo_used_mask;
3889*bbecb9d1SAndroid Build Coastguard Worker          u_bit_scan_consecutive_range(&mask, &start, &array_count);
3890*bbecb9d1SAndroid Build Coastguard Worker 
3891*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(glsl_strbufs, "switch (addr%d + %d) {\n", inst->Src[0].Indirect.Index, inst->Src[0].Register.Index - base);
3892*bbecb9d1SAndroid Build Coastguard Worker          for (int i = 0; i < array_count; ++i) {
3893*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(glsl_strbufs, "case %d:\n", i);
3894*bbecb9d1SAndroid Build Coastguard Worker             snprintf(src, 128,"%sssboarr%s[%d].%sssbocontents%d", cname, atomic_str, i, cname, base);
3895*bbecb9d1SAndroid Build Coastguard Worker             emit_load_mem(glsl_strbufs, mydst, inst->Dst[0].Register.WriteMask, get_string(dtypeprefix), atomic_op, src, atomic_src);
3896*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(glsl_strbufs, "  break;\n");
3897*bbecb9d1SAndroid Build Coastguard Worker          }
3898*bbecb9d1SAndroid Build Coastguard Worker          emit_buf(glsl_strbufs, "}\n");
3899*bbecb9d1SAndroid Build Coastguard Worker       }
3900*bbecb9d1SAndroid Build Coastguard Worker    } else if (src->Register.File == TGSI_FILE_HW_ATOMIC) {
3901*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(glsl_strbufs, "%s = uintBitsToFloat(atomicCounter(%s));\n", dst, srcs[0]);
3902*bbecb9d1SAndroid Build Coastguard Worker    }
3903*bbecb9d1SAndroid Build Coastguard Worker    return true;
3904*bbecb9d1SAndroid Build Coastguard Worker }
3905*bbecb9d1SAndroid Build Coastguard Worker 
get_atomic_opname(int tgsi_opcode,bool * is_cas)3906*bbecb9d1SAndroid Build Coastguard Worker static const char *get_atomic_opname(int tgsi_opcode, bool *is_cas)
3907*bbecb9d1SAndroid Build Coastguard Worker {
3908*bbecb9d1SAndroid Build Coastguard Worker    const char *opname;
3909*bbecb9d1SAndroid Build Coastguard Worker    *is_cas = false;
3910*bbecb9d1SAndroid Build Coastguard Worker    switch (tgsi_opcode) {
3911*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMUADD:
3912*bbecb9d1SAndroid Build Coastguard Worker       opname = "Add";
3913*bbecb9d1SAndroid Build Coastguard Worker       break;
3914*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMXCHG:
3915*bbecb9d1SAndroid Build Coastguard Worker       opname = "Exchange";
3916*bbecb9d1SAndroid Build Coastguard Worker       break;
3917*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMCAS:
3918*bbecb9d1SAndroid Build Coastguard Worker       opname = "CompSwap";
3919*bbecb9d1SAndroid Build Coastguard Worker       *is_cas = true;
3920*bbecb9d1SAndroid Build Coastguard Worker       break;
3921*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMAND:
3922*bbecb9d1SAndroid Build Coastguard Worker       opname = "And";
3923*bbecb9d1SAndroid Build Coastguard Worker       break;
3924*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMOR:
3925*bbecb9d1SAndroid Build Coastguard Worker       opname = "Or";
3926*bbecb9d1SAndroid Build Coastguard Worker       break;
3927*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMXOR:
3928*bbecb9d1SAndroid Build Coastguard Worker       opname = "Xor";
3929*bbecb9d1SAndroid Build Coastguard Worker       break;
3930*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMUMIN:
3931*bbecb9d1SAndroid Build Coastguard Worker       opname = "Min";
3932*bbecb9d1SAndroid Build Coastguard Worker       break;
3933*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMUMAX:
3934*bbecb9d1SAndroid Build Coastguard Worker       opname = "Max";
3935*bbecb9d1SAndroid Build Coastguard Worker       break;
3936*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMIMIN:
3937*bbecb9d1SAndroid Build Coastguard Worker       opname = "Min";
3938*bbecb9d1SAndroid Build Coastguard Worker       break;
3939*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMIMAX:
3940*bbecb9d1SAndroid Build Coastguard Worker       opname = "Max";
3941*bbecb9d1SAndroid Build Coastguard Worker       break;
3942*bbecb9d1SAndroid Build Coastguard Worker    default:
3943*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf( "illegal atomic opcode");
3944*bbecb9d1SAndroid Build Coastguard Worker       return NULL;
3945*bbecb9d1SAndroid Build Coastguard Worker    }
3946*bbecb9d1SAndroid Build Coastguard Worker    return opname;
3947*bbecb9d1SAndroid Build Coastguard Worker }
3948*bbecb9d1SAndroid Build Coastguard Worker 
3949*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
3950*bbecb9d1SAndroid Build Coastguard Worker static void
translate_resq(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,const char * srcs[4],const char * dst,const char * writemask)3951*bbecb9d1SAndroid Build Coastguard Worker translate_resq(struct dump_ctx *ctx, const struct tgsi_full_instruction *inst,
3952*bbecb9d1SAndroid Build Coastguard Worker                const char *srcs[4], const char *dst, const char *writemask)
3953*bbecb9d1SAndroid Build Coastguard Worker {
3954*bbecb9d1SAndroid Build Coastguard Worker    const struct tgsi_full_src_register *src = &inst->Src[0];
3955*bbecb9d1SAndroid Build Coastguard Worker 
3956*bbecb9d1SAndroid Build Coastguard Worker    if (src->Register.File == TGSI_FILE_IMAGE) {
3957*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Dst[0].Register.WriteMask & 0x8) {
3958*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_TXQS | SHADER_REQ_INTS;
3959*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = %s(imageSamples(%s));\n",
3960*bbecb9d1SAndroid Build Coastguard Worker                    dst, get_string(INT_BITS_TO_FLOAT), srcs[0]);
3961*bbecb9d1SAndroid Build Coastguard Worker       }
3962*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Dst[0].Register.WriteMask & 0x7) {
3963*bbecb9d1SAndroid Build Coastguard Worker          const char *swizzle_mask = (ctx->cfg->use_gles && inst->Memory.Texture == TGSI_TEXTURE_1D_ARRAY) ?
3964*bbecb9d1SAndroid Build Coastguard Worker                                    ".xz" : "";
3965*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_IMAGE_SIZE | SHADER_REQ_INTS;
3966*bbecb9d1SAndroid Build Coastguard Worker          bool skip_emit_writemask = inst->Memory.Texture == TGSI_TEXTURE_BUFFER ||
3967*bbecb9d1SAndroid Build Coastguard Worker                                     (!ctx->cfg->use_gles && inst->Memory.Texture == TGSI_TEXTURE_1D);
3968*bbecb9d1SAndroid Build Coastguard Worker 
3969*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = %s(imageSize(%s)%s%s);\n",
3970*bbecb9d1SAndroid Build Coastguard Worker                    dst, get_string(INT_BITS_TO_FLOAT), srcs[0],
3971*bbecb9d1SAndroid Build Coastguard Worker                    swizzle_mask, skip_emit_writemask ? "" : writemask);
3972*bbecb9d1SAndroid Build Coastguard Worker       }
3973*bbecb9d1SAndroid Build Coastguard Worker    } else if (src->Register.File == TGSI_FILE_BUFFER) {
3974*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(int(%s.length()) << 2);\n",
3975*bbecb9d1SAndroid Build Coastguard Worker                 dst, get_string(INT_BITS_TO_FLOAT), srcs[0]);
3976*bbecb9d1SAndroid Build Coastguard Worker    }
3977*bbecb9d1SAndroid Build Coastguard Worker }
3978*bbecb9d1SAndroid Build Coastguard Worker 
3979*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
3980*bbecb9d1SAndroid Build Coastguard Worker static void
translate_atomic(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,struct source_info * sinfo,const char * srcs[4],char * dst)3981*bbecb9d1SAndroid Build Coastguard Worker translate_atomic(struct dump_ctx *ctx,
3982*bbecb9d1SAndroid Build Coastguard Worker                  const struct tgsi_full_instruction *inst,
3983*bbecb9d1SAndroid Build Coastguard Worker                  struct source_info *sinfo,
3984*bbecb9d1SAndroid Build Coastguard Worker                  const char *srcs[4],
3985*bbecb9d1SAndroid Build Coastguard Worker                  char *dst)
3986*bbecb9d1SAndroid Build Coastguard Worker {
3987*bbecb9d1SAndroid Build Coastguard Worker    const struct tgsi_full_src_register *src = &inst->Src[0];
3988*bbecb9d1SAndroid Build Coastguard Worker    const char *opname;
3989*bbecb9d1SAndroid Build Coastguard Worker    enum vrend_type_qualifier stypeprefix = TYPE_CONVERSION_NONE;
3990*bbecb9d1SAndroid Build Coastguard Worker    enum vrend_type_qualifier dtypeprefix = TYPE_CONVERSION_NONE;
3991*bbecb9d1SAndroid Build Coastguard Worker    enum vrend_type_qualifier stypecast = TYPE_CONVERSION_NONE;
3992*bbecb9d1SAndroid Build Coastguard Worker    bool is_cas;
3993*bbecb9d1SAndroid Build Coastguard Worker    char cas_str[128] = "";
3994*bbecb9d1SAndroid Build Coastguard Worker 
3995*bbecb9d1SAndroid Build Coastguard Worker    if (src->Register.File == TGSI_FILE_IMAGE) {
3996*bbecb9d1SAndroid Build Coastguard Worker      enum tgsi_return_type itype;
3997*bbecb9d1SAndroid Build Coastguard Worker      get_internalformat_string(ctx->images[sinfo->sreg_index].decl.Format, &itype);
3998*bbecb9d1SAndroid Build Coastguard Worker      switch (itype) {
3999*bbecb9d1SAndroid Build Coastguard Worker      default:
4000*bbecb9d1SAndroid Build Coastguard Worker      case TGSI_RETURN_TYPE_UINT:
4001*bbecb9d1SAndroid Build Coastguard Worker         stypeprefix = FLOAT_BITS_TO_UINT;
4002*bbecb9d1SAndroid Build Coastguard Worker         dtypeprefix = UINT_BITS_TO_FLOAT;
4003*bbecb9d1SAndroid Build Coastguard Worker         stypecast = UINT;
4004*bbecb9d1SAndroid Build Coastguard Worker         break;
4005*bbecb9d1SAndroid Build Coastguard Worker      case TGSI_RETURN_TYPE_SINT:
4006*bbecb9d1SAndroid Build Coastguard Worker         stypeprefix = FLOAT_BITS_TO_INT;
4007*bbecb9d1SAndroid Build Coastguard Worker         dtypeprefix = INT_BITS_TO_FLOAT;
4008*bbecb9d1SAndroid Build Coastguard Worker         stypecast = INT;
4009*bbecb9d1SAndroid Build Coastguard Worker         break;
4010*bbecb9d1SAndroid Build Coastguard Worker      case TGSI_RETURN_TYPE_FLOAT:
4011*bbecb9d1SAndroid Build Coastguard Worker         if (ctx->cfg->has_es31_compat)
4012*bbecb9d1SAndroid Build Coastguard Worker            ctx->shader_req_bits |= SHADER_REQ_ES31_COMPAT;
4013*bbecb9d1SAndroid Build Coastguard Worker         else
4014*bbecb9d1SAndroid Build Coastguard Worker            ctx->shader_req_bits |= SHADER_REQ_SHADER_ATOMIC_FLOAT;
4015*bbecb9d1SAndroid Build Coastguard Worker         stypecast = FLOAT;
4016*bbecb9d1SAndroid Build Coastguard Worker         break;
4017*bbecb9d1SAndroid Build Coastguard Worker      }
4018*bbecb9d1SAndroid Build Coastguard Worker    } else {
4019*bbecb9d1SAndroid Build Coastguard Worker      stypeprefix = FLOAT_BITS_TO_UINT;
4020*bbecb9d1SAndroid Build Coastguard Worker      dtypeprefix = UINT_BITS_TO_FLOAT;
4021*bbecb9d1SAndroid Build Coastguard Worker      stypecast = UINT;
4022*bbecb9d1SAndroid Build Coastguard Worker    }
4023*bbecb9d1SAndroid Build Coastguard Worker 
4024*bbecb9d1SAndroid Build Coastguard Worker    opname = get_atomic_opname(inst->Instruction.Opcode, &is_cas);
4025*bbecb9d1SAndroid Build Coastguard Worker    if (!opname) {
4026*bbecb9d1SAndroid Build Coastguard Worker       set_buf_error(&ctx->glsl_strbufs);
4027*bbecb9d1SAndroid Build Coastguard Worker       return;
4028*bbecb9d1SAndroid Build Coastguard Worker    }
4029*bbecb9d1SAndroid Build Coastguard Worker 
4030*bbecb9d1SAndroid Build Coastguard Worker    if (is_cas)
4031*bbecb9d1SAndroid Build Coastguard Worker       snprintf(cas_str, 128, ", %s(%s(%s))", get_string(stypecast), get_string(stypeprefix), srcs[3]);
4032*bbecb9d1SAndroid Build Coastguard Worker 
4033*bbecb9d1SAndroid Build Coastguard Worker    if (src->Register.File == TGSI_FILE_IMAGE) {
4034*bbecb9d1SAndroid Build Coastguard Worker       bool is_ms = false;
4035*bbecb9d1SAndroid Build Coastguard Worker       enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx->images[sinfo->sreg_index].decl.Resource, &is_ms, ctx->cfg->use_gles);
4036*bbecb9d1SAndroid Build Coastguard Worker       const char *conversion = sinfo->override_no_cast[1] ? "" : get_string(FLOAT_BITS_TO_INT);
4037*bbecb9d1SAndroid Build Coastguard Worker       char ms_str[32] = "";
4038*bbecb9d1SAndroid Build Coastguard Worker       if (is_ms) {
4039*bbecb9d1SAndroid Build Coastguard Worker          snprintf(ms_str, 32, ", int(%s.w)", srcs[1]);
4040*bbecb9d1SAndroid Build Coastguard Worker       }
4041*bbecb9d1SAndroid Build Coastguard Worker 
4042*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles || !inst->Src[0].Register.Indirect) {
4043*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = %s(imageAtomic%s(%s, %s(%s(%s))%s, %s(%s(%s))%s));\n",
4044*bbecb9d1SAndroid Build Coastguard Worker                    dst, get_string(dtypeprefix), opname, srcs[0],
4045*bbecb9d1SAndroid Build Coastguard Worker                    get_string(coord_prefix), conversion, srcs[1], ms_str,
4046*bbecb9d1SAndroid Build Coastguard Worker                    get_string(stypecast), get_string(stypeprefix), srcs[2],
4047*bbecb9d1SAndroid Build Coastguard Worker                    cas_str);
4048*bbecb9d1SAndroid Build Coastguard Worker       } else {
4049*bbecb9d1SAndroid Build Coastguard Worker          char src[32] = "";
4050*bbecb9d1SAndroid Build Coastguard Worker          struct vrend_array *image = lookup_image_array_ptr(ctx, inst->Src[0].Register.Index);
4051*bbecb9d1SAndroid Build Coastguard Worker          if (image) {
4052*bbecb9d1SAndroid Build Coastguard Worker             int basearrayidx = image->first;
4053*bbecb9d1SAndroid Build Coastguard Worker             int array_size = image->array_size;
4054*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(&ctx->glsl_strbufs, "switch (addr%d + %d) {\n", inst->Src[0].Indirect.Index, inst->Src[0].Register.Index - basearrayidx);
4055*bbecb9d1SAndroid Build Coastguard Worker             const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4056*bbecb9d1SAndroid Build Coastguard Worker 
4057*bbecb9d1SAndroid Build Coastguard Worker             for (int i = 0; i < array_size; ++i) {
4058*bbecb9d1SAndroid Build Coastguard Worker                snprintf(src, 32, "%simg%d[%d]", cname, basearrayidx, i);
4059*bbecb9d1SAndroid Build Coastguard Worker                emit_buff(&ctx->glsl_strbufs, "case %d: %s = %s(imageAtomic%s(%s, %s(%s(%s))%s, %s(%s(%s))%s));\n",
4060*bbecb9d1SAndroid Build Coastguard Worker                          i, dst, get_string(dtypeprefix), opname, src,
4061*bbecb9d1SAndroid Build Coastguard Worker                          get_string(coord_prefix), conversion, srcs[1],
4062*bbecb9d1SAndroid Build Coastguard Worker                          ms_str, get_string(stypecast),
4063*bbecb9d1SAndroid Build Coastguard Worker                          get_string(stypeprefix), srcs[2], cas_str);
4064*bbecb9d1SAndroid Build Coastguard Worker             }
4065*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(&ctx->glsl_strbufs, "}\n");
4066*bbecb9d1SAndroid Build Coastguard Worker          }
4067*bbecb9d1SAndroid Build Coastguard Worker       }
4068*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_IMAGE_ATOMIC;
4069*bbecb9d1SAndroid Build Coastguard Worker    }
4070*bbecb9d1SAndroid Build Coastguard Worker    if (src->Register.File == TGSI_FILE_BUFFER || src->Register.File == TGSI_FILE_MEMORY) {
4071*bbecb9d1SAndroid Build Coastguard Worker       enum vrend_type_qualifier type;
4072*bbecb9d1SAndroid Build Coastguard Worker       if ((is_integer_memory(ctx, src->Register.File, src->Register.Index))) {
4073*bbecb9d1SAndroid Build Coastguard Worker 	 type = INT;
4074*bbecb9d1SAndroid Build Coastguard Worker 	 dtypeprefix = INT_BITS_TO_FLOAT;
4075*bbecb9d1SAndroid Build Coastguard Worker 	 stypeprefix = FLOAT_BITS_TO_INT;
4076*bbecb9d1SAndroid Build Coastguard Worker       } else {
4077*bbecb9d1SAndroid Build Coastguard Worker 	 type = UINT;
4078*bbecb9d1SAndroid Build Coastguard Worker 	 dtypeprefix = UINT_BITS_TO_FLOAT;
4079*bbecb9d1SAndroid Build Coastguard Worker 	 stypeprefix = FLOAT_BITS_TO_UINT;
4080*bbecb9d1SAndroid Build Coastguard Worker       }
4081*bbecb9d1SAndroid Build Coastguard Worker 
4082*bbecb9d1SAndroid Build Coastguard Worker       if (is_cas)
4083*bbecb9d1SAndroid Build Coastguard Worker          snprintf(cas_str, sizeof(cas_str), ", %s(%s(%s))", get_string(type), get_string(stypeprefix), srcs[3]);
4084*bbecb9d1SAndroid Build Coastguard Worker 
4085*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(atomic%s(%s[int(floatBitsToInt(%s)) >> 2], %s(%s(%s).x)%s));\n",
4086*bbecb9d1SAndroid Build Coastguard Worker                 dst, get_string(dtypeprefix), opname, srcs[0], srcs[1],
4087*bbecb9d1SAndroid Build Coastguard Worker                 get_string(type), get_string(stypeprefix), srcs[2], cas_str);
4088*bbecb9d1SAndroid Build Coastguard Worker    }
4089*bbecb9d1SAndroid Build Coastguard Worker    if(src->Register.File == TGSI_FILE_HW_ATOMIC) {
4090*bbecb9d1SAndroid Build Coastguard Worker       if (sinfo->imm_value == -1)
4091*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = %s(atomicCounterDecrement(%s) + 1u);\n",
4092*bbecb9d1SAndroid Build Coastguard Worker                    dst, get_string(dtypeprefix), srcs[0]);
4093*bbecb9d1SAndroid Build Coastguard Worker       else if (sinfo->imm_value == 1)
4094*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = %s(atomicCounterIncrement(%s));\n",
4095*bbecb9d1SAndroid Build Coastguard Worker                    dst, get_string(dtypeprefix), srcs[0]);
4096*bbecb9d1SAndroid Build Coastguard Worker       else
4097*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = %s(atomicCounter%sARB(%s, floatBitsToUint(%s).x%s));\n",
4098*bbecb9d1SAndroid Build Coastguard Worker                    dst, get_string(dtypeprefix), opname, srcs[0], srcs[2],
4099*bbecb9d1SAndroid Build Coastguard Worker                    cas_str);
4100*bbecb9d1SAndroid Build Coastguard Worker    }
4101*bbecb9d1SAndroid Build Coastguard Worker 
4102*bbecb9d1SAndroid Build Coastguard Worker }
4103*bbecb9d1SAndroid Build Coastguard Worker 
reswizzle_dest(const struct vrend_shader_io * io,const struct tgsi_full_dst_register * dst_reg,char * reswizzled,const char * writemask)4104*bbecb9d1SAndroid Build Coastguard Worker static const char *reswizzle_dest(const struct vrend_shader_io *io, const struct tgsi_full_dst_register *dst_reg,
4105*bbecb9d1SAndroid Build Coastguard Worker                                   char *reswizzled, const char *writemask)
4106*bbecb9d1SAndroid Build Coastguard Worker {
4107*bbecb9d1SAndroid Build Coastguard Worker    if (io->usage_mask != 0xf) {
4108*bbecb9d1SAndroid Build Coastguard Worker       if (io->num_components > 1) {
4109*bbecb9d1SAndroid Build Coastguard Worker          const int wm = dst_reg->Register.WriteMask;
4110*bbecb9d1SAndroid Build Coastguard Worker          int k = 1;
4111*bbecb9d1SAndroid Build Coastguard Worker          reswizzled[0] = '.';
4112*bbecb9d1SAndroid Build Coastguard Worker          for (int i = 0; i < io->num_components; ++i) {
4113*bbecb9d1SAndroid Build Coastguard Worker             if (wm & (1 << i))
4114*bbecb9d1SAndroid Build Coastguard Worker                reswizzled[k++] = get_swiz_char(i);
4115*bbecb9d1SAndroid Build Coastguard Worker          }
4116*bbecb9d1SAndroid Build Coastguard Worker          reswizzled[k] = 0;
4117*bbecb9d1SAndroid Build Coastguard Worker       }
4118*bbecb9d1SAndroid Build Coastguard Worker       writemask = reswizzled;
4119*bbecb9d1SAndroid Build Coastguard Worker    }
4120*bbecb9d1SAndroid Build Coastguard Worker    return writemask;
4121*bbecb9d1SAndroid Build Coastguard Worker }
4122*bbecb9d1SAndroid Build Coastguard Worker 
get_destination_info_generic(const struct dump_ctx * ctx,const struct tgsi_full_dst_register * dst_reg,const struct vrend_shader_io * io,const char * writemask,struct vrend_strbuf * result)4123*bbecb9d1SAndroid Build Coastguard Worker static void get_destination_info_generic(const struct dump_ctx *ctx,
4124*bbecb9d1SAndroid Build Coastguard Worker                                          const struct tgsi_full_dst_register *dst_reg,
4125*bbecb9d1SAndroid Build Coastguard Worker                                          const struct vrend_shader_io *io,
4126*bbecb9d1SAndroid Build Coastguard Worker                                          const char *writemask,
4127*bbecb9d1SAndroid Build Coastguard Worker                                          struct vrend_strbuf *result)
4128*bbecb9d1SAndroid Build Coastguard Worker {
4129*bbecb9d1SAndroid Build Coastguard Worker    const char *blkarray = (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL) ? "[gl_InvocationID]" : "";
4130*bbecb9d1SAndroid Build Coastguard Worker    const char *stage_prefix = get_stage_output_name_prefix(ctx->prog_type);
4131*bbecb9d1SAndroid Build Coastguard Worker    const char *wm = io->override_no_wm ? "" : writemask;
4132*bbecb9d1SAndroid Build Coastguard Worker    char reswizzled[6] = "";
4133*bbecb9d1SAndroid Build Coastguard Worker    char outvarname[64];
4134*bbecb9d1SAndroid Build Coastguard Worker 
4135*bbecb9d1SAndroid Build Coastguard Worker    wm = reswizzle_dest(io, dst_reg, reswizzled, writemask);
4136*bbecb9d1SAndroid Build Coastguard Worker 
4137*bbecb9d1SAndroid Build Coastguard Worker    strbuf_reset(result);
4138*bbecb9d1SAndroid Build Coastguard Worker 
4139*bbecb9d1SAndroid Build Coastguard Worker    enum io_decl_type decl_type = decl_plain;
4140*bbecb9d1SAndroid Build Coastguard Worker    if (io->first != io->last && prefer_generic_io_block(ctx, io_out)) {
4141*bbecb9d1SAndroid Build Coastguard Worker       get_blockvarname(outvarname, stage_prefix,  io, blkarray);
4142*bbecb9d1SAndroid Build Coastguard Worker       blkarray = outvarname;
4143*bbecb9d1SAndroid Build Coastguard Worker       decl_type = decl_block;
4144*bbecb9d1SAndroid Build Coastguard Worker    }
4145*bbecb9d1SAndroid Build Coastguard Worker    vrend_shader_write_io_as_dst(result, blkarray, io, dst_reg, decl_type);
4146*bbecb9d1SAndroid Build Coastguard Worker    strbuf_appendf(result, "%s", wm);
4147*bbecb9d1SAndroid Build Coastguard Worker }
4148*bbecb9d1SAndroid Build Coastguard Worker 
4149*bbecb9d1SAndroid Build Coastguard Worker static
find_io_index(int num_io,struct vrend_shader_io * io,int index)4150*bbecb9d1SAndroid Build Coastguard Worker int find_io_index(int num_io, struct vrend_shader_io *io, int index)
4151*bbecb9d1SAndroid Build Coastguard Worker {
4152*bbecb9d1SAndroid Build Coastguard Worker    for (int j = 0; j < num_io; j++) {
4153*bbecb9d1SAndroid Build Coastguard Worker       if (io[j].first <= index &&
4154*bbecb9d1SAndroid Build Coastguard Worker           io[j].last >= index) {
4155*bbecb9d1SAndroid Build Coastguard Worker          return j;
4156*bbecb9d1SAndroid Build Coastguard Worker       }
4157*bbecb9d1SAndroid Build Coastguard Worker    }
4158*bbecb9d1SAndroid Build Coastguard Worker    return -1;
4159*bbecb9d1SAndroid Build Coastguard Worker }
4160*bbecb9d1SAndroid Build Coastguard Worker 
4161*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
4162*bbecb9d1SAndroid Build Coastguard Worker static bool
get_destination_info(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,struct dest_info * dinfo,struct vrend_strbuf dst_bufs[3],char fp64_dsts[3][255],char * writemask)4163*bbecb9d1SAndroid Build Coastguard Worker get_destination_info(struct dump_ctx *ctx,
4164*bbecb9d1SAndroid Build Coastguard Worker                      const struct tgsi_full_instruction *inst,
4165*bbecb9d1SAndroid Build Coastguard Worker                      struct dest_info *dinfo,
4166*bbecb9d1SAndroid Build Coastguard Worker                      struct vrend_strbuf dst_bufs[3],
4167*bbecb9d1SAndroid Build Coastguard Worker                      char fp64_dsts[3][255],
4168*bbecb9d1SAndroid Build Coastguard Worker                      char *writemask)
4169*bbecb9d1SAndroid Build Coastguard Worker {
4170*bbecb9d1SAndroid Build Coastguard Worker    const struct tgsi_full_dst_register *dst_reg;
4171*bbecb9d1SAndroid Build Coastguard Worker    enum tgsi_opcode_type dtype = tgsi_opcode_infer_dst_type(inst->Instruction.Opcode);
4172*bbecb9d1SAndroid Build Coastguard Worker 
4173*bbecb9d1SAndroid Build Coastguard Worker    if (dtype == TGSI_TYPE_SIGNED || dtype == TGSI_TYPE_UNSIGNED)
4174*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_INTS;
4175*bbecb9d1SAndroid Build Coastguard Worker 
4176*bbecb9d1SAndroid Build Coastguard Worker    if (dtype == TGSI_TYPE_DOUBLE) {
4177*bbecb9d1SAndroid Build Coastguard Worker       /* we need the uvec2 conversion for doubles */
4178*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_INTS | SHADER_REQ_FP64;
4179*bbecb9d1SAndroid Build Coastguard Worker    }
4180*bbecb9d1SAndroid Build Coastguard Worker 
4181*bbecb9d1SAndroid Build Coastguard Worker    if (inst->Instruction.Opcode == TGSI_OPCODE_TXQ) {
4182*bbecb9d1SAndroid Build Coastguard Worker       dinfo->dtypeprefix = INT_BITS_TO_FLOAT;
4183*bbecb9d1SAndroid Build Coastguard Worker    } else {
4184*bbecb9d1SAndroid Build Coastguard Worker       switch (dtype) {
4185*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TYPE_UNSIGNED:
4186*bbecb9d1SAndroid Build Coastguard Worker          dinfo->dtypeprefix = UINT_BITS_TO_FLOAT;
4187*bbecb9d1SAndroid Build Coastguard Worker          break;
4188*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_TYPE_SIGNED:
4189*bbecb9d1SAndroid Build Coastguard Worker          dinfo->dtypeprefix = INT_BITS_TO_FLOAT;
4190*bbecb9d1SAndroid Build Coastguard Worker          break;
4191*bbecb9d1SAndroid Build Coastguard Worker       default:
4192*bbecb9d1SAndroid Build Coastguard Worker          break;
4193*bbecb9d1SAndroid Build Coastguard Worker       }
4194*bbecb9d1SAndroid Build Coastguard Worker    }
4195*bbecb9d1SAndroid Build Coastguard Worker 
4196*bbecb9d1SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < inst->Instruction.NumDstRegs; i++) {
4197*bbecb9d1SAndroid Build Coastguard Worker       char fp64_writemask[6] = "";
4198*bbecb9d1SAndroid Build Coastguard Worker       dst_reg = &inst->Dst[i];
4199*bbecb9d1SAndroid Build Coastguard Worker       dinfo->dst_override_no_wm[i] = false;
4200*bbecb9d1SAndroid Build Coastguard Worker       if (dst_reg->Register.WriteMask != TGSI_WRITEMASK_XYZW) {
4201*bbecb9d1SAndroid Build Coastguard Worker          int wm_idx = 0, dbl_wm_idx = 0;
4202*bbecb9d1SAndroid Build Coastguard Worker          writemask[wm_idx++] = '.';
4203*bbecb9d1SAndroid Build Coastguard Worker          fp64_writemask[dbl_wm_idx++] = '.';
4204*bbecb9d1SAndroid Build Coastguard Worker 
4205*bbecb9d1SAndroid Build Coastguard Worker          if (dst_reg->Register.WriteMask & 0x1)
4206*bbecb9d1SAndroid Build Coastguard Worker             writemask[wm_idx++] = 'x';
4207*bbecb9d1SAndroid Build Coastguard Worker          if (dst_reg->Register.WriteMask & 0x2)
4208*bbecb9d1SAndroid Build Coastguard Worker             writemask[wm_idx++] = 'y';
4209*bbecb9d1SAndroid Build Coastguard Worker          if (dst_reg->Register.WriteMask & 0x4)
4210*bbecb9d1SAndroid Build Coastguard Worker             writemask[wm_idx++] = 'z';
4211*bbecb9d1SAndroid Build Coastguard Worker          if (dst_reg->Register.WriteMask & 0x8)
4212*bbecb9d1SAndroid Build Coastguard Worker             writemask[wm_idx++] = 'w';
4213*bbecb9d1SAndroid Build Coastguard Worker 
4214*bbecb9d1SAndroid Build Coastguard Worker          if (dtype == TGSI_TYPE_DOUBLE) {
4215*bbecb9d1SAndroid Build Coastguard Worker            if (dst_reg->Register.WriteMask & 0x3)
4216*bbecb9d1SAndroid Build Coastguard Worker              fp64_writemask[dbl_wm_idx++] = 'x';
4217*bbecb9d1SAndroid Build Coastguard Worker            if (dst_reg->Register.WriteMask & 0xc)
4218*bbecb9d1SAndroid Build Coastguard Worker              fp64_writemask[dbl_wm_idx++] = 'y';
4219*bbecb9d1SAndroid Build Coastguard Worker          }
4220*bbecb9d1SAndroid Build Coastguard Worker 
4221*bbecb9d1SAndroid Build Coastguard Worker          if (dtype == TGSI_TYPE_DOUBLE) {
4222*bbecb9d1SAndroid Build Coastguard Worker             if (dbl_wm_idx == 2)
4223*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dstconv = DOUBLE;
4224*bbecb9d1SAndroid Build Coastguard Worker             else
4225*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dstconv = DVEC2;
4226*bbecb9d1SAndroid Build Coastguard Worker          } else {
4227*bbecb9d1SAndroid Build Coastguard Worker             dinfo->dstconv = FLOAT + wm_idx - 2;
4228*bbecb9d1SAndroid Build Coastguard Worker             dinfo->udstconv = UINT + wm_idx - 2;
4229*bbecb9d1SAndroid Build Coastguard Worker             dinfo->idstconv = INT + wm_idx - 2;
4230*bbecb9d1SAndroid Build Coastguard Worker          }
4231*bbecb9d1SAndroid Build Coastguard Worker       } else {
4232*bbecb9d1SAndroid Build Coastguard Worker          if (dtype == TGSI_TYPE_DOUBLE)
4233*bbecb9d1SAndroid Build Coastguard Worker             dinfo->dstconv = DVEC2;
4234*bbecb9d1SAndroid Build Coastguard Worker          else
4235*bbecb9d1SAndroid Build Coastguard Worker             dinfo->dstconv = VEC4;
4236*bbecb9d1SAndroid Build Coastguard Worker          dinfo->udstconv = UVEC4;
4237*bbecb9d1SAndroid Build Coastguard Worker          dinfo->idstconv = IVEC4;
4238*bbecb9d1SAndroid Build Coastguard Worker       }
4239*bbecb9d1SAndroid Build Coastguard Worker 
4240*bbecb9d1SAndroid Build Coastguard Worker       if (dst_reg->Register.File == TGSI_FILE_OUTPUT) {
4241*bbecb9d1SAndroid Build Coastguard Worker          int j = find_io_index(ctx->num_outputs, ctx->outputs,
4242*bbecb9d1SAndroid Build Coastguard Worker                                dst_reg->Register.Index);
4243*bbecb9d1SAndroid Build Coastguard Worker 
4244*bbecb9d1SAndroid Build Coastguard Worker          if (j < 0)
4245*bbecb9d1SAndroid Build Coastguard Worker             return false;
4246*bbecb9d1SAndroid Build Coastguard Worker 
4247*bbecb9d1SAndroid Build Coastguard Worker          struct vrend_shader_io *output = &ctx->outputs[j];
4248*bbecb9d1SAndroid Build Coastguard Worker 
4249*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Instruction.Precise) {
4250*bbecb9d1SAndroid Build Coastguard Worker             if (!output->invariant && output->name != TGSI_SEMANTIC_CLIPVERTEX &&
4251*bbecb9d1SAndroid Build Coastguard Worker                 ctx->cfg->has_gpu_shader5) {
4252*bbecb9d1SAndroid Build Coastguard Worker                output->precise = true;
4253*bbecb9d1SAndroid Build Coastguard Worker                ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
4254*bbecb9d1SAndroid Build Coastguard Worker             }
4255*bbecb9d1SAndroid Build Coastguard Worker          }
4256*bbecb9d1SAndroid Build Coastguard Worker 
4257*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->glsl_ver_required >= 140 && output->name == TGSI_SEMANTIC_CLIPVERTEX) {
4258*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL) {
4259*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(&dst_bufs[i], "%s[gl_InvocationID]", output->glsl_name);
4260*bbecb9d1SAndroid Build Coastguard Worker             } else {
4261*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(&dst_bufs[i], "%s", ctx->is_last_vertex_stage ? "clipv_tmp" : output->glsl_name);
4262*bbecb9d1SAndroid Build Coastguard Worker             }
4263*bbecb9d1SAndroid Build Coastguard Worker          } else if (output->name == TGSI_SEMANTIC_CLIPDIST) {
4264*bbecb9d1SAndroid Build Coastguard Worker             char clip_indirect[32] = "";
4265*bbecb9d1SAndroid Build Coastguard Worker             if (output->first != output->last) {
4266*bbecb9d1SAndroid Build Coastguard Worker                if (dst_reg->Register.Indirect)
4267*bbecb9d1SAndroid Build Coastguard Worker                   snprintf(clip_indirect, sizeof(clip_indirect), "+ addr%d", dst_reg->Indirect.Index);
4268*bbecb9d1SAndroid Build Coastguard Worker                else
4269*bbecb9d1SAndroid Build Coastguard Worker                   snprintf(clip_indirect, sizeof(clip_indirect), "+ %d", dst_reg->Register.Index - output->first);
4270*bbecb9d1SAndroid Build Coastguard Worker             }
4271*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(&dst_bufs[i], "clip_dist_temp[%d %s]%s", output->sid, clip_indirect, writemask);
4272*bbecb9d1SAndroid Build Coastguard Worker          } else if (output->name == TGSI_SEMANTIC_TESSOUTER ||
4273*bbecb9d1SAndroid Build Coastguard Worker                     output->name == TGSI_SEMANTIC_TESSINNER ||
4274*bbecb9d1SAndroid Build Coastguard Worker                     output->name == TGSI_SEMANTIC_SAMPLEMASK) {
4275*bbecb9d1SAndroid Build Coastguard Worker             int idx;
4276*bbecb9d1SAndroid Build Coastguard Worker             switch (dst_reg->Register.WriteMask) {
4277*bbecb9d1SAndroid Build Coastguard Worker             case 0x1: idx = 0; break;
4278*bbecb9d1SAndroid Build Coastguard Worker             case 0x2: idx = 1; break;
4279*bbecb9d1SAndroid Build Coastguard Worker             case 0x4: idx = 2; break;
4280*bbecb9d1SAndroid Build Coastguard Worker             case 0x8: idx = 3; break;
4281*bbecb9d1SAndroid Build Coastguard Worker             default:
4282*bbecb9d1SAndroid Build Coastguard Worker                idx = 0;
4283*bbecb9d1SAndroid Build Coastguard Worker                break;
4284*bbecb9d1SAndroid Build Coastguard Worker             }
4285*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(&dst_bufs[i], "%s[%d]", output->glsl_name, idx);
4286*bbecb9d1SAndroid Build Coastguard Worker             if (output->is_int) {
4287*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dtypeprefix = FLOAT_BITS_TO_INT;
4288*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dstconv = INT;
4289*bbecb9d1SAndroid Build Coastguard Worker             }
4290*bbecb9d1SAndroid Build Coastguard Worker          } else {
4291*bbecb9d1SAndroid Build Coastguard Worker             if (output->glsl_gl_block) {
4292*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(&dst_bufs[i], "gl_out[%s].%s%s",
4293*bbecb9d1SAndroid Build Coastguard Worker                           ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ? "gl_InvocationID" : "0",
4294*bbecb9d1SAndroid Build Coastguard Worker                           output->glsl_name,
4295*bbecb9d1SAndroid Build Coastguard Worker                           output->override_no_wm ? "" : writemask);
4296*bbecb9d1SAndroid Build Coastguard Worker             } else if (output->name == TGSI_SEMANTIC_GENERIC) {
4297*bbecb9d1SAndroid Build Coastguard Worker                struct vrend_shader_io *io = ctx->generic_ios.output_range.used ? &ctx->generic_ios.output_range.io : output;
4298*bbecb9d1SAndroid Build Coastguard Worker                get_destination_info_generic(ctx, dst_reg, io, writemask, &dst_bufs[i]);
4299*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dst_override_no_wm[i] = output->override_no_wm;
4300*bbecb9d1SAndroid Build Coastguard Worker             } else if (output->name == TGSI_SEMANTIC_TEXCOORD) {
4301*bbecb9d1SAndroid Build Coastguard Worker                get_destination_info_generic(ctx, dst_reg, output, writemask, &dst_bufs[i]);
4302*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dst_override_no_wm[i] = output->override_no_wm;
4303*bbecb9d1SAndroid Build Coastguard Worker             } else if (output->name == TGSI_SEMANTIC_PATCH) {
4304*bbecb9d1SAndroid Build Coastguard Worker                struct vrend_shader_io *io = ctx->patch_ios.output_range.used ? &ctx->patch_ios.output_range.io : output;
4305*bbecb9d1SAndroid Build Coastguard Worker                char reswizzled[6] = "";
4306*bbecb9d1SAndroid Build Coastguard Worker                const char *wm = reswizzle_dest(io, dst_reg, reswizzled, writemask);
4307*bbecb9d1SAndroid Build Coastguard Worker                strbuf_reset(&dst_bufs[i]);
4308*bbecb9d1SAndroid Build Coastguard Worker                vrend_shader_write_io_as_dst(&dst_bufs[i], "", io, dst_reg, decl_plain);
4309*bbecb9d1SAndroid Build Coastguard Worker                if (!output->override_no_wm)
4310*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_appendf(&dst_bufs[i], "%s", wm);
4311*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dst_override_no_wm[i] = output->override_no_wm;
4312*bbecb9d1SAndroid Build Coastguard Worker             } else {
4313*bbecb9d1SAndroid Build Coastguard Worker                if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL) {
4314*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(&dst_bufs[i], "%s[gl_InvocationID]%s", output->glsl_name, output->override_no_wm ? "" : writemask);
4315*bbecb9d1SAndroid Build Coastguard Worker                } else {
4316*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(&dst_bufs[i], "%s%s", output->glsl_name, output->override_no_wm ? "" : writemask);
4317*bbecb9d1SAndroid Build Coastguard Worker                }
4318*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dst_override_no_wm[i] = output->override_no_wm;
4319*bbecb9d1SAndroid Build Coastguard Worker             }
4320*bbecb9d1SAndroid Build Coastguard Worker             if (output->is_int) {
4321*bbecb9d1SAndroid Build Coastguard Worker                if (dinfo->dtypeprefix == TYPE_CONVERSION_NONE)
4322*bbecb9d1SAndroid Build Coastguard Worker                   dinfo->dtypeprefix = FLOAT_BITS_TO_INT;
4323*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dstconv = INT;
4324*bbecb9d1SAndroid Build Coastguard Worker             }
4325*bbecb9d1SAndroid Build Coastguard Worker             else if (output->type == VEC_UINT) {
4326*bbecb9d1SAndroid Build Coastguard Worker                if (dinfo->dtypeprefix == TYPE_CONVERSION_NONE)
4327*bbecb9d1SAndroid Build Coastguard Worker                   dinfo->dtypeprefix = FLOAT_BITS_TO_UINT;
4328*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dstconv = dinfo->udstconv;
4329*bbecb9d1SAndroid Build Coastguard Worker             }
4330*bbecb9d1SAndroid Build Coastguard Worker             else if (output->type == VEC_INT) {
4331*bbecb9d1SAndroid Build Coastguard Worker                if (dinfo->dtypeprefix == TYPE_CONVERSION_NONE)
4332*bbecb9d1SAndroid Build Coastguard Worker                   dinfo->dtypeprefix = FLOAT_BITS_TO_INT;
4333*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dstconv = dinfo->idstconv;
4334*bbecb9d1SAndroid Build Coastguard Worker             }
4335*bbecb9d1SAndroid Build Coastguard Worker             if (output->name == TGSI_SEMANTIC_PSIZE) {
4336*bbecb9d1SAndroid Build Coastguard Worker                dinfo->dstconv = FLOAT;
4337*bbecb9d1SAndroid Build Coastguard Worker                break;
4338*bbecb9d1SAndroid Build Coastguard Worker             }
4339*bbecb9d1SAndroid Build Coastguard Worker          }
4340*bbecb9d1SAndroid Build Coastguard Worker       }
4341*bbecb9d1SAndroid Build Coastguard Worker       else if (dst_reg->Register.File == TGSI_FILE_TEMPORARY) {
4342*bbecb9d1SAndroid Build Coastguard Worker          char temp_buf[64];
4343*bbecb9d1SAndroid Build Coastguard Worker          get_temp(ctx, dst_reg->Register.Indirect, 0, dst_reg->Register.Index,
4344*bbecb9d1SAndroid Build Coastguard Worker                   temp_buf, &ctx->require_dummy_value);
4345*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&dst_bufs[i], "%s%s", temp_buf, writemask);
4346*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Instruction.Precise) {
4347*bbecb9d1SAndroid Build Coastguard Worker             struct vrend_temp_range *range = find_temp_range(ctx, dst_reg->Register.Index);
4348*bbecb9d1SAndroid Build Coastguard Worker             if (range && ctx->cfg->has_gpu_shader5) {
4349*bbecb9d1SAndroid Build Coastguard Worker                range->precise_result = true;
4350*bbecb9d1SAndroid Build Coastguard Worker                ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
4351*bbecb9d1SAndroid Build Coastguard Worker             }
4352*bbecb9d1SAndroid Build Coastguard Worker          }
4353*bbecb9d1SAndroid Build Coastguard Worker       }
4354*bbecb9d1SAndroid Build Coastguard Worker       else if (dst_reg->Register.File == TGSI_FILE_IMAGE) {
4355*bbecb9d1SAndroid Build Coastguard Worker          const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4356*bbecb9d1SAndroid Build Coastguard Worker 	 if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
4357*bbecb9d1SAndroid Build Coastguard Worker             int basearrayidx = lookup_image_array(ctx, dst_reg->Register.Index);
4358*bbecb9d1SAndroid Build Coastguard Worker             if (dst_reg->Register.Indirect) {
4359*bbecb9d1SAndroid Build Coastguard Worker                assert(dst_reg->Indirect.File == TGSI_FILE_ADDRESS);
4360*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(&dst_bufs[i], "%simg%d[addr%d + %d]", cname, basearrayidx, dst_reg->Indirect.Index, dst_reg->Register.Index - basearrayidx);
4361*bbecb9d1SAndroid Build Coastguard Worker             } else
4362*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(&dst_bufs[i], "%simg%d[%d]", cname, basearrayidx, dst_reg->Register.Index - basearrayidx);
4363*bbecb9d1SAndroid Build Coastguard Worker          } else
4364*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(&dst_bufs[i], "%simg%d", cname, dst_reg->Register.Index);
4365*bbecb9d1SAndroid Build Coastguard Worker          dinfo->dest_index = dst_reg->Register.Index;
4366*bbecb9d1SAndroid Build Coastguard Worker       } else if (dst_reg->Register.File == TGSI_FILE_BUFFER) {
4367*bbecb9d1SAndroid Build Coastguard Worker          const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4368*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
4369*bbecb9d1SAndroid Build Coastguard Worker             bool atomic_ssbo = ctx->ssbo_atomic_mask & (1 << dst_reg->Register.Index);
4370*bbecb9d1SAndroid Build Coastguard Worker             const char *atomic_str = atomic_ssbo ? "atomic" : "";
4371*bbecb9d1SAndroid Build Coastguard Worker             int base = atomic_ssbo ? ctx->ssbo_atomic_array_base : ctx->ssbo_array_base;
4372*bbecb9d1SAndroid Build Coastguard Worker             if (dst_reg->Register.Indirect) {
4373*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(&dst_bufs[i], "%sssboarr%s[addr%d+%d].%sssbocontents%d", cname, atomic_str, dst_reg->Indirect.Index, dst_reg->Register.Index - base, cname, base);
4374*bbecb9d1SAndroid Build Coastguard Worker             } else
4375*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(&dst_bufs[i], "%sssboarr%s[%d].%sssbocontents%d", cname, atomic_str, dst_reg->Register.Index - base, cname, base);
4376*bbecb9d1SAndroid Build Coastguard Worker          } else
4377*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(&dst_bufs[i], "%sssbocontents%d", cname, dst_reg->Register.Index);
4378*bbecb9d1SAndroid Build Coastguard Worker          dinfo->dest_index = dst_reg->Register.Index;
4379*bbecb9d1SAndroid Build Coastguard Worker       } else if (dst_reg->Register.File == TGSI_FILE_MEMORY) {
4380*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&dst_bufs[i], "values");
4381*bbecb9d1SAndroid Build Coastguard Worker       } else if (dst_reg->Register.File == TGSI_FILE_ADDRESS) {
4382*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&dst_bufs[i], "addr%d", dst_reg->Register.Index);
4383*bbecb9d1SAndroid Build Coastguard Worker       }
4384*bbecb9d1SAndroid Build Coastguard Worker 
4385*bbecb9d1SAndroid Build Coastguard Worker       if (dtype == TGSI_TYPE_DOUBLE) {
4386*bbecb9d1SAndroid Build Coastguard Worker          strcpy(fp64_dsts[i], dst_bufs[i].buf);
4387*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(&dst_bufs[i], "fp64_dst[%d]%s", i, fp64_writemask);
4388*bbecb9d1SAndroid Build Coastguard Worker          writemask[0] = 0;
4389*bbecb9d1SAndroid Build Coastguard Worker       }
4390*bbecb9d1SAndroid Build Coastguard Worker 
4391*bbecb9d1SAndroid Build Coastguard Worker    }
4392*bbecb9d1SAndroid Build Coastguard Worker 
4393*bbecb9d1SAndroid Build Coastguard Worker    return true;
4394*bbecb9d1SAndroid Build Coastguard Worker }
4395*bbecb9d1SAndroid Build Coastguard Worker 
shift_swizzles(const struct vrend_shader_io * io,const struct tgsi_full_src_register * src,int swz_offset,char * swizzle_shifted,const char * swizzle)4396*bbecb9d1SAndroid Build Coastguard Worker static const char *shift_swizzles(const struct vrend_shader_io *io, const struct tgsi_full_src_register *src,
4397*bbecb9d1SAndroid Build Coastguard Worker                                   int swz_offset, char *swizzle_shifted, const char *swizzle)
4398*bbecb9d1SAndroid Build Coastguard Worker {
4399*bbecb9d1SAndroid Build Coastguard Worker    if (io->usage_mask != 0xf && swizzle[0]) {
4400*bbecb9d1SAndroid Build Coastguard Worker       if (io->num_components > 1) {
4401*bbecb9d1SAndroid Build Coastguard Worker          swizzle_shifted[swz_offset++] = '.';
4402*bbecb9d1SAndroid Build Coastguard Worker          for (int i = 0; i < 4; ++i) {
4403*bbecb9d1SAndroid Build Coastguard Worker             switch (i) {
4404*bbecb9d1SAndroid Build Coastguard Worker             case 0: swizzle_shifted[swz_offset++] = get_swiz_char(src->Register.SwizzleX);
4405*bbecb9d1SAndroid Build Coastguard Worker                break;
4406*bbecb9d1SAndroid Build Coastguard Worker             case 1: swizzle_shifted[swz_offset++] = get_swiz_char(src->Register.SwizzleY);
4407*bbecb9d1SAndroid Build Coastguard Worker                break;
4408*bbecb9d1SAndroid Build Coastguard Worker             case 2: swizzle_shifted[swz_offset++] = src->Register.SwizzleZ < io->num_components ?
4409*bbecb9d1SAndroid Build Coastguard Worker                                                        get_swiz_char(src->Register.SwizzleZ) : 'x';
4410*bbecb9d1SAndroid Build Coastguard Worker                break;
4411*bbecb9d1SAndroid Build Coastguard Worker             case 3: swizzle_shifted[swz_offset++] = src->Register.SwizzleW < io->num_components ?
4412*bbecb9d1SAndroid Build Coastguard Worker                                                        get_swiz_char(src->Register.SwizzleW) : 'x';
4413*bbecb9d1SAndroid Build Coastguard Worker             }
4414*bbecb9d1SAndroid Build Coastguard Worker          }
4415*bbecb9d1SAndroid Build Coastguard Worker          swizzle_shifted[swz_offset] = 0;
4416*bbecb9d1SAndroid Build Coastguard Worker       }
4417*bbecb9d1SAndroid Build Coastguard Worker       swizzle = swizzle_shifted;
4418*bbecb9d1SAndroid Build Coastguard Worker    }
4419*bbecb9d1SAndroid Build Coastguard Worker    return swizzle;
4420*bbecb9d1SAndroid Build Coastguard Worker }
4421*bbecb9d1SAndroid Build Coastguard Worker 
get_source_info_generic(const struct dump_ctx * ctx,enum io_type iot,enum vrend_type_qualifier srcstypeprefix,const char * prefix,const struct tgsi_full_src_register * src,const struct vrend_shader_io * io,const char * arrayname,const char * swizzle,struct vrend_strbuf * result)4422*bbecb9d1SAndroid Build Coastguard Worker static void get_source_info_generic(const struct dump_ctx *ctx,
4423*bbecb9d1SAndroid Build Coastguard Worker                                     enum io_type iot,
4424*bbecb9d1SAndroid Build Coastguard Worker                                     enum vrend_type_qualifier srcstypeprefix,
4425*bbecb9d1SAndroid Build Coastguard Worker                                     const char *prefix,
4426*bbecb9d1SAndroid Build Coastguard Worker                                     const struct tgsi_full_src_register *src,
4427*bbecb9d1SAndroid Build Coastguard Worker                                     const struct vrend_shader_io *io,
4428*bbecb9d1SAndroid Build Coastguard Worker                                     const  char *arrayname,
4429*bbecb9d1SAndroid Build Coastguard Worker                                     const char *swizzle,
4430*bbecb9d1SAndroid Build Coastguard Worker                                     struct vrend_strbuf *result)
4431*bbecb9d1SAndroid Build Coastguard Worker {
4432*bbecb9d1SAndroid Build Coastguard Worker    int swz_offset = 0;
4433*bbecb9d1SAndroid Build Coastguard Worker    char swizzle_shifted[6] = "";
4434*bbecb9d1SAndroid Build Coastguard Worker    char outvarname[64];
4435*bbecb9d1SAndroid Build Coastguard Worker 
4436*bbecb9d1SAndroid Build Coastguard Worker    if (swizzle[0] == ')') {
4437*bbecb9d1SAndroid Build Coastguard Worker       swizzle_shifted[swz_offset++] = ')';
4438*bbecb9d1SAndroid Build Coastguard Worker       swizzle_shifted[swz_offset] = 0;
4439*bbecb9d1SAndroid Build Coastguard Worker    }
4440*bbecb9d1SAndroid Build Coastguard Worker 
4441*bbecb9d1SAndroid Build Coastguard Worker    /* This IO element is not using all vector elements, so we have to shift the swizzle names */
4442*bbecb9d1SAndroid Build Coastguard Worker    swizzle = shift_swizzles(io, src, swz_offset, swizzle_shifted, swizzle);
4443*bbecb9d1SAndroid Build Coastguard Worker 
4444*bbecb9d1SAndroid Build Coastguard Worker    strbuf_fmt(result, "%s(%s", get_string(srcstypeprefix), prefix);
4445*bbecb9d1SAndroid Build Coastguard Worker 
4446*bbecb9d1SAndroid Build Coastguard Worker    enum io_decl_type decl_type = decl_plain;
4447*bbecb9d1SAndroid Build Coastguard Worker 
4448*bbecb9d1SAndroid Build Coastguard Worker    if ((io->first != io->last || io->overlapping_array) &&
4449*bbecb9d1SAndroid Build Coastguard Worker        prefer_generic_io_block(ctx, iot)) {
4450*bbecb9d1SAndroid Build Coastguard Worker 
4451*bbecb9d1SAndroid Build Coastguard Worker       const struct vrend_shader_io *array = io->overlapping_array ?
4452*bbecb9d1SAndroid Build Coastguard Worker             io->overlapping_array : io;
4453*bbecb9d1SAndroid Build Coastguard Worker 
4454*bbecb9d1SAndroid Build Coastguard Worker       const char *stage_prefix = iot == io_in ?
4455*bbecb9d1SAndroid Build Coastguard Worker                                     get_stage_input_name_prefix(ctx, ctx->prog_type) :
4456*bbecb9d1SAndroid Build Coastguard Worker                                     get_stage_output_name_prefix(ctx->prog_type);
4457*bbecb9d1SAndroid Build Coastguard Worker       get_blockvarname(outvarname, stage_prefix, array, arrayname);
4458*bbecb9d1SAndroid Build Coastguard Worker       arrayname = outvarname;
4459*bbecb9d1SAndroid Build Coastguard Worker       decl_type = decl_block;
4460*bbecb9d1SAndroid Build Coastguard Worker    }
4461*bbecb9d1SAndroid Build Coastguard Worker 
4462*bbecb9d1SAndroid Build Coastguard Worker    vrend_shader_write_io_as_src(result, arrayname, io, src, decl_type);
4463*bbecb9d1SAndroid Build Coastguard Worker    strbuf_appendf(result, "%s)", io->is_int ? "" : swizzle);
4464*bbecb9d1SAndroid Build Coastguard Worker }
4465*bbecb9d1SAndroid Build Coastguard Worker 
get_source_info_patch(enum vrend_type_qualifier srcstypeprefix,const char * prefix,const struct tgsi_full_src_register * src,const struct vrend_shader_io * io,const char * arrayname,const char * swizzle,struct vrend_strbuf * result)4466*bbecb9d1SAndroid Build Coastguard Worker static void get_source_info_patch(enum vrend_type_qualifier srcstypeprefix,
4467*bbecb9d1SAndroid Build Coastguard Worker                                   const char *prefix,
4468*bbecb9d1SAndroid Build Coastguard Worker                                   const struct tgsi_full_src_register *src,
4469*bbecb9d1SAndroid Build Coastguard Worker                                   const struct vrend_shader_io *io,
4470*bbecb9d1SAndroid Build Coastguard Worker                                   const  char *arrayname,
4471*bbecb9d1SAndroid Build Coastguard Worker                                   const char *swizzle,
4472*bbecb9d1SAndroid Build Coastguard Worker                                   struct vrend_strbuf *result)
4473*bbecb9d1SAndroid Build Coastguard Worker {
4474*bbecb9d1SAndroid Build Coastguard Worker    int swz_offset = 0;
4475*bbecb9d1SAndroid Build Coastguard Worker    char swizzle_shifted[7] = "";
4476*bbecb9d1SAndroid Build Coastguard Worker    if (swizzle[0] == ')') {
4477*bbecb9d1SAndroid Build Coastguard Worker       swizzle_shifted[swz_offset++] = ')';
4478*bbecb9d1SAndroid Build Coastguard Worker       swizzle_shifted[swz_offset] = 0;
4479*bbecb9d1SAndroid Build Coastguard Worker    }
4480*bbecb9d1SAndroid Build Coastguard Worker 
4481*bbecb9d1SAndroid Build Coastguard Worker    swizzle = shift_swizzles(io, src, swz_offset, swizzle_shifted, swizzle);
4482*bbecb9d1SAndroid Build Coastguard Worker 
4483*bbecb9d1SAndroid Build Coastguard Worker    strbuf_fmt(result, "%s(%s", get_string(srcstypeprefix), prefix);
4484*bbecb9d1SAndroid Build Coastguard Worker    vrend_shader_write_io_as_src(result, io->last == io->first ? arrayname : "", io, src, decl_plain);
4485*bbecb9d1SAndroid Build Coastguard Worker    strbuf_appendf(result, "%s)", io->is_int ? "" : swizzle);
4486*bbecb9d1SAndroid Build Coastguard Worker }
4487*bbecb9d1SAndroid Build Coastguard Worker 
get_tesslevel_as_source(struct vrend_strbuf * src_buf,const char * prefix,const char * name,const struct tgsi_src_register * reg)4488*bbecb9d1SAndroid Build Coastguard Worker static void get_tesslevel_as_source(struct vrend_strbuf *src_buf, const char *prefix,
4489*bbecb9d1SAndroid Build Coastguard Worker                                     const char *name, const struct tgsi_src_register *reg)
4490*bbecb9d1SAndroid Build Coastguard Worker {
4491*bbecb9d1SAndroid Build Coastguard Worker    strbuf_fmt(src_buf, "%s(vec4(%s[%d], %s[%d], %s[%d], %s[%d]))",
4492*bbecb9d1SAndroid Build Coastguard Worker               prefix,
4493*bbecb9d1SAndroid Build Coastguard Worker               name, reg->SwizzleX,
4494*bbecb9d1SAndroid Build Coastguard Worker               name, reg->SwizzleY,
4495*bbecb9d1SAndroid Build Coastguard Worker               name, reg->SwizzleZ,
4496*bbecb9d1SAndroid Build Coastguard Worker               name, reg->SwizzleW);
4497*bbecb9d1SAndroid Build Coastguard Worker }
4498*bbecb9d1SAndroid Build Coastguard Worker 
get_source_swizzle(const struct tgsi_full_src_register * src,char swizzle[8])4499*bbecb9d1SAndroid Build Coastguard Worker static void get_source_swizzle(const struct tgsi_full_src_register *src, char swizzle[8])
4500*bbecb9d1SAndroid Build Coastguard Worker {
4501*bbecb9d1SAndroid Build Coastguard Worker    if (src->Register.SwizzleX != TGSI_SWIZZLE_X ||
4502*bbecb9d1SAndroid Build Coastguard Worker        src->Register.SwizzleY != TGSI_SWIZZLE_Y ||
4503*bbecb9d1SAndroid Build Coastguard Worker        src->Register.SwizzleZ != TGSI_SWIZZLE_Z ||
4504*bbecb9d1SAndroid Build Coastguard Worker        src->Register.SwizzleW != TGSI_SWIZZLE_W) {
4505*bbecb9d1SAndroid Build Coastguard Worker       *swizzle++ = '.';
4506*bbecb9d1SAndroid Build Coastguard Worker       *swizzle++ = get_swiz_char(src->Register.SwizzleX);
4507*bbecb9d1SAndroid Build Coastguard Worker       *swizzle++ = get_swiz_char(src->Register.SwizzleY);
4508*bbecb9d1SAndroid Build Coastguard Worker       *swizzle++ = get_swiz_char(src->Register.SwizzleZ);
4509*bbecb9d1SAndroid Build Coastguard Worker       *swizzle++ = get_swiz_char(src->Register.SwizzleW);
4510*bbecb9d1SAndroid Build Coastguard Worker    }
4511*bbecb9d1SAndroid Build Coastguard Worker 
4512*bbecb9d1SAndroid Build Coastguard Worker    *swizzle++ = 0;
4513*bbecb9d1SAndroid Build Coastguard Worker }
4514*bbecb9d1SAndroid Build Coastguard Worker 
4515*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
4516*bbecb9d1SAndroid Build Coastguard Worker static bool
get_source_info(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,struct source_info * sinfo,struct vrend_strbuf srcs[4],char src_swizzle0[16])4517*bbecb9d1SAndroid Build Coastguard Worker get_source_info(struct dump_ctx *ctx,
4518*bbecb9d1SAndroid Build Coastguard Worker                 const struct tgsi_full_instruction *inst,
4519*bbecb9d1SAndroid Build Coastguard Worker                 struct source_info *sinfo,
4520*bbecb9d1SAndroid Build Coastguard Worker                 struct vrend_strbuf srcs[4], char src_swizzle0[16])
4521*bbecb9d1SAndroid Build Coastguard Worker {
4522*bbecb9d1SAndroid Build Coastguard Worker    bool stprefix = false;
4523*bbecb9d1SAndroid Build Coastguard Worker 
4524*bbecb9d1SAndroid Build Coastguard Worker    enum vrend_type_qualifier stypeprefix = TYPE_CONVERSION_NONE;
4525*bbecb9d1SAndroid Build Coastguard Worker    enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(inst->Instruction.Opcode);
4526*bbecb9d1SAndroid Build Coastguard Worker 
4527*bbecb9d1SAndroid Build Coastguard Worker    if (stype == TGSI_TYPE_SIGNED || stype == TGSI_TYPE_UNSIGNED)
4528*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_INTS;
4529*bbecb9d1SAndroid Build Coastguard Worker    if (stype == TGSI_TYPE_DOUBLE)
4530*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_INTS | SHADER_REQ_FP64;
4531*bbecb9d1SAndroid Build Coastguard Worker 
4532*bbecb9d1SAndroid Build Coastguard Worker    switch (stype) {
4533*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TYPE_DOUBLE:
4534*bbecb9d1SAndroid Build Coastguard Worker       stypeprefix = FLOAT_BITS_TO_UINT;
4535*bbecb9d1SAndroid Build Coastguard Worker       sinfo->svec4 = DVEC2;
4536*bbecb9d1SAndroid Build Coastguard Worker       stprefix = true;
4537*bbecb9d1SAndroid Build Coastguard Worker       break;
4538*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TYPE_UNSIGNED:
4539*bbecb9d1SAndroid Build Coastguard Worker       stypeprefix = FLOAT_BITS_TO_UINT;
4540*bbecb9d1SAndroid Build Coastguard Worker       sinfo->svec4 = UVEC4;
4541*bbecb9d1SAndroid Build Coastguard Worker       stprefix = true;
4542*bbecb9d1SAndroid Build Coastguard Worker       break;
4543*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TYPE_SIGNED:
4544*bbecb9d1SAndroid Build Coastguard Worker       stypeprefix = FLOAT_BITS_TO_INT;
4545*bbecb9d1SAndroid Build Coastguard Worker       sinfo->svec4 = IVEC4;
4546*bbecb9d1SAndroid Build Coastguard Worker       stprefix = true;
4547*bbecb9d1SAndroid Build Coastguard Worker       break;
4548*bbecb9d1SAndroid Build Coastguard Worker    default:
4549*bbecb9d1SAndroid Build Coastguard Worker       break;
4550*bbecb9d1SAndroid Build Coastguard Worker    }
4551*bbecb9d1SAndroid Build Coastguard Worker 
4552*bbecb9d1SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < inst->Instruction.NumSrcRegs; i++) {
4553*bbecb9d1SAndroid Build Coastguard Worker       const struct tgsi_full_src_register *src = &inst->Src[i];
4554*bbecb9d1SAndroid Build Coastguard Worker       struct vrend_strbuf *src_buf = &srcs[i];
4555*bbecb9d1SAndroid Build Coastguard Worker       char swizzle[16] = "";
4556*bbecb9d1SAndroid Build Coastguard Worker       char *swizzle_writer = swizzle;
4557*bbecb9d1SAndroid Build Coastguard Worker       char prefix[6] = "";
4558*bbecb9d1SAndroid Build Coastguard Worker       char arrayname[16] = "";
4559*bbecb9d1SAndroid Build Coastguard Worker       char fp64_src[255];
4560*bbecb9d1SAndroid Build Coastguard Worker       int swz_idx = 0, pre_idx = 0;
4561*bbecb9d1SAndroid Build Coastguard Worker       boolean isfloatabsolute = src->Register.Absolute && stype != TGSI_TYPE_DOUBLE;
4562*bbecb9d1SAndroid Build Coastguard Worker 
4563*bbecb9d1SAndroid Build Coastguard Worker       sinfo->override_no_wm[i] = false;
4564*bbecb9d1SAndroid Build Coastguard Worker       sinfo->override_no_cast[i] = false;
4565*bbecb9d1SAndroid Build Coastguard Worker 
4566*bbecb9d1SAndroid Build Coastguard Worker       if (src->Register.Negate)
4567*bbecb9d1SAndroid Build Coastguard Worker          prefix[pre_idx++] = '-';
4568*bbecb9d1SAndroid Build Coastguard Worker       if (isfloatabsolute)
4569*bbecb9d1SAndroid Build Coastguard Worker          strcpy(&prefix[pre_idx++], "abs(");
4570*bbecb9d1SAndroid Build Coastguard Worker 
4571*bbecb9d1SAndroid Build Coastguard Worker       if (src->Register.Dimension) {
4572*bbecb9d1SAndroid Build Coastguard Worker          if (src->Dimension.Indirect) {
4573*bbecb9d1SAndroid Build Coastguard Worker             assert(src->DimIndirect.File == TGSI_FILE_ADDRESS);
4574*bbecb9d1SAndroid Build Coastguard Worker             sprintf(arrayname, "[addr%d]", src->DimIndirect.Index);
4575*bbecb9d1SAndroid Build Coastguard Worker          } else
4576*bbecb9d1SAndroid Build Coastguard Worker             sprintf(arrayname, "[%d]", src->Dimension.Index);
4577*bbecb9d1SAndroid Build Coastguard Worker       }
4578*bbecb9d1SAndroid Build Coastguard Worker 
4579*bbecb9d1SAndroid Build Coastguard Worker       /* These instructions don't support swizzles in the first parameter
4580*bbecb9d1SAndroid Build Coastguard Worker        * pass the swizzle to the caller instead */
4581*bbecb9d1SAndroid Build Coastguard Worker       if ((inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE ||
4582*bbecb9d1SAndroid Build Coastguard Worker            inst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET ||
4583*bbecb9d1SAndroid Build Coastguard Worker            inst->Instruction.Opcode == TGSI_OPCODE_INTERP_CENTROID) &&
4584*bbecb9d1SAndroid Build Coastguard Worker           i == 0) {
4585*bbecb9d1SAndroid Build Coastguard Worker          swizzle_writer = src_swizzle0;
4586*bbecb9d1SAndroid Build Coastguard Worker       }
4587*bbecb9d1SAndroid Build Coastguard Worker 
4588*bbecb9d1SAndroid Build Coastguard Worker       if (isfloatabsolute)
4589*bbecb9d1SAndroid Build Coastguard Worker          swizzle_writer[swz_idx++] = ')';
4590*bbecb9d1SAndroid Build Coastguard Worker 
4591*bbecb9d1SAndroid Build Coastguard Worker       get_source_swizzle(src, swizzle_writer + swz_idx);
4592*bbecb9d1SAndroid Build Coastguard Worker 
4593*bbecb9d1SAndroid Build Coastguard Worker       if (src->Register.File == TGSI_FILE_INPUT) {
4594*bbecb9d1SAndroid Build Coastguard Worker          int j = find_io_index(ctx->num_inputs, ctx->inputs, src->Register.Index);
4595*bbecb9d1SAndroid Build Coastguard Worker          if (j < 0)
4596*bbecb9d1SAndroid Build Coastguard Worker             return false;
4597*bbecb9d1SAndroid Build Coastguard Worker 
4598*bbecb9d1SAndroid Build Coastguard Worker          struct vrend_shader_io *input = &ctx->inputs[j];
4599*bbecb9d1SAndroid Build Coastguard Worker 
4600*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->prog_type == TGSI_PROCESSOR_VERTEX) {
4601*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->key->vs.attrib_zyxw_bitmask & (1 << input->first)) {
4602*bbecb9d1SAndroid Build Coastguard Worker                swizzle_writer[swz_idx++] = '.';
4603*bbecb9d1SAndroid Build Coastguard Worker                swizzle_writer[swz_idx++] = 'z';
4604*bbecb9d1SAndroid Build Coastguard Worker                swizzle_writer[swz_idx++] = 'y';
4605*bbecb9d1SAndroid Build Coastguard Worker                swizzle_writer[swz_idx++] = 'x';
4606*bbecb9d1SAndroid Build Coastguard Worker                swizzle_writer[swz_idx++] = 'w';
4607*bbecb9d1SAndroid Build Coastguard Worker             }
4608*bbecb9d1SAndroid Build Coastguard Worker             get_source_swizzle(src, swizzle_writer + swz_idx);
4609*bbecb9d1SAndroid Build Coastguard Worker          }
4610*bbecb9d1SAndroid Build Coastguard Worker 
4611*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT &&
4612*bbecb9d1SAndroid Build Coastguard Worker              ctx->key->color_two_side && input->name == TGSI_SEMANTIC_COLOR)
4613*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(src_buf, "%s(%s%s%d%s%s)", get_string(stypeprefix), prefix, "realcolor", input->sid, arrayname, swizzle);
4614*bbecb9d1SAndroid Build Coastguard Worker          else if (input->glsl_gl_block) {
4615*bbecb9d1SAndroid Build Coastguard Worker             /* GS input clipdist requires a conversion */
4616*bbecb9d1SAndroid Build Coastguard Worker             if (input->name == TGSI_SEMANTIC_CLIPDIST) {
4617*bbecb9d1SAndroid Build Coastguard Worker                create_swizzled_clipdist(ctx, src_buf, src, j, true, get_string(stypeprefix), prefix, arrayname, input->first);
4618*bbecb9d1SAndroid Build Coastguard Worker             } else {
4619*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "%s(vec4(%sgl_in%s.%s)%s)", get_string(stypeprefix), prefix, arrayname, input->glsl_name, swizzle);
4620*bbecb9d1SAndroid Build Coastguard Worker             }
4621*bbecb9d1SAndroid Build Coastguard Worker          }
4622*bbecb9d1SAndroid Build Coastguard Worker          else if (input->name == TGSI_SEMANTIC_PRIMID)
4623*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(src_buf, "%s(vec4(intBitsToFloat(%s)))", get_string(stypeprefix), input->glsl_name);
4624*bbecb9d1SAndroid Build Coastguard Worker          else if (input->name == TGSI_SEMANTIC_FACE)
4625*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(src_buf, "%s(%s ? 1.0 : -1.0)", get_string(stypeprefix), input->glsl_name);
4626*bbecb9d1SAndroid Build Coastguard Worker          else if (input->name == TGSI_SEMANTIC_CLIPDIST) {
4627*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT)
4628*bbecb9d1SAndroid Build Coastguard Worker                load_clipdist_fs(ctx, src_buf, src, j, get_string(stypeprefix), input->first);
4629*bbecb9d1SAndroid Build Coastguard Worker             else
4630*bbecb9d1SAndroid Build Coastguard Worker                create_swizzled_clipdist(ctx, src_buf, src, j, false, get_string(stypeprefix), prefix, arrayname, input->first);
4631*bbecb9d1SAndroid Build Coastguard Worker          }  else if (input->name == TGSI_SEMANTIC_TESSOUTER ||
4632*bbecb9d1SAndroid Build Coastguard Worker                      input->name == TGSI_SEMANTIC_TESSINNER) {
4633*bbecb9d1SAndroid Build Coastguard Worker             get_tesslevel_as_source(src_buf, prefix, input->glsl_name, &src->Register);
4634*bbecb9d1SAndroid Build Coastguard Worker          } else {
4635*bbecb9d1SAndroid Build Coastguard Worker             enum vrend_type_qualifier srcstypeprefix = stypeprefix;
4636*bbecb9d1SAndroid Build Coastguard Worker             if (input->type != VEC_FLOAT) {
4637*bbecb9d1SAndroid Build Coastguard Worker                if (stype == TGSI_TYPE_UNSIGNED)
4638*bbecb9d1SAndroid Build Coastguard Worker                   srcstypeprefix = UVEC4;
4639*bbecb9d1SAndroid Build Coastguard Worker                else if (stype == TGSI_TYPE_SIGNED)
4640*bbecb9d1SAndroid Build Coastguard Worker                   srcstypeprefix = IVEC4;
4641*bbecb9d1SAndroid Build Coastguard Worker                else if (input->type == VEC_INT)
4642*bbecb9d1SAndroid Build Coastguard Worker                   srcstypeprefix = INT_BITS_TO_FLOAT;
4643*bbecb9d1SAndroid Build Coastguard Worker                else // input->type == VEC_UINT
4644*bbecb9d1SAndroid Build Coastguard Worker                   srcstypeprefix = UINT_BITS_TO_FLOAT;
4645*bbecb9d1SAndroid Build Coastguard Worker             }
4646*bbecb9d1SAndroid Build Coastguard Worker 
4647*bbecb9d1SAndroid Build Coastguard Worker             if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1) {
4648*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "floatBitsToInt(%s%s%s%s)", prefix, input->glsl_name, arrayname, swizzle);
4649*bbecb9d1SAndroid Build Coastguard Worker             } else if (input->name == TGSI_SEMANTIC_GENERIC) {
4650*bbecb9d1SAndroid Build Coastguard Worker                get_source_info_generic(ctx, io_in, srcstypeprefix, prefix, src,
4651*bbecb9d1SAndroid Build Coastguard Worker                                        &ctx->inputs[j], arrayname, swizzle, src_buf);
4652*bbecb9d1SAndroid Build Coastguard Worker             } else if (input->name == TGSI_SEMANTIC_TEXCOORD) {
4653*bbecb9d1SAndroid Build Coastguard Worker                get_source_info_generic(ctx, io_in, srcstypeprefix, prefix, src,
4654*bbecb9d1SAndroid Build Coastguard Worker                                        &ctx->inputs[j], arrayname, swizzle, src_buf);
4655*bbecb9d1SAndroid Build Coastguard Worker             } else if (input->name == TGSI_SEMANTIC_PATCH) {
4656*bbecb9d1SAndroid Build Coastguard Worker                get_source_info_patch(srcstypeprefix, prefix, src,
4657*bbecb9d1SAndroid Build Coastguard Worker                                      &ctx->inputs[j], arrayname, swizzle, src_buf);
4658*bbecb9d1SAndroid Build Coastguard Worker             } else if (input->name == TGSI_SEMANTIC_POSITION && ctx->prog_type == TGSI_PROCESSOR_VERTEX &&
4659*bbecb9d1SAndroid Build Coastguard Worker                        input->first != input->last) {
4660*bbecb9d1SAndroid Build Coastguard Worker                if (src->Register.Indirect)
4661*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "%s(%s%s%s[addr%d + %d]%s)", get_string(srcstypeprefix), prefix, input->glsl_name, arrayname,
4662*bbecb9d1SAndroid Build Coastguard Worker                              src->Indirect.Index, src->Register.Index, input->is_int ? "" : swizzle);
4663*bbecb9d1SAndroid Build Coastguard Worker                else
4664*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "%s(%s%s%s[%d]%s)", get_string(srcstypeprefix), prefix, input->glsl_name, arrayname,
4665*bbecb9d1SAndroid Build Coastguard Worker                              src->Register.Index, input->is_int ? "" : swizzle);
4666*bbecb9d1SAndroid Build Coastguard Worker             } else
4667*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "%s(%s%s%s%s)", get_string(srcstypeprefix), prefix, input->glsl_name, arrayname, input->is_int ? "" : swizzle);
4668*bbecb9d1SAndroid Build Coastguard Worker          }
4669*bbecb9d1SAndroid Build Coastguard Worker          sinfo->override_no_wm[i] = input->override_no_wm;
4670*bbecb9d1SAndroid Build Coastguard Worker       } else if (src->Register.File == TGSI_FILE_OUTPUT) {
4671*bbecb9d1SAndroid Build Coastguard Worker          int j = find_io_index(ctx->num_outputs, ctx->outputs, src->Register.Index);
4672*bbecb9d1SAndroid Build Coastguard Worker          if (j < 0)
4673*bbecb9d1SAndroid Build Coastguard Worker             return false;
4674*bbecb9d1SAndroid Build Coastguard Worker 
4675*bbecb9d1SAndroid Build Coastguard Worker          struct vrend_shader_io *output = &ctx->outputs[j];
4676*bbecb9d1SAndroid Build Coastguard Worker 
4677*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Instruction.Opcode == TGSI_OPCODE_FBFETCH) {
4678*bbecb9d1SAndroid Build Coastguard Worker             output->fbfetch_used = true;
4679*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_FBFETCH;
4680*bbecb9d1SAndroid Build Coastguard Worker          }
4681*bbecb9d1SAndroid Build Coastguard Worker 
4682*bbecb9d1SAndroid Build Coastguard Worker          enum vrend_type_qualifier srcstypeprefix = stypeprefix;
4683*bbecb9d1SAndroid Build Coastguard Worker          if (stype == TGSI_TYPE_UNSIGNED && output->is_int)
4684*bbecb9d1SAndroid Build Coastguard Worker             srcstypeprefix = TYPE_CONVERSION_NONE;
4685*bbecb9d1SAndroid Build Coastguard Worker          if (output->glsl_gl_block) {
4686*bbecb9d1SAndroid Build Coastguard Worker             if (output->name == TGSI_SEMANTIC_CLIPDIST) {
4687*bbecb9d1SAndroid Build Coastguard Worker                char clip_indirect[32] = "";
4688*bbecb9d1SAndroid Build Coastguard Worker                if (output->first != output->last) {
4689*bbecb9d1SAndroid Build Coastguard Worker                   if (src->Register.Indirect)
4690*bbecb9d1SAndroid Build Coastguard Worker                      snprintf(clip_indirect, sizeof(clip_indirect), "+ addr%d", src->Indirect.Index);
4691*bbecb9d1SAndroid Build Coastguard Worker                   else
4692*bbecb9d1SAndroid Build Coastguard Worker                      snprintf(clip_indirect, sizeof(clip_indirect), "+ %d", src->Register.Index - output->first);
4693*bbecb9d1SAndroid Build Coastguard Worker                }
4694*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "clip_dist_temp[%d%s]", output->sid, clip_indirect);
4695*bbecb9d1SAndroid Build Coastguard Worker             }
4696*bbecb9d1SAndroid Build Coastguard Worker          } else if (output->name == TGSI_SEMANTIC_GENERIC) {
4697*bbecb9d1SAndroid Build Coastguard Worker             struct vrend_shader_io *io = ctx->generic_ios.output_range.used ? &ctx->generic_ios.output_range.io : &ctx->outputs[j];
4698*bbecb9d1SAndroid Build Coastguard Worker             get_source_info_generic(ctx, io_out, srcstypeprefix, prefix, src, io, arrayname, swizzle, src_buf);
4699*bbecb9d1SAndroid Build Coastguard Worker          } else if (output->name == TGSI_SEMANTIC_PATCH) {
4700*bbecb9d1SAndroid Build Coastguard Worker             struct vrend_shader_io *io = ctx->patch_ios.output_range.used ? &ctx->patch_ios.output_range.io : &ctx->outputs[j];
4701*bbecb9d1SAndroid Build Coastguard Worker             get_source_info_patch(srcstypeprefix, prefix, src, io, arrayname, swizzle, src_buf);
4702*bbecb9d1SAndroid Build Coastguard Worker          } else if (output->name == TGSI_SEMANTIC_TESSOUTER ||
4703*bbecb9d1SAndroid Build Coastguard Worker                     output->name == TGSI_SEMANTIC_TESSINNER) {
4704*bbecb9d1SAndroid Build Coastguard Worker             get_tesslevel_as_source(src_buf, prefix, output->glsl_name, &src->Register);
4705*bbecb9d1SAndroid Build Coastguard Worker          } else {
4706*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(src_buf, "%s(%s%s%s%s)", get_string(srcstypeprefix), prefix, output->glsl_name, arrayname, output->is_int ? "" : swizzle);
4707*bbecb9d1SAndroid Build Coastguard Worker          }
4708*bbecb9d1SAndroid Build Coastguard Worker          sinfo->override_no_wm[i] = output->override_no_wm;
4709*bbecb9d1SAndroid Build Coastguard Worker       } else if (src->Register.File == TGSI_FILE_TEMPORARY) {
4710*bbecb9d1SAndroid Build Coastguard Worker          struct vrend_temp_range *range = find_temp_range(ctx, src->Register.Index);
4711*bbecb9d1SAndroid Build Coastguard Worker          if (!range)
4712*bbecb9d1SAndroid Build Coastguard Worker             return false;
4713*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1) {
4714*bbecb9d1SAndroid Build Coastguard Worker             stprefix = true;
4715*bbecb9d1SAndroid Build Coastguard Worker             stypeprefix = FLOAT_BITS_TO_INT;
4716*bbecb9d1SAndroid Build Coastguard Worker          }
4717*bbecb9d1SAndroid Build Coastguard Worker          char temp_buf[64];
4718*bbecb9d1SAndroid Build Coastguard Worker          get_temp(ctx, src->Register.Indirect, src->Indirect.Index, src->Register.Index,
4719*bbecb9d1SAndroid Build Coastguard Worker                   temp_buf, &ctx->require_dummy_value);
4720*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(src_buf, "%s%c%s%s%s%c", get_string(stypeprefix), stprefix ? '(' : ' ', prefix, temp_buf, swizzle, stprefix ? ')' : ' ');
4721*bbecb9d1SAndroid Build Coastguard Worker       } else if (src->Register.File == TGSI_FILE_CONSTANT) {
4722*bbecb9d1SAndroid Build Coastguard Worker          const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4723*bbecb9d1SAndroid Build Coastguard Worker          int dim = 0;
4724*bbecb9d1SAndroid Build Coastguard Worker          if (src->Register.Dimension && src->Dimension.Index != 0) {
4725*bbecb9d1SAndroid Build Coastguard Worker             dim = src->Dimension.Index;
4726*bbecb9d1SAndroid Build Coastguard Worker             if (src->Dimension.Indirect) {
4727*bbecb9d1SAndroid Build Coastguard Worker                assert(src->DimIndirect.File == TGSI_FILE_ADDRESS);
4728*bbecb9d1SAndroid Build Coastguard Worker                ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
4729*bbecb9d1SAndroid Build Coastguard Worker                if (src->Register.Indirect) {
4730*bbecb9d1SAndroid Build Coastguard Worker                   assert(src->Indirect.File == TGSI_FILE_ADDRESS);
4731*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "%s(%s%suboarr[addr%d].ubocontents[addr%d + %d]%s)", get_string(stypeprefix), prefix, cname, src->DimIndirect.Index, src->Indirect.Index, src->Register.Index, swizzle);
4732*bbecb9d1SAndroid Build Coastguard Worker                } else
4733*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "%s(%s%suboarr[addr%d].ubocontents[%d]%s)", get_string(stypeprefix), prefix, cname, src->DimIndirect.Index, src->Register.Index, swizzle);
4734*bbecb9d1SAndroid Build Coastguard Worker             } else {
4735*bbecb9d1SAndroid Build Coastguard Worker                if (ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT)) {
4736*bbecb9d1SAndroid Build Coastguard Worker                   if (src->Register.Indirect) {
4737*bbecb9d1SAndroid Build Coastguard Worker                      strbuf_fmt(src_buf, "%s(%s%suboarr[%d].ubocontents[addr%d + %d]%s)", get_string(stypeprefix), prefix, cname, dim - ctx->ubo_base, src->Indirect.Index, src->Register.Index, swizzle);
4738*bbecb9d1SAndroid Build Coastguard Worker                   } else
4739*bbecb9d1SAndroid Build Coastguard Worker                      strbuf_fmt(src_buf, "%s(%s%suboarr[%d].ubocontents[%d]%s)", get_string(stypeprefix), prefix, cname, dim - ctx->ubo_base, src->Register.Index, swizzle);
4740*bbecb9d1SAndroid Build Coastguard Worker                } else {
4741*bbecb9d1SAndroid Build Coastguard Worker                   if (src->Register.Indirect) {
4742*bbecb9d1SAndroid Build Coastguard Worker                      strbuf_fmt(src_buf, "%s(%s%subo%dcontents[addr0 + %d]%s)", get_string(stypeprefix), prefix, cname, dim, src->Register.Index, swizzle);
4743*bbecb9d1SAndroid Build Coastguard Worker                   } else
4744*bbecb9d1SAndroid Build Coastguard Worker                      strbuf_fmt(src_buf, "%s(%s%subo%dcontents[%d]%s)", get_string(stypeprefix), prefix, cname, dim, src->Register.Index, swizzle);
4745*bbecb9d1SAndroid Build Coastguard Worker                }
4746*bbecb9d1SAndroid Build Coastguard Worker             }
4747*bbecb9d1SAndroid Build Coastguard Worker          } else {
4748*bbecb9d1SAndroid Build Coastguard Worker             enum vrend_type_qualifier csp = TYPE_CONVERSION_NONE;
4749*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_INTS;
4750*bbecb9d1SAndroid Build Coastguard Worker             if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1)
4751*bbecb9d1SAndroid Build Coastguard Worker                csp = IVEC4;
4752*bbecb9d1SAndroid Build Coastguard Worker             else if (stype == TGSI_TYPE_FLOAT || stype == TGSI_TYPE_UNTYPED)
4753*bbecb9d1SAndroid Build Coastguard Worker                csp = UINT_BITS_TO_FLOAT;
4754*bbecb9d1SAndroid Build Coastguard Worker             else if (stype == TGSI_TYPE_SIGNED)
4755*bbecb9d1SAndroid Build Coastguard Worker                csp = IVEC4;
4756*bbecb9d1SAndroid Build Coastguard Worker 
4757*bbecb9d1SAndroid Build Coastguard Worker             if (src->Register.Indirect) {
4758*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "%s%s(%sconst%d[addr0 + %d]%s)", prefix, get_string(csp), cname, dim, src->Register.Index, swizzle);
4759*bbecb9d1SAndroid Build Coastguard Worker             } else
4760*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "%s%s(%sconst%d[%d]%s)", prefix, get_string(csp), cname, dim, src->Register.Index, swizzle);
4761*bbecb9d1SAndroid Build Coastguard Worker          }
4762*bbecb9d1SAndroid Build Coastguard Worker       } else if (src->Register.File == TGSI_FILE_SAMPLER) {
4763*bbecb9d1SAndroid Build Coastguard Worker          const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4764*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
4765*bbecb9d1SAndroid Build Coastguard Worker             int basearrayidx = lookup_sampler_array(ctx, src->Register.Index);
4766*bbecb9d1SAndroid Build Coastguard Worker             if (src->Register.Indirect) {
4767*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "%ssamp%d[addr%d+%d]%s", cname, basearrayidx, src->Indirect.Index, src->Register.Index - basearrayidx, swizzle);
4768*bbecb9d1SAndroid Build Coastguard Worker             } else {
4769*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "%ssamp%d[%d]%s", cname, basearrayidx, src->Register.Index - basearrayidx, swizzle);
4770*bbecb9d1SAndroid Build Coastguard Worker             }
4771*bbecb9d1SAndroid Build Coastguard Worker          } else {
4772*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(src_buf, "%ssamp%d%s", cname, src->Register.Index, swizzle);
4773*bbecb9d1SAndroid Build Coastguard Worker          }
4774*bbecb9d1SAndroid Build Coastguard Worker          sinfo->sreg_index = src->Register.Index;
4775*bbecb9d1SAndroid Build Coastguard Worker       } else if (src->Register.File == TGSI_FILE_IMAGE) {
4776*bbecb9d1SAndroid Build Coastguard Worker          const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4777*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
4778*bbecb9d1SAndroid Build Coastguard Worker             int basearrayidx = lookup_image_array(ctx, src->Register.Index);
4779*bbecb9d1SAndroid Build Coastguard Worker             if (src->Register.Indirect) {
4780*bbecb9d1SAndroid Build Coastguard Worker                assert(src->Indirect.File == TGSI_FILE_ADDRESS);
4781*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "%simg%d[addr%d + %d]", cname, basearrayidx, src->Indirect.Index, src->Register.Index - basearrayidx);
4782*bbecb9d1SAndroid Build Coastguard Worker             } else
4783*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "%simg%d[%d]", cname, basearrayidx, src->Register.Index - basearrayidx);
4784*bbecb9d1SAndroid Build Coastguard Worker          } else
4785*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(src_buf, "%simg%d%s", cname, src->Register.Index, swizzle);
4786*bbecb9d1SAndroid Build Coastguard Worker          sinfo->sreg_index = src->Register.Index;
4787*bbecb9d1SAndroid Build Coastguard Worker       } else if (src->Register.File == TGSI_FILE_BUFFER) {
4788*bbecb9d1SAndroid Build Coastguard Worker          const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4789*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
4790*bbecb9d1SAndroid Build Coastguard Worker             bool atomic_ssbo = ctx->ssbo_atomic_mask & (1 << src->Register.Index);
4791*bbecb9d1SAndroid Build Coastguard Worker             const char *atomic_str = atomic_ssbo ? "atomic" : "";
4792*bbecb9d1SAndroid Build Coastguard Worker             int base = atomic_ssbo ? ctx->ssbo_atomic_array_base : ctx->ssbo_array_base;
4793*bbecb9d1SAndroid Build Coastguard Worker             if (src->Register.Indirect) {
4794*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "%sssboarr%s[addr%d+%d].%sssbocontents%d%s", cname, atomic_str, src->Indirect.Index, src->Register.Index - base, cname, base, swizzle);
4795*bbecb9d1SAndroid Build Coastguard Worker             } else {
4796*bbecb9d1SAndroid Build Coastguard Worker                strbuf_fmt(src_buf, "%sssboarr%s[%d].%sssbocontents%d%s", cname, atomic_str, src->Register.Index - base, cname, base, swizzle);
4797*bbecb9d1SAndroid Build Coastguard Worker             }
4798*bbecb9d1SAndroid Build Coastguard Worker          } else {
4799*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(src_buf, "%sssbocontents%d%s", cname, src->Register.Index, swizzle);
4800*bbecb9d1SAndroid Build Coastguard Worker          }
4801*bbecb9d1SAndroid Build Coastguard Worker          sinfo->sreg_index = src->Register.Index;
4802*bbecb9d1SAndroid Build Coastguard Worker       } else if (src->Register.File == TGSI_FILE_MEMORY) {
4803*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(src_buf, "values");
4804*bbecb9d1SAndroid Build Coastguard Worker          sinfo->sreg_index = src->Register.Index;
4805*bbecb9d1SAndroid Build Coastguard Worker       } else if (src->Register.File == TGSI_FILE_IMMEDIATE) {
4806*bbecb9d1SAndroid Build Coastguard Worker          if (src->Register.Index >= (int)ARRAY_SIZE(ctx->imm)) {
4807*bbecb9d1SAndroid Build Coastguard Worker             vrend_printf( "Immediate exceeded, max is %lu\n", ARRAY_SIZE(ctx->imm));
4808*bbecb9d1SAndroid Build Coastguard Worker             return false;
4809*bbecb9d1SAndroid Build Coastguard Worker          }
4810*bbecb9d1SAndroid Build Coastguard Worker          struct immed *imd = &ctx->imm[src->Register.Index];
4811*bbecb9d1SAndroid Build Coastguard Worker          int idx = src->Register.SwizzleX;
4812*bbecb9d1SAndroid Build Coastguard Worker          char temp[48];
4813*bbecb9d1SAndroid Build Coastguard Worker          enum vrend_type_qualifier vtype = VEC4;
4814*bbecb9d1SAndroid Build Coastguard Worker          enum vrend_type_qualifier imm_stypeprefix = stypeprefix;
4815*bbecb9d1SAndroid Build Coastguard Worker 
4816*bbecb9d1SAndroid Build Coastguard Worker          if ((inst->Instruction.Opcode == TGSI_OPCODE_TG4 && i == 1) ||
4817*bbecb9d1SAndroid Build Coastguard Worker              (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1))
4818*bbecb9d1SAndroid Build Coastguard Worker             stype = TGSI_TYPE_SIGNED;
4819*bbecb9d1SAndroid Build Coastguard Worker 
4820*bbecb9d1SAndroid Build Coastguard Worker          if (imd->type == TGSI_IMM_UINT32 || imd->type == TGSI_IMM_INT32) {
4821*bbecb9d1SAndroid Build Coastguard Worker             if (imd->type == TGSI_IMM_UINT32)
4822*bbecb9d1SAndroid Build Coastguard Worker                vtype = UVEC4;
4823*bbecb9d1SAndroid Build Coastguard Worker             else
4824*bbecb9d1SAndroid Build Coastguard Worker                vtype = IVEC4;
4825*bbecb9d1SAndroid Build Coastguard Worker 
4826*bbecb9d1SAndroid Build Coastguard Worker             if (stype == TGSI_TYPE_UNSIGNED && imd->type == TGSI_IMM_INT32)
4827*bbecb9d1SAndroid Build Coastguard Worker                imm_stypeprefix = UVEC4;
4828*bbecb9d1SAndroid Build Coastguard Worker             else if (stype == TGSI_TYPE_SIGNED && imd->type == TGSI_IMM_UINT32)
4829*bbecb9d1SAndroid Build Coastguard Worker                imm_stypeprefix = IVEC4;
4830*bbecb9d1SAndroid Build Coastguard Worker             else if (stype == TGSI_TYPE_FLOAT || stype == TGSI_TYPE_UNTYPED) {
4831*bbecb9d1SAndroid Build Coastguard Worker                if (imd->type == TGSI_IMM_INT32)
4832*bbecb9d1SAndroid Build Coastguard Worker                   imm_stypeprefix = INT_BITS_TO_FLOAT;
4833*bbecb9d1SAndroid Build Coastguard Worker                else
4834*bbecb9d1SAndroid Build Coastguard Worker                   imm_stypeprefix = UINT_BITS_TO_FLOAT;
4835*bbecb9d1SAndroid Build Coastguard Worker             } else if (stype == TGSI_TYPE_UNSIGNED || stype == TGSI_TYPE_SIGNED)
4836*bbecb9d1SAndroid Build Coastguard Worker                imm_stypeprefix = TYPE_CONVERSION_NONE;
4837*bbecb9d1SAndroid Build Coastguard Worker          } else if (imd->type == TGSI_IMM_FLOAT64) {
4838*bbecb9d1SAndroid Build Coastguard Worker             vtype = UVEC4;
4839*bbecb9d1SAndroid Build Coastguard Worker             if (stype == TGSI_TYPE_DOUBLE)
4840*bbecb9d1SAndroid Build Coastguard Worker                imm_stypeprefix = TYPE_CONVERSION_NONE;
4841*bbecb9d1SAndroid Build Coastguard Worker             else
4842*bbecb9d1SAndroid Build Coastguard Worker                imm_stypeprefix = UINT_BITS_TO_FLOAT;
4843*bbecb9d1SAndroid Build Coastguard Worker          }
4844*bbecb9d1SAndroid Build Coastguard Worker 
4845*bbecb9d1SAndroid Build Coastguard Worker          /* build up a vec4 of immediates */
4846*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(src_buf, "%s%s(%s(", prefix,
4847*bbecb9d1SAndroid Build Coastguard Worker                     get_string(imm_stypeprefix), get_string(vtype));
4848*bbecb9d1SAndroid Build Coastguard Worker 
4849*bbecb9d1SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < 4; j++) {
4850*bbecb9d1SAndroid Build Coastguard Worker             if (j == 0)
4851*bbecb9d1SAndroid Build Coastguard Worker                idx = src->Register.SwizzleX;
4852*bbecb9d1SAndroid Build Coastguard Worker             else if (j == 1)
4853*bbecb9d1SAndroid Build Coastguard Worker                idx = src->Register.SwizzleY;
4854*bbecb9d1SAndroid Build Coastguard Worker             else if (j == 2)
4855*bbecb9d1SAndroid Build Coastguard Worker                idx = src->Register.SwizzleZ;
4856*bbecb9d1SAndroid Build Coastguard Worker             else if (j == 3)
4857*bbecb9d1SAndroid Build Coastguard Worker                idx = src->Register.SwizzleW;
4858*bbecb9d1SAndroid Build Coastguard Worker 
4859*bbecb9d1SAndroid Build Coastguard Worker             if (inst->Instruction.Opcode == TGSI_OPCODE_TG4 && i == 1 && j == 0) {
4860*bbecb9d1SAndroid Build Coastguard Worker                if (imd->val[idx].ui > 0) {
4861*bbecb9d1SAndroid Build Coastguard Worker                   sinfo->tg4_has_component = true;
4862*bbecb9d1SAndroid Build Coastguard Worker                   if (!ctx->cfg->use_gles)
4863*bbecb9d1SAndroid Build Coastguard Worker                      ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
4864*bbecb9d1SAndroid Build Coastguard Worker                }
4865*bbecb9d1SAndroid Build Coastguard Worker             }
4866*bbecb9d1SAndroid Build Coastguard Worker 
4867*bbecb9d1SAndroid Build Coastguard Worker             switch (imd->type) {
4868*bbecb9d1SAndroid Build Coastguard Worker             case TGSI_IMM_FLOAT32:
4869*bbecb9d1SAndroid Build Coastguard Worker                if (isinf(imd->val[idx].f) || isnan(imd->val[idx].f)) {
4870*bbecb9d1SAndroid Build Coastguard Worker                   ctx->shader_req_bits |= SHADER_REQ_INTS;
4871*bbecb9d1SAndroid Build Coastguard Worker                   snprintf(temp, 48, "uintBitsToFloat(%uU)", imd->val[idx].ui);
4872*bbecb9d1SAndroid Build Coastguard Worker                } else
4873*bbecb9d1SAndroid Build Coastguard Worker                   snprintf(temp, 25, "%.8g", imd->val[idx].f);
4874*bbecb9d1SAndroid Build Coastguard Worker                break;
4875*bbecb9d1SAndroid Build Coastguard Worker             case TGSI_IMM_UINT32:
4876*bbecb9d1SAndroid Build Coastguard Worker                snprintf(temp, 25, "%uU", imd->val[idx].ui);
4877*bbecb9d1SAndroid Build Coastguard Worker                break;
4878*bbecb9d1SAndroid Build Coastguard Worker             case TGSI_IMM_INT32:
4879*bbecb9d1SAndroid Build Coastguard Worker                snprintf(temp, 25, "%d", imd->val[idx].i);
4880*bbecb9d1SAndroid Build Coastguard Worker                sinfo->imm_value = imd->val[idx].i;
4881*bbecb9d1SAndroid Build Coastguard Worker                break;
4882*bbecb9d1SAndroid Build Coastguard Worker             case TGSI_IMM_FLOAT64:
4883*bbecb9d1SAndroid Build Coastguard Worker                snprintf(temp, 48, "%uU", imd->val[idx].ui);
4884*bbecb9d1SAndroid Build Coastguard Worker                break;
4885*bbecb9d1SAndroid Build Coastguard Worker             default:
4886*bbecb9d1SAndroid Build Coastguard Worker                vrend_printf( "unhandled imm type: %x\n", imd->type);
4887*bbecb9d1SAndroid Build Coastguard Worker                return false;
4888*bbecb9d1SAndroid Build Coastguard Worker             }
4889*bbecb9d1SAndroid Build Coastguard Worker             strbuf_append(src_buf, temp);
4890*bbecb9d1SAndroid Build Coastguard Worker             if (j < 3)
4891*bbecb9d1SAndroid Build Coastguard Worker                strbuf_append(src_buf, ",");
4892*bbecb9d1SAndroid Build Coastguard Worker             else {
4893*bbecb9d1SAndroid Build Coastguard Worker                snprintf(temp, 4, "))%c", isfloatabsolute ? ')' : 0);
4894*bbecb9d1SAndroid Build Coastguard Worker                strbuf_append(src_buf, temp);
4895*bbecb9d1SAndroid Build Coastguard Worker             }
4896*bbecb9d1SAndroid Build Coastguard Worker          }
4897*bbecb9d1SAndroid Build Coastguard Worker       } else if (src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
4898*bbecb9d1SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < ctx->num_system_values; j++)
4899*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->system_values[j].first == src->Register.Index) {
4900*bbecb9d1SAndroid Build Coastguard Worker                if (ctx->system_values[j].name == TGSI_SEMANTIC_VERTEXID ||
4901*bbecb9d1SAndroid Build Coastguard Worker                    ctx->system_values[j].name == TGSI_SEMANTIC_INSTANCEID ||
4902*bbecb9d1SAndroid Build Coastguard Worker                    ctx->system_values[j].name == TGSI_SEMANTIC_PRIMID ||
4903*bbecb9d1SAndroid Build Coastguard Worker                    ctx->system_values[j].name == TGSI_SEMANTIC_VERTICESIN ||
4904*bbecb9d1SAndroid Build Coastguard Worker                    ctx->system_values[j].name == TGSI_SEMANTIC_INVOCATIONID ||
4905*bbecb9d1SAndroid Build Coastguard Worker                    ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEID) {
4906*bbecb9d1SAndroid Build Coastguard Worker                   if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1)
4907*bbecb9d1SAndroid Build Coastguard Worker                      strbuf_fmt(src_buf, "ivec4(%s)", ctx->system_values[j].glsl_name);
4908*bbecb9d1SAndroid Build Coastguard Worker                   else
4909*bbecb9d1SAndroid Build Coastguard Worker                      strbuf_fmt(src_buf, "%s(vec4(intBitsToFloat(%s)))", get_string(stypeprefix), ctx->system_values[j].glsl_name);
4910*bbecb9d1SAndroid Build Coastguard Worker                } else if (ctx->system_values[j].name == TGSI_SEMANTIC_HELPER_INVOCATION) {
4911*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "uvec4(%s)", ctx->system_values[j].glsl_name);
4912*bbecb9d1SAndroid Build Coastguard Worker                } else if (ctx->system_values[j].name == TGSI_SEMANTIC_TESSINNER ||
4913*bbecb9d1SAndroid Build Coastguard Worker                         ctx->system_values[j].name == TGSI_SEMANTIC_TESSOUTER) {
4914*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "%s(vec4(%s[%d], %s[%d], %s[%d], %s[%d]))",
4915*bbecb9d1SAndroid Build Coastguard Worker                              prefix,
4916*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, src->Register.SwizzleX,
4917*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, src->Register.SwizzleY,
4918*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, src->Register.SwizzleZ,
4919*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, src->Register.SwizzleW);
4920*bbecb9d1SAndroid Build Coastguard Worker                } else if (ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEPOS) {
4921*bbecb9d1SAndroid Build Coastguard Worker                   /* gl_SamplePosition is a vec2, but TGSI_SEMANTIC_SAMPLEPOS
4922*bbecb9d1SAndroid Build Coastguard Worker                    * is a vec4 with z = w = 0
4923*bbecb9d1SAndroid Build Coastguard Worker                    */
4924*bbecb9d1SAndroid Build Coastguard Worker                   const char *components[4] = {
4925*bbecb9d1SAndroid Build Coastguard Worker                      "gl_SamplePosition.x", "gl_SamplePosition.y", "0.0", "0.0"
4926*bbecb9d1SAndroid Build Coastguard Worker                   };
4927*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "%s(vec4(%s, %s, %s, %s))",
4928*bbecb9d1SAndroid Build Coastguard Worker                              prefix,
4929*bbecb9d1SAndroid Build Coastguard Worker                              components[src->Register.SwizzleX],
4930*bbecb9d1SAndroid Build Coastguard Worker                              components[src->Register.SwizzleY],
4931*bbecb9d1SAndroid Build Coastguard Worker                              components[src->Register.SwizzleZ],
4932*bbecb9d1SAndroid Build Coastguard Worker                              components[src->Register.SwizzleW]);
4933*bbecb9d1SAndroid Build Coastguard Worker                } else if (ctx->system_values[j].name == TGSI_SEMANTIC_TESSCOORD) {
4934*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "%s(vec4(%s.%c, %s.%c, %s.%c, %s.%c))",
4935*bbecb9d1SAndroid Build Coastguard Worker                              prefix,
4936*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleX),
4937*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleY),
4938*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleZ),
4939*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleW));
4940*bbecb9d1SAndroid Build Coastguard Worker                } else if (ctx->system_values[j].name == TGSI_SEMANTIC_GRID_SIZE ||
4941*bbecb9d1SAndroid Build Coastguard Worker                           ctx->system_values[j].name == TGSI_SEMANTIC_THREAD_ID ||
4942*bbecb9d1SAndroid Build Coastguard Worker                           ctx->system_values[j].name == TGSI_SEMANTIC_BLOCK_ID) {
4943*bbecb9d1SAndroid Build Coastguard Worker                   enum vrend_type_qualifier mov_conv = TYPE_CONVERSION_NONE;
4944*bbecb9d1SAndroid Build Coastguard Worker                   if (inst->Instruction.Opcode == TGSI_OPCODE_MOV &&
4945*bbecb9d1SAndroid Build Coastguard Worker                       inst->Dst[0].Register.File == TGSI_FILE_TEMPORARY)
4946*bbecb9d1SAndroid Build Coastguard Worker                     mov_conv = UINT_BITS_TO_FLOAT;
4947*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "%s(uvec4(%s.%c, %s.%c, %s.%c, %s.%c))", get_string(mov_conv),
4948*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleX),
4949*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleY),
4950*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleZ),
4951*bbecb9d1SAndroid Build Coastguard Worker                              ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleW));
4952*bbecb9d1SAndroid Build Coastguard Worker                   sinfo->override_no_cast[i] = true;
4953*bbecb9d1SAndroid Build Coastguard Worker                } else if (ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEMASK) {
4954*bbecb9d1SAndroid Build Coastguard Worker                   const char *vec_type = "ivec4";
4955*bbecb9d1SAndroid Build Coastguard Worker                   enum vrend_type_qualifier srcstypeprefix = TYPE_CONVERSION_NONE;
4956*bbecb9d1SAndroid Build Coastguard Worker                   if (stypeprefix == TYPE_CONVERSION_NONE)
4957*bbecb9d1SAndroid Build Coastguard Worker                      srcstypeprefix = INT_BITS_TO_FLOAT;
4958*bbecb9d1SAndroid Build Coastguard Worker                   else if (stype == TGSI_TYPE_UNSIGNED)
4959*bbecb9d1SAndroid Build Coastguard Worker                      vec_type = "uvec4";
4960*bbecb9d1SAndroid Build Coastguard Worker 
4961*bbecb9d1SAndroid Build Coastguard Worker                   ctx->shader_req_bits |= SHADER_REQ_SAMPLE_SHADING | SHADER_REQ_INTS;
4962*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "%s(%s(%s, %s, %s, %s))",
4963*bbecb9d1SAndroid Build Coastguard Worker                      get_string(srcstypeprefix),
4964*bbecb9d1SAndroid Build Coastguard Worker                      vec_type,
4965*bbecb9d1SAndroid Build Coastguard Worker                      src->Register.SwizzleX == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0",
4966*bbecb9d1SAndroid Build Coastguard Worker                      src->Register.SwizzleY == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0",
4967*bbecb9d1SAndroid Build Coastguard Worker                      src->Register.SwizzleZ == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0",
4968*bbecb9d1SAndroid Build Coastguard Worker                      src->Register.SwizzleW == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0");
4969*bbecb9d1SAndroid Build Coastguard Worker                } else
4970*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "%s%s", prefix, ctx->system_values[j].glsl_name);
4971*bbecb9d1SAndroid Build Coastguard Worker                sinfo->override_no_wm[i] = ctx->system_values[j].override_no_wm;
4972*bbecb9d1SAndroid Build Coastguard Worker                break;
4973*bbecb9d1SAndroid Build Coastguard Worker             }
4974*bbecb9d1SAndroid Build Coastguard Worker       } else if (src->Register.File == TGSI_FILE_HW_ATOMIC) {
4975*bbecb9d1SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < ctx->num_abo; j++) {
4976*bbecb9d1SAndroid Build Coastguard Worker             if (src->Dimension.Index == ctx->abo_idx[j] &&
4977*bbecb9d1SAndroid Build Coastguard Worker                 src->Register.Index >= ctx->abo_offsets[j] &&
4978*bbecb9d1SAndroid Build Coastguard Worker                 src->Register.Index < ctx->abo_offsets[j] + ctx->abo_sizes[j]) {
4979*bbecb9d1SAndroid Build Coastguard Worker                int abo_idx = ctx->abo_idx[j];
4980*bbecb9d1SAndroid Build Coastguard Worker                int abo_offset = ctx->abo_offsets[j] * 4;
4981*bbecb9d1SAndroid Build Coastguard Worker                if (ctx->abo_sizes[j] > 1) {
4982*bbecb9d1SAndroid Build Coastguard Worker                   int offset = src->Register.Index - ctx->abo_offsets[j];
4983*bbecb9d1SAndroid Build Coastguard Worker                   if (src->Register.Indirect) {
4984*bbecb9d1SAndroid Build Coastguard Worker                      assert(src->Indirect.File == TGSI_FILE_ADDRESS);
4985*bbecb9d1SAndroid Build Coastguard Worker                      strbuf_fmt(src_buf, "ac%d_%d[addr%d + %d]", abo_idx, abo_offset, src->Indirect.Index, offset);
4986*bbecb9d1SAndroid Build Coastguard Worker                   } else
4987*bbecb9d1SAndroid Build Coastguard Worker                      strbuf_fmt(src_buf, "ac%d_%d[%d]", abo_idx, abo_offset, offset);
4988*bbecb9d1SAndroid Build Coastguard Worker                } else
4989*bbecb9d1SAndroid Build Coastguard Worker                   strbuf_fmt(src_buf, "ac%d_%d", abo_idx, abo_offset);
4990*bbecb9d1SAndroid Build Coastguard Worker                break;
4991*bbecb9d1SAndroid Build Coastguard Worker             }
4992*bbecb9d1SAndroid Build Coastguard Worker          }
4993*bbecb9d1SAndroid Build Coastguard Worker          sinfo->sreg_index = src->Register.Index;
4994*bbecb9d1SAndroid Build Coastguard Worker       }
4995*bbecb9d1SAndroid Build Coastguard Worker 
4996*bbecb9d1SAndroid Build Coastguard Worker       if (stype == TGSI_TYPE_DOUBLE) {
4997*bbecb9d1SAndroid Build Coastguard Worker          boolean isabsolute = src->Register.Absolute;
4998*bbecb9d1SAndroid Build Coastguard Worker          strcpy(fp64_src, src_buf->buf);
4999*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(src_buf, "fp64_src[%d]", i);
5000*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s.x = %spackDouble2x32(uvec2(%s%s))%s;\n", src_buf->buf, isabsolute ? "abs(" : "", fp64_src, swizzle, isabsolute ? ")" : "");
5001*bbecb9d1SAndroid Build Coastguard Worker       }
5002*bbecb9d1SAndroid Build Coastguard Worker    }
5003*bbecb9d1SAndroid Build Coastguard Worker 
5004*bbecb9d1SAndroid Build Coastguard Worker    return true;
5005*bbecb9d1SAndroid Build Coastguard Worker }
5006*bbecb9d1SAndroid Build Coastguard Worker 
rewrite_1d_image_coordinate(struct vrend_strbuf * src,const struct tgsi_full_instruction * inst)5007*bbecb9d1SAndroid Build Coastguard Worker static bool rewrite_1d_image_coordinate(struct vrend_strbuf *src, const struct tgsi_full_instruction *inst)
5008*bbecb9d1SAndroid Build Coastguard Worker {
5009*bbecb9d1SAndroid Build Coastguard Worker    if (inst->Src[0].Register.File == TGSI_FILE_IMAGE &&
5010*bbecb9d1SAndroid Build Coastguard Worker        (inst->Memory.Texture == TGSI_TEXTURE_1D ||
5011*bbecb9d1SAndroid Build Coastguard Worker         inst->Memory.Texture == TGSI_TEXTURE_1D_ARRAY))  {
5012*bbecb9d1SAndroid Build Coastguard Worker 
5013*bbecb9d1SAndroid Build Coastguard Worker       /* duplicate src */
5014*bbecb9d1SAndroid Build Coastguard Worker       size_t len = strbuf_get_len(src);
5015*bbecb9d1SAndroid Build Coastguard Worker       char *buf = malloc(len);
5016*bbecb9d1SAndroid Build Coastguard Worker       if (!buf)
5017*bbecb9d1SAndroid Build Coastguard Worker          return false;
5018*bbecb9d1SAndroid Build Coastguard Worker       strncpy(buf, src->buf, len);
5019*bbecb9d1SAndroid Build Coastguard Worker 
5020*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Memory.Texture == TGSI_TEXTURE_1D)
5021*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(src, "vec2(vec4(%s).x, 0)", buf);
5022*bbecb9d1SAndroid Build Coastguard Worker       else if (inst->Memory.Texture == TGSI_TEXTURE_1D_ARRAY)
5023*bbecb9d1SAndroid Build Coastguard Worker          strbuf_fmt(src, "vec3(%s.xy, 0).xzy", buf);
5024*bbecb9d1SAndroid Build Coastguard Worker 
5025*bbecb9d1SAndroid Build Coastguard Worker       free(buf);
5026*bbecb9d1SAndroid Build Coastguard Worker    }
5027*bbecb9d1SAndroid Build Coastguard Worker    return true;
5028*bbecb9d1SAndroid Build Coastguard Worker }
5029*bbecb9d1SAndroid Build Coastguard Worker 
5030*bbecb9d1SAndroid Build Coastguard Worker /* We have indirect IO access, but the guest actually send separate values, so
5031*bbecb9d1SAndroid Build Coastguard Worker  * now we have to emulate arrays by putting IO values into arrays according
5032*bbecb9d1SAndroid Build Coastguard Worker  * to semantic. Only join elements that are consecutive. */
5033*bbecb9d1SAndroid Build Coastguard Worker static int
make_array_from_semantic(struct vrend_shader_io * io,int start_index,int num_entries,enum tgsi_semantic semantic)5034*bbecb9d1SAndroid Build Coastguard Worker make_array_from_semantic(struct vrend_shader_io *io, int start_index,
5035*bbecb9d1SAndroid Build Coastguard Worker                          int num_entries, enum tgsi_semantic semantic)
5036*bbecb9d1SAndroid Build Coastguard Worker {
5037*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_shader_io *io_out_range = &io[start_index];
5038*bbecb9d1SAndroid Build Coastguard Worker 
5039*bbecb9d1SAndroid Build Coastguard Worker    int last_sid = io_out_range->sid;
5040*bbecb9d1SAndroid Build Coastguard Worker    for (int i = start_index + 1; i < num_entries; ++i) {
5041*bbecb9d1SAndroid Build Coastguard Worker       if (io[i].name == semantic && (io[i].sid - last_sid == 1)) {
5042*bbecb9d1SAndroid Build Coastguard Worker          io[i].glsl_predefined_no_emit = true;
5043*bbecb9d1SAndroid Build Coastguard Worker          last_sid = io[i].sid;
5044*bbecb9d1SAndroid Build Coastguard Worker          io[i].array_offset = io[i].sid - io_out_range->sid;
5045*bbecb9d1SAndroid Build Coastguard Worker          io_out_range->last = io_out_range->first + io[i].array_offset;
5046*bbecb9d1SAndroid Build Coastguard Worker          io[i].overlapping_array = io_out_range;
5047*bbecb9d1SAndroid Build Coastguard Worker       } else {
5048*bbecb9d1SAndroid Build Coastguard Worker          break;
5049*bbecb9d1SAndroid Build Coastguard Worker       }
5050*bbecb9d1SAndroid Build Coastguard Worker    }
5051*bbecb9d1SAndroid Build Coastguard Worker    return io_out_range->last + 1;
5052*bbecb9d1SAndroid Build Coastguard Worker }
5053*bbecb9d1SAndroid Build Coastguard Worker 
5054*bbecb9d1SAndroid Build Coastguard Worker static bool
collapse_vars_to_arrays(struct vrend_shader_io * io,int num_entries,enum tgsi_semantic semantic)5055*bbecb9d1SAndroid Build Coastguard Worker collapse_vars_to_arrays(struct vrend_shader_io *io,
5056*bbecb9d1SAndroid Build Coastguard Worker                            int num_entries,
5057*bbecb9d1SAndroid Build Coastguard Worker                            enum tgsi_semantic semantic)
5058*bbecb9d1SAndroid Build Coastguard Worker {
5059*bbecb9d1SAndroid Build Coastguard Worker 
5060*bbecb9d1SAndroid Build Coastguard Worker    bool retval = 0;
5061*bbecb9d1SAndroid Build Coastguard Worker    int start_index = 0;
5062*bbecb9d1SAndroid Build Coastguard Worker    while (start_index < num_entries) {
5063*bbecb9d1SAndroid Build Coastguard Worker       if (io[start_index].name == semantic && !io[start_index].glsl_predefined_no_emit) {
5064*bbecb9d1SAndroid Build Coastguard Worker          int new_start_index = make_array_from_semantic(io, start_index, num_entries, semantic);
5065*bbecb9d1SAndroid Build Coastguard Worker          retval |= io[start_index].first != io[start_index].last;
5066*bbecb9d1SAndroid Build Coastguard Worker          start_index = new_start_index;
5067*bbecb9d1SAndroid Build Coastguard Worker       } else {
5068*bbecb9d1SAndroid Build Coastguard Worker          ++start_index;
5069*bbecb9d1SAndroid Build Coastguard Worker       }
5070*bbecb9d1SAndroid Build Coastguard Worker    }
5071*bbecb9d1SAndroid Build Coastguard Worker 
5072*bbecb9d1SAndroid Build Coastguard Worker    io->num_components = 4;
5073*bbecb9d1SAndroid Build Coastguard Worker    io->usage_mask = 0xf;
5074*bbecb9d1SAndroid Build Coastguard Worker    return retval;
5075*bbecb9d1SAndroid Build Coastguard Worker }
5076*bbecb9d1SAndroid Build Coastguard Worker 
5077*bbecb9d1SAndroid Build Coastguard Worker static void
rewrite_io_ranged(struct dump_ctx * ctx)5078*bbecb9d1SAndroid Build Coastguard Worker rewrite_io_ranged(struct dump_ctx *ctx)
5079*bbecb9d1SAndroid Build Coastguard Worker {
5080*bbecb9d1SAndroid Build Coastguard Worker    if ((ctx->info.indirect_files & (1 << TGSI_FILE_INPUT)) ||
5081*bbecb9d1SAndroid Build Coastguard Worker        ctx->key->require_input_arrays) {
5082*bbecb9d1SAndroid Build Coastguard Worker 
5083*bbecb9d1SAndroid Build Coastguard Worker       bool generic_array = collapse_vars_to_arrays(ctx->inputs, ctx->num_inputs,
5084*bbecb9d1SAndroid Build Coastguard Worker                                                   TGSI_SEMANTIC_GENERIC);
5085*bbecb9d1SAndroid Build Coastguard Worker       bool patch_array = collapse_vars_to_arrays(ctx->inputs, ctx->num_inputs,
5086*bbecb9d1SAndroid Build Coastguard Worker                                                  TGSI_SEMANTIC_PATCH);
5087*bbecb9d1SAndroid Build Coastguard Worker 
5088*bbecb9d1SAndroid Build Coastguard Worker       ctx->has_input_arrays = generic_array || patch_array;
5089*bbecb9d1SAndroid Build Coastguard Worker 
5090*bbecb9d1SAndroid Build Coastguard Worker       if (prefer_generic_io_block(ctx, io_in))
5091*bbecb9d1SAndroid Build Coastguard Worker          ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
5092*bbecb9d1SAndroid Build Coastguard Worker    }
5093*bbecb9d1SAndroid Build Coastguard Worker 
5094*bbecb9d1SAndroid Build Coastguard Worker    if ((ctx->info.indirect_files & (1 << TGSI_FILE_OUTPUT)) ||
5095*bbecb9d1SAndroid Build Coastguard Worker        ctx->key->require_output_arrays) {
5096*bbecb9d1SAndroid Build Coastguard Worker 
5097*bbecb9d1SAndroid Build Coastguard Worker       bool generic_array = collapse_vars_to_arrays(ctx->outputs, ctx->num_outputs,
5098*bbecb9d1SAndroid Build Coastguard Worker                                                   TGSI_SEMANTIC_GENERIC);
5099*bbecb9d1SAndroid Build Coastguard Worker       bool patch_array = collapse_vars_to_arrays(ctx->outputs, ctx->num_outputs,
5100*bbecb9d1SAndroid Build Coastguard Worker                                                 TGSI_SEMANTIC_PATCH);
5101*bbecb9d1SAndroid Build Coastguard Worker 
5102*bbecb9d1SAndroid Build Coastguard Worker       ctx->has_output_arrays = generic_array || patch_array;
5103*bbecb9d1SAndroid Build Coastguard Worker 
5104*bbecb9d1SAndroid Build Coastguard Worker       if (prefer_generic_io_block(ctx, io_out))
5105*bbecb9d1SAndroid Build Coastguard Worker          ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
5106*bbecb9d1SAndroid Build Coastguard Worker    }
5107*bbecb9d1SAndroid Build Coastguard Worker 
5108*bbecb9d1SAndroid Build Coastguard Worker    if ((ctx->has_output_arrays || ctx->has_input_arrays)
5109*bbecb9d1SAndroid Build Coastguard Worker        && ctx->cfg->has_arrays_of_arrays && !ctx->cfg->use_gles)
5110*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_ARRAYS_OF_ARRAYS;
5111*bbecb9d1SAndroid Build Coastguard Worker 
5112*bbecb9d1SAndroid Build Coastguard Worker }
5113*bbecb9d1SAndroid Build Coastguard Worker 
5114*bbecb9d1SAndroid Build Coastguard Worker static
rewrite_vs_pos_array(struct dump_ctx * ctx)5115*bbecb9d1SAndroid Build Coastguard Worker void rewrite_vs_pos_array(struct dump_ctx *ctx)
5116*bbecb9d1SAndroid Build Coastguard Worker {
5117*bbecb9d1SAndroid Build Coastguard Worker    int range_start = 0xffff;
5118*bbecb9d1SAndroid Build Coastguard Worker    int range_end = 0;
5119*bbecb9d1SAndroid Build Coastguard Worker    int io_idx = 0;
5120*bbecb9d1SAndroid Build Coastguard Worker 
5121*bbecb9d1SAndroid Build Coastguard Worker    for (uint i = 0; i < ctx->num_inputs; ++i) {
5122*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->inputs[i].name == TGSI_SEMANTIC_POSITION) {
5123*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].glsl_predefined_no_emit = true;
5124*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[i].first < range_start) {
5125*bbecb9d1SAndroid Build Coastguard Worker             io_idx = i;
5126*bbecb9d1SAndroid Build Coastguard Worker             range_start = ctx->inputs[i].first;
5127*bbecb9d1SAndroid Build Coastguard Worker          }
5128*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[i].last > range_end)
5129*bbecb9d1SAndroid Build Coastguard Worker             range_end = ctx->inputs[i].last;
5130*bbecb9d1SAndroid Build Coastguard Worker       }
5131*bbecb9d1SAndroid Build Coastguard Worker    }
5132*bbecb9d1SAndroid Build Coastguard Worker 
5133*bbecb9d1SAndroid Build Coastguard Worker    if (range_start != range_end) {
5134*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[io_idx].first = range_start;
5135*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[io_idx].last = range_end;
5136*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[io_idx].glsl_predefined_no_emit = false;
5137*bbecb9d1SAndroid Build Coastguard Worker       ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
5138*bbecb9d1SAndroid Build Coastguard Worker    }
5139*bbecb9d1SAndroid Build Coastguard Worker }
5140*bbecb9d1SAndroid Build Coastguard Worker 
5141*bbecb9d1SAndroid Build Coastguard Worker 
5142*bbecb9d1SAndroid Build Coastguard Worker static
emit_fs_clipdistance_load(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)5143*bbecb9d1SAndroid Build Coastguard Worker void emit_fs_clipdistance_load(const struct dump_ctx *ctx,
5144*bbecb9d1SAndroid Build Coastguard Worker                                struct vrend_glsl_strbufs *glsl_strbufs)
5145*bbecb9d1SAndroid Build Coastguard Worker {
5146*bbecb9d1SAndroid Build Coastguard Worker    int i;
5147*bbecb9d1SAndroid Build Coastguard Worker 
5148*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx->fs_uses_clipdist_input)
5149*bbecb9d1SAndroid Build Coastguard Worker       return;
5150*bbecb9d1SAndroid Build Coastguard Worker 
5151*bbecb9d1SAndroid Build Coastguard Worker    int prev_num = ctx->key->num_in_clip + ctx->key->num_in_cull;
5152*bbecb9d1SAndroid Build Coastguard Worker    int ndists;
5153*bbecb9d1SAndroid Build Coastguard Worker    const char *prefix="";
5154*bbecb9d1SAndroid Build Coastguard Worker 
5155*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL)
5156*bbecb9d1SAndroid Build Coastguard Worker       prefix = "gl_out[gl_InvocationID].";
5157*bbecb9d1SAndroid Build Coastguard Worker 
5158*bbecb9d1SAndroid Build Coastguard Worker    ndists = ctx->num_in_clip_dist;
5159*bbecb9d1SAndroid Build Coastguard Worker    if (prev_num > 0)
5160*bbecb9d1SAndroid Build Coastguard Worker       ndists = prev_num;
5161*bbecb9d1SAndroid Build Coastguard Worker 
5162*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ndists; i++) {
5163*bbecb9d1SAndroid Build Coastguard Worker       int clipidx = i < 4 ? 0 : 1;
5164*bbecb9d1SAndroid Build Coastguard Worker       char swiz = i & 3;
5165*bbecb9d1SAndroid Build Coastguard Worker       char wm = 0;
5166*bbecb9d1SAndroid Build Coastguard Worker       switch (swiz) {
5167*bbecb9d1SAndroid Build Coastguard Worker       default:
5168*bbecb9d1SAndroid Build Coastguard Worker       case 0: wm = 'x'; break;
5169*bbecb9d1SAndroid Build Coastguard Worker       case 1: wm = 'y'; break;
5170*bbecb9d1SAndroid Build Coastguard Worker       case 2: wm = 'z'; break;
5171*bbecb9d1SAndroid Build Coastguard Worker       case 3: wm = 'w'; break;
5172*bbecb9d1SAndroid Build Coastguard Worker       }
5173*bbecb9d1SAndroid Build Coastguard Worker       bool is_cull = false;
5174*bbecb9d1SAndroid Build Coastguard Worker       if (prev_num > 0) {
5175*bbecb9d1SAndroid Build Coastguard Worker          if (i >= ctx->key->num_in_clip && i < prev_num)
5176*bbecb9d1SAndroid Build Coastguard Worker             is_cull = true;
5177*bbecb9d1SAndroid Build Coastguard Worker       }
5178*bbecb9d1SAndroid Build Coastguard Worker       const char *clip_cull = is_cull ? "Cull" : "Clip";
5179*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(glsl_strbufs, "clip_dist_temp[%d].%c = %sgl_%sDistance[%d];\n", clipidx, wm, prefix, clip_cull,
5180*bbecb9d1SAndroid Build Coastguard Worker                 is_cull ? i - ctx->key->num_in_clip : i);
5181*bbecb9d1SAndroid Build Coastguard Worker    }
5182*bbecb9d1SAndroid Build Coastguard Worker }
5183*bbecb9d1SAndroid Build Coastguard Worker 
5184*bbecb9d1SAndroid Build Coastguard Worker static
renumber_io_arrays(unsigned nio,struct vrend_shader_io * io)5185*bbecb9d1SAndroid Build Coastguard Worker void renumber_io_arrays(unsigned nio, struct vrend_shader_io *io)
5186*bbecb9d1SAndroid Build Coastguard Worker {
5187*bbecb9d1SAndroid Build Coastguard Worker    int next_array_id = 1;
5188*bbecb9d1SAndroid Build Coastguard Worker    for (unsigned i = 0; i < nio; ++i) {
5189*bbecb9d1SAndroid Build Coastguard Worker       if (io[i].name != TGSI_SEMANTIC_GENERIC &&
5190*bbecb9d1SAndroid Build Coastguard Worker           io[i].name != TGSI_SEMANTIC_PATCH)
5191*bbecb9d1SAndroid Build Coastguard Worker          continue;
5192*bbecb9d1SAndroid Build Coastguard Worker       if (io[i].array_id > 0)
5193*bbecb9d1SAndroid Build Coastguard Worker          io[i].array_id = next_array_id++;
5194*bbecb9d1SAndroid Build Coastguard Worker    }
5195*bbecb9d1SAndroid Build Coastguard Worker }
5196*bbecb9d1SAndroid Build Coastguard Worker 
5197*bbecb9d1SAndroid Build Coastguard Worker // TODO Consider exposing non-const ctx-> members as args to make *ctx const
handle_io_arrays(struct dump_ctx * ctx)5198*bbecb9d1SAndroid Build Coastguard Worker static void handle_io_arrays(struct dump_ctx *ctx)
5199*bbecb9d1SAndroid Build Coastguard Worker {
5200*bbecb9d1SAndroid Build Coastguard Worker    /* If the guest sent real IO arrays then we declare them individually,
5201*bbecb9d1SAndroid Build Coastguard Worker     * and have to do some work to deal with overlapping values, regions and
5202*bbecb9d1SAndroid Build Coastguard Worker     * enhanced layouts */
5203*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->guest_sent_io_arrays)  {
5204*bbecb9d1SAndroid Build Coastguard Worker 
5205*bbecb9d1SAndroid Build Coastguard Worker       /* Array ID numbering is not ordered accross shaders, so do
5206*bbecb9d1SAndroid Build Coastguard Worker        * some renumbering for generics and patches. */
5207*bbecb9d1SAndroid Build Coastguard Worker       renumber_io_arrays(ctx->num_inputs, ctx->inputs);
5208*bbecb9d1SAndroid Build Coastguard Worker       renumber_io_arrays(ctx->num_outputs, ctx->outputs);
5209*bbecb9d1SAndroid Build Coastguard Worker 
5210*bbecb9d1SAndroid Build Coastguard Worker    } else {
5211*bbecb9d1SAndroid Build Coastguard Worker       /* The guest didn't send real arrays, do we might have to add a big array
5212*bbecb9d1SAndroid Build Coastguard Worker        * for all generic and another for patch inputs */
5213*bbecb9d1SAndroid Build Coastguard Worker       rewrite_io_ranged(ctx);
5214*bbecb9d1SAndroid Build Coastguard Worker    }
5215*bbecb9d1SAndroid Build Coastguard Worker }
5216*bbecb9d1SAndroid Build Coastguard Worker 
5217*bbecb9d1SAndroid Build Coastguard Worker static int
compare_shader_io(const void * vlhs,const void * vrhs)5218*bbecb9d1SAndroid Build Coastguard Worker compare_shader_io(const void *vlhs, const void *vrhs)
5219*bbecb9d1SAndroid Build Coastguard Worker {
5220*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_shader_io *lhs = (struct vrend_shader_io *)vlhs;
5221*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_shader_io *rhs = (struct vrend_shader_io *)vrhs;
5222*bbecb9d1SAndroid Build Coastguard Worker 
5223*bbecb9d1SAndroid Build Coastguard Worker    if (lhs->name < rhs->name)
5224*bbecb9d1SAndroid Build Coastguard Worker       return -1;
5225*bbecb9d1SAndroid Build Coastguard Worker    if (lhs->name > rhs->name)
5226*bbecb9d1SAndroid Build Coastguard Worker       return 1;
5227*bbecb9d1SAndroid Build Coastguard Worker    return lhs->sid - rhs->sid;
5228*bbecb9d1SAndroid Build Coastguard Worker }
5229*bbecb9d1SAndroid Build Coastguard Worker 
5230*bbecb9d1SAndroid Build Coastguard Worker static void
add_missing_semantic_inputs(struct vrend_shader_io * inputs,int * num_inputs,int * next_location,uint64_t sids_missing,const char * prefix,char * type_prefix,enum tgsi_semantic name,const struct vrend_shader_key * key)5231*bbecb9d1SAndroid Build Coastguard Worker add_missing_semantic_inputs(struct vrend_shader_io *inputs, int *num_inputs,
5232*bbecb9d1SAndroid Build Coastguard Worker                             int *next_location, uint64_t sids_missing,
5233*bbecb9d1SAndroid Build Coastguard Worker                             const char *prefix, char *type_prefix,
5234*bbecb9d1SAndroid Build Coastguard Worker                             enum tgsi_semantic name,
5235*bbecb9d1SAndroid Build Coastguard Worker                             const struct vrend_shader_key *key)
5236*bbecb9d1SAndroid Build Coastguard Worker {
5237*bbecb9d1SAndroid Build Coastguard Worker 
5238*bbecb9d1SAndroid Build Coastguard Worker    while (sids_missing) {
5239*bbecb9d1SAndroid Build Coastguard Worker       int sid = u_bit_scan64(&sids_missing);
5240*bbecb9d1SAndroid Build Coastguard Worker       struct vrend_shader_io *io = &inputs[*num_inputs];
5241*bbecb9d1SAndroid Build Coastguard Worker       io->sid = sid;
5242*bbecb9d1SAndroid Build Coastguard Worker       io->last = io->first = *next_location;
5243*bbecb9d1SAndroid Build Coastguard Worker       io->name = name;
5244*bbecb9d1SAndroid Build Coastguard Worker       io->type = VEC_FLOAT;
5245*bbecb9d1SAndroid Build Coastguard Worker       uint32_t sids_added = 1 << sid;
5246*bbecb9d1SAndroid Build Coastguard Worker 
5247*bbecb9d1SAndroid Build Coastguard Worker 
5248*bbecb9d1SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < key->in_arrays.num_arrays; j++) {
5249*bbecb9d1SAndroid Build Coastguard Worker          const struct vrend_shader_io_array *array = &key->in_arrays.layout[j];
5250*bbecb9d1SAndroid Build Coastguard Worker          if (array->name == name &&
5251*bbecb9d1SAndroid Build Coastguard Worker              array->sid <= sid &&
5252*bbecb9d1SAndroid Build Coastguard Worker              array->sid + array->size >= sid) {
5253*bbecb9d1SAndroid Build Coastguard Worker             io->last = io->first + array->size;
5254*bbecb9d1SAndroid Build Coastguard Worker             io->sid = array->sid;
5255*bbecb9d1SAndroid Build Coastguard Worker             sids_added = ((1u << array->size) - 1) << sid;
5256*bbecb9d1SAndroid Build Coastguard Worker             break;
5257*bbecb9d1SAndroid Build Coastguard Worker          }
5258*bbecb9d1SAndroid Build Coastguard Worker       }
5259*bbecb9d1SAndroid Build Coastguard Worker 
5260*bbecb9d1SAndroid Build Coastguard Worker       (*next_location) += io->last - io->first + 1;
5261*bbecb9d1SAndroid Build Coastguard Worker 
5262*bbecb9d1SAndroid Build Coastguard Worker       sids_missing &= ~sids_added;
5263*bbecb9d1SAndroid Build Coastguard Worker 
5264*bbecb9d1SAndroid Build Coastguard Worker       snprintf(io->glsl_name, 128, "%s%s%d", prefix, type_prefix, sid);
5265*bbecb9d1SAndroid Build Coastguard Worker       (*num_inputs)++;
5266*bbecb9d1SAndroid Build Coastguard Worker    }
5267*bbecb9d1SAndroid Build Coastguard Worker }
5268*bbecb9d1SAndroid Build Coastguard Worker 
5269*bbecb9d1SAndroid Build Coastguard Worker static int
add_missing_inputs(const struct dump_ctx * ctx,struct vrend_shader_io * inputs,int num_inputs)5270*bbecb9d1SAndroid Build Coastguard Worker add_missing_inputs(const struct dump_ctx *ctx, struct vrend_shader_io *inputs,
5271*bbecb9d1SAndroid Build Coastguard Worker                    int num_inputs)
5272*bbecb9d1SAndroid Build Coastguard Worker {
5273*bbecb9d1SAndroid Build Coastguard Worker    uint64_t generics_declared = 0;
5274*bbecb9d1SAndroid Build Coastguard Worker    uint64_t patches_declared = 0;
5275*bbecb9d1SAndroid Build Coastguard Worker    uint8_t texcoord_declared = 0;
5276*bbecb9d1SAndroid Build Coastguard Worker 
5277*bbecb9d1SAndroid Build Coastguard Worker    int next_location = 0;
5278*bbecb9d1SAndroid Build Coastguard Worker    for (int i = 0; i < num_inputs; ++i) {
5279*bbecb9d1SAndroid Build Coastguard Worker       int offset = 0;
5280*bbecb9d1SAndroid Build Coastguard Worker       for (int k = inputs[i].first; k <= inputs[i].last; ++k, ++offset) {
5281*bbecb9d1SAndroid Build Coastguard Worker          int sid = inputs[i].sid + offset;
5282*bbecb9d1SAndroid Build Coastguard Worker          switch (inputs[i].name) {
5283*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_SEMANTIC_GENERIC:
5284*bbecb9d1SAndroid Build Coastguard Worker             generics_declared |= 1ull << sid;
5285*bbecb9d1SAndroid Build Coastguard Worker             break;
5286*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_SEMANTIC_PATCH:
5287*bbecb9d1SAndroid Build Coastguard Worker             patches_declared |= 1ull << sid;
5288*bbecb9d1SAndroid Build Coastguard Worker             break;
5289*bbecb9d1SAndroid Build Coastguard Worker          case TGSI_SEMANTIC_TEXCOORD:
5290*bbecb9d1SAndroid Build Coastguard Worker             texcoord_declared |= 1ull << sid;
5291*bbecb9d1SAndroid Build Coastguard Worker             break;
5292*bbecb9d1SAndroid Build Coastguard Worker          default:
5293*bbecb9d1SAndroid Build Coastguard Worker             ;
5294*bbecb9d1SAndroid Build Coastguard Worker          }
5295*bbecb9d1SAndroid Build Coastguard Worker       }
5296*bbecb9d1SAndroid Build Coastguard Worker       if (next_location < inputs[i].last)
5297*bbecb9d1SAndroid Build Coastguard Worker          next_location = inputs[i].last;
5298*bbecb9d1SAndroid Build Coastguard Worker    }
5299*bbecb9d1SAndroid Build Coastguard Worker    ++next_location;
5300*bbecb9d1SAndroid Build Coastguard Worker 
5301*bbecb9d1SAndroid Build Coastguard Worker    uint64_t generics_missing = ctx->key->in_generic_expected_mask & ~generics_declared;
5302*bbecb9d1SAndroid Build Coastguard Worker    uint64_t patches_missing = ctx->key->in_patch_expected_mask & ~patches_declared;
5303*bbecb9d1SAndroid Build Coastguard Worker    uint64_t texcoord_missing = ctx->key->in_texcoord_expected_mask & ~texcoord_declared;
5304*bbecb9d1SAndroid Build Coastguard Worker 
5305*bbecb9d1SAndroid Build Coastguard Worker    const char *prefix = get_stage_input_name_prefix(ctx, ctx->prog_type);
5306*bbecb9d1SAndroid Build Coastguard Worker    add_missing_semantic_inputs(inputs, &num_inputs, &next_location,
5307*bbecb9d1SAndroid Build Coastguard Worker                                generics_missing, prefix, "_g",
5308*bbecb9d1SAndroid Build Coastguard Worker                                TGSI_SEMANTIC_GENERIC, ctx->key);
5309*bbecb9d1SAndroid Build Coastguard Worker    add_missing_semantic_inputs(inputs, &num_inputs, &next_location,
5310*bbecb9d1SAndroid Build Coastguard Worker                                texcoord_missing, prefix, "_t",
5311*bbecb9d1SAndroid Build Coastguard Worker                                TGSI_SEMANTIC_TEXCOORD, ctx->key);
5312*bbecb9d1SAndroid Build Coastguard Worker    add_missing_semantic_inputs(inputs, &num_inputs, &next_location,
5313*bbecb9d1SAndroid Build Coastguard Worker                                patches_missing, "patch", "",
5314*bbecb9d1SAndroid Build Coastguard Worker                                TGSI_SEMANTIC_PATCH, ctx->key);
5315*bbecb9d1SAndroid Build Coastguard Worker 
5316*bbecb9d1SAndroid Build Coastguard Worker    qsort(inputs, num_inputs, sizeof(struct vrend_shader_io),
5317*bbecb9d1SAndroid Build Coastguard Worker          compare_shader_io);
5318*bbecb9d1SAndroid Build Coastguard Worker    return num_inputs;
5319*bbecb9d1SAndroid Build Coastguard Worker }
5320*bbecb9d1SAndroid Build Coastguard Worker 
5321*bbecb9d1SAndroid Build Coastguard Worker static boolean
iter_instruction(struct tgsi_iterate_context * iter,struct tgsi_full_instruction * inst)5322*bbecb9d1SAndroid Build Coastguard Worker iter_instruction(struct tgsi_iterate_context *iter,
5323*bbecb9d1SAndroid Build Coastguard Worker                  struct tgsi_full_instruction *inst)
5324*bbecb9d1SAndroid Build Coastguard Worker {
5325*bbecb9d1SAndroid Build Coastguard Worker    struct dump_ctx *ctx = (struct dump_ctx *)iter;
5326*bbecb9d1SAndroid Build Coastguard Worker    struct dest_info dinfo = { 0 };
5327*bbecb9d1SAndroid Build Coastguard Worker    struct source_info sinfo = { 0 };
5328*bbecb9d1SAndroid Build Coastguard Worker    const char *srcs[4];
5329*bbecb9d1SAndroid Build Coastguard Worker    char *dsts[3];
5330*bbecb9d1SAndroid Build Coastguard Worker    char fp64_dsts[3][255];
5331*bbecb9d1SAndroid Build Coastguard Worker    uint instno = ctx->instno++;
5332*bbecb9d1SAndroid Build Coastguard Worker    char writemask[6] = "";
5333*bbecb9d1SAndroid Build Coastguard Worker    char src_swizzle0[16];
5334*bbecb9d1SAndroid Build Coastguard Worker 
5335*bbecb9d1SAndroid Build Coastguard Worker    sinfo.svec4 = VEC4;
5336*bbecb9d1SAndroid Build Coastguard Worker 
5337*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->prog_type == (enum tgsi_processor_type) -1)
5338*bbecb9d1SAndroid Build Coastguard Worker       ctx->prog_type = iter->processor.Processor;
5339*bbecb9d1SAndroid Build Coastguard Worker 
5340*bbecb9d1SAndroid Build Coastguard Worker    if (instno == 0) {
5341*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->prog_type != TGSI_PROCESSOR_VERTEX)
5342*bbecb9d1SAndroid Build Coastguard Worker          ctx->num_inputs = add_missing_inputs(ctx, ctx->inputs, ctx->num_inputs);
5343*bbecb9d1SAndroid Build Coastguard Worker       handle_io_arrays(ctx);
5344*bbecb9d1SAndroid Build Coastguard Worker 
5345*bbecb9d1SAndroid Build Coastguard Worker       /* Vertex shader inputs are not send as arrays, but the access may still be
5346*bbecb9d1SAndroid Build Coastguard Worker        * indirect. so we have to deal with that */
5347*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->prog_type == TGSI_PROCESSOR_VERTEX &&
5348*bbecb9d1SAndroid Build Coastguard Worker           ctx->info.indirect_files & (1 << TGSI_FILE_INPUT)) {
5349*bbecb9d1SAndroid Build Coastguard Worker          rewrite_vs_pos_array(ctx);
5350*bbecb9d1SAndroid Build Coastguard Worker       }
5351*bbecb9d1SAndroid Build Coastguard Worker 
5352*bbecb9d1SAndroid Build Coastguard Worker       emit_buf(&ctx->glsl_strbufs, "void main(void)\n{\n");
5353*bbecb9d1SAndroid Build Coastguard Worker       if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
5354*bbecb9d1SAndroid Build Coastguard Worker          emit_color_select(ctx, &ctx->glsl_strbufs);
5355*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->fs_uses_clipdist_input)
5356*bbecb9d1SAndroid Build Coastguard Worker             emit_fs_clipdistance_load(ctx, &ctx->glsl_strbufs);
5357*bbecb9d1SAndroid Build Coastguard Worker       }
5358*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->so)
5359*bbecb9d1SAndroid Build Coastguard Worker          prepare_so_movs(ctx);
5360*bbecb9d1SAndroid Build Coastguard Worker 
5361*bbecb9d1SAndroid Build Coastguard Worker       /* GLES doesn't allow invariant specifiers on inputs, but on GL with
5362*bbecb9d1SAndroid Build Coastguard Worker        * GLSL < 4.30 it is required to match the output of the previous stage */
5363*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles) {
5364*bbecb9d1SAndroid Build Coastguard Worker          for (unsigned i = 0; i < ctx->num_inputs; ++i) {
5365*bbecb9d1SAndroid Build Coastguard Worker             uint32_t bit_pos = varying_bit_from_semantic_and_index(ctx->inputs[i].name, ctx->inputs[i].sid);
5366*bbecb9d1SAndroid Build Coastguard Worker             uint32_t slot = bit_pos / 32;
5367*bbecb9d1SAndroid Build Coastguard Worker             uint32_t bit = 1u << (bit_pos & 0x1f);
5368*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->key->force_invariant_inputs[slot] & bit)
5369*bbecb9d1SAndroid Build Coastguard Worker                ctx->inputs[i].invariant = 1;
5370*bbecb9d1SAndroid Build Coastguard Worker             else
5371*bbecb9d1SAndroid Build Coastguard Worker                ctx->inputs[i].invariant = 0;
5372*bbecb9d1SAndroid Build Coastguard Worker          }
5373*bbecb9d1SAndroid Build Coastguard Worker       }
5374*bbecb9d1SAndroid Build Coastguard Worker    }
5375*bbecb9d1SAndroid Build Coastguard Worker 
5376*bbecb9d1SAndroid Build Coastguard Worker    if (!get_destination_info(ctx, inst, &dinfo, ctx->dst_bufs, fp64_dsts, writemask))
5377*bbecb9d1SAndroid Build Coastguard Worker       return false;
5378*bbecb9d1SAndroid Build Coastguard Worker 
5379*bbecb9d1SAndroid Build Coastguard Worker    if (!get_source_info(ctx, inst, &sinfo, ctx->src_bufs, src_swizzle0))
5380*bbecb9d1SAndroid Build Coastguard Worker       return false;
5381*bbecb9d1SAndroid Build Coastguard Worker 
5382*bbecb9d1SAndroid Build Coastguard Worker    for (size_t i = 0; i < ARRAY_SIZE(srcs); ++i)
5383*bbecb9d1SAndroid Build Coastguard Worker       srcs[i] = ctx->src_bufs[i].buf;
5384*bbecb9d1SAndroid Build Coastguard Worker 
5385*bbecb9d1SAndroid Build Coastguard Worker    for (size_t i = 0; i < ARRAY_SIZE(dsts); ++i)
5386*bbecb9d1SAndroid Build Coastguard Worker       dsts[i] = ctx->dst_bufs[i].buf;
5387*bbecb9d1SAndroid Build Coastguard Worker 
5388*bbecb9d1SAndroid Build Coastguard Worker    switch (inst->Instruction.Opcode) {
5389*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SQRT:
5390*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DSQRT:
5391*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = sqrt(vec4(%s))%s;\n", dsts[0], srcs[0], writemask);
5392*bbecb9d1SAndroid Build Coastguard Worker       break;
5393*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_LRP:
5394*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = mix(vec4(%s), vec4(%s), vec4(%s))%s;\n", dsts[0], srcs[2], srcs[1], srcs[0], writemask);
5395*bbecb9d1SAndroid Build Coastguard Worker       break;
5396*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DP2:
5397*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(dot(vec2(%s), vec2(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5398*bbecb9d1SAndroid Build Coastguard Worker       break;
5399*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DP3:
5400*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(dot(vec3(%s), vec3(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5401*bbecb9d1SAndroid Build Coastguard Worker       break;
5402*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DP4:
5403*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(dot(vec4(%s), vec4(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5404*bbecb9d1SAndroid Build Coastguard Worker       break;
5405*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DPH:
5406*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(dot(vec4(vec3(%s), 1.0), vec4(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5407*bbecb9d1SAndroid Build Coastguard Worker       break;
5408*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_MAX:
5409*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DMAX:
5410*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_IMAX:
5411*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UMAX:
5412*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(max(%s, %s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5413*bbecb9d1SAndroid Build Coastguard Worker       break;
5414*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_MIN:
5415*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DMIN:
5416*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_IMIN:
5417*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UMIN:
5418*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(min(%s, %s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5419*bbecb9d1SAndroid Build Coastguard Worker       break;
5420*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ABS:
5421*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_IABS:
5422*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DABS:
5423*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("abs");
5424*bbecb9d1SAndroid Build Coastguard Worker       break;
5425*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_KILL_IF:
5426*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "if (any(lessThan(%s, vec4(0.0))))\ndiscard;\n", srcs[0]);
5427*bbecb9d1SAndroid Build Coastguard Worker       break;
5428*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_IF:
5429*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UIF:
5430*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "if (bool(%s.x)) {\n", srcs[0]);
5431*bbecb9d1SAndroid Build Coastguard Worker       indent_buf(&ctx->glsl_strbufs);
5432*bbecb9d1SAndroid Build Coastguard Worker       break;
5433*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ELSE:
5434*bbecb9d1SAndroid Build Coastguard Worker       outdent_buf(&ctx->glsl_strbufs);
5435*bbecb9d1SAndroid Build Coastguard Worker       emit_buf(&ctx->glsl_strbufs, "} else {\n");
5436*bbecb9d1SAndroid Build Coastguard Worker       indent_buf(&ctx->glsl_strbufs);
5437*bbecb9d1SAndroid Build Coastguard Worker       break;
5438*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ENDIF:
5439*bbecb9d1SAndroid Build Coastguard Worker       emit_buf(&ctx->glsl_strbufs, "}\n");
5440*bbecb9d1SAndroid Build Coastguard Worker       outdent_buf(&ctx->glsl_strbufs);
5441*bbecb9d1SAndroid Build Coastguard Worker       break;
5442*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_KILL:
5443*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "discard;\n");
5444*bbecb9d1SAndroid Build Coastguard Worker       break;
5445*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DST:
5446*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = vec4(1.0, %s.y * %s.y, %s.z, %s.w);\n", dsts[0],
5447*bbecb9d1SAndroid Build Coastguard Worker                srcs[0], srcs[1], srcs[0], srcs[1]);
5448*bbecb9d1SAndroid Build Coastguard Worker       break;
5449*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_LIT:
5450*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(vec4(1.0, max(%s.x, 0.0), step(0.0, %s.x) * pow(max(0.0, %s.y), clamp(%s.w, -128.0, 128.0)), 1.0)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[0], srcs[0], srcs[0], writemask);
5451*bbecb9d1SAndroid Build Coastguard Worker       break;
5452*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_EX2:
5453*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("exp2");
5454*bbecb9d1SAndroid Build Coastguard Worker       break;
5455*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_LG2:
5456*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("log2");
5457*bbecb9d1SAndroid Build Coastguard Worker       break;
5458*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_EXP:
5459*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(vec4(pow(2.0, floor(%s.x)), %s.x - floor(%s.x), exp2(%s.x), 1.0)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[0], srcs[0], srcs[0], writemask);
5460*bbecb9d1SAndroid Build Coastguard Worker       break;
5461*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_LOG:
5462*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(vec4(floor(log2(%s.x)), %s.x / pow(2.0, floor(log2(%s.x))), log2(%s.x), 1.0)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[0], srcs[0], srcs[0], writemask);
5463*bbecb9d1SAndroid Build Coastguard Worker       break;
5464*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_COS:
5465*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("cos");
5466*bbecb9d1SAndroid Build Coastguard Worker       break;
5467*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SIN:
5468*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("sin");
5469*bbecb9d1SAndroid Build Coastguard Worker       break;
5470*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SCS:
5471*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(vec4(cos(%s.x), sin(%s.x), 0, 1)%s);\n", dsts[0], get_string(dinfo.dstconv),
5472*bbecb9d1SAndroid Build Coastguard Worker                srcs[0], srcs[0], writemask);
5473*bbecb9d1SAndroid Build Coastguard Worker       break;
5474*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DDX:
5475*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("dFdx");
5476*bbecb9d1SAndroid Build Coastguard Worker       break;
5477*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DDY:
5478*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("dFdy");
5479*bbecb9d1SAndroid Build Coastguard Worker       break;
5480*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DDX_FINE:
5481*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_DERIVATIVE_CONTROL;
5482*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("dFdxFine");
5483*bbecb9d1SAndroid Build Coastguard Worker       break;
5484*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DDY_FINE:
5485*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_DERIVATIVE_CONTROL;
5486*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("dFdyFine");
5487*bbecb9d1SAndroid Build Coastguard Worker       break;
5488*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_RCP:
5489*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(1.0/(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5490*bbecb9d1SAndroid Build Coastguard Worker       break;
5491*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DRCP:
5492*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(1.0LF/(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5493*bbecb9d1SAndroid Build Coastguard Worker       break;
5494*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_FLR:
5495*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DFLR:
5496*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("floor");
5497*bbecb9d1SAndroid Build Coastguard Worker       break;
5498*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ROUND:
5499*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DROUND:
5500*bbecb9d1SAndroid Build Coastguard Worker       // There is no TGSI OPCODE for roundEven, prefer roundEven
5501*bbecb9d1SAndroid Build Coastguard Worker       // so roundEven in guest gets translated to roundEven.
5502*bbecb9d1SAndroid Build Coastguard Worker       if ((ctx->cfg->use_gles && ctx->cfg->glsl_version >= 300) ||
5503*bbecb9d1SAndroid Build Coastguard Worker           ctx->cfg->glsl_version >= 400)
5504*bbecb9d1SAndroid Build Coastguard Worker          emit_op1("roundEven");
5505*bbecb9d1SAndroid Build Coastguard Worker       else
5506*bbecb9d1SAndroid Build Coastguard Worker          emit_op1("round");
5507*bbecb9d1SAndroid Build Coastguard Worker       break;
5508*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ISSG:
5509*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("sign");
5510*bbecb9d1SAndroid Build Coastguard Worker       break;
5511*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_CEIL:
5512*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DCEIL:
5513*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("ceil");
5514*bbecb9d1SAndroid Build Coastguard Worker       break;
5515*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_FRC:
5516*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DFRAC:
5517*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("fract");
5518*bbecb9d1SAndroid Build Coastguard Worker       break;
5519*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TRUNC:
5520*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DTRUNC:
5521*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("trunc");
5522*bbecb9d1SAndroid Build Coastguard Worker       break;
5523*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SSG:
5524*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DSSG:
5525*bbecb9d1SAndroid Build Coastguard Worker       emit_op1("sign");
5526*bbecb9d1SAndroid Build Coastguard Worker       break;
5527*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_RSQ:
5528*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DRSQ:
5529*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(inversesqrt(%s.x));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5530*bbecb9d1SAndroid Build Coastguard Worker       break;
5531*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_FBFETCH:
5532*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_MOV:
5533*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(%s%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], sinfo.override_no_wm[0] ? "" : writemask);
5534*bbecb9d1SAndroid Build Coastguard Worker       break;
5535*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ADD:
5536*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DADD:
5537*bbecb9d1SAndroid Build Coastguard Worker       emit_arit_op2("+");
5538*bbecb9d1SAndroid Build Coastguard Worker       break;
5539*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UADD:
5540*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(uvec4(%s) + uvec4(%s))%s);\n", dsts[0],
5541*bbecb9d1SAndroid Build Coastguard Worker             get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5542*bbecb9d1SAndroid Build Coastguard Worker       break;
5543*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SUB:
5544*bbecb9d1SAndroid Build Coastguard Worker       emit_arit_op2("-");
5545*bbecb9d1SAndroid Build Coastguard Worker       break;
5546*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_MUL:
5547*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DMUL:
5548*bbecb9d1SAndroid Build Coastguard Worker       emit_arit_op2("*");
5549*bbecb9d1SAndroid Build Coastguard Worker       break;
5550*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DIV:
5551*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DDIV:
5552*bbecb9d1SAndroid Build Coastguard Worker       emit_arit_op2("/");
5553*bbecb9d1SAndroid Build Coastguard Worker       break;
5554*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UMUL:
5555*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((uvec4(%s) * uvec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5556*bbecb9d1SAndroid Build Coastguard Worker       break;
5557*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UMOD:
5558*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((uvec4(%s) %% uvec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5559*bbecb9d1SAndroid Build Coastguard Worker       break;
5560*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_IDIV:
5561*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((ivec4(%s) / ivec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5562*bbecb9d1SAndroid Build Coastguard Worker       break;
5563*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UDIV:
5564*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((uvec4(%s) / uvec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
5565*bbecb9d1SAndroid Build Coastguard Worker       break;
5566*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ISHR:
5567*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_USHR:
5568*bbecb9d1SAndroid Build Coastguard Worker       emit_arit_op2(">>");
5569*bbecb9d1SAndroid Build Coastguard Worker       break;
5570*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SHL:
5571*bbecb9d1SAndroid Build Coastguard Worker       emit_arit_op2("<<");
5572*bbecb9d1SAndroid Build Coastguard Worker       break;
5573*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_MAD:
5574*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s((%s * %s + %s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1], srcs[2], writemask);
5575*bbecb9d1SAndroid Build Coastguard Worker       break;
5576*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UMAD:
5577*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DMAD:
5578*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s((%s * %s + %s)%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], srcs[2], writemask);
5579*bbecb9d1SAndroid Build Coastguard Worker       break;
5580*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_OR:
5581*bbecb9d1SAndroid Build Coastguard Worker       emit_arit_op2("|");
5582*bbecb9d1SAndroid Build Coastguard Worker       break;
5583*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_AND:
5584*bbecb9d1SAndroid Build Coastguard Worker       emit_arit_op2("&");
5585*bbecb9d1SAndroid Build Coastguard Worker       break;
5586*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_XOR:
5587*bbecb9d1SAndroid Build Coastguard Worker       emit_arit_op2("^");
5588*bbecb9d1SAndroid Build Coastguard Worker       break;
5589*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_MOD:
5590*bbecb9d1SAndroid Build Coastguard Worker       emit_arit_op2("%");
5591*bbecb9d1SAndroid Build Coastguard Worker       break;
5592*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TEX:
5593*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TEX2:
5594*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXB:
5595*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXL:
5596*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXB2:
5597*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXL2:
5598*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXD:
5599*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXF:
5600*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TG4:
5601*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXP:
5602*bbecb9d1SAndroid Build Coastguard Worker       translate_tex(ctx, inst, &sinfo, &dinfo, srcs, dsts[0], writemask);
5603*bbecb9d1SAndroid Build Coastguard Worker       break;
5604*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_LODQ:
5605*bbecb9d1SAndroid Build Coastguard Worker       emit_lodq(ctx, inst, &sinfo, &dinfo, srcs, dsts[0], writemask);
5606*bbecb9d1SAndroid Build Coastguard Worker       break;
5607*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXQ:
5608*bbecb9d1SAndroid Build Coastguard Worker       emit_txq(ctx, inst, sinfo.sreg_index, srcs, dsts[0], writemask);
5609*bbecb9d1SAndroid Build Coastguard Worker       break;
5610*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_TXQS:
5611*bbecb9d1SAndroid Build Coastguard Worker       emit_txqs(ctx, inst, sinfo.sreg_index, srcs, dsts[0]);
5612*bbecb9d1SAndroid Build Coastguard Worker       break;
5613*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_I2F:
5614*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(ivec4(%s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], writemask);
5615*bbecb9d1SAndroid Build Coastguard Worker       break;
5616*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_I2D:
5617*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(ivec4(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5618*bbecb9d1SAndroid Build Coastguard Worker       break;
5619*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_D2F:
5620*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5621*bbecb9d1SAndroid Build Coastguard Worker       break;
5622*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_U2F:
5623*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(uvec4(%s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], writemask);
5624*bbecb9d1SAndroid Build Coastguard Worker       break;
5625*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_U2D:
5626*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(uvec4(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5627*bbecb9d1SAndroid Build Coastguard Worker       break;
5628*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_F2I:
5629*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(ivec4(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], writemask);
5630*bbecb9d1SAndroid Build Coastguard Worker       break;
5631*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_D2I:
5632*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(%s(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), get_string(dinfo.idstconv), srcs[0]);
5633*bbecb9d1SAndroid Build Coastguard Worker       break;
5634*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_F2U:
5635*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(uvec4(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], writemask);
5636*bbecb9d1SAndroid Build Coastguard Worker       break;
5637*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_D2U:
5638*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(%s(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), get_string(dinfo.udstconv), srcs[0]);
5639*bbecb9d1SAndroid Build Coastguard Worker       break;
5640*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_F2D:
5641*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
5642*bbecb9d1SAndroid Build Coastguard Worker       break;
5643*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_NOT:
5644*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(uintBitsToFloat(~(uvec4(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5645*bbecb9d1SAndroid Build Coastguard Worker       break;
5646*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_INEG:
5647*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(intBitsToFloat(-(ivec4(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5648*bbecb9d1SAndroid Build Coastguard Worker       break;
5649*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DNEG:
5650*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(-%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
5651*bbecb9d1SAndroid Build Coastguard Worker       break;
5652*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SEQ:
5653*bbecb9d1SAndroid Build Coastguard Worker       emit_compare("equal");
5654*bbecb9d1SAndroid Build Coastguard Worker       break;
5655*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_USEQ:
5656*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_FSEQ:
5657*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DSEQ:
5658*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Instruction.Opcode == TGSI_OPCODE_DSEQ)
5659*bbecb9d1SAndroid Build Coastguard Worker          strcpy(writemask, ".x");
5660*bbecb9d1SAndroid Build Coastguard Worker       emit_ucompare("equal");
5661*bbecb9d1SAndroid Build Coastguard Worker       break;
5662*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SLT:
5663*bbecb9d1SAndroid Build Coastguard Worker       emit_compare("lessThan");
5664*bbecb9d1SAndroid Build Coastguard Worker       break;
5665*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SLE:
5666*bbecb9d1SAndroid Build Coastguard Worker       emit_compare("lessThanEqual");
5667*bbecb9d1SAndroid Build Coastguard Worker       break;
5668*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SGT:
5669*bbecb9d1SAndroid Build Coastguard Worker       emit_compare("greaterThan");
5670*bbecb9d1SAndroid Build Coastguard Worker       break;
5671*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ISLT:
5672*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_USLT:
5673*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_FSLT:
5674*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DSLT:
5675*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Instruction.Opcode == TGSI_OPCODE_DSLT)
5676*bbecb9d1SAndroid Build Coastguard Worker          strcpy(writemask, ".x");
5677*bbecb9d1SAndroid Build Coastguard Worker       emit_ucompare("lessThan");
5678*bbecb9d1SAndroid Build Coastguard Worker       break;
5679*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SNE:
5680*bbecb9d1SAndroid Build Coastguard Worker       emit_compare("notEqual");
5681*bbecb9d1SAndroid Build Coastguard Worker       break;
5682*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_USNE:
5683*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_FSNE:
5684*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DSNE:
5685*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Instruction.Opcode == TGSI_OPCODE_DSNE)
5686*bbecb9d1SAndroid Build Coastguard Worker          strcpy(writemask, ".x");
5687*bbecb9d1SAndroid Build Coastguard Worker       emit_ucompare("notEqual");
5688*bbecb9d1SAndroid Build Coastguard Worker       break;
5689*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_SGE:
5690*bbecb9d1SAndroid Build Coastguard Worker       emit_compare("greaterThanEqual");
5691*bbecb9d1SAndroid Build Coastguard Worker       break;
5692*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ISGE:
5693*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_USGE:
5694*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_FSGE:
5695*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_DSGE:
5696*bbecb9d1SAndroid Build Coastguard Worker       if (inst->Instruction.Opcode == TGSI_OPCODE_DSGE)
5697*bbecb9d1SAndroid Build Coastguard Worker           strcpy(writemask, ".x");
5698*bbecb9d1SAndroid Build Coastguard Worker       emit_ucompare("greaterThanEqual");
5699*bbecb9d1SAndroid Build Coastguard Worker       break;
5700*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_POW:
5701*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(pow(%s, %s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5702*bbecb9d1SAndroid Build Coastguard Worker       break;
5703*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_CMP:
5704*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = mix(%s, %s, greaterThanEqual(%s, vec4(0.0)))%s;\n", dsts[0], srcs[1], srcs[2], srcs[0], writemask);
5705*bbecb9d1SAndroid Build Coastguard Worker       break;
5706*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UCMP:
5707*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = mix(%s, %s, notEqual(floatBitsToUint(%s), uvec4(0.0)))%s;\n", dsts[0], srcs[2], srcs[1], srcs[0], writemask);
5708*bbecb9d1SAndroid Build Coastguard Worker       break;
5709*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_END:
5710*bbecb9d1SAndroid Build Coastguard Worker       if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
5711*bbecb9d1SAndroid Build Coastguard Worker          handle_vertex_proc_exit(ctx, &ctx->glsl_strbufs, &ctx->has_clipvertex_so);
5712*bbecb9d1SAndroid Build Coastguard Worker       } else if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL && ctx->cfg->has_cull_distance) {
5713*bbecb9d1SAndroid Build Coastguard Worker          emit_clip_dist_movs(ctx, &ctx->glsl_strbufs);
5714*bbecb9d1SAndroid Build Coastguard Worker       } else if (iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL && ctx->cfg->has_cull_distance) {
5715*bbecb9d1SAndroid Build Coastguard Worker 	 if (ctx->so && !ctx->key->gs_present)
5716*bbecb9d1SAndroid Build Coastguard Worker             emit_so_movs(ctx, &ctx->glsl_strbufs, &ctx->has_clipvertex_so);
5717*bbecb9d1SAndroid Build Coastguard Worker          emit_clip_dist_movs(ctx, &ctx->glsl_strbufs);
5718*bbecb9d1SAndroid Build Coastguard Worker          if (!ctx->key->gs_present) {
5719*bbecb9d1SAndroid Build Coastguard Worker             emit_prescale(&ctx->glsl_strbufs);
5720*bbecb9d1SAndroid Build Coastguard Worker          }
5721*bbecb9d1SAndroid Build Coastguard Worker       } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
5722*bbecb9d1SAndroid Build Coastguard Worker          handle_fragment_proc_exit(ctx, &ctx->glsl_strbufs);
5723*bbecb9d1SAndroid Build Coastguard Worker       }
5724*bbecb9d1SAndroid Build Coastguard Worker       emit_buf(&ctx->glsl_strbufs, "}\n");
5725*bbecb9d1SAndroid Build Coastguard Worker       break;
5726*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_RET:
5727*bbecb9d1SAndroid Build Coastguard Worker       if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
5728*bbecb9d1SAndroid Build Coastguard Worker          handle_vertex_proc_exit(ctx, &ctx->glsl_strbufs, &ctx->has_clipvertex_so);
5729*bbecb9d1SAndroid Build Coastguard Worker       } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
5730*bbecb9d1SAndroid Build Coastguard Worker          handle_fragment_proc_exit(ctx, &ctx->glsl_strbufs);
5731*bbecb9d1SAndroid Build Coastguard Worker       }
5732*bbecb9d1SAndroid Build Coastguard Worker       emit_buf(&ctx->glsl_strbufs, "return;\n");
5733*bbecb9d1SAndroid Build Coastguard Worker       break;
5734*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ARL:
5735*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = int(floor(%s)%s);\n", dsts[0], srcs[0], writemask);
5736*bbecb9d1SAndroid Build Coastguard Worker       break;
5737*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UARL:
5738*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = int(%s);\n", dsts[0], srcs[0]);
5739*bbecb9d1SAndroid Build Coastguard Worker       break;
5740*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_XPD:
5741*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(cross(vec3(%s), vec3(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
5742*bbecb9d1SAndroid Build Coastguard Worker       break;
5743*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_BGNLOOP:
5744*bbecb9d1SAndroid Build Coastguard Worker       emit_buf(&ctx->glsl_strbufs, "do {\n");
5745*bbecb9d1SAndroid Build Coastguard Worker       indent_buf(&ctx->glsl_strbufs);
5746*bbecb9d1SAndroid Build Coastguard Worker       break;
5747*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ENDLOOP:
5748*bbecb9d1SAndroid Build Coastguard Worker       outdent_buf(&ctx->glsl_strbufs);
5749*bbecb9d1SAndroid Build Coastguard Worker       emit_buf(&ctx->glsl_strbufs, "} while(true);\n");
5750*bbecb9d1SAndroid Build Coastguard Worker       break;
5751*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_BRK:
5752*bbecb9d1SAndroid Build Coastguard Worker       emit_buf(&ctx->glsl_strbufs, "break;\n");
5753*bbecb9d1SAndroid Build Coastguard Worker       break;
5754*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_EMIT: {
5755*bbecb9d1SAndroid Build Coastguard Worker       struct immed *imd = &ctx->imm[(inst->Src[0].Register.Index)];
5756*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->so && ctx->key->gs_present)
5757*bbecb9d1SAndroid Build Coastguard Worker          emit_so_movs(ctx, &ctx->glsl_strbufs, &ctx->has_clipvertex_so);
5758*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->has_cull_distance && ctx->key->gs.emit_clip_distance)
5759*bbecb9d1SAndroid Build Coastguard Worker          emit_clip_dist_movs(ctx, &ctx->glsl_strbufs);
5760*bbecb9d1SAndroid Build Coastguard Worker       emit_prescale(&ctx->glsl_strbufs);
5761*bbecb9d1SAndroid Build Coastguard Worker       if (imd->val[inst->Src[0].Register.SwizzleX].ui > 0) {
5762*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5763*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "EmitStreamVertex(%d);\n", imd->val[inst->Src[0].Register.SwizzleX].ui);
5764*bbecb9d1SAndroid Build Coastguard Worker       } else
5765*bbecb9d1SAndroid Build Coastguard Worker          emit_buf(&ctx->glsl_strbufs, "EmitVertex();\n");
5766*bbecb9d1SAndroid Build Coastguard Worker       break;
5767*bbecb9d1SAndroid Build Coastguard Worker    }
5768*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ENDPRIM: {
5769*bbecb9d1SAndroid Build Coastguard Worker       struct immed *imd = &ctx->imm[(inst->Src[0].Register.Index)];
5770*bbecb9d1SAndroid Build Coastguard Worker       if (imd->val[inst->Src[0].Register.SwizzleX].ui > 0) {
5771*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5772*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "EndStreamPrimitive(%d);\n", imd->val[inst->Src[0].Register.SwizzleX].ui);
5773*bbecb9d1SAndroid Build Coastguard Worker       } else
5774*bbecb9d1SAndroid Build Coastguard Worker          emit_buf(&ctx->glsl_strbufs, "EndPrimitive();\n");
5775*bbecb9d1SAndroid Build Coastguard Worker       break;
5776*bbecb9d1SAndroid Build Coastguard Worker    }
5777*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_INTERP_CENTROID:
5778*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(interpolateAtCentroid(%s)%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], src_swizzle0);
5779*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5780*bbecb9d1SAndroid Build Coastguard Worker       break;
5781*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_INTERP_SAMPLE:
5782*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(interpolateAtSample(%s, %s.x)%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], src_swizzle0);
5783*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5784*bbecb9d1SAndroid Build Coastguard Worker       break;
5785*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_INTERP_OFFSET:
5786*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(vec4(interpolateAtOffset(%s, %s.xy)%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], src_swizzle0);
5787*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5788*bbecb9d1SAndroid Build Coastguard Worker       break;
5789*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UMUL_HI:
5790*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "umulExtended(%s, %s, umul_temp, mul_utemp);\n", srcs[0], srcs[1]);
5791*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(umul_temp%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), writemask);
5792*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles) {
5793*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->cfg->has_gpu_shader5)
5794*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5795*bbecb9d1SAndroid Build Coastguard Worker          else
5796*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_SHADER_INTEGER_FUNC;
5797*bbecb9d1SAndroid Build Coastguard Worker       }
5798*bbecb9d1SAndroid Build Coastguard Worker       ctx->write_mul_utemp = true;
5799*bbecb9d1SAndroid Build Coastguard Worker       break;
5800*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_IMUL_HI:
5801*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "imulExtended(%s, %s, imul_temp, mul_itemp);\n", srcs[0], srcs[1]);
5802*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(imul_temp%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), writemask);
5803*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles) {
5804*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->cfg->has_gpu_shader5)
5805*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5806*bbecb9d1SAndroid Build Coastguard Worker          else
5807*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_SHADER_INTEGER_FUNC;
5808*bbecb9d1SAndroid Build Coastguard Worker       }
5809*bbecb9d1SAndroid Build Coastguard Worker       ctx->write_mul_itemp = true;
5810*bbecb9d1SAndroid Build Coastguard Worker       break;
5811*bbecb9d1SAndroid Build Coastguard Worker 
5812*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_IBFE:
5813*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(bitfieldExtract(%s, int(%s.x), int(%s.x))));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], srcs[2]);
5814*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5815*bbecb9d1SAndroid Build Coastguard Worker       break;
5816*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UBFE:
5817*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(bitfieldExtract(%s, int(%s.x), int(%s.x))));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], srcs[2]);
5818*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5819*bbecb9d1SAndroid Build Coastguard Worker       break;
5820*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_BFI:
5821*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(uintBitsToFloat(bitfieldInsert(%s, %s, int(%s), int(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1], srcs[2], srcs[3]);
5822*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5823*bbecb9d1SAndroid Build Coastguard Worker       break;
5824*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_BREV:
5825*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(bitfieldReverse(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
5826*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5827*bbecb9d1SAndroid Build Coastguard Worker       break;
5828*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_POPC:
5829*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(bitCount(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
5830*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5831*bbecb9d1SAndroid Build Coastguard Worker       break;
5832*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_LSB:
5833*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(findLSB(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
5834*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5835*bbecb9d1SAndroid Build Coastguard Worker       break;
5836*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_IMSB:
5837*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_UMSB:
5838*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(findMSB(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
5839*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
5840*bbecb9d1SAndroid Build Coastguard Worker       break;
5841*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_BARRIER:
5842*bbecb9d1SAndroid Build Coastguard Worker       emit_buf(&ctx->glsl_strbufs, "barrier();\n");
5843*bbecb9d1SAndroid Build Coastguard Worker       break;
5844*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_MEMBAR: {
5845*bbecb9d1SAndroid Build Coastguard Worker       struct immed *imd = &ctx->imm[(inst->Src[0].Register.Index)];
5846*bbecb9d1SAndroid Build Coastguard Worker       uint32_t val = imd->val[inst->Src[0].Register.SwizzleX].ui;
5847*bbecb9d1SAndroid Build Coastguard Worker       uint32_t all_val = (TGSI_MEMBAR_SHADER_BUFFER |
5848*bbecb9d1SAndroid Build Coastguard Worker                           TGSI_MEMBAR_ATOMIC_BUFFER |
5849*bbecb9d1SAndroid Build Coastguard Worker                           TGSI_MEMBAR_SHADER_IMAGE |
5850*bbecb9d1SAndroid Build Coastguard Worker                           TGSI_MEMBAR_SHARED);
5851*bbecb9d1SAndroid Build Coastguard Worker 
5852*bbecb9d1SAndroid Build Coastguard Worker       if (val & TGSI_MEMBAR_THREAD_GROUP) {
5853*bbecb9d1SAndroid Build Coastguard Worker          emit_buf(&ctx->glsl_strbufs, "groupMemoryBarrier();\n");
5854*bbecb9d1SAndroid Build Coastguard Worker       } else {
5855*bbecb9d1SAndroid Build Coastguard Worker          if ((val & all_val) == all_val) {
5856*bbecb9d1SAndroid Build Coastguard Worker             emit_buf(&ctx->glsl_strbufs, "memoryBarrier();\n");
5857*bbecb9d1SAndroid Build Coastguard Worker             ctx->shader_req_bits |= SHADER_REQ_IMAGE_LOAD_STORE;
5858*bbecb9d1SAndroid Build Coastguard Worker          } else {
5859*bbecb9d1SAndroid Build Coastguard Worker             if (val & TGSI_MEMBAR_SHADER_BUFFER) {
5860*bbecb9d1SAndroid Build Coastguard Worker                emit_buf(&ctx->glsl_strbufs, "memoryBarrierBuffer();\n");
5861*bbecb9d1SAndroid Build Coastguard Worker             }
5862*bbecb9d1SAndroid Build Coastguard Worker             if (val & TGSI_MEMBAR_ATOMIC_BUFFER) {
5863*bbecb9d1SAndroid Build Coastguard Worker                emit_buf(&ctx->glsl_strbufs, "memoryBarrierAtomicCounter();\n");
5864*bbecb9d1SAndroid Build Coastguard Worker             }
5865*bbecb9d1SAndroid Build Coastguard Worker             if (val & TGSI_MEMBAR_SHADER_IMAGE) {
5866*bbecb9d1SAndroid Build Coastguard Worker                emit_buf(&ctx->glsl_strbufs, "memoryBarrierImage();\n");
5867*bbecb9d1SAndroid Build Coastguard Worker             }
5868*bbecb9d1SAndroid Build Coastguard Worker             if (val & TGSI_MEMBAR_SHARED) {
5869*bbecb9d1SAndroid Build Coastguard Worker                emit_buf(&ctx->glsl_strbufs, "memoryBarrierShared();\n");
5870*bbecb9d1SAndroid Build Coastguard Worker             }
5871*bbecb9d1SAndroid Build Coastguard Worker          }
5872*bbecb9d1SAndroid Build Coastguard Worker       }
5873*bbecb9d1SAndroid Build Coastguard Worker       break;
5874*bbecb9d1SAndroid Build Coastguard Worker    }
5875*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_STORE:
5876*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->use_gles) {
5877*bbecb9d1SAndroid Build Coastguard Worker          if (!rewrite_1d_image_coordinate(ctx->src_bufs + 1, inst))
5878*bbecb9d1SAndroid Build Coastguard Worker             return false;
5879*bbecb9d1SAndroid Build Coastguard Worker          srcs[1] = ctx->src_bufs[1].buf;
5880*bbecb9d1SAndroid Build Coastguard Worker       }
5881*bbecb9d1SAndroid Build Coastguard Worker       /* Don't try to write to dest with a negative index. */
5882*bbecb9d1SAndroid Build Coastguard Worker       if (dinfo.dest_index >= 0)
5883*bbecb9d1SAndroid Build Coastguard Worker          translate_store(ctx, &ctx->glsl_strbufs, ctx->ssbo_memory_qualifier, ctx->images,
5884*bbecb9d1SAndroid Build Coastguard Worker                          inst, &sinfo, srcs, &dinfo, dsts[0]);
5885*bbecb9d1SAndroid Build Coastguard Worker       break;
5886*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_LOAD:
5887*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->use_gles) {
5888*bbecb9d1SAndroid Build Coastguard Worker          if (!rewrite_1d_image_coordinate(ctx->src_bufs + 1, inst))
5889*bbecb9d1SAndroid Build Coastguard Worker             return false;
5890*bbecb9d1SAndroid Build Coastguard Worker          srcs[1] = ctx->src_bufs[1].buf;
5891*bbecb9d1SAndroid Build Coastguard Worker       }
5892*bbecb9d1SAndroid Build Coastguard Worker       /* Replace an obvious out-of-bounds load with loading zero. */
5893*bbecb9d1SAndroid Build Coastguard Worker       if (sinfo.sreg_index < 0 ||
5894*bbecb9d1SAndroid Build Coastguard Worker           !translate_load(ctx, &ctx->glsl_strbufs, ctx->ssbo_memory_qualifier, ctx->images,
5895*bbecb9d1SAndroid Build Coastguard Worker                           inst, &sinfo, &dinfo, srcs, dsts[0], writemask)) {
5896*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n", dsts[0], writemask);
5897*bbecb9d1SAndroid Build Coastguard Worker       }
5898*bbecb9d1SAndroid Build Coastguard Worker       break;
5899*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMUADD:
5900*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMXCHG:
5901*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMCAS:
5902*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMAND:
5903*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMOR:
5904*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMXOR:
5905*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMUMIN:
5906*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMUMAX:
5907*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMIMIN:
5908*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_ATOMIMAX:
5909*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->use_gles) {
5910*bbecb9d1SAndroid Build Coastguard Worker          if (!rewrite_1d_image_coordinate(ctx->src_bufs + 1, inst))
5911*bbecb9d1SAndroid Build Coastguard Worker             return false;
5912*bbecb9d1SAndroid Build Coastguard Worker          srcs[1] = ctx->src_bufs[1].buf;
5913*bbecb9d1SAndroid Build Coastguard Worker       }
5914*bbecb9d1SAndroid Build Coastguard Worker       translate_atomic(ctx, inst, &sinfo, srcs, dsts[0]);
5915*bbecb9d1SAndroid Build Coastguard Worker       break;
5916*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_RESQ:
5917*bbecb9d1SAndroid Build Coastguard Worker       translate_resq(ctx, inst, srcs, dsts[0], writemask);
5918*bbecb9d1SAndroid Build Coastguard Worker       break;
5919*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_OPCODE_CLOCK:
5920*bbecb9d1SAndroid Build Coastguard Worker       ctx->shader_req_bits |= SHADER_REQ_SHADER_CLOCK;
5921*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = uintBitsToFloat(clock2x32ARB());\n", dsts[0]);
5922*bbecb9d1SAndroid Build Coastguard Worker       break;
5923*bbecb9d1SAndroid Build Coastguard Worker    default:
5924*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf("failed to convert opcode %d\n", inst->Instruction.Opcode);
5925*bbecb9d1SAndroid Build Coastguard Worker       break;
5926*bbecb9d1SAndroid Build Coastguard Worker    }
5927*bbecb9d1SAndroid Build Coastguard Worker 
5928*bbecb9d1SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < 1; i++) {
5929*bbecb9d1SAndroid Build Coastguard Worker       enum tgsi_opcode_type dtype = tgsi_opcode_infer_dst_type(inst->Instruction.Opcode);
5930*bbecb9d1SAndroid Build Coastguard Worker       if (dtype == TGSI_TYPE_DOUBLE) {
5931*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx->glsl_strbufs, "%s = uintBitsToFloat(unpackDouble2x32(%s));\n", fp64_dsts[0], dsts[0]);
5932*bbecb9d1SAndroid Build Coastguard Worker       }
5933*bbecb9d1SAndroid Build Coastguard Worker    }
5934*bbecb9d1SAndroid Build Coastguard Worker    if (inst->Instruction.Saturate) {
5935*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx->glsl_strbufs, "%s = clamp(%s, 0.0, 1.0);\n", dsts[0], dsts[0]);
5936*bbecb9d1SAndroid Build Coastguard Worker    }
5937*bbecb9d1SAndroid Build Coastguard Worker 
5938*bbecb9d1SAndroid Build Coastguard Worker    if (strbuf_get_error(&ctx->glsl_strbufs.glsl_main))
5939*bbecb9d1SAndroid Build Coastguard Worker        return false;
5940*bbecb9d1SAndroid Build Coastguard Worker    return true;
5941*bbecb9d1SAndroid Build Coastguard Worker }
5942*bbecb9d1SAndroid Build Coastguard Worker 
5943*bbecb9d1SAndroid Build Coastguard Worker static boolean
prolog(struct tgsi_iterate_context * iter)5944*bbecb9d1SAndroid Build Coastguard Worker prolog(struct tgsi_iterate_context *iter)
5945*bbecb9d1SAndroid Build Coastguard Worker {
5946*bbecb9d1SAndroid Build Coastguard Worker    struct dump_ctx *ctx = (struct dump_ctx *)iter;
5947*bbecb9d1SAndroid Build Coastguard Worker 
5948*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->prog_type == (enum tgsi_processor_type) -1)
5949*bbecb9d1SAndroid Build Coastguard Worker       ctx->prog_type = iter->processor.Processor;
5950*bbecb9d1SAndroid Build Coastguard Worker 
5951*bbecb9d1SAndroid Build Coastguard Worker    if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX &&
5952*bbecb9d1SAndroid Build Coastguard Worker        ctx->key->gs_present)
5953*bbecb9d1SAndroid Build Coastguard Worker       ctx->glsl_ver_required = require_glsl_ver(ctx, 150);
5954*bbecb9d1SAndroid Build Coastguard Worker 
5955*bbecb9d1SAndroid Build Coastguard Worker    return true;
5956*bbecb9d1SAndroid Build Coastguard Worker }
5957*bbecb9d1SAndroid Build Coastguard Worker 
emit_ext(struct vrend_glsl_strbufs * glsl_strbufs,const char * name,const char * verb)5958*bbecb9d1SAndroid Build Coastguard Worker static void emit_ext(struct vrend_glsl_strbufs *glsl_strbufs, const char *name,
5959*bbecb9d1SAndroid Build Coastguard Worker                      const char *verb)
5960*bbecb9d1SAndroid Build Coastguard Worker {
5961*bbecb9d1SAndroid Build Coastguard Worker    emit_ver_extf(glsl_strbufs, "#extension GL_%s : %s\n", name, verb);
5962*bbecb9d1SAndroid Build Coastguard Worker }
5963*bbecb9d1SAndroid Build Coastguard Worker 
emit_header(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)5964*bbecb9d1SAndroid Build Coastguard Worker static void emit_header(const struct dump_ctx *ctx, struct vrend_glsl_strbufs *glsl_strbufs)
5965*bbecb9d1SAndroid Build Coastguard Worker {
5966*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->cfg->use_gles) {
5967*bbecb9d1SAndroid Build Coastguard Worker       emit_ver_extf(glsl_strbufs, "#version %d es\n", ctx->cfg->glsl_version);
5968*bbecb9d1SAndroid Build Coastguard Worker 
5969*bbecb9d1SAndroid Build Coastguard Worker       if ((ctx->shader_req_bits & SHADER_REQ_CLIP_DISTANCE) ||
5970*bbecb9d1SAndroid Build Coastguard Worker           (ctx->cfg->has_cull_distance && ctx->num_out_clip_dist == 0)) {
5971*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "EXT_clip_cull_distance", "require");
5972*bbecb9d1SAndroid Build Coastguard Worker       }
5973*bbecb9d1SAndroid Build Coastguard Worker 
5974*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_SAMPLER_MS)
5975*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "OES_texture_storage_multisample_2d_array", "require");
5976*bbecb9d1SAndroid Build Coastguard Worker 
5977*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_CONSERVATIVE_DEPTH)
5978*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "EXT_conservative_depth", "require");
5979*bbecb9d1SAndroid Build Coastguard Worker 
5980*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT) {
5981*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->shader_req_bits & SHADER_REQ_FBFETCH)
5982*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "EXT_shader_framebuffer_fetch", "require");
5983*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->shader_req_bits & SHADER_REQ_BLEND_EQUATION_ADVANCED)
5984*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "KHR_blend_equation_advanced", "require");
5985*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->cfg->has_dual_src_blend)
5986*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "EXT_blend_func_extended", "require");
5987*bbecb9d1SAndroid Build Coastguard Worker       }
5988*bbecb9d1SAndroid Build Coastguard Worker 
5989*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_VIEWPORT_IDX)
5990*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "OES_viewport_array", "require");
5991*bbecb9d1SAndroid Build Coastguard Worker 
5992*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY) {
5993*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "EXT_geometry_shader", "require");
5994*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->shader_req_bits & SHADER_REQ_PSIZE)
5995*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "OES_geometry_point_size", "enable");
5996*bbecb9d1SAndroid Build Coastguard Worker       }
5997*bbecb9d1SAndroid Build Coastguard Worker 
5998*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_NV_IMAGE_FORMATS)
5999*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "NV_image_formats", "require");
6000*bbecb9d1SAndroid Build Coastguard Worker 
6001*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_SEPERATE_SHADER_OBJECTS)
6002*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "EXT_separate_shader_objects", "require");
6003*bbecb9d1SAndroid Build Coastguard Worker 
6004*bbecb9d1SAndroid Build Coastguard Worker       if ((ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
6005*bbecb9d1SAndroid Build Coastguard Worker            ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL)) {
6006*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->cfg->glsl_version < 320)
6007*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "OES_tessellation_shader", "require");
6008*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "OES_tessellation_point_size", "enable");
6009*bbecb9d1SAndroid Build Coastguard Worker       }
6010*bbecb9d1SAndroid Build Coastguard Worker 
6011*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->cfg->glsl_version < 320) {
6012*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->shader_req_bits & SHADER_REQ_SAMPLER_BUF)
6013*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "EXT_texture_buffer", "require");
6014*bbecb9d1SAndroid Build Coastguard Worker          if (prefer_generic_io_block(ctx, io_in) || prefer_generic_io_block(ctx, io_out)) {
6015*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "OES_shader_io_blocks", "require");
6016*bbecb9d1SAndroid Build Coastguard Worker          }
6017*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->shader_req_bits & SHADER_REQ_SAMPLE_SHADING)
6018*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "OES_sample_variables", "require");
6019*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->shader_req_bits & SHADER_REQ_GPU_SHADER5) {
6020*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "OES_gpu_shader5", "require");
6021*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "OES_shader_multisample_interpolation",
6022*bbecb9d1SAndroid Build Coastguard Worker                            "require");
6023*bbecb9d1SAndroid Build Coastguard Worker          }
6024*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->shader_req_bits & SHADER_REQ_CUBE_ARRAY)
6025*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "OES_texture_cube_map_array", "require");
6026*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->shader_req_bits & SHADER_REQ_LAYER)
6027*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "EXT_geometry_shader", "require");
6028*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->shader_req_bits & SHADER_REQ_IMAGE_ATOMIC)
6029*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "OES_shader_image_atomic", "require");
6030*bbecb9d1SAndroid Build Coastguard Worker 
6031*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->shader_req_bits & SHADER_REQ_GEOMETRY_SHADER)
6032*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "EXT_geometry_shader", "require");
6033*bbecb9d1SAndroid Build Coastguard Worker       }
6034*bbecb9d1SAndroid Build Coastguard Worker 
6035*bbecb9d1SAndroid Build Coastguard Worker       if (logiop_require_inout(ctx->key)) {
6036*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->cfg->has_fbfetch_coherent)
6037*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "EXT_shader_framebuffer_fetch", "require");
6038*bbecb9d1SAndroid Build Coastguard Worker          else
6039*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, "EXT_shader_framebuffer_fetch_non_coherent", "require");
6040*bbecb9d1SAndroid Build Coastguard Worker 
6041*bbecb9d1SAndroid Build Coastguard Worker       }
6042*bbecb9d1SAndroid Build Coastguard Worker 
6043*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_TEXTURE_SHADOW_LOD)
6044*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "EXT_texture_shadow_lod", "require");
6045*bbecb9d1SAndroid Build Coastguard Worker 
6046*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_LODQ)
6047*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "EXT_texture_query_lod", "require");
6048*bbecb9d1SAndroid Build Coastguard Worker 
6049*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_SHADER_NOPERSPECTIVE_INTERPOLATION)
6050*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "NV_shader_noperspective_interpolation", "require");
6051*bbecb9d1SAndroid Build Coastguard Worker 
6052*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "precision highp float;\n");
6053*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "precision highp int;\n");
6054*bbecb9d1SAndroid Build Coastguard Worker    } else {
6055*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->prog_type == TGSI_PROCESSOR_COMPUTE) {
6056*bbecb9d1SAndroid Build Coastguard Worker          emit_ver_ext(glsl_strbufs, "#version 330\n");
6057*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_compute_shader", "require");
6058*bbecb9d1SAndroid Build Coastguard Worker       } else {
6059*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->glsl_ver_required > 150)
6060*bbecb9d1SAndroid Build Coastguard Worker             emit_ver_extf(glsl_strbufs, "#version %d\n", ctx->glsl_ver_required);
6061*bbecb9d1SAndroid Build Coastguard Worker          else if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
6062*bbecb9d1SAndroid Build Coastguard Worker              ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL ||
6063*bbecb9d1SAndroid Build Coastguard Worker              ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
6064*bbecb9d1SAndroid Build Coastguard Worker              ctx->glsl_ver_required == 150)
6065*bbecb9d1SAndroid Build Coastguard Worker             emit_ver_ext(glsl_strbufs, "#version 150\n");
6066*bbecb9d1SAndroid Build Coastguard Worker          else if (ctx->glsl_ver_required == 140)
6067*bbecb9d1SAndroid Build Coastguard Worker             emit_ver_ext(glsl_strbufs, "#version 140\n");
6068*bbecb9d1SAndroid Build Coastguard Worker          else
6069*bbecb9d1SAndroid Build Coastguard Worker             emit_ver_ext(glsl_strbufs, "#version 130\n");
6070*bbecb9d1SAndroid Build Coastguard Worker       }
6071*bbecb9d1SAndroid Build Coastguard Worker 
6072*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_ENHANCED_LAYOUTS)
6073*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_enhanced_layouts", "require");
6074*bbecb9d1SAndroid Build Coastguard Worker 
6075*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_SEPERATE_SHADER_OBJECTS)
6076*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_separate_shader_objects", "require");
6077*bbecb9d1SAndroid Build Coastguard Worker 
6078*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_EXPLICIT_ATTRIB_LOCATION)
6079*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_explicit_attrib_location", "require");
6080*bbecb9d1SAndroid Build Coastguard Worker 
6081*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->shader_req_bits & SHADER_REQ_ARRAYS_OF_ARRAYS)
6082*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_arrays_of_arrays", "require");
6083*bbecb9d1SAndroid Build Coastguard Worker 
6084*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
6085*bbecb9d1SAndroid Build Coastguard Worker           ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL)
6086*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_tessellation_shader", "require");
6087*bbecb9d1SAndroid Build Coastguard Worker 
6088*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->prog_type == TGSI_PROCESSOR_VERTEX && ctx->cfg->use_explicit_locations)
6089*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_explicit_attrib_location", "require");
6090*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && fs_emit_layout(ctx))
6091*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_fragment_coord_conventions", "require");
6092*bbecb9d1SAndroid Build Coastguard Worker 
6093*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->ubo_used_mask)
6094*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_uniform_buffer_object", "require");
6095*bbecb9d1SAndroid Build Coastguard Worker 
6096*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->num_cull_dist_prop || ctx->key->num_in_cull || ctx->key->num_out_cull)
6097*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_cull_distance", "require");
6098*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->ssbo_used_mask)
6099*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_shader_storage_buffer_object", "require");
6100*bbecb9d1SAndroid Build Coastguard Worker 
6101*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->num_abo) {
6102*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_shader_atomic_counters", "require");
6103*bbecb9d1SAndroid Build Coastguard Worker          emit_ext(glsl_strbufs, "ARB_shader_atomic_counter_ops", "require");
6104*bbecb9d1SAndroid Build Coastguard Worker       }
6105*bbecb9d1SAndroid Build Coastguard Worker 
6106*bbecb9d1SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < ARRAY_SIZE(shader_req_table); i++) {
6107*bbecb9d1SAndroid Build Coastguard Worker          if (shader_req_table[i].key == SHADER_REQ_SAMPLER_RECT && ctx->glsl_ver_required >= 140)
6108*bbecb9d1SAndroid Build Coastguard Worker             continue;
6109*bbecb9d1SAndroid Build Coastguard Worker 
6110*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->shader_req_bits & shader_req_table[i].key) {
6111*bbecb9d1SAndroid Build Coastguard Worker             emit_ext(glsl_strbufs, shader_req_table[i].string, "require");
6112*bbecb9d1SAndroid Build Coastguard Worker          }
6113*bbecb9d1SAndroid Build Coastguard Worker       }
6114*bbecb9d1SAndroid Build Coastguard Worker    }
6115*bbecb9d1SAndroid Build Coastguard Worker }
6116*bbecb9d1SAndroid Build Coastguard Worker 
vrend_shader_samplerreturnconv(enum tgsi_return_type type)6117*bbecb9d1SAndroid Build Coastguard Worker char vrend_shader_samplerreturnconv(enum tgsi_return_type type)
6118*bbecb9d1SAndroid Build Coastguard Worker {
6119*bbecb9d1SAndroid Build Coastguard Worker    switch (type) {
6120*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_RETURN_TYPE_SINT:
6121*bbecb9d1SAndroid Build Coastguard Worker       return 'i';
6122*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_RETURN_TYPE_UINT:
6123*bbecb9d1SAndroid Build Coastguard Worker       return 'u';
6124*bbecb9d1SAndroid Build Coastguard Worker    default:
6125*bbecb9d1SAndroid Build Coastguard Worker       return ' ';
6126*bbecb9d1SAndroid Build Coastguard Worker    }
6127*bbecb9d1SAndroid Build Coastguard Worker }
6128*bbecb9d1SAndroid Build Coastguard Worker 
vrend_shader_samplertypeconv(bool use_gles,int sampler_type)6129*bbecb9d1SAndroid Build Coastguard Worker const char *vrend_shader_samplertypeconv(bool use_gles, int sampler_type)
6130*bbecb9d1SAndroid Build Coastguard Worker {
6131*bbecb9d1SAndroid Build Coastguard Worker    switch (sampler_type) {
6132*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_BUFFER: return "Buffer";
6133*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_1D:
6134*bbecb9d1SAndroid Build Coastguard Worker       if (!use_gles)
6135*bbecb9d1SAndroid Build Coastguard Worker          return "1D";
6136*bbecb9d1SAndroid Build Coastguard Worker       /* fallthrough */
6137*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D: return "2D";
6138*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_3D: return "3D";
6139*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_CUBE: return "Cube";
6140*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_RECT: return use_gles ? "2D" : "2DRect";
6141*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW1D:
6142*bbecb9d1SAndroid Build Coastguard Worker       if (!use_gles) {
6143*bbecb9d1SAndroid Build Coastguard Worker          return "1DShadow";
6144*bbecb9d1SAndroid Build Coastguard Worker       }
6145*bbecb9d1SAndroid Build Coastguard Worker       /* fallthrough */
6146*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW2D: return "2DShadow";
6147*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWRECT:
6148*bbecb9d1SAndroid Build Coastguard Worker       return (!use_gles) ? "2DRectShadow" : "2DShadow";
6149*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_1D_ARRAY:
6150*bbecb9d1SAndroid Build Coastguard Worker       if (!use_gles)
6151*bbecb9d1SAndroid Build Coastguard Worker          return "1DArray";
6152*bbecb9d1SAndroid Build Coastguard Worker       /* fallthrough */
6153*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_ARRAY: return "2DArray";
6154*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW1D_ARRAY:
6155*bbecb9d1SAndroid Build Coastguard Worker       if (!use_gles) {
6156*bbecb9d1SAndroid Build Coastguard Worker          return "1DArrayShadow";
6157*bbecb9d1SAndroid Build Coastguard Worker       }
6158*bbecb9d1SAndroid Build Coastguard Worker       /* fallthrough */
6159*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOW2D_ARRAY: return "2DArrayShadow";
6160*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWCUBE: return "CubeShadow";
6161*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_CUBE_ARRAY: return "CubeArray";
6162*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_SHADOWCUBE_ARRAY: return "CubeArrayShadow";
6163*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_MSAA: return "2DMS";
6164*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_TEXTURE_2D_ARRAY_MSAA: return "2DMSArray";
6165*bbecb9d1SAndroid Build Coastguard Worker    default: return NULL;
6166*bbecb9d1SAndroid Build Coastguard Worker    }
6167*bbecb9d1SAndroid Build Coastguard Worker }
6168*bbecb9d1SAndroid Build Coastguard Worker 
get_interp_string(const struct vrend_shader_cfg * cfg,enum tgsi_interpolate_mode interpolate,bool flatshade)6169*bbecb9d1SAndroid Build Coastguard Worker static const char *get_interp_string(const struct vrend_shader_cfg *cfg, enum tgsi_interpolate_mode interpolate, bool flatshade)
6170*bbecb9d1SAndroid Build Coastguard Worker {
6171*bbecb9d1SAndroid Build Coastguard Worker    switch (interpolate) {
6172*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_INTERPOLATE_LINEAR:
6173*bbecb9d1SAndroid Build Coastguard Worker       if (cfg->has_nopersective)
6174*bbecb9d1SAndroid Build Coastguard Worker          return "noperspective ";
6175*bbecb9d1SAndroid Build Coastguard Worker       else
6176*bbecb9d1SAndroid Build Coastguard Worker          return "";
6177*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_INTERPOLATE_PERSPECTIVE:
6178*bbecb9d1SAndroid Build Coastguard Worker       return "smooth ";
6179*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_INTERPOLATE_CONSTANT:
6180*bbecb9d1SAndroid Build Coastguard Worker       return "flat ";
6181*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_INTERPOLATE_COLOR:
6182*bbecb9d1SAndroid Build Coastguard Worker       if (flatshade)
6183*bbecb9d1SAndroid Build Coastguard Worker          return "flat ";
6184*bbecb9d1SAndroid Build Coastguard Worker       /* fallthrough */
6185*bbecb9d1SAndroid Build Coastguard Worker    default:
6186*bbecb9d1SAndroid Build Coastguard Worker       return "";
6187*bbecb9d1SAndroid Build Coastguard Worker    }
6188*bbecb9d1SAndroid Build Coastguard Worker }
6189*bbecb9d1SAndroid Build Coastguard Worker 
get_aux_string(enum tgsi_interpolate_loc location)6190*bbecb9d1SAndroid Build Coastguard Worker static const char *get_aux_string(enum tgsi_interpolate_loc location)
6191*bbecb9d1SAndroid Build Coastguard Worker {
6192*bbecb9d1SAndroid Build Coastguard Worker    switch (location) {
6193*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_INTERPOLATE_LOC_CENTER:
6194*bbecb9d1SAndroid Build Coastguard Worker    default:
6195*bbecb9d1SAndroid Build Coastguard Worker       return "";
6196*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_INTERPOLATE_LOC_CENTROID:
6197*bbecb9d1SAndroid Build Coastguard Worker       return "centroid ";
6198*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_INTERPOLATE_LOC_SAMPLE:
6199*bbecb9d1SAndroid Build Coastguard Worker       return "sample ";
6200*bbecb9d1SAndroid Build Coastguard Worker    }
6201*bbecb9d1SAndroid Build Coastguard Worker }
6202*bbecb9d1SAndroid Build Coastguard Worker 
emit_sampler_decl(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,uint32_t * shadow_samp_mask,uint32_t i,uint32_t range,const struct vrend_shader_sampler * sampler)6203*bbecb9d1SAndroid Build Coastguard Worker static void emit_sampler_decl(const struct dump_ctx *ctx,
6204*bbecb9d1SAndroid Build Coastguard Worker                               struct vrend_glsl_strbufs *glsl_strbufs,
6205*bbecb9d1SAndroid Build Coastguard Worker                               uint32_t *shadow_samp_mask,
6206*bbecb9d1SAndroid Build Coastguard Worker                               uint32_t i, uint32_t range,
6207*bbecb9d1SAndroid Build Coastguard Worker                               const struct vrend_shader_sampler *sampler)
6208*bbecb9d1SAndroid Build Coastguard Worker {
6209*bbecb9d1SAndroid Build Coastguard Worker    char ptc;
6210*bbecb9d1SAndroid Build Coastguard Worker    bool is_shad;
6211*bbecb9d1SAndroid Build Coastguard Worker    const char *sname, *precision, *stc;
6212*bbecb9d1SAndroid Build Coastguard Worker 
6213*bbecb9d1SAndroid Build Coastguard Worker    sname = tgsi_proc_to_prefix(ctx->prog_type);
6214*bbecb9d1SAndroid Build Coastguard Worker 
6215*bbecb9d1SAndroid Build Coastguard Worker    precision = (ctx->cfg->use_gles) ? "highp" : "";
6216*bbecb9d1SAndroid Build Coastguard Worker 
6217*bbecb9d1SAndroid Build Coastguard Worker    ptc = vrend_shader_samplerreturnconv(sampler->tgsi_sampler_return);
6218*bbecb9d1SAndroid Build Coastguard Worker    stc = vrend_shader_samplertypeconv(ctx->cfg->use_gles, sampler->tgsi_sampler_type);
6219*bbecb9d1SAndroid Build Coastguard Worker    is_shad = samplertype_is_shadow(sampler->tgsi_sampler_type);
6220*bbecb9d1SAndroid Build Coastguard Worker 
6221*bbecb9d1SAndroid Build Coastguard Worker    if (range)
6222*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "uniform %s %csampler%s %ssamp%d[%d];\n", precision, ptc, stc, sname, i, range);
6223*bbecb9d1SAndroid Build Coastguard Worker    else
6224*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "uniform %s %csampler%s %ssamp%d;\n", precision, ptc, stc, sname, i);
6225*bbecb9d1SAndroid Build Coastguard Worker 
6226*bbecb9d1SAndroid Build Coastguard Worker    if (is_shad) {
6227*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "uniform %s vec4 %sshadmask%d;\n", precision, sname, i);
6228*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "uniform %s vec4 %sshadadd%d;\n", precision, sname, i);
6229*bbecb9d1SAndroid Build Coastguard Worker       *shadow_samp_mask |= (1 << i);
6230*bbecb9d1SAndroid Build Coastguard Worker    }
6231*bbecb9d1SAndroid Build Coastguard Worker }
6232*bbecb9d1SAndroid Build Coastguard Worker 
get_internalformat_string(int virgl_format,enum tgsi_return_type * stype)6233*bbecb9d1SAndroid Build Coastguard Worker const char *get_internalformat_string(int virgl_format, enum tgsi_return_type *stype)
6234*bbecb9d1SAndroid Build Coastguard Worker {
6235*bbecb9d1SAndroid Build Coastguard Worker    switch (virgl_format) {
6236*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R11G11B10_FLOAT:
6237*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_FLOAT;
6238*bbecb9d1SAndroid Build Coastguard Worker       return "r11f_g11f_b10f";
6239*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R10G10B10A2_UNORM:
6240*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UNORM;
6241*bbecb9d1SAndroid Build Coastguard Worker       return "rgb10_a2";
6242*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R10G10B10A2_UINT:
6243*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UINT;
6244*bbecb9d1SAndroid Build Coastguard Worker       return "rgb10_a2ui";
6245*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8_UNORM:
6246*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UNORM;
6247*bbecb9d1SAndroid Build Coastguard Worker       return "r8";
6248*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8_SNORM:
6249*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SNORM;
6250*bbecb9d1SAndroid Build Coastguard Worker       return "r8_snorm";
6251*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8_UINT:
6252*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UINT;
6253*bbecb9d1SAndroid Build Coastguard Worker       return "r8ui";
6254*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8_SINT:
6255*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SINT;
6256*bbecb9d1SAndroid Build Coastguard Worker       return "r8i";
6257*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8_UNORM:
6258*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UNORM;
6259*bbecb9d1SAndroid Build Coastguard Worker       return "rg8";
6260*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8_SNORM:
6261*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SNORM;
6262*bbecb9d1SAndroid Build Coastguard Worker       return "rg8_snorm";
6263*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8_UINT:
6264*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UINT;
6265*bbecb9d1SAndroid Build Coastguard Worker       return "rg8ui";
6266*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8_SINT:
6267*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SINT;
6268*bbecb9d1SAndroid Build Coastguard Worker       return "rg8i";
6269*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8B8A8_UNORM:
6270*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UNORM;
6271*bbecb9d1SAndroid Build Coastguard Worker       return "rgba8";
6272*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8B8A8_SNORM:
6273*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SNORM;
6274*bbecb9d1SAndroid Build Coastguard Worker       return "rgba8_snorm";
6275*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8B8A8_UINT:
6276*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UINT;
6277*bbecb9d1SAndroid Build Coastguard Worker       return "rgba8ui";
6278*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8B8A8_SINT:
6279*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SINT;
6280*bbecb9d1SAndroid Build Coastguard Worker       return "rgba8i";
6281*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16_UNORM:
6282*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UNORM;
6283*bbecb9d1SAndroid Build Coastguard Worker       return "r16";
6284*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16_SNORM:
6285*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SNORM;
6286*bbecb9d1SAndroid Build Coastguard Worker       return "r16_snorm";
6287*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16_UINT:
6288*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UINT;
6289*bbecb9d1SAndroid Build Coastguard Worker       return "r16ui";
6290*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16_SINT:
6291*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SINT;
6292*bbecb9d1SAndroid Build Coastguard Worker       return "r16i";
6293*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16_FLOAT:
6294*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_FLOAT;
6295*bbecb9d1SAndroid Build Coastguard Worker       return "r16f";
6296*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16G16_UNORM:
6297*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UNORM;
6298*bbecb9d1SAndroid Build Coastguard Worker       return "rg16";
6299*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16G16_SNORM:
6300*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SNORM;
6301*bbecb9d1SAndroid Build Coastguard Worker       return "rg16_snorm";
6302*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16G16_UINT:
6303*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UINT;
6304*bbecb9d1SAndroid Build Coastguard Worker       return "rg16ui";
6305*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16G16_SINT:
6306*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SINT;
6307*bbecb9d1SAndroid Build Coastguard Worker       return "rg16i";
6308*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16G16_FLOAT:
6309*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_FLOAT;
6310*bbecb9d1SAndroid Build Coastguard Worker       return "rg16f";
6311*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16G16B16A16_UNORM:
6312*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UNORM;
6313*bbecb9d1SAndroid Build Coastguard Worker       return "rgba16";
6314*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16G16B16A16_SNORM:
6315*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SNORM;
6316*bbecb9d1SAndroid Build Coastguard Worker       return "rgba16_snorm";
6317*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16G16B16A16_FLOAT:
6318*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_FLOAT;
6319*bbecb9d1SAndroid Build Coastguard Worker       return "rgba16f";
6320*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R32_FLOAT:
6321*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_FLOAT;
6322*bbecb9d1SAndroid Build Coastguard Worker       return "r32f";
6323*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R32_UINT:
6324*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UINT;
6325*bbecb9d1SAndroid Build Coastguard Worker       return "r32ui";
6326*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R32_SINT:
6327*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SINT;
6328*bbecb9d1SAndroid Build Coastguard Worker       return "r32i";
6329*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R32G32_FLOAT:
6330*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_FLOAT;
6331*bbecb9d1SAndroid Build Coastguard Worker       return "rg32f";
6332*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R32G32_UINT:
6333*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UINT;
6334*bbecb9d1SAndroid Build Coastguard Worker       return "rg32ui";
6335*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R32G32_SINT:
6336*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SINT;
6337*bbecb9d1SAndroid Build Coastguard Worker       return "rg32i";
6338*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R32G32B32A32_FLOAT:
6339*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_FLOAT;
6340*bbecb9d1SAndroid Build Coastguard Worker       return "rgba32f";
6341*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R32G32B32A32_UINT:
6342*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UINT;
6343*bbecb9d1SAndroid Build Coastguard Worker       return "rgba32ui";
6344*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16G16B16A16_UINT:
6345*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UINT;
6346*bbecb9d1SAndroid Build Coastguard Worker       return "rgba16ui";
6347*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16G16B16A16_SINT:
6348*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SINT;
6349*bbecb9d1SAndroid Build Coastguard Worker       return "rgba16i";
6350*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_R32G32B32A32_SINT:
6351*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_SINT;
6352*bbecb9d1SAndroid Build Coastguard Worker       return "rgba32i";
6353*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FORMAT_NONE:
6354*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UNORM;
6355*bbecb9d1SAndroid Build Coastguard Worker       return "";
6356*bbecb9d1SAndroid Build Coastguard Worker    default:
6357*bbecb9d1SAndroid Build Coastguard Worker       *stype = TGSI_RETURN_TYPE_UNORM;
6358*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf( "illegal format %d\n", virgl_format);
6359*bbecb9d1SAndroid Build Coastguard Worker       return "";
6360*bbecb9d1SAndroid Build Coastguard Worker    }
6361*bbecb9d1SAndroid Build Coastguard Worker }
6362*bbecb9d1SAndroid Build Coastguard Worker 
emit_image_decl(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,uint32_t i,uint32_t range,const struct vrend_shader_image * image)6363*bbecb9d1SAndroid Build Coastguard Worker static void emit_image_decl(const struct dump_ctx *ctx,
6364*bbecb9d1SAndroid Build Coastguard Worker                             struct vrend_glsl_strbufs *glsl_strbufs,
6365*bbecb9d1SAndroid Build Coastguard Worker                             uint32_t i, uint32_t range,
6366*bbecb9d1SAndroid Build Coastguard Worker                             const struct vrend_shader_image *image)
6367*bbecb9d1SAndroid Build Coastguard Worker {
6368*bbecb9d1SAndroid Build Coastguard Worker    char ptc;
6369*bbecb9d1SAndroid Build Coastguard Worker    const char *sname, *stc, *formatstr;
6370*bbecb9d1SAndroid Build Coastguard Worker    enum tgsi_return_type itype;
6371*bbecb9d1SAndroid Build Coastguard Worker    const char *volatile_str = image->vflag ? "volatile " : "";
6372*bbecb9d1SAndroid Build Coastguard Worker    const char *coherent_str = image->coherent ? "coherent " : "";
6373*bbecb9d1SAndroid Build Coastguard Worker    const char *precision = ctx->cfg->use_gles ? "highp " : "";
6374*bbecb9d1SAndroid Build Coastguard Worker    const char *access = "";
6375*bbecb9d1SAndroid Build Coastguard Worker    formatstr = get_internalformat_string(image->decl.Format, &itype);
6376*bbecb9d1SAndroid Build Coastguard Worker    ptc = vrend_shader_samplerreturnconv(itype);
6377*bbecb9d1SAndroid Build Coastguard Worker    sname = tgsi_proc_to_prefix(ctx->prog_type);
6378*bbecb9d1SAndroid Build Coastguard Worker    stc = vrend_shader_samplertypeconv(ctx->cfg->use_gles, image->decl.Resource);
6379*bbecb9d1SAndroid Build Coastguard Worker 
6380*bbecb9d1SAndroid Build Coastguard Worker 
6381*bbecb9d1SAndroid Build Coastguard Worker    /* From ARB_shader_image_load_store:
6382*bbecb9d1SAndroid Build Coastguard Worker       Any image variable used for shader loads or atomic memory operations must
6383*bbecb9d1SAndroid Build Coastguard Worker       be declared with a format layout qualifier matching the format of its
6384*bbecb9d1SAndroid Build Coastguard Worker       associated image unit, ...  Otherwise, the access is considered to
6385*bbecb9d1SAndroid Build Coastguard Worker       involve a format mismatch, ...  Image variables used exclusively for
6386*bbecb9d1SAndroid Build Coastguard Worker       image stores need not include a format layout qualifier, but any declared
6387*bbecb9d1SAndroid Build Coastguard Worker       qualifier must match the image unit format to avoid a format mismatch. */
6388*bbecb9d1SAndroid Build Coastguard Worker    bool require_format_specifer = true;
6389*bbecb9d1SAndroid Build Coastguard Worker    if (!image->decl.Writable) {
6390*bbecb9d1SAndroid Build Coastguard Worker       access = "readonly ";
6391*bbecb9d1SAndroid Build Coastguard Worker    } else if (!image->decl.Format ||
6392*bbecb9d1SAndroid Build Coastguard Worker             (ctx->cfg->use_gles &&
6393*bbecb9d1SAndroid Build Coastguard Worker              (image->decl.Format != PIPE_FORMAT_R32_FLOAT) &&
6394*bbecb9d1SAndroid Build Coastguard Worker              (image->decl.Format != PIPE_FORMAT_R32_SINT) &&
6395*bbecb9d1SAndroid Build Coastguard Worker              (image->decl.Format != PIPE_FORMAT_R32_UINT))) {
6396*bbecb9d1SAndroid Build Coastguard Worker       access = "writeonly ";
6397*bbecb9d1SAndroid Build Coastguard Worker       require_format_specifer = formatstr[0] != '\0';
6398*bbecb9d1SAndroid Build Coastguard Worker    }
6399*bbecb9d1SAndroid Build Coastguard Worker 
6400*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->cfg->use_gles) { /* TODO: enable on OpenGL 4.2 and up also */
6401*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "layout(binding=%d%s%s) ",
6402*bbecb9d1SAndroid Build Coastguard Worker                i, formatstr[0] != '\0' ? ", " : ", rgba32f", formatstr);
6403*bbecb9d1SAndroid Build Coastguard Worker    } else if (require_format_specifer) {
6404*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "layout(%s) ",
6405*bbecb9d1SAndroid Build Coastguard Worker                 formatstr[0] != '\0' ? formatstr : "rgba32f");
6406*bbecb9d1SAndroid Build Coastguard Worker    }
6407*bbecb9d1SAndroid Build Coastguard Worker 
6408*bbecb9d1SAndroid Build Coastguard Worker    if (range)
6409*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "%s%s%suniform %s%cimage%s %simg%d[%d];\n",
6410*bbecb9d1SAndroid Build Coastguard Worker                access, volatile_str, coherent_str, precision, ptc, stc, sname, i, range);
6411*bbecb9d1SAndroid Build Coastguard Worker    else
6412*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "%s%s%suniform %s%cimage%s %simg%d;\n",
6413*bbecb9d1SAndroid Build Coastguard Worker                access, volatile_str, coherent_str, precision, ptc, stc, sname, i);
6414*bbecb9d1SAndroid Build Coastguard Worker }
6415*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_common(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,uint32_t * shadow_samp_mask)6416*bbecb9d1SAndroid Build Coastguard Worker static int emit_ios_common(const struct dump_ctx *ctx,
6417*bbecb9d1SAndroid Build Coastguard Worker                            struct vrend_glsl_strbufs *glsl_strbufs,
6418*bbecb9d1SAndroid Build Coastguard Worker                            uint32_t *shadow_samp_mask)
6419*bbecb9d1SAndroid Build Coastguard Worker {
6420*bbecb9d1SAndroid Build Coastguard Worker    uint i;
6421*bbecb9d1SAndroid Build Coastguard Worker    const char *sname = tgsi_proc_to_prefix(ctx->prog_type);
6422*bbecb9d1SAndroid Build Coastguard Worker    int glsl_ver_required = ctx->glsl_ver_required;
6423*bbecb9d1SAndroid Build Coastguard Worker 
6424*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_temp_ranges; i++) {
6425*bbecb9d1SAndroid Build Coastguard Worker       const char *precise = ctx->temp_ranges[i].precise_result ? "precise" : "";
6426*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->temp_ranges[i].array_id > 0) {
6427*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "%s vec4 temp%d[%d];\n", precise, ctx->temp_ranges[i].first,
6428*bbecb9d1SAndroid Build Coastguard Worker                    ctx->temp_ranges[i].last - ctx->temp_ranges[i].first + 1);
6429*bbecb9d1SAndroid Build Coastguard Worker       } else {
6430*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "%s vec4 temp%d;\n", precise, ctx->temp_ranges[i].first);
6431*bbecb9d1SAndroid Build Coastguard Worker       }
6432*bbecb9d1SAndroid Build Coastguard Worker    }
6433*bbecb9d1SAndroid Build Coastguard Worker 
6434*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->require_dummy_value)
6435*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "vec4 dummy_value = vec4(0.0, 0.0, 0.0, 0.0);\n");
6436*bbecb9d1SAndroid Build Coastguard Worker 
6437*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->write_mul_utemp) {
6438*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "uvec4 mul_utemp;\n");
6439*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "uvec4 umul_temp;\n");
6440*bbecb9d1SAndroid Build Coastguard Worker    }
6441*bbecb9d1SAndroid Build Coastguard Worker 
6442*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->write_mul_itemp) {
6443*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "ivec4 mul_itemp;\n");
6444*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "ivec4 imul_temp;\n");
6445*bbecb9d1SAndroid Build Coastguard Worker    }
6446*bbecb9d1SAndroid Build Coastguard Worker 
6447*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->ssbo_used_mask || ctx->has_file_memory) {
6448*bbecb9d1SAndroid Build Coastguard Worker      emit_hdr(glsl_strbufs, "uint ssbo_addr_temp;\n");
6449*bbecb9d1SAndroid Build Coastguard Worker    }
6450*bbecb9d1SAndroid Build Coastguard Worker 
6451*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->shader_req_bits & SHADER_REQ_FP64) {
6452*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "dvec2 fp64_dst[3];\n");
6453*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "dvec2 fp64_src[4];\n");
6454*bbecb9d1SAndroid Build Coastguard Worker    }
6455*bbecb9d1SAndroid Build Coastguard Worker 
6456*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_address; i++) {
6457*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "int addr%d;\n", i);
6458*bbecb9d1SAndroid Build Coastguard Worker    }
6459*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->num_consts) {
6460*bbecb9d1SAndroid Build Coastguard Worker       const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
6461*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "uniform uvec4 %sconst0[%d];\n", cname, ctx->num_consts);
6462*bbecb9d1SAndroid Build Coastguard Worker    }
6463*bbecb9d1SAndroid Build Coastguard Worker 
6464*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->ubo_used_mask) {
6465*bbecb9d1SAndroid Build Coastguard Worker       const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
6466*bbecb9d1SAndroid Build Coastguard Worker 
6467*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT)) {
6468*bbecb9d1SAndroid Build Coastguard Worker          glsl_ver_required = require_glsl_ver(ctx, 150);
6469*bbecb9d1SAndroid Build Coastguard Worker          int first = ffs(ctx->ubo_used_mask) - 1;
6470*bbecb9d1SAndroid Build Coastguard Worker          unsigned num_ubo = util_bitcount(ctx->ubo_used_mask);
6471*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "uniform %subo { vec4 ubocontents[%d]; } %suboarr[%d];\n", cname, ctx->ubo_sizes[first], cname, num_ubo);
6472*bbecb9d1SAndroid Build Coastguard Worker       } else {
6473*bbecb9d1SAndroid Build Coastguard Worker          unsigned mask = ctx->ubo_used_mask;
6474*bbecb9d1SAndroid Build Coastguard Worker          while (mask) {
6475*bbecb9d1SAndroid Build Coastguard Worker             uint32_t i = u_bit_scan(&mask);
6476*bbecb9d1SAndroid Build Coastguard Worker             emit_hdrf(glsl_strbufs, "uniform %subo%d { vec4 %subo%dcontents[%d]; };\n", cname, i, cname, i, ctx->ubo_sizes[i]);
6477*bbecb9d1SAndroid Build Coastguard Worker          }
6478*bbecb9d1SAndroid Build Coastguard Worker       }
6479*bbecb9d1SAndroid Build Coastguard Worker    }
6480*bbecb9d1SAndroid Build Coastguard Worker 
6481*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
6482*bbecb9d1SAndroid Build Coastguard Worker       for (i = 0; i < ctx->num_sampler_arrays; i++) {
6483*bbecb9d1SAndroid Build Coastguard Worker          uint32_t first = ctx->sampler_arrays[i].first;
6484*bbecb9d1SAndroid Build Coastguard Worker          uint32_t range = ctx->sampler_arrays[i].array_size;
6485*bbecb9d1SAndroid Build Coastguard Worker 
6486*bbecb9d1SAndroid Build Coastguard Worker          emit_sampler_decl(ctx, glsl_strbufs, shadow_samp_mask, first, range, ctx->samplers + first);
6487*bbecb9d1SAndroid Build Coastguard Worker       }
6488*bbecb9d1SAndroid Build Coastguard Worker    } else {
6489*bbecb9d1SAndroid Build Coastguard Worker       uint nsamp = util_last_bit(ctx->samplers_used);
6490*bbecb9d1SAndroid Build Coastguard Worker       for (i = 0; i < nsamp; i++) {
6491*bbecb9d1SAndroid Build Coastguard Worker 
6492*bbecb9d1SAndroid Build Coastguard Worker          if ((ctx->samplers_used & (1 << i)) == 0)
6493*bbecb9d1SAndroid Build Coastguard Worker             continue;
6494*bbecb9d1SAndroid Build Coastguard Worker 
6495*bbecb9d1SAndroid Build Coastguard Worker          emit_sampler_decl(ctx, glsl_strbufs, shadow_samp_mask, i, 0, ctx->samplers + i);
6496*bbecb9d1SAndroid Build Coastguard Worker       }
6497*bbecb9d1SAndroid Build Coastguard Worker    }
6498*bbecb9d1SAndroid Build Coastguard Worker 
6499*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->cfg->use_gles && ctx->gles_use_tex_query_level)
6500*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "uniform int %s_texlod[%d];\n", tgsi_proc_to_prefix(ctx->info.processor),
6501*bbecb9d1SAndroid Build Coastguard Worker                 util_bitcount(ctx->samplers_used));
6502*bbecb9d1SAndroid Build Coastguard Worker 
6503*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
6504*bbecb9d1SAndroid Build Coastguard Worker       for (i = 0; i < ctx->num_image_arrays; i++) {
6505*bbecb9d1SAndroid Build Coastguard Worker          uint32_t first = ctx->image_arrays[i].first;
6506*bbecb9d1SAndroid Build Coastguard Worker          uint32_t range = ctx->image_arrays[i].array_size;
6507*bbecb9d1SAndroid Build Coastguard Worker          emit_image_decl(ctx, glsl_strbufs, first, range, ctx->images + first);
6508*bbecb9d1SAndroid Build Coastguard Worker       }
6509*bbecb9d1SAndroid Build Coastguard Worker    } else {
6510*bbecb9d1SAndroid Build Coastguard Worker       uint32_t mask = ctx->images_used_mask;
6511*bbecb9d1SAndroid Build Coastguard Worker       while (mask) {
6512*bbecb9d1SAndroid Build Coastguard Worker          i = u_bit_scan(&mask);
6513*bbecb9d1SAndroid Build Coastguard Worker          emit_image_decl(ctx, glsl_strbufs, i, 0, ctx->images + i);
6514*bbecb9d1SAndroid Build Coastguard Worker       }
6515*bbecb9d1SAndroid Build Coastguard Worker    }
6516*bbecb9d1SAndroid Build Coastguard Worker 
6517*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_abo; i++){
6518*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "layout (binding = %d, offset = %d) uniform atomic_uint ac%d_%d", ctx->abo_idx[i], ctx->abo_offsets[i] * 4, ctx->abo_idx[i], ctx->abo_offsets[i] * 4);
6519*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->abo_sizes[i] > 1)
6520*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "[%d]", ctx->abo_sizes[i]);
6521*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, ";\n");
6522*bbecb9d1SAndroid Build Coastguard Worker    }
6523*bbecb9d1SAndroid Build Coastguard Worker 
6524*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
6525*bbecb9d1SAndroid Build Coastguard Worker       uint32_t mask = ctx->ssbo_used_mask;
6526*bbecb9d1SAndroid Build Coastguard Worker       while (mask) {
6527*bbecb9d1SAndroid Build Coastguard Worker          int start, count;
6528*bbecb9d1SAndroid Build Coastguard Worker          u_bit_scan_consecutive_range(&mask, &start, &count);
6529*bbecb9d1SAndroid Build Coastguard Worker          const char *atomic = (ctx->ssbo_atomic_mask & (1 << start)) ? "atomic" : "";
6530*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "layout (binding = %d, std430) buffer %sssbo%d { uint %sssbocontents%d[]; } %sssboarr%s[%d];\n", start, sname, start, sname, start, sname, atomic, count);
6531*bbecb9d1SAndroid Build Coastguard Worker       }
6532*bbecb9d1SAndroid Build Coastguard Worker    } else {
6533*bbecb9d1SAndroid Build Coastguard Worker       uint32_t mask = ctx->ssbo_used_mask;
6534*bbecb9d1SAndroid Build Coastguard Worker       while (mask) {
6535*bbecb9d1SAndroid Build Coastguard Worker          uint32_t id = u_bit_scan(&mask);
6536*bbecb9d1SAndroid Build Coastguard Worker          enum vrend_type_qualifier type = (ctx->ssbo_integer_mask & (1 << id)) ? INT : UINT;
6537*bbecb9d1SAndroid Build Coastguard Worker          char *coherent = ctx->ssbo_memory_qualifier[id] == TGSI_MEMORY_COHERENT ? "coherent" : "";
6538*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "layout (binding = %d, std430) %s buffer %sssbo%d { %s %sssbocontents%d[]; };\n", id, coherent, sname, id,
6539*bbecb9d1SAndroid Build Coastguard Worker                   get_string(type), sname, id);
6540*bbecb9d1SAndroid Build Coastguard Worker       }
6541*bbecb9d1SAndroid Build Coastguard Worker    }
6542*bbecb9d1SAndroid Build Coastguard Worker 
6543*bbecb9d1SAndroid Build Coastguard Worker    return glsl_ver_required;
6544*bbecb9d1SAndroid Build Coastguard Worker }
6545*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_streamout(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)6546*bbecb9d1SAndroid Build Coastguard Worker static void emit_ios_streamout(const struct dump_ctx *ctx,
6547*bbecb9d1SAndroid Build Coastguard Worker                                struct vrend_glsl_strbufs *glsl_strbufs)
6548*bbecb9d1SAndroid Build Coastguard Worker {
6549*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->so) {
6550*bbecb9d1SAndroid Build Coastguard Worker       char outtype[6] = "";
6551*bbecb9d1SAndroid Build Coastguard Worker       for (uint i = 0; i < ctx->so->num_outputs; i++) {
6552*bbecb9d1SAndroid Build Coastguard Worker          if (!ctx->write_so_outputs[i])
6553*bbecb9d1SAndroid Build Coastguard Worker             continue;
6554*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->so->output[i].num_components == 1)
6555*bbecb9d1SAndroid Build Coastguard Worker             snprintf(outtype, 6, "float");
6556*bbecb9d1SAndroid Build Coastguard Worker          else
6557*bbecb9d1SAndroid Build Coastguard Worker             snprintf(outtype, 6, "vec%d", ctx->so->output[i].num_components);
6558*bbecb9d1SAndroid Build Coastguard Worker 
6559*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->so->output[i].stream && ctx->prog_type == TGSI_PROCESSOR_GEOMETRY)
6560*bbecb9d1SAndroid Build Coastguard Worker             emit_hdrf(glsl_strbufs, "layout (stream=%d) out %s tfout%d;\n", ctx->so->output[i].stream, outtype, i);
6561*bbecb9d1SAndroid Build Coastguard Worker          else  {
6562*bbecb9d1SAndroid Build Coastguard Worker             const struct vrend_shader_io *output = get_io_slot(&ctx->outputs[0], ctx->num_outputs,
6563*bbecb9d1SAndroid Build Coastguard Worker                   ctx->so->output[i].register_index);
6564*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->so->output[i].need_temp || output->name == TGSI_SEMANTIC_CLIPDIST ||
6565*bbecb9d1SAndroid Build Coastguard Worker                 ctx->prog_type == TGSI_PROCESSOR_GEOMETRY || output->glsl_predefined_no_emit) {
6566*bbecb9d1SAndroid Build Coastguard Worker 
6567*bbecb9d1SAndroid Build Coastguard Worker                if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL)
6568*bbecb9d1SAndroid Build Coastguard Worker                   emit_hdrf(glsl_strbufs, "out %s tfout%d[];\n", outtype, i);
6569*bbecb9d1SAndroid Build Coastguard Worker                else
6570*bbecb9d1SAndroid Build Coastguard Worker                   emit_hdrf(glsl_strbufs, "out %s tfout%d;\n", outtype, i);
6571*bbecb9d1SAndroid Build Coastguard Worker             }
6572*bbecb9d1SAndroid Build Coastguard Worker          }
6573*bbecb9d1SAndroid Build Coastguard Worker       }
6574*bbecb9d1SAndroid Build Coastguard Worker    }
6575*bbecb9d1SAndroid Build Coastguard Worker }
6576*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_indirect_generics_output(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,const char * postfix)6577*bbecb9d1SAndroid Build Coastguard Worker static void emit_ios_indirect_generics_output(const struct dump_ctx *ctx,
6578*bbecb9d1SAndroid Build Coastguard Worker                                               struct vrend_glsl_strbufs *glsl_strbufs,
6579*bbecb9d1SAndroid Build Coastguard Worker                                               const char *postfix)
6580*bbecb9d1SAndroid Build Coastguard Worker {
6581*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->generic_ios.output_range.used) {
6582*bbecb9d1SAndroid Build Coastguard Worker       int size = ctx->generic_ios.output_range.io.last -
6583*bbecb9d1SAndroid Build Coastguard Worker          ctx->generic_ios.output_range.io.first + 1;
6584*bbecb9d1SAndroid Build Coastguard Worker       char array_handle[32] = "";
6585*bbecb9d1SAndroid Build Coastguard Worker       if (size > 1)
6586*bbecb9d1SAndroid Build Coastguard Worker          snprintf(array_handle, sizeof(array_handle), "[%d]", size);
6587*bbecb9d1SAndroid Build Coastguard Worker 
6588*bbecb9d1SAndroid Build Coastguard Worker       if (prefer_generic_io_block(ctx, io_out)) {
6589*bbecb9d1SAndroid Build Coastguard Worker          char blockname[64];
6590*bbecb9d1SAndroid Build Coastguard Worker          const char *stage_prefix = get_stage_output_name_prefix(ctx->prog_type);
6591*bbecb9d1SAndroid Build Coastguard Worker          get_blockname(blockname, stage_prefix, &ctx->generic_ios.output_range.io);
6592*bbecb9d1SAndroid Build Coastguard Worker 
6593*bbecb9d1SAndroid Build Coastguard Worker          char blockvarame[64];
6594*bbecb9d1SAndroid Build Coastguard Worker          get_blockvarname(blockvarame, stage_prefix, &ctx->generic_ios.output_range.io, postfix);
6595*bbecb9d1SAndroid Build Coastguard Worker 
6596*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "out %s {\n  vec4 %s%s; \n} %s;\n", blockname,
6597*bbecb9d1SAndroid Build Coastguard Worker                    ctx->generic_ios.output_range.io.glsl_name, array_handle, blockvarame);
6598*bbecb9d1SAndroid Build Coastguard Worker       } else
6599*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "out vec4 %s%s%s;\n",
6600*bbecb9d1SAndroid Build Coastguard Worker                    ctx->generic_ios.output_range.io.glsl_name,
6601*bbecb9d1SAndroid Build Coastguard Worker                    postfix,
6602*bbecb9d1SAndroid Build Coastguard Worker                    array_handle);
6603*bbecb9d1SAndroid Build Coastguard Worker    }
6604*bbecb9d1SAndroid Build Coastguard Worker }
6605*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_indirect_generics_input(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,const char * postfix)6606*bbecb9d1SAndroid Build Coastguard Worker static void emit_ios_indirect_generics_input(const struct dump_ctx *ctx,
6607*bbecb9d1SAndroid Build Coastguard Worker                                              struct vrend_glsl_strbufs *glsl_strbufs,
6608*bbecb9d1SAndroid Build Coastguard Worker                                              const char *postfix)
6609*bbecb9d1SAndroid Build Coastguard Worker {
6610*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->generic_ios.input_range.used) {
6611*bbecb9d1SAndroid Build Coastguard Worker       int size = ctx->generic_ios.input_range.io.last -
6612*bbecb9d1SAndroid Build Coastguard Worker          ctx->generic_ios.input_range.io.first + 1;
6613*bbecb9d1SAndroid Build Coastguard Worker       char array_handle[32] = "";
6614*bbecb9d1SAndroid Build Coastguard Worker       if (size > 1)
6615*bbecb9d1SAndroid Build Coastguard Worker          snprintf(array_handle, sizeof(array_handle), "[%d]", size);
6616*bbecb9d1SAndroid Build Coastguard Worker 
6617*bbecb9d1SAndroid Build Coastguard Worker       assert(size < 256 && size >= 0);
6618*bbecb9d1SAndroid Build Coastguard Worker 
6619*bbecb9d1SAndroid Build Coastguard Worker       if (prefer_generic_io_block(ctx, io_in)) {
6620*bbecb9d1SAndroid Build Coastguard Worker 
6621*bbecb9d1SAndroid Build Coastguard Worker          char blockname[64];
6622*bbecb9d1SAndroid Build Coastguard Worker          char blockvarame[64];
6623*bbecb9d1SAndroid Build Coastguard Worker          const char *stage_prefix = get_stage_input_name_prefix(ctx, ctx->prog_type);
6624*bbecb9d1SAndroid Build Coastguard Worker 
6625*bbecb9d1SAndroid Build Coastguard Worker          get_blockname(blockname, stage_prefix, &ctx->generic_ios.input_range.io);
6626*bbecb9d1SAndroid Build Coastguard Worker          get_blockvarname(blockvarame, stage_prefix, &ctx->generic_ios.input_range.io,
6627*bbecb9d1SAndroid Build Coastguard Worker                           postfix);
6628*bbecb9d1SAndroid Build Coastguard Worker 
6629*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "in %s {\n        vec4 %s%s; \n} %s;\n",
6630*bbecb9d1SAndroid Build Coastguard Worker                    blockname, ctx->generic_ios.input_range.io.glsl_name,
6631*bbecb9d1SAndroid Build Coastguard Worker                    array_handle, blockvarame);
6632*bbecb9d1SAndroid Build Coastguard Worker       } else
6633*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "in vec4 %s%s%s;\n",
6634*bbecb9d1SAndroid Build Coastguard Worker                    ctx->generic_ios.input_range.io.glsl_name,
6635*bbecb9d1SAndroid Build Coastguard Worker                    postfix,
6636*bbecb9d1SAndroid Build Coastguard Worker                    array_handle);
6637*bbecb9d1SAndroid Build Coastguard Worker    }
6638*bbecb9d1SAndroid Build Coastguard Worker }
6639*bbecb9d1SAndroid Build Coastguard Worker 
6640*bbecb9d1SAndroid Build Coastguard Worker static void
emit_ios_generic(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,enum io_type iot,const char * prefix,const struct vrend_shader_io * io,const char * inout,const char * postfix)6641*bbecb9d1SAndroid Build Coastguard Worker emit_ios_generic(const struct dump_ctx *ctx,
6642*bbecb9d1SAndroid Build Coastguard Worker                  struct vrend_glsl_strbufs *glsl_strbufs,
6643*bbecb9d1SAndroid Build Coastguard Worker                  struct vrend_generic_ios *generic_ios,
6644*bbecb9d1SAndroid Build Coastguard Worker                  struct vrend_texcoord_ios *texcoord_ios,
6645*bbecb9d1SAndroid Build Coastguard Worker                  enum io_type iot,  const char *prefix,
6646*bbecb9d1SAndroid Build Coastguard Worker                  const struct vrend_shader_io *io, const char *inout,
6647*bbecb9d1SAndroid Build Coastguard Worker                  const char *postfix)
6648*bbecb9d1SAndroid Build Coastguard Worker {
6649*bbecb9d1SAndroid Build Coastguard Worker    const char *atype[3] =  {
6650*bbecb9d1SAndroid Build Coastguard Worker       " vec4", "ivec4", "uvec4"
6651*bbecb9d1SAndroid Build Coastguard Worker    };
6652*bbecb9d1SAndroid Build Coastguard Worker 
6653*bbecb9d1SAndroid Build Coastguard Worker    const char *t = atype[io->type];
6654*bbecb9d1SAndroid Build Coastguard Worker 
6655*bbecb9d1SAndroid Build Coastguard Worker    char layout[128] = "";
6656*bbecb9d1SAndroid Build Coastguard Worker 
6657*bbecb9d1SAndroid Build Coastguard Worker    if (io->overlapping_array)
6658*bbecb9d1SAndroid Build Coastguard Worker       return;
6659*bbecb9d1SAndroid Build Coastguard Worker 
6660*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->separable_program && io->name == TGSI_SEMANTIC_GENERIC &&
6661*bbecb9d1SAndroid Build Coastguard Worker        !(ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && strcmp(inout, "in") != 0)) {
6662*bbecb9d1SAndroid Build Coastguard Worker       snprintf(layout, sizeof(layout), "layout(location = %d) ", 31 - io->sid);
6663*bbecb9d1SAndroid Build Coastguard Worker    }
6664*bbecb9d1SAndroid Build Coastguard Worker 
6665*bbecb9d1SAndroid Build Coastguard Worker    if (io->first == io->last) {
6666*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, layout);
6667*bbecb9d1SAndroid Build Coastguard Worker       /* ugly leave spaces to patch interp in later */
6668*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "%s%s %s  %s %s %s%s;\n",
6669*bbecb9d1SAndroid Build Coastguard Worker                 io->precise ? "precise" : "",
6670*bbecb9d1SAndroid Build Coastguard Worker                 io->invariant ? "invariant" : "",
6671*bbecb9d1SAndroid Build Coastguard Worker                 prefix,
6672*bbecb9d1SAndroid Build Coastguard Worker                 inout,
6673*bbecb9d1SAndroid Build Coastguard Worker                 t,
6674*bbecb9d1SAndroid Build Coastguard Worker                 io->glsl_name,
6675*bbecb9d1SAndroid Build Coastguard Worker                 postfix);
6676*bbecb9d1SAndroid Build Coastguard Worker 
6677*bbecb9d1SAndroid Build Coastguard Worker       if (io->name == TGSI_SEMANTIC_GENERIC) {
6678*bbecb9d1SAndroid Build Coastguard Worker          assert(io->sid < 64);
6679*bbecb9d1SAndroid Build Coastguard Worker          if (iot == io_in) {
6680*bbecb9d1SAndroid Build Coastguard Worker             generic_ios->match.inputs_emitted_mask |= 1ull << io->sid;
6681*bbecb9d1SAndroid Build Coastguard Worker          } else {
6682*bbecb9d1SAndroid Build Coastguard Worker             generic_ios->match.outputs_emitted_mask |= 1ull << io->sid;
6683*bbecb9d1SAndroid Build Coastguard Worker          }
6684*bbecb9d1SAndroid Build Coastguard Worker       } else if (io->name == TGSI_SEMANTIC_TEXCOORD) {
6685*bbecb9d1SAndroid Build Coastguard Worker          assert(io->sid < 8);
6686*bbecb9d1SAndroid Build Coastguard Worker          if (iot == io_in) {
6687*bbecb9d1SAndroid Build Coastguard Worker             texcoord_ios->match.inputs_emitted_mask |= 1ull << io->sid;
6688*bbecb9d1SAndroid Build Coastguard Worker          } else {
6689*bbecb9d1SAndroid Build Coastguard Worker             texcoord_ios->match.outputs_emitted_mask |= 1ull << io->sid;
6690*bbecb9d1SAndroid Build Coastguard Worker          }
6691*bbecb9d1SAndroid Build Coastguard Worker       }
6692*bbecb9d1SAndroid Build Coastguard Worker 
6693*bbecb9d1SAndroid Build Coastguard Worker    } else {
6694*bbecb9d1SAndroid Build Coastguard Worker       int array_size = io->last - io->first + 1;
6695*bbecb9d1SAndroid Build Coastguard Worker       if (prefer_generic_io_block(ctx, iot)) {
6696*bbecb9d1SAndroid Build Coastguard Worker          const char *stage_prefix = iot == io_in ? get_stage_input_name_prefix(ctx, ctx->prog_type):
6697*bbecb9d1SAndroid Build Coastguard Worker                                                    get_stage_output_name_prefix(ctx->prog_type);
6698*bbecb9d1SAndroid Build Coastguard Worker 
6699*bbecb9d1SAndroid Build Coastguard Worker          char blockname[64];
6700*bbecb9d1SAndroid Build Coastguard Worker          get_blockname(blockname, stage_prefix, io);
6701*bbecb9d1SAndroid Build Coastguard Worker 
6702*bbecb9d1SAndroid Build Coastguard Worker          char blockvarame[64];
6703*bbecb9d1SAndroid Build Coastguard Worker          get_blockvarname(blockvarame, stage_prefix, io, postfix);
6704*bbecb9d1SAndroid Build Coastguard Worker 
6705*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "%s %s {\n", inout, blockname);
6706*bbecb9d1SAndroid Build Coastguard Worker          emit_hdr(glsl_strbufs, layout);
6707*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "%s%s\n%s     %s %s[%d]; \n} %s;\n",
6708*bbecb9d1SAndroid Build Coastguard Worker                    io->precise ? "precise" : "",
6709*bbecb9d1SAndroid Build Coastguard Worker                    io->invariant ? "invariant" : "",
6710*bbecb9d1SAndroid Build Coastguard Worker                    prefix,
6711*bbecb9d1SAndroid Build Coastguard Worker                    t,
6712*bbecb9d1SAndroid Build Coastguard Worker                    io->glsl_name,
6713*bbecb9d1SAndroid Build Coastguard Worker                    array_size,
6714*bbecb9d1SAndroid Build Coastguard Worker                    blockvarame);
6715*bbecb9d1SAndroid Build Coastguard Worker       } else {
6716*bbecb9d1SAndroid Build Coastguard Worker          emit_hdr(glsl_strbufs, layout);
6717*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "%s%s\n%s       %s %s %s%s[%d];\n",
6718*bbecb9d1SAndroid Build Coastguard Worker                    io->precise ? "precise" : "",
6719*bbecb9d1SAndroid Build Coastguard Worker                    io->invariant ? "invariant" : "",
6720*bbecb9d1SAndroid Build Coastguard Worker                    prefix,
6721*bbecb9d1SAndroid Build Coastguard Worker                    inout,
6722*bbecb9d1SAndroid Build Coastguard Worker                    t,
6723*bbecb9d1SAndroid Build Coastguard Worker                    io->glsl_name,
6724*bbecb9d1SAndroid Build Coastguard Worker                    postfix,
6725*bbecb9d1SAndroid Build Coastguard Worker                    array_size);
6726*bbecb9d1SAndroid Build Coastguard Worker 
6727*bbecb9d1SAndroid Build Coastguard Worker          uint64_t mask = ((1ull << array_size) - 1) << io->sid;
6728*bbecb9d1SAndroid Build Coastguard Worker          if (io->name == TGSI_SEMANTIC_GENERIC) {
6729*bbecb9d1SAndroid Build Coastguard Worker             assert(io->sid + array_size < 64);
6730*bbecb9d1SAndroid Build Coastguard Worker             if (iot == io_in) {
6731*bbecb9d1SAndroid Build Coastguard Worker                generic_ios->match.inputs_emitted_mask |= mask;
6732*bbecb9d1SAndroid Build Coastguard Worker             } else {
6733*bbecb9d1SAndroid Build Coastguard Worker                generic_ios->match.outputs_emitted_mask |= mask;
6734*bbecb9d1SAndroid Build Coastguard Worker             }
6735*bbecb9d1SAndroid Build Coastguard Worker          } else if (io->name == TGSI_SEMANTIC_TEXCOORD) {
6736*bbecb9d1SAndroid Build Coastguard Worker             assert(io->sid + array_size < 8);
6737*bbecb9d1SAndroid Build Coastguard Worker             if (iot == io_in) {
6738*bbecb9d1SAndroid Build Coastguard Worker                texcoord_ios->match.inputs_emitted_mask |= mask;
6739*bbecb9d1SAndroid Build Coastguard Worker             } else {
6740*bbecb9d1SAndroid Build Coastguard Worker                texcoord_ios->match.outputs_emitted_mask |= mask;
6741*bbecb9d1SAndroid Build Coastguard Worker             }
6742*bbecb9d1SAndroid Build Coastguard Worker          }
6743*bbecb9d1SAndroid Build Coastguard Worker       }
6744*bbecb9d1SAndroid Build Coastguard Worker    }
6745*bbecb9d1SAndroid Build Coastguard Worker }
6746*bbecb9d1SAndroid Build Coastguard Worker 
6747*bbecb9d1SAndroid Build Coastguard Worker typedef bool (*can_emit_generic_callback)(const struct vrend_shader_io *io);
6748*bbecb9d1SAndroid Build Coastguard Worker 
6749*bbecb9d1SAndroid Build Coastguard Worker /* Front and back color of the same semantic ID must have the same interpolator
6750*bbecb9d1SAndroid Build Coastguard Worker  * specifiers, and it may happen, that one or the other shader doesn't define
6751*bbecb9d1SAndroid Build Coastguard Worker  * both, front and back color, so always compare these two as COLOR. */
6752*bbecb9d1SAndroid Build Coastguard Worker static inline
get_semantic_to_compare(enum tgsi_semantic name)6753*bbecb9d1SAndroid Build Coastguard Worker enum tgsi_semantic get_semantic_to_compare(enum tgsi_semantic name)
6754*bbecb9d1SAndroid Build Coastguard Worker {
6755*bbecb9d1SAndroid Build Coastguard Worker    switch (name) {
6756*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_COLOR:
6757*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_BCOLOR:
6758*bbecb9d1SAndroid Build Coastguard Worker       return TGSI_SEMANTIC_COLOR;
6759*bbecb9d1SAndroid Build Coastguard Worker    default:
6760*bbecb9d1SAndroid Build Coastguard Worker       return name;
6761*bbecb9d1SAndroid Build Coastguard Worker    }
6762*bbecb9d1SAndroid Build Coastguard Worker }
6763*bbecb9d1SAndroid Build Coastguard Worker 
6764*bbecb9d1SAndroid Build Coastguard Worker static const char *
get_interpolator_prefix(struct vrend_strbuf * buf,uint32_t * num_interps,const struct vrend_shader_cfg * cfg,const struct vrend_shader_io * io,const struct vrend_fs_shader_info * fs_info,bool flatshade)6765*bbecb9d1SAndroid Build Coastguard Worker get_interpolator_prefix(struct vrend_strbuf *buf, uint32_t *num_interps,
6766*bbecb9d1SAndroid Build Coastguard Worker                         const struct vrend_shader_cfg *cfg, const struct vrend_shader_io *io,
6767*bbecb9d1SAndroid Build Coastguard Worker                         const struct vrend_fs_shader_info *fs_info, bool flatshade)
6768*bbecb9d1SAndroid Build Coastguard Worker {
6769*bbecb9d1SAndroid Build Coastguard Worker    if (io->name == TGSI_SEMANTIC_GENERIC ||
6770*bbecb9d1SAndroid Build Coastguard Worker        io->name == TGSI_SEMANTIC_TEXCOORD ||
6771*bbecb9d1SAndroid Build Coastguard Worker        io->name == TGSI_SEMANTIC_COLOR ||
6772*bbecb9d1SAndroid Build Coastguard Worker        io->name == TGSI_SEMANTIC_BCOLOR) {
6773*bbecb9d1SAndroid Build Coastguard Worker       (*num_interps)++;
6774*bbecb9d1SAndroid Build Coastguard Worker       enum tgsi_semantic name = get_semantic_to_compare(io->name);
6775*bbecb9d1SAndroid Build Coastguard Worker 
6776*bbecb9d1SAndroid Build Coastguard Worker       for (int j = 0; j < fs_info->num_interps; ++j) {
6777*bbecb9d1SAndroid Build Coastguard Worker          if (get_semantic_to_compare(fs_info->interpinfo[j].semantic_name) == name &&
6778*bbecb9d1SAndroid Build Coastguard Worker              fs_info->interpinfo[j].semantic_index == io->sid) {
6779*bbecb9d1SAndroid Build Coastguard Worker             strbuf_fmt(buf, "%s %s",
6780*bbecb9d1SAndroid Build Coastguard Worker                        get_interp_string(cfg, fs_info->interpinfo[j].interpolate, flatshade),
6781*bbecb9d1SAndroid Build Coastguard Worker                        get_aux_string(fs_info->interpinfo[j].location));
6782*bbecb9d1SAndroid Build Coastguard Worker             return buf->buf;
6783*bbecb9d1SAndroid Build Coastguard Worker          }
6784*bbecb9d1SAndroid Build Coastguard Worker       }
6785*bbecb9d1SAndroid Build Coastguard Worker    }
6786*bbecb9d1SAndroid Build Coastguard Worker    return "";
6787*bbecb9d1SAndroid Build Coastguard Worker }
6788*bbecb9d1SAndroid Build Coastguard Worker 
6789*bbecb9d1SAndroid Build Coastguard Worker static void
emit_ios_generic_outputs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint8_t front_back_color_emitted_flags[],bool * force_color_two_side,uint32_t * num_interps,const can_emit_generic_callback can_emit_generic)6790*bbecb9d1SAndroid Build Coastguard Worker emit_ios_generic_outputs(const struct dump_ctx *ctx,
6791*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_glsl_strbufs *glsl_strbufs,
6792*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_generic_ios *generic_ios,
6793*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_texcoord_ios *texcoord_ios,
6794*bbecb9d1SAndroid Build Coastguard Worker                          uint8_t front_back_color_emitted_flags[],
6795*bbecb9d1SAndroid Build Coastguard Worker                          bool *force_color_two_side,
6796*bbecb9d1SAndroid Build Coastguard Worker                          uint32_t *num_interps,
6797*bbecb9d1SAndroid Build Coastguard Worker                          const can_emit_generic_callback can_emit_generic)
6798*bbecb9d1SAndroid Build Coastguard Worker {
6799*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
6800*bbecb9d1SAndroid Build Coastguard Worker    uint64_t fc_emitted = 0;
6801*bbecb9d1SAndroid Build Coastguard Worker    uint64_t bc_emitted = 0;
6802*bbecb9d1SAndroid Build Coastguard Worker 
6803*bbecb9d1SAndroid Build Coastguard Worker    char buffer[64];
6804*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_strbuf buf;
6805*bbecb9d1SAndroid Build Coastguard Worker    strbuf_alloc_fixed(&buf, buffer, sizeof(buffer));
6806*bbecb9d1SAndroid Build Coastguard Worker 
6807*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_outputs; i++) {
6808*bbecb9d1SAndroid Build Coastguard Worker 
6809*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->outputs[i].glsl_predefined_no_emit) {
6810*bbecb9d1SAndroid Build Coastguard Worker          /* GS stream outputs are handled separately */
6811*bbecb9d1SAndroid Build Coastguard Worker          if (!can_emit_generic(&ctx->outputs[i]))
6812*bbecb9d1SAndroid Build Coastguard Worker             continue;
6813*bbecb9d1SAndroid Build Coastguard Worker 
6814*bbecb9d1SAndroid Build Coastguard Worker          /* It is save to use buf here even though it is declared outside the loop, because
6815*bbecb9d1SAndroid Build Coastguard Worker           * when written it is reset, and the content is used within the iteration */
6816*bbecb9d1SAndroid Build Coastguard Worker          const char *prefix = get_interpolator_prefix(&buf, num_interps, ctx->cfg, &ctx->outputs[i],
6817*bbecb9d1SAndroid Build Coastguard Worker                                                       &ctx->key->fs_info, ctx->key->flatshade);
6818*bbecb9d1SAndroid Build Coastguard Worker 
6819*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR) {
6820*bbecb9d1SAndroid Build Coastguard Worker             front_back_color_emitted_flags[ctx->outputs[i].sid] |= FRONT_COLOR_EMITTED;
6821*bbecb9d1SAndroid Build Coastguard Worker             fc_emitted |= 1ull << ctx->outputs[i].sid;
6822*bbecb9d1SAndroid Build Coastguard Worker          }
6823*bbecb9d1SAndroid Build Coastguard Worker 
6824*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->outputs[i].name == TGSI_SEMANTIC_BCOLOR) {
6825*bbecb9d1SAndroid Build Coastguard Worker             front_back_color_emitted_flags[ctx->outputs[i].sid] |= BACK_COLOR_EMITTED;
6826*bbecb9d1SAndroid Build Coastguard Worker             bc_emitted |= 1ull << ctx->outputs[i].sid;
6827*bbecb9d1SAndroid Build Coastguard Worker          }
6828*bbecb9d1SAndroid Build Coastguard Worker 
6829*bbecb9d1SAndroid Build Coastguard Worker          emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios,
6830*bbecb9d1SAndroid Build Coastguard Worker                           io_out, prefix, &ctx->outputs[i],
6831*bbecb9d1SAndroid Build Coastguard Worker                           ctx->outputs[i].fbfetch_used ? "inout" : "out", "");
6832*bbecb9d1SAndroid Build Coastguard Worker       } else if (ctx->outputs[i].invariant || ctx->outputs[i].precise) {
6833*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "%s%s;\n",
6834*bbecb9d1SAndroid Build Coastguard Worker                    ctx->outputs[i].precise ? "precise " :
6835*bbecb9d1SAndroid Build Coastguard Worker                    (ctx->outputs[i].invariant ? "invariant " : ""),
6836*bbecb9d1SAndroid Build Coastguard Worker                    ctx->outputs[i].glsl_name);
6837*bbecb9d1SAndroid Build Coastguard Worker       }
6838*bbecb9d1SAndroid Build Coastguard Worker    }
6839*bbecb9d1SAndroid Build Coastguard Worker 
6840*bbecb9d1SAndroid Build Coastguard Worker    /* If a back color emitted without a corresponding front color, then
6841*bbecb9d1SAndroid Build Coastguard Worker     * we have to force two side coloring, because the FS shader might expect
6842*bbecb9d1SAndroid Build Coastguard Worker     * a front color too. */
6843*bbecb9d1SAndroid Build Coastguard Worker    if (bc_emitted & ~fc_emitted)
6844*bbecb9d1SAndroid Build Coastguard Worker       *force_color_two_side = 1;
6845*bbecb9d1SAndroid Build Coastguard Worker }
6846*bbecb9d1SAndroid Build Coastguard Worker 
6847*bbecb9d1SAndroid Build Coastguard Worker static uint64_t
emit_ios_patch(struct vrend_glsl_strbufs * glsl_strbufs,const char * prefix,const struct vrend_shader_io * io,const char * inout,int size,bool emit_location)6848*bbecb9d1SAndroid Build Coastguard Worker emit_ios_patch(struct vrend_glsl_strbufs *glsl_strbufs,
6849*bbecb9d1SAndroid Build Coastguard Worker                const char *prefix, const struct vrend_shader_io *io,
6850*bbecb9d1SAndroid Build Coastguard Worker                const char *inout, int size, bool emit_location)
6851*bbecb9d1SAndroid Build Coastguard Worker {
6852*bbecb9d1SAndroid Build Coastguard Worker    uint64_t emitted_patches = 0;
6853*bbecb9d1SAndroid Build Coastguard Worker 
6854*bbecb9d1SAndroid Build Coastguard Worker    /* We start these locations from 32 and proceed downwards, to avoid
6855*bbecb9d1SAndroid Build Coastguard Worker     * conflicting with generic IO locations. */
6856*bbecb9d1SAndroid Build Coastguard Worker    if (emit_location)
6857*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "layout(location = %d) ", io->sid);
6858*bbecb9d1SAndroid Build Coastguard Worker 
6859*bbecb9d1SAndroid Build Coastguard Worker    if (io->last == io->first) {
6860*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "%s %s vec4 %s;\n", prefix, inout, io->glsl_name);
6861*bbecb9d1SAndroid Build Coastguard Worker       emitted_patches |= 1ul << io->sid;
6862*bbecb9d1SAndroid Build Coastguard Worker    } else {
6863*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "%s %s vec4 %s[%d];\n", prefix, inout,
6864*bbecb9d1SAndroid Build Coastguard Worker                 io->glsl_name, size);
6865*bbecb9d1SAndroid Build Coastguard Worker       uint64_t mask = (1ul << size) - 1;
6866*bbecb9d1SAndroid Build Coastguard Worker       emitted_patches |= mask << io->sid;
6867*bbecb9d1SAndroid Build Coastguard Worker    }
6868*bbecb9d1SAndroid Build Coastguard Worker    return emitted_patches;
6869*bbecb9d1SAndroid Build Coastguard Worker }
6870*bbecb9d1SAndroid Build Coastguard Worker 
6871*bbecb9d1SAndroid Build Coastguard Worker static bool
can_emit_generic_default(UNUSED const struct vrend_shader_io * io)6872*bbecb9d1SAndroid Build Coastguard Worker can_emit_generic_default(UNUSED const struct vrend_shader_io *io)
6873*bbecb9d1SAndroid Build Coastguard Worker {
6874*bbecb9d1SAndroid Build Coastguard Worker    return true;
6875*bbecb9d1SAndroid Build Coastguard Worker }
6876*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_vs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint32_t * num_interps,uint8_t front_back_color_emitted_flags[],bool * force_color_two_side)6877*bbecb9d1SAndroid Build Coastguard Worker static void emit_ios_vs(const struct dump_ctx *ctx,
6878*bbecb9d1SAndroid Build Coastguard Worker                         struct vrend_glsl_strbufs *glsl_strbufs,
6879*bbecb9d1SAndroid Build Coastguard Worker                         struct vrend_generic_ios *generic_ios,
6880*bbecb9d1SAndroid Build Coastguard Worker                         struct vrend_texcoord_ios *texcoord_ios,
6881*bbecb9d1SAndroid Build Coastguard Worker                         uint32_t *num_interps,
6882*bbecb9d1SAndroid Build Coastguard Worker                         uint8_t front_back_color_emitted_flags[],
6883*bbecb9d1SAndroid Build Coastguard Worker                         bool *force_color_two_side)
6884*bbecb9d1SAndroid Build Coastguard Worker {
6885*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
6886*bbecb9d1SAndroid Build Coastguard Worker 
6887*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_inputs; i++) {
6888*bbecb9d1SAndroid Build Coastguard Worker       char postfix[32] = "";
6889*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->inputs[i].glsl_predefined_no_emit) {
6890*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->cfg->use_explicit_locations) {
6891*bbecb9d1SAndroid Build Coastguard Worker             emit_hdrf(glsl_strbufs, "layout(location=%d) ", ctx->inputs[i].first);
6892*bbecb9d1SAndroid Build Coastguard Worker          }
6893*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[i].first != ctx->inputs[i].last)
6894*bbecb9d1SAndroid Build Coastguard Worker             snprintf(postfix, sizeof(postfix), "[%d]", ctx->inputs[i].last - ctx->inputs[i].first + 1);
6895*bbecb9d1SAndroid Build Coastguard Worker          const char *vtype[3] = {"vec4", "ivec4", "uvec4"};
6896*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "in %s %s%s;\n",
6897*bbecb9d1SAndroid Build Coastguard Worker                    vtype[ctx->inputs[i].type], ctx->inputs[i].glsl_name, postfix);
6898*bbecb9d1SAndroid Build Coastguard Worker       }
6899*bbecb9d1SAndroid Build Coastguard Worker    }
6900*bbecb9d1SAndroid Build Coastguard Worker 
6901*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_indirect_generics_output(ctx, glsl_strbufs, "");
6902*bbecb9d1SAndroid Build Coastguard Worker 
6903*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_generic_outputs(ctx, glsl_strbufs, generic_ios, texcoord_ios,
6904*bbecb9d1SAndroid Build Coastguard Worker                             front_back_color_emitted_flags, force_color_two_side,
6905*bbecb9d1SAndroid Build Coastguard Worker                             num_interps, can_emit_generic_default);
6906*bbecb9d1SAndroid Build Coastguard Worker 
6907*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->key->color_two_side || ctx->force_color_two_side) {
6908*bbecb9d1SAndroid Build Coastguard Worker       bool fcolor_emitted, bcolor_emitted;
6909*bbecb9d1SAndroid Build Coastguard Worker 
6910*bbecb9d1SAndroid Build Coastguard Worker       enum tgsi_interpolate_mode interpolators[2] = {TGSI_INTERPOLATE_COLOR, TGSI_INTERPOLATE_COLOR};
6911*bbecb9d1SAndroid Build Coastguard Worker       enum tgsi_interpolate_loc interp_loc[2] = { TGSI_INTERPOLATE_LOC_CENTER, TGSI_INTERPOLATE_LOC_CENTER};
6912*bbecb9d1SAndroid Build Coastguard Worker       for (int k = 0; k < ctx->key->fs_info.num_interps; k++) {
6913*bbecb9d1SAndroid Build Coastguard Worker          const struct vrend_interp_info *interp_info = &ctx->key->fs_info.interpinfo[k];
6914*bbecb9d1SAndroid Build Coastguard Worker          if (interp_info->semantic_name == TGSI_SEMANTIC_COLOR ||
6915*bbecb9d1SAndroid Build Coastguard Worker              interp_info->semantic_name == TGSI_SEMANTIC_BCOLOR) {
6916*bbecb9d1SAndroid Build Coastguard Worker             interpolators[interp_info->semantic_index] = interp_info->interpolate;
6917*bbecb9d1SAndroid Build Coastguard Worker             interp_loc[interp_info->semantic_index] = interp_info->location;
6918*bbecb9d1SAndroid Build Coastguard Worker          }
6919*bbecb9d1SAndroid Build Coastguard Worker       }
6920*bbecb9d1SAndroid Build Coastguard Worker 
6921*bbecb9d1SAndroid Build Coastguard Worker       for (i = 0; i < ctx->num_outputs; i++) {
6922*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->outputs[i].sid >= 2)
6923*bbecb9d1SAndroid Build Coastguard Worker             continue;
6924*bbecb9d1SAndroid Build Coastguard Worker 
6925*bbecb9d1SAndroid Build Coastguard Worker          fcolor_emitted = bcolor_emitted = false;
6926*bbecb9d1SAndroid Build Coastguard Worker 
6927*bbecb9d1SAndroid Build Coastguard Worker          fcolor_emitted = front_back_color_emitted_flags[ctx->outputs[i].sid] & FRONT_COLOR_EMITTED;
6928*bbecb9d1SAndroid Build Coastguard Worker          bcolor_emitted = front_back_color_emitted_flags[ctx->outputs[i].sid] & BACK_COLOR_EMITTED;
6929*bbecb9d1SAndroid Build Coastguard Worker 
6930*bbecb9d1SAndroid Build Coastguard Worker          if (fcolor_emitted && !bcolor_emitted) {
6931*bbecb9d1SAndroid Build Coastguard Worker             emit_hdrf(glsl_strbufs, "%s %s out vec4 vso_bc%d;\n",
6932*bbecb9d1SAndroid Build Coastguard Worker                       get_interp_string(ctx->cfg, interpolators[ctx->outputs[i].sid], ctx->key->flatshade),
6933*bbecb9d1SAndroid Build Coastguard Worker                       get_aux_string(interp_loc[ctx->outputs[i].sid]),
6934*bbecb9d1SAndroid Build Coastguard Worker                       ctx->outputs[i].sid);
6935*bbecb9d1SAndroid Build Coastguard Worker             front_back_color_emitted_flags[ctx->outputs[i].sid] |= BACK_COLOR_EMITTED;
6936*bbecb9d1SAndroid Build Coastguard Worker          }
6937*bbecb9d1SAndroid Build Coastguard Worker          if (bcolor_emitted && !fcolor_emitted) {
6938*bbecb9d1SAndroid Build Coastguard Worker             emit_hdrf(glsl_strbufs, "%s %s out vec4 vso_c%d;\n",
6939*bbecb9d1SAndroid Build Coastguard Worker                       get_interp_string(ctx->cfg, interpolators[ctx->outputs[i].sid], ctx->key->flatshade),
6940*bbecb9d1SAndroid Build Coastguard Worker                       get_aux_string(interp_loc[ctx->outputs[i].sid]),
6941*bbecb9d1SAndroid Build Coastguard Worker                       ctx->outputs[i].sid);
6942*bbecb9d1SAndroid Build Coastguard Worker             front_back_color_emitted_flags[ctx->outputs[i].sid] |= FRONT_COLOR_EMITTED;
6943*bbecb9d1SAndroid Build Coastguard Worker          }
6944*bbecb9d1SAndroid Build Coastguard Worker       }
6945*bbecb9d1SAndroid Build Coastguard Worker    }
6946*bbecb9d1SAndroid Build Coastguard Worker 
6947*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->key->vs.fog_fixup_mask)
6948*bbecb9d1SAndroid Build Coastguard Worker       emit_fog_fixup_hdr(ctx, glsl_strbufs);
6949*bbecb9d1SAndroid Build Coastguard Worker 
6950*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->has_clipvertex && ctx->is_last_vertex_stage) {
6951*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "%svec4 clipv_tmp;\n", ctx->has_clipvertex_so ? "out " : "");
6952*bbecb9d1SAndroid Build Coastguard Worker    }
6953*bbecb9d1SAndroid Build Coastguard Worker 
6954*bbecb9d1SAndroid Build Coastguard Worker    char cull_buf[64] = "";
6955*bbecb9d1SAndroid Build Coastguard Worker    char clip_buf[64] = "";
6956*bbecb9d1SAndroid Build Coastguard Worker 
6957*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->cfg->has_cull_distance && (ctx->num_out_clip_dist || ctx->is_last_vertex_stage)) {
6958*bbecb9d1SAndroid Build Coastguard Worker       int num_clip_dists = ctx->num_clip_dist_prop ? ctx->num_clip_dist_prop : 0;
6959*bbecb9d1SAndroid Build Coastguard Worker       int num_cull_dists = ctx->num_cull_dist_prop ? ctx->num_cull_dist_prop : 0;
6960*bbecb9d1SAndroid Build Coastguard Worker 
6961*bbecb9d1SAndroid Build Coastguard Worker       int num_clip_cull = num_clip_dists + num_cull_dists;
6962*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->num_out_clip_dist && !num_clip_cull)
6963*bbecb9d1SAndroid Build Coastguard Worker          num_clip_dists = ctx->num_out_clip_dist;
6964*bbecb9d1SAndroid Build Coastguard Worker 
6965*bbecb9d1SAndroid Build Coastguard Worker       if (num_clip_dists)
6966*bbecb9d1SAndroid Build Coastguard Worker          snprintf(clip_buf, 64, "out float gl_ClipDistance[%d];\n", num_clip_dists);
6967*bbecb9d1SAndroid Build Coastguard Worker       if (num_cull_dists)
6968*bbecb9d1SAndroid Build Coastguard Worker          snprintf(cull_buf, 64, "out float gl_CullDistance[%d];\n", num_cull_dists);
6969*bbecb9d1SAndroid Build Coastguard Worker 
6970*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->is_last_vertex_stage) {
6971*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "%s%s", clip_buf, cull_buf);
6972*bbecb9d1SAndroid Build Coastguard Worker       }
6973*bbecb9d1SAndroid Build Coastguard Worker 
6974*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "vec4 clip_dist_temp[2];\n");
6975*bbecb9d1SAndroid Build Coastguard Worker    }
6976*bbecb9d1SAndroid Build Coastguard Worker 
6977*bbecb9d1SAndroid Build Coastguard Worker    const char *psize_buf = ctx->has_pointsize_output ? "out float gl_PointSize;\n" : "";
6978*bbecb9d1SAndroid Build Coastguard Worker 
6979*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx->is_last_vertex_stage && ctx->key->use_pervertex_in) {
6980*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "out gl_PerVertex {\n vec4 gl_Position;\n %s%s%s};\n", clip_buf, cull_buf, psize_buf);
6981*bbecb9d1SAndroid Build Coastguard Worker    }
6982*bbecb9d1SAndroid Build Coastguard Worker }
6983*bbecb9d1SAndroid Build Coastguard Worker 
get_depth_layout(int depth_layout)6984*bbecb9d1SAndroid Build Coastguard Worker static const char *get_depth_layout(int depth_layout)
6985*bbecb9d1SAndroid Build Coastguard Worker {
6986*bbecb9d1SAndroid Build Coastguard Worker    const char *dl[4]  = {
6987*bbecb9d1SAndroid Build Coastguard Worker       "depth_any",
6988*bbecb9d1SAndroid Build Coastguard Worker       "depth_greater",
6989*bbecb9d1SAndroid Build Coastguard Worker       "depth_less",
6990*bbecb9d1SAndroid Build Coastguard Worker       "depth_unchanged"
6991*bbecb9d1SAndroid Build Coastguard Worker    };
6992*bbecb9d1SAndroid Build Coastguard Worker 
6993*bbecb9d1SAndroid Build Coastguard Worker    if (depth_layout < 1 || depth_layout > TGSI_FS_DEPTH_LAYOUT_UNCHANGED)
6994*bbecb9d1SAndroid Build Coastguard Worker       return NULL;
6995*bbecb9d1SAndroid Build Coastguard Worker    return dl[depth_layout -1];
6996*bbecb9d1SAndroid Build Coastguard Worker }
6997*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_fs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint32_t * num_interps)6998*bbecb9d1SAndroid Build Coastguard Worker static void emit_ios_fs(const struct dump_ctx *ctx,
6999*bbecb9d1SAndroid Build Coastguard Worker                         struct vrend_glsl_strbufs *glsl_strbufs,
7000*bbecb9d1SAndroid Build Coastguard Worker                         struct vrend_generic_ios *generic_ios,
7001*bbecb9d1SAndroid Build Coastguard Worker                         struct vrend_texcoord_ios *texcoord_ios,
7002*bbecb9d1SAndroid Build Coastguard Worker                         uint32_t *num_interps
7003*bbecb9d1SAndroid Build Coastguard Worker                         )
7004*bbecb9d1SAndroid Build Coastguard Worker {
7005*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
7006*bbecb9d1SAndroid Build Coastguard Worker 
7007*bbecb9d1SAndroid Build Coastguard Worker    if (fs_emit_layout(ctx)) {
7008*bbecb9d1SAndroid Build Coastguard Worker       bool upper_left = ctx->fs_lower_left_origin == ctx->key->fs.lower_left_origin;
7009*bbecb9d1SAndroid Build Coastguard Worker       char comma = (upper_left && ctx->fs_integer_pixel_center) ? ',' : ' ';
7010*bbecb9d1SAndroid Build Coastguard Worker 
7011*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->cfg->use_gles)
7012*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "layout(%s%c%s) in vec4 gl_FragCoord;\n",
7013*bbecb9d1SAndroid Build Coastguard Worker                    upper_left ? "origin_upper_left" : "",
7014*bbecb9d1SAndroid Build Coastguard Worker                    comma,
7015*bbecb9d1SAndroid Build Coastguard Worker                    ctx->fs_integer_pixel_center ? "pixel_center_integer" : "");
7016*bbecb9d1SAndroid Build Coastguard Worker    }
7017*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->early_depth_stencil) {
7018*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "layout(early_fragment_tests) in;\n");
7019*bbecb9d1SAndroid Build Coastguard Worker    }
7020*bbecb9d1SAndroid Build Coastguard Worker 
7021*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_indirect_generics_input(ctx, glsl_strbufs, "");
7022*bbecb9d1SAndroid Build Coastguard Worker 
7023*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_inputs; i++) {
7024*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->inputs[i].glsl_predefined_no_emit) {
7025*bbecb9d1SAndroid Build Coastguard Worker          const char *prefix = "";
7026*bbecb9d1SAndroid Build Coastguard Worker          const char *auxprefix = "";
7027*bbecb9d1SAndroid Build Coastguard Worker 
7028*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->cfg->use_gles) {
7029*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->inputs[i].name == TGSI_SEMANTIC_COLOR) {
7030*bbecb9d1SAndroid Build Coastguard Worker                if (!(ctx->key->fs.available_color_in_bits & (1 << ctx->inputs[i].sid))) {
7031*bbecb9d1SAndroid Build Coastguard Worker                   emit_hdrf(glsl_strbufs, "vec4 %s = vec4(0.0, 0.0, 0.0, 0.0);\n",
7032*bbecb9d1SAndroid Build Coastguard Worker                             ctx->inputs[i].glsl_name);
7033*bbecb9d1SAndroid Build Coastguard Worker                   continue;
7034*bbecb9d1SAndroid Build Coastguard Worker                }
7035*bbecb9d1SAndroid Build Coastguard Worker             }
7036*bbecb9d1SAndroid Build Coastguard Worker 
7037*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->inputs[i].name == TGSI_SEMANTIC_BCOLOR) {
7038*bbecb9d1SAndroid Build Coastguard Worker                if (!(ctx->key->fs.available_color_in_bits & (1 << ctx->inputs[i].sid) << 2)) {
7039*bbecb9d1SAndroid Build Coastguard Worker                   emit_hdrf(glsl_strbufs, "vec4 %s = vec4(0.0, 0.0, 0.0, 0.0);\n",
7040*bbecb9d1SAndroid Build Coastguard Worker                             ctx->inputs[i].glsl_name);
7041*bbecb9d1SAndroid Build Coastguard Worker                   continue;
7042*bbecb9d1SAndroid Build Coastguard Worker                }
7043*bbecb9d1SAndroid Build Coastguard Worker             }
7044*bbecb9d1SAndroid Build Coastguard Worker          }
7045*bbecb9d1SAndroid Build Coastguard Worker 
7046*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC ||
7047*bbecb9d1SAndroid Build Coastguard Worker               ctx->inputs[i].name == TGSI_SEMANTIC_COLOR ||
7048*bbecb9d1SAndroid Build Coastguard Worker               ctx->inputs[i].name == TGSI_SEMANTIC_BCOLOR) {
7049*bbecb9d1SAndroid Build Coastguard Worker             prefix = get_interp_string(ctx->cfg, ctx->inputs[i].interpolate, ctx->key->flatshade);
7050*bbecb9d1SAndroid Build Coastguard Worker             if (!prefix)
7051*bbecb9d1SAndroid Build Coastguard Worker                prefix = "";
7052*bbecb9d1SAndroid Build Coastguard Worker             auxprefix = get_aux_string(ctx->inputs[i].location);
7053*bbecb9d1SAndroid Build Coastguard Worker             (*num_interps)++;
7054*bbecb9d1SAndroid Build Coastguard Worker          }
7055*bbecb9d1SAndroid Build Coastguard Worker 
7056*bbecb9d1SAndroid Build Coastguard Worker          char prefixes[64];
7057*bbecb9d1SAndroid Build Coastguard Worker          snprintf(prefixes, sizeof(prefixes), "%s %s", prefix, auxprefix);
7058*bbecb9d1SAndroid Build Coastguard Worker          emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios, io_in, prefixes, &ctx->inputs[i], "in", "");
7059*bbecb9d1SAndroid Build Coastguard Worker       }
7060*bbecb9d1SAndroid Build Coastguard Worker    }
7061*bbecb9d1SAndroid Build Coastguard Worker 
7062*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->key->color_two_side) {
7063*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->color_in_mask & 1)
7064*bbecb9d1SAndroid Build Coastguard Worker          emit_hdr(glsl_strbufs, "vec4 realcolor0;\n");
7065*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->color_in_mask & 2)
7066*bbecb9d1SAndroid Build Coastguard Worker          emit_hdr(glsl_strbufs, "vec4 realcolor1;\n");
7067*bbecb9d1SAndroid Build Coastguard Worker    }
7068*bbecb9d1SAndroid Build Coastguard Worker 
7069*bbecb9d1SAndroid Build Coastguard Worker    unsigned choices = ctx->fs_blend_equation_advanced;
7070*bbecb9d1SAndroid Build Coastguard Worker    while (choices) {
7071*bbecb9d1SAndroid Build Coastguard Worker       enum gl_advanced_blend_mode choice = (enum gl_advanced_blend_mode)u_bit_scan(&choices);
7072*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "layout(blend_support_%s) out;\n", blend_to_name(choice));
7073*bbecb9d1SAndroid Build Coastguard Worker    }
7074*bbecb9d1SAndroid Build Coastguard Worker 
7075*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->write_all_cbufs) {
7076*bbecb9d1SAndroid Build Coastguard Worker       const char* type = "vec4";
7077*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->key->fs.cbufs_unsigned_int_bitmask)
7078*bbecb9d1SAndroid Build Coastguard Worker          type = "uvec4";
7079*bbecb9d1SAndroid Build Coastguard Worker       else if (ctx->key->fs.cbufs_signed_int_bitmask)
7080*bbecb9d1SAndroid Build Coastguard Worker          type = "ivec4";
7081*bbecb9d1SAndroid Build Coastguard Worker 
7082*bbecb9d1SAndroid Build Coastguard Worker       for (i = 0; i < (uint32_t)ctx->cfg->max_draw_buffers; i++) {
7083*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->cfg->use_gles) {
7084*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->key->fs.logicop_enabled)
7085*bbecb9d1SAndroid Build Coastguard Worker                emit_hdrf(glsl_strbufs, "%s fsout_tmp_c%d;\n", type, i);
7086*bbecb9d1SAndroid Build Coastguard Worker 
7087*bbecb9d1SAndroid Build Coastguard Worker             if (logiop_require_inout(ctx->key)) {
7088*bbecb9d1SAndroid Build Coastguard Worker                const char *noncoherent = ctx->cfg->has_fbfetch_coherent ? "" : ", noncoherent";
7089*bbecb9d1SAndroid Build Coastguard Worker                emit_hdrf(glsl_strbufs, "layout (location=%d%s) inout highp %s fsout_c%d;\n", i, noncoherent, type, i);
7090*bbecb9d1SAndroid Build Coastguard Worker             } else
7091*bbecb9d1SAndroid Build Coastguard Worker                emit_hdrf(glsl_strbufs, "layout (location=%d) out %s fsout_c%d;\n", i,
7092*bbecb9d1SAndroid Build Coastguard Worker 			 type, i);
7093*bbecb9d1SAndroid Build Coastguard Worker          } else
7094*bbecb9d1SAndroid Build Coastguard Worker             emit_hdrf(glsl_strbufs, "out %s fsout_c%d;\n", type, i);
7095*bbecb9d1SAndroid Build Coastguard Worker       }
7096*bbecb9d1SAndroid Build Coastguard Worker    } else {
7097*bbecb9d1SAndroid Build Coastguard Worker       for (i = 0; i < ctx->num_outputs; i++) {
7098*bbecb9d1SAndroid Build Coastguard Worker 
7099*bbecb9d1SAndroid Build Coastguard Worker          if (!ctx->outputs[i].glsl_predefined_no_emit) {
7100*bbecb9d1SAndroid Build Coastguard Worker             char prefix[64] = "";
7101*bbecb9d1SAndroid Build Coastguard Worker 
7102*bbecb9d1SAndroid Build Coastguard Worker             if (ctx->cfg->use_gles &&
7103*bbecb9d1SAndroid Build Coastguard Worker                 ctx->outputs[i].name == TGSI_SEMANTIC_COLOR &&
7104*bbecb9d1SAndroid Build Coastguard Worker                 !ctx->cfg->has_dual_src_blend)
7105*bbecb9d1SAndroid Build Coastguard Worker                sprintf(prefix, "layout(location = %d)", ctx->outputs[i].sid);
7106*bbecb9d1SAndroid Build Coastguard Worker 
7107*bbecb9d1SAndroid Build Coastguard Worker             emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios, io_out, prefix, &ctx->outputs[i],
7108*bbecb9d1SAndroid Build Coastguard Worker                               ctx->outputs[i].fbfetch_used ? "inout" : "out", "");
7109*bbecb9d1SAndroid Build Coastguard Worker 
7110*bbecb9d1SAndroid Build Coastguard Worker          } else if (ctx->outputs[i].invariant || ctx->outputs[i].precise) {
7111*bbecb9d1SAndroid Build Coastguard Worker             emit_hdrf(glsl_strbufs, "%s%s;\n",
7112*bbecb9d1SAndroid Build Coastguard Worker                       ctx->outputs[i].precise ? "precise " :
7113*bbecb9d1SAndroid Build Coastguard Worker                       (ctx->outputs[i].invariant ? "invariant " : ""),
7114*bbecb9d1SAndroid Build Coastguard Worker                       ctx->outputs[i].glsl_name);
7115*bbecb9d1SAndroid Build Coastguard Worker          }
7116*bbecb9d1SAndroid Build Coastguard Worker       }
7117*bbecb9d1SAndroid Build Coastguard Worker    }
7118*bbecb9d1SAndroid Build Coastguard Worker 
7119*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->fs_depth_layout) {
7120*bbecb9d1SAndroid Build Coastguard Worker       const char *depth_layout = get_depth_layout(ctx->fs_depth_layout);
7121*bbecb9d1SAndroid Build Coastguard Worker       if (depth_layout)
7122*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "layout (%s) out float gl_FragDepth;\n", depth_layout);
7123*bbecb9d1SAndroid Build Coastguard Worker    }
7124*bbecb9d1SAndroid Build Coastguard Worker 
7125*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->num_in_clip_dist) {
7126*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->key->num_in_clip) {
7127*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "in float gl_ClipDistance[%d];\n", ctx->key->num_in_clip);
7128*bbecb9d1SAndroid Build Coastguard Worker       } else if (ctx->num_in_clip_dist > 4 && !ctx->key->num_in_cull) {
7129*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "in float gl_ClipDistance[%d];\n", ctx->num_in_clip_dist);
7130*bbecb9d1SAndroid Build Coastguard Worker       }
7131*bbecb9d1SAndroid Build Coastguard Worker 
7132*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->key->num_in_cull) {
7133*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "in float gl_CullDistance[%d];\n", ctx->key->num_in_cull);
7134*bbecb9d1SAndroid Build Coastguard Worker       }
7135*bbecb9d1SAndroid Build Coastguard Worker       if(ctx->fs_uses_clipdist_input)
7136*bbecb9d1SAndroid Build Coastguard Worker          emit_hdr(glsl_strbufs, "vec4 clip_dist_temp[2];\n");
7137*bbecb9d1SAndroid Build Coastguard Worker    }
7138*bbecb9d1SAndroid Build Coastguard Worker }
7139*bbecb9d1SAndroid Build Coastguard Worker 
7140*bbecb9d1SAndroid Build Coastguard Worker static bool
can_emit_generic_geom(const struct vrend_shader_io * io)7141*bbecb9d1SAndroid Build Coastguard Worker can_emit_generic_geom(const struct vrend_shader_io *io)
7142*bbecb9d1SAndroid Build Coastguard Worker {
7143*bbecb9d1SAndroid Build Coastguard Worker    return io->stream == 0;
7144*bbecb9d1SAndroid Build Coastguard Worker }
7145*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_per_vertex_in(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,bool * has_pervertex)7146*bbecb9d1SAndroid Build Coastguard Worker static void emit_ios_per_vertex_in(const struct dump_ctx *ctx,
7147*bbecb9d1SAndroid Build Coastguard Worker                                    struct vrend_glsl_strbufs *glsl_strbufs,
7148*bbecb9d1SAndroid Build Coastguard Worker                                    bool *has_pervertex)
7149*bbecb9d1SAndroid Build Coastguard Worker {
7150*bbecb9d1SAndroid Build Coastguard Worker    char clip_var[64] = "";
7151*bbecb9d1SAndroid Build Coastguard Worker    char cull_var[64] = "";
7152*bbecb9d1SAndroid Build Coastguard Worker 
7153*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->num_in_clip_dist) {
7154*bbecb9d1SAndroid Build Coastguard Worker       int clip_dist, cull_dist;
7155*bbecb9d1SAndroid Build Coastguard Worker 
7156*bbecb9d1SAndroid Build Coastguard Worker       clip_dist = ctx->key->num_in_clip;
7157*bbecb9d1SAndroid Build Coastguard Worker       cull_dist = ctx->key->num_in_cull;
7158*bbecb9d1SAndroid Build Coastguard Worker 
7159*bbecb9d1SAndroid Build Coastguard Worker       int num_clip_cull = clip_dist + cull_dist;
7160*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->num_in_clip_dist && !num_clip_cull)
7161*bbecb9d1SAndroid Build Coastguard Worker          clip_dist = ctx->num_in_clip_dist;
7162*bbecb9d1SAndroid Build Coastguard Worker 
7163*bbecb9d1SAndroid Build Coastguard Worker       if (clip_dist)
7164*bbecb9d1SAndroid Build Coastguard Worker          snprintf(clip_var, 64, "float gl_ClipDistance[%d];\n", clip_dist);
7165*bbecb9d1SAndroid Build Coastguard Worker       if (cull_dist)
7166*bbecb9d1SAndroid Build Coastguard Worker          snprintf(cull_var, 64, "float gl_CullDistance[%d];\n", cull_dist);
7167*bbecb9d1SAndroid Build Coastguard Worker 
7168*bbecb9d1SAndroid Build Coastguard Worker       (*has_pervertex) = true;
7169*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "in gl_PerVertex {\n vec4 gl_Position; \n %s%s%s\n} gl_in[];\n",
7170*bbecb9d1SAndroid Build Coastguard Worker                 clip_var, cull_var, ctx->has_pointsize_input ? "float gl_PointSize;\n" : "");
7171*bbecb9d1SAndroid Build Coastguard Worker 
7172*bbecb9d1SAndroid Build Coastguard Worker    }
7173*bbecb9d1SAndroid Build Coastguard Worker 
7174*bbecb9d1SAndroid Build Coastguard Worker }
7175*bbecb9d1SAndroid Build Coastguard Worker 
7176*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_per_vertex_out(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,const char * instance_var)7177*bbecb9d1SAndroid Build Coastguard Worker static void emit_ios_per_vertex_out(const struct dump_ctx *ctx,
7178*bbecb9d1SAndroid Build Coastguard Worker                                     struct vrend_glsl_strbufs *glsl_strbufs, const char *instance_var)
7179*bbecb9d1SAndroid Build Coastguard Worker {
7180*bbecb9d1SAndroid Build Coastguard Worker    int clip_dist = ctx->num_clip_dist_prop ? ctx->num_clip_dist_prop : ctx->key->num_out_clip;
7181*bbecb9d1SAndroid Build Coastguard Worker    int cull_dist = ctx->num_cull_dist_prop ? ctx->num_cull_dist_prop : ctx->key->num_out_cull;
7182*bbecb9d1SAndroid Build Coastguard Worker    int num_clip_cull = clip_dist + cull_dist;
7183*bbecb9d1SAndroid Build Coastguard Worker 
7184*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->num_out_clip_dist && !num_clip_cull)
7185*bbecb9d1SAndroid Build Coastguard Worker       clip_dist = ctx->num_out_clip_dist;
7186*bbecb9d1SAndroid Build Coastguard Worker 
7187*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->key->use_pervertex_in) {
7188*bbecb9d1SAndroid Build Coastguard Worker       char clip_var[64] = "", cull_var[64] = "";
7189*bbecb9d1SAndroid Build Coastguard Worker       if (cull_dist)
7190*bbecb9d1SAndroid Build Coastguard Worker          snprintf(cull_var, 64, "float gl_CullDistance[%d];\n", cull_dist);
7191*bbecb9d1SAndroid Build Coastguard Worker 
7192*bbecb9d1SAndroid Build Coastguard Worker       if (clip_dist)
7193*bbecb9d1SAndroid Build Coastguard Worker          snprintf(clip_var, 64, "float gl_ClipDistance[%d];\n", clip_dist);
7194*bbecb9d1SAndroid Build Coastguard Worker 
7195*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "out gl_PerVertex {\n vec4 gl_Position; \n %s%s%s\n} %s;\n",
7196*bbecb9d1SAndroid Build Coastguard Worker                 clip_var, cull_var,
7197*bbecb9d1SAndroid Build Coastguard Worker                 ctx->has_pointsize_output ? "float gl_PointSize;\n" : "",
7198*bbecb9d1SAndroid Build Coastguard Worker                 instance_var);
7199*bbecb9d1SAndroid Build Coastguard Worker    }
7200*bbecb9d1SAndroid Build Coastguard Worker 
7201*bbecb9d1SAndroid Build Coastguard Worker    if (clip_dist + cull_dist > 0)
7202*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "vec4 clip_dist_temp[2];\n");
7203*bbecb9d1SAndroid Build Coastguard Worker 
7204*bbecb9d1SAndroid Build Coastguard Worker }
7205*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_geom(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint8_t front_back_color_emitted_flags[],uint32_t * num_interps,bool * has_pervertex,bool * force_color_two_side)7206*bbecb9d1SAndroid Build Coastguard Worker static void emit_ios_geom(const struct dump_ctx *ctx,
7207*bbecb9d1SAndroid Build Coastguard Worker                           struct vrend_glsl_strbufs *glsl_strbufs,
7208*bbecb9d1SAndroid Build Coastguard Worker                           struct vrend_generic_ios *generic_ios,
7209*bbecb9d1SAndroid Build Coastguard Worker                           struct vrend_texcoord_ios *texcoord_ios,
7210*bbecb9d1SAndroid Build Coastguard Worker                           uint8_t front_back_color_emitted_flags[],
7211*bbecb9d1SAndroid Build Coastguard Worker                           uint32_t *num_interps,
7212*bbecb9d1SAndroid Build Coastguard Worker                           bool *has_pervertex,
7213*bbecb9d1SAndroid Build Coastguard Worker                           bool *force_color_two_side)
7214*bbecb9d1SAndroid Build Coastguard Worker {
7215*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
7216*bbecb9d1SAndroid Build Coastguard Worker    char invocbuf[25];
7217*bbecb9d1SAndroid Build Coastguard Worker 
7218*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->gs_num_invocations)
7219*bbecb9d1SAndroid Build Coastguard Worker       snprintf(invocbuf, 25, ", invocations = %d", ctx->gs_num_invocations);
7220*bbecb9d1SAndroid Build Coastguard Worker 
7221*bbecb9d1SAndroid Build Coastguard Worker    emit_hdrf(glsl_strbufs, "layout(%s%s) in;\n", prim_to_name(ctx->gs_in_prim),
7222*bbecb9d1SAndroid Build Coastguard Worker              ctx->gs_num_invocations > 1 ? invocbuf : "");
7223*bbecb9d1SAndroid Build Coastguard Worker    emit_hdrf(glsl_strbufs, "layout(%s, max_vertices = %d) out;\n", prim_to_name(ctx->gs_out_prim), ctx->gs_max_out_verts);
7224*bbecb9d1SAndroid Build Coastguard Worker 
7225*bbecb9d1SAndroid Build Coastguard Worker 
7226*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_inputs; i++) {
7227*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->inputs[i].glsl_predefined_no_emit) {
7228*bbecb9d1SAndroid Build Coastguard Worker          char postfix[64];
7229*bbecb9d1SAndroid Build Coastguard Worker          snprintf(postfix, sizeof(postfix), "[%d]", gs_input_prim_to_size(ctx->gs_in_prim));
7230*bbecb9d1SAndroid Build Coastguard Worker          emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios,
7231*bbecb9d1SAndroid Build Coastguard Worker                           io_in, "", &ctx->inputs[i], "in", postfix);
7232*bbecb9d1SAndroid Build Coastguard Worker       }
7233*bbecb9d1SAndroid Build Coastguard Worker    }
7234*bbecb9d1SAndroid Build Coastguard Worker 
7235*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_outputs; i++) {
7236*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->outputs[i].glsl_predefined_no_emit) {
7237*bbecb9d1SAndroid Build Coastguard Worker          if (!ctx->outputs[i].stream)
7238*bbecb9d1SAndroid Build Coastguard Worker             continue;
7239*bbecb9d1SAndroid Build Coastguard Worker 
7240*bbecb9d1SAndroid Build Coastguard Worker          const char *prefix = "";
7241*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC ||
7242*bbecb9d1SAndroid Build Coastguard Worker              ctx->outputs[i].name == TGSI_SEMANTIC_COLOR ||
7243*bbecb9d1SAndroid Build Coastguard Worker              ctx->outputs[i].name == TGSI_SEMANTIC_BCOLOR) {
7244*bbecb9d1SAndroid Build Coastguard Worker             (*num_interps)++;
7245*bbecb9d1SAndroid Build Coastguard Worker          }
7246*bbecb9d1SAndroid Build Coastguard Worker 
7247*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "layout (stream = %d) %s%s%sout vec4 %s;\n", ctx->outputs[i].stream, prefix,
7248*bbecb9d1SAndroid Build Coastguard Worker                    ctx->outputs[i].precise ? "precise " : "",
7249*bbecb9d1SAndroid Build Coastguard Worker                    ctx->outputs[i].invariant ? "invariant " : "",
7250*bbecb9d1SAndroid Build Coastguard Worker                    ctx->outputs[i].glsl_name);
7251*bbecb9d1SAndroid Build Coastguard Worker       }
7252*bbecb9d1SAndroid Build Coastguard Worker    }
7253*bbecb9d1SAndroid Build Coastguard Worker 
7254*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_indirect_generics_output(ctx, glsl_strbufs, "");
7255*bbecb9d1SAndroid Build Coastguard Worker 
7256*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_generic_outputs(ctx, glsl_strbufs, generic_ios, texcoord_ios,
7257*bbecb9d1SAndroid Build Coastguard Worker                             front_back_color_emitted_flags, force_color_two_side,
7258*bbecb9d1SAndroid Build Coastguard Worker                             num_interps, can_emit_generic_geom);
7259*bbecb9d1SAndroid Build Coastguard Worker 
7260*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_per_vertex_in(ctx, glsl_strbufs, has_pervertex);
7261*bbecb9d1SAndroid Build Coastguard Worker 
7262*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->has_clipvertex) {
7263*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "%svec4 clipv_tmp;\n", ctx->has_clipvertex_so ? "out " : "");
7264*bbecb9d1SAndroid Build Coastguard Worker    }
7265*bbecb9d1SAndroid Build Coastguard Worker 
7266*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->num_out_clip_dist) {
7267*bbecb9d1SAndroid Build Coastguard Worker       bool has_clip_or_cull_prop = ctx->num_clip_dist_prop + ctx->num_cull_dist_prop > 0;
7268*bbecb9d1SAndroid Build Coastguard Worker 
7269*bbecb9d1SAndroid Build Coastguard Worker       int num_clip_dists = has_clip_or_cull_prop ? ctx->num_clip_dist_prop :
7270*bbecb9d1SAndroid Build Coastguard Worker                                                    (ctx->num_out_clip_dist ? ctx->num_out_clip_dist : 8);
7271*bbecb9d1SAndroid Build Coastguard Worker       int num_cull_dists = has_clip_or_cull_prop ? ctx->num_cull_dist_prop : 0;
7272*bbecb9d1SAndroid Build Coastguard Worker 
7273*bbecb9d1SAndroid Build Coastguard Worker       char cull_buf[64] = "";
7274*bbecb9d1SAndroid Build Coastguard Worker       char clip_buf[64] = "";
7275*bbecb9d1SAndroid Build Coastguard Worker 
7276*bbecb9d1SAndroid Build Coastguard Worker       if (num_clip_dists)
7277*bbecb9d1SAndroid Build Coastguard Worker          snprintf(clip_buf, 64, "out float gl_ClipDistance[%d];\n", num_clip_dists);
7278*bbecb9d1SAndroid Build Coastguard Worker       if (num_cull_dists)
7279*bbecb9d1SAndroid Build Coastguard Worker          snprintf(cull_buf, 64, "out float gl_CullDistance[%d];\n", num_cull_dists);
7280*bbecb9d1SAndroid Build Coastguard Worker 
7281*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "%s%s\n", clip_buf, cull_buf);
7282*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "vec4 clip_dist_temp[2];\n");
7283*bbecb9d1SAndroid Build Coastguard Worker    }
7284*bbecb9d1SAndroid Build Coastguard Worker }
7285*bbecb9d1SAndroid Build Coastguard Worker 
7286*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_tcs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint64_t * emitted_out_patches_mask,bool * has_pervertex)7287*bbecb9d1SAndroid Build Coastguard Worker static void emit_ios_tcs(const struct dump_ctx *ctx,
7288*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_glsl_strbufs *glsl_strbufs,
7289*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_generic_ios *generic_ios,
7290*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_texcoord_ios *texcoord_ios,
7291*bbecb9d1SAndroid Build Coastguard Worker                          uint64_t *emitted_out_patches_mask,
7292*bbecb9d1SAndroid Build Coastguard Worker                          bool *has_pervertex)
7293*bbecb9d1SAndroid Build Coastguard Worker {
7294*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
7295*bbecb9d1SAndroid Build Coastguard Worker 
7296*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_indirect_generics_input(ctx, glsl_strbufs, "[]");
7297*bbecb9d1SAndroid Build Coastguard Worker 
7298*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_inputs; i++) {
7299*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->inputs[i].glsl_predefined_no_emit) {
7300*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[i].name == TGSI_SEMANTIC_PATCH) {
7301*bbecb9d1SAndroid Build Coastguard Worker             emit_ios_patch(glsl_strbufs, "",  &ctx->inputs[i], "in",
7302*bbecb9d1SAndroid Build Coastguard Worker                            ctx->inputs[i].last - ctx->inputs[i].first + 1,
7303*bbecb9d1SAndroid Build Coastguard Worker                            ctx->separable_program);
7304*bbecb9d1SAndroid Build Coastguard Worker          } else
7305*bbecb9d1SAndroid Build Coastguard Worker             emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios, io_in, "", &ctx->inputs[i], "in", "[]");
7306*bbecb9d1SAndroid Build Coastguard Worker       }
7307*bbecb9d1SAndroid Build Coastguard Worker    }
7308*bbecb9d1SAndroid Build Coastguard Worker 
7309*bbecb9d1SAndroid Build Coastguard Worker    uint64_t emitted_patches = 0;
7310*bbecb9d1SAndroid Build Coastguard Worker 
7311*bbecb9d1SAndroid Build Coastguard Worker    emit_hdrf(glsl_strbufs, "layout(vertices = %d) out;\n", ctx->tcs_vertices_out);
7312*bbecb9d1SAndroid Build Coastguard Worker 
7313*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->patch_ios.output_range.used)
7314*bbecb9d1SAndroid Build Coastguard Worker       emitted_patches |= emit_ios_patch(glsl_strbufs, "patch", &ctx->patch_ios.output_range.io, "out",
7315*bbecb9d1SAndroid Build Coastguard Worker                                         ctx->patch_ios.output_range.io.last - ctx->patch_ios.output_range.io.first + 1,
7316*bbecb9d1SAndroid Build Coastguard Worker                                         ctx->separable_program);
7317*bbecb9d1SAndroid Build Coastguard Worker 
7318*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_outputs; i++) {
7319*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->outputs[i].glsl_predefined_no_emit) {
7320*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->outputs[i].name == TGSI_SEMANTIC_PATCH) {
7321*bbecb9d1SAndroid Build Coastguard Worker 
7322*bbecb9d1SAndroid Build Coastguard Worker             emitted_patches |= emit_ios_patch(glsl_strbufs, "patch", &ctx->outputs[i], "out",
7323*bbecb9d1SAndroid Build Coastguard Worker                                               ctx->outputs[i].last - ctx->outputs[i].first + 1,
7324*bbecb9d1SAndroid Build Coastguard Worker                                               ctx->separable_program);
7325*bbecb9d1SAndroid Build Coastguard Worker          } else
7326*bbecb9d1SAndroid Build Coastguard Worker             emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios, io_out, "", &ctx->outputs[i], "out", "[]");
7327*bbecb9d1SAndroid Build Coastguard Worker       } else if (ctx->outputs[i].invariant || ctx->outputs[i].precise) {
7328*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "%s%s;\n",
7329*bbecb9d1SAndroid Build Coastguard Worker                    ctx->outputs[i].precise ? "precise " :
7330*bbecb9d1SAndroid Build Coastguard Worker                    (ctx->outputs[i].invariant ? "invariant " : ""),
7331*bbecb9d1SAndroid Build Coastguard Worker                    ctx->outputs[i].glsl_name);
7332*bbecb9d1SAndroid Build Coastguard Worker       }
7333*bbecb9d1SAndroid Build Coastguard Worker    }
7334*bbecb9d1SAndroid Build Coastguard Worker 
7335*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_per_vertex_in(ctx, glsl_strbufs, has_pervertex);
7336*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_per_vertex_out(ctx, glsl_strbufs, " gl_out[]");
7337*bbecb9d1SAndroid Build Coastguard Worker 
7338*bbecb9d1SAndroid Build Coastguard Worker    *emitted_out_patches_mask = emitted_patches;
7339*bbecb9d1SAndroid Build Coastguard Worker }
7340*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_tes(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint8_t front_back_color_emitted_flags[],uint32_t * num_interps,bool * has_pervertex,bool * force_color_two_side)7341*bbecb9d1SAndroid Build Coastguard Worker static void emit_ios_tes(const struct dump_ctx *ctx,
7342*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_glsl_strbufs *glsl_strbufs,
7343*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_generic_ios *generic_ios,
7344*bbecb9d1SAndroid Build Coastguard Worker                          struct vrend_texcoord_ios *texcoord_ios,
7345*bbecb9d1SAndroid Build Coastguard Worker                          uint8_t front_back_color_emitted_flags[],
7346*bbecb9d1SAndroid Build Coastguard Worker                          uint32_t *num_interps,
7347*bbecb9d1SAndroid Build Coastguard Worker                          bool *has_pervertex,
7348*bbecb9d1SAndroid Build Coastguard Worker                          bool *force_color_two_side)
7349*bbecb9d1SAndroid Build Coastguard Worker {
7350*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
7351*bbecb9d1SAndroid Build Coastguard Worker 
7352*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->patch_ios.input_range.used)
7353*bbecb9d1SAndroid Build Coastguard Worker       emit_ios_patch(glsl_strbufs, "patch", &ctx->patch_ios.input_range.io, "in",
7354*bbecb9d1SAndroid Build Coastguard Worker                      ctx->patch_ios.input_range.io.last -
7355*bbecb9d1SAndroid Build Coastguard Worker                         ctx->patch_ios.input_range.io.first + 1,
7356*bbecb9d1SAndroid Build Coastguard Worker                      ctx->separable_program);
7357*bbecb9d1SAndroid Build Coastguard Worker 
7358*bbecb9d1SAndroid Build Coastguard Worker    if (generic_ios->input_range.used)
7359*bbecb9d1SAndroid Build Coastguard Worker       emit_ios_indirect_generics_input(ctx, glsl_strbufs, "[]");
7360*bbecb9d1SAndroid Build Coastguard Worker 
7361*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_inputs; i++) {
7362*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->inputs[i].glsl_predefined_no_emit) {
7363*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[i].name == TGSI_SEMANTIC_PATCH)
7364*bbecb9d1SAndroid Build Coastguard Worker             emit_ios_patch(glsl_strbufs, "patch", &ctx->inputs[i], "in",
7365*bbecb9d1SAndroid Build Coastguard Worker                            ctx->inputs[i].last - ctx->inputs[i].first + 1,
7366*bbecb9d1SAndroid Build Coastguard Worker                            ctx->separable_program);
7367*bbecb9d1SAndroid Build Coastguard Worker          else
7368*bbecb9d1SAndroid Build Coastguard Worker             emit_ios_generic(ctx, glsl_strbufs, generic_ios, texcoord_ios, io_in, "", &ctx->inputs[i], "in", "[]");
7369*bbecb9d1SAndroid Build Coastguard Worker       }
7370*bbecb9d1SAndroid Build Coastguard Worker    }
7371*bbecb9d1SAndroid Build Coastguard Worker 
7372*bbecb9d1SAndroid Build Coastguard Worker    emit_hdrf(glsl_strbufs, "layout(%s, %s, %s%s) in;\n",
7373*bbecb9d1SAndroid Build Coastguard Worker              prim_to_tes_name(ctx->tes_prim_mode),
7374*bbecb9d1SAndroid Build Coastguard Worker              get_spacing_string(ctx->tes_spacing),
7375*bbecb9d1SAndroid Build Coastguard Worker              ctx->tes_vertex_order ? "cw" : "ccw",
7376*bbecb9d1SAndroid Build Coastguard Worker              ctx->tes_point_mode ? ", point_mode" : "");
7377*bbecb9d1SAndroid Build Coastguard Worker 
7378*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_indirect_generics_output(ctx, glsl_strbufs, "");
7379*bbecb9d1SAndroid Build Coastguard Worker 
7380*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_generic_outputs(ctx, glsl_strbufs, generic_ios, texcoord_ios,
7381*bbecb9d1SAndroid Build Coastguard Worker                             front_back_color_emitted_flags, force_color_two_side,
7382*bbecb9d1SAndroid Build Coastguard Worker                             num_interps, can_emit_generic_default);
7383*bbecb9d1SAndroid Build Coastguard Worker 
7384*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_per_vertex_in(ctx, glsl_strbufs, has_pervertex);
7385*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_per_vertex_out(ctx, glsl_strbufs, "");
7386*bbecb9d1SAndroid Build Coastguard Worker 
7387*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->has_clipvertex && !ctx->key->gs_present) {
7388*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "%svec4 clipv_tmp;\n", ctx->has_clipvertex_so ? "out " : "");
7389*bbecb9d1SAndroid Build Coastguard Worker    }
7390*bbecb9d1SAndroid Build Coastguard Worker 
7391*bbecb9d1SAndroid Build Coastguard Worker }
7392*bbecb9d1SAndroid Build Coastguard Worker 
7393*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios_cs(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs)7394*bbecb9d1SAndroid Build Coastguard Worker static void emit_ios_cs(const struct dump_ctx *ctx,
7395*bbecb9d1SAndroid Build Coastguard Worker                         struct vrend_glsl_strbufs *glsl_strbufs)
7396*bbecb9d1SAndroid Build Coastguard Worker {
7397*bbecb9d1SAndroid Build Coastguard Worker    emit_hdrf(glsl_strbufs, "layout (local_size_x = %d, local_size_y = %d, local_size_z = %d) in;\n",
7398*bbecb9d1SAndroid Build Coastguard Worker              ctx->local_cs_block_size[0], ctx->local_cs_block_size[1], ctx->local_cs_block_size[2]);
7399*bbecb9d1SAndroid Build Coastguard Worker 
7400*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->req_local_mem) {
7401*bbecb9d1SAndroid Build Coastguard Worker       enum vrend_type_qualifier type = ctx->integer_memory ? INT : UINT;
7402*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "shared %s values[%d];\n", get_string(type), ctx->req_local_mem / 4);
7403*bbecb9d1SAndroid Build Coastguard Worker    }
7404*bbecb9d1SAndroid Build Coastguard Worker }
7405*bbecb9d1SAndroid Build Coastguard Worker 
emit_interp_info(struct vrend_glsl_strbufs * glsl_strbufs,const struct vrend_shader_cfg * cfg,const struct vrend_fs_shader_info * fs_info,enum tgsi_semantic semantic,int sid,bool flatshade)7406*bbecb9d1SAndroid Build Coastguard Worker static void emit_interp_info(struct vrend_glsl_strbufs *glsl_strbufs,
7407*bbecb9d1SAndroid Build Coastguard Worker                              const struct vrend_shader_cfg *cfg,
7408*bbecb9d1SAndroid Build Coastguard Worker                              const struct vrend_fs_shader_info *fs_info,
7409*bbecb9d1SAndroid Build Coastguard Worker                              enum tgsi_semantic semantic, int sid, bool flatshade)
7410*bbecb9d1SAndroid Build Coastguard Worker {
7411*bbecb9d1SAndroid Build Coastguard Worker    for (int j = 0; j < fs_info->num_interps; ++j) {
7412*bbecb9d1SAndroid Build Coastguard Worker       if (fs_info->interpinfo[j].semantic_name == semantic &&
7413*bbecb9d1SAndroid Build Coastguard Worker           fs_info->interpinfo[j].semantic_index == sid) {
7414*bbecb9d1SAndroid Build Coastguard Worker          emit_hdrf(glsl_strbufs, "%s %s ",
7415*bbecb9d1SAndroid Build Coastguard Worker                    get_interp_string(cfg, fs_info->interpinfo[j].interpolate, flatshade),
7416*bbecb9d1SAndroid Build Coastguard Worker                    get_aux_string(fs_info->interpinfo[j].location));
7417*bbecb9d1SAndroid Build Coastguard Worker          break;
7418*bbecb9d1SAndroid Build Coastguard Worker       }
7419*bbecb9d1SAndroid Build Coastguard Worker    }
7420*bbecb9d1SAndroid Build Coastguard Worker }
7421*bbecb9d1SAndroid Build Coastguard Worker 
7422*bbecb9d1SAndroid Build Coastguard Worker struct sematic_info {
7423*bbecb9d1SAndroid Build Coastguard Worker    enum tgsi_semantic name;
7424*bbecb9d1SAndroid Build Coastguard Worker    const char prefix;
7425*bbecb9d1SAndroid Build Coastguard Worker };
7426*bbecb9d1SAndroid Build Coastguard Worker 
emit_match_interfaces(struct vrend_glsl_strbufs * glsl_strbufs,const struct dump_ctx * ctx,const struct vrend_interface_bits * match,const struct sematic_info * semantic)7427*bbecb9d1SAndroid Build Coastguard Worker static void emit_match_interfaces(struct vrend_glsl_strbufs *glsl_strbufs,
7428*bbecb9d1SAndroid Build Coastguard Worker                                   const struct dump_ctx *ctx,
7429*bbecb9d1SAndroid Build Coastguard Worker                                   const struct vrend_interface_bits *match,
7430*bbecb9d1SAndroid Build Coastguard Worker                                   const struct sematic_info *semantic)
7431*bbecb9d1SAndroid Build Coastguard Worker {
7432*bbecb9d1SAndroid Build Coastguard Worker    uint64_t mask = (match->outputs_expected_mask | match->outputs_emitted_mask)
7433*bbecb9d1SAndroid Build Coastguard Worker                    ^ match->outputs_emitted_mask;
7434*bbecb9d1SAndroid Build Coastguard Worker 
7435*bbecb9d1SAndroid Build Coastguard Worker    while (mask) {
7436*bbecb9d1SAndroid Build Coastguard Worker       int i = u_bit_scan64(&mask);
7437*bbecb9d1SAndroid Build Coastguard Worker       emit_interp_info(glsl_strbufs, ctx->cfg, &ctx->key->fs_info,
7438*bbecb9d1SAndroid Build Coastguard Worker                        semantic->name, i, ctx->key->flatshade);
7439*bbecb9d1SAndroid Build Coastguard Worker 
7440*bbecb9d1SAndroid Build Coastguard Worker       if (semantic->name == TGSI_SEMANTIC_GENERIC && ctx->separable_program)
7441*bbecb9d1SAndroid Build Coastguard Worker           emit_hdrf(glsl_strbufs, "layout(location=%d) ", i);
7442*bbecb9d1SAndroid Build Coastguard Worker 
7443*bbecb9d1SAndroid Build Coastguard Worker       emit_hdrf(glsl_strbufs, "out vec4 %s_%c%d%s;\n",
7444*bbecb9d1SAndroid Build Coastguard Worker                 get_stage_output_name_prefix(ctx->prog_type),
7445*bbecb9d1SAndroid Build Coastguard Worker                 semantic->prefix, i,
7446*bbecb9d1SAndroid Build Coastguard Worker                 ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ? "[]" : "");
7447*bbecb9d1SAndroid Build Coastguard Worker    }
7448*bbecb9d1SAndroid Build Coastguard Worker }
7449*bbecb9d1SAndroid Build Coastguard Worker 
emit_ios(const struct dump_ctx * ctx,struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_generic_ios * generic_ios,struct vrend_texcoord_ios * texcoord_ios,uint64_t * patches_emitted_mask,uint8_t front_back_color_emitted_flags[],uint32_t * num_interps,bool * has_pervertex,bool * force_color_two_side,uint32_t * shadow_samp_mask)7450*bbecb9d1SAndroid Build Coastguard Worker static int emit_ios(const struct dump_ctx *ctx,
7451*bbecb9d1SAndroid Build Coastguard Worker                     struct vrend_glsl_strbufs *glsl_strbufs,
7452*bbecb9d1SAndroid Build Coastguard Worker                     struct vrend_generic_ios *generic_ios,
7453*bbecb9d1SAndroid Build Coastguard Worker                     struct vrend_texcoord_ios *texcoord_ios,
7454*bbecb9d1SAndroid Build Coastguard Worker                     uint64_t *patches_emitted_mask,
7455*bbecb9d1SAndroid Build Coastguard Worker                     uint8_t front_back_color_emitted_flags[],
7456*bbecb9d1SAndroid Build Coastguard Worker                     uint32_t *num_interps,
7457*bbecb9d1SAndroid Build Coastguard Worker                     bool *has_pervertex,
7458*bbecb9d1SAndroid Build Coastguard Worker                     bool *force_color_two_side,
7459*bbecb9d1SAndroid Build Coastguard Worker                     uint32_t *shadow_samp_mask)
7460*bbecb9d1SAndroid Build Coastguard Worker {
7461*bbecb9d1SAndroid Build Coastguard Worker    *num_interps = 0;
7462*bbecb9d1SAndroid Build Coastguard Worker    int glsl_ver_required = ctx->glsl_ver_required;
7463*bbecb9d1SAndroid Build Coastguard Worker 
7464*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->so && ctx->so->num_outputs >= PIPE_MAX_SO_OUTPUTS) {
7465*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf( "Num outputs exceeded, max is %u\n", PIPE_MAX_SO_OUTPUTS);
7466*bbecb9d1SAndroid Build Coastguard Worker       set_hdr_error(glsl_strbufs);
7467*bbecb9d1SAndroid Build Coastguard Worker       return glsl_ver_required;
7468*bbecb9d1SAndroid Build Coastguard Worker    }
7469*bbecb9d1SAndroid Build Coastguard Worker 
7470*bbecb9d1SAndroid Build Coastguard Worker    switch (ctx->prog_type) {
7471*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_VERTEX:
7472*bbecb9d1SAndroid Build Coastguard Worker       emit_ios_vs(ctx, glsl_strbufs, generic_ios, texcoord_ios, num_interps, front_back_color_emitted_flags, force_color_two_side);
7473*bbecb9d1SAndroid Build Coastguard Worker       break;
7474*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_FRAGMENT:
7475*bbecb9d1SAndroid Build Coastguard Worker       emit_ios_fs(ctx, glsl_strbufs, generic_ios, texcoord_ios, num_interps);
7476*bbecb9d1SAndroid Build Coastguard Worker       break;
7477*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_GEOMETRY:
7478*bbecb9d1SAndroid Build Coastguard Worker       emit_ios_geom(ctx, glsl_strbufs, generic_ios, texcoord_ios, front_back_color_emitted_flags, num_interps, has_pervertex, force_color_two_side);
7479*bbecb9d1SAndroid Build Coastguard Worker       break;
7480*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_TESS_CTRL:
7481*bbecb9d1SAndroid Build Coastguard Worker       emit_ios_tcs(ctx, glsl_strbufs, generic_ios, texcoord_ios, patches_emitted_mask, has_pervertex);
7482*bbecb9d1SAndroid Build Coastguard Worker       break;
7483*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_TESS_EVAL:
7484*bbecb9d1SAndroid Build Coastguard Worker       emit_ios_tes(ctx, glsl_strbufs, generic_ios, texcoord_ios, front_back_color_emitted_flags, num_interps, has_pervertex, force_color_two_side);
7485*bbecb9d1SAndroid Build Coastguard Worker       break;
7486*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_PROCESSOR_COMPUTE:
7487*bbecb9d1SAndroid Build Coastguard Worker       emit_ios_cs(ctx, glsl_strbufs);
7488*bbecb9d1SAndroid Build Coastguard Worker       break;
7489*bbecb9d1SAndroid Build Coastguard Worker    default:
7490*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf("Unknown shader processor %d\n", ctx->prog_type);
7491*bbecb9d1SAndroid Build Coastguard Worker       set_hdr_error(glsl_strbufs);
7492*bbecb9d1SAndroid Build Coastguard Worker       return glsl_ver_required;
7493*bbecb9d1SAndroid Build Coastguard Worker    }
7494*bbecb9d1SAndroid Build Coastguard Worker 
7495*bbecb9d1SAndroid Build Coastguard Worker    const struct sematic_info generic = {TGSI_SEMANTIC_GENERIC, 'g'};
7496*bbecb9d1SAndroid Build Coastguard Worker    const struct sematic_info texcoord = {TGSI_SEMANTIC_TEXCOORD, 't'};
7497*bbecb9d1SAndroid Build Coastguard Worker 
7498*bbecb9d1SAndroid Build Coastguard Worker    emit_match_interfaces(glsl_strbufs, ctx, &generic_ios->match, &generic);
7499*bbecb9d1SAndroid Build Coastguard Worker    emit_match_interfaces(glsl_strbufs, ctx, &texcoord_ios->match, &texcoord);
7500*bbecb9d1SAndroid Build Coastguard Worker 
7501*bbecb9d1SAndroid Build Coastguard Worker    emit_ios_streamout(ctx, glsl_strbufs);
7502*bbecb9d1SAndroid Build Coastguard Worker    glsl_ver_required = emit_ios_common(ctx, glsl_strbufs, shadow_samp_mask);
7503*bbecb9d1SAndroid Build Coastguard Worker 
7504*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT &&
7505*bbecb9d1SAndroid Build Coastguard Worker        ctx->key->pstipple_enabled) {
7506*bbecb9d1SAndroid Build Coastguard Worker       emit_hdr(glsl_strbufs, "uint stip_temp;\n");
7507*bbecb9d1SAndroid Build Coastguard Worker    }
7508*bbecb9d1SAndroid Build Coastguard Worker 
7509*bbecb9d1SAndroid Build Coastguard Worker    return glsl_ver_required;
7510*bbecb9d1SAndroid Build Coastguard Worker }
7511*bbecb9d1SAndroid Build Coastguard Worker 
fill_fragment_interpolants(const struct dump_ctx * ctx,struct vrend_fs_shader_info * fs_info)7512*bbecb9d1SAndroid Build Coastguard Worker static boolean fill_fragment_interpolants(const struct dump_ctx *ctx, struct vrend_fs_shader_info *fs_info)
7513*bbecb9d1SAndroid Build Coastguard Worker {
7514*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i, index = 0;
7515*bbecb9d1SAndroid Build Coastguard Worker 
7516*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < ctx->num_inputs; i++) {
7517*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->inputs[i].glsl_predefined_no_emit)
7518*bbecb9d1SAndroid Build Coastguard Worker          continue;
7519*bbecb9d1SAndroid Build Coastguard Worker 
7520*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->inputs[i].name != TGSI_SEMANTIC_GENERIC &&
7521*bbecb9d1SAndroid Build Coastguard Worker           ctx->inputs[i].name != TGSI_SEMANTIC_COLOR)
7522*bbecb9d1SAndroid Build Coastguard Worker          continue;
7523*bbecb9d1SAndroid Build Coastguard Worker 
7524*bbecb9d1SAndroid Build Coastguard Worker       if (index >= ctx->num_interps) {
7525*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf( "mismatch in number of interps %d %d\n", index, ctx->num_interps);
7526*bbecb9d1SAndroid Build Coastguard Worker          return true;
7527*bbecb9d1SAndroid Build Coastguard Worker       }
7528*bbecb9d1SAndroid Build Coastguard Worker       fs_info->interpinfo[index].semantic_name = ctx->inputs[i].name;
7529*bbecb9d1SAndroid Build Coastguard Worker       fs_info->interpinfo[index].semantic_index = ctx->inputs[i].sid;
7530*bbecb9d1SAndroid Build Coastguard Worker       fs_info->interpinfo[index].interpolate = ctx->inputs[i].interpolate;
7531*bbecb9d1SAndroid Build Coastguard Worker       fs_info->interpinfo[index].location = ctx->inputs[i].location;
7532*bbecb9d1SAndroid Build Coastguard Worker       index++;
7533*bbecb9d1SAndroid Build Coastguard Worker    }
7534*bbecb9d1SAndroid Build Coastguard Worker    return true;
7535*bbecb9d1SAndroid Build Coastguard Worker }
7536*bbecb9d1SAndroid Build Coastguard Worker 
fill_interpolants(const struct dump_ctx * ctx,struct vrend_variable_shader_info * sinfo)7537*bbecb9d1SAndroid Build Coastguard Worker static boolean fill_interpolants(const struct dump_ctx *ctx, struct vrend_variable_shader_info *sinfo)
7538*bbecb9d1SAndroid Build Coastguard Worker {
7539*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx->num_interps)
7540*bbecb9d1SAndroid Build Coastguard Worker       return true;
7541*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->prog_type != TGSI_PROCESSOR_FRAGMENT)
7542*bbecb9d1SAndroid Build Coastguard Worker       return true;
7543*bbecb9d1SAndroid Build Coastguard Worker 
7544*bbecb9d1SAndroid Build Coastguard Worker    return fill_fragment_interpolants(ctx, &sinfo->fs_info);
7545*bbecb9d1SAndroid Build Coastguard Worker }
7546*bbecb9d1SAndroid Build Coastguard Worker 
analyze_instruction(struct tgsi_iterate_context * iter,struct tgsi_full_instruction * inst)7547*bbecb9d1SAndroid Build Coastguard Worker static boolean analyze_instruction(struct tgsi_iterate_context *iter,
7548*bbecb9d1SAndroid Build Coastguard Worker                                    struct tgsi_full_instruction *inst)
7549*bbecb9d1SAndroid Build Coastguard Worker {
7550*bbecb9d1SAndroid Build Coastguard Worker    struct dump_ctx *ctx = (struct dump_ctx *)iter;
7551*bbecb9d1SAndroid Build Coastguard Worker    uint32_t opcode = inst->Instruction.Opcode;
7552*bbecb9d1SAndroid Build Coastguard Worker    if (opcode == TGSI_OPCODE_ATOMIMIN || opcode == TGSI_OPCODE_ATOMIMAX) {
7553*bbecb9d1SAndroid Build Coastguard Worker        const struct tgsi_full_src_register *src = &inst->Src[0];
7554*bbecb9d1SAndroid Build Coastguard Worker        if (src->Register.File == TGSI_FILE_BUFFER)
7555*bbecb9d1SAndroid Build Coastguard Worker          ctx->ssbo_integer_mask |= 1 << src->Register.Index;
7556*bbecb9d1SAndroid Build Coastguard Worker        if (src->Register.File == TGSI_FILE_MEMORY)
7557*bbecb9d1SAndroid Build Coastguard Worker          ctx->integer_memory = true;
7558*bbecb9d1SAndroid Build Coastguard Worker    }
7559*bbecb9d1SAndroid Build Coastguard Worker 
7560*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx->fs_uses_clipdist_input && (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT)) {
7561*bbecb9d1SAndroid Build Coastguard Worker       for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) {
7562*bbecb9d1SAndroid Build Coastguard Worker          if (inst->Src[i].Register.File == TGSI_FILE_INPUT) {
7563*bbecb9d1SAndroid Build Coastguard Worker             int idx = inst->Src[i].Register.Index;
7564*bbecb9d1SAndroid Build Coastguard Worker             for (unsigned j = 0; j < ctx->num_inputs; ++j) {
7565*bbecb9d1SAndroid Build Coastguard Worker                if (ctx->inputs[j].first <= idx && ctx->inputs[j].last >= idx &&
7566*bbecb9d1SAndroid Build Coastguard Worker                    ctx->inputs[j].name == TGSI_SEMANTIC_CLIPDIST) {
7567*bbecb9d1SAndroid Build Coastguard Worker                   ctx->fs_uses_clipdist_input = true;
7568*bbecb9d1SAndroid Build Coastguard Worker                   break;
7569*bbecb9d1SAndroid Build Coastguard Worker                }
7570*bbecb9d1SAndroid Build Coastguard Worker             }
7571*bbecb9d1SAndroid Build Coastguard Worker          }
7572*bbecb9d1SAndroid Build Coastguard Worker       }
7573*bbecb9d1SAndroid Build Coastguard Worker    }
7574*bbecb9d1SAndroid Build Coastguard Worker 
7575*bbecb9d1SAndroid Build Coastguard Worker 
7576*bbecb9d1SAndroid Build Coastguard Worker    return true;
7577*bbecb9d1SAndroid Build Coastguard Worker }
7578*bbecb9d1SAndroid Build Coastguard Worker 
fill_var_sinfo(const struct dump_ctx * ctx,struct vrend_variable_shader_info * sinfo)7579*bbecb9d1SAndroid Build Coastguard Worker static void fill_var_sinfo(const struct dump_ctx *ctx, struct vrend_variable_shader_info *sinfo)
7580*bbecb9d1SAndroid Build Coastguard Worker {
7581*bbecb9d1SAndroid Build Coastguard Worker    sinfo->num_ucp = ctx->is_last_vertex_stage ? VIRGL_NUM_CLIP_PLANES : 0;
7582*bbecb9d1SAndroid Build Coastguard Worker    sinfo->fs_info.has_sample_input = ctx->has_sample_input;
7583*bbecb9d1SAndroid Build Coastguard Worker    sinfo->fs_info.has_noperspective = ctx->has_noperspective;
7584*bbecb9d1SAndroid Build Coastguard Worker    sinfo->fs_info.num_interps = ctx->num_interps;
7585*bbecb9d1SAndroid Build Coastguard Worker    sinfo->fs_info.glsl_ver = ctx->glsl_ver_required;
7586*bbecb9d1SAndroid Build Coastguard Worker    bool has_prop = (ctx->num_clip_dist_prop + ctx->num_cull_dist_prop) > 0;
7587*bbecb9d1SAndroid Build Coastguard Worker 
7588*bbecb9d1SAndroid Build Coastguard Worker    sinfo->num_in_clip = has_prop ? ctx->num_clip_dist_prop : ctx->key->num_in_clip;
7589*bbecb9d1SAndroid Build Coastguard Worker    sinfo->num_in_cull = has_prop ? ctx->num_cull_dist_prop : ctx->key->num_in_cull;
7590*bbecb9d1SAndroid Build Coastguard Worker    sinfo->num_out_clip = has_prop ? ctx->num_clip_dist_prop : ctx->key->num_out_clip;
7591*bbecb9d1SAndroid Build Coastguard Worker    sinfo->num_out_cull = has_prop ? ctx->num_cull_dist_prop : ctx->key->num_out_cull;
7592*bbecb9d1SAndroid Build Coastguard Worker    sinfo->legacy_color_bits = ctx->color_out_mask;
7593*bbecb9d1SAndroid Build Coastguard Worker }
7594*bbecb9d1SAndroid Build Coastguard Worker 
fill_sinfo(const struct dump_ctx * ctx,struct vrend_shader_info * sinfo)7595*bbecb9d1SAndroid Build Coastguard Worker static void fill_sinfo(const struct dump_ctx *ctx, struct vrend_shader_info *sinfo)
7596*bbecb9d1SAndroid Build Coastguard Worker {
7597*bbecb9d1SAndroid Build Coastguard Worker    sinfo->use_pervertex_in = ctx->has_pervertex;
7598*bbecb9d1SAndroid Build Coastguard Worker    sinfo->samplers_used_mask = ctx->samplers_used;
7599*bbecb9d1SAndroid Build Coastguard Worker    sinfo->images_used_mask = ctx->images_used_mask;
7600*bbecb9d1SAndroid Build Coastguard Worker    sinfo->num_consts = ctx->num_consts;
7601*bbecb9d1SAndroid Build Coastguard Worker    sinfo->ubo_used_mask = ctx->ubo_used_mask;
7602*bbecb9d1SAndroid Build Coastguard Worker    sinfo->fog_input_mask = ctx->fog_input_mask;
7603*bbecb9d1SAndroid Build Coastguard Worker    sinfo->fog_output_mask = ctx->fog_output_mask;
7604*bbecb9d1SAndroid Build Coastguard Worker 
7605*bbecb9d1SAndroid Build Coastguard Worker    sinfo->ssbo_used_mask = ctx->ssbo_used_mask;
7606*bbecb9d1SAndroid Build Coastguard Worker 
7607*bbecb9d1SAndroid Build Coastguard Worker    sinfo->ubo_indirect = !!(ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT));
7608*bbecb9d1SAndroid Build Coastguard Worker 
7609*bbecb9d1SAndroid Build Coastguard Worker    sinfo->has_output_arrays = ctx->has_output_arrays;
7610*bbecb9d1SAndroid Build Coastguard Worker    sinfo->has_input_arrays = ctx->has_input_arrays;
7611*bbecb9d1SAndroid Build Coastguard Worker 
7612*bbecb9d1SAndroid Build Coastguard Worker    sinfo->out_generic_emitted_mask = ctx->generic_ios.match.outputs_emitted_mask;
7613*bbecb9d1SAndroid Build Coastguard Worker    sinfo->out_texcoord_emitted_mask = ctx->texcoord_ios.match.outputs_emitted_mask;
7614*bbecb9d1SAndroid Build Coastguard Worker    sinfo->out_patch_emitted_mask = ctx->patches_emitted_mask;
7615*bbecb9d1SAndroid Build Coastguard Worker 
7616*bbecb9d1SAndroid Build Coastguard Worker    sinfo->num_inputs = ctx->num_inputs;
7617*bbecb9d1SAndroid Build Coastguard Worker    sinfo->num_outputs = ctx->num_outputs;
7618*bbecb9d1SAndroid Build Coastguard Worker    sinfo->shadow_samp_mask = ctx->shadow_samp_mask;
7619*bbecb9d1SAndroid Build Coastguard Worker    sinfo->gs_out_prim = ctx->gs_out_prim;
7620*bbecb9d1SAndroid Build Coastguard Worker    sinfo->tes_prim = ctx->tes_prim_mode;
7621*bbecb9d1SAndroid Build Coastguard Worker    sinfo->tes_point_mode = ctx->tes_point_mode;
7622*bbecb9d1SAndroid Build Coastguard Worker    sinfo->fs_blend_equation_advanced = ctx->fs_blend_equation_advanced;
7623*bbecb9d1SAndroid Build Coastguard Worker    sinfo->separable_program = ctx->separable_program;
7624*bbecb9d1SAndroid Build Coastguard Worker 
7625*bbecb9d1SAndroid Build Coastguard Worker    if (sinfo->so_names || ctx->so_names) {
7626*bbecb9d1SAndroid Build Coastguard Worker       if (sinfo->so_names) {
7627*bbecb9d1SAndroid Build Coastguard Worker          for (unsigned i = 0; i < sinfo->so_info.num_outputs; ++i)
7628*bbecb9d1SAndroid Build Coastguard Worker             free(sinfo->so_names[i]);
7629*bbecb9d1SAndroid Build Coastguard Worker          free(sinfo->so_names);
7630*bbecb9d1SAndroid Build Coastguard Worker       }
7631*bbecb9d1SAndroid Build Coastguard Worker    }
7632*bbecb9d1SAndroid Build Coastguard Worker 
7633*bbecb9d1SAndroid Build Coastguard Worker    /* Record information about the layout of generics and patches for apssing it
7634*bbecb9d1SAndroid Build Coastguard Worker     * to the next shader stage. mesa/tgsi doesn't provide this information for
7635*bbecb9d1SAndroid Build Coastguard Worker     * TCS, TES, and GEOM shaders.
7636*bbecb9d1SAndroid Build Coastguard Worker     */
7637*bbecb9d1SAndroid Build Coastguard Worker    for(unsigned i = 0; i < ctx->num_outputs; i++) {
7638*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT) {
7639*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR)
7640*bbecb9d1SAndroid Build Coastguard Worker             sinfo->fs_output_layout[i] = ctx->outputs[i].sid;
7641*bbecb9d1SAndroid Build Coastguard Worker          else
7642*bbecb9d1SAndroid Build Coastguard Worker             sinfo->fs_output_layout[i] = -1;
7643*bbecb9d1SAndroid Build Coastguard Worker       }
7644*bbecb9d1SAndroid Build Coastguard Worker    }
7645*bbecb9d1SAndroid Build Coastguard Worker 
7646*bbecb9d1SAndroid Build Coastguard Worker    sinfo->so_names = ctx->so_names;
7647*bbecb9d1SAndroid Build Coastguard Worker    sinfo->attrib_input_mask = ctx->attrib_input_mask;
7648*bbecb9d1SAndroid Build Coastguard Worker    if (sinfo->sampler_arrays)
7649*bbecb9d1SAndroid Build Coastguard Worker       free(sinfo->sampler_arrays);
7650*bbecb9d1SAndroid Build Coastguard Worker    sinfo->sampler_arrays = ctx->sampler_arrays;
7651*bbecb9d1SAndroid Build Coastguard Worker    sinfo->num_sampler_arrays = ctx->num_sampler_arrays;
7652*bbecb9d1SAndroid Build Coastguard Worker    if (sinfo->image_arrays)
7653*bbecb9d1SAndroid Build Coastguard Worker       free(sinfo->image_arrays);
7654*bbecb9d1SAndroid Build Coastguard Worker    sinfo->image_arrays = ctx->image_arrays;
7655*bbecb9d1SAndroid Build Coastguard Worker    sinfo->num_image_arrays = ctx->num_image_arrays;
7656*bbecb9d1SAndroid Build Coastguard Worker    sinfo->in_generic_emitted_mask = ctx->generic_ios.match.inputs_emitted_mask;
7657*bbecb9d1SAndroid Build Coastguard Worker    sinfo->in_texcoord_emitted_mask = ctx->texcoord_ios.match.inputs_emitted_mask;
7658*bbecb9d1SAndroid Build Coastguard Worker 
7659*bbecb9d1SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ctx->num_outputs; ++i) {
7660*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->outputs[i].invariant) {
7661*bbecb9d1SAndroid Build Coastguard Worker          uint32_t bit_pos = varying_bit_from_semantic_and_index(ctx->outputs[i].name, ctx->outputs[i].sid);
7662*bbecb9d1SAndroid Build Coastguard Worker          uint32_t slot = bit_pos / 32;
7663*bbecb9d1SAndroid Build Coastguard Worker          uint32_t bit = 1u << (bit_pos & 0x1f);
7664*bbecb9d1SAndroid Build Coastguard Worker          sinfo->invariant_outputs[slot] |= bit;
7665*bbecb9d1SAndroid Build Coastguard Worker       }
7666*bbecb9d1SAndroid Build Coastguard Worker    }
7667*bbecb9d1SAndroid Build Coastguard Worker    sinfo->gles_use_tex_query_level = ctx->gles_use_tex_query_level;
7668*bbecb9d1SAndroid Build Coastguard Worker 
7669*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->guest_sent_io_arrays) {
7670*bbecb9d1SAndroid Build Coastguard Worker       sinfo->output_arrays.num_arrays = 0;
7671*bbecb9d1SAndroid Build Coastguard Worker       for (unsigned i = 0; i < ctx->num_outputs; ++i) {
7672*bbecb9d1SAndroid Build Coastguard Worker          const struct vrend_shader_io *io = &ctx->outputs[i];
7673*bbecb9d1SAndroid Build Coastguard Worker          if (io->array_id  > 0) {
7674*bbecb9d1SAndroid Build Coastguard Worker             struct vrend_shader_io_array *array =
7675*bbecb9d1SAndroid Build Coastguard Worker                   &sinfo->output_arrays.layout[sinfo->output_arrays.num_arrays];
7676*bbecb9d1SAndroid Build Coastguard Worker             array->sid = io->sid;
7677*bbecb9d1SAndroid Build Coastguard Worker             array->size = io->last - io->first;
7678*bbecb9d1SAndroid Build Coastguard Worker             array->name = io->name;
7679*bbecb9d1SAndroid Build Coastguard Worker             array->array_id = io->array_id;
7680*bbecb9d1SAndroid Build Coastguard Worker             ++sinfo->output_arrays.num_arrays;
7681*bbecb9d1SAndroid Build Coastguard Worker          }
7682*bbecb9d1SAndroid Build Coastguard Worker       }
7683*bbecb9d1SAndroid Build Coastguard Worker    }
7684*bbecb9d1SAndroid Build Coastguard Worker }
7685*bbecb9d1SAndroid Build Coastguard Worker 
allocate_strbuffers(struct vrend_glsl_strbufs * glsl_strbufs)7686*bbecb9d1SAndroid Build Coastguard Worker static bool allocate_strbuffers(struct vrend_glsl_strbufs* glsl_strbufs)
7687*bbecb9d1SAndroid Build Coastguard Worker {
7688*bbecb9d1SAndroid Build Coastguard Worker    if (!strbuf_alloc(&glsl_strbufs->glsl_main, 4096))
7689*bbecb9d1SAndroid Build Coastguard Worker       return false;
7690*bbecb9d1SAndroid Build Coastguard Worker 
7691*bbecb9d1SAndroid Build Coastguard Worker    if (strbuf_get_error(&glsl_strbufs->glsl_main))
7692*bbecb9d1SAndroid Build Coastguard Worker       return false;
7693*bbecb9d1SAndroid Build Coastguard Worker 
7694*bbecb9d1SAndroid Build Coastguard Worker    if (!strbuf_alloc(&glsl_strbufs->glsl_hdr, 1024))
7695*bbecb9d1SAndroid Build Coastguard Worker       return false;
7696*bbecb9d1SAndroid Build Coastguard Worker 
7697*bbecb9d1SAndroid Build Coastguard Worker    if (!strbuf_alloc(&glsl_strbufs->glsl_ver_ext, 1024))
7698*bbecb9d1SAndroid Build Coastguard Worker       return false;
7699*bbecb9d1SAndroid Build Coastguard Worker 
7700*bbecb9d1SAndroid Build Coastguard Worker    return true;
7701*bbecb9d1SAndroid Build Coastguard Worker }
7702*bbecb9d1SAndroid Build Coastguard Worker 
set_strbuffers(const struct vrend_glsl_strbufs * glsl_strbufs,struct vrend_strarray * shader)7703*bbecb9d1SAndroid Build Coastguard Worker static void set_strbuffers(const struct vrend_glsl_strbufs* glsl_strbufs,
7704*bbecb9d1SAndroid Build Coastguard Worker                            struct vrend_strarray *shader)
7705*bbecb9d1SAndroid Build Coastguard Worker {
7706*bbecb9d1SAndroid Build Coastguard Worker    strarray_addstrbuf(shader, &glsl_strbufs->glsl_ver_ext);
7707*bbecb9d1SAndroid Build Coastguard Worker    strarray_addstrbuf(shader, &glsl_strbufs->glsl_hdr);
7708*bbecb9d1SAndroid Build Coastguard Worker    strarray_addstrbuf(shader, &glsl_strbufs->glsl_main);
7709*bbecb9d1SAndroid Build Coastguard Worker }
7710*bbecb9d1SAndroid Build Coastguard Worker 
emit_required_sysval_uniforms(struct vrend_strbuf * block,uint32_t mask)7711*bbecb9d1SAndroid Build Coastguard Worker static void emit_required_sysval_uniforms(struct vrend_strbuf *block, uint32_t mask)
7712*bbecb9d1SAndroid Build Coastguard Worker {
7713*bbecb9d1SAndroid Build Coastguard Worker    if (!mask)
7714*bbecb9d1SAndroid Build Coastguard Worker       return;
7715*bbecb9d1SAndroid Build Coastguard Worker 
7716*bbecb9d1SAndroid Build Coastguard Worker    strbuf_append(block, "layout (std140) uniform VirglBlock {\n");
7717*bbecb9d1SAndroid Build Coastguard Worker    strbuf_append(block, "\tvec4 clipp[8];\n");
7718*bbecb9d1SAndroid Build Coastguard Worker    strbuf_appendf(block, "\tuint stipple_pattern[%d];\n", VREND_POLYGON_STIPPLE_SIZE);
7719*bbecb9d1SAndroid Build Coastguard Worker    strbuf_append(block, "\tfloat winsys_adjust_y;\n");
7720*bbecb9d1SAndroid Build Coastguard Worker    strbuf_append(block, "\tfloat alpha_ref_val;\n");
7721*bbecb9d1SAndroid Build Coastguard Worker    strbuf_append(block, "\tbool clip_plane_enabled;\n");
7722*bbecb9d1SAndroid Build Coastguard Worker    strbuf_append(block, "};\n");
7723*bbecb9d1SAndroid Build Coastguard Worker 
7724*bbecb9d1SAndroid Build Coastguard Worker }
7725*bbecb9d1SAndroid Build Coastguard Worker 
compare_sid(const void * lhs,const void * rhs)7726*bbecb9d1SAndroid Build Coastguard Worker static int compare_sid(const void *lhs, const void *rhs)
7727*bbecb9d1SAndroid Build Coastguard Worker {
7728*bbecb9d1SAndroid Build Coastguard Worker    const struct vrend_shader_io *l = (struct vrend_shader_io *)lhs;
7729*bbecb9d1SAndroid Build Coastguard Worker    const struct vrend_shader_io *r = (struct vrend_shader_io *)rhs;
7730*bbecb9d1SAndroid Build Coastguard Worker 
7731*bbecb9d1SAndroid Build Coastguard Worker    if (l->name != r->name)
7732*bbecb9d1SAndroid Build Coastguard Worker       return l->name - r->name;
7733*bbecb9d1SAndroid Build Coastguard Worker 
7734*bbecb9d1SAndroid Build Coastguard Worker    return l->sid - r->sid;
7735*bbecb9d1SAndroid Build Coastguard Worker }
7736*bbecb9d1SAndroid Build Coastguard Worker 
7737*bbecb9d1SAndroid Build Coastguard Worker struct sso_scan_ctx {
7738*bbecb9d1SAndroid Build Coastguard Worker    struct tgsi_iterate_context iter;
7739*bbecb9d1SAndroid Build Coastguard Worker    const struct vrend_shader_cfg *cfg;
7740*bbecb9d1SAndroid Build Coastguard Worker    uint8_t max_generic_in_sid;
7741*bbecb9d1SAndroid Build Coastguard Worker    uint8_t max_patch_in_sid;
7742*bbecb9d1SAndroid Build Coastguard Worker    uint8_t max_generic_out_sid;
7743*bbecb9d1SAndroid Build Coastguard Worker    uint8_t max_patch_out_sid;
7744*bbecb9d1SAndroid Build Coastguard Worker    bool separable_program;
7745*bbecb9d1SAndroid Build Coastguard Worker    bool unsupported_io;
7746*bbecb9d1SAndroid Build Coastguard Worker };
7747*bbecb9d1SAndroid Build Coastguard Worker 
7748*bbecb9d1SAndroid Build Coastguard Worker static boolean
iter_prop_for_separable(struct tgsi_iterate_context * iter,struct tgsi_full_property * prop)7749*bbecb9d1SAndroid Build Coastguard Worker iter_prop_for_separable(struct tgsi_iterate_context *iter,
7750*bbecb9d1SAndroid Build Coastguard Worker           struct tgsi_full_property *prop)
7751*bbecb9d1SAndroid Build Coastguard Worker {
7752*bbecb9d1SAndroid Build Coastguard Worker    struct sso_scan_ctx *ctx = (struct sso_scan_ctx *) iter;
7753*bbecb9d1SAndroid Build Coastguard Worker 
7754*bbecb9d1SAndroid Build Coastguard Worker    if (prop->Property.PropertyName == TGSI_PROPERTY_SEPARABLE_PROGRAM)
7755*bbecb9d1SAndroid Build Coastguard Worker       ctx->separable_program = prop->u[0].Data != 0;
7756*bbecb9d1SAndroid Build Coastguard Worker    return true;
7757*bbecb9d1SAndroid Build Coastguard Worker }
7758*bbecb9d1SAndroid Build Coastguard Worker 
7759*bbecb9d1SAndroid Build Coastguard Worker static boolean
iter_decl_for_overlap(struct tgsi_iterate_context * iter,struct tgsi_full_declaration * decl)7760*bbecb9d1SAndroid Build Coastguard Worker iter_decl_for_overlap(struct tgsi_iterate_context *iter,
7761*bbecb9d1SAndroid Build Coastguard Worker                       struct tgsi_full_declaration *decl)
7762*bbecb9d1SAndroid Build Coastguard Worker {
7763*bbecb9d1SAndroid Build Coastguard Worker    struct sso_scan_ctx *ctx = (struct sso_scan_ctx *) iter;
7764*bbecb9d1SAndroid Build Coastguard Worker 
7765*bbecb9d1SAndroid Build Coastguard Worker    /* VS inputs and FS outputs are of no interest
7766*bbecb9d1SAndroid Build Coastguard Worker     * when it comes to IO matching */
7767*bbecb9d1SAndroid Build Coastguard Worker    if (decl->Declaration.File == TGSI_FILE_INPUT &&
7768*bbecb9d1SAndroid Build Coastguard Worker        iter->processor.Processor == TGSI_PROCESSOR_VERTEX)
7769*bbecb9d1SAndroid Build Coastguard Worker       return true;
7770*bbecb9d1SAndroid Build Coastguard Worker 
7771*bbecb9d1SAndroid Build Coastguard Worker    if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
7772*bbecb9d1SAndroid Build Coastguard Worker        iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT)
7773*bbecb9d1SAndroid Build Coastguard Worker       return true;
7774*bbecb9d1SAndroid Build Coastguard Worker 
7775*bbecb9d1SAndroid Build Coastguard Worker    switch (decl->Semantic.Name) {
7776*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PATCH:
7777*bbecb9d1SAndroid Build Coastguard Worker       if (decl->Declaration.File == TGSI_FILE_INPUT) {
7778*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->max_patch_in_sid < decl->Semantic.Index)
7779*bbecb9d1SAndroid Build Coastguard Worker             ctx->max_patch_in_sid = decl->Semantic.Index;
7780*bbecb9d1SAndroid Build Coastguard Worker       } else {
7781*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->max_patch_out_sid < decl->Semantic.Index)
7782*bbecb9d1SAndroid Build Coastguard Worker             ctx->max_patch_out_sid = decl->Semantic.Index;
7783*bbecb9d1SAndroid Build Coastguard Worker       }
7784*bbecb9d1SAndroid Build Coastguard Worker       break;
7785*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_GENERIC:
7786*bbecb9d1SAndroid Build Coastguard Worker       if (decl->Declaration.File == TGSI_FILE_INPUT) {
7787*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->max_generic_in_sid < decl->Semantic.Index)
7788*bbecb9d1SAndroid Build Coastguard Worker             ctx->max_generic_in_sid = decl->Semantic.Index;
7789*bbecb9d1SAndroid Build Coastguard Worker       } else {
7790*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->max_generic_out_sid < decl->Semantic.Index)
7791*bbecb9d1SAndroid Build Coastguard Worker             ctx->max_generic_out_sid = decl->Semantic.Index;
7792*bbecb9d1SAndroid Build Coastguard Worker       }
7793*bbecb9d1SAndroid Build Coastguard Worker       break;
7794*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_COLOR:
7795*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_CLIPVERTEX:
7796*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_BCOLOR:
7797*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_TEXCOORD:
7798*bbecb9d1SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_FOG:
7799*bbecb9d1SAndroid Build Coastguard Worker       /* These are semantics that need to be matched by name and since we can't
7800*bbecb9d1SAndroid Build Coastguard Worker        * guarantee that they exist in all the stages of separable shaders
7801*bbecb9d1SAndroid Build Coastguard Worker        * we can't emit the shader as SSO */
7802*bbecb9d1SAndroid Build Coastguard Worker       ctx->unsupported_io = true;
7803*bbecb9d1SAndroid Build Coastguard Worker       break;
7804*bbecb9d1SAndroid Build Coastguard Worker    default:
7805*bbecb9d1SAndroid Build Coastguard Worker       ;
7806*bbecb9d1SAndroid Build Coastguard Worker    }
7807*bbecb9d1SAndroid Build Coastguard Worker    return true;
7808*bbecb9d1SAndroid Build Coastguard Worker }
7809*bbecb9d1SAndroid Build Coastguard Worker 
7810*bbecb9d1SAndroid Build Coastguard Worker 
vrend_shader_query_separable_program(const struct tgsi_token * tokens,const struct vrend_shader_cfg * cfg)7811*bbecb9d1SAndroid Build Coastguard Worker bool vrend_shader_query_separable_program(const struct tgsi_token *tokens,
7812*bbecb9d1SAndroid Build Coastguard Worker                                           const struct vrend_shader_cfg *cfg)
7813*bbecb9d1SAndroid Build Coastguard Worker {
7814*bbecb9d1SAndroid Build Coastguard Worker    struct sso_scan_ctx ctx = {0};
7815*bbecb9d1SAndroid Build Coastguard Worker    ctx.cfg = cfg;
7816*bbecb9d1SAndroid Build Coastguard Worker    ctx.iter.iterate_property = iter_prop_for_separable;
7817*bbecb9d1SAndroid Build Coastguard Worker    ctx.iter.iterate_declaration = iter_decl_for_overlap;
7818*bbecb9d1SAndroid Build Coastguard Worker    tgsi_iterate_shader(tokens, &ctx.iter);
7819*bbecb9d1SAndroid Build Coastguard Worker 
7820*bbecb9d1SAndroid Build Coastguard Worker    /* Since we have to match by location, and have to handle generics and patches
7821*bbecb9d1SAndroid Build Coastguard Worker     * at in the limited range of 32 locations, we have to make sure that the
7822*bbecb9d1SAndroid Build Coastguard Worker     * the generics range and the patch range don't overlap. In addition, to
7823*bbecb9d1SAndroid Build Coastguard Worker     * work around that radeonsi doesn't support patch locations above 30 we have
7824*bbecb9d1SAndroid Build Coastguard Worker     * to check that limit too. */
7825*bbecb9d1SAndroid Build Coastguard Worker    bool supports_separable = !ctx.unsupported_io &&
7826*bbecb9d1SAndroid Build Coastguard Worker                              (ctx.max_generic_in_sid + ctx.max_patch_in_sid < MAX_VARYING) &&
7827*bbecb9d1SAndroid Build Coastguard Worker                              (ctx.max_generic_out_sid + ctx.max_patch_out_sid < MAX_VARYING) &&
7828*bbecb9d1SAndroid Build Coastguard Worker                              (ctx.max_patch_in_sid < ctx.cfg->max_shader_patch_varyings) &&
7829*bbecb9d1SAndroid Build Coastguard Worker                              (ctx.max_patch_out_sid < ctx.cfg->max_shader_patch_varyings);
7830*bbecb9d1SAndroid Build Coastguard Worker    return ctx.separable_program && supports_separable;
7831*bbecb9d1SAndroid Build Coastguard Worker }
7832*bbecb9d1SAndroid Build Coastguard Worker 
vrend_convert_shader(const struct vrend_context * rctx,const struct vrend_shader_cfg * cfg,const struct tgsi_token * tokens,uint32_t req_local_mem,const struct vrend_shader_key * key,struct vrend_shader_info * sinfo,struct vrend_variable_shader_info * var_sinfo,struct vrend_strarray * shader)7833*bbecb9d1SAndroid Build Coastguard Worker bool vrend_convert_shader(const struct vrend_context *rctx,
7834*bbecb9d1SAndroid Build Coastguard Worker                           const struct vrend_shader_cfg *cfg,
7835*bbecb9d1SAndroid Build Coastguard Worker                           const struct tgsi_token *tokens,
7836*bbecb9d1SAndroid Build Coastguard Worker                           uint32_t req_local_mem,
7837*bbecb9d1SAndroid Build Coastguard Worker                           const struct vrend_shader_key *key,
7838*bbecb9d1SAndroid Build Coastguard Worker                           struct vrend_shader_info *sinfo,
7839*bbecb9d1SAndroid Build Coastguard Worker                           struct vrend_variable_shader_info *var_sinfo,
7840*bbecb9d1SAndroid Build Coastguard Worker                           struct vrend_strarray *shader)
7841*bbecb9d1SAndroid Build Coastguard Worker {
7842*bbecb9d1SAndroid Build Coastguard Worker    struct dump_ctx ctx;
7843*bbecb9d1SAndroid Build Coastguard Worker    boolean bret;
7844*bbecb9d1SAndroid Build Coastguard Worker 
7845*bbecb9d1SAndroid Build Coastguard Worker    memset(&ctx, 0, sizeof(struct dump_ctx));
7846*bbecb9d1SAndroid Build Coastguard Worker    ctx.cfg = cfg;
7847*bbecb9d1SAndroid Build Coastguard Worker 
7848*bbecb9d1SAndroid Build Coastguard Worker    /* First pass to deal with edge cases. */
7849*bbecb9d1SAndroid Build Coastguard Worker    ctx.iter.iterate_declaration = iter_decls;
7850*bbecb9d1SAndroid Build Coastguard Worker    ctx.iter.iterate_instruction = analyze_instruction;
7851*bbecb9d1SAndroid Build Coastguard Worker    bret = tgsi_iterate_shader(tokens, &ctx.iter);
7852*bbecb9d1SAndroid Build Coastguard Worker    if (bret == false)
7853*bbecb9d1SAndroid Build Coastguard Worker       return false;
7854*bbecb9d1SAndroid Build Coastguard Worker 
7855*bbecb9d1SAndroid Build Coastguard Worker    ctx.is_last_vertex_stage =
7856*bbecb9d1SAndroid Build Coastguard Worker          (ctx.iter.processor.Processor == TGSI_PROCESSOR_GEOMETRY) ||
7857*bbecb9d1SAndroid Build Coastguard Worker          (ctx.iter.processor.Processor == TGSI_PROCESSOR_TESS_EVAL && !key->gs_present) ||
7858*bbecb9d1SAndroid Build Coastguard Worker          (ctx.iter.processor.Processor == TGSI_PROCESSOR_VERTEX &&  !key->gs_present && !key->tes_present);
7859*bbecb9d1SAndroid Build Coastguard Worker 
7860*bbecb9d1SAndroid Build Coastguard Worker    ctx.num_inputs = 0;
7861*bbecb9d1SAndroid Build Coastguard Worker    ctx.iter.prolog = prolog;
7862*bbecb9d1SAndroid Build Coastguard Worker    ctx.iter.iterate_instruction = iter_instruction;
7863*bbecb9d1SAndroid Build Coastguard Worker    ctx.iter.iterate_declaration = iter_declaration;
7864*bbecb9d1SAndroid Build Coastguard Worker    ctx.iter.iterate_immediate = iter_immediate;
7865*bbecb9d1SAndroid Build Coastguard Worker    ctx.iter.iterate_property = iter_property;
7866*bbecb9d1SAndroid Build Coastguard Worker    ctx.iter.epilog = NULL;
7867*bbecb9d1SAndroid Build Coastguard Worker    ctx.key = key;
7868*bbecb9d1SAndroid Build Coastguard Worker    ctx.cfg = cfg;
7869*bbecb9d1SAndroid Build Coastguard Worker    ctx.prog_type = -1;
7870*bbecb9d1SAndroid Build Coastguard Worker    ctx.num_image_arrays = 0;
7871*bbecb9d1SAndroid Build Coastguard Worker    ctx.image_arrays = NULL;
7872*bbecb9d1SAndroid Build Coastguard Worker    ctx.num_sampler_arrays = 0;
7873*bbecb9d1SAndroid Build Coastguard Worker    ctx.sampler_arrays = NULL;
7874*bbecb9d1SAndroid Build Coastguard Worker    ctx.ssbo_array_base = 0xffffffff;
7875*bbecb9d1SAndroid Build Coastguard Worker    ctx.ssbo_atomic_array_base = 0xffffffff;
7876*bbecb9d1SAndroid Build Coastguard Worker    ctx.has_sample_input = false;
7877*bbecb9d1SAndroid Build Coastguard Worker    ctx.req_local_mem = req_local_mem;
7878*bbecb9d1SAndroid Build Coastguard Worker    ctx.guest_sent_io_arrays = false;
7879*bbecb9d1SAndroid Build Coastguard Worker    ctx.generic_ios.match.outputs_expected_mask = key->out_generic_expected_mask;
7880*bbecb9d1SAndroid Build Coastguard Worker    ctx.texcoord_ios.match.outputs_expected_mask = key->out_texcoord_expected_mask;
7881*bbecb9d1SAndroid Build Coastguard Worker 
7882*bbecb9d1SAndroid Build Coastguard Worker    tgsi_scan_shader(tokens, &ctx.info);
7883*bbecb9d1SAndroid Build Coastguard Worker    /* if we are in core profile mode we should use GLSL 1.40 */
7884*bbecb9d1SAndroid Build Coastguard Worker    if (cfg->use_core_profile && cfg->glsl_version >= 140)
7885*bbecb9d1SAndroid Build Coastguard Worker       ctx.glsl_ver_required = require_glsl_ver(&ctx, 140);
7886*bbecb9d1SAndroid Build Coastguard Worker 
7887*bbecb9d1SAndroid Build Coastguard Worker    if (sinfo->so_info.num_outputs) {
7888*bbecb9d1SAndroid Build Coastguard Worker       ctx.so = &sinfo->so_info;
7889*bbecb9d1SAndroid Build Coastguard Worker       ctx.so_names = calloc(sinfo->so_info.num_outputs, sizeof(char *));
7890*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx.so_names)
7891*bbecb9d1SAndroid Build Coastguard Worker          goto fail;
7892*bbecb9d1SAndroid Build Coastguard Worker    } else
7893*bbecb9d1SAndroid Build Coastguard Worker       ctx.so_names = NULL;
7894*bbecb9d1SAndroid Build Coastguard Worker 
7895*bbecb9d1SAndroid Build Coastguard Worker    if (ctx.info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT))
7896*bbecb9d1SAndroid Build Coastguard Worker       ctx.glsl_ver_required = require_glsl_ver(&ctx, 150);
7897*bbecb9d1SAndroid Build Coastguard Worker 
7898*bbecb9d1SAndroid Build Coastguard Worker    if (ctx.info.indirect_files & (1 << TGSI_FILE_BUFFER) ||
7899*bbecb9d1SAndroid Build Coastguard Worker        ctx.info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
7900*bbecb9d1SAndroid Build Coastguard Worker       ctx.glsl_ver_required = require_glsl_ver(&ctx, 150);
7901*bbecb9d1SAndroid Build Coastguard Worker       ctx.shader_req_bits |= SHADER_REQ_GPU_SHADER5;
7902*bbecb9d1SAndroid Build Coastguard Worker    }
7903*bbecb9d1SAndroid Build Coastguard Worker    if (ctx.info.indirect_files & (1 << TGSI_FILE_SAMPLER))
7904*bbecb9d1SAndroid Build Coastguard Worker       ctx.shader_req_bits |= SHADER_REQ_GPU_SHADER5;
7905*bbecb9d1SAndroid Build Coastguard Worker 
7906*bbecb9d1SAndroid Build Coastguard Worker    if (!allocate_strbuffers(&ctx.glsl_strbufs))
7907*bbecb9d1SAndroid Build Coastguard Worker       goto fail;
7908*bbecb9d1SAndroid Build Coastguard Worker 
7909*bbecb9d1SAndroid Build Coastguard Worker    bret = tgsi_iterate_shader(tokens, &ctx.iter);
7910*bbecb9d1SAndroid Build Coastguard Worker    if (bret == false)
7911*bbecb9d1SAndroid Build Coastguard Worker       goto fail;
7912*bbecb9d1SAndroid Build Coastguard Worker 
7913*bbecb9d1SAndroid Build Coastguard Worker    /* If we need a sysvalue UBO then we require GLSL 1.40 */
7914*bbecb9d1SAndroid Build Coastguard Worker    if (ctx.glsl_strbufs.required_sysval_uniform_decls)
7915*bbecb9d1SAndroid Build Coastguard Worker       ctx.glsl_ver_required = require_glsl_ver(&ctx, 140);
7916*bbecb9d1SAndroid Build Coastguard Worker 
7917*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx.cfg->use_gles &&
7918*bbecb9d1SAndroid Build Coastguard Worker       ( key->in_arrays.num_arrays > 0 ) &&
7919*bbecb9d1SAndroid Build Coastguard Worker        (ctx.prog_type == TGSI_PROCESSOR_GEOMETRY ||
7920*bbecb9d1SAndroid Build Coastguard Worker         ctx.prog_type == TGSI_PROCESSOR_TESS_CTRL ||
7921*bbecb9d1SAndroid Build Coastguard Worker         ctx.prog_type == TGSI_PROCESSOR_TESS_EVAL)) {
7922*bbecb9d1SAndroid Build Coastguard Worker       ctx.shader_req_bits |= SHADER_REQ_ARRAYS_OF_ARRAYS;
7923*bbecb9d1SAndroid Build Coastguard Worker    }
7924*bbecb9d1SAndroid Build Coastguard Worker 
7925*bbecb9d1SAndroid Build Coastguard Worker    for (size_t i = 0; i < ARRAY_SIZE(ctx.src_bufs); ++i)
7926*bbecb9d1SAndroid Build Coastguard Worker       strbuf_free(ctx.src_bufs + i);
7927*bbecb9d1SAndroid Build Coastguard Worker 
7928*bbecb9d1SAndroid Build Coastguard Worker    for (size_t i = 0; i < ARRAY_SIZE(ctx.dst_bufs); ++i)
7929*bbecb9d1SAndroid Build Coastguard Worker       strbuf_free(ctx.dst_bufs + i);
7930*bbecb9d1SAndroid Build Coastguard Worker 
7931*bbecb9d1SAndroid Build Coastguard Worker    if (ctx.prog_type == TGSI_PROCESSOR_FRAGMENT)
7932*bbecb9d1SAndroid Build Coastguard Worker       qsort(ctx.outputs, ctx.num_outputs, sizeof(struct vrend_shader_io), compare_sid);
7933*bbecb9d1SAndroid Build Coastguard Worker 
7934*bbecb9d1SAndroid Build Coastguard Worker    const struct vrend_fs_shader_info *fs_info = &key->fs_info;
7935*bbecb9d1SAndroid Build Coastguard Worker 
7936*bbecb9d1SAndroid Build Coastguard Worker    if (fs_info->num_interps && fs_info->has_sample_input &&
7937*bbecb9d1SAndroid Build Coastguard Worker        ((cfg->use_gles && cfg->glsl_version < 320) ||
7938*bbecb9d1SAndroid Build Coastguard Worker         cfg->glsl_version >= 320)) {
7939*bbecb9d1SAndroid Build Coastguard Worker       ctx.shader_req_bits |= SHADER_REQ_GPU_SHADER5;
7940*bbecb9d1SAndroid Build Coastguard Worker    }
7941*bbecb9d1SAndroid Build Coastguard Worker 
7942*bbecb9d1SAndroid Build Coastguard Worker    if (fs_info->num_interps && fs_info->has_noperspective &&
7943*bbecb9d1SAndroid Build Coastguard Worker        cfg->use_gles) {
7944*bbecb9d1SAndroid Build Coastguard Worker       ctx.shader_req_bits |= SHADER_REQ_SHADER_NOPERSPECTIVE_INTERPOLATION;
7945*bbecb9d1SAndroid Build Coastguard Worker    }
7946*bbecb9d1SAndroid Build Coastguard Worker 
7947*bbecb9d1SAndroid Build Coastguard Worker    emit_header(&ctx, &ctx.glsl_strbufs);
7948*bbecb9d1SAndroid Build Coastguard Worker    ctx.glsl_ver_required = emit_ios(&ctx, &ctx.glsl_strbufs, &ctx.generic_ios,
7949*bbecb9d1SAndroid Build Coastguard Worker                                     &ctx.texcoord_ios, &ctx.patches_emitted_mask,
7950*bbecb9d1SAndroid Build Coastguard Worker                                     ctx.front_back_color_emitted_flags,
7951*bbecb9d1SAndroid Build Coastguard Worker                                     &ctx.num_interps, &ctx.has_pervertex,
7952*bbecb9d1SAndroid Build Coastguard Worker                                     &ctx.force_color_two_side,
7953*bbecb9d1SAndroid Build Coastguard Worker                                     &ctx.shadow_samp_mask);
7954*bbecb9d1SAndroid Build Coastguard Worker 
7955*bbecb9d1SAndroid Build Coastguard Worker    if (strbuf_get_error(&ctx.glsl_strbufs.glsl_hdr))
7956*bbecb9d1SAndroid Build Coastguard Worker       goto fail;
7957*bbecb9d1SAndroid Build Coastguard Worker 
7958*bbecb9d1SAndroid Build Coastguard Worker    bret = fill_interpolants(&ctx, var_sinfo);
7959*bbecb9d1SAndroid Build Coastguard Worker    if (bret == false)
7960*bbecb9d1SAndroid Build Coastguard Worker       goto fail;
7961*bbecb9d1SAndroid Build Coastguard Worker 
7962*bbecb9d1SAndroid Build Coastguard Worker    free(ctx.temp_ranges);
7963*bbecb9d1SAndroid Build Coastguard Worker 
7964*bbecb9d1SAndroid Build Coastguard Worker    fill_sinfo(&ctx, sinfo);
7965*bbecb9d1SAndroid Build Coastguard Worker    fill_var_sinfo(&ctx, var_sinfo);
7966*bbecb9d1SAndroid Build Coastguard Worker 
7967*bbecb9d1SAndroid Build Coastguard Worker    emit_required_sysval_uniforms (&ctx.glsl_strbufs.glsl_hdr,
7968*bbecb9d1SAndroid Build Coastguard Worker                                   ctx.glsl_strbufs.required_sysval_uniform_decls);
7969*bbecb9d1SAndroid Build Coastguard Worker    set_strbuffers(&ctx.glsl_strbufs, shader);
7970*bbecb9d1SAndroid Build Coastguard Worker 
7971*bbecb9d1SAndroid Build Coastguard Worker    VREND_DEBUG(dbg_shader_glsl, rctx, "GLSL:");
7972*bbecb9d1SAndroid Build Coastguard Worker    VREND_DEBUG_EXT(dbg_shader_glsl, rctx, strarray_dump(shader));
7973*bbecb9d1SAndroid Build Coastguard Worker    VREND_DEBUG(dbg_shader_glsl, rctx, "\n");
7974*bbecb9d1SAndroid Build Coastguard Worker 
7975*bbecb9d1SAndroid Build Coastguard Worker    return true;
7976*bbecb9d1SAndroid Build Coastguard Worker  fail:
7977*bbecb9d1SAndroid Build Coastguard Worker    strbuf_free(&ctx.glsl_strbufs.glsl_main);
7978*bbecb9d1SAndroid Build Coastguard Worker    strbuf_free(&ctx.glsl_strbufs.glsl_hdr);
7979*bbecb9d1SAndroid Build Coastguard Worker    strbuf_free(&ctx.glsl_strbufs.glsl_ver_ext);
7980*bbecb9d1SAndroid Build Coastguard Worker    free(ctx.so_names);
7981*bbecb9d1SAndroid Build Coastguard Worker    free(ctx.temp_ranges);
7982*bbecb9d1SAndroid Build Coastguard Worker    return false;
7983*bbecb9d1SAndroid Build Coastguard Worker }
7984*bbecb9d1SAndroid Build Coastguard Worker 
7985*bbecb9d1SAndroid Build Coastguard Worker static boolean
iter_vs_declaration(struct tgsi_iterate_context * iter,struct tgsi_full_declaration * decl)7986*bbecb9d1SAndroid Build Coastguard Worker iter_vs_declaration(struct tgsi_iterate_context *iter,
7987*bbecb9d1SAndroid Build Coastguard Worker                     struct tgsi_full_declaration *decl)
7988*bbecb9d1SAndroid Build Coastguard Worker {
7989*bbecb9d1SAndroid Build Coastguard Worker    struct dump_ctx *ctx = (struct dump_ctx *)iter;
7990*bbecb9d1SAndroid Build Coastguard Worker 
7991*bbecb9d1SAndroid Build Coastguard Worker    const char *shader_in_prefix = "vso";
7992*bbecb9d1SAndroid Build Coastguard Worker    const char *shader_out_prefix = "tco";
7993*bbecb9d1SAndroid Build Coastguard Worker    const char *name_prefix = "";
7994*bbecb9d1SAndroid Build Coastguard Worker    unsigned i;
7995*bbecb9d1SAndroid Build Coastguard Worker 
7996*bbecb9d1SAndroid Build Coastguard Worker    // Generate a shader that passes through all VS outputs
7997*bbecb9d1SAndroid Build Coastguard Worker    if (decl->Declaration.File == TGSI_FILE_OUTPUT) {
7998*bbecb9d1SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < ctx->num_inputs; j++) {
7999*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[j].name == decl->Semantic.Name &&
8000*bbecb9d1SAndroid Build Coastguard Worker              ctx->inputs[j].sid == decl->Semantic.Index &&
8001*bbecb9d1SAndroid Build Coastguard Worker              ctx->inputs[j].first == decl->Range.First &&
8002*bbecb9d1SAndroid Build Coastguard Worker              ctx->inputs[j].usage_mask  == decl->Declaration.UsageMask &&
8003*bbecb9d1SAndroid Build Coastguard Worker              ((!decl->Declaration.Array && ctx->inputs[j].array_id == 0) ||
8004*bbecb9d1SAndroid Build Coastguard Worker               (ctx->inputs[j].array_id  == decl->Array.ArrayID)))
8005*bbecb9d1SAndroid Build Coastguard Worker             return true;
8006*bbecb9d1SAndroid Build Coastguard Worker       }
8007*bbecb9d1SAndroid Build Coastguard Worker       i = ctx->num_inputs++;
8008*bbecb9d1SAndroid Build Coastguard Worker 
8009*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].name = decl->Semantic.Name;
8010*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].sid = decl->Semantic.Index;
8011*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].interpolate = decl->Interp.Interpolate;
8012*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].location = decl->Interp.Location;
8013*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].first = decl->Range.First;
8014*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].last = decl->Range.Last;
8015*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].array_id = decl->Declaration.Array ? decl->Array.ArrayID : 0;
8016*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].usage_mask = decl->Declaration.UsageMask;
8017*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].num_components = 4;
8018*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].glsl_predefined_no_emit = false;
8019*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].glsl_no_index = false;
8020*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].override_no_wm = ctx->inputs[i].num_components == 1;
8021*bbecb9d1SAndroid Build Coastguard Worker       ctx->inputs[i].glsl_gl_block = false;
8022*bbecb9d1SAndroid Build Coastguard Worker 
8023*bbecb9d1SAndroid Build Coastguard Worker       switch (ctx->inputs[i].name) {
8024*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_PSIZE:
8025*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_PointSize";
8026*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].glsl_predefined_no_emit = true;
8027*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].glsl_no_index = true;
8028*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].override_no_wm = true;
8029*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].glsl_gl_block = true;
8030*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_PSIZE;
8031*bbecb9d1SAndroid Build Coastguard Worker          break;
8032*bbecb9d1SAndroid Build Coastguard Worker 
8033*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_CLIPDIST:
8034*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_ClipDistance";
8035*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].glsl_predefined_no_emit = true;
8036*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].glsl_no_index = true;
8037*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].glsl_gl_block = true;
8038*bbecb9d1SAndroid Build Coastguard Worker          ctx->num_in_clip_dist += 4 * (ctx->inputs[i].last - ctx->inputs[i].first + 1);
8039*bbecb9d1SAndroid Build Coastguard Worker          ctx->shader_req_bits |= SHADER_REQ_CLIP_DISTANCE;
8040*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[i].last != ctx->inputs[i].first)
8041*bbecb9d1SAndroid Build Coastguard Worker             ctx->guest_sent_io_arrays = true;
8042*bbecb9d1SAndroid Build Coastguard Worker          break;
8043*bbecb9d1SAndroid Build Coastguard Worker 
8044*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_POSITION:
8045*bbecb9d1SAndroid Build Coastguard Worker          name_prefix = "gl_Position";
8046*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].glsl_predefined_no_emit = true;
8047*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].glsl_no_index = true;
8048*bbecb9d1SAndroid Build Coastguard Worker          ctx->inputs[i].glsl_gl_block = true;
8049*bbecb9d1SAndroid Build Coastguard Worker          break;
8050*bbecb9d1SAndroid Build Coastguard Worker 
8051*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_PATCH:
8052*bbecb9d1SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_GENERIC:
8053*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[i].first != ctx->inputs[i].last ||
8054*bbecb9d1SAndroid Build Coastguard Worker              ctx->inputs[i].array_id > 0) {
8055*bbecb9d1SAndroid Build Coastguard Worker             ctx->guest_sent_io_arrays = true;
8056*bbecb9d1SAndroid Build Coastguard Worker             if (!ctx->cfg->use_gles)
8057*bbecb9d1SAndroid Build Coastguard Worker                ctx->shader_req_bits |= SHADER_REQ_ARRAYS_OF_ARRAYS;
8058*bbecb9d1SAndroid Build Coastguard Worker          }
8059*bbecb9d1SAndroid Build Coastguard Worker          break;
8060*bbecb9d1SAndroid Build Coastguard Worker       default:
8061*bbecb9d1SAndroid Build Coastguard Worker          break;
8062*bbecb9d1SAndroid Build Coastguard Worker       }
8063*bbecb9d1SAndroid Build Coastguard Worker 
8064*bbecb9d1SAndroid Build Coastguard Worker       memcpy(&ctx->outputs[i], &ctx->inputs[i], sizeof(struct vrend_shader_io));
8065*bbecb9d1SAndroid Build Coastguard Worker 
8066*bbecb9d1SAndroid Build Coastguard Worker       if (ctx->inputs[i].glsl_no_index) {
8067*bbecb9d1SAndroid Build Coastguard Worker          snprintf(ctx->inputs[i].glsl_name, 128, "%s", name_prefix);
8068*bbecb9d1SAndroid Build Coastguard Worker          snprintf(ctx->outputs[i].glsl_name, 128, "%s", name_prefix);
8069*bbecb9d1SAndroid Build Coastguard Worker       } else {
8070*bbecb9d1SAndroid Build Coastguard Worker          if (ctx->inputs[i].name == TGSI_SEMANTIC_FOG){
8071*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].usage_mask = 0xf;
8072*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].num_components = 4;
8073*bbecb9d1SAndroid Build Coastguard Worker             ctx->inputs[i].override_no_wm = false;
8074*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i].glsl_name, 64, "%s_f%d", shader_in_prefix, ctx->inputs[i].sid);
8075*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->outputs[i].glsl_name, 64, "%s_f%d", shader_out_prefix, ctx->inputs[i].sid);
8076*bbecb9d1SAndroid Build Coastguard Worker          } else if (ctx->inputs[i].name == TGSI_SEMANTIC_COLOR) {
8077*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i].glsl_name, 64, "%s_c%d", shader_in_prefix, ctx->inputs[i].sid);
8078*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->outputs[i].glsl_name, 64, "%s_c%d", shader_out_prefix, ctx->inputs[i].sid);
8079*bbecb9d1SAndroid Build Coastguard Worker          } else if (ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC) {
8080*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i].glsl_name, 64, "%s_g%d", shader_in_prefix, ctx->inputs[i].sid);
8081*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->outputs[i].glsl_name, 64, "%s_g%d", shader_out_prefix, ctx->inputs[i].sid);
8082*bbecb9d1SAndroid Build Coastguard Worker          } else {
8083*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->outputs[i].glsl_name, 64, "%s_%d", shader_in_prefix, ctx->inputs[i].first);
8084*bbecb9d1SAndroid Build Coastguard Worker             snprintf(ctx->inputs[i].glsl_name, 64, "%s_%d", shader_out_prefix, ctx->inputs[i].first);
8085*bbecb9d1SAndroid Build Coastguard Worker          }
8086*bbecb9d1SAndroid Build Coastguard Worker       }
8087*bbecb9d1SAndroid Build Coastguard Worker    }
8088*bbecb9d1SAndroid Build Coastguard Worker    return true;
8089*bbecb9d1SAndroid Build Coastguard Worker }
8090*bbecb9d1SAndroid Build Coastguard Worker 
vrend_shader_create_passthrough_tcs(const struct vrend_context * rctx,const struct vrend_shader_cfg * cfg,const struct tgsi_token * vs_tokens,const struct vrend_shader_key * key,const float tess_factors[6],struct vrend_shader_info * sinfo,struct vrend_strarray * shader,int vertices_per_patch)8091*bbecb9d1SAndroid Build Coastguard Worker bool vrend_shader_create_passthrough_tcs(const struct vrend_context *rctx,
8092*bbecb9d1SAndroid Build Coastguard Worker                                          const struct vrend_shader_cfg *cfg,
8093*bbecb9d1SAndroid Build Coastguard Worker                                          const struct tgsi_token *vs_tokens,
8094*bbecb9d1SAndroid Build Coastguard Worker                                          const struct vrend_shader_key *key,
8095*bbecb9d1SAndroid Build Coastguard Worker                                          const float tess_factors[6],
8096*bbecb9d1SAndroid Build Coastguard Worker                                          struct vrend_shader_info *sinfo,
8097*bbecb9d1SAndroid Build Coastguard Worker                                          struct vrend_strarray *shader,
8098*bbecb9d1SAndroid Build Coastguard Worker                                          int vertices_per_patch)
8099*bbecb9d1SAndroid Build Coastguard Worker {
8100*bbecb9d1SAndroid Build Coastguard Worker    struct dump_ctx ctx;
8101*bbecb9d1SAndroid Build Coastguard Worker 
8102*bbecb9d1SAndroid Build Coastguard Worker    memset(&ctx, 0, sizeof(struct dump_ctx));
8103*bbecb9d1SAndroid Build Coastguard Worker 
8104*bbecb9d1SAndroid Build Coastguard Worker    ctx.prog_type = TGSI_PROCESSOR_TESS_CTRL;
8105*bbecb9d1SAndroid Build Coastguard Worker    ctx.cfg = cfg;
8106*bbecb9d1SAndroid Build Coastguard Worker    ctx.key = key;
8107*bbecb9d1SAndroid Build Coastguard Worker    ctx.iter.iterate_declaration = iter_vs_declaration;
8108*bbecb9d1SAndroid Build Coastguard Worker    ctx.ssbo_array_base = 0xffffffff;
8109*bbecb9d1SAndroid Build Coastguard Worker    ctx.ssbo_atomic_array_base = 0xffffffff;
8110*bbecb9d1SAndroid Build Coastguard Worker    ctx.has_sample_input = false;
8111*bbecb9d1SAndroid Build Coastguard Worker 
8112*bbecb9d1SAndroid Build Coastguard Worker    if (!allocate_strbuffers(&ctx.glsl_strbufs))
8113*bbecb9d1SAndroid Build Coastguard Worker       goto fail;
8114*bbecb9d1SAndroid Build Coastguard Worker 
8115*bbecb9d1SAndroid Build Coastguard Worker    tgsi_iterate_shader(vs_tokens, &ctx.iter);
8116*bbecb9d1SAndroid Build Coastguard Worker 
8117*bbecb9d1SAndroid Build Coastguard Worker    /*  What is the default on GL? */
8118*bbecb9d1SAndroid Build Coastguard Worker    ctx.tcs_vertices_out = vertices_per_patch;
8119*bbecb9d1SAndroid Build Coastguard Worker 
8120*bbecb9d1SAndroid Build Coastguard Worker    ctx.num_outputs = ctx.num_inputs;
8121*bbecb9d1SAndroid Build Coastguard Worker 
8122*bbecb9d1SAndroid Build Coastguard Worker    handle_io_arrays(&ctx);
8123*bbecb9d1SAndroid Build Coastguard Worker 
8124*bbecb9d1SAndroid Build Coastguard Worker    emit_header(&ctx, &ctx.glsl_strbufs);
8125*bbecb9d1SAndroid Build Coastguard Worker    ctx.glsl_ver_required = emit_ios(&ctx, &ctx.glsl_strbufs, &ctx.generic_ios,
8126*bbecb9d1SAndroid Build Coastguard Worker                                     &ctx.texcoord_ios, &ctx.patches_emitted_mask,
8127*bbecb9d1SAndroid Build Coastguard Worker                                     ctx.front_back_color_emitted_flags,
8128*bbecb9d1SAndroid Build Coastguard Worker                                     &ctx.num_interps, &ctx.has_pervertex,
8129*bbecb9d1SAndroid Build Coastguard Worker                                     &ctx.force_color_two_side,
8130*bbecb9d1SAndroid Build Coastguard Worker                                     &ctx.shadow_samp_mask);
8131*bbecb9d1SAndroid Build Coastguard Worker 
8132*bbecb9d1SAndroid Build Coastguard Worker    emit_buf(&ctx.glsl_strbufs, "void main() {\n");
8133*bbecb9d1SAndroid Build Coastguard Worker 
8134*bbecb9d1SAndroid Build Coastguard Worker    for (unsigned int i = 0; i < ctx.num_inputs; ++i) {
8135*bbecb9d1SAndroid Build Coastguard Worker       const char *out_prefix = "";
8136*bbecb9d1SAndroid Build Coastguard Worker       const char *in_prefix = "";
8137*bbecb9d1SAndroid Build Coastguard Worker 
8138*bbecb9d1SAndroid Build Coastguard Worker       const char *postfix = "";
8139*bbecb9d1SAndroid Build Coastguard Worker 
8140*bbecb9d1SAndroid Build Coastguard Worker       if (ctx.inputs[i].glsl_gl_block) {
8141*bbecb9d1SAndroid Build Coastguard Worker          out_prefix = "gl_out[gl_InvocationID].";
8142*bbecb9d1SAndroid Build Coastguard Worker          in_prefix = "gl_in[gl_InvocationID].";
8143*bbecb9d1SAndroid Build Coastguard Worker       } else {
8144*bbecb9d1SAndroid Build Coastguard Worker          postfix = "[gl_InvocationID]";
8145*bbecb9d1SAndroid Build Coastguard Worker       }
8146*bbecb9d1SAndroid Build Coastguard Worker 
8147*bbecb9d1SAndroid Build Coastguard Worker       if (ctx.inputs[i].first == ctx.inputs[i].last) {
8148*bbecb9d1SAndroid Build Coastguard Worker          emit_buff(&ctx.glsl_strbufs, "%s%s%s = %s%s%s;\n",
8149*bbecb9d1SAndroid Build Coastguard Worker                    out_prefix, ctx.outputs[i].glsl_name, postfix,
8150*bbecb9d1SAndroid Build Coastguard Worker                    in_prefix, ctx.inputs[i].glsl_name, postfix);
8151*bbecb9d1SAndroid Build Coastguard Worker       } else {
8152*bbecb9d1SAndroid Build Coastguard Worker          unsigned size = ctx.inputs[i].last == ctx.inputs[i].first + 1;
8153*bbecb9d1SAndroid Build Coastguard Worker          for (unsigned int k = 0; k < size; ++k) {
8154*bbecb9d1SAndroid Build Coastguard Worker             emit_buff(&ctx.glsl_strbufs, "%s%s%s[%d] = %s%s%s[%d];\n",
8155*bbecb9d1SAndroid Build Coastguard Worker                       out_prefix, ctx.outputs[i].glsl_name, postfix, k,
8156*bbecb9d1SAndroid Build Coastguard Worker                       in_prefix, ctx.inputs[i].glsl_name, postfix, k);
8157*bbecb9d1SAndroid Build Coastguard Worker          }
8158*bbecb9d1SAndroid Build Coastguard Worker       }
8159*bbecb9d1SAndroid Build Coastguard Worker    }
8160*bbecb9d1SAndroid Build Coastguard Worker 
8161*bbecb9d1SAndroid Build Coastguard Worker    for (int i = 0; i < 4; ++i)
8162*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx.glsl_strbufs, "gl_TessLevelOuter[%d] = %f;\n", i, tess_factors[i]);
8163*bbecb9d1SAndroid Build Coastguard Worker 
8164*bbecb9d1SAndroid Build Coastguard Worker    for (int i = 0; i < 2; ++i)
8165*bbecb9d1SAndroid Build Coastguard Worker       emit_buff(&ctx.glsl_strbufs, "gl_TessLevelInner[%d] = %f;\n", i, tess_factors[i + 4]);
8166*bbecb9d1SAndroid Build Coastguard Worker 
8167*bbecb9d1SAndroid Build Coastguard Worker    emit_buf(&ctx.glsl_strbufs, "}\n");
8168*bbecb9d1SAndroid Build Coastguard Worker 
8169*bbecb9d1SAndroid Build Coastguard Worker    fill_sinfo(&ctx, sinfo);
8170*bbecb9d1SAndroid Build Coastguard Worker    emit_required_sysval_uniforms (&ctx.glsl_strbufs.glsl_hdr,
8171*bbecb9d1SAndroid Build Coastguard Worker                                   ctx.glsl_strbufs.required_sysval_uniform_decls);
8172*bbecb9d1SAndroid Build Coastguard Worker    set_strbuffers(&ctx.glsl_strbufs, shader);
8173*bbecb9d1SAndroid Build Coastguard Worker 
8174*bbecb9d1SAndroid Build Coastguard Worker    VREND_DEBUG(dbg_shader_glsl, rctx, "GLSL:");
8175*bbecb9d1SAndroid Build Coastguard Worker    VREND_DEBUG_EXT(dbg_shader_glsl, rctx, strarray_dump(shader));
8176*bbecb9d1SAndroid Build Coastguard Worker    VREND_DEBUG(dbg_shader_glsl, rctx, "\n");
8177*bbecb9d1SAndroid Build Coastguard Worker 
8178*bbecb9d1SAndroid Build Coastguard Worker    return true;
8179*bbecb9d1SAndroid Build Coastguard Worker fail:
8180*bbecb9d1SAndroid Build Coastguard Worker    strbuf_free(&ctx.glsl_strbufs.glsl_main);
8181*bbecb9d1SAndroid Build Coastguard Worker    strbuf_free(&ctx.glsl_strbufs.glsl_hdr);
8182*bbecb9d1SAndroid Build Coastguard Worker    strbuf_free(&ctx.glsl_strbufs.glsl_ver_ext);
8183*bbecb9d1SAndroid Build Coastguard Worker    free(ctx.so_names);
8184*bbecb9d1SAndroid Build Coastguard Worker    free(ctx.temp_ranges);
8185*bbecb9d1SAndroid Build Coastguard Worker    return false;
8186*bbecb9d1SAndroid Build Coastguard Worker }
8187*bbecb9d1SAndroid Build Coastguard Worker 
8188*bbecb9d1SAndroid Build Coastguard Worker static
vrend_shader_write_io_as_src(struct vrend_strbuf * result,const char * array_or_varname,const struct vrend_shader_io * io,const struct tgsi_full_src_register * src,enum io_decl_type decl_type)8189*bbecb9d1SAndroid Build Coastguard Worker void vrend_shader_write_io_as_src(struct vrend_strbuf *result,
8190*bbecb9d1SAndroid Build Coastguard Worker                                   const  char *array_or_varname,
8191*bbecb9d1SAndroid Build Coastguard Worker                                   const struct vrend_shader_io *io,
8192*bbecb9d1SAndroid Build Coastguard Worker                                   const struct tgsi_full_src_register *src,
8193*bbecb9d1SAndroid Build Coastguard Worker                                   enum io_decl_type decl_type)
8194*bbecb9d1SAndroid Build Coastguard Worker {
8195*bbecb9d1SAndroid Build Coastguard Worker 
8196*bbecb9d1SAndroid Build Coastguard Worker 
8197*bbecb9d1SAndroid Build Coastguard Worker    if (io->first == io->last && !io->overlapping_array) {
8198*bbecb9d1SAndroid Build Coastguard Worker       strbuf_appendf(result, "%s%s", io->glsl_name, array_or_varname);
8199*bbecb9d1SAndroid Build Coastguard Worker    } else {
8200*bbecb9d1SAndroid Build Coastguard Worker       const struct vrend_shader_io *base = io->overlapping_array ? io->overlapping_array : io;
8201*bbecb9d1SAndroid Build Coastguard Worker       const int offset = src->Register.Index - io->first + io->array_offset;
8202*bbecb9d1SAndroid Build Coastguard Worker 
8203*bbecb9d1SAndroid Build Coastguard Worker       if (decl_type == decl_block) {
8204*bbecb9d1SAndroid Build Coastguard Worker          if (src->Register.Indirect)
8205*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(result, "%s.%s[addr%d + %d]", array_or_varname, base->glsl_name,
8206*bbecb9d1SAndroid Build Coastguard Worker                            src->Indirect.Index, offset);
8207*bbecb9d1SAndroid Build Coastguard Worker          else
8208*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(result, "%s.%s[%d]", array_or_varname, base->glsl_name, offset);
8209*bbecb9d1SAndroid Build Coastguard Worker       } else {
8210*bbecb9d1SAndroid Build Coastguard Worker          if (src->Register.Indirect)
8211*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(result, "%s%s[addr%d + %d]", base->glsl_name,
8212*bbecb9d1SAndroid Build Coastguard Worker                            array_or_varname, src->Indirect.Index, offset);
8213*bbecb9d1SAndroid Build Coastguard Worker          else
8214*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(result, "%s%s[%d]", base->glsl_name,
8215*bbecb9d1SAndroid Build Coastguard Worker                            array_or_varname, offset);
8216*bbecb9d1SAndroid Build Coastguard Worker       }
8217*bbecb9d1SAndroid Build Coastguard Worker    }
8218*bbecb9d1SAndroid Build Coastguard Worker }
8219*bbecb9d1SAndroid Build Coastguard Worker 
8220*bbecb9d1SAndroid Build Coastguard Worker static
vrend_shader_write_io_as_dst(struct vrend_strbuf * result,const char * array_or_varname,const struct vrend_shader_io * io,const struct tgsi_full_dst_register * src,enum io_decl_type decl_type)8221*bbecb9d1SAndroid Build Coastguard Worker void vrend_shader_write_io_as_dst(struct vrend_strbuf *result,
8222*bbecb9d1SAndroid Build Coastguard Worker                                   const  char *array_or_varname,
8223*bbecb9d1SAndroid Build Coastguard Worker                                   const struct vrend_shader_io *io,
8224*bbecb9d1SAndroid Build Coastguard Worker                                   const struct tgsi_full_dst_register *src,
8225*bbecb9d1SAndroid Build Coastguard Worker                                   enum io_decl_type decl_type)
8226*bbecb9d1SAndroid Build Coastguard Worker {
8227*bbecb9d1SAndroid Build Coastguard Worker 
8228*bbecb9d1SAndroid Build Coastguard Worker    if (io->first == io->last) {
8229*bbecb9d1SAndroid Build Coastguard Worker       if (io->overlapping_array)
8230*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(result, "%s%s[%d]", io->overlapping_array->glsl_name,
8231*bbecb9d1SAndroid Build Coastguard Worker                         array_or_varname, io->array_offset);
8232*bbecb9d1SAndroid Build Coastguard Worker       else
8233*bbecb9d1SAndroid Build Coastguard Worker          strbuf_appendf(result, "%s%s", io->glsl_name, array_or_varname);
8234*bbecb9d1SAndroid Build Coastguard Worker    } else {
8235*bbecb9d1SAndroid Build Coastguard Worker       const struct vrend_shader_io *base = io->overlapping_array ? io->overlapping_array : io;
8236*bbecb9d1SAndroid Build Coastguard Worker       const int offset = src->Register.Index - io->first + io->array_offset;
8237*bbecb9d1SAndroid Build Coastguard Worker 
8238*bbecb9d1SAndroid Build Coastguard Worker       if (decl_type == decl_block) {
8239*bbecb9d1SAndroid Build Coastguard Worker          if (src->Register.Indirect)
8240*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(result, "%s.%s[addr%d + %d]", array_or_varname, base->glsl_name,
8241*bbecb9d1SAndroid Build Coastguard Worker                            src->Indirect.Index, offset);
8242*bbecb9d1SAndroid Build Coastguard Worker          else
8243*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(result, "%s.%s[%d]", array_or_varname, base->glsl_name, offset);
8244*bbecb9d1SAndroid Build Coastguard Worker       } else {
8245*bbecb9d1SAndroid Build Coastguard Worker          if (src->Register.Indirect)
8246*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(result, "%s%s[addr%d + %d]", base->glsl_name,
8247*bbecb9d1SAndroid Build Coastguard Worker                            array_or_varname, src->Indirect.Index, offset);
8248*bbecb9d1SAndroid Build Coastguard Worker          else
8249*bbecb9d1SAndroid Build Coastguard Worker             strbuf_appendf(result, "%s%s[%d]", base->glsl_name,
8250*bbecb9d1SAndroid Build Coastguard Worker                            array_or_varname, offset);
8251*bbecb9d1SAndroid Build Coastguard Worker       }
8252*bbecb9d1SAndroid Build Coastguard Worker    }
8253*bbecb9d1SAndroid Build Coastguard Worker }
8254*bbecb9d1SAndroid Build Coastguard Worker 
vrend_shader_needs_alpha_func(const struct vrend_shader_key * key)8255*bbecb9d1SAndroid Build Coastguard Worker bool vrend_shader_needs_alpha_func(const struct vrend_shader_key *key) {
8256*bbecb9d1SAndroid Build Coastguard Worker    if (!key->add_alpha_test)
8257*bbecb9d1SAndroid Build Coastguard Worker       return false;
8258*bbecb9d1SAndroid Build Coastguard Worker    switch (key->alpha_test) {
8259*bbecb9d1SAndroid Build Coastguard Worker    default:
8260*bbecb9d1SAndroid Build Coastguard Worker       return false;
8261*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_LESS:
8262*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_EQUAL:
8263*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_LEQUAL:
8264*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_GREATER:
8265*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_NOTEQUAL:
8266*bbecb9d1SAndroid Build Coastguard Worker    case PIPE_FUNC_GEQUAL:
8267*bbecb9d1SAndroid Build Coastguard Worker       return true;
8268*bbecb9d1SAndroid Build Coastguard Worker    }
8269*bbecb9d1SAndroid Build Coastguard Worker }
8270*bbecb9d1SAndroid Build Coastguard Worker 
8271