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