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(TGSI_PROCESSOR_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); }
/** * Make a fragment shader that copies the input color to N output colors. */ void * util_make_fragment_clonecolor_shader(struct pipe_context *pipe, int num_cbufs) { struct ureg_program *ureg; struct ureg_src src; struct ureg_dst dst[PIPE_MAX_COLOR_BUFS]; int i; assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); if (ureg == NULL) return NULL; src = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_COLOR, 0, TGSI_INTERPOLATE_PERSPECTIVE ); for (i = 0; i < num_cbufs; i++) dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i ); for (i = 0; i < num_cbufs; i++) ureg_MOV( ureg, dst[i], src ); ureg_END( ureg ); return ureg_create_shader_and_destroy( ureg, pipe ); }
/** * Make a fragment shader that copies the input color to N output colors. */ void * util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, int input_semantic, int input_interpolate) { struct ureg_program *ureg; struct ureg_src src; struct ureg_dst dst[PIPE_MAX_COLOR_BUFS]; int i; assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); ureg = ureg_create( PIPE_SHADER_FRAGMENT ); if (!ureg) return NULL; src = ureg_DECL_fs_input( ureg, input_semantic, 0, input_interpolate ); for (i = 0; i < num_cbufs; i++) dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i ); for (i = 0; i < num_cbufs; i++) ureg_MOV( ureg, dst[i], src ); ureg_END( ureg ); return ureg_create_shader_and_destroy( ureg, 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_vertex_passthrough_shader_with_so(struct pipe_context *pipe, uint num_attribs, const uint *semantic_names, const uint *semantic_indexes, bool window_space, const struct pipe_stream_output_info *so) { struct ureg_program *ureg; uint i; ureg = ureg_create( PIPE_SHADER_VERTEX ); if (!ureg) return NULL; if (window_space) ureg_property(ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, TRUE); for (i = 0; i < num_attribs; i++) { struct ureg_src src; struct ureg_dst dst; src = ureg_DECL_vs_input( ureg, i ); dst = ureg_DECL_output( ureg, semantic_names[i], semantic_indexes[i]); ureg_MOV( ureg, dst, src ); } ureg_END( ureg ); return ureg_create_shader_with_so_and_destroy( ureg, pipe, so ); }
void * util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, uint num_attribs, const uint *semantic_names, const uint *semantic_indexes, const struct pipe_stream_output_info *so) { struct ureg_program *ureg; uint i; ureg = ureg_create( TGSI_PROCESSOR_VERTEX ); if (ureg == NULL) return NULL; for (i = 0; i < num_attribs; i++) { struct ureg_src src; struct ureg_dst dst; src = ureg_DECL_vs_input( ureg, i ); dst = ureg_DECL_output( ureg, semantic_names[i], semantic_indexes[i]); ureg_MOV( ureg, dst, src ); } ureg_END( ureg ); return ureg_create_shader_with_so_and_destroy( ureg, pipe, so ); }
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); }
/** * If we fail to compile a fragment shader (because it uses too many * registers, for example) we'll use a dummy/fallback shader that * simply emits a constant color (red for debug, black for release). * We hit this with the Unigine/Heaven demo when Shaders = High. * With black, the demo still looks good. */ static const struct tgsi_token * get_dummy_fragment_shader(void) { #ifdef DEBUG static const float color[4] = { 1.0, 0.0, 0.0, 0.0 }; /* red */ #else static const float color[4] = { 0.0, 0.0, 0.0, 0.0 }; /* black */ #endif struct ureg_program *ureg; const struct tgsi_token *tokens; struct ureg_src src; struct ureg_dst dst; unsigned num_tokens; ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); if (!ureg) return NULL; dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); src = ureg_DECL_immediate(ureg, color, 4); ureg_MOV(ureg, dst, src); ureg_END(ureg); tokens = ureg_get_tokens(ureg, &num_tokens); ureg_destroy(ureg); return tokens; }
/** * If we fail to compile a vertex shader we'll use a dummy/fallback shader * that simply emits a (0,0,0,1) vertex position. */ static const struct tgsi_token * get_dummy_vertex_shader(void) { static const float zero[4] = { 0.0, 0.0, 0.0, 1.0 }; struct ureg_program *ureg; const struct tgsi_token *tokens; struct ureg_src src; struct ureg_dst dst; unsigned num_tokens; ureg = ureg_create(TGSI_PROCESSOR_VERTEX); if (!ureg) return NULL; dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); src = ureg_DECL_immediate(ureg, zero, 4); ureg_MOV(ureg, dst, src); ureg_END(ureg); tokens = ureg_get_tokens(ureg, &num_tokens); ureg_destroy(ureg); return tokens; }
/** * Make a simple fragment texture shader which reads a texture and writes it * as stencil. */ void * util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe, unsigned tex_target, unsigned interp_mode, bool load_level_zero, bool use_txf) { struct ureg_program *ureg; struct ureg_src stencil_sampler; struct ureg_src tex; struct ureg_dst out, stencil; struct ureg_src imm; ureg = ureg_create( PIPE_SHADER_FRAGMENT ); if (!ureg) return NULL; stencil_sampler = ureg_DECL_sampler( ureg, 0 ); 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 ); 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(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 ); }
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 * 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); }
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); }
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 * 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); }
/** * Make a simple fragment texture shader which reads a texture and writes it * as stencil. */ void * util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe, unsigned tex_target, unsigned interp_mode) { struct ureg_program *ureg; struct ureg_src stencil_sampler; struct ureg_src tex; struct ureg_dst out, stencil; struct ureg_src imm; ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); if (ureg == NULL) return NULL; stencil_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 ); 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(stencil, TGSI_WRITEMASK_Y), tex_target, tex, stencil_sampler ); ureg_END( ureg ); return ureg_create_shader_and_destroy( ureg, pipe ); }
static void * create_vert_shader(struct vl_deint_filter *filter) { struct ureg_program *shader; struct ureg_src i_vpos; struct ureg_dst o_vpos, o_vtex; shader = ureg_create(PIPE_SHADER_VERTEX); if (!shader) return NULL; i_vpos = ureg_DECL_vs_input(shader, 0); o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX); ureg_MOV(shader, o_vpos, i_vpos); ureg_MOV(shader, o_vtex, i_vpos); ureg_END(shader); return ureg_create_shader_and_destroy(shader, filter->pipe); }
/** * This is used when TCS is NULL in the VS->TCS->TES chain. In this case, * VS passes its outputs to TES directly, so the fixed-function shader only * has to write TESSOUTER and TESSINNER. */ void *si_create_fixed_func_tcs(struct si_context *sctx) { struct ureg_src outer, inner; struct ureg_dst tessouter, tessinner; struct ureg_program *ureg = ureg_create(PIPE_SHADER_TESS_CTRL); if (!ureg) return NULL; outer = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_DEFAULT_TESSOUTER_SI, 0); inner = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_DEFAULT_TESSINNER_SI, 0); tessouter = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSOUTER, 0); tessinner = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSINNER, 0); ureg_MOV(ureg, tessouter, outer); ureg_MOV(ureg, tessinner, inner); ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, &sctx->b); }
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)); }
void * util_make_geometry_passthrough_shader(struct pipe_context *pipe, uint num_attribs, const ubyte *semantic_names, const ubyte *semantic_indexes) { static const unsigned zero[4] = {0, 0, 0, 0}; struct ureg_program *ureg; struct ureg_dst dst[PIPE_MAX_SHADER_OUTPUTS]; struct ureg_src src[PIPE_MAX_SHADER_INPUTS]; 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_POINTS); ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, PIPE_PRIM_POINTS); ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, 1); ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS, 1); imm = ureg_DECL_immediate_uint(ureg, zero, 4); /** * Loop over all the attribs and declare the corresponding * declarations in the geometry shader */ for (i = 0; i < num_attribs; i++) { src[i] = ureg_DECL_input(ureg, semantic_names[i], semantic_indexes[i], 0, 1); src[i] = ureg_src_dimension(src[i], 0); dst[i] = ureg_DECL_output(ureg, semantic_names[i], semantic_indexes[i]); } /* MOV dst[i] src[i] */ for (i = 0; i < num_attribs; i++) { ureg_MOV(ureg, dst[i], src[i]); } /* EMIT IMM[0] */ ureg_insn(ureg, TGSI_OPCODE_EMIT, NULL, 0, &imm, 1, 0); /* END */ ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, pipe); }
/** * Create a simple fragment shader that sets the color to white. */ static void *create_white_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_COLOR, 0); imm = ureg_imm4f(ureg, 1.0f, 1.0f, 1.0f, 1.0f); ureg_MOV(ureg, out, imm); ureg_END(ureg); return ureg_create_shader_and_destroy(ureg, pipe); }
/** * 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); }
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); }
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 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)); } }
/** * 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 ); }
static void r300_dummy_fragment_shader( struct r300_context* r300, struct r300_fragment_shader_code* shader) { struct pipe_shader_state state; struct ureg_program *ureg; struct ureg_dst out; struct ureg_src imm; /* Make a simple fragment shader which outputs (0, 0, 0, 1) */ ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); imm = ureg_imm4f(ureg, 0, 0, 0, 1); ureg_MOV(ureg, out, imm); ureg_END(ureg); state.tokens = ureg_finalize(ureg); shader->dummy = TRUE; r300_translate_fragment_shader(r300, shader, state.tokens); ureg_destroy(ureg); }
static void r300_dummy_vertex_shader( struct r300_context* r300, struct r300_vertex_shader* shader) { struct ureg_program *ureg; struct ureg_dst dst; struct ureg_src imm; /* Make a simple vertex shader which outputs (0, 0, 0, 1), * effectively rendering nothing. */ ureg = ureg_create(TGSI_PROCESSOR_VERTEX); dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); imm = ureg_imm4f(ureg, 0, 0, 0, 1); ureg_MOV(ureg, dst, imm); ureg_END(ureg); shader->state.tokens = tgsi_dup_tokens(ureg_finalize(ureg)); ureg_destroy(ureg); shader->dummy = TRUE; r300_init_vs_outputs(r300, shader); r300_translate_vertex_shader(r300, shader); }
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); }
/** * Translate Mesa program to TGSI format. * \param program the program to translate * \param numInputs number of input registers used * \param inputMapping maps Mesa fragment program inputs to TGSI generic * input indexes * \param inputSemanticName the TGSI_SEMANTIC flag for each input * \param inputSemanticIndex the semantic index (ex: which texcoord) for * each input * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input * \param numOutputs number of output registers used * \param outputMapping maps Mesa fragment program outputs to TGSI * generic outputs * \param outputSemanticName the TGSI_SEMANTIC flag for each output * \param outputSemanticIndex the semantic index (ex: which texcoord) for * each output * * \return PIPE_OK or PIPE_ERROR_OUT_OF_MEMORY */ enum pipe_error st_translate_mesa_program( struct gl_context *ctx, uint procType, struct ureg_program *ureg, const struct gl_program *program, GLuint numInputs, const GLuint inputMapping[], const ubyte inputSemanticName[], const ubyte inputSemanticIndex[], const GLuint interpMode[], GLuint numOutputs, const GLuint outputMapping[], const ubyte outputSemanticName[], const ubyte outputSemanticIndex[], boolean passthrough_edgeflags, boolean clamp_color) { struct st_translate translate, *t; unsigned i; enum pipe_error ret = PIPE_OK; assert(numInputs <= ARRAY_SIZE(t->inputs)); assert(numOutputs <= ARRAY_SIZE(t->outputs)); t = &translate; memset(t, 0, sizeof *t); t->procType = procType; t->inputMapping = inputMapping; t->outputMapping = outputMapping; t->ureg = ureg; /*_mesa_print_program(program);*/ /* * Declare input attributes. */ if (procType == TGSI_PROCESSOR_FRAGMENT) { for (i = 0; i < numInputs; i++) { t->inputs[i] = ureg_DECL_fs_input(ureg, inputSemanticName[i], inputSemanticIndex[i], interpMode[i]); } if (program->InputsRead & VARYING_BIT_POS) { /* Must do this after setting up t->inputs, and before * emitting constant references, below: */ emit_wpos(st_context(ctx), t, program, ureg); } if (program->InputsRead & VARYING_BIT_FACE) { emit_face_var( t, program ); } /* * Declare output attributes. */ for (i = 0; i < numOutputs; i++) { switch (outputSemanticName[i]) { case TGSI_SEMANTIC_POSITION: t->outputs[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, /* Z / Depth */ outputSemanticIndex[i] ); t->outputs[i] = ureg_writemask( t->outputs[i], TGSI_WRITEMASK_Z ); break; case TGSI_SEMANTIC_STENCIL: t->outputs[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_STENCIL, /* Stencil */ outputSemanticIndex[i] ); t->outputs[i] = ureg_writemask( t->outputs[i], TGSI_WRITEMASK_Y ); break; case TGSI_SEMANTIC_COLOR: t->outputs[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, outputSemanticIndex[i] ); break; default: debug_assert(0); return 0; } } } else if (procType == TGSI_PROCESSOR_GEOMETRY) { for (i = 0; i < numInputs; i++) { t->inputs[i] = ureg_DECL_input(ureg, inputSemanticName[i], inputSemanticIndex[i], 0, 1); } for (i = 0; i < numOutputs; i++) { t->outputs[i] = ureg_DECL_output( ureg, outputSemanticName[i], outputSemanticIndex[i] ); } } else { assert(procType == TGSI_PROCESSOR_VERTEX); for (i = 0; i < numInputs; i++) { t->inputs[i] = ureg_DECL_vs_input(ureg, i); } for (i = 0; i < numOutputs; i++) { t->outputs[i] = ureg_DECL_output( ureg, outputSemanticName[i], outputSemanticIndex[i] ); if (outputSemanticName[i] == TGSI_SEMANTIC_FOG) { /* force register to contain a fog coordinate in the form (F, 0, 0, 1). */ ureg_MOV(ureg, ureg_writemask(t->outputs[i], TGSI_WRITEMASK_YZW), ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 1.0f)); t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_X); } } if (passthrough_edgeflags) emit_edgeflags( t, program ); } /* Declare address register. */ if (program->NumAddressRegs > 0) { debug_assert( program->NumAddressRegs == 1 ); t->address[0] = ureg_DECL_address( ureg ); } /* Declare misc input registers */ { GLbitfield sysInputs = program->SystemValuesRead; unsigned numSys = 0; for (i = 0; sysInputs; i++) { if (sysInputs & (1 << i)) { unsigned semName = _mesa_sysval_to_semantic[i]; t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0); if (semName == TGSI_SEMANTIC_INSTANCEID || semName == TGSI_SEMANTIC_VERTEXID) { /* From Gallium perspective, these system values are always * integer, and require native integer support. However, if * native integer is supported on the vertex stage but not the * pixel stage (e.g, i915g + draw), Mesa will generate IR that * assumes these system values are floats. To resolve the * inconsistency, we insert a U2F. */ struct st_context *st = st_context(ctx); struct pipe_screen *pscreen = st->pipe->screen; assert(procType == TGSI_PROCESSOR_VERTEX); assert(pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS)); (void) pscreen; /* silence non-debug build warnings */ if (!ctx->Const.NativeIntegers) { struct ureg_dst temp = ureg_DECL_local_temporary(t->ureg); ureg_U2F( t->ureg, ureg_writemask(temp, TGSI_WRITEMASK_X), t->systemValues[i]); t->systemValues[i] = ureg_scalar(ureg_src(temp), 0); } } numSys++; sysInputs &= ~(1 << i); } } } if (program->IndirectRegisterFiles & (1 << PROGRAM_TEMPORARY)) { /* If temps are accessed with indirect addressing, declare temporaries * in sequential order. Else, we declare them on demand elsewhere. */ for (i = 0; i < program->NumTemporaries; i++) { /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */ t->temps[i] = ureg_DECL_temporary( t->ureg ); } } /* Emit constants and immediates. Mesa uses a single index space * for these, so we put all the translated regs in t->constants. */ if (program->Parameters) { t->constants = calloc( program->Parameters->NumParameters, sizeof t->constants[0] ); if (t->constants == NULL) { ret = PIPE_ERROR_OUT_OF_MEMORY; goto out; } for (i = 0; i < program->Parameters->NumParameters; i++) { switch (program->Parameters->Parameters[i].Type) { case PROGRAM_STATE_VAR: case PROGRAM_UNIFORM: t->constants[i] = ureg_DECL_constant( ureg, i ); break; /* Emit immediates only when there's no indirect addressing of * the const buffer. * FIXME: Be smarter and recognize param arrays: * indirect addressing is only valid within the referenced * array. */ case PROGRAM_CONSTANT: if (program->IndirectRegisterFiles & PROGRAM_ANY_CONST) t->constants[i] = ureg_DECL_constant( ureg, i ); else t->constants[i] = ureg_DECL_immediate( ureg, (const float*) program->Parameters->ParameterValues[i], 4 ); break; default: break; } } } /* texture samplers */ for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) { if (program->SamplersUsed & (1 << i)) { t->samplers[i] = ureg_DECL_sampler( ureg, i ); } } /* Emit each instruction in turn: */ for (i = 0; i < program->NumInstructions; i++) { set_insn_start( t, ureg_get_instruction_number( ureg )); compile_instruction( ctx, t, &program->Instructions[i], clamp_color ); } /* Fix up all emitted labels: */ for (i = 0; i < t->labels_count; i++) { ureg_fixup_label( ureg, t->labels[i].token, t->insn[t->labels[i].branch_target] ); } out: free(t->insn); free(t->labels); free(t->constants); if (t->error) { debug_printf("%s: translate error flag set\n", __func__); } return ret; }