diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-08-26 05:30:39 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-08-26 05:30:39 +0000 |
commit | 27c93456b58343162f7c4ad20ca6bea0c9a91646 (patch) | |
tree | 945c20b63e0b9975ee40f114c5312f8d8f1a2d0b /lib/mesa/src/gallium/auxiliary/util | |
parent | 875b83a3ee95e248388fbf72271acc80f6f97987 (diff) |
Import Mesa 20.1.6
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/util')
22 files changed, 676 insertions, 900 deletions
diff --git a/lib/mesa/src/gallium/auxiliary/util/u_async_debug.h b/lib/mesa/src/gallium/auxiliary/util/u_async_debug.h index be783dc87..b192a01f9 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_async_debug.h +++ b/lib/mesa/src/gallium/auxiliary/util/u_async_debug.h @@ -34,7 +34,7 @@ #define UTIL_ASYNC_DEBUG_H #include "pipe/p_state.h" - +#include "util/u_debug.h" #include "util/simple_mtx.h" struct util_debug_message { diff --git a/lib/mesa/src/gallium/auxiliary/util/u_compute.c b/lib/mesa/src/gallium/auxiliary/util/u_compute.c index ccf711929..bc884b6ae 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_compute.c +++ b/lib/mesa/src/gallium/auxiliary/util/u_compute.c @@ -30,7 +30,7 @@ #include "pipe/p_state.h" #include "u_bitcast.h" -#include "u_format.h" +#include "util/format/u_format.h" #include "u_sampler.h" #include "tgsi/tgsi_text.h" #include "tgsi/tgsi_ureg.h" @@ -120,12 +120,6 @@ void util_compute_blit(struct pipe_context *ctx, struct pipe_blit_info *blit_inf ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, &image); - /* Initialize the sampler view. */ - u_sampler_view_default_template(&src_templ, src, src->format); - src_templ.format = util_format_linear(blit_info->src.format); - src_view = ctx->create_sampler_view(ctx, src, &src_templ); - ctx->set_sampler_views(ctx, PIPE_SHADER_COMPUTE, 0, 1, &src_view); - struct pipe_sampler_state sampler_state={0}; sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; @@ -140,6 +134,12 @@ void util_compute_blit(struct pipe_context *ctx, struct pipe_blit_info *blit_inf sampler_state_p = ctx->create_sampler_state(ctx, &sampler_state); ctx->bind_sampler_states(ctx, PIPE_SHADER_COMPUTE, 0, 1, &sampler_state_p); + /* Initialize the sampler view. */ + u_sampler_view_default_template(&src_templ, src, src->format); + src_templ.format = util_format_linear(blit_info->src.format); + src_view = ctx->create_sampler_view(ctx, src, &src_templ); + ctx->set_sampler_views(ctx, PIPE_SHADER_COMPUTE, 0, 1, &src_view); + if (!*compute_state) *compute_state = blit_compute_shader(ctx); ctx->bind_compute_state(ctx, *compute_state); diff --git a/lib/mesa/src/gallium/auxiliary/util/u_debug_describe.c b/lib/mesa/src/gallium/auxiliary/util/u_debug_describe.c index b78c99dd4..8bfd970a5 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_debug_describe.c +++ b/lib/mesa/src/gallium/auxiliary/util/u_debug_describe.c @@ -25,7 +25,7 @@ **************************************************************************/ #include "pipe/p_state.h" -#include "util/u_format.h" +#include "util/format/u_format.h" #include "util/u_debug_describe.h" #include "util/u_string.h" diff --git a/lib/mesa/src/gallium/auxiliary/util/u_debug_image.c b/lib/mesa/src/gallium/auxiliary/util/u_debug_image.c index 4e7984886..550fc86ce 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_debug_image.c +++ b/lib/mesa/src/gallium/auxiliary/util/u_debug_image.c @@ -25,7 +25,7 @@ #include "util/u_debug_image.h" -#include "util/u_format.h" +#include "util/format/u_format.h" #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -220,6 +220,7 @@ debug_dump_transfer_bmp(UNUSED struct pipe_context *pipe, pipe_get_tile_rgba(transfer, ptr, 0, 0, transfer->box.width, transfer->box.height, + transfer->resource->format, rgba); debug_dump_float_rgba_bmp(filename, diff --git a/lib/mesa/src/gallium/auxiliary/util/u_dirty_surfaces.h b/lib/mesa/src/gallium/auxiliary/util/u_dirty_surfaces.h index ccde8a8c1..e9ec5f259 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_dirty_surfaces.h +++ b/lib/mesa/src/gallium/auxiliary/util/u_dirty_surfaces.h @@ -50,7 +50,7 @@ struct util_dirty_surface static inline void util_dirty_surfaces_init(struct util_dirty_surfaces *ds) { - LIST_INITHEAD(&ds->dirty_list); + list_inithead(&ds->dirty_list); } static inline void @@ -85,7 +85,7 @@ util_dirty_surfaces_use_levels_for_sampling(struct pipe_context *pipe, struct ut static inline void util_dirty_surfaces_use_for_sampling_with(struct pipe_context *pipe, struct util_dirty_surfaces *dss, struct pipe_sampler_view *psv, struct pipe_sampler_state *pss, util_dirty_surface_flush_t flush) { - if(!LIST_IS_EMPTY(&dss->dirty_list)) + if(!list_is_empty(&dss->dirty_list)) util_dirty_surfaces_use_levels_for_sampling(pipe, dss, (unsigned)pss->min_lod + psv->u.tex.first_level, MIN2((unsigned)ceilf(pss->max_lod) + psv->u.tex.first_level, psv->u.tex.last_level), flush); } @@ -93,27 +93,27 @@ util_dirty_surfaces_use_for_sampling_with(struct pipe_context *pipe, struct util static inline void util_dirty_surface_init(struct util_dirty_surface *ds) { - LIST_INITHEAD(&ds->dirty_list); + list_inithead(&ds->dirty_list); } static inline boolean util_dirty_surface_is_dirty(struct util_dirty_surface *ds) { - return !LIST_IS_EMPTY(&ds->dirty_list); + return !list_is_empty(&ds->dirty_list); } static inline void util_dirty_surface_set_dirty(struct util_dirty_surfaces *dss, struct util_dirty_surface *ds) { - if(LIST_IS_EMPTY(&ds->dirty_list)) - LIST_ADDTAIL(&ds->dirty_list, &dss->dirty_list); + if(list_is_empty(&ds->dirty_list)) + list_addtail(&ds->dirty_list, &dss->dirty_list); } static inline void util_dirty_surface_set_clean(struct util_dirty_surfaces *dss, struct util_dirty_surface *ds) { - if(!LIST_IS_EMPTY(&ds->dirty_list)) - LIST_DELINIT(&ds->dirty_list); + if(!list_is_empty(&ds->dirty_list)) + list_delinit(&ds->dirty_list); } #endif diff --git a/lib/mesa/src/gallium/auxiliary/util/u_fifo.h b/lib/mesa/src/gallium/auxiliary/util/u_fifo.h index a7aad6179..b53a3ddd5 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_fifo.h +++ b/lib/mesa/src/gallium/auxiliary/util/u_fifo.h @@ -80,7 +80,7 @@ u_fifo_pop(struct util_fifo *fifo, void **ptr) *ptr = array[fifo->tail]; - ++fifo->num; + --fifo->num; return TRUE; } diff --git a/lib/mesa/src/gallium/auxiliary/util/u_gen_mipmap.c b/lib/mesa/src/gallium/auxiliary/util/u_gen_mipmap.c index 06737c58f..d8a5f2fc0 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/lib/mesa/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -36,7 +36,7 @@ #include "util/u_gen_mipmap.h" -#include "util/u_format.h" +#include "util/format/u_format.h" #include "util/u_inlines.h" diff --git a/lib/mesa/src/gallium/auxiliary/util/u_half.h b/lib/mesa/src/gallium/auxiliary/util/u_half.h index 966d213bd..bbcc843c3 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_half.h +++ b/lib/mesa/src/gallium/auxiliary/util/u_half.h @@ -30,6 +30,7 @@ #include "pipe/p_compiler.h" #include "util/u_math.h" +#include "util/half_float.h" #ifdef __cplusplus extern "C" { @@ -46,6 +47,12 @@ extern "C" { static inline uint16_t util_float_to_half(float f) { + return _mesa_float_to_half(f); +} + +static inline uint16_t +util_float_to_half_rtz(float f) +{ uint32_t sign_mask = 0x80000000; uint32_t round_mask = ~0xfff; uint32_t f32inf = 0xff << 23; @@ -123,7 +130,7 @@ util_half_to_float(uint16_t f16) f32.ui |= 0xff << 23; /* Sign */ - f32.ui |= (f16 & 0x8000) << 16; + f32.ui |= (uint32_t)(f16 & 0x8000) << 16; return f32.f; } diff --git a/lib/mesa/src/gallium/auxiliary/util/u_hash_table.c b/lib/mesa/src/gallium/auxiliary/util/u_hash_table.c index 201b9a23b..9182da558 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_hash_table.c +++ b/lib/mesa/src/gallium/auxiliary/util/u_hash_table.c @@ -25,286 +25,97 @@ * **************************************************************************/ -/** - * @file - * General purpose hash table implementation. - * - * Just uses the cso_hash for now, but it might be better switch to a linear - * probing hash table implementation at some point -- as it is said they have - * better lookup and cache performance and it appears to be possible to write - * a lock-free implementation of such hash tables . - * - * @author José Fonseca <jfonseca@vmware.com> - */ - -#include "pipe/p_compiler.h" -#include "util/u_debug.h" - -#include "cso_cache/cso_hash.h" - -#include "util/u_memory.h" +#include "util/u_pointer.h" #include "util/u_hash_table.h" - -struct util_hash_table -{ - struct cso_hash *cso; - - /** Hash function */ - unsigned (*hash)(void *key); - - /** Compare two keys */ - int (*compare)(void *key1, void *key2); - - /* TODO: key, value destructors? */ -}; - - -struct util_hash_table_item -{ - void *key; - void *value; -}; +#if DETECT_OS_UNIX +#include <sys/stat.h> +#endif -static inline struct util_hash_table_item * -util_hash_table_item(struct cso_hash_iter iter) +static uint32_t +pointer_hash(const void *key) { - return (struct util_hash_table_item *)cso_hash_iter_data(iter); + return _mesa_hash_pointer(key); } -struct util_hash_table * -util_hash_table_create(unsigned (*hash)(void *key), - int (*compare)(void *key1, void *key2)) +static bool +pointer_equal(const void *a, const void *b) { - struct util_hash_table *ht; - - ht = MALLOC_STRUCT(util_hash_table); - if (!ht) - return NULL; - - ht->cso = cso_hash_create(); - if(!ht->cso) { - FREE(ht); - return NULL; - } - - ht->hash = hash; - ht->compare = compare; - - return ht; + return a == b; } -static inline struct cso_hash_iter -util_hash_table_find_iter(struct util_hash_table *ht, - void *key, - unsigned key_hash) +struct hash_table * +util_hash_table_create_ptr_keys(void) { - struct cso_hash_iter iter; - struct util_hash_table_item *item; - - 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)) - break; - iter = cso_hash_iter_next(iter); - } - - return iter; + return _mesa_hash_table_create(NULL, pointer_hash, pointer_equal); } -static inline struct util_hash_table_item * -util_hash_table_find_item(struct util_hash_table *ht, - void *key, - unsigned key_hash) +static uint32_t hash_fd(const void *key) { - struct cso_hash_iter iter; - struct util_hash_table_item *item; - - 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)) - return item; - iter = cso_hash_iter_next(iter); - } - - return NULL; -} +#if DETECT_OS_UNIX + int fd = pointer_to_intptr(key); + struct stat stat; + fstat(fd, &stat); -enum pipe_error -util_hash_table_set(struct util_hash_table *ht, - void *key, - void *value) -{ - unsigned key_hash; - struct util_hash_table_item *item; - struct cso_hash_iter iter; - - assert(ht); - if (!ht) - return PIPE_ERROR_BAD_INPUT; - - key_hash = ht->hash(key); - - item = util_hash_table_find_item(ht, key, key_hash); - if (item) { - /* TODO: key/value destruction? */ - item->value = value; - return PIPE_OK; - } - - item = MALLOC_STRUCT(util_hash_table_item); - if (!item) - return PIPE_ERROR_OUT_OF_MEMORY; - - item->key = key; - item->value = value; - - iter = cso_hash_insert(ht->cso, key_hash, item); - if(cso_hash_iter_is_null(iter)) { - FREE(item); - return PIPE_ERROR_OUT_OF_MEMORY; - } - - return PIPE_OK; + return stat.st_dev ^ stat.st_ino ^ stat.st_rdev; +#else + return 0; +#endif } -void * -util_hash_table_get(struct util_hash_table *ht, - void *key) +static bool equal_fd(const void *key1, const void *key2) { - unsigned key_hash; - struct util_hash_table_item *item; - - assert(ht); - if (!ht) - return NULL; - - key_hash = ht->hash(key); - - item = util_hash_table_find_item(ht, key, key_hash); - if (!item) - return NULL; - - return item->value; +#if DETECT_OS_UNIX + int fd1 = pointer_to_intptr(key1); + int fd2 = pointer_to_intptr(key2); + struct stat stat1, stat2; + + fstat(fd1, &stat1); + fstat(fd2, &stat2); + + return stat1.st_dev == stat2.st_dev && + stat1.st_ino == stat2.st_ino && + stat1.st_rdev == stat2.st_rdev; +#else + return 0; +#endif } -void -util_hash_table_remove(struct util_hash_table *ht, - void *key) +struct hash_table * +util_hash_table_create_fd_keys(void) { - unsigned key_hash; - struct cso_hash_iter iter; - struct util_hash_table_item *item; - - assert(ht); - if (!ht) - return; - - key_hash = ht->hash(key); - - iter = util_hash_table_find_iter(ht, key, key_hash); - if(cso_hash_iter_is_null(iter)) - return; - - item = util_hash_table_item(iter); - assert(item); - FREE(item); - - cso_hash_erase(ht->cso, iter); + return _mesa_hash_table_create(NULL, hash_fd, equal_fd); } -void -util_hash_table_clear(struct util_hash_table *ht) +void * +util_hash_table_get(struct hash_table *ht, + void *key) { - struct cso_hash_iter iter; - struct util_hash_table_item *item; + struct hash_entry *entry = _mesa_hash_table_search(ht, key); - assert(ht); - if (!ht) - return; - - 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)); - FREE(item); - iter = cso_hash_first_node(ht->cso); - } + return entry ? entry->data : NULL; } enum pipe_error -util_hash_table_foreach(struct util_hash_table *ht, - enum pipe_error (*callback) +util_hash_table_foreach(struct hash_table *ht, + enum pipe_error (*callback) (void *key, void *value, void *data), - void *data) + void *data) { - struct cso_hash_iter iter; - struct util_hash_table_item *item; - enum pipe_error result; - - assert(ht); - if (!ht) - return PIPE_ERROR_BAD_INPUT; - - 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); - if(result != PIPE_OK) - return result; - iter = cso_hash_iter_next(iter); + hash_table_foreach(ht, entry) { + enum pipe_error error = callback((void*)entry->key, entry->data, data); + if (error != PIPE_OK) + return error; } - - return PIPE_OK; -} - - -static enum pipe_error -util_hash_inc(UNUSED void *k, UNUSED void *v, void *d) -{ - ++*(size_t *)d; return PIPE_OK; } - - -size_t -util_hash_table_count(struct util_hash_table *ht) -{ - size_t count = 0; - util_hash_table_foreach(ht, util_hash_inc, &count); - return count; -} - - -void -util_hash_table_destroy(struct util_hash_table *ht) -{ - struct cso_hash_iter iter; - struct util_hash_table_item *item; - - assert(ht); - if (!ht) - return; - - 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); - - FREE(ht); -} diff --git a/lib/mesa/src/gallium/auxiliary/util/u_hash_table.h b/lib/mesa/src/gallium/auxiliary/util/u_hash_table.h index ac00db8a0..4be4cef30 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_hash_table.h +++ b/lib/mesa/src/gallium/auxiliary/util/u_hash_table.h @@ -27,8 +27,6 @@ /** * General purpose hash table. - * - * @author José Fonseca <jfonseca@vmware.com> */ #ifndef U_HASH_TABLE_H_ @@ -36,64 +34,38 @@ #include "pipe/p_defines.h" +#include "util/hash_table.h" #ifdef __cplusplus extern "C" { #endif - /** - * Generic purpose hash table. + * Create a hash table where the keys are generic pointers. */ -struct util_hash_table; +struct hash_table * +util_hash_table_create_ptr_keys(void); /** - * Create an hash table. - * - * @param hash hash function - * @param compare should return 0 for two equal keys. + * Create a hash table where the keys are device FDs. */ -struct util_hash_table * -util_hash_table_create(unsigned (*hash)(void *key), - int (*compare)(void *key1, void *key2)); +struct hash_table * +util_hash_table_create_fd_keys(void); -enum pipe_error -util_hash_table_set(struct util_hash_table *ht, - void *key, - void *value); - void * -util_hash_table_get(struct util_hash_table *ht, +util_hash_table_get(struct hash_table *ht, void *key); -void -util_hash_table_remove(struct util_hash_table *ht, - void *key); - - -void -util_hash_table_clear(struct util_hash_table *ht); - - enum pipe_error -util_hash_table_foreach(struct util_hash_table *ht, +util_hash_table_foreach(struct hash_table *ht, enum pipe_error (*callback) (void *key, void *value, void *data), void *data); - -size_t -util_hash_table_count(struct util_hash_table *ht); - - -void -util_hash_table_destroy(struct util_hash_table *ht); - - #ifdef __cplusplus } #endif diff --git a/lib/mesa/src/gallium/auxiliary/util/u_idalloc.c b/lib/mesa/src/gallium/auxiliary/util/u_idalloc.c index 26104552e..2c48993b8 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_idalloc.c +++ b/lib/mesa/src/gallium/auxiliary/util/u_idalloc.c @@ -34,7 +34,7 @@ #include "util/u_idalloc.h" #include "util/u_math.h" -#include "util/u_memory.h" +#include <stdlib.h> void util_idalloc_init(struct util_idalloc *buf) diff --git a/lib/mesa/src/gallium/auxiliary/util/u_live_shader_cache.c b/lib/mesa/src/gallium/auxiliary/util/u_live_shader_cache.c new file mode 100644 index 000000000..15f387b49 --- /dev/null +++ b/lib/mesa/src/gallium/auxiliary/util/u_live_shader_cache.c @@ -0,0 +1,191 @@ +/* + * Copyright 2019 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "util/u_live_shader_cache.h" + +#include "util/u_inlines.h" +#include "tgsi/tgsi_from_mesa.h" +#include "tgsi/tgsi_parse.h" + +#include "compiler/nir/nir_serialize.h" + +#include "util/blob.h" +#include "util/hash_table.h" +#include "util/mesa-sha1.h" + +static uint32_t key_hash(const void *key) +{ + /* Take the first dword of SHA1. */ + return *(uint32_t*)key; +} + +static bool key_equals(const void *a, const void *b) +{ + /* Compare SHA1s. */ + return memcmp(a, b, 20) == 0; +} + +void +util_live_shader_cache_init(struct util_live_shader_cache *cache, + void *(*create_shader)(struct pipe_context *, + const struct pipe_shader_state *state), + void (*destroy_shader)(struct pipe_context *, void *)) +{ + simple_mtx_init(&cache->lock, mtx_plain); + cache->hashtable = _mesa_hash_table_create(NULL, key_hash, key_equals); + cache->create_shader = create_shader; + cache->destroy_shader = destroy_shader; +} + +void +util_live_shader_cache_deinit(struct util_live_shader_cache *cache) +{ + if (cache->hashtable) { + /* The hash table should be empty at this point. */ + _mesa_hash_table_destroy(cache->hashtable, NULL); + simple_mtx_destroy(&cache->lock); + } +} + +void * +util_live_shader_cache_get(struct pipe_context *ctx, + struct util_live_shader_cache *cache, + const struct pipe_shader_state *state, + bool* cache_hit) +{ + struct blob blob = {0}; + unsigned ir_size; + const void *ir_binary; + enum pipe_shader_type stage; + + /* Get the shader binary and shader stage. */ + if (state->type == PIPE_SHADER_IR_TGSI) { + ir_binary = state->tokens; + ir_size = tgsi_num_tokens(state->tokens) * + sizeof(struct tgsi_token); + stage = tgsi_get_processor_type(state->tokens); + } else if (state->type == PIPE_SHADER_IR_NIR) { + blob_init(&blob); + nir_serialize(&blob, state->ir.nir, true); + ir_binary = blob.data; + ir_size = blob.size; + stage = pipe_shader_type_from_mesa(((nir_shader*)state->ir.nir)->info.stage); + } else { + assert(0); + return NULL; + } + + /* Compute SHA1 of pipe_shader_state. */ + struct mesa_sha1 sha1_ctx; + unsigned char sha1[20]; + _mesa_sha1_init(&sha1_ctx); + _mesa_sha1_update(&sha1_ctx, ir_binary, ir_size); + if ((stage == PIPE_SHADER_VERTEX || + stage == PIPE_SHADER_TESS_EVAL || + stage == PIPE_SHADER_GEOMETRY) && + state->stream_output.num_outputs) { + _mesa_sha1_update(&sha1_ctx, &state->stream_output, + sizeof(state->stream_output)); + } + _mesa_sha1_final(&sha1_ctx, sha1); + + if (ir_binary == blob.data) + blob_finish(&blob); + + /* Find the shader in the live cache. */ + simple_mtx_lock(&cache->lock); + struct hash_entry *entry = _mesa_hash_table_search(cache->hashtable, sha1); + struct util_live_shader *shader = entry ? entry->data : NULL; + + /* Increase the refcount. */ + if (shader) { + pipe_reference(NULL, &shader->reference); + cache->hits++; + } + simple_mtx_unlock(&cache->lock); + + if (cache_hit) + *cache_hit = (shader != NULL); + + /* Return if the shader already exists. */ + if (shader) { + if (state->type == PIPE_SHADER_IR_NIR) + ralloc_free(state->ir.nir); + return shader; + } + + /* The cache mutex is unlocked to allow multiple create_shader + * invocations to run simultaneously. + */ + shader = (struct util_live_shader*)cache->create_shader(ctx, state); + pipe_reference_init(&shader->reference, 1); + memcpy(shader->sha1, sha1, sizeof(sha1)); + + simple_mtx_lock(&cache->lock); + /* The same shader might have been created in parallel. This is rare. + * If so, keep the one already in cache. + */ + struct hash_entry *entry2 = _mesa_hash_table_search(cache->hashtable, sha1); + struct util_live_shader *shader2 = entry2 ? entry2->data : NULL; + + if (shader2) { + cache->destroy_shader(ctx, shader); + shader = shader2; + /* Increase the refcount. */ + pipe_reference(NULL, &shader->reference); + } else { + _mesa_hash_table_insert(cache->hashtable, shader->sha1, shader); + } + cache->misses++; + simple_mtx_unlock(&cache->lock); + + return shader; +} + +void +util_shader_reference(struct pipe_context *ctx, + struct util_live_shader_cache *cache, + void **dst, void *src) +{ + if (*dst == src) + return; + + struct util_live_shader *dst_shader = (struct util_live_shader*)*dst; + struct util_live_shader *src_shader = (struct util_live_shader*)src; + + simple_mtx_lock(&cache->lock); + bool destroy = pipe_reference(&dst_shader->reference, &src_shader->reference); + if (destroy) { + struct hash_entry *entry = _mesa_hash_table_search(cache->hashtable, + dst_shader->sha1); + assert(entry); + _mesa_hash_table_remove(cache->hashtable, entry); + } + simple_mtx_unlock(&cache->lock); + + if (destroy) + cache->destroy_shader(ctx, dst_shader); + + *dst = src; +} diff --git a/lib/mesa/src/gallium/auxiliary/util/u_live_shader_cache.h b/lib/mesa/src/gallium/auxiliary/util/u_live_shader_cache.h new file mode 100644 index 000000000..b6e6e32c7 --- /dev/null +++ b/lib/mesa/src/gallium/auxiliary/util/u_live_shader_cache.h @@ -0,0 +1,91 @@ +/* + * Copyright 2019 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* This deduplicates live shader CSOs, meaning that creating 2 shaders with + * the same IR will return the same CSO. + * + * How to use this: + * + * - create_xx_state should only call util_live_shader_cache_get. + * + * - delete_xx_state should only call util_shader_reference(&shader, NULL). + * This will decrease the reference count. + * + * - Driver shaders must inherit util_live_shader. They don't have to + * initialize it. + * + * - Declare struct util_live_shader_cache in your pipe_screen (no pointer) if + * you support shareable shaders. If not, declare it in your pipe_context. + * + * - Set your create_shader and destroy_shader driver callbacks with + * util_live_shader_cache_init. These are your driver versions of + * create_xx_state and delete_xx_state. There is no distinction between + * vs, tcs, tes, gs, fs. Instead, get the shader type from the IR. + * + * - Call util_live_shader_cache_deinit when you destroy your screen or context. + */ + +#ifndef U_LIVE_SHADER_CACHE_H +#define U_LIVE_SHADER_CACHE_H + +#include "util/simple_mtx.h" +#include "pipe/p_state.h" + +struct util_live_shader_cache { + simple_mtx_t lock; + struct hash_table *hashtable; + + void *(*create_shader)(struct pipe_context *, + const struct pipe_shader_state *state); + void (*destroy_shader)(struct pipe_context *, void *); + + unsigned hits, misses; +}; + +struct util_live_shader { + struct pipe_reference reference; + unsigned char sha1[20]; +}; + +void +util_live_shader_cache_init(struct util_live_shader_cache *cache, + void *(*create_shader)(struct pipe_context *, + const struct pipe_shader_state *state), + void (*destroy_shader)(struct pipe_context *, void *)); + +void +util_live_shader_cache_deinit(struct util_live_shader_cache *cache); + +void * +util_live_shader_cache_get(struct pipe_context *ctx, + struct util_live_shader_cache *cache, + const struct pipe_shader_state *state, + bool* cache_hit); + +void +util_shader_reference(struct pipe_context *ctx, + struct util_live_shader_cache *cache, + void **dst, void *src); + +#endif diff --git a/lib/mesa/src/gallium/auxiliary/util/u_pack_color.h b/lib/mesa/src/gallium/auxiliary/util/u_pack_color.h index 0166126c5..a395fbc80 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_pack_color.h +++ b/lib/mesa/src/gallium/auxiliary/util/u_pack_color.h @@ -37,8 +37,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" -#include "util/u_debug_gallium.h" -#include "util/u_format.h" +#include "util/format/u_format.h" #include "util/u_math.h" @@ -430,10 +429,18 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color * /* Handle other cases with a generic function. */ default: - util_format_write_4f(format, rgba, 0, uc, 0, 0, 0, 1, 1); + util_format_pack_rgba(format, uc, rgba, 1); } } - + +static inline void +util_pack_color_union(enum pipe_format format, + union util_color *dst, + const union pipe_color_union *src) +{ + util_format_pack_rgba(format, dst, &src->ui, 1); +} + /* Integer versions of util_pack_z and util_pack_z_stencil - useful for * constructing clear masks. */ @@ -455,7 +462,8 @@ util_pack_mask_z(enum pipe_format format, uint32_t z) case PIPE_FORMAT_S8_UINT: return 0; default: - debug_print_format("gallium: unhandled format in util_pack_mask_z()", format); + debug_printf("gallium: unhandled format in util_pack_mask_z(): %s\n", + util_format_name(format)); assert(0); return 0; } @@ -551,7 +559,8 @@ util_pack_z(enum pipe_format format, double z) /* this case can get it via util_pack_z_stencil() */ return 0; default: - debug_print_format("gallium: unhandled format in util_pack_z()", format); + debug_printf("gallium: unhandled format in util_pack_z(): %s\n", + util_format_name(format)); assert(0); return 0; } diff --git a/lib/mesa/src/gallium/auxiliary/util/u_pwr8.h b/lib/mesa/src/gallium/auxiliary/util/u_pwr8.h index ffd9f9231..7eb52efd6 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_pwr8.h +++ b/lib/mesa/src/gallium/auxiliary/util/u_pwr8.h @@ -32,7 +32,7 @@ #ifndef U_PWR8_H_ #define U_PWR8_H_ -#if defined(_ARCH_PWR8) && defined(PIPE_ARCH_LITTLE_ENDIAN) +#if defined(_ARCH_PWR8) && UTIL_ARCH_LITTLE_ENDIAN #define VECTOR_ALIGN_16 __attribute__ ((__aligned__ (16))) @@ -53,7 +53,7 @@ vec_set_epi32 (int i3, int i2, int i1, int i0) { __m128i_union vdst; -#ifdef PIPE_ARCH_LITTLE_ENDIAN +#if UTIL_ARCH_LITTLE_ENDIAN vdst.i[0] = i0; vdst.i[1] = i1; vdst.i[2] = i2; @@ -78,7 +78,7 @@ static inline __m128i vec_unpacklo_epi32 (__m128i even, __m128i odd) { static const __m128i perm_mask = -#ifdef PIPE_ARCH_LITTLE_ENDIAN +#if UTIL_ARCH_LITTLE_ENDIAN { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23}; #else {24, 25, 26, 27, 8, 9, 10, 11, 28, 29, 30, 31, 12, 13, 14, 15}; @@ -91,7 +91,7 @@ static inline __m128i vec_unpackhi_epi32 (__m128i even, __m128i odd) { static const __m128i perm_mask = -#ifdef PIPE_ARCH_LITTLE_ENDIAN +#if UTIL_ARCH_LITTLE_ENDIAN { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31}; #else {16, 17, 18, 19, 0, 1, 2, 3, 20, 21, 22, 23, 4, 5, 6, 7}; @@ -104,7 +104,7 @@ static inline __m128i vec_unpacklo_epi64 (__m128i even, __m128i odd) { static const __m128i perm_mask = -#ifdef PIPE_ARCH_LITTLE_ENDIAN +#if UTIL_ARCH_LITTLE_ENDIAN { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}; #else {24, 25, 26, 27, 28, 29, 30, 31, 8, 9, 10, 11, 12, 13, 14, 15}; @@ -117,7 +117,7 @@ static inline __m128i vec_unpackhi_epi64 (__m128i even, __m128i odd) { static const __m128i perm_mask = -#ifdef PIPE_ARCH_LITTLE_ENDIAN +#if UTIL_ARCH_LITTLE_ENDIAN { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}; #else {16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7}; @@ -236,7 +236,7 @@ vec_loadu_si128 (const uint32_t* src) { __m128i_union vsrc; -#ifdef PIPE_ARCH_LITTLE_ENDIAN +#if UTIL_ARCH_LITTLE_ENDIAN vsrc.m128ui = *((vector unsigned int *) src); @@ -280,7 +280,7 @@ vec_movemask_epi8 (__m128i vsrc) vtemp.m128i = vec_vgbbd(vsrc); -#ifdef PIPE_ARCH_LITTLE_ENDIAN +#if UTIL_ARCH_LITTLE_ENDIAN result = vtemp.ub[15] << 8 | vtemp.ub[7]; #else result = vtemp.ub[0] << 8 | vtemp.ub[8]; @@ -292,7 +292,7 @@ vec_movemask_epi8 (__m128i vsrc) static inline __m128i vec_packs_epi16 (__m128i a, __m128i b) { -#ifdef PIPE_ARCH_LITTLE_ENDIAN +#if UTIL_ARCH_LITTLE_ENDIAN return (__m128i) vec_packs ((vector signed short) a, (vector signed short) b); #else @@ -304,13 +304,13 @@ vec_packs_epi16 (__m128i a, __m128i b) static inline __m128i vec_packs_epi32 (__m128i a, __m128i b) { -#ifdef PIPE_ARCH_LITTLE_ENDIAN +#if UTIL_ARCH_LITTLE_ENDIAN return (__m128i) vec_packs ((vector signed int) a, (vector signed int) b); #else return (__m128i) vec_packs ((vector signed int) b, (vector signed int) a); #endif } -#endif /* _ARCH_PWR8 && PIPE_ARCH_LITTLE_ENDIAN */ +#endif /* _ARCH_PWR8 && UTIL_ARCH_LITTLE_ENDIAN */ #endif /* U_PWR8_H_ */ diff --git a/lib/mesa/src/gallium/auxiliary/util/u_sampler.c b/lib/mesa/src/gallium/auxiliary/util/u_sampler.c index 5da1d5fdf..2c823d456 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_sampler.c +++ b/lib/mesa/src/gallium/auxiliary/util/u_sampler.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "u_format.h" +#include "util/format/u_format.h" #include "u_sampler.h" diff --git a/lib/mesa/src/gallium/auxiliary/util/u_screen.c b/lib/mesa/src/gallium/auxiliary/util/u_screen.c index 88f4945e7..ae024f0e6 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_screen.c +++ b/lib/mesa/src/gallium/auxiliary/util/u_screen.c @@ -223,6 +223,7 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen, case PIPE_CAP_SHAREABLE_SHADERS: case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: case PIPE_CAP_CLEAR_TEXTURE: + case PIPE_CAP_CLEAR_SCISSORED: case PIPE_CAP_DRAW_PARAMETERS: case PIPE_CAP_TGSI_PACK_HALF_FLOAT: case PIPE_CAP_MULTI_DRAW_INDIRECT: @@ -258,6 +259,8 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen, case PIPE_CAP_MAX_WINDOW_RECTANGLES: /* Enables EXT_window_rectangles */ case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED: case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: + case PIPE_CAP_VIEWPORT_SWIZZLE: + case PIPE_CAP_VIEWPORT_MASK: case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: case PIPE_CAP_TGSI_ARRAY_COMPONENTS: case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: @@ -296,6 +299,10 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen, */ return 1; + case PIPE_CAP_PREFER_IMM_ARRAYS_AS_CONSTBUF: + /* Don't unset this unless your driver can do better */ + return 1; + case PIPE_CAP_POST_DEPTH_COVERAGE: case PIPE_CAP_BINDLESS_TEXTURE: case PIPE_CAP_NIR_SAMPLERS_AS_DEREF: @@ -337,6 +344,7 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen, case PIPE_CAP_ATOMIC_FLOAT_MINMAX: case PIPE_CAP_SHADER_SAMPLES_IDENTICAL: case PIPE_CAP_TGSI_ATOMINC_WRAP: + case PIPE_CAP_TGSI_TG4_COMPONENT_IN_SWIZZLE: return 0; case PIPE_CAP_MAX_GS_INVOCATIONS: @@ -366,12 +374,19 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen, case PIPE_CAP_COMPUTE_SHADER_DERIVATIVES: return 0; - case PIPE_CAP_MAX_FRAMES_IN_FLIGHT: + case PIPE_CAP_THROTTLE: return 1; case PIPE_CAP_TEXTURE_SHADOW_LOD: return 0; + case PIPE_CAP_GL_SPIRV: + case PIPE_CAP_GL_SPIRV_VARIABLE_POINTERS: + return 0; + + case PIPE_CAP_DEMOTE_TO_HELPER_INVOCATION: + return 0; + case PIPE_CAP_DMABUF: #if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) return 1; @@ -379,6 +394,45 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen, return 0; #endif + case PIPE_CAP_TEXTURE_SHADOW_MAP: /* Enables ARB_shadow */ + return 1; + + case PIPE_CAP_FLATSHADE: + case PIPE_CAP_ALPHA_TEST: + case PIPE_CAP_POINT_SIZE_FIXED: + case PIPE_CAP_TWO_SIDED_COLOR: + case PIPE_CAP_CLIP_PLANES: + return 1; + + case PIPE_CAP_MAX_VERTEX_BUFFERS: + return 16; + + case PIPE_CAP_OPENCL_INTEGER_FUNCTIONS: + case PIPE_CAP_INTEGER_MULTIPLY_32X16: + case PIPE_CAP_DRAW_INFO_START_WITH_USER_INDICES: + return 0; + case PIPE_CAP_NIR_IMAGES_AS_DEREF: + return 1; + + case PIPE_CAP_FRONTEND_NOOP: + /* Enables INTEL_blackhole_render */ + return 0; + + case PIPE_CAP_PACKED_STREAM_OUTPUT: + return 1; + + case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED: + case PIPE_CAP_PSIZ_CLAMPED: + case PIPE_CAP_MAP_UNSYNCHRONIZED_THREAD_SAFE: + return 0; + + case PIPE_CAP_GL_BEGIN_END_BUFFER_SIZE: + return 512 * 1024; + + case PIPE_CAP_SYSTEM_SVM: + case PIPE_CAP_ALPHA_TO_COVERAGE_DITHER_CONTROL: + return 0; + default: unreachable("bad PIPE_CAP_*"); } diff --git a/lib/mesa/src/gallium/auxiliary/util/u_split_draw.c b/lib/mesa/src/gallium/auxiliary/util/u_split_draw.c new file mode 100644 index 000000000..39989aad0 --- /dev/null +++ b/lib/mesa/src/gallium/auxiliary/util/u_split_draw.c @@ -0,0 +1,67 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "pipe/p_defines.h" +#include "util/u_debug.h" +#include "util/u_split_draw.h" + +bool +u_split_draw(const struct pipe_draw_info *info, uint32_t max_verts, + uint32_t *count, uint32_t *step) +{ + if (*count <= max_verts) { + *step = *count; + return false; + } + + switch (info->mode) { + case PIPE_PRIM_POINTS: + *count = *step = max_verts; + break; + case PIPE_PRIM_LINES: + *count = *step = max_verts - (max_verts % 2); + break; + case PIPE_PRIM_LINE_STRIP: + *count = max_verts; + *step = max_verts - 1; + break; + case PIPE_PRIM_LINE_LOOP: + *count = max_verts; + *step = max_verts - 1; + debug_warn_once("unhandled line loop " + "looping behavior with " + ">max vert count\n"); + break; + case PIPE_PRIM_TRIANGLES: + *count = *step = max_verts - (max_verts % 3); + break; + case PIPE_PRIM_TRIANGLE_STRIP: + *count = max_verts; + *step = max_verts - 2; + break; + default: + debug_warn_once("unhandled primitive " + "max vert count, truncating\n"); + *count = *step = max_verts; + } + + return true; +} diff --git a/lib/mesa/src/gallium/auxiliary/util/u_split_draw.h b/lib/mesa/src/gallium/auxiliary/util/u_split_draw.h new file mode 100644 index 000000000..b3236a23b --- /dev/null +++ b/lib/mesa/src/gallium/auxiliary/util/u_split_draw.h @@ -0,0 +1,48 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef U_SPLIT_DRAW_H +#define U_SPLIT_DRAW_H + +#include "pipe/p_state.h" + +/** + * For non-indexed drawing, this function helps work around hardware + * limits on the number of verts in a single draw. + * + * For the given mode of primitive from info, calculate the count and + * step in the buffer so the draw can be split into multiple draws. + * + * \param info pointer to the original pipe_draw_info from draw_vbo + * \param max_verts max number of vertices that can be handled by the hardware + * \param count number of vertices remaining in the draw call. It is also + * used as a return parameter, containing how many vertices + * should be sent in the next job to the hardware. + * \param step return parameter, will contain how many vertices should be + * skipped from the original count on the next call to this + * function (may differ from count if the primitive mode + * requires the last vertices to be reused in the next draw) + */ +bool +u_split_draw(const struct pipe_draw_info *info, uint32_t max_verts, + uint32_t *count, uint32_t *step); + +#endif diff --git a/lib/mesa/src/gallium/auxiliary/util/u_tile.c b/lib/mesa/src/gallium/auxiliary/util/u_tile.c index 0239b8704..d954301a9 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_tile.c +++ b/lib/mesa/src/gallium/auxiliary/util/u_tile.c @@ -34,8 +34,8 @@ #include "pipe/p_defines.h" #include "util/u_inlines.h" -#include "util/u_format.h" -#include "util/u_format_bptc.h" +#include "util/format/u_format.h" +#include "util/format/u_format_bptc.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_surface.h" @@ -355,491 +355,67 @@ x32_s8_get_tile_rgba(const unsigned *src, } void -pipe_tile_raw_to_rgba(enum pipe_format format, - const void *src, - uint w, uint h, - float *dst, unsigned dst_stride) -{ - switch (format) { - case PIPE_FORMAT_Z16_UNORM: - z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_Z32_UNORM: - z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_Z24_UNORM_S8_UINT: - case PIPE_FORMAT_Z24X8_UNORM: - s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_S8_UINT: - s8_get_tile_rgba((unsigned char *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_X24S8_UINT: - s8x24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_S8_UINT_Z24_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_S8X24_UINT: - x24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_Z32_FLOAT: - z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: - z32f_x24s8_get_tile_rgba((float *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_X32_S8X24_UINT: - x32_s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - default: - util_format_read_4f(format, - dst, dst_stride * sizeof(float), - src, util_format_get_stride(format, w), - 0, 0, w, h); - } -} - -void -pipe_tile_raw_to_unsigned(enum pipe_format format, - const void *src, - uint w, uint h, - unsigned *dst, unsigned dst_stride) -{ - util_format_read_4ui(format, - dst, dst_stride * sizeof(float), - src, util_format_get_stride(format, w), - 0, 0, w, h); -} - -void -pipe_tile_raw_to_signed(enum pipe_format format, - void *src, - uint w, uint h, - int *dst, unsigned dst_stride) -{ - util_format_read_4i(format, - dst, dst_stride * sizeof(float), - src, util_format_get_stride(format, w), - 0, 0, w, h); -} - -void -pipe_get_tile_rgba(struct pipe_transfer *pt, - const void *src, - uint x, uint y, uint w, uint h, - float *p) -{ - pipe_get_tile_rgba_format(pt, src, x, y, w, h, pt->resource->format, p); -} - - -void -pipe_get_tile_rgba_format(struct pipe_transfer *pt, - const void *src, - uint x, uint y, uint w, uint h, - enum pipe_format format, - float *p) -{ - unsigned dst_stride = w * 4; - void *packed; - - if (u_clip_tile(x, y, &w, &h, &pt->box)) { - return; - } - - packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); - if (!packed) { - return; - } - - if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) { - assert((x & 1) == 0); - } - - pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0); - - pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride); - - FREE(packed); -} - - -void pipe_put_tile_rgba(struct pipe_transfer *pt, void *dst, uint x, uint y, uint w, uint h, - const float *p) -{ - pipe_put_tile_rgba_format(pt, dst, x, y, w, h, pt->resource->format, p); -} - - -void -pipe_put_tile_rgba_format(struct pipe_transfer *pt, - void *dst, - uint x, uint y, uint w, uint h, - enum pipe_format format, - const float *p) + enum pipe_format format, const void *p) { unsigned src_stride = w * 4; - void *packed; if (u_clip_tile(x, y, &w, &h, &pt->box)) return; - packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); - - if (!packed) - return; - - switch (format) { - case PIPE_FORMAT_Z16_UNORM: - /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_Z32_UNORM: - /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_Z24_UNORM_S8_UINT: - case PIPE_FORMAT_Z24X8_UNORM: - /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_S8_UINT_Z24_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_Z32_FLOAT: - /*z32f_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: - /*z32f_s8x24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ - break; - default: - util_format_write_4f(format, + /* softpipe's S8_UINT texture cache fetch needs to take the rgba_format + * path, not ui (since there's no ui unpack for s8, but it's technically + * pure integer). + */ + if (util_format_is_pure_uint(format)) { + util_format_write_4ui(format, + p, src_stride * sizeof(float), + dst, pt->stride, + x, y, w, h); + } else if (util_format_is_pure_sint(format)) { + util_format_write_4i(format, p, src_stride * sizeof(float), - packed, util_format_get_stride(format, w), - 0, 0, w, h); - } - - pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0); - - FREE(packed); -} - -void -pipe_put_tile_i_format(struct pipe_transfer *pt, - void *dst, - uint x, uint y, uint w, uint h, - enum pipe_format format, - const int *p) -{ - unsigned src_stride = w * 4; - void *packed; - - if (u_clip_tile(x, y, &w, &h, &pt->box)) - return; - - packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); - - if (!packed) - return; - - util_format_write_4i(format, - p, src_stride * sizeof(float), - packed, util_format_get_stride(format, w), - 0, 0, w, h); - - pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0); - - FREE(packed); -} - -void -pipe_put_tile_ui_format(struct pipe_transfer *pt, - void *dst, - uint x, uint y, uint w, uint h, - enum pipe_format format, - const unsigned int *p) -{ - unsigned src_stride = w * 4; - void *packed; - - if (u_clip_tile(x, y, &w, &h, &pt->box)) - return; - - packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); - - if (!packed) - return; - - util_format_write_4ui(format, - p, src_stride * sizeof(float), - packed, util_format_get_stride(format, w), - 0, 0, w, h); - - pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0); - - FREE(packed); -} - -/** - * Get a block of Z values, converted to 32-bit range. - */ -void -pipe_get_tile_z(struct pipe_transfer *pt, - const void *src, - uint x, uint y, uint w, uint h, - uint *z) -{ - const uint dstStride = w; - const ubyte *map = src; - uint *pDest = z; - uint i, j; - enum pipe_format format = pt->resource->format; - - if (u_clip_tile(x, y, &w, &h, &pt->box)) - return; - - switch (format) { - case PIPE_FORMAT_Z32_UNORM: - { - const uint *ptrc - = (const uint *)(map + y * pt->stride + x*4); - for (i = 0; i < h; i++) { - memcpy(pDest, ptrc, 4 * w); - pDest += dstStride; - ptrc += pt->stride/4; - } - } - break; - case PIPE_FORMAT_Z24_UNORM_S8_UINT: - case PIPE_FORMAT_Z24X8_UNORM: - { - const uint *ptrc - = (const uint *)(map + y * pt->stride + x*4); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 24-bit Z to 32-bit Z */ - pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff); - } - pDest += dstStride; - ptrc += pt->stride/4; - } + dst, pt->stride, + x, y, w, h); + } else { + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + /*z16_put_tile_rgba((ushort *) dst, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_Z32_UNORM: + /*z32_put_tile_rgba((unsigned *) dst, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_Z24X8_UNORM: + /*s8z24_put_tile_rgba((unsigned *) dst, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_S8_UINT_Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + /*z24s8_put_tile_rgba((unsigned *) dst, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_Z32_FLOAT: + /*z32f_put_tile_rgba((unsigned *) dst, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + /*z32f_s8x24_put_tile_rgba((unsigned *) dst, w, h, p, src_stride);*/ + break; + default: + util_format_write_4f(format, + p, src_stride * sizeof(float), + dst, pt->stride, + x, y, w, h); } - break; - case PIPE_FORMAT_S8_UINT_Z24_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - { - const uint *ptrc - = (const uint *)(map + y * pt->stride + x*4); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 24-bit Z to 32-bit Z */ - pDest[j] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff); - } - pDest += dstStride; - ptrc += pt->stride/4; - } - } - break; - case PIPE_FORMAT_Z16_UNORM: - { - const ushort *ptrc - = (const ushort *)(map + y * pt->stride + x*2); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 16-bit Z to 32-bit Z */ - pDest[j] = (ptrc[j] << 16) | ptrc[j]; - } - pDest += dstStride; - ptrc += pt->stride/2; - } - } - break; - case PIPE_FORMAT_Z32_FLOAT: - { - const float *ptrc = (const float *)(map + y * pt->stride + x*4); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert float Z to 32-bit Z */ - if (ptrc[j] <= 0.0) { - pDest[j] = 0; - } - else if (ptrc[j] >= 1.0) { - pDest[j] = 0xffffffff; - } - else { - double z = ptrc[j] * 0xffffffff; - pDest[j] = (uint) z; - } - } - pDest += dstStride; - ptrc += pt->stride/4; - } - } - break; - case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: - { - const float *ptrc = (const float *)(map + y * pt->stride + x*8); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert float Z to 32-bit Z */ - if (ptrc[j] <= 0.0) { - pDest[j*2] = 0; - } - else if (ptrc[j] >= 1.0) { - pDest[j*2] = 0xffffffff; - } - else { - double z = ptrc[j] * 0xffffffff; - pDest[j*2] = (uint) z; - } - } - pDest += dstStride; - ptrc += pt->stride/4; - } - } - break; - default: - assert(0); } } - void -pipe_put_tile_z(struct pipe_transfer *pt, - void *dst, - uint x, uint y, uint w, uint h, - const uint *zSrc) -{ - const uint srcStride = w; - const uint *ptrc = zSrc; - ubyte *map = dst; - uint i, j; - enum pipe_format format = pt->resource->format; - - if (u_clip_tile(x, y, &w, &h, &pt->box)) - return; - - switch (format) { - case PIPE_FORMAT_Z32_UNORM: - { - uint *pDest = (uint *) (map + y * pt->stride + x*4); - for (i = 0; i < h; i++) { - memcpy(pDest, ptrc, 4 * w); - pDest += pt->stride/4; - ptrc += srcStride; - } - } - break; - case PIPE_FORMAT_Z24_UNORM_S8_UINT: - { - uint *pDest = (uint *) (map + y * pt->stride + x*4); - /*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/ - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 32-bit Z to 24-bit Z, preserve stencil */ - pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8; - } - pDest += pt->stride/4; - ptrc += srcStride; - } - } - break; - case PIPE_FORMAT_Z24X8_UNORM: - { - uint *pDest = (uint *) (map + y * pt->stride + x*4); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 32-bit Z to 24-bit Z (0 stencil) */ - pDest[j] = ptrc[j] >> 8; - } - pDest += pt->stride/4; - ptrc += srcStride; - } - } - break; - case PIPE_FORMAT_S8_UINT_Z24_UNORM: - { - uint *pDest = (uint *) (map + y * pt->stride + x*4); - /*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/ - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 32-bit Z to 24-bit Z, preserve stencil */ - pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00); - } - pDest += pt->stride/4; - ptrc += srcStride; - } - } - break; - case PIPE_FORMAT_X8Z24_UNORM: - { - uint *pDest = (uint *) (map + y * pt->stride + x*4); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 32-bit Z to 24-bit Z (0 stencil) */ - pDest[j] = ptrc[j] & 0xffffff00; - } - pDest += pt->stride/4; - ptrc += srcStride; - } - } - break; - case PIPE_FORMAT_Z16_UNORM: - { - ushort *pDest = (ushort *) (map + y * pt->stride + x*2); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 32-bit Z to 16-bit Z */ - pDest[j] = ptrc[j] >> 16; - } - pDest += pt->stride/2; - ptrc += srcStride; - } - } - break; - case PIPE_FORMAT_Z32_FLOAT: - { - float *pDest = (float *) (map + y * pt->stride + x*4); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 32-bit integer Z to float Z */ - const double scale = 1.0 / 0xffffffffU; - pDest[j] = (float) (ptrc[j] * scale); - } - pDest += pt->stride/4; - ptrc += srcStride; - } - } - break; - case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: - { - float *pDest = (float *) (map + y * pt->stride + x*8); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 32-bit integer Z to float Z */ - const double scale = 1.0 / 0xffffffffU; - pDest[j*2] = (float) (ptrc[j] * scale); - } - pDest += pt->stride/4; - ptrc += srcStride; - } - } - break; - default: - assert(0); - } -} - - -void -pipe_get_tile_ui_format(struct pipe_transfer *pt, - const void *src, - uint x, uint y, uint w, uint h, - enum pipe_format format, - unsigned int *p) +pipe_get_tile_rgba(struct pipe_transfer *pt, + const void *src, + uint x, uint y, uint w, uint h, + enum pipe_format format, + void *dst) { unsigned dst_stride = w * 4; void *packed; @@ -859,38 +435,58 @@ pipe_get_tile_ui_format(struct pipe_transfer *pt, pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0); - pipe_tile_raw_to_unsigned(format, packed, w, h, p, dst_stride); - - FREE(packed); -} - - -void -pipe_get_tile_i_format(struct pipe_transfer *pt, - const void *src, - uint x, uint y, uint w, uint h, - enum pipe_format format, - int *p) -{ - unsigned dst_stride = w * 4; - void *packed; - - if (u_clip_tile(x, y, &w, &h, &pt->box)) { - return; - } - - packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); - if (!packed) { - return; - } - - if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) { - assert((x & 1) == 0); + if (util_format_is_pure_uint(format) && + !util_format_is_depth_or_stencil(format)) { + util_format_read_4ui(format, + dst, dst_stride * sizeof(float), + packed, util_format_get_stride(format, w), + 0, 0, w, h); + } else if (util_format_is_pure_sint(format)) { + util_format_read_4i(format, + dst, dst_stride * sizeof(float), + packed, util_format_get_stride(format, w), + 0, 0, w, h); + } else { + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + z16_get_tile_rgba((ushort *) packed, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_Z32_UNORM: + z32_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_Z24X8_UNORM: + s8z24_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_S8_UINT: + s8_get_tile_rgba((unsigned char *) packed, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_X24S8_UINT: + s8x24_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_S8_UINT_Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + z24s8_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_S8X24_UINT: + x24s8_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_Z32_FLOAT: + z32f_get_tile_rgba((float *) packed, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + z32f_x24s8_get_tile_rgba((float *) packed, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_X32_S8X24_UINT: + x32_s8_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); + break; + default: + util_format_read_4f(format, + dst, dst_stride * sizeof(float), + packed, util_format_get_stride(format, w), + 0, 0, w, h); + } } - pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0); - - pipe_tile_raw_to_signed(format, packed, w, h, p, dst_stride); - FREE(packed); } diff --git a/lib/mesa/src/gallium/auxiliary/util/u_tile.h b/lib/mesa/src/gallium/auxiliary/util/u_tile.h index dc1f568a8..3dc087d5e 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_tile.h +++ b/lib/mesa/src/gallium/auxiliary/util/u_tile.h @@ -77,86 +77,15 @@ void pipe_get_tile_rgba(struct pipe_transfer *pt, const void *src, uint x, uint y, uint w, uint h, - float *p); - -void -pipe_get_tile_rgba_format(struct pipe_transfer *pt, - const void *src, - uint x, uint y, uint w, uint h, - enum pipe_format format, - float *p); + enum pipe_format format, + void *dst); void pipe_put_tile_rgba(struct pipe_transfer *pt, void *dst, uint x, uint y, uint w, uint h, - const float *p); - -void -pipe_put_tile_rgba_format(struct pipe_transfer *pt, - void *dst, - uint x, uint y, uint w, uint h, - enum pipe_format format, - const float *p); - - -void -pipe_get_tile_z(struct pipe_transfer *pt, - const void *src, - uint x, uint y, uint w, uint h, - uint *z); - -void -pipe_put_tile_z(struct pipe_transfer *pt, - void *dst, - uint x, uint y, uint w, uint h, - const uint *z); - -void -pipe_tile_raw_to_rgba(enum pipe_format format, - const void *src, - uint w, uint h, - float *dst, unsigned dst_stride); - -void -pipe_tile_raw_to_unsigned(enum pipe_format format, - const void *src, - uint w, uint h, - unsigned *dst, unsigned dst_stride); - -void -pipe_tile_raw_to_signed(enum pipe_format format, - void *src, - uint w, uint h, - int *dst, unsigned dst_stride); - -void -pipe_get_tile_ui_format(struct pipe_transfer *pt, - const void *src, - uint x, uint y, uint w, uint h, - enum pipe_format format, - unsigned int *p); - -void -pipe_get_tile_i_format(struct pipe_transfer *pt, - const void *src, - uint x, uint y, uint w, uint h, - enum pipe_format format, - int *p); - -void -pipe_put_tile_ui_format(struct pipe_transfer *pt, - void *dst, - uint x, uint y, uint w, uint h, - enum pipe_format format, - const unsigned *p); - -void -pipe_put_tile_i_format(struct pipe_transfer *pt, - void *dst, - uint x, uint y, uint w, uint h, - enum pipe_format format, - const int *p); + enum pipe_format format, + const void *src); #ifdef __cplusplus } diff --git a/lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c b/lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c index f33d98b47..0ba8abdf7 100644 --- a/lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c +++ b/lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c @@ -24,9 +24,9 @@ #include "pipe/p_screen.h" #include "util/u_box.h" -#include "util/u_format.h" -#include "util/u_format_rgtc.h" -#include "util/u_format_zs.h" +#include "util/format/u_format.h" +#include "util/format/u_format_rgtc.h" +#include "util/format/u_format_zs.h" #include "util/u_inlines.h" #include "util/u_transfer_helper.h" |