Mesa (main): lavapipe: use cso caching

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jun 11 17:42:42 UTC 2021


Module: Mesa
Branch: main
Commit: 5b3e8d3d6f1be2e17523d3aab720f4f6584b5cdc
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5b3e8d3d6f1be2e17523d3aab720f4f6584b5cdc

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Thu Jun 10 16:51:39 2021 -0400

lavapipe: use cso caching

really this only needs cso_cache api, but it's cumbersome to redo all
the hashing and state creation, so just use the whole context

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11071>

---

 src/gallium/frontends/lavapipe/lvp_device.c  |   2 +
 src/gallium/frontends/lavapipe/lvp_execute.c | 133 ++++++---------------------
 src/gallium/frontends/lavapipe/lvp_private.h |   2 +
 3 files changed, 33 insertions(+), 104 deletions(-)

diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c
index 0febdc17607..7b6859507a4 100644
--- a/src/gallium/frontends/lavapipe/lvp_device.c
+++ b/src/gallium/frontends/lavapipe/lvp_device.c
@@ -1137,6 +1137,7 @@ lvp_queue_init(struct lvp_device *device, struct lvp_queue *queue)
 
    queue->flags = 0;
    queue->ctx = device->pscreen->context_create(device->pscreen, NULL, PIPE_CONTEXT_ROBUST_BUFFER_ACCESS);
+   queue->cso = cso_create_context(queue->ctx, CSO_NO_VBUF);
    list_inithead(&queue->workqueue);
    p_atomic_set(&queue->count, 0);
    mtx_init(&queue->m, mtx_plain);
@@ -1158,6 +1159,7 @@ lvp_queue_finish(struct lvp_queue *queue)
 
    cnd_destroy(&queue->new_work);
    mtx_destroy(&queue->m);
+   cso_destroy_context(queue->cso);
    queue->ctx->destroy(queue->ctx);
 }
 
diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c
index 5fd213ce19a..6987a43a8c8 100644
--- a/src/gallium/frontends/lavapipe/lvp_execute.c
+++ b/src/gallium/frontends/lavapipe/lvp_execute.c
@@ -47,6 +47,7 @@
 
 struct rendering_state {
    struct pipe_context *pctx;
+   struct cso_context *cso;
 
    bool blend_dirty;
    bool rs_dirty;
@@ -70,11 +71,8 @@ struct rendering_state {
    struct pipe_framebuffer_state framebuffer;
 
    struct pipe_blend_state blend_state;
-   void *blend_handle;
    struct pipe_rasterizer_state rs_state;
-   void *rast_handle;
    struct pipe_depth_stencil_alpha_state dsa_state;
-   void *dsa_handle;
 
    struct pipe_blend_color blend_color;
    struct pipe_stencil_ref stencil_ref;
@@ -95,12 +93,13 @@ struct rendering_state {
    int num_vb;
    unsigned start_vb;
    struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
-   int num_ve;
-   struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
+   struct cso_velems_state velem;
 
    struct pipe_sampler_view *sv[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
    int num_sampler_views[PIPE_SHADER_TYPES];
    struct pipe_sampler_state ss[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
+   /* cso_context api is stupid */
+   const struct pipe_sampler_state *cso_ss_ptr[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
    int num_sampler_states[PIPE_SHADER_TYPES];
    bool sv_dirty[PIPE_SHADER_TYPES];
    bool ss_dirty[PIPE_SHADER_TYPES];
@@ -203,47 +202,27 @@ static void emit_state(struct rendering_state *state)
 {
    int sh;
    if (state->blend_dirty) {
-      if (state->blend_handle) {
-         state->pctx->bind_blend_state(state->pctx, NULL);
-         state->pctx->delete_blend_state(state->pctx, state->blend_handle);
-      }
-      state->blend_handle = state->pctx->create_blend_state(state->pctx,
-                                                            &state->blend_state);
-      state->pctx->bind_blend_state(state->pctx, state->blend_handle);
-
+      cso_set_blend(state->cso, &state->blend_state);
       state->blend_dirty = false;
    }
 
    if (state->rs_dirty) {
-      if (state->rast_handle) {
-         state->pctx->bind_rasterizer_state(state->pctx, NULL);
-         state->pctx->delete_rasterizer_state(state->pctx, state->rast_handle);
-      }
-      state->rast_handle = state->pctx->create_rasterizer_state(state->pctx,
-                                                                &state->rs_state);
-      state->pctx->bind_rasterizer_state(state->pctx, state->rast_handle);
+      cso_set_rasterizer(state->cso, &state->rs_state);
       state->rs_dirty = false;
    }
 
    if (state->dsa_dirty) {
-      if (state->dsa_handle) {
-         state->pctx->bind_depth_stencil_alpha_state(state->pctx, NULL);
-         state->pctx->delete_depth_stencil_alpha_state(state->pctx, state->dsa_handle);
-      }
-      state->dsa_handle = state->pctx->create_depth_stencil_alpha_state(state->pctx,
-                                                                        &state->dsa_state);
-      state->pctx->bind_depth_stencil_alpha_state(state->pctx, state->dsa_handle);
-
+      cso_set_depth_stencil_alpha(state->cso, &state->dsa_state);
       state->dsa_dirty = false;
    }
 
    if (state->sample_mask_dirty) {
-      state->pctx->set_sample_mask(state->pctx, state->sample_mask);
+      cso_set_sample_mask(state->cso, state->sample_mask);
       state->sample_mask_dirty = false;
    }
 
    if (state->min_samples_dirty) {
-      state->pctx->set_min_samples(state->pctx, state->min_samples);
+      cso_set_min_samples(state->cso, state->min_samples);
       state->min_samples_dirty = false;
    }
 
@@ -253,28 +232,20 @@ static void emit_state(struct rendering_state *state)
    }
 
    if (state->stencil_ref_dirty) {
-      state->pctx->set_stencil_ref(state->pctx, state->stencil_ref);
+      cso_set_stencil_ref(state->cso, state->stencil_ref);
       state->stencil_ref_dirty = false;
    }
 
    if (state->vb_dirty) {
-      state->pctx->set_vertex_buffers(state->pctx, state->start_vb,
-                                      state->num_vb, 0, false, state->vb);
+      cso_set_vertex_buffers(state->cso, state->start_vb, state->num_vb, state->vb);
       state->vb_dirty = false;
    }
 
    if (state->ve_dirty) {
-      void *ve = NULL;
-      if (state->velems_cso)
-         ve = state->velems_cso;
-
-      state->velems_cso = state->pctx->create_vertex_elements_state(state->pctx, state->num_ve,
-                                                                    state->ve);
-      state->pctx->bind_vertex_elements_state(state->pctx, state->velems_cso);
-
-      if (ve)
-         state->pctx->delete_vertex_elements_state(state->pctx, ve);
+      cso_set_vertex_elements(state->cso, &state->velem);
+      state->ve_dirty = false;
    }
+   
 
    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
       if (state->constbuf_dirty[sh]) {
@@ -319,17 +290,10 @@ static void emit_state(struct rendering_state *state)
    }
 
    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
-      int i;
       if (!state->ss_dirty[sh])
          continue;
 
-      for (i = 0; i < state->num_sampler_states[sh]; i++) {
-         if (state->ss_cso[sh][i])
-            state->pctx->delete_sampler_state(state->pctx, state->ss_cso[sh][i]);
-         state->ss_cso[sh][i] = state->pctx->create_sampler_state(state->pctx, &state->ss[sh][i]);
-      }
-
-      state->pctx->bind_sampler_states(state->pctx, sh, 0, state->num_sampler_states[sh], state->ss_cso[sh]);
+      cso_set_samplers(state->cso, sh, state->num_sampler_states[sh], state->cso_ss_ptr[sh]);
    }
 
    if (state->vp_dirty) {
@@ -640,26 +604,26 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
       int max_location = -1;
       for (i = 0; i < vi->vertexAttributeDescriptionCount; i++) {
          unsigned location = vi->pVertexAttributeDescriptions[i].location;
-         state->ve[location].src_offset = vi->pVertexAttributeDescriptions[i].offset;
-         state->ve[location].vertex_buffer_index = vi->pVertexAttributeDescriptions[i].binding;
-         state->ve[location].src_format = vk_format_to_pipe(vi->pVertexAttributeDescriptions[i].format);
+         state->velem.velems[location].src_offset = vi->pVertexAttributeDescriptions[i].offset;
+         state->velem.velems[location].vertex_buffer_index = vi->pVertexAttributeDescriptions[i].binding;
+         state->velem.velems[location].src_format = vk_format_to_pipe(vi->pVertexAttributeDescriptions[i].format);
 
          switch (vi->pVertexBindingDescriptions[vi->pVertexAttributeDescriptions[i].binding].inputRate) {
          case VK_VERTEX_INPUT_RATE_VERTEX:
-            state->ve[location].instance_divisor = 0;
+            state->velem.velems[location].instance_divisor = 0;
             break;
          case VK_VERTEX_INPUT_RATE_INSTANCE:
             if (div_state) {
                for (unsigned j = 0; j < div_state->vertexBindingDivisorCount; j++) {
                   const VkVertexInputBindingDivisorDescriptionEXT *desc =
                      &div_state->pVertexBindingDivisors[j];
-                  if (desc->binding == state->ve[location].vertex_buffer_index) {
-                     state->ve[location].instance_divisor = desc->divisor;
+                  if (desc->binding == state->velem.velems[location].vertex_buffer_index) {
+                     state->velem.velems[location].instance_divisor = desc->divisor;
                      break;
                   }
                }
             } else
-               state->ve[location].instance_divisor = 1;
+               state->velem.velems[location].instance_divisor = 1;
             break;
          default:
             assert(0);
@@ -669,7 +633,7 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
          if ((int)location > max_location)
             max_location = location;
       }
-      state->num_ve = max_location + 1;
+      state->velem.count = max_location + 1;
       state->vb_dirty = true;
       state->ve_dirty = true;
    }
@@ -3148,60 +3112,21 @@ VkResult lvp_execute_cmds(struct lvp_device *device,
    struct rendering_state state;
    memset(&state, 0, sizeof(state));
    state.pctx = queue->ctx;
+   state.cso = queue->cso;
    state.blend_dirty = true;
    state.dsa_dirty = true;
    state.rs_dirty = true;
    state.vp_dirty = true;
+   for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) {
+      for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++)
+         state.cso_ss_ptr[s][i] = &state.ss[s][i];
+   }
    /* create a gallium context */
    lvp_execute_cmd_buffer(cmd_buffer, &state);
 
    state.start_vb = -1;
    state.num_vb = 0;
-   state.pctx->set_vertex_buffers(state.pctx, 0, 0, PIPE_MAX_ATTRIBS, false, NULL);
-   state.pctx->bind_vertex_elements_state(state.pctx, NULL);
-   state.pctx->bind_vs_state(state.pctx, NULL);
-   state.pctx->bind_fs_state(state.pctx, NULL);
-   state.pctx->bind_gs_state(state.pctx, NULL);
-   if (state.pctx->bind_tcs_state)
-      state.pctx->bind_tcs_state(state.pctx, NULL);
-   if (state.pctx->bind_tes_state)
-      state.pctx->bind_tes_state(state.pctx, NULL);
-   if (state.pctx->bind_compute_state)
-      state.pctx->bind_compute_state(state.pctx, NULL);
-   if (state.velems_cso)
-      state.pctx->delete_vertex_elements_state(state.pctx, state.velems_cso);
-
-   state.pctx->bind_rasterizer_state(state.pctx, NULL);
-   state.pctx->delete_rasterizer_state(state.pctx, state.rast_handle);
-   if (state.blend_handle) {
-      state.pctx->bind_blend_state(state.pctx, NULL);
-      state.pctx->delete_blend_state(state.pctx, state.blend_handle);
-   }
-
-   if (state.dsa_handle) {
-      state.pctx->bind_depth_stencil_alpha_state(state.pctx, NULL);
-      state.pctx->delete_depth_stencil_alpha_state(state.pctx, state.dsa_handle);
-   }
-
-   for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) {
-      for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-         if (state.sv[s][i])
-            pipe_sampler_view_reference(&state.sv[s][i], NULL);
-         if (state.ss_cso[s][i]) {
-            state.pctx->delete_sampler_state(state.pctx, state.ss_cso[s][i]);
-            state.ss_cso[s][i] = NULL;
-         }
-      }
-      state.pctx->bind_sampler_states(state.pctx, s, 0, PIPE_MAX_SAMPLERS, state.ss_cso[s]);
-
-      state.pctx->set_shader_images(state.pctx, s, 0, 0, device->physical_device->max_images, NULL);
-
-      state.pctx->set_constant_buffer(state.pctx, s, 0, false, NULL);
-      for (unsigned idx = 0; idx < state.num_const_bufs[s]; idx++)
-         state.pctx->set_constant_buffer(state.pctx, s, idx + 1, false, NULL);
-   }
-
-   state.pctx->set_stream_output_targets(state.pctx, 0, NULL, NULL);
+   cso_unbind_context(queue->cso);
    for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
       if (state.so_targets[i]) {
          state.pctx->stream_output_target_destroy(state.pctx, state.so_targets[i]);
diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h
index 361a4d236e7..86004ba4be6 100644
--- a/src/gallium/frontends/lavapipe/lvp_private.h
+++ b/src/gallium/frontends/lavapipe/lvp_private.h
@@ -35,6 +35,7 @@
 #include "compiler/shader_enums.h"
 #include "pipe/p_screen.h"
 #include "pipe/p_state.h"
+#include "cso_cache/cso_context.h"
 #include "nir.h"
 
 /* Pre-declarations needed for WSI entrypoints */
@@ -162,6 +163,7 @@ struct lvp_queue {
    VkDeviceQueueCreateFlags flags;
    struct lvp_device *                         device;
    struct pipe_context *ctx;
+   struct cso_context *cso;
    bool shutdown;
    thrd_t exec_thread;
    mtx_t m;



More information about the mesa-commit mailing list