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;
}