|
61 | 61 | plCommandBuffer* ptCommandBufferFreeList; |
62 | 62 | } plCommandPool; |
63 | 63 |
|
| 64 | +typedef struct _plBindGroupFreeSlot |
| 65 | +{ |
| 66 | + uint32_t uSize; |
| 67 | + uint32_t uOffset; |
| 68 | +} plBindGroupFreeSlot; |
| 69 | + |
64 | 70 | typedef struct _plBindGroupPool |
65 | 71 | { |
66 | | - plDevice* ptDevice; |
67 | | - id<MTLHeap> tDescriptorHeap; |
68 | | - size_t szHeapSize; |
69 | | - plBindGroupPoolDesc tDesc; |
70 | | - plMetalBuffer tArgumentBuffer; |
71 | | - size_t szCurrentArgumentOffset; |
| 72 | + plDevice* ptDevice; |
| 73 | + id<MTLHeap> tDescriptorHeap; |
| 74 | + size_t szHeapSize; |
| 75 | + plBindGroupPoolDesc tDesc; |
| 76 | + plMetalBuffer tArgumentBuffer; |
| 77 | + size_t szCurrentArgumentOffset; |
| 78 | + plBindGroupFreeSlot* sbtFreeSlots; |
72 | 79 | } plBindGroupPool; |
73 | 80 |
|
74 | 81 | typedef struct _plFrameContext |
|
109 | 116 | uint32_t uOffset; |
110 | 117 | uint32_t uSize; |
111 | 118 | plTextureHandle tFirstTexture; // for use with imgui for now (temp) |
| 119 | + plBindGroupPool* ptPool; |
112 | 120 | } plMetalBindGroup; |
113 | 121 |
|
114 | 122 | typedef struct _plMetalShader |
|
285 | 293 | const NSUInteger uCopyHeight = ptRegion->uImageHeight ? ptRegion->uImageHeight : 1; |
286 | 294 | const NSUInteger uCopyDepth = ptRegion->uImageDepth ? ptRegion->uImageDepth : 1; |
287 | 295 |
|
288 | | - const NSUInteger uBufferRowLength = ptRegion->uBufferRowLength ? ptRegion->uBufferRowLength : uCopyWidth * uFormatStride; |
289 | | - const NSUInteger uBufferImageHeight = ptRegion->uBufferImageHeight ? ptRegion->uBufferImageHeight : uCopyHeight * uFormatStride; |
| 296 | + const NSUInteger uBufferRowLength = ptRegion->uBufferRowLength ? ptRegion->uBufferRowLength * uFormatStride : uCopyWidth * uFormatStride; |
| 297 | + const NSUInteger uBufferImageHeight = ptRegion->uBufferImageHeight ? ptRegion->uBufferImageHeight * uFormatStride : uCopyHeight * uFormatStride; |
290 | 298 |
|
291 | 299 | const NSUInteger uBytesPerRow = uBufferRowLength; |
292 | 300 |
|
|
766 | 774 |
|
767 | 775 | plMetalBindGroup tMetalBindGroup = { |
768 | 776 | .tLayout = *ptLayout, |
| 777 | + .ptPool = ptDesc->ptPool |
769 | 778 | }; |
770 | 779 |
|
771 | 780 | tMetalBindGroup.tShaderArgumentBuffer = ptDesc->ptPool->tArgumentBuffer.tBuffer; |
772 | | - tMetalBindGroup.uOffset = ptDesc->ptPool->szCurrentArgumentOffset; |
| 781 | + |
| 782 | + // get new |
| 783 | + if(ptDesc->ptPool->szCurrentArgumentOffset + argumentBufferLength <= ptDesc->ptPool->szHeapSize) |
| 784 | + { |
| 785 | + tMetalBindGroup.uOffset = ptDesc->ptPool->szCurrentArgumentOffset; |
| 786 | + PL_ASSERT(ptDesc->ptPool->szCurrentArgumentOffset + argumentBufferLength <= ptDesc->ptPool->szHeapSize); |
| 787 | + ptDesc->ptPool->szCurrentArgumentOffset += argumentBufferLength; |
| 788 | + } |
| 789 | + else // full so lets recycle |
| 790 | + { |
| 791 | + // check for free slot |
| 792 | + uint32_t uBestSlot = UINT32_MAX; |
| 793 | + uint32_t uSlotCount = pl_sb_size(ptDesc->ptPool->sbtFreeSlots); |
| 794 | + for(uint32_t i = 0; i < uSlotCount; i++) |
| 795 | + { |
| 796 | + if(ptDesc->ptPool->sbtFreeSlots[i].uSize == argumentBufferLength) |
| 797 | + { |
| 798 | + uBestSlot = i; |
| 799 | + break; |
| 800 | + } |
| 801 | + else if(ptDesc->ptPool->sbtFreeSlots[i].uSize > argumentBufferLength) |
| 802 | + { |
| 803 | + if(uBestSlot == UINT32_MAX) |
| 804 | + uBestSlot = i; |
| 805 | + else if(ptDesc->ptPool->sbtFreeSlots[i].uSize < ptDesc->ptPool->sbtFreeSlots[uBestSlot].uSize) |
| 806 | + uBestSlot = i; |
| 807 | + } |
| 808 | + } |
| 809 | + |
| 810 | + PL_ASSERT(uBestSlot != UINT32_MAX); |
| 811 | + tMetalBindGroup.uOffset = ptDesc->ptPool->sbtFreeSlots[uBestSlot].uOffset; |
| 812 | + pl_sb_del_swap(ptDesc->ptPool->sbtFreeSlots, uBestSlot); |
| 813 | + } |
773 | 814 | tMetalBindGroup.uSize = argumentBufferLength; |
774 | 815 |
|
775 | | - PL_ASSERT(ptDesc->ptPool->szCurrentArgumentOffset + argumentBufferLength <= ptDesc->ptPool->szHeapSize); |
776 | | - ptDesc->ptPool->szCurrentArgumentOffset += argumentBufferLength; |
777 | 816 | [tMetalBindGroup.tShaderArgumentBuffer retain]; |
778 | 817 | if(ptDesc->pcDebugName) |
779 | 818 | tMetalBindGroup.tShaderArgumentBuffer.label = [NSString stringWithUTF8String:ptDesc->pcDebugName]; |
|
897 | 936 | void |
898 | 937 | pl_graphics_cleanup_bind_group_pool(plBindGroupPool* ptPool) |
899 | 938 | { |
| 939 | + pl_sb_free(ptPool->sbtFreeSlots); |
900 | 940 | PL_FREE(ptPool); |
901 | 941 | } |
902 | 942 |
|
|
3096 | 3136 | const uint16_t iBindGroupIndex = ptGarbage->sbtBindGroups[i].uIndex; |
3097 | 3137 | plBindGroup* ptResource = &ptDevice->sbtBindGroupsCold[iBindGroupIndex]; |
3098 | 3138 | plMetalBindGroup* ptMetalResource = &ptDevice->sbtBindGroupsHot[iBindGroupIndex]; |
| 3139 | + plBindGroupFreeSlot tFreeSlot = { |
| 3140 | + .uSize = ptMetalResource->uSize, |
| 3141 | + .uOffset = ptMetalResource->uOffset |
| 3142 | + }; |
| 3143 | + pl_sb_push(ptMetalResource->ptPool->sbtFreeSlots, tFreeSlot); |
3099 | 3144 | [ptMetalResource->tShaderArgumentBuffer release]; |
3100 | 3145 | ptMetalResource->tShaderArgumentBuffer = nil; |
3101 | 3146 | pl_sb_push(ptDevice->sbtBindGroupFreeIndices, iBindGroupIndex); |
|
3322 | 3367 | pl_sb_push(ptDevice->sbtBindGroupFreeIndices, tHandle.uIndex); |
3323 | 3368 |
|
3324 | 3369 | plMetalBindGroup* ptMetalResource = &ptDevice->sbtBindGroupsHot[tHandle.uIndex]; |
| 3370 | + plBindGroupFreeSlot tFreeSlot = { |
| 3371 | + .uSize = ptMetalResource->uSize, |
| 3372 | + .uOffset = ptMetalResource->uOffset |
| 3373 | + }; |
| 3374 | + pl_sb_push(ptMetalResource->ptPool->sbtFreeSlots, tFreeSlot); |
3325 | 3375 | plBindGroup* ptResource = &ptDevice->sbtBindGroupsCold[tHandle.uIndex]; |
3326 | 3376 | [ptMetalResource->tShaderArgumentBuffer release]; |
3327 | 3377 | ptMetalResource->tShaderArgumentBuffer = nil; |
|
0 commit comments