From: George Kyriazis Date: Fri, 10 Feb 2017 16:24:32 +0000 (-0600) Subject: swr: add fetch shader cache X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=669d8f626f64cee1bc74ef7869aac8585b6dcfe6;p=mesa.git swr: add fetch shader cache 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 --- diff --git a/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.h b/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.h index 15474536d4b..622608a820b 100644 --- a/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.h +++ b/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.h @@ -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 }; diff --git a/src/gallium/drivers/swr/swr_draw.cpp b/src/gallium/drivers/swr/swr_draw.cpp index c4d5e5c4495..4bdd3bbaa3e 100644 --- a/src/gallium/drivers/swr/swr_draw.cpp +++ b/src/gallium/drivers/swr/swr_draw.cpp @@ -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); diff --git a/src/gallium/drivers/swr/swr_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp index 979a28b353b..676938c4c9a 100644 --- a/src/gallium/drivers/swr/swr_shader.cpp +++ b/src/gallium/drivers/swr/swr_shader.cpp @@ -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) diff --git a/src/gallium/drivers/swr/swr_shader.h b/src/gallium/drivers/swr/swr_shader.h index 7e3399ccd87..266573f7eaf 100644 --- a/src/gallium/drivers/swr/swr_shader.h +++ b/src/gallium/drivers/swr/swr_shader.h @@ -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 { @@ -75,7 +82,15 @@ template <> struct hash { return util_hash_crc32(&k, sizeof(k)); } }; + +template <> struct hash { + 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); diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp index f1f4963c259..116f19f1ecf 100644 --- a/src/gallium/drivers/swr/swr_state.cpp +++ b/src/gallium/drivers/swr/swr_state.cpp @@ -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; } diff --git a/src/gallium/drivers/swr/swr_state.h b/src/gallium/drivers/swr/swr_state.h index 1960abddfa6..202f16547f9 100644 --- a/src/gallium/drivers/swr/swr_state.h +++ b/src/gallium/drivers/swr/swr_state.h @@ -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 map; }; struct swr_blend_state {