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 ¶ms); 160 angle::Result convertIndexBuffer(ContextVk *contextVk, 161 vk::BufferHelper *dest, 162 vk::BufferHelper *src, 163 const ConvertIndexParameters ¶ms); 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 ¶ms); 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 ¶ms); 178 179 angle::Result convertLineLoopArrayIndirectBuffer( 180 ContextVk *contextVk, 181 vk::BufferHelper *srcIndirectBuffer, 182 vk::BufferHelper *destIndirectBuffer, 183 vk::BufferHelper *destIndexBuffer, 184 const ConvertLineLoopArrayIndirectParameters ¶ms); 185 186 angle::Result convertVertexBuffer(ContextVk *contextVk, 187 vk::BufferHelper *dest, 188 vk::BufferHelper *src, 189 const ConvertVertexParameters ¶ms); 190 191 angle::Result clearFramebuffer(ContextVk *contextVk, 192 FramebufferVk *framebuffer, 193 const ClearFramebufferParameters ¶ms); 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 ¶ms); 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 ¶ms); 207 angle::Result stencilBlitResolveNoShaderExport(ContextVk *contextVk, 208 FramebufferVk *framebuffer, 209 vk::ImageHelper *src, 210 const vk::ImageView *srcStencilView, 211 const BlitResolveParameters ¶ms); 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 ¶ms); 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 ¶ms); 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 ¶ms); 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 ¶ms); 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