nv50: implement independent blend functions for nva3+ and fix cap
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Wed, 2 Mar 2011 18:41:08 +0000 (19:41 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Wed, 2 Mar 2011 19:59:53 +0000 (20:59 +0100)
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_state.c
src/gallium/drivers/nv50/nv50_stateobj.h

index f2b03e8..2bc26e5 100644 (file)
@@ -115,8 +115,9 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return 0;
    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
    case PIPE_CAP_INDEP_BLEND_ENABLE:
-   case PIPE_CAP_INDEP_BLEND_FUNC:
       return 1;
+   case PIPE_CAP_INDEP_BLEND_FUNC:
+      return nv50_screen(pscreen)->base.device->chipset >= 0xa3;
    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
       return 1;
index 17f272b..2f6fdb4 100644 (file)
@@ -88,7 +88,14 @@ nv50_blend_state_create(struct pipe_context *pipe,
 {
    struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj);
    int i;
-   boolean blend_enabled = cso->rt[0].blend_enable;
+   boolean emit_common_func = cso->rt[0].blend_enable;
+
+   const uint32_t chipset = nv50_context(pipe)->screen->base.device->chipset;
+
+   if (chipset >= 0xa3) {
+      SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1);
+      SB_DATA    (so, cso->independent_blend_enable);
+   }
 
    so->pipe = *cso;
 
@@ -97,14 +104,30 @@ nv50_blend_state_create(struct pipe_context *pipe,
       for (i = 0; i < 8; ++i) {
          SB_DATA(so, cso->rt[i].blend_enable);
          if (cso->rt[i].blend_enable)
-            blend_enabled = TRUE;
+            emit_common_func = TRUE;
+      }
+
+      if (chipset >= 0xa3) {
+         emit_common_func = FALSE;
+
+         for (i = 0; i < 8; ++i) {
+            if (!cso->rt[i].blend_enable)
+               continue;
+            SB_BEGIN_3D_(so, NVA3_3D_IBLEND_EQUATION_RGB(i), 6);
+            SB_DATA     (so, nvgl_blend_eqn(cso->rt[i].rgb_func));
+            SB_DATA     (so, nv50_blend_fac(cso->rt[i].rgb_src_factor));
+            SB_DATA     (so, nv50_blend_fac(cso->rt[i].rgb_dst_factor));
+            SB_DATA     (so, nvgl_blend_eqn(cso->rt[i].alpha_func));
+            SB_DATA     (so, nv50_blend_fac(cso->rt[i].alpha_src_factor));
+            SB_DATA     (so, nv50_blend_fac(cso->rt[i].alpha_dst_factor));
+         }
       }
    } else {
       for (i = 0; i < 8; ++i)
-         SB_DATA(so, blend_enabled);
+         SB_DATA(so, cso->rt[0].blend_enable);
    }
 
-   if (blend_enabled) {
+   if (emit_common_func) {
       SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5);
       SB_DATA    (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
       SB_DATA    (so, nv50_blend_fac(cso->rt[0].rgb_src_factor));
index 49f1837..f4e458b 100644 (file)
    (so)->state[(so)->size++] =                                                 \
       ((s) << 18) | (NV50_SUBCH_3D << 13) | NV50_3D_##m
 
+#define SB_BEGIN_3D_(so, m, s)                                                 \
+   (so)->state[(so)->size++] =                                                 \
+      ((s) << 18) | (NV50_SUBCH_3D << 13) | m
+
 #define SB_DATA(so, u) (so)->state[(so)->size++] = (u)
 
 struct nv50_blend_stateobj {
    struct pipe_blend_state pipe;
    int size;
-   uint32_t state[29];
+   uint32_t state[78];
 };
 
 struct nv50_tsc_entry {