blob: c8e1f654c233a723063e22b8516414cf69a2733f [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"
17
Chris Forbes2527b4d2019-04-24 14:32:07 -070018namespace
19{
Chris Forbes10186cb2019-05-14 18:44:52 -070020 VkComponentMapping ResolveComponentMapping(VkComponentMapping m, vk::Format format)
Chris Forbes2527b4d2019-04-24 14:32:07 -070021 {
Nicolas Capens6b63c802019-05-16 11:10:34 -040022 m = vk::ResolveIdentityMapping(m);
Chris Forbes10186cb2019-05-14 18:44:52 -070023
24 // Replace non-present components with zero/one swizzles so that the sampler
25 // will give us correct interactions between channel replacement and texel replacement,
26 // where we've had to invent new channels behind the app's back (eg transparent decompression
27 // of ETC2 RGB -> BGRA8)
28 VkComponentSwizzle table[] = {
29 VK_COMPONENT_SWIZZLE_IDENTITY,
30 VK_COMPONENT_SWIZZLE_ZERO,
31 VK_COMPONENT_SWIZZLE_ONE,
32 VK_COMPONENT_SWIZZLE_R,
33 format.componentCount() < 2 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_G,
34 format.componentCount() < 3 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_B,
35 format.componentCount() < 4 ? VK_COMPONENT_SWIZZLE_ONE : VK_COMPONENT_SWIZZLE_A,
Chris Forbes2527b4d2019-04-24 14:32:07 -070036 };
Chris Forbes10186cb2019-05-14 18:44:52 -070037
38 return {table[m.r], table[m.g], table[m.b], table[m.a]};
Chris Forbes2527b4d2019-04-24 14:32:07 -070039 }
Nicolas Capens22fbf8f2019-04-25 15:58:13 -040040
41 VkImageSubresourceRange ResolveRemainingLevelsLayers(VkImageSubresourceRange range, const vk::Image *image)
42 {
43 return {
44 range.aspectMask,
45 range.baseMipLevel,
46 (range.levelCount == VK_REMAINING_MIP_LEVELS) ? (image->getMipLevels() - range.baseMipLevel) : range.levelCount,
47 range.baseArrayLayer,
48 (range.layerCount == VK_REMAINING_ARRAY_LAYERS) ? (image->getArrayLayers() - range.baseArrayLayer) : range.layerCount,
49 };
50 }
Chris Forbes2527b4d2019-04-24 14:32:07 -070051}
52
Alexis Hetu9fbaf692018-11-19 11:30:43 -050053namespace vk
54{
55
Ben Claytoneac32c42019-04-26 11:25:57 +010056std::atomic<uint32_t> ImageView::nextID(1);
57
Nicolas Capens6b63c802019-05-16 11:10:34 -040058ImageView::ImageView(const VkImageViewCreateInfo* pCreateInfo, void* mem, const vk::SamplerYcbcrConversion *ycbcrConversion) :
Alexis Hetued303732019-01-16 15:47:19 -050059 image(Cast(pCreateInfo->image)), viewType(pCreateInfo->viewType), format(pCreateInfo->format),
Chris Forbes10186cb2019-05-14 18:44:52 -070060 components(ResolveComponentMapping(pCreateInfo->components, format)),
Nicolas Capens6b63c802019-05-16 11:10:34 -040061 subresourceRange(ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image)),
62 ycbcrConversion(ycbcrConversion)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050063{
64}
65
66size_t ImageView::ComputeRequiredAllocationSize(const VkImageViewCreateInfo* pCreateInfo)
67{
68 return 0;
69}
70
71void ImageView::destroy(const VkAllocationCallbacks* pAllocator)
72{
73}
74
Alexis Hetued303732019-01-16 15:47:19 -050075bool ImageView::imageTypesMatch(VkImageType imageType) const
76{
Alexis Hetu911b85f2019-04-09 17:43:05 -040077 uint32_t imageArrayLayers = image->getArrayLayers();
Alexis Hetued303732019-01-16 15:47:19 -050078
Alexis Hetu911b85f2019-04-09 17:43:05 -040079 switch(viewType)
Alexis Hetued303732019-01-16 15:47:19 -050080 {
Alexis Hetu911b85f2019-04-09 17:43:05 -040081 case VK_IMAGE_VIEW_TYPE_1D:
82 return (imageType == VK_IMAGE_TYPE_1D) &&
83 (subresourceRange.layerCount == 1);
84 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
85 return imageType == VK_IMAGE_TYPE_1D;
86 case VK_IMAGE_VIEW_TYPE_2D:
87 return ((imageType == VK_IMAGE_TYPE_2D) ||
88 ((imageType == VK_IMAGE_TYPE_3D) &&
89 (imageArrayLayers == 1))) &&
90 (subresourceRange.layerCount == 1);
91 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
92 return (imageType == VK_IMAGE_TYPE_2D) ||
93 ((imageType == VK_IMAGE_TYPE_3D) &&
94 (imageArrayLayers == 1));
95 case VK_IMAGE_VIEW_TYPE_CUBE:
96 return image->isCube() &&
97 (imageArrayLayers >= subresourceRange.layerCount) &&
98 (subresourceRange.layerCount == 6);
99 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
100 return image->isCube() &&
101 (imageArrayLayers >= subresourceRange.layerCount) &&
102 (subresourceRange.layerCount >= 6);
103 case VK_IMAGE_VIEW_TYPE_3D:
104 return (imageType == VK_IMAGE_TYPE_3D) &&
105 (imageArrayLayers == 1) &&
106 (subresourceRange.layerCount == 1);
Alexis Hetued303732019-01-16 15:47:19 -0500107 default:
Alexis Hetu911b85f2019-04-09 17:43:05 -0400108 UNREACHABLE("Unexpected viewType %d", (int)viewType);
Alexis Hetued303732019-01-16 15:47:19 -0500109 }
110
111 return false;
112}
113
Alexis Hetubfdb95a2019-01-24 16:42:22 -0500114void ImageView::clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkRect2D& renderArea)
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500115{
116 // Note: clearing ignores swizzling, so components is ignored.
117
Alexis Hetued303732019-01-16 15:47:19 -0500118 if(!imageTypesMatch(image->getImageType()))
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500119 {
Ben Clayton00424c12019-03-17 17:29:30 +0000120 UNIMPLEMENTED("imageTypesMatch");
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500121 }
122
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400123 if(!format.isCompatible(image->getFormat()))
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500124 {
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400125 UNIMPLEMENTED("incompatible formats");
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500126 }
127
Chris Forbes64cf1392019-03-15 18:37:58 -0700128 VkImageSubresourceRange sr = subresourceRange;
129 sr.aspectMask = aspectMask;
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400130 image->clear(clearValue, format, renderArea, sr);
Alexis Hetu9fbaf692018-11-19 11:30:43 -0500131}
132
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500133void ImageView::clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkClearRect& renderArea)
134{
135 // Note: clearing ignores swizzling, so components is ignored.
136
137 if(!imageTypesMatch(image->getImageType()))
138 {
Ben Clayton00424c12019-03-17 17:29:30 +0000139 UNIMPLEMENTED("imageTypesMatch");
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500140 }
141
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400142 if(!format.isCompatible(image->getFormat()))
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500143 {
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400144 UNIMPLEMENTED("incompatible formats");
Chris Forbes58228822019-04-17 12:51:29 -0700145 }
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500146
147 VkImageSubresourceRange sr;
148 sr.aspectMask = aspectMask;
149 sr.baseMipLevel = subresourceRange.baseMipLevel;
150 sr.levelCount = subresourceRange.levelCount;
151 sr.baseArrayLayer = renderArea.baseArrayLayer + subresourceRange.baseArrayLayer;
152 sr.layerCount = renderArea.layerCount;
153
Alexis Hetu04dae5e2019-04-08 13:41:50 -0400154 image->clear(clearValue, format, renderArea.rect, sr);
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500155}
156
Alexis Hetu54ec7592019-03-20 14:37:16 -0400157void ImageView::resolve(ImageView* resolveAttachment)
158{
159 if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
160 {
161 UNIMPLEMENTED("levelCount");
162 }
163
164 VkImageCopy region;
165 region.srcSubresource =
166 {
167 subresourceRange.aspectMask,
168 subresourceRange.baseMipLevel,
169 subresourceRange.baseArrayLayer,
170 subresourceRange.layerCount
171 };
172 region.srcOffset = { 0, 0, 0 };
173 region.dstSubresource =
174 {
175 resolveAttachment->subresourceRange.aspectMask,
176 resolveAttachment->subresourceRange.baseMipLevel,
177 resolveAttachment->subresourceRange.baseArrayLayer,
178 resolveAttachment->subresourceRange.layerCount
179 };
180 region.dstOffset = { 0, 0, 0 };
Nicolas Capensba873302019-05-16 11:25:27 -0400181 region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
182 subresourceRange.baseMipLevel);
Alexis Hetu54ec7592019-03-20 14:37:16 -0400183
184 image->copyTo(*(resolveAttachment->image), region);
185}
186
Alexis Hetuac873342019-04-17 15:59:03 -0400187const Image* ImageView::getImage(Usage usage) const
188{
189 switch(usage)
190 {
191 case RAW:
192 return image;
193 case SAMPLING:
Alexis Hetu62ad1ee2019-05-16 14:20:16 -0400194 return image->getSampledImage(format);
Alexis Hetuac873342019-04-17 15:59:03 -0400195 default:
196 UNIMPLEMENTED("usage %d", int(usage));
197 return nullptr;
198 }
199}
200
201Format ImageView::getFormat(Usage usage) const
202{
203 return ((usage == RAW) || (getImage(usage) == image)) ? format : getImage(usage)->getFormat();
204}
205
206int ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
207{
208 return getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
209}
210
211int ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
212{
213 return getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
214}
215
216int ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
217{
218 return static_cast<int>(getImage(usage)->getLayerSize(aspect));
219}
220
221VkExtent3D ImageView::getMipLevelExtent(uint32_t mipLevel) const
222{
Nicolas Capensba873302019-05-16 11:25:27 -0400223 return image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
224 subresourceRange.baseMipLevel + mipLevel);
Alexis Hetuac873342019-04-17 15:59:03 -0400225}
226
227void *ImageView::getOffsetPointer(const VkOffset3D& offset, VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer, Usage usage) const
Alexis Hetu6159a852019-02-26 14:42:36 -0500228{
Nicolas Capens9e735102019-04-18 15:03:06 -0400229 ASSERT(mipLevel < subresourceRange.levelCount);
230
Alexis Hetu6159a852019-02-26 14:42:36 -0500231 VkImageSubresourceLayers imageSubresourceLayers =
232 {
Alexis Hetuf955e632019-03-08 15:15:20 -0500233 static_cast<VkImageAspectFlags>(aspect),
Nicolas Capens9e735102019-04-18 15:03:06 -0400234 subresourceRange.baseMipLevel + mipLevel,
Nicolas Capensa195abb2019-04-25 17:15:56 -0400235 subresourceRange.baseArrayLayer + layer,
Alexis Hetu6159a852019-02-26 14:42:36 -0500236 subresourceRange.layerCount
237 };
Nicolas Capensba873302019-05-16 11:25:27 -0400238
Alexis Hetuac873342019-04-17 15:59:03 -0400239 return getImage(usage)->getTexelPointer(offset, imageSubresourceLayers);
Chris Forbes7c33e882019-02-21 14:58:28 -0800240}
241
Chris Forbes2995dc22019-03-02 14:57:20 -0800242}