program.c revision 67c2d80a839614e4638d6cff390627122f8148ca
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/framebuffer.h"
35#include "main/hash.h"
36#include "main/macros.h"
37#include "program.h"
38#include "prog_cache.h"
39#include "prog_parameter.h"
40#include "prog_instruction.h"
41#include "util/ralloc.h"
42
43
44/**
45 * A pointer to this dummy program is put into the hash table when
46 * glGenPrograms is called.
47 */
48struct gl_program _mesa_DummyProgram;
49
50
51/**
52 * Init context's vertex/fragment program state
53 */
54void
55_mesa_init_program(struct gl_context *ctx)
56{
57   /*
58    * If this assertion fails, we need to increase the field
59    * size for register indexes (see INST_INDEX_BITS).
60    */
61   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents / 4
62          <= (1 << INST_INDEX_BITS));
63   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents / 4
64          <= (1 << INST_INDEX_BITS));
65
66   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps <= (1 << INST_INDEX_BITS));
67   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= (1 << INST_INDEX_BITS));
68   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTemps <= (1 << INST_INDEX_BITS));
69   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= (1 << INST_INDEX_BITS));
70
71   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents <= 4 * MAX_UNIFORMS);
72   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents <= 4 * MAX_UNIFORMS);
73
74   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxAddressOffset <= (1 << INST_INDEX_BITS));
75   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAddressOffset <= (1 << INST_INDEX_BITS));
76
77   /* If this fails, increase prog_instruction::TexSrcUnit size */
78   STATIC_ASSERT(MAX_TEXTURE_UNITS <= (1 << 5));
79
80   /* If this fails, increase prog_instruction::TexSrcTarget size */
81   STATIC_ASSERT(NUM_TEXTURE_TARGETS <= (1 << 4));
82
83   ctx->Program.ErrorPos = -1;
84   ctx->Program.ErrorString = strdup("");
85
86   ctx->VertexProgram.Enabled = GL_FALSE;
87   ctx->VertexProgram.PointSizeEnabled =
88      (ctx->API == API_OPENGLES2) ? GL_TRUE : GL_FALSE;
89   ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
90   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
91                            ctx->Shared->DefaultVertexProgram);
92   assert(ctx->VertexProgram.Current);
93   ctx->VertexProgram.Cache = _mesa_new_program_cache();
94
95   ctx->FragmentProgram.Enabled = GL_FALSE;
96   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
97                            ctx->Shared->DefaultFragmentProgram);
98   assert(ctx->FragmentProgram.Current);
99   ctx->FragmentProgram.Cache = _mesa_new_program_cache();
100
101   /* XXX probably move this stuff */
102   ctx->ATIFragmentShader.Enabled = GL_FALSE;
103   ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader;
104   assert(ctx->ATIFragmentShader.Current);
105   ctx->ATIFragmentShader.Current->RefCount++;
106}
107
108
109/**
110 * Free a context's vertex/fragment program state
111 */
112void
113_mesa_free_program_data(struct gl_context *ctx)
114{
115   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
116   _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
117   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
118   _mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache);
119
120   /* XXX probably move this stuff */
121   if (ctx->ATIFragmentShader.Current) {
122      ctx->ATIFragmentShader.Current->RefCount--;
123      if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
124         free(ctx->ATIFragmentShader.Current);
125      }
126   }
127
128   free((void *) ctx->Program.ErrorString);
129}
130
131
132/**
133 * Update the default program objects in the given context to reference those
134 * specified in the shared state and release those referencing the old
135 * shared state.
136 */
137void
138_mesa_update_default_objects_program(struct gl_context *ctx)
139{
140   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
141                            ctx->Shared->DefaultVertexProgram);
142   assert(ctx->VertexProgram.Current);
143
144   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
145                            ctx->Shared->DefaultFragmentProgram);
146   assert(ctx->FragmentProgram.Current);
147
148   /* XXX probably move this stuff */
149   if (ctx->ATIFragmentShader.Current) {
150      ctx->ATIFragmentShader.Current->RefCount--;
151      if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
152         free(ctx->ATIFragmentShader.Current);
153      }
154   }
155   ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
156   assert(ctx->ATIFragmentShader.Current);
157   ctx->ATIFragmentShader.Current->RefCount++;
158}
159
160
161/**
162 * Set the vertex/fragment program error state (position and error string).
163 * This is generally called from within the parsers.
164 */
165void
166_mesa_set_program_error(struct gl_context *ctx, GLint pos, const char *string)
167{
168   ctx->Program.ErrorPos = pos;
169   free((void *) ctx->Program.ErrorString);
170   if (!string)
171      string = "";
172   ctx->Program.ErrorString = strdup(string);
173}
174
175
176/**
177 * Initialize a new gl_program object.
178 */
179struct gl_program *
180_mesa_init_gl_program(struct gl_program *prog, GLenum target, GLuint id)
181{
182   GLuint i;
183
184   if (!prog)
185      return NULL;
186
187   memset(prog, 0, sizeof(*prog));
188   mtx_init(&prog->Mutex, mtx_plain);
189   prog->Id = id;
190   prog->Target = target;
191   prog->RefCount = 1;
192   prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
193
194   /* default mapping from samplers to texture units */
195   for (i = 0; i < MAX_SAMPLERS; i++)
196      prog->SamplerUnits[i] = i;
197
198   return prog;
199}
200
201
202/**
203 * Allocate and initialize a new fragment/vertex program object but
204 * don't put it into the program hash table.  Called via
205 * ctx->Driver.NewProgram.  May be overridden (ie. replaced) by a
206 * device driver function to implement OO deriviation with additional
207 * types not understood by this function.
208 *
209 * \param ctx  context
210 * \param id   program id/number
211 * \param target  program target/type
212 * \return  pointer to new program object
213 */
214struct gl_program *
215_mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id)
216{
217   switch (target) {
218   case GL_VERTEX_PROGRAM_ARB: { /* == GL_VERTEX_PROGRAM_NV */
219      struct gl_vertex_program *prog = CALLOC_STRUCT(gl_vertex_program);
220      return _mesa_init_gl_program(&prog->Base, target, id);
221   }
222   case GL_FRAGMENT_PROGRAM_ARB: {
223      struct gl_fragment_program *prog = CALLOC_STRUCT(gl_fragment_program);
224      return _mesa_init_gl_program(&prog->Base, target, id);
225   }
226   case GL_GEOMETRY_PROGRAM_NV: {
227      struct gl_geometry_program *prog = CALLOC_STRUCT(gl_geometry_program);
228      return _mesa_init_gl_program(&prog->Base, target, id);
229   }
230   case GL_TESS_CONTROL_PROGRAM_NV:
231   case GL_TESS_EVALUATION_PROGRAM_NV: {
232      struct gl_program *prog = CALLOC_STRUCT(gl_program);
233      return _mesa_init_gl_program(prog, target, id);
234   }
235   case GL_COMPUTE_PROGRAM_NV: {
236      struct gl_compute_program *prog = CALLOC_STRUCT(gl_compute_program);
237      return _mesa_init_gl_program(&prog->Base, target, id);
238   }
239   default:
240      _mesa_problem(ctx, "bad target in _mesa_new_program");
241      return NULL;
242   }
243}
244
245
246/**
247 * Delete a program and remove it from the hash table, ignoring the
248 * reference count.
249 * Called via ctx->Driver.DeleteProgram.  May be wrapped (OO deriviation)
250 * by a device driver function.
251 */
252void
253_mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
254{
255   (void) ctx;
256   assert(prog);
257   assert(prog->RefCount==0);
258
259   if (prog == &_mesa_DummyProgram)
260      return;
261
262   free(prog->String);
263   free(prog->LocalParams);
264
265   if (prog->Instructions) {
266      _mesa_free_instructions(prog->Instructions, prog->NumInstructions);
267   }
268   if (prog->Parameters) {
269      _mesa_free_parameter_list(prog->Parameters);
270   }
271
272   if (prog->nir) {
273      ralloc_free(prog->nir);
274   }
275
276   mtx_destroy(&prog->Mutex);
277   free(prog);
278}
279
280
281/**
282 * Return the gl_program object for a given ID.
283 * Basically just a wrapper for _mesa_HashLookup() to avoid a lot of
284 * casts elsewhere.
285 */
286struct gl_program *
287_mesa_lookup_program(struct gl_context *ctx, GLuint id)
288{
289   if (id)
290      return (struct gl_program *) _mesa_HashLookup(ctx->Shared->Programs, id);
291   else
292      return NULL;
293}
294
295
296/**
297 * Reference counting for vertex/fragment programs
298 * This is normally only called from the _mesa_reference_program() macro
299 * when there's a real pointer change.
300 */
301void
302_mesa_reference_program_(struct gl_context *ctx,
303                         struct gl_program **ptr,
304                         struct gl_program *prog)
305{
306#ifndef NDEBUG
307   assert(ptr);
308   if (*ptr && prog) {
309      /* sanity check */
310      if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB)
311         assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
312      else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
313         assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
314                prog->Target == GL_FRAGMENT_PROGRAM_NV);
315      else if ((*ptr)->Target == GL_GEOMETRY_PROGRAM_NV)
316         assert(prog->Target == GL_GEOMETRY_PROGRAM_NV);
317   }
318#endif
319
320   if (*ptr) {
321      GLboolean deleteFlag;
322      struct gl_program *oldProg = *ptr;
323
324      mtx_lock(&oldProg->Mutex);
325      assert(oldProg->RefCount > 0);
326      oldProg->RefCount--;
327
328      deleteFlag = (oldProg->RefCount == 0);
329      mtx_unlock(&oldProg->Mutex);
330
331      if (deleteFlag) {
332         assert(ctx);
333         ctx->Driver.DeleteProgram(ctx, oldProg);
334      }
335
336      *ptr = NULL;
337   }
338
339   assert(!*ptr);
340   if (prog) {
341      mtx_lock(&prog->Mutex);
342      prog->RefCount++;
343      mtx_unlock(&prog->Mutex);
344   }
345
346   *ptr = prog;
347}
348
349
350/**
351 * Insert 'count' NOP instructions at 'start' in the given program.
352 * Adjust branch targets accordingly.
353 */
354GLboolean
355_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count)
356{
357   const GLuint origLen = prog->NumInstructions;
358   const GLuint newLen = origLen + count;
359   struct prog_instruction *newInst;
360   GLuint i;
361
362   /* adjust branches */
363   for (i = 0; i < prog->NumInstructions; i++) {
364      struct prog_instruction *inst = prog->Instructions + i;
365      if (inst->BranchTarget > 0) {
366         if ((GLuint)inst->BranchTarget >= start) {
367            inst->BranchTarget += count;
368         }
369      }
370   }
371
372   /* Alloc storage for new instructions */
373   newInst = _mesa_alloc_instructions(newLen);
374   if (!newInst) {
375      return GL_FALSE;
376   }
377
378   /* Copy 'start' instructions into new instruction buffer */
379   _mesa_copy_instructions(newInst, prog->Instructions, start);
380
381   /* init the new instructions */
382   _mesa_init_instructions(newInst + start, count);
383
384   /* Copy the remaining/tail instructions to new inst buffer */
385   _mesa_copy_instructions(newInst + start + count,
386                           prog->Instructions + start,
387                           origLen - start);
388
389   /* free old instructions */
390   _mesa_free_instructions(prog->Instructions, origLen);
391
392   /* install new instructions */
393   prog->Instructions = newInst;
394   prog->NumInstructions = newLen;
395
396   return GL_TRUE;
397}
398
399/**
400 * Delete 'count' instructions at 'start' in the given program.
401 * Adjust branch targets accordingly.
402 */
403GLboolean
404_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count)
405{
406   const GLuint origLen = prog->NumInstructions;
407   const GLuint newLen = origLen - count;
408   struct prog_instruction *newInst;
409   GLuint i;
410
411   /* adjust branches */
412   for (i = 0; i < prog->NumInstructions; i++) {
413      struct prog_instruction *inst = prog->Instructions + i;
414      if (inst->BranchTarget > 0) {
415         if (inst->BranchTarget > (GLint) start) {
416            inst->BranchTarget -= count;
417         }
418      }
419   }
420
421   /* Alloc storage for new instructions */
422   newInst = _mesa_alloc_instructions(newLen);
423   if (!newInst) {
424      return GL_FALSE;
425   }
426
427   /* Copy 'start' instructions into new instruction buffer */
428   _mesa_copy_instructions(newInst, prog->Instructions, start);
429
430   /* Copy the remaining/tail instructions to new inst buffer */
431   _mesa_copy_instructions(newInst + start,
432                           prog->Instructions + start + count,
433                           newLen - start);
434
435   /* free old instructions */
436   _mesa_free_instructions(prog->Instructions, origLen);
437
438   /* install new instructions */
439   prog->Instructions = newInst;
440   prog->NumInstructions = newLen;
441
442   return GL_TRUE;
443}
444
445
446/**
447 * Populate the 'used' array with flags indicating which registers (TEMPs,
448 * INPUTs, OUTPUTs, etc, are used by the given program.
449 * \param file  type of register to scan for
450 * \param used  returns true/false flags for in use / free
451 * \param usedSize  size of the 'used' array
452 */
453void
454_mesa_find_used_registers(const struct gl_program *prog,
455                          gl_register_file file,
456                          GLboolean used[], GLuint usedSize)
457{
458   GLuint i, j;
459
460   memset(used, 0, usedSize);
461
462   for (i = 0; i < prog->NumInstructions; i++) {
463      const struct prog_instruction *inst = prog->Instructions + i;
464      const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
465
466      if (inst->DstReg.File == file) {
467         assert(inst->DstReg.Index < usedSize);
468         if(inst->DstReg.Index < usedSize)
469            used[inst->DstReg.Index] = GL_TRUE;
470      }
471
472      for (j = 0; j < n; j++) {
473         if (inst->SrcReg[j].File == file) {
474            assert(inst->SrcReg[j].Index < (GLint) usedSize);
475            if (inst->SrcReg[j].Index < (GLint) usedSize)
476               used[inst->SrcReg[j].Index] = GL_TRUE;
477         }
478      }
479   }
480}
481
482
483/**
484 * Scan the given 'used' register flag array for the first entry
485 * that's >= firstReg.
486 * \param used  vector of flags indicating registers in use (as returned
487 *              by _mesa_find_used_registers())
488 * \param usedSize  size of the 'used' array
489 * \param firstReg  first register to start searching at
490 * \return index of unused register, or -1 if none.
491 */
492GLint
493_mesa_find_free_register(const GLboolean used[],
494                         GLuint usedSize, GLuint firstReg)
495{
496   GLuint i;
497
498   assert(firstReg < usedSize);
499
500   for (i = firstReg; i < usedSize; i++)
501      if (!used[i])
502         return i;
503
504   return -1;
505}
506
507
508/* Gets the minimum number of shader invocations per fragment.
509 * This function is useful to determine if we need to do per
510 * sample shading or per fragment shading.
511 */
512GLint
513_mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
514                                       const struct gl_fragment_program *prog,
515                                       bool ignore_sample_qualifier)
516{
517   /* From ARB_sample_shading specification:
518    * "Using gl_SampleID in a fragment shader causes the entire shader
519    *  to be evaluated per-sample."
520    *
521    * "Using gl_SamplePosition in a fragment shader causes the entire
522    *  shader to be evaluated per-sample."
523    *
524    * "If MULTISAMPLE or SAMPLE_SHADING_ARB is disabled, sample shading
525    *  has no effect."
526    */
527   if (ctx->Multisample.Enabled) {
528      /* The ARB_gpu_shader5 specification says:
529       *
530       * "Use of the "sample" qualifier on a fragment shader input
531       *  forces per-sample shading"
532       */
533      if (prog->IsSample && !ignore_sample_qualifier)
534         return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1);
535
536      if (prog->Base.SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID |
537                                         SYSTEM_BIT_SAMPLE_POS))
538         return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1);
539      else if (ctx->Multisample.SampleShading)
540         return MAX2(ceil(ctx->Multisample.MinSampleShadingValue *
541                          _mesa_geometric_samples(ctx->DrawBuffer)), 1);
542      else
543         return 1;
544   }
545   return 1;
546}
547