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
36 extern int vrend_dump_shaders;
37
38 /* start convert of tgsi to glsl */
39
40 #define INTERP_PREFIX " "
41 #define INVARI_PREFIX "invariant"
42
43 #define SHADER_REQ_NONE 0
44 #define SHADER_REQ_SAMPLER_RECT (1 << 0)
45 #define SHADER_REQ_CUBE_ARRAY (1 << 1)
46 #define SHADER_REQ_INTS (1 << 2)
47 #define SHADER_REQ_SAMPLER_MS (1 << 3)
48 #define SHADER_REQ_INSTANCE_ID (1 << 4)
49 #define SHADER_REQ_LODQ (1 << 5)
50 #define SHADER_REQ_TXQ_LEVELS (1 << 6)
51 #define SHADER_REQ_TG4 (1 << 7)
52 #define SHADER_REQ_VIEWPORT_IDX (1 << 8)
53 #define SHADER_REQ_STENCIL_EXPORT (1 << 9)
54 #define SHADER_REQ_LAYER (1 << 10)
55 #define SHADER_REQ_SAMPLE_SHADING (1 << 11)
56 #define SHADER_REQ_GPU_SHADER5 (1 << 12)
57 #define SHADER_REQ_DERIVATIVE_CONTROL (1 << 13)
58 #define SHADER_REQ_FP64 (1 << 14)
59 #define SHADER_REQ_IMAGE_LOAD_STORE (1 << 15)
60 #define SHADER_REQ_ES31_COMPAT (1 << 16)
61 #define SHADER_REQ_IMAGE_SIZE (1 << 17)
62 #define SHADER_REQ_TXQS (1 << 18)
63 #define SHADER_REQ_FBFETCH (1 << 19)
64 #define SHADER_REQ_SHADER_CLOCK (1 << 20)
65 #define SHADER_REQ_PSIZE (1 << 21)
66
67 struct vrend_shader_io {
68 unsigned name;
69 unsigned gpr;
70 unsigned done;
71 int sid;
72 unsigned interpolate;
73 int first;
74 unsigned location;
75 bool invariant;
76 bool precise;
77 bool glsl_predefined_no_emit;
78 bool glsl_no_index;
79 bool glsl_gl_block;
80 bool override_no_wm;
81 bool is_int;
82 bool fbfetch_used;
83 char glsl_name[128];
84 unsigned stream;
85 };
86
87 struct vrend_shader_sampler {
88 int tgsi_sampler_type;
89 enum tgsi_return_type tgsi_sampler_return;
90 };
91
92 struct vrend_shader_table {
93 uint32_t key;
94 const char *string;
95 };
96
97 struct vrend_shader_image {
98 struct tgsi_declaration_image decl;
99 enum tgsi_return_type image_return;
100 bool vflag;
101 };
102
103 #define MAX_IMMEDIATE 1024
104 struct immed {
105 int type;
106 union imm {
107 uint32_t ui;
108 int32_t i;
109 float f;
110 } val[4];
111 };
112
113 struct vrend_temp_range {
114 int first;
115 int last;
116 int array_id;
117 };
118
119 struct vrend_io_range {
120 int first;
121 int last;
122 int array_id;
123 bool used;
124 };
125
126 struct dump_ctx {
127 struct tgsi_iterate_context iter;
128 struct vrend_shader_cfg *cfg;
129 struct tgsi_shader_info info;
130 int prog_type;
131 int size;
132 char *glsl_main;
133 uint instno;
134
135 uint32_t num_interps;
136 uint32_t num_inputs;
137 uint32_t attrib_input_mask;
138 struct vrend_shader_io inputs[64];
139 uint32_t num_outputs;
140 struct vrend_shader_io outputs[64];
141 uint32_t num_system_values;
142 struct vrend_shader_io system_values[32];
143
144 struct vrend_io_range generic_input_range;
145 struct vrend_io_range patch_input_range;
146 struct vrend_io_range generic_output_range;
147 struct vrend_io_range patch_output_range;
148
149 uint32_t num_temp_ranges;
150 struct vrend_temp_range *temp_ranges;
151
152 struct vrend_shader_sampler samplers[32];
153 uint32_t samplers_used;
154
155 uint32_t ssbo_used_mask;
156 uint32_t ssbo_atomic_mask;
157 uint32_t ssbo_array_base;
158 uint32_t ssbo_atomic_array_base;
159 uint32_t ssbo_integer_mask;
160
161 struct vrend_shader_image images[32];
162 uint32_t images_used_mask;
163
164 struct vrend_array *image_arrays;
165 uint32_t num_image_arrays;
166
167 struct vrend_array *sampler_arrays;
168 uint32_t num_sampler_arrays;
169
170 int num_consts;
171 int num_imm;
172 struct immed imm[MAX_IMMEDIATE];
173 unsigned fragcoord_input;
174
175 uint32_t req_local_mem;
176 bool integer_memory;
177
178 uint32_t num_ubo;
179 uint32_t ubo_base;
180 int ubo_idx[32];
181 int ubo_sizes[32];
182 uint32_t num_address;
183
184 uint32_t shader_req_bits;
185
186 struct pipe_stream_output_info *so;
187 char **so_names;
188 bool write_so_outputs[PIPE_MAX_SO_OUTPUTS];
189 bool uses_sampler_buf;
190 bool write_all_cbufs;
191 uint32_t shadow_samp_mask;
192
193 int fs_coord_origin, fs_pixel_center;
194
195 int gs_in_prim, gs_out_prim, gs_max_out_verts;
196 int gs_num_invocations;
197
198 struct vrend_shader_key *key;
199 int indent_level;
200 int num_in_clip_dist;
201 int num_clip_dist;
202 int glsl_ver_required;
203 int color_in_mask;
204 /* only used when cull is enabled */
205 uint8_t num_cull_dist_prop, num_clip_dist_prop;
206 bool front_face_emitted;
207
208 bool has_clipvertex;
209 bool has_clipvertex_so;
210 bool vs_has_pervertex;
211 bool write_mul_utemp;
212 bool write_mul_itemp;
213 bool has_sample_input;
214 bool early_depth_stencil;
215
216 int tcs_vertices_out;
217 int tes_prim_mode;
218 int tes_spacing;
219 int tes_vertex_order;
220 int tes_point_mode;
221
222 uint16_t local_cs_block_size[3];
223 };
224
225 static const struct vrend_shader_table shader_req_table[] = {
226 { SHADER_REQ_SAMPLER_RECT, "GL_ARB_texture_rectangle" },
227 { SHADER_REQ_CUBE_ARRAY, "GL_ARB_texture_cube_map_array" },
228 { SHADER_REQ_INTS, "GL_ARB_shader_bit_encoding" },
229 { SHADER_REQ_SAMPLER_MS, "GL_ARB_texture_multisample" },
230 { SHADER_REQ_INSTANCE_ID, "GL_ARB_draw_instanced" },
231 { SHADER_REQ_LODQ, "GL_ARB_texture_query_lod" },
232 { SHADER_REQ_TXQ_LEVELS, "GL_ARB_texture_query_levels" },
233 { SHADER_REQ_TG4, "GL_ARB_texture_gather" },
234 { SHADER_REQ_VIEWPORT_IDX, "GL_ARB_viewport_array" },
235 { SHADER_REQ_STENCIL_EXPORT, "GL_ARB_shader_stencil_export" },
236 { SHADER_REQ_LAYER, "GL_ARB_fragment_layer_viewport" },
237 { SHADER_REQ_SAMPLE_SHADING, "GL_ARB_sample_shading" },
238 { SHADER_REQ_GPU_SHADER5, "GL_ARB_gpu_shader5" },
239 { SHADER_REQ_DERIVATIVE_CONTROL, "GL_ARB_derivative_control" },
240 { SHADER_REQ_FP64, "GL_ARB_gpu_shader_fp64" },
241 { SHADER_REQ_IMAGE_LOAD_STORE, "GL_ARB_shader_image_load_store" },
242 { SHADER_REQ_ES31_COMPAT, "GL_ARB_ES3_1_compatibility" },
243 { SHADER_REQ_IMAGE_SIZE, "GL_ARB_shader_image_size" },
244 { SHADER_REQ_TXQS, "GL_ARB_shader_texture_image_samples" },
245 { SHADER_REQ_FBFETCH, "GL_EXT_shader_framebuffer_fetch" },
246 { SHADER_REQ_SHADER_CLOCK, "GL_ARB_shader_clock" },
247 };
248
249 enum vrend_type_qualifier {
250 TYPE_CONVERSION_NONE = 0,
251 FLOAT = 1,
252 VEC2 = 2,
253 VEC3 = 3,
254 VEC4 = 4,
255 INT = 5,
256 IVEC2 = 6,
257 IVEC3 = 7,
258 IVEC4 = 8,
259 UINT = 9,
260 UVEC2 = 10,
261 UVEC3 = 11,
262 UVEC4 = 12,
263 FLOAT_BITS_TO_UINT = 13,
264 UINT_BITS_TO_FLOAT = 14,
265 FLOAT_BITS_TO_INT = 15,
266 INT_BITS_TO_FLOAT = 16,
267 DOUBLE = 17,
268 DVEC2 = 18,
269 };
270
271 struct dest_info {
272 enum vrend_type_qualifier dtypeprefix;
273 enum vrend_type_qualifier dstconv;
274 enum vrend_type_qualifier udstconv;
275 enum vrend_type_qualifier idstconv;
276 bool dst_override_no_wm[2];
277 };
278
279 struct source_info {
280 enum vrend_type_qualifier svec4;
281 uint32_t sreg_index;
282 bool tg4_has_component;
283 bool override_no_wm[3];
284 bool override_no_cast[3];
285 };
286
287 static const struct vrend_shader_table conversion_table[] =
288 {
289 {TYPE_CONVERSION_NONE, ""},
290 {FLOAT, "float"},
291 {VEC2, "vec2"},
292 {VEC3, "vec3"},
293 {VEC4, "vec4"},
294 {INT, "int"},
295 {IVEC2, "ivec2"},
296 {IVEC3, "ivec3"},
297 {IVEC4, "ivec4"},
298 {UINT, "uint"},
299 {UVEC2, "uvec2"},
300 {UVEC3, "uvec3"},
301 {UVEC4, "uvec4"},
302 {FLOAT_BITS_TO_UINT, "floatBitsToUint"},
303 {UINT_BITS_TO_FLOAT, "uintBitsToFloat"},
304 {FLOAT_BITS_TO_INT, "floatBitsToInt"},
305 {INT_BITS_TO_FLOAT, "intBitsToFloat"},
306 {DOUBLE, "double"},
307 {DVEC2, "dvec2"},
308 };
309
get_string(enum vrend_type_qualifier key)310 static inline const char *get_string(enum vrend_type_qualifier key)
311 {
312 if (key >= ARRAY_SIZE(conversion_table)) {
313 printf("Unable to find the correct conversion\n");
314 return conversion_table[TYPE_CONVERSION_NONE].string;
315 }
316
317 return conversion_table[key].string;
318 }
319
get_wm_string(unsigned wm)320 static inline const char *get_wm_string(unsigned wm)
321 {
322 switch(wm) {
323 case TGSI_WRITEMASK_NONE:
324 return "";
325 case TGSI_WRITEMASK_X:
326 return ".x";
327 case TGSI_WRITEMASK_XY:
328 return ".xy";
329 case TGSI_WRITEMASK_XYZ:
330 return ".xyz";
331 case TGSI_WRITEMASK_W:
332 return ".w";
333 default:
334 printf("Unable to unknown writemask\n");
335 return "";
336 }
337 }
338
339 const char *get_internalformat_string(int virgl_format, enum tgsi_return_type *stype);
340
tgsi_proc_to_prefix(int shader_type)341 static inline const char *tgsi_proc_to_prefix(int shader_type)
342 {
343 switch (shader_type) {
344 case TGSI_PROCESSOR_VERTEX: return "vs";
345 case TGSI_PROCESSOR_FRAGMENT: return "fs";
346 case TGSI_PROCESSOR_GEOMETRY: return "gs";
347 case TGSI_PROCESSOR_TESS_CTRL: return "tc";
348 case TGSI_PROCESSOR_TESS_EVAL: return "te";
349 case TGSI_PROCESSOR_COMPUTE: return "cs";
350 default:
351 return NULL;
352 };
353 }
354
prim_to_name(int prim)355 static inline const char *prim_to_name(int prim)
356 {
357 switch (prim) {
358 case PIPE_PRIM_POINTS: return "points";
359 case PIPE_PRIM_LINES: return "lines";
360 case PIPE_PRIM_LINE_STRIP: return "line_strip";
361 case PIPE_PRIM_LINES_ADJACENCY: return "lines_adjacency";
362 case PIPE_PRIM_TRIANGLES: return "triangles";
363 case PIPE_PRIM_TRIANGLE_STRIP: return "triangle_strip";
364 case PIPE_PRIM_TRIANGLES_ADJACENCY: return "triangles_adjacency";
365 case PIPE_PRIM_QUADS: return "quads";
366 default: return "UNKNOWN";
367 };
368 }
369
prim_to_tes_name(int prim)370 static inline const char *prim_to_tes_name(int prim)
371 {
372 switch (prim) {
373 case PIPE_PRIM_QUADS: return "quads";
374 case PIPE_PRIM_TRIANGLES: return "triangles";
375 case PIPE_PRIM_LINES: return "isolines";
376 default: return "UNKNOWN";
377 }
378 }
379
get_spacing_string(int spacing)380 static const char *get_spacing_string(int spacing)
381 {
382 switch (spacing) {
383 case PIPE_TESS_SPACING_FRACTIONAL_ODD:
384 return "fractional_odd_spacing";
385 case PIPE_TESS_SPACING_FRACTIONAL_EVEN:
386 return "fractional_even_spacing";
387 case PIPE_TESS_SPACING_EQUAL:
388 default:
389 return "equal_spacing";
390 }
391 }
392
gs_input_prim_to_size(int prim)393 static inline int gs_input_prim_to_size(int prim)
394 {
395 switch (prim) {
396 case PIPE_PRIM_POINTS: return 1;
397 case PIPE_PRIM_LINES: return 2;
398 case PIPE_PRIM_LINES_ADJACENCY: return 4;
399 case PIPE_PRIM_TRIANGLES: return 3;
400 case PIPE_PRIM_TRIANGLES_ADJACENCY: return 6;
401 default: return -1;
402 };
403 }
404
fs_emit_layout(struct dump_ctx * ctx)405 static inline bool fs_emit_layout(struct dump_ctx *ctx)
406 {
407 if (ctx->fs_pixel_center)
408 return true;
409 /* if coord origin is 0 and invert is 0 - emit origin_upper_left,
410 if coord_origin is 0 and invert is 1 - emit nothing (lower)
411 if coord origin is 1 and invert is 0 - emit nothing (lower)
412 if coord_origin is 1 and invert is 1 - emit origin upper left */
413 if (!(ctx->fs_coord_origin ^ ctx->key->invert_fs_origin))
414 return true;
415 return false;
416 }
417
get_stage_input_name_prefix(struct dump_ctx * ctx,int processor)418 static const char *get_stage_input_name_prefix(struct dump_ctx *ctx, int processor)
419 {
420 const char *name_prefix;
421 switch (processor) {
422 case TGSI_PROCESSOR_FRAGMENT:
423 if (ctx->key->gs_present)
424 name_prefix = "gso";
425 else if (ctx->key->tes_present)
426 name_prefix = "teo";
427 else
428 name_prefix = "vso";
429 break;
430 case TGSI_PROCESSOR_GEOMETRY:
431 if (ctx->key->tes_present)
432 name_prefix = "teo";
433 else
434 name_prefix = "vso";
435 break;
436 case TGSI_PROCESSOR_TESS_EVAL:
437 if (ctx->key->tcs_present)
438 name_prefix = "tco";
439 else
440 name_prefix = "vso";
441 break;
442 case TGSI_PROCESSOR_TESS_CTRL:
443 name_prefix = "vso";
444 break;
445 case TGSI_PROCESSOR_VERTEX:
446 default:
447 name_prefix = "in";
448 break;
449 }
450 return name_prefix;
451 }
452
get_stage_output_name_prefix(int processor)453 static const char *get_stage_output_name_prefix(int processor)
454 {
455 const char *name_prefix;
456 switch (processor) {
457 case TGSI_PROCESSOR_FRAGMENT:
458 name_prefix = "fsout";
459 break;
460 case TGSI_PROCESSOR_GEOMETRY:
461 name_prefix = "gso";
462 break;
463 case TGSI_PROCESSOR_VERTEX:
464 name_prefix = "vso";
465 break;
466 case TGSI_PROCESSOR_TESS_CTRL:
467 name_prefix = "tco";
468 break;
469 case TGSI_PROCESSOR_TESS_EVAL:
470 name_prefix = "teo";
471 break;
472 default:
473 name_prefix = "out";
474 break;
475 }
476 return name_prefix;
477 }
478
require_glsl_ver(struct dump_ctx * ctx,int glsl_ver)479 static void require_glsl_ver(struct dump_ctx *ctx, int glsl_ver)
480 {
481 if (glsl_ver > ctx->glsl_ver_required)
482 ctx->glsl_ver_required = glsl_ver;
483 }
484
strcat_realloc(char * str,const char * catstr)485 static char *strcat_realloc(char *str, const char *catstr)
486 {
487 char *new = realloc(str, strlen(str) + strlen(catstr) + 1);
488 if (!new) {
489 free(str);
490 return NULL;
491 }
492 strcat(new, catstr);
493 return new;
494 }
495
add_str_to_glsl_main(struct dump_ctx * ctx,const char * buf)496 static char *add_str_to_glsl_main(struct dump_ctx *ctx, const char *buf)
497 {
498 ctx->glsl_main = strcat_realloc(ctx->glsl_main, buf);
499 return ctx->glsl_main;
500 }
501
allocate_temp_range(struct dump_ctx * ctx,int first,int last,int array_id)502 static int allocate_temp_range(struct dump_ctx *ctx, int first, int last,
503 int array_id)
504 {
505 int idx = ctx->num_temp_ranges;
506
507 ctx->temp_ranges = realloc(ctx->temp_ranges, sizeof(struct vrend_temp_range) * (idx + 1));
508 if (!ctx->temp_ranges)
509 return ENOMEM;
510
511 ctx->temp_ranges[idx].first = first;
512 ctx->temp_ranges[idx].last = last;
513 ctx->temp_ranges[idx].array_id = array_id;
514 ctx->num_temp_ranges++;
515 return 0;
516 }
517
find_temp_range(struct dump_ctx * ctx,int index)518 static struct vrend_temp_range *find_temp_range(struct dump_ctx *ctx, int index)
519 {
520 uint32_t i;
521 for (i = 0; i < ctx->num_temp_ranges; i++) {
522 if (index >= ctx->temp_ranges[i].first &&
523 index <= ctx->temp_ranges[i].last)
524 return &ctx->temp_ranges[i];
525 }
526 return NULL;
527 }
528
add_images(struct dump_ctx * ctx,int first,int last,struct tgsi_declaration_image * img_decl)529 static int add_images(struct dump_ctx *ctx, int first, int last,
530 struct tgsi_declaration_image *img_decl)
531 {
532 int i;
533
534 for (i = first; i <= last; i++) {
535 ctx->images[i].decl = *img_decl;
536 ctx->images[i].vflag = false;
537 ctx->images_used_mask |= (1 << i);
538
539 if (ctx->images[i].decl.Resource == TGSI_TEXTURE_CUBE_ARRAY)
540 ctx->shader_req_bits |= SHADER_REQ_CUBE_ARRAY;
541 else if (ctx->images[i].decl.Resource == TGSI_TEXTURE_2D_MSAA ||
542 ctx->images[i].decl.Resource == TGSI_TEXTURE_2D_ARRAY_MSAA)
543 ctx->shader_req_bits |= SHADER_REQ_SAMPLER_MS;
544 else if (ctx->images[i].decl.Resource == TGSI_TEXTURE_BUFFER)
545 ctx->uses_sampler_buf = true;
546 else if (ctx->images[i].decl.Resource == TGSI_TEXTURE_RECT)
547 ctx->shader_req_bits |= SHADER_REQ_SAMPLER_RECT;
548 }
549
550 if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
551 if (ctx->num_image_arrays) {
552 struct vrend_array *last_array = &ctx->image_arrays[ctx->num_image_arrays - 1];
553 /*
554 * If this set of images is consecutive to the last array,
555 * and has compatible return and decls, then increase the array size.
556 */
557 if ((last_array->first + last_array->array_size == first) &&
558 !memcmp(&ctx->images[last_array->first].decl, &ctx->images[first].decl, sizeof(ctx->images[first].decl)) &&
559 ctx->images[last_array->first].image_return == ctx->images[first].image_return) {
560 last_array->array_size += last - first + 1;
561 return 0;
562 }
563 }
564
565 /* allocate a new image array for this range of images */
566 ctx->num_image_arrays++;
567 ctx->image_arrays = realloc(ctx->image_arrays, sizeof(struct vrend_array) * ctx->num_image_arrays);
568 if (!ctx->image_arrays)
569 return -1;
570 ctx->image_arrays[ctx->num_image_arrays - 1].first = first;
571 ctx->image_arrays[ctx->num_image_arrays - 1].array_size = last - first + 1;
572 }
573 return 0;
574 }
575
add_sampler_array(struct dump_ctx * ctx,int first,int last)576 static int add_sampler_array(struct dump_ctx *ctx, int first, int last)
577 {
578 int idx = ctx->num_sampler_arrays;
579 ctx->num_sampler_arrays++;
580 ctx->sampler_arrays = realloc(ctx->sampler_arrays, sizeof(struct vrend_array) * ctx->num_sampler_arrays);
581 if (!ctx->sampler_arrays)
582 return -1;
583
584 ctx->sampler_arrays[idx].first = first;
585 ctx->sampler_arrays[idx].array_size = last - first + 1;
586 return 0;
587 }
588
lookup_sampler_array(struct dump_ctx * ctx,int index)589 static int lookup_sampler_array(struct dump_ctx *ctx, int index)
590 {
591 uint32_t i;
592 for (i = 0; i < ctx->num_sampler_arrays; i++) {
593 int last = ctx->sampler_arrays[i].first + ctx->sampler_arrays[i].array_size - 1;
594 if (index >= ctx->sampler_arrays[i].first &&
595 index <= last) {
596 return ctx->sampler_arrays[i].first;
597 }
598 }
599 return -1;
600 }
601
shader_lookup_sampler_array(struct vrend_shader_info * sinfo,int index)602 int shader_lookup_sampler_array(struct vrend_shader_info *sinfo, int index)
603 {
604 int i;
605 for (i = 0; i < sinfo->num_sampler_arrays; i++) {
606 int last = sinfo->sampler_arrays[i].first + sinfo->sampler_arrays[i].array_size - 1;
607 if (index >= sinfo->sampler_arrays[i].first &&
608 index <= last) {
609 return sinfo->sampler_arrays[i].first;
610 }
611 }
612 return -1;
613 }
614
add_samplers(struct dump_ctx * ctx,int first,int last,int sview_type,enum tgsi_return_type sview_rtype)615 static int add_samplers(struct dump_ctx *ctx, int first, int last, int sview_type, enum tgsi_return_type sview_rtype)
616 {
617 if (sview_rtype == TGSI_RETURN_TYPE_SINT ||
618 sview_rtype == TGSI_RETURN_TYPE_UINT)
619 ctx->shader_req_bits |= SHADER_REQ_INTS;
620
621 for (int i = first; i <= last; i++) {
622 ctx->samplers[i].tgsi_sampler_return = sview_rtype;
623 ctx->samplers[i].tgsi_sampler_type = sview_type;
624 }
625
626 if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
627 if (ctx->num_sampler_arrays) {
628 struct vrend_array *last_array = &ctx->sampler_arrays[ctx->num_sampler_arrays - 1];
629 if ((last_array->first + last_array->array_size == first) &&
630 ctx->samplers[last_array->first].tgsi_sampler_type == sview_type &&
631 ctx->samplers[last_array->first].tgsi_sampler_return == sview_rtype) {
632 last_array->array_size += last - first + 1;
633 return 0;
634 }
635 }
636
637 /* allocate a new image array for this range of images */
638 return add_sampler_array(ctx, first, last);
639 }
640 return 0;
641 }
642
ctx_indirect_inputs(struct dump_ctx * ctx)643 static bool ctx_indirect_inputs(struct dump_ctx *ctx)
644 {
645 if (ctx->info.indirect_files & (1 << TGSI_FILE_INPUT))
646 return true;
647 if (ctx->key->num_indirect_generic_inputs || ctx->key->num_indirect_patch_inputs)
648 return true;
649 return false;
650 }
651
ctx_indirect_outputs(struct dump_ctx * ctx)652 static bool ctx_indirect_outputs(struct dump_ctx *ctx)
653 {
654 if (ctx->info.indirect_files & (1 << TGSI_FILE_OUTPUT))
655 return true;
656 if (ctx->key->num_indirect_generic_outputs || ctx->key->num_indirect_patch_outputs)
657 return true;
658 return false;
659 }
660
lookup_image_array(struct dump_ctx * ctx,int index)661 static int lookup_image_array(struct dump_ctx *ctx, int index)
662 {
663 uint32_t i;
664 for (i = 0; i < ctx->num_image_arrays; i++) {
665 if (index >= ctx->image_arrays[i].first &&
666 index <= ctx->image_arrays[i].first + ctx->image_arrays[i].array_size - 1) {
667 return ctx->image_arrays[i].first;
668 }
669 }
670 return -1;
671 }
672
673 static boolean
iter_declaration(struct tgsi_iterate_context * iter,struct tgsi_full_declaration * decl)674 iter_declaration(struct tgsi_iterate_context *iter,
675 struct tgsi_full_declaration *decl )
676 {
677 struct dump_ctx *ctx = (struct dump_ctx *)iter;
678 int i;
679 int color_offset = 0;
680 const char *name_prefix = "";
681 bool add_two_side = false;
682 bool indirect = false;
683
684 switch (decl->Declaration.File) {
685 case TGSI_FILE_INPUT:
686 i = ctx->num_inputs++;
687 indirect = ctx_indirect_inputs(ctx);
688 if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) {
689 fprintf(stderr, "Number of inputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->inputs));
690 return FALSE;
691 }
692 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
693 ctx->attrib_input_mask |= (1 << decl->Range.First);
694 }
695 ctx->inputs[i].name = decl->Semantic.Name;
696 ctx->inputs[i].sid = decl->Semantic.Index;
697 ctx->inputs[i].interpolate = decl->Interp.Interpolate;
698 ctx->inputs[i].location = decl->Interp.Location;
699 ctx->inputs[i].first = decl->Range.First;
700 ctx->inputs[i].glsl_predefined_no_emit = false;
701 ctx->inputs[i].glsl_no_index = false;
702 ctx->inputs[i].override_no_wm = false;
703 ctx->inputs[i].glsl_gl_block = false;
704
705 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT &&
706 decl->Interp.Location == TGSI_INTERPOLATE_LOC_SAMPLE) {
707 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
708 ctx->has_sample_input = true;
709 }
710
711 switch (ctx->inputs[i].name) {
712 case TGSI_SEMANTIC_COLOR:
713 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
714 if (ctx->glsl_ver_required < 140) {
715 if (decl->Semantic.Index == 0)
716 name_prefix = "gl_Color";
717 else if (decl->Semantic.Index == 1)
718 name_prefix = "gl_SecondaryColor";
719 else
720 fprintf(stderr, "got illegal color semantic index %d\n", decl->Semantic.Index);
721 ctx->inputs[i].glsl_no_index = true;
722 } else {
723 if (ctx->key->color_two_side) {
724 int j = ctx->num_inputs++;
725 if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) {
726 fprintf(stderr, "Number of inputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->inputs));
727 return FALSE;
728 }
729
730 ctx->inputs[j].name = TGSI_SEMANTIC_BCOLOR;
731 ctx->inputs[j].sid = decl->Semantic.Index;
732 ctx->inputs[j].interpolate = decl->Interp.Interpolate;
733 ctx->inputs[j].location = decl->Interp.Location;
734 ctx->inputs[j].first = decl->Range.First;
735 ctx->inputs[j].glsl_predefined_no_emit = false;
736 ctx->inputs[j].glsl_no_index = false;
737 ctx->inputs[j].override_no_wm = false;
738
739 ctx->color_in_mask |= (1 << decl->Semantic.Index);
740
741 if (ctx->front_face_emitted == false) {
742 int k = ctx->num_inputs++;
743 if (ctx->num_inputs > ARRAY_SIZE(ctx->inputs)) {
744 fprintf(stderr, "Number of inputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->inputs));
745 return FALSE;
746 }
747
748 ctx->inputs[k].name = TGSI_SEMANTIC_FACE;
749 ctx->inputs[k].sid = 0;
750 ctx->inputs[k].interpolate = 0;
751 ctx->inputs[k].location = TGSI_INTERPOLATE_LOC_CENTER;
752 ctx->inputs[k].first = 0;
753 ctx->inputs[k].override_no_wm = false;
754 ctx->inputs[k].glsl_predefined_no_emit = true;
755 ctx->inputs[k].glsl_no_index = true;
756 }
757 add_two_side = true;
758 }
759 name_prefix = "ex";
760 }
761 break;
762 }
763 /* fallthrough */
764 case TGSI_SEMANTIC_PRIMID:
765 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
766 name_prefix = "gl_PrimitiveIDIn";
767 ctx->inputs[i].glsl_predefined_no_emit = true;
768 ctx->inputs[i].glsl_no_index = true;
769 ctx->inputs[i].override_no_wm = true;
770 ctx->shader_req_bits |= SHADER_REQ_INTS;
771 break;
772 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
773 name_prefix = "gl_PrimitiveID";
774 ctx->inputs[i].glsl_predefined_no_emit = true;
775 ctx->inputs[i].glsl_no_index = true;
776 require_glsl_ver(ctx, 150);
777 break;
778 }
779 /* fallthrough */
780 case TGSI_SEMANTIC_VIEWPORT_INDEX:
781 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
782 ctx->inputs[i].glsl_predefined_no_emit = true;
783 ctx->inputs[i].glsl_no_index = true;
784 ctx->inputs[i].is_int = true;
785 ctx->inputs[i].override_no_wm = true;
786 name_prefix = "gl_ViewportIndex";
787 if (ctx->glsl_ver_required >= 140)
788 ctx->shader_req_bits |= SHADER_REQ_LAYER;
789 break;
790 }
791 /* fallthrough */
792 case TGSI_SEMANTIC_LAYER:
793 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
794 name_prefix = "gl_Layer";
795 ctx->inputs[i].glsl_predefined_no_emit = true;
796 ctx->inputs[i].glsl_no_index = true;
797 ctx->inputs[i].is_int = true;
798 ctx->inputs[i].override_no_wm = true;
799 ctx->shader_req_bits |= SHADER_REQ_LAYER;
800 break;
801 }
802 /* fallthrough */
803 case TGSI_SEMANTIC_PSIZE:
804 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
805 iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
806 iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
807 name_prefix = "gl_PointSize";
808 ctx->inputs[i].glsl_predefined_no_emit = true;
809 ctx->inputs[i].glsl_no_index = true;
810 ctx->inputs[i].override_no_wm = true;
811 ctx->inputs[i].glsl_gl_block = true;
812 ctx->shader_req_bits |= SHADER_REQ_PSIZE;
813 break;
814 }
815 /* fallthrough */
816 case TGSI_SEMANTIC_CLIPDIST:
817 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
818 iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
819 iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
820 name_prefix = "gl_ClipDistance";
821 ctx->inputs[i].glsl_predefined_no_emit = true;
822 ctx->inputs[i].glsl_no_index = true;
823 ctx->inputs[i].glsl_gl_block = true;
824 ctx->num_in_clip_dist += 4;
825 break;
826 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
827 name_prefix = "gl_ClipDistance";
828 ctx->inputs[i].glsl_predefined_no_emit = true;
829 ctx->inputs[i].glsl_no_index = true;
830 ctx->num_in_clip_dist += 4;
831 break;
832 }
833 /* fallthrough */
834 case TGSI_SEMANTIC_POSITION:
835 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
836 iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
837 iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
838 name_prefix = "gl_Position";
839 ctx->inputs[i].glsl_predefined_no_emit = true;
840 ctx->inputs[i].glsl_no_index = true;
841 ctx->inputs[i].glsl_gl_block = true;
842 break;
843 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
844 name_prefix = "gl_FragCoord";
845 ctx->inputs[i].glsl_predefined_no_emit = true;
846 ctx->inputs[i].glsl_no_index = true;
847 break;
848 }
849 /* fallthrough */
850 case TGSI_SEMANTIC_FACE:
851 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
852 if (ctx->front_face_emitted) {
853 ctx->num_inputs--;
854 return TRUE;
855 }
856 name_prefix = "gl_FrontFacing";
857 ctx->inputs[i].glsl_predefined_no_emit = true;
858 ctx->inputs[i].glsl_no_index = true;
859 ctx->front_face_emitted = true;
860 break;
861 }
862 /* fallthrough */
863 case TGSI_SEMANTIC_PATCH:
864 if (indirect && ctx->inputs[i].name == TGSI_SEMANTIC_PATCH) {
865 ctx->inputs[i].glsl_predefined_no_emit = true;
866 if (ctx->inputs[i].sid < ctx->patch_input_range.first || ctx->patch_input_range.used == false) {
867 ctx->patch_input_range.first = ctx->inputs[i].sid;
868 ctx->patch_input_range.array_id = i;
869 ctx->patch_input_range.used = true;
870 }
871 if (ctx->inputs[i].sid > ctx->patch_input_range.last)
872 ctx->patch_input_range.last = ctx->inputs[i].sid;
873 }
874 /* fallthrough */
875 case TGSI_SEMANTIC_GENERIC:
876 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
877 if (ctx->key->coord_replace & (1 << ctx->inputs[i].sid)) {
878 if (ctx->cfg->use_gles)
879 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)";
880 else
881 name_prefix = "vec4(gl_PointCoord, 0.0, 1.0)";
882 ctx->inputs[i].glsl_predefined_no_emit = true;
883 ctx->inputs[i].glsl_no_index = true;
884 break;
885 }
886 }
887 if (indirect && ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC) {
888 ctx->inputs[i].glsl_predefined_no_emit = true;
889 if (ctx->inputs[i].sid < ctx->generic_input_range.first || ctx->generic_input_range.used == false) {
890 ctx->generic_input_range.first = ctx->inputs[i].sid;
891 ctx->generic_input_range.array_id = i;
892 ctx->generic_input_range.used = true;
893 }
894 if (ctx->inputs[i].sid > ctx->generic_input_range.last)
895 ctx->generic_input_range.last = ctx->inputs[i].sid;
896 }
897 /* fallthrough */
898 default:
899 name_prefix = get_stage_input_name_prefix(ctx, iter->processor.Processor);
900 break;
901 }
902
903 if (ctx->inputs[i].glsl_no_index)
904 snprintf(ctx->inputs[i].glsl_name, 128, "%s", name_prefix);
905 else {
906 if (ctx->inputs[i].name == TGSI_SEMANTIC_FOG)
907 snprintf(ctx->inputs[i].glsl_name, 64, "%s_f%d", name_prefix, ctx->inputs[i].sid);
908 else if (ctx->inputs[i].name == TGSI_SEMANTIC_COLOR)
909 snprintf(ctx->inputs[i].glsl_name, 64, "%s_c%d", name_prefix, ctx->inputs[i].sid);
910 else if (ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC)
911 snprintf(ctx->inputs[i].glsl_name, 64, "%s_g%d", name_prefix, ctx->inputs[i].sid);
912 else if (ctx->inputs[i].name == TGSI_SEMANTIC_PATCH)
913 snprintf(ctx->inputs[i].glsl_name, 64, "%s_p%d", name_prefix, ctx->inputs[i].sid);
914 else
915 snprintf(ctx->inputs[i].glsl_name, 64, "%s_%d", name_prefix, ctx->inputs[i].first);
916 }
917 if (add_two_side) {
918 snprintf(ctx->inputs[i + 1].glsl_name, 64, "%s_bc%d", name_prefix, ctx->inputs[i + 1].sid);
919 if (!ctx->front_face_emitted) {
920 snprintf(ctx->inputs[i + 2].glsl_name, 64, "%s", "gl_FrontFacing");
921 ctx->front_face_emitted = true;
922 }
923 }
924 break;
925 case TGSI_FILE_OUTPUT:
926 i = ctx->num_outputs++;
927 indirect = ctx_indirect_outputs(ctx);
928 if (ctx->num_outputs > ARRAY_SIZE(ctx->outputs)) {
929 fprintf(stderr, "Number of outputs exceeded, max is %lu\n", ARRAY_SIZE(ctx->outputs));
930 return FALSE;
931 }
932
933 ctx->outputs[i].name = decl->Semantic.Name;
934 ctx->outputs[i].sid = decl->Semantic.Index;
935 ctx->outputs[i].interpolate = decl->Interp.Interpolate;
936 ctx->outputs[i].invariant = decl->Declaration.Invariant;
937 ctx->outputs[i].precise = false;
938 ctx->outputs[i].first = decl->Range.First;
939 ctx->outputs[i].glsl_predefined_no_emit = false;
940 ctx->outputs[i].glsl_no_index = false;
941 ctx->outputs[i].override_no_wm = false;
942 ctx->outputs[i].is_int = false;
943 ctx->outputs[i].fbfetch_used = false;
944
945 switch (ctx->outputs[i].name) {
946 case TGSI_SEMANTIC_POSITION:
947 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX ||
948 iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
949 iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
950 iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
951 if (ctx->outputs[i].first > 0)
952 fprintf(stderr,"Illegal position input\n");
953 name_prefix = "gl_Position";
954 ctx->outputs[i].glsl_predefined_no_emit = true;
955 ctx->outputs[i].glsl_no_index = true;
956 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL)
957 ctx->outputs[i].glsl_gl_block = true;
958 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
959 name_prefix = "gl_FragDepth";
960 ctx->outputs[i].glsl_predefined_no_emit = true;
961 ctx->outputs[i].glsl_no_index = true;
962 ctx->outputs[i].override_no_wm = true;
963 }
964 break;
965 case TGSI_SEMANTIC_STENCIL:
966 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
967 name_prefix = "gl_FragStencilRefARB";
968 ctx->outputs[i].glsl_predefined_no_emit = true;
969 ctx->outputs[i].glsl_no_index = true;
970 ctx->outputs[i].override_no_wm = true;
971 ctx->outputs[i].is_int = true;
972 ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_STENCIL_EXPORT);
973 }
974 break;
975 case TGSI_SEMANTIC_CLIPDIST:
976 name_prefix = "gl_ClipDistance";
977 ctx->outputs[i].glsl_predefined_no_emit = true;
978 ctx->outputs[i].glsl_no_index = true;
979 ctx->num_clip_dist += 4;
980 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX &&
981 (ctx->key->gs_present || ctx->key->tcs_present))
982 require_glsl_ver(ctx, 150);
983 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL)
984 ctx->outputs[i].glsl_gl_block = true;
985 break;
986 case TGSI_SEMANTIC_CLIPVERTEX:
987 name_prefix = "gl_ClipVertex";
988 ctx->outputs[i].glsl_predefined_no_emit = true;
989 ctx->outputs[i].glsl_no_index = true;
990 ctx->outputs[i].override_no_wm = true;
991 if (ctx->glsl_ver_required >= 140)
992 ctx->has_clipvertex = true;
993 break;
994 case TGSI_SEMANTIC_SAMPLEMASK:
995 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
996 ctx->outputs[i].glsl_predefined_no_emit = true;
997 ctx->outputs[i].glsl_no_index = true;
998 ctx->outputs[i].override_no_wm = true;
999 ctx->outputs[i].is_int = true;
1000 ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_SAMPLE_SHADING);
1001 name_prefix = "gl_SampleMask";
1002 break;
1003 }
1004 break;
1005 case TGSI_SEMANTIC_COLOR:
1006 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
1007 if (ctx->glsl_ver_required < 140) {
1008 ctx->outputs[i].glsl_no_index = true;
1009 if (ctx->outputs[i].sid == 0)
1010 name_prefix = "gl_FrontColor";
1011 else if (ctx->outputs[i].sid == 1)
1012 name_prefix = "gl_FrontSecondaryColor";
1013 } else
1014 name_prefix = "ex";
1015 break;
1016 }
1017 /* fallthrough */
1018 case TGSI_SEMANTIC_BCOLOR:
1019 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
1020 if (ctx->glsl_ver_required < 140) {
1021 ctx->outputs[i].glsl_no_index = true;
1022 if (ctx->outputs[i].sid == 0)
1023 name_prefix = "gl_BackColor";
1024 else if (ctx->outputs[i].sid == 1)
1025 name_prefix = "gl_BackSecondaryColor";
1026 break;
1027 } else
1028 name_prefix = "ex";
1029 break;
1030 }
1031 /* fallthrough */
1032 case TGSI_SEMANTIC_PSIZE:
1033 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX ||
1034 iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY ||
1035 iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL ||
1036 iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
1037 ctx->outputs[i].glsl_predefined_no_emit = true;
1038 ctx->outputs[i].glsl_no_index = true;
1039 ctx->outputs[i].override_no_wm = true;
1040 ctx->shader_req_bits |= SHADER_REQ_PSIZE;
1041 name_prefix = "gl_PointSize";
1042 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL)
1043 ctx->outputs[i].glsl_gl_block = true;
1044 break;
1045 }
1046 /* fallthrough */
1047 case TGSI_SEMANTIC_LAYER:
1048 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
1049 ctx->outputs[i].glsl_predefined_no_emit = true;
1050 ctx->outputs[i].glsl_no_index = true;
1051 ctx->outputs[i].override_no_wm = true;
1052 ctx->outputs[i].is_int = true;
1053 name_prefix = "gl_Layer";
1054 break;
1055 }
1056 /* fallthrough */
1057 case TGSI_SEMANTIC_PRIMID:
1058 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
1059 ctx->outputs[i].glsl_predefined_no_emit = true;
1060 ctx->outputs[i].glsl_no_index = true;
1061 ctx->outputs[i].override_no_wm = true;
1062 ctx->outputs[i].is_int = true;
1063 name_prefix = "gl_PrimitiveID";
1064 break;
1065 }
1066 /* fallthrough */
1067 case TGSI_SEMANTIC_VIEWPORT_INDEX:
1068 if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
1069 ctx->outputs[i].glsl_predefined_no_emit = true;
1070 ctx->outputs[i].glsl_no_index = true;
1071 ctx->outputs[i].override_no_wm = true;
1072 ctx->outputs[i].is_int = true;
1073 name_prefix = "gl_ViewportIndex";
1074 if (ctx->glsl_ver_required >= 140)
1075 ctx->shader_req_bits |= SHADER_REQ_VIEWPORT_IDX;
1076 break;
1077 }
1078 /* fallthrough */
1079 case TGSI_SEMANTIC_TESSOUTER:
1080 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL) {
1081 ctx->outputs[i].glsl_predefined_no_emit = true;
1082 ctx->outputs[i].glsl_no_index = true;
1083 ctx->outputs[i].override_no_wm = true;
1084 name_prefix = "gl_TessLevelOuter";
1085 break;
1086 }
1087 /* fallthrough */
1088 case TGSI_SEMANTIC_TESSINNER:
1089 if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL) {
1090 ctx->outputs[i].glsl_predefined_no_emit = true;
1091 ctx->outputs[i].glsl_no_index = true;
1092 ctx->outputs[i].override_no_wm = true;
1093 name_prefix = "gl_TessLevelInner";
1094 break;
1095 }
1096 /* fallthrough */
1097 case TGSI_SEMANTIC_GENERIC:
1098 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX)
1099 if (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC)
1100 color_offset = -1;
1101 if (indirect && ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC) {
1102 ctx->outputs[i].glsl_predefined_no_emit = true;
1103 require_glsl_ver(ctx, 150);
1104 if (ctx->outputs[i].sid < ctx->generic_output_range.first || ctx->generic_output_range.used == false) {
1105 ctx->generic_output_range.array_id = i;
1106 ctx->generic_output_range.first = ctx->outputs[i].sid;
1107 ctx->generic_output_range.used = true;
1108 }
1109 if (ctx->outputs[i].sid > ctx->generic_output_range.last)
1110 ctx->generic_output_range.last = ctx->outputs[i].sid;
1111 }
1112 /* fallthrough */
1113 case TGSI_SEMANTIC_PATCH:
1114 if (indirect && ctx->outputs[i].name == TGSI_SEMANTIC_PATCH) {
1115 ctx->outputs[i].glsl_predefined_no_emit = true;
1116 require_glsl_ver(ctx, 150);
1117 if (ctx->outputs[i].sid < ctx->patch_output_range.first || ctx->patch_output_range.used == false) {
1118 ctx->patch_output_range.array_id = i;
1119 ctx->patch_output_range.first = ctx->outputs[i].sid;
1120 ctx->patch_output_range.used = true;
1121 }
1122 if (ctx->outputs[i].sid > ctx->patch_output_range.last)
1123 ctx->patch_output_range.last = ctx->outputs[i].sid;
1124 }
1125 /* fallthrough */
1126 default:
1127 name_prefix = get_stage_output_name_prefix(iter->processor.Processor);
1128 break;
1129 }
1130
1131 if (ctx->outputs[i].glsl_no_index)
1132 snprintf(ctx->outputs[i].glsl_name, 64, "%s", name_prefix);
1133 else {
1134 if (ctx->outputs[i].name == TGSI_SEMANTIC_FOG)
1135 snprintf(ctx->outputs[i].glsl_name, 64, "%s_f%d", name_prefix, ctx->outputs[i].sid);
1136 else if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR)
1137 snprintf(ctx->outputs[i].glsl_name, 64, "%s_c%d", name_prefix, ctx->outputs[i].sid);
1138 else if (ctx->outputs[i].name == TGSI_SEMANTIC_BCOLOR)
1139 snprintf(ctx->outputs[i].glsl_name, 64, "%s_bc%d", name_prefix, ctx->outputs[i].sid);
1140 else if (ctx->outputs[i].name == TGSI_SEMANTIC_PATCH)
1141 snprintf(ctx->outputs[i].glsl_name, 64, "%s_p%d", name_prefix, ctx->outputs[i].sid);
1142 else if (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC)
1143 snprintf(ctx->outputs[i].glsl_name, 64, "%s_g%d", name_prefix, ctx->outputs[i].sid);
1144 else
1145 snprintf(ctx->outputs[i].glsl_name, 64, "%s_%d", name_prefix, ctx->outputs[i].first + color_offset);
1146
1147 }
1148 break;
1149 case TGSI_FILE_TEMPORARY:
1150 if (allocate_temp_range(ctx, decl->Range.First, decl->Range.Last,
1151 decl->Array.ArrayID))
1152 return FALSE;
1153 break;
1154 case TGSI_FILE_SAMPLER:
1155 ctx->samplers_used |= (1 << decl->Range.Last);
1156 break;
1157 case TGSI_FILE_SAMPLER_VIEW: {
1158 int ret;
1159 if (decl->Range.Last >= ARRAY_SIZE(ctx->samplers)) {
1160 fprintf(stderr, "Sampler view exceeded, max is %lu\n", ARRAY_SIZE(ctx->samplers));
1161 return FALSE;
1162 }
1163 ret = add_samplers(ctx, decl->Range.First, decl->Range.Last, decl->SamplerView.Resource, decl->SamplerView.ReturnTypeX);
1164 if (ret == -1)
1165 return FALSE;
1166 break;
1167 }
1168 case TGSI_FILE_IMAGE: {
1169 int ret;
1170 ctx->shader_req_bits |= SHADER_REQ_IMAGE_LOAD_STORE;
1171 if (decl->Range.Last >= ARRAY_SIZE(ctx->images)) {
1172 fprintf(stderr, "Image view exceeded, max is %lu\n", ARRAY_SIZE(ctx->images));
1173 return FALSE;
1174 }
1175 ret = add_images(ctx, decl->Range.First, decl->Range.Last, &decl->Image);
1176 if (ret == -1)
1177 return FALSE;
1178 break;
1179 }
1180 case TGSI_FILE_BUFFER:
1181 if (decl->Range.First >= 32) {
1182 fprintf(stderr, "Buffer view exceeded, max is 32\n");
1183 return FALSE;
1184 }
1185 ctx->ssbo_used_mask |= (1 << decl->Range.First);
1186 if (decl->Declaration.Atomic) {
1187 if (decl->Range.First < ctx->ssbo_atomic_array_base)
1188 ctx->ssbo_atomic_array_base = decl->Range.First;
1189 ctx->ssbo_atomic_mask |= (1 << decl->Range.First);
1190 } else {
1191 if (decl->Range.First < ctx->ssbo_array_base)
1192 ctx->ssbo_array_base = decl->Range.First;
1193 }
1194 break;
1195 case TGSI_FILE_CONSTANT:
1196 if (decl->Declaration.Dimension && decl->Dim.Index2D != 0) {
1197 if (ctx->num_ubo >= ARRAY_SIZE(ctx->ubo_idx)) {
1198 fprintf(stderr, "Number of uniforms exceeded, max is %lu\n", ARRAY_SIZE(ctx->ubo_idx));
1199 return FALSE;
1200 }
1201 ctx->ubo_idx[ctx->num_ubo] = decl->Dim.Index2D;
1202 ctx->ubo_sizes[ctx->num_ubo] = decl->Range.Last + 1;
1203 ctx->num_ubo++;
1204 } else {
1205 /* if we have a normal single const set then ubo base should be 1 */
1206 ctx->ubo_base = 1;
1207 if (decl->Range.Last) {
1208 if (decl->Range.Last + 1 > ctx->num_consts)
1209 ctx->num_consts = decl->Range.Last + 1;
1210 } else
1211 ctx->num_consts++;
1212 }
1213 break;
1214 case TGSI_FILE_ADDRESS:
1215 ctx->num_address = decl->Range.Last + 1;
1216 break;
1217 case TGSI_FILE_SYSTEM_VALUE:
1218 i = ctx->num_system_values++;
1219 if (ctx->num_system_values > ARRAY_SIZE(ctx->system_values)) {
1220 fprintf(stderr, "Number of system values exceeded, max is %lu\n", ARRAY_SIZE(ctx->system_values));
1221 return FALSE;
1222 }
1223
1224 ctx->system_values[i].name = decl->Semantic.Name;
1225 ctx->system_values[i].sid = decl->Semantic.Index;
1226 ctx->system_values[i].glsl_predefined_no_emit = true;
1227 ctx->system_values[i].glsl_no_index = true;
1228 ctx->system_values[i].override_no_wm = true;
1229 ctx->system_values[i].first = decl->Range.First;
1230 if (decl->Semantic.Name == TGSI_SEMANTIC_INSTANCEID) {
1231 name_prefix = "gl_InstanceID";
1232 ctx->shader_req_bits |= SHADER_REQ_INSTANCE_ID | SHADER_REQ_INTS;
1233 } else if (decl->Semantic.Name == TGSI_SEMANTIC_VERTEXID) {
1234 name_prefix = "gl_VertexID";
1235 ctx->shader_req_bits |= SHADER_REQ_INTS;
1236 } else if (decl->Semantic.Name == TGSI_SEMANTIC_HELPER_INVOCATION) {
1237 name_prefix = "gl_HelperInvocation";
1238 ctx->shader_req_bits |= SHADER_REQ_ES31_COMPAT;
1239 } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEID) {
1240 name_prefix = "gl_SampleID";
1241 ctx->shader_req_bits |= (SHADER_REQ_SAMPLE_SHADING | SHADER_REQ_INTS);
1242 } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEPOS) {
1243 name_prefix = "gl_SamplePosition";
1244 ctx->shader_req_bits |= SHADER_REQ_SAMPLE_SHADING;
1245 } else if (decl->Semantic.Name == TGSI_SEMANTIC_INVOCATIONID) {
1246 name_prefix = "gl_InvocationID";
1247 ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_GPU_SHADER5);
1248 } else if (decl->Semantic.Name == TGSI_SEMANTIC_SAMPLEMASK) {
1249 name_prefix = "gl_SampleMaskIn[0]";
1250 ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_GPU_SHADER5);
1251 } else if (decl->Semantic.Name == TGSI_SEMANTIC_PRIMID) {
1252 name_prefix = "gl_PrimitiveID";
1253 ctx->shader_req_bits |= (SHADER_REQ_INTS | SHADER_REQ_GPU_SHADER5);
1254 } else if (decl->Semantic.Name == TGSI_SEMANTIC_TESSCOORD) {
1255 name_prefix = "gl_TessCoord";
1256 ctx->system_values[i].override_no_wm = false;
1257 } else if (decl->Semantic.Name == TGSI_SEMANTIC_VERTICESIN) {
1258 ctx->shader_req_bits |= SHADER_REQ_INTS;
1259 name_prefix = "gl_PatchVerticesIn";
1260 } else if (decl->Semantic.Name == TGSI_SEMANTIC_TESSOUTER) {
1261 name_prefix = "gl_TessLevelOuter";
1262 } else if (decl->Semantic.Name == TGSI_SEMANTIC_TESSINNER) {
1263 name_prefix = "gl_TessLevelInner";
1264 } else if (decl->Semantic.Name == TGSI_SEMANTIC_THREAD_ID) {
1265 name_prefix = "gl_LocalInvocationID";
1266 ctx->system_values[i].override_no_wm = false;
1267 } else if (decl->Semantic.Name == TGSI_SEMANTIC_BLOCK_ID) {
1268 name_prefix = "gl_WorkGroupID";
1269 ctx->system_values[i].override_no_wm = false;
1270 } else if (decl->Semantic.Name == TGSI_SEMANTIC_GRID_SIZE) {
1271 name_prefix = "gl_NumWorkGroups";
1272 ctx->system_values[i].override_no_wm = false;
1273 } else {
1274 fprintf(stderr, "unsupported system value %d\n", decl->Semantic.Name);
1275 name_prefix = "unknown";
1276 }
1277 snprintf(ctx->system_values[i].glsl_name, 64, "%s", name_prefix);
1278 break;
1279 case TGSI_FILE_MEMORY:
1280 break;
1281 default:
1282 fprintf(stderr,"unsupported file %d declaration\n", decl->Declaration.File);
1283 break;
1284 }
1285
1286 return TRUE;
1287 }
1288
1289 static boolean
iter_property(struct tgsi_iterate_context * iter,struct tgsi_full_property * prop)1290 iter_property(struct tgsi_iterate_context *iter,
1291 struct tgsi_full_property *prop)
1292 {
1293 struct dump_ctx *ctx = (struct dump_ctx *) iter;
1294
1295 if (prop->Property.PropertyName == TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS) {
1296 if (prop->u[0].Data == 1)
1297 ctx->write_all_cbufs = true;
1298 }
1299
1300 if (prop->Property.PropertyName == TGSI_PROPERTY_FS_COORD_ORIGIN) {
1301 ctx->fs_coord_origin = prop->u[0].Data;
1302 }
1303
1304 if (prop->Property.PropertyName == TGSI_PROPERTY_FS_COORD_PIXEL_CENTER) {
1305 ctx->fs_pixel_center = prop->u[0].Data;
1306 }
1307
1308 if (prop->Property.PropertyName == TGSI_PROPERTY_GS_INPUT_PRIM) {
1309 ctx->gs_in_prim = prop->u[0].Data;
1310 }
1311
1312 if (prop->Property.PropertyName == TGSI_PROPERTY_GS_OUTPUT_PRIM) {
1313 ctx->gs_out_prim = prop->u[0].Data;
1314 }
1315
1316 if (prop->Property.PropertyName == TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES) {
1317 ctx->gs_max_out_verts = prop->u[0].Data;
1318 }
1319
1320 if (prop->Property.PropertyName == TGSI_PROPERTY_GS_INVOCATIONS) {
1321 ctx->gs_num_invocations = prop->u[0].Data;
1322 }
1323
1324 if (prop->Property.PropertyName == TGSI_PROPERTY_NUM_CLIPDIST_ENABLED) {
1325 ctx->num_clip_dist_prop = prop->u[0].Data;
1326 }
1327
1328 if (prop->Property.PropertyName == TGSI_PROPERTY_NUM_CULLDIST_ENABLED) {
1329 ctx->num_cull_dist_prop = prop->u[0].Data;
1330 }
1331
1332 if (prop->Property.PropertyName == TGSI_PROPERTY_TCS_VERTICES_OUT) {
1333 ctx->tcs_vertices_out = prop->u[0].Data;
1334 }
1335
1336 if (prop->Property.PropertyName == TGSI_PROPERTY_TES_PRIM_MODE) {
1337 ctx->tes_prim_mode = prop->u[0].Data;
1338 }
1339
1340 if (prop->Property.PropertyName == TGSI_PROPERTY_TES_SPACING) {
1341 ctx->tes_spacing = prop->u[0].Data;
1342 }
1343
1344 if (prop->Property.PropertyName == TGSI_PROPERTY_TES_VERTEX_ORDER_CW) {
1345 ctx->tes_vertex_order = prop->u[0].Data;
1346 }
1347
1348 if (prop->Property.PropertyName == TGSI_PROPERTY_TES_POINT_MODE) {
1349 ctx->tes_point_mode = prop->u[0].Data;
1350 }
1351
1352 if (prop->Property.PropertyName == TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL) {
1353 ctx->early_depth_stencil = prop->u[0].Data > 0;
1354 if (ctx->early_depth_stencil) {
1355 require_glsl_ver(ctx, 150);
1356 ctx->shader_req_bits |= SHADER_REQ_IMAGE_LOAD_STORE;
1357 }
1358 }
1359
1360 if (prop->Property.PropertyName == TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH)
1361 ctx->local_cs_block_size[0] = prop->u[0].Data;
1362 if (prop->Property.PropertyName == TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT)
1363 ctx->local_cs_block_size[1] = prop->u[0].Data;
1364 if (prop->Property.PropertyName == TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH)
1365 ctx->local_cs_block_size[2] = prop->u[0].Data;
1366 return TRUE;
1367 }
1368
1369 static boolean
iter_immediate(struct tgsi_iterate_context * iter,struct tgsi_full_immediate * imm)1370 iter_immediate(
1371 struct tgsi_iterate_context *iter,
1372 struct tgsi_full_immediate *imm )
1373 {
1374 struct dump_ctx *ctx = (struct dump_ctx *) iter;
1375 int i;
1376 uint32_t first = ctx->num_imm;
1377
1378 if (first >= ARRAY_SIZE(ctx->imm)) {
1379 fprintf(stderr, "Number of immediates exceeded, max is: %lu\n", ARRAY_SIZE(ctx->imm));
1380 return FALSE;
1381 }
1382
1383 ctx->imm[first].type = imm->Immediate.DataType;
1384 for (i = 0; i < 4; i++) {
1385 if (imm->Immediate.DataType == TGSI_IMM_FLOAT32) {
1386 ctx->imm[first].val[i].f = imm->u[i].Float;
1387 } else if (imm->Immediate.DataType == TGSI_IMM_UINT32 ||
1388 imm->Immediate.DataType == TGSI_IMM_FLOAT64) {
1389 ctx->shader_req_bits |= SHADER_REQ_INTS;
1390 ctx->imm[first].val[i].ui = imm->u[i].Uint;
1391 } else if (imm->Immediate.DataType == TGSI_IMM_INT32) {
1392 ctx->shader_req_bits |= SHADER_REQ_INTS;
1393 ctx->imm[first].val[i].i = imm->u[i].Int;
1394 }
1395 }
1396 ctx->num_imm++;
1397 return TRUE;
1398 }
1399
get_swiz_char(int swiz)1400 static char get_swiz_char(int swiz)
1401 {
1402 switch(swiz){
1403 case TGSI_SWIZZLE_X: return 'x';
1404 case TGSI_SWIZZLE_Y: return 'y';
1405 case TGSI_SWIZZLE_Z: return 'z';
1406 case TGSI_SWIZZLE_W: return 'w';
1407 default: return 0;
1408 }
1409 }
1410
emit_cbuf_writes(struct dump_ctx * ctx)1411 static int emit_cbuf_writes(struct dump_ctx *ctx)
1412 {
1413 char buf[255];
1414 int i;
1415 char *sret;
1416
1417 for (i = ctx->num_outputs; i < ctx->cfg->max_draw_buffers; i++) {
1418 snprintf(buf, 255, "fsout_c%d = fsout_c0;\n", i);
1419 sret = add_str_to_glsl_main(ctx, buf);
1420 if (!sret)
1421 return ENOMEM;
1422 }
1423 return 0;
1424 }
1425
emit_a8_swizzle(struct dump_ctx * ctx)1426 static int emit_a8_swizzle(struct dump_ctx *ctx)
1427 {
1428 char buf[255];
1429 char *sret;
1430 snprintf(buf, 255, "fsout_c0.x = fsout_c0.w;\n");
1431 sret = add_str_to_glsl_main(ctx, buf);
1432 if (!sret)
1433 return ENOMEM;
1434 return 0;
1435 }
1436
1437 static const char *atests[PIPE_FUNC_ALWAYS + 1] = {
1438 "false",
1439 "<",
1440 "==",
1441 "<=",
1442 ">",
1443 "!=",
1444 ">=",
1445 "true"
1446 };
1447
emit_alpha_test(struct dump_ctx * ctx)1448 static int emit_alpha_test(struct dump_ctx *ctx)
1449 {
1450 char buf[255];
1451 char comp_buf[128];
1452 char *sret;
1453
1454 if (!ctx->num_outputs)
1455 return 0;
1456
1457 if (!ctx->write_all_cbufs) {
1458 /* only emit alpha stanza if first output is 0 */
1459 if (ctx->outputs[0].sid != 0)
1460 return 0;
1461 }
1462 switch (ctx->key->alpha_test) {
1463 case PIPE_FUNC_NEVER:
1464 case PIPE_FUNC_ALWAYS:
1465 snprintf(comp_buf, 128, "%s", atests[ctx->key->alpha_test]);
1466 break;
1467 case PIPE_FUNC_LESS:
1468 case PIPE_FUNC_EQUAL:
1469 case PIPE_FUNC_LEQUAL:
1470 case PIPE_FUNC_GREATER:
1471 case PIPE_FUNC_NOTEQUAL:
1472 case PIPE_FUNC_GEQUAL:
1473 snprintf(comp_buf, 128, "%s %s %f", "fsout_c0.w", atests[ctx->key->alpha_test], ctx->key->alpha_ref_val);
1474 break;
1475 default:
1476 fprintf(stderr, "invalid alpha-test: %x\n", ctx->key->alpha_test);
1477 return EINVAL;
1478 }
1479
1480 snprintf(buf, 255, "if (!(%s)) {\n\tdiscard;\n}\n", comp_buf);
1481 sret = add_str_to_glsl_main(ctx, buf);
1482 if (!sret)
1483 return ENOMEM;
1484 return 0;
1485 }
1486
emit_pstipple_pass(struct dump_ctx * ctx)1487 static int emit_pstipple_pass(struct dump_ctx *ctx)
1488 {
1489 char buf[255];
1490 char *sret;
1491 snprintf(buf, 255, "stip_temp = texture(pstipple_sampler, vec2(gl_FragCoord.x / 32, gl_FragCoord.y / 32)).x;\n");
1492 sret = add_str_to_glsl_main(ctx, buf);
1493 if (!sret)
1494 return ENOMEM;
1495 snprintf(buf, 255, "if (stip_temp > 0) {\n\tdiscard;\n}\n");
1496 sret = add_str_to_glsl_main(ctx, buf);
1497 return sret ? 0 : ENOMEM;
1498 }
1499
emit_color_select(struct dump_ctx * ctx)1500 static int emit_color_select(struct dump_ctx *ctx)
1501 {
1502 char buf[255];
1503 char *sret = NULL;
1504
1505 if (!ctx->key->color_two_side || !(ctx->color_in_mask & 0x3))
1506 return 0;
1507
1508 if (ctx->color_in_mask & 1) {
1509 snprintf(buf, 255, "realcolor0 = gl_FrontFacing ? ex_c0 : ex_bc0;\n");
1510 sret = add_str_to_glsl_main(ctx, buf);
1511 }
1512 if (ctx->color_in_mask & 2) {
1513 snprintf(buf, 255, "realcolor1 = gl_FrontFacing ? ex_c1 : ex_bc1;\n");
1514 sret = add_str_to_glsl_main(ctx, buf);
1515 }
1516 return sret ? 0 : ENOMEM;
1517 }
1518
emit_prescale(struct dump_ctx * ctx)1519 static int emit_prescale(struct dump_ctx *ctx)
1520 {
1521 char buf[255];
1522 char *sret;
1523
1524 snprintf(buf, 255, "gl_Position.y = gl_Position.y * winsys_adjust_y;\n");
1525 sret = add_str_to_glsl_main(ctx, buf);
1526 if (!sret)
1527 return ENOMEM;
1528 return 0;
1529 }
1530
prepare_so_movs(struct dump_ctx * ctx)1531 static int prepare_so_movs(struct dump_ctx *ctx)
1532 {
1533 uint32_t i;
1534 for (i = 0; i < ctx->so->num_outputs; i++) {
1535 ctx->write_so_outputs[i] = true;
1536 if (ctx->so->output[i].start_component != 0)
1537 continue;
1538 if (ctx->so->output[i].num_components != 4)
1539 continue;
1540 if (ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_CLIPDIST)
1541 continue;
1542 if (ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_POSITION)
1543 continue;
1544
1545 ctx->outputs[ctx->so->output[i].register_index].stream = ctx->so->output[i].stream;
1546 if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY && ctx->so->output[i].stream)
1547 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
1548
1549 ctx->write_so_outputs[i] = false;
1550 }
1551 return 0;
1552 }
1553
emit_so_movs(struct dump_ctx * ctx)1554 static int emit_so_movs(struct dump_ctx *ctx)
1555 {
1556 char buf[255];
1557 uint32_t i, j;
1558 char outtype[15] = {0};
1559 char writemask[6];
1560 char *sret;
1561
1562 if (ctx->so->num_outputs >= PIPE_MAX_SO_OUTPUTS) {
1563 fprintf(stderr, "Num outputs exceeded, max is %u\n", PIPE_MAX_SO_OUTPUTS);
1564 return EINVAL;
1565 }
1566
1567 for (i = 0; i < ctx->so->num_outputs; i++) {
1568 if (ctx->so->output[i].start_component != 0) {
1569 int wm_idx = 0;
1570 writemask[wm_idx++] = '.';
1571 for (j = 0; j < ctx->so->output[i].num_components; j++) {
1572 unsigned idx = ctx->so->output[i].start_component + j;
1573 if (idx >= 4)
1574 break;
1575 if (idx <= 2)
1576 writemask[wm_idx++] = 'x' + idx;
1577 else
1578 writemask[wm_idx++] = 'w';
1579 }
1580 writemask[wm_idx] = '\0';
1581 } else
1582 writemask[0] = 0;
1583
1584 if (!ctx->write_so_outputs[i]) {
1585 if (ctx->so->output[i].register_index > ctx->num_outputs)
1586 ctx->so_names[i] = NULL;
1587 else if (ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_CLIPVERTEX && ctx->has_clipvertex) {
1588 ctx->so_names[i] = strdup("clipv_tmp");
1589 ctx->has_clipvertex_so = true;
1590 } else
1591 ctx->so_names[i] = strdup(ctx->outputs[ctx->so->output[i].register_index].glsl_name);
1592 } else {
1593 char ntemp[8];
1594 snprintf(ntemp, 8, "tfout%d", i);
1595 ctx->so_names[i] = strdup(ntemp);
1596 }
1597 if (ctx->so->output[i].num_components == 1) {
1598 if (ctx->outputs[ctx->so->output[i].register_index].is_int)
1599 snprintf(outtype, 15, "intBitsToFloat");
1600 else
1601 snprintf(outtype, 15, "float");
1602 } else
1603 snprintf(outtype, 15, "vec%d", ctx->so->output[i].num_components);
1604
1605 if (ctx->so->output[i].register_index >= 255)
1606 continue;
1607
1608 buf[0] = 0;
1609 if (ctx->outputs[ctx->so->output[i].register_index].name == TGSI_SEMANTIC_CLIPDIST) {
1610 snprintf(buf, 255, "tfout%d = %s(clip_dist_temp[%d]%s);\n", i, outtype, ctx->outputs[ctx->so->output[i].register_index].sid,
1611 writemask);
1612 } else {
1613 if (ctx->write_so_outputs[i])
1614 snprintf(buf, 255, "tfout%d = %s(%s%s);\n", i, outtype, ctx->outputs[ctx->so->output[i].register_index].glsl_name, writemask);
1615 }
1616 sret = add_str_to_glsl_main(ctx, buf);
1617 if (!sret)
1618 return ENOMEM;
1619 }
1620 return 0;
1621 }
1622
emit_clip_dist_movs(struct dump_ctx * ctx)1623 static int emit_clip_dist_movs(struct dump_ctx *ctx)
1624 {
1625 char buf[255];
1626 int i;
1627 char *sret;
1628 bool has_prop = (ctx->num_clip_dist_prop + ctx->num_cull_dist_prop) > 0;
1629 int ndists;
1630 const char *prefix="";
1631
1632 if (ctx->prog_type == PIPE_SHADER_TESS_CTRL)
1633 prefix = "gl_out[gl_InvocationID].";
1634 if (ctx->num_clip_dist == 0 && ctx->key->clip_plane_enable) {
1635 for (i = 0; i < 8; i++) {
1636 snprintf(buf, 255, "%sgl_ClipDistance[%d] = dot(%s, clipp[%d]);\n", prefix, i, ctx->has_clipvertex ? "clipv_tmp" : "gl_Position", i);
1637 sret = add_str_to_glsl_main(ctx, buf);
1638 if (!sret)
1639 return ENOMEM;
1640 }
1641 return 0;
1642 }
1643 ndists = ctx->num_clip_dist;
1644 if (has_prop)
1645 ndists = ctx->num_clip_dist_prop + ctx->num_cull_dist_prop;
1646 for (i = 0; i < ndists; i++) {
1647 int clipidx = i < 4 ? 0 : 1;
1648 char swiz = i & 3;
1649 char wm = 0;
1650 switch (swiz) {
1651 case 0: wm = 'x'; break;
1652 case 1: wm = 'y'; break;
1653 case 2: wm = 'z'; break;
1654 case 3: wm = 'w'; break;
1655 default:
1656 return EINVAL;
1657 }
1658 bool is_cull = false;
1659 if (has_prop) {
1660 if (i >= ctx->num_clip_dist_prop && i < ctx->num_clip_dist_prop + ctx->num_cull_dist_prop)
1661 is_cull = true;
1662 }
1663 const char *clip_cull = is_cull ? "Cull" : "Clip";
1664 snprintf(buf, 255, "%sgl_%sDistance[%d] = clip_dist_temp[%d].%c;\n", prefix, clip_cull,
1665 is_cull ? i - ctx->num_clip_dist_prop : i, clipidx, wm);
1666 sret = add_str_to_glsl_main(ctx, buf);
1667 if (!sret)
1668 return ENOMEM;
1669 }
1670 return 0;
1671 }
1672
1673 #define emit_arit_op2(op) snprintf(buf, 255, "%s = %s(%s((%s %s %s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], op, srcs[1], writemask)
1674 #define emit_op1(op) snprintf(buf, 255, "%s = %s(%s(%s(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), op, srcs[0], writemask)
1675 #define emit_compare(op) snprintf(buf, 255, "%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)
1676
1677 #define emit_ucompare(op) snprintf(buf, 255, "%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))
1678
emit_buf(struct dump_ctx * ctx,const char * buf)1679 static int emit_buf(struct dump_ctx *ctx, const char *buf)
1680 {
1681 int i;
1682 char *sret;
1683 for (i = 0; i < ctx->indent_level; i++) {
1684 sret = add_str_to_glsl_main(ctx, "\t");
1685 if (!sret)
1686 return ENOMEM;
1687 }
1688
1689 sret = add_str_to_glsl_main(ctx, buf);
1690 return sret ? 0 : ENOMEM;
1691 }
1692
1693 #define EMIT_BUF_WITH_RET(ctx, buf) do { \
1694 int _ret = emit_buf((ctx), (buf)); \
1695 if (_ret) return FALSE; \
1696 } while(0)
1697
handle_vertex_proc_exit(struct dump_ctx * ctx)1698 static int handle_vertex_proc_exit(struct dump_ctx *ctx)
1699 {
1700 if (ctx->so && !ctx->key->gs_present && !ctx->key->tes_present) {
1701 if (emit_so_movs(ctx))
1702 return FALSE;
1703 }
1704
1705 if (emit_clip_dist_movs(ctx))
1706 return FALSE;
1707
1708 if (!ctx->key->gs_present && !ctx->key->tes_present) {
1709 if (emit_prescale(ctx))
1710 return FALSE;
1711 }
1712
1713 return TRUE;
1714 }
1715
handle_fragment_proc_exit(struct dump_ctx * ctx)1716 static int handle_fragment_proc_exit(struct dump_ctx *ctx)
1717 {
1718 if (ctx->key->pstipple_tex) {
1719 if (emit_pstipple_pass(ctx))
1720 return FALSE;
1721 }
1722
1723 if (ctx->key->cbufs_are_a8_bitmask) {
1724 if (emit_a8_swizzle(ctx))
1725 return FALSE;
1726 }
1727
1728 if (ctx->key->add_alpha_test) {
1729 if (emit_alpha_test(ctx))
1730 return FALSE;
1731 }
1732
1733 if (ctx->write_all_cbufs) {
1734 if (emit_cbuf_writes(ctx))
1735 return FALSE;
1736 }
1737
1738 return TRUE;
1739 }
1740
set_texture_reqs(struct dump_ctx * ctx,struct tgsi_full_instruction * inst,uint32_t sreg_index,bool * is_shad)1741 static bool set_texture_reqs(struct dump_ctx *ctx,
1742 struct tgsi_full_instruction *inst,
1743 uint32_t sreg_index,
1744 bool *is_shad)
1745 {
1746 if (sreg_index >= ARRAY_SIZE(ctx->samplers)) {
1747 fprintf(stderr, "Sampler view exceeded, max is %lu\n", ARRAY_SIZE(ctx->samplers));
1748 return false;
1749 }
1750 ctx->samplers[sreg_index].tgsi_sampler_type = inst->Texture.Texture;
1751
1752 switch (inst->Texture.Texture) {
1753 case TGSI_TEXTURE_1D:
1754 case TGSI_TEXTURE_2D:
1755 case TGSI_TEXTURE_3D:
1756 case TGSI_TEXTURE_CUBE:
1757 case TGSI_TEXTURE_1D_ARRAY:
1758 case TGSI_TEXTURE_2D_ARRAY:
1759 break;
1760 case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
1761 *is_shad = true;
1762 /* fallthrough */
1763 case TGSI_TEXTURE_CUBE_ARRAY:
1764 ctx->shader_req_bits |= SHADER_REQ_CUBE_ARRAY;
1765 break;
1766 case TGSI_TEXTURE_2D_MSAA:
1767 case TGSI_TEXTURE_2D_ARRAY_MSAA:
1768 ctx->shader_req_bits |= SHADER_REQ_SAMPLER_MS;
1769 break;
1770 case TGSI_TEXTURE_BUFFER:
1771 ctx->uses_sampler_buf = true;
1772 break;
1773 case TGSI_TEXTURE_SHADOWRECT:
1774 *is_shad = true;
1775 /* fallthrough */
1776 case TGSI_TEXTURE_RECT:
1777 ctx->shader_req_bits |= SHADER_REQ_SAMPLER_RECT;
1778 break;
1779 case TGSI_TEXTURE_SHADOW1D:
1780 case TGSI_TEXTURE_SHADOW2D:
1781 case TGSI_TEXTURE_SHADOWCUBE:
1782 case TGSI_TEXTURE_SHADOW1D_ARRAY:
1783 case TGSI_TEXTURE_SHADOW2D_ARRAY:
1784 *is_shad = true;
1785 break;
1786 default:
1787 fprintf(stderr, "unhandled texture: %x\n", inst->Texture.Texture);
1788 return false;
1789 }
1790
1791 if (ctx->cfg->glsl_version >= 140)
1792 if ((ctx->shader_req_bits & SHADER_REQ_SAMPLER_RECT) || ctx->uses_sampler_buf)
1793 require_glsl_ver(ctx, 140);
1794
1795 return true;
1796 }
1797
1798 /* size queries are pretty much separate */
emit_txq(struct dump_ctx * ctx,struct tgsi_full_instruction * inst,uint32_t sreg_index,char srcs[4][255],char dsts[3][255],const char * writemask)1799 static int emit_txq(struct dump_ctx *ctx,
1800 struct tgsi_full_instruction *inst,
1801 uint32_t sreg_index,
1802 char srcs[4][255],
1803 char dsts[3][255],
1804 const char *writemask)
1805 {
1806 unsigned twm = TGSI_WRITEMASK_NONE;
1807 char bias[128] = {0};
1808 char buf[512];
1809 const int sampler_index = 1;
1810 bool is_shad;
1811 enum vrend_type_qualifier dtypeprefix = INT_BITS_TO_FLOAT;
1812
1813 if (set_texture_reqs(ctx, inst, sreg_index, &is_shad) == false)
1814 return FALSE;
1815
1816 /* no lod parameter for txq for these */
1817 if (inst->Texture.Texture != TGSI_TEXTURE_RECT &&
1818 inst->Texture.Texture != TGSI_TEXTURE_SHADOWRECT &&
1819 inst->Texture.Texture != TGSI_TEXTURE_BUFFER &&
1820 inst->Texture.Texture != TGSI_TEXTURE_2D_MSAA &&
1821 inst->Texture.Texture != TGSI_TEXTURE_2D_ARRAY_MSAA)
1822 snprintf(bias, 128, ", int(%s.w)", srcs[0]);
1823
1824 /* need to emit a textureQueryLevels */
1825 if (inst->Dst[0].Register.WriteMask & 0x8) {
1826
1827 if (inst->Texture.Texture != TGSI_TEXTURE_BUFFER &&
1828 inst->Texture.Texture != TGSI_TEXTURE_RECT &&
1829 inst->Texture.Texture != TGSI_TEXTURE_2D_MSAA &&
1830 inst->Texture.Texture != TGSI_TEXTURE_2D_ARRAY_MSAA) {
1831 ctx->shader_req_bits |= SHADER_REQ_TXQ_LEVELS;
1832 if (inst->Dst[0].Register.WriteMask & 0x7)
1833 twm = TGSI_WRITEMASK_W;
1834 snprintf(buf, 255, "%s%s = %s(textureQueryLevels(%s));\n", dsts[0], get_wm_string(twm), get_string(dtypeprefix), srcs[sampler_index]);
1835 EMIT_BUF_WITH_RET(ctx, buf);
1836 }
1837
1838 if (inst->Dst[0].Register.WriteMask & 0x7) {
1839 switch (inst->Texture.Texture) {
1840 case TGSI_TEXTURE_1D:
1841 case TGSI_TEXTURE_BUFFER:
1842 case TGSI_TEXTURE_SHADOW1D:
1843 twm = TGSI_WRITEMASK_X;
1844 break;
1845 case TGSI_TEXTURE_1D_ARRAY:
1846 case TGSI_TEXTURE_SHADOW1D_ARRAY:
1847 case TGSI_TEXTURE_2D:
1848 case TGSI_TEXTURE_SHADOW2D:
1849 case TGSI_TEXTURE_RECT:
1850 case TGSI_TEXTURE_SHADOWRECT:
1851 case TGSI_TEXTURE_CUBE:
1852 case TGSI_TEXTURE_SHADOWCUBE:
1853 case TGSI_TEXTURE_2D_MSAA:
1854 twm = TGSI_WRITEMASK_XY;
1855 break;
1856 case TGSI_TEXTURE_3D:
1857 case TGSI_TEXTURE_2D_ARRAY:
1858 case TGSI_TEXTURE_SHADOW2D_ARRAY:
1859 case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
1860 case TGSI_TEXTURE_CUBE_ARRAY:
1861 case TGSI_TEXTURE_2D_ARRAY_MSAA:
1862 twm = TGSI_WRITEMASK_XYZ;
1863 break;
1864 }
1865 }
1866 }
1867
1868 if (inst->Dst[0].Register.WriteMask & 0x7) {
1869 snprintf(buf, 255, "%s%s = %s(textureSize(%s%s))%s;\n", dsts[0], get_wm_string(twm), get_string(dtypeprefix), srcs[sampler_index], bias, util_bitcount(inst->Dst[0].Register.WriteMask) > 1 ? writemask : "");
1870 EMIT_BUF_WITH_RET(ctx, buf);
1871 }
1872 return 0;
1873 }
1874
1875 /* sample queries are pretty much separate */
emit_txqs(struct dump_ctx * ctx,struct tgsi_full_instruction * inst,uint32_t sreg_index,char srcs[4][255],char dsts[3][255])1876 static int emit_txqs(struct dump_ctx *ctx,
1877 struct tgsi_full_instruction *inst,
1878 uint32_t sreg_index,
1879 char srcs[4][255],
1880 char dsts[3][255])
1881 {
1882 char buf[512];
1883 const int sampler_index = 0;
1884 bool is_shad;
1885 enum vrend_type_qualifier dtypeprefix = INT_BITS_TO_FLOAT;
1886
1887 ctx->shader_req_bits |= SHADER_REQ_TXQS;
1888 if (set_texture_reqs(ctx, inst, sreg_index, &is_shad) == false)
1889 return FALSE;
1890
1891 if (inst->Texture.Texture != TGSI_TEXTURE_2D_MSAA &&
1892 inst->Texture.Texture != TGSI_TEXTURE_2D_ARRAY_MSAA)
1893 return FALSE;
1894
1895 snprintf(buf, 255, "%s = %s(textureSamples(%s));\n", dsts[0],
1896 get_string(dtypeprefix), srcs[sampler_index]);
1897 EMIT_BUF_WITH_RET(ctx, buf);
1898 return 0;
1899 }
1900
get_tex_inst_ext(struct tgsi_full_instruction * inst)1901 static const char *get_tex_inst_ext(struct tgsi_full_instruction *inst)
1902 {
1903 const char *tex_ext = "";
1904 if (inst->Instruction.Opcode == TGSI_OPCODE_LODQ) {
1905 tex_ext = "QueryLOD";
1906 } else if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) {
1907 if (inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
1908 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY ||
1909 inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY)
1910 tex_ext = "";
1911 else if (inst->Texture.NumOffsets == 1)
1912 tex_ext = "ProjOffset";
1913 else
1914 tex_ext = "Proj";
1915 } else if (inst->Instruction.Opcode == TGSI_OPCODE_TXL ||
1916 inst->Instruction.Opcode == TGSI_OPCODE_TXL2) {
1917 if (inst->Texture.NumOffsets == 1)
1918 tex_ext = "LodOffset";
1919 else
1920 tex_ext = "Lod";
1921 } else if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) {
1922 if (inst->Texture.NumOffsets == 1)
1923 tex_ext = "GradOffset";
1924 else
1925 tex_ext = "Grad";
1926 } else if (inst->Instruction.Opcode == TGSI_OPCODE_TG4) {
1927 if (inst->Texture.NumOffsets == 4)
1928 tex_ext = "GatherOffsets";
1929 else if (inst->Texture.NumOffsets == 1)
1930 tex_ext = "GatherOffset";
1931 else
1932 tex_ext = "Gather";
1933 } else {
1934 if (inst->Texture.NumOffsets == 1)
1935 tex_ext = "Offset";
1936 else
1937 tex_ext = "";
1938 }
1939 return tex_ext;
1940 }
1941
fill_offset_buffer(struct dump_ctx * ctx,struct tgsi_full_instruction * inst,char * offbuf)1942 static bool fill_offset_buffer(struct dump_ctx *ctx,
1943 struct tgsi_full_instruction *inst,
1944 char *offbuf)
1945 {
1946 if (inst->TexOffsets[0].File == TGSI_FILE_IMMEDIATE) {
1947 struct immed *imd = &ctx->imm[inst->TexOffsets[0].Index];
1948 switch (inst->Texture.Texture) {
1949 case TGSI_TEXTURE_1D:
1950 case TGSI_TEXTURE_1D_ARRAY:
1951 case TGSI_TEXTURE_SHADOW1D:
1952 case TGSI_TEXTURE_SHADOW1D_ARRAY:
1953 snprintf(offbuf, 25, ", int(%d)", imd->val[inst->TexOffsets[0].SwizzleX].i);
1954 break;
1955 case TGSI_TEXTURE_RECT:
1956 case TGSI_TEXTURE_SHADOWRECT:
1957 case TGSI_TEXTURE_2D:
1958 case TGSI_TEXTURE_2D_ARRAY:
1959 case TGSI_TEXTURE_SHADOW2D:
1960 case TGSI_TEXTURE_SHADOW2D_ARRAY:
1961 snprintf(offbuf, 25, ", ivec2(%d, %d)", imd->val[inst->TexOffsets[0].SwizzleX].i, imd->val[inst->TexOffsets[0].SwizzleY].i);
1962 break;
1963 case TGSI_TEXTURE_3D:
1964 snprintf(offbuf, 25, ", ivec3(%d, %d, %d)", imd->val[inst->TexOffsets[0].SwizzleX].i, imd->val[inst->TexOffsets[0].SwizzleY].i,
1965 imd->val[inst->TexOffsets[0].SwizzleZ].i);
1966 break;
1967 default:
1968 fprintf(stderr, "unhandled texture: %x\n", inst->Texture.Texture);
1969 return false;
1970 }
1971 } else if (inst->TexOffsets[0].File == TGSI_FILE_TEMPORARY) {
1972 struct vrend_temp_range *range = find_temp_range(ctx, inst->TexOffsets[0].Index);
1973 int idx = inst->TexOffsets[0].Index - range->first;
1974 switch (inst->Texture.Texture) {
1975 case TGSI_TEXTURE_1D:
1976 case TGSI_TEXTURE_1D_ARRAY:
1977 case TGSI_TEXTURE_SHADOW1D:
1978 case TGSI_TEXTURE_SHADOW1D_ARRAY:
1979 snprintf(offbuf, 120, ", int(floatBitsToInt(temp%d[%d].%c))",
1980 range->first, idx,
1981 get_swiz_char(inst->TexOffsets[0].SwizzleX));
1982 break;
1983 case TGSI_TEXTURE_RECT:
1984 case TGSI_TEXTURE_SHADOWRECT:
1985 case TGSI_TEXTURE_2D:
1986 case TGSI_TEXTURE_2D_ARRAY:
1987 case TGSI_TEXTURE_SHADOW2D:
1988 case TGSI_TEXTURE_SHADOW2D_ARRAY:
1989 snprintf(offbuf, 120, ", ivec2(floatBitsToInt(temp%d[%d].%c), floatBitsToInt(temp%d[%d].%c))",
1990 range->first, idx,
1991 get_swiz_char(inst->TexOffsets[0].SwizzleX),
1992 range->first, idx,
1993 get_swiz_char(inst->TexOffsets[0].SwizzleY));
1994 break;
1995 case TGSI_TEXTURE_3D:
1996 snprintf(offbuf, 120, ", ivec3(floatBitsToInt(temp%d[%d].%c), floatBitsToInt(temp%d[%d].%c), floatBitsToInt(temp%d[%d].%c)",
1997 range->first, idx,
1998 get_swiz_char(inst->TexOffsets[0].SwizzleX),
1999 range->first, idx,
2000 get_swiz_char(inst->TexOffsets[0].SwizzleY),
2001 range->first, idx,
2002 get_swiz_char(inst->TexOffsets[0].SwizzleZ));
2003 break;
2004 default:
2005 fprintf(stderr, "unhandled texture: %x\n", inst->Texture.Texture);
2006 return false;
2007 break;
2008 }
2009 } else if (inst->TexOffsets[0].File == TGSI_FILE_INPUT) {
2010 for (uint32_t j = 0; j < ctx->num_inputs; j++) {
2011 if (ctx->inputs[j].first != inst->TexOffsets[0].Index)
2012 continue;
2013 switch (inst->Texture.Texture) {
2014 case TGSI_TEXTURE_1D:
2015 case TGSI_TEXTURE_1D_ARRAY:
2016 case TGSI_TEXTURE_SHADOW1D:
2017 case TGSI_TEXTURE_SHADOW1D_ARRAY:
2018 snprintf(offbuf, 120, ", int(floatBitsToInt(%s.%c))",
2019 ctx->inputs[j].glsl_name,
2020 get_swiz_char(inst->TexOffsets[0].SwizzleX));
2021 break;
2022 case TGSI_TEXTURE_RECT:
2023 case TGSI_TEXTURE_SHADOWRECT:
2024 case TGSI_TEXTURE_2D:
2025 case TGSI_TEXTURE_2D_ARRAY:
2026 case TGSI_TEXTURE_SHADOW2D:
2027 case TGSI_TEXTURE_SHADOW2D_ARRAY:
2028 snprintf(offbuf, 120, ", ivec2(floatBitsToInt(%s.%c), floatBitsToInt(%s.%c))",
2029 ctx->inputs[j].glsl_name,
2030 get_swiz_char(inst->TexOffsets[0].SwizzleX),
2031 ctx->inputs[j].glsl_name,
2032 get_swiz_char(inst->TexOffsets[0].SwizzleY));
2033 break;
2034 case TGSI_TEXTURE_3D:
2035 snprintf(offbuf, 120, ", ivec3(floatBitsToInt(%s.%c), floatBitsToInt(%s.%c), floatBitsToInt(%s.%c)",
2036 ctx->inputs[j].glsl_name,
2037 get_swiz_char(inst->TexOffsets[0].SwizzleX),
2038 ctx->inputs[j].glsl_name,
2039 get_swiz_char(inst->TexOffsets[0].SwizzleY),
2040 ctx->inputs[j].glsl_name,
2041 get_swiz_char(inst->TexOffsets[0].SwizzleZ));
2042 break;
2043 default:
2044 fprintf(stderr, "unhandled texture: %x\n", inst->Texture.Texture);
2045 return false;
2046 break;
2047 }
2048 }
2049 }
2050 return true;
2051 }
2052
translate_tex(struct dump_ctx * ctx,struct tgsi_full_instruction * inst,struct source_info * sinfo,struct dest_info * dinfo,char srcs[4][255],char dsts[3][255],const char * writemask)2053 static int translate_tex(struct dump_ctx *ctx,
2054 struct tgsi_full_instruction *inst,
2055 struct source_info *sinfo,
2056 struct dest_info *dinfo,
2057 char srcs[4][255],
2058 char dsts[3][255],
2059 const char *writemask)
2060 {
2061 enum vrend_type_qualifier txfi = TYPE_CONVERSION_NONE;
2062 unsigned twm = TGSI_WRITEMASK_NONE, gwm = TGSI_WRITEMASK_NONE;
2063 enum vrend_type_qualifier dtypeprefix = TYPE_CONVERSION_NONE;
2064 bool is_shad = false;
2065 char buf[512];
2066 char offbuf[128] = {0};
2067 char bias[128] = {0};
2068 int sampler_index;
2069 const char *tex_ext;
2070
2071 if (set_texture_reqs(ctx, inst, sinfo->sreg_index, &is_shad) == false)
2072 return FALSE;
2073
2074 switch (ctx->samplers[sinfo->sreg_index].tgsi_sampler_return) {
2075 case TGSI_RETURN_TYPE_SINT:
2076 /* if dstconv isn't an int */
2077 if (dinfo->dstconv != INT)
2078 dtypeprefix = INT_BITS_TO_FLOAT;
2079 break;
2080 case TGSI_RETURN_TYPE_UINT:
2081 /* if dstconv isn't an int */
2082 if (dinfo->dstconv != INT)
2083 dtypeprefix = UINT_BITS_TO_FLOAT;
2084 break;
2085 default:
2086 break;
2087 }
2088
2089 sampler_index = 1;
2090
2091 if (inst->Instruction.Opcode == TGSI_OPCODE_LODQ)
2092 ctx->shader_req_bits |= SHADER_REQ_LODQ;
2093
2094 switch (inst->Texture.Texture) {
2095 case TGSI_TEXTURE_1D:
2096 case TGSI_TEXTURE_BUFFER:
2097 if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
2098 twm = TGSI_WRITEMASK_NONE;
2099 else
2100 twm = TGSI_WRITEMASK_X;
2101 txfi = INT;
2102 break;
2103 case TGSI_TEXTURE_1D_ARRAY:
2104 twm = TGSI_WRITEMASK_XY;
2105 txfi = IVEC2;
2106 break;
2107 case TGSI_TEXTURE_2D:
2108 case TGSI_TEXTURE_RECT:
2109 if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
2110 twm = TGSI_WRITEMASK_NONE;
2111 else
2112 twm = TGSI_WRITEMASK_XY;
2113 txfi = IVEC2;
2114 break;
2115 case TGSI_TEXTURE_SHADOW1D:
2116 case TGSI_TEXTURE_SHADOW2D:
2117 case TGSI_TEXTURE_SHADOW1D_ARRAY:
2118 case TGSI_TEXTURE_SHADOWRECT:
2119 case TGSI_TEXTURE_3D:
2120 if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
2121 twm = TGSI_WRITEMASK_NONE;
2122 else if (inst->Instruction.Opcode == TGSI_OPCODE_TG4)
2123 twm = TGSI_WRITEMASK_XY;
2124 else
2125 twm = TGSI_WRITEMASK_XYZ;
2126 txfi = IVEC3;
2127 break;
2128 case TGSI_TEXTURE_CUBE:
2129 case TGSI_TEXTURE_2D_ARRAY:
2130 twm = TGSI_WRITEMASK_XYZ;
2131 txfi = IVEC3;
2132 break;
2133 case TGSI_TEXTURE_2D_MSAA:
2134 twm = TGSI_WRITEMASK_XY;
2135 txfi = IVEC2;
2136 break;
2137 case TGSI_TEXTURE_2D_ARRAY_MSAA:
2138 twm = TGSI_WRITEMASK_XYZ;
2139 txfi = IVEC3;
2140 break;
2141
2142 case TGSI_TEXTURE_SHADOWCUBE:
2143 case TGSI_TEXTURE_SHADOW2D_ARRAY:
2144 case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
2145 case TGSI_TEXTURE_CUBE_ARRAY:
2146 default:
2147 if (inst->Instruction.Opcode == TGSI_OPCODE_TG4 &&
2148 inst->Texture.Texture != TGSI_TEXTURE_CUBE_ARRAY
2149 && inst->Texture.Texture != TGSI_TEXTURE_SHADOWCUBE_ARRAY)
2150 twm = TGSI_WRITEMASK_XYZ;
2151 else
2152 twm = TGSI_WRITEMASK_NONE;
2153 txfi = TYPE_CONVERSION_NONE;
2154 break;
2155 }
2156
2157 if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) {
2158 switch (inst->Texture.Texture) {
2159 case TGSI_TEXTURE_1D:
2160 case TGSI_TEXTURE_SHADOW1D:
2161 case TGSI_TEXTURE_1D_ARRAY:
2162 case TGSI_TEXTURE_SHADOW1D_ARRAY:
2163 gwm = TGSI_WRITEMASK_X;
2164 break;
2165 case TGSI_TEXTURE_2D:
2166 case TGSI_TEXTURE_SHADOW2D:
2167 case TGSI_TEXTURE_2D_ARRAY:
2168 case TGSI_TEXTURE_SHADOW2D_ARRAY:
2169 case TGSI_TEXTURE_RECT:
2170 case TGSI_TEXTURE_SHADOWRECT:
2171 gwm = TGSI_WRITEMASK_XY;
2172 break;
2173 case TGSI_TEXTURE_3D:
2174 case TGSI_TEXTURE_CUBE:
2175 case TGSI_TEXTURE_SHADOWCUBE:
2176 case TGSI_TEXTURE_CUBE_ARRAY:
2177 gwm = TGSI_WRITEMASK_XYZ;
2178 break;
2179 default:
2180 gwm = TGSI_WRITEMASK_NONE;
2181 break;
2182 }
2183 }
2184
2185 if (inst->Instruction.Opcode == TGSI_OPCODE_TXB2 || inst->Instruction.Opcode == TGSI_OPCODE_TXL2 || inst->Instruction.Opcode == TGSI_OPCODE_TEX2) {
2186 sampler_index = 2;
2187 if (inst->Instruction.Opcode != TGSI_OPCODE_TEX2)
2188 snprintf(bias, 64, ", %s.x", srcs[1]);
2189 else if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
2190 snprintf(bias, 64, ", float(%s)", srcs[1]);
2191 } else if (inst->Instruction.Opcode == TGSI_OPCODE_TXB || inst->Instruction.Opcode == TGSI_OPCODE_TXL)
2192 snprintf(bias, 64, ", %s.w", srcs[0]);
2193 else if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) {
2194 if (inst->Texture.Texture == TGSI_TEXTURE_1D ||
2195 inst->Texture.Texture == TGSI_TEXTURE_2D ||
2196 inst->Texture.Texture == TGSI_TEXTURE_2D_MSAA ||
2197 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY_MSAA ||
2198 inst->Texture.Texture == TGSI_TEXTURE_3D ||
2199 inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY ||
2200 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY) {
2201 snprintf(bias, 64, ", int(%s.w)", srcs[0]);
2202 }
2203 } else if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) {
2204 snprintf(bias, 128, ", %s%s, %s%s", srcs[1], get_wm_string(gwm), srcs[2], get_wm_string(gwm));
2205 sampler_index = 3;
2206 } else if (inst->Instruction.Opcode == TGSI_OPCODE_TG4) {
2207 sampler_index = 2;
2208 ctx->shader_req_bits |= SHADER_REQ_TG4;
2209 if (inst->Texture.NumOffsets > 1 || is_shad || (ctx->shader_req_bits & SHADER_REQ_SAMPLER_RECT))
2210 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
2211 if (inst->Texture.NumOffsets == 1) {
2212 if (inst->TexOffsets[0].File != TGSI_FILE_IMMEDIATE)
2213 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
2214 }
2215 if (is_shad) {
2216 if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
2217 inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY)
2218 snprintf(bias, 64, ", %s.w", srcs[0]);
2219 else if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
2220 snprintf(bias, 64, ", %s.x", srcs[1]);
2221 else
2222 snprintf(bias, 64, ", %s.z", srcs[0]);
2223 } else if (sinfo->tg4_has_component) {
2224 if (inst->Texture.NumOffsets == 0) {
2225 if (inst->Texture.Texture == TGSI_TEXTURE_2D ||
2226 inst->Texture.Texture == TGSI_TEXTURE_RECT ||
2227 inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
2228 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY ||
2229 inst->Texture.Texture == TGSI_TEXTURE_CUBE_ARRAY)
2230 snprintf(bias, 64, ", int(%s)", srcs[1]);
2231 } else if (inst->Texture.NumOffsets) {
2232 if (inst->Texture.Texture == TGSI_TEXTURE_2D ||
2233 inst->Texture.Texture == TGSI_TEXTURE_RECT ||
2234 inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY)
2235 snprintf(bias, 64, ", int(%s)", srcs[1]);
2236 }
2237 }
2238 } else
2239 bias[0] = 0;
2240
2241 tex_ext = get_tex_inst_ext(inst);
2242
2243 if (inst->Texture.NumOffsets == 1) {
2244 if (inst->TexOffsets[0].Index >= (int)ARRAY_SIZE(ctx->imm)) {
2245 fprintf(stderr, "Immediate exceeded, max is %lu\n", ARRAY_SIZE(ctx->imm));
2246 return false;
2247 }
2248
2249 if (!fill_offset_buffer(ctx, inst, offbuf))
2250 return false;
2251
2252 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)) {
2253 char tmp[128];
2254 strcpy(tmp, offbuf);
2255 strcpy(offbuf, bias);
2256 strcpy(bias, tmp);
2257 }
2258 }
2259 if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) {
2260 snprintf(buf, 255, "%s = %s(%s(texelFetch%s(%s, %s(%s%s)%s%s)%s));\n", dsts[0], get_string(dinfo->dstconv), get_string(dtypeprefix), tex_ext, srcs[sampler_index], get_string(txfi), srcs[0], get_wm_string(twm), bias, offbuf, dinfo->dst_override_no_wm[0] ? "" : writemask);
2261 } else if (ctx->cfg->glsl_version < 140 && (ctx->shader_req_bits & SHADER_REQ_SAMPLER_RECT)) {
2262 /* rect is special in GLSL 1.30 */
2263 if (inst->Texture.Texture == TGSI_TEXTURE_RECT)
2264 snprintf(buf, 255, "%s = texture2DRect(%s, %s.xy)%s;\n", dsts[0], srcs[sampler_index], srcs[0], writemask);
2265 else if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWRECT)
2266 snprintf(buf, 255, "%s = shadow2DRect(%s, %s.xyz)%s;\n", dsts[0], srcs[sampler_index], srcs[0], writemask);
2267 } else if (is_shad && inst->Instruction.Opcode != TGSI_OPCODE_TG4) { /* TGSI returns 1.0 in alpha */
2268 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
2269 const struct tgsi_full_src_register *src = &inst->Src[sampler_index];
2270 snprintf(buf, 255, "%s = %s(%s(vec4(vec4(texture%s(%s, %s%s%s%s)) * %sshadmask%d + %sshadadd%d)%s));\n", dsts[0], get_string(dinfo->dstconv), get_string(dtypeprefix), tex_ext, srcs[sampler_index], srcs[0], get_wm_string(twm), offbuf, bias, cname, src->Register.Index, cname, src->Register.Index, writemask);
2271 } else {
2272 /* OpenGL ES do not support 1D texture
2273 * so we use a 2D texture with a parameter set to 0.5
2274 */
2275 if (ctx->cfg->use_gles && inst->Texture.Texture == TGSI_TEXTURE_1D) {
2276 snprintf(buf, 255, "%s = %s(%s(texture2D(%s, vec2(%s%s%s%s, 0.5))%s));\n", dsts[0], get_string(dinfo->dstconv), get_string(dtypeprefix), srcs[sampler_index], srcs[0], get_wm_string(twm), offbuf, bias, dinfo->dst_override_no_wm[0] ? "" : writemask);
2277 } else {
2278 snprintf(buf, 255, "%s = %s(%s(texture%s(%s, %s%s%s%s)%s));\n", dsts[0], get_string(dinfo->dstconv), get_string(dtypeprefix), tex_ext, srcs[sampler_index], srcs[0], get_wm_string(twm), offbuf, bias, dinfo->dst_override_no_wm[0] ? "" : writemask);
2279 }
2280 }
2281 return emit_buf(ctx, buf);
2282 }
2283
2284 static void
create_swizzled_clipdist(struct dump_ctx * ctx,char * result,const struct tgsi_full_src_register * src,int input_idx,bool gl_in,const char * stypeprefix,const char * prefix,const char * arrayname)2285 create_swizzled_clipdist(struct dump_ctx *ctx,
2286 char *result,
2287 const struct tgsi_full_src_register *src,
2288 int input_idx,
2289 bool gl_in,
2290 const char *stypeprefix,
2291 const char *prefix,
2292 const char *arrayname)
2293 {
2294 char clipdistvec[4][64] = {};
2295 int idx;
2296 bool has_prev_vals = (ctx->key->prev_stage_num_cull_out + ctx->key->prev_stage_num_clip_out) > 0;
2297 int num_culls = has_prev_vals ? ctx->key->prev_stage_num_cull_out : 0;
2298 int num_clips = has_prev_vals ? ctx->key->prev_stage_num_clip_out : ctx->num_in_clip_dist;
2299 for (unsigned cc = 0; cc < 4; cc++) {
2300 const char *cc_name = ctx->inputs[input_idx].glsl_name;
2301 idx = ctx->inputs[input_idx].sid * 4;
2302 if (cc == 0)
2303 idx += src->Register.SwizzleX;
2304 else if (cc == 1)
2305 idx += src->Register.SwizzleY;
2306 else if (cc == 2)
2307 idx += src->Register.SwizzleZ;
2308 else if (cc == 3)
2309 idx += src->Register.SwizzleW;
2310
2311 if (num_culls) {
2312 if (idx >= num_clips) {
2313 idx -= num_clips;
2314 cc_name = "gl_CullDistance";
2315 }
2316 if (ctx->key->prev_stage_num_cull_out)
2317 if (idx >= ctx->key->prev_stage_num_cull_out)
2318 idx = 0;
2319 } else {
2320 if (ctx->key->prev_stage_num_clip_out)
2321 if (idx >= ctx->key->prev_stage_num_clip_out)
2322 idx = 0;
2323 }
2324 if (gl_in)
2325 snprintf(clipdistvec[cc], 64, "%sgl_in%s.%s[%d]", prefix, arrayname, cc_name, idx);
2326 else
2327 snprintf(clipdistvec[cc], 64, "%s%s%s[%d]", prefix, arrayname, cc_name, idx);
2328 }
2329 snprintf(result, 255, "%s(vec4(%s,%s,%s,%s))", stypeprefix, clipdistvec[0], clipdistvec[1], clipdistvec[2], clipdistvec[3]);
2330 }
2331
get_coord_prefix(int resource,bool * is_ms)2332 static enum vrend_type_qualifier get_coord_prefix(int resource, bool *is_ms)
2333 {
2334 switch(resource) {
2335 case TGSI_TEXTURE_1D:
2336 case TGSI_TEXTURE_BUFFER:
2337 return INT;
2338 case TGSI_TEXTURE_2D:
2339 case TGSI_TEXTURE_RECT:
2340 case TGSI_TEXTURE_1D_ARRAY:
2341 return IVEC2;
2342 case TGSI_TEXTURE_3D:
2343 case TGSI_TEXTURE_CUBE:
2344 case TGSI_TEXTURE_2D_ARRAY:
2345 case TGSI_TEXTURE_CUBE_ARRAY:
2346 return IVEC3;
2347 case TGSI_TEXTURE_2D_MSAA:
2348 *is_ms = true;
2349 return IVEC2;
2350 case TGSI_TEXTURE_2D_ARRAY_MSAA:
2351 *is_ms = true;
2352 return IVEC3;
2353 default:
2354 return TYPE_CONVERSION_NONE;
2355 }
2356 }
2357
is_integer_memory(struct dump_ctx * ctx,enum tgsi_file_type file_type,uint32_t index)2358 static bool is_integer_memory(struct dump_ctx *ctx, enum tgsi_file_type file_type, uint32_t index)
2359 {
2360 switch(file_type) {
2361 case TGSI_FILE_BUFFER:
2362 return !!(ctx->ssbo_integer_mask & (1 << index));
2363 case TGSI_FILE_MEMORY:
2364 return ctx->integer_memory;
2365 default:
2366 fprintf(stderr, "Invalid file type");
2367 }
2368
2369 return false;
2370 }
2371
2372 static int
translate_store(struct dump_ctx * ctx,struct tgsi_full_instruction * inst,struct source_info * sinfo,char srcs[4][255],char dsts[3][255])2373 translate_store(struct dump_ctx *ctx,
2374 struct tgsi_full_instruction *inst,
2375 struct source_info *sinfo,
2376 char srcs[4][255],
2377 char dsts[3][255])
2378 {
2379 const struct tgsi_full_dst_register *dst = &inst->Dst[0];
2380 char buf[512];
2381
2382 if (dst->Register.File == TGSI_FILE_IMAGE) {
2383 bool is_ms = false;
2384 enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx->images[dst->Register.Index].decl.Resource, &is_ms);
2385 enum tgsi_return_type itype;
2386 char ms_str[32] = {};
2387 enum vrend_type_qualifier stypeprefix = TYPE_CONVERSION_NONE;
2388 const char *conversion = sinfo->override_no_cast[0] ? "" : get_string(FLOAT_BITS_TO_INT);
2389 get_internalformat_string(inst->Memory.Format, &itype);
2390 if (is_ms) {
2391 snprintf(ms_str, 32, "int(%s.w),", srcs[0]);
2392 }
2393 switch (itype) {
2394 case TGSI_RETURN_TYPE_UINT:
2395 stypeprefix = FLOAT_BITS_TO_UINT;
2396 break;
2397 case TGSI_RETURN_TYPE_SINT:
2398 stypeprefix = FLOAT_BITS_TO_INT;
2399 break;
2400 default:
2401 break;
2402 }
2403 snprintf(buf, 512, "imageStore(%s,%s(%s(%s)),%s%s(%s));\n", dsts[0], get_string(coord_prefix),
2404 conversion, srcs[0], ms_str, get_string(stypeprefix), srcs[1]);
2405 EMIT_BUF_WITH_RET(ctx, buf);
2406 } else if (dst->Register.File == TGSI_FILE_BUFFER || dst->Register.File == TGSI_FILE_MEMORY) {
2407 enum vrend_type_qualifier dtypeprefix;
2408 dtypeprefix = (is_integer_memory(ctx, dst->Register.File, dst->Register.Index)) ? FLOAT_BITS_TO_INT : FLOAT_BITS_TO_UINT;
2409 const char *conversion = sinfo->override_no_cast[1] ? "" : get_string(dtypeprefix);
2410 if (inst->Dst[0].Register.WriteMask & 0x1) {
2411 snprintf(buf, 255, "%s[uint(floatBitsToUint(%s))>>2] = %s(%s).x;\n", dsts[0], srcs[0], conversion, srcs[1]);
2412 EMIT_BUF_WITH_RET(ctx, buf);
2413 }
2414 if (inst->Dst[0].Register.WriteMask & 0x2) {
2415 snprintf(buf, 255, "%s[(uint(floatBitsToUint(%s))>>2)+1u] = %s(%s).y;\n", dsts[0], srcs[0], conversion, srcs[1]);
2416 EMIT_BUF_WITH_RET(ctx, buf);
2417 }
2418 if (inst->Dst[0].Register.WriteMask & 0x4) {
2419 snprintf(buf, 255, "%s[(uint(floatBitsToUint(%s))>>2)+2u] = %s(%s).z;\n", dsts[0], srcs[0], conversion, srcs[1]);
2420 EMIT_BUF_WITH_RET(ctx, buf);
2421 }
2422 if (inst->Dst[0].Register.WriteMask & 0x8) {
2423 snprintf(buf, 255, "%s[(uint(floatBitsToUint(%s))>>2)+3u] = %s(%s).w;\n", dsts[0], srcs[0], conversion, srcs[1]);
2424 EMIT_BUF_WITH_RET(ctx, buf);
2425 }
2426 }
2427 return 0;
2428 }
2429
2430 static int
translate_load(struct dump_ctx * ctx,struct tgsi_full_instruction * inst,struct source_info * sinfo,struct dest_info * dinfo,char srcs[4][255],char dsts[3][255],const char * writemask)2431 translate_load(struct dump_ctx *ctx,
2432 struct tgsi_full_instruction *inst,
2433 struct source_info *sinfo,
2434 struct dest_info *dinfo,
2435 char srcs[4][255],
2436 char dsts[3][255],
2437 const char *writemask)
2438 {
2439 char buf[512];
2440 const struct tgsi_full_src_register *src = &inst->Src[0];
2441 if (src->Register.File == TGSI_FILE_IMAGE) {
2442 bool is_ms = false;
2443 enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx->images[sinfo->sreg_index].decl.Resource, &is_ms);
2444 enum vrend_type_qualifier dtypeprefix = TYPE_CONVERSION_NONE;
2445 const char *conversion = sinfo->override_no_cast[1] ? "" : get_string(FLOAT_BITS_TO_INT);
2446 enum tgsi_return_type itype;
2447 get_internalformat_string(ctx->images[sinfo->sreg_index].decl.Format, &itype);
2448 char ms_str[32] = {};
2449 const char *wm = dinfo->dst_override_no_wm[0] ? "" : writemask;
2450 if (is_ms) {
2451 snprintf(ms_str, 32, ", int(%s.w)", srcs[1]);
2452 }
2453 switch (itype) {
2454 case TGSI_RETURN_TYPE_UINT:
2455 dtypeprefix = UINT_BITS_TO_FLOAT;
2456 break;
2457 case TGSI_RETURN_TYPE_SINT:
2458 dtypeprefix = INT_BITS_TO_FLOAT;
2459 break;
2460 default:
2461 break;
2462 }
2463 snprintf(buf, 512, "%s = %s(imageLoad(%s, %s(%s(%s))%s)%s);\n", dsts[0], get_string(dtypeprefix), srcs[0],
2464 get_string(coord_prefix), conversion, srcs[1], ms_str, wm);
2465 EMIT_BUF_WITH_RET(ctx, buf);
2466 } else if (src->Register.File == TGSI_FILE_BUFFER ||
2467 src->Register.File == TGSI_FILE_MEMORY) {
2468 char mydst[255], atomic_op[9], atomic_src[10];
2469 enum vrend_type_qualifier dtypeprefix;
2470 strcpy(mydst, dsts[0]);
2471 char *wmp = strchr(mydst, '.');
2472 if (wmp)
2473 wmp[0] = 0;
2474 snprintf(buf, 255, "ssbo_addr_temp = uint(floatBitsToUint(%s)) >> 2;\n", srcs[1]);
2475 EMIT_BUF_WITH_RET(ctx, buf);
2476
2477 atomic_op[0] = atomic_src[0] = '\0';
2478 if (ctx->ssbo_atomic_mask & (1 << src->Register.Index)) {
2479 /* Emulate atomicCounter with atomicOr. */
2480 strcpy(atomic_op, "atomicOr");
2481 strcpy(atomic_src, ", uint(0)");
2482 }
2483
2484 dtypeprefix = (is_integer_memory(ctx, src->Register.File, src->Register.Index)) ? INT_BITS_TO_FLOAT : UINT_BITS_TO_FLOAT;
2485 if (inst->Dst[0].Register.WriteMask & 0x1) {
2486 snprintf(buf, 255, "%s.x = (%s(%s(%s[ssbo_addr_temp]%s)));\n", mydst, get_string(dtypeprefix), atomic_op, srcs[0], atomic_src);
2487 EMIT_BUF_WITH_RET(ctx, buf);
2488 }
2489 if (inst->Dst[0].Register.WriteMask & 0x2) {
2490 snprintf(buf, 255, "%s.y = (%s(%s(%s[ssbo_addr_temp + 1u]%s)));\n", mydst, get_string(dtypeprefix), atomic_op, srcs[0], atomic_src);
2491 EMIT_BUF_WITH_RET(ctx, buf);
2492 }
2493 if (inst->Dst[0].Register.WriteMask & 0x4) {
2494 snprintf(buf, 255, "%s.z = (%s(%s(%s[ssbo_addr_temp + 2u]%s)));\n", mydst, get_string(dtypeprefix), atomic_op, srcs[0], atomic_src);
2495 EMIT_BUF_WITH_RET(ctx, buf);
2496 }
2497 if (inst->Dst[0].Register.WriteMask & 0x8) {
2498 snprintf(buf, 255, "%s.w = (%s(%s(%s[ssbo_addr_temp + 3u]%s)));\n", mydst, get_string(dtypeprefix), atomic_op, srcs[0], atomic_src);
2499 EMIT_BUF_WITH_RET(ctx, buf);
2500 }
2501 }
2502 return 0;
2503 }
2504
get_atomic_opname(int tgsi_opcode,bool * is_cas)2505 static const char *get_atomic_opname(int tgsi_opcode, bool *is_cas)
2506 {
2507 const char *opname;
2508 *is_cas = false;
2509 switch (tgsi_opcode) {
2510 case TGSI_OPCODE_ATOMUADD:
2511 opname = "Add";
2512 break;
2513 case TGSI_OPCODE_ATOMXCHG:
2514 opname = "Exchange";
2515 break;
2516 case TGSI_OPCODE_ATOMCAS:
2517 opname = "CompSwap";
2518 *is_cas = true;
2519 break;
2520 case TGSI_OPCODE_ATOMAND:
2521 opname = "And";
2522 break;
2523 case TGSI_OPCODE_ATOMOR:
2524 opname = "Or";
2525 break;
2526 case TGSI_OPCODE_ATOMXOR:
2527 opname = "Xor";
2528 break;
2529 case TGSI_OPCODE_ATOMUMIN:
2530 opname = "Min";
2531 break;
2532 case TGSI_OPCODE_ATOMUMAX:
2533 opname = "Max";
2534 break;
2535 case TGSI_OPCODE_ATOMIMIN:
2536 opname = "Min";
2537 break;
2538 case TGSI_OPCODE_ATOMIMAX:
2539 opname = "Max";
2540 break;
2541 default:
2542 fprintf(stderr, "illegal atomic opcode");
2543 return NULL;
2544 }
2545 return opname;
2546 }
2547
2548 static int
translate_resq(struct dump_ctx * ctx,struct tgsi_full_instruction * inst,char srcs[4][255],char dsts[3][255])2549 translate_resq(struct dump_ctx *ctx, struct tgsi_full_instruction *inst,
2550 char srcs[4][255], char dsts[3][255])
2551 {
2552 char buf[512];
2553 const struct tgsi_full_src_register *src = &inst->Src[0];
2554
2555 if (src->Register.File == TGSI_FILE_IMAGE) {
2556 if (inst->Dst[0].Register.WriteMask & 0x8) {
2557 ctx->shader_req_bits |= SHADER_REQ_TXQS | SHADER_REQ_INTS;
2558 snprintf(buf, 255, "%s = %s(imageSamples(%s));\n", dsts[0], get_string(INT_BITS_TO_FLOAT), srcs[0]);
2559 EMIT_BUF_WITH_RET(ctx, buf);
2560 }
2561 if (inst->Dst[0].Register.WriteMask & 0x7) {
2562 ctx->shader_req_bits |= SHADER_REQ_IMAGE_SIZE | SHADER_REQ_INTS;
2563 snprintf(buf, 255, "%s = %s(imageSize(%s));\n", dsts[0], get_string(INT_BITS_TO_FLOAT), srcs[0]);
2564 EMIT_BUF_WITH_RET(ctx, buf);
2565 }
2566 } else if (src->Register.File == TGSI_FILE_BUFFER) {
2567 snprintf(buf, 255, "%s = %s(int(%s.length()) << 2);\n", dsts[0], get_string(INT_BITS_TO_FLOAT), srcs[0]);
2568 EMIT_BUF_WITH_RET(ctx, buf);
2569 }
2570
2571 return 0;
2572 }
2573
2574 static int
translate_atomic(struct dump_ctx * ctx,struct tgsi_full_instruction * inst,struct source_info * sinfo,char srcs[4][255],char dsts[3][255])2575 translate_atomic(struct dump_ctx *ctx,
2576 struct tgsi_full_instruction *inst,
2577 struct source_info *sinfo,
2578 char srcs[4][255],
2579 char dsts[3][255])
2580 {
2581 char buf[512];
2582 const struct tgsi_full_src_register *src = &inst->Src[0];
2583 const char *opname;
2584 enum vrend_type_qualifier stypeprefix = TYPE_CONVERSION_NONE;
2585 enum vrend_type_qualifier dtypeprefix = TYPE_CONVERSION_NONE;
2586 enum vrend_type_qualifier stypecast = TYPE_CONVERSION_NONE;
2587 bool is_cas;
2588 char cas_str[128] = {};
2589
2590 if (src->Register.File == TGSI_FILE_IMAGE) {
2591 enum tgsi_return_type itype;
2592 get_internalformat_string(ctx->images[sinfo->sreg_index].decl.Format, &itype);
2593 switch (itype) {
2594 default:
2595 case TGSI_RETURN_TYPE_UINT:
2596 stypeprefix = FLOAT_BITS_TO_UINT;
2597 dtypeprefix = UINT_BITS_TO_FLOAT;
2598 stypecast = UINT;
2599 break;
2600 case TGSI_RETURN_TYPE_SINT:
2601 stypeprefix = FLOAT_BITS_TO_INT;
2602 dtypeprefix = INT_BITS_TO_FLOAT;
2603 stypecast = INT;
2604 break;
2605 case TGSI_RETURN_TYPE_FLOAT:
2606 ctx->shader_req_bits |= SHADER_REQ_ES31_COMPAT;
2607 stypecast = FLOAT;
2608 break;
2609 }
2610 } else {
2611 stypeprefix = FLOAT_BITS_TO_UINT;
2612 dtypeprefix = UINT_BITS_TO_FLOAT;
2613 stypecast = UINT;
2614 }
2615
2616 opname = get_atomic_opname(inst->Instruction.Opcode, &is_cas);
2617 if (!opname)
2618 return -1;
2619
2620 if (is_cas)
2621 snprintf(cas_str, 128, ", %s(%s(%s))", get_string(stypecast), get_string(stypeprefix), srcs[3]);
2622
2623 if (src->Register.File == TGSI_FILE_IMAGE) {
2624 bool is_ms = false;
2625 enum vrend_type_qualifier coord_prefix = get_coord_prefix(ctx->images[sinfo->sreg_index].decl.Resource, &is_ms);
2626 const char *conversion = sinfo->override_no_cast[1] ? "" : get_string(FLOAT_BITS_TO_INT);
2627 char ms_str[32] = {};
2628 if (is_ms) {
2629 snprintf(ms_str, 32, ", int(%s.w)", srcs[1]);
2630 }
2631 snprintf(buf, 512, "%s = %s(imageAtomic%s(%s, %s(%s(%s))%s, %s(%s(%s))%s));\n", dsts[0],
2632 get_string(dtypeprefix), opname, srcs[0], get_string(coord_prefix), conversion,
2633 srcs[1], ms_str, get_string(stypecast), get_string(stypeprefix), srcs[2], cas_str);
2634 EMIT_BUF_WITH_RET(ctx, buf);
2635 }
2636 if (src->Register.File == TGSI_FILE_BUFFER || src->Register.File == TGSI_FILE_MEMORY) {
2637 enum vrend_type_qualifier type;
2638 if ((is_integer_memory(ctx, src->Register.File, src->Register.Index))) {
2639 type = INT;
2640 dtypeprefix = INT_BITS_TO_FLOAT;
2641 stypeprefix = FLOAT_BITS_TO_INT;
2642 } else {
2643 type = UINT;
2644 dtypeprefix = UINT_BITS_TO_FLOAT;
2645 stypeprefix = FLOAT_BITS_TO_UINT;
2646 }
2647
2648 snprintf(buf, 512, "%s = %s(atomic%s(%s[int(floatBitsToInt(%s)) >> 2], %s(%s(%s).x)%s));\n", dsts[0], get_string(dtypeprefix), opname, srcs[0], srcs[1], get_string(type), get_string(stypeprefix), srcs[2], cas_str);
2649 EMIT_BUF_WITH_RET(ctx, buf);
2650 }
2651 return 0;
2652 }
2653
2654 static int
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)2655 get_destination_info(struct dump_ctx *ctx,
2656 const struct tgsi_full_instruction *inst,
2657 struct dest_info *dinfo,
2658 char dsts[3][255],
2659 char fp64_dsts[3][255],
2660 char *writemask)
2661 {
2662 const struct tgsi_full_dst_register *dst_reg;
2663 enum tgsi_opcode_type dtype = tgsi_opcode_infer_dst_type(inst->Instruction.Opcode);
2664
2665 if (dtype == TGSI_TYPE_SIGNED || dtype == TGSI_TYPE_UNSIGNED)
2666 ctx->shader_req_bits |= SHADER_REQ_INTS;
2667
2668 if (dtype == TGSI_TYPE_DOUBLE) {
2669 /* we need the uvec2 conversion for doubles */
2670 ctx->shader_req_bits |= SHADER_REQ_INTS | SHADER_REQ_FP64;
2671 }
2672
2673 if (inst->Instruction.Opcode == TGSI_OPCODE_TXQ) {
2674 dinfo->dtypeprefix = INT_BITS_TO_FLOAT;
2675 } else {
2676 switch (dtype) {
2677 case TGSI_TYPE_UNSIGNED:
2678 dinfo->dtypeprefix = UINT_BITS_TO_FLOAT;
2679 break;
2680 case TGSI_TYPE_SIGNED:
2681 dinfo->dtypeprefix = INT_BITS_TO_FLOAT;
2682 break;
2683 default:
2684 break;
2685 }
2686 }
2687
2688 for (uint32_t i = 0; i < inst->Instruction.NumDstRegs; i++) {
2689 char fp64_writemask[6] = {0};
2690 dst_reg = &inst->Dst[i];
2691 dinfo->dst_override_no_wm[i] = false;
2692 if (dst_reg->Register.WriteMask != TGSI_WRITEMASK_XYZW) {
2693 int wm_idx = 0, dbl_wm_idx = 0;
2694 writemask[wm_idx++] = '.';
2695 fp64_writemask[dbl_wm_idx++] = '.';
2696
2697 if (dst_reg->Register.WriteMask & 0x1)
2698 writemask[wm_idx++] = 'x';
2699 if (dst_reg->Register.WriteMask & 0x2)
2700 writemask[wm_idx++] = 'y';
2701 if (dst_reg->Register.WriteMask & 0x4)
2702 writemask[wm_idx++] = 'z';
2703 if (dst_reg->Register.WriteMask & 0x8)
2704 writemask[wm_idx++] = 'w';
2705
2706 if (dtype == TGSI_TYPE_DOUBLE) {
2707 if (dst_reg->Register.WriteMask & 0x3)
2708 fp64_writemask[dbl_wm_idx++] = 'x';
2709 if (dst_reg->Register.WriteMask & 0xc)
2710 fp64_writemask[dbl_wm_idx++] = 'y';
2711 }
2712
2713 if (dtype == TGSI_TYPE_DOUBLE) {
2714 if (dbl_wm_idx == 2)
2715 dinfo->dstconv = DOUBLE;
2716 else
2717 dinfo->dstconv = DVEC2;
2718 } else {
2719 dinfo->dstconv = FLOAT + wm_idx - 2;
2720 dinfo->udstconv = UINT + wm_idx - 2;
2721 dinfo->idstconv = INT + wm_idx - 2;
2722 }
2723 } else {
2724 if (dtype == TGSI_TYPE_DOUBLE)
2725 dinfo->dstconv = DVEC2;
2726 else
2727 dinfo->dstconv = VEC4;
2728 dinfo->udstconv = UVEC4;
2729 dinfo->idstconv = IVEC4;
2730 }
2731
2732 if (dst_reg->Register.File == TGSI_FILE_OUTPUT) {
2733 for (uint32_t j = 0; j < ctx->num_outputs; j++) {
2734 if (ctx->outputs[j].first == dst_reg->Register.Index) {
2735
2736 if (inst->Instruction.Precise) {
2737 ctx->outputs[j].precise = true;
2738 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
2739 }
2740
2741 if (ctx->glsl_ver_required >= 140 && ctx->outputs[j].name == TGSI_SEMANTIC_CLIPVERTEX) {
2742 snprintf(dsts[i], 255, "clipv_tmp");
2743 } else if (ctx->outputs[j].name == TGSI_SEMANTIC_CLIPDIST) {
2744 snprintf(dsts[i], 255, "clip_dist_temp[%d]", ctx->outputs[j].sid);
2745 } else if (ctx->outputs[j].name == TGSI_SEMANTIC_TESSOUTER ||
2746 ctx->outputs[j].name == TGSI_SEMANTIC_TESSINNER ||
2747 ctx->outputs[j].name == TGSI_SEMANTIC_SAMPLEMASK) {
2748 int idx;
2749 switch (dst_reg->Register.WriteMask) {
2750 case 0x1: idx = 0; break;
2751 case 0x2: idx = 1; break;
2752 case 0x4: idx = 2; break;
2753 case 0x8: idx = 3; break;
2754 default:
2755 idx = 0;
2756 break;
2757 }
2758 snprintf(dsts[i], 255, "%s[%d]", ctx->outputs[j].glsl_name, idx);
2759 if (ctx->outputs[j].is_int) {
2760 dinfo->dtypeprefix = FLOAT_BITS_TO_INT;
2761 dinfo->dstconv = INT;
2762 }
2763 } else {
2764 if (ctx->outputs[j].glsl_gl_block) {
2765 snprintf(dsts[i], 255, "gl_out[%s].%s%s",
2766 ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ? "gl_InvocationID" : "0",
2767 ctx->outputs[j].glsl_name,
2768 ctx->outputs[j].override_no_wm ? "" : writemask);
2769 } else if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL && ctx->outputs[j].name != TGSI_SEMANTIC_PATCH) {
2770 if (ctx_indirect_outputs(ctx)) {
2771 if (dst_reg->Register.Indirect)
2772 snprintf(dsts[i], 255, "oblk[gl_InvocationID].%s%d[addr%d + %d]%s", get_stage_output_name_prefix(ctx->prog_type), ctx->generic_output_range.first, dst_reg->Indirect.Index, dst_reg->Register.Index - ctx->generic_output_range.array_id, ctx->outputs[j].override_no_wm ? "" : writemask);
2773 else
2774 snprintf(dsts[i], 255, "oblk[gl_InvocationID].%s%d[%d]%s", get_stage_output_name_prefix(ctx->prog_type), ctx->generic_output_range.first, dst_reg->Register.Index - ctx->generic_output_range.array_id, ctx->outputs[j].override_no_wm ? "" : writemask);
2775
2776 } else
2777 snprintf(dsts[i], 255, "%s[gl_InvocationID]%s", ctx->outputs[j].glsl_name, ctx->outputs[j].override_no_wm ? "" : writemask);
2778 } else if (ctx_indirect_outputs(ctx) && ctx->outputs[j].name == TGSI_SEMANTIC_GENERIC) {
2779 if (dst_reg->Register.Indirect)
2780 snprintf(dsts[i], 255, "oblk.%s%d[addr%d + %d]%s", get_stage_output_name_prefix(ctx->prog_type), ctx->generic_output_range.first, dst_reg->Indirect.Index, dst_reg->Register.Index - ctx->generic_output_range.array_id, ctx->outputs[j].override_no_wm ? "" : writemask);
2781 else
2782 snprintf(dsts[i], 255, "oblk.%s%d[%d]%s", get_stage_output_name_prefix(ctx->prog_type), ctx->generic_output_range.first, dst_reg->Register.Index - ctx->generic_output_range.array_id, ctx->outputs[j].override_no_wm ? "" : writemask);
2783 dinfo->dst_override_no_wm[i] = ctx->outputs[j].override_no_wm;
2784 } else if (ctx_indirect_outputs(ctx) && ctx->outputs[j].name == TGSI_SEMANTIC_PATCH) {
2785 if (dst_reg->Register.Indirect)
2786 snprintf(dsts[i], 255, "%sp%d[addr%d + %d]%s", get_stage_output_name_prefix(ctx->prog_type), ctx->patch_output_range.first, dst_reg->Indirect.Index, dst_reg->Register.Index - ctx->patch_output_range.array_id, ctx->outputs[j].override_no_wm ? "" : writemask);
2787 else
2788 snprintf(dsts[i], 255, "%sp%d[%d]%s", get_stage_output_name_prefix(ctx->prog_type), ctx->patch_output_range.first, dst_reg->Register.Index - ctx->patch_output_range.array_id, ctx->outputs[j].override_no_wm ? "" : writemask);
2789 dinfo->dst_override_no_wm[i] = ctx->outputs[j].override_no_wm;
2790 } else {
2791 snprintf(dsts[i], 255, "%s%s", ctx->outputs[j].glsl_name, ctx->outputs[j].override_no_wm ? "" : writemask);
2792 dinfo->dst_override_no_wm[i] = ctx->outputs[j].override_no_wm;
2793 }
2794 if (ctx->outputs[j].is_int) {
2795 if (dinfo->dtypeprefix == TYPE_CONVERSION_NONE)
2796 dinfo->dtypeprefix = FLOAT_BITS_TO_INT;
2797 dinfo->dstconv = INT;
2798 }
2799 if (ctx->outputs[j].name == TGSI_SEMANTIC_PSIZE) {
2800 dinfo->dstconv = FLOAT;
2801 break;
2802 }
2803 }
2804 }
2805 }
2806 }
2807 else if (dst_reg->Register.File == TGSI_FILE_TEMPORARY) {
2808 struct vrend_temp_range *range = find_temp_range(ctx, dst_reg->Register.Index);
2809 if (!range)
2810 return FALSE;
2811 if (dst_reg->Register.Indirect) {
2812 snprintf(dsts[i], 255, "temp%d[addr0 + %d]%s", range->first, dst_reg->Register.Index - range->first, writemask);
2813 } else
2814 snprintf(dsts[i], 255, "temp%d[%d]%s", range->first, dst_reg->Register.Index - range->first, writemask);
2815 }
2816 else if (dst_reg->Register.File == TGSI_FILE_IMAGE) {
2817 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
2818 if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
2819 int basearrayidx = lookup_image_array(ctx, dst_reg->Register.Index);
2820 if (dst_reg->Register.Indirect) {
2821 assert(dst_reg->Indirect.File == TGSI_FILE_ADDRESS);
2822 snprintf(dsts[i], 255, "%simg%d[addr%d + %d]", cname, basearrayidx, dst_reg->Indirect.Index, dst_reg->Register.Index - basearrayidx);
2823 } else
2824 snprintf(dsts[i], 255, "%simg%d[%d]", cname, basearrayidx, dst_reg->Register.Index - basearrayidx);
2825 } else
2826 snprintf(dsts[i], 255, "%simg%d", cname, dst_reg->Register.Index);
2827 } else if (dst_reg->Register.File == TGSI_FILE_BUFFER) {
2828 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
2829 if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
2830 bool atomic_ssbo = ctx->ssbo_atomic_mask & (1 << dst_reg->Register.Index);
2831 const char *atomic_str = atomic_ssbo ? "atomic" : "";
2832 int base = atomic_ssbo ? ctx->ssbo_atomic_array_base : ctx->ssbo_array_base;
2833 if (dst_reg->Register.Indirect) {
2834 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);
2835 } else
2836 snprintf(dsts[i], 255, "%sssboarr%s[%d].%sssbocontents%d", cname, atomic_str, dst_reg->Register.Index - base, cname, base);
2837 } else
2838 snprintf(dsts[i], 255, "%sssbocontents%d", cname, dst_reg->Register.Index);
2839 } else if (dst_reg->Register.File == TGSI_FILE_MEMORY) {
2840 snprintf(dsts[i], 255, "values");
2841 } else if (dst_reg->Register.File == TGSI_FILE_ADDRESS) {
2842 snprintf(dsts[i], 255, "addr%d", dst_reg->Register.Index);
2843 }
2844
2845 if (dtype == TGSI_TYPE_DOUBLE) {
2846 strcpy(fp64_dsts[i], dsts[i]);
2847 snprintf(dsts[i], 255, "fp64_dst[%d]%s", i, fp64_writemask);
2848 writemask[0] = 0;
2849 }
2850
2851 }
2852
2853 return 0;
2854 }
2855
fill_blkarray(struct dump_ctx * ctx,const struct tgsi_full_src_register * src,char * blkarray)2856 static void fill_blkarray(struct dump_ctx *ctx,
2857 const struct tgsi_full_src_register *src,
2858 char *blkarray)
2859 {
2860 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL)
2861 strcpy(blkarray, "[gl_InvocationID]");
2862 else {
2863 if (src->Register.Dimension) {
2864 if (src->Dimension.Indirect)
2865 snprintf(blkarray, 32, "[addr%d + %d]", src->DimIndirect.Index, src->Dimension.Index);
2866 else
2867 snprintf(blkarray, 32, "[%d]", src->Dimension.Index);
2868 } else
2869 strcpy(blkarray, "[0]");
2870 }
2871 }
2872
2873 static int
get_source_info(struct dump_ctx * ctx,const struct tgsi_full_instruction * inst,struct source_info * sinfo,char srcs[3][255],char src_swizzle0[10])2874 get_source_info(struct dump_ctx *ctx,
2875 const struct tgsi_full_instruction *inst,
2876 struct source_info *sinfo,
2877 char srcs[3][255], char src_swizzle0[10])
2878 {
2879 bool stprefix = false;
2880
2881 enum vrend_type_qualifier stypeprefix = TYPE_CONVERSION_NONE;
2882 enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(inst->Instruction.Opcode);
2883
2884 if (stype == TGSI_TYPE_SIGNED || stype == TGSI_TYPE_UNSIGNED)
2885 ctx->shader_req_bits |= SHADER_REQ_INTS;
2886 if (stype == TGSI_TYPE_DOUBLE)
2887 ctx->shader_req_bits |= SHADER_REQ_INTS | SHADER_REQ_FP64;
2888
2889 switch (stype) {
2890 case TGSI_TYPE_DOUBLE:
2891 stypeprefix = FLOAT_BITS_TO_UINT;
2892 sinfo->svec4 = DVEC2;
2893 stprefix = true;
2894 break;
2895 case TGSI_TYPE_UNSIGNED:
2896 stypeprefix = FLOAT_BITS_TO_UINT;
2897 sinfo->svec4 = UVEC4;
2898 stprefix = true;
2899 break;
2900 case TGSI_TYPE_SIGNED:
2901 stypeprefix = FLOAT_BITS_TO_INT;
2902 sinfo->svec4 = IVEC4;
2903 stprefix = true;
2904 break;
2905 default:
2906 break;
2907 }
2908
2909 for (uint32_t i = 0; i < inst->Instruction.NumSrcRegs; i++) {
2910 const struct tgsi_full_src_register *src = &inst->Src[i];
2911 char swizzle[8] = {0};
2912 char prefix[6] = {0};
2913 char arrayname[16] = {0};
2914 char fp64_src[255];
2915 int swz_idx = 0, pre_idx = 0;
2916 boolean isfloatabsolute = src->Register.Absolute && stype != TGSI_TYPE_DOUBLE;
2917
2918 sinfo->override_no_wm[i] = false;
2919 sinfo->override_no_cast[i] = false;
2920 if (isfloatabsolute)
2921 swizzle[swz_idx++] = ')';
2922
2923 if (src->Register.Negate)
2924 prefix[pre_idx++] = '-';
2925 if (isfloatabsolute)
2926 strcpy(&prefix[pre_idx++], "abs(");
2927
2928 if (src->Register.Dimension) {
2929 if (src->Dimension.Indirect) {
2930 assert(src->DimIndirect.File == TGSI_FILE_ADDRESS);
2931 sprintf(arrayname, "[addr%d]", src->DimIndirect.Index);
2932 } else
2933 sprintf(arrayname, "[%d]", src->Dimension.Index);
2934 }
2935
2936 if (src->Register.SwizzleX != TGSI_SWIZZLE_X ||
2937 src->Register.SwizzleY != TGSI_SWIZZLE_Y ||
2938 src->Register.SwizzleZ != TGSI_SWIZZLE_Z ||
2939 src->Register.SwizzleW != TGSI_SWIZZLE_W) {
2940 swizzle[swz_idx++] = '.';
2941 swizzle[swz_idx++] = get_swiz_char(src->Register.SwizzleX);
2942 swizzle[swz_idx++] = get_swiz_char(src->Register.SwizzleY);
2943 swizzle[swz_idx++] = get_swiz_char(src->Register.SwizzleZ);
2944 swizzle[swz_idx++] = get_swiz_char(src->Register.SwizzleW);
2945 }
2946 if (src->Register.File == TGSI_FILE_INPUT) {
2947 for (uint32_t j = 0; j < ctx->num_inputs; j++)
2948 if (ctx->inputs[j].first == src->Register.Index) {
2949 if (ctx->key->color_two_side && ctx->inputs[j].name == TGSI_SEMANTIC_COLOR)
2950 snprintf(srcs[i], 255, "%s(%s%s%d%s%s)", get_string(stypeprefix), prefix, "realcolor", ctx->inputs[j].sid, arrayname, swizzle);
2951 else if (ctx->inputs[j].glsl_gl_block) {
2952 /* GS input clipdist requires a conversion */
2953 if (ctx->inputs[j].name == TGSI_SEMANTIC_CLIPDIST) {
2954 create_swizzled_clipdist(ctx, srcs[i], src, j, true, get_string(stypeprefix), prefix, arrayname);
2955 } else {
2956 snprintf(srcs[i], 255, "%s(vec4(%sgl_in%s.%s)%s)", get_string(stypeprefix), prefix, arrayname, ctx->inputs[j].glsl_name, swizzle);
2957 }
2958 }
2959 else if (ctx->inputs[j].name == TGSI_SEMANTIC_PRIMID)
2960 snprintf(srcs[i], 255, "%s(vec4(intBitsToFloat(%s)))", get_string(stypeprefix), ctx->inputs[j].glsl_name);
2961 else if (ctx->inputs[j].name == TGSI_SEMANTIC_FACE)
2962 snprintf(srcs[i], 255, "%s(%s ? 1.0 : -1.0)", get_string(stypeprefix), ctx->inputs[j].glsl_name);
2963 else if (ctx->inputs[j].name == TGSI_SEMANTIC_CLIPDIST) {
2964 create_swizzled_clipdist(ctx, srcs[i], src, j, false, get_string(stypeprefix), prefix, arrayname);
2965 } else {
2966 enum vrend_type_qualifier srcstypeprefix = stypeprefix;
2967 if ((stype == TGSI_TYPE_UNSIGNED || stype == TGSI_TYPE_SIGNED) &&
2968 ctx->inputs[j].is_int)
2969 srcstypeprefix = TYPE_CONVERSION_NONE;
2970
2971 if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1) {
2972 snprintf(srcs[i], 255, "floatBitsToInt(%s%s%s%s)", prefix, ctx->inputs[j].glsl_name, arrayname, swizzle);
2973 } else if (ctx->inputs[j].name == TGSI_SEMANTIC_GENERIC &&
2974 ctx_indirect_inputs(ctx)) {
2975 char blkarray[32] = {};
2976 fill_blkarray(ctx, src, blkarray);
2977 if (src->Register.Indirect)
2978 snprintf(srcs[i], 255, "%s(%sblk%s.%s%d[addr%d + %d]%s)", get_string(srcstypeprefix), prefix, blkarray, get_stage_input_name_prefix(ctx, ctx->prog_type), ctx->generic_input_range.first, src->Indirect.Index, src->Register.Index - ctx->generic_input_range.array_id, ctx->inputs[j].is_int ? "" : swizzle);
2979 else
2980 snprintf(srcs[i], 255, "%s(%sblk%s.%s%d[%d]%s)", get_string(srcstypeprefix), prefix, blkarray, get_stage_input_name_prefix(ctx, ctx->prog_type), ctx->generic_input_range.first, src->Register.Index - ctx->generic_input_range.array_id, ctx->inputs[j].is_int ? "" : swizzle);
2981 } else if (ctx->inputs[j].name == TGSI_SEMANTIC_PATCH &&
2982 ctx_indirect_inputs(ctx)) {
2983 if (src->Register.Indirect)
2984 snprintf(srcs[i], 255, "%s(%s%sp%d[addr%d + %d]%s)", get_string(srcstypeprefix), prefix, get_stage_input_name_prefix(ctx, ctx->prog_type), ctx->patch_input_range.first, src->Indirect.Index, src->Register.Index - ctx->patch_input_range.array_id, ctx->inputs[j].is_int ? "" : swizzle);
2985 else
2986 snprintf(srcs[i], 255, "%s(%s%sp%d[%d]%s)", get_string(srcstypeprefix), prefix, get_stage_input_name_prefix(ctx, ctx->prog_type), ctx->patch_input_range.first, src->Register.Index - ctx->patch_input_range.array_id, ctx->inputs[j].is_int ? "" : swizzle);
2987 } else
2988 snprintf(srcs[i], 255, "%s(%s%s%s%s)", get_string(srcstypeprefix), prefix, ctx->inputs[j].glsl_name, arrayname, ctx->inputs[j].is_int ? "" : swizzle);
2989 }
2990 if ((inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE ||
2991 inst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET ||
2992 inst->Instruction.Opcode == TGSI_OPCODE_INTERP_CENTROID) &&
2993 i == 0) {
2994 snprintf(srcs[0], 255, "%s", ctx->inputs[j].glsl_name);
2995 snprintf(src_swizzle0, 10, "%s", swizzle);
2996 }
2997 sinfo->override_no_wm[i] = ctx->inputs[j].override_no_wm;
2998 break;
2999 }
3000 } else if (src->Register.File == TGSI_FILE_OUTPUT) {
3001 for (uint32_t j = 0; j < ctx->num_outputs; j++) {
3002 if (ctx->outputs[j].first == src->Register.Index) {
3003 if (inst->Instruction.Opcode == TGSI_OPCODE_FBFETCH) {
3004 ctx->outputs[j].fbfetch_used = true;
3005 ctx->shader_req_bits |= SHADER_REQ_FBFETCH;
3006 }
3007
3008 enum vrend_type_qualifier srcstypeprefix = stypeprefix;
3009 if (stype == TGSI_TYPE_UNSIGNED && ctx->outputs[j].is_int)
3010 srcstypeprefix = TYPE_CONVERSION_NONE;
3011 if (ctx->outputs[j].glsl_gl_block) {
3012 if (ctx->outputs[j].name == TGSI_SEMANTIC_CLIPDIST) {
3013 snprintf(srcs[i], 255, "clip_dist_temp[%d]", ctx->outputs[j].sid);
3014 }
3015 } else if (ctx->outputs[j].name == TGSI_SEMANTIC_GENERIC &&
3016 ctx_indirect_outputs(ctx)) {
3017 char blkarray[32] = {};
3018 fill_blkarray(ctx, src, blkarray);
3019 if (src->Register.Indirect)
3020 snprintf(srcs[i], 255, "%s(%soblk%s.%s%d[addr%d + %d]%s)", get_string(srcstypeprefix), prefix, blkarray, get_stage_output_name_prefix(ctx->prog_type), ctx->generic_output_range.first, src->Indirect.Index, src->Register.Index - ctx->generic_output_range.array_id, ctx->outputs[j].is_int ? "" : swizzle);
3021 else
3022 snprintf(srcs[i], 255, "%s(%soblk%s.%s%d[%d]%s)", get_string(srcstypeprefix), prefix, blkarray, get_stage_output_name_prefix(ctx->prog_type), ctx->generic_output_range.first, src->Register.Index - ctx->generic_output_range.array_id, ctx->outputs[j].is_int ? "" : swizzle);
3023 } else if (ctx->outputs[j].name == TGSI_SEMANTIC_PATCH &&
3024 ctx_indirect_outputs(ctx)) {
3025 if (src->Register.Indirect)
3026 snprintf(srcs[i], 255, "%s(%s%sp%d[addr%d + %d]%s)", get_string(srcstypeprefix), prefix, get_stage_output_name_prefix(ctx->prog_type), ctx->patch_output_range.first, src->Indirect.Index, src->Register.Index - ctx->patch_output_range.array_id, ctx->outputs[j].is_int ? "" : swizzle);
3027 else
3028 snprintf(srcs[i], 255, "%s(%s%sp%d[%d]%s)", get_string(srcstypeprefix), prefix, get_stage_output_name_prefix(ctx->prog_type), ctx->patch_output_range.first, src->Register.Index - ctx->patch_output_range.array_id, ctx->outputs[j].is_int ? "" : swizzle);
3029 } else {
3030 snprintf(srcs[i], 255, "%s(%s%s%s%s)", get_string(srcstypeprefix), prefix, ctx->outputs[j].glsl_name, arrayname, ctx->outputs[j].is_int ? "" : swizzle);
3031 }
3032 }
3033 }
3034 } else if (src->Register.File == TGSI_FILE_TEMPORARY) {
3035 struct vrend_temp_range *range = find_temp_range(ctx, src->Register.Index);
3036 if (!range)
3037 return FALSE;
3038 if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1) {
3039 stprefix = true;
3040 stypeprefix = FLOAT_BITS_TO_INT;
3041 }
3042
3043 if (src->Register.Indirect) {
3044 assert(src->Indirect.File == TGSI_FILE_ADDRESS);
3045 snprintf(srcs[i], 255, "%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 ? ')' : ' ');
3046 } else
3047 snprintf(srcs[i], 255, "%s%c%stemp%d[%d]%s%c", get_string(stypeprefix), stprefix ? '(' : ' ', prefix, range->first, src->Register.Index - range->first, swizzle, stprefix ? ')' : ' ');
3048 } else if (src->Register.File == TGSI_FILE_CONSTANT) {
3049 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3050 int dim = 0;
3051 if (src->Register.Dimension && src->Dimension.Index != 0) {
3052 dim = src->Dimension.Index;
3053 if (src->Dimension.Indirect) {
3054 assert(src->DimIndirect.File == TGSI_FILE_ADDRESS);
3055 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3056 if (src->Register.Indirect) {
3057 assert(src->Indirect.File == TGSI_FILE_ADDRESS);
3058 snprintf(srcs[i], 255, "%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);
3059 } else
3060 snprintf(srcs[i], 255, "%s(%s%suboarr[addr%d].ubocontents[%d]%s)", get_string(stypeprefix), prefix, cname, src->DimIndirect.Index, src->Register.Index, swizzle);
3061 } else {
3062 if (ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT)) {
3063 if (src->Register.Indirect) {
3064 snprintf(srcs[i], 255, "%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);
3065 } else
3066 snprintf(srcs[i], 255, "%s(%s%suboarr[%d].ubocontents[%d]%s)", get_string(stypeprefix), prefix, cname, dim - ctx->ubo_base, src->Register.Index, swizzle);
3067 } else {
3068 if (src->Register.Indirect) {
3069 snprintf(srcs[i], 255, "%s(%s%subo%dcontents[addr0 + %d]%s)", get_string(stypeprefix), prefix, cname, dim, src->Register.Index, swizzle);
3070 } else
3071 snprintf(srcs[i], 255, "%s(%s%subo%dcontents[%d]%s)", get_string(stypeprefix), prefix, cname, dim, src->Register.Index, swizzle);
3072 }
3073 }
3074 } else {
3075 enum vrend_type_qualifier csp = TYPE_CONVERSION_NONE;
3076 ctx->shader_req_bits |= SHADER_REQ_INTS;
3077 if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1)
3078 csp = IVEC4;
3079 else if (stype == TGSI_TYPE_FLOAT || stype == TGSI_TYPE_UNTYPED)
3080 csp = UINT_BITS_TO_FLOAT;
3081 else if (stype == TGSI_TYPE_SIGNED)
3082 csp = IVEC4;
3083
3084 if (src->Register.Indirect) {
3085 snprintf(srcs[i], 255, "%s%s(%sconst%d[addr0 + %d]%s)", prefix, get_string(csp), cname, dim, src->Register.Index, swizzle);
3086 } else
3087 snprintf(srcs[i], 255, "%s%s(%sconst%d[%d]%s)", prefix, get_string(csp), cname, dim, src->Register.Index, swizzle);
3088 }
3089 } else if (src->Register.File == TGSI_FILE_SAMPLER) {
3090 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3091 if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
3092 int basearrayidx = lookup_sampler_array(ctx, src->Register.Index);
3093 if (src->Register.Indirect) {
3094 snprintf(srcs[i], 255, "%ssamp%d[addr%d+%d]%s", cname, basearrayidx, src->Indirect.Index, src->Register.Index - basearrayidx, swizzle);
3095 } else {
3096 snprintf(srcs[i], 255, "%ssamp%d[%d]%s", cname, basearrayidx, src->Register.Index - basearrayidx, swizzle);
3097 }
3098 } else {
3099 snprintf(srcs[i], 255, "%ssamp%d%s", cname, src->Register.Index, swizzle);
3100 }
3101 sinfo->sreg_index = src->Register.Index;
3102 } else if (src->Register.File == TGSI_FILE_IMAGE) {
3103 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3104 if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
3105 int basearrayidx = lookup_image_array(ctx, src->Register.Index);
3106 if (src->Register.Indirect) {
3107 assert(src->Indirect.File == TGSI_FILE_ADDRESS);
3108 snprintf(srcs[i], 255, "%simg%d[addr%d + %d]", cname, basearrayidx, src->Indirect.Index, src->Register.Index - basearrayidx);
3109 } else
3110 snprintf(srcs[i], 255, "%simg%d[%d]", cname, basearrayidx, src->Register.Index - basearrayidx);
3111 } else
3112 snprintf(srcs[i], 255, "%simg%d%s", cname, src->Register.Index, swizzle);
3113 sinfo->sreg_index = src->Register.Index;
3114 } else if (src->Register.File == TGSI_FILE_BUFFER) {
3115 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
3116 if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
3117 bool atomic_ssbo = ctx->ssbo_atomic_mask & (1 << src->Register.Index);
3118 const char *atomic_str = atomic_ssbo ? "atomic" : "";
3119 int base = atomic_ssbo ? ctx->ssbo_atomic_array_base : ctx->ssbo_array_base;
3120 if (src->Register.Indirect) {
3121 snprintf(srcs[i], 255, "%sssboarr%s[addr%d+%d].%sssbocontents%d%s", cname, atomic_str, src->Indirect.Index, src->Register.Index - base, cname, base, swizzle);
3122 } else {
3123 snprintf(srcs[i], 255, "%sssboarr%s[%d].%sssbocontents%d%s", cname, atomic_str, src->Register.Index - base, cname, base, swizzle);
3124 }
3125 } else {
3126 snprintf(srcs[i], 255, "%sssbocontents%d%s", cname, src->Register.Index, swizzle);
3127 }
3128 sinfo->sreg_index = src->Register.Index;
3129 } else if (src->Register.File == TGSI_FILE_MEMORY) {
3130 snprintf(srcs[i], 255, "values");
3131 sinfo->sreg_index = src->Register.Index;
3132 } else if (src->Register.File == TGSI_FILE_IMMEDIATE) {
3133 if (src->Register.Index >= (int)ARRAY_SIZE(ctx->imm)) {
3134 fprintf(stderr, "Immediate exceeded, max is %lu\n", ARRAY_SIZE(ctx->imm));
3135 return false;
3136 }
3137 struct immed *imd = &ctx->imm[src->Register.Index];
3138 int idx = src->Register.SwizzleX;
3139 char temp[48];
3140 enum vrend_type_qualifier vtype = VEC4;
3141 enum vrend_type_qualifier imm_stypeprefix = stypeprefix;
3142
3143 if ((inst->Instruction.Opcode == TGSI_OPCODE_TG4 && i == 1) ||
3144 (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1))
3145 stype = TGSI_TYPE_SIGNED;
3146
3147 if (imd->type == TGSI_IMM_UINT32 || imd->type == TGSI_IMM_INT32) {
3148 if (imd->type == TGSI_IMM_UINT32)
3149 vtype = UVEC4;
3150 else
3151 vtype = IVEC4;
3152
3153 if (stype == TGSI_TYPE_UNSIGNED && imd->type == TGSI_IMM_INT32)
3154 imm_stypeprefix = UVEC4;
3155 else if (stype == TGSI_TYPE_SIGNED && imd->type == TGSI_IMM_UINT32)
3156 imm_stypeprefix = IVEC4;
3157 else if (stype == TGSI_TYPE_FLOAT || stype == TGSI_TYPE_UNTYPED) {
3158 if (imd->type == TGSI_IMM_INT32)
3159 imm_stypeprefix = INT_BITS_TO_FLOAT;
3160 else
3161 imm_stypeprefix = UINT_BITS_TO_FLOAT;
3162 } else if (stype == TGSI_TYPE_UNSIGNED || stype == TGSI_TYPE_SIGNED)
3163 imm_stypeprefix = TYPE_CONVERSION_NONE;
3164 } else if (imd->type == TGSI_IMM_FLOAT64) {
3165 vtype = UVEC4;
3166 if (stype == TGSI_TYPE_DOUBLE)
3167 imm_stypeprefix = TYPE_CONVERSION_NONE;
3168 else
3169 imm_stypeprefix = UINT_BITS_TO_FLOAT;
3170 }
3171
3172 /* build up a vec4 of immediates */
3173 snprintf(srcs[i], 255, "%s(%s%s(", get_string(imm_stypeprefix), prefix, get_string(vtype));
3174 for (uint32_t j = 0; j < 4; j++) {
3175 if (j == 0)
3176 idx = src->Register.SwizzleX;
3177 else if (j == 1)
3178 idx = src->Register.SwizzleY;
3179 else if (j == 2)
3180 idx = src->Register.SwizzleZ;
3181 else if (j == 3)
3182 idx = src->Register.SwizzleW;
3183
3184 if (inst->Instruction.Opcode == TGSI_OPCODE_TG4 && i == 1 && j == 0) {
3185 if (imd->val[idx].ui > 0) {
3186 sinfo->tg4_has_component = true;
3187 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3188 }
3189 }
3190
3191 switch (imd->type) {
3192 case TGSI_IMM_FLOAT32:
3193 if (isinf(imd->val[idx].f) || isnan(imd->val[idx].f)) {
3194 ctx->shader_req_bits |= SHADER_REQ_INTS;
3195 snprintf(temp, 48, "uintBitsToFloat(%uU)", imd->val[idx].ui);
3196 } else
3197 snprintf(temp, 25, "%.8g", imd->val[idx].f);
3198 break;
3199 case TGSI_IMM_UINT32:
3200 snprintf(temp, 25, "%uU", imd->val[idx].ui);
3201 break;
3202 case TGSI_IMM_INT32:
3203 snprintf(temp, 25, "%d", imd->val[idx].i);
3204 break;
3205 case TGSI_IMM_FLOAT64:
3206 snprintf(temp, 48, "%uU", imd->val[idx].ui);
3207 break;
3208 default:
3209 fprintf(stderr, "unhandled imm type: %x\n", imd->type);
3210 return false;
3211 }
3212 strncat(srcs[i], temp, 255);
3213 if (j < 3)
3214 strcat(srcs[i], ",");
3215 else {
3216 snprintf(temp, 4, "))%c", isfloatabsolute ? ')' : 0);
3217 strncat(srcs[i], temp, 255);
3218 }
3219 }
3220 } else if (src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
3221 for (uint32_t j = 0; j < ctx->num_system_values; j++)
3222 if (ctx->system_values[j].first == src->Register.Index) {
3223 if (ctx->system_values[j].name == TGSI_SEMANTIC_VERTEXID ||
3224 ctx->system_values[j].name == TGSI_SEMANTIC_INSTANCEID ||
3225 ctx->system_values[j].name == TGSI_SEMANTIC_PRIMID ||
3226 ctx->system_values[j].name == TGSI_SEMANTIC_VERTICESIN ||
3227 ctx->system_values[j].name == TGSI_SEMANTIC_INVOCATIONID ||
3228 ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEID) {
3229 if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE && i == 1)
3230 snprintf(srcs[i], 255, "ivec4(%s)", ctx->system_values[j].glsl_name);
3231 else
3232 snprintf(srcs[i], 255, "%s(vec4(intBitsToFloat(%s)))", get_string(stypeprefix), ctx->system_values[j].glsl_name);
3233 } else if (ctx->system_values[j].name == TGSI_SEMANTIC_HELPER_INVOCATION) {
3234 snprintf(srcs[i], 255, "uvec4(%s)", ctx->system_values[j].glsl_name);
3235 } else if (ctx->system_values[j].name == TGSI_SEMANTIC_TESSINNER ||
3236 ctx->system_values[j].name == TGSI_SEMANTIC_TESSOUTER) {
3237 snprintf(srcs[i], 255, "%s(vec4(%s[%d], %s[%d], %s[%d], %s[%d]))",
3238 prefix,
3239 ctx->system_values[j].glsl_name, src->Register.SwizzleX,
3240 ctx->system_values[j].glsl_name, src->Register.SwizzleY,
3241 ctx->system_values[j].glsl_name, src->Register.SwizzleZ,
3242 ctx->system_values[j].glsl_name, src->Register.SwizzleW);
3243 } else if (ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEPOS ||
3244 ctx->system_values[j].name == TGSI_SEMANTIC_TESSCOORD) {
3245 snprintf(srcs[i], 255, "%s(vec4(%s.%c, %s.%c, %s.%c, %s.%c))",
3246 prefix,
3247 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleX),
3248 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleY),
3249 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleZ),
3250 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleW));
3251 } else if (ctx->system_values[j].name == TGSI_SEMANTIC_GRID_SIZE ||
3252 ctx->system_values[j].name == TGSI_SEMANTIC_THREAD_ID ||
3253 ctx->system_values[j].name == TGSI_SEMANTIC_BLOCK_ID) {
3254 snprintf(srcs[i], 255, "uvec4(%s.%c, %s.%c, %s.%c, %s.%c)",
3255 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleX),
3256 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleY),
3257 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleZ),
3258 ctx->system_values[j].glsl_name, get_swiz_char(src->Register.SwizzleW));
3259 sinfo->override_no_cast[i] = true;
3260 } else if (ctx->system_values[j].name == TGSI_SEMANTIC_SAMPLEMASK) {
3261 snprintf(srcs[i], 255, "ivec4(%s, %s, %s, %s)",
3262 src->Register.SwizzleX == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0",
3263 src->Register.SwizzleY == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0",
3264 src->Register.SwizzleZ == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0",
3265 src->Register.SwizzleW == TGSI_SWIZZLE_X ? ctx->system_values[j].glsl_name : "0");
3266 } else
3267 snprintf(srcs[i], 255, "%s%s", prefix, ctx->system_values[j].glsl_name);
3268 sinfo->override_no_wm[i] = ctx->system_values[j].override_no_wm;
3269 break;
3270 }
3271 }
3272
3273 if (stype == TGSI_TYPE_DOUBLE) {
3274 boolean isabsolute = src->Register.Absolute;
3275 char buf[512];
3276 strcpy(fp64_src, srcs[i]);
3277 snprintf(srcs[i], 255, "fp64_src[%d]", i);
3278 snprintf(buf, 255, "%s.x = %spackDouble2x32(uvec2(%s%s))%s;\n", srcs[i], isabsolute ? "abs(" : "", fp64_src, swizzle, isabsolute ? ")" : "");
3279 EMIT_BUF_WITH_RET(ctx, buf);
3280 }
3281 }
3282
3283 return 0;
3284 }
3285
3286 static boolean
iter_instruction(struct tgsi_iterate_context * iter,struct tgsi_full_instruction * inst)3287 iter_instruction(struct tgsi_iterate_context *iter,
3288 struct tgsi_full_instruction *inst)
3289 {
3290 struct dump_ctx *ctx = (struct dump_ctx *)iter;
3291 struct dest_info dinfo = { 0 };
3292 struct source_info sinfo = { 0 };
3293 char srcs[4][255], dsts[3][255], buf[512];
3294 char fp64_dsts[3][255];
3295 uint instno = ctx->instno++;
3296 char writemask[6] = {0};
3297 char *sret;
3298 int ret;
3299 char src_swizzle0[10];
3300
3301 sinfo.svec4 = VEC4;
3302
3303 if (ctx->prog_type == -1)
3304 ctx->prog_type = iter->processor.Processor;
3305
3306 if (instno == 0) {
3307 sret = add_str_to_glsl_main(ctx, "void main(void)\n{\n");
3308 if (!sret)
3309 return FALSE;
3310 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
3311 ret = emit_color_select(ctx);
3312 if (ret)
3313 return FALSE;
3314 }
3315 if (ctx->so)
3316 prepare_so_movs(ctx);
3317 }
3318
3319 ret = get_destination_info(ctx, inst, &dinfo, dsts, fp64_dsts, writemask);
3320 if (ret)
3321 return FALSE;
3322
3323 ret = get_source_info(ctx, inst, &sinfo, srcs, src_swizzle0);
3324 if (ret)
3325 return FALSE;
3326
3327 switch (inst->Instruction.Opcode) {
3328 case TGSI_OPCODE_SQRT:
3329 case TGSI_OPCODE_DSQRT:
3330 snprintf(buf, 255, "%s = sqrt(vec4(%s))%s;\n", dsts[0], srcs[0], writemask);
3331 EMIT_BUF_WITH_RET(ctx, buf);
3332 break;
3333 case TGSI_OPCODE_LRP:
3334 snprintf(buf, 255, "%s = mix(vec4(%s), vec4(%s), vec4(%s))%s;\n", dsts[0], srcs[2], srcs[1], srcs[0], writemask);
3335 EMIT_BUF_WITH_RET(ctx, buf);
3336 break;
3337 case TGSI_OPCODE_DP2:
3338 snprintf(buf, 255, "%s = %s(dot(vec2(%s), vec2(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
3339 EMIT_BUF_WITH_RET(ctx, buf);
3340 break;
3341 case TGSI_OPCODE_DP3:
3342 snprintf(buf, 255, "%s = %s(dot(vec3(%s), vec3(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
3343 EMIT_BUF_WITH_RET(ctx, buf);
3344 break;
3345 case TGSI_OPCODE_DP4:
3346 snprintf(buf, 255, "%s = %s(dot(vec4(%s), vec4(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
3347 EMIT_BUF_WITH_RET(ctx, buf);
3348 break;
3349 case TGSI_OPCODE_DPH:
3350 snprintf(buf, 255, "%s = %s(dot(vec4(vec3(%s), 1.0), vec4(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
3351 EMIT_BUF_WITH_RET(ctx, buf);
3352 break;
3353 case TGSI_OPCODE_MAX:
3354 case TGSI_OPCODE_DMAX:
3355 case TGSI_OPCODE_IMAX:
3356 case TGSI_OPCODE_UMAX:
3357 snprintf(buf, 255, "%s = %s(%s(max(%s, %s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1]);
3358 EMIT_BUF_WITH_RET(ctx, buf);
3359 break;
3360 case TGSI_OPCODE_MIN:
3361 case TGSI_OPCODE_DMIN:
3362 case TGSI_OPCODE_IMIN:
3363 case TGSI_OPCODE_UMIN:
3364 snprintf(buf, 255, "%s = %s(%s(min(%s, %s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1]);
3365 EMIT_BUF_WITH_RET(ctx, buf);
3366 break;
3367 case TGSI_OPCODE_ABS:
3368 case TGSI_OPCODE_IABS:
3369 case TGSI_OPCODE_DABS:
3370 emit_op1("abs");
3371 EMIT_BUF_WITH_RET(ctx, buf);
3372 break;
3373 case TGSI_OPCODE_KILL_IF:
3374 snprintf(buf, 255, "if (any(lessThan(%s, vec4(0.0))))\ndiscard;\n", srcs[0]);
3375 EMIT_BUF_WITH_RET(ctx, buf);
3376 break;
3377 case TGSI_OPCODE_IF:
3378 case TGSI_OPCODE_UIF:
3379 snprintf(buf, 255, "if (any(bvec4(%s))) {\n", srcs[0]);
3380 EMIT_BUF_WITH_RET(ctx, buf);
3381 ctx->indent_level++;
3382 break;
3383 case TGSI_OPCODE_ELSE:
3384 snprintf(buf, 255, "} else {\n");
3385 ctx->indent_level--;
3386 EMIT_BUF_WITH_RET(ctx, buf);
3387 ctx->indent_level++;
3388 break;
3389 case TGSI_OPCODE_ENDIF:
3390 snprintf(buf, 255, "}\n");
3391 ctx->indent_level--;
3392 EMIT_BUF_WITH_RET(ctx, buf);
3393 break;
3394 case TGSI_OPCODE_KILL:
3395 snprintf(buf, 255, "discard;\n");
3396 EMIT_BUF_WITH_RET(ctx, buf);
3397 break;
3398 case TGSI_OPCODE_DST:
3399 snprintf(buf, 512, "%s = vec4(1.0, %s.y * %s.y, %s.z, %s.w);\n", dsts[0],
3400 srcs[0], srcs[1], srcs[0], srcs[1]);
3401 EMIT_BUF_WITH_RET(ctx, buf);
3402 break;
3403 case TGSI_OPCODE_LIT:
3404 snprintf(buf, 512, "%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);
3405 EMIT_BUF_WITH_RET(ctx, buf);
3406 break;
3407 case TGSI_OPCODE_EX2:
3408 emit_op1("exp2");
3409 EMIT_BUF_WITH_RET(ctx, buf);
3410 break;
3411 case TGSI_OPCODE_LG2:
3412 emit_op1("log2");
3413 EMIT_BUF_WITH_RET(ctx, buf);
3414 break;
3415 case TGSI_OPCODE_EXP:
3416 snprintf(buf, 512, "%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);
3417 EMIT_BUF_WITH_RET(ctx, buf);
3418 break;
3419 case TGSI_OPCODE_LOG:
3420 snprintf(buf, 512, "%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);
3421 EMIT_BUF_WITH_RET(ctx, buf);
3422 break;
3423 case TGSI_OPCODE_COS:
3424 emit_op1("cos");
3425 EMIT_BUF_WITH_RET(ctx, buf);
3426 break;
3427 case TGSI_OPCODE_SIN:
3428 emit_op1("sin");
3429 EMIT_BUF_WITH_RET(ctx, buf);
3430 break;
3431 case TGSI_OPCODE_SCS:
3432 snprintf(buf, 255, "%s = %s(vec4(cos(%s.x), sin(%s.x), 0, 1)%s);\n", dsts[0], get_string(dinfo.dstconv),
3433 srcs[0], srcs[0], writemask);
3434 EMIT_BUF_WITH_RET(ctx, buf);
3435 break;
3436 case TGSI_OPCODE_DDX:
3437 emit_op1("dFdx");
3438 EMIT_BUF_WITH_RET(ctx, buf);
3439 break;
3440 case TGSI_OPCODE_DDY:
3441 emit_op1("dFdy");
3442 EMIT_BUF_WITH_RET(ctx, buf);
3443 break;
3444 case TGSI_OPCODE_DDX_FINE:
3445 ctx->shader_req_bits |= SHADER_REQ_DERIVATIVE_CONTROL;
3446 emit_op1("dFdxFine");
3447 EMIT_BUF_WITH_RET(ctx, buf);
3448 break;
3449 case TGSI_OPCODE_DDY_FINE:
3450 ctx->shader_req_bits |= SHADER_REQ_DERIVATIVE_CONTROL;
3451 emit_op1("dFdyFine");
3452 EMIT_BUF_WITH_RET(ctx, buf);
3453 break;
3454 case TGSI_OPCODE_RCP:
3455 snprintf(buf, 255, "%s = %s(1.0/(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
3456 EMIT_BUF_WITH_RET(ctx, buf);
3457 break;
3458 case TGSI_OPCODE_DRCP:
3459 snprintf(buf, 255, "%s = %s(1.0LF/(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
3460 EMIT_BUF_WITH_RET(ctx, buf);
3461 break;
3462 case TGSI_OPCODE_FLR:
3463 emit_op1("floor");
3464 EMIT_BUF_WITH_RET(ctx, buf);
3465 break;
3466 case TGSI_OPCODE_ROUND:
3467 emit_op1("round");
3468 EMIT_BUF_WITH_RET(ctx, buf);
3469 break;
3470 case TGSI_OPCODE_ISSG:
3471 emit_op1("sign");
3472 EMIT_BUF_WITH_RET(ctx, buf);
3473 break;
3474 case TGSI_OPCODE_CEIL:
3475 emit_op1("ceil");
3476 EMIT_BUF_WITH_RET(ctx, buf);
3477 break;
3478 case TGSI_OPCODE_FRC:
3479 case TGSI_OPCODE_DFRAC:
3480 emit_op1("fract");
3481 EMIT_BUF_WITH_RET(ctx, buf);
3482 break;
3483 case TGSI_OPCODE_TRUNC:
3484 emit_op1("trunc");
3485 EMIT_BUF_WITH_RET(ctx, buf);
3486 break;
3487 case TGSI_OPCODE_SSG:
3488 emit_op1("sign");
3489 EMIT_BUF_WITH_RET(ctx, buf);
3490 break;
3491 case TGSI_OPCODE_RSQ:
3492 case TGSI_OPCODE_DRSQ:
3493 snprintf(buf, 255, "%s = %s(inversesqrt(%s.x));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
3494 EMIT_BUF_WITH_RET(ctx, buf);
3495 break;
3496 case TGSI_OPCODE_FBFETCH:
3497 case TGSI_OPCODE_MOV:
3498 snprintf(buf, 255, "%s = %s(%s(%s%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], sinfo.override_no_wm[0] ? "" : writemask);
3499 EMIT_BUF_WITH_RET(ctx, buf);
3500 break;
3501 case TGSI_OPCODE_ADD:
3502 case TGSI_OPCODE_DADD:
3503 emit_arit_op2("+");
3504 EMIT_BUF_WITH_RET(ctx, buf);
3505 break;
3506 case TGSI_OPCODE_UADD:
3507 snprintf(buf, 512, "%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);
3508 EMIT_BUF_WITH_RET(ctx, buf);
3509 break;
3510 case TGSI_OPCODE_SUB:
3511 emit_arit_op2("-");
3512 EMIT_BUF_WITH_RET(ctx, buf);
3513 break;
3514 case TGSI_OPCODE_MUL:
3515 case TGSI_OPCODE_DMUL:
3516 emit_arit_op2("*");
3517 EMIT_BUF_WITH_RET(ctx, buf);
3518 break;
3519 case TGSI_OPCODE_DIV:
3520 case TGSI_OPCODE_DDIV:
3521 emit_arit_op2("/");
3522 EMIT_BUF_WITH_RET(ctx, buf);
3523 break;
3524 case TGSI_OPCODE_UMUL:
3525 snprintf(buf, 512, "%s = %s(%s((uvec4(%s) * uvec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
3526 EMIT_BUF_WITH_RET(ctx, buf);
3527 break;
3528 case TGSI_OPCODE_UMOD:
3529 snprintf(buf, 255, "%s = %s(%s((uvec4(%s) %% uvec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
3530 EMIT_BUF_WITH_RET(ctx, buf);
3531 break;
3532 case TGSI_OPCODE_IDIV:
3533 snprintf(buf, 255, "%s = %s(%s((ivec4(%s) / ivec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
3534 EMIT_BUF_WITH_RET(ctx, buf);
3535 break;
3536 case TGSI_OPCODE_UDIV:
3537 snprintf(buf, 255, "%s = %s(%s((uvec4(%s) / uvec4(%s)))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], srcs[1], writemask);
3538 EMIT_BUF_WITH_RET(ctx, buf);
3539 break;
3540 case TGSI_OPCODE_ISHR:
3541 case TGSI_OPCODE_USHR:
3542 emit_arit_op2(">>");
3543 EMIT_BUF_WITH_RET(ctx, buf);
3544 break;
3545 case TGSI_OPCODE_SHL:
3546 emit_arit_op2("<<");
3547 EMIT_BUF_WITH_RET(ctx, buf);
3548 break;
3549 case TGSI_OPCODE_MAD:
3550 snprintf(buf, 255, "%s = %s((%s * %s + %s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1], srcs[2], writemask);
3551 EMIT_BUF_WITH_RET(ctx, buf);
3552 break;
3553 case TGSI_OPCODE_UMAD:
3554 case TGSI_OPCODE_DMAD:
3555 snprintf(buf, 512, "%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);
3556 EMIT_BUF_WITH_RET(ctx, buf);
3557 break;
3558 case TGSI_OPCODE_OR:
3559 emit_arit_op2("|");
3560 EMIT_BUF_WITH_RET(ctx, buf);
3561 break;
3562 case TGSI_OPCODE_AND:
3563 emit_arit_op2("&");
3564 EMIT_BUF_WITH_RET(ctx, buf);
3565 break;
3566 case TGSI_OPCODE_XOR:
3567 emit_arit_op2("^");
3568 EMIT_BUF_WITH_RET(ctx, buf);
3569 break;
3570 case TGSI_OPCODE_MOD:
3571 emit_arit_op2("%");
3572 EMIT_BUF_WITH_RET(ctx, buf);
3573 break;
3574 case TGSI_OPCODE_TEX:
3575 case TGSI_OPCODE_TEX2:
3576 case TGSI_OPCODE_TXB:
3577 case TGSI_OPCODE_TXL:
3578 case TGSI_OPCODE_TXB2:
3579 case TGSI_OPCODE_TXL2:
3580 case TGSI_OPCODE_TXD:
3581 case TGSI_OPCODE_TXF:
3582 case TGSI_OPCODE_TG4:
3583 case TGSI_OPCODE_TXP:
3584 case TGSI_OPCODE_LODQ:
3585 ret = translate_tex(ctx, inst, &sinfo, &dinfo, srcs, dsts, writemask);
3586 if (ret)
3587 return FALSE;
3588 break;
3589 case TGSI_OPCODE_TXQ:
3590 ret = emit_txq(ctx, inst, sinfo.sreg_index, srcs, dsts, writemask);
3591 if (ret)
3592 return FALSE;
3593 break;
3594 case TGSI_OPCODE_TXQS:
3595 ret = emit_txqs(ctx, inst, sinfo.sreg_index, srcs, dsts);
3596 if (ret)
3597 return FALSE;
3598 break;
3599 case TGSI_OPCODE_I2F:
3600 snprintf(buf, 255, "%s = %s(ivec4(%s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], writemask);
3601 EMIT_BUF_WITH_RET(ctx, buf);
3602 break;
3603 case TGSI_OPCODE_I2D:
3604 snprintf(buf, 255, "%s = %s(ivec4(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
3605 EMIT_BUF_WITH_RET(ctx, buf);
3606 break;
3607 case TGSI_OPCODE_D2F:
3608 snprintf(buf, 255, "%s = %s(%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
3609 EMIT_BUF_WITH_RET(ctx, buf);
3610 break;
3611 case TGSI_OPCODE_U2F:
3612 snprintf(buf, 255, "%s = %s(uvec4(%s)%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0], writemask);
3613 EMIT_BUF_WITH_RET(ctx, buf);
3614 break;
3615 case TGSI_OPCODE_U2D:
3616 snprintf(buf, 255, "%s = %s(uvec4(%s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
3617 EMIT_BUF_WITH_RET(ctx, buf);
3618 break;
3619 case TGSI_OPCODE_F2I:
3620 snprintf(buf, 255, "%s = %s(%s(ivec4(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], writemask);
3621 EMIT_BUF_WITH_RET(ctx, buf);
3622 break;
3623 case TGSI_OPCODE_D2I:
3624 snprintf(buf, 255, "%s = %s(%s(%s(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), get_string(dinfo.idstconv), srcs[0]);
3625 EMIT_BUF_WITH_RET(ctx, buf);
3626 break;
3627 case TGSI_OPCODE_F2U:
3628 snprintf(buf, 255, "%s = %s(%s(uvec4(%s))%s);\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], writemask);
3629 EMIT_BUF_WITH_RET(ctx, buf);
3630 break;
3631 case TGSI_OPCODE_D2U:
3632 snprintf(buf, 255, "%s = %s(%s(%s(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), get_string(dinfo.udstconv), srcs[0]);
3633 EMIT_BUF_WITH_RET(ctx, buf);
3634 break;
3635 case TGSI_OPCODE_F2D:
3636 snprintf(buf, 255, "%s = %s(%s(%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
3637 EMIT_BUF_WITH_RET(ctx, buf);
3638 break;
3639 case TGSI_OPCODE_NOT:
3640 snprintf(buf, 255, "%s = %s(uintBitsToFloat(~(uvec4(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
3641 EMIT_BUF_WITH_RET(ctx, buf);
3642 break;
3643 case TGSI_OPCODE_INEG:
3644 snprintf(buf, 255, "%s = %s(intBitsToFloat(-(ivec4(%s))));\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
3645 EMIT_BUF_WITH_RET(ctx, buf);
3646 break;
3647 case TGSI_OPCODE_DNEG:
3648 snprintf(buf, 255, "%s = %s(-%s);\n", dsts[0], get_string(dinfo.dstconv), srcs[0]);
3649 EMIT_BUF_WITH_RET(ctx, buf);
3650 break;
3651 case TGSI_OPCODE_SEQ:
3652 emit_compare("equal");
3653 EMIT_BUF_WITH_RET(ctx, buf);
3654 break;
3655 case TGSI_OPCODE_USEQ:
3656 case TGSI_OPCODE_FSEQ:
3657 case TGSI_OPCODE_DSEQ:
3658 if (inst->Instruction.Opcode == TGSI_OPCODE_DSEQ)
3659 strcpy(writemask, ".x");
3660 emit_ucompare("equal");
3661 EMIT_BUF_WITH_RET(ctx, buf);
3662 break;
3663 case TGSI_OPCODE_SLT:
3664 emit_compare("lessThan");
3665 EMIT_BUF_WITH_RET(ctx, buf);
3666 break;
3667 case TGSI_OPCODE_ISLT:
3668 case TGSI_OPCODE_USLT:
3669 case TGSI_OPCODE_FSLT:
3670 case TGSI_OPCODE_DSLT:
3671 if (inst->Instruction.Opcode == TGSI_OPCODE_DSLT)
3672 strcpy(writemask, ".x");
3673 emit_ucompare("lessThan");
3674 EMIT_BUF_WITH_RET(ctx, buf);
3675 break;
3676 case TGSI_OPCODE_SNE:
3677 emit_compare("notEqual");
3678 EMIT_BUF_WITH_RET(ctx, buf);
3679 break;
3680 case TGSI_OPCODE_USNE:
3681 case TGSI_OPCODE_FSNE:
3682 case TGSI_OPCODE_DSNE:
3683 if (inst->Instruction.Opcode == TGSI_OPCODE_DSNE)
3684 strcpy(writemask, ".x");
3685 emit_ucompare("notEqual");
3686 EMIT_BUF_WITH_RET(ctx, buf);
3687 break;
3688 case TGSI_OPCODE_SGE:
3689 emit_compare("greaterThanEqual");
3690 EMIT_BUF_WITH_RET(ctx, buf);
3691 break;
3692 case TGSI_OPCODE_ISGE:
3693 case TGSI_OPCODE_USGE:
3694 case TGSI_OPCODE_FSGE:
3695 case TGSI_OPCODE_DSGE:
3696 if (inst->Instruction.Opcode == TGSI_OPCODE_DSGE)
3697 strcpy(writemask, ".x");
3698 emit_ucompare("greaterThanEqual");
3699 EMIT_BUF_WITH_RET(ctx, buf);
3700 break;
3701 case TGSI_OPCODE_POW:
3702 snprintf(buf, 255, "%s = %s(pow(%s, %s));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
3703 EMIT_BUF_WITH_RET(ctx, buf);
3704 break;
3705 case TGSI_OPCODE_CMP:
3706 snprintf(buf, 255, "%s = mix(%s, %s, greaterThanEqual(%s, vec4(0.0)))%s;\n", dsts[0], srcs[1], srcs[2], srcs[0], writemask);
3707 EMIT_BUF_WITH_RET(ctx, buf);
3708 break;
3709 case TGSI_OPCODE_UCMP:
3710 snprintf(buf, 512, "%s = mix(%s, %s, notEqual(floatBitsToUint(%s), uvec4(0.0)))%s;\n", dsts[0], srcs[2], srcs[1], srcs[0], writemask);
3711 EMIT_BUF_WITH_RET(ctx, buf);
3712 break;
3713 case TGSI_OPCODE_END:
3714 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
3715 if (handle_vertex_proc_exit(ctx) == FALSE)
3716 return FALSE;
3717 } else if (iter->processor.Processor == TGSI_PROCESSOR_TESS_CTRL) {
3718 ret = emit_clip_dist_movs(ctx);
3719 if (ret)
3720 return FALSE;
3721 } else if (iter->processor.Processor == TGSI_PROCESSOR_TESS_EVAL) {
3722 if (ctx->so && !ctx->key->gs_present)
3723 if (emit_so_movs(ctx))
3724 return FALSE;
3725 ret = emit_clip_dist_movs(ctx);
3726 if (ret)
3727 return FALSE;
3728 if (!ctx->key->gs_present) {
3729 ret = emit_prescale(ctx);
3730 if (ret)
3731 return FALSE;
3732 }
3733 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
3734 if (handle_fragment_proc_exit(ctx) == FALSE)
3735 return FALSE;
3736 }
3737 sret = add_str_to_glsl_main(ctx, "}\n");
3738 if (!sret)
3739 return FALSE;
3740 break;
3741 case TGSI_OPCODE_RET:
3742 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX) {
3743 if (handle_vertex_proc_exit(ctx) == FALSE)
3744 return FALSE;
3745 } else if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
3746 if (handle_fragment_proc_exit(ctx) == FALSE)
3747 return FALSE;
3748 }
3749 EMIT_BUF_WITH_RET(ctx, "return;\n");
3750 break;
3751 case TGSI_OPCODE_ARL:
3752 snprintf(buf, 255, "%s = int(floor(%s)%s);\n", dsts[0], srcs[0], writemask);
3753 EMIT_BUF_WITH_RET(ctx, buf);
3754 break;
3755 case TGSI_OPCODE_UARL:
3756 snprintf(buf, 255, "%s = int(%s);\n", dsts[0], srcs[0]);
3757 EMIT_BUF_WITH_RET(ctx, buf);
3758 break;
3759 case TGSI_OPCODE_XPD:
3760 snprintf(buf, 255, "%s = %s(cross(vec3(%s), vec3(%s)));\n", dsts[0], get_string(dinfo.dstconv), srcs[0], srcs[1]);
3761 EMIT_BUF_WITH_RET(ctx, buf);
3762 break;
3763 case TGSI_OPCODE_BGNLOOP:
3764 snprintf(buf, 255, "do {\n");
3765 EMIT_BUF_WITH_RET(ctx, buf);
3766 ctx->indent_level++;
3767 break;
3768 case TGSI_OPCODE_ENDLOOP:
3769 ctx->indent_level--;
3770 snprintf(buf, 255, "} while(true);\n");
3771 EMIT_BUF_WITH_RET(ctx, buf);
3772 break;
3773 case TGSI_OPCODE_BRK:
3774 snprintf(buf, 255, "break;\n");
3775 EMIT_BUF_WITH_RET(ctx, buf);
3776 break;
3777 case TGSI_OPCODE_EMIT: {
3778 struct immed *imd = &ctx->imm[(inst->Src[0].Register.Index)];
3779 if (ctx->so && ctx->key->gs_present) {
3780 emit_so_movs(ctx);
3781 }
3782 ret = emit_clip_dist_movs(ctx);
3783 if (ret)
3784 return FALSE;
3785 ret = emit_prescale(ctx);
3786 if (ret)
3787 return FALSE;
3788 if (imd->val[inst->Src[0].Register.SwizzleX].ui > 0) {
3789 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3790 snprintf(buf, 255, "EmitStreamVertex(%d);\n", imd->val[inst->Src[0].Register.SwizzleX].ui);
3791 } else
3792 snprintf(buf, 255, "EmitVertex();\n");
3793 EMIT_BUF_WITH_RET(ctx, buf);
3794 break;
3795 }
3796 case TGSI_OPCODE_ENDPRIM: {
3797 struct immed *imd = &ctx->imm[(inst->Src[0].Register.Index)];
3798 if (imd->val[inst->Src[0].Register.SwizzleX].ui > 0) {
3799 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3800 snprintf(buf, 255, "EndStreamPrimitive(%d);\n", imd->val[inst->Src[0].Register.SwizzleX].ui);
3801 } else
3802 snprintf(buf, 255, "EndPrimitive();\n");
3803 EMIT_BUF_WITH_RET(ctx, buf);
3804 break;
3805 }
3806 case TGSI_OPCODE_INTERP_CENTROID:
3807 snprintf(buf, 255, "%s = %s(%s(vec4(interpolateAtCentroid(%s))%s));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0], src_swizzle0);
3808 EMIT_BUF_WITH_RET(ctx, buf);
3809 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3810 break;
3811 case TGSI_OPCODE_INTERP_SAMPLE:
3812 snprintf(buf, 255, "%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);
3813 EMIT_BUF_WITH_RET(ctx, buf);
3814 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3815 break;
3816 case TGSI_OPCODE_INTERP_OFFSET:
3817 snprintf(buf, 255, "%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);
3818 EMIT_BUF_WITH_RET(ctx, buf);
3819 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3820 break;
3821 case TGSI_OPCODE_UMUL_HI:
3822 snprintf(buf, 255, "umulExtended(%s, %s, umul_temp, mul_utemp);\n", srcs[0], srcs[1]);
3823 EMIT_BUF_WITH_RET(ctx, buf);
3824 snprintf(buf, 255, "%s = %s(%s(umul_temp));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix));
3825 EMIT_BUF_WITH_RET(ctx, buf);
3826 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3827 ctx->write_mul_utemp = true;
3828 break;
3829 case TGSI_OPCODE_IMUL_HI:
3830 snprintf(buf, 255, "imulExtended(%s, %s, imul_temp, mul_itemp);\n", srcs[0], srcs[1]);
3831 EMIT_BUF_WITH_RET(ctx, buf);
3832 snprintf(buf, 255, "%s = %s(%s(imul_temp));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix));
3833 EMIT_BUF_WITH_RET(ctx, buf);
3834 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3835 ctx->write_mul_itemp = true;
3836 break;
3837
3838 case TGSI_OPCODE_IBFE:
3839 snprintf(buf, 255, "%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]);
3840 EMIT_BUF_WITH_RET(ctx, buf);
3841 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3842 break;
3843 case TGSI_OPCODE_UBFE:
3844 snprintf(buf, 255, "%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]);
3845 EMIT_BUF_WITH_RET(ctx, buf);
3846 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3847 break;
3848 case TGSI_OPCODE_BFI:
3849 snprintf(buf, 255, "%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]);
3850 EMIT_BUF_WITH_RET(ctx, buf);
3851 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3852 break;
3853 case TGSI_OPCODE_BREV:
3854 snprintf(buf, 255, "%s = %s(%s(bitfieldReverse(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
3855 EMIT_BUF_WITH_RET(ctx, buf);
3856 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3857 break;
3858 case TGSI_OPCODE_POPC:
3859 snprintf(buf, 255, "%s = %s(%s(bitCount(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
3860 EMIT_BUF_WITH_RET(ctx, buf);
3861 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3862 break;
3863 case TGSI_OPCODE_LSB:
3864 snprintf(buf, 255, "%s = %s(%s(findLSB(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
3865 EMIT_BUF_WITH_RET(ctx, buf);
3866 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3867 break;
3868 case TGSI_OPCODE_IMSB:
3869 case TGSI_OPCODE_UMSB:
3870 snprintf(buf, 255, "%s = %s(%s(findMSB(%s)));\n", dsts[0], get_string(dinfo.dstconv), get_string(dinfo.dtypeprefix), srcs[0]);
3871 EMIT_BUF_WITH_RET(ctx, buf);
3872 ctx->shader_req_bits |= SHADER_REQ_GPU_SHADER5;
3873 break;
3874 case TGSI_OPCODE_BARRIER:
3875 snprintf(buf, 255, "barrier();\n");
3876 EMIT_BUF_WITH_RET(ctx, buf);
3877 break;
3878 case TGSI_OPCODE_MEMBAR: {
3879 struct immed *imd = &ctx->imm[(inst->Src[0].Register.Index)];
3880 uint32_t val = imd->val[inst->Src[0].Register.SwizzleX].ui;
3881 uint32_t all_val = (TGSI_MEMBAR_SHADER_BUFFER |
3882 TGSI_MEMBAR_ATOMIC_BUFFER |
3883 TGSI_MEMBAR_SHADER_IMAGE |
3884 TGSI_MEMBAR_SHARED);
3885
3886 if (val & TGSI_MEMBAR_THREAD_GROUP) {
3887 snprintf(buf, 255, "groupMemoryBarrier();\n");
3888 EMIT_BUF_WITH_RET(ctx, buf);
3889 } else {
3890 if ((val & all_val) == all_val) {
3891 snprintf(buf, 255, "memoryBarrier();\n");
3892 EMIT_BUF_WITH_RET(ctx, buf);
3893 } else {
3894 if (val & TGSI_MEMBAR_SHADER_BUFFER) {
3895 snprintf(buf, 255, "memoryBarrierBuffer();\n");
3896 EMIT_BUF_WITH_RET(ctx, buf);
3897 }
3898 if (val & TGSI_MEMBAR_ATOMIC_BUFFER) {
3899 snprintf(buf, 255, "memoryBarrierAtomic();\n");
3900 EMIT_BUF_WITH_RET(ctx, buf);
3901 }
3902 if (val & TGSI_MEMBAR_SHADER_IMAGE) {
3903 snprintf(buf, 255, "memoryBarrierImage();\n");
3904 EMIT_BUF_WITH_RET(ctx, buf);
3905 }
3906 if (val & TGSI_MEMBAR_SHARED) {
3907 snprintf(buf, 255, "memoryBarrierShared();\n");
3908 EMIT_BUF_WITH_RET(ctx, buf);
3909 }
3910 }
3911 }
3912 break;
3913 }
3914 case TGSI_OPCODE_STORE:
3915 ret = translate_store(ctx, inst, &sinfo, srcs, dsts);
3916 if (ret)
3917 return FALSE;
3918 break;
3919 case TGSI_OPCODE_LOAD:
3920 ret = translate_load(ctx, inst, &sinfo, &dinfo, srcs, dsts, writemask);
3921 if (ret)
3922 return FALSE;
3923 break;
3924 case TGSI_OPCODE_ATOMUADD:
3925 case TGSI_OPCODE_ATOMXCHG:
3926 case TGSI_OPCODE_ATOMCAS:
3927 case TGSI_OPCODE_ATOMAND:
3928 case TGSI_OPCODE_ATOMOR:
3929 case TGSI_OPCODE_ATOMXOR:
3930 case TGSI_OPCODE_ATOMUMIN:
3931 case TGSI_OPCODE_ATOMUMAX:
3932 case TGSI_OPCODE_ATOMIMIN:
3933 case TGSI_OPCODE_ATOMIMAX:
3934 ret = translate_atomic(ctx, inst, &sinfo, srcs, dsts);
3935 if (ret)
3936 return FALSE;
3937 break;
3938 case TGSI_OPCODE_RESQ:
3939 ret = translate_resq(ctx, inst, srcs, dsts);
3940 if (ret)
3941 return FALSE;
3942 break;
3943 case TGSI_OPCODE_CLOCK:
3944 ctx->shader_req_bits |= SHADER_REQ_SHADER_CLOCK;
3945 snprintf(buf, 255, "%s = uintBitsToFloat(clock2x32ARB());\n", dsts[0]);
3946 EMIT_BUF_WITH_RET(ctx, buf);
3947 break;
3948 default:
3949 fprintf(stderr,"failed to convert opcode %d\n", inst->Instruction.Opcode);
3950 break;
3951 }
3952
3953 for (uint32_t i = 0; i < 1; i++) {
3954 enum tgsi_opcode_type dtype = tgsi_opcode_infer_dst_type(inst->Instruction.Opcode);
3955 if (dtype == TGSI_TYPE_DOUBLE) {
3956 snprintf(buf, 255, "%s = uintBitsToFloat(unpackDouble2x32(%s));\n", fp64_dsts[0], dsts[0]);
3957 EMIT_BUF_WITH_RET(ctx, buf);
3958 }
3959 }
3960 if (inst->Instruction.Saturate) {
3961 snprintf(buf, 255, "%s = clamp(%s, 0.0, 1.0);\n", dsts[0], dsts[0]);
3962 EMIT_BUF_WITH_RET(ctx, buf);
3963 }
3964 return TRUE;
3965 }
3966
3967 static boolean
prolog(struct tgsi_iterate_context * iter)3968 prolog(struct tgsi_iterate_context *iter)
3969 {
3970 struct dump_ctx *ctx = (struct dump_ctx *)iter;
3971
3972 if (ctx->prog_type == -1)
3973 ctx->prog_type = iter->processor.Processor;
3974
3975 if (iter->processor.Processor == TGSI_PROCESSOR_VERTEX &&
3976 ctx->key->gs_present)
3977 require_glsl_ver(ctx, 150);
3978
3979 return TRUE;
3980 }
3981
3982 #define STRCAT_WITH_RET(mainstr, buf) do { \
3983 (mainstr) = strcat_realloc((mainstr), (buf)); \
3984 if ((mainstr) == NULL) return NULL; \
3985 } while(0)
3986
3987 /* reserve space for: "#extension GL_ARB_gpu_shader5 : require\n" */
3988 #define PAD_GPU_SHADER5(s) \
3989 STRCAT_WITH_RET(s, " \n")
3990
emit_header(struct dump_ctx * ctx,char * glsl_hdr)3991 static char *emit_header(struct dump_ctx *ctx, char *glsl_hdr)
3992 {
3993 if (ctx->cfg->use_gles) {
3994 char buf[32];
3995 snprintf(buf, sizeof(buf), "#version %d es\n", ctx->cfg->glsl_version);
3996 STRCAT_WITH_RET(glsl_hdr, buf);
3997 if (ctx->shader_req_bits & SHADER_REQ_SAMPLER_MS)
3998 STRCAT_WITH_RET(glsl_hdr, "#extension GL_OES_texture_storage_multisample_2d_array : require\n");
3999
4000 if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY) {
4001 STRCAT_WITH_RET(glsl_hdr, "#extension GL_EXT_geometry_shader : require\n");
4002 if (ctx->shader_req_bits & SHADER_REQ_PSIZE)
4003 STRCAT_WITH_RET(glsl_hdr, "#extension GL_OES_geometry_point_size : enable\n");
4004 }
4005
4006 if ((ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
4007 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL)) {
4008 if (ctx->cfg->glsl_version < 320)
4009 STRCAT_WITH_RET(glsl_hdr, "#extension GL_OES_tessellation_shader : require\n");
4010 STRCAT_WITH_RET(glsl_hdr, "#extension GL_OES_tessellation_point_size : enable\n");
4011 }
4012
4013 PAD_GPU_SHADER5(glsl_hdr);
4014 STRCAT_WITH_RET(glsl_hdr, "precision highp float;\n");
4015 STRCAT_WITH_RET(glsl_hdr, "precision highp int;\n");
4016 } else {
4017 char buf[128];
4018 if (ctx->prog_type == TGSI_PROCESSOR_COMPUTE) {
4019 STRCAT_WITH_RET(glsl_hdr, "#version 330\n");
4020 STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_compute_shader : require\n");
4021 } else {
4022 if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
4023 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL ||
4024 ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
4025 ctx->glsl_ver_required == 150)
4026 STRCAT_WITH_RET(glsl_hdr, "#version 150\n");
4027 else if (ctx->glsl_ver_required == 140)
4028 STRCAT_WITH_RET(glsl_hdr, "#version 140\n");
4029 else
4030 STRCAT_WITH_RET(glsl_hdr, "#version 130\n");
4031 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX ||
4032 ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
4033 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL)
4034 PAD_GPU_SHADER5(glsl_hdr);
4035 }
4036
4037 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
4038 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL)
4039 STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_tessellation_shader : require\n");
4040
4041 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX && ctx->cfg->use_explicit_locations)
4042 STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_explicit_attrib_location : require\n");
4043 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && fs_emit_layout(ctx))
4044 STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_fragment_coord_conventions : require\n");
4045
4046 if (ctx->num_ubo)
4047 STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_uniform_buffer_object : require\n");
4048
4049 if (ctx->num_cull_dist_prop || ctx->key->prev_stage_num_cull_out)
4050 STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_cull_distance : require\n");
4051 if (ctx->ssbo_used_mask)
4052 STRCAT_WITH_RET(glsl_hdr, "#extension GL_ARB_shader_storage_buffer_object : require\n");
4053
4054 for (uint32_t i = 0; i < ARRAY_SIZE(shader_req_table); i++) {
4055 if (shader_req_table[i].key == SHADER_REQ_SAMPLER_RECT && ctx->glsl_ver_required >= 140)
4056 continue;
4057
4058 if (ctx->shader_req_bits & shader_req_table[i].key) {
4059 snprintf(buf, 128, "#extension %s : require\n", shader_req_table[i].string);
4060 STRCAT_WITH_RET(glsl_hdr, buf);
4061 }
4062 }
4063 }
4064
4065 return glsl_hdr;
4066 }
4067
vrend_shader_samplerreturnconv(enum tgsi_return_type type)4068 char vrend_shader_samplerreturnconv(enum tgsi_return_type type)
4069 {
4070 switch (type) {
4071 case TGSI_RETURN_TYPE_SINT:
4072 return 'i';
4073 case TGSI_RETURN_TYPE_UINT:
4074 return 'u';
4075 default:
4076 return ' ';
4077 }
4078 }
4079
vrend_shader_samplertypeconv(int sampler_type,int * is_shad)4080 const char *vrend_shader_samplertypeconv(int sampler_type, int *is_shad)
4081 {
4082 switch (sampler_type) {
4083 case TGSI_TEXTURE_BUFFER: return "Buffer";
4084 case TGSI_TEXTURE_1D: return "1D";
4085 case TGSI_TEXTURE_2D: return "2D";
4086 case TGSI_TEXTURE_3D: return "3D";
4087 case TGSI_TEXTURE_CUBE: return "Cube";
4088 case TGSI_TEXTURE_RECT: return "2DRect";
4089 case TGSI_TEXTURE_SHADOW1D: *is_shad = 1; return "1DShadow";
4090 case TGSI_TEXTURE_SHADOW2D: *is_shad = 1; return "2DShadow";
4091 case TGSI_TEXTURE_SHADOWRECT: *is_shad = 1; return "2DRectShadow";
4092 case TGSI_TEXTURE_1D_ARRAY: return "1DArray";
4093 case TGSI_TEXTURE_2D_ARRAY: return "2DArray";
4094 case TGSI_TEXTURE_SHADOW1D_ARRAY: *is_shad = 1; return "1DArrayShadow";
4095 case TGSI_TEXTURE_SHADOW2D_ARRAY: *is_shad = 1; return "2DArrayShadow";
4096 case TGSI_TEXTURE_SHADOWCUBE: *is_shad = 1; return "CubeShadow";
4097 case TGSI_TEXTURE_CUBE_ARRAY: return "CubeArray";
4098 case TGSI_TEXTURE_SHADOWCUBE_ARRAY: *is_shad = 1; return "CubeArrayShadow";
4099 case TGSI_TEXTURE_2D_MSAA: return "2DMS";
4100 case TGSI_TEXTURE_2D_ARRAY_MSAA: return "2DMSArray";
4101 default: return NULL;
4102 }
4103 }
4104
get_interp_string(struct vrend_shader_cfg * cfg,int interpolate,bool flatshade)4105 static const char *get_interp_string(struct vrend_shader_cfg *cfg, int interpolate, bool flatshade)
4106 {
4107 switch (interpolate) {
4108 case TGSI_INTERPOLATE_LINEAR:
4109 if (!cfg->use_gles)
4110 return "noperspective ";
4111 else
4112 return "";
4113 case TGSI_INTERPOLATE_PERSPECTIVE:
4114 return "smooth ";
4115 case TGSI_INTERPOLATE_CONSTANT:
4116 return "flat ";
4117 case TGSI_INTERPOLATE_COLOR:
4118 if (flatshade)
4119 return "flat ";
4120 /* fallthrough */
4121 default:
4122 return NULL;
4123 }
4124 }
4125
get_aux_string(unsigned location)4126 static const char *get_aux_string(unsigned location)
4127 {
4128 switch (location) {
4129 case TGSI_INTERPOLATE_LOC_CENTER:
4130 default:
4131 return "";
4132 case TGSI_INTERPOLATE_LOC_CENTROID:
4133 return "centroid ";
4134 case TGSI_INTERPOLATE_LOC_SAMPLE:
4135 return "sample ";
4136 }
4137 }
4138
emit_sampler_decl(struct dump_ctx * ctx,char * glsl_hdr,uint32_t i,uint32_t range,const struct vrend_shader_sampler * sampler)4139 static void *emit_sampler_decl(struct dump_ctx *ctx, char *glsl_hdr,
4140 uint32_t i, uint32_t range,
4141 const struct vrend_shader_sampler *sampler)
4142 {
4143 char buf[255], ptc;
4144 int is_shad = 0;
4145 const char *sname, *precision, *stc;
4146
4147 sname = tgsi_proc_to_prefix(ctx->prog_type);
4148
4149 precision = (ctx->cfg->use_gles) ? "highp " : " ";
4150
4151 ptc = vrend_shader_samplerreturnconv(sampler->tgsi_sampler_return);
4152 stc = vrend_shader_samplertypeconv(sampler->tgsi_sampler_type, &is_shad);
4153
4154 /* GLES does not support 1D textures -- we use a 2D texture and set the parameter set to 0.5 */
4155 if (ctx->cfg->use_gles && sampler->tgsi_sampler_type == TGSI_TEXTURE_1D)
4156 snprintf(buf, 255, "uniform highp %csampler2D %ssamp%d;\n", ptc, sname, i);
4157 else if (range)
4158 snprintf(buf, 255, "uniform %s%csampler%s %ssamp%d[%d];\n", precision, ptc, stc, sname, i, range);
4159 else
4160 snprintf(buf, 255, "uniform %s%csampler%s %ssamp%d;\n", precision, ptc, stc, sname, i);
4161
4162 STRCAT_WITH_RET(glsl_hdr, buf);
4163 if (is_shad) {
4164 snprintf(buf, 255, "uniform %svec4 %sshadmask%d;\n", precision, sname, i);
4165 STRCAT_WITH_RET(glsl_hdr, buf);
4166 snprintf(buf, 255, "uniform %svec4 %sshadadd%d;\n", precision, sname, i);
4167 STRCAT_WITH_RET(glsl_hdr, buf);
4168 ctx->shadow_samp_mask |= (1 << i);
4169 }
4170
4171 return glsl_hdr;
4172 }
4173
get_internalformat_string(int virgl_format,enum tgsi_return_type * stype)4174 const char *get_internalformat_string(int virgl_format, enum tgsi_return_type *stype)
4175 {
4176 switch (virgl_format) {
4177 case PIPE_FORMAT_R11G11B10_FLOAT:
4178 *stype = TGSI_RETURN_TYPE_FLOAT;
4179 return "r11f_g11f_b10f";
4180 case PIPE_FORMAT_R10G10B10A2_UNORM:
4181 *stype = TGSI_RETURN_TYPE_UNORM;
4182 return "rgb10_a2";
4183 case PIPE_FORMAT_R10G10B10A2_UINT:
4184 *stype = TGSI_RETURN_TYPE_UINT;
4185 return "rgb10_a2ui";
4186 case PIPE_FORMAT_R8_UNORM:
4187 *stype = TGSI_RETURN_TYPE_UNORM;
4188 return "r8";
4189 case PIPE_FORMAT_R8_SNORM:
4190 *stype = TGSI_RETURN_TYPE_SNORM;
4191 return "r8_snorm";
4192 case PIPE_FORMAT_R8_UINT:
4193 *stype = TGSI_RETURN_TYPE_UINT;
4194 return "r8ui";
4195 case PIPE_FORMAT_R8_SINT:
4196 *stype = TGSI_RETURN_TYPE_SINT;
4197 return "r8i";
4198 case PIPE_FORMAT_R8G8_UNORM:
4199 *stype = TGSI_RETURN_TYPE_UNORM;
4200 return "rg8";
4201 case PIPE_FORMAT_R8G8_SNORM:
4202 *stype = TGSI_RETURN_TYPE_SNORM;
4203 return "rg8_snorm";
4204 case PIPE_FORMAT_R8G8_UINT:
4205 *stype = TGSI_RETURN_TYPE_UINT;
4206 return "rg8ui";
4207 case PIPE_FORMAT_R8G8_SINT:
4208 *stype = TGSI_RETURN_TYPE_SINT;
4209 return "rg8i";
4210 case PIPE_FORMAT_R8G8B8A8_UNORM:
4211 *stype = TGSI_RETURN_TYPE_UNORM;
4212 return "rgba8";
4213 case PIPE_FORMAT_R8G8B8A8_SNORM:
4214 *stype = TGSI_RETURN_TYPE_SNORM;
4215 return "rgba8_snorm";
4216 case PIPE_FORMAT_R8G8B8A8_UINT:
4217 *stype = TGSI_RETURN_TYPE_UINT;
4218 return "rgba8ui";
4219 case PIPE_FORMAT_R8G8B8A8_SINT:
4220 *stype = TGSI_RETURN_TYPE_SINT;
4221 return "rgba8i";
4222 case PIPE_FORMAT_R16_UNORM:
4223 *stype = TGSI_RETURN_TYPE_UNORM;
4224 return "r16";
4225 case PIPE_FORMAT_R16_SNORM:
4226 *stype = TGSI_RETURN_TYPE_SNORM;
4227 return "r16_snorm";
4228 case PIPE_FORMAT_R16_UINT:
4229 *stype = TGSI_RETURN_TYPE_UINT;
4230 return "r16ui";
4231 case PIPE_FORMAT_R16_SINT:
4232 *stype = TGSI_RETURN_TYPE_SINT;
4233 return "r16i";
4234 case PIPE_FORMAT_R16_FLOAT:
4235 *stype = TGSI_RETURN_TYPE_FLOAT;
4236 return "r16f";
4237 case PIPE_FORMAT_R16G16_UNORM:
4238 *stype = TGSI_RETURN_TYPE_UNORM;
4239 return "rg16";
4240 case PIPE_FORMAT_R16G16_SNORM:
4241 *stype = TGSI_RETURN_TYPE_SNORM;
4242 return "rg16_snorm";
4243 case PIPE_FORMAT_R16G16_UINT:
4244 *stype = TGSI_RETURN_TYPE_UINT;
4245 return "rg16ui";
4246 case PIPE_FORMAT_R16G16_SINT:
4247 *stype = TGSI_RETURN_TYPE_SINT;
4248 return "rg16i";
4249 case PIPE_FORMAT_R16G16_FLOAT:
4250 *stype = TGSI_RETURN_TYPE_FLOAT;
4251 return "rg16f";
4252 case PIPE_FORMAT_R16G16B16A16_UNORM:
4253 *stype = TGSI_RETURN_TYPE_UNORM;
4254 return "rgba16";
4255 case PIPE_FORMAT_R16G16B16A16_SNORM:
4256 *stype = TGSI_RETURN_TYPE_SNORM;
4257 return "rgba16_snorm";
4258 case PIPE_FORMAT_R16G16B16A16_FLOAT:
4259 *stype = TGSI_RETURN_TYPE_FLOAT;
4260 return "rgba16f";
4261 case PIPE_FORMAT_R32_FLOAT:
4262 *stype = TGSI_RETURN_TYPE_FLOAT;
4263 return "r32f";
4264 case PIPE_FORMAT_R32_UINT:
4265 *stype = TGSI_RETURN_TYPE_UINT;
4266 return "r32ui";
4267 case PIPE_FORMAT_R32_SINT:
4268 *stype = TGSI_RETURN_TYPE_SINT;
4269 return "r32i";
4270 case PIPE_FORMAT_R32G32_FLOAT:
4271 *stype = TGSI_RETURN_TYPE_FLOAT;
4272 return "rg32f";
4273 case PIPE_FORMAT_R32G32_UINT:
4274 *stype = TGSI_RETURN_TYPE_UINT;
4275 return "rg32ui";
4276 case PIPE_FORMAT_R32G32_SINT:
4277 *stype = TGSI_RETURN_TYPE_SINT;
4278 return "rg32i";
4279 case PIPE_FORMAT_R32G32B32A32_FLOAT:
4280 *stype = TGSI_RETURN_TYPE_FLOAT;
4281 return "rgba32f";
4282 case PIPE_FORMAT_R32G32B32A32_UINT:
4283 *stype = TGSI_RETURN_TYPE_UINT;
4284 return "rgba32ui";
4285 case PIPE_FORMAT_R16G16B16A16_UINT:
4286 *stype = TGSI_RETURN_TYPE_UINT;
4287 return "rgba16ui";
4288 case PIPE_FORMAT_R16G16B16A16_SINT:
4289 *stype = TGSI_RETURN_TYPE_SINT;
4290 return "rgba16i";
4291 case PIPE_FORMAT_R32G32B32A32_SINT:
4292 *stype = TGSI_RETURN_TYPE_SINT;
4293 return "rgba32i";
4294 case PIPE_FORMAT_NONE:
4295 *stype = TGSI_RETURN_TYPE_UNORM;
4296 return "";
4297 default:
4298 *stype = TGSI_RETURN_TYPE_UNORM;
4299 fprintf(stderr, "illegal format %d\n", virgl_format);
4300 return "";
4301 }
4302 }
4303
emit_image_decl(const struct dump_ctx * ctx,char * glsl_hdr,uint32_t i,uint32_t range,const struct vrend_shader_image * image)4304 static void *emit_image_decl(const struct dump_ctx *ctx, char *glsl_hdr,
4305 uint32_t i, uint32_t range,
4306 const struct vrend_shader_image *image)
4307 {
4308 char buf[255], ptc;
4309 int is_shad = 0;
4310 const char *sname, *stc, *formatstr;
4311 enum tgsi_return_type itype;
4312 const char *volatile_str = image->vflag ? "volatile " : "";
4313 const char *precision = ctx->cfg->use_gles ? "highp " : "";
4314 const char *access = "";
4315 formatstr = get_internalformat_string(image->decl.Format, &itype);
4316 ptc = vrend_shader_samplerreturnconv(itype);
4317 sname = tgsi_proc_to_prefix(ctx->prog_type);
4318 stc = vrend_shader_samplertypeconv(image->decl.Resource, &is_shad);
4319
4320 if (!image->decl.Writable)
4321 access = "readonly ";
4322 else if (!image->decl.Format)
4323 access = "writeonly ";
4324
4325 if (ctx->cfg->use_gles) { /* TODO: enable on OpenGL 4.2 and up also */
4326 snprintf(buf, 255, "layout(binding=%d%s%s) ",
4327 i, formatstr[0] != '\0' ? ", " : "", formatstr);
4328 STRCAT_WITH_RET(glsl_hdr, buf);
4329 } else if (formatstr[0] != '\0') {
4330 snprintf(buf, 255, "layout(%s) ", formatstr);
4331 STRCAT_WITH_RET(glsl_hdr, buf);
4332 }
4333
4334 if (range)
4335 snprintf(buf, 255, "%s%suniform %s%cimage%s %simg%d[%d];\n",
4336 access, volatile_str, precision, ptc, stc, sname, i, range);
4337 else
4338 snprintf(buf, 255, "%s%suniform %s%cimage%s %simg%d;\n",
4339 access, volatile_str, precision, ptc, stc, sname, i);
4340
4341 STRCAT_WITH_RET(glsl_hdr, buf);
4342 return glsl_hdr;
4343 }
4344
emit_ios(struct dump_ctx * ctx,char * glsl_hdr)4345 static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
4346 {
4347 uint32_t i;
4348 char buf[255];
4349 char postfix[8];
4350 const char *prefix = "", *auxprefix = "";
4351 bool fcolor_emitted[2], bcolor_emitted[2];
4352 uint32_t nsamp;
4353 const char *sname = tgsi_proc_to_prefix(ctx->prog_type);
4354 ctx->num_interps = 0;
4355
4356 if (ctx->so && ctx->so->num_outputs >= PIPE_MAX_SO_OUTPUTS) {
4357 fprintf(stderr, "Num outputs exceeded, max is %u\n", PIPE_MAX_SO_OUTPUTS);
4358 return NULL;
4359 }
4360
4361 if (ctx->key->color_two_side) {
4362 fcolor_emitted[0] = fcolor_emitted[1] = false;
4363 bcolor_emitted[0] = bcolor_emitted[1] = false;
4364 }
4365 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT) {
4366 if (fs_emit_layout(ctx)) {
4367 bool upper_left = !(ctx->fs_coord_origin ^ ctx->key->invert_fs_origin);
4368 char comma = (upper_left && ctx->fs_pixel_center) ? ',' : ' ';
4369
4370 snprintf(buf, 255, "layout(%s%c%s) in vec4 gl_FragCoord;\n",
4371 upper_left ? "origin_upper_left" : "",
4372 comma,
4373 ctx->fs_pixel_center ? "pixel_center_integer" : "");
4374 STRCAT_WITH_RET(glsl_hdr, buf);
4375 }
4376 if (ctx->early_depth_stencil) {
4377 snprintf(buf, 255, "layout(early_fragment_tests) in;\n");
4378 STRCAT_WITH_RET(glsl_hdr, buf);
4379 }
4380 }
4381
4382 if (ctx->prog_type == TGSI_PROCESSOR_COMPUTE) {
4383 snprintf(buf, 255, "layout (local_size_x = %d, local_size_y = %d, local_size_z = %d) in;\n",
4384 ctx->local_cs_block_size[0], ctx->local_cs_block_size[1], ctx->local_cs_block_size[2]);
4385 STRCAT_WITH_RET(glsl_hdr, buf);
4386
4387 if (ctx->req_local_mem) {
4388 enum vrend_type_qualifier type = ctx->integer_memory ? INT : UINT;
4389 snprintf(buf, 255, "shared %s values[%d];\n", get_string(type), ctx->req_local_mem / 4);
4390 STRCAT_WITH_RET(glsl_hdr, buf);
4391 }
4392 }
4393
4394 if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY) {
4395 char invocbuf[25];
4396
4397 if (ctx->gs_num_invocations)
4398 snprintf(invocbuf, 25, ", invocations = %d", ctx->gs_num_invocations);
4399
4400 snprintf(buf, 255, "layout(%s%s) in;\n", prim_to_name(ctx->gs_in_prim),
4401 ctx->gs_num_invocations > 1 ? invocbuf : "");
4402 STRCAT_WITH_RET(glsl_hdr, buf);
4403 snprintf(buf, 255, "layout(%s, max_vertices = %d) out;\n", prim_to_name(ctx->gs_out_prim), ctx->gs_max_out_verts);
4404 STRCAT_WITH_RET(glsl_hdr, buf);
4405 }
4406
4407 if (ctx_indirect_inputs(ctx)) {
4408 const char *name_prefix = get_stage_input_name_prefix(ctx, ctx->prog_type);
4409 if (ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL) {
4410 if (ctx->patch_input_range.used) {
4411 int size = ctx->patch_input_range.last - ctx->patch_input_range.first + 1;
4412 if (size < ctx->key->num_indirect_patch_inputs)
4413 size = ctx->key->num_indirect_patch_inputs;
4414 snprintf(buf, 255, "patch in vec4 %sp%d[%d];\n", name_prefix, ctx->patch_input_range.first, size);
4415 STRCAT_WITH_RET(glsl_hdr, buf);
4416 }
4417 }
4418
4419 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
4420 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL) {
4421 if (ctx->generic_input_range.used) {
4422 int size = ctx->generic_input_range.last - ctx->generic_input_range.first + 1;
4423 if (size < ctx->key->num_indirect_generic_inputs)
4424 size = ctx->key->num_indirect_generic_inputs;
4425 snprintf(buf, 255, "in block { vec4 %s%d[%d]; } blk[];\n", name_prefix, ctx->generic_input_range.first, size);
4426 STRCAT_WITH_RET(glsl_hdr, buf);
4427 }
4428 }
4429 }
4430 for (i = 0; i < ctx->num_inputs; i++) {
4431 if (!ctx->inputs[i].glsl_predefined_no_emit) {
4432 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX && ctx->cfg->use_explicit_locations) {
4433 snprintf(buf, 255, "layout(location=%d) ", ctx->inputs[i].first);
4434 STRCAT_WITH_RET(glsl_hdr, buf);
4435 }
4436 if (ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL && ctx->inputs[i].name == TGSI_SEMANTIC_PATCH)
4437 prefix = "patch ";
4438 else if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT &&
4439 (ctx->inputs[i].name == TGSI_SEMANTIC_GENERIC ||
4440 ctx->inputs[i].name == TGSI_SEMANTIC_COLOR)) {
4441 prefix = get_interp_string(ctx->cfg, ctx->inputs[i].interpolate, ctx->key->flatshade);
4442 if (!prefix)
4443 prefix = "";
4444 auxprefix = get_aux_string(ctx->inputs[i].location);
4445 ctx->num_interps++;
4446 }
4447
4448 if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY) {
4449 snprintf(postfix, 8, "[%d]", gs_input_prim_to_size(ctx->gs_in_prim));
4450 } else if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL ||
4451 (ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL && ctx->inputs[i].name != TGSI_SEMANTIC_PATCH)) {
4452 snprintf(postfix, 8, "[]");
4453 } else
4454 postfix[0] = 0;
4455 snprintf(buf, 255, "%s%sin vec4 %s%s;\n", prefix, auxprefix, ctx->inputs[i].glsl_name, postfix);
4456 STRCAT_WITH_RET(glsl_hdr, buf);
4457 }
4458
4459 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && ctx->cfg->use_gles &&
4460 (ctx->key->coord_replace & (1 << ctx->inputs[i].sid))) {
4461 snprintf(buf, 255, "uniform float winsys_adjust_y;\n");
4462 STRCAT_WITH_RET(glsl_hdr, buf);
4463 }
4464 }
4465 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL) {
4466 snprintf(buf, 255, "layout(vertices = %d) out;\n", ctx->tcs_vertices_out);
4467 STRCAT_WITH_RET(glsl_hdr, buf);
4468 }
4469 if (ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL) {
4470 snprintf(buf, 255, "layout(%s, %s, %s%s) in;\n",
4471 prim_to_tes_name(ctx->tes_prim_mode),
4472 get_spacing_string(ctx->tes_spacing),
4473 ctx->tes_vertex_order ? "cw" : "ccw",
4474 ctx->tes_point_mode ? ", point_mode" : "");
4475 STRCAT_WITH_RET(glsl_hdr, buf);
4476 }
4477
4478 if (ctx_indirect_outputs(ctx)) {
4479 const char *name_prefix = get_stage_output_name_prefix(ctx->prog_type);
4480 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX) {
4481 if (ctx->generic_output_range.used) {
4482 snprintf(buf, 255, "out block { vec4 %s%d[%d]; } oblk;\n", name_prefix, ctx->generic_output_range.first, ctx->generic_output_range.last - ctx->generic_output_range.first + 1);
4483 STRCAT_WITH_RET(glsl_hdr, buf);
4484 }
4485 }
4486 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL) {
4487 if (ctx->generic_output_range.used) {
4488 snprintf(buf, 255, "out block { vec4 %s%d[%d]; } oblk[];\n", name_prefix, ctx->generic_output_range.first, ctx->generic_output_range.last - ctx->generic_output_range.first + 1);
4489 STRCAT_WITH_RET(glsl_hdr, buf);
4490 }
4491 if (ctx->patch_output_range.used) {
4492 snprintf(buf, 255, "patch out vec4 %sp%d[%d];\n", name_prefix, ctx->patch_output_range.first, ctx->patch_output_range.last - ctx->patch_output_range.first + 1);
4493 STRCAT_WITH_RET(glsl_hdr, buf);
4494 }
4495 }
4496 }
4497
4498 if (ctx->write_all_cbufs) {
4499 for (i = 0; i < (uint32_t)ctx->cfg->max_draw_buffers; i++) {
4500 if (ctx->cfg->use_gles)
4501 snprintf(buf, 255, "layout (location=%d) out vec4 fsout_c%d;\n", i, i);
4502 else
4503 snprintf(buf, 255, "out vec4 fsout_c%d;\n", i);
4504 STRCAT_WITH_RET(glsl_hdr, buf);
4505 }
4506 } else {
4507 for (i = 0; i < ctx->num_outputs; i++) {
4508 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX && ctx->key->color_two_side && ctx->outputs[i].sid < 2) {
4509 if (ctx->outputs[i].name == TGSI_SEMANTIC_COLOR)
4510 fcolor_emitted[ctx->outputs[i].sid] = true;
4511 if (ctx->outputs[i].name == TGSI_SEMANTIC_BCOLOR)
4512 bcolor_emitted[ctx->outputs[i].sid] = true;
4513 }
4514 if (!ctx->outputs[i].glsl_predefined_no_emit) {
4515 if ((ctx->prog_type == TGSI_PROCESSOR_VERTEX ||
4516 ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
4517 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL) &&
4518 (ctx->outputs[i].name == TGSI_SEMANTIC_GENERIC ||
4519 ctx->outputs[i].name == TGSI_SEMANTIC_COLOR ||
4520 ctx->outputs[i].name == TGSI_SEMANTIC_BCOLOR)) {
4521 ctx->num_interps++;
4522 prefix = INTERP_PREFIX;
4523 } else
4524 prefix = "";
4525 /* ugly leave spaces to patch interp in later */
4526 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL) {
4527 if (ctx->outputs[i].name == TGSI_SEMANTIC_PATCH)
4528 snprintf(buf, 255, "patch out vec4 %s;\n", ctx->outputs[i].glsl_name);
4529 else
4530 snprintf(buf, 255, "%sout vec4 %s[];\n", prefix, ctx->outputs[i].glsl_name);
4531 } else if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY && ctx->outputs[i].stream)
4532 snprintf(buf, 255, "layout (stream = %d) %s%s%sout vec4 %s;\n", ctx->outputs[i].stream, prefix,
4533 ctx->outputs[i].precise ? "precise " : "",
4534 ctx->outputs[i].invariant ? "invariant " : "",
4535 ctx->outputs[i].glsl_name);
4536 else
4537 snprintf(buf, 255, "%s%s%s%s vec4 %s;\n",
4538 prefix,
4539 ctx->outputs[i].precise ? "precise " : "",
4540 ctx->outputs[i].invariant ? "invariant " : "",
4541 ctx->outputs[i].fbfetch_used ? "inout" : "out",
4542 ctx->outputs[i].glsl_name);
4543 STRCAT_WITH_RET(glsl_hdr, buf);
4544 } else if (ctx->outputs[i].invariant || ctx->outputs[i].precise) {
4545 snprintf(buf, 255, "%s%s %s;\n",
4546 ctx->outputs[i].precise ? "precise " : "",
4547 ctx->outputs[i].invariant ? "invariant " : "",
4548 ctx->outputs[i].glsl_name);
4549 STRCAT_WITH_RET(glsl_hdr, buf);
4550 }
4551 }
4552 }
4553
4554 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX && ctx->key->color_two_side) {
4555 for (i = 0; i < 2; i++) {
4556 if (fcolor_emitted[i] && !bcolor_emitted[i]) {
4557 snprintf(buf, 255, "%sout vec4 ex_bc%d;\n", INTERP_PREFIX, i);
4558 STRCAT_WITH_RET(glsl_hdr, buf);
4559 }
4560 if (bcolor_emitted[i] && !fcolor_emitted[i]) {
4561 snprintf(buf, 255, "%sout vec4 ex_c%d;\n", INTERP_PREFIX, i);
4562 STRCAT_WITH_RET(glsl_hdr, buf);
4563 }
4564 }
4565 }
4566
4567 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX ||
4568 ctx->prog_type == TGSI_PROCESSOR_GEOMETRY ||
4569 ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL) {
4570 snprintf(buf, 255, "uniform float winsys_adjust_y;\n");
4571 STRCAT_WITH_RET(glsl_hdr, buf);
4572 }
4573
4574 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX) {
4575 if (ctx->has_clipvertex) {
4576 snprintf(buf, 255, "%svec4 clipv_tmp;\n", ctx->has_clipvertex_so ? "out " : "");
4577 STRCAT_WITH_RET(glsl_hdr, buf);
4578 }
4579 if (ctx->num_clip_dist || ctx->key->clip_plane_enable) {
4580 bool has_prop = (ctx->num_clip_dist_prop + ctx->num_cull_dist_prop) > 0;
4581 int num_clip_dists = ctx->num_clip_dist ? ctx->num_clip_dist : 8;
4582 int num_cull_dists = 0;
4583 char cull_buf[64] = { 0 };
4584 char clip_buf[64] = { 0 };
4585 if (has_prop) {
4586 num_clip_dists = ctx->num_clip_dist_prop;
4587 num_cull_dists = ctx->num_cull_dist_prop;
4588 if (num_clip_dists)
4589 snprintf(clip_buf, 64, "out float gl_ClipDistance[%d];\n", num_clip_dists);
4590 if (num_cull_dists)
4591 snprintf(cull_buf, 64, "out float gl_CullDistance[%d];\n", num_cull_dists);
4592 } else
4593 snprintf(clip_buf, 64, "out float gl_ClipDistance[%d];\n", num_clip_dists);
4594 if (ctx->key->clip_plane_enable) {
4595 snprintf(buf, 255, "uniform vec4 clipp[8];\n");
4596 STRCAT_WITH_RET(glsl_hdr, buf);
4597 }
4598 if (ctx->key->gs_present || ctx->key->tes_present) {
4599 ctx->vs_has_pervertex = true;
4600 snprintf(buf, 255, "out gl_PerVertex {\n vec4 gl_Position;\n float gl_PointSize;\n%s%s};\n", clip_buf, cull_buf);
4601 STRCAT_WITH_RET(glsl_hdr, buf);
4602 } else {
4603 snprintf(buf, 255, "%s%s", clip_buf, cull_buf);
4604 STRCAT_WITH_RET(glsl_hdr, buf);
4605 }
4606 snprintf(buf, 255, "vec4 clip_dist_temp[2];\n");
4607 STRCAT_WITH_RET(glsl_hdr, buf);
4608 }
4609 }
4610
4611 if (ctx->prog_type == TGSI_PROCESSOR_GEOMETRY) {
4612 if (ctx->num_in_clip_dist || ctx->key->clip_plane_enable || ctx->key->prev_stage_pervertex_out) {
4613 int clip_dist, cull_dist;
4614 char clip_var[64] = {}, cull_var[64] = {};
4615
4616 clip_dist = ctx->key->prev_stage_num_clip_out ? ctx->key->prev_stage_num_clip_out : ctx->num_in_clip_dist;
4617 cull_dist = ctx->key->prev_stage_num_cull_out;
4618
4619 if (clip_dist)
4620 snprintf(clip_var, 64, "float gl_ClipDistance[%d];\n", clip_dist);
4621 if (cull_dist)
4622 snprintf(cull_var, 64, "float gl_CullDistance[%d];\n", cull_dist);
4623
4624 snprintf(buf, 255, "in gl_PerVertex {\n vec4 gl_Position;\n float gl_PointSize; \n %s%s\n} gl_in[];\n", clip_var, cull_var);
4625 STRCAT_WITH_RET(glsl_hdr, buf);
4626 }
4627 if (ctx->num_clip_dist) {
4628 bool has_prop = (ctx->num_clip_dist_prop + ctx->num_cull_dist_prop) > 0;
4629 int num_clip_dists = ctx->num_clip_dist ? ctx->num_clip_dist : 8;
4630 int num_cull_dists = 0;
4631 char cull_buf[64] = { 0 };
4632 char clip_buf[64] = { 0 };
4633 if (has_prop) {
4634 num_clip_dists = ctx->num_clip_dist_prop;
4635 num_cull_dists = ctx->num_cull_dist_prop;
4636 if (num_clip_dists)
4637 snprintf(clip_buf, 64, "out float gl_ClipDistance[%d];\n", num_clip_dists);
4638 if (num_cull_dists)
4639 snprintf(cull_buf, 64, "out float gl_CullDistance[%d];\n", num_cull_dists);
4640 } else
4641 snprintf(clip_buf, 64, "out float gl_ClipDistance[%d];\n", num_clip_dists);
4642 snprintf(buf, 255, "%s%s\n", clip_buf, cull_buf);
4643 STRCAT_WITH_RET(glsl_hdr, buf);
4644 snprintf(buf, 255, "vec4 clip_dist_temp[2];\n");
4645 STRCAT_WITH_RET(glsl_hdr, buf);
4646 }
4647 }
4648
4649 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && ctx->num_in_clip_dist) {
4650 if (ctx->key->prev_stage_num_clip_out) {
4651 snprintf(buf, 255, "in float gl_ClipDistance[%d];\n", ctx->key->prev_stage_num_clip_out);
4652 STRCAT_WITH_RET(glsl_hdr, buf);
4653 }
4654 if (ctx->key->prev_stage_num_cull_out) {
4655 snprintf(buf, 255, "in float gl_CullDistance[%d];\n", ctx->key->prev_stage_num_cull_out);
4656 STRCAT_WITH_RET(glsl_hdr, buf);
4657 }
4658 }
4659
4660 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL || ctx->prog_type == TGSI_PROCESSOR_TESS_EVAL) {
4661 if (ctx->num_in_clip_dist || ctx->key->prev_stage_pervertex_out) {
4662 int clip_dist, cull_dist;
4663 char clip_var[64] = {}, cull_var[64] = {};
4664
4665 clip_dist = ctx->key->prev_stage_num_clip_out ? ctx->key->prev_stage_num_clip_out : ctx->num_in_clip_dist;
4666 cull_dist = ctx->key->prev_stage_num_cull_out;
4667
4668 if (clip_dist)
4669 snprintf(clip_var, 64, "float gl_ClipDistance[%d];\n", clip_dist);
4670 if (cull_dist)
4671 snprintf(cull_var, 64, "float gl_CullDistance[%d];\n", cull_dist);
4672
4673 snprintf(buf, 255, "in gl_PerVertex {\n vec4 gl_Position;\n float gl_PointSize; \n %s%s} gl_in[];\n", clip_var, cull_var);
4674 STRCAT_WITH_RET(glsl_hdr, buf);
4675 }
4676 if (ctx->num_clip_dist) {
4677 snprintf(buf, 255, "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);
4678 STRCAT_WITH_RET(glsl_hdr, buf);
4679 snprintf(buf, 255, "vec4 clip_dist_temp[2];\n");
4680 STRCAT_WITH_RET(glsl_hdr, buf);
4681 }
4682 }
4683
4684 if (ctx->so) {
4685 char outtype[6] = {0};
4686 for (i = 0; i < ctx->so->num_outputs; i++) {
4687 if (!ctx->write_so_outputs[i])
4688 continue;
4689 if (ctx->so->output[i].num_components == 1)
4690 snprintf(outtype, 6, "float");
4691 else
4692 snprintf(outtype, 6, "vec%d", ctx->so->output[i].num_components);
4693 if (ctx->prog_type == TGSI_PROCESSOR_TESS_CTRL)
4694 snprintf(buf, 255, "out %s tfout%d[];\n", outtype, i);
4695 else if (ctx->so->output[i].stream && ctx->prog_type == TGSI_PROCESSOR_GEOMETRY)
4696 snprintf(buf, 255, "layout (stream=%d) out %s tfout%d;\n", ctx->so->output[i].stream, outtype, i);
4697 else
4698 snprintf(buf, 255, "out %s tfout%d;\n", outtype, i);
4699 STRCAT_WITH_RET(glsl_hdr, buf);
4700 }
4701 }
4702 for (i = 0; i < ctx->num_temp_ranges; i++) {
4703 snprintf(buf, 255, "vec4 temp%d[%d];\n", ctx->temp_ranges[i].first, ctx->temp_ranges[i].last - ctx->temp_ranges[i].first + 1);
4704 STRCAT_WITH_RET(glsl_hdr, buf);
4705 }
4706
4707 if (ctx->write_mul_utemp) {
4708 snprintf(buf, 255, "uvec4 mul_utemp;\n");
4709 STRCAT_WITH_RET(glsl_hdr, buf);
4710 snprintf(buf, 255, "uvec4 umul_temp;\n");
4711 STRCAT_WITH_RET(glsl_hdr, buf);
4712 }
4713
4714 if (ctx->write_mul_itemp) {
4715 snprintf(buf, 255, "ivec4 mul_itemp;\n");
4716 STRCAT_WITH_RET(glsl_hdr, buf);
4717 snprintf(buf, 255, "ivec4 imul_temp;\n");
4718 STRCAT_WITH_RET(glsl_hdr, buf);
4719 }
4720
4721 if (ctx->ssbo_used_mask) {
4722 snprintf(buf, 255, "uint ssbo_addr_temp;\n");
4723 STRCAT_WITH_RET(glsl_hdr, buf);
4724 }
4725
4726 if (ctx->shader_req_bits & SHADER_REQ_FP64) {
4727 snprintf(buf, 255, "dvec2 fp64_dst[3];\n");
4728 STRCAT_WITH_RET(glsl_hdr, buf);
4729 snprintf(buf, 255, "dvec2 fp64_src[4];\n");
4730 STRCAT_WITH_RET(glsl_hdr, buf);
4731 }
4732
4733 for (i = 0; i < ctx->num_address; i++) {
4734 snprintf(buf, 255, "int addr%d;\n", i);
4735 STRCAT_WITH_RET(glsl_hdr, buf);
4736 }
4737 if (ctx->num_consts) {
4738 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4739 snprintf(buf, 255, "uniform uvec4 %sconst0[%d];\n", cname, ctx->num_consts);
4740 STRCAT_WITH_RET(glsl_hdr, buf);
4741 }
4742
4743 if (ctx->key->color_two_side) {
4744 if (ctx->color_in_mask & 1) {
4745 snprintf(buf, 255, "vec4 realcolor0;\n");
4746 STRCAT_WITH_RET(glsl_hdr, buf);
4747 }
4748 if (ctx->color_in_mask & 2) {
4749 snprintf(buf, 255, "vec4 realcolor1;\n");
4750 STRCAT_WITH_RET(glsl_hdr, buf);
4751 }
4752 }
4753 if (ctx->num_ubo) {
4754 const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
4755
4756 if (ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT)) {
4757 require_glsl_ver(ctx, 150);
4758 snprintf(buf, 255, "uniform %subo { vec4 ubocontents[%d]; } %suboarr[%d];\n", cname, ctx->ubo_sizes[0], cname, ctx->num_ubo);
4759 STRCAT_WITH_RET(glsl_hdr, buf);
4760 } else {
4761 for (i = 0; i < ctx->num_ubo; i++) {
4762 snprintf(buf, 255, "uniform %subo%d { vec4 %subo%dcontents[%d]; };\n", cname, ctx->ubo_idx[i], cname, ctx->ubo_idx[i], ctx->ubo_sizes[i]);
4763 STRCAT_WITH_RET(glsl_hdr, buf);
4764 }
4765 }
4766 }
4767
4768 if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
4769 for (i = 0; i < ctx->num_sampler_arrays; i++) {
4770 uint32_t first = ctx->sampler_arrays[i].first;
4771 uint32_t range = ctx->sampler_arrays[i].array_size;
4772 glsl_hdr = emit_sampler_decl(ctx, glsl_hdr, first, range, ctx->samplers + first);
4773 if (!glsl_hdr)
4774 return NULL;
4775 }
4776 } else {
4777 nsamp = util_last_bit(ctx->samplers_used);
4778 for (i = 0; i < nsamp; i++) {
4779
4780 if ((ctx->samplers_used & (1 << i)) == 0)
4781 continue;
4782
4783 glsl_hdr = emit_sampler_decl(ctx, glsl_hdr, i, 0, ctx->samplers + i);
4784 if (!glsl_hdr)
4785 return NULL;
4786 }
4787 }
4788
4789 if (ctx->info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
4790 for (i = 0; i < ctx->num_image_arrays; i++) {
4791 uint32_t first = ctx->image_arrays[i].first;
4792 uint32_t range = ctx->image_arrays[i].array_size;
4793 glsl_hdr = emit_image_decl(ctx, glsl_hdr, first, range, ctx->images + first);
4794 if (!glsl_hdr)
4795 return NULL;
4796 }
4797 } else {
4798 uint32_t mask = ctx->images_used_mask;
4799 while (mask) {
4800 i = u_bit_scan(&mask);
4801 glsl_hdr = emit_image_decl(ctx, glsl_hdr, i, 0, ctx->images + i);
4802 if (!glsl_hdr)
4803 return NULL;
4804 }
4805 }
4806
4807 if (ctx->info.indirect_files & (1 << TGSI_FILE_BUFFER)) {
4808 uint32_t mask = ctx->ssbo_used_mask;
4809 while (mask) {
4810 int start, count;
4811 u_bit_scan_consecutive_range(&mask, &start, &count);
4812 const char *atomic = (ctx->ssbo_atomic_mask & (1 << start)) ? "atomic" : "";
4813 snprintf(buf, 255, "layout (binding = %d, std430) buffer %sssbo%d { uint %sssbocontents%d[]; } %sssboarr%s[%d];\n", start, sname, start, sname, start, sname, atomic, count);
4814 STRCAT_WITH_RET(glsl_hdr, buf);
4815 }
4816 } else {
4817 uint32_t mask = ctx->ssbo_used_mask;
4818 while (mask) {
4819 uint32_t id = u_bit_scan(&mask);
4820 sname = tgsi_proc_to_prefix(ctx->prog_type);
4821 enum vrend_type_qualifier type = (ctx->ssbo_integer_mask & (1 << id)) ? INT : UINT;
4822 snprintf(buf, 255, "layout (binding = %d, std430) buffer %sssbo%d { %s %sssbocontents%d[]; };\n", id, sname, id,
4823 get_string(type), sname, id);
4824 STRCAT_WITH_RET(glsl_hdr, buf);
4825 }
4826 }
4827
4828 if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT &&
4829 ctx->key->pstipple_tex == true) {
4830 snprintf(buf, 255, "uniform sampler2D pstipple_sampler;\nfloat stip_temp;\n");
4831 STRCAT_WITH_RET(glsl_hdr, buf);
4832 }
4833 return glsl_hdr;
4834 }
4835
fill_fragment_interpolants(struct dump_ctx * ctx,struct vrend_shader_info * sinfo)4836 static boolean fill_fragment_interpolants(struct dump_ctx *ctx, struct vrend_shader_info *sinfo)
4837 {
4838 uint32_t i, index = 0;
4839
4840 for (i = 0; i < ctx->num_inputs; i++) {
4841 if (ctx->inputs[i].glsl_predefined_no_emit)
4842 continue;
4843
4844 if (ctx->inputs[i].name != TGSI_SEMANTIC_GENERIC &&
4845 ctx->inputs[i].name != TGSI_SEMANTIC_COLOR)
4846 continue;
4847
4848 if (index >= ctx->num_interps) {
4849 fprintf(stderr, "mismatch in number of interps %d %d\n", index, ctx->num_interps);
4850 return TRUE;
4851 }
4852 sinfo->interpinfo[index].semantic_name = ctx->inputs[i].name;
4853 sinfo->interpinfo[index].semantic_index = ctx->inputs[i].sid;
4854 sinfo->interpinfo[index].interpolate = ctx->inputs[i].interpolate;
4855 sinfo->interpinfo[index].location = ctx->inputs[i].location;
4856 index++;
4857 }
4858 return TRUE;
4859 }
4860
fill_interpolants(struct dump_ctx * ctx,struct vrend_shader_info * sinfo)4861 static boolean fill_interpolants(struct dump_ctx *ctx, struct vrend_shader_info *sinfo)
4862 {
4863 boolean ret;
4864
4865 if (!ctx->num_interps)
4866 return TRUE;
4867 if (ctx->prog_type == TGSI_PROCESSOR_VERTEX || ctx->prog_type == TGSI_PROCESSOR_GEOMETRY)
4868 return TRUE;
4869
4870 free(sinfo->interpinfo);
4871 sinfo->interpinfo = calloc(ctx->num_interps, sizeof(struct vrend_interp_info));
4872 if (!sinfo->interpinfo)
4873 return FALSE;
4874
4875 ret = fill_fragment_interpolants(ctx, sinfo);
4876 if (ret == FALSE)
4877 goto out_fail;
4878
4879 return TRUE;
4880 out_fail:
4881 free(sinfo->interpinfo);
4882 return FALSE;
4883 }
4884
analyze_instruction(struct tgsi_iterate_context * iter,struct tgsi_full_instruction * inst)4885 static boolean analyze_instruction(struct tgsi_iterate_context *iter,
4886 struct tgsi_full_instruction *inst)
4887 {
4888 struct dump_ctx *ctx = (struct dump_ctx *)iter;
4889 uint32_t opcode = inst->Instruction.Opcode;
4890 if (opcode == TGSI_OPCODE_ATOMIMIN || opcode == TGSI_OPCODE_ATOMIMAX) {
4891 const struct tgsi_full_src_register *src = &inst->Src[0];
4892 if (src->Register.File == TGSI_FILE_BUFFER)
4893 ctx->ssbo_integer_mask |= 1 << src->Register.Index;
4894 if (src->Register.File == TGSI_FILE_MEMORY)
4895 ctx->integer_memory = true;
4896 }
4897
4898 return true;
4899 }
4900
vrend_convert_shader(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)4901 char *vrend_convert_shader(struct vrend_shader_cfg *cfg,
4902 const struct tgsi_token *tokens,
4903 uint32_t req_local_mem,
4904 struct vrend_shader_key *key,
4905 struct vrend_shader_info *sinfo)
4906 {
4907 struct dump_ctx ctx;
4908 char *glsl_final = NULL;
4909 boolean bret;
4910 char *glsl_hdr = NULL;
4911
4912 memset(&ctx, 0, sizeof(struct dump_ctx));
4913
4914 /* First pass to deal with edge cases. */
4915 ctx.iter.iterate_instruction = analyze_instruction;
4916 bret = tgsi_iterate_shader(tokens, &ctx.iter);
4917 if (bret == FALSE)
4918 return NULL;
4919
4920 ctx.iter.prolog = prolog;
4921 ctx.iter.iterate_instruction = iter_instruction;
4922 ctx.iter.iterate_declaration = iter_declaration;
4923 ctx.iter.iterate_immediate = iter_immediate;
4924 ctx.iter.iterate_property = iter_property;
4925 ctx.iter.epilog = NULL;
4926 ctx.key = key;
4927 ctx.cfg = cfg;
4928 ctx.prog_type = -1;
4929 ctx.num_image_arrays = 0;
4930 ctx.image_arrays = NULL;
4931 ctx.num_sampler_arrays = 0;
4932 ctx.sampler_arrays = NULL;
4933 ctx.ssbo_array_base = 0xffffffff;
4934 ctx.ssbo_atomic_array_base = 0xffffffff;
4935 ctx.has_sample_input = false;
4936 ctx.req_local_mem = req_local_mem;
4937 tgsi_scan_shader(tokens, &ctx.info);
4938 /* if we are in core profile mode we should use GLSL 1.40 */
4939 if (cfg->use_core_profile && cfg->glsl_version >= 140)
4940 require_glsl_ver(&ctx, 140);
4941
4942 if (sinfo->so_info.num_outputs) {
4943 ctx.so = &sinfo->so_info;
4944 ctx.so_names = calloc(sinfo->so_info.num_outputs, sizeof(char *));
4945 if (!ctx.so_names)
4946 goto fail;
4947 } else
4948 ctx.so_names = NULL;
4949
4950 if (ctx.info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT))
4951 require_glsl_ver(&ctx, 150);
4952
4953 if (ctx.info.indirect_files & (1 << TGSI_FILE_BUFFER) ||
4954 ctx.info.indirect_files & (1 << TGSI_FILE_IMAGE)) {
4955 require_glsl_ver(&ctx, 150);
4956 ctx.shader_req_bits |= SHADER_REQ_GPU_SHADER5;
4957 }
4958 if (ctx.info.indirect_files & (1 << TGSI_FILE_SAMPLER))
4959 ctx.shader_req_bits |= SHADER_REQ_GPU_SHADER5;
4960
4961 ctx.glsl_main = malloc(4096);
4962 if (!ctx.glsl_main)
4963 goto fail;
4964
4965 ctx.glsl_main[0] = '\0';
4966 bret = tgsi_iterate_shader(tokens, &ctx.iter);
4967 if (bret == FALSE)
4968 goto fail;
4969
4970 glsl_hdr = malloc(1024);
4971 if (!glsl_hdr)
4972 goto fail;
4973 glsl_hdr[0] = '\0';
4974 glsl_hdr = emit_header(&ctx, glsl_hdr);
4975 if (!glsl_hdr)
4976 goto fail;
4977
4978 glsl_hdr = emit_ios(&ctx, glsl_hdr);
4979 if (!glsl_hdr)
4980 goto fail;
4981
4982 glsl_final = malloc(strlen(glsl_hdr) + strlen(ctx.glsl_main) + 1);
4983 if (!glsl_final)
4984 goto fail;
4985
4986 glsl_final[0] = '\0';
4987
4988 bret = fill_interpolants(&ctx, sinfo);
4989 if (bret == FALSE)
4990 goto fail;
4991
4992 strcat(glsl_final, glsl_hdr);
4993 strcat(glsl_final, ctx.glsl_main);
4994 if (vrend_dump_shaders)
4995 fprintf(stderr,"GLSL: %s\n", glsl_final);
4996 free(ctx.temp_ranges);
4997 free(ctx.glsl_main);
4998 free(glsl_hdr);
4999 sinfo->num_ucp = ctx.key->clip_plane_enable ? 8 : 0;
5000 sinfo->has_pervertex_out = ctx.vs_has_pervertex;
5001 sinfo->has_sample_input = ctx.has_sample_input;
5002 bool has_prop = (ctx.num_clip_dist_prop + ctx.num_cull_dist_prop) > 0;
5003 sinfo->num_clip_out = has_prop ? ctx.num_clip_dist_prop : (ctx.num_clip_dist ? ctx.num_clip_dist : 8);
5004 sinfo->num_cull_out = has_prop ? ctx.num_cull_dist_prop : 0;
5005 sinfo->samplers_used_mask = ctx.samplers_used;
5006 sinfo->images_used_mask = ctx.images_used_mask;
5007 sinfo->num_consts = ctx.num_consts;
5008 sinfo->num_ubos = ctx.num_ubo;
5009 memcpy(sinfo->ubo_idx, ctx.ubo_idx, ctx.num_ubo * sizeof(*ctx.ubo_idx));
5010
5011 sinfo->ssbo_used_mask = ctx.ssbo_used_mask;
5012
5013 sinfo->ubo_indirect = ctx.info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT);
5014 if (ctx_indirect_inputs(&ctx)) {
5015 if (ctx.generic_input_range.used)
5016 sinfo->num_indirect_generic_inputs = ctx.generic_input_range.last - ctx.generic_input_range.first + 1;
5017 if (ctx.patch_input_range.used)
5018 sinfo->num_indirect_patch_inputs = ctx.patch_input_range.last - ctx.patch_input_range.first + 1;
5019 }
5020 if (ctx_indirect_outputs(&ctx)) {
5021 if (ctx.generic_output_range.used)
5022 sinfo->num_indirect_generic_outputs = ctx.generic_output_range.last - ctx.generic_output_range.first + 1;
5023 if (ctx.patch_output_range.used)
5024 sinfo->num_indirect_patch_outputs = ctx.patch_output_range.last - ctx.patch_output_range.first + 1;
5025 }
5026
5027 sinfo->num_inputs = ctx.num_inputs;
5028 sinfo->num_interps = ctx.num_interps;
5029 sinfo->num_outputs = ctx.num_outputs;
5030 sinfo->shadow_samp_mask = ctx.shadow_samp_mask;
5031 sinfo->glsl_ver = ctx.glsl_ver_required;
5032 sinfo->gs_out_prim = ctx.gs_out_prim;
5033 sinfo->tes_prim = ctx.tes_prim_mode;
5034 sinfo->tes_point_mode = ctx.tes_point_mode;
5035 sinfo->so_names = ctx.so_names;
5036 sinfo->attrib_input_mask = ctx.attrib_input_mask;
5037 sinfo->sampler_arrays = ctx.sampler_arrays;
5038 sinfo->num_sampler_arrays = ctx.num_sampler_arrays;
5039 sinfo->image_arrays = ctx.image_arrays;
5040 sinfo->num_image_arrays = ctx.num_image_arrays;
5041 return glsl_final;
5042 fail:
5043 free(ctx.glsl_main);
5044 free(glsl_final);
5045 free(glsl_hdr);
5046 free(ctx.so_names);
5047 free(ctx.temp_ranges);
5048 return NULL;
5049 }
5050
replace_interp(char * program,const char * var_name,const char * pstring,const char * auxstring)5051 static void replace_interp(char *program,
5052 const char *var_name,
5053 const char *pstring, const char *auxstring)
5054 {
5055 char *ptr;
5056 int mylen = strlen(INTERP_PREFIX) + strlen("out vec4 ");
5057
5058 ptr = strstr(program, var_name);
5059
5060 if (!ptr)
5061 return;
5062
5063 ptr -= mylen;
5064
5065 memset(ptr, ' ', strlen(INTERP_PREFIX));
5066 memcpy(ptr, pstring, strlen(pstring));
5067 memcpy(ptr + strlen(pstring), auxstring, strlen(auxstring));
5068 }
5069
5070 static const char *gpu_shader5_string = "#extension GL_ARB_gpu_shader5 : require\n";
5071
require_gpu_shader5(char * program)5072 static void require_gpu_shader5(char *program)
5073 {
5074 /* the first line is the #version line */
5075 char *ptr = strchr(program, '\n');
5076 if (!ptr)
5077 return;
5078 ptr++;
5079
5080 memcpy(ptr, gpu_shader5_string, strlen(gpu_shader5_string));
5081 }
5082
vrend_patch_vertex_shader_interpolants(struct vrend_shader_cfg * cfg,char * program,struct vrend_shader_info * vs_info,struct vrend_shader_info * fs_info,const char * oprefix,bool flatshade)5083 bool vrend_patch_vertex_shader_interpolants(struct vrend_shader_cfg *cfg, char *program,
5084 struct vrend_shader_info *vs_info,
5085 struct vrend_shader_info *fs_info, const char *oprefix, bool flatshade)
5086 {
5087 int i;
5088 const char *pstring, *auxstring;
5089 char glsl_name[64];
5090 if (!vs_info || !fs_info)
5091 return true;
5092
5093 if (!fs_info->interpinfo)
5094 return true;
5095
5096 if (fs_info->has_sample_input)
5097 require_gpu_shader5(program);
5098
5099 for (i = 0; i < fs_info->num_interps; i++) {
5100 pstring = get_interp_string(cfg, fs_info->interpinfo[i].interpolate, flatshade);
5101 if (!pstring)
5102 continue;
5103
5104 auxstring = get_aux_string(fs_info->interpinfo[i].location);
5105
5106 switch (fs_info->interpinfo[i].semantic_name) {
5107 case TGSI_SEMANTIC_COLOR:
5108 /* color is a bit trickier */
5109 if (fs_info->glsl_ver < 140) {
5110 if (fs_info->interpinfo[i].semantic_index == 1) {
5111 replace_interp(program, "gl_FrontSecondaryColor", pstring, auxstring);
5112 replace_interp(program, "gl_BackSecondaryColor", pstring, auxstring);
5113 } else {
5114 replace_interp(program, "gl_FrontColor", pstring, auxstring);
5115 replace_interp(program, "gl_BackColor", pstring, auxstring);
5116 }
5117 } else {
5118 snprintf(glsl_name, 64, "ex_c%d", fs_info->interpinfo[i].semantic_index);
5119 replace_interp(program, glsl_name, pstring, auxstring);
5120 snprintf(glsl_name, 64, "ex_bc%d", fs_info->interpinfo[i].semantic_index);
5121 replace_interp(program, glsl_name, pstring, auxstring);
5122 }
5123 break;
5124 case TGSI_SEMANTIC_GENERIC:
5125 snprintf(glsl_name, 64, "%s_g%d", oprefix, fs_info->interpinfo[i].semantic_index);
5126 replace_interp(program, glsl_name, pstring, auxstring);
5127 break;
5128 default:
5129 fprintf(stderr,"unhandled semantic: %x\n", fs_info->interpinfo[i].semantic_name);
5130 return false;
5131 }
5132 }
5133
5134 if (vrend_dump_shaders)
5135 fprintf(stderr,"GLSL: post interp: %s\n", program);
5136 return true;
5137 }
5138