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#include "VkImage.hpp"
17#include <System/Math.hpp>
18
19namespace
20{
21 VkComponentMapping ResolveComponentMapping(VkComponentMapping m, vk::Format format)
22 {
23 m = vk::ResolveIdentityMapping(m);
24
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,
37 };
38
39 return {table[m.r], table[m.g], table[m.b], table[m.a]};
40 }
41
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 }
52}
53
54namespace vk
55{
56
57std::atomic<uint32_t> ImageView::nextID(1);
58
59ImageView::ImageView(const VkImageViewCreateInfo* pCreateInfo, void* mem, const vk::SamplerYcbcrConversion *ycbcrConversion) :
60 image(vk::Cast(pCreateInfo->image)), viewType(pCreateInfo->viewType), format(pCreateInfo->format),
61 components(ResolveComponentMapping(pCreateInfo->components, format)),
62 subresourceRange(ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image)),
63 ycbcrConversion(ycbcrConversion)
64{
65}
66
67size_t ImageView::ComputeRequiredAllocationSize(const VkImageViewCreateInfo* pCreateInfo)
68{
69 return 0;
70}
71
72void ImageView::destroy(const VkAllocationCallbacks* pAllocator)
73{
74}
75
76bool ImageView::imageTypesMatch(VkImageType imageType) const
77{
78 uint32_t imageArrayLayers = image->getArrayLayers();
79
80 switch(viewType)
81 {
82 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);
108 default:
109 UNREACHABLE("Unexpected viewType %d", (int)viewType);
110 }
111
112 return false;
113}
114
115void ImageView::clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkRect2D& renderArea)
116{
117 // Note: clearing ignores swizzling, so components is ignored.
118
119 if(!imageTypesMatch(image->getImageType()))
120 {
121 UNIMPLEMENTED("imageTypesMatch");
122 }
123
124 if(!format.isCompatible(image->getFormat()))
125 {
126 UNIMPLEMENTED("incompatible formats");
127 }
128
129 VkImageSubresourceRange sr = subresourceRange;
130 sr.aspectMask = aspectMask;
131 image->clear(clearValue, format, renderArea, sr);
132}
133
134void 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 {
140 UNIMPLEMENTED("imageTypesMatch");
141 }
142
143 if(!format.isCompatible(image->getFormat()))
144 {
145 UNIMPLEMENTED("incompatible formats");
146 }
147
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
155 image->clear(clearValue, format, renderArea.rect, sr);
156}
157
158void 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
170void 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
200void 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 };
224 region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
225 subresourceRange.baseMipLevel);
226
227 image->copyTo(resolveAttachment->image, region);
228}
229
230void 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
240const Image* ImageView::getImage(Usage usage) const
241{
242 switch(usage)
243 {
244 case RAW:
245 return image;
246 case SAMPLING:
247 return image->getSampledImage(format);
248 default:
249 UNIMPLEMENTED("usage %d", int(usage));
250 return nullptr;
251 }
252}
253
254Format ImageView::getFormat(Usage usage) const
255{
256 Format imageFormat = ((usage == RAW) || (getImage(usage) == image)) ? format : getImage(usage)->getFormat();
257 return imageFormat.getAspectFormat(subresourceRange.aspectMask);
258}
259
260int ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
261{
262 return getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
263}
264
265int ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
266{
267 return getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
268}
269
270int ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
271{
272 return static_cast<int>(getImage(usage)->getLayerSize(aspect));
273}
274
275VkExtent3D ImageView::getMipLevelExtent(uint32_t mipLevel) const
276{
277 return image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
278 subresourceRange.baseMipLevel + mipLevel);
279}
280
281void *ImageView::getOffsetPointer(const VkOffset3D& offset, VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer, Usage usage) const
282{
283 ASSERT(mipLevel < subresourceRange.levelCount);
284
285 VkImageSubresourceLayers imageSubresourceLayers =
286 {
287 static_cast<VkImageAspectFlags>(aspect),
288 subresourceRange.baseMipLevel + mipLevel,
289 subresourceRange.baseArrayLayer + layer,
290 subresourceRange.layerCount
291 };
292
293 return getImage(usage)->getTexelPointer(offset, imageSubresourceLayers);
294}
295
296}
297