Beispiel #1
0
/**
 * Add an immediate scalar to the constant list, while trying to avoid
 * duplicates.
 */
unsigned rc_constants_add_immediate_scalar(struct rc_constant_list * c, float data, unsigned * swizzle)
{
    unsigned index;
    int free_index = -1;
    struct rc_constant constant;

    for(index = 0; index < c->Count; ++index) {
        if (c->Constants[index].Type == RC_CONSTANT_IMMEDIATE) {
            unsigned comp;
            for(comp = 0; comp < c->Constants[index].Size; ++comp) {
                if (c->Constants[index].u.Immediate[comp] == data) {
                    *swizzle = RC_MAKE_SWIZZLE(comp, comp, comp, comp);
                    return index;
                }
            }

            if (c->Constants[index].Size < 4)
                free_index = index;
        }
    }

    if (free_index >= 0) {
        unsigned comp = c->Constants[free_index].Size++;
        c->Constants[free_index].u.Immediate[comp] = data;
        *swizzle = RC_MAKE_SWIZZLE(comp, comp, comp, comp);
        return free_index;
    }

    memset(&constant, 0, sizeof(constant));
    constant.Type = RC_CONSTANT_IMMEDIATE;
    constant.Size = 1;
    constant.u.Immediate[0] = data;
    *swizzle = RC_SWIZZLE_XXXX;

    return rc_constants_add(c, &constant);
}
/**
 * Introduce standard code fragment to deal with fragment.position.
 */
void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input,
                                int full_vtransform)
{
	unsigned tempregi = rc_find_free_temporary(c);
	struct rc_instruction * inst_rcp;
	struct rc_instruction * inst_mul;
	struct rc_instruction * inst_mad;
	struct rc_instruction * inst;

	c->Program.InputsRead &= ~(1 << wpos);
	c->Program.InputsRead |= 1 << new_input;

	/* perspective divide */
	inst_rcp = rc_insert_new_instruction(c, &c->Program.Instructions);
	inst_rcp->U.I.Opcode = RC_OPCODE_RCP;

	inst_rcp->U.I.DstReg.File = RC_FILE_TEMPORARY;
	inst_rcp->U.I.DstReg.Index = tempregi;
	inst_rcp->U.I.DstReg.WriteMask = RC_MASK_W;

	inst_rcp->U.I.SrcReg[0].File = RC_FILE_INPUT;
	inst_rcp->U.I.SrcReg[0].Index = new_input;
	inst_rcp->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW;

	inst_mul = rc_insert_new_instruction(c, inst_rcp);
	inst_mul->U.I.Opcode = RC_OPCODE_MUL;

	inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY;
	inst_mul->U.I.DstReg.Index = tempregi;
	inst_mul->U.I.DstReg.WriteMask = RC_MASK_XYZ;

	inst_mul->U.I.SrcReg[0].File = RC_FILE_INPUT;
	inst_mul->U.I.SrcReg[0].Index = new_input;

	inst_mul->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
	inst_mul->U.I.SrcReg[1].Index = tempregi;
	inst_mul->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW;

	/* viewport transformation */
	inst_mad = rc_insert_new_instruction(c, inst_mul);
	inst_mad->U.I.Opcode = RC_OPCODE_MAD;

	inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY;
	inst_mad->U.I.DstReg.Index = tempregi;
	inst_mad->U.I.DstReg.WriteMask = RC_MASK_XYZ;

	inst_mad->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
	inst_mad->U.I.SrcReg[0].Index = tempregi;
	inst_mad->U.I.SrcReg[0].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);

	inst_mad->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
	inst_mad->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);

	inst_mad->U.I.SrcReg[2].File = RC_FILE_CONSTANT;
	inst_mad->U.I.SrcReg[2].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);

	if (full_vtransform) {
		inst_mad->U.I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_VIEWPORT_SCALE, 0);
		inst_mad->U.I.SrcReg[2].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_VIEWPORT_OFFSET, 0);
	} else {
		inst_mad->U.I.SrcReg[1].Index =
		inst_mad->U.I.SrcReg[2].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_WINDOW_DIMENSION, 0);
	}

	for (inst = inst_mad->Next; inst != &c->Program.Instructions; inst = inst->Next) {
		const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
		unsigned i;

		for(i = 0; i < opcode->NumSrcRegs; i++) {
			if (inst->U.I.SrcReg[i].File == RC_FILE_INPUT &&
			    inst->U.I.SrcReg[i].Index == wpos) {
				inst->U.I.SrcReg[i].File = RC_FILE_TEMPORARY;
				inst->U.I.SrcReg[i].Index = tempregi;
			}
		}
	}
}
Beispiel #3
0
static void get_external_state(
    struct r300_context* r300,
    struct r300_fragment_program_external_state* state)
{
    struct r300_textures_state *texstate = r300->textures_state.state;
    struct r300_rs_state *rs = r300->rs_state.state;
    unsigned i;

    state->frag_clamp = rs ? rs->rs.clamp_fragment_color : 0;

    for (i = 0; i < texstate->sampler_state_count; i++) {
        struct r300_sampler_state *s = texstate->sampler_states[i];
        struct r300_sampler_view *v = texstate->sampler_views[i];
        struct r300_resource *t;

        if (!s || !v) {
            continue;
        }

        t = r300_resource(v->base.texture);

        if (s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
            state->unit[i].compare_mode_enabled = 1;

            /* Fortunately, no need to translate this. */
            state->unit[i].texture_compare_func = s->state.compare_func;
        }

        state->unit[i].non_normalized_coords = !s->state.normalized_coords;
        state->unit[i].convert_unorm_to_snorm =
                v->base.format == PIPE_FORMAT_RGTC1_SNORM ||
                v->base.format == PIPE_FORMAT_LATC1_SNORM;

        /* Pass texture swizzling to the compiler, some lowering passes need it. */
        if (v->base.format == PIPE_FORMAT_RGTC1_SNORM ||
            v->base.format == PIPE_FORMAT_LATC1_SNORM) {
            unsigned char swizzle[4];

            util_format_compose_swizzles(
                            util_format_description(v->base.format)->swizzle,
                            v->swizzle,
                            swizzle);

            state->unit[i].texture_swizzle =
                    RC_MAKE_SWIZZLE(swizzle[0], swizzle[1],
                                    swizzle[2], swizzle[3]);
        } else if (state->unit[i].compare_mode_enabled) {
            state->unit[i].texture_swizzle =
                RC_MAKE_SWIZZLE(v->swizzle[0], v->swizzle[1],
                                v->swizzle[2], v->swizzle[3]);
        }

        /* XXX this should probably take into account STR, not just S. */
        if (t->tex.is_npot) {
            switch (s->state.wrap_s) {
            case PIPE_TEX_WRAP_REPEAT:
                state->unit[i].wrap_mode = RC_WRAP_REPEAT;
                break;

            case PIPE_TEX_WRAP_MIRROR_REPEAT:
                state->unit[i].wrap_mode = RC_WRAP_MIRRORED_REPEAT;
                break;

            case PIPE_TEX_WRAP_MIRROR_CLAMP:
            case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
            case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
                state->unit[i].wrap_mode = RC_WRAP_MIRRORED_CLAMP;
                break;

            default:
                state->unit[i].wrap_mode = RC_WRAP_NONE;
            }

            if (t->b.b.b.target == PIPE_TEXTURE_3D)
                state->unit[i].clamp_and_scale_before_fetch = TRUE;
        }
    }
}