Create wrapper for drm_i915_gem_exec_object2

Related-To: NEO-6852
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2022-05-11 15:06:01 +00:00
committed by Compute-Runtime-Automation
parent 0b68fdbe52
commit 268393d776
17 changed files with 172 additions and 92 deletions

View File

@@ -9,6 +9,7 @@
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/libult/linux/drm_mock.h"
#include "shared/test/common/mocks/linux/mock_drm_allocation.h"
#include "shared/test/common/mocks/linux/mock_drm_wrappers.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_gmm_helper.h"
#include "shared/test/common/os_interface/linux/device_command_stream_fixture.h"
@@ -25,7 +26,7 @@ TEST_F(DrmBufferObjectTest, WhenCallingExecThenReturnIsCorrect) {
mock->ioctl_expected.total = 1;
mock->ioctl_res = 0;
drm_i915_gem_exec_object2 execObjectsStorage = {};
ExecObject execObjectsStorage = {};
auto ret = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, 0, 0);
EXPECT_EQ(mock->ioctl_res, ret);
EXPECT_EQ(0u, mock->execBuffer.flags);
@@ -35,7 +36,7 @@ TEST_F(DrmBufferObjectTest, GivenInvalidParamsWhenCallingExecThenEfaultIsReturne
mock->ioctl_expected.total = 3;
mock->ioctl_res = -1;
mock->errnoValue = EFAULT;
drm_i915_gem_exec_object2 execObjectsStorage = {};
ExecObject execObjectsStorage = {};
EXPECT_EQ(EFAULT, bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, 0, 0));
}
@@ -46,7 +47,7 @@ TEST_F(DrmBufferObjectTest, GivenDetectedGpuHangDuringEvictUnusedAllocationsWhen
bo->callBaseEvictUnusedAllocations = false;
drm_i915_gem_exec_object2 execObjectsStorage = {};
ExecObject execObjectsStorage = {};
const auto result = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, 0, 0);
EXPECT_EQ(BufferObject::gpuHangDetected, result);
@@ -80,25 +81,25 @@ TEST_F(DrmBufferObjectTest, givenBindAvailableWhenCallWaitThenNoIoctlIsCalled) {
}
TEST_F(DrmBufferObjectTest, givenAddressThatWhenSizeIsAddedCrosses32BitBoundaryWhenExecIsCalledThen48BitFlagIsSet) {
drm_i915_gem_exec_object2 execObject;
MockExecObject execObject{};
memset(&execObject, 0, sizeof(execObject));
bo->setAddress(((uint64_t)1u << 32) - 0x1000u);
bo->setSize(0x1000);
bo->fillExecObject(execObject, osContext.get(), 0, 1);
//base address + size > size of 32bit address space
EXPECT_TRUE(execObject.flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS);
EXPECT_TRUE(execObject.has48BAddressSupportFlag());
}
TEST_F(DrmBufferObjectTest, givenAddressThatWhenSizeIsAddedWithin32BitBoundaryWhenExecIsCalledThen48BitFlagSet) {
drm_i915_gem_exec_object2 execObject;
MockExecObject execObject{};
memset(&execObject, 0, sizeof(execObject));
bo->setAddress(((uint64_t)1u << 32) - 0x1000u);
bo->setSize(0xFFF);
bo->fillExecObject(execObject, osContext.get(), 0, 1);
//base address + size < size of 32bit address space
EXPECT_TRUE(execObject.flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS);
EXPECT_TRUE(execObject.has48BAddressSupportFlag());
}
TEST_F(DrmBufferObjectTest, whenExecFailsThenPinFails) {
@@ -179,7 +180,7 @@ TEST_F(DrmBufferObjectTest, whenPrintExecutionBufferIsSetToTrueThenMessageFoundI
mock->ioctl_expected.total = 1;
DebugManagerStateRestore restore;
DebugManager.flags.PrintExecutionBuffer.set(true);
drm_i915_gem_exec_object2 execObjectsStorage = {};
ExecObject execObjectsStorage = {};
testing::internal::CaptureStdout();
auto ret = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, 0, 0);
@@ -369,7 +370,7 @@ TEST(DrmBufferObject, givenDrmIoctlReturnsErrorNotSupportedThenBufferObjectRetur
std::unique_ptr<OsContextLinux> osContext;
osContext.reset(new OsContextLinux(*drm, 0u, EngineDescriptorHelper::getDefaultDescriptor()));
drm_i915_gem_exec_object2 execObjectsStorage = {};
ExecObject execObjectsStorage = {};
auto ret = bo.exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, 0, 0);
EXPECT_NE(0, ret);
}
@@ -538,7 +539,7 @@ TEST(DrmBufferObject, whenMarkForCapturedCalledThenIsMarkedForCaptureReturnsTrue
}
TEST_F(DrmBufferObjectTest, givenBoMarkedForCaptureWhenFillingExecObjectThenCaptureFlagIsSet) {
drm_i915_gem_exec_object2 execObject;
MockExecObject execObject{};
memset(&execObject, 0, sizeof(execObject));
bo->markForCapture();
@@ -546,11 +547,11 @@ TEST_F(DrmBufferObjectTest, givenBoMarkedForCaptureWhenFillingExecObjectThenCapt
bo->setSize(0x1000);
bo->fillExecObject(execObject, osContext.get(), 0, 1);
EXPECT_TRUE(execObject.flags & EXEC_OBJECT_CAPTURE);
EXPECT_TRUE(execObject.hasCaptureFlag());
}
TEST_F(DrmBufferObjectTest, givenAsyncDebugFlagWhenFillingExecObjectThenFlagIsSet) {
drm_i915_gem_exec_object2 execObject;
MockExecObject execObject{};
DebugManagerStateRestore restorer;
DebugManager.flags.UseAsyncDrmExec.set(1);
@@ -559,7 +560,7 @@ TEST_F(DrmBufferObjectTest, givenAsyncDebugFlagWhenFillingExecObjectThenFlagIsSe
bo->setSize(0x1000);
bo->fillExecObject(execObject, osContext.get(), 0, 1);
EXPECT_TRUE(execObject.flags & EXEC_OBJECT_ASYNC);
EXPECT_TRUE(execObject.hasAsyncFlag());
}
TEST_F(DrmBufferObjectTest, given47bitAddressWhenSetThenIsAddressNotCanonized) {

View File

@@ -25,7 +25,7 @@ TEST_F(DrmBufferObjectPrelimTest, GivenCompletionAddressWhenCallingExecThenRetur
constexpr uint32_t completionValue = 33;
constexpr uint64_t expectedCompletionValue = completionValue;
drm_i915_gem_exec_object2 execObjectsStorage = {};
ExecObject execObjectsStorage = {};
auto ret = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, completionAddress, completionValue);
EXPECT_EQ(0, ret);
EXPECT_EQ(completionAddress, mock->context.completionAddress);

View File

@@ -25,6 +25,7 @@
#include "shared/test/common/helpers/dispatch_flags_helper.h"
#include "shared/test/common/helpers/execution_environment_helper.h"
#include "shared/test/common/mocks/linux/mock_drm_command_stream_receiver.h"
#include "shared/test/common/mocks/linux/mock_drm_wrappers.h"
#include "shared/test/common/mocks/mock_allocation_properties.h"
#include "shared/test/common/mocks/mock_gmm.h"
#include "shared/test/common/mocks/mock_gmm_page_table_mngr.h"
@@ -72,7 +73,7 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenCommandStreamWhenItIsFlush
HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenTaskThatRequiresLargeResourceCountWhenItIsFlushedThenExecStorageIsResized) {
std::vector<GraphicsAllocation *> graphicsAllocations;
auto &execStorage = static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->getExecStorage();
auto &execStorage = static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->execObjectsStorage;
execStorage.resize(0);
for (auto id = 0; id < 10; id++) {
@@ -1585,18 +1586,19 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenAllocInMemoryOperationsInt
csr->flush(batchBuffer, csr->getResidencyAllocations());
const auto boRequirments = [&allocation](const auto &bo) {
return (static_cast<int>(bo.handle) == static_cast<DrmAllocation *>(allocation)->getBO()->peekHandle() &&
bo.offset == static_cast<DrmAllocation *>(allocation)->getBO()->peekAddress());
const auto execObjectRequirements = [&allocation](const auto &execObject) {
auto mockExecObject = static_cast<const MockExecObject &>(execObject);
return (static_cast<int>(mockExecObject.getHandle()) == static_cast<DrmAllocation *>(allocation)->getBO()->peekHandle() &&
mockExecObject.getOffset() == static_cast<DrmAllocation *>(allocation)->getBO()->peekAddress());
};
auto &residency = static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->getExecStorage();
EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), boRequirments) != residency.end());
auto &residency = static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->execObjectsStorage;
EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) != residency.end());
EXPECT_EQ(residency.size(), 2u);
residency.clear();
csr->flush(batchBuffer, csr->getResidencyAllocations());
EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), boRequirments) != residency.end());
EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) != residency.end());
EXPECT_EQ(residency.size(), 2u);
residency.clear();
@@ -1605,7 +1607,7 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenAllocInMemoryOperationsInt
csr->flush(batchBuffer, csr->getResidencyAllocations());
EXPECT_FALSE(std::find_if(residency.begin(), residency.end(), boRequirments) != residency.end());
EXPECT_FALSE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) != residency.end());
EXPECT_EQ(residency.size(), 1u);
mm->freeGraphicsMemory(allocation);

View File

@@ -15,6 +15,7 @@
#include "shared/test/common/libult/linux/drm_mock_helper.h"
#include "shared/test/common/libult/linux/drm_mock_prelim_context.h"
#include "shared/test/common/libult/linux/drm_query_mock.h"
#include "shared/test/common/mocks/linux/mock_drm_wrappers.h"
#include "shared/test/common/mocks/mock_allocation_properties.h"
#include "shared/test/common/mocks/mock_gfx_partition.h"
#include "shared/test/common/mocks/mock_gmm.h"
@@ -2086,13 +2087,14 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedPrelimTest, givenUseVmBindSetWhenFlus
csr->flush(batchBuffer, csr->getResidencyAllocations());
const auto boRequirments = [&allocation](const auto &bo) {
return (static_cast<int>(bo.handle) == 0u &&
bo.offset == static_cast<DrmAllocation *>(allocation)->getBO()->peekAddress());
const auto execObjectRequirements = [&allocation](const auto &execObject) {
auto mockExecObject = static_cast<const MockExecObject &>(execObject);
return (mockExecObject.getHandle() == 0 &&
mockExecObject.getOffset() == static_cast<DrmAllocation *>(allocation)->getBO()->peekAddress());
};
auto &residency = static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->getExecStorage();
EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), boRequirments) == residency.end());
auto &residency = static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->execObjectsStorage;
EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) == residency.end());
EXPECT_EQ(residency.size(), 1u);
residency.clear();
@@ -2115,13 +2117,14 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedPrelimTest, givenUseVmBindAndPassBoun
csr->flush(batchBuffer, csr->getResidencyAllocations());
const auto boRequirments = [&allocation](const auto &bo) {
return (static_cast<int>(bo.handle) == 0 &&
bo.offset == static_cast<DrmAllocation *>(allocation)->getBO()->peekAddress());
const auto execObjectRequirements = [&allocation](const auto &execObject) {
auto mockExecObject = static_cast<const MockExecObject &>(execObject);
return (mockExecObject.getHandle() == 0 &&
mockExecObject.getOffset() == static_cast<DrmAllocation *>(allocation)->getBO()->peekAddress());
};
auto &residency = static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->getExecStorage();
EXPECT_FALSE(std::find_if(residency.begin(), residency.end(), boRequirments) != residency.end());
auto &residency = static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->execObjectsStorage;
EXPECT_FALSE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) != residency.end());
EXPECT_EQ(residency.size(), 1u);
residency.clear();
@@ -2144,13 +2147,14 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedPrelimTest, givenUseVmBindAndPassBoun
csr->flush(batchBuffer, csr->getResidencyAllocations());
const auto boRequirments = [&allocation](const auto &bo) {
return (static_cast<int>(bo.handle) == 0 &&
bo.offset == static_cast<DrmAllocation *>(allocation)->getBO()->peekAddress());
const auto execObjectRequirements = [&allocation](const auto &execObject) {
auto mockExecObject = static_cast<const MockExecObject &>(execObject);
return (mockExecObject.getHandle() == 0 &&
mockExecObject.getOffset() == static_cast<DrmAllocation *>(allocation)->getBO()->peekAddress());
};
auto &residency = static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->getExecStorage();
EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), boRequirments) != residency.end());
auto &residency = static_cast<TestedDrmCommandStreamReceiver<FamilyType> *>(csr)->execObjectsStorage;
EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) != residency.end());
EXPECT_EQ(residency.size(), 2u);
residency.clear();

View File

@@ -83,7 +83,7 @@ bool DrmDirectSubmission<GfxFamily, Dispatcher>::submit(uint64_t gpuAddress, siz
auto execFlags = osContextLinux->getEngineFlag() | I915_EXEC_NO_RELOC;
auto &drmContextIds = osContextLinux->getDrmContextIds();
drm_i915_gem_exec_object2 execObject{};
ExecObject execObject{};
this->handleResidency();

View File

@@ -115,32 +115,15 @@ uint32_t BufferObject::getOsContextId(OsContext *osContext) {
return perContextVmsUsed ? osContext->getContextId() : 0u;
}
void BufferObject::fillExecObject(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) {
execObject.handle = this->handle;
execObject.relocation_count = 0; //No relocations, we are SoftPinning
execObject.relocs_ptr = 0ul;
execObject.alignment = 0;
execObject.offset = this->gpuAddress;
execObject.flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
if (DebugManager.flags.UseAsyncDrmExec.get() == 1) {
execObject.flags |= EXEC_OBJECT_ASYNC;
}
if (this->isMarkedForCapture()) {
execObject.flags |= EXEC_OBJECT_CAPTURE;
}
execObject.rsvd1 = drmContextId;
execObject.rsvd2 = 0;
void BufferObject::fillExecObject(ExecObject &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) {
const auto osContextId = drm->isPerContextVMRequired() ? osContext->getContextId() : 0;
if (this->bindInfo[osContextId][vmHandleId]) {
execObject.handle = 0u;
}
auto ioctlHelper = drm->getIoctlHelper();
ioctlHelper->fillExecObject(execObject, this->handle, this->gpuAddress, drmContextId, this->bindInfo[osContextId][vmHandleId], this->isMarkedForCapture());
}
int BufferObject::exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId,
BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) {
BufferObject *const residency[], size_t residencyCount, ExecObject *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) {
for (size_t i = 0; i < residencyCount; i++) {
residency[i]->fillExecObject(execObjectsStorage[i], osContext, vmHandleId, drmContextId);
}
@@ -249,7 +232,8 @@ int BufferObject::unbind(OsContext *osContext, uint32_t vmHandleId) {
return retVal;
}
void BufferObject::printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const size_t &residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, BufferObject *const residency[]) {
void BufferObject::printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const size_t &residencyCount, ExecObject *execObjectsStorage, BufferObject *const residency[]) {
auto ioctlHelper = drm->getIoctlHelper();
std::stringstream logger;
logger << "drm_i915_gem_execbuffer2 { "
<< "buffer_ptr: " + std::to_string(execbuf.buffers_ptr)
@@ -262,17 +246,10 @@ void BufferObject::printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const
size_t i;
for (i = 0; i < residencyCount; i++) {
logger << "Buffer Object = { handle: BO-" << execObjectsStorage[i].handle
<< ", address range: 0x" << (void *)execObjectsStorage[i].offset
<< " - 0x" << (void *)ptrOffset(execObjectsStorage[i].offset, residency[i]->peekSize())
<< ", flags: " << std::hex << execObjectsStorage[i].flags << std::dec
<< ", size: " << residency[i]->peekSize() << " }\n";
ioctlHelper->logExecObject(execObjectsStorage[i], logger, residency[i]->peekSize());
}
logger << "Command Buffer Object = { handle: BO-" << execObjectsStorage[i].handle
<< ", address range: 0x" << (void *)execObjectsStorage[i].offset
<< " - 0x" << (void *)ptrOffset(execObjectsStorage[i].offset, this->peekSize())
<< ", flags: " << std::hex << execObjectsStorage[i].flags << std::dec
<< ", size: " << this->peekSize() << " }\n";
logger << "Command ";
ioctlHelper->logExecObject(execObjectsStorage[i], logger, this->peekSize());
printf("%s\n", logger.str().c_str());
}
@@ -297,7 +274,7 @@ int BufferObject::pin(BufferObject *const boToPin[], size_t numberOfBos, OsConte
if (this->drm->isVmBindAvailable()) {
retVal = bindBOsWithinContext(boToPin, numberOfBos, osContext, vmHandleId);
} else {
StackVec<drm_i915_gem_exec_object2, maxFragmentsCount + 1> execObject(numberOfBos + 1);
StackVec<ExecObject, maxFragmentsCount + 1> execObject(numberOfBos + 1);
retVal = this->exec(4u, 0u, 0u, false, osContext, vmHandleId, drmContextId, boToPin, numberOfBos, &execObject[0], 0, 0);
}
@@ -315,7 +292,7 @@ int BufferObject::validateHostPtr(BufferObject *const boToPin[], size_t numberOf
}
}
} else {
StackVec<drm_i915_gem_exec_object2, maxFragmentsCount + 1> execObject(numberOfBos + 1);
StackVec<ExecObject, maxFragmentsCount + 1> execObject(numberOfBos + 1);
retVal = this->exec(4u, 0u, 0u, false, osContext, vmHandleId, drmContextId, boToPin, numberOfBos, &execObject[0], 0, 0);
}

View File

@@ -19,12 +19,12 @@
#include <stdint.h>
#include <vector>
struct drm_i915_gem_exec_object2;
struct drm_i915_gem_relocation_entry;
struct drm_i915_gem_execbuffer2;
namespace NEO {
struct ExecObject;
class DrmMemoryManager;
class Drm;
class OsContext;
@@ -47,12 +47,12 @@ class BufferObject {
MOCKABLE_VIRTUAL int validateHostPtr(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId);
MOCKABLE_VIRTUAL int exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId,
BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue);
BufferObject *const residency[], size_t residencyCount, ExecObject *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue);
int bind(OsContext *osContext, uint32_t vmHandleId);
int unbind(OsContext *osContext, uint32_t vmHandleId);
void printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const size_t &residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, BufferObject *const residency[]);
void printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const size_t &residencyCount, ExecObject *execObjectsStorage, BufferObject *const residency[]);
int wait(int64_t timeoutNs);
bool close();
@@ -159,7 +159,7 @@ class BufferObject {
bool requiresExplicitResidency = false;
uint32_t getOsContextId(OsContext *osContext);
MOCKABLE_VIRTUAL void fillExecObject(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId);
MOCKABLE_VIRTUAL void fillExecObject(ExecObject &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId);
void printBOBindingResult(OsContext *osContext, uint32_t vmHandleId, bool bind, int retVal);
void *lockedAddress; // CPU side virtual address

View File

@@ -8,8 +8,7 @@
#pragma once
#include "shared/source/command_stream/device_command_stream.h"
#include "shared/source/os_interface/linux/drm_gem_close_worker.h"
#include "drm/i915_drm.h"
#include "shared/source/os_interface/linux/ioctl_helper.h"
#include <vector>
@@ -74,7 +73,7 @@ class DrmCommandStreamReceiver : public DeviceCommandStreamReceiver<GfxFamily> {
bool isUserFenceWaitActive();
std::vector<BufferObject *> residency;
std::vector<drm_i915_gem_exec_object2> execObjectsStorage;
std::vector<ExecObject> execObjectsStorage;
Drm *drm;
gemCloseWorkerMode gemCloseWorkerOperationMode;

View File

@@ -20,7 +20,6 @@
#include "shared/source/utilities/api_intercept.h"
#include "shared/source/utilities/stackvec.h"
#include "drm/i915_drm.h"
#include "engine_node.h"
#include "igfxfmid.h"

View File

@@ -7,12 +7,50 @@
#include "shared/source/os_interface/linux/ioctl_helper.h"
#include "shared/source/helpers/ptr_math.h"
#include "shared/source/os_interface/linux/drm_neo.h"
#include "drm/i915_drm.h"
namespace NEO {
uint32_t IoctlHelper::ioctl(Drm *drm, unsigned long request, void *arg) {
return drm->ioctl(request, arg);
}
static_assert(sizeof(ExecObject) == sizeof(drm_i915_gem_exec_object2));
void IoctlHelper::fillExecObject(ExecObject &execObject, uint32_t handle, uint64_t gpuAddress, uint32_t drmContextId, bool bindInfo, bool isMarkedForCapture) {
auto drmExecObject = reinterpret_cast<drm_i915_gem_exec_object2 *>(execObject.data);
drmExecObject->handle = handle;
drmExecObject->relocation_count = 0; //No relocations, we are SoftPinning
drmExecObject->relocs_ptr = 0ul;
drmExecObject->alignment = 0;
drmExecObject->offset = gpuAddress;
drmExecObject->flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
if (DebugManager.flags.UseAsyncDrmExec.get() == 1) {
drmExecObject->flags |= EXEC_OBJECT_ASYNC;
}
if (isMarkedForCapture) {
drmExecObject->flags |= EXEC_OBJECT_CAPTURE;
}
drmExecObject->rsvd1 = drmContextId;
drmExecObject->rsvd2 = 0;
if (bindInfo) {
drmExecObject->handle = 0u;
}
}
void IoctlHelper::logExecObject(const ExecObject &execObject, std::stringstream &logger, size_t size) {
auto drmExecObject = reinterpret_cast<const drm_i915_gem_exec_object2 *>(execObject.data);
logger << "Buffer Object = { handle: BO-" << drmExecObject->handle
<< ", address range: 0x" << reinterpret_cast<void *>(drmExecObject->offset)
<< " - 0x" << reinterpret_cast<void *>(ptrOffset(drmExecObject->offset, size))
<< ", flags: " << std::hex << drmExecObject->flags << std::dec
<< ", size: " << size << " }\n";
}
} // namespace NEO

View File

@@ -75,6 +75,10 @@ using MemRegionsVec = StackVec<MemoryClassInstance, 5>;
using VmBindExtSetPatT = uint8_t[40];
using VmBindExtUserFenceT = uint8_t[56];
struct ExecObject {
uint8_t data[56];
};
class IoctlHelper {
public:
virtual ~IoctlHelper() {}
@@ -127,6 +131,9 @@ class IoctlHelper {
virtual bool isContextDebugSupported(Drm *drm) = 0;
virtual int setContextDebugFlag(Drm *drm, uint32_t drmContextId) = 0;
virtual bool isDebugAttachAvailable() = 0;
void fillExecObject(ExecObject &execObject, uint32_t handle, uint64_t gpuAddress, uint32_t drmContextId, bool bindInfo, bool isMarkedForCapture);
void logExecObject(const ExecObject &execObject, std::stringstream &logger, size_t size);
};
class IoctlHelperUpstream : public IoctlHelper {

View File

@@ -107,6 +107,8 @@ else()
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_allocation.h
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_command_stream_receiver.h
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_memory_manager.h
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_wrappers.cpp
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_wrappers.h
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_os_context_linux.h
)
endif()

View File

@@ -27,7 +27,7 @@ class MockBufferObject : public BufferObject {
MockBufferObject(Drm *drm) : BufferObject(drm, CommonConstants::unsupportedPatIndex, 0, 0, 1) {
}
int exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId,
BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) override {
BufferObject *const residency[], size_t residencyCount, ExecObject *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) override {
passedExecParams.push_back({completionGpuAddress, completionValue});
return BufferObject::exec(used, startOffset, flags, requiresCoherency, osContext, vmHandleId, drmContextId,
residency, residencyCount, execObjectsStorage, completionGpuAddress, completionValue);

View File

@@ -35,6 +35,7 @@ class TestedDrmCommandStreamReceiver : public DrmCommandStreamReceiver<GfxFamily
using DrmCommandStreamReceiver<GfxFamily>::residency;
using DrmCommandStreamReceiver<GfxFamily>::useContextForUserFenceWait;
using DrmCommandStreamReceiver<GfxFamily>::useUserFenceWait;
using DrmCommandStreamReceiver<GfxFamily>::execObjectsStorage;
using CommandStreamReceiverHw<GfxFamily>::directSubmission;
using CommandStreamReceiverHw<GfxFamily>::blitterDirectSubmission;
using CommandStreamReceiverHw<GfxFamily>::CommandStreamReceiver::lastSentSliceCount;
@@ -75,10 +76,6 @@ class TestedDrmCommandStreamReceiver : public DrmCommandStreamReceiver<GfxFamily
this->submissionAggregator.reset(newSubmissionsAggregator);
}
std::vector<drm_i915_gem_exec_object2> &getExecStorage() {
return this->execObjectsStorage;
}
bool createPreemptionAllocation() override {
if (ultHwConfig.csrBaseCallCreatePreemption) {
return CommandStreamReceiver::createPreemptionAllocation();

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/test/common/mocks/linux/mock_drm_wrappers.h"
#include "drm/i915_drm.h"
namespace NEO {
uint32_t MockExecObject::getHandle() const {
auto drmExecObject = reinterpret_cast<const drm_i915_gem_exec_object2 *>(this->data);
return drmExecObject->handle;
}
uint64_t MockExecObject::getOffset() const {
auto drmExecObject = reinterpret_cast<const drm_i915_gem_exec_object2 *>(this->data);
return drmExecObject->offset;
}
bool MockExecObject::has48BAddressSupportFlag() const {
auto drmExecObject = reinterpret_cast<const drm_i915_gem_exec_object2 *>(this->data);
return drmExecObject->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
}
bool MockExecObject::hasCaptureFlag() const {
auto drmExecObject = reinterpret_cast<const drm_i915_gem_exec_object2 *>(this->data);
return drmExecObject->flags & EXEC_OBJECT_CAPTURE;
}
bool MockExecObject::hasAsyncFlag() const {
auto drmExecObject = reinterpret_cast<const drm_i915_gem_exec_object2 *>(this->data);
return drmExecObject->flags & EXEC_OBJECT_ASYNC;
}
} // namespace NEO

View File

@@ -0,0 +1,22 @@
/*
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/os_interface/linux/ioctl_helper.h"
namespace NEO {
struct MockExecObject : ExecObject {
uint32_t getHandle() const;
uint64_t getOffset() const;
bool has48BAddressSupportFlag() const;
bool hasCaptureFlag() const;
bool hasAsyncFlag() const;
};
static_assert(sizeof(MockExecObject) == sizeof(ExecObject));
} // namespace NEO

View File

@@ -12,8 +12,6 @@
#include "shared/test/common/helpers/engine_descriptor_helper.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "drm/i915_drm.h"
#include <memory>
class TestedBufferObject : public BufferObject {
@@ -29,7 +27,7 @@ class TestedBufferObject : public BufferObject {
this->tilingMode = mode;
}
void fillExecObject(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) override {
void fillExecObject(ExecObject &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) override {
BufferObject::fillExecObject(execObject, osContext, vmHandleId, drmContextId);
execObjectPointerFilled = &execObject;
}
@@ -39,7 +37,7 @@ class TestedBufferObject : public BufferObject {
}
int exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId,
BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) override {
BufferObject *const residency[], size_t residencyCount, ExecObject *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) override {
this->receivedCompletionGpuAddress = completionGpuAddress;
this->receivedCompletionValue = completionValue;
this->execCalled++;
@@ -59,7 +57,7 @@ class TestedBufferObject : public BufferObject {
}
uint64_t receivedCompletionGpuAddress = 0;
drm_i915_gem_exec_object2 *execObjectPointerFilled = nullptr;
ExecObject *execObjectPointerFilled = nullptr;
uint32_t receivedCompletionValue = 0;
uint32_t execCalled = 0;
bool callBaseEvictUnusedAllocations{true};
@@ -70,7 +68,7 @@ class DrmBufferObjectFixture {
public:
std::unique_ptr<DrmClass> mock;
TestedBufferObject *bo;
drm_i915_gem_exec_object2 execObjectsStorage[256];
ExecObject execObjectsStorage[256];
std::unique_ptr<OsContextLinux> osContext;
void SetUp() { // NOLINT(readability-identifier-naming)