blob: d847aa72142ffbc1138954336390243c8de49ed1 [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
Chris Forbes2527b4d2019-04-24 14:32:07 -070019namespace
20{
Chris Forbes10186cb2019-05-14 18:44:52 -070021 VkComponentMapping ResolveComponentMapping(VkComponentMapping m, vk::Format format)
Chris Forbes2527b4d2019-04-24 14:32:07 -070022 {
Nicolas Capens6b63c802019-05-16 11:10:34 -040023 m = vk::ResolveIdentityMapping(m);
Chris Forbes10186cb2019-05-14 18:44:52 -070024
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,
Chris Forbes2527b4d2019-04-24 14:32:07 -070037 };
Chris Forbes10186cb2019-05-14 18:44:52 -070038
39 return {table[m.r], table[m.g], table[m.b], table[m.a]};
Chris Forbes2527b4d2019-04-24 14:32:07 -070040 }
Nicolas Capens22fbf8f2019-04-25 15:58:13 -040041
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 }
Chris Forbes2527b4d2019-04-24 14:32:07 -070052}
53
Alexis Hetu9fbaf692018-11-19 11:30:43 -050054namespace vk
55{
56
Ben Claytoneac32c42019-04-26 11:25:57 +010057std::atomic<uint32_t> ImageView::nextID(1);
58
Nicolas Capens6b63c802019-05-16 11:10:34 -040059ImageView::ImageView(const VkImageViewCreateInfo* pCreateInfo, void* mem, const vk::SamplerYcbcrConversion *ycbcrConversion) :
Alexis Hetubd4cf812019-06-14 15:14:07 -040060 image(vk::Cast(pCreateInfo->image)), viewType(pCreateInfo->viewType), format(pCreateInfo->format),
Chris Forbes10186cb2019-05-14 18:44:52 -070061 components(ResolveComponentMapping(pCreateInfo->components, format)),
Nicolas Capens6b63c802019-05-16 11:10:34 -040062 subresourceRange(ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image)),
63 ycbcrConversion(ycbcrConversion)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050064{
65}
66
67size_t ImageView::ComputeRequiredAllocationSize(const VkImageViewCreateInfo* pCreateInfo)
68{
69 return 0;
70}
71
72void ImageView::destroy(const VkAllocationCallbacks* pAllocator)
73{
74}
75
Alexis Hetued303732019-01-16 15:47:19 -050076bool ImageView::imageTypesMatch(VkImageType imageType) const
77{
Alexis Hetu911b85f2019-04-09 17:43:05 -040078 uint32_t imageArrayLayers = image->getArrayLayers();
Alexis Hetued303732019-01-16 15:47:19 -050079
Alexis Hetu911b85f2019-04-09 17:43:05 -040080 switch(viewType)
Alexis Hetued303732019-01-16 15:47:19 -050081 {
Alexis Hetu911b85f2019-04-09 17:43:05 -040082 case VK_IMAGE_VIEW_TYPE_1D:
83 return (imageType == VK_IMAGE_TYPE_1D) &&
84 (subresourceRange.layerCount == 1);
85 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
86 return imageType == VK_IMAGE_TYPE_1D;
87 case VK_IMAGE_VIEW_TYPE_2D:
88 return ((imageType == VK_IMAGE_TYPE_2D) ||
89 ((imageType == VK_IMAGE_TYPE_3D) &&
90 (imageArrayLayers == 1))) &&
91 (subresourceRange.layerCount == 1);
92 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
93 return (imageType == VK_IMAGE_TYPE_2D) ||
94 ((imageType == VK_IMAGE_TYPE_3D) &&
95 (imageArrayLayers == 1));
96 case VK_IMAGE_VIEW_TYPE_CUBE:
97 return image->isCube() &&
98 (imageArrayLayers >= subresourceRange.layerCount) &&
99 (subresourceRange.layerCount == 6);
100 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
101 return image->isCube() &&
102 (imageArrayLayers >= subresourceRange.layerCount) &&
103 (subresourceRange.layerCount >= 6);
104 case VK_IMAGE_VIEW_TYPE_3D:
105 return (imageType == VK_IMAGE_TYPE_3D) &&
106 (imageArrayLayers == 1) &&
107 (subresourceRange.layerCount == 1);
Alexis Hetued303732019-01-16 15:47:19 -0500108 default:
Alexis Hetu911b85f2019-04-09 17:43:05 -0400109 UNREACHABLE("Unexpected viewType %d", (int)viewType);
Alexis Hetued303732019-01-16 15:47:19 -0500110 }
111
112 return false;
113}
114
Alexis Hetubfdb95a2019-01-24 16:42:22 -0500115void ImageView::clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkRect2D& renderArea)
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500116{
117 // Note: clearing ignores swizzling, so components is ignored.
118
Alexis Hetued303732019-01-16 15:47:19 -0500119 if(!imageTypesMatch(image->getImageType()))
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500120 {
Ben Clayton00424c12019-03-17 17:29:30 +0000121 UNIMPLEMENTED("imageTypesMatch");
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500122 }
123
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400124 if(!format.isCompatible(image->getFormat()))
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500125 {
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400126 UNIMPLEMENTED("incompatible formats");
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500127 }
128
Chris Forbes64cf1392019-03-15 18:37:58 -0700129 VkImageSubresourceRange sr = subresourceRange;
130 sr.aspectMask = aspectMask;
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400131 image->clear(clearValue, format, renderArea, sr);
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500132}
133
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500134void ImageView::clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkClearRect& renderArea)
135{
136 // Note: clearing ignores swizzling, so components is ignored.
137
138 if(!imageTypesMatch(image->getImageType()))
139 {
Ben Clayton00424c12019-03-17 17:29:30 +0000140 UNIMPLEMENTED("imageTypesMatch");
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500141 }
142
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400143 if(!format.isCompatible(image->getFormat()))
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500144 {
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400145 UNIMPLEMENTED("incompatible formats");
Chris Forbes58228822019-04-17 12:51:29 -0700146 }
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500147
148 VkImageSubresourceRange sr;
149 sr.aspectMask = aspectMask;
150 sr.baseMipLevel = subresourceRange.baseMipLevel;
151 sr.levelCount = subresourceRange.levelCount;
152 sr.baseArrayLayer = renderArea.baseArrayLayer + subresourceRange.baseArrayLayer;
153 sr.layerCount = renderArea.layerCount;
154
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400155 image->clear(clearValue, format, renderArea.rect, sr);
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500156}
157
Chris Forbes2e5042a2019-08-23 09:03:48 -0700158void ImageView::clearWithLayerMask(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
159{
160 while (layerMask)
161 {
162 uint32_t layer = sw::log2i(layerMask);
163 layerMask &= ~(1 << layer);
164 VkClearRect r = {renderArea, layer, 1};
165 r.baseArrayLayer = layer;
166 clear(clearValue, aspectMask, r);
167 }
168}
169
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700170void ImageView::resolve(ImageView* resolveAttachment, int layer)
171{
172 if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
173 {
174 UNIMPLEMENTED("levelCount");
175 }
176
177 VkImageCopy region;
178 region.srcSubresource =
179 {
180 subresourceRange.aspectMask,
181 subresourceRange.baseMipLevel,
182 subresourceRange.baseArrayLayer + layer,
183 1
184 };
185 region.srcOffset = { 0, 0, 0 };
186 region.dstSubresource =
187 {
188 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
Alexis Hetu54ec7592019-03-20 14:37:16 -0400200void ImageView::resolve(ImageView* resolveAttachment)
201{
202 if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
203 {
204 UNIMPLEMENTED("levelCount");
205 }
206
207 VkImageCopy region;
208 region.srcSubresource =
209 {
210 subresourceRange.aspectMask,
211 subresourceRange.baseMipLevel,
212 subresourceRange.baseArrayLayer,
213 subresourceRange.layerCount
214 };
215 region.srcOffset = { 0, 0, 0 };
216 region.dstSubresource =
217 {
218 resolveAttachment->subresourceRange.aspectMask,
219 resolveAttachment->subresourceRange.baseMipLevel,
220 resolveAttachment->subresourceRange.baseArrayLayer,
221 resolveAttachment->subresourceRange.layerCount
222 };
223 region.dstOffset = { 0, 0, 0 };
Nicolas Capensba873302019-05-16 11:25:27 -0400224 region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
225 subresourceRange.baseMipLevel);
Alexis Hetu54ec7592019-03-20 14:37:16 -0400226
Alexis Hetu63ae9242019-06-06 13:52:15 -0400227 image->copyTo(resolveAttachment->image, region);
Alexis Hetu54ec7592019-03-20 14:37:16 -0400228}
229
Chris Forbes2e5042a2019-08-23 09:03:48 -0700230void ImageView::resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask)
231{
232 while (layerMask)
233 {
234 int layer = sw::log2i(layerMask);
235 layerMask &= ~(1 << layer);
236 resolve(resolveAttachment, layer);
237 }
238}
239
Alexis Hetuac873342019-04-17 15:59:03 -0400240const Image* ImageView::getImage(Usage usage) const
241{
242 switch(usage)
243 {
244 case RAW:
245 return image;
246 case SAMPLING:
Alexis Hetu62ad1ee2019-05-16 14:20:16 -0400247 return image->getSampledImage(format);
Alexis Hetuac873342019-04-17 15:59:03 -0400248 default:
249 UNIMPLEMENTED("usage %d", int(usage));
250 return nullptr;
251 }
252}
253
254Format ImageView::getFormat(Usage usage) const
255{
256 return ((usage == RAW) || (getImage(usage) == image)) ? format : getImage(usage)->getFormat();
257}
258
259int ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
260{
261 return getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
262}
263
264int ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
265{
266 return getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
267}
268
269int ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
270{
271 return static_cast<int>(getImage(usage)->getLayerSize(aspect));
272}
273
274VkExtent3D ImageView::getMipLevelExtent(uint32_t mipLevel) const
275{
Nicolas Capensba873302019-05-16 11:25:27 -0400276 return image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
277 subresourceRange.baseMipLevel + mipLevel);
Alexis Hetuac873342019-04-17 15:59:03 -0400278}
279
280void *ImageView::getOffsetPointer(const VkOffset3D& offset, VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer, Usage usage) const
Alexis Hetu6159a852019-02-26 14:42:36 -0500281{
Nicolas Capens9e735102019-04-18 15:03:06 -0400282 ASSERT(mipLevel < subresourceRange.levelCount);
283
Alexis Hetu6159a852019-02-26 14:42:36 -0500284 VkImageSubresourceLayers imageSubresourceLayers =
285 {
Alexis Hetuf955e632019-03-08 15:15:20 -0500286 static_cast<VkImageAspectFlags>(aspect),
Nicolas Capens9e735102019-04-18 15:03:06 -0400287 subresourceRange.baseMipLevel + mipLevel,
Nicolas Capensa195abb2019-04-25 17:15:56 -0400288 subresourceRange.baseArrayLayer + layer,
Alexis Hetu6159a852019-02-26 14:42:36 -0500289 subresourceRange.layerCount
290 };
Nicolas Capensba873302019-05-16 11:25:27 -0400291
Alexis Hetuac873342019-04-17 15:59:03 -0400292 return getImage(usage)->getTexelPointer(offset, imageSubresourceLayers);
Chris Forbes7c33e882019-02-21 14:58:28 -0800293}
294
Chris Forbes2995dc22019-03-02 14:57:20 -0800295}