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