static void linear_gradient(struct ureg_program *ureg, struct ureg_dst out, struct ureg_src pos, struct ureg_src sampler, struct ureg_src coords, struct ureg_src const0124, struct ureg_src matrow0, struct ureg_src matrow1, struct ureg_src matrow2) { struct ureg_dst temp0 = ureg_DECL_temporary(ureg); struct ureg_dst temp1 = ureg_DECL_temporary(ureg); struct ureg_dst temp2 = ureg_DECL_temporary(ureg); struct ureg_dst temp3 = ureg_DECL_temporary(ureg); struct ureg_dst temp4 = ureg_DECL_temporary(ureg); struct ureg_dst temp5 = ureg_DECL_temporary(ureg); ureg_MOV(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos); ureg_MOV(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_Z), ureg_scalar(const0124, TGSI_SWIZZLE_Y)); ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0)); ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0)); ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0)); ureg_RCP(ureg, temp3, ureg_src(temp3)); ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3)); ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3)); ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X), ureg_src(temp1)); ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y), ureg_src(temp2)); ureg_MUL(ureg, temp0, ureg_scalar(coords, TGSI_SWIZZLE_Y), ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_Y)); ureg_MAD(ureg, temp1, ureg_scalar(coords, TGSI_SWIZZLE_X), ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_X), ureg_src(temp0)); ureg_MUL(ureg, temp2, ureg_src(temp1), ureg_scalar(coords, TGSI_SWIZZLE_Z)); ureg_TEX(ureg, out, TGSI_TEXTURE_1D, ureg_src(temp2), sampler); ureg_release_temporary(ureg, temp0); ureg_release_temporary(ureg, temp1); ureg_release_temporary(ureg, temp2); ureg_release_temporary(ureg, temp3); ureg_release_temporary(ureg, temp4); ureg_release_temporary(ureg, temp5); }
static void * create_frag_shader_rgba(struct vl_compositor *c) { struct ureg_program *shader; struct ureg_src tc, color, sampler; struct ureg_dst texel, fragment; shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); if (!shader) return false; tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR); color = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_COLOR, VS_O_COLOR, TGSI_INTERPOLATE_LINEAR); sampler = ureg_DECL_sampler(shader, 0); texel = ureg_DECL_temporary(shader); fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); /* * fragment = tex(tc, sampler) */ ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler); ureg_MUL(shader, fragment, ureg_src(texel), color); ureg_END(shader); return ureg_create_shader_and_destroy(shader, c->pipe); }
static struct ureg_dst calc_position(struct vl_mc *r, struct ureg_program *shader, struct ureg_src block_scale) { struct ureg_src vrect, vpos; struct ureg_dst t_vpos; struct ureg_dst o_vpos; vrect = ureg_DECL_vs_input(shader, VS_I_RECT); vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); t_vpos = ureg_DECL_temporary(shader); o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); /* * block_scale = (VL_MACROBLOCK_WIDTH, VL_MACROBLOCK_HEIGHT) / (dst.width, dst.height) * * t_vpos = (vpos + vrect) * block_scale * o_vpos.xy = t_vpos * o_vpos.zw = vpos */ ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect); ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), block_scale); ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos)); ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f)); return t_vpos; }
void * util_make_fs_msaa_resolve(struct pipe_context *pipe, enum tgsi_texture_type tgsi_tex, unsigned nr_samples, enum tgsi_return_type stype) { struct ureg_program *ureg; struct ureg_src sampler, coord; struct ureg_dst out, tmp_sum, tmp_coord, tmp; unsigned i; ureg = ureg_create(PIPE_SHADER_FRAGMENT); if (!ureg) return NULL; /* Declarations. */ sampler = ureg_DECL_sampler(ureg, 0); ureg_DECL_sampler_view(ureg, 0, tgsi_tex, stype, stype, stype, stype); coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_LINEAR); out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); tmp_sum = ureg_DECL_temporary(ureg); tmp_coord = ureg_DECL_temporary(ureg); tmp = ureg_DECL_temporary(ureg); /* Instructions. */ ureg_MOV(ureg, tmp_sum, ureg_imm1f(ureg, 0)); ureg_F2U(ureg, tmp_coord, coord); for (i = 0; i < nr_samples; i++) { /* Read one sample. */ ureg_MOV(ureg, ureg_writemask(tmp_coord, TGSI_WRITEMASK_W), ureg_imm1u(ureg, i)); ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord), sampler); if (stype == TGSI_RETURN_TYPE_UINT) ureg_U2F(ureg, tmp, ureg_src(tmp)); else if (stype == TGSI_RETURN_TYPE_SINT) ureg_I2F(ureg, tmp, ureg_src(tmp)); /* Add it to the sum.*/ ureg_ADD(ureg, tmp_sum, ureg_src(tmp_sum), ureg_src(tmp)); } /* Calculate the average and return. */ ureg_MUL(ureg, tmp_sum, ureg_src(tmp_sum), ureg_imm1f(ureg, 1.0 / nr_samples)); if (stype == TGSI_RETURN_TYPE_UINT) ureg_F2U(ureg, out, ureg_src(tmp_sum)); else if (stype == TGSI_RETURN_TYPE_SINT) ureg_F2I(ureg, out, ureg_src(tmp_sum)); else ureg_MOV(ureg, out, ureg_src(tmp_sum)); ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, pipe); }
static INLINE void src_in_mask(struct ureg_program *ureg, struct ureg_dst dst, struct ureg_src src, struct ureg_src mask, unsigned component_alpha, unsigned mask_luminance) { if (component_alpha == FS_CA_FULL) { ureg_MUL(ureg, dst, src, mask); } else if (component_alpha == FS_CA_SRCALPHA) { ureg_MUL(ureg, dst, ureg_scalar(src, TGSI_SWIZZLE_W), mask); } else { if (mask_luminance) ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_X)); else ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_W)); } }
static INLINE void xrender_tex(struct ureg_program *ureg, struct ureg_dst dst, struct ureg_src coords, struct ureg_src sampler, struct ureg_src imm0, boolean repeat_none, boolean swizzle, boolean set_alpha) { if (repeat_none) { struct ureg_dst tmp0 = ureg_DECL_temporary(ureg); struct ureg_dst tmp1 = ureg_DECL_temporary(ureg); ureg_SGT(ureg, tmp1, ureg_swizzle(coords, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y), ureg_scalar(imm0, TGSI_SWIZZLE_X)); ureg_SLT(ureg, tmp0, ureg_swizzle(coords, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y), ureg_scalar(imm0, TGSI_SWIZZLE_W)); ureg_MIN(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1)); ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X), ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y)); ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler); if (swizzle) ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1), TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, TGSI_SWIZZLE_W)); if (set_alpha) ureg_MOV(ureg, ureg_writemask(tmp1, TGSI_WRITEMASK_W), ureg_scalar(imm0, TGSI_SWIZZLE_W)); ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0)); ureg_release_temporary(ureg, tmp0); ureg_release_temporary(ureg, tmp1); } else { if (swizzle) { struct ureg_dst tmp = ureg_DECL_temporary(ureg); ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler); ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp), TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, TGSI_SWIZZLE_W)); ureg_release_temporary(ureg, tmp); } else { ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler); } if (set_alpha) ureg_MOV(ureg, ureg_writemask(dst, TGSI_WRITEMASK_W), ureg_scalar(imm0, TGSI_SWIZZLE_W)); } }
static void * create_yuv_shader(struct pipe_context *pipe, struct ureg_program *ureg) { struct ureg_src y_sampler, u_sampler, v_sampler; struct ureg_src pos; struct ureg_src matrow0, matrow1, matrow2; struct ureg_dst y, u, v, rgb; struct ureg_dst out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); pos = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_PERSPECTIVE); rgb = ureg_DECL_temporary(ureg); y = ureg_DECL_temporary(ureg); u = ureg_DECL_temporary(ureg); v = ureg_DECL_temporary(ureg); y_sampler = ureg_DECL_sampler(ureg, 0); u_sampler = ureg_DECL_sampler(ureg, 1); v_sampler = ureg_DECL_sampler(ureg, 2); matrow0 = ureg_DECL_constant(ureg, 0); matrow1 = ureg_DECL_constant(ureg, 1); matrow2 = ureg_DECL_constant(ureg, 2); ureg_TEX(ureg, y, TGSI_TEXTURE_2D, pos, y_sampler); ureg_TEX(ureg, u, TGSI_TEXTURE_2D, pos, u_sampler); ureg_TEX(ureg, v, TGSI_TEXTURE_2D, pos, v_sampler); ureg_SUB(ureg, u, ureg_src(u), ureg_scalar(matrow0, TGSI_SWIZZLE_W)); ureg_SUB(ureg, v, ureg_src(v), ureg_scalar(matrow0, TGSI_SWIZZLE_W)); ureg_MUL(ureg, rgb, ureg_scalar(ureg_src(y), TGSI_SWIZZLE_X), matrow0); ureg_MAD(ureg, rgb, ureg_scalar(ureg_src(u), TGSI_SWIZZLE_X), matrow1, ureg_src(rgb)); ureg_MAD(ureg, rgb, ureg_scalar(ureg_src(v), TGSI_SWIZZLE_X), matrow2, ureg_src(rgb)); /* rgb.a = 1; */ ureg_MOV(ureg, ureg_writemask(rgb, TGSI_WRITEMASK_W), ureg_scalar(matrow0, TGSI_SWIZZLE_X)); ureg_MOV(ureg, out, ureg_src(rgb)); ureg_release_temporary(ureg, rgb); ureg_release_temporary(ureg, y); ureg_release_temporary(ureg, u); ureg_release_temporary(ureg, v); ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, pipe); }
static void * create_ref_vert_shader(struct vl_mc *r) { struct ureg_program *shader; struct ureg_src mv_scale; struct ureg_src vmv[2]; struct ureg_dst t_vpos; struct ureg_dst o_vmv[2]; unsigned i; shader = ureg_create(TGSI_PROCESSOR_VERTEX); if (!shader) return NULL; vmv[0] = ureg_DECL_vs_input(shader, VS_I_MV_TOP); vmv[1] = ureg_DECL_vs_input(shader, VS_I_MV_BOTTOM); t_vpos = calc_position(r, shader, ureg_imm2f(shader, (float)VL_MACROBLOCK_WIDTH / r->buffer_width, (float)VL_MACROBLOCK_HEIGHT / r->buffer_height) ); o_vmv[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP); o_vmv[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM); /* * mv_scale.xy = 0.5 / (dst.width, dst.height); * mv_scale.z = 1.0f / 4.0f * mv_scale.w = 1.0f / 255.0f * * // Apply motion vectors * o_vmv[0..1].xy = vmv[0..1] * mv_scale + t_vpos * o_vmv[0..1].zw = vmv[0..1] * mv_scale * */ mv_scale = ureg_imm4f(shader, 0.5f / r->buffer_width, 0.5f / r->buffer_height, 1.0f / 4.0f, 1.0f / PIPE_VIDEO_MV_WEIGHT_MAX); for (i = 0; i < 2; ++i) { ureg_MAD(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_XY), mv_scale, vmv[i], ureg_src(t_vpos)); ureg_MUL(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_ZW), mv_scale, vmv[i]); } ureg_release_temporary(shader, t_vpos); ureg_END(shader); return ureg_create_shader_and_destroy(shader, r->pipe); }
void vl_idct_stage2_vert_shader(struct vl_idct *idct, struct ureg_program *shader, unsigned first_output, struct ureg_dst tex) { struct ureg_src vrect, vpos; struct ureg_src scale; struct ureg_dst t_start; struct ureg_dst o_l_addr[2], o_r_addr[2]; vrect = ureg_DECL_vs_input(shader, VS_I_RECT); vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); t_start = ureg_DECL_temporary(shader); --first_output; o_l_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_L_ADDR0); o_l_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_L_ADDR1); o_r_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_R_ADDR0); o_r_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_R_ADDR1); scale = ureg_imm2f(shader, (float)VL_BLOCK_WIDTH / idct->buffer_width, (float)VL_BLOCK_HEIGHT / idct->buffer_height); ureg_MUL(shader, ureg_writemask(tex, TGSI_WRITEMASK_Z), ureg_scalar(vrect, TGSI_SWIZZLE_X), ureg_imm1f(shader, VL_BLOCK_WIDTH / idct->nr_of_render_targets)); ureg_MUL(shader, ureg_writemask(t_start, TGSI_WRITEMASK_XY), vpos, scale); calc_addr(shader, o_l_addr, vrect, ureg_imm1f(shader, 0.0f), false, false, VL_BLOCK_WIDTH / 4); calc_addr(shader, o_r_addr, ureg_src(tex), ureg_src(t_start), true, false, idct->buffer_height / 4); ureg_MOV(shader, ureg_writemask(o_r_addr[0], TGSI_WRITEMASK_Z), ureg_src(tex)); ureg_MOV(shader, ureg_writemask(o_r_addr[1], TGSI_WRITEMASK_Z), ureg_src(tex)); }
static void * create_mismatch_vert_shader(struct vl_idct *idct) { struct ureg_program *shader; struct ureg_src vpos; struct ureg_src scale; struct ureg_dst t_tex; struct ureg_dst o_vpos, o_addr[2]; shader = ureg_create(TGSI_PROCESSOR_VERTEX); if (!shader) return NULL; vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); t_tex = ureg_DECL_temporary(shader); o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); o_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0); o_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1); /* * scale = (VL_BLOCK_WIDTH, VL_BLOCK_HEIGHT) / (dst.width, dst.height) * * t_vpos = vpos + 7 / VL_BLOCK_WIDTH * o_vpos.xy = t_vpos * scale * * o_addr = calc_addr(...) * */ scale = ureg_imm2f(shader, (float)VL_BLOCK_WIDTH / idct->buffer_width, (float)VL_BLOCK_HEIGHT / idct->buffer_height); ureg_MAD(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), vpos, scale, scale); ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f)); ureg_MUL(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), vpos, scale); calc_addr(shader, o_addr, ureg_src(t_tex), ureg_src(t_tex), false, false, idct->buffer_width / 4); ureg_release_temporary(shader, t_tex); ureg_END(shader); return ureg_create_shader_and_destroy(shader, idct->pipe); }
static struct ureg_dst calc_line(struct ureg_program *shader) { struct ureg_dst tmp; struct ureg_src pos; tmp = ureg_DECL_temporary(shader); pos = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS, TGSI_INTERPOLATE_LINEAR); /* * tmp.y = fraction(pos.y / 2) >= 0.5 ? 1 : 0 */ ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), pos, ureg_imm1f(shader, 0.5f)); ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(tmp)); ureg_SGE(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(tmp), ureg_imm1f(shader, 0.5f)); return tmp; }
/** * Translate a SWZ instruction into a MOV, MUL or MAD instruction. EG: * * SWZ dst, src.x-y10 * * becomes: * * MAD dst {1,-1,0,0}, src.xyxx, {0,0,1,0} */ static void emit_swz( struct st_translate *t, struct ureg_dst dst, const struct prog_src_register *SrcReg ) { struct ureg_program *ureg = t->ureg; struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index ); unsigned negate_mask = SrcReg->Negate; unsigned one_mask = ((GET_SWZ(SrcReg->Swizzle, 0) == SWIZZLE_ONE) << 0 | (GET_SWZ(SrcReg->Swizzle, 1) == SWIZZLE_ONE) << 1 | (GET_SWZ(SrcReg->Swizzle, 2) == SWIZZLE_ONE) << 2 | (GET_SWZ(SrcReg->Swizzle, 3) == SWIZZLE_ONE) << 3); unsigned zero_mask = ((GET_SWZ(SrcReg->Swizzle, 0) == SWIZZLE_ZERO) << 0 | (GET_SWZ(SrcReg->Swizzle, 1) == SWIZZLE_ZERO) << 1 | (GET_SWZ(SrcReg->Swizzle, 2) == SWIZZLE_ZERO) << 2 | (GET_SWZ(SrcReg->Swizzle, 3) == SWIZZLE_ZERO) << 3); unsigned negative_one_mask = one_mask & negate_mask; unsigned positive_one_mask = one_mask & ~negate_mask; struct ureg_src imm; unsigned i; unsigned mul_swizzle[4] = {0,0,0,0}; unsigned add_swizzle[4] = {0,0,0,0}; unsigned src_swizzle[4] = {0,0,0,0}; boolean need_add = FALSE; boolean need_mul = FALSE; if (dst.WriteMask == 0) return; /* Is this just a MOV? */ if (zero_mask == 0 && one_mask == 0 && (negate_mask == 0 || negate_mask == TGSI_WRITEMASK_XYZW)) { ureg_MOV( ureg, dst, translate_src( t, SrcReg )); return; } #define IMM_ZERO 0 #define IMM_ONE 1 #define IMM_NEG_ONE 2 imm = ureg_imm3f( ureg, 0, 1, -1 ); for (i = 0; i < 4; i++) { unsigned bit = 1 << i; if (dst.WriteMask & bit) { if (positive_one_mask & bit) { mul_swizzle[i] = IMM_ZERO; add_swizzle[i] = IMM_ONE; need_add = TRUE; } else if (negative_one_mask & bit) { mul_swizzle[i] = IMM_ZERO; add_swizzle[i] = IMM_NEG_ONE; need_add = TRUE; } else if (zero_mask & bit) { mul_swizzle[i] = IMM_ZERO; add_swizzle[i] = IMM_ZERO; need_add = TRUE; } else { add_swizzle[i] = IMM_ZERO; src_swizzle[i] = GET_SWZ(SrcReg->Swizzle, i); need_mul = TRUE; if (negate_mask & bit) { mul_swizzle[i] = IMM_NEG_ONE; } else { mul_swizzle[i] = IMM_ONE; } } } } if (need_mul && need_add) { ureg_MAD( ureg, dst, swizzle_4v( src, src_swizzle ), swizzle_4v( imm, mul_swizzle ), swizzle_4v( imm, add_swizzle ) ); } else if (need_mul) { ureg_MUL( ureg, dst, swizzle_4v( src, src_swizzle ), swizzle_4v( imm, mul_swizzle ) ); } else if (need_add) { ureg_MOV( ureg, dst, swizzle_4v( imm, add_swizzle ) ); } else { debug_assert(0); } #undef IMM_ZERO #undef IMM_ONE #undef IMM_NEG_ONE }
static void * create_deint_frag_shader(struct vl_deint_filter *filter, unsigned field, struct vertex2f *sizes, bool spatial_filter) { struct ureg_program *shader; struct ureg_src i_vtex; struct ureg_src sampler_cur; struct ureg_src sampler_prevprev; struct ureg_src sampler_prev; struct ureg_src sampler_next; struct ureg_dst o_fragment; struct ureg_dst t_tex; struct ureg_dst t_comp_top, t_comp_bot; struct ureg_dst t_diff; struct ureg_dst t_a, t_b; struct ureg_dst t_weave, t_linear; shader = ureg_create(PIPE_SHADER_FRAGMENT); if (!shader) { return NULL; } t_tex = ureg_DECL_temporary(shader); t_comp_top = ureg_DECL_temporary(shader); t_comp_bot = ureg_DECL_temporary(shader); t_diff = ureg_DECL_temporary(shader); t_a = ureg_DECL_temporary(shader); t_b = ureg_DECL_temporary(shader); t_weave = ureg_DECL_temporary(shader); t_linear = ureg_DECL_temporary(shader); i_vtex = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR); sampler_prevprev = ureg_DECL_sampler(shader, 0); sampler_prev = ureg_DECL_sampler(shader, 1); sampler_cur = ureg_DECL_sampler(shader, 2); sampler_next = ureg_DECL_sampler(shader, 3); o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); // we don't care about ZW interpolation (allows better optimization) ureg_MOV(shader, t_tex, i_vtex); ureg_MOV(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 0)); // sample between texels for cheap lowpass ureg_ADD(shader, t_comp_top, ureg_src(t_tex), ureg_imm4f(shader, sizes->x * 0.5f, sizes->y * -0.5f, 0, 0)); ureg_ADD(shader, t_comp_bot, ureg_src(t_tex), ureg_imm4f(shader, sizes->x * -0.5f, sizes->y * 0.5f, 1.0f, 0)); if (field == 0) { /* interpolating top field -> current field is a bottom field */ // cur vs prev2 ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_cur); ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_prevprev); ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_src(t_a), ureg_negate(ureg_src(t_b))); // prev vs next ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_prev); ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_next); ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_Y), ureg_src(t_a), ureg_negate(ureg_src(t_b))); } else { /* interpolating bottom field -> current field is a top field */ // cur vs prev2 ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_cur); ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_prevprev); ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_src(t_a), ureg_negate(ureg_src(t_b))); // prev vs next ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_prev); ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_next); ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_Y), ureg_src(t_a), ureg_negate(ureg_src(t_b))); } // absolute maximum of differences ureg_MAX(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_abs(ureg_src(t_diff)), ureg_scalar(ureg_abs(ureg_src(t_diff)), TGSI_SWIZZLE_Y)); if (field == 0) { /* weave with prev top field */ ureg_TEX(shader, t_weave, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_tex), sampler_prev); /* get linear interpolation from current bottom field */ ureg_ADD(shader, t_comp_top, ureg_src(t_tex), ureg_imm4f(shader, 0, sizes->y * -1.0f, 1.0f, 0)); ureg_TEX(shader, t_linear, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_cur); } else { /* weave with prev bottom field */ ureg_ADD(shader, t_comp_bot, ureg_src(t_tex), ureg_imm4f(shader, 0, 0, 1.0f, 0)); ureg_TEX(shader, t_weave, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_prev); /* get linear interpolation from current top field */ ureg_ADD(shader, t_comp_bot, ureg_src(t_tex), ureg_imm4f(shader, 0, sizes->y * 1.0f, 0, 0)); ureg_TEX(shader, t_linear, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_cur); } // mix between weave and linear // fully weave if diff < 6 (0.02353), fully interpolate if diff > 14 (0.05490) ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_src(t_diff), ureg_imm4f(shader, -0.02353f, 0, 0, 0)); ureg_MUL(shader, ureg_saturate(ureg_writemask(t_diff, TGSI_WRITEMASK_X)), ureg_src(t_diff), ureg_imm4f(shader, 31.8750f, 0, 0, 0)); ureg_LRP(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_X), ureg_src(t_diff), ureg_src(t_linear), ureg_src(t_weave)); ureg_MOV(shader, o_fragment, ureg_scalar(ureg_src(t_tex), TGSI_SWIZZLE_X)); ureg_release_temporary(shader, t_tex); ureg_release_temporary(shader, t_comp_top); ureg_release_temporary(shader, t_comp_bot); ureg_release_temporary(shader, t_diff); ureg_release_temporary(shader, t_a); ureg_release_temporary(shader, t_b); ureg_release_temporary(shader, t_weave); ureg_release_temporary(shader, t_linear); ureg_END(shader); return ureg_create_shader_and_destroy(shader, filter->pipe); }
static void * create_mismatch_frag_shader(struct vl_idct *idct) { struct ureg_program *shader; struct ureg_src addr[2]; struct ureg_dst m[8][2]; struct ureg_dst fragment; unsigned i; shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); if (!shader) return NULL; addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0, TGSI_INTERPOLATE_LINEAR); addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1, TGSI_INTERPOLATE_LINEAR); fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); for (i = 0; i < 8; ++i) { m[i][0] = ureg_DECL_temporary(shader); m[i][1] = ureg_DECL_temporary(shader); } for (i = 0; i < 8; ++i) { increment_addr(shader, m[i], addr, false, false, i, idct->buffer_height); } for (i = 0; i < 8; ++i) { struct ureg_src s_addr[2]; s_addr[0] = ureg_src(m[i][0]); s_addr[1] = ureg_src(m[i][1]); fetch_four(shader, m[i], s_addr, ureg_DECL_sampler(shader, 0), false); } for (i = 1; i < 8; ++i) { ureg_ADD(shader, m[0][0], ureg_src(m[0][0]), ureg_src(m[i][0])); ureg_ADD(shader, m[0][1], ureg_src(m[0][1]), ureg_src(m[i][1])); } ureg_ADD(shader, m[0][0], ureg_src(m[0][0]), ureg_src(m[0][1])); ureg_DP4(shader, m[0][0], ureg_abs(ureg_src(m[0][0])), ureg_imm1f(shader, 1 << 14)); ureg_MUL(shader, ureg_writemask(m[0][0], TGSI_WRITEMASK_W), ureg_abs(ureg_src(m[7][1])), ureg_imm1f(shader, 1 << 14)); ureg_FRC(shader, m[0][0], ureg_src(m[0][0])); ureg_SGT(shader, m[0][0], ureg_imm1f(shader, 0.5f), ureg_abs(ureg_src(m[0][0]))); ureg_CMP(shader, ureg_writemask(m[0][0], TGSI_WRITEMASK_W), ureg_negate(ureg_src(m[0][0])), ureg_imm1f(shader, 1.0f / (1 << 15)), ureg_imm1f(shader, -1.0f / (1 << 15))); ureg_MUL(shader, ureg_writemask(m[0][0], TGSI_WRITEMASK_W), ureg_src(m[0][0]), ureg_scalar(ureg_src(m[0][0]), TGSI_SWIZZLE_X)); ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), ureg_src(m[7][1])); ureg_ADD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_src(m[0][0]), ureg_src(m[7][1])); for (i = 0; i < 8; ++i) { ureg_release_temporary(shader, m[i][0]); ureg_release_temporary(shader, m[i][1]); } ureg_END(shader); return ureg_create_shader_and_destroy(shader, idct->pipe); }
void * util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe, enum tgsi_texture_type tgsi_tex, unsigned nr_samples, enum tgsi_return_type stype) { struct ureg_program *ureg; struct ureg_src sampler, coord; struct ureg_dst out, tmp, top, bottom; struct ureg_dst tmp_coord[4], tmp_sum[4]; unsigned i, c; ureg = ureg_create(PIPE_SHADER_FRAGMENT); if (!ureg) return NULL; /* Declarations. */ sampler = ureg_DECL_sampler(ureg, 0); ureg_DECL_sampler_view(ureg, 0, tgsi_tex, stype, stype, stype, stype); coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_LINEAR); out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); for (c = 0; c < 4; c++) tmp_sum[c] = ureg_DECL_temporary(ureg); for (c = 0; c < 4; c++) tmp_coord[c] = ureg_DECL_temporary(ureg); tmp = ureg_DECL_temporary(ureg); top = ureg_DECL_temporary(ureg); bottom = ureg_DECL_temporary(ureg); /* Instructions. */ for (c = 0; c < 4; c++) ureg_MOV(ureg, tmp_sum[c], ureg_imm1f(ureg, 0)); /* Get 4 texture coordinates for the bilinear filter. */ ureg_F2U(ureg, tmp_coord[0], coord); /* top-left */ ureg_UADD(ureg, tmp_coord[1], ureg_src(tmp_coord[0]), ureg_imm4u(ureg, 1, 0, 0, 0)); /* top-right */ ureg_UADD(ureg, tmp_coord[2], ureg_src(tmp_coord[0]), ureg_imm4u(ureg, 0, 1, 0, 0)); /* bottom-left */ ureg_UADD(ureg, tmp_coord[3], ureg_src(tmp_coord[0]), ureg_imm4u(ureg, 1, 1, 0, 0)); /* bottom-right */ for (i = 0; i < nr_samples; i++) { for (c = 0; c < 4; c++) { /* Read one sample. */ ureg_MOV(ureg, ureg_writemask(tmp_coord[c], TGSI_WRITEMASK_W), ureg_imm1u(ureg, i)); ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord[c]), sampler); if (stype == TGSI_RETURN_TYPE_UINT) ureg_U2F(ureg, tmp, ureg_src(tmp)); else if (stype == TGSI_RETURN_TYPE_SINT) ureg_I2F(ureg, tmp, ureg_src(tmp)); /* Add it to the sum.*/ ureg_ADD(ureg, tmp_sum[c], ureg_src(tmp_sum[c]), ureg_src(tmp)); } } /* Calculate the average. */ for (c = 0; c < 4; c++) ureg_MUL(ureg, tmp_sum[c], ureg_src(tmp_sum[c]), ureg_imm1f(ureg, 1.0 / nr_samples)); /* Take the 4 average values and apply a standard bilinear filter. */ ureg_FRC(ureg, tmp, coord); ureg_LRP(ureg, top, ureg_scalar(ureg_src(tmp), 0), ureg_src(tmp_sum[1]), ureg_src(tmp_sum[0])); ureg_LRP(ureg, bottom, ureg_scalar(ureg_src(tmp), 0), ureg_src(tmp_sum[3]), ureg_src(tmp_sum[2])); ureg_LRP(ureg, tmp, ureg_scalar(ureg_src(tmp), 1), ureg_src(bottom), ureg_src(top)); /* Convert to the texture format and return. */ if (stype == TGSI_RETURN_TYPE_UINT) ureg_F2U(ureg, out, ureg_src(tmp)); else if (stype == TGSI_RETURN_TYPE_SINT) ureg_F2I(ureg, out, ureg_src(tmp)); else ureg_MOV(ureg, out, ureg_src(tmp)); ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, pipe); }
static void * create_vert_shader(struct vl_compositor *c) { struct ureg_program *shader; struct ureg_src vpos, vtex, color; struct ureg_dst tmp; struct ureg_dst o_vpos, o_vtex, o_color; struct ureg_dst o_vtop, o_vbottom; shader = ureg_create(TGSI_PROCESSOR_VERTEX); if (!shader) return false; vpos = ureg_DECL_vs_input(shader, 0); vtex = ureg_DECL_vs_input(shader, 1); color = ureg_DECL_vs_input(shader, 2); tmp = ureg_DECL_temporary(shader); o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); o_color = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, VS_O_COLOR); o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX); o_vtop = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP); o_vbottom = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM); /* * o_vpos = vpos * o_vtex = vtex * o_color = color */ ureg_MOV(shader, o_vpos, vpos); ureg_MOV(shader, o_vtex, vtex); ureg_MOV(shader, o_color, color); /* * tmp.x = vtex.w / 2 * tmp.y = vtex.w / 4 * * o_vtop.x = vtex.x * o_vtop.y = vtex.y * tmp.x + 0.25f * o_vtop.z = vtex.y * tmp.y + 0.25f * o_vtop.w = 1 / tmp.x * * o_vbottom.x = vtex.x * o_vbottom.y = vtex.y * tmp.x - 0.25f * o_vbottom.z = vtex.y * tmp.y - 0.25f * o_vbottom.w = 1 / tmp.y */ ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_scalar(vtex, TGSI_SWIZZLE_W), ureg_imm1f(shader, 0.5f)); ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_scalar(vtex, TGSI_SWIZZLE_W), ureg_imm1f(shader, 0.25f)); ureg_MOV(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_X), vtex); ureg_MAD(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_Y), ureg_scalar(vtex, TGSI_SWIZZLE_Y), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_imm1f(shader, 0.25f)); ureg_MAD(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_Z), ureg_scalar(vtex, TGSI_SWIZZLE_Y), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), ureg_imm1f(shader, 0.25f)); ureg_RCP(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_W), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X)); ureg_MOV(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_X), vtex); ureg_MAD(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_Y), ureg_scalar(vtex, TGSI_SWIZZLE_Y), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_imm1f(shader, -0.25f)); ureg_MAD(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_Z), ureg_scalar(vtex, TGSI_SWIZZLE_Y), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), ureg_imm1f(shader, -0.25f)); ureg_RCP(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_W), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y)); ureg_END(shader); return ureg_create_shader_and_destroy(shader, c->pipe); }
static void * create_ref_frag_shader(struct vl_mc *r) { const float y_scale = r->buffer_height / 2 * r->macroblock_size / VL_MACROBLOCK_HEIGHT; struct ureg_program *shader; struct ureg_src tc[2], sampler; struct ureg_dst ref, field; struct ureg_dst fragment; unsigned label; shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); if (!shader) return NULL; tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR); tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR); sampler = ureg_DECL_sampler(shader, 0); ref = ureg_DECL_temporary(shader); fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); field = calc_line(shader); /* * ref = field.z ? tc[1] : tc[0] * * // Adjust tc acording to top/bottom field selection * if (|ref.z|) { * ref.y *= y_scale * ref.y = floor(ref.y) * ref.y += ref.z * ref.y /= y_scale * } * fragment.xyz = tex(ref, sampler[0]) */ ureg_CMP(shader, ureg_writemask(ref, TGSI_WRITEMASK_XYZ), ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), tc[1], tc[0]); ureg_CMP(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), tc[1], tc[0]); ureg_IF(shader, ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z), &label); ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), ureg_src(ref), ureg_imm1f(shader, y_scale)); ureg_FLR(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), ureg_src(ref)); ureg_ADD(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), ureg_src(ref), ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z)); ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), ureg_src(ref), ureg_imm1f(shader, 1.0f / y_scale)); ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); ureg_ENDIF(shader); ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), TGSI_TEXTURE_2D, ureg_src(ref), sampler); ureg_release_temporary(shader, ref); ureg_release_temporary(shader, field); ureg_END(shader); return ureg_create_shader_and_destroy(shader, r->pipe); }
static void * create_ycbcr_vert_shader(struct vl_mc *r, vl_mc_ycbcr_vert_shader vs_callback, void *callback_priv) { struct ureg_program *shader; struct ureg_src vrect, vpos; struct ureg_dst t_vpos, t_vtex; struct ureg_dst o_vpos, o_flags; struct vertex2f scale = { (float)VL_BLOCK_WIDTH / r->buffer_width * VL_MACROBLOCK_WIDTH / r->macroblock_size, (float)VL_BLOCK_HEIGHT / r->buffer_height * VL_MACROBLOCK_HEIGHT / r->macroblock_size }; unsigned label; shader = ureg_create(TGSI_PROCESSOR_VERTEX); if (!shader) return NULL; vrect = ureg_DECL_vs_input(shader, VS_I_RECT); vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); t_vpos = calc_position(r, shader, ureg_imm2f(shader, scale.x, scale.y)); t_vtex = ureg_DECL_temporary(shader); o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); o_flags = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_FLAGS); /* * o_vtex.xy = t_vpos * o_flags.z = intra * 0.5 * * if(interlaced) { * t_vtex.xy = vrect.y ? { 0, scale.y } : { -scale.y : 0 } * t_vtex.z = vpos.y % 2 * t_vtex.y = t_vtex.z ? t_vtex.x : t_vtex.y * o_vpos.y = t_vtex.y + t_vpos.y * * o_flags.w = t_vtex.z ? 0 : 1 * } * */ vs_callback(callback_priv, r, shader, VS_O_VTEX, t_vpos); ureg_MUL(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_Z), ureg_scalar(vpos, TGSI_SWIZZLE_Z), ureg_imm1f(shader, 0.5f)); ureg_MOV(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_W), ureg_imm1f(shader, -1.0f)); if (r->macroblock_size == VL_MACROBLOCK_HEIGHT) { //TODO ureg_IF(shader, ureg_scalar(vpos, TGSI_SWIZZLE_W), &label); ureg_CMP(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_XY), ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_Y)), ureg_imm2f(shader, 0.0f, scale.y), ureg_imm2f(shader, -scale.y, 0.0f)); ureg_MUL(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Z), ureg_scalar(vpos, TGSI_SWIZZLE_Y), ureg_imm1f(shader, 0.5f)); ureg_FRC(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Z), ureg_src(t_vtex)); ureg_CMP(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y), ureg_negate(ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Z)), ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_X), ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Y)); ureg_ADD(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_Y), ureg_src(t_vpos), ureg_src(t_vtex)); ureg_CMP(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_W), ureg_negate(ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Z)), ureg_imm1f(shader, 0.0f), ureg_imm1f(shader, 1.0f)); ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); ureg_ENDIF(shader); } ureg_release_temporary(shader, t_vtex); ureg_release_temporary(shader, t_vpos); ureg_END(shader); return ureg_create_shader_and_destroy(shader, r->pipe); }
static void * create_frag_shader_weave(struct vl_compositor *c) { struct ureg_program *shader; struct ureg_src i_tc[2]; struct ureg_src csc[3]; struct ureg_src sampler[3]; struct ureg_dst t_tc[2]; struct ureg_dst t_texel[2]; struct ureg_dst o_fragment; unsigned i, j; shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); if (!shader) return false; i_tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR); i_tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR); for (i = 0; i < 3; ++i) { csc[i] = ureg_DECL_constant(shader, i); sampler[i] = ureg_DECL_sampler(shader, i); } for (i = 0; i < 2; ++i) { t_tc[i] = ureg_DECL_temporary(shader); t_texel[i] = ureg_DECL_temporary(shader); } o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); /* calculate the texture offsets * t_tc.x = i_tc.x * t_tc.y = (round(i_tc.y) + 0.5) / height * 2 */ for (i = 0; i < 2; ++i) { ureg_MOV(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_X), i_tc[i]); ureg_ROUND(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_YZ), i_tc[i]); ureg_MOV(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_W), ureg_imm1f(shader, i ? 0.75f : 0.25f)); ureg_ADD(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_YZ), ureg_src(t_tc[i]), ureg_imm1f(shader, 0.5f)); ureg_MUL(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_Y), ureg_src(t_tc[i]), ureg_scalar(i_tc[0], TGSI_SWIZZLE_W)); ureg_MUL(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_Z), ureg_src(t_tc[i]), ureg_scalar(i_tc[1], TGSI_SWIZZLE_W)); } /* fetch the texels * texel[0..1].x = tex(t_tc[0..1][0]) * texel[0..1].y = tex(t_tc[0..1][1]) * texel[0..1].z = tex(t_tc[0..1][2]) */ for (i = 0; i < 2; ++i) for (j = 0; j < 3; ++j) { struct ureg_src src = ureg_swizzle(ureg_src(t_tc[i]), TGSI_SWIZZLE_X, j ? TGSI_SWIZZLE_Z : TGSI_SWIZZLE_Y, TGSI_SWIZZLE_W, TGSI_SWIZZLE_W); ureg_TEX(shader, ureg_writemask(t_texel[i], TGSI_WRITEMASK_X << j), TGSI_TEXTURE_3D, src, sampler[j]); } /* calculate linear interpolation factor * factor = |round(i_tc.y) - i_tc.y| * 2 */ ureg_ROUND(shader, ureg_writemask(t_tc[0], TGSI_WRITEMASK_YZ), i_tc[0]); ureg_ADD(shader, ureg_writemask(t_tc[0], TGSI_WRITEMASK_YZ), ureg_src(t_tc[0]), ureg_negate(i_tc[0])); ureg_MUL(shader, ureg_writemask(t_tc[0], TGSI_WRITEMASK_XY), ureg_abs(ureg_src(t_tc[0])), ureg_imm1f(shader, 2.0f)); ureg_LRP(shader, t_texel[0], ureg_swizzle(ureg_src(t_tc[0]), TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z), ureg_src(t_texel[1]), ureg_src(t_texel[0])); /* and finally do colour space transformation * fragment = csc * texel */ ureg_MOV(shader, ureg_writemask(t_texel[0], TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f)); for (i = 0; i < 3; ++i) ureg_DP4(shader, ureg_writemask(o_fragment, TGSI_WRITEMASK_X << i), csc[i], ureg_src(t_texel[0])); ureg_MOV(shader, ureg_writemask(o_fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f)); for (i = 0; i < 2; ++i) { ureg_release_temporary(shader, t_texel[i]); ureg_release_temporary(shader, t_tc[i]); } ureg_END(shader); return ureg_create_shader_and_destroy(shader, c->pipe); }
static void * create_vert_shader(struct vl_zscan *zscan) { struct ureg_program *shader; struct ureg_src scale; struct ureg_src vrect, vpos, block_num; struct ureg_dst tmp; struct ureg_dst o_vpos; struct ureg_dst *o_vtex; unsigned i; shader = ureg_create(PIPE_SHADER_VERTEX); if (!shader) return NULL; o_vtex = MALLOC(zscan->num_channels * sizeof(struct ureg_dst)); scale = ureg_imm2f(shader, (float)VL_BLOCK_WIDTH / zscan->buffer_width, (float)VL_BLOCK_HEIGHT / zscan->buffer_height); vrect = ureg_DECL_vs_input(shader, VS_I_RECT); vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); block_num = ureg_DECL_vs_input(shader, VS_I_BLOCK_NUM); tmp = ureg_DECL_temporary(shader); o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); for (i = 0; i < zscan->num_channels; ++i) o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX + i); /* * o_vpos.xy = (vpos + vrect) * scale * o_vpos.zw = 1.0f * * tmp.xy = InstanceID / blocks_per_line * tmp.x = frac(tmp.x) * tmp.y = floor(tmp.y) * * o_vtex.x = vrect.x / blocks_per_line + tmp.x * o_vtex.y = vrect.y * o_vtex.z = tmp.z * blocks_per_line / blocks_total */ ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XY), vpos, vrect); ureg_MUL(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(tmp), scale); ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f)); ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XW), ureg_scalar(block_num, TGSI_SWIZZLE_X), ureg_imm1f(shader, 1.0f / zscan->blocks_per_line)); ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X)); ureg_FLR(shader, ureg_writemask(tmp, TGSI_WRITEMASK_W), ureg_src(tmp)); for (i = 0; i < zscan->num_channels; ++i) { ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), ureg_imm1f(shader, 1.0f / (zscan->blocks_per_line * VL_BLOCK_WIDTH) * (i - (signed)zscan->num_channels / 2))); ureg_MAD(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_X), vrect, ureg_imm1f(shader, 1.0f / zscan->blocks_per_line), ureg_src(tmp)); ureg_MOV(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_Y), vrect); ureg_MOV(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_Z), vpos); ureg_MUL(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_W), ureg_src(tmp), ureg_imm1f(shader, (float)zscan->blocks_per_line / zscan->blocks_total)); } ureg_release_temporary(shader, tmp); ureg_END(shader); FREE(o_vtex); return ureg_create_shader_and_destroy(shader, zscan->pipe); }
static void * create_frag_shader(struct vl_zscan *zscan) { struct ureg_program *shader; struct ureg_src *vtex; struct ureg_src samp_src, samp_scan, samp_quant; struct ureg_dst *tmp; struct ureg_dst quant, fragment; unsigned i; shader = ureg_create(PIPE_SHADER_FRAGMENT); if (!shader) return NULL; vtex = MALLOC(zscan->num_channels * sizeof(struct ureg_src)); tmp = MALLOC(zscan->num_channels * sizeof(struct ureg_dst)); for (i = 0; i < zscan->num_channels; ++i) vtex[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX + i, TGSI_INTERPOLATE_LINEAR); samp_src = ureg_DECL_sampler(shader, 0); samp_scan = ureg_DECL_sampler(shader, 1); samp_quant = ureg_DECL_sampler(shader, 2); for (i = 0; i < zscan->num_channels; ++i) tmp[i] = ureg_DECL_temporary(shader); quant = ureg_DECL_temporary(shader); fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); /* * tmp.x = tex(vtex, 1) * tmp.y = vtex.z * fragment = tex(tmp, 0) * quant */ for (i = 0; i < zscan->num_channels; ++i) ureg_TEX(shader, ureg_writemask(tmp[i], TGSI_WRITEMASK_X), TGSI_TEXTURE_2D, vtex[i], samp_scan); for (i = 0; i < zscan->num_channels; ++i) ureg_MOV(shader, ureg_writemask(tmp[i], TGSI_WRITEMASK_Y), ureg_scalar(vtex[i], TGSI_SWIZZLE_W)); for (i = 0; i < zscan->num_channels; ++i) { ureg_TEX(shader, ureg_writemask(tmp[0], TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D, ureg_src(tmp[i]), samp_src); ureg_TEX(shader, ureg_writemask(quant, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_3D, vtex[i], samp_quant); } ureg_MUL(shader, quant, ureg_src(quant), ureg_imm1f(shader, 16.0f)); ureg_MUL(shader, fragment, ureg_src(tmp[0]), ureg_src(quant)); for (i = 0; i < zscan->num_channels; ++i) ureg_release_temporary(shader, tmp[i]); ureg_END(shader); FREE(vtex); FREE(tmp); return ureg_create_shader_and_destroy(shader, zscan->pipe); }
static void * create_ycbcr_frag_shader(struct vl_mc *r, float scale, bool invert, vl_mc_ycbcr_frag_shader fs_callback, void *callback_priv) { struct ureg_program *shader; struct ureg_src flags; struct ureg_dst tmp; struct ureg_dst fragment; unsigned label; shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); if (!shader) return NULL; flags = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_FLAGS, TGSI_INTERPOLATE_LINEAR); fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); tmp = calc_line(shader); /* * if (field == tc.w) * kill(); * else { * fragment.xyz = tex(tc, sampler) * scale + tc.z * fragment.w = 1.0f * } */ ureg_SEQ(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_scalar(flags, TGSI_SWIZZLE_W), ureg_src(tmp)); ureg_IF(shader, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), &label); ureg_KILP(shader); ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); ureg_ELSE(shader, &label); fs_callback(callback_priv, r, shader, VS_O_VTEX, tmp); if (scale != 1.0f) ureg_MAD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), ureg_src(tmp), ureg_imm1f(shader, scale), ureg_scalar(flags, TGSI_SWIZZLE_Z)); else ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), ureg_src(tmp), ureg_scalar(flags, TGSI_SWIZZLE_Z)); ureg_MUL(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), ureg_src(tmp), ureg_imm1f(shader, invert ? -1.0f : 1.0f)); ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f)); ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); ureg_ENDIF(shader); ureg_release_temporary(shader, tmp); ureg_END(shader); return ureg_create_shader_and_destroy(shader, r->pipe); }