diff --git a/docs/features.txt b/docs/features.txt
index bed129f3b53..e26a0df3b90 100644
--- a/docs/features.txt
+++ b/docs/features.txt
@@ -550,7 +550,7 @@ Khronos extensions that are not part of any Vulkan version:
VK_EXT_graphics_pipeline_library DONE (lvp)
VK_EXT_image_2d_view_of_3d DONE (anv, lvp)
VK_EXT_image_drm_format_modifier DONE (anv, radv/gfx9+, tu, v3dv, vn)
- VK_EXT_image_view_min_lod DONE (radv)
+ VK_EXT_image_view_min_lod DONE (radv, tu)
VK_EXT_index_type_uint8 DONE (anv, lvp, radv/gfx8+, v3dv, tu)
VK_EXT_line_rasterization DONE (anv, lvp, radv, tu, v3dv)
VK_EXT_memory_budget DONE (anv, radv, tu)
diff --git a/src/freedreno/fdl/fd6_view.c b/src/freedreno/fdl/fd6_view.c
index b6dce31c22b..432d8f76477 100644
--- a/src/freedreno/fdl/fd6_view.c
+++ b/src/freedreno/fdl/fd6_view.c
@@ -226,6 +226,7 @@ fdl6_view_init(struct fdl6_view *view, const struct fdl_layout **layouts,
view->descriptor[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(layer_size);
view->descriptor[4] = base_addr;
view->descriptor[5] = (base_addr >> 32) | A6XX_TEX_CONST_5_DEPTH(depth);
+ view->descriptor[6] = A6XX_TEX_CONST_6_MIN_LOD_CLAMP(args->min_lod_clamp - args->base_miplevel);
if (layout->tile_all)
view->descriptor[3] |= A6XX_TEX_CONST_3_TILE_ALL;
diff --git a/src/freedreno/fdl/freedreno_layout.h b/src/freedreno/fdl/freedreno_layout.h
index 37a565b338d..2b7d1f6f916 100644
--- a/src/freedreno/fdl/freedreno_layout.h
+++ b/src/freedreno/fdl/freedreno_layout.h
@@ -273,6 +273,7 @@ struct fdl_view_args {
uint64_t iova;
uint32_t base_array_layer, base_miplevel;
uint32_t layer_count, level_count;
+ float min_lod_clamp;
unsigned char swiz[4];
enum pipe_format format;
enum fdl_view_type type;
diff --git a/src/freedreno/registers/adreno/a6xx.xml b/src/freedreno/registers/adreno/a6xx.xml
index fc4f60b7b94..22a9961755d 100644
--- a/src/freedreno/registers/adreno/a6xx.xml
+++ b/src/freedreno/registers/adreno/a6xx.xml
@@ -3862,6 +3862,8 @@ to upconvert to 32b float internally?
+
+
diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c
index de6d302bf04..ae447f620a0 100644
--- a/src/freedreno/vulkan/tu_device.c
+++ b/src/freedreno/vulkan/tu_device.c
@@ -204,6 +204,7 @@ get_device_extensions(const struct tu_physical_device *device,
.EXT_subgroup_size_control = true,
.EXT_image_robustness = true,
.EXT_primitives_generated_query = true,
+ .EXT_image_view_min_lod = true,
#ifndef TU_USE_KGSL
.EXT_physical_device_drm = true,
#endif
@@ -849,6 +850,12 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
features->primitivesGeneratedQueryWithNonZeroStreams = false;
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT: {
+ VkPhysicalDeviceImageViewMinLodFeaturesEXT *features =
+ (VkPhysicalDeviceImageViewMinLodFeaturesEXT *)ext;
+ features->minLod = true;
+ break;
+ }
default:
break;
diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c
index ff011f9bc3a..72fe3113865 100644
--- a/src/freedreno/vulkan/tu_image.c
+++ b/src/freedreno/vulkan/tu_image.c
@@ -176,6 +176,9 @@ tu_image_view_init(struct tu_image_view *iview,
const struct tu_sampler_ycbcr_conversion *conversion = ycbcr_conversion ?
tu_sampler_ycbcr_conversion_from_handle(ycbcr_conversion->conversion) : NULL;
+ const struct VkImageViewMinLodCreateInfoEXT *min_lod =
+ vk_find_struct_const(pCreateInfo->pNext, IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT);
+
iview->image = image;
const struct fdl_layout *layouts[3];
@@ -214,6 +217,7 @@ tu_image_view_init(struct tu_image_view *iview,
args.base_miplevel = range->baseMipLevel;
args.layer_count = tu_get_layerCount(image, range);
args.level_count = tu_get_levelCount(image, range);
+ args.min_lod_clamp = min_lod ? min_lod->minLod : 0.f;
args.format = tu_format_for_aspect(format, aspect_mask);
vk_component_mapping_to_pipe_swizzle(pCreateInfo->components, args.swiz);
if (conversion) {