xref: /aosp_15_r20/external/swiftshader/src/Vulkan/VkImageView.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1 // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "VkImageView.hpp"
16 
17 #include "VkImage.hpp"
18 #include "VkStructConversion.hpp"
19 #include "System/Math.hpp"
20 #include "System/Types.hpp"
21 
22 #include <climits>
23 
24 namespace vk {
25 namespace {
26 
GetImageViewFormat(const VkImageViewCreateInfo * pCreateInfo)27 Format GetImageViewFormat(const VkImageViewCreateInfo *pCreateInfo)
28 {
29 	// VkImageViewCreateInfo: "If image has an external format, format must be VK_FORMAT_UNDEFINED"
30 	// In that case, obtain the format from the underlying image.
31 	if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
32 	{
33 		return Format(pCreateInfo->format);
34 	}
35 
36 	return vk::Cast(pCreateInfo->image)->getFormat();
37 }
38 
39 }  // anonymous namespace
40 
ResolveIdentityMapping(VkComponentMapping mapping)41 VkComponentMapping ResolveIdentityMapping(VkComponentMapping mapping)
42 {
43 	return {
44 		(mapping.r == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_R : mapping.r,
45 		(mapping.g == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_G : mapping.g,
46 		(mapping.b == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_B : mapping.b,
47 		(mapping.a == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_A : mapping.a,
48 	};
49 }
50 
ResolveComponentMapping(VkComponentMapping mapping,vk::Format format)51 VkComponentMapping ResolveComponentMapping(VkComponentMapping mapping, vk::Format format)
52 {
53 	mapping = vk::ResolveIdentityMapping(mapping);
54 
55 	// Replace non-present components with zero/one swizzles so that the sampler
56 	// will give us correct interactions between channel replacement and texel replacement,
57 	// where we've had to invent new channels behind the app's back (eg transparent decompression
58 	// of ETC2 RGB -> BGRA8)
59 	VkComponentSwizzle table[] = {
60 		VK_COMPONENT_SWIZZLE_IDENTITY,
61 		VK_COMPONENT_SWIZZLE_ZERO,
62 		VK_COMPONENT_SWIZZLE_ONE,
63 		VK_COMPONENT_SWIZZLE_R,
64 		format.componentCount() < 2 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_G,
65 		format.componentCount() < 3 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_B,
66 		format.componentCount() < 4 ? VK_COMPONENT_SWIZZLE_ONE : VK_COMPONENT_SWIZZLE_A,
67 	};
68 
69 	return { table[mapping.r], table[mapping.g], table[mapping.b], table[mapping.a] };
70 }
71 
ResolveRemainingLevelsLayers(VkImageSubresourceRange range,const vk::Image * image)72 VkImageSubresourceRange ResolveRemainingLevelsLayers(VkImageSubresourceRange range, const vk::Image *image)
73 {
74 	return {
75 		range.aspectMask,
76 		range.baseMipLevel,
77 		(range.levelCount == VK_REMAINING_MIP_LEVELS) ? (image->getMipLevels() - range.baseMipLevel) : range.levelCount,
78 		range.baseArrayLayer,
79 		(range.layerCount == VK_REMAINING_ARRAY_LAYERS) ? (image->getArrayLayers() - range.baseArrayLayer) : range.layerCount,
80 	};
81 }
82 
Identifier(const VkImageViewCreateInfo * pCreateInfo)83 Identifier::Identifier(const VkImageViewCreateInfo *pCreateInfo)
84 {
85 	const Image *image = vk::Cast(pCreateInfo->image);
86 
87 	VkImageSubresourceRange subresource = ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image);
88 	vk::Format viewFormat = GetImageViewFormat(pCreateInfo).getAspectFormat(subresource.aspectMask);
89 	const Image *sampledImage = image->getSampledImage(viewFormat);
90 
91 	vk::Format samplingFormat = (image == sampledImage) ? viewFormat : sampledImage->getFormat().getAspectFormat(subresource.aspectMask);
92 	pack({ pCreateInfo->viewType, samplingFormat, ResolveComponentMapping(pCreateInfo->components, viewFormat),
93 	       static_cast<uint8_t>(subresource.baseMipLevel),
94 	       static_cast<uint8_t>(subresource.baseMipLevel + subresource.levelCount), subresource.levelCount <= 1u });
95 }
96 
Identifier(VkFormat bufferFormat)97 Identifier::Identifier(VkFormat bufferFormat)
98 {
99 	constexpr VkComponentMapping identityMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
100 	pack({ VK_IMAGE_VIEW_TYPE_1D, bufferFormat, ResolveComponentMapping(identityMapping, bufferFormat), 0, 1, true });
101 }
102 
pack(const State & state)103 void Identifier::pack(const State &state)
104 {
105 	imageViewType = static_cast<uint32_t>(state.imageViewType);
106 	format = Format::mapTo8bit(state.format);
107 	r = static_cast<uint32_t>(state.mapping.r);
108 	g = static_cast<uint32_t>(state.mapping.g);
109 	b = static_cast<uint32_t>(state.mapping.b);
110 	a = static_cast<uint32_t>(state.mapping.a);
111 	minLod = state.minLod;
112 	maxLod = state.maxLod;
113 	singleMipLevel = state.singleMipLevel;
114 }
115 
getState() const116 Identifier::State Identifier::getState() const
117 {
118 	return { static_cast<VkImageViewType>(imageViewType),
119 		     Format::mapFrom8bit(static_cast<uint8_t>(format)),
120 		     { static_cast<VkComponentSwizzle>(r),
121 		       static_cast<VkComponentSwizzle>(g),
122 		       static_cast<VkComponentSwizzle>(b),
123 		       static_cast<VkComponentSwizzle>(a) },
124 		     static_cast<uint8_t>(minLod),
125 		     static_cast<uint8_t>(maxLod),
126 		     static_cast<bool>(singleMipLevel) };
127 }
128 
ImageView(const VkImageViewCreateInfo * pCreateInfo,void * mem,const vk::SamplerYcbcrConversion * ycbcrConversion)129 ImageView::ImageView(const VkImageViewCreateInfo *pCreateInfo, void *mem, const vk::SamplerYcbcrConversion *ycbcrConversion)
130     : image(vk::Cast(pCreateInfo->image))
131     , viewType(pCreateInfo->viewType)
132     , format(GetImageViewFormat(pCreateInfo))
133     , components(ResolveComponentMapping(pCreateInfo->components, format))
134     , subresourceRange(ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image))
135     , ycbcrConversion(ycbcrConversion)
136     , id(pCreateInfo)
137 {
138 }
139 
ComputeRequiredAllocationSize(const VkImageViewCreateInfo * pCreateInfo)140 size_t ImageView::ComputeRequiredAllocationSize(const VkImageViewCreateInfo *pCreateInfo)
141 {
142 	return 0;
143 }
144 
destroy(const VkAllocationCallbacks * pAllocator)145 void ImageView::destroy(const VkAllocationCallbacks *pAllocator)
146 {
147 }
148 
149 // Vulkan 1.2 Table 8. Image and image view parameter compatibility requirements
imageTypesMatch(VkImageType imageType) const150 bool ImageView::imageTypesMatch(VkImageType imageType) const
151 {
152 	uint32_t imageArrayLayers = image->getArrayLayers();
153 
154 	switch(viewType)
155 	{
156 	case VK_IMAGE_VIEW_TYPE_1D:
157 		return (imageType == VK_IMAGE_TYPE_1D) &&
158 		       (subresourceRange.layerCount == 1);
159 	case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
160 		return imageType == VK_IMAGE_TYPE_1D;
161 	case VK_IMAGE_VIEW_TYPE_2D:
162 		return ((imageType == VK_IMAGE_TYPE_2D) ||
163 		        ((imageType == VK_IMAGE_TYPE_3D) &&
164 		         (imageArrayLayers == 1))) &&
165 		       (subresourceRange.layerCount == 1);
166 	case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
167 		return (imageType == VK_IMAGE_TYPE_2D) ||
168 		       ((imageType == VK_IMAGE_TYPE_3D) &&
169 		        (imageArrayLayers == 1));
170 	case VK_IMAGE_VIEW_TYPE_CUBE:
171 		return image->isCubeCompatible() &&
172 		       (imageArrayLayers >= subresourceRange.layerCount) &&
173 		       (subresourceRange.layerCount == 6);
174 	case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
175 		return image->isCubeCompatible() &&
176 		       (imageArrayLayers >= subresourceRange.layerCount) &&
177 		       (subresourceRange.layerCount >= 6);
178 	case VK_IMAGE_VIEW_TYPE_3D:
179 		return (imageType == VK_IMAGE_TYPE_3D) &&
180 		       (imageArrayLayers == 1) &&
181 		       (subresourceRange.layerCount == 1);
182 	default:
183 		UNREACHABLE("Unexpected viewType %d", (int)viewType);
184 	}
185 
186 	return false;
187 }
188 
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkRect2D & renderArea)189 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkRect2D &renderArea)
190 {
191 	// Note: clearing ignores swizzling, so components is ignored.
192 
193 	ASSERT(imageTypesMatch(image->getImageType()));
194 	ASSERT(format.isCompatible(image->getFormat()));
195 
196 	VkImageSubresourceRange sr = subresourceRange;
197 	sr.aspectMask = aspectMask;
198 	image->clear(clearValue, format, renderArea, sr);
199 }
200 
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkClearRect & renderArea)201 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkClearRect &renderArea)
202 {
203 	// Note: clearing ignores swizzling, so components is ignored.
204 
205 	ASSERT(imageTypesMatch(image->getImageType()));
206 	ASSERT(format.isCompatible(image->getFormat()));
207 
208 	VkImageSubresourceRange sr;
209 	sr.aspectMask = aspectMask;
210 	sr.baseMipLevel = subresourceRange.baseMipLevel;
211 	sr.levelCount = subresourceRange.levelCount;
212 	sr.baseArrayLayer = renderArea.baseArrayLayer + subresourceRange.baseArrayLayer;
213 	sr.layerCount = renderArea.layerCount;
214 
215 	image->clear(clearValue, format, renderArea.rect, sr);
216 }
217 
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkRect2D & renderArea,uint32_t layerMask)218 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
219 {
220 	if(layerMask == 0)
221 	{
222 		clear(clearValue, aspectMask, renderArea);
223 	}
224 	else
225 	{
226 		clearWithLayerMask(clearValue, aspectMask, renderArea, layerMask);
227 	}
228 }
229 
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkClearRect & renderArea,uint32_t layerMask)230 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkClearRect &renderArea, uint32_t layerMask)
231 {
232 	if(layerMask == 0)
233 	{
234 		clear(clearValue, aspectMask, renderArea);
235 	}
236 	else
237 	{
238 		clearWithLayerMask(clearValue, aspectMask, renderArea.rect, layerMask);
239 	}
240 }
241 
clearWithLayerMask(const VkClearValue & clearValue,VkImageAspectFlags aspectMask,const VkRect2D & renderArea,uint32_t layerMask)242 void ImageView::clearWithLayerMask(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
243 {
244 	while(layerMask)
245 	{
246 		uint32_t layer = sw::log2i(layerMask);
247 		layerMask &= ~(1 << layer);
248 		VkClearRect r = { renderArea, layer, 1 };
249 		r.baseArrayLayer = layer;
250 		clear(clearValue, aspectMask, r);
251 	}
252 }
253 
resolveSingleLayer(ImageView * resolveAttachment,int layer)254 void ImageView::resolveSingleLayer(ImageView *resolveAttachment, int layer)
255 {
256 	if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
257 	{
258 		UNIMPLEMENTED("b/148242443: levelCount != 1");  // FIXME(b/148242443)
259 	}
260 
261 	VkImageResolve2KHR region;
262 	region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR;
263 	region.pNext = nullptr;
264 	region.srcSubresource = {
265 		subresourceRange.aspectMask,
266 		subresourceRange.baseMipLevel,
267 		subresourceRange.baseArrayLayer + layer,
268 		1
269 	};
270 	region.srcOffset = { 0, 0, 0 };
271 	region.dstSubresource = {
272 		resolveAttachment->subresourceRange.aspectMask,
273 		resolveAttachment->subresourceRange.baseMipLevel,
274 		resolveAttachment->subresourceRange.baseArrayLayer + layer,
275 		1
276 	};
277 	region.dstOffset = { 0, 0, 0 };
278 	region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
279 	                                         subresourceRange.baseMipLevel);
280 
281 	image->resolveTo(resolveAttachment->image, region);
282 }
283 
resolve(ImageView * resolveAttachment)284 void ImageView::resolve(ImageView *resolveAttachment)
285 {
286 	if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
287 	{
288 		UNIMPLEMENTED("b/148242443: levelCount != 1");  // FIXME(b/148242443)
289 	}
290 
291 	VkImageResolve2KHR region;
292 	region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR;
293 	region.pNext = nullptr;
294 	region.srcSubresource = {
295 		subresourceRange.aspectMask,
296 		subresourceRange.baseMipLevel,
297 		subresourceRange.baseArrayLayer,
298 		subresourceRange.layerCount
299 	};
300 	region.srcOffset = { 0, 0, 0 };
301 	region.dstSubresource = {
302 		resolveAttachment->subresourceRange.aspectMask,
303 		resolveAttachment->subresourceRange.baseMipLevel,
304 		resolveAttachment->subresourceRange.baseArrayLayer,
305 		resolveAttachment->subresourceRange.layerCount
306 	};
307 	region.dstOffset = { 0, 0, 0 };
308 	region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
309 	                                         subresourceRange.baseMipLevel);
310 
311 	image->resolveTo(resolveAttachment->image, region);
312 }
313 
resolve(ImageView * resolveAttachment,uint32_t layerMask)314 void ImageView::resolve(ImageView *resolveAttachment, uint32_t layerMask)
315 {
316 	if(layerMask == 0)
317 	{
318 		resolve(resolveAttachment);
319 	}
320 	else
321 	{
322 		resolveWithLayerMask(resolveAttachment, layerMask);
323 	}
324 }
325 
resolveWithLayerMask(ImageView * resolveAttachment,uint32_t layerMask)326 void ImageView::resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask)
327 {
328 	while(layerMask)
329 	{
330 		int layer = sw::log2i(layerMask);
331 		layerMask &= ~(1 << layer);
332 		resolveSingleLayer(resolveAttachment, layer);
333 	}
334 }
335 
resolveDepthStencil(ImageView * resolveAttachment,VkResolveModeFlagBits depthResolveMode,VkResolveModeFlagBits stencilResolveMode)336 void ImageView::resolveDepthStencil(ImageView *resolveAttachment, VkResolveModeFlagBits depthResolveMode, VkResolveModeFlagBits stencilResolveMode)
337 {
338 	ASSERT(subresourceRange.levelCount == 1 && resolveAttachment->subresourceRange.levelCount == 1);
339 	if((subresourceRange.layerCount != 1) || (resolveAttachment->subresourceRange.layerCount != 1))
340 	{
341 		UNIMPLEMENTED("b/148242443: layerCount != 1");  // FIXME(b/148242443)
342 	}
343 
344 	image->resolveDepthStencilTo(this, resolveAttachment, depthResolveMode, stencilResolveMode);
345 }
346 
getImage(Usage usage) const347 const Image *ImageView::getImage(Usage usage) const
348 {
349 	switch(usage)
350 	{
351 	case RAW:
352 		return image;
353 	case SAMPLING:
354 		return image->getSampledImage(format);
355 	default:
356 		UNREACHABLE("usage %d", int(usage));
357 		return nullptr;
358 	}
359 }
360 
getFormat(Usage usage) const361 Format ImageView::getFormat(Usage usage) const
362 {
363 	Format imageFormat = ((usage == RAW) || (getImage(usage) == image)) ? format : getImage(usage)->getFormat();
364 	return imageFormat.getAspectFormat(subresourceRange.aspectMask);
365 }
366 
rowPitchBytes(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const367 uint32_t ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
368 {
369 	return sw::assert_cast<uint32_t>(getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel));
370 }
371 
slicePitchBytes(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const372 uint32_t ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
373 {
374 	return sw::assert_cast<uint32_t>(getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel));
375 }
376 
getMipLevelSize(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const377 uint32_t ImageView::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
378 {
379 	return sw::assert_cast<uint32_t>(getImage(usage)->getMipLevelSize(aspect, subresourceRange.baseMipLevel + mipLevel));
380 }
381 
layerPitchBytes(VkImageAspectFlagBits aspect,Usage usage) const382 uint32_t ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
383 {
384 	return sw::assert_cast<uint32_t>(getImage(usage)->getLayerSize(aspect));
385 }
386 
getMipLevelExtent(uint32_t mipLevel) const387 VkExtent2D ImageView::getMipLevelExtent(uint32_t mipLevel) const
388 {
389 	return Extent2D(image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
390 	                                         subresourceRange.baseMipLevel + mipLevel));
391 }
392 
getMipLevelExtent(uint32_t mipLevel,VkImageAspectFlagBits aspect) const393 VkExtent2D ImageView::getMipLevelExtent(uint32_t mipLevel, VkImageAspectFlagBits aspect) const
394 {
395 	return Extent2D(image->getMipLevelExtent(aspect, subresourceRange.baseMipLevel + mipLevel));
396 }
397 
getDepthOrLayerCount(uint32_t mipLevel) const398 uint32_t ImageView::getDepthOrLayerCount(uint32_t mipLevel) const
399 {
400 	VkExtent3D extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
401 	                                             subresourceRange.baseMipLevel + mipLevel);
402 	uint32_t layers = subresourceRange.layerCount;
403 	uint32_t depthOrLayers = layers > 1 ? layers : extent.depth;
404 
405 	// For cube images the number of whole cubes is returned
406 	if(viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
407 	   viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
408 	{
409 		depthOrLayers /= 6;
410 	}
411 
412 	return depthOrLayers;
413 }
414 
getOffsetPointer(const VkOffset3D & offset,VkImageAspectFlagBits aspect,uint32_t mipLevel,uint32_t layer,Usage usage) const415 void *ImageView::getOffsetPointer(const VkOffset3D &offset, VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer, Usage usage) const
416 {
417 	ASSERT(mipLevel < subresourceRange.levelCount);
418 
419 	VkImageSubresource imageSubresource = {
420 		static_cast<VkImageAspectFlags>(aspect),
421 		subresourceRange.baseMipLevel + mipLevel,
422 		subresourceRange.baseArrayLayer + layer,
423 	};
424 
425 	return getImage(usage)->getTexelPointer(offset, imageSubresource);
426 }
427 
428 }  // namespace vk
429