Fix T72467: Crash when using many (>64) images in a shader

Previously this limit was rather high, but with UDIMs it's fairly easy
to reach this many images. Even though this exceeds the texture limit
on most hardware as far as I can tell, it should at least not crash.

The old code uses a fixed array which overflows eventually, this fix
replaces the array with a GSet.

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D6416
This commit is contained in:
Lukas Stockner
2019-12-16 15:49:19 +01:00
committed by Lukas Stockner
parent 8d16dc029e
commit 6a3f2b30d2
3 changed files with 21 additions and 13 deletions

View File

@@ -406,6 +406,9 @@ GSet *BLI_gset_str_new(const char *info);
GSet *BLI_gset_pair_new_ex(const char *info, const unsigned int nentries_reserve)
ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
GSet *BLI_gset_pair_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
GSet *BLI_gset_int_new_ex(const char *info,
const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
GSet *BLI_gset_int_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
/** \} */

View File

@@ -278,4 +278,13 @@ GSet *BLI_gset_pair_new(const char *info)
return BLI_gset_pair_new_ex(info, 0);
}
GSet *BLI_gset_int_new_ex(const char *info, const uint nentries_reserve)
{
return BLI_gset_new_ex(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, info, nentries_reserve);
}
GSet *BLI_gset_int_new(const char *info)
{
return BLI_gset_int_new_ex(info, 0);
}
/** \} */

View File

@@ -2131,8 +2131,10 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
static int count_active_texture_sampler(GPUShader *shader, char *source)
{
char *code = source;
int samplers_id[64]; /* Remember this is per stage. */
int sampler_len = 0;
/* Remember this is per stage. */
GSet *sampler_ids = BLI_gset_int_new(__func__);
int num_samplers = 0;
while ((code = strstr(code, "uniform "))) {
/* Move past "uniform". */
@@ -2167,22 +2169,16 @@ static int count_active_texture_sampler(GPUShader *shader, char *source)
continue;
}
/* Catch duplicates. */
bool is_duplicate = false;
for (int i = 0; i < sampler_len; i++) {
if (samplers_id[i] == id) {
is_duplicate = true;
}
}
if (!is_duplicate) {
samplers_id[sampler_len] = id;
sampler_len++;
if (BLI_gset_add(sampler_ids, POINTER_FROM_INT(id))) {
num_samplers++;
}
}
}
}
return sampler_len;
BLI_gset_free(sampler_ids, NULL);
return num_samplers;
}
static bool gpu_pass_shader_validate(GPUPass *pass, GPUShader *shader)