1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker
15*03ce13f7SAndroid Build Coastguard Worker #include "VkImageView.hpp"
16*03ce13f7SAndroid Build Coastguard Worker
17*03ce13f7SAndroid Build Coastguard Worker #include "VkImage.hpp"
18*03ce13f7SAndroid Build Coastguard Worker #include "VkStructConversion.hpp"
19*03ce13f7SAndroid Build Coastguard Worker #include "System/Math.hpp"
20*03ce13f7SAndroid Build Coastguard Worker #include "System/Types.hpp"
21*03ce13f7SAndroid Build Coastguard Worker
22*03ce13f7SAndroid Build Coastguard Worker #include <climits>
23*03ce13f7SAndroid Build Coastguard Worker
24*03ce13f7SAndroid Build Coastguard Worker namespace vk {
25*03ce13f7SAndroid Build Coastguard Worker namespace {
26*03ce13f7SAndroid Build Coastguard Worker
GetImageViewFormat(const VkImageViewCreateInfo * pCreateInfo)27*03ce13f7SAndroid Build Coastguard Worker Format GetImageViewFormat(const VkImageViewCreateInfo *pCreateInfo)
28*03ce13f7SAndroid Build Coastguard Worker {
29*03ce13f7SAndroid Build Coastguard Worker // VkImageViewCreateInfo: "If image has an external format, format must be VK_FORMAT_UNDEFINED"
30*03ce13f7SAndroid Build Coastguard Worker // In that case, obtain the format from the underlying image.
31*03ce13f7SAndroid Build Coastguard Worker if(pCreateInfo->format != VK_FORMAT_UNDEFINED)
32*03ce13f7SAndroid Build Coastguard Worker {
33*03ce13f7SAndroid Build Coastguard Worker return Format(pCreateInfo->format);
34*03ce13f7SAndroid Build Coastguard Worker }
35*03ce13f7SAndroid Build Coastguard Worker
36*03ce13f7SAndroid Build Coastguard Worker return vk::Cast(pCreateInfo->image)->getFormat();
37*03ce13f7SAndroid Build Coastguard Worker }
38*03ce13f7SAndroid Build Coastguard Worker
39*03ce13f7SAndroid Build Coastguard Worker } // anonymous namespace
40*03ce13f7SAndroid Build Coastguard Worker
ResolveIdentityMapping(VkComponentMapping mapping)41*03ce13f7SAndroid Build Coastguard Worker VkComponentMapping ResolveIdentityMapping(VkComponentMapping mapping)
42*03ce13f7SAndroid Build Coastguard Worker {
43*03ce13f7SAndroid Build Coastguard Worker return {
44*03ce13f7SAndroid Build Coastguard Worker (mapping.r == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_R : mapping.r,
45*03ce13f7SAndroid Build Coastguard Worker (mapping.g == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_G : mapping.g,
46*03ce13f7SAndroid Build Coastguard Worker (mapping.b == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_B : mapping.b,
47*03ce13f7SAndroid Build Coastguard Worker (mapping.a == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_A : mapping.a,
48*03ce13f7SAndroid Build Coastguard Worker };
49*03ce13f7SAndroid Build Coastguard Worker }
50*03ce13f7SAndroid Build Coastguard Worker
ResolveComponentMapping(VkComponentMapping mapping,vk::Format format)51*03ce13f7SAndroid Build Coastguard Worker VkComponentMapping ResolveComponentMapping(VkComponentMapping mapping, vk::Format format)
52*03ce13f7SAndroid Build Coastguard Worker {
53*03ce13f7SAndroid Build Coastguard Worker mapping = vk::ResolveIdentityMapping(mapping);
54*03ce13f7SAndroid Build Coastguard Worker
55*03ce13f7SAndroid Build Coastguard Worker // Replace non-present components with zero/one swizzles so that the sampler
56*03ce13f7SAndroid Build Coastguard Worker // will give us correct interactions between channel replacement and texel replacement,
57*03ce13f7SAndroid Build Coastguard Worker // where we've had to invent new channels behind the app's back (eg transparent decompression
58*03ce13f7SAndroid Build Coastguard Worker // of ETC2 RGB -> BGRA8)
59*03ce13f7SAndroid Build Coastguard Worker VkComponentSwizzle table[] = {
60*03ce13f7SAndroid Build Coastguard Worker VK_COMPONENT_SWIZZLE_IDENTITY,
61*03ce13f7SAndroid Build Coastguard Worker VK_COMPONENT_SWIZZLE_ZERO,
62*03ce13f7SAndroid Build Coastguard Worker VK_COMPONENT_SWIZZLE_ONE,
63*03ce13f7SAndroid Build Coastguard Worker VK_COMPONENT_SWIZZLE_R,
64*03ce13f7SAndroid Build Coastguard Worker format.componentCount() < 2 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_G,
65*03ce13f7SAndroid Build Coastguard Worker format.componentCount() < 3 ? VK_COMPONENT_SWIZZLE_ZERO : VK_COMPONENT_SWIZZLE_B,
66*03ce13f7SAndroid Build Coastguard Worker format.componentCount() < 4 ? VK_COMPONENT_SWIZZLE_ONE : VK_COMPONENT_SWIZZLE_A,
67*03ce13f7SAndroid Build Coastguard Worker };
68*03ce13f7SAndroid Build Coastguard Worker
69*03ce13f7SAndroid Build Coastguard Worker return { table[mapping.r], table[mapping.g], table[mapping.b], table[mapping.a] };
70*03ce13f7SAndroid Build Coastguard Worker }
71*03ce13f7SAndroid Build Coastguard Worker
ResolveRemainingLevelsLayers(VkImageSubresourceRange range,const vk::Image * image)72*03ce13f7SAndroid Build Coastguard Worker VkImageSubresourceRange ResolveRemainingLevelsLayers(VkImageSubresourceRange range, const vk::Image *image)
73*03ce13f7SAndroid Build Coastguard Worker {
74*03ce13f7SAndroid Build Coastguard Worker return {
75*03ce13f7SAndroid Build Coastguard Worker range.aspectMask,
76*03ce13f7SAndroid Build Coastguard Worker range.baseMipLevel,
77*03ce13f7SAndroid Build Coastguard Worker (range.levelCount == VK_REMAINING_MIP_LEVELS) ? (image->getMipLevels() - range.baseMipLevel) : range.levelCount,
78*03ce13f7SAndroid Build Coastguard Worker range.baseArrayLayer,
79*03ce13f7SAndroid Build Coastguard Worker (range.layerCount == VK_REMAINING_ARRAY_LAYERS) ? (image->getArrayLayers() - range.baseArrayLayer) : range.layerCount,
80*03ce13f7SAndroid Build Coastguard Worker };
81*03ce13f7SAndroid Build Coastguard Worker }
82*03ce13f7SAndroid Build Coastguard Worker
Identifier(const VkImageViewCreateInfo * pCreateInfo)83*03ce13f7SAndroid Build Coastguard Worker Identifier::Identifier(const VkImageViewCreateInfo *pCreateInfo)
84*03ce13f7SAndroid Build Coastguard Worker {
85*03ce13f7SAndroid Build Coastguard Worker const Image *image = vk::Cast(pCreateInfo->image);
86*03ce13f7SAndroid Build Coastguard Worker
87*03ce13f7SAndroid Build Coastguard Worker VkImageSubresourceRange subresource = ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image);
88*03ce13f7SAndroid Build Coastguard Worker vk::Format viewFormat = GetImageViewFormat(pCreateInfo).getAspectFormat(subresource.aspectMask);
89*03ce13f7SAndroid Build Coastguard Worker const Image *sampledImage = image->getSampledImage(viewFormat);
90*03ce13f7SAndroid Build Coastguard Worker
91*03ce13f7SAndroid Build Coastguard Worker vk::Format samplingFormat = (image == sampledImage) ? viewFormat : sampledImage->getFormat().getAspectFormat(subresource.aspectMask);
92*03ce13f7SAndroid Build Coastguard Worker pack({ pCreateInfo->viewType, samplingFormat, ResolveComponentMapping(pCreateInfo->components, viewFormat),
93*03ce13f7SAndroid Build Coastguard Worker static_cast<uint8_t>(subresource.baseMipLevel),
94*03ce13f7SAndroid Build Coastguard Worker static_cast<uint8_t>(subresource.baseMipLevel + subresource.levelCount), subresource.levelCount <= 1u });
95*03ce13f7SAndroid Build Coastguard Worker }
96*03ce13f7SAndroid Build Coastguard Worker
Identifier(VkFormat bufferFormat)97*03ce13f7SAndroid Build Coastguard Worker Identifier::Identifier(VkFormat bufferFormat)
98*03ce13f7SAndroid Build Coastguard Worker {
99*03ce13f7SAndroid Build Coastguard Worker constexpr VkComponentMapping identityMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
100*03ce13f7SAndroid Build Coastguard Worker pack({ VK_IMAGE_VIEW_TYPE_1D, bufferFormat, ResolveComponentMapping(identityMapping, bufferFormat), 0, 1, true });
101*03ce13f7SAndroid Build Coastguard Worker }
102*03ce13f7SAndroid Build Coastguard Worker
pack(const State & state)103*03ce13f7SAndroid Build Coastguard Worker void Identifier::pack(const State &state)
104*03ce13f7SAndroid Build Coastguard Worker {
105*03ce13f7SAndroid Build Coastguard Worker imageViewType = static_cast<uint32_t>(state.imageViewType);
106*03ce13f7SAndroid Build Coastguard Worker format = Format::mapTo8bit(state.format);
107*03ce13f7SAndroid Build Coastguard Worker r = static_cast<uint32_t>(state.mapping.r);
108*03ce13f7SAndroid Build Coastguard Worker g = static_cast<uint32_t>(state.mapping.g);
109*03ce13f7SAndroid Build Coastguard Worker b = static_cast<uint32_t>(state.mapping.b);
110*03ce13f7SAndroid Build Coastguard Worker a = static_cast<uint32_t>(state.mapping.a);
111*03ce13f7SAndroid Build Coastguard Worker minLod = state.minLod;
112*03ce13f7SAndroid Build Coastguard Worker maxLod = state.maxLod;
113*03ce13f7SAndroid Build Coastguard Worker singleMipLevel = state.singleMipLevel;
114*03ce13f7SAndroid Build Coastguard Worker }
115*03ce13f7SAndroid Build Coastguard Worker
getState() const116*03ce13f7SAndroid Build Coastguard Worker Identifier::State Identifier::getState() const
117*03ce13f7SAndroid Build Coastguard Worker {
118*03ce13f7SAndroid Build Coastguard Worker return { static_cast<VkImageViewType>(imageViewType),
119*03ce13f7SAndroid Build Coastguard Worker Format::mapFrom8bit(static_cast<uint8_t>(format)),
120*03ce13f7SAndroid Build Coastguard Worker { static_cast<VkComponentSwizzle>(r),
121*03ce13f7SAndroid Build Coastguard Worker static_cast<VkComponentSwizzle>(g),
122*03ce13f7SAndroid Build Coastguard Worker static_cast<VkComponentSwizzle>(b),
123*03ce13f7SAndroid Build Coastguard Worker static_cast<VkComponentSwizzle>(a) },
124*03ce13f7SAndroid Build Coastguard Worker static_cast<uint8_t>(minLod),
125*03ce13f7SAndroid Build Coastguard Worker static_cast<uint8_t>(maxLod),
126*03ce13f7SAndroid Build Coastguard Worker static_cast<bool>(singleMipLevel) };
127*03ce13f7SAndroid Build Coastguard Worker }
128*03ce13f7SAndroid Build Coastguard Worker
ImageView(const VkImageViewCreateInfo * pCreateInfo,void * mem,const vk::SamplerYcbcrConversion * ycbcrConversion)129*03ce13f7SAndroid Build Coastguard Worker ImageView::ImageView(const VkImageViewCreateInfo *pCreateInfo, void *mem, const vk::SamplerYcbcrConversion *ycbcrConversion)
130*03ce13f7SAndroid Build Coastguard Worker : image(vk::Cast(pCreateInfo->image))
131*03ce13f7SAndroid Build Coastguard Worker , viewType(pCreateInfo->viewType)
132*03ce13f7SAndroid Build Coastguard Worker , format(GetImageViewFormat(pCreateInfo))
133*03ce13f7SAndroid Build Coastguard Worker , components(ResolveComponentMapping(pCreateInfo->components, format))
134*03ce13f7SAndroid Build Coastguard Worker , subresourceRange(ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image))
135*03ce13f7SAndroid Build Coastguard Worker , ycbcrConversion(ycbcrConversion)
136*03ce13f7SAndroid Build Coastguard Worker , id(pCreateInfo)
137*03ce13f7SAndroid Build Coastguard Worker {
138*03ce13f7SAndroid Build Coastguard Worker }
139*03ce13f7SAndroid Build Coastguard Worker
ComputeRequiredAllocationSize(const VkImageViewCreateInfo * pCreateInfo)140*03ce13f7SAndroid Build Coastguard Worker size_t ImageView::ComputeRequiredAllocationSize(const VkImageViewCreateInfo *pCreateInfo)
141*03ce13f7SAndroid Build Coastguard Worker {
142*03ce13f7SAndroid Build Coastguard Worker return 0;
143*03ce13f7SAndroid Build Coastguard Worker }
144*03ce13f7SAndroid Build Coastguard Worker
destroy(const VkAllocationCallbacks * pAllocator)145*03ce13f7SAndroid Build Coastguard Worker void ImageView::destroy(const VkAllocationCallbacks *pAllocator)
146*03ce13f7SAndroid Build Coastguard Worker {
147*03ce13f7SAndroid Build Coastguard Worker }
148*03ce13f7SAndroid Build Coastguard Worker
149*03ce13f7SAndroid Build Coastguard Worker // Vulkan 1.2 Table 8. Image and image view parameter compatibility requirements
imageTypesMatch(VkImageType imageType) const150*03ce13f7SAndroid Build Coastguard Worker bool ImageView::imageTypesMatch(VkImageType imageType) const
151*03ce13f7SAndroid Build Coastguard Worker {
152*03ce13f7SAndroid Build Coastguard Worker uint32_t imageArrayLayers = image->getArrayLayers();
153*03ce13f7SAndroid Build Coastguard Worker
154*03ce13f7SAndroid Build Coastguard Worker switch(viewType)
155*03ce13f7SAndroid Build Coastguard Worker {
156*03ce13f7SAndroid Build Coastguard Worker case VK_IMAGE_VIEW_TYPE_1D:
157*03ce13f7SAndroid Build Coastguard Worker return (imageType == VK_IMAGE_TYPE_1D) &&
158*03ce13f7SAndroid Build Coastguard Worker (subresourceRange.layerCount == 1);
159*03ce13f7SAndroid Build Coastguard Worker case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
160*03ce13f7SAndroid Build Coastguard Worker return imageType == VK_IMAGE_TYPE_1D;
161*03ce13f7SAndroid Build Coastguard Worker case VK_IMAGE_VIEW_TYPE_2D:
162*03ce13f7SAndroid Build Coastguard Worker return ((imageType == VK_IMAGE_TYPE_2D) ||
163*03ce13f7SAndroid Build Coastguard Worker ((imageType == VK_IMAGE_TYPE_3D) &&
164*03ce13f7SAndroid Build Coastguard Worker (imageArrayLayers == 1))) &&
165*03ce13f7SAndroid Build Coastguard Worker (subresourceRange.layerCount == 1);
166*03ce13f7SAndroid Build Coastguard Worker case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
167*03ce13f7SAndroid Build Coastguard Worker return (imageType == VK_IMAGE_TYPE_2D) ||
168*03ce13f7SAndroid Build Coastguard Worker ((imageType == VK_IMAGE_TYPE_3D) &&
169*03ce13f7SAndroid Build Coastguard Worker (imageArrayLayers == 1));
170*03ce13f7SAndroid Build Coastguard Worker case VK_IMAGE_VIEW_TYPE_CUBE:
171*03ce13f7SAndroid Build Coastguard Worker return image->isCubeCompatible() &&
172*03ce13f7SAndroid Build Coastguard Worker (imageArrayLayers >= subresourceRange.layerCount) &&
173*03ce13f7SAndroid Build Coastguard Worker (subresourceRange.layerCount == 6);
174*03ce13f7SAndroid Build Coastguard Worker case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
175*03ce13f7SAndroid Build Coastguard Worker return image->isCubeCompatible() &&
176*03ce13f7SAndroid Build Coastguard Worker (imageArrayLayers >= subresourceRange.layerCount) &&
177*03ce13f7SAndroid Build Coastguard Worker (subresourceRange.layerCount >= 6);
178*03ce13f7SAndroid Build Coastguard Worker case VK_IMAGE_VIEW_TYPE_3D:
179*03ce13f7SAndroid Build Coastguard Worker return (imageType == VK_IMAGE_TYPE_3D) &&
180*03ce13f7SAndroid Build Coastguard Worker (imageArrayLayers == 1) &&
181*03ce13f7SAndroid Build Coastguard Worker (subresourceRange.layerCount == 1);
182*03ce13f7SAndroid Build Coastguard Worker default:
183*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("Unexpected viewType %d", (int)viewType);
184*03ce13f7SAndroid Build Coastguard Worker }
185*03ce13f7SAndroid Build Coastguard Worker
186*03ce13f7SAndroid Build Coastguard Worker return false;
187*03ce13f7SAndroid Build Coastguard Worker }
188*03ce13f7SAndroid Build Coastguard Worker
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkRect2D & renderArea)189*03ce13f7SAndroid Build Coastguard Worker void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkRect2D &renderArea)
190*03ce13f7SAndroid Build Coastguard Worker {
191*03ce13f7SAndroid Build Coastguard Worker // Note: clearing ignores swizzling, so components is ignored.
192*03ce13f7SAndroid Build Coastguard Worker
193*03ce13f7SAndroid Build Coastguard Worker ASSERT(imageTypesMatch(image->getImageType()));
194*03ce13f7SAndroid Build Coastguard Worker ASSERT(format.isCompatible(image->getFormat()));
195*03ce13f7SAndroid Build Coastguard Worker
196*03ce13f7SAndroid Build Coastguard Worker VkImageSubresourceRange sr = subresourceRange;
197*03ce13f7SAndroid Build Coastguard Worker sr.aspectMask = aspectMask;
198*03ce13f7SAndroid Build Coastguard Worker image->clear(clearValue, format, renderArea, sr);
199*03ce13f7SAndroid Build Coastguard Worker }
200*03ce13f7SAndroid Build Coastguard Worker
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkClearRect & renderArea)201*03ce13f7SAndroid Build Coastguard Worker void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkClearRect &renderArea)
202*03ce13f7SAndroid Build Coastguard Worker {
203*03ce13f7SAndroid Build Coastguard Worker // Note: clearing ignores swizzling, so components is ignored.
204*03ce13f7SAndroid Build Coastguard Worker
205*03ce13f7SAndroid Build Coastguard Worker ASSERT(imageTypesMatch(image->getImageType()));
206*03ce13f7SAndroid Build Coastguard Worker ASSERT(format.isCompatible(image->getFormat()));
207*03ce13f7SAndroid Build Coastguard Worker
208*03ce13f7SAndroid Build Coastguard Worker VkImageSubresourceRange sr;
209*03ce13f7SAndroid Build Coastguard Worker sr.aspectMask = aspectMask;
210*03ce13f7SAndroid Build Coastguard Worker sr.baseMipLevel = subresourceRange.baseMipLevel;
211*03ce13f7SAndroid Build Coastguard Worker sr.levelCount = subresourceRange.levelCount;
212*03ce13f7SAndroid Build Coastguard Worker sr.baseArrayLayer = renderArea.baseArrayLayer + subresourceRange.baseArrayLayer;
213*03ce13f7SAndroid Build Coastguard Worker sr.layerCount = renderArea.layerCount;
214*03ce13f7SAndroid Build Coastguard Worker
215*03ce13f7SAndroid Build Coastguard Worker image->clear(clearValue, format, renderArea.rect, sr);
216*03ce13f7SAndroid Build Coastguard Worker }
217*03ce13f7SAndroid Build Coastguard Worker
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkRect2D & renderArea,uint32_t layerMask)218*03ce13f7SAndroid Build Coastguard Worker void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
219*03ce13f7SAndroid Build Coastguard Worker {
220*03ce13f7SAndroid Build Coastguard Worker if(layerMask == 0)
221*03ce13f7SAndroid Build Coastguard Worker {
222*03ce13f7SAndroid Build Coastguard Worker clear(clearValue, aspectMask, renderArea);
223*03ce13f7SAndroid Build Coastguard Worker }
224*03ce13f7SAndroid Build Coastguard Worker else
225*03ce13f7SAndroid Build Coastguard Worker {
226*03ce13f7SAndroid Build Coastguard Worker clearWithLayerMask(clearValue, aspectMask, renderArea, layerMask);
227*03ce13f7SAndroid Build Coastguard Worker }
228*03ce13f7SAndroid Build Coastguard Worker }
229*03ce13f7SAndroid Build Coastguard Worker
clear(const VkClearValue & clearValue,const VkImageAspectFlags aspectMask,const VkClearRect & renderArea,uint32_t layerMask)230*03ce13f7SAndroid Build Coastguard Worker void ImageView::clear(const VkClearValue &clearValue, const VkImageAspectFlags aspectMask, const VkClearRect &renderArea, uint32_t layerMask)
231*03ce13f7SAndroid Build Coastguard Worker {
232*03ce13f7SAndroid Build Coastguard Worker if(layerMask == 0)
233*03ce13f7SAndroid Build Coastguard Worker {
234*03ce13f7SAndroid Build Coastguard Worker clear(clearValue, aspectMask, renderArea);
235*03ce13f7SAndroid Build Coastguard Worker }
236*03ce13f7SAndroid Build Coastguard Worker else
237*03ce13f7SAndroid Build Coastguard Worker {
238*03ce13f7SAndroid Build Coastguard Worker clearWithLayerMask(clearValue, aspectMask, renderArea.rect, layerMask);
239*03ce13f7SAndroid Build Coastguard Worker }
240*03ce13f7SAndroid Build Coastguard Worker }
241*03ce13f7SAndroid Build Coastguard Worker
clearWithLayerMask(const VkClearValue & clearValue,VkImageAspectFlags aspectMask,const VkRect2D & renderArea,uint32_t layerMask)242*03ce13f7SAndroid Build Coastguard Worker void ImageView::clearWithLayerMask(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask)
243*03ce13f7SAndroid Build Coastguard Worker {
244*03ce13f7SAndroid Build Coastguard Worker while(layerMask)
245*03ce13f7SAndroid Build Coastguard Worker {
246*03ce13f7SAndroid Build Coastguard Worker uint32_t layer = sw::log2i(layerMask);
247*03ce13f7SAndroid Build Coastguard Worker layerMask &= ~(1 << layer);
248*03ce13f7SAndroid Build Coastguard Worker VkClearRect r = { renderArea, layer, 1 };
249*03ce13f7SAndroid Build Coastguard Worker r.baseArrayLayer = layer;
250*03ce13f7SAndroid Build Coastguard Worker clear(clearValue, aspectMask, r);
251*03ce13f7SAndroid Build Coastguard Worker }
252*03ce13f7SAndroid Build Coastguard Worker }
253*03ce13f7SAndroid Build Coastguard Worker
resolveSingleLayer(ImageView * resolveAttachment,int layer)254*03ce13f7SAndroid Build Coastguard Worker void ImageView::resolveSingleLayer(ImageView *resolveAttachment, int layer)
255*03ce13f7SAndroid Build Coastguard Worker {
256*03ce13f7SAndroid Build Coastguard Worker if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
257*03ce13f7SAndroid Build Coastguard Worker {
258*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443)
259*03ce13f7SAndroid Build Coastguard Worker }
260*03ce13f7SAndroid Build Coastguard Worker
261*03ce13f7SAndroid Build Coastguard Worker VkImageResolve2KHR region;
262*03ce13f7SAndroid Build Coastguard Worker region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR;
263*03ce13f7SAndroid Build Coastguard Worker region.pNext = nullptr;
264*03ce13f7SAndroid Build Coastguard Worker region.srcSubresource = {
265*03ce13f7SAndroid Build Coastguard Worker subresourceRange.aspectMask,
266*03ce13f7SAndroid Build Coastguard Worker subresourceRange.baseMipLevel,
267*03ce13f7SAndroid Build Coastguard Worker subresourceRange.baseArrayLayer + layer,
268*03ce13f7SAndroid Build Coastguard Worker 1
269*03ce13f7SAndroid Build Coastguard Worker };
270*03ce13f7SAndroid Build Coastguard Worker region.srcOffset = { 0, 0, 0 };
271*03ce13f7SAndroid Build Coastguard Worker region.dstSubresource = {
272*03ce13f7SAndroid Build Coastguard Worker resolveAttachment->subresourceRange.aspectMask,
273*03ce13f7SAndroid Build Coastguard Worker resolveAttachment->subresourceRange.baseMipLevel,
274*03ce13f7SAndroid Build Coastguard Worker resolveAttachment->subresourceRange.baseArrayLayer + layer,
275*03ce13f7SAndroid Build Coastguard Worker 1
276*03ce13f7SAndroid Build Coastguard Worker };
277*03ce13f7SAndroid Build Coastguard Worker region.dstOffset = { 0, 0, 0 };
278*03ce13f7SAndroid Build Coastguard Worker region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
279*03ce13f7SAndroid Build Coastguard Worker subresourceRange.baseMipLevel);
280*03ce13f7SAndroid Build Coastguard Worker
281*03ce13f7SAndroid Build Coastguard Worker image->resolveTo(resolveAttachment->image, region);
282*03ce13f7SAndroid Build Coastguard Worker }
283*03ce13f7SAndroid Build Coastguard Worker
resolve(ImageView * resolveAttachment)284*03ce13f7SAndroid Build Coastguard Worker void ImageView::resolve(ImageView *resolveAttachment)
285*03ce13f7SAndroid Build Coastguard Worker {
286*03ce13f7SAndroid Build Coastguard Worker if((subresourceRange.levelCount != 1) || (resolveAttachment->subresourceRange.levelCount != 1))
287*03ce13f7SAndroid Build Coastguard Worker {
288*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED("b/148242443: levelCount != 1"); // FIXME(b/148242443)
289*03ce13f7SAndroid Build Coastguard Worker }
290*03ce13f7SAndroid Build Coastguard Worker
291*03ce13f7SAndroid Build Coastguard Worker VkImageResolve2KHR region;
292*03ce13f7SAndroid Build Coastguard Worker region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR;
293*03ce13f7SAndroid Build Coastguard Worker region.pNext = nullptr;
294*03ce13f7SAndroid Build Coastguard Worker region.srcSubresource = {
295*03ce13f7SAndroid Build Coastguard Worker subresourceRange.aspectMask,
296*03ce13f7SAndroid Build Coastguard Worker subresourceRange.baseMipLevel,
297*03ce13f7SAndroid Build Coastguard Worker subresourceRange.baseArrayLayer,
298*03ce13f7SAndroid Build Coastguard Worker subresourceRange.layerCount
299*03ce13f7SAndroid Build Coastguard Worker };
300*03ce13f7SAndroid Build Coastguard Worker region.srcOffset = { 0, 0, 0 };
301*03ce13f7SAndroid Build Coastguard Worker region.dstSubresource = {
302*03ce13f7SAndroid Build Coastguard Worker resolveAttachment->subresourceRange.aspectMask,
303*03ce13f7SAndroid Build Coastguard Worker resolveAttachment->subresourceRange.baseMipLevel,
304*03ce13f7SAndroid Build Coastguard Worker resolveAttachment->subresourceRange.baseArrayLayer,
305*03ce13f7SAndroid Build Coastguard Worker resolveAttachment->subresourceRange.layerCount
306*03ce13f7SAndroid Build Coastguard Worker };
307*03ce13f7SAndroid Build Coastguard Worker region.dstOffset = { 0, 0, 0 };
308*03ce13f7SAndroid Build Coastguard Worker region.extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
309*03ce13f7SAndroid Build Coastguard Worker subresourceRange.baseMipLevel);
310*03ce13f7SAndroid Build Coastguard Worker
311*03ce13f7SAndroid Build Coastguard Worker image->resolveTo(resolveAttachment->image, region);
312*03ce13f7SAndroid Build Coastguard Worker }
313*03ce13f7SAndroid Build Coastguard Worker
resolve(ImageView * resolveAttachment,uint32_t layerMask)314*03ce13f7SAndroid Build Coastguard Worker void ImageView::resolve(ImageView *resolveAttachment, uint32_t layerMask)
315*03ce13f7SAndroid Build Coastguard Worker {
316*03ce13f7SAndroid Build Coastguard Worker if(layerMask == 0)
317*03ce13f7SAndroid Build Coastguard Worker {
318*03ce13f7SAndroid Build Coastguard Worker resolve(resolveAttachment);
319*03ce13f7SAndroid Build Coastguard Worker }
320*03ce13f7SAndroid Build Coastguard Worker else
321*03ce13f7SAndroid Build Coastguard Worker {
322*03ce13f7SAndroid Build Coastguard Worker resolveWithLayerMask(resolveAttachment, layerMask);
323*03ce13f7SAndroid Build Coastguard Worker }
324*03ce13f7SAndroid Build Coastguard Worker }
325*03ce13f7SAndroid Build Coastguard Worker
resolveWithLayerMask(ImageView * resolveAttachment,uint32_t layerMask)326*03ce13f7SAndroid Build Coastguard Worker void ImageView::resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask)
327*03ce13f7SAndroid Build Coastguard Worker {
328*03ce13f7SAndroid Build Coastguard Worker while(layerMask)
329*03ce13f7SAndroid Build Coastguard Worker {
330*03ce13f7SAndroid Build Coastguard Worker int layer = sw::log2i(layerMask);
331*03ce13f7SAndroid Build Coastguard Worker layerMask &= ~(1 << layer);
332*03ce13f7SAndroid Build Coastguard Worker resolveSingleLayer(resolveAttachment, layer);
333*03ce13f7SAndroid Build Coastguard Worker }
334*03ce13f7SAndroid Build Coastguard Worker }
335*03ce13f7SAndroid Build Coastguard Worker
resolveDepthStencil(ImageView * resolveAttachment,VkResolveModeFlagBits depthResolveMode,VkResolveModeFlagBits stencilResolveMode)336*03ce13f7SAndroid Build Coastguard Worker void ImageView::resolveDepthStencil(ImageView *resolveAttachment, VkResolveModeFlagBits depthResolveMode, VkResolveModeFlagBits stencilResolveMode)
337*03ce13f7SAndroid Build Coastguard Worker {
338*03ce13f7SAndroid Build Coastguard Worker ASSERT(subresourceRange.levelCount == 1 && resolveAttachment->subresourceRange.levelCount == 1);
339*03ce13f7SAndroid Build Coastguard Worker if((subresourceRange.layerCount != 1) || (resolveAttachment->subresourceRange.layerCount != 1))
340*03ce13f7SAndroid Build Coastguard Worker {
341*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED("b/148242443: layerCount != 1"); // FIXME(b/148242443)
342*03ce13f7SAndroid Build Coastguard Worker }
343*03ce13f7SAndroid Build Coastguard Worker
344*03ce13f7SAndroid Build Coastguard Worker image->resolveDepthStencilTo(this, resolveAttachment, depthResolveMode, stencilResolveMode);
345*03ce13f7SAndroid Build Coastguard Worker }
346*03ce13f7SAndroid Build Coastguard Worker
getImage(Usage usage) const347*03ce13f7SAndroid Build Coastguard Worker const Image *ImageView::getImage(Usage usage) const
348*03ce13f7SAndroid Build Coastguard Worker {
349*03ce13f7SAndroid Build Coastguard Worker switch(usage)
350*03ce13f7SAndroid Build Coastguard Worker {
351*03ce13f7SAndroid Build Coastguard Worker case RAW:
352*03ce13f7SAndroid Build Coastguard Worker return image;
353*03ce13f7SAndroid Build Coastguard Worker case SAMPLING:
354*03ce13f7SAndroid Build Coastguard Worker return image->getSampledImage(format);
355*03ce13f7SAndroid Build Coastguard Worker default:
356*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("usage %d", int(usage));
357*03ce13f7SAndroid Build Coastguard Worker return nullptr;
358*03ce13f7SAndroid Build Coastguard Worker }
359*03ce13f7SAndroid Build Coastguard Worker }
360*03ce13f7SAndroid Build Coastguard Worker
getFormat(Usage usage) const361*03ce13f7SAndroid Build Coastguard Worker Format ImageView::getFormat(Usage usage) const
362*03ce13f7SAndroid Build Coastguard Worker {
363*03ce13f7SAndroid Build Coastguard Worker Format imageFormat = ((usage == RAW) || (getImage(usage) == image)) ? format : getImage(usage)->getFormat();
364*03ce13f7SAndroid Build Coastguard Worker return imageFormat.getAspectFormat(subresourceRange.aspectMask);
365*03ce13f7SAndroid Build Coastguard Worker }
366*03ce13f7SAndroid Build Coastguard Worker
rowPitchBytes(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const367*03ce13f7SAndroid Build Coastguard Worker uint32_t ImageView::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
368*03ce13f7SAndroid Build Coastguard Worker {
369*03ce13f7SAndroid Build Coastguard Worker return sw::assert_cast<uint32_t>(getImage(usage)->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel));
370*03ce13f7SAndroid Build Coastguard Worker }
371*03ce13f7SAndroid Build Coastguard Worker
slicePitchBytes(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const372*03ce13f7SAndroid Build Coastguard Worker uint32_t ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
373*03ce13f7SAndroid Build Coastguard Worker {
374*03ce13f7SAndroid Build Coastguard Worker return sw::assert_cast<uint32_t>(getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel));
375*03ce13f7SAndroid Build Coastguard Worker }
376*03ce13f7SAndroid Build Coastguard Worker
getMipLevelSize(VkImageAspectFlagBits aspect,uint32_t mipLevel,Usage usage) const377*03ce13f7SAndroid Build Coastguard Worker uint32_t ImageView::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
378*03ce13f7SAndroid Build Coastguard Worker {
379*03ce13f7SAndroid Build Coastguard Worker return sw::assert_cast<uint32_t>(getImage(usage)->getMipLevelSize(aspect, subresourceRange.baseMipLevel + mipLevel));
380*03ce13f7SAndroid Build Coastguard Worker }
381*03ce13f7SAndroid Build Coastguard Worker
layerPitchBytes(VkImageAspectFlagBits aspect,Usage usage) const382*03ce13f7SAndroid Build Coastguard Worker uint32_t ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
383*03ce13f7SAndroid Build Coastguard Worker {
384*03ce13f7SAndroid Build Coastguard Worker return sw::assert_cast<uint32_t>(getImage(usage)->getLayerSize(aspect));
385*03ce13f7SAndroid Build Coastguard Worker }
386*03ce13f7SAndroid Build Coastguard Worker
getMipLevelExtent(uint32_t mipLevel) const387*03ce13f7SAndroid Build Coastguard Worker VkExtent2D ImageView::getMipLevelExtent(uint32_t mipLevel) const
388*03ce13f7SAndroid Build Coastguard Worker {
389*03ce13f7SAndroid Build Coastguard Worker return Extent2D(image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
390*03ce13f7SAndroid Build Coastguard Worker subresourceRange.baseMipLevel + mipLevel));
391*03ce13f7SAndroid Build Coastguard Worker }
392*03ce13f7SAndroid Build Coastguard Worker
getMipLevelExtent(uint32_t mipLevel,VkImageAspectFlagBits aspect) const393*03ce13f7SAndroid Build Coastguard Worker VkExtent2D ImageView::getMipLevelExtent(uint32_t mipLevel, VkImageAspectFlagBits aspect) const
394*03ce13f7SAndroid Build Coastguard Worker {
395*03ce13f7SAndroid Build Coastguard Worker return Extent2D(image->getMipLevelExtent(aspect, subresourceRange.baseMipLevel + mipLevel));
396*03ce13f7SAndroid Build Coastguard Worker }
397*03ce13f7SAndroid Build Coastguard Worker
getDepthOrLayerCount(uint32_t mipLevel) const398*03ce13f7SAndroid Build Coastguard Worker uint32_t ImageView::getDepthOrLayerCount(uint32_t mipLevel) const
399*03ce13f7SAndroid Build Coastguard Worker {
400*03ce13f7SAndroid Build Coastguard Worker VkExtent3D extent = image->getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask),
401*03ce13f7SAndroid Build Coastguard Worker subresourceRange.baseMipLevel + mipLevel);
402*03ce13f7SAndroid Build Coastguard Worker uint32_t layers = subresourceRange.layerCount;
403*03ce13f7SAndroid Build Coastguard Worker uint32_t depthOrLayers = layers > 1 ? layers : extent.depth;
404*03ce13f7SAndroid Build Coastguard Worker
405*03ce13f7SAndroid Build Coastguard Worker // For cube images the number of whole cubes is returned
406*03ce13f7SAndroid Build Coastguard Worker if(viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
407*03ce13f7SAndroid Build Coastguard Worker viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
408*03ce13f7SAndroid Build Coastguard Worker {
409*03ce13f7SAndroid Build Coastguard Worker depthOrLayers /= 6;
410*03ce13f7SAndroid Build Coastguard Worker }
411*03ce13f7SAndroid Build Coastguard Worker
412*03ce13f7SAndroid Build Coastguard Worker return depthOrLayers;
413*03ce13f7SAndroid Build Coastguard Worker }
414*03ce13f7SAndroid Build Coastguard Worker
getOffsetPointer(const VkOffset3D & offset,VkImageAspectFlagBits aspect,uint32_t mipLevel,uint32_t layer,Usage usage) const415*03ce13f7SAndroid Build Coastguard Worker void *ImageView::getOffsetPointer(const VkOffset3D &offset, VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer, Usage usage) const
416*03ce13f7SAndroid Build Coastguard Worker {
417*03ce13f7SAndroid Build Coastguard Worker ASSERT(mipLevel < subresourceRange.levelCount);
418*03ce13f7SAndroid Build Coastguard Worker
419*03ce13f7SAndroid Build Coastguard Worker VkImageSubresource imageSubresource = {
420*03ce13f7SAndroid Build Coastguard Worker static_cast<VkImageAspectFlags>(aspect),
421*03ce13f7SAndroid Build Coastguard Worker subresourceRange.baseMipLevel + mipLevel,
422*03ce13f7SAndroid Build Coastguard Worker subresourceRange.baseArrayLayer + layer,
423*03ce13f7SAndroid Build Coastguard Worker };
424*03ce13f7SAndroid Build Coastguard Worker
425*03ce13f7SAndroid Build Coastguard Worker return getImage(usage)->getTexelPointer(offset, imageSubresource);
426*03ce13f7SAndroid Build Coastguard Worker }
427*03ce13f7SAndroid Build Coastguard Worker
428*03ce13f7SAndroid Build Coastguard Worker } // namespace vk
429