ilo: replace a boolean by bool
[mesa.git] / src / gallium / state_trackers / vega / asm_fill.h
index a95e4c9efcbf4e19cd4446c98dd717d8d97fc767..77e6a14fe9973d4cbb357c72366e35839058a3d3 100644 (file)
@@ -273,21 +273,71 @@ alpha_per_channel( struct ureg_program *ureg,
 }
 
 /**
- * Emit instructions for the specified blend mode.  Colors should be
- * premultiplied.  Two temporary registers are required.
+ * Premultiply src and dst.
+ */
+static INLINE void
+blend_premultiply( struct ureg_program *ureg,
+                   struct ureg_src src,
+                   struct ureg_src src_channel_alpha,
+                   struct ureg_src dst)
+{
+   /* premultiply src */
+   ureg_MUL(ureg,
+            ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ),
+            src,
+            src_channel_alpha);
+   /* premultiply dst */
+   ureg_MUL(ureg,
+            ureg_writemask(ureg_dst(dst), TGSI_WRITEMASK_XYZ),
+            dst,
+            ureg_scalar(dst, TGSI_SWIZZLE_W));
+}
+
+/**
+ * Unpremultiply src.
+ */
+static INLINE void
+blend_unpremultiply( struct ureg_program *ureg,
+                     struct ureg_src src,
+                     struct ureg_src one,
+                     struct ureg_dst temp[1])
+{
+   /* replace 0.0f by 1.0f before calculating reciprocal */
+   ureg_CMP(ureg,
+            temp[0],
+            ureg_negate(ureg_scalar(src, TGSI_SWIZZLE_W)),
+            ureg_scalar(src, TGSI_SWIZZLE_W),
+            one);
+   ureg_RCP(ureg, temp[0], ureg_src(temp[0]));
+
+   ureg_MUL(ureg,
+            ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ),
+            src,
+            ureg_src(temp[0]));
+}
+
+/**
+ * Emit instructions for the specified blend mode.  Colors will be
+ * unpremultiplied.  Two temporary registers are required.
  *
- * XXX callers do not pass premultiplied colors!
+ * The output is written back to src.
  */
 static INLINE void
 blend_generic(struct ureg_program *ureg,
               VGBlendMode mode,
-              struct ureg_dst out,
               struct ureg_src src,
               struct ureg_src src_channel_alpha,
               struct ureg_src dst,
               struct ureg_src one,
               struct ureg_dst temp[2])
 {
+   struct ureg_dst out;
+
+   blend_premultiply(ureg, src, src_channel_alpha, dst);
+
+   /* blend in-place */
+   out = ureg_dst(src);
+
    switch (mode) {
    case VG_BLEND_SRC:
       ureg_MOV(ureg, out, src);
@@ -317,7 +367,7 @@ blend_generic(struct ureg_program *ureg,
             ureg_scalar(dst, TGSI_SWIZZLE_W), ureg_negate(src), src);
       ureg_MAD(ureg, temp[1],
             src_channel_alpha, ureg_negate(dst), dst);
-      ureg_MAD(ureg, temp[1], src, dst, ureg_src(temp[1]));
+      ureg_MAD(ureg, temp[0], src, dst, ureg_src(temp[0]));
       ureg_ADD(ureg, out, ureg_src(temp[0]), ureg_src(temp[1]));
       /* alpha is src over */
       ureg_ADD(ureg, ureg_writemask(out, TGSI_WRITEMASK_W),
@@ -355,6 +405,72 @@ blend_generic(struct ureg_program *ureg,
       assert(0);
       break;
    }
+
+   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_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)
+{
+   BLEND_GENERIC(VG_BLEND_SRC_OVER);
+}
+
+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);
+}
+
+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
@@ -365,13 +481,7 @@ blend_multiply( 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_MULTIPLY, *out,
-                 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_MULTIPLY);
 }
 
 static INLINE void
@@ -382,13 +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, *out,
-                 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_SCREEN);
 }
 
 static INLINE void
@@ -399,13 +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, *out,
-                 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_DARKEN);
 }
 
 static INLINE void
@@ -416,13 +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, *out,
-                 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);
+}
+
+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
@@ -554,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[] = {