panfrost: Simplify make_fixed_blend_mode prototype
[mesa.git] / src / gallium / drivers / zink / zink_draw.c
index a9d6bcbf08c28946a163997cc92eaa53964b7de3..b103d089df3bb1cf647073ff5afd11264cead8ad 100644 (file)
@@ -11,6 +11,7 @@
 #include "util/u_helpers.h"
 #include "util/u_inlines.h"
 #include "util/u_prim.h"
+#include "util/u_prim_restart.h"
 
 static VkDescriptorSet
 allocate_descriptor_set(struct zink_screen *screen,
@@ -159,18 +160,18 @@ zink_bind_vertex_buffers(struct zink_batch *batch, struct zink_context *ctx)
 static struct zink_gfx_program *
 get_gfx_program(struct zink_context *ctx)
 {
-   if (ctx->dirty_program) {
+   if (ctx->dirty_shader_stages) {
       struct hash_entry *entry = _mesa_hash_table_search(ctx->program_cache,
                                                          ctx->gfx_stages);
       if (!entry) {
          struct zink_gfx_program *prog;
          prog = zink_create_gfx_program(ctx, ctx->gfx_stages);
-         entry = _mesa_hash_table_insert(ctx->program_cache, prog->stages, prog);
+         entry = _mesa_hash_table_insert(ctx->program_cache, prog->shaders, prog);
          if (!entry)
             return NULL;
       }
       ctx->curr_program = entry->data;
-      ctx->dirty_program = false;
+      ctx->dirty_shader_stages = 0;
    }
 
    assert(ctx->curr_program);
@@ -196,6 +197,12 @@ line_width_needed(enum pipe_prim_type reduced_prim,
    }
 }
 
+static inline bool
+restart_supported(enum pipe_prim_type mode)
+{
+    return mode == PIPE_PRIM_LINE_STRIP || mode == PIPE_PRIM_TRIANGLE_STRIP || mode == PIPE_PRIM_TRIANGLE_FAN;
+}
+
 void
 zink_draw_vbo(struct pipe_context *pctx,
               const struct pipe_draw_info *dinfo)
@@ -206,10 +213,15 @@ zink_draw_vbo(struct pipe_context *pctx,
    struct zink_so_target *so_target = zink_so_target(dinfo->count_from_stream_output);
    VkBuffer counter_buffers[PIPE_MAX_SO_OUTPUTS];
    VkDeviceSize counter_buffer_offsets[PIPE_MAX_SO_OUTPUTS] = {};
+   bool need_index_buffer_unref = false;
+
 
+   if (dinfo->primitive_restart && !restart_supported(dinfo->mode)) {
+       util_draw_vbo_without_prim_restart(pctx, dinfo);
+       return;
+   }
    if (dinfo->mode >= PIPE_PRIM_QUADS ||
-       dinfo->mode == PIPE_PRIM_LINE_LOOP ||
-       (dinfo->index_size == 1 && !screen->have_EXT_index_type_uint8)) {
+       dinfo->mode == PIPE_PRIM_LINE_LOOP) {
       if (!u_trim_pipe_prim(dinfo->mode, (unsigned *)&dinfo->count))
          return;
 
@@ -222,6 +234,10 @@ zink_draw_vbo(struct pipe_context *pctx,
    if (!gfx_program)
       return;
 
+   if (ctx->gfx_pipeline_state.primitive_restart != !!dinfo->primitive_restart)
+      ctx->gfx_pipeline_state.hash = 0;
+   ctx->gfx_pipeline_state.primitive_restart = !!dinfo->primitive_restart;
+
    VkPipeline pipeline = zink_get_gfx_pipeline(screen, gfx_program,
                                                &ctx->gfx_pipeline_state,
                                                dinfo->mode);
@@ -249,13 +265,20 @@ zink_draw_vbo(struct pipe_context *pctx,
    unsigned index_offset = 0;
    struct pipe_resource *index_buffer = NULL;
    if (dinfo->index_size > 0) {
-      if (dinfo->has_user_indices) {
-         if (!util_upload_index_buffer(pctx, dinfo, &index_buffer, &index_offset, 4)) {
-            debug_printf("util_upload_index_buffer() failed\n");
-            return;
-         }
-      } else
-         index_buffer = dinfo->index.resource;
+       uint32_t restart_index = util_prim_restart_index_from_size(dinfo->index_size);
+       if ((dinfo->primitive_restart && (dinfo->restart_index != restart_index)) ||
+           (!screen->have_EXT_index_type_uint8 && dinfo->index_size == 8)) {
+          util_translate_prim_restart_ib(pctx, dinfo, &index_buffer);
+          need_index_buffer_unref = true;
+       } else {
+          if (dinfo->has_user_indices) {
+             if (!util_upload_index_buffer(pctx, dinfo, &index_buffer, &index_offset, 4)) {
+                debug_printf("util_upload_index_buffer() failed\n");
+                return;
+             }
+          } else
+             index_buffer = dinfo->index.resource;
+       }
    }
 
    VkWriteDescriptorSet wds[PIPE_SHADER_TYPES * PIPE_MAX_CONSTANT_BUFFERS + PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS];
@@ -274,7 +297,7 @@ zink_draw_vbo(struct pipe_context *pctx,
       if (i == MESA_SHADER_VERTEX && ctx->num_so_targets) {
          for (unsigned i = 0; i < ctx->num_so_targets; i++) {
             struct zink_so_target *t = zink_so_target(ctx->so_targets[i]);
-            t->stride = shader->stream_output.stride[i] * sizeof(uint32_t);
+            t->stride = shader->streamout.so_info.stride[i] * sizeof(uint32_t);
          }
       }
 
@@ -347,6 +370,7 @@ zink_draw_vbo(struct pipe_context *pctx,
       batch = zink_batch_rp(ctx);
       assert(batch->descs_left >= gfx_program->num_descriptors);
    }
+   zink_batch_reference_program(batch, ctx->curr_program);
 
    VkDescriptorSet desc_set = allocate_descriptor_set(screen, batch,
                                                       gfx_program);
@@ -424,7 +448,11 @@ zink_draw_vbo(struct pipe_context *pctx,
 
    if (dinfo->index_size > 0) {
       VkIndexType index_type;
-      switch (dinfo->index_size) {
+      unsigned index_size = dinfo->index_size;
+      if (need_index_buffer_unref)
+         /* index buffer will have been promoted from uint8 to uint16 in this case */
+         index_size = MAX2(index_size, 2);
+      switch (index_size) {
       case 1:
          assert(screen->have_EXT_index_type_uint8);
          index_type = VK_INDEX_TYPE_UINT8_EXT;
@@ -443,7 +471,7 @@ zink_draw_vbo(struct pipe_context *pctx,
       zink_batch_reference_resoure(batch, res);
       vkCmdDrawIndexed(batch->cmdbuf,
          dinfo->count, dinfo->instance_count,
-         dinfo->start, dinfo->index_bias, dinfo->start_instance);
+         need_index_buffer_unref ? 0 : dinfo->start, dinfo->index_bias, dinfo->start_instance);
    } else {
       if (so_target && screen->tf_props.transformFeedbackDraw) {
          zink_batch_reference_resoure(batch, zink_resource(so_target->counter_buffer));
@@ -455,7 +483,7 @@ zink_draw_vbo(struct pipe_context *pctx,
          vkCmdDraw(batch->cmdbuf, dinfo->count, dinfo->instance_count, dinfo->start, dinfo->start_instance);
    }
 
-   if (dinfo->index_size > 0 && dinfo->has_user_indices)
+   if (dinfo->index_size > 0 && (dinfo->has_user_indices || need_index_buffer_unref))
       pipe_resource_reference(&index_buffer, NULL);
 
    if (ctx->num_so_targets) {