these files now live in the shader directory

This commit is contained in:
Brian Paul 2004-03-30 22:52:00 +00:00
parent bcc6a02afc
commit 27eb79c9dc
10 changed files with 0 additions and 5505 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,52 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 5.1
*
* Copyright (C) 1999-2002 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.
*
* Authors:
* Brian Paul
*/
#ifndef NVFRAGPARSE_H
#define NVFRAGPARSE_H
extern void
_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum target,
const GLubyte *str, GLsizei len,
struct fragment_program *program);
extern void
_mesa_print_nv_fragment_program(const struct fragment_program *program);
extern const char *
_mesa_nv_fragment_input_register_name(GLuint i);
extern const char *
_mesa_nv_fragment_output_register_name(GLuint i);
#endif

View file

@ -1,161 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 5.1
*
* Copyright (C) 1999-2003 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.
*/
/* Private fragment program types and constants only used by files
* related to fragment programs.
*
* XXX TO-DO: Rename this file "fragprog.h" since it's not NV-specific.
*/
#ifndef NVFRAGPROG_H
#define NVFRAGPROG_H
#include "config.h"
/* output registers */
#define FRAG_OUTPUT_COLR 0
#define FRAG_OUTPUT_COLH 1
#define FRAG_OUTPUT_DEPR 2
/* condition codes */
#define COND_GT 1 /* greater than zero */
#define COND_EQ 2 /* equal to zero */
#define COND_LT 3 /* less than zero */
#define COND_UN 4 /* unordered (NaN) */
#define COND_GE 5 /* greater then or equal to zero */
#define COND_LE 6 /* less then or equal to zero */
#define COND_NE 7 /* not equal to zero */
#define COND_TR 8 /* always true */
#define COND_FL 9 /* always false */
/* instruction precision */
#define FLOAT32 0x1
#define FLOAT16 0x2
#define FIXED12 0x4
/* Fragment program instruction opcodes */
enum fp_opcode {
FP_OPCODE_ABS = 1000, /* ARB_f_p only */
FP_OPCODE_ADD,
FP_OPCODE_CMP, /* ARB_f_p only */
FP_OPCODE_COS,
FP_OPCODE_DDX, /* NV_f_p only */
FP_OPCODE_DDY, /* NV_f_p only */
FP_OPCODE_DP3,
FP_OPCODE_DP4,
FP_OPCODE_DPH, /* ARB_f_p only */
FP_OPCODE_DST,
FP_OPCODE_EX2,
FP_OPCODE_FLR,
FP_OPCODE_FRC,
FP_OPCODE_KIL,
FP_OPCODE_LG2,
FP_OPCODE_LIT,
FP_OPCODE_LRP,
FP_OPCODE_MAD,
FP_OPCODE_MAX,
FP_OPCODE_MIN,
FP_OPCODE_MOV,
FP_OPCODE_MUL,
FP_OPCODE_PK2H, /* NV_f_p only */
FP_OPCODE_PK2US, /* NV_f_p only */
FP_OPCODE_PK4B, /* NV_f_p only */
FP_OPCODE_PK4UB, /* NV_f_p only */
FP_OPCODE_POW,
FP_OPCODE_RCP,
FP_OPCODE_RFL, /* NV_f_p only */
FP_OPCODE_RSQ,
FP_OPCODE_SCS, /* ARB_f_p only */
FP_OPCODE_SEQ, /* NV_f_p only */
FP_OPCODE_SFL, /* NV_f_p only */
FP_OPCODE_SGE, /* NV_f_p only */
FP_OPCODE_SGT, /* NV_f_p only */
FP_OPCODE_SIN,
FP_OPCODE_SLE, /* NV_f_p only */
FP_OPCODE_SLT,
FP_OPCODE_SNE, /* NV_f_p only */
FP_OPCODE_STR, /* NV_f_p only */
FP_OPCODE_SUB,
FP_OPCODE_SWZ, /* ARB_f_p only */
FP_OPCODE_TEX,
FP_OPCODE_TXB, /* ARB_f_p only */
FP_OPCODE_TXD, /* NV_f_p only */
FP_OPCODE_TXP,
FP_OPCODE_UP2H, /* NV_f_p only */
FP_OPCODE_UP2US, /* NV_f_p only */
FP_OPCODE_UP4B, /* NV_f_p only */
FP_OPCODE_UP4UB, /* NV_f_p only */
FP_OPCODE_XPD, /* ARB_f_p only - cross product */
FP_OPCODE_X2D, /* NV_f_p only - 2d mat mul */
FP_OPCODE_END /* private opcode */
};
/* Instruction source register */
struct fp_src_register
{
enum register_file File;
GLint Index;
GLuint Swizzle[4];
GLboolean NegateBase; /* negate before absolute value? */
GLboolean Abs; /* take absolute value? */
GLboolean NegateAbs; /* negate after absolute value? */
};
/* Instruction destination register */
struct fp_dst_register
{
enum register_file File;
GLint Index;
GLboolean WriteMask[4];
GLuint CondMask;
GLuint CondSwizzle[4];
};
/* Fragment program instruction */
struct fp_instruction
{
enum fp_opcode Opcode;
struct fp_src_register SrcReg[3];
struct fp_dst_register DstReg;
GLboolean Saturate;
GLboolean UpdateCondRegister;
GLubyte Precision; /* FLOAT32, FLOAT16 or FIXED12 */
GLubyte TexSrcUnit; /* texture unit for TEX, TXD, TXP instructions */
GLubyte TexSrcBit; /* TEXTURE_1D,2D,3D,CUBE,RECT_BIT source target */
#if FEATURE_MESA_program_debug
GLint StringPos;
#endif
};
#endif

View file

@ -1,871 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 6.0
*
* 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_registers(ctx);
_mesa_init_tracked_matrices(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;
}
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 ? _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)
{
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);
params[0] = (GLint) ctx->Current.Attrib[index][0];
params[1] = (GLint) ctx->Current.Attrib[index][1];
params[2] = (GLint) ctx->Current.Attrib[index][2];
params[3] = (GLint) ctx->Current.Attrib[index][3];
break;
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
if (!ctx->Extensions.ARB_vertex_buffer_object) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
return;
}
params[0] = ctx->Array.VertexAttrib[index].BufferObj->Name;
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
return;
}
}
/**
* Get a vertex array attribute pointer.
* \note Not compiled into display lists.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerNV(index)");
return;
}
if (pname != GL_ATTRIB_ARRAY_POINTER_NV) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerNV(pname)");
return;
}
*pointer = (GLvoid *) ctx->Array.VertexAttrib[index].Ptr;;
}
/**
* Load/parse/compile a program.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
const GLubyte *program)
{
struct program *prog;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (id == 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(id)");
return;
}
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id);
if (prog && prog->Target != 0 && prog->Target != target) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target)");
return;
}
if ((target == GL_VERTEX_PROGRAM_NV ||
target == GL_VERTEX_STATE_PROGRAM_NV)
&& ctx->Extensions.NV_vertex_program) {
struct vertex_program *vprog = (struct vertex_program *) prog;
if (!vprog) {
vprog = CALLOC_STRUCT(vertex_program);
if (!vprog) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
return;
}
vprog->Base.RefCount = 1;
vprog->Base.Resident = GL_TRUE;
_mesa_HashInsert(ctx->Shared->Programs, id, vprog);
}
_mesa_parse_nv_vertex_program(ctx, target, program, len, vprog);
}
else if (target == GL_FRAGMENT_PROGRAM_NV
&& ctx->Extensions.NV_fragment_program) {
struct fragment_program *fprog = (struct fragment_program *) prog;
if (!fprog) {
fprog = CALLOC_STRUCT(fragment_program);
if (!fprog) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
return;
}
fprog->Base.RefCount = 1;
fprog->Base.Resident = GL_TRUE;
_mesa_HashInsert(ctx->Shared->Programs, id, fprog);
}
_mesa_parse_nv_fragment_program(ctx, target, program, len, fprog);
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glLoadProgramNV(target)");
}
}
/**
* Set a program parameter register.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_ProgramParameter4dNV(GLenum target, GLuint index,
GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
_mesa_ProgramParameter4fNV(target, index,
(GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)w);
}
/**
* Set a program parameter register.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_ProgramParameter4dvNV(GLenum target, GLuint index,
const GLdouble *params)
{
_mesa_ProgramParameter4fNV(target, index,
(GLfloat)params[0], (GLfloat)params[1],
(GLfloat)params[2], (GLfloat)params[3]);
}
/**
* Set a program parameter register.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_ProgramParameter4fNV(GLenum target, GLuint index,
GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) {
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
}
else {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameterNV(index)");
return;
}
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameterNV");
return;
}
}
/**
* Set a program parameter register.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_ProgramParameter4fvNV(GLenum target, GLuint index,
const GLfloat *params)
{
_mesa_ProgramParameter4fNV(target, index,
params[0], params[1], params[2], params[3]);
}
/**
* Set a sequence of program parameter registers.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_ProgramParameters4dvNV(GLenum target, GLuint index,
GLuint num, const GLdouble *params)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
GLuint i;
if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4dvNV");
return;
}
for (i = 0; i < num; i++) {
ctx->VertexProgram.Parameters[index + i][0] = (GLfloat) params[0];
ctx->VertexProgram.Parameters[index + i][1] = (GLfloat) params[1];
ctx->VertexProgram.Parameters[index + i][2] = (GLfloat) params[2];
ctx->VertexProgram.Parameters[index + i][3] = (GLfloat) params[3];
params += 4;
};
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameters4dvNV");
return;
}
}
/**
* Set a sequence of program parameter registers.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_ProgramParameters4fvNV(GLenum target, GLuint index,
GLuint num, const GLfloat *params)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
GLuint i;
if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4fvNV");
return;
}
for (i = 0; i < num; i++) {
COPY_4V(ctx->VertexProgram.Parameters[index + i], params);
params += 4;
};
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameters4fvNV");
return;
}
}
/**
* Setup tracking of matrices into program parameter registers.
* \note Called from the GL API dispatcher.
*/
void GLAPIENTRY
_mesa_TrackMatrixNV(GLenum target, GLuint address,
GLenum matrix, GLenum transform)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
if (address & 0x3) {
/* addr must be multiple of four */
_mesa_error(ctx, GL_INVALID_VALUE, "glTrackMatrixNV(address)");
return;
}
switch (matrix) {
case GL_NONE:
case GL_MODELVIEW:
case GL_PROJECTION:
case GL_TEXTURE:
case GL_COLOR:
case GL_MODELVIEW_PROJECTION_NV:
case GL_MATRIX0_NV:
case GL_MATRIX1_NV:
case GL_MATRIX2_NV:
case GL_MATRIX3_NV:
case GL_MATRIX4_NV:
case GL_MATRIX5_NV:
case GL_MATRIX6_NV:
case GL_MATRIX7_NV:
/* OK, fallthrough */
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(matrix)");
return;
}
switch (transform) {
case GL_IDENTITY_NV:
case GL_INVERSE_NV:
case GL_TRANSPOSE_NV:
case GL_INVERSE_TRANSPOSE_NV:
/* OK, fallthrough */
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(transform)");
return;
}
ctx->VertexProgram.TrackMatrix[address / 4] = matrix;
ctx->VertexProgram.TrackMatrixTransform[address / 4] = transform;
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(target)");
return;
}
}
void GLAPIENTRY
_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
struct program *prog;
struct fragment_program *fragProg;
GLfloat *v;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id);
if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glProgramNamedParameterNV");
return;
}
if (len <= 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV");
return;
}
fragProg = (struct fragment_program *) prog;
v = _mesa_lookup_parameter_value(fragProg->Parameters, len, (char *) name);
if (v) {
v[0] = x;
v[1] = y;
v[2] = z;
v[3] = w;
return;
}
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV");
}
void GLAPIENTRY
_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
const float v[])
{
_mesa_ProgramNamedParameter4fNV(id, len, name, v[0], v[1], v[2], v[3]);
}
void GLAPIENTRY
_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
_mesa_ProgramNamedParameter4fNV(id, len, name, (GLfloat)x, (GLfloat)y,
(GLfloat)z, (GLfloat)w);
}
void GLAPIENTRY
_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
const double v[])
{
_mesa_ProgramNamedParameter4fNV(id, len, name,
(GLfloat)v[0], (GLfloat)v[1],
(GLfloat)v[2], (GLfloat)v[3]);
}
void GLAPIENTRY
_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
GLfloat *params)
{
struct program *prog;
struct fragment_program *fragProg;
const GLfloat *v;
GET_CURRENT_CONTEXT(ctx);
if (!ctx->_CurrentProgram)
ASSERT_OUTSIDE_BEGIN_END(ctx);
prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id);
if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramNamedParameterNV");
return;
}
if (len <= 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV");
return;
}
fragProg = (struct fragment_program *) prog;
v = _mesa_lookup_parameter_value(fragProg->Parameters, len, (char *) name);
if (v) {
params[0] = v[0];
params[1] = v[1];
params[2] = v[2];
params[3] = v[3];
return;
}
_mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV");
}
void GLAPIENTRY
_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
GLdouble *params)
{
GLfloat floatParams[4];
_mesa_GetProgramNamedParameterfvNV(id, len, name, floatParams);
COPY_4V(params, floatParams);
}

View file

@ -1,119 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 5.1
*
* Copyright (C) 1999-2003 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.
*
* Authors:
* Brian Paul
*/
#ifndef NVPROGRAM_H
#define NVPROGRAM_H
extern void GLAPIENTRY
_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params);
extern GLboolean GLAPIENTRY
_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences);
extern void GLAPIENTRY
_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids);
extern void GLAPIENTRY
_mesa_GetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat *params);
extern void GLAPIENTRY
_mesa_GetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble *params);
extern void GLAPIENTRY
_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params);
extern void GLAPIENTRY
_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program);
extern void GLAPIENTRY
_mesa_GetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint *params);
extern void GLAPIENTRY
_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params);
extern void GLAPIENTRY
_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params);
extern void GLAPIENTRY
_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params);
extern void GLAPIENTRY
_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer);
extern void GLAPIENTRY
_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program);
extern void GLAPIENTRY
_mesa_ProgramParameter4dNV(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
extern void GLAPIENTRY
_mesa_ProgramParameter4dvNV(GLenum target, GLuint index, const GLdouble *params);
extern void GLAPIENTRY
_mesa_ProgramParameter4fNV(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
extern void GLAPIENTRY
_mesa_ProgramParameter4fvNV(GLenum target, GLuint index, const GLfloat *params);
extern void GLAPIENTRY
_mesa_ProgramParameters4dvNV(GLenum target, GLuint index, GLuint num, const GLdouble *params);
extern void GLAPIENTRY
_mesa_ProgramParameters4fvNV(GLenum target, GLuint index, GLuint num, const GLfloat *params);
extern void GLAPIENTRY
_mesa_TrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform);
extern void GLAPIENTRY
_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
GLfloat x, GLfloat y, GLfloat z, GLfloat w);
extern void GLAPIENTRY
_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
const float v[]);
extern void GLAPIENTRY
_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
GLdouble x, GLdouble y, GLdouble z, GLdouble w);
extern void GLAPIENTRY
_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
const double v[]);
extern void GLAPIENTRY
_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
GLfloat *params);
extern void GLAPIENTRY
_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
GLdouble *params);
#endif

View file

@ -1,839 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 6.0.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 nvvertexec.c
* Code to execute vertex programs.
* \author Brian Paul
*/
#include "glheader.h"
#include "context.h"
#include "imports.h"
#include "macros.h"
#include "mtypes.h"
#include "nvvertexec.h"
#include "nvvertprog.h"
#include "program.h"
#include "math/m_matrix.h"
static const GLfloat zeroVec[4] = { 0, 0, 0, 0 };
/**
* Load/initialize the vertex program registers.
* This needs to be done per vertex.
*/
void
_mesa_init_vp_registers(GLcontext *ctx)
{
GLuint i;
/* Input registers get initialized from the current vertex attribs */
MEMCPY(ctx->VertexProgram.Inputs, ctx->Current.Attrib,
VERT_ATTRIB_MAX * 4 * sizeof(GLfloat));
/* Output and temp regs are initialized to [0,0,0,1] */
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) {
ASSIGN_4V(ctx->VertexProgram.Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F);
}
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) {
ASSIGN_4V(ctx->VertexProgram.Temporaries[i], 0.0F, 0.0F, 0.0F, 1.0F);
}
/* The program parameters aren't touched */
/* XXX: This should be moved to glBegin() time, but its safe (and slow!)
* here - Karl
*/
if (ctx->VertexProgram.Current->Parameters) {
/* Grab the state */
_mesa_load_state_parameters(ctx, ctx->VertexProgram.Current->Parameters);
/* And copy it into the program state */
for (i=0; i<ctx->VertexProgram.Current->Parameters->NumParameters; i++) {
MEMCPY(ctx->VertexProgram.Parameters[i],
&ctx->VertexProgram.Current->Parameters->Parameters[i].Values,
4*sizeof(GLfloat));
}
}
}
/**
* Copy the 16 elements of a matrix into four consecutive program
* registers starting at 'pos'.
*/
static void
load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16])
{
GLuint i;
for (i = 0; i < 4; i++) {
registers[pos + i][0] = mat[0 + i];
registers[pos + i][1] = mat[4 + i];
registers[pos + i][2] = mat[8 + i];
registers[pos + i][3] = mat[12 + i];
}
}
/**
* As above, but transpose the matrix.
*/
static void
load_transpose_matrix(GLfloat registers[][4], GLuint pos,
const GLfloat mat[16])
{
MEMCPY(registers[pos], mat, 16 * sizeof(GLfloat));
}
/**
* Load all currently tracked matrices into the program registers.
* This needs to be done per glBegin/glEnd.
*/
void
_mesa_init_tracked_matrices(GLcontext *ctx)
{
GLuint i;
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
/* point 'mat' at source matrix */
GLmatrix *mat;
if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) {
mat = ctx->ModelviewMatrixStack.Top;
}
else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) {
mat = ctx->ProjectionMatrixStack.Top;
}
else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) {
mat = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top;
}
else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) {
mat = ctx->ColorMatrixStack.Top;
}
else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) {
/* XXX verify the combined matrix is up to date */
mat = &ctx->_ModelProjectMatrix;
}
else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV &&
ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) {
GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV;
ASSERT(n < MAX_PROGRAM_MATRICES);
mat = ctx->ProgramMatrixStack[n].Top;
}
else {
/* no matrix is tracked, but we leave the register values as-is */
assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE);
continue;
}
/* load the matrix */
if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) {
load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
}
else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) {
_math_matrix_analyse(mat); /* update the inverse */
assert((mat->flags & MAT_DIRTY_INVERSE) == 0);
load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
}
else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) {
load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
}
else {
assert(ctx->VertexProgram.TrackMatrixTransform[i]
== GL_INVERSE_TRANSPOSE_NV);
_math_matrix_analyse(mat); /* update the inverse */
assert((mat->flags & MAT_DIRTY_INVERSE) == 0);
load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
}
}
}
/**
* For debugging. Dump the current vertex program machine registers.
*/
void
_mesa_dump_vp_state( const struct vertex_program_state *state )
{
int i;
_mesa_printf("VertexIn:\n");
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_INPUTS; i++) {
_mesa_printf("%d: %f %f %f %f ", i,
state->Inputs[i][0],
state->Inputs[i][1],
state->Inputs[i][2],
state->Inputs[i][3]);
}
_mesa_printf("\n");
_mesa_printf("VertexOut:\n");
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) {
_mesa_printf("%d: %f %f %f %f ", i,
state->Outputs[i][0],
state->Outputs[i][1],
state->Outputs[i][2],
state->Outputs[i][3]);
}
_mesa_printf("\n");
_mesa_printf("Registers:\n");
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) {
_mesa_printf("%d: %f %f %f %f ", i,
state->Temporaries[i][0],
state->Temporaries[i][1],
state->Temporaries[i][2],
state->Temporaries[i][3]);
}
_mesa_printf("\n");
_mesa_printf("Parameters:\n");
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) {
_mesa_printf("%d: %f %f %f %f ", i,
state->Parameters[i][0],
state->Parameters[i][1],
state->Parameters[i][2],
state->Parameters[i][3]);
}
_mesa_printf("\n");
}
/**
* Return a pointer to the 4-element float vector specified by the given
* source register.
*/
static INLINE const GLfloat *
get_register_pointer( const struct vp_src_register *source,
const struct vertex_program_state *state )
{
if (source->RelAddr) {
const GLint reg = source->Index + state->AddressReg[0];
ASSERT( (source->File == PROGRAM_ENV_PARAM) ||
(source->File == PROGRAM_STATE_VAR) );
if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
return zeroVec;
else
return state->Parameters[reg];
}
else {
switch (source->File) {
case PROGRAM_TEMPORARY:
return state->Temporaries[source->Index];
case PROGRAM_INPUT:
return state->Inputs[source->Index];
case PROGRAM_LOCAL_PARAM:
/* XXX fix */
return state->Temporaries[source->Index];
case PROGRAM_ENV_PARAM:
return state->Parameters[source->Index];
case PROGRAM_STATE_VAR:
return state->Parameters[source->Index];
default:
_mesa_problem(NULL,
"Bad source register file in fetch_vector4(vp)");
return NULL;
}
}
return NULL;
}
/**
* Fetch a 4-element float vector from the given source register.
* Apply swizzling and negating as needed.
*/
static INLINE void
fetch_vector4( const struct vp_src_register *source,
const struct vertex_program_state *state,
GLfloat result[4] )
{
const GLfloat *src = get_register_pointer(source, state);
if (source->Negate) {
result[0] = -src[source->Swizzle[0]];
result[1] = -src[source->Swizzle[1]];
result[2] = -src[source->Swizzle[2]];
result[3] = -src[source->Swizzle[3]];
}
else {
result[0] = src[source->Swizzle[0]];
result[1] = src[source->Swizzle[1]];
result[2] = src[source->Swizzle[2]];
result[3] = src[source->Swizzle[3]];
}
}
/**
* As above, but only return result[0] element.
*/
static INLINE void
fetch_vector1( const struct vp_src_register *source,
const struct vertex_program_state *state,
GLfloat result[4] )
{
const GLfloat *src = get_register_pointer(source, state);
if (source->Negate) {
result[0] = -src[source->Swizzle[0]];
}
else {
result[0] = src[source->Swizzle[0]];
}
}
/**
* Store 4 floats into a register.
*/
static void
store_vector4( const struct vp_dst_register *dest,
struct vertex_program_state *state,
const GLfloat value[4] )
{
GLfloat *dst;
switch (dest->File) {
case PROGRAM_TEMPORARY:
dst = state->Temporaries[dest->Index];
break;
case PROGRAM_OUTPUT:
dst = state->Outputs[dest->Index];
break;
case PROGRAM_ENV_PARAM:
{
/* a slight hack */
GET_CURRENT_CONTEXT(ctx);
dst = ctx->VertexProgram.Parameters[dest->Index];
}
break;
default:
_mesa_problem(NULL, "Invalid register file in store_vector4(file=%d)",
dest->File);
return;
}
if (dest->WriteMask[0])
dst[0] = value[0];
if (dest->WriteMask[1])
dst[1] = value[1];
if (dest->WriteMask[2])
dst[2] = value[2];
if (dest->WriteMask[3])
dst[3] = value[3];
}
/**
* Set x to positive or negative infinity.
*/
#if defined(USE_IEEE) || defined(_WIN32)
#define SET_POS_INFINITY(x) ( *((GLuint *) &x) = 0x7F800000 )
#define SET_NEG_INFINITY(x) ( *((GLuint *) &x) = 0xFF800000 )
#elif defined(VMS)
#define SET_POS_INFINITY(x) x = __MAXFLOAT
#define SET_NEG_INFINITY(x) x = -__MAXFLOAT
#else
#define SET_POS_INFINITY(x) x = (GLfloat) HUGE_VAL
#define SET_NEG_INFINITY(x) x = (GLfloat) -HUGE_VAL
#endif
#define SET_FLOAT_BITS(x, bits) ((fi_type *) &(x))->i = bits
/**
* Execute the given vertex program
*/
void
_mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
{
struct vertex_program_state *state = &ctx->VertexProgram;
const struct vp_instruction *inst;
ctx->_CurrentProgram = GL_VERTEX_PROGRAM_ARB; /* or NV, doesn't matter */
/* If the program is position invariant, multiply the input
* position and the MVP matrix and stick it into the output pos slot
*/
if (ctx->VertexProgram.Current->IsPositionInvariant) {
TRANSFORM_POINT( ctx->VertexProgram.Outputs[0],
ctx->_ModelProjectMatrix.m,
ctx->VertexProgram.Inputs[0]);
/* XXX: This could go elsewhere */
ctx->VertexProgram.Current->OutputsWritten |= 0x1;
}
for (inst = program->Instructions; /*inst->Opcode != VP_OPCODE_END*/; inst++) {
if (ctx->VertexProgram.CallbackEnabled &&
ctx->VertexProgram.Callback) {
ctx->VertexProgram.CurrentPosition = inst->StringPos;
ctx->VertexProgram.Callback(program->Base.Target,
ctx->VertexProgram.CallbackData);
}
switch (inst->Opcode) {
case VP_OPCODE_MOV:
{
GLfloat t[4];
fetch_vector4( &inst->SrcReg[0], state, t );
store_vector4( &inst->DstReg, state, t );
}
break;
case VP_OPCODE_LIT:
{
const GLfloat epsilon = 1.0e-5F; /* XXX fix? */
GLfloat t[4], lit[4];
fetch_vector4( &inst->SrcReg[0], state, t );
if (t[3] < -(128.0F - epsilon))
t[3] = - (128.0F - epsilon);
else if (t[3] > 128.0F - epsilon)
t[3] = 128.0F - epsilon;
if (t[0] < 0.0)
t[0] = 0.0;
if (t[1] < 0.0)
t[1] = 0.0;
lit[0] = 1.0;
lit[1] = t[0];
lit[2] = (t[0] > 0.0) ? (GLfloat) exp(t[3] * log(t[1])) : 0.0F;
lit[3] = 1.0;
store_vector4( &inst->DstReg, state, lit );
}
break;
case VP_OPCODE_RCP:
{
GLfloat t[4];
fetch_vector1( &inst->SrcReg[0], state, t );
if (t[0] != 1.0F)
t[0] = 1.0F / t[0]; /* div by zero is infinity! */
t[1] = t[2] = t[3] = t[0];
store_vector4( &inst->DstReg, state, t );
}
break;
case VP_OPCODE_RSQ:
{
GLfloat t[4];
fetch_vector1( &inst->SrcReg[0], state, t );
t[0] = INV_SQRTF(FABSF(t[0]));
t[1] = t[2] = t[3] = t[0];
store_vector4( &inst->DstReg, state, t );
}
break;
case VP_OPCODE_EXP:
{
GLfloat t[4], q[4], floor_t0;
fetch_vector1( &inst->SrcReg[0], state, t );
floor_t0 = (float) floor(t[0]);
if (floor_t0 > FLT_MAX_EXP) {
SET_POS_INFINITY(q[0]);
SET_POS_INFINITY(q[2]);
}
else if (floor_t0 < FLT_MIN_EXP) {
q[0] = 0.0F;
q[2] = 0.0F;
}
else {
#ifdef USE_IEEE
GLint ii = (GLint) floor_t0;
ii = (ii < 23) + 0x3f800000;
SET_FLOAT_BITS(q[0], ii);
q[0] = *((GLfloat *) &ii);
#else
q[0] = (GLfloat) pow(2.0, floor_t0);
#endif
q[2] = (GLfloat) (q[0] * LOG2(q[1]));
}
q[1] = t[0] - floor_t0;
q[3] = 1.0F;
store_vector4( &inst->DstReg, state, q );
}
break;
case VP_OPCODE_LOG:
{
GLfloat t[4], q[4], abs_t0;
fetch_vector1( &inst->SrcReg[0], state, t );
abs_t0 = (GLfloat) fabs(t[0]);
if (abs_t0 != 0.0F) {
/* Since we really can't handle infinite values on VMS
* like other OSes we'll use __MAXFLOAT to represent
* infinity. This may need some tweaking.
*/
#ifdef VMS
if (abs_t0 == __MAXFLOAT)
#else
if (IS_INF_OR_NAN(abs_t0))
#endif
{
SET_POS_INFINITY(q[0]);
q[1] = 1.0F;
SET_POS_INFINITY(q[2]);
}
else {
int exponent;
double mantissa = frexp(t[0], &exponent);
q[0] = (GLfloat) (exponent - 1);
q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */
q[2] = (GLfloat) (q[0] + LOG2(q[1]));
}
}
else {
SET_NEG_INFINITY(q[0]);
q[1] = 1.0F;
SET_NEG_INFINITY(q[2]);
}
q[3] = 1.0;
store_vector4( &inst->DstReg, state, q );
}
break;
case VP_OPCODE_MUL:
{
GLfloat t[4], u[4], prod[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
prod[0] = t[0] * u[0];
prod[1] = t[1] * u[1];
prod[2] = t[2] * u[2];
prod[3] = t[3] * u[3];
store_vector4( &inst->DstReg, state, prod );
}
break;
case VP_OPCODE_ADD:
{
GLfloat t[4], u[4], sum[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
sum[0] = t[0] + u[0];
sum[1] = t[1] + u[1];
sum[2] = t[2] + u[2];
sum[3] = t[3] + u[3];
store_vector4( &inst->DstReg, state, sum );
}
break;
case VP_OPCODE_DP3:
{
GLfloat t[4], u[4], dot[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2];
dot[1] = dot[2] = dot[3] = dot[0];
store_vector4( &inst->DstReg, state, dot );
}
break;
case VP_OPCODE_DP4:
{
GLfloat t[4], u[4], dot[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + t[3] * u[3];
dot[1] = dot[2] = dot[3] = dot[0];
store_vector4( &inst->DstReg, state, dot );
}
break;
case VP_OPCODE_DST:
{
GLfloat t[4], u[4], dst[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
dst[0] = 1.0F;
dst[1] = t[1] * u[1];
dst[2] = t[2];
dst[3] = u[3];
store_vector4( &inst->DstReg, state, dst );
}
break;
case VP_OPCODE_MIN:
{
GLfloat t[4], u[4], min[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
min[0] = (t[0] < u[0]) ? t[0] : u[0];
min[1] = (t[1] < u[1]) ? t[1] : u[1];
min[2] = (t[2] < u[2]) ? t[2] : u[2];
min[3] = (t[3] < u[3]) ? t[3] : u[3];
store_vector4( &inst->DstReg, state, min );
}
break;
case VP_OPCODE_MAX:
{
GLfloat t[4], u[4], max[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
max[0] = (t[0] > u[0]) ? t[0] : u[0];
max[1] = (t[1] > u[1]) ? t[1] : u[1];
max[2] = (t[2] > u[2]) ? t[2] : u[2];
max[3] = (t[3] > u[3]) ? t[3] : u[3];
store_vector4( &inst->DstReg, state, max );
}
break;
case VP_OPCODE_SLT:
{
GLfloat t[4], u[4], slt[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
slt[0] = (t[0] < u[0]) ? 1.0F : 0.0F;
slt[1] = (t[1] < u[1]) ? 1.0F : 0.0F;
slt[2] = (t[2] < u[2]) ? 1.0F : 0.0F;
slt[3] = (t[3] < u[3]) ? 1.0F : 0.0F;
store_vector4( &inst->DstReg, state, slt );
}
break;
case VP_OPCODE_SGE:
{
GLfloat t[4], u[4], sge[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
sge[0] = (t[0] >= u[0]) ? 1.0F : 0.0F;
sge[1] = (t[1] >= u[1]) ? 1.0F : 0.0F;
sge[2] = (t[2] >= u[2]) ? 1.0F : 0.0F;
sge[3] = (t[3] >= u[3]) ? 1.0F : 0.0F;
store_vector4( &inst->DstReg, state, sge );
}
break;
case VP_OPCODE_MAD:
{
GLfloat t[4], u[4], v[4], sum[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
fetch_vector4( &inst->SrcReg[2], state, v );
sum[0] = t[0] * u[0] + v[0];
sum[1] = t[1] * u[1] + v[1];
sum[2] = t[2] * u[2] + v[2];
sum[3] = t[3] * u[3] + v[3];
store_vector4( &inst->DstReg, state, sum );
}
break;
case VP_OPCODE_ARL:
{
GLfloat t[4];
fetch_vector4( &inst->SrcReg[0], state, t );
state->AddressReg[0] = (GLint) floor(t[0]);
}
break;
case VP_OPCODE_DPH:
{
GLfloat t[4], u[4], dot[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + u[3];
dot[1] = dot[2] = dot[3] = dot[0];
store_vector4( &inst->DstReg, state, dot );
}
break;
case VP_OPCODE_RCC:
{
GLfloat t[4], u;
fetch_vector1( &inst->SrcReg[0], state, t );
if (t[0] == 1.0F)
u = 1.0F;
else
u = 1.0F / t[0];
if (u > 0.0F) {
if (u > 1.884467e+019F) {
u = 1.884467e+019F; /* IEEE 32-bit binary value 0x5F800000 */
}
else if (u < 5.42101e-020F) {
u = 5.42101e-020F; /* IEEE 32-bit binary value 0x1F800000 */
}
}
else {
if (u < -1.884467e+019F) {
u = -1.884467e+019F; /* IEEE 32-bit binary value 0xDF800000 */
}
else if (u > -5.42101e-020F) {
u = -5.42101e-020F; /* IEEE 32-bit binary value 0x9F800000 */
}
}
t[0] = t[1] = t[2] = t[3] = u;
store_vector4( &inst->DstReg, state, t );
}
break;
case VP_OPCODE_SUB: /* GL_NV_vertex_program1_1 */
{
GLfloat t[4], u[4], sum[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
sum[0] = t[0] - u[0];
sum[1] = t[1] - u[1];
sum[2] = t[2] - u[2];
sum[3] = t[3] - u[3];
store_vector4( &inst->DstReg, state, sum );
}
break;
case VP_OPCODE_ABS: /* GL_NV_vertex_program1_1 */
{
GLfloat t[4];
fetch_vector4( &inst->SrcReg[0], state, t );
if (t[0] < 0.0) t[0] = -t[0];
if (t[1] < 0.0) t[1] = -t[1];
if (t[2] < 0.0) t[2] = -t[2];
if (t[3] < 0.0) t[3] = -t[3];
store_vector4( &inst->DstReg, state, t );
}
break;
case VP_OPCODE_FLR: /* GL_ARB_vertex_program */
{
GLfloat t[4];
fetch_vector4( &inst->SrcReg[0], state, t );
t[0] = FLOORF(t[0]);
t[1] = FLOORF(t[1]);
t[2] = FLOORF(t[2]);
t[3] = FLOORF(t[3]);
store_vector4( &inst->DstReg, state, t );
}
break;
case VP_OPCODE_FRC: /* GL_ARB_vertex_program */
{
GLfloat t[4];
fetch_vector4( &inst->SrcReg[0], state, t );
t[0] = t[0] - FLOORF(t[0]);
t[1] = t[1] - FLOORF(t[1]);
t[2] = t[2] - FLOORF(t[2]);
t[3] = t[3] - FLOORF(t[3]);
store_vector4( &inst->DstReg, state, t );
}
break;
case VP_OPCODE_EX2: /* GL_ARB_vertex_program */
{
GLfloat t[4];
fetch_vector1( &inst->SrcReg[0], state, t );
t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(2.0, t[0]);
store_vector4( &inst->DstReg, state, t );
}
break;
case VP_OPCODE_LG2: /* GL_ARB_vertex_program */
{
GLfloat t[4];
fetch_vector1( &inst->SrcReg[0], state, t );
t[0] = t[1] = t[2] = t[3] = LOG2(t[0]);
store_vector4( &inst->DstReg, state, t );
}
break;
case VP_OPCODE_POW: /* GL_ARB_vertex_program */
{
GLfloat t[4], u[4];
fetch_vector1( &inst->SrcReg[0], state, t );
fetch_vector1( &inst->SrcReg[1], state, u );
t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(t[0], u[0]);
store_vector4( &inst->DstReg, state, t );
}
break;
case VP_OPCODE_XPD: /* GL_ARB_vertex_program */
{
GLfloat t[4], u[4], cross[4];
fetch_vector4( &inst->SrcReg[0], state, t );
fetch_vector4( &inst->SrcReg[1], state, u );
cross[0] = t[1] * u[2] - t[2] * u[1];
cross[1] = t[2] * u[0] - t[0] * u[2];
cross[2] = t[0] * u[1] - t[1] * u[0];
store_vector4( &inst->DstReg, state, cross );
}
break;
case VP_OPCODE_SWZ: /* GL_ARB_vertex_program */
{
const struct vp_src_register *source = &inst->SrcReg[0];
const GLfloat *src = get_register_pointer(source, state);
GLfloat result[4];
GLuint i;
/* do extended swizzling here */
for (i = 0; i < 3; i++) {
if (source->Swizzle[i] == SWIZZLE_ZERO)
result[i] = 0.0;
else if (source->Swizzle[i] == SWIZZLE_ONE)
result[i] = -1.0;
else
result[i] = -src[source->Swizzle[i]];
if (source->Negate)
result[i] = -result[i];
}
store_vector4( &inst->DstReg, state, result );
}
break;
case VP_OPCODE_END:
ctx->_CurrentProgram = 0;
return;
default:
/* bad instruction opcode */
_mesa_problem(ctx, "Bad VP Opcode in _mesa_exec_vertex_program");
ctx->_CurrentProgram = 0;
return;
} /* switch */
} /* for */
ctx->_CurrentProgram = 0;
}
/**
Thoughts on vertex program optimization:
The obvious thing to do is to compile the vertex program into X86/SSE/3DNow!
assembly code. That will probably be a lot of work.
Another approach might be to replace the vp_instruction->Opcode field with
a pointer to a specialized C function which executes the instruction.
In particular we can write functions which skip swizzling, negating,
masking, relative addressing, etc. when they're not needed.
For example:
void simple_add( struct vp_instruction *inst )
{
GLfloat *sum = machine->Registers[inst->DstReg.Register];
GLfloat *a = machine->Registers[inst->SrcReg[0].Register];
GLfloat *b = machine->Registers[inst->SrcReg[1].Register];
sum[0] = a[0] + b[0];
sum[1] = a[1] + b[1];
sum[2] = a[2] + b[2];
sum[3] = a[3] + b[3];
}
*/
/*
KW:
A first step would be to 'vectorize' the programs in the same way as
the normal transformation code in the tnl module. Thus each opcode
takes zero or more input vectors (registers) and produces one or more
output vectors.
These operations would intially be coded in C, with machine-specific
assembly following, as is currently the case for matrix
transformations in the math/ directory. The preprocessing scheme for
selecting simpler operations Brian describes above would also work
here.
This should give reasonable performance without excessive effort.
*/

View file

@ -1,43 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 5.1
*
* Copyright (C) 1999-2003 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.
*
* Authors:
* Brian Paul
*/
#ifndef NVVERTEXEC_H
#define NVVERTEXEC_H
extern void
_mesa_init_vp_registers(GLcontext *ctx);
extern void
_mesa_init_tracked_matrices(GLcontext *ctx);
extern void
_mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program);
extern void
_mesa_dump_vp_state( const struct vertex_program_state *state );
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,50 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 5.1
*
* Copyright (C) 1999-2003 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.
*
* Authors:
* Brian Paul
*/
#ifndef NVVERTPARSE_H
#define NVVERTPARSE_H
extern void
_mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum target,
const GLubyte *str, GLsizei len,
struct vertex_program *program);
extern void
_mesa_print_nv_vertex_instruction(const struct vp_instruction *inst);
extern void
_mesa_print_nv_vertex_program(const struct vertex_program *program);
extern const char *
_mesa_nv_vertex_input_register_name(GLuint i);
extern const char *
_mesa_nv_vertex_output_register_name(GLuint i);
#endif

View file

@ -1,107 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 5.1
*
* Copyright (C) 1999-2002 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.
*/
/* Private vertex program types and constants only used by files
* related to vertex programs.
*
* XXX TO-DO: Rename this file "vertprog.h" since it's not NV-specific.
*/
#ifndef NVVERTPROG_H
#define NVVERTPROG_H
/* Vertex program opcodes */
enum vp_opcode
{
VP_OPCODE_MOV,
VP_OPCODE_LIT,
VP_OPCODE_RCP,
VP_OPCODE_RSQ,
VP_OPCODE_EXP,
VP_OPCODE_LOG,
VP_OPCODE_MUL,
VP_OPCODE_ADD,
VP_OPCODE_DP3,
VP_OPCODE_DP4,
VP_OPCODE_DST,
VP_OPCODE_MIN,
VP_OPCODE_MAX,
VP_OPCODE_SLT,
VP_OPCODE_SGE,
VP_OPCODE_MAD,
VP_OPCODE_ARL,
VP_OPCODE_DPH,
VP_OPCODE_RCC,
VP_OPCODE_SUB,
VP_OPCODE_ABS,
VP_OPCODE_END,
/* Additional opcodes for GL_ARB_vertex_program */
VP_OPCODE_FLR,
VP_OPCODE_FRC,
VP_OPCODE_EX2,
VP_OPCODE_LG2,
VP_OPCODE_POW,
VP_OPCODE_XPD,
VP_OPCODE_SWZ
};
/* Instruction source register */
struct vp_src_register
{
enum register_file File; /* which register file */
GLint Index; /* index into register file */
GLubyte Swizzle[4]; /* Each value is 0,1,2,3 for x,y,z,w or */
/* SWIZZLE_ZERO or SWIZZLE_ONE for VP_OPCODE_SWZ. */
GLboolean Negate;
GLboolean RelAddr;
};
/* Instruction destination register */
struct vp_dst_register
{
enum register_file File; /* which register file */
GLint Index; /* index into register file */
GLboolean WriteMask[4];
};
/* Vertex program instruction */
struct vp_instruction
{
enum vp_opcode Opcode;
struct vp_src_register SrcReg[3];
struct vp_dst_register DstReg;
#if FEATURE_MESA_program_debug
GLint StringPos;
#endif
};
#endif /* VERTPROG_H */