1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2021 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkBuffer.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h" 13cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkDescriptorSet.h" 14cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h" 15cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkMemory.h" 16cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkMemoryReclaimer.h" 17cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkUtil.h" 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X) 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ciGrVkBuffer::GrVkBuffer(GrVkGpu* gpu, 22cb93a386Sopenharmony_ci size_t sizeInBytes, 23cb93a386Sopenharmony_ci GrGpuBufferType bufferType, 24cb93a386Sopenharmony_ci GrAccessPattern accessPattern, 25cb93a386Sopenharmony_ci VkBuffer buffer, 26cb93a386Sopenharmony_ci const GrVkAlloc& alloc, 27cb93a386Sopenharmony_ci const GrVkDescriptorSet* uniformDescriptorSet) 28cb93a386Sopenharmony_ci : GrGpuBuffer(gpu, sizeInBytes, bufferType, accessPattern) 29cb93a386Sopenharmony_ci , fBuffer(buffer) 30cb93a386Sopenharmony_ci , fAlloc(alloc) 31cb93a386Sopenharmony_ci , fUniformDescriptorSet(uniformDescriptorSet) { 32cb93a386Sopenharmony_ci // We always require dynamic buffers to be mappable 33cb93a386Sopenharmony_ci SkASSERT(accessPattern != kDynamic_GrAccessPattern || this->isVkMappable()); 34cb93a386Sopenharmony_ci SkASSERT(bufferType != GrGpuBufferType::kUniform || uniformDescriptorSet); 35cb93a386Sopenharmony_ci this->setRealAlloc(true); // OH ISSUE: set real alloc flag 36cb93a386Sopenharmony_ci this->setRealAllocSize(sizeInBytes); // OH ISSUE: set real alloc size 37cb93a386Sopenharmony_ci this->registerWithCache(SkBudgeted::kYes); 38cb93a386Sopenharmony_ci} 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_cistatic const GrVkDescriptorSet* make_uniform_desc_set(GrVkGpu* gpu, VkBuffer buffer, size_t size) { 41cb93a386Sopenharmony_ci const GrVkDescriptorSet* descriptorSet = gpu->resourceProvider().getUniformDescriptorSet(); 42cb93a386Sopenharmony_ci if (!descriptorSet) { 43cb93a386Sopenharmony_ci return nullptr; 44cb93a386Sopenharmony_ci } 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci VkDescriptorBufferInfo bufferInfo; 47cb93a386Sopenharmony_ci memset(&bufferInfo, 0, sizeof(VkDescriptorBufferInfo)); 48cb93a386Sopenharmony_ci bufferInfo.buffer = buffer; 49cb93a386Sopenharmony_ci bufferInfo.offset = 0; 50cb93a386Sopenharmony_ci bufferInfo.range = size; 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci VkWriteDescriptorSet descriptorWrite; 53cb93a386Sopenharmony_ci memset(&descriptorWrite, 0, sizeof(VkWriteDescriptorSet)); 54cb93a386Sopenharmony_ci descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 55cb93a386Sopenharmony_ci descriptorWrite.pNext = nullptr; 56cb93a386Sopenharmony_ci descriptorWrite.dstSet = *descriptorSet->descriptorSet(); 57cb93a386Sopenharmony_ci descriptorWrite.dstBinding = GrVkUniformHandler::kUniformBinding; 58cb93a386Sopenharmony_ci descriptorWrite.dstArrayElement = 0; 59cb93a386Sopenharmony_ci descriptorWrite.descriptorCount = 1; 60cb93a386Sopenharmony_ci descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 61cb93a386Sopenharmony_ci descriptorWrite.pImageInfo = nullptr; 62cb93a386Sopenharmony_ci descriptorWrite.pBufferInfo = &bufferInfo; 63cb93a386Sopenharmony_ci descriptorWrite.pTexelBufferView = nullptr; 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci GR_VK_CALL(gpu->vkInterface(), 66cb93a386Sopenharmony_ci UpdateDescriptorSets(gpu->device(), 1, &descriptorWrite, 0, nullptr)); 67cb93a386Sopenharmony_ci return descriptorSet; 68cb93a386Sopenharmony_ci} 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_cisk_sp<GrVkBuffer> GrVkBuffer::Make(GrVkGpu* gpu, 71cb93a386Sopenharmony_ci size_t size, 72cb93a386Sopenharmony_ci GrGpuBufferType bufferType, 73cb93a386Sopenharmony_ci GrAccessPattern accessPattern) { 74cb93a386Sopenharmony_ci VkBuffer buffer; 75cb93a386Sopenharmony_ci GrVkAlloc alloc; 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_ci // The only time we don't require mappable buffers is when we have a static access pattern and 78cb93a386Sopenharmony_ci // we're on a device where gpu only memory has faster reads on the gpu than memory that is also 79cb93a386Sopenharmony_ci // mappable on the cpu. Protected memory always uses mappable buffers. 80cb93a386Sopenharmony_ci bool requiresMappable = gpu->protectedContext() || 81cb93a386Sopenharmony_ci accessPattern == kDynamic_GrAccessPattern || 82cb93a386Sopenharmony_ci accessPattern == kStream_GrAccessPattern || 83cb93a386Sopenharmony_ci !gpu->vkCaps().gpuOnlyBuffersMorePerformant(); 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci using BufferUsage = GrVkMemoryAllocator::BufferUsage; 86cb93a386Sopenharmony_ci BufferUsage allocUsage; 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_ci // create the buffer object 89cb93a386Sopenharmony_ci VkBufferCreateInfo bufInfo; 90cb93a386Sopenharmony_ci memset(&bufInfo, 0, sizeof(VkBufferCreateInfo)); 91cb93a386Sopenharmony_ci bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 92cb93a386Sopenharmony_ci bufInfo.flags = 0; 93cb93a386Sopenharmony_ci bufInfo.size = size; 94cb93a386Sopenharmony_ci switch (bufferType) { 95cb93a386Sopenharmony_ci case GrGpuBufferType::kVertex: 96cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; 97cb93a386Sopenharmony_ci allocUsage = requiresMappable ? BufferUsage::kCpuWritesGpuReads : BufferUsage::kGpuOnly; 98cb93a386Sopenharmony_ci break; 99cb93a386Sopenharmony_ci case GrGpuBufferType::kIndex: 100cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; 101cb93a386Sopenharmony_ci allocUsage = requiresMappable ? BufferUsage::kCpuWritesGpuReads : BufferUsage::kGpuOnly; 102cb93a386Sopenharmony_ci break; 103cb93a386Sopenharmony_ci case GrGpuBufferType::kDrawIndirect: 104cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; 105cb93a386Sopenharmony_ci allocUsage = requiresMappable ? BufferUsage::kCpuWritesGpuReads : BufferUsage::kGpuOnly; 106cb93a386Sopenharmony_ci break; 107cb93a386Sopenharmony_ci case GrGpuBufferType::kUniform: 108cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 109cb93a386Sopenharmony_ci allocUsage = BufferUsage::kCpuWritesGpuReads; 110cb93a386Sopenharmony_ci break; 111cb93a386Sopenharmony_ci case GrGpuBufferType::kXferCpuToGpu: 112cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 113cb93a386Sopenharmony_ci allocUsage = BufferUsage::kTransfersFromCpuToGpu; 114cb93a386Sopenharmony_ci break; 115cb93a386Sopenharmony_ci case GrGpuBufferType::kXferGpuToCpu: 116cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; 117cb93a386Sopenharmony_ci allocUsage = BufferUsage::kTransfersFromGpuToCpu; 118cb93a386Sopenharmony_ci break; 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci // We may not always get a mappable buffer for non dynamic access buffers. Thus we set the 121cb93a386Sopenharmony_ci // transfer dst usage bit in case we need to do a copy to write data. 122cb93a386Sopenharmony_ci // TODO: It doesn't really hurt setting this extra usage flag, but maybe we can narrow the scope 123cb93a386Sopenharmony_ci // of buffers we set it on more than just not dynamic. 124cb93a386Sopenharmony_ci if (!requiresMappable) { 125cb93a386Sopenharmony_ci bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; 126cb93a386Sopenharmony_ci } 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_ci bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 129cb93a386Sopenharmony_ci bufInfo.queueFamilyIndexCount = 0; 130cb93a386Sopenharmony_ci bufInfo.pQueueFamilyIndices = nullptr; 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_ci VkResult err; 133cb93a386Sopenharmony_ci err = VK_CALL(gpu, CreateBuffer(gpu->device(), &bufInfo, nullptr, &buffer)); 134cb93a386Sopenharmony_ci if (err) { 135cb93a386Sopenharmony_ci return nullptr; 136cb93a386Sopenharmony_ci } 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ci#ifdef SKIA_DFX_FOR_OHOS 139cb93a386Sopenharmony_ci if (!GrVkMemory::AllocAndBindBufferMemory(gpu, buffer, allocUsage, &alloc, size)) { 140cb93a386Sopenharmony_ci#else 141cb93a386Sopenharmony_ci if (!GrVkMemory::AllocAndBindBufferMemory(gpu, buffer, allocUsage, &alloc)) { 142cb93a386Sopenharmony_ci#endif 143cb93a386Sopenharmony_ci VK_CALL(gpu, DestroyBuffer(gpu->device(), buffer, nullptr)); 144cb93a386Sopenharmony_ci return nullptr; 145cb93a386Sopenharmony_ci } 146cb93a386Sopenharmony_ci 147cb93a386Sopenharmony_ci // If this is a uniform buffer we must setup a descriptor set 148cb93a386Sopenharmony_ci const GrVkDescriptorSet* uniformDescSet = nullptr; 149cb93a386Sopenharmony_ci if (bufferType == GrGpuBufferType::kUniform) { 150cb93a386Sopenharmony_ci uniformDescSet = make_uniform_desc_set(gpu, buffer, size); 151cb93a386Sopenharmony_ci if (!uniformDescSet) { 152cb93a386Sopenharmony_ci DestroyAndFreeBufferMemory(gpu, alloc, buffer); 153cb93a386Sopenharmony_ci return nullptr; 154cb93a386Sopenharmony_ci } 155cb93a386Sopenharmony_ci } 156cb93a386Sopenharmony_ci 157cb93a386Sopenharmony_ci return sk_sp<GrVkBuffer>(new GrVkBuffer(gpu, size, bufferType, accessPattern, buffer, alloc, 158cb93a386Sopenharmony_ci uniformDescSet)); 159cb93a386Sopenharmony_ci} 160cb93a386Sopenharmony_ci 161cb93a386Sopenharmony_cisk_sp<GrVkBuffer> GrVkBuffer::MakeFromOHNativeBuffer(GrVkGpu* gpu, 162cb93a386Sopenharmony_ci OH_NativeBuffer *nativeBuffer, 163cb93a386Sopenharmony_ci size_t bufferSize, 164cb93a386Sopenharmony_ci GrGpuBufferType bufferType, 165cb93a386Sopenharmony_ci GrAccessPattern accessPattern) { 166cb93a386Sopenharmony_ci SkASSERT(gpu); 167cb93a386Sopenharmony_ci SkASSERT(nativeBuffer); 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ci VkBuffer buffer; 170cb93a386Sopenharmony_ci GrVkAlloc alloc; 171cb93a386Sopenharmony_ci 172cb93a386Sopenharmony_ci // create the buffer object 173cb93a386Sopenharmony_ci VkBufferCreateInfo bufInfo{}; 174cb93a386Sopenharmony_ci bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 175cb93a386Sopenharmony_ci bufInfo.flags = 0; 176cb93a386Sopenharmony_ci bufInfo.size = bufferSize; 177cb93a386Sopenharmony_ci switch (bufferType) { 178cb93a386Sopenharmony_ci case GrGpuBufferType::kVertex: 179cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; 180cb93a386Sopenharmony_ci break; 181cb93a386Sopenharmony_ci case GrGpuBufferType::kIndex: 182cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; 183cb93a386Sopenharmony_ci break; 184cb93a386Sopenharmony_ci case GrGpuBufferType::kDrawIndirect: 185cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; 186cb93a386Sopenharmony_ci break; 187cb93a386Sopenharmony_ci case GrGpuBufferType::kUniform: 188cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 189cb93a386Sopenharmony_ci break; 190cb93a386Sopenharmony_ci case GrGpuBufferType::kXferCpuToGpu: 191cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 192cb93a386Sopenharmony_ci break; 193cb93a386Sopenharmony_ci case GrGpuBufferType::kXferGpuToCpu: 194cb93a386Sopenharmony_ci bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; 195cb93a386Sopenharmony_ci break; 196cb93a386Sopenharmony_ci } 197cb93a386Sopenharmony_ci 198cb93a386Sopenharmony_ci bool requiresMappable = gpu->protectedContext() || 199cb93a386Sopenharmony_ci accessPattern == kDynamic_GrAccessPattern || 200cb93a386Sopenharmony_ci accessPattern == kStream_GrAccessPattern || 201cb93a386Sopenharmony_ci !gpu->vkCaps().gpuOnlyBuffersMorePerformant(); 202cb93a386Sopenharmony_ci if (!requiresMappable) { 203cb93a386Sopenharmony_ci bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; 204cb93a386Sopenharmony_ci } 205cb93a386Sopenharmony_ci 206cb93a386Sopenharmony_ci bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 207cb93a386Sopenharmony_ci bufInfo.queueFamilyIndexCount = 0; 208cb93a386Sopenharmony_ci bufInfo.pQueueFamilyIndices = nullptr; 209cb93a386Sopenharmony_ci 210cb93a386Sopenharmony_ci VkResult err = VK_CALL(gpu, CreateBuffer(gpu->device(), &bufInfo, nullptr, &buffer)); 211cb93a386Sopenharmony_ci if (err) { 212cb93a386Sopenharmony_ci return nullptr; 213cb93a386Sopenharmony_ci } 214cb93a386Sopenharmony_ci 215cb93a386Sopenharmony_ci if (!GrVkMemory::ImportAndBindBufferMemory(gpu, nativeBuffer, buffer, &alloc)) { 216cb93a386Sopenharmony_ci VK_CALL(gpu, DestroyBuffer(gpu->device(), buffer, nullptr)); 217cb93a386Sopenharmony_ci return nullptr; 218cb93a386Sopenharmony_ci } 219cb93a386Sopenharmony_ci 220cb93a386Sopenharmony_ci return sk_sp<GrVkBuffer>(new GrVkBuffer(gpu, bufferSize, bufferType, accessPattern, buffer, alloc, nullptr)); 221cb93a386Sopenharmony_ci} 222cb93a386Sopenharmony_ci 223cb93a386Sopenharmony_ci// OH ISSUE: Integrate Destroy and Free 224cb93a386Sopenharmony_civoid GrVkBuffer::DestroyAndFreeBufferMemory(const GrVkGpu* gpu, const GrVkAlloc& alloc, const VkBuffer& buffer) 225cb93a386Sopenharmony_ci{ 226cb93a386Sopenharmony_ci VK_CALL(gpu, DestroyBuffer(gpu->device(), buffer, nullptr)); 227cb93a386Sopenharmony_ci GrVkMemory::FreeBufferMemory(gpu, alloc); 228cb93a386Sopenharmony_ci} 229cb93a386Sopenharmony_ci 230cb93a386Sopenharmony_civoid GrVkBuffer::vkMap(size_t size) { 231cb93a386Sopenharmony_ci SkASSERT(!fMapPtr); 232cb93a386Sopenharmony_ci if (this->isVkMappable()) { 233cb93a386Sopenharmony_ci // Not every buffer will use command buffer usage refs and instead the command buffer just 234cb93a386Sopenharmony_ci // holds normal refs. Systems higher up in Ganesh should be making sure not to reuse a 235cb93a386Sopenharmony_ci // buffer that currently has a ref held by something else. However, we do need to make sure 236cb93a386Sopenharmony_ci // there isn't a buffer with just a command buffer usage that is trying to be mapped. 237cb93a386Sopenharmony_ci SkASSERT(this->internalHasNoCommandBufferUsages()); 238cb93a386Sopenharmony_ci SkASSERT(fAlloc.fSize > 0); 239cb93a386Sopenharmony_ci SkASSERT(fAlloc.fSize >= size); 240cb93a386Sopenharmony_ci fMapPtr = GrVkMemory::MapAlloc(this->getVkGpu(), fAlloc); 241cb93a386Sopenharmony_ci if (fMapPtr && this->intendedType() == GrGpuBufferType::kXferGpuToCpu) { 242cb93a386Sopenharmony_ci GrVkMemory::InvalidateMappedAlloc(this->getVkGpu(), fAlloc, 0, size); 243cb93a386Sopenharmony_ci } 244cb93a386Sopenharmony_ci } 245cb93a386Sopenharmony_ci} 246cb93a386Sopenharmony_ci 247cb93a386Sopenharmony_civoid GrVkBuffer::vkUnmap(size_t size) { 248cb93a386Sopenharmony_ci SkASSERT(fMapPtr && this->isVkMappable()); 249cb93a386Sopenharmony_ci 250cb93a386Sopenharmony_ci SkASSERT(fAlloc.fSize > 0); 251cb93a386Sopenharmony_ci SkASSERT(fAlloc.fSize >= size); 252cb93a386Sopenharmony_ci 253cb93a386Sopenharmony_ci GrVkGpu* gpu = this->getVkGpu(); 254cb93a386Sopenharmony_ci GrVkMemory::FlushMappedAlloc(gpu, fAlloc, 0, size); 255cb93a386Sopenharmony_ci GrVkMemory::UnmapAlloc(gpu, fAlloc); 256cb93a386Sopenharmony_ci} 257cb93a386Sopenharmony_ci 258cb93a386Sopenharmony_cistatic VkAccessFlags buffer_type_to_access_flags(GrGpuBufferType type) { 259cb93a386Sopenharmony_ci switch (type) { 260cb93a386Sopenharmony_ci case GrGpuBufferType::kIndex: 261cb93a386Sopenharmony_ci return VK_ACCESS_INDEX_READ_BIT; 262cb93a386Sopenharmony_ci case GrGpuBufferType::kVertex: 263cb93a386Sopenharmony_ci return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; 264cb93a386Sopenharmony_ci default: 265cb93a386Sopenharmony_ci // This helper is only called for static buffers so we should only ever see index or 266cb93a386Sopenharmony_ci // vertex buffers types 267cb93a386Sopenharmony_ci SkUNREACHABLE; 268cb93a386Sopenharmony_ci } 269cb93a386Sopenharmony_ci} 270cb93a386Sopenharmony_ci 271cb93a386Sopenharmony_civoid GrVkBuffer::copyCpuDataToGpuBuffer(const void* src, size_t size) { 272cb93a386Sopenharmony_ci SkASSERT(src); 273cb93a386Sopenharmony_ci 274cb93a386Sopenharmony_ci GrVkGpu* gpu = this->getVkGpu(); 275cb93a386Sopenharmony_ci 276cb93a386Sopenharmony_ci // We should never call this method in protected contexts. 277cb93a386Sopenharmony_ci SkASSERT(!gpu->protectedContext()); 278cb93a386Sopenharmony_ci 279cb93a386Sopenharmony_ci // The vulkan api restricts the use of vkCmdUpdateBuffer to updates that are less than or equal 280cb93a386Sopenharmony_ci // to 65536 bytes and a size the is 4 byte aligned. 281cb93a386Sopenharmony_ci if ((size <= 65536) && (0 == (size & 0x3)) && !gpu->vkCaps().avoidUpdateBuffers()) { 282cb93a386Sopenharmony_ci gpu->updateBuffer(sk_ref_sp(this), src, /*offset=*/0, size); 283cb93a386Sopenharmony_ci } else { 284cb93a386Sopenharmony_ci GrResourceProvider* resourceProvider = gpu->getContext()->priv().resourceProvider(); 285cb93a386Sopenharmony_ci sk_sp<GrGpuBuffer> transferBuffer = resourceProvider->createBuffer( 286cb93a386Sopenharmony_ci size, GrGpuBufferType::kXferCpuToGpu, kDynamic_GrAccessPattern, src); 287cb93a386Sopenharmony_ci if (!transferBuffer) { 288cb93a386Sopenharmony_ci return; 289cb93a386Sopenharmony_ci } 290cb93a386Sopenharmony_ci 291cb93a386Sopenharmony_ci gpu->copyBuffer(std::move(transferBuffer), sk_ref_sp(this), /*srcOffset=*/0, 292cb93a386Sopenharmony_ci /*dstOffset=*/0, size); 293cb93a386Sopenharmony_ci } 294cb93a386Sopenharmony_ci 295cb93a386Sopenharmony_ci this->addMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, 296cb93a386Sopenharmony_ci buffer_type_to_access_flags(this->intendedType()), 297cb93a386Sopenharmony_ci VK_PIPELINE_STAGE_TRANSFER_BIT, 298cb93a386Sopenharmony_ci VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 299cb93a386Sopenharmony_ci /*byRegion=*/false); 300cb93a386Sopenharmony_ci} 301cb93a386Sopenharmony_ci 302cb93a386Sopenharmony_civoid GrVkBuffer::addMemoryBarrier(VkAccessFlags srcAccessMask, 303cb93a386Sopenharmony_ci VkAccessFlags dstAccesMask, 304cb93a386Sopenharmony_ci VkPipelineStageFlags srcStageMask, 305cb93a386Sopenharmony_ci VkPipelineStageFlags dstStageMask, 306cb93a386Sopenharmony_ci bool byRegion) const { 307cb93a386Sopenharmony_ci VkBufferMemoryBarrier bufferMemoryBarrier = { 308cb93a386Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // sType 309cb93a386Sopenharmony_ci nullptr, // pNext 310cb93a386Sopenharmony_ci srcAccessMask, // srcAccessMask 311cb93a386Sopenharmony_ci dstAccesMask, // dstAccessMask 312cb93a386Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex 313cb93a386Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex 314cb93a386Sopenharmony_ci fBuffer, // buffer 315cb93a386Sopenharmony_ci 0, // offset 316cb93a386Sopenharmony_ci this->size(), // size 317cb93a386Sopenharmony_ci }; 318cb93a386Sopenharmony_ci 319cb93a386Sopenharmony_ci // TODO: restrict to area of buffer we're interested in 320cb93a386Sopenharmony_ci this->getVkGpu()->addBufferMemoryBarrier(srcStageMask, dstStageMask, byRegion, 321cb93a386Sopenharmony_ci &bufferMemoryBarrier); 322cb93a386Sopenharmony_ci} 323cb93a386Sopenharmony_ci 324cb93a386Sopenharmony_civoid GrVkBuffer::vkRelease() { 325cb93a386Sopenharmony_ci if (this->wasDestroyed()) { 326cb93a386Sopenharmony_ci return; 327cb93a386Sopenharmony_ci } 328cb93a386Sopenharmony_ci 329cb93a386Sopenharmony_ci if (fMapPtr) { 330cb93a386Sopenharmony_ci this->vkUnmap(this->size()); 331cb93a386Sopenharmony_ci fMapPtr = nullptr; 332cb93a386Sopenharmony_ci } 333cb93a386Sopenharmony_ci 334cb93a386Sopenharmony_ci if (fUniformDescriptorSet) { 335cb93a386Sopenharmony_ci fUniformDescriptorSet->recycle(); 336cb93a386Sopenharmony_ci fUniformDescriptorSet = nullptr; 337cb93a386Sopenharmony_ci } 338cb93a386Sopenharmony_ci 339cb93a386Sopenharmony_ci SkASSERT(fBuffer); 340cb93a386Sopenharmony_ci SkASSERT(fAlloc.fMemory && fAlloc.fBackendMemory); 341cb93a386Sopenharmony_ci 342cb93a386Sopenharmony_ci // OH ISSUE: asyn memory reclaimer 343cb93a386Sopenharmony_ci auto reclaimer = this->getVkGpu()->memoryReclaimer(); 344cb93a386Sopenharmony_ci if (!reclaimer || !reclaimer->addMemoryToWaitQueue(this->getVkGpu(), fAlloc, fBuffer)) { 345cb93a386Sopenharmony_ci DestroyAndFreeBufferMemory(this->getVkGpu(), fAlloc, fBuffer); 346cb93a386Sopenharmony_ci } 347cb93a386Sopenharmony_ci 348cb93a386Sopenharmony_ci fBuffer = VK_NULL_HANDLE; 349cb93a386Sopenharmony_ci fAlloc.fMemory = VK_NULL_HANDLE; 350cb93a386Sopenharmony_ci fAlloc.fBackendMemory = 0; 351cb93a386Sopenharmony_ci} 352cb93a386Sopenharmony_ci 353cb93a386Sopenharmony_civoid GrVkBuffer::onRelease() { 354cb93a386Sopenharmony_ci this->vkRelease(); 355cb93a386Sopenharmony_ci this->GrGpuBuffer::onRelease(); 356cb93a386Sopenharmony_ci} 357cb93a386Sopenharmony_ci 358cb93a386Sopenharmony_civoid GrVkBuffer::onAbandon() { 359cb93a386Sopenharmony_ci this->vkRelease(); 360cb93a386Sopenharmony_ci this->GrGpuBuffer::onAbandon(); 361cb93a386Sopenharmony_ci} 362cb93a386Sopenharmony_ci 363cb93a386Sopenharmony_civoid GrVkBuffer::onMap() { 364cb93a386Sopenharmony_ci if (!this->wasDestroyed()) { 365cb93a386Sopenharmony_ci this->vkMap(this->size()); 366cb93a386Sopenharmony_ci } 367cb93a386Sopenharmony_ci} 368cb93a386Sopenharmony_ci 369cb93a386Sopenharmony_civoid GrVkBuffer::onUnmap() { 370cb93a386Sopenharmony_ci if (!this->wasDestroyed()) { 371cb93a386Sopenharmony_ci this->vkUnmap(this->size()); 372cb93a386Sopenharmony_ci } 373cb93a386Sopenharmony_ci} 374cb93a386Sopenharmony_ci 375cb93a386Sopenharmony_cibool GrVkBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) { 376cb93a386Sopenharmony_ci if (this->wasDestroyed()) { 377cb93a386Sopenharmony_ci return false; 378cb93a386Sopenharmony_ci } 379cb93a386Sopenharmony_ci 380cb93a386Sopenharmony_ci if (srcSizeInBytes > this->size()) { 381cb93a386Sopenharmony_ci return false; 382cb93a386Sopenharmony_ci } 383cb93a386Sopenharmony_ci 384cb93a386Sopenharmony_ci if (this->isVkMappable()) { 385cb93a386Sopenharmony_ci this->vkMap(srcSizeInBytes); 386cb93a386Sopenharmony_ci if (!fMapPtr) { 387cb93a386Sopenharmony_ci return false; 388cb93a386Sopenharmony_ci } 389cb93a386Sopenharmony_ci memcpy(fMapPtr, src, srcSizeInBytes); 390cb93a386Sopenharmony_ci this->vkUnmap(srcSizeInBytes); 391cb93a386Sopenharmony_ci fMapPtr = nullptr; 392cb93a386Sopenharmony_ci } else { 393cb93a386Sopenharmony_ci this->copyCpuDataToGpuBuffer(src, srcSizeInBytes); 394cb93a386Sopenharmony_ci } 395cb93a386Sopenharmony_ci return true; 396cb93a386Sopenharmony_ci} 397cb93a386Sopenharmony_ci 398cb93a386Sopenharmony_ciGrVkGpu* GrVkBuffer::getVkGpu() const { 399cb93a386Sopenharmony_ci SkASSERT(!this->wasDestroyed()); 400cb93a386Sopenharmony_ci return static_cast<GrVkGpu*>(this->getGpu()); 401cb93a386Sopenharmony_ci} 402cb93a386Sopenharmony_ci 403cb93a386Sopenharmony_ciconst VkDescriptorSet* GrVkBuffer::uniformDescriptorSet() const { 404cb93a386Sopenharmony_ci SkASSERT(fUniformDescriptorSet); 405cb93a386Sopenharmony_ci return fUniformDescriptorSet->descriptorSet(); 406cb93a386Sopenharmony_ci} 407cb93a386Sopenharmony_ci 408