• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
59 void *
util_make_vertex_passthrough_shader(struct pipe_context * pipe,uint num_attribs,const enum tgsi_semantic * semantic_names,const uint * semantic_indexes,bool window_space)60 util_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 
72 void *
util_make_vertex_passthrough_shader_with_so(struct pipe_context * pipe,uint num_attribs,const enum tgsi_semantic * semantic_names,const uint * semantic_indexes,bool window_space,bool layered,const struct pipe_stream_output_info * so)73 util_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 
util_make_layered_clear_vertex_shader(struct pipe_context * pipe)118 void *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  */
util_make_layered_clear_helper_vertex_shader(struct pipe_context * pipe)132 void *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  */
util_make_layered_clear_geometry_shader(struct pipe_context * pipe)162 void *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 
202 static void
ureg_load_tex(struct ureg_program * ureg,struct ureg_dst out,struct ureg_src coord,struct ureg_src sampler,enum tgsi_texture_type tex_target,bool load_level_zero,bool use_txf)203 ureg_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  */
235 void *
util_make_fragment_tex_shader_xrbias(struct pipe_context * pipe,enum tgsi_texture_type tex_target)236 util_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  */
285 void *
util_make_fragment_tex_shader_writemask(struct pipe_context * pipe,enum tgsi_texture_type tex_target,enum tgsi_interpolate_mode interp_mode,unsigned writemask,enum tgsi_return_type stype,enum tgsi_return_type dtype,bool load_level_zero,bool use_txf)286 util_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  */
363 void *
util_make_fragment_tex_shader(struct pipe_context * pipe,enum tgsi_texture_type tex_target,enum tgsi_interpolate_mode interp_mode,enum tgsi_return_type stype,enum tgsi_return_type dtype,bool load_level_zero,bool use_txf)364 util_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  */
385 void *
util_make_fs_blit_zs(struct pipe_context * pipe,unsigned zs_mask,enum tgsi_texture_type tex_target,bool load_level_zero,bool use_txf)386 util_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  */
444 void *
util_make_fragment_passthrough_shader(struct pipe_context * pipe,int input_semantic,int input_interpolate,boolean write_all_cbufs)445 util_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 
481 void *
util_make_empty_fragment_shader(struct pipe_context * pipe)482 util_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  */
496 void *
util_make_fragment_cloneinput_shader(struct pipe_context * pipe,int num_cbufs,int input_semantic,int input_interpolate)497 util_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 
527 static void *
util_make_fs_blit_msaa_gen(struct pipe_context * pipe,enum tgsi_texture_type tgsi_tex,bool sample_shading,const char * samp_type,const char * output_semantic,const char * output_mask,const char * conversion_decl,const char * conversion)528 util_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  */
586 void *
util_make_fs_blit_msaa_color(struct pipe_context * pipe,enum tgsi_texture_type tgsi_tex,enum tgsi_return_type stype,enum tgsi_return_type dtype,bool sample_shading)587 util_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  */
627 void *
util_make_fs_blit_msaa_depth(struct pipe_context * pipe,enum tgsi_texture_type tgsi_tex,bool sample_shading)628 util_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  */
643 void *
util_make_fs_blit_msaa_stencil(struct pipe_context * pipe,enum tgsi_texture_type tgsi_tex,bool sample_shading)644 util_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  */
661 void *
util_make_fs_blit_msaa_depthstencil(struct pipe_context * pipe,enum tgsi_texture_type tgsi_tex,bool sample_shading)662 util_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 
709 void *
util_make_fs_msaa_resolve(struct pipe_context * pipe,enum tgsi_texture_type tgsi_tex,unsigned nr_samples,enum tgsi_return_type stype)710 util_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 
769 void *
util_make_fs_msaa_resolve_bilinear(struct pipe_context * pipe,enum tgsi_texture_type tgsi_tex,unsigned nr_samples,enum tgsi_return_type stype)770 util_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 
865 void *
util_make_geometry_passthrough_shader(struct pipe_context * pipe,uint num_attribs,const ubyte * semantic_names,const ubyte * semantic_indexes)866 util_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  */
928 void *
util_make_fs_pack_color_zs(struct pipe_context * pipe,enum tgsi_texture_type tex_target,enum pipe_format zs_format,bool dst_is_color)929 util_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  */
1084 void *
util_make_tess_ctrl_passthrough_shader(struct pipe_context * pipe,uint num_vs_outputs,uint num_tes_inputs,const ubyte * vs_semantic_names,const ubyte * vs_semantic_indexes,const ubyte * tes_semantic_names,const ubyte * tes_semantic_indexes,const unsigned vertices_per_patch)1085 util_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 
1185 void *
util_make_fs_stencil_blit(struct pipe_context * pipe,bool msaa_src)1186 util_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 
1223 void *
util_make_fs_clear_all_cbufs(struct pipe_context * pipe)1224 util_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