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), subresource.levelCount <= 1u });
93 }
94
Identifier(VkFormat bufferFormat)95 Identifier::Identifier(VkFormat bufferFormat)
96 {
97 constexpr VkComponentMapping identityMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
98 pack({ VK_IMAGE_VIEW_TYPE_1D, bufferFormat, ResolveComponentMapping(identityMapping, bufferFormat), true });
99 }
100
pack(const State & state)101 void Identifier::pack(const State &state)
102 {
103 imageViewType = static_cast<uint32_t>(state.imageViewType);
104 format = Format::mapTo8bit(state.format);
105 r = static_cast<uint32_t>(state.mapping.r);
106 g = static_cast<uint32_t>(state.mapping.g);
107 b = static_cast<uint32_t>(state.mapping.b);
108 a = static_cast<uint32_t>(state.mapping.a);
109 singleMipLevel = state.singleMipLevel;
110 }
111
getState() const112 Identifier::State Identifier::getState() const
113 {
114 return { static_cast<VkImageViewType>(imageViewType),
115 Format::mapFrom8bit(static_cast<uint8_t>(format)),
116 { static_cast<VkComponentSwizzle>(r),
117 static_cast<VkComponentSwizzle>(g),
118 static_cast<VkComponentSwizzle>(b),
119 static_cast<VkComponentSwizzle>(a) },
120 static_cast<bool>(singleMipLevel) };
121 }
122
ImageView(const VkImageViewCreateInfo * pCreateInfo,void * mem,const vk::SamplerYcbcrConversion * ycbcrConversion)123 ImageView::ImageView(const VkImageViewCreateInfo *pCreateInfo, void *mem, const vk::SamplerYcbcrConversion *ycbcrConversion)
124 : image(vk::Cast(pCreateInfo->image))
125 , viewType(pCreateInfo->viewType)
126 , format(GetImageViewFormat(pCreateInfo))
127 , components(ResolveComponentMapping(pCreateInfo->components, format))
128 , subresourceRange(ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image))
129 , ycbcrConversion(ycbcrConversion)
130 , id(pCreateInfo)
131 {
132 }
133
ComputeRequiredAllocationSize(const VkImageViewCreateInfo * pCreateInfo)134 size_t ImageView::ComputeRequiredAllocationSize(const VkImageViewCreateInfo *pCreateInfo)
135 {
136 return 0;
137 }
138
destroy(const VkAllocationCallbacks * pAllocator)139 void ImageView::destroy(const VkAllocationCallbacks *pAllocator)
140 {
141 }
142
143 // Vulkan 1.2 Table 8. Image and image view parameter compatibility requirements
imageTypesMatch(VkImageType imageType) const144 bool ImageView::imageTypesMatch(VkImageType imageType) const
145 {
146 uint32_t imageArrayLayers = image->getArrayLayers();
147
148 switch(viewType)
149 {
150 case VK_IMAGE_VIEW_TYPE_1D:
151 return (imageType == VK_IMAGE_TYPE_1D) &&
152 (subresourceRange.layerCount == 1);
153 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
154 return imageType == VK_IMAGE_TYPE_1D;
155 case VK_IMAGE_VIEW_TYPE_2D:
156 return ((imageType == VK_IMAGE_TYPE_2D) ||
157 ((imageType == VK_IMAGE_TYPE_3D) &&
158 (imageArrayLayers == 1))) &&
159 (subresourceRange.layerCount == 1);
160 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
161 return (imageType == VK_IMAGE_TYPE_2D) ||
162 ((imageType == VK_IMAGE_TYPE_3D) &&
163 (imageArrayLayers == 1));
164 case VK_IMAGE_VIEW_TYPE_CUBE:
165 return image->isCubeCompatible() &&
166 (imageArrayLayers >= subresourceRange.layerCount) &&
167 (subresourceRange.layerCount == 6);
168 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
169 return image->isCubeCompatible() &&
170 (imageArrayLayers >= subresourceRange.layerCount) &&
171 (subresourceRange.layerCount >= 6);
172 case VK_IMAGE_VIEW_TYPE_3D:
173 return (imageType == VK_IMAGE_TYPE_3D) &&
174 (imageArrayLayers == 1) &&
175 (subresourceRange.layerCount == 1);
176 default:
177 UNREACHABLE("Unexpected viewType %d", (int)viewType);
178 }
179
180 return false;
181 }
182
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkRect2D & renderArea)183 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkRect2D &renderArea)
184 {
185 // Note: clearing ignores swizzling, so components is ignored.
186
187 ASSERT(imageTypesMatch(image->getImageType()));
188 ASSERT(format.isCompatible(image->getFormat()));
189
190 VkImageSubresourceRange sr = subresourceRange;
191 sr.aspectMask = aspectMask;
192 image->clear(clearValue, format, renderArea, sr);
193 }
194
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkClearRect & renderArea)195 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkClearRect &renderArea)
196 {
197 // Note: clearing ignores swizzling, so components is ignored.
198
199 ASSERT(imageTypesMatch(image->getImageType()));
200 ASSERT(format.isCompatible(image->getFormat()));
201
202 VkImageSubresourceRange sr;
203 sr.aspectMask = aspectMask;
204 sr.baseMipLevel = subresourceRange.baseMipLevel;
205 sr.levelCount = subresourceRange.levelCount;
206 sr.baseArrayLayer = renderArea.baseArrayLayer + subresourceRange.baseArrayLayer;
207 sr.layerCount = renderArea.layerCount;
208
209 image->clear(clearValue, format, renderArea.rect, sr);
210 }
211
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkRect2D & renderArea,uint32_t layerMask)212 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
213 {
214 if(layerMask == 0)
215 {
216 clear(clearValue, aspectMask, renderArea);
217 }
218 else
219 {
220 clearWithLayerMask(clearValue, aspectMask, renderArea, layerMask);
221 }
222 }
223
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkClearRect & renderArea,uint32_t layerMask)224 void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkClearRect &renderArea, uint32_t layerMask)
225 {
226 if(layerMask == 0)
227 {
228 clear(clearValue, aspectMask, renderArea);
229 }
230 else
231 {
232 clearWithLayerMask(clearValue, aspectMask, renderArea.rect, layerMask);
233 }
234 }
235
clearWithLayerMask(const VkClearValue & clearValue,VkImageAspectFlags aspectMask,const VkRect2D & renderArea,uint32_t layerMask)236 void ImageView::clearWithLayerMask(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
237 {
238 while(layerMask)
239 {
240 uint32_t layer = sw::log2i(layerMask);
241 layerMask &= ~(1 << layer);
242 VkClearRect r = { renderArea, layer, 1 };
243 r.baseArrayLayer = layer;
244 clear(clearValue, aspectMask, r);
245 }
246 }
247
resolveSingleLayer(ImageView * resolveAttachment,int layer)248 void ImageView::resolveSingleLayer(ImageView *resolveAttachment, int layer)
249 {
250 if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
251 {
252 UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443)
253 }
254
255 VkImageResolve2KHR region;
256 region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR;
257 region.pNext = nullptr;
258 region.srcSubresource = {
259 subresourceRange.aspectMask,
260 subresourceRange.baseMipLevel,
261 subresourceRange.baseArrayLayer + layer,
262 1
263 };
264 region.srcOffset = { 0, 0, 0 };
265 region.dstSubresource = {
266 resolveAttachment->subresourceRange.aspectMask,
267 resolveAttachment->subresourceRange.baseMipLevel,
268 resolveAttachment->subresourceRange.baseArrayLayer + layer,
269 1
270 };
271 region.dstOffset = { 0, 0, 0 };
272 region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
273 subresourceRange.baseMipLevel);
274
275 image->resolveTo(resolveAttachment->image, region);
276 }
277
resolve(ImageView * resolveAttachment)278 void ImageView::resolve(ImageView *resolveAttachment)
279 {
280 if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
281 {
282 UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443)
283 }
284
285 VkImageResolve2KHR region;
286 region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR;
287 region.pNext = nullptr;
288 region.srcSubresource = {
289 subresourceRange.aspectMask,
290 subresourceRange.baseMipLevel,
291 subresourceRange.baseArrayLayer,
292 subresourceRange.layerCount
293 };
294 region.srcOffset = { 0, 0, 0 };
295 region.dstSubresource = {
296 resolveAttachment->subresourceRange.aspectMask,
297 resolveAttachment->subresourceRange.baseMipLevel,
298 resolveAttachment->subresourceRange.baseArrayLayer,
299 resolveAttachment->subresourceRange.layerCount
300 };
301 region.dstOffset = { 0, 0, 0 };
302 region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
303 subresourceRange.baseMipLevel);
304
305 image->resolveTo(resolveAttachment->image, region);
306 }
307
resolve(ImageView * resolveAttachment,uint32_t layerMask)308 void ImageView::resolve(ImageView *resolveAttachment, uint32_t layerMask)
309 {
310 if(layerMask == 0)
311 {
312 resolve(resolveAttachment);
313 }
314 else
315 {
316 resolveWithLayerMask(resolveAttachment, layerMask);
317 }
318 }
319
resolveWithLayerMask(ImageView * resolveAttachment,uint32_t layerMask)320 void ImageView::resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask)
321 {
322 while(layerMask)
323 {
324 int layer = sw::log2i(layerMask);
325 layerMask &= ~(1 << layer);
326 resolveSingleLayer(resolveAttachment, layer);
327 }
328 }
329
resolveDepthStencil(ImageView * resolveAttachment,VkResolveModeFlagBits depthResolveMode,VkResolveModeFlagBits stencilResolveMode)330 void ImageView::resolveDepthStencil(ImageView *resolveAttachment, VkResolveModeFlagBits depthResolveMode, VkResolveModeFlagBits stencilResolveMode)
331 {
332 ASSERT(subresourceRange.levelCount == 1 && resolveAttachment->subresourceRange.levelCount == 1);
333 if((subresourceRange.layerCount != 1) || (resolveAttachment->subresourceRange.layerCount != 1))
334 {
335 UNIMPLEMENTED("b/148242443: layerCount != 1"); // FIXME(b/148242443)
336 }
337
338 image->resolveDepthStencilTo(this, resolveAttachment, depthResolveMode, stencilResolveMode);
339 }
340
getImage(Usage usage) const341 const Image *ImageView::getImage(Usage usage) const
342 {
343 switch(usage)
344 {
345 case RAW:
346 return image;
347 case SAMPLING:
348 return image->getSampledImage(format);
349 default:
350 UNREACHABLE("usage %d", int(usage));
351 return nullptr;
352 }
353 }
354
getFormat(Usage usage) const355 Format ImageView::getFormat(Usage usage) const
356 {
357 Format imageFormat = ((usage == RAW) || (getImage(usage) == image)) ? format : getImage(usage)->getFormat();
358 return imageFormat.getAspectFormat(subresourceRange.aspectMask);
359 }
360
rowPitchBytes(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const361 uint32_t ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
362 {
363 return sw::assert_cast<uint32_t>(getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel));
364 }
365
slicePitchBytes(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const366 uint32_t ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
367 {
368 return sw::assert_cast<uint32_t>(getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel));
369 }
370
getMipLevelSize(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const371 uint32_t ImageView::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
372 {
373 return sw::assert_cast<uint32_t>(getImage(usage)->getMipLevelSize(aspect, subresourceRange.baseMipLevel + mipLevel));
374 }
375
layerPitchBytes(VkImageAspectFlagBits aspect,Usage usage) const376 uint32_t ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
377 {
378 return sw::assert_cast<uint32_t>(getImage(usage)->getLayerSize(aspect));
379 }
380
getMipLevelExtent(uint32_t mipLevel) const381 VkExtent2D ImageView::getMipLevelExtent(uint32_t mipLevel) const
382 {
383 return Extent2D(image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
384 subresourceRange.baseMipLevel + mipLevel));
385 }
386
getMipLevelExtent(uint32_t mipLevel,VkImageAspectFlagBits aspect) const387 VkExtent2D ImageView::getMipLevelExtent(uint32_t mipLevel, VkImageAspectFlagBits aspect) const
388 {
389 return Extent2D(image->getMipLevelExtent(aspect, subresourceRange.baseMipLevel + mipLevel));
390 }
391
getDepthOrLayerCount(uint32_t mipLevel) const392 uint32_t ImageView::getDepthOrLayerCount(uint32_t mipLevel) const
393 {
394 VkExtent3D extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
395 subresourceRange.baseMipLevel + mipLevel);
396 uint32_t layers = subresourceRange.layerCount;
397 uint32_t depthOrLayers = layers > 1 ? layers : extent.depth;
398
399 // For cube images the number of whole cubes is returned
400 if(viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
401 viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
402 {
403 depthOrLayers /= 6;
404 }
405
406 return depthOrLayers;
407 }
408
getOffsetPointer(const VkOffset3D & offset,VkImageAspectFlagBits aspect,uint32_t mipLevel,uint32_t layer,Usage usage) const409 void *ImageView::getOffsetPointer(const VkOffset3D &offset, VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer, Usage usage) const
410 {
411 ASSERT(mipLevel < subresourceRange.levelCount);
412
413 VkImageSubresource imageSubresource = {
414 static_cast<VkImageAspectFlags>(aspect),
415 subresourceRange.baseMipLevel + mipLevel,
416 subresourceRange.baseArrayLayer + layer,
417 };
418
419 return getImage(usage)->getTexelPointer(offset, imageSubresource);
420 }
421
422 } // namespace vk
423