cso: make memcmp and hash computation use a literal key size for blend state
authorMarek Olšák <marek.olsak@amd.com>
Sun, 7 Aug 2022 23:41:16 +0000 (19:41 -0400)
committerMarge Bot <emma+marge@anholt.net>
Wed, 19 Oct 2022 04:56:55 +0000 (04:56 +0000)
This results in faster lookups because memcmp and the hash computation
can be unrolled.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19129>

src/gallium/auxiliary/cso_cache/cso_context.c

index 1f95272..efce6f6 100644 (file)
@@ -460,6 +460,9 @@ cso_destroy_context(struct cso_context *ctx)
  * template, insert it in the cache and return it.
  */
 
+#define CSO_BLEND_KEY_SIZE_RT0      offsetof(struct pipe_blend_state, rt[1])
+#define CSO_BLEND_KEY_SIZE_ALL_RT   sizeof(struct pipe_blend_state)
+
 /*
  * If the driver returns 0 from the create method then they will assign
  * the data member of the cso to be the template itself.
@@ -469,15 +472,26 @@ enum pipe_error
 cso_set_blend(struct cso_context *ctx,
               const struct pipe_blend_state *templ)
 {
-   const unsigned key_size = templ->independent_blend_enable ?
-      sizeof(struct pipe_blend_state) :
-      (char *)&(templ->rt[1]) - (char *)templ;
-   const unsigned hash_key = cso_construct_key(templ, key_size);
-   struct cso_hash_iter iter =
-      cso_find_state_template(&ctx->cache, hash_key, CSO_BLEND, templ,
-                              key_size);
+   unsigned key_size, hash_key;
+   struct cso_hash_iter iter;
    void *handle;
 
+   if (templ->independent_blend_enable) {
+      /* This is duplicated with the else block below because we want key_size
+       * to be a literal constant, so that memcpy and the hash computation can
+       * be inlined and unrolled.
+       */
+      hash_key = cso_construct_key(templ, CSO_BLEND_KEY_SIZE_ALL_RT);
+      iter = cso_find_state_template(&ctx->cache, hash_key, CSO_BLEND,
+                                     templ, CSO_BLEND_KEY_SIZE_ALL_RT);
+      key_size = CSO_BLEND_KEY_SIZE_ALL_RT;
+   } else {
+      hash_key = cso_construct_key(templ, CSO_BLEND_KEY_SIZE_RT0);
+      iter = cso_find_state_template(&ctx->cache, hash_key, CSO_BLEND,
+                                     templ, CSO_BLEND_KEY_SIZE_RT0);
+      key_size = CSO_BLEND_KEY_SIZE_RT0;
+   }
+
    if (cso_hash_iter_is_null(iter)) {
       struct cso_blend *cso = MALLOC(sizeof(struct cso_blend));
       if (!cso)