Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenslang_link.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.3 00004 * 00005 * Copyright (C) 2008 Brian Paul All Rights Reserved. 00006 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 00007 * 00008 * Permission is hereby granted, free of charge, to any person obtaining a 00009 * copy of this software and associated documentation files (the "Software"), 00010 * to deal in the Software without restriction, including without limitation 00011 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00012 * and/or sell copies of the Software, and to permit persons to whom the 00013 * Software is furnished to do so, subject to the following conditions: 00014 * 00015 * The above copyright notice and this permission notice shall be included 00016 * in all copies or substantial portions of the Software. 00017 * 00018 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00019 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00020 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00021 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00022 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00023 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00024 */ 00025 00032 #include "main/imports.h" 00033 #include "main/context.h" 00034 #include "main/hash.h" 00035 #include "main/macros.h" 00036 #include "shader/program.h" 00037 #include "shader/prog_instruction.h" 00038 #include "shader/prog_parameter.h" 00039 #include "shader/prog_print.h" 00040 #include "shader/prog_statevars.h" 00041 #include "shader/prog_uniform.h" 00042 #include "shader/shader_api.h" 00043 #include "slang_link.h" 00044 00045 00047 static struct gl_vertex_program * 00048 vertex_program(struct gl_program *prog) 00049 { 00050 assert(prog->Target == GL_VERTEX_PROGRAM_ARB); 00051 return (struct gl_vertex_program *) prog; 00052 } 00053 00054 00056 static struct gl_fragment_program * 00057 fragment_program(struct gl_program *prog) 00058 { 00059 assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); 00060 return (struct gl_fragment_program *) prog; 00061 } 00062 00063 00067 static void 00068 link_error(struct gl_shader_program *shProg, const char *msg) 00069 { 00070 if (shProg->InfoLog) { 00071 _mesa_free(shProg->InfoLog); 00072 } 00073 shProg->InfoLog = _mesa_strdup(msg); 00074 shProg->LinkStatus = GL_FALSE; 00075 } 00076 00077 00078 00082 static GLboolean 00083 bits_agree(GLbitfield flags1, GLbitfield flags2, GLbitfield bit) 00084 { 00085 return (flags1 & bit) == (flags2 & bit); 00086 } 00087 00088 00099 static GLboolean 00100 link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog) 00101 { 00102 GLuint *map, i, firstVarying, newFile; 00103 GLbitfield *inOutFlags; 00104 00105 map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint)); 00106 if (!map) 00107 return GL_FALSE; 00108 00109 /* Varying variables are treated like other vertex program outputs 00110 * (and like other fragment program inputs). The position of the 00111 * first varying differs for vertex/fragment programs... 00112 * Also, replace File=PROGRAM_VARYING with File=PROGRAM_INPUT/OUTPUT. 00113 */ 00114 if (prog->Target == GL_VERTEX_PROGRAM_ARB) { 00115 firstVarying = VERT_RESULT_VAR0; 00116 newFile = PROGRAM_OUTPUT; 00117 inOutFlags = prog->OutputFlags; 00118 } 00119 else { 00120 assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); 00121 firstVarying = FRAG_ATTRIB_VAR0; 00122 newFile = PROGRAM_INPUT; 00123 inOutFlags = prog->InputFlags; 00124 } 00125 00126 for (i = 0; i < prog->Varying->NumParameters; i++) { 00127 /* see if this varying is in the linked varying list */ 00128 const struct gl_program_parameter *var = prog->Varying->Parameters + i; 00129 GLint j = _mesa_lookup_parameter_index(shProg->Varying, -1, var->Name); 00130 if (j >= 0) { 00131 /* varying is already in list, do some error checking */ 00132 const struct gl_program_parameter *v = 00133 &shProg->Varying->Parameters[j]; 00134 if (var->Size != v->Size) { 00135 link_error(shProg, "mismatched varying variable types"); 00136 return GL_FALSE; 00137 } 00138 if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_CENTROID)) { 00139 char msg[100]; 00140 _mesa_snprintf(msg, sizeof(msg), 00141 "centroid modifier mismatch for '%s'", var->Name); 00142 link_error(shProg, msg); 00143 return GL_FALSE; 00144 } 00145 if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_INVARIANT)) { 00146 char msg[100]; 00147 _mesa_snprintf(msg, sizeof(msg), 00148 "invariant modifier mismatch for '%s'", var->Name); 00149 link_error(shProg, msg); 00150 return GL_FALSE; 00151 } 00152 } 00153 else { 00154 /* not already in linked list */ 00155 j = _mesa_add_varying(shProg->Varying, var->Name, var->Size, 00156 var->Flags); 00157 } 00158 00159 /* Map varying[i] to varying[j]. 00160 * Plus, set prog->Input/OutputFlags[] as described above. 00161 * Note: the loop here takes care of arrays or large (sz>4) vars. 00162 */ 00163 { 00164 GLint sz = var->Size; 00165 while (sz > 0) { 00166 inOutFlags[firstVarying + j] = var->Flags; 00167 /*printf("Link varying from %d to %d\n", i, j);*/ 00168 map[i++] = j++; 00169 sz -= 4; 00170 } 00171 i--; /* go back one */ 00172 } 00173 } 00174 00175 00176 /* OK, now scan the program/shader instructions looking for varying vars, 00177 * replacing the old index with the new index. 00178 */ 00179 for (i = 0; i < prog->NumInstructions; i++) { 00180 struct prog_instruction *inst = prog->Instructions + i; 00181 GLuint j; 00182 00183 if (inst->DstReg.File == PROGRAM_VARYING) { 00184 inst->DstReg.File = newFile; 00185 inst->DstReg.Index = map[ inst->DstReg.Index ] + firstVarying; 00186 } 00187 00188 for (j = 0; j < 3; j++) { 00189 if (inst->SrcReg[j].File == PROGRAM_VARYING) { 00190 inst->SrcReg[j].File = newFile; 00191 inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ] + firstVarying; 00192 } 00193 } 00194 } 00195 00196 free(map); 00197 00198 /* these will get recomputed before linking is completed */ 00199 prog->InputsRead = 0x0; 00200 prog->OutputsWritten = 0x0; 00201 00202 return GL_TRUE; 00203 } 00204 00205 00224 static GLboolean 00225 link_uniform_vars(GLcontext *ctx, 00226 struct gl_shader_program *shProg, 00227 struct gl_program *prog, 00228 GLuint *numSamplers) 00229 { 00230 GLuint samplerMap[200]; /* max number of samplers declared, not used */ 00231 GLuint i; 00232 00233 for (i = 0; i < prog->Parameters->NumParameters; i++) { 00234 const struct gl_program_parameter *p = prog->Parameters->Parameters + i; 00235 00236 /* 00237 * XXX FIX NEEDED HERE 00238 * We should also be adding a uniform if p->Type == PROGRAM_STATE_VAR. 00239 * For example, modelview matrix, light pos, etc. 00240 * Also, we need to update the state-var name-generator code to 00241 * generate GLSL-style names, like "gl_LightSource[0].position". 00242 * Furthermore, we'll need to fix the state-var's size/datatype info. 00243 */ 00244 00245 if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) 00246 && p->Used) { 00247 /* add this uniform, indexing into the target's Parameters list */ 00248 struct gl_uniform *uniform = 00249 _mesa_append_uniform(shProg->Uniforms, p->Name, prog->Target, i); 00250 if (uniform) 00251 uniform->Initialized = p->Initialized; 00252 } 00253 00254 /* The samplerMap[] table we build here is used to remap/re-index 00255 * sampler references by TEX instructions. 00256 */ 00257 if (p->Type == PROGRAM_SAMPLER && p->Used) { 00258 /* Allocate a new sampler index */ 00259 GLuint oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0]; 00260 GLuint newSampNum = *numSamplers; 00261 if (newSampNum >= ctx->Const.MaxTextureImageUnits) { 00262 char s[100]; 00263 _mesa_sprintf(s, "Too many texture samplers (%u, max is %u)", 00264 newSampNum, ctx->Const.MaxTextureImageUnits); 00265 link_error(shProg, s); 00266 return GL_FALSE; 00267 } 00268 /* save old->new mapping in the table */ 00269 if (oldSampNum < Elements(samplerMap)) 00270 samplerMap[oldSampNum] = newSampNum; 00271 /* update parameter's sampler index */ 00272 prog->Parameters->ParameterValues[i][0] = (GLfloat) newSampNum; 00273 (*numSamplers)++; 00274 } 00275 } 00276 00277 /* OK, now scan the program/shader instructions looking for texture 00278 * instructions using sampler vars. Replace old sampler indexes with 00279 * new ones. 00280 */ 00281 prog->SamplersUsed = 0x0; 00282 for (i = 0; i < prog->NumInstructions; i++) { 00283 struct prog_instruction *inst = prog->Instructions + i; 00284 if (_mesa_is_tex_instruction(inst->Opcode)) { 00285 const GLint oldSampNum = inst->TexSrcUnit; 00286 00287 #if 0 00288 printf("====== remap sampler from %d to %d\n", 00289 inst->TexSrcUnit, samplerMap[ inst->TexSrcUnit ]); 00290 #endif 00291 00292 /* here, texUnit is really samplerUnit */ 00293 if (oldSampNum < Elements(samplerMap)) { 00294 const GLuint newSampNum = samplerMap[oldSampNum]; 00295 inst->TexSrcUnit = newSampNum; 00296 prog->SamplerTargets[newSampNum] = inst->TexSrcTarget; 00297 prog->SamplersUsed |= (1 << newSampNum); 00298 } 00299 } 00300 } 00301 00302 return GL_TRUE; 00303 } 00304 00305 00314 static GLboolean 00315 _slang_resolve_attributes(struct gl_shader_program *shProg, 00316 const struct gl_program *origProg, 00317 struct gl_program *linkedProg) 00318 { 00319 GLint attribMap[MAX_VERTEX_ATTRIBS]; 00320 GLuint i, j; 00321 GLbitfield usedAttributes; /* generics only, not legacy attributes */ 00322 00323 assert(origProg != linkedProg); 00324 assert(origProg->Target == GL_VERTEX_PROGRAM_ARB); 00325 assert(linkedProg->Target == GL_VERTEX_PROGRAM_ARB); 00326 00327 if (!shProg->Attributes) 00328 shProg->Attributes = _mesa_new_parameter_list(); 00329 00330 if (linkedProg->Attributes) { 00331 _mesa_free_parameter_list(linkedProg->Attributes); 00332 } 00333 linkedProg->Attributes = _mesa_new_parameter_list(); 00334 00335 00336 /* Build a bitmask indicating which attribute indexes have been 00337 * explicitly bound by the user with glBindAttributeLocation(). 00338 */ 00339 usedAttributes = 0x0; 00340 for (i = 0; i < shProg->Attributes->NumParameters; i++) { 00341 GLint attr = shProg->Attributes->Parameters[i].StateIndexes[0]; 00342 usedAttributes |= (1 << attr); 00343 } 00344 00345 /* If gl_Vertex is used, that actually counts against the limit 00346 * on generic vertex attributes. This avoids the ambiguity of 00347 * whether glVertexAttrib4fv(0, v) sets legacy attribute 0 (vert pos) 00348 * or generic attribute[0]. If gl_Vertex is used, we want the former. 00349 */ 00350 if (origProg->InputsRead & VERT_BIT_POS) { 00351 usedAttributes |= 0x1; 00352 } 00353 00354 /* initialize the generic attribute map entries to -1 */ 00355 for (i = 0; i < MAX_VERTEX_ATTRIBS; i++) { 00356 attribMap[i] = -1; 00357 } 00358 00359 /* 00360 * Scan program for generic attribute references 00361 */ 00362 for (i = 0; i < linkedProg->NumInstructions; i++) { 00363 struct prog_instruction *inst = linkedProg->Instructions + i; 00364 for (j = 0; j < 3; j++) { 00365 if (inst->SrcReg[j].File == PROGRAM_INPUT && 00366 inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) { 00367 /* 00368 * OK, we've found a generic vertex attribute reference. 00369 */ 00370 const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0; 00371 00372 GLint attr = attribMap[k]; 00373 00374 if (attr < 0) { 00375 /* Need to figure out attribute mapping now. 00376 */ 00377 const char *name = origProg->Attributes->Parameters[k].Name; 00378 const GLint size = origProg->Attributes->Parameters[k].Size; 00379 const GLenum type =origProg->Attributes->Parameters[k].DataType; 00380 GLint index; 00381 00382 /* See if there's a user-defined attribute binding for 00383 * this name. 00384 */ 00385 index = _mesa_lookup_parameter_index(shProg->Attributes, 00386 -1, name); 00387 if (index >= 0) { 00388 /* Found a user-defined binding */ 00389 attr = shProg->Attributes->Parameters[index].StateIndexes[0]; 00390 } 00391 else { 00392 /* No user-defined binding, choose our own attribute number. 00393 * Start at 1 since generic attribute 0 always aliases 00394 * glVertex/position. 00395 */ 00396 for (attr = 0; attr < MAX_VERTEX_ATTRIBS; attr++) { 00397 if (((1 << attr) & usedAttributes) == 0) 00398 break; 00399 } 00400 if (attr == MAX_VERTEX_ATTRIBS) { 00401 link_error(shProg, "Too many vertex attributes"); 00402 return GL_FALSE; 00403 } 00404 00405 /* mark this attribute as used */ 00406 usedAttributes |= (1 << attr); 00407 } 00408 00409 attribMap[k] = attr; 00410 00411 /* Save the final name->attrib binding so it can be queried 00412 * with glGetAttributeLocation(). 00413 */ 00414 _mesa_add_attribute(linkedProg->Attributes, name, 00415 size, type, attr); 00416 } 00417 00418 assert(attr >= 0); 00419 00420 /* update the instruction's src reg */ 00421 inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr; 00422 } 00423 } 00424 } 00425 00426 return GL_TRUE; 00427 } 00428 00429 00435 static void 00436 _slang_count_temporaries(struct gl_program *prog) 00437 { 00438 GLuint i, j; 00439 GLint maxIndex = -1; 00440 00441 for (i = 0; i < prog->NumInstructions; i++) { 00442 const struct prog_instruction *inst = prog->Instructions + i; 00443 const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); 00444 for (j = 0; j < numSrc; j++) { 00445 if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) { 00446 if (maxIndex < inst->SrcReg[j].Index) 00447 maxIndex = inst->SrcReg[j].Index; 00448 } 00449 if (inst->DstReg.File == PROGRAM_TEMPORARY) { 00450 if (maxIndex < (GLint) inst->DstReg.Index) 00451 maxIndex = inst->DstReg.Index; 00452 } 00453 } 00454 } 00455 00456 prog->NumTemporaries = (GLuint) (maxIndex + 1); 00457 } 00458 00459 00464 static void 00465 _slang_update_inputs_outputs(struct gl_program *prog) 00466 { 00467 GLuint i, j; 00468 GLuint maxAddrReg = 0; 00469 00470 prog->InputsRead = 0x0; 00471 prog->OutputsWritten = 0x0; 00472 00473 for (i = 0; i < prog->NumInstructions; i++) { 00474 const struct prog_instruction *inst = prog->Instructions + i; 00475 const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); 00476 for (j = 0; j < numSrc; j++) { 00477 if (inst->SrcReg[j].File == PROGRAM_INPUT) { 00478 prog->InputsRead |= 1 << inst->SrcReg[j].Index; 00479 if (prog->Target == GL_FRAGMENT_PROGRAM_ARB && 00480 inst->SrcReg[j].Index == FRAG_ATTRIB_FOGC) { 00481 /* The fragment shader FOGC input is used for fog, 00482 * front-facing and sprite/point coord. 00483 */ 00484 struct gl_fragment_program *fp = fragment_program(prog); 00485 const GLint swz = GET_SWZ(inst->SrcReg[j].Swizzle, 0); 00486 if (swz == SWIZZLE_X) 00487 fp->UsesFogFragCoord = GL_TRUE; 00488 else if (swz == SWIZZLE_Y) 00489 fp->UsesFrontFacing = GL_TRUE; 00490 else if (swz == SWIZZLE_Z || swz == SWIZZLE_W) 00491 fp->UsesPointCoord = GL_TRUE; 00492 } 00493 } 00494 else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) { 00495 maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1)); 00496 } 00497 } 00498 00499 if (inst->DstReg.File == PROGRAM_OUTPUT) { 00500 prog->OutputsWritten |= 1 << inst->DstReg.Index; 00501 if (inst->DstReg.RelAddr) { 00502 /* If the output attribute is indexed with relative addressing 00503 * we know that it must be a varying or texcoord such as 00504 * gl_TexCoord[i] = v; In this case, mark all the texcoords 00505 * or varying outputs as being written. It's not an error if 00506 * a vertex shader writes varying vars that aren't used by the 00507 * fragment shader. But it is an error for a fragment shader 00508 * to use varyings that are not written by the vertex shader. 00509 */ 00510 if (prog->Target == GL_VERTEX_PROGRAM_ARB) { 00511 if (inst->DstReg.Index == VERT_RESULT_TEX0) { 00512 /* mark all texcoord outputs as written */ 00513 const GLbitfield mask = 00514 ((1 << MAX_TEXTURE_COORD_UNITS) - 1) << VERT_RESULT_TEX0; 00515 prog->OutputsWritten |= mask; 00516 } 00517 else if (inst->DstReg.Index == VERT_RESULT_VAR0) { 00518 /* mark all generic varying outputs as written */ 00519 const GLbitfield mask = 00520 ((1 << MAX_VARYING) - 1) << VERT_RESULT_VAR0; 00521 prog->OutputsWritten |= mask; 00522 } 00523 } 00524 } 00525 } 00526 else if (inst->DstReg.File == PROGRAM_ADDRESS) { 00527 maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1); 00528 } 00529 } 00530 00531 prog->NumAddressRegs = maxAddrReg; 00532 } 00533 00534 00546 void 00547 _slang_link(GLcontext *ctx, 00548 GLhandleARB programObj, 00549 struct gl_shader_program *shProg) 00550 { 00551 const struct gl_vertex_program *vertProg; 00552 const struct gl_fragment_program *fragProg; 00553 GLuint numSamplers = 0; 00554 GLuint i; 00555 00556 _mesa_clear_shader_program_data(ctx, shProg); 00557 00558 /* check that all programs compiled successfully */ 00559 for (i = 0; i < shProg->NumShaders; i++) { 00560 if (!shProg->Shaders[i]->CompileStatus) { 00561 link_error(shProg, "linking with uncompiled shader\n"); 00562 return; 00563 } 00564 } 00565 00566 shProg->Uniforms = _mesa_new_uniform_list(); 00567 shProg->Varying = _mesa_new_parameter_list(); 00568 00572 vertProg = NULL; 00573 fragProg = NULL; 00574 for (i = 0; i < shProg->NumShaders; i++) { 00575 struct gl_shader *shader = shProg->Shaders[i]; 00576 if (shader->Type == GL_VERTEX_SHADER) { 00577 if (shader->Main) 00578 vertProg = vertex_program(shader->Program); 00579 } 00580 else if (shader->Type == GL_FRAGMENT_SHADER) { 00581 if (shader->Main) 00582 fragProg = fragment_program(shader->Program); 00583 } 00584 else { 00585 _mesa_problem(ctx, "unexpected shader target in slang_link()"); 00586 } 00587 } 00588 00589 #if FEATURE_es2_glsl 00590 /* must have both a vertex and fragment program for ES2 */ 00591 if (!vertProg) { 00592 link_error(shProg, "missing vertex shader\n"); 00593 return; 00594 } 00595 if (!fragProg) { 00596 link_error(shProg, "missing fragment shader\n"); 00597 return; 00598 } 00599 #endif 00600 00601 /* 00602 * Make copies of the vertex/fragment programs now since we'll be 00603 * changing src/dst registers after merging the uniforms and varying vars. 00604 */ 00605 _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); 00606 if (vertProg) { 00607 struct gl_vertex_program *linked_vprog = 00608 vertex_program(_mesa_clone_program(ctx, &vertProg->Base)); 00609 shProg->VertexProgram = linked_vprog; /* refcount OK */ 00610 ASSERT(shProg->VertexProgram->Base.RefCount == 1); 00611 } 00612 00613 _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); 00614 if (fragProg) { 00615 struct gl_fragment_program *linked_fprog = 00616 fragment_program(_mesa_clone_program(ctx, &fragProg->Base)); 00617 shProg->FragmentProgram = linked_fprog; /* refcount OK */ 00618 ASSERT(shProg->FragmentProgram->Base.RefCount == 1); 00619 } 00620 00621 /* link varying vars */ 00622 if (shProg->VertexProgram) { 00623 if (!link_varying_vars(shProg, &shProg->VertexProgram->Base)) 00624 return; 00625 } 00626 if (shProg->FragmentProgram) { 00627 if (!link_varying_vars(shProg, &shProg->FragmentProgram->Base)) 00628 return; 00629 } 00630 00631 /* link uniform vars */ 00632 if (shProg->VertexProgram) { 00633 if (!link_uniform_vars(ctx, shProg, &shProg->VertexProgram->Base, 00634 &numSamplers)) { 00635 return; 00636 } 00637 } 00638 if (shProg->FragmentProgram) { 00639 if (!link_uniform_vars(ctx, shProg, &shProg->FragmentProgram->Base, 00640 &numSamplers)) { 00641 return; 00642 } 00643 } 00644 00645 /*_mesa_print_uniforms(shProg->Uniforms);*/ 00646 00647 if (shProg->VertexProgram) { 00648 if (!_slang_resolve_attributes(shProg, &vertProg->Base, 00649 &shProg->VertexProgram->Base)) { 00650 return; 00651 } 00652 } 00653 00654 if (shProg->VertexProgram) { 00655 _slang_update_inputs_outputs(&shProg->VertexProgram->Base); 00656 _slang_count_temporaries(&shProg->VertexProgram->Base); 00657 if (!(shProg->VertexProgram->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) { 00658 /* the vertex program did not compute a vertex position */ 00659 link_error(shProg, 00660 "gl_Position was not written by vertex shader\n"); 00661 return; 00662 } 00663 } 00664 if (shProg->FragmentProgram) { 00665 _slang_count_temporaries(&shProg->FragmentProgram->Base); 00666 _slang_update_inputs_outputs(&shProg->FragmentProgram->Base); 00667 } 00668 00669 /* Check that all the varying vars needed by the fragment shader are 00670 * actually produced by the vertex shader. 00671 */ 00672 if (shProg->FragmentProgram) { 00673 const GLbitfield varyingRead 00674 = shProg->FragmentProgram->Base.InputsRead >> FRAG_ATTRIB_VAR0; 00675 const GLbitfield varyingWritten = shProg->VertexProgram ? 00676 shProg->VertexProgram->Base.OutputsWritten >> VERT_RESULT_VAR0 : 0x0; 00677 if ((varyingRead & varyingWritten) != varyingRead) { 00678 link_error(shProg, 00679 "Fragment program using varying vars not written by vertex shader\n"); 00680 return; 00681 } 00682 } 00683 00684 /* check that gl_FragColor and gl_FragData are not both written to */ 00685 if (shProg->FragmentProgram) { 00686 GLbitfield outputsWritten = shProg->FragmentProgram->Base.OutputsWritten; 00687 if ((outputsWritten & ((1 << FRAG_RESULT_COLR))) && 00688 (outputsWritten >= (1 << FRAG_RESULT_DATA0))) { 00689 link_error(shProg, "Fragment program cannot write both gl_FragColor" 00690 " and gl_FragData[].\n"); 00691 return; 00692 } 00693 } 00694 00695 00696 if (fragProg && shProg->FragmentProgram) { 00697 /* Compute initial program's TexturesUsed info */ 00698 _mesa_update_shader_textures_used(&shProg->FragmentProgram->Base); 00699 00700 /* notify driver that a new fragment program has been compiled/linked */ 00701 ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, 00702 &shProg->FragmentProgram->Base); 00703 if (MESA_VERBOSE & VERBOSE_GLSL_DUMP) { 00704 printf("Mesa original fragment program:\n"); 00705 _mesa_print_program(&fragProg->Base); 00706 _mesa_print_program_parameters(ctx, &fragProg->Base); 00707 00708 printf("Mesa post-link fragment program:\n"); 00709 _mesa_print_program(&shProg->FragmentProgram->Base); 00710 _mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base); 00711 } 00712 } 00713 00714 if (vertProg && shProg->VertexProgram) { 00715 /* Compute initial program's TexturesUsed info */ 00716 _mesa_update_shader_textures_used(&shProg->VertexProgram->Base); 00717 00718 /* notify driver that a new vertex program has been compiled/linked */ 00719 ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, 00720 &shProg->VertexProgram->Base); 00721 if (MESA_VERBOSE & VERBOSE_GLSL_DUMP) { 00722 printf("Mesa original vertex program:\n"); 00723 _mesa_print_program(&vertProg->Base); 00724 _mesa_print_program_parameters(ctx, &vertProg->Base); 00725 00726 printf("Mesa post-link vertex program:\n"); 00727 _mesa_print_program(&shProg->VertexProgram->Base); 00728 _mesa_print_program_parameters(ctx, &shProg->VertexProgram->Base); 00729 } 00730 } 00731 00732 if (MESA_VERBOSE & VERBOSE_GLSL_DUMP) { 00733 printf("Varying vars:\n"); 00734 _mesa_print_parameter_list(shProg->Varying); 00735 } 00736 00737 shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram); 00738 } 00739 Generated on Sat May 26 2012 04:19:27 for ReactOS by
1.7.6.1
|