intel: handle XGL_LAST_MIP_OR_SLICE

The miplevel or slice count of XGL_IMAGE_SUBRESOURCE_RANGE can have the
special value XGL_LAST_MIP_OR_SLICE.
diff --git a/icd/intel/img.c b/icd/intel/img.c
index 278f4e1..b3423bb 100644
--- a/icd/intel/img.c
+++ b/icd/intel/img.c
@@ -92,6 +92,7 @@
 
     img->type = info->imageType;
     img->depth = info->extent.depth;
+    img->mip_levels = info->mipLevels;
     img->array_size = info->arraySize;
     img->samples = info->samples;
     intel_layout_init(layout, dev, info, scanout);
diff --git a/icd/intel/img.h b/icd/intel/img.h
index 9805305..a478536 100644
--- a/icd/intel/img.h
+++ b/icd/intel/img.h
@@ -38,6 +38,7 @@
 
     XGL_IMAGE_TYPE type;
     XGL_INT depth;
+    XGL_UINT mip_levels;
     XGL_UINT array_size;
     XGL_UINT samples;
     struct intel_layout layout;
diff --git a/icd/intel/view.c b/icd/intel/view.c
index 3090ae9..87e4a9f 100644
--- a/icd/intel/view.c
+++ b/icd/intel/view.c
@@ -1080,6 +1080,21 @@
 {
     struct intel_img *img = intel_img(info->image);
     struct intel_img_view *view;
+    XGL_UINT mip_levels, array_size;
+
+    if (info->subresourceRange.baseMipLevel >= img->mip_levels ||
+        info->subresourceRange.baseArraySlice >= img->array_size ||
+        !info->subresourceRange.mipLevels ||
+        !info->subresourceRange.arraySize)
+        return XGL_ERROR_INVALID_VALUE;
+
+    mip_levels = info->subresourceRange.mipLevels;
+    if (mip_levels > img->mip_levels - info->subresourceRange.baseMipLevel)
+        mip_levels = img->mip_levels - info->subresourceRange.baseMipLevel;
+
+    array_size = info->subresourceRange.arraySize;
+    if (array_size > img->array_size - info->subresourceRange.baseArraySlice)
+        array_size = img->array_size - info->subresourceRange.baseArraySlice;
 
     view = (struct intel_img_view *) intel_base_create(dev, sizeof(*view),
             dev->base.dbg, XGL_DBG_OBJECT_IMAGE_VIEW, info, 0);
@@ -1094,17 +1109,15 @@
 
     if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7)) {
         surface_state_tex_gen7(dev->gpu, img, info->viewType, info->format,
-                info->subresourceRange.baseMipLevel,
-                info->subresourceRange.mipLevels,
-                info->subresourceRange.baseArraySlice,
-                info->subresourceRange.arraySize, false, view->cmd);
+                info->subresourceRange.baseMipLevel, mip_levels,
+                info->subresourceRange.baseArraySlice, array_size,
+                false, view->cmd);
         view->cmd_len = 8;
     } else {
         surface_state_tex_gen6(dev->gpu, img, info->viewType, info->format,
-                info->subresourceRange.baseMipLevel,
-                info->subresourceRange.mipLevels,
-                info->subresourceRange.baseArraySlice,
-                info->subresourceRange.arraySize, false, view->cmd);
+                info->subresourceRange.baseMipLevel, mip_levels,
+                info->subresourceRange.baseArraySlice, array_size,
+                false, view->cmd);
         view->cmd_len = 6;
     }