Re-org of register files for vertex/fragment programs. Will be easier to
hook in global state references, etc. for ARB programs.
This commit is contained in:
parent
4f12be0249
commit
f2dd273322
|
@ -63,7 +63,7 @@ _mesa_init_program(GLcontext *ctx)
|
|||
ctx->VertexProgram.Current = (struct vertex_program *) ctx->Shared->DefaultVertexProgram;
|
||||
assert(ctx->VertexProgram.Current);
|
||||
ctx->VertexProgram.Current->Base.RefCount++;
|
||||
for (i = 0; i < VP_NUM_PROG_REGS / 4; i++) {
|
||||
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
|
||||
ctx->VertexProgram.TrackMatrix[i] = GL_NONE;
|
||||
ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV;
|
||||
}
|
||||
|
@ -271,8 +271,7 @@ _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
|
|||
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
|
||||
return;
|
||||
}
|
||||
index += FP_PROG_REG_START;
|
||||
ASSIGN_4V(ctx->FragmentProgram.Machine.Registers[index], x, y, z, w);
|
||||
ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w);
|
||||
}
|
||||
if (target == GL_VERTEX_PROGRAM_ARB
|
||||
&& ctx->Extensions.ARB_vertex_program) {
|
||||
|
@ -280,8 +279,7 @@ _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
|
|||
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
|
||||
return;
|
||||
}
|
||||
index += VP_PROG_REG_START;
|
||||
ASSIGN_4V(ctx->VertexProgram.Machine.Registers[index], x, y, z, w);
|
||||
ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
|
||||
|
@ -331,8 +329,7 @@ _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
|
|||
_mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
|
||||
return;
|
||||
}
|
||||
index += FP_PROG_REG_START;
|
||||
COPY_4V(params, ctx->FragmentProgram.Machine.Registers[index]);
|
||||
COPY_4V(params, ctx->FragmentProgram.Parameters[index]);
|
||||
}
|
||||
if (target == GL_VERTEX_PROGRAM_ARB
|
||||
&& ctx->Extensions.ARB_vertex_program) {
|
||||
|
@ -340,8 +337,7 @@ _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
|
|||
_mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
|
||||
return;
|
||||
}
|
||||
index += VP_PROG_REG_START;
|
||||
COPY_4V(params, ctx->VertexProgram.Machine.Registers[index]);
|
||||
COPY_4V(params, ctx->VertexProgram.Parameters[index]);
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
|
||||
|
@ -830,8 +826,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target,
|
|||
"glGetProgramRegisterfvMESA(registerName)");
|
||||
return;
|
||||
}
|
||||
COPY_4V(v, ctx->VertexProgram.Machine.Registers
|
||||
[VP_TEMP_REG_START + i]);
|
||||
COPY_4V(v, ctx->VertexProgram.Temporaries[i]);
|
||||
}
|
||||
else if (reg[0] == 'v' && reg[1] == '[') {
|
||||
/* Vertex Input attribute */
|
||||
|
@ -842,8 +837,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target,
|
|||
sprintf(number, "%d", i);
|
||||
if (_mesa_strncmp(reg + 2, name, 4) == 0 ||
|
||||
_mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) {
|
||||
COPY_4V(v, ctx->VertexProgram.Machine.Registers
|
||||
[VP_INPUT_REG_START + i]);
|
||||
COPY_4V(v, ctx->VertexProgram.Inputs[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -896,8 +890,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target,
|
|||
"glGetProgramRegisterfvMESA(registerName)");
|
||||
return;
|
||||
}
|
||||
COPY_4V(v,
|
||||
ctx->FragmentProgram.Machine.Registers[FP_TEMP_REG_START + i]);
|
||||
COPY_4V(v, ctx->FragmentProgram.Machine.Temporaries[i]);
|
||||
}
|
||||
else if (reg[0] == 'f' && reg[1] == '[') {
|
||||
/* Fragment input attribute */
|
||||
|
@ -905,8 +898,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target,
|
|||
for (i = 0; i < ctx->Const.MaxFragmentProgramAttribs; i++) {
|
||||
const char *name = _mesa_nv_fragment_input_register_name(i);
|
||||
if (_mesa_strncmp(reg + 2, name, 4) == 0) {
|
||||
COPY_4V(v, ctx->FragmentProgram.Machine.Registers
|
||||
[FP_INPUT_REG_START + i]);
|
||||
COPY_4V(v, ctx->FragmentProgram.Machine.Inputs[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -916,18 +908,15 @@ _mesa_GetProgramRegisterfvMESA(GLenum target,
|
|||
}
|
||||
else if (_mesa_strcmp(reg, "o[COLR]") == 0) {
|
||||
/* Fragment output color */
|
||||
COPY_4V(v, ctx->FragmentProgram.Machine.Registers
|
||||
[FP_OUTPUT_REG_START + FRAG_OUTPUT_COLR]);
|
||||
COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_COLR]);
|
||||
}
|
||||
else if (_mesa_strcmp(reg, "o[COLH]") == 0) {
|
||||
/* Fragment output color */
|
||||
COPY_4V(v, ctx->FragmentProgram.Machine.Registers
|
||||
[FP_OUTPUT_REG_START + FRAG_OUTPUT_COLH]);
|
||||
COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_COLH]);
|
||||
}
|
||||
else if (_mesa_strcmp(reg, "o[DEPR]") == 0) {
|
||||
/* Fragment output depth */
|
||||
COPY_4V(v, ctx->FragmentProgram.Machine.Registers
|
||||
[FP_OUTPUT_REG_START + FRAG_OUTPUT_DEPR]);
|
||||
COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR]);
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
|
|
|
@ -20,9 +20,6 @@
|
|||
* 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 ARBVERTPARSE_H
|
||||
|
|
|
@ -113,10 +113,6 @@
|
|||
#include "varray.h"
|
||||
#if FEATURE_NV_vertex_program
|
||||
#include "nvprogram.h"
|
||||
#include "nvvertprog.h"
|
||||
#endif
|
||||
#if FEATURE_NV_fragment_program
|
||||
#include "nvfragprog.h"
|
||||
#endif
|
||||
#include "vtxfmt.h"
|
||||
#if _HAVE_FULL_GL
|
||||
|
|
|
@ -146,15 +146,6 @@ do { \
|
|||
(DST)[3] = (SRC)[3]; \
|
||||
} while (0)
|
||||
|
||||
/** Copy a 4-element vector with cast */
|
||||
#define COPY_4V_CAST( DST, SRC, CAST ) \
|
||||
do { \
|
||||
(DST)[0] = (CAST)(SRC)[0]; \
|
||||
(DST)[1] = (CAST)(SRC)[1]; \
|
||||
(DST)[2] = (CAST)(SRC)[2]; \
|
||||
(DST)[3] = (CAST)(SRC)[3]; \
|
||||
} while (0)
|
||||
|
||||
/** Copy a 4-element unsigned byte vector */
|
||||
#if defined(__i386__)
|
||||
#define COPY_4UBV(DST, SRC) \
|
||||
|
|
|
@ -1352,7 +1352,8 @@ struct gl_selection {
|
|||
/**
|
||||
* 1-D Evaluator control points
|
||||
*/
|
||||
struct gl_1d_map {
|
||||
struct gl_1d_map
|
||||
{
|
||||
GLuint Order; /**< Number of control points */
|
||||
GLfloat u1, u2, du; /**< u1, u2, 1.0/(u2-u1) */
|
||||
GLfloat *Points; /**< Points to contiguous control points */
|
||||
|
@ -1362,7 +1363,8 @@ struct gl_1d_map {
|
|||
/**
|
||||
* 2-D Evaluator control points
|
||||
*/
|
||||
struct gl_2d_map {
|
||||
struct gl_2d_map
|
||||
{
|
||||
GLuint Uorder; /**< Number of control points in U dimension */
|
||||
GLuint Vorder; /**< Number of control points in V dimension */
|
||||
GLfloat u1, u2, du;
|
||||
|
@ -1374,7 +1376,8 @@ struct gl_2d_map {
|
|||
/**
|
||||
* All evaluator control points
|
||||
*/
|
||||
struct gl_evaluators {
|
||||
struct gl_evaluators
|
||||
{
|
||||
/**
|
||||
* \name 1-D maps
|
||||
*/
|
||||
|
@ -1409,45 +1412,41 @@ struct gl_evaluators {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* \name NV_vertex_program runtime state
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
|
||||
/**
|
||||
* Machine state (i.e. the register file)
|
||||
*/
|
||||
struct vp_machine
|
||||
{
|
||||
GLfloat Registers[MAX_NV_VERTEX_PROGRAM_TEMPS
|
||||
+ MAX_NV_VERTEX_PROGRAM_PARAMS
|
||||
+ MAX_NV_VERTEX_PROGRAM_INPUTS
|
||||
+ MAX_NV_VERTEX_PROGRAM_OUTPUTS][4];
|
||||
GLint AddressReg; /* might someday be a 4-vector */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* NV_fragment_program runtime state
|
||||
*/
|
||||
struct fp_machine
|
||||
{
|
||||
GLfloat Registers[MAX_NV_FRAGMENT_PROGRAM_TEMPS
|
||||
+ MAX_NV_FRAGMENT_PROGRAM_PARAMS
|
||||
+ MAX_NV_FRAGMENT_PROGRAM_INPUTS
|
||||
+ MAX_NV_FRAGMENT_PROGRAM_OUTPUTS
|
||||
+ MAX_NV_FRAGMENT_PROGRAM_WRITE_ONLYS][4];
|
||||
GLfloat Temporaries[MAX_NV_FRAGMENT_PROGRAM_TEMPS][4];
|
||||
GLfloat Inputs[MAX_NV_FRAGMENT_PROGRAM_INPUTS][4];
|
||||
GLfloat Outputs[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS][4];
|
||||
GLuint CondCodes[4];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Names of the various vertex/fragment register files
|
||||
*/
|
||||
enum register_file
|
||||
{
|
||||
PROGRAM_TEMPORARY = 10,
|
||||
PROGRAM_INPUT,
|
||||
PROGRAM_OUTPUT,
|
||||
PROGRAM_LOCAL_PARAM,
|
||||
PROGRAM_ENV_PARAM,
|
||||
PROGRAM_NAMED_PARAM,
|
||||
PROGRAM_STATE_VAR,
|
||||
PROGRAM_WRITE_ONLY
|
||||
};
|
||||
|
||||
|
||||
/* Vertex and fragment instructions */
|
||||
struct vp_instruction;
|
||||
struct fp_instruction;
|
||||
|
||||
|
||||
/**
|
||||
* Program parameters
|
||||
* Named program parameters
|
||||
*/
|
||||
struct program_parameter
|
||||
{
|
||||
|
@ -1522,11 +1521,17 @@ struct vertex_program_state
|
|||
GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_NV */
|
||||
GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_NV */
|
||||
struct vertex_program *Current; /**< ptr to currently bound program */
|
||||
struct vp_machine Machine; /**< machine state */
|
||||
|
||||
GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
|
||||
GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
|
||||
|
||||
GLfloat Parameters[MAX_NV_VERTEX_PROGRAM_PARAMS][4]; /* Env params */
|
||||
/* Only used during program execution (may be moved someday): */
|
||||
GLfloat Temporaries[MAX_NV_VERTEX_PROGRAM_TEMPS][4];
|
||||
GLfloat Inputs[MAX_NV_VERTEX_PROGRAM_INPUTS][4];
|
||||
GLfloat Outputs[MAX_NV_VERTEX_PROGRAM_OUTPUTS][4];
|
||||
GLint AddressReg[4];
|
||||
|
||||
#if FEATURE_MESA_program_debug
|
||||
GLprogramcallbackMESA Callback;
|
||||
GLvoid *CallbackData;
|
||||
|
@ -1544,6 +1549,7 @@ struct fragment_program_state
|
|||
GLboolean Enabled; /* GL_VERTEX_PROGRAM_NV */
|
||||
struct fragment_program *Current; /* ptr to currently bound program */
|
||||
struct fp_machine Machine; /* machine state */
|
||||
GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /* Env params */
|
||||
|
||||
#if FEATURE_MESA_program_debug
|
||||
GLprogramcallbackMESA Callback;
|
||||
|
@ -1553,7 +1559,6 @@ struct fragment_program_state
|
|||
#endif
|
||||
};
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*
|
||||
* State for GL_ARB_occlusion_query
|
||||
|
@ -1570,7 +1575,8 @@ struct occlusion_state
|
|||
/**
|
||||
* State which can be shared by multiple contexts:
|
||||
*/
|
||||
struct gl_shared_state {
|
||||
struct gl_shared_state
|
||||
{
|
||||
_glthread_Mutex Mutex; /**< for thread safety */
|
||||
GLint RefCount; /**< Reference count */
|
||||
struct _mesa_HashTable *DisplayList; /**< Display lists hash table */
|
||||
|
@ -1613,7 +1619,8 @@ struct gl_shared_state {
|
|||
* In C++ terms, think of this as a base class from which device drivers
|
||||
* will make derived classes.
|
||||
*/
|
||||
struct gl_frame_buffer {
|
||||
struct gl_frame_buffer
|
||||
{
|
||||
GLvisual Visual; /**< The corresponding visual */
|
||||
|
||||
GLuint Width, Height; /**< size of frame buffer in pixels */
|
||||
|
@ -1664,7 +1671,8 @@ struct gl_frame_buffer {
|
|||
* Constants which may be overridden by device driver during context creation
|
||||
* but are never changed after that.
|
||||
*/
|
||||
struct gl_constants {
|
||||
struct gl_constants
|
||||
{
|
||||
GLint MaxTextureLevels; /**< Maximum number of allowed mipmap levels. */
|
||||
GLint Max3DTextureLevels; /**< Maximum number of allowed mipmap levels for 3D texture targets. */
|
||||
GLint MaxCubeTextureLevels; /**< Maximum number of allowed mipmap levels for GL_ARB_texture_cube_map */
|
||||
|
@ -1716,7 +1724,8 @@ struct gl_constants {
|
|||
/**
|
||||
* List of extensions.
|
||||
*/
|
||||
struct gl_extensions {
|
||||
struct gl_extensions
|
||||
{
|
||||
/**
|
||||
* \name Flags to quickly test if certain extensions are available.
|
||||
*
|
||||
|
|
|
@ -444,59 +444,6 @@ static const char *OutputRegisters[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS + 1] = {
|
|||
};
|
||||
|
||||
|
||||
static GLint
|
||||
TempRegisterNumber(GLuint r)
|
||||
{
|
||||
if (r >= FP_TEMP_REG_START && r <= FP_TEMP_REG_END)
|
||||
return r - FP_TEMP_REG_START;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static GLint
|
||||
HalfTempRegisterNumber(GLuint r)
|
||||
{
|
||||
if (r >= FP_TEMP_REG_START + 32 && r <= FP_TEMP_REG_END)
|
||||
return r - FP_TEMP_REG_START - 32;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static GLint
|
||||
InputRegisterNumber(GLuint r)
|
||||
{
|
||||
if (r >= FP_INPUT_REG_START && r <= FP_INPUT_REG_END)
|
||||
return r - FP_INPUT_REG_START;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static GLint
|
||||
OutputRegisterNumber(GLuint r)
|
||||
{
|
||||
if (r >= FP_OUTPUT_REG_START && r <= FP_OUTPUT_REG_END)
|
||||
return r - FP_OUTPUT_REG_START;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static GLint
|
||||
ProgramRegisterNumber(GLuint r)
|
||||
{
|
||||
if (r >= FP_PROG_REG_START && r <= FP_PROG_REG_END)
|
||||
return r - FP_PROG_REG_START;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static GLint
|
||||
DummyRegisterNumber(GLuint r)
|
||||
{
|
||||
if (r >= FP_DUMMY_REG_START && r <= FP_DUMMY_REG_END)
|
||||
return r - FP_DUMMY_REG_START;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
|
@ -823,7 +770,7 @@ Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
|
|||
reg += 32;
|
||||
if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS)
|
||||
RETURN_ERROR1("Invalid temporary register name");
|
||||
*tempRegNum = FP_TEMP_REG_START + reg;
|
||||
*tempRegNum = reg;
|
||||
}
|
||||
else {
|
||||
RETURN_ERROR1("Invalid temporary register name");
|
||||
|
@ -840,10 +787,10 @@ static GLboolean
|
|||
Parse_DummyReg(struct parse_state *parseState, GLint *regNum)
|
||||
{
|
||||
if (Parse_String(parseState, "RC")) {
|
||||
*regNum = FP_DUMMY_REG_START;
|
||||
*regNum = 0;
|
||||
}
|
||||
else if (Parse_String(parseState, "HC")) {
|
||||
*regNum = FP_DUMMY_REG_START + 1;
|
||||
*regNum = 1;
|
||||
}
|
||||
else {
|
||||
RETURN_ERROR1("Invalid write-only register name");
|
||||
|
@ -872,7 +819,7 @@ Parse_ProgramParamReg(struct parse_state *parseState, GLint *regNum)
|
|||
GLint reg = _mesa_atoi((const char *) token);
|
||||
if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS)
|
||||
RETURN_ERROR1("Invalid constant program number");
|
||||
*regNum = FP_PROG_REG_START + reg;
|
||||
*regNum = reg;
|
||||
}
|
||||
else {
|
||||
RETURN_ERROR;
|
||||
|
@ -904,7 +851,7 @@ Parse_FragReg(struct parse_state *parseState, GLint *tempRegNum)
|
|||
}
|
||||
for (j = 0; InputRegisters[j]; j++) {
|
||||
if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) {
|
||||
*tempRegNum = FP_INPUT_REG_START + j;
|
||||
*tempRegNum = j;
|
||||
parseState->inputsRead |= (1 << j);
|
||||
break;
|
||||
}
|
||||
|
@ -940,7 +887,7 @@ Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
|
|||
for (j = 0; OutputRegisters[j]; j++) {
|
||||
if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) {
|
||||
static GLuint bothColors = (1 << FRAG_OUTPUT_COLR) | (1 << FRAG_OUTPUT_COLH);
|
||||
*outputRegNum = FP_OUTPUT_REG_START + j;
|
||||
*outputRegNum = j;
|
||||
parseState->outputsWritten |= (1 << j);
|
||||
if ((parseState->outputsWritten & bothColors) == bothColors) {
|
||||
RETURN_ERROR1("Illegal to write to both o[COLR] and o[COLH]");
|
||||
|
@ -972,17 +919,20 @@ Parse_MaskedDstReg(struct parse_state *parseState,
|
|||
if (_mesa_strcmp((const char *) token, "RC") == 0 ||
|
||||
_mesa_strcmp((const char *) token, "HC") == 0) {
|
||||
/* a write-only register */
|
||||
if (!Parse_DummyReg(parseState, &dstReg->Register))
|
||||
dstReg->File = PROGRAM_WRITE_ONLY;
|
||||
if (!Parse_DummyReg(parseState, &dstReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else if (token[0] == 'R' || token[0] == 'H') {
|
||||
/* a temporary register */
|
||||
if (!Parse_TempReg(parseState, &dstReg->Register))
|
||||
dstReg->File = PROGRAM_TEMPORARY;
|
||||
if (!Parse_TempReg(parseState, &dstReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else if (token[0] == 'o') {
|
||||
/* an output register */
|
||||
if (!Parse_OutputReg(parseState, &dstReg->Register))
|
||||
dstReg->File = PROGRAM_OUTPUT;
|
||||
if (!Parse_OutputReg(parseState, &dstReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else {
|
||||
|
@ -1100,17 +1050,20 @@ Parse_VectorSrc(struct parse_state *parseState,
|
|||
* literal or vector literal.
|
||||
*/
|
||||
if (token[0] == 'R' || token[0] == 'H') {
|
||||
if (!Parse_TempReg(parseState, &srcReg->Register))
|
||||
srcReg->File = PROGRAM_TEMPORARY;
|
||||
if (!Parse_TempReg(parseState, &srcReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else if (token[0] == 'f') {
|
||||
/* XXX this might be an identier! */
|
||||
if (!Parse_FragReg(parseState, &srcReg->Register))
|
||||
srcReg->File = PROGRAM_INPUT;
|
||||
if (!Parse_FragReg(parseState, &srcReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else if (token[0] == 'p') {
|
||||
/* XXX this might be an identier! */
|
||||
if (!Parse_ProgramParamReg(parseState, &srcReg->Register))
|
||||
srcReg->File = PROGRAM_LOCAL_PARAM;
|
||||
if (!Parse_ProgramParamReg(parseState, &srcReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else if (IsLetter(token[0])){
|
||||
|
@ -1122,8 +1075,8 @@ Parse_VectorSrc(struct parse_state *parseState,
|
|||
if (paramIndex < 0) {
|
||||
RETURN_ERROR2("Undefined constant or parameter: ", ident);
|
||||
}
|
||||
srcReg->IsParameter = GL_TRUE;
|
||||
srcReg->Register = paramIndex;
|
||||
srcReg->File = PROGRAM_NAMED_PARAM;
|
||||
srcReg->Index = paramIndex;
|
||||
}
|
||||
else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){
|
||||
/* literal scalar constant */
|
||||
|
@ -1131,13 +1084,9 @@ Parse_VectorSrc(struct parse_state *parseState,
|
|||
GLuint paramIndex;
|
||||
if (!Parse_ScalarConstant(parseState, values))
|
||||
RETURN_ERROR;
|
||||
#if 0
|
||||
srcReg->Register = 0; /* XXX fix */
|
||||
#else
|
||||
paramIndex = add_unnamed_constant(parseState, values);
|
||||
srcReg->IsParameter = GL_TRUE;
|
||||
srcReg->Register = paramIndex;
|
||||
#endif
|
||||
srcReg->File = PROGRAM_NAMED_PARAM;
|
||||
srcReg->Index = paramIndex;
|
||||
}
|
||||
else if (token[0] == '{'){
|
||||
/* literal vector constant */
|
||||
|
@ -1147,8 +1096,8 @@ Parse_VectorSrc(struct parse_state *parseState,
|
|||
if (!Parse_VectorConstant(parseState, values))
|
||||
RETURN_ERROR;
|
||||
paramIndex = add_unnamed_constant(parseState, values);
|
||||
srcReg->IsParameter = GL_TRUE;
|
||||
srcReg->Register = paramIndex;
|
||||
srcReg->File = PROGRAM_NAMED_PARAM;
|
||||
srcReg->Index = paramIndex;
|
||||
}
|
||||
else {
|
||||
RETURN_ERROR2("Invalid source register name", token);
|
||||
|
@ -1216,11 +1165,13 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
|
|||
|
||||
/* Src reg can be R<n>, H<n> or a named fragment attrib */
|
||||
if (token[0] == 'R' || token[0] == 'H') {
|
||||
if (!Parse_TempReg(parseState, &srcReg->Register))
|
||||
srcReg->File = PROGRAM_TEMPORARY;
|
||||
if (!Parse_TempReg(parseState, &srcReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else if (token[0] == 'f') {
|
||||
if (!Parse_FragReg(parseState, &srcReg->Register))
|
||||
srcReg->File = PROGRAM_INPUT;
|
||||
if (!Parse_FragReg(parseState, &srcReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else if (token[0] == '{') {
|
||||
|
@ -1231,8 +1182,8 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
|
|||
if (!Parse_VectorConstant(parseState, values))
|
||||
RETURN_ERROR;
|
||||
paramIndex = add_unnamed_constant(parseState, values);
|
||||
srcReg->IsParameter = GL_TRUE;
|
||||
srcReg->Register = paramIndex;
|
||||
srcReg->File = PROGRAM_NAMED_PARAM;
|
||||
srcReg->Index = paramIndex;
|
||||
}
|
||||
else if (IsDigit(token[0])) {
|
||||
/* scalar literal */
|
||||
|
@ -1241,8 +1192,8 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
|
|||
if (!Parse_ScalarConstant(parseState, values))
|
||||
RETURN_ERROR;
|
||||
paramIndex = add_unnamed_constant(parseState, values);
|
||||
srcReg->IsParameter = GL_TRUE;
|
||||
srcReg->Register = paramIndex;
|
||||
srcReg->Index = paramIndex;
|
||||
srcReg->File = PROGRAM_NAMED_PARAM;
|
||||
needSuffix = GL_FALSE;
|
||||
}
|
||||
else {
|
||||
|
@ -1298,13 +1249,10 @@ Parse_InstructionSequence(struct parse_state *parseState,
|
|||
GLubyte token[100];
|
||||
|
||||
/* Initialize the instruction */
|
||||
inst->SrcReg[0].Register = -1;
|
||||
inst->SrcReg[1].Register = -1;
|
||||
inst->SrcReg[2].Register = -1;
|
||||
inst->SrcReg[0].IsParameter = GL_FALSE;
|
||||
inst->SrcReg[1].IsParameter = GL_FALSE;
|
||||
inst->SrcReg[2].IsParameter = GL_FALSE;
|
||||
inst->DstReg.Register = -1;
|
||||
inst->SrcReg[0].File = -1;
|
||||
inst->SrcReg[1].File = -1;
|
||||
inst->SrcReg[2].File = -1;
|
||||
inst->DstReg.File = -1;
|
||||
inst->DstReg.CondSwizzle[0] = 0;
|
||||
inst->DstReg.CondSwizzle[1] = 1;
|
||||
inst->DstReg.CondSwizzle[2] = 2;
|
||||
|
@ -1617,7 +1565,6 @@ PrintSrcReg(const struct fragment_program *program,
|
|||
const struct fp_src_register *src)
|
||||
{
|
||||
static const char comps[5] = "xyzw";
|
||||
GLint r;
|
||||
|
||||
if (src->NegateAbs) {
|
||||
_mesa_printf("-");
|
||||
|
@ -1628,38 +1575,38 @@ PrintSrcReg(const struct fragment_program *program,
|
|||
if (src->NegateBase) {
|
||||
_mesa_printf("-");
|
||||
}
|
||||
if (src->IsParameter) {
|
||||
if (program->Parameters[src->Register].Constant) {
|
||||
if (src->File == PROGRAM_NAMED_PARAM) {
|
||||
if (program->Parameters[src->Index].Constant) {
|
||||
printf("{%g, %g, %g, %g}",
|
||||
program->Parameters[src->Register].Values[0],
|
||||
program->Parameters[src->Register].Values[1],
|
||||
program->Parameters[src->Register].Values[2],
|
||||
program->Parameters[src->Register].Values[3]);
|
||||
program->Parameters[src->Index].Values[0],
|
||||
program->Parameters[src->Index].Values[1],
|
||||
program->Parameters[src->Index].Values[2],
|
||||
program->Parameters[src->Index].Values[3]);
|
||||
}
|
||||
else {
|
||||
printf("%s", program->Parameters[src->Register].Name);
|
||||
printf("%s", program->Parameters[src->Index].Name);
|
||||
}
|
||||
}
|
||||
else if ((r = OutputRegisterNumber(src->Register)) >= 0) {
|
||||
_mesa_printf("o[%s]", OutputRegisters[r]);
|
||||
else if (src->File == PROGRAM_OUTPUT) {
|
||||
_mesa_printf("o[%s]", OutputRegisters[src->Index]);
|
||||
}
|
||||
else if ((r = InputRegisterNumber(src->Register)) >= 0) {
|
||||
_mesa_printf("f[%s]", InputRegisters[r]);
|
||||
else if (src->File == PROGRAM_INPUT) {
|
||||
_mesa_printf("f[%s]", InputRegisters[src->Index]);
|
||||
}
|
||||
else if ((r = ProgramRegisterNumber(src->Register)) >= 0) {
|
||||
_mesa_printf("p[%d]", r);
|
||||
else if (src->File == PROGRAM_LOCAL_PARAM) {
|
||||
_mesa_printf("p[%d]", src->Index);
|
||||
}
|
||||
else if ((r = HalfTempRegisterNumber(src->Register)) >= 0) {
|
||||
_mesa_printf("H%d", r);
|
||||
else if (src->File == PROGRAM_TEMPORARY) {
|
||||
if (src->Index >= 32)
|
||||
_mesa_printf("H%d", src->Index);
|
||||
else
|
||||
_mesa_printf("R%d", src->Index);
|
||||
}
|
||||
else if ((r = TempRegisterNumber(src->Register)) >= 0) {
|
||||
_mesa_printf("R%d", r);
|
||||
}
|
||||
else if ((r = DummyRegisterNumber(src->Register)) >= 0) {
|
||||
_mesa_printf("%cC", "HR"[r]);
|
||||
else if (src->File == PROGRAM_WRITE_ONLY) {
|
||||
_mesa_printf("%cC", "HR"[src->Index]);
|
||||
}
|
||||
else {
|
||||
_mesa_problem(NULL, "Invalid fragment register %d", src->Register);
|
||||
_mesa_problem(NULL, "Invalid fragment register %d", src->Index);
|
||||
return;
|
||||
}
|
||||
if (src->Swizzle[0] == src->Swizzle[1] &&
|
||||
|
@ -1739,22 +1686,21 @@ PrintDstReg(const struct fp_dst_register *dst)
|
|||
{
|
||||
GLint w = dst->WriteMask[0] + dst->WriteMask[1]
|
||||
+ dst->WriteMask[2] + dst->WriteMask[3];
|
||||
GLint r;
|
||||
|
||||
if ((r = OutputRegisterNumber(dst->Register)) >= 0) {
|
||||
_mesa_printf("o[%s]", OutputRegisters[r]);
|
||||
if (dst->File == PROGRAM_OUTPUT) {
|
||||
_mesa_printf("o[%s]", OutputRegisters[dst->Index]);
|
||||
}
|
||||
else if ((r = HalfTempRegisterNumber(dst->Register)) >= 0) {
|
||||
_mesa_printf("H%d", r);
|
||||
else if (dst->File == PROGRAM_TEMPORARY) {
|
||||
if (dst->Index >= 32)
|
||||
_mesa_printf("H%d", dst->Index);
|
||||
else
|
||||
_mesa_printf("R%d", dst->Index);
|
||||
}
|
||||
else if ((r = TempRegisterNumber(dst->Register)) >= 0) {
|
||||
_mesa_printf("R%d", r);
|
||||
else if (dst->File == PROGRAM_LOCAL_PARAM) {
|
||||
_mesa_printf("p[%d]", dst->Index);
|
||||
}
|
||||
else if ((r = ProgramRegisterNumber(dst->Register)) >= 0) {
|
||||
_mesa_printf("p[%d]", r);
|
||||
}
|
||||
else if ((r = DummyRegisterNumber(dst->Register)) >= 0) {
|
||||
_mesa_printf("%cC", "HR"[r]);
|
||||
else if (dst->File == PROGRAM_WRITE_ONLY) {
|
||||
_mesa_printf("%cC", "HR"[dst->Index]);
|
||||
}
|
||||
else {
|
||||
_mesa_printf("???");
|
||||
|
|
|
@ -53,19 +53,6 @@
|
|||
#define FRAG_OUTPUT_DEPR 2
|
||||
|
||||
|
||||
/* Location of register sets within the whole register file */
|
||||
#define FP_INPUT_REG_START 0
|
||||
#define FP_INPUT_REG_END (FP_INPUT_REG_START + MAX_NV_FRAGMENT_PROGRAM_INPUTS - 1)
|
||||
#define FP_OUTPUT_REG_START (FP_INPUT_REG_END + 1)
|
||||
#define FP_OUTPUT_REG_END (FP_OUTPUT_REG_START + MAX_NV_FRAGMENT_PROGRAM_OUTPUTS - 1)
|
||||
#define FP_TEMP_REG_START (FP_OUTPUT_REG_END + 1)
|
||||
#define FP_TEMP_REG_END (FP_TEMP_REG_START + MAX_NV_FRAGMENT_PROGRAM_TEMPS - 1)
|
||||
#define FP_PROG_REG_START (FP_TEMP_REG_END + 1)
|
||||
#define FP_PROG_REG_END (FP_PROG_REG_START + MAX_NV_FRAGMENT_PROGRAM_PARAMS - 1)
|
||||
#define FP_DUMMY_REG_START (FP_PROG_REG_END + 1)
|
||||
#define FP_DUMMY_REG_END (FP_DUMMY_REG_START + MAX_NV_FRAGMENT_PROGRAM_WRITE_ONLYS - 1)
|
||||
|
||||
|
||||
/* condition codes */
|
||||
#define COND_GT 1 /* greater than zero */
|
||||
#define COND_EQ 2 /* equal to zero */
|
||||
|
@ -84,6 +71,7 @@
|
|||
#define FIXED12 0x4
|
||||
|
||||
|
||||
/* Fragment program instruction opcodes */
|
||||
enum fp_opcode {
|
||||
FP_OPCODE_ADD = 1000,
|
||||
FP_OPCODE_COS,
|
||||
|
@ -134,10 +122,11 @@ enum fp_opcode {
|
|||
};
|
||||
|
||||
|
||||
/* Instruction source register */
|
||||
struct fp_src_register
|
||||
{
|
||||
GLint Register; /* or the offset from the address register */
|
||||
GLboolean IsParameter; /* true if register refers to a param or constant */
|
||||
enum register_file File;
|
||||
GLint Index;
|
||||
GLuint Swizzle[4];
|
||||
GLboolean NegateBase; /* negate before absolute value? */
|
||||
GLboolean Abs; /* take absolute value? */
|
||||
|
@ -148,13 +137,15 @@ struct fp_src_register
|
|||
/* Instruction destination register */
|
||||
struct fp_dst_register
|
||||
{
|
||||
GLint 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;
|
||||
|
|
|
@ -48,29 +48,21 @@ static const GLfloat zeroVec[4] = { 0, 0, 0, 0 };
|
|||
void
|
||||
_mesa_init_vp_registers(GLcontext *ctx)
|
||||
{
|
||||
struct vp_machine *machine = &(ctx->VertexProgram.Machine);
|
||||
GLuint i;
|
||||
|
||||
/* Input registers get initialized from the current vertex attribs */
|
||||
MEMCPY(machine->Registers[VP_INPUT_REG_START],
|
||||
ctx->Current.Attrib,
|
||||
16 * 4 * sizeof(GLfloat));
|
||||
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 = VP_OUTPUT_REG_START; i <= VP_OUTPUT_REG_END; i++) {
|
||||
machine->Registers[i][0] = 0.0F;
|
||||
machine->Registers[i][1] = 0.0F;
|
||||
machine->Registers[i][2] = 0.0F;
|
||||
machine->Registers[i][3] = 1.0F;
|
||||
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 = VP_TEMP_REG_START; i <= VP_TEMP_REG_END; i++) {
|
||||
machine->Registers[i][0] = 0.0F;
|
||||
machine->Registers[i][1] = 0.0F;
|
||||
machine->Registers[i][2] = 0.0F;
|
||||
machine->Registers[i][3] = 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 regs aren't touched */
|
||||
/* The program parameters aren't touched */
|
||||
}
|
||||
|
||||
|
||||
|
@ -83,7 +75,6 @@ static void
|
|||
load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16])
|
||||
{
|
||||
GLuint i;
|
||||
pos += VP_PROG_REG_START;
|
||||
for (i = 0; i < 4; i++) {
|
||||
registers[pos + i][0] = mat[0 + i];
|
||||
registers[pos + i][1] = mat[4 + i];
|
||||
|
@ -100,7 +91,6 @@ static void
|
|||
load_transpose_matrix(GLfloat registers[][4], GLuint pos,
|
||||
const GLfloat mat[16])
|
||||
{
|
||||
pos += VP_PROG_REG_START;
|
||||
MEMCPY(registers[pos], mat, 16 * sizeof(GLfloat));
|
||||
}
|
||||
|
||||
|
@ -114,7 +104,7 @@ _mesa_init_tracked_matrices(GLcontext *ctx)
|
|||
{
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < VP_NUM_PROG_REGS / 4; 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) {
|
||||
|
@ -147,23 +137,22 @@ _mesa_init_tracked_matrices(GLcontext *ctx)
|
|||
|
||||
/* load the matrix */
|
||||
if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) {
|
||||
load_matrix(ctx->VertexProgram.Machine.Registers, i*4, mat->m);
|
||||
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.Machine.Registers, i*4, mat->inv);
|
||||
load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
|
||||
}
|
||||
else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) {
|
||||
load_transpose_matrix(ctx->VertexProgram.Machine.Registers, i*4, mat->m);
|
||||
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.Machine.Registers,
|
||||
i*4, mat->inv);
|
||||
load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,72 +163,103 @@ _mesa_init_tracked_matrices(GLcontext *ctx)
|
|||
* For debugging. Dump the current vertex program machine registers.
|
||||
*/
|
||||
void
|
||||
_mesa_dump_vp_machine( const struct vp_machine *machine )
|
||||
_mesa_dump_vp_state( const struct vertex_program_state *state )
|
||||
{
|
||||
int i;
|
||||
_mesa_printf("VertexIn:\n");
|
||||
for (i = 0; i < VP_NUM_INPUT_REGS; i++) {
|
||||
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_INPUTS; i++) {
|
||||
_mesa_printf("%d: %f %f %f %f ", i,
|
||||
machine->Registers[i + VP_INPUT_REG_START][0],
|
||||
machine->Registers[i + VP_INPUT_REG_START][1],
|
||||
machine->Registers[i + VP_INPUT_REG_START][2],
|
||||
machine->Registers[i + VP_INPUT_REG_START][3]);
|
||||
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 < VP_NUM_OUTPUT_REGS; i++) {
|
||||
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) {
|
||||
_mesa_printf("%d: %f %f %f %f ", i,
|
||||
machine->Registers[i + VP_OUTPUT_REG_START][0],
|
||||
machine->Registers[i + VP_OUTPUT_REG_START][1],
|
||||
machine->Registers[i + VP_OUTPUT_REG_START][2],
|
||||
machine->Registers[i + VP_OUTPUT_REG_START][3]);
|
||||
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 < VP_NUM_TEMP_REGS; i++) {
|
||||
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) {
|
||||
_mesa_printf("%d: %f %f %f %f ", i,
|
||||
machine->Registers[i + VP_TEMP_REG_START][0],
|
||||
machine->Registers[i + VP_TEMP_REG_START][1],
|
||||
machine->Registers[i + VP_TEMP_REG_START][2],
|
||||
machine->Registers[i + VP_TEMP_REG_START][3]);
|
||||
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 < VP_NUM_PROG_REGS; i++) {
|
||||
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) {
|
||||
_mesa_printf("%d: %f %f %f %f ", i,
|
||||
machine->Registers[i + VP_PROG_REG_START][0],
|
||||
machine->Registers[i + VP_PROG_REG_START][1],
|
||||
machine->Registers[i + VP_PROG_REG_START][2],
|
||||
machine->Registers[i + VP_PROG_REG_START][3]);
|
||||
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);
|
||||
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:
|
||||
/* XXX fix */
|
||||
return NULL;
|
||||
break;
|
||||
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 void
|
||||
static INLINE void
|
||||
fetch_vector4( const struct vp_src_register *source,
|
||||
const struct vp_machine *machine,
|
||||
const struct vertex_program_state *state,
|
||||
GLfloat result[4] )
|
||||
{
|
||||
const GLfloat *src;
|
||||
|
||||
if (source->RelAddr) {
|
||||
const GLint reg = source->Register + machine->AddressReg;
|
||||
if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
|
||||
src = zeroVec;
|
||||
else
|
||||
src = machine->Registers[VP_PROG_REG_START + reg];
|
||||
}
|
||||
else {
|
||||
src = machine->Registers[source->Register];
|
||||
}
|
||||
const GLfloat *src = get_register_pointer(source, state);
|
||||
|
||||
if (source->Negate) {
|
||||
result[0] = -src[source->Swizzle[0]];
|
||||
|
@ -256,26 +276,16 @@ fetch_vector4( const struct vp_src_register *source,
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* As above, but only return result[0] element.
|
||||
*/
|
||||
static void
|
||||
static INLINE void
|
||||
fetch_vector1( const struct vp_src_register *source,
|
||||
const struct vp_machine *machine,
|
||||
const struct vertex_program_state *state,
|
||||
GLfloat result[4] )
|
||||
{
|
||||
const GLfloat *src;
|
||||
|
||||
if (source->RelAddr) {
|
||||
const GLint reg = source->Register + machine->AddressReg;
|
||||
if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
|
||||
src = zeroVec;
|
||||
else
|
||||
src = machine->Registers[VP_PROG_REG_START + reg];
|
||||
}
|
||||
else {
|
||||
src = machine->Registers[source->Register];
|
||||
}
|
||||
const GLfloat *src = get_register_pointer(source, state);
|
||||
|
||||
if (source->Negate) {
|
||||
result[0] = -src[source->Swizzle[0]];
|
||||
|
@ -290,10 +300,22 @@ fetch_vector1( const struct vp_src_register *source,
|
|||
* Store 4 floats into a register.
|
||||
*/
|
||||
static void
|
||||
store_vector4( const struct vp_dst_register *dest, struct vp_machine *machine,
|
||||
store_vector4( const struct vp_dst_register *dest,
|
||||
struct vertex_program_state *state,
|
||||
const GLfloat value[4] )
|
||||
{
|
||||
GLfloat *dst = machine->Registers[dest->Register];
|
||||
GLfloat *dst;
|
||||
switch (dest->File) {
|
||||
case PROGRAM_TEMPORARY:
|
||||
dst = state->Temporaries[dest->Index];
|
||||
break;
|
||||
case PROGRAM_OUTPUT:
|
||||
dst = state->Outputs[dest->Index];
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(NULL, "Invalid register file in fetch_vector1(vp)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (dest->WriteMask[0])
|
||||
dst[0] = value[0];
|
||||
|
@ -329,7 +351,7 @@ store_vector4( const struct vp_dst_register *dest, struct vp_machine *machine,
|
|||
void
|
||||
_mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
|
||||
{
|
||||
struct vp_machine *machine = &ctx->VertexProgram.Machine;
|
||||
struct vertex_program_state *state = &ctx->VertexProgram;
|
||||
const struct vp_instruction *inst;
|
||||
|
||||
ctx->_CurrentProgram = GL_VERTEX_PROGRAM_ARB; /* or NV, doesn't matter */
|
||||
|
@ -347,15 +369,15 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
|
|||
case VP_OPCODE_MOV:
|
||||
{
|
||||
GLfloat t[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
store_vector4( &inst->DstReg, machine, t );
|
||||
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], machine, t );
|
||||
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)
|
||||
|
@ -368,32 +390,32 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
|
|||
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, machine, lit );
|
||||
store_vector4( &inst->DstReg, state, lit );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_RCP:
|
||||
{
|
||||
GLfloat t[4];
|
||||
fetch_vector1( &inst->SrcReg[0], machine, t );
|
||||
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, machine, t );
|
||||
store_vector4( &inst->DstReg, state, t );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_RSQ:
|
||||
{
|
||||
GLfloat t[4];
|
||||
fetch_vector1( &inst->SrcReg[0], machine, t );
|
||||
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, machine, t );
|
||||
store_vector4( &inst->DstReg, state, t );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_EXP:
|
||||
{
|
||||
GLfloat t[4], q[4], floor_t0;
|
||||
fetch_vector1( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector1( &inst->SrcReg[0], state, t );
|
||||
floor_t0 = (float) floor(t[0]);
|
||||
if (floor_t0 > FLT_MAX_EXP) {
|
||||
SET_POS_INFINITY(q[0]);
|
||||
|
@ -416,13 +438,13 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
|
|||
}
|
||||
q[1] = t[0] - floor_t0;
|
||||
q[3] = 1.0F;
|
||||
store_vector4( &inst->DstReg, machine, q );
|
||||
store_vector4( &inst->DstReg, state, q );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_LOG:
|
||||
{
|
||||
GLfloat t[4], q[4], abs_t0;
|
||||
fetch_vector1( &inst->SrcReg[0], machine, t );
|
||||
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
|
||||
|
@ -453,147 +475,147 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
|
|||
SET_NEG_INFINITY(q[2]);
|
||||
}
|
||||
q[3] = 1.0;
|
||||
store_vector4( &inst->DstReg, machine, q );
|
||||
store_vector4( &inst->DstReg, state, q );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_MUL:
|
||||
{
|
||||
GLfloat t[4], u[4], prod[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, prod );
|
||||
store_vector4( &inst->DstReg, state, prod );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_ADD:
|
||||
{
|
||||
GLfloat t[4], u[4], sum[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, sum );
|
||||
store_vector4( &inst->DstReg, state, sum );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_DP3:
|
||||
{
|
||||
GLfloat t[4], u[4], dot[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, dot );
|
||||
store_vector4( &inst->DstReg, state, dot );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_DP4:
|
||||
{
|
||||
GLfloat t[4], u[4], dot[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, dot );
|
||||
store_vector4( &inst->DstReg, state, dot );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_DST:
|
||||
{
|
||||
GLfloat t[4], u[4], dst[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, dst );
|
||||
store_vector4( &inst->DstReg, state, dst );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_MIN:
|
||||
{
|
||||
GLfloat t[4], u[4], min[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, min );
|
||||
store_vector4( &inst->DstReg, state, min );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_MAX:
|
||||
{
|
||||
GLfloat t[4], u[4], max[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, max );
|
||||
store_vector4( &inst->DstReg, state, max );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_SLT:
|
||||
{
|
||||
GLfloat t[4], u[4], slt[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, slt );
|
||||
store_vector4( &inst->DstReg, state, slt );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_SGE:
|
||||
{
|
||||
GLfloat t[4], u[4], sge[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, sge );
|
||||
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], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
fetch_vector4( &inst->SrcReg[2], machine, v );
|
||||
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, machine, sum );
|
||||
store_vector4( &inst->DstReg, state, sum );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_ARL:
|
||||
{
|
||||
GLfloat t[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
machine->AddressReg = (GLint) floor(t[0]);
|
||||
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], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, dot );
|
||||
store_vector4( &inst->DstReg, state, dot );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_RCC:
|
||||
{
|
||||
GLfloat t[4], u;
|
||||
fetch_vector1( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector1( &inst->SrcReg[0], state, t );
|
||||
if (t[0] == 1.0F)
|
||||
u = 1.0F;
|
||||
else
|
||||
|
@ -615,110 +637,98 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
|
|||
}
|
||||
}
|
||||
t[0] = t[1] = t[2] = t[3] = u;
|
||||
store_vector4( &inst->DstReg, machine, t );
|
||||
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], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, sum );
|
||||
store_vector4( &inst->DstReg, state, sum );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_ABS: /* GL_NV_vertex_program1_1 */
|
||||
{
|
||||
GLfloat t[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
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, machine, t );
|
||||
store_vector4( &inst->DstReg, state, t );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_FLR: /* GL_ARB_vertex_program */
|
||||
{
|
||||
GLfloat t[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
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, machine, t );
|
||||
store_vector4( &inst->DstReg, state, t );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_FRC: /* GL_ARB_vertex_program */
|
||||
{
|
||||
GLfloat t[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, t );
|
||||
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, machine, t );
|
||||
store_vector4( &inst->DstReg, state, t );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_EX2: /* GL_ARB_vertex_program */
|
||||
{
|
||||
GLfloat t[4];
|
||||
fetch_vector1( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector1( &inst->SrcReg[0], state, t );
|
||||
t[0] = t[1] = t[2] = t[3] = _mesa_pow(2.0, t[0]);
|
||||
store_vector4( &inst->DstReg, machine, t );
|
||||
store_vector4( &inst->DstReg, state, t );
|
||||
}
|
||||
break;
|
||||
case VP_OPCODE_LG2: /* GL_ARB_vertex_program */
|
||||
{
|
||||
GLfloat t[4];
|
||||
fetch_vector1( &inst->SrcReg[0], machine, t );
|
||||
fetch_vector1( &inst->SrcReg[0], state, t );
|
||||
t[0] = t[1] = t[2] = t[3] = LOG2(t[0]);
|
||||
store_vector4( &inst->DstReg, machine, t );
|
||||
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], machine, t );
|
||||
fetch_vector1( &inst->SrcReg[1], machine, u );
|
||||
fetch_vector1( &inst->SrcReg[0], state, t );
|
||||
fetch_vector1( &inst->SrcReg[1], state, u );
|
||||
t[0] = t[1] = t[2] = t[3] = _mesa_pow(t[0], u[0]);
|
||||
store_vector4( &inst->DstReg, machine, t );
|
||||
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], machine, t );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, u );
|
||||
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, machine, cross );
|
||||
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;
|
||||
const GLfloat *src = get_register_pointer(source, state);
|
||||
GLfloat result[4];
|
||||
GLuint i;
|
||||
|
||||
/* Code similar to fetch_vector4() */
|
||||
if (source->RelAddr) {
|
||||
const GLint reg = source->Register + machine->AddressReg;
|
||||
if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
|
||||
src = zeroVec;
|
||||
else
|
||||
src = machine->Registers[VP_PROG_REG_START + reg];
|
||||
}
|
||||
else {
|
||||
src = machine->Registers[source->Register];
|
||||
}
|
||||
|
||||
/* extended swizzling here */
|
||||
/* do extended swizzling here */
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (source->Swizzle[i] == SWIZZLE_ZERO)
|
||||
result[i] = 0.0;
|
||||
|
@ -729,7 +739,7 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
|
|||
if (source->Negate)
|
||||
result[i] = -result[i];
|
||||
}
|
||||
store_vector4( &inst->DstReg, machine, result );
|
||||
store_vector4( &inst->DstReg, state, result );
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -38,6 +38,6 @@ extern void
|
|||
_mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program);
|
||||
|
||||
extern void
|
||||
_mesa_dump_vp_machine( const struct vp_machine *machine );
|
||||
_mesa_dump_vp_state( const struct vertex_program_state *state );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,7 +54,7 @@ struct parse_state {
|
|||
GLboolean isVersion1_1;
|
||||
GLuint inputsRead;
|
||||
GLuint outputsWritten;
|
||||
GLuint progRegsWritten;
|
||||
GLboolean anyProgRegsWritten;
|
||||
GLuint numInst; /* number of instructions parsed */
|
||||
};
|
||||
|
||||
|
@ -282,33 +282,18 @@ static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {
|
|||
"TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
|
||||
};
|
||||
|
||||
/* NOTE: the order here must match opcodes in nvvertprog.h */
|
||||
static const char *Opcodes[] = {
|
||||
"MOV", "LIT", "RCP", "RSQ", "EXP", "LOG", "MUL", "ADD", "DP3", "DP4",
|
||||
"DST", "MIN", "MAX", "SLT", "SGE", "MAD", "ARL", "DPH", "RCC", "SUB",
|
||||
"ABS", "END", NULL
|
||||
"ABS", "END",
|
||||
/* GL_ARB_vertex_program */
|
||||
"FLR", "FRC", "EX2", "LG2", "POW", "XPD", "SWZ",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
|
||||
static GLuint
|
||||
IsProgRegister(GLuint r)
|
||||
{
|
||||
return (GLuint) (r >= VP_PROG_REG_START && r <= VP_PROG_REG_END);
|
||||
}
|
||||
|
||||
static GLuint
|
||||
IsInputRegister(GLuint r)
|
||||
{
|
||||
return (GLuint) (r >= VP_INPUT_REG_START && r <= VP_INPUT_REG_END);
|
||||
}
|
||||
|
||||
static GLuint
|
||||
IsOutputRegister(GLuint r)
|
||||
{
|
||||
return (GLuint) (r >= VP_OUTPUT_REG_START && r <= VP_OUTPUT_REG_END);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a temporary register: Rnn
|
||||
*/
|
||||
|
@ -325,9 +310,9 @@ Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
|
|||
|
||||
if (IsDigit(token[1])) {
|
||||
GLint reg = _mesa_atoi((char *) (token + 1));
|
||||
if (reg >= VP_NUM_TEMP_REGS)
|
||||
if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS)
|
||||
RETURN_ERROR1("Bad temporary register name");
|
||||
*tempRegNum = VP_TEMP_REG_START + reg;
|
||||
*tempRegNum = reg;
|
||||
}
|
||||
else {
|
||||
RETURN_ERROR1("Bad temporary register name");
|
||||
|
@ -379,9 +364,9 @@ Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum)
|
|||
if (IsDigit(token[0])) {
|
||||
/* a numbered program parameter register */
|
||||
GLint reg = _mesa_atoi((char *) token);
|
||||
if (reg >= VP_NUM_PROG_REGS)
|
||||
RETURN_ERROR1("Bad constant program number");
|
||||
*regNum = VP_PROG_REG_START + reg;
|
||||
if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
|
||||
RETURN_ERROR1("Bad program parameter number");
|
||||
*regNum = reg;
|
||||
}
|
||||
else {
|
||||
RETURN_ERROR;
|
||||
|
@ -413,9 +398,10 @@ Parse_ParamReg(struct parse_state *parseState, struct vp_src_register *srcReg)
|
|||
GLint reg;
|
||||
(void) Parse_Token(parseState, token);
|
||||
reg = _mesa_atoi((char *) token);
|
||||
if (reg >= VP_NUM_PROG_REGS)
|
||||
RETURN_ERROR1("Bad constant program number");
|
||||
srcReg->Register = VP_PROG_REG_START + reg;
|
||||
if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
|
||||
RETURN_ERROR1("Bad program parameter number");
|
||||
srcReg->File = PROGRAM_ENV_PARAM;
|
||||
srcReg->Index = reg;
|
||||
}
|
||||
else if (_mesa_strcmp((const char *) token, "A0") == 0) {
|
||||
/* address register "A0.x" */
|
||||
|
@ -423,8 +409,7 @@ Parse_ParamReg(struct parse_state *parseState, struct vp_src_register *srcReg)
|
|||
RETURN_ERROR;
|
||||
|
||||
srcReg->RelAddr = GL_TRUE;
|
||||
srcReg->Register = 0;
|
||||
|
||||
srcReg->File = PROGRAM_ENV_PARAM;
|
||||
/* Look for +/-N offset */
|
||||
if (!Peek_Token(parseState, token))
|
||||
RETURN_ERROR;
|
||||
|
@ -442,12 +427,12 @@ Parse_ParamReg(struct parse_state *parseState, struct vp_src_register *srcReg)
|
|||
if (sign == '-') {
|
||||
if (k > 64)
|
||||
RETURN_ERROR1("Bad address offset");
|
||||
srcReg->Register = -k;
|
||||
srcReg->Index = -k;
|
||||
}
|
||||
else {
|
||||
if (k > 63)
|
||||
RETURN_ERROR1("Bad address offset");
|
||||
srcReg->Register = k;
|
||||
srcReg->Index = k;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -496,14 +481,14 @@ Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum)
|
|||
|
||||
if (IsDigit(token[0])) {
|
||||
GLint reg = _mesa_atoi((char *) token);
|
||||
if (reg >= VP_NUM_INPUT_REGS)
|
||||
if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS)
|
||||
RETURN_ERROR1("Bad vertex attribute register name");
|
||||
*tempRegNum = VP_INPUT_REG_START + reg;
|
||||
*tempRegNum = reg;
|
||||
}
|
||||
else {
|
||||
for (j = 0; InputRegisters[j]; j++) {
|
||||
if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) {
|
||||
*tempRegNum = VP_INPUT_REG_START + j;
|
||||
*tempRegNum = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -547,7 +532,7 @@ Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
|
|||
/* try to match an output register name */
|
||||
for (j = start; OutputRegisters[j]; j++) {
|
||||
if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) {
|
||||
*outputRegNum = VP_OUTPUT_REG_START + j;
|
||||
*outputRegNum = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -573,17 +558,20 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstRe
|
|||
|
||||
if (token[0] == 'R') {
|
||||
/* a temporary register */
|
||||
if (!Parse_TempReg(parseState, &dstReg->Register))
|
||||
dstReg->File = PROGRAM_TEMPORARY;
|
||||
if (!Parse_TempReg(parseState, &dstReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else if (!parseState->isStateProgram && token[0] == 'o') {
|
||||
/* an output register */
|
||||
if (!Parse_OutputReg(parseState, &dstReg->Register))
|
||||
dstReg->File = PROGRAM_OUTPUT;
|
||||
if (!Parse_OutputReg(parseState, &dstReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else if (parseState->isStateProgram && token[0] == 'c') {
|
||||
/* absolute program parameter register */
|
||||
if (!Parse_AbsParamReg(parseState, &dstReg->Register))
|
||||
dstReg->File = PROGRAM_ENV_PARAM;
|
||||
if (!Parse_AbsParamReg(parseState, &dstReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else {
|
||||
|
@ -662,7 +650,8 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR
|
|||
|
||||
/* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
|
||||
if (token[0] == 'R') {
|
||||
if (!Parse_TempReg(parseState, &srcReg->Register))
|
||||
srcReg->File = PROGRAM_TEMPORARY;
|
||||
if (!Parse_TempReg(parseState, &srcReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else if (token[0] == 'c') {
|
||||
|
@ -670,7 +659,8 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR
|
|||
RETURN_ERROR;
|
||||
}
|
||||
else if (token[0] == 'v') {
|
||||
if (!Parse_AttribReg(parseState, &srcReg->Register))
|
||||
srcReg->File = PROGRAM_INPUT;
|
||||
if (!Parse_AttribReg(parseState, &srcReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else {
|
||||
|
@ -751,7 +741,8 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe
|
|||
|
||||
/* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
|
||||
if (token[0] == 'R') {
|
||||
if (!Parse_TempReg(parseState, &srcReg->Register))
|
||||
srcReg->File = PROGRAM_TEMPORARY;
|
||||
if (!Parse_TempReg(parseState, &srcReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else if (token[0] == 'c') {
|
||||
|
@ -759,7 +750,8 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe
|
|||
RETURN_ERROR;
|
||||
}
|
||||
else if (token[0] == 'v') {
|
||||
if (!Parse_AttribReg(parseState, &srcReg->Register))
|
||||
srcReg->File = PROGRAM_INPUT;
|
||||
if (!Parse_AttribReg(parseState, &srcReg->Index))
|
||||
RETURN_ERROR;
|
||||
}
|
||||
else {
|
||||
|
@ -861,15 +853,15 @@ Parse_BiOpInstruction(struct parse_state *parseState,
|
|||
RETURN_ERROR;
|
||||
|
||||
/* make sure we don't reference more than one program parameter register */
|
||||
if (IsProgRegister(inst->SrcReg[0].Register) &&
|
||||
IsProgRegister(inst->SrcReg[1].Register) &&
|
||||
inst->SrcReg[0].Register != inst->SrcReg[1].Register)
|
||||
if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
|
||||
inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
|
||||
inst->SrcReg[0].Index != inst->SrcReg[1].Index)
|
||||
RETURN_ERROR1("Can't reference two program parameter registers");
|
||||
|
||||
/* make sure we don't reference more than one vertex attribute register */
|
||||
if (IsInputRegister(inst->SrcReg[0].Register) &&
|
||||
IsInputRegister(inst->SrcReg[1].Register) &&
|
||||
inst->SrcReg[0].Register != inst->SrcReg[1].Register)
|
||||
if (inst->SrcReg[0].File == PROGRAM_INPUT &&
|
||||
inst->SrcReg[1].File == PROGRAM_INPUT &&
|
||||
inst->SrcReg[0].Index != inst->SrcReg[1].Index)
|
||||
RETURN_ERROR1("Can't reference two vertex attribute registers");
|
||||
|
||||
return GL_TRUE;
|
||||
|
@ -916,27 +908,27 @@ Parse_TriOpInstruction(struct parse_state *parseState,
|
|||
RETURN_ERROR;
|
||||
|
||||
/* make sure we don't reference more than one program parameter register */
|
||||
if ((IsProgRegister(inst->SrcReg[0].Register) &&
|
||||
IsProgRegister(inst->SrcReg[1].Register) &&
|
||||
inst->SrcReg[0].Register != inst->SrcReg[1].Register) ||
|
||||
(IsProgRegister(inst->SrcReg[0].Register) &&
|
||||
IsProgRegister(inst->SrcReg[2].Register) &&
|
||||
inst->SrcReg[0].Register != inst->SrcReg[2].Register) ||
|
||||
(IsProgRegister(inst->SrcReg[1].Register) &&
|
||||
IsProgRegister(inst->SrcReg[2].Register) &&
|
||||
inst->SrcReg[1].Register != inst->SrcReg[2].Register))
|
||||
if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
|
||||
inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
|
||||
inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
|
||||
(inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
|
||||
inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
|
||||
inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
|
||||
(inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
|
||||
inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
|
||||
inst->SrcReg[1].Index != inst->SrcReg[2].Index))
|
||||
RETURN_ERROR1("Can only reference one program register");
|
||||
|
||||
/* make sure we don't reference more than one vertex attribute register */
|
||||
if ((IsInputRegister(inst->SrcReg[0].Register) &&
|
||||
IsInputRegister(inst->SrcReg[1].Register) &&
|
||||
inst->SrcReg[0].Register != inst->SrcReg[1].Register) ||
|
||||
(IsInputRegister(inst->SrcReg[0].Register) &&
|
||||
IsInputRegister(inst->SrcReg[2].Register) &&
|
||||
inst->SrcReg[0].Register != inst->SrcReg[2].Register) ||
|
||||
(IsInputRegister(inst->SrcReg[1].Register) &&
|
||||
IsInputRegister(inst->SrcReg[2].Register) &&
|
||||
inst->SrcReg[1].Register != inst->SrcReg[2].Register))
|
||||
if ((inst->SrcReg[0].File == PROGRAM_INPUT &&
|
||||
inst->SrcReg[1].File == PROGRAM_INPUT &&
|
||||
inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
|
||||
(inst->SrcReg[0].File == PROGRAM_INPUT &&
|
||||
inst->SrcReg[2].File == PROGRAM_INPUT &&
|
||||
inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
|
||||
(inst->SrcReg[1].File == PROGRAM_INPUT &&
|
||||
inst->SrcReg[2].File == PROGRAM_INPUT &&
|
||||
inst->SrcReg[1].Index != inst->SrcReg[2].Index))
|
||||
RETURN_ERROR1("Can only reference one input register");
|
||||
|
||||
return GL_TRUE;
|
||||
|
@ -1042,10 +1034,10 @@ Parse_InstructionSequence(struct parse_state *parseState,
|
|||
struct vp_instruction *inst = program + parseState->numInst;
|
||||
|
||||
/* Initialize the instruction */
|
||||
inst->SrcReg[0].Register = -1;
|
||||
inst->SrcReg[1].Register = -1;
|
||||
inst->SrcReg[2].Register = -1;
|
||||
inst->DstReg.Register = -1;
|
||||
inst->SrcReg[0].File = -1;
|
||||
inst->SrcReg[1].File = -1;
|
||||
inst->SrcReg[2].File = -1;
|
||||
inst->DstReg.File = -1;
|
||||
|
||||
if (Parse_String(parseState, "MOV")) {
|
||||
if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_MOV))
|
||||
|
@ -1145,26 +1137,17 @@ Parse_InstructionSequence(struct parse_state *parseState,
|
|||
}
|
||||
|
||||
/* examine input/output registers */
|
||||
{
|
||||
const GLint srcReg0 = inst->SrcReg[0].Register;
|
||||
const GLint srcReg1 = inst->SrcReg[1].Register;
|
||||
const GLint srcReg2 = inst->SrcReg[2].Register;
|
||||
const GLint dstReg = inst->DstReg.Register;
|
||||
if (inst->DstReg.File == PROGRAM_OUTPUT)
|
||||
parseState->outputsWritten |= (1 << inst->DstReg.Index);
|
||||
else if (inst->DstReg.File == PROGRAM_ENV_PARAM)
|
||||
parseState->anyProgRegsWritten = GL_TRUE;
|
||||
|
||||
if (IsOutputRegister(dstReg))
|
||||
parseState->outputsWritten |= (1 << (dstReg - VP_OUTPUT_REG_START));
|
||||
else if (IsProgRegister(dstReg))
|
||||
parseState->progRegsWritten |= (1 << (dstReg - VP_PROG_REG_START));
|
||||
|
||||
if (IsInputRegister(srcReg0) && !inst->SrcReg[0].RelAddr)
|
||||
parseState->inputsRead |= (1 << (srcReg0 - VP_INPUT_REG_START));
|
||||
|
||||
if (IsInputRegister(srcReg1) && !inst->SrcReg[1].RelAddr)
|
||||
parseState->inputsRead |= (1 << (srcReg1 - VP_INPUT_REG_START));
|
||||
|
||||
if (IsInputRegister(srcReg2) && !inst->SrcReg[2].RelAddr)
|
||||
parseState->inputsRead |= (1 << (srcReg2 - VP_INPUT_REG_START));
|
||||
}
|
||||
if (inst->SrcReg[0].File == PROGRAM_INPUT)
|
||||
parseState->inputsRead |= (1 << inst->SrcReg[0].Index);
|
||||
if (inst->SrcReg[1].File == PROGRAM_INPUT)
|
||||
parseState->inputsRead |= (1 << inst->SrcReg[1].Index);
|
||||
if (inst->SrcReg[2].File == PROGRAM_INPUT)
|
||||
parseState->inputsRead |= (1 << inst->SrcReg[2].Index);
|
||||
|
||||
parseState->numInst++;
|
||||
|
||||
|
@ -1222,7 +1205,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
|
|||
parseState.numInst = 0;
|
||||
parseState.inputsRead = 0;
|
||||
parseState.outputsWritten = 0;
|
||||
parseState.progRegsWritten = 0;
|
||||
parseState.anyProgRegsWritten = GL_FALSE;
|
||||
|
||||
/* Reset error state */
|
||||
_mesa_set_program_error(ctx, -1, NULL);
|
||||
|
@ -1263,7 +1246,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
|
|||
/* successful parse! */
|
||||
|
||||
if (parseState.isStateProgram) {
|
||||
if (parseState.progRegsWritten == 0) {
|
||||
if (!parseState.anyProgRegsWritten) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glLoadProgramNV(c[#] not written)");
|
||||
return;
|
||||
|
@ -1331,27 +1314,25 @@ PrintSrcReg(const struct vp_src_register *src)
|
|||
if (src->Negate)
|
||||
_mesa_printf("-");
|
||||
if (src->RelAddr) {
|
||||
if (src->Register > 0)
|
||||
_mesa_printf("c[A0.x + %d]", src->Register);
|
||||
else if (src->Register < 0)
|
||||
_mesa_printf("c[A0.x - %d]", -src->Register);
|
||||
if (src->Index > 0)
|
||||
_mesa_printf("c[A0.x + %d]", src->Index);
|
||||
else if (src->Index < 0)
|
||||
_mesa_printf("c[A0.x - %d]", -src->Index);
|
||||
else
|
||||
_mesa_printf("c[A0.x]");
|
||||
}
|
||||
else if (src->Register >= VP_OUTPUT_REG_START
|
||||
&& src->Register <= VP_OUTPUT_REG_END) {
|
||||
_mesa_printf("o[%s]", OutputRegisters[src->Register - VP_OUTPUT_REG_START]);
|
||||
else if (src->File == PROGRAM_OUTPUT) {
|
||||
_mesa_printf("o[%s]", OutputRegisters[src->Index]);
|
||||
}
|
||||
else if (src->Register >= VP_INPUT_REG_START
|
||||
&& src->Register <= VP_INPUT_REG_END) {
|
||||
_mesa_printf("v[%s]", InputRegisters[src->Register - VP_INPUT_REG_START]);
|
||||
else if (src->File == PROGRAM_INPUT) {
|
||||
_mesa_printf("v[%s]", InputRegisters[src->Index]);
|
||||
}
|
||||
else if (src->Register >= VP_PROG_REG_START
|
||||
&& src->Register <= VP_PROG_REG_END) {
|
||||
_mesa_printf("c[%d]", src->Register - VP_PROG_REG_START);
|
||||
else if (src->File == PROGRAM_ENV_PARAM) {
|
||||
_mesa_printf("c[%d]", src->Index);
|
||||
}
|
||||
else {
|
||||
_mesa_printf("R%d", src->Register - VP_TEMP_REG_START);
|
||||
ASSERT(src->File == PROGRAM_TEMPORARY);
|
||||
_mesa_printf("R%d", src->Index);
|
||||
}
|
||||
|
||||
if (src->Swizzle[0] == src->Swizzle[1] &&
|
||||
|
@ -1378,20 +1359,18 @@ PrintDstReg(const struct vp_dst_register *dst)
|
|||
GLint w = dst->WriteMask[0] + dst->WriteMask[1]
|
||||
+ dst->WriteMask[2] + dst->WriteMask[3];
|
||||
|
||||
if (dst->Register >= VP_OUTPUT_REG_START
|
||||
&& dst->Register <= VP_OUTPUT_REG_END) {
|
||||
_mesa_printf("o[%s]", OutputRegisters[dst->Register - VP_OUTPUT_REG_START]);
|
||||
if (dst->File == PROGRAM_OUTPUT) {
|
||||
_mesa_printf("o[%s]", OutputRegisters[dst->Index]);
|
||||
}
|
||||
else if (dst->Register >= VP_INPUT_REG_START
|
||||
&& dst->Register <= VP_INPUT_REG_END) {
|
||||
_mesa_printf("v[%s]", InputRegisters[dst->Register - VP_INPUT_REG_START]);
|
||||
else if (dst->File == PROGRAM_INPUT) {
|
||||
_mesa_printf("v[%s]", InputRegisters[dst->Index]);
|
||||
}
|
||||
else if (dst->Register >= VP_PROG_REG_START
|
||||
&& dst->Register <= VP_PROG_REG_END) {
|
||||
_mesa_printf("c[%d]", dst->Register - VP_PROG_REG_START);
|
||||
else if (dst->File == PROGRAM_ENV_PARAM) {
|
||||
_mesa_printf("c[%d]", dst->Index);
|
||||
}
|
||||
else {
|
||||
_mesa_printf("R%d", dst->Register - VP_TEMP_REG_START);
|
||||
ASSERT(dst->File == PROGRAM_TEMPORARY);
|
||||
_mesa_printf("R%d", dst->Index);
|
||||
}
|
||||
|
||||
if (w != 0 && w != 4) {
|
||||
|
|
|
@ -32,22 +32,6 @@
|
|||
#define NVVERTPROG_H
|
||||
|
||||
|
||||
#define VP_NUM_INPUT_REGS MAX_NV_VERTEX_PROGRAM_INPUTS
|
||||
#define VP_NUM_OUTPUT_REGS MAX_NV_VERTEX_PROGRAM_OUTPUTS
|
||||
#define VP_NUM_TEMP_REGS MAX_NV_VERTEX_PROGRAM_TEMPS
|
||||
#define VP_NUM_PROG_REGS MAX_NV_VERTEX_PROGRAM_PARAMS
|
||||
|
||||
/* Location of register groups within the whole register file */
|
||||
#define VP_INPUT_REG_START 0
|
||||
#define VP_INPUT_REG_END (VP_INPUT_REG_START + VP_NUM_INPUT_REGS - 1)
|
||||
#define VP_OUTPUT_REG_START (VP_INPUT_REG_END + 1)
|
||||
#define VP_OUTPUT_REG_END (VP_OUTPUT_REG_START + VP_NUM_OUTPUT_REGS - 1)
|
||||
#define VP_TEMP_REG_START (VP_OUTPUT_REG_END + 1)
|
||||
#define VP_TEMP_REG_END (VP_TEMP_REG_START + VP_NUM_TEMP_REGS - 1)
|
||||
#define VP_PROG_REG_START (VP_TEMP_REG_END + 1)
|
||||
#define VP_PROG_REG_END (VP_PROG_REG_START + VP_NUM_PROG_REGS - 1)
|
||||
|
||||
|
||||
/* for GL_ARB_v_p SWZ instruction */
|
||||
#define SWIZZLE_ZERO 100
|
||||
#define SWIZZLE_ONE 101
|
||||
|
@ -89,10 +73,12 @@ enum vp_opcode
|
|||
};
|
||||
|
||||
|
||||
|
||||
/* Instruction source register */
|
||||
struct vp_src_register
|
||||
{
|
||||
GLint Register; /* or the offset from the address 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;
|
||||
|
@ -103,7 +89,8 @@ struct vp_src_register
|
|||
/* Instruction destination register */
|
||||
struct vp_dst_register
|
||||
{
|
||||
GLint Register;
|
||||
enum register_file File; /* which register file */
|
||||
GLint Index; /* index into register file */
|
||||
GLboolean WriteMask[4];
|
||||
};
|
||||
|
||||
|
|
|
@ -97,18 +97,40 @@ fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
|
|||
* Apply swizzling and negating as needed.
|
||||
*/
|
||||
static void
|
||||
fetch_vector4( const struct fp_src_register *source,
|
||||
const struct fp_machine *machine,
|
||||
fetch_vector4( GLcontext *ctx,
|
||||
const struct fp_src_register *source,
|
||||
struct fp_machine *machine,
|
||||
const struct fragment_program *program,
|
||||
GLfloat result[4] )
|
||||
{
|
||||
const GLfloat *src;
|
||||
|
||||
if (source->IsParameter) {
|
||||
src = program->Parameters[source->Register].Values;
|
||||
}
|
||||
else {
|
||||
src = machine->Registers[source->Register];
|
||||
switch (source->File) {
|
||||
case PROGRAM_TEMPORARY:
|
||||
ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_TEMPS);
|
||||
src = machine->Temporaries[source->Index];
|
||||
break;
|
||||
case PROGRAM_INPUT:
|
||||
ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
|
||||
src = machine->Inputs[source->Index];
|
||||
break;
|
||||
case PROGRAM_LOCAL_PARAM:
|
||||
ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS);
|
||||
src = program->Base.LocalParams[source->Index];
|
||||
break;
|
||||
case PROGRAM_ENV_PARAM:
|
||||
ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_PARAMS);
|
||||
src = ctx->FragmentProgram.Parameters[source->Index];
|
||||
break;
|
||||
case PROGRAM_NAMED_PARAM:
|
||||
ASSERT(source->Index < program->NumParameters);
|
||||
src = program->Parameters[source->Index].Values;
|
||||
break;
|
||||
case PROGRAM_STATE_VAR:
|
||||
abort();
|
||||
default:
|
||||
_mesa_problem(ctx, "Invalid input register file in fetch_vector4");
|
||||
return;
|
||||
}
|
||||
|
||||
result[0] = src[source->Swizzle[0]];
|
||||
|
@ -151,7 +173,9 @@ fetch_vector4_deriv( const struct fp_src_register *source,
|
|||
|
||||
ASSERT(xOrY == 'X' || xOrY == 'Y');
|
||||
|
||||
switch (source->Register) {
|
||||
assert(source->File == PROGRAM_INPUT);
|
||||
|
||||
switch (source->Index) {
|
||||
case FRAG_ATTRIB_WPOS:
|
||||
if (xOrY == 'X') {
|
||||
src[0] = 1.0;
|
||||
|
@ -217,14 +241,14 @@ fetch_vector4_deriv( const struct fp_src_register *source,
|
|||
case FRAG_ATTRIB_TEX6:
|
||||
case FRAG_ATTRIB_TEX7:
|
||||
if (xOrY == 'X') {
|
||||
const GLuint u = source->Register - FRAG_ATTRIB_TEX0;
|
||||
const GLuint u = source->Index - FRAG_ATTRIB_TEX0;
|
||||
src[0] = span->texStepX[u][0] * (1.0F / CHAN_MAXF);
|
||||
src[1] = span->texStepX[u][1] * (1.0F / CHAN_MAXF);
|
||||
src[2] = span->texStepX[u][2] * (1.0F / CHAN_MAXF);
|
||||
src[3] = span->texStepX[u][3] * (1.0F / CHAN_MAXF);
|
||||
}
|
||||
else {
|
||||
const GLuint u = source->Register - FRAG_ATTRIB_TEX0;
|
||||
const GLuint u = source->Index - FRAG_ATTRIB_TEX0;
|
||||
src[0] = span->texStepY[u][0] * (1.0F / CHAN_MAXF);
|
||||
src[1] = span->texStepY[u][1] * (1.0F / CHAN_MAXF);
|
||||
src[2] = span->texStepY[u][2] * (1.0F / CHAN_MAXF);
|
||||
|
@ -266,18 +290,40 @@ fetch_vector4_deriv( const struct fp_src_register *source,
|
|||
* As above, but only return result[0] element.
|
||||
*/
|
||||
static void
|
||||
fetch_vector1( const struct fp_src_register *source,
|
||||
fetch_vector1( GLcontext *ctx,
|
||||
const struct fp_src_register *source,
|
||||
const struct fp_machine *machine,
|
||||
const struct fragment_program *program,
|
||||
GLfloat result[4] )
|
||||
{
|
||||
const GLfloat *src;
|
||||
|
||||
if (source->IsParameter) {
|
||||
src = program->Parameters[source->Register].Values;
|
||||
}
|
||||
else {
|
||||
src = machine->Registers[source->Register];
|
||||
switch (source->File) {
|
||||
case PROGRAM_TEMPORARY:
|
||||
ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_TEMPS);
|
||||
src = machine->Temporaries[source->Index];
|
||||
break;
|
||||
case PROGRAM_INPUT:
|
||||
ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
|
||||
src = machine->Inputs[source->Index];
|
||||
break;
|
||||
case PROGRAM_LOCAL_PARAM:
|
||||
ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS);
|
||||
src = program->Base.LocalParams[source->Index];
|
||||
break;
|
||||
case PROGRAM_ENV_PARAM:
|
||||
ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_PARAMS);
|
||||
src = ctx->FragmentProgram.Parameters[source->Index];
|
||||
break;
|
||||
case PROGRAM_NAMED_PARAM:
|
||||
ASSERT(source->Index < program->NumParameters);
|
||||
src = program->Parameters[source->Index].Values;
|
||||
break;
|
||||
case PROGRAM_STATE_VAR:
|
||||
abort();
|
||||
default:
|
||||
_mesa_problem(ctx, "Invalid input register file in fetch_vector1");
|
||||
return;
|
||||
}
|
||||
|
||||
result[0] = src[source->Swizzle[0]];
|
||||
|
@ -342,11 +388,23 @@ store_vector4( const struct fp_instruction *inst,
|
|||
const struct fp_dst_register *dest = &(inst->DstReg);
|
||||
const GLboolean clamp = inst->Saturate;
|
||||
const GLboolean updateCC = inst->UpdateCondRegister;
|
||||
GLfloat *dstReg = machine->Registers[dest->Register];
|
||||
GLfloat *dstReg;
|
||||
GLfloat clampedValue[4];
|
||||
const GLboolean *writeMask = dest->WriteMask;
|
||||
GLboolean condWriteMask[4];
|
||||
|
||||
switch (dest->File) {
|
||||
case PROGRAM_OUTPUT:
|
||||
dstReg = machine->Outputs[dest->Index];
|
||||
break;
|
||||
case PROGRAM_TEMPORARY:
|
||||
dstReg = machine->Temporaries[dest->Index];
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(NULL, "bad register file in store_vector4(fp)");
|
||||
return;
|
||||
}
|
||||
|
||||
#if DEBUG_FRAG
|
||||
if (value[0] > 1.0e10 ||
|
||||
IS_INF_OR_NAN(value[0]) ||
|
||||
|
@ -419,12 +477,12 @@ init_machine_deriv( GLcontext *ctx,
|
|||
_mesa_memcpy(dMachine, machine, sizeof(struct fp_machine));
|
||||
|
||||
/* Clear temporary registers */
|
||||
_mesa_bzero((GLfloat*) (machine->Registers + FP_TEMP_REG_START) ,
|
||||
_mesa_bzero(machine->Temporaries,
|
||||
MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
|
||||
|
||||
/* Add derivatives */
|
||||
if (program->InputsRead & (1 << FRAG_ATTRIB_WPOS)) {
|
||||
GLfloat *wpos = (GLfloat*) machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_WPOS];
|
||||
GLfloat *wpos = (GLfloat*) machine->Inputs[FRAG_ATTRIB_WPOS];
|
||||
if (xOrY == 'X') {
|
||||
wpos[0] += 1.0F;
|
||||
wpos[1] += 0.0F;
|
||||
|
@ -439,7 +497,7 @@ init_machine_deriv( GLcontext *ctx,
|
|||
}
|
||||
}
|
||||
if (program->InputsRead & (1 << FRAG_ATTRIB_COL0)) {
|
||||
GLfloat *col0 = (GLfloat*) machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL0];
|
||||
GLfloat *col0 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL0];
|
||||
if (xOrY == 'X') {
|
||||
col0[0] += span->drdx * (1.0F / CHAN_MAXF);
|
||||
col0[1] += span->dgdx * (1.0F / CHAN_MAXF);
|
||||
|
@ -454,7 +512,7 @@ init_machine_deriv( GLcontext *ctx,
|
|||
}
|
||||
}
|
||||
if (program->InputsRead & (1 << FRAG_ATTRIB_COL1)) {
|
||||
GLfloat *col1 = (GLfloat*) machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL1];
|
||||
GLfloat *col1 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL1];
|
||||
if (xOrY == 'X') {
|
||||
col1[0] += span->dsrdx * (1.0F / CHAN_MAXF);
|
||||
col1[1] += span->dsgdx * (1.0F / CHAN_MAXF);
|
||||
|
@ -469,7 +527,7 @@ init_machine_deriv( GLcontext *ctx,
|
|||
}
|
||||
}
|
||||
if (program->InputsRead & (1 << FRAG_ATTRIB_FOGC)) {
|
||||
GLfloat *fogc = (GLfloat*) machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_FOGC];
|
||||
GLfloat *fogc = (GLfloat*) machine->Inputs[FRAG_ATTRIB_FOGC];
|
||||
if (xOrY == 'X') {
|
||||
fogc[0] += span->dfogdx;
|
||||
}
|
||||
|
@ -479,7 +537,7 @@ init_machine_deriv( GLcontext *ctx,
|
|||
}
|
||||
for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
|
||||
if (program->InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) {
|
||||
GLfloat *tex = (GLfloat*) machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_TEX0+u];
|
||||
GLfloat *tex = (GLfloat*) machine->Inputs[FRAG_ATTRIB_TEX0 + u];
|
||||
if (xOrY == 'X') {
|
||||
tex[0] += span->texStepX[u][0];
|
||||
tex[1] += span->texStepX[u][1];
|
||||
|
@ -539,8 +597,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_ADD:
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = a[0] + b[0];
|
||||
result[1] = a[1] + b[1];
|
||||
result[2] = a[2] + b[2];
|
||||
|
@ -551,7 +609,7 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_COS:
|
||||
{
|
||||
GLfloat a[4], result[4];
|
||||
fetch_vector1( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
result[0] = result[1] = result[2] = result[3] = _mesa_cos(a[0]);
|
||||
store_vector4( inst, machine, result );
|
||||
}
|
||||
|
@ -568,11 +626,11 @@ execute_program( GLcontext *ctx,
|
|||
* Finally, find the difference in the register values for
|
||||
* the original and derivative runs.
|
||||
*/
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a);
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a);
|
||||
init_machine_deriv(ctx, machine, program, span,
|
||||
'X', &dMachine);
|
||||
execute_program(ctx, program, pc, &dMachine, span, column);
|
||||
fetch_vector4( &inst->SrcReg[0], &dMachine, program, aNext );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext );
|
||||
result[0] = aNext[0] - a[0];
|
||||
result[1] = aNext[1] - a[1];
|
||||
result[2] = aNext[2] - a[2];
|
||||
|
@ -588,9 +646,9 @@ execute_program( GLcontext *ctx,
|
|||
if (!fetch_vector4_deriv(&inst->SrcReg[0], span, 'Y', result)) {
|
||||
init_machine_deriv(ctx, machine, program, span,
|
||||
'Y', &dMachine);
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a);
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a);
|
||||
execute_program(ctx, program, pc, &dMachine, span, column);
|
||||
fetch_vector4( &inst->SrcReg[0], &dMachine, program, aNext );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext );
|
||||
result[0] = aNext[0] - a[0];
|
||||
result[1] = aNext[1] - a[1];
|
||||
result[2] = aNext[2] - a[2];
|
||||
|
@ -602,8 +660,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_DP3:
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = result[1] = result[2] = result[3] =
|
||||
a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
store_vector4( inst, machine, result );
|
||||
|
@ -616,8 +674,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_DP4:
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = result[1] = result[2] = result[3] =
|
||||
a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
|
||||
store_vector4( inst, machine, result );
|
||||
|
@ -626,8 +684,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_DST: /* Distance vector */
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = 1.0F;
|
||||
result[1] = a[1] * b[1];
|
||||
result[2] = a[2];
|
||||
|
@ -638,7 +696,7 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_EX2: /* Exponential base 2 */
|
||||
{
|
||||
GLfloat a[4], result[4];
|
||||
fetch_vector1( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
result[0] = result[1] = result[2] = result[3] =
|
||||
(GLfloat) _mesa_pow(2.0, a[0]);
|
||||
store_vector4( inst, machine, result );
|
||||
|
@ -647,7 +705,7 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_FLR:
|
||||
{
|
||||
GLfloat a[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
result[0] = FLOORF(a[0]);
|
||||
result[1] = FLOORF(a[1]);
|
||||
result[2] = FLOORF(a[2]);
|
||||
|
@ -658,7 +716,7 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_FRC:
|
||||
{
|
||||
GLfloat a[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
result[0] = a[0] - FLOORF(a[0]);
|
||||
result[1] = a[1] - FLOORF(a[1]);
|
||||
result[2] = a[2] - FLOORF(a[2]);
|
||||
|
@ -681,7 +739,7 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_LG2: /* log base 2 */
|
||||
{
|
||||
GLfloat a[4], result[4];
|
||||
fetch_vector1( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
result[0] = result[1] = result[2] = result[3]
|
||||
= LOG2(a[0]);
|
||||
store_vector4( inst, machine, result );
|
||||
|
@ -690,7 +748,7 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_LIT:
|
||||
{
|
||||
GLfloat a[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
if (a[0] < 0.0F)
|
||||
a[0] = 0.0F;
|
||||
if (a[1] < 0.0F)
|
||||
|
@ -705,9 +763,9 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_LRP:
|
||||
{
|
||||
GLfloat a[4], b[4], c[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( &inst->SrcReg[2], machine, program, c );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c );
|
||||
result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0];
|
||||
result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1];
|
||||
result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2];
|
||||
|
@ -718,9 +776,9 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_MAD:
|
||||
{
|
||||
GLfloat a[4], b[4], c[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( &inst->SrcReg[2], machine, program, c );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c );
|
||||
result[0] = a[0] * b[0] + c[0];
|
||||
result[1] = a[1] * b[1] + c[1];
|
||||
result[2] = a[2] * b[2] + c[2];
|
||||
|
@ -731,8 +789,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_MAX:
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = MAX2(a[0], b[0]);
|
||||
result[1] = MAX2(a[1], b[1]);
|
||||
result[2] = MAX2(a[2], b[2]);
|
||||
|
@ -743,8 +801,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_MIN:
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = MIN2(a[0], b[0]);
|
||||
result[1] = MIN2(a[1], b[1]);
|
||||
result[2] = MIN2(a[2], b[2]);
|
||||
|
@ -755,15 +813,15 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_MOV:
|
||||
{
|
||||
GLfloat result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, result );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, result );
|
||||
store_vector4( inst, machine, result );
|
||||
}
|
||||
break;
|
||||
case FP_OPCODE_MUL:
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = a[0] * b[0];
|
||||
result[1] = a[1] * b[1];
|
||||
result[2] = a[2] * b[2];
|
||||
|
@ -783,7 +841,7 @@ execute_program( GLcontext *ctx,
|
|||
GLfloat a[4], result[4];
|
||||
const GLuint *rawBits = (const GLuint *) a;
|
||||
GLuint *rawResult = (GLuint *) result;
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3]
|
||||
= rawBits[0] | (rawBits[1] << 16);
|
||||
store_vector4( inst, machine, result );
|
||||
|
@ -793,7 +851,7 @@ execute_program( GLcontext *ctx,
|
|||
{
|
||||
GLfloat a[4], result[4];
|
||||
GLuint usx, usy, *rawResult = (GLuint *) result;
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
a[0] = CLAMP(a[0], 0.0F, 1.0F);
|
||||
a[1] = CLAMP(a[0], 0.0F, 1.0F);
|
||||
usx = IROUND(a[0] * 65535.0F);
|
||||
|
@ -807,7 +865,7 @@ execute_program( GLcontext *ctx,
|
|||
{
|
||||
GLfloat a[4], result[4];
|
||||
GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result;
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F);
|
||||
a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F);
|
||||
a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F);
|
||||
|
@ -825,7 +883,7 @@ execute_program( GLcontext *ctx,
|
|||
{
|
||||
GLfloat a[4], result[4];
|
||||
GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result;
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
a[0] = CLAMP(a[0], 0.0F, 1.0F);
|
||||
a[1] = CLAMP(a[1], 0.0F, 1.0F);
|
||||
a[2] = CLAMP(a[2], 0.0F, 1.0F);
|
||||
|
@ -842,8 +900,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_POW:
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector1( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = result[1] = result[2] = result[3]
|
||||
= _mesa_pow(a[0], b[0]);
|
||||
store_vector4( inst, machine, result );
|
||||
|
@ -852,7 +910,7 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_RCP:
|
||||
{
|
||||
GLfloat a[4], result[4];
|
||||
fetch_vector1( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
#if DEBUG_FRAG
|
||||
if (a[0] == 0)
|
||||
printf("RCP(0)\n");
|
||||
|
@ -867,8 +925,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_RFL:
|
||||
{
|
||||
GLfloat axis[4], dir[4], result[4], tmp[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, axis );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, dir );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, axis );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dir );
|
||||
tmp[3] = axis[0] * axis[0]
|
||||
+ axis[1] * axis[1]
|
||||
+ axis[2] * axis[2];
|
||||
|
@ -885,7 +943,7 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_RSQ: /* 1 / sqrt() */
|
||||
{
|
||||
GLfloat a[4], result[4];
|
||||
fetch_vector1( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]);
|
||||
store_vector4( inst, machine, result );
|
||||
#if DEBUG_FRAG
|
||||
|
@ -896,8 +954,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_SEQ: /* set on equal */
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = (a[0] == b[0]) ? 1.0F : 0.0F;
|
||||
result[1] = (a[1] == b[1]) ? 1.0F : 0.0F;
|
||||
result[2] = (a[2] == b[2]) ? 1.0F : 0.0F;
|
||||
|
@ -914,8 +972,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_SGE: /* set on greater or equal */
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F;
|
||||
result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F;
|
||||
result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F;
|
||||
|
@ -926,8 +984,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_SGT: /* set on greater */
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = (a[0] > b[0]) ? 1.0F : 0.0F;
|
||||
result[1] = (a[1] > b[1]) ? 1.0F : 0.0F;
|
||||
result[2] = (a[2] > b[2]) ? 1.0F : 0.0F;
|
||||
|
@ -938,7 +996,7 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_SIN:
|
||||
{
|
||||
GLfloat a[4], result[4];
|
||||
fetch_vector1( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
result[0] = result[1] = result[2] = result[3] = _mesa_sin(a[0]);
|
||||
store_vector4( inst, machine, result );
|
||||
}
|
||||
|
@ -946,8 +1004,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_SLE: /* set on less or equal */
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F;
|
||||
result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F;
|
||||
result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F;
|
||||
|
@ -958,8 +1016,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_SLT: /* set on less */
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = (a[0] < b[0]) ? 1.0F : 0.0F;
|
||||
result[1] = (a[1] < b[1]) ? 1.0F : 0.0F;
|
||||
result[2] = (a[2] < b[2]) ? 1.0F : 0.0F;
|
||||
|
@ -970,8 +1028,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_SNE: /* set on not equal */
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = (a[0] != b[0]) ? 1.0F : 0.0F;
|
||||
result[1] = (a[1] != b[1]) ? 1.0F : 0.0F;
|
||||
result[2] = (a[2] != b[2]) ? 1.0F : 0.0F;
|
||||
|
@ -988,8 +1046,8 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_SUB:
|
||||
{
|
||||
GLfloat a[4], b[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
result[0] = a[0] - b[0];
|
||||
result[1] = a[1] - b[1];
|
||||
result[2] = a[2] - b[2];
|
||||
|
@ -1001,7 +1059,7 @@ execute_program( GLcontext *ctx,
|
|||
/* Texel lookup */
|
||||
{
|
||||
GLfloat texcoord[4], color[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, texcoord );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord );
|
||||
/* XXX: Undo perspective divide from interpolate_texcoords() */
|
||||
fetch_texel( ctx, texcoord,
|
||||
span->array->lambda[inst->TexSrcUnit][column],
|
||||
|
@ -1013,9 +1071,9 @@ execute_program( GLcontext *ctx,
|
|||
/* Texture lookup w/ partial derivatives for LOD */
|
||||
{
|
||||
GLfloat texcoord[4], dtdx[4], dtdy[4], color[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, texcoord );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, dtdx );
|
||||
fetch_vector4( &inst->SrcReg[2], machine, program, dtdy );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dtdx );
|
||||
fetch_vector4( ctx, &inst->SrcReg[2], machine, program, dtdy );
|
||||
fetch_texel_deriv( ctx, texcoord, dtdx, dtdy, inst->TexSrcUnit,
|
||||
color );
|
||||
store_vector4( inst, machine, color );
|
||||
|
@ -1025,7 +1083,7 @@ execute_program( GLcontext *ctx,
|
|||
/* Texture lookup w/ perspective divide */
|
||||
{
|
||||
GLfloat texcoord[4], color[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, texcoord );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord );
|
||||
/* Already did perspective divide in interpolate_texcoords() */
|
||||
fetch_texel( ctx, texcoord,
|
||||
span->array->lambda[inst->TexSrcUnit][column],
|
||||
|
@ -1039,7 +1097,7 @@ execute_program( GLcontext *ctx,
|
|||
GLfloat a[4], result[4];
|
||||
const GLuint *rawBits = (const GLuint *) a;
|
||||
GLuint *rawResult = (GLuint *) result;
|
||||
fetch_vector1( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
rawResult[0] = rawBits[0] & 0xffff;
|
||||
rawResult[1] = (rawBits[0] >> 16) & 0xffff;
|
||||
rawResult[2] = rawBits[0] & 0xffff;
|
||||
|
@ -1051,7 +1109,7 @@ execute_program( GLcontext *ctx,
|
|||
{
|
||||
GLfloat a[4], result[4];
|
||||
const GLuint *rawBits = (const GLuint *) a;
|
||||
fetch_vector1( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
result[0] = (GLfloat) ((rawBits[0] >> 0) & 0xffff) / 65535.0F;
|
||||
result[1] = (GLfloat) ((rawBits[0] >> 16) & 0xffff) / 65535.0F;
|
||||
result[2] = result[0];
|
||||
|
@ -1063,7 +1121,7 @@ execute_program( GLcontext *ctx,
|
|||
{
|
||||
GLfloat a[4], result[4];
|
||||
const GLuint *rawBits = (const GLuint *) a;
|
||||
fetch_vector1( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F;
|
||||
result[0] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F;
|
||||
result[0] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F;
|
||||
|
@ -1075,7 +1133,7 @@ execute_program( GLcontext *ctx,
|
|||
{
|
||||
GLfloat a[4], result[4];
|
||||
const GLuint *rawBits = (const GLuint *) a;
|
||||
fetch_vector1( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F;
|
||||
result[0] = ((rawBits[0] >> 8) & 0xff) / 255.0F;
|
||||
result[0] = ((rawBits[0] >> 16) & 0xff) / 255.0F;
|
||||
|
@ -1086,9 +1144,9 @@ execute_program( GLcontext *ctx,
|
|||
case FP_OPCODE_X2D: /* 2-D matrix transform */
|
||||
{
|
||||
GLfloat a[4], b[4], c[4], result[4];
|
||||
fetch_vector4( &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( &inst->SrcReg[2], machine, program, c );
|
||||
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
|
||||
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
|
||||
fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c );
|
||||
result[0] = a[0] + b[0] * c[0] + b[1] * c[1];
|
||||
result[1] = a[1] + b[0] * c[2] + b[1] * c[3];
|
||||
result[2] = a[2] + b[0] * c[0] + b[1] * c[1];
|
||||
|
@ -1114,45 +1172,39 @@ init_machine( GLcontext *ctx, struct fp_machine *machine,
|
|||
const struct sw_span *span, GLuint col )
|
||||
{
|
||||
GLuint inputsRead = program->InputsRead;
|
||||
GLuint j, u;
|
||||
GLuint u;
|
||||
|
||||
if (ctx->FragmentProgram.CallbackEnabled)
|
||||
inputsRead = ~0;
|
||||
|
||||
/* Clear temporary registers */
|
||||
_mesa_bzero(machine->Registers + FP_TEMP_REG_START,
|
||||
_mesa_bzero(machine->Temporaries,
|
||||
MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
|
||||
|
||||
/* Load program local parameters */
|
||||
for (j = 0; j < MAX_NV_FRAGMENT_PROGRAM_PARAMS; j++) {
|
||||
COPY_4V(machine->Registers[FP_PROG_REG_START + j],
|
||||
program->Base.LocalParams[j]);
|
||||
}
|
||||
|
||||
/* Load input registers */
|
||||
if (inputsRead & (1 << FRAG_ATTRIB_WPOS)) {
|
||||
GLfloat *wpos = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_WPOS];
|
||||
GLfloat *wpos = machine->Inputs[FRAG_ATTRIB_WPOS];
|
||||
wpos[0] = span->x + col;
|
||||
wpos[1] = span->y;
|
||||
wpos[2] = (GLfloat) span->array->z[col] / ctx->DepthMaxF;
|
||||
wpos[3] = span->w + col * span->dwdx;
|
||||
}
|
||||
if (inputsRead & (1 << FRAG_ATTRIB_COL0)) {
|
||||
GLfloat *col0 = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL0];
|
||||
GLfloat *col0 = machine->Inputs[FRAG_ATTRIB_COL0];
|
||||
col0[0] = CHAN_TO_FLOAT(span->array->rgba[col][RCOMP]);
|
||||
col0[1] = CHAN_TO_FLOAT(span->array->rgba[col][GCOMP]);
|
||||
col0[2] = CHAN_TO_FLOAT(span->array->rgba[col][BCOMP]);
|
||||
col0[3] = CHAN_TO_FLOAT(span->array->rgba[col][ACOMP]);
|
||||
}
|
||||
if (inputsRead & (1 << FRAG_ATTRIB_COL1)) {
|
||||
GLfloat *col1 = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL1];
|
||||
GLfloat *col1 = machine->Inputs[FRAG_ATTRIB_COL1];
|
||||
col1[0] = CHAN_TO_FLOAT(span->array->spec[col][RCOMP]);
|
||||
col1[1] = CHAN_TO_FLOAT(span->array->spec[col][GCOMP]);
|
||||
col1[2] = CHAN_TO_FLOAT(span->array->spec[col][BCOMP]);
|
||||
col1[3] = CHAN_TO_FLOAT(span->array->spec[col][ACOMP]);
|
||||
}
|
||||
if (inputsRead & (1 << FRAG_ATTRIB_FOGC)) {
|
||||
GLfloat *fogc = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_FOGC];
|
||||
GLfloat *fogc = machine->Inputs[FRAG_ATTRIB_FOGC];
|
||||
fogc[0] = span->array->fog[col];
|
||||
fogc[1] = 0.0F;
|
||||
fogc[2] = 0.0F;
|
||||
|
@ -1160,7 +1212,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine,
|
|||
}
|
||||
for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
|
||||
if (inputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) {
|
||||
GLfloat *tex = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_TEX0+u];
|
||||
GLfloat *tex = machine->Inputs[FRAG_ATTRIB_TEX0 + u];
|
||||
/*ASSERT(ctx->Texture._EnabledCoordUnits & (1 << u));*/
|
||||
COPY_4V(tex, span->array->texcoords[u][col]);
|
||||
/*ASSERT(tex[0] != 0 || tex[1] != 0 || tex[2] != 0);*/
|
||||
|
@ -1196,7 +1248,7 @@ _swrast_exec_nv_fragment_program( GLcontext *ctx, struct sw_span *span )
|
|||
/* Store output registers */
|
||||
{
|
||||
const GLfloat *colOut
|
||||
= ctx->FragmentProgram.Machine.Registers[FP_OUTPUT_REG_START];
|
||||
= ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_COLR];
|
||||
UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][RCOMP], colOut[0]);
|
||||
UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][GCOMP], colOut[1]);
|
||||
UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][BCOMP], colOut[2]);
|
||||
|
@ -1204,7 +1256,7 @@ _swrast_exec_nv_fragment_program( GLcontext *ctx, struct sw_span *span )
|
|||
}
|
||||
/* depth value */
|
||||
if (program->OutputsWritten & (1 << FRAG_OUTPUT_DEPR))
|
||||
span->array->z[i] = IROUND(ctx->FragmentProgram.Machine.Registers[FP_OUTPUT_REG_START + 2][0] * ctx->DepthMaxF);
|
||||
span->array->z[i] = IROUND(ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR][0] * ctx->DepthMaxF);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,6 @@ static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
|
|||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vp_stage_data *store = VP_STAGE_DATA(stage);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
struct vp_machine *machine = &(ctx->VertexProgram.Machine);
|
||||
struct vertex_program *program = ctx->VertexProgram.Current;
|
||||
GLuint i;
|
||||
|
||||
|
@ -135,7 +134,7 @@ static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
|
|||
/* the traditional glBegin/glVertex/glEnd case */
|
||||
for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
|
||||
if (attr == 0 || (program->InputsRead & (1 << attr))) {
|
||||
COPY_4V(machine->Registers[VP_INPUT_REG_START + attr],
|
||||
COPY_4V(ctx->VertexProgram.Inputs[attr],
|
||||
VB->AttribPtr[attr]->data[i]);
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +146,7 @@ static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
|
|||
const GLubyte *ptr = (const GLubyte*) VB->AttribPtr[attr]->data;
|
||||
const GLuint stride = VB->AttribPtr[attr]->stride;
|
||||
const GLfloat *data = (GLfloat *) (ptr + stride * i);
|
||||
COPY_4V(machine->Registers[VP_INPUT_REG_START + attr], data);
|
||||
COPY_4V(ctx->VertexProgram.Inputs[attr], data);
|
||||
/*ASSERT(VB->AttribPtr[attr]->size == 4);*/
|
||||
ASSERT(stride == 4 * sizeof(GLfloat) || stride == 0);
|
||||
}
|
||||
|
@ -158,38 +157,22 @@ static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
|
|||
ASSERT(program);
|
||||
_mesa_exec_vertex_program(ctx, program);
|
||||
|
||||
#if 0
|
||||
printf("Output %d: %f, %f, %f, %f\n", i,
|
||||
machine->Registers[VP_OUTPUT_REG_START + 0][0],
|
||||
machine->Registers[VP_OUTPUT_REG_START + 0][1],
|
||||
machine->Registers[VP_OUTPUT_REG_START + 0][2],
|
||||
machine->Registers[VP_OUTPUT_REG_START + 0][3]);
|
||||
printf(" color: %f, %f, %f, %f\n",
|
||||
machine->Registers[VP_OUTPUT_REG_START +_1][0],
|
||||
machine->Registers[VP_OUTPUT_REG_START + 1][1],
|
||||
machine->Registers[VP_OUTPUT_REG_START + 1][2],
|
||||
machine->Registers[VP_OUTPUT_REG_START + 1][3]);
|
||||
printf("PointSize[%d]: %g\n", i,
|
||||
machine->Registers[VP_OUTPUT_REG_START + VERT_RESULT_PSIZ][0]);
|
||||
#endif
|
||||
|
||||
/* Fixup fog an point size results if needed */
|
||||
if (ctx->Fog.Enabled &&
|
||||
(program->OutputsWritten & (1 << VERT_RESULT_FOGC)) == 0) {
|
||||
machine->Registers[VP_OUTPUT_REG_START + VERT_RESULT_FOGC][0] = 1.0;
|
||||
ctx->VertexProgram.Outputs[VERT_RESULT_FOGC][0] = 1.0;
|
||||
}
|
||||
|
||||
if (ctx->VertexProgram.PointSizeEnabled &&
|
||||
(program->OutputsWritten & (1 << VERT_RESULT_PSIZ)) == 0) {
|
||||
machine->Registers[VP_OUTPUT_REG_START + VERT_RESULT_PSIZ][0]
|
||||
= ctx->Point.Size;
|
||||
ctx->VertexProgram.Outputs[VERT_RESULT_PSIZ][0] = ctx->Point.Size;
|
||||
}
|
||||
|
||||
/* copy the output registers into the VB->attribs arrays */
|
||||
/* XXX (optimize) could use a conditional and smaller loop limit here */
|
||||
for (attr = 0; attr < 15; attr++) {
|
||||
COPY_4V( store->attribs[attr].data[i],
|
||||
machine->Registers[VP_OUTPUT_REG_START + attr] );
|
||||
COPY_4V(store->attribs[attr].data[i],
|
||||
ctx->VertexProgram.Outputs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue