diff --git a/src/gallium/drivers/d3d12/d3d12_batch.cpp b/src/gallium/drivers/d3d12/d3d12_batch.cpp index 3728df8f42b..40394a0f82d 100644 --- a/src/gallium/drivers/d3d12/d3d12_batch.cpp +++ b/src/gallium/drivers/d3d12/d3d12_batch.cpp @@ -37,6 +37,20 @@ #include + +unsigned d3d12_sampler_desc_table_key_hash(const void* key) +{ + const d3d12_sampler_desc_table_key* table = (d3d12_sampler_desc_table_key*)key; + + return _mesa_hash_data(table->descs, sizeof(table->descs[0]) * table->count); +} +bool d3d12_sampler_desc_table_key_equals(const void* a, const void* b) +{ + const d3d12_sampler_desc_table_key* table_a = (d3d12_sampler_desc_table_key*)a; + const d3d12_sampler_desc_table_key* table_b = (d3d12_sampler_desc_table_key*)b; + return table_a->count == table_b->count && memcmp(table_a->descs, table_b->descs, sizeof(table_a->descs[0]) * table_a->count) == 0; +} + bool d3d12_init_batch(struct d3d12_context *ctx, struct d3d12_batch *batch) { @@ -44,6 +58,8 @@ d3d12_init_batch(struct d3d12_context *ctx, struct d3d12_batch *batch) batch->bos = _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); + batch->sampler_tables = _mesa_hash_table_create(NULL, d3d12_sampler_desc_table_key_hash, + d3d12_sampler_desc_table_key_equals); batch->sampler_views = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); batch->surfaces = _mesa_set_create(NULL, _mesa_hash_pointer, @@ -52,7 +68,7 @@ d3d12_init_batch(struct d3d12_context *ctx, struct d3d12_batch *batch) _mesa_hash_pointer, _mesa_key_pointer_equal); - if (!batch->bos || !batch->sampler_views || !batch->surfaces || !batch->objects) + if (!batch->bos || !batch->sampler_tables || !batch->sampler_views || !batch->surfaces || !batch->objects) return false; util_dynarray_init(&batch->zombie_samplers, NULL); @@ -86,6 +102,13 @@ delete_bo(hash_entry *entry) d3d12_bo_unreference(bo); } +static void +delete_sampler_view_table(hash_entry *entry) +{ + FREE((void*)entry->key); + FREE(entry->data); +} + static void delete_sampler_view(set_entry *entry) { @@ -121,6 +144,7 @@ d3d12_reset_batch(struct d3d12_context *ctx, struct d3d12_batch *batch, uint64_t } _mesa_hash_table_clear(batch->bos, delete_bo); + _mesa_hash_table_clear(batch->sampler_tables, delete_sampler_view_table); _mesa_set_clear(batch->sampler_views, delete_sampler_view); _mesa_set_clear(batch->surfaces, delete_surface); _mesa_set_clear(batch->objects, delete_object); @@ -149,6 +173,7 @@ d3d12_destroy_batch(struct d3d12_context *ctx, struct d3d12_batch *batch) d3d12_descriptor_heap_free(batch->sampler_heap); d3d12_descriptor_heap_free(batch->view_heap); _mesa_hash_table_destroy(batch->bos, NULL); + _mesa_hash_table_destroy(batch->sampler_tables, NULL); _mesa_set_destroy(batch->sampler_views, NULL); _mesa_set_destroy(batch->surfaces, NULL); _mesa_set_destroy(batch->objects, NULL); diff --git a/src/gallium/drivers/d3d12/d3d12_batch.h b/src/gallium/drivers/d3d12/d3d12_batch.h index 191fa69978b..db37a2c5676 100644 --- a/src/gallium/drivers/d3d12/d3d12_batch.h +++ b/src/gallium/drivers/d3d12/d3d12_batch.h @@ -26,6 +26,7 @@ #include "util/u_dynarray.h" #include "util/hash_table.h" +#include "pipe/p_state.h" #include #include "d3d12_common.h" @@ -34,10 +35,18 @@ struct d3d12_bo; struct d3d12_descriptor_heap; struct d3d12_fence; + +struct d3d12_sampler_desc_table_key +{ + D3D12_CPU_DESCRIPTOR_HANDLE descs[PIPE_MAX_SHADER_SAMPLER_VIEWS]; + unsigned count; +}; + struct d3d12_batch { struct d3d12_fence *fence; struct hash_table *bos; + struct hash_table *sampler_tables; struct set *sampler_views; struct set *surfaces; struct set *objects; diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp index 58784e61c2e..f9b11bb5ab8 100644 --- a/src/gallium/drivers/d3d12/d3d12_draw.cpp +++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp @@ -191,13 +191,10 @@ fill_sampler_descriptors(struct d3d12_context *ctx, { const struct d3d12_shader *shader = shader_sel->current; struct d3d12_batch *batch = d3d12_current_batch(ctx); - D3D12_CPU_DESCRIPTOR_HANDLE descs[PIPE_MAX_SHADER_SAMPLER_VIEWS]; - struct d3d12_descriptor_handle table_start; + struct d3d12_sampler_desc_table_key view; - d2d12_descriptor_heap_get_next_handle(batch->sampler_heap, &table_start); - - for (unsigned i = shader->begin_srv_binding; i < shader->end_srv_binding; i++) - { + view.count = 0; + for (unsigned i = shader->begin_srv_binding; i < shader->end_srv_binding; i++, view.count++) { struct d3d12_sampler_state *sampler; if (i == shader->pstipple_binding) { @@ -209,15 +206,32 @@ fill_sampler_descriptors(struct d3d12_context *ctx, unsigned desc_idx = i - shader->begin_srv_binding; if (sampler != NULL) { if (sampler->is_shadow_sampler && shader_sel->compare_with_lod_bias_grad) - descs[desc_idx] = sampler->handle_without_shadow.cpu_handle; + view.descs[desc_idx] = sampler->handle_without_shadow.cpu_handle; else - descs[desc_idx] = sampler->handle.cpu_handle; + view.descs[desc_idx] = sampler->handle.cpu_handle; } else - descs[desc_idx] = ctx->null_sampler.cpu_handle; + view.descs[desc_idx] = ctx->null_sampler.cpu_handle; } - d3d12_descriptor_heap_append_handles(batch->sampler_heap, descs, shader->end_srv_binding - shader->begin_srv_binding); - return table_start.gpu_handle; + hash_entry* sampler_entry = + (hash_entry*)_mesa_hash_table_search(batch->sampler_tables, &view); + + if (!sampler_entry) { + d3d12_sampler_desc_table_key* sampler_table_key = MALLOC_STRUCT(d3d12_sampler_desc_table_key); + sampler_table_key->count = view.count; + memcpy(sampler_table_key->descs, &view.descs, view.count * sizeof(view.descs[0])); + + d3d12_descriptor_handle* sampler_table_data = MALLOC_STRUCT(d3d12_descriptor_handle); + d2d12_descriptor_heap_get_next_handle(batch->sampler_heap, sampler_table_data); + + d3d12_descriptor_heap_append_handles(batch->sampler_heap, view.descs, shader->end_srv_binding - shader->begin_srv_binding); + + _mesa_hash_table_insert(batch->sampler_tables, sampler_table_key, sampler_table_data); + + return sampler_table_data->gpu_handle; + } else + return ((d3d12_descriptor_handle*)sampler_entry->data)->gpu_handle; + } static D3D12_UAV_DIMENSION