st/xa: Kill a couple of compilation warnings
[mesa.git] / src / gallium / state_trackers / xa / xa_composite.c
index b30728423e86792fede485e0e7a8f5fff1e9de0c..0659c77be53ec7445c279e3b31e1c083d6a9c2f0 100644 (file)
@@ -39,7 +39,7 @@
 #define XFixedToDouble(f)    (((double) (f)) / 65536.)
 
 struct xa_composite_blend {
-    enum xa_composite_op op : 8;
+    unsigned op : 8;
 
     unsigned alpha_dst : 4;
     unsigned alpha_src : 4;
@@ -79,6 +79,25 @@ static const struct xa_composite_blend xa_blends[] = {
 };
 
 
+/*
+ * The alpha value stored in a luminance texture is read by the
+ * hardware as color.
+ */
+static unsigned
+xa_convert_blend_for_luminance(unsigned factor)
+{
+    switch(factor) {
+    case PIPE_BLENDFACTOR_DST_ALPHA:
+       return PIPE_BLENDFACTOR_DST_COLOR;
+    case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+       return PIPE_BLENDFACTOR_INV_DST_COLOR;
+    default:
+       break;
+    }
+    return factor;
+}
+
+
 static boolean
 blend_for_op(struct xa_composite_blend *blend,
             enum xa_composite_op op,
@@ -92,9 +111,15 @@ blend_for_op(struct xa_composite_blend *blend,
     boolean supported = FALSE;
 
     /*
-     * our default in case something goes wrong
+     * Temporarily disable component alpha since it appears buggy.
      */
+    if (src_pic->component_alpha ||
+       (mask_pic && mask_pic->component_alpha))
+       return FALSE;
 
+    /*
+     * our default in case something goes wrong
+     */
     *blend = xa_blends[XA_BLEND_OP_OVER];
 
     for (i = 0; i < num_blends; ++i) {
@@ -104,15 +129,20 @@ blend_for_op(struct xa_composite_blend *blend,
        }
     }
 
+    if (!dst_pic->srf)
+       return supported;
+
+    if (dst_pic->srf->tex->format == PIPE_FORMAT_L8_UNORM) {
+       blend->rgb_src = xa_convert_blend_for_luminance(blend->rgb_src);
+       blend->rgb_dst = xa_convert_blend_for_luminance(blend->rgb_dst);
+    }
 
     /*
      * If there's no dst alpha channel, adjust the blend op so that we'll treat
      * it as always 1.
      */
 
-    if (dst_pic &&
-       xa_format_a(xa_surface_format(dst_pic->srf)) == 0 &&
-       blend->alpha_dst) {
+    if (xa_format_a(dst_pic->pict_format) == 0 && blend->alpha_dst) {
        if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA)
            blend->rgb_src = PIPE_BLENDFACTOR_ONE;
        else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA)
@@ -125,7 +155,7 @@ blend_for_op(struct xa_composite_blend *blend,
      * channels multiplied by the source picture's alpha.
      */
     if (mask_pic && mask_pic->component_alpha &&
-       xa_format_rgb(xa_surface_format(mask_pic->srf)) &&
+       xa_format_rgb(mask_pic->pict_format) &&
        blend->alpha_src) {
        if (blend->rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) {
            blend->rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR;
@@ -183,45 +213,46 @@ xa_is_filter_accelerated(struct xa_picture *pic)
     return 1;
 }
 
-int
-xa_composite_is_accelerated(const struct xa_composite *comp)
+XA_EXPORT int
+xa_composite_check_accelerated(const struct xa_composite *comp)
 {
     struct xa_composite_blend blend;
     struct xa_picture *src_pic = comp->src;
 
     if (!xa_is_filter_accelerated(src_pic) ||
        !xa_is_filter_accelerated(comp->mask)) {
-       return 0;
+       return -XA_ERR_INVAL;
     }
 
 
     if (src_pic->src_pict) {
        if (src_pic->src_pict->type != xa_src_pict_solid_fill)
-           return 0;
+           return -XA_ERR_INVAL;
     }
 
     if (blend_for_op(&blend, comp->op, comp->src, comp->mask, comp->dst)) {
        struct xa_picture *mask = comp->mask;
        if (mask && mask->component_alpha &&
-           xa_format_rgb(xa_surface_format(mask->srf))) {
+           xa_format_rgb(mask->pict_format)) {
            if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) {
-               return 0;
+               return -XA_ERR_INVAL;
            }
        }
 
-       return 1;
+       return XA_ERR_NONE;
     }
-    return 0;
+    return -XA_ERR_INVAL;
 }
 
-static void
+static int
 bind_composite_blend_state(struct xa_context *ctx,
                           const struct xa_composite *comp)
 {
     struct xa_composite_blend blend_opt;
     struct pipe_blend_state blend;
 
-    blend_for_op(&blend_opt, comp->op, comp->src, comp->mask, comp->dst);
+    if (!blend_for_op(&blend_opt, comp->op, comp->src, comp->mask, comp->dst))
+       return -XA_ERR_INVAL;
 
     memset(&blend, 0, sizeof(struct pipe_blend_state));
     blend.rt[0].blend_enable = 1;
@@ -233,11 +264,11 @@ bind_composite_blend_state(struct xa_context *ctx,
     blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst;
 
     cso_set_blend(ctx->cso, &blend);
+    return XA_ERR_NONE;
 }
 
 static unsigned int
 picture_format_fixups(struct xa_picture *src_pic,
-                     struct xa_picture *dst_pic,
                      int mask)
 {
     boolean set_alpha = FALSE;
@@ -247,25 +278,23 @@ picture_format_fixups(struct xa_picture *src_pic,
     enum xa_formats src_hw_format, src_pic_format;
     enum xa_surface_type src_hw_type, src_pic_type;
 
+    if (!src)
+       return 0;
+
     src_hw_format = xa_surface_format(src);
     src_pic_format = src_pic->pict_format;
 
+    set_alpha = (xa_format_type_is_color(src_pic_format) &&
+                xa_format_a(src_pic_format) == 0);
+
+    if (set_alpha)
+       ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
+
     if (src_hw_format == src_pic_format) {
-       if (src_pic->pict_format == xa_format_a8) {
-           if (mask)
-               return FS_MASK_LUMINANCE;
-           else if (dst_pic->pict_format != xa_format_a8) {
-
-               /*
-                * if both dst and src are luminance then
-                * we don't want to swizzle the alpha (X) of the
-                * source into W component of the dst because
-                * it will break our destination
-                */
-               return FS_SRC_LUMINANCE;
-           }
-       }
-       return 0;
+       if (src->tex->format == PIPE_FORMAT_L8_UNORM)
+           return ((mask) ? FS_MASK_LUMINANCE : FS_SRC_LUMINANCE);
+
+       return ret;
     }
 
     src_hw_type = xa_format_type(src_hw_format);
@@ -277,27 +306,21 @@ picture_format_fixups(struct xa_picture *src_pic,
                 src_pic_type == xa_type_argb)));
 
     if (!swizzle && (src_hw_type != src_pic_type))
-       return 0;
+      return ret;
 
-    set_alpha = (xa_format_type_is_color(src_hw_type) &&
-                xa_format_a(src_hw_type) == 0);
-
-    if (set_alpha)
-       ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
     if (swizzle)
        ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
 
     return ret;
 }
 
-static void
+static int
 bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
 {
     unsigned vs_traits = 0, fs_traits = 0;
     struct xa_shader shader;
     struct xa_picture *src_pic = comp->src;
     struct xa_picture *mask_pic = comp->mask;
-    struct xa_picture *dst_pic = comp->dst;
 
     ctx->has_solid_color = FALSE;
 
@@ -318,7 +341,7 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
            vs_traits |= VS_COMPOSITE;
        }
 
-       fs_traits |= picture_format_fixups(src_pic, dst_pic, 0);
+       fs_traits |= picture_format_fixups(src_pic, 0);
     }
 
     if (mask_pic) {
@@ -330,19 +353,25 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
 
        if (mask_pic->component_alpha) {
            struct xa_composite_blend blend;
-           blend_for_op(&blend, comp->op, src_pic, mask_pic, NULL);
+           if (!blend_for_op(&blend, comp->op, src_pic, mask_pic, NULL))
+               return -XA_ERR_INVAL;
+
            if (blend.alpha_src) {
                fs_traits |= FS_CA_SRCALPHA;
            } else
                fs_traits |= FS_CA_FULL;
        }
 
-       fs_traits |= picture_format_fixups(mask_pic, dst_pic, 1);
+       fs_traits |= picture_format_fixups(mask_pic, 1);
     }
 
+    if (ctx->srf->format == PIPE_FORMAT_L8_UNORM)
+       fs_traits |= FS_DST_LUMINANCE;
+
     shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
     cso_set_vertex_shader_handle(ctx->cso, shader.vs);
     cso_set_fragment_shader_handle(ctx->cso, shader.fs);
+    return XA_ERR_NONE;
 }
 
 static void
@@ -419,38 +448,44 @@ bind_samplers(struct xa_context *ctx,
                                   ctx->bound_sampler_views);
 }
 
-int
+XA_EXPORT int
 xa_composite_prepare(struct xa_context *ctx,
                     const struct xa_composite *comp)
 {
     struct xa_surface *dst_srf = comp->dst->srf;
     int ret;
 
-    ret = xa_surface_psurf_create(ctx, dst_srf);
+    ret = xa_ctx_srf_create(ctx, dst_srf);
     if (ret != XA_ERR_NONE)
        return ret;
 
-    renderer_bind_destination(ctx, dst_srf->srf,
-                             dst_srf->srf->width,
-                             dst_srf->srf->height);
+    ctx->dst = dst_srf;
+    renderer_bind_destination(ctx, ctx->srf, ctx->srf->width,
+                             ctx->srf->height);
 
-    bind_composite_blend_state(ctx, comp);
-    bind_shaders(ctx, comp);
+    ret = bind_composite_blend_state(ctx, comp);
+    if (ret != XA_ERR_NONE)
+       return ret;
+    ret = bind_shaders(ctx, comp);
+    if (ret != XA_ERR_NONE)
+       return ret;
     bind_samplers(ctx, comp);
 
     if (ctx->num_bound_samplers == 0 ) { /* solid fill */
        renderer_begin_solid(ctx);
     } else {
        renderer_begin_textures(ctx);
+       ctx->comp = comp;
     }
 
-    xa_surface_psurf_destroy(dst_srf);
+    xa_ctx_srf_destroy(ctx);
     return XA_ERR_NONE;
 }
 
-void xa_composite_rect(struct xa_context *ctx,
-                      int srcX, int srcY, int maskX, int maskY,
-                      int dstX, int dstY, int width, int height)
+XA_EXPORT void
+xa_composite_rect(struct xa_context *ctx,
+                 int srcX, int srcY, int maskX, int maskY,
+                 int dstX, int dstY, int width, int height)
 {
     if (ctx->num_bound_samplers == 0 ) { /* solid fill */
        renderer_solid(ctx, dstX, dstY, dstX + width, dstY + height,
@@ -463,7 +498,7 @@ void xa_composite_rect(struct xa_context *ctx,
 
        if (comp->src->has_transform)
            src_matrix = comp->src->transform;
-       if (comp->mask->has_transform)
+       if (comp->mask && comp->mask->has_transform)
            mask_matrix = comp->mask->transform;
 
        renderer_texture(ctx, pos, width, height,
@@ -471,7 +506,7 @@ void xa_composite_rect(struct xa_context *ctx,
     }
 }
 
-void
+XA_EXPORT void
 xa_composite_done(struct xa_context *ctx)
 {
     renderer_draw_flush(ctx);
@@ -479,7 +514,7 @@ xa_composite_done(struct xa_context *ctx)
 
     ctx->comp = NULL;
     ctx->has_solid_color = FALSE;
-    ctx->num_bound_samplers = 0;
+    xa_ctx_sampler_views_destroy(ctx);
 }
 
 static const struct xa_composite_allocation a = {
@@ -488,7 +523,7 @@ static const struct xa_composite_allocation a = {
     .xa_source_pict_size = sizeof(union xa_source_pict),
 };
 
-const struct xa_composite_allocation *
+XA_EXPORT const struct xa_composite_allocation *
 xa_composite_allocation(void)
 {
     return &a;