• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // UtilsVk.h:
7 //    Defines the UtilsVk class, a helper for various internal draw/dispatch utilities such as
8 //    buffer clear and copy, image clear and copy, texture mip map generation, etc.
9 //
10 //    - Buffer clear: Implemented, but no current users
11 //    - Convert index buffer:
12 //      * Used by VertexArrayVk::convertIndexBufferGPU() to convert a ubyte element array to ushort
13 //    - Convert vertex buffer:
14 //      * Used by VertexArrayVk::convertVertexBufferGPU() to convert vertex attributes from
15 //        unsupported formats to their fallbacks.
16 //    - Image clear: Used by FramebufferVk::clearWithDraw().
17 //    - Image copy: Used by TextureVk::copySubImageImplWithDraw().
18 //    - Color blit/resolve: Used by FramebufferVk::blit() to implement blit or multisample resolve
19 //      on color images.
20 //    - Depth/Stencil blit/resolve: Used by FramebufferVk::blit() to implement blit or multisample
21 //      resolve on depth/stencil images.
22 //    - Overlay Cull/Draw: Used by OverlayVk to efficiently draw a UI for debugging.
23 //    - Mipmap generation: Not yet implemented
24 //
25 
26 #ifndef LIBANGLE_RENDERER_VULKAN_UTILSVK_H_
27 #define LIBANGLE_RENDERER_VULKAN_UTILSVK_H_
28 
29 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
30 #include "libANGLE/renderer/vulkan/vk_helpers.h"
31 #include "libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h"
32 
33 namespace rx
34 {
35 class UtilsVk : angle::NonCopyable
36 {
37   public:
38     UtilsVk();
39     ~UtilsVk();
40 
41     void destroy(VkDevice device);
42 
43     struct ClearParameters
44     {
45         VkClearColorValue clearValue;
46         size_t offset;
47         size_t size;
48     };
49 
50     struct ConvertIndexParameters
51     {
52         uint32_t srcOffset = 0;
53         uint32_t dstOffset = 0;
54         uint32_t maxIndex  = 0;
55     };
56 
57     struct ConvertIndexIndirectParameters
58     {
59         uint32_t srcIndirectBufOffset = 0;
60         uint32_t dstIndexBufOffset    = 0;
61         uint32_t maxIndex             = 0;
62         uint32_t dstIndirectBufOffset = 0;
63     };
64 
65     struct ConvertLineLoopIndexIndirectParameters
66     {
67         uint32_t indirectBufferOffset    = 0;
68         uint32_t dstIndirectBufferOffset = 0;
69         uint32_t dstIndexBufferOffset    = 0;
70         uint32_t indicesBitsWidth        = 0;
71     };
72 
73     struct ConvertLineLoopArrayIndirectParameters
74     {
75         uint32_t indirectBufferOffset    = 0;
76         uint32_t dstIndirectBufferOffset = 0;
77         uint32_t dstIndexBufferOffset    = 0;
78     };
79 
80     struct ConvertVertexParameters
81     {
82         size_t vertexCount;
83         const angle::Format *srcFormat;
84         const angle::Format *destFormat;
85         size_t srcStride;
86         size_t srcOffset;
87         size_t destOffset;
88     };
89 
90     struct ClearFramebufferParameters
91     {
92         // Satisfy chromium-style with a constructor that does what = {} was already doing in a
93         // safer way.
94         ClearFramebufferParameters();
95 
96         gl::Rectangle clearArea;
97 
98         // Note that depth clear is never needed to be done with a draw call.
99         bool clearColor;
100         bool clearStencil;
101 
102         uint8_t stencilMask;
103         VkColorComponentFlags colorMaskFlags;
104         uint32_t colorAttachmentIndexGL;
105         const angle::Format *colorFormat;
106 
107         VkClearColorValue colorClearValue;
108         uint8_t stencilClearValue;
109     };
110 
111     struct BlitResolveParameters
112     {
113         // |srcOffset| and |dstIndexBufferOffset| define the original blit/resolve offsets, possibly
114         // flipped.
115         int srcOffset[2];
116         int destOffset[2];
117         // |stretch| is SourceDimension / DestDimension used to transfer dest coordinates to source.
118         float stretch[2];
119         // |srcExtents| is used to normalize source coordinates for sampling.
120         int srcExtents[2];
121         // |blitArea| is the area in destination where blit happens.  It's expected that scissor
122         // and source clipping effects have already been applied to it.
123         gl::Rectangle blitArea;
124         int srcLayer;
125         // Whether linear or point sampling should be used.
126         bool linear;
127         bool flipX;
128         bool flipY;
129     };
130 
131     struct CopyImageParameters
132     {
133         int srcOffset[2];
134         int srcExtents[2];
135         int destOffset[2];
136         int srcMip;
137         int srcLayer;
138         int srcHeight;
139         bool srcPremultiplyAlpha;
140         bool srcUnmultiplyAlpha;
141         bool srcFlipY;
142         bool destFlipY;
143     };
144 
145     struct OverlayCullParameters
146     {
147         uint32_t subgroupSize[2];
148         bool supportsSubgroupBallot;
149         bool supportsSubgroupArithmetic;
150     };
151 
152     struct OverlayDrawParameters
153     {
154         uint32_t subgroupSize[2];
155     };
156 
157     angle::Result clearBuffer(ContextVk *contextVk,
158                               vk::BufferHelper *dest,
159                               const ClearParameters &params);
160     angle::Result convertIndexBuffer(ContextVk *contextVk,
161                                      vk::BufferHelper *dest,
162                                      vk::BufferHelper *src,
163                                      const ConvertIndexParameters &params);
164     angle::Result convertIndexIndirectBuffer(ContextVk *contextVk,
165                                              vk::BufferHelper *srcIndirectBuf,
166                                              vk::BufferHelper *srcIndexBuf,
167                                              vk::BufferHelper *dstIndirectBuf,
168                                              vk::BufferHelper *dstIndexBuf,
169                                              const ConvertIndexIndirectParameters &params);
170 
171     angle::Result convertLineLoopIndexIndirectBuffer(
172         ContextVk *contextVk,
173         vk::BufferHelper *srcIndirectBuffer,
174         vk::BufferHelper *destIndirectBuffer,
175         vk::BufferHelper *destIndexBuffer,
176         vk::BufferHelper *srcIndexBuffer,
177         const ConvertLineLoopIndexIndirectParameters &params);
178 
179     angle::Result convertLineLoopArrayIndirectBuffer(
180         ContextVk *contextVk,
181         vk::BufferHelper *srcIndirectBuffer,
182         vk::BufferHelper *destIndirectBuffer,
183         vk::BufferHelper *destIndexBuffer,
184         const ConvertLineLoopArrayIndirectParameters &params);
185 
186     angle::Result convertVertexBuffer(ContextVk *contextVk,
187                                       vk::BufferHelper *dest,
188                                       vk::BufferHelper *src,
189                                       const ConvertVertexParameters &params);
190 
191     angle::Result clearFramebuffer(ContextVk *contextVk,
192                                    FramebufferVk *framebuffer,
193                                    const ClearFramebufferParameters &params);
194 
195     // Resolve images if multisampled.  Blit otherwise.
196     angle::Result colorBlitResolve(ContextVk *contextVk,
197                                    FramebufferVk *framebuffer,
198                                    vk::ImageHelper *src,
199                                    const vk::ImageView *srcView,
200                                    const BlitResolveParameters &params);
201     angle::Result depthStencilBlitResolve(ContextVk *contextVk,
202                                           FramebufferVk *framebuffer,
203                                           vk::ImageHelper *src,
204                                           const vk::ImageView *srcDepthView,
205                                           const vk::ImageView *srcStencilView,
206                                           const BlitResolveParameters &params);
207     angle::Result stencilBlitResolveNoShaderExport(ContextVk *contextVk,
208                                                    FramebufferVk *framebuffer,
209                                                    vk::ImageHelper *src,
210                                                    const vk::ImageView *srcStencilView,
211                                                    const BlitResolveParameters &params);
212 
213     angle::Result copyImage(ContextVk *contextVk,
214                             vk::ImageHelper *dest,
215                             const vk::ImageView *destView,
216                             vk::ImageHelper *src,
217                             const vk::ImageView *srcView,
218                             const CopyImageParameters &params);
219 
220     // Overlay utilities.
221     angle::Result cullOverlayWidgets(ContextVk *contextVk,
222                                      vk::BufferHelper *enabledWidgetsBuffer,
223                                      vk::ImageHelper *dest,
224                                      const vk::ImageView *destView,
225                                      const OverlayCullParameters &params);
226 
227     angle::Result drawOverlay(ContextVk *contextVk,
228                               vk::BufferHelper *textWidgetsBuffer,
229                               vk::BufferHelper *graphWidgetsBuffer,
230                               vk::ImageHelper *font,
231                               const vk::ImageView *fontView,
232                               vk::ImageHelper *culledWidgets,
233                               const vk::ImageView *culledWidgetsView,
234                               vk::ImageHelper *dest,
235                               const vk::ImageView *destView,
236                               const OverlayDrawParameters &params);
237 
238   private:
239     ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
240 
241     struct BufferUtilsShaderParams
242     {
243         // Structure matching PushConstants in BufferUtils.comp
244         uint32_t destOffset          = 0;
245         uint32_t size                = 0;
246         uint32_t srcOffset           = 0;
247         uint32_t padding             = 0;
248         VkClearColorValue clearValue = {};
249     };
250 
251     struct ConvertIndexShaderParams
252     {
253         uint32_t srcOffset     = 0;
254         uint32_t dstOffsetDiv4 = 0;
255         uint32_t maxIndex      = 0;
256         uint32_t _padding      = 0;
257     };
258 
259     struct ConvertIndexIndirectShaderParams
260     {
261         uint32_t srcIndirectOffsetDiv4 = 0;
262         uint32_t dstOffsetDiv4         = 0;
263         uint32_t maxIndex              = 0;
264         uint32_t dstIndirectOffsetDiv4 = 0;
265     };
266 
267     struct ConvertIndexIndirectLineLoopShaderParams
268     {
269         uint32_t cmdOffsetDiv4    = 0;
270         uint32_t dstCmdOffsetDiv4 = 0;
271         uint32_t dstOffsetDiv4    = 0;
272         uint32_t isRestartEnabled = 0;
273     };
274 
275     struct ConvertIndirectLineLoopShaderParams
276     {
277         uint32_t cmdOffsetDiv4    = 0;
278         uint32_t dstCmdOffsetDiv4 = 0;
279         uint32_t dstOffsetDiv4    = 0;
280     };
281 
282     struct ConvertVertexShaderParams
283     {
284         ConvertVertexShaderParams();
285 
286         // Structure matching PushConstants in ConvertVertex.comp
287         uint32_t outputCount    = 0;
288         uint32_t componentCount = 0;
289         uint32_t srcOffset      = 0;
290         uint32_t destOffset     = 0;
291         uint32_t Ns             = 0;
292         uint32_t Bs             = 0;
293         uint32_t Ss             = 0;
294         uint32_t Es             = 0;
295         uint32_t Nd             = 0;
296         uint32_t Bd             = 0;
297         uint32_t Sd             = 0;
298         uint32_t Ed             = 0;
299     };
300 
301     struct ImageClearShaderParams
302     {
303         // Structure matching PushConstants in ImageClear.frag
304         VkClearColorValue clearValue = {};
305     };
306 
307     struct ImageCopyShaderParams
308     {
309         ImageCopyShaderParams();
310 
311         // Structure matching PushConstants in ImageCopy.frag
312         int32_t srcOffset[2]             = {};
313         int32_t destOffset[2]            = {};
314         int32_t srcMip                   = 0;
315         int32_t srcLayer                 = 0;
316         uint32_t flipY                   = 0;
317         uint32_t premultiplyAlpha        = 0;
318         uint32_t unmultiplyAlpha         = 0;
319         uint32_t destHasLuminance        = 0;
320         uint32_t destIsAlpha             = 0;
321         uint32_t destDefaultChannelsMask = 0;
322     };
323 
324     union BlitResolveOffset
325     {
326         int32_t resolve[2];
327         float blit[2];
328     };
329 
330     struct BlitResolveShaderParams
331     {
332         // Structure matching PushConstants in BlitResolve.frag
333         BlitResolveOffset offset = {};
334         float stretch[2]         = {};
335         float invSrcExtent[2]    = {};
336         int32_t srcLayer         = 0;
337         int32_t samples          = 0;
338         float invSamples         = 0;
339         uint32_t outputMask      = 0;
340         uint32_t flipX           = 0;
341         uint32_t flipY           = 0;
342     };
343 
344     struct BlitResolveStencilNoExportShaderParams
345     {
346         // Structure matching PushConstants in BlitResolveStencilNoExport.comp
347         BlitResolveOffset offset = {};
348         float stretch[2]         = {};
349         float invSrcExtent[2]    = {};
350         int32_t srcLayer         = 0;
351         int32_t srcWidth         = 0;
352         int32_t blitArea[4]      = {};
353         int32_t destPitch        = 0;
354         uint32_t flipX           = 0;
355         uint32_t flipY           = 0;
356     };
357 
358     struct OverlayDrawShaderParams
359     {
360         // Structure matching PushConstants in OverlayDraw.comp
361         uint32_t outputSize[2] = {};
362     };
363 
364     ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
365 
366     // Functions implemented by the class:
367     enum class Function
368     {
369         // Functions implemented in graphics
370         ImageClear  = 0,
371         ImageCopy   = 1,
372         BlitResolve = 2,
373 
374         // Functions implemented in compute
375         ComputeStartIndex          = 3,  // Special value to separate draw and dispatch functions.
376         BufferClear                = 3,
377         ConvertIndexBuffer         = 4,
378         ConvertVertexBuffer        = 5,
379         BlitResolveStencilNoExport = 6,
380         OverlayCull                = 7,
381         OverlayDraw                = 8,
382         ConvertIndexIndirectBuffer = 9,
383         ConvertIndexIndirectLineLoopBuffer = 10,
384         ConvertIndirectLineLoopBuffer      = 11,
385 
386         InvalidEnum = 12,
387         EnumCount   = 12,
388     };
389 
390     // Common function that creates the pipeline for the specified function, binds it and prepares
391     // the draw/dispatch call.  If function >= ComputeStartIndex, fsCsShader is expected to be a
392     // compute shader, vsShader and pipelineDesc should be nullptr, and this will set up a dispatch
393     // call. Otherwise fsCsShader is expected to be a fragment shader and this will set up a draw
394     // call.
395     angle::Result setupProgram(ContextVk *contextVk,
396                                Function function,
397                                vk::RefCounted<vk::ShaderAndSerial> *fsCsShader,
398                                vk::RefCounted<vk::ShaderAndSerial> *vsShader,
399                                vk::ShaderProgramHelper *program,
400                                const vk::GraphicsPipelineDesc *pipelineDesc,
401                                const VkDescriptorSet descriptorSet,
402                                const void *pushConstants,
403                                size_t pushConstantsSize,
404                                vk::CommandBuffer *commandBuffer);
405 
406     // Initializes descriptor set layout, pipeline layout and descriptor pool corresponding to given
407     // function, if not already initialized.  Uses setSizes to create the layout.  For example, if
408     // this array has two entries {STORAGE_TEXEL_BUFFER, 1} and {UNIFORM_TEXEL_BUFFER, 3}, then the
409     // created set layout would be binding 0 for storage texel buffer and bindings 1 through 3 for
410     // uniform texel buffer.  All resources are put in set 0.
411     angle::Result ensureResourcesInitialized(ContextVk *contextVk,
412                                              Function function,
413                                              VkDescriptorPoolSize *setSizes,
414                                              size_t setSizesCount,
415                                              size_t pushConstantsSize);
416 
417     // Initializers corresponding to functions, calling into ensureResourcesInitialized with the
418     // appropriate parameters.
419     angle::Result ensureBufferClearResourcesInitialized(ContextVk *contextVk);
420     angle::Result ensureConvertIndexResourcesInitialized(ContextVk *contextVk);
421     angle::Result ensureConvertIndexIndirectResourcesInitialized(ContextVk *contextVk);
422     angle::Result ensureConvertIndexIndirectLineLoopResourcesInitialized(ContextVk *contextVk);
423     angle::Result ensureConvertIndirectLineLoopResourcesInitialized(ContextVk *contextVk);
424     angle::Result ensureConvertVertexResourcesInitialized(ContextVk *contextVk);
425     angle::Result ensureImageClearResourcesInitialized(ContextVk *contextVk);
426     angle::Result ensureImageCopyResourcesInitialized(ContextVk *contextVk);
427     angle::Result ensureBlitResolveResourcesInitialized(ContextVk *contextVk);
428     angle::Result ensureBlitResolveStencilNoExportResourcesInitialized(ContextVk *contextVk);
429     angle::Result ensureOverlayCullResourcesInitialized(ContextVk *contextVk);
430     angle::Result ensureOverlayDrawResourcesInitialized(ContextVk *contextVk);
431 
432     angle::Result ensureSamplersInitialized(ContextVk *context);
433 
434     angle::Result startRenderPass(ContextVk *contextVk,
435                                   vk::ImageHelper *image,
436                                   const vk::ImageView *imageView,
437                                   const vk::RenderPassDesc &renderPassDesc,
438                                   const gl::Rectangle &renderArea,
439                                   vk::CommandBuffer **commandBufferOut);
440 
441     // Blits or resolves either color or depth/stencil, based on which view is given.
442     angle::Result blitResolveImpl(ContextVk *contextVk,
443                                   FramebufferVk *framebuffer,
444                                   vk::ImageHelper *src,
445                                   const vk::ImageView *srcColorView,
446                                   const vk::ImageView *srcDepthView,
447                                   const vk::ImageView *srcStencilView,
448                                   const BlitResolveParameters &params);
449 
450     // Allocates a single descriptor set.
451     angle::Result allocateDescriptorSet(ContextVk *contextVk,
452                                         Function function,
453                                         vk::RefCountedDescriptorPoolBinding *bindingOut,
454                                         VkDescriptorSet *descriptorSetOut);
455 
456     angle::PackedEnumMap<Function, vk::DescriptorSetLayoutPointerArray> mDescriptorSetLayouts;
457     angle::PackedEnumMap<Function, vk::BindingPointer<vk::PipelineLayout>> mPipelineLayouts;
458     angle::PackedEnumMap<Function, vk::DynamicDescriptorPool> mDescriptorPools;
459 
460     vk::ShaderProgramHelper mBufferUtilsPrograms[vk::InternalShader::BufferUtils_comp::kArrayLen];
461     vk::ShaderProgramHelper mConvertIndexPrograms[vk::InternalShader::ConvertIndex_comp::kArrayLen];
462     vk::ShaderProgramHelper mConvertIndexIndirectLineLoopPrograms
463         [vk::InternalShader::ConvertIndexIndirectLineLoop_comp::kArrayLen];
464     vk::ShaderProgramHelper mConvertIndirectLineLoopPrograms
465         [vk::InternalShader::ConvertIndirectLineLoop_comp::kArrayLen];
466     vk::ShaderProgramHelper
467         mConvertVertexPrograms[vk::InternalShader::ConvertVertex_comp::kArrayLen];
468     vk::ShaderProgramHelper mImageClearProgramVSOnly;
469     vk::ShaderProgramHelper mImageClearProgram[vk::InternalShader::ImageClear_frag::kArrayLen];
470     vk::ShaderProgramHelper mImageCopyPrograms[vk::InternalShader::ImageCopy_frag::kArrayLen];
471     vk::ShaderProgramHelper mBlitResolvePrograms[vk::InternalShader::BlitResolve_frag::kArrayLen];
472     vk::ShaderProgramHelper mBlitResolveStencilNoExportPrograms
473         [vk::InternalShader::BlitResolveStencilNoExport_comp::kArrayLen];
474     vk::ShaderProgramHelper mOverlayCullPrograms[vk::InternalShader::OverlayCull_comp::kArrayLen];
475     vk::ShaderProgramHelper mOverlayDrawPrograms[vk::InternalShader::OverlayDraw_comp::kArrayLen];
476 
477     vk::Sampler mPointSampler;
478     vk::Sampler mLinearSampler;
479 };
480 
481 }  // namespace rx
482 
483 #endif  // LIBANGLE_RENDERER_VULKAN_UTILSVK_H_
484