Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenarbprogram.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.0 00004 * 00005 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00032 #include "main/glheader.h" 00033 #include "main/context.h" 00034 #include "main/hash.h" 00035 #include "main/imports.h" 00036 #include "main/macros.h" 00037 #include "main/mtypes.h" 00038 #include "arbprogram.h" 00039 #include "arbprogparse.h" 00040 #include "program.h" 00041 00042 00043 00052 static GLboolean 00053 compatible_program_targets(GLenum t1, GLenum t2) 00054 { 00055 if (t1 == t2) 00056 return GL_TRUE; 00057 if (t1 == GL_FRAGMENT_PROGRAM_ARB && t2 == GL_FRAGMENT_PROGRAM_NV) 00058 return GL_TRUE; 00059 if (t1 == GL_FRAGMENT_PROGRAM_NV && t2 == GL_FRAGMENT_PROGRAM_ARB) 00060 return GL_TRUE; 00061 return GL_FALSE; 00062 } 00063 00064 00070 void GLAPIENTRY 00071 _mesa_BindProgram(GLenum target, GLuint id) 00072 { 00073 struct gl_program *curProg, *newProg; 00074 GET_CURRENT_CONTEXT(ctx); 00075 ASSERT_OUTSIDE_BEGIN_END(ctx); 00076 00077 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 00078 00079 /* Error-check target and get curProg */ 00080 if ((target == GL_VERTEX_PROGRAM_ARB) && /* == GL_VERTEX_PROGRAM_NV */ 00081 (ctx->Extensions.NV_vertex_program || 00082 ctx->Extensions.ARB_vertex_program)) { 00083 curProg = &ctx->VertexProgram.Current->Base; 00084 } 00085 else if ((target == GL_FRAGMENT_PROGRAM_NV 00086 && ctx->Extensions.NV_fragment_program) || 00087 (target == GL_FRAGMENT_PROGRAM_ARB 00088 && ctx->Extensions.ARB_fragment_program)) { 00089 curProg = &ctx->FragmentProgram.Current->Base; 00090 } 00091 else { 00092 _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV/ARB(target)"); 00093 return; 00094 } 00095 00096 /* 00097 * Get pointer to new program to bind. 00098 * NOTE: binding to a non-existant program is not an error. 00099 * That's supposed to be caught in glBegin. 00100 */ 00101 if (id == 0) { 00102 /* Bind a default program */ 00103 newProg = NULL; 00104 if (target == GL_VERTEX_PROGRAM_ARB) /* == GL_VERTEX_PROGRAM_NV */ 00105 newProg = &ctx->Shared->DefaultVertexProgram->Base; 00106 else 00107 newProg = &ctx->Shared->DefaultFragmentProgram->Base; 00108 } 00109 else { 00110 /* Bind a user program */ 00111 newProg = _mesa_lookup_program(ctx, id); 00112 if (!newProg || newProg == &_mesa_DummyProgram) { 00113 /* allocate a new program now */ 00114 newProg = ctx->Driver.NewProgram(ctx, target, id); 00115 if (!newProg) { 00116 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV/ARB"); 00117 return; 00118 } 00119 _mesa_HashInsert(ctx->Shared->Programs, id, newProg); 00120 } 00121 else if (!compatible_program_targets(newProg->Target, target)) { 00122 _mesa_error(ctx, GL_INVALID_OPERATION, 00123 "glBindProgramNV/ARB(target mismatch)"); 00124 return; 00125 } 00126 } 00127 00130 if (curProg->Id == id) { 00131 /* binding same program - no change */ 00132 return; 00133 } 00134 00135 /* bind newProg */ 00136 if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */ 00137 _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, 00138 (struct gl_vertex_program *) newProg); 00139 } 00140 else if (target == GL_FRAGMENT_PROGRAM_NV || 00141 target == GL_FRAGMENT_PROGRAM_ARB) { 00142 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, 00143 (struct gl_fragment_program *) newProg); 00144 } 00145 00146 /* Never null pointers */ 00147 ASSERT(ctx->VertexProgram.Current); 00148 ASSERT(ctx->FragmentProgram.Current); 00149 00150 if (ctx->Driver.BindProgram) 00151 ctx->Driver.BindProgram(ctx, target, newProg); 00152 } 00153 00154 00160 void GLAPIENTRY 00161 _mesa_DeletePrograms(GLsizei n, const GLuint *ids) 00162 { 00163 GLint i; 00164 GET_CURRENT_CONTEXT(ctx); 00165 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 00166 00167 if (n < 0) { 00168 _mesa_error( ctx, GL_INVALID_VALUE, "glDeleteProgramsNV" ); 00169 return; 00170 } 00171 00172 for (i = 0; i < n; i++) { 00173 if (ids[i] != 0) { 00174 struct gl_program *prog = _mesa_lookup_program(ctx, ids[i]); 00175 if (prog == &_mesa_DummyProgram) { 00176 _mesa_HashRemove(ctx->Shared->Programs, ids[i]); 00177 } 00178 else if (prog) { 00179 /* Unbind program if necessary */ 00180 if (prog->Target == GL_VERTEX_PROGRAM_ARB || /* == GL_VERTEX_PROGRAM_NV */ 00181 prog->Target == GL_VERTEX_STATE_PROGRAM_NV) { 00182 if (ctx->VertexProgram.Current && 00183 ctx->VertexProgram.Current->Base.Id == ids[i]) { 00184 /* unbind this currently bound program */ 00185 _mesa_BindProgram(prog->Target, 0); 00186 } 00187 } 00188 else if (prog->Target == GL_FRAGMENT_PROGRAM_NV || 00189 prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 00190 if (ctx->FragmentProgram.Current && 00191 ctx->FragmentProgram.Current->Base.Id == ids[i]) { 00192 /* unbind this currently bound program */ 00193 _mesa_BindProgram(prog->Target, 0); 00194 } 00195 } 00196 else { 00197 _mesa_problem(ctx, "bad target in glDeleteProgramsNV"); 00198 return; 00199 } 00200 /* The ID is immediately available for re-use now */ 00201 _mesa_HashRemove(ctx->Shared->Programs, ids[i]); 00202 _mesa_reference_program(ctx, &prog, NULL); 00203 } 00204 } 00205 } 00206 } 00207 00208 00214 void GLAPIENTRY 00215 _mesa_GenPrograms(GLsizei n, GLuint *ids) 00216 { 00217 GLuint first; 00218 GLuint i; 00219 GET_CURRENT_CONTEXT(ctx); 00220 ASSERT_OUTSIDE_BEGIN_END(ctx); 00221 00222 if (n < 0) { 00223 _mesa_error(ctx, GL_INVALID_VALUE, "glGenPrograms"); 00224 return; 00225 } 00226 00227 if (!ids) 00228 return; 00229 00230 first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, n); 00231 00232 /* Insert pointer to dummy program as placeholder */ 00233 for (i = 0; i < (GLuint) n; i++) { 00234 _mesa_HashInsert(ctx->Shared->Programs, first + i, &_mesa_DummyProgram); 00235 } 00236 00237 /* Return the program names */ 00238 for (i = 0; i < (GLuint) n; i++) { 00239 ids[i] = first + i; 00240 } 00241 } 00242 00243 00244 void GLAPIENTRY 00245 _mesa_EnableVertexAttribArrayARB(GLuint index) 00246 { 00247 GET_CURRENT_CONTEXT(ctx); 00248 ASSERT_OUTSIDE_BEGIN_END(ctx); 00249 00250 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 00251 _mesa_error(ctx, GL_INVALID_VALUE, 00252 "glEnableVertexAttribArrayARB(index)"); 00253 return; 00254 } 00255 00256 FLUSH_VERTICES(ctx, _NEW_ARRAY); 00257 ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_TRUE; 00258 ctx->Array.ArrayObj->_Enabled |= _NEW_ARRAY_ATTRIB(index); 00259 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index); 00260 } 00261 00262 00263 void GLAPIENTRY 00264 _mesa_DisableVertexAttribArrayARB(GLuint index) 00265 { 00266 GET_CURRENT_CONTEXT(ctx); 00267 ASSERT_OUTSIDE_BEGIN_END(ctx); 00268 00269 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 00270 _mesa_error(ctx, GL_INVALID_VALUE, 00271 "glEnableVertexAttribArrayARB(index)"); 00272 return; 00273 } 00274 00275 FLUSH_VERTICES(ctx, _NEW_ARRAY); 00276 ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_FALSE; 00277 ctx->Array.ArrayObj->_Enabled &= ~_NEW_ARRAY_ATTRIB(index); 00278 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index); 00279 } 00280 00281 00282 void GLAPIENTRY 00283 _mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params) 00284 { 00285 GLfloat fparams[4]; 00286 GET_CURRENT_CONTEXT(ctx); 00287 ASSERT_OUTSIDE_BEGIN_END(ctx); 00288 00289 _mesa_GetVertexAttribfvARB(index, pname, fparams); 00290 if (ctx->ErrorValue == GL_NO_ERROR) { 00291 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 00292 COPY_4V(params, fparams); 00293 } 00294 else { 00295 params[0] = fparams[0]; 00296 } 00297 } 00298 } 00299 00300 00301 void GLAPIENTRY 00302 _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) 00303 { 00304 GET_CURRENT_CONTEXT(ctx); 00305 ASSERT_OUTSIDE_BEGIN_END(ctx); 00306 00307 if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) { 00308 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)"); 00309 return; 00310 } 00311 00312 switch (pname) { 00313 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: 00314 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Enabled; 00315 break; 00316 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: 00317 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Size; 00318 break; 00319 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: 00320 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Stride; 00321 break; 00322 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: 00323 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Type; 00324 break; 00325 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: 00326 params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Normalized; 00327 break; 00328 case GL_CURRENT_VERTEX_ATTRIB_ARB: 00329 if (index == 0) { 00330 _mesa_error(ctx, GL_INVALID_OPERATION, 00331 "glGetVertexAttribfvARB(index==0)"); 00332 return; 00333 } 00334 FLUSH_CURRENT(ctx, 0); 00335 COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]); 00336 break; 00337 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: 00338 if (!ctx->Extensions.ARB_vertex_buffer_object) { 00339 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)"); 00340 return; 00341 } 00342 params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].BufferObj->Name; 00343 break; 00344 default: 00345 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)"); 00346 return; 00347 } 00348 } 00349 00350 00351 void GLAPIENTRY 00352 _mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params) 00353 { 00354 GLfloat fparams[4]; 00355 GET_CURRENT_CONTEXT(ctx); 00356 ASSERT_OUTSIDE_BEGIN_END(ctx); 00357 00358 _mesa_GetVertexAttribfvARB(index, pname, fparams); 00359 if (ctx->ErrorValue == GL_NO_ERROR) { 00360 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 00361 COPY_4V_CAST(params, fparams, GLint); /* float to int */ 00362 } 00363 else { 00364 params[0] = (GLint) fparams[0]; 00365 } 00366 } 00367 } 00368 00369 00370 void GLAPIENTRY 00371 _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer) 00372 { 00373 GET_CURRENT_CONTEXT(ctx); 00374 ASSERT_OUTSIDE_BEGIN_END(ctx); 00375 00376 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 00377 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)"); 00378 return; 00379 } 00380 00381 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) { 00382 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)"); 00383 return; 00384 } 00385 00386 *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr; 00387 } 00388 00389 00397 GLboolean GLAPIENTRY 00398 _mesa_IsProgramARB(GLuint id) 00399 { 00400 struct gl_program *prog = NULL; 00401 GET_CURRENT_CONTEXT(ctx); 00402 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 00403 00404 if (id == 0) 00405 return GL_FALSE; 00406 00407 prog = _mesa_lookup_program(ctx, id); 00408 if (prog && (prog != &_mesa_DummyProgram)) 00409 return GL_TRUE; 00410 else 00411 return GL_FALSE; 00412 } 00413 00414 00415 void GLAPIENTRY 00416 _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, 00417 const GLvoid *string) 00418 { 00419 GET_CURRENT_CONTEXT(ctx); 00420 ASSERT_OUTSIDE_BEGIN_END(ctx); 00421 00422 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 00423 00424 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) { 00425 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)"); 00426 return; 00427 } 00428 00429 if (target == GL_VERTEX_PROGRAM_ARB 00430 && ctx->Extensions.ARB_vertex_program) { 00431 struct gl_vertex_program *prog = ctx->VertexProgram.Current; 00432 _mesa_parse_arb_vertex_program(ctx, target, string, len, prog); 00433 00434 if (ctx->Program.ErrorPos == -1 && ctx->Driver.ProgramStringNotify) 00435 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base ); 00436 } 00437 else if (target == GL_FRAGMENT_PROGRAM_ARB 00438 && ctx->Extensions.ARB_fragment_program) { 00439 struct gl_fragment_program *prog = ctx->FragmentProgram.Current; 00440 _mesa_parse_arb_fragment_program(ctx, target, string, len, prog); 00441 00442 if (ctx->Program.ErrorPos == -1 && ctx->Driver.ProgramStringNotify) 00443 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base ); 00444 } 00445 else { 00446 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)"); 00447 return; 00448 } 00449 } 00450 00451 00458 void GLAPIENTRY 00459 _mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index, 00460 GLdouble x, GLdouble y, GLdouble z, GLdouble w) 00461 { 00462 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, 00463 (GLfloat) z, (GLfloat) w); 00464 } 00465 00466 00473 void GLAPIENTRY 00474 _mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index, 00475 const GLdouble *params) 00476 { 00477 _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) params[0], 00478 (GLfloat) params[1], (GLfloat) params[2], 00479 (GLfloat) params[3]); 00480 } 00481 00482 00489 void GLAPIENTRY 00490 _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, 00491 GLfloat x, GLfloat y, GLfloat z, GLfloat w) 00492 { 00493 GET_CURRENT_CONTEXT(ctx); 00494 ASSERT_OUTSIDE_BEGIN_END(ctx); 00495 00496 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 00497 00498 if (target == GL_FRAGMENT_PROGRAM_ARB 00499 && ctx->Extensions.ARB_fragment_program) { 00500 if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { 00501 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)"); 00502 return; 00503 } 00504 ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w); 00505 } 00506 else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */ 00507 && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) { 00508 if (index >= ctx->Const.VertexProgram.MaxEnvParams) { 00509 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)"); 00510 return; 00511 } 00512 ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w); 00513 } 00514 else { 00515 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)"); 00516 return; 00517 } 00518 } 00519 00526 void GLAPIENTRY 00527 _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index, 00528 const GLfloat *params) 00529 { 00530 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1], 00531 params[2], params[3]); 00532 } 00533 00534 00535 void GLAPIENTRY 00536 _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, 00537 const GLfloat *params) 00538 { 00539 GET_CURRENT_CONTEXT(ctx); 00540 GLint i; 00541 GLfloat * dest; 00542 ASSERT_OUTSIDE_BEGIN_END(ctx); 00543 00544 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 00545 00546 if (count <= 0) { 00547 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(count)"); 00548 } 00549 00550 if (target == GL_FRAGMENT_PROGRAM_ARB 00551 && ctx->Extensions.ARB_fragment_program) { 00552 if ((index + count) > ctx->Const.FragmentProgram.MaxEnvParams) { 00553 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)"); 00554 return; 00555 } 00556 dest = ctx->FragmentProgram.Parameters[index]; 00557 } 00558 else if (target == GL_VERTEX_PROGRAM_ARB 00559 && ctx->Extensions.ARB_vertex_program) { 00560 if ((index + count) > ctx->Const.VertexProgram.MaxEnvParams) { 00561 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)"); 00562 return; 00563 } 00564 dest = ctx->VertexProgram.Parameters[index]; 00565 } 00566 else { 00567 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameters4fv(target)"); 00568 return; 00569 } 00570 00571 for ( i = 0 ; i < count ; i++ ) { 00572 COPY_4V(dest, params); 00573 params += 4; 00574 dest += 4; 00575 } 00576 } 00577 00578 00579 void GLAPIENTRY 00580 _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index, 00581 GLdouble *params) 00582 { 00583 GET_CURRENT_CONTEXT(ctx); 00584 GLfloat fparams[4]; 00585 00586 _mesa_GetProgramEnvParameterfvARB(target, index, fparams); 00587 if (ctx->ErrorValue == GL_NO_ERROR) { 00588 params[0] = fparams[0]; 00589 params[1] = fparams[1]; 00590 params[2] = fparams[2]; 00591 params[3] = fparams[3]; 00592 } 00593 } 00594 00595 00596 void GLAPIENTRY 00597 _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, 00598 GLfloat *params) 00599 { 00600 GET_CURRENT_CONTEXT(ctx); 00601 00602 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 00603 00604 if (!ctx->_CurrentProgram) 00605 ASSERT_OUTSIDE_BEGIN_END(ctx); 00606 00607 if (target == GL_FRAGMENT_PROGRAM_ARB 00608 && ctx->Extensions.ARB_fragment_program) { 00609 if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { 00610 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)"); 00611 return; 00612 } 00613 COPY_4V(params, ctx->FragmentProgram.Parameters[index]); 00614 } 00615 else if (target == GL_VERTEX_PROGRAM_ARB 00616 && ctx->Extensions.ARB_vertex_program) { 00617 if (index >= ctx->Const.VertexProgram.MaxEnvParams) { 00618 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)"); 00619 return; 00620 } 00621 COPY_4V(params, ctx->VertexProgram.Parameters[index]); 00622 } 00623 else { 00624 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)"); 00625 return; 00626 } 00627 } 00628 00629 00633 void GLAPIENTRY 00634 _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index, 00635 GLfloat x, GLfloat y, GLfloat z, GLfloat w) 00636 { 00637 GET_CURRENT_CONTEXT(ctx); 00638 struct gl_program *prog; 00639 ASSERT_OUTSIDE_BEGIN_END(ctx); 00640 00641 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 00642 00643 if ((target == GL_FRAGMENT_PROGRAM_NV 00644 && ctx->Extensions.NV_fragment_program) || 00645 (target == GL_FRAGMENT_PROGRAM_ARB 00646 && ctx->Extensions.ARB_fragment_program)) { 00647 if (index >= ctx->Const.FragmentProgram.MaxLocalParams) { 00648 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB"); 00649 return; 00650 } 00651 prog = &(ctx->FragmentProgram.Current->Base); 00652 } 00653 else if (target == GL_VERTEX_PROGRAM_ARB 00654 && ctx->Extensions.ARB_vertex_program) { 00655 if (index >= ctx->Const.VertexProgram.MaxLocalParams) { 00656 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB"); 00657 return; 00658 } 00659 prog = &(ctx->VertexProgram.Current->Base); 00660 } 00661 else { 00662 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB"); 00663 return; 00664 } 00665 00666 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS); 00667 prog->LocalParams[index][0] = x; 00668 prog->LocalParams[index][1] = y; 00669 prog->LocalParams[index][2] = z; 00670 prog->LocalParams[index][3] = w; 00671 } 00672 00673 00677 void GLAPIENTRY 00678 _mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index, 00679 const GLfloat *params) 00680 { 00681 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1], 00682 params[2], params[3]); 00683 } 00684 00685 00686 void GLAPIENTRY 00687 _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, 00688 const GLfloat *params) 00689 { 00690 GET_CURRENT_CONTEXT(ctx); 00691 struct gl_program *prog; 00692 GLint i; 00693 ASSERT_OUTSIDE_BEGIN_END(ctx); 00694 00695 FLUSH_VERTICES(ctx, _NEW_PROGRAM); 00696 00697 if (count <= 0) { 00698 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fv(count)"); 00699 } 00700 00701 if (target == GL_FRAGMENT_PROGRAM_ARB 00702 && ctx->Extensions.ARB_fragment_program) { 00703 if ((index + count) > ctx->Const.FragmentProgram.MaxLocalParams) { 00704 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)"); 00705 return; 00706 } 00707 prog = &(ctx->FragmentProgram.Current->Base); 00708 } 00709 else if (target == GL_VERTEX_PROGRAM_ARB 00710 && ctx->Extensions.ARB_vertex_program) { 00711 if ((index + count) > ctx->Const.VertexProgram.MaxLocalParams) { 00712 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)"); 00713 return; 00714 } 00715 prog = &(ctx->VertexProgram.Current->Base); 00716 } 00717 else { 00718 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameters4fvEXT(target)"); 00719 return; 00720 } 00721 00722 for (i = 0; i < count; i++) { 00723 ASSERT((index + i) < MAX_PROGRAM_LOCAL_PARAMS); 00724 COPY_4V(prog->LocalParams[index + i], params); 00725 params += 4; 00726 } 00727 } 00728 00729 00733 void GLAPIENTRY 00734 _mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index, 00735 GLdouble x, GLdouble y, 00736 GLdouble z, GLdouble w) 00737 { 00738 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, 00739 (GLfloat) z, (GLfloat) w); 00740 } 00741 00742 00746 void GLAPIENTRY 00747 _mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index, 00748 const GLdouble *params) 00749 { 00750 _mesa_ProgramLocalParameter4fARB(target, index, 00751 (GLfloat) params[0], (GLfloat) params[1], 00752 (GLfloat) params[2], (GLfloat) params[3]); 00753 } 00754 00755 00759 void GLAPIENTRY 00760 _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index, 00761 GLfloat *params) 00762 { 00763 const struct gl_program *prog; 00764 GLuint maxParams; 00765 GET_CURRENT_CONTEXT(ctx); 00766 ASSERT_OUTSIDE_BEGIN_END(ctx); 00767 00768 if (target == GL_VERTEX_PROGRAM_ARB 00769 && ctx->Extensions.ARB_vertex_program) { 00770 prog = &(ctx->VertexProgram.Current->Base); 00771 maxParams = ctx->Const.VertexProgram.MaxLocalParams; 00772 } 00773 else if (target == GL_FRAGMENT_PROGRAM_ARB 00774 && ctx->Extensions.ARB_fragment_program) { 00775 prog = &(ctx->FragmentProgram.Current->Base); 00776 maxParams = ctx->Const.FragmentProgram.MaxLocalParams; 00777 } 00778 else if (target == GL_FRAGMENT_PROGRAM_NV 00779 && ctx->Extensions.NV_fragment_program) { 00780 prog = &(ctx->FragmentProgram.Current->Base); 00781 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS; 00782 } 00783 else { 00784 _mesa_error(ctx, GL_INVALID_ENUM, 00785 "glGetProgramLocalParameterARB(target)"); 00786 return; 00787 } 00788 00789 if (index >= maxParams) { 00790 _mesa_error(ctx, GL_INVALID_VALUE, 00791 "glGetProgramLocalParameterARB(index)"); 00792 return; 00793 } 00794 00795 ASSERT(prog); 00796 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS); 00797 COPY_4V(params, prog->LocalParams[index]); 00798 } 00799 00800 00804 void GLAPIENTRY 00805 _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index, 00806 GLdouble *params) 00807 { 00808 GET_CURRENT_CONTEXT(ctx); 00809 GLfloat floatParams[4]; 00810 ASSIGN_4V(floatParams, 0.0F, 0.0F, 0.0F, 0.0F); 00811 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams); 00812 if (ctx->ErrorValue == GL_NO_ERROR) { 00813 COPY_4V(params, floatParams); 00814 } 00815 } 00816 00817 00818 void GLAPIENTRY 00819 _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params) 00820 { 00821 const struct gl_program_constants *limits; 00822 struct gl_program *prog; 00823 GET_CURRENT_CONTEXT(ctx); 00824 00825 if (!ctx->_CurrentProgram) 00826 ASSERT_OUTSIDE_BEGIN_END(ctx); 00827 00828 if (target == GL_VERTEX_PROGRAM_ARB 00829 && ctx->Extensions.ARB_vertex_program) { 00830 prog = &(ctx->VertexProgram.Current->Base); 00831 limits = &ctx->Const.VertexProgram; 00832 } 00833 else if (target == GL_FRAGMENT_PROGRAM_ARB 00834 && ctx->Extensions.ARB_fragment_program) { 00835 prog = &(ctx->FragmentProgram.Current->Base); 00836 limits = &ctx->Const.FragmentProgram; 00837 } 00838 else { 00839 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); 00840 return; 00841 } 00842 00843 ASSERT(prog); 00844 ASSERT(limits); 00845 00846 /* Queries supported for both vertex and fragment programs */ 00847 switch (pname) { 00848 case GL_PROGRAM_LENGTH_ARB: 00849 *params 00850 = prog->String ? (GLint) _mesa_strlen((char *) prog->String) : 0; 00851 return; 00852 case GL_PROGRAM_FORMAT_ARB: 00853 *params = prog->Format; 00854 return; 00855 case GL_PROGRAM_BINDING_ARB: 00856 *params = prog->Id; 00857 return; 00858 case GL_PROGRAM_INSTRUCTIONS_ARB: 00859 *params = prog->NumInstructions; 00860 return; 00861 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB: 00862 *params = limits->MaxInstructions; 00863 return; 00864 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB: 00865 *params = prog->NumNativeInstructions; 00866 return; 00867 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB: 00868 *params = limits->MaxNativeInstructions; 00869 return; 00870 case GL_PROGRAM_TEMPORARIES_ARB: 00871 *params = prog->NumTemporaries; 00872 return; 00873 case GL_MAX_PROGRAM_TEMPORARIES_ARB: 00874 *params = limits->MaxTemps; 00875 return; 00876 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB: 00877 *params = prog->NumNativeTemporaries; 00878 return; 00879 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB: 00880 *params = limits->MaxNativeTemps; 00881 return; 00882 case GL_PROGRAM_PARAMETERS_ARB: 00883 *params = prog->NumParameters; 00884 return; 00885 case GL_MAX_PROGRAM_PARAMETERS_ARB: 00886 *params = limits->MaxParameters; 00887 return; 00888 case GL_PROGRAM_NATIVE_PARAMETERS_ARB: 00889 *params = prog->NumNativeParameters; 00890 return; 00891 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB: 00892 *params = limits->MaxNativeParameters; 00893 return; 00894 case GL_PROGRAM_ATTRIBS_ARB: 00895 *params = prog->NumAttributes; 00896 return; 00897 case GL_MAX_PROGRAM_ATTRIBS_ARB: 00898 *params = limits->MaxAttribs; 00899 return; 00900 case GL_PROGRAM_NATIVE_ATTRIBS_ARB: 00901 *params = prog->NumNativeAttributes; 00902 return; 00903 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB: 00904 *params = limits->MaxNativeAttribs; 00905 return; 00906 case GL_PROGRAM_ADDRESS_REGISTERS_ARB: 00907 *params = prog->NumAddressRegs; 00908 return; 00909 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB: 00910 *params = limits->MaxAddressRegs; 00911 return; 00912 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB: 00913 *params = prog->NumNativeAddressRegs; 00914 return; 00915 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB: 00916 *params = limits->MaxNativeAddressRegs; 00917 return; 00918 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB: 00919 *params = limits->MaxLocalParams; 00920 return; 00921 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB: 00922 *params = limits->MaxEnvParams; 00923 return; 00924 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB: 00925 /* 00926 * XXX we may not really need a driver callback here. 00927 * If the number of native instructions, registers, etc. used 00928 * are all below the maximums, we could return true. 00929 * The spec says that even if this query returns true, there's 00930 * no guarantee that the program will run in hardware. 00931 */ 00932 if (prog->Id == 0) { 00933 /* default/null program */ 00934 *params = GL_FALSE; 00935 } 00936 else if (ctx->Driver.IsProgramNative) { 00937 /* ask the driver */ 00938 *params = ctx->Driver.IsProgramNative( ctx, target, prog ); 00939 } 00940 else { 00941 /* probably running in software */ 00942 *params = GL_TRUE; 00943 } 00944 return; 00945 default: 00946 /* continue with fragment-program only queries below */ 00947 break; 00948 } 00949 00950 /* 00951 * The following apply to fragment programs only (at this time) 00952 */ 00953 if (target == GL_FRAGMENT_PROGRAM_ARB) { 00954 const struct gl_fragment_program *fp = ctx->FragmentProgram.Current; 00955 switch (pname) { 00956 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB: 00957 *params = fp->Base.NumNativeAluInstructions; 00958 return; 00959 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB: 00960 *params = fp->Base.NumAluInstructions; 00961 return; 00962 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB: 00963 *params = fp->Base.NumTexInstructions; 00964 return; 00965 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB: 00966 *params = fp->Base.NumNativeTexInstructions; 00967 return; 00968 case GL_PROGRAM_TEX_INDIRECTIONS_ARB: 00969 *params = fp->Base.NumTexIndirections; 00970 return; 00971 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB: 00972 *params = fp->Base.NumNativeTexIndirections; 00973 return; 00974 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB: 00975 *params = limits->MaxAluInstructions; 00976 return; 00977 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB: 00978 *params = limits->MaxNativeAluInstructions; 00979 return; 00980 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB: 00981 *params = limits->MaxTexInstructions; 00982 return; 00983 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB: 00984 *params = limits->MaxNativeTexInstructions; 00985 return; 00986 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB: 00987 *params = limits->MaxTexIndirections; 00988 return; 00989 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB: 00990 *params = limits->MaxNativeTexIndirections; 00991 return; 00992 default: 00993 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)"); 00994 return; 00995 } 00996 } 00997 } 00998 00999 01000 void GLAPIENTRY 01001 _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) 01002 { 01003 const struct gl_program *prog; 01004 char *dst = (char *) string; 01005 GET_CURRENT_CONTEXT(ctx); 01006 01007 if (!ctx->_CurrentProgram) 01008 ASSERT_OUTSIDE_BEGIN_END(ctx); 01009 01010 if (target == GL_VERTEX_PROGRAM_ARB) { 01011 prog = &(ctx->VertexProgram.Current->Base); 01012 } 01013 else if (target == GL_FRAGMENT_PROGRAM_ARB) { 01014 prog = &(ctx->FragmentProgram.Current->Base); 01015 } 01016 else { 01017 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)"); 01018 return; 01019 } 01020 01021 ASSERT(prog); 01022 01023 if (pname != GL_PROGRAM_STRING_ARB) { 01024 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)"); 01025 return; 01026 } 01027 01028 if (prog->String) 01029 _mesa_memcpy(dst, prog->String, _mesa_strlen((char *) prog->String)); 01030 else 01031 *dst = '\0'; 01032 } Generated on Thu May 24 2012 04:20:48 for ReactOS by
1.7.6.1
|