xref: /aosp_15_r20/external/swiftshader/src/Vulkan/VkImageView.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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