Exemple #1
0
static void r300_insert_wpos(struct r300_vertex_program_compiler* c,
                             struct r300_shader_semantics* outputs)
{
    int i, lastOutput = 0;

    /* Find the max output index. */
    lastOutput = MAX2(lastOutput, outputs->psize);
    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
        lastOutput = MAX2(lastOutput, outputs->color[i]);
        lastOutput = MAX2(lastOutput, outputs->bcolor[i]);
    }
    for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
        lastOutput = MAX2(lastOutput, outputs->generic[i]);
    }
    lastOutput = MAX2(lastOutput, outputs->fog);

    /* Set WPOS after the last output. */
    lastOutput++;
    rc_copy_output(&c->Base, 0, lastOutput); /* out[lastOutput] = out[0]; */
    outputs->wpos = lastOutput;
}
static struct r300_vertex_program *build_program(GLcontext *ctx,
						 struct r300_vertex_program_key *wanted_key,
						 const struct gl_vertex_program *mesa_vp)
{
	struct r300_vertex_program *vp;
	struct r300_vertex_program_compiler compiler;

	vp = _mesa_calloc(sizeof(*vp));
	vp->Base = (struct gl_vertex_program *) _mesa_clone_program(ctx, &mesa_vp->Base);
	_mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));

	rc_init(&compiler.Base);
	compiler.Base.Debug = (RADEON_DEBUG & RADEON_VERTS) ? GL_TRUE : GL_FALSE;

	compiler.code = &vp->code;
	compiler.RequiredOutputs = compute_required_outputs(vp->Base, vp->key.FpReads);
	compiler.SetHwInputOutput = &t_inputs_outputs;

	if (compiler.Base.Debug) {
		fprintf(stderr, "Initial vertex program:\n");
		_mesa_print_program(&vp->Base->Base);
		fflush(stderr);
	}

	if (mesa_vp->IsPositionInvariant) {
		_mesa_insert_mvp_code(ctx, vp->Base);
	}

	radeon_mesa_to_rc_program(&compiler.Base, &vp->Base->Base);

	if (mesa_vp->IsNVProgram)
		initialize_NV_registers(&compiler.Base);

	rc_move_output(&compiler.Base, VERT_RESULT_PSIZ, VERT_RESULT_PSIZ, WRITEMASK_X);

	if (vp->key.WPosAttr != FRAG_ATTRIB_MAX) {
		rc_copy_output(&compiler.Base,
			VERT_RESULT_HPOS,
			vp->key.WPosAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0);
	}

	if (vp->key.FogAttr != FRAG_ATTRIB_MAX) {
		rc_move_output(&compiler.Base,
			VERT_RESULT_FOGC,
			vp->key.FogAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0, WRITEMASK_X);
	}

	r3xx_compile_vertex_program(&compiler);

	if (vp->code.constants.Count > ctx->Const.VertexProgram.MaxParameters) {
		rc_error(&compiler.Base, "Program exceeds constant buffer size limit\n");
	}

	vp->error = compiler.Base.Error;

	vp->Base->Base.InputsRead = vp->code.InputsRead;
	vp->Base->Base.OutputsWritten = vp->code.OutputsWritten;

	rc_destroy(&compiler.Base);

	return vp;
}
Exemple #3
0
void r300_translate_vertex_shader(struct r300_context *r300,
                                  struct r300_vertex_shader *vs)
{
    struct r300_vertex_program_compiler compiler;
    struct tgsi_to_rc ttr;
    unsigned i;

    /* Setup the compiler */
    memset(&compiler, 0, sizeof(compiler));
    rc_init(&compiler.Base, NULL);

    DBG_ON(r300, DBG_VP) ? compiler.Base.Debug |= RC_DBG_LOG : 0;
    DBG_ON(r300, DBG_P_STAT) ? compiler.Base.Debug |= RC_DBG_STATS : 0;
    compiler.code = &vs->code;
    compiler.UserData = vs;
    compiler.Base.is_r500 = r300->screen->caps.is_r500;
    compiler.Base.disable_optimizations = DBG_ON(r300, DBG_NO_OPT);
    compiler.Base.has_half_swizzles = FALSE;
    compiler.Base.has_presub = FALSE;
    compiler.Base.has_omod = FALSE;
    compiler.Base.max_temp_regs = 32;
    compiler.Base.max_constants = 256;
    compiler.Base.max_alu_insts = r300->screen->caps.is_r500 ? 1024 : 256;

    if (compiler.Base.Debug & RC_DBG_LOG) {
        DBG(r300, DBG_VP, "r300: Initial vertex program\n");
        tgsi_dump(vs->state.tokens, 0);
    }

    /* Translate TGSI to our internal representation */
    ttr.compiler = &compiler.Base;
    ttr.info = &vs->info;
    ttr.use_half_swizzles = FALSE;

    r300_tgsi_to_rc(&ttr, vs->state.tokens);

    if (ttr.error) {
        fprintf(stderr, "r300 VP: Cannot translate a shader. "
                "Using a dummy shader instead.\n");
        r300_dummy_vertex_shader(r300, vs);
        return;
    }

    if (compiler.Base.Program.Constants.Count > 200) {
        compiler.Base.remove_unused_constants = TRUE;
    }

    compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1));
    compiler.SetHwInputOutput = &set_vertex_inputs_outputs;

    /* Insert the WPOS output. */
    rc_copy_output(&compiler.Base, 0, vs->outputs.wpos);

    /* Invoke the compiler */
    r3xx_compile_vertex_program(&compiler);
    if (compiler.Base.Error) {
        fprintf(stderr, "r300 VP: Compiler error:\n%sUsing a dummy shader"
                " instead.\n", compiler.Base.ErrorMsg);

        if (vs->dummy) {
            fprintf(stderr, "r300 VP: Cannot compile the dummy shader! "
                    "Giving up...\n");
            abort();
        }

        rc_destroy(&compiler.Base);
        r300_dummy_vertex_shader(r300, vs);
        return;
    }

    /* Initialize numbers of constants for each type. */
    vs->externals_count = 0;
    for (i = 0;
            i < vs->code.constants.Count &&
            vs->code.constants.Constants[i].Type == RC_CONSTANT_EXTERNAL; i++) {
        vs->externals_count = i+1;
    }
    for (; i < vs->code.constants.Count; i++) {
        assert(vs->code.constants.Constants[i].Type == RC_CONSTANT_IMMEDIATE);
    }
    vs->immediates_count = vs->code.constants.Count - vs->externals_count;

    /* And, finally... */
    rc_destroy(&compiler.Base);
}