freedreno/a4xx: fix SP_FS_MRT_REG.HALF_PRECISION
[mesa.git] / src / gallium / drivers / freedreno / a4xx / fd4_blend.c
index b2d494930c46375384b1204d51992197281df27b..6c9fb3dd49ac0c0f202136059f8f0344ba094dc3 100644 (file)
@@ -1,5 +1,3 @@
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
 /*
  * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
  *
@@ -27,6 +25,7 @@
  */
 
 #include "pipe/p_state.h"
+#include "util/u_blend.h"
 #include "util/u_string.h"
 #include "util/u_memory.h"
 
@@ -34,7 +33,7 @@
 #include "fd4_context.h"
 #include "fd4_format.h"
 
-static enum a4xx_rb_blend_opcode
+static enum a3xx_rb_blend_opcode
 blend_func(unsigned func)
 {
        switch (func) {
@@ -59,12 +58,12 @@ fd4_blend_state_create(struct pipe_context *pctx,
                const struct pipe_blend_state *cso)
 {
        struct fd4_blend_stateobj *so;
-//     enum a3xx_rop_code rop = ROP_COPY;
+       enum a3xx_rop_code rop = ROP_COPY;
        bool reads_dest = false;
-       int i;
+       unsigned i, mrt_blend = 0;
 
        if (cso->logicop_enable) {
-//             rop = cso->logicop_func;  /* maps 1:1 */
+               rop = cso->logicop_func;  /* maps 1:1 */
 
                switch (cso->logicop_func) {
                case PIPE_LOGICOP_NOR:
@@ -84,11 +83,6 @@ fd4_blend_state_create(struct pipe_context *pctx,
                }
        }
 
-       if (cso->independent_blend_enable) {
-               DBG("Unsupported! independent blend state");
-               return NULL;
-       }
-
        so = CALLOC_STRUCT(fd4_blend_stateobj);
        if (!so)
                return NULL;
@@ -96,18 +90,32 @@ fd4_blend_state_create(struct pipe_context *pctx,
        so->base = *cso;
 
        for (i = 0; i < ARRAY_SIZE(so->rb_mrt); i++) {
-               const struct pipe_rt_blend_state *rt = &cso->rt[i];
+               const struct pipe_rt_blend_state *rt;
+
+               if (cso->independent_blend_enable)
+                       rt = &cso->rt[i];
+               else
+                       rt = &cso->rt[0];
 
-               so->rb_mrt[i].blend_control =
+               so->rb_mrt[i].blend_control_rgb =
                                A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(fd_blend_factor(rt->rgb_src_factor)) |
                                A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) |
-                               A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(fd_blend_factor(rt->rgb_dst_factor)) |
+                               A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(fd_blend_factor(rt->rgb_dst_factor));
+
+               so->rb_mrt[i].blend_control_alpha =
                                A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(fd_blend_factor(rt->alpha_src_factor)) |
                                A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(blend_func(rt->alpha_func)) |
                                A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(fd_blend_factor(rt->alpha_dst_factor));
 
+               so->rb_mrt[i].blend_control_no_alpha_rgb =
+                               A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(fd_blend_factor(util_blend_dst_alpha_to_one(rt->rgb_src_factor))) |
+                               A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) |
+                               A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(fd_blend_factor(util_blend_dst_alpha_to_one(rt->rgb_dst_factor)));
+
+
                so->rb_mrt[i].control =
-                               0xc00 | /* XXX ROP_CODE ?? */
+                               A4XX_RB_MRT_CONTROL_ROP_CODE(rop) |
+                               COND(cso->logicop_enable, A4XX_RB_MRT_CONTROL_ROP_ENABLE) |
                                A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(rt->colormask);
 
                if (rt->blend_enable) {
@@ -115,15 +123,20 @@ fd4_blend_state_create(struct pipe_context *pctx,
                                        A4XX_RB_MRT_CONTROL_READ_DEST_ENABLE |
                                        A4XX_RB_MRT_CONTROL_BLEND |
                                        A4XX_RB_MRT_CONTROL_BLEND2;
-                       so->rb_fs_output |= A4XX_RB_FS_OUTPUT_ENABLE_BLEND;
+                       mrt_blend |= (1 << i);
                }
 
-               if (reads_dest)
+               if (reads_dest) {
                        so->rb_mrt[i].control |= A4XX_RB_MRT_CONTROL_READ_DEST_ENABLE;
+                       mrt_blend |= (1 << i);
+               }
 
                if (cso->dither)
                        so->rb_mrt[i].buf_info |= A4XX_RB_MRT_BUF_INFO_DITHER_MODE(DITHER_ALWAYS);
        }
 
+       so->rb_fs_output = A4XX_RB_FS_OUTPUT_ENABLE_BLEND(mrt_blend) |
+               COND(cso->independent_blend_enable, A4XX_RB_FS_OUTPUT_INDEPENDENT_BLEND);
+
        return so;
 }