Пример #1
0
static struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c, 
						     GLfloat s0,
						     GLfloat s1,
						     GLfloat s2,
						     GLfloat s3)
{
   struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
   GLfloat values[4];
   GLuint idx;
   GLuint swizzle;

   values[0] = s0;
   values[1] = s1;
   values[2] = s2;
   values[3] = s3;

   /* Have to search, otherwise multiple compilations will each grow
    * the parameter list.
    */
   for (idx = 0; idx < paramList->NumParameters; idx++) {
      if (paramList->Parameters[idx].Type == PROGRAM_CONSTANT &&
	  memcmp(paramList->ParameterValues[idx], values, sizeof(values)) == 0)

	 /* XXX: this mimics the mesa bug which puts all constants and
	  * parameters into the "PROGRAM_STATE_VAR" category:
	  */
	 return src_reg(PROGRAM_STATE_VAR, idx);
   }
   
   idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle );
   assert(swizzle == SWIZZLE_NOOP); /* Need to handle swizzle in reg setup */
   return src_reg(PROGRAM_STATE_VAR, idx);
}
Пример #2
0
/**
 * "Post-process" a GPU program.  This is intended to be used for debugging.
 * Example actions include no-op'ing instructions or changing instruction
 * behaviour.
 */
void
_mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog)
{
   static const GLfloat white[4] = { 0.5, 0.5, 0.5, 0.5 };
   GLuint i;
   GLuint whiteSwizzle;
   GLint whiteIndex = _mesa_add_unnamed_constant(prog->Parameters,
                                                 (gl_constant_value *) white,
                                                 4, &whiteSwizzle);

   (void) whiteIndex;

   for (i = 0; i < prog->NumInstructions; i++) {
      struct prog_instruction *inst = prog->Instructions + i;
      const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);

      (void) n;

      if (_mesa_is_tex_instruction(inst->Opcode)) {
#if 0
         /* replace TEX/TXP/TXB with MOV */
         inst->Opcode = OPCODE_MOV;
         inst->DstReg.WriteMask = WRITEMASK_XYZW;
         inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
         inst->SrcReg[0].Negate = NEGATE_NONE;
#endif

#if 0
         /* disable shadow texture mode */
         inst->TexShadow = 0;
#endif
      }

      if (inst->Opcode == OPCODE_TXP) {
#if 0
         inst->Opcode = OPCODE_MOV;
         inst->DstReg.WriteMask = WRITEMASK_XYZW;
         inst->SrcReg[0].File = PROGRAM_CONSTANT;
         inst->SrcReg[0].Index = whiteIndex;
         inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
         inst->SrcReg[0].Negate = NEGATE_NONE;
#endif
#if 0
         inst->TexShadow = 0;
#endif
#if 0
         inst->Opcode = OPCODE_TEX;
         inst->TexShadow = 0;
#endif
      }

   }
}
Пример #3
0
static struct prog_src_register
src_reg_for_vec4(struct gl_program *prog, const float *val)
{
   struct prog_src_register src;
   unsigned swiz;

   memset(&src, 0, sizeof(src));

   src.File = PROGRAM_CONSTANT;
   src.Index = _mesa_add_unnamed_constant(prog->Parameters,
					  (gl_constant_value *) val, 4, &swiz);
   src.Swizzle = swiz;
   return src;
}
Пример #4
0
static struct ureg register_const4f( struct tnl_program *p,
			      GLfloat s0,
			      GLfloat s1,
			      GLfloat s2,
			      GLfloat s3)
{
   GLfloat values[4];
   GLint idx;
   GLuint swizzle;
   values[0] = s0;
   values[1] = s1;
   values[2] = s2;
   values[3] = s3;
   idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4,
                                     &swizzle );
   ASSERT(swizzle == SWIZZLE_NOOP);
   return make_ureg(PROGRAM_CONSTANT, idx);
}
Пример #5
0
static struct ureg register_const4f( struct tnl_program *p, 
			      GLfloat s0,
			      GLfloat s1,
			      GLfloat s2,
			      GLfloat s3)
{
   GLfloat values[4];
   GLint idx;
   GLuint swizzle;
   values[0] = s0;
   values[1] = s1;
   values[2] = s2;
   values[3] = s3;
   idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4,
                                     &swizzle);
   /* XXX what about swizzle? */
   return make_ureg(PROGRAM_STATE_VAR, idx);
}
Пример #6
0
/**
 * Parse a vector source (register, constant, etc):
 *   <vectorSrc>    ::= <absVectorSrc>
 *                    | <baseVectorSrc>
 *   <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|"
 */
static GLboolean
Parse_VectorSrc(struct parse_state *parseState,
                struct prog_src_register *srcReg)
{
   GLfloat sign = 1.0F;
   GLubyte token[100];
   GLint idx;
   GLuint negateBase, negateAbs;

   /*
    * First, take care of +/- and absolute value stuff.
    */
   if (Parse_String(parseState, "-"))
      sign = -1.0F;
   else if (Parse_String(parseState, "+"))
      sign = +1.0F;

   if (Parse_String(parseState, "|")) {
      srcReg->Abs = GL_TRUE;
      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;

      if (Parse_String(parseState, "-"))
         negateBase = NEGATE_XYZW;
      else if (Parse_String(parseState, "+"))
         negateBase = NEGATE_NONE;
      else
         negateBase = NEGATE_NONE;
   }
   else {
      srcReg->Abs = GL_FALSE;
      negateAbs = NEGATE_NONE;
      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
   }

   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;

   /* This should be the real src vector/register name */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;

   /* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar
    * literal or vector literal.
    */
   if (token[0] == 'R' || token[0] == 'H') {
      srcReg->File = PROGRAM_TEMPORARY;
      if (!Parse_TempReg(parseState, &idx))
         RETURN_ERROR;
      srcReg->Index = idx;
   }
   else if (token[0] == 'f') {
      /* XXX this might be an identifier! */
      srcReg->File = PROGRAM_INPUT;
      if (!Parse_FragReg(parseState, &idx))
         RETURN_ERROR;
      srcReg->Index = idx;
   }
   else if (token[0] == 'p') {
      /* XXX this might be an identifier! */
      srcReg->File = PROGRAM_LOCAL_PARAM;
      if (!Parse_ProgramParamReg(parseState, &idx))
         RETURN_ERROR;
      srcReg->Index = idx;
   }
   else if (IsLetter(token[0])){
      GLubyte ident[100];
      GLint paramIndex;
      if (!Parse_Identifier(parseState, ident))
         RETURN_ERROR;
      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
                                                -1, (const char *) ident);
      if (paramIndex < 0) {
         RETURN_ERROR2("Undefined constant or parameter: ", ident);
      }
      srcReg->File = PROGRAM_NAMED_PARAM;
      srcReg->Index = paramIndex;      
   }
   else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){
      /* literal scalar constant */
      GLfloat values[4];
      GLuint paramIndex;
      if (!Parse_ScalarConstant(parseState, values))
         RETURN_ERROR;
      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
                                              values, 4, NULL);
      srcReg->File = PROGRAM_NAMED_PARAM;
      srcReg->Index = paramIndex;
   }
   else if (token[0] == '{'){
      /* literal vector constant */
      GLfloat values[4];
      GLuint paramIndex;
      (void) Parse_String(parseState, "{");
      if (!Parse_VectorConstant(parseState, values))
         RETURN_ERROR;
      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
                                              values, 4, NULL);
      srcReg->File = PROGRAM_NAMED_PARAM;
      srcReg->Index = paramIndex;      
   }
   else {
      RETURN_ERROR2("Invalid source register name", token);
   }

   /* init swizzle fields */
   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, swz))
         RETURN_ERROR1("Invalid swizzle suffix");

      srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
   }

   /* Finish absolute value */
   if (srcReg->Abs && !Parse_String(parseState, "|")) {
      RETURN_ERROR1("Expected |");
   }

   return GL_TRUE;
}
Пример #7
0
static GLboolean
Parse_ScalarSrcReg(struct parse_state *parseState,
                   struct prog_src_register *srcReg)
{
   GLubyte token[100];
   GLfloat sign = 1.0F;
   GLboolean needSuffix = GL_TRUE;
   GLint idx;
   GLuint negateBase, negateAbs;

   /*
    * First, take care of +/- and absolute value stuff.
    */
   if (Parse_String(parseState, "-"))
      sign = -1.0F;
   else if (Parse_String(parseState, "+"))
      sign = +1.0F;

   if (Parse_String(parseState, "|")) {
      srcReg->Abs = GL_TRUE;
      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;

      if (Parse_String(parseState, "-"))
         negateBase = NEGATE_XYZW;
      else if (Parse_String(parseState, "+"))
         negateBase = NEGATE_NONE;
      else
         negateBase = NEGATE_NONE;
   }
   else {
      srcReg->Abs = GL_FALSE;
      negateAbs = NEGATE_NONE;
      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
   }

   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;

   if (!Peek_Token(parseState, token))
      RETURN_ERROR;

   /* Src reg can be R<n>, H<n> or a named fragment attrib */
   if (token[0] == 'R' || token[0] == 'H') {
      srcReg->File = PROGRAM_TEMPORARY;
      if (!Parse_TempReg(parseState, &idx))
         RETURN_ERROR;
      srcReg->Index = idx;
   }
   else if (token[0] == 'f') {
      srcReg->File = PROGRAM_INPUT;
      if (!Parse_FragReg(parseState, &idx))
         RETURN_ERROR;
      srcReg->Index = idx;
   }
   else if (token[0] == '{') {
      /* vector literal */
      GLfloat values[4];
      GLuint paramIndex;
      (void) Parse_String(parseState, "{");
      if (!Parse_VectorConstant(parseState, values))
         RETURN_ERROR;
      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
                                              values, 4, NULL);
      srcReg->File = PROGRAM_NAMED_PARAM;
      srcReg->Index = paramIndex;      
   }
   else if (IsLetter(token[0])){
      /* named param/constant */
      GLubyte ident[100];
      GLint paramIndex;
      if (!Parse_Identifier(parseState, ident))
         RETURN_ERROR;
      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
                                                -1, (const char *) ident);
      if (paramIndex < 0) {
         RETURN_ERROR2("Undefined constant or parameter: ", ident);
      }
      srcReg->File = PROGRAM_NAMED_PARAM;
      srcReg->Index = paramIndex;      
   }
   else if (IsDigit(token[0])) {
      /* scalar literal */
      GLfloat values[4];
      GLuint paramIndex;
      if (!Parse_ScalarConstant(parseState, values))
         RETURN_ERROR;
      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
                                              values, 4, NULL);
      srcReg->Index = paramIndex;      
      srcReg->File = PROGRAM_NAMED_PARAM;
      needSuffix = GL_FALSE;
   }
   else {
      RETURN_ERROR2("Invalid scalar source argument", token);
   }

   srcReg->Swizzle = 0;
   if (needSuffix) {
      /* parse .[xyzw] suffix */
      if (!Parse_String(parseState, "."))
         RETURN_ERROR1("Expected .");

      if (!Parse_Token(parseState, token))
         RETURN_ERROR;

      if (token[0] == 'x' && token[1] == 0) {
         srcReg->Swizzle = 0;
      }
      else if (token[0] == 'y' && token[1] == 0) {
         srcReg->Swizzle = 1;
      }
      else if (token[0] == 'z' && token[1] == 0) {
         srcReg->Swizzle = 2;
      }
      else if (token[0] == 'w' && token[1] == 0) {
         srcReg->Swizzle = 3;
      }
      else {
         RETURN_ERROR1("Invalid scalar source suffix");
      }
   }

   /* Finish absolute value */
   if (srcReg->Abs && !Parse_String(parseState, "|")) {
      RETURN_ERROR1("Expected |");
   }

   return GL_TRUE;
}
Пример #8
0
/**
 * XXX description???
 * \return GL_TRUE for success, GL_FALSE for failure
 */
GLboolean
_mesa_layout_parameters(struct asm_parser_state *state)
{
   struct gl_program_parameter_list *layout;
   struct asm_instruction *inst;
   unsigned i;

   layout =
      _mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters);

   /* PASS 1:  Move any parameters that are accessed indirectly from the
    * original parameter list to the new parameter list.
    */
   for (inst = state->inst_head; inst != NULL; inst = inst->next) {
      for (i = 0; i < 3; i++) {
	 if (inst->SrcReg[i].Base.RelAddr) {
	    /* Only attempt to add the to the new parameter list once.
	     */
	    if (!inst->SrcReg[i].Symbol->pass1_done) {
	       const int new_begin =
		  copy_indirect_accessed_array(state->prog->Parameters, layout,
		      inst->SrcReg[i].Symbol->param_binding_begin,
		      inst->SrcReg[i].Symbol->param_binding_length);

	       if (new_begin < 0) {
		  return GL_FALSE;
	       }

	       inst->SrcReg[i].Symbol->param_binding_begin = new_begin;
	       inst->SrcReg[i].Symbol->pass1_done = 1;
	    }

	    /* Previously the Index was just the offset from the parameter
	     * array.  Now that the base of the parameter array is known, the
	     * index can be updated to its actual value.
	     */
	    inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
	    inst->Base.SrcReg[i].Index +=
	       inst->SrcReg[i].Symbol->param_binding_begin;
	 }
      }
   }

   /* PASS 2:  Move any parameters that are not accessed indirectly from the
    * original parameter list to the new parameter list.
    */
   for (inst = state->inst_head; inst != NULL; inst = inst->next) {
      for (i = 0; i < 3; i++) {
	 const struct gl_program_parameter *p;
	 const int idx = inst->SrcReg[i].Base.Index;
	 unsigned swizzle = SWIZZLE_NOOP;

	 /* All relative addressed operands were processed on the first
	  * pass.  Just skip them here.
	  */
	 if (inst->SrcReg[i].Base.RelAddr) {
	    continue;
	 }

	 if ((inst->SrcReg[i].Base.File <= PROGRAM_VARYING )
	     || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) {
	    continue;
	 }

	 inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
	 p = & state->prog->Parameters->Parameters[idx];

	 switch (p->Type) {
	 case PROGRAM_CONSTANT: {
	    const float *const v =
	       state->prog->Parameters->ParameterValues[idx];

	    inst->Base.SrcReg[i].Index =
	       _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle);

	    inst->Base.SrcReg[i].Swizzle = 
	       _mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle);
	    break;
	 }

	 case PROGRAM_STATE_VAR:
	    inst->Base.SrcReg[i].Index =
	       _mesa_add_state_reference(layout, p->StateIndexes);
	    break;

	 default:
	    break;
	 }

	 inst->SrcReg[i].Base.File = p->Type;
	 inst->Base.SrcReg[i].File = p->Type;
      }
   }

   layout->StateFlags = state->prog->Parameters->StateFlags;
   _mesa_free_parameter_list(state->prog->Parameters);
   state->prog->Parameters = layout;

   return GL_TRUE;
}