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