• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
21 #include <climits>
22 
23 namespace vk {
24 namespace {
25 
GetImageViewFormat(const VkImageViewCreateInfo * pCreateInfo)26 Format GetImageViewFormat(const VkImageViewCreateInfo *pCreateInfo)
27 {
28 	// VkImageViewCreateInfo: "If image has an external format, format must be VK_FORMAT_UNDEFINED"
29 	// In that case, obtain the format from the underlying image.
30 	if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
31 	{
32 		return Format(pCreateInfo->format);
33 	}
34 
35 	return vk::Cast(pCreateInfo->image)->getFormat();
36 }
37 
38 }  // anonymous namespace
39 
ResolveIdentityMapping(VkComponentMapping mapping)40 VkComponentMapping ResolveIdentityMapping(VkComponentMapping mapping)
41 {
42 	return {
43 		(mapping.r == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_R : mapping.r,
44 		(mapping.g == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_G : mapping.g,
45 		(mapping.b == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_B : mapping.b,
46 		(mapping.a == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_A : mapping.a,
47 	};
48 }
49 
ResolveComponentMapping(VkComponentMapping mapping,vk::Format format)50 VkComponentMapping ResolveComponentMapping(VkComponentMapping mapping, vk::Format format)
51 {
52 	mapping = vk::ResolveIdentityMapping(mapping);
53 
54 	// Replace non-present components with zero/one swizzles so that the sampler
55 	// will give us correct interactions between channel replacement and texel replacement,
56 	// where we've had to invent new channels behind the app's back (eg transparent decompression
57 	// of ETC2 RGB -> BGRA8)
58 	VkComponentSwizzle table[] = {
59 		VK_COMPONENT_SWIZZLE_IDENTITY,
60 		VK_COMPONENT_SWIZZLE_ZERO,
61 		VK_COMPONENT_SWIZZLE_ONE,
62 		VK_COMPONENT_SWIZZLE_R,
63 		format.componentCount() < 2 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_G,
64 		format.componentCount() < 3 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_B,
65 		format.componentCount() < 4 ? VK_COMPONENT_SWIZZLE_ONE : VK_COMPONENT_SWIZZLE_A,
66 	};
67 
68 	return { table[mapping.r], table[mapping.g], table[mapping.b], table[mapping.a] };
69 }
70 
ResolveRemainingLevelsLayers(VkImageSubresourceRange range,const vk::Image * image)71 VkImageSubresourceRange ResolveRemainingLevelsLayers(VkImageSubresourceRange range, const vk::Image *image)
72 {
73 	return {
74 		range.aspectMask,
75 		range.baseMipLevel,
76 		(range.levelCount == VK_REMAINING_MIP_LEVELS) ? (image->getMipLevels() - range.baseMipLevel) : range.levelCount,
77 		range.baseArrayLayer,
78 		(range.layerCount == VK_REMAINING_ARRAY_LAYERS) ? (image->getArrayLayers() - range.baseArrayLayer) : range.layerCount,
79 	};
80 }
81 
Identifier(const VkImageViewCreateInfo * pCreateInfo)82 Identifier::Identifier(const VkImageViewCreateInfo *pCreateInfo)
83 {
84 	const Image *image = vk::Cast(pCreateInfo->image);
85 
86 	VkImageSubresourceRange subresource = ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image);
87 	vk::Format viewFormat = GetImageViewFormat(pCreateInfo).getAspectFormat(subresource.aspectMask);
88 	const Image *sampledImage = image->getSampledImage(viewFormat);
89 
90 	vk::Format samplingFormat = (image == sampledImage) ? viewFormat : sampledImage->getFormat().getAspectFormat(subresource.aspectMask);
91 	pack({ pCreateInfo->viewType, samplingFormat, ResolveComponentMapping(pCreateInfo->components, viewFormat), subresource.levelCount <= 1u });
92 }
93 
Identifier(VkFormat bufferFormat)94 Identifier::Identifier(VkFormat bufferFormat)
95 {
96 	constexpr VkComponentMapping identityMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
97 	pack({ VK_IMAGE_VIEW_TYPE_1D, bufferFormat, ResolveComponentMapping(identityMapping, bufferFormat), true });
98 }
99 
pack(const State & state)100 void Identifier::pack(const State &state)
101 {
102 	imageViewType = static_cast<uint32_t>(state.imageViewType);
103 	format = Format::mapTo8bit(state.format);
104 	r = static_cast<uint32_t>(state.mapping.r);
105 	g = static_cast<uint32_t>(state.mapping.g);
106 	b = static_cast<uint32_t>(state.mapping.b);
107 	a = static_cast<uint32_t>(state.mapping.a);
108 	singleMipLevel = state.singleMipLevel;
109 }
110 
getState() const111 Identifier::State Identifier::getState() const
112 {
113 	return { static_cast<VkImageViewType>(imageViewType),
114 		     Format::mapFrom8bit(static_cast<uint8_t>(format)),
115 		     { static_cast<VkComponentSwizzle>(r),
116 		       static_cast<VkComponentSwizzle>(g),
117 		       static_cast<VkComponentSwizzle>(b),
118 		       static_cast<VkComponentSwizzle>(a) },
119 		     static_cast<bool>(singleMipLevel) };
120 }
121 
ImageView(const VkImageViewCreateInfo * pCreateInfo,void * mem,const vk::SamplerYcbcrConversion * ycbcrConversion)122 ImageView::ImageView(const VkImageViewCreateInfo *pCreateInfo, void *mem, const vk::SamplerYcbcrConversion *ycbcrConversion)
123     : image(vk::Cast(pCreateInfo->image))
124     , viewType(pCreateInfo->viewType)
125     , format(GetImageViewFormat(pCreateInfo))
126     , components(ResolveComponentMapping(pCreateInfo->components, format))
127     , subresourceRange(ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image))
128     , ycbcrConversion(ycbcrConversion)
129     , id(pCreateInfo)
130 {
131 }
132 
ComputeRequiredAllocationSize(const VkImageViewCreateInfo * pCreateInfo)133 size_t ImageView::ComputeRequiredAllocationSize(const VkImageViewCreateInfo *pCreateInfo)
134 {
135 	return 0;
136 }
137 
destroy(const VkAllocationCallbacks * pAllocator)138 void ImageView::destroy(const VkAllocationCallbacks *pAllocator)
139 {
140 }
141 
142 // Vulkan 1.2 Table 8. Image and image view parameter compatibility requirements
imageTypesMatch(VkImageType imageType) const143 bool ImageView::imageTypesMatch(VkImageType imageType) const
144 {
145 	uint32_t imageArrayLayers = image->getArrayLayers();
146 
147 	switch(viewType)
148 	{
149 	case VK_IMAGE_VIEW_TYPE_1D:
150 		return (imageType == VK_IMAGE_TYPE_1D) &&
151 		       (subresourceRange.layerCount == 1);
152 	case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
153 		return imageType == VK_IMAGE_TYPE_1D;
154 	case VK_IMAGE_VIEW_TYPE_2D:
155 		return ((imageType == VK_IMAGE_TYPE_2D) ||
156 		        ((imageType == VK_IMAGE_TYPE_3D) &&
157 		         (imageArrayLayers == 1))) &&
158 		       (subresourceRange.layerCount == 1);
159 	case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
160 		return (imageType == VK_IMAGE_TYPE_2D) ||
161 		       ((imageType == VK_IMAGE_TYPE_3D) &&
162 		        (imageArrayLayers == 1));
163 	case VK_IMAGE_VIEW_TYPE_CUBE:
164 		return image->isCubeCompatible() &&
165 		       (imageArrayLayers >= subresourceRange.layerCount) &&
166 		       (subresourceRange.layerCount == 6);
167 	case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
168 		return image->isCubeCompatible() &&
169 		       (imageArrayLayers >= subresourceRange.layerCount) &&
170 		       (subresourceRange.layerCount >= 6);
171 	case VK_IMAGE_VIEW_TYPE_3D:
172 		return (imageType == VK_IMAGE_TYPE_3D) &&
173 		       (imageArrayLayers == 1) &&
174 		       (subresourceRange.layerCount == 1);
175 	default:
176 		UNREACHABLE("Unexpected viewType %d", (int)viewType);
177 	}
178 
179 	return false;
180 }
181 
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkRect2D & renderArea)182 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkRect2D &renderArea)
183 {
184 	// Note: clearing ignores swizzling, so components is ignored.
185 
186 	ASSERT(imageTypesMatch(image->getImageType()));
187 	ASSERT(format.isCompatible(image->getFormat()));
188 
189 	VkImageSubresourceRange sr = subresourceRange;
190 	sr.aspectMask = aspectMask;
191 	image->clear(clearValue, format, renderArea, sr);
192 }
193 
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkClearRect & renderArea)194 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkClearRect &renderArea)
195 {
196 	// Note: clearing ignores swizzling, so components is ignored.
197 
198 	ASSERT(imageTypesMatch(image->getImageType()));
199 	ASSERT(format.isCompatible(image->getFormat()));
200 
201 	VkImageSubresourceRange sr;
202 	sr.aspectMask = aspectMask;
203 	sr.baseMipLevel = subresourceRange.baseMipLevel;
204 	sr.levelCount = subresourceRange.levelCount;
205 	sr.baseArrayLayer = renderArea.baseArrayLayer + subresourceRange.baseArrayLayer;
206 	sr.layerCount = renderArea.layerCount;
207 
208 	image->clear(clearValue, format, renderArea.rect, sr);
209 }
210 
clearWithLayerMask(const VkClearValue & clearValue,VkImageAspectFlags aspectMask,const VkRect2D & renderArea,uint32_t layerMask)211 void ImageView::clearWithLayerMask(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
212 {
213 	while(layerMask)
214 	{
215 		uint32_t layer = sw::log2i(layerMask);
216 		layerMask &= ~(1 << layer);
217 		VkClearRect r = { renderArea, layer, 1 };
218 		r.baseArrayLayer = layer;
219 		clear(clearValue, aspectMask, r);
220 	}
221 }
222 
resolve(ImageView * resolveAttachment,int layer)223 void ImageView::resolve(ImageView *resolveAttachment, int layer)
224 {
225 	if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
226 	{
227 		UNIMPLEMENTED("b/148242443: levelCount != 1");  // FIXME(b/148242443)
228 	}
229 
230 	VkImageResolve2KHR region;
231 	region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR;
232 	region.pNext = nullptr;
233 	region.srcSubresource = {
234 		subresourceRange.aspectMask,
235 		subresourceRange.baseMipLevel,
236 		subresourceRange.baseArrayLayer + layer,
237 		1
238 	};
239 	region.srcOffset = { 0, 0, 0 };
240 	region.dstSubresource = {
241 		resolveAttachment->subresourceRange.aspectMask,
242 		resolveAttachment->subresourceRange.baseMipLevel,
243 		resolveAttachment->subresourceRange.baseArrayLayer + layer,
244 		1
245 	};
246 	region.dstOffset = { 0, 0, 0 };
247 	region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
248 	                                         subresourceRange.baseMipLevel);
249 
250 	image->resolveTo(resolveAttachment->image, region);
251 }
252 
resolve(ImageView * resolveAttachment)253 void ImageView::resolve(ImageView *resolveAttachment)
254 {
255 	if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
256 	{
257 		UNIMPLEMENTED("b/148242443: levelCount != 1");  // FIXME(b/148242443)
258 	}
259 
260 	VkImageResolve2KHR region;
261 	region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR;
262 	region.pNext = nullptr;
263 	region.srcSubresource = {
264 		subresourceRange.aspectMask,
265 		subresourceRange.baseMipLevel,
266 		subresourceRange.baseArrayLayer,
267 		subresourceRange.layerCount
268 	};
269 	region.srcOffset = { 0, 0, 0 };
270 	region.dstSubresource = {
271 		resolveAttachment->subresourceRange.aspectMask,
272 		resolveAttachment->subresourceRange.baseMipLevel,
273 		resolveAttachment->subresourceRange.baseArrayLayer,
274 		resolveAttachment->subresourceRange.layerCount
275 	};
276 	region.dstOffset = { 0, 0, 0 };
277 	region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
278 	                                         subresourceRange.baseMipLevel);
279 
280 	image->resolveTo(resolveAttachment->image, region);
281 }
282 
resolveWithLayerMask(ImageView * resolveAttachment,uint32_t layerMask)283 void ImageView::resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask)
284 {
285 	while(layerMask)
286 	{
287 		int layer = sw::log2i(layerMask);
288 		layerMask &= ~(1 << layer);
289 		resolve(resolveAttachment, layer);
290 	}
291 }
292 
resolveDepthStencil(ImageView * resolveAttachment,const VkSubpassDescriptionDepthStencilResolve & dsResolve)293 void ImageView::resolveDepthStencil(ImageView *resolveAttachment, const VkSubpassDescriptionDepthStencilResolve &dsResolve)
294 {
295 	ASSERT(subresourceRange.levelCount == 1 && resolveAttachment->subresourceRange.levelCount == 1);
296 	if((subresourceRange.layerCount != 1) || (resolveAttachment->subresourceRange.layerCount != 1))
297 	{
298 		UNIMPLEMENTED("b/148242443: layerCount != 1");  // FIXME(b/148242443)
299 	}
300 
301 	image->resolveDepthStencilTo(this, resolveAttachment, dsResolve);
302 }
303 
getImage(Usage usage) const304 const Image *ImageView::getImage(Usage usage) const
305 {
306 	switch(usage)
307 	{
308 	case RAW:
309 		return image;
310 	case SAMPLING:
311 		return image->getSampledImage(format);
312 	default:
313 		UNREACHABLE("usage %d", int(usage));
314 		return nullptr;
315 	}
316 }
317 
getFormat(Usage usage) const318 Format ImageView::getFormat(Usage usage) const
319 {
320 	Format imageFormat = ((usage == RAW) || (getImage(usage) == image)) ? format : getImage(usage)->getFormat();
321 	return imageFormat.getAspectFormat(subresourceRange.aspectMask);
322 }
323 
rowPitchBytes(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const324 int ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
325 {
326 	return getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
327 }
328 
slicePitchBytes(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const329 int ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
330 {
331 	return getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
332 }
333 
getMipLevelSize(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const334 int ImageView::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
335 {
336 	return getImage(usage)->getMipLevelSize(aspect, subresourceRange.baseMipLevel + mipLevel);
337 }
338 
layerPitchBytes(VkImageAspectFlagBits aspect,Usage usage) const339 int ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
340 {
341 	return static_cast<int>(getImage(usage)->getLayerSize(aspect));
342 }
343 
getMipLevelExtent(uint32_t mipLevel) const344 VkExtent2D ImageView::getMipLevelExtent(uint32_t mipLevel) const
345 {
346 	return Extent2D(image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
347 	                                         subresourceRange.baseMipLevel + mipLevel));
348 }
349 
getMipLevelExtent(uint32_t mipLevel,VkImageAspectFlagBits aspect) const350 VkExtent2D ImageView::getMipLevelExtent(uint32_t mipLevel, VkImageAspectFlagBits aspect) const
351 {
352 	return Extent2D(image->getMipLevelExtent(aspect, subresourceRange.baseMipLevel + mipLevel));
353 }
354 
getDepthOrLayerCount(uint32_t mipLevel) const355 int ImageView::getDepthOrLayerCount(uint32_t mipLevel) const
356 {
357 	VkExtent3D extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
358 	                                             subresourceRange.baseMipLevel + mipLevel);
359 	int layers = subresourceRange.layerCount;
360 	int depthOrLayers = layers > 1 ? layers : extent.depth;
361 
362 	// For cube images the number of whole cubes is returned
363 	if(viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
364 	   viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
365 	{
366 		depthOrLayers /= 6;
367 	}
368 
369 	return depthOrLayers;
370 }
371 
getOffsetPointer(const VkOffset3D & offset,VkImageAspectFlagBits aspect,uint32_t mipLevel,uint32_t layer,Usage usage) const372 void *ImageView::getOffsetPointer(const VkOffset3D &offset, VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer, Usage usage) const
373 {
374 	ASSERT(mipLevel < subresourceRange.levelCount);
375 
376 	VkImageSubresource imageSubresource = {
377 		static_cast<VkImageAspectFlags>(aspect),
378 		subresourceRange.baseMipLevel + mipLevel,
379 		subresourceRange.baseArrayLayer + layer,
380 	};
381 
382 	return getImage(usage)->getTexelPointer(offset, imageSubresource);
383 }
384 
385 }  // namespace vk
386