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 "main/state.h"
39 #include "program.h"
40 #include "prog_cache.h"
41 #include "prog_parameter.h"
42 #include "prog_instruction.h"
43 #include "util/bitscan.h"
44 #include "util/ralloc.h"
45 #include "util/u_atomic.h"
46
47 #include "state_tracker/st_program.h"
48 #include "state_tracker/st_context.h"
49
50 /**
51 * A pointer to this dummy program is put into the hash table when
52 * glGenPrograms is called.
53 */
54 struct gl_program _mesa_DummyProgram;
55
56
57 /**
58 * Init context's vertex/fragment program state
59 */
60 void
_mesa_init_program(struct gl_context * ctx)61 _mesa_init_program(struct gl_context *ctx)
62 {
63 /*
64 * If this assertion fails, we need to increase the field
65 * size for register indexes (see INST_INDEX_BITS).
66 */
67 assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents / 4
68 <= (1 << INST_INDEX_BITS));
69 assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents / 4
70 <= (1 << INST_INDEX_BITS));
71
72 assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps <= (1 << INST_INDEX_BITS));
73 assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= (1 << INST_INDEX_BITS));
74 assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTemps <= (1 << INST_INDEX_BITS));
75 assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= (1 << INST_INDEX_BITS));
76
77 assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents <= 4 * MAX_UNIFORMS);
78 assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents <= 4 * MAX_UNIFORMS);
79
80 assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxAddressOffset <= (1 << INST_INDEX_BITS));
81 assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAddressOffset <= (1 << INST_INDEX_BITS));
82
83 /* If this fails, increase prog_instruction::TexSrcUnit size */
84 STATIC_ASSERT(MAX_TEXTURE_UNITS <= (1 << 5));
85
86 /* If this fails, increase prog_instruction::TexSrcTarget size */
87 STATIC_ASSERT(NUM_TEXTURE_TARGETS <= (1 << 4));
88
89 ctx->Program.ErrorPos = -1;
90 ctx->Program.ErrorString = strdup("");
91
92 ctx->VertexProgram.Enabled = GL_FALSE;
93 ctx->VertexProgram.PointSizeEnabled =
94 (ctx->API == API_OPENGLES2) ? GL_TRUE : GL_FALSE;
95 ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
96 _mesa_reference_program(ctx, &ctx->VertexProgram.Current,
97 ctx->Shared->DefaultVertexProgram);
98 assert(ctx->VertexProgram.Current);
99 ctx->VertexProgram.Cache = _mesa_new_program_cache();
100
101 ctx->FragmentProgram.Enabled = GL_FALSE;
102 _mesa_reference_program(ctx, &ctx->FragmentProgram.Current,
103 ctx->Shared->DefaultFragmentProgram);
104 assert(ctx->FragmentProgram.Current);
105 ctx->FragmentProgram.Cache = _mesa_new_program_cache();
106 _mesa_reset_vertex_processing_mode(ctx);
107
108 /* XXX probably move this stuff */
109 ctx->ATIFragmentShader.Enabled = GL_FALSE;
110 ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader;
111 assert(ctx->ATIFragmentShader.Current);
112 ctx->ATIFragmentShader.Current->RefCount++;
113 }
114
115
116 /**
117 * Free a context's vertex/fragment program state
118 */
119 void
_mesa_free_program_data(struct gl_context * ctx)120 _mesa_free_program_data(struct gl_context *ctx)
121 {
122 _mesa_reference_program(ctx, &ctx->VertexProgram.Current, NULL);
123 _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
124 _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, NULL);
125 _mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache);
126
127 /* XXX probably move this stuff */
128 if (ctx->ATIFragmentShader.Current) {
129 ctx->ATIFragmentShader.Current->RefCount--;
130 if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
131 free(ctx->ATIFragmentShader.Current);
132 }
133 }
134
135 free((void *) ctx->Program.ErrorString);
136 }
137
138
139 /**
140 * Update the default program objects in the given context to reference those
141 * specified in the shared state and release those referencing the old
142 * shared state.
143 */
144 void
_mesa_update_default_objects_program(struct gl_context * ctx)145 _mesa_update_default_objects_program(struct gl_context *ctx)
146 {
147 _mesa_reference_program(ctx, &ctx->VertexProgram.Current,
148 ctx->Shared->DefaultVertexProgram);
149 assert(ctx->VertexProgram.Current);
150
151 _mesa_reference_program(ctx, &ctx->FragmentProgram.Current,
152 ctx->Shared->DefaultFragmentProgram);
153 assert(ctx->FragmentProgram.Current);
154
155 /* XXX probably move this stuff */
156 if (ctx->ATIFragmentShader.Current) {
157 ctx->ATIFragmentShader.Current->RefCount--;
158 if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
159 free(ctx->ATIFragmentShader.Current);
160 }
161 }
162 ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
163 assert(ctx->ATIFragmentShader.Current);
164 ctx->ATIFragmentShader.Current->RefCount++;
165 }
166
167
168 /**
169 * Set the vertex/fragment program error state (position and error string).
170 * This is generally called from within the parsers.
171 */
172 void
_mesa_set_program_error(struct gl_context * ctx,GLint pos,const char * string)173 _mesa_set_program_error(struct gl_context *ctx, GLint pos, const char *string)
174 {
175 ctx->Program.ErrorPos = pos;
176 free((void *) ctx->Program.ErrorString);
177 if (!string)
178 string = "";
179 ctx->Program.ErrorString = strdup(string);
180 }
181
182
183 /**
184 * Initialize a new gl_program object.
185 */
186 struct gl_program *
_mesa_init_gl_program(struct gl_program * prog,gl_shader_stage stage,GLuint id,bool is_arb_asm)187 _mesa_init_gl_program(struct gl_program *prog, gl_shader_stage stage,
188 GLuint id, bool is_arb_asm)
189 {
190 if (!prog)
191 return NULL;
192
193 memset(prog, 0, sizeof(*prog));
194 prog->Id = id;
195 prog->Target = _mesa_shader_stage_to_program(stage);
196 prog->RefCount = 1;
197 prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
198 prog->info.stage = stage;
199 prog->info.use_legacy_math_rules = is_arb_asm;
200
201 /* Uniforms that lack an initializer in the shader code have an initial
202 * value of zero. This includes sampler uniforms.
203 *
204 * Page 24 (page 30 of the PDF) of the GLSL 1.20 spec says:
205 *
206 * "The link time initial value is either the value of the variable's
207 * initializer, if present, or 0 if no initializer is present. Sampler
208 * types cannot have initializers."
209 *
210 * So we only initialise ARB assembly style programs.
211 */
212 if (is_arb_asm) {
213 /* default mapping from samplers to texture units */
214 for (unsigned i = 0; i < MAX_SAMPLERS; i++)
215 prog->SamplerUnits[i] = i;
216 }
217
218 return prog;
219 }
220
221 struct gl_program *
_mesa_new_program(struct gl_context * ctx,gl_shader_stage stage,GLuint id,bool is_arb_asm)222 _mesa_new_program(struct gl_context *ctx, gl_shader_stage stage, GLuint id,
223 bool is_arb_asm)
224 {
225 struct gl_program *prog;
226
227 switch (stage) {
228 case MESA_SHADER_VERTEX:
229 prog = (struct gl_program*)rzalloc(NULL, struct gl_vertex_program);
230 break;
231 default:
232 prog = rzalloc(NULL, struct gl_program);
233 break;
234 }
235
236 return _mesa_init_gl_program(prog, stage, id, is_arb_asm);
237 }
238
239 /**
240 * Delete a program and remove it from the hash table, ignoring the
241 * reference count.
242 */
243 void
_mesa_delete_program(struct gl_context * ctx,struct gl_program * prog)244 _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
245 {
246 struct st_context *st = st_context(ctx);
247 assert(prog);
248 assert(prog->RefCount==0);
249
250 st_release_variants(st, prog);
251
252 free(prog->serialized_nir);
253
254 if (prog == &_mesa_DummyProgram)
255 return;
256
257 if (prog->Parameters) {
258 _mesa_free_parameter_list(prog->Parameters);
259 }
260
261 if (prog->nir) {
262 ralloc_free(prog->nir);
263 }
264
265 if (prog->sh.BindlessSamplers) {
266 ralloc_free(prog->sh.BindlessSamplers);
267 }
268
269 if (prog->sh.BindlessImages) {
270 ralloc_free(prog->sh.BindlessImages);
271 }
272
273 if (prog->driver_cache_blob) {
274 ralloc_free(prog->driver_cache_blob);
275 }
276
277 ralloc_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 */
286 struct gl_program *
_mesa_lookup_program(struct gl_context * ctx,GLuint id)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 */
301 void
_mesa_reference_program_(struct gl_context * ctx,struct gl_program ** ptr,struct gl_program * prog)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 struct gl_program *oldProg = *ptr;
322
323 assert(oldProg->RefCount > 0);
324
325 if (p_atomic_dec_zero(&oldProg->RefCount)) {
326 assert(ctx);
327 _mesa_reference_shader_program_data(&oldProg->sh.data, NULL);
328 _mesa_delete_program(ctx, oldProg);
329 }
330
331 *ptr = NULL;
332 }
333
334 assert(!*ptr);
335 if (prog) {
336 p_atomic_inc(&prog->RefCount);
337 }
338
339 *ptr = prog;
340 }
341
342 /* Gets the minimum number of shader invocations per fragment.
343 * This function is useful to determine if we need to do per
344 * sample shading or per fragment shading.
345 */
346 GLint
_mesa_get_min_invocations_per_fragment(struct gl_context * ctx,const struct gl_program * prog)347 _mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
348 const struct gl_program *prog)
349 {
350 /* From ARB_sample_shading specification:
351 * "Using gl_SampleID in a fragment shader causes the entire shader
352 * to be evaluated per-sample."
353 *
354 * "Using gl_SamplePosition in a fragment shader causes the entire
355 * shader to be evaluated per-sample."
356 *
357 * "If MULTISAMPLE or SAMPLE_SHADING_ARB is disabled, sample shading
358 * has no effect."
359 */
360 if (ctx->Multisample.Enabled) {
361 /* The ARB_gpu_shader5 specification says:
362 *
363 * "Use of the "sample" qualifier on a fragment shader input
364 * forces per-sample shading"
365 */
366 if (prog->info.fs.uses_sample_qualifier ||
367 BITSET_TEST(prog->info.system_values_read, SYSTEM_VALUE_SAMPLE_ID) ||
368 BITSET_TEST(prog->info.system_values_read, SYSTEM_VALUE_SAMPLE_POS))
369 return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1);
370 else if (ctx->Multisample.SampleShading)
371 return MAX2(ceilf(ctx->Multisample.MinSampleShadingValue *
372 _mesa_geometric_samples(ctx->DrawBuffer)), 1);
373 else
374 return 1;
375 }
376 return 1;
377 }
378
379
380 GLbitfield
gl_external_samplers(const struct gl_program * prog)381 gl_external_samplers(const struct gl_program *prog)
382 {
383 GLbitfield external_samplers = 0;
384 GLbitfield mask = prog->SamplersUsed;
385
386 while (mask) {
387 int idx = u_bit_scan(&mask);
388 if (prog->sh.SamplerTargets[idx] == TEXTURE_EXTERNAL_INDEX)
389 external_samplers |= (1 << idx);
390 }
391
392 return external_samplers;
393 }
394
compare_state_var(const void * a1,const void * a2)395 static int compare_state_var(const void *a1, const void *a2)
396 {
397 const struct gl_program_parameter *p1 =
398 (const struct gl_program_parameter *)a1;
399 const struct gl_program_parameter *p2 =
400 (const struct gl_program_parameter *)a2;
401
402 for (unsigned i = 0; i < STATE_LENGTH; i++) {
403 if (p1->StateIndexes[i] != p2->StateIndexes[i])
404 return p1->StateIndexes[i] - p2->StateIndexes[i];
405 }
406 return 0;
407 }
408
409 void
_mesa_add_separate_state_parameters(struct gl_program * prog,struct gl_program_parameter_list * state_params)410 _mesa_add_separate_state_parameters(struct gl_program *prog,
411 struct gl_program_parameter_list *state_params)
412 {
413 unsigned num_state_params = state_params->NumParameters;
414
415 /* All state parameters should be vec4s. */
416 for (unsigned i = 0; i < num_state_params; i++) {
417 assert(state_params->Parameters[i].Type == PROGRAM_STATE_VAR);
418 assert(state_params->Parameters[i].Size == 4);
419 assert(state_params->Parameters[i].ValueOffset == i * 4);
420 }
421
422 /* Sort state parameters to facilitate better parameter merging. */
423 qsort(state_params->Parameters, num_state_params,
424 sizeof(state_params->Parameters[0]), compare_state_var);
425 unsigned *remap = malloc(num_state_params * sizeof(unsigned));
426
427 /* Add state parameters to the end of the parameter list. */
428 for (unsigned i = 0; i < num_state_params; i++) {
429 unsigned old_index = state_params->Parameters[i].ValueOffset / 4;
430
431 remap[old_index] =
432 _mesa_add_parameter(prog->Parameters, PROGRAM_STATE_VAR,
433 state_params->Parameters[i].Name,
434 state_params->Parameters[i].Size,
435 GL_NONE, NULL,
436 state_params->Parameters[i].StateIndexes,
437 state_params->Parameters[i].Padded);
438
439 prog->Parameters->StateFlags |=
440 _mesa_program_state_flags(state_params->Parameters[i].StateIndexes);
441 }
442
443 /* Fix up state parameter offsets in instructions. */
444 int num_instr = prog->arb.NumInstructions;
445 struct prog_instruction *instrs = prog->arb.Instructions;
446
447 /* Fix src indices after sorting. */
448 for (unsigned i = 0; i < num_instr; i++) {
449 struct prog_instruction *inst = instrs + i;
450 unsigned num_src = _mesa_num_inst_src_regs(inst->Opcode);
451
452 for (unsigned j = 0; j < num_src; j++) {
453 if (inst->SrcReg[j].File == PROGRAM_STATE_VAR)
454 inst->SrcReg[j].Index = remap[inst->SrcReg[j].Index];
455 }
456 }
457 free(remap);
458 }
459