Exemplo n.º 1
0
static void
handle_sample_op(GLcontext * ctx, struct atifs_machine *machine,
		 struct atifs_instruction *inst, const struct sw_span *span,
		 GLuint column)
{
   GLuint idx = inst->DstReg[0].Index - GL_REG_0_ATI;
   GLuint swizzle = inst->DstReg[0].Swizzle;
   GLuint sample_tex = inst->SrcReg[0][0].Index;

   /* if we get here after passing pass one then we are starting pass two - backup the registers */
   if (machine->pass == 1) {
      finish_pass(machine);
      machine->pass = 2;
   }

   if (sample_tex >= GL_TEXTURE0_ARB && sample_tex <= GL_TEXTURE7_ARB) {
      sample_tex -= GL_TEXTURE0_ARB;
      fetch_texel(ctx, span->array->texcoords[sample_tex][column], 0.0F,
		  sample_tex, machine->Registers[idx]);
   }
   else if (sample_tex >= GL_REG_0_ATI && sample_tex <= GL_REG_5_ATI) {
      /* this is wrong... */
      sample_tex -= GL_REG_0_ATI;
      fetch_texel(ctx, machine->Registers[sample_tex], 0, sample_tex,
		  machine->Registers[idx]);
   }

   apply_swizzle(machine, idx, swizzle);
}
Exemplo n.º 2
0
static void
handle_pass_op(struct atifs_machine *machine, struct atifs_instruction *inst,
	       const struct sw_span *span, GLuint column)
{
   GLuint idx = inst->DstReg[0].Index - GL_REG_0_ATI;
   GLuint swizzle = inst->DstReg[0].Swizzle;
   GLuint pass_tex = inst->SrcReg[0][0].Index;

   /* if we get here after passing pass one then we are starting pass two - backup the registers */
   if (machine->pass == 1) {
      finish_pass(machine);
      machine->pass = 2;
   }
   if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) {
      pass_tex -= GL_TEXTURE0_ARB;
      COPY_4V(machine->Registers[idx],
	      span->array->texcoords[pass_tex][column]);
   }
   else if (pass_tex >= GL_REG_0_ATI && pass_tex <= GL_REG_5_ATI
	    && machine->pass == 2) {
      pass_tex -= GL_REG_0_ATI;
      COPY_4V(machine->Registers[idx], machine->PrevPassRegisters[pass_tex]);
   }
   apply_swizzle(machine, idx, swizzle);

}
Exemplo n.º 3
0
/**
 * Execute the given fragment shader.
 * NOTE: we do everything in single-precision floating point
 * \param ctx - rendering context
 * \param shader - the shader to execute
 * \param machine - virtual machine state
 * \param span - the SWspan we're operating on
 * \param column - which pixel [i] we're operating on in the span
 */
static void
execute_shader(struct gl_context *ctx, const struct ati_fragment_shader *shader,
	       struct atifs_machine *machine, const SWspan *span,
               GLuint column)
{
   GLuint pc;
   struct atifs_instruction *inst;
   struct atifs_setupinst *texinst;
   GLint optype;
   GLuint i;
   GLint j, pass;
   GLint dstreg;
   GLfloat src[2][3][4];
   GLfloat zeros[4] = { 0.0, 0.0, 0.0, 0.0 };
   GLfloat ones[4] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat dst[2][4], *dstp;

   for (pass = 0; pass < shader->NumPasses; pass++) {
      if (pass > 0)
	 finish_pass(machine);
      for (j = 0; j < MAX_NUM_FRAGMENT_REGISTERS_ATI; j++) {
	 texinst = &shader->SetupInst[pass][j];
	 if (texinst->Opcode == ATI_FRAGMENT_SHADER_PASS_OP)
	    handle_pass_op(machine, texinst, span, column, j);
	 else if (texinst->Opcode == ATI_FRAGMENT_SHADER_SAMPLE_OP)
	    handle_sample_op(ctx, machine, texinst, span, column, j);
      }

      for (pc = 0; pc < shader->numArithInstr[pass]; pc++) {
	 inst = &shader->Instructions[pass][pc];

	 /* setup the source registers for color and alpha ops */
	 for (optype = 0; optype < 2; optype++) {
 	    for (i = 0; i < inst->ArgCount[optype]; i++) {
	       GLint index = inst->SrcReg[optype][i].Index;

	       if (index >= GL_REG_0_ATI && index <= GL_REG_5_ATI)
		  SETUP_SRC_REG(optype, i,
				machine->Registers[index - GL_REG_0_ATI]);
	       else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) {
		  if (shader->LocalConstDef & (1 << (index - GL_CON_0_ATI))) {
		     SETUP_SRC_REG(optype, i,
				shader->Constants[index - GL_CON_0_ATI]);
		  } else {
		     SETUP_SRC_REG(optype, i,
				ctx->ATIFragmentShader.GlobalConstants[index - GL_CON_0_ATI]);
		  }
	       }
	       else if (index == GL_ONE)
		  SETUP_SRC_REG(optype, i, ones);
	       else if (index == GL_ZERO)
		  SETUP_SRC_REG(optype, i, zeros);
	       else if (index == GL_PRIMARY_COLOR_EXT)
		  SETUP_SRC_REG(optype, i,
				machine->Inputs[ATI_FS_INPUT_PRIMARY]);
	       else if (index == GL_SECONDARY_INTERPOLATOR_ATI)
		  SETUP_SRC_REG(optype, i,
				machine->Inputs[ATI_FS_INPUT_SECONDARY]);

	       apply_src_rep(optype, inst->SrcReg[optype][i].argRep,
			     src[optype][i]);
	       apply_src_mod(optype, inst->SrcReg[optype][i].argMod,
			     src[optype][i]);
	    }
	 }

	 /* Execute the operations - color then alpha */
	 for (optype = 0; optype < 2; optype++) {
	    if (inst->Opcode[optype]) {
	       switch (inst->Opcode[optype]) {
	       case GL_ADD_ATI:
		  if (!optype)
		     for (i = 0; i < 3; i++) {
			dst[optype][i] =
			   src[optype][0][i] + src[optype][1][i];
		     }
		  else
		     dst[optype][3] = src[optype][0][3] + src[optype][1][3];
		  break;
	       case GL_SUB_ATI:
		  if (!optype)
		     for (i = 0; i < 3; i++) {
			dst[optype][i] =
			   src[optype][0][i] - src[optype][1][i];
		     }
		  else
		     dst[optype][3] = src[optype][0][3] - src[optype][1][3];
		  break;
	       case GL_MUL_ATI:
		  if (!optype)
		     for (i = 0; i < 3; i++) {
			dst[optype][i] =
			   src[optype][0][i] * src[optype][1][i];
		     }
		  else
		     dst[optype][3] = src[optype][0][3] * src[optype][1][3];
		  break;
	       case GL_MAD_ATI:
		  if (!optype)
		     for (i = 0; i < 3; i++) {
			dst[optype][i] =
			   src[optype][0][i] * src[optype][1][i] +
			   src[optype][2][i];
		     }
		  else
		     dst[optype][3] =
			src[optype][0][3] * src[optype][1][3] +
			src[optype][2][3];
		  break;
	       case GL_LERP_ATI:
		  if (!optype)
		     for (i = 0; i < 3; i++) {
			dst[optype][i] =
			   src[optype][0][i] * src[optype][1][i] + (1 -
								    src
								    [optype]
								    [0][i]) *
			   src[optype][2][i];
		     }
		  else
		     dst[optype][3] =
			src[optype][0][3] * src[optype][1][3] + (1 -
								 src[optype]
								 [0][3]) *
			src[optype][2][3];
		  break;

	       case GL_MOV_ATI:
		  if (!optype)
		     for (i = 0; i < 3; i++) {
			dst[optype][i] = src[optype][0][i];
		     }
		  else
		     dst[optype][3] = src[optype][0][3];
		  break;
	       case GL_CND_ATI:
		  if (!optype) {
		     for (i = 0; i < 3; i++) {
			dst[optype][i] =
			   (src[optype][2][i] >
			    0.5) ? src[optype][0][i] : src[optype][1][i];
		     }
		  }
		  else {
		     dst[optype][3] =
			(src[optype][2][3] >
			 0.5) ? src[optype][0][3] : src[optype][1][3];
		  }
		  break;

	       case GL_CND0_ATI:
		  if (!optype)
		     for (i = 0; i < 3; i++) {
			dst[optype][i] =
			   (src[optype][2][i] >=
			    0) ? src[optype][0][i] : src[optype][1][i];
		     }
		  else {
		     dst[optype][3] =
			(src[optype][2][3] >=
			 0) ? src[optype][0][3] : src[optype][1][3];
		  }
		  break;
	       case GL_DOT2_ADD_ATI:
		  {
		     GLfloat result;

		     /* DOT 2 always uses the source from the color op */
		     /* could save recalculation of dot products for alpha inst */
		     result = src[0][0][0] * src[0][1][0] +
			src[0][0][1] * src[0][1][1] + src[0][2][2];
		     if (!optype) {
			for (i = 0; i < 3; i++) {
			   dst[optype][i] = result;
			}
		     }
		     else
			dst[optype][3] = result;
		  }
		  break;
	       case GL_DOT3_ATI:
		  {
		     GLfloat result;

		     /* DOT 3 always uses the source from the color op */
		     result = src[0][0][0] * src[0][1][0] +
			src[0][0][1] * src[0][1][1] +
			src[0][0][2] * src[0][1][2];

		     if (!optype) {
			for (i = 0; i < 3; i++) {
			   dst[optype][i] = result;
			}
		     }
		     else
			dst[optype][3] = result;
		  }
		  break;
	       case GL_DOT4_ATI:
		  {
		     GLfloat result;

		     /* DOT 4 always uses the source from the color op */
		     result = src[0][0][0] * src[0][1][0] +
			src[0][0][1] * src[0][1][1] +
			src[0][0][2] * src[0][1][2] +
			src[0][0][3] * src[0][1][3];
		     if (!optype) {
			for (i = 0; i < 3; i++) {
			   dst[optype][i] = result;
			}
		     }
		     else
			dst[optype][3] = result;
		  }
		  break;

	       }
	    }
	 }

	 /* write out the destination registers */
	 for (optype = 0; optype < 2; optype++) {
	    if (inst->Opcode[optype]) {
	       dstreg = inst->DstReg[optype].Index;
	       dstp = machine->Registers[dstreg - GL_REG_0_ATI];

	       if ((optype == 0) || ((inst->Opcode[1] != GL_DOT2_ADD_ATI) &&
		  (inst->Opcode[1] != GL_DOT3_ATI) && (inst->Opcode[1] != GL_DOT4_ATI)))
	          write_dst_addr(optype, inst->DstReg[optype].dstMod,
			      inst->DstReg[optype].dstMask, dst[optype],
			      dstp);
	       else
		  write_dst_addr(1, inst->DstReg[0].dstMod, 0, dst[1], dstp);
	    }
	 }
      }
   }
}