svga: Performance fixes
[mesa.git] / src / gallium / drivers / svga / svga_state_gs.c
index 9f6885b95a26e5f831704fd1584a51e8a984acf5..670b757c45fd428831383fbba5217fef470dcf4b 100644 (file)
@@ -53,13 +53,9 @@ translate_geometry_program(struct svga_context *svga,
                            const struct svga_geometry_shader *gs,
                            const struct svga_compile_key *key)
 {
-   if (svga_have_vgpu10(svga)) {
-      return svga_tgsi_vgpu10_translate(svga, &gs->base, key,
-                                        PIPE_SHADER_GEOMETRY);
-   }
-   else {
-      return svga_tgsi_vgpu9_translate(&gs->base, key, PIPE_SHADER_GEOMETRY);
-   }
+   assert(svga_have_vgpu10(svga));
+   return svga_tgsi_vgpu10_translate(svga, &gs->base, key,
+                                     PIPE_SHADER_GEOMETRY);
 }
 
 
@@ -76,38 +72,33 @@ compile_gs(struct svga_context *svga,
    enum pipe_error ret = PIPE_ERROR;
 
    variant = translate_geometry_program(svga, gs, key);
-   if (variant == NULL) {
+   if (!variant) {
       /* some problem during translation, try the dummy shader */
       const struct tgsi_token *dummy = get_dummy_geometry_shader();
       if (!dummy) {
-         ret = PIPE_ERROR_OUT_OF_MEMORY;
-         goto fail;
+         return PIPE_ERROR_OUT_OF_MEMORY;
       }
       debug_printf("Failed to compile geometry shader, using dummy shader instead.\n");
       FREE((void *) gs->base.tokens);
       gs->base.tokens = dummy;
       variant = translate_geometry_program(svga, gs, key);
-      if (variant == NULL) {
-         ret = PIPE_ERROR;
-         goto fail;
+      if (!variant) {
+         return PIPE_ERROR;
       }
    }
 
-   ret = svga_define_shader(svga, SVGA3D_SHADERTYPE_GS, variant);
-   if (ret != PIPE_OK)
-      goto fail;
+   ret = svga_define_shader(svga, variant);
+   if (ret != PIPE_OK) {
+      svga_destroy_shader_variant(svga, variant);
+      return ret;
+   }
 
    *out_variant = variant;
 
    return PIPE_OK;
-
-fail:
-   if (variant) {
-      svga_destroy_shader_variant(svga, SVGA3D_SHADERTYPE_GS, variant);
-   }
-   return ret;
 }
 
+
 static void
 make_gs_key(struct svga_context *svga, struct svga_compile_key *key)
 {
@@ -118,99 +109,82 @@ make_gs_key(struct svga_context *svga, struct svga_compile_key *key)
    /*
     * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER
     */
-   svga_init_shader_key_common(svga, PIPE_SHADER_GEOMETRY, key);
+   svga_init_shader_key_common(svga, PIPE_SHADER_GEOMETRY, &gs->base, key);
 
    memcpy(key->generic_remap_table, gs->generic_remap_table,
           sizeof(gs->generic_remap_table));
 
    key->gs.vs_generic_outputs = svga->curr.vs->generic_outputs;
 
-   key->gs.need_prescale = svga->state.hw_clear.prescale.enabled;
+   key->gs.need_prescale = svga->state.hw_clear.prescale[0].enabled;
 
    key->gs.writes_psize = gs->base.info.writes_psize;
    key->gs.wide_point = gs->wide_point;
+   key->gs.writes_viewport_index = gs->base.info.writes_viewport_index;
+   if (key->gs.writes_viewport_index) {
+      key->gs.num_prescale = svga->state.hw_clear.num_prescale;
+   } else {
+      key->gs.num_prescale = 1;
+   }
    key->sprite_coord_enable = svga->curr.rast->templ.sprite_coord_enable;
    key->sprite_origin_lower_left = (svga->curr.rast->templ.sprite_coord_mode
                                     == PIPE_SPRITE_COORD_LOWER_LEFT);
 
    /* SVGA_NEW_RAST */
    key->clip_plane_enable = svga->curr.rast->templ.clip_plane_enable;
-}
-
-
-/**
- * svga_reemit_gs_bindings - Reemit the geometry shader bindings
- */
-enum pipe_error
-svga_reemit_gs_bindings(struct svga_context *svga)
-{
-   enum pipe_error ret;
-   struct svga_winsys_gb_shader *gbshader = NULL;
-   SVGA3dShaderId shaderId = SVGA3D_INVALID_ID;
 
-   assert(svga->rebind.flags.gs);
-   assert(svga_have_gb_objects(svga));
-
-   /* Geometry Shader is only supported in vgpu10 */
-   assert(svga_have_vgpu10(svga));
-
-   if (svga->state.hw_draw.gs) {
-      gbshader = svga->state.hw_draw.gs->gb_shader;
-      shaderId = svga->state.hw_draw.gs->id;
-   }
-
-   if (!svga_need_to_rebind_resources(svga)) {
-      ret =  svga->swc->resource_rebind(svga->swc, NULL, gbshader,
-                                        SVGA_RELOC_READ);
-      goto out;
-   }
-
-   ret = SVGA3D_vgpu10_SetShader(svga->swc, SVGA3D_SHADERTYPE_GS,
-                                 gbshader, shaderId);
-
- out:
-   if (ret != PIPE_OK)
-      return ret;
-
-   svga->rebind.flags.gs = FALSE;
-   return PIPE_OK;
+   /* Mark this as the last shader in the vertex processing stage */
+   key->last_vertex_stage = 1;
 }
 
+
 static enum pipe_error
-emit_hw_gs(struct svga_context *svga, unsigned dirty)
+emit_hw_gs(struct svga_context *svga, uint64_t dirty)
 {
    struct svga_shader_variant *variant;
    struct svga_geometry_shader *gs = svga->curr.gs;
    enum pipe_error ret = PIPE_OK;
    struct svga_compile_key key;
 
+   assert(svga_have_vgpu10(svga));
+
+   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITGS);
+
    /* If there's a user-defined GS, we should have a pointer to a derived
     * GS.  This should have been resolved in update_tgsi_transform().
     */
    if (svga->curr.user_gs)
       assert(svga->curr.gs);
 
-   if (gs == NULL) {
+   if (!gs) {
       if (svga->state.hw_draw.gs != NULL) {
 
          /** The previous geometry shader is made inactive.
           *  Needs to unbind the geometry shader.
           */
          ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL);
+         if (ret != PIPE_OK)
+            goto done;
          svga->state.hw_draw.gs = NULL;
       }
-      return ret;
+      goto done;
    }
 
    /* If there is stream output info for this geometry shader, then use
     * it instead of the one from the vertex shader.
     */
    if (svga_have_gs_streamout(svga)) {
-      svga_set_stream_output(svga, gs->base.stream_output);
+      ret = svga_set_stream_output(svga, gs->base.stream_output);
+      if (ret != PIPE_OK) {
+         goto done;
+      }
    }
    else if (!svga_have_vs_streamout(svga)) {
       /* turn off stream out */
-      svga_set_stream_output(svga, NULL);
+      ret = svga_set_stream_output(svga, NULL);
+      if (ret != PIPE_OK) {
+         goto done;
+      }
    }
 
    /* SVGA_NEW_NEED_SWTNL */
@@ -227,7 +201,7 @@ emit_hw_gs(struct svga_context *svga, unsigned dirty)
       if (!variant) {
          ret = compile_gs(svga, gs, &key, &variant);
          if (ret != PIPE_OK)
-            return ret;
+            goto done;
 
          /* insert the new variant at head of linked list */
          assert(variant);
@@ -240,14 +214,16 @@ emit_hw_gs(struct svga_context *svga, unsigned dirty)
       /* Bind the new variant */
       ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, variant);
       if (ret != PIPE_OK)
-         return ret;
+         goto done;
 
       svga->rebind.flags.gs = FALSE;
       svga->dirty |= SVGA_NEW_GS_VARIANT;
       svga->state.hw_draw.gs = variant;
    }
 
-   return PIPE_OK;
+done:
+   SVGA_STATS_TIME_POP(svga_sws(svga));
+   return ret;
 }
 
 struct svga_tracked_state svga_hw_gs =