Returns base alignment of struct member. If |roundUp| is true, also ensure that structs, arrays, and matrices are aligned at least to a multiple of 16 bytes. (That is, when roundUp is true, this function returns the *extended* alignment as it's called by the Vulkan spec.)
| 158 | // multiple of 16 bytes. (That is, when roundUp is true, this function |
| 159 | // returns the *extended* alignment as it's called by the Vulkan spec.) |
| 160 | uint32_t getBaseAlignment(uint32_t member_id, bool roundUp, |
| 161 | const LayoutConstraints& inherited, |
| 162 | MemberConstraints& constraints, |
| 163 | ValidationState_t& vstate) { |
| 164 | const auto inst = vstate.FindDef(member_id); |
| 165 | const auto& words = inst->words(); |
| 166 | // Minimal alignment is byte-aligned. |
| 167 | uint32_t baseAlignment = 1; |
| 168 | switch (inst->opcode()) { |
| 169 | case spv::Op::OpTypeSampledImage: |
| 170 | case spv::Op::OpTypeSampler: |
| 171 | case spv::Op::OpTypeImage: |
| 172 | if (vstate.HasCapability(spv::Capability::BindlessTextureNV)) |
| 173 | return vstate.samplerimage_variable_address_mode() / 8; |
| 174 | // SPV_EXT_descriptor_heap provides a way to access opaque images, we |
| 175 | // assume alignment is validated at runtime as it is determined by the |
| 176 | // client API |
| 177 | if (vstate.HasCapability(spv::Capability::DescriptorHeapEXT)) return 1; |
| 178 | assert(0); |
| 179 | return 0; |
| 180 | case spv::Op::OpTypeInt: |
| 181 | case spv::Op::OpTypeFloat: |
| 182 | baseAlignment = words[2] / 8; |
| 183 | break; |
| 184 | case spv::Op::OpTypeVector: { |
| 185 | const auto componentId = words[2]; |
| 186 | const auto numComponents = words[3]; |
| 187 | const auto componentAlignment = getBaseAlignment( |
| 188 | componentId, roundUp, inherited, constraints, vstate); |
| 189 | baseAlignment = |
| 190 | componentAlignment * |
| 191 | ((numComponents == 3 || numComponents > 4) ? 4 : numComponents); |
| 192 | break; |
| 193 | } |
| 194 | case spv::Op::OpTypeVectorIdEXT: { |
| 195 | const auto componentId = words[2]; |
| 196 | const auto numComponents = vstate.GetDimension(inst->id()); |
| 197 | assert(numComponents != 0); |
| 198 | const auto componentAlignment = getBaseAlignment( |
| 199 | componentId, roundUp, inherited, constraints, vstate); |
| 200 | baseAlignment = |
| 201 | componentAlignment * |
| 202 | ((numComponents == 3 || numComponents > 4) ? 4 : numComponents); |
| 203 | break; |
| 204 | } |
| 205 | case spv::Op::OpTypeMatrix: { |
| 206 | const auto column_type = words[2]; |
| 207 | if (inherited.majorness == kColumnMajor) { |
| 208 | baseAlignment = getBaseAlignment(column_type, roundUp, inherited, |
| 209 | constraints, vstate); |
| 210 | } else { |
| 211 | // A row-major matrix of C columns has a base alignment equal to the |
| 212 | // base alignment of a vector of C matrix components. |
| 213 | const auto num_columns = words[3]; |
| 214 | const auto component_inst = vstate.FindDef(column_type); |
| 215 | const auto component_id = component_inst->words()[2]; |
| 216 | const auto componentAlignment = getBaseAlignment( |
| 217 | component_id, roundUp, inherited, constraints, vstate); |
no test coverage detected