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