static void add_tex_reader(
	struct schedule_state * s,
	struct schedule_instruction * writer,
	struct schedule_instruction * reader)
{
	if (!writer || writer->Instruction->Type != RC_INSTRUCTION_NORMAL) {
		/*Not a TEX instructions */
		return;
	}
	reader->TexReadCount++;
	rc_list_add(&writer->TexReaders, rc_list(&s->C->Pool, reader));
}
示例#2
0
文件: fn_basic.c 项目: robacklin/cftp
void fn_colon(char **args)
{
	char *cmd, *p, *line = NULL;
	int i;

	if (args) {
	    cmd = args[0];
	    args++;
	}
	else {
	    line = p = read_string(": ", 1);
	    if (line == NULL || line[0] == '\0') {
		free(line);
		disp_status(DISP_STATUS, "");
		return;
	    }

	    if ((cmd=rc_token(&p)) == NULL) {
		disp_status(DISP_STATUS, "no function");
		return;
	    }
	}
	
	if ((i=find_function(cmd)) < 0) {
	    disp_status(DISP_STATUS, "unknown function: %s", cmd);
	    if (line)
		free(line);
	    return;
	}

	if (line) {
	    args = rc_list(p);
	}

	disp_status(DISP_STATUS, "");
	
	if (functions[i].fn)
	    functions[i].fn(args);

	if (line) {
	    free(line);
	    if (args) {
		for (i=0; args[i]; i++)
		    free(args[i]);
		free(args);
	    }
	}
}
/**
 * Emit all ready texture instructions in a single block.
 *
 * Emit as a single block to (hopefully) sample many textures in parallel,
 * and to avoid hardware indirections on R300.
 */
static void emit_all_tex(struct schedule_state * s, struct rc_instruction * before)
{
	struct schedule_instruction *readytex;
	struct rc_instruction * inst_begin;

	assert(s->ReadyTEX);
	notify_sem_wait(s);

	/* Node marker for R300 */
	inst_begin = rc_insert_new_instruction(s->C, before->Prev);
	inst_begin->U.I.Opcode = RC_OPCODE_BEGIN_TEX;

	/* Link texture instructions back in */
	readytex = s->ReadyTEX;
	while(readytex) {
		rc_insert_instruction(before->Prev, readytex->Instruction);
		DBG("%i: commit TEX reads\n", readytex->Instruction->IP);

		/* All of the TEX instructions in the same TEX block have
		 * their source registers read from before any of the
		 * instructions in that block write to their destination
		 * registers.  This means that when we commit a TEX
		 * instruction, any other TEX instruction that wants to write
		 * to one of the committed instruction's source register can be
		 * marked as ready and should be emitted in the same TEX
		 * block. This prevents the following sequence from being
		 * emitted in two different TEX blocks:
		 * 0: TEX temp[0].xyz, temp[1].xy__, 2D[0];
		 * 1: TEX temp[1].xyz, temp[2].xy__, 2D[0];
		 */
		commit_update_reads(s, readytex);
		readytex = readytex->NextReady;
	}
	readytex = s->ReadyTEX;
	s->ReadyTEX = 0;
	while(readytex){
		DBG("%i: commit TEX writes\n", readytex->Instruction->IP);
		commit_update_writes(s, readytex);
		/* Set semaphore bits for last TEX instruction in the block */
		if (!readytex->NextReady) {
			readytex->Instruction->U.I.TexSemAcquire = 1;
			readytex->Instruction->U.I.TexSemWait = 1;
		}
		rc_list_add(&s->PendingTEX, rc_list(&s->C->Pool, readytex));
		readytex = readytex->NextReady;
	}
}
示例#4
0
文件: fn_bind.c 项目: robacklin/cftp
void
fn_bind(char **args)
{
    enum state state, s2;
    int key, fn, i;
    char *line = NULL;
    char *staten, *kname, *cmd, **list, *p;
    struct binding *b;

    state = bs_none;

    if (args) {
	if ((s2=parse_state(args[0])) != bs_nostate) {
	    staten = args[0];
	    state = s2;
	    args++;
	}
	kname = args[0];
	cmd = args[1];
	args += 2;
    }
    else {
	if (rc_inrc) {
	    rc_error("bind: no arguments given");
	    return;
	}
	line = p = read_string("bind ", 1);

	if ((kname=rc_token(&p)) == NULL) {
	    disp_status(DISP_STATUS, "no key");
	    free(line);
	    return;
	}
	if ((s2=parse_state(kname)) != bs_nostate) {
	    staten = kname;
	    state = s2;

	    if ((kname=rc_token(&p)) == NULL) {
		disp_status(DISP_STATUS, "no key");
		free(line);
		return;
	    }
	}
	cmd = rc_token(&p);
    }

    if (state == bs_unknown) {
	if (rc_inrc)
	    rc_error("unknown state: %s", staten);
	else
	    disp_status(DISP_STATUS, "unknown state: %s", staten);
	if (line)
	    free(line);
	return;
    }

    if ((key=parse_key(kname)) < 0) {
	if (rc_inrc)
	    rc_error("unknown key: %s", kname);
	else
	    disp_status(DISP_STATUS, "unknown key: %s", kname);
	if (line)
	    free(line);
	return;
    }
	
    if (cmd) {
	if ((fn=find_function(cmd)) < 0) {
	    if (rc_inrc)
		rc_error("unknown function: %s", cmd);
	    else
		disp_status(DISP_STATUS, "unknown function: %s", cmd);
	    if (line)
		free(line);
	    return;
	}
    }

    if (!rc_inrc)
	disp_status(DISP_STATUS, "");
	
    b = get_function(key, state);

    if (b->state == state) {
	b->fn = -1;
	if (b->args) {
	    if (b->args < binding_argpool
		|| (b->args >= binding_argpool+binding_nargpool)) {
		for (i=0; b->args[i]; i++)
		    free(b->args[i]);
		free(b->args);
		b->args = NULL;
	    }
	}
    }
    else {
	if ((b=(struct binding *)malloc(sizeof(struct binding))) == NULL)
	    return;
	b->fn = -1;
	b->args = NULL;
	b->state = state;

	b->next = binding[key].next;
	binding[key].next = b;
    }

    if (cmd) {
	if (line)
	    list = rc_list(p);
	else {
	    for (i=0; args[i]; i++)
		;
	    if (i > 0) {
		list = (char **)malloc(sizeof(char *)*(i+1));
		memcpy(list, args, sizeof(char *)*(i+1));
	    }
	    else
		list = NULL;
	}

	b->fn = fn;
	b->args = list;
    }

    return;
}
示例#5
0
文件: mkbind.c 项目: robacklin/cftp
int
main(int argc, char **argv)
{
    FILE *fin, *fout;
    char line[4096], *p, *tok, **args;
    char tmp[128];
    struct binding *b;
    int i, j, off, argoff;
    int maxkey;

    prg = argv[0];
    rc_inrc = 1;
    maxkey = max_fnkey + 256;

    if (argc == 2 && strcmp(argv[1], ".") != 0)
	srcdir = argv[1];
    else
	srcdir = NULL;

    initnames();

    for (i=0; i<maxkey; i++) {
	binding[i].next = NULL;
	binding[i].state = bs_none;
	binding[i].fn = -1;
	binding[i].args = NULL;
    }
    off = 0;


    /* processing ``bindings.desc'' */

    if ((fin=vpath_open(FNAME ".desc")) == NULL)
	exit(1);

    rc_lineno = 0;
    while (fgets(line, 4096, fin) != NULL) {
	rc_lineno++;
	p = line;
	if ((tok=rc_token(&p)) == NULL || tok[0] == '#')
	    continue;
	if (strcasecmp(tok, "bind") != 0) {
	    rc_error("non-bind command ignored: %s", tok);
	    continue;
	}
	
	args = rc_list(p);

	fn_bind(args);
    }
    
    if (ferror(fin)) {
	fprintf(stderr, "%s: read error in `%s': %s.\n",
		prg, rc_filename, strerror(errno));
	fclose(fin);
	exit(1);
    }
    fclose(fin);
    free(rc_filename);
    rc_filename = NULL;


    /* writing ``bindings.c'' in temp file */

    sprintf(tmp, FNAME ".c.%d", getpid());

    if ((fout=fopen(tmp, "w")) == NULL) {
	fprintf(stderr, "%s: can't open output file `%s': %s.\n",
		prg, tmp, strerror(errno));
	exit(1);
    }

    fprintf(fout, "%s", header);


    /* output: bindings */

    off = argoff = 0;
    fprintf(fout, "struct binding " NAME "[] = {\n");
    for (i=0; i<maxkey; i++) {
	fprintf(fout, "    { ");
	if (binding[i].next) {
	    fprintf(fout, "binding_pool+%3d, ", off);
	    for (b=binding[i].next; b; b=b->next)
		off++;
	}
	else
	    fprintf(fout, "NULL            , ");
	if (binding[i].state+1 < nstates)
	    fprintf(fout, "%s, ", states[binding[i].state+1]);
	else
	    fprintf(fout, "%d, ", binding[i].state);
	fprintf(fout, "%3d, ", binding[i].fn);
	if (binding[i].args) {
	    fprintf(fout, "binding_argpool+%d },\n", argoff);
	    for (j=0; binding[i].args[j]; j++)
		;
		argoff += j+1;
	}
	else
	    fprintf(fout, "NULL },\n");
    }
    fprintf(fout, "};\n\n");

    if (ferror(fout)) {
	fprintf(stderr, "%s: write error on `%s': %s.\n",
		prg, FNAME ".c", strerror(errno));
	exit(1);
	fclose(fout);
    }

    /* output: bindings_pool */

    off = 1;
    fprintf(fout, "struct binding " NAME "_" POOL "[] = {\n");
    for (i=0; i<maxkey; i++)
	if (binding[i].next) {
	    for (b=binding[i].next; b; b=b->next) {
		fprintf(fout, "    { ");
		if (b->next)
		    fprintf(fout, "binding_pool+%3d, ", off);
		else
		    fprintf(fout, "NULL            , ");
		if (b->state+1 < nstates)
		    fprintf(fout, "%s, ", states[b->state+1]);
		else
		    fprintf(fout, "%d, ", b->state);
		fprintf(fout, "%3d, ", b->fn);
		if (b->args) {
		    fprintf(fout, "binding_argpool+%d },\n", argoff);
		    for (j=0; b->args[j]; j++)
			;
		    argoff += j+1;
		}
		else
		    fprintf(fout, "NULL },\n");

		off++;
	    }
	}
    fprintf(fout, "};\n\n");
    fprintf(fout, "int " NAME "_n" POOL " = sizeof(" NAME "_" POOL ")"
	    " / sizeof(" NAME "_" POOL "[0]);\n\n");
    
    if (ferror(fout)) {
	fprintf(stderr, "%s: write error on `%s': %s.\n",
		prg, FNAME ".c", strerror(errno));
	exit(1);
	fclose(fout);
    }

    
    /* output: binding_argpool */

    fprintf(fout, "char *" NAME "_" ARGS "[] = {\n   ");
    for (i=0; i<maxkey; i++)
	if (binding[i].args)
	    print_args(fout, binding[i].args);
    for (i=0; i<maxkey; i++)
	if (binding[i].next)
	    for (b=binding[i].next; b; b=b->next)
		if (b->args)
		    print_args(fout, b->args);
    fprintf(fout, "\n};\n\n");

    fprintf(fout, "int " NAME "_n" ARGS " = sizeof(" NAME "_" ARGS ")"
	    " / sizeof(" NAME "_" ARGS "[0]);\n");

    if (ferror(fout)) {
	fprintf(stderr, "%s: write error on `%s': %s.\n",
		prg, FNAME ".c", strerror(errno));
	fclose(fout);
	exit(1);
    }

    fclose(fout);

    /* rename tmp file to ``bindings.c'' */

    if (rename(tmp, FNAME ".c") < 0) {
	fprintf(stderr, "%s: cannot rename `%s' to `%s': %s\n",
		prg, tmp, FNAME ".c", strerror(errno));
	exit(1);
    }

    exit(0);
}