Flutter Engine
The Flutter Engine
Macros | Functions
GrVkGpu.cpp File Reference
#include "src/gpu/ganesh/vk/GrVkGpu.h"
#include "include/core/SkTextureCompressionType.h"
#include "include/gpu/GrBackendSemaphore.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrContextOptions.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/ganesh/vk/GrVkBackendSemaphore.h"
#include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
#include "include/gpu/vk/GrVkTypes.h"
#include "include/gpu/vk/VulkanBackendContext.h"
#include "include/gpu/vk/VulkanExtensions.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkRectMemcpy.h"
#include "src/core/SkCompressedDataUtils.h"
#include "src/core/SkMipmap.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/DataUtils.h"
#include "src/gpu/ganesh/GrBackendUtils.h"
#include "src/gpu/ganesh/GrDataUtils.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrGeometryProcessor.h"
#include "src/gpu/ganesh/GrGpuResourceCacheAccess.h"
#include "src/gpu/ganesh/GrNativeRect.h"
#include "src/gpu/ganesh/GrPipeline.h"
#include "src/gpu/ganesh/GrPixmap.h"
#include "src/gpu/ganesh/GrRenderTarget.h"
#include "src/gpu/ganesh/GrResourceProvider.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "src/gpu/ganesh/GrThreadSafePipelineBuilder.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/image/SkImage_Ganesh.h"
#include "src/gpu/ganesh/surface/SkSurface_Ganesh.h"
#include "src/gpu/ganesh/vk/GrVkBuffer.h"
#include "src/gpu/ganesh/vk/GrVkCommandBuffer.h"
#include "src/gpu/ganesh/vk/GrVkCommandPool.h"
#include "src/gpu/ganesh/vk/GrVkFramebuffer.h"
#include "src/gpu/ganesh/vk/GrVkImage.h"
#include "src/gpu/ganesh/vk/GrVkOpsRenderPass.h"
#include "src/gpu/ganesh/vk/GrVkPipeline.h"
#include "src/gpu/ganesh/vk/GrVkPipelineState.h"
#include "src/gpu/ganesh/vk/GrVkRenderPass.h"
#include "src/gpu/ganesh/vk/GrVkResourceProvider.h"
#include "src/gpu/ganesh/vk/GrVkSemaphore.h"
#include "src/gpu/ganesh/vk/GrVkTexture.h"
#include "src/gpu/ganesh/vk/GrVkTextureRenderTarget.h"
#include "src/gpu/vk/VulkanInterface.h"
#include "src/gpu/vk/VulkanMemory.h"
#include "src/gpu/vk/VulkanUtilsPriv.h"
#include "include/gpu/vk/VulkanTypes.h"
#include "include/private/gpu/vk/SkiaVulkan.h"

Go to the source code of this file.

Macros

#define VK_CALL(X)   GR_VK_CALL(this->vkInterface(), X)
 
#define VK_CALL_RET(RET, X)   GR_VK_CALL_RESULT(this, RET, X)
 

Functions

static void add_transfer_dst_buffer_mem_barrier (GrVkGpu *gpu, GrVkBuffer *dst, size_t offset, size_t size, bool after)
 
static size_t fill_in_compressed_regions (GrStagingBufferManager *stagingBufferManager, TArray< VkBufferImageCopy > *regions, TArray< size_t > *individualMipOffsets, GrStagingBufferManager::Slice *slice, SkTextureCompressionType compression, VkFormat vkFormat, SkISize dimensions, skgpu::Mipmapped mipmapped)
 
static bool check_image_info (const GrVkCaps &caps, const GrVkImageInfo &info, bool needsAllocation, uint32_t graphicsQueueIndex)
 
static bool check_tex_image_info (const GrVkCaps &caps, const GrVkImageInfo &info)
 
static bool check_rt_image_info (const GrVkCaps &caps, const GrVkImageInfo &info, bool resolveOnly)
 
bool copy_src_data (char *mapPtr, VkFormat vkFormat, const TArray< size_t > &individualMipOffsets, const GrPixmap srcData[], int numMipLevels)
 
void set_layout_and_queue_from_mutable_state (GrVkGpu *gpu, GrVkImage *image, VkImageLayout newLayout, uint32_t newQueueFamilyIndex)
 

Macro Definition Documentation

◆ VK_CALL

#define VK_CALL (   X)    GR_VK_CALL(this->vkInterface(), X)

Definition at line 67 of file GrVkGpu.cpp.

◆ VK_CALL_RET

#define VK_CALL_RET (   RET,
  X 
)    GR_VK_CALL_RESULT(this, RET, X)

Definition at line 68 of file GrVkGpu.cpp.

Function Documentation

◆ add_transfer_dst_buffer_mem_barrier()

static void add_transfer_dst_buffer_mem_barrier ( GrVkGpu gpu,
GrVkBuffer dst,
size_t  offset,
size_t  size,
bool  after 
)
static

Definition at line 550 of file GrVkGpu.cpp.

554 {
555 if (dst->intendedType() != GrGpuBufferType::kIndex &&
556 dst->intendedType() != GrGpuBufferType::kVertex) {
557 return;
558 }
559
560 VkAccessFlags srcAccessMask = dst->intendedType() == GrGpuBufferType::kIndex
564
567
568 if (after) {
569 using std::swap;
570 swap(srcAccessMask, dstAccessMask );
571 swap(srcPipelineStageFlags, dstPipelineStageFlags);
572 }
573
574 VkBufferMemoryBarrier bufferMemoryBarrier = {
576 nullptr, // pNext
577 srcAccessMask, // srcAccessMask
578 dstAccessMask, // dstAccessMask
579 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
580 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex
581 dst->vkBuffer(), // buffer
582 offset, // offset
583 size, // size
584 };
585
586 gpu->addBufferMemoryBarrier(srcPipelineStageFlags,
587 dstPipelineStageFlags,
588 /*byRegion=*/false,
589 &bufferMemoryBarrier);
590}
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
void addBufferMemoryBarrier(const GrManagedResource *, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, bool byRegion, VkBufferMemoryBarrier *barrier) const
Definition: GrVkGpu.cpp:2127
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
dst
Definition: cp.py:12
SeparatedVector2 offset
VkFlags VkAccessFlags
Definition: vulkan_core.h:2235
@ VK_ACCESS_TRANSFER_WRITE_BIT
Definition: vulkan_core.h:2212
@ VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
Definition: vulkan_core.h:2202
@ VK_ACCESS_INDEX_READ_BIT
Definition: vulkan_core.h:2201
VkPipelineStageFlagBits
Definition: vulkan_core.h:2434
@ VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
Definition: vulkan_core.h:2437
@ VK_PIPELINE_STAGE_TRANSFER_BIT
Definition: vulkan_core.h:2447
#define VK_QUEUE_FAMILY_IGNORED
Definition: vulkan_core.h:127
@ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER
Definition: vulkan_core.h:246

◆ check_image_info()

static bool check_image_info ( const GrVkCaps caps,
const GrVkImageInfo info,
bool  needsAllocation,
uint32_t  graphicsQueueIndex 
)
static

Definition at line 1275 of file GrVkGpu.cpp.

1278 {
1279 if (VK_NULL_HANDLE == info.fImage) {
1280 return false;
1281 }
1282
1283 if (VK_NULL_HANDLE == info.fAlloc.fMemory && needsAllocation) {
1284 return false;
1285 }
1286
1287 if (info.fImageLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR && !caps.supportsSwapchain()) {
1288 return false;
1289 }
1290
1291 if (info.fCurrentQueueFamily != VK_QUEUE_FAMILY_IGNORED &&
1292 info.fCurrentQueueFamily != VK_QUEUE_FAMILY_EXTERNAL &&
1293 info.fCurrentQueueFamily != VK_QUEUE_FAMILY_FOREIGN_EXT) {
1294 if (info.fSharingMode == VK_SHARING_MODE_EXCLUSIVE) {
1295 if (info.fCurrentQueueFamily != graphicsQueueIndex) {
1296 return false;
1297 }
1298 } else {
1299 return false;
1300 }
1301 }
1302
1303 if (info.fYcbcrConversionInfo.isValid()) {
1304 if (!caps.supportsYcbcrConversion()) {
1305 return false;
1306 }
1307 if (info.fYcbcrConversionInfo.fExternalFormat != 0) {
1308 return true;
1309 }
1310 }
1311
1312 // We currently require everything to be made with transfer bits set
1313 if (!SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) ||
1314 !SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) {
1315 return false;
1316 }
1317
1318 return true;
1319}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
bool supportsYcbcrConversion() const
Definition: GrVkCaps.h:153
bool supportsSwapchain() const
Definition: GrVkCaps.h:126
@ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
Definition: vulkan_core.h:1348
@ VK_SHARING_MODE_EXCLUSIVE
Definition: vulkan_core.h:1813
@ VK_IMAGE_USAGE_TRANSFER_DST_BIT
Definition: vulkan_core.h:2353
@ VK_IMAGE_USAGE_TRANSFER_SRC_BIT
Definition: vulkan_core.h:2352
#define VK_QUEUE_FAMILY_FOREIGN_EXT
#define VK_NULL_HANDLE
Definition: vulkan_core.h:46
#define VK_QUEUE_FAMILY_EXTERNAL
Definition: vulkan_core.h:4927

◆ check_rt_image_info()

static bool check_rt_image_info ( const GrVkCaps caps,
const GrVkImageInfo info,
bool  resolveOnly 
)
static

Definition at line 1363 of file GrVkGpu.cpp.

1363 {
1364 if (!caps.isFormatRenderable(info.fFormat, info.fSampleCount)) {
1365 return false;
1366 }
1367 if (!resolveOnly && !SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
1368 return false;
1369 }
1370 return true;
1371}
bool isFormatRenderable(const GrBackendFormat &format, int sampleCount) const override
Definition: GrVkCaps.cpp:1587
@ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
Definition: vulkan_core.h:2356

◆ check_tex_image_info()

static bool check_tex_image_info ( const GrVkCaps caps,
const GrVkImageInfo info 
)
static

Definition at line 1321 of file GrVkGpu.cpp.

1321 {
1322 // We don't support directly importing multisampled textures for sampling from shaders.
1323 if (info.fSampleCount != 1) {
1324 return false;
1325 }
1326
1327 if (info.fYcbcrConversionInfo.isValid() && info.fYcbcrConversionInfo.fExternalFormat != 0) {
1328 return true;
1329 }
1330 if (info.fImageTiling == VK_IMAGE_TILING_OPTIMAL) {
1331 if (!caps.isVkFormatTexturable(info.fFormat)) {
1332 return false;
1333 }
1334 } else if (info.fImageTiling == VK_IMAGE_TILING_LINEAR) {
1335 if (!caps.isVkFormatTexturableLinearly(info.fFormat)) {
1336 return false;
1337 }
1338 } else if (info.fImageTiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
1339 if (!caps.supportsDRMFormatModifiers()) {
1340 return false;
1341 }
1342 // To be technically correct we should query the vulkan support for VkFormat and
1343 // drmFormatModifier pairs to confirm the required feature support is there. However, we
1344 // currently don't have our caps and format tables set up to do this effeciently. So
1345 // instead we just rely on the client's passed in VkImageUsageFlags and assume they we set
1346 // up using valid features (checked below). In practice this should all be safe because
1347 // currently we are setting all drm format modifier textures to have a
1348 // GrTextureType::kExternal so we just really need to be able to read these video VkImage in
1349 // a shader. The video decoder isn't going to give us VkImages that don't support being
1350 // sampled.
1351 } else {
1353 }
1354
1355 // We currently require all textures to be made with sample support
1356 if (!SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT)) {
1357 return false;
1358 }
1359
1360 return true;
1361}
#define SkUNREACHABLE
Definition: SkAssert.h:135
bool isVkFormatTexturable(VkFormat) const
Definition: GrVkCaps.cpp:1566
bool supportsDRMFormatModifiers() const
Definition: GrVkCaps.h:168
bool isVkFormatTexturableLinearly(VkFormat format) const
Definition: GrVkCaps.h:67
@ VK_IMAGE_TILING_OPTIMAL
Definition: vulkan_core.h:1767
@ VK_IMAGE_TILING_LINEAR
Definition: vulkan_core.h:1768
@ VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT
Definition: vulkan_core.h:1769
@ VK_IMAGE_USAGE_SAMPLED_BIT
Definition: vulkan_core.h:2354

◆ copy_src_data()

bool copy_src_data ( char *  mapPtr,
VkFormat  vkFormat,
const TArray< size_t > &  individualMipOffsets,
const GrPixmap  srcData[],
int  numMipLevels 
)

Definition at line 1625 of file GrVkGpu.cpp.

1629 {
1630 SkASSERT(srcData && numMipLevels);
1632 SkASSERT(individualMipOffsets.size() == numMipLevels);
1633 SkASSERT(mapPtr);
1634
1635 size_t bytesPerPixel = skgpu::VkFormatBytesPerBlock(vkFormat);
1636
1637 for (int level = 0; level < numMipLevels; ++level) {
1638 const size_t trimRB = srcData[level].info().width() * bytesPerPixel;
1639
1640 SkRectMemcpy(mapPtr + individualMipOffsets[level], trimRB,
1641 srcData[level].addr(), srcData[level].rowBytes(),
1642 trimRB, srcData[level].height());
1643 }
1644 return true;
1645}
#define SkASSERT(cond)
Definition: SkAssert.h:116
static void SkRectMemcpy(void *dst, size_t dstRB, const void *src, size_t srcRB, size_t trimRowBytes, int rowCount)
Definition: SkRectMemcpy.h:16
int width() const
Definition: GrImageInfo.h:54
const GrImageInfo & info() const
Definition: GrPixmap.h:17
int size() const
Definition: SkTArray.h:421
static constexpr size_t VkFormatBytesPerBlock(VkFormat vkFormat)
static constexpr bool VkFormatIsCompressed(VkFormat vkFormat)
int32_t height

◆ fill_in_compressed_regions()

static size_t fill_in_compressed_regions ( GrStagingBufferManager stagingBufferManager,
TArray< VkBufferImageCopy > *  regions,
TArray< size_t > *  individualMipOffsets,
GrStagingBufferManager::Slice slice,
SkTextureCompressionType  compression,
VkFormat  vkFormat,
SkISize  dimensions,
skgpu::Mipmapped  mipmapped 
)
static

Definition at line 881 of file GrVkGpu.cpp.

888 {
890 int numMipLevels = 1;
891 if (mipmapped == skgpu::Mipmapped::kYes) {
892 numMipLevels = SkMipmap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
893 }
894
895 regions->reserve_exact(regions->size() + numMipLevels);
896 individualMipOffsets->reserve_exact(individualMipOffsets->size() + numMipLevels);
897
898 size_t bytesPerBlock = skgpu::VkFormatBytesPerBlock(vkFormat);
899
900 size_t bufferSize = SkCompressedDataSize(
901 compression, dimensions, individualMipOffsets, mipmapped == skgpu::Mipmapped::kYes);
902 SkASSERT(individualMipOffsets->size() == numMipLevels);
903
904 // Get a staging buffer slice to hold our mip data.
905 // Vulkan requires offsets in the buffer to be aligned to multiple of the texel size and 4
906 size_t alignment = bytesPerBlock;
907 switch (alignment & 0b11) {
908 case 0: break; // alignment is already a multiple of 4.
909 case 2: alignment *= 2; break; // alignment is a multiple of 2 but not 4.
910 default: alignment *= 4; break; // alignment is not a multiple of 2.
911 }
912 *slice = stagingBufferManager->allocateStagingBufferSlice(bufferSize, alignment);
913 if (!slice->fBuffer) {
914 return 0;
915 }
916
917 for (int i = 0; i < numMipLevels; ++i) {
918 VkBufferImageCopy& region = regions->push_back();
919 memset(&region, 0, sizeof(VkBufferImageCopy));
920 region.bufferOffset = slice->fOffset + (*individualMipOffsets)[i];
921 SkISize revisedDimensions = skgpu::CompressedDimensions(compression, dimensions);
922 region.bufferRowLength = revisedDimensions.width();
923 region.bufferImageHeight = revisedDimensions.height();
924 region.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, SkToU32(i), 0, 1};
925 region.imageOffset = {0, 0, 0};
926 region.imageExtent = {SkToU32(dimensions.width()),
927 SkToU32(dimensions.height()), 1};
928
929 dimensions = {std::max(1, dimensions.width() /2),
930 std::max(1, dimensions.height()/2)};
931 }
932
933 return bufferSize;
934}
size_t SkCompressedDataSize(SkTextureCompressionType type, SkISize dimensions, TArray< size_t > *individualMipOffsets, bool mipmapped)
constexpr uint32_t SkToU32(S x)
Definition: SkTo.h:26
Slice allocateStagingBufferSlice(size_t size, size_t requiredAlignment=1)
static int ComputeLevelCount(int baseWidth, int baseHeight)
Definition: SkMipmap.cpp:134
void reserve_exact(int n)
Definition: SkTArray.h:181
static float max(float r, float g, float b)
Definition: hsl.cpp:49
ClipOpAndAA opAA SkRegion region
Definition: SkRecords.h:238
SkISize CompressedDimensions(SkTextureCompressionType type, SkISize baseDimensions)
Definition: DataUtils.cpp:195
Definition: SkSize.h:16
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37
@ VK_IMAGE_ASPECT_COLOR_BIT
Definition: vulkan_core.h:2238

◆ set_layout_and_queue_from_mutable_state()

void set_layout_and_queue_from_mutable_state ( GrVkGpu gpu,
GrVkImage image,
VkImageLayout  newLayout,
uint32_t  newQueueFamilyIndex 
)

Definition at line 1899 of file GrVkGpu.cpp.

1901 {
1902 // Even though internally we use this helper for getting src access flags and stages they
1903 // can also be used for general dst flags since we don't know exactly what the client
1904 // plans on using the image for.
1905 if (newLayout == VK_IMAGE_LAYOUT_UNDEFINED) {
1906 newLayout = image->currentLayout();
1907 }
1909 VkAccessFlags dstAccess = GrVkImage::LayoutToSrcAccessMask(newLayout);
1910
1911 uint32_t currentQueueFamilyIndex = image->currentQueueFamilyIndex();
1912 auto isSpecialQueue = [](uint32_t queueFamilyIndex) {
1913 return queueFamilyIndex == VK_QUEUE_FAMILY_EXTERNAL ||
1914 queueFamilyIndex == VK_QUEUE_FAMILY_FOREIGN_EXT;
1915 };
1916 if (isSpecialQueue(currentQueueFamilyIndex) && isSpecialQueue(newQueueFamilyIndex)) {
1917 // It is illegal to have both the new and old queue be special queue families (i.e. external
1918 // or foreign).
1919 return;
1920 }
1921
1922 image->setImageLayoutAndQueueIndex(gpu, newLayout, dstAccess, dstStage, false,
1923 newQueueFamilyIndex);
1924}
static VkAccessFlags LayoutToSrcAccessMask(const VkImageLayout layout)
Definition: GrVkImage.cpp:335
static VkPipelineStageFlags LayoutToPipelineSrcStageFlags(const VkImageLayout layout)
Definition: GrVkImage.cpp:312
sk_sp< const SkImage > image
Definition: SkRecords.h:269
VkFlags VkPipelineStageFlags
Definition: vulkan_core.h:2470
@ VK_IMAGE_LAYOUT_UNDEFINED
Definition: vulkan_core.h:1331