Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2019-08-15 00:43:03 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-08-15 00:59:34 +0300
commit6fcd071c7bcb8c9a5e0a7d0e7a6ef6363e43627e (patch)
tree98b5220f921ef3c473d937997016f901647f6cbf /source/blender/gpu
parent80e9eb66d568311f4acddf5dfe5bbf8f8618f18d (diff)
GPU: Vertex Format: Increase number of byte per attribute name
This reduces the risks of hash collision while maintaining a small number of character per attrib.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/GPU_vertex_format.h2
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.c49
2 files changed, 24 insertions, 27 deletions
diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h
index 97c1828b593..8c22e3e1104 100644
--- a/source/blender/gpu/GPU_vertex_format.h
+++ b/source/blender/gpu/GPU_vertex_format.h
@@ -35,7 +35,7 @@
#define GPU_VERT_ATTR_NAMES_BUF_LEN 256
#define GPU_VERT_FORMAT_MAX_NAMES 63 /* More than enough, actual max is ~30. */
/* Computed as GPU_VERT_ATTR_NAMES_BUF_LEN / 30 (actual max format name). */
-#define GPU_MAX_SAFE_ATTRIB_NAME 8
+#define GPU_MAX_SAFE_ATTRIB_NAME 12
typedef enum {
GPU_COMP_I8,
diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c
index 2cfb17b1568..11df86c0b3a 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.c
+++ b/source/blender/gpu/intern/gpu_vertex_format.c
@@ -220,20 +220,6 @@ int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
return -1;
}
-/* Encode 4 original bytes into 6 safe bytes. */
-static void safe_bytes(char out[6], const char data[4])
-{
- char safe_chars[63] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
-
- uint32_t in = *(uint32_t *)data;
- for (int i = 0; i < 6; i++) {
- /* Encoding in base63 */
- out[i] = safe_chars[in % 63u];
- in /= 63u;
- }
-}
-
-#if 0 /* For when we can use 11chars names. */
/* Encode 8 original bytes into 11 safe bytes. */
static void safe_bytes(char out[11], const char data[8])
{
@@ -246,7 +232,6 @@ static void safe_bytes(char out[11], const char data[8])
in /= 63lu;
}
}
-#endif
/* Warning: Always add a prefix to the result of this function as
* the generated string can start with a number and not be a valid attribute name. */
@@ -254,22 +239,34 @@ void GPU_vertformat_safe_attrib_name(const char *attrib_name,
char *r_safe_name,
uint UNUSED(max_len))
{
- char data[4] = {0};
- /* We use a hash to identify each data layer based on its name.
- * NOTE: This is still prone to hash collision but the risks are very low.*/
- *(uint *)data = BLI_ghashutil_strhash_p_murmur(attrib_name);
+ char data[8] = {0};
+ uint len = strlen(attrib_name);
+
+ if (len > 8) {
+ /* Start with the first 4 chars of the name; */
+ for (int i = 0; i < 4; i++) {
+ data[i] = attrib_name[i];
+ }
+ /* We use a hash to identify each data layer based on its name.
+ * NOTE: This is still prone to hash collision but the risks are very low.*/
+ /* Start hashing after the first 2 chars. */
+ *(uint *)&data[4] = BLI_ghashutil_strhash_p_murmur(attrib_name + 4);
+ }
+ else {
+ /* Copy the whole name. Collision is barelly possible
+ * (hash would have to be equal to the last 4 bytes). */
+ for (int i = 0; i < 8 && attrib_name[i] != '\0'; i++) {
+ data[i] = attrib_name[i];
+ }
+ }
/* Convert to safe bytes characters. */
safe_bytes(r_safe_name, data);
/* End the string */
- r_safe_name[6] = '\0';
-
- /* TOOD(fclem) When UV and Tangent buffers will be separated, name buffer will have plenty more
- * space. In this case, we can think of having ~13 chars for each name which would be enough to
- * encode some of the input string along with the hash to reduce colision possibility. */
+ r_safe_name[11] = '\0';
- BLI_assert(GPU_MAX_SAFE_ATTRIB_NAME >= 7);
+ BLI_assert(GPU_MAX_SAFE_ATTRIB_NAME >= 12);
#if 0 /* For debugging */
- printf("%s > %x > %s\n", attrib_name, *(uint32_t *)data, r_safe_name);
+ printf("%s > %lx > %s\n", attrib_name, *(uint64_t *)data, r_safe_name);
#endif
}