Beispiel #1
0
/* This one is simple - just take the interpolated fog coordinate and
 * use it as the fog blend factor.
 */
static void fog_interpolated( struct brw_wm_compile *c )
{
   struct prog_src_register fogc = src_reg(PROGRAM_INPUT, FRAG_ATTRIB_FOGC);
   
   if (!(c->fp_interp_emitted & (1<<FRAG_ATTRIB_FOGC))) 
      emit_interp(c, FRAG_ATTRIB_FOGC);

   fog_blend( c, src_swizzle1(fogc, GET_SWZ(fogc.Swizzle,X)));
}
Beispiel #2
0
static void validate_src_regs( struct brw_wm_compile *c,
			       const struct prog_instruction *inst )
{
   GLuint nr_args = brw_wm_nr_args( inst->Opcode );
   GLuint i;

   for (i = 0; i < nr_args; i++) {
      if (inst->SrcReg[i].File == PROGRAM_INPUT) {
	 GLuint idx = inst->SrcReg[i].Index;
	 if (!(c->fp_interp_emitted & (1<<idx))) {
	    emit_interp(c, idx);
	 }
      }
   }
}
Beispiel #3
0
/**
 * Initial pass for fragment program code generation.
 * This function is used by both the GLSL and non-GLSL paths.
 */
int brw_wm_pass_fp( struct brw_wm_compile *c )
{
   struct brw_fragment_shader *fs = c->fp;
   struct tgsi_parse_context parse;
   struct tgsi_full_instruction *inst;
   struct tgsi_full_declaration *decl;
   const float *imm;
   GLuint size;
   GLuint i;

   if (BRW_DEBUG & DEBUG_WM) {
      debug_printf("pre-fp:\n");
      tgsi_dump(fs->tokens, 0); 
   }

   c->fp_pixel_xy = src_undef();
   c->fp_delta_xy = src_undef();
   c->fp_pixel_w = src_undef();
   c->nr_fp_insns = 0;
   c->nr_immediates = 0;


   /* Loop over all instructions doing assorted simplifications and
    * transformations.
    */
   tgsi_parse_init( &parse, fs->tokens );
   while( !tgsi_parse_end_of_tokens( &parse ) ) {
      tgsi_parse_token( &parse );

      switch( parse.FullToken.Token.Type ) {
      case TGSI_TOKEN_TYPE_DECLARATION:
	 /* Turn intput declarations into special WM_* instructions.
	  *
	  * XXX: For non-branching shaders, consider deferring variable
	  * initialization as late as possible to minimize register
	  * usage.  This is how the original BRW driver worked.
	  *
	  * In a branching shader, must preamble instructions at decl
	  * time, as instruction order in the shader does not
	  * correspond to the order instructions are executed in the
	  * wild.
	  *
	  * This is where special instructions such as WM_CINTERP,
	  * WM_LINTERP, WM_PINTERP and WM_WPOSXY are emitted to
	  * compute shader inputs from the payload registers and pixel
	  * position.
	  */
         decl = &parse.FullToken.FullDeclaration;
         if( decl->Declaration.File == TGSI_FILE_INPUT ) {
            unsigned first, last, mask;
            unsigned attrib;

            first = decl->Range.First;
            last = decl->Range.Last;
            mask = decl->Declaration.UsageMask;

            for (attrib = first; attrib <= last; attrib++) {
	       emit_interp(c, 
			   attrib, 
			   decl->Semantic.Name,
			   decl->Declaration.Interpolate );
            }
         }
	 
         break;

      case TGSI_TOKEN_TYPE_IMMEDIATE:
	 /* Unlike VS programs we can probably manage fine encoding
	  * immediate values directly into the emitted EU
	  * instructions, as we probably only need to reference one
	  * float value per instruction.  Just save the data for now
	  * and use directly later.
	  */
	 i = c->nr_immediates++;
	 imm = &parse.FullToken.FullImmediate.u[i].Float;
	 size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;

	 if (c->nr_immediates >= BRW_WM_MAX_CONST)
	    return PIPE_ERROR_OUT_OF_MEMORY;

	 for (i = 0; i < size; i++)
	    c->immediate[c->nr_immediates].v[i] = imm[i];

	 for (; i < 4; i++)
	    c->immediate[c->nr_immediates].v[i] = 0.0;

	 c->immediate[c->nr_immediates].nr = size;
	 c->nr_immediates++;
	 break;

      case TGSI_TOKEN_TYPE_INSTRUCTION:
         inst = &parse.FullToken.FullInstruction;
	 emit_insn(c, inst);
	 break;
      }
   }

   if (BRW_DEBUG & DEBUG_WM) {
      brw_wm_print_fp_program( c, "pass_fp" );
      debug_printf("\n");
   }

   return c->error;
}