mesa: point size arrays
[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/util/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 TGSI_DEBUG 0
53
54
55 /** XXX we should use the version of this from p_util.h but including
56 * that header causes symbol collisions.
57 */
58 static INLINE void *
59 mem_dup(const void *src, uint size)
60 {
61 void *dup = MALLOC(size);
62 if (dup)
63 memcpy(dup, src, size);
64 return dup;
65 }
66
67
68
69 /**
70 * Translate a Mesa vertex shader into a TGSI shader.
71 * \param outputMapping to map vertex program output registers to TGSI
72 * output slots
73 * \param tokensOut destination for TGSI tokens
74 * \return pointer to cached pipe_shader object.
75 */
76 void
77 st_translate_vertex_program(struct st_context *st,
78 struct st_vertex_program *stvp,
79 const GLuint outputMapping[])
80 {
81 struct pipe_context *pipe = st->pipe;
82 struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
83 GLuint defaultOutputMapping[VERT_RESULT_MAX];
84 struct pipe_shader_state vs;
85 GLuint attr, i;
86 GLuint num_generic = 0;
87 GLuint num_tokens;
88
89 ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
90 ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
91 uint vs_num_inputs = 0;
92
93 ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
94 ubyte vs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
95 uint vs_num_outputs = 0;
96
97 memset(&vs, 0, sizeof(vs));
98
99 if (stvp->Base.IsPositionInvariant)
100 _mesa_insert_mvp_code(st->ctx, &stvp->Base);
101
102 /*
103 * Determine number of inputs, the mappings between VERT_ATTRIB_x
104 * and TGSI generic input indexes, plus input attrib semantic info.
105 */
106 for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
107 if (stvp->Base.Base.InputsRead & (1 << attr)) {
108 const GLuint slot = vs_num_inputs;
109
110 vs_num_inputs++;
111
112 stvp->input_to_index[attr] = slot;
113 stvp->index_to_input[slot] = attr;
114
115 switch (attr) {
116 case VERT_ATTRIB_POS:
117 vs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
118 vs_input_semantic_index[slot] = 0;
119 break;
120 case VERT_ATTRIB_WEIGHT:
121 /* fall-through */
122 case VERT_ATTRIB_NORMAL:
123 /* just label as a generic */
124 vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
125 vs_input_semantic_index[slot] = 0;
126 break;
127 case VERT_ATTRIB_COLOR0:
128 vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
129 vs_input_semantic_index[slot] = 0;
130 break;
131 case VERT_ATTRIB_COLOR1:
132 vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
133 vs_input_semantic_index[slot] = 1;
134 break;
135 case VERT_ATTRIB_FOG:
136 vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
137 vs_input_semantic_index[slot] = 0;
138 break;
139 case VERT_ATTRIB_POINT_SIZE:
140 vs_input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
141 vs_input_semantic_index[slot] = 0;
142 break;
143 case VERT_ATTRIB_TEX0:
144 case VERT_ATTRIB_TEX1:
145 case VERT_ATTRIB_TEX2:
146 case VERT_ATTRIB_TEX3:
147 case VERT_ATTRIB_TEX4:
148 case VERT_ATTRIB_TEX5:
149 case VERT_ATTRIB_TEX6:
150 case VERT_ATTRIB_TEX7:
151 vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
152 vs_input_semantic_index[slot] = num_generic++;
153 break;
154 case VERT_ATTRIB_GENERIC0:
155 case VERT_ATTRIB_GENERIC1:
156 case VERT_ATTRIB_GENERIC2:
157 case VERT_ATTRIB_GENERIC3:
158 case VERT_ATTRIB_GENERIC4:
159 case VERT_ATTRIB_GENERIC5:
160 case VERT_ATTRIB_GENERIC6:
161 case VERT_ATTRIB_GENERIC7:
162 assert(attr < VERT_ATTRIB_MAX);
163 vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
164 vs_input_semantic_index[slot] = num_generic++;
165 break;
166 default:
167 assert(0);
168 }
169 }
170 }
171
172 /* initialize output semantics to defaults */
173 for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
174 vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
175 vs_output_semantic_index[i] = 0;
176 }
177
178 num_generic = 0;
179 /*
180 * Determine number of outputs, the (default) output register
181 * mapping and the semantic information for each output.
182 */
183 for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
184 if (stvp->Base.Base.OutputsWritten & (1 << attr)) {
185 GLuint slot;
186
187 if (outputMapping) {
188 slot = outputMapping[attr];
189 assert(slot != ~0);
190 }
191 else {
192 slot = vs_num_outputs;
193 vs_num_outputs++;
194 defaultOutputMapping[attr] = slot;
195 }
196
197 /*
198 printf("Output %u -> slot %u\n", attr, slot);
199 */
200
201 switch (attr) {
202 case VERT_RESULT_HPOS:
203 assert(slot == 0);
204 vs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
205 vs_output_semantic_index[slot] = 0;
206 break;
207 case VERT_RESULT_COL0:
208 vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
209 vs_output_semantic_index[slot] = 0;
210 break;
211 case VERT_RESULT_COL1:
212 vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
213 vs_output_semantic_index[slot] = 1;
214 break;
215 case VERT_RESULT_BFC0:
216 vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
217 vs_output_semantic_index[slot] = 0;
218 break;
219 case VERT_RESULT_BFC1:
220 vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
221 vs_output_semantic_index[slot] = 1;
222 break;
223 case VERT_RESULT_FOGC:
224 vs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
225 vs_output_semantic_index[slot] = 0;
226 break;
227 case VERT_RESULT_PSIZ:
228 vs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
229 vs_output_semantic_index[slot] = 0;
230 break;
231 case VERT_RESULT_EDGE:
232 assert(0);
233 break;
234 case VERT_RESULT_TEX0:
235 case VERT_RESULT_TEX1:
236 case VERT_RESULT_TEX2:
237 case VERT_RESULT_TEX3:
238 case VERT_RESULT_TEX4:
239 case VERT_RESULT_TEX5:
240 case VERT_RESULT_TEX6:
241 case VERT_RESULT_TEX7:
242 vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
243 vs_output_semantic_index[slot] = num_generic++;
244 break;
245 case VERT_RESULT_VAR0:
246 /* fall-through */
247 default:
248 assert(attr - VERT_RESULT_VAR0 < MAX_VARYING);
249 vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
250 vs_output_semantic_index[slot] = num_generic++;
251 }
252 }
253 }
254
255 assert(vs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION);
256
257
258 if (outputMapping) {
259 /* find max output slot referenced to compute vs_num_outputs */
260 GLuint maxSlot = 0;
261 for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
262 if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
263 maxSlot = outputMapping[attr];
264 }
265 vs_num_outputs = maxSlot + 1;
266 }
267 else {
268 outputMapping = defaultOutputMapping;
269 }
270
271 /* free old shader state, if any */
272 if (stvp->state.tokens) {
273 FREE((void *) stvp->state.tokens);
274 stvp->state.tokens = NULL;
275 }
276 if (stvp->driver_shader) {
277 cso_delete_vertex_shader(st->cso_context, stvp->driver_shader);
278 stvp->driver_shader = NULL;
279 }
280
281 /* XXX: fix static allocation of tokens:
282 */
283 num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_VERTEX,
284 &stvp->Base.Base,
285 /* inputs */
286 vs_num_inputs,
287 stvp->input_to_index,
288 vs_input_semantic_name,
289 vs_input_semantic_index,
290 NULL,
291 /* outputs */
292 vs_num_outputs,
293 outputMapping,
294 vs_output_semantic_name,
295 vs_output_semantic_index,
296 /* tokenized result */
297 tokens, ST_MAX_SHADER_TOKENS);
298
299 vs.tokens = (struct tgsi_token *)
300 mem_dup(tokens, num_tokens * sizeof(tokens[0]));
301
302 stvp->num_inputs = vs_num_inputs;
303 stvp->state = vs; /* struct copy */
304 stvp->driver_shader = pipe->create_vs_state(pipe, &vs);
305
306 if (0)
307 _mesa_print_program(&stvp->Base.Base);
308
309 if (TGSI_DEBUG)
310 tgsi_dump( vs.tokens, 0 );
311 }
312
313
314
315 /**
316 * Translate a Mesa fragment shader into a TGSI shader.
317 * \param inputMapping to map fragment program input registers to TGSI
318 * input slots
319 * \param tokensOut destination for TGSI tokens
320 * \return pointer to cached pipe_shader object.
321 */
322 void
323 st_translate_fragment_program(struct st_context *st,
324 struct st_fragment_program *stfp,
325 const GLuint inputMapping[])
326 {
327 struct pipe_context *pipe = st->pipe;
328 struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
329 GLuint outputMapping[FRAG_RESULT_MAX];
330 GLuint defaultInputMapping[FRAG_ATTRIB_MAX];
331 struct pipe_shader_state fs;
332 GLuint interpMode[16]; /* XXX size? */
333 GLuint attr;
334 const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
335 GLuint vslot = 0;
336 GLuint num_generic = 0;
337 GLuint num_tokens;
338
339 ubyte fs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
340 ubyte fs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
341 uint fs_num_inputs = 0;
342
343 ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
344 ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
345 uint fs_num_outputs = 0;
346
347 memset(&fs, 0, sizeof(fs));
348
349 /* which vertex output goes to the first fragment input: */
350 if (inputsRead & FRAG_BIT_WPOS)
351 vslot = 0;
352 else
353 vslot = 1;
354
355 /*
356 * Convert Mesa program inputs to TGSI input register semantics.
357 */
358 for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) {
359 if (inputsRead & (1 << attr)) {
360 const GLuint slot = fs_num_inputs;
361
362 defaultInputMapping[attr] = slot;
363
364 stfp->input_map[slot] = vslot++;
365
366 fs_num_inputs++;
367
368 switch (attr) {
369 case FRAG_ATTRIB_WPOS:
370 fs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
371 fs_input_semantic_index[slot] = 0;
372 interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
373 break;
374 case FRAG_ATTRIB_COL0:
375 fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
376 fs_input_semantic_index[slot] = 0;
377 interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
378 break;
379 case FRAG_ATTRIB_COL1:
380 fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
381 fs_input_semantic_index[slot] = 1;
382 interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
383 break;
384 case FRAG_ATTRIB_FOGC:
385 fs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
386 fs_input_semantic_index[slot] = 0;
387 interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
388 break;
389 case FRAG_ATTRIB_TEX0:
390 case FRAG_ATTRIB_TEX1:
391 case FRAG_ATTRIB_TEX2:
392 case FRAG_ATTRIB_TEX3:
393 case FRAG_ATTRIB_TEX4:
394 case FRAG_ATTRIB_TEX5:
395 case FRAG_ATTRIB_TEX6:
396 case FRAG_ATTRIB_TEX7:
397 fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
398 fs_input_semantic_index[slot] = num_generic++;
399 interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
400 break;
401 case FRAG_ATTRIB_VAR0:
402 /* fall-through */
403 default:
404 fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
405 fs_input_semantic_index[slot] = num_generic++;
406 interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
407 }
408 }
409 }
410
411 /*
412 * Semantics and mapping for outputs
413 */
414 {
415 uint numColors = 0;
416 GLbitfield outputsWritten = stfp->Base.Base.OutputsWritten;
417
418 /* if z is written, emit that first */
419 if (outputsWritten & (1 << FRAG_RESULT_DEPR)) {
420 fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_POSITION;
421 fs_output_semantic_index[fs_num_outputs] = 0;
422 outputMapping[FRAG_RESULT_DEPR] = fs_num_outputs;
423 fs_num_outputs++;
424 outputsWritten &= ~(1 << FRAG_RESULT_DEPR);
425 }
426
427 /* handle remaning outputs (color) */
428 for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
429 if (outputsWritten & (1 << attr)) {
430 switch (attr) {
431 case FRAG_RESULT_DEPR:
432 /* handled above */
433 assert(0);
434 break;
435 case FRAG_RESULT_COLR:
436 fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR;
437 fs_output_semantic_index[fs_num_outputs] = numColors;
438 outputMapping[attr] = fs_num_outputs;
439 numColors++;
440 break;
441 default:
442 assert(0);
443 }
444 fs_num_outputs++;
445 }
446 }
447 }
448
449 if (!inputMapping)
450 inputMapping = defaultInputMapping;
451
452 /* XXX: fix static allocation of tokens:
453 */
454 num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_FRAGMENT,
455 &stfp->Base.Base,
456 /* inputs */
457 fs_num_inputs,
458 inputMapping,
459 fs_input_semantic_name,
460 fs_input_semantic_index,
461 interpMode,
462 /* outputs */
463 fs_num_outputs,
464 outputMapping,
465 fs_output_semantic_name,
466 fs_output_semantic_index,
467 /* tokenized result */
468 tokens, ST_MAX_SHADER_TOKENS);
469
470 fs.tokens = (struct tgsi_token *)
471 mem_dup(tokens, num_tokens * sizeof(tokens[0]));
472
473 stfp->state = fs; /* struct copy */
474 stfp->driver_shader = pipe->create_fs_state(pipe, &fs);
475
476 if (0)
477 _mesa_print_program(&stfp->Base.Base);
478
479 if (TGSI_DEBUG)
480 tgsi_dump( fs.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
481 }
482