Ejemplo n.º 1
0
/* Creates shader:
 *    (sy)(ss)(rpt3)mov.f16f16 hr0.x, (r)hc0.x
 *    end
 */
static struct fd3_shader_stateobj *
create_solid_fp(struct pipe_context *pctx)
{
	struct fd3_shader_stateobj *so;
	struct ir3_shader *ir = ir3_shader_create();
	struct ir3_instruction *instr;

	/* (sy)(ss)(rpt3)mov.f16f16 hr0.x, (r)hc0.x */
	instr = ir3_instr_create(ir, 1, 0);  /* mov/cov instructions have no opc */
	instr->flags = IR3_INSTR_SY | IR3_INSTR_SS;
	instr->repeat = 3;
	instr->cat1.src_type = TYPE_F16;
	instr->cat1.dst_type = TYPE_F16;

	ir3_reg_create(instr, regid(0,0), IR3_REG_HALF);  /* hr0.x */
	ir3_reg_create(instr, regid(0,0), IR3_REG_HALF |  /* (r)hc0.x */
			IR3_REG_CONST | IR3_REG_R);

	/* end */
	instr = ir3_instr_create(ir, 0, OPC_END);

	so = create_internal_shader(pctx, SHADER_FRAGMENT, ir);
	if (!so)
		return NULL;

	so->color_regid = regid(0,0);
	so->half_precision = true;
	so->inputs_count = 0;
	so->total_in = 0;

	return so;
}
Ejemplo n.º 2
0
/* Creates shader:
 *    (sy)(ss)end
 */
static struct fd3_shader_stateobj *
create_solid_vp(struct pipe_context *pctx)
{
	struct fd3_shader_stateobj *so;
	struct ir3_shader *ir = ir3_shader_create();
	struct ir3_instruction *instr;

	/* (sy)(ss)end */
	instr = ir3_instr_create(ir, 0, OPC_END);
	instr->flags = IR3_INSTR_SY | IR3_INSTR_SS;


	so = create_internal_shader(pctx, SHADER_VERTEX, ir);
	if (!so)
		return NULL;

	so->pos_regid = regid(0,0);
	so->psize_regid = regid(63,0);
	so->inputs_count = 1;
	so->inputs[0].regid = regid(0,0);
	so->inputs[0].compmask = 0xf;
	so->total_in = 4;
	so->outputs_count = 0;

	fixup_vp_regfootprint(so);

	return so;
}
Ejemplo n.º 3
0
static void block_sched(struct ir3_sched_ctx *ctx, struct ir3_block *block)
{
	struct ir3_instruction *instr;

	/* schedule all the shader input's (meta-instr) first so that
	 * the RA step sees that the input registers contain a value
	 * from the start of the shader:
	 */
	if (!block->parent) {
		unsigned i;
		for (i = 0; i < block->ninputs; i++) {
			struct ir3_instruction *in = block->inputs[i];
			if (in)
				schedule(ctx, in, true);
		}
	}

	while ((instr = block->head) && !ctx->error) {
		/* NOTE: always grab next *before* trysched(), in case the
		 * instruction is actually scheduled (and therefore moved
		 * from depth list into scheduled list)
		 */
		struct ir3_instruction *next = instr->next;
		int cnt = trysched(ctx, instr);

		if (cnt == DELAYED)
			cnt = block_sched_undelayed(ctx, block);

		/* -1 is signal to return up stack, but to us means same as 0: */
		cnt = MAX2(0, cnt);
		cnt += ctx->cnt;
		instr = next;

		/* if deepest remaining instruction cannot be scheduled, try
		 * the increasingly more shallow instructions until needed
		 * number of delay slots is filled:
		 */
		while (instr && (cnt > ctx->cnt)) {
			next = instr->next;
			trysched(ctx, instr);
			instr = next;
		}

		/* and if we run out of instructions that can be scheduled,
		 * then it is time for nop's:
		 */
		while (cnt > ctx->cnt)
			schedule(ctx, ir3_instr_create(block, 0, OPC_NOP), false);
	}

	/* at this point, scheduled list is in reverse order, so fix that: */
	block->head = reverse(ctx->scheduled);
}
Ejemplo n.º 4
0
static void schedule(struct ir3_sched_ctx *ctx,
		struct ir3_instruction *instr, bool remove)
{
	struct ir3_block *block = instr->block;

	/* maybe there is a better way to handle this than just stuffing
	 * a nop.. ideally we'd know about this constraint in the
	 * scheduling and depth calculation..
	 */
	if (ctx->scheduled && is_sfu(ctx->scheduled) && is_sfu(instr))
		schedule(ctx, ir3_instr_create(block, 0, OPC_NOP), false);

	/* remove from depth list:
	 */
	if (remove) {
		struct ir3_instruction *p = prev(instr);

		/* NOTE: this can happen for inputs which are not
		 * read.. in that case there is no need to schedule
		 * the input, so just bail:
		 */
		if (instr != (p ? p->next : block->head))
			return;

		if (p)
			p->next = instr->next;
		else
			block->head = instr->next;
	}

	if (writes_addr(instr)) {
		assert(ctx->addr == NULL);
		ctx->addr = instr;
	}

	if (writes_pred(instr)) {
		assert(ctx->pred == NULL);
		ctx->pred = instr;
	}

	instr->flags |= IR3_INSTR_MARK;

	instr->next = ctx->scheduled;
	ctx->scheduled = instr;

	ctx->cnt++;
}
Ejemplo n.º 5
0
static void arr_insert_mov_in(void *arr, int idx, struct ir3_instruction *instr)
{
	/* so, we can't insert a mov in front of a meta:in.. and the downstream
	 * instruction already has a pointer to 'instr'.  So we cheat a bit and
	 * morph the meta:in instruction into a mov and insert a new meta:in
	 * in front.
	 */
	struct ir3_instruction *in;

	debug_assert(instr->regs_count == 1);

	in = ir3_instr_create(instr->block, OPC_META_INPUT);
	in->inout.block = instr->block;
	ir3_reg_create(in, instr->regs[0]->num, 0);

	/* create src reg for meta:in and fixup to now be a mov: */
	ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = in;
	instr->opc = OPC_MOV;
	instr->cat1.src_type = TYPE_F32;
	instr->cat1.dst_type = TYPE_F32;

	((struct ir3_instruction **)arr)[idx] = in;
}
Ejemplo n.º 6
0
/* Creates shader:
 *    (sy)(ss)(rpt1)bary.f (ei)r0.z, (r)0, r0.x
 *    (rpt5)nop
 *    sam (f32)(xyzw)r0.x, r0.z, s#0, t#0
 *    (sy)(rpt3)cov.f32f16 hr0.x, (r)r0.x
 *    end
 */
static struct fd3_shader_stateobj *
create_blit_fp(struct pipe_context *pctx)
{
	struct fd3_shader_stateobj *so;
	struct ir3_shader *ir = ir3_shader_create();
	struct ir3_instruction *instr;

	/* (sy)(ss)(rpt1)bary.f (ei)r0.z, (r)0, r0.x */
	instr = ir3_instr_create(ir, 2, OPC_BARY_F);
	instr->flags = IR3_INSTR_SY | IR3_INSTR_SS;
	instr->repeat = 1;

	ir3_reg_create(instr, regid(0,2), IR3_REG_EI);    /* (ei)r0.z */
	ir3_reg_create(instr, 0, IR3_REG_R |              /* (r)0 */
			IR3_REG_IMMED)->iim_val = 0;
	ir3_reg_create(instr, regid(0,0), 0);             /* r0.x */

	/* (rpt5)nop */
	instr = ir3_instr_create(ir, 0, OPC_NOP);
	instr->repeat = 5;

	/* sam (f32)(xyzw)r0.x, r0.z, s#0, t#0 */
	instr = ir3_instr_create(ir, 5, OPC_SAM);
	instr->cat5.samp = 0;
	instr->cat5.tex  = 0;
	instr->cat5.type = TYPE_F32;

	ir3_reg_create(instr, regid(0,0),                 /* (xyzw)r0.x */
			0)->wrmask = 0xf;
	ir3_reg_create(instr, regid(0,2), 0);             /* r0.z */

	/* (sy)(rpt3)cov.f32f16 hr0.x, (r)r0.x */
	instr = ir3_instr_create(ir, 1, 0);  /* mov/cov instructions have no opc */
	instr->flags = IR3_INSTR_SY;
	instr->repeat = 3;
	instr->cat1.src_type = TYPE_F32;
	instr->cat1.dst_type = TYPE_F16;

	ir3_reg_create(instr, regid(0,0), IR3_REG_HALF);  /* hr0.x */
	ir3_reg_create(instr, regid(0,0), IR3_REG_R);     /* (r)r0.x */

	/* end */
	instr = ir3_instr_create(ir, 0, OPC_END);

	so = create_internal_shader(pctx, SHADER_FRAGMENT, ir);
	if (!so)
		return NULL;

	so->color_regid = regid(0,0);
	so->half_precision = true;
	so->inputs_count = 1;
	so->inputs[0].inloc = 8;
	so->inputs[0].compmask = 0x3;
	so->total_in = 2;
	so->samplers_count = 1;

	so->vpsrepl[0] = 0x99999999;
	so->vpsrepl[1] = 0x99999999;
	so->vpsrepl[2] = 0x99999999;
	so->vpsrepl[3] = 0x99999999;

	return so;
}