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