static void * create_copy_frag_shader(struct vl_deint_filter *filter, unsigned field) { struct ureg_program *shader; struct ureg_src i_vtex; struct ureg_src sampler; struct ureg_dst o_fragment; struct ureg_dst t_tex; shader = ureg_create(PIPE_SHADER_FRAGMENT); if (!shader) { return NULL; } t_tex = ureg_DECL_temporary(shader); i_vtex = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR); sampler = ureg_DECL_sampler(shader, 2); o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); ureg_MOV(shader, t_tex, i_vtex); if (field) { ureg_MOV(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_ZW), ureg_imm4f(shader, 0, 0, 1.0f, 0)); } else { ureg_MOV(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 0)); } ureg_TEX(shader, o_fragment, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_tex), sampler); ureg_release_temporary(shader, t_tex); ureg_END(shader); return ureg_create_shader_and_destroy(shader, filter->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; }
/** * Create a simple vertex shader that passes through position and the given * attribute. */ static void *create_passthrough_vs(struct pipe_context *pipe, int semantic_name) { struct ureg_program *ureg; struct ureg_src src[2], constants[3]; struct ureg_dst dst[2], tmp; int i; ureg = ureg_create(TGSI_PROCESSOR_VERTEX); if (!ureg) return NULL; /* position is in user coordinates */ src[0] = ureg_DECL_vs_input(ureg, 0); dst[0] = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); tmp = ureg_DECL_temporary(ureg); for (i = 0; i < Elements(constants); i++) constants[i] = ureg_DECL_constant(ureg, i); /* transform to clipped coordinates */ ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), src[0], constants[0]); ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Y), src[0], constants[1]); ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Z), src[0]); ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W), src[0], constants[2]); ureg_MOV(ureg, dst[0], ureg_src(tmp)); if (semantic_name >= 0) { src[1] = ureg_DECL_vs_input(ureg, 1); dst[1] = ureg_DECL_output(ureg, semantic_name, 0); ureg_MOV(ureg, dst[1], src[1]); } ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, pipe); }
void * st_pbo_create_vs(struct st_context *st) { struct pipe_screen *pscreen = st->pipe->screen; bool use_nir = PIPE_SHADER_IR_NIR == pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_PREFERRED_IR); if (use_nir) { unsigned inputs[] = { VERT_ATTRIB_POS, SYSTEM_VALUE_INSTANCE_ID, }; unsigned outputs[] = { VARYING_SLOT_POS, VARYING_SLOT_LAYER }; return st_nir_make_passthrough_shader(st, "st/pbo VS", MESA_SHADER_VERTEX, st->pbo.layers ? 2 : 1, inputs, outputs, NULL, (1 << 1)); } struct ureg_program *ureg; struct ureg_src in_pos; struct ureg_src in_instanceid; struct ureg_dst out_pos; struct ureg_dst out_layer; ureg = ureg_create(PIPE_SHADER_VERTEX); if (!ureg) return NULL; in_pos = ureg_DECL_vs_input(ureg, TGSI_SEMANTIC_POSITION); out_pos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); if (st->pbo.layers) { in_instanceid = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0); if (!st->pbo.use_gs) out_layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0); } /* out_pos = in_pos */ ureg_MOV(ureg, out_pos, in_pos); if (st->pbo.layers) { if (st->pbo.use_gs) { /* out_pos.z = i2f(gl_InstanceID) */ ureg_I2F(ureg, ureg_writemask(out_pos, TGSI_WRITEMASK_Z), ureg_scalar(in_instanceid, TGSI_SWIZZLE_X)); } else { /* out_layer = gl_InstanceID */ ureg_MOV(ureg, ureg_writemask(out_layer, TGSI_WRITEMASK_X), ureg_scalar(in_instanceid, TGSI_SWIZZLE_X)); } } ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, st->pipe); }
/** * Make a simple fragment texture shader which reads the texture unit 0 and 1 * and writes it as depth and stencil, respectively. */ void * util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe, unsigned tex_target, unsigned interp_mode, bool load_level_zero, bool use_txf) { struct ureg_program *ureg; struct ureg_src depth_sampler, stencil_sampler; struct ureg_src tex; struct ureg_dst out, depth, stencil; struct ureg_src imm; ureg = ureg_create( PIPE_SHADER_FRAGMENT ); if (!ureg) return NULL; depth_sampler = ureg_DECL_sampler( ureg, 0 ); ureg_DECL_sampler_view(ureg, 0, tex_target, TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT); stencil_sampler = ureg_DECL_sampler( ureg, 1 ); ureg_DECL_sampler_view(ureg, 0, tex_target, TGSI_RETURN_TYPE_UINT, TGSI_RETURN_TYPE_UINT, TGSI_RETURN_TYPE_UINT, TGSI_RETURN_TYPE_UINT); tex = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_GENERIC, 0, interp_mode ); out = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ); depth = ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ); stencil = ureg_DECL_output( ureg, TGSI_SEMANTIC_STENCIL, 0 ); imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); ureg_MOV( ureg, out, imm ); ureg_load_tex(ureg, ureg_writemask(depth, TGSI_WRITEMASK_Z), tex, depth_sampler, tex_target, load_level_zero, use_txf); ureg_load_tex(ureg, ureg_writemask(stencil, TGSI_WRITEMASK_Y), tex, stencil_sampler, tex_target, load_level_zero, use_txf); ureg_END( ureg ); return ureg_create_shader_and_destroy( ureg, pipe ); }
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_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); }
static void * create_frag_shader(struct vl_matrix_filter *filter, unsigned num_offsets, struct vertex2f *offsets, const float *matrix_values) { struct ureg_program *shader; struct ureg_src i_vtex; struct ureg_src sampler; struct ureg_dst tmp; struct ureg_dst t_sum; struct ureg_dst o_fragment; unsigned i; shader = ureg_create(PIPE_SHADER_FRAGMENT); if (!shader) { return NULL; } i_vtex = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR); sampler = ureg_DECL_sampler(shader, 0); ureg_DECL_sampler_view(shader, 0, TGSI_TEXTURE_2D, TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT); tmp = ureg_DECL_temporary(shader); t_sum = ureg_DECL_temporary(shader); o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); ureg_MOV(shader, t_sum, ureg_imm1f(shader, 0.0f)); for (i = 0; i < num_offsets; ++i) { if (matrix_values[i] == 0.0f) continue; if (!is_vec_zero(offsets[i])) { ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XY), i_vtex, ureg_imm2f(shader, offsets[i].x, offsets[i].y)); ureg_MOV(shader, ureg_writemask(tmp, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 0.0f)); ureg_TEX(shader, tmp, TGSI_TEXTURE_2D, ureg_src(tmp), sampler); } else { ureg_TEX(shader, tmp, TGSI_TEXTURE_2D, i_vtex, sampler); } ureg_MAD(shader, t_sum, ureg_src(tmp), ureg_imm1f(shader, matrix_values[i]), ureg_src(t_sum)); } ureg_MOV(shader, o_fragment, ureg_src(t_sum)); ureg_END(shader); return ureg_create_shader_and_destroy(shader, filter->pipe); }
/** * Compile one arithmetic operation COLOR&ALPHA pair into TGSI instructions. */ static void compile_instruction(struct st_translate *t, const struct atifs_instruction *inst) { unsigned optype; for (optype = 0; optype < 2; optype++) { /* color, alpha */ const struct instruction_desc *desc; struct ureg_dst dst[1]; struct ureg_src args[3]; /* arguments for the main operation */ unsigned arg; unsigned dstreg = inst->DstReg[optype].Index - GL_REG_0_ATI; if (!inst->Opcode[optype]) continue; desc = &inst_desc[inst->Opcode[optype] - GL_MOV_ATI]; /* prepare the arguments */ for (arg = 0; arg < desc->arg_count; arg++) { if (arg >= inst->ArgCount[optype]) { _mesa_warning(0, "Using 0 for missing argument %d of %s\n", arg, desc->name); args[arg] = ureg_imm1f(t->ureg, 0.0f); } else { args[arg] = prepare_argument(t, arg, &inst->SrcReg[optype][arg]); } } /* prepare dst */ dst[0] = get_temp(t, dstreg); if (optype) { dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_W); } else { GLuint dstMask = inst->DstReg[optype].dstMask; if (dstMask == GL_NONE) { dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XYZ); } else { dst[0] = ureg_writemask(dst[0], dstMask); /* the enum values match */ } } /* emit the main instruction */ emit_arith_inst(t, desc, dst, args, arg); emit_dstmod(t, *dst, inst->DstReg[optype].dstMod); t->regs_written[t->current_pass][dstreg] = true; } }
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_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 void * create_frag_shader_palette(struct vl_compositor *c, bool include_cc) { struct ureg_program *shader; struct ureg_src csc[3]; struct ureg_src tc; struct ureg_src sampler; struct ureg_src palette; struct ureg_dst texel; struct ureg_dst fragment; unsigned i; shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); if (!shader) return false; for (i = 0; include_cc && i < 3; ++i) csc[i] = ureg_DECL_constant(shader, i); tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR); sampler = ureg_DECL_sampler(shader, 0); palette = ureg_DECL_sampler(shader, 1); texel = ureg_DECL_temporary(shader); fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); /* * texel = tex(tc, sampler) * fragment.xyz = tex(texel, palette) * csc * fragment.a = texel.a */ ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler); ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_src(texel)); if (include_cc) { ureg_TEX(shader, texel, TGSI_TEXTURE_1D, ureg_src(texel), palette); for (i = 0; i < 3; ++i) ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i], ureg_src(texel)); } else { ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), TGSI_TEXTURE_1D, ureg_src(texel), palette); } ureg_release_temporary(shader, texel); ureg_END(shader); return ureg_create_shader_and_destroy(shader, c->pipe); }
/** * Make a simple fragment texture shader which reads the texture unit 0 and 1 * and writes it as depth and stencil, respectively. */ void * util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe, unsigned tex_target, unsigned interp_mode) { struct ureg_program *ureg; struct ureg_src depth_sampler, stencil_sampler; struct ureg_src tex; struct ureg_dst out, depth, stencil; struct ureg_src imm; ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); if (ureg == NULL) return NULL; depth_sampler = ureg_DECL_sampler( ureg, 0 ); stencil_sampler = ureg_DECL_sampler( ureg, 1 ); tex = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_GENERIC, 0, interp_mode ); out = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ); depth = ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ); stencil = ureg_DECL_output( ureg, TGSI_SEMANTIC_STENCIL, 0 ); imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); ureg_MOV( ureg, out, imm ); ureg_TEX( ureg, ureg_writemask(depth, TGSI_WRITEMASK_Z), tex_target, tex, depth_sampler ); ureg_TEX( ureg, ureg_writemask(stencil, TGSI_WRITEMASK_Y), tex_target, tex, stencil_sampler ); ureg_END( ureg ); return ureg_create_shader_and_destroy( ureg, pipe ); }
static void * fd_prog_blit(struct pipe_context *pctx, int rts, bool depth) { int i; struct ureg_src tc; struct ureg_program *ureg; debug_assert(rts <= MAX_RENDER_TARGETS); ureg = ureg_create(PIPE_SHADER_FRAGMENT); if (!ureg) return NULL; tc = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_PERSPECTIVE); for (i = 0; i < rts; i++) ureg_TEX(ureg, ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, i), TGSI_TEXTURE_2D, tc, ureg_DECL_sampler(ureg, i)); if (depth) ureg_TEX(ureg, ureg_writemask( ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0), TGSI_WRITEMASK_Z), TGSI_TEXTURE_2D, tc, ureg_DECL_sampler(ureg, rts)); ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, pctx); }
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 void increment_addr(struct ureg_program *shader, struct ureg_dst daddr[2], struct ureg_src saddr[2], bool right_side, bool transposed, int pos, float size) { unsigned wm_start = (right_side == transposed) ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_Y; unsigned wm_tc = (right_side == transposed) ? TGSI_WRITEMASK_Y : TGSI_WRITEMASK_X; /* * daddr[0..1].(start) = saddr[0..1].(start) * daddr[0..1].(tc) = saddr[0..1].(tc) */ ureg_MOV(shader, ureg_writemask(daddr[0], wm_start), saddr[0]); ureg_ADD(shader, ureg_writemask(daddr[0], wm_tc), saddr[0], ureg_imm1f(shader, pos / size)); ureg_MOV(shader, ureg_writemask(daddr[1], wm_start), saddr[1]); ureg_ADD(shader, ureg_writemask(daddr[1], wm_tc), saddr[1], ureg_imm1f(shader, pos / size)); }
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 matrix_mul(struct ureg_program *shader, struct ureg_dst dst, struct ureg_dst l[2], struct ureg_dst r[2]) { struct ureg_dst tmp; tmp = ureg_DECL_temporary(shader); /* * tmp.xy = dot4(m[0][0..1], m[1][0..1]) * dst = tmp.x + tmp.y */ ureg_DP4(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_src(l[0]), ureg_src(r[0])); ureg_DP4(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(l[1]), ureg_src(r[1])); ureg_ADD(shader, dst, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y)); ureg_release_temporary(shader, tmp); }
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; }
static void * create_frag_shader_video_buffer(struct vl_compositor *c) { struct ureg_program *shader; struct ureg_src tc; struct ureg_src csc[3]; struct ureg_src sampler[3]; struct ureg_dst texel; struct ureg_dst fragment; unsigned i; 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); for (i = 0; i < 3; ++i) { csc[i] = ureg_DECL_constant(shader, i); sampler[i] = ureg_DECL_sampler(shader, i); } texel = ureg_DECL_temporary(shader); fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); /* * texel.xyz = tex(tc, sampler[i]) * fragment = csc * texel */ for (i = 0; i < 3; ++i) ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_3D, tc, sampler[i]); ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f)); for (i = 0; i < 3; ++i) ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i], ureg_src(texel)); ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f)); ureg_release_temporary(shader, texel); ureg_END(shader); return ureg_create_shader_and_destroy(shader, c->pipe); }
static void calc_addr(struct ureg_program *shader, struct ureg_dst addr[2], struct ureg_src tc, struct ureg_src start, bool right_side, bool transposed, float size) { unsigned wm_start = (right_side == transposed) ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_Y; unsigned sw_start = right_side ? TGSI_SWIZZLE_Y : TGSI_SWIZZLE_X; unsigned wm_tc = (right_side == transposed) ? TGSI_WRITEMASK_Y : TGSI_WRITEMASK_X; unsigned sw_tc = right_side ? TGSI_SWIZZLE_X : TGSI_SWIZZLE_Y; /* * addr[0..1].(start) = right_side ? start.x : tc.x * addr[0..1].(tc) = right_side ? tc.y : start.y * addr[0..1].z = tc.z * addr[1].(start) += 1.0f / scale */ ureg_MOV(shader, ureg_writemask(addr[0], wm_start), ureg_scalar(start, sw_start)); ureg_MOV(shader, ureg_writemask(addr[0], wm_tc), ureg_scalar(tc, sw_tc)); ureg_ADD(shader, ureg_writemask(addr[1], wm_start), ureg_scalar(start, sw_start), ureg_imm1f(shader, 1.0f / size)); ureg_MOV(shader, ureg_writemask(addr[1], wm_tc), ureg_scalar(tc, sw_tc)); }
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)); }
/** * Create a simple fragment shader that sets the depth to 0.0f. */ static void *create_scissor_fs(struct pipe_context *pipe) { struct ureg_program *ureg; struct ureg_dst out; struct ureg_src imm; ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); out = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); imm = ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 0.0f); ureg_MOV(ureg, ureg_writemask(out, TGSI_WRITEMASK_Z), imm); ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, pipe); }
void * st_pbo_create_gs(struct st_context *st) { static const int zero = 0; struct ureg_program *ureg; struct ureg_dst out_pos; struct ureg_dst out_layer; struct ureg_src in_pos; struct ureg_src imm; unsigned i; ureg = ureg_create(PIPE_SHADER_GEOMETRY); if (!ureg) return NULL; ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, PIPE_PRIM_TRIANGLES); ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, PIPE_PRIM_TRIANGLE_STRIP); ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, 3); out_pos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); out_layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0); in_pos = ureg_DECL_input(ureg, TGSI_SEMANTIC_POSITION, 0, 0, 1); imm = ureg_DECL_immediate_int(ureg, &zero, 1); for (i = 0; i < 3; ++i) { struct ureg_src in_pos_vertex = ureg_src_dimension(in_pos, i); /* out_pos = in_pos[i] */ ureg_MOV(ureg, out_pos, in_pos_vertex); /* out_layer.x = f2i(in_pos[i].z) */ ureg_F2I(ureg, ureg_writemask(out_layer, TGSI_WRITEMASK_X), ureg_scalar(in_pos_vertex, TGSI_SWIZZLE_Z)); ureg_EMIT(ureg, ureg_scalar(imm, TGSI_SWIZZLE_X)); } ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, st->pipe); }
/** * Create a TGSI ureg_dst register from a Mesa dest register. */ static struct ureg_dst translate_dst( struct st_translate *t, const struct prog_dst_register *DstReg, boolean saturate, boolean clamp_color) { struct ureg_dst dst = dst_register( t, DstReg->File, DstReg->Index ); dst = ureg_writemask( dst, DstReg->WriteMask ); if (saturate) dst = ureg_saturate( dst ); else if (clamp_color && DstReg->File == PROGRAM_OUTPUT) { /* Clamp colors for ARB_color_buffer_float. */ switch (t->procType) { case TGSI_PROCESSOR_VERTEX: /* This can only occur with a compatibility profile, which doesn't * support geometry shaders. */ if (DstReg->Index == VARYING_SLOT_COL0 || DstReg->Index == VARYING_SLOT_COL1 || DstReg->Index == VARYING_SLOT_BFC0 || DstReg->Index == VARYING_SLOT_BFC1) { dst = ureg_saturate(dst); } break; case TGSI_PROCESSOR_FRAGMENT: if (DstReg->Index >= FRAG_RESULT_COLOR) { dst = ureg_saturate(dst); } break; } } if (DstReg->RelAddr) dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) ); return dst; }
/** * Create a TGSI ureg_dst register from a Mesa dest register. */ static struct ureg_dst translate_dst( struct st_translate *t, const struct prog_dst_register *DstReg, boolean saturate, boolean clamp_color) { struct ureg_dst dst = dst_register( t, DstReg->File, DstReg->Index ); dst = ureg_writemask( dst, DstReg->WriteMask ); if (saturate) dst = ureg_saturate( dst ); else if (clamp_color && DstReg->File == PROGRAM_OUTPUT) { /* Clamp colors for ARB_color_buffer_float. */ switch (t->procType) { case TGSI_PROCESSOR_VERTEX: /* XXX if the geometry shader is present, this must be done there * instead of here. */ if (DstReg->Index == VARYING_SLOT_COL0 || DstReg->Index == VARYING_SLOT_COL1 || DstReg->Index == VARYING_SLOT_BFC0 || DstReg->Index == VARYING_SLOT_BFC1) { dst = ureg_saturate(dst); } break; case TGSI_PROCESSOR_FRAGMENT: if (DstReg->Index >= FRAG_RESULT_COLOR) { dst = ureg_saturate(dst); } break; } } if (DstReg->RelAddr) dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) ); return dst; }
void * st_pbo_create_vs(struct st_context *st) { struct ureg_program *ureg; struct ureg_src in_pos; struct ureg_src in_instanceid; struct ureg_dst out_pos; struct ureg_dst out_layer; ureg = ureg_create(PIPE_SHADER_VERTEX); if (!ureg) return NULL; in_pos = ureg_DECL_vs_input(ureg, TGSI_SEMANTIC_POSITION); out_pos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); if (st->pbo.layers) { in_instanceid = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0); if (!st->pbo.use_gs) out_layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0); } /* out_pos = in_pos */ ureg_MOV(ureg, out_pos, in_pos); if (st->pbo.layers) { if (st->pbo.use_gs) { /* out_pos.z = i2f(gl_InstanceID) */ ureg_I2F(ureg, ureg_writemask(out_pos, TGSI_WRITEMASK_Z), ureg_scalar(in_instanceid, TGSI_SWIZZLE_X)); } else { /* out_layer = gl_InstanceID */ ureg_MOV(ureg, out_layer, in_instanceid); } } ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, st->pipe); }
static void mc_vert_shader_callback(void *priv, struct vl_mc *mc, struct ureg_program *shader, unsigned first_output, struct ureg_dst tex) { struct vl_mpeg12_decoder *dec = priv; struct ureg_dst o_vtex; assert(priv && mc); assert(shader); if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) { struct vl_idct *idct = mc == &dec->mc_y ? &dec->idct_y : &dec->idct_c; vl_idct_stage2_vert_shader(idct, shader, first_output, tex); } else { o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output); ureg_MOV(shader, ureg_writemask(o_vtex, TGSI_WRITEMASK_XY), ureg_src(tex)); } }
/** * Create a TGSI ureg_dst register from a Mesa dest register. */ static struct ureg_dst translate_dst( struct st_translate *t, const struct prog_dst_register *DstReg, boolean saturate) { struct ureg_dst dst = dst_register( t, DstReg->File, DstReg->Index ); dst = ureg_writemask( dst, DstReg->WriteMask ); if (saturate) dst = ureg_saturate( dst ); if (DstReg->RelAddr) dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) ); return dst; }
/** * Make simple fragment texture shader: * IMM {0,0,0,1} // (if writemask != 0xf) * MOV OUT[0], IMM[0] // (if writemask != 0xf) * TEX OUT[0].writemask, IN[0], SAMP[0], 2D; * END; * * \param tex_target one of PIPE_TEXTURE_x * \parma interp_mode either TGSI_INTERPOLATE_LINEAR or PERSPECTIVE * \param writemask mask of TGSI_WRITEMASK_x */ void * util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, unsigned tex_target, unsigned interp_mode, unsigned writemask ) { struct ureg_program *ureg; struct ureg_src sampler; struct ureg_src tex; struct ureg_dst out; assert(interp_mode == TGSI_INTERPOLATE_LINEAR || interp_mode == TGSI_INTERPOLATE_PERSPECTIVE); ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); if (ureg == NULL) return NULL; sampler = ureg_DECL_sampler( ureg, 0 ); tex = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_GENERIC, 0, interp_mode ); out = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ); if (writemask != TGSI_WRITEMASK_XYZW) { struct ureg_src imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); ureg_MOV( ureg, out, imm ); } ureg_TEX( ureg, ureg_writemask(out, writemask), tex_target, tex, sampler ); ureg_END( ureg ); return ureg_create_shader_and_destroy( ureg, pipe ); }