Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: src/gpu/vk/GrVkMemory.cpp

Issue 2128673002: Pull out freelist allocation from GrVkSubHeap (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Clean up and fixes Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/vk/GrVkMemory.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrVkMemory.h" 8 #include "GrVkMemory.h"
9 9
10 #include "GrVkGpu.h" 10 #include "GrVkGpu.h"
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 } else if (VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == layout) { 235 } else if (VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == layout) {
236 flags = VK_ACCESS_TRANSFER_WRITE_BIT; 236 flags = VK_ACCESS_TRANSFER_WRITE_BIT;
237 } else if (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == layout) { 237 } else if (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == layout) {
238 flags = VK_ACCESS_TRANSFER_READ_BIT; 238 flags = VK_ACCESS_TRANSFER_READ_BIT;
239 } else if (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout) { 239 } else if (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout) {
240 flags = VK_ACCESS_SHADER_READ_BIT; 240 flags = VK_ACCESS_SHADER_READ_BIT;
241 } 241 }
242 return flags; 242 return flags;
243 } 243 }
244 244
245 GrVkSubHeap::GrVkSubHeap(const GrVkGpu* gpu, uint32_t memoryTypeIndex, 245 bool GrVkFreeListAlloc::alloc(VkDeviceSize requestedSize,
246 VkDeviceSize size, VkDeviceSize alignment) 246 VkDeviceSize* allocOffset, VkDeviceSize* allocSize ) {
247 : fGpu(gpu) 247 VkDeviceSize alignedSize = align_size(requestedSize, fAlignment);
248 , fMemoryTypeIndex(memoryTypeIndex) {
249
250 VkMemoryAllocateInfo allocInfo = {
251 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
252 NULL, // pNext
253 size, // allocationSize
254 memoryTypeIndex, // memoryTypeIndex
255 };
256
257 VkResult err = GR_VK_CALL(gpu->vkInterface(), AllocateMemory(gpu->device(),
258 &allocInfo,
259 nullptr,
260 &fAlloc));
261
262 if (VK_SUCCESS == err) {
263 fSize = size;
264 fAlignment = alignment;
265 fFreeSize = size;
266 fLargestBlockSize = size;
267 fLargestBlockOffset = 0;
268
269 Block* block = fFreeList.addToTail();
270 block->fOffset = 0;
271 block->fSize = fSize;
272 } else {
273 fSize = 0;
274 fAlignment = 0;
275 fFreeSize = 0;
276 fLargestBlockSize = 0;
277 }
278 }
279
280 GrVkSubHeap::~GrVkSubHeap() {
281 const GrVkInterface* iface = fGpu->vkInterface();
282 GR_VK_CALL(iface, FreeMemory(fGpu->device(), fAlloc, nullptr));
283
284 fFreeList.reset();
285 }
286
287 bool GrVkSubHeap::alloc(VkDeviceSize size, GrVkAlloc* alloc) {
288 VkDeviceSize alignedSize = align_size(size, fAlignment);
289 248
290 // find the smallest block big enough for our allocation 249 // find the smallest block big enough for our allocation
291 FreeList::Iter iter = fFreeList.headIter(); 250 FreeList::Iter iter = fFreeList.headIter();
292 FreeList::Iter bestFitIter; 251 FreeList::Iter bestFitIter;
293 VkDeviceSize bestFitSize = fSize + 1; 252 VkDeviceSize bestFitSize = fSize + 1;
294 VkDeviceSize secondLargestSize = 0; 253 VkDeviceSize secondLargestSize = 0;
295 VkDeviceSize secondLargestOffset = 0; 254 VkDeviceSize secondLargestOffset = 0;
296 while (iter.get()) { 255 while (iter.get()) {
297 Block* block = iter.get(); 256 Block* block = iter.get();
298 // need to adjust size to match desired alignment 257 // need to adjust size to match desired alignment
299 SkASSERT(align_size(block->fOffset, fAlignment) - block->fOffset == 0); 258 SkASSERT(align_size(block->fOffset, fAlignment) - block->fOffset == 0);
300 if (block->fSize >= alignedSize && block->fSize < bestFitSize) { 259 if (block->fSize >= alignedSize && block->fSize < bestFitSize) {
301 bestFitIter = iter; 260 bestFitIter = iter;
302 bestFitSize = block->fSize; 261 bestFitSize = block->fSize;
303 } 262 }
304 if (secondLargestSize < block->fSize && block->fOffset != fLargestBlockO ffset) { 263 if (secondLargestSize < block->fSize && block->fOffset != fLargestBlockO ffset) {
305 secondLargestSize = block->fSize; 264 secondLargestSize = block->fSize;
306 secondLargestOffset = block->fOffset; 265 secondLargestOffset = block->fOffset;
307 } 266 }
308 iter.next(); 267 iter.next();
309 } 268 }
310 SkASSERT(secondLargestSize <= fLargestBlockSize); 269 SkASSERT(secondLargestSize <= fLargestBlockSize);
311 270
312 Block* bestFit = bestFitIter.get(); 271 Block* bestFit = bestFitIter.get();
313 if (bestFit) { 272 if (bestFit) {
314 alloc->fMemory = fAlloc;
315 SkASSERT(align_size(bestFit->fOffset, fAlignment) == bestFit->fOffset); 273 SkASSERT(align_size(bestFit->fOffset, fAlignment) == bestFit->fOffset);
316 alloc->fOffset = bestFit->fOffset; 274 *allocOffset = bestFit->fOffset;
317 alloc->fSize = alignedSize; 275 *allocSize = alignedSize;
318 // adjust or remove current block 276 // adjust or remove current block
319 VkDeviceSize originalBestFitOffset = bestFit->fOffset; 277 VkDeviceSize originalBestFitOffset = bestFit->fOffset;
320 if (bestFit->fSize > alignedSize) { 278 if (bestFit->fSize > alignedSize) {
321 bestFit->fOffset += alignedSize; 279 bestFit->fOffset += alignedSize;
322 bestFit->fSize -= alignedSize; 280 bestFit->fSize -= alignedSize;
323 if (fLargestBlockOffset == originalBestFitOffset) { 281 if (fLargestBlockOffset == originalBestFitOffset) {
324 if (bestFit->fSize >= secondLargestSize) { 282 if (bestFit->fSize >= secondLargestSize) {
325 fLargestBlockSize = bestFit->fSize; 283 fLargestBlockSize = bestFit->fSize;
326 fLargestBlockOffset = bestFit->fOffset; 284 fLargestBlockOffset = bestFit->fOffset;
327 } else { 285 } else {
(...skipping 27 matching lines...) Expand all
355 Block* block = iter.get(); 313 Block* block = iter.get();
356 if (largestSize < block->fSize) { 314 if (largestSize < block->fSize) {
357 largestSize = block->fSize; 315 largestSize = block->fSize;
358 } 316 }
359 iter.next(); 317 iter.next();
360 } 318 }
361 SkASSERT(largestSize == fLargestBlockSize); 319 SkASSERT(largestSize == fLargestBlockSize);
362 #endif 320 #endif
363 } 321 }
364 fFreeSize -= alignedSize; 322 fFreeSize -= alignedSize;
365 SkASSERT(alloc->fSize > 0); 323 SkASSERT(allocSize > 0);
366 324
367 return true; 325 return true;
368 } 326 }
369 327
370 SkDebugf("Can't allocate %d bytes, %d bytes available, largest free block %d \n", alignedSize, fFreeSize, fLargestBlockSize); 328 SkDebugf("Can't allocate %d bytes, %d bytes available, largest free block %d \n", alignedSize, fFreeSize, fLargestBlockSize);
371 329
372 return false; 330 return false;
373 } 331 }
374 332
375 333 void GrVkFreeListAlloc::free(VkDeviceSize allocOffset, VkDeviceSize allocSize) {
376 void GrVkSubHeap::free(const GrVkAlloc& alloc) {
377 SkASSERT(alloc.fMemory == fAlloc);
378
379 // find the block right after this allocation 334 // find the block right after this allocation
380 FreeList::Iter iter = fFreeList.headIter(); 335 FreeList::Iter iter = fFreeList.headIter();
381 FreeList::Iter prev; 336 FreeList::Iter prev;
382 while (iter.get() && iter.get()->fOffset < alloc.fOffset) { 337 while (iter.get() && iter.get()->fOffset < allocOffset) {
383 prev = iter; 338 prev = iter;
384 iter.next(); 339 iter.next();
385 } 340 }
386 // we have four cases: 341 // we have four cases:
387 // we exactly follow the previous one 342 // we exactly follow the previous one
388 Block* block; 343 Block* block;
389 if (prev.get() && prev.get()->fOffset + prev.get()->fSize == alloc.fOffset) { 344 if (prev.get() && prev.get()->fOffset + prev.get()->fSize == allocOffset) {
390 block = prev.get(); 345 block = prev.get();
391 block->fSize += alloc.fSize; 346 block->fSize += allocSize;
392 if (block->fOffset == fLargestBlockOffset) { 347 if (block->fOffset == fLargestBlockOffset) {
393 fLargestBlockSize = block->fSize; 348 fLargestBlockSize = block->fSize;
394 } 349 }
395 // and additionally we may exactly precede the next one 350 // and additionally we may exactly precede the next one
396 if (iter.get() && iter.get()->fOffset == alloc.fOffset + alloc.fSize) { 351 if (iter.get() && iter.get()->fOffset == allocOffset + allocSize) {
397 block->fSize += iter.get()->fSize; 352 block->fSize += iter.get()->fSize;
398 if (iter.get()->fOffset == fLargestBlockOffset) { 353 if (iter.get()->fOffset == fLargestBlockOffset) {
399 fLargestBlockOffset = block->fOffset; 354 fLargestBlockOffset = block->fOffset;
400 fLargestBlockSize = block->fSize; 355 fLargestBlockSize = block->fSize;
401 } 356 }
402 fFreeList.remove(iter.get()); 357 fFreeList.remove(iter.get());
403 } 358 }
404 // or we only exactly proceed the next one 359 // or we only exactly proceed the next one
405 } else if (iter.get() && iter.get()->fOffset == alloc.fOffset + alloc.fSize) { 360 } else if (iter.get() && iter.get()->fOffset == allocOffset + allocSize) {
406 block = iter.get(); 361 block = iter.get();
407 block->fSize += alloc.fSize; 362 block->fSize += allocSize;
408 if (block->fOffset == fLargestBlockOffset) { 363 if (block->fOffset == fLargestBlockOffset) {
409 fLargestBlockOffset = alloc.fOffset; 364 fLargestBlockOffset = allocOffset;
410 fLargestBlockSize = block->fSize; 365 fLargestBlockSize = block->fSize;
411 } 366 }
412 block->fOffset = alloc.fOffset; 367 block->fOffset = allocOffset;
413 // or we fall somewhere in between, with gaps 368 // or we fall somewhere in between, with gaps
414 } else { 369 } else {
415 block = fFreeList.addBefore(iter); 370 block = fFreeList.addBefore(iter);
416 block->fOffset = alloc.fOffset; 371 block->fOffset = allocOffset;
417 block->fSize = alloc.fSize; 372 block->fSize = allocSize;
418 } 373 }
419 fFreeSize += alloc.fSize; 374 fFreeSize += allocSize;
420 if (block->fSize > fLargestBlockSize) { 375 if (block->fSize > fLargestBlockSize) {
421 fLargestBlockSize = block->fSize; 376 fLargestBlockSize = block->fSize;
422 fLargestBlockOffset = block->fOffset; 377 fLargestBlockOffset = block->fOffset;
423 } 378 }
424 379
425 #ifdef SK_DEBUG 380 #ifdef SK_DEBUG
426 VkDeviceSize largestSize = 0; 381 VkDeviceSize largestSize = 0;
427 iter = fFreeList.headIter(); 382 iter = fFreeList.headIter();
428 while (iter.get()) { 383 while (iter.get()) {
429 Block* block = iter.get(); 384 Block* block = iter.get();
430 if (largestSize < block->fSize) { 385 if (largestSize < block->fSize) {
431 largestSize = block->fSize; 386 largestSize = block->fSize;
432 } 387 }
433 iter.next(); 388 iter.next();
434 } 389 }
435 SkASSERT(fLargestBlockSize == largestSize); 390 SkASSERT(fLargestBlockSize == largestSize);
436 #endif 391 #endif
437 } 392 }
438 393
439 GrVkHeap::~GrVkHeap() { 394 GrVkSubHeap::GrVkSubHeap(const GrVkGpu* gpu, uint32_t memoryTypeIndex,
395 VkDeviceSize size, VkDeviceSize alignment)
396 : INHERITED(size, alignment)
397 , fGpu(gpu)
398 , fMemoryTypeIndex(memoryTypeIndex) {
399
400 VkMemoryAllocateInfo allocInfo = {
401 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
402 NULL, // pNext
403 size, // allocationSize
404 memoryTypeIndex, // memoryTypeIndex
405 };
406
407 VkResult err = GR_VK_CALL(gpu->vkInterface(), AllocateMemory(gpu->device(),
408 &allocInfo,
409 nullptr,
410 &fAlloc));
411 if (VK_SUCCESS != err) {
412 this->reset();
413 }
414 }
415
416 GrVkSubHeap::~GrVkSubHeap() {
417 const GrVkInterface* iface = fGpu->vkInterface();
418 GR_VK_CALL(iface, FreeMemory(fGpu->device(), fAlloc, nullptr));
419 }
420
421 bool GrVkSubHeap::alloc(VkDeviceSize size, GrVkAlloc* alloc) {
422 alloc->fMemory = fAlloc;
423 return INHERITED::alloc(size, &alloc->fOffset, &alloc->fSize);
424 }
425
426 void GrVkSubHeap::free(const GrVkAlloc& alloc) {
427 SkASSERT(alloc.fMemory == fAlloc);
428
429 INHERITED::free(alloc.fOffset, alloc.fSize);
440 } 430 }
441 431
442 bool GrVkHeap::subAlloc(VkDeviceSize size, VkDeviceSize alignment, 432 bool GrVkHeap::subAlloc(VkDeviceSize size, VkDeviceSize alignment,
443 uint32_t memoryTypeIndex, GrVkAlloc* alloc) { 433 uint32_t memoryTypeIndex, GrVkAlloc* alloc) {
444 VkDeviceSize alignedSize = align_size(size, alignment); 434 VkDeviceSize alignedSize = align_size(size, alignment);
445 435
446 // if requested is larger than our subheap allocation, just alloc directly 436 // if requested is larger than our subheap allocation, just alloc directly
447 if (alignedSize > fSubHeapSize) { 437 if (alignedSize > fSubHeapSize) {
448 VkMemoryAllocateInfo allocInfo = { 438 VkMemoryAllocateInfo allocInfo = {
449 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType 439 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 fSubHeaps[i]->free(alloc); 548 fSubHeaps[i]->free(alloc);
559 fUsedSize -= alloc.fSize; 549 fUsedSize -= alloc.fSize;
560 return true; 550 return true;
561 } 551 }
562 } 552 }
563 553
564 return false; 554 return false;
565 } 555 }
566 556
567 557
OLDNEW
« no previous file with comments | « src/gpu/vk/GrVkMemory.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698