From 90679f1dcf3e1ad9e8ef50372de39578bc196ec5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= <pedrojrulez@gmail.com>
Date: Wed, 31 Jul 2024 19:56:39 +0200
Subject: [PATCH] Report shader arrays sized after spec constants as zero-sized

This effectively disables validation of the size of the data provided.
---
 thirdparty/README.md                           |  2 +-
 ....patch => 1-specialization-constants.patch} |  0
 .../2-zero-size-for-sc-sized-arrays.patch      | 18 ++++++++++++++++++
 thirdparty/spirv-reflect/spirv_reflect.c       |  7 +++++++
 4 files changed, 26 insertions(+), 1 deletion(-)
 rename thirdparty/spirv-reflect/patches/{specialization-constants.patch => 1-specialization-constants.patch} (100%)
 create mode 100644 thirdparty/spirv-reflect/patches/2-zero-size-for-sc-sized-arrays.patch

diff --git a/thirdparty/README.md b/thirdparty/README.md
index 9a56f6baa41b..47618d675bdd 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -845,7 +845,7 @@ Files extracted from upstream source:
 Some downstream changes have been made and are identified by
 `// -- GODOT begin --` and `// -- GODOT end --` comments.
 They can be reapplied using the patches included in the `patches`
-folder.
+folder, in order.
 
 
 ## squish
diff --git a/thirdparty/spirv-reflect/patches/specialization-constants.patch b/thirdparty/spirv-reflect/patches/1-specialization-constants.patch
similarity index 100%
rename from thirdparty/spirv-reflect/patches/specialization-constants.patch
rename to thirdparty/spirv-reflect/patches/1-specialization-constants.patch
diff --git a/thirdparty/spirv-reflect/patches/2-zero-size-for-sc-sized-arrays.patch b/thirdparty/spirv-reflect/patches/2-zero-size-for-sc-sized-arrays.patch
new file mode 100644
index 000000000000..dbf6069d075a
--- /dev/null
+++ b/thirdparty/spirv-reflect/patches/2-zero-size-for-sc-sized-arrays.patch
@@ -0,0 +1,18 @@
+diff --git a/thirdparty/spirv-reflect/spirv_reflect.c b/thirdparty/spirv-reflect/spirv_reflect.c
+index c96dd85439..2ca9c8580d 100644
+--- a/thirdparty/spirv-reflect/spirv_reflect.c
++++ b/thirdparty/spirv-reflect/spirv_reflect.c
+@@ -2692,6 +2692,13 @@ static SpvReflectResult ParseDescriptorBlockVariableSizes(SpvReflectPrvParser* p
+         // ...then array
+         uint32_t element_count = (p_member_var->array.dims_count > 0 ? 1 : 0);
+         for (uint32_t i = 0; i < p_member_var->array.dims_count; ++i) {
++// -- GODOT begin --
++          if (p_member_var->array.spec_constant_op_ids[i] != (uint32_t)INVALID_VALUE) {
++            // Force size to be reported as 0 to effectively disable buffer size validation, since
++            // the value is unreliable anyway as only valid for the default values of the SCs involved.
++            element_count = 0;
++          }
++// -- GODOT end --
+           element_count *= p_member_var->array.dims[i];
+         }
+         p_member_var->size = element_count * p_member_var->array.stride;
diff --git a/thirdparty/spirv-reflect/spirv_reflect.c b/thirdparty/spirv-reflect/spirv_reflect.c
index c96dd854392d..d6c926b40a11 100644
--- a/thirdparty/spirv-reflect/spirv_reflect.c
+++ b/thirdparty/spirv-reflect/spirv_reflect.c
@@ -2692,6 +2692,13 @@ static SpvReflectResult ParseDescriptorBlockVariableSizes(SpvReflectPrvParser* p
         // ...then array
         uint32_t element_count = (p_member_var->array.dims_count > 0 ? 1 : 0);
         for (uint32_t i = 0; i < p_member_var->array.dims_count; ++i) {
+// -- GODOT begin --
+          if (p_member_var->array.spec_constant_op_ids[i] != (uint32_t)INVALID_VALUE) {
+            // Force size to be reported as 0 to effectively disable buffer size validation, since
+            // the value is unreliable anyway as only valid for the default values of the SCs involved.
+            element_count = 0;
+          }
+// -- GODOT end --
           element_count *= p_member_var->array.dims[i];
         }
         p_member_var->size = element_count * p_member_var->array.stride;