Beispiel #1
0
static void
svga_delete_gs_state(struct pipe_context *pipe, void *shader)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_geometry_shader *gs = (struct svga_geometry_shader *)shader;
   struct svga_geometry_shader *next_gs;
   struct svga_shader_variant *variant, *tmp;
   enum pipe_error ret;

   svga_hwtnl_flush_retry(svga);

   /* Start deletion from the original geometry shader state */
   if (gs->base.parent != NULL)
      gs = (struct svga_geometry_shader *)gs->base.parent;

   /* Free the list of geometry shaders */
   while (gs) {
      next_gs = (struct svga_geometry_shader *)gs->base.next;

      if (gs->base.stream_output != NULL)
         svga_delete_stream_output(svga, gs->base.stream_output);

      draw_delete_geometry_shader(svga->swtnl.draw, gs->draw_shader);

      for (variant = gs->base.variants; variant; variant = tmp) {
         tmp = variant->next;

         /* Check if deleting currently bound shader */
         if (variant == svga->state.hw_draw.gs) {
            ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL);
            if (ret != PIPE_OK) {
               svga_context_flush(svga, NULL);
               ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL);
               assert(ret == PIPE_OK);
            }
            svga->state.hw_draw.gs = NULL;
         }

         ret = svga_destroy_shader_variant(svga, SVGA3D_SHADERTYPE_GS, variant);
         if (ret != PIPE_OK) {
            svga_context_flush(svga, NULL);
            ret = svga_destroy_shader_variant(svga, SVGA3D_SHADERTYPE_GS,
                                              variant);
            assert(ret == PIPE_OK);
         }
      }

      FREE((void *)gs->base.tokens);
      FREE(gs);
      gs = next_gs;
   }
}
Beispiel #2
0
static void
svga_delete_vs_state(struct pipe_context *pipe, void *shader)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader;
   struct svga_shader_variant *variant, *tmp;
   enum pipe_error ret;

   svga_hwtnl_flush_retry(svga);

   assert(vs->base.parent == NULL);

   /* Check if there is a generated geometry shader to go with this
    * vertex shader. If there is, then delete the geometry shader as well.
    */
   if (vs->gs != NULL) {
      svga->pipe.delete_gs_state(&svga->pipe, vs->gs);
   }

   if (vs->base.stream_output != NULL)
      svga_delete_stream_output(svga, vs->base.stream_output);

   draw_delete_vertex_shader(svga->swtnl.draw, vs->draw_shader);

   for (variant = vs->base.variants; variant; variant = tmp) {
      tmp = variant->next;

      /* Check if deleting currently bound shader */
      if (variant == svga->state.hw_draw.vs) {
         ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_VS, NULL);
         if (ret != PIPE_OK) {
            svga_context_flush(svga, NULL);
            ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_VS, NULL);
            assert(ret == PIPE_OK);
         }
         svga->state.hw_draw.vs = NULL;
      }

      ret = svga_destroy_shader_variant(svga, SVGA3D_SHADERTYPE_VS, variant);
      if (ret != PIPE_OK) {
         svga_context_flush(svga, NULL);
         ret = svga_destroy_shader_variant(svga, SVGA3D_SHADERTYPE_VS, variant);
         assert(ret == PIPE_OK);
      }
   }

   FREE((void *)vs->base.tokens);
   FREE(vs);
}
Beispiel #3
0
/**
 * Translate TGSI shader into an svga shader variant.
 */
static enum pipe_error
compile_gs(struct svga_context *svga,
           struct svga_geometry_shader *gs,
           const struct svga_compile_key *key,
           struct svga_shader_variant **out_variant)
{
   struct svga_shader_variant *variant;
   enum pipe_error ret = PIPE_ERROR;

   variant = translate_geometry_program(svga, gs, key);
   if (!variant) {
      /* some problem during translation, try the dummy shader */
      const struct tgsi_token *dummy = get_dummy_geometry_shader();
      if (!dummy) {
         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) {
         return PIPE_ERROR;
      }
   }

   ret = svga_define_shader(svga, SVGA3D_SHADERTYPE_GS, variant);
   if (ret != PIPE_OK) {
      svga_destroy_shader_variant(svga, SVGA3D_SHADERTYPE_GS, variant);
      return ret;
   }

   *out_variant = variant;

   return PIPE_OK;
}
Beispiel #4
0
/**
 * Translate TGSI shader into an svga shader variant.
 */
static enum pipe_error
compile_fs(struct svga_context *svga,
           struct svga_fragment_shader *fs,
           const struct svga_compile_key *key,
           struct svga_shader_variant **out_variant)
{
   struct svga_shader_variant *variant;
   enum pipe_error ret = PIPE_ERROR;

   variant = translate_fragment_program(svga, fs, key);
   if (variant == NULL) {
      debug_printf("Failed to compile fragment shader,"
                   " using dummy shader instead.\n");
      variant = get_compiled_dummy_shader(svga, fs, key);
   }
   else if (svga_shader_too_large(svga, variant)) {
      /* too big, use dummy shader */
      debug_printf("Shader too large (%u bytes),"
                   " using dummy shader instead.\n",
                   (unsigned) (variant->nr_tokens
                               * sizeof(variant->tokens[0])));
      /* Free the too-large variant */
      svga_destroy_shader_variant(svga, SVGA3D_SHADERTYPE_PS, variant);
      /* Use simple pass-through shader instead */
      variant = get_compiled_dummy_shader(svga, fs, key);
   }

   if (!variant) {
      return PIPE_ERROR;
   }

   ret = svga_define_shader(svga, SVGA3D_SHADERTYPE_PS, variant);
   if (ret != PIPE_OK) {
      svga_destroy_shader_variant(svga, SVGA3D_SHADERTYPE_PS, variant);
      return ret;
   }

   *out_variant = variant;

   /* insert variant at head of linked list */
   variant->next = fs->base.variants;
   fs->base.variants = variant;

   return PIPE_OK;
}
Beispiel #5
0
/**
 * Translate TGSI shader into an svga shader variant.
 */
static enum pipe_error
compile_fs(struct svga_context *svga,
           struct svga_fragment_shader *fs,
           const struct svga_fs_compile_key *key,
           struct svga_shader_variant **out_variant)
{
   struct svga_shader_variant *variant;
   enum pipe_error ret = PIPE_ERROR;

   variant = svga_translate_fragment_program( fs, key );
   if (variant == NULL) {
      debug_printf("Failed to compile fragment shader,"
                   " using dummy shader instead.\n");
      variant = get_compiled_dummy_shader(fs, key);
      if (!variant) {
         ret = PIPE_ERROR;
         goto fail;
      }
   }

   if (variant->nr_tokens * sizeof(variant->tokens[0])
       + sizeof(SVGA3dCmdDefineShader) + sizeof(SVGA3dCmdHeader)
       >= SVGA_CB_MAX_COMMAND_SIZE) {
      /* too big, use dummy shader */
      debug_printf("Shader too large (%lu bytes),"
                   " using dummy shader instead.\n",
                   (unsigned long ) variant->nr_tokens * sizeof(variant->tokens[0]));
      variant = get_compiled_dummy_shader(fs, key);
      if (!variant) {
         ret = PIPE_ERROR;
         goto fail;
      }
   }

   ret = svga_define_shader(svga, SVGA3D_SHADERTYPE_PS, variant);
   if (ret != PIPE_OK)
      goto fail;

   *out_variant = variant;

   /* insert variants at head of linked list */
   variant->next = fs->base.variants;
   fs->base.variants = variant;

   return PIPE_OK;

fail:
   if (variant) {
      svga_destroy_shader_variant(svga, SVGA3D_SHADERTYPE_PS, variant);
   }
   return ret;
}