1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the "Software"), 8848b8605Smrg * to deal in the Software without restriction, including without limitation 9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 11848b8605Smrg * Software is furnished to do so, subject to the following conditions: 12848b8605Smrg * 13848b8605Smrg * The above copyright notice and this permission notice shall be included 14848b8605Smrg * in all copies or substantial portions of the Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg/** 26848b8605Smrg * \file program.c 27848b8605Smrg * Vertex and fragment program support functions. 28848b8605Smrg * \author Brian Paul 29848b8605Smrg */ 30848b8605Smrg 31848b8605Smrg 32848b8605Smrg#include "main/glheader.h" 33848b8605Smrg#include "main/context.h" 34b8e80941Smrg#include "main/framebuffer.h" 35848b8605Smrg#include "main/hash.h" 36848b8605Smrg#include "main/macros.h" 37b8e80941Smrg#include "main/shaderobj.h" 38848b8605Smrg#include "program.h" 39848b8605Smrg#include "prog_cache.h" 40848b8605Smrg#include "prog_parameter.h" 41848b8605Smrg#include "prog_instruction.h" 42b8e80941Smrg#include "util/bitscan.h" 43b8e80941Smrg#include "util/ralloc.h" 44b8e80941Smrg#include "util/u_atomic.h" 45848b8605Smrg 46848b8605Smrg 47848b8605Smrg/** 48848b8605Smrg * A pointer to this dummy program is put into the hash table when 49848b8605Smrg * glGenPrograms is called. 50848b8605Smrg */ 51848b8605Smrgstruct gl_program _mesa_DummyProgram; 52848b8605Smrg 53848b8605Smrg 54848b8605Smrg/** 55848b8605Smrg * Init context's vertex/fragment program state 56848b8605Smrg */ 57848b8605Smrgvoid 58848b8605Smrg_mesa_init_program(struct gl_context *ctx) 59848b8605Smrg{ 60848b8605Smrg /* 61848b8605Smrg * If this assertion fails, we need to increase the field 62848b8605Smrg * size for register indexes (see INST_INDEX_BITS). 63848b8605Smrg */ 64b8e80941Smrg assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents / 4 65848b8605Smrg <= (1 << INST_INDEX_BITS)); 66b8e80941Smrg assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents / 4 67848b8605Smrg <= (1 << INST_INDEX_BITS)); 68848b8605Smrg 69b8e80941Smrg assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps <= (1 << INST_INDEX_BITS)); 70b8e80941Smrg assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= (1 << INST_INDEX_BITS)); 71b8e80941Smrg assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTemps <= (1 << INST_INDEX_BITS)); 72b8e80941Smrg assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= (1 << INST_INDEX_BITS)); 73848b8605Smrg 74b8e80941Smrg assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents <= 4 * MAX_UNIFORMS); 75b8e80941Smrg assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents <= 4 * MAX_UNIFORMS); 76848b8605Smrg 77b8e80941Smrg assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxAddressOffset <= (1 << INST_INDEX_BITS)); 78b8e80941Smrg assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAddressOffset <= (1 << INST_INDEX_BITS)); 79848b8605Smrg 80848b8605Smrg /* If this fails, increase prog_instruction::TexSrcUnit size */ 81848b8605Smrg STATIC_ASSERT(MAX_TEXTURE_UNITS <= (1 << 5)); 82848b8605Smrg 83848b8605Smrg /* If this fails, increase prog_instruction::TexSrcTarget size */ 84848b8605Smrg STATIC_ASSERT(NUM_TEXTURE_TARGETS <= (1 << 4)); 85848b8605Smrg 86848b8605Smrg ctx->Program.ErrorPos = -1; 87b8e80941Smrg ctx->Program.ErrorString = strdup(""); 88848b8605Smrg 89848b8605Smrg ctx->VertexProgram.Enabled = GL_FALSE; 90848b8605Smrg ctx->VertexProgram.PointSizeEnabled = 91848b8605Smrg (ctx->API == API_OPENGLES2) ? GL_TRUE : GL_FALSE; 92848b8605Smrg ctx->VertexProgram.TwoSideEnabled = GL_FALSE; 93b8e80941Smrg _mesa_reference_program(ctx, &ctx->VertexProgram.Current, 94b8e80941Smrg ctx->Shared->DefaultVertexProgram); 95848b8605Smrg assert(ctx->VertexProgram.Current); 96848b8605Smrg ctx->VertexProgram.Cache = _mesa_new_program_cache(); 97848b8605Smrg 98848b8605Smrg ctx->FragmentProgram.Enabled = GL_FALSE; 99b8e80941Smrg _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, 100b8e80941Smrg ctx->Shared->DefaultFragmentProgram); 101848b8605Smrg assert(ctx->FragmentProgram.Current); 102848b8605Smrg ctx->FragmentProgram.Cache = _mesa_new_program_cache(); 103b8e80941Smrg ctx->VertexProgram._VPMode = VP_MODE_FF; 104848b8605Smrg 105848b8605Smrg /* XXX probably move this stuff */ 106848b8605Smrg ctx->ATIFragmentShader.Enabled = GL_FALSE; 107848b8605Smrg ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader; 108848b8605Smrg assert(ctx->ATIFragmentShader.Current); 109848b8605Smrg ctx->ATIFragmentShader.Current->RefCount++; 110848b8605Smrg} 111848b8605Smrg 112848b8605Smrg 113848b8605Smrg/** 114848b8605Smrg * Free a context's vertex/fragment program state 115848b8605Smrg */ 116848b8605Smrgvoid 117848b8605Smrg_mesa_free_program_data(struct gl_context *ctx) 118848b8605Smrg{ 119b8e80941Smrg _mesa_reference_program(ctx, &ctx->VertexProgram.Current, NULL); 120848b8605Smrg _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache); 121b8e80941Smrg _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, NULL); 122848b8605Smrg _mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache); 123848b8605Smrg 124848b8605Smrg /* XXX probably move this stuff */ 125848b8605Smrg if (ctx->ATIFragmentShader.Current) { 126848b8605Smrg ctx->ATIFragmentShader.Current->RefCount--; 127848b8605Smrg if (ctx->ATIFragmentShader.Current->RefCount <= 0) { 128848b8605Smrg free(ctx->ATIFragmentShader.Current); 129848b8605Smrg } 130848b8605Smrg } 131848b8605Smrg 132848b8605Smrg free((void *) ctx->Program.ErrorString); 133848b8605Smrg} 134848b8605Smrg 135848b8605Smrg 136848b8605Smrg/** 137848b8605Smrg * Update the default program objects in the given context to reference those 138848b8605Smrg * specified in the shared state and release those referencing the old 139848b8605Smrg * shared state. 140848b8605Smrg */ 141848b8605Smrgvoid 142848b8605Smrg_mesa_update_default_objects_program(struct gl_context *ctx) 143848b8605Smrg{ 144b8e80941Smrg _mesa_reference_program(ctx, &ctx->VertexProgram.Current, 145b8e80941Smrg ctx->Shared->DefaultVertexProgram); 146848b8605Smrg assert(ctx->VertexProgram.Current); 147848b8605Smrg 148b8e80941Smrg _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, 149848b8605Smrg ctx->Shared->DefaultFragmentProgram); 150848b8605Smrg assert(ctx->FragmentProgram.Current); 151848b8605Smrg 152848b8605Smrg /* XXX probably move this stuff */ 153848b8605Smrg if (ctx->ATIFragmentShader.Current) { 154848b8605Smrg ctx->ATIFragmentShader.Current->RefCount--; 155848b8605Smrg if (ctx->ATIFragmentShader.Current->RefCount <= 0) { 156848b8605Smrg free(ctx->ATIFragmentShader.Current); 157848b8605Smrg } 158848b8605Smrg } 159848b8605Smrg ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader; 160848b8605Smrg assert(ctx->ATIFragmentShader.Current); 161848b8605Smrg ctx->ATIFragmentShader.Current->RefCount++; 162848b8605Smrg} 163848b8605Smrg 164848b8605Smrg 165848b8605Smrg/** 166848b8605Smrg * Set the vertex/fragment program error state (position and error string). 167848b8605Smrg * This is generally called from within the parsers. 168848b8605Smrg */ 169848b8605Smrgvoid 170848b8605Smrg_mesa_set_program_error(struct gl_context *ctx, GLint pos, const char *string) 171848b8605Smrg{ 172848b8605Smrg ctx->Program.ErrorPos = pos; 173848b8605Smrg free((void *) ctx->Program.ErrorString); 174848b8605Smrg if (!string) 175848b8605Smrg string = ""; 176b8e80941Smrg ctx->Program.ErrorString = strdup(string); 177848b8605Smrg} 178848b8605Smrg 179848b8605Smrg 180848b8605Smrg/** 181848b8605Smrg * Initialize a new gl_program object. 182848b8605Smrg */ 183b8e80941Smrgstruct gl_program * 184b8e80941Smrg_mesa_init_gl_program(struct gl_program *prog, GLenum target, GLuint id, 185b8e80941Smrg bool is_arb_asm) 186848b8605Smrg{ 187b8e80941Smrg if (!prog) 188b8e80941Smrg return NULL; 189848b8605Smrg 190848b8605Smrg memset(prog, 0, sizeof(*prog)); 191848b8605Smrg prog->Id = id; 192848b8605Smrg prog->Target = target; 193848b8605Smrg prog->RefCount = 1; 194848b8605Smrg prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB; 195b8e80941Smrg prog->info.stage = _mesa_program_enum_to_shader_stage(target); 196b8e80941Smrg prog->is_arb_asm = is_arb_asm; 197848b8605Smrg 198b8e80941Smrg /* Uniforms that lack an initializer in the shader code have an initial 199b8e80941Smrg * value of zero. This includes sampler uniforms. 200b8e80941Smrg * 201b8e80941Smrg * Page 24 (page 30 of the PDF) of the GLSL 1.20 spec says: 202b8e80941Smrg * 203b8e80941Smrg * "The link time initial value is either the value of the variable's 204b8e80941Smrg * initializer, if present, or 0 if no initializer is present. Sampler 205b8e80941Smrg * types cannot have initializers." 206b8e80941Smrg * 207b8e80941Smrg * So we only initialise ARB assembly style programs. 208b8e80941Smrg */ 209b8e80941Smrg if (is_arb_asm) { 210b8e80941Smrg /* default mapping from samplers to texture units */ 211b8e80941Smrg for (unsigned i = 0; i < MAX_SAMPLERS; i++) 212b8e80941Smrg prog->SamplerUnits[i] = i; 213848b8605Smrg } 214848b8605Smrg 215b8e80941Smrg return prog; 216848b8605Smrg} 217848b8605Smrg 218848b8605Smrg 219848b8605Smrg/** 220848b8605Smrg * Allocate and initialize a new fragment/vertex program object but 221848b8605Smrg * don't put it into the program hash table. Called via 222848b8605Smrg * ctx->Driver.NewProgram. May be overridden (ie. replaced) by a 223848b8605Smrg * device driver function to implement OO deriviation with additional 224848b8605Smrg * types not understood by this function. 225848b8605Smrg * 226848b8605Smrg * \param ctx context 227848b8605Smrg * \param id program id/number 228848b8605Smrg * \param target program target/type 229848b8605Smrg * \return pointer to new program object 230848b8605Smrg */ 231848b8605Smrgstruct gl_program * 232b8e80941Smrg_mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id, 233b8e80941Smrg bool is_arb_asm) 234848b8605Smrg{ 235848b8605Smrg switch (target) { 236848b8605Smrg case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ 237b8e80941Smrg case GL_GEOMETRY_PROGRAM_NV: 238b8e80941Smrg case GL_TESS_CONTROL_PROGRAM_NV: 239b8e80941Smrg case GL_TESS_EVALUATION_PROGRAM_NV: 240848b8605Smrg case GL_FRAGMENT_PROGRAM_ARB: 241b8e80941Smrg case GL_COMPUTE_PROGRAM_NV: { 242b8e80941Smrg struct gl_program *prog = rzalloc(NULL, struct gl_program); 243b8e80941Smrg return _mesa_init_gl_program(prog, target, id, is_arb_asm); 244b8e80941Smrg } 245848b8605Smrg default: 246848b8605Smrg _mesa_problem(ctx, "bad target in _mesa_new_program"); 247b8e80941Smrg return NULL; 248848b8605Smrg } 249848b8605Smrg} 250848b8605Smrg 251848b8605Smrg 252848b8605Smrg/** 253848b8605Smrg * Delete a program and remove it from the hash table, ignoring the 254848b8605Smrg * reference count. 255848b8605Smrg * Called via ctx->Driver.DeleteProgram. May be wrapped (OO deriviation) 256848b8605Smrg * by a device driver function. 257848b8605Smrg */ 258848b8605Smrgvoid 259848b8605Smrg_mesa_delete_program(struct gl_context *ctx, struct gl_program *prog) 260848b8605Smrg{ 261848b8605Smrg (void) ctx; 262b8e80941Smrg assert(prog); 263b8e80941Smrg assert(prog->RefCount==0); 264848b8605Smrg 265848b8605Smrg if (prog == &_mesa_DummyProgram) 266848b8605Smrg return; 267848b8605Smrg 268848b8605Smrg if (prog->Parameters) { 269848b8605Smrg _mesa_free_parameter_list(prog->Parameters); 270848b8605Smrg } 271848b8605Smrg 272b8e80941Smrg if (prog->nir) { 273b8e80941Smrg ralloc_free(prog->nir); 274b8e80941Smrg } 275b8e80941Smrg 276b8e80941Smrg if (prog->sh.BindlessSamplers) { 277b8e80941Smrg ralloc_free(prog->sh.BindlessSamplers); 278b8e80941Smrg } 279b8e80941Smrg 280b8e80941Smrg if (prog->sh.BindlessImages) { 281b8e80941Smrg ralloc_free(prog->sh.BindlessImages); 282b8e80941Smrg } 283b8e80941Smrg 284b8e80941Smrg if (prog->driver_cache_blob) { 285b8e80941Smrg ralloc_free(prog->driver_cache_blob); 286b8e80941Smrg } 287b8e80941Smrg 288b8e80941Smrg ralloc_free(prog); 289848b8605Smrg} 290848b8605Smrg 291848b8605Smrg 292848b8605Smrg/** 293848b8605Smrg * Return the gl_program object for a given ID. 294848b8605Smrg * Basically just a wrapper for _mesa_HashLookup() to avoid a lot of 295848b8605Smrg * casts elsewhere. 296848b8605Smrg */ 297848b8605Smrgstruct gl_program * 298848b8605Smrg_mesa_lookup_program(struct gl_context *ctx, GLuint id) 299848b8605Smrg{ 300848b8605Smrg if (id) 301848b8605Smrg return (struct gl_program *) _mesa_HashLookup(ctx->Shared->Programs, id); 302848b8605Smrg else 303848b8605Smrg return NULL; 304848b8605Smrg} 305848b8605Smrg 306848b8605Smrg 307848b8605Smrg/** 308848b8605Smrg * Reference counting for vertex/fragment programs 309848b8605Smrg * This is normally only called from the _mesa_reference_program() macro 310848b8605Smrg * when there's a real pointer change. 311848b8605Smrg */ 312848b8605Smrgvoid 313848b8605Smrg_mesa_reference_program_(struct gl_context *ctx, 314848b8605Smrg struct gl_program **ptr, 315848b8605Smrg struct gl_program *prog) 316848b8605Smrg{ 317848b8605Smrg#ifndef NDEBUG 318848b8605Smrg assert(ptr); 319848b8605Smrg if (*ptr && prog) { 320848b8605Smrg /* sanity check */ 321848b8605Smrg if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB) 322b8e80941Smrg assert(prog->Target == GL_VERTEX_PROGRAM_ARB); 323848b8605Smrg else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB) 324b8e80941Smrg assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB || 325848b8605Smrg prog->Target == GL_FRAGMENT_PROGRAM_NV); 326b8e80941Smrg else if ((*ptr)->Target == GL_GEOMETRY_PROGRAM_NV) 327b8e80941Smrg assert(prog->Target == GL_GEOMETRY_PROGRAM_NV); 328848b8605Smrg } 329848b8605Smrg#endif 330848b8605Smrg 331848b8605Smrg if (*ptr) { 332b8e80941Smrg struct gl_program *oldProg = *ptr; 333848b8605Smrg 334b8e80941Smrg assert(oldProg->RefCount > 0); 335848b8605Smrg 336b8e80941Smrg if (p_atomic_dec_zero(&oldProg->RefCount)) { 337b8e80941Smrg assert(ctx); 338b8e80941Smrg _mesa_reference_shader_program_data(ctx, &oldProg->sh.data, NULL); 339b8e80941Smrg ctx->Driver.DeleteProgram(ctx, oldProg); 340848b8605Smrg } 341848b8605Smrg 342848b8605Smrg *ptr = NULL; 343848b8605Smrg } 344848b8605Smrg 345848b8605Smrg assert(!*ptr); 346848b8605Smrg if (prog) { 347b8e80941Smrg p_atomic_inc(&prog->RefCount); 348848b8605Smrg } 349848b8605Smrg 350848b8605Smrg *ptr = prog; 351848b8605Smrg} 352848b8605Smrg 353848b8605Smrg 354848b8605Smrg/** 355848b8605Smrg * Insert 'count' NOP instructions at 'start' in the given program. 356848b8605Smrg * Adjust branch targets accordingly. 357848b8605Smrg */ 358848b8605SmrgGLboolean 359848b8605Smrg_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count) 360848b8605Smrg{ 361b8e80941Smrg const GLuint origLen = prog->arb.NumInstructions; 362848b8605Smrg const GLuint newLen = origLen + count; 363848b8605Smrg struct prog_instruction *newInst; 364848b8605Smrg GLuint i; 365848b8605Smrg 366848b8605Smrg /* adjust branches */ 367b8e80941Smrg for (i = 0; i < prog->arb.NumInstructions; i++) { 368b8e80941Smrg struct prog_instruction *inst = prog->arb.Instructions + i; 369848b8605Smrg if (inst->BranchTarget > 0) { 370848b8605Smrg if ((GLuint)inst->BranchTarget >= start) { 371848b8605Smrg inst->BranchTarget += count; 372848b8605Smrg } 373848b8605Smrg } 374848b8605Smrg } 375848b8605Smrg 376848b8605Smrg /* Alloc storage for new instructions */ 377b8e80941Smrg newInst = rzalloc_array(prog, struct prog_instruction, newLen); 378848b8605Smrg if (!newInst) { 379848b8605Smrg return GL_FALSE; 380848b8605Smrg } 381848b8605Smrg 382848b8605Smrg /* Copy 'start' instructions into new instruction buffer */ 383b8e80941Smrg _mesa_copy_instructions(newInst, prog->arb.Instructions, start); 384848b8605Smrg 385848b8605Smrg /* init the new instructions */ 386848b8605Smrg _mesa_init_instructions(newInst + start, count); 387848b8605Smrg 388848b8605Smrg /* Copy the remaining/tail instructions to new inst buffer */ 389848b8605Smrg _mesa_copy_instructions(newInst + start + count, 390b8e80941Smrg prog->arb.Instructions + start, 391848b8605Smrg origLen - start); 392848b8605Smrg 393848b8605Smrg /* free old instructions */ 394b8e80941Smrg ralloc_free(prog->arb.Instructions); 395848b8605Smrg 396848b8605Smrg /* install new instructions */ 397b8e80941Smrg prog->arb.Instructions = newInst; 398b8e80941Smrg prog->arb.NumInstructions = newLen; 399848b8605Smrg 400848b8605Smrg return GL_TRUE; 401848b8605Smrg} 402848b8605Smrg 403848b8605Smrg/** 404848b8605Smrg * Delete 'count' instructions at 'start' in the given program. 405848b8605Smrg * Adjust branch targets accordingly. 406848b8605Smrg */ 407848b8605SmrgGLboolean 408b8e80941Smrg_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count, 409b8e80941Smrg void *mem_ctx) 410848b8605Smrg{ 411b8e80941Smrg const GLuint origLen = prog->arb.NumInstructions; 412848b8605Smrg const GLuint newLen = origLen - count; 413848b8605Smrg struct prog_instruction *newInst; 414848b8605Smrg GLuint i; 415848b8605Smrg 416848b8605Smrg /* adjust branches */ 417b8e80941Smrg for (i = 0; i < prog->arb.NumInstructions; i++) { 418b8e80941Smrg struct prog_instruction *inst = prog->arb.Instructions + i; 419848b8605Smrg if (inst->BranchTarget > 0) { 420848b8605Smrg if (inst->BranchTarget > (GLint) start) { 421848b8605Smrg inst->BranchTarget -= count; 422848b8605Smrg } 423848b8605Smrg } 424848b8605Smrg } 425848b8605Smrg 426848b8605Smrg /* Alloc storage for new instructions */ 427b8e80941Smrg newInst = rzalloc_array(mem_ctx, struct prog_instruction, newLen); 428848b8605Smrg if (!newInst) { 429848b8605Smrg return GL_FALSE; 430848b8605Smrg } 431848b8605Smrg 432848b8605Smrg /* Copy 'start' instructions into new instruction buffer */ 433b8e80941Smrg _mesa_copy_instructions(newInst, prog->arb.Instructions, start); 434848b8605Smrg 435848b8605Smrg /* Copy the remaining/tail instructions to new inst buffer */ 436848b8605Smrg _mesa_copy_instructions(newInst + start, 437b8e80941Smrg prog->arb.Instructions + start + count, 438848b8605Smrg newLen - start); 439848b8605Smrg 440848b8605Smrg /* free old instructions */ 441b8e80941Smrg ralloc_free(prog->arb.Instructions); 442848b8605Smrg 443848b8605Smrg /* install new instructions */ 444b8e80941Smrg prog->arb.Instructions = newInst; 445b8e80941Smrg prog->arb.NumInstructions = newLen; 446848b8605Smrg 447848b8605Smrg return GL_TRUE; 448848b8605Smrg} 449848b8605Smrg 450848b8605Smrg 451848b8605Smrg/** 452848b8605Smrg * Populate the 'used' array with flags indicating which registers (TEMPs, 453848b8605Smrg * INPUTs, OUTPUTs, etc, are used by the given program. 454848b8605Smrg * \param file type of register to scan for 455848b8605Smrg * \param used returns true/false flags for in use / free 456848b8605Smrg * \param usedSize size of the 'used' array 457848b8605Smrg */ 458848b8605Smrgvoid 459848b8605Smrg_mesa_find_used_registers(const struct gl_program *prog, 460848b8605Smrg gl_register_file file, 461848b8605Smrg GLboolean used[], GLuint usedSize) 462848b8605Smrg{ 463848b8605Smrg GLuint i, j; 464848b8605Smrg 465848b8605Smrg memset(used, 0, usedSize); 466848b8605Smrg 467b8e80941Smrg for (i = 0; i < prog->arb.NumInstructions; i++) { 468b8e80941Smrg const struct prog_instruction *inst = prog->arb.Instructions + i; 469848b8605Smrg const GLuint n = _mesa_num_inst_src_regs(inst->Opcode); 470848b8605Smrg 471848b8605Smrg if (inst->DstReg.File == file) { 472b8e80941Smrg assert(inst->DstReg.Index < usedSize); 473848b8605Smrg if(inst->DstReg.Index < usedSize) 474848b8605Smrg used[inst->DstReg.Index] = GL_TRUE; 475848b8605Smrg } 476848b8605Smrg 477848b8605Smrg for (j = 0; j < n; j++) { 478848b8605Smrg if (inst->SrcReg[j].File == file) { 479b8e80941Smrg assert(inst->SrcReg[j].Index < (GLint) usedSize); 480848b8605Smrg if (inst->SrcReg[j].Index < (GLint) usedSize) 481848b8605Smrg used[inst->SrcReg[j].Index] = GL_TRUE; 482848b8605Smrg } 483848b8605Smrg } 484848b8605Smrg } 485848b8605Smrg} 486848b8605Smrg 487848b8605Smrg 488848b8605Smrg/** 489848b8605Smrg * Scan the given 'used' register flag array for the first entry 490848b8605Smrg * that's >= firstReg. 491848b8605Smrg * \param used vector of flags indicating registers in use (as returned 492848b8605Smrg * by _mesa_find_used_registers()) 493848b8605Smrg * \param usedSize size of the 'used' array 494848b8605Smrg * \param firstReg first register to start searching at 495848b8605Smrg * \return index of unused register, or -1 if none. 496848b8605Smrg */ 497848b8605SmrgGLint 498848b8605Smrg_mesa_find_free_register(const GLboolean used[], 499848b8605Smrg GLuint usedSize, GLuint firstReg) 500848b8605Smrg{ 501848b8605Smrg GLuint i; 502848b8605Smrg 503848b8605Smrg assert(firstReg < usedSize); 504848b8605Smrg 505848b8605Smrg for (i = firstReg; i < usedSize; i++) 506848b8605Smrg if (!used[i]) 507848b8605Smrg return i; 508848b8605Smrg 509848b8605Smrg return -1; 510848b8605Smrg} 511848b8605Smrg 512848b8605Smrg 513848b8605Smrg/* Gets the minimum number of shader invocations per fragment. 514848b8605Smrg * This function is useful to determine if we need to do per 515848b8605Smrg * sample shading or per fragment shading. 516848b8605Smrg */ 517848b8605SmrgGLint 518848b8605Smrg_mesa_get_min_invocations_per_fragment(struct gl_context *ctx, 519b8e80941Smrg const struct gl_program *prog) 520848b8605Smrg{ 521848b8605Smrg /* From ARB_sample_shading specification: 522848b8605Smrg * "Using gl_SampleID in a fragment shader causes the entire shader 523848b8605Smrg * to be evaluated per-sample." 524848b8605Smrg * 525848b8605Smrg * "Using gl_SamplePosition in a fragment shader causes the entire 526848b8605Smrg * shader to be evaluated per-sample." 527848b8605Smrg * 528848b8605Smrg * "If MULTISAMPLE or SAMPLE_SHADING_ARB is disabled, sample shading 529848b8605Smrg * has no effect." 530848b8605Smrg */ 531848b8605Smrg if (ctx->Multisample.Enabled) { 532848b8605Smrg /* The ARB_gpu_shader5 specification says: 533848b8605Smrg * 534848b8605Smrg * "Use of the "sample" qualifier on a fragment shader input 535848b8605Smrg * forces per-sample shading" 536848b8605Smrg */ 537b8e80941Smrg if (prog->info.fs.uses_sample_qualifier || 538b8e80941Smrg (prog->info.system_values_read & (SYSTEM_BIT_SAMPLE_ID | 539b8e80941Smrg SYSTEM_BIT_SAMPLE_POS))) 540b8e80941Smrg return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1); 541848b8605Smrg else if (ctx->Multisample.SampleShading) 542848b8605Smrg return MAX2(ceil(ctx->Multisample.MinSampleShadingValue * 543b8e80941Smrg _mesa_geometric_samples(ctx->DrawBuffer)), 1); 544848b8605Smrg else 545848b8605Smrg return 1; 546848b8605Smrg } 547848b8605Smrg return 1; 548848b8605Smrg} 549b8e80941Smrg 550b8e80941Smrg 551b8e80941SmrgGLbitfield 552b8e80941Smrggl_external_samplers(const struct gl_program *prog) 553b8e80941Smrg{ 554b8e80941Smrg GLbitfield external_samplers = 0; 555b8e80941Smrg GLbitfield mask = prog->SamplersUsed; 556b8e80941Smrg 557b8e80941Smrg while (mask) { 558b8e80941Smrg int idx = u_bit_scan(&mask); 559b8e80941Smrg if (prog->sh.SamplerTargets[idx] == TEXTURE_EXTERNAL_INDEX) 560b8e80941Smrg external_samplers |= (1 << idx); 561b8e80941Smrg } 562b8e80941Smrg 563b8e80941Smrg return external_samplers; 564b8e80941Smrg} 565