st/mesa: remove invalid assertion
[platform/upstream/mesa.git] / src / mesa / state_tracker / st_program.c
1 /**************************************************************************
2  * 
3  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4  * All Rights Reserved.
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  * 
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  * 
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  * 
26  **************************************************************************/
27  /*
28   * Authors:
29   *   Keith Whitwell <keith@tungstengraphics.com>
30   *   Brian Paul
31   */
32
33
34 #include "main/imports.h"
35 #include "main/mtypes.h"
36 #include "shader/prog_print.h"
37 #include "shader/programopt.h"
38
39 #include "pipe/p_context.h"
40 #include "pipe/p_defines.h"
41 #include "pipe/p_shader_tokens.h"
42 #include "draw/draw_context.h"
43 #include "tgsi/tgsi_dump.h"
44
45 #include "st_context.h"
46 #include "st_atom.h"
47 #include "st_program.h"
48 #include "st_mesa_to_tgsi.h"
49 #include "cso_cache/cso_context.h"
50
51
52 #define ST_MAX_SHADER_TOKENS (8 * 1024)
53
54
55 #define TGSI_DEBUG 0
56
57
58 /**
59  * Translate a Mesa vertex shader into a TGSI shader.
60  * \param outputMapping  to map vertex program output registers (VERT_RESULT_x)
61  *       to TGSI output slots
62  * \param tokensOut  destination for TGSI tokens
63  * \return  pointer to cached pipe_shader object.
64  */
65 void
66 st_translate_vertex_program(struct st_context *st,
67                             struct st_vertex_program *stvp,
68                             const GLuint outputMapping[],
69                             const ubyte *outputSemanticName,
70                             const ubyte *outputSemanticIndex)
71 {
72    struct pipe_context *pipe = st->pipe;
73    struct tgsi_token *tokens;
74    GLuint defaultOutputMapping[VERT_RESULT_MAX];
75    struct pipe_shader_state vs;
76    GLuint attr, i;
77    GLuint num_generic = 0;
78    GLuint num_tokens;
79
80    ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
81    ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
82    uint vs_num_inputs = 0;
83
84    ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
85    ubyte vs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
86    uint vs_num_outputs = 0;
87
88    GLbitfield input_flags[MAX_PROGRAM_INPUTS];
89    GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
90
91    tokens =  (struct tgsi_token *)MALLOC(ST_MAX_SHADER_TOKENS * sizeof *tokens);
92    if(!tokens) {
93       /* FIXME: propagate error to the caller */
94       assert(0);
95       return;
96    }
97
98    memset(&vs, 0, sizeof(vs));
99    memset(input_flags, 0, sizeof(input_flags));
100    memset(output_flags, 0, sizeof(output_flags));
101
102    if (stvp->Base.IsPositionInvariant)
103       _mesa_insert_mvp_code(st->ctx, &stvp->Base);
104
105    /*
106     * Determine number of inputs, the mappings between VERT_ATTRIB_x
107     * and TGSI generic input indexes, plus input attrib semantic info.
108     */
109    for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
110       if (stvp->Base.Base.InputsRead & (1 << attr)) {
111          const GLuint slot = vs_num_inputs;
112
113          vs_num_inputs++;
114
115          stvp->input_to_index[attr] = slot;
116          stvp->index_to_input[slot] = attr;
117
118          switch (attr) {
119          case VERT_ATTRIB_POS:
120             vs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
121             vs_input_semantic_index[slot] = 0;
122             break;
123          case VERT_ATTRIB_WEIGHT:
124             /* fall-through */
125          case VERT_ATTRIB_NORMAL:
126             /* just label as a generic */
127             vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
128             vs_input_semantic_index[slot] = 0;
129             break;
130          case VERT_ATTRIB_COLOR0:
131             vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
132             vs_input_semantic_index[slot] = 0;
133             break;
134          case VERT_ATTRIB_COLOR1:
135             vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
136             vs_input_semantic_index[slot] = 1;
137             break;
138          case VERT_ATTRIB_FOG:
139             vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
140             vs_input_semantic_index[slot] = 0;
141             break;
142          case VERT_ATTRIB_POINT_SIZE:
143             vs_input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
144             vs_input_semantic_index[slot] = 0;
145             break;
146          case VERT_ATTRIB_TEX0:
147          case VERT_ATTRIB_TEX1:
148          case VERT_ATTRIB_TEX2:
149          case VERT_ATTRIB_TEX3:
150          case VERT_ATTRIB_TEX4:
151          case VERT_ATTRIB_TEX5:
152          case VERT_ATTRIB_TEX6:
153          case VERT_ATTRIB_TEX7:
154             vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
155             vs_input_semantic_index[slot] = num_generic++;
156             break;
157          case VERT_ATTRIB_GENERIC0:
158          case VERT_ATTRIB_GENERIC1:
159          case VERT_ATTRIB_GENERIC2:
160          case VERT_ATTRIB_GENERIC3:
161          case VERT_ATTRIB_GENERIC4:
162          case VERT_ATTRIB_GENERIC5:
163          case VERT_ATTRIB_GENERIC6:
164          case VERT_ATTRIB_GENERIC7:
165          case VERT_ATTRIB_GENERIC8:
166          case VERT_ATTRIB_GENERIC9:
167          case VERT_ATTRIB_GENERIC10:
168          case VERT_ATTRIB_GENERIC11:
169          case VERT_ATTRIB_GENERIC12:
170          case VERT_ATTRIB_GENERIC13:
171          case VERT_ATTRIB_GENERIC14:
172          case VERT_ATTRIB_GENERIC15:
173             assert(attr < VERT_ATTRIB_MAX);
174             vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
175             vs_input_semantic_index[slot] = num_generic++;
176             break;
177          default:
178             assert(0);
179          }
180
181          input_flags[slot] = stvp->Base.Base.InputFlags[attr];
182       }
183    }
184
185 #if 0
186    if (outputMapping && outputSemanticName) {
187       printf("VERT_RESULT  written  out_slot  semantic_name  semantic_index\n");
188       for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
189          printf("    %-2d          %c       %3d          %2d              %2d\n",
190                 attr, 
191                 ((stvp->Base.Base.OutputsWritten & (1 << attr)) ? 'Y' : ' '),
192                 outputMapping[attr],
193                 outputSemanticName[attr],
194                 outputSemanticIndex[attr]);
195       }
196    }
197 #endif
198
199    /* initialize output semantics to defaults */
200    for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
201       vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
202       vs_output_semantic_index[i] = 0;
203       output_flags[i] = 0x0;
204    }
205
206    num_generic = 0;
207    /*
208     * Determine number of outputs, the (default) output register
209     * mapping and the semantic information for each output.
210     */
211    for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
212       if (stvp->Base.Base.OutputsWritten & (1 << attr)) {
213          GLuint slot;
214
215          /* XXX
216           * Pass in the fragment program's input's semantic info.
217           * Use the generic semantic indexes from there, instead of
218           * guessing below.
219           */
220
221          if (outputMapping) {
222             slot = outputMapping[attr];
223             assert(slot != ~0);
224          }
225          else {
226             slot = vs_num_outputs;
227             vs_num_outputs++;
228             defaultOutputMapping[attr] = slot;
229          }
230
231          switch (attr) {
232          case VERT_RESULT_HPOS:
233             assert(slot == 0);
234             vs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
235             vs_output_semantic_index[slot] = 0;
236             break;
237          case VERT_RESULT_COL0:
238             vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
239             vs_output_semantic_index[slot] = 0;
240             break;
241          case VERT_RESULT_COL1:
242             vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
243             vs_output_semantic_index[slot] = 1;
244             break;
245          case VERT_RESULT_BFC0:
246             vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
247             vs_output_semantic_index[slot] = 0;
248             break;
249          case VERT_RESULT_BFC1:
250             vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
251             vs_output_semantic_index[slot] = 1;
252             break;
253          case VERT_RESULT_FOGC:
254             vs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
255             vs_output_semantic_index[slot] = 0;
256             break;
257          case VERT_RESULT_PSIZ:
258             vs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
259             vs_output_semantic_index[slot] = 0;
260             break;
261          case VERT_RESULT_EDGE:
262             assert(0);
263             break;
264          case VERT_RESULT_TEX0:
265          case VERT_RESULT_TEX1:
266          case VERT_RESULT_TEX2:
267          case VERT_RESULT_TEX3:
268          case VERT_RESULT_TEX4:
269          case VERT_RESULT_TEX5:
270          case VERT_RESULT_TEX6:
271          case VERT_RESULT_TEX7:
272             /* fall-through */
273          case VERT_RESULT_VAR0:
274             /* fall-through */
275          default:
276             if (outputSemanticName) {
277                /* use provided semantic into */
278                assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT);
279                vs_output_semantic_name[slot] = outputSemanticName[attr];
280                vs_output_semantic_index[slot] = outputSemanticIndex[attr];
281             }
282             else {
283                /* use default semantic info */
284                vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
285                vs_output_semantic_index[slot] = num_generic++;
286             }
287          }
288
289          output_flags[slot] = stvp->Base.Base.OutputFlags[attr];
290       }
291    }
292
293    if (outputMapping) {
294       /* find max output slot referenced to compute vs_num_outputs */
295       GLuint maxSlot = 0;
296       for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
297          if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
298             maxSlot = outputMapping[attr];
299       }
300       vs_num_outputs = maxSlot + 1;
301    }
302    else {
303       outputMapping = defaultOutputMapping;
304    }
305
306    /* free old shader state, if any */
307    if (stvp->state.tokens) {
308       _mesa_free((void *) stvp->state.tokens);
309       stvp->state.tokens = NULL;
310    }
311    if (stvp->driver_shader) {
312       cso_delete_vertex_shader(st->cso_context, stvp->driver_shader);
313       stvp->driver_shader = NULL;
314    }
315
316    /* XXX: fix static allocation of tokens:
317     */
318    num_tokens = st_translate_mesa_program(st->ctx,
319                                           TGSI_PROCESSOR_VERTEX,
320                                           &stvp->Base.Base,
321                                           /* inputs */
322                                           vs_num_inputs,
323                                           stvp->input_to_index,
324                                           vs_input_semantic_name,
325                                           vs_input_semantic_index,
326                                           NULL,
327                                           input_flags,
328                                           /* outputs */
329                                           vs_num_outputs,
330                                           outputMapping,
331                                           vs_output_semantic_name,
332                                           vs_output_semantic_index,
333                                           output_flags,
334                                           /* tokenized result */
335                                           tokens, ST_MAX_SHADER_TOKENS);
336
337    assert(num_tokens < ST_MAX_SHADER_TOKENS);
338
339    vs.tokens = (struct tgsi_token *)
340       _mesa_realloc(tokens,
341                     ST_MAX_SHADER_TOKENS * sizeof *tokens,
342                     num_tokens * sizeof *tokens);
343
344    stvp->num_inputs = vs_num_inputs;
345    stvp->state = vs; /* struct copy */
346    stvp->driver_shader = pipe->create_vs_state(pipe, &vs);
347
348    if (0)
349       _mesa_print_program(&stvp->Base.Base);
350
351    if (TGSI_DEBUG)
352       tgsi_dump( vs.tokens, 0 );
353 }
354
355
356
357 /**
358  * Translate a Mesa fragment shader into a TGSI shader.
359  * \param inputMapping  to map fragment program input registers to TGSI
360  *                      input slots
361  * \param tokensOut  destination for TGSI tokens
362  * \return  pointer to cached pipe_shader object.
363  */
364 void
365 st_translate_fragment_program(struct st_context *st,
366                               struct st_fragment_program *stfp,
367                               const GLuint inputMapping[])
368 {
369    struct pipe_context *pipe = st->pipe;
370    struct tgsi_token *tokens;
371    GLuint outputMapping[FRAG_RESULT_MAX];
372    GLuint defaultInputMapping[FRAG_ATTRIB_MAX];
373    struct pipe_shader_state fs;
374    GLuint interpMode[16];  /* XXX size? */
375    GLuint attr;
376    const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
377    GLuint vslot = 0;
378    GLuint num_generic = 0;
379    GLuint num_tokens;
380
381    uint fs_num_inputs = 0;
382
383    ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
384    ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
385    uint fs_num_outputs = 0;
386
387    GLbitfield input_flags[MAX_PROGRAM_INPUTS];
388    GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
389
390    tokens =  (struct tgsi_token *)MALLOC(ST_MAX_SHADER_TOKENS * sizeof *tokens);
391    if(!tokens) {
392       /* FIXME: propagate error to the caller */
393       assert(0);
394       return;
395    }
396
397    memset(&fs, 0, sizeof(fs));
398    memset(input_flags, 0, sizeof(input_flags));
399    memset(output_flags, 0, sizeof(output_flags));
400
401    /* which vertex output goes to the first fragment input: */
402    if (inputsRead & FRAG_BIT_WPOS)
403       vslot = 0;
404    else
405       vslot = 1;
406
407    /*
408     * Convert Mesa program inputs to TGSI input register semantics.
409     */
410    for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) {
411       if (inputsRead & (1 << attr)) {
412          const GLuint slot = fs_num_inputs;
413
414          defaultInputMapping[attr] = slot;
415
416          stfp->input_map[slot] = vslot++;
417
418          fs_num_inputs++;
419
420          switch (attr) {
421          case FRAG_ATTRIB_WPOS:
422             stfp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
423             stfp->input_semantic_index[slot] = 0;
424             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
425             break;
426          case FRAG_ATTRIB_COL0:
427             stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
428             stfp->input_semantic_index[slot] = 0;
429             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
430             break;
431          case FRAG_ATTRIB_COL1:
432             stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
433             stfp->input_semantic_index[slot] = 1;
434             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
435             break;
436          case FRAG_ATTRIB_FOGC:
437             if (stfp->Base.UsesPointCoord) {
438                stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
439                stfp->input_semantic_index[slot] = num_generic++;
440             } else {
441                stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
442                stfp->input_semantic_index[slot] = 0;
443             }
444             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
445             break;
446          case FRAG_ATTRIB_TEX0:
447          case FRAG_ATTRIB_TEX1:
448          case FRAG_ATTRIB_TEX2:
449          case FRAG_ATTRIB_TEX3:
450          case FRAG_ATTRIB_TEX4:
451          case FRAG_ATTRIB_TEX5:
452          case FRAG_ATTRIB_TEX6:
453          case FRAG_ATTRIB_TEX7:
454             stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
455             stfp->input_semantic_index[slot] = num_generic++;
456             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
457             break;
458          case FRAG_ATTRIB_VAR0:
459             /* fall-through */
460          default:
461             stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
462             stfp->input_semantic_index[slot] = num_generic++;
463             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
464          }
465
466          input_flags[slot] = stfp->Base.Base.InputFlags[attr];
467       }
468    }
469
470    /*
471     * Semantics and mapping for outputs
472     */
473    {
474       uint numColors = 0;
475       GLbitfield outputsWritten = stfp->Base.Base.OutputsWritten;
476
477       /* if z is written, emit that first */
478       if (outputsWritten & (1 << FRAG_RESULT_DEPTH)) {
479          fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_POSITION;
480          fs_output_semantic_index[fs_num_outputs] = 0;
481          outputMapping[FRAG_RESULT_DEPTH] = fs_num_outputs;
482          fs_num_outputs++;
483          outputsWritten &= ~(1 << FRAG_RESULT_DEPTH);
484       }
485
486       /* handle remaning outputs (color) */
487       for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
488          if (outputsWritten & (1 << attr)) {
489             switch (attr) {
490             case FRAG_RESULT_DEPTH:
491                /* handled above */
492                assert(0);
493                break;
494             default:
495                assert(attr == FRAG_RESULT_COLOR ||
496                       (FRAG_RESULT_DATA0 <= attr && attr < FRAG_RESULT_MAX));
497                fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR;
498                fs_output_semantic_index[fs_num_outputs] = numColors;
499                outputMapping[attr] = fs_num_outputs;
500                numColors++;
501                break;
502             }
503
504             output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr];
505
506             fs_num_outputs++;
507          }
508       }
509    }
510
511    if (!inputMapping)
512       inputMapping = defaultInputMapping;
513
514    /* XXX: fix static allocation of tokens:
515     */
516    num_tokens = st_translate_mesa_program(st->ctx,
517                                           TGSI_PROCESSOR_FRAGMENT,
518                                           &stfp->Base.Base,
519                                           /* inputs */
520                                           fs_num_inputs,
521                                           inputMapping,
522                                           stfp->input_semantic_name,
523                                           stfp->input_semantic_index,
524                                           interpMode,
525                                           input_flags,
526                                           /* outputs */
527                                           fs_num_outputs,
528                                           outputMapping,
529                                           fs_output_semantic_name,
530                                           fs_output_semantic_index,
531                                           output_flags,
532                                           /* tokenized result */
533                                           tokens, ST_MAX_SHADER_TOKENS);
534
535    assert(num_tokens < ST_MAX_SHADER_TOKENS);
536
537    fs.tokens = (struct tgsi_token *)
538       _mesa_realloc(tokens,
539                     ST_MAX_SHADER_TOKENS * sizeof *tokens,
540                     num_tokens * sizeof *tokens);
541
542    stfp->state = fs; /* struct copy */
543    stfp->driver_shader = pipe->create_fs_state(pipe, &fs);
544
545    if (0)
546       _mesa_print_program(&stfp->Base.Base);
547
548    if (TGSI_DEBUG)
549       tgsi_dump( fs.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
550 }
551
552
553 /**
554  * Debug- print current shader text
555  */
556 void
557 st_print_shaders(GLcontext *ctx)
558 {
559    struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
560    if (shProg) {
561       GLuint i;
562       for (i = 0; i < shProg->NumShaders; i++) {
563          printf("GLSL shader %u of %u:\n", i, shProg->NumShaders);
564          printf("%s\n", shProg->Shaders[i]->Source);
565       }
566    }
567 }