st/vega: Add blend shaders for all blend modes.
authorChia-I Wu <olv@lunarg.com>
Sat, 4 Dec 2010 14:42:46 +0000 (22:42 +0800)
committerChia-I Wu <olv@lunarg.com>
Sat, 4 Dec 2010 15:41:35 +0000 (23:41 +0800)
src/gallium/state_trackers/vega/asm_fill.h
src/gallium/state_trackers/vega/shader.c
src/gallium/state_trackers/vega/shaders_cache.c
src/gallium/state_trackers/vega/shaders_cache.h

index 5ff76975e22805fbf6cc3899eca19edfb4ec1c64..77e6a14fe9973d4cbb357c72366e35839058a3d3 100644 (file)
@@ -409,24 +409,79 @@ blend_generic(struct ureg_program *ureg,
    blend_unpremultiply(ureg, src, one, temp);
 }
 
+#define BLEND_GENERIC(mode) \
+   do { \
+      ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]);         \
+      blend_generic(ureg, (mode), ureg_src(temp[0]), ureg_src(temp[1]),    \
+                    ureg_src(temp[2]),                                     \
+                    ureg_scalar(constant[3], TGSI_SWIZZLE_Y), temp + 3);   \
+      ureg_MOV(ureg, *out, ureg_src(temp[0]));                             \
+   } while (0)
+
 static INLINE void
-blend_multiply( struct ureg_program *ureg,
+blend_src( struct ureg_program *ureg,
+           struct ureg_dst *out,
+           struct ureg_src *in,
+           struct ureg_src *sampler,
+           struct ureg_dst *temp,
+           struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_SRC);
+}
+
+static INLINE void
+blend_src_over( struct ureg_program *ureg,
                 struct ureg_dst *out,
                 struct ureg_src *in,
                 struct ureg_src *sampler,
                 struct ureg_dst *temp,
                 struct ureg_src *constant)
 {
-   ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]);
+   BLEND_GENERIC(VG_BLEND_SRC_OVER);
+}
 
-   blend_generic(ureg, VG_BLEND_MULTIPLY,
-                 ureg_src(temp[0]),
-                 ureg_src(temp[1]),
-                 ureg_src(temp[2]),
-                 ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
-                 temp + 3);
+static INLINE void
+blend_dst_over( struct ureg_program *ureg,
+                struct ureg_dst *out,
+                struct ureg_src *in,
+                struct ureg_src *sampler,
+                struct ureg_dst *temp,
+                struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_DST_OVER);
+}
 
-   ureg_MOV(ureg, *out, ureg_src(temp[0]));
+static INLINE void
+blend_src_in( struct ureg_program *ureg,
+              struct ureg_dst *out,
+              struct ureg_src *in,
+              struct ureg_src *sampler,
+              struct ureg_dst *temp,
+              struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_SRC_IN);
+}
+
+static INLINE void
+blend_dst_in( struct ureg_program *ureg,
+              struct ureg_dst *out,
+              struct ureg_src *in,
+              struct ureg_src *sampler,
+              struct ureg_dst *temp,
+              struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_DST_IN);
+}
+
+static INLINE void
+blend_multiply( struct ureg_program *ureg,
+                struct ureg_dst *out,
+                struct ureg_src *in,
+                struct ureg_src *sampler,
+                struct ureg_dst *temp,
+                struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_MULTIPLY);
 }
 
 static INLINE void
@@ -437,16 +492,7 @@ blend_screen( struct ureg_program *ureg,
               struct ureg_dst     *temp,
               struct ureg_src     *constant)
 {
-   ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]);
-
-   blend_generic(ureg, VG_BLEND_SCREEN,
-                 ureg_src(temp[0]),
-                 ureg_src(temp[1]),
-                 ureg_src(temp[2]),
-                 ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
-                 temp + 3);
-
-   ureg_MOV(ureg, *out, ureg_src(temp[0]));
+   BLEND_GENERIC(VG_BLEND_SCREEN);
 }
 
 static INLINE void
@@ -457,16 +503,7 @@ blend_darken( struct ureg_program *ureg,
               struct ureg_dst     *temp,
               struct ureg_src     *constant)
 {
-   ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]);
-
-   blend_generic(ureg, VG_BLEND_DARKEN,
-                 ureg_src(temp[0]),
-                 ureg_src(temp[1]),
-                 ureg_src(temp[2]),
-                 ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
-                 temp + 3);
-
-   ureg_MOV(ureg, *out, ureg_src(temp[0]));
+   BLEND_GENERIC(VG_BLEND_DARKEN);
 }
 
 static INLINE void
@@ -477,16 +514,18 @@ blend_lighten( struct ureg_program *ureg,
                struct ureg_dst *temp,
                struct ureg_src     *constant)
 {
-   ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]);
-
-   blend_generic(ureg, VG_BLEND_LIGHTEN,
-                 ureg_src(temp[0]),
-                 ureg_src(temp[1]),
-                 ureg_src(temp[2]),
-                 ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
-                 temp + 3);
+   BLEND_GENERIC(VG_BLEND_LIGHTEN);
+}
 
-   ureg_MOV(ureg, *out, ureg_src(temp[0]));
+static INLINE void
+blend_additive( struct ureg_program *ureg,
+                struct ureg_dst *out,
+                struct ureg_src *in,
+                struct ureg_src *sampler,
+                struct ureg_dst *temp,
+                struct ureg_src *constant)
+{
+   BLEND_GENERIC(VG_BLEND_ADDITIVE);
 }
 
 static INLINE void
@@ -618,14 +657,18 @@ static const struct shader_asm_info shaders_alpha_asm[] = {
 
 /* extra blend modes */
 static const struct shader_asm_info shaders_blend_asm[] = {
-   {VEGA_BLEND_MULTIPLY_SHADER, blend_multiply,
-    VG_TRUE,  3, 1, 2, 1, 0, 5},
-   {VEGA_BLEND_SCREEN_SHADER, blend_screen,
-    VG_TRUE,  3, 1, 2, 1, 0, 5},
-   {VEGA_BLEND_DARKEN_SHADER, blend_darken,
-    VG_TRUE,  3, 1, 2, 1, 0, 5},
-   {VEGA_BLEND_LIGHTEN_SHADER, blend_lighten,
-    VG_TRUE,  3, 1, 2, 1, 0, 5},
+#define BLEND_ASM_INFO(id, func) { (id), (func), VG_TRUE, 3, 1, 2, 1, 0, 5 }
+   BLEND_ASM_INFO(VEGA_BLEND_SRC_SHADER, blend_src),
+   BLEND_ASM_INFO(VEGA_BLEND_SRC_OVER_SHADER, blend_src_over),
+   BLEND_ASM_INFO(VEGA_BLEND_DST_OVER_SHADER, blend_dst_over),
+   BLEND_ASM_INFO(VEGA_BLEND_SRC_IN_SHADER, blend_src_in),
+   BLEND_ASM_INFO(VEGA_BLEND_DST_IN_SHADER, blend_dst_in),
+   BLEND_ASM_INFO(VEGA_BLEND_MULTIPLY_SHADER, blend_multiply),
+   BLEND_ASM_INFO(VEGA_BLEND_SCREEN_SHADER, blend_screen),
+   BLEND_ASM_INFO(VEGA_BLEND_DARKEN_SHADER, blend_darken),
+   BLEND_ASM_INFO(VEGA_BLEND_LIGHTEN_SHADER, blend_lighten),
+   BLEND_ASM_INFO(VEGA_BLEND_ADDITIVE_SHADER, blend_additive)
+#undef BLEND_ASM_INFO
 };
 
 static const struct shader_asm_info shaders_mask_asm[] = {
index 8577d21efe41571ac1c92ef40e2cb06c03906b77..92d3f5549e9fd6b224da92c2fc5d405b6b37a98e 100644 (file)
@@ -128,16 +128,30 @@ static VGint setup_constant_buffer(struct shader *shader)
    return param_bytes;
 }
 
+static VGboolean blend_use_shader(struct vg_context *ctx)
+{
+   VGboolean advanced_blending;
+
+   switch (ctx->state.vg.blend_mode) {
+   case VG_BLEND_MULTIPLY:
+   case VG_BLEND_SCREEN:
+   case VG_BLEND_DARKEN:
+   case VG_BLEND_LIGHTEN:
+      advanced_blending = VG_TRUE;
+      break;
+   default:
+      advanced_blending = VG_FALSE;
+      break;
+   }
+
+   return advanced_blending;
+}
+
 static VGint blend_bind_samplers(struct vg_context *ctx,
                                  struct pipe_sampler_state **samplers,
                                  struct pipe_sampler_view **sampler_views)
 {
-   VGBlendMode bmode = ctx->state.vg.blend_mode;
-
-   if (bmode == VG_BLEND_MULTIPLY ||
-       bmode == VG_BLEND_SCREEN ||
-       bmode == VG_BLEND_DARKEN ||
-       bmode == VG_BLEND_LIGHTEN) {
+   if (blend_use_shader(ctx)) {
       samplers[2] = &ctx->blend_sampler;
       sampler_views[2] = vg_prepare_blend_surface(ctx);
 
@@ -209,7 +223,6 @@ static void setup_shader_program(struct shader *shader)
    VGint shader_id = 0;
    VGBlendMode blend_mode = ctx->state.vg.blend_mode;
    VGboolean black_white = is_format_bw(shader);
-   VGboolean advanced_blend;
 
    /* 1st stage: fill */
    if (!shader->drawing_image ||
@@ -256,26 +269,28 @@ static void setup_shader_program(struct shader *shader)
    if (shader->color_transform)
       shader_id |= VEGA_COLOR_TRANSFORM_SHADER;
 
-   switch(blend_mode) {
-   case VG_BLEND_MULTIPLY:
-   case VG_BLEND_SCREEN:
-   case VG_BLEND_DARKEN:
-   case VG_BLEND_LIGHTEN:
-      advanced_blend = VG_TRUE;
-      break;
-   default:
-      /* handled by pipe_blend_state */
-      advanced_blend = VG_FALSE;
-      break;
-   }
-
-   if (advanced_blend) {
+   if (blend_use_shader(ctx)) {
       if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL)
          shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER;
       else
          shader_id |= VEGA_ALPHA_NORMAL_SHADER;
 
       switch(blend_mode) {
+      case VG_BLEND_SRC:
+         shader_id |= VEGA_BLEND_SRC_SHADER;
+         break;
+      case VG_BLEND_SRC_OVER:
+         shader_id |= VEGA_BLEND_SRC_OVER_SHADER;
+         break;
+      case VG_BLEND_DST_OVER:
+         shader_id |= VEGA_BLEND_DST_OVER_SHADER;
+         break;
+      case VG_BLEND_SRC_IN:
+         shader_id |= VEGA_BLEND_SRC_IN_SHADER;
+         break;
+      case VG_BLEND_DST_IN:
+         shader_id |= VEGA_BLEND_DST_IN_SHADER;
+         break;
       case VG_BLEND_MULTIPLY:
          shader_id |= VEGA_BLEND_MULTIPLY_SHADER;
          break;
@@ -288,6 +303,9 @@ static void setup_shader_program(struct shader *shader)
       case VG_BLEND_LIGHTEN:
          shader_id |= VEGA_BLEND_LIGHTEN_SHADER;
          break;
+      case VG_BLEND_ADDITIVE:
+         shader_id |= VEGA_BLEND_ADDITIVE_SHADER;
+         break;
       default:
          assert(0);
          break;
index e9873eb18b29b5e56496f05dcd39b16590d0a357..023996ce2d8c848ea84dc265b6e5ec5826ec2776 100644 (file)
@@ -318,10 +318,16 @@ create_shader(struct pipe_context *pipe,
    /* fifth stage */
    sh = SHADERS_GET_BLEND_SHADER(id);
    switch (sh) {
+   case VEGA_BLEND_SRC_SHADER:
+   case VEGA_BLEND_SRC_OVER_SHADER:
+   case VEGA_BLEND_DST_OVER_SHADER:
+   case VEGA_BLEND_SRC_IN_SHADER:
+   case VEGA_BLEND_DST_IN_SHADER:
    case VEGA_BLEND_MULTIPLY_SHADER:
    case VEGA_BLEND_SCREEN_SHADER:
    case VEGA_BLEND_DARKEN_SHADER:
    case VEGA_BLEND_LIGHTEN_SHADER:
+   case VEGA_BLEND_ADDITIVE_SHADER:
       shaders[idx] = &shaders_blend_asm[(sh >> SHADERS_BLEND_SHIFT) - 1];
       assert(shaders[idx]->id == sh);
       idx++;
index 9265c547ed3ece606bf18747001a27d2fa8aed97..05014f25dccedb4669f319ab9df48d991fdfb943 100644 (file)
@@ -37,7 +37,7 @@ struct shaders_cache;
 #define _SHADERS_IMAGE_BITS            2
 #define _SHADERS_COLOR_TRANSFORM_BITS  1
 #define _SHADERS_ALPHA_BITS            2
-#define _SHADERS_BLEND_BITS            3
+#define _SHADERS_BLEND_BITS            4
 #define _SHADERS_MASK_BITS             1
 #define _SHADERS_PREMULTIPLY_BITS      2
 #define _SHADERS_BW_BITS               1
@@ -79,10 +79,16 @@ enum VegaShaderType {
    VEGA_ALPHA_NORMAL_SHADER       = 1 <<  SHADERS_ALPHA_SHIFT,
    VEGA_ALPHA_PER_CHANNEL_SHADER  = 2 <<  SHADERS_ALPHA_SHIFT,
 
-   VEGA_BLEND_MULTIPLY_SHADER     = 1 << SHADERS_BLEND_SHIFT,
-   VEGA_BLEND_SCREEN_SHADER       = 2 << SHADERS_BLEND_SHIFT,
-   VEGA_BLEND_DARKEN_SHADER       = 3 << SHADERS_BLEND_SHIFT,
-   VEGA_BLEND_LIGHTEN_SHADER      = 4 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_SRC_SHADER          = 1 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_SRC_OVER_SHADER     = 2 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_DST_OVER_SHADER     = 3 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_SRC_IN_SHADER       = 4 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_DST_IN_SHADER       = 5 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_MULTIPLY_SHADER     = 6 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_SCREEN_SHADER       = 7 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_DARKEN_SHADER       = 8 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_LIGHTEN_SHADER      = 9 << SHADERS_BLEND_SHIFT,
+   VEGA_BLEND_ADDITIVE_SHADER     = 10<< SHADERS_BLEND_SHIFT,
 
    VEGA_MASK_SHADER               = 1 << SHADERS_MASK_SHIFT,