📄 nvprogram.c
字号:
/*
* Mesa 3-D graphics library
* Version: 6.1
*
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file nvprogram.c
* NVIDIA vertex/fragment program state management functions.
* \author Brian Paul
*/
/*
* Regarding GL_NV_fragment/vertex_program, GL_NV_vertex_program1_1, etc:
*
* Portions of this software may use or implement intellectual
* property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
* any and all warranties with respect to such intellectual property,
* including any use thereof or modifications thereto.
*/
#include "glheader.h"
#include "context.h"
#include "hash.h"
#include "imports.h"
#include "macros.h"
#include "mtypes.h"
#include "nvfragparse.h"
#include "nvfragprog.h"
#include "nvvertexec.h"
#include "nvvertparse.h"
#include "nvvertprog.h"
#include "nvprogram.h"
#include "program.h"
/**
* Execute a vertex state program.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params)
{
struct vertex_program *vprog;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (target != GL_VERTEX_STATE_PROGRAM_NV) {
_mesa_error(ctx, GL_INVALID_ENUM, "glExecuteProgramNV");
return;
}
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
vprog = (struct vertex_program *)
_mesa_HashLookup(ctx->Shared->Programs, id);
if (!vprog || vprog->Base.Target != GL_VERTEX_STATE_PROGRAM_NV) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glExecuteProgramNV");
return;
}
_mesa_init_vp_per_vertex_registers(ctx);
_mesa_init_vp_per_primitive_registers(ctx);
COPY_4V(ctx->VertexProgram.Inputs[VERT_ATTRIB_POS], params);
_mesa_exec_vertex_program(ctx, vprog);
}
/**
* Determine if a set of programs is resident in hardware.
* \note Not compiled into display lists.
* \note Called from the GL API dispatcher.
*/
GLboolean GLAPIENTRY _mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids,
GLboolean *residences)
{
GLint i, j;
GLboolean allResident = GL_TRUE;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
if (n < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV(n)");
return GL_FALSE;
}
for (i = 0; i < n; i++) {
const struct program *prog;
if (ids[i] == 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV");
return GL_FALSE;
}
prog = (const struct program *)
_mesa_HashLookup(ctx->Shared->Programs, ids[i]);
if (!prog) {
_mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV");
return GL_FALSE;
}
if (prog->Resident) {
if (!allResident)
residences[i] = GL_TRUE;
}
else {
if (allResident) {
allResident = GL_FALSE;
for (j = 0; j < i; j++)
residences[j] = GL_TRUE;
}
residences[i] = GL_FALSE;
}
}
return allResident;
}
/**
* Request that a set of programs be resident in hardware.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids)
{
GLint i;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (n < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(n)");
return;
}
/* just error checking for now */
for (i = 0; i < n; i++) {
struct program *prog;
if (ids[i] == 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(id)");
return;
}
prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, ids[i]);
if (!prog) {
_mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(id)");
return;
}
/* XXX this is really a hardware thing we should hook out */
prog->Resident = GL_TRUE;
}
}
/**
* Get a program parameter register.
* \note Not compiled into display lists.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_GetProgramParameterfvNV(GLenum target, GLuint index,
GLenum pname, GLfloat *params)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (target == GL_VERTEX_PROGRAM_NV) {
if (pname == GL_PROGRAM_PARAMETER_NV) {
if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) {
COPY_4V(params, ctx->VertexProgram.Parameters[index]);
}
else {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetProgramParameterfvNV(index)");
return;
}
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterfvNV(pname)");
return;
}
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterfvNV(target)");
return;
}
}
/**
* Get a program parameter register.
* \note Not compiled into display lists.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_GetProgramParameterdvNV(GLenum target, GLuint index,
GLenum pname, GLdouble *params)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (target == GL_VERTEX_PROGRAM_NV) {
if (pname == GL_PROGRAM_PARAMETER_NV) {
if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) {
COPY_4V(params, ctx->VertexProgram.Parameters[index]);
}
else {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetProgramParameterdvNV(index)");
return;
}
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterdvNV(pname)");
return;
}
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterdvNV(target)");
return;
}
}
/**
* Get a program attribute.
* \note Not compiled into display lists.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params)
{
struct program *prog;
GET_CURRENT_CONTEXT(ctx);
if (!ctx->_CurrentProgram)
ASSERT_OUTSIDE_BEGIN_END(ctx);
prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id);
if (!prog) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramivNV");
return;
}
switch (pname) {
case GL_PROGRAM_TARGET_NV:
*params = prog->Target;
return;
case GL_PROGRAM_LENGTH_NV:
*params = prog->String ?(GLint)_mesa_strlen((char *) prog->String) : 0;
return;
case GL_PROGRAM_RESIDENT_NV:
*params = prog->Resident;
return;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivNV(pname)");
return;
}
}
/**
* Get the program source code.
* \note Not compiled into display lists.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program)
{
struct program *prog;
GET_CURRENT_CONTEXT(ctx);
if (!ctx->_CurrentProgram)
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (pname != GL_PROGRAM_STRING_NV) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringNV(pname)");
return;
}
prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id);
if (!prog) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramStringNV");
return;
}
if (prog->String) {
MEMCPY(program, prog->String, _mesa_strlen((char *) prog->String));
}
else {
program[0] = 0;
}
}
/**
* Get matrix tracking information.
* \note Not compiled into display lists.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_GetTrackMatrixivNV(GLenum target, GLuint address,
GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (target == GL_VERTEX_PROGRAM_NV
&& ctx->Extensions.NV_vertex_program) {
GLuint i;
if ((address & 0x3) || address >= MAX_NV_VERTEX_PROGRAM_PARAMS) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetTrackMatrixivNV(address)");
return;
}
i = address / 4;
switch (pname) {
case GL_TRACK_MATRIX_NV:
params[0] = (GLint) ctx->VertexProgram.TrackMatrix[i];
return;
case GL_TRACK_MATRIX_TRANSFORM_NV:
params[0] = (GLint) ctx->VertexProgram.TrackMatrixTransform[i];
return;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTrackMatrixivNV");
return;
}
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTrackMatrixivNV");
return;
}
}
/**
* Get a vertex (or vertex array) attribute.
* \note Not compiled into display lists.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (index == 0 || index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
return;
}
switch (pname) {
case GL_ATTRIB_ARRAY_SIZE_NV:
params[0] = ctx->Array.VertexAttrib[index].Size;
break;
case GL_ATTRIB_ARRAY_STRIDE_NV:
params[0] = ctx->Array.VertexAttrib[index].Stride;
break;
case GL_ATTRIB_ARRAY_TYPE_NV:
params[0] = ctx->Array.VertexAttrib[index].Type;
break;
case GL_CURRENT_ATTRIB_NV:
FLUSH_CURRENT(ctx, 0);
COPY_4V(params, ctx->Current.Attrib[index]);
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
return;
}
}
/**
* Get a vertex (or vertex array) attribute.
* \note Not compiled into display lists.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (index == 0 || index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
return;
}
switch (pname) {
case GL_ATTRIB_ARRAY_SIZE_NV:
params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Size;
break;
case GL_ATTRIB_ARRAY_STRIDE_NV:
params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Stride;
break;
case GL_ATTRIB_ARRAY_TYPE_NV:
params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Type;
break;
case GL_CURRENT_ATTRIB_NV:
FLUSH_CURRENT(ctx, 0);
COPY_4V(params, ctx->Current.Attrib[index]);
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
return;
}
}
/**
* Get a vertex (or vertex array) attribute.
* \note Not compiled into display lists.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -