From 0ca1f1e0cc6ccd08f22f7f6b3b18a1cb80a21eeb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Oct 2021 10:58:13 +1000 Subject: [PATCH 1/4] bitset: don't set ranges outside the size. Converting some shader info bitfields into bitsets, showed some cases where we deliberately overflowed the bitfield (trying to set out of bounds bits). Just drop out of bounds bit settting to keep the same behaviour. --- src/util/bitset.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/util/bitset.h b/src/util/bitset.h index 279ad553e798..1a6c4819094d 100644 --- a/src/util/bitset.h +++ b/src/util/bitset.h @@ -222,7 +222,8 @@ __bitset_set_range(BITSET_WORD *r, unsigned start, unsigned end) } #define BITSET_SET_RANGE(x, b, e) \ - __bitset_set_range(x, b, e) + if ((b) < (sizeof(x) * 8) && (e) < (sizeof(x) * 8)) \ + __bitset_set_range(x, b, e) static inline unsigned __bitset_prefix_sum(const BITSET_WORD *x, unsigned b, unsigned n) -- GitLab From 4ca7b226e11d4fbfffbd32d3779a39f6e64e5a1c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 13 Oct 2021 16:02:27 +1000 Subject: [PATCH 2/4] shader_info: use a define for texture limits. This needs to be bumped to 128 for OpenCL --- src/compiler/shader_info.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h index 405b20422880..551c2fd7008b 100644 --- a/src/compiler/shader_info.h +++ b/src/compiler/shader_info.h @@ -34,6 +34,7 @@ extern "C" { #endif #define MAX_INLINABLE_UNIFORMS 4 +#define MAX_SHADER_TEXTURES 32 struct spirv_supported_capabilities { bool address; @@ -189,10 +190,10 @@ typedef struct shader_info { uint64_t patch_outputs_accessed_indirectly; /** Bitfield of which textures are used */ - BITSET_DECLARE(textures_used, 32); + BITSET_DECLARE(textures_used, MAX_SHADER_TEXTURES); /** Bitfield of which textures are used by texelFetch() */ - BITSET_DECLARE(textures_used_by_txf, 32); + BITSET_DECLARE(textures_used_by_txf, MAX_SHADER_TEXTURES); /** Bitfield of which images are used */ uint32_t images_used; -- GitLab From 6bb4b7493ad0a028f33ca63e38d0512ca8e28133 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 13 Oct 2021 16:24:46 +1000 Subject: [PATCH 3/4] shader_info: convert image masks into bitsets. For OpenCL these need to be bumped to 64, first convert them into bitsets with just 32-bits. --- src/compiler/glsl/gl_nir_lower_samplers_as_deref.c | 3 +-- src/compiler/nir/nir_gather_info.c | 12 ++++++------ src/compiler/shader_info.h | 9 ++++++--- src/gallium/drivers/iris/iris_resolve.c | 2 +- src/gallium/drivers/radeonsi/si_compute.c | 4 ++-- src/gallium/drivers/radeonsi/si_descriptors.c | 2 +- src/gallium/drivers/radeonsi/si_shader.c | 2 +- src/gallium/drivers/radeonsi/si_state_shaders.c | 2 +- src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c | 2 +- src/gallium/drivers/zink/zink_program.c | 2 +- src/mesa/state_tracker/st_glsl_to_nir.cpp | 2 +- src/panfrost/bifrost/bifrost_compile.c | 2 +- src/panfrost/lib/pan_shader.c | 2 +- 13 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c b/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c index ddd9697fe52e..b56f77c7ca3b 100644 --- a/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c +++ b/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c @@ -128,9 +128,8 @@ record_images_used(struct shader_info *info, /* Structs have been lowered already, so get_aoa_size is sufficient. */ const unsigned size = glsl_type_is_array(var->type) ? glsl_get_aoa_size(var->type) : 1; - unsigned mask = ((1ull << MAX2(size, 1)) - 1) << var->data.binding; - info->images_used |= mask; + BITSET_SET_RANGE_INSIDE_WORD(info->images_used, var->data.binding, var->data.binding + (MAX2(size, 1) - 1)); } diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index b44a04bf2abe..35e23f93cae1 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -829,8 +829,8 @@ nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint) { shader->info.num_textures = 0; shader->info.num_images = 0; - shader->info.image_buffers = 0; - shader->info.msaa_images = 0; + BITSET_ZERO(shader->info.image_buffers); + BITSET_ZERO(shader->info.msaa_images); shader->info.bit_sizes_float = 0; shader->info.bit_sizes_int = 0; @@ -849,12 +849,12 @@ nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint) const struct glsl_type *image_type = glsl_without_array(var->type); if (glsl_get_sampler_dim(image_type) == GLSL_SAMPLER_DIM_BUF) { - shader->info.image_buffers |= - BITFIELD_RANGE(shader->info.num_images, num_image_slots); + BITSET_SET_RANGE(shader->info.image_buffers, shader->info.num_images, + shader->info.num_images + num_image_slots); } if (glsl_get_sampler_dim(image_type) == GLSL_SAMPLER_DIM_MS) { - shader->info.msaa_images |= - BITFIELD_RANGE(shader->info.num_images, num_image_slots); + BITSET_SET_RANGE(shader->info.msaa_images, shader->info.num_images, + shader->info.num_images + num_image_slots); } shader->info.num_images += num_image_slots; } diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h index 551c2fd7008b..920fe7b346f6 100644 --- a/src/compiler/shader_info.h +++ b/src/compiler/shader_info.h @@ -34,6 +34,7 @@ extern "C" { #endif #define MAX_INLINABLE_UNIFORMS 4 +#define MAX_SHADER_IMAGES 32 #define MAX_SHADER_TEXTURES 32 struct spirv_supported_capabilities { @@ -196,11 +197,13 @@ typedef struct shader_info { BITSET_DECLARE(textures_used_by_txf, MAX_SHADER_TEXTURES); /** Bitfield of which images are used */ - uint32_t images_used; + BITSET_DECLARE(images_used, MAX_SHADER_IMAGES); + /** Bitfield of which images are buffers. */ - uint32_t image_buffers; + BITSET_DECLARE(image_buffers, MAX_SHADER_IMAGES); + /** Bitfield of which images are MSAA. */ - uint32_t msaa_images; + BITSET_DECLARE(msaa_images, MAX_SHADER_IMAGES); /* SPV_KHR_float_controls: execution mode for floating point ops */ uint16_t float_controls_execution_mode; diff --git a/src/gallium/drivers/iris/iris_resolve.c b/src/gallium/drivers/iris/iris_resolve.c index 50fc9a94dfec..892111196207 100644 --- a/src/gallium/drivers/iris/iris_resolve.c +++ b/src/gallium/drivers/iris/iris_resolve.c @@ -121,7 +121,7 @@ resolve_image_views(struct iris_context *ice, bool *draw_aux_buffer_disabled, bool consider_framebuffer) { - uint32_t views = info ? (shs->bound_image_views & info->images_used) : 0; + uint32_t views = info ? (shs->bound_image_views & info->images_used[0]) : 0; while (views) { const int i = u_bit_scan(&views); diff --git a/src/gallium/drivers/radeonsi/si_compute.c b/src/gallium/drivers/radeonsi/si_compute.c index 0ae232db2713..ba403ddf1537 100644 --- a/src/gallium/drivers/radeonsi/si_compute.c +++ b/src/gallium/drivers/radeonsi/si_compute.c @@ -151,10 +151,10 @@ static void si_create_compute_state_async(void *job, void *gdata, int thread_ind /* Images in user SGPRs. */ unsigned non_msaa_images = u_bit_consecutive(0, sel->info.base.num_images) & - ~sel->info.base.msaa_images; + ~sel->info.base.msaa_images[0]; for (unsigned i = 0; i < 3 && non_msaa_images & (1 << i); i++) { - unsigned num_sgprs = sel->info.base.image_buffers & (1 << i) ? 4 : 8; + unsigned num_sgprs = BITSET_TEST(sel->info.base.image_buffers, i) ? 4 : 8; if (align(user_sgprs, num_sgprs) + num_sgprs > 16) break; diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index f02855743a51..ea6029d0b163 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -2182,7 +2182,7 @@ void si_emit_compute_shader_pointers(struct si_context *sctx) unsigned num_sgprs = 8; /* Image buffers are in desc[4..7]. */ - if (shader->info.base.image_buffers & (1 << i)) { + if (BITSET_TEST(shader->info.base.image_buffers, i)) { desc_offset += 4; num_sgprs = 4; } diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 546f9da11203..c0610894fbef 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -720,7 +720,7 @@ void si_init_shader_args(struct si_shader_context *ctx, bool ngg_cull_shader) } /* Images in user SGPRs. */ for (unsigned i = 0; i < shader->selector->cs_num_images_in_user_sgprs; i++) { - unsigned num_sgprs = shader->selector->info.base.image_buffers & (1 << i) ? 4 : 8; + unsigned num_sgprs = BITSET_TEST(shader->selector->info.base.image_buffers, i) ? 4 : 8; while (ctx->args.num_sgprs_used % num_sgprs != 0) ac_add_arg(&ctx->args, AC_ARG_SGPR, 1, AC_ARG_INT, NULL); diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 921bd5446415..179737f52bbe 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -2784,7 +2784,7 @@ void si_get_active_slot_masks(const struct si_shader_info *info, uint64_t *const num_constbufs = info->base.num_ubos; /* two 8-byte images share one 16-byte slot */ num_images = align(info->base.num_images, 2); - num_msaa_images = align(util_last_bit(info->base.msaa_images), 2); + num_msaa_images = align(BITSET_LAST_BIT(info->base.msaa_images), 2); num_samplers = BITSET_LAST_BIT(info->base.textures_used); /* The layout is: sb[last] ... sb[0], cb[0] ... cb[last] */ diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c index 5a28cce44eb8..6af16dcbff18 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c @@ -3771,7 +3771,7 @@ nir_to_spirv(struct nir_shader *s, const struct zink_so_info *so_info, uint32_t goto fail; spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShader); - if (s->info.image_buffers != 0) + if (BITSET_COUNT(s->info.image_buffers) != 0) spirv_builder_emit_cap(&ctx.builder, SpvCapabilityImageBuffer); spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySampledBuffer); diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index a735f67a6d60..9ad1d91fd38b 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -485,7 +485,7 @@ zink_program_get_descriptor_usage(struct zink_context *ctx, enum pipe_shader_typ case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: return BITSET_TEST_RANGE(zs->nir->info.textures_used, 0, PIPE_MAX_SAMPLERS - 1); case ZINK_DESCRIPTOR_TYPE_IMAGE: - return zs->nir->info.images_used; + return BITSET_TEST_RANGE(zs->nir->info.images_used, 0, PIPE_MAX_SHADER_IMAGES - 1); default: unreachable("unknown descriptor type!"); } diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index deface8ad4b3..7c4cb7e17a16 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -988,7 +988,7 @@ st_nir_lower_samplers(struct pipe_screen *screen, nir_shader *nir, if (prog) { BITSET_COPY(prog->info.textures_used, nir->info.textures_used); BITSET_COPY(prog->info.textures_used_by_txf, nir->info.textures_used_by_txf); - prog->info.images_used = nir->info.images_used; + BITSET_COPY(prog->info.images_used, nir->info.images_used); } } diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index 44bf23345657..8e2632894545 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -3447,7 +3447,7 @@ bi_optimize_nir(nir_shader *nir, unsigned gpu_id, bool is_blend) nir->info.outputs_accessed_indirectly || nir->info.patch_inputs_read_indirectly || nir->info.patch_outputs_accessed_indirectly || - nir->info.images_used; + nir->info.images_used[0]; if (any_indirects) { nir_convert_to_lcssa(nir, true, true); diff --git a/src/panfrost/lib/pan_shader.c b/src/panfrost/lib/pan_shader.c index 6924155fa352..9a2aaf7078d5 100644 --- a/src/panfrost/lib/pan_shader.c +++ b/src/panfrost/lib/pan_shader.c @@ -300,7 +300,7 @@ GENX(pan_shader_compile)(nir_shader *s, else info->ubo_count = s->info.num_ubos; - info->attribute_count += util_last_bit(s->info.images_used); + info->attribute_count += BITSET_LAST_BIT(s->info.images_used); info->writes_global = s->info.writes_memory; info->sampler_count = info->texture_count = BITSET_LAST_BIT(s->info.textures_used); -- GitLab From 98c9ae81ae79e95eb08d9a452c16507ccd7914f4 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 13 Oct 2021 16:25:47 +1000 Subject: [PATCH 4/4] shader_info: bump limits to support OpenCL 3.0 OpenCL requires 128 read only, and 64 writable images which translates into this. This prepares shader info for those limits. --- src/compiler/shader_info.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h index 920fe7b346f6..f76dfac6be56 100644 --- a/src/compiler/shader_info.h +++ b/src/compiler/shader_info.h @@ -34,8 +34,8 @@ extern "C" { #endif #define MAX_INLINABLE_UNIFORMS 4 -#define MAX_SHADER_IMAGES 32 -#define MAX_SHADER_TEXTURES 32 +#define MAX_SHADER_IMAGES 64 +#define MAX_SHADER_TEXTURES 128 struct spirv_supported_capabilities { bool address; -- GitLab