diff options
Diffstat (limited to 'src/gallium/state_trackers/xorg/xorg_exa_tgsi.c')
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa_tgsi.c | 176 |
1 files changed, 124 insertions, 52 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c index cfee10c3b3..83cc12fea9 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c @@ -44,33 +44,29 @@ */ struct xorg_shaders { - struct exa_context *exa; + struct xorg_renderer *r; struct cso_hash *vs_hash; struct cso_hash *fs_hash; }; -static const char over_op[] = - "SUB TEMP[3], CONST[0].wwww, TEMP[1].wwww\n" - "MUL TEMP[3], TEMP[0], TEMP[3]\n" - "ADD TEMP[0], TEMP[3], TEMP[0]\n"; - - -static INLINE void -create_preamble(struct ureg_program *ureg) -{ -} - - static INLINE void src_in_mask(struct ureg_program *ureg, struct ureg_dst dst, struct ureg_src src, - struct ureg_src mask) + struct ureg_src mask, + int component_alpha) { - /* MUL dst, src, mask.wwww */ - ureg_MUL(ureg, dst, src, - ureg_scalar(mask, TGSI_SWIZZLE_W)); + 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 { + ureg_MUL(ureg, dst, src, + ureg_scalar(mask, TGSI_SWIZZLE_X)); + } } static struct ureg_src @@ -79,8 +75,7 @@ vs_normalize_coords(struct ureg_program *ureg, struct ureg_src coords, { struct ureg_dst tmp = ureg_DECL_temporary(ureg); struct ureg_src ret; - ureg_MUL(ureg, tmp, coords, const0); - ureg_ADD(ureg, tmp, ureg_src(tmp), const1); + ureg_MAD(ureg, tmp, coords, const0, const1); ret = ureg_src(tmp); ureg_release_temporary(ureg, tmp); return ret; @@ -241,42 +236,46 @@ create_vs(struct pipe_context *pipe, boolean is_fill = vs_traits & VS_FILL; boolean is_composite = vs_traits & VS_COMPOSITE; boolean has_mask = vs_traits & VS_MASK; + boolean is_yuv = vs_traits & VS_YUV; + unsigned input_slot = 0; ureg = ureg_create(TGSI_PROCESSOR_VERTEX); if (ureg == NULL) return 0; - const0 = ureg_DECL_constant(ureg); - const1 = ureg_DECL_constant(ureg); + const0 = ureg_DECL_constant(ureg, 0); + const1 = ureg_DECL_constant(ureg, 1); /* it has to be either a fill or a composite op */ - debug_assert(is_fill ^ is_composite); + debug_assert((is_fill ^ is_composite) ^ is_yuv); - src = ureg_DECL_vs_input(ureg, - TGSI_SEMANTIC_POSITION, 0); + src = ureg_DECL_vs_input(ureg, input_slot++); dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); src = vs_normalize_coords(ureg, src, const0, const1); ureg_MOV(ureg, dst, src); + if (is_yuv) { + src = ureg_DECL_vs_input(ureg, input_slot++); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); + ureg_MOV(ureg, dst, src); + } if (is_composite) { - src = ureg_DECL_vs_input(ureg, - TGSI_SEMANTIC_GENERIC, 1); - dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1); + src = ureg_DECL_vs_input(ureg, input_slot++); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); ureg_MOV(ureg, dst, src); } + if (is_fill) { - src = ureg_DECL_vs_input(ureg, - TGSI_SEMANTIC_COLOR, 1); - dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 1); + src = ureg_DECL_vs_input(ureg, input_slot++); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); ureg_MOV(ureg, dst, src); } if (has_mask) { - src = ureg_DECL_vs_input(ureg, - TGSI_SEMANTIC_GENERIC, 2); - dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 2); + src = ureg_DECL_vs_input(ureg, input_slot++); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1); ureg_MOV(ureg, dst, src); } @@ -286,6 +285,75 @@ create_vs(struct pipe_context *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); +} + +static void * create_fs(struct pipe_context *pipe, unsigned fs_traits) { @@ -300,13 +368,15 @@ create_fs(struct pipe_context *pipe, boolean is_solid = fs_traits & FS_SOLID_FILL; boolean is_lingrad = fs_traits & FS_LINGRAD_FILL; boolean is_radgrad = fs_traits & FS_RADGRAD_FILL; + unsigned comp_alpha = fs_traits & FS_COMPONENT_ALPHA; + boolean is_yuv = fs_traits & FS_YUV; ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); if (ureg == NULL) return 0; - /* it has to be either a fill or a composite op */ - debug_assert(is_fill ^ is_composite); + /* it has to be either a fill, a composite op or a yuv conversion */ + debug_assert((is_fill ^ is_composite) ^ is_yuv); out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, @@ -315,11 +385,10 @@ create_fs(struct pipe_context *pipe, if (is_composite) { src_sampler = ureg_DECL_sampler(ureg, 0); src_input = ureg_DECL_fs_input(ureg, - TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_PERSPECTIVE); - } - if (is_fill) { + } else if (is_fill) { if (is_solid) src_input = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, @@ -330,12 +399,15 @@ create_fs(struct pipe_context *pipe, TGSI_SEMANTIC_POSITION, 0, TGSI_INTERPOLATE_PERSPECTIVE); + } else { + debug_assert(is_yuv); + return create_yuv_shader(pipe, ureg); } if (has_mask) { mask_sampler = ureg_DECL_sampler(ureg, 1); mask_pos = ureg_DECL_fs_input(ureg, - TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, 1, TGSI_INTERPOLATE_PERSPECTIVE); } @@ -370,11 +442,11 @@ create_fs(struct pipe_context *pipe, else src = out; - coords = ureg_DECL_constant(ureg); - const0124 = ureg_DECL_constant(ureg); - matrow0 = ureg_DECL_constant(ureg); - matrow1 = ureg_DECL_constant(ureg); - matrow2 = ureg_DECL_constant(ureg); + coords = ureg_DECL_constant(ureg, 0); + const0124 = ureg_DECL_constant(ureg, 1); + matrow0 = ureg_DECL_constant(ureg, 2); + matrow1 = ureg_DECL_constant(ureg, 3); + matrow2 = ureg_DECL_constant(ureg, 4); if (is_lingrad) { linear_gradient(ureg, src, @@ -396,7 +468,7 @@ create_fs(struct pipe_context *pipe, ureg_TEX(ureg, mask, TGSI_TEXTURE_2D, mask_pos, mask_sampler); /* src IN mask */ - src_in_mask(ureg, out, ureg_src(src), ureg_src(mask)); + src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), comp_alpha); ureg_release_temporary(ureg, mask); } @@ -405,11 +477,11 @@ create_fs(struct pipe_context *pipe, return ureg_create_shader_and_destroy(ureg, pipe); } -struct xorg_shaders * xorg_shaders_create(struct exa_context *exa) +struct xorg_shaders * xorg_shaders_create(struct xorg_renderer *r) { struct xorg_shaders *sc = CALLOC_STRUCT(xorg_shaders); - sc->exa = exa; + sc->r = r; sc->vs_hash = cso_hash_create(); sc->fs_hash = cso_hash_create(); @@ -436,9 +508,9 @@ cache_destroy(struct cso_context *cso, void xorg_shaders_destroy(struct xorg_shaders *sc) { - cache_destroy(sc->exa->cso, sc->vs_hash, + cache_destroy(sc->r->cso, sc->vs_hash, PIPE_SHADER_VERTEX); - cache_destroy(sc->exa->cso, sc->fs_hash, + cache_destroy(sc->r->cso, sc->fs_hash, PIPE_SHADER_FRAGMENT); free(sc); @@ -470,12 +542,12 @@ struct xorg_shader xorg_shaders_get(struct xorg_shaders *sc, unsigned vs_traits, unsigned fs_traits) { - struct xorg_shader shader = {0}; + struct xorg_shader shader = { NULL, NULL }; void *vs, *fs; - vs = shader_from_cache(sc->exa->ctx, PIPE_SHADER_VERTEX, + vs = shader_from_cache(sc->r->pipe, PIPE_SHADER_VERTEX, sc->vs_hash, vs_traits); - fs = shader_from_cache(sc->exa->ctx, PIPE_SHADER_FRAGMENT, + fs = shader_from_cache(sc->r->pipe, PIPE_SHADER_FRAGMENT, sc->fs_hash, fs_traits); debug_assert(vs && fs); |