swr: add fetch shader cache
authorGeorge Kyriazis <george.kyriazis@intel.com>
Fri, 10 Feb 2017 16:24:32 +0000 (10:24 -0600)
committerTim Rowley <timothy.o.rowley@intel.com>
Thu, 23 Feb 2017 22:36:13 +0000 (16:36 -0600)
For now, the cache key is all of FETCH_COMPILE_STATE.

Use new/delete for swr_vertex_element_state, since we have to call the
constructors/destructors of the struct elements.

Reviewed-by: Bruce Cherniak <bruce.cherniak@intel.com>
src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.h
src/gallium/drivers/swr/swr_draw.cpp
src/gallium/drivers/swr/swr_shader.cpp
src/gallium/drivers/swr/swr_shader.h
src/gallium/drivers/swr/swr_state.cpp
src/gallium/drivers/swr/swr_state.h

index 1547453..622608a 100644 (file)
@@ -94,7 +94,7 @@ enum ComponentControl
 //////////////////////////////////////////////////////////////////////////
 struct FETCH_COMPILE_STATE
 {
-    uint32_t numAttribs;
+    uint32_t numAttribs {0};
     INPUT_ELEMENT_DESC layout[KNOB_NUM_ATTRIBUTES];
     SWR_FORMAT indexType;
     uint32_t cutIndex{ 0xffffffff };
index c4d5e5c..4bdd3bb 100644 (file)
@@ -141,19 +141,22 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    }
 
    struct swr_vertex_element_state *velems = ctx->velems;
-   if (!velems->fsFunc
-       || (velems->fsState.cutIndex != info->restart_index)
-       || (velems->fsState.bEnableCutIndex != info->primitive_restart)) {
-
-      velems->fsState.cutIndex = info->restart_index;
-      velems->fsState.bEnableCutIndex = info->primitive_restart;
-
-      /* Create Fetch Shader */
+   velems->fsState.cutIndex = info->restart_index;
+   velems->fsState.bEnableCutIndex = info->primitive_restart;
+
+   swr_jit_fetch_key key;
+   swr_generate_fetch_key(key, velems);
+   auto search = velems->map.find(key);
+   if (search != velems->map.end()) {
+      velems->fsFunc = search->second;
+   } else {
       HANDLE hJitMgr = swr_screen(ctx->pipe.screen)->hJitMgr;
       velems->fsFunc = JitCompileFetch(hJitMgr, velems->fsState);
 
       debug_printf("fetch shader %p\n", velems->fsFunc);
       assert(velems->fsFunc && "Error: FetchShader = NULL");
+
+      velems->map.insert(std::make_pair(key, velems->fsFunc));
    }
 
    SwrSetFetchFunc(ctx->swrContext, velems->fsFunc);
index 979a28b..676938c 100644 (file)
@@ -61,6 +61,11 @@ bool operator==(const swr_jit_vs_key &lhs, const swr_jit_vs_key &rhs)
    return !memcmp(&lhs, &rhs, sizeof(lhs));
 }
 
+bool operator==(const swr_jit_fetch_key &lhs, const swr_jit_fetch_key &rhs)
+{
+   return !memcmp(&lhs, &rhs, sizeof(lhs));
+}
+
 static void
 swr_generate_sampler_key(const struct lp_tgsi_info &info,
                          struct swr_context *ctx,
@@ -157,6 +162,15 @@ swr_generate_vs_key(struct swr_jit_vs_key &key,
    swr_generate_sampler_key(swr_vs->info, ctx, PIPE_SHADER_VERTEX, key);
 }
 
+void
+swr_generate_fetch_key(struct swr_jit_fetch_key &key,
+                       struct swr_vertex_element_state *velems)
+{
+   memset(&key, 0, sizeof(key));
+
+   key.fsState = velems->fsState;
+}
+
 struct BuilderSWR : public Builder {
    BuilderSWR(JitManager *pJitMgr, const char *pName)
       : Builder(pJitMgr)
index 7e3399c..266573f 100644 (file)
@@ -42,6 +42,9 @@ void swr_generate_vs_key(struct swr_jit_vs_key &key,
                          struct swr_context *ctx,
                          swr_vertex_shader *swr_vs);
 
+void swr_generate_fetch_key(struct swr_jit_fetch_key &key,
+                            struct swr_vertex_element_state *velems);
+
 struct swr_jit_sampler_key {
    unsigned nr_samplers;
    unsigned nr_sampler_views;
@@ -60,6 +63,10 @@ struct swr_jit_vs_key : swr_jit_sampler_key {
    unsigned clip_plane_mask; // from rasterizer state & vs_info
 };
 
+struct swr_jit_fetch_key {
+   FETCH_COMPILE_STATE fsState;
+};
+
 namespace std
 {
 template <> struct hash<swr_jit_fs_key> {
@@ -75,7 +82,15 @@ template <> struct hash<swr_jit_vs_key> {
       return util_hash_crc32(&k, sizeof(k));
    }
 };
+
+template <> struct hash<swr_jit_fetch_key> {
+   std::size_t operator()(const swr_jit_fetch_key &k) const
+   {
+      return util_hash_crc32(&k, sizeof(k));
+   }
+};
 };
 
 bool operator==(const swr_jit_fs_key &lhs, const swr_jit_fs_key &rhs);
 bool operator==(const swr_jit_vs_key &lhs, const swr_jit_vs_key &rhs);
+bool operator==(const swr_jit_fetch_key &lhs, const swr_jit_fetch_key &rhs);
index f1f4963..116f19f 100644 (file)
@@ -451,7 +451,7 @@ swr_create_vertex_elements_state(struct pipe_context *pipe,
 {
    struct swr_vertex_element_state *velems;
    assert(num_elements <= PIPE_MAX_ATTRIBS);
-   velems = CALLOC_STRUCT(swr_vertex_element_state);
+   velems = new swr_vertex_element_state;
    if (velems) {
       velems->fsState.bVertexIDOffsetEnable = true;
       velems->fsState.numAttribs = num_elements;
@@ -521,8 +521,10 @@ swr_bind_vertex_elements_state(struct pipe_context *pipe, void *velems)
 static void
 swr_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
 {
+   struct swr_vertex_element_state *swr_velems =
+      (struct swr_vertex_element_state *) velems;
    /* XXX Need to destroy fetch shader? */
-   FREE(velems);
+   delete swr_velems;
 }
 
 
index 1960abd..202f165 100644 (file)
@@ -70,10 +70,11 @@ struct swr_fragment_shader {
 /* Vertex element state */
 struct swr_vertex_element_state {
    FETCH_COMPILE_STATE fsState;
-   PFN_FETCH_FUNC fsFunc;
-   uint32_t stream_pitch[PIPE_MAX_ATTRIBS];
-   uint32_t min_instance_div[PIPE_MAX_ATTRIBS];
-   uint32_t instanced_bufs;
+   PFN_FETCH_FUNC fsFunc {NULL};
+   uint32_t stream_pitch[PIPE_MAX_ATTRIBS] {0};
+   uint32_t min_instance_div[PIPE_MAX_ATTRIBS] {0};
+   uint32_t instanced_bufs {0};
+   std::unordered_map<swr_jit_fetch_key, PFN_FETCH_FUNC> map;
 };
 
 struct swr_blend_state {