st/xorg: implement repeatnone and make some code smell less like ass
authorZack Rusin <zackr@vmware.com>
Thu, 12 Nov 2009 00:52:08 +0000 (19:52 -0500)
committerZack Rusin <zackr@vmware.com>
Thu, 12 Nov 2009 00:55:50 +0000 (19:55 -0500)
src/gallium/state_trackers/xorg/xorg_composite.c
src/gallium/state_trackers/xorg/xorg_exa.c
src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
src/gallium/state_trackers/xorg/xorg_exa_tgsi.h

index 2689daed5f5ce57102628e74429100c88fb76f49..02dc949c93ea2e5ac7124bbac2fb28358689adcb 100644 (file)
@@ -199,10 +199,6 @@ boolean xorg_composite_accelerated(int op,
                           op);
          }
       }
-      if ((pSrcPicture && pSrcPicture->repeatType == RepeatNone) ||
-          (pMaskPicture && pMaskPicture->repeatType == RepeatNone)) {
-         XORG_FALLBACK("RepeatNone is not supported");
-      }
 
       return TRUE;
    }
@@ -243,6 +239,9 @@ bind_shaders(struct exa_context *exa, int op,
    exa->has_solid_color = FALSE;
 
    if (pSrcPicture) {
+      if (pSrcPicture->repeatType == RepeatNone && pSrcPicture->transform)
+         fs_traits |= FS_SRC_REPEAT_NONE;
+
       if (pSrcPicture->pSourcePict) {
          if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
             fs_traits |= FS_SOLID_FILL;
@@ -263,6 +262,8 @@ bind_shaders(struct exa_context *exa, int op,
    if (pMaskPicture) {
       vs_traits |= VS_MASK;
       fs_traits |= FS_MASK;
+      if (pMaskPicture->repeatType == RepeatNone && pMaskPicture->transform)
+         fs_traits |= FS_MASK_REPEAT_NONE;
       if (pMaskPicture->componentAlpha) {
          struct xorg_composite_blend blend;
          blend_for_op(&blend, op,
index c71779bc207cee96815ce23ad5304789b6483d90..a77ee7a9084c2afb8ef5e82a6adcc771b4299d2f 100644 (file)
@@ -51,7 +51,6 @@
 /*
  * Helper functions
  */
-#if DEBUG_PRINT
 struct render_format_str {
    int format;
    const char *name;
@@ -109,7 +108,6 @@ static const char *render_format_name(int format)
    }
    return NULL;
 }
-#endif
 
 static void
 exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_format)
index 83cc12fea9aec62327cdadcda6ba857a266d411b..5880de4154b366e587e248d79936f04685275319 100644 (file)
@@ -233,10 +233,10 @@ create_vs(struct pipe_context *pipe,
    struct ureg_src src;
    struct ureg_dst dst;
    struct ureg_src const0, const1;
-   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;
+   boolean is_fill = (vs_traits & VS_FILL) != 0;
+   boolean is_composite = (vs_traits & VS_COMPOSITE) != 0;
+   boolean has_mask = (vs_traits & VS_MASK) != 0;
+   boolean is_yuv = (vs_traits & VS_YUV) != 0;
    unsigned input_slot = 0;
 
    ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
@@ -353,6 +353,47 @@ create_yuv_shader(struct pipe_context *pipe, struct ureg_program *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,
+            boolean repeat_none)
+{
+   if (repeat_none) {
+      struct ureg_dst tmp0 = ureg_DECL_temporary(ureg);
+      struct ureg_dst tmp1 = ureg_DECL_temporary(ureg);
+      struct ureg_src const0 = ureg_DECL_constant(ureg, 0);
+      unsigned label;
+      ureg_SLT(ureg, tmp1, ureg_swizzle(coords,
+                                        TGSI_SWIZZLE_X,
+                                        TGSI_SWIZZLE_Y,
+                                        TGSI_SWIZZLE_X,
+                                        TGSI_SWIZZLE_Y),
+               ureg_scalar(const0, TGSI_SWIZZLE_X));
+      ureg_SGT(ureg, tmp0, ureg_swizzle(coords,
+                                        TGSI_SWIZZLE_X,
+                                        TGSI_SWIZZLE_Y,
+                                        TGSI_SWIZZLE_X,
+                                        TGSI_SWIZZLE_Y),
+               ureg_scalar(const0, TGSI_SWIZZLE_W));
+      ureg_MAX(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1));
+      ureg_MAX(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X),
+               ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y));
+      label = ureg_get_instruction_number(ureg) + 2;
+      ureg_IF(ureg, ureg_src(tmp0), &label);
+      ureg_MOV(ureg, dst, ureg_scalar(const0, TGSI_SWIZZLE_X));
+      label += 2;
+      ureg_ELSE(ureg, &label);
+      ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler);
+      ureg_ENDIF(ureg);
+      ureg_release_temporary(ureg, tmp0);
+      ureg_release_temporary(ureg, tmp1);
+   } else
+      ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler);
+}
+
 static void *
 create_fs(struct pipe_context *pipe,
           unsigned fs_traits)
@@ -362,14 +403,16 @@ create_fs(struct pipe_context *pipe,
    struct ureg_src /*dst_pos,*/ src_input, mask_pos;
    struct ureg_dst src, mask;
    struct ureg_dst out;
-   boolean has_mask = fs_traits & FS_MASK;
-   boolean is_fill = fs_traits & FS_FILL;
-   boolean is_composite = fs_traits & FS_COMPOSITE;
-   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;
+   unsigned has_mask = (fs_traits & FS_MASK) != 0;
+   unsigned is_fill = (fs_traits & FS_FILL) != 0;
+   unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0;
+   unsigned is_solid   = (fs_traits & FS_SOLID_FILL) != 0;
+   unsigned is_lingrad = (fs_traits & FS_LINGRAD_FILL) != 0;
+   unsigned is_radgrad = (fs_traits & FS_RADGRAD_FILL) != 0;
+   unsigned comp_alpha = (fs_traits & FS_COMPONENT_ALPHA) != 0;
+   unsigned is_yuv = (fs_traits & FS_YUV) != 0;
+   unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0;
+   unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0;
 
    ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
    if (ureg == NULL)
@@ -425,8 +468,8 @@ create_fs(struct pipe_context *pipe,
          src = ureg_DECL_temporary(ureg);
       else
          src = out;
-      ureg_TEX(ureg, src,
-               TGSI_TEXTURE_2D, src_input, src_sampler);
+      xrender_tex(ureg, src, src_input, src_sampler,
+                  src_repeat_none);
    } else if (is_fill) {
       if (is_solid) {
          if (has_mask)
@@ -465,8 +508,8 @@ create_fs(struct pipe_context *pipe,
 
    if (has_mask) {
       mask = ureg_DECL_temporary(ureg);
-      ureg_TEX(ureg, mask,
-               TGSI_TEXTURE_2D, mask_pos, mask_sampler);
+      xrender_tex(ureg, mask, mask_pos, mask_sampler,
+                  mask_repeat_none);
       /* src IN mask */
       src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), comp_alpha);
       ureg_release_temporary(ureg, mask);
index d3bfa304c2be19aac775ccd6339273bebc0372fb..c038dc2231f57966a990894c59016565732e45f1 100644 (file)
@@ -25,7 +25,9 @@ enum xorg_fs_traits {
    FS_RADGRAD_FILL     = 1 << 4,
    FS_CA_FULL          = 1 << 5, /* src.rgba * mask.rgba */
    FS_CA_SRCALPHA      = 1 << 6, /* src.aaaa * mask.rgba */
-   FS_YUV              = 1<<  7,
+   FS_YUV              = 1 << 7,
+   FS_SRC_REPEAT_NONE  = 1 << 8,
+   FS_MASK_REPEAT_NONE = 1 << 9,
 
    FS_FILL             = (FS_SOLID_FILL |
                           FS_LINGRAD_FILL |