48 if (spv_bytes.size() < 5U *
sizeof(uint32_t) || (spv_bytes.size() %
sizeof(uint32_t)) != 0U) {
52 const auto *word_data =
reinterpret_cast<const uint32_t *
>(spv_bytes.data());
53 const std::span<const uint32_t> words(word_data, spv_bytes.size() /
sizeof(uint32_t));
54 if (words.front() != SPIRV_MAGIC) {
59 uint32_t entry_point_id = 0;
60 const uint32_t id_bound = words[3];
61 if (id_bound == 0U || id_bound > words.size()) {
64 std::vector<uint32_t> descriptor_sets(id_bound, UINT32_MAX);
65 std::vector<uint32_t> descriptor_bindings(id_bound, UINT32_MAX);
66 for (std::size_t offset = 5; offset < words.size();) {
67 const uint16_t word_count =
static_cast<uint16_t
>(words[offset] >> 16U);
68 const uint16_t opcode =
static_cast<uint16_t
>(words[offset] & 0xFFFFU);
69 if (word_count == 0 || offset + word_count > words.size()) {
72 if (opcode == OP_ENTRY_POINT && word_count >= 3U && entry_point_id == 0U) {
73 entry_point_id = words[offset + 2U];
74 switch (words[offset + 1U]) {
75 case EXECUTION_MODEL_VERTEX:
78 case EXECUTION_MODEL_FRAGMENT:
81 case EXECUTION_MODEL_COMPUTE:
88 }
else if (opcode == OP_DECORATE && word_count >= 4U && words[offset + 1U] < id_bound) {
89 const uint32_t target_id = words[offset + 1U];
90 const uint32_t decoration = words[offset + 2U];
91 if (decoration == DECORATION_BINDING) {
92 descriptor_bindings[target_id] = words[offset + 3U];
93 }
else if (decoration == DECORATION_DESCRIPTOR_SET) {
94 descriptor_sets[target_id] = words[offset + 3U];
96 }
else if (opcode == OP_TYPE_IMAGE && word_count >= 9U) {
97 const uint32_t image_format = words[offset + 8U];
98 if (image_format == IMAGE_FORMAT_RGBA8) {
100 }
else if (image_format == IMAGE_FORMAT_RGBA16F) {
104 offset += word_count;
107 for (uint32_t
id = 0;
id < id_bound; ++id) {
108 if (descriptor_sets[
id] != 0U) {
111 switch (descriptor_bindings[
id]) {
127 for (std::size_t offset = 5; offset < words.size();) {
128 const uint16_t word_count =
static_cast<uint16_t
>(words[offset] >> 16U);
129 const uint16_t opcode =
static_cast<uint16_t
>(words[offset] & 0xFFFFU);
130 if (opcode == OP_EXECUTION_MODE && word_count >= 6U && words[offset + 1U] == entry_point_id && words[offset + 2U] == EXECUTION_MODE_LOCAL_SIZE) {
136 offset += word_count;
143 if (device == VK_NULL_HANDLE) {
144 throw mxvk::Exception(
"Cannot create shader module with a null device");
146 if (spv_bytes.empty() || (spv_bytes.size() % 4U) != 0U) {
150 VkShaderModuleCreateInfo create_info{};
151 create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
152 create_info.codeSize = spv_bytes.size();
153 create_info.pCode =
reinterpret_cast<const uint32_t *
>(spv_bytes.data());
155 VkShaderModule module = VK_NULL_HANDLE;
156 if (vkCreateShaderModule(device, &create_info,
nullptr, &module) != VK_SUCCESS) {