mesa: Remove debugging code from _mesa_reference_*.
[mesa.git] / src / mesa / program / program.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2007 Brian Paul 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 "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file program.c
27 * Vertex and fragment program support functions.
28 * \author Brian Paul
29 */
30
31
32 #include "main/glheader.h"
33 #include "main/context.h"
34 #include "main/hash.h"
35 #include "main/macros.h"
36 #include "program.h"
37 #include "prog_cache.h"
38 #include "prog_parameter.h"
39 #include "prog_instruction.h"
40 #include "util/ralloc.h"
41
42
43 /**
44 * A pointer to this dummy program is put into the hash table when
45 * glGenPrograms is called.
46 */
47 struct gl_program _mesa_DummyProgram;
48
49
50 /**
51 * Init context's vertex/fragment program state
52 */
53 void
54 _mesa_init_program(struct gl_context *ctx)
55 {
56 /*
57 * If this assertion fails, we need to increase the field
58 * size for register indexes (see INST_INDEX_BITS).
59 */
60 assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents / 4
61 <= (1 << INST_INDEX_BITS));
62 assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents / 4
63 <= (1 << INST_INDEX_BITS));
64
65 assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps <= (1 << INST_INDEX_BITS));
66 assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= (1 << INST_INDEX_BITS));
67 assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTemps <= (1 << INST_INDEX_BITS));
68 assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= (1 << INST_INDEX_BITS));
69
70 assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents <= 4 * MAX_UNIFORMS);
71 assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents <= 4 * MAX_UNIFORMS);
72
73 assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxAddressOffset <= (1 << INST_INDEX_BITS));
74 assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAddressOffset <= (1 << INST_INDEX_BITS));
75
76 /* If this fails, increase prog_instruction::TexSrcUnit size */
77 STATIC_ASSERT(MAX_TEXTURE_UNITS <= (1 << 5));
78
79 /* If this fails, increase prog_instruction::TexSrcTarget size */
80 STATIC_ASSERT(NUM_TEXTURE_TARGETS <= (1 << 4));
81
82 ctx->Program.ErrorPos = -1;
83 ctx->Program.ErrorString = strdup("");
84
85 ctx->VertexProgram.Enabled = GL_FALSE;
86 ctx->VertexProgram.PointSizeEnabled =
87 (ctx->API == API_OPENGLES2) ? GL_TRUE : GL_FALSE;
88 ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
89 _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
90 ctx->Shared->DefaultVertexProgram);
91 assert(ctx->VertexProgram.Current);
92 ctx->VertexProgram.Cache = _mesa_new_program_cache();
93
94 ctx->FragmentProgram.Enabled = GL_FALSE;
95 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
96 ctx->Shared->DefaultFragmentProgram);
97 assert(ctx->FragmentProgram.Current);
98 ctx->FragmentProgram.Cache = _mesa_new_program_cache();
99
100 /* XXX probably move this stuff */
101 ctx->ATIFragmentShader.Enabled = GL_FALSE;
102 ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader;
103 assert(ctx->ATIFragmentShader.Current);
104 ctx->ATIFragmentShader.Current->RefCount++;
105 }
106
107
108 /**
109 * Free a context's vertex/fragment program state
110 */
111 void
112 _mesa_free_program_data(struct gl_context *ctx)
113 {
114 _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
115 _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
116 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
117 _mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache);
118
119 /* XXX probably move this stuff */
120 if (ctx->ATIFragmentShader.Current) {
121 ctx->ATIFragmentShader.Current->RefCount--;
122 if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
123 free(ctx->ATIFragmentShader.Current);
124 }
125 }
126
127 free((void *) ctx->Program.ErrorString);
128 }
129
130
131 /**
132 * Update the default program objects in the given context to reference those
133 * specified in the shared state and release those referencing the old
134 * shared state.
135 */
136 void
137 _mesa_update_default_objects_program(struct gl_context *ctx)
138 {
139 _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
140 ctx->Shared->DefaultVertexProgram);
141 assert(ctx->VertexProgram.Current);
142
143 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
144 ctx->Shared->DefaultFragmentProgram);
145 assert(ctx->FragmentProgram.Current);
146
147 /* XXX probably move this stuff */
148 if (ctx->ATIFragmentShader.Current) {
149 ctx->ATIFragmentShader.Current->RefCount--;
150 if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
151 free(ctx->ATIFragmentShader.Current);
152 }
153 }
154 ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
155 assert(ctx->ATIFragmentShader.Current);
156 ctx->ATIFragmentShader.Current->RefCount++;
157 }
158
159
160 /**
161 * Set the vertex/fragment program error state (position and error string).
162 * This is generally called from within the parsers.
163 */
164 void
165 _mesa_set_program_error(struct gl_context *ctx, GLint pos, const char *string)
166 {
167 ctx->Program.ErrorPos = pos;
168 free((void *) ctx->Program.ErrorString);
169 if (!string)
170 string = "";
171 ctx->Program.ErrorString = strdup(string);
172 }
173
174
175 /**
176 * Find the line number and column for 'pos' within 'string'.
177 * Return a copy of the line which contains 'pos'. Free the line with
178 * free().
179 * \param string the program string
180 * \param pos the position within the string
181 * \param line returns the line number corresponding to 'pos'.
182 * \param col returns the column number corresponding to 'pos'.
183 * \return copy of the line containing 'pos'.
184 */
185 const GLubyte *
186 _mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
187 GLint *line, GLint *col)
188 {
189 const GLubyte *lineStart = string;
190 const GLubyte *p = string;
191 GLubyte *s;
192 int len;
193
194 *line = 1;
195
196 while (p != pos) {
197 if (*p == (GLubyte) '\n') {
198 (*line)++;
199 lineStart = p + 1;
200 }
201 p++;
202 }
203
204 *col = (pos - lineStart) + 1;
205
206 /* return copy of this line */
207 while (*p != 0 && *p != '\n')
208 p++;
209 len = p - lineStart;
210 s = malloc(len + 1);
211 memcpy(s, lineStart, len);
212 s[len] = 0;
213
214 return s;
215 }
216
217
218 /**
219 * Initialize a new gl_program object.
220 */
221 static void
222 init_program_struct(struct gl_program *prog, GLenum target, GLuint id)
223 {
224 GLuint i;
225
226 assert(prog);
227
228 memset(prog, 0, sizeof(*prog));
229 prog->Id = id;
230 prog->Target = target;
231 prog->RefCount = 1;
232 prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
233
234 /* default mapping from samplers to texture units */
235 for (i = 0; i < MAX_SAMPLERS; i++)
236 prog->SamplerUnits[i] = i;
237 }
238
239
240 /**
241 * Initialize a new fragment program object.
242 */
243 struct gl_program *
244 _mesa_init_fragment_program(struct gl_context *ctx,
245 struct gl_fragment_program *prog,
246 GLenum target, GLuint id)
247 {
248 if (prog) {
249 init_program_struct(&prog->Base, target, id);
250 return &prog->Base;
251 }
252 return NULL;
253 }
254
255
256 /**
257 * Initialize a new vertex program object.
258 */
259 struct gl_program *
260 _mesa_init_vertex_program(struct gl_context *ctx,
261 struct gl_vertex_program *prog,
262 GLenum target, GLuint id)
263 {
264 if (prog) {
265 init_program_struct(&prog->Base, target, id);
266 return &prog->Base;
267 }
268 return NULL;
269 }
270
271
272 /**
273 * Initialize a new compute program object.
274 */
275 struct gl_program *
276 _mesa_init_compute_program(struct gl_context *ctx,
277 struct gl_compute_program *prog,
278 GLenum target, GLuint id)
279 {
280 if (prog) {
281 init_program_struct(&prog->Base, target, id);
282 return &prog->Base;
283 }
284 return NULL;
285 }
286
287
288 /**
289 * Initialize a new tessellation control program object.
290 */
291 struct gl_program *
292 _mesa_init_tess_ctrl_program(struct gl_context *ctx,
293 struct gl_tess_ctrl_program *prog,
294 GLenum target, GLuint id)
295 {
296 if (prog) {
297 init_program_struct(&prog->Base, target, id);
298 return &prog->Base;
299 }
300 return NULL;
301 }
302
303
304 /**
305 * Initialize a new tessellation evaluation program object.
306 */
307 struct gl_program *
308 _mesa_init_tess_eval_program(struct gl_context *ctx,
309 struct gl_tess_eval_program *prog,
310 GLenum target, GLuint id)
311 {
312 if (prog) {
313 init_program_struct(&prog->Base, target, id);
314 return &prog->Base;
315 }
316 return NULL;
317 }
318
319
320 /**
321 * Initialize a new geometry program object.
322 */
323 struct gl_program *
324 _mesa_init_geometry_program(struct gl_context *ctx,
325 struct gl_geometry_program *prog,
326 GLenum target, GLuint id)
327 {
328 if (prog) {
329 init_program_struct(&prog->Base, target, id);
330 return &prog->Base;
331 }
332 return NULL;
333 }
334
335
336 /**
337 * Allocate and initialize a new fragment/vertex program object but
338 * don't put it into the program hash table. Called via
339 * ctx->Driver.NewProgram. May be overridden (ie. replaced) by a
340 * device driver function to implement OO deriviation with additional
341 * types not understood by this function.
342 *
343 * \param ctx context
344 * \param id program id/number
345 * \param target program target/type
346 * \return pointer to new program object
347 */
348 struct gl_program *
349 _mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id)
350 {
351 struct gl_program *prog;
352 switch (target) {
353 case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
354 prog = _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
355 target, id );
356 break;
357 case GL_FRAGMENT_PROGRAM_NV:
358 case GL_FRAGMENT_PROGRAM_ARB:
359 prog =_mesa_init_fragment_program(ctx,
360 CALLOC_STRUCT(gl_fragment_program),
361 target, id );
362 break;
363 case GL_GEOMETRY_PROGRAM_NV:
364 prog = _mesa_init_geometry_program(ctx,
365 CALLOC_STRUCT(gl_geometry_program),
366 target, id);
367 break;
368 case GL_TESS_CONTROL_PROGRAM_NV:
369 prog = _mesa_init_tess_ctrl_program(ctx,
370 CALLOC_STRUCT(gl_tess_ctrl_program),
371 target, id);
372 break;
373 case GL_TESS_EVALUATION_PROGRAM_NV:
374 prog = _mesa_init_tess_eval_program(ctx,
375 CALLOC_STRUCT(gl_tess_eval_program),
376 target, id);
377 break;
378 case GL_COMPUTE_PROGRAM_NV:
379 prog = _mesa_init_compute_program(ctx,
380 CALLOC_STRUCT(gl_compute_program),
381 target, id);
382 break;
383 default:
384 _mesa_problem(ctx, "bad target in _mesa_new_program");
385 prog = NULL;
386 }
387 return prog;
388 }
389
390
391 /**
392 * Delete a program and remove it from the hash table, ignoring the
393 * reference count.
394 * Called via ctx->Driver.DeleteProgram. May be wrapped (OO deriviation)
395 * by a device driver function.
396 */
397 void
398 _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
399 {
400 (void) ctx;
401 assert(prog);
402 assert(prog->RefCount==0);
403
404 if (prog == &_mesa_DummyProgram)
405 return;
406
407 free(prog->String);
408 free(prog->LocalParams);
409
410 if (prog->Instructions) {
411 _mesa_free_instructions(prog->Instructions, prog->NumInstructions);
412 }
413 if (prog->Parameters) {
414 _mesa_free_parameter_list(prog->Parameters);
415 }
416
417 if (prog->nir) {
418 ralloc_free(prog->nir);
419 }
420
421 free(prog);
422 }
423
424
425 /**
426 * Return the gl_program object for a given ID.
427 * Basically just a wrapper for _mesa_HashLookup() to avoid a lot of
428 * casts elsewhere.
429 */
430 struct gl_program *
431 _mesa_lookup_program(struct gl_context *ctx, GLuint id)
432 {
433 if (id)
434 return (struct gl_program *) _mesa_HashLookup(ctx->Shared->Programs, id);
435 else
436 return NULL;
437 }
438
439
440 /**
441 * Reference counting for vertex/fragment programs
442 * This is normally only called from the _mesa_reference_program() macro
443 * when there's a real pointer change.
444 */
445 void
446 _mesa_reference_program_(struct gl_context *ctx,
447 struct gl_program **ptr,
448 struct gl_program *prog)
449 {
450 #ifndef NDEBUG
451 assert(ptr);
452 if (*ptr && prog) {
453 /* sanity check */
454 if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB)
455 assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
456 else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
457 assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
458 prog->Target == GL_FRAGMENT_PROGRAM_NV);
459 else if ((*ptr)->Target == GL_GEOMETRY_PROGRAM_NV)
460 assert(prog->Target == GL_GEOMETRY_PROGRAM_NV);
461 }
462 #endif
463
464 if (*ptr) {
465 GLboolean deleteFlag;
466
467 /*mtx_lock(&(*ptr)->Mutex);*/
468 assert((*ptr)->RefCount > 0);
469 (*ptr)->RefCount--;
470
471 deleteFlag = ((*ptr)->RefCount == 0);
472 /*mtx_lock(&(*ptr)->Mutex);*/
473
474 if (deleteFlag) {
475 assert(ctx);
476 ctx->Driver.DeleteProgram(ctx, *ptr);
477 }
478
479 *ptr = NULL;
480 }
481
482 assert(!*ptr);
483 if (prog) {
484 /*mtx_lock(&prog->Mutex);*/
485 prog->RefCount++;
486 /*mtx_unlock(&prog->Mutex);*/
487 }
488
489 *ptr = prog;
490 }
491
492
493 /**
494 * Return a copy of a program.
495 * XXX Problem here if the program object is actually OO-derivation
496 * made by a device driver.
497 */
498 struct gl_program *
499 _mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog)
500 {
501 struct gl_program *clone;
502
503 clone = ctx->Driver.NewProgram(ctx, prog->Target, prog->Id);
504 if (!clone)
505 return NULL;
506
507 assert(clone->Target == prog->Target);
508 assert(clone->RefCount == 1);
509
510 clone->String = (GLubyte *) strdup((char *) prog->String);
511 clone->Format = prog->Format;
512 clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
513 if (!clone->Instructions) {
514 _mesa_reference_program(ctx, &clone, NULL);
515 return NULL;
516 }
517 _mesa_copy_instructions(clone->Instructions, prog->Instructions,
518 prog->NumInstructions);
519 clone->InputsRead = prog->InputsRead;
520 clone->OutputsWritten = prog->OutputsWritten;
521 clone->SamplersUsed = prog->SamplersUsed;
522 clone->ShadowSamplers = prog->ShadowSamplers;
523 memcpy(clone->TexturesUsed, prog->TexturesUsed, sizeof(prog->TexturesUsed));
524
525 if (prog->Parameters)
526 clone->Parameters = _mesa_clone_parameter_list(prog->Parameters);
527 if (prog->LocalParams) {
528 clone->LocalParams = malloc(MAX_PROGRAM_LOCAL_PARAMS *
529 sizeof(float[4]));
530 if (!clone->LocalParams) {
531 _mesa_reference_program(ctx, &clone, NULL);
532 return NULL;
533 }
534 memcpy(clone->LocalParams, prog->LocalParams,
535 MAX_PROGRAM_LOCAL_PARAMS * sizeof(float[4]));
536 }
537 clone->IndirectRegisterFiles = prog->IndirectRegisterFiles;
538 clone->NumInstructions = prog->NumInstructions;
539 clone->NumTemporaries = prog->NumTemporaries;
540 clone->NumParameters = prog->NumParameters;
541 clone->NumAttributes = prog->NumAttributes;
542 clone->NumAddressRegs = prog->NumAddressRegs;
543 clone->NumNativeInstructions = prog->NumNativeInstructions;
544 clone->NumNativeTemporaries = prog->NumNativeTemporaries;
545 clone->NumNativeParameters = prog->NumNativeParameters;
546 clone->NumNativeAttributes = prog->NumNativeAttributes;
547 clone->NumNativeAddressRegs = prog->NumNativeAddressRegs;
548 clone->NumAluInstructions = prog->NumAluInstructions;
549 clone->NumTexInstructions = prog->NumTexInstructions;
550 clone->NumTexIndirections = prog->NumTexIndirections;
551 clone->NumNativeAluInstructions = prog->NumNativeAluInstructions;
552 clone->NumNativeTexInstructions = prog->NumNativeTexInstructions;
553 clone->NumNativeTexIndirections = prog->NumNativeTexIndirections;
554
555 switch (prog->Target) {
556 case GL_VERTEX_PROGRAM_ARB:
557 {
558 const struct gl_vertex_program *vp = gl_vertex_program_const(prog);
559 struct gl_vertex_program *vpc = gl_vertex_program(clone);
560 vpc->IsPositionInvariant = vp->IsPositionInvariant;
561 }
562 break;
563 case GL_FRAGMENT_PROGRAM_ARB:
564 {
565 const struct gl_fragment_program *fp = gl_fragment_program_const(prog);
566 struct gl_fragment_program *fpc = gl_fragment_program(clone);
567 fpc->UsesKill = fp->UsesKill;
568 fpc->UsesDFdy = fp->UsesDFdy;
569 fpc->OriginUpperLeft = fp->OriginUpperLeft;
570 fpc->PixelCenterInteger = fp->PixelCenterInteger;
571 }
572 break;
573 case GL_GEOMETRY_PROGRAM_NV:
574 {
575 const struct gl_geometry_program *gp = gl_geometry_program_const(prog);
576 struct gl_geometry_program *gpc = gl_geometry_program(clone);
577 gpc->VerticesOut = gp->VerticesOut;
578 gpc->InputType = gp->InputType;
579 gpc->Invocations = gp->Invocations;
580 gpc->OutputType = gp->OutputType;
581 gpc->UsesEndPrimitive = gp->UsesEndPrimitive;
582 gpc->UsesStreams = gp->UsesStreams;
583 }
584 break;
585 case GL_TESS_CONTROL_PROGRAM_NV:
586 {
587 const struct gl_tess_ctrl_program *tcp = gl_tess_ctrl_program_const(prog);
588 struct gl_tess_ctrl_program *tcpc = gl_tess_ctrl_program(clone);
589 tcpc->VerticesOut = tcp->VerticesOut;
590 }
591 break;
592 case GL_TESS_EVALUATION_PROGRAM_NV:
593 {
594 const struct gl_tess_eval_program *tep = gl_tess_eval_program_const(prog);
595 struct gl_tess_eval_program *tepc = gl_tess_eval_program(clone);
596 tepc->PrimitiveMode = tep->PrimitiveMode;
597 tepc->Spacing = tep->Spacing;
598 tepc->VertexOrder = tep->VertexOrder;
599 tepc->PointMode = tep->PointMode;
600 }
601 break;
602 default:
603 _mesa_problem(NULL, "Unexpected target in _mesa_clone_program");
604 }
605
606 return clone;
607 }
608
609
610 /**
611 * Insert 'count' NOP instructions at 'start' in the given program.
612 * Adjust branch targets accordingly.
613 */
614 GLboolean
615 _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count)
616 {
617 const GLuint origLen = prog->NumInstructions;
618 const GLuint newLen = origLen + count;
619 struct prog_instruction *newInst;
620 GLuint i;
621
622 /* adjust branches */
623 for (i = 0; i < prog->NumInstructions; i++) {
624 struct prog_instruction *inst = prog->Instructions + i;
625 if (inst->BranchTarget > 0) {
626 if ((GLuint)inst->BranchTarget >= start) {
627 inst->BranchTarget += count;
628 }
629 }
630 }
631
632 /* Alloc storage for new instructions */
633 newInst = _mesa_alloc_instructions(newLen);
634 if (!newInst) {
635 return GL_FALSE;
636 }
637
638 /* Copy 'start' instructions into new instruction buffer */
639 _mesa_copy_instructions(newInst, prog->Instructions, start);
640
641 /* init the new instructions */
642 _mesa_init_instructions(newInst + start, count);
643
644 /* Copy the remaining/tail instructions to new inst buffer */
645 _mesa_copy_instructions(newInst + start + count,
646 prog->Instructions + start,
647 origLen - start);
648
649 /* free old instructions */
650 _mesa_free_instructions(prog->Instructions, origLen);
651
652 /* install new instructions */
653 prog->Instructions = newInst;
654 prog->NumInstructions = newLen;
655
656 return GL_TRUE;
657 }
658
659 /**
660 * Delete 'count' instructions at 'start' in the given program.
661 * Adjust branch targets accordingly.
662 */
663 GLboolean
664 _mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count)
665 {
666 const GLuint origLen = prog->NumInstructions;
667 const GLuint newLen = origLen - count;
668 struct prog_instruction *newInst;
669 GLuint i;
670
671 /* adjust branches */
672 for (i = 0; i < prog->NumInstructions; i++) {
673 struct prog_instruction *inst = prog->Instructions + i;
674 if (inst->BranchTarget > 0) {
675 if (inst->BranchTarget > (GLint) start) {
676 inst->BranchTarget -= count;
677 }
678 }
679 }
680
681 /* Alloc storage for new instructions */
682 newInst = _mesa_alloc_instructions(newLen);
683 if (!newInst) {
684 return GL_FALSE;
685 }
686
687 /* Copy 'start' instructions into new instruction buffer */
688 _mesa_copy_instructions(newInst, prog->Instructions, start);
689
690 /* Copy the remaining/tail instructions to new inst buffer */
691 _mesa_copy_instructions(newInst + start,
692 prog->Instructions + start + count,
693 newLen - start);
694
695 /* free old instructions */
696 _mesa_free_instructions(prog->Instructions, origLen);
697
698 /* install new instructions */
699 prog->Instructions = newInst;
700 prog->NumInstructions = newLen;
701
702 return GL_TRUE;
703 }
704
705
706 /**
707 * Search instructions for registers that match (oldFile, oldIndex),
708 * replacing them with (newFile, newIndex).
709 */
710 static void
711 replace_registers(struct prog_instruction *inst, GLuint numInst,
712 GLuint oldFile, GLuint oldIndex,
713 GLuint newFile, GLuint newIndex)
714 {
715 GLuint i, j;
716 for (i = 0; i < numInst; i++) {
717 /* src regs */
718 for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) {
719 if (inst[i].SrcReg[j].File == oldFile &&
720 inst[i].SrcReg[j].Index == oldIndex) {
721 inst[i].SrcReg[j].File = newFile;
722 inst[i].SrcReg[j].Index = newIndex;
723 }
724 }
725 /* dst reg */
726 if (inst[i].DstReg.File == oldFile && inst[i].DstReg.Index == oldIndex) {
727 inst[i].DstReg.File = newFile;
728 inst[i].DstReg.Index = newIndex;
729 }
730 }
731 }
732
733
734 /**
735 * Search instructions for references to program parameters. When found,
736 * increment the parameter index by 'offset'.
737 * Used when combining programs.
738 */
739 static void
740 adjust_param_indexes(struct prog_instruction *inst, GLuint numInst,
741 GLuint offset)
742 {
743 GLuint i, j;
744 for (i = 0; i < numInst; i++) {
745 for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) {
746 GLuint f = inst[i].SrcReg[j].File;
747 if (f == PROGRAM_CONSTANT ||
748 f == PROGRAM_UNIFORM ||
749 f == PROGRAM_STATE_VAR) {
750 inst[i].SrcReg[j].Index += offset;
751 }
752 }
753 }
754 }
755
756
757 /**
758 * Combine two programs into one. Fix instructions so the outputs of
759 * the first program go to the inputs of the second program.
760 */
761 struct gl_program *
762 _mesa_combine_programs(struct gl_context *ctx,
763 const struct gl_program *progA,
764 const struct gl_program *progB)
765 {
766 struct prog_instruction *newInst;
767 struct gl_program *newProg;
768 const GLuint lenA = progA->NumInstructions - 1; /* omit END instr */
769 const GLuint lenB = progB->NumInstructions;
770 const GLuint numParamsA = _mesa_num_parameters(progA->Parameters);
771 const GLuint newLength = lenA + lenB;
772 GLboolean usedTemps[MAX_PROGRAM_TEMPS];
773 GLuint firstTemp = 0;
774 GLbitfield64 inputsB;
775 GLuint i;
776
777 assert(progA->Target == progB->Target);
778
779 newInst = _mesa_alloc_instructions(newLength);
780 if (!newInst)
781 return GL_FALSE;
782
783 _mesa_copy_instructions(newInst, progA->Instructions, lenA);
784 _mesa_copy_instructions(newInst + lenA, progB->Instructions, lenB);
785
786 /* adjust branch / instruction addresses for B's instructions */
787 for (i = 0; i < lenB; i++) {
788 newInst[lenA + i].BranchTarget += lenA;
789 }
790
791 newProg = ctx->Driver.NewProgram(ctx, progA->Target, 0);
792 newProg->Instructions = newInst;
793 newProg->NumInstructions = newLength;
794
795 /* find used temp regs (we may need new temps below) */
796 _mesa_find_used_registers(newProg, PROGRAM_TEMPORARY,
797 usedTemps, MAX_PROGRAM_TEMPS);
798
799 if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) {
800 const struct gl_fragment_program *fprogA, *fprogB;
801 struct gl_fragment_program *newFprog;
802 GLbitfield64 progB_inputsRead = progB->InputsRead;
803 GLint progB_colorFile, progB_colorIndex;
804
805 fprogA = gl_fragment_program_const(progA);
806 fprogB = gl_fragment_program_const(progB);
807 newFprog = gl_fragment_program(newProg);
808
809 newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill;
810 newFprog->UsesDFdy = fprogA->UsesDFdy || fprogB->UsesDFdy;
811
812 /* We'll do a search and replace for instances
813 * of progB_colorFile/progB_colorIndex below...
814 */
815 progB_colorFile = PROGRAM_INPUT;
816 progB_colorIndex = VARYING_SLOT_COL0;
817
818 /*
819 * The fragment program may get color from a state var rather than
820 * a fragment input (vertex output) if it's constant.
821 * See the texenvprogram.c code.
822 * So, search the program's parameter list now to see if the program
823 * gets color from a state var instead of a conventional fragment
824 * input register.
825 */
826 for (i = 0; i < progB->Parameters->NumParameters; i++) {
827 struct gl_program_parameter *p = &progB->Parameters->Parameters[i];
828 if (p->Type == PROGRAM_STATE_VAR &&
829 p->StateIndexes[0] == STATE_INTERNAL &&
830 p->StateIndexes[1] == STATE_CURRENT_ATTRIB &&
831 (int) p->StateIndexes[2] == (int) VERT_ATTRIB_COLOR0) {
832 progB_inputsRead |= VARYING_BIT_COL0;
833 progB_colorFile = PROGRAM_STATE_VAR;
834 progB_colorIndex = i;
835 break;
836 }
837 }
838
839 /* Connect color outputs of fprogA to color inputs of fprogB, via a
840 * new temporary register.
841 */
842 if ((progA->OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) &&
843 (progB_inputsRead & VARYING_BIT_COL0)) {
844 GLint tempReg = _mesa_find_free_register(usedTemps, MAX_PROGRAM_TEMPS,
845 firstTemp);
846 if (tempReg < 0) {
847 _mesa_problem(ctx, "No free temp regs found in "
848 "_mesa_combine_programs(), using 31");
849 tempReg = 31;
850 }
851 firstTemp = tempReg + 1;
852
853 /* replace writes to result.color[0] with tempReg */
854 replace_registers(newInst, lenA,
855 PROGRAM_OUTPUT, FRAG_RESULT_COLOR,
856 PROGRAM_TEMPORARY, tempReg);
857 /* replace reads from the input color with tempReg */
858 replace_registers(newInst + lenA, lenB,
859 progB_colorFile, progB_colorIndex, /* search for */
860 PROGRAM_TEMPORARY, tempReg /* replace with */ );
861 }
862
863 /* compute combined program's InputsRead */
864 inputsB = progB_inputsRead;
865 if (progA->OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) {
866 inputsB &= ~(1 << VARYING_SLOT_COL0);
867 }
868 newProg->InputsRead = progA->InputsRead | inputsB;
869 newProg->OutputsWritten = progB->OutputsWritten;
870 newProg->SamplersUsed = progA->SamplersUsed | progB->SamplersUsed;
871 }
872 else {
873 /* vertex program */
874 assert(0); /* XXX todo */
875 }
876
877 /*
878 * Merge parameters (uniforms, constants, etc)
879 */
880 newProg->Parameters = _mesa_combine_parameter_lists(progA->Parameters,
881 progB->Parameters);
882
883 adjust_param_indexes(newInst + lenA, lenB, numParamsA);
884
885
886 return newProg;
887 }
888
889
890 /**
891 * Populate the 'used' array with flags indicating which registers (TEMPs,
892 * INPUTs, OUTPUTs, etc, are used by the given program.
893 * \param file type of register to scan for
894 * \param used returns true/false flags for in use / free
895 * \param usedSize size of the 'used' array
896 */
897 void
898 _mesa_find_used_registers(const struct gl_program *prog,
899 gl_register_file file,
900 GLboolean used[], GLuint usedSize)
901 {
902 GLuint i, j;
903
904 memset(used, 0, usedSize);
905
906 for (i = 0; i < prog->NumInstructions; i++) {
907 const struct prog_instruction *inst = prog->Instructions + i;
908 const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
909
910 if (inst->DstReg.File == file) {
911 assert(inst->DstReg.Index < usedSize);
912 if(inst->DstReg.Index < usedSize)
913 used[inst->DstReg.Index] = GL_TRUE;
914 }
915
916 for (j = 0; j < n; j++) {
917 if (inst->SrcReg[j].File == file) {
918 assert(inst->SrcReg[j].Index < (GLint) usedSize);
919 if (inst->SrcReg[j].Index < (GLint) usedSize)
920 used[inst->SrcReg[j].Index] = GL_TRUE;
921 }
922 }
923 }
924 }
925
926
927 /**
928 * Scan the given 'used' register flag array for the first entry
929 * that's >= firstReg.
930 * \param used vector of flags indicating registers in use (as returned
931 * by _mesa_find_used_registers())
932 * \param usedSize size of the 'used' array
933 * \param firstReg first register to start searching at
934 * \return index of unused register, or -1 if none.
935 */
936 GLint
937 _mesa_find_free_register(const GLboolean used[],
938 GLuint usedSize, GLuint firstReg)
939 {
940 GLuint i;
941
942 assert(firstReg < usedSize);
943
944 for (i = firstReg; i < usedSize; i++)
945 if (!used[i])
946 return i;
947
948 return -1;
949 }
950
951
952
953 /**
954 * Check if the given register index is valid (doesn't exceed implementation-
955 * dependent limits).
956 * \return GL_TRUE if OK, GL_FALSE if bad index
957 */
958 GLboolean
959 _mesa_valid_register_index(const struct gl_context *ctx,
960 gl_shader_stage shaderType,
961 gl_register_file file, GLint index)
962 {
963 const struct gl_program_constants *c;
964
965 assert(0 <= shaderType && shaderType < MESA_SHADER_STAGES);
966 c = &ctx->Const.Program[shaderType];
967
968 switch (file) {
969 case PROGRAM_UNDEFINED:
970 return GL_TRUE; /* XXX or maybe false? */
971
972 case PROGRAM_TEMPORARY:
973 return index >= 0 && index < (GLint) c->MaxTemps;
974
975 case PROGRAM_UNIFORM:
976 case PROGRAM_STATE_VAR:
977 /* aka constant buffer */
978 return index >= 0 && index < (GLint) c->MaxUniformComponents / 4;
979
980 case PROGRAM_CONSTANT:
981 /* constant buffer w/ possible relative negative addressing */
982 return (index > (int) c->MaxUniformComponents / -4 &&
983 index < (int) c->MaxUniformComponents / 4);
984
985 case PROGRAM_INPUT:
986 if (index < 0)
987 return GL_FALSE;
988
989 switch (shaderType) {
990 case MESA_SHADER_VERTEX:
991 return index < VERT_ATTRIB_GENERIC0 + (GLint) c->MaxAttribs;
992 case MESA_SHADER_FRAGMENT:
993 return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
994 case MESA_SHADER_GEOMETRY:
995 return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
996 default:
997 return GL_FALSE;
998 }
999
1000 case PROGRAM_OUTPUT:
1001 if (index < 0)
1002 return GL_FALSE;
1003
1004 switch (shaderType) {
1005 case MESA_SHADER_VERTEX:
1006 return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
1007 case MESA_SHADER_FRAGMENT:
1008 return index < FRAG_RESULT_DATA0 + (GLint) ctx->Const.MaxDrawBuffers;
1009 case MESA_SHADER_GEOMETRY:
1010 return index < VARYING_SLOT_VAR0 + (GLint) ctx->Const.MaxVarying;
1011 default:
1012 return GL_FALSE;
1013 }
1014
1015 case PROGRAM_ADDRESS:
1016 return index >= 0 && index < (GLint) c->MaxAddressRegs;
1017
1018 default:
1019 _mesa_problem(ctx,
1020 "unexpected register file in _mesa_valid_register_index()");
1021 return GL_FALSE;
1022 }
1023 }
1024
1025
1026
1027 /**
1028 * "Post-process" a GPU program. This is intended to be used for debugging.
1029 * Example actions include no-op'ing instructions or changing instruction
1030 * behaviour.
1031 */
1032 void
1033 _mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog)
1034 {
1035 static const GLfloat white[4] = { 0.5, 0.5, 0.5, 0.5 };
1036 GLuint i;
1037 GLuint whiteSwizzle;
1038 GLint whiteIndex = _mesa_add_unnamed_constant(prog->Parameters,
1039 (gl_constant_value *) white,
1040 4, &whiteSwizzle);
1041
1042 (void) whiteIndex;
1043
1044 for (i = 0; i < prog->NumInstructions; i++) {
1045 struct prog_instruction *inst = prog->Instructions + i;
1046 const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
1047
1048 (void) n;
1049
1050 if (_mesa_is_tex_instruction(inst->Opcode)) {
1051 #if 0
1052 /* replace TEX/TXP/TXB with MOV */
1053 inst->Opcode = OPCODE_MOV;
1054 inst->DstReg.WriteMask = WRITEMASK_XYZW;
1055 inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
1056 inst->SrcReg[0].Negate = NEGATE_NONE;
1057 #endif
1058
1059 #if 0
1060 /* disable shadow texture mode */
1061 inst->TexShadow = 0;
1062 #endif
1063 }
1064
1065 if (inst->Opcode == OPCODE_TXP) {
1066 #if 0
1067 inst->Opcode = OPCODE_MOV;
1068 inst->DstReg.WriteMask = WRITEMASK_XYZW;
1069 inst->SrcReg[0].File = PROGRAM_CONSTANT;
1070 inst->SrcReg[0].Index = whiteIndex;
1071 inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
1072 inst->SrcReg[0].Negate = NEGATE_NONE;
1073 #endif
1074 #if 0
1075 inst->TexShadow = 0;
1076 #endif
1077 #if 0
1078 inst->Opcode = OPCODE_TEX;
1079 inst->TexShadow = 0;
1080 #endif
1081 }
1082
1083 }
1084 }
1085
1086 /* Gets the minimum number of shader invocations per fragment.
1087 * This function is useful to determine if we need to do per
1088 * sample shading or per fragment shading.
1089 */
1090 GLint
1091 _mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
1092 const struct gl_fragment_program *prog,
1093 bool ignore_sample_qualifier)
1094 {
1095 /* From ARB_sample_shading specification:
1096 * "Using gl_SampleID in a fragment shader causes the entire shader
1097 * to be evaluated per-sample."
1098 *
1099 * "Using gl_SamplePosition in a fragment shader causes the entire
1100 * shader to be evaluated per-sample."
1101 *
1102 * "If MULTISAMPLE or SAMPLE_SHADING_ARB is disabled, sample shading
1103 * has no effect."
1104 */
1105 if (ctx->Multisample.Enabled) {
1106 /* The ARB_gpu_shader5 specification says:
1107 *
1108 * "Use of the "sample" qualifier on a fragment shader input
1109 * forces per-sample shading"
1110 */
1111 if (prog->IsSample && !ignore_sample_qualifier)
1112 return MAX2(ctx->DrawBuffer->Visual.samples, 1);
1113
1114 if (prog->Base.SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID |
1115 SYSTEM_BIT_SAMPLE_POS))
1116 return MAX2(ctx->DrawBuffer->Visual.samples, 1);
1117 else if (ctx->Multisample.SampleShading)
1118 return MAX2(ceil(ctx->Multisample.MinSampleShadingValue *
1119 ctx->DrawBuffer->Visual.samples), 1);
1120 else
1121 return 1;
1122 }
1123 return 1;
1124 }