dev-util/spirv-headers,dev-util/spirv-tools: update patches for vksp
Also installed new needed files by vksp in
`/usr/include/spirv-tools/vksp`
BUG=None
TEST=emerge-brya spirv-tools spirv-headers
Cq-Depend: chromium:5352251
Change-Id: I86cebb637f5f490c39d4f80e05871e1745680e39
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/overlays/portage-stable/+/5355626
Tested-by: Romaric Jodin <rjodin@chromium.org>
Commit-Queue: Romaric Jodin <rjodin@chromium.org>
Reviewed-by: Prahlad Kilambi <prahladk@google.com>
diff --git a/dev-util/spirv-headers/files/GITHUB-PR-398-vksp_header.patch b/dev-util/spirv-headers/files/GITHUB-PR-398-vksp_header.patch
index fcbe714..0f41e2c 100644
--- a/dev-util/spirv-headers/files/GITHUB-PR-398-vksp_header.patch
+++ b/dev-util/spirv-headers/files/GITHUB-PR-398-vksp_header.patch
@@ -1,3 +1,29 @@
+commit 2e3dc2e17b591a5303aa73f316ffcfefb3516e11
+Author: Romaric Jodin <89833130+rjodinchr@users.noreply.github.com>
+Date: Wed Jan 10 18:02:35 2024 +0100
+
+ Publish the header for the vulkan-shader-profiler embedded reflection… (#398)
+
+ * Publish the header for the vulkan-shader-profiler embedded reflection non-semantic instruction set
+
+ vulkan-shader-profiler is a tool based on perfetto to help vulkan
+ developer profil their applications.
+ First on the Host side using perfetto, but then using the extractor
+ and the runner, this tools allow to get inside about a shader using
+ counters (based on SPV_KHR_shader_clock)
+
+ * Update include/spirv/unified1/NonSemanticVkspReflection.h
+
+ Co-authored-by: Ben Ashbaugh <ben.ashbaugh@intel.com>
+
+ * Revert "Update include/spirv/unified1/NonSemanticVkspReflection.h"
+
+ This reverts commit 3c9c24db2949c59926bd25d777e10ab60ae2cb9c.
+
+ ---------
+
+ Co-authored-by: Ben Ashbaugh <ben.ashbaugh@intel.com>
+
diff --git a/BUILD.bazel b/BUILD.bazel
index c898ade..25634d9 100644
--- a/BUILD.bazel
@@ -36,7 +62,7 @@
"include/spirv/unified1/spirv.hpp",
diff --git a/include/spirv/unified1/NonSemanticVkspReflection.h b/include/spirv/unified1/NonSemanticVkspReflection.h
new file mode 100644
-index 0000000..7d73015
+index 0000000..47a279d
--- /dev/null
+++ b/include/spirv/unified1/NonSemanticVkspReflection.h
@@ -0,0 +1,57 @@
@@ -85,9 +111,9 @@
+ NonSemanticVkspReflectionStopCounter = 3,
+ NonSemanticVkspReflectionPushConstants = 4,
+ NonSemanticVkspReflectionSpecializationMapEntry = 5,
-+ NonSemanticVkspReflectionDescriptorSetsBuffer = 6,
-+ NonSemanticVkspReflectionDescriptorSetsImage = 7,
-+ NonSemanticVkspReflectionDescriptorSetsSampler = 8,
++ NonSemanticVkspReflectionDescriptorSetBuffer = 6,
++ NonSemanticVkspReflectionDescriptorSetImage = 7,
++ NonSemanticVkspReflectionDescriptorSetSampler = 8,
+ NonSemanticVkspReflectionInstructionsMax = 0x7fffffff
+};
+
diff --git a/dev-util/spirv-headers/spirv-headers-1.3.261-r3.ebuild b/dev-util/spirv-headers/spirv-headers-1.3.261-r4.ebuild
similarity index 100%
rename from dev-util/spirv-headers/spirv-headers-1.3.261-r3.ebuild
rename to dev-util/spirv-headers/spirv-headers-1.3.261-r4.ebuild
diff --git a/dev-util/spirv-tools/files/GITHUB-PR-5512-vksp_passes.patch b/dev-util/spirv-tools/files/GITHUB-PR-5512-vksp_passes.patch
index b9caf7f..f3ce554 100644
--- a/dev-util/spirv-tools/files/GITHUB-PR-5512-vksp_passes.patch
+++ b/dev-util/spirv-tools/files/GITHUB-PR-5512-vksp_passes.patch
@@ -1,56 +1,14 @@
-diff --git a/Android.mk b/Android.mk
-index dcb8d631..9cfa5fc4 100644
---- a/Android.mk
-+++ b/Android.mk
-@@ -286,6 +286,7 @@ $(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-shader-bal
- $(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-shader-explicit-vertex-parameter,""))
- $(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-shader-trinary-minmax,""))
- $(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),nonsemantic.clspvreflection,""))
-+$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),nonsemantic.vkspreflection,""))
-
- define gen_spvtools_enum_string_mapping
- $(call generate-file-dir,$(1)/extension_enum.inc.inc)
-diff --git a/BUILD.bazel b/BUILD.bazel
-index a2342770..8c26b15c 100644
---- a/BUILD.bazel
-+++ b/BUILD.bazel
-@@ -58,6 +58,8 @@ generate_vendor_tables(extension = "debuginfo")
-
- generate_vendor_tables(extension = "nonsemantic.clspvreflection")
-
-+generate_vendor_tables(extension = "nonsemantic.vkspreflection")
-+
- generate_vendor_tables(
- extension = "opencl.debuginfo.100",
- operand_kind_prefix = "CLDEBUG100_",
-@@ -147,6 +149,7 @@ cc_library(
- ":gen_vendor_tables_debuginfo",
- ":gen_vendor_tables_nonsemantic_clspvreflection",
- ":gen_vendor_tables_nonsemantic_shader_debuginfo_100",
-+ ":gen_vendor_tables_nonsemantic_vkspreflection",
- ":gen_vendor_tables_opencl_debuginfo_100",
- ":gen_vendor_tables_spv_amd_gcn_shader",
- ":gen_vendor_tables_spv_amd_shader_ballot",
-diff --git a/BUILD.gn b/BUILD.gn
-index bc48e43b..84e262a7 100644
---- a/BUILD.gn
-+++ b/BUILD.gn
-@@ -331,6 +331,10 @@ spvtools_vendor_tables = [
- "nonsemantic.shader.debuginfo.100",
- "SHDEBUG100_",
- ],
-+ [
-+ "nonsemantic.vkspreflection",
-+ "...nil...",
-+ ],
- ]
-
- foreach(table_def, spvtools_vendor_tables) {
+commit 1df303da6e1b827277c806e159dcb40774f92567
+Author: Romaric Jodin <rjodin@chromium.org>
+Date: Fri Mar 8 05:59:04 2024 +0100
+
+ add support for vulkan-shader-profiler external passes
+
diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h
-index 0208097a..81be83d4 100644
+index a7b57b82..08cfd657 100644
--- a/include/spirv-tools/libspirv.h
+++ b/include/spirv-tools/libspirv.h
-@@ -318,6 +318,7 @@ typedef enum spv_ext_inst_type_t {
+@@ -333,6 +333,7 @@ typedef enum spv_ext_inst_type_t {
SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100,
SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION,
SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100,
@@ -58,145 +16,8 @@
// Multiple distinct extended instruction set types could return this
// value, if they are prefixed with NonSemantic. and are otherwise
-diff --git a/include/spirv-tools/optimizer.hpp b/include/spirv-tools/optimizer.hpp
-index 8579c8c4..321cb038 100644
---- a/include/spirv-tools/optimizer.hpp
-+++ b/include/spirv-tools/optimizer.hpp
-@@ -992,6 +992,132 @@ Optimizer::PassToken CreateFixFuncCallArgumentsPass();
- // the unknown capability interacts with one of the trimmed capabilities.
- Optimizer::PassToken CreateTrimCapabilitiesPass();
-
-+struct vksp_push_constant {
-+ uint32_t offset;
-+ uint32_t size;
-+ uint32_t stageFlags;
-+ const char* pValues;
-+};
-+
-+#define VKSP_DESCRIPTOR_TYPE_STORAGE_BUFFER_COUNTER_BITS (0xf0000000)
-+#define VKSP_DESCRIPTOR_TYPE_STORAGE_BUFFER_COUNTER_MASK \
-+ (~VKSP_DESCRIPTOR_TYPE_STORAGE_BUFFER_COUNTER_BITS)
-+#define VKSP_DESCRIPTOR_TYPE_STORAGE_BUFFER_COUNTER \
-+ (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER | \
-+ VKSP_DESCRIPTOR_TYPE_STORAGE_BUFFER_COUNTER_BITS)
-+struct vksp_descriptor_set {
-+ uint32_t ds;
-+ uint32_t binding;
-+ uint32_t type;
-+ union {
-+ struct {
-+ uint32_t flags;
-+ uint32_t queueFamilyIndexCount;
-+ uint32_t sharingMode;
-+ uint32_t size;
-+ uint32_t usage;
-+ uint32_t range;
-+ uint32_t offset;
-+ uint32_t memorySize;
-+ uint32_t memoryType;
-+ uint32_t bindOffset;
-+ } buffer;
-+ struct {
-+ uint32_t imageLayout;
-+ uint32_t imageFlags;
-+ uint32_t imageType;
-+ uint32_t format;
-+ uint32_t width;
-+ uint32_t height;
-+ uint32_t depth;
-+ uint32_t mipLevels;
-+ uint32_t arrayLayers;
-+ uint32_t samples;
-+ uint32_t tiling;
-+ uint32_t usage;
-+ uint32_t sharingMode;
-+ uint32_t queueFamilyIndexCount;
-+ uint32_t initialLayout;
-+ uint32_t aspectMask;
-+ uint32_t baseMipLevel;
-+ uint32_t levelCount;
-+ uint32_t baseArrayLayer;
-+ uint32_t layerCount;
-+ uint32_t viewFlags;
-+ uint32_t viewType;
-+ uint32_t viewFormat;
-+ uint32_t component_a;
-+ uint32_t component_b;
-+ uint32_t component_g;
-+ uint32_t component_r;
-+ uint32_t memorySize;
-+ uint32_t memoryType;
-+ uint32_t bindOffset;
-+ } image;
-+ struct {
-+ uint32_t flags;
-+ uint32_t magFilter;
-+ uint32_t minFilter;
-+ uint32_t mipmapMode;
-+ uint32_t addressModeU;
-+ uint32_t addressModeV;
-+ uint32_t addressModeW;
-+ union {
-+ float fMipLodBias;
-+ uint32_t uMipLodBias;
-+ };
-+ uint32_t anisotropyEnable;
-+ union {
-+ float fMaxAnisotropy;
-+ uint32_t uMaxAnisotropy;
-+ };
-+ uint32_t compareEnable;
-+ uint32_t compareOp;
-+ union {
-+ float fMinLod;
-+ uint32_t uMinLod;
-+ };
-+ union {
-+ float fMaxLod;
-+ uint32_t uMaxLod;
-+ };
-+ uint32_t borderColor;
-+ uint32_t unnormalizedCoordinates;
-+ } sampler;
-+ };
-+};
-+
-+struct vksp_configuration {
-+ const char* enabledExtensionNames;
-+ uint32_t specializationInfoDataSize;
-+ const char* specializationInfoData;
-+ const char* shaderName;
-+ const char* entryPoint;
-+ uint32_t groupCountX;
-+ uint32_t groupCountY;
-+ uint32_t groupCountZ;
-+};
-+
-+struct vksp_specialization_map_entry {
-+ uint32_t constantID;
-+ uint32_t offset;
-+ uint32_t size;
-+};
-+
-+struct vksp_counter {
-+ uint32_t index;
-+ const char* name;
-+};
-+
-+Optimizer::PassToken CreateInsertVkspReflectInfoPass(
-+ std::vector<vksp_push_constant>* pc, std::vector<vksp_descriptor_set>* ds,
-+ std::vector<vksp_specialization_map_entry>* me, vksp_configuration* config);
-+
-+Optimizer::PassToken CreateExtractVkspReflectInfoPass(
-+ std::vector<vksp_push_constant>* pc, std::vector<vksp_descriptor_set>* ds,
-+ std::vector<vksp_specialization_map_entry>* me,
-+ std::vector<vksp_counter>* counters, vksp_configuration* config);
-+
- } // namespace spvtools
-
- #endif // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
-index 748fbf26..c34addbe 100644
+index f4ee3c84..d0454c6c 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -156,6 +156,7 @@ spvtools_vendor_tables("debuginfo" "debuginfo" "")
@@ -249,26 +70,6 @@
return true;
}
return false;
-diff --git a/source/opt/CMakeLists.txt b/source/opt/CMakeLists.txt
-index 99a74cd7..594157c4 100644
---- a/source/opt/CMakeLists.txt
-+++ b/source/opt/CMakeLists.txt
-@@ -131,6 +131,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
- vector_dce.h
- workaround1209.h
- wrap_opkill.h
-+ vksp_passes.h
-
- fix_func_call_arguments.cpp
- aggressive_dead_code_elim_pass.cpp
-@@ -246,6 +247,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
- vector_dce.cpp
- workaround1209.cpp
- wrap_opkill.cpp
-+ vksp_passes.cpp
- )
-
- if(MSVC AND (NOT ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")))
diff --git a/source/opt/constants.cpp b/source/opt/constants.cpp
index a487a45b..6eebbb57 100644
--- a/source/opt/constants.cpp
@@ -291,930 +92,8 @@
}
uint32_t ConstantManager::GetUIntConstId(uint32_t val) {
-diff --git a/source/opt/optimizer.cpp b/source/opt/optimizer.cpp
-index 6301be6c..d9bfcf4f 100644
---- a/source/opt/optimizer.cpp
-+++ b/source/opt/optimizer.cpp
-@@ -1076,6 +1076,23 @@ Optimizer::PassToken CreateTrimCapabilitiesPass() {
- return MakeUnique<Optimizer::PassToken::Impl>(
- MakeUnique<opt::TrimCapabilitiesPass>());
- }
-+
-+Optimizer::PassToken CreateInsertVkspReflectInfoPass(
-+ std::vector<vksp_push_constant>* pc, std::vector<vksp_descriptor_set>* ds,
-+ std::vector<vksp_specialization_map_entry>* me,
-+ vksp_configuration* config) {
-+ return MakeUnique<Optimizer::PassToken::Impl>(
-+ MakeUnique<opt::InsertVkspReflectInfoPass>(pc, ds, me, config));
-+}
-+Optimizer::PassToken CreateExtractVkspReflectInfoPass(
-+ std::vector<vksp_push_constant>* pc, std::vector<vksp_descriptor_set>* ds,
-+ std::vector<vksp_specialization_map_entry>* me,
-+ std::vector<vksp_counter>* counters, vksp_configuration* config) {
-+ return MakeUnique<Optimizer::PassToken::Impl>(
-+ MakeUnique<opt::ExtractVkspReflectInfoPass>(pc, ds, me, counters,
-+ config));
-+}
-+
- } // namespace spvtools
-
- extern "C" {
-diff --git a/source/opt/passes.h b/source/opt/passes.h
-index f87216dd..b0da2ac4 100644
---- a/source/opt/passes.h
-+++ b/source/opt/passes.h
-@@ -88,5 +88,6 @@
- #include "source/opt/vector_dce.h"
- #include "source/opt/workaround1209.h"
- #include "source/opt/wrap_opkill.h"
-+#include "source/opt/vksp_passes.h"
-
- #endif // SOURCE_OPT_PASSES_H_
-diff --git a/source/opt/vksp_passes.cpp b/source/opt/vksp_passes.cpp
-new file mode 100644
-index 00000000..750185a3
---- /dev/null
-+++ b/source/opt/vksp_passes.cpp
-@@ -0,0 +1,770 @@
-+// Copyright (c) 2023 Google LLC
-+//
-+// Licensed under the Apache License, Version 2.0 (the "License");
-+// you may not use this file except in compliance with the License.
-+// You may obtain a copy of the License at
-+//
-+// http://www.apache.org/licenses/LICENSE-2.0
-+//
-+// Unless required by applicable law or agreed to in writing, software
-+// distributed under the License is distributed on an "AS IS" BASIS,
-+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+// See the License for the specific language governing permissions and
-+// limitations under the License.
-+
-+#include "source/opt/vksp_passes.h"
-+
-+#include "source/opt/instruction.h"
-+#include "source/opt/types.h"
-+#include "spirv-tools/libspirv.h"
-+#include "spirv-tools/optimizer.hpp"
-+#include "spirv/unified1/NonSemanticVkspReflection.h"
-+#include "spirv/unified1/spirv.hpp11"
-+#include "vulkan/vulkan.h"
-+
-+namespace spvtools {
-+namespace opt {
-+
-+Pass::Status InsertVkspReflectInfoPass::Process() {
-+ auto module = context()->module();
-+
-+ std::vector<uint32_t> ext_words =
-+ spvtools::utils::MakeVector("NonSemantic.VkspReflection.1");
-+ auto ExtInstId = context()->TakeNextId();
-+ auto ExtInst =
-+ new Instruction(context(), spv::Op::OpExtInstImport, 0u, ExtInstId,
-+ {{SPV_OPERAND_TYPE_LITERAL_STRING, ext_words}});
-+ module->AddExtInstImport(std::unique_ptr<Instruction>(ExtInst));
-+
-+ uint32_t void_ty_id = context()->get_type_mgr()->GetVoidTypeId();
-+
-+ std::vector<uint32_t> enabledExtensions =
-+ spvtools::utils::MakeVector(config_->enabledExtensionNames);
-+ std::vector<uint32_t> pData =
-+ spvtools::utils::MakeVector(config_->specializationInfoData);
-+ std::vector<uint32_t> shaderName =
-+ spvtools::utils::MakeVector(config_->shaderName);
-+ std::vector<uint32_t> entryPoint =
-+ spvtools::utils::MakeVector(config_->entryPoint);
-+ auto ConfigId = context()->TakeNextId();
-+ auto ConfigInst = new Instruction(
-+ context(), spv::Op::OpExtInst, void_ty_id, ConfigId,
-+ {
-+ {SPV_OPERAND_TYPE_ID, {ExtInstId}},
-+ {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
-+ {NonSemanticVkspReflectionConfiguration}},
-+ {SPV_OPERAND_TYPE_LITERAL_STRING, enabledExtensions},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER,
-+ {config_->specializationInfoDataSize}},
-+ {SPV_OPERAND_TYPE_LITERAL_STRING, pData},
-+ {SPV_OPERAND_TYPE_LITERAL_STRING, shaderName},
-+ {SPV_OPERAND_TYPE_LITERAL_STRING, entryPoint},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {config_->groupCountX}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {config_->groupCountY}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {config_->groupCountZ}},
-+ });
-+ module->AddExtInstDebugInfo(std::unique_ptr<Instruction>(ConfigInst));
-+
-+ for (auto& pc : *pc_) {
-+ std::vector<uint32_t> pValues = spvtools::utils::MakeVector(pc.pValues);
-+ auto PcInstId = context()->TakeNextId();
-+ auto PcInst =
-+ new Instruction(context(), spv::Op::OpExtInst, void_ty_id, PcInstId,
-+ {
-+ {SPV_OPERAND_TYPE_ID, {ExtInstId}},
-+ {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
-+ {NonSemanticVkspReflectionPushConstants}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {pc.offset}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {pc.size}},
-+ {SPV_OPERAND_TYPE_LITERAL_STRING, pValues},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {pc.stageFlags}},
-+ });
-+ module->AddExtInstDebugInfo(std::unique_ptr<Instruction>(PcInst));
-+ }
-+
-+ for (auto& ds : *ds_) {
-+ switch (ds.type) {
-+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
-+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
-+ auto DsInstId = context()->TakeNextId();
-+ auto DstInst = new Instruction(
-+ context(), spv::Op::OpExtInst, void_ty_id, DsInstId,
-+ {
-+ {SPV_OPERAND_TYPE_ID, {ExtInstId}},
-+ {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
-+ {NonSemanticVkspReflectionDescriptorSetsBuffer}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.ds}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.binding}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.type}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.buffer.flags}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER,
-+ {ds.buffer.queueFamilyIndexCount}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.buffer.sharingMode}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.buffer.size}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.buffer.usage}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.buffer.range}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.buffer.offset}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.buffer.memorySize}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.buffer.memoryType}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.buffer.bindOffset}},
-+ });
-+ module->AddExtInstDebugInfo(std::unique_ptr<Instruction>(DstInst));
-+ } break;
-+ case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
-+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
-+ auto DsInstId = context()->TakeNextId();
-+ auto DstInst = new Instruction(
-+ context(), spv::Op::OpExtInst, void_ty_id, DsInstId,
-+ {
-+ {SPV_OPERAND_TYPE_ID, {ExtInstId}},
-+ {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
-+ {NonSemanticVkspReflectionDescriptorSetsImage}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.ds}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.binding}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.type}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.imageLayout}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.imageFlags}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.imageType}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.format}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.width}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.height}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.depth}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.mipLevels}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.arrayLayers}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.samples}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.tiling}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.usage}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.sharingMode}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER,
-+ {ds.image.queueFamilyIndexCount}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.initialLayout}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.aspectMask}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.baseMipLevel}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.levelCount}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.baseArrayLayer}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.layerCount}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.viewFlags}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.viewType}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.viewFormat}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.component_a}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.component_b}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.component_g}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.component_r}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.memorySize}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.memoryType}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.image.bindOffset}},
-+ });
-+ module->AddExtInstDebugInfo(std::unique_ptr<Instruction>(DstInst));
-+ } break;
-+ case VK_DESCRIPTOR_TYPE_SAMPLER: {
-+ auto DsInstId = context()->TakeNextId();
-+ auto DstInst = new Instruction(
-+ context(), spv::Op::OpExtInst, void_ty_id, DsInstId,
-+ {
-+ {SPV_OPERAND_TYPE_ID, {ExtInstId}},
-+ {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
-+ {NonSemanticVkspReflectionDescriptorSetsSampler}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.ds}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.binding}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.type}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.sampler.flags}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.sampler.magFilter}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.sampler.minFilter}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.sampler.mipmapMode}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.sampler.addressModeU}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.sampler.addressModeV}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.sampler.addressModeW}},
-+ {SPV_OPERAND_TYPE_LITERAL_FLOAT, {ds.sampler.uMipLodBias}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER,
-+ {ds.sampler.anisotropyEnable}},
-+ {SPV_OPERAND_TYPE_LITERAL_FLOAT, {ds.sampler.uMaxAnisotropy}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.sampler.compareEnable}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.sampler.compareOp}},
-+ {SPV_OPERAND_TYPE_LITERAL_FLOAT, {ds.sampler.uMinLod}},
-+ {SPV_OPERAND_TYPE_LITERAL_FLOAT, {ds.sampler.uMaxLod}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {ds.sampler.borderColor}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER,
-+ {ds.sampler.unnormalizedCoordinates}},
-+ });
-+ module->AddExtInstDebugInfo(std::unique_ptr<Instruction>(DstInst));
-+ } break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ for (auto& me : *me_) {
-+ auto MapEntryId = context()->TakeNextId();
-+ auto MapEntryInst =
-+ new Instruction(context(), spv::Op::OpExtInst, void_ty_id, MapEntryId,
-+ {
-+ {SPV_OPERAND_TYPE_ID, {ExtInstId}},
-+ {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
-+ {NonSemanticVkspReflectionSpecializationMapEntry}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {me.constantID}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {me.offset}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {me.size}},
-+ });
-+ module->AddExtInstDebugInfo(std::unique_ptr<Instruction>(MapEntryInst));
-+ }
-+
-+ return Status::SuccessWithChange;
-+}
-+
-+int32_t ExtractVkspReflectInfoPass::UpdateMaxBinding(uint32_t ds,
-+ uint32_t binding,
-+ int32_t max_binding) {
-+ if (ds != 0) {
-+ return max_binding;
-+ } else {
-+ return std::max(max_binding, (int32_t)binding);
-+ }
-+}
-+
-+void ExtractVkspReflectInfoPass::ParseInstruction(
-+ Instruction* inst, uint32_t ext_inst_id,
-+ std::map<uint32_t, uint32_t>& id_to_descriptor_set,
-+ std::map<uint32_t, uint32_t>& id_to_binding,
-+ int32_t& descriptor_set_0_max_binding,
-+ std::vector<Instruction*>& start_counters,
-+ std::vector<Instruction*>& stop_counters) {
-+ uint32_t op_id = 2;
-+ if (inst->opcode() == spv::Op::OpDecorate) {
-+ spv::Decoration decoration = (spv::Decoration)inst->GetOperand(1).words[0];
-+ if (decoration == spv::Decoration::DescriptorSet) {
-+ auto id = inst->GetOperand(0).AsId();
-+ auto ds = inst->GetOperand(2).words[0];
-+ id_to_descriptor_set[id] = ds;
-+ if (ds == 0 && id_to_binding.count(id) > 0) {
-+ descriptor_set_0_max_binding = UpdateMaxBinding(
-+ ds, id_to_binding[id], descriptor_set_0_max_binding);
-+ }
-+ } else if (decoration == spv::Decoration::Binding) {
-+ auto id = inst->GetOperand(0).AsId();
-+ auto binding = inst->GetOperand(2).words[0];
-+ id_to_binding[id] = binding;
-+ if (id_to_descriptor_set.count(id) > 0) {
-+ descriptor_set_0_max_binding = UpdateMaxBinding(
-+ id_to_descriptor_set[id], binding, descriptor_set_0_max_binding);
-+ }
-+ }
-+ return;
-+ } else if (inst->opcode() != spv::Op::OpExtInst ||
-+ ext_inst_id != inst->GetOperand(op_id++).AsId()) {
-+ return;
-+ }
-+
-+ auto vksp_inst = inst->GetOperand(op_id++).words[0];
-+ switch (vksp_inst) {
-+ case NonSemanticVkspReflectionConfiguration:
-+ config_->enabledExtensionNames =
-+ strdup(inst->GetOperand(op_id++).AsString().c_str());
-+ config_->specializationInfoDataSize = inst->GetOperand(op_id++).words[0];
-+ config_->specializationInfoData =
-+ strdup(inst->GetOperand(op_id++).AsString().c_str());
-+ config_->shaderName =
-+ strdup(inst->GetOperand(op_id++).AsString().c_str());
-+ config_->entryPoint =
-+ strdup(inst->GetOperand(op_id++).AsString().c_str());
-+ config_->groupCountX = inst->GetOperand(op_id++).words[0];
-+ config_->groupCountY = inst->GetOperand(op_id++).words[0];
-+ config_->groupCountZ = inst->GetOperand(op_id++).words[0];
-+ break;
-+ case NonSemanticVkspReflectionDescriptorSetsBuffer: {
-+ vksp_descriptor_set ds;
-+ ds.ds = inst->GetOperand(op_id++).words[0];
-+ ds.binding = inst->GetOperand(op_id++).words[0];
-+ ds.type = inst->GetOperand(op_id++).words[0];
-+ ds.buffer.flags = inst->GetOperand(op_id++).words[0];
-+ ds.buffer.queueFamilyIndexCount = inst->GetOperand(op_id++).words[0];
-+ ds.buffer.sharingMode = inst->GetOperand(op_id++).words[0];
-+ ds.buffer.size = inst->GetOperand(op_id++).words[0];
-+ ds.buffer.usage = inst->GetOperand(op_id++).words[0];
-+ ds.buffer.range = inst->GetOperand(op_id++).words[0];
-+ ds.buffer.offset = inst->GetOperand(op_id++).words[0];
-+ ds.buffer.memorySize = inst->GetOperand(op_id++).words[0];
-+ ds.buffer.memoryType = inst->GetOperand(op_id++).words[0];
-+ ds.buffer.bindOffset = inst->GetOperand(op_id++).words[0];
-+ ds_->push_back(ds);
-+ descriptor_set_0_max_binding =
-+ UpdateMaxBinding(ds.ds, ds.binding, descriptor_set_0_max_binding);
-+ } break;
-+ case NonSemanticVkspReflectionDescriptorSetsImage: {
-+ vksp_descriptor_set ds;
-+ ds.ds = inst->GetOperand(op_id++).words[0];
-+ ds.binding = inst->GetOperand(op_id++).words[0];
-+ ds.type = inst->GetOperand(op_id++).words[0];
-+ ds.image.imageLayout = inst->GetOperand(op_id++).words[0];
-+ ds.image.imageFlags = inst->GetOperand(op_id++).words[0];
-+ ds.image.imageType = inst->GetOperand(op_id++).words[0];
-+ ds.image.format = inst->GetOperand(op_id++).words[0];
-+ ds.image.width = inst->GetOperand(op_id++).words[0];
-+ ds.image.height = inst->GetOperand(op_id++).words[0];
-+ ds.image.depth = inst->GetOperand(op_id++).words[0];
-+ ds.image.mipLevels = inst->GetOperand(op_id++).words[0];
-+ ds.image.arrayLayers = inst->GetOperand(op_id++).words[0];
-+ ds.image.samples = inst->GetOperand(op_id++).words[0];
-+ ds.image.tiling = inst->GetOperand(op_id++).words[0];
-+ ds.image.usage = inst->GetOperand(op_id++).words[0];
-+ ds.image.sharingMode = inst->GetOperand(op_id++).words[0];
-+ ds.image.queueFamilyIndexCount = inst->GetOperand(op_id++).words[0];
-+ ds.image.initialLayout = inst->GetOperand(op_id++).words[0];
-+ ds.image.aspectMask = inst->GetOperand(op_id++).words[0];
-+ ds.image.baseMipLevel = inst->GetOperand(op_id++).words[0];
-+ ds.image.levelCount = inst->GetOperand(op_id++).words[0];
-+ ds.image.baseArrayLayer = inst->GetOperand(op_id++).words[0];
-+ ds.image.layerCount = inst->GetOperand(op_id++).words[0];
-+ ds.image.viewFlags = inst->GetOperand(op_id++).words[0];
-+ ds.image.viewType = inst->GetOperand(op_id++).words[0];
-+ ds.image.viewFormat = inst->GetOperand(op_id++).words[0];
-+ ds.image.component_a = inst->GetOperand(op_id++).words[0];
-+ ds.image.component_b = inst->GetOperand(op_id++).words[0];
-+ ds.image.component_g = inst->GetOperand(op_id++).words[0];
-+ ds.image.component_r = inst->GetOperand(op_id++).words[0];
-+ ds.image.memorySize = inst->GetOperand(op_id++).words[0];
-+ ds.image.memoryType = inst->GetOperand(op_id++).words[0];
-+ ds.image.bindOffset = inst->GetOperand(op_id++).words[0];
-+ ds_->push_back(ds);
-+ descriptor_set_0_max_binding =
-+ UpdateMaxBinding(ds.ds, ds.binding, descriptor_set_0_max_binding);
-+ } break;
-+ case NonSemanticVkspReflectionDescriptorSetsSampler: {
-+ vksp_descriptor_set ds;
-+ ds.ds = inst->GetOperand(op_id++).words[0];
-+ ds.binding = inst->GetOperand(op_id++).words[0];
-+ ds.type = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.flags = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.magFilter = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.minFilter = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.mipmapMode = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.addressModeU = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.addressModeV = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.addressModeW = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.uMipLodBias = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.anisotropyEnable = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.uMaxAnisotropy = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.compareEnable = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.compareOp = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.uMinLod = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.uMaxLod = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.borderColor = inst->GetOperand(op_id++).words[0];
-+ ds.sampler.unnormalizedCoordinates = inst->GetOperand(op_id++).words[0];
-+ ds_->push_back(ds);
-+ descriptor_set_0_max_binding =
-+ UpdateMaxBinding(ds.ds, ds.binding, descriptor_set_0_max_binding);
-+ } break;
-+ case NonSemanticVkspReflectionPushConstants:
-+ vksp_push_constant pc;
-+ pc.offset = inst->GetOperand(op_id++).words[0];
-+ pc.size = inst->GetOperand(op_id++).words[0];
-+ pc.pValues = strdup(inst->GetOperand(op_id++).AsString().c_str());
-+ pc.stageFlags = inst->GetOperand(op_id++).words[0];
-+ pc_->push_back(pc);
-+ break;
-+ case NonSemanticVkspReflectionSpecializationMapEntry:
-+ vksp_specialization_map_entry me;
-+ me.constantID = inst->GetOperand(op_id++).words[0];
-+ me.offset = inst->GetOperand(op_id++).words[0];
-+ me.size = inst->GetOperand(op_id++).words[0];
-+ me_->push_back(me);
-+ break;
-+ case NonSemanticVkspReflectionStartCounter:
-+ start_counters.push_back(inst);
-+ break;
-+ case NonSemanticVkspReflectionStopCounter:
-+ stop_counters.push_back(inst);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+void ExtractVkspReflectInfoPass::CreateVariables(
-+ uint32_t u64_arr_ty_id, uint32_t u64_arr_st_ty_id,
-+ uint32_t local_counters_ty_id, uint32_t counters_ty_id,
-+ uint32_t global_counters_ds, uint32_t global_counters_binding,
-+ uint32_t& global_counters_id, uint32_t& local_counters_id) {
-+ auto module = context()->module();
-+
-+ auto decorate_arr_inst = new Instruction(
-+ context(), spv::Op::OpDecorate, 0, 0,
-+ {{SPV_OPERAND_TYPE_ID, {u64_arr_ty_id}},
-+ {SPV_OPERAND_TYPE_DECORATION, {(uint32_t)spv::Decoration::ArrayStride}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {8}}});
-+ module->AddAnnotationInst(std::unique_ptr<Instruction>(decorate_arr_inst));
-+
-+ auto decorate_member_offset_inst = new Instruction(
-+ context(), spv::Op::OpMemberDecorate, 0, 0,
-+ {{SPV_OPERAND_TYPE_ID, {u64_arr_st_ty_id}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0}},
-+ {SPV_OPERAND_TYPE_DECORATION, {(uint32_t)spv::Decoration::Offset}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0}}});
-+ module->AddAnnotationInst(
-+ std::unique_ptr<Instruction>(decorate_member_offset_inst));
-+
-+ auto decorate_arr_st_inst = new Instruction(
-+ context(), spv::Op::OpDecorate, 0, 0,
-+ {{SPV_OPERAND_TYPE_ID, {u64_arr_st_ty_id}},
-+ {SPV_OPERAND_TYPE_DECORATION, {(uint32_t)spv::Decoration::Block}}});
-+ module->AddAnnotationInst(std::unique_ptr<Instruction>(decorate_arr_st_inst));
-+
-+ local_counters_id = context()->TakeNextId();
-+ auto local_counters_inst = new Instruction(
-+ context(), spv::Op::OpVariable, local_counters_ty_id, local_counters_id,
-+ {{SPV_OPERAND_TYPE_LITERAL_INTEGER,
-+ {(uint32_t)spv::StorageClass::Private}}});
-+ module->AddGlobalValue(std::unique_ptr<Instruction>(local_counters_inst));
-+
-+ global_counters_id = context()->TakeNextId();
-+ auto global_counters_inst = new Instruction(
-+ context(), spv::Op::OpVariable, counters_ty_id, global_counters_id,
-+ {{SPV_OPERAND_TYPE_LITERAL_INTEGER,
-+ {(uint32_t)spv::StorageClass::StorageBuffer}}});
-+ module->AddGlobalValue(std::unique_ptr<Instruction>(global_counters_inst));
-+
-+ auto counters_descriptor_set_inst = new Instruction(
-+ context(), spv::Op::OpDecorate, 0, 0,
-+ {{SPV_OPERAND_TYPE_ID, {global_counters_inst->result_id()}},
-+ {SPV_OPERAND_TYPE_DECORATION,
-+ {(uint32_t)spv::Decoration::DescriptorSet}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {global_counters_ds}}});
-+ module->AddAnnotationInst(
-+ std::unique_ptr<Instruction>(counters_descriptor_set_inst));
-+
-+ auto counters_binding_inst = new Instruction(
-+ context(), spv::Op::OpDecorate, 0, 0,
-+ {{SPV_OPERAND_TYPE_ID, {global_counters_inst->result_id()}},
-+ {SPV_OPERAND_TYPE_DECORATION, {(uint32_t)spv::Decoration::Binding}},
-+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {global_counters_binding}}});
-+ module->AddAnnotationInst(
-+ std::unique_ptr<Instruction>(counters_binding_inst));
-+}
-+
-+void ExtractVkspReflectInfoPass::CreatePrologue(
-+ Instruction* entry_point_inst, uint32_t u64_private_ptr_ty_id,
-+ uint32_t u64_ty_id, uint32_t subgroup_scope_id, uint32_t global_counters_id,
-+ uint32_t local_counters_id, std::vector<Instruction*>& start_counters,
-+ Function*& function, uint32_t& read_clock_id) {
-+ auto* cst_mgr = context()->get_constant_mgr();
-+ entry_point_inst->AddOperand({SPV_OPERAND_TYPE_ID, {global_counters_id}});
-+ entry_point_inst->AddOperand({SPV_OPERAND_TYPE_ID, {local_counters_id}});
-+
-+ auto function_id = entry_point_inst->GetOperand(1).AsId();
-+ function = context()->GetFunction(function_id);
-+
-+ auto& function_first_inst = *function->entry()->begin();
-+
-+ auto u64_cst0_id =
-+ cst_mgr->GetDefiningInstruction(cst_mgr->GetIntConst(0, 64, 0))
-+ ->result_id();
-+
-+ for (unsigned i = 0; i < start_counters.size(); i++) {
-+ auto get_id = context()->TakeNextId();
-+ auto gep_inst = new Instruction(
-+ context(), spv::Op::OpAccessChain, u64_private_ptr_ty_id, get_id,
-+ {{SPV_OPERAND_TYPE_ID, {local_counters_id}},
-+ {SPV_OPERAND_TYPE_ID, {cst_mgr->GetUIntConstId(i)}}});
-+ gep_inst->InsertBefore(&function_first_inst);
-+
-+ auto store_inst = new Instruction(context(), spv::Op::OpStore, 0, 0,
-+ {{SPV_OPERAND_TYPE_ID, {get_id}},
-+ {SPV_OPERAND_TYPE_ID, {u64_cst0_id}}});
-+ store_inst->InsertAfter(gep_inst);
-+ }
-+
-+ read_clock_id = context()->TakeNextId();
-+ auto read_clock_inst = new Instruction(
-+ context(), spv::Op::OpReadClockKHR, u64_ty_id, read_clock_id,
-+ {{SPV_OPERAND_TYPE_SCOPE_ID, {subgroup_scope_id}}});
-+ read_clock_inst->InsertBefore(&function_first_inst);
-+}
-+
-+void ExtractVkspReflectInfoPass::CreateEpilogue(
-+ Instruction* return_inst, uint32_t read_clock_id, uint32_t u64_ty_id,
-+ uint32_t u64_ptr_ty_id, uint32_t u64_private_ptr_ty_id,
-+ uint32_t subgroup_scope_id, uint32_t device_scope_id,
-+ uint32_t acq_rel_mem_sem_id, uint32_t global_counters_id,
-+ uint32_t local_counters_id, std::vector<Instruction*>& start_counters) {
-+ auto* cst_mgr = context()->get_constant_mgr();
-+
-+ auto read_clock_end_id = context()->TakeNextId();
-+ auto read_clock_end_inst = new Instruction(
-+ context(), spv::Op::OpReadClockKHR, u64_ty_id, read_clock_end_id,
-+ {{SPV_OPERAND_TYPE_SCOPE_ID, {subgroup_scope_id}}});
-+ read_clock_end_inst->InsertBefore(return_inst);
-+
-+ auto substraction_id = context()->TakeNextId();
-+ auto substraction_inst =
-+ new Instruction(context(), spv::Op::OpISub, u64_ty_id, substraction_id,
-+ {{SPV_OPERAND_TYPE_ID, {read_clock_end_id}},
-+ {SPV_OPERAND_TYPE_ID, {read_clock_id}}});
-+ substraction_inst->InsertAfter(read_clock_end_inst);
-+
-+ auto gep_invocations_id = context()->TakeNextId();
-+ auto gep_invocations_inst = new Instruction(
-+ context(), spv::Op::OpAccessChain, u64_ptr_ty_id, gep_invocations_id,
-+ {{SPV_OPERAND_TYPE_ID, {global_counters_id}},
-+ {SPV_OPERAND_TYPE_ID, {cst_mgr->GetUIntConstId(0)}},
-+ {SPV_OPERAND_TYPE_ID, {cst_mgr->GetUIntConstId(0)}}});
-+ gep_invocations_inst->InsertAfter(substraction_inst);
-+
-+ auto atomic_incr_id = context()->TakeNextId();
-+ auto atomic_incr_inst = new Instruction(
-+ context(), spv::Op::OpAtomicIIncrement, u64_ty_id, atomic_incr_id,
-+ {{SPV_OPERAND_TYPE_ID, {gep_invocations_id}},
-+ {SPV_OPERAND_TYPE_SCOPE_ID, {device_scope_id}},
-+ {SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, {acq_rel_mem_sem_id}}});
-+ atomic_incr_inst->InsertAfter(gep_invocations_inst);
-+
-+ auto gep_entrypoint_counter_id = context()->TakeNextId();
-+ auto gep_entrypoint_counter_inst =
-+ new Instruction(context(), spv::Op::OpAccessChain, u64_ptr_ty_id,
-+ gep_entrypoint_counter_id,
-+ {{SPV_OPERAND_TYPE_ID, {global_counters_id}},
-+ {SPV_OPERAND_TYPE_ID, {cst_mgr->GetUIntConstId(0)}},
-+ {SPV_OPERAND_TYPE_ID, {cst_mgr->GetUIntConstId(1)}}});
-+ gep_entrypoint_counter_inst->InsertAfter(atomic_incr_inst);
-+
-+ auto atomic_add_id = context()->TakeNextId();
-+ auto atomic_add_inst = new Instruction(
-+ context(), spv::Op::OpAtomicIAdd, u64_ty_id, atomic_add_id,
-+ {{SPV_OPERAND_TYPE_ID, {gep_entrypoint_counter_id}},
-+ {SPV_OPERAND_TYPE_SCOPE_ID, {device_scope_id}},
-+ {SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, {acq_rel_mem_sem_id}},
-+ {SPV_OPERAND_TYPE_ID, {substraction_id}}});
-+ atomic_add_inst->InsertAfter(gep_entrypoint_counter_inst);
-+
-+ for (unsigned i = 0; i < start_counters.size(); i++) {
-+ auto gep_id = context()->TakeNextId();
-+ auto gep_inst = new Instruction(
-+ context(), spv::Op::OpAccessChain, u64_private_ptr_ty_id, gep_id,
-+ {{SPV_OPERAND_TYPE_ID, {local_counters_id}},
-+ {SPV_OPERAND_TYPE_ID, {cst_mgr->GetUIntConstId(i)}}});
-+ gep_inst->InsertAfter(atomic_add_inst);
-+
-+ auto load_id = context()->TakeNextId();
-+ auto load_inst =
-+ new Instruction(context(), spv::Op::OpLoad, u64_ty_id, load_id,
-+ {{SPV_OPERAND_TYPE_ID, {gep_id}}});
-+ load_inst->InsertAfter(gep_inst);
-+
-+ auto gep_atomic_id = context()->TakeNextId();
-+ auto gep_atomic_inst = new Instruction(
-+ context(), spv::Op::OpAccessChain, u64_ptr_ty_id, gep_atomic_id,
-+ {{SPV_OPERAND_TYPE_ID, {global_counters_id}},
-+ {SPV_OPERAND_TYPE_ID, {cst_mgr->GetUIntConstId(0)}},
-+ {SPV_OPERAND_TYPE_ID, {cst_mgr->GetUIntConstId(2 + i)}}});
-+ gep_atomic_inst->InsertAfter(load_inst);
-+
-+ atomic_add_id = context()->TakeNextId();
-+ atomic_add_inst = new Instruction(
-+ context(), spv::Op::OpAtomicIAdd, u64_ty_id, atomic_add_id,
-+ {{SPV_OPERAND_TYPE_ID, {gep_atomic_id}},
-+ {SPV_OPERAND_TYPE_SCOPE_ID, {device_scope_id}},
-+ {SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, {acq_rel_mem_sem_id}},
-+ {SPV_OPERAND_TYPE_ID, {load_id}}});
-+ atomic_add_inst->InsertAfter(gep_atomic_inst);
-+ }
-+}
-+
-+void ExtractVkspReflectInfoPass::CreateCounters(
-+ uint32_t u64_ty_id, uint32_t u64_private_ptr_ty_id,
-+ uint32_t subgroup_scope_id, std::vector<Instruction*>& start_counters,
-+ std::vector<Instruction*>& stop_counters, uint32_t local_counters_id) {
-+ auto* cst_mgr = context()->get_constant_mgr();
-+ std::map<uint32_t, std::pair<uint32_t, uint32_t>> start_counters_id_map;
-+ uint32_t next_counter_id = 2;
-+
-+ for (auto* inst : start_counters) {
-+ const char* counter_name = strdup(inst->GetOperand(4).AsString().c_str());
-+
-+ auto read_clock_id = context()->TakeNextId();
-+ auto read_clock_inst = new Instruction(
-+ context(), spv::Op::OpReadClockKHR, u64_ty_id, read_clock_id,
-+ {{SPV_OPERAND_TYPE_SCOPE_ID, {subgroup_scope_id}}});
-+ read_clock_inst->InsertBefore(inst);
-+
-+ counters_->push_back({next_counter_id, counter_name});
-+ start_counters_id_map[inst->result_id()] =
-+ std::make_pair(read_clock_id, next_counter_id);
-+ next_counter_id++;
-+ }
-+
-+ for (auto* inst : stop_counters) {
-+ auto read_clock_ext_inst_id = inst->GetOperand(4).AsId();
-+ if (start_counters_id_map.count(read_clock_ext_inst_id) == 0) {
-+ continue;
-+ }
-+ auto pair = start_counters_id_map[read_clock_ext_inst_id];
-+ auto read_clock_id = pair.first;
-+ auto counters_var_index = pair.second;
-+
-+ auto read_clock_end_id = context()->TakeNextId();
-+ auto read_clock_end_inst = new Instruction(
-+ context(), spv::Op::OpReadClockKHR, u64_ty_id, read_clock_end_id,
-+ {{SPV_OPERAND_TYPE_SCOPE_ID, {subgroup_scope_id}}});
-+ read_clock_end_inst->InsertAfter(inst);
-+
-+ auto substraction_id = context()->TakeNextId();
-+ auto substraction_inst =
-+ new Instruction(context(), spv::Op::OpISub, u64_ty_id, substraction_id,
-+ {{SPV_OPERAND_TYPE_ID, {read_clock_end_id}},
-+ {SPV_OPERAND_TYPE_ID, {read_clock_id}}});
-+ substraction_inst->InsertAfter(read_clock_end_inst);
-+
-+ auto gep_id = context()->TakeNextId();
-+ auto gep_inst = new Instruction(
-+ context(), spv::Op::OpAccessChain, u64_private_ptr_ty_id, gep_id,
-+ {{SPV_OPERAND_TYPE_ID, {local_counters_id}},
-+ {SPV_OPERAND_TYPE_ID,
-+ {cst_mgr->GetUIntConstId(counters_var_index - 2)}}});
-+ gep_inst->InsertAfter(substraction_inst);
-+
-+ auto load_id = context()->TakeNextId();
-+ auto load_inst =
-+ new Instruction(context(), spv::Op::OpLoad, u64_ty_id, load_id,
-+ {{SPV_OPERAND_TYPE_ID, {gep_id}}});
-+ load_inst->InsertAfter(gep_inst);
-+
-+ auto add_id = context()->TakeNextId();
-+ auto add_inst =
-+ new Instruction(context(), spv::Op::OpIAdd, u64_ty_id, add_id,
-+ {{SPV_OPERAND_TYPE_ID, {load_id}},
-+ {SPV_OPERAND_TYPE_ID, {substraction_id}}});
-+ add_inst->InsertAfter(load_inst);
-+
-+ auto store_inst = new Instruction(
-+ context(), spv::Op::OpStore, 0, 0,
-+ {{SPV_OPERAND_TYPE_ID, {gep_id}}, {SPV_OPERAND_TYPE_ID, {add_id}}});
-+ store_inst->InsertAfter(add_inst);
-+ }
-+}
-+
-+Pass::Status ExtractVkspReflectInfoPass::Process() {
-+ auto module = context()->module();
-+ uint32_t ext_inst_id =
-+ module->GetExtInstImportId("NonSemantic.VkspReflection.1");
-+ int32_t descriptor_set_0_max_binding = -1;
-+ std::map<uint32_t, uint32_t> id_to_descriptor_set;
-+ std::map<uint32_t, uint32_t> id_to_binding;
-+ std::vector<Instruction*> start_counters;
-+ std::vector<Instruction*> stop_counters;
-+
-+ module->ForEachInst([this, ext_inst_id, &id_to_descriptor_set, &id_to_binding,
-+ &descriptor_set_0_max_binding, &start_counters,
-+ &stop_counters](Instruction* inst) {
-+ ParseInstruction(inst, ext_inst_id, id_to_descriptor_set, id_to_binding,
-+ descriptor_set_0_max_binding, start_counters,
-+ stop_counters);
-+ });
-+
-+ context()->AddExtension("SPV_KHR_shader_clock");
-+ context()->AddExtension("SPV_KHR_storage_buffer_storage_class");
-+ context()->AddCapability(spv::Capability::ShaderClockKHR);
-+ context()->AddCapability(spv::Capability::Int64);
-+ context()->AddCapability(spv::Capability::Int64Atomics);
-+
-+ uint32_t global_counters_ds = 0;
-+ uint32_t global_counters_binding = descriptor_set_0_max_binding + 1;
-+ auto counters_size =
-+ (uint32_t)(sizeof(uint64_t) *
-+ (2 + start_counters
-+ .size())); // 2 for the number of invocations and the
-+ // time of the whole entry point
-+ ds_->push_back(
-+ {global_counters_ds,
-+ global_counters_binding,
-+ (uint32_t)VKSP_DESCRIPTOR_TYPE_STORAGE_BUFFER_COUNTER,
-+ {.buffer = {0, 0, VK_SHARING_MODE_EXCLUSIVE, counters_size,
-+ VK_BUFFER_USAGE_TRANSFER_DST_BIT |
-+ VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
-+ counters_size, 0, counters_size, UINT32_MAX, 0}}});
-+
-+ auto* cst_mgr = context()->get_constant_mgr();
-+ auto* type_mgr = context()->get_type_mgr();
-+
-+ auto u64_ty = type_mgr->GetIntType(64, 0);
-+ analysis::RuntimeArray run_arr(u64_ty);
-+ auto u64_run_arr_ty = type_mgr->GetRegisteredType(&run_arr);
-+ analysis::Struct st({u64_run_arr_ty});
-+ auto u64_run_arr_st_ty = type_mgr->GetRegisteredType(&st);
-+ analysis::Pointer u64_run_arr_st_ty_ptr(u64_run_arr_st_ty,
-+ spv::StorageClass::StorageBuffer);
-+ auto u64_run_arr_st_ptr_ty =
-+ type_mgr->GetRegisteredType(&u64_run_arr_st_ty_ptr);
-+
-+ analysis::Pointer u64_ty_ptr(u64_ty, spv::StorageClass::StorageBuffer);
-+ auto u64_ptr_ty = type_mgr->GetRegisteredType(&u64_ty_ptr);
-+
-+ analysis::Array arr(
-+ u64_ty, analysis::Array::LengthInfo{
-+ cst_mgr->GetUIntConstId((uint32_t)start_counters.size()),
-+ {0, (uint32_t)start_counters.size()}});
-+ auto u64_arr_ty = type_mgr->GetRegisteredType(&arr);
-+ analysis::Pointer u64_arr_ty_ptr(u64_arr_ty, spv::StorageClass::Private);
-+ auto u64_arr_ptr_ty = type_mgr->GetRegisteredType(&u64_arr_ty_ptr);
-+ analysis::Pointer u64_ty_ptr_private(u64_ty, spv::StorageClass::Private);
-+ auto u64_private_ptr_ty = type_mgr->GetRegisteredType(&u64_ty_ptr_private);
-+
-+ auto local_counters_ty_id = type_mgr->GetId(u64_arr_ptr_ty);
-+ auto counters_ty_id = type_mgr->GetId(u64_run_arr_st_ptr_ty);
-+ auto u64_ty_id = type_mgr->GetId(u64_ty);
-+ auto u64_ptr_ty_id = type_mgr->GetId(u64_ptr_ty);
-+ auto u64_arr_ty_id = type_mgr->GetId(u64_run_arr_ty);
-+ auto u64_arr_st_ty_id = type_mgr->GetId(u64_run_arr_st_ty);
-+ auto u64_private_ptr_ty_id = type_mgr->GetId(u64_private_ptr_ty);
-+
-+ auto subgroup_scope_id =
-+ cst_mgr->GetUIntConstId((uint32_t)spv::Scope::Subgroup);
-+ auto device_scope_id = cst_mgr->GetUIntConstId((uint32_t)spv::Scope::Device);
-+ auto acq_rel_mem_sem_id = cst_mgr->GetUIntConstId(
-+ (uint32_t)spv::MemorySemanticsMask::AcquireRelease);
-+
-+ uint32_t global_counters_id;
-+ uint32_t local_counters_id;
-+ CreateVariables(u64_arr_ty_id, u64_arr_st_ty_id, local_counters_ty_id,
-+ counters_ty_id, global_counters_ds, global_counters_binding,
-+ global_counters_id, local_counters_id);
-+
-+ bool found = false;
-+ for (auto& entry_point_inst : module->entry_points()) {
-+ auto function_name = entry_point_inst.GetOperand(2).AsString();
-+ if (function_name != std::string(config_->entryPoint)) {
-+ continue;
-+ }
-+ found = true;
-+
-+ uint32_t read_clock_id;
-+ Function* function;
-+ CreatePrologue(&entry_point_inst, u64_private_ptr_ty_id, u64_ty_id,
-+ subgroup_scope_id, global_counters_id, local_counters_id,
-+ start_counters, function, read_clock_id);
-+
-+ function->ForEachInst([this, read_clock_id, u64_ty_id, u64_ptr_ty_id,
-+ u64_private_ptr_ty_id, subgroup_scope_id,
-+ device_scope_id, acq_rel_mem_sem_id,
-+ global_counters_id, local_counters_id,
-+ &start_counters](Instruction* inst) {
-+ if (inst->opcode() != spv::Op::OpReturn) {
-+ return;
-+ }
-+ CreateEpilogue(inst, read_clock_id, u64_ty_id, u64_ptr_ty_id,
-+ u64_private_ptr_ty_id, subgroup_scope_id, device_scope_id,
-+ acq_rel_mem_sem_id, global_counters_id, local_counters_id,
-+ start_counters);
-+ });
-+
-+ break;
-+ }
-+ if (!found) {
-+ return Status::Failure;
-+ }
-+
-+ CreateCounters(u64_ty_id, u64_private_ptr_ty_id, subgroup_scope_id,
-+ start_counters, stop_counters, local_counters_id);
-+
-+ return Status::SuccessWithChange;
-+}
-+
-+} // namespace opt
-+} // namespace spvtools
-diff --git a/source/opt/vksp_passes.h b/source/opt/vksp_passes.h
-new file mode 100644
-index 00000000..cd9fdfd3
---- /dev/null
-+++ b/source/opt/vksp_passes.h
-@@ -0,0 +1,101 @@
-+// Copyright (c) 2023 Google LLC
-+//
-+// Licensed under the Apache License, Version 2.0 (the "License");
-+// you may not use this file except in compliance with the License.
-+// You may obtain a copy of the License at
-+//
-+// http://www.apache.org/licenses/LICENSE-2.0
-+//
-+// Unless required by applicable law or agreed to in writing, software
-+// distributed under the License is distributed on an "AS IS" BASIS,
-+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+// See the License for the specific language governing permissions and
-+// limitations under the License.
-+
-+#ifndef SOURCE_OPT_VKSP_PASSES_H_
-+#define SOURCE_OPT_VKSP_PASSES_H_
-+
-+#include "source/opt/module.h"
-+#include "source/opt/pass.h"
-+#include "spirv-tools/optimizer.hpp"
-+
-+namespace spvtools {
-+namespace opt {
-+
-+class InsertVkspReflectInfoPass : public Pass {
-+ public:
-+ InsertVkspReflectInfoPass(std::vector<vksp_push_constant>* pc,
-+ std::vector<vksp_descriptor_set>* ds,
-+ std::vector<vksp_specialization_map_entry>* me,
-+ vksp_configuration* config)
-+ : pc_(pc), ds_(ds), me_(me), config_(config) {}
-+ const char* name() const override { return "insert-vksp-reflect-info"; }
-+ Status Process() override;
-+
-+ private:
-+ std::vector<vksp_push_constant>* pc_;
-+ std::vector<vksp_descriptor_set>* ds_;
-+ std::vector<vksp_specialization_map_entry>* me_;
-+ vksp_configuration* config_;
-+};
-+
-+class ExtractVkspReflectInfoPass : public Pass {
-+ public:
-+ ExtractVkspReflectInfoPass(std::vector<vksp_push_constant>* pc,
-+ std::vector<vksp_descriptor_set>* ds,
-+ std::vector<vksp_specialization_map_entry>* me,
-+ std::vector<vksp_counter>* counters,
-+ vksp_configuration* config)
-+ : pc_(pc), ds_(ds), me_(me), counters_(counters), config_(config) {}
-+ const char* name() const override { return "extract-vksp-reflect-info"; }
-+ Status Process() override;
-+
-+ private:
-+ int32_t UpdateMaxBinding(uint32_t ds, uint32_t binding, int32_t max_binding);
-+
-+ void ParseInstruction(Instruction* inst, uint32_t ext_inst_id,
-+ std::map<uint32_t, uint32_t>& id_to_descriptor_set,
-+ std::map<uint32_t, uint32_t>& id_to_binding,
-+ int32_t& descriptor_set_0_max_binding,
-+ std::vector<Instruction*>& start_counters,
-+ std::vector<Instruction*>& stop_counters);
-+
-+ void CreateVariables(uint32_t u64_arr_ty_id, uint32_t u64_arr_st_ty_id,
-+ uint32_t local_counters_ty_id, uint32_t counters_ty_id,
-+ uint32_t global_counters_ds,
-+ uint32_t global_counters_binding,
-+ uint32_t& global_counters_id,
-+ uint32_t& local_counters_id);
-+
-+ void CreatePrologue(Instruction* entry_point_inst,
-+ uint32_t u64_private_ptr_ty_id, uint32_t u64_ty_id,
-+ uint32_t subgroup_scope_id, uint32_t global_counters_id,
-+ uint32_t local_counters_id,
-+ std::vector<Instruction*>& start_counters,
-+ Function*& function, uint32_t& read_clock_id);
-+
-+ void CreateEpilogue(Instruction* inst, uint32_t read_clock_id,
-+ uint32_t u64_ty_id, uint32_t u64_ptr_ty_id,
-+ uint32_t u64_private_ptr_ty_id,
-+ uint32_t subgroup_scope_id, uint32_t device_scope_id,
-+ uint32_t acq_rel_mem_sem_id, uint32_t global_counters_id,
-+ uint32_t local_counters_id,
-+ std::vector<Instruction*>& start_counters);
-+
-+ void CreateCounters(uint32_t u64_ty_id, uint32_t u64_private_ptr_ty_id,
-+ uint32_t subgroup_scope_id,
-+ std::vector<Instruction*>& start_counters,
-+ std::vector<Instruction*>& stop_counters,
-+ uint32_t local_counters_id);
-+
-+ std::vector<vksp_push_constant>* pc_;
-+ std::vector<vksp_descriptor_set>* ds_;
-+ std::vector<vksp_specialization_map_entry>* me_;
-+ std::vector<vksp_counter>* counters_;
-+ vksp_configuration* config_;
-+};
-+
-+} // namespace opt
-+} // namespace spvtools
-+
-+#endif // SOURCE_OPT_VKSP_REFLECT_INFO_PASS_H_
diff --git a/source/table.h b/source/table.h
-index 8097f13f..f1e971bf 100644
+index 8097f13f..4f1dc1f8 100644
--- a/source/table.h
+++ b/source/table.h
@@ -74,7 +74,7 @@ typedef struct spv_ext_inst_desc_t {
@@ -1222,7 +101,7 @@
const uint32_t numCapabilities;
const spv::Capability* capabilities;
- const spv_operand_type_t operandTypes[16]; // TODO: Smaller/larger?
-+ const spv_operand_type_t operandTypes[64]; // TODO: Smaller/larger?
++ const spv_operand_type_t operandTypes[40]; // vksp needs at least 40
} spv_ext_inst_desc_t;
typedef struct spv_ext_inst_group_t {
diff --git a/dev-util/spirv-tools/spirv-tools-1.3.261-r1.ebuild b/dev-util/spirv-tools/spirv-tools-1.3.261-r2.ebuild
similarity index 100%
rename from dev-util/spirv-tools/spirv-tools-1.3.261-r1.ebuild
rename to dev-util/spirv-tools/spirv-tools-1.3.261-r2.ebuild
diff --git a/dev-util/spirv-tools/spirv-tools-1.3.261.ebuild b/dev-util/spirv-tools/spirv-tools-1.3.261.ebuild
index f4e5dc9..b814c30 100644
--- a/dev-util/spirv-tools/spirv-tools-1.3.261.ebuild
+++ b/dev-util/spirv-tools/spirv-tools-1.3.261.ebuild
@@ -46,3 +46,15 @@
append-lfs-flags
cmake_src_configure
}
+
+multilib_src_install() {
+ # Install files needed by vksp
+ local DIR="/usr/include/spirv-tools/vksp"
+ dodir "${DIR}"
+ insinto "${DIR}"
+ doins "${BUILD_DIR}/extension_enum.inc"
+ doins "${BUILD_DIR}/NonSemanticShaderDebugInfo100.h"
+ doins "${BUILD_DIR}/OpenCLDebugInfo100.h"
+
+ cmake_src_install
+}