[Mesa-dev] [PATCH 07/19] svga: update shader code for GBS

Brian Paul brianp at vmware.com
Thu Feb 13 17:20:59 PST 2014


Reviewed-by: Thomas Hellstrom <thellstrom at vmware.com>
Cc: "10.1" <mesa-stable at lists.freedesktop.org>
---
 src/gallium/drivers/svga/svga_context.c  |    4 +++
 src/gallium/drivers/svga/svga_context.h  |    2 ++
 src/gallium/drivers/svga/svga_draw.c     |   14 ++++++++
 src/gallium/drivers/svga/svga_shader.c   |   21 ++++++++++-
 src/gallium/drivers/svga/svga_state.h    |    4 +++
 src/gallium/drivers/svga/svga_state_fs.c |   58 ++++++++++++++++++++++++------
 src/gallium/drivers/svga/svga_state_vs.c |   56 ++++++++++++++++++++++++-----
 src/gallium/drivers/svga/svga_tgsi.h     |    3 ++
 8 files changed, 142 insertions(+), 20 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index de769ca..4da9a65 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -197,6 +197,10 @@ void svga_context_flush( struct svga_context *svga,
     */
    svga->rebind.rendertargets = TRUE;
    svga->rebind.texture_samplers = TRUE;
+   if (svga_have_gb_objects(svga)) {
+      svga->rebind.vs = TRUE;
+      svga->rebind.fs = TRUE;
+   }
 
    if (SVGA_DEBUG & DEBUG_SYNC) {
       if (fence)
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 71a8eea..0daab0b 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -374,6 +374,8 @@ struct svga_context
    struct {
       unsigned rendertargets:1;
       unsigned texture_samplers:1;
+      unsigned vs:1;
+      unsigned fs:1;
    } rebind;
 
    struct svga_hwtnl *hwtnl;
diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c
index 80dbc35..fa0cac4 100644
--- a/src/gallium/drivers/svga/svga_draw.c
+++ b/src/gallium/drivers/svga/svga_draw.c
@@ -213,6 +213,20 @@ svga_hwtnl_flush(struct svga_hwtnl *hwtnl)
          }
       }
 
+      if (svga->rebind.vs) {
+         ret = svga_reemit_vs_bindings(svga);
+         if (ret != PIPE_OK) {
+            return ret;
+         }
+      }
+
+      if (svga->rebind.fs) {
+         ret = svga_reemit_fs_bindings(svga);
+         if (ret != PIPE_OK) {
+            return ret;
+         }
+      }
+
       SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n",
                svga->curr.framebuffer.cbufs[0] ?
                svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL,
diff --git a/src/gallium/drivers/svga/svga_shader.c b/src/gallium/drivers/svga/svga_shader.c
index 88877b2..6b6b441 100644
--- a/src/gallium/drivers/svga/svga_shader.c
+++ b/src/gallium/drivers/svga/svga_shader.c
@@ -43,7 +43,17 @@ svga_define_shader(struct svga_context *svga,
 {
    unsigned codeLen = variant->nr_tokens * sizeof(variant->tokens[0]);
 
-   {
+   if (svga_have_gb_objects(svga)) {
+      struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
+
+      variant->gb_shader = sws->shader_create(sws, type,
+                                              variant->tokens, codeLen);
+      if (!variant->gb_shader)
+         return PIPE_ERROR_OUT_OF_MEMORY;
+
+      return PIPE_OK;
+   }
+   else {
       enum pipe_error ret;
 
       /* Allocate an integer ID for the shader */
@@ -79,6 +89,14 @@ svga_destroy_shader_variant(struct svga_context *svga,
 {
    enum pipe_error ret = PIPE_OK;
 
+   if (svga_have_gb_objects(svga)) {
+      struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
+
+      sws->shader_destroy(sws, variant->gb_shader);
+      variant->gb_shader = NULL;
+      goto end;
+   }
+
    /* first try */
    if (variant->id != UTIL_BITMASK_INVALID_INDEX) {
       ret = SVGA3D_DestroyShader(svga->swc, variant->id, type);
@@ -94,6 +112,7 @@ svga_destroy_shader_variant(struct svga_context *svga,
       util_bitmask_clear(svga->shader_id_bm, variant->id);
    }
 
+end:
    FREE((unsigned *)variant->tokens);
    FREE(variant);
 
diff --git a/src/gallium/drivers/svga/svga_state.h b/src/gallium/drivers/svga/svga_state.h
index 7051263..3325626 100644
--- a/src/gallium/drivers/svga/svga_state.h
+++ b/src/gallium/drivers/svga/svga_state.h
@@ -95,4 +95,8 @@ enum pipe_error svga_reemit_framebuffer_bindings( struct svga_context *svga );
 
 enum pipe_error svga_reemit_tss_bindings( struct svga_context *svga );
 
+enum pipe_error svga_reemit_vs_bindings(struct svga_context *svga);
+
+enum pipe_error svga_reemit_fs_bindings(struct svga_context *svga);
+
 #endif
diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c
index 7119a19..dde739c 100644
--- a/src/gallium/drivers/svga/svga_state_fs.c
+++ b/src/gallium/drivers/svga/svga_state_fs.c
@@ -321,13 +321,36 @@ make_fs_key(const struct svga_context *svga,
 }
 
 
+/**
+ * svga_reemit_fs_bindings - Reemit the fragment shader bindings
+ */
+enum pipe_error
+svga_reemit_fs_bindings(struct svga_context *svga)
+{
+   enum pipe_error ret;
+
+   assert(svga->rebind.fs);
+   assert(svga_have_gb_objects(svga));
+
+   if (!svga->state.hw_draw.fs)
+      return PIPE_OK;
+
+   ret = SVGA3D_SetGBShader(svga->swc, SVGA3D_SHADERTYPE_PS,
+                            svga->state.hw_draw.fs->gb_shader);
+   if (ret != PIPE_OK)
+      return ret;
+
+   svga->rebind.fs = FALSE;
+   return PIPE_OK;
+}
+
+
+
 static enum pipe_error
 emit_hw_fs(struct svga_context *svga, unsigned dirty)
 {
    struct svga_shader_variant *variant = NULL;
-   unsigned id = SVGA3D_INVALID_ID;
    enum pipe_error ret = PIPE_OK;
-
    struct svga_fragment_shader *fs = svga->curr.fs;
    struct svga_fs_compile_key key;
 
@@ -349,17 +372,30 @@ emit_hw_fs(struct svga_context *svga, unsigned dirty)
          return ret;
    }
 
-   assert (variant);
-   id = variant->id;
-
-   assert(id != SVGA3D_INVALID_ID);
+   assert(variant);
 
    if (variant != svga->state.hw_draw.fs) {
-      ret = SVGA3D_SetShader(svga->swc,
-                             SVGA3D_SHADERTYPE_PS,
-                             id );
-      if (ret != PIPE_OK)
-         return ret;
+      if (svga_have_gb_objects(svga)) {
+         /*
+          * Bind is necessary here only because pipebuffer_fenced may move
+          * the shader contents around....
+          */
+         ret = SVGA3D_BindGBShader(svga->swc, variant->gb_shader);
+         if (ret != PIPE_OK)
+            return ret;
+
+         ret = SVGA3D_SetGBShader(svga->swc, SVGA3D_SHADERTYPE_PS,
+                                  variant->gb_shader);
+         if (ret != PIPE_OK)
+            return ret;
+
+         svga->rebind.fs = FALSE;
+      }
+      else {
+         ret = SVGA3D_SetShader(svga->swc, SVGA3D_SHADERTYPE_PS, variant->id);
+         if (ret != PIPE_OK)
+            return ret;
+      }
 
       svga->dirty |= SVGA_NEW_FS_VARIANT;
       svga->state.hw_draw.fs = variant;      
diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c
index aaef17e..2f130aec 100644
--- a/src/gallium/drivers/svga/svga_state_vs.c
+++ b/src/gallium/drivers/svga/svga_state_vs.c
@@ -162,12 +162,32 @@ make_vs_key(struct svga_context *svga, struct svga_vs_compile_key *key)
 }
 
 
+/**
+ * svga_reemit_vs_bindings - Reemit the vertex shader bindings
+ */
+enum pipe_error
+svga_reemit_vs_bindings(struct svga_context *svga)
+{
+   enum pipe_error ret;
+   struct svga_winsys_gb_shader *gbshader =
+      svga->state.hw_draw.vs ? svga->state.hw_draw.vs->gb_shader : NULL;
+
+   assert(svga->rebind.vs);
+   assert(svga_have_gb_objects(svga));
+
+   ret = SVGA3D_SetGBShader(svga->swc, SVGA3D_SHADERTYPE_VS, gbshader);
+   if (ret != PIPE_OK)
+      return ret;
+
+   svga->rebind.vs = FALSE;
+   return PIPE_OK;
+}
+
 
 static enum pipe_error
 emit_hw_vs(struct svga_context *svga, unsigned dirty)
 {
    struct svga_shader_variant *variant = NULL;
-   unsigned id = SVGA3D_INVALID_ID;
    enum pipe_error ret = PIPE_OK;
 
    /* SVGA_NEW_NEED_SWTNL */
@@ -184,16 +204,36 @@ emit_hw_vs(struct svga_context *svga, unsigned dirty)
             return ret;
       }
 
-      assert (variant);
-      id = variant->id;
+      assert(variant);
    }
 
    if (variant != svga->state.hw_draw.vs) {
-      ret = SVGA3D_SetShader(svga->swc,
-                             SVGA3D_SHADERTYPE_VS,
-                             id );
-      if (ret != PIPE_OK)
-         return ret;
+      if (svga_have_gb_objects(svga)) {
+         struct svga_winsys_gb_shader *gbshader =
+            variant ? variant->gb_shader : NULL;
+
+         /*
+          * Bind is necessary here only because pipebuffer_fenced may move
+          * the shader contents around....
+          */
+         if (gbshader) {
+            ret = SVGA3D_BindGBShader(svga->swc, gbshader);
+            if (ret != PIPE_OK)
+               return ret;
+         }
+
+         ret = SVGA3D_SetGBShader(svga->swc, SVGA3D_SHADERTYPE_VS, gbshader);
+         if (ret != PIPE_OK)
+            return ret;
+
+         svga->rebind.vs = FALSE;
+      }
+      else {
+         unsigned id = variant ? variant->id : SVGA_ID_INVALID;
+         ret = SVGA3D_SetShader(svga->swc, SVGA3D_SHADERTYPE_VS, id);
+         if (ret != PIPE_OK)
+            return ret;
+      }
 
       svga->dirty |= SVGA_NEW_VS_VARIANT;
       svga->state.hw_draw.vs = variant;      
diff --git a/src/gallium/drivers/svga/svga_tgsi.h b/src/gallium/drivers/svga/svga_tgsi.h
index 9a0c7b8..4fe88b3 100644
--- a/src/gallium/drivers/svga/svga_tgsi.h
+++ b/src/gallium/drivers/svga/svga_tgsi.h
@@ -106,6 +106,9 @@ struct svga_shader_variant
     */
    unsigned id;
    
+   /* GB object buffer containing the bytecode */
+   struct svga_winsys_gb_shader *gb_shader;
+
    /** Next variant */
    struct svga_shader_variant *next;
 };
-- 
1.7.10.4



More information about the mesa-dev mailing list