From 7c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 21 Apr 2005 14:46:57 +0000 Subject: Reduce the size of mesa's internal fragment and vertex program representations by switching to packed structures for registers and instructions. --- src/mesa/drivers/dri/i915/i915_fragprog.c | 38 +-- src/mesa/main/mtypes.h | 23 +- src/mesa/shader/arbfragparse.c | 45 +-- src/mesa/shader/arbprogparse.c | 464 ++++++++++++++++++------------ src/mesa/shader/arbvertparse.c | 208 ++++++-------- src/mesa/shader/arbvertparse.h | 3 + src/mesa/shader/grammar.c | 1 - src/mesa/shader/nvfragparse.c | 188 ++++++------ src/mesa/shader/nvfragprog.h | 48 ++-- src/mesa/shader/nvvertexec.c | 38 +-- src/mesa/shader/nvvertparse.c | 121 ++++---- src/mesa/shader/nvvertprog.h | 75 +++-- src/mesa/shader/program.c | 48 +++- src/mesa/shader/program.h | 31 +- src/mesa/swrast/s_nvfragprog.c | 73 ++--- 15 files changed, 774 insertions(+), 630 deletions(-) diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index 40e118ec41..dae28cb0bc 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -130,7 +130,7 @@ static GLuint src_vector( struct i915_fragment_program *p, case PROGRAM_STATE_VAR: case PROGRAM_NAMED_PARAM: src = i915_emit_param4fv( - p, program->Parameters->Parameters[source->Index].Values ); + p, program->Parameters->ParameterValues[source->Index] ); break; default: @@ -139,10 +139,10 @@ static GLuint src_vector( struct i915_fragment_program *p, } src = swizzle(src, - source->Swizzle[0], - source->Swizzle[1], - source->Swizzle[2], - source->Swizzle[3]); + GET_SWZ(source->Swizzle, 0), + GET_SWZ(source->Swizzle, 1), + GET_SWZ(source->Swizzle, 2), + GET_SWZ(source->Swizzle, 3)); if (source->NegateBase) src = negate( src, 1,1,1,1 ); @@ -179,30 +179,30 @@ static GLuint get_result_flags( const struct fp_instruction *inst ) GLuint flags = 0; if (inst->Saturate) flags |= A0_DEST_SATURATE; - if (inst->DstReg.WriteMask[0]) flags |= A0_DEST_CHANNEL_X; - if (inst->DstReg.WriteMask[1]) flags |= A0_DEST_CHANNEL_Y; - if (inst->DstReg.WriteMask[2]) flags |= A0_DEST_CHANNEL_Z; - if (inst->DstReg.WriteMask[3]) flags |= A0_DEST_CHANNEL_W; + if (inst->DstReg.WriteMask & WRITEMASK_X) flags |= A0_DEST_CHANNEL_X; + if (inst->DstReg.WriteMask & WRITEMASK_Y) flags |= A0_DEST_CHANNEL_Y; + if (inst->DstReg.WriteMask & WRITEMASK_Z) flags |= A0_DEST_CHANNEL_Z; + if (inst->DstReg.WriteMask & WRITEMASK_W) flags |= A0_DEST_CHANNEL_W; return flags; } -static GLuint translate_tex_src_bit( struct i915_fragment_program *p, +static GLuint translate_tex_src_idx( struct i915_fragment_program *p, GLubyte bit ) { switch (bit) { - case TEXTURE_1D_BIT: return D0_SAMPLE_TYPE_2D; - case TEXTURE_2D_BIT: return D0_SAMPLE_TYPE_2D; - case TEXTURE_RECT_BIT: return D0_SAMPLE_TYPE_2D; - case TEXTURE_3D_BIT: return D0_SAMPLE_TYPE_VOLUME; - case TEXTURE_CUBE_BIT: return D0_SAMPLE_TYPE_CUBE; + case TEXTURE_1D_INDEX: return D0_SAMPLE_TYPE_2D; + case TEXTURE_2D_INDEX: return D0_SAMPLE_TYPE_2D; + case TEXTURE_RECT_INDEX: return D0_SAMPLE_TYPE_2D; + case TEXTURE_3D_INDEX: return D0_SAMPLE_TYPE_VOLUME; + case TEXTURE_CUBE_INDEX: return D0_SAMPLE_TYPE_CUBE; default: i915_program_error(p, "TexSrcBit"); return 0; } } #define EMIT_TEX( OP ) \ do { \ - GLuint dim = translate_tex_src_bit( p, inst->TexSrcBit ); \ + GLuint dim = translate_tex_src_idx( p, inst->TexSrcIdx ); \ GLuint sampler = i915_emit_decl(p, REG_TYPE_S, \ inst->TexSrcUnit, dim); \ GLuint coord = src_vector( p, &inst->SrcReg[0], program); \ @@ -592,10 +592,10 @@ static void upload_program( struct i915_fragment_program *p ) swizzle(tmp, X,Y,X,Y), swizzle(tmp, X,X,ONE,ONE), 0); - if (inst->DstReg.WriteMask[1]) { + if (inst->DstReg.WriteMask & WRITEMASK_Y) { GLuint tmp1; - if (inst->DstReg.WriteMask[0]) + if (inst->DstReg.WriteMask & WRITEMASK_X) tmp1 = i915_get_utemp( p ); else tmp1 = tmp; @@ -614,7 +614,7 @@ static void upload_program( struct i915_fragment_program *p ) i915_emit_const4fv( p, sin_constants ), 0); } - if (inst->DstReg.WriteMask[0]) { + if (inst->DstReg.WriteMask & WRITEMASK_X) { i915_emit_arith( p, A0_MUL, tmp, A0_DEST_CHANNEL_XYZ, 0, diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 37803b7b4b..ac9fc87d1e 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -213,6 +213,27 @@ enum /*@}*/ +/** + * Indexes for vertex program result attributes + */ +#define VERT_RESULT_HPOS 0 +#define VERT_RESULT_COL0 1 +#define VERT_RESULT_COL1 2 +#define VERT_RESULT_BFC0 3 +#define VERT_RESULT_BFC1 4 +#define VERT_RESULT_FOGC 5 +#define VERT_RESULT_PSIZ 6 +#define VERT_RESULT_TEX0 7 +#define VERT_RESULT_TEX1 8 +#define VERT_RESULT_TEX2 9 +#define VERT_RESULT_TEX3 10 +#define VERT_RESULT_TEX4 11 +#define VERT_RESULT_TEX5 12 +#define VERT_RESULT_TEX6 13 +#define VERT_RESULT_TEX7 14 +#define VERT_RESULT_MAX 15 + + /** * Indexes for fragment program input attributes. */ @@ -1679,7 +1700,7 @@ struct atifs_machine */ enum register_file { - PROGRAM_TEMPORARY = 10, + PROGRAM_TEMPORARY, PROGRAM_INPUT, PROGRAM_OUTPUT, PROGRAM_LOCAL_PARAM, diff --git a/src/mesa/shader/arbfragparse.c b/src/mesa/shader/arbfragparse.c index 9c85d3413a..5a2eb02eac 100644 --- a/src/mesa/shader/arbfragparse.c +++ b/src/mesa/shader/arbfragparse.c @@ -35,6 +35,7 @@ #include "imports.h" #include "macros.h" #include "mtypes.h" +#include "program.h" #include "arbprogparse.h" #include "arbfragparse.h" @@ -43,9 +44,9 @@ _mesa_debug_fp_inst(GLint num, struct fp_instruction *fp) { GLint a; - fprintf(stderr, "PROGRAM_OUTPUT: 0x%x\n", PROGRAM_OUTPUT); - fprintf(stderr, "PROGRAM_INPUT: 0x%x\n", PROGRAM_INPUT); - fprintf(stderr, "PROGRAM_TEMPORARY: 0x%x\n", PROGRAM_TEMPORARY); +/* fprintf(stderr, "PROGRAM_OUTPUT: 0x%x\n", PROGRAM_OUTPUT); */ +/* fprintf(stderr, "PROGRAM_INPUT: 0x%x\n", PROGRAM_INPUT); */ +/* fprintf(stderr, "PROGRAM_TEMPORARY: 0x%x\n", PROGRAM_TEMPORARY); */ for (a=0; a bit 1 * y,g -> bit 2 * x,r -> bit 3 + * + * ==> Need to reverse the order of bits for this! */ - mask = *(*inst)++; - - WriteMask[0] = (GLboolean) (mask & (1 << 3)) >> 3; - WriteMask[1] = (GLboolean) (mask & (1 << 2)) >> 2; - WriteMask[2] = (GLboolean) (mask & (1 << 1)) >> 1; - WriteMask[3] = (GLboolean) (mask & (1)); + tmp = (GLint) *(*inst)++; + *WriteMask = (((tmp>>3) & 0x1) | + ((tmp>>1) & 0x2) | + ((tmp<<1) & 0x4) | + ((tmp<<3) & 0x8)); return 0; } @@ -2498,6 +2498,8 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, GLuint binding_state, binding_idx, is_generic, found; GLint offset; + *IsRelOffset = 0; + /* And the binding for the src */ switch (*(*inst)++) { case REGISTER_ATTRIB: @@ -2652,45 +2654,94 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, /** */ static GLuint -parse_vector_src_reg (GLcontext * ctx, GLubyte ** inst, - struct var_cache **vc_head, struct arb_program *Program, - GLint * File, GLint * Index, GLboolean * Negate, - GLubyte * Swizzle, GLboolean *IsRelOffset) +parse_fp_vector_src_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct fp_src_register *reg ) { + + GLint File; + GLint Index; + GLboolean Negate; + GLubyte Swizzle[4]; + GLboolean IsRelOffset; + /* Grab the sign */ - *Negate = (parse_sign (inst) == -1); + Negate = (parse_sign (inst) == -1) ? 0xf : 0x0; /* And the src reg */ - if (parse_src_reg (ctx, inst, vc_head, Program, File, Index, IsRelOffset)) + if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) return 1; /* finally, the swizzle */ parse_swizzle_mask (inst, Swizzle, 4); + reg->File = File; + reg->Index = Index; + reg->Abs = 0; /* NV only */ + reg->NegateAbs = 0; /* NV only */ + reg->NegateBase = Negate; + reg->Swizzle = (Swizzle[0] << 0 | + Swizzle[1] << 3 | + Swizzle[2] << 6 | + Swizzle[3] << 9); + return 0; } -/** - */ + +static GLuint +parse_fp_dst_reg(GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct fp_dst_register *reg ) +{ + GLint file, idx, mask; + + if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask)) + return 1; + + reg->CondMask = 0; /* NV only */ + reg->CondSwizzle = 0; /* NV only */ + reg->File = file; + reg->Index = idx; + reg->WriteMask = mask; + return 0; +} + + + static GLuint -parse_scalar_src_reg (GLcontext * ctx, GLubyte ** inst, - struct var_cache **vc_head, struct arb_program *Program, - GLint * File, GLint * Index, GLboolean * Negate, - GLubyte * Swizzle, GLboolean *IsRelOffset) +parse_fp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct fp_src_register *reg ) { + + GLint File; + GLint Index; + GLboolean Negate; + GLubyte Swizzle[4]; + GLboolean IsRelOffset; + /* Grab the sign */ - *Negate = (parse_sign (inst) == -1); + Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0; /* And the src reg */ - if (parse_src_reg (ctx, inst, vc_head, Program, File, Index, IsRelOffset)) + if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) return 1; - /* Now, get the component and shove it into all the swizzle slots */ + /* finally, the swizzle */ parse_swizzle_mask (inst, Swizzle, 1); + reg->File = File; + reg->Index = Index; + reg->Abs = 0; /* NV only */ + reg->NegateAbs = 0; /* NV only */ + reg->NegateBase = Negate; + reg->Swizzle = (Swizzle[0] << 0); + return 0; } + /** * This is a big mother that handles getting opcodes into the instruction * and handling the src & dst registers for fragment program instructions @@ -2700,8 +2751,7 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, struct arb_program *Program, struct fp_instruction *fp) { - GLint a, b; - GLubyte swz[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */ + GLint a; GLuint texcoord; GLubyte instClass, type, code; GLboolean rel; @@ -2774,20 +2824,11 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst, break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File, - &fp->DstReg.Index, fp->DstReg.WriteMask)) + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; - fp->SrcReg[0].Abs = GL_FALSE; - fp->SrcReg[0].NegateAbs = GL_FALSE; - if (parse_vector_src_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File, - &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase, - swz, &rel)) + if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) return 1; - for (b=0; b<4; b++) - fp->SrcReg[0].Swizzle[b] = swz[b]; break; case OP_ALU_SCALAR: @@ -2836,19 +2877,11 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst, break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File, - &fp->DstReg.Index, fp->DstReg.WriteMask)) + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; - fp->SrcReg[0].Abs = GL_FALSE; - fp->SrcReg[0].NegateAbs = GL_FALSE; - if (parse_scalar_src_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File, - &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase, - swz, &rel)) + + if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) return 1; - for (b=0; b<4; b++) - fp->SrcReg[0].Swizzle[b] = swz[b]; break; case OP_ALU_BINSC: @@ -2860,20 +2893,12 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst, break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File, - &fp->DstReg.Index, fp->DstReg.WriteMask)) + if (parse_fp_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg)) return 1; + for (a = 0; a < 2; a++) { - fp->SrcReg[a].Abs = GL_FALSE; - fp->SrcReg[a].NegateAbs = GL_FALSE; - if (parse_scalar_src_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File, - &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase, - swz, &rel)) + if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) return 1; - for (b=0; b<4; b++) - fp->SrcReg[a].Swizzle[b] = swz[b]; } break; @@ -2953,20 +2978,11 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst, break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File, - &fp->DstReg.Index, fp->DstReg.WriteMask)) + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; for (a = 0; a < 2; a++) { - fp->SrcReg[a].Abs = GL_FALSE; - fp->SrcReg[a].NegateAbs = GL_FALSE; - if (parse_vector_src_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File, - &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase, - swz, &rel)) - return 1; - for (b=0; b<4; b++) - fp->SrcReg[a].Swizzle[b] = swz[b]; + if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) + return 1; } break; @@ -2991,20 +3007,12 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst, break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File, - &fp->DstReg.Index, fp->DstReg.WriteMask)) + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; + for (a = 0; a < 3; a++) { - fp->SrcReg[a].Abs = GL_FALSE; - fp->SrcReg[a].NegateAbs = GL_FALSE; - if (parse_vector_src_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File, - &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase, - swz, &rel)) - return 1; - for (b=0; b<4; b++) - fp->SrcReg[a].Swizzle[b] = swz[b]; + if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) + return 1; } break; @@ -3016,19 +3024,28 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst, fp->Opcode = FP_OPCODE_SWZ; break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File, - &fp->DstReg.Index, fp->DstReg.WriteMask)) + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; - if (parse_src_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File, - &fp->SrcReg[0].Index, &rel)) - return 1; - parse_extended_swizzle_mask (inst, swz, - &fp->SrcReg[0].NegateBase); - for (b=0; b<4; b++) - fp->SrcReg[0].Swizzle[b] = swz[b]; + { + GLubyte Swizzle[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */ + GLubyte Negate[4]; + GLint File, Index; + + if (parse_src_reg(ctx, inst, vc_head, Program, &File, &Index, &rel)) + return 1; + parse_extended_swizzle_mask (inst, Swizzle, Negate); + fp->SrcReg[0].File = File; + fp->SrcReg[0].Index = Index; + fp->SrcReg[0].NegateBase = (Negate[0] << 0 | + Negate[1] << 1 | + Negate[2] << 2 | + Negate[3] << 3); + fp->SrcReg[0].Swizzle = (Swizzle[0] << 0 | + Swizzle[1] << 3 | + Swizzle[2] << 6 | + Swizzle[3] << 9); + } break; case OP_TEX_SAMPLE: @@ -3046,26 +3063,17 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst, break; case OP_TXB_SAT: - fp->Saturate = 1; case OP_TXB: fp->Opcode = FP_OPCODE_TXB; break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File, - &fp->DstReg.Index, fp->DstReg.WriteMask)) + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; - fp->SrcReg[0].Abs = GL_FALSE; - fp->SrcReg[0].NegateAbs = GL_FALSE; - if (parse_vector_src_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File, - &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase, - swz, &rel)) + + if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) return 1; - for (b=0; b<4; b++) - fp->SrcReg[0].Swizzle[b] = swz[b]; /* texImageUnit */ if (parse_texcoord_num (ctx, inst, Program, &texcoord)) @@ -3075,19 +3083,19 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst, /* texTarget */ switch (*(*inst)++) { case TEXTARGET_1D: - fp->TexSrcBit = TEXTURE_1D_BIT; + fp->TexSrcIdx = TEXTURE_1D_INDEX; break; case TEXTARGET_2D: - fp->TexSrcBit = TEXTURE_2D_BIT; + fp->TexSrcIdx = TEXTURE_2D_INDEX; break; case TEXTARGET_3D: - fp->TexSrcBit = TEXTURE_3D_BIT; + fp->TexSrcIdx = TEXTURE_3D_INDEX; break; case TEXTARGET_RECT: - fp->TexSrcBit = TEXTURE_RECT_BIT; + fp->TexSrcIdx = TEXTURE_RECT_INDEX; break; case TEXTARGET_CUBE: - fp->TexSrcBit = TEXTURE_CUBE_BIT; + fp->TexSrcIdx = TEXTURE_CUBE_INDEX; break; case TEXTARGET_SHADOW1D: case TEXTARGET_SHADOW2D: @@ -3095,26 +3103,131 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst, /* TODO ARB_fragment_program_shadow code */ break; } - Program->TexturesUsed[texcoord] |= fp->TexSrcBit; + Program->TexturesUsed[texcoord] |= (1<TexSrcIdx); break; case OP_TEX_KIL: - fp->Opcode = FP_OPCODE_KIL; - fp->SrcReg[0].Abs = GL_FALSE; - fp->SrcReg[0].NegateAbs = GL_FALSE; - if (parse_vector_src_reg - (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File, - &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase, - swz, &rel)) + if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) return 1; - for (b=0; b<4; b++) - fp->SrcReg[0].Swizzle[b] = swz[b]; break; } return 0; } +static GLuint +parse_vp_dst_reg(GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct vp_dst_register *reg ) +{ + GLint file, idx, mask; + + if (parse_masked_dst_reg(ctx, inst, vc_head, Program, &file, &idx, &mask)) + return 1; + + reg->File = file; + reg->Index = idx; + reg->WriteMask = mask; + return 0; +} + +/** + * Handle the parsing out of a masked address register + * + * \param Index - The register index we write to + * \param WriteMask - The mask controlling which components we write (1->write) + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_vp_address_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, + struct arb_program *Program, + struct vp_dst_register *reg) +{ + GLint idx; + + if (parse_address_reg (ctx, inst, vc_head, Program, &idx)) + return 1; + + /* This should be 0x8 */ + (*inst)++; + + reg->File = PROGRAM_ADDRESS; + reg->Index = idx; + + /* Writemask of .x is implied */ + reg->WriteMask = 0x1; + return 0; +} + +/** + */ +static GLuint +parse_vp_vector_src_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct vp_src_register *reg ) +{ + + GLint File; + GLint Index; + GLboolean Negate; + GLubyte Swizzle[4]; + GLboolean IsRelOffset; + + /* Grab the sign */ + Negate = (parse_sign (inst) == -1) ? 0xf : 0x0; + + /* And the src reg */ + if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) + return 1; + + /* finally, the swizzle */ + parse_swizzle_mask (inst, Swizzle, 4); + + reg->File = File; + reg->Index = Index; + reg->Swizzle = ((Swizzle[0] << 0) | + (Swizzle[1] << 3) | + (Swizzle[2] << 6) | + (Swizzle[3] << 9)); + reg->Negate = Negate; + reg->RelAddr = IsRelOffset; + return 0; +} + + +static GLuint +parse_vp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct vp_src_register *reg ) +{ + + GLint File; + GLint Index; + GLboolean Negate; + GLubyte Swizzle[4]; + GLboolean IsRelOffset; + + /* Grab the sign */ + Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0; + + /* And the src reg */ + if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) + return 1; + + /* finally, the swizzle */ + parse_swizzle_mask (inst, Swizzle, 1); + + reg->File = File; + reg->Index = Index; + reg->Swizzle = (Swizzle[0] << 0); + reg->Negate = Negate; + reg->RelAddr = IsRelOffset; + return 0; +} + + /** * This is a big mother that handles getting opcodes into the instruction * and handling the src & dst registers for vertex program instructions @@ -3135,17 +3248,12 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst, /* Record the position in the program string for debugging */ vp->StringPos = Program->Position; - vp->Data = NULL; - vp->SrcReg[0].RelAddr = vp->SrcReg[1].RelAddr = vp->SrcReg[2].RelAddr = 0; - - for (a = 0; a < 4; a++) { - vp->SrcReg[0].Swizzle[a] = a; - vp->SrcReg[1].Swizzle[a] = a; - vp->SrcReg[2].Swizzle[a] = a; - vp->DstReg.WriteMask[a] = 1; - } + vp->SrcReg[0].Swizzle = SWIZZLE_NOOP; + vp->SrcReg[1].Swizzle = SWIZZLE_NOOP; + vp->SrcReg[2].Swizzle = SWIZZLE_NOOP; + vp->DstReg.WriteMask = 0xf; switch (type) { /* XXX: */ @@ -3155,17 +3263,13 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst, /* Remember to set SrcReg.RelAddr; */ /* Get the masked address register [dst] */ - if (parse_masked_address_reg - (ctx, inst, vc_head, Program, &vp->DstReg.Index, - vp->DstReg.WriteMask)) + if (parse_vp_address_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; + vp->DstReg.File = PROGRAM_ADDRESS; /* Get a scalar src register */ - if (parse_scalar_src_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File, - &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate, - vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr)) + if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) return 1; break; @@ -3188,14 +3292,11 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst, vp->Opcode = VP_OPCODE_MOV; break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File, - &vp->DstReg.Index, vp->DstReg.WriteMask)) + + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; - if (parse_vector_src_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File, - &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate, - vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr)) + + if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) return 1; break; @@ -3220,14 +3321,10 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst, vp->Opcode = VP_OPCODE_RSQ; break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File, - &vp->DstReg.Index, vp->DstReg.WriteMask)) + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; - if (parse_scalar_src_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File, - &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate, - vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr)) + + if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) return 1; break; @@ -3237,15 +3334,11 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst, vp->Opcode = VP_OPCODE_POW; break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File, - &vp->DstReg.Index, vp->DstReg.WriteMask)) + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; + for (a = 0; a < 2; a++) { - if (parse_scalar_src_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File, - &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate, - vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr)) + if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) return 1; } break; @@ -3289,15 +3382,11 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst, vp->Opcode = VP_OPCODE_XPD; break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File, - &vp->DstReg.Index, vp->DstReg.WriteMask)) + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; + for (a = 0; a < 2; a++) { - if (parse_vector_src_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File, - &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate, - vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr)) + if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) return 1; } break; @@ -3309,15 +3398,11 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst, break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File, - &vp->DstReg.Index, vp->DstReg.WriteMask)) + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; + for (a = 0; a < 3; a++) { - if (parse_vector_src_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File, - &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate, - vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr)) + if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) return 1; } break; @@ -3328,17 +3413,30 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst, vp->Opcode = VP_OPCODE_SWZ; break; } - if (parse_masked_dst_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File, - &vp->DstReg.Index, vp->DstReg.WriteMask)) - return 1; - - if (parse_src_reg - (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File, - &vp->SrcReg[0].Index, &vp->SrcReg[0].RelAddr)) - return 1; - parse_extended_swizzle_mask (inst, vp->SrcReg[0].Swizzle, - &vp->SrcReg[0].Negate); + { + GLubyte Swizzle[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */ + GLubyte Negate[4]; + GLboolean RelAddr; + GLint File, Index; + + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + return 1; + + if (parse_src_reg(ctx, inst, vc_head, Program, &File, &Index, &RelAddr)) + return 1; + parse_extended_swizzle_mask (inst, Swizzle, Negate); + vp->SrcReg[0].File = File; + vp->SrcReg[0].Index = Index; + vp->SrcReg[0].Negate = (Negate[0] << 0 | + Negate[1] << 1 | + Negate[2] << 2 | + Negate[3] << 3); + vp->SrcReg[0].Swizzle = (Swizzle[0] << 0 | + Swizzle[1] << 3 | + Swizzle[2] << 6 | + Swizzle[3] << 9); + vp->SrcReg[0].RelAddr = RelAddr; + } break; } return 0; diff --git a/src/mesa/shader/arbvertparse.c b/src/mesa/shader/arbvertparse.c index fd0666b326..5545aff8b7 100644 --- a/src/mesa/shader/arbvertparse.c +++ b/src/mesa/shader/arbvertparse.c @@ -37,6 +37,7 @@ #include "imports.h" #include "macros.h" #include "mtypes.h" +#include "program.h" #include "nvprogram.h" #include "nvvertparse.h" #include "nvvertprog.h" @@ -48,129 +49,104 @@ * XXX this is probably redundant. We've already got code like this * in the nvvertparse.c file. Combine/clean-up someday. */ -static GLvoid -debug_vp_inst(GLint num, struct vp_instruction *vp) +void _mesa_debug_vp_inst(GLint num, struct vp_instruction *vp) { GLint a; + static const char *opcode_string[] = { + "ABS", + "ADD", + "ARL", + "DP3", + "DP4", + "DPH", + "DST", + "END", /* Placeholder */ + "EX2", /* ARB only */ + "EXP", + "FLR", /* ARB */ + "FRC", /* ARB */ + "LG2", /* ARB only */ + "LIT", + "LOG", + "MAD", + "MAX", + "MIN", + "MOV", + "MUL", + "POW", /* ARB only */ + "PRINT", /* Mesa only */ + "RCC", + "RCP", + "RSQ", + "SGE", + "SLT", + "SUB", + "SWZ", /* ARB only */ + "XPD" /* ARB only */ + }; + + static const char *file_string[] = { + "TEMP", + "INPUT", + "OUTPUT", + "LOCAL", + "ENV", + "NAMED", + "STATE", + "WRITE_ONLY", + "ADDR" + }; + + static const char swz[] = "xyzw01??"; for (a=0; aInstructions = ap.VPInstructions; #if DEBUG_VP - debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions); -#else - (void) debug_vp_inst; + _mesa_debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions); #endif } diff --git a/src/mesa/shader/arbvertparse.h b/src/mesa/shader/arbvertparse.h index 3e4490b8be..f2ac1570be 100644 --- a/src/mesa/shader/arbvertparse.h +++ b/src/mesa/shader/arbvertparse.h @@ -30,4 +30,7 @@ _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target, const GLubyte * str, GLsizei len, struct vertex_program *program); +extern void +_mesa_debug_vp_inst(GLint num, struct vp_instruction *vp); + #endif diff --git a/src/mesa/shader/grammar.c b/src/mesa/shader/grammar.c index 7864b36b38..1260bf29fb 100644 --- a/src/mesa/shader/grammar.c +++ b/src/mesa/shader/grammar.c @@ -33,7 +33,6 @@ #endif /* - $Id: grammar.c,v 1.10 2004/12/08 14:00:46 alanh Exp $ */ /* diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c index bf1196cbf7..e51ba314f5 100644 --- a/src/mesa/shader/nvfragparse.c +++ b/src/mesa/shader/nvfragparse.c @@ -692,11 +692,15 @@ Parse_CondCodeMask(struct parse_state *parseState, /* look for optional .xyzw swizzle */ if (Parse_String(parseState, ".")) { GLubyte token[100]; + GLuint swz[4]; + if (!Parse_Token(parseState, token)) /* get xyzw suffix */ RETURN_ERROR; - if (!Parse_SwizzleSuffix(token, dstReg->CondSwizzle)) + if (!Parse_SwizzleSuffix(token, swz)) RETURN_ERROR1("Invalid swizzle suffix"); + + dstReg->CondSwizzle = MAKE_SWIZZLE(swz); } return GL_TRUE; @@ -864,6 +868,7 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct fp_dst_register *dstReg) { GLubyte token[100]; + GLint idx; /* Dst reg can be R, H, o[n], RC or HC */ if (!Peek_Token(parseState, token)) @@ -873,20 +878,23 @@ Parse_MaskedDstReg(struct parse_state *parseState, _mesa_strcmp((const char *) token, "HC") == 0) { /* a write-only register */ dstReg->File = PROGRAM_WRITE_ONLY; - if (!Parse_DummyReg(parseState, &dstReg->Index)) + if (!Parse_DummyReg(parseState, &idx)) RETURN_ERROR; + dstReg->Index = idx; } else if (token[0] == 'R' || token[0] == 'H') { /* a temporary register */ dstReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &dstReg->Index)) + if (!Parse_TempReg(parseState, &idx)) RETURN_ERROR; + dstReg->Index = idx; } else if (token[0] == 'o') { /* an output register */ dstReg->File = PROGRAM_OUTPUT; - if (!Parse_OutputReg(parseState, &dstReg->Index)) + if (!Parse_OutputReg(parseState, &idx)) RETURN_ERROR; + dstReg->Index = idx; } else { RETURN_ERROR1("Invalid destination register name"); @@ -900,25 +908,22 @@ Parse_MaskedDstReg(struct parse_state *parseState, if (!Parse_Token(parseState, token)) /* get xyzw writemask */ RETURN_ERROR; - dstReg->WriteMask[0] = GL_FALSE; - dstReg->WriteMask[1] = GL_FALSE; - dstReg->WriteMask[2] = GL_FALSE; - dstReg->WriteMask[3] = GL_FALSE; + dstReg->WriteMask = 0; if (token[k] == 'x') { - dstReg->WriteMask[0] = GL_TRUE; + dstReg->WriteMask |= WRITEMASK_X; k++; } if (token[k] == 'y') { - dstReg->WriteMask[1] = GL_TRUE; + dstReg->WriteMask |= WRITEMASK_Y; k++; } if (token[k] == 'z') { - dstReg->WriteMask[2] = GL_TRUE; + dstReg->WriteMask |= WRITEMASK_Z; k++; } if (token[k] == 'w') { - dstReg->WriteMask[3] = GL_TRUE; + dstReg->WriteMask |= WRITEMASK_W; k++; } if (k == 0) { @@ -927,10 +932,7 @@ Parse_MaskedDstReg(struct parse_state *parseState, } else { - dstReg->WriteMask[0] = GL_TRUE; - dstReg->WriteMask[1] = GL_TRUE; - dstReg->WriteMask[2] = GL_TRUE; - dstReg->WriteMask[3] = GL_TRUE; + dstReg->WriteMask = WRITEMASK_XYZW; } /* optional condition code mask */ @@ -948,10 +950,7 @@ Parse_MaskedDstReg(struct parse_state *parseState, else { /* no cond code mask */ dstReg->CondMask = COND_TR; - dstReg->CondSwizzle[0] = 0; - dstReg->CondSwizzle[1] = 1; - dstReg->CondSwizzle[2] = 2; - dstReg->CondSwizzle[3] = 3; + dstReg->CondSwizzle = SWIZZLE_NOOP; return GL_TRUE; } } @@ -969,6 +968,7 @@ Parse_VectorSrc(struct parse_state *parseState, { GLfloat sign = 1.0F; GLubyte token[100]; + GLint idx; /* * First, take care of +/- and absolute value stuff. @@ -1004,20 +1004,23 @@ Parse_VectorSrc(struct parse_state *parseState, */ if (token[0] == 'R' || token[0] == 'H') { srcReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &srcReg->Index)) + if (!Parse_TempReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else if (token[0] == 'f') { /* XXX this might be an identier! */ srcReg->File = PROGRAM_INPUT; - if (!Parse_FragReg(parseState, &srcReg->Index)) + if (!Parse_FragReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else if (token[0] == 'p') { /* XXX this might be an identier! */ srcReg->File = PROGRAM_LOCAL_PARAM; - if (!Parse_ProgramParamReg(parseState, &srcReg->Index)) + if (!Parse_ProgramParamReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else if (IsLetter(token[0])){ GLubyte ident[100]; @@ -1058,18 +1061,19 @@ Parse_VectorSrc(struct parse_state *parseState, } /* init swizzle fields */ - srcReg->Swizzle[0] = 0; - srcReg->Swizzle[1] = 1; - srcReg->Swizzle[2] = 2; - srcReg->Swizzle[3] = 3; + srcReg->Swizzle = SWIZZLE_NOOP; /* Look for optional swizzle suffix */ if (Parse_String(parseState, ".")) { + GLuint swz[4]; + if (!Parse_Token(parseState, token)) RETURN_ERROR; - if (!Parse_SwizzleSuffix(token, srcReg->Swizzle)) + if (!Parse_SwizzleSuffix(token, swz)) RETURN_ERROR1("Invalid swizzle suffix"); + + srcReg->Swizzle = MAKE_SWIZZLE(swz); } /* Finish absolute value */ @@ -1088,6 +1092,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState, GLubyte token[100]; GLfloat sign = 1.0F; GLboolean needSuffix = GL_TRUE; + GLint idx; /* * First, take care of +/- and absolute value stuff. @@ -1120,13 +1125,15 @@ Parse_ScalarSrcReg(struct parse_state *parseState, /* Src reg can be R, H or a named fragment attrib */ if (token[0] == 'R' || token[0] == 'H') { srcReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &srcReg->Index)) + if (!Parse_TempReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else if (token[0] == 'f') { srcReg->File = PROGRAM_INPUT; - if (!Parse_FragReg(parseState, &srcReg->Index)) + if (!Parse_FragReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else if (token[0] == '{') { /* vector literal */ @@ -1154,6 +1161,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState, RETURN_ERROR2("Invalid scalar source argument", token); } + srcReg->Swizzle = 0; if (needSuffix) { /* parse .[xyzw] suffix */ if (!Parse_String(parseState, ".")) @@ -1163,25 +1171,21 @@ Parse_ScalarSrcReg(struct parse_state *parseState, RETURN_ERROR; if (token[0] == 'x' && token[1] == 0) { - srcReg->Swizzle[0] = 0; + srcReg->Swizzle = 0; } else if (token[0] == 'y' && token[1] == 0) { - srcReg->Swizzle[0] = 1; + srcReg->Swizzle = 1; } else if (token[0] == 'z' && token[1] == 0) { - srcReg->Swizzle[0] = 2; + srcReg->Swizzle = 2; } else if (token[0] == 'w' && token[1] == 0) { - srcReg->Swizzle[0] = 3; + srcReg->Swizzle = 3; } else { RETURN_ERROR1("Invalid scalar source suffix"); } } - else { - srcReg->Swizzle[0] = 0; - } - srcReg->Swizzle[1] = srcReg->Swizzle[2] = srcReg->Swizzle[3] = 0; /* Finish absolute value */ if (srcReg->Abs && !Parse_String(parseState, "|")) { @@ -1199,6 +1203,7 @@ Parse_PrintInstruction(struct parse_state *parseState, const GLubyte *str; GLubyte *msg; GLuint len; + GLint idx; /* The first argument is a literal string 'just like this' */ if (!Parse_String(parseState, "'")) @@ -1220,8 +1225,9 @@ Parse_PrintInstruction(struct parse_state *parseState, GetToken(parseState, token); if (token[0] == 'o') { /* dst reg */ - if (!Parse_OutputReg(parseState, &inst->SrcReg[0].Index)) + if (!Parse_OutputReg(parseState, &idx)) RETURN_ERROR; + inst->SrcReg[0].Index = idx; inst->SrcReg[0].File = PROGRAM_OUTPUT; } else { @@ -1235,10 +1241,7 @@ Parse_PrintInstruction(struct parse_state *parseState, inst->SrcReg[0].File = -1; } - inst->SrcReg[0].Swizzle[0] = 0; - inst->SrcReg[0].Swizzle[1] = 1; - inst->SrcReg[0].Swizzle[2] = 2; - inst->SrcReg[0].Swizzle[3] = 3; + inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; inst->SrcReg[0].NegateBase = GL_FALSE; inst->SrcReg[0].Abs = GL_FALSE; inst->SrcReg[0].NegateAbs = GL_FALSE; @@ -1261,10 +1264,7 @@ Parse_InstructionSequence(struct parse_state *parseState, inst->SrcReg[1].File = (enum register_file) -1; inst->SrcReg[2].File = (enum register_file) -1; inst->DstReg.File = (enum register_file) -1; - inst->DstReg.CondSwizzle[0] = 0; - inst->DstReg.CondSwizzle[1] = 1; - inst->DstReg.CondSwizzle[2] = 2; - inst->DstReg.CondSwizzle[3] = 3; + inst->DstReg.CondSwizzle = SWIZZLE_NOOP; inst->Data = NULL; /* special instructions */ @@ -1400,15 +1400,18 @@ Parse_InstructionSequence(struct parse_state *parseState, /* XXX to-do */ } else if (instMatch.inputs == INPUT_1V_T) { + GLubyte unit, idx; if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) RETURN_ERROR; if (!Parse_String(parseState, ",")) RETURN_ERROR1("Expected ,"); - if (!Parse_TextureImageId(parseState, &inst->TexSrcUnit, - &inst->TexSrcBit)) + if (!Parse_TextureImageId(parseState, &unit, &idx)) RETURN_ERROR; + inst->TexSrcUnit = unit; + inst->TexSrcIdx = idx; } else if (instMatch.inputs == INPUT_3V_T) { + GLubyte unit, idx; if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) RETURN_ERROR; if (!Parse_String(parseState, ",")) @@ -1421,9 +1424,10 @@ Parse_InstructionSequence(struct parse_state *parseState, RETURN_ERROR; if (!Parse_String(parseState, ",")) RETURN_ERROR1("Expected ,"); - if (!Parse_TextureImageId(parseState, &inst->TexSrcUnit, - &inst->TexSrcBit)) + if (!Parse_TextureImageId(parseState, &unit, &idx)) RETURN_ERROR; + inst->TexSrcUnit = unit; + inst->TexSrcIdx = idx; } else if (instMatch.inputs == INPUT_1V_S) { if (!Parse_PrintInstruction(parseState, inst)) @@ -1586,10 +1590,10 @@ PrintSrcReg(const struct fragment_program *program, if (src->File == PROGRAM_NAMED_PARAM) { if (program->Parameters->Parameters[src->Index].Type == CONSTANT) { printf("{%g, %g, %g, %g}", - program->Parameters->Parameters[src->Index].Values[0], - program->Parameters->Parameters[src->Index].Values[1], - program->Parameters->Parameters[src->Index].Values[2], - program->Parameters->Parameters[src->Index].Values[3]); + program->Parameters->ParameterValues[src->Index][0], + program->Parameters->ParameterValues[src->Index][1], + program->Parameters->ParameterValues[src->Index][2], + program->Parameters->ParameterValues[src->Index][3]); } else { ASSERT(program->Parameters->Parameters[src->Index].Type @@ -1619,20 +1623,17 @@ PrintSrcReg(const struct fragment_program *program, _mesa_problem(NULL, "Invalid fragment register %d", src->Index); return; } - if (src->Swizzle[0] == src->Swizzle[1] && - src->Swizzle[0] == src->Swizzle[2] && - src->Swizzle[0] == src->Swizzle[3]) { - _mesa_printf(".%c", comps[src->Swizzle[0]]); + if (GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 1) && + GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 2) && + GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 3)) { + _mesa_printf(".%c", comps[GET_SWZ(src->Swizzle, 0)]); } - else if (src->Swizzle[0] != 0 || - src->Swizzle[1] != 1 || - src->Swizzle[2] != 2 || - src->Swizzle[3] != 3) { + else if (src->Swizzle != SWIZZLE_NOOP) { _mesa_printf(".%c%c%c%c", - comps[src->Swizzle[0]], - comps[src->Swizzle[1]], - comps[src->Swizzle[2]], - comps[src->Swizzle[3]]); + comps[GET_SWZ(src->Swizzle, 0)], + comps[GET_SWZ(src->Swizzle, 1)], + comps[GET_SWZ(src->Swizzle, 2)], + comps[GET_SWZ(src->Swizzle, 3)]); } if (src->Abs) { _mesa_printf("|"); @@ -1643,20 +1644,20 @@ static void PrintTextureSrc(const struct fp_instruction *inst) { _mesa_printf("TEX%d, ", inst->TexSrcUnit); - switch (inst->TexSrcBit) { - case TEXTURE_1D_BIT: + switch (inst->TexSrcIdx) { + case TEXTURE_1D_INDEX: _mesa_printf("1D"); break; - case TEXTURE_2D_BIT: + case TEXTURE_2D_INDEX: _mesa_printf("2D"); break; - case TEXTURE_3D_BIT: + case TEXTURE_3D_INDEX: _mesa_printf("3D"); break; - case TEXTURE_RECT_BIT: + case TEXTURE_RECT_INDEX: _mesa_printf("RECT"); break; - case TEXTURE_CUBE_BIT: + case TEXTURE_CUBE_INDEX: _mesa_printf("CUBE"); break; default: @@ -1673,20 +1674,17 @@ PrintCondCode(const struct fp_dst_register *dst) }; _mesa_printf("%s", ccString[dst->CondMask]); - if (dst->CondSwizzle[0] == dst->CondSwizzle[1] && - dst->CondSwizzle[0] == dst->CondSwizzle[2] && - dst->CondSwizzle[0] == dst->CondSwizzle[3]) { - _mesa_printf(".%c", comps[dst->CondSwizzle[0]]); - } - else if (dst->CondSwizzle[0] != 0 || - dst->CondSwizzle[1] != 1 || - dst->CondSwizzle[2] != 2 || - dst->CondSwizzle[3] != 3) { + if (GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 1) && + GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 2) && + GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 3)) { + _mesa_printf(".%c", comps[GET_SWZ(dst->CondSwizzle, 0)]); + } + else if (dst->CondSwizzle != SWIZZLE_NOOP) { _mesa_printf(".%c%c%c%c", - comps[dst->CondSwizzle[0]], - comps[dst->CondSwizzle[1]], - comps[dst->CondSwizzle[2]], - comps[dst->CondSwizzle[3]]); + comps[GET_SWZ(dst->CondSwizzle, 0)], + comps[GET_SWZ(dst->CondSwizzle, 1)], + comps[GET_SWZ(dst->CondSwizzle, 2)], + comps[GET_SWZ(dst->CondSwizzle, 3)]); } } @@ -1694,9 +1692,6 @@ PrintCondCode(const struct fp_dst_register *dst) static void PrintDstReg(const struct fp_dst_register *dst) { - GLint w = dst->WriteMask[0] + dst->WriteMask[1] - + dst->WriteMask[2] + dst->WriteMask[3]; - if (dst->File == PROGRAM_OUTPUT) { _mesa_printf("o[%s]", OutputRegisters[dst->Index]); } @@ -1716,23 +1711,20 @@ PrintDstReg(const struct fp_dst_register *dst) _mesa_printf("???"); } - if (w != 0 && w != 4) { + if (dst->WriteMask != 0 && dst->WriteMask != 0xf) { _mesa_printf("."); - if (dst->WriteMask[0]) + if (dst->WriteMask & 0x1) _mesa_printf("x"); - if (dst->WriteMask[1]) + if (dst->WriteMask & 0x2) _mesa_printf("y"); - if (dst->WriteMask[2]) + if (dst->WriteMask & 0x4) _mesa_printf("z"); - if (dst->WriteMask[3]) + if (dst->WriteMask & 0x8) _mesa_printf("w"); } if (dst->CondMask != COND_TR || - dst->CondSwizzle[0] != 0 || - dst->CondSwizzle[1] != 1 || - dst->CondSwizzle[2] != 2 || - dst->CondSwizzle[3] != 3) { + dst->CondSwizzle != SWIZZLE_NOOP) { _mesa_printf(" ("); PrintCondCode(dst); _mesa_printf(")"); diff --git a/src/mesa/shader/nvfragprog.h b/src/mesa/shader/nvfragprog.h index ddfc4993ed..fb846f1107 100644 --- a/src/mesa/shader/nvfragprog.h +++ b/src/mesa/shader/nvfragprog.h @@ -34,7 +34,7 @@ #define NVFRAGPROG_H #include "config.h" - +#include "mtypes.h" /* output registers */ #define FRAG_OUTPUT_COLR 0 @@ -62,8 +62,7 @@ /* Fragment program instruction opcodes */ enum fp_opcode { - FP_OPCODE_INVALID = -1, /* Force signed enum */ - FP_OPCODE_ABS = 1000, /* ARB_f_p only */ + FP_OPCODE_ABS, /* ARB_f_p only */ FP_OPCODE_ADD, FP_OPCODE_CMP, /* ARB_f_p only */ FP_OPCODE_COS, @@ -125,41 +124,44 @@ enum fp_opcode { /* Instruction source register */ struct fp_src_register { - enum register_file File; - GLint Index; - GLuint Swizzle[4]; - GLboolean NegateBase; /* negate before absolute value? */ - GLboolean Abs; /* take absolute value? */ - GLboolean NegateAbs; /* negate after absolute value? */ + GLuint File:4; + GLuint Index:8; + GLuint Swizzle:12; + GLuint NegateBase:4; /* ARB: negate/extended negate. + NV: negate before absolute value? */ + GLuint Abs:1; /* NV: take absolute value? */ + GLuint NegateAbs:1; /* NV: negate after absolute value? */ }; /* Instruction destination register */ struct fp_dst_register { - enum register_file File; - GLint Index; - GLboolean WriteMask[4]; - GLuint CondMask; - GLuint CondSwizzle[4]; + GLuint File:4; + GLuint Index:8; + GLuint WriteMask:4; + GLuint CondMask:4; /* NV: enough bits? */ + GLuint CondSwizzle:12; /* NV: enough bits? */ }; /* Fragment program instruction */ struct fp_instruction { - enum fp_opcode Opcode; - struct fp_src_register SrcReg[3]; - struct fp_dst_register DstReg; - GLboolean Saturate; - GLboolean UpdateCondRegister; - GLubyte Precision; /* FLOAT32, FLOAT16 or FIXED12 */ - GLubyte TexSrcUnit; /* texture unit for TEX, TXD, TXP instructions */ - GLubyte TexSrcBit; /* TEXTURE_1D,2D,3D,CUBE,RECT_BIT source target */ + GLuint Opcode:6; + GLuint Saturate:1; + GLuint UpdateCondRegister:1; /* NV */ + GLuint Precision:2; /* NV: unused/unneeded? */ + GLuint TexSrcUnit:4; /* texture unit for TEX, TXD, TXP instructions */ + GLuint TexSrcIdx:3; /* TEXTURE_1D,2D,3D,CUBE,RECT_INDEX source target */ + #if FEATURE_MESA_program_debug - GLint StringPos; + GLint StringPos:15; /* enough bits? */ #endif + void *Data; /* some arbitrary data, only used for PRINT instruction now */ + struct fp_src_register SrcReg[3]; + struct fp_dst_register DstReg; }; diff --git a/src/mesa/shader/nvvertexec.c b/src/mesa/shader/nvvertexec.c index f0558da1ab..679400c13e 100644 --- a/src/mesa/shader/nvvertexec.c +++ b/src/mesa/shader/nvvertexec.c @@ -239,7 +239,7 @@ get_register_pointer( const struct vp_src_register *source, else if (source->File == PROGRAM_ENV_PARAM) return state->Parameters[reg]; else - return state->Current->Parameters->Parameters[reg].Values; + return state->Current->Parameters->ParameterValues[reg]; } else { switch (source->File) { @@ -261,7 +261,7 @@ get_register_pointer( const struct vp_src_register *source, return state->Parameters[source->Index]; case PROGRAM_STATE_VAR: ASSERT(source->Index < state->Current->Parameters->NumParameters); - return state->Current->Parameters->Parameters[source->Index].Values; + return state->Current->Parameters->ParameterValues[source->Index]; default: _mesa_problem(NULL, "Bad source register file in get_register_pointer"); @@ -284,16 +284,16 @@ fetch_vector4( const struct vp_src_register *source, const GLfloat *src = get_register_pointer(source, state); if (source->Negate) { - result[0] = -src[source->Swizzle[0]]; - result[1] = -src[source->Swizzle[1]]; - result[2] = -src[source->Swizzle[2]]; - result[3] = -src[source->Swizzle[3]]; + result[0] = -src[GET_SWZ(source->Swizzle, 0)]; + result[1] = -src[GET_SWZ(source->Swizzle, 1)]; + result[2] = -src[GET_SWZ(source->Swizzle, 2)]; + result[3] = -src[GET_SWZ(source->Swizzle, 3)]; } else { - result[0] = src[source->Swizzle[0]]; - result[1] = src[source->Swizzle[1]]; - result[2] = src[source->Swizzle[2]]; - result[3] = src[source->Swizzle[3]]; + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[1] = src[GET_SWZ(source->Swizzle, 1)]; + result[2] = src[GET_SWZ(source->Swizzle, 2)]; + result[3] = src[GET_SWZ(source->Swizzle, 3)]; } } @@ -310,10 +310,10 @@ fetch_vector1( const struct vp_src_register *source, const GLfloat *src = get_register_pointer(source, state); if (source->Negate) { - result[0] = -src[source->Swizzle[0]]; + result[0] = -src[GET_SWZ(source->Swizzle, 0)]; } else { - result[0] = src[source->Swizzle[0]]; + result[0] = src[GET_SWZ(source->Swizzle, 0)]; } } @@ -347,13 +347,13 @@ store_vector4( const struct vp_dst_register *dest, return; } - if (dest->WriteMask[0]) + if (dest->WriteMask & WRITEMASK_X) dst[0] = value[0]; - if (dest->WriteMask[1]) + if (dest->WriteMask & WRITEMASK_Y) dst[1] = value[1]; - if (dest->WriteMask[2]) + if (dest->WriteMask & WRITEMASK_Z) dst[2] = value[2]; - if (dest->WriteMask[3]) + if (dest->WriteMask & WRITEMASK_W) dst[3] = value[3]; } @@ -766,12 +766,12 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program) /* do extended swizzling here */ for (i = 0; i < 3; i++) { - if (source->Swizzle[i] == SWIZZLE_ZERO) + if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ZERO) result[i] = 0.0; - else if (source->Swizzle[i] == SWIZZLE_ONE) + else if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ONE) result[i] = -1.0; else - result[i] = -src[source->Swizzle[i]]; + result[i] = -src[GET_SWZ(source->Swizzle, i)]; if (source->Negate) result[i] = -result[i]; } diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c index b02143a2e6..23a01c7617 100644 --- a/src/mesa/shader/nvvertparse.c +++ b/src/mesa/shader/nvvertparse.c @@ -563,6 +563,7 @@ static GLboolean Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstReg) { GLubyte token[100]; + GLint idx; /* Dst reg can be R or o[n] */ if (!Peek_Token(parseState, token)) @@ -571,22 +572,25 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstRe if (token[0] == 'R') { /* a temporary register */ dstReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &dstReg->Index)) + if (!Parse_TempReg(parseState, &idx)) RETURN_ERROR; + dstReg->Index = idx; } else if (!parseState->isStateProgram && token[0] == 'o') { /* an output register */ dstReg->File = PROGRAM_OUTPUT; - if (!Parse_OutputReg(parseState, &dstReg->Index)) + if (!Parse_OutputReg(parseState, &idx)) RETURN_ERROR; + dstReg->Index = idx; } else if (parseState->isStateProgram && token[0] == 'c' && parseState->isStateProgram) { /* absolute program parameter register */ /* Only valid for vertex state programs */ dstReg->File = PROGRAM_ENV_PARAM; - if (!Parse_AbsParamReg(parseState, &dstReg->Index)) + if (!Parse_AbsParamReg(parseState, &idx)) RETURN_ERROR; + dstReg->Index = idx; } else { RETURN_ERROR1("Bad destination register name"); @@ -606,25 +610,22 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstRe if (!Parse_Token(parseState, token)) RETURN_ERROR; - dstReg->WriteMask[0] = GL_FALSE; - dstReg->WriteMask[1] = GL_FALSE; - dstReg->WriteMask[2] = GL_FALSE; - dstReg->WriteMask[3] = GL_FALSE; + dstReg->WriteMask = 0; if (token[k] == 'x') { - dstReg->WriteMask[0] = GL_TRUE; + dstReg->WriteMask |= WRITEMASK_X; k++; } if (token[k] == 'y') { - dstReg->WriteMask[1] = GL_TRUE; + dstReg->WriteMask |= WRITEMASK_Y; k++; } if (token[k] == 'z') { - dstReg->WriteMask[2] = GL_TRUE; + dstReg->WriteMask |= WRITEMASK_Z; k++; } if (token[k] == 'w') { - dstReg->WriteMask[3] = GL_TRUE; + dstReg->WriteMask |= WRITEMASK_W; k++; } if (k == 0) { @@ -633,10 +634,7 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstRe return GL_TRUE; } else { - dstReg->WriteMask[0] = GL_TRUE; - dstReg->WriteMask[1] = GL_TRUE; - dstReg->WriteMask[2] = GL_TRUE; - dstReg->WriteMask[3] = GL_TRUE; + dstReg->WriteMask = WRITEMASK_XYZW; return GL_TRUE; } } @@ -646,6 +644,7 @@ static GLboolean Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcReg) { GLubyte token[100]; + GLint idx; srcReg->RelAddr = GL_FALSE; @@ -665,8 +664,9 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR /* Src reg can be R, c[n], c[n +/- offset], or a named vertex attrib */ if (token[0] == 'R') { srcReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &srcReg->Index)) + if (!Parse_TempReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else if (token[0] == 'c') { if (!Parse_ParamReg(parseState, srcReg)) @@ -674,18 +674,16 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR } else if (token[0] == 'v') { srcReg->File = PROGRAM_INPUT; - if (!Parse_AttribReg(parseState, &srcReg->Index)) + if (!Parse_AttribReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else { RETURN_ERROR2("Bad source register name", token); } /* init swizzle fields */ - srcReg->Swizzle[0] = 0; - srcReg->Swizzle[1] = 1; - srcReg->Swizzle[2] = 2; - srcReg->Swizzle[3] = 3; + srcReg->Swizzle = SWIZZLE_NOOP; /* Look for optional swizzle suffix */ if (!Peek_Token(parseState, token)) @@ -699,13 +697,13 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR if (token[1] == 0) { /* single letter swizzle */ if (token[0] == 'x') - ASSIGN_4V(srcReg->Swizzle, 0, 0, 0, 0); + srcReg->Swizzle = MAKE_SWIZZLE4(0, 0, 0, 0); else if (token[0] == 'y') - ASSIGN_4V(srcReg->Swizzle, 1, 1, 1, 1); + srcReg->Swizzle = MAKE_SWIZZLE4(1, 1, 1, 1); else if (token[0] == 'z') - ASSIGN_4V(srcReg->Swizzle, 2, 2, 2, 2); + srcReg->Swizzle = MAKE_SWIZZLE4(2, 2, 2, 2); else if (token[0] == 'w') - ASSIGN_4V(srcReg->Swizzle, 3, 3, 3, 3); + srcReg->Swizzle = MAKE_SWIZZLE4(3, 3, 3, 3); else RETURN_ERROR1("Expected x, y, z, or w"); } @@ -714,13 +712,13 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR GLint k; for (k = 0; token[k] && k < 5; k++) { if (token[k] == 'x') - srcReg->Swizzle[k] = 0; + srcReg->Swizzle |= 0 << (k*3); else if (token[k] == 'y') - srcReg->Swizzle[k] = 1; + srcReg->Swizzle |= 1 << (k*3); else if (token[k] == 'z') - srcReg->Swizzle[k] = 2; + srcReg->Swizzle |= 2 << (k*3); else if (token[k] == 'w') - srcReg->Swizzle[k] = 3; + srcReg->Swizzle |= 3 << (k*3); else RETURN_ERROR; } @@ -737,6 +735,7 @@ static GLboolean Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcReg) { GLubyte token[100]; + GLint idx; srcReg->RelAddr = GL_FALSE; @@ -756,8 +755,9 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe /* Src reg can be R, c[n], c[n +/- offset], or a named vertex attrib */ if (token[0] == 'R') { srcReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &srcReg->Index)) + if (!Parse_TempReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else if (token[0] == 'c') { if (!Parse_ParamReg(parseState, srcReg)) @@ -765,8 +765,9 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe } else if (token[0] == 'v') { srcReg->File = PROGRAM_INPUT; - if (!Parse_AttribReg(parseState, &srcReg->Index)) + if (!Parse_AttribReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else { RETURN_ERROR2("Bad source register name", token); @@ -780,21 +781,20 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe RETURN_ERROR; if (token[0] == 'x' && token[1] == 0) { - srcReg->Swizzle[0] = 0; + srcReg->Swizzle = 0; } else if (token[0] == 'y' && token[1] == 0) { - srcReg->Swizzle[0] = 1; + srcReg->Swizzle = 1; } else if (token[0] == 'z' && token[1] == 0) { - srcReg->Swizzle[0] = 2; + srcReg->Swizzle = 2; } else if (token[0] == 'w' && token[1] == 0) { - srcReg->Swizzle[0] = 3; + srcReg->Swizzle = 3; } else { RETURN_ERROR1("Bad scalar source suffix"); } - srcReg->Swizzle[1] = srcReg->Swizzle[2] = srcReg->Swizzle[3] = 0; return GL_TRUE; } @@ -1042,6 +1042,7 @@ Parse_PrintInstruction(struct parse_state *parseState, struct vp_instruction *in GLuint len; GLubyte token[100]; struct vp_src_register *srcReg = &inst->SrcReg[0]; + GLint idx; inst->Opcode = VP_OPCODE_PRINT; inst->StringPos = parseState->curLine - parseState->start; @@ -1069,18 +1070,16 @@ Parse_PrintInstruction(struct parse_state *parseState, struct vp_instruction *in srcReg->RelAddr = GL_FALSE; srcReg->Negate = GL_FALSE; - srcReg->Swizzle[0] = 0; - srcReg->Swizzle[1] = 1; - srcReg->Swizzle[2] = 2; - srcReg->Swizzle[3] = 3; + srcReg->Swizzle = SWIZZLE_NOOP; /* Register can be R, c[n], c[n +/- offset], a named vertex attrib, * or an o[n] output register. */ if (token[0] == 'R') { srcReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &srcReg->Index)) + if (!Parse_TempReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else if (token[0] == 'c') { srcReg->File = PROGRAM_ENV_PARAM; @@ -1089,13 +1088,15 @@ Parse_PrintInstruction(struct parse_state *parseState, struct vp_instruction *in } else if (token[0] == 'v') { srcReg->File = PROGRAM_INPUT; - if (!Parse_AttribReg(parseState, &srcReg->Index)) + if (!Parse_AttribReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else if (token[0] == 'o') { srcReg->File = PROGRAM_OUTPUT; - if (!Parse_OutputReg(parseState, &srcReg->Index)) + if (!Parse_OutputReg(parseState, &idx)) RETURN_ERROR; + srcReg->Index = idx; } else { RETURN_ERROR2("Bad source register name", token); @@ -1448,20 +1449,17 @@ PrintSrcReg(const struct vp_src_register *src) _mesa_printf("R%d", src->Index); } - if (src->Swizzle[0] == src->Swizzle[1] && - src->Swizzle[0] == src->Swizzle[2] && - src->Swizzle[0] == src->Swizzle[3]) { - _mesa_printf(".%c", comps[src->Swizzle[0]]); + if (GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 1) && + GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 2) && + GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 3)) { + _mesa_printf(".%c", comps[GET_SWZ(src->Swizzle, 0)]); } - else if (src->Swizzle[0] != 0 || - src->Swizzle[1] != 1 || - src->Swizzle[2] != 2 || - src->Swizzle[3] != 3) { + else if (src->Swizzle != SWIZZLE_NOOP) { _mesa_printf(".%c%c%c%c", - comps[src->Swizzle[0]], - comps[src->Swizzle[1]], - comps[src->Swizzle[2]], - comps[src->Swizzle[3]]); + comps[GET_SWZ(src->Swizzle, 0)], + comps[GET_SWZ(src->Swizzle, 1)], + comps[GET_SWZ(src->Swizzle, 2)], + comps[GET_SWZ(src->Swizzle, 3)]); } } @@ -1469,9 +1467,6 @@ PrintSrcReg(const struct vp_src_register *src) static void PrintDstReg(const struct vp_dst_register *dst) { - GLint w = dst->WriteMask[0] + dst->WriteMask[1] - + dst->WriteMask[2] + dst->WriteMask[3]; - if (dst->File == PROGRAM_OUTPUT) { _mesa_printf("o[%s]", OutputRegisters[dst->Index]); } @@ -1486,15 +1481,15 @@ PrintDstReg(const struct vp_dst_register *dst) _mesa_printf("R%d", dst->Index); } - if (w != 0 && w != 4) { + if (dst->WriteMask != 0 && dst->WriteMask != 0xf) { _mesa_printf("."); - if (dst->WriteMask[0]) + if (dst->WriteMask & 0x1) _mesa_printf("x"); - if (dst->WriteMask[1]) + if (dst->WriteMask & 0x2) _mesa_printf("y"); - if (dst->WriteMask[2]) + if (dst->WriteMask & 0x4) _mesa_printf("z"); - if (dst->WriteMask[3]) + if (dst->WriteMask & 0x8) _mesa_printf("w"); } } diff --git a/src/mesa/shader/nvvertprog.h b/src/mesa/shader/nvvertprog.h index 583b901207..ca9930a974 100644 --- a/src/mesa/shader/nvvertprog.h +++ b/src/mesa/shader/nvvertprog.h @@ -37,38 +37,36 @@ /* Vertex program opcodes */ enum vp_opcode { - VP_OPCODE_MOV, - VP_OPCODE_LIT, - VP_OPCODE_RCP, - VP_OPCODE_RSQ, - VP_OPCODE_EXP, - VP_OPCODE_LOG, - VP_OPCODE_MUL, + VP_OPCODE_ABS, VP_OPCODE_ADD, + VP_OPCODE_ARL, VP_OPCODE_DP3, VP_OPCODE_DP4, + VP_OPCODE_DPH, VP_OPCODE_DST, - VP_OPCODE_MIN, - VP_OPCODE_MAX, - VP_OPCODE_SLT, - VP_OPCODE_SGE, + VP_OPCODE_END, /* Placeholder */ + VP_OPCODE_EX2, /* ARB only */ + VP_OPCODE_EXP, + VP_OPCODE_FLR, /* ARB */ + VP_OPCODE_FRC, /* ARB */ + VP_OPCODE_LG2, /* ARB only */ + VP_OPCODE_LIT, + VP_OPCODE_LOG, VP_OPCODE_MAD, - VP_OPCODE_ARL, - VP_OPCODE_DPH, + VP_OPCODE_MAX, + VP_OPCODE_MIN, + VP_OPCODE_MOV, + VP_OPCODE_MUL, + VP_OPCODE_POW, /* ARB only */ + VP_OPCODE_PRINT, /* Mesa only */ VP_OPCODE_RCC, + VP_OPCODE_RCP, + VP_OPCODE_RSQ, + VP_OPCODE_SGE, + VP_OPCODE_SLT, VP_OPCODE_SUB, - VP_OPCODE_ABS, - VP_OPCODE_END, - /* Additional opcodes for GL_ARB_vertex_program */ - VP_OPCODE_FLR, - VP_OPCODE_FRC, - VP_OPCODE_EX2, - VP_OPCODE_LG2, - VP_OPCODE_POW, - VP_OPCODE_XPD, - VP_OPCODE_SWZ, - /* Special Mesa opcodes */ - VP_OPCODE_PRINT + VP_OPCODE_SWZ, /* ARB only */ + VP_OPCODE_XPD /* ARB only */ }; @@ -76,34 +74,35 @@ enum vp_opcode /* Instruction source register */ struct vp_src_register { - enum register_file File; /* which register file */ - GLint Index; /* index into register file */ - GLubyte Swizzle[4]; /* Each value is 0,1,2,3 for x,y,z,w or */ - /* SWIZZLE_ZERO or SWIZZLE_ONE for VP_OPCODE_SWZ. */ - GLboolean Negate; - GLboolean RelAddr; + GLuint File:4; + GLuint Index:8; + GLuint Swizzle:12; + GLuint Negate:4; /* ARB requires component-wise negation. */ + GLuint RelAddr:1; + GLuint pad:3; }; /* Instruction destination register */ struct vp_dst_register { - enum register_file File; /* which register file */ - GLint Index; /* index into register file */ - GLboolean WriteMask[4]; + GLuint File:4; + GLuint Index:8; + GLuint WriteMask:4; + GLuint pad:16; }; /* Vertex program instruction */ struct vp_instruction { - enum vp_opcode Opcode; - struct vp_src_register SrcReg[3]; - struct vp_dst_register DstReg; + GLshort Opcode; #if FEATURE_MESA_program_debug - GLint StringPos; + GLshort StringPos; #endif void *Data; /* some arbitrary data, only used for PRINT instruction now */ + struct vp_src_register SrcReg[3]; + struct vp_dst_register DstReg; }; diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index faa4889a2e..15b9021660 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -368,6 +368,7 @@ _mesa_free_parameters(struct program_parameter_list *paramList) _mesa_free((void *) paramList->Parameters[i].Name); } _mesa_free(paramList->Parameters); + _mesa_free(paramList->ParameterValues); paramList->NumParameters = 0; paramList->Parameters = NULL; } @@ -387,7 +388,13 @@ add_parameter(struct program_parameter_list *paramList, _mesa_realloc(paramList->Parameters, n * sizeof(struct program_parameter), (n + 1) * sizeof(struct program_parameter)); - if (!paramList->Parameters) { + paramList->ParameterValues = (GLfloat (*)[4]) + _mesa_realloc(paramList->ParameterValues, + n * 4 * sizeof(GLfloat), + (n + 1) * 4 * sizeof(GLfloat)); + + if (!paramList->Parameters || + !paramList->ParameterValues) { /* out of memory */ paramList->NumParameters = 0; return -1; @@ -397,7 +404,7 @@ add_parameter(struct program_parameter_list *paramList, paramList->Parameters[n].Name = _mesa_strdup(name); paramList->Parameters[n].Type = type; if (values) - COPY_4V(paramList->Parameters[n].Values, values); + COPY_4V(paramList->ParameterValues[n], values); return (GLint) n; } } @@ -491,7 +498,7 @@ _mesa_lookup_parameter_value(struct program_parameter_list *paramList, /* name is null-terminated */ for (i = 0; i < paramList->NumParameters; i++) { if (_mesa_strcmp(paramList->Parameters[i].Name, name) == 0) - return paramList->Parameters[i].Values; + return paramList->ParameterValues[i]; } } else { @@ -499,7 +506,7 @@ _mesa_lookup_parameter_value(struct program_parameter_list *paramList, for (i = 0; i < paramList->NumParameters; i++) { if (_mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen) - return paramList->Parameters[i].Values; + return paramList->ParameterValues[i]; } } return NULL; @@ -629,14 +636,18 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[], /* Compute infinite half angle vector: * half-vector = light_position + (0, 0, 1) * and then normalize. w = 0 - * - * light.EyePosition.w should be 0 for infinite lights. + * + * light.EyePosition.w should be 0 for infinite lights. */ - ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition); - NORMALIZE_3FV(value); - value[3] = 0; + ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition); + NORMALIZE_3FV(value); + value[3] = 0; } return; + case STATE_POSITION_NORMALIZED: + COPY_4V(value, ctx->Light.Light[ln].EyePosition); + NORMALIZE_3FV( value ); + return; default: _mesa_problem(ctx, "Invalid light state in fetch_state"); return; @@ -879,6 +890,20 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[], } } return; + + case STATE_INTERNAL: + { + switch (state[1]) { + case STATE_NORMAL_SCALE: + ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1); + break; + default: + _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); + return; + } + } + return; + default: _mesa_problem(ctx, "Invalid state in _mesa_fetch_state"); return; @@ -903,8 +928,9 @@ _mesa_load_state_parameters(GLcontext *ctx, for (i = 0; i < paramList->NumParameters; i++) { if (paramList->Parameters[i].Type == STATE) { - _mesa_fetch_state(ctx, paramList->Parameters[i].StateIndexes, - paramList->Parameters[i].Values); + _mesa_fetch_state(ctx, + paramList->Parameters[i].StateIndexes, + paramList->ParameterValues[i]); } } } diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index dcd64adfe9..e290c92ee3 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -51,6 +51,29 @@ #define SWIZZLE_ZERO 4 /* keep these values together: KW */ #define SWIZZLE_ONE 5 /* keep these values together: KW */ +#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9)) +#define MAKE_SWIZZLE(x) MAKE_SWIZZLE4((x)[0], (x)[1], (x)[2], (x)[3]) +#define SWIZZLE_NOOP MAKE_SWIZZLE4(0,1,2,3) +#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7) +#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1) + + +#define WRITEMASK_X 0x1 +#define WRITEMASK_Y 0x2 +#define WRITEMASK_XY 0x3 +#define WRITEMASK_Z 0x4 +#define WRITEMASK_XZ 0x5 +#define WRITEMASK_YZ 0x6 +#define WRITEMASK_XYZ 0x7 +#define WRITEMASK_W 0x8 +#define WRITEMASK_XW 0x9 +#define WRITEMASK_YW 0xa +#define WRITEMASK_XYW 0xb +#define WRITEMASK_ZW 0xc +#define WRITEMASK_XZW 0xd +#define WRITEMASK_YZW 0xe +#define WRITEMASK_XYZW 0xf + extern struct program _mesa_DummyProgram; @@ -158,7 +181,11 @@ enum state_index { STATE_FRAGMENT_PROGRAM, STATE_ENV, - STATE_LOCAL + STATE_LOCAL, + + STATE_INTERNAL, /* Mesa additions */ + STATE_NORMAL_SCALE, + STATE_POSITION_NORMALIZED }; @@ -183,7 +210,6 @@ struct program_parameter const char *Name; /* Null-terminated */ enum parameter_type Type; enum state_index StateIndexes[6]; /* Global state reference */ - GLfloat Values[4]; }; @@ -191,6 +217,7 @@ struct program_parameter_list { GLuint NumParameters; struct program_parameter *Parameters; + GLfloat (*ParameterValues)[4]; }; diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index 5d9979c5c6..2fea568cc9 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -137,10 +137,10 @@ get_register_pointer( GLcontext *ctx, /* Fallthrough */ case PROGRAM_NAMED_PARAM: ASSERT(source->Index < (GLint) program->Parameters->NumParameters); - src = program->Parameters->Parameters[source->Index].Values; + src = program->Parameters->ParameterValues[source->Index]; break; default: - _mesa_problem(ctx, "Invalid input register file in fetch_vector4"); + _mesa_problem(ctx, "Invalid input register file %d in fetch_vector4", source->File); src = NULL; } return src; @@ -161,10 +161,10 @@ fetch_vector4( GLcontext *ctx, const GLfloat *src = get_register_pointer(ctx, source, machine, program); ASSERT(src); - result[0] = src[source->Swizzle[0]]; - result[1] = src[source->Swizzle[1]]; - result[2] = src[source->Swizzle[2]]; - result[3] = src[source->Swizzle[3]]; + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[1] = src[GET_SWZ(source->Swizzle, 1)]; + result[2] = src[GET_SWZ(source->Swizzle, 2)]; + result[3] = src[GET_SWZ(source->Swizzle, 3)]; if (source->NegateBase) { result[0] = -result[0]; @@ -291,10 +291,10 @@ fetch_vector4_deriv( GLcontext *ctx, return GL_FALSE; } - result[0] = src[source->Swizzle[0]]; - result[1] = src[source->Swizzle[1]]; - result[2] = src[source->Swizzle[2]]; - result[3] = src[source->Swizzle[3]]; + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[1] = src[GET_SWZ(source->Swizzle, 1)]; + result[2] = src[GET_SWZ(source->Swizzle, 2)]; + result[3] = src[GET_SWZ(source->Swizzle, 3)]; if (source->NegateBase) { result[0] = -result[0]; @@ -331,7 +331,7 @@ fetch_vector1( GLcontext *ctx, const GLfloat *src = get_register_pointer(ctx, source, machine, program); ASSERT(src); - result[0] = src[source->Swizzle[0]]; + result[0] = src[GET_SWZ(source->Swizzle, 0)]; if (source->NegateBase) { result[0] = -result[0]; @@ -397,8 +397,8 @@ store_vector4( const struct fp_instruction *inst, GLfloat *dstReg; GLfloat dummyReg[4]; GLfloat clampedValue[4]; - const GLboolean *writeMask = dest->WriteMask; GLboolean condWriteMask[4]; + GLuint writeMask = dest->WriteMask; switch (dest->File) { case PROGRAM_OUTPUT: @@ -433,33 +433,37 @@ store_vector4( const struct fp_instruction *inst, } if (dest->CondMask != COND_TR) { - condWriteMask[0] = writeMask[0] - && test_cc(machine->CondCodes[dest->CondSwizzle[0]], dest->CondMask); - condWriteMask[1] = writeMask[1] - && test_cc(machine->CondCodes[dest->CondSwizzle[1]], dest->CondMask); - condWriteMask[2] = writeMask[2] - && test_cc(machine->CondCodes[dest->CondSwizzle[2]], dest->CondMask); - condWriteMask[3] = writeMask[3] - && test_cc(machine->CondCodes[dest->CondSwizzle[3]], dest->CondMask); - writeMask = condWriteMask; + condWriteMask[0] = GET_BIT(writeMask, 0) + && test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 0)], dest->CondMask); + condWriteMask[1] = GET_BIT(writeMask, 1) + && test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 1)], dest->CondMask); + condWriteMask[2] = GET_BIT(writeMask, 2) + && test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 2)], dest->CondMask); + condWriteMask[3] = GET_BIT(writeMask, 3) + && test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 3)], dest->CondMask); + + writeMask = ((condWriteMask[0] << 0) | + (condWriteMask[1] << 1) | + (condWriteMask[2] << 2) | + (condWriteMask[3] << 3)); } - if (writeMask[0]) { + if (GET_BIT(writeMask, 0)) { dstReg[0] = value[0]; if (updateCC) machine->CondCodes[0] = generate_cc(value[0]); } - if (writeMask[1]) { + if (GET_BIT(writeMask, 1)) { dstReg[1] = value[1]; if (updateCC) machine->CondCodes[1] = generate_cc(value[1]); } - if (writeMask[2]) { + if (GET_BIT(writeMask, 2)) { dstReg[2] = value[2]; if (updateCC) machine->CondCodes[2] = generate_cc(value[2]); } - if (writeMask[3]) { + if (GET_BIT(writeMask, 3)) { dstReg[3] = value[3]; if (updateCC) machine->CondCodes[3] = generate_cc(value[3]); @@ -779,12 +783,12 @@ execute_program( GLcontext *ctx, break; case FP_OPCODE_KIL_NV: /* NV_f_p only */ { - const GLuint *swizzle = inst->DstReg.CondSwizzle; + const GLuint swizzle = inst->DstReg.CondSwizzle; const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[swizzle[0]], condMask) || - test_cc(machine->CondCodes[swizzle[1]], condMask) || - test_cc(machine->CondCodes[swizzle[2]], condMask) || - test_cc(machine->CondCodes[swizzle[3]], condMask)) { + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { return GL_FALSE; } } @@ -1154,12 +1158,13 @@ execute_program( GLcontext *ctx, /* do extended swizzling here */ for (i = 0; i < 3; i++) { - if (source->Swizzle[i] == SWIZZLE_ZERO) + if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ZERO) result[i] = 0.0; - else if (source->Swizzle[i] == SWIZZLE_ONE) + else if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ONE) result[i] = -1.0; else - result[i] = -src[source->Swizzle[i]]; + result[i] = -src[GET_SWZ(source->Swizzle, i)]; + if (source->NegateBase) result[i] = -result[i]; } @@ -1224,7 +1229,7 @@ execute_program( GLcontext *ctx, { GLfloat texcoord[4], color[4]; fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); - if (inst->TexSrcBit != TEXTURE_CUBE_BIT) { + if (inst->TexSrcIdx != TEXTURE_CUBE_INDEX) { texcoord[0] /= texcoord[3]; texcoord[1] /= texcoord[3]; texcoord[2] /= texcoord[3]; -- cgit v1.2.3