2023-09-20 18:47:56 +08:00
|
|
|
/*
|
2024-01-13 00:27:50 +08:00
|
|
|
* Copyright (C) 2023-2024 Intel Corporation
|
2023-09-20 18:47:56 +08:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2023-09-27 22:02:30 +08:00
|
|
|
#include "shared/source/helpers/non_copyable_or_moveable.h"
|
2023-09-20 18:47:56 +08:00
|
|
|
#include "shared/source/helpers/ptr_math.h"
|
|
|
|
|
|
|
|
#include <cstdint>
|
2023-10-03 17:34:45 +08:00
|
|
|
#include <memory>
|
2023-09-20 18:47:56 +08:00
|
|
|
#include <vector>
|
|
|
|
|
2023-09-27 22:02:30 +08:00
|
|
|
namespace NEO {
|
|
|
|
class GraphicsAllocation;
|
|
|
|
class MemoryManager;
|
2024-01-13 00:27:50 +08:00
|
|
|
class Device;
|
2023-09-27 22:02:30 +08:00
|
|
|
|
2023-11-30 19:27:42 +08:00
|
|
|
class InOrderExecInfo : public NEO::NonCopyableClass {
|
|
|
|
public:
|
2023-09-27 22:02:30 +08:00
|
|
|
~InOrderExecInfo();
|
|
|
|
|
|
|
|
InOrderExecInfo() = delete;
|
|
|
|
|
2024-01-13 00:27:50 +08:00
|
|
|
static std::shared_ptr<InOrderExecInfo> create(NEO::Device &device, uint32_t partitionCount, bool regularCmdList, bool atomicDeviceSignalling, bool duplicatedHostStorage);
|
|
|
|
static std::shared_ptr<InOrderExecInfo> createFromExternalAllocation(NEO::Device &device, uint64_t deviceAddress, uint64_t *hostAddress, uint64_t counterValue);
|
2023-09-27 22:02:30 +08:00
|
|
|
|
2024-01-13 00:27:50 +08:00
|
|
|
InOrderExecInfo(NEO::GraphicsAllocation *deviceCounterAllocation, NEO::GraphicsAllocation *hostCounterAllocation, NEO::MemoryManager &memoryManager, uint32_t partitionCount, bool regularCmdList, bool atomicDeviceSignalling);
|
|
|
|
|
|
|
|
NEO::GraphicsAllocation *getDeviceCounterAllocation() const { return deviceCounterAllocation; }
|
2023-12-07 23:33:34 +08:00
|
|
|
NEO::GraphicsAllocation *getHostCounterAllocation() const { return hostCounterAllocation; }
|
2023-12-11 19:45:58 +08:00
|
|
|
uint64_t *getBaseHostAddress() const { return hostAddress; }
|
2024-01-13 00:27:50 +08:00
|
|
|
uint64_t getBaseDeviceAddress() const { return deviceAddress; }
|
2023-11-30 19:27:42 +08:00
|
|
|
|
|
|
|
uint64_t getCounterValue() const { return counterValue; }
|
|
|
|
void addCounterValue(uint64_t addValue) { counterValue += addValue; }
|
|
|
|
void resetCounterValue() { counterValue = 0; }
|
|
|
|
|
|
|
|
uint64_t getRegularCmdListSubmissionCounter() const { return regularCmdListSubmissionCounter; }
|
|
|
|
void addRegularCmdListSubmissionCounter(uint64_t addValue) { regularCmdListSubmissionCounter += addValue; }
|
|
|
|
|
|
|
|
bool isRegularCmdList() const { return regularCmdList; }
|
2023-12-07 23:33:34 +08:00
|
|
|
bool isHostStorageDuplicated() const { return duplicatedHostStorage; }
|
2023-12-13 19:47:42 +08:00
|
|
|
bool isAtomicDeviceSignalling() const { return atomicDeviceSignalling; }
|
2023-11-30 19:27:42 +08:00
|
|
|
|
2023-12-01 21:20:13 +08:00
|
|
|
uint32_t getNumDevicePartitionsToWait() const { return numDevicePartitionsToWait; }
|
|
|
|
uint32_t getNumHostPartitionsToWait() const { return numHostPartitionsToWait; }
|
|
|
|
|
2023-12-11 19:45:58 +08:00
|
|
|
void addAllocationOffset(uint32_t addValue) { allocationOffset += addValue; }
|
|
|
|
uint32_t getAllocationOffset() const { return allocationOffset; }
|
|
|
|
|
2023-11-30 19:27:42 +08:00
|
|
|
void reset();
|
|
|
|
|
|
|
|
protected:
|
2023-09-27 22:02:30 +08:00
|
|
|
NEO::MemoryManager &memoryManager;
|
2024-01-13 00:27:50 +08:00
|
|
|
NEO::GraphicsAllocation *deviceCounterAllocation = nullptr;
|
2023-12-07 23:33:34 +08:00
|
|
|
NEO::GraphicsAllocation *hostCounterAllocation = nullptr;
|
2023-11-30 19:27:42 +08:00
|
|
|
uint64_t counterValue = 0;
|
2023-09-27 22:02:30 +08:00
|
|
|
uint64_t regularCmdListSubmissionCounter = 0;
|
2024-01-13 00:27:50 +08:00
|
|
|
uint64_t deviceAddress = 0;
|
2023-12-01 21:20:13 +08:00
|
|
|
uint64_t *hostAddress = nullptr;
|
|
|
|
uint32_t numDevicePartitionsToWait = 0;
|
|
|
|
uint32_t numHostPartitionsToWait = 0;
|
2023-12-11 19:45:58 +08:00
|
|
|
uint32_t allocationOffset = 0;
|
2023-11-30 19:27:42 +08:00
|
|
|
bool regularCmdList = false;
|
2023-12-07 23:33:34 +08:00
|
|
|
bool duplicatedHostStorage = false;
|
2023-12-13 19:47:42 +08:00
|
|
|
bool atomicDeviceSignalling = false;
|
2023-09-27 22:02:30 +08:00
|
|
|
};
|
|
|
|
|
2023-09-29 21:47:43 +08:00
|
|
|
namespace InOrderPatchCommandHelpers {
|
|
|
|
inline uint64_t getAppendCounterValue(const InOrderExecInfo &inOrderExecInfo) {
|
2023-11-30 19:27:42 +08:00
|
|
|
if (inOrderExecInfo.isRegularCmdList() && inOrderExecInfo.getRegularCmdListSubmissionCounter() > 1) {
|
|
|
|
return inOrderExecInfo.getCounterValue() * (inOrderExecInfo.getRegularCmdListSubmissionCounter() - 1);
|
2023-09-29 21:47:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum class PatchCmdType {
|
2023-12-14 00:09:52 +08:00
|
|
|
none,
|
|
|
|
lri64b,
|
|
|
|
sdi,
|
|
|
|
semaphore,
|
|
|
|
walker
|
2023-09-20 18:47:56 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
2023-09-29 21:47:43 +08:00
|
|
|
struct PatchCmd {
|
2023-12-21 21:48:32 +08:00
|
|
|
PatchCmd(std::shared_ptr<InOrderExecInfo> *inOrderExecInfo, void *cmd1, void *cmd2, uint64_t baseCounterValue, PatchCmdType patchCmdType, bool deviceAtomicSignaling, bool duplicatedHostStorage)
|
|
|
|
: cmd1(cmd1), cmd2(cmd2), baseCounterValue(baseCounterValue), patchCmdType(patchCmdType), deviceAtomicSignaling(deviceAtomicSignaling), duplicatedHostStorage(duplicatedHostStorage) {
|
2023-10-03 17:34:45 +08:00
|
|
|
if (inOrderExecInfo) {
|
|
|
|
this->inOrderExecInfo = *inOrderExecInfo;
|
|
|
|
}
|
|
|
|
}
|
2023-09-20 18:47:56 +08:00
|
|
|
|
2023-11-09 01:23:41 +08:00
|
|
|
void patch(uint64_t appendCounterValue) {
|
2023-09-29 21:47:43 +08:00
|
|
|
switch (patchCmdType) {
|
2023-12-14 00:09:52 +08:00
|
|
|
case PatchCmdType::sdi:
|
2023-11-09 01:23:41 +08:00
|
|
|
patchSdi(appendCounterValue);
|
2023-09-22 19:18:43 +08:00
|
|
|
break;
|
2023-12-14 00:09:52 +08:00
|
|
|
case PatchCmdType::semaphore:
|
2023-11-09 01:23:41 +08:00
|
|
|
patchSemaphore(appendCounterValue);
|
2023-09-22 19:18:43 +08:00
|
|
|
break;
|
2023-12-14 00:09:52 +08:00
|
|
|
case PatchCmdType::walker:
|
2023-11-09 01:23:41 +08:00
|
|
|
patchComputeWalker(appendCounterValue);
|
|
|
|
break;
|
2023-12-14 00:09:52 +08:00
|
|
|
case PatchCmdType::lri64b:
|
2023-11-09 01:23:41 +08:00
|
|
|
patchLri64b(appendCounterValue);
|
2023-09-22 19:18:43 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
UNRECOVERABLE_IF(true);
|
|
|
|
break;
|
2023-09-20 18:47:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-03 17:34:45 +08:00
|
|
|
bool isExternalDependency() const { return inOrderExecInfo.get(); }
|
|
|
|
|
|
|
|
std::shared_ptr<InOrderExecInfo> inOrderExecInfo;
|
2023-11-09 01:23:41 +08:00
|
|
|
void *cmd1 = nullptr;
|
|
|
|
void *cmd2 = nullptr;
|
2023-09-20 18:47:56 +08:00
|
|
|
const uint64_t baseCounterValue = 0;
|
2023-12-14 00:09:52 +08:00
|
|
|
const PatchCmdType patchCmdType = PatchCmdType::none;
|
2023-12-21 21:48:32 +08:00
|
|
|
bool deviceAtomicSignaling = false;
|
|
|
|
bool duplicatedHostStorage = false;
|
2023-09-20 18:47:56 +08:00
|
|
|
|
|
|
|
protected:
|
2023-11-09 01:23:41 +08:00
|
|
|
void patchSdi(uint64_t appendCounterValue) {
|
|
|
|
auto sdiCmd = reinterpret_cast<typename GfxFamily::MI_STORE_DATA_IMM *>(cmd1);
|
|
|
|
sdiCmd->setDataDword0(getLowPart(baseCounterValue + appendCounterValue));
|
|
|
|
sdiCmd->setDataDword1(getHighPart(baseCounterValue + appendCounterValue));
|
2023-09-20 18:47:56 +08:00
|
|
|
}
|
|
|
|
|
2023-11-09 01:23:41 +08:00
|
|
|
void patchSemaphore(uint64_t appendCounterValue) {
|
2023-10-03 17:34:45 +08:00
|
|
|
if (isExternalDependency()) {
|
2023-11-09 01:23:41 +08:00
|
|
|
appendCounterValue = InOrderPatchCommandHelpers::getAppendCounterValue(*inOrderExecInfo);
|
|
|
|
if (appendCounterValue == 0) {
|
2023-10-03 17:34:45 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-09 01:23:41 +08:00
|
|
|
auto semaphoreCmd = reinterpret_cast<typename GfxFamily::MI_SEMAPHORE_WAIT *>(cmd1);
|
|
|
|
semaphoreCmd->setSemaphoreDataDword(static_cast<uint32_t>(baseCounterValue + appendCounterValue));
|
2023-09-20 18:47:56 +08:00
|
|
|
}
|
|
|
|
|
2023-12-21 21:16:43 +08:00
|
|
|
void patchComputeWalker(uint64_t appendCounterValue);
|
2023-09-22 19:18:43 +08:00
|
|
|
|
2023-11-09 01:23:41 +08:00
|
|
|
void patchLri64b(uint64_t appendCounterValue) {
|
|
|
|
if (isExternalDependency()) {
|
|
|
|
appendCounterValue = InOrderPatchCommandHelpers::getAppendCounterValue(*inOrderExecInfo);
|
|
|
|
if (appendCounterValue == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const uint64_t counterValue = baseCounterValue + appendCounterValue;
|
|
|
|
|
|
|
|
auto lri1 = reinterpret_cast<typename GfxFamily::MI_LOAD_REGISTER_IMM *>(cmd1);
|
|
|
|
lri1->setDataDword(getLowPart(counterValue));
|
|
|
|
|
|
|
|
auto lri2 = reinterpret_cast<typename GfxFamily::MI_LOAD_REGISTER_IMM *>(cmd2);
|
|
|
|
lri2->setDataDword(getHighPart(counterValue));
|
|
|
|
}
|
|
|
|
|
2023-09-29 21:47:43 +08:00
|
|
|
PatchCmd() = delete;
|
2023-09-20 18:47:56 +08:00
|
|
|
};
|
|
|
|
|
2023-09-29 21:47:43 +08:00
|
|
|
} // namespace InOrderPatchCommandHelpers
|
2023-09-20 18:47:56 +08:00
|
|
|
|
|
|
|
template <typename GfxFamily>
|
2023-12-11 20:10:56 +08:00
|
|
|
using InOrderPatchCommandsContainer = std::vector<NEO::InOrderPatchCommandHelpers::PatchCmd<GfxFamily>>;
|
2023-09-20 18:47:56 +08:00
|
|
|
|
2023-12-11 20:10:56 +08:00
|
|
|
} // namespace NEO
|