1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // UtilsVk.cpp:
7*8975f5c5SAndroid Build Coastguard Worker // Implements the UtilsVk class.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/UtilsVk.h"
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker #include "common/spirv/spirv_instruction_builder_autogen.h"
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/ContextVk.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/FramebufferVk.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/RenderTargetVk.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/SurfaceVk.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_renderer.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_utils.h"
20*8975f5c5SAndroid Build Coastguard Worker
21*8975f5c5SAndroid Build Coastguard Worker namespace rx
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker
24*8975f5c5SAndroid Build Coastguard Worker namespace ConvertVertex_comp = vk::InternalShader::ConvertVertex_comp;
25*8975f5c5SAndroid Build Coastguard Worker namespace ImageClear_frag = vk::InternalShader::ImageClear_frag;
26*8975f5c5SAndroid Build Coastguard Worker namespace ImageCopy_frag = vk::InternalShader::ImageCopy_frag;
27*8975f5c5SAndroid Build Coastguard Worker namespace ImageCopyFloat_frag = vk::InternalShader::ImageCopyFloat_frag;
28*8975f5c5SAndroid Build Coastguard Worker namespace CopyImageToBuffer_comp = vk::InternalShader::CopyImageToBuffer_comp;
29*8975f5c5SAndroid Build Coastguard Worker namespace BlitResolve_frag = vk::InternalShader::BlitResolve_frag;
30*8975f5c5SAndroid Build Coastguard Worker namespace Blit3DSrc_frag = vk::InternalShader::Blit3DSrc_frag;
31*8975f5c5SAndroid Build Coastguard Worker namespace BlitResolveStencilNoExport_comp = vk::InternalShader::BlitResolveStencilNoExport_comp;
32*8975f5c5SAndroid Build Coastguard Worker namespace ExportStencil_frag = vk::InternalShader::ExportStencil_frag;
33*8975f5c5SAndroid Build Coastguard Worker namespace ConvertIndexIndirectLineLoop_comp = vk::InternalShader::ConvertIndexIndirectLineLoop_comp;
34*8975f5c5SAndroid Build Coastguard Worker namespace GenerateMipmap_comp = vk::InternalShader::GenerateMipmap_comp;
35*8975f5c5SAndroid Build Coastguard Worker namespace EtcToBc_comp = vk::InternalShader::EtcToBc_comp;
36*8975f5c5SAndroid Build Coastguard Worker
37*8975f5c5SAndroid Build Coastguard Worker namespace spirv = angle::spirv;
38*8975f5c5SAndroid Build Coastguard Worker
39*8975f5c5SAndroid Build Coastguard Worker namespace
40*8975f5c5SAndroid Build Coastguard Worker {
41*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kConvertIndexDestinationBinding = 0;
42*8975f5c5SAndroid Build Coastguard Worker
43*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kConvertVertexDestinationBinding = 0;
44*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kConvertVertexSourceBinding = 1;
45*8975f5c5SAndroid Build Coastguard Worker
46*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kImageCopySourceBinding = 0;
47*8975f5c5SAndroid Build Coastguard Worker
48*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kCopyImageToBufferSourceBinding = 0;
49*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kCopyImageToBufferDestinationBinding = 1;
50*8975f5c5SAndroid Build Coastguard Worker
51*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kBlitResolveColorOrDepthBinding = 0;
52*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kBlitResolveStencilBinding = 1;
53*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kBlitResolveSamplerBinding = 2;
54*8975f5c5SAndroid Build Coastguard Worker
55*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kBlitResolveStencilNoExportDestBinding = 0;
56*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kBlitResolveStencilNoExportSrcBinding = 1;
57*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kBlitResolveStencilNoExportSamplerBinding = 2;
58*8975f5c5SAndroid Build Coastguard Worker
59*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kExportStencilInputIndex = 0;
60*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kExportStencilBinding = 0;
61*8975f5c5SAndroid Build Coastguard Worker
62*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kOverlayDrawTextWidgetsBinding = 0;
63*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kOverlayDrawGraphWidgetsBinding = 1;
64*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kOverlayDrawFontBinding = 2;
65*8975f5c5SAndroid Build Coastguard Worker
66*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kGenerateMipmapDestinationBinding = 0;
67*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kGenerateMipmapSourceBinding = 1;
68*8975f5c5SAndroid Build Coastguard Worker
69*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kGenerateFragmentShadingRateAttachmentBinding = 0;
70*8975f5c5SAndroid Build Coastguard Worker
ValidateFloatOneAsUint()71*8975f5c5SAndroid Build Coastguard Worker bool ValidateFloatOneAsUint()
72*8975f5c5SAndroid Build Coastguard Worker {
73*8975f5c5SAndroid Build Coastguard Worker union
74*8975f5c5SAndroid Build Coastguard Worker {
75*8975f5c5SAndroid Build Coastguard Worker uint32_t asUint;
76*8975f5c5SAndroid Build Coastguard Worker float asFloat;
77*8975f5c5SAndroid Build Coastguard Worker } one;
78*8975f5c5SAndroid Build Coastguard Worker one.asUint = gl::Float32One;
79*8975f5c5SAndroid Build Coastguard Worker return one.asFloat == 1.0f;
80*8975f5c5SAndroid Build Coastguard Worker }
81*8975f5c5SAndroid Build Coastguard Worker
GetConvertVertexFlags(const UtilsVk::ConvertVertexParameters & params)82*8975f5c5SAndroid Build Coastguard Worker uint32_t GetConvertVertexFlags(const UtilsVk::ConvertVertexParameters ¶ms)
83*8975f5c5SAndroid Build Coastguard Worker {
84*8975f5c5SAndroid Build Coastguard Worker bool srcIsSint = params.srcFormat->isSint();
85*8975f5c5SAndroid Build Coastguard Worker bool srcIsUint = params.srcFormat->isUint();
86*8975f5c5SAndroid Build Coastguard Worker bool srcIsSnorm = params.srcFormat->isSnorm();
87*8975f5c5SAndroid Build Coastguard Worker bool srcIsUnorm = params.srcFormat->isUnorm();
88*8975f5c5SAndroid Build Coastguard Worker bool srcIsFixed = params.srcFormat->isFixed;
89*8975f5c5SAndroid Build Coastguard Worker bool srcIsFloat = params.srcFormat->isFloat();
90*8975f5c5SAndroid Build Coastguard Worker bool srcIsHalfFloat = params.srcFormat->isVertexTypeHalfFloat();
91*8975f5c5SAndroid Build Coastguard Worker
92*8975f5c5SAndroid Build Coastguard Worker bool dstIsSint = params.dstFormat->isSint();
93*8975f5c5SAndroid Build Coastguard Worker bool dstIsUint = params.dstFormat->isUint();
94*8975f5c5SAndroid Build Coastguard Worker bool dstIsSnorm = params.dstFormat->isSnorm();
95*8975f5c5SAndroid Build Coastguard Worker bool dstIsUnorm = params.dstFormat->isUnorm();
96*8975f5c5SAndroid Build Coastguard Worker bool dstIsFloat = params.dstFormat->isFloat();
97*8975f5c5SAndroid Build Coastguard Worker bool dstIsHalfFloat = params.dstFormat->isVertexTypeHalfFloat();
98*8975f5c5SAndroid Build Coastguard Worker
99*8975f5c5SAndroid Build Coastguard Worker // Assert on the types to make sure the shader supports its. These are based on
100*8975f5c5SAndroid Build Coastguard Worker // ConvertVertex_comp::Conversion values.
101*8975f5c5SAndroid Build Coastguard Worker ASSERT(!dstIsSint || srcIsSint); // If destination is sint, src must be sint too
102*8975f5c5SAndroid Build Coastguard Worker ASSERT(!dstIsUint || srcIsUint); // If destination is uint, src must be uint too
103*8975f5c5SAndroid Build Coastguard Worker ASSERT(!srcIsFixed || dstIsFloat); // If source is fixed, dst must be float
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker // One of each bool set must be true
106*8975f5c5SAndroid Build Coastguard Worker ASSERT(srcIsSint || srcIsUint || srcIsSnorm || srcIsUnorm || srcIsFixed || srcIsFloat);
107*8975f5c5SAndroid Build Coastguard Worker ASSERT(dstIsSint || dstIsUint || dstIsSnorm || dstIsUnorm || dstIsFloat || dstIsHalfFloat);
108*8975f5c5SAndroid Build Coastguard Worker
109*8975f5c5SAndroid Build Coastguard Worker // We currently don't have any big-endian devices in the list of supported platforms. The
110*8975f5c5SAndroid Build Coastguard Worker // shader is capable of supporting big-endian architectures, but the relevant flag (IsBigEndian)
111*8975f5c5SAndroid Build Coastguard Worker // is not added to the build configuration file (to reduce binary size). If necessary, add
112*8975f5c5SAndroid Build Coastguard Worker // IsBigEndian to ConvertVertex.comp.json and select the appropriate flag based on the
113*8975f5c5SAndroid Build Coastguard Worker // endian-ness test here.
114*8975f5c5SAndroid Build Coastguard Worker ASSERT(IsLittleEndian());
115*8975f5c5SAndroid Build Coastguard Worker
116*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = 0;
117*8975f5c5SAndroid Build Coastguard Worker
118*8975f5c5SAndroid Build Coastguard Worker if (srcIsHalfFloat && dstIsHalfFloat)
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker // Note that HalfFloat conversion uses the same shader as Uint.
121*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kUintToUint;
122*8975f5c5SAndroid Build Coastguard Worker }
123*8975f5c5SAndroid Build Coastguard Worker else if ((srcIsSnorm && dstIsSnorm) || (srcIsUnorm && dstIsUnorm))
124*8975f5c5SAndroid Build Coastguard Worker {
125*8975f5c5SAndroid Build Coastguard Worker // Do snorm->snorm and unorm->unorm copies using the uint->uint shader. Currently only
126*8975f5c5SAndroid Build Coastguard Worker // supported for same-width formats, so it's only used when adding channels.
127*8975f5c5SAndroid Build Coastguard Worker ASSERT(params.srcFormat->redBits == params.dstFormat->redBits);
128*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kUintToUint;
129*8975f5c5SAndroid Build Coastguard Worker }
130*8975f5c5SAndroid Build Coastguard Worker else if (srcIsSint && dstIsSint)
131*8975f5c5SAndroid Build Coastguard Worker {
132*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kSintToSint;
133*8975f5c5SAndroid Build Coastguard Worker }
134*8975f5c5SAndroid Build Coastguard Worker else if (srcIsUint && dstIsUint)
135*8975f5c5SAndroid Build Coastguard Worker {
136*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kUintToUint;
137*8975f5c5SAndroid Build Coastguard Worker }
138*8975f5c5SAndroid Build Coastguard Worker else if (srcIsSint)
139*8975f5c5SAndroid Build Coastguard Worker {
140*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kSintToFloat;
141*8975f5c5SAndroid Build Coastguard Worker }
142*8975f5c5SAndroid Build Coastguard Worker else if (srcIsUint)
143*8975f5c5SAndroid Build Coastguard Worker {
144*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kUintToFloat;
145*8975f5c5SAndroid Build Coastguard Worker }
146*8975f5c5SAndroid Build Coastguard Worker else if (srcIsSnorm)
147*8975f5c5SAndroid Build Coastguard Worker {
148*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kSnormToFloat;
149*8975f5c5SAndroid Build Coastguard Worker }
150*8975f5c5SAndroid Build Coastguard Worker else if (srcIsUnorm)
151*8975f5c5SAndroid Build Coastguard Worker {
152*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kUnormToFloat;
153*8975f5c5SAndroid Build Coastguard Worker }
154*8975f5c5SAndroid Build Coastguard Worker else if (srcIsFixed)
155*8975f5c5SAndroid Build Coastguard Worker {
156*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kFixedToFloat;
157*8975f5c5SAndroid Build Coastguard Worker }
158*8975f5c5SAndroid Build Coastguard Worker else if (srcIsFloat)
159*8975f5c5SAndroid Build Coastguard Worker {
160*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kFloatToFloat;
161*8975f5c5SAndroid Build Coastguard Worker }
162*8975f5c5SAndroid Build Coastguard Worker else
163*8975f5c5SAndroid Build Coastguard Worker {
164*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
165*8975f5c5SAndroid Build Coastguard Worker }
166*8975f5c5SAndroid Build Coastguard Worker
167*8975f5c5SAndroid Build Coastguard Worker return flags;
168*8975f5c5SAndroid Build Coastguard Worker }
169*8975f5c5SAndroid Build Coastguard Worker
GetImageClearFlags(const angle::Format & format,uint32_t attachmentIndex,bool clearDepth)170*8975f5c5SAndroid Build Coastguard Worker uint32_t GetImageClearFlags(const angle::Format &format, uint32_t attachmentIndex, bool clearDepth)
171*8975f5c5SAndroid Build Coastguard Worker {
172*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kAttachmentFlagStep =
173*8975f5c5SAndroid Build Coastguard Worker ImageClear_frag::kAttachment1 - ImageClear_frag::kAttachment0;
174*8975f5c5SAndroid Build Coastguard Worker
175*8975f5c5SAndroid Build Coastguard Worker static_assert(gl::IMPLEMENTATION_MAX_DRAW_BUFFERS == 8,
176*8975f5c5SAndroid Build Coastguard Worker "ImageClear shader assumes maximum 8 draw buffers");
177*8975f5c5SAndroid Build Coastguard Worker static_assert(
178*8975f5c5SAndroid Build Coastguard Worker ImageClear_frag::kAttachment0 + 7 * kAttachmentFlagStep == ImageClear_frag::kAttachment7,
179*8975f5c5SAndroid Build Coastguard Worker "ImageClear AttachmentN flag calculation needs correction");
180*8975f5c5SAndroid Build Coastguard Worker
181*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = ImageClear_frag::kAttachment0 + attachmentIndex * kAttachmentFlagStep;
182*8975f5c5SAndroid Build Coastguard Worker
183*8975f5c5SAndroid Build Coastguard Worker if (format.isSint())
184*8975f5c5SAndroid Build Coastguard Worker {
185*8975f5c5SAndroid Build Coastguard Worker flags |= ImageClear_frag::kIsSint;
186*8975f5c5SAndroid Build Coastguard Worker }
187*8975f5c5SAndroid Build Coastguard Worker else if (format.isUint())
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker flags |= ImageClear_frag::kIsUint;
190*8975f5c5SAndroid Build Coastguard Worker }
191*8975f5c5SAndroid Build Coastguard Worker else
192*8975f5c5SAndroid Build Coastguard Worker {
193*8975f5c5SAndroid Build Coastguard Worker flags |= ImageClear_frag::kIsFloat;
194*8975f5c5SAndroid Build Coastguard Worker }
195*8975f5c5SAndroid Build Coastguard Worker
196*8975f5c5SAndroid Build Coastguard Worker if (clearDepth)
197*8975f5c5SAndroid Build Coastguard Worker {
198*8975f5c5SAndroid Build Coastguard Worker flags |= ImageClear_frag::kClearDepth;
199*8975f5c5SAndroid Build Coastguard Worker }
200*8975f5c5SAndroid Build Coastguard Worker
201*8975f5c5SAndroid Build Coastguard Worker return flags;
202*8975f5c5SAndroid Build Coastguard Worker }
203*8975f5c5SAndroid Build Coastguard Worker
GetFormatFlags(const angle::Format & format,uint32_t intFlag,uint32_t uintFlag,uint32_t floatFlag)204*8975f5c5SAndroid Build Coastguard Worker uint32_t GetFormatFlags(const angle::Format &format,
205*8975f5c5SAndroid Build Coastguard Worker uint32_t intFlag,
206*8975f5c5SAndroid Build Coastguard Worker uint32_t uintFlag,
207*8975f5c5SAndroid Build Coastguard Worker uint32_t floatFlag)
208*8975f5c5SAndroid Build Coastguard Worker {
209*8975f5c5SAndroid Build Coastguard Worker if (format.isSint())
210*8975f5c5SAndroid Build Coastguard Worker {
211*8975f5c5SAndroid Build Coastguard Worker return intFlag;
212*8975f5c5SAndroid Build Coastguard Worker }
213*8975f5c5SAndroid Build Coastguard Worker if (format.isUint())
214*8975f5c5SAndroid Build Coastguard Worker {
215*8975f5c5SAndroid Build Coastguard Worker return uintFlag;
216*8975f5c5SAndroid Build Coastguard Worker }
217*8975f5c5SAndroid Build Coastguard Worker return floatFlag;
218*8975f5c5SAndroid Build Coastguard Worker }
219*8975f5c5SAndroid Build Coastguard Worker
GetImageCopyFlags(const angle::Format & srcIntendedFormat,const angle::Format & dstIntendedFormat)220*8975f5c5SAndroid Build Coastguard Worker uint32_t GetImageCopyFlags(const angle::Format &srcIntendedFormat,
221*8975f5c5SAndroid Build Coastguard Worker const angle::Format &dstIntendedFormat)
222*8975f5c5SAndroid Build Coastguard Worker {
223*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = 0;
224*8975f5c5SAndroid Build Coastguard Worker
225*8975f5c5SAndroid Build Coastguard Worker flags |= GetFormatFlags(srcIntendedFormat, ImageCopy_frag::kSrcIsSint,
226*8975f5c5SAndroid Build Coastguard Worker ImageCopy_frag::kSrcIsUint, ImageCopy_frag::kSrcIsFloat);
227*8975f5c5SAndroid Build Coastguard Worker flags |= GetFormatFlags(dstIntendedFormat, ImageCopy_frag::kDstIsSint,
228*8975f5c5SAndroid Build Coastguard Worker ImageCopy_frag::kDstIsUint, ImageCopy_frag::kDstIsFloat);
229*8975f5c5SAndroid Build Coastguard Worker
230*8975f5c5SAndroid Build Coastguard Worker return flags;
231*8975f5c5SAndroid Build Coastguard Worker }
232*8975f5c5SAndroid Build Coastguard Worker
GetCopyImageToBufferFlags(const angle::Format & srcFormat)233*8975f5c5SAndroid Build Coastguard Worker uint32_t GetCopyImageToBufferFlags(const angle::Format &srcFormat)
234*8975f5c5SAndroid Build Coastguard Worker {
235*8975f5c5SAndroid Build Coastguard Worker ASSERT(!srcFormat.isSint() && !srcFormat.isUint());
236*8975f5c5SAndroid Build Coastguard Worker return CopyImageToBuffer_comp::kSrcIsFloat;
237*8975f5c5SAndroid Build Coastguard Worker }
238*8975f5c5SAndroid Build Coastguard Worker
GetBlitResolveFlags(bool blitColor,bool blitDepth,bool blitStencil,const angle::Format & intendedFormat)239*8975f5c5SAndroid Build Coastguard Worker uint32_t GetBlitResolveFlags(bool blitColor,
240*8975f5c5SAndroid Build Coastguard Worker bool blitDepth,
241*8975f5c5SAndroid Build Coastguard Worker bool blitStencil,
242*8975f5c5SAndroid Build Coastguard Worker const angle::Format &intendedFormat)
243*8975f5c5SAndroid Build Coastguard Worker {
244*8975f5c5SAndroid Build Coastguard Worker if (blitColor)
245*8975f5c5SAndroid Build Coastguard Worker {
246*8975f5c5SAndroid Build Coastguard Worker return GetFormatFlags(intendedFormat, BlitResolve_frag::kBlitColorInt,
247*8975f5c5SAndroid Build Coastguard Worker BlitResolve_frag::kBlitColorUint, BlitResolve_frag::kBlitColorFloat);
248*8975f5c5SAndroid Build Coastguard Worker }
249*8975f5c5SAndroid Build Coastguard Worker
250*8975f5c5SAndroid Build Coastguard Worker if (blitDepth)
251*8975f5c5SAndroid Build Coastguard Worker {
252*8975f5c5SAndroid Build Coastguard Worker if (blitStencil)
253*8975f5c5SAndroid Build Coastguard Worker {
254*8975f5c5SAndroid Build Coastguard Worker return BlitResolve_frag::kBlitDepthStencil;
255*8975f5c5SAndroid Build Coastguard Worker }
256*8975f5c5SAndroid Build Coastguard Worker else
257*8975f5c5SAndroid Build Coastguard Worker {
258*8975f5c5SAndroid Build Coastguard Worker return BlitResolve_frag::kBlitDepth;
259*8975f5c5SAndroid Build Coastguard Worker }
260*8975f5c5SAndroid Build Coastguard Worker }
261*8975f5c5SAndroid Build Coastguard Worker else
262*8975f5c5SAndroid Build Coastguard Worker {
263*8975f5c5SAndroid Build Coastguard Worker return BlitResolve_frag::kBlitStencil;
264*8975f5c5SAndroid Build Coastguard Worker }
265*8975f5c5SAndroid Build Coastguard Worker }
266*8975f5c5SAndroid Build Coastguard Worker
GetConvertIndexIndirectLineLoopFlag(uint32_t indicesBitsWidth)267*8975f5c5SAndroid Build Coastguard Worker uint32_t GetConvertIndexIndirectLineLoopFlag(uint32_t indicesBitsWidth)
268*8975f5c5SAndroid Build Coastguard Worker {
269*8975f5c5SAndroid Build Coastguard Worker switch (indicesBitsWidth)
270*8975f5c5SAndroid Build Coastguard Worker {
271*8975f5c5SAndroid Build Coastguard Worker case 8:
272*8975f5c5SAndroid Build Coastguard Worker return ConvertIndexIndirectLineLoop_comp::kIs8Bits;
273*8975f5c5SAndroid Build Coastguard Worker case 16:
274*8975f5c5SAndroid Build Coastguard Worker return ConvertIndexIndirectLineLoop_comp::kIs16Bits;
275*8975f5c5SAndroid Build Coastguard Worker case 32:
276*8975f5c5SAndroid Build Coastguard Worker return ConvertIndexIndirectLineLoop_comp::kIs32Bits;
277*8975f5c5SAndroid Build Coastguard Worker default:
278*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
279*8975f5c5SAndroid Build Coastguard Worker return 0;
280*8975f5c5SAndroid Build Coastguard Worker }
281*8975f5c5SAndroid Build Coastguard Worker }
282*8975f5c5SAndroid Build Coastguard Worker
GetGenerateMipmapFlags(ContextVk * contextVk,const angle::Format & actualFormat)283*8975f5c5SAndroid Build Coastguard Worker uint32_t GetGenerateMipmapFlags(ContextVk *contextVk, const angle::Format &actualFormat)
284*8975f5c5SAndroid Build Coastguard Worker {
285*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = 0;
286*8975f5c5SAndroid Build Coastguard Worker
287*8975f5c5SAndroid Build Coastguard Worker // Note: If bits-per-component is 8 or 16 and float16 is supported in the shader, use that for
288*8975f5c5SAndroid Build Coastguard Worker // faster math.
289*8975f5c5SAndroid Build Coastguard Worker const bool hasShaderFloat16 = contextVk->getFeatures().supportsShaderFloat16.enabled;
290*8975f5c5SAndroid Build Coastguard Worker
291*8975f5c5SAndroid Build Coastguard Worker if (actualFormat.redBits <= 8)
292*8975f5c5SAndroid Build Coastguard Worker {
293*8975f5c5SAndroid Build Coastguard Worker flags = hasShaderFloat16 ? GenerateMipmap_comp::kIsRGBA8_UseHalf
294*8975f5c5SAndroid Build Coastguard Worker : GenerateMipmap_comp::kIsRGBA8;
295*8975f5c5SAndroid Build Coastguard Worker }
296*8975f5c5SAndroid Build Coastguard Worker else if (actualFormat.redBits <= 16)
297*8975f5c5SAndroid Build Coastguard Worker {
298*8975f5c5SAndroid Build Coastguard Worker flags = hasShaderFloat16 ? GenerateMipmap_comp::kIsRGBA16_UseHalf
299*8975f5c5SAndroid Build Coastguard Worker : GenerateMipmap_comp::kIsRGBA16;
300*8975f5c5SAndroid Build Coastguard Worker }
301*8975f5c5SAndroid Build Coastguard Worker else
302*8975f5c5SAndroid Build Coastguard Worker {
303*8975f5c5SAndroid Build Coastguard Worker flags = GenerateMipmap_comp::kIsRGBA32F;
304*8975f5c5SAndroid Build Coastguard Worker }
305*8975f5c5SAndroid Build Coastguard Worker
306*8975f5c5SAndroid Build Coastguard Worker flags |= UtilsVk::GetGenerateMipmapMaxLevels(contextVk) == UtilsVk::kGenerateMipmapMaxLevels
307*8975f5c5SAndroid Build Coastguard Worker ? GenerateMipmap_comp::kDestSize6
308*8975f5c5SAndroid Build Coastguard Worker : GenerateMipmap_comp::kDestSize4;
309*8975f5c5SAndroid Build Coastguard Worker
310*8975f5c5SAndroid Build Coastguard Worker return flags;
311*8975f5c5SAndroid Build Coastguard Worker }
312*8975f5c5SAndroid Build Coastguard Worker
313*8975f5c5SAndroid Build Coastguard Worker enum UnresolveColorAttachmentType
314*8975f5c5SAndroid Build Coastguard Worker {
315*8975f5c5SAndroid Build Coastguard Worker kUnresolveTypeUnused = 0,
316*8975f5c5SAndroid Build Coastguard Worker kUnresolveTypeFloat = 1,
317*8975f5c5SAndroid Build Coastguard Worker kUnresolveTypeSint = 2,
318*8975f5c5SAndroid Build Coastguard Worker kUnresolveTypeUint = 3,
319*8975f5c5SAndroid Build Coastguard Worker };
320*8975f5c5SAndroid Build Coastguard Worker
GetUnresolveFlags(uint32_t colorAttachmentCount,const gl::DrawBuffersArray<vk::ImageHelper * > & colorSrc,bool unresolveDepth,bool unresolveStencil,gl::DrawBuffersArray<UnresolveColorAttachmentType> * attachmentTypesOut)321*8975f5c5SAndroid Build Coastguard Worker uint32_t GetUnresolveFlags(uint32_t colorAttachmentCount,
322*8975f5c5SAndroid Build Coastguard Worker const gl::DrawBuffersArray<vk::ImageHelper *> &colorSrc,
323*8975f5c5SAndroid Build Coastguard Worker bool unresolveDepth,
324*8975f5c5SAndroid Build Coastguard Worker bool unresolveStencil,
325*8975f5c5SAndroid Build Coastguard Worker gl::DrawBuffersArray<UnresolveColorAttachmentType> *attachmentTypesOut)
326*8975f5c5SAndroid Build Coastguard Worker {
327*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = 0;
328*8975f5c5SAndroid Build Coastguard Worker
329*8975f5c5SAndroid Build Coastguard Worker for (uint32_t attachmentIndex = 0; attachmentIndex < colorAttachmentCount; ++attachmentIndex)
330*8975f5c5SAndroid Build Coastguard Worker {
331*8975f5c5SAndroid Build Coastguard Worker const angle::Format &format = colorSrc[attachmentIndex]->getIntendedFormat();
332*8975f5c5SAndroid Build Coastguard Worker
333*8975f5c5SAndroid Build Coastguard Worker UnresolveColorAttachmentType type = kUnresolveTypeFloat;
334*8975f5c5SAndroid Build Coastguard Worker if (format.isSint())
335*8975f5c5SAndroid Build Coastguard Worker {
336*8975f5c5SAndroid Build Coastguard Worker type = kUnresolveTypeSint;
337*8975f5c5SAndroid Build Coastguard Worker }
338*8975f5c5SAndroid Build Coastguard Worker else if (format.isUint())
339*8975f5c5SAndroid Build Coastguard Worker {
340*8975f5c5SAndroid Build Coastguard Worker type = kUnresolveTypeUint;
341*8975f5c5SAndroid Build Coastguard Worker }
342*8975f5c5SAndroid Build Coastguard Worker
343*8975f5c5SAndroid Build Coastguard Worker (*attachmentTypesOut)[attachmentIndex] = type;
344*8975f5c5SAndroid Build Coastguard Worker
345*8975f5c5SAndroid Build Coastguard Worker // |flags| is comprised of |colorAttachmentCount| values from
346*8975f5c5SAndroid Build Coastguard Worker // |UnresolveColorAttachmentType|, each taking up 2 bits.
347*8975f5c5SAndroid Build Coastguard Worker flags |= type << (2 * attachmentIndex);
348*8975f5c5SAndroid Build Coastguard Worker }
349*8975f5c5SAndroid Build Coastguard Worker
350*8975f5c5SAndroid Build Coastguard Worker // Additionally, two bits are used for depth and stencil unresolve.
351*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kDepthUnresolveFlagBit = 2 * gl::IMPLEMENTATION_MAX_DRAW_BUFFERS;
352*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kStencilUnresolveFlagBit = kDepthUnresolveFlagBit + 1;
353*8975f5c5SAndroid Build Coastguard Worker if (unresolveDepth)
354*8975f5c5SAndroid Build Coastguard Worker {
355*8975f5c5SAndroid Build Coastguard Worker flags |= 1 << kDepthUnresolveFlagBit;
356*8975f5c5SAndroid Build Coastguard Worker }
357*8975f5c5SAndroid Build Coastguard Worker
358*8975f5c5SAndroid Build Coastguard Worker if (unresolveStencil)
359*8975f5c5SAndroid Build Coastguard Worker {
360*8975f5c5SAndroid Build Coastguard Worker flags |= 1 << kStencilUnresolveFlagBit;
361*8975f5c5SAndroid Build Coastguard Worker }
362*8975f5c5SAndroid Build Coastguard Worker
363*8975f5c5SAndroid Build Coastguard Worker return flags;
364*8975f5c5SAndroid Build Coastguard Worker }
365*8975f5c5SAndroid Build Coastguard Worker
GetFormatDefaultChannelMask(const angle::Format & intendedImageFormat,const angle::Format & actualImageFormat)366*8975f5c5SAndroid Build Coastguard Worker uint32_t GetFormatDefaultChannelMask(const angle::Format &intendedImageFormat,
367*8975f5c5SAndroid Build Coastguard Worker const angle::Format &actualImageFormat)
368*8975f5c5SAndroid Build Coastguard Worker {
369*8975f5c5SAndroid Build Coastguard Worker uint32_t mask = 0;
370*8975f5c5SAndroid Build Coastguard Worker
371*8975f5c5SAndroid Build Coastguard Worker // Red can never be introduced due to format emulation (except for luma which is handled
372*8975f5c5SAndroid Build Coastguard Worker // especially)
373*8975f5c5SAndroid Build Coastguard Worker ASSERT(((intendedImageFormat.redBits > 0) == (actualImageFormat.redBits > 0)) ||
374*8975f5c5SAndroid Build Coastguard Worker intendedImageFormat.isLUMA());
375*8975f5c5SAndroid Build Coastguard Worker mask |= intendedImageFormat.greenBits == 0 && actualImageFormat.greenBits > 0 ? 2 : 0;
376*8975f5c5SAndroid Build Coastguard Worker mask |= intendedImageFormat.blueBits == 0 && actualImageFormat.blueBits > 0 ? 4 : 0;
377*8975f5c5SAndroid Build Coastguard Worker mask |= intendedImageFormat.alphaBits == 0 && actualImageFormat.alphaBits > 0 ? 8 : 0;
378*8975f5c5SAndroid Build Coastguard Worker
379*8975f5c5SAndroid Build Coastguard Worker return mask;
380*8975f5c5SAndroid Build Coastguard Worker }
381*8975f5c5SAndroid Build Coastguard Worker
382*8975f5c5SAndroid Build Coastguard Worker // Calculate the transformation offset for blit/resolve. See BlitResolve.frag for details on how
383*8975f5c5SAndroid Build Coastguard Worker // these values are derived.
CalculateBlitOffset(const UtilsVk::BlitResolveParameters & params,float offset[2])384*8975f5c5SAndroid Build Coastguard Worker void CalculateBlitOffset(const UtilsVk::BlitResolveParameters ¶ms, float offset[2])
385*8975f5c5SAndroid Build Coastguard Worker {
386*8975f5c5SAndroid Build Coastguard Worker int srcOffsetFactorX = params.flipX ? -1 : 1;
387*8975f5c5SAndroid Build Coastguard Worker int srcOffsetFactorY = params.flipY ? -1 : 1;
388*8975f5c5SAndroid Build Coastguard Worker
389*8975f5c5SAndroid Build Coastguard Worker offset[0] = params.dstOffset[0] * params.stretch[0] - params.srcOffset[0] * srcOffsetFactorX;
390*8975f5c5SAndroid Build Coastguard Worker offset[1] = params.dstOffset[1] * params.stretch[1] - params.srcOffset[1] * srcOffsetFactorY;
391*8975f5c5SAndroid Build Coastguard Worker }
392*8975f5c5SAndroid Build Coastguard Worker
CalculateResolveOffset(const UtilsVk::BlitResolveParameters & params,int32_t offset[2])393*8975f5c5SAndroid Build Coastguard Worker void CalculateResolveOffset(const UtilsVk::BlitResolveParameters ¶ms, int32_t offset[2])
394*8975f5c5SAndroid Build Coastguard Worker {
395*8975f5c5SAndroid Build Coastguard Worker int srcOffsetFactorX = params.flipX ? -1 : 1;
396*8975f5c5SAndroid Build Coastguard Worker int srcOffsetFactorY = params.flipY ? -1 : 1;
397*8975f5c5SAndroid Build Coastguard Worker
398*8975f5c5SAndroid Build Coastguard Worker // There's no stretching in resolve.
399*8975f5c5SAndroid Build Coastguard Worker offset[0] = params.dstOffset[0] - params.srcOffset[0] * srcOffsetFactorX;
400*8975f5c5SAndroid Build Coastguard Worker offset[1] = params.dstOffset[1] - params.srcOffset[1] * srcOffsetFactorY;
401*8975f5c5SAndroid Build Coastguard Worker }
402*8975f5c5SAndroid Build Coastguard Worker
SetDepthStateForWrite(vk::Renderer * renderer,vk::GraphicsPipelineDesc * desc)403*8975f5c5SAndroid Build Coastguard Worker void SetDepthStateForWrite(vk::Renderer *renderer, vk::GraphicsPipelineDesc *desc)
404*8975f5c5SAndroid Build Coastguard Worker {
405*8975f5c5SAndroid Build Coastguard Worker if (!renderer->getFeatures().useDepthTestEnableDynamicState.enabled)
406*8975f5c5SAndroid Build Coastguard Worker {
407*8975f5c5SAndroid Build Coastguard Worker desc->setDepthTestEnabled(VK_TRUE);
408*8975f5c5SAndroid Build Coastguard Worker }
409*8975f5c5SAndroid Build Coastguard Worker if (!renderer->getFeatures().useDepthWriteEnableDynamicState.enabled)
410*8975f5c5SAndroid Build Coastguard Worker {
411*8975f5c5SAndroid Build Coastguard Worker desc->setDepthWriteEnabled(VK_TRUE);
412*8975f5c5SAndroid Build Coastguard Worker }
413*8975f5c5SAndroid Build Coastguard Worker if (!renderer->getFeatures().useDepthCompareOpDynamicState.enabled)
414*8975f5c5SAndroid Build Coastguard Worker {
415*8975f5c5SAndroid Build Coastguard Worker desc->setDepthFunc(VK_COMPARE_OP_ALWAYS);
416*8975f5c5SAndroid Build Coastguard Worker }
417*8975f5c5SAndroid Build Coastguard Worker }
418*8975f5c5SAndroid Build Coastguard Worker
SetDepthStateForUnused(vk::Renderer * renderer,vk::GraphicsPipelineDesc * desc)419*8975f5c5SAndroid Build Coastguard Worker void SetDepthStateForUnused(vk::Renderer *renderer, vk::GraphicsPipelineDesc *desc)
420*8975f5c5SAndroid Build Coastguard Worker {
421*8975f5c5SAndroid Build Coastguard Worker if (!renderer->getFeatures().useDepthTestEnableDynamicState.enabled)
422*8975f5c5SAndroid Build Coastguard Worker {
423*8975f5c5SAndroid Build Coastguard Worker desc->setDepthTestEnabled(VK_FALSE);
424*8975f5c5SAndroid Build Coastguard Worker }
425*8975f5c5SAndroid Build Coastguard Worker if (!renderer->getFeatures().useDepthWriteEnableDynamicState.enabled)
426*8975f5c5SAndroid Build Coastguard Worker {
427*8975f5c5SAndroid Build Coastguard Worker desc->setDepthWriteEnabled(VK_FALSE);
428*8975f5c5SAndroid Build Coastguard Worker }
429*8975f5c5SAndroid Build Coastguard Worker }
430*8975f5c5SAndroid Build Coastguard Worker
SetDepthDynamicStateForWrite(vk::Renderer * renderer,vk::RenderPassCommandBuffer * commandBuffer)431*8975f5c5SAndroid Build Coastguard Worker void SetDepthDynamicStateForWrite(vk::Renderer *renderer,
432*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer)
433*8975f5c5SAndroid Build Coastguard Worker {
434*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useDepthTestEnableDynamicState.enabled)
435*8975f5c5SAndroid Build Coastguard Worker {
436*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setDepthTestEnable(VK_TRUE);
437*8975f5c5SAndroid Build Coastguard Worker }
438*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useDepthWriteEnableDynamicState.enabled)
439*8975f5c5SAndroid Build Coastguard Worker {
440*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setDepthWriteEnable(VK_TRUE);
441*8975f5c5SAndroid Build Coastguard Worker }
442*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useDepthCompareOpDynamicState.enabled)
443*8975f5c5SAndroid Build Coastguard Worker {
444*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setDepthCompareOp(VK_COMPARE_OP_ALWAYS);
445*8975f5c5SAndroid Build Coastguard Worker }
446*8975f5c5SAndroid Build Coastguard Worker }
447*8975f5c5SAndroid Build Coastguard Worker
SetDepthDynamicStateForUnused(vk::Renderer * renderer,vk::RenderPassCommandBuffer * commandBuffer)448*8975f5c5SAndroid Build Coastguard Worker void SetDepthDynamicStateForUnused(vk::Renderer *renderer,
449*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer)
450*8975f5c5SAndroid Build Coastguard Worker {
451*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useDepthTestEnableDynamicState.enabled)
452*8975f5c5SAndroid Build Coastguard Worker {
453*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setDepthTestEnable(VK_FALSE);
454*8975f5c5SAndroid Build Coastguard Worker }
455*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useDepthWriteEnableDynamicState.enabled)
456*8975f5c5SAndroid Build Coastguard Worker {
457*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setDepthWriteEnable(VK_FALSE);
458*8975f5c5SAndroid Build Coastguard Worker }
459*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useDepthCompareOpDynamicState.enabled)
460*8975f5c5SAndroid Build Coastguard Worker {
461*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setDepthCompareOp(VK_COMPARE_OP_ALWAYS);
462*8975f5c5SAndroid Build Coastguard Worker }
463*8975f5c5SAndroid Build Coastguard Worker }
464*8975f5c5SAndroid Build Coastguard Worker
465*8975f5c5SAndroid Build Coastguard Worker // Sets the appropriate settings in the pipeline for either the shader to output stencil, regardless
466*8975f5c5SAndroid Build Coastguard Worker // of whether its done through the reference value or the shader stencil export extension.
SetStencilStateForWrite(vk::Renderer * renderer,vk::GraphicsPipelineDesc * desc)467*8975f5c5SAndroid Build Coastguard Worker void SetStencilStateForWrite(vk::Renderer *renderer, vk::GraphicsPipelineDesc *desc)
468*8975f5c5SAndroid Build Coastguard Worker {
469*8975f5c5SAndroid Build Coastguard Worker if (!renderer->getFeatures().useStencilTestEnableDynamicState.enabled)
470*8975f5c5SAndroid Build Coastguard Worker {
471*8975f5c5SAndroid Build Coastguard Worker desc->setStencilTestEnabled(true);
472*8975f5c5SAndroid Build Coastguard Worker }
473*8975f5c5SAndroid Build Coastguard Worker if (!renderer->getFeatures().useStencilOpDynamicState.enabled)
474*8975f5c5SAndroid Build Coastguard Worker {
475*8975f5c5SAndroid Build Coastguard Worker desc->setStencilFrontFuncs(VK_COMPARE_OP_ALWAYS);
476*8975f5c5SAndroid Build Coastguard Worker desc->setStencilBackFuncs(VK_COMPARE_OP_ALWAYS);
477*8975f5c5SAndroid Build Coastguard Worker desc->setStencilFrontOps(VK_STENCIL_OP_REPLACE, VK_STENCIL_OP_REPLACE,
478*8975f5c5SAndroid Build Coastguard Worker VK_STENCIL_OP_REPLACE);
479*8975f5c5SAndroid Build Coastguard Worker desc->setStencilBackOps(VK_STENCIL_OP_REPLACE, VK_STENCIL_OP_REPLACE,
480*8975f5c5SAndroid Build Coastguard Worker VK_STENCIL_OP_REPLACE);
481*8975f5c5SAndroid Build Coastguard Worker }
482*8975f5c5SAndroid Build Coastguard Worker }
483*8975f5c5SAndroid Build Coastguard Worker
SetStencilDynamicStateForWrite(vk::Renderer * renderer,vk::RenderPassCommandBuffer * commandBuffer)484*8975f5c5SAndroid Build Coastguard Worker void SetStencilDynamicStateForWrite(vk::Renderer *renderer,
485*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer)
486*8975f5c5SAndroid Build Coastguard Worker {
487*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useStencilTestEnableDynamicState.enabled)
488*8975f5c5SAndroid Build Coastguard Worker {
489*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilTestEnable(true);
490*8975f5c5SAndroid Build Coastguard Worker }
491*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useStencilOpDynamicState.enabled)
492*8975f5c5SAndroid Build Coastguard Worker {
493*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilOp(VK_STENCIL_FACE_FRONT_BIT, VK_STENCIL_OP_REPLACE,
494*8975f5c5SAndroid Build Coastguard Worker VK_STENCIL_OP_REPLACE, VK_STENCIL_OP_REPLACE,
495*8975f5c5SAndroid Build Coastguard Worker VK_COMPARE_OP_ALWAYS);
496*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilOp(VK_STENCIL_FACE_BACK_BIT, VK_STENCIL_OP_REPLACE,
497*8975f5c5SAndroid Build Coastguard Worker VK_STENCIL_OP_REPLACE, VK_STENCIL_OP_REPLACE,
498*8975f5c5SAndroid Build Coastguard Worker VK_COMPARE_OP_ALWAYS);
499*8975f5c5SAndroid Build Coastguard Worker }
500*8975f5c5SAndroid Build Coastguard Worker }
501*8975f5c5SAndroid Build Coastguard Worker
SetStencilDynamicStateForUnused(vk::Renderer * renderer,vk::RenderPassCommandBuffer * commandBuffer)502*8975f5c5SAndroid Build Coastguard Worker void SetStencilDynamicStateForUnused(vk::Renderer *renderer,
503*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer)
504*8975f5c5SAndroid Build Coastguard Worker {
505*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useStencilTestEnableDynamicState.enabled)
506*8975f5c5SAndroid Build Coastguard Worker {
507*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilTestEnable(false);
508*8975f5c5SAndroid Build Coastguard Worker }
509*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useStencilOpDynamicState.enabled)
510*8975f5c5SAndroid Build Coastguard Worker {
511*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilOp(VK_STENCIL_FACE_FRONT_BIT, VK_STENCIL_OP_REPLACE,
512*8975f5c5SAndroid Build Coastguard Worker VK_STENCIL_OP_REPLACE, VK_STENCIL_OP_REPLACE,
513*8975f5c5SAndroid Build Coastguard Worker VK_COMPARE_OP_ALWAYS);
514*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilOp(VK_STENCIL_FACE_BACK_BIT, VK_STENCIL_OP_REPLACE,
515*8975f5c5SAndroid Build Coastguard Worker VK_STENCIL_OP_REPLACE, VK_STENCIL_OP_REPLACE,
516*8975f5c5SAndroid Build Coastguard Worker VK_COMPARE_OP_ALWAYS);
517*8975f5c5SAndroid Build Coastguard Worker }
518*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilCompareMask(0x00, 0x00);
519*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilWriteMask(0x00, 0x00);
520*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilReference(0x00, 0x00);
521*8975f5c5SAndroid Build Coastguard Worker }
522*8975f5c5SAndroid Build Coastguard Worker
HandlePrimitiveRestart(ContextVk * contextVk,gl::DrawElementsType glIndexType,GLsizei indexCount,const uint8_t * srcPtr,uint8_t * outPtr)523*8975f5c5SAndroid Build Coastguard Worker void HandlePrimitiveRestart(ContextVk *contextVk,
524*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType glIndexType,
525*8975f5c5SAndroid Build Coastguard Worker GLsizei indexCount,
526*8975f5c5SAndroid Build Coastguard Worker const uint8_t *srcPtr,
527*8975f5c5SAndroid Build Coastguard Worker uint8_t *outPtr)
528*8975f5c5SAndroid Build Coastguard Worker {
529*8975f5c5SAndroid Build Coastguard Worker switch (glIndexType)
530*8975f5c5SAndroid Build Coastguard Worker {
531*8975f5c5SAndroid Build Coastguard Worker case gl::DrawElementsType::UnsignedByte:
532*8975f5c5SAndroid Build Coastguard Worker if (contextVk->getFeatures().supportsIndexTypeUint8.enabled)
533*8975f5c5SAndroid Build Coastguard Worker {
534*8975f5c5SAndroid Build Coastguard Worker CopyLineLoopIndicesWithRestart<uint8_t, uint8_t>(indexCount, srcPtr, outPtr);
535*8975f5c5SAndroid Build Coastguard Worker }
536*8975f5c5SAndroid Build Coastguard Worker else
537*8975f5c5SAndroid Build Coastguard Worker {
538*8975f5c5SAndroid Build Coastguard Worker CopyLineLoopIndicesWithRestart<uint8_t, uint16_t>(indexCount, srcPtr, outPtr);
539*8975f5c5SAndroid Build Coastguard Worker }
540*8975f5c5SAndroid Build Coastguard Worker break;
541*8975f5c5SAndroid Build Coastguard Worker case gl::DrawElementsType::UnsignedShort:
542*8975f5c5SAndroid Build Coastguard Worker CopyLineLoopIndicesWithRestart<uint16_t, uint16_t>(indexCount, srcPtr, outPtr);
543*8975f5c5SAndroid Build Coastguard Worker break;
544*8975f5c5SAndroid Build Coastguard Worker case gl::DrawElementsType::UnsignedInt:
545*8975f5c5SAndroid Build Coastguard Worker CopyLineLoopIndicesWithRestart<uint32_t, uint32_t>(indexCount, srcPtr, outPtr);
546*8975f5c5SAndroid Build Coastguard Worker break;
547*8975f5c5SAndroid Build Coastguard Worker default:
548*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
549*8975f5c5SAndroid Build Coastguard Worker }
550*8975f5c5SAndroid Build Coastguard Worker }
551*8975f5c5SAndroid Build Coastguard Worker
552*8975f5c5SAndroid Build Coastguard Worker namespace unresolve
553*8975f5c5SAndroid Build Coastguard Worker {
554*8975f5c5SAndroid Build Coastguard Worker // The unresolve shader looks like the following, based on the number and types of unresolve
555*8975f5c5SAndroid Build Coastguard Worker // attachments. Note that stencil is placed first, to align with the ExportStencil shader, and
556*8975f5c5SAndroid Build Coastguard Worker // simplifying descriptor set creation.
557*8975f5c5SAndroid Build Coastguard Worker //
558*8975f5c5SAndroid Build Coastguard Worker // #version 450 core
559*8975f5c5SAndroid Build Coastguard Worker // #extension GL_ARB_shader_stencil_export : require
560*8975f5c5SAndroid Build Coastguard Worker //
561*8975f5c5SAndroid Build Coastguard Worker // layout(location = 0) out vec4 colorOut0;
562*8975f5c5SAndroid Build Coastguard Worker // layout(location = 1) out ivec4 colorOut1;
563*8975f5c5SAndroid Build Coastguard Worker // layout(location = 2) out uvec4 colorOut2;
564*8975f5c5SAndroid Build Coastguard Worker // layout(input_attachment_index = 0, set = 0, binding = 0) uniform usubpassInput stencilIn;
565*8975f5c5SAndroid Build Coastguard Worker // layout(input_attachment_index = 0, set = 0, binding = 1) uniform subpassInput depthIn;
566*8975f5c5SAndroid Build Coastguard Worker // layout(input_attachment_index = 1, set = 0, binding = 2) uniform subpassInput colorIn0;
567*8975f5c5SAndroid Build Coastguard Worker // layout(input_attachment_index = 2, set = 0, binding = 3) uniform isubpassInput colorIn1;
568*8975f5c5SAndroid Build Coastguard Worker // layout(input_attachment_index = 3, set = 0, binding = 4) uniform usubpassInput colorIn2;
569*8975f5c5SAndroid Build Coastguard Worker //
570*8975f5c5SAndroid Build Coastguard Worker // void main()
571*8975f5c5SAndroid Build Coastguard Worker // {
572*8975f5c5SAndroid Build Coastguard Worker // colorOut0 = subpassLoad(colorIn0);
573*8975f5c5SAndroid Build Coastguard Worker // colorOut1 = subpassLoad(colorIn1);
574*8975f5c5SAndroid Build Coastguard Worker // colorOut2 = subpassLoad(colorIn2);
575*8975f5c5SAndroid Build Coastguard Worker // gl_FragDepth = subpassLoad(depthIn).x;
576*8975f5c5SAndroid Build Coastguard Worker // gl_FragStencilRefARB = int(subpassLoad(stencilIn).x);
577*8975f5c5SAndroid Build Coastguard Worker // }
578*8975f5c5SAndroid Build Coastguard Worker //
579*8975f5c5SAndroid Build Coastguard Worker // This shader compiles to the following SPIR-V:
580*8975f5c5SAndroid Build Coastguard Worker //
581*8975f5c5SAndroid Build Coastguard Worker // OpCapability Shader \
582*8975f5c5SAndroid Build Coastguard Worker // OpCapability InputAttachment \
583*8975f5c5SAndroid Build Coastguard Worker // OpCapability StencilExportEXT \ Preamble. Mostly fixed, except
584*8975f5c5SAndroid Build Coastguard Worker // OpExtension "SPV_EXT_shader_stencil_export" \ OpEntryPoint should enumerate
585*8975f5c5SAndroid Build Coastguard Worker // %1 = OpExtInstImport "GLSL.std.450" \ out variables, stencil export
586*8975f5c5SAndroid Build Coastguard Worker // OpMemoryModel Logical GLSL450 / is conditional to stencil
587*8975f5c5SAndroid Build Coastguard Worker // OpEntryPoint Fragment %4 "main" %26 %27 %28 %29 %30 / unresolve, and depth replacing
588*8975f5c5SAndroid Build Coastguard Worker // OpExecutionMode %4 OriginUpperLeft / conditional to depth unresolve.
589*8975f5c5SAndroid Build Coastguard Worker // OpExecutionMode %4 DepthReplacing /
590*8975f5c5SAndroid Build Coastguard Worker // OpSource GLSL 450 /
591*8975f5c5SAndroid Build Coastguard Worker //
592*8975f5c5SAndroid Build Coastguard Worker // OpName %4 "main" \
593*8975f5c5SAndroid Build Coastguard Worker // OpName %26 "colorOut0" \
594*8975f5c5SAndroid Build Coastguard Worker // OpName %27 "colorOut1" \
595*8975f5c5SAndroid Build Coastguard Worker // OpName %28 "colorOut2" \
596*8975f5c5SAndroid Build Coastguard Worker // OpName %29 "gl_FragDepth" \ Debug information. Not generated here.
597*8975f5c5SAndroid Build Coastguard Worker // OpName %30 "gl_FragStencilRefARB" /
598*8975f5c5SAndroid Build Coastguard Worker // OpName %31 "colorIn0" /
599*8975f5c5SAndroid Build Coastguard Worker // OpName %32 "colorIn1" /
600*8975f5c5SAndroid Build Coastguard Worker // OpName %33 "colorIn2" /
601*8975f5c5SAndroid Build Coastguard Worker // OpName %34 "depthIn" /
602*8975f5c5SAndroid Build Coastguard Worker // OpName %35 "stencilIn" /
603*8975f5c5SAndroid Build Coastguard Worker //
604*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %26 Location 0 \
605*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %27 Location 1 \ Location decoration of out variables.
606*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %28 Location 2 /
607*8975f5c5SAndroid Build Coastguard Worker //
608*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %29 BuiltIn FragDepth \ Builtin outputs, conditional to depth
609*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %30 BuiltIn FragStencilRefEXT / and stencil unresolve.
610*8975f5c5SAndroid Build Coastguard Worker //
611*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %31 DescriptorSet 0 \
612*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %31 Binding 2 \
613*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %31 InputAttachmentIndex 1 \
614*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %32 DescriptorSet 0 \
615*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %32 Binding 3 \
616*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %32 InputAttachmentIndex 2 \
617*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %33 DescriptorSet 0 \ set, binding and input_attachment
618*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %33 Binding 4 \ decorations of the subpassInput
619*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %33 InputAttachmentIndex 3 / variables.
620*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %34 DescriptorSet 0 /
621*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %34 Binding 1 /
622*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %34 InputAttachmentIndex 0 /
623*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %35 DescriptorSet 0 /
624*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %35 Binding 0 /
625*8975f5c5SAndroid Build Coastguard Worker // OpDecorate %35 InputAttachmentIndex 0 /
626*8975f5c5SAndroid Build Coastguard Worker //
627*8975f5c5SAndroid Build Coastguard Worker // %2 = OpTypeVoid \ Type of main(). Fixed.
628*8975f5c5SAndroid Build Coastguard Worker // %3 = OpTypeFunction %2 /
629*8975f5c5SAndroid Build Coastguard Worker //
630*8975f5c5SAndroid Build Coastguard Worker // %6 = OpTypeFloat 32 \
631*8975f5c5SAndroid Build Coastguard Worker // %7 = OpTypeVector %6 4 \
632*8975f5c5SAndroid Build Coastguard Worker // %8 = OpTypePointer Output %7 \ Type declaration for "out vec4"
633*8975f5c5SAndroid Build Coastguard Worker // %9 = OpTypeImage %6 SubpassData 0 0 0 2 Unknown / and "subpassInput". Fixed.
634*8975f5c5SAndroid Build Coastguard Worker // %10 = OpTypePointer UniformConstant %9 /
635*8975f5c5SAndroid Build Coastguard Worker //
636*8975f5c5SAndroid Build Coastguard Worker // %11 = OpTypeInt 32 1 \
637*8975f5c5SAndroid Build Coastguard Worker // %12 = OpTypeVector %11 4 \
638*8975f5c5SAndroid Build Coastguard Worker // %13 = OpTypePointer Output %12 \ Type declaration for "out ivec4"
639*8975f5c5SAndroid Build Coastguard Worker // %14 = OpTypeImage %11 SubpassData 0 0 0 2 Unknown / and "isubpassInput". Fixed.
640*8975f5c5SAndroid Build Coastguard Worker // %15 = OpTypePointer UniformConstant %14 /
641*8975f5c5SAndroid Build Coastguard Worker //
642*8975f5c5SAndroid Build Coastguard Worker // %16 = OpTypeInt 32 0 \
643*8975f5c5SAndroid Build Coastguard Worker // %17 = OpTypeVector %16 4 \
644*8975f5c5SAndroid Build Coastguard Worker // %18 = OpTypePointer Output %17 \ Type declaration for "out uvec4"
645*8975f5c5SAndroid Build Coastguard Worker // %19 = OpTypeImage %16 SubpassData 0 0 0 2 Unknown / and "usubpassInput". Fixed.
646*8975f5c5SAndroid Build Coastguard Worker // %20 = OpTypePointer UniformConstant %19 /
647*8975f5c5SAndroid Build Coastguard Worker //
648*8975f5c5SAndroid Build Coastguard Worker // %21 = OpTypePointer Output %6 \ Type declaraions for depth and stencil. Fixed.
649*8975f5c5SAndroid Build Coastguard Worker // %22 = OpTypePointer Output %11 /
650*8975f5c5SAndroid Build Coastguard Worker //
651*8975f5c5SAndroid Build Coastguard Worker // %23 = OpConstant %11 0 \
652*8975f5c5SAndroid Build Coastguard Worker // %24 = OpTypeVector %11 2 \ ivec2(0) for OpImageRead. subpassLoad
653*8975f5c5SAndroid Build Coastguard Worker // %25 = OpConstantComposite %22 %21 %21 / doesn't require coordinates. Fixed.
654*8975f5c5SAndroid Build Coastguard Worker //
655*8975f5c5SAndroid Build Coastguard Worker // %26 = OpVariable %8 Output \
656*8975f5c5SAndroid Build Coastguard Worker // %27 = OpVariable %13 Output \
657*8975f5c5SAndroid Build Coastguard Worker // %28 = OpVariable %18 Output \
658*8975f5c5SAndroid Build Coastguard Worker // %29 = OpVariable %21 Output \
659*8975f5c5SAndroid Build Coastguard Worker // %30 = OpVariable %22 Output \ Actual "out" and "*subpassInput"
660*8975f5c5SAndroid Build Coastguard Worker // %31 = OpVariable %10 UniformConstant / variable declarations.
661*8975f5c5SAndroid Build Coastguard Worker // %32 = OpVariable %15 UniformConstant /
662*8975f5c5SAndroid Build Coastguard Worker // %33 = OpVariable %20 UniformConstant /
663*8975f5c5SAndroid Build Coastguard Worker // %34 = OpVariable %10 UniformConstant /
664*8975f5c5SAndroid Build Coastguard Worker // %35 = OpVariable %20 UniformConstant /
665*8975f5c5SAndroid Build Coastguard Worker //
666*8975f5c5SAndroid Build Coastguard Worker // %4 = OpFunction %2 None %3 \ Top of main(). Fixed.
667*8975f5c5SAndroid Build Coastguard Worker // %5 = OpLabel /
668*8975f5c5SAndroid Build Coastguard Worker //
669*8975f5c5SAndroid Build Coastguard Worker // %36 = OpLoad %9 %31 \
670*8975f5c5SAndroid Build Coastguard Worker // %37 = OpImageRead %7 %36 %23 \ colorOut0 = subpassLoad(colorIn0);
671*8975f5c5SAndroid Build Coastguard Worker // OpStore %26 %37 /
672*8975f5c5SAndroid Build Coastguard Worker //
673*8975f5c5SAndroid Build Coastguard Worker // %38 = OpLoad %14 %32 \
674*8975f5c5SAndroid Build Coastguard Worker // %39 = OpImageRead %12 %38 %23 \ colorOut1 = subpassLoad(colorIn1);
675*8975f5c5SAndroid Build Coastguard Worker // OpStore %27 %39 /
676*8975f5c5SAndroid Build Coastguard Worker //
677*8975f5c5SAndroid Build Coastguard Worker // %40 = OpLoad %19 %33 \
678*8975f5c5SAndroid Build Coastguard Worker // %41 = OpImageRead %17 %40 %23 \ colorOut2 = subpassLoad(colorIn2);
679*8975f5c5SAndroid Build Coastguard Worker // OpStore %28 %41 /
680*8975f5c5SAndroid Build Coastguard Worker //
681*8975f5c5SAndroid Build Coastguard Worker // %42 = OpLoad %9 %34 \
682*8975f5c5SAndroid Build Coastguard Worker // %43 = OpImageRead %7 %42 %23 \ gl_FragDepth = subpassLoad(depthIn).x;
683*8975f5c5SAndroid Build Coastguard Worker // %44 = OpCompositeExtract %6 %43 0 /
684*8975f5c5SAndroid Build Coastguard Worker // OpStore %29 %44 /
685*8975f5c5SAndroid Build Coastguard Worker //
686*8975f5c5SAndroid Build Coastguard Worker // %45 = OpLoad %19 %35 \
687*8975f5c5SAndroid Build Coastguard Worker // %46 = OpImageRead %17 %45 %23 \
688*8975f5c5SAndroid Build Coastguard Worker // %47 = OpCompositeExtract %16 %46 0 \ gl_FragStencilRefARB = int(subpassLoad(stencilIn).x);
689*8975f5c5SAndroid Build Coastguard Worker // %48 = OpBitcast %11 %47 /
690*8975f5c5SAndroid Build Coastguard Worker // OpStore %30 %48 /
691*8975f5c5SAndroid Build Coastguard Worker //
692*8975f5c5SAndroid Build Coastguard Worker // OpReturn \ Bottom of main(). Fixed.
693*8975f5c5SAndroid Build Coastguard Worker // OpFunctionEnd /
694*8975f5c5SAndroid Build Coastguard Worker //
695*8975f5c5SAndroid Build Coastguard Worker // What makes the generation of this shader manageable is that the majority of it is constant
696*8975f5c5SAndroid Build Coastguard Worker // between the different variations of the shader. The rest are repeating patterns with different
697*8975f5c5SAndroid Build Coastguard Worker // ids or indices.
698*8975f5c5SAndroid Build Coastguard Worker
699*8975f5c5SAndroid Build Coastguard Worker enum
700*8975f5c5SAndroid Build Coastguard Worker {
701*8975f5c5SAndroid Build Coastguard Worker // main() ids
702*8975f5c5SAndroid Build Coastguard Worker kIdExtInstImport = 1,
703*8975f5c5SAndroid Build Coastguard Worker kIdVoid,
704*8975f5c5SAndroid Build Coastguard Worker kIdMainType,
705*8975f5c5SAndroid Build Coastguard Worker kIdMain,
706*8975f5c5SAndroid Build Coastguard Worker kIdMainLabel,
707*8975f5c5SAndroid Build Coastguard Worker
708*8975f5c5SAndroid Build Coastguard Worker // Types for "out vec4" and "subpassInput"
709*8975f5c5SAndroid Build Coastguard Worker kIdFloatType,
710*8975f5c5SAndroid Build Coastguard Worker kIdFloat4Type,
711*8975f5c5SAndroid Build Coastguard Worker kIdFloat4OutType,
712*8975f5c5SAndroid Build Coastguard Worker kIdFloatSubpassImageType,
713*8975f5c5SAndroid Build Coastguard Worker kIdFloatSubpassInputType,
714*8975f5c5SAndroid Build Coastguard Worker
715*8975f5c5SAndroid Build Coastguard Worker // Types for "out ivec4" and "isubpassInput"
716*8975f5c5SAndroid Build Coastguard Worker kIdSIntType,
717*8975f5c5SAndroid Build Coastguard Worker kIdSInt4Type,
718*8975f5c5SAndroid Build Coastguard Worker kIdSInt4OutType,
719*8975f5c5SAndroid Build Coastguard Worker kIdSIntSubpassImageType,
720*8975f5c5SAndroid Build Coastguard Worker kIdSIntSubpassInputType,
721*8975f5c5SAndroid Build Coastguard Worker
722*8975f5c5SAndroid Build Coastguard Worker // Types for "out uvec4" and "usubpassInput"
723*8975f5c5SAndroid Build Coastguard Worker kIdUIntType,
724*8975f5c5SAndroid Build Coastguard Worker kIdUInt4Type,
725*8975f5c5SAndroid Build Coastguard Worker kIdUInt4OutType,
726*8975f5c5SAndroid Build Coastguard Worker kIdUIntSubpassImageType,
727*8975f5c5SAndroid Build Coastguard Worker kIdUIntSubpassInputType,
728*8975f5c5SAndroid Build Coastguard Worker
729*8975f5c5SAndroid Build Coastguard Worker // Types for gl_FragDepth && gl_FragStencilRefARB
730*8975f5c5SAndroid Build Coastguard Worker kIdFloatOutType,
731*8975f5c5SAndroid Build Coastguard Worker kIdSIntOutType,
732*8975f5c5SAndroid Build Coastguard Worker
733*8975f5c5SAndroid Build Coastguard Worker // ivec2(0) constant
734*8975f5c5SAndroid Build Coastguard Worker kIdSIntZero,
735*8975f5c5SAndroid Build Coastguard Worker kIdSInt2Type,
736*8975f5c5SAndroid Build Coastguard Worker kIdSInt2Zero,
737*8975f5c5SAndroid Build Coastguard Worker
738*8975f5c5SAndroid Build Coastguard Worker // Output variable ids
739*8975f5c5SAndroid Build Coastguard Worker kIdColor0Out,
740*8975f5c5SAndroid Build Coastguard Worker kIdDepthOut = kIdColor0Out + gl::IMPLEMENTATION_MAX_DRAW_BUFFERS,
741*8975f5c5SAndroid Build Coastguard Worker kIdStencilOut,
742*8975f5c5SAndroid Build Coastguard Worker
743*8975f5c5SAndroid Build Coastguard Worker // Input variable ids
744*8975f5c5SAndroid Build Coastguard Worker kIdColor0In,
745*8975f5c5SAndroid Build Coastguard Worker kIdDepthIn = kIdColor0In + gl::IMPLEMENTATION_MAX_DRAW_BUFFERS,
746*8975f5c5SAndroid Build Coastguard Worker kIdStencilIn,
747*8975f5c5SAndroid Build Coastguard Worker
748*8975f5c5SAndroid Build Coastguard Worker // Ids for temp variables
749*8975f5c5SAndroid Build Coastguard Worker kIdColor0Load,
750*8975f5c5SAndroid Build Coastguard Worker // 2 temp ids per color unresolve
751*8975f5c5SAndroid Build Coastguard Worker kIdDepthLoad = kIdColor0Load + gl::IMPLEMENTATION_MAX_DRAW_BUFFERS * 2,
752*8975f5c5SAndroid Build Coastguard Worker // 3 temp ids for depth unresolve
753*8975f5c5SAndroid Build Coastguard Worker kIdStencilLoad = kIdDepthLoad + 3,
754*8975f5c5SAndroid Build Coastguard Worker // Total number of ids used
755*8975f5c5SAndroid Build Coastguard Worker // 4 temp ids for stencil unresolve
756*8975f5c5SAndroid Build Coastguard Worker kIdCount = kIdStencilLoad + 4,
757*8975f5c5SAndroid Build Coastguard Worker };
758*8975f5c5SAndroid Build Coastguard Worker
InsertPreamble(uint32_t colorAttachmentCount,bool unresolveDepth,bool unresolveStencil,angle::spirv::Blob * blobOut)759*8975f5c5SAndroid Build Coastguard Worker void InsertPreamble(uint32_t colorAttachmentCount,
760*8975f5c5SAndroid Build Coastguard Worker bool unresolveDepth,
761*8975f5c5SAndroid Build Coastguard Worker bool unresolveStencil,
762*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob *blobOut)
763*8975f5c5SAndroid Build Coastguard Worker {
764*8975f5c5SAndroid Build Coastguard Worker spirv::WriteCapability(blobOut, spv::CapabilityShader);
765*8975f5c5SAndroid Build Coastguard Worker spirv::WriteCapability(blobOut, spv::CapabilityInputAttachment);
766*8975f5c5SAndroid Build Coastguard Worker if (unresolveStencil)
767*8975f5c5SAndroid Build Coastguard Worker {
768*8975f5c5SAndroid Build Coastguard Worker spirv::WriteCapability(blobOut, spv::CapabilityStencilExportEXT);
769*8975f5c5SAndroid Build Coastguard Worker spirv::WriteExtension(blobOut, "SPV_EXT_shader_stencil_export");
770*8975f5c5SAndroid Build Coastguard Worker }
771*8975f5c5SAndroid Build Coastguard Worker // OpExtInstImport is actually not needed by this shader. We don't use any instructions from
772*8975f5c5SAndroid Build Coastguard Worker // GLSL.std.450.
773*8975f5c5SAndroid Build Coastguard Worker spirv::WriteMemoryModel(blobOut, spv::AddressingModelLogical, spv::MemoryModelGLSL450);
774*8975f5c5SAndroid Build Coastguard Worker
775*8975f5c5SAndroid Build Coastguard Worker // Create the list of entry point ids, including only the out variables.
776*8975f5c5SAndroid Build Coastguard Worker spirv::IdRefList entryPointIds;
777*8975f5c5SAndroid Build Coastguard Worker for (uint32_t colorIndex = 0; colorIndex < colorAttachmentCount; ++colorIndex)
778*8975f5c5SAndroid Build Coastguard Worker {
779*8975f5c5SAndroid Build Coastguard Worker entryPointIds.push_back(spirv::IdRef(kIdColor0Out + colorIndex));
780*8975f5c5SAndroid Build Coastguard Worker }
781*8975f5c5SAndroid Build Coastguard Worker if (unresolveDepth)
782*8975f5c5SAndroid Build Coastguard Worker {
783*8975f5c5SAndroid Build Coastguard Worker entryPointIds.push_back(spirv::IdRef(kIdDepthOut));
784*8975f5c5SAndroid Build Coastguard Worker }
785*8975f5c5SAndroid Build Coastguard Worker if (unresolveStencil)
786*8975f5c5SAndroid Build Coastguard Worker {
787*8975f5c5SAndroid Build Coastguard Worker entryPointIds.push_back(spirv::IdRef(kIdStencilOut));
788*8975f5c5SAndroid Build Coastguard Worker }
789*8975f5c5SAndroid Build Coastguard Worker spirv::WriteEntryPoint(blobOut, spv::ExecutionModelFragment, spirv::IdRef(kIdMain), "main",
790*8975f5c5SAndroid Build Coastguard Worker entryPointIds);
791*8975f5c5SAndroid Build Coastguard Worker
792*8975f5c5SAndroid Build Coastguard Worker spirv::WriteExecutionMode(blobOut, spirv::IdRef(kIdMain), spv::ExecutionModeOriginUpperLeft,
793*8975f5c5SAndroid Build Coastguard Worker {});
794*8975f5c5SAndroid Build Coastguard Worker if (unresolveDepth)
795*8975f5c5SAndroid Build Coastguard Worker {
796*8975f5c5SAndroid Build Coastguard Worker spirv::WriteExecutionMode(blobOut, spirv::IdRef(kIdMain), spv::ExecutionModeDepthReplacing,
797*8975f5c5SAndroid Build Coastguard Worker {});
798*8975f5c5SAndroid Build Coastguard Worker }
799*8975f5c5SAndroid Build Coastguard Worker spirv::WriteSource(blobOut, spv::SourceLanguageGLSL, spirv::LiteralInteger(450), nullptr,
800*8975f5c5SAndroid Build Coastguard Worker nullptr);
801*8975f5c5SAndroid Build Coastguard Worker }
802*8975f5c5SAndroid Build Coastguard Worker
InsertInputDecorations(spirv::IdRef id,uint32_t attachmentIndex,uint32_t binding,angle::spirv::Blob * blobOut)803*8975f5c5SAndroid Build Coastguard Worker void InsertInputDecorations(spirv::IdRef id,
804*8975f5c5SAndroid Build Coastguard Worker uint32_t attachmentIndex,
805*8975f5c5SAndroid Build Coastguard Worker uint32_t binding,
806*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob *blobOut)
807*8975f5c5SAndroid Build Coastguard Worker {
808*8975f5c5SAndroid Build Coastguard Worker spirv::WriteDecorate(blobOut, id, spv::DecorationDescriptorSet,
809*8975f5c5SAndroid Build Coastguard Worker {spirv::LiteralInteger(ToUnderlying(DescriptorSetIndex::Internal))});
810*8975f5c5SAndroid Build Coastguard Worker spirv::WriteDecorate(blobOut, id, spv::DecorationBinding, {spirv::LiteralInteger(binding)});
811*8975f5c5SAndroid Build Coastguard Worker spirv::WriteDecorate(blobOut, id, spv::DecorationInputAttachmentIndex,
812*8975f5c5SAndroid Build Coastguard Worker {spirv::LiteralInteger(attachmentIndex)});
813*8975f5c5SAndroid Build Coastguard Worker }
814*8975f5c5SAndroid Build Coastguard Worker
InsertColorDecorations(uint32_t colorIndex,uint32_t colorInputIndexStart,uint32_t colorBindingIndexStart,angle::spirv::Blob * blobOut)815*8975f5c5SAndroid Build Coastguard Worker void InsertColorDecorations(uint32_t colorIndex,
816*8975f5c5SAndroid Build Coastguard Worker uint32_t colorInputIndexStart,
817*8975f5c5SAndroid Build Coastguard Worker uint32_t colorBindingIndexStart,
818*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob *blobOut)
819*8975f5c5SAndroid Build Coastguard Worker {
820*8975f5c5SAndroid Build Coastguard Worker // Decorate the output color attachment with Location
821*8975f5c5SAndroid Build Coastguard Worker spirv::WriteDecorate(blobOut, spirv::IdRef(kIdColor0Out + colorIndex), spv::DecorationLocation,
822*8975f5c5SAndroid Build Coastguard Worker {spirv::LiteralInteger(colorIndex)});
823*8975f5c5SAndroid Build Coastguard Worker // Decorate the subpasss input color attachment with Set/Binding/InputAttachmentIndex.
824*8975f5c5SAndroid Build Coastguard Worker InsertInputDecorations(spirv::IdRef(kIdColor0In + colorIndex),
825*8975f5c5SAndroid Build Coastguard Worker colorIndex + colorInputIndexStart, colorIndex + colorBindingIndexStart,
826*8975f5c5SAndroid Build Coastguard Worker blobOut);
827*8975f5c5SAndroid Build Coastguard Worker }
828*8975f5c5SAndroid Build Coastguard Worker
InsertDepthStencilDecorations(bool unresolveDepth,bool unresolveStencil,bool supportsShaderStencilExport,uint32_t * nextInputIndex,uint32_t * nextBindingIndex,angle::spirv::Blob * blobOut)829*8975f5c5SAndroid Build Coastguard Worker void InsertDepthStencilDecorations(bool unresolveDepth,
830*8975f5c5SAndroid Build Coastguard Worker bool unresolveStencil,
831*8975f5c5SAndroid Build Coastguard Worker bool supportsShaderStencilExport,
832*8975f5c5SAndroid Build Coastguard Worker uint32_t *nextInputIndex,
833*8975f5c5SAndroid Build Coastguard Worker uint32_t *nextBindingIndex,
834*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob *blobOut)
835*8975f5c5SAndroid Build Coastguard Worker {
836*8975f5c5SAndroid Build Coastguard Worker if (unresolveStencil && supportsShaderStencilExport)
837*8975f5c5SAndroid Build Coastguard Worker {
838*8975f5c5SAndroid Build Coastguard Worker // Make sure unresolve desc set is compatible with the ExportStencil shader.
839*8975f5c5SAndroid Build Coastguard Worker ASSERT(*nextInputIndex == kExportStencilInputIndex);
840*8975f5c5SAndroid Build Coastguard Worker ASSERT(*nextBindingIndex == kExportStencilBinding);
841*8975f5c5SAndroid Build Coastguard Worker
842*8975f5c5SAndroid Build Coastguard Worker // Decorate the output stencil attachment with Location
843*8975f5c5SAndroid Build Coastguard Worker spirv::WriteDecorate(blobOut, spirv::IdRef(kIdStencilOut), spv::DecorationBuiltIn,
844*8975f5c5SAndroid Build Coastguard Worker {spirv::LiteralInteger(spv::BuiltInFragStencilRefEXT)});
845*8975f5c5SAndroid Build Coastguard Worker // Decorate the subpasss input stencil attachment with Set/Binding/InputAttachmentIndex.
846*8975f5c5SAndroid Build Coastguard Worker InsertInputDecorations(spirv::IdRef(kIdStencilIn), *nextInputIndex, *nextBindingIndex,
847*8975f5c5SAndroid Build Coastguard Worker blobOut);
848*8975f5c5SAndroid Build Coastguard Worker
849*8975f5c5SAndroid Build Coastguard Worker // Advance the binding. Note that the depth/stencil attachment has the same input
850*8975f5c5SAndroid Build Coastguard Worker // attachment index (it's the same attachment in the subpass), but different bindings (one
851*8975f5c5SAndroid Build Coastguard Worker // aspect per image view).
852*8975f5c5SAndroid Build Coastguard Worker ++*nextBindingIndex;
853*8975f5c5SAndroid Build Coastguard Worker }
854*8975f5c5SAndroid Build Coastguard Worker if (unresolveDepth)
855*8975f5c5SAndroid Build Coastguard Worker {
856*8975f5c5SAndroid Build Coastguard Worker // Decorate the output depth attachment with Location
857*8975f5c5SAndroid Build Coastguard Worker spirv::WriteDecorate(blobOut, spirv::IdRef(kIdDepthOut), spv::DecorationBuiltIn,
858*8975f5c5SAndroid Build Coastguard Worker {spirv::LiteralInteger(spv::BuiltInFragDepth)});
859*8975f5c5SAndroid Build Coastguard Worker // Decorate the subpasss input depth attachment with Set/Binding/InputAttachmentIndex.
860*8975f5c5SAndroid Build Coastguard Worker InsertInputDecorations(spirv::IdRef(kIdDepthIn), *nextInputIndex, *nextBindingIndex,
861*8975f5c5SAndroid Build Coastguard Worker blobOut);
862*8975f5c5SAndroid Build Coastguard Worker
863*8975f5c5SAndroid Build Coastguard Worker ++*nextBindingIndex;
864*8975f5c5SAndroid Build Coastguard Worker }
865*8975f5c5SAndroid Build Coastguard Worker
866*8975f5c5SAndroid Build Coastguard Worker if (unresolveDepth || unresolveStencil)
867*8975f5c5SAndroid Build Coastguard Worker {
868*8975f5c5SAndroid Build Coastguard Worker // Even if stencil is taking a special path and is not being unresolved with color and
869*8975f5c5SAndroid Build Coastguard Worker // depth, the input index is still consumed so the ExportStencil shader can operate on it.
870*8975f5c5SAndroid Build Coastguard Worker ++*nextInputIndex;
871*8975f5c5SAndroid Build Coastguard Worker }
872*8975f5c5SAndroid Build Coastguard Worker }
873*8975f5c5SAndroid Build Coastguard Worker
InsertDerivativeTypes(spirv::IdRef baseId,spirv::IdRef vec4Id,spirv::IdRef vec4OutId,spirv::IdRef imageTypeId,spirv::IdRef inputTypeId,angle::spirv::Blob * blobOut)874*8975f5c5SAndroid Build Coastguard Worker void InsertDerivativeTypes(spirv::IdRef baseId,
875*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef vec4Id,
876*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef vec4OutId,
877*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef imageTypeId,
878*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef inputTypeId,
879*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob *blobOut)
880*8975f5c5SAndroid Build Coastguard Worker {
881*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypeVector(blobOut, vec4Id, baseId, spirv::LiteralInteger(4));
882*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypePointer(blobOut, vec4OutId, spv::StorageClassOutput, vec4Id);
883*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypeImage(blobOut, imageTypeId, baseId, spv::DimSubpassData,
884*8975f5c5SAndroid Build Coastguard Worker // Unused with subpass inputs
885*8975f5c5SAndroid Build Coastguard Worker spirv::LiteralInteger(0),
886*8975f5c5SAndroid Build Coastguard Worker // Not arrayed
887*8975f5c5SAndroid Build Coastguard Worker spirv::LiteralInteger(0),
888*8975f5c5SAndroid Build Coastguard Worker // Not multisampled
889*8975f5c5SAndroid Build Coastguard Worker spirv::LiteralInteger(0),
890*8975f5c5SAndroid Build Coastguard Worker // Used without a sampler
891*8975f5c5SAndroid Build Coastguard Worker spirv::LiteralInteger(2), spv::ImageFormatUnknown, nullptr);
892*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypePointer(blobOut, inputTypeId, spv::StorageClassUniformConstant, imageTypeId);
893*8975f5c5SAndroid Build Coastguard Worker }
894*8975f5c5SAndroid Build Coastguard Worker
InsertCommonTypes(angle::spirv::Blob * blobOut)895*8975f5c5SAndroid Build Coastguard Worker void InsertCommonTypes(angle::spirv::Blob *blobOut)
896*8975f5c5SAndroid Build Coastguard Worker {
897*8975f5c5SAndroid Build Coastguard Worker // Types to support main().
898*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypeVoid(blobOut, spirv::IdRef(kIdVoid));
899*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypeFunction(blobOut, spirv::IdRef(kIdMainType), spirv::IdRef(kIdVoid), {});
900*8975f5c5SAndroid Build Coastguard Worker
901*8975f5c5SAndroid Build Coastguard Worker // Float types
902*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypeFloat(blobOut, spirv::IdRef(kIdFloatType), spirv::LiteralInteger(32), nullptr);
903*8975f5c5SAndroid Build Coastguard Worker InsertDerivativeTypes(spirv::IdRef(kIdFloatType), spirv::IdRef(kIdFloat4Type),
904*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdFloat4OutType), spirv::IdRef(kIdFloatSubpassImageType),
905*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdFloatSubpassInputType), blobOut);
906*8975f5c5SAndroid Build Coastguard Worker
907*8975f5c5SAndroid Build Coastguard Worker // Int types
908*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypeInt(blobOut, spirv::IdRef(kIdSIntType), spirv::LiteralInteger(32),
909*8975f5c5SAndroid Build Coastguard Worker spirv::LiteralInteger(1));
910*8975f5c5SAndroid Build Coastguard Worker InsertDerivativeTypes(spirv::IdRef(kIdSIntType), spirv::IdRef(kIdSInt4Type),
911*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdSInt4OutType), spirv::IdRef(kIdSIntSubpassImageType),
912*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdSIntSubpassInputType), blobOut);
913*8975f5c5SAndroid Build Coastguard Worker
914*8975f5c5SAndroid Build Coastguard Worker // Unsigned int types
915*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypeInt(blobOut, spirv::IdRef(kIdUIntType), spirv::LiteralInteger(32),
916*8975f5c5SAndroid Build Coastguard Worker spirv::LiteralInteger(0));
917*8975f5c5SAndroid Build Coastguard Worker InsertDerivativeTypes(spirv::IdRef(kIdUIntType), spirv::IdRef(kIdUInt4Type),
918*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdUInt4OutType), spirv::IdRef(kIdUIntSubpassImageType),
919*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdUIntSubpassInputType), blobOut);
920*8975f5c5SAndroid Build Coastguard Worker
921*8975f5c5SAndroid Build Coastguard Worker // Types to support depth/stencil
922*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypePointer(blobOut, spirv::IdRef(kIdFloatOutType), spv::StorageClassOutput,
923*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdFloatType));
924*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypePointer(blobOut, spirv::IdRef(kIdSIntOutType), spv::StorageClassOutput,
925*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdSIntType));
926*8975f5c5SAndroid Build Coastguard Worker
927*8975f5c5SAndroid Build Coastguard Worker // Constants used to load from subpass inputs
928*8975f5c5SAndroid Build Coastguard Worker spirv::WriteConstant(blobOut, spirv::IdRef(kIdSIntType), spirv::IdRef(kIdSIntZero),
929*8975f5c5SAndroid Build Coastguard Worker spirv::LiteralInteger(0));
930*8975f5c5SAndroid Build Coastguard Worker spirv::WriteTypeVector(blobOut, spirv::IdRef(kIdSInt2Type), spirv::IdRef(kIdSIntType),
931*8975f5c5SAndroid Build Coastguard Worker spirv::LiteralInteger(2));
932*8975f5c5SAndroid Build Coastguard Worker spirv::WriteConstantComposite(blobOut, spirv::IdRef(kIdSInt2Type), spirv::IdRef(kIdSInt2Zero),
933*8975f5c5SAndroid Build Coastguard Worker {spirv::IdRef(kIdSIntZero), spirv::IdRef(kIdSIntZero)});
934*8975f5c5SAndroid Build Coastguard Worker }
935*8975f5c5SAndroid Build Coastguard Worker
InsertVariableDecl(spirv::IdRef outType,spirv::IdRef outId,spirv::IdRef inType,spirv::IdRef inId,angle::spirv::Blob * blobOut)936*8975f5c5SAndroid Build Coastguard Worker void InsertVariableDecl(spirv::IdRef outType,
937*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef outId,
938*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef inType,
939*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef inId,
940*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob *blobOut)
941*8975f5c5SAndroid Build Coastguard Worker {
942*8975f5c5SAndroid Build Coastguard Worker // Declare both the output and subpass input variables.
943*8975f5c5SAndroid Build Coastguard Worker spirv::WriteVariable(blobOut, outType, outId, spv::StorageClassOutput, nullptr);
944*8975f5c5SAndroid Build Coastguard Worker spirv::WriteVariable(blobOut, inType, inId, spv::StorageClassUniformConstant, nullptr);
945*8975f5c5SAndroid Build Coastguard Worker }
946*8975f5c5SAndroid Build Coastguard Worker
InsertColorVariableDecl(uint32_t colorIndex,UnresolveColorAttachmentType type,angle::spirv::Blob * blobOut)947*8975f5c5SAndroid Build Coastguard Worker void InsertColorVariableDecl(uint32_t colorIndex,
948*8975f5c5SAndroid Build Coastguard Worker UnresolveColorAttachmentType type,
949*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob *blobOut)
950*8975f5c5SAndroid Build Coastguard Worker {
951*8975f5c5SAndroid Build Coastguard Worker // Find the correct types for color variable declarations.
952*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef outType(kIdFloat4OutType);
953*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef outId(kIdColor0Out + colorIndex);
954*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef inType(kIdFloatSubpassInputType);
955*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef inId(kIdColor0In + colorIndex);
956*8975f5c5SAndroid Build Coastguard Worker switch (type)
957*8975f5c5SAndroid Build Coastguard Worker {
958*8975f5c5SAndroid Build Coastguard Worker case kUnresolveTypeSint:
959*8975f5c5SAndroid Build Coastguard Worker outType = spirv::IdRef(kIdSInt4OutType);
960*8975f5c5SAndroid Build Coastguard Worker inType = spirv::IdRef(kIdSIntSubpassInputType);
961*8975f5c5SAndroid Build Coastguard Worker break;
962*8975f5c5SAndroid Build Coastguard Worker case kUnresolveTypeUint:
963*8975f5c5SAndroid Build Coastguard Worker outType = spirv::IdRef(kIdUInt4OutType);
964*8975f5c5SAndroid Build Coastguard Worker inType = spirv::IdRef(kIdUIntSubpassInputType);
965*8975f5c5SAndroid Build Coastguard Worker break;
966*8975f5c5SAndroid Build Coastguard Worker default:
967*8975f5c5SAndroid Build Coastguard Worker break;
968*8975f5c5SAndroid Build Coastguard Worker }
969*8975f5c5SAndroid Build Coastguard Worker InsertVariableDecl(outType, outId, inType, inId, blobOut);
970*8975f5c5SAndroid Build Coastguard Worker }
971*8975f5c5SAndroid Build Coastguard Worker
InsertDepthStencilVariableDecl(bool unresolveDepth,bool unresolveStencil,angle::spirv::Blob * blobOut)972*8975f5c5SAndroid Build Coastguard Worker void InsertDepthStencilVariableDecl(bool unresolveDepth,
973*8975f5c5SAndroid Build Coastguard Worker bool unresolveStencil,
974*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob *blobOut)
975*8975f5c5SAndroid Build Coastguard Worker {
976*8975f5c5SAndroid Build Coastguard Worker if (unresolveDepth)
977*8975f5c5SAndroid Build Coastguard Worker {
978*8975f5c5SAndroid Build Coastguard Worker InsertVariableDecl(spirv::IdRef(kIdFloatOutType), spirv::IdRef(kIdDepthOut),
979*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdFloatSubpassInputType), spirv::IdRef(kIdDepthIn),
980*8975f5c5SAndroid Build Coastguard Worker blobOut);
981*8975f5c5SAndroid Build Coastguard Worker }
982*8975f5c5SAndroid Build Coastguard Worker if (unresolveStencil)
983*8975f5c5SAndroid Build Coastguard Worker {
984*8975f5c5SAndroid Build Coastguard Worker InsertVariableDecl(spirv::IdRef(kIdSIntOutType), spirv::IdRef(kIdStencilOut),
985*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdUIntSubpassInputType), spirv::IdRef(kIdStencilIn),
986*8975f5c5SAndroid Build Coastguard Worker blobOut);
987*8975f5c5SAndroid Build Coastguard Worker }
988*8975f5c5SAndroid Build Coastguard Worker }
989*8975f5c5SAndroid Build Coastguard Worker
InsertTopOfMain(angle::spirv::Blob * blobOut)990*8975f5c5SAndroid Build Coastguard Worker void InsertTopOfMain(angle::spirv::Blob *blobOut)
991*8975f5c5SAndroid Build Coastguard Worker {
992*8975f5c5SAndroid Build Coastguard Worker spirv::WriteFunction(blobOut, spirv::IdRef(kIdVoid), spirv::IdRef(kIdMain),
993*8975f5c5SAndroid Build Coastguard Worker spv::FunctionControlMaskNone, spirv::IdRef(kIdMainType));
994*8975f5c5SAndroid Build Coastguard Worker spirv::WriteLabel(blobOut, spirv::IdRef(kIdMainLabel));
995*8975f5c5SAndroid Build Coastguard Worker }
996*8975f5c5SAndroid Build Coastguard Worker
InsertColorUnresolveLoadStore(uint32_t colorIndex,UnresolveColorAttachmentType type,angle::spirv::Blob * blobOut)997*8975f5c5SAndroid Build Coastguard Worker void InsertColorUnresolveLoadStore(uint32_t colorIndex,
998*8975f5c5SAndroid Build Coastguard Worker UnresolveColorAttachmentType type,
999*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob *blobOut)
1000*8975f5c5SAndroid Build Coastguard Worker {
1001*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef loadResult(kIdColor0Load + colorIndex * 2);
1002*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef imageReadResult(loadResult + 1);
1003*8975f5c5SAndroid Build Coastguard Worker
1004*8975f5c5SAndroid Build Coastguard Worker // Find the correct types for load/store.
1005*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef loadType(kIdFloatSubpassImageType);
1006*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef readType(kIdFloat4Type);
1007*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef inId(kIdColor0In + colorIndex);
1008*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef outId(kIdColor0Out + colorIndex);
1009*8975f5c5SAndroid Build Coastguard Worker switch (type)
1010*8975f5c5SAndroid Build Coastguard Worker {
1011*8975f5c5SAndroid Build Coastguard Worker case kUnresolveTypeSint:
1012*8975f5c5SAndroid Build Coastguard Worker loadType = spirv::IdRef(kIdSIntSubpassImageType);
1013*8975f5c5SAndroid Build Coastguard Worker readType = spirv::IdRef(kIdSInt4Type);
1014*8975f5c5SAndroid Build Coastguard Worker break;
1015*8975f5c5SAndroid Build Coastguard Worker case kUnresolveTypeUint:
1016*8975f5c5SAndroid Build Coastguard Worker loadType = spirv::IdRef(kIdUIntSubpassImageType);
1017*8975f5c5SAndroid Build Coastguard Worker readType = spirv::IdRef(kIdUInt4Type);
1018*8975f5c5SAndroid Build Coastguard Worker break;
1019*8975f5c5SAndroid Build Coastguard Worker default:
1020*8975f5c5SAndroid Build Coastguard Worker break;
1021*8975f5c5SAndroid Build Coastguard Worker }
1022*8975f5c5SAndroid Build Coastguard Worker
1023*8975f5c5SAndroid Build Coastguard Worker // Load the subpass input image, read from it, and store in output.
1024*8975f5c5SAndroid Build Coastguard Worker spirv::WriteLoad(blobOut, loadType, loadResult, inId, nullptr);
1025*8975f5c5SAndroid Build Coastguard Worker spirv::WriteImageRead(blobOut, readType, imageReadResult, loadResult,
1026*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdSInt2Zero), nullptr, {});
1027*8975f5c5SAndroid Build Coastguard Worker spirv::WriteStore(blobOut, outId, imageReadResult, nullptr);
1028*8975f5c5SAndroid Build Coastguard Worker }
1029*8975f5c5SAndroid Build Coastguard Worker
InsertDepthStencilUnresolveLoadStore(bool unresolveDepth,bool unresolveStencil,angle::spirv::Blob * blobOut)1030*8975f5c5SAndroid Build Coastguard Worker void InsertDepthStencilUnresolveLoadStore(bool unresolveDepth,
1031*8975f5c5SAndroid Build Coastguard Worker bool unresolveStencil,
1032*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob *blobOut)
1033*8975f5c5SAndroid Build Coastguard Worker {
1034*8975f5c5SAndroid Build Coastguard Worker if (unresolveDepth)
1035*8975f5c5SAndroid Build Coastguard Worker {
1036*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef loadResult(kIdDepthLoad);
1037*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef imageReadResult(loadResult + 1);
1038*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef extractResult(imageReadResult + 1);
1039*8975f5c5SAndroid Build Coastguard Worker
1040*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef loadType(kIdFloatSubpassImageType);
1041*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef readType(kIdFloat4Type);
1042*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef inId(kIdDepthIn);
1043*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef outId(kIdDepthOut);
1044*8975f5c5SAndroid Build Coastguard Worker
1045*8975f5c5SAndroid Build Coastguard Worker // Load the subpass input image, read from it, select .x, and store in output.
1046*8975f5c5SAndroid Build Coastguard Worker spirv::WriteLoad(blobOut, loadType, loadResult, inId, nullptr);
1047*8975f5c5SAndroid Build Coastguard Worker spirv::WriteImageRead(blobOut, readType, imageReadResult, loadResult,
1048*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdSInt2Zero), nullptr, {});
1049*8975f5c5SAndroid Build Coastguard Worker spirv::WriteCompositeExtract(blobOut, spirv::IdRef(kIdFloatType), extractResult,
1050*8975f5c5SAndroid Build Coastguard Worker imageReadResult, {spirv::LiteralInteger(0)});
1051*8975f5c5SAndroid Build Coastguard Worker spirv::WriteStore(blobOut, outId, extractResult, nullptr);
1052*8975f5c5SAndroid Build Coastguard Worker }
1053*8975f5c5SAndroid Build Coastguard Worker if (unresolveStencil)
1054*8975f5c5SAndroid Build Coastguard Worker {
1055*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef loadResult(kIdStencilLoad);
1056*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef imageReadResult(loadResult + 1);
1057*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef extractResult(imageReadResult + 1);
1058*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef bitcastResult(extractResult + 1);
1059*8975f5c5SAndroid Build Coastguard Worker
1060*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef loadType(kIdUIntSubpassImageType);
1061*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef readType(kIdUInt4Type);
1062*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef inId(kIdStencilIn);
1063*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef outId(kIdStencilOut);
1064*8975f5c5SAndroid Build Coastguard Worker
1065*8975f5c5SAndroid Build Coastguard Worker // Load the subpass input image, read from it, select .x, and store in output. There's a
1066*8975f5c5SAndroid Build Coastguard Worker // bitcast involved since the stencil subpass input has unsigned type, while
1067*8975f5c5SAndroid Build Coastguard Worker // gl_FragStencilRefARB is signed!
1068*8975f5c5SAndroid Build Coastguard Worker spirv::WriteLoad(blobOut, loadType, loadResult, inId, nullptr);
1069*8975f5c5SAndroid Build Coastguard Worker spirv::WriteImageRead(blobOut, readType, imageReadResult, loadResult,
1070*8975f5c5SAndroid Build Coastguard Worker spirv::IdRef(kIdSInt2Zero), nullptr, {});
1071*8975f5c5SAndroid Build Coastguard Worker spirv::WriteCompositeExtract(blobOut, spirv::IdRef(kIdUIntType), extractResult,
1072*8975f5c5SAndroid Build Coastguard Worker imageReadResult, {spirv::LiteralInteger(0)});
1073*8975f5c5SAndroid Build Coastguard Worker spirv::WriteBitcast(blobOut, spirv::IdRef(kIdSIntType), bitcastResult, extractResult);
1074*8975f5c5SAndroid Build Coastguard Worker spirv::WriteStore(blobOut, outId, bitcastResult, nullptr);
1075*8975f5c5SAndroid Build Coastguard Worker }
1076*8975f5c5SAndroid Build Coastguard Worker }
1077*8975f5c5SAndroid Build Coastguard Worker
InsertBottomOfMain(angle::spirv::Blob * blobOut)1078*8975f5c5SAndroid Build Coastguard Worker void InsertBottomOfMain(angle::spirv::Blob *blobOut)
1079*8975f5c5SAndroid Build Coastguard Worker {
1080*8975f5c5SAndroid Build Coastguard Worker spirv::WriteReturn(blobOut);
1081*8975f5c5SAndroid Build Coastguard Worker spirv::WriteFunctionEnd(blobOut);
1082*8975f5c5SAndroid Build Coastguard Worker }
1083*8975f5c5SAndroid Build Coastguard Worker
MakeFragShader(uint32_t colorAttachmentCount,gl::DrawBuffersArray<UnresolveColorAttachmentType> & colorAttachmentTypes,bool unresolveDepth,bool unresolveStencil,bool supportsShaderStencilExport)1084*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob MakeFragShader(
1085*8975f5c5SAndroid Build Coastguard Worker uint32_t colorAttachmentCount,
1086*8975f5c5SAndroid Build Coastguard Worker gl::DrawBuffersArray<UnresolveColorAttachmentType> &colorAttachmentTypes,
1087*8975f5c5SAndroid Build Coastguard Worker bool unresolveDepth,
1088*8975f5c5SAndroid Build Coastguard Worker bool unresolveStencil,
1089*8975f5c5SAndroid Build Coastguard Worker bool supportsShaderStencilExport)
1090*8975f5c5SAndroid Build Coastguard Worker {
1091*8975f5c5SAndroid Build Coastguard Worker const bool unresolveStencilWithShaderExport = unresolveStencil && supportsShaderStencilExport;
1092*8975f5c5SAndroid Build Coastguard Worker
1093*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob code;
1094*8975f5c5SAndroid Build Coastguard Worker
1095*8975f5c5SAndroid Build Coastguard Worker // Reserve a sensible amount of memory. A single-attachment shader is 169 words.
1096*8975f5c5SAndroid Build Coastguard Worker code.reserve(169);
1097*8975f5c5SAndroid Build Coastguard Worker
1098*8975f5c5SAndroid Build Coastguard Worker // Header
1099*8975f5c5SAndroid Build Coastguard Worker spirv::WriteSpirvHeader(&code, spirv::kVersion_1_0, kIdCount);
1100*8975f5c5SAndroid Build Coastguard Worker
1101*8975f5c5SAndroid Build Coastguard Worker // The preamble
1102*8975f5c5SAndroid Build Coastguard Worker InsertPreamble(colorAttachmentCount, unresolveDepth, unresolveStencilWithShaderExport, &code);
1103*8975f5c5SAndroid Build Coastguard Worker
1104*8975f5c5SAndroid Build Coastguard Worker // Depth stencil decorations
1105*8975f5c5SAndroid Build Coastguard Worker uint32_t colorInputIndexStart = 0;
1106*8975f5c5SAndroid Build Coastguard Worker uint32_t colorBindingIndexStart = 0;
1107*8975f5c5SAndroid Build Coastguard Worker InsertDepthStencilDecorations(unresolveDepth, unresolveStencil, supportsShaderStencilExport,
1108*8975f5c5SAndroid Build Coastguard Worker &colorInputIndexStart, &colorBindingIndexStart, &code);
1109*8975f5c5SAndroid Build Coastguard Worker
1110*8975f5c5SAndroid Build Coastguard Worker // Color attachment decorations
1111*8975f5c5SAndroid Build Coastguard Worker for (uint32_t colorIndex = 0; colorIndex < colorAttachmentCount; ++colorIndex)
1112*8975f5c5SAndroid Build Coastguard Worker {
1113*8975f5c5SAndroid Build Coastguard Worker InsertColorDecorations(colorIndex, colorInputIndexStart, colorBindingIndexStart, &code);
1114*8975f5c5SAndroid Build Coastguard Worker }
1115*8975f5c5SAndroid Build Coastguard Worker
1116*8975f5c5SAndroid Build Coastguard Worker // Common types
1117*8975f5c5SAndroid Build Coastguard Worker InsertCommonTypes(&code);
1118*8975f5c5SAndroid Build Coastguard Worker
1119*8975f5c5SAndroid Build Coastguard Worker // Attachment declarations
1120*8975f5c5SAndroid Build Coastguard Worker for (uint32_t colorIndex = 0; colorIndex < colorAttachmentCount; ++colorIndex)
1121*8975f5c5SAndroid Build Coastguard Worker {
1122*8975f5c5SAndroid Build Coastguard Worker InsertColorVariableDecl(colorIndex, colorAttachmentTypes[colorIndex], &code);
1123*8975f5c5SAndroid Build Coastguard Worker }
1124*8975f5c5SAndroid Build Coastguard Worker InsertDepthStencilVariableDecl(unresolveDepth, unresolveStencilWithShaderExport, &code);
1125*8975f5c5SAndroid Build Coastguard Worker
1126*8975f5c5SAndroid Build Coastguard Worker // Top of main
1127*8975f5c5SAndroid Build Coastguard Worker InsertTopOfMain(&code);
1128*8975f5c5SAndroid Build Coastguard Worker
1129*8975f5c5SAndroid Build Coastguard Worker // Load and store for each attachment
1130*8975f5c5SAndroid Build Coastguard Worker for (uint32_t colorIndex = 0; colorIndex < colorAttachmentCount; ++colorIndex)
1131*8975f5c5SAndroid Build Coastguard Worker {
1132*8975f5c5SAndroid Build Coastguard Worker InsertColorUnresolveLoadStore(colorIndex, colorAttachmentTypes[colorIndex], &code);
1133*8975f5c5SAndroid Build Coastguard Worker }
1134*8975f5c5SAndroid Build Coastguard Worker InsertDepthStencilUnresolveLoadStore(unresolveDepth, unresolveStencilWithShaderExport, &code);
1135*8975f5c5SAndroid Build Coastguard Worker
1136*8975f5c5SAndroid Build Coastguard Worker // Bottom of main
1137*8975f5c5SAndroid Build Coastguard Worker InsertBottomOfMain(&code);
1138*8975f5c5SAndroid Build Coastguard Worker
1139*8975f5c5SAndroid Build Coastguard Worker return code;
1140*8975f5c5SAndroid Build Coastguard Worker }
1141*8975f5c5SAndroid Build Coastguard Worker } // namespace unresolve
1142*8975f5c5SAndroid Build Coastguard Worker
GetUnresolveFrag(vk::Context * context,uint32_t colorAttachmentCount,gl::DrawBuffersArray<UnresolveColorAttachmentType> & colorAttachmentTypes,bool unresolveDepth,bool unresolveStencil,vk::ShaderModulePtr * shader)1143*8975f5c5SAndroid Build Coastguard Worker angle::Result GetUnresolveFrag(
1144*8975f5c5SAndroid Build Coastguard Worker vk::Context *context,
1145*8975f5c5SAndroid Build Coastguard Worker uint32_t colorAttachmentCount,
1146*8975f5c5SAndroid Build Coastguard Worker gl::DrawBuffersArray<UnresolveColorAttachmentType> &colorAttachmentTypes,
1147*8975f5c5SAndroid Build Coastguard Worker bool unresolveDepth,
1148*8975f5c5SAndroid Build Coastguard Worker bool unresolveStencil,
1149*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr *shader)
1150*8975f5c5SAndroid Build Coastguard Worker {
1151*8975f5c5SAndroid Build Coastguard Worker if (*shader)
1152*8975f5c5SAndroid Build Coastguard Worker {
1153*8975f5c5SAndroid Build Coastguard Worker ASSERT((*shader)->valid());
1154*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1155*8975f5c5SAndroid Build Coastguard Worker }
1156*8975f5c5SAndroid Build Coastguard Worker
1157*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob shaderCode = unresolve::MakeFragShader(
1158*8975f5c5SAndroid Build Coastguard Worker colorAttachmentCount, colorAttachmentTypes, unresolveDepth, unresolveStencil,
1159*8975f5c5SAndroid Build Coastguard Worker context->getFeatures().supportsShaderStencilExport.enabled);
1160*8975f5c5SAndroid Build Coastguard Worker
1161*8975f5c5SAndroid Build Coastguard Worker ASSERT(spirv::Validate(shaderCode));
1162*8975f5c5SAndroid Build Coastguard Worker
1163*8975f5c5SAndroid Build Coastguard Worker // Create shader lazily. Access will need to be locked for multi-threading.
1164*8975f5c5SAndroid Build Coastguard Worker return vk::InitShaderModule(context, shader, shaderCode.data(), shaderCode.size() * 4);
1165*8975f5c5SAndroid Build Coastguard Worker }
1166*8975f5c5SAndroid Build Coastguard Worker
MakeColorBufferMask(uint32_t colorAttachmentIndexGL)1167*8975f5c5SAndroid Build Coastguard Worker gl::DrawBufferMask MakeColorBufferMask(uint32_t colorAttachmentIndexGL)
1168*8975f5c5SAndroid Build Coastguard Worker {
1169*8975f5c5SAndroid Build Coastguard Worker gl::DrawBufferMask mask;
1170*8975f5c5SAndroid Build Coastguard Worker mask.set(colorAttachmentIndexGL);
1171*8975f5c5SAndroid Build Coastguard Worker return mask;
1172*8975f5c5SAndroid Build Coastguard Worker }
1173*8975f5c5SAndroid Build Coastguard Worker
UpdateColorAccess(ContextVk * contextVk,gl::DrawBufferMask colorAttachmentMask,gl::DrawBufferMask colorEnabledMask)1174*8975f5c5SAndroid Build Coastguard Worker void UpdateColorAccess(ContextVk *contextVk,
1175*8975f5c5SAndroid Build Coastguard Worker gl::DrawBufferMask colorAttachmentMask,
1176*8975f5c5SAndroid Build Coastguard Worker gl::DrawBufferMask colorEnabledMask)
1177*8975f5c5SAndroid Build Coastguard Worker {
1178*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBufferHelper *renderPassCommands =
1179*8975f5c5SAndroid Build Coastguard Worker &contextVk->getStartedRenderPassCommands();
1180*8975f5c5SAndroid Build Coastguard Worker
1181*8975f5c5SAndroid Build Coastguard Worker // Explicitly mark a color write because we are modifying the color buffer.
1182*8975f5c5SAndroid Build Coastguard Worker vk::PackedAttachmentIndex colorIndexVk(0);
1183*8975f5c5SAndroid Build Coastguard Worker for (size_t colorIndexGL : colorAttachmentMask)
1184*8975f5c5SAndroid Build Coastguard Worker {
1185*8975f5c5SAndroid Build Coastguard Worker if (colorEnabledMask.test(colorIndexGL))
1186*8975f5c5SAndroid Build Coastguard Worker {
1187*8975f5c5SAndroid Build Coastguard Worker renderPassCommands->onColorAccess(colorIndexVk, vk::ResourceAccess::ReadWrite);
1188*8975f5c5SAndroid Build Coastguard Worker }
1189*8975f5c5SAndroid Build Coastguard Worker ++colorIndexVk;
1190*8975f5c5SAndroid Build Coastguard Worker }
1191*8975f5c5SAndroid Build Coastguard Worker }
1192*8975f5c5SAndroid Build Coastguard Worker
UpdateDepthStencilAccess(ContextVk * contextVk,bool depthWrite,bool stencilWrite)1193*8975f5c5SAndroid Build Coastguard Worker void UpdateDepthStencilAccess(ContextVk *contextVk, bool depthWrite, bool stencilWrite)
1194*8975f5c5SAndroid Build Coastguard Worker {
1195*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBufferHelper *renderPassCommands =
1196*8975f5c5SAndroid Build Coastguard Worker &contextVk->getStartedRenderPassCommands();
1197*8975f5c5SAndroid Build Coastguard Worker
1198*8975f5c5SAndroid Build Coastguard Worker if (depthWrite)
1199*8975f5c5SAndroid Build Coastguard Worker {
1200*8975f5c5SAndroid Build Coastguard Worker // Explicitly mark a depth write because we are modifying the depth buffer.
1201*8975f5c5SAndroid Build Coastguard Worker renderPassCommands->onDepthAccess(vk::ResourceAccess::ReadWrite);
1202*8975f5c5SAndroid Build Coastguard Worker // Because we may have changed the depth access mode, update read only depth mode.
1203*8975f5c5SAndroid Build Coastguard Worker renderPassCommands->updateDepthReadOnlyMode(contextVk->getDepthStencilAttachmentFlags());
1204*8975f5c5SAndroid Build Coastguard Worker }
1205*8975f5c5SAndroid Build Coastguard Worker if (stencilWrite)
1206*8975f5c5SAndroid Build Coastguard Worker {
1207*8975f5c5SAndroid Build Coastguard Worker // Explicitly mark a stencil write because we are modifying the stencil buffer.
1208*8975f5c5SAndroid Build Coastguard Worker renderPassCommands->onStencilAccess(vk::ResourceAccess::ReadWrite);
1209*8975f5c5SAndroid Build Coastguard Worker // Because we may have changed the stencil access mode, update read only stencil mode.
1210*8975f5c5SAndroid Build Coastguard Worker renderPassCommands->updateStencilReadOnlyMode(contextVk->getDepthStencilAttachmentFlags());
1211*8975f5c5SAndroid Build Coastguard Worker }
1212*8975f5c5SAndroid Build Coastguard Worker }
1213*8975f5c5SAndroid Build Coastguard Worker
ResetDynamicState(ContextVk * contextVk,vk::RenderPassCommandBuffer * commandBuffer)1214*8975f5c5SAndroid Build Coastguard Worker void ResetDynamicState(ContextVk *contextVk, vk::RenderPassCommandBuffer *commandBuffer)
1215*8975f5c5SAndroid Build Coastguard Worker {
1216*8975f5c5SAndroid Build Coastguard Worker // Reset dynamic state that might affect UtilsVk. Mark all dynamic state dirty for simplicity.
1217*8975f5c5SAndroid Build Coastguard Worker // Ideally, only dynamic state that is changed by UtilsVk will be marked dirty but, until such
1218*8975f5c5SAndroid Build Coastguard Worker // time as extensive transition tests are written, this approach is less bug-prone.
1219*8975f5c5SAndroid Build Coastguard Worker
1220*8975f5c5SAndroid Build Coastguard Worker // Notes: the following dynamic state doesn't apply to UtilsVk functions:
1221*8975f5c5SAndroid Build Coastguard Worker //
1222*8975f5c5SAndroid Build Coastguard Worker // - line width: UtilsVk doesn't use line primitives
1223*8975f5c5SAndroid Build Coastguard Worker // - depth bias: UtilsVk doesn't enable depth bias
1224*8975f5c5SAndroid Build Coastguard Worker // - blend constants: UtilsVk doesn't enable blending
1225*8975f5c5SAndroid Build Coastguard Worker // - logic op: UtilsVk doesn't enable logic op
1226*8975f5c5SAndroid Build Coastguard Worker //
1227*8975f5c5SAndroid Build Coastguard Worker // The following dynamic state is always set by UtilsVk when effective:
1228*8975f5c5SAndroid Build Coastguard Worker //
1229*8975f5c5SAndroid Build Coastguard Worker // - depth write mask: UtilsVk sets this when enabling depth test
1230*8975f5c5SAndroid Build Coastguard Worker // - depth compare op: UtilsVk sets this when enabling depth test
1231*8975f5c5SAndroid Build Coastguard Worker // - stencil compare mask: UtilsVk sets this when enabling stencil test
1232*8975f5c5SAndroid Build Coastguard Worker // - stencil write mask: UtilsVk sets this when enabling stencil test
1233*8975f5c5SAndroid Build Coastguard Worker // - stencil reference: UtilsVk sets this when enabling stencil test
1234*8975f5c5SAndroid Build Coastguard Worker // - stencil func: UtilsVk sets this when enabling stencil test
1235*8975f5c5SAndroid Build Coastguard Worker // - stencil ops: UtilsVk sets this when enabling stencil test
1236*8975f5c5SAndroid Build Coastguard Worker
1237*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
1238*8975f5c5SAndroid Build Coastguard Worker
1239*8975f5c5SAndroid Build Coastguard Worker // Reset all other dynamic state, since it can affect UtilsVk functions:
1240*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useCullModeDynamicState.enabled)
1241*8975f5c5SAndroid Build Coastguard Worker {
1242*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setCullMode(VK_CULL_MODE_NONE);
1243*8975f5c5SAndroid Build Coastguard Worker }
1244*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useFrontFaceDynamicState.enabled)
1245*8975f5c5SAndroid Build Coastguard Worker {
1246*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setFrontFace(VK_FRONT_FACE_COUNTER_CLOCKWISE);
1247*8975f5c5SAndroid Build Coastguard Worker }
1248*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useDepthTestEnableDynamicState.enabled)
1249*8975f5c5SAndroid Build Coastguard Worker {
1250*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setDepthTestEnable(VK_FALSE);
1251*8975f5c5SAndroid Build Coastguard Worker }
1252*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useStencilTestEnableDynamicState.enabled)
1253*8975f5c5SAndroid Build Coastguard Worker {
1254*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilTestEnable(VK_FALSE);
1255*8975f5c5SAndroid Build Coastguard Worker }
1256*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useRasterizerDiscardEnableDynamicState.enabled)
1257*8975f5c5SAndroid Build Coastguard Worker {
1258*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setRasterizerDiscardEnable(VK_FALSE);
1259*8975f5c5SAndroid Build Coastguard Worker }
1260*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().useDepthBiasEnableDynamicState.enabled)
1261*8975f5c5SAndroid Build Coastguard Worker {
1262*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setDepthBiasEnable(VK_FALSE);
1263*8975f5c5SAndroid Build Coastguard Worker }
1264*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().usePrimitiveRestartEnableDynamicState.enabled)
1265*8975f5c5SAndroid Build Coastguard Worker {
1266*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setPrimitiveRestartEnable(VK_FALSE);
1267*8975f5c5SAndroid Build Coastguard Worker }
1268*8975f5c5SAndroid Build Coastguard Worker if (contextVk->getFeatures().supportsFragmentShadingRate.enabled)
1269*8975f5c5SAndroid Build Coastguard Worker {
1270*8975f5c5SAndroid Build Coastguard Worker VkExtent2D fragmentSize = {1, 1};
1271*8975f5c5SAndroid Build Coastguard Worker VkFragmentShadingRateCombinerOpKHR shadingRateCombinerOp[2] = {
1272*8975f5c5SAndroid Build Coastguard Worker VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
1273*8975f5c5SAndroid Build Coastguard Worker VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR};
1274*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setFragmentShadingRate(&fragmentSize, shadingRateCombinerOp);
1275*8975f5c5SAndroid Build Coastguard Worker }
1276*8975f5c5SAndroid Build Coastguard Worker if (renderer->getFeatures().supportsLogicOpDynamicState.enabled)
1277*8975f5c5SAndroid Build Coastguard Worker {
1278*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setLogicOp(VK_LOGIC_OP_COPY);
1279*8975f5c5SAndroid Build Coastguard Worker }
1280*8975f5c5SAndroid Build Coastguard Worker if (contextVk->getFeatures().supportsVertexInputDynamicState.enabled)
1281*8975f5c5SAndroid Build Coastguard Worker {
1282*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setVertexInput(0, nullptr, 0, nullptr);
1283*8975f5c5SAndroid Build Coastguard Worker }
1284*8975f5c5SAndroid Build Coastguard Worker
1285*8975f5c5SAndroid Build Coastguard Worker // Let ContextVk know that it should refresh all dynamic state.
1286*8975f5c5SAndroid Build Coastguard Worker contextVk->invalidateAllDynamicState();
1287*8975f5c5SAndroid Build Coastguard Worker }
1288*8975f5c5SAndroid Build Coastguard Worker } // namespace
1289*8975f5c5SAndroid Build Coastguard Worker
1290*8975f5c5SAndroid Build Coastguard Worker UtilsVk::ConvertVertexShaderParams::ConvertVertexShaderParams() = default;
1291*8975f5c5SAndroid Build Coastguard Worker
1292*8975f5c5SAndroid Build Coastguard Worker UtilsVk::ImageCopyShaderParams::ImageCopyShaderParams() = default;
1293*8975f5c5SAndroid Build Coastguard Worker
GetGenerateMipmapMaxLevels(ContextVk * contextVk)1294*8975f5c5SAndroid Build Coastguard Worker uint32_t UtilsVk::GetGenerateMipmapMaxLevels(ContextVk *contextVk)
1295*8975f5c5SAndroid Build Coastguard Worker {
1296*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
1297*8975f5c5SAndroid Build Coastguard Worker
1298*8975f5c5SAndroid Build Coastguard Worker uint32_t maxPerStageDescriptorStorageImages =
1299*8975f5c5SAndroid Build Coastguard Worker renderer->getPhysicalDeviceProperties().limits.maxPerStageDescriptorStorageImages;
1300*8975f5c5SAndroid Build Coastguard Worker
1301*8975f5c5SAndroid Build Coastguard Worker // Vulkan requires that there be support for at least 4 storage images per stage.
1302*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kMinimumStorageImagesLimit = 4;
1303*8975f5c5SAndroid Build Coastguard Worker ASSERT(maxPerStageDescriptorStorageImages >= kMinimumStorageImagesLimit);
1304*8975f5c5SAndroid Build Coastguard Worker
1305*8975f5c5SAndroid Build Coastguard Worker // If fewer than max-levels are supported, use 4 levels (which is the minimum required number
1306*8975f5c5SAndroid Build Coastguard Worker // of storage image bindings).
1307*8975f5c5SAndroid Build Coastguard Worker return maxPerStageDescriptorStorageImages < kGenerateMipmapMaxLevels
1308*8975f5c5SAndroid Build Coastguard Worker ? kMinimumStorageImagesLimit
1309*8975f5c5SAndroid Build Coastguard Worker : kGenerateMipmapMaxLevels;
1310*8975f5c5SAndroid Build Coastguard Worker }
1311*8975f5c5SAndroid Build Coastguard Worker
1312*8975f5c5SAndroid Build Coastguard Worker UtilsVk::UtilsVk() = default;
1313*8975f5c5SAndroid Build Coastguard Worker
1314*8975f5c5SAndroid Build Coastguard Worker UtilsVk::~UtilsVk() = default;
1315*8975f5c5SAndroid Build Coastguard Worker
destroy(ContextVk * contextVk)1316*8975f5c5SAndroid Build Coastguard Worker void UtilsVk::destroy(ContextVk *contextVk)
1317*8975f5c5SAndroid Build Coastguard Worker {
1318*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
1319*8975f5c5SAndroid Build Coastguard Worker VkDevice device = renderer->getDevice();
1320*8975f5c5SAndroid Build Coastguard Worker
1321*8975f5c5SAndroid Build Coastguard Worker for (Function f : angle::AllEnums<Function>())
1322*8975f5c5SAndroid Build Coastguard Worker {
1323*8975f5c5SAndroid Build Coastguard Worker for (auto &descriptorSetLayout : mDescriptorSetLayouts[f])
1324*8975f5c5SAndroid Build Coastguard Worker {
1325*8975f5c5SAndroid Build Coastguard Worker descriptorSetLayout.reset();
1326*8975f5c5SAndroid Build Coastguard Worker }
1327*8975f5c5SAndroid Build Coastguard Worker mPipelineLayouts[f].reset();
1328*8975f5c5SAndroid Build Coastguard Worker mDescriptorPools[f].destroy(device);
1329*8975f5c5SAndroid Build Coastguard Worker }
1330*8975f5c5SAndroid Build Coastguard Worker
1331*8975f5c5SAndroid Build Coastguard Worker for (auto &item : mImageCopyWithSamplerPipelineLayouts)
1332*8975f5c5SAndroid Build Coastguard Worker {
1333*8975f5c5SAndroid Build Coastguard Worker const vk::SamplerDesc &samplerDesc = item.first;
1334*8975f5c5SAndroid Build Coastguard Worker
1335*8975f5c5SAndroid Build Coastguard Worker for (auto &descriptorSetLayout : mImageCopyWithSamplerDescriptorSetLayouts[samplerDesc])
1336*8975f5c5SAndroid Build Coastguard Worker {
1337*8975f5c5SAndroid Build Coastguard Worker descriptorSetLayout.reset();
1338*8975f5c5SAndroid Build Coastguard Worker }
1339*8975f5c5SAndroid Build Coastguard Worker mImageCopyWithSamplerPipelineLayouts[samplerDesc].reset();
1340*8975f5c5SAndroid Build Coastguard Worker mImageCopyWithSamplerDescriptorPools[samplerDesc].destroy(device);
1341*8975f5c5SAndroid Build Coastguard Worker }
1342*8975f5c5SAndroid Build Coastguard Worker
1343*8975f5c5SAndroid Build Coastguard Worker for (ComputeShaderProgramAndPipelines &programAndPipelines : mConvertIndex)
1344*8975f5c5SAndroid Build Coastguard Worker {
1345*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1346*8975f5c5SAndroid Build Coastguard Worker for (vk::PipelineHelper &pipeline : programAndPipelines.pipelines)
1347*8975f5c5SAndroid Build Coastguard Worker {
1348*8975f5c5SAndroid Build Coastguard Worker pipeline.destroy(device);
1349*8975f5c5SAndroid Build Coastguard Worker }
1350*8975f5c5SAndroid Build Coastguard Worker }
1351*8975f5c5SAndroid Build Coastguard Worker for (ComputeShaderProgramAndPipelines &programAndPipelines : mConvertIndirectLineLoop)
1352*8975f5c5SAndroid Build Coastguard Worker {
1353*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1354*8975f5c5SAndroid Build Coastguard Worker for (vk::PipelineHelper &pipeline : programAndPipelines.pipelines)
1355*8975f5c5SAndroid Build Coastguard Worker {
1356*8975f5c5SAndroid Build Coastguard Worker pipeline.destroy(device);
1357*8975f5c5SAndroid Build Coastguard Worker }
1358*8975f5c5SAndroid Build Coastguard Worker }
1359*8975f5c5SAndroid Build Coastguard Worker for (ComputeShaderProgramAndPipelines &programAndPipelines : mConvertIndexIndirectLineLoop)
1360*8975f5c5SAndroid Build Coastguard Worker {
1361*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1362*8975f5c5SAndroid Build Coastguard Worker for (vk::PipelineHelper &pipeline : programAndPipelines.pipelines)
1363*8975f5c5SAndroid Build Coastguard Worker {
1364*8975f5c5SAndroid Build Coastguard Worker pipeline.destroy(device);
1365*8975f5c5SAndroid Build Coastguard Worker }
1366*8975f5c5SAndroid Build Coastguard Worker }
1367*8975f5c5SAndroid Build Coastguard Worker for (ComputeShaderProgramAndPipelines &programAndPipelines : mConvertVertex)
1368*8975f5c5SAndroid Build Coastguard Worker {
1369*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1370*8975f5c5SAndroid Build Coastguard Worker for (vk::PipelineHelper &pipeline : programAndPipelines.pipelines)
1371*8975f5c5SAndroid Build Coastguard Worker {
1372*8975f5c5SAndroid Build Coastguard Worker pipeline.destroy(device);
1373*8975f5c5SAndroid Build Coastguard Worker }
1374*8975f5c5SAndroid Build Coastguard Worker }
1375*8975f5c5SAndroid Build Coastguard Worker mImageClearVSOnly.program.destroy(renderer);
1376*8975f5c5SAndroid Build Coastguard Worker mImageClearVSOnly.pipelines.destroy(contextVk);
1377*8975f5c5SAndroid Build Coastguard Worker for (GraphicsShaderProgramAndPipelines &programAndPipelines : mImageClear)
1378*8975f5c5SAndroid Build Coastguard Worker {
1379*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1380*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.pipelines.destroy(contextVk);
1381*8975f5c5SAndroid Build Coastguard Worker }
1382*8975f5c5SAndroid Build Coastguard Worker for (GraphicsShaderProgramAndPipelines &programAndPipelines : mImageCopy)
1383*8975f5c5SAndroid Build Coastguard Worker {
1384*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1385*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.pipelines.destroy(contextVk);
1386*8975f5c5SAndroid Build Coastguard Worker }
1387*8975f5c5SAndroid Build Coastguard Worker mImageCopyFloat.program.destroy(renderer);
1388*8975f5c5SAndroid Build Coastguard Worker mImageCopyFloat.pipelines.destroy(contextVk);
1389*8975f5c5SAndroid Build Coastguard Worker for (auto &iter : mImageCopyWithSampler)
1390*8975f5c5SAndroid Build Coastguard Worker {
1391*8975f5c5SAndroid Build Coastguard Worker GraphicsShaderProgramAndPipelines &programAndPipelines = iter.second;
1392*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1393*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.pipelines.destroy(contextVk);
1394*8975f5c5SAndroid Build Coastguard Worker }
1395*8975f5c5SAndroid Build Coastguard Worker for (ComputeShaderProgramAndPipelines &programAndPipelines : mCopyImageToBuffer)
1396*8975f5c5SAndroid Build Coastguard Worker {
1397*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1398*8975f5c5SAndroid Build Coastguard Worker for (vk::PipelineHelper &pipeline : programAndPipelines.pipelines)
1399*8975f5c5SAndroid Build Coastguard Worker {
1400*8975f5c5SAndroid Build Coastguard Worker pipeline.destroy(device);
1401*8975f5c5SAndroid Build Coastguard Worker }
1402*8975f5c5SAndroid Build Coastguard Worker }
1403*8975f5c5SAndroid Build Coastguard Worker for (GraphicsShaderProgramAndPipelines &programAndPipelines : mBlitResolve)
1404*8975f5c5SAndroid Build Coastguard Worker {
1405*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1406*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.pipelines.destroy(contextVk);
1407*8975f5c5SAndroid Build Coastguard Worker }
1408*8975f5c5SAndroid Build Coastguard Worker for (GraphicsShaderProgramAndPipelines &programAndPipelines : mBlit3DSrc)
1409*8975f5c5SAndroid Build Coastguard Worker {
1410*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1411*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.pipelines.destroy(contextVk);
1412*8975f5c5SAndroid Build Coastguard Worker }
1413*8975f5c5SAndroid Build Coastguard Worker for (ComputeShaderProgramAndPipelines &programAndPipelines : mBlitResolveStencilNoExport)
1414*8975f5c5SAndroid Build Coastguard Worker {
1415*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1416*8975f5c5SAndroid Build Coastguard Worker for (vk::PipelineHelper &pipeline : programAndPipelines.pipelines)
1417*8975f5c5SAndroid Build Coastguard Worker {
1418*8975f5c5SAndroid Build Coastguard Worker pipeline.destroy(device);
1419*8975f5c5SAndroid Build Coastguard Worker }
1420*8975f5c5SAndroid Build Coastguard Worker }
1421*8975f5c5SAndroid Build Coastguard Worker mExportStencil.program.destroy(renderer);
1422*8975f5c5SAndroid Build Coastguard Worker mExportStencil.pipelines.destroy(contextVk);
1423*8975f5c5SAndroid Build Coastguard Worker mOverlayDraw.program.destroy(renderer);
1424*8975f5c5SAndroid Build Coastguard Worker mOverlayDraw.pipelines.destroy(contextVk);
1425*8975f5c5SAndroid Build Coastguard Worker for (ComputeShaderProgramAndPipelines &programAndPipelines : mGenerateMipmap)
1426*8975f5c5SAndroid Build Coastguard Worker {
1427*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1428*8975f5c5SAndroid Build Coastguard Worker for (vk::PipelineHelper &pipeline : programAndPipelines.pipelines)
1429*8975f5c5SAndroid Build Coastguard Worker {
1430*8975f5c5SAndroid Build Coastguard Worker pipeline.destroy(device);
1431*8975f5c5SAndroid Build Coastguard Worker }
1432*8975f5c5SAndroid Build Coastguard Worker }
1433*8975f5c5SAndroid Build Coastguard Worker for (ComputeShaderProgramAndPipelines &programAndPipelines : mEtcToBc)
1434*8975f5c5SAndroid Build Coastguard Worker {
1435*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1436*8975f5c5SAndroid Build Coastguard Worker for (vk::PipelineHelper &pipeline : programAndPipelines.pipelines)
1437*8975f5c5SAndroid Build Coastguard Worker {
1438*8975f5c5SAndroid Build Coastguard Worker pipeline.destroy(device);
1439*8975f5c5SAndroid Build Coastguard Worker }
1440*8975f5c5SAndroid Build Coastguard Worker }
1441*8975f5c5SAndroid Build Coastguard Worker for (auto &programIter : mUnresolve)
1442*8975f5c5SAndroid Build Coastguard Worker {
1443*8975f5c5SAndroid Build Coastguard Worker GraphicsShaderProgramAndPipelines &programAndPipelines = programIter.second;
1444*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.program.destroy(renderer);
1445*8975f5c5SAndroid Build Coastguard Worker programAndPipelines.pipelines.destroy(contextVk);
1446*8975f5c5SAndroid Build Coastguard Worker }
1447*8975f5c5SAndroid Build Coastguard Worker mUnresolve.clear();
1448*8975f5c5SAndroid Build Coastguard Worker
1449*8975f5c5SAndroid Build Coastguard Worker mUnresolveFragShaders.clear();
1450*8975f5c5SAndroid Build Coastguard Worker
1451*8975f5c5SAndroid Build Coastguard Worker mPointSampler.destroy(device);
1452*8975f5c5SAndroid Build Coastguard Worker mLinearSampler.destroy(device);
1453*8975f5c5SAndroid Build Coastguard Worker
1454*8975f5c5SAndroid Build Coastguard Worker mGenerateFragmentShadingRateAttachment.program.destroy(renderer);
1455*8975f5c5SAndroid Build Coastguard Worker for (vk::PipelineHelper &pipeline : mGenerateFragmentShadingRateAttachment.pipelines)
1456*8975f5c5SAndroid Build Coastguard Worker {
1457*8975f5c5SAndroid Build Coastguard Worker pipeline.destroy(device);
1458*8975f5c5SAndroid Build Coastguard Worker }
1459*8975f5c5SAndroid Build Coastguard Worker }
1460*8975f5c5SAndroid Build Coastguard Worker
ensureResourcesInitialized(ContextVk * contextVk,Function function,VkDescriptorPoolSize * setSizes,size_t setSizesCount,size_t pushConstantsSize)1461*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureResourcesInitialized(ContextVk *contextVk,
1462*8975f5c5SAndroid Build Coastguard Worker Function function,
1463*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize *setSizes,
1464*8975f5c5SAndroid Build Coastguard Worker size_t setSizesCount,
1465*8975f5c5SAndroid Build Coastguard Worker size_t pushConstantsSize)
1466*8975f5c5SAndroid Build Coastguard Worker {
1467*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetLayoutDesc descriptorSetDesc;
1468*8975f5c5SAndroid Build Coastguard Worker bool isCompute = function >= Function::ComputeStartIndex;
1469*8975f5c5SAndroid Build Coastguard Worker VkShaderStageFlags descStages =
1470*8975f5c5SAndroid Build Coastguard Worker isCompute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_FRAGMENT_BIT;
1471*8975f5c5SAndroid Build Coastguard Worker if (function == Function::OverlayDraw)
1472*8975f5c5SAndroid Build Coastguard Worker {
1473*8975f5c5SAndroid Build Coastguard Worker descStages |= VK_SHADER_STAGE_VERTEX_BIT;
1474*8975f5c5SAndroid Build Coastguard Worker }
1475*8975f5c5SAndroid Build Coastguard Worker
1476*8975f5c5SAndroid Build Coastguard Worker uint32_t currentBinding = 0;
1477*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < setSizesCount; ++i)
1478*8975f5c5SAndroid Build Coastguard Worker {
1479*8975f5c5SAndroid Build Coastguard Worker descriptorSetDesc.addBinding(currentBinding, setSizes[i].type, setSizes[i].descriptorCount,
1480*8975f5c5SAndroid Build Coastguard Worker descStages, nullptr);
1481*8975f5c5SAndroid Build Coastguard Worker ++currentBinding;
1482*8975f5c5SAndroid Build Coastguard Worker }
1483*8975f5c5SAndroid Build Coastguard Worker
1484*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getDescriptorSetLayoutCache().getDescriptorSetLayout(
1485*8975f5c5SAndroid Build Coastguard Worker contextVk, descriptorSetDesc,
1486*8975f5c5SAndroid Build Coastguard Worker &mDescriptorSetLayouts[function][DescriptorSetIndex::Internal]));
1487*8975f5c5SAndroid Build Coastguard Worker
1488*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetLayoutBindingVector bindingVector;
1489*8975f5c5SAndroid Build Coastguard Worker descriptorSetDesc.unpackBindings(&bindingVector);
1490*8975f5c5SAndroid Build Coastguard Worker std::vector<VkDescriptorPoolSize> descriptorPoolSizes;
1491*8975f5c5SAndroid Build Coastguard Worker
1492*8975f5c5SAndroid Build Coastguard Worker for (const VkDescriptorSetLayoutBinding &binding : bindingVector)
1493*8975f5c5SAndroid Build Coastguard Worker {
1494*8975f5c5SAndroid Build Coastguard Worker if (binding.descriptorCount > 0)
1495*8975f5c5SAndroid Build Coastguard Worker {
1496*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize poolSize = {};
1497*8975f5c5SAndroid Build Coastguard Worker
1498*8975f5c5SAndroid Build Coastguard Worker poolSize.type = binding.descriptorType;
1499*8975f5c5SAndroid Build Coastguard Worker poolSize.descriptorCount = binding.descriptorCount;
1500*8975f5c5SAndroid Build Coastguard Worker descriptorPoolSizes.emplace_back(poolSize);
1501*8975f5c5SAndroid Build Coastguard Worker }
1502*8975f5c5SAndroid Build Coastguard Worker }
1503*8975f5c5SAndroid Build Coastguard Worker if (!descriptorPoolSizes.empty())
1504*8975f5c5SAndroid Build Coastguard Worker {
1505*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mDescriptorPools[function].init(
1506*8975f5c5SAndroid Build Coastguard Worker contextVk, descriptorPoolSizes.data(), descriptorPoolSizes.size(),
1507*8975f5c5SAndroid Build Coastguard Worker *mDescriptorSetLayouts[function][DescriptorSetIndex::Internal]));
1508*8975f5c5SAndroid Build Coastguard Worker }
1509*8975f5c5SAndroid Build Coastguard Worker
1510*8975f5c5SAndroid Build Coastguard Worker // Corresponding pipeline layouts:
1511*8975f5c5SAndroid Build Coastguard Worker vk::PipelineLayoutDesc pipelineLayoutDesc;
1512*8975f5c5SAndroid Build Coastguard Worker
1513*8975f5c5SAndroid Build Coastguard Worker pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::Internal, descriptorSetDesc);
1514*8975f5c5SAndroid Build Coastguard Worker if (pushConstantsSize)
1515*8975f5c5SAndroid Build Coastguard Worker {
1516*8975f5c5SAndroid Build Coastguard Worker pipelineLayoutDesc.updatePushConstantRange(descStages, 0,
1517*8975f5c5SAndroid Build Coastguard Worker static_cast<uint32_t>(pushConstantsSize));
1518*8975f5c5SAndroid Build Coastguard Worker }
1519*8975f5c5SAndroid Build Coastguard Worker
1520*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getPipelineLayoutCache().getPipelineLayout(contextVk, pipelineLayoutDesc,
1521*8975f5c5SAndroid Build Coastguard Worker mDescriptorSetLayouts[function],
1522*8975f5c5SAndroid Build Coastguard Worker &mPipelineLayouts[function]));
1523*8975f5c5SAndroid Build Coastguard Worker
1524*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1525*8975f5c5SAndroid Build Coastguard Worker }
1526*8975f5c5SAndroid Build Coastguard Worker
ensureConvertIndexResourcesInitialized(ContextVk * contextVk)1527*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureConvertIndexResourcesInitialized(ContextVk *contextVk)
1528*8975f5c5SAndroid Build Coastguard Worker {
1529*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[Function::ConvertIndexBuffer])
1530*8975f5c5SAndroid Build Coastguard Worker {
1531*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1532*8975f5c5SAndroid Build Coastguard Worker }
1533*8975f5c5SAndroid Build Coastguard Worker
1534*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[2] = {
1535*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1},
1536*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1},
1537*8975f5c5SAndroid Build Coastguard Worker };
1538*8975f5c5SAndroid Build Coastguard Worker
1539*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::ConvertIndexBuffer, setSizes,
1540*8975f5c5SAndroid Build Coastguard Worker ArraySize(setSizes), sizeof(ConvertIndexShaderParams));
1541*8975f5c5SAndroid Build Coastguard Worker }
1542*8975f5c5SAndroid Build Coastguard Worker
ensureConvertIndexIndirectResourcesInitialized(ContextVk * contextVk)1543*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureConvertIndexIndirectResourcesInitialized(ContextVk *contextVk)
1544*8975f5c5SAndroid Build Coastguard Worker {
1545*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[Function::ConvertIndexIndirectBuffer])
1546*8975f5c5SAndroid Build Coastguard Worker {
1547*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1548*8975f5c5SAndroid Build Coastguard Worker }
1549*8975f5c5SAndroid Build Coastguard Worker
1550*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[4] = {
1551*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, // dst index buffer
1552*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, // source index buffer
1553*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, // src indirect buffer
1554*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, // dst indirect buffer
1555*8975f5c5SAndroid Build Coastguard Worker };
1556*8975f5c5SAndroid Build Coastguard Worker
1557*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::ConvertIndexIndirectBuffer, setSizes,
1558*8975f5c5SAndroid Build Coastguard Worker ArraySize(setSizes),
1559*8975f5c5SAndroid Build Coastguard Worker sizeof(ConvertIndexIndirectShaderParams));
1560*8975f5c5SAndroid Build Coastguard Worker }
1561*8975f5c5SAndroid Build Coastguard Worker
ensureConvertIndexIndirectLineLoopResourcesInitialized(ContextVk * contextVk)1562*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureConvertIndexIndirectLineLoopResourcesInitialized(ContextVk *contextVk)
1563*8975f5c5SAndroid Build Coastguard Worker {
1564*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[Function::ConvertIndexIndirectLineLoopBuffer])
1565*8975f5c5SAndroid Build Coastguard Worker {
1566*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1567*8975f5c5SAndroid Build Coastguard Worker }
1568*8975f5c5SAndroid Build Coastguard Worker
1569*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[4] = {
1570*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, // cmd buffer
1571*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, // dst cmd buffer
1572*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, // source index buffer
1573*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, // dst index buffer
1574*8975f5c5SAndroid Build Coastguard Worker };
1575*8975f5c5SAndroid Build Coastguard Worker
1576*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::ConvertIndexIndirectLineLoopBuffer,
1577*8975f5c5SAndroid Build Coastguard Worker setSizes, ArraySize(setSizes),
1578*8975f5c5SAndroid Build Coastguard Worker sizeof(ConvertIndexIndirectLineLoopShaderParams));
1579*8975f5c5SAndroid Build Coastguard Worker }
1580*8975f5c5SAndroid Build Coastguard Worker
ensureConvertIndirectLineLoopResourcesInitialized(ContextVk * contextVk)1581*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureConvertIndirectLineLoopResourcesInitialized(ContextVk *contextVk)
1582*8975f5c5SAndroid Build Coastguard Worker {
1583*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[Function::ConvertIndirectLineLoopBuffer])
1584*8975f5c5SAndroid Build Coastguard Worker {
1585*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1586*8975f5c5SAndroid Build Coastguard Worker }
1587*8975f5c5SAndroid Build Coastguard Worker
1588*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[3] = {
1589*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, // cmd buffer
1590*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, // dst cmd buffer
1591*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, // dst index buffer
1592*8975f5c5SAndroid Build Coastguard Worker };
1593*8975f5c5SAndroid Build Coastguard Worker
1594*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::ConvertIndirectLineLoopBuffer, setSizes,
1595*8975f5c5SAndroid Build Coastguard Worker ArraySize(setSizes),
1596*8975f5c5SAndroid Build Coastguard Worker sizeof(ConvertIndirectLineLoopShaderParams));
1597*8975f5c5SAndroid Build Coastguard Worker }
1598*8975f5c5SAndroid Build Coastguard Worker
ensureConvertVertexResourcesInitialized(ContextVk * contextVk)1599*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureConvertVertexResourcesInitialized(ContextVk *contextVk)
1600*8975f5c5SAndroid Build Coastguard Worker {
1601*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[Function::ConvertVertexBuffer])
1602*8975f5c5SAndroid Build Coastguard Worker {
1603*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1604*8975f5c5SAndroid Build Coastguard Worker }
1605*8975f5c5SAndroid Build Coastguard Worker
1606*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[2] = {
1607*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1},
1608*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1},
1609*8975f5c5SAndroid Build Coastguard Worker };
1610*8975f5c5SAndroid Build Coastguard Worker
1611*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::ConvertVertexBuffer, setSizes,
1612*8975f5c5SAndroid Build Coastguard Worker ArraySize(setSizes), sizeof(ConvertVertexShaderParams));
1613*8975f5c5SAndroid Build Coastguard Worker }
1614*8975f5c5SAndroid Build Coastguard Worker
ensureImageClearResourcesInitialized(ContextVk * contextVk)1615*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureImageClearResourcesInitialized(ContextVk *contextVk)
1616*8975f5c5SAndroid Build Coastguard Worker {
1617*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[Function::ImageClear])
1618*8975f5c5SAndroid Build Coastguard Worker {
1619*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1620*8975f5c5SAndroid Build Coastguard Worker }
1621*8975f5c5SAndroid Build Coastguard Worker
1622*8975f5c5SAndroid Build Coastguard Worker // The shader does not use any descriptor sets.
1623*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::ImageClear, nullptr, 0,
1624*8975f5c5SAndroid Build Coastguard Worker sizeof(ImageClearShaderParams));
1625*8975f5c5SAndroid Build Coastguard Worker }
1626*8975f5c5SAndroid Build Coastguard Worker
ensureImageCopyResourcesInitialized(ContextVk * contextVk)1627*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureImageCopyResourcesInitialized(ContextVk *contextVk)
1628*8975f5c5SAndroid Build Coastguard Worker {
1629*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[Function::ImageCopy])
1630*8975f5c5SAndroid Build Coastguard Worker {
1631*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1632*8975f5c5SAndroid Build Coastguard Worker }
1633*8975f5c5SAndroid Build Coastguard Worker
1634*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[1] = {
1635*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1},
1636*8975f5c5SAndroid Build Coastguard Worker };
1637*8975f5c5SAndroid Build Coastguard Worker
1638*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::ImageCopy, setSizes, ArraySize(setSizes),
1639*8975f5c5SAndroid Build Coastguard Worker sizeof(ImageCopyShaderParams));
1640*8975f5c5SAndroid Build Coastguard Worker }
1641*8975f5c5SAndroid Build Coastguard Worker
ensureImageCopyResourcesInitializedWithSampler(ContextVk * contextVk,const vk::SamplerDesc & samplerDesc)1642*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureImageCopyResourcesInitializedWithSampler(
1643*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
1644*8975f5c5SAndroid Build Coastguard Worker const vk::SamplerDesc &samplerDesc)
1645*8975f5c5SAndroid Build Coastguard Worker {
1646*8975f5c5SAndroid Build Coastguard Worker if (mImageCopyWithSamplerPipelineLayouts[samplerDesc])
1647*8975f5c5SAndroid Build Coastguard Worker {
1648*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1649*8975f5c5SAndroid Build Coastguard Worker }
1650*8975f5c5SAndroid Build Coastguard Worker
1651*8975f5c5SAndroid Build Coastguard Worker vk::SharedSamplerPtr sampler;
1652*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
1653*8975f5c5SAndroid Build Coastguard Worker contextVk->getRenderer()->getSamplerCache().getSampler(contextVk, samplerDesc, &sampler));
1654*8975f5c5SAndroid Build Coastguard Worker
1655*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetLayoutDesc descriptorSetDesc;
1656*8975f5c5SAndroid Build Coastguard Worker descriptorSetDesc.addBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1,
1657*8975f5c5SAndroid Build Coastguard Worker VK_SHADER_STAGE_FRAGMENT_BIT, &sampler->get());
1658*8975f5c5SAndroid Build Coastguard Worker
1659*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getDescriptorSetLayoutCache().getDescriptorSetLayout(
1660*8975f5c5SAndroid Build Coastguard Worker contextVk, descriptorSetDesc,
1661*8975f5c5SAndroid Build Coastguard Worker &mImageCopyWithSamplerDescriptorSetLayouts[samplerDesc][DescriptorSetIndex::Internal]));
1662*8975f5c5SAndroid Build Coastguard Worker
1663*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[1] = {
1664*8975f5c5SAndroid Build Coastguard Worker // A single YCbCr sampler may consume up to 3 descriptors.
1665*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3},
1666*8975f5c5SAndroid Build Coastguard Worker };
1667*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mImageCopyWithSamplerDescriptorPools[samplerDesc].init(
1668*8975f5c5SAndroid Build Coastguard Worker contextVk, setSizes, 1,
1669*8975f5c5SAndroid Build Coastguard Worker *mImageCopyWithSamplerDescriptorSetLayouts[samplerDesc][DescriptorSetIndex::Internal]));
1670*8975f5c5SAndroid Build Coastguard Worker
1671*8975f5c5SAndroid Build Coastguard Worker vk::PipelineLayoutDesc pipelineLayoutDesc;
1672*8975f5c5SAndroid Build Coastguard Worker pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::Internal, descriptorSetDesc);
1673*8975f5c5SAndroid Build Coastguard Worker pipelineLayoutDesc.updatePushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 0,
1674*8975f5c5SAndroid Build Coastguard Worker sizeof(ImageCopyShaderParams));
1675*8975f5c5SAndroid Build Coastguard Worker
1676*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getPipelineLayoutCache().getPipelineLayout(
1677*8975f5c5SAndroid Build Coastguard Worker contextVk, pipelineLayoutDesc, mImageCopyWithSamplerDescriptorSetLayouts[samplerDesc],
1678*8975f5c5SAndroid Build Coastguard Worker &mImageCopyWithSamplerPipelineLayouts[samplerDesc]));
1679*8975f5c5SAndroid Build Coastguard Worker
1680*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1681*8975f5c5SAndroid Build Coastguard Worker }
1682*8975f5c5SAndroid Build Coastguard Worker
ensureCopyImageToBufferResourcesInitialized(ContextVk * contextVk)1683*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureCopyImageToBufferResourcesInitialized(ContextVk *contextVk)
1684*8975f5c5SAndroid Build Coastguard Worker {
1685*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[Function::CopyImageToBuffer])
1686*8975f5c5SAndroid Build Coastguard Worker {
1687*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1688*8975f5c5SAndroid Build Coastguard Worker }
1689*8975f5c5SAndroid Build Coastguard Worker
1690*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[2] = {
1691*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1},
1692*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1},
1693*8975f5c5SAndroid Build Coastguard Worker };
1694*8975f5c5SAndroid Build Coastguard Worker
1695*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::CopyImageToBuffer, setSizes,
1696*8975f5c5SAndroid Build Coastguard Worker ArraySize(setSizes), sizeof(CopyImageToBufferShaderParams));
1697*8975f5c5SAndroid Build Coastguard Worker }
1698*8975f5c5SAndroid Build Coastguard Worker
ensureBlitResolveResourcesInitialized(ContextVk * contextVk)1699*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureBlitResolveResourcesInitialized(ContextVk *contextVk)
1700*8975f5c5SAndroid Build Coastguard Worker {
1701*8975f5c5SAndroid Build Coastguard Worker if (!mPipelineLayouts[Function::BlitResolve])
1702*8975f5c5SAndroid Build Coastguard Worker {
1703*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[3] = {
1704*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1},
1705*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1},
1706*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_SAMPLER, 1},
1707*8975f5c5SAndroid Build Coastguard Worker };
1708*8975f5c5SAndroid Build Coastguard Worker
1709*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureResourcesInitialized(contextVk, Function::BlitResolve, setSizes,
1710*8975f5c5SAndroid Build Coastguard Worker ArraySize(setSizes), sizeof(BlitResolveShaderParams)));
1711*8975f5c5SAndroid Build Coastguard Worker }
1712*8975f5c5SAndroid Build Coastguard Worker
1713*8975f5c5SAndroid Build Coastguard Worker return ensureSamplersInitialized(contextVk);
1714*8975f5c5SAndroid Build Coastguard Worker }
1715*8975f5c5SAndroid Build Coastguard Worker
ensureBlitResolveStencilNoExportResourcesInitialized(ContextVk * contextVk)1716*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureBlitResolveStencilNoExportResourcesInitialized(ContextVk *contextVk)
1717*8975f5c5SAndroid Build Coastguard Worker {
1718*8975f5c5SAndroid Build Coastguard Worker if (!mPipelineLayouts[Function::BlitResolveStencilNoExport])
1719*8975f5c5SAndroid Build Coastguard Worker {
1720*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[3] = {
1721*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1},
1722*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1},
1723*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_SAMPLER, 1},
1724*8975f5c5SAndroid Build Coastguard Worker };
1725*8975f5c5SAndroid Build Coastguard Worker
1726*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureResourcesInitialized(contextVk, Function::BlitResolveStencilNoExport,
1727*8975f5c5SAndroid Build Coastguard Worker setSizes, ArraySize(setSizes),
1728*8975f5c5SAndroid Build Coastguard Worker sizeof(BlitResolveStencilNoExportShaderParams)));
1729*8975f5c5SAndroid Build Coastguard Worker }
1730*8975f5c5SAndroid Build Coastguard Worker
1731*8975f5c5SAndroid Build Coastguard Worker return ensureSamplersInitialized(contextVk);
1732*8975f5c5SAndroid Build Coastguard Worker }
1733*8975f5c5SAndroid Build Coastguard Worker
ensureExportStencilResourcesInitialized(ContextVk * contextVk)1734*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureExportStencilResourcesInitialized(ContextVk *contextVk)
1735*8975f5c5SAndroid Build Coastguard Worker {
1736*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[Function::ExportStencil])
1737*8975f5c5SAndroid Build Coastguard Worker {
1738*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1739*8975f5c5SAndroid Build Coastguard Worker }
1740*8975f5c5SAndroid Build Coastguard Worker
1741*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[1] = {
1742*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1},
1743*8975f5c5SAndroid Build Coastguard Worker };
1744*8975f5c5SAndroid Build Coastguard Worker
1745*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::ExportStencil, setSizes,
1746*8975f5c5SAndroid Build Coastguard Worker ArraySize(setSizes), sizeof(ExportStencilShaderParams));
1747*8975f5c5SAndroid Build Coastguard Worker }
1748*8975f5c5SAndroid Build Coastguard Worker
ensureOverlayDrawResourcesInitialized(ContextVk * contextVk)1749*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureOverlayDrawResourcesInitialized(ContextVk *contextVk)
1750*8975f5c5SAndroid Build Coastguard Worker {
1751*8975f5c5SAndroid Build Coastguard Worker if (!mPipelineLayouts[Function::OverlayDraw])
1752*8975f5c5SAndroid Build Coastguard Worker {
1753*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[3] = {
1754*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1},
1755*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1},
1756*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1},
1757*8975f5c5SAndroid Build Coastguard Worker };
1758*8975f5c5SAndroid Build Coastguard Worker
1759*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureResourcesInitialized(contextVk, Function::OverlayDraw, setSizes,
1760*8975f5c5SAndroid Build Coastguard Worker ArraySize(setSizes), sizeof(OverlayDrawShaderParams)));
1761*8975f5c5SAndroid Build Coastguard Worker }
1762*8975f5c5SAndroid Build Coastguard Worker
1763*8975f5c5SAndroid Build Coastguard Worker return ensureSamplersInitialized(contextVk);
1764*8975f5c5SAndroid Build Coastguard Worker }
1765*8975f5c5SAndroid Build Coastguard Worker
ensureGenerateMipmapResourcesInitialized(ContextVk * contextVk)1766*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureGenerateMipmapResourcesInitialized(ContextVk *contextVk)
1767*8975f5c5SAndroid Build Coastguard Worker {
1768*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[Function::GenerateMipmap])
1769*8975f5c5SAndroid Build Coastguard Worker {
1770*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1771*8975f5c5SAndroid Build Coastguard Worker }
1772*8975f5c5SAndroid Build Coastguard Worker
1773*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[2] = {
1774*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, GetGenerateMipmapMaxLevels(contextVk)},
1775*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1},
1776*8975f5c5SAndroid Build Coastguard Worker };
1777*8975f5c5SAndroid Build Coastguard Worker
1778*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::GenerateMipmap, setSizes,
1779*8975f5c5SAndroid Build Coastguard Worker ArraySize(setSizes), sizeof(GenerateMipmapShaderParams));
1780*8975f5c5SAndroid Build Coastguard Worker }
1781*8975f5c5SAndroid Build Coastguard Worker
ensureTransCodeEtcToBcResourcesInitialized(ContextVk * contextVk)1782*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureTransCodeEtcToBcResourcesInitialized(ContextVk *contextVk)
1783*8975f5c5SAndroid Build Coastguard Worker {
1784*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[Function::TransCodeEtcToBc])
1785*8975f5c5SAndroid Build Coastguard Worker {
1786*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1787*8975f5c5SAndroid Build Coastguard Worker }
1788*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[2] = {
1789*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1},
1790*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1},
1791*8975f5c5SAndroid Build Coastguard Worker };
1792*8975f5c5SAndroid Build Coastguard Worker
1793*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::TransCodeEtcToBc, setSizes,
1794*8975f5c5SAndroid Build Coastguard Worker ArraySize(setSizes), sizeof(EtcToBcShaderParams));
1795*8975f5c5SAndroid Build Coastguard Worker }
1796*8975f5c5SAndroid Build Coastguard Worker
ensureUnresolveResourcesInitialized(ContextVk * contextVk,Function function,uint32_t attachmentCount)1797*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureUnresolveResourcesInitialized(ContextVk *contextVk,
1798*8975f5c5SAndroid Build Coastguard Worker Function function,
1799*8975f5c5SAndroid Build Coastguard Worker uint32_t attachmentCount)
1800*8975f5c5SAndroid Build Coastguard Worker {
1801*8975f5c5SAndroid Build Coastguard Worker ASSERT(static_cast<uint32_t>(function) -
1802*8975f5c5SAndroid Build Coastguard Worker static_cast<uint32_t>(Function::Unresolve1Attachment) ==
1803*8975f5c5SAndroid Build Coastguard Worker attachmentCount - 1);
1804*8975f5c5SAndroid Build Coastguard Worker
1805*8975f5c5SAndroid Build Coastguard Worker if (mPipelineLayouts[function])
1806*8975f5c5SAndroid Build Coastguard Worker {
1807*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1808*8975f5c5SAndroid Build Coastguard Worker }
1809*8975f5c5SAndroid Build Coastguard Worker
1810*8975f5c5SAndroid Build Coastguard Worker vk::FramebufferAttachmentArray<VkDescriptorPoolSize> setSizes;
1811*8975f5c5SAndroid Build Coastguard Worker std::fill(setSizes.begin(), setSizes.end(),
1812*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1});
1813*8975f5c5SAndroid Build Coastguard Worker
1814*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, function, setSizes.data(), attachmentCount, 0);
1815*8975f5c5SAndroid Build Coastguard Worker }
1816*8975f5c5SAndroid Build Coastguard Worker
ensureSamplersInitialized(ContextVk * contextVk)1817*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureSamplersInitialized(ContextVk *contextVk)
1818*8975f5c5SAndroid Build Coastguard Worker {
1819*8975f5c5SAndroid Build Coastguard Worker VkSamplerCreateInfo samplerInfo = {};
1820*8975f5c5SAndroid Build Coastguard Worker samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
1821*8975f5c5SAndroid Build Coastguard Worker samplerInfo.flags = 0;
1822*8975f5c5SAndroid Build Coastguard Worker samplerInfo.magFilter = VK_FILTER_NEAREST;
1823*8975f5c5SAndroid Build Coastguard Worker samplerInfo.minFilter = VK_FILTER_NEAREST;
1824*8975f5c5SAndroid Build Coastguard Worker samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
1825*8975f5c5SAndroid Build Coastguard Worker samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1826*8975f5c5SAndroid Build Coastguard Worker samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1827*8975f5c5SAndroid Build Coastguard Worker samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1828*8975f5c5SAndroid Build Coastguard Worker samplerInfo.mipLodBias = 0.0f;
1829*8975f5c5SAndroid Build Coastguard Worker samplerInfo.anisotropyEnable = VK_FALSE;
1830*8975f5c5SAndroid Build Coastguard Worker samplerInfo.maxAnisotropy = 1;
1831*8975f5c5SAndroid Build Coastguard Worker samplerInfo.compareEnable = VK_FALSE;
1832*8975f5c5SAndroid Build Coastguard Worker samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
1833*8975f5c5SAndroid Build Coastguard Worker samplerInfo.minLod = 0;
1834*8975f5c5SAndroid Build Coastguard Worker samplerInfo.maxLod = 0;
1835*8975f5c5SAndroid Build Coastguard Worker samplerInfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
1836*8975f5c5SAndroid Build Coastguard Worker samplerInfo.unnormalizedCoordinates = VK_FALSE;
1837*8975f5c5SAndroid Build Coastguard Worker
1838*8975f5c5SAndroid Build Coastguard Worker if (!mPointSampler.valid())
1839*8975f5c5SAndroid Build Coastguard Worker {
1840*8975f5c5SAndroid Build Coastguard Worker ANGLE_VK_TRY(contextVk, mPointSampler.init(contextVk->getDevice(), samplerInfo));
1841*8975f5c5SAndroid Build Coastguard Worker }
1842*8975f5c5SAndroid Build Coastguard Worker
1843*8975f5c5SAndroid Build Coastguard Worker samplerInfo.magFilter = VK_FILTER_LINEAR;
1844*8975f5c5SAndroid Build Coastguard Worker samplerInfo.minFilter = VK_FILTER_LINEAR;
1845*8975f5c5SAndroid Build Coastguard Worker
1846*8975f5c5SAndroid Build Coastguard Worker if (!mLinearSampler.valid())
1847*8975f5c5SAndroid Build Coastguard Worker {
1848*8975f5c5SAndroid Build Coastguard Worker ANGLE_VK_TRY(contextVk, mLinearSampler.init(contextVk->getDevice(), samplerInfo));
1849*8975f5c5SAndroid Build Coastguard Worker }
1850*8975f5c5SAndroid Build Coastguard Worker
1851*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1852*8975f5c5SAndroid Build Coastguard Worker }
1853*8975f5c5SAndroid Build Coastguard Worker
ensureGenerateFragmentShadingRateResourcesInitialized(ContextVk * contextVk)1854*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::ensureGenerateFragmentShadingRateResourcesInitialized(ContextVk *contextVk)
1855*8975f5c5SAndroid Build Coastguard Worker {
1856*8975f5c5SAndroid Build Coastguard Worker if (mGenerateFragmentShadingRateAttachment.program.valid(gl::ShaderType::Compute))
1857*8975f5c5SAndroid Build Coastguard Worker {
1858*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1859*8975f5c5SAndroid Build Coastguard Worker }
1860*8975f5c5SAndroid Build Coastguard Worker
1861*8975f5c5SAndroid Build Coastguard Worker VkDescriptorPoolSize setSizes[1] = {
1862*8975f5c5SAndroid Build Coastguard Worker {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1},
1863*8975f5c5SAndroid Build Coastguard Worker };
1864*8975f5c5SAndroid Build Coastguard Worker
1865*8975f5c5SAndroid Build Coastguard Worker return ensureResourcesInitialized(contextVk, Function::GenerateFragmentShadingRate, setSizes,
1866*8975f5c5SAndroid Build Coastguard Worker ArraySize(setSizes),
1867*8975f5c5SAndroid Build Coastguard Worker sizeof(GenerateFragmentShadingRateParameters));
1868*8975f5c5SAndroid Build Coastguard Worker }
1869*8975f5c5SAndroid Build Coastguard Worker
setupComputeProgram(ContextVk * contextVk,Function function,const vk::ShaderModulePtr & csShader,ComputeShaderProgramAndPipelines * programAndPipelines,const VkDescriptorSet descriptorSet,const void * pushConstants,size_t pushConstantsSize,vk::OutsideRenderPassCommandBufferHelper * commandBufferHelper)1870*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::setupComputeProgram(
1871*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
1872*8975f5c5SAndroid Build Coastguard Worker Function function,
1873*8975f5c5SAndroid Build Coastguard Worker const vk::ShaderModulePtr &csShader,
1874*8975f5c5SAndroid Build Coastguard Worker ComputeShaderProgramAndPipelines *programAndPipelines,
1875*8975f5c5SAndroid Build Coastguard Worker const VkDescriptorSet descriptorSet,
1876*8975f5c5SAndroid Build Coastguard Worker const void *pushConstants,
1877*8975f5c5SAndroid Build Coastguard Worker size_t pushConstantsSize,
1878*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper)
1879*8975f5c5SAndroid Build Coastguard Worker {
1880*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
1881*8975f5c5SAndroid Build Coastguard Worker
1882*8975f5c5SAndroid Build Coastguard Worker ASSERT(function >= Function::ComputeStartIndex);
1883*8975f5c5SAndroid Build Coastguard Worker
1884*8975f5c5SAndroid Build Coastguard Worker const vk::PipelineLayoutPtr &pipelineLayout = mPipelineLayouts[function];
1885*8975f5c5SAndroid Build Coastguard Worker
1886*8975f5c5SAndroid Build Coastguard Worker if (!programAndPipelines->program.valid(gl::ShaderType::Compute))
1887*8975f5c5SAndroid Build Coastguard Worker {
1888*8975f5c5SAndroid Build Coastguard Worker programAndPipelines->program.setShader(gl::ShaderType::Compute, csShader);
1889*8975f5c5SAndroid Build Coastguard Worker }
1890*8975f5c5SAndroid Build Coastguard Worker
1891*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper *pipeline;
1892*8975f5c5SAndroid Build Coastguard Worker vk::PipelineCacheAccess pipelineCache;
1893*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(renderer->getPipelineCache(contextVk, &pipelineCache));
1894*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(programAndPipelines->program.getOrCreateComputePipeline(
1895*8975f5c5SAndroid Build Coastguard Worker contextVk, &programAndPipelines->pipelines, &pipelineCache, *pipelineLayout,
1896*8975f5c5SAndroid Build Coastguard Worker vk::GetComputePipelineOptions(contextVk->pipelineRobustness(),
1897*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineProtectedAccess()),
1898*8975f5c5SAndroid Build Coastguard Worker PipelineSource::Utils, &pipeline, nullptr, nullptr));
1899*8975f5c5SAndroid Build Coastguard Worker commandBufferHelper->retainResource(pipeline);
1900*8975f5c5SAndroid Build Coastguard Worker
1901*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer = &commandBufferHelper->getCommandBuffer();
1902*8975f5c5SAndroid Build Coastguard Worker commandBuffer->bindComputePipeline(pipeline->getPipeline());
1903*8975f5c5SAndroid Build Coastguard Worker
1904*8975f5c5SAndroid Build Coastguard Worker contextVk->invalidateComputePipelineBinding();
1905*8975f5c5SAndroid Build Coastguard Worker
1906*8975f5c5SAndroid Build Coastguard Worker if (descriptorSet != VK_NULL_HANDLE)
1907*8975f5c5SAndroid Build Coastguard Worker {
1908*8975f5c5SAndroid Build Coastguard Worker commandBuffer->bindDescriptorSets(*pipelineLayout, VK_PIPELINE_BIND_POINT_COMPUTE,
1909*8975f5c5SAndroid Build Coastguard Worker DescriptorSetIndex::Internal, 1, &descriptorSet, 0,
1910*8975f5c5SAndroid Build Coastguard Worker nullptr);
1911*8975f5c5SAndroid Build Coastguard Worker contextVk->invalidateComputeDescriptorSet(DescriptorSetIndex::Internal);
1912*8975f5c5SAndroid Build Coastguard Worker }
1913*8975f5c5SAndroid Build Coastguard Worker
1914*8975f5c5SAndroid Build Coastguard Worker if (pushConstants)
1915*8975f5c5SAndroid Build Coastguard Worker {
1916*8975f5c5SAndroid Build Coastguard Worker commandBuffer->pushConstants(*pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0,
1917*8975f5c5SAndroid Build Coastguard Worker static_cast<uint32_t>(pushConstantsSize), pushConstants);
1918*8975f5c5SAndroid Build Coastguard Worker }
1919*8975f5c5SAndroid Build Coastguard Worker
1920*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1921*8975f5c5SAndroid Build Coastguard Worker }
1922*8975f5c5SAndroid Build Coastguard Worker
setupGraphicsProgramWithLayout(ContextVk * contextVk,const vk::PipelineLayout & pipelineLayout,const vk::ShaderModulePtr & vsShader,const vk::ShaderModulePtr & fsShader,GraphicsShaderProgramAndPipelines * programAndPipelines,const vk::GraphicsPipelineDesc * pipelineDesc,const VkDescriptorSet descriptorSet,const void * pushConstants,size_t pushConstantsSize,vk::RenderPassCommandBuffer * commandBuffer)1923*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::setupGraphicsProgramWithLayout(
1924*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
1925*8975f5c5SAndroid Build Coastguard Worker const vk::PipelineLayout &pipelineLayout,
1926*8975f5c5SAndroid Build Coastguard Worker const vk::ShaderModulePtr &vsShader,
1927*8975f5c5SAndroid Build Coastguard Worker const vk::ShaderModulePtr &fsShader,
1928*8975f5c5SAndroid Build Coastguard Worker GraphicsShaderProgramAndPipelines *programAndPipelines,
1929*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc *pipelineDesc,
1930*8975f5c5SAndroid Build Coastguard Worker const VkDescriptorSet descriptorSet,
1931*8975f5c5SAndroid Build Coastguard Worker const void *pushConstants,
1932*8975f5c5SAndroid Build Coastguard Worker size_t pushConstantsSize,
1933*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer)
1934*8975f5c5SAndroid Build Coastguard Worker {
1935*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
1936*8975f5c5SAndroid Build Coastguard Worker
1937*8975f5c5SAndroid Build Coastguard Worker if (!programAndPipelines->program.valid(gl::ShaderType::Vertex))
1938*8975f5c5SAndroid Build Coastguard Worker {
1939*8975f5c5SAndroid Build Coastguard Worker programAndPipelines->program.setShader(gl::ShaderType::Vertex, vsShader);
1940*8975f5c5SAndroid Build Coastguard Worker if (fsShader)
1941*8975f5c5SAndroid Build Coastguard Worker {
1942*8975f5c5SAndroid Build Coastguard Worker programAndPipelines->program.setShader(gl::ShaderType::Fragment, fsShader);
1943*8975f5c5SAndroid Build Coastguard Worker }
1944*8975f5c5SAndroid Build Coastguard Worker }
1945*8975f5c5SAndroid Build Coastguard Worker
1946*8975f5c5SAndroid Build Coastguard Worker // This value is not used but is passed to getGraphicsPipeline to avoid a nullptr check.
1947*8975f5c5SAndroid Build Coastguard Worker vk::PipelineCacheAccess pipelineCache;
1948*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(renderer->getPipelineCache(contextVk, &pipelineCache));
1949*8975f5c5SAndroid Build Coastguard Worker
1950*8975f5c5SAndroid Build Coastguard Worker // Pull in a compatible RenderPass.
1951*8975f5c5SAndroid Build Coastguard Worker const vk::RenderPass *compatibleRenderPass = nullptr;
1952*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getCompatibleRenderPass(pipelineDesc->getRenderPassDesc(),
1953*8975f5c5SAndroid Build Coastguard Worker &compatibleRenderPass));
1954*8975f5c5SAndroid Build Coastguard Worker
1955*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc *descPtr;
1956*8975f5c5SAndroid Build Coastguard Worker vk::PipelineHelper *helper;
1957*8975f5c5SAndroid Build Coastguard Worker
1958*8975f5c5SAndroid Build Coastguard Worker if (!programAndPipelines->pipelines.getPipeline(*pipelineDesc, &descPtr, &helper))
1959*8975f5c5SAndroid Build Coastguard Worker {
1960*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(programAndPipelines->program.createGraphicsPipeline(
1961*8975f5c5SAndroid Build Coastguard Worker contextVk, &programAndPipelines->pipelines, &pipelineCache, *compatibleRenderPass,
1962*8975f5c5SAndroid Build Coastguard Worker pipelineLayout, PipelineSource::Utils, *pipelineDesc, {}, &descPtr, &helper));
1963*8975f5c5SAndroid Build Coastguard Worker }
1964*8975f5c5SAndroid Build Coastguard Worker
1965*8975f5c5SAndroid Build Coastguard Worker contextVk->getStartedRenderPassCommands().retainResource(helper);
1966*8975f5c5SAndroid Build Coastguard Worker commandBuffer->bindGraphicsPipeline(helper->getPipeline());
1967*8975f5c5SAndroid Build Coastguard Worker
1968*8975f5c5SAndroid Build Coastguard Worker contextVk->invalidateGraphicsPipelineBinding();
1969*8975f5c5SAndroid Build Coastguard Worker
1970*8975f5c5SAndroid Build Coastguard Worker if (descriptorSet != VK_NULL_HANDLE)
1971*8975f5c5SAndroid Build Coastguard Worker {
1972*8975f5c5SAndroid Build Coastguard Worker commandBuffer->bindDescriptorSets(pipelineLayout, VK_PIPELINE_BIND_POINT_GRAPHICS,
1973*8975f5c5SAndroid Build Coastguard Worker DescriptorSetIndex::Internal, 1, &descriptorSet, 0,
1974*8975f5c5SAndroid Build Coastguard Worker nullptr);
1975*8975f5c5SAndroid Build Coastguard Worker contextVk->invalidateGraphicsDescriptorSet(DescriptorSetIndex::Internal);
1976*8975f5c5SAndroid Build Coastguard Worker }
1977*8975f5c5SAndroid Build Coastguard Worker
1978*8975f5c5SAndroid Build Coastguard Worker if (pushConstants)
1979*8975f5c5SAndroid Build Coastguard Worker {
1980*8975f5c5SAndroid Build Coastguard Worker commandBuffer->pushConstants(pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0,
1981*8975f5c5SAndroid Build Coastguard Worker static_cast<uint32_t>(pushConstantsSize), pushConstants);
1982*8975f5c5SAndroid Build Coastguard Worker }
1983*8975f5c5SAndroid Build Coastguard Worker
1984*8975f5c5SAndroid Build Coastguard Worker ResetDynamicState(contextVk, commandBuffer);
1985*8975f5c5SAndroid Build Coastguard Worker
1986*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1987*8975f5c5SAndroid Build Coastguard Worker }
1988*8975f5c5SAndroid Build Coastguard Worker
setupGraphicsProgram(ContextVk * contextVk,Function function,const vk::ShaderModulePtr & vsShader,const vk::ShaderModulePtr & fsShader,GraphicsShaderProgramAndPipelines * programAndPipelines,const vk::GraphicsPipelineDesc * pipelineDesc,const VkDescriptorSet descriptorSet,const void * pushConstants,size_t pushConstantsSize,vk::RenderPassCommandBuffer * commandBuffer)1989*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::setupGraphicsProgram(ContextVk *contextVk,
1990*8975f5c5SAndroid Build Coastguard Worker Function function,
1991*8975f5c5SAndroid Build Coastguard Worker const vk::ShaderModulePtr &vsShader,
1992*8975f5c5SAndroid Build Coastguard Worker const vk::ShaderModulePtr &fsShader,
1993*8975f5c5SAndroid Build Coastguard Worker GraphicsShaderProgramAndPipelines *programAndPipelines,
1994*8975f5c5SAndroid Build Coastguard Worker const vk::GraphicsPipelineDesc *pipelineDesc,
1995*8975f5c5SAndroid Build Coastguard Worker const VkDescriptorSet descriptorSet,
1996*8975f5c5SAndroid Build Coastguard Worker const void *pushConstants,
1997*8975f5c5SAndroid Build Coastguard Worker size_t pushConstantsSize,
1998*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer)
1999*8975f5c5SAndroid Build Coastguard Worker {
2000*8975f5c5SAndroid Build Coastguard Worker ASSERT(function < Function::ComputeStartIndex);
2001*8975f5c5SAndroid Build Coastguard Worker
2002*8975f5c5SAndroid Build Coastguard Worker return setupGraphicsProgramWithLayout(
2003*8975f5c5SAndroid Build Coastguard Worker contextVk, *mPipelineLayouts[function], vsShader, fsShader, programAndPipelines,
2004*8975f5c5SAndroid Build Coastguard Worker pipelineDesc, descriptorSet, pushConstants, pushConstantsSize, commandBuffer);
2005*8975f5c5SAndroid Build Coastguard Worker }
2006*8975f5c5SAndroid Build Coastguard Worker
convertIndexBuffer(ContextVk * contextVk,vk::BufferHelper * dst,vk::BufferHelper * src,const ConvertIndexParameters & params)2007*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::convertIndexBuffer(ContextVk *contextVk,
2008*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dst,
2009*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *src,
2010*8975f5c5SAndroid Build Coastguard Worker const ConvertIndexParameters ¶ms)
2011*8975f5c5SAndroid Build Coastguard Worker {
2012*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureConvertIndexResourcesInitialized(contextVk));
2013*8975f5c5SAndroid Build Coastguard Worker
2014*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access;
2015*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderRead(src);
2016*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(dst);
2017*8975f5c5SAndroid Build Coastguard Worker
2018*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
2019*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
2020*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper(access, &commandBufferHelper));
2021*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &commandBufferHelper->getCommandBuffer();
2022*8975f5c5SAndroid Build Coastguard Worker
2023*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
2024*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, commandBufferHelper, Function::ConvertIndexBuffer,
2025*8975f5c5SAndroid Build Coastguard Worker &descriptorSet));
2026*8975f5c5SAndroid Build Coastguard Worker
2027*8975f5c5SAndroid Build Coastguard Worker std::array<VkDescriptorBufferInfo, 2> buffers = {{
2028*8975f5c5SAndroid Build Coastguard Worker {dst->getBuffer().getHandle(), dst->getOffset(), dst->getSize()},
2029*8975f5c5SAndroid Build Coastguard Worker {src->getBuffer().getHandle(), src->getOffset(), src->getSize()},
2030*8975f5c5SAndroid Build Coastguard Worker }};
2031*8975f5c5SAndroid Build Coastguard Worker
2032*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfo = {};
2033*8975f5c5SAndroid Build Coastguard Worker writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2034*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstSet = descriptorSet;
2035*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstBinding = kConvertIndexDestinationBinding;
2036*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorCount = 2;
2037*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2038*8975f5c5SAndroid Build Coastguard Worker writeInfo.pBufferInfo = buffers.data();
2039*8975f5c5SAndroid Build Coastguard Worker
2040*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 1, &writeInfo, 0, nullptr);
2041*8975f5c5SAndroid Build Coastguard Worker
2042*8975f5c5SAndroid Build Coastguard Worker ConvertIndexShaderParams shaderParams = {params.srcOffset, params.dstOffset >> 2,
2043*8975f5c5SAndroid Build Coastguard Worker params.maxIndex, 0};
2044*8975f5c5SAndroid Build Coastguard Worker
2045*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = 0;
2046*8975f5c5SAndroid Build Coastguard Worker if (contextVk->getState().isPrimitiveRestartEnabled())
2047*8975f5c5SAndroid Build Coastguard Worker {
2048*8975f5c5SAndroid Build Coastguard Worker flags |= vk::InternalShader::ConvertIndex_comp::kIsPrimitiveRestartEnabled;
2049*8975f5c5SAndroid Build Coastguard Worker }
2050*8975f5c5SAndroid Build Coastguard Worker
2051*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr shader;
2052*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getShaderLibrary().getConvertIndex_comp(contextVk, flags, &shader));
2053*8975f5c5SAndroid Build Coastguard Worker
2054*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupComputeProgram(contextVk, Function::ConvertIndexBuffer, shader,
2055*8975f5c5SAndroid Build Coastguard Worker &mConvertIndex[flags], descriptorSet, &shaderParams,
2056*8975f5c5SAndroid Build Coastguard Worker sizeof(ConvertIndexShaderParams), commandBufferHelper));
2057*8975f5c5SAndroid Build Coastguard Worker
2058*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kInvocationsPerGroup = 64;
2059*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kInvocationsPerIndex = 2;
2060*8975f5c5SAndroid Build Coastguard Worker const uint32_t kIndexCount = params.maxIndex;
2061*8975f5c5SAndroid Build Coastguard Worker const uint32_t kGroupCount =
2062*8975f5c5SAndroid Build Coastguard Worker UnsignedCeilDivide(kIndexCount * kInvocationsPerIndex, kInvocationsPerGroup);
2063*8975f5c5SAndroid Build Coastguard Worker commandBuffer->dispatch(kGroupCount, 1, 1);
2064*8975f5c5SAndroid Build Coastguard Worker
2065*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2066*8975f5c5SAndroid Build Coastguard Worker }
2067*8975f5c5SAndroid Build Coastguard Worker
convertIndexIndirectBuffer(ContextVk * contextVk,vk::BufferHelper * srcIndirectBuf,vk::BufferHelper * srcIndexBuf,vk::BufferHelper * dstIndirectBuf,vk::BufferHelper * dstIndexBuf,const ConvertIndexIndirectParameters & params)2068*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::convertIndexIndirectBuffer(ContextVk *contextVk,
2069*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *srcIndirectBuf,
2070*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *srcIndexBuf,
2071*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dstIndirectBuf,
2072*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dstIndexBuf,
2073*8975f5c5SAndroid Build Coastguard Worker const ConvertIndexIndirectParameters ¶ms)
2074*8975f5c5SAndroid Build Coastguard Worker {
2075*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureConvertIndexIndirectResourcesInitialized(contextVk));
2076*8975f5c5SAndroid Build Coastguard Worker
2077*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access;
2078*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderRead(srcIndirectBuf);
2079*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderRead(srcIndexBuf);
2080*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(dstIndirectBuf);
2081*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(dstIndexBuf);
2082*8975f5c5SAndroid Build Coastguard Worker
2083*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
2084*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
2085*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper(access, &commandBufferHelper));
2086*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &commandBufferHelper->getCommandBuffer();
2087*8975f5c5SAndroid Build Coastguard Worker
2088*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
2089*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, commandBufferHelper,
2090*8975f5c5SAndroid Build Coastguard Worker Function::ConvertIndexIndirectBuffer, &descriptorSet));
2091*8975f5c5SAndroid Build Coastguard Worker
2092*8975f5c5SAndroid Build Coastguard Worker std::array<VkDescriptorBufferInfo, 4> buffers = {{
2093*8975f5c5SAndroid Build Coastguard Worker {dstIndexBuf->getBuffer().getHandle(), dstIndexBuf->getOffset(), dstIndexBuf->getSize()},
2094*8975f5c5SAndroid Build Coastguard Worker {srcIndexBuf->getBuffer().getHandle(), srcIndexBuf->getOffset(), srcIndexBuf->getSize()},
2095*8975f5c5SAndroid Build Coastguard Worker {srcIndirectBuf->getBuffer().getHandle(), srcIndirectBuf->getOffset(),
2096*8975f5c5SAndroid Build Coastguard Worker srcIndirectBuf->getSize()},
2097*8975f5c5SAndroid Build Coastguard Worker {dstIndirectBuf->getBuffer().getHandle(), dstIndirectBuf->getOffset(),
2098*8975f5c5SAndroid Build Coastguard Worker dstIndirectBuf->getSize()},
2099*8975f5c5SAndroid Build Coastguard Worker }};
2100*8975f5c5SAndroid Build Coastguard Worker
2101*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfo = {};
2102*8975f5c5SAndroid Build Coastguard Worker writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2103*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstSet = descriptorSet;
2104*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstBinding = kConvertIndexDestinationBinding;
2105*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorCount = 4;
2106*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2107*8975f5c5SAndroid Build Coastguard Worker writeInfo.pBufferInfo = buffers.data();
2108*8975f5c5SAndroid Build Coastguard Worker
2109*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 1, &writeInfo, 0, nullptr);
2110*8975f5c5SAndroid Build Coastguard Worker
2111*8975f5c5SAndroid Build Coastguard Worker ConvertIndexIndirectShaderParams shaderParams = {
2112*8975f5c5SAndroid Build Coastguard Worker params.srcIndirectBufOffset >> 2, params.srcIndexBufOffset, params.dstIndexBufOffset >> 2,
2113*8975f5c5SAndroid Build Coastguard Worker params.maxIndex, params.dstIndirectBufOffset >> 2};
2114*8975f5c5SAndroid Build Coastguard Worker
2115*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = vk::InternalShader::ConvertIndex_comp::kIsIndirect;
2116*8975f5c5SAndroid Build Coastguard Worker if (contextVk->getState().isPrimitiveRestartEnabled())
2117*8975f5c5SAndroid Build Coastguard Worker {
2118*8975f5c5SAndroid Build Coastguard Worker flags |= vk::InternalShader::ConvertIndex_comp::kIsPrimitiveRestartEnabled;
2119*8975f5c5SAndroid Build Coastguard Worker }
2120*8975f5c5SAndroid Build Coastguard Worker
2121*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr shader;
2122*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getShaderLibrary().getConvertIndex_comp(contextVk, flags, &shader));
2123*8975f5c5SAndroid Build Coastguard Worker
2124*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupComputeProgram(contextVk, Function::ConvertIndexIndirectBuffer, shader,
2125*8975f5c5SAndroid Build Coastguard Worker &mConvertIndex[flags], descriptorSet, &shaderParams,
2126*8975f5c5SAndroid Build Coastguard Worker sizeof(ConvertIndexIndirectShaderParams), commandBufferHelper));
2127*8975f5c5SAndroid Build Coastguard Worker
2128*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kInvocationsPerGroup = 64;
2129*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kInvocationsPerIndex = 2;
2130*8975f5c5SAndroid Build Coastguard Worker const uint32_t kIndexCount = params.maxIndex;
2131*8975f5c5SAndroid Build Coastguard Worker const uint32_t kGroupCount =
2132*8975f5c5SAndroid Build Coastguard Worker UnsignedCeilDivide(kIndexCount * kInvocationsPerIndex, kInvocationsPerGroup);
2133*8975f5c5SAndroid Build Coastguard Worker commandBuffer->dispatch(kGroupCount, 1, 1);
2134*8975f5c5SAndroid Build Coastguard Worker
2135*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2136*8975f5c5SAndroid Build Coastguard Worker }
2137*8975f5c5SAndroid Build Coastguard Worker
convertLineLoopIndexIndirectBuffer(ContextVk * contextVk,vk::BufferHelper * srcIndirectBuffer,vk::BufferHelper * srcIndexBuffer,vk::BufferHelper * dstIndirectBuffer,vk::BufferHelper * dstIndexBuffer,const ConvertLineLoopIndexIndirectParameters & params)2138*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::convertLineLoopIndexIndirectBuffer(
2139*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
2140*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *srcIndirectBuffer,
2141*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *srcIndexBuffer,
2142*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dstIndirectBuffer,
2143*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dstIndexBuffer,
2144*8975f5c5SAndroid Build Coastguard Worker const ConvertLineLoopIndexIndirectParameters ¶ms)
2145*8975f5c5SAndroid Build Coastguard Worker {
2146*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureConvertIndexIndirectLineLoopResourcesInitialized(contextVk));
2147*8975f5c5SAndroid Build Coastguard Worker
2148*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access;
2149*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderRead(srcIndirectBuffer);
2150*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderRead(srcIndexBuffer);
2151*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(dstIndirectBuffer);
2152*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(dstIndexBuffer);
2153*8975f5c5SAndroid Build Coastguard Worker
2154*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
2155*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
2156*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper(access, &commandBufferHelper));
2157*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &commandBufferHelper->getCommandBuffer();
2158*8975f5c5SAndroid Build Coastguard Worker
2159*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
2160*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, commandBufferHelper,
2161*8975f5c5SAndroid Build Coastguard Worker Function::ConvertIndexIndirectLineLoopBuffer, &descriptorSet));
2162*8975f5c5SAndroid Build Coastguard Worker
2163*8975f5c5SAndroid Build Coastguard Worker std::array<VkDescriptorBufferInfo, 4> buffers = {{
2164*8975f5c5SAndroid Build Coastguard Worker {dstIndexBuffer->getBuffer().getHandle(), dstIndexBuffer->getOffset(),
2165*8975f5c5SAndroid Build Coastguard Worker dstIndexBuffer->getSize()},
2166*8975f5c5SAndroid Build Coastguard Worker {srcIndexBuffer->getBuffer().getHandle(), srcIndexBuffer->getOffset(),
2167*8975f5c5SAndroid Build Coastguard Worker srcIndexBuffer->getSize()},
2168*8975f5c5SAndroid Build Coastguard Worker {srcIndirectBuffer->getBuffer().getHandle(), srcIndirectBuffer->getOffset(),
2169*8975f5c5SAndroid Build Coastguard Worker srcIndirectBuffer->getSize()},
2170*8975f5c5SAndroid Build Coastguard Worker {dstIndirectBuffer->getBuffer().getHandle(), dstIndirectBuffer->getOffset(),
2171*8975f5c5SAndroid Build Coastguard Worker dstIndirectBuffer->getSize()},
2172*8975f5c5SAndroid Build Coastguard Worker }};
2173*8975f5c5SAndroid Build Coastguard Worker
2174*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfo = {};
2175*8975f5c5SAndroid Build Coastguard Worker writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2176*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstSet = descriptorSet;
2177*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstBinding = kConvertIndexDestinationBinding;
2178*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorCount = 4;
2179*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2180*8975f5c5SAndroid Build Coastguard Worker writeInfo.pBufferInfo = buffers.data();
2181*8975f5c5SAndroid Build Coastguard Worker
2182*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 1, &writeInfo, 0, nullptr);
2183*8975f5c5SAndroid Build Coastguard Worker
2184*8975f5c5SAndroid Build Coastguard Worker ConvertIndexIndirectLineLoopShaderParams shaderParams = {
2185*8975f5c5SAndroid Build Coastguard Worker params.indirectBufferOffset >> 2, params.dstIndirectBufferOffset >> 2,
2186*8975f5c5SAndroid Build Coastguard Worker params.srcIndexBufferOffset, params.dstIndexBufferOffset >> 2,
2187*8975f5c5SAndroid Build Coastguard Worker contextVk->getState().isPrimitiveRestartEnabled()};
2188*8975f5c5SAndroid Build Coastguard Worker
2189*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = GetConvertIndexIndirectLineLoopFlag(params.indicesBitsWidth);
2190*8975f5c5SAndroid Build Coastguard Worker
2191*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr shader;
2192*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getShaderLibrary().getConvertIndexIndirectLineLoop_comp(contextVk, flags,
2193*8975f5c5SAndroid Build Coastguard Worker &shader));
2194*8975f5c5SAndroid Build Coastguard Worker
2195*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupComputeProgram(contextVk, Function::ConvertIndexIndirectLineLoopBuffer, shader,
2196*8975f5c5SAndroid Build Coastguard Worker &mConvertIndexIndirectLineLoop[flags], descriptorSet,
2197*8975f5c5SAndroid Build Coastguard Worker &shaderParams, sizeof(ConvertIndexIndirectLineLoopShaderParams),
2198*8975f5c5SAndroid Build Coastguard Worker commandBufferHelper));
2199*8975f5c5SAndroid Build Coastguard Worker
2200*8975f5c5SAndroid Build Coastguard Worker commandBuffer->dispatch(1, 1, 1);
2201*8975f5c5SAndroid Build Coastguard Worker
2202*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2203*8975f5c5SAndroid Build Coastguard Worker }
2204*8975f5c5SAndroid Build Coastguard Worker
convertLineLoopArrayIndirectBuffer(ContextVk * contextVk,vk::BufferHelper * srcIndirectBuffer,vk::BufferHelper * dstIndirectBuffer,vk::BufferHelper * dstIndexBuffer,const ConvertLineLoopArrayIndirectParameters & params)2205*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::convertLineLoopArrayIndirectBuffer(
2206*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
2207*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *srcIndirectBuffer,
2208*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dstIndirectBuffer,
2209*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dstIndexBuffer,
2210*8975f5c5SAndroid Build Coastguard Worker const ConvertLineLoopArrayIndirectParameters ¶ms)
2211*8975f5c5SAndroid Build Coastguard Worker {
2212*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureConvertIndirectLineLoopResourcesInitialized(contextVk));
2213*8975f5c5SAndroid Build Coastguard Worker
2214*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access;
2215*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderRead(srcIndirectBuffer);
2216*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(dstIndirectBuffer);
2217*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(dstIndexBuffer);
2218*8975f5c5SAndroid Build Coastguard Worker
2219*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
2220*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
2221*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper(access, &commandBufferHelper));
2222*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &commandBufferHelper->getCommandBuffer();
2223*8975f5c5SAndroid Build Coastguard Worker
2224*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
2225*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, commandBufferHelper,
2226*8975f5c5SAndroid Build Coastguard Worker Function::ConvertIndirectLineLoopBuffer, &descriptorSet));
2227*8975f5c5SAndroid Build Coastguard Worker
2228*8975f5c5SAndroid Build Coastguard Worker std::array<VkDescriptorBufferInfo, 3> buffers = {{
2229*8975f5c5SAndroid Build Coastguard Worker {srcIndirectBuffer->getBuffer().getHandle(), srcIndirectBuffer->getOffset(),
2230*8975f5c5SAndroid Build Coastguard Worker srcIndirectBuffer->getSize()},
2231*8975f5c5SAndroid Build Coastguard Worker {dstIndirectBuffer->getBuffer().getHandle(), dstIndirectBuffer->getOffset(),
2232*8975f5c5SAndroid Build Coastguard Worker dstIndirectBuffer->getSize()},
2233*8975f5c5SAndroid Build Coastguard Worker {dstIndexBuffer->getBuffer().getHandle(), dstIndexBuffer->getOffset(),
2234*8975f5c5SAndroid Build Coastguard Worker dstIndexBuffer->getSize()},
2235*8975f5c5SAndroid Build Coastguard Worker }};
2236*8975f5c5SAndroid Build Coastguard Worker
2237*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfo = {};
2238*8975f5c5SAndroid Build Coastguard Worker writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2239*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstSet = descriptorSet;
2240*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstBinding = kConvertIndexDestinationBinding;
2241*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorCount = 3;
2242*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2243*8975f5c5SAndroid Build Coastguard Worker writeInfo.pBufferInfo = buffers.data();
2244*8975f5c5SAndroid Build Coastguard Worker
2245*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 1, &writeInfo, 0, nullptr);
2246*8975f5c5SAndroid Build Coastguard Worker
2247*8975f5c5SAndroid Build Coastguard Worker ConvertIndirectLineLoopShaderParams shaderParams = {params.indirectBufferOffset >> 2,
2248*8975f5c5SAndroid Build Coastguard Worker params.dstIndirectBufferOffset >> 2,
2249*8975f5c5SAndroid Build Coastguard Worker params.dstIndexBufferOffset >> 2};
2250*8975f5c5SAndroid Build Coastguard Worker
2251*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = 0;
2252*8975f5c5SAndroid Build Coastguard Worker
2253*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr shader;
2254*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
2255*8975f5c5SAndroid Build Coastguard Worker contextVk->getShaderLibrary().getConvertIndirectLineLoop_comp(contextVk, flags, &shader));
2256*8975f5c5SAndroid Build Coastguard Worker
2257*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupComputeProgram(contextVk, Function::ConvertIndirectLineLoopBuffer, shader,
2258*8975f5c5SAndroid Build Coastguard Worker &mConvertIndirectLineLoop[flags], descriptorSet, &shaderParams,
2259*8975f5c5SAndroid Build Coastguard Worker sizeof(ConvertIndirectLineLoopShaderParams),
2260*8975f5c5SAndroid Build Coastguard Worker commandBufferHelper));
2261*8975f5c5SAndroid Build Coastguard Worker
2262*8975f5c5SAndroid Build Coastguard Worker commandBuffer->dispatch(1, 1, 1);
2263*8975f5c5SAndroid Build Coastguard Worker
2264*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2265*8975f5c5SAndroid Build Coastguard Worker }
2266*8975f5c5SAndroid Build Coastguard Worker
2267*8975f5c5SAndroid Build Coastguard Worker // Used to clear a layer of a renderable texture in part or whole (EXT_clear_texture).
clearTexture(ContextVk * contextVk,vk::ImageHelper * dst,ClearTextureParameters & params)2268*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::clearTexture(ContextVk *contextVk,
2269*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *dst,
2270*8975f5c5SAndroid Build Coastguard Worker ClearTextureParameters ¶ms)
2271*8975f5c5SAndroid Build Coastguard Worker {
2272*8975f5c5SAndroid Build Coastguard Worker const angle::Format &dstActualFormat = dst->getActualFormat();
2273*8975f5c5SAndroid Build Coastguard Worker bool isDepthOrStencil = dstActualFormat.hasDepthOrStencilBits();
2274*8975f5c5SAndroid Build Coastguard Worker bool isFormatDS = dstActualFormat.hasDepthAndStencilBits();
2275*8975f5c5SAndroid Build Coastguard Worker
2276*8975f5c5SAndroid Build Coastguard Worker vk::DeviceScoped<vk::ImageView> destView(contextVk->getDevice());
2277*8975f5c5SAndroid Build Coastguard Worker const gl::TextureType destViewType = vk::Get2DTextureType(1, dst->getSamples());
2278*8975f5c5SAndroid Build Coastguard Worker
2279*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(dst->initLayerImageView(contextVk, destViewType, params.aspectFlags,
2280*8975f5c5SAndroid Build Coastguard Worker gl::SwizzleState(), &destView.get(), params.level, 1,
2281*8975f5c5SAndroid Build Coastguard Worker params.layer, 1));
2282*8975f5c5SAndroid Build Coastguard Worker
2283*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle renderArea = {};
2284*8975f5c5SAndroid Build Coastguard Worker renderArea.x = params.clearArea.x;
2285*8975f5c5SAndroid Build Coastguard Worker renderArea.y = params.clearArea.y;
2286*8975f5c5SAndroid Build Coastguard Worker renderArea.width = params.clearArea.width;
2287*8975f5c5SAndroid Build Coastguard Worker renderArea.height = params.clearArea.height;
2288*8975f5c5SAndroid Build Coastguard Worker
2289*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassDesc renderPassDesc;
2290*8975f5c5SAndroid Build Coastguard Worker renderPassDesc.setSamples(dst->getSamples());
2291*8975f5c5SAndroid Build Coastguard Worker
2292*8975f5c5SAndroid Build Coastguard Worker if (!isDepthOrStencil)
2293*8975f5c5SAndroid Build Coastguard Worker {
2294*8975f5c5SAndroid Build Coastguard Worker renderPassDesc.packColorAttachment(0, dstActualFormat.id);
2295*8975f5c5SAndroid Build Coastguard Worker }
2296*8975f5c5SAndroid Build Coastguard Worker else
2297*8975f5c5SAndroid Build Coastguard Worker {
2298*8975f5c5SAndroid Build Coastguard Worker renderPassDesc.packDepthStencilAttachment(dstActualFormat.id);
2299*8975f5c5SAndroid Build Coastguard Worker }
2300*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer;
2301*8975f5c5SAndroid Build Coastguard Worker vk::ImageLayout imageLayout =
2302*8975f5c5SAndroid Build Coastguard Worker isDepthOrStencil ? vk::ImageLayout::DepthWriteStencilWrite : vk::ImageLayout::ColorWrite;
2303*8975f5c5SAndroid Build Coastguard Worker
2304*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(startRenderPass(contextVk, dst, &destView.get(), renderPassDesc, renderArea,
2305*8975f5c5SAndroid Build Coastguard Worker params.aspectFlags, ¶ms.clearValue,
2306*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassSource::InternalUtils, &commandBuffer));
2307*8975f5c5SAndroid Build Coastguard Worker
2308*8975f5c5SAndroid Build Coastguard Worker // If the format contains both depth and stencil, the barrier aspect mask for the image should
2309*8975f5c5SAndroid Build Coastguard Worker // include both bits.
2310*8975f5c5SAndroid Build Coastguard Worker contextVk->onImageRenderPassWrite(
2311*8975f5c5SAndroid Build Coastguard Worker dst->toGLLevel(params.level), params.layer, 1,
2312*8975f5c5SAndroid Build Coastguard Worker isFormatDS ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : params.aspectFlags,
2313*8975f5c5SAndroid Build Coastguard Worker imageLayout, dst);
2314*8975f5c5SAndroid Build Coastguard Worker
2315*8975f5c5SAndroid Build Coastguard Worker vk::ImageView destViewObject = destView.release();
2316*8975f5c5SAndroid Build Coastguard Worker contextVk->addGarbage(&destViewObject);
2317*8975f5c5SAndroid Build Coastguard Worker
2318*8975f5c5SAndroid Build Coastguard Worker // Close the render pass for this temporary framebuffer. If the render pass is not immediately
2319*8975f5c5SAndroid Build Coastguard Worker // closed and the render area grows due to scissor change, the clear area unexpectedly changes.
2320*8975f5c5SAndroid Build Coastguard Worker // This can be avoided if the scissor code takes LOAD_OP_CLEAR into account before deciding to
2321*8975f5c5SAndroid Build Coastguard Worker // grow the render pass's render area.
2322*8975f5c5SAndroid Build Coastguard Worker return contextVk->flushCommandsAndEndRenderPass(
2323*8975f5c5SAndroid Build Coastguard Worker RenderPassClosureReason::TemporaryForClearTexture);
2324*8975f5c5SAndroid Build Coastguard Worker }
2325*8975f5c5SAndroid Build Coastguard Worker
convertVertexBuffer(ContextVk * contextVk,vk::BufferHelper * dst,vk::BufferHelper * src,const ConvertVertexParameters & params,const OffsetAndVertexCounts & additionalOffsetVertexCounts)2326*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::convertVertexBuffer(
2327*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
2328*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dst,
2329*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *src,
2330*8975f5c5SAndroid Build Coastguard Worker const ConvertVertexParameters ¶ms,
2331*8975f5c5SAndroid Build Coastguard Worker const OffsetAndVertexCounts &additionalOffsetVertexCounts)
2332*8975f5c5SAndroid Build Coastguard Worker {
2333*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access;
2334*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderRead(src);
2335*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(dst);
2336*8975f5c5SAndroid Build Coastguard Worker
2337*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
2338*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper(access, &commandBufferHelper));
2339*8975f5c5SAndroid Build Coastguard Worker
2340*8975f5c5SAndroid Build Coastguard Worker ConvertVertexShaderParams shaderParams;
2341*8975f5c5SAndroid Build Coastguard Worker shaderParams.Ns = params.srcFormat->channelCount;
2342*8975f5c5SAndroid Build Coastguard Worker shaderParams.Bs = params.srcFormat->pixelBytes / params.srcFormat->channelCount;
2343*8975f5c5SAndroid Build Coastguard Worker shaderParams.Ss = static_cast<uint32_t>(params.srcStride);
2344*8975f5c5SAndroid Build Coastguard Worker shaderParams.Nd = params.dstFormat->channelCount;
2345*8975f5c5SAndroid Build Coastguard Worker shaderParams.Bd = params.dstFormat->pixelBytes / params.dstFormat->channelCount;
2346*8975f5c5SAndroid Build Coastguard Worker shaderParams.Sd = shaderParams.Nd * shaderParams.Bd;
2347*8975f5c5SAndroid Build Coastguard Worker // The component size is expected to either be 1, 2 or 4 bytes.
2348*8975f5c5SAndroid Build Coastguard Worker ASSERT(4 % shaderParams.Bs == 0);
2349*8975f5c5SAndroid Build Coastguard Worker ASSERT(4 % shaderParams.Bd == 0);
2350*8975f5c5SAndroid Build Coastguard Worker shaderParams.Es = 4 / shaderParams.Bs;
2351*8975f5c5SAndroid Build Coastguard Worker shaderParams.Ed = 4 / shaderParams.Bd;
2352*8975f5c5SAndroid Build Coastguard Worker // Total number of output components is simply the number of vertices by number of components in
2353*8975f5c5SAndroid Build Coastguard Worker // each.
2354*8975f5c5SAndroid Build Coastguard Worker shaderParams.componentCount = static_cast<uint32_t>(params.vertexCount * shaderParams.Nd);
2355*8975f5c5SAndroid Build Coastguard Worker // Total number of 4-byte outputs is the number of components divided by how many components can
2356*8975f5c5SAndroid Build Coastguard Worker // fit in a 4-byte value. Note that this value is also the invocation size of the shader.
2357*8975f5c5SAndroid Build Coastguard Worker shaderParams.outputCount = UnsignedCeilDivide(shaderParams.componentCount, shaderParams.Ed);
2358*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset = static_cast<uint32_t>(params.srcOffset);
2359*8975f5c5SAndroid Build Coastguard Worker shaderParams.dstOffset = static_cast<uint32_t>(params.dstOffset);
2360*8975f5c5SAndroid Build Coastguard Worker
2361*8975f5c5SAndroid Build Coastguard Worker bool isSrcA2BGR10 =
2362*8975f5c5SAndroid Build Coastguard Worker params.srcFormat->vertexAttribType == gl::VertexAttribType::UnsignedInt2101010 ||
2363*8975f5c5SAndroid Build Coastguard Worker params.srcFormat->vertexAttribType == gl::VertexAttribType::Int2101010;
2364*8975f5c5SAndroid Build Coastguard Worker bool isSrcRGB10A2 =
2365*8975f5c5SAndroid Build Coastguard Worker params.srcFormat->vertexAttribType == gl::VertexAttribType::UnsignedInt1010102 ||
2366*8975f5c5SAndroid Build Coastguard Worker params.srcFormat->vertexAttribType == gl::VertexAttribType::Int1010102;
2367*8975f5c5SAndroid Build Coastguard Worker
2368*8975f5c5SAndroid Build Coastguard Worker shaderParams.isSrcHDR = isSrcA2BGR10 || isSrcRGB10A2;
2369*8975f5c5SAndroid Build Coastguard Worker shaderParams.isSrcA2BGR10 = isSrcA2BGR10;
2370*8975f5c5SAndroid Build Coastguard Worker
2371*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = GetConvertVertexFlags(params);
2372*8975f5c5SAndroid Build Coastguard Worker
2373*8975f5c5SAndroid Build Coastguard Worker // See GLES3.0 section 2.9.1 Transferring Array Elements
2374*8975f5c5SAndroid Build Coastguard Worker const uint32_t srcValueBits = shaderParams.isSrcHDR ? 2 : shaderParams.Bs * 8;
2375*8975f5c5SAndroid Build Coastguard Worker const uint32_t srcValueMask =
2376*8975f5c5SAndroid Build Coastguard Worker srcValueBits == 32 ? 0xFFFFFFFFu : angle::BitMask<uint32_t>(srcValueBits);
2377*8975f5c5SAndroid Build Coastguard Worker switch (flags)
2378*8975f5c5SAndroid Build Coastguard Worker {
2379*8975f5c5SAndroid Build Coastguard Worker case ConvertVertex_comp::kSintToSint:
2380*8975f5c5SAndroid Build Coastguard Worker case ConvertVertex_comp::kSintToFloat:
2381*8975f5c5SAndroid Build Coastguard Worker case ConvertVertex_comp::kUintToFloat:
2382*8975f5c5SAndroid Build Coastguard Worker // For integers, alpha should take a value of 1.
2383*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = 1;
2384*8975f5c5SAndroid Build Coastguard Worker break;
2385*8975f5c5SAndroid Build Coastguard Worker
2386*8975f5c5SAndroid Build Coastguard Worker case ConvertVertex_comp::kUintToUint:
2387*8975f5c5SAndroid Build Coastguard Worker // For integers, alpha should take a value of 1. However, uint->uint is also used to
2388*8975f5c5SAndroid Build Coastguard Worker // add channels to RGB snorm, unorm and half formats.
2389*8975f5c5SAndroid Build Coastguard Worker if (params.dstFormat->isSnorm())
2390*8975f5c5SAndroid Build Coastguard Worker {
2391*8975f5c5SAndroid Build Coastguard Worker // See case ConvertVertex_comp::kSnormToFloat below.
2392*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = srcValueMask >> 1;
2393*8975f5c5SAndroid Build Coastguard Worker }
2394*8975f5c5SAndroid Build Coastguard Worker else if (params.dstFormat->isUnorm())
2395*8975f5c5SAndroid Build Coastguard Worker {
2396*8975f5c5SAndroid Build Coastguard Worker // See case ConvertVertex_comp::kUnormToFloat below.
2397*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = srcValueMask;
2398*8975f5c5SAndroid Build Coastguard Worker }
2399*8975f5c5SAndroid Build Coastguard Worker else if (params.dstFormat->isVertexTypeHalfFloat())
2400*8975f5c5SAndroid Build Coastguard Worker {
2401*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = gl::Float16One;
2402*8975f5c5SAndroid Build Coastguard Worker }
2403*8975f5c5SAndroid Build Coastguard Worker else
2404*8975f5c5SAndroid Build Coastguard Worker {
2405*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = 1;
2406*8975f5c5SAndroid Build Coastguard Worker }
2407*8975f5c5SAndroid Build Coastguard Worker break;
2408*8975f5c5SAndroid Build Coastguard Worker
2409*8975f5c5SAndroid Build Coastguard Worker case ConvertVertex_comp::kSnormToFloat:
2410*8975f5c5SAndroid Build Coastguard Worker // The largest signed number with as many bits as the alpha channel of the source is
2411*8975f5c5SAndroid Build Coastguard Worker // 0b011...1 which is srcValueMask >> 1
2412*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = srcValueMask >> 1;
2413*8975f5c5SAndroid Build Coastguard Worker break;
2414*8975f5c5SAndroid Build Coastguard Worker
2415*8975f5c5SAndroid Build Coastguard Worker case ConvertVertex_comp::kUnormToFloat:
2416*8975f5c5SAndroid Build Coastguard Worker // The largest unsigned number with as many bits as the alpha channel of the source is
2417*8975f5c5SAndroid Build Coastguard Worker // 0b11...1 which is srcValueMask
2418*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = srcValueMask;
2419*8975f5c5SAndroid Build Coastguard Worker break;
2420*8975f5c5SAndroid Build Coastguard Worker
2421*8975f5c5SAndroid Build Coastguard Worker case ConvertVertex_comp::kFixedToFloat:
2422*8975f5c5SAndroid Build Coastguard Worker // 1.0 in fixed point is 0x10000
2423*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = 0x10000;
2424*8975f5c5SAndroid Build Coastguard Worker break;
2425*8975f5c5SAndroid Build Coastguard Worker
2426*8975f5c5SAndroid Build Coastguard Worker case ConvertVertex_comp::kFloatToFloat:
2427*8975f5c5SAndroid Build Coastguard Worker ASSERT(ValidateFloatOneAsUint());
2428*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = gl::Float32One;
2429*8975f5c5SAndroid Build Coastguard Worker break;
2430*8975f5c5SAndroid Build Coastguard Worker
2431*8975f5c5SAndroid Build Coastguard Worker default:
2432*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
2433*8975f5c5SAndroid Build Coastguard Worker }
2434*8975f5c5SAndroid Build Coastguard Worker
2435*8975f5c5SAndroid Build Coastguard Worker return convertVertexBufferImpl(contextVk, dst, src, flags, commandBufferHelper, shaderParams,
2436*8975f5c5SAndroid Build Coastguard Worker additionalOffsetVertexCounts);
2437*8975f5c5SAndroid Build Coastguard Worker }
2438*8975f5c5SAndroid Build Coastguard Worker
convertVertexBufferImpl(ContextVk * contextVk,vk::BufferHelper * dst,vk::BufferHelper * src,uint32_t flags,vk::OutsideRenderPassCommandBufferHelper * commandBufferHelper,const ConvertVertexShaderParams & shaderParams,const OffsetAndVertexCounts & additionalOffsetVertexCounts)2439*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::convertVertexBufferImpl(
2440*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
2441*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dst,
2442*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *src,
2443*8975f5c5SAndroid Build Coastguard Worker uint32_t flags,
2444*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper,
2445*8975f5c5SAndroid Build Coastguard Worker const ConvertVertexShaderParams &shaderParams,
2446*8975f5c5SAndroid Build Coastguard Worker const OffsetAndVertexCounts &additionalOffsetVertexCounts)
2447*8975f5c5SAndroid Build Coastguard Worker {
2448*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureConvertVertexResourcesInitialized(contextVk));
2449*8975f5c5SAndroid Build Coastguard Worker
2450*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
2451*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &commandBufferHelper->getCommandBuffer();
2452*8975f5c5SAndroid Build Coastguard Worker
2453*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
2454*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, commandBufferHelper, Function::ConvertVertexBuffer,
2455*8975f5c5SAndroid Build Coastguard Worker &descriptorSet));
2456*8975f5c5SAndroid Build Coastguard Worker
2457*8975f5c5SAndroid Build Coastguard Worker // ConvertVertexBuffer writes whole 4 bytes to dstOffset. Caller must ensure dstOffset is
2458*8975f5c5SAndroid Build Coastguard Worker // aligned on 4 bytes boundary.
2459*8975f5c5SAndroid Build Coastguard Worker ASSERT(dst->getOffset() % 4 == 0);
2460*8975f5c5SAndroid Build Coastguard Worker
2461*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfo = {};
2462*8975f5c5SAndroid Build Coastguard Worker VkDescriptorBufferInfo buffers[2] = {
2463*8975f5c5SAndroid Build Coastguard Worker {dst->getBuffer().getHandle(), dst->getOffset(), dst->getSize()},
2464*8975f5c5SAndroid Build Coastguard Worker {src->getBuffer().getHandle(), src->getOffset(), src->getSize()},
2465*8975f5c5SAndroid Build Coastguard Worker };
2466*8975f5c5SAndroid Build Coastguard Worker static_assert(kConvertVertexDestinationBinding + 1 == kConvertVertexSourceBinding,
2467*8975f5c5SAndroid Build Coastguard Worker "Update write info");
2468*8975f5c5SAndroid Build Coastguard Worker
2469*8975f5c5SAndroid Build Coastguard Worker writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2470*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstSet = descriptorSet;
2471*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstBinding = kConvertVertexDestinationBinding;
2472*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorCount = 2;
2473*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2474*8975f5c5SAndroid Build Coastguard Worker writeInfo.pBufferInfo = buffers;
2475*8975f5c5SAndroid Build Coastguard Worker
2476*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 1, &writeInfo, 0, nullptr);
2477*8975f5c5SAndroid Build Coastguard Worker
2478*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr shader;
2479*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getShaderLibrary().getConvertVertex_comp(contextVk, flags, &shader));
2480*8975f5c5SAndroid Build Coastguard Worker
2481*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupComputeProgram(contextVk, Function::ConvertVertexBuffer, shader,
2482*8975f5c5SAndroid Build Coastguard Worker &mConvertVertex[flags], descriptorSet, &shaderParams,
2483*8975f5c5SAndroid Build Coastguard Worker sizeof(shaderParams), commandBufferHelper));
2484*8975f5c5SAndroid Build Coastguard Worker
2485*8975f5c5SAndroid Build Coastguard Worker commandBuffer->dispatch(UnsignedCeilDivide(shaderParams.outputCount, 64), 1, 1);
2486*8975f5c5SAndroid Build Coastguard Worker
2487*8975f5c5SAndroid Build Coastguard Worker if (!additionalOffsetVertexCounts.empty())
2488*8975f5c5SAndroid Build Coastguard Worker {
2489*8975f5c5SAndroid Build Coastguard Worker ConvertVertexShaderParams constants = shaderParams;
2490*8975f5c5SAndroid Build Coastguard Worker
2491*8975f5c5SAndroid Build Coastguard Worker for (const OffsetAndVertexCount &offsetAndVertexCount : additionalOffsetVertexCounts)
2492*8975f5c5SAndroid Build Coastguard Worker {
2493*8975f5c5SAndroid Build Coastguard Worker // Total number of output components is simply the number of vertices by number of
2494*8975f5c5SAndroid Build Coastguard Worker // components in each.
2495*8975f5c5SAndroid Build Coastguard Worker constants.componentCount =
2496*8975f5c5SAndroid Build Coastguard Worker static_cast<uint32_t>(offsetAndVertexCount.vertexCount * shaderParams.Nd);
2497*8975f5c5SAndroid Build Coastguard Worker // Total number of 4-byte outputs is the number of components divided by how many
2498*8975f5c5SAndroid Build Coastguard Worker // components can fit in a 4-byte value. Note that this value is also the invocation
2499*8975f5c5SAndroid Build Coastguard Worker // size of the shader.
2500*8975f5c5SAndroid Build Coastguard Worker constants.outputCount = UnsignedCeilDivide(constants.componentCount, shaderParams.Ed);
2501*8975f5c5SAndroid Build Coastguard Worker constants.srcOffset = static_cast<uint32_t>(offsetAndVertexCount.srcOffset);
2502*8975f5c5SAndroid Build Coastguard Worker constants.dstOffset = static_cast<uint32_t>(offsetAndVertexCount.dstOffset);
2503*8975f5c5SAndroid Build Coastguard Worker
2504*8975f5c5SAndroid Build Coastguard Worker commandBuffer->pushConstants(*mPipelineLayouts[Function::ConvertVertexBuffer],
2505*8975f5c5SAndroid Build Coastguard Worker VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(constants),
2506*8975f5c5SAndroid Build Coastguard Worker &constants);
2507*8975f5c5SAndroid Build Coastguard Worker // Since multiple compute dispatch all convert from the same srcBuffer and write to the
2508*8975f5c5SAndroid Build Coastguard Worker // same dstBuffer, even if the ranges overlap, they should end up with writing the same
2509*8975f5c5SAndroid Build Coastguard Worker // values, thus no barrier is needed here.
2510*8975f5c5SAndroid Build Coastguard Worker commandBuffer->dispatch(UnsignedCeilDivide(constants.outputCount, 64), 1, 1);
2511*8975f5c5SAndroid Build Coastguard Worker }
2512*8975f5c5SAndroid Build Coastguard Worker }
2513*8975f5c5SAndroid Build Coastguard Worker
2514*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2515*8975f5c5SAndroid Build Coastguard Worker }
2516*8975f5c5SAndroid Build Coastguard Worker
startRenderPass(ContextVk * contextVk,vk::ImageHelper * image,const vk::ImageView * imageView,const vk::RenderPassDesc & renderPassDesc,const gl::Rectangle & renderArea,const VkImageAspectFlags aspectFlags,const VkClearValue * clearValue,vk::RenderPassSource renderPassSource,vk::RenderPassCommandBuffer ** commandBufferOut)2517*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::startRenderPass(ContextVk *contextVk,
2518*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *image,
2519*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *imageView,
2520*8975f5c5SAndroid Build Coastguard Worker const vk::RenderPassDesc &renderPassDesc,
2521*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &renderArea,
2522*8975f5c5SAndroid Build Coastguard Worker const VkImageAspectFlags aspectFlags,
2523*8975f5c5SAndroid Build Coastguard Worker const VkClearValue *clearValue,
2524*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassSource renderPassSource,
2525*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer **commandBufferOut)
2526*8975f5c5SAndroid Build Coastguard Worker {
2527*8975f5c5SAndroid Build Coastguard Worker ASSERT(aspectFlags == VK_IMAGE_ASPECT_COLOR_BIT ||
2528*8975f5c5SAndroid Build Coastguard Worker (aspectFlags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0);
2529*8975f5c5SAndroid Build Coastguard Worker vk::ImageLayout imageLayout = aspectFlags == VK_IMAGE_ASPECT_COLOR_BIT
2530*8975f5c5SAndroid Build Coastguard Worker ? vk::ImageLayout::ColorWrite
2531*8975f5c5SAndroid Build Coastguard Worker : vk::ImageLayout::DepthWriteStencilWrite;
2532*8975f5c5SAndroid Build Coastguard Worker vk::Framebuffer framebuffer;
2533*8975f5c5SAndroid Build Coastguard Worker vk::Framebuffer framebufferHandle;
2534*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassFramebuffer renderPassFramebuffer;
2535*8975f5c5SAndroid Build Coastguard Worker
2536*8975f5c5SAndroid Build Coastguard Worker const uint32_t framebufferWidth = renderArea.x + renderArea.width;
2537*8975f5c5SAndroid Build Coastguard Worker const uint32_t framebufferHeight = renderArea.y + renderArea.height;
2538*8975f5c5SAndroid Build Coastguard Worker const uint32_t framebufferLayers = 1;
2539*8975f5c5SAndroid Build Coastguard Worker vk::ImagelessFramebuffer imageless = vk::ImagelessFramebuffer::Yes;
2540*8975f5c5SAndroid Build Coastguard Worker
2541*8975f5c5SAndroid Build Coastguard Worker if (!contextVk->getFeatures().preferDynamicRendering.enabled)
2542*8975f5c5SAndroid Build Coastguard Worker {
2543*8975f5c5SAndroid Build Coastguard Worker imageless = vk::ImagelessFramebuffer::No;
2544*8975f5c5SAndroid Build Coastguard Worker
2545*8975f5c5SAndroid Build Coastguard Worker const vk::RenderPass *compatibleRenderPass = nullptr;
2546*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getCompatibleRenderPass(renderPassDesc, &compatibleRenderPass));
2547*8975f5c5SAndroid Build Coastguard Worker
2548*8975f5c5SAndroid Build Coastguard Worker VkFramebufferCreateInfo framebufferInfo = {};
2549*8975f5c5SAndroid Build Coastguard Worker
2550*8975f5c5SAndroid Build Coastguard Worker // Minimize the framebuffer coverage to only cover up to the render area.
2551*8975f5c5SAndroid Build Coastguard Worker framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2552*8975f5c5SAndroid Build Coastguard Worker framebufferInfo.flags = 0;
2553*8975f5c5SAndroid Build Coastguard Worker framebufferInfo.renderPass = compatibleRenderPass->getHandle();
2554*8975f5c5SAndroid Build Coastguard Worker framebufferInfo.attachmentCount = 1;
2555*8975f5c5SAndroid Build Coastguard Worker framebufferInfo.pAttachments = imageView->ptr();
2556*8975f5c5SAndroid Build Coastguard Worker framebufferInfo.width = framebufferWidth;
2557*8975f5c5SAndroid Build Coastguard Worker framebufferInfo.height = framebufferHeight;
2558*8975f5c5SAndroid Build Coastguard Worker framebufferInfo.layers = framebufferLayers;
2559*8975f5c5SAndroid Build Coastguard Worker
2560*8975f5c5SAndroid Build Coastguard Worker ANGLE_VK_TRY(contextVk, framebuffer.init(contextVk->getDevice(), framebufferInfo));
2561*8975f5c5SAndroid Build Coastguard Worker
2562*8975f5c5SAndroid Build Coastguard Worker framebufferHandle.setHandle(framebuffer.getHandle());
2563*8975f5c5SAndroid Build Coastguard Worker }
2564*8975f5c5SAndroid Build Coastguard Worker
2565*8975f5c5SAndroid Build Coastguard Worker renderPassFramebuffer.setFramebuffer(
2566*8975f5c5SAndroid Build Coastguard Worker contextVk, std::move(framebufferHandle), {imageView->getHandle()}, framebufferWidth,
2567*8975f5c5SAndroid Build Coastguard Worker framebufferHeight, framebufferLayers, imageless, renderPassSource);
2568*8975f5c5SAndroid Build Coastguard Worker
2569*8975f5c5SAndroid Build Coastguard Worker // If a clear value has been provided, the load op is set to clear.
2570*8975f5c5SAndroid Build Coastguard Worker vk::AttachmentOpsArray renderPassAttachmentOps;
2571*8975f5c5SAndroid Build Coastguard Worker vk::PackedClearValuesArray clearValues;
2572*8975f5c5SAndroid Build Coastguard Worker VkClearValue attachmentClearValue = {};
2573*8975f5c5SAndroid Build Coastguard Worker
2574*8975f5c5SAndroid Build Coastguard Worker if (clearValue == nullptr)
2575*8975f5c5SAndroid Build Coastguard Worker {
2576*8975f5c5SAndroid Build Coastguard Worker renderPassAttachmentOps.initWithLoadStore(vk::kAttachmentIndexZero, imageLayout,
2577*8975f5c5SAndroid Build Coastguard Worker imageLayout);
2578*8975f5c5SAndroid Build Coastguard Worker }
2579*8975f5c5SAndroid Build Coastguard Worker else
2580*8975f5c5SAndroid Build Coastguard Worker {
2581*8975f5c5SAndroid Build Coastguard Worker attachmentClearValue = *clearValue;
2582*8975f5c5SAndroid Build Coastguard Worker renderPassAttachmentOps.setLayouts(vk::kAttachmentIndexZero, imageLayout, imageLayout);
2583*8975f5c5SAndroid Build Coastguard Worker renderPassAttachmentOps.setClearOp(vk::kAttachmentIndexZero);
2584*8975f5c5SAndroid Build Coastguard Worker renderPassAttachmentOps.setClearStencilOp(vk::kAttachmentIndexZero);
2585*8975f5c5SAndroid Build Coastguard Worker }
2586*8975f5c5SAndroid Build Coastguard Worker
2587*8975f5c5SAndroid Build Coastguard Worker if (aspectFlags == VK_IMAGE_ASPECT_COLOR_BIT)
2588*8975f5c5SAndroid Build Coastguard Worker {
2589*8975f5c5SAndroid Build Coastguard Worker clearValues.storeColor(vk::kAttachmentIndexZero, attachmentClearValue);
2590*8975f5c5SAndroid Build Coastguard Worker }
2591*8975f5c5SAndroid Build Coastguard Worker else
2592*8975f5c5SAndroid Build Coastguard Worker {
2593*8975f5c5SAndroid Build Coastguard Worker clearValues.storeDepthStencil(vk::kAttachmentIndexZero, attachmentClearValue);
2594*8975f5c5SAndroid Build Coastguard Worker }
2595*8975f5c5SAndroid Build Coastguard Worker
2596*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->beginNewRenderPass(
2597*8975f5c5SAndroid Build Coastguard Worker std::move(renderPassFramebuffer), renderArea, renderPassDesc, renderPassAttachmentOps,
2598*8975f5c5SAndroid Build Coastguard Worker vk::PackedAttachmentCount(1), vk::kAttachmentIndexInvalid, clearValues, commandBufferOut));
2599*8975f5c5SAndroid Build Coastguard Worker
2600*8975f5c5SAndroid Build Coastguard Worker contextVk->addGarbage(&framebuffer);
2601*8975f5c5SAndroid Build Coastguard Worker
2602*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2603*8975f5c5SAndroid Build Coastguard Worker }
2604*8975f5c5SAndroid Build Coastguard Worker
clearFramebuffer(ContextVk * contextVk,FramebufferVk * framebuffer,const ClearFramebufferParameters & params)2605*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
2606*8975f5c5SAndroid Build Coastguard Worker FramebufferVk *framebuffer,
2607*8975f5c5SAndroid Build Coastguard Worker const ClearFramebufferParameters ¶ms)
2608*8975f5c5SAndroid Build Coastguard Worker {
2609*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
2610*8975f5c5SAndroid Build Coastguard Worker
2611*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureImageClearResourcesInitialized(contextVk));
2612*8975f5c5SAndroid Build Coastguard Worker
2613*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &scissoredRenderArea = params.clearArea;
2614*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer;
2615*8975f5c5SAndroid Build Coastguard Worker
2616*8975f5c5SAndroid Build Coastguard Worker // Start a new render pass if not already started
2617*8975f5c5SAndroid Build Coastguard Worker if (contextVk->hasActiveRenderPass() &&
2618*8975f5c5SAndroid Build Coastguard Worker contextVk->hasStartedRenderPassWithQueueSerial(framebuffer->getLastRenderPassQueueSerial()))
2619*8975f5c5SAndroid Build Coastguard Worker {
2620*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBufferHelper *renderPassCommands =
2621*8975f5c5SAndroid Build Coastguard Worker &contextVk->getStartedRenderPassCommands();
2622*8975f5c5SAndroid Build Coastguard Worker renderPassCommands->growRenderArea(contextVk, scissoredRenderArea);
2623*8975f5c5SAndroid Build Coastguard Worker
2624*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &renderPassCommands->getCommandBuffer();
2625*8975f5c5SAndroid Build Coastguard Worker }
2626*8975f5c5SAndroid Build Coastguard Worker else
2627*8975f5c5SAndroid Build Coastguard Worker {
2628*8975f5c5SAndroid Build Coastguard Worker // Deferred clears should be handled already.
2629*8975f5c5SAndroid Build Coastguard Worker ASSERT(!framebuffer->hasDeferredClears());
2630*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->startRenderPass(scissoredRenderArea, &commandBuffer, nullptr));
2631*8975f5c5SAndroid Build Coastguard Worker }
2632*8975f5c5SAndroid Build Coastguard Worker
2633*8975f5c5SAndroid Build Coastguard Worker UpdateColorAccess(contextVk, framebuffer->getState().getColorAttachmentsMask(),
2634*8975f5c5SAndroid Build Coastguard Worker MakeColorBufferMask(params.colorAttachmentIndexGL));
2635*8975f5c5SAndroid Build Coastguard Worker UpdateDepthStencilAccess(contextVk, params.clearDepth, params.clearStencil);
2636*8975f5c5SAndroid Build Coastguard Worker
2637*8975f5c5SAndroid Build Coastguard Worker ImageClearShaderParams shaderParams;
2638*8975f5c5SAndroid Build Coastguard Worker shaderParams.clearValue = params.colorClearValue;
2639*8975f5c5SAndroid Build Coastguard Worker shaderParams.clearDepth = params.depthStencilClearValue.depth;
2640*8975f5c5SAndroid Build Coastguard Worker
2641*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineDesc pipelineDesc;
2642*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.initDefaults(contextVk, vk::GraphicsPipelineSubset::Complete,
2643*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineRobustness(),
2644*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineProtectedAccess());
2645*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setColorWriteMasks(0, gl::DrawBufferMask(), gl::DrawBufferMask());
2646*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setSingleColorWriteMask(params.colorAttachmentIndexGL, params.colorMaskFlags);
2647*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRasterizationSamples(framebuffer->getSamples());
2648*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRenderPassDesc(framebuffer->getRenderPassDesc());
2649*8975f5c5SAndroid Build Coastguard Worker // Clears can be done on a currently open render pass, so make sure the correct subpass index is
2650*8975f5c5SAndroid Build Coastguard Worker // used.
2651*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setSubpass(contextVk->getCurrentSubpassIndex());
2652*8975f5c5SAndroid Build Coastguard Worker
2653*8975f5c5SAndroid Build Coastguard Worker // Clear depth by enabling depth clamping and setting the viewport depth range to the clear
2654*8975f5c5SAndroid Build Coastguard Worker // value if possible. Otherwise use the shader to export depth.
2655*8975f5c5SAndroid Build Coastguard Worker const bool supportsDepthClamp = renderer->getPhysicalDeviceFeatures().depthClamp == VK_TRUE;
2656*8975f5c5SAndroid Build Coastguard Worker if (params.clearDepth)
2657*8975f5c5SAndroid Build Coastguard Worker {
2658*8975f5c5SAndroid Build Coastguard Worker SetDepthStateForWrite(renderer, &pipelineDesc);
2659*8975f5c5SAndroid Build Coastguard Worker if (supportsDepthClamp)
2660*8975f5c5SAndroid Build Coastguard Worker {
2661*8975f5c5SAndroid Build Coastguard Worker // Note: this path requires the depthClamp Vulkan feature.
2662*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setDepthClampEnabled(true);
2663*8975f5c5SAndroid Build Coastguard Worker }
2664*8975f5c5SAndroid Build Coastguard Worker }
2665*8975f5c5SAndroid Build Coastguard Worker
2666*8975f5c5SAndroid Build Coastguard Worker // Clear stencil by enabling stencil write with the right mask.
2667*8975f5c5SAndroid Build Coastguard Worker if (params.clearStencil)
2668*8975f5c5SAndroid Build Coastguard Worker {
2669*8975f5c5SAndroid Build Coastguard Worker SetStencilStateForWrite(renderer, &pipelineDesc);
2670*8975f5c5SAndroid Build Coastguard Worker }
2671*8975f5c5SAndroid Build Coastguard Worker
2672*8975f5c5SAndroid Build Coastguard Worker vk::ShaderLibrary &shaderLibrary = contextVk->getShaderLibrary();
2673*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr vertexShader;
2674*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr fragmentShader;
2675*8975f5c5SAndroid Build Coastguard Worker GraphicsShaderProgramAndPipelines *imageClearProgramAndPipelines = &mImageClearVSOnly;
2676*8975f5c5SAndroid Build Coastguard Worker
2677*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getFullScreenTri_vert(contextVk, 0, &vertexShader));
2678*8975f5c5SAndroid Build Coastguard Worker if (params.clearColor)
2679*8975f5c5SAndroid Build Coastguard Worker {
2680*8975f5c5SAndroid Build Coastguard Worker const uint32_t flags =
2681*8975f5c5SAndroid Build Coastguard Worker GetImageClearFlags(*params.colorFormat, params.colorAttachmentIndexGL,
2682*8975f5c5SAndroid Build Coastguard Worker params.clearDepth && !supportsDepthClamp);
2683*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getImageClear_frag(contextVk, flags, &fragmentShader));
2684*8975f5c5SAndroid Build Coastguard Worker imageClearProgramAndPipelines = &mImageClear[flags];
2685*8975f5c5SAndroid Build Coastguard Worker }
2686*8975f5c5SAndroid Build Coastguard Worker
2687*8975f5c5SAndroid Build Coastguard Worker // Make sure transform feedback is paused. Needs to be done before binding the pipeline as
2688*8975f5c5SAndroid Build Coastguard Worker // that's not allowed in Vulkan.
2689*8975f5c5SAndroid Build Coastguard Worker const bool isTransformFeedbackActiveUnpaused =
2690*8975f5c5SAndroid Build Coastguard Worker contextVk->getStartedRenderPassCommands().isTransformFeedbackActiveUnpaused();
2691*8975f5c5SAndroid Build Coastguard Worker contextVk->pauseTransformFeedbackIfActiveUnpaused();
2692*8975f5c5SAndroid Build Coastguard Worker
2693*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupGraphicsProgram(contextVk, Function::ImageClear, vertexShader, fragmentShader,
2694*8975f5c5SAndroid Build Coastguard Worker imageClearProgramAndPipelines, &pipelineDesc, VK_NULL_HANDLE,
2695*8975f5c5SAndroid Build Coastguard Worker &shaderParams, sizeof(shaderParams), commandBuffer));
2696*8975f5c5SAndroid Build Coastguard Worker
2697*8975f5c5SAndroid Build Coastguard Worker // Set dynamic state
2698*8975f5c5SAndroid Build Coastguard Worker VkViewport viewport;
2699*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle completeRenderArea = framebuffer->getRotatedCompleteRenderArea(contextVk);
2700*8975f5c5SAndroid Build Coastguard Worker bool invertViewport = contextVk->isViewportFlipEnabledForDrawFBO();
2701*8975f5c5SAndroid Build Coastguard Worker bool clipSpaceOriginUpperLeft =
2702*8975f5c5SAndroid Build Coastguard Worker contextVk->getState().getClipOrigin() == gl::ClipOrigin::UpperLeft;
2703*8975f5c5SAndroid Build Coastguard Worker // Set depth range to clear value. If clearing depth, the vertex shader depth output is clamped
2704*8975f5c5SAndroid Build Coastguard Worker // to this value, thus clearing the depth buffer to the desired clear value.
2705*8975f5c5SAndroid Build Coastguard Worker const float clearDepthValue = params.depthStencilClearValue.depth;
2706*8975f5c5SAndroid Build Coastguard Worker gl_vk::GetViewport(completeRenderArea, clearDepthValue, clearDepthValue, invertViewport,
2707*8975f5c5SAndroid Build Coastguard Worker clipSpaceOriginUpperLeft, completeRenderArea.height, &viewport);
2708*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setViewport(0, 1, &viewport);
2709*8975f5c5SAndroid Build Coastguard Worker
2710*8975f5c5SAndroid Build Coastguard Worker const VkRect2D scissor = gl_vk::GetRect(params.clearArea);
2711*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setScissor(0, 1, &scissor);
2712*8975f5c5SAndroid Build Coastguard Worker
2713*8975f5c5SAndroid Build Coastguard Worker if (params.clearDepth)
2714*8975f5c5SAndroid Build Coastguard Worker {
2715*8975f5c5SAndroid Build Coastguard Worker SetDepthDynamicStateForWrite(renderer, commandBuffer);
2716*8975f5c5SAndroid Build Coastguard Worker }
2717*8975f5c5SAndroid Build Coastguard Worker else
2718*8975f5c5SAndroid Build Coastguard Worker {
2719*8975f5c5SAndroid Build Coastguard Worker SetDepthDynamicStateForUnused(renderer, commandBuffer);
2720*8975f5c5SAndroid Build Coastguard Worker }
2721*8975f5c5SAndroid Build Coastguard Worker
2722*8975f5c5SAndroid Build Coastguard Worker if (params.clearStencil)
2723*8975f5c5SAndroid Build Coastguard Worker {
2724*8975f5c5SAndroid Build Coastguard Worker constexpr uint8_t kCompareMask = 0xFF;
2725*8975f5c5SAndroid Build Coastguard Worker const uint8_t clearStencilValue =
2726*8975f5c5SAndroid Build Coastguard Worker static_cast<uint8_t>(params.depthStencilClearValue.stencil);
2727*8975f5c5SAndroid Build Coastguard Worker
2728*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilCompareMask(kCompareMask, kCompareMask);
2729*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilWriteMask(params.stencilMask, params.stencilMask);
2730*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilReference(clearStencilValue, clearStencilValue);
2731*8975f5c5SAndroid Build Coastguard Worker
2732*8975f5c5SAndroid Build Coastguard Worker SetStencilDynamicStateForWrite(renderer, commandBuffer);
2733*8975f5c5SAndroid Build Coastguard Worker }
2734*8975f5c5SAndroid Build Coastguard Worker else
2735*8975f5c5SAndroid Build Coastguard Worker {
2736*8975f5c5SAndroid Build Coastguard Worker SetStencilDynamicStateForUnused(renderer, commandBuffer);
2737*8975f5c5SAndroid Build Coastguard Worker }
2738*8975f5c5SAndroid Build Coastguard Worker
2739*8975f5c5SAndroid Build Coastguard Worker ASSERT(contextVk->hasStartedRenderPassWithQueueSerial(
2740*8975f5c5SAndroid Build Coastguard Worker framebuffer->getLastRenderPassQueueSerial()));
2741*8975f5c5SAndroid Build Coastguard Worker // Make sure this draw call doesn't count towards occlusion query results.
2742*8975f5c5SAndroid Build Coastguard Worker contextVk->pauseRenderPassQueriesIfActive();
2743*8975f5c5SAndroid Build Coastguard Worker commandBuffer->draw(3, 0);
2744*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->resumeRenderPassQueriesIfActive());
2745*8975f5c5SAndroid Build Coastguard Worker
2746*8975f5c5SAndroid Build Coastguard Worker // If transform feedback was active, we can't pause and resume it in the same render pass
2747*8975f5c5SAndroid Build Coastguard Worker // because we can't insert a memory barrier for the counter buffers. In that case, break the
2748*8975f5c5SAndroid Build Coastguard Worker // render pass.
2749*8975f5c5SAndroid Build Coastguard Worker if (isTransformFeedbackActiveUnpaused)
2750*8975f5c5SAndroid Build Coastguard Worker {
2751*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass(
2752*8975f5c5SAndroid Build Coastguard Worker RenderPassClosureReason::XfbResumeAfterDrawBasedClear));
2753*8975f5c5SAndroid Build Coastguard Worker }
2754*8975f5c5SAndroid Build Coastguard Worker
2755*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2756*8975f5c5SAndroid Build Coastguard Worker }
2757*8975f5c5SAndroid Build Coastguard Worker
clearImage(ContextVk * contextVk,vk::ImageHelper * dst,const ClearImageParameters & params)2758*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::clearImage(ContextVk *contextVk,
2759*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *dst,
2760*8975f5c5SAndroid Build Coastguard Worker const ClearImageParameters ¶ms)
2761*8975f5c5SAndroid Build Coastguard Worker {
2762*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
2763*8975f5c5SAndroid Build Coastguard Worker
2764*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureImageClearResourcesInitialized(contextVk));
2765*8975f5c5SAndroid Build Coastguard Worker
2766*8975f5c5SAndroid Build Coastguard Worker const angle::Format &dstActualFormat = dst->getActualFormat();
2767*8975f5c5SAndroid Build Coastguard Worker
2768*8975f5c5SAndroid Build Coastguard Worker // Currently, this function is only used to clear emulated channels of color images.
2769*8975f5c5SAndroid Build Coastguard Worker ASSERT(!dstActualFormat.hasDepthOrStencilBits());
2770*8975f5c5SAndroid Build Coastguard Worker
2771*8975f5c5SAndroid Build Coastguard Worker // TODO: currently this function is only implemented for images that are drawable. If needed,
2772*8975f5c5SAndroid Build Coastguard Worker // for images that are not drawable, the following algorithm can be used.
2773*8975f5c5SAndroid Build Coastguard Worker //
2774*8975f5c5SAndroid Build Coastguard Worker // - Copy image to temp buffer
2775*8975f5c5SAndroid Build Coastguard Worker // - Use convertVertexBufferImpl to overwrite the alpha channel
2776*8975f5c5SAndroid Build Coastguard Worker // - Copy the result back to the image
2777*8975f5c5SAndroid Build Coastguard Worker //
2778*8975f5c5SAndroid Build Coastguard Worker // Note that the following check is not enough; if the image is AHB-imported, then the draw path
2779*8975f5c5SAndroid Build Coastguard Worker // cannot be taken if AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER hasn't been specified, even if the
2780*8975f5c5SAndroid Build Coastguard Worker // format is renderable.
2781*8975f5c5SAndroid Build Coastguard Worker //
2782*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42264676
2783*8975f5c5SAndroid Build Coastguard Worker if (!vk::FormatHasNecessaryFeature(renderer, dstActualFormat.id, dst->getTilingMode(),
2784*8975f5c5SAndroid Build Coastguard Worker VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
2785*8975f5c5SAndroid Build Coastguard Worker {
2786*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
2787*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2788*8975f5c5SAndroid Build Coastguard Worker }
2789*8975f5c5SAndroid Build Coastguard Worker
2790*8975f5c5SAndroid Build Coastguard Worker vk::DeviceScoped<vk::ImageView> destView(contextVk->getDevice());
2791*8975f5c5SAndroid Build Coastguard Worker const gl::TextureType destViewType = vk::Get2DTextureType(1, dst->getSamples());
2792*8975f5c5SAndroid Build Coastguard Worker
2793*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(dst->initLayerImageView(contextVk, destViewType, VK_IMAGE_ASPECT_COLOR_BIT,
2794*8975f5c5SAndroid Build Coastguard Worker gl::SwizzleState(), &destView.get(), params.dstMip, 1,
2795*8975f5c5SAndroid Build Coastguard Worker params.dstLayer, 1));
2796*8975f5c5SAndroid Build Coastguard Worker
2797*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &renderArea = params.clearArea;
2798*8975f5c5SAndroid Build Coastguard Worker
2799*8975f5c5SAndroid Build Coastguard Worker ImageClearShaderParams shaderParams;
2800*8975f5c5SAndroid Build Coastguard Worker shaderParams.clearValue = params.colorClearValue;
2801*8975f5c5SAndroid Build Coastguard Worker shaderParams.clearDepth = 0;
2802*8975f5c5SAndroid Build Coastguard Worker
2803*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassDesc renderPassDesc;
2804*8975f5c5SAndroid Build Coastguard Worker renderPassDesc.setSamples(dst->getSamples());
2805*8975f5c5SAndroid Build Coastguard Worker renderPassDesc.packColorAttachment(0, dstActualFormat.id);
2806*8975f5c5SAndroid Build Coastguard Worker
2807*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineDesc pipelineDesc;
2808*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.initDefaults(contextVk, vk::GraphicsPipelineSubset::Complete,
2809*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineRobustness(),
2810*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineProtectedAccess());
2811*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setSingleColorWriteMask(0, params.colorMaskFlags);
2812*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRasterizationSamples(dst->getSamples());
2813*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRenderPassDesc(renderPassDesc);
2814*8975f5c5SAndroid Build Coastguard Worker
2815*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer;
2816*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(startRenderPass(contextVk, dst, &destView.get(), renderPassDesc, renderArea,
2817*8975f5c5SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_COLOR_BIT, nullptr,
2818*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassSource::InternalUtils, &commandBuffer));
2819*8975f5c5SAndroid Build Coastguard Worker
2820*8975f5c5SAndroid Build Coastguard Worker UpdateColorAccess(contextVk, MakeColorBufferMask(0), MakeColorBufferMask(0));
2821*8975f5c5SAndroid Build Coastguard Worker
2822*8975f5c5SAndroid Build Coastguard Worker contextVk->onImageRenderPassWrite(dst->toGLLevel(params.dstMip), params.dstLayer, 1,
2823*8975f5c5SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorWrite, dst);
2824*8975f5c5SAndroid Build Coastguard Worker
2825*8975f5c5SAndroid Build Coastguard Worker const uint32_t flags = GetImageClearFlags(dstActualFormat, 0, false);
2826*8975f5c5SAndroid Build Coastguard Worker
2827*8975f5c5SAndroid Build Coastguard Worker vk::ShaderLibrary &shaderLibrary = contextVk->getShaderLibrary();
2828*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr vertexShader;
2829*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr fragmentShader;
2830*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getFullScreenTri_vert(contextVk, 0, &vertexShader));
2831*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getImageClear_frag(contextVk, flags, &fragmentShader));
2832*8975f5c5SAndroid Build Coastguard Worker
2833*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupGraphicsProgram(contextVk, Function::ImageClear, vertexShader, fragmentShader,
2834*8975f5c5SAndroid Build Coastguard Worker &mImageClear[flags], &pipelineDesc, VK_NULL_HANDLE,
2835*8975f5c5SAndroid Build Coastguard Worker &shaderParams, sizeof(shaderParams), commandBuffer));
2836*8975f5c5SAndroid Build Coastguard Worker
2837*8975f5c5SAndroid Build Coastguard Worker // Set dynamic state
2838*8975f5c5SAndroid Build Coastguard Worker VkViewport viewport;
2839*8975f5c5SAndroid Build Coastguard Worker gl_vk::GetViewport(renderArea, 0.0f, 1.0f, false, false, dst->getExtents().height, &viewport);
2840*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setViewport(0, 1, &viewport);
2841*8975f5c5SAndroid Build Coastguard Worker
2842*8975f5c5SAndroid Build Coastguard Worker VkRect2D scissor = gl_vk::GetRect(renderArea);
2843*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setScissor(0, 1, &scissor);
2844*8975f5c5SAndroid Build Coastguard Worker
2845*8975f5c5SAndroid Build Coastguard Worker SetDepthDynamicStateForUnused(renderer, commandBuffer);
2846*8975f5c5SAndroid Build Coastguard Worker SetStencilDynamicStateForUnused(renderer, commandBuffer);
2847*8975f5c5SAndroid Build Coastguard Worker
2848*8975f5c5SAndroid Build Coastguard Worker // Note: this utility creates its own framebuffer, thus bypassing ContextVk::startRenderPass.
2849*8975f5c5SAndroid Build Coastguard Worker // As such, occlusion queries are not enabled.
2850*8975f5c5SAndroid Build Coastguard Worker commandBuffer->draw(3, 0);
2851*8975f5c5SAndroid Build Coastguard Worker
2852*8975f5c5SAndroid Build Coastguard Worker vk::ImageView destViewObject = destView.release();
2853*8975f5c5SAndroid Build Coastguard Worker contextVk->addGarbage(&destViewObject);
2854*8975f5c5SAndroid Build Coastguard Worker
2855*8975f5c5SAndroid Build Coastguard Worker // Close the render pass for this temporary framebuffer.
2856*8975f5c5SAndroid Build Coastguard Worker return contextVk->flushCommandsAndEndRenderPass(
2857*8975f5c5SAndroid Build Coastguard Worker RenderPassClosureReason::TemporaryForImageClear);
2858*8975f5c5SAndroid Build Coastguard Worker }
2859*8975f5c5SAndroid Build Coastguard Worker
colorBlitResolve(ContextVk * contextVk,FramebufferVk * framebuffer,vk::ImageHelper * src,const vk::ImageView * srcView,const BlitResolveParameters & params)2860*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::colorBlitResolve(ContextVk *contextVk,
2861*8975f5c5SAndroid Build Coastguard Worker FramebufferVk *framebuffer,
2862*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *src,
2863*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *srcView,
2864*8975f5c5SAndroid Build Coastguard Worker const BlitResolveParameters ¶ms)
2865*8975f5c5SAndroid Build Coastguard Worker {
2866*8975f5c5SAndroid Build Coastguard Worker // The views passed to this function are already retained, so a render pass cannot be already
2867*8975f5c5SAndroid Build Coastguard Worker // open. Otherwise, this function closes the render pass, which may incur a vkQueueSubmit and
2868*8975f5c5SAndroid Build Coastguard Worker // then the views are used in a new command buffer without having been retained for it.
2869*8975f5c5SAndroid Build Coastguard Worker // http://crbug.com/1272266#c22
2870*8975f5c5SAndroid Build Coastguard Worker //
2871*8975f5c5SAndroid Build Coastguard Worker // Note that depth/stencil views for blit are not derived from a |Resource| class and are
2872*8975f5c5SAndroid Build Coastguard Worker // retained differently.
2873*8975f5c5SAndroid Build Coastguard Worker ASSERT(!contextVk->hasActiveRenderPass());
2874*8975f5c5SAndroid Build Coastguard Worker
2875*8975f5c5SAndroid Build Coastguard Worker return blitResolveImpl(contextVk, framebuffer, src, srcView, nullptr, nullptr, params);
2876*8975f5c5SAndroid Build Coastguard Worker }
2877*8975f5c5SAndroid Build Coastguard Worker
depthStencilBlitResolve(ContextVk * contextVk,FramebufferVk * framebuffer,vk::ImageHelper * src,const vk::ImageView * srcDepthView,const vk::ImageView * srcStencilView,const BlitResolveParameters & params)2878*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::depthStencilBlitResolve(ContextVk *contextVk,
2879*8975f5c5SAndroid Build Coastguard Worker FramebufferVk *framebuffer,
2880*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *src,
2881*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *srcDepthView,
2882*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *srcStencilView,
2883*8975f5c5SAndroid Build Coastguard Worker const BlitResolveParameters ¶ms)
2884*8975f5c5SAndroid Build Coastguard Worker {
2885*8975f5c5SAndroid Build Coastguard Worker return blitResolveImpl(contextVk, framebuffer, src, nullptr, srcDepthView, srcStencilView,
2886*8975f5c5SAndroid Build Coastguard Worker params);
2887*8975f5c5SAndroid Build Coastguard Worker }
2888*8975f5c5SAndroid Build Coastguard Worker
blitResolveImpl(ContextVk * contextVk,FramebufferVk * framebuffer,vk::ImageHelper * src,const vk::ImageView * srcColorView,const vk::ImageView * srcDepthView,const vk::ImageView * srcStencilView,const BlitResolveParameters & params)2889*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::blitResolveImpl(ContextVk *contextVk,
2890*8975f5c5SAndroid Build Coastguard Worker FramebufferVk *framebuffer,
2891*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *src,
2892*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *srcColorView,
2893*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *srcDepthView,
2894*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *srcStencilView,
2895*8975f5c5SAndroid Build Coastguard Worker const BlitResolveParameters ¶ms)
2896*8975f5c5SAndroid Build Coastguard Worker {
2897*8975f5c5SAndroid Build Coastguard Worker // Possible ways to resolve color are:
2898*8975f5c5SAndroid Build Coastguard Worker //
2899*8975f5c5SAndroid Build Coastguard Worker // - vkCmdResolveImage: This is by far the easiest method, but lacks the ability to flip
2900*8975f5c5SAndroid Build Coastguard Worker // images during resolve.
2901*8975f5c5SAndroid Build Coastguard Worker // - Manual resolve: A shader can read all samples from input, average them and output.
2902*8975f5c5SAndroid Build Coastguard Worker // - Using subpass resolve attachment: A shader can transform the sample colors from source to
2903*8975f5c5SAndroid Build Coastguard Worker // destination coordinates and the subpass resolve would finish the job.
2904*8975f5c5SAndroid Build Coastguard Worker //
2905*8975f5c5SAndroid Build Coastguard Worker // The first method is unable to handle flipping, so it's not generally applicable. The last
2906*8975f5c5SAndroid Build Coastguard Worker // method would have been great were we able to modify the last render pass that rendered into
2907*8975f5c5SAndroid Build Coastguard Worker // source, but still wouldn't be able to handle flipping. The second method is implemented in
2908*8975f5c5SAndroid Build Coastguard Worker // this function for complete control.
2909*8975f5c5SAndroid Build Coastguard Worker
2910*8975f5c5SAndroid Build Coastguard Worker // Possible ways to resolve depth/stencil are:
2911*8975f5c5SAndroid Build Coastguard Worker //
2912*8975f5c5SAndroid Build Coastguard Worker // - Manual resolve: A shader can read a samples from input and choose that for output.
2913*8975f5c5SAndroid Build Coastguard Worker // - Using subpass resolve attachment through VkSubpassDescriptionDepthStencilResolveKHR: This
2914*8975f5c5SAndroid Build Coastguard Worker // requires an extension that's not very well supported.
2915*8975f5c5SAndroid Build Coastguard Worker //
2916*8975f5c5SAndroid Build Coastguard Worker // The first method is implemented in this function.
2917*8975f5c5SAndroid Build Coastguard Worker
2918*8975f5c5SAndroid Build Coastguard Worker // Possible ways to blit color, depth or stencil are:
2919*8975f5c5SAndroid Build Coastguard Worker //
2920*8975f5c5SAndroid Build Coastguard Worker // - vkCmdBlitImage: This function works if the source and destination formats have the blit
2921*8975f5c5SAndroid Build Coastguard Worker // feature.
2922*8975f5c5SAndroid Build Coastguard Worker // - Manual blit: A shader can sample from the source image and write it to the destination.
2923*8975f5c5SAndroid Build Coastguard Worker //
2924*8975f5c5SAndroid Build Coastguard Worker // The first method has a serious shortcoming. GLES allows blit parameters to exceed the
2925*8975f5c5SAndroid Build Coastguard Worker // source or destination boundaries. The actual blit is clipped to these limits, but the
2926*8975f5c5SAndroid Build Coastguard Worker // scaling applied is determined solely by the input areas. Vulkan requires the blit parameters
2927*8975f5c5SAndroid Build Coastguard Worker // to be within the source and destination bounds. This makes it hard to keep the scaling
2928*8975f5c5SAndroid Build Coastguard Worker // constant.
2929*8975f5c5SAndroid Build Coastguard Worker //
2930*8975f5c5SAndroid Build Coastguard Worker // The second method is implemented in this function, which shares code with the resolve method.
2931*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
2932*8975f5c5SAndroid Build Coastguard Worker
2933*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureBlitResolveResourcesInitialized(contextVk));
2934*8975f5c5SAndroid Build Coastguard Worker
2935*8975f5c5SAndroid Build Coastguard Worker bool isResolve = src->getSamples() > 1;
2936*8975f5c5SAndroid Build Coastguard Worker
2937*8975f5c5SAndroid Build Coastguard Worker BlitResolveShaderParams shaderParams;
2938*8975f5c5SAndroid Build Coastguard Worker // Note: adjustments made for pre-rotatation in FramebufferVk::blit() affect these
2939*8975f5c5SAndroid Build Coastguard Worker // Calculate*Offset() functions.
2940*8975f5c5SAndroid Build Coastguard Worker if (isResolve)
2941*8975f5c5SAndroid Build Coastguard Worker {
2942*8975f5c5SAndroid Build Coastguard Worker CalculateResolveOffset(params, shaderParams.offset.resolve);
2943*8975f5c5SAndroid Build Coastguard Worker }
2944*8975f5c5SAndroid Build Coastguard Worker else
2945*8975f5c5SAndroid Build Coastguard Worker {
2946*8975f5c5SAndroid Build Coastguard Worker CalculateBlitOffset(params, shaderParams.offset.blit);
2947*8975f5c5SAndroid Build Coastguard Worker }
2948*8975f5c5SAndroid Build Coastguard Worker shaderParams.stretch[0] = params.stretch[0];
2949*8975f5c5SAndroid Build Coastguard Worker shaderParams.stretch[1] = params.stretch[1];
2950*8975f5c5SAndroid Build Coastguard Worker shaderParams.invSrcExtent[0] = 1.0f / params.srcExtents[0];
2951*8975f5c5SAndroid Build Coastguard Worker shaderParams.invSrcExtent[1] = 1.0f / params.srcExtents[1];
2952*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcLayer = params.srcLayer;
2953*8975f5c5SAndroid Build Coastguard Worker shaderParams.samples = src->getSamples();
2954*8975f5c5SAndroid Build Coastguard Worker shaderParams.invSamples = 1.0f / shaderParams.samples;
2955*8975f5c5SAndroid Build Coastguard Worker shaderParams.outputMask = framebuffer->getState().getEnabledDrawBuffers().bits();
2956*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipX = params.flipX;
2957*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipY = params.flipY;
2958*8975f5c5SAndroid Build Coastguard Worker shaderParams.rotateXY = 0;
2959*8975f5c5SAndroid Build Coastguard Worker
2960*8975f5c5SAndroid Build Coastguard Worker // Potentially make adjustments for pre-rotation. Depending on the angle some of the
2961*8975f5c5SAndroid Build Coastguard Worker // shaderParams need to be adjusted.
2962*8975f5c5SAndroid Build Coastguard Worker switch (params.rotation)
2963*8975f5c5SAndroid Build Coastguard Worker {
2964*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Identity:
2965*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated90Degrees:
2966*8975f5c5SAndroid Build Coastguard Worker break;
2967*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated180Degrees:
2968*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated270Degrees:
2969*8975f5c5SAndroid Build Coastguard Worker if (isResolve)
2970*8975f5c5SAndroid Build Coastguard Worker {
2971*8975f5c5SAndroid Build Coastguard Worker // Align the offset with minus 1, or the sample position near the edge will be
2972*8975f5c5SAndroid Build Coastguard Worker // wrong.
2973*8975f5c5SAndroid Build Coastguard Worker shaderParams.offset.resolve[0] += params.rotatedOffsetFactor[0] - 1;
2974*8975f5c5SAndroid Build Coastguard Worker shaderParams.offset.resolve[1] += params.rotatedOffsetFactor[1] - 1;
2975*8975f5c5SAndroid Build Coastguard Worker }
2976*8975f5c5SAndroid Build Coastguard Worker else
2977*8975f5c5SAndroid Build Coastguard Worker {
2978*8975f5c5SAndroid Build Coastguard Worker shaderParams.offset.blit[0] += params.rotatedOffsetFactor[0];
2979*8975f5c5SAndroid Build Coastguard Worker shaderParams.offset.blit[1] += params.rotatedOffsetFactor[1];
2980*8975f5c5SAndroid Build Coastguard Worker }
2981*8975f5c5SAndroid Build Coastguard Worker break;
2982*8975f5c5SAndroid Build Coastguard Worker default:
2983*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
2984*8975f5c5SAndroid Build Coastguard Worker break;
2985*8975f5c5SAndroid Build Coastguard Worker }
2986*8975f5c5SAndroid Build Coastguard Worker
2987*8975f5c5SAndroid Build Coastguard Worker shaderParams.rotateXY = IsRotatedAspectRatio(params.rotation);
2988*8975f5c5SAndroid Build Coastguard Worker
2989*8975f5c5SAndroid Build Coastguard Worker bool blitColor = srcColorView != nullptr;
2990*8975f5c5SAndroid Build Coastguard Worker bool blitDepth = srcDepthView != nullptr;
2991*8975f5c5SAndroid Build Coastguard Worker bool blitStencil = srcStencilView != nullptr;
2992*8975f5c5SAndroid Build Coastguard Worker
2993*8975f5c5SAndroid Build Coastguard Worker // Either color is blitted/resolved or depth/stencil, but not both.
2994*8975f5c5SAndroid Build Coastguard Worker ASSERT(blitColor != (blitDepth || blitStencil));
2995*8975f5c5SAndroid Build Coastguard Worker
2996*8975f5c5SAndroid Build Coastguard Worker // Linear sampling is only valid with color blitting.
2997*8975f5c5SAndroid Build Coastguard Worker ASSERT((blitColor && !isResolve) || !params.linear);
2998*8975f5c5SAndroid Build Coastguard Worker
2999*8975f5c5SAndroid Build Coastguard Worker uint32_t flags =
3000*8975f5c5SAndroid Build Coastguard Worker GetBlitResolveFlags(blitColor, blitDepth, blitStencil, src->getIntendedFormat());
3001*8975f5c5SAndroid Build Coastguard Worker flags |= src->getLayerCount() > 1 ? BlitResolve_frag::kSrcIsArray : 0;
3002*8975f5c5SAndroid Build Coastguard Worker flags |= isResolve ? BlitResolve_frag::kIsResolve : 0;
3003*8975f5c5SAndroid Build Coastguard Worker Function function = Function::BlitResolve;
3004*8975f5c5SAndroid Build Coastguard Worker
3005*8975f5c5SAndroid Build Coastguard Worker // Note: a different shader is used for 3D color blits, but otherwise the desc sets, parameters
3006*8975f5c5SAndroid Build Coastguard Worker // etc are identical.
3007*8975f5c5SAndroid Build Coastguard Worker const bool isSrc3D = src->getType() == VK_IMAGE_TYPE_3D;
3008*8975f5c5SAndroid Build Coastguard Worker ASSERT(!isSrc3D || (blitColor && !isResolve));
3009*8975f5c5SAndroid Build Coastguard Worker if (isSrc3D)
3010*8975f5c5SAndroid Build Coastguard Worker {
3011*8975f5c5SAndroid Build Coastguard Worker flags = GetFormatFlags(src->getIntendedFormat(), Blit3DSrc_frag::kBlitInt,
3012*8975f5c5SAndroid Build Coastguard Worker Blit3DSrc_frag::kBlitUint, Blit3DSrc_frag::kBlitFloat);
3013*8975f5c5SAndroid Build Coastguard Worker }
3014*8975f5c5SAndroid Build Coastguard Worker
3015*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineDesc pipelineDesc;
3016*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.initDefaults(contextVk, vk::GraphicsPipelineSubset::Complete,
3017*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineRobustness(),
3018*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineProtectedAccess());
3019*8975f5c5SAndroid Build Coastguard Worker if (blitColor)
3020*8975f5c5SAndroid Build Coastguard Worker {
3021*8975f5c5SAndroid Build Coastguard Worker constexpr VkColorComponentFlags kAllColorComponents =
3022*8975f5c5SAndroid Build Coastguard Worker VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT |
3023*8975f5c5SAndroid Build Coastguard Worker VK_COLOR_COMPONENT_A_BIT;
3024*8975f5c5SAndroid Build Coastguard Worker
3025*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setColorWriteMasks(
3026*8975f5c5SAndroid Build Coastguard Worker gl::BlendStateExt::ColorMaskStorage::GetReplicatedValue(
3027*8975f5c5SAndroid Build Coastguard Worker kAllColorComponents, gl::BlendStateExt::ColorMaskStorage::GetMask(
3028*8975f5c5SAndroid Build Coastguard Worker framebuffer->getRenderPassDesc().colorAttachmentRange())),
3029*8975f5c5SAndroid Build Coastguard Worker framebuffer->getEmulatedAlphaAttachmentMask(), ~gl::DrawBufferMask());
3030*8975f5c5SAndroid Build Coastguard Worker }
3031*8975f5c5SAndroid Build Coastguard Worker else
3032*8975f5c5SAndroid Build Coastguard Worker {
3033*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setColorWriteMasks(0, gl::DrawBufferMask(), gl::DrawBufferMask());
3034*8975f5c5SAndroid Build Coastguard Worker }
3035*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRenderPassDesc(framebuffer->getRenderPassDesc());
3036*8975f5c5SAndroid Build Coastguard Worker if (blitDepth)
3037*8975f5c5SAndroid Build Coastguard Worker {
3038*8975f5c5SAndroid Build Coastguard Worker SetDepthStateForWrite(renderer, &pipelineDesc);
3039*8975f5c5SAndroid Build Coastguard Worker }
3040*8975f5c5SAndroid Build Coastguard Worker
3041*8975f5c5SAndroid Build Coastguard Worker if (blitStencil)
3042*8975f5c5SAndroid Build Coastguard Worker {
3043*8975f5c5SAndroid Build Coastguard Worker SetStencilStateForWrite(renderer, &pipelineDesc);
3044*8975f5c5SAndroid Build Coastguard Worker }
3045*8975f5c5SAndroid Build Coastguard Worker
3046*8975f5c5SAndroid Build Coastguard Worker // All deferred clear must have been flushed, otherwise it will conflict with params.blitArea.
3047*8975f5c5SAndroid Build Coastguard Worker ASSERT(!framebuffer->hasDeferredClears());
3048*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer;
3049*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, params.blitArea, &commandBuffer, nullptr));
3050*8975f5c5SAndroid Build Coastguard Worker
3051*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
3052*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, &contextVk->getStartedRenderPassCommands(),
3053*8975f5c5SAndroid Build Coastguard Worker Function::BlitResolve, &descriptorSet));
3054*8975f5c5SAndroid Build Coastguard Worker
3055*8975f5c5SAndroid Build Coastguard Worker // Pick layout consistent with GetImageReadLayout() to avoid unnecessary layout change.
3056*8975f5c5SAndroid Build Coastguard Worker vk::ImageLayout srcImagelayout = src->isDepthOrStencil()
3057*8975f5c5SAndroid Build Coastguard Worker ? vk::ImageLayout::DepthReadStencilReadFragmentShaderRead
3058*8975f5c5SAndroid Build Coastguard Worker : vk::ImageLayout::FragmentShaderReadOnly;
3059*8975f5c5SAndroid Build Coastguard Worker contextVk->onImageRenderPassRead(src->getAspectFlags(), srcImagelayout, src);
3060*8975f5c5SAndroid Build Coastguard Worker
3061*8975f5c5SAndroid Build Coastguard Worker UpdateColorAccess(contextVk, framebuffer->getState().getColorAttachmentsMask(),
3062*8975f5c5SAndroid Build Coastguard Worker framebuffer->getState().getEnabledDrawBuffers());
3063*8975f5c5SAndroid Build Coastguard Worker UpdateDepthStencilAccess(contextVk, blitDepth, blitStencil);
3064*8975f5c5SAndroid Build Coastguard Worker
3065*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo imageInfos[2] = {};
3066*8975f5c5SAndroid Build Coastguard Worker
3067*8975f5c5SAndroid Build Coastguard Worker if (blitColor)
3068*8975f5c5SAndroid Build Coastguard Worker {
3069*8975f5c5SAndroid Build Coastguard Worker imageInfos[0].imageView = srcColorView->getHandle();
3070*8975f5c5SAndroid Build Coastguard Worker imageInfos[0].imageLayout = src->getCurrentLayout(renderer);
3071*8975f5c5SAndroid Build Coastguard Worker }
3072*8975f5c5SAndroid Build Coastguard Worker if (blitDepth)
3073*8975f5c5SAndroid Build Coastguard Worker {
3074*8975f5c5SAndroid Build Coastguard Worker imageInfos[0].imageView = srcDepthView->getHandle();
3075*8975f5c5SAndroid Build Coastguard Worker imageInfos[0].imageLayout = src->getCurrentLayout(renderer);
3076*8975f5c5SAndroid Build Coastguard Worker }
3077*8975f5c5SAndroid Build Coastguard Worker if (blitStencil)
3078*8975f5c5SAndroid Build Coastguard Worker {
3079*8975f5c5SAndroid Build Coastguard Worker imageInfos[1].imageView = srcStencilView->getHandle();
3080*8975f5c5SAndroid Build Coastguard Worker imageInfos[1].imageLayout = src->getCurrentLayout(renderer);
3081*8975f5c5SAndroid Build Coastguard Worker }
3082*8975f5c5SAndroid Build Coastguard Worker
3083*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo samplerInfo = {};
3084*8975f5c5SAndroid Build Coastguard Worker samplerInfo.sampler = params.linear ? mLinearSampler.getHandle() : mPointSampler.getHandle();
3085*8975f5c5SAndroid Build Coastguard Worker
3086*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfos[3] = {};
3087*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
3088*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstSet = descriptorSet;
3089*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstBinding = kBlitResolveColorOrDepthBinding;
3090*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorCount = 1;
3091*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
3092*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].pImageInfo = &imageInfos[0];
3093*8975f5c5SAndroid Build Coastguard Worker
3094*8975f5c5SAndroid Build Coastguard Worker writeInfos[1] = writeInfos[0];
3095*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].dstBinding = kBlitResolveStencilBinding;
3096*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].pImageInfo = &imageInfos[1];
3097*8975f5c5SAndroid Build Coastguard Worker
3098*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
3099*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].dstSet = descriptorSet;
3100*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].dstBinding = kBlitResolveSamplerBinding;
3101*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].descriptorCount = 1;
3102*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
3103*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].pImageInfo = &samplerInfo;
3104*8975f5c5SAndroid Build Coastguard Worker
3105*8975f5c5SAndroid Build Coastguard Worker // If resolving color, there's one write info; index 0
3106*8975f5c5SAndroid Build Coastguard Worker // If resolving depth, write info index 0 must be written
3107*8975f5c5SAndroid Build Coastguard Worker // If resolving stencil, write info index 1 must also be written
3108*8975f5c5SAndroid Build Coastguard Worker //
3109*8975f5c5SAndroid Build Coastguard Worker // Note again that resolving color and depth/stencil are mutually exclusive here.
3110*8975f5c5SAndroid Build Coastguard Worker uint32_t writeInfoOffset = blitDepth || blitColor ? 0 : 1;
3111*8975f5c5SAndroid Build Coastguard Worker uint32_t writeInfoCount = blitColor + blitDepth + blitStencil;
3112*8975f5c5SAndroid Build Coastguard Worker
3113*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), writeInfoCount, writeInfos + writeInfoOffset, 0,
3114*8975f5c5SAndroid Build Coastguard Worker nullptr);
3115*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 1, &writeInfos[2], 0, nullptr);
3116*8975f5c5SAndroid Build Coastguard Worker
3117*8975f5c5SAndroid Build Coastguard Worker vk::ShaderLibrary &shaderLibrary = contextVk->getShaderLibrary();
3118*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr vertexShader;
3119*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr fragmentShader;
3120*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getFullScreenTri_vert(contextVk, 0, &vertexShader));
3121*8975f5c5SAndroid Build Coastguard Worker if (isSrc3D)
3122*8975f5c5SAndroid Build Coastguard Worker {
3123*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getBlit3DSrc_frag(contextVk, flags, &fragmentShader));
3124*8975f5c5SAndroid Build Coastguard Worker }
3125*8975f5c5SAndroid Build Coastguard Worker else
3126*8975f5c5SAndroid Build Coastguard Worker {
3127*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getBlitResolve_frag(contextVk, flags, &fragmentShader));
3128*8975f5c5SAndroid Build Coastguard Worker }
3129*8975f5c5SAndroid Build Coastguard Worker
3130*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupGraphicsProgram(contextVk, function, vertexShader, fragmentShader,
3131*8975f5c5SAndroid Build Coastguard Worker isSrc3D ? &mBlit3DSrc[flags] : &mBlitResolve[flags],
3132*8975f5c5SAndroid Build Coastguard Worker &pipelineDesc, descriptorSet, &shaderParams,
3133*8975f5c5SAndroid Build Coastguard Worker sizeof(shaderParams), commandBuffer));
3134*8975f5c5SAndroid Build Coastguard Worker
3135*8975f5c5SAndroid Build Coastguard Worker // Set dynamic state
3136*8975f5c5SAndroid Build Coastguard Worker VkViewport viewport;
3137*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle completeRenderArea = framebuffer->getRotatedCompleteRenderArea(contextVk);
3138*8975f5c5SAndroid Build Coastguard Worker gl_vk::GetViewport(completeRenderArea, 0.0f, 1.0f, false, false, completeRenderArea.height,
3139*8975f5c5SAndroid Build Coastguard Worker &viewport);
3140*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setViewport(0, 1, &viewport);
3141*8975f5c5SAndroid Build Coastguard Worker
3142*8975f5c5SAndroid Build Coastguard Worker VkRect2D scissor = gl_vk::GetRect(params.blitArea);
3143*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setScissor(0, 1, &scissor);
3144*8975f5c5SAndroid Build Coastguard Worker
3145*8975f5c5SAndroid Build Coastguard Worker if (blitDepth)
3146*8975f5c5SAndroid Build Coastguard Worker {
3147*8975f5c5SAndroid Build Coastguard Worker SetDepthDynamicStateForWrite(renderer, commandBuffer);
3148*8975f5c5SAndroid Build Coastguard Worker }
3149*8975f5c5SAndroid Build Coastguard Worker else
3150*8975f5c5SAndroid Build Coastguard Worker {
3151*8975f5c5SAndroid Build Coastguard Worker SetDepthDynamicStateForUnused(renderer, commandBuffer);
3152*8975f5c5SAndroid Build Coastguard Worker }
3153*8975f5c5SAndroid Build Coastguard Worker
3154*8975f5c5SAndroid Build Coastguard Worker if (blitStencil)
3155*8975f5c5SAndroid Build Coastguard Worker {
3156*8975f5c5SAndroid Build Coastguard Worker constexpr uint8_t kCompleteMask = 0xFF;
3157*8975f5c5SAndroid Build Coastguard Worker constexpr uint8_t kUnusedReference = 0x00;
3158*8975f5c5SAndroid Build Coastguard Worker
3159*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilCompareMask(kCompleteMask, kCompleteMask);
3160*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilWriteMask(kCompleteMask, kCompleteMask);
3161*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilReference(kUnusedReference, kUnusedReference);
3162*8975f5c5SAndroid Build Coastguard Worker
3163*8975f5c5SAndroid Build Coastguard Worker SetStencilDynamicStateForWrite(renderer, commandBuffer);
3164*8975f5c5SAndroid Build Coastguard Worker }
3165*8975f5c5SAndroid Build Coastguard Worker else
3166*8975f5c5SAndroid Build Coastguard Worker {
3167*8975f5c5SAndroid Build Coastguard Worker SetStencilDynamicStateForUnused(renderer, commandBuffer);
3168*8975f5c5SAndroid Build Coastguard Worker }
3169*8975f5c5SAndroid Build Coastguard Worker
3170*8975f5c5SAndroid Build Coastguard Worker // Note: this utility starts the render pass directly, thus bypassing
3171*8975f5c5SAndroid Build Coastguard Worker // ContextVk::startRenderPass. As such, occlusion queries are not enabled.
3172*8975f5c5SAndroid Build Coastguard Worker commandBuffer->draw(3, 0);
3173*8975f5c5SAndroid Build Coastguard Worker
3174*8975f5c5SAndroid Build Coastguard Worker // Don't allow this render pass to be reactivated by the user's draw call due to test flakiness
3175*8975f5c5SAndroid Build Coastguard Worker // on win/intel bot.
3176*8975f5c5SAndroid Build Coastguard Worker contextVk->disableRenderPassReactivation();
3177*8975f5c5SAndroid Build Coastguard Worker
3178*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3179*8975f5c5SAndroid Build Coastguard Worker }
3180*8975f5c5SAndroid Build Coastguard Worker
stencilBlitResolveNoShaderExport(ContextVk * contextVk,FramebufferVk * framebuffer,vk::ImageHelper * src,const vk::ImageView * srcStencilView,const BlitResolveParameters & params)3181*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::stencilBlitResolveNoShaderExport(ContextVk *contextVk,
3182*8975f5c5SAndroid Build Coastguard Worker FramebufferVk *framebuffer,
3183*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *src,
3184*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *srcStencilView,
3185*8975f5c5SAndroid Build Coastguard Worker const BlitResolveParameters ¶ms)
3186*8975f5c5SAndroid Build Coastguard Worker {
3187*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
3188*8975f5c5SAndroid Build Coastguard Worker
3189*8975f5c5SAndroid Build Coastguard Worker // When VK_EXT_shader_stencil_export is not available, stencil is blitted/resolved into a
3190*8975f5c5SAndroid Build Coastguard Worker // temporary buffer which is then copied into the stencil aspect of the image.
3191*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureBlitResolveStencilNoExportResourcesInitialized(contextVk));
3192*8975f5c5SAndroid Build Coastguard Worker
3193*8975f5c5SAndroid Build Coastguard Worker bool isResolve = src->getSamples() > 1;
3194*8975f5c5SAndroid Build Coastguard Worker
3195*8975f5c5SAndroid Build Coastguard Worker // Create a temporary buffer to blit/resolve stencil into.
3196*8975f5c5SAndroid Build Coastguard Worker vk::RendererScoped<vk::BufferHelper> blitBuffer(renderer);
3197*8975f5c5SAndroid Build Coastguard Worker
3198*8975f5c5SAndroid Build Coastguard Worker uint32_t bufferRowLengthInUints = UnsignedCeilDivide(params.blitArea.width, sizeof(uint32_t));
3199*8975f5c5SAndroid Build Coastguard Worker VkDeviceSize bufferSize = bufferRowLengthInUints * sizeof(uint32_t) * params.blitArea.height;
3200*8975f5c5SAndroid Build Coastguard Worker
3201*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->initBufferAllocation(
3202*8975f5c5SAndroid Build Coastguard Worker &blitBuffer.get(), renderer->getDeviceLocalMemoryTypeIndex(),
3203*8975f5c5SAndroid Build Coastguard Worker static_cast<size_t>(bufferSize), renderer->getDefaultBufferAlignment(),
3204*8975f5c5SAndroid Build Coastguard Worker BufferUsageType::Static));
3205*8975f5c5SAndroid Build Coastguard Worker
3206*8975f5c5SAndroid Build Coastguard Worker BlitResolveStencilNoExportShaderParams shaderParams;
3207*8975f5c5SAndroid Build Coastguard Worker // Note: adjustments made for pre-rotatation in FramebufferVk::blit() affect these
3208*8975f5c5SAndroid Build Coastguard Worker // Calculate*Offset() functions.
3209*8975f5c5SAndroid Build Coastguard Worker if (isResolve)
3210*8975f5c5SAndroid Build Coastguard Worker {
3211*8975f5c5SAndroid Build Coastguard Worker CalculateResolveOffset(params, shaderParams.offset.resolve);
3212*8975f5c5SAndroid Build Coastguard Worker }
3213*8975f5c5SAndroid Build Coastguard Worker else
3214*8975f5c5SAndroid Build Coastguard Worker {
3215*8975f5c5SAndroid Build Coastguard Worker CalculateBlitOffset(params, shaderParams.offset.blit);
3216*8975f5c5SAndroid Build Coastguard Worker }
3217*8975f5c5SAndroid Build Coastguard Worker shaderParams.stretch[0] = params.stretch[0];
3218*8975f5c5SAndroid Build Coastguard Worker shaderParams.stretch[1] = params.stretch[1];
3219*8975f5c5SAndroid Build Coastguard Worker shaderParams.invSrcExtent[0] = 1.0f / params.srcExtents[0];
3220*8975f5c5SAndroid Build Coastguard Worker shaderParams.invSrcExtent[1] = 1.0f / params.srcExtents[1];
3221*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcLayer = params.srcLayer;
3222*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcWidth = params.srcExtents[0];
3223*8975f5c5SAndroid Build Coastguard Worker shaderParams.dstPitch = bufferRowLengthInUints;
3224*8975f5c5SAndroid Build Coastguard Worker shaderParams.blitArea[0] = params.blitArea.x;
3225*8975f5c5SAndroid Build Coastguard Worker shaderParams.blitArea[1] = params.blitArea.y;
3226*8975f5c5SAndroid Build Coastguard Worker shaderParams.blitArea[2] = params.blitArea.width;
3227*8975f5c5SAndroid Build Coastguard Worker shaderParams.blitArea[3] = params.blitArea.height;
3228*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipX = params.flipX;
3229*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipY = params.flipY;
3230*8975f5c5SAndroid Build Coastguard Worker shaderParams.rotateXY = 0;
3231*8975f5c5SAndroid Build Coastguard Worker
3232*8975f5c5SAndroid Build Coastguard Worker // Potentially make adjustments for pre-rotatation. Depending on the angle some of the
3233*8975f5c5SAndroid Build Coastguard Worker // shaderParams need to be adjusted.
3234*8975f5c5SAndroid Build Coastguard Worker switch (params.rotation)
3235*8975f5c5SAndroid Build Coastguard Worker {
3236*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Identity:
3237*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated90Degrees:
3238*8975f5c5SAndroid Build Coastguard Worker break;
3239*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated180Degrees:
3240*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated270Degrees:
3241*8975f5c5SAndroid Build Coastguard Worker if (isResolve)
3242*8975f5c5SAndroid Build Coastguard Worker {
3243*8975f5c5SAndroid Build Coastguard Worker // Align the offset with minus 1, or the sample position near the edge will be
3244*8975f5c5SAndroid Build Coastguard Worker // wrong.
3245*8975f5c5SAndroid Build Coastguard Worker shaderParams.offset.resolve[0] += params.rotatedOffsetFactor[0] - 1;
3246*8975f5c5SAndroid Build Coastguard Worker shaderParams.offset.resolve[1] += params.rotatedOffsetFactor[1] - 1;
3247*8975f5c5SAndroid Build Coastguard Worker }
3248*8975f5c5SAndroid Build Coastguard Worker else
3249*8975f5c5SAndroid Build Coastguard Worker {
3250*8975f5c5SAndroid Build Coastguard Worker shaderParams.offset.blit[0] += params.rotatedOffsetFactor[0];
3251*8975f5c5SAndroid Build Coastguard Worker shaderParams.offset.blit[1] += params.rotatedOffsetFactor[1];
3252*8975f5c5SAndroid Build Coastguard Worker }
3253*8975f5c5SAndroid Build Coastguard Worker break;
3254*8975f5c5SAndroid Build Coastguard Worker default:
3255*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
3256*8975f5c5SAndroid Build Coastguard Worker break;
3257*8975f5c5SAndroid Build Coastguard Worker }
3258*8975f5c5SAndroid Build Coastguard Worker
3259*8975f5c5SAndroid Build Coastguard Worker shaderParams.rotateXY = IsRotatedAspectRatio(params.rotation);
3260*8975f5c5SAndroid Build Coastguard Worker
3261*8975f5c5SAndroid Build Coastguard Worker // Linear sampling is only valid with color blitting.
3262*8975f5c5SAndroid Build Coastguard Worker ASSERT(!params.linear);
3263*8975f5c5SAndroid Build Coastguard Worker
3264*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = src->getLayerCount() > 1 ? BlitResolveStencilNoExport_comp::kSrcIsArray : 0;
3265*8975f5c5SAndroid Build Coastguard Worker flags |= isResolve ? BlitResolve_frag::kIsResolve : 0;
3266*8975f5c5SAndroid Build Coastguard Worker
3267*8975f5c5SAndroid Build Coastguard Worker RenderTargetVk *depthStencilRenderTarget = framebuffer->getDepthStencilRenderTarget();
3268*8975f5c5SAndroid Build Coastguard Worker ASSERT(depthStencilRenderTarget != nullptr);
3269*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *depthStencilImage = &depthStencilRenderTarget->getImageForWrite();
3270*8975f5c5SAndroid Build Coastguard Worker
3271*8975f5c5SAndroid Build Coastguard Worker // Change layouts prior to computation.
3272*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access;
3273*8975f5c5SAndroid Build Coastguard Worker access.onImageComputeShaderRead(src->getAspectFlags(), src);
3274*8975f5c5SAndroid Build Coastguard Worker access.onImageTransferWrite(depthStencilRenderTarget->getLevelIndex(), 1,
3275*8975f5c5SAndroid Build Coastguard Worker depthStencilRenderTarget->getLayerIndex(), 1,
3276*8975f5c5SAndroid Build Coastguard Worker depthStencilImage->getAspectFlags(), depthStencilImage);
3277*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(&blitBuffer.get());
3278*8975f5c5SAndroid Build Coastguard Worker
3279*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
3280*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
3281*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
3282*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper(access, &commandBufferHelper));
3283*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &commandBufferHelper->getCommandBuffer();
3284*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, commandBufferHelper,
3285*8975f5c5SAndroid Build Coastguard Worker Function::BlitResolveStencilNoExport, &descriptorSet));
3286*8975f5c5SAndroid Build Coastguard Worker
3287*8975f5c5SAndroid Build Coastguard Worker // Blit/resolve stencil into the buffer.
3288*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo imageInfo = {};
3289*8975f5c5SAndroid Build Coastguard Worker imageInfo.imageView = srcStencilView->getHandle();
3290*8975f5c5SAndroid Build Coastguard Worker imageInfo.imageLayout = src->getCurrentLayout(renderer);
3291*8975f5c5SAndroid Build Coastguard Worker
3292*8975f5c5SAndroid Build Coastguard Worker VkDescriptorBufferInfo bufferInfo = {};
3293*8975f5c5SAndroid Build Coastguard Worker bufferInfo.buffer = blitBuffer.get().getBuffer().getHandle();
3294*8975f5c5SAndroid Build Coastguard Worker bufferInfo.offset = blitBuffer.get().getOffset();
3295*8975f5c5SAndroid Build Coastguard Worker bufferInfo.range = blitBuffer.get().getSize();
3296*8975f5c5SAndroid Build Coastguard Worker
3297*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo samplerInfo = {};
3298*8975f5c5SAndroid Build Coastguard Worker samplerInfo.sampler = params.linear ? mLinearSampler.getHandle() : mPointSampler.getHandle();
3299*8975f5c5SAndroid Build Coastguard Worker
3300*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfos[3] = {};
3301*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
3302*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstSet = descriptorSet;
3303*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstBinding = kBlitResolveStencilNoExportDestBinding;
3304*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorCount = 1;
3305*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
3306*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].pBufferInfo = &bufferInfo;
3307*8975f5c5SAndroid Build Coastguard Worker
3308*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
3309*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].dstSet = descriptorSet;
3310*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].dstBinding = kBlitResolveStencilNoExportSrcBinding;
3311*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].descriptorCount = 1;
3312*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
3313*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].pImageInfo = &imageInfo;
3314*8975f5c5SAndroid Build Coastguard Worker
3315*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
3316*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].dstSet = descriptorSet;
3317*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].dstBinding = kBlitResolveStencilNoExportSamplerBinding;
3318*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].descriptorCount = 1;
3319*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
3320*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].pImageInfo = &samplerInfo;
3321*8975f5c5SAndroid Build Coastguard Worker
3322*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 3, writeInfos, 0, nullptr);
3323*8975f5c5SAndroid Build Coastguard Worker
3324*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr shader;
3325*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getShaderLibrary().getBlitResolveStencilNoExport_comp(contextVk, flags,
3326*8975f5c5SAndroid Build Coastguard Worker &shader));
3327*8975f5c5SAndroid Build Coastguard Worker
3328*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupComputeProgram(contextVk, Function::BlitResolveStencilNoExport, shader,
3329*8975f5c5SAndroid Build Coastguard Worker &mBlitResolveStencilNoExport[flags], descriptorSet, &shaderParams,
3330*8975f5c5SAndroid Build Coastguard Worker sizeof(shaderParams), commandBufferHelper));
3331*8975f5c5SAndroid Build Coastguard Worker commandBuffer->dispatch(UnsignedCeilDivide(bufferRowLengthInUints, 8),
3332*8975f5c5SAndroid Build Coastguard Worker UnsignedCeilDivide(params.blitArea.height, 8), 1);
3333*8975f5c5SAndroid Build Coastguard Worker
3334*8975f5c5SAndroid Build Coastguard Worker // Add a barrier prior to copy.
3335*8975f5c5SAndroid Build Coastguard Worker VkMemoryBarrier memoryBarrier = {};
3336*8975f5c5SAndroid Build Coastguard Worker memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
3337*8975f5c5SAndroid Build Coastguard Worker memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
3338*8975f5c5SAndroid Build Coastguard Worker memoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
3339*8975f5c5SAndroid Build Coastguard Worker
3340*8975f5c5SAndroid Build Coastguard Worker commandBuffer->memoryBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
3341*8975f5c5SAndroid Build Coastguard Worker VK_PIPELINE_STAGE_TRANSFER_BIT, memoryBarrier);
3342*8975f5c5SAndroid Build Coastguard Worker
3343*8975f5c5SAndroid Build Coastguard Worker // Copy the resulting buffer into dst.
3344*8975f5c5SAndroid Build Coastguard Worker VkBufferImageCopy region = {};
3345*8975f5c5SAndroid Build Coastguard Worker region.bufferOffset = blitBuffer.get().getOffset();
3346*8975f5c5SAndroid Build Coastguard Worker region.bufferRowLength = bufferRowLengthInUints * sizeof(uint32_t);
3347*8975f5c5SAndroid Build Coastguard Worker region.bufferImageHeight = params.blitArea.height;
3348*8975f5c5SAndroid Build Coastguard Worker region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
3349*8975f5c5SAndroid Build Coastguard Worker region.imageSubresource.mipLevel =
3350*8975f5c5SAndroid Build Coastguard Worker depthStencilImage->toVkLevel(depthStencilRenderTarget->getLevelIndex()).get();
3351*8975f5c5SAndroid Build Coastguard Worker region.imageSubresource.baseArrayLayer = depthStencilRenderTarget->getLayerIndex();
3352*8975f5c5SAndroid Build Coastguard Worker region.imageSubresource.layerCount = 1;
3353*8975f5c5SAndroid Build Coastguard Worker region.imageOffset.x = params.blitArea.x;
3354*8975f5c5SAndroid Build Coastguard Worker region.imageOffset.y = params.blitArea.y;
3355*8975f5c5SAndroid Build Coastguard Worker region.imageOffset.z = 0;
3356*8975f5c5SAndroid Build Coastguard Worker region.imageExtent.width = params.blitArea.width;
3357*8975f5c5SAndroid Build Coastguard Worker region.imageExtent.height = params.blitArea.height;
3358*8975f5c5SAndroid Build Coastguard Worker region.imageExtent.depth = 1;
3359*8975f5c5SAndroid Build Coastguard Worker
3360*8975f5c5SAndroid Build Coastguard Worker commandBuffer->copyBufferToImage(blitBuffer.get().getBuffer().getHandle(),
3361*8975f5c5SAndroid Build Coastguard Worker depthStencilImage->getImage(),
3362*8975f5c5SAndroid Build Coastguard Worker depthStencilImage->getCurrentLayout(renderer), 1, ®ion);
3363*8975f5c5SAndroid Build Coastguard Worker
3364*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3365*8975f5c5SAndroid Build Coastguard Worker }
3366*8975f5c5SAndroid Build Coastguard Worker
copyImage(ContextVk * contextVk,vk::ImageHelper * dst,const vk::ImageView * destView,vk::ImageHelper * src,const vk::ImageView * srcView,const CopyImageParameters & params)3367*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::copyImage(ContextVk *contextVk,
3368*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *dst,
3369*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *destView,
3370*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *src,
3371*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *srcView,
3372*8975f5c5SAndroid Build Coastguard Worker const CopyImageParameters ¶ms)
3373*8975f5c5SAndroid Build Coastguard Worker {
3374*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
3375*8975f5c5SAndroid Build Coastguard Worker
3376*8975f5c5SAndroid Build Coastguard Worker // The views passed to this function are already retained, so a render pass cannot be already
3377*8975f5c5SAndroid Build Coastguard Worker // open. Otherwise, this function closes the render pass, which may incur a vkQueueSubmit and
3378*8975f5c5SAndroid Build Coastguard Worker // then the views are used in a new command buffer without having been retained for it.
3379*8975f5c5SAndroid Build Coastguard Worker // http://crbug.com/1272266#c22
3380*8975f5c5SAndroid Build Coastguard Worker ASSERT(!contextVk->hasActiveRenderPass());
3381*8975f5c5SAndroid Build Coastguard Worker
3382*8975f5c5SAndroid Build Coastguard Worker const angle::Format &srcIntendedFormat = src->getIntendedFormat();
3383*8975f5c5SAndroid Build Coastguard Worker const angle::Format &dstIntendedFormat = dst->getIntendedFormat();
3384*8975f5c5SAndroid Build Coastguard Worker
3385*8975f5c5SAndroid Build Coastguard Worker const bool isYUV = src->getYcbcrConversionDesc().valid();
3386*8975f5c5SAndroid Build Coastguard Worker const bool isSrcMultisampled = params.srcSampleCount > 1;
3387*8975f5c5SAndroid Build Coastguard Worker
3388*8975f5c5SAndroid Build Coastguard Worker vk::SamplerDesc samplerDesc;
3389*8975f5c5SAndroid Build Coastguard Worker if (isYUV)
3390*8975f5c5SAndroid Build Coastguard Worker {
3391*8975f5c5SAndroid Build Coastguard Worker samplerDesc = vk::SamplerDesc(contextVk, gl::SamplerState(), false,
3392*8975f5c5SAndroid Build Coastguard Worker &src->getYcbcrConversionDesc(), srcIntendedFormat.id);
3393*8975f5c5SAndroid Build Coastguard Worker
3394*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureImageCopyResourcesInitializedWithSampler(contextVk, samplerDesc));
3395*8975f5c5SAndroid Build Coastguard Worker }
3396*8975f5c5SAndroid Build Coastguard Worker else
3397*8975f5c5SAndroid Build Coastguard Worker {
3398*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureImageCopyResourcesInitialized(contextVk));
3399*8975f5c5SAndroid Build Coastguard Worker }
3400*8975f5c5SAndroid Build Coastguard Worker
3401*8975f5c5SAndroid Build Coastguard Worker ImageCopyShaderParams shaderParams;
3402*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipX = 0;
3403*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipY = params.srcFlipY || params.dstFlipY;
3404*8975f5c5SAndroid Build Coastguard Worker shaderParams.premultiplyAlpha = params.srcPremultiplyAlpha;
3405*8975f5c5SAndroid Build Coastguard Worker shaderParams.unmultiplyAlpha = params.srcUnmultiplyAlpha;
3406*8975f5c5SAndroid Build Coastguard Worker shaderParams.dstHasLuminance = dstIntendedFormat.luminanceBits > 0;
3407*8975f5c5SAndroid Build Coastguard Worker shaderParams.dstIsAlpha = dstIntendedFormat.isLUMA() && dstIntendedFormat.alphaBits > 0;
3408*8975f5c5SAndroid Build Coastguard Worker shaderParams.dstDefaultChannelsMask =
3409*8975f5c5SAndroid Build Coastguard Worker GetFormatDefaultChannelMask(dst->getIntendedFormat(), dst->getActualFormat());
3410*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcMip = params.srcMip;
3411*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcLayer = params.srcLayer;
3412*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcSampleCount = params.srcSampleCount;
3413*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset[0] = params.srcOffset[0];
3414*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset[1] = params.srcOffset[1];
3415*8975f5c5SAndroid Build Coastguard Worker shaderParams.dstOffset[0] = params.dstOffset[0];
3416*8975f5c5SAndroid Build Coastguard Worker shaderParams.dstOffset[1] = params.dstOffset[1];
3417*8975f5c5SAndroid Build Coastguard Worker shaderParams.rotateXY = 0;
3418*8975f5c5SAndroid Build Coastguard Worker
3419*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcIsSRGB = params.srcColorEncoding == GL_SRGB;
3420*8975f5c5SAndroid Build Coastguard Worker shaderParams.dstIsSRGB = params.dstColorEncoding == GL_SRGB;
3421*8975f5c5SAndroid Build Coastguard Worker
3422*8975f5c5SAndroid Build Coastguard Worker // If both src and dst are sRGB, and there is no alpha multiplication/division necessary, then
3423*8975f5c5SAndroid Build Coastguard Worker // the shader can work with sRGB data and pretend they are linear.
3424*8975f5c5SAndroid Build Coastguard Worker if (shaderParams.srcIsSRGB && shaderParams.dstIsSRGB && !shaderParams.premultiplyAlpha &&
3425*8975f5c5SAndroid Build Coastguard Worker !shaderParams.unmultiplyAlpha)
3426*8975f5c5SAndroid Build Coastguard Worker {
3427*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcIsSRGB = false;
3428*8975f5c5SAndroid Build Coastguard Worker shaderParams.dstIsSRGB = false;
3429*8975f5c5SAndroid Build Coastguard Worker }
3430*8975f5c5SAndroid Build Coastguard Worker
3431*8975f5c5SAndroid Build Coastguard Worker ASSERT(!(params.srcFlipY && params.dstFlipY));
3432*8975f5c5SAndroid Build Coastguard Worker if (params.srcFlipY)
3433*8975f5c5SAndroid Build Coastguard Worker {
3434*8975f5c5SAndroid Build Coastguard Worker // If viewport is flipped, the shader expects srcOffset[1] to have the
3435*8975f5c5SAndroid Build Coastguard Worker // last row's index instead of the first's.
3436*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset[1] = params.srcHeight - params.srcOffset[1] - 1;
3437*8975f5c5SAndroid Build Coastguard Worker }
3438*8975f5c5SAndroid Build Coastguard Worker else if (params.dstFlipY)
3439*8975f5c5SAndroid Build Coastguard Worker {
3440*8975f5c5SAndroid Build Coastguard Worker // If image is flipped during copy, the shader uses the same code path as above,
3441*8975f5c5SAndroid Build Coastguard Worker // with srcOffset being set to the last row's index instead of the first's.
3442*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset[1] = params.srcOffset[1] + params.srcExtents[1] - 1;
3443*8975f5c5SAndroid Build Coastguard Worker }
3444*8975f5c5SAndroid Build Coastguard Worker
3445*8975f5c5SAndroid Build Coastguard Worker switch (params.srcRotation)
3446*8975f5c5SAndroid Build Coastguard Worker {
3447*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Identity:
3448*8975f5c5SAndroid Build Coastguard Worker break;
3449*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated90Degrees:
3450*8975f5c5SAndroid Build Coastguard Worker shaderParams.rotateXY = 1;
3451*8975f5c5SAndroid Build Coastguard Worker break;
3452*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated180Degrees:
3453*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipX = true;
3454*8975f5c5SAndroid Build Coastguard Worker ASSERT(shaderParams.flipY);
3455*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipY = false;
3456*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset[0] += params.srcExtents[0];
3457*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset[1] -= params.srcExtents[1];
3458*8975f5c5SAndroid Build Coastguard Worker break;
3459*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated270Degrees:
3460*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipX = true;
3461*8975f5c5SAndroid Build Coastguard Worker ASSERT(!shaderParams.flipY);
3462*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipY = true;
3463*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset[0] += params.srcExtents[0];
3464*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset[1] += params.srcExtents[1];
3465*8975f5c5SAndroid Build Coastguard Worker shaderParams.rotateXY = 1;
3466*8975f5c5SAndroid Build Coastguard Worker break;
3467*8975f5c5SAndroid Build Coastguard Worker default:
3468*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
3469*8975f5c5SAndroid Build Coastguard Worker break;
3470*8975f5c5SAndroid Build Coastguard Worker }
3471*8975f5c5SAndroid Build Coastguard Worker
3472*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassDesc renderPassDesc;
3473*8975f5c5SAndroid Build Coastguard Worker renderPassDesc.setSamples(dst->getSamples());
3474*8975f5c5SAndroid Build Coastguard Worker renderPassDesc.packColorAttachment(0, dst->getActualFormatID());
3475*8975f5c5SAndroid Build Coastguard Worker
3476*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineDesc pipelineDesc;
3477*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.initDefaults(contextVk, vk::GraphicsPipelineSubset::Complete,
3478*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineRobustness(),
3479*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineProtectedAccess());
3480*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRenderPassDesc(renderPassDesc);
3481*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRasterizationSamples(dst->getSamples());
3482*8975f5c5SAndroid Build Coastguard Worker
3483*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle renderArea;
3484*8975f5c5SAndroid Build Coastguard Worker renderArea.x = params.dstOffset[0];
3485*8975f5c5SAndroid Build Coastguard Worker renderArea.y = params.dstOffset[1];
3486*8975f5c5SAndroid Build Coastguard Worker renderArea.width = params.srcExtents[0];
3487*8975f5c5SAndroid Build Coastguard Worker renderArea.height = params.srcExtents[1];
3488*8975f5c5SAndroid Build Coastguard Worker if ((params.srcRotation == SurfaceRotation::Rotated90Degrees) ||
3489*8975f5c5SAndroid Build Coastguard Worker (params.srcRotation == SurfaceRotation::Rotated270Degrees))
3490*8975f5c5SAndroid Build Coastguard Worker {
3491*8975f5c5SAndroid Build Coastguard Worker // The surface is rotated 90/270 degrees. This changes the aspect ratio of the surface.
3492*8975f5c5SAndroid Build Coastguard Worker std::swap(renderArea.width, renderArea.height);
3493*8975f5c5SAndroid Build Coastguard Worker }
3494*8975f5c5SAndroid Build Coastguard Worker
3495*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer;
3496*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(startRenderPass(contextVk, dst, destView, renderPassDesc, renderArea,
3497*8975f5c5SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_COLOR_BIT, nullptr,
3498*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassSource::InternalUtils, &commandBuffer));
3499*8975f5c5SAndroid Build Coastguard Worker
3500*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
3501*8975f5c5SAndroid Build Coastguard Worker if (isYUV)
3502*8975f5c5SAndroid Build Coastguard Worker {
3503*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSetForImageCopyWithSampler(
3504*8975f5c5SAndroid Build Coastguard Worker contextVk, &contextVk->getStartedRenderPassCommands(), samplerDesc, &descriptorSet));
3505*8975f5c5SAndroid Build Coastguard Worker }
3506*8975f5c5SAndroid Build Coastguard Worker else
3507*8975f5c5SAndroid Build Coastguard Worker {
3508*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, &contextVk->getStartedRenderPassCommands(),
3509*8975f5c5SAndroid Build Coastguard Worker Function::ImageCopy, &descriptorSet));
3510*8975f5c5SAndroid Build Coastguard Worker }
3511*8975f5c5SAndroid Build Coastguard Worker
3512*8975f5c5SAndroid Build Coastguard Worker UpdateColorAccess(contextVk, MakeColorBufferMask(0), MakeColorBufferMask(0));
3513*8975f5c5SAndroid Build Coastguard Worker
3514*8975f5c5SAndroid Build Coastguard Worker // Change source layout inside render pass.
3515*8975f5c5SAndroid Build Coastguard Worker contextVk->onImageRenderPassRead(VK_IMAGE_ASPECT_COLOR_BIT,
3516*8975f5c5SAndroid Build Coastguard Worker vk::ImageLayout::FragmentShaderReadOnly, src);
3517*8975f5c5SAndroid Build Coastguard Worker contextVk->onImageRenderPassWrite(params.dstMip, params.dstLayer, 1, VK_IMAGE_ASPECT_COLOR_BIT,
3518*8975f5c5SAndroid Build Coastguard Worker vk::ImageLayout::ColorWrite, dst);
3519*8975f5c5SAndroid Build Coastguard Worker
3520*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo imageInfo = {};
3521*8975f5c5SAndroid Build Coastguard Worker imageInfo.imageView = srcView->getHandle();
3522*8975f5c5SAndroid Build Coastguard Worker imageInfo.imageLayout = src->getCurrentLayout(renderer);
3523*8975f5c5SAndroid Build Coastguard Worker
3524*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfo = {};
3525*8975f5c5SAndroid Build Coastguard Worker writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
3526*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstSet = descriptorSet;
3527*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstBinding = kImageCopySourceBinding;
3528*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorCount = 1;
3529*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorType =
3530*8975f5c5SAndroid Build Coastguard Worker isYUV ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
3531*8975f5c5SAndroid Build Coastguard Worker writeInfo.pImageInfo = &imageInfo;
3532*8975f5c5SAndroid Build Coastguard Worker
3533*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 1, &writeInfo, 0, nullptr);
3534*8975f5c5SAndroid Build Coastguard Worker
3535*8975f5c5SAndroid Build Coastguard Worker vk::ShaderLibrary &shaderLibrary = contextVk->getShaderLibrary();
3536*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr vertexShader;
3537*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr fragmentShader;
3538*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getFullScreenTri_vert(contextVk, 0, &vertexShader));
3539*8975f5c5SAndroid Build Coastguard Worker
3540*8975f5c5SAndroid Build Coastguard Worker if (isYUV)
3541*8975f5c5SAndroid Build Coastguard Worker {
3542*8975f5c5SAndroid Build Coastguard Worker ASSERT(src->getType() == VK_IMAGE_TYPE_2D);
3543*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getImageCopyFloat_frag(contextVk, ImageCopyFloat_frag::kSrcIsYUV,
3544*8975f5c5SAndroid Build Coastguard Worker &fragmentShader));
3545*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupGraphicsProgramWithLayout(
3546*8975f5c5SAndroid Build Coastguard Worker contextVk, *mImageCopyWithSamplerPipelineLayouts[samplerDesc], vertexShader,
3547*8975f5c5SAndroid Build Coastguard Worker fragmentShader, &mImageCopyWithSampler[samplerDesc], &pipelineDesc, descriptorSet,
3548*8975f5c5SAndroid Build Coastguard Worker &shaderParams, sizeof(shaderParams), commandBuffer));
3549*8975f5c5SAndroid Build Coastguard Worker }
3550*8975f5c5SAndroid Build Coastguard Worker else if (isSrcMultisampled)
3551*8975f5c5SAndroid Build Coastguard Worker {
3552*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getImageCopyFloat_frag(contextVk, ImageCopyFloat_frag::kSrcIs2DMS,
3553*8975f5c5SAndroid Build Coastguard Worker &fragmentShader));
3554*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupGraphicsProgram(contextVk, Function::ImageCopy, vertexShader, fragmentShader,
3555*8975f5c5SAndroid Build Coastguard Worker &mImageCopyFloat, &pipelineDesc, descriptorSet,
3556*8975f5c5SAndroid Build Coastguard Worker &shaderParams, sizeof(shaderParams), commandBuffer));
3557*8975f5c5SAndroid Build Coastguard Worker }
3558*8975f5c5SAndroid Build Coastguard Worker else
3559*8975f5c5SAndroid Build Coastguard Worker {
3560*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = GetImageCopyFlags(srcIntendedFormat, dstIntendedFormat);
3561*8975f5c5SAndroid Build Coastguard Worker if (src->getType() == VK_IMAGE_TYPE_3D)
3562*8975f5c5SAndroid Build Coastguard Worker {
3563*8975f5c5SAndroid Build Coastguard Worker flags |= ImageCopy_frag::kSrcIs3D;
3564*8975f5c5SAndroid Build Coastguard Worker }
3565*8975f5c5SAndroid Build Coastguard Worker else if (src->getLayerCount() > 1)
3566*8975f5c5SAndroid Build Coastguard Worker {
3567*8975f5c5SAndroid Build Coastguard Worker flags |= ImageCopy_frag::kSrcIs2DArray;
3568*8975f5c5SAndroid Build Coastguard Worker }
3569*8975f5c5SAndroid Build Coastguard Worker else
3570*8975f5c5SAndroid Build Coastguard Worker {
3571*8975f5c5SAndroid Build Coastguard Worker ASSERT(src->getType() == VK_IMAGE_TYPE_2D);
3572*8975f5c5SAndroid Build Coastguard Worker flags |= ImageCopy_frag::kSrcIs2D;
3573*8975f5c5SAndroid Build Coastguard Worker }
3574*8975f5c5SAndroid Build Coastguard Worker
3575*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getImageCopy_frag(contextVk, flags, &fragmentShader));
3576*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupGraphicsProgram(contextVk, Function::ImageCopy, vertexShader, fragmentShader,
3577*8975f5c5SAndroid Build Coastguard Worker &mImageCopy[flags], &pipelineDesc, descriptorSet,
3578*8975f5c5SAndroid Build Coastguard Worker &shaderParams, sizeof(shaderParams), commandBuffer));
3579*8975f5c5SAndroid Build Coastguard Worker }
3580*8975f5c5SAndroid Build Coastguard Worker
3581*8975f5c5SAndroid Build Coastguard Worker // Set dynamic state
3582*8975f5c5SAndroid Build Coastguard Worker VkViewport viewport;
3583*8975f5c5SAndroid Build Coastguard Worker gl_vk::GetViewport(renderArea, 0.0f, 1.0f, false, false, dst->getExtents().height, &viewport);
3584*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setViewport(0, 1, &viewport);
3585*8975f5c5SAndroid Build Coastguard Worker
3586*8975f5c5SAndroid Build Coastguard Worker VkRect2D scissor = gl_vk::GetRect(renderArea);
3587*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setScissor(0, 1, &scissor);
3588*8975f5c5SAndroid Build Coastguard Worker
3589*8975f5c5SAndroid Build Coastguard Worker SetDepthDynamicStateForUnused(renderer, commandBuffer);
3590*8975f5c5SAndroid Build Coastguard Worker SetStencilDynamicStateForUnused(renderer, commandBuffer);
3591*8975f5c5SAndroid Build Coastguard Worker
3592*8975f5c5SAndroid Build Coastguard Worker // Note: this utility creates its own framebuffer, thus bypassing ContextVk::startRenderPass.
3593*8975f5c5SAndroid Build Coastguard Worker // As such, occlusion queries are not enabled.
3594*8975f5c5SAndroid Build Coastguard Worker commandBuffer->draw(3, 0);
3595*8975f5c5SAndroid Build Coastguard Worker
3596*8975f5c5SAndroid Build Coastguard Worker // Close the render pass for this temporary framebuffer.
3597*8975f5c5SAndroid Build Coastguard Worker return contextVk->flushCommandsAndEndRenderPass(RenderPassClosureReason::TemporaryForImageCopy);
3598*8975f5c5SAndroid Build Coastguard Worker }
3599*8975f5c5SAndroid Build Coastguard Worker
copyImageBits(ContextVk * contextVk,vk::ImageHelper * dst,vk::ImageHelper * src,const CopyImageBitsParameters & params)3600*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::copyImageBits(ContextVk *contextVk,
3601*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *dst,
3602*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *src,
3603*8975f5c5SAndroid Build Coastguard Worker const CopyImageBitsParameters ¶ms)
3604*8975f5c5SAndroid Build Coastguard Worker {
3605*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
3606*8975f5c5SAndroid Build Coastguard Worker
3607*8975f5c5SAndroid Build Coastguard Worker // This function is used to copy the bit representation of an image to another, and is used to
3608*8975f5c5SAndroid Build Coastguard Worker // support EXT_copy_image when a format is emulated. Currently, only RGB->RGBA emulation is
3609*8975f5c5SAndroid Build Coastguard Worker // possible, and so this function is tailored to this specific kind of emulation.
3610*8975f5c5SAndroid Build Coastguard Worker //
3611*8975f5c5SAndroid Build Coastguard Worker // The copy can be done with various degrees of efficiency:
3612*8975f5c5SAndroid Build Coastguard Worker //
3613*8975f5c5SAndroid Build Coastguard Worker // - If the UINT reinterpretation format for src supports SAMPLED usage, texels can be read
3614*8975f5c5SAndroid Build Coastguard Worker // directly from that. Otherwise vkCmdCopyImageToBuffer can be used and data then read from
3615*8975f5c5SAndroid Build Coastguard Worker // the buffer.
3616*8975f5c5SAndroid Build Coastguard Worker // - If the UINT reinterpretation format for dst supports STORAGE usage, texels can be written
3617*8975f5c5SAndroid Build Coastguard Worker // directly to that. Otherwise conversion can be done to a buffer and then
3618*8975f5c5SAndroid Build Coastguard Worker // vkCmdCopyBufferToImage used.
3619*8975f5c5SAndroid Build Coastguard Worker //
3620*8975f5c5SAndroid Build Coastguard Worker // This requires four different shaders. For simplicity, this function unconditionally copies
3621*8975f5c5SAndroid Build Coastguard Worker // src to a temp buffer, transforms to another temp buffer and copies to the dst. No known
3622*8975f5c5SAndroid Build Coastguard Worker // applications use EXT_copy_image on RGB formats, so no further optimization is currently
3623*8975f5c5SAndroid Build Coastguard Worker // necessary.
3624*8975f5c5SAndroid Build Coastguard Worker //
3625*8975f5c5SAndroid Build Coastguard Worker // The conversion between buffers can be done with ConvertVertex.comp in UintToUint mode, so no
3626*8975f5c5SAndroid Build Coastguard Worker // new shader is necessary. The srcEmulatedAlpha parameter is used to make sure the destination
3627*8975f5c5SAndroid Build Coastguard Worker // alpha value is correct, if dst is RGBA.
3628*8975f5c5SAndroid Build Coastguard Worker
3629*8975f5c5SAndroid Build Coastguard Worker // This path should only be necessary for when RGBA is used as fallback for RGB. No other
3630*8975f5c5SAndroid Build Coastguard Worker // format which can be used with EXT_copy_image has a fallback.
3631*8975f5c5SAndroid Build Coastguard Worker ASSERT(src->getIntendedFormat().blueBits > 0 && src->getIntendedFormat().alphaBits == 0);
3632*8975f5c5SAndroid Build Coastguard Worker ASSERT(dst->getIntendedFormat().blueBits > 0 && dst->getIntendedFormat().alphaBits == 0);
3633*8975f5c5SAndroid Build Coastguard Worker
3634*8975f5c5SAndroid Build Coastguard Worker const angle::Format &srcImageFormat = src->getActualFormat();
3635*8975f5c5SAndroid Build Coastguard Worker const angle::Format &dstImageFormat = dst->getActualFormat();
3636*8975f5c5SAndroid Build Coastguard Worker
3637*8975f5c5SAndroid Build Coastguard Worker // Create temporary buffers.
3638*8975f5c5SAndroid Build Coastguard Worker vk::RendererScoped<vk::BufferHelper> srcBuffer(renderer);
3639*8975f5c5SAndroid Build Coastguard Worker vk::RendererScoped<vk::BufferHelper> dstBuffer(renderer);
3640*8975f5c5SAndroid Build Coastguard Worker
3641*8975f5c5SAndroid Build Coastguard Worker const uint32_t srcPixelBytes = srcImageFormat.pixelBytes;
3642*8975f5c5SAndroid Build Coastguard Worker const uint32_t dstPixelBytes = dstImageFormat.pixelBytes;
3643*8975f5c5SAndroid Build Coastguard Worker
3644*8975f5c5SAndroid Build Coastguard Worker const uint32_t totalPixelCount =
3645*8975f5c5SAndroid Build Coastguard Worker params.copyExtents[0] * params.copyExtents[1] * params.copyExtents[2];
3646*8975f5c5SAndroid Build Coastguard Worker // Note that buffer sizes are rounded up a multiple of uint size, as that the granularity in
3647*8975f5c5SAndroid Build Coastguard Worker // which the compute shader accesses these buffers.
3648*8975f5c5SAndroid Build Coastguard Worker const VkDeviceSize srcBufferSize =
3649*8975f5c5SAndroid Build Coastguard Worker roundUpPow2<uint32_t>(srcPixelBytes * totalPixelCount, sizeof(uint32_t));
3650*8975f5c5SAndroid Build Coastguard Worker const VkDeviceSize dstBufferSize =
3651*8975f5c5SAndroid Build Coastguard Worker roundUpPow2<uint32_t>(dstPixelBytes * totalPixelCount, sizeof(uint32_t));
3652*8975f5c5SAndroid Build Coastguard Worker
3653*8975f5c5SAndroid Build Coastguard Worker VkBufferCreateInfo bufferInfo = {};
3654*8975f5c5SAndroid Build Coastguard Worker bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
3655*8975f5c5SAndroid Build Coastguard Worker bufferInfo.flags = 0;
3656*8975f5c5SAndroid Build Coastguard Worker bufferInfo.size = srcBufferSize;
3657*8975f5c5SAndroid Build Coastguard Worker bufferInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3658*8975f5c5SAndroid Build Coastguard Worker bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3659*8975f5c5SAndroid Build Coastguard Worker bufferInfo.queueFamilyIndexCount = 0;
3660*8975f5c5SAndroid Build Coastguard Worker bufferInfo.pQueueFamilyIndices = nullptr;
3661*8975f5c5SAndroid Build Coastguard Worker
3662*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(srcBuffer.get().init(contextVk, bufferInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
3663*8975f5c5SAndroid Build Coastguard Worker
3664*8975f5c5SAndroid Build Coastguard Worker bufferInfo.size = dstBufferSize;
3665*8975f5c5SAndroid Build Coastguard Worker bufferInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
3666*8975f5c5SAndroid Build Coastguard Worker
3667*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(dstBuffer.get().init(contextVk, bufferInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
3668*8975f5c5SAndroid Build Coastguard Worker
3669*8975f5c5SAndroid Build Coastguard Worker bool isSrc3D = src->getType() == VK_IMAGE_TYPE_3D;
3670*8975f5c5SAndroid Build Coastguard Worker bool isDst3D = dst->getType() == VK_IMAGE_TYPE_3D;
3671*8975f5c5SAndroid Build Coastguard Worker
3672*8975f5c5SAndroid Build Coastguard Worker // Change layouts prior to computation.
3673*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access;
3674*8975f5c5SAndroid Build Coastguard Worker access.onImageTransferRead(src->getAspectFlags(), src);
3675*8975f5c5SAndroid Build Coastguard Worker access.onImageTransferWrite(params.dstLevel, 1, isDst3D ? 0 : params.dstOffset[2],
3676*8975f5c5SAndroid Build Coastguard Worker isDst3D ? 1 : params.copyExtents[2], VK_IMAGE_ASPECT_COLOR_BIT,
3677*8975f5c5SAndroid Build Coastguard Worker dst);
3678*8975f5c5SAndroid Build Coastguard Worker
3679*8975f5c5SAndroid Build Coastguard Worker // srcBuffer is the destination of copyImageToBuffer() below.
3680*8975f5c5SAndroid Build Coastguard Worker access.onBufferTransferWrite(&srcBuffer.get());
3681*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(&dstBuffer.get());
3682*8975f5c5SAndroid Build Coastguard Worker
3683*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
3684*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
3685*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper(access, &commandBufferHelper));
3686*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &commandBufferHelper->getCommandBuffer();
3687*8975f5c5SAndroid Build Coastguard Worker
3688*8975f5c5SAndroid Build Coastguard Worker // Copy src into buffer, completely packed.
3689*8975f5c5SAndroid Build Coastguard Worker VkBufferImageCopy srcRegion = {};
3690*8975f5c5SAndroid Build Coastguard Worker srcRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3691*8975f5c5SAndroid Build Coastguard Worker srcRegion.imageSubresource.mipLevel = src->toVkLevel(params.srcLevel).get();
3692*8975f5c5SAndroid Build Coastguard Worker srcRegion.imageSubresource.baseArrayLayer = isSrc3D ? 0 : params.srcOffset[2];
3693*8975f5c5SAndroid Build Coastguard Worker srcRegion.imageSubresource.layerCount = isSrc3D ? 1 : params.copyExtents[2];
3694*8975f5c5SAndroid Build Coastguard Worker srcRegion.imageOffset.x = params.srcOffset[0];
3695*8975f5c5SAndroid Build Coastguard Worker srcRegion.imageOffset.y = params.srcOffset[1];
3696*8975f5c5SAndroid Build Coastguard Worker srcRegion.imageOffset.z = isSrc3D ? params.srcOffset[2] : 0;
3697*8975f5c5SAndroid Build Coastguard Worker srcRegion.imageExtent.width = params.copyExtents[0];
3698*8975f5c5SAndroid Build Coastguard Worker srcRegion.imageExtent.height = params.copyExtents[1];
3699*8975f5c5SAndroid Build Coastguard Worker srcRegion.imageExtent.depth = isSrc3D ? params.copyExtents[2] : 1;
3700*8975f5c5SAndroid Build Coastguard Worker
3701*8975f5c5SAndroid Build Coastguard Worker commandBuffer->copyImageToBuffer(src->getImage(), src->getCurrentLayout(renderer),
3702*8975f5c5SAndroid Build Coastguard Worker srcBuffer.get().getBuffer().getHandle(), 1, &srcRegion);
3703*8975f5c5SAndroid Build Coastguard Worker
3704*8975f5c5SAndroid Build Coastguard Worker // Add a barrier prior to dispatch call.
3705*8975f5c5SAndroid Build Coastguard Worker VkMemoryBarrier memoryBarrier = {};
3706*8975f5c5SAndroid Build Coastguard Worker memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
3707*8975f5c5SAndroid Build Coastguard Worker memoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3708*8975f5c5SAndroid Build Coastguard Worker memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
3709*8975f5c5SAndroid Build Coastguard Worker
3710*8975f5c5SAndroid Build Coastguard Worker commandBuffer->memoryBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
3711*8975f5c5SAndroid Build Coastguard Worker VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, memoryBarrier);
3712*8975f5c5SAndroid Build Coastguard Worker
3713*8975f5c5SAndroid Build Coastguard Worker // Set up ConvertVertex shader to convert between the formats. Only the following three cases
3714*8975f5c5SAndroid Build Coastguard Worker // are possible:
3715*8975f5c5SAndroid Build Coastguard Worker //
3716*8975f5c5SAndroid Build Coastguard Worker // - RGB -> RGBA: Ns = 3, Ss = src.pixelBytes,
3717*8975f5c5SAndroid Build Coastguard Worker // Nd = 4, Sd = dst.pixelBytes, use srcEmulatedAlpha
3718*8975f5c5SAndroid Build Coastguard Worker //
3719*8975f5c5SAndroid Build Coastguard Worker // - RGBA -> RGBA: Ns = 3, Ss = src.pixelBytes,
3720*8975f5c5SAndroid Build Coastguard Worker // Nd = 4, Sd = dst.pixelBytes, use srcEmulatedAlpha
3721*8975f5c5SAndroid Build Coastguard Worker //
3722*8975f5c5SAndroid Build Coastguard Worker // - RGBA -> RGB: Ns = 3, Ss = src.pixelBytes,
3723*8975f5c5SAndroid Build Coastguard Worker // Nd = 3, Sd = dst.pixelBytes
3724*8975f5c5SAndroid Build Coastguard Worker //
3725*8975f5c5SAndroid Build Coastguard Worker // The trick here is with RGBA -> RGBA, where Ns is specified as 3, so that the emulated alpha
3726*8975f5c5SAndroid Build Coastguard Worker // from source is not taken (as uint), but rather one is provided such that the destination
3727*8975f5c5SAndroid Build Coastguard Worker // alpha would contain the correct emulated alpha.
3728*8975f5c5SAndroid Build Coastguard Worker //
3729*8975f5c5SAndroid Build Coastguard Worker ConvertVertexShaderParams shaderParams;
3730*8975f5c5SAndroid Build Coastguard Worker shaderParams.Ns = 3;
3731*8975f5c5SAndroid Build Coastguard Worker shaderParams.Bs = srcImageFormat.pixelBytes / srcImageFormat.channelCount;
3732*8975f5c5SAndroid Build Coastguard Worker shaderParams.Ss = srcImageFormat.pixelBytes;
3733*8975f5c5SAndroid Build Coastguard Worker shaderParams.Nd = dstImageFormat.channelCount;
3734*8975f5c5SAndroid Build Coastguard Worker shaderParams.Bd = dstImageFormat.pixelBytes / dstImageFormat.channelCount;
3735*8975f5c5SAndroid Build Coastguard Worker shaderParams.Sd = shaderParams.Nd * shaderParams.Bd;
3736*8975f5c5SAndroid Build Coastguard Worker // The component size is expected to either be 1, 2 or 4 bytes.
3737*8975f5c5SAndroid Build Coastguard Worker ASSERT(4 % shaderParams.Bs == 0);
3738*8975f5c5SAndroid Build Coastguard Worker ASSERT(4 % shaderParams.Bd == 0);
3739*8975f5c5SAndroid Build Coastguard Worker shaderParams.Es = 4 / shaderParams.Bs;
3740*8975f5c5SAndroid Build Coastguard Worker shaderParams.Ed = 4 / shaderParams.Bd;
3741*8975f5c5SAndroid Build Coastguard Worker // Total number of output components is simply the number of pixels by number of components in
3742*8975f5c5SAndroid Build Coastguard Worker // each.
3743*8975f5c5SAndroid Build Coastguard Worker shaderParams.componentCount = totalPixelCount * shaderParams.Nd;
3744*8975f5c5SAndroid Build Coastguard Worker // Total number of 4-byte outputs is the number of components divided by how many components can
3745*8975f5c5SAndroid Build Coastguard Worker // fit in a 4-byte value. Note that this value is also the invocation size of the shader.
3746*8975f5c5SAndroid Build Coastguard Worker shaderParams.outputCount = UnsignedCeilDivide(shaderParams.componentCount, shaderParams.Ed);
3747*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset = 0;
3748*8975f5c5SAndroid Build Coastguard Worker shaderParams.dstOffset = 0;
3749*8975f5c5SAndroid Build Coastguard Worker shaderParams.isSrcHDR = 0;
3750*8975f5c5SAndroid Build Coastguard Worker shaderParams.isSrcA2BGR10 = 0;
3751*8975f5c5SAndroid Build Coastguard Worker
3752*8975f5c5SAndroid Build Coastguard Worker // Due to the requirements of EXT_copy_image, the channel size of src and dst must be
3753*8975f5c5SAndroid Build Coastguard Worker // identical. Usage of srcEmulatedAlpha relies on this as it's used to output an alpha value in
3754*8975f5c5SAndroid Build Coastguard Worker // dst through the source.
3755*8975f5c5SAndroid Build Coastguard Worker ASSERT(shaderParams.Bs == shaderParams.Bd);
3756*8975f5c5SAndroid Build Coastguard Worker
3757*8975f5c5SAndroid Build Coastguard Worker // The following RGB formats are allowed in EXT_copy_image:
3758*8975f5c5SAndroid Build Coastguard Worker //
3759*8975f5c5SAndroid Build Coastguard Worker // - RGB32F, RGB32UI, RGB32I
3760*8975f5c5SAndroid Build Coastguard Worker // - RGB16F, RGB16UI, RGB16I
3761*8975f5c5SAndroid Build Coastguard Worker // - RGB8, RGB8_SNORM, SRGB8, RGB8UI, RGB8I
3762*8975f5c5SAndroid Build Coastguard Worker //
3763*8975f5c5SAndroid Build Coastguard Worker // The value of emulated alpha is:
3764*8975f5c5SAndroid Build Coastguard Worker //
3765*8975f5c5SAndroid Build Coastguard Worker // - 1 for all RGB*I and RGB*UI formats
3766*8975f5c5SAndroid Build Coastguard Worker // - bit representation of 1.0f for RGB32F
3767*8975f5c5SAndroid Build Coastguard Worker // - bit representation of half-float 1.0f for RGB16F
3768*8975f5c5SAndroid Build Coastguard Worker // - 0xFF for RGB8 and SRGB8
3769*8975f5c5SAndroid Build Coastguard Worker // - 0x7F for RGB8_SNORM
3770*8975f5c5SAndroid Build Coastguard Worker if (dstImageFormat.isInt())
3771*8975f5c5SAndroid Build Coastguard Worker {
3772*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = 1;
3773*8975f5c5SAndroid Build Coastguard Worker }
3774*8975f5c5SAndroid Build Coastguard Worker else if (dstImageFormat.isUnorm())
3775*8975f5c5SAndroid Build Coastguard Worker {
3776*8975f5c5SAndroid Build Coastguard Worker ASSERT(shaderParams.Bd == 1);
3777*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = 0xFF;
3778*8975f5c5SAndroid Build Coastguard Worker }
3779*8975f5c5SAndroid Build Coastguard Worker else if (dstImageFormat.isSnorm())
3780*8975f5c5SAndroid Build Coastguard Worker {
3781*8975f5c5SAndroid Build Coastguard Worker ASSERT(shaderParams.Bd == 1);
3782*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = 0x7F;
3783*8975f5c5SAndroid Build Coastguard Worker }
3784*8975f5c5SAndroid Build Coastguard Worker else if (shaderParams.Bd == 2)
3785*8975f5c5SAndroid Build Coastguard Worker {
3786*8975f5c5SAndroid Build Coastguard Worker ASSERT(dstImageFormat.isFloat());
3787*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = gl::Float16One;
3788*8975f5c5SAndroid Build Coastguard Worker }
3789*8975f5c5SAndroid Build Coastguard Worker else if (shaderParams.Bd == 4)
3790*8975f5c5SAndroid Build Coastguard Worker {
3791*8975f5c5SAndroid Build Coastguard Worker ASSERT(dstImageFormat.isFloat());
3792*8975f5c5SAndroid Build Coastguard Worker ASSERT(ValidateFloatOneAsUint());
3793*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = gl::Float32One;
3794*8975f5c5SAndroid Build Coastguard Worker }
3795*8975f5c5SAndroid Build Coastguard Worker else
3796*8975f5c5SAndroid Build Coastguard Worker {
3797*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
3798*8975f5c5SAndroid Build Coastguard Worker }
3799*8975f5c5SAndroid Build Coastguard Worker
3800*8975f5c5SAndroid Build Coastguard Worker // Use UintToUint conversion to preserve the bit pattern during transfer.
3801*8975f5c5SAndroid Build Coastguard Worker const uint32_t flags = ConvertVertex_comp::kUintToUint;
3802*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(convertVertexBufferImpl(contextVk, &dstBuffer.get(), &srcBuffer.get(), flags,
3803*8975f5c5SAndroid Build Coastguard Worker commandBufferHelper, shaderParams, {}));
3804*8975f5c5SAndroid Build Coastguard Worker
3805*8975f5c5SAndroid Build Coastguard Worker // Add a barrier prior to copy.
3806*8975f5c5SAndroid Build Coastguard Worker memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
3807*8975f5c5SAndroid Build Coastguard Worker memoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
3808*8975f5c5SAndroid Build Coastguard Worker
3809*8975f5c5SAndroid Build Coastguard Worker commandBuffer->memoryBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
3810*8975f5c5SAndroid Build Coastguard Worker VK_PIPELINE_STAGE_TRANSFER_BIT, memoryBarrier);
3811*8975f5c5SAndroid Build Coastguard Worker
3812*8975f5c5SAndroid Build Coastguard Worker // Copy buffer into dst. It's completely packed.
3813*8975f5c5SAndroid Build Coastguard Worker VkBufferImageCopy dstRegion = {};
3814*8975f5c5SAndroid Build Coastguard Worker dstRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3815*8975f5c5SAndroid Build Coastguard Worker dstRegion.imageSubresource.mipLevel = dst->toVkLevel(params.dstLevel).get();
3816*8975f5c5SAndroid Build Coastguard Worker dstRegion.imageSubresource.baseArrayLayer = isDst3D ? 0 : params.dstOffset[2];
3817*8975f5c5SAndroid Build Coastguard Worker dstRegion.imageSubresource.layerCount = isDst3D ? 1 : params.copyExtents[2];
3818*8975f5c5SAndroid Build Coastguard Worker dstRegion.imageOffset.x = params.dstOffset[0];
3819*8975f5c5SAndroid Build Coastguard Worker dstRegion.imageOffset.y = params.dstOffset[1];
3820*8975f5c5SAndroid Build Coastguard Worker dstRegion.imageOffset.z = isDst3D ? params.dstOffset[2] : 0;
3821*8975f5c5SAndroid Build Coastguard Worker dstRegion.imageExtent.width = params.copyExtents[0];
3822*8975f5c5SAndroid Build Coastguard Worker dstRegion.imageExtent.height = params.copyExtents[1];
3823*8975f5c5SAndroid Build Coastguard Worker dstRegion.imageExtent.depth = isDst3D ? params.copyExtents[2] : 1;
3824*8975f5c5SAndroid Build Coastguard Worker
3825*8975f5c5SAndroid Build Coastguard Worker commandBuffer->copyBufferToImage(dstBuffer.get().getBuffer().getHandle(), dst->getImage(),
3826*8975f5c5SAndroid Build Coastguard Worker dst->getCurrentLayout(renderer), 1, &dstRegion);
3827*8975f5c5SAndroid Build Coastguard Worker
3828*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3829*8975f5c5SAndroid Build Coastguard Worker }
3830*8975f5c5SAndroid Build Coastguard Worker
copyImageToBuffer(ContextVk * contextVk,vk::BufferHelper * dst,vk::ImageHelper * src,const CopyImageToBufferParameters & params)3831*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::copyImageToBuffer(ContextVk *contextVk,
3832*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dst,
3833*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *src,
3834*8975f5c5SAndroid Build Coastguard Worker const CopyImageToBufferParameters ¶ms)
3835*8975f5c5SAndroid Build Coastguard Worker {
3836*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
3837*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureCopyImageToBufferResourcesInitialized(contextVk));
3838*8975f5c5SAndroid Build Coastguard Worker
3839*8975f5c5SAndroid Build Coastguard Worker const angle::Format &srcFormat = src->getActualFormat();
3840*8975f5c5SAndroid Build Coastguard Worker
3841*8975f5c5SAndroid Build Coastguard Worker ASSERT(params.outputOffset % sizeof(uint32_t) == 0);
3842*8975f5c5SAndroid Build Coastguard Worker ASSERT(params.outputPitch % sizeof(uint32_t) == 0);
3843*8975f5c5SAndroid Build Coastguard Worker
3844*8975f5c5SAndroid Build Coastguard Worker CopyImageToBufferShaderParams shaderParams;
3845*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset[0] = params.srcOffset[0];
3846*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset[1] = params.srcOffset[1];
3847*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcDepth = params.srcLayer;
3848*8975f5c5SAndroid Build Coastguard Worker shaderParams.reverseRowOrder = params.reverseRowOrder;
3849*8975f5c5SAndroid Build Coastguard Worker shaderParams.size[0] = params.size[0];
3850*8975f5c5SAndroid Build Coastguard Worker shaderParams.size[1] = params.size[1];
3851*8975f5c5SAndroid Build Coastguard Worker shaderParams.outputOffset = static_cast<uint32_t>(params.outputOffset / sizeof(uint32_t));
3852*8975f5c5SAndroid Build Coastguard Worker shaderParams.outputPitch = params.outputPitch / sizeof(uint32_t);
3853*8975f5c5SAndroid Build Coastguard Worker shaderParams.isDstSnorm = params.outputFormat->isSnorm();
3854*8975f5c5SAndroid Build Coastguard Worker
3855*8975f5c5SAndroid Build Coastguard Worker gl::SwizzleState swizzle;
3856*8975f5c5SAndroid Build Coastguard Worker if (params.outputFormat->isBGRA())
3857*8975f5c5SAndroid Build Coastguard Worker {
3858*8975f5c5SAndroid Build Coastguard Worker swizzle.swizzleRed = GL_BLUE;
3859*8975f5c5SAndroid Build Coastguard Worker swizzle.swizzleBlue = GL_RED;
3860*8975f5c5SAndroid Build Coastguard Worker }
3861*8975f5c5SAndroid Build Coastguard Worker
3862*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = GetCopyImageToBufferFlags(srcFormat);
3863*8975f5c5SAndroid Build Coastguard Worker gl::TextureType textureType;
3864*8975f5c5SAndroid Build Coastguard Worker if (src->getType() == VK_IMAGE_TYPE_3D)
3865*8975f5c5SAndroid Build Coastguard Worker {
3866*8975f5c5SAndroid Build Coastguard Worker flags |= CopyImageToBuffer_comp::kSrcIs3D;
3867*8975f5c5SAndroid Build Coastguard Worker textureType = gl::TextureType::_3D;
3868*8975f5c5SAndroid Build Coastguard Worker }
3869*8975f5c5SAndroid Build Coastguard Worker else
3870*8975f5c5SAndroid Build Coastguard Worker {
3871*8975f5c5SAndroid Build Coastguard Worker flags |= CopyImageToBuffer_comp::kSrcIs2D;
3872*8975f5c5SAndroid Build Coastguard Worker textureType = gl::TextureType::_2D;
3873*8975f5c5SAndroid Build Coastguard Worker }
3874*8975f5c5SAndroid Build Coastguard Worker
3875*8975f5c5SAndroid Build Coastguard Worker // Don't decode to linear colorspace when copying an image
3876*8975f5c5SAndroid Build Coastguard Worker angle::FormatID imageFormat = src->getActualFormatID();
3877*8975f5c5SAndroid Build Coastguard Worker angle::FormatID linearFormat =
3878*8975f5c5SAndroid Build Coastguard Worker src->getActualFormat().isSRGB ? ConvertToLinear(imageFormat) : imageFormat;
3879*8975f5c5SAndroid Build Coastguard Worker ASSERT(linearFormat != angle::FormatID::NONE);
3880*8975f5c5SAndroid Build Coastguard Worker
3881*8975f5c5SAndroid Build Coastguard Worker vk::DeviceScoped<vk::ImageView> srcView(contextVk->getDevice());
3882*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(src->initReinterpretedLayerImageView(
3883*8975f5c5SAndroid Build Coastguard Worker contextVk, textureType, src->getAspectFlags(), swizzle, &srcView.get(), params.srcMip, 1,
3884*8975f5c5SAndroid Build Coastguard Worker textureType == gl::TextureType::_2D ? params.srcLayer : 0, 1, VK_IMAGE_USAGE_SAMPLED_BIT,
3885*8975f5c5SAndroid Build Coastguard Worker linearFormat));
3886*8975f5c5SAndroid Build Coastguard Worker
3887*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access;
3888*8975f5c5SAndroid Build Coastguard Worker access.onImageComputeShaderRead(src->getAspectFlags(), src);
3889*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(dst);
3890*8975f5c5SAndroid Build Coastguard Worker
3891*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
3892*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper(access, &commandBufferHelper));
3893*8975f5c5SAndroid Build Coastguard Worker
3894*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
3895*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &commandBufferHelper->getCommandBuffer();
3896*8975f5c5SAndroid Build Coastguard Worker
3897*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
3898*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, commandBufferHelper, Function::CopyImageToBuffer,
3899*8975f5c5SAndroid Build Coastguard Worker &descriptorSet));
3900*8975f5c5SAndroid Build Coastguard Worker
3901*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo imageInfo = {};
3902*8975f5c5SAndroid Build Coastguard Worker imageInfo.imageView = srcView.get().getHandle();
3903*8975f5c5SAndroid Build Coastguard Worker imageInfo.imageLayout = src->getCurrentLayout(renderer);
3904*8975f5c5SAndroid Build Coastguard Worker
3905*8975f5c5SAndroid Build Coastguard Worker VkDescriptorBufferInfo bufferInfo = {};
3906*8975f5c5SAndroid Build Coastguard Worker bufferInfo.buffer = dst->getBuffer().getHandle();
3907*8975f5c5SAndroid Build Coastguard Worker bufferInfo.offset = dst->getOffset();
3908*8975f5c5SAndroid Build Coastguard Worker bufferInfo.range = dst->getSize();
3909*8975f5c5SAndroid Build Coastguard Worker
3910*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfo[2] = {};
3911*8975f5c5SAndroid Build Coastguard Worker
3912*8975f5c5SAndroid Build Coastguard Worker writeInfo[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
3913*8975f5c5SAndroid Build Coastguard Worker writeInfo[0].dstSet = descriptorSet;
3914*8975f5c5SAndroid Build Coastguard Worker writeInfo[0].dstBinding = kCopyImageToBufferSourceBinding;
3915*8975f5c5SAndroid Build Coastguard Worker writeInfo[0].descriptorCount = 1;
3916*8975f5c5SAndroid Build Coastguard Worker writeInfo[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
3917*8975f5c5SAndroid Build Coastguard Worker writeInfo[0].pImageInfo = &imageInfo;
3918*8975f5c5SAndroid Build Coastguard Worker
3919*8975f5c5SAndroid Build Coastguard Worker writeInfo[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
3920*8975f5c5SAndroid Build Coastguard Worker writeInfo[1].dstSet = descriptorSet;
3921*8975f5c5SAndroid Build Coastguard Worker writeInfo[1].dstBinding = kCopyImageToBufferDestinationBinding;
3922*8975f5c5SAndroid Build Coastguard Worker writeInfo[1].descriptorCount = 1;
3923*8975f5c5SAndroid Build Coastguard Worker writeInfo[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
3924*8975f5c5SAndroid Build Coastguard Worker writeInfo[1].pBufferInfo = &bufferInfo;
3925*8975f5c5SAndroid Build Coastguard Worker
3926*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 2, writeInfo, 0, nullptr);
3927*8975f5c5SAndroid Build Coastguard Worker
3928*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr shader;
3929*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getShaderLibrary().getCopyImageToBuffer_comp(contextVk, flags, &shader));
3930*8975f5c5SAndroid Build Coastguard Worker
3931*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupComputeProgram(contextVk, Function::CopyImageToBuffer, shader,
3932*8975f5c5SAndroid Build Coastguard Worker &mCopyImageToBuffer[flags], descriptorSet, &shaderParams,
3933*8975f5c5SAndroid Build Coastguard Worker sizeof(shaderParams), commandBufferHelper));
3934*8975f5c5SAndroid Build Coastguard Worker
3935*8975f5c5SAndroid Build Coastguard Worker commandBuffer->dispatch(UnsignedCeilDivide(params.size[0], 8),
3936*8975f5c5SAndroid Build Coastguard Worker UnsignedCeilDivide(params.size[1], 8), 1);
3937*8975f5c5SAndroid Build Coastguard Worker
3938*8975f5c5SAndroid Build Coastguard Worker vk::ImageView srcViewObject = srcView.release();
3939*8975f5c5SAndroid Build Coastguard Worker contextVk->addGarbage(&srcViewObject);
3940*8975f5c5SAndroid Build Coastguard Worker
3941*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3942*8975f5c5SAndroid Build Coastguard Worker }
3943*8975f5c5SAndroid Build Coastguard Worker
copyRgbToRgba(ContextVk * contextVk,const angle::Format & srcFormat,vk::BufferHelper * srcBuffer,uint32_t srcOffset,uint32_t pixelCount,vk::BufferHelper * dstBuffer)3944*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::copyRgbToRgba(ContextVk *contextVk,
3945*8975f5c5SAndroid Build Coastguard Worker const angle::Format &srcFormat,
3946*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *srcBuffer,
3947*8975f5c5SAndroid Build Coastguard Worker uint32_t srcOffset,
3948*8975f5c5SAndroid Build Coastguard Worker uint32_t pixelCount,
3949*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dstBuffer)
3950*8975f5c5SAndroid Build Coastguard Worker {
3951*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
3952*8975f5c5SAndroid Build Coastguard Worker
3953*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access;
3954*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderRead(srcBuffer);
3955*8975f5c5SAndroid Build Coastguard Worker access.onBufferComputeShaderWrite(dstBuffer);
3956*8975f5c5SAndroid Build Coastguard Worker
3957*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper(access, &commandBufferHelper));
3958*8975f5c5SAndroid Build Coastguard Worker
3959*8975f5c5SAndroid Build Coastguard Worker rx::UtilsVk::ConvertVertexShaderParams shaderParams;
3960*8975f5c5SAndroid Build Coastguard Worker shaderParams.Ns = 3; // src channels
3961*8975f5c5SAndroid Build Coastguard Worker shaderParams.Bs = 4; // src bytes per channel
3962*8975f5c5SAndroid Build Coastguard Worker shaderParams.Ss = 12; // src stride
3963*8975f5c5SAndroid Build Coastguard Worker shaderParams.Nd = 4; // dest channels
3964*8975f5c5SAndroid Build Coastguard Worker shaderParams.Bd = 4; // dest bytes per channel
3965*8975f5c5SAndroid Build Coastguard Worker shaderParams.Sd = 16; // dest stride
3966*8975f5c5SAndroid Build Coastguard Worker shaderParams.Es = 4 / shaderParams.Bs;
3967*8975f5c5SAndroid Build Coastguard Worker shaderParams.Ed = 4 / shaderParams.Bd;
3968*8975f5c5SAndroid Build Coastguard Worker // Total number of output components is simply the number of pixels by number of components in
3969*8975f5c5SAndroid Build Coastguard Worker // each.
3970*8975f5c5SAndroid Build Coastguard Worker shaderParams.componentCount = pixelCount * shaderParams.Nd;
3971*8975f5c5SAndroid Build Coastguard Worker // Total number of 4-byte outputs is the number of components divided by how many components can
3972*8975f5c5SAndroid Build Coastguard Worker // fit in a 4-byte value. Note that this value is also the invocation size of the shader.
3973*8975f5c5SAndroid Build Coastguard Worker shaderParams.outputCount = UnsignedCeilDivide(shaderParams.componentCount, shaderParams.Ed);
3974*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcOffset = srcOffset;
3975*8975f5c5SAndroid Build Coastguard Worker shaderParams.dstOffset = 0;
3976*8975f5c5SAndroid Build Coastguard Worker shaderParams.isSrcHDR = 0;
3977*8975f5c5SAndroid Build Coastguard Worker shaderParams.isSrcA2BGR10 = 0;
3978*8975f5c5SAndroid Build Coastguard Worker
3979*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = 0;
3980*8975f5c5SAndroid Build Coastguard Worker switch (srcFormat.id)
3981*8975f5c5SAndroid Build Coastguard Worker {
3982*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::R32G32B32_UINT:
3983*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kUintToUint;
3984*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = 1;
3985*8975f5c5SAndroid Build Coastguard Worker break;
3986*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::R32G32B32_SINT:
3987*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kSintToSint;
3988*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = 1;
3989*8975f5c5SAndroid Build Coastguard Worker break;
3990*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::R32G32B32_FLOAT:
3991*8975f5c5SAndroid Build Coastguard Worker flags = ConvertVertex_comp::kFloatToFloat;
3992*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcEmulatedAlpha = gl::Float32One;
3993*8975f5c5SAndroid Build Coastguard Worker break;
3994*8975f5c5SAndroid Build Coastguard Worker default:
3995*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
3996*8975f5c5SAndroid Build Coastguard Worker }
3997*8975f5c5SAndroid Build Coastguard Worker
3998*8975f5c5SAndroid Build Coastguard Worker return convertVertexBufferImpl(contextVk, dstBuffer, srcBuffer, flags, commandBufferHelper,
3999*8975f5c5SAndroid Build Coastguard Worker shaderParams, {});
4000*8975f5c5SAndroid Build Coastguard Worker }
4001*8975f5c5SAndroid Build Coastguard Worker
GetEtcToBcFlags(const angle::Format & format)4002*8975f5c5SAndroid Build Coastguard Worker uint32_t GetEtcToBcFlags(const angle::Format &format)
4003*8975f5c5SAndroid Build Coastguard Worker {
4004*8975f5c5SAndroid Build Coastguard Worker switch (format.id)
4005*8975f5c5SAndroid Build Coastguard Worker {
4006*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC1_R8G8B8_UNORM_BLOCK:
4007*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK:
4008*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK:
4009*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK:
4010*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK:
4011*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK:
4012*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK:
4013*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK:
4014*8975f5c5SAndroid Build Coastguard Worker return EtcToBc_comp::kEtcRgba8ToBC3;
4015*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::EAC_R11_SNORM_BLOCK:
4016*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::EAC_R11_UNORM_BLOCK:
4017*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::EAC_R11G11_SNORM_BLOCK:
4018*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::EAC_R11G11_UNORM_BLOCK:
4019*8975f5c5SAndroid Build Coastguard Worker return EtcToBc_comp::kEtcRg11ToBC5;
4020*8975f5c5SAndroid Build Coastguard Worker default:
4021*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
4022*8975f5c5SAndroid Build Coastguard Worker return EtcToBc_comp::kEtcRgba8ToBC3;
4023*8975f5c5SAndroid Build Coastguard Worker }
4024*8975f5c5SAndroid Build Coastguard Worker }
4025*8975f5c5SAndroid Build Coastguard Worker
GetCompactibleUINTFormat(const angle::Format & format)4026*8975f5c5SAndroid Build Coastguard Worker angle::FormatID GetCompactibleUINTFormat(const angle::Format &format)
4027*8975f5c5SAndroid Build Coastguard Worker {
4028*8975f5c5SAndroid Build Coastguard Worker ASSERT(format.pixelBytes == 8 || format.pixelBytes == 16);
4029*8975f5c5SAndroid Build Coastguard Worker return format.pixelBytes != 8 ? angle::FormatID::R32G32B32A32_UINT
4030*8975f5c5SAndroid Build Coastguard Worker : angle::FormatID::R32G32_UINT;
4031*8975f5c5SAndroid Build Coastguard Worker }
4032*8975f5c5SAndroid Build Coastguard Worker
transCodeEtcToBc(ContextVk * contextVk,vk::BufferHelper * srcBuffer,vk::ImageHelper * dstImage,const VkBufferImageCopy * copyRegion)4033*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::transCodeEtcToBc(ContextVk *contextVk,
4034*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *srcBuffer,
4035*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *dstImage,
4036*8975f5c5SAndroid Build Coastguard Worker const VkBufferImageCopy *copyRegion)
4037*8975f5c5SAndroid Build Coastguard Worker {
4038*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureTransCodeEtcToBcResourcesInitialized(contextVk));
4039*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
4040*8975f5c5SAndroid Build Coastguard Worker const angle::Format &intendedFormat = dstImage->getIntendedFormat();
4041*8975f5c5SAndroid Build Coastguard Worker vk::ContextScoped<vk::BufferViewHelper> bufferViewHelper(contextVk);
4042*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &info =
4043*8975f5c5SAndroid Build Coastguard Worker gl::GetSizedInternalFormatInfo(intendedFormat.glInternalFormat);
4044*8975f5c5SAndroid Build Coastguard Worker
4045*8975f5c5SAndroid Build Coastguard Worker // According to GLES spec. Etc texture don't support 3D texture type.
4046*8975f5c5SAndroid Build Coastguard Worker ASSERT(copyRegion->bufferRowLength % info.compressedBlockWidth == 0 &&
4047*8975f5c5SAndroid Build Coastguard Worker copyRegion->bufferImageHeight % info.compressedBlockHeight == 0 &&
4048*8975f5c5SAndroid Build Coastguard Worker copyRegion->imageExtent.depth == 1);
4049*8975f5c5SAndroid Build Coastguard Worker
4050*8975f5c5SAndroid Build Coastguard Worker ASSERT(dstImage->getType() != VK_IMAGE_TYPE_1D && dstImage->getType() != VK_IMAGE_TYPE_3D);
4051*8975f5c5SAndroid Build Coastguard Worker
4052*8975f5c5SAndroid Build Coastguard Worker GLuint sliceTexels = (copyRegion->bufferRowLength / info.compressedBlockWidth) *
4053*8975f5c5SAndroid Build Coastguard Worker (copyRegion->bufferImageHeight / info.compressedBlockHeight);
4054*8975f5c5SAndroid Build Coastguard Worker GLuint sliceSize = sliceTexels * intendedFormat.pixelBytes;
4055*8975f5c5SAndroid Build Coastguard Worker GLuint texBufferSize = sliceSize * copyRegion->imageSubresource.layerCount;
4056*8975f5c5SAndroid Build Coastguard Worker
4057*8975f5c5SAndroid Build Coastguard Worker // Make sure the texture buffer size not out of limit.
4058*8975f5c5SAndroid Build Coastguard Worker // Usually the limit is more than 128M.
4059*8975f5c5SAndroid Build Coastguard Worker ASSERT(
4060*8975f5c5SAndroid Build Coastguard Worker texBufferSize <
4061*8975f5c5SAndroid Build Coastguard Worker static_cast<GLuint>(renderer->getPhysicalDeviceProperties().limits.maxTexelBufferElements));
4062*8975f5c5SAndroid Build Coastguard Worker const vk::BufferView *srcBufferView = nullptr;
4063*8975f5c5SAndroid Build Coastguard Worker bufferViewHelper.get().init(renderer, 0, texBufferSize);
4064*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(bufferViewHelper.get().getView(
4065*8975f5c5SAndroid Build Coastguard Worker contextVk, *srcBuffer, copyRegion->bufferOffset,
4066*8975f5c5SAndroid Build Coastguard Worker renderer->getFormat(GetCompactibleUINTFormat(intendedFormat)), &srcBufferView));
4067*8975f5c5SAndroid Build Coastguard Worker
4068*8975f5c5SAndroid Build Coastguard Worker vk::LevelIndex dstLevel =
4069*8975f5c5SAndroid Build Coastguard Worker gl::LevelIndexWrapper<uint32_t>(copyRegion->imageSubresource.mipLevel);
4070*8975f5c5SAndroid Build Coastguard Worker
4071*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
4072*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper({}, &commandBufferHelper));
4073*8975f5c5SAndroid Build Coastguard Worker const angle::Format &format = dstImage->getIntendedFormat();
4074*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = GetEtcToBcFlags(format);
4075*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr shader;
4076*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getShaderLibrary().getEtcToBc_comp(contextVk, flags, &shader));
4077*8975f5c5SAndroid Build Coastguard Worker
4078*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
4079*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &commandBufferHelper->getCommandBuffer();
4080*8975f5c5SAndroid Build Coastguard Worker
4081*8975f5c5SAndroid Build Coastguard Worker // For BC format, shader need width and height to be multiple of four.
4082*8975f5c5SAndroid Build Coastguard Worker uint32_t width = rx::roundUpPow2(copyRegion->imageExtent.width, 4u);
4083*8975f5c5SAndroid Build Coastguard Worker uint32_t height = rx::roundUpPow2(copyRegion->imageExtent.height, 4u);
4084*8975f5c5SAndroid Build Coastguard Worker
4085*8975f5c5SAndroid Build Coastguard Worker // push constants data
4086*8975f5c5SAndroid Build Coastguard Worker EtcToBcShaderParams shaderParams = {};
4087*8975f5c5SAndroid Build Coastguard Worker shaderParams.offsetX = static_cast<uint32_t>(copyRegion->imageOffset.x);
4088*8975f5c5SAndroid Build Coastguard Worker shaderParams.offsetY = static_cast<uint32_t>(copyRegion->imageOffset.y);
4089*8975f5c5SAndroid Build Coastguard Worker shaderParams.texelOffset = 0;
4090*8975f5c5SAndroid Build Coastguard Worker shaderParams.width = width;
4091*8975f5c5SAndroid Build Coastguard Worker shaderParams.height = height;
4092*8975f5c5SAndroid Build Coastguard Worker shaderParams.alphaBits = format.alphaBits;
4093*8975f5c5SAndroid Build Coastguard Worker shaderParams.isSigned = format.isSnorm();
4094*8975f5c5SAndroid Build Coastguard Worker shaderParams.isEacRg = format.channelCount == 2; // EAC_RG11
4095*8975f5c5SAndroid Build Coastguard Worker
4096*8975f5c5SAndroid Build Coastguard Worker VkBufferView bufferView = srcBufferView->getHandle();
4097*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeDescriptorSet[2] = {};
4098*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
4099*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
4100*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[0].dstBinding = 0;
4101*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[0].pBufferInfo = nullptr;
4102*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[0].descriptorCount = 1;
4103*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[0].pTexelBufferView = &bufferView;
4104*8975f5c5SAndroid Build Coastguard Worker
4105*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo imageInfo = {};
4106*8975f5c5SAndroid Build Coastguard Worker imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
4107*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
4108*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
4109*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[1].dstBinding = 1;
4110*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[1].pImageInfo = &imageInfo;
4111*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[1].descriptorCount = 1;
4112*8975f5c5SAndroid Build Coastguard Worker // Due to limitation VUID-VkImageViewCreateInfo-image-07072, we have to copy layer by layer.
4113*8975f5c5SAndroid Build Coastguard Worker for (uint32_t i = 0; i < copyRegion->imageSubresource.layerCount; ++i)
4114*8975f5c5SAndroid Build Coastguard Worker {
4115*8975f5c5SAndroid Build Coastguard Worker vk::DeviceScoped<vk::ImageView> scopedImageView(contextVk->getDevice());
4116*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(dstImage->initReinterpretedLayerImageView(
4117*8975f5c5SAndroid Build Coastguard Worker contextVk, gl::TextureType::_2D, VK_IMAGE_ASPECT_COLOR_BIT, gl::SwizzleState(),
4118*8975f5c5SAndroid Build Coastguard Worker &scopedImageView.get(), dstLevel, 1, copyRegion->imageSubresource.baseArrayLayer + i, 1,
4119*8975f5c5SAndroid Build Coastguard Worker VK_IMAGE_USAGE_STORAGE_BIT, GetCompactibleUINTFormat(intendedFormat)));
4120*8975f5c5SAndroid Build Coastguard Worker imageInfo.imageView = scopedImageView.get().getHandle();
4121*8975f5c5SAndroid Build Coastguard Worker
4122*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
4123*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, commandBufferHelper, Function::TransCodeEtcToBc,
4124*8975f5c5SAndroid Build Coastguard Worker &descriptorSet));
4125*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[0].dstSet = descriptorSet;
4126*8975f5c5SAndroid Build Coastguard Worker writeDescriptorSet[1].dstSet = descriptorSet;
4127*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 2, writeDescriptorSet, 0, nullptr);
4128*8975f5c5SAndroid Build Coastguard Worker
4129*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupComputeProgram(contextVk, Function::TransCodeEtcToBc, shader,
4130*8975f5c5SAndroid Build Coastguard Worker &mEtcToBc[flags], descriptorSet, &shaderParams,
4131*8975f5c5SAndroid Build Coastguard Worker sizeof(shaderParams), commandBufferHelper));
4132*8975f5c5SAndroid Build Coastguard Worker
4133*8975f5c5SAndroid Build Coastguard Worker // Work group size is 8 x 8 x 1
4134*8975f5c5SAndroid Build Coastguard Worker commandBuffer->dispatch(UnsignedCeilDivide(width, 8), UnsignedCeilDivide(height, 8), 1);
4135*8975f5c5SAndroid Build Coastguard Worker // Release temporary views
4136*8975f5c5SAndroid Build Coastguard Worker vk::ImageView imageView = scopedImageView.release();
4137*8975f5c5SAndroid Build Coastguard Worker contextVk->addGarbage(&imageView);
4138*8975f5c5SAndroid Build Coastguard Worker
4139*8975f5c5SAndroid Build Coastguard Worker shaderParams.texelOffset += sliceTexels;
4140*8975f5c5SAndroid Build Coastguard Worker }
4141*8975f5c5SAndroid Build Coastguard Worker // Retain buffer view
4142*8975f5c5SAndroid Build Coastguard Worker commandBufferHelper->retainResource(&bufferViewHelper.get());
4143*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4144*8975f5c5SAndroid Build Coastguard Worker }
4145*8975f5c5SAndroid Build Coastguard Worker
generateMipmap(ContextVk * contextVk,vk::ImageHelper * src,const vk::ImageView * srcLevelZeroView,vk::ImageHelper * dst,const GenerateMipmapDestLevelViews & destLevelViews,const vk::Sampler & sampler,const GenerateMipmapParameters & params)4146*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::generateMipmap(ContextVk *contextVk,
4147*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *src,
4148*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *srcLevelZeroView,
4149*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *dst,
4150*8975f5c5SAndroid Build Coastguard Worker const GenerateMipmapDestLevelViews &destLevelViews,
4151*8975f5c5SAndroid Build Coastguard Worker const vk::Sampler &sampler,
4152*8975f5c5SAndroid Build Coastguard Worker const GenerateMipmapParameters ¶ms)
4153*8975f5c5SAndroid Build Coastguard Worker {
4154*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
4155*8975f5c5SAndroid Build Coastguard Worker
4156*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureGenerateMipmapResourcesInitialized(contextVk));
4157*8975f5c5SAndroid Build Coastguard Worker
4158*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &srcExtents = src->getLevelExtents(vk::LevelIndex(params.srcLevel));
4159*8975f5c5SAndroid Build Coastguard Worker ASSERT(srcExtents.depth == 1);
4160*8975f5c5SAndroid Build Coastguard Worker
4161*8975f5c5SAndroid Build Coastguard Worker // Each workgroup processes a 64x64 tile of the image.
4162*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kPixelWorkgroupRatio = 64;
4163*8975f5c5SAndroid Build Coastguard Worker const uint32_t workGroupX = UnsignedCeilDivide(srcExtents.width, kPixelWorkgroupRatio);
4164*8975f5c5SAndroid Build Coastguard Worker const uint32_t workGroupY = UnsignedCeilDivide(srcExtents.height, kPixelWorkgroupRatio);
4165*8975f5c5SAndroid Build Coastguard Worker
4166*8975f5c5SAndroid Build Coastguard Worker GenerateMipmapShaderParams shaderParams;
4167*8975f5c5SAndroid Build Coastguard Worker shaderParams.invSrcExtent[0] = 1.0f / srcExtents.width;
4168*8975f5c5SAndroid Build Coastguard Worker shaderParams.invSrcExtent[1] = 1.0f / srcExtents.height;
4169*8975f5c5SAndroid Build Coastguard Worker shaderParams.levelCount = params.dstLevelCount;
4170*8975f5c5SAndroid Build Coastguard Worker
4171*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = GetGenerateMipmapFlags(contextVk, src->getActualFormat());
4172*8975f5c5SAndroid Build Coastguard Worker
4173*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
4174*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper({}, &commandBufferHelper));
4175*8975f5c5SAndroid Build Coastguard Worker
4176*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
4177*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, commandBufferHelper, Function::GenerateMipmap,
4178*8975f5c5SAndroid Build Coastguard Worker &descriptorSet));
4179*8975f5c5SAndroid Build Coastguard Worker
4180*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo destImageInfos[kGenerateMipmapMaxLevels] = {};
4181*8975f5c5SAndroid Build Coastguard Worker for (uint32_t level = 0; level < kGenerateMipmapMaxLevels; ++level)
4182*8975f5c5SAndroid Build Coastguard Worker {
4183*8975f5c5SAndroid Build Coastguard Worker destImageInfos[level].imageView = destLevelViews[level]->getHandle();
4184*8975f5c5SAndroid Build Coastguard Worker destImageInfos[level].imageLayout = dst->getCurrentLayout(renderer);
4185*8975f5c5SAndroid Build Coastguard Worker }
4186*8975f5c5SAndroid Build Coastguard Worker
4187*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo srcImageInfo = {};
4188*8975f5c5SAndroid Build Coastguard Worker srcImageInfo.imageView = srcLevelZeroView->getHandle();
4189*8975f5c5SAndroid Build Coastguard Worker srcImageInfo.imageLayout = src->getCurrentLayout(renderer);
4190*8975f5c5SAndroid Build Coastguard Worker srcImageInfo.sampler = sampler.getHandle();
4191*8975f5c5SAndroid Build Coastguard Worker
4192*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfos[2] = {};
4193*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
4194*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstSet = descriptorSet;
4195*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstBinding = kGenerateMipmapDestinationBinding;
4196*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorCount = GetGenerateMipmapMaxLevels(contextVk);
4197*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
4198*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].pImageInfo = destImageInfos;
4199*8975f5c5SAndroid Build Coastguard Worker
4200*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
4201*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].dstSet = descriptorSet;
4202*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].dstBinding = kGenerateMipmapSourceBinding;
4203*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].descriptorCount = 1;
4204*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
4205*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].pImageInfo = &srcImageInfo;
4206*8975f5c5SAndroid Build Coastguard Worker
4207*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 2, writeInfos, 0, nullptr);
4208*8975f5c5SAndroid Build Coastguard Worker
4209*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr shader;
4210*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getShaderLibrary().getGenerateMipmap_comp(contextVk, flags, &shader));
4211*8975f5c5SAndroid Build Coastguard Worker
4212*8975f5c5SAndroid Build Coastguard Worker // Note: onImageRead/onImageWrite is expected to be called by the caller. This avoids inserting
4213*8975f5c5SAndroid Build Coastguard Worker // barriers between calls for each layer of the image.
4214*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
4215*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &commandBufferHelper->getCommandBuffer();
4216*8975f5c5SAndroid Build Coastguard Worker
4217*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupComputeProgram(contextVk, Function::GenerateMipmap, shader,
4218*8975f5c5SAndroid Build Coastguard Worker &mGenerateMipmap[flags], descriptorSet, &shaderParams,
4219*8975f5c5SAndroid Build Coastguard Worker sizeof(shaderParams), commandBufferHelper));
4220*8975f5c5SAndroid Build Coastguard Worker
4221*8975f5c5SAndroid Build Coastguard Worker commandBuffer->dispatch(workGroupX, workGroupY, 1);
4222*8975f5c5SAndroid Build Coastguard Worker
4223*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4224*8975f5c5SAndroid Build Coastguard Worker }
4225*8975f5c5SAndroid Build Coastguard Worker
generateMipmapWithDraw(ContextVk * contextVk,vk::ImageHelper * image,const angle::FormatID actualFormatID,const bool isMipmapFiltered)4226*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::generateMipmapWithDraw(ContextVk *contextVk,
4227*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *image,
4228*8975f5c5SAndroid Build Coastguard Worker const angle::FormatID actualFormatID,
4229*8975f5c5SAndroid Build Coastguard Worker const bool isMipmapFiltered)
4230*8975f5c5SAndroid Build Coastguard Worker {
4231*8975f5c5SAndroid Build Coastguard Worker // This function only supports -
4232*8975f5c5SAndroid Build Coastguard Worker // 1. color formats that support color attachment feature
4233*8975f5c5SAndroid Build Coastguard Worker // 2. image is of type VK_IMAGE_TYPE_2D and is not MSAA
4234*8975f5c5SAndroid Build Coastguard Worker ASSERT(image);
4235*8975f5c5SAndroid Build Coastguard Worker ASSERT(image->getType() == VK_IMAGE_TYPE_2D && image->getSamples() == 1);
4236*8975f5c5SAndroid Build Coastguard Worker const angle::Format &actualFormat = angle::Format::Get(actualFormatID);
4237*8975f5c5SAndroid Build Coastguard Worker ASSERT(!actualFormat.hasDepthOrStencilBits());
4238*8975f5c5SAndroid Build Coastguard Worker // TODO: the following check is not enough; if the image is AHB-imported, then the draw path
4239*8975f5c5SAndroid Build Coastguard Worker // cannot be taken if AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER hasn't been specified, even if the
4240*8975f5c5SAndroid Build Coastguard Worker // format is renderable.
4241*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
4242*8975f5c5SAndroid Build Coastguard Worker ASSERT(vk::FormatHasNecessaryFeature(renderer, actualFormat.id, image->getTilingMode(),
4243*8975f5c5SAndroid Build Coastguard Worker VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT));
4244*8975f5c5SAndroid Build Coastguard Worker
4245*8975f5c5SAndroid Build Coastguard Worker // Ensure required resources are initialized
4246*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureBlitResolveResourcesInitialized(contextVk));
4247*8975f5c5SAndroid Build Coastguard Worker
4248*8975f5c5SAndroid Build Coastguard Worker uint32_t layerCount = image->getLayerCount();
4249*8975f5c5SAndroid Build Coastguard Worker uint32_t levelCount = image->getLevelCount();
4250*8975f5c5SAndroid Build Coastguard Worker GLint sampleCount = image->getSamples();
4251*8975f5c5SAndroid Build Coastguard Worker gl::LevelIndex baseLevelGL = image->getFirstAllocatedLevel();
4252*8975f5c5SAndroid Build Coastguard Worker vk::LevelIndex baseLevelVK = image->toVkLevel(baseLevelGL);
4253*8975f5c5SAndroid Build Coastguard Worker vk::LevelIndex maxLevelVK = baseLevelVK + (levelCount - 1);
4254*8975f5c5SAndroid Build Coastguard Worker
4255*8975f5c5SAndroid Build Coastguard Worker // Transition entire image to color attachment layout
4256*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access;
4257*8975f5c5SAndroid Build Coastguard Worker access.onImageDrawMipmapGenerationWrite(baseLevelGL, levelCount, 0, layerCount,
4258*8975f5c5SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_COLOR_BIT, image);
4259*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *outsideCommandBuffer;
4260*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &outsideCommandBuffer));
4261*8975f5c5SAndroid Build Coastguard Worker
4262*8975f5c5SAndroid Build Coastguard Worker gl::TextureType textureType = vk::Get2DTextureType(layerCount, sampleCount);
4263*8975f5c5SAndroid Build Coastguard Worker gl::SwizzleState swizzle = {};
4264*8975f5c5SAndroid Build Coastguard Worker VkImageUsageFlags imageUsageFlags = image->getUsage();
4265*8975f5c5SAndroid Build Coastguard Worker
4266*8975f5c5SAndroid Build Coastguard Worker // Setup shaders for draw
4267*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = GetBlitResolveFlags(true, false, false, actualFormat);
4268*8975f5c5SAndroid Build Coastguard Worker flags |= layerCount > 1 ? BlitResolve_frag::kSrcIsArray : 0;
4269*8975f5c5SAndroid Build Coastguard Worker Function function = Function::BlitResolve;
4270*8975f5c5SAndroid Build Coastguard Worker
4271*8975f5c5SAndroid Build Coastguard Worker vk::ShaderLibrary &shaderLibrary = contextVk->getShaderLibrary();
4272*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr vertexShader;
4273*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr fragmentShader;
4274*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getFullScreenTri_vert(contextVk, 0, &vertexShader));
4275*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getBlitResolve_frag(contextVk, flags, &fragmentShader));
4276*8975f5c5SAndroid Build Coastguard Worker
4277*8975f5c5SAndroid Build Coastguard Worker // Setup blit shader parameters
4278*8975f5c5SAndroid Build Coastguard Worker BlitResolveShaderParams shaderParams;
4279*8975f5c5SAndroid Build Coastguard Worker shaderParams.offset.blit[0] = 0.0f;
4280*8975f5c5SAndroid Build Coastguard Worker shaderParams.offset.blit[1] = 0.0f;
4281*8975f5c5SAndroid Build Coastguard Worker shaderParams.stretch[0] = 1.0f;
4282*8975f5c5SAndroid Build Coastguard Worker shaderParams.stretch[1] = 1.0f;
4283*8975f5c5SAndroid Build Coastguard Worker shaderParams.samples = 1;
4284*8975f5c5SAndroid Build Coastguard Worker shaderParams.invSamples = 1.0f;
4285*8975f5c5SAndroid Build Coastguard Worker shaderParams.outputMask = 1;
4286*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipX = 0;
4287*8975f5c5SAndroid Build Coastguard Worker shaderParams.flipY = 0;
4288*8975f5c5SAndroid Build Coastguard Worker shaderParams.rotateXY = 0;
4289*8975f5c5SAndroid Build Coastguard Worker
4290*8975f5c5SAndroid Build Coastguard Worker // Setup pipeline for draw
4291*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassDesc renderPassDesc;
4292*8975f5c5SAndroid Build Coastguard Worker renderPassDesc.setSamples(sampleCount);
4293*8975f5c5SAndroid Build Coastguard Worker renderPassDesc.packColorAttachment(0, actualFormatID);
4294*8975f5c5SAndroid Build Coastguard Worker
4295*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineDesc pipelineDesc;
4296*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.initDefaults(contextVk, vk::GraphicsPipelineSubset::Complete,
4297*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineRobustness(),
4298*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineProtectedAccess());
4299*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setSingleColorWriteMask(0, (VkColorComponentFlagBits::VK_COLOR_COMPONENT_R_BIT |
4300*8975f5c5SAndroid Build Coastguard Worker VkColorComponentFlagBits::VK_COLOR_COMPONENT_G_BIT |
4301*8975f5c5SAndroid Build Coastguard Worker VkColorComponentFlagBits::VK_COLOR_COMPONENT_B_BIT |
4302*8975f5c5SAndroid Build Coastguard Worker VkColorComponentFlagBits::VK_COLOR_COMPONENT_A_BIT));
4303*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRasterizationSamples(sampleCount);
4304*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRenderPassDesc(renderPassDesc);
4305*8975f5c5SAndroid Build Coastguard Worker
4306*8975f5c5SAndroid Build Coastguard Worker // Setup write descriptors
4307*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo imageInfos = {};
4308*8975f5c5SAndroid Build Coastguard Worker imageInfos.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4309*8975f5c5SAndroid Build Coastguard Worker
4310*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo samplerInfo = {};
4311*8975f5c5SAndroid Build Coastguard Worker samplerInfo.sampler = isMipmapFiltered ? mLinearSampler.getHandle() : mPointSampler.getHandle();
4312*8975f5c5SAndroid Build Coastguard Worker
4313*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfos[2] = {};
4314*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
4315*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstBinding = kBlitResolveColorOrDepthBinding;
4316*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorCount = 1;
4317*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
4318*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].pImageInfo = &imageInfos;
4319*8975f5c5SAndroid Build Coastguard Worker
4320*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
4321*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].dstBinding = kBlitResolveSamplerBinding;
4322*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].descriptorCount = 1;
4323*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
4324*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].pImageInfo = &samplerInfo;
4325*8975f5c5SAndroid Build Coastguard Worker
4326*8975f5c5SAndroid Build Coastguard Worker // Setup for read barrier
4327*8975f5c5SAndroid Build Coastguard Worker VkImageMemoryBarrier barrier = {};
4328*8975f5c5SAndroid Build Coastguard Worker barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4329*8975f5c5SAndroid Build Coastguard Worker barrier.image = image->getImage().getHandle();
4330*8975f5c5SAndroid Build Coastguard Worker barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
4331*8975f5c5SAndroid Build Coastguard Worker barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
4332*8975f5c5SAndroid Build Coastguard Worker barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4333*8975f5c5SAndroid Build Coastguard Worker barrier.subresourceRange.baseArrayLayer = 0;
4334*8975f5c5SAndroid Build Coastguard Worker barrier.subresourceRange.layerCount = layerCount;
4335*8975f5c5SAndroid Build Coastguard Worker barrier.subresourceRange.baseMipLevel = baseLevelVK.get();
4336*8975f5c5SAndroid Build Coastguard Worker barrier.subresourceRange.levelCount = 1;
4337*8975f5c5SAndroid Build Coastguard Worker barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
4338*8975f5c5SAndroid Build Coastguard Worker barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
4339*8975f5c5SAndroid Build Coastguard Worker barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4340*8975f5c5SAndroid Build Coastguard Worker barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
4341*8975f5c5SAndroid Build Coastguard Worker
4342*8975f5c5SAndroid Build Coastguard Worker // Sample from mipLevel N and draw to mipLevel N+1
4343*8975f5c5SAndroid Build Coastguard Worker for (vk::LevelIndex srcLevelVk = baseLevelVK; srcLevelVk < maxLevelVK;)
4344*8975f5c5SAndroid Build Coastguard Worker {
4345*8975f5c5SAndroid Build Coastguard Worker // Transition "srcLevel" of all layers to shader read only optimal layout
4346*8975f5c5SAndroid Build Coastguard Worker outsideCommandBuffer = nullptr;
4347*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &outsideCommandBuffer));
4348*8975f5c5SAndroid Build Coastguard Worker
4349*8975f5c5SAndroid Build Coastguard Worker barrier.subresourceRange.baseMipLevel = srcLevelVk.get();
4350*8975f5c5SAndroid Build Coastguard Worker outsideCommandBuffer->imageBarrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4351*8975f5c5SAndroid Build Coastguard Worker VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, barrier);
4352*8975f5c5SAndroid Build Coastguard Worker
4353*8975f5c5SAndroid Build Coastguard Worker // Update render area
4354*8975f5c5SAndroid Build Coastguard Worker vk::LevelIndex dstLevelVk = srcLevelVk + 1;
4355*8975f5c5SAndroid Build Coastguard Worker ASSERT(dstLevelVk <= baseLevelVK + levelCount);
4356*8975f5c5SAndroid Build Coastguard Worker gl::Extents extents = image->getLevelExtents(dstLevelVk);
4357*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle renderArea = gl::Rectangle(0, 0, extents.width, extents.height);
4358*8975f5c5SAndroid Build Coastguard Worker VkViewport viewport;
4359*8975f5c5SAndroid Build Coastguard Worker gl_vk::GetViewport(renderArea, 0.0f, 1.0f, false, false, renderArea.height, &viewport);
4360*8975f5c5SAndroid Build Coastguard Worker VkRect2D scissor = gl_vk::GetRect(renderArea);
4361*8975f5c5SAndroid Build Coastguard Worker
4362*8975f5c5SAndroid Build Coastguard Worker shaderParams.invSrcExtent[0] = 1.0f / renderArea.width;
4363*8975f5c5SAndroid Build Coastguard Worker shaderParams.invSrcExtent[1] = 1.0f / renderArea.height;
4364*8975f5c5SAndroid Build Coastguard Worker
4365*8975f5c5SAndroid Build Coastguard Worker // mipLevel N --> mipLevel N+1 must be done for each layer
4366*8975f5c5SAndroid Build Coastguard Worker for (uint32_t currentLayer = 0; currentLayer < layerCount; currentLayer++)
4367*8975f5c5SAndroid Build Coastguard Worker {
4368*8975f5c5SAndroid Build Coastguard Worker // Create image views for currentLayer's srcLevelVk and dstLevelVk
4369*8975f5c5SAndroid Build Coastguard Worker vk::ImageView srcImageView;
4370*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(image->initReinterpretedLayerImageView(
4371*8975f5c5SAndroid Build Coastguard Worker contextVk, textureType, image->getAspectFlags(), swizzle, &srcImageView, srcLevelVk,
4372*8975f5c5SAndroid Build Coastguard Worker 1, currentLayer, 1, imageUsageFlags, actualFormatID));
4373*8975f5c5SAndroid Build Coastguard Worker
4374*8975f5c5SAndroid Build Coastguard Worker vk::ImageView dstImageView;
4375*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(image->initReinterpretedLayerImageView(
4376*8975f5c5SAndroid Build Coastguard Worker contextVk, textureType, image->getAspectFlags(), swizzle, &dstImageView, dstLevelVk,
4377*8975f5c5SAndroid Build Coastguard Worker 1, currentLayer, 1, imageUsageFlags, actualFormatID));
4378*8975f5c5SAndroid Build Coastguard Worker
4379*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer = nullptr;
4380*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(startRenderPass(contextVk, image, &dstImageView, renderPassDesc, renderArea,
4381*8975f5c5SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_COLOR_BIT, nullptr,
4382*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassSource::InternalUtils, &commandBuffer));
4383*8975f5c5SAndroid Build Coastguard Worker
4384*8975f5c5SAndroid Build Coastguard Worker UpdateColorAccess(contextVk, MakeColorBufferMask(0), MakeColorBufferMask(0));
4385*8975f5c5SAndroid Build Coastguard Worker
4386*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
4387*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, &contextVk->getStartedRenderPassCommands(),
4388*8975f5c5SAndroid Build Coastguard Worker Function::BlitResolve, &descriptorSet));
4389*8975f5c5SAndroid Build Coastguard Worker
4390*8975f5c5SAndroid Build Coastguard Worker // Update write descriptor info
4391*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstSet = descriptorSet;
4392*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].dstSet = descriptorSet;
4393*8975f5c5SAndroid Build Coastguard Worker imageInfos.imageView = srcImageView.getHandle();
4394*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 2, writeInfos, 0, nullptr);
4395*8975f5c5SAndroid Build Coastguard Worker
4396*8975f5c5SAndroid Build Coastguard Worker // Update layer index and create pipeline
4397*8975f5c5SAndroid Build Coastguard Worker shaderParams.srcLayer = currentLayer;
4398*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupGraphicsProgram(contextVk, function, vertexShader, fragmentShader,
4399*8975f5c5SAndroid Build Coastguard Worker &mBlitResolve[flags], &pipelineDesc, descriptorSet,
4400*8975f5c5SAndroid Build Coastguard Worker &shaderParams, sizeof(shaderParams), commandBuffer));
4401*8975f5c5SAndroid Build Coastguard Worker
4402*8975f5c5SAndroid Build Coastguard Worker // Set dynamic state
4403*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setViewport(0, 1, &viewport);
4404*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setScissor(0, 1, &scissor);
4405*8975f5c5SAndroid Build Coastguard Worker SetDepthDynamicStateForUnused(renderer, commandBuffer);
4406*8975f5c5SAndroid Build Coastguard Worker SetStencilDynamicStateForUnused(renderer, commandBuffer);
4407*8975f5c5SAndroid Build Coastguard Worker
4408*8975f5c5SAndroid Build Coastguard Worker // Note: this utility creates its own framebuffer, thus bypassing
4409*8975f5c5SAndroid Build Coastguard Worker // ContextVk::startRenderPass. As such, occlusion queries are not enabled.
4410*8975f5c5SAndroid Build Coastguard Worker commandBuffer->draw(3, 0);
4411*8975f5c5SAndroid Build Coastguard Worker
4412*8975f5c5SAndroid Build Coastguard Worker contextVk->addGarbage(&srcImageView);
4413*8975f5c5SAndroid Build Coastguard Worker contextVk->addGarbage(&dstImageView);
4414*8975f5c5SAndroid Build Coastguard Worker }
4415*8975f5c5SAndroid Build Coastguard Worker
4416*8975f5c5SAndroid Build Coastguard Worker // Close the render pass for this temporary framebuffer.
4417*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass(
4418*8975f5c5SAndroid Build Coastguard Worker RenderPassClosureReason::GenerateMipmapWithDraw));
4419*8975f5c5SAndroid Build Coastguard Worker
4420*8975f5c5SAndroid Build Coastguard Worker srcLevelVk = dstLevelVk;
4421*8975f5c5SAndroid Build Coastguard Worker }
4422*8975f5c5SAndroid Build Coastguard Worker
4423*8975f5c5SAndroid Build Coastguard Worker // Transition the last mipLevel to shader read only optimal layout
4424*8975f5c5SAndroid Build Coastguard Worker outsideCommandBuffer = nullptr;
4425*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &outsideCommandBuffer));
4426*8975f5c5SAndroid Build Coastguard Worker
4427*8975f5c5SAndroid Build Coastguard Worker barrier.subresourceRange.baseMipLevel = maxLevelVK.get();
4428*8975f5c5SAndroid Build Coastguard Worker outsideCommandBuffer->imageBarrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4429*8975f5c5SAndroid Build Coastguard Worker VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, barrier);
4430*8975f5c5SAndroid Build Coastguard Worker
4431*8975f5c5SAndroid Build Coastguard Worker // Update image's layout related state to shader read only optimal layout
4432*8975f5c5SAndroid Build Coastguard Worker image->setCurrentImageLayout(renderer, vk::ImageLayout::FragmentShaderReadOnly);
4433*8975f5c5SAndroid Build Coastguard Worker
4434*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4435*8975f5c5SAndroid Build Coastguard Worker }
4436*8975f5c5SAndroid Build Coastguard Worker
unresolve(ContextVk * contextVk,const FramebufferVk * framebuffer,const UnresolveParameters & params)4437*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::unresolve(ContextVk *contextVk,
4438*8975f5c5SAndroid Build Coastguard Worker const FramebufferVk *framebuffer,
4439*8975f5c5SAndroid Build Coastguard Worker const UnresolveParameters ¶ms)
4440*8975f5c5SAndroid Build Coastguard Worker {
4441*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
4442*8975f5c5SAndroid Build Coastguard Worker
4443*8975f5c5SAndroid Build Coastguard Worker // Get attachment count and pointers to resolve images and views.
4444*8975f5c5SAndroid Build Coastguard Worker gl::DrawBuffersArray<vk::ImageHelper *> colorSrc = {};
4445*8975f5c5SAndroid Build Coastguard Worker gl::DrawBuffersArray<const vk::ImageView *> colorSrcView = {};
4446*8975f5c5SAndroid Build Coastguard Worker
4447*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *depthSrcView = nullptr;
4448*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *stencilSrcView = nullptr;
4449*8975f5c5SAndroid Build Coastguard Worker
4450*8975f5c5SAndroid Build Coastguard Worker // The subpass that initializes the multisampled-render-to-texture attachments packs the
4451*8975f5c5SAndroid Build Coastguard Worker // attachments that need to be unresolved, so the attachment indices of this subpass are not the
4452*8975f5c5SAndroid Build Coastguard Worker // same. See InitializeUnresolveSubpass for details.
4453*8975f5c5SAndroid Build Coastguard Worker vk::PackedAttachmentIndex colorIndexVk(0);
4454*8975f5c5SAndroid Build Coastguard Worker for (size_t colorIndexGL : params.unresolveColorMask)
4455*8975f5c5SAndroid Build Coastguard Worker {
4456*8975f5c5SAndroid Build Coastguard Worker RenderTargetVk *colorRenderTarget = framebuffer->getColorDrawRenderTarget(colorIndexGL);
4457*8975f5c5SAndroid Build Coastguard Worker
4458*8975f5c5SAndroid Build Coastguard Worker ASSERT(colorRenderTarget->hasResolveAttachment());
4459*8975f5c5SAndroid Build Coastguard Worker ASSERT(colorRenderTarget->isImageTransient());
4460*8975f5c5SAndroid Build Coastguard Worker
4461*8975f5c5SAndroid Build Coastguard Worker colorSrc[colorIndexVk.get()] = &colorRenderTarget->getResolveImageForRenderPass();
4462*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
4463*8975f5c5SAndroid Build Coastguard Worker colorRenderTarget->getResolveImageView(contextVk, &colorSrcView[colorIndexVk.get()]));
4464*8975f5c5SAndroid Build Coastguard Worker
4465*8975f5c5SAndroid Build Coastguard Worker ++colorIndexVk;
4466*8975f5c5SAndroid Build Coastguard Worker }
4467*8975f5c5SAndroid Build Coastguard Worker
4468*8975f5c5SAndroid Build Coastguard Worker if (params.unresolveDepth || params.unresolveStencil)
4469*8975f5c5SAndroid Build Coastguard Worker {
4470*8975f5c5SAndroid Build Coastguard Worker RenderTargetVk *depthStencilRenderTarget = framebuffer->getDepthStencilRenderTarget();
4471*8975f5c5SAndroid Build Coastguard Worker
4472*8975f5c5SAndroid Build Coastguard Worker ASSERT(depthStencilRenderTarget->hasResolveAttachment());
4473*8975f5c5SAndroid Build Coastguard Worker ASSERT(depthStencilRenderTarget->isImageTransient());
4474*8975f5c5SAndroid Build Coastguard Worker
4475*8975f5c5SAndroid Build Coastguard Worker if (params.unresolveDepth)
4476*8975f5c5SAndroid Build Coastguard Worker {
4477*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(depthStencilRenderTarget->getResolveDepthOrStencilImageView(
4478*8975f5c5SAndroid Build Coastguard Worker contextVk, VK_IMAGE_ASPECT_DEPTH_BIT, &depthSrcView));
4479*8975f5c5SAndroid Build Coastguard Worker }
4480*8975f5c5SAndroid Build Coastguard Worker
4481*8975f5c5SAndroid Build Coastguard Worker if (params.unresolveStencil)
4482*8975f5c5SAndroid Build Coastguard Worker {
4483*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(depthStencilRenderTarget->getResolveDepthOrStencilImageView(
4484*8975f5c5SAndroid Build Coastguard Worker contextVk, VK_IMAGE_ASPECT_STENCIL_BIT, &stencilSrcView));
4485*8975f5c5SAndroid Build Coastguard Worker }
4486*8975f5c5SAndroid Build Coastguard Worker }
4487*8975f5c5SAndroid Build Coastguard Worker
4488*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineDesc pipelineDesc;
4489*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.initDefaults(contextVk, vk::GraphicsPipelineSubset::Complete,
4490*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineRobustness(),
4491*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineProtectedAccess());
4492*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRasterizationSamples(framebuffer->getSamples());
4493*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRenderPassDesc(framebuffer->getRenderPassDesc());
4494*8975f5c5SAndroid Build Coastguard Worker
4495*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer =
4496*8975f5c5SAndroid Build Coastguard Worker &contextVk->getStartedRenderPassCommands().getCommandBuffer();
4497*8975f5c5SAndroid Build Coastguard Worker
4498*8975f5c5SAndroid Build Coastguard Worker vk::ShaderLibrary &shaderLibrary = contextVk->getShaderLibrary();
4499*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr vertexShader;
4500*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getFullScreenTri_vert(contextVk, 0, &vertexShader));
4501*8975f5c5SAndroid Build Coastguard Worker
4502*8975f5c5SAndroid Build Coastguard Worker // Set dynamic state
4503*8975f5c5SAndroid Build Coastguard Worker VkViewport viewport;
4504*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle completeRenderArea = framebuffer->getRotatedCompleteRenderArea(contextVk);
4505*8975f5c5SAndroid Build Coastguard Worker bool invertViewport = contextVk->isViewportFlipEnabledForDrawFBO();
4506*8975f5c5SAndroid Build Coastguard Worker bool clipSpaceOriginUpperLeft =
4507*8975f5c5SAndroid Build Coastguard Worker contextVk->getState().getClipOrigin() == gl::ClipOrigin::UpperLeft;
4508*8975f5c5SAndroid Build Coastguard Worker gl_vk::GetViewport(completeRenderArea, 0.0f, 1.0f, invertViewport, clipSpaceOriginUpperLeft,
4509*8975f5c5SAndroid Build Coastguard Worker completeRenderArea.height, &viewport);
4510*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setViewport(0, 1, &viewport);
4511*8975f5c5SAndroid Build Coastguard Worker
4512*8975f5c5SAndroid Build Coastguard Worker VkRect2D scissor = gl_vk::GetRect(completeRenderArea);
4513*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setScissor(0, 1, &scissor);
4514*8975f5c5SAndroid Build Coastguard Worker
4515*8975f5c5SAndroid Build Coastguard Worker // When VK_EXT_shader_stencil_export is enabled, the draw call can directly read from the
4516*8975f5c5SAndroid Build Coastguard Worker // stencil buffer and export it. When disabled, a special path is taken after the main
4517*8975f5c5SAndroid Build Coastguard Worker // unresolve draw call.
4518*8975f5c5SAndroid Build Coastguard Worker const bool unresolveStencilWithShaderExport =
4519*8975f5c5SAndroid Build Coastguard Worker params.unresolveStencil && contextVk->getFeatures().supportsShaderStencilExport.enabled;
4520*8975f5c5SAndroid Build Coastguard Worker
4521*8975f5c5SAndroid Build Coastguard Worker const uint32_t colorAttachmentCount = colorIndexVk.get();
4522*8975f5c5SAndroid Build Coastguard Worker const uint32_t depthStencilBindingCount =
4523*8975f5c5SAndroid Build Coastguard Worker (params.unresolveDepth ? 1 : 0) + (unresolveStencilWithShaderExport ? 1 : 0);
4524*8975f5c5SAndroid Build Coastguard Worker const uint32_t totalBindingCount = colorAttachmentCount + depthStencilBindingCount;
4525*8975f5c5SAndroid Build Coastguard Worker
4526*8975f5c5SAndroid Build Coastguard Worker if (totalBindingCount > 0)
4527*8975f5c5SAndroid Build Coastguard Worker {
4528*8975f5c5SAndroid Build Coastguard Worker const Function function = static_cast<Function>(
4529*8975f5c5SAndroid Build Coastguard Worker static_cast<uint32_t>(Function::Unresolve1Attachment) + totalBindingCount - 1);
4530*8975f5c5SAndroid Build Coastguard Worker
4531*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureUnresolveResourcesInitialized(contextVk, function, totalBindingCount));
4532*8975f5c5SAndroid Build Coastguard Worker
4533*8975f5c5SAndroid Build Coastguard Worker if (params.unresolveDepth)
4534*8975f5c5SAndroid Build Coastguard Worker {
4535*8975f5c5SAndroid Build Coastguard Worker SetDepthStateForWrite(renderer, &pipelineDesc);
4536*8975f5c5SAndroid Build Coastguard Worker }
4537*8975f5c5SAndroid Build Coastguard Worker
4538*8975f5c5SAndroid Build Coastguard Worker if (unresolveStencilWithShaderExport)
4539*8975f5c5SAndroid Build Coastguard Worker {
4540*8975f5c5SAndroid Build Coastguard Worker SetStencilStateForWrite(renderer, &pipelineDesc);
4541*8975f5c5SAndroid Build Coastguard Worker }
4542*8975f5c5SAndroid Build Coastguard Worker
4543*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
4544*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, &contextVk->getStartedRenderPassCommands(),
4545*8975f5c5SAndroid Build Coastguard Worker function, &descriptorSet));
4546*8975f5c5SAndroid Build Coastguard Worker
4547*8975f5c5SAndroid Build Coastguard Worker vk::FramebufferAttachmentArray<VkDescriptorImageInfo> inputImageInfo = {};
4548*8975f5c5SAndroid Build Coastguard Worker uint32_t inputBindingIndex = 0;
4549*8975f5c5SAndroid Build Coastguard Worker
4550*8975f5c5SAndroid Build Coastguard Worker if (unresolveStencilWithShaderExport)
4551*8975f5c5SAndroid Build Coastguard Worker {
4552*8975f5c5SAndroid Build Coastguard Worker inputImageInfo[inputBindingIndex].imageView = stencilSrcView->getHandle();
4553*8975f5c5SAndroid Build Coastguard Worker inputImageInfo[inputBindingIndex].imageLayout =
4554*8975f5c5SAndroid Build Coastguard Worker VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4555*8975f5c5SAndroid Build Coastguard Worker ++inputBindingIndex;
4556*8975f5c5SAndroid Build Coastguard Worker }
4557*8975f5c5SAndroid Build Coastguard Worker if (params.unresolveDepth)
4558*8975f5c5SAndroid Build Coastguard Worker {
4559*8975f5c5SAndroid Build Coastguard Worker inputImageInfo[inputBindingIndex].imageView = depthSrcView->getHandle();
4560*8975f5c5SAndroid Build Coastguard Worker inputImageInfo[inputBindingIndex].imageLayout =
4561*8975f5c5SAndroid Build Coastguard Worker VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4562*8975f5c5SAndroid Build Coastguard Worker ++inputBindingIndex;
4563*8975f5c5SAndroid Build Coastguard Worker }
4564*8975f5c5SAndroid Build Coastguard Worker
4565*8975f5c5SAndroid Build Coastguard Worker for (uint32_t attachmentIndex = 0; attachmentIndex < colorAttachmentCount;
4566*8975f5c5SAndroid Build Coastguard Worker ++attachmentIndex)
4567*8975f5c5SAndroid Build Coastguard Worker {
4568*8975f5c5SAndroid Build Coastguard Worker inputImageInfo[inputBindingIndex].imageView =
4569*8975f5c5SAndroid Build Coastguard Worker colorSrcView[attachmentIndex]->getHandle();
4570*8975f5c5SAndroid Build Coastguard Worker inputImageInfo[inputBindingIndex].imageLayout =
4571*8975f5c5SAndroid Build Coastguard Worker VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4572*8975f5c5SAndroid Build Coastguard Worker ++inputBindingIndex;
4573*8975f5c5SAndroid Build Coastguard Worker }
4574*8975f5c5SAndroid Build Coastguard Worker
4575*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfo = {};
4576*8975f5c5SAndroid Build Coastguard Worker writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
4577*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstSet = descriptorSet;
4578*8975f5c5SAndroid Build Coastguard Worker writeInfo.dstBinding = 0;
4579*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorCount = totalBindingCount;
4580*8975f5c5SAndroid Build Coastguard Worker writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
4581*8975f5c5SAndroid Build Coastguard Worker writeInfo.pImageInfo = inputImageInfo.data();
4582*8975f5c5SAndroid Build Coastguard Worker
4583*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 1, &writeInfo, 0, nullptr);
4584*8975f5c5SAndroid Build Coastguard Worker
4585*8975f5c5SAndroid Build Coastguard Worker gl::DrawBuffersArray<UnresolveColorAttachmentType> colorAttachmentTypes;
4586*8975f5c5SAndroid Build Coastguard Worker uint32_t flags = GetUnresolveFlags(colorAttachmentCount, colorSrc, params.unresolveDepth,
4587*8975f5c5SAndroid Build Coastguard Worker unresolveStencilWithShaderExport, &colorAttachmentTypes);
4588*8975f5c5SAndroid Build Coastguard Worker
4589*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr &fragmentShader = mUnresolveFragShaders[flags];
4590*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(GetUnresolveFrag(contextVk, colorAttachmentCount, colorAttachmentTypes,
4591*8975f5c5SAndroid Build Coastguard Worker params.unresolveDepth, params.unresolveStencil,
4592*8975f5c5SAndroid Build Coastguard Worker &fragmentShader));
4593*8975f5c5SAndroid Build Coastguard Worker
4594*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupGraphicsProgram(contextVk, function, vertexShader, fragmentShader,
4595*8975f5c5SAndroid Build Coastguard Worker &mUnresolve[flags], &pipelineDesc, descriptorSet, nullptr, 0,
4596*8975f5c5SAndroid Build Coastguard Worker commandBuffer));
4597*8975f5c5SAndroid Build Coastguard Worker
4598*8975f5c5SAndroid Build Coastguard Worker if (params.unresolveDepth)
4599*8975f5c5SAndroid Build Coastguard Worker {
4600*8975f5c5SAndroid Build Coastguard Worker SetDepthDynamicStateForWrite(renderer, commandBuffer);
4601*8975f5c5SAndroid Build Coastguard Worker }
4602*8975f5c5SAndroid Build Coastguard Worker else
4603*8975f5c5SAndroid Build Coastguard Worker {
4604*8975f5c5SAndroid Build Coastguard Worker SetDepthDynamicStateForUnused(renderer, commandBuffer);
4605*8975f5c5SAndroid Build Coastguard Worker }
4606*8975f5c5SAndroid Build Coastguard Worker
4607*8975f5c5SAndroid Build Coastguard Worker if (unresolveStencilWithShaderExport)
4608*8975f5c5SAndroid Build Coastguard Worker {
4609*8975f5c5SAndroid Build Coastguard Worker constexpr uint8_t kCompleteMask = 0xFF;
4610*8975f5c5SAndroid Build Coastguard Worker constexpr uint8_t kUnusedReference = 0x00;
4611*8975f5c5SAndroid Build Coastguard Worker
4612*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilCompareMask(kCompleteMask, kCompleteMask);
4613*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilWriteMask(kCompleteMask, kCompleteMask);
4614*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilReference(kUnusedReference, kUnusedReference);
4615*8975f5c5SAndroid Build Coastguard Worker
4616*8975f5c5SAndroid Build Coastguard Worker SetStencilDynamicStateForWrite(renderer, commandBuffer);
4617*8975f5c5SAndroid Build Coastguard Worker }
4618*8975f5c5SAndroid Build Coastguard Worker else
4619*8975f5c5SAndroid Build Coastguard Worker {
4620*8975f5c5SAndroid Build Coastguard Worker SetStencilDynamicStateForUnused(renderer, commandBuffer);
4621*8975f5c5SAndroid Build Coastguard Worker }
4622*8975f5c5SAndroid Build Coastguard Worker
4623*8975f5c5SAndroid Build Coastguard Worker // This draw call is made before ContextVk gets a chance to start the occlusion query. As
4624*8975f5c5SAndroid Build Coastguard Worker // such, occlusion queries are not enabled.
4625*8975f5c5SAndroid Build Coastguard Worker commandBuffer->draw(3, 0);
4626*8975f5c5SAndroid Build Coastguard Worker }
4627*8975f5c5SAndroid Build Coastguard Worker
4628*8975f5c5SAndroid Build Coastguard Worker // If stencil needs to be unresolved, but stencil export is not supported, set each bit of
4629*8975f5c5SAndroid Build Coastguard Worker // stencil by adjusting the mask and controlling the output with `discard;` in the shader. This
4630*8975f5c5SAndroid Build Coastguard Worker // requires that the stencil is cleared to 0 beforehand.
4631*8975f5c5SAndroid Build Coastguard Worker if (params.unresolveStencil && !unresolveStencilWithShaderExport)
4632*8975f5c5SAndroid Build Coastguard Worker {
4633*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureExportStencilResourcesInitialized(contextVk));
4634*8975f5c5SAndroid Build Coastguard Worker
4635*8975f5c5SAndroid Build Coastguard Worker // Disable color and depth output, and only let stencil through.
4636*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setColorWriteMasks(0, gl::DrawBufferMask(), gl::DrawBufferMask());
4637*8975f5c5SAndroid Build Coastguard Worker
4638*8975f5c5SAndroid Build Coastguard Worker SetDepthStateForUnused(renderer, &pipelineDesc);
4639*8975f5c5SAndroid Build Coastguard Worker SetStencilStateForWrite(renderer, &pipelineDesc);
4640*8975f5c5SAndroid Build Coastguard Worker
4641*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr exportStencilShader;
4642*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getExportStencil_frag(contextVk, 0, &exportStencilShader));
4643*8975f5c5SAndroid Build Coastguard Worker
4644*8975f5c5SAndroid Build Coastguard Worker // A new descriptor set is needed to match the layout of the ExportStencil program.
4645*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet exportStencilDescriptorSet;
4646*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, &contextVk->getStartedRenderPassCommands(),
4647*8975f5c5SAndroid Build Coastguard Worker Function::ExportStencil, &exportStencilDescriptorSet));
4648*8975f5c5SAndroid Build Coastguard Worker
4649*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo stencilImageInfo = {};
4650*8975f5c5SAndroid Build Coastguard Worker stencilImageInfo.imageView = stencilSrcView->getHandle();
4651*8975f5c5SAndroid Build Coastguard Worker stencilImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4652*8975f5c5SAndroid Build Coastguard Worker
4653*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet stencilWriteInfo = {};
4654*8975f5c5SAndroid Build Coastguard Worker stencilWriteInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
4655*8975f5c5SAndroid Build Coastguard Worker stencilWriteInfo.dstSet = exportStencilDescriptorSet;
4656*8975f5c5SAndroid Build Coastguard Worker stencilWriteInfo.dstBinding = 0;
4657*8975f5c5SAndroid Build Coastguard Worker stencilWriteInfo.descriptorCount = 1;
4658*8975f5c5SAndroid Build Coastguard Worker stencilWriteInfo.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
4659*8975f5c5SAndroid Build Coastguard Worker stencilWriteInfo.pImageInfo = &stencilImageInfo;
4660*8975f5c5SAndroid Build Coastguard Worker
4661*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 1, &stencilWriteInfo, 0, nullptr);
4662*8975f5c5SAndroid Build Coastguard Worker
4663*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupGraphicsProgram(contextVk, Function::ExportStencil, vertexShader,
4664*8975f5c5SAndroid Build Coastguard Worker exportStencilShader, &mExportStencil, &pipelineDesc,
4665*8975f5c5SAndroid Build Coastguard Worker exportStencilDescriptorSet, nullptr, 0, commandBuffer));
4666*8975f5c5SAndroid Build Coastguard Worker
4667*8975f5c5SAndroid Build Coastguard Worker SetDepthDynamicStateForUnused(renderer, commandBuffer);
4668*8975f5c5SAndroid Build Coastguard Worker SetStencilDynamicStateForWrite(renderer, commandBuffer);
4669*8975f5c5SAndroid Build Coastguard Worker
4670*8975f5c5SAndroid Build Coastguard Worker constexpr uint8_t kCompareMask = 0xFF;
4671*8975f5c5SAndroid Build Coastguard Worker constexpr uint8_t kReference = 0xFF;
4672*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilCompareMask(kCompareMask, kCompareMask);
4673*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilReference(kReference, kReference);
4674*8975f5c5SAndroid Build Coastguard Worker
4675*8975f5c5SAndroid Build Coastguard Worker // Set each bit in a different draw call. This is not terribly efficient, but manages to
4676*8975f5c5SAndroid Build Coastguard Worker // keep the transient multisampled stencil data on tile and avoids having to write it back
4677*8975f5c5SAndroid Build Coastguard Worker // to memory / allocate memory for it.
4678*8975f5c5SAndroid Build Coastguard Worker for (uint32_t bit = 0; bit < 8; ++bit)
4679*8975f5c5SAndroid Build Coastguard Worker {
4680*8975f5c5SAndroid Build Coastguard Worker const uint32_t writeMask = 1u << bit;
4681*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setStencilWriteMask(writeMask, writeMask);
4682*8975f5c5SAndroid Build Coastguard Worker
4683*8975f5c5SAndroid Build Coastguard Worker ExportStencilShaderParams shaderParams;
4684*8975f5c5SAndroid Build Coastguard Worker shaderParams.bit = bit;
4685*8975f5c5SAndroid Build Coastguard Worker
4686*8975f5c5SAndroid Build Coastguard Worker commandBuffer->pushConstants(
4687*8975f5c5SAndroid Build Coastguard Worker *mPipelineLayouts[Function::ExportStencil], VK_SHADER_STAGE_FRAGMENT_BIT, 0,
4688*8975f5c5SAndroid Build Coastguard Worker /*static_cast<uint32_t>*/ (sizeof(shaderParams)), &shaderParams);
4689*8975f5c5SAndroid Build Coastguard Worker
4690*8975f5c5SAndroid Build Coastguard Worker commandBuffer->draw(3, 0);
4691*8975f5c5SAndroid Build Coastguard Worker }
4692*8975f5c5SAndroid Build Coastguard Worker }
4693*8975f5c5SAndroid Build Coastguard Worker
4694*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4695*8975f5c5SAndroid Build Coastguard Worker }
4696*8975f5c5SAndroid Build Coastguard Worker
drawOverlay(ContextVk * contextVk,vk::BufferHelper * textWidgetsBuffer,vk::BufferHelper * graphWidgetsBuffer,vk::ImageHelper * font,const vk::ImageView * fontView,vk::ImageHelper * dst,const vk::ImageView * destView,const OverlayDrawParameters & params)4697*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::drawOverlay(ContextVk *contextVk,
4698*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *textWidgetsBuffer,
4699*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *graphWidgetsBuffer,
4700*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *font,
4701*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *fontView,
4702*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *dst,
4703*8975f5c5SAndroid Build Coastguard Worker const vk::ImageView *destView,
4704*8975f5c5SAndroid Build Coastguard Worker const OverlayDrawParameters ¶ms)
4705*8975f5c5SAndroid Build Coastguard Worker {
4706*8975f5c5SAndroid Build Coastguard Worker vk::Renderer *renderer = contextVk->getRenderer();
4707*8975f5c5SAndroid Build Coastguard Worker
4708*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureOverlayDrawResourcesInitialized(contextVk));
4709*8975f5c5SAndroid Build Coastguard Worker
4710*8975f5c5SAndroid Build Coastguard Worker OverlayDrawShaderParams shaderParams;
4711*8975f5c5SAndroid Build Coastguard Worker shaderParams.viewportSize[0] = dst->getExtents().width;
4712*8975f5c5SAndroid Build Coastguard Worker shaderParams.viewportSize[1] = dst->getExtents().height;
4713*8975f5c5SAndroid Build Coastguard Worker shaderParams.isText = false;
4714*8975f5c5SAndroid Build Coastguard Worker shaderParams.rotateXY = params.rotateXY;
4715*8975f5c5SAndroid Build Coastguard Worker if (params.rotateXY)
4716*8975f5c5SAndroid Build Coastguard Worker {
4717*8975f5c5SAndroid Build Coastguard Worker std::swap(shaderParams.viewportSize[0], shaderParams.viewportSize[1]);
4718*8975f5c5SAndroid Build Coastguard Worker }
4719*8975f5c5SAndroid Build Coastguard Worker
4720*8975f5c5SAndroid Build Coastguard Worker ASSERT(dst->getLevelCount() == 1 && dst->getLayerCount() == 1 &&
4721*8975f5c5SAndroid Build Coastguard Worker dst->getFirstAllocatedLevel() == gl::LevelIndex(0));
4722*8975f5c5SAndroid Build Coastguard Worker
4723*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassDesc renderPassDesc;
4724*8975f5c5SAndroid Build Coastguard Worker renderPassDesc.setSamples(1);
4725*8975f5c5SAndroid Build Coastguard Worker renderPassDesc.packColorAttachment(0, dst->getActualFormatID());
4726*8975f5c5SAndroid Build Coastguard Worker
4727*8975f5c5SAndroid Build Coastguard Worker vk::GraphicsPipelineDesc pipelineDesc;
4728*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.initDefaults(contextVk, vk::GraphicsPipelineSubset::Complete,
4729*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineRobustness(),
4730*8975f5c5SAndroid Build Coastguard Worker contextVk->pipelineProtectedAccess());
4731*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setRenderPassDesc(renderPassDesc);
4732*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setTopology(gl::PrimitiveMode::TriangleStrip);
4733*8975f5c5SAndroid Build Coastguard Worker pipelineDesc.setSingleBlend(0, true, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_SRC_ALPHA,
4734*8975f5c5SAndroid Build Coastguard Worker VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA);
4735*8975f5c5SAndroid Build Coastguard Worker
4736*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle renderArea;
4737*8975f5c5SAndroid Build Coastguard Worker renderArea.x = 0;
4738*8975f5c5SAndroid Build Coastguard Worker renderArea.y = 0;
4739*8975f5c5SAndroid Build Coastguard Worker renderArea.width = shaderParams.viewportSize[0];
4740*8975f5c5SAndroid Build Coastguard Worker renderArea.height = shaderParams.viewportSize[1];
4741*8975f5c5SAndroid Build Coastguard Worker
4742*8975f5c5SAndroid Build Coastguard Worker // A potential optimization is to reuse the already open render pass if it belongs to the
4743*8975f5c5SAndroid Build Coastguard Worker // swapchain.
4744*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBuffer *commandBuffer;
4745*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(startRenderPass(contextVk, dst, destView, renderPassDesc, renderArea,
4746*8975f5c5SAndroid Build Coastguard Worker VK_IMAGE_ASPECT_COLOR_BIT, nullptr,
4747*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassSource::DefaultFramebuffer, &commandBuffer));
4748*8975f5c5SAndroid Build Coastguard Worker
4749*8975f5c5SAndroid Build Coastguard Worker vk::RenderPassCommandBufferHelper *commandBufferHelper =
4750*8975f5c5SAndroid Build Coastguard Worker &contextVk->getStartedRenderPassCommands();
4751*8975f5c5SAndroid Build Coastguard Worker
4752*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
4753*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, commandBufferHelper, Function::OverlayDraw,
4754*8975f5c5SAndroid Build Coastguard Worker &descriptorSet));
4755*8975f5c5SAndroid Build Coastguard Worker
4756*8975f5c5SAndroid Build Coastguard Worker UpdateColorAccess(contextVk, MakeColorBufferMask(0), MakeColorBufferMask(0));
4757*8975f5c5SAndroid Build Coastguard Worker
4758*8975f5c5SAndroid Build Coastguard Worker commandBufferHelper->retainResource(textWidgetsBuffer);
4759*8975f5c5SAndroid Build Coastguard Worker commandBufferHelper->retainResource(graphWidgetsBuffer);
4760*8975f5c5SAndroid Build Coastguard Worker contextVk->onImageRenderPassRead(VK_IMAGE_ASPECT_COLOR_BIT,
4761*8975f5c5SAndroid Build Coastguard Worker vk::ImageLayout::FragmentShaderReadOnly, font);
4762*8975f5c5SAndroid Build Coastguard Worker contextVk->onImageRenderPassWrite(gl::LevelIndex(0), 0, 1, VK_IMAGE_ASPECT_COLOR_BIT,
4763*8975f5c5SAndroid Build Coastguard Worker vk::ImageLayout::ColorWrite, dst);
4764*8975f5c5SAndroid Build Coastguard Worker
4765*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo imageInfo = {};
4766*8975f5c5SAndroid Build Coastguard Worker imageInfo.imageView = fontView->getHandle();
4767*8975f5c5SAndroid Build Coastguard Worker imageInfo.imageLayout = font->getCurrentLayout(renderer);
4768*8975f5c5SAndroid Build Coastguard Worker
4769*8975f5c5SAndroid Build Coastguard Worker VkDescriptorBufferInfo bufferInfos[2] = {};
4770*8975f5c5SAndroid Build Coastguard Worker bufferInfos[0].buffer = textWidgetsBuffer->getBuffer().getHandle();
4771*8975f5c5SAndroid Build Coastguard Worker bufferInfos[0].offset = textWidgetsBuffer->getOffset();
4772*8975f5c5SAndroid Build Coastguard Worker bufferInfos[0].range = textWidgetsBuffer->getSize();
4773*8975f5c5SAndroid Build Coastguard Worker
4774*8975f5c5SAndroid Build Coastguard Worker bufferInfos[1].buffer = graphWidgetsBuffer->getBuffer().getHandle();
4775*8975f5c5SAndroid Build Coastguard Worker bufferInfos[1].offset = graphWidgetsBuffer->getOffset();
4776*8975f5c5SAndroid Build Coastguard Worker bufferInfos[1].range = graphWidgetsBuffer->getSize();
4777*8975f5c5SAndroid Build Coastguard Worker
4778*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfos[3] = {};
4779*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
4780*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstSet = descriptorSet;
4781*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstBinding = kOverlayDrawTextWidgetsBinding;
4782*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorCount = 1;
4783*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
4784*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].pBufferInfo = &bufferInfos[0];
4785*8975f5c5SAndroid Build Coastguard Worker
4786*8975f5c5SAndroid Build Coastguard Worker writeInfos[1] = writeInfos[0];
4787*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].dstBinding = kOverlayDrawGraphWidgetsBinding;
4788*8975f5c5SAndroid Build Coastguard Worker writeInfos[1].pBufferInfo = &bufferInfos[1];
4789*8975f5c5SAndroid Build Coastguard Worker
4790*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
4791*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].dstSet = descriptorSet;
4792*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].dstBinding = kOverlayDrawFontBinding;
4793*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].descriptorCount = 1;
4794*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
4795*8975f5c5SAndroid Build Coastguard Worker writeInfos[2].pImageInfo = &imageInfo;
4796*8975f5c5SAndroid Build Coastguard Worker
4797*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 3, writeInfos, 0, nullptr);
4798*8975f5c5SAndroid Build Coastguard Worker
4799*8975f5c5SAndroid Build Coastguard Worker vk::ShaderLibrary &shaderLibrary = contextVk->getShaderLibrary();
4800*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr vertexShader;
4801*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr fragmentShader;
4802*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getOverlayDraw_vert(contextVk, 0, &vertexShader));
4803*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(shaderLibrary.getOverlayDraw_frag(contextVk, 0, &fragmentShader));
4804*8975f5c5SAndroid Build Coastguard Worker
4805*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupGraphicsProgram(contextVk, Function::OverlayDraw, vertexShader, fragmentShader,
4806*8975f5c5SAndroid Build Coastguard Worker &mOverlayDraw, &pipelineDesc, descriptorSet, nullptr, 0,
4807*8975f5c5SAndroid Build Coastguard Worker commandBuffer));
4808*8975f5c5SAndroid Build Coastguard Worker
4809*8975f5c5SAndroid Build Coastguard Worker // Set dynamic state
4810*8975f5c5SAndroid Build Coastguard Worker VkViewport viewport;
4811*8975f5c5SAndroid Build Coastguard Worker gl_vk::GetViewport(renderArea, 0.0f, 1.0f, false, false, dst->getExtents().height, &viewport);
4812*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setViewport(0, 1, &viewport);
4813*8975f5c5SAndroid Build Coastguard Worker
4814*8975f5c5SAndroid Build Coastguard Worker VkRect2D scissor = gl_vk::GetRect(renderArea);
4815*8975f5c5SAndroid Build Coastguard Worker commandBuffer->setScissor(0, 1, &scissor);
4816*8975f5c5SAndroid Build Coastguard Worker
4817*8975f5c5SAndroid Build Coastguard Worker SetDepthDynamicStateForUnused(renderer, commandBuffer);
4818*8975f5c5SAndroid Build Coastguard Worker SetStencilDynamicStateForUnused(renderer, commandBuffer);
4819*8975f5c5SAndroid Build Coastguard Worker
4820*8975f5c5SAndroid Build Coastguard Worker // Draw all the graph widgets.
4821*8975f5c5SAndroid Build Coastguard Worker if (params.graphWidgetCount > 0)
4822*8975f5c5SAndroid Build Coastguard Worker {
4823*8975f5c5SAndroid Build Coastguard Worker shaderParams.isText = false;
4824*8975f5c5SAndroid Build Coastguard Worker commandBuffer->pushConstants(*mPipelineLayouts[Function::OverlayDraw],
4825*8975f5c5SAndroid Build Coastguard Worker VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0,
4826*8975f5c5SAndroid Build Coastguard Worker sizeof(shaderParams), &shaderParams);
4827*8975f5c5SAndroid Build Coastguard Worker commandBuffer->drawInstanced(4, params.graphWidgetCount, 0);
4828*8975f5c5SAndroid Build Coastguard Worker }
4829*8975f5c5SAndroid Build Coastguard Worker // Draw all the text widgets.
4830*8975f5c5SAndroid Build Coastguard Worker if (params.textWidgetCount > 0)
4831*8975f5c5SAndroid Build Coastguard Worker {
4832*8975f5c5SAndroid Build Coastguard Worker shaderParams.isText = true;
4833*8975f5c5SAndroid Build Coastguard Worker commandBuffer->pushConstants(*mPipelineLayouts[Function::OverlayDraw],
4834*8975f5c5SAndroid Build Coastguard Worker VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0,
4835*8975f5c5SAndroid Build Coastguard Worker sizeof(shaderParams), &shaderParams);
4836*8975f5c5SAndroid Build Coastguard Worker commandBuffer->drawInstanced(4, params.textWidgetCount, 0);
4837*8975f5c5SAndroid Build Coastguard Worker }
4838*8975f5c5SAndroid Build Coastguard Worker
4839*8975f5c5SAndroid Build Coastguard Worker // Overlay is always drawn as the last render pass before present. Automatically move the
4840*8975f5c5SAndroid Build Coastguard Worker // layout to PresentSrc.
4841*8975f5c5SAndroid Build Coastguard Worker contextVk->onColorDraw(gl::LevelIndex(0), 0, 1, dst, nullptr, {}, vk::PackedAttachmentIndex(0));
4842*8975f5c5SAndroid Build Coastguard Worker if (contextVk->getFeatures().supportsPresentation.enabled &&
4843*8975f5c5SAndroid Build Coastguard Worker !contextVk->getFeatures().preferDynamicRendering.enabled)
4844*8975f5c5SAndroid Build Coastguard Worker {
4845*8975f5c5SAndroid Build Coastguard Worker contextVk->getStartedRenderPassCommands().setImageOptimizeForPresent(dst);
4846*8975f5c5SAndroid Build Coastguard Worker contextVk->finalizeImageLayout(dst, {});
4847*8975f5c5SAndroid Build Coastguard Worker }
4848*8975f5c5SAndroid Build Coastguard Worker
4849*8975f5c5SAndroid Build Coastguard Worker // Close the render pass for this temporary framebuffer.
4850*8975f5c5SAndroid Build Coastguard Worker return contextVk->flushCommandsAndEndRenderPass(
4851*8975f5c5SAndroid Build Coastguard Worker RenderPassClosureReason::TemporaryForOverlayDraw);
4852*8975f5c5SAndroid Build Coastguard Worker }
4853*8975f5c5SAndroid Build Coastguard Worker
generateFragmentShadingRate(ContextVk * contextVk,vk::ImageHelper * shadingRateAttachmentImageHelper,vk::ImageViewHelper * shadingRateAttachmentImageViewHelper,const GenerateFragmentShadingRateParameters & shadingRateParameters)4854*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::generateFragmentShadingRate(
4855*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
4856*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *shadingRateAttachmentImageHelper,
4857*8975f5c5SAndroid Build Coastguard Worker vk::ImageViewHelper *shadingRateAttachmentImageViewHelper,
4858*8975f5c5SAndroid Build Coastguard Worker const GenerateFragmentShadingRateParameters &shadingRateParameters)
4859*8975f5c5SAndroid Build Coastguard Worker {
4860*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureGenerateFragmentShadingRateResourcesInitialized(contextVk));
4861*8975f5c5SAndroid Build Coastguard Worker
4862*8975f5c5SAndroid Build Coastguard Worker // Each workgroup processes an 8x8 tile of the image.
4863*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kPixelWorkgroupSize = 8;
4864*8975f5c5SAndroid Build Coastguard Worker const uint32_t workGroupX =
4865*8975f5c5SAndroid Build Coastguard Worker UnsignedCeilDivide(shadingRateParameters.attachmentWidth, kPixelWorkgroupSize);
4866*8975f5c5SAndroid Build Coastguard Worker const uint32_t workGroupY =
4867*8975f5c5SAndroid Build Coastguard Worker UnsignedCeilDivide(shadingRateParameters.attachmentHeight, kPixelWorkgroupSize);
4868*8975f5c5SAndroid Build Coastguard Worker
4869*8975f5c5SAndroid Build Coastguard Worker // Setup compute shader
4870*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper;
4871*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access = {};
4872*8975f5c5SAndroid Build Coastguard Worker
4873*8975f5c5SAndroid Build Coastguard Worker // Fragment shading rate image will always have 1 layer.
4874*8975f5c5SAndroid Build Coastguard Worker access.onImageComputeShaderWrite(shadingRateAttachmentImageHelper->getFirstAllocatedLevel(),
4875*8975f5c5SAndroid Build Coastguard Worker shadingRateAttachmentImageHelper->getLevelCount(), 0,
4876*8975f5c5SAndroid Build Coastguard Worker shadingRateAttachmentImageHelper->getLayerCount(),
4877*8975f5c5SAndroid Build Coastguard Worker shadingRateAttachmentImageHelper->getAspectFlags(),
4878*8975f5c5SAndroid Build Coastguard Worker shadingRateAttachmentImageHelper);
4879*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBufferHelper(access, &commandBufferHelper));
4880*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet descriptorSet;
4881*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(allocateDescriptorSet(contextVk, commandBufferHelper,
4882*8975f5c5SAndroid Build Coastguard Worker Function::GenerateFragmentShadingRate, &descriptorSet));
4883*8975f5c5SAndroid Build Coastguard Worker VkDescriptorImageInfo destShadingRateImage = {};
4884*8975f5c5SAndroid Build Coastguard Worker destShadingRateImage.imageView =
4885*8975f5c5SAndroid Build Coastguard Worker shadingRateAttachmentImageViewHelper->getFragmentShadingRateImageView().getHandle();
4886*8975f5c5SAndroid Build Coastguard Worker destShadingRateImage.imageLayout =
4887*8975f5c5SAndroid Build Coastguard Worker shadingRateAttachmentImageHelper->getCurrentLayout(contextVk->getRenderer());
4888*8975f5c5SAndroid Build Coastguard Worker destShadingRateImage.sampler = mPointSampler.getHandle();
4889*8975f5c5SAndroid Build Coastguard Worker VkWriteDescriptorSet writeInfos[1] = {};
4890*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
4891*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstSet = descriptorSet;
4892*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].dstBinding = kGenerateFragmentShadingRateAttachmentBinding;
4893*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorCount = 1;
4894*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
4895*8975f5c5SAndroid Build Coastguard Worker writeInfos[0].pImageInfo = &destShadingRateImage;
4896*8975f5c5SAndroid Build Coastguard Worker
4897*8975f5c5SAndroid Build Coastguard Worker vkUpdateDescriptorSets(contextVk->getDevice(), 1, writeInfos, 0, nullptr);
4898*8975f5c5SAndroid Build Coastguard Worker
4899*8975f5c5SAndroid Build Coastguard Worker vk::ShaderModulePtr computeShader;
4900*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getShaderLibrary().getGenerateFragmentShadingRate_comp(contextVk, 0,
4901*8975f5c5SAndroid Build Coastguard Worker &computeShader));
4902*8975f5c5SAndroid Build Coastguard Worker
4903*8975f5c5SAndroid Build Coastguard Worker // Record the command
4904*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
4905*8975f5c5SAndroid Build Coastguard Worker commandBuffer = &commandBufferHelper->getCommandBuffer();
4906*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setupComputeProgram(contextVk, Function::GenerateFragmentShadingRate, computeShader,
4907*8975f5c5SAndroid Build Coastguard Worker &mGenerateFragmentShadingRateAttachment, descriptorSet,
4908*8975f5c5SAndroid Build Coastguard Worker &shadingRateParameters, sizeof(shadingRateParameters),
4909*8975f5c5SAndroid Build Coastguard Worker commandBufferHelper));
4910*8975f5c5SAndroid Build Coastguard Worker commandBuffer->dispatch(workGroupX, workGroupY, 1);
4911*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4912*8975f5c5SAndroid Build Coastguard Worker }
4913*8975f5c5SAndroid Build Coastguard Worker
allocateDescriptorSetWithLayout(ContextVk * contextVk,vk::CommandBufferHelperCommon * commandBufferHelper,vk::DynamicDescriptorPool & descriptorPool,const vk::DescriptorSetLayout & descriptorSetLayout,VkDescriptorSet * descriptorSetOut)4914*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::allocateDescriptorSetWithLayout(
4915*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
4916*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferHelperCommon *commandBufferHelper,
4917*8975f5c5SAndroid Build Coastguard Worker vk::DynamicDescriptorPool &descriptorPool,
4918*8975f5c5SAndroid Build Coastguard Worker const vk::DescriptorSetLayout &descriptorSetLayout,
4919*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet *descriptorSetOut)
4920*8975f5c5SAndroid Build Coastguard Worker {
4921*8975f5c5SAndroid Build Coastguard Worker vk::DescriptorSetPointer descriptorSet;
4922*8975f5c5SAndroid Build Coastguard Worker
4923*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(descriptorPool.allocateDescriptorSet(contextVk, descriptorSetLayout, &descriptorSet));
4924*8975f5c5SAndroid Build Coastguard Worker
4925*8975f5c5SAndroid Build Coastguard Worker // Retain the individual descriptorSet to the command buffer.
4926*8975f5c5SAndroid Build Coastguard Worker commandBufferHelper->retainResource(descriptorSet.get());
4927*8975f5c5SAndroid Build Coastguard Worker
4928*8975f5c5SAndroid Build Coastguard Worker *descriptorSetOut = descriptorSet->getDescriptorSet();
4929*8975f5c5SAndroid Build Coastguard Worker
4930*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4931*8975f5c5SAndroid Build Coastguard Worker }
4932*8975f5c5SAndroid Build Coastguard Worker
allocateDescriptorSet(ContextVk * contextVk,vk::CommandBufferHelperCommon * commandBufferHelper,Function function,VkDescriptorSet * descriptorSetOut)4933*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::allocateDescriptorSet(ContextVk *contextVk,
4934*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferHelperCommon *commandBufferHelper,
4935*8975f5c5SAndroid Build Coastguard Worker Function function,
4936*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet *descriptorSetOut)
4937*8975f5c5SAndroid Build Coastguard Worker {
4938*8975f5c5SAndroid Build Coastguard Worker return allocateDescriptorSetWithLayout(
4939*8975f5c5SAndroid Build Coastguard Worker contextVk, commandBufferHelper, mDescriptorPools[function],
4940*8975f5c5SAndroid Build Coastguard Worker *mDescriptorSetLayouts[function][DescriptorSetIndex::Internal], descriptorSetOut);
4941*8975f5c5SAndroid Build Coastguard Worker }
4942*8975f5c5SAndroid Build Coastguard Worker
allocateDescriptorSetForImageCopyWithSampler(ContextVk * contextVk,vk::CommandBufferHelperCommon * commandBufferHelper,const vk::SamplerDesc & samplerDesc,VkDescriptorSet * descriptorSetOut)4943*8975f5c5SAndroid Build Coastguard Worker angle::Result UtilsVk::allocateDescriptorSetForImageCopyWithSampler(
4944*8975f5c5SAndroid Build Coastguard Worker ContextVk *contextVk,
4945*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferHelperCommon *commandBufferHelper,
4946*8975f5c5SAndroid Build Coastguard Worker const vk::SamplerDesc &samplerDesc,
4947*8975f5c5SAndroid Build Coastguard Worker VkDescriptorSet *descriptorSetOut)
4948*8975f5c5SAndroid Build Coastguard Worker {
4949*8975f5c5SAndroid Build Coastguard Worker return allocateDescriptorSetWithLayout(
4950*8975f5c5SAndroid Build Coastguard Worker contextVk, commandBufferHelper, mImageCopyWithSamplerDescriptorPools[samplerDesc],
4951*8975f5c5SAndroid Build Coastguard Worker *mImageCopyWithSamplerDescriptorSetLayouts[samplerDesc][DescriptorSetIndex::Internal],
4952*8975f5c5SAndroid Build Coastguard Worker descriptorSetOut);
4953*8975f5c5SAndroid Build Coastguard Worker }
4954*8975f5c5SAndroid Build Coastguard Worker
ClearFramebufferParameters()4955*8975f5c5SAndroid Build Coastguard Worker UtilsVk::ClearFramebufferParameters::ClearFramebufferParameters()
4956*8975f5c5SAndroid Build Coastguard Worker : clearColor(false),
4957*8975f5c5SAndroid Build Coastguard Worker clearDepth(false),
4958*8975f5c5SAndroid Build Coastguard Worker clearStencil(false),
4959*8975f5c5SAndroid Build Coastguard Worker stencilMask(0),
4960*8975f5c5SAndroid Build Coastguard Worker colorMaskFlags(0),
4961*8975f5c5SAndroid Build Coastguard Worker colorAttachmentIndexGL(0),
4962*8975f5c5SAndroid Build Coastguard Worker colorFormat(nullptr),
4963*8975f5c5SAndroid Build Coastguard Worker colorClearValue{},
4964*8975f5c5SAndroid Build Coastguard Worker depthStencilClearValue{}
4965*8975f5c5SAndroid Build Coastguard Worker {}
4966*8975f5c5SAndroid Build Coastguard Worker
4967*8975f5c5SAndroid Build Coastguard Worker // LineLoopHelper implementation.
LineLoopHelper(vk::Renderer * renderer)4968*8975f5c5SAndroid Build Coastguard Worker LineLoopHelper::LineLoopHelper(vk::Renderer *renderer) {}
4969*8975f5c5SAndroid Build Coastguard Worker LineLoopHelper::~LineLoopHelper() = default;
4970*8975f5c5SAndroid Build Coastguard Worker
getIndexBufferForDrawArrays(ContextVk * contextVk,uint32_t clampedVertexCount,GLint firstVertex,vk::BufferHelper ** bufferOut)4971*8975f5c5SAndroid Build Coastguard Worker angle::Result LineLoopHelper::getIndexBufferForDrawArrays(ContextVk *contextVk,
4972*8975f5c5SAndroid Build Coastguard Worker uint32_t clampedVertexCount,
4973*8975f5c5SAndroid Build Coastguard Worker GLint firstVertex,
4974*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper **bufferOut)
4975*8975f5c5SAndroid Build Coastguard Worker {
4976*8975f5c5SAndroid Build Coastguard Worker size_t allocateBytes = sizeof(uint32_t) * (static_cast<size_t>(clampedVertexCount) + 1);
4977*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->initBufferForVertexConversion(&mDynamicIndexBuffer, allocateBytes,
4978*8975f5c5SAndroid Build Coastguard Worker vk::MemoryHostVisibility::Visible));
4979*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *indexBuffer = mDynamicIndexBuffer.getBuffer();
4980*8975f5c5SAndroid Build Coastguard Worker uint32_t *indices = reinterpret_cast<uint32_t *>(indexBuffer->getMappedMemory());
4981*8975f5c5SAndroid Build Coastguard Worker
4982*8975f5c5SAndroid Build Coastguard Worker // Note: there could be an overflow in this addition.
4983*8975f5c5SAndroid Build Coastguard Worker uint32_t unsignedFirstVertex = static_cast<uint32_t>(firstVertex);
4984*8975f5c5SAndroid Build Coastguard Worker uint32_t vertexCount = (clampedVertexCount + unsignedFirstVertex);
4985*8975f5c5SAndroid Build Coastguard Worker for (uint32_t vertexIndex = unsignedFirstVertex; vertexIndex < vertexCount; vertexIndex++)
4986*8975f5c5SAndroid Build Coastguard Worker {
4987*8975f5c5SAndroid Build Coastguard Worker *indices++ = vertexIndex;
4988*8975f5c5SAndroid Build Coastguard Worker }
4989*8975f5c5SAndroid Build Coastguard Worker *indices = unsignedFirstVertex;
4990*8975f5c5SAndroid Build Coastguard Worker
4991*8975f5c5SAndroid Build Coastguard Worker // Since we are not using the VK_MEMORY_PROPERTY_HOST_COHERENT_BIT flag when creating the
4992*8975f5c5SAndroid Build Coastguard Worker // device memory in the StreamingBuffer, we always need to make sure we flush it after
4993*8975f5c5SAndroid Build Coastguard Worker // writing.
4994*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(indexBuffer->flush(contextVk->getRenderer()));
4995*8975f5c5SAndroid Build Coastguard Worker
4996*8975f5c5SAndroid Build Coastguard Worker *bufferOut = indexBuffer;
4997*8975f5c5SAndroid Build Coastguard Worker
4998*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4999*8975f5c5SAndroid Build Coastguard Worker }
5000*8975f5c5SAndroid Build Coastguard Worker
getIndexBufferForElementArrayBuffer(ContextVk * contextVk,BufferVk * elementArrayBufferVk,gl::DrawElementsType glIndexType,int indexCount,intptr_t elementArrayOffset,vk::BufferHelper ** bufferOut,uint32_t * indexCountOut)5001*8975f5c5SAndroid Build Coastguard Worker angle::Result LineLoopHelper::getIndexBufferForElementArrayBuffer(ContextVk *contextVk,
5002*8975f5c5SAndroid Build Coastguard Worker BufferVk *elementArrayBufferVk,
5003*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType glIndexType,
5004*8975f5c5SAndroid Build Coastguard Worker int indexCount,
5005*8975f5c5SAndroid Build Coastguard Worker intptr_t elementArrayOffset,
5006*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper **bufferOut,
5007*8975f5c5SAndroid Build Coastguard Worker uint32_t *indexCountOut)
5008*8975f5c5SAndroid Build Coastguard Worker {
5009*8975f5c5SAndroid Build Coastguard Worker if (glIndexType == gl::DrawElementsType::UnsignedByte ||
5010*8975f5c5SAndroid Build Coastguard Worker contextVk->getState().isPrimitiveRestartEnabled())
5011*8975f5c5SAndroid Build Coastguard Worker {
5012*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRACE_EVENT0("gpu.angle", "LineLoopHelper::getIndexBufferForElementArrayBuffer");
5013*8975f5c5SAndroid Build Coastguard Worker
5014*8975f5c5SAndroid Build Coastguard Worker void *srcDataMapping = nullptr;
5015*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(elementArrayBufferVk->mapImpl(contextVk, GL_MAP_READ_BIT, &srcDataMapping));
5016*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(streamIndices(contextVk, glIndexType, indexCount,
5017*8975f5c5SAndroid Build Coastguard Worker static_cast<const uint8_t *>(srcDataMapping) + elementArrayOffset,
5018*8975f5c5SAndroid Build Coastguard Worker bufferOut, indexCountOut));
5019*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(elementArrayBufferVk->unmapImpl(contextVk));
5020*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
5021*8975f5c5SAndroid Build Coastguard Worker }
5022*8975f5c5SAndroid Build Coastguard Worker
5023*8975f5c5SAndroid Build Coastguard Worker *indexCountOut = indexCount + 1;
5024*8975f5c5SAndroid Build Coastguard Worker
5025*8975f5c5SAndroid Build Coastguard Worker size_t unitSize = contextVk->getVkIndexTypeSize(glIndexType);
5026*8975f5c5SAndroid Build Coastguard Worker
5027*8975f5c5SAndroid Build Coastguard Worker size_t allocateBytes = unitSize * (indexCount + 1) + 1;
5028*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->initBufferForVertexConversion(&mDynamicIndexBuffer, allocateBytes,
5029*8975f5c5SAndroid Build Coastguard Worker vk::MemoryHostVisibility::Visible));
5030*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *indexBuffer = mDynamicIndexBuffer.getBuffer();
5031*8975f5c5SAndroid Build Coastguard Worker
5032*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *sourceBuffer = &elementArrayBufferVk->getBuffer();
5033*8975f5c5SAndroid Build Coastguard Worker VkDeviceSize sourceOffset =
5034*8975f5c5SAndroid Build Coastguard Worker static_cast<VkDeviceSize>(elementArrayOffset) + sourceBuffer->getOffset();
5035*8975f5c5SAndroid Build Coastguard Worker uint64_t unitCount = static_cast<VkDeviceSize>(indexCount);
5036*8975f5c5SAndroid Build Coastguard Worker angle::FixedVector<VkBufferCopy, 2> copies = {
5037*8975f5c5SAndroid Build Coastguard Worker {sourceOffset, indexBuffer->getOffset(), unitCount * unitSize},
5038*8975f5c5SAndroid Build Coastguard Worker {sourceOffset, indexBuffer->getOffset() + unitCount * unitSize, unitSize},
5039*8975f5c5SAndroid Build Coastguard Worker };
5040*8975f5c5SAndroid Build Coastguard Worker
5041*8975f5c5SAndroid Build Coastguard Worker vk::CommandBufferAccess access;
5042*8975f5c5SAndroid Build Coastguard Worker access.onBufferTransferWrite(indexBuffer);
5043*8975f5c5SAndroid Build Coastguard Worker access.onBufferTransferRead(sourceBuffer);
5044*8975f5c5SAndroid Build Coastguard Worker
5045*8975f5c5SAndroid Build Coastguard Worker vk::OutsideRenderPassCommandBuffer *commandBuffer;
5046*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &commandBuffer));
5047*8975f5c5SAndroid Build Coastguard Worker
5048*8975f5c5SAndroid Build Coastguard Worker commandBuffer->copyBuffer(sourceBuffer->getBuffer(), indexBuffer->getBuffer(),
5049*8975f5c5SAndroid Build Coastguard Worker static_cast<uint32_t>(copies.size()), copies.data());
5050*8975f5c5SAndroid Build Coastguard Worker
5051*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(indexBuffer->flush(contextVk->getRenderer()));
5052*8975f5c5SAndroid Build Coastguard Worker
5053*8975f5c5SAndroid Build Coastguard Worker *bufferOut = indexBuffer;
5054*8975f5c5SAndroid Build Coastguard Worker
5055*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
5056*8975f5c5SAndroid Build Coastguard Worker }
5057*8975f5c5SAndroid Build Coastguard Worker
streamIndices(ContextVk * contextVk,gl::DrawElementsType glIndexType,GLsizei indexCount,const uint8_t * srcPtr,vk::BufferHelper ** bufferOut,uint32_t * indexCountOut)5058*8975f5c5SAndroid Build Coastguard Worker angle::Result LineLoopHelper::streamIndices(ContextVk *contextVk,
5059*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType glIndexType,
5060*8975f5c5SAndroid Build Coastguard Worker GLsizei indexCount,
5061*8975f5c5SAndroid Build Coastguard Worker const uint8_t *srcPtr,
5062*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper **bufferOut,
5063*8975f5c5SAndroid Build Coastguard Worker uint32_t *indexCountOut)
5064*8975f5c5SAndroid Build Coastguard Worker {
5065*8975f5c5SAndroid Build Coastguard Worker size_t unitSize = contextVk->getVkIndexTypeSize(glIndexType);
5066*8975f5c5SAndroid Build Coastguard Worker
5067*8975f5c5SAndroid Build Coastguard Worker uint32_t numOutIndices = indexCount + 1;
5068*8975f5c5SAndroid Build Coastguard Worker if (contextVk->getState().isPrimitiveRestartEnabled())
5069*8975f5c5SAndroid Build Coastguard Worker {
5070*8975f5c5SAndroid Build Coastguard Worker numOutIndices = GetLineLoopWithRestartIndexCount(glIndexType, indexCount, srcPtr);
5071*8975f5c5SAndroid Build Coastguard Worker }
5072*8975f5c5SAndroid Build Coastguard Worker *indexCountOut = numOutIndices;
5073*8975f5c5SAndroid Build Coastguard Worker
5074*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->initBufferForVertexConversion(
5075*8975f5c5SAndroid Build Coastguard Worker &mDynamicIndexBuffer, unitSize * numOutIndices, vk::MemoryHostVisibility::Visible));
5076*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *indexBuffer = mDynamicIndexBuffer.getBuffer();
5077*8975f5c5SAndroid Build Coastguard Worker uint8_t *indices = indexBuffer->getMappedMemory();
5078*8975f5c5SAndroid Build Coastguard Worker
5079*8975f5c5SAndroid Build Coastguard Worker if (contextVk->getState().isPrimitiveRestartEnabled())
5080*8975f5c5SAndroid Build Coastguard Worker {
5081*8975f5c5SAndroid Build Coastguard Worker HandlePrimitiveRestart(contextVk, glIndexType, indexCount, srcPtr, indices);
5082*8975f5c5SAndroid Build Coastguard Worker }
5083*8975f5c5SAndroid Build Coastguard Worker else
5084*8975f5c5SAndroid Build Coastguard Worker {
5085*8975f5c5SAndroid Build Coastguard Worker if (contextVk->shouldConvertUint8VkIndexType(glIndexType))
5086*8975f5c5SAndroid Build Coastguard Worker {
5087*8975f5c5SAndroid Build Coastguard Worker // If vulkan doesn't support uint8 index types, we need to emulate it.
5088*8975f5c5SAndroid Build Coastguard Worker VkIndexType indexType = contextVk->getVkIndexType(glIndexType);
5089*8975f5c5SAndroid Build Coastguard Worker ASSERT(indexType == VK_INDEX_TYPE_UINT16);
5090*8975f5c5SAndroid Build Coastguard Worker uint16_t *indicesDst = reinterpret_cast<uint16_t *>(indices);
5091*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < indexCount; i++)
5092*8975f5c5SAndroid Build Coastguard Worker {
5093*8975f5c5SAndroid Build Coastguard Worker indicesDst[i] = srcPtr[i];
5094*8975f5c5SAndroid Build Coastguard Worker }
5095*8975f5c5SAndroid Build Coastguard Worker
5096*8975f5c5SAndroid Build Coastguard Worker indicesDst[indexCount] = srcPtr[0];
5097*8975f5c5SAndroid Build Coastguard Worker }
5098*8975f5c5SAndroid Build Coastguard Worker else
5099*8975f5c5SAndroid Build Coastguard Worker {
5100*8975f5c5SAndroid Build Coastguard Worker memcpy(indices, srcPtr, unitSize * indexCount);
5101*8975f5c5SAndroid Build Coastguard Worker memcpy(indices + unitSize * indexCount, srcPtr, unitSize);
5102*8975f5c5SAndroid Build Coastguard Worker }
5103*8975f5c5SAndroid Build Coastguard Worker }
5104*8975f5c5SAndroid Build Coastguard Worker
5105*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(indexBuffer->flush(contextVk->getRenderer()));
5106*8975f5c5SAndroid Build Coastguard Worker
5107*8975f5c5SAndroid Build Coastguard Worker *bufferOut = indexBuffer;
5108*8975f5c5SAndroid Build Coastguard Worker
5109*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
5110*8975f5c5SAndroid Build Coastguard Worker }
5111*8975f5c5SAndroid Build Coastguard Worker
streamIndicesIndirect(ContextVk * contextVk,gl::DrawElementsType glIndexType,vk::BufferHelper * srcIndexBuffer,vk::BufferHelper * srcIndirectBuffer,VkDeviceSize indirectBufferOffset,vk::BufferHelper ** dstIndexBufferOut,vk::BufferHelper ** dstIndirectBufferOut)5112*8975f5c5SAndroid Build Coastguard Worker angle::Result LineLoopHelper::streamIndicesIndirect(ContextVk *contextVk,
5113*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType glIndexType,
5114*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *srcIndexBuffer,
5115*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *srcIndirectBuffer,
5116*8975f5c5SAndroid Build Coastguard Worker VkDeviceSize indirectBufferOffset,
5117*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper **dstIndexBufferOut,
5118*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper **dstIndirectBufferOut)
5119*8975f5c5SAndroid Build Coastguard Worker {
5120*8975f5c5SAndroid Build Coastguard Worker size_t unitSize = contextVk->getVkIndexTypeSize(glIndexType);
5121*8975f5c5SAndroid Build Coastguard Worker size_t allocateBytes = static_cast<size_t>(srcIndexBuffer->getSize() + unitSize);
5122*8975f5c5SAndroid Build Coastguard Worker
5123*8975f5c5SAndroid Build Coastguard Worker if (contextVk->getState().isPrimitiveRestartEnabled())
5124*8975f5c5SAndroid Build Coastguard Worker {
5125*8975f5c5SAndroid Build Coastguard Worker // If primitive restart, new index buffer is 135% the size of the original index buffer. The
5126*8975f5c5SAndroid Build Coastguard Worker // smallest lineloop with primitive restart is 3 indices (point 1, point 2 and restart
5127*8975f5c5SAndroid Build Coastguard Worker // value) when converted to linelist becomes 4 vertices. Expansion of 4/3. Any larger
5128*8975f5c5SAndroid Build Coastguard Worker // lineloops would have less overhead and require less extra space. Any incomplete
5129*8975f5c5SAndroid Build Coastguard Worker // primitives can be dropped or left incomplete and thus not increase the size of the
5130*8975f5c5SAndroid Build Coastguard Worker // destination index buffer. Since we don't know the number of indices being used we'll use
5131*8975f5c5SAndroid Build Coastguard Worker // the size of the index buffer as allocated as the index count.
5132*8975f5c5SAndroid Build Coastguard Worker size_t numInputIndices = static_cast<size_t>(srcIndexBuffer->getSize() / unitSize);
5133*8975f5c5SAndroid Build Coastguard Worker size_t numNewInputIndices = ((numInputIndices * 4) / 3) + 1;
5134*8975f5c5SAndroid Build Coastguard Worker allocateBytes = static_cast<size_t>(numNewInputIndices * unitSize);
5135*8975f5c5SAndroid Build Coastguard Worker }
5136*8975f5c5SAndroid Build Coastguard Worker
5137*8975f5c5SAndroid Build Coastguard Worker // Allocate buffer for results
5138*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->initBufferForVertexConversion(&mDynamicIndexBuffer, allocateBytes,
5139*8975f5c5SAndroid Build Coastguard Worker vk::MemoryHostVisibility::Visible));
5140*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->initBufferForVertexConversion(&mDynamicIndirectBuffer,
5141*8975f5c5SAndroid Build Coastguard Worker sizeof(VkDrawIndexedIndirectCommand),
5142*8975f5c5SAndroid Build Coastguard Worker vk::MemoryHostVisibility::Visible));
5143*8975f5c5SAndroid Build Coastguard Worker
5144*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dstIndexBuffer = mDynamicIndexBuffer.getBuffer();
5145*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dstIndirectBuffer = mDynamicIndirectBuffer.getBuffer();
5146*8975f5c5SAndroid Build Coastguard Worker
5147*8975f5c5SAndroid Build Coastguard Worker // Copy relevant section of the source into destination at allocated offset. Note that the
5148*8975f5c5SAndroid Build Coastguard Worker // offset returned by allocate() above is in bytes. As is the indices offset pointer.
5149*8975f5c5SAndroid Build Coastguard Worker UtilsVk::ConvertLineLoopIndexIndirectParameters params = {};
5150*8975f5c5SAndroid Build Coastguard Worker params.indirectBufferOffset = static_cast<uint32_t>(indirectBufferOffset);
5151*8975f5c5SAndroid Build Coastguard Worker params.dstIndirectBufferOffset = 0;
5152*8975f5c5SAndroid Build Coastguard Worker params.srcIndexBufferOffset = 0;
5153*8975f5c5SAndroid Build Coastguard Worker params.dstIndexBufferOffset = 0;
5154*8975f5c5SAndroid Build Coastguard Worker params.indicesBitsWidth = static_cast<uint32_t>(unitSize * 8);
5155*8975f5c5SAndroid Build Coastguard Worker
5156*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getUtils().convertLineLoopIndexIndirectBuffer(
5157*8975f5c5SAndroid Build Coastguard Worker contextVk, srcIndirectBuffer, srcIndexBuffer, dstIndirectBuffer, dstIndexBuffer, params));
5158*8975f5c5SAndroid Build Coastguard Worker
5159*8975f5c5SAndroid Build Coastguard Worker mDynamicIndexBuffer.clearDirty();
5160*8975f5c5SAndroid Build Coastguard Worker mDynamicIndirectBuffer.clearDirty();
5161*8975f5c5SAndroid Build Coastguard Worker
5162*8975f5c5SAndroid Build Coastguard Worker *dstIndexBufferOut = dstIndexBuffer;
5163*8975f5c5SAndroid Build Coastguard Worker *dstIndirectBufferOut = dstIndirectBuffer;
5164*8975f5c5SAndroid Build Coastguard Worker
5165*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
5166*8975f5c5SAndroid Build Coastguard Worker }
5167*8975f5c5SAndroid Build Coastguard Worker
streamArrayIndirect(ContextVk * contextVk,size_t vertexCount,vk::BufferHelper * arrayIndirectBuffer,VkDeviceSize arrayIndirectBufferOffset,vk::BufferHelper ** dstIndexBufferOut,vk::BufferHelper ** dstIndexIndirectBufferOut)5168*8975f5c5SAndroid Build Coastguard Worker angle::Result LineLoopHelper::streamArrayIndirect(ContextVk *contextVk,
5169*8975f5c5SAndroid Build Coastguard Worker size_t vertexCount,
5170*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *arrayIndirectBuffer,
5171*8975f5c5SAndroid Build Coastguard Worker VkDeviceSize arrayIndirectBufferOffset,
5172*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper **dstIndexBufferOut,
5173*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper **dstIndexIndirectBufferOut)
5174*8975f5c5SAndroid Build Coastguard Worker {
5175*8975f5c5SAndroid Build Coastguard Worker auto unitSize = sizeof(uint32_t);
5176*8975f5c5SAndroid Build Coastguard Worker size_t allocateBytes = static_cast<size_t>((vertexCount + 1) * unitSize);
5177*8975f5c5SAndroid Build Coastguard Worker
5178*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->initBufferForVertexConversion(&mDynamicIndexBuffer, allocateBytes,
5179*8975f5c5SAndroid Build Coastguard Worker vk::MemoryHostVisibility::Visible));
5180*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->initBufferForVertexConversion(&mDynamicIndirectBuffer,
5181*8975f5c5SAndroid Build Coastguard Worker sizeof(VkDrawIndexedIndirectCommand),
5182*8975f5c5SAndroid Build Coastguard Worker vk::MemoryHostVisibility::Visible));
5183*8975f5c5SAndroid Build Coastguard Worker
5184*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dstIndexBuffer = mDynamicIndexBuffer.getBuffer();
5185*8975f5c5SAndroid Build Coastguard Worker vk::BufferHelper *dstIndirectBuffer = mDynamicIndirectBuffer.getBuffer();
5186*8975f5c5SAndroid Build Coastguard Worker
5187*8975f5c5SAndroid Build Coastguard Worker // Copy relevant section of the source into destination at allocated offset. Note that the
5188*8975f5c5SAndroid Build Coastguard Worker // offset returned by allocate() above is in bytes. As is the indices offset pointer.
5189*8975f5c5SAndroid Build Coastguard Worker UtilsVk::ConvertLineLoopArrayIndirectParameters params = {};
5190*8975f5c5SAndroid Build Coastguard Worker params.indirectBufferOffset = static_cast<uint32_t>(arrayIndirectBufferOffset);
5191*8975f5c5SAndroid Build Coastguard Worker params.dstIndirectBufferOffset = 0;
5192*8975f5c5SAndroid Build Coastguard Worker params.dstIndexBufferOffset = 0;
5193*8975f5c5SAndroid Build Coastguard Worker
5194*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextVk->getUtils().convertLineLoopArrayIndirectBuffer(
5195*8975f5c5SAndroid Build Coastguard Worker contextVk, arrayIndirectBuffer, dstIndirectBuffer, dstIndexBuffer, params));
5196*8975f5c5SAndroid Build Coastguard Worker
5197*8975f5c5SAndroid Build Coastguard Worker mDynamicIndexBuffer.clearDirty();
5198*8975f5c5SAndroid Build Coastguard Worker mDynamicIndirectBuffer.clearDirty();
5199*8975f5c5SAndroid Build Coastguard Worker
5200*8975f5c5SAndroid Build Coastguard Worker *dstIndexBufferOut = dstIndexBuffer;
5201*8975f5c5SAndroid Build Coastguard Worker *dstIndexIndirectBufferOut = dstIndirectBuffer;
5202*8975f5c5SAndroid Build Coastguard Worker
5203*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
5204*8975f5c5SAndroid Build Coastguard Worker }
5205*8975f5c5SAndroid Build Coastguard Worker
release(ContextVk * contextVk)5206*8975f5c5SAndroid Build Coastguard Worker void LineLoopHelper::release(ContextVk *contextVk)
5207*8975f5c5SAndroid Build Coastguard Worker {
5208*8975f5c5SAndroid Build Coastguard Worker mDynamicIndexBuffer.release(contextVk->getRenderer());
5209*8975f5c5SAndroid Build Coastguard Worker mDynamicIndirectBuffer.release(contextVk->getRenderer());
5210*8975f5c5SAndroid Build Coastguard Worker }
5211*8975f5c5SAndroid Build Coastguard Worker
destroy(vk::Renderer * renderer)5212*8975f5c5SAndroid Build Coastguard Worker void LineLoopHelper::destroy(vk::Renderer *renderer)
5213*8975f5c5SAndroid Build Coastguard Worker {
5214*8975f5c5SAndroid Build Coastguard Worker mDynamicIndexBuffer.destroy(renderer);
5215*8975f5c5SAndroid Build Coastguard Worker mDynamicIndirectBuffer.destroy(renderer);
5216*8975f5c5SAndroid Build Coastguard Worker }
5217*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
5218