blob: cc1d558298d2da9726f6f26b3f9f48ffbd3fc88a [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"
Chris Forbes2e5042a2019-08-23 09:03:48 -070017#include <System/Math.hpp>
Alexis Hetu9fbaf692018-11-19 11:30:43 -050018
Nicolas Capens157ba262019-12-10 17:49:14 -050019namespace {
20
21VkComponentMapping ResolveComponentMapping(VkComponentMapping m, vk::Format format)
Chris Forbes2527b4d2019-04-24 14:32:07 -070022{
Nicolas Capens157ba262019-12-10 17:49:14 -050023 m = vk::ResolveIdentityMapping(m);
Chris Forbes10186cb2019-05-14 18:44:52 -070024
Nicolas Capens157ba262019-12-10 17:49:14 -050025 // 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 };
Chris Forbes10186cb2019-05-14 18:44:52 -070038
Ben Clayton2ed93ab2019-12-17 20:38:03 +000039 return { table[m.r], table[m.g], table[m.b], table[m.a] };
Chris Forbes2527b4d2019-04-24 14:32:07 -070040}
41
Nicolas Capens157ba262019-12-10 17:49:14 -050042VkImageSubresourceRange ResolveRemainingLevelsLayers(VkImageSubresourceRange range, const vk::Image *image)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050043{
Nicolas Capens157ba262019-12-10 17:49:14 -050044 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
55namespace vk {
Alexis Hetu9fbaf692018-11-19 11:30:43 -050056
Ben Claytoneac32c42019-04-26 11:25:57 +010057std::atomic<uint32_t> ImageView::nextID(1);
58
Ben Clayton2ed93ab2019-12-17 20:38:03 +000059ImageView::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)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050066{
67}
68
Ben Clayton2ed93ab2019-12-17 20:38:03 +000069size_t ImageView::ComputeRequiredAllocationSize(const VkImageViewCreateInfo *pCreateInfo)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050070{
71 return 0;
72}
73
Ben Clayton2ed93ab2019-12-17 20:38:03 +000074void ImageView::destroy(const VkAllocationCallbacks *pAllocator)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050075{
76}
77
Alexis Hetued303732019-01-16 15:47:19 -050078bool ImageView::imageTypesMatch(VkImageType imageType) const
79{
Alexis Hetu911b85f2019-04-09 17:43:05 -040080 uint32_t imageArrayLayers = image->getArrayLayers();
Alexis Hetued303732019-01-16 15:47:19 -050081
Alexis Hetu911b85f2019-04-09 17:43:05 -040082 switch(viewType)
Alexis Hetued303732019-01-16 15:47:19 -050083 {
Ben Clayton2ed93ab2019-12-17 20:38:03 +000084 case VK_IMAGE_VIEW_TYPE_1D:
85 return (imageType == VK_IMAGE_TYPE_1D) &&
86 (subresourceRange.layerCount == 1);
87 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
88 return imageType == VK_IMAGE_TYPE_1D;
89 case VK_IMAGE_VIEW_TYPE_2D:
90 return ((imageType == VK_IMAGE_TYPE_2D) ||
91 ((imageType == VK_IMAGE_TYPE_3D) &&
92 (imageArrayLayers == 1))) &&
93 (subresourceRange.layerCount == 1);
94 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
95 return (imageType == VK_IMAGE_TYPE_2D) ||
96 ((imageType == VK_IMAGE_TYPE_3D) &&
97 (imageArrayLayers == 1));
98 case VK_IMAGE_VIEW_TYPE_CUBE:
99 return image->isCube() &&
100 (imageArrayLayers >= subresourceRange.layerCount) &&
101 (subresourceRange.layerCount == 6);
102 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
103 return image->isCube() &&
104 (imageArrayLayers >= subresourceRange.layerCount) &&
105 (subresourceRange.layerCount >= 6);
106 case VK_IMAGE_VIEW_TYPE_3D:
107 return (imageType == VK_IMAGE_TYPE_3D) &&
108 (imageArrayLayers == 1) &&
109 (subresourceRange.layerCount == 1);
110 default:
111 UNREACHABLE("Unexpected viewType %d", (int)viewType);
Alexis Hetued303732019-01-16 15:47:19 -0500112 }
113
114 return false;
115}
116
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000117void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkRect2D &renderArea)
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500118{
119 // Note: clearing ignores swizzling, so components is ignored.
120
Alexis Hetued303732019-01-16 15:47:19 -0500121 if(!imageTypesMatch(image->getImageType()))
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500122 {
Ben Clayton00424c12019-03-17 17:29:30 +0000123 UNIMPLEMENTED("imageTypesMatch");
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500124 }
125
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400126 if(!format.isCompatible(image->getFormat()))
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500127 {
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400128 UNIMPLEMENTED("incompatible formats");
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500129 }
130
Chris Forbes64cf1392019-03-15 18:37:58 -0700131 VkImageSubresourceRange sr = subresourceRange;
132 sr.aspectMask = aspectMask;
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400133 image->clear(clearValue, format, renderArea, sr);
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500134}
135
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000136void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkClearRect &renderArea)
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500137{
138 // Note: clearing ignores swizzling, so components is ignored.
139
140 if(!imageTypesMatch(image->getImageType()))
141 {
Ben Clayton00424c12019-03-17 17:29:30 +0000142 UNIMPLEMENTED("imageTypesMatch");
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500143 }
144
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400145 if(!format.isCompatible(image->getFormat()))
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500146 {
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400147 UNIMPLEMENTED("incompatible formats");
Chris Forbes58228822019-04-17 12:51:29 -0700148 }
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500149
150 VkImageSubresourceRange sr;
151 sr.aspectMask = aspectMask;
152 sr.baseMipLevel = subresourceRange.baseMipLevel;
153 sr.levelCount = subresourceRange.levelCount;
154 sr.baseArrayLayer = renderArea.baseArrayLayer + subresourceRange.baseArrayLayer;
155 sr.layerCount = renderArea.layerCount;
156
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400157 image->clear(clearValue, format, renderArea.rect, sr);
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500158}
159
Chris Forbes2e5042a2019-08-23 09:03:48 -0700160void ImageView::clearWithLayerMask(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
161{
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500162 while(layerMask)
Chris Forbes2e5042a2019-08-23 09:03:48 -0700163 {
164 uint32_t layer = sw::log2i(layerMask);
165 layerMask &= ~(1 << layer);
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000166 VkClearRect r = { renderArea, layer, 1 };
Chris Forbes2e5042a2019-08-23 09:03:48 -0700167 r.baseArrayLayer = layer;
168 clear(clearValue, aspectMask, r);
169 }
170}
171
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000172void ImageView::resolve(ImageView *resolveAttachment, int layer)
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700173{
174 if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
175 {
176 UNIMPLEMENTED("levelCount");
177 }
178
179 VkImageCopy region;
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000180 region.srcSubresource = {
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700181 subresourceRange.aspectMask,
182 subresourceRange.baseMipLevel,
183 subresourceRange.baseArrayLayer + layer,
184 1
185 };
186 region.srcOffset = { 0, 0, 0 };
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000187 region.dstSubresource = {
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700188 resolveAttachment->subresourceRange.aspectMask,
189 resolveAttachment->subresourceRange.baseMipLevel,
190 resolveAttachment->subresourceRange.baseArrayLayer + layer,
191 1
192 };
193 region.dstOffset = { 0, 0, 0 };
194 region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
195 subresourceRange.baseMipLevel);
196
197 image->copyTo(resolveAttachment->image, region);
198}
199
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000200void ImageView::resolve(ImageView *resolveAttachment)
Alexis Hetu54ec7592019-03-20 14:37:16 -0400201{
202 if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
203 {
204 UNIMPLEMENTED("levelCount");
205 }
206
207 VkImageCopy region;
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000208 region.srcSubresource = {
Alexis Hetu54ec7592019-03-20 14:37:16 -0400209 subresourceRange.aspectMask,
210 subresourceRange.baseMipLevel,
211 subresourceRange.baseArrayLayer,
212 subresourceRange.layerCount
213 };
214 region.srcOffset = { 0, 0, 0 };
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000215 region.dstSubresource = {
Alexis Hetu54ec7592019-03-20 14:37:16 -0400216 resolveAttachment->subresourceRange.aspectMask,
217 resolveAttachment->subresourceRange.baseMipLevel,
218 resolveAttachment->subresourceRange.baseArrayLayer,
219 resolveAttachment->subresourceRange.layerCount
220 };
221 region.dstOffset = { 0, 0, 0 };
Nicolas Capensba873302019-05-16 11:25:27 -0400222 region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
223 subresourceRange.baseMipLevel);
Alexis Hetu54ec7592019-03-20 14:37:16 -0400224
Alexis Hetu63ae9242019-06-06 13:52:15 -0400225 image->copyTo(resolveAttachment->image, region);
Alexis Hetu54ec7592019-03-20 14:37:16 -0400226}
227
Chris Forbes2e5042a2019-08-23 09:03:48 -0700228void ImageView::resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask)
229{
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500230 while(layerMask)
Chris Forbes2e5042a2019-08-23 09:03:48 -0700231 {
232 int layer = sw::log2i(layerMask);
233 layerMask &= ~(1 << layer);
234 resolve(resolveAttachment, layer);
235 }
236}
237
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000238const Image *ImageView::getImage(Usage usage) const
Alexis Hetuac873342019-04-17 15:59:03 -0400239{
240 switch(usage)
241 {
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000242 case RAW:
243 return image;
244 case SAMPLING:
245 return image->getSampledImage(format);
246 default:
247 UNIMPLEMENTED("usage %d", int(usage));
248 return nullptr;
Alexis Hetuac873342019-04-17 15:59:03 -0400249 }
250}
251
252Format ImageView::getFormat(Usage usage) const
253{
Alexis Hetu9c18a972019-09-17 15:41:21 -0400254 Format imageFormat = ((usage == RAW) || (getImage(usage) == image)) ? format : getImage(usage)->getFormat();
255 return imageFormat.getAspectFormat(subresourceRange.aspectMask);
Alexis Hetuac873342019-04-17 15:59:03 -0400256}
257
258int ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
259{
260 return getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
261}
262
263int ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
264{
265 return getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
266}
267
Alexis Hetu8a6dcf72019-11-26 17:24:42 -0500268int ImageView::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
269{
270 return getImage(usage)->getMipLevelSize(aspect, subresourceRange.baseMipLevel + mipLevel);
271}
272
Alexis Hetuac873342019-04-17 15:59:03 -0400273int ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
274{
275 return static_cast<int>(getImage(usage)->getLayerSize(aspect));
276}
277
278VkExtent3D ImageView::getMipLevelExtent(uint32_t mipLevel) const
279{
Nicolas Capensba873302019-05-16 11:25:27 -0400280 return image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
281 subresourceRange.baseMipLevel + mipLevel);
Alexis Hetuac873342019-04-17 15:59:03 -0400282}
283
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000284void *ImageView::getOffsetPointer(const VkOffset3D &offset, VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer, Usage usage) const
Alexis Hetu6159a852019-02-26 14:42:36 -0500285{
Nicolas Capens9e735102019-04-18 15:03:06 -0400286 ASSERT(mipLevel < subresourceRange.levelCount);
287
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000288 VkImageSubresourceLayers imageSubresourceLayers = {
Alexis Hetuf955e632019-03-08 15:15:20 -0500289 static_cast<VkImageAspectFlags>(aspect),
Nicolas Capens9e735102019-04-18 15:03:06 -0400290 subresourceRange.baseMipLevel + mipLevel,
Nicolas Capensa195abb2019-04-25 17:15:56 -0400291 subresourceRange.baseArrayLayer + layer,
Alexis Hetu6159a852019-02-26 14:42:36 -0500292 subresourceRange.layerCount
293 };
Nicolas Capensba873302019-05-16 11:25:27 -0400294
Alexis Hetuac873342019-04-17 15:59:03 -0400295 return getImage(usage)->getTexelPointer(offset, imageSubresourceLayers);
Chris Forbes7c33e882019-02-21 14:58:28 -0800296}
297
Nicolas Capens157ba262019-12-10 17:49:14 -0500298} // namespace vk