• 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 #include "VkImage.hpp"
17 #include <System/Math.hpp>
18 
19 namespace {
20 
ResolveComponentMapping(VkComponentMapping m,vk::Format format)21 VkComponentMapping ResolveComponentMapping(VkComponentMapping m, vk::Format format)
22 {
23 	m = vk::ResolveIdentityMapping(m);
24 
25 	// Replace non-present components with zero/one swizzles so that the sampler
26 	// will give us correct interactions between channel replacement and texel replacement,
27 	// where we've had to invent new channels behind the app's back (eg transparent decompression
28 	// of ETC2 RGB -> BGRA8)
29 	VkComponentSwizzle table[] = {
30 		VK_COMPONENT_SWIZZLE_IDENTITY,
31 		VK_COMPONENT_SWIZZLE_ZERO,
32 		VK_COMPONENT_SWIZZLE_ONE,
33 		VK_COMPONENT_SWIZZLE_R,
34 		format.componentCount() < 2 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_G,
35 		format.componentCount() < 3 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_B,
36 		format.componentCount() < 4 ? VK_COMPONENT_SWIZZLE_ONE : VK_COMPONENT_SWIZZLE_A,
37 	};
38 
39 	return { table[m.r], table[m.g], table[m.b], table[m.a] };
40 }
41 
ResolveRemainingLevelsLayers(VkImageSubresourceRange range,const vk::Image * image)42 VkImageSubresourceRange ResolveRemainingLevelsLayers(VkImageSubresourceRange range, const vk::Image *image)
43 {
44 	return {
45 		range.aspectMask,
46 		range.baseMipLevel,
47 		(range.levelCount == VK_REMAINING_MIP_LEVELS) ? (image->getMipLevels() - range.baseMipLevel) : range.levelCount,
48 		range.baseArrayLayer,
49 		(range.layerCount == VK_REMAINING_ARRAY_LAYERS) ? (image->getArrayLayers() - range.baseArrayLayer) : range.layerCount,
50 	};
51 }
52 
53 }  // anonymous namespace
54 
55 namespace vk {
56 
57 std::atomic<uint32_t> ImageView::nextID(1);
58 
ImageView(const VkImageViewCreateInfo * pCreateInfo,void * mem,const vk::SamplerYcbcrConversion * ycbcrConversion)59 ImageView::ImageView(const VkImageViewCreateInfo *pCreateInfo, void *mem, const vk::SamplerYcbcrConversion *ycbcrConversion)
60     : image(vk::Cast(pCreateInfo->image))
61     , viewType(pCreateInfo->viewType)
62     , format(pCreateInfo->format)
63     , components(ResolveComponentMapping(pCreateInfo->components, format))
64     , subresourceRange(ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image))
65     , ycbcrConversion(ycbcrConversion)
66 {
67 }
68 
ComputeRequiredAllocationSize(const VkImageViewCreateInfo * pCreateInfo)69 size_t ImageView::ComputeRequiredAllocationSize(const VkImageViewCreateInfo *pCreateInfo)
70 {
71 	return 0;
72 }
73 
destroy(const VkAllocationCallbacks * pAllocator)74 void ImageView::destroy(const VkAllocationCallbacks *pAllocator)
75 {
76 }
77 
78 // Vulkan 1.2 Table 8. Image and image view parameter compatibility requirements
imageTypesMatch(VkImageType imageType) const79 bool ImageView::imageTypesMatch(VkImageType imageType) const
80 {
81 	uint32_t imageArrayLayers = image->getArrayLayers();
82 
83 	switch(viewType)
84 	{
85 		case VK_IMAGE_VIEW_TYPE_1D:
86 			return (imageType == VK_IMAGE_TYPE_1D) &&
87 			       (subresourceRange.layerCount == 1);
88 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
89 			return imageType == VK_IMAGE_TYPE_1D;
90 		case VK_IMAGE_VIEW_TYPE_2D:
91 			return ((imageType == VK_IMAGE_TYPE_2D) ||
92 			        ((imageType == VK_IMAGE_TYPE_3D) &&
93 			         (imageArrayLayers == 1))) &&
94 			       (subresourceRange.layerCount == 1);
95 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
96 			return (imageType == VK_IMAGE_TYPE_2D) ||
97 			       ((imageType == VK_IMAGE_TYPE_3D) &&
98 			        (imageArrayLayers == 1));
99 		case VK_IMAGE_VIEW_TYPE_CUBE:
100 			return image->isCube() &&
101 			       (imageArrayLayers >= subresourceRange.layerCount) &&
102 			       (subresourceRange.layerCount == 6);
103 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
104 			return image->isCube() &&
105 			       (imageArrayLayers >= subresourceRange.layerCount) &&
106 			       (subresourceRange.layerCount >= 6);
107 		case VK_IMAGE_VIEW_TYPE_3D:
108 			return (imageType == VK_IMAGE_TYPE_3D) &&
109 			       (imageArrayLayers == 1) &&
110 			       (subresourceRange.layerCount == 1);
111 		default:
112 			UNREACHABLE("Unexpected viewType %d", (int)viewType);
113 	}
114 
115 	return false;
116 }
117 
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkRect2D & renderArea)118 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkRect2D &renderArea)
119 {
120 	// Note: clearing ignores swizzling, so components is ignored.
121 
122 	ASSERT(imageTypesMatch(image->getImageType()));
123 	ASSERT(format.isCompatible(image->getFormat()));
124 
125 	VkImageSubresourceRange sr = subresourceRange;
126 	sr.aspectMask = aspectMask;
127 	image->clear(clearValue, format, renderArea, sr);
128 }
129 
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkClearRect & renderArea)130 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkClearRect &renderArea)
131 {
132 	// Note: clearing ignores swizzling, so components is ignored.
133 
134 	ASSERT(imageTypesMatch(image->getImageType()));
135 	ASSERT(format.isCompatible(image->getFormat()));
136 
137 	VkImageSubresourceRange sr;
138 	sr.aspectMask = aspectMask;
139 	sr.baseMipLevel = subresourceRange.baseMipLevel;
140 	sr.levelCount = subresourceRange.levelCount;
141 	sr.baseArrayLayer = renderArea.baseArrayLayer + subresourceRange.baseArrayLayer;
142 	sr.layerCount = renderArea.layerCount;
143 
144 	image->clear(clearValue, format, renderArea.rect, sr);
145 }
146 
clearWithLayerMask(const VkClearValue & clearValue,VkImageAspectFlags aspectMask,const VkRect2D & renderArea,uint32_t layerMask)147 void ImageView::clearWithLayerMask(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
148 {
149 	while(layerMask)
150 	{
151 		uint32_t layer = sw::log2i(layerMask);
152 		layerMask &= ~(1 << layer);
153 		VkClearRect r = { renderArea, layer, 1 };
154 		r.baseArrayLayer = layer;
155 		clear(clearValue, aspectMask, r);
156 	}
157 }
158 
resolve(ImageView * resolveAttachment,int layer)159 void ImageView::resolve(ImageView *resolveAttachment, int layer)
160 {
161 	if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
162 	{
163 		UNIMPLEMENTED("b/148242443: levelCount != 1");  // FIXME(b/148242443)
164 	}
165 
166 	VkImageCopy region;
167 	region.srcSubresource = {
168 		subresourceRange.aspectMask,
169 		subresourceRange.baseMipLevel,
170 		subresourceRange.baseArrayLayer + layer,
171 		1
172 	};
173 	region.srcOffset = { 0, 0, 0 };
174 	region.dstSubresource = {
175 		resolveAttachment->subresourceRange.aspectMask,
176 		resolveAttachment->subresourceRange.baseMipLevel,
177 		resolveAttachment->subresourceRange.baseArrayLayer + layer,
178 		1
179 	};
180 	region.dstOffset = { 0, 0, 0 };
181 	region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
182 	                                         subresourceRange.baseMipLevel);
183 
184 	image->copyTo(resolveAttachment->image, region);
185 }
186 
resolve(ImageView * resolveAttachment)187 void ImageView::resolve(ImageView *resolveAttachment)
188 {
189 	if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
190 	{
191 		UNIMPLEMENTED("b/148242443: levelCount != 1");  // FIXME(b/148242443)
192 	}
193 
194 	VkImageCopy region;
195 	region.srcSubresource = {
196 		subresourceRange.aspectMask,
197 		subresourceRange.baseMipLevel,
198 		subresourceRange.baseArrayLayer,
199 		subresourceRange.layerCount
200 	};
201 	region.srcOffset = { 0, 0, 0 };
202 	region.dstSubresource = {
203 		resolveAttachment->subresourceRange.aspectMask,
204 		resolveAttachment->subresourceRange.baseMipLevel,
205 		resolveAttachment->subresourceRange.baseArrayLayer,
206 		resolveAttachment->subresourceRange.layerCount
207 	};
208 	region.dstOffset = { 0, 0, 0 };
209 	region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
210 	                                         subresourceRange.baseMipLevel);
211 
212 	image->copyTo(resolveAttachment->image, region);
213 }
214 
resolveWithLayerMask(ImageView * resolveAttachment,uint32_t layerMask)215 void ImageView::resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask)
216 {
217 	while(layerMask)
218 	{
219 		int layer = sw::log2i(layerMask);
220 		layerMask &= ~(1 << layer);
221 		resolve(resolveAttachment, layer);
222 	}
223 }
224 
getImage(Usage usage) const225 const Image *ImageView::getImage(Usage usage) const
226 {
227 	switch(usage)
228 	{
229 		case RAW:
230 			return image;
231 		case SAMPLING:
232 			return image->getSampledImage(format);
233 		default:
234 			UNREACHABLE("usage %d", int(usage));
235 			return nullptr;
236 	}
237 }
238 
getFormat(Usage usage) const239 Format ImageView::getFormat(Usage usage) const
240 {
241 	Format imageFormat = ((usage == RAW) || (getImage(usage) == image)) ? format : getImage(usage)->getFormat();
242 	return imageFormat.getAspectFormat(subresourceRange.aspectMask);
243 }
244 
rowPitchBytes(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const245 int ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
246 {
247 	return getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
248 }
249 
slicePitchBytes(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const250 int ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
251 {
252 	return getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
253 }
254 
getMipLevelSize(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const255 int ImageView::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
256 {
257 	return getImage(usage)->getMipLevelSize(aspect, subresourceRange.baseMipLevel + mipLevel);
258 }
259 
layerPitchBytes(VkImageAspectFlagBits aspect,Usage usage) const260 int ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
261 {
262 	return static_cast<int>(getImage(usage)->getLayerSize(aspect));
263 }
264 
getMipLevelExtent(uint32_t mipLevel) const265 VkExtent3D ImageView::getMipLevelExtent(uint32_t mipLevel) const
266 {
267 	return image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
268 	                                subresourceRange.baseMipLevel + mipLevel);
269 }
270 
getOffsetPointer(const VkOffset3D & offset,VkImageAspectFlagBits aspect,uint32_t mipLevel,uint32_t layer,Usage usage) const271 void *ImageView::getOffsetPointer(const VkOffset3D &offset, VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer, Usage usage) const
272 {
273 	ASSERT(mipLevel < subresourceRange.levelCount);
274 
275 	VkImageSubresourceLayers imageSubresourceLayers = {
276 		static_cast<VkImageAspectFlags>(aspect),
277 		subresourceRange.baseMipLevel + mipLevel,
278 		subresourceRange.baseArrayLayer + layer,
279 		subresourceRange.layerCount
280 	};
281 
282 	return getImage(usage)->getTexelPointer(offset, imageSubresourceLayers);
283 }
284 
285 }  // namespace vk
286