Esempio n. 1
0
struct gl_program_parameter_list *
_mesa_clone_parameter_list(const struct gl_program_parameter_list *list)
{
   struct gl_program_parameter_list *clone;
   GLuint i;

   clone = _mesa_new_parameter_list();
   if (!clone)
      return NULL;

   /** Not too efficient, but correct */
   for (i = 0; i < list->NumParameters; i++) {
      struct gl_program_parameter *p = list->Parameters + i;
      GLuint size = MIN2(p->Size, 4);
      GLint j = _mesa_add_parameter(clone, p->Type, p->Name, size, p->DataType,
                                    list->ParameterValues[i], NULL);
      ASSERT(j >= 0);
      /* copy state indexes */
      if (p->Type == PROGRAM_STATE_VAR) {
         GLint k;
         struct gl_program_parameter *q = clone->Parameters + j;
         for (k = 0; k < STATE_LENGTH; k++) {
            q->StateIndexes[k] = p->StateIndexes[k];
         }
      }
      else {
         clone->Parameters[j].Size = p->Size;
      }
   }

   return clone;
}
Esempio n. 2
0
/**
 * Return a new parameter list which is listA + listB.
 */
struct gl_program_parameter_list *
_mesa_combine_parameter_lists(const struct gl_program_parameter_list *listA,
                              const struct gl_program_parameter_list *listB)
{
   struct gl_program_parameter_list *list;

   if (listA) {
      list = _mesa_clone_parameter_list(listA);
      if (list && listB) {
         GLuint i;
         for (i = 0; i < listB->NumParameters; i++) {
            struct gl_program_parameter *param = listB->Parameters + i;
            _mesa_add_parameter(list, param->Type, param->Name, param->Size,
                                param->DataType,
                                listB->ParameterValues[i],
                                param->StateIndexes);
         }
      }
   }
   else if (listB) {
      list = _mesa_clone_parameter_list(listB);
   }
   else {
      list = NULL;
   }
   return list;
}
Esempio n. 3
0
/**
 * Add a new state reference to the parameter list.
 * This will be used when the program contains something like this:
 *    PARAM ambient = state.material.front.ambient;
 *
 * \param paramList  the parameter list
 * \param stateTokens  an array of 5 (STATE_LENGTH) state tokens
 * \return index of the new parameter.
 */
GLint
_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
                          const gl_state_index stateTokens[STATE_LENGTH])
{
   const GLuint size = 4; /* XXX fix */
   char *name;
   GLint index;

   /* Check if the state reference is already in the list */
   for (index = 0; index < (GLint) paramList->NumParameters; index++) {
      if (!memcmp(paramList->Parameters[index].StateIndexes,
		  stateTokens, STATE_LENGTH * sizeof(gl_state_index))) {
	 return index;
      }
   }

   name = _mesa_program_state_string(stateTokens);
   index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name,
                               size, GL_NONE,
                               NULL, (gl_state_index *) stateTokens);
   paramList->StateFlags |= _mesa_program_state_flags(stateTokens);

   /* free name string here since we duplicated it in add_parameter() */
   free(name);

   return index;
}
Esempio n. 4
0
/**
 * Add a sampler to the parameter list.
 * \param name  uniform's name
 * \param datatype  GL_SAMPLER_2D, GL_SAMPLER_2D_RECT_ARB, etc.
 * \param index  the sampler number (as seen in TEX instructions)
 * \return  sampler index (starting at zero) or -1 if error
 */
GLint
_mesa_add_sampler(struct gl_program_parameter_list *paramList,
                  const char *name, GLenum datatype)
{
   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) {
      ASSERT(paramList->Parameters[i].Size == 1);
      ASSERT(paramList->Parameters[i].DataType == datatype);
      /* already in list */
      return (GLint) paramList->ParameterValues[i][0];
   }
   else {
      GLuint i;
      const GLint size = 1; /* a sampler is basically a texture unit number */
      GLfloat value[4];
      GLint numSamplers = 0;
      for (i = 0; i < paramList->NumParameters; i++) {
         if (paramList->Parameters[i].Type == PROGRAM_SAMPLER)
            numSamplers++;
      }
      value[0] = (GLfloat) numSamplers;
      value[1] = value[2] = value[3] = 0.0F;
      (void) _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
                                 size, datatype, value, NULL, 0x0);
      return numSamplers;
   }
}
Esempio n. 5
0
GLint
_mesa_add_sized_state_reference(struct gl_program_parameter_list *paramList,
                                const gl_state_index16 stateTokens[STATE_LENGTH],
                                const unsigned size, bool pad_and_align)
{
   char *name;
   GLint index;

   /* Check if the state reference is already in the list */
   for (index = 0; index < (GLint) paramList->NumParameters; index++) {
      if (!memcmp(paramList->Parameters[index].StateIndexes,
                  stateTokens,
                  sizeof(paramList->Parameters[index].StateIndexes))) {
         return index;
      }
   }

   name = _mesa_program_state_string(stateTokens);
   index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name,
                               size, GL_NONE, NULL, stateTokens,
                               pad_and_align);
   paramList->StateFlags |= _mesa_program_state_flags(stateTokens);

   /* free name string here since we duplicated it in add_parameter() */
   free(name);

   return index;
}
Esempio n. 6
0
/**
 * Add a new named program parameter (Ex: NV_fragment_program DEFINE statement)
 * \return index of the new entry in the parameter list
 */
GLint
_mesa_add_named_parameter(struct gl_program_parameter_list *paramList,
                          const char *name, const GLfloat values[4])
{
   return _mesa_add_parameter(paramList, PROGRAM_NAMED_PARAM, name,
                              4, GL_NONE, values, NULL);
                              
}
Esempio n. 7
0
/**
 * Add parameter representing a varying variable.
 */
GLint
_mesa_add_varying(struct gl_program_parameter_list *paramList,
                  const char *name, GLuint size)
{
   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_VARYING) {
      /* already in list */
      return i;
   }
   else {
      assert(size == 4);
      i = _mesa_add_parameter(paramList, PROGRAM_VARYING, name,
                              size, GL_NONE, NULL, NULL);
      return i;
   }
}
Esempio n. 8
0
/**
 * Add a new unnamed constant to the parameter list.  This will be used
 * when a fragment/vertex program contains something like this:
 *    MOV r, { 0, 1, 2, 3 };
 * If swizzleOut is non-null we'll search the parameter list for an
 * existing instance of the constant which matches with a swizzle.
 *
 * \param paramList  the parameter list
 * \param values  four float values
 * \param swizzleOut  returns swizzle mask for accessing the constant
 * \return index/position of the new parameter in the parameter list.
 */
GLint
_mesa_add_typed_unnamed_constant(struct gl_program_parameter_list *paramList,
                           const gl_constant_value values[4], GLuint size,
                           GLenum datatype, GLuint *swizzleOut)
{
   GLint pos;
   ASSERT(size >= 1);
   ASSERT(size <= 4);

   if (swizzleOut &&
       _mesa_lookup_parameter_constant(paramList, values,
                                       size, &pos, swizzleOut)) {
      return pos;
   }

   /* Look for empty space in an already unnamed constant parameter
    * to add this constant.  This will only work for single-element
    * constants because we rely on smearing (i.e. .yyyy or .zzzz).
    */
   if (size == 1 && swizzleOut) {
      for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) {
         struct gl_program_parameter *p = paramList->Parameters + pos;
         if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) {
            /* ok, found room */
            gl_constant_value *pVal = paramList->ParameterValues[pos];
            GLuint swz = p->Size; /* 1, 2 or 3 for Y, Z, W */
            pVal[p->Size] = values[0];
            p->Size++;
            *swizzleOut = MAKE_SWIZZLE4(swz, swz, swz, swz);
            return pos;
         }
      }
   }

   /* add a new parameter to store this constant */
   pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL,
                             size, datatype, values, NULL);
   if (pos >= 0 && swizzleOut) {
      if (size == 1)
         *swizzleOut = SWIZZLE_XXXX;
      else
         *swizzleOut = SWIZZLE_NOOP;
   }
   return pos;
}
Esempio n. 9
0
/**
 * Add a sampler to the parameter list.
 * \param name  uniform's name
 * \param datatype  GL_SAMPLER_2D, GL_SAMPLER_2D_RECT_ARB, etc.
 */
GLint
_mesa_add_sampler(struct gl_program_parameter_list *paramList,
                  const char *name, GLenum datatype)
{
   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) {
      ASSERT(paramList->Parameters[i].Size == 1);
      ASSERT(paramList->Parameters[i].DataType == datatype);
      /* already in list */
      return i;
   }
   else {
      const GLint size = 1; /* a sampler is basically a texture unit number */
      i = _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
                              size, datatype, NULL, NULL);
      return i;
   }
}
Esempio n. 10
0
/**
 * Add a uniform to the parameter list.
 * Note that if the uniform is an array, size may be greater than
 * what's implied by the datatype.
 * \param name  uniform's name
 * \param size  number of floats to allocate
 * \param datatype  GL_FLOAT_VEC3, GL_FLOAT_MAT4, etc.
 */
GLint
_mesa_add_uniform(struct gl_program_parameter_list *paramList,
                  const char *name, GLuint size, GLenum datatype)
{
   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
   ASSERT(datatype != GL_NONE);
   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_UNIFORM) {
      ASSERT(paramList->Parameters[i].Size == size);
      ASSERT(paramList->Parameters[i].DataType == datatype);
      /* already in list */
      return i;
   }
   else {
      i = _mesa_add_parameter(paramList, PROGRAM_UNIFORM, name,
                              size, datatype, NULL, NULL);
      return i;
   }
}
Esempio n. 11
0
/**
 * Add a new named constant to the parameter list.
 * This will be used when the program contains something like this:
 *    PARAM myVals = { 0, 1, 2, 3 };
 *
 * \param paramList  the parameter list
 * \param name  the name for the constant
 * \param values  four float values
 * \return index/position of the new parameter in the parameter list
 */
GLint
_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
                         const char *name, const GLfloat values[4],
                         GLuint size)
{
#if 0 /* disable this for now -- we need to save the name! */
   GLint pos;
   GLuint swizzle;
   ASSERT(size == 4); /* XXX future feature */
   /* check if we already have this constant */
   if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) {
      return pos;
   }
#endif
   size = 4; /** XXX fix */
   return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name,
                              size, GL_NONE, values, NULL);
}
Esempio n. 12
0
/**
 * Add parameter representing a vertex program attribute.
 * \param size  size of attribute (in floats), may be -1 if unknown
 * \param attrib  the attribute index, or -1 if unknown
 */
GLint
_mesa_add_attribute(struct gl_program_parameter_list *paramList,
                    const char *name, GLint size, GLint attrib)
{
   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
   if (i >= 0) {
      /* replace */
      if (attrib < 0)
         attrib = i;
      paramList->Parameters[i].StateIndexes[0] = attrib;
   }
   else {
      /* add */
      gl_state_index state[STATE_LENGTH];
      state[0] = (gl_state_index) attrib;
      if (size < 0)
         size = 4;
      i = _mesa_add_parameter(paramList, PROGRAM_INPUT, name,
                              size, GL_NONE, NULL, state);
   }
   return i;
}
Esempio n. 13
0
/**
 * Add a new named constant to the parameter list.
 * This will be used when the program contains something like this:
 *    PARAM myVals = { 0, 1, 2, 3 };
 *
 * \param paramList  the parameter list
 * \param name  the name for the constant
 * \param values  four float values
 * \return index/position of the new parameter in the parameter list
 */
GLint
_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
                         const char *name, const gl_constant_value values[4],
                         GLuint size)
{
   /* first check if this is a duplicate constant */
   GLint pos;
   for (pos = 0; pos < (GLint)paramList->NumParameters; pos++) {
      const gl_constant_value *pvals = paramList->ParameterValues[pos];
      if (pvals[0].u == values[0].u &&
          pvals[1].u == values[1].u &&
          pvals[2].u == values[2].u &&
          pvals[3].u == values[3].u &&
          strcmp(paramList->Parameters[pos].Name, name) == 0) {
         /* Same name and value is already in the param list - reuse it */
         return pos;
      }
   }
   /* not found, add new parameter */
   return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name,
                              size, GL_NONE, values, NULL);
}
Esempio n. 14
0
/**
 * Add a new state reference to the parameter list.
 * This will be used when the program contains something like this:
 *    PARAM ambient = state.material.front.ambient;
 *
 * \param paramList  the parameter list
 * \param stateTokens  an array of 5 (STATE_LENGTH) state tokens
 * \return index of the new parameter.
 */
GLint
_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
                          const gl_state_index stateTokens[STATE_LENGTH])
{
   const GLuint size = 4; /* XXX fix */
   const char *name;
   GLint index;

   /* Check if the state reference is already in the list */
   for (index = 0; index < (GLint) paramList->NumParameters; index++) {
      GLuint i, match = 0;
      for (i = 0; i < STATE_LENGTH; i++) {
         if (paramList->Parameters[index].StateIndexes[i] == stateTokens[i]) {
            match++;
         }
         else {
            break;
         }
      }
      if (match == STATE_LENGTH) {
         /* this state reference is already in the parameter list */
         return index;
      }
   }

   name = _mesa_program_state_string(stateTokens);
   index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name,
                               size, GL_NONE,
                               NULL, (gl_state_index *) stateTokens);
   paramList->StateFlags |= _mesa_program_state_flags(stateTokens);

   /* free name string here since we duplicated it in add_parameter() */
   _mesa_free((void *) name);

   return index;
}
Esempio n. 15
0
/**
 * Called in ProgramStringNotify, we need to fill the metadata of the
 * gl_program attached to the ati_fragment_shader
 */
void
st_init_atifs_prog(struct gl_context *ctx, struct gl_program *prog)
{
   /* we know this is st_fragment_program, because of st_new_ati_fs() */
   struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
   struct ati_fragment_shader *atifs = stfp->ati_fs;

   unsigned pass, i, r, optype, arg;

   static const gl_state_index fog_params_state[STATE_LENGTH] =
      {STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0};
   static const gl_state_index fog_color[STATE_LENGTH] =
      {STATE_FOG_COLOR, 0, 0, 0, 0};

   prog->InputsRead = 0;
   prog->OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR);
   prog->SamplersUsed = 0;
   prog->Parameters = _mesa_new_parameter_list();

   /* fill in InputsRead, SamplersUsed, TexturesUsed */
   for (pass = 0; pass < atifs->NumPasses; pass++) {
      for (r = 0; r < MAX_NUM_FRAGMENT_REGISTERS_ATI; r++) {
         struct atifs_setupinst *texinst = &atifs->SetupInst[pass][r];
         GLuint pass_tex = texinst->src;

         if (texinst->Opcode == ATI_FRAGMENT_SHADER_SAMPLE_OP) {
            /* mark which texcoords are used */
            prog->InputsRead |= BITFIELD64_BIT(VARYING_SLOT_TEX0 + pass_tex - GL_TEXTURE0_ARB);
            /* by default there is 1:1 mapping between samplers and textures */
            prog->SamplersUsed |= (1 << r);
            /* the target is unknown here, it will be fixed in the draw call */
            prog->TexturesUsed[r] = TEXTURE_2D_BIT;
         } else if (texinst->Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
            if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) {
               prog->InputsRead |= BITFIELD64_BIT(VARYING_SLOT_TEX0 + pass_tex - GL_TEXTURE0_ARB);
            }
         }
      }
   }
   for (pass = 0; pass < atifs->NumPasses; pass++) {
      for (i = 0; i < atifs->numArithInstr[pass]; i++) {
         struct atifs_instruction *inst = &atifs->Instructions[pass][i];

         for (optype = 0; optype < 2; optype++) { /* color, alpha */
            if (inst->Opcode[optype]) {
               for (arg = 0; arg < inst->ArgCount[optype]; arg++) {
                  GLint index = inst->SrcReg[optype][arg].Index;
                  if (index == GL_PRIMARY_COLOR_EXT) {
                     prog->InputsRead |= BITFIELD64_BIT(VARYING_SLOT_COL0);
                  } else if (index == GL_SECONDARY_INTERPOLATOR_ATI) {
                     /* note: ATI_fragment_shader.txt never specifies what
                      * GL_SECONDARY_INTERPOLATOR_ATI is, swrast uses
                      * VARYING_SLOT_COL1 for this input */
                     prog->InputsRead |= BITFIELD64_BIT(VARYING_SLOT_COL1);
                  }
               }
            }
         }
      }
   }
   /* we may need fog */
   prog->InputsRead |= BITFIELD64_BIT(VARYING_SLOT_FOGC);

   /* we always have the ATI_fs constants, and the fog params */
   for (i = 0; i < MAX_NUM_FRAGMENT_CONSTANTS_ATI; i++) {
      _mesa_add_parameter(prog->Parameters, PROGRAM_UNIFORM,
                          NULL, 4, GL_FLOAT, NULL, NULL);
   }
   _mesa_add_state_reference(prog->Parameters, fog_params_state);
   _mesa_add_state_reference(prog->Parameters, fog_color);

   prog->NumInstructions = 0;
   prog->NumTemporaries = MAX_NUM_FRAGMENT_REGISTERS_ATI + 3; /* 3 input temps for arith ops */
   prog->NumParameters = MAX_NUM_FRAGMENT_CONSTANTS_ATI + 2; /* 2 state variables for fog */
}