/* Creates shader: * EXEC ADDR(0x3) CNT(0x1) * (S)FETCH: VERTEX R1.xyz1 = R0.x FMT_32_32_32_FLOAT * UNSIGNED STRIDE(12) CONST(26, 0) * ALLOC POSITION SIZE(0x0) * EXEC ADDR(0x4) CNT(0x1) * ALU: MAXv export62 = R1, R1 ; gl_Position * ALLOC PARAM/PIXEL SIZE(0x0) * EXEC_END ADDR(0x5) CNT(0x0) */ static struct fd2_shader_stateobj * create_solid_vp(void) { struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX); struct ir2_cf *cf; struct ir2_instruction *instr; if (!so) return NULL; so->ir = ir2_shader_create(); cf = ir2_cf_create(so->ir, EXEC); instr = ir2_instr_create_vtx_fetch(cf, 26, 0, FMT_32_32_32_FLOAT, false, 12); ir2_reg_create(instr, 1, "xyz1", 0); ir2_reg_create(instr, 0, "x", 0); cf = ir2_cf_create_alloc(so->ir, SQ_POSITION, 0); cf = ir2_cf_create(so->ir, EXEC); instr = ir2_instr_create_alu(cf, MAXv, ~0); ir2_reg_create(instr, 62, NULL, IR2_REG_EXPORT); ir2_reg_create(instr, 1, NULL, 0); ir2_reg_create(instr, 1, NULL, 0); cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0); cf = ir2_cf_create(so->ir, EXEC_END); return assemble(so); }
/* Creates shader: * EXEC ADDR(0x2) CNT(0x1) * (S)FETCH: SAMPLE R0.xyzw = R0.xyx CONST(0) LOCATION(CENTER) * ALLOC PARAM/PIXEL SIZE(0x0) * EXEC_END ADDR(0x3) CNT(0x1) * ALU: MAXv export0 = R0, R0 ; gl_FragColor * NOP */ static struct fd2_shader_stateobj * create_blit_fp(void) { struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT); struct ir2_cf *cf; struct ir2_instruction *instr; if (!so) return NULL; so->ir = ir2_shader_create(); cf = ir2_cf_create(so->ir, EXEC); instr = ir2_instr_create_tex_fetch(cf, 0); ir2_reg_create(instr, 0, "xyzw", 0); ir2_reg_create(instr, 0, "xyx", 0); instr->sync = true; cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0); cf = ir2_cf_create(so->ir, EXEC_END); instr = ir2_instr_create_alu(cf, MAXv, ~0); ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT); ir2_reg_create(instr, 0, NULL, 0); ir2_reg_create(instr, 0, NULL, 0); return assemble(so); }
static struct ir2_cf * next_exec_cf(struct fd2_compile_context *ctx) { struct ir2_cf *cf = ctx->cf; if (!cf || cf->exec.instrs_count >= ARRAY_SIZE(ctx->cf->exec.instrs)) ctx->cf = cf = ir2_cf_create(ctx->so->ir, EXEC); return cf; }
void * ir2_shader_assemble(struct ir2_shader *shader, struct ir2_shader_info *info) { uint32_t i, j; uint32_t *ptr, *dwords = NULL; uint32_t idx = 0; int ret; info->sizedwords = 0; info->max_reg = -1; info->max_input_reg = 0; info->regs_written = 0; /* we need an even # of CF's.. insert a NOP if needed */ if (shader->cfs_count != align(shader->cfs_count, 2)) ir2_cf_create(shader, NOP); /* first pass, resolve sizes and addresses: */ ret = shader_resolve(shader, info); if (ret) { ERROR_MSG("resolve failed: %d", ret); goto fail; } ptr = dwords = calloc(4, info->sizedwords); /* second pass, emit CF program in pairs: */ for (i = 0; i < shader->cfs_count; i += 2) { instr_cf_t *cfs = (instr_cf_t *)ptr; ret = cf_emit(shader->cfs[i], &cfs[0]); if (ret) { ERROR_MSG("CF emit failed: %d\n", ret); goto fail; } ret = cf_emit(shader->cfs[i+1], &cfs[1]); if (ret) { ERROR_MSG("CF emit failed: %d\n", ret); goto fail; } ptr += 3; assert((ptr - dwords) <= info->sizedwords); } /* third pass, emit ALU/FETCH: */ for (i = 0; i < shader->cfs_count; i++) { struct ir2_cf *cf = shader->cfs[i]; if ((cf->cf_type == EXEC) || (cf->cf_type == EXEC_END)) { for (j = 0; j < cf->exec.instrs_count; j++) { ret = instr_emit(cf->exec.instrs[j], ptr, idx++, info); if (ret) { ERROR_MSG("instruction emit failed: %d", ret); goto fail; } ptr += 3; assert((ptr - dwords) <= info->sizedwords); } } } return dwords; fail: free(dwords); return NULL; }