svga: check return value of define_query_vgpu{9,10}
[mesa.git] / src / gallium / drivers / svga / svga_pipe_blend.c
index 0c9d6129b53e144f51db4db31be472031a9b6a5f..b5557d31f4401b815be1651d4193cd6292503bfe 100644 (file)
@@ -37,6 +37,9 @@
 static inline unsigned
 svga_translate_blend_factor(const struct svga_context *svga, unsigned factor)
 {
+   /* Note: there is no SVGA3D_BLENDOP_[INV]BLENDFACTORALPHA so
+    * we can't translate PIPE_BLENDFACTOR_[INV_]CONST_ALPHA properly.
+    */
    switch (factor) {
    case PIPE_BLENDFACTOR_ZERO:            return SVGA3D_BLENDOP_ZERO;
    case PIPE_BLENDFACTOR_SRC_ALPHA:       return SVGA3D_BLENDOP_SRCALPHA;
@@ -115,7 +118,6 @@ define_blend_state_object(struct svga_context *svga,
       perRT[i].renderTargetWriteMask = bs->rt[i].writemask;
       perRT[i].logicOpEnable = 0;
       perRT[i].logicOp = SVGA3D_LOGICOP_COPY;
-      assert(perRT[i].srcBlend == perRT[0].srcBlend);
    }
 
    /* Loop in case command buffer is full and we need to flush and retry */
@@ -142,6 +144,20 @@ svga_create_blend_state(struct pipe_context *pipe,
    struct svga_blend_state *blend = CALLOC_STRUCT( svga_blend_state );
    unsigned i;
 
+   if (!blend)
+      return NULL;
+
+   /* Find index of first target with blending enabled.  If no blending is
+    * enabled at all, first_enabled will be zero.
+    */
+   unsigned first_enabled = 0;
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+      if (templ->rt[i].blend_enable) {
+         first_enabled = i;
+         break;
+      }
+   }
+
    /* Fill in the per-rendertarget blend state.  We currently only
     * support independent blend enable and colormask per render target.
     */
@@ -243,26 +259,37 @@ svga_create_blend_state(struct pipe_context *pipe,
          blend->rt[i].srcblend_alpha = blend->rt[i].srcblend;
          blend->rt[i].dstblend_alpha = blend->rt[i].dstblend;
          blend->rt[i].blendeq_alpha = blend->rt[i].blendeq;
+
+         if (templ->logicop_func == PIPE_LOGICOP_XOR) {
+            pipe_debug_message(&svga->debug.callback, CONFORMANCE,
+                               "XOR logicop mode has limited support");
+         }
+         else if (templ->logicop_func != PIPE_LOGICOP_COPY) {
+            pipe_debug_message(&svga->debug.callback, CONFORMANCE,
+                               "general logicops are not supported");
+         }
       }
       else {
-         /* Note: the vgpu10 device does not yet support independent
-          * blend terms per render target.  Target[0] always specifies the
-          * blending terms.
+         /* Note: per-target blend terms are only supported for sm4_1
+          * device. For vgpu10 device, the blending terms must be identical
+          * for all targets (this is why we need the first_enabled index).
           */
-         if (templ->independent_blend_enable || templ->rt[0].blend_enable) {
-            /* always use the 0th target's blending terms for now */
+         const unsigned j =
+            svga_have_sm4_1(svga) && templ->independent_blend_enable
+            ? i : first_enabled;
+         if (templ->independent_blend_enable || templ->rt[j].blend_enable) {
             blend->rt[i].srcblend =
-               svga_translate_blend_factor(svga, templ->rt[0].rgb_src_factor);
+               svga_translate_blend_factor(svga, templ->rt[j].rgb_src_factor);
             blend->rt[i].dstblend =
-               svga_translate_blend_factor(svga, templ->rt[0].rgb_dst_factor);
+               svga_translate_blend_factor(svga, templ->rt[j].rgb_dst_factor);
             blend->rt[i].blendeq =
-               svga_translate_blend_func(templ->rt[0].rgb_func);
+               svga_translate_blend_func(templ->rt[j].rgb_func);
             blend->rt[i].srcblend_alpha =
-               svga_translate_blend_factor(svga, templ->rt[0].alpha_src_factor);
+               svga_translate_blend_factor(svga, templ->rt[j].alpha_src_factor);
             blend->rt[i].dstblend_alpha =
-               svga_translate_blend_factor(svga, templ->rt[0].alpha_dst_factor);
+               svga_translate_blend_factor(svga, templ->rt[j].alpha_dst_factor);
             blend->rt[i].blendeq_alpha =
-               svga_translate_blend_func(templ->rt[0].alpha_func);
+               svga_translate_blend_func(templ->rt[j].alpha_func);
 
             if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend ||
                 blend->rt[i].dstblend_alpha != blend->rt[i].dstblend ||
@@ -316,12 +343,15 @@ svga_create_blend_state(struct pipe_context *pipe,
    blend->independent_blend_enable = templ->independent_blend_enable;
 
    blend->alpha_to_coverage = templ->alpha_to_coverage;
+   blend->alpha_to_one = templ->alpha_to_one;
 
    if (svga_have_vgpu10(svga)) {
       define_blend_state_object(svga, blend);
    }
 
-   svga->hud.num_state_objects++;
+   svga->hud.num_blend_objects++;
+   SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws,
+                        SVGA_STATS_COUNT_BLENDSTATE);
 
    return blend;
 }
@@ -343,7 +373,7 @@ static void svga_delete_blend_state(struct pipe_context *pipe,
    struct svga_blend_state *bs =
       (struct svga_blend_state *) blend;
 
-   if (bs->id != SVGA3D_INVALID_ID) {
+   if (svga_have_vgpu10(svga) && bs->id != SVGA3D_INVALID_ID) {
       enum pipe_error ret;
 
       ret = SVGA3D_vgpu10_DestroyBlendState(svga->swc, bs->id);
@@ -361,7 +391,7 @@ static void svga_delete_blend_state(struct pipe_context *pipe,
    }
 
    FREE(blend);
-   svga->hud.num_state_objects--;
+   svga->hud.num_blend_objects--;
 }
 
 static void svga_set_blend_color( struct pipe_context *pipe,