mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00
Preemption - SIP command programming
Change-Id: I4c7c805a77a9decb8f13d39055bfb2590209ca3e
This commit is contained in:

committed by
sys_ocldev

parent
6272c3ee65
commit
d290955a57
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -238,6 +238,13 @@ IndirectHeap &CommandQueue::getIndirectHeap(IndirectHeap::Type heapType,
|
||||
minHeapSize -= MemoryConstants::pageSize;
|
||||
}
|
||||
|
||||
size_t reservedSize = 0;
|
||||
if (heapType == IndirectHeap::INSTRUCTION) {
|
||||
reservedSize = alignUp(device->getCommandStreamReceiver().getInstructionHeapCmdStreamReceiverReservedSize(),
|
||||
MemoryConstants::cacheLineSize);
|
||||
}
|
||||
|
||||
minRequiredSize += reservedSize;
|
||||
minRequiredSize = minRequiredSize ? std::max(minRequiredSize, minHeapSize) : 0;
|
||||
minRequiredSize = minRequiredSize > 0 ? alignUp(minRequiredSize, MemoryConstants::cacheLineSize) : 0;
|
||||
|
||||
@ -255,6 +262,11 @@ IndirectHeap &CommandQueue::getIndirectHeap(IndirectHeap::Type heapType,
|
||||
heap = new IndirectHeap(heapMemory);
|
||||
heap->overrideMaxSize(minRequiredSize);
|
||||
}
|
||||
|
||||
if (heapType == IndirectHeap::INSTRUCTION) {
|
||||
device->getCommandStreamReceiver().initializeInstructionHeapCmdStreamReceiverReservedBlock(*heap);
|
||||
heap->align(MemoryConstants::cacheLineSize);
|
||||
}
|
||||
}
|
||||
|
||||
return *heap;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -20,7 +20,10 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "runtime/built_ins/built_ins.h"
|
||||
#include "runtime/command_stream/command_stream_receiver.h"
|
||||
#include "runtime/command_stream/preemption.h"
|
||||
#include "runtime/device/device.h"
|
||||
#include "runtime/memory_manager/memory_manager.h"
|
||||
#include "runtime/helpers/cache_policy.h"
|
||||
#include "runtime/os_interface/os_interface.h"
|
||||
@ -197,4 +200,13 @@ void CommandStreamReceiver::setRequiredScratchSize(uint32_t newRequiredScratchSi
|
||||
requiredScratchSize = newRequiredScratchSize;
|
||||
}
|
||||
}
|
||||
|
||||
size_t CommandStreamReceiver::getInstructionHeapCmdStreamReceiverReservedSize() const {
|
||||
return PreemptionHelper::getInstructionHeapSipKernelReservedSize(*memoryManager->device);
|
||||
}
|
||||
|
||||
void CommandStreamReceiver::initializeInstructionHeapCmdStreamReceiverReservedBlock(LinearStream &ih) const {
|
||||
return PreemptionHelper::initializeInstructionHeapSipKernelReservedBlock(ih, *memoryManager->device);
|
||||
}
|
||||
|
||||
} // namespace OCLRT
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -109,6 +109,12 @@ class CommandStreamReceiver {
|
||||
virtual void waitForTaskCountWithKmdNotifyFallback(uint32_t taskCountToWait, FlushStamp flushStampToWait) = 0;
|
||||
MOCKABLE_VIRTUAL bool waitForCompletionWithTimeout(bool enableTimeout, int64_t timeoutMs, uint32_t taskCountToWait);
|
||||
|
||||
// returns size of block that needs to be reserved at the beginning of each instruction heap for CommandStreamReceiver
|
||||
MOCKABLE_VIRTUAL size_t getInstructionHeapCmdStreamReceiverReservedSize() const;
|
||||
|
||||
// allows CommandStreamReceiver to prepopulate reserved block in instruction heap
|
||||
MOCKABLE_VIRTUAL void initializeInstructionHeapCmdStreamReceiverReservedBlock(LinearStream &ih) const;
|
||||
|
||||
protected:
|
||||
// taskCount - # of tasks submitted
|
||||
uint32_t taskCount = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -61,14 +61,14 @@ class CommandStreamReceiverHw : public CommandStreamReceiver {
|
||||
static void addBatchBufferStart(MI_BATCH_BUFFER_START *commandBufferMemory, uint64_t startAddress);
|
||||
static void alignToCacheLine(LinearStream &commandStream);
|
||||
|
||||
size_t getRequiredCsrSize();
|
||||
size_t getRequiredCmdStreamSize(const DispatchFlags &dispatchFlags);
|
||||
size_t getCmdSizeForCoherency();
|
||||
void programCoherency(LinearStream &csr, DispatchFlags &dispatchFlags);
|
||||
|
||||
void waitForTaskCountWithKmdNotifyFallback(uint32_t taskCountToWait, FlushStamp flushStampToWait) override;
|
||||
|
||||
protected:
|
||||
void programPreemption(LinearStream &csr, DispatchFlags &dispatchFlags);
|
||||
void programPreemption(LinearStream &csr, DispatchFlags &dispatchFlags, const LinearStream &ih);
|
||||
void programL3(LinearStream &csr, DispatchFlags &dispatchFlags, uint32_t &newL3Config);
|
||||
void programMediaSampler(LinearStream &csr, DispatchFlags &dispatchFlags);
|
||||
void programPreamble(LinearStream &csr, DispatchFlags &dispatchFlags, uint32_t &newL3Config);
|
||||
@ -93,5 +93,5 @@ class CommandStreamReceiverHw : public CommandStreamReceiver {
|
||||
};
|
||||
|
||||
template <typename GfxFamily>
|
||||
size_t getSizeRequiredPreambleCS(const HardwareInfo &hwInfo);
|
||||
size_t getSizeRequiredPreambleCS(const Device &device);
|
||||
} // namespace OCLRT
|
||||
|
@ -67,11 +67,11 @@ inline void CommandStreamReceiverHw<GfxFamily>::alignToCacheLine(LinearStream &c
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
size_t getSizeRequiredPreambleCS(const HardwareInfo &hwInfo) {
|
||||
size_t getSizeRequiredPreambleCS(const Device &device) {
|
||||
return sizeof(typename GfxFamily::MI_LOAD_REGISTER_IMM) +
|
||||
sizeof(typename GfxFamily::PIPELINE_SELECT) +
|
||||
sizeof(typename GfxFamily::PIPE_CONTROL) +
|
||||
sizeof(typename GfxFamily::MEDIA_VFE_STATE) + PreambleHelper<GfxFamily>::getAdditionalCommandsSize(hwInfo);
|
||||
sizeof(typename GfxFamily::MEDIA_VFE_STATE) + PreambleHelper<GfxFamily>::getAdditionalCommandsSize(device);
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
@ -163,11 +163,11 @@ CompletionStamp CommandStreamReceiverHw<GfxFamily>::flushTask(
|
||||
csrSizeRequestFlags.preemptionRequestChanged = this->lastPreemptionMode != dispatchFlags.preemptionMode;
|
||||
csrSizeRequestFlags.mediaSamplerConfigChanged = this->lastMediaSamplerConfig != dispatchFlags.mediaSamplerRequired;
|
||||
|
||||
auto &commandStreamCSR = this->getCS(getRequiredCsrSize());
|
||||
auto &commandStreamCSR = this->getCS(getRequiredCmdStreamSize(dispatchFlags));
|
||||
auto commandStreamStartCSR = commandStreamCSR.getUsed();
|
||||
|
||||
initPageTableManagerRegisters(commandStreamCSR);
|
||||
programPreemption(commandStreamCSR, dispatchFlags);
|
||||
programPreemption(commandStreamCSR, dispatchFlags, ih);
|
||||
programCoherency(commandStreamCSR, dispatchFlags);
|
||||
programL3(commandStreamCSR, dispatchFlags, newL3Config);
|
||||
programMediaSampler(commandStreamCSR, dispatchFlags);
|
||||
@ -491,8 +491,8 @@ uint64_t CommandStreamReceiverHw<GfxFamily>::getScratchPatchAddress() {
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
size_t CommandStreamReceiverHw<GfxFamily>::getRequiredCsrSize() {
|
||||
size_t size = getSizeRequiredPreambleCS<GfxFamily>(hwInfo) +
|
||||
size_t CommandStreamReceiverHw<GfxFamily>::getRequiredCmdStreamSize(const DispatchFlags &dispatchFlags) {
|
||||
size_t size = getSizeRequiredPreambleCS<GfxFamily>(*memoryManager->device) +
|
||||
sizeof(typename GfxFamily::STATE_BASE_ADDRESS) +
|
||||
sizeof(PIPE_CONTROL) +
|
||||
getRequiredPipeControlSize() +
|
||||
@ -502,9 +502,8 @@ size_t CommandStreamReceiverHw<GfxFamily>::getRequiredCsrSize() {
|
||||
}
|
||||
size += getCmdSizeForCoherency();
|
||||
|
||||
if (csrSizeRequestFlags.preemptionRequestChanged) {
|
||||
size += PreemptionHelper::getRequiredCmdStreamSize<GfxFamily>(memoryManager->device->getPreemptionMode());
|
||||
}
|
||||
size += PreemptionHelper::getRequiredCmdStreamSize<GfxFamily>(dispatchFlags.preemptionMode, this->lastPreemptionMode);
|
||||
|
||||
return alignUp(size, MemoryConstants::cacheLineSize);
|
||||
}
|
||||
|
||||
@ -529,11 +528,11 @@ inline void CommandStreamReceiverHw<GfxFamily>::waitForTaskCountWithKmdNotifyFal
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
inline void CommandStreamReceiverHw<GfxFamily>::programPreemption(LinearStream &csr, DispatchFlags &dispatchFlags) {
|
||||
if (csrSizeRequestFlags.preemptionRequestChanged) {
|
||||
PreemptionHelper::programCmdStream<GfxFamily>(&csr, dispatchFlags.preemptionMode, preemptionCsrAllocation, nullptr);
|
||||
this->lastPreemptionMode = dispatchFlags.preemptionMode;
|
||||
}
|
||||
inline void CommandStreamReceiverHw<GfxFamily>::programPreemption(LinearStream &csr, DispatchFlags &dispatchFlags,
|
||||
const LinearStream &ih) {
|
||||
PreemptionHelper::programCmdStream<GfxFamily>(csr, dispatchFlags.preemptionMode, this->lastPreemptionMode, preemptionCsrAllocation,
|
||||
ih, *memoryManager->device);
|
||||
this->lastPreemptionMode = dispatchFlags.preemptionMode;
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
@ -562,7 +561,7 @@ inline void CommandStreamReceiverHw<GfxFamily>::programMediaSampler(LinearStream
|
||||
template <typename GfxFamily>
|
||||
inline void CommandStreamReceiverHw<GfxFamily>::programPreamble(LinearStream &csr, DispatchFlags &dispatchFlags, uint32_t &newL3Config) {
|
||||
if (!this->isPreambleSent) {
|
||||
PreambleHelper<GfxFamily>::programPreamble(&csr, hwInfo, newL3Config, this->requiredThreadArbitrationPolicy);
|
||||
PreambleHelper<GfxFamily>::programPreamble(&csr, *memoryManager->device, newL3Config, this->requiredThreadArbitrationPolicy, this->preemptionCsrAllocation);
|
||||
this->isPreambleSent = true;
|
||||
this->lastSentL3Config = newL3Config;
|
||||
this->lastSentThreadAribtrationPolicy = this->requiredThreadArbitrationPolicy;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -20,8 +20,11 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "runtime/built_ins/built_ins.h"
|
||||
#include "runtime/command_stream/preemption.h"
|
||||
#include "runtime/device/device.h"
|
||||
#include "runtime/helpers/dispatch_info.h"
|
||||
#include "runtime/helpers/string.h"
|
||||
#include "runtime/kernel/kernel.h"
|
||||
|
||||
namespace OCLRT {
|
||||
@ -101,4 +104,37 @@ void PreemptionHelper::adjustDefaultPreemptionMode(RuntimeCapabilityTable &devic
|
||||
}
|
||||
}
|
||||
|
||||
size_t PreemptionHelper::getInstructionHeapSipKernelReservedSize(const Device &device) {
|
||||
if (device.getPreemptionMode() != PreemptionMode::MidThread) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BuiltIns::getInstance().getSipKernel(SipKernelType::Csr, device).getBinarySize();
|
||||
}
|
||||
|
||||
void PreemptionHelper::initializeInstructionHeapSipKernelReservedBlock(LinearStream &ih, const Device &device) {
|
||||
if (device.getPreemptionMode() != PreemptionMode::MidThread) {
|
||||
return;
|
||||
}
|
||||
|
||||
const SipKernel &sip = BuiltIns::getInstance().getSipKernel(SipKernelType::Csr, device);
|
||||
size_t sipSize = sip.getBinarySize();
|
||||
UNRECOVERABLE_IF(sipSize > ih.getAvailableSpace());
|
||||
UNRECOVERABLE_IF(0 != ih.getUsed());
|
||||
void *blockForSip = ih.getSpace(sipSize);
|
||||
UNRECOVERABLE_IF(nullptr == blockForSip);
|
||||
auto err = memcpy_s(blockForSip, sipSize, sip.getBinary(), sipSize);
|
||||
UNRECOVERABLE_IF(err != 0);
|
||||
}
|
||||
|
||||
// verify that SIP CSR kernel resides at the begining of the InstructionHeap
|
||||
bool PreemptionHelper::isValidInstructionHeapForMidThreadPreemption(const LinearStream &ih, const Device &device) {
|
||||
const SipKernel &sip = BuiltIns::getInstance().getSipKernel(SipKernelType::Csr, device);
|
||||
if (ih.getUsed() < sip.getBinarySize()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (0 == memcmp(ih.getBase(), sip.getBinary(), sip.getBinarySize()));
|
||||
}
|
||||
|
||||
} // namespace OCLRT
|
||||
|
@ -38,11 +38,22 @@ class PreemptionHelper {
|
||||
static bool allowMidThreadPreemption(Kernel *kernel, Device &device);
|
||||
static void adjustDefaultPreemptionMode(RuntimeCapabilityTable &deviceCapabilities, bool allowMidThread, bool allowThreadGroup, bool allowMidBatch);
|
||||
|
||||
template <typename GfxFamily>
|
||||
static void programCmdStream(LinearStream *cmdStream, PreemptionMode &preemptionMode, GraphicsAllocation *preemptionCsr, GraphicsAllocation *sipKernel);
|
||||
static size_t getInstructionHeapSipKernelReservedSize(const Device &device);
|
||||
static void initializeInstructionHeapSipKernelReservedBlock(LinearStream &ih, const Device &device);
|
||||
static bool isValidInstructionHeapForMidThreadPreemption(const LinearStream &ih, const Device &device);
|
||||
|
||||
template <typename GfxFamily>
|
||||
static size_t getRequiredCmdStreamSize(PreemptionMode preemptionMode);
|
||||
static size_t getRequiredPreambleSize(const Device &device);
|
||||
|
||||
template <typename GfxFamily>
|
||||
static void programPreamble(LinearStream &preambleCmdStream, const Device &device, const GraphicsAllocation *preemptionCsr);
|
||||
|
||||
template <typename GfxFamily>
|
||||
static size_t getRequiredCmdStreamSize(PreemptionMode newPreemptionMode, PreemptionMode oldPreemptionMode);
|
||||
|
||||
template <typename GfxFamily>
|
||||
static void programCmdStream(LinearStream &cmdStream, PreemptionMode newPreemptionMode, PreemptionMode oldPreemptionMode,
|
||||
GraphicsAllocation *preemptionCsr, const LinearStream &ih, const Device &device);
|
||||
|
||||
template <typename GfxFamily>
|
||||
static size_t getPreemptionWaCsSize(const Device &device);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -52,7 +52,7 @@ void CommandStreamReceiverHw<Family>::addDcFlushToPipeControl(Family::PIPE_CONTR
|
||||
pCmd->setDcFlushEnable(flushDC);
|
||||
}
|
||||
|
||||
template size_t getSizeRequiredPreambleCS<Family>(const HardwareInfo &hwInfo);
|
||||
template size_t getSizeRequiredPreambleCS<Family>(const Device &hwInfo);
|
||||
|
||||
template <>
|
||||
void populateFactoryTable<CommandStreamReceiverHw<Family>>() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -37,7 +37,7 @@ void PreambleHelper<BDWFamily>::programThreadArbitration(LinearStream *pCommandS
|
||||
}
|
||||
|
||||
template <>
|
||||
uint32_t PreambleHelper<BDWFamily>::getAdditionalCommandsSize(const HardwareInfo &hwInfo) {
|
||||
uint32_t PreambleHelper<BDWFamily>::getAdditionalCommandsSize(const Device &device) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -35,23 +35,42 @@ static constexpr uint32_t cmdLevelVal = (1 << 2);
|
||||
}; // namespace PreemptionBDW
|
||||
|
||||
template <>
|
||||
void PreemptionHelper::programCmdStream<GfxFamily>(LinearStream *cmdStream, PreemptionMode &preemptionMode, GraphicsAllocation *preemptionCsr, GraphicsAllocation *sipKernel) {
|
||||
void PreemptionHelper::programCmdStream<GfxFamily>(LinearStream &cmdStream, PreemptionMode newPreemptionMode, PreemptionMode oldPreemptionMode,
|
||||
GraphicsAllocation *preemptionCsr, const LinearStream &ih, const Device &device) {
|
||||
if (newPreemptionMode == oldPreemptionMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t regVal = 0;
|
||||
if (preemptionMode == PreemptionMode::ThreadGroup) {
|
||||
if (newPreemptionMode == PreemptionMode::ThreadGroup) {
|
||||
regVal = PreemptionBDW::threadGroupVal;
|
||||
} else {
|
||||
regVal = PreemptionBDW::cmdLevelVal;
|
||||
}
|
||||
|
||||
LriHelper<GfxFamily>::program(cmdStream, PreemptionBDW::mmioAddress, regVal);
|
||||
LriHelper<GfxFamily>::program(&cmdStream, PreemptionBDW::mmioAddress, regVal);
|
||||
}
|
||||
|
||||
template <>
|
||||
size_t PreemptionHelper::getRequiredCmdStreamSize<GfxFamily>(PreemptionMode preemptionMode) {
|
||||
size_t PreemptionHelper::getRequiredCmdStreamSize<GfxFamily>(PreemptionMode newPreemptionMode, PreemptionMode oldPreemptionMode) {
|
||||
if (newPreemptionMode == oldPreemptionMode) {
|
||||
return 0;
|
||||
}
|
||||
return sizeof(typename GfxFamily::MI_LOAD_REGISTER_IMM);
|
||||
}
|
||||
|
||||
template <>
|
||||
size_t PreemptionHelper::getRequiredPreambleSize<GfxFamily>(const Device &device) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
void PreemptionHelper::programPreamble<GfxFamily>(LinearStream &preambleCmdStream, const Device &device,
|
||||
const GraphicsAllocation *preemptionCsr) {
|
||||
}
|
||||
|
||||
template size_t PreemptionHelper::getPreemptionWaCsSize<GfxFamily>(const Device &device);
|
||||
template void PreemptionHelper::applyPreemptionWaCmdsBegin<GfxFamily>(LinearStream *pCommandStream, const Device &device);
|
||||
template void PreemptionHelper::applyPreemptionWaCmdsEnd<GfxFamily>(LinearStream *pCommandStream, const Device &device);
|
||||
|
||||
} // namespace OCLRT
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -56,7 +56,7 @@ template <>
|
||||
void CommandStreamReceiverHw<Family>::addDcFlushToPipeControl(Family::PIPE_CONTROL *pCmd, bool flushDC) {
|
||||
}
|
||||
|
||||
template size_t getSizeRequiredPreambleCS<Family>(const HardwareInfo &hwInfo);
|
||||
template size_t getSizeRequiredPreambleCS<Family>(const Device &device);
|
||||
|
||||
template <>
|
||||
void populateFactoryTable<CommandStreamReceiverHw<Family>>() {
|
||||
|
@ -20,6 +20,9 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "runtime/built_ins/built_ins.h"
|
||||
#include "runtime/command_stream/preemption.h"
|
||||
#include "runtime/command_stream/preemption.inl"
|
||||
#include "runtime/memory_manager/graphics_allocation.h"
|
||||
@ -40,33 +43,62 @@ static constexpr uint32_t midThreadVal = 0;
|
||||
}; // namespace PreemptionSKL
|
||||
|
||||
template <>
|
||||
void PreemptionHelper::programCmdStream<GfxFamily>(LinearStream *cmdStream, PreemptionMode &preemptionMode, GraphicsAllocation *preemptionCsr, GraphicsAllocation *sipKernel) {
|
||||
void PreemptionHelper::programCmdStream<GfxFamily>(LinearStream &cmdStream,
|
||||
PreemptionMode newPreemptionMode, PreemptionMode oldPreemptionMode,
|
||||
GraphicsAllocation *preemptionCsr,
|
||||
const LinearStream &ih, const Device &device) {
|
||||
if (oldPreemptionMode == newPreemptionMode) {
|
||||
DEBUG_BREAK_IF((newPreemptionMode == PreemptionMode::MidThread) && (false == isValidInstructionHeapForMidThreadPreemption(ih, device)));
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t regVal = 0;
|
||||
if (preemptionMode == PreemptionMode::MidThread) {
|
||||
if (newPreemptionMode == PreemptionMode::MidThread) {
|
||||
regVal = PreemptionSKL::midThreadVal | PreemptionSKL::mask;
|
||||
} else if (preemptionMode == PreemptionMode::ThreadGroup) {
|
||||
} else if (newPreemptionMode == PreemptionMode::ThreadGroup) {
|
||||
regVal = PreemptionSKL::threadGroupVal | PreemptionSKL::mask;
|
||||
} else {
|
||||
regVal = PreemptionSKL::cmdLevelVal | PreemptionSKL::mask;
|
||||
}
|
||||
|
||||
LriHelper<GfxFamily>::program(cmdStream, PreemptionSKL::mmioAddress, regVal);
|
||||
|
||||
if (preemptionMode == PreemptionMode::MidThread) {
|
||||
typedef typename GfxFamily::GPGPU_CSR_BASE_ADDRESS GPGPU_CSR_BASE_ADDRESS;
|
||||
auto csr = (GPGPU_CSR_BASE_ADDRESS *)cmdStream->getSpace(sizeof(GPGPU_CSR_BASE_ADDRESS));
|
||||
*csr = GPGPU_CSR_BASE_ADDRESS::sInit();
|
||||
csr->setGpgpuCsrBaseAddress(preemptionCsr->getGpuAddressToPatch());
|
||||
}
|
||||
LriHelper<GfxFamily>::program(&cmdStream, PreemptionSKL::mmioAddress, regVal);
|
||||
}
|
||||
|
||||
template <>
|
||||
size_t PreemptionHelper::getRequiredCmdStreamSize<GfxFamily>(PreemptionMode preemptionMode) {
|
||||
size_t size = sizeof(typename GfxFamily::MI_LOAD_REGISTER_IMM);
|
||||
if (preemptionMode == PreemptionMode::MidThread) {
|
||||
size += sizeof(typename GfxFamily::GPGPU_CSR_BASE_ADDRESS);
|
||||
size_t PreemptionHelper::getRequiredCmdStreamSize<GfxFamily>(PreemptionMode newPreemptionMode, PreemptionMode oldPreemptionMode) {
|
||||
if (newPreemptionMode == oldPreemptionMode) {
|
||||
return 0;
|
||||
}
|
||||
return size;
|
||||
return sizeof(typename GfxFamily::MI_LOAD_REGISTER_IMM);
|
||||
}
|
||||
|
||||
template <>
|
||||
size_t PreemptionHelper::getRequiredPreambleSize<GfxFamily>(const Device &device) {
|
||||
if (device.getPreemptionMode() != PreemptionMode::MidThread) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sizeof(typename GfxFamily::GPGPU_CSR_BASE_ADDRESS) + sizeof(typename GfxFamily::STATE_SIP);
|
||||
}
|
||||
|
||||
template <>
|
||||
void PreemptionHelper::programPreamble<GfxFamily>(LinearStream &preambleCmdStream, const Device &device,
|
||||
const GraphicsAllocation *preemptionCsr) {
|
||||
if (device.getPreemptionMode() != PreemptionMode::MidThread) {
|
||||
return;
|
||||
}
|
||||
|
||||
UNRECOVERABLE_IF(nullptr == preemptionCsr);
|
||||
using GPGPU_CSR_BASE_ADDRESS = typename GfxFamily::GPGPU_CSR_BASE_ADDRESS;
|
||||
using STATE_SIP = typename GfxFamily::STATE_SIP;
|
||||
|
||||
auto csr = reinterpret_cast<GPGPU_CSR_BASE_ADDRESS *>(preambleCmdStream.getSpace(sizeof(GPGPU_CSR_BASE_ADDRESS)));
|
||||
csr->init();
|
||||
csr->setGpgpuCsrBaseAddress(preemptionCsr->getGpuAddressToPatch());
|
||||
|
||||
auto sip = reinterpret_cast<STATE_SIP *>(preambleCmdStream.getSpace(sizeof(STATE_SIP)));
|
||||
sip->init();
|
||||
sip->setSystemInstructionPointer(0);
|
||||
}
|
||||
|
||||
template size_t PreemptionHelper::getPreemptionWaCsSize<GfxFamily>(const Device &device);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -28,6 +28,7 @@ namespace OCLRT {
|
||||
|
||||
struct HardwareInfo;
|
||||
class Device;
|
||||
class GraphicsAllocation;
|
||||
class LinearStream;
|
||||
|
||||
template <typename GfxFamily>
|
||||
@ -37,13 +38,15 @@ struct PreambleHelper {
|
||||
static void programL3(LinearStream *pCommandStream, uint32_t l3Config);
|
||||
static void programPipelineSelect(LinearStream *pCommandStream);
|
||||
static void programThreadArbitration(LinearStream *pCommandStream, uint32_t requiredThreadArbitrationPolicy);
|
||||
static void programPreemption(LinearStream *pCommandStream, const Device &device, GraphicsAllocation *preemptionCsr);
|
||||
static void setupPipeControlInFrontOfCommand(void *pCmd, const HardwareInfo *hwInfo, bool isVfeCommand);
|
||||
static void programVFEState(LinearStream *pCommandStream, const HardwareInfo &hwInfo, int scratchSize, uint64_t scratchAddress);
|
||||
static void programPreamble(LinearStream *pCommandStream, const HardwareInfo &hwInfo, uint32_t l3Config, uint32_t requiredThreadArbitrationPolicy);
|
||||
static void programPreamble(LinearStream *pCommandStream, const Device &device, uint32_t l3Config,
|
||||
uint32_t requiredThreadArbitrationPolicy, GraphicsAllocation *preemptionCsr);
|
||||
static uint32_t getL3Config(const HardwareInfo &hwInfo, bool useSLM);
|
||||
static void programPSForMedia(LinearStream *pCommandStream, bool enable);
|
||||
static bool getMediaSamplerDopClockGateEnable(LinearStream *pCommandStream);
|
||||
static uint32_t getAdditionalCommandsSize(const HardwareInfo &hwInfo);
|
||||
static uint32_t getAdditionalCommandsSize(const Device &device);
|
||||
static void programGenSpecificPreambleWorkArounds(LinearStream *pCommandStream, const HardwareInfo &hwInfo);
|
||||
static uint32_t getUrbEntryAllocationSize();
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -22,6 +22,7 @@
|
||||
|
||||
#include "runtime/helpers/preamble.h"
|
||||
#include "runtime/command_stream/linear_stream.h"
|
||||
#include "runtime/command_stream/preemption.h"
|
||||
#include "hw_cmds.h"
|
||||
#include "reg_configs.h"
|
||||
#include "runtime/device/device.h"
|
||||
@ -64,10 +65,12 @@ void PreambleHelper<GfxFamily>::programGenSpecificPreambleWorkArounds(LinearStre
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
uint32_t PreambleHelper<GfxFamily>::getAdditionalCommandsSize(const HardwareInfo &hwInfo) {
|
||||
uint32_t PreambleHelper<GfxFamily>::getAdditionalCommandsSize(const Device &device) {
|
||||
typedef typename GfxFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
|
||||
typedef typename GfxFamily::PIPE_CONTROL PIPE_CONTROL;
|
||||
return sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL);
|
||||
size_t requiredSize = sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL);
|
||||
requiredSize += PreemptionHelper::getRequiredPreambleSize<GfxFamily>(device);
|
||||
return static_cast<uint32_t>(requiredSize);
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
@ -105,11 +108,18 @@ void PreambleHelper<GfxFamily>::programL3(LinearStream *pCommandStream, uint32_t
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
void PreambleHelper<GfxFamily>::programPreamble(LinearStream *pCommandStream, const HardwareInfo &hwInfo, uint32_t l3Config, uint32_t requiredThreadArbitrationPolicy) {
|
||||
void PreambleHelper<GfxFamily>::programPreamble(LinearStream *pCommandStream, const Device &device, uint32_t l3Config,
|
||||
uint32_t requiredThreadArbitrationPolicy, GraphicsAllocation *preemptionCsr) {
|
||||
programL3(pCommandStream, l3Config);
|
||||
programPipelineSelect(pCommandStream);
|
||||
programThreadArbitration(pCommandStream, requiredThreadArbitrationPolicy);
|
||||
programGenSpecificPreambleWorkArounds(pCommandStream, hwInfo);
|
||||
programPreemption(pCommandStream, device, preemptionCsr);
|
||||
programGenSpecificPreambleWorkArounds(pCommandStream, device.getHardwareInfo());
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
void PreambleHelper<GfxFamily>::programPreemption(LinearStream *pCommandStream, const Device &device, GraphicsAllocation *preemptionCsr) {
|
||||
PreemptionHelper::programPreamble<GfxFamily>(*pCommandStream, device, preemptionCsr);
|
||||
}
|
||||
|
||||
template <typename GfxFamily>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -36,8 +36,10 @@
|
||||
#include "unit_tests/fixtures/memory_management_fixture.h"
|
||||
#include "unit_tests/helpers/debug_manager_state_restore.h"
|
||||
#include "unit_tests/libult/ult_command_stream_receiver.h"
|
||||
#include "unit_tests/mocks/mock_memory_manager.h"
|
||||
#include "unit_tests/mocks/mock_command_queue.h"
|
||||
#include "unit_tests/mocks/mock_context.h"
|
||||
#include "unit_tests/mocks/mock_csr.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "gmock/gmock.h"
|
||||
@ -741,3 +743,26 @@ HWTEST_F(KmdNotifyTests, givenMultipleCommandQueuesWhenMarkerIsEmittedThenGraphi
|
||||
auto commandStreamGraphicsAllocation2 = commandQ->getCS(0).getGraphicsAllocation();
|
||||
EXPECT_EQ(commandStreamGraphicsAllocation, commandStreamGraphicsAllocation2);
|
||||
}
|
||||
|
||||
TEST(CommandQueueGetIndirectHeap, whenNewInstructionHeapIsBeingCreatedThenCommandStreamReceiverCanReserveAMemoryBlockAtItsBegining) {
|
||||
char pattern[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 39, 41};
|
||||
static_assert(false == isAligned<MemoryConstants::cacheLineSize>(sizeof(pattern)),
|
||||
"Will be checking for automatic cacheline alignment, so pattern length must not be a multiple of cacheline");
|
||||
size_t alignedPatternSize = alignUp(sizeof(pattern), MemoryConstants::cacheLineSize);
|
||||
|
||||
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
|
||||
MockCommandStreamReceiver *csr = new MockCommandStreamReceiver;
|
||||
mockDevice->resetCommandStreamReceiver(csr);
|
||||
|
||||
csr->instructionHeapReserveredData.assign(pattern, pattern + sizeof(pattern));
|
||||
MockCommandQueue cmdQ{nullptr, mockDevice.get(), nullptr};
|
||||
IndirectHeap &heap = cmdQ.getIndirectHeap(OCLRT::IndirectHeap::INSTRUCTION, 8192);
|
||||
EXPECT_LE(8192U, heap.getAvailableSpace());
|
||||
EXPECT_EQ(alignedPatternSize, heap.getUsed());
|
||||
|
||||
ASSERT_LE(sizeof(pattern), heap.getMaxAvailableSpace());
|
||||
char *reservedBlock = reinterpret_cast<char *>(heap.getBase());
|
||||
auto dataFoundInReservedBlock = ArrayRef<char>(reservedBlock, sizeof(pattern));
|
||||
auto expectedData = ArrayRef<char>(csr->instructionHeapReserveredData);
|
||||
EXPECT_THAT(dataFoundInReservedBlock, testing::ContainerEq(expectedData));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -565,7 +565,7 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, flushTaskWithOnlyEnoughMemoryForPr
|
||||
commandStreamReceiver.lastSentL3Config = l3Config;
|
||||
|
||||
auto &csrCS = commandStreamReceiver.getCS();
|
||||
size_t sizeNeededForPreamble = getSizeRequiredPreambleCS<FamilyType>(commandStreamReceiver.hwInfo);
|
||||
size_t sizeNeededForPreamble = getSizeRequiredPreambleCS<FamilyType>(MockDevice(commandStreamReceiver.hwInfo));
|
||||
size_t sizeNeededForStateBaseAddress = sizeof(STATE_BASE_ADDRESS) + sizeof(PIPE_CONTROL);
|
||||
size_t sizeNeededForPipeControl = commandStreamReceiver.getRequiredPipeControlSize();
|
||||
size_t sizeNeeded = sizeNeededForPreamble +
|
||||
@ -598,7 +598,7 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, flushTaskWithOnlyEnoughMemoryForPr
|
||||
commandStreamReceiver.lastSentL3Config = l3Config;
|
||||
|
||||
auto &csrCS = commandStreamReceiver.getCS();
|
||||
size_t sizeNeededForPreamble = getSizeRequiredPreambleCS<FamilyType>(commandStreamReceiver.hwInfo);
|
||||
size_t sizeNeededForPreamble = getSizeRequiredPreambleCS<FamilyType>(MockDevice(commandStreamReceiver.hwInfo));
|
||||
size_t sizeNeededForStateBaseAddress = sizeof(STATE_BASE_ADDRESS) + sizeof(PIPE_CONTROL);
|
||||
size_t sizeNeededForPipeControl = commandStreamReceiver.getRequiredPipeControlSize();
|
||||
size_t sizeNeeded = sizeNeededForPreamble +
|
||||
@ -631,7 +631,7 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, flushTaskWithOnlyEnoughMemoryForPr
|
||||
commandStreamReceiver.lastSentL3Config = l3Config;
|
||||
|
||||
auto &csrCS = commandStreamReceiver.getCS();
|
||||
size_t sizeNeeded = getSizeRequiredPreambleCS<FamilyType>(commandStreamReceiver.hwInfo) +
|
||||
size_t sizeNeeded = getSizeRequiredPreambleCS<FamilyType>(MockDevice(commandStreamReceiver.hwInfo)) +
|
||||
sizeof(STATE_BASE_ADDRESS) +
|
||||
sizeof(PIPE_CONTROL) +
|
||||
commandStreamReceiver.getRequiredPipeControlSize() +
|
||||
@ -639,7 +639,8 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, flushTaskWithOnlyEnoughMemoryForPr
|
||||
|
||||
sizeNeeded = alignUp(sizeNeeded, MemoryConstants::cacheLineSize);
|
||||
|
||||
csrCS.getSpace(csrCS.getAvailableSpace() - commandStreamReceiver.getRequiredCsrSize());
|
||||
DispatchFlags flags;
|
||||
csrCS.getSpace(csrCS.getAvailableSpace() - commandStreamReceiver.getRequiredCmdStreamSize(flags));
|
||||
auto expectedBase = csrCS.getBase();
|
||||
|
||||
// This case handles when we have *just* enough space
|
||||
@ -1784,11 +1785,12 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, requiredCsrSizeAlignedToCacheline)
|
||||
csrSizeRequest.l3ConfigChanged = true;
|
||||
|
||||
commandStreamReceiver.overrideCsrSizeReqFlags(csrSizeRequest);
|
||||
auto l3ConfigChangedSize = commandStreamReceiver.getRequiredCsrSize();
|
||||
DispatchFlags flags;
|
||||
auto l3ConfigChangedSize = commandStreamReceiver.getRequiredCmdStreamSize(flags);
|
||||
|
||||
csrSizeRequest.l3ConfigChanged = false;
|
||||
commandStreamReceiver.overrideCsrSizeReqFlags(csrSizeRequest);
|
||||
auto l3ConfigNotChangedSize = commandStreamReceiver.getRequiredCsrSize();
|
||||
auto l3ConfigNotChangedSize = commandStreamReceiver.getRequiredCmdStreamSize(flags);
|
||||
|
||||
EXPECT_EQ(alignUp(l3ConfigChangedSize, MemoryConstants::cacheLineSize), l3ConfigChangedSize);
|
||||
EXPECT_EQ(alignUp(l3ConfigNotChangedSize, MemoryConstants::cacheLineSize), l3ConfigNotChangedSize);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -23,6 +23,7 @@
|
||||
#include "runtime/command_stream/linear_stream.h"
|
||||
#include "runtime/command_stream/command_stream_receiver.h"
|
||||
#include "runtime/command_stream/thread_arbitration_policy.h"
|
||||
#include "runtime/command_stream/preemption.h"
|
||||
#include "runtime/memory_manager/memory_manager.h"
|
||||
#include "runtime/memory_manager/graphics_allocation.h"
|
||||
#include "runtime/mem_obj/buffer.h"
|
||||
@ -30,10 +31,13 @@
|
||||
#include "unit_tests/mocks/mock_context.h"
|
||||
#include "unit_tests/fixtures/device_fixture.h"
|
||||
#include "unit_tests/fixtures/memory_management_fixture.h"
|
||||
#include "unit_tests/mocks/mock_builtins.h"
|
||||
#include "unit_tests/mocks/mock_csr.h"
|
||||
#include "test.h"
|
||||
#include "runtime/helpers/cache_policy.h"
|
||||
|
||||
#include "gmock/gmock-matchers.h"
|
||||
|
||||
using namespace OCLRT;
|
||||
|
||||
struct CommandStreamReceiverTest : public DeviceFixture,
|
||||
@ -204,3 +208,39 @@ HWTEST_F(CommandStreamReceiverTest, givenDefaultCommandStreamReceiverThenDefault
|
||||
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
|
||||
EXPECT_EQ(CommandStreamReceiver::DispatchMode::ImmediateDispatch, csr.dispatchMode);
|
||||
}
|
||||
|
||||
TEST(CommandStreamReceiver, cmdStreamReceiverReservedBlockInInstructionHeapIsBasedOnPreemptionHelper) {
|
||||
char pattern[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 39, 41};
|
||||
|
||||
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
|
||||
mockDevice->setPreemptionMode(PreemptionMode::MidThread);
|
||||
|
||||
{
|
||||
MockBuiltins mockBuiltins;
|
||||
mockBuiltins.overrideGlobalBuiltins();
|
||||
{
|
||||
auto sipOverride = std::unique_ptr<OCLRT::SipKernel>(new OCLRT::SipKernel(OCLRT::SipKernelType::Csr,
|
||||
pattern, sizeof(pattern)));
|
||||
mockBuiltins.overrideSipKernel(std::move(sipOverride));
|
||||
}
|
||||
|
||||
size_t reservedSize = mockDevice->getCommandStreamReceiver().getInstructionHeapCmdStreamReceiverReservedSize();
|
||||
size_t expectedSize = OCLRT::PreemptionHelper::getInstructionHeapSipKernelReservedSize(*mockDevice);
|
||||
EXPECT_NE(0U, expectedSize);
|
||||
EXPECT_EQ(expectedSize, reservedSize);
|
||||
ASSERT_LE(expectedSize, reservedSize);
|
||||
|
||||
StackVec<char, 4096> cmdStreamIhBuffer;
|
||||
cmdStreamIhBuffer.resize(reservedSize);
|
||||
LinearStream cmdStreamReceiverInstrucionHeap{cmdStreamIhBuffer.begin(), cmdStreamIhBuffer.size()};
|
||||
mockDevice->getCommandStreamReceiver().initializeInstructionHeapCmdStreamReceiverReservedBlock(cmdStreamReceiverInstrucionHeap);
|
||||
|
||||
StackVec<char, 4096> preemptionHelperIhBuffer;
|
||||
preemptionHelperIhBuffer.resize(expectedSize);
|
||||
LinearStream preemptionHelperInstrucionHeap{preemptionHelperIhBuffer.begin(), preemptionHelperIhBuffer.size()};
|
||||
PreemptionHelper::initializeInstructionHeapSipKernelReservedBlock(preemptionHelperInstrucionHeap, *mockDevice);
|
||||
|
||||
cmdStreamIhBuffer.resize(expectedSize);
|
||||
EXPECT_THAT(preemptionHelperIhBuffer, testing::ContainerEq(cmdStreamIhBuffer));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -71,7 +71,10 @@ BDWTEST_F(ThreadArbitrationGen8, givenPreambleWhenItIsProgrammedThenThreadArbitr
|
||||
typedef BDWFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
|
||||
LinearStream &cs = linearStream;
|
||||
uint32_t l3Config = PreambleHelper<BDWFamily>::getL3Config(**platformDevices, true);
|
||||
PreambleHelper<BDWFamily>::programPreamble(&linearStream, **platformDevices, l3Config, ThreadArbitrationPolicy::threadArbirtrationPolicyRoundRobin);
|
||||
|
||||
PreambleHelper<BDWFamily>::programPreamble(&linearStream, MockDevice(**platformDevices), l3Config,
|
||||
ThreadArbitrationPolicy::threadArbirtrationPolicyRoundRobin,
|
||||
nullptr);
|
||||
|
||||
parseCommands<BDWFamily>(cs);
|
||||
|
||||
@ -84,7 +87,7 @@ BDWTEST_F(ThreadArbitrationGen8, givenPreambleWhenItIsProgrammedThenThreadArbitr
|
||||
EXPECT_EQ(RegisterOffset, lri.getRegisterOffset());
|
||||
EXPECT_EQ(1u, lri.getDataDword() & 1);
|
||||
|
||||
EXPECT_EQ(0u, PreambleHelper<BDWFamily>::getAdditionalCommandsSize(**platformDevices));
|
||||
EXPECT_EQ(0u, PreambleHelper<BDWFamily>::getAdditionalCommandsSize(MockDevice(**platformDevices)));
|
||||
}
|
||||
|
||||
typedef PreambleFixture Gen8UrbEntryAllocationSize;
|
||||
|
@ -50,6 +50,15 @@ GEN8TEST_F(Gen8PreemptionTests, allowThreadGroupPreemptionReturnsTrue) {
|
||||
EXPECT_TRUE(PreemptionHelper::allowThreadGroupPreemption(kernel.get(), waTable));
|
||||
}
|
||||
|
||||
GEN8TEST_F(Gen8PreemptionTests, doesNotProgramPreamble) {
|
||||
size_t requiredSize = PreemptionHelper::getRequiredPreambleSize<FamilyType>(*device);
|
||||
EXPECT_EQ(0U, requiredSize);
|
||||
|
||||
LinearStream cmdStream{nullptr, 0};
|
||||
PreemptionHelper::programPreamble<FamilyType>(cmdStream, *device, nullptr);
|
||||
EXPECT_EQ(0U, cmdStream.getUsed());
|
||||
}
|
||||
|
||||
GEN8TEST_F(Gen8PreemptionEnqueueKernelTest, givenSecondEnqueueWithTheSamePreemptionRequestThenDontReprogram) {
|
||||
pDevice->setPreemptionMode(PreemptionMode::ThreadGroup);
|
||||
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -21,10 +21,11 @@
|
||||
*/
|
||||
|
||||
#include "runtime/command_stream/thread_arbitration_policy.h"
|
||||
#include "runtime/command_stream/preemption.h"
|
||||
#include "runtime/gen9/reg_configs.h"
|
||||
#include "runtime/helpers/preamble.h"
|
||||
#include "unit_tests/preamble/preamble_fixture.h"
|
||||
#include "unit_tests/gen_common/gen_cmd_parse.h"
|
||||
#include "runtime/gen9/reg_configs.h"
|
||||
|
||||
using namespace OCLRT;
|
||||
|
||||
@ -76,10 +77,11 @@ typedef PreambleFixture ThreadArbitration;
|
||||
SKLTEST_F(ThreadArbitration, givenPreambleWhenItIsProgrammedThenThreadArbitrationIsSetToRoundRobin) {
|
||||
typedef SKLFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
|
||||
typedef SKLFamily::PIPE_CONTROL PIPE_CONTROL;
|
||||
HardwareInfo hwInfo;
|
||||
LinearStream &cs = linearStream;
|
||||
uint32_t l3Config = PreambleHelper<FamilyType>::getL3Config(**platformDevices, true);
|
||||
PreambleHelper<SKLFamily>::programPreamble(&linearStream, **platformDevices, l3Config, ThreadArbitrationPolicy::threadArbirtrationPolicyRoundRobin);
|
||||
PreambleHelper<SKLFamily>::programPreamble(&linearStream, MockDevice(**platformDevices), l3Config,
|
||||
ThreadArbitrationPolicy::threadArbirtrationPolicyRoundRobin,
|
||||
nullptr);
|
||||
|
||||
parseCommands<SKLFamily>(cs);
|
||||
|
||||
@ -93,7 +95,8 @@ SKLTEST_F(ThreadArbitration, givenPreambleWhenItIsProgrammedThenThreadArbitratio
|
||||
EXPECT_EQ(0xE404u, lri.getRegisterOffset());
|
||||
EXPECT_EQ(0x100u, lri.getDataDword());
|
||||
|
||||
EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL), PreambleHelper<SKLFamily>::getAdditionalCommandsSize(hwInfo));
|
||||
EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL),
|
||||
PreambleHelper<SKLFamily>::getAdditionalCommandsSize(MockDevice(*platformDevices[0])));
|
||||
}
|
||||
|
||||
GEN9TEST_F(PreambleVfeState, WaOff) {
|
||||
|
@ -60,6 +60,50 @@ PreemptionTestHwDetails GetPreemptionTestHwDetails<SKLFamily>() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
GEN9TEST_F(Gen9PreemptionTests, whenMidThreadPreemptionIsNotAvailableThenDoesNotProgramPreamble) {
|
||||
device->setPreemptionMode(PreemptionMode::ThreadGroup);
|
||||
|
||||
size_t requiredSize = PreemptionHelper::getRequiredPreambleSize<FamilyType>(*device);
|
||||
EXPECT_EQ(0U, requiredSize);
|
||||
|
||||
LinearStream cmdStream{nullptr, 0};
|
||||
PreemptionHelper::programPreamble<FamilyType>(cmdStream, *device, nullptr);
|
||||
EXPECT_EQ(0U, cmdStream.getUsed());
|
||||
}
|
||||
|
||||
GEN9TEST_F(Gen9PreemptionTests, whenMidThreadPreemptionIsAvailableThenProgramsPreamble) {
|
||||
using GPGPU_CSR_BASE_ADDRESS = typename FamilyType::GPGPU_CSR_BASE_ADDRESS;
|
||||
using STATE_SIP = typename FamilyType::STATE_SIP;
|
||||
|
||||
device->setPreemptionMode(PreemptionMode::MidThread);
|
||||
executionEnvironment->DisableMidThreadPreemption = 0;
|
||||
|
||||
size_t minCsrSize = device->getHardwareInfo().pSysInfo->CsrSizeInMb * MemoryConstants::megaByte;
|
||||
uint64_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte;
|
||||
MockGraphicsAllocation csrSurface((void *)minCsrAlignment, minCsrSize);
|
||||
|
||||
// verify preamble programming
|
||||
size_t requiredPreambleSize = PreemptionHelper::getRequiredPreambleSize<FamilyType>(*device);
|
||||
size_t expectedPreambleSize = sizeof(GPGPU_CSR_BASE_ADDRESS) + sizeof(STATE_SIP);
|
||||
EXPECT_EQ(expectedPreambleSize, requiredPreambleSize);
|
||||
|
||||
StackVec<char, 8192> preambleStorage(requiredPreambleSize);
|
||||
ASSERT_LE(requiredPreambleSize, preambleStorage.size());
|
||||
LinearStream preambleCmdStream{preambleStorage.begin(), preambleStorage.size()};
|
||||
PreemptionHelper::programPreamble<FamilyType>(preambleCmdStream, *device, &csrSurface);
|
||||
|
||||
HardwareParse hwParsePreamble;
|
||||
hwParsePreamble.parseCommands<FamilyType>(preambleCmdStream);
|
||||
|
||||
auto csrBaseAddressCmd = hwParsePreamble.getCommand<GPGPU_CSR_BASE_ADDRESS>();
|
||||
ASSERT_NE(nullptr, csrBaseAddressCmd);
|
||||
EXPECT_EQ(csrSurface.getGpuAddressToPatch(), csrBaseAddressCmd->getGpgpuCsrBaseAddress());
|
||||
|
||||
auto stateSipCmd = hwParsePreamble.getCommand<STATE_SIP>();
|
||||
ASSERT_NE(nullptr, stateSipCmd);
|
||||
EXPECT_EQ(0U, stateSipCmd->getSystemInstructionPointer());
|
||||
}
|
||||
|
||||
GEN9TEST_F(Gen9ThreadGroupPreemptionEnqueueKernelTest, givenSecondEnqueueWithTheSamePreemptionRequestThenDontReprogramThreadGroupNoWa) {
|
||||
pDevice->setPreemptionMode(PreemptionMode::ThreadGroup);
|
||||
WhitelistedRegisters regs = {};
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2017, Intel Corporation
|
||||
# Copyright (c) 2018, Intel Corporation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
@ -24,6 +24,7 @@ set(IGDRCL_SRCS_tests_mocks
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mock_async_event_handler.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mock_block_kernel_manager.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mock_buffer.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mock_builtins.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mock_cif.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mock_cif.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mock_command_queue.h"
|
||||
|
61
unit_tests/mocks/mock_builtins.h
Normal file
61
unit_tests/mocks/mock_builtins.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "runtime/built_ins/built_ins.h"
|
||||
#include "runtime/built_ins/sip.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class MockBuiltins : public OCLRT::BuiltIns {
|
||||
public:
|
||||
MockBuiltins() {
|
||||
originalGlobalBuiltins = this;
|
||||
}
|
||||
|
||||
~MockBuiltins() override {
|
||||
if (originalGlobalBuiltins != this) {
|
||||
BuiltIns::pInstance = originalGlobalBuiltins;
|
||||
}
|
||||
}
|
||||
|
||||
void overrideGlobalBuiltins() {
|
||||
originalGlobalBuiltins = BuiltIns::pInstance;
|
||||
BuiltIns::pInstance = this;
|
||||
}
|
||||
|
||||
const OCLRT::SipKernel &getSipKernel(OCLRT::SipKernelType type, const OCLRT::Device &device) override {
|
||||
if (sipKernelsOverride.find(type) != sipKernelsOverride.end()) {
|
||||
return *sipKernelsOverride[type];
|
||||
}
|
||||
|
||||
return BuiltIns::getSipKernel(type, device);
|
||||
}
|
||||
|
||||
void overrideSipKernel(std::unique_ptr<OCLRT::SipKernel> kernel) {
|
||||
sipKernelsOverride[kernel->getType()] = std::move(kernel);
|
||||
}
|
||||
|
||||
OCLRT::BuiltIns *originalGlobalBuiltins = nullptr;
|
||||
std::map<OCLRT::SipKernelType, std::unique_ptr<OCLRT::SipKernel>> sipKernelsOverride;
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -26,6 +26,7 @@
|
||||
#include "runtime/memory_manager/graphics_allocation.h"
|
||||
#include "runtime/helpers/options.h"
|
||||
#include "runtime/helpers/flush_stamp.h"
|
||||
#include "runtime/helpers/string.h"
|
||||
#include "unit_tests/libult/ult_command_stream_receiver.h"
|
||||
#include <vector>
|
||||
|
||||
@ -198,6 +199,10 @@ class MockCommandStreamReceiver : public CommandStreamReceiver {
|
||||
public:
|
||||
using CommandStreamReceiver::latestSentTaskCount;
|
||||
using CommandStreamReceiver::tagAddress;
|
||||
std::vector<char> instructionHeapReserveredData;
|
||||
|
||||
~MockCommandStreamReceiver() {
|
||||
}
|
||||
|
||||
FlushStamp flush(BatchBuffer &batchBuffer, EngineType engineOrdinal, ResidencyContainer *allocationsForResidency) override;
|
||||
|
||||
@ -221,4 +226,23 @@ class MockCommandStreamReceiver : public CommandStreamReceiver {
|
||||
}
|
||||
|
||||
void setOSInterface(OSInterface *osInterface);
|
||||
|
||||
size_t getInstructionHeapCmdStreamReceiverReservedSize() const override {
|
||||
if (instructionHeapReserveredData.size() == 0) {
|
||||
return CommandStreamReceiver::getInstructionHeapCmdStreamReceiverReservedSize();
|
||||
}
|
||||
|
||||
return instructionHeapReserveredData.size();
|
||||
}
|
||||
|
||||
void initializeInstructionHeapCmdStreamReceiverReservedBlock(LinearStream &ih) const override {
|
||||
if (instructionHeapReserveredData.size() == 0) {
|
||||
CommandStreamReceiver::initializeInstructionHeapCmdStreamReceiverReservedBlock(ih);
|
||||
return;
|
||||
}
|
||||
|
||||
void *block = ih.getSpace(instructionHeapReserveredData.size());
|
||||
memcpy_s(block, instructionHeapReserveredData.size(),
|
||||
instructionHeapReserveredData.data(), instructionHeapReserveredData.size());
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -40,6 +40,7 @@ extern bool initialized;
|
||||
class MockDevice : public Device {
|
||||
public:
|
||||
using Device::initializeCaps;
|
||||
using Device::commandStreamReceiver;
|
||||
|
||||
void setOSTime(OSTime *osTime);
|
||||
void setDriverInfo(DriverInfo *driverInfo);
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2017, Intel Corporation
|
||||
# Copyright (c) 2018, Intel Corporation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
@ -22,4 +22,5 @@ set(IGDRCL_SRCS_tests_preamble
|
||||
"${IGDRCL_SRCS_tests_preamble}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/preamble_fixture.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/preamble_tests.cpp"
|
||||
PARENT_SCOPE)
|
||||
|
76
unit_tests/preamble/preamble_tests.cpp
Normal file
76
unit_tests/preamble/preamble_tests.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "runtime/command_stream/preemption.h"
|
||||
#include "runtime/helpers/preamble.h"
|
||||
#include "runtime/utilities/stackvec.h"
|
||||
#include "unit_tests/gen_common/test.h"
|
||||
#include "unit_tests/mocks/mock_device.h"
|
||||
#include "unit_tests/mocks/mock_graphics_allocation.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using PreambleTest = ::testing::Test;
|
||||
|
||||
using namespace OCLRT;
|
||||
|
||||
HWTEST_F(PreambleTest, PreemptionIsTakenIntoAccountWhenProgrammingPreamble) {
|
||||
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
|
||||
|
||||
mockDevice->setPreemptionMode(PreemptionMode::MidThread);
|
||||
uint32_t cmdSizePreambleMidThread = PreambleHelper<FamilyType>::getAdditionalCommandsSize(*mockDevice);
|
||||
uint32_t cmdSizePreemptionMidThread = static_cast<uint32_t>(PreemptionHelper::getRequiredPreambleSize<FamilyType>(*mockDevice));
|
||||
|
||||
mockDevice->setPreemptionMode(PreemptionMode::Disabled);
|
||||
uint32_t cmdSizePreambleDisabled = PreambleHelper<FamilyType>::getAdditionalCommandsSize(*mockDevice);
|
||||
uint32_t cmdSizePreemptionDisabled = static_cast<uint32_t>(PreemptionHelper::getRequiredPreambleSize<FamilyType>(*mockDevice));
|
||||
|
||||
EXPECT_LE(cmdSizePreemptionMidThread, cmdSizePreambleMidThread);
|
||||
EXPECT_LE(cmdSizePreemptionDisabled, cmdSizePreambleDisabled);
|
||||
|
||||
EXPECT_LE(cmdSizePreemptionDisabled, cmdSizePreemptionMidThread);
|
||||
EXPECT_LE((cmdSizePreemptionMidThread - cmdSizePreemptionDisabled), (cmdSizePreambleMidThread - cmdSizePreambleDisabled));
|
||||
|
||||
mockDevice->setPreemptionMode(PreemptionMode::MidThread);
|
||||
StackVec<char, 8192> preambleBuffer(8192);
|
||||
LinearStream preambleStream(&*preambleBuffer.begin(), preambleBuffer.size());
|
||||
|
||||
StackVec<char, 4096> preemptionBuffer;
|
||||
preemptionBuffer.resize(cmdSizePreemptionMidThread);
|
||||
LinearStream preemptionStream(&*preemptionBuffer.begin(), preemptionBuffer.size());
|
||||
|
||||
uintptr_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte;
|
||||
MockGraphicsAllocation csrSurface(reinterpret_cast<void *>(minCsrAlignment), 1024);
|
||||
|
||||
PreambleHelper<FamilyType>::programPreamble(&preambleStream, *mockDevice, 0U,
|
||||
ThreadArbitrationPolicy::threadArbirtrationPolicyRoundRobin, &csrSurface);
|
||||
|
||||
PreemptionHelper::programPreamble<FamilyType>(preemptionStream, *mockDevice, &csrSurface);
|
||||
|
||||
ASSERT_LE(preemptionStream.getUsed(), preambleStream.getUsed());
|
||||
|
||||
auto it = std::search(&preambleBuffer[0], &preambleBuffer[preambleStream.getUsed()],
|
||||
&preemptionBuffer[0], &preemptionBuffer[preemptionStream.getUsed()]);
|
||||
EXPECT_NE(&preambleBuffer[preambleStream.getUsed()], it);
|
||||
}
|
@ -25,6 +25,7 @@
|
||||
#include "unit_tests/fixtures/preemption_fixture.h"
|
||||
#include "unit_tests/helpers/debug_manager_state_restore.h"
|
||||
#include "unit_tests/helpers/hw_parse.h"
|
||||
#include "unit_tests/mocks/mock_builtins.h"
|
||||
#include "unit_tests/mocks/mock_device.h"
|
||||
#include "unit_tests/mocks/mock_graphics_allocation.h"
|
||||
#include "unit_tests/mocks/mock_kernel.h"
|
||||
@ -288,21 +289,157 @@ TEST(PreemptionTest, defaultMode) {
|
||||
EXPECT_EQ(0, DebugManager.flags.ForcePreemptionMode.get());
|
||||
}
|
||||
|
||||
TEST(PreemptionTest, whenPreemptionModeIsNotMidThreadThenInstructionHeapSipKernelReservedSizeIsEmpty) {
|
||||
char buffer[4096];
|
||||
LinearStream instructionHeap(buffer, sizeof(buffer));
|
||||
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
|
||||
|
||||
mockDevice->setPreemptionMode(PreemptionMode::Disabled);
|
||||
EXPECT_EQ(0U, PreemptionHelper::getInstructionHeapSipKernelReservedSize(*mockDevice));
|
||||
PreemptionHelper::initializeInstructionHeapSipKernelReservedBlock(instructionHeap, *mockDevice);
|
||||
ASSERT_EQ(0U, instructionHeap.getUsed());
|
||||
|
||||
mockDevice->setPreemptionMode(PreemptionMode::MidBatch);
|
||||
EXPECT_EQ(0U, PreemptionHelper::getInstructionHeapSipKernelReservedSize(*mockDevice));
|
||||
PreemptionHelper::initializeInstructionHeapSipKernelReservedBlock(instructionHeap, *mockDevice);
|
||||
ASSERT_EQ(0U, instructionHeap.getUsed());
|
||||
|
||||
mockDevice->setPreemptionMode(PreemptionMode::ThreadGroup);
|
||||
EXPECT_EQ(0U, PreemptionHelper::getInstructionHeapSipKernelReservedSize(*mockDevice));
|
||||
PreemptionHelper::initializeInstructionHeapSipKernelReservedBlock(instructionHeap, *mockDevice);
|
||||
ASSERT_EQ(0U, instructionHeap.getUsed());
|
||||
}
|
||||
|
||||
TEST(PreemptionTest, instructionHeapIsInvalidIfItSmallerThanSipKernel) {
|
||||
char instructionHeapBuffer[4096];
|
||||
LinearStream instructionHeap(instructionHeapBuffer, sizeof(instructionHeapBuffer));
|
||||
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
|
||||
mockDevice->setPreemptionMode(PreemptionMode::MidThread);
|
||||
|
||||
char sipPattern[] = {2, 3, 5, 11, 13, 17, 19, 23, 29, 31, 37, 39, 41};
|
||||
instructionHeap.getSpace(sizeof(sipPattern) - 1);
|
||||
memcpy_s(instructionHeapBuffer, sizeof(instructionHeapBuffer), sipPattern, sizeof(sipPattern));
|
||||
|
||||
{
|
||||
MockBuiltins mockBuiltins;
|
||||
mockBuiltins.overrideGlobalBuiltins();
|
||||
{
|
||||
auto sipOverride = std::unique_ptr<OCLRT::SipKernel>(new OCLRT::SipKernel(OCLRT::SipKernelType::Csr,
|
||||
sipPattern, sizeof(sipPattern)));
|
||||
mockBuiltins.overrideSipKernel(std::move(sipOverride));
|
||||
}
|
||||
|
||||
EXPECT_FALSE(PreemptionHelper::isValidInstructionHeapForMidThreadPreemption(instructionHeap, *mockDevice));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(PreemptionTest, instructionHeapIsInvalidIfItDoesNotContainSipKernelAtTheBegining) {
|
||||
char instructionHeapBuffer[4096];
|
||||
LinearStream instructionHeap(instructionHeapBuffer, sizeof(instructionHeapBuffer));
|
||||
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
|
||||
mockDevice->setPreemptionMode(PreemptionMode::MidThread);
|
||||
|
||||
char sipPattern[] = {2, 3, 5, 11, 13, 17, 19, 23, 29, 31, 37, 39, 41};
|
||||
instructionHeap.getSpace(sizeof(instructionHeapBuffer));
|
||||
memcpy_s(instructionHeapBuffer + 1, sizeof(instructionHeapBuffer) - 1, sipPattern, sizeof(sipPattern));
|
||||
|
||||
{
|
||||
MockBuiltins mockBuiltins;
|
||||
mockBuiltins.overrideGlobalBuiltins();
|
||||
{
|
||||
auto sipOverride = std::unique_ptr<OCLRT::SipKernel>(new OCLRT::SipKernel(OCLRT::SipKernelType::Csr,
|
||||
sipPattern, sizeof(sipPattern)));
|
||||
mockBuiltins.overrideSipKernel(std::move(sipOverride));
|
||||
}
|
||||
|
||||
EXPECT_FALSE(PreemptionHelper::isValidInstructionHeapForMidThreadPreemption(instructionHeap, *mockDevice));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(PreemptionTest, instructionHeapIsValidIfItContainSipKernelAtTheBegining) {
|
||||
char instructionHeapBuffer[4096];
|
||||
LinearStream instructionHeap(instructionHeapBuffer, sizeof(instructionHeapBuffer));
|
||||
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
|
||||
mockDevice->setPreemptionMode(PreemptionMode::MidThread);
|
||||
|
||||
char sipPattern[] = {2, 3, 5, 11, 13, 17, 19, 23, 29, 31, 37, 39, 41};
|
||||
instructionHeap.getSpace(sizeof(instructionHeapBuffer));
|
||||
memcpy_s(instructionHeapBuffer, sizeof(instructionHeapBuffer), sipPattern, sizeof(sipPattern));
|
||||
|
||||
{
|
||||
MockBuiltins mockBuiltins;
|
||||
mockBuiltins.overrideGlobalBuiltins();
|
||||
{
|
||||
auto sipOverride = std::unique_ptr<OCLRT::SipKernel>(new OCLRT::SipKernel(OCLRT::SipKernelType::Csr,
|
||||
sipPattern, sizeof(sipPattern)));
|
||||
mockBuiltins.overrideSipKernel(std::move(sipOverride));
|
||||
}
|
||||
|
||||
EXPECT_TRUE(PreemptionHelper::isValidInstructionHeapForMidThreadPreemption(instructionHeap, *mockDevice));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(PreemptionTest, whenPreemptionModeIsMidThreadThenInstructionHeapSipKernelReservedBlockIsProperlyInitialized) {
|
||||
char instructionHeapBuffer[4096];
|
||||
memset(instructionHeapBuffer, 7, sizeof(instructionHeapBuffer));
|
||||
LinearStream instructionHeap(instructionHeapBuffer, sizeof(instructionHeapBuffer));
|
||||
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
|
||||
mockDevice->setPreemptionMode(PreemptionMode::MidThread);
|
||||
|
||||
char sipPattern[] = {2, 3, 5, 11, 13, 17, 19, 23, 29, 31, 37, 39, 41};
|
||||
|
||||
{
|
||||
MockBuiltins mockBuiltins;
|
||||
mockBuiltins.overrideGlobalBuiltins();
|
||||
{
|
||||
auto sipOverride = std::unique_ptr<OCLRT::SipKernel>(new OCLRT::SipKernel(OCLRT::SipKernelType::Csr,
|
||||
sipPattern, sizeof(sipPattern)));
|
||||
mockBuiltins.overrideSipKernel(std::move(sipOverride));
|
||||
}
|
||||
|
||||
EXPECT_EQ(sizeof(sipPattern), PreemptionHelper::getInstructionHeapSipKernelReservedSize(*mockDevice));
|
||||
PreemptionHelper::initializeInstructionHeapSipKernelReservedBlock(instructionHeap, *mockDevice);
|
||||
EXPECT_TRUE(PreemptionHelper::isValidInstructionHeapForMidThreadPreemption(instructionHeap, *mockDevice));
|
||||
EXPECT_EQ(7, instructionHeapBuffer[sizeof(sipPattern)]); // check for overflow
|
||||
}
|
||||
}
|
||||
|
||||
struct PreemptionHwTest : ::testing::Test, ::testing::WithParamInterface<PreemptionMode> {
|
||||
};
|
||||
|
||||
HWTEST_P(PreemptionHwTest, getRequiredCmdStreamSizeReturns0WhenPreemptionModeIsNotChanging) {
|
||||
PreemptionMode mode = GetParam();
|
||||
size_t requiredSize = PreemptionHelper::getRequiredCmdStreamSize<FamilyType>(mode, mode);
|
||||
EXPECT_EQ(0U, requiredSize);
|
||||
|
||||
StackVec<char, 4096> buffer(requiredSize);
|
||||
LinearStream cmdStream(buffer.begin(), buffer.size());
|
||||
|
||||
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
|
||||
{
|
||||
MockBuiltins tmpBuiltins;
|
||||
char sipData[16] = {0};
|
||||
tmpBuiltins.overrideSipKernel(std::unique_ptr<OCLRT::SipKernel>(new OCLRT::SipKernel{SipKernelType::Csr, sipData, sizeof(sipData)}));
|
||||
tmpBuiltins.overrideGlobalBuiltins();
|
||||
PreemptionHelper::programCmdStream<FamilyType>(cmdStream, mode, mode,
|
||||
nullptr, LinearStream(nullptr, 0), *mockDevice);
|
||||
}
|
||||
EXPECT_EQ(0U, cmdStream.getUsed());
|
||||
}
|
||||
|
||||
HWTEST_P(PreemptionHwTest, getRequiredCmdStreamSizeReturnsSizeOfMiLoadRegisterImmWhenPreemptionModeIsChanging) {
|
||||
PreemptionMode mode = GetParam();
|
||||
PreemptionMode differentPreemptionMode = static_cast<PreemptionMode>(0);
|
||||
|
||||
if (false == GetPreemptionTestHwDetails<FamilyType>().supportsPreemptionProgramming()) {
|
||||
EXPECT_EQ(0U, PreemptionHelper::getRequiredCmdStreamSize<FamilyType>(mode));
|
||||
EXPECT_EQ(0U, PreemptionHelper::getRequiredCmdStreamSize<FamilyType>(mode, differentPreemptionMode));
|
||||
return;
|
||||
}
|
||||
|
||||
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
|
||||
|
||||
size_t requiredSize = PreemptionHelper::getRequiredCmdStreamSize<FamilyType>(mode);
|
||||
EXPECT_LE(sizeof(MI_LOAD_REGISTER_IMM), requiredSize);
|
||||
size_t requiredSize = PreemptionHelper::getRequiredCmdStreamSize<FamilyType>(mode, differentPreemptionMode);
|
||||
EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM), requiredSize);
|
||||
|
||||
StackVec<char, 4096> buffer(requiredSize);
|
||||
LinearStream cmdStream(buffer.begin(), buffer.size());
|
||||
@ -313,16 +450,21 @@ HWTEST_P(PreemptionHwTest, getRequiredCmdStreamSizeReturnsSizeOfMiLoadRegisterIm
|
||||
uint64_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte;
|
||||
MockGraphicsAllocation csrSurface((void *)minCsrAlignment, minCsrSize);
|
||||
|
||||
PreemptionHelper::programCmdStream<FamilyType>(&cmdStream, mode, &csrSurface, nullptr);
|
||||
PreemptionHelper::programCmdStream<FamilyType>(cmdStream, mode, differentPreemptionMode,
|
||||
nullptr, LinearStream(nullptr, 0), *mockDevice);
|
||||
EXPECT_EQ(requiredSize, cmdStream.getUsed());
|
||||
}
|
||||
|
||||
HWTEST_P(PreemptionHwTest, programCmdStreamAddsProperMiLoadRegisterImmCommandToTheStream) {
|
||||
PreemptionMode mode = GetParam();
|
||||
PreemptionMode differentPreemptionMode = static_cast<PreemptionMode>(0);
|
||||
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
|
||||
|
||||
if (false == GetPreemptionTestHwDetails<FamilyType>().supportsPreemptionProgramming()) {
|
||||
LinearStream cmdStream(nullptr, 0U);
|
||||
PreemptionHelper::programCmdStream<FamilyType>(&cmdStream, mode, nullptr, nullptr);
|
||||
LinearStream instructionHeap(nullptr, 0U);
|
||||
PreemptionHelper::programCmdStream<FamilyType>(cmdStream, mode, differentPreemptionMode, nullptr,
|
||||
instructionHeap, *mockDevice);
|
||||
EXPECT_EQ(0U, cmdStream.getUsed());
|
||||
return;
|
||||
}
|
||||
@ -337,17 +479,16 @@ HWTEST_P(PreemptionHwTest, programCmdStreamAddsProperMiLoadRegisterImmCommandToT
|
||||
expectedRegValue = hwDetails.modeToRegValueMap[mode];
|
||||
}
|
||||
|
||||
size_t requiredSize = PreemptionHelper::getRequiredCmdStreamSize<FamilyType>(mode);
|
||||
size_t requiredSize = PreemptionHelper::getRequiredCmdStreamSize<FamilyType>(mode, differentPreemptionMode);
|
||||
StackVec<char, 4096> buffer(requiredSize);
|
||||
LinearStream cmdStream(buffer.begin(), buffer.size());
|
||||
|
||||
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
|
||||
|
||||
size_t minCsrSize = mockDevice->getHardwareInfo().pSysInfo->CsrSizeInMb * MemoryConstants::megaByte;
|
||||
uint64_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte;
|
||||
MockGraphicsAllocation csrSurface((void *)minCsrAlignment, minCsrSize);
|
||||
|
||||
PreemptionHelper::programCmdStream<FamilyType>(&cmdStream, mode, &csrSurface, nullptr);
|
||||
PreemptionHelper::programCmdStream<FamilyType>(cmdStream, mode, differentPreemptionMode,
|
||||
&csrSurface, LinearStream(nullptr, 0), *mockDevice);
|
||||
|
||||
HardwareParse cmdParser;
|
||||
cmdParser.parseCommands<FamilyType>(cmdStream);
|
||||
|
Reference in New Issue
Block a user