Call makeResident only once per BufferObject

When different graphics allocations are created from
the same backing storage makeResident should be called only once.

Change-Id: Ide8ab385894505fd405eef010768dbcac3b92fba
Signed-off-by: Jacek Danecki <jacek.danecki@intel.com>
This commit is contained in:
Jacek Danecki
2018-06-08 14:40:21 +02:00
parent 892cf13c15
commit 4d48a6afec
4 changed files with 40 additions and 11 deletions

View File

@ -44,7 +44,7 @@
namespace OCLRT {
BufferObject::BufferObject(Drm *drm, int handle, bool isAllocated) : drm(drm), refCount(1), handle(handle), isReused(false), isAllocated(isAllocated) {
BufferObject::BufferObject(Drm *drm, int handle, bool isAllocated) : isResident(false), drm(drm), refCount(1), handle(handle), isReused(false), isAllocated(isAllocated) {
this->isSoftpin = false;
this->tiling_mode = I915_TILING_NONE;

View File

@ -88,8 +88,11 @@ class BufferObject {
ResidencyVector *getResidency() { return &residency; }
StorageAllocatorType peekAllocationType() const { return storageAllocatorType; }
void setAllocationType(StorageAllocatorType allocatorType) { this->storageAllocatorType = allocatorType; }
bool peekIsResident() const { return isResident; }
void setIsResident(bool isResident) { this->isResident = isResident; }
protected:
bool isResident;
BufferObject(Drm *drm, int handle, bool isAllocated);
Drm *drm;
@ -112,11 +115,11 @@ class BufferObject {
uint64_t offset64; // last-seen GPU offset
size_t size;
void *address; // GPU side virtual address
void *address; // GPU side virtual address
void *lockedAddress; // CPU side virtual address
bool isAllocated = false;
uint64_t unmapSize = 0;
StorageAllocatorType storageAllocatorType = UNKNOWN_ALLOCATOR;
};
}
} // namespace OCLRT

View File

@ -100,7 +100,8 @@ void DrmCommandStreamReceiver<GfxFamily>::makeResident(GraphicsAllocation &gfxAl
template <typename GfxFamily>
void DrmCommandStreamReceiver<GfxFamily>::makeResident(BufferObject *bo) {
if (bo) {
if (bo && !bo->peekIsResident()) {
bo->setIsResident(true);
residency.push_back(bo);
}
}
@ -108,14 +109,12 @@ void DrmCommandStreamReceiver<GfxFamily>::makeResident(BufferObject *bo) {
template <typename GfxFamily>
void DrmCommandStreamReceiver<GfxFamily>::processResidency(ResidencyContainer *inputAllocationsForResidency) {
auto &allocationsForResidency = inputAllocationsForResidency ? *inputAllocationsForResidency : getMemoryManager()->getResidencyAllocations();
for (uint32_t i = 0; i < allocationsForResidency.size(); i++) {
DrmAllocation *drmAlloc = reinterpret_cast<DrmAllocation *>(allocationsForResidency[i]);
for (uint32_t a = 0; a < allocationsForResidency.size(); a++) {
DrmAllocation *drmAlloc = reinterpret_cast<DrmAllocation *>(allocationsForResidency[a]);
if (drmAlloc->fragmentsStorage.fragmentCount) {
for (unsigned int i = 0; i < drmAlloc->fragmentsStorage.fragmentCount; i++) {
if (!drmAlloc->fragmentsStorage.fragmentStorageData[i].residency->resident) {
makeResident(drmAlloc->fragmentsStorage.fragmentStorageData[i].osHandleStorage->bo);
drmAlloc->fragmentsStorage.fragmentStorageData[i].residency->resident = true;
}
for (unsigned int f = 0; f < drmAlloc->fragmentsStorage.fragmentCount; f++) {
makeResident(drmAlloc->fragmentsStorage.fragmentStorageData[f].osHandleStorage->bo);
drmAlloc->fragmentsStorage.fragmentStorageData[f].residency->resident = true;
}
} else {
BufferObject *bo = drmAlloc->getBO();
@ -130,11 +129,15 @@ void DrmCommandStreamReceiver<GfxFamily>::makeNonResident(GraphicsAllocation &gf
// If flush wasn't called we need to make all objects non-resident.
// If makeNonResident is called before flush, vector will be cleared.
if (gfxAllocation.residencyTaskCount != ObjectNotResident) {
for (auto &surface : residency) {
surface->setIsResident(false);
}
if (this->residency.size() != 0) {
this->residency.clear();
}
if (gfxAllocation.fragmentsStorage.fragmentCount) {
for (auto fragmentId = 0u; fragmentId < gfxAllocation.fragmentsStorage.fragmentCount; fragmentId++) {
gfxAllocation.fragmentsStorage.fragmentStorageData[fragmentId].osHandleStorage->bo->setIsResident(false);
gfxAllocation.fragmentsStorage.fragmentStorageData[fragmentId].residency->resident = false;
}
}

View File

@ -1364,6 +1364,29 @@ TEST_F(DrmCommandStreamLeaksTest, GivenAllocationsContainingDifferentCountOfFrag
EXPECT_EQ(0u, hostPtrManager.getFragmentCount());
}
TEST_F(DrmCommandStreamLeaksTest, GivenTwoAllocationsWhenBackingStorageIsTheSameThenMakeResidentShouldAddOnlyOneLocation) {
auto ptr = (void *)0x1000;
auto size = MemoryConstants::pageSize;
auto ptr2 = (void *)0x1000;
auto allocation = mm->allocateGraphicsMemory(size, ptr);
auto allocation2 = mm->allocateGraphicsMemory(size, ptr2);
csr->makeResident(*allocation);
csr->makeResident(*allocation2);
csr->processResidency(nullptr);
EXPECT_EQ(tCsr->getResidencyVector()->size(), 1u);
csr->makeNonResident(*allocation);
csr->makeNonResident(*allocation2);
mm->freeGraphicsMemory(allocation);
mm->freeGraphicsMemory(allocation2);
mm->clearResidencyAllocations();
}
TEST_F(DrmCommandStreamLeaksTest, makeResidentSizeZero) {
std::unique_ptr<BufferObject> buffer(this->createBO(0));
DrmAllocation allocation(buffer.get(), nullptr, buffer->peekSize());