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 "main/shaderobj.h"
38#include "program.h"
39#include "prog_cache.h"
40#include "prog_parameter.h"
41#include "prog_instruction.h"
42#include "util/ralloc.h"
43
44
45/**
46 * A pointer to this dummy program is put into the hash table when
47 * glGenPrograms is called.
48 */
49struct gl_program _mesa_DummyProgram;
50
51
52/**
53 * Init context's vertex/fragment program state
54 */
55void
56_mesa_init_program(struct gl_context *ctx)
57{
58   /*
59    * If this assertion fails, we need to increase the field
60    * size for register indexes (see INST_INDEX_BITS).
61    */
62   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents / 4
63          <= (1 << INST_INDEX_BITS));
64   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents / 4
65          <= (1 << INST_INDEX_BITS));
66
67   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps <= (1 << INST_INDEX_BITS));
68   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= (1 << INST_INDEX_BITS));
69   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTemps <= (1 << INST_INDEX_BITS));
70   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= (1 << INST_INDEX_BITS));
71
72   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents <= 4 * MAX_UNIFORMS);
73   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents <= 4 * MAX_UNIFORMS);
74
75   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxAddressOffset <= (1 << INST_INDEX_BITS));
76   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAddressOffset <= (1 << INST_INDEX_BITS));
77
78   /* If this fails, increase prog_instruction::TexSrcUnit size */
79   STATIC_ASSERT(MAX_TEXTURE_UNITS <= (1 << 5));
80
81   /* If this fails, increase prog_instruction::TexSrcTarget size */
82   STATIC_ASSERT(NUM_TEXTURE_TARGETS <= (1 << 4));
83
84   ctx->Program.ErrorPos = -1;
85   ctx->Program.ErrorString = strdup("");
86
87   ctx->VertexProgram.Enabled = GL_FALSE;
88   ctx->VertexProgram.PointSizeEnabled =
89      (ctx->API == API_OPENGLES2) ? GL_TRUE : GL_FALSE;
90   ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
91   _mesa_reference_program(ctx, &ctx->VertexProgram.Current,
92                           ctx->Shared->DefaultVertexProgram);
93   assert(ctx->VertexProgram.Current);
94   ctx->VertexProgram.Cache = _mesa_new_program_cache();
95
96   ctx->FragmentProgram.Enabled = GL_FALSE;
97   _mesa_reference_program(ctx, &ctx->FragmentProgram.Current,
98                           ctx->Shared->DefaultFragmentProgram);
99   assert(ctx->FragmentProgram.Current);
100   ctx->FragmentProgram.Cache = _mesa_new_program_cache();
101
102   /* XXX probably move this stuff */
103   ctx->ATIFragmentShader.Enabled = GL_FALSE;
104   ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader;
105   assert(ctx->ATIFragmentShader.Current);
106   ctx->ATIFragmentShader.Current->RefCount++;
107}
108
109
110/**
111 * Free a context's vertex/fragment program state
112 */
113void
114_mesa_free_program_data(struct gl_context *ctx)
115{
116   _mesa_reference_program(ctx, &ctx->VertexProgram.Current, NULL);
117   _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
118   _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, NULL);
119   _mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache);
120
121   /* XXX probably move this stuff */
122   if (ctx->ATIFragmentShader.Current) {
123      ctx->ATIFragmentShader.Current->RefCount--;
124      if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
125         free(ctx->ATIFragmentShader.Current);
126      }
127   }
128
129   free((void *) ctx->Program.ErrorString);
130}
131
132
133/**
134 * Update the default program objects in the given context to reference those
135 * specified in the shared state and release those referencing the old
136 * shared state.
137 */
138void
139_mesa_update_default_objects_program(struct gl_context *ctx)
140{
141   _mesa_reference_program(ctx, &ctx->VertexProgram.Current,
142                           ctx->Shared->DefaultVertexProgram);
143   assert(ctx->VertexProgram.Current);
144
145   _mesa_reference_program(ctx, &ctx->FragmentProgram.Current,
146                            ctx->Shared->DefaultFragmentProgram);
147   assert(ctx->FragmentProgram.Current);
148
149   /* XXX probably move this stuff */
150   if (ctx->ATIFragmentShader.Current) {
151      ctx->ATIFragmentShader.Current->RefCount--;
152      if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
153         free(ctx->ATIFragmentShader.Current);
154      }
155   }
156   ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
157   assert(ctx->ATIFragmentShader.Current);
158   ctx->ATIFragmentShader.Current->RefCount++;
159}
160
161
162/**
163 * Set the vertex/fragment program error state (position and error string).
164 * This is generally called from within the parsers.
165 */
166void
167_mesa_set_program_error(struct gl_context *ctx, GLint pos, const char *string)
168{
169   ctx->Program.ErrorPos = pos;
170   free((void *) ctx->Program.ErrorString);
171   if (!string)
172      string = "";
173   ctx->Program.ErrorString = strdup(string);
174}
175
176
177/**
178 * Initialize a new gl_program object.
179 */
180struct gl_program *
181_mesa_init_gl_program(struct gl_program *prog, GLenum target, GLuint id,
182                      bool is_arb_asm)
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   prog->info.stage = _mesa_program_enum_to_shader_stage(target);
194   prog->is_arb_asm = is_arb_asm;
195
196   /* Uniforms that lack an initializer in the shader code have an initial
197    * value of zero.  This includes sampler uniforms.
198    *
199    * Page 24 (page 30 of the PDF) of the GLSL 1.20 spec says:
200    *
201    *     "The link time initial value is either the value of the variable's
202    *     initializer, if present, or 0 if no initializer is present. Sampler
203    *     types cannot have initializers."
204    *
205    * So we only initialise ARB assembly style programs.
206    */
207   if (is_arb_asm) {
208      /* default mapping from samplers to texture units */
209      for (unsigned i = 0; i < MAX_SAMPLERS; i++)
210         prog->SamplerUnits[i] = i;
211   }
212
213   return prog;
214}
215
216
217/**
218 * Allocate and initialize a new fragment/vertex program object but
219 * don't put it into the program hash table.  Called via
220 * ctx->Driver.NewProgram.  May be overridden (ie. replaced) by a
221 * device driver function to implement OO deriviation with additional
222 * types not understood by this function.
223 *
224 * \param ctx  context
225 * \param id   program id/number
226 * \param target  program target/type
227 * \return  pointer to new program object
228 */
229struct gl_program *
230_mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id,
231                  bool is_arb_asm)
232{
233   switch (target) {
234   case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
235   case GL_GEOMETRY_PROGRAM_NV:
236   case GL_TESS_CONTROL_PROGRAM_NV:
237   case GL_TESS_EVALUATION_PROGRAM_NV:
238   case GL_FRAGMENT_PROGRAM_ARB:
239   case GL_COMPUTE_PROGRAM_NV: {
240      struct gl_program *prog = rzalloc(NULL, struct gl_program);
241      return _mesa_init_gl_program(prog, target, id, is_arb_asm);
242   }
243   default:
244      _mesa_problem(ctx, "bad target in _mesa_new_program");
245      return NULL;
246   }
247}
248
249
250/**
251 * Delete a program and remove it from the hash table, ignoring the
252 * reference count.
253 * Called via ctx->Driver.DeleteProgram.  May be wrapped (OO deriviation)
254 * by a device driver function.
255 */
256void
257_mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
258{
259   (void) ctx;
260   assert(prog);
261   assert(prog->RefCount==0);
262
263   if (prog == &_mesa_DummyProgram)
264      return;
265
266   if (prog->Parameters) {
267      _mesa_free_parameter_list(prog->Parameters);
268   }
269
270   if (prog->nir) {
271      ralloc_free(prog->nir);
272   }
273
274   mtx_destroy(&prog->Mutex);
275   ralloc_free(prog);
276}
277
278
279/**
280 * Return the gl_program object for a given ID.
281 * Basically just a wrapper for _mesa_HashLookup() to avoid a lot of
282 * casts elsewhere.
283 */
284struct gl_program *
285_mesa_lookup_program(struct gl_context *ctx, GLuint id)
286{
287   if (id)
288      return (struct gl_program *) _mesa_HashLookup(ctx->Shared->Programs, id);
289   else
290      return NULL;
291}
292
293
294/**
295 * Reference counting for vertex/fragment programs
296 * This is normally only called from the _mesa_reference_program() macro
297 * when there's a real pointer change.
298 */
299void
300_mesa_reference_program_(struct gl_context *ctx,
301                         struct gl_program **ptr,
302                         struct gl_program *prog)
303{
304#ifndef NDEBUG
305   assert(ptr);
306   if (*ptr && prog) {
307      /* sanity check */
308      if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB)
309         assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
310      else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
311         assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
312                prog->Target == GL_FRAGMENT_PROGRAM_NV);
313      else if ((*ptr)->Target == GL_GEOMETRY_PROGRAM_NV)
314         assert(prog->Target == GL_GEOMETRY_PROGRAM_NV);
315   }
316#endif
317
318   if (*ptr) {
319      GLboolean deleteFlag;
320      struct gl_program *oldProg = *ptr;
321
322      mtx_lock(&oldProg->Mutex);
323      assert(oldProg->RefCount > 0);
324      oldProg->RefCount--;
325
326      deleteFlag = (oldProg->RefCount == 0);
327      mtx_unlock(&oldProg->Mutex);
328
329      if (deleteFlag) {
330         assert(ctx);
331         _mesa_reference_shader_program_data(ctx, &oldProg->sh.data, NULL);
332         ctx->Driver.DeleteProgram(ctx, oldProg);
333      }
334
335      *ptr = NULL;
336   }
337
338   assert(!*ptr);
339   if (prog) {
340      mtx_lock(&prog->Mutex);
341      prog->RefCount++;
342      mtx_unlock(&prog->Mutex);
343   }
344
345   *ptr = prog;
346}
347
348
349/**
350 * Insert 'count' NOP instructions at 'start' in the given program.
351 * Adjust branch targets accordingly.
352 */
353GLboolean
354_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count)
355{
356   const GLuint origLen = prog->arb.NumInstructions;
357   const GLuint newLen = origLen + count;
358   struct prog_instruction *newInst;
359   GLuint i;
360
361   /* adjust branches */
362   for (i = 0; i < prog->arb.NumInstructions; i++) {
363      struct prog_instruction *inst = prog->arb.Instructions + i;
364      if (inst->BranchTarget > 0) {
365         if ((GLuint)inst->BranchTarget >= start) {
366            inst->BranchTarget += count;
367         }
368      }
369   }
370
371   /* Alloc storage for new instructions */
372   newInst = rzalloc_array(prog, struct prog_instruction, newLen);
373   if (!newInst) {
374      return GL_FALSE;
375   }
376
377   /* Copy 'start' instructions into new instruction buffer */
378   _mesa_copy_instructions(newInst, prog->arb.Instructions, start);
379
380   /* init the new instructions */
381   _mesa_init_instructions(newInst + start, count);
382
383   /* Copy the remaining/tail instructions to new inst buffer */
384   _mesa_copy_instructions(newInst + start + count,
385                           prog->arb.Instructions + start,
386                           origLen - start);
387
388   /* free old instructions */
389   ralloc_free(prog->arb.Instructions);
390
391   /* install new instructions */
392   prog->arb.Instructions = newInst;
393   prog->arb.NumInstructions = newLen;
394
395   return GL_TRUE;
396}
397
398/**
399 * Delete 'count' instructions at 'start' in the given program.
400 * Adjust branch targets accordingly.
401 */
402GLboolean
403_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count,
404                          void *mem_ctx)
405{
406   const GLuint origLen = prog->arb.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->arb.NumInstructions; i++) {
413      struct prog_instruction *inst = prog->arb.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 = rzalloc_array(mem_ctx, struct prog_instruction, newLen);
423   if (!newInst) {
424      return GL_FALSE;
425   }
426
427   /* Copy 'start' instructions into new instruction buffer */
428   _mesa_copy_instructions(newInst, prog->arb.Instructions, start);
429
430   /* Copy the remaining/tail instructions to new inst buffer */
431   _mesa_copy_instructions(newInst + start,
432                           prog->arb.Instructions + start + count,
433                           newLen - start);
434
435   /* free old instructions */
436   ralloc_free(prog->arb.Instructions);
437
438   /* install new instructions */
439   prog->arb.Instructions = newInst;
440   prog->arb.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->arb.NumInstructions; i++) {
463      const struct prog_instruction *inst = prog->arb.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_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->info.fs.uses_sample_qualifier && !ignore_sample_qualifier)
534         return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1);
535
536      if (prog->info.system_values_read & (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