svga: update shader code for GBS
authorBrian Paul <brianp@vmware.com>
Sat, 8 Feb 2014 17:51:14 +0000 (09:51 -0800)
committerBrian Paul <brianp@vmware.com>
Fri, 14 Feb 2014 15:21:44 +0000 (08:21 -0700)
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
Cc: "10.1" <mesa-stable@lists.freedesktop.org>
src/gallium/drivers/svga/svga_context.c
src/gallium/drivers/svga/svga_context.h
src/gallium/drivers/svga/svga_draw.c
src/gallium/drivers/svga/svga_shader.c
src/gallium/drivers/svga/svga_state.h
src/gallium/drivers/svga/svga_state_fs.c
src/gallium/drivers/svga/svga_state_vs.c
src/gallium/drivers/svga/svga_tgsi.h

index de769cac95f4256ac72d67e929ba150a15081b31..4da9a6551f6bdf02891a17eb087502b2b9f81426 100644 (file)
@@ -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)
index 71a8eea3fe1ff1004965c0826e8dc74d1b9893e9..0daab0b322954010963d7fcb8ddbcf0f307d2350 100644 (file)
@@ -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;
index 80dbc359a62a374c0251c10b1a9658a6c3888131..fa0cac4a8c4e7bad8894f08724dd1fa7bef4700a 100644 (file)
@@ -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,
index 88877b27e98280b96f818c699294c84e2463a956..6b6b441cb828e37ec06321146ff61bdc0918e1fc 100644 (file)
@@ -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);
 
index 7051263daf00f4a51b6f56d5eab677df8fa4a1fc..3325626a4d1d4663c05134b89553c7437d1943ae 100644 (file)
@@ -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
index 7119a19f0a8da6a98067e981f10c209ebd05dc7e..dde739c121d8871404aed86868d090d3d4a08df0 100644 (file)
@@ -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;      
index aaef17ef35f7a9882e704372c3e1ca1ac233bd7f..2f130aec5b496158bf1ea43dea10538b7abde2a7 100644 (file)
@@ -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;      
index 9a0c7b8f41e27f9c8b0cefe58caacb2f988de798..4fe88b3b70d95d62983ca4ee8b109190102402e9 100644 (file)
@@ -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;
 };