Returns the effective extent of an image subresource, adjusted for mip level and array depth.
| 54 | |
| 55 | // Returns the effective extent of an image subresource, adjusted for mip level and array depth. |
| 56 | VkExtent3D GetEffectiveExtent(uint32_t mip_levels, VkExtent3D extent, VkFormat format, VkImageCreateFlags2KHR flags, |
| 57 | VkImageType image_type, uint32_t array_layers, VkImageAspectFlags aspect_mask, uint32_t mip_level, |
| 58 | bool layer_only) { |
| 59 | // Return zero extent if mip level doesn't exist |
| 60 | if (mip_level >= mip_levels) { |
| 61 | return VkExtent3D{0, 0, 0}; |
| 62 | } |
| 63 | |
| 64 | // If multi-plane, adjust per-plane extent |
| 65 | if (vkuFormatIsMultiplane(format)) { |
| 66 | VkExtent2D divisors = vkuFindMultiplaneExtentDivisors(format, static_cast<VkImageAspectFlagBits>(aspect_mask)); |
| 67 | extent.width /= divisors.width; |
| 68 | extent.height /= divisors.height; |
| 69 | } |
| 70 | |
| 71 | // Mip Maps |
| 72 | { |
| 73 | const uint32_t corner = (flags & VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV) ? 1 : 0; |
| 74 | const uint32_t min_size = 1 + corner; |
| 75 | const uint32_t round_up_nudge = corner ? static_cast<uint32_t>((1 << mip_level) - 1) : 0u; |
| 76 | |
| 77 | if (extent.width != 0) { |
| 78 | extent.width = (extent.width + round_up_nudge) >> mip_level; |
| 79 | extent.width = std::max({min_size, extent.width}); |
| 80 | } |
| 81 | if (extent.height != 0) { |
| 82 | extent.height = (extent.height + round_up_nudge) >> mip_level; |
| 83 | extent.height = std::max({min_size, extent.height}); |
| 84 | } |
| 85 | if (extent.depth != 0) { |
| 86 | extent.depth = (extent.depth + round_up_nudge) >> mip_level; |
| 87 | extent.depth = std::max({min_size, extent.depth}); |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | // Image arrays have an effective z extent that isn't diminished by mip level |
| 92 | // Some cases (https://gitlab.khronos.org/vulkan/vulkan/-/issues/4819) we want only 1 layer's extent |
| 93 | if (VK_IMAGE_TYPE_3D != image_type && !layer_only) { |
| 94 | extent.depth = array_layers; |
| 95 | } |
| 96 | |
| 97 | return extent; |
| 98 | } |
| 99 | |
| 100 | // Currently only used by the testing framework |
| 101 | VkExtent3D GetEffectiveExtent(const VkImageCreateInfo& ci, const VkImageAspectFlags aspect_mask, const uint32_t mip_level) { |
no outgoing calls
no test coverage detected