示例#1
0
static GLuint get_source( struct i915_fragment_program *p, 
			  GLenum src, GLuint unit )
{
   switch (src) {
   case GL_TEXTURE: 
      if (p->src_texture == UREG_BAD) {

	 /* TODO: Use D0_CHANNEL_XY where possible.
	  */
	 GLuint dim = translate_tex_src_bit( p, p->ctx->Texture.Unit[unit]._ReallyEnabled);
	 GLuint sampler = i915_emit_decl(p, REG_TYPE_S, unit, dim);
	 GLuint texcoord = i915_emit_decl(p, REG_TYPE_T, unit, D0_CHANNEL_ALL);
	 GLuint tmp = i915_get_temp( p );
	 GLuint op = T0_TEXLD;

	 if (p->VB->TexCoordPtr[unit]->size == 4)
	    op = T0_TEXLDP;

	 p->src_texture = i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, 
					  sampler, texcoord, op );
      }

      return p->src_texture;

      /* Crossbar: */
   case GL_TEXTURE0:
   case GL_TEXTURE1:
   case GL_TEXTURE2:
   case GL_TEXTURE3:
   case GL_TEXTURE4:
   case GL_TEXTURE5:
   case GL_TEXTURE6:
   case GL_TEXTURE7: {
      return UREG_BAD;
   }

   case GL_CONSTANT:
      return i915_emit_const4fv( p, p->ctx->Texture.Unit[unit].EnvColor );
   case GL_PRIMARY_COLOR:
      return i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL);
   case GL_PREVIOUS:
   default: 
      i915_emit_decl(p, 
		GET_UREG_TYPE(p->src_previous),
		GET_UREG_NR(p->src_previous), D0_CHANNEL_ALL); 
      return p->src_previous;
   }
}
示例#2
0
static void emit_program_fini( struct i915_fragment_program *p )
{
   int cf = get_source( p, GL_PREVIOUS, 0 );
   int out = UREG( REG_TYPE_OC, 0 );

   if (p->ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
      /* Emit specular add.
       */
      GLuint s = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_ALL);
      i915_emit_arith( p, A0_ADD, out, A0_DEST_CHANNEL_ALL, 0, cf, 
		  swizzle(s, X,Y,Z,ZERO), 0 );
   }
   else if (cf != out) {
      /* Will wind up in here if no texture enabled or a couple of
       * other scenarios (GL_REPLACE for instance).
       */
      i915_emit_arith( p, A0_MOV, out, A0_DEST_CHANNEL_ALL, 0, cf, 0, 0 );
   }
}
/**
 * Generate texel lookup instruction.
 */
static void
emit_tex(struct i915_fp_compile *p,
         const struct i915_full_instruction *inst,
         uint opcode,
         struct i915_fragment_shader* fs)
{
   uint texture = inst->Texture.Texture;
   uint unit = inst->Src[1].Register.Index;
   uint tex = translate_tex_src_target( p, texture );
   uint sampler = i915_emit_decl(p, REG_TYPE_S, unit, tex);
   uint coord = src_vector( p, &inst->Src[0], fs);

   i915_emit_texld( p,
                    get_result_vector( p, &inst->Dst[0] ),
                    get_result_flags( inst ),
                    sampler,
                    coord,
                    opcode,
                    i915_num_coords(texture) );
}
/**
 * Retrieve a ureg for the given source register.  Will emit
 * constants, apply swizzling and negation as needed.
 */
static GLuint
src_vector(struct i915_fragment_program *p,
           const struct prog_src_register *source,
           const struct gl_fragment_program *program)
{
   GLuint src;

   switch (source->File) {

      /* Registers:
       */
   case PROGRAM_TEMPORARY:
      if (source->Index >= I915_MAX_TEMPORARY) {
         i915_program_error(p, "Exceeded max temporary reg");
         return 0;
      }
      src = UREG(REG_TYPE_R, source->Index);
      break;
   case PROGRAM_INPUT:
      switch (source->Index) {
      case FRAG_ATTRIB_WPOS:
         src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL);
         break;
      case FRAG_ATTRIB_COL0:
         src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL);
         break;
      case FRAG_ATTRIB_COL1:
         src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ);
         src = swizzle(src, X, Y, Z, ONE);
         break;
      case FRAG_ATTRIB_FOGC:
         src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W);
         src = swizzle(src, W, ZERO, ZERO, ONE);
         break;
      case FRAG_ATTRIB_TEX0:
      case FRAG_ATTRIB_TEX1:
      case FRAG_ATTRIB_TEX2:
      case FRAG_ATTRIB_TEX3:
      case FRAG_ATTRIB_TEX4:
      case FRAG_ATTRIB_TEX5:
      case FRAG_ATTRIB_TEX6:
      case FRAG_ATTRIB_TEX7:
         src = i915_emit_decl(p, REG_TYPE_T,
                              T_TEX0 + (source->Index - FRAG_ATTRIB_TEX0),
                              D0_CHANNEL_ALL);
         break;

      default:
         i915_program_error(p, "Bad source->Index");
         return 0;
      }
      break;

      /* Various paramters and env values.  All emitted to
       * hardware as program constants.
       */
   case PROGRAM_LOCAL_PARAM:
      src = i915_emit_param4fv(p, program->Base.LocalParams[source->Index]);
      break;

   case PROGRAM_ENV_PARAM:
      src =
         i915_emit_param4fv(p,
                            p->ctx->FragmentProgram.Parameters[source->
                                                               Index]);
      break;

   case PROGRAM_CONSTANT:
   case PROGRAM_STATE_VAR:
   case PROGRAM_NAMED_PARAM:
      src =
         i915_emit_param4fv(p,
                            program->Base.Parameters->ParameterValues[source->
                                                                      Index]);
      break;

   default:
      i915_program_error(p, "Bad source->File");
      return 0;
   }

   src = swizzle(src,
                 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,
                   GET_BIT(source->NegateBase, 0),
                   GET_BIT(source->NegateBase, 1),
                   GET_BIT(source->NegateBase, 2),
                   GET_BIT(source->NegateBase, 3));

   return src;
}
/**
 * Construct a ureg for the given source register.  Will emit
 * constants, apply swizzling and negation as needed.
 */
static uint
src_vector(struct i915_fp_compile *p,
           const struct i915_full_src_register *source,
           struct i915_fragment_shader *fs)
{
   uint index = source->Register.Index;
   uint src = 0, sem_name, sem_ind;

   switch (source->Register.File) {
   case TGSI_FILE_TEMPORARY:
      if (source->Register.Index >= I915_MAX_TEMPORARY) {
         i915_program_error(p, "Exceeded max temporary reg");
         return 0;
      }
      src = UREG(REG_TYPE_R, index);
      break;
   case TGSI_FILE_INPUT:
      /* XXX: Packing COL1, FOGC into a single attribute works for
       * texenv programs, but will fail for real fragment programs
       * that use these attributes and expect them to be a full 4
       * components wide.  Could use a texcoord to pass these
       * attributes if necessary, but that won't work in the general
       * case.
       * 
       * We also use a texture coordinate to pass wpos when possible.
       */

      sem_name = p->shader->info.input_semantic_name[index];
      sem_ind = p->shader->info.input_semantic_index[index];

      switch (sem_name) {
      case TGSI_SEMANTIC_POSITION:
         {
            /* for fragcoord */
            int real_tex_unit = get_mapping(fs, I915_SEMANTIC_POS);
            src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL);
            break;
         }
      case TGSI_SEMANTIC_COLOR:
         if (sem_ind == 0) {
            src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL);
         }
         else {
            /* secondary color */
            assert(sem_ind == 1);
            src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ);
            src = swizzle(src, X, Y, Z, ONE);
         }
         break;
      case TGSI_SEMANTIC_FOG:
         src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W);
         src = swizzle(src, W, W, W, W);
         break;
      case TGSI_SEMANTIC_GENERIC:
         {
            int real_tex_unit = get_mapping(fs, sem_ind);
            src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL);
            break;
         }
      case TGSI_SEMANTIC_FACE:
         {
            /* for back/front faces */
            int real_tex_unit = get_mapping(fs, I915_SEMANTIC_FACE);
            src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_X);
            break;
         }
      default:
         i915_program_error(p, "Bad source->Index");
         return 0;
      }
      break;

   case TGSI_FILE_IMMEDIATE:
      assert(index < p->num_immediates);
      index = p->immediates_map[index];
      /* fall-through */
   case TGSI_FILE_CONSTANT:
      src = UREG(REG_TYPE_CONST, index);
      break;

   default:
      i915_program_error(p, "Bad source->File");
      return 0;
   }

   src = swizzle(src,
		 source->Register.SwizzleX,
		 source->Register.SwizzleY,
		 source->Register.SwizzleZ,
		 source->Register.SwizzleW);

   /* There's both negate-all-components and per-component negation.
    * Try to handle both here.
    */
   {
      int n = source->Register.Negate;
      src = negate(src, n, n, n, n);
   }

   /* no abs() */
#if 0
   /* XXX assertions disabled to allow arbfplight.c to run */
   /* XXX enable these assertions, or fix things */
   assert(!source->Register.Absolute);
#endif
   if (source->Register.Absolute)
      debug_printf("Unhandled absolute value\n");

   return src;
}