/**
 * Transform TEX, TXP, TXB, and KIL instructions in the following way:
 *  - premultiply texture coordinates for RECT
 *  - extract operand swizzles
 *  - introduce a temporary register when write masks are needed
 *
 * \todo If/when r5xx uses the radeon_program architecture, this can probably
 * be reused.
 */
static GLboolean transform_TEX(
	struct radeon_transform_context *t,
	struct prog_instruction* orig_inst, void* data)
{
	struct r300_fragment_program_compiler *compiler =
		(struct r300_fragment_program_compiler*)data;
	struct prog_instruction inst = *orig_inst;
	struct prog_instruction* tgt;
	GLboolean destredirect = GL_FALSE;

	if (inst.Opcode != OPCODE_TEX &&
	    inst.Opcode != OPCODE_TXB &&
	    inst.Opcode != OPCODE_TXP &&
	    inst.Opcode != OPCODE_KIL)
		return GL_FALSE;

	if (inst.Opcode != OPCODE_KIL &&
	    t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) {
		GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;

		if (comparefunc == GL_NEVER || comparefunc == GL_ALWAYS) {
			tgt = radeonAppendInstructions(t->Program, 1);

			tgt->Opcode = OPCODE_MOV;
			tgt->DstReg = inst.DstReg;
			if (comparefunc == GL_ALWAYS) {
				tgt->SrcReg[0].File = PROGRAM_BUILTIN;
				tgt->SrcReg[0].Swizzle = SWIZZLE_1111;
			} else {
				tgt->SrcReg[0] = shadow_ambient(t->Program, inst.TexSrcUnit);
			}
			return GL_TRUE;
		}

		inst.DstReg.File = PROGRAM_TEMPORARY;
		inst.DstReg.Index = radeonFindFreeTemporary(t);
		inst.DstReg.WriteMask = WRITEMASK_XYZW;
	}


	/* Hardware uses [0..1]x[0..1] range for rectangle textures
	 * instead of [0..Width]x[0..Height].
	 * Add a scaling instruction.
	 */
	if (inst.Opcode != OPCODE_KIL && inst.TexSrcTarget == TEXTURE_RECT_INDEX) {
		gl_state_index tokens[STATE_LENGTH] = {
			STATE_INTERNAL, STATE_R300_TEXRECT_FACTOR, 0, 0,
			0
		};

		int tempreg = radeonFindFreeTemporary(t);
		int factor_index;

		tokens[2] = inst.TexSrcUnit;
		factor_index = _mesa_add_state_reference(t->Program->Parameters, tokens);

		tgt = radeonAppendInstructions(t->Program, 1);

		tgt->Opcode = OPCODE_MUL;
		tgt->DstReg.File = PROGRAM_TEMPORARY;
		tgt->DstReg.Index = tempreg;
		tgt->SrcReg[0] = inst.SrcReg[0];
		tgt->SrcReg[1].File = PROGRAM_STATE_VAR;
		tgt->SrcReg[1].Index = factor_index;

		reset_srcreg(&inst.SrcReg[0]);
		inst.SrcReg[0].File = PROGRAM_TEMPORARY;
		inst.SrcReg[0].Index = tempreg;
	}

	if (inst.Opcode != OPCODE_KIL) {
		if (inst.DstReg.File != PROGRAM_TEMPORARY ||
		    inst.DstReg.WriteMask != WRITEMASK_XYZW) {
			int tempreg = radeonFindFreeTemporary(t);

			inst.DstReg.File = PROGRAM_TEMPORARY;
			inst.DstReg.Index = tempreg;
			inst.DstReg.WriteMask = WRITEMASK_XYZW;
			destredirect = GL_TRUE;
		}
	}

	tgt = radeonAppendInstructions(t->Program, 1);
	_mesa_copy_instructions(tgt, &inst, 1);

	if (inst.Opcode != OPCODE_KIL &&
	    t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) {
		GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
		GLuint depthmode = compiler->fp->state.unit[inst.TexSrcUnit].depth_texture_mode;
		int rcptemp = radeonFindFreeTemporary(t);
		int pass, fail;

		tgt = radeonAppendInstructions(t->Program, 3);

		tgt[0].Opcode = OPCODE_RCP;
		tgt[0].DstReg.File = PROGRAM_TEMPORARY;
		tgt[0].DstReg.Index = rcptemp;
		tgt[0].DstReg.WriteMask = WRITEMASK_W;
		tgt[0].SrcReg[0] = inst.SrcReg[0];
		tgt[0].SrcReg[0].Swizzle = SWIZZLE_WWWW;

		tgt[1].Opcode = OPCODE_MAD;
		tgt[1].DstReg = inst.DstReg;
		tgt[1].DstReg.WriteMask = orig_inst->DstReg.WriteMask;
		tgt[1].SrcReg[0] = inst.SrcReg[0];
		tgt[1].SrcReg[0].Swizzle = SWIZZLE_ZZZZ;
		tgt[1].SrcReg[1].File = PROGRAM_TEMPORARY;
		tgt[1].SrcReg[1].Index = rcptemp;
		tgt[1].SrcReg[1].Swizzle = SWIZZLE_WWWW;
		tgt[1].SrcReg[2].File = PROGRAM_TEMPORARY;
		tgt[1].SrcReg[2].Index = inst.DstReg.Index;
		if (depthmode == 0) /* GL_LUMINANCE */
			tgt[1].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z);
		else if (depthmode == 2) /* GL_ALPHA */
			tgt[1].SrcReg[2].Swizzle = SWIZZLE_WWWW;

		/* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
		 *   r  < tex  <=>      -tex+r < 0
		 *   r >= tex  <=> not (-tex+r < 0 */
		if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL)
			tgt[1].SrcReg[2].NegateBase = tgt[0].SrcReg[2].NegateBase ^ NEGATE_XYZW;
		else
			tgt[1].SrcReg[0].NegateBase = tgt[0].SrcReg[0].NegateBase ^ NEGATE_XYZW;

		tgt[2].Opcode = OPCODE_CMP;
		tgt[2].DstReg = orig_inst->DstReg;
		tgt[2].SrcReg[0].File = PROGRAM_TEMPORARY;
		tgt[2].SrcReg[0].Index = tgt[1].DstReg.Index;

		if (comparefunc == GL_LESS || comparefunc == GL_GREATER) {
			pass = 1;
			fail = 2;
		} else {
			pass = 2;
			fail = 1;
		}

		tgt[2].SrcReg[pass].File = PROGRAM_BUILTIN;
		tgt[2].SrcReg[pass].Swizzle = SWIZZLE_1111;
		tgt[2].SrcReg[fail] = shadow_ambient(t->Program, inst.TexSrcUnit);
	} else if (destredirect) {
		tgt = radeonAppendInstructions(t->Program, 1);

		tgt->Opcode = OPCODE_MOV;
		tgt->DstReg = orig_inst->DstReg;
		tgt->SrcReg[0].File = PROGRAM_TEMPORARY;
		tgt->SrcReg[0].Index = inst.DstReg.Index;
	}

	return GL_TRUE;
}
Ejemplo n.º 2
0
/**
 * Given a user-specified texture base format, the actual gallium texture
 * format and the current GL_DEPTH_MODE, return a texture swizzle.
 *
 * Consider the case where the user requests a GL_RGB internal texture
 * format the driver actually uses an RGBA format.  The A component should
 * be ignored and sampling from the texture should always return (r,g,b,1).
 * But if we rendered to the texture we might have written A values != 1.
 * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1.
 * This function computes the texture swizzle needed to get the expected
 * values.
 *
 * In the case of depth textures, the GL_DEPTH_MODE state determines the
 * texture swizzle.
 *
 * This result must be composed with the user-specified swizzle to get
 * the final swizzle.
 */
static unsigned
compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode,
                               enum pipe_format actualFormat)
{
   switch (baseFormat) {
   case GL_RGBA:
      return SWIZZLE_XYZW;
   case GL_RGB:
      if (util_format_has_alpha(actualFormat))
         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
      else
         return SWIZZLE_XYZW;
   case GL_RG:
      if (util_format_get_nr_components(actualFormat) > 2)
         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
      else
         return SWIZZLE_XYZW;
   case GL_RED:
      if (util_format_get_nr_components(actualFormat) > 1)
         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
                              SWIZZLE_ZERO, SWIZZLE_ONE);
      else
         return SWIZZLE_XYZW;
   case GL_ALPHA:
      if (util_format_get_nr_components(actualFormat) > 1)
         return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
                              SWIZZLE_ZERO, SWIZZLE_W);
      else
         return SWIZZLE_XYZW;
   case GL_LUMINANCE:
      if (util_format_get_nr_components(actualFormat) > 1)
         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
      else
         return SWIZZLE_XYZW;
   case GL_LUMINANCE_ALPHA:
      if (util_format_get_nr_components(actualFormat) > 2)
         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W);
      else
         return SWIZZLE_XYZW;
   case GL_INTENSITY:
      if (util_format_get_nr_components(actualFormat) > 1)
         return SWIZZLE_XXXX;
      else
         return SWIZZLE_XYZW;
   case GL_STENCIL_INDEX:
      return SWIZZLE_XYZW;
   case GL_DEPTH_STENCIL:
      /* fall-through */
   case GL_DEPTH_COMPONENT:
      /* Now examine the depth mode */
      switch (depthMode) {
      case GL_LUMINANCE:
         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
      case GL_INTENSITY:
         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
      case GL_ALPHA:
         return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
                              SWIZZLE_ZERO, SWIZZLE_X);
      case GL_RED:
         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
                              SWIZZLE_ZERO, SWIZZLE_ONE);
      default:
         assert(!"Unexpected depthMode");
         return SWIZZLE_XYZW;
      }
   default:
      assert(!"Unexpected baseFormat");
      return SWIZZLE_XYZW;
   }
}
Ejemplo n.º 3
0
/**
 * Given a user-specified texture base format, the actual gallium texture
 * format and the current GL_DEPTH_MODE, return a texture swizzle.
 *
 * Consider the case where the user requests a GL_RGB internal texture
 * format the driver actually uses an RGBA format.  The A component should
 * be ignored and sampling from the texture should always return (r,g,b,1).
 * But if we rendered to the texture we might have written A values != 1.
 * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1.
 * This function computes the texture swizzle needed to get the expected
 * values.
 *
 * In the case of depth textures, the GL_DEPTH_MODE state determines the
 * texture swizzle.
 *
 * This result must be composed with the user-specified swizzle to get
 * the final swizzle.
 */
static unsigned
compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode,
                               enum pipe_format actualFormat,
                               unsigned glsl_version)
{
    switch (baseFormat) {
    case GL_RGBA:
        return SWIZZLE_XYZW;
    case GL_RGB:
        if (util_format_has_alpha(actualFormat))
            return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
        else
            return SWIZZLE_XYZW;
    case GL_RG:
        if (util_format_get_nr_components(actualFormat) > 2)
            return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
        else
            return SWIZZLE_XYZW;
    case GL_RED:
        if (util_format_get_nr_components(actualFormat) > 1)
            return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
                                 SWIZZLE_ZERO, SWIZZLE_ONE);
        else
            return SWIZZLE_XYZW;
    case GL_ALPHA:
        if (util_format_get_nr_components(actualFormat) > 1)
            return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
                                 SWIZZLE_ZERO, SWIZZLE_W);
        else
            return SWIZZLE_XYZW;
    case GL_LUMINANCE:
        if (util_format_get_nr_components(actualFormat) > 1)
            return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
        else
            return SWIZZLE_XYZW;
    case GL_LUMINANCE_ALPHA:
        if (util_format_get_nr_components(actualFormat) > 2)
            return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W);
        else
            return SWIZZLE_XYZW;
    case GL_INTENSITY:
        if (util_format_get_nr_components(actualFormat) > 1)
            return SWIZZLE_XXXX;
        else
            return SWIZZLE_XYZW;
    case GL_STENCIL_INDEX:
    case GL_DEPTH_STENCIL:
    case GL_DEPTH_COMPONENT:
        /* Now examine the depth mode */
        switch (depthMode) {
        case GL_LUMINANCE:
            return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
        case GL_INTENSITY:
            return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
        case GL_ALPHA:
            /* The texture(sampler*Shadow) functions from GLSL 1.30 ignore
             * the depth mode and return float, while older shadow* functions
             * and ARB_fp instructions return vec4 according to the depth mode.
             *
             * The problem with the GLSL 1.30 functions is that GL_ALPHA forces
             * them to return 0, breaking them completely.
             *
             * A proper fix would increase code complexity and that's not worth
             * it for a rarely used feature such as the GL_ALPHA depth mode
             * in GL3. Therefore, change GL_ALPHA to GL_INTENSITY for all
             * shaders that use GLSL 1.30 or later.
             *
             * BTW, it's required that sampler views are updated when
             * shaders change (check_sampler_swizzle takes care of that).
             */
            if (glsl_version && glsl_version >= 130)
                return SWIZZLE_XXXX;
            else
                return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
                                     SWIZZLE_ZERO, SWIZZLE_X);
        case GL_RED:
            return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
                                 SWIZZLE_ZERO, SWIZZLE_ONE);
        default:
            assert(!"Unexpected depthMode");
            return SWIZZLE_XYZW;
        }
    default:
        assert(!"Unexpected baseFormat");
        return SWIZZLE_XYZW;
    }
}
/**
 * Transform the program to support fragment.position.
 *
 * Introduce a small fragment at the start of the program that will be
 * the only code that directly reads the FRAG_ATTRIB_WPOS input.
 * All other code pieces that reference that input will be rewritten
 * to read from a newly allocated temporary.
 *
 * \todo if/when r5xx supports the radeon_program architecture, this is a
 * likely candidate for code sharing.
 */
static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
{
	GLuint InputsRead = compiler->fp->mesa_program.Base.InputsRead;

	if (!(InputsRead & FRAG_BIT_WPOS))
		return;

	static gl_state_index tokens[STATE_LENGTH] = {
		STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0
	};
	struct prog_instruction *fpi;
	GLuint window_index;
	int i = 0;
	GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY);

	_mesa_insert_instructions(compiler->program, 0, 3);
	fpi = compiler->program->Instructions;

	/* perspective divide */
	fpi[i].Opcode = OPCODE_RCP;

	fpi[i].DstReg.File = PROGRAM_TEMPORARY;
	fpi[i].DstReg.Index = tempregi;
	fpi[i].DstReg.WriteMask = WRITEMASK_W;
	fpi[i].DstReg.CondMask = COND_TR;

	fpi[i].SrcReg[0].File = PROGRAM_INPUT;
	fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS;
	fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW;
	i++;

	fpi[i].Opcode = OPCODE_MUL;

	fpi[i].DstReg.File = PROGRAM_TEMPORARY;
	fpi[i].DstReg.Index = tempregi;
	fpi[i].DstReg.WriteMask = WRITEMASK_XYZ;
	fpi[i].DstReg.CondMask = COND_TR;

	fpi[i].SrcReg[0].File = PROGRAM_INPUT;
	fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS;
	fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;

	fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY;
	fpi[i].SrcReg[1].Index = tempregi;
	fpi[i].SrcReg[1].Swizzle = SWIZZLE_WWWW;
	i++;

	/* viewport transformation */
	window_index = _mesa_add_state_reference(compiler->program->Parameters, tokens);

	fpi[i].Opcode = OPCODE_MAD;

	fpi[i].DstReg.File = PROGRAM_TEMPORARY;
	fpi[i].DstReg.Index = tempregi;
	fpi[i].DstReg.WriteMask = WRITEMASK_XYZ;
	fpi[i].DstReg.CondMask = COND_TR;

	fpi[i].SrcReg[0].File = PROGRAM_TEMPORARY;
	fpi[i].SrcReg[0].Index = tempregi;
	fpi[i].SrcReg[0].Swizzle =
	    MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);

	fpi[i].SrcReg[1].File = PROGRAM_STATE_VAR;
	fpi[i].SrcReg[1].Index = window_index;
	fpi[i].SrcReg[1].Swizzle =
	    MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);

	fpi[i].SrcReg[2].File = PROGRAM_STATE_VAR;
	fpi[i].SrcReg[2].Index = window_index;
	fpi[i].SrcReg[2].Swizzle =
	    MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
	i++;

	for (; i < compiler->program->NumInstructions; ++i) {
		int reg;
		for (reg = 0; reg < 3; reg++) {
			if (fpi[i].SrcReg[reg].File == PROGRAM_INPUT &&
			    fpi[i].SrcReg[reg].Index == FRAG_ATTRIB_WPOS) {
				fpi[i].SrcReg[reg].File = PROGRAM_TEMPORARY;
				fpi[i].SrcReg[reg].Index = tempregi;
			}
		}
	}
}
Ejemplo n.º 5
0
/**
 * Look for a float vector in the given parameter list.  The float vector
 * may be of length 1, 2, 3 or 4.  If swizzleOut is non-null, we'll try
 * swizzling to find a match.
 * \param list  the parameter list to search
 * \param v  the float vector to search for
 * \param size  number of element in v
 * \param posOut  returns the position of the constant, if found
 * \param swizzleOut  returns a swizzle mask describing location of the
 *                    vector elements if found.
 * \return GL_TRUE if found, GL_FALSE if not found
 */
GLboolean
_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
                                const GLfloat v[], GLuint vSize,
                                GLint *posOut, GLuint *swizzleOut)
{
   GLuint i;

   assert(vSize >= 1);
   assert(vSize <= 4);

   if (!list)
      return -1;

   for (i = 0; i < list->NumParameters; i++) {
      if (list->Parameters[i].Type == PROGRAM_CONSTANT) {
         if (!swizzleOut) {
            /* swizzle not allowed */
            GLuint j, match = 0;
            for (j = 0; j < vSize; j++) {
               if (v[j] == list->ParameterValues[i][j])
                  match++;
            }
            if (match == vSize) {
               *posOut = i;
               return GL_TRUE;
            }
         }
         else {
            /* try matching w/ swizzle */
             if (vSize == 1) {
                /* look for v[0] anywhere within float[4] value */
                GLuint j;
                for (j = 0; j < 4; j++) {
                   if (list->ParameterValues[i][j] == v[0]) {
                      /* found it */
                      *posOut = i;
                      *swizzleOut = MAKE_SWIZZLE4(j, j, j, j);
                      return GL_TRUE;
                   }
                }
             }
             else if (vSize <= list->Parameters[i].Size) {
                /* see if we can match this constant (with a swizzle) */
                GLuint swz[4];
                GLuint match = 0, j, k;
                for (j = 0; j < vSize; j++) {
                   if (v[j] == list->ParameterValues[i][j]) {
                      swz[j] = j;
                      match++;
                   }
                   else {
                      for (k = 0; k < list->Parameters[i].Size; k++) {
                         if (v[j] == list->ParameterValues[i][k]) {
                            swz[j] = k;
                            match++;
                            break;
                         }
                      }
                   }
                }
                /* smear last value to remaining positions */
                for (; j < 4; j++)
                   swz[j] = swz[j-1];

                if (match == vSize) {
                   *posOut = i;
                   *swizzleOut = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
                   return GL_TRUE;
                }
             }
         }
      }
   }

   *posOut = -1;
   return GL_FALSE;
}
Ejemplo n.º 6
0
void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead,  GLuint *_OutputsWritten)
{
	r300ContextPtr rmesa = R300_CONTEXT( ctx );
	TNLcontext *tnl = TNL_CONTEXT(ctx);
	struct vertex_buffer *VB = &tnl->vb;
	int first_free_tex = 0;
	GLuint InputsRead = 0;
	GLuint OutputsWritten = 0;
	int num_attrs = 0;
	GLuint fp_reads = rmesa->selected_fp->InputsRead;
	struct vertex_attribute *attrs = rmesa->vbuf.attribs;

	radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
	rmesa->swtcl.coloroffset = rmesa->swtcl.specoffset = 0;
	rmesa->radeon.swtcl.vertex_attr_count = 0;

	if (RADEON_DEBUG & RADEON_VERTS)
		fprintf(stderr, "%s\n", __func__);

	/* We always want non Ndc coords format */
	VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;

	/* Always write position vector */
	InputsRead |= 1 << VERT_ATTRIB_POS;
	OutputsWritten |= 1 << VERT_RESULT_HPOS;
	EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F );
	ADD_ATTR(VERT_ATTRIB_POS, R300_DATA_TYPE_FLOAT_4, SWTCL_OVM_POS, SWIZZLE_XYZW, MASK_XYZW, 0);
	rmesa->swtcl.coloroffset = 4;

	if (fp_reads & FRAG_BIT_COL0) {
		InputsRead |= 1 << VERT_ATTRIB_COLOR0;
		OutputsWritten |= 1 << VERT_RESULT_COL0;
#if MESA_LITTLE_ENDIAN
		EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA );
		ADD_ATTR(VERT_ATTRIB_COLOR0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW, 1);
#else
		EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR );
		ADD_ATTR(VERT_ATTRIB_COLOR0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW, 1);
#endif
	}

	if (fp_reads & FRAG_BIT_COL1) {
		GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
		InputsRead |= 1 << VERT_ATTRIB_COLOR1;
		OutputsWritten |= 1 << VERT_RESULT_COL1;
#if MESA_LITTLE_ENDIAN
		EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4UB_4F_RGBA );
		ADD_ATTR(VERT_ATTRIB_COLOR1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR1, swiz, MASK_XYZW, 1);
#else
		EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4UB_4F_ABGR );
		ADD_ATTR(VERT_ATTRIB_COLOR1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR1, swiz, MASK_XYZW, 1);
#endif
		rmesa->swtcl.specoffset = rmesa->swtcl.coloroffset + 1;
	}

	if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
		VB->AttribPtr[VERT_ATTRIB_GENERIC0] = VB->ColorPtr[1];
		OutputsWritten |= 1 << VERT_RESULT_BFC0;
#if MESA_LITTLE_ENDIAN
		EMIT_ATTR( _TNL_ATTRIB_GENERIC0, EMIT_4UB_4F_RGBA );
		ADD_ATTR(VERT_ATTRIB_GENERIC0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR2, SWIZZLE_XYZW, MASK_XYZW, 1);
#else
		EMIT_ATTR( _TNL_ATTRIB_GENERIC0, EMIT_4UB_4F_ABGR );
		ADD_ATTR(VERT_ATTRIB_GENERIC0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR2, SWIZZLE_XYZW, MASK_XYZW, 1);
#endif
		if (fp_reads & FRAG_BIT_COL1) {
			VB->AttribPtr[VERT_ATTRIB_GENERIC1] = VB->SecondaryColorPtr[1];
			GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
			OutputsWritten |= 1 << VERT_RESULT_BFC1;
#if MESA_LITTLE_ENDIAN
			EMIT_ATTR( _TNL_ATTRIB_GENERIC1, EMIT_4UB_4F_RGBA );
			ADD_ATTR(VERT_ATTRIB_GENERIC1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR3, swiz, MASK_XYZW, 1);
#else
			EMIT_ATTR( _TNL_ATTRIB_GENERIC1, EMIT_4UB_4F_ABGR );
			ADD_ATTR(VERT_ATTRIB_GENERIC1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR3, swiz, MASK_XYZW, 1);
#endif
		}
	}

	if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE )) {
		GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
		InputsRead |= 1 << VERT_ATTRIB_POINT_SIZE;
		OutputsWritten |= 1 << VERT_RESULT_PSIZ;
		EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F );
		ADD_ATTR(VERT_ATTRIB_POINT_SIZE, R300_DATA_TYPE_FLOAT_1, SWTCL_OVM_POINT_SIZE, swiz, MASK_X, 0);
	}

	if (rmesa->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) {
		int tex_id = rmesa->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0;

		VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_POS];
		VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_POS];
		RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id);
	}

	if (rmesa->selected_fp->fog_attr != FRAG_ATTRIB_MAX) {
		int tex_id = rmesa->selected_fp->fog_attr - FRAG_ATTRIB_TEX0;

		VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG];
		VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG];
		RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id);
	}

	/**
	 *  Sending only one texcoord component may lead to lock up,
	 *  so for all textures always output 4 texcoord components to RS.
	 */
	{
		int i;
		GLuint swiz, format, hw_format;
		for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
			if (fp_reads & FRAG_BIT_TEX(i)) {
				switch (VB->TexCoordPtr[i]->size) {
					case 1:
						format = EMIT_1F;
						hw_format = R300_DATA_TYPE_FLOAT_1;
						swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE);
						break;
					case 2:
						format = EMIT_2F;
						hw_format = R300_DATA_TYPE_FLOAT_2;
						swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
						break;
					case 3:
						format = EMIT_3F;
						hw_format = R300_DATA_TYPE_FLOAT_3;
						swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
						break;
					case 4:
						format = EMIT_4F;
						hw_format = R300_DATA_TYPE_FLOAT_4;
						swiz = SWIZZLE_XYZW;
						break;
					default:
						continue;
				}
				InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i);
				OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
				EMIT_ATTR(_TNL_ATTRIB_TEX(i), format);
				ADD_ATTR(VERT_ATTRIB_TEX0 + i, hw_format, SWTCL_OVM_TEX(first_free_tex), swiz, MASK_XYZW, 0);
				++first_free_tex;
			}
		}
	}

	if (first_free_tex >= ctx->Const.MaxTextureUnits) {
		fprintf(stderr, "\tout of free texcoords to write fog coordinate\n");
		_mesa_exit(-1);
	}

	R300_NEWPRIM(rmesa);
	rmesa->vbuf.num_attribs = num_attrs;
	*_InputsRead = InputsRead;
	*_OutputsWritten = OutputsWritten;

	RENDERINPUTS_COPY(rmesa->render_inputs_bitset, tnl->render_inputs_bitset);
}
Ejemplo n.º 7
0
   {"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW},
   {"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
   {"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
   {"specular", {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
   {"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX},
};

static struct gl_builtin_uniform_element gl_LightSource_elements[] = {
   {"ambient", {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
   {"diffuse", {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
   {"specular", {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
   {"position", {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW},
   {"halfVector", {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW},
   {"spotDirection", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION},
    MAKE_SWIZZLE4(SWIZZLE_X,
		  SWIZZLE_Y,
		  SWIZZLE_Z,
		  SWIZZLE_Z)},
   {"spotCosCutoff", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW},
   {"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX},
   {"spotExponent", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW},
   {"constantAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX},
   {"linearAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY},
   {"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ},
};

static struct gl_builtin_uniform_element gl_LightModel_elements[] = {
   {"ambient", {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW},
};

static struct gl_builtin_uniform_element gl_FrontLightModelProduct_elements[] = {
   {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW},
Ejemplo n.º 8
0
static void
_mesa_insert_mvp_mad_code(struct gl_context *ctx, struct gl_vertex_program *vprog)
{
    struct prog_instruction *newInst;
    const GLuint origLen = vprog->Base.NumInstructions;
    const GLuint newLen = origLen + 4;
    GLuint hposTemp;
    GLuint i;

    /*
     * Setup state references for the modelview/projection matrix.
     * XXX we should check if these state vars are already declared.
     */
    static const gl_state_index mvpState[4][STATE_LENGTH] = {
        { STATE_MVP_MATRIX, 0, 0, 0, STATE_MATRIX_TRANSPOSE },
        { STATE_MVP_MATRIX, 0, 1, 1, STATE_MATRIX_TRANSPOSE },
        { STATE_MVP_MATRIX, 0, 2, 2, STATE_MATRIX_TRANSPOSE },
        { STATE_MVP_MATRIX, 0, 3, 3, STATE_MATRIX_TRANSPOSE },
    };
    GLint mvpRef[4];

    for (i = 0; i < 4; i++) {
        mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters,
                                              mvpState[i]);
    }

    /* Alloc storage for new instructions */
    newInst = _mesa_alloc_instructions(newLen);
    if (!newInst) {
        _mesa_error(ctx, GL_OUT_OF_MEMORY,
                    "glProgramString(inserting position_invariant code)");
        return;
    }

    /* TEMP hposTemp; */
    hposTemp = vprog->Base.NumTemporaries++;

    /*
     * Generated instructions:
     *    emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]);
     *    emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp);
     *    emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp);
     *    emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp);
     */
    _mesa_init_instructions(newInst, 4);

    newInst[0].Opcode = OPCODE_MUL;
    newInst[0].DstReg.File = PROGRAM_TEMPORARY;
    newInst[0].DstReg.Index = hposTemp;
    newInst[0].DstReg.WriteMask = WRITEMASK_XYZW;
    newInst[0].SrcReg[0].File = PROGRAM_INPUT;
    newInst[0].SrcReg[0].Index = VERT_ATTRIB_POS;
    newInst[0].SrcReg[0].Swizzle = SWIZZLE_XXXX;
    newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR;
    newInst[0].SrcReg[1].Index = mvpRef[0];
    newInst[0].SrcReg[1].Swizzle = SWIZZLE_NOOP;

    for (i = 1; i <= 2; i++) {
        newInst[i].Opcode = OPCODE_MAD;
        newInst[i].DstReg.File = PROGRAM_TEMPORARY;
        newInst[i].DstReg.Index = hposTemp;
        newInst[i].DstReg.WriteMask = WRITEMASK_XYZW;
        newInst[i].SrcReg[0].File = PROGRAM_INPUT;
        newInst[i].SrcReg[0].Index = VERT_ATTRIB_POS;
        newInst[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(i,i,i,i);
        newInst[i].SrcReg[1].File = PROGRAM_STATE_VAR;
        newInst[i].SrcReg[1].Index = mvpRef[i];
        newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
        newInst[i].SrcReg[2].File = PROGRAM_TEMPORARY;
        newInst[i].SrcReg[2].Index = hposTemp;
        newInst[1].SrcReg[2].Swizzle = SWIZZLE_NOOP;
    }

    newInst[3].Opcode = OPCODE_MAD;
    newInst[3].DstReg.File = PROGRAM_OUTPUT;
    newInst[3].DstReg.Index = VARYING_SLOT_POS;
    newInst[3].DstReg.WriteMask = WRITEMASK_XYZW;
    newInst[3].SrcReg[0].File = PROGRAM_INPUT;
    newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS;
    newInst[3].SrcReg[0].Swizzle = SWIZZLE_WWWW;
    newInst[3].SrcReg[1].File = PROGRAM_STATE_VAR;
    newInst[3].SrcReg[1].Index = mvpRef[3];
    newInst[3].SrcReg[1].Swizzle = SWIZZLE_NOOP;
    newInst[3].SrcReg[2].File = PROGRAM_TEMPORARY;
    newInst[3].SrcReg[2].Index = hposTemp;
    newInst[3].SrcReg[2].Swizzle = SWIZZLE_NOOP;


    /* Append original instructions after new instructions */
    _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen);

    /* free old instructions */
    _mesa_free_instructions(vprog->Base.Instructions, origLen);

    /* install new instructions */
    vprog->Base.Instructions = newInst;
    vprog->Base.NumInstructions = newLen;
    vprog->Base.InputsRead |= VERT_BIT_POS;
    vprog->Base.OutputsWritten |= BITFIELD64_BIT(VARYING_SLOT_POS);
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
/**
 * Returns a fragment program which implements the current pixel transfer ops.
 */
static struct gl_fragment_program *
get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key)
{
   struct st_context *st = ctx->st;
   struct prog_instruction inst[MAX_INST];
   struct gl_program_parameter_list *params;
   struct gl_fragment_program *fp;
   GLuint ic = 0;
   const GLuint colorTemp = 0;

   fp = (struct gl_fragment_program *)
      ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
   if (!fp)
      return NULL;

   params = _mesa_new_parameter_list();

   /*
    * Get initial pixel color from the texture.
    * TEX colorTemp, fragment.texcoord[0], texture[0], 2D;
    */
   _mesa_init_instructions(inst + ic, 1);
   inst[ic].Opcode = OPCODE_TEX;
   inst[ic].DstReg.File = PROGRAM_TEMPORARY;
   inst[ic].DstReg.Index = colorTemp;
   inst[ic].SrcReg[0].File = PROGRAM_INPUT;
   inst[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
   inst[ic].TexSrcUnit = 0;
   inst[ic].TexSrcTarget = TEXTURE_2D_INDEX;
   ic++;
   fp->Base.InputsRead = (1 << FRAG_ATTRIB_TEX0);
   fp->Base.OutputsWritten = (1 << FRAG_RESULT_COLR);
   fp->Base.SamplersUsed = 0x1;  /* sampler 0 (bit 0) is used */

   if (key->scaleAndBias) {
      static const gl_state_index scale_state[STATE_LENGTH] =
         { STATE_INTERNAL, STATE_PT_SCALE, 0, 0, 0 };
      static const gl_state_index bias_state[STATE_LENGTH] =
         { STATE_INTERNAL, STATE_PT_BIAS, 0, 0, 0 };
      GLfloat scale[4], bias[4];
      GLint scale_p, bias_p;

      scale[0] = ctx->Pixel.RedScale;
      scale[1] = ctx->Pixel.GreenScale;
      scale[2] = ctx->Pixel.BlueScale;
      scale[3] = ctx->Pixel.AlphaScale;
      bias[0] = ctx->Pixel.RedBias;
      bias[1] = ctx->Pixel.GreenBias;
      bias[2] = ctx->Pixel.BlueBias;
      bias[3] = ctx->Pixel.AlphaBias;

      scale_p = _mesa_add_state_reference(params, scale_state);
      bias_p = _mesa_add_state_reference(params, bias_state);

      /* MAD colorTemp, colorTemp, scale, bias; */
      _mesa_init_instructions(inst + ic, 1);
      inst[ic].Opcode = OPCODE_MAD;
      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
      inst[ic].DstReg.Index = colorTemp;
      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
      inst[ic].SrcReg[0].Index = colorTemp;
      inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR;
      inst[ic].SrcReg[1].Index = scale_p;
      inst[ic].SrcReg[2].File = PROGRAM_STATE_VAR;
      inst[ic].SrcReg[2].Index = bias_p;
      ic++;
   }

   if (key->pixelMaps) {
      const GLuint temp = 1;

      /* create the colormap/texture now if not already done */
      if (!st->pixel_xfer.pixelmap_texture) {
         st->pixel_xfer.pixelmap_texture = create_color_map_texture(ctx);
      }

      /* with a little effort, we can do four pixel map look-ups with
       * two TEX instructions:
       */

      /* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */
      _mesa_init_instructions(inst + ic, 1);
      inst[ic].Opcode = OPCODE_TEX;
      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
      inst[ic].DstReg.Index = temp;
      inst[ic].DstReg.WriteMask = WRITEMASK_XY; /* write R,G */
      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
      inst[ic].SrcReg[0].Index = colorTemp;
      inst[ic].TexSrcUnit = 1;
      inst[ic].TexSrcTarget = TEXTURE_2D_INDEX;
      ic++;

      /* TEX temp.ba, colorTemp.baba, texture[1], 2D; */
      _mesa_init_instructions(inst + ic, 1);
      inst[ic].Opcode = OPCODE_TEX;
      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
      inst[ic].DstReg.Index = temp;
      inst[ic].DstReg.WriteMask = WRITEMASK_ZW; /* write B,A */
      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
      inst[ic].SrcReg[0].Index = colorTemp;
      inst[ic].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W,
                                                 SWIZZLE_Z, SWIZZLE_W);
      inst[ic].TexSrcUnit = 1;
      inst[ic].TexSrcTarget = TEXTURE_2D_INDEX;
      ic++;

      /* MOV colorTemp, temp; */
      _mesa_init_instructions(inst + ic, 1);
      inst[ic].Opcode = OPCODE_MOV;
      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
      inst[ic].DstReg.Index = colorTemp;
      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
      inst[ic].SrcReg[0].Index = temp;
      ic++;

      fp->Base.SamplersUsed |= (1 << 1);  /* sampler 1 is used */
   }

   if (key->colorMatrix) {
      static const gl_state_index row0_state[STATE_LENGTH] =
         { STATE_COLOR_MATRIX, 0, 0, 0, 0 };
      static const gl_state_index row1_state[STATE_LENGTH] =
         { STATE_COLOR_MATRIX, 0, 1, 1, 0 };
      static const gl_state_index row2_state[STATE_LENGTH] =
         { STATE_COLOR_MATRIX, 0, 2, 2, 0 };
      static const gl_state_index row3_state[STATE_LENGTH] =
         { STATE_COLOR_MATRIX, 0, 3, 3, 0 };

      GLint row0_p = _mesa_add_state_reference(params, row0_state);
      GLint row1_p = _mesa_add_state_reference(params, row1_state);
      GLint row2_p = _mesa_add_state_reference(params, row2_state);
      GLint row3_p = _mesa_add_state_reference(params, row3_state);
      const GLuint temp = 1;

      /* DP4 temp.x, colorTemp, matrow0; */
      _mesa_init_instructions(inst + ic, 1);
      inst[ic].Opcode = OPCODE_DP4;
      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
      inst[ic].DstReg.Index = temp;
      inst[ic].DstReg.WriteMask = WRITEMASK_X;
      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
      inst[ic].SrcReg[0].Index = colorTemp;
      inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR;
      inst[ic].SrcReg[1].Index = row0_p;
      ic++;

      /* DP4 temp.y, colorTemp, matrow1; */
      _mesa_init_instructions(inst + ic, 1);
      inst[ic].Opcode = OPCODE_DP4;
      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
      inst[ic].DstReg.Index = temp;
      inst[ic].DstReg.WriteMask = WRITEMASK_Y;
      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
      inst[ic].SrcReg[0].Index = colorTemp;
      inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR;
      inst[ic].SrcReg[1].Index = row1_p;
      ic++;

      /* DP4 temp.z, colorTemp, matrow2; */
      _mesa_init_instructions(inst + ic, 1);
      inst[ic].Opcode = OPCODE_DP4;
      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
      inst[ic].DstReg.Index = temp;
      inst[ic].DstReg.WriteMask = WRITEMASK_Z;
      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
      inst[ic].SrcReg[0].Index = colorTemp;
      inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR;
      inst[ic].SrcReg[1].Index = row2_p;
      ic++;

      /* DP4 temp.w, colorTemp, matrow3; */
      _mesa_init_instructions(inst + ic, 1);
      inst[ic].Opcode = OPCODE_DP4;
      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
      inst[ic].DstReg.Index = temp;
      inst[ic].DstReg.WriteMask = WRITEMASK_W;
      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
      inst[ic].SrcReg[0].Index = colorTemp;
      inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR;
      inst[ic].SrcReg[1].Index = row3_p;
      ic++;

      /* MOV colorTemp, temp; */
      _mesa_init_instructions(inst + ic, 1);
      inst[ic].Opcode = OPCODE_MOV;
      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
      inst[ic].DstReg.Index = colorTemp;
      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
      inst[ic].SrcReg[0].Index = temp;
      ic++;
   }

   if (key->colorMatrixPostScaleBias) {
      static const gl_state_index scale_state[STATE_LENGTH] =
         { STATE_INTERNAL, STATE_PT_SCALE, 0, 0, 0 };
      static const gl_state_index bias_state[STATE_LENGTH] =
         { STATE_INTERNAL, STATE_PT_BIAS, 0, 0, 0 };
      GLint scale_param, bias_param;

      scale_param = _mesa_add_state_reference(params, scale_state);
      bias_param = _mesa_add_state_reference(params, bias_state);

      _mesa_init_instructions(inst + ic, 1);
      inst[ic].Opcode = OPCODE_MAD;
      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
      inst[ic].DstReg.Index = colorTemp;
      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
      inst[ic].SrcReg[0].Index = colorTemp;
      inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR;
      inst[ic].SrcReg[1].Index = scale_param;
      inst[ic].SrcReg[2].File = PROGRAM_STATE_VAR;
      inst[ic].SrcReg[2].Index = bias_param;
      ic++;
   }

   /* Modify last instruction's dst reg to write to result.color */
   {
      struct prog_instruction *last = &inst[ic - 1];
      last->DstReg.File = PROGRAM_OUTPUT;
      last->DstReg.Index = FRAG_RESULT_COLR;
   }

   /* END; */
   _mesa_init_instructions(inst + ic, 1);
   inst[ic].Opcode = OPCODE_END;
   ic++;

   assert(ic <= MAX_INST);


   fp->Base.Instructions = _mesa_alloc_instructions(ic);
   if (!fp->Base.Instructions) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY,
                  "generating pixel transfer program");
      return NULL;
   }

   _mesa_copy_instructions(fp->Base.Instructions, inst, ic);
   fp->Base.NumInstructions = ic;
   fp->Base.Parameters = params;

#if 0
   printf("========= pixel transfer prog\n");
   _mesa_print_program(&fp->Base);
   _mesa_print_parameter_list(fp->Base.Parameters);
#endif

   return fp;
}
Ejemplo n.º 11
0
static struct prog_src_register src_swizzle( struct prog_src_register reg, int x, int y, int z, int w )
{
   reg.Swizzle = MAKE_SWIZZLE4(x,y,z,w);
   return reg;
}
Ejemplo n.º 12
0
static GLboolean
Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
{
   GLubyte token[100];
   GLint idx;

   srcReg->RelAddr = GL_FALSE;

   /* check for '-' */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;
   if (token[0] == '-') {
      (void) Parse_String(parseState, "-");
      srcReg->NegateBase = GL_TRUE;
      if (!Peek_Token(parseState, token))
         RETURN_ERROR;
   }
   else {
      srcReg->NegateBase = GL_FALSE;
   }

   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
   if (token[0] == 'R') {
      srcReg->File = PROGRAM_TEMPORARY;
      if (!Parse_TempReg(parseState, &idx))
         RETURN_ERROR;
      srcReg->Index = idx;
   }
   else if (token[0] == 'c') {
      if (!Parse_ParamReg(parseState, srcReg))
         RETURN_ERROR;
   }
   else if (token[0] == 'v') {
      srcReg->File = PROGRAM_INPUT;
      if (!Parse_AttribReg(parseState, &idx))
         RETURN_ERROR;
      srcReg->Index = idx;
   }
   else {
      RETURN_ERROR2("Bad source register name", token);
   }

   /* init swizzle fields */
   srcReg->Swizzle = SWIZZLE_NOOP;

   /* Look for optional swizzle suffix */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;
   if (token[0] == '.') {
      (void) Parse_String(parseState, ".");  /* consume . */

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

      if (token[1] == 0) {
         /* single letter swizzle */
         if (token[0] == 'x')
            srcReg->Swizzle = MAKE_SWIZZLE4(0, 0, 0, 0);
         else if (token[0] == 'y')
            srcReg->Swizzle = MAKE_SWIZZLE4(1, 1, 1, 1);
         else if (token[0] == 'z')
            srcReg->Swizzle = MAKE_SWIZZLE4(2, 2, 2, 2);
         else if (token[0] == 'w')
            srcReg->Swizzle = MAKE_SWIZZLE4(3, 3, 3, 3);
         else
            RETURN_ERROR1("Expected x, y, z, or w");
      }
      else {
         /* 2, 3 or 4-component swizzle */
         GLint k;
         for (k = 0; token[k] && k < 5; k++) {
            if (token[k] == 'x')
               srcReg->Swizzle |= 0 << (k*3);
            else if (token[k] == 'y')
               srcReg->Swizzle |= 1 << (k*3);
            else if (token[k] == 'z')
               srcReg->Swizzle |= 2 << (k*3);
            else if (token[k] == 'w')
               srcReg->Swizzle |= 3 << (k*3);
            else
               RETURN_ERROR;
         }
         if (k >= 5)
            RETURN_ERROR;
      }
   }

   return GL_TRUE;
}
Ejemplo n.º 13
0
static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const struct gl_client_array *input)
{
	r300ContextPtr r300 = R300_CONTEXT(ctx);
	struct r300_vertex_buffer *vbuf = &r300->vbuf;
	struct vertex_attribute r300_attr = { 0 };
	GLenum type;
	GLuint stride;

	radeon_print(RADEON_RENDER, RADEON_TRACE, "%s\n", __func__);
	stride = (input->StrideB == 0) ? getTypeSize(input->Type) * input->Size : input->StrideB;

	if (input->Type == GL_DOUBLE || input->Type == GL_UNSIGNED_INT || input->Type == GL_INT ||
#if MESA_BIG_ENDIAN
	    getTypeSize(input->Type) != 4 ||
#endif
	    stride < 4) {

		type = GL_FLOAT;

		if (input->StrideB == 0) {
			r300_attr.stride = 0;
		} else {
			r300_attr.stride = sizeof(GLfloat) * input->Size;
		}
		r300_attr.dwords = input->Size;
		r300_attr.is_named_bo = GL_FALSE;
	} else {
		type = input->Type;
		r300_attr.dwords = (getTypeSize(type) * input->Size + 3)/ 4;
		if (!input->BufferObj->Name) {

			if (input->StrideB == 0) {
				r300_attr.stride = 0;
			} else {
				r300_attr.stride = (getTypeSize(type) * input->Size + 3) & ~3;
			}

			r300_attr.is_named_bo = GL_FALSE;
		}
	}

	r300_attr.size = input->Size;
	r300_attr.element = attr;
	r300_attr.dst_loc = vbuf->num_attribs;

	switch (type) {
		case GL_FLOAT:
			switch (input->Size) {
				case 1: r300_attr.data_type = R300_DATA_TYPE_FLOAT_1; break;
				case 2: r300_attr.data_type = R300_DATA_TYPE_FLOAT_2; break;
				case 3: r300_attr.data_type = R300_DATA_TYPE_FLOAT_3; break;
				case 4: r300_attr.data_type = R300_DATA_TYPE_FLOAT_4; break;
			}
			r300_attr._signed = 0;
			r300_attr.normalize = 0;
			break;
		case GL_HALF_FLOAT:
			switch (input->Size) {
				case 1:
				case 2:
					r300_attr.data_type = R300_DATA_TYPE_FLT16_2;
					break;
				case 3:
				case 4:
					r300_attr.data_type = R300_DATA_TYPE_FLT16_4;
					break;
			}
			break;
		case GL_SHORT:
			r300_attr._signed = 1;
			r300_attr.normalize = input->Normalized;
			switch (input->Size) {
				case 1:
				case 2:
					r300_attr.data_type = R300_DATA_TYPE_SHORT_2;
					break;
				case 3:
				case 4:
					r300_attr.data_type = R300_DATA_TYPE_SHORT_4;
					break;
			}
			break;
		case GL_BYTE:
			r300_attr._signed = 1;
			r300_attr.normalize = input->Normalized;
			r300_attr.data_type = R300_DATA_TYPE_BYTE;
			break;
		case GL_UNSIGNED_SHORT:
			r300_attr._signed = 0;
			r300_attr.normalize = input->Normalized;
			switch (input->Size) {
				case 1:
				case 2:
					r300_attr.data_type = R300_DATA_TYPE_SHORT_2;
					break;
				case 3:
				case 4:
					r300_attr.data_type = R300_DATA_TYPE_SHORT_4;
					break;
			}
			break;
		case GL_UNSIGNED_BYTE:
			r300_attr._signed = 0;
			r300_attr.normalize = input->Normalized;
			if (input->Format == GL_BGRA)
				r300_attr.data_type = R300_DATA_TYPE_D3DCOLOR;
			else
				r300_attr.data_type = R300_DATA_TYPE_BYTE;
			break;

		default:
		case GL_DOUBLE:
		case GL_INT:
		case GL_UNSIGNED_INT:
			assert(0);
			break;
	}

	switch (input->Size) {
		case 4:
			r300_attr.swizzle = SWIZZLE_XYZW;
			break;
		case 3:
			r300_attr.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
			break;
		case 2:
			r300_attr.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
			break;
		case 1:
			r300_attr.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE);
			break;
	}

	r300_attr.write_mask = MASK_XYZW;

	vbuf->attribs[vbuf->num_attribs] = r300_attr;
	++vbuf->num_attribs;
}