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