blob: e8a6cad0f50aa110a13f9007f6f8192e13c0da01 [file] [log] [blame]
Alexis Hetu911b85f2019-04-09 17:43:05 -04001// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
Alexis Hetu9fbaf692018-11-19 11:30:43 -05002//
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"
Nicolas Capens77090262020-03-19 00:26:21 -040017#include "System/Math.hpp"
18
19#include <climits>
Alexis Hetu9fbaf692018-11-19 11:30:43 -050020
Nicolas Capens157ba262019-12-10 17:49:14 -050021namespace {
22
23VkComponentMapping ResolveComponentMapping(VkComponentMapping m, vk::Format format)
Chris Forbes2527b4d2019-04-24 14:32:07 -070024{
Nicolas Capens157ba262019-12-10 17:49:14 -050025 m = vk::ResolveIdentityMapping(m);
Chris Forbes10186cb2019-05-14 18:44:52 -070026
Nicolas Capens157ba262019-12-10 17:49:14 -050027 // Replace non-present components with zero/one swizzles so that the sampler
28 // will give us correct interactions between channel replacement and texel replacement,
29 // where we've had to invent new channels behind the app's back (eg transparent decompression
30 // of ETC2 RGB -> BGRA8)
31 VkComponentSwizzle table[] = {
32 VK_COMPONENT_SWIZZLE_IDENTITY,
33 VK_COMPONENT_SWIZZLE_ZERO,
34 VK_COMPONENT_SWIZZLE_ONE,
35 VK_COMPONENT_SWIZZLE_R,
36 format.componentCount() < 2 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_G,
37 format.componentCount() < 3 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_B,
38 format.componentCount() < 4 ? VK_COMPONENT_SWIZZLE_ONE : VK_COMPONENT_SWIZZLE_A,
39 };
Chris Forbes10186cb2019-05-14 18:44:52 -070040
Ben Clayton2ed93ab2019-12-17 20:38:03 +000041 return { table[m.r], table[m.g], table[m.b], table[m.a] };
Chris Forbes2527b4d2019-04-24 14:32:07 -070042}
43
Nicolas Capens157ba262019-12-10 17:49:14 -050044VkImageSubresourceRange ResolveRemainingLevelsLayers(VkImageSubresourceRange range, const vk::Image *image)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050045{
Nicolas Capens157ba262019-12-10 17:49:14 -050046 return {
47 range.aspectMask,
48 range.baseMipLevel,
49 (range.levelCount == VK_REMAINING_MIP_LEVELS) ? (image->getMipLevels() - range.baseMipLevel) : range.levelCount,
50 range.baseArrayLayer,
51 (range.layerCount == VK_REMAINING_ARRAY_LAYERS) ? (image->getArrayLayers() - range.baseArrayLayer) : range.layerCount,
52 };
53}
54
55} // anonymous namespace
56
57namespace vk {
Alexis Hetu9fbaf692018-11-19 11:30:43 -050058
Nicolas Capens77090262020-03-19 00:26:21 -040059Identifier::Identifier(const Image *image, VkImageViewType type, VkFormat fmt, VkComponentMapping mapping)
60{
61 imageViewType = type;
62 format = Format::mapTo8bit(fmt);
63 r = mapping.r;
64 g = mapping.g;
65 b = mapping.b;
66 a = mapping.a;
Nicolas Capens77090262020-03-19 00:26:21 -040067}
68
69Identifier::Identifier(VkFormat fmt)
70{
Antonio Maiorano941293d2020-04-27 10:22:49 -040071 static_assert(vk::VK_IMAGE_VIEW_TYPE_END_RANGE == 6, "VkImageViewType does not allow using 7 to indicate buffer view");
Nicolas Capens77090262020-03-19 00:26:21 -040072 imageViewType = 7; // Still fits in 3-bit field
73 format = Format::mapTo8bit(fmt);
74}
Ben Claytoneac32c42019-04-26 11:25:57 +010075
Ben Clayton2ed93ab2019-12-17 20:38:03 +000076ImageView::ImageView(const VkImageViewCreateInfo *pCreateInfo, void *mem, const vk::SamplerYcbcrConversion *ycbcrConversion)
77 : image(vk::Cast(pCreateInfo->image))
78 , viewType(pCreateInfo->viewType)
79 , format(pCreateInfo->format)
80 , components(ResolveComponentMapping(pCreateInfo->components, format))
81 , subresourceRange(ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image))
82 , ycbcrConversion(ycbcrConversion)
Nicolas Capens9f2dd0d2020-03-26 12:00:35 -040083 , id(image, viewType, format.getAspectFormat(subresourceRange.aspectMask), components)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050084{
85}
86
Ben Clayton2ed93ab2019-12-17 20:38:03 +000087size_t ImageView::ComputeRequiredAllocationSize(const VkImageViewCreateInfo *pCreateInfo)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050088{
89 return 0;
90}
91
Ben Clayton2ed93ab2019-12-17 20:38:03 +000092void ImageView::destroy(const VkAllocationCallbacks *pAllocator)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050093{
94}
95
Nicolas Capensdd0e6002020-01-24 01:21:47 -050096// Vulkan 1.2 Table 8. Image and image view parameter compatibility requirements
Alexis Hetued303732019-01-16 15:47:19 -050097bool ImageView::imageTypesMatch(VkImageType imageType) const
98{
Alexis Hetu911b85f2019-04-09 17:43:05 -040099 uint32_t imageArrayLayers = image->getArrayLayers();
Alexis Hetued303732019-01-16 15:47:19 -0500100
Alexis Hetu911b85f2019-04-09 17:43:05 -0400101 switch(viewType)
Alexis Hetued303732019-01-16 15:47:19 -0500102 {
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000103 case VK_IMAGE_VIEW_TYPE_1D:
104 return (imageType == VK_IMAGE_TYPE_1D) &&
105 (subresourceRange.layerCount == 1);
106 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
107 return imageType == VK_IMAGE_TYPE_1D;
108 case VK_IMAGE_VIEW_TYPE_2D:
109 return ((imageType == VK_IMAGE_TYPE_2D) ||
110 ((imageType == VK_IMAGE_TYPE_3D) &&
111 (imageArrayLayers == 1))) &&
112 (subresourceRange.layerCount == 1);
113 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
114 return (imageType == VK_IMAGE_TYPE_2D) ||
115 ((imageType == VK_IMAGE_TYPE_3D) &&
116 (imageArrayLayers == 1));
117 case VK_IMAGE_VIEW_TYPE_CUBE:
118 return image->isCube() &&
119 (imageArrayLayers >= subresourceRange.layerCount) &&
120 (subresourceRange.layerCount == 6);
121 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
122 return image->isCube() &&
123 (imageArrayLayers >= subresourceRange.layerCount) &&
124 (subresourceRange.layerCount >= 6);
125 case VK_IMAGE_VIEW_TYPE_3D:
126 return (imageType == VK_IMAGE_TYPE_3D) &&
127 (imageArrayLayers == 1) &&
128 (subresourceRange.layerCount == 1);
129 default:
130 UNREACHABLE("Unexpected viewType %d", (int)viewType);
Alexis Hetued303732019-01-16 15:47:19 -0500131 }
132
133 return false;
134}
135
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000136void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkRect2D &renderArea)
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500137{
138 // Note: clearing ignores swizzling, so components is ignored.
139
Nicolas Capensdd0e6002020-01-24 01:21:47 -0500140 ASSERT(imageTypesMatch(image->getImageType()));
141 ASSERT(format.isCompatible(image->getFormat()));
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500142
Chris Forbes64cf1392019-03-15 18:37:58 -0700143 VkImageSubresourceRange sr = subresourceRange;
144 sr.aspectMask = aspectMask;
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400145 image->clear(clearValue, format, renderArea, sr);
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500146}
147
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000148void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkClearRect &renderArea)
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500149{
150 // Note: clearing ignores swizzling, so components is ignored.
151
Nicolas Capensdd0e6002020-01-24 01:21:47 -0500152 ASSERT(imageTypesMatch(image->getImageType()));
153 ASSERT(format.isCompatible(image->getFormat()));
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500154
155 VkImageSubresourceRange sr;
156 sr.aspectMask = aspectMask;
157 sr.baseMipLevel = subresourceRange.baseMipLevel;
158 sr.levelCount = subresourceRange.levelCount;
159 sr.baseArrayLayer = renderArea.baseArrayLayer + subresourceRange.baseArrayLayer;
160 sr.layerCount = renderArea.layerCount;
161
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400162 image->clear(clearValue, format, renderArea.rect, sr);
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500163}
164
Chris Forbes2e5042a2019-08-23 09:03:48 -0700165void ImageView::clearWithLayerMask(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
166{
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500167 while(layerMask)
Chris Forbes2e5042a2019-08-23 09:03:48 -0700168 {
169 uint32_t layer = sw::log2i(layerMask);
170 layerMask &= ~(1 << layer);
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000171 VkClearRect r = { renderArea, layer, 1 };
Chris Forbes2e5042a2019-08-23 09:03:48 -0700172 r.baseArrayLayer = layer;
173 clear(clearValue, aspectMask, r);
174 }
175}
176
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000177void ImageView::resolve(ImageView *resolveAttachment, int layer)
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700178{
179 if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
180 {
Nicolas Capensdd0e6002020-01-24 01:21:47 -0500181 UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443)
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700182 }
183
Nicolas Capens2aace0d2020-07-02 16:35:23 -0400184 VkImageResolve region;
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000185 region.srcSubresource = {
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700186 subresourceRange.aspectMask,
187 subresourceRange.baseMipLevel,
188 subresourceRange.baseArrayLayer + layer,
189 1
190 };
191 region.srcOffset = { 0, 0, 0 };
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000192 region.dstSubresource = {
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700193 resolveAttachment->subresourceRange.aspectMask,
194 resolveAttachment->subresourceRange.baseMipLevel,
195 resolveAttachment->subresourceRange.baseArrayLayer + layer,
196 1
197 };
198 region.dstOffset = { 0, 0, 0 };
199 region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
200 subresourceRange.baseMipLevel);
201
Nicolas Capens2aace0d2020-07-02 16:35:23 -0400202 image->resolveTo(resolveAttachment->image, region);
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700203}
204
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000205void ImageView::resolve(ImageView *resolveAttachment)
Alexis Hetu54ec7592019-03-20 14:37:16 -0400206{
207 if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
208 {
Nicolas Capensdd0e6002020-01-24 01:21:47 -0500209 UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443)
Alexis Hetu54ec7592019-03-20 14:37:16 -0400210 }
211
Nicolas Capens2aace0d2020-07-02 16:35:23 -0400212 VkImageResolve region;
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000213 region.srcSubresource = {
Alexis Hetu54ec7592019-03-20 14:37:16 -0400214 subresourceRange.aspectMask,
215 subresourceRange.baseMipLevel,
216 subresourceRange.baseArrayLayer,
217 subresourceRange.layerCount
218 };
219 region.srcOffset = { 0, 0, 0 };
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000220 region.dstSubresource = {
Alexis Hetu54ec7592019-03-20 14:37:16 -0400221 resolveAttachment->subresourceRange.aspectMask,
222 resolveAttachment->subresourceRange.baseMipLevel,
223 resolveAttachment->subresourceRange.baseArrayLayer,
224 resolveAttachment->subresourceRange.layerCount
225 };
226 region.dstOffset = { 0, 0, 0 };
Nicolas Capensba873302019-05-16 11:25:27 -0400227 region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
228 subresourceRange.baseMipLevel);
Alexis Hetu54ec7592019-03-20 14:37:16 -0400229
Nicolas Capens2aace0d2020-07-02 16:35:23 -0400230 image->resolveTo(resolveAttachment->image, region);
Alexis Hetu54ec7592019-03-20 14:37:16 -0400231}
232
Chris Forbes2e5042a2019-08-23 09:03:48 -0700233void ImageView::resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask)
234{
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500235 while(layerMask)
Chris Forbes2e5042a2019-08-23 09:03:48 -0700236 {
237 int layer = sw::log2i(layerMask);
238 layerMask &= ~(1 << layer);
239 resolve(resolveAttachment, layer);
240 }
241}
242
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000243const Image *ImageView::getImage(Usage usage) const
Alexis Hetuac873342019-04-17 15:59:03 -0400244{
245 switch(usage)
246 {
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000247 case RAW:
248 return image;
249 case SAMPLING:
250 return image->getSampledImage(format);
251 default:
Nicolas Capens44bd43a2020-01-22 03:07:14 -0500252 UNREACHABLE("usage %d", int(usage));
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000253 return nullptr;
Alexis Hetuac873342019-04-17 15:59:03 -0400254 }
255}
256
257Format ImageView::getFormat(Usage usage) const
258{
Alexis Hetu9c18a972019-09-17 15:41:21 -0400259 Format imageFormat = ((usage == RAW) || (getImage(usage) == image)) ? format : getImage(usage)->getFormat();
260 return imageFormat.getAspectFormat(subresourceRange.aspectMask);
Alexis Hetuac873342019-04-17 15:59:03 -0400261}
262
263int ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
264{
265 return getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
266}
267
268int ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
269{
270 return getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
271}
272
Alexis Hetu8a6dcf72019-11-26 17:24:42 -0500273int ImageView::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
274{
275 return getImage(usage)->getMipLevelSize(aspect, subresourceRange.baseMipLevel + mipLevel);
276}
277
Alexis Hetuac873342019-04-17 15:59:03 -0400278int ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
279{
280 return static_cast<int>(getImage(usage)->getLayerSize(aspect));
281}
282
283VkExtent3D ImageView::getMipLevelExtent(uint32_t mipLevel) const
284{
Nicolas Capensba873302019-05-16 11:25:27 -0400285 return image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
286 subresourceRange.baseMipLevel + mipLevel);
Alexis Hetuac873342019-04-17 15:59:03 -0400287}
288
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000289void *ImageView::getOffsetPointer(const VkOffset3D &offset, VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer, Usage usage) const
Alexis Hetu6159a852019-02-26 14:42:36 -0500290{
Nicolas Capens9e735102019-04-18 15:03:06 -0400291 ASSERT(mipLevel < subresourceRange.levelCount);
292
Alexis Hetu46159712020-06-15 16:13:51 -0400293 VkImageSubresource imageSubresource = {
Alexis Hetuf955e632019-03-08 15:15:20 -0500294 static_cast<VkImageAspectFlags>(aspect),
Nicolas Capens9e735102019-04-18 15:03:06 -0400295 subresourceRange.baseMipLevel + mipLevel,
Nicolas Capensa195abb2019-04-25 17:15:56 -0400296 subresourceRange.baseArrayLayer + layer,
Alexis Hetu6159a852019-02-26 14:42:36 -0500297 };
Nicolas Capensba873302019-05-16 11:25:27 -0400298
Alexis Hetu46159712020-06-15 16:13:51 -0400299 return getImage(usage)->getTexelPointer(offset, imageSubresource);
Chris Forbes7c33e882019-02-21 14:58:28 -0800300}
301
Nicolas Capens157ba262019-12-10 17:49:14 -0500302} // namespace vk