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;
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 */
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.
*/
}
}
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 ||
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;
}
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);
}
FREE(blend);
- svga->hud.num_state_objects--;
+ svga->hud.num_blend_objects--;
}
static void svga_set_blend_color( struct pipe_context *pipe,