etnaviv: introduce struct etna_compiler
[mesa.git] / src / gallium / drivers / zink / zink_program.c
index 95b47a69d934e99b4b8bfb0d780c4871769bf202..341c3293ac2a2dea0d8bd9a310603d92dfcdb6d5 100644 (file)
 #include "util/set.h"
 #include "util/u_debug.h"
 #include "util/u_memory.h"
+#include "tgsi/tgsi_from_mesa.h"
+
+struct pipeline_cache_entry {
+   struct zink_gfx_pipeline_state state;
+   VkPipeline pipeline;
+};
 
 static VkDescriptorSetLayout
 create_desc_set_layout(VkDevice dev,
@@ -108,9 +114,10 @@ equals_gfx_pipeline_state(const void *a, const void *b)
 }
 
 struct zink_gfx_program *
-zink_create_gfx_program(struct zink_screen *screen,
+zink_create_gfx_program(struct zink_context *ctx,
                         struct zink_shader *stages[PIPE_SHADER_TYPES - 1])
 {
+   struct zink_screen *screen = zink_screen(ctx->base.screen);
    struct zink_gfx_program *prog = CALLOC_STRUCT(zink_gfx_program);
    if (!prog)
       goto fail;
@@ -123,8 +130,11 @@ zink_create_gfx_program(struct zink_screen *screen,
          goto fail;
    }
 
-   for (int i = 0; i < PIPE_SHADER_TYPES - 1; ++i)
+   for (int i = 0; i < PIPE_SHADER_TYPES - 1; ++i) {
       prog->stages[i] = stages[i];
+      if (stages[i])
+         _mesa_set_add(stages[i]->programs, prog);
+   }
 
    prog->dsl = create_desc_set_layout(screen->dev, stages,
                                       &prog->num_descriptors);
@@ -148,6 +158,16 @@ fail:
    return NULL;
 }
 
+static void
+gfx_program_remove_shader(struct zink_gfx_program *prog, struct zink_shader *shader)
+{
+   enum pipe_shader_type p_stage = pipe_shader_type_from_mesa(shader->info.stage);
+
+   assert(prog->stages[p_stage] == shader);
+   prog->stages[p_stage] = NULL;
+   _mesa_set_remove_key(shader->programs, prog);
+}
+
 void
 zink_destroy_gfx_program(struct zink_screen *screen,
                          struct zink_gfx_program *prog)
@@ -158,6 +178,11 @@ zink_destroy_gfx_program(struct zink_screen *screen,
    if (prog->dsl)
       vkDestroyDescriptorSetLayout(screen->dev, prog->dsl, NULL);
 
+   for (int i = 0; i < PIPE_SHADER_TYPES - 1; ++i) {
+      if (prog->stages[i])
+         gfx_program_remove_shader(prog, prog->stages[i]);
+   }
+
    /* unref all used render-passes */
    if (prog->render_passes) {
       set_foreach(prog->render_passes, entry) {
@@ -167,14 +192,19 @@ zink_destroy_gfx_program(struct zink_screen *screen,
       _mesa_set_destroy(prog->render_passes, NULL);
    }
 
+   for (int i = 0; i < ARRAY_SIZE(prog->pipelines); ++i) {
+      hash_table_foreach(prog->pipelines[i], entry) {
+         struct pipeline_cache_entry *pc_entry = entry->data;
+
+         vkDestroyPipeline(screen->dev, pc_entry->pipeline, NULL);
+         free(pc_entry);
+      }
+      _mesa_hash_table_destroy(prog->pipelines[i], NULL);
+   }
+
    FREE(prog);
 }
 
-struct pipeline_cache_entry {
-   struct zink_gfx_pipeline_state state;
-   VkPipeline pipeline;
-};
-
 static VkPrimitiveTopology
 primitive_topology(enum pipe_prim_type mode)
 {