Mesa (master): gallium/cso_hash: make cso_hash declared within structures instead of alloc'd

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Feb 14 23:52:33 UTC 2020


Module: Mesa
Branch: master
Commit: a8bbf1054093f638c83a27696b841d053a83ba72
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a8bbf1054093f638c83a27696b841d053a83ba72

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Tue Jan 21 20:10:43 2020 -0500

gallium/cso_hash: make cso_hash declared within structures instead of alloc'd

This removes one level of indirection.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3829>

---

 src/gallium/auxiliary/cso_cache/cso_cache.c       | 12 +++----
 src/gallium/auxiliary/cso_cache/cso_hash.c        | 19 ++++--------
 src/gallium/auxiliary/cso_cache/cso_hash.h        |  4 +--
 src/gallium/auxiliary/tgsi/tgsi_sanity.c          | 38 +++++++++++------------
 src/gallium/auxiliary/translate/translate_cache.c | 12 +++----
 src/gallium/auxiliary/util/u_hash_table.c         | 25 +++++++--------
 src/gallium/auxiliary/util/u_surfaces.c           | 17 +++++-----
 src/gallium/auxiliary/util/u_surfaces.h           |  4 +--
 src/gallium/state_trackers/xa/xa_tgsi.c           | 18 +++++------
 9 files changed, 69 insertions(+), 80 deletions(-)

diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c
index 4c1a76d9022..6cae21ca871 100644
--- a/src/gallium/auxiliary/cso_cache/cso_cache.c
+++ b/src/gallium/auxiliary/cso_cache/cso_cache.c
@@ -37,7 +37,7 @@
 
 
 struct cso_cache {
-   struct cso_hash *hashes[CSO_CACHE_MAX];
+   struct cso_hash hashes[CSO_CACHE_MAX];
    int    max_size;
 
    cso_sanitize_callback sanitize_cb;
@@ -82,9 +82,7 @@ unsigned cso_construct_key(void *item, int item_size)
 
 static inline struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_type type)
 {
-   struct cso_hash *hash;
-   hash = sc->hashes[type];
-   return hash;
+   return &sc->hashes[type];
 }
 
 static void delete_blend_state(void *state, UNUSED void *data)
@@ -252,7 +250,7 @@ struct cso_cache *cso_cache_create(void)
 
    sc->max_size           = 4096;
    for (i = 0; i < CSO_CACHE_MAX; i++)
-      sc->hashes[i] = cso_hash_create();
+      cso_hash_init(&sc->hashes[i]);
 
    sc->sanitize_cb        = sanitize_cb;
    sc->sanitize_data      = 0;
@@ -292,7 +290,7 @@ void cso_cache_delete(struct cso_cache *sc)
    cso_for_each_state(sc, CSO_VELEMENTS, delete_velements, 0);
 
    for (i = 0; i < CSO_CACHE_MAX; i++)
-      cso_hash_delete(sc->hashes[i]);
+      cso_hash_deinit(&sc->hashes[i]);
 
    FREE(sc);
 }
@@ -304,7 +302,7 @@ void cso_set_maximum_cache_size(struct cso_cache *sc, int number)
    sc->max_size = number;
 
    for (i = 0; i < CSO_CACHE_MAX; i++)
-      sanitize_hash(sc, sc->hashes[i], i, sc->max_size);
+      sanitize_hash(sc, &sc->hashes[i], i, sc->max_size);
 }
 
 int cso_maximum_cache_size(const struct cso_cache *sc)
diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c
index 9d633243ac9..753cd89f1ed 100644
--- a/src/gallium/auxiliary/cso_cache/cso_hash.c
+++ b/src/gallium/auxiliary/cso_cache/cso_hash.c
@@ -199,17 +199,11 @@ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash,
    }
 }
 
-struct cso_hash * cso_hash_create(void)
+bool cso_hash_init(struct cso_hash *hash)
 {
-   struct cso_hash *hash = MALLOC_STRUCT(cso_hash);
-   if (!hash)
-      return NULL;
-
    hash->data.d = MALLOC_STRUCT(cso_hash_data);
-   if (!hash->data.d) {
-      FREE(hash);
-      return NULL;
-   }
+   if (!hash->data.d)
+      return false;
 
    hash->data.d->fakeNext = 0;
    hash->data.d->buckets = 0;
@@ -218,11 +212,10 @@ struct cso_hash * cso_hash_create(void)
    hash->data.d->userNumBits = (short)MinNumBits;
    hash->data.d->numBits = 0;
    hash->data.d->numBuckets = 0;
-
-   return hash;
+   return true;
 }
 
-void cso_hash_delete(struct cso_hash *hash)
+void cso_hash_deinit(struct cso_hash *hash)
 {
    struct cso_node *e_for_x = (struct cso_node *)(hash->data.d);
    struct cso_node **bucket = (struct cso_node **)(hash->data.d->buckets);
@@ -237,7 +230,7 @@ void cso_hash_delete(struct cso_hash *hash)
    }
    FREE(hash->data.d->buckets);
    FREE(hash->data.d);
-   FREE(hash);
+   hash->data.d = NULL;
 }
 
 unsigned cso_hash_iter_key(struct cso_hash_iter iter)
diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h
index e41cb9e0af3..b86e11c5fd5 100644
--- a/src/gallium/auxiliary/cso_cache/cso_hash.h
+++ b/src/gallium/auxiliary/cso_cache/cso_hash.h
@@ -79,8 +79,8 @@ struct cso_hash_data {
    int numBuckets;
 };
 
-struct cso_hash *cso_hash_create(void);
-void             cso_hash_delete(struct cso_hash *hash);
+bool cso_hash_init(struct cso_hash *hash);
+void cso_hash_deinit(struct cso_hash *hash);
 
 
 int              cso_hash_size(struct cso_hash *hash);
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index 47f426d813d..35f00730380 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -47,9 +47,9 @@ typedef struct {
 struct sanity_check_ctx
 {
    struct tgsi_iterate_context iter;
-   struct cso_hash *regs_decl;
-   struct cso_hash *regs_used;
-   struct cso_hash *regs_ind_used;
+   struct cso_hash regs_decl;
+   struct cso_hash regs_used;
+   struct cso_hash regs_ind_used;
 
    uint num_imms;
    uint num_instructions;
@@ -203,7 +203,7 @@ is_register_declared(
    const scan_register *reg)
 {
    void *data = cso_hash_find_data_from_template(
-      ctx->regs_decl, scan_register_key(reg),
+      &ctx->regs_decl, scan_register_key(reg),
       (void*)reg, sizeof(scan_register));
    return  data ? TRUE : FALSE;
 }
@@ -214,7 +214,7 @@ is_any_register_declared(
    uint file )
 {
    struct cso_hash_iter iter =
-      cso_hash_first_node(ctx->regs_decl);
+      cso_hash_first_node(&ctx->regs_decl);
 
    while (!cso_hash_iter_is_null(iter)) {
       scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
@@ -232,7 +232,7 @@ is_register_used(
    scan_register *reg)
 {
    void *data = cso_hash_find_data_from_template(
-      ctx->regs_used, scan_register_key(reg),
+      &ctx->regs_used, scan_register_key(reg),
       reg, sizeof(scan_register));
    return  data ? TRUE : FALSE;
 }
@@ -243,7 +243,7 @@ is_ind_register_used(
    struct sanity_check_ctx *ctx,
    scan_register *reg)
 {
-   return cso_hash_contains(ctx->regs_ind_used, reg->file);
+   return cso_hash_contains(&ctx->regs_ind_used, reg->file);
 }
 
 static const char *file_names[TGSI_FILE_COUNT] =
@@ -280,7 +280,7 @@ check_register_usage(
       if (!is_any_register_declared( ctx, reg->file ))
          report_error( ctx, "%s: Undeclared %s register", file_names[reg->file], name );
       if (!is_ind_register_used(ctx, reg))
-         cso_hash_insert(ctx->regs_ind_used, reg->file, reg);
+         cso_hash_insert(&ctx->regs_ind_used, reg->file, reg);
       else
          FREE(reg);
    }
@@ -296,7 +296,7 @@ check_register_usage(
          }
       }
       if (!is_register_used( ctx, reg ))
-         cso_hash_insert(ctx->regs_used, scan_register_key(reg), reg);
+         cso_hash_insert(&ctx->regs_used, scan_register_key(reg), reg);
       else
          FREE(reg);
    }
@@ -381,7 +381,7 @@ check_and_declare(struct sanity_check_ctx *ctx,
    if (is_register_declared( ctx, reg))
       report_error( ctx, "%s[%u]: The same register declared more than once",
                     file_names[reg->file], reg->indices[0] );
-   cso_hash_insert(ctx->regs_decl,
+   cso_hash_insert(&ctx->regs_decl,
                    scan_register_key(reg),
                    reg);
 }
@@ -463,7 +463,7 @@ iter_immediate(
     */
    reg = MALLOC(sizeof(scan_register));
    fill_scan_register1d(reg, TGSI_FILE_IMMEDIATE, ctx->num_imms);
-   cso_hash_insert(ctx->regs_decl, scan_register_key(reg), reg);
+   cso_hash_insert(&ctx->regs_decl, scan_register_key(reg), reg);
    ctx->num_imms++;
 
    /* Check data type validity.
@@ -522,7 +522,7 @@ epilog(
     */
    {
       struct cso_hash_iter iter =
-         cso_hash_first_node(ctx->regs_decl);
+         cso_hash_first_node(&ctx->regs_decl);
 
       while (!cso_hash_iter_is_null(iter)) {
          scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
@@ -552,7 +552,7 @@ regs_hash_destroy(struct cso_hash *hash)
       assert(reg->file < TGSI_FILE_COUNT);
       FREE(reg);
    }
-   cso_hash_delete(hash);
+   cso_hash_deinit(hash);
 }
 
 boolean
@@ -569,9 +569,9 @@ tgsi_sanity_check(
    ctx.iter.iterate_property = iter_property;
    ctx.iter.epilog = epilog;
 
-   ctx.regs_decl = cso_hash_create();
-   ctx.regs_used = cso_hash_create();
-   ctx.regs_ind_used = cso_hash_create();
+   cso_hash_init(&ctx.regs_decl);
+   cso_hash_init(&ctx.regs_used);
+   cso_hash_init(&ctx.regs_ind_used);
 
    ctx.num_imms = 0;
    ctx.num_instructions = 0;
@@ -583,9 +583,9 @@ tgsi_sanity_check(
    ctx.print = debug_get_option_print_sanity();
 
    retval = tgsi_iterate_shader( tokens, &ctx.iter );
-   regs_hash_destroy(ctx.regs_decl);
-   regs_hash_destroy(ctx.regs_used);
-   regs_hash_destroy(ctx.regs_ind_used);
+   regs_hash_destroy(&ctx.regs_decl);
+   regs_hash_destroy(&ctx.regs_used);
+   regs_hash_destroy(&ctx.regs_ind_used);
    if (retval == FALSE)
       return FALSE;
 
diff --git a/src/gallium/auxiliary/translate/translate_cache.c b/src/gallium/auxiliary/translate/translate_cache.c
index 8aad7cdfb2b..0189b2a85d6 100644
--- a/src/gallium/auxiliary/translate/translate_cache.c
+++ b/src/gallium/auxiliary/translate/translate_cache.c
@@ -34,7 +34,7 @@
 #include "cso_cache/cso_hash.h"
 
 struct translate_cache {
-   struct cso_hash *hash;
+   struct cso_hash hash;
 };
 
 struct translate_cache * translate_cache_create( void )
@@ -44,14 +44,14 @@ struct translate_cache * translate_cache_create( void )
       return NULL;
    }
 
-   cache->hash = cso_hash_create();
+   cso_hash_init(&cache->hash);
    return cache;
 }
 
 
 static inline void delete_translates(struct translate_cache *cache)
 {
-   struct cso_hash *hash = cache->hash;
+   struct cso_hash *hash = &cache->hash;
    struct cso_hash_iter iter = cso_hash_first_node(hash);
    while (!cso_hash_iter_is_null(iter)) {
       struct translate *state = (struct translate*)cso_hash_iter_data(iter);
@@ -65,7 +65,7 @@ static inline void delete_translates(struct translate_cache *cache)
 void translate_cache_destroy(struct translate_cache *cache)
 {
    delete_translates(cache);
-   cso_hash_delete(cache->hash);
+   cso_hash_deinit(&cache->hash);
    FREE(cache);
 }
 
@@ -92,14 +92,14 @@ struct translate * translate_cache_find(struct translate_cache *cache,
 {
    unsigned hash_key = create_key(key);
    struct translate *translate = (struct translate*)
-      cso_hash_find_data_from_template(cache->hash,
+      cso_hash_find_data_from_template(&cache->hash,
                                        hash_key,
                                        key, sizeof(*key));
 
    if (!translate) {
       /* create/insert */
       translate = translate_create(key);
-      cso_hash_insert(cache->hash, hash_key, translate);
+      cso_hash_insert(&cache->hash, hash_key, translate);
    }
 
    return translate;
diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c
index 201b9a23b65..5ae35758b77 100644
--- a/src/gallium/auxiliary/util/u_hash_table.c
+++ b/src/gallium/auxiliary/util/u_hash_table.c
@@ -49,7 +49,7 @@
 
 struct util_hash_table
 {
-   struct cso_hash *cso;   
+   struct cso_hash cso;
    
    /** Hash function */
    unsigned (*hash)(void *key);
@@ -85,8 +85,7 @@ util_hash_table_create(unsigned (*hash)(void *key),
    if (!ht)
       return NULL;
    
-   ht->cso = cso_hash_create();
-   if(!ht->cso) {
+   if (!cso_hash_init(&ht->cso)) {
       FREE(ht);
       return NULL;
    }
@@ -106,7 +105,7 @@ util_hash_table_find_iter(struct util_hash_table *ht,
    struct cso_hash_iter iter;
    struct util_hash_table_item *item;
    
-   iter = cso_hash_find(ht->cso, key_hash);
+   iter = cso_hash_find(&ht->cso, key_hash);
    while (!cso_hash_iter_is_null(iter)) {
       item = (struct util_hash_table_item *)cso_hash_iter_data(iter);
       if (!ht->compare(item->key, key))
@@ -126,7 +125,7 @@ util_hash_table_find_item(struct util_hash_table *ht,
    struct cso_hash_iter iter;
    struct util_hash_table_item *item;
    
-   iter = cso_hash_find(ht->cso, key_hash);
+   iter = cso_hash_find(&ht->cso, key_hash);
    while (!cso_hash_iter_is_null(iter)) {
       item = (struct util_hash_table_item *)cso_hash_iter_data(iter);
       if (!ht->compare(item->key, key))
@@ -167,7 +166,7 @@ util_hash_table_set(struct util_hash_table *ht,
    item->key = key;
    item->value = value;
    
-   iter = cso_hash_insert(ht->cso, key_hash, item);
+   iter = cso_hash_insert(&ht->cso, key_hash, item);
    if(cso_hash_iter_is_null(iter)) {
       FREE(item);
       return PIPE_ERROR_OUT_OF_MEMORY;
@@ -220,7 +219,7 @@ util_hash_table_remove(struct util_hash_table *ht,
    assert(item);
    FREE(item);
    
-   cso_hash_erase(ht->cso, iter);
+   cso_hash_erase(&ht->cso, iter);
 }
 
 
@@ -234,11 +233,11 @@ util_hash_table_clear(struct util_hash_table *ht)
    if (!ht)
       return;
 
-   iter = cso_hash_first_node(ht->cso);
+   iter = cso_hash_first_node(&ht->cso);
    while (!cso_hash_iter_is_null(iter)) {
-      item = (struct util_hash_table_item *)cso_hash_take(ht->cso, cso_hash_iter_key(iter));
+      item = (struct util_hash_table_item *)cso_hash_take(&ht->cso, cso_hash_iter_key(iter));
       FREE(item);
-      iter = cso_hash_first_node(ht->cso);
+      iter = cso_hash_first_node(&ht->cso);
    }
 }
 
@@ -257,7 +256,7 @@ util_hash_table_foreach(struct util_hash_table *ht,
    if (!ht)
       return PIPE_ERROR_BAD_INPUT;
 
-   iter = cso_hash_first_node(ht->cso);
+   iter = cso_hash_first_node(&ht->cso);
    while (!cso_hash_iter_is_null(iter)) {
       item = (struct util_hash_table_item *)cso_hash_iter_data(iter);
       result = callback(item->key, item->value, data);
@@ -297,14 +296,14 @@ util_hash_table_destroy(struct util_hash_table *ht)
    if (!ht)
       return;
 
-   iter = cso_hash_first_node(ht->cso);
+   iter = cso_hash_first_node(&ht->cso);
    while (!cso_hash_iter_is_null(iter)) {
       item = (struct util_hash_table_item *)cso_hash_iter_data(iter);
       FREE(item);
       iter = cso_hash_iter_next(iter);
    }
 
-   cso_hash_delete(ht->cso);
+   cso_hash_deinit(&ht->cso);
    
    FREE(ht);
 }
diff --git a/src/gallium/auxiliary/util/u_surfaces.c b/src/gallium/auxiliary/util/u_surfaces.c
index 78b2506e47b..c9b357c5571 100644
--- a/src/gallium/auxiliary/util/u_surfaces.c
+++ b/src/gallium/auxiliary/util/u_surfaces.c
@@ -39,10 +39,10 @@ util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size,
 
    if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
    {    /* or 2D array */
-      if(!us->u.hash)
-         us->u.hash = cso_hash_create();
+      if (!us->u.hash.data.d)
+         cso_hash_init(&us->u.hash);
 
-      ps = cso_hash_iter_data(cso_hash_find(us->u.hash, (layer << 8) | level));
+      ps = cso_hash_iter_data(cso_hash_find(&us->u.hash, (layer << 8) | level));
    }
    else
    {
@@ -68,7 +68,7 @@ util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size,
    pipe_surface_init(ctx, ps, pt, level, layer);
 
    if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
-      cso_hash_insert(us->u.hash, (layer << 8) | level, ps);
+      cso_hash_insert(&us->u.hash, (layer << 8) | level, ps);
    else
       us->u.array[level] = ps;
 
@@ -82,7 +82,7 @@ util_surfaces_do_detach(struct util_surfaces *us, struct pipe_surface *ps)
    struct pipe_resource *pt = ps->texture;
    if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
    {    /* or 2D array */
-      cso_hash_erase(us->u.hash, cso_hash_find(us->u.hash, (ps->u.tex.first_layer << 8) | ps->u.tex.level));
+      cso_hash_erase(&us->u.hash, cso_hash_find(&us->u.hash, (ps->u.tex.first_layer << 8) | ps->u.tex.level));
    }
    else
       us->u.array[ps->u.tex.level] = 0;
@@ -93,17 +93,16 @@ util_surfaces_destroy(struct util_surfaces *us, struct pipe_resource *pt, void (
 {
    if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
    {    /* or 2D array */
-      if(us->u.hash)
+      if (&us->u.hash)
       {
          struct cso_hash_iter iter;
-         iter = cso_hash_first_node(us->u.hash);
+         iter = cso_hash_first_node(&us->u.hash);
          while (!cso_hash_iter_is_null(iter)) {
             destroy_surface(cso_hash_iter_data(iter));
             iter = cso_hash_iter_next(iter);
          }
 
-         cso_hash_delete(us->u.hash);
-         us->u.hash = NULL;
+         cso_hash_deinit(&us->u.hash);
       }
    }
    else
diff --git a/src/gallium/auxiliary/util/u_surfaces.h b/src/gallium/auxiliary/util/u_surfaces.h
index b84694c540b..e34f7c75d07 100644
--- a/src/gallium/auxiliary/util/u_surfaces.h
+++ b/src/gallium/auxiliary/util/u_surfaces.h
@@ -36,7 +36,7 @@ struct util_surfaces
 {
    union
    {
-      struct cso_hash *hash;
+      struct cso_hash hash;
       struct pipe_surface **array;
       void* pv;
    } u;
@@ -77,7 +77,7 @@ util_surfaces_peek(struct util_surfaces *us, struct pipe_resource *pt, unsigned
       return 0;
 
    if(unlikely(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE))
-      return cso_hash_iter_data(cso_hash_find(us->u.hash, (layer << 8) | level));
+      return cso_hash_iter_data(cso_hash_find(&us->u.hash, (layer << 8) | level));
    else
       return us->u.array[level];
 }
diff --git a/src/gallium/state_trackers/xa/xa_tgsi.c b/src/gallium/state_trackers/xa/xa_tgsi.c
index ed3e0895d98..caa300461cd 100644
--- a/src/gallium/state_trackers/xa/xa_tgsi.c
+++ b/src/gallium/state_trackers/xa/xa_tgsi.c
@@ -99,8 +99,8 @@ print_fs_traits(int fs_traits)
 struct xa_shaders {
     struct xa_context *r;
 
-    struct cso_hash *vs_hash;
-    struct cso_hash *fs_hash;
+    struct cso_hash vs_hash;
+    struct cso_hash fs_hash;
 };
 
 static inline void
@@ -424,8 +424,8 @@ xa_shaders_create(struct xa_context *r)
     struct xa_shaders *sc = CALLOC_STRUCT(xa_shaders);
 
     sc->r = r;
-    sc->vs_hash = cso_hash_create();
-    sc->fs_hash = cso_hash_create();
+    cso_hash_init(&sc->vs_hash);
+    cso_hash_init(&sc->fs_hash);
 
     return sc;
 }
@@ -446,14 +446,14 @@ cache_destroy(struct cso_context *cso,
 	}
 	iter = cso_hash_erase(hash, iter);
     }
-    cso_hash_delete(hash);
+    cso_hash_deinit(hash);
 }
 
 void
 xa_shaders_destroy(struct xa_shaders *sc)
 {
-    cache_destroy(sc->r->cso, sc->vs_hash, PIPE_SHADER_VERTEX);
-    cache_destroy(sc->r->cso, sc->fs_hash, PIPE_SHADER_FRAGMENT);
+    cache_destroy(sc->r->cso, &sc->vs_hash, PIPE_SHADER_VERTEX);
+    cache_destroy(sc->r->cso, &sc->fs_hash, PIPE_SHADER_FRAGMENT);
 
     FREE(sc);
 }
@@ -485,9 +485,9 @@ xa_shaders_get(struct xa_shaders *sc, unsigned vs_traits, unsigned fs_traits)
     void *vs, *fs;
 
     vs = shader_from_cache(sc->r->pipe, PIPE_SHADER_VERTEX,
-			   sc->vs_hash, vs_traits);
+			   &sc->vs_hash, vs_traits);
     fs = shader_from_cache(sc->r->pipe, PIPE_SHADER_FRAGMENT,
-			   sc->fs_hash, fs_traits);
+			   &sc->fs_hash, fs_traits);
 
     debug_assert(vs && fs);
     if (!vs || !fs)



More information about the mesa-commit mailing list