mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-20 17:00:59 +08:00
Add initial implementation of Linux direct submission
Change-Id: I9ee0434897bc3e980b240a8373190f0803e6c102 Signed-off-by: Lukasz Jobczyk <lukasz.jobczyk@intel.com>
This commit is contained in:
committed by
sys_ocldev
parent
5b26d9be17
commit
21e16ff2c5
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "shared/source/command_stream/linear_stream.h"
|
||||
#include "shared/source/direct_submission/linux/drm_direct_submission.h"
|
||||
#include "shared/source/execution_environment/execution_environment.h"
|
||||
#include "shared/source/gmm_helper/gmm_helper.h"
|
||||
#include "shared/source/gmm_helper/page_table_mngr.h"
|
||||
@@ -72,6 +73,10 @@ bool DrmCommandStreamReceiver<GfxFamily>::flush(BatchBuffer &batchBuffer, Reside
|
||||
auto lock = memoryOperationsInterface->lockHandlerForExecWA();
|
||||
memoryOperationsInterface->mergeWithResidencyContainer(this->osContext, allocationsForResidency);
|
||||
|
||||
if (this->directSubmission.get()) {
|
||||
return this->directSubmission->dispatchCommandBuffer(batchBuffer, *this->flushStamp.get());
|
||||
}
|
||||
|
||||
this->flushStamp->setStamp(bb->peekHandle());
|
||||
this->flushInternal(batchBuffer, allocationsForResidency);
|
||||
|
||||
|
||||
@@ -35,8 +35,6 @@ class WddmCommandStreamReceiver : public DeviceCommandStreamReceiver<GfxFamily>
|
||||
}
|
||||
GmmPageTableMngr *createPageTableManager() override;
|
||||
|
||||
bool initDirectSubmission(Device &device, OsContext &osContext) override;
|
||||
|
||||
protected:
|
||||
void kmDafLockAllocations(ResidencyContainer &allocationsForResidency);
|
||||
|
||||
|
||||
@@ -155,43 +155,4 @@ void WddmCommandStreamReceiver<GfxFamily>::kmDafLockAllocations(ResidencyContain
|
||||
}
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
bool WddmCommandStreamReceiver<GfxFamily>::initDirectSubmission(Device &device, OsContext &osContext) {
|
||||
bool ret = true;
|
||||
|
||||
if (DebugManager.flags.EnableDirectSubmission.get() == 1) {
|
||||
auto contextEngineType = osContext.getEngineType();
|
||||
const DirectSubmissionProperties &directSubmissionProperty =
|
||||
device.getHardwareInfo().capabilityTable.directSubmissionEngines.data[contextEngineType];
|
||||
|
||||
bool startDirect = true;
|
||||
if (!osContext.isDefaultContext()) {
|
||||
startDirect = directSubmissionProperty.useNonDefault;
|
||||
}
|
||||
if (osContext.isLowPriority()) {
|
||||
startDirect = directSubmissionProperty.useLowPriority;
|
||||
}
|
||||
if (osContext.isInternalEngine()) {
|
||||
startDirect = directSubmissionProperty.useInternal;
|
||||
}
|
||||
if (osContext.isRootDevice()) {
|
||||
startDirect = directSubmissionProperty.useRootDevice;
|
||||
}
|
||||
|
||||
if (directSubmissionProperty.engineSupported && startDirect) {
|
||||
if (contextEngineType == aub_stream::ENGINE_BCS) {
|
||||
blitterDirectSubmission = std::make_unique<
|
||||
WddmDirectSubmission<GfxFamily, BlitterDispatcher<GfxFamily>>>(device, osContext);
|
||||
ret = blitterDirectSubmission->initialize(directSubmissionProperty.submitOnInit);
|
||||
} else {
|
||||
directSubmission = std::make_unique<
|
||||
WddmDirectSubmission<GfxFamily, RenderDispatcher<GfxFamily>>>(device, osContext);
|
||||
ret = directSubmission->initialize(directSubmissionProperty.submitOnInit);
|
||||
this->dispatchMode = DispatchMode::ImmediateDispatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -1287,6 +1287,41 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, FlushNotAligned) {
|
||||
csr->flush(batchBuffer, csr->getResidencyAllocations());
|
||||
}
|
||||
|
||||
struct DrmCommandStreamDirectSubmissionTest : public DrmCommandStreamEnhancedTest {
|
||||
|
||||
template <typename GfxFamily>
|
||||
void SetUpT() {
|
||||
DebugManager.flags.EnableDirectSubmission.set(1u);
|
||||
DrmCommandStreamEnhancedTest::SetUpT<GfxFamily>();
|
||||
auto hwInfo = device->getRootDeviceEnvironment().getMutableHardwareInfo();
|
||||
auto engineType = device->getDefaultEngine().osContext->getEngineType();
|
||||
hwInfo->capabilityTable.directSubmissionEngines.data[engineType].engineSupported = true;
|
||||
csr->initDirectSubmission(*device.get(), *device->getDefaultEngine().osContext);
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
void TearDownT() {
|
||||
this->dbgState.reset();
|
||||
DrmCommandStreamEnhancedTest::TearDownT<GfxFamily>();
|
||||
}
|
||||
|
||||
DebugManagerStateRestore restorer;
|
||||
};
|
||||
|
||||
HWTEST_TEMPLATED_F(DrmCommandStreamDirectSubmissionTest, givenEnabledDirectSubmissionWhenFlushThenFlushStampIsNotUpdated) {
|
||||
auto &cs = csr->getCS();
|
||||
CommandStreamReceiverHw<FamilyType>::addBatchBufferEnd(cs, nullptr);
|
||||
CommandStreamReceiverHw<FamilyType>::alignToCacheLine(cs);
|
||||
BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 4, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr};
|
||||
uint8_t bbStart[64];
|
||||
batchBuffer.endCmdPtr = &bbStart[0];
|
||||
|
||||
auto flushStamp = csr->obtainCurrentFlushStamp();
|
||||
csr->flush(batchBuffer, csr->getResidencyAllocations());
|
||||
|
||||
EXPECT_EQ(csr->obtainCurrentFlushStamp(), flushStamp);
|
||||
}
|
||||
|
||||
HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, CheckDrmFree) {
|
||||
auto &cs = csr->getCS();
|
||||
auto commandBuffer = static_cast<DrmAllocation *>(cs.getGraphicsAllocation());
|
||||
|
||||
@@ -97,6 +97,8 @@ class CommandStreamReceiverHw : public CommandStreamReceiver {
|
||||
return blitterDirectSubmission.get() != nullptr;
|
||||
}
|
||||
|
||||
bool initDirectSubmission(Device &device, OsContext &osContext) override;
|
||||
|
||||
protected:
|
||||
void programPreemption(LinearStream &csr, DispatchFlags &dispatchFlags);
|
||||
void programL3(LinearStream &csr, DispatchFlags &dispatchFlags, uint32_t &newL3Config);
|
||||
|
||||
@@ -1029,4 +1029,41 @@ inline size_t CommandStreamReceiverHw<GfxFamily>::getCmdSizeForPrologue() const
|
||||
return 0u;
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
inline bool CommandStreamReceiverHw<GfxFamily>::initDirectSubmission(Device &device, OsContext &osContext) {
|
||||
bool ret = true;
|
||||
|
||||
if (DebugManager.flags.EnableDirectSubmission.get() == 1) {
|
||||
auto contextEngineType = osContext.getEngineType();
|
||||
const DirectSubmissionProperties &directSubmissionProperty =
|
||||
device.getHardwareInfo().capabilityTable.directSubmissionEngines.data[contextEngineType];
|
||||
|
||||
bool startDirect = true;
|
||||
if (!osContext.isDefaultContext()) {
|
||||
startDirect = directSubmissionProperty.useNonDefault;
|
||||
}
|
||||
if (osContext.isLowPriority()) {
|
||||
startDirect = directSubmissionProperty.useLowPriority;
|
||||
}
|
||||
if (osContext.isInternalEngine()) {
|
||||
startDirect = directSubmissionProperty.useInternal;
|
||||
}
|
||||
if (osContext.isRootDevice()) {
|
||||
startDirect = directSubmissionProperty.useRootDevice;
|
||||
}
|
||||
|
||||
if (directSubmissionProperty.engineSupported && startDirect) {
|
||||
if (contextEngineType == aub_stream::ENGINE_BCS) {
|
||||
blitterDirectSubmission = DirectSubmissionHw<GfxFamily, BlitterDispatcher<GfxFamily>>::create(device, osContext);
|
||||
ret = blitterDirectSubmission->initialize(directSubmissionProperty.submitOnInit);
|
||||
} else {
|
||||
directSubmission = DirectSubmissionHw<GfxFamily, RenderDispatcher<GfxFamily>>::create(device, osContext);
|
||||
ret = directSubmission->initialize(directSubmissionProperty.submitOnInit);
|
||||
this->dispatchMode = DispatchMode::ImmediateDispatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -59,15 +59,19 @@ class DirectSubmissionHw {
|
||||
|
||||
bool dispatchCommandBuffer(BatchBuffer &batchBuffer, FlushStampTracker &flushStamp);
|
||||
|
||||
static std::unique_ptr<DirectSubmissionHw<GfxFamily, Dispatcher>> create(Device &device, OsContext &osContext);
|
||||
|
||||
protected:
|
||||
static constexpr size_t prefetchSize = 8 * MemoryConstants::cacheLineSize;
|
||||
static constexpr size_t prefetchNoops = prefetchSize / sizeof(uint32_t);
|
||||
bool allocateResources();
|
||||
void deallocateResources();
|
||||
virtual bool allocateOsResources(DirectSubmissionAllocations &allocations) = 0;
|
||||
MOCKABLE_VIRTUAL bool makeResourcesResident(DirectSubmissionAllocations &allocations);
|
||||
virtual bool allocateOsResources() = 0;
|
||||
virtual bool submit(uint64_t gpuAddress, size_t size) = 0;
|
||||
virtual bool handleResidency() = 0;
|
||||
virtual uint64_t switchRingBuffers() = 0;
|
||||
virtual uint64_t switchRingBuffers();
|
||||
virtual void handleSwitchRingBuffers() = 0;
|
||||
GraphicsAllocation *switchRingBuffersAllocations();
|
||||
virtual uint64_t updateTagValue() = 0;
|
||||
virtual void getTagAddressValue(TagData &tagData) = 0;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "shared/source/memory_manager/allocation_properties.h"
|
||||
#include "shared/source/memory_manager/graphics_allocation.h"
|
||||
#include "shared/source/memory_manager/memory_manager.h"
|
||||
#include "shared/source/memory_manager/memory_operations_handler.h"
|
||||
#include "shared/source/os_interface/os_context.h"
|
||||
#include "shared/source/utilities/cpu_info.h"
|
||||
#include "shared/source/utilities/cpuintrinsics.h"
|
||||
@@ -87,7 +88,18 @@ bool DirectSubmissionHw<GfxFamily, Dispatcher>::allocateResources() {
|
||||
cpuCachelineFlush(semaphorePtr, MemoryConstants::cacheLineSize);
|
||||
workloadModeOneStoreAddress = static_cast<volatile void *>(&semaphoreData->Reserved1Uint32);
|
||||
*static_cast<volatile uint32_t *>(workloadModeOneStoreAddress) = 0u;
|
||||
return allocateOsResources(allocations);
|
||||
|
||||
auto ret = makeResourcesResident(allocations);
|
||||
|
||||
return ret && allocateOsResources();
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
bool DirectSubmissionHw<GfxFamily, Dispatcher>::makeResourcesResident(DirectSubmissionAllocations &allocations) {
|
||||
auto memoryInterface = this->device.getRootDeviceEnvironment().memoryOperationsInterface.get();
|
||||
auto ret = memoryInterface->makeResident(&device, ArrayRef<GraphicsAllocation *>(allocations)) == MemoryOperationsStatus::SUCCESS;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
@@ -337,6 +349,25 @@ inline void DirectSubmissionHw<GfxFamily, Dispatcher>::setReturnAddress(void *re
|
||||
*returnBBStart = cmd;
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
inline uint64_t DirectSubmissionHw<GfxFamily, Dispatcher>::switchRingBuffers() {
|
||||
GraphicsAllocation *nextRingBuffer = switchRingBuffersAllocations();
|
||||
void *flushPtr = ringCommandStream.getSpace(0);
|
||||
uint64_t currentBufferGpuVa = getCommandBufferPositionGpuAddress(flushPtr);
|
||||
|
||||
if (ringStart) {
|
||||
dispatchSwitchRingBufferSection(nextRingBuffer->getGpuAddress());
|
||||
cpuCachelineFlush(flushPtr, getSizeSwitchRingBufferSection());
|
||||
}
|
||||
|
||||
ringCommandStream.replaceBuffer(nextRingBuffer->getUnderlyingBuffer(), ringCommandStream.getMaxAvailableSpace());
|
||||
ringCommandStream.replaceGraphicsAllocation(nextRingBuffer);
|
||||
|
||||
handleSwitchRingBuffers();
|
||||
|
||||
return currentBufferGpuVa;
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
inline GraphicsAllocation *DirectSubmissionHw<GfxFamily, Dispatcher>::switchRingBuffersAllocations() {
|
||||
GraphicsAllocation *nextAllocation = nullptr;
|
||||
|
||||
@@ -19,12 +19,14 @@ class DrmDirectSubmission : public DirectSubmissionHw<GfxFamily, Dispatcher> {
|
||||
DrmDirectSubmission(Device &device,
|
||||
OsContext &osContext);
|
||||
|
||||
~DrmDirectSubmission();
|
||||
|
||||
protected:
|
||||
bool allocateOsResources(DirectSubmissionAllocations &allocations) override;
|
||||
bool allocateOsResources() override;
|
||||
bool submit(uint64_t gpuAddress, size_t size) override;
|
||||
|
||||
bool handleResidency() override;
|
||||
uint64_t switchRingBuffers() override;
|
||||
void handleSwitchRingBuffers() override;
|
||||
uint64_t updateTagValue() override;
|
||||
void getTagAddressValue(TagData &tagData) override;
|
||||
};
|
||||
|
||||
@@ -8,33 +8,73 @@
|
||||
#include "shared/source/command_stream/linear_stream.h"
|
||||
#include "shared/source/direct_submission/linux/drm_direct_submission.h"
|
||||
#include "shared/source/os_interface/linux/drm_allocation.h"
|
||||
#include "shared/source/os_interface/linux/drm_buffer_object.h"
|
||||
#include "shared/source/os_interface/linux/drm_neo.h"
|
||||
#include "shared/source/os_interface/linux/os_context_linux.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
inline std::unique_ptr<DirectSubmissionHw<GfxFamily, Dispatcher>> DirectSubmissionHw<GfxFamily, Dispatcher>::create(Device &device, OsContext &osContext) {
|
||||
return std::make_unique<DrmDirectSubmission<GfxFamily, Dispatcher>>(device, osContext);
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
DrmDirectSubmission<GfxFamily, Dispatcher>::DrmDirectSubmission(Device &device,
|
||||
OsContext &osContext)
|
||||
: DirectSubmissionHw<GfxFamily, Dispatcher>(device, osContext) {
|
||||
this->disableMonitorFence = true;
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
bool DrmDirectSubmission<GfxFamily, Dispatcher>::allocateOsResources(DirectSubmissionAllocations &allocations) {
|
||||
return false;
|
||||
inline DrmDirectSubmission<GfxFamily, Dispatcher>::~DrmDirectSubmission() {
|
||||
if (this->ringStart) {
|
||||
this->stopRingBuffer();
|
||||
auto bb = static_cast<DrmAllocation *>(this->ringCommandStream.getGraphicsAllocation())->getBO();
|
||||
bb->wait(-1);
|
||||
}
|
||||
this->deallocateResources();
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
bool DrmDirectSubmission<GfxFamily, Dispatcher>::allocateOsResources() {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
bool DrmDirectSubmission<GfxFamily, Dispatcher>::submit(uint64_t gpuAddress, size_t size) {
|
||||
return false;
|
||||
auto bb = static_cast<DrmAllocation *>(this->ringCommandStream.getGraphicsAllocation())->getBO();
|
||||
|
||||
auto osContextLinux = static_cast<OsContextLinux *>(&this->osContext);
|
||||
auto execFlags = osContextLinux->getEngineFlag() | I915_EXEC_NO_RELOC;
|
||||
auto &drmContextIds = osContextLinux->getDrmContextIds();
|
||||
|
||||
drm_i915_gem_exec_object2 execObject{};
|
||||
|
||||
bool ret = false;
|
||||
for (const auto &drmContextId : drmContextIds) {
|
||||
ret |= bb->exec(static_cast<uint32_t>(size),
|
||||
0,
|
||||
execFlags,
|
||||
false,
|
||||
drmContextId,
|
||||
nullptr,
|
||||
0,
|
||||
&execObject);
|
||||
}
|
||||
|
||||
return !ret;
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
bool DrmDirectSubmission<GfxFamily, Dispatcher>::handleResidency() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
uint64_t DrmDirectSubmission<GfxFamily, Dispatcher>::switchRingBuffers() {
|
||||
return 0ull;
|
||||
void DrmDirectSubmission<GfxFamily, Dispatcher>::handleSwitchRingBuffers() {
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
|
||||
@@ -25,12 +25,12 @@ class WddmDirectSubmission : public DirectSubmissionHw<GfxFamily, Dispatcher> {
|
||||
~WddmDirectSubmission();
|
||||
|
||||
protected:
|
||||
bool allocateOsResources(DirectSubmissionAllocations &allocations) override;
|
||||
bool allocateOsResources() override;
|
||||
bool submit(uint64_t gpuAddress, size_t size) override;
|
||||
|
||||
bool handleResidency() override;
|
||||
void handleCompletionRingBuffer(uint64_t completionValue, MonitoredFence &fence);
|
||||
uint64_t switchRingBuffers() override;
|
||||
void handleSwitchRingBuffers() override;
|
||||
uint64_t updateTagValue() override;
|
||||
void getTagAddressValue(TagData &tagData) override;
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ namespace NEO {
|
||||
// Initialize COMMAND_BUFFER_HEADER Type PatchList Streamer Perf Tag
|
||||
DECLARE_COMMAND_BUFFER(CommandBufferHeader, UMD_OCL, FALSE, FALSE, PERFTAG_OCL);
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
inline std::unique_ptr<DirectSubmissionHw<GfxFamily, Dispatcher>> DirectSubmissionHw<GfxFamily, Dispatcher>::create(Device &device, OsContext &osContext) {
|
||||
return std::make_unique<WddmDirectSubmission<GfxFamily, Dispatcher>>(device, osContext);
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
WddmDirectSubmission<GfxFamily, Dispatcher>::WddmDirectSubmission(Device &device,
|
||||
OsContext &osContext)
|
||||
@@ -49,18 +54,12 @@ WddmDirectSubmission<GfxFamily, Dispatcher>::~WddmDirectSubmission() {
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
bool WddmDirectSubmission<GfxFamily, Dispatcher>::allocateOsResources(DirectSubmissionAllocations &allocations) {
|
||||
bool WddmDirectSubmission<GfxFamily, Dispatcher>::allocateOsResources() {
|
||||
//for now only WDDM2.0
|
||||
UNRECOVERABLE_IF(wddm->getWddmVersion() != WddmVersion::WDDM_2_0);
|
||||
|
||||
WddmMemoryOperationsHandler *memoryInterface =
|
||||
static_cast<WddmMemoryOperationsHandler *>(device.getRootDeviceEnvironment().memoryOperationsInterface.get());
|
||||
|
||||
bool ret = wddm->getWddmInterface()->createMonitoredFence(ringFence);
|
||||
ringFence.currentFenceValue = 1;
|
||||
if (ret) {
|
||||
ret = memoryInterface->makeResident(&device, ArrayRef<GraphicsAllocation *>(allocations)) == MemoryOperationsStatus::SUCCESS;
|
||||
}
|
||||
perfLogResidencyVariadicLog(wddm->getResidencyLogger(), "ULLS resource allocation finished with: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -93,27 +92,13 @@ bool WddmDirectSubmission<GfxFamily, Dispatcher>::handleResidency() {
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
uint64_t WddmDirectSubmission<GfxFamily, Dispatcher>::switchRingBuffers() {
|
||||
GraphicsAllocation *nextRingBuffer = switchRingBuffersAllocations();
|
||||
void *flushPtr = ringCommandStream.getSpace(0);
|
||||
uint64_t currentBufferGpuVa = getCommandBufferPositionGpuAddress(flushPtr);
|
||||
|
||||
if (ringStart) {
|
||||
dispatchSwitchRingBufferSection(nextRingBuffer->getGpuAddress());
|
||||
cpuCachelineFlush(flushPtr, getSizeSwitchRingBufferSection());
|
||||
}
|
||||
|
||||
ringCommandStream.replaceBuffer(nextRingBuffer->getUnderlyingBuffer(), ringCommandStream.getMaxAvailableSpace());
|
||||
ringCommandStream.replaceGraphicsAllocation(nextRingBuffer);
|
||||
|
||||
void WddmDirectSubmission<GfxFamily, Dispatcher>::handleSwitchRingBuffers() {
|
||||
if (ringStart) {
|
||||
if (completionRingBuffers[currentRingBuffer] != 0) {
|
||||
MonitoredFence ¤tFence = osContextWin->getResidencyController().getMonitoredFence();
|
||||
handleCompletionRingBuffer(completionRingBuffers[currentRingBuffer], currentFence);
|
||||
}
|
||||
}
|
||||
|
||||
return currentBufferGpuVa;
|
||||
}
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "shared/source/debug_settings/debug_settings_manager.h"
|
||||
#include "shared/source/direct_submission/dispatchers/render_dispatcher.h"
|
||||
#include "shared/source/helpers/flush_stamp.h"
|
||||
#include "shared/source/os_interface/device_factory.h"
|
||||
#include "shared/source/os_interface/os_context.h"
|
||||
#include "shared/test/unit_test/cmd_parse/hw_parse.h"
|
||||
#include "shared/test/unit_test/fixtures/device_fixture.h"
|
||||
@@ -33,6 +34,7 @@ extern std::atomic<uintptr_t> lastClFlushedPtr;
|
||||
struct DirectSubmissionFixture : public DeviceFixture {
|
||||
void SetUp() {
|
||||
DeviceFixture::SetUp();
|
||||
DeviceFactory::prepareDeviceEnvironments(*pDevice->getExecutionEnvironment());
|
||||
|
||||
osContext.reset(OsContext::create(nullptr, 0u, pDevice->getDeviceBitfield(), aub_stream::ENGINE_RCS, PreemptionMode::ThreadGroup,
|
||||
false, false, false));
|
||||
|
||||
@@ -8,33 +8,44 @@
|
||||
#include "shared/source/direct_submission/dispatchers/render_dispatcher.h"
|
||||
#include "shared/source/direct_submission/linux/drm_direct_submission.h"
|
||||
#include "shared/source/os_interface/linux/os_context_linux.h"
|
||||
#include "shared/test/unit_test/fixtures/device_fixture.h"
|
||||
#include "shared/test/unit_test/helpers/ult_hw_config.h"
|
||||
#include "shared/test/unit_test/helpers/variable_backup.h"
|
||||
#include "shared/test/unit_test/mocks/mock_device.h"
|
||||
|
||||
#include "opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.h"
|
||||
#include "opencl/test/unit_test/os_interface/linux/drm_mock.h"
|
||||
#include "test.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
struct DrmDirectSubmissionFixture : public DeviceFixture {
|
||||
void SetUp() {
|
||||
DeviceFixture::SetUp();
|
||||
struct DrmDirectSubmissionTest : public DrmMemoryManagerBasic {
|
||||
void SetUp() override {
|
||||
backupUlt = std::make_unique<VariableBackup<UltHwConfig>>(&ultHwConfig);
|
||||
|
||||
osContext = std::make_unique<OsContextLinux>(drmMock, 0u, 0u, aub_stream::ENGINE_RCS,
|
||||
PreemptionMode::ThreadGroup, false, false, false);
|
||||
DrmMemoryManagerBasic::SetUp();
|
||||
executionEnvironment.incRefInternal();
|
||||
|
||||
ultHwConfig.forceOsAgnosticMemoryManager = false;
|
||||
device.reset(MockDevice::create<MockDevice>(&executionEnvironment, 0u));
|
||||
osContext = std::make_unique<OsContextLinux>(*executionEnvironment.rootDeviceEnvironments[0]->osInterface->get()->getDrm(),
|
||||
0u, device->getDeviceBitfield(), aub_stream::ENGINE_RCS, PreemptionMode::ThreadGroup,
|
||||
false, false, false);
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
DeviceFixture::TearDown();
|
||||
void TearDown() override {
|
||||
DrmMemoryManagerBasic::TearDown();
|
||||
}
|
||||
|
||||
std::unique_ptr<OsContextLinux> osContext;
|
||||
DrmMock drmMock;
|
||||
std::unique_ptr<MockDevice> device;
|
||||
|
||||
std::unique_ptr<VariableBackup<UltHwConfig>> backupUlt;
|
||||
};
|
||||
|
||||
template <typename GfxFamily, typename Dispatcher>
|
||||
struct MockDrmDirectSubmission : public DrmDirectSubmission<GfxFamily, Dispatcher> {
|
||||
using BaseClass = DrmDirectSubmission<GfxFamily, Dispatcher>;
|
||||
using BaseClass::allocateOsResources;
|
||||
using BaseClass::allocateResources;
|
||||
using BaseClass::DrmDirectSubmission;
|
||||
using BaseClass::getTagAddressValue;
|
||||
using BaseClass::handleResidency;
|
||||
@@ -43,24 +54,21 @@ struct MockDrmDirectSubmission : public DrmDirectSubmission<GfxFamily, Dispatche
|
||||
using BaseClass::updateTagValue;
|
||||
};
|
||||
|
||||
using DrmDirectSubmissionTest = Test<DrmDirectSubmissionFixture>;
|
||||
|
||||
using namespace NEO;
|
||||
|
||||
HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenCallingLinuxImplementationThenExpectAllFailAsNotImplemented) {
|
||||
MockDrmDirectSubmission<FamilyType, RenderDispatcher<FamilyType>> drmDirectSubmission(*pDevice,
|
||||
HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenCallingLinuxImplementationThenExpectInitialImplementationValues) {
|
||||
MockDrmDirectSubmission<FamilyType, RenderDispatcher<FamilyType>> drmDirectSubmission(*device.get(),
|
||||
*osContext.get());
|
||||
|
||||
DirectSubmissionAllocations allocations;
|
||||
EXPECT_FALSE(drmDirectSubmission.allocateOsResources(allocations));
|
||||
EXPECT_TRUE(drmDirectSubmission.allocateResources());
|
||||
|
||||
uint64_t gpuAddress = 0x1000;
|
||||
size_t size = 0x1000;
|
||||
EXPECT_FALSE(drmDirectSubmission.submit(gpuAddress, size));
|
||||
EXPECT_TRUE(drmDirectSubmission.submit(gpuAddress, size));
|
||||
|
||||
EXPECT_FALSE(drmDirectSubmission.handleResidency());
|
||||
EXPECT_TRUE(drmDirectSubmission.handleResidency());
|
||||
|
||||
EXPECT_EQ(0ull, drmDirectSubmission.switchRingBuffers());
|
||||
EXPECT_NE(0ull, drmDirectSubmission.switchRingBuffers());
|
||||
|
||||
EXPECT_EQ(0ull, drmDirectSubmission.updateTagValue());
|
||||
|
||||
@@ -69,3 +77,20 @@ HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenCallingLinuxImplem
|
||||
EXPECT_EQ(0ull, tagData.tagAddress);
|
||||
EXPECT_EQ(0ull, tagData.tagValue);
|
||||
}
|
||||
|
||||
HWTEST_F(DrmDirectSubmissionTest, whenCreateDirectSubmissionThenValidObjectIsReturned) {
|
||||
auto directSubmission = DirectSubmissionHw<FamilyType, RenderDispatcher<FamilyType>>::create(*device.get(),
|
||||
*osContext.get());
|
||||
EXPECT_NE(directSubmission.get(), nullptr);
|
||||
}
|
||||
|
||||
HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenDestructObjectThenIoctlIsCalled) {
|
||||
auto drmDirectSubmission = std::make_unique<MockDrmDirectSubmission<FamilyType, RenderDispatcher<FamilyType>>>(*device.get(),
|
||||
*osContext.get());
|
||||
auto drm = static_cast<DrmMock *>(executionEnvironment.rootDeviceEnvironments[0]->osInterface->get()->getDrm());
|
||||
drm->ioctlCallsCount = 0u;
|
||||
drmDirectSubmission->initialize(true);
|
||||
drmDirectSubmission.reset();
|
||||
|
||||
EXPECT_EQ(drm->ioctlCallsCount, 11u);
|
||||
}
|
||||
@@ -126,28 +126,15 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenSubmitingCmdBufferThenExpectPass
|
||||
}
|
||||
|
||||
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesThenExpectRingMonitorFenceCreatedAndAllocationsResident) {
|
||||
MemoryManager *memoryManager = device->getExecutionEnvironment()->memoryManager.get();
|
||||
const auto allocationSize = MemoryConstants::pageSize;
|
||||
const AllocationProperties commandStreamAllocationProperties{device->getRootDeviceIndex(),
|
||||
allocationSize,
|
||||
GraphicsAllocation::AllocationType::RING_BUFFER, device->getDeviceBitfield()};
|
||||
GraphicsAllocation *ringBuffer = memoryManager->allocateGraphicsMemoryWithProperties(commandStreamAllocationProperties);
|
||||
ASSERT_NE(nullptr, ringBuffer);
|
||||
|
||||
MockWddmDirectSubmission<FamilyType, RenderDispatcher<FamilyType>> wddmDirectSubmission(*device.get(),
|
||||
*osContext.get());
|
||||
|
||||
DirectSubmissionAllocations allocations;
|
||||
allocations.push_back(ringBuffer);
|
||||
|
||||
bool ret = wddmDirectSubmission.allocateOsResources(allocations);
|
||||
bool ret = wddmDirectSubmission.allocateResources();
|
||||
EXPECT_TRUE(ret);
|
||||
|
||||
EXPECT_EQ(1u, wddmMockInterface->createMonitoredFenceCalled);
|
||||
EXPECT_EQ(1u, wddm->makeResidentResult.called);
|
||||
EXPECT_EQ(1u, wddm->makeResidentResult.handleCount);
|
||||
|
||||
memoryManager->freeGraphicsMemory(ringBuffer);
|
||||
EXPECT_EQ(3u, wddm->makeResidentResult.handleCount);
|
||||
}
|
||||
|
||||
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesFenceCreationFailsThenExpectRingMonitorFenceNotCreatedAndAllocationsNotResident) {
|
||||
@@ -166,7 +153,7 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesFenceCreation
|
||||
|
||||
wddmMockInterface->createMonitoredFenceCalledFail = true;
|
||||
|
||||
bool ret = wddmDirectSubmission.allocateOsResources(allocations);
|
||||
bool ret = wddmDirectSubmission.allocateOsResources();
|
||||
EXPECT_FALSE(ret);
|
||||
|
||||
EXPECT_EQ(1u, wddmMockInterface->createMonitoredFenceCalled);
|
||||
@@ -177,32 +164,19 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesFenceCreation
|
||||
}
|
||||
|
||||
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesResidencyFailsThenExpectRingMonitorFenceCreatedAndAllocationsNotResident) {
|
||||
MemoryManager *memoryManager = device->getExecutionEnvironment()->memoryManager.get();
|
||||
const auto allocationSize = MemoryConstants::pageSize;
|
||||
const AllocationProperties commandStreamAllocationProperties{device->getRootDeviceIndex(),
|
||||
allocationSize,
|
||||
GraphicsAllocation::AllocationType::RING_BUFFER, device->getDeviceBitfield()};
|
||||
GraphicsAllocation *ringBuffer = memoryManager->allocateGraphicsMemoryWithProperties(commandStreamAllocationProperties);
|
||||
ASSERT_NE(nullptr, ringBuffer);
|
||||
|
||||
MockWddmDirectSubmission<FamilyType, RenderDispatcher<FamilyType>> wddmDirectSubmission(*device.get(),
|
||||
*osContext.get());
|
||||
|
||||
DirectSubmissionAllocations allocations;
|
||||
allocations.push_back(ringBuffer);
|
||||
|
||||
wddm->callBaseMakeResident = false;
|
||||
wddm->makeResidentStatus = false;
|
||||
|
||||
bool ret = wddmDirectSubmission.allocateOsResources(allocations);
|
||||
bool ret = wddmDirectSubmission.allocateResources();
|
||||
EXPECT_FALSE(ret);
|
||||
|
||||
EXPECT_EQ(1u, wddmMockInterface->createMonitoredFenceCalled);
|
||||
EXPECT_EQ(0u, wddmMockInterface->createMonitoredFenceCalled);
|
||||
//expect 2 makeResident calls, due to fail on 1st and then retry (which also fails)
|
||||
EXPECT_EQ(2u, wddm->makeResidentResult.called);
|
||||
EXPECT_EQ(1u, wddm->makeResidentResult.handleCount);
|
||||
|
||||
memoryManager->freeGraphicsMemory(ringBuffer);
|
||||
EXPECT_EQ(3u, wddm->makeResidentResult.handleCount);
|
||||
}
|
||||
|
||||
HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenGettingTagDataThenExpectContextMonitorFence) {
|
||||
@@ -406,24 +380,11 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmResidencyEnabledWhenAllocatingResour
|
||||
EXPECT_EQ(1u, NEO::IoFunctions::mockVfptrinfCalled);
|
||||
EXPECT_EQ(0u, NEO::IoFunctions::mockFcloseCalled);
|
||||
|
||||
MemoryManager *memoryManager = device->getExecutionEnvironment()->memoryManager.get();
|
||||
const auto allocationSize = MemoryConstants::pageSize;
|
||||
const AllocationProperties commandStreamAllocationProperties{device->getRootDeviceIndex(),
|
||||
allocationSize,
|
||||
GraphicsAllocation::AllocationType::RING_BUFFER, device->getDeviceBitfield()};
|
||||
GraphicsAllocation *ringBuffer = memoryManager->allocateGraphicsMemoryWithProperties(commandStreamAllocationProperties);
|
||||
ASSERT_NE(nullptr, ringBuffer);
|
||||
|
||||
DirectSubmissionAllocations allocations;
|
||||
allocations.push_back(ringBuffer);
|
||||
|
||||
bool ret = wddmDirectSubmission.allocateOsResources(allocations);
|
||||
bool ret = wddmDirectSubmission.allocateResources();
|
||||
EXPECT_TRUE(ret);
|
||||
|
||||
memoryManager->freeGraphicsMemory(ringBuffer);
|
||||
|
||||
EXPECT_EQ(1u, NEO::IoFunctions::mockFopenCalled);
|
||||
EXPECT_EQ(6u, NEO::IoFunctions::mockVfptrinfCalled);
|
||||
EXPECT_EQ(10u, NEO::IoFunctions::mockVfptrinfCalled);
|
||||
EXPECT_EQ(0u, NEO::IoFunctions::mockFcloseCalled);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,10 +66,14 @@ struct MockDirectSubmissionHw : public DirectSubmissionHw<GfxFamily, Dispatcher>
|
||||
deallocateResources();
|
||||
}
|
||||
|
||||
bool allocateOsResources(DirectSubmissionAllocations &allocations) override {
|
||||
bool allocateOsResources() override {
|
||||
return allocateOsResourcesReturn;
|
||||
}
|
||||
|
||||
bool makeResourcesResident(DirectSubmissionAllocations &allocations) override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool submit(uint64_t gpuAddress, size_t size) override {
|
||||
submitGpuAddress = gpuAddress;
|
||||
submitSize = size;
|
||||
@@ -82,15 +86,7 @@ struct MockDirectSubmissionHw : public DirectSubmissionHw<GfxFamily, Dispatcher>
|
||||
return handleResidencyReturn;
|
||||
}
|
||||
|
||||
uint64_t switchRingBuffers() override {
|
||||
GraphicsAllocation *nextRingBuffer = switchRingBuffersAllocations();
|
||||
uint64_t currentBufferGpuVa = getCommandBufferPositionGpuAddress(ringCommandStream.getSpace(0));
|
||||
|
||||
ringCommandStream.replaceBuffer(nextRingBuffer->getUnderlyingBuffer(), ringCommandStream.getMaxAvailableSpace());
|
||||
ringCommandStream.replaceGraphicsAllocation(nextRingBuffer);
|
||||
|
||||
return currentBufferGpuVa;
|
||||
}
|
||||
void handleSwitchRingBuffers() override {}
|
||||
|
||||
uint64_t updateTagValue() override {
|
||||
return updateTagValueReturn;
|
||||
|
||||
@@ -14,6 +14,7 @@ template <typename GfxFamily, typename Dispatcher>
|
||||
struct MockWddmDirectSubmission : public WddmDirectSubmission<GfxFamily, Dispatcher> {
|
||||
using BaseClass = WddmDirectSubmission<GfxFamily, Dispatcher>;
|
||||
using BaseClass::allocateOsResources;
|
||||
using BaseClass::allocateResources;
|
||||
using BaseClass::commandBufferHeader;
|
||||
using BaseClass::completionRingBuffers;
|
||||
using BaseClass::currentRingBuffer;
|
||||
|
||||
Reference in New Issue
Block a user