[Mesa-dev] [PATCH 3/4] svga: create vgpu10 blend state objects on demand

Brian Paul brianp at vmware.com
Fri Jun 24 02:07:53 UTC 2016


Instead of creating the blend object right away, wait until state
validation time.  We'll build on this in the next commit.
---
 src/gallium/drivers/svga/svga_context.h    |  6 +++
 src/gallium/drivers/svga/svga_pipe_blend.c | 70 ++++++++++++++++++++----------
 src/gallium/drivers/svga/svga_state_rss.c  | 13 +++---
 src/gallium/drivers/svga/svga_surface.c    |  1 +
 4 files changed, 61 insertions(+), 29 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 4f1c07e..391a93a 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -631,6 +631,12 @@ void svga_init_query_functions( struct svga_context *svga );
 void svga_init_surface_functions(struct svga_context *svga);
 void svga_init_stream_output_functions( struct svga_context *svga );
 
+enum pipe_error
+svga_bind_blend_state_object(struct svga_context *svga,
+                             struct svga_blend_state *bs,
+                             const float blend_factor[4],
+                             unsigned sample_mask);
+
 void svga_cleanup_vertex_state( struct svga_context *svga );
 void svga_cleanup_tss_binding( struct svga_context *svga );
 void svga_cleanup_framebuffer( struct svga_context *svga );
diff --git a/src/gallium/drivers/svga/svga_pipe_blend.c b/src/gallium/drivers/svga/svga_pipe_blend.c
index 9a4fcc3..e10bc56 100644
--- a/src/gallium/drivers/svga/svga_pipe_blend.c
+++ b/src/gallium/drivers/svga/svga_pipe_blend.c
@@ -89,21 +89,19 @@ svga_translate_blend_func(unsigned mode)
 
 
 /**
- * Define a vgpu10 blend state object for the given
- * svga blend state.
+ * Define a vgpu10 blend state object for the given svga blend state using
+ * the given ID number.
  */
-static void
+static enum pipe_error
 define_blend_state_object(struct svga_context *svga,
-                          struct svga_blend_state *bs)
+                          struct svga_blend_state *bs,
+                          unsigned id)
 {
    SVGA3dDXBlendStatePerRT perRT[SVGA3D_MAX_RENDER_TARGETS];
-   unsigned try;
    int i;
 
    assert(svga_have_vgpu10(svga));
 
-   bs->id = util_bitmask_add(svga->blend_object_id_bm);
-
    for (i = 0; i < SVGA3D_DX_MAX_RENDER_TARGETS; i++) {
       perRT[i].blendEnable = bs->rt[i].blend_enable;
       perRT[i].srcBlend = bs->rt[i].srcblend;
@@ -118,19 +116,47 @@ define_blend_state_object(struct svga_context *svga,
       assert(perRT[i].srcBlend == perRT[0].srcBlend);
    }
 
-   /* Loop in case command buffer is full and we need to flush and retry */
-   for (try = 0; try < 2; try++) {
-      enum pipe_error ret;
+   return SVGA3D_vgpu10_DefineBlendState(svga->swc,
+                                         id,
+                                         bs->alpha_to_coverage,
+                                         bs->independent_blend_enable,
+                                         perRT);
+}
 
-      ret = SVGA3D_vgpu10_DefineBlendState(svga->swc,
-                                           bs->id,
-                                           bs->alpha_to_coverage,
-                                           bs->independent_blend_enable,
-                                           perRT);
-      if (ret == PIPE_OK)
-         return;
-      svga_context_flush(svga, NULL);
+
+/**
+ * Called from the state validation code to bind the given blend state.
+ * The VGPU10 blend state object will be created on demand.
+ */
+enum pipe_error
+svga_bind_blend_state_object(struct svga_context *svga,
+                             struct svga_blend_state *bs,
+                             const float blend_factor[4],
+                             unsigned sample_mask)
+{
+   enum pipe_error ret;
+   unsigned obj_id;
+
+   assert(svga_have_vgpu10(svga));
+
+   if (bs->id != SVGA3D_INVALID_ID) {
+      obj_id = bs->id;
+   }
+   else {
+      /* create blend state object */
+      obj_id = util_bitmask_add(svga->blend_object_id_bm);
+      bs->id = obj_id;
+
+      ret = define_blend_state_object(svga, bs, obj_id);
+      if (ret != PIPE_OK) {
+         util_bitmask_clear(svga->blend_object_id_bm, obj_id);
+         return ret;
+      }
    }
+
+   ret = SVGA3D_vgpu10_SetBlendState(svga->swc, obj_id,
+                                     blend_factor, sample_mask);
+   return ret;
 }
 
 
@@ -329,9 +355,8 @@ svga_create_blend_state(struct pipe_context *pipe,
 
    blend->alpha_to_coverage = templ->alpha_to_coverage;
 
-   if (svga_have_vgpu10(svga)) {
-      define_blend_state_object(svga, blend);
-   }
+   /* blend state objects will be created on demand */
+   blend->id = SVGA3D_INVALID_ID;
 
    svga->hud.num_blend_objects++;
 
@@ -352,8 +377,7 @@ static void svga_delete_blend_state(struct pipe_context *pipe,
                                     void *blend)
 {
    struct svga_context *svga = svga_context(pipe);
-   struct svga_blend_state *bs =
-      (struct svga_blend_state *) blend;
+   struct svga_blend_state *bs = (struct svga_blend_state *) blend;
 
    if (bs->id != SVGA3D_INVALID_ID) {
       enum pipe_error ret;
diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c
index e22268d..1540899 100644
--- a/src/gallium/drivers/svga/svga_state_rss.c
+++ b/src/gallium/drivers/svga/svga_state_rss.c
@@ -343,8 +343,8 @@ emit_rss_vgpu10(struct svga_context *svga, unsigned dirty)
 
    svga_hwtnl_flush_retry(svga);
 
-   if (dirty & (SVGA_NEW_BLEND | SVGA_NEW_BLEND_COLOR)) {
-      const struct svga_blend_state *curr;
+   if (dirty & (SVGA_NEW_BLEND | SVGA_NEW_BLEND_COLOR | SVGA_NEW_FRAME_BUFFER)) {
+      struct svga_blend_state *curr;
       float blend_factor[4];
 
       if (svga_has_any_integer_cbufs(svga)) {
@@ -356,7 +356,8 @@ emit_rss_vgpu10(struct svga_context *svga, unsigned dirty)
          blend_factor[3] = 0;
       }
       else {
-         curr = svga->curr.blend;
+         /* cast-away const */
+         curr = (struct svga_blend_state *) svga->curr.blend;
 
          if (curr->blend_color_alpha) {
             blend_factor[0] =
@@ -379,9 +380,9 @@ emit_rss_vgpu10(struct svga_context *svga, unsigned dirty)
           svga->state.hw_draw.blend_factor[2] != blend_factor[2] ||
           svga->state.hw_draw.blend_factor[3] != blend_factor[3] ||
           svga->state.hw_draw.blend_sample_mask != svga->curr.sample_mask) {
-         ret = SVGA3D_vgpu10_SetBlendState(svga->swc, curr->id,
-                                           blend_factor,
-                                           svga->curr.sample_mask);
+         ret = svga_bind_blend_state_object(svga, curr,
+                                            blend_factor,
+                                            svga->curr.sample_mask);
          if (ret != PIPE_OK)
             return ret;
 
diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c
index ad06a1d..5af3a89 100644
--- a/src/gallium/drivers/svga/svga_surface.c
+++ b/src/gallium/drivers/svga/svga_surface.c
@@ -238,6 +238,7 @@ svga_create_surface_view(struct pipe_context *pipe,
    s->base.format = surf_tmpl->format;
    s->base.width = u_minify(pt->width0, surf_tmpl->u.tex.level);
    s->base.height = u_minify(pt->height0, surf_tmpl->u.tex.level);
+   s->base.alpha_one = surf_tmpl->alpha_one;
    s->base.u.tex.level = surf_tmpl->u.tex.level;
    s->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
    s->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
-- 
1.9.1



More information about the mesa-dev mailing list