1/**************************************************************************
2 *
3 * Copyright 2008 VMware, Inc.
4 * All Rights Reserved.
5 * Copyright 2009 Marek Olšák <maraeo@gmail.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29/**
30 * @file
31 * Simple vertex/fragment shader generators.
32 *
33 * @author Brian Paul
34           Marek Olšák
35 */
36
37
38#include "pipe/p_context.h"
39#include "pipe/p_shader_tokens.h"
40#include "pipe/p_state.h"
41#include "util/u_simple_shaders.h"
42#include "util/u_debug.h"
43#include "util/u_memory.h"
44#include "util/u_string.h"
45#include "tgsi/tgsi_dump.h"
46#include "tgsi/tgsi_strings.h"
47#include "tgsi/tgsi_ureg.h"
48#include "tgsi/tgsi_text.h"
49#include <stdio.h> /* include last */
50
51
52
53/**
54 * Make simple vertex pass-through shader.
55 * \param num_attribs  number of attributes to pass through
56 * \param semantic_names  array of semantic names for each attribute
57 * \param semantic_indexes  array of semantic indexes for each attribute
58 */
59void *
60util_make_vertex_passthrough_shader(struct pipe_context *pipe,
61                                    uint num_attribs,
62                                    const enum tgsi_semantic *semantic_names,
63                                    const uint *semantic_indexes,
64                                    bool window_space)
65{
66   return util_make_vertex_passthrough_shader_with_so(pipe, num_attribs,
67                                                      semantic_names,
68                                                      semantic_indexes,
69                                                      window_space, false, NULL);
70}
71
72void *
73util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe,
74                                    uint num_attribs,
75                                    const enum tgsi_semantic *semantic_names,
76                                    const uint *semantic_indexes,
77                                    bool window_space, bool layered,
78				    const struct pipe_stream_output_info *so)
79{
80   struct ureg_program *ureg;
81   uint i;
82
83   ureg = ureg_create( PIPE_SHADER_VERTEX );
84   if (!ureg)
85      return NULL;
86
87   if (window_space)
88      ureg_property(ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, TRUE);
89
90   for (i = 0; i < num_attribs; i++) {
91      struct ureg_src src;
92      struct ureg_dst dst;
93
94      src = ureg_DECL_vs_input( ureg, i );
95
96      dst = ureg_DECL_output( ureg,
97                              semantic_names[i],
98                              semantic_indexes[i]);
99
100      ureg_MOV( ureg, dst, src );
101   }
102
103   if (layered) {
104      struct ureg_src instance_id =
105         ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0);
106      struct ureg_dst layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0);
107
108      ureg_MOV(ureg, ureg_writemask(layer, TGSI_WRITEMASK_X),
109               ureg_scalar(instance_id, TGSI_SWIZZLE_X));
110   }
111
112   ureg_END( ureg );
113
114   return ureg_create_shader_with_so_and_destroy( ureg, pipe, so );
115}
116
117
118void *util_make_layered_clear_vertex_shader(struct pipe_context *pipe)
119{
120   const enum tgsi_semantic semantic_names[] = {TGSI_SEMANTIC_POSITION,
121                                                TGSI_SEMANTIC_GENERIC};
122   const unsigned semantic_indices[] = {0, 0};
123
124   return util_make_vertex_passthrough_shader_with_so(pipe, 2, semantic_names,
125                                                      semantic_indices, false,
126                                                      true, NULL);
127}
128
129/**
130 * Takes position and color, and outputs position, color, and instance id.
131 */
132void *util_make_layered_clear_helper_vertex_shader(struct pipe_context *pipe)
133{
134   static const char text[] =
135         "VERT\n"
136         "DCL IN[0]\n"
137         "DCL IN[1]\n"
138         "DCL SV[0], INSTANCEID\n"
139         "DCL OUT[0], POSITION\n"
140         "DCL OUT[1], GENERIC[0]\n"
141         "DCL OUT[2], GENERIC[1]\n"
142
143         "MOV OUT[0], IN[0]\n"
144         "MOV OUT[1], IN[1]\n"
145         "MOV OUT[2].x, SV[0].xxxx\n"
146         "END\n";
147   struct tgsi_token tokens[1000];
148   struct pipe_shader_state state = {0};
149
150   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
151      assert(0);
152      return NULL;
153   }
154   pipe_shader_state_from_tgsi(&state, tokens);
155   return pipe->create_vs_state(pipe, &state);
156}
157
158/**
159 * Takes position, color, and target layer, and emits vertices on that target
160 * layer, with the specified color.
161 */
162void *util_make_layered_clear_geometry_shader(struct pipe_context *pipe)
163{
164   static const char text[] =
165      "GEOM\n"
166      "PROPERTY GS_INPUT_PRIMITIVE TRIANGLES\n"
167      "PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP\n"
168      "PROPERTY GS_MAX_OUTPUT_VERTICES 3\n"
169      "PROPERTY GS_INVOCATIONS 1\n"
170      "DCL IN[][0], POSITION\n" /* position */
171      "DCL IN[][1], GENERIC[0]\n" /* color */
172      "DCL IN[][2], GENERIC[1]\n" /* vs invocation */
173      "DCL OUT[0], POSITION\n"
174      "DCL OUT[1], GENERIC[0]\n"
175      "DCL OUT[2], LAYER\n"
176      "IMM[0] INT32 {0, 0, 0, 0}\n"
177
178      "MOV OUT[0], IN[0][0]\n"
179      "MOV OUT[1], IN[0][1]\n"
180      "MOV OUT[2].x, IN[0][2].xxxx\n"
181      "EMIT IMM[0].xxxx\n"
182      "MOV OUT[0], IN[1][0]\n"
183      "MOV OUT[1], IN[1][1]\n"
184      "MOV OUT[2].x, IN[1][2].xxxx\n"
185      "EMIT IMM[0].xxxx\n"
186      "MOV OUT[0], IN[2][0]\n"
187      "MOV OUT[1], IN[2][1]\n"
188      "MOV OUT[2].x, IN[2][2].xxxx\n"
189      "EMIT IMM[0].xxxx\n"
190      "END\n";
191   struct tgsi_token tokens[1000];
192   struct pipe_shader_state state = {0};
193
194   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
195      assert(0);
196      return NULL;
197   }
198   pipe_shader_state_from_tgsi(&state, tokens);
199   return pipe->create_gs_state(pipe, &state);
200}
201
202static void
203ureg_load_tex(struct ureg_program *ureg, struct ureg_dst out,
204              struct ureg_src coord, struct ureg_src sampler,
205              enum tgsi_texture_type tex_target,
206              bool load_level_zero, bool use_txf)
207{
208   if (use_txf) {
209      struct ureg_dst temp = ureg_DECL_temporary(ureg);
210
211      ureg_F2I(ureg, temp, coord);
212
213      if (load_level_zero)
214         ureg_TXF_LZ(ureg, out, tex_target, ureg_src(temp), sampler);
215      else
216         ureg_TXF(ureg, out, tex_target, ureg_src(temp), sampler);
217   } else {
218      if (load_level_zero)
219         ureg_TEX_LZ(ureg, out, tex_target, coord, sampler);
220      else
221         ureg_TEX(ureg, out, tex_target, coord, sampler);
222   }
223}
224
225/**
226 * Make simple fragment texture shader, with xrbias->float conversion:
227 *  IMM {1023/510, -384/510, 0, 1}
228 *  TEX TEMP[0], IN[0], SAMP[0], 2D;
229 *  MAD TEMP[0].xyz TEMP[0], IMM[0].xxxx, IMM[0].yyyy
230 *  MOV OUT[0], TEMP[0]
231 *  END;
232 *
233 * \param tex_target  one of PIPE_TEXTURE_x
234 */
235void *
236util_make_fragment_tex_shader_xrbias(struct pipe_context *pipe,
237                                     enum tgsi_texture_type tex_target)
238{
239   struct ureg_program *ureg;
240   struct ureg_src sampler;
241   struct ureg_src coord;
242   struct ureg_dst temp;
243   struct ureg_dst out;
244   struct ureg_src imm;
245   enum tgsi_return_type stype = TGSI_RETURN_TYPE_FLOAT;
246
247   ureg = ureg_create(PIPE_SHADER_FRAGMENT);
248   if (!ureg)
249      return NULL;
250
251   imm = ureg_imm4f(ureg, 1023.0f/510.0f, -384.0f/510.0f, 0.0f, 1.0f);
252   sampler = ureg_DECL_sampler(ureg, 0);
253   ureg_DECL_sampler_view(ureg, 0, tex_target, stype, stype, stype, stype);
254   coord = ureg_DECL_fs_input(ureg,
255                              TGSI_SEMANTIC_GENERIC, 0,
256                              TGSI_INTERPOLATE_LINEAR);
257   out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
258   temp = ureg_DECL_temporary(ureg);
259
260   ureg_TEX(ureg, temp, tex_target, coord, sampler);
261   ureg_MAD(ureg, ureg_writemask(temp, TGSI_WRITEMASK_XYZ),
262            ureg_src(temp),
263            ureg_scalar(imm, TGSI_SWIZZLE_X),
264            ureg_scalar(imm, TGSI_SWIZZLE_Y));
265   ureg_MOV(ureg, out, ureg_src(temp));
266   ureg_END(ureg);
267
268   return ureg_create_shader_and_destroy(ureg, pipe);
269}
270
271
272/**
273 * Make simple fragment texture shader:
274 *  IMM {0,0,0,1}                         // (if writemask != 0xf)
275 *  MOV TEMP[0], IMM[0]                   // (if writemask != 0xf)
276 *  TEX TEMP[0].writemask, IN[0], SAMP[0], 2D;
277 *   .. optional SINT <-> UINT clamping ..
278 *  MOV OUT[0], TEMP[0]
279 *  END;
280 *
281 * \param tex_target  one of TGSI_TEXTURE_x
282 * \parma interp_mode  either TGSI_INTERPOLATE_LINEAR or PERSPECTIVE
283 * \param writemask  mask of TGSI_WRITEMASK_x
284 */
285void *
286util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
287                                        enum tgsi_texture_type tex_target,
288                                        enum tgsi_interpolate_mode interp_mode,
289                                        unsigned writemask,
290                                        enum tgsi_return_type stype,
291                                        enum tgsi_return_type dtype,
292                                        bool load_level_zero,
293                                        bool use_txf)
294{
295   struct ureg_program *ureg;
296   struct ureg_src sampler;
297   struct ureg_src tex;
298   struct ureg_dst temp;
299   struct ureg_dst out;
300
301   assert((stype == TGSI_RETURN_TYPE_FLOAT) == (dtype == TGSI_RETURN_TYPE_FLOAT));
302   assert(interp_mode == TGSI_INTERPOLATE_LINEAR ||
303          interp_mode == TGSI_INTERPOLATE_PERSPECTIVE);
304
305   ureg = ureg_create( PIPE_SHADER_FRAGMENT );
306   if (!ureg)
307      return NULL;
308
309   sampler = ureg_DECL_sampler( ureg, 0 );
310
311   ureg_DECL_sampler_view(ureg, 0, tex_target, stype, stype, stype, stype);
312
313   tex = ureg_DECL_fs_input( ureg,
314                             TGSI_SEMANTIC_GENERIC, 0,
315                             interp_mode );
316
317   out = ureg_DECL_output( ureg,
318                           TGSI_SEMANTIC_COLOR,
319                           0 );
320
321   temp = ureg_DECL_temporary(ureg);
322
323   if (writemask != TGSI_WRITEMASK_XYZW) {
324      struct ureg_src imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
325
326      ureg_MOV(ureg, temp, imm);
327   }
328
329   if (tex_target == TGSI_TEXTURE_BUFFER)
330      ureg_TXF(ureg,
331               ureg_writemask(temp, writemask),
332               tex_target, tex, sampler);
333   else
334      ureg_load_tex(ureg, ureg_writemask(temp, writemask), tex, sampler,
335                    tex_target, load_level_zero, use_txf);
336
337   if (stype != dtype) {
338      if (stype == TGSI_RETURN_TYPE_SINT) {
339         assert(dtype == TGSI_RETURN_TYPE_UINT);
340
341         ureg_IMAX(ureg, temp, ureg_src(temp), ureg_imm1i(ureg, 0));
342      } else {
343         assert(stype == TGSI_RETURN_TYPE_UINT);
344         assert(dtype == TGSI_RETURN_TYPE_SINT);
345
346         ureg_UMIN(ureg, temp, ureg_src(temp), ureg_imm1u(ureg, (1u << 31) - 1));
347      }
348   }
349
350   ureg_MOV(ureg, out, ureg_src(temp));
351
352   ureg_END( ureg );
353
354   return ureg_create_shader_and_destroy( ureg, pipe );
355}
356
357
358/**
359 * Make a simple fragment shader that sets the output color to a color
360 * taken from a texture.
361 * \param tex_target  one of TGSI_TEXTURE_x
362 */
363void *
364util_make_fragment_tex_shader(struct pipe_context *pipe,
365                              enum tgsi_texture_type tex_target,
366                              enum tgsi_interpolate_mode interp_mode,
367                              enum tgsi_return_type stype,
368                              enum tgsi_return_type dtype,
369                              bool load_level_zero,
370                              bool use_txf)
371{
372   return util_make_fragment_tex_shader_writemask( pipe,
373                                                   tex_target,
374                                                   interp_mode,
375                                                   TGSI_WRITEMASK_XYZW,
376                                                   stype, dtype, load_level_zero,
377                                                   use_txf);
378}
379
380
381/**
382 * Make a simple fragment texture shader which reads the texture unit 0 and 1
383 * and writes it as depth and stencil, respectively.
384 */
385void *
386util_make_fs_blit_zs(struct pipe_context *pipe, unsigned zs_mask,
387                     enum tgsi_texture_type tex_target,
388                     bool load_level_zero, bool use_txf)
389{
390   struct ureg_program *ureg;
391   struct ureg_src depth_sampler, stencil_sampler, coord;
392   struct ureg_dst depth, stencil, tmp;
393
394   ureg = ureg_create(PIPE_SHADER_FRAGMENT);
395   if (!ureg)
396      return NULL;
397
398   coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0,
399                              TGSI_INTERPOLATE_LINEAR);
400   tmp = ureg_DECL_temporary(ureg);
401
402   if (zs_mask & PIPE_MASK_Z) {
403      depth_sampler = ureg_DECL_sampler(ureg, 0);
404      ureg_DECL_sampler_view(ureg, 0, tex_target,
405                             TGSI_RETURN_TYPE_FLOAT,
406                             TGSI_RETURN_TYPE_FLOAT,
407                             TGSI_RETURN_TYPE_FLOAT,
408                             TGSI_RETURN_TYPE_FLOAT);
409
410      ureg_load_tex(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), coord,
411                    depth_sampler, tex_target, load_level_zero, use_txf);
412
413      depth = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
414      ureg_MOV(ureg, ureg_writemask(depth, TGSI_WRITEMASK_Z),
415               ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X));
416   }
417
418   if (zs_mask & PIPE_MASK_S) {
419      stencil_sampler = ureg_DECL_sampler(ureg, zs_mask & PIPE_MASK_Z ? 1 : 0);
420      ureg_DECL_sampler_view(ureg, zs_mask & PIPE_MASK_Z ? 1 : 0, tex_target,
421                             TGSI_RETURN_TYPE_UINT,
422                             TGSI_RETURN_TYPE_UINT,
423                             TGSI_RETURN_TYPE_UINT,
424                             TGSI_RETURN_TYPE_UINT);
425
426      ureg_load_tex(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), coord,
427                    stencil_sampler, tex_target, load_level_zero, use_txf);
428
429      stencil = ureg_DECL_output(ureg, TGSI_SEMANTIC_STENCIL, 0);
430      ureg_MOV(ureg, ureg_writemask(stencil, TGSI_WRITEMASK_Y),
431               ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X));
432   }
433
434   ureg_END(ureg);
435
436   return ureg_create_shader_and_destroy(ureg, pipe);
437}
438
439
440/**
441 * Make simple fragment color pass-through shader that replicates OUT[0]
442 * to all bound colorbuffers.
443 */
444void *
445util_make_fragment_passthrough_shader(struct pipe_context *pipe,
446                                      int input_semantic,
447                                      int input_interpolate,
448                                      boolean write_all_cbufs)
449{
450   static const char shader_templ[] =
451         "FRAG\n"
452         "%s"
453         "DCL IN[0], %s[0], %s\n"
454         "DCL OUT[0], COLOR[0]\n"
455
456         "MOV OUT[0], IN[0]\n"
457         "END\n";
458
459   char text[sizeof(shader_templ)+100];
460   struct tgsi_token tokens[1000];
461   struct pipe_shader_state state = {0};
462
463   sprintf(text, shader_templ,
464           write_all_cbufs ? "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n" : "",
465           tgsi_semantic_names[input_semantic],
466           tgsi_interpolate_names[input_interpolate]);
467
468   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
469      assert(0);
470      return NULL;
471   }
472   pipe_shader_state_from_tgsi(&state, tokens);
473#if 0
474   tgsi_dump(state.tokens, 0);
475#endif
476
477   return pipe->create_fs_state(pipe, &state);
478}
479
480
481void *
482util_make_empty_fragment_shader(struct pipe_context *pipe)
483{
484   struct ureg_program *ureg = ureg_create(PIPE_SHADER_FRAGMENT);
485   if (!ureg)
486      return NULL;
487
488   ureg_END(ureg);
489   return ureg_create_shader_and_destroy(ureg, pipe);
490}
491
492
493/**
494 * Make a fragment shader that copies the input color to N output colors.
495 */
496void *
497util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
498                                     int input_semantic,
499                                     int input_interpolate)
500{
501   struct ureg_program *ureg;
502   struct ureg_src src;
503   struct ureg_dst dst[PIPE_MAX_COLOR_BUFS];
504   int i;
505
506   assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
507
508   ureg = ureg_create( PIPE_SHADER_FRAGMENT );
509   if (!ureg)
510      return NULL;
511
512   src = ureg_DECL_fs_input( ureg, input_semantic, 0,
513                             input_interpolate );
514
515   for (i = 0; i < num_cbufs; i++)
516      dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i );
517
518   for (i = 0; i < num_cbufs; i++)
519      ureg_MOV( ureg, dst[i], src );
520
521   ureg_END( ureg );
522
523   return ureg_create_shader_and_destroy( ureg, pipe );
524}
525
526
527static void *
528util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
529                           enum tgsi_texture_type tgsi_tex,
530                           bool sample_shading,
531                           const char *samp_type,
532                           const char *output_semantic,
533                           const char *output_mask,
534                           const char *conversion_decl,
535                           const char *conversion)
536{
537   static const char shader_templ[] =
538         "FRAG\n"
539         "DCL IN[0], GENERIC[0], LINEAR\n"
540         "DCL SAMP[0]\n"
541         "DCL SVIEW[0], %s, %s\n"
542         "DCL OUT[0], %s\n"
543         "DCL TEMP[0]\n"
544         "%s"
545         "%s"
546
547         "F2U TEMP[0], IN[0]\n"
548         "%s"
549         "TXF TEMP[0], TEMP[0], SAMP[0], %s\n"
550         "%s"
551         "MOV OUT[0]%s, TEMP[0]\n"
552         "END\n";
553
554   const char *type = tgsi_texture_names[tgsi_tex];
555   char text[sizeof(shader_templ)+400];
556   struct tgsi_token tokens[1000];
557   struct pipe_shader_state state = {0};
558
559   assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA ||
560          tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA);
561
562   snprintf(text, sizeof(text), shader_templ, type, samp_type,
563            output_semantic, sample_shading ? "DCL SV[0], SAMPLEID\n" : "",
564            conversion_decl, sample_shading ? "MOV TEMP[0].w, SV[0].xxxx\n" : "",
565            type, conversion, output_mask);
566
567   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
568      puts(text);
569      assert(0);
570      return NULL;
571   }
572   pipe_shader_state_from_tgsi(&state, tokens);
573#if 0
574   tgsi_dump(state.tokens, 0);
575#endif
576
577   return pipe->create_fs_state(pipe, &state);
578}
579
580
581/**
582 * Make a fragment shader that sets the output color to a color
583 * fetched from a multisample texture.
584 * \param tex_target  one of PIPE_TEXTURE_x
585 */
586void *
587util_make_fs_blit_msaa_color(struct pipe_context *pipe,
588                             enum tgsi_texture_type tgsi_tex,
589                             enum tgsi_return_type stype,
590                             enum tgsi_return_type dtype,
591                             bool sample_shading)
592{
593   const char *samp_type;
594   const char *conversion_decl = "";
595   const char *conversion = "";
596
597   if (stype == TGSI_RETURN_TYPE_UINT) {
598      samp_type = "UINT";
599
600      if (dtype == TGSI_RETURN_TYPE_SINT) {
601         conversion_decl = "IMM[0] UINT32 {2147483647, 0, 0, 0}\n";
602         conversion = "UMIN TEMP[0], TEMP[0], IMM[0].xxxx\n";
603      }
604   } else if (stype == TGSI_RETURN_TYPE_SINT) {
605      samp_type = "SINT";
606
607      if (dtype == TGSI_RETURN_TYPE_UINT) {
608         conversion_decl = "IMM[0] INT32 {0, 0, 0, 0}\n";
609         conversion = "IMAX TEMP[0], TEMP[0], IMM[0].xxxx\n";
610      }
611   } else {
612      assert(dtype == TGSI_RETURN_TYPE_FLOAT);
613      samp_type = "FLOAT";
614   }
615
616   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, sample_shading, samp_type,
617                                     "COLOR[0]", "", conversion_decl,
618                                     conversion);
619}
620
621
622/**
623 * Make a fragment shader that sets the output depth to a depth value
624 * fetched from a multisample texture.
625 * \param tex_target  one of PIPE_TEXTURE_x
626 */
627void *
628util_make_fs_blit_msaa_depth(struct pipe_context *pipe,
629                             enum tgsi_texture_type tgsi_tex,
630                             bool sample_shading)
631{
632   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, sample_shading, "FLOAT",
633                                     "POSITION", ".z", "",
634                                     "MOV TEMP[0].z, TEMP[0].xxxx\n");
635}
636
637
638/**
639 * Make a fragment shader that sets the output stencil to a stencil value
640 * fetched from a multisample texture.
641 * \param tex_target  one of PIPE_TEXTURE_x
642 */
643void *
644util_make_fs_blit_msaa_stencil(struct pipe_context *pipe,
645                               enum tgsi_texture_type tgsi_tex,
646                               bool sample_shading)
647{
648   return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, sample_shading, "UINT",
649                                     "STENCIL", ".y", "",
650                                     "MOV TEMP[0].y, TEMP[0].xxxx\n");
651}
652
653
654/**
655 * Make a fragment shader that sets the output depth and stencil to depth
656 * and stencil values fetched from two multisample textures / samplers.
657 * The sizes of both textures should match (it should be one depth-stencil
658 * texture).
659 * \param tex_target  one of PIPE_TEXTURE_x
660 */
661void *
662util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe,
663                                    enum tgsi_texture_type tgsi_tex,
664                                    bool sample_shading)
665{
666   static const char shader_templ[] =
667         "FRAG\n"
668         "DCL IN[0], GENERIC[0], LINEAR\n"
669         "DCL SAMP[0..1]\n"
670         "DCL SVIEW[0], %s, FLOAT\n"
671         "DCL SVIEW[1], %s, UINT\n"
672         "DCL OUT[0], POSITION\n"
673         "DCL OUT[1], STENCIL\n"
674         "DCL TEMP[0]\n"
675         "%s"
676
677         "F2U TEMP[0], IN[0]\n"
678         "%s"
679         "TXF OUT[0].z, TEMP[0], SAMP[0], %s\n"
680         "TXF OUT[1].y, TEMP[0], SAMP[1], %s\n"
681         "END\n";
682
683   const char *type = tgsi_texture_names[tgsi_tex];
684   char text[sizeof(shader_templ)+400];
685   struct tgsi_token tokens[1000];
686   struct pipe_shader_state state = {0};
687
688   assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA ||
689          tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA);
690
691   sprintf(text, shader_templ, type, type,
692           sample_shading ? "DCL SV[0], SAMPLEID\n" : "",
693           sample_shading ? "MOV TEMP[0].w, SV[0].xxxx\n" : "",
694           type, type);
695
696   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
697      assert(0);
698      return NULL;
699   }
700   pipe_shader_state_from_tgsi(&state, tokens);
701#if 0
702   tgsi_dump(state.tokens, 0);
703#endif
704
705   return pipe->create_fs_state(pipe, &state);
706}
707
708
709void *
710util_make_fs_msaa_resolve(struct pipe_context *pipe,
711                          enum tgsi_texture_type tgsi_tex, unsigned nr_samples,
712                          enum tgsi_return_type stype)
713{
714   struct ureg_program *ureg;
715   struct ureg_src sampler, coord;
716   struct ureg_dst out, tmp_sum, tmp_coord, tmp;
717   unsigned i;
718
719   ureg = ureg_create(PIPE_SHADER_FRAGMENT);
720   if (!ureg)
721      return NULL;
722
723   /* Declarations. */
724   sampler = ureg_DECL_sampler(ureg, 0);
725   ureg_DECL_sampler_view(ureg, 0, tgsi_tex, stype, stype, stype, stype);
726   coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0,
727                              TGSI_INTERPOLATE_LINEAR);
728   out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
729   tmp_sum = ureg_DECL_temporary(ureg);
730   tmp_coord = ureg_DECL_temporary(ureg);
731   tmp = ureg_DECL_temporary(ureg);
732
733   /* Instructions. */
734   ureg_MOV(ureg, tmp_sum, ureg_imm1f(ureg, 0));
735   ureg_F2U(ureg, tmp_coord, coord);
736
737   for (i = 0; i < nr_samples; i++) {
738      /* Read one sample. */
739      ureg_MOV(ureg, ureg_writemask(tmp_coord, TGSI_WRITEMASK_W),
740               ureg_imm1u(ureg, i));
741      ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord), sampler);
742
743      if (stype == TGSI_RETURN_TYPE_UINT)
744         ureg_U2F(ureg, tmp, ureg_src(tmp));
745      else if (stype == TGSI_RETURN_TYPE_SINT)
746         ureg_I2F(ureg, tmp, ureg_src(tmp));
747
748      /* Add it to the sum.*/
749      ureg_ADD(ureg, tmp_sum, ureg_src(tmp_sum), ureg_src(tmp));
750   }
751
752   /* Calculate the average and return. */
753   ureg_MUL(ureg, tmp_sum, ureg_src(tmp_sum),
754            ureg_imm1f(ureg, 1.0 / nr_samples));
755
756   if (stype == TGSI_RETURN_TYPE_UINT)
757      ureg_F2U(ureg, out, ureg_src(tmp_sum));
758   else if (stype == TGSI_RETURN_TYPE_SINT)
759      ureg_F2I(ureg, out, ureg_src(tmp_sum));
760   else
761      ureg_MOV(ureg, out, ureg_src(tmp_sum));
762
763   ureg_END(ureg);
764
765   return ureg_create_shader_and_destroy(ureg, pipe);
766}
767
768
769void *
770util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
771                                   enum tgsi_texture_type tgsi_tex,
772                                   unsigned nr_samples,
773                                   enum tgsi_return_type stype)
774{
775   struct ureg_program *ureg;
776   struct ureg_src sampler, coord;
777   struct ureg_dst out, tmp, top, bottom;
778   struct ureg_dst tmp_coord[4], tmp_sum[4];
779   unsigned i, c;
780
781   ureg = ureg_create(PIPE_SHADER_FRAGMENT);
782   if (!ureg)
783      return NULL;
784
785   /* Declarations. */
786   sampler = ureg_DECL_sampler(ureg, 0);
787   ureg_DECL_sampler_view(ureg, 0, tgsi_tex, stype, stype, stype, stype);
788   coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0,
789                              TGSI_INTERPOLATE_LINEAR);
790   out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
791   for (c = 0; c < 4; c++)
792      tmp_sum[c] = ureg_DECL_temporary(ureg);
793   for (c = 0; c < 4; c++)
794      tmp_coord[c] = ureg_DECL_temporary(ureg);
795   tmp = ureg_DECL_temporary(ureg);
796   top = ureg_DECL_temporary(ureg);
797   bottom = ureg_DECL_temporary(ureg);
798
799   /* Instructions. */
800   for (c = 0; c < 4; c++)
801      ureg_MOV(ureg, tmp_sum[c], ureg_imm1f(ureg, 0));
802
803   /* Get 4 texture coordinates for the bilinear filter. */
804   ureg_F2U(ureg, tmp_coord[0], coord); /* top-left */
805   ureg_UADD(ureg, tmp_coord[1], ureg_src(tmp_coord[0]),
806             ureg_imm4u(ureg, 1, 0, 0, 0)); /* top-right */
807   ureg_UADD(ureg, tmp_coord[2], ureg_src(tmp_coord[0]),
808             ureg_imm4u(ureg, 0, 1, 0, 0)); /* bottom-left */
809   ureg_UADD(ureg, tmp_coord[3], ureg_src(tmp_coord[0]),
810             ureg_imm4u(ureg, 1, 1, 0, 0)); /* bottom-right */
811
812   for (i = 0; i < nr_samples; i++) {
813      for (c = 0; c < 4; c++) {
814         /* Read one sample. */
815         ureg_MOV(ureg, ureg_writemask(tmp_coord[c], TGSI_WRITEMASK_W),
816                  ureg_imm1u(ureg, i));
817         ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord[c]), sampler);
818
819         if (stype == TGSI_RETURN_TYPE_UINT)
820            ureg_U2F(ureg, tmp, ureg_src(tmp));
821         else if (stype == TGSI_RETURN_TYPE_SINT)
822            ureg_I2F(ureg, tmp, ureg_src(tmp));
823
824         /* Add it to the sum.*/
825         ureg_ADD(ureg, tmp_sum[c], ureg_src(tmp_sum[c]), ureg_src(tmp));
826      }
827   }
828
829   /* Calculate the average. */
830   for (c = 0; c < 4; c++)
831      ureg_MUL(ureg, tmp_sum[c], ureg_src(tmp_sum[c]),
832               ureg_imm1f(ureg, 1.0 / nr_samples));
833
834   /* Take the 4 average values and apply a standard bilinear filter. */
835   ureg_FRC(ureg, tmp, coord);
836
837   ureg_LRP(ureg, top,
838            ureg_scalar(ureg_src(tmp), 0),
839            ureg_src(tmp_sum[1]),
840            ureg_src(tmp_sum[0]));
841
842   ureg_LRP(ureg, bottom,
843            ureg_scalar(ureg_src(tmp), 0),
844            ureg_src(tmp_sum[3]),
845            ureg_src(tmp_sum[2]));
846
847   ureg_LRP(ureg, tmp,
848            ureg_scalar(ureg_src(tmp), 1),
849            ureg_src(bottom),
850            ureg_src(top));
851
852   /* Convert to the texture format and return. */
853   if (stype == TGSI_RETURN_TYPE_UINT)
854      ureg_F2U(ureg, out, ureg_src(tmp));
855   else if (stype == TGSI_RETURN_TYPE_SINT)
856      ureg_F2I(ureg, out, ureg_src(tmp));
857   else
858      ureg_MOV(ureg, out, ureg_src(tmp));
859
860   ureg_END(ureg);
861
862   return ureg_create_shader_and_destroy(ureg, pipe);
863}
864
865void *
866util_make_geometry_passthrough_shader(struct pipe_context *pipe,
867                                      uint num_attribs,
868                                      const ubyte *semantic_names,
869                                      const ubyte *semantic_indexes)
870{
871   static const unsigned zero[4] = {0, 0, 0, 0};
872
873   struct ureg_program *ureg;
874   struct ureg_dst dst[PIPE_MAX_SHADER_OUTPUTS];
875   struct ureg_src src[PIPE_MAX_SHADER_INPUTS];
876   struct ureg_src imm;
877
878   unsigned i;
879
880   ureg = ureg_create(PIPE_SHADER_GEOMETRY);
881   if (!ureg)
882      return NULL;
883
884   ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, PIPE_PRIM_POINTS);
885   ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, PIPE_PRIM_POINTS);
886   ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, 1);
887   ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS, 1);
888   imm = ureg_DECL_immediate_uint(ureg, zero, 4);
889
890   /**
891    * Loop over all the attribs and declare the corresponding
892    * declarations in the geometry shader
893    */
894   for (i = 0; i < num_attribs; i++) {
895      src[i] = ureg_DECL_input(ureg, semantic_names[i],
896                               semantic_indexes[i], 0, 1);
897      src[i] = ureg_src_dimension(src[i], 0);
898      dst[i] = ureg_DECL_output(ureg, semantic_names[i], semantic_indexes[i]);
899   }
900
901   /* MOV dst[i] src[i] */
902   for (i = 0; i < num_attribs; i++) {
903      ureg_MOV(ureg, dst[i], src[i]);
904   }
905
906   /* EMIT IMM[0] */
907   ureg_insn(ureg, TGSI_OPCODE_EMIT, NULL, 0, &imm, 1, 0);
908
909   /* END */
910   ureg_END(ureg);
911
912   return ureg_create_shader_and_destroy(ureg, pipe);
913}
914
915
916/**
917 * Blit from color to ZS or from ZS to color in a manner that is equivalent
918 * to memcpy.
919 *
920 * Color is either R32_UINT (for Z24S8 / S8Z24) or R32G32_UINT (Z32_S8X24).
921 *
922 * Depth and stencil samplers are used to load depth and stencil,
923 * and they are packed and the result is written to a color output.
924 *   OR
925 * A color sampler is used to load a color value, which is unpacked and
926 * written to depth and stencil shader outputs.
927 */
928void *
929util_make_fs_pack_color_zs(struct pipe_context *pipe,
930                           enum tgsi_texture_type tex_target,
931                           enum pipe_format zs_format,
932                           bool dst_is_color)
933{
934   struct ureg_program *ureg;
935   struct ureg_src depth_sampler, stencil_sampler, color_sampler, coord;
936   struct ureg_dst out, depth, depth_x, stencil, out_depth, out_stencil, color;
937
938   assert(zs_format == PIPE_FORMAT_Z24_UNORM_S8_UINT || /* color is R32_UINT */
939          zs_format == PIPE_FORMAT_S8_UINT_Z24_UNORM || /* color is R32_UINT */
940          zs_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT || /* color is R32G32_UINT */
941          zs_format == PIPE_FORMAT_Z24X8_UNORM || /* color is R32_UINT */
942          zs_format == PIPE_FORMAT_X8Z24_UNORM); /* color is R32_UINT */
943
944   bool has_stencil = zs_format != PIPE_FORMAT_Z24X8_UNORM &&
945                      zs_format != PIPE_FORMAT_X8Z24_UNORM;
946   bool is_z24 = zs_format != PIPE_FORMAT_Z32_FLOAT_S8X24_UINT;
947   bool z24_is_high = zs_format == PIPE_FORMAT_S8_UINT_Z24_UNORM ||
948                      zs_format == PIPE_FORMAT_X8Z24_UNORM;
949
950   ureg = ureg_create(PIPE_SHADER_FRAGMENT);
951   if (!ureg)
952      return NULL;
953
954   coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0,
955                              TGSI_INTERPOLATE_LINEAR);
956
957   if (dst_is_color) {
958      /* Load depth. */
959      depth_sampler = ureg_DECL_sampler(ureg, 0);
960      ureg_DECL_sampler_view(ureg, 0, tex_target,
961                             TGSI_RETURN_TYPE_FLOAT,
962                             TGSI_RETURN_TYPE_FLOAT,
963                             TGSI_RETURN_TYPE_FLOAT,
964                             TGSI_RETURN_TYPE_FLOAT);
965
966      depth = ureg_DECL_temporary(ureg);
967      depth_x = ureg_writemask(depth, TGSI_WRITEMASK_X);
968      ureg_load_tex(ureg, depth_x, coord, depth_sampler, tex_target, true, true);
969
970      /* Pack to Z24. */
971      if (is_z24) {
972         double imm = 0xffffff;
973         struct ureg_src imm_f64 = ureg_DECL_immediate_f64(ureg, &imm, 2);
974         struct ureg_dst tmp_xy = ureg_writemask(ureg_DECL_temporary(ureg),
975                                                 TGSI_WRITEMASK_XY);
976
977         ureg_F2D(ureg, tmp_xy, ureg_src(depth));
978         ureg_DMUL(ureg, tmp_xy, ureg_src(tmp_xy), imm_f64);
979         ureg_D2U(ureg, depth_x, ureg_src(tmp_xy));
980
981         if (z24_is_high)
982            ureg_SHL(ureg, depth_x, ureg_src(depth), ureg_imm1u(ureg, 8));
983         else
984            ureg_AND(ureg, depth_x, ureg_src(depth), ureg_imm1u(ureg, 0xffffff));
985      }
986
987      if (has_stencil) {
988         /* Load stencil. */
989         stencil_sampler = ureg_DECL_sampler(ureg, 1);
990         ureg_DECL_sampler_view(ureg, 0, tex_target,
991                                TGSI_RETURN_TYPE_UINT,
992                                TGSI_RETURN_TYPE_UINT,
993                                TGSI_RETURN_TYPE_UINT,
994                                TGSI_RETURN_TYPE_UINT);
995
996         stencil = ureg_writemask(ureg_DECL_temporary(ureg), TGSI_WRITEMASK_X);
997         ureg_load_tex(ureg, stencil, coord, stencil_sampler, tex_target,
998                       true, true);
999
1000         /* Pack stencil into depth. */
1001         if (is_z24) {
1002            if (!z24_is_high)
1003               ureg_SHL(ureg, stencil, ureg_src(stencil), ureg_imm1u(ureg, 24));
1004
1005            ureg_OR(ureg, depth_x, ureg_src(depth), ureg_src(stencil));
1006         }
1007      }
1008
1009      out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
1010
1011      if (is_z24) {
1012         ureg_MOV(ureg, ureg_writemask(out, TGSI_WRITEMASK_X), ureg_src(depth));
1013      } else {
1014         /* Z32_S8X24 */
1015         ureg_MOV(ureg, ureg_writemask(depth, TGSI_WRITEMASK_Y),
1016                  ureg_scalar(ureg_src(stencil), TGSI_SWIZZLE_X));
1017         ureg_MOV(ureg, ureg_writemask(out, TGSI_WRITEMASK_XY), ureg_src(depth));
1018      }
1019   } else {
1020      color_sampler = ureg_DECL_sampler(ureg, 0);
1021      ureg_DECL_sampler_view(ureg, 0, tex_target,
1022                             TGSI_RETURN_TYPE_UINT,
1023                             TGSI_RETURN_TYPE_UINT,
1024                             TGSI_RETURN_TYPE_UINT,
1025                             TGSI_RETURN_TYPE_UINT);
1026
1027      color = ureg_DECL_temporary(ureg);
1028      ureg_load_tex(ureg, color, coord, color_sampler, tex_target, true, true);
1029
1030      depth = ureg_writemask(ureg_DECL_temporary(ureg), TGSI_WRITEMASK_X);
1031      stencil = ureg_writemask(ureg_DECL_temporary(ureg), TGSI_WRITEMASK_X);
1032
1033      if (is_z24) {
1034         double imm = 1.0 / 0xffffff;
1035         struct ureg_src imm_f64 = ureg_DECL_immediate_f64(ureg, &imm, 2);
1036         struct ureg_dst tmp_xy = ureg_writemask(ureg_DECL_temporary(ureg),
1037                                                 TGSI_WRITEMASK_XY);
1038
1039         ureg_UBFE(ureg, depth, ureg_src(color),
1040                   ureg_imm1u(ureg, z24_is_high ? 8 : 0),
1041                   ureg_imm1u(ureg, 24));
1042         ureg_U2D(ureg, tmp_xy, ureg_src(depth));
1043         ureg_DMUL(ureg, tmp_xy, ureg_src(tmp_xy), imm_f64);
1044         ureg_D2F(ureg, depth, ureg_src(tmp_xy));
1045      } else {
1046         /* depth = color.x; (Z32_S8X24) */
1047         ureg_MOV(ureg, depth, ureg_src(color));
1048      }
1049
1050      out_depth = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
1051      ureg_MOV(ureg, ureg_writemask(out_depth, TGSI_WRITEMASK_Z),
1052               ureg_scalar(ureg_src(depth), TGSI_SWIZZLE_X));
1053
1054      if (has_stencil) {
1055         if (is_z24) {
1056            ureg_UBFE(ureg, stencil, ureg_src(color),
1057                      ureg_imm1u(ureg, z24_is_high ? 0 : 24),
1058                      ureg_imm1u(ureg, 8));
1059         } else {
1060            /* stencil = color.y[0:7]; (Z32_S8X24) */
1061            ureg_UBFE(ureg, stencil,
1062                      ureg_scalar(ureg_src(color), TGSI_SWIZZLE_Y),
1063                      ureg_imm1u(ureg, 0),
1064                      ureg_imm1u(ureg, 8));
1065         }
1066
1067         out_stencil = ureg_DECL_output(ureg, TGSI_SEMANTIC_STENCIL, 0);
1068         ureg_MOV(ureg, ureg_writemask(out_stencil, TGSI_WRITEMASK_Y),
1069                  ureg_scalar(ureg_src(stencil), TGSI_SWIZZLE_X));
1070      }
1071   }
1072
1073   ureg_END(ureg);
1074
1075   return ureg_create_shader_and_destroy(ureg, pipe);
1076}
1077
1078
1079/**
1080 * Create passthrough tessellation control shader.
1081 * Passthrough tessellation control shader has output of vertex shader
1082 * as input and input of tessellation eval shader as output.
1083 */
1084void *
1085util_make_tess_ctrl_passthrough_shader(struct pipe_context *pipe,
1086                                       uint num_vs_outputs,
1087                                       uint num_tes_inputs,
1088                                       const ubyte *vs_semantic_names,
1089                                       const ubyte *vs_semantic_indexes,
1090                                       const ubyte *tes_semantic_names,
1091                                       const ubyte *tes_semantic_indexes,
1092                                       const unsigned vertices_per_patch)
1093{
1094   unsigned i, j;
1095   unsigned num_regs;
1096
1097   struct ureg_program *ureg;
1098   struct ureg_dst temp, addr;
1099   struct ureg_src invocationID;
1100   struct ureg_dst dst[PIPE_MAX_SHADER_OUTPUTS];
1101   struct ureg_src src[PIPE_MAX_SHADER_INPUTS];
1102
1103   ureg = ureg_create(PIPE_SHADER_TESS_CTRL);
1104
1105   if (!ureg)
1106      return NULL;
1107
1108   ureg_property(ureg, TGSI_PROPERTY_TCS_VERTICES_OUT, vertices_per_patch);
1109
1110   num_regs = 0;
1111
1112   for (i = 0; i < num_tes_inputs; i++) {
1113      switch (tes_semantic_names[i]) {
1114      case TGSI_SEMANTIC_POSITION:
1115      case TGSI_SEMANTIC_PSIZE:
1116      case TGSI_SEMANTIC_COLOR:
1117      case TGSI_SEMANTIC_BCOLOR:
1118      case TGSI_SEMANTIC_CLIPDIST:
1119      case TGSI_SEMANTIC_CLIPVERTEX:
1120      case TGSI_SEMANTIC_TEXCOORD:
1121      case TGSI_SEMANTIC_FOG:
1122      case TGSI_SEMANTIC_GENERIC:
1123         for (j = 0; j < num_vs_outputs; j++) {
1124            if (tes_semantic_names[i] == vs_semantic_names[j] &&
1125                tes_semantic_indexes[i] == vs_semantic_indexes[j]) {
1126
1127               dst[num_regs] = ureg_DECL_output(ureg,
1128                                               tes_semantic_names[i],
1129                                               tes_semantic_indexes[i]);
1130               src[num_regs] = ureg_DECL_input(ureg, vs_semantic_names[j],
1131                                               vs_semantic_indexes[j],
1132                                               0, 1);
1133
1134               if (tes_semantic_names[i] == TGSI_SEMANTIC_GENERIC ||
1135                   tes_semantic_names[i] == TGSI_SEMANTIC_POSITION) {
1136                  src[num_regs] = ureg_src_dimension(src[num_regs], 0);
1137                  dst[num_regs] = ureg_dst_dimension(dst[num_regs], 0);
1138               }
1139
1140               num_regs++;
1141               break;
1142            }
1143         }
1144         break;
1145      default:
1146         break;
1147      }
1148   }
1149
1150   dst[num_regs] = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSOUTER,
1151                                    num_regs);
1152   src[num_regs] = ureg_DECL_constant(ureg, 0);
1153   num_regs++;
1154   dst[num_regs] = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSINNER,
1155                                    num_regs);
1156   src[num_regs] = ureg_DECL_constant(ureg, 1);
1157   num_regs++;
1158
1159   if (vertices_per_patch > 1) {
1160      invocationID = ureg_DECL_system_value(ureg,
1161                        TGSI_SEMANTIC_INVOCATIONID, 0);
1162      temp = ureg_DECL_local_temporary(ureg);
1163      addr = ureg_DECL_address(ureg);
1164      ureg_UARL(ureg, ureg_writemask(addr, TGSI_WRITEMASK_X),
1165                ureg_scalar(invocationID, TGSI_SWIZZLE_X));
1166   }
1167
1168   for (i = 0; i < num_regs; i++) {
1169      if (dst[i].Dimension && vertices_per_patch > 1) {
1170         struct ureg_src addr_x = ureg_scalar(ureg_src(addr), TGSI_SWIZZLE_X);
1171         ureg_MOV(ureg, temp, ureg_src_dimension_indirect(src[i],
1172                  addr_x, 0));
1173         ureg_MOV(ureg, ureg_dst_dimension_indirect(dst[i],
1174                  addr_x, 0), ureg_src(temp));
1175      }
1176      else
1177         ureg_MOV(ureg, dst[i], src[i]);
1178   }
1179
1180   ureg_END(ureg);
1181
1182   return ureg_create_shader_and_destroy(ureg, pipe);
1183}
1184
1185void *
1186util_make_fs_stencil_blit(struct pipe_context *pipe, bool msaa_src)
1187{
1188   static const char shader_templ[] =
1189      "FRAG\n"
1190      "DCL IN[0], GENERIC[0], LINEAR\n"
1191      "DCL SAMP[0]\n"
1192      "DCL SVIEW[0], %s, UINT\n"
1193      "DCL CONST[0][0]\n"
1194      "DCL TEMP[0]\n"
1195
1196      "F2U TEMP[0], IN[0]\n"
1197      "TXF_LZ TEMP[0].x, TEMP[0], SAMP[0], %s\n"
1198      "AND TEMP[0].x, TEMP[0], CONST[0][0]\n"
1199      "USNE TEMP[0].x, TEMP[0], CONST[0][0]\n"
1200      "U2F TEMP[0].x, TEMP[0]\n"
1201      "KILL_IF -TEMP[0].xxxx\n"
1202      "END\n";
1203
1204   char text[sizeof(shader_templ)+100];
1205   struct tgsi_token tokens[1000];
1206   struct pipe_shader_state state = { 0 };
1207
1208   enum tgsi_texture_type tgsi_tex = msaa_src ? TGSI_TEXTURE_2D_MSAA :
1209                                                TGSI_TEXTURE_2D;
1210
1211   sprintf(text, shader_templ, tgsi_texture_names[tgsi_tex], tgsi_texture_names[tgsi_tex]);
1212
1213   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
1214      assert(0);
1215      return NULL;
1216   }
1217
1218   pipe_shader_state_from_tgsi(&state, tokens);
1219
1220   return pipe->create_fs_state(pipe, &state);
1221}
1222
1223void *
1224util_make_fs_clear_all_cbufs(struct pipe_context *pipe)
1225{
1226   static const char text[] =
1227      "FRAG\n"
1228      "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n"
1229      "DCL OUT[0], COLOR[0]\n"
1230      "DCL CONST[0][0]\n"
1231
1232      "MOV OUT[0], CONST[0][0]\n"
1233      "END\n";
1234
1235   struct tgsi_token tokens[1000];
1236   struct pipe_shader_state state = { 0 };
1237
1238   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
1239      assert(0);
1240      return NULL;
1241   }
1242
1243   pipe_shader_state_from_tgsi(&state, tokens);
1244
1245   return pipe->create_fs_state(pipe, &state);
1246}
1247