tgsi/scan: use wrap-around shift behavior explicitly for file_mask
authorRoland Scheidegger <sroland@vmware.com>
Fri, 2 Mar 2018 02:00:41 +0000 (03:00 +0100)
committerRoland Scheidegger <sroland@vmware.com>
Tue, 6 Mar 2018 04:18:17 +0000 (05:18 +0100)
The comment said it will only represent the lowest 32 regs. This was
not entirely true in practice, since at least on x86 you'll get
masked shifts (unless the compiler could recognize it already and toss
it out). It turns out this actually works out alright (presumably
noone uses it for temp regs) when increasing max sampler views, so
make that behavior explicit.
Albeit it feels a bit hacky (but in any case, explicit behavior there
is better than undefined behavior).

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/auxiliary/tgsi/tgsi_scan.c
src/gallium/drivers/llvmpipe/lp_state_fs.c
src/gallium/drivers/swr/swr_shader.cpp

index c35eff25ba8d80a1d6ef878d59abe7cc2463785c..4a2b3540639470906016488e7efdb0abbb1f3ffc 100644 (file)
@@ -585,8 +585,11 @@ scan_declaration(struct tgsi_shader_info *info,
       int buffer;
       unsigned index, target, type;
 
-      /* only first 32 regs will appear in this bitfield */
-      info->file_mask[file] |= (1 << reg);
+      /*
+       * only first 32 regs will appear in this bitfield, if larger
+       * bits will wrap around.
+       */
+      info->file_mask[file] |= (1u << (reg & 31));
       info->file_count[file]++;
       info->file_max[file] = MAX2(info->file_max[file], (int)reg);
 
index 603fd84f6b1d0ea00af6c15b46be559a63dd8d01..66645b07ac7061d4a76003ce35e8b5482a5a1ce2 100644 (file)
@@ -3323,7 +3323,12 @@ make_variant_key(struct llvmpipe_context *lp,
    if (shader->info.base.file_max[TGSI_FILE_SAMPLER_VIEW] != -1) {
       key->nr_sampler_views = shader->info.base.file_max[TGSI_FILE_SAMPLER_VIEW] + 1;
       for(i = 0; i < key->nr_sampler_views; ++i) {
-         if(shader->info.base.file_mask[TGSI_FILE_SAMPLER_VIEW] & (1 << i)) {
+         /*
+          * Note sview may exceed what's representable by file_mask.
+          * This will still work, the only downside is that not actually
+          * used views may be included in the shader key.
+          */
+         if(shader->info.base.file_mask[TGSI_FILE_SAMPLER_VIEW] & (1u << (i & 31))) {
             lp_sampler_static_texture_state(&key->state[i].texture_state,
                                             lp->sampler_views[PIPE_SHADER_FRAGMENT][i]);
          }
index e5fb679f8b3fcc4bc94d2f47aeb570b8ff16371d..477fa7f2db45b501765252fceccf924297d21167 100644 (file)
@@ -98,7 +98,7 @@ swr_generate_sampler_key(const struct lp_tgsi_info &info,
       key.nr_sampler_views =
          info.base.file_max[TGSI_FILE_SAMPLER_VIEW] + 1;
       for (unsigned i = 0; i < key.nr_sampler_views; i++) {
-         if (info.base.file_mask[TGSI_FILE_SAMPLER_VIEW] & (1 << i)) {
+         if (info.base.file_mask[TGSI_FILE_SAMPLER_VIEW] & (1u << (i & 31))) {
             const struct pipe_sampler_view *view =
                ctx->sampler_views[shader_type][i];
             lp_sampler_static_texture_state(