2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2018-01-08 23:13:51 +08:00
|
|
|
* Copyright (c) 2018, Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
* 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/command_stream_receiver_hw.h"
|
2018-07-05 17:23:28 +08:00
|
|
|
#include "runtime/command_stream/experimental_command_buffer.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "runtime/command_stream/linear_stream.h"
|
|
|
|
#include "runtime/device/device.h"
|
2018-02-08 23:00:20 +08:00
|
|
|
#include "runtime/gtpin/gtpin_notify.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "runtime/helpers/cache_policy.h"
|
2018-04-04 17:34:46 +08:00
|
|
|
#include "runtime/helpers/flat_batch_buffer_helper_hw.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "runtime/helpers/preamble.h"
|
|
|
|
#include "runtime/helpers/ptr_math.h"
|
|
|
|
#include "runtime/helpers/state_base_address.h"
|
|
|
|
#include "runtime/helpers/options.h"
|
2018-08-29 19:39:27 +08:00
|
|
|
#include "runtime/indirect_heap/indirect_heap.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "runtime/memory_manager/memory_manager.h"
|
|
|
|
#include "runtime/os_interface/debug_settings_manager.h"
|
|
|
|
#include "runtime/command_stream/preemption.h"
|
2018-03-30 23:57:51 +08:00
|
|
|
#include "runtime/command_queue/gpgpu_walker.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "command_stream_receiver_hw.h"
|
|
|
|
|
|
|
|
namespace OCLRT {
|
|
|
|
|
2018-09-03 22:44:42 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
size_t CommandStreamReceiverHw<GfxFamily>::getSshHeapSize() {
|
|
|
|
return defaultHeapSize;
|
|
|
|
}
|
|
|
|
|
2018-02-20 15:11:24 +08:00
|
|
|
template <typename GfxFamily>
|
2018-08-29 19:39:27 +08:00
|
|
|
CommandStreamReceiverHw<GfxFamily>::CommandStreamReceiverHw(const HardwareInfo &hwInfoIn, ExecutionEnvironment &executionEnvironment)
|
2018-09-03 22:44:42 +08:00
|
|
|
: CommandStreamReceiver(executionEnvironment), hwInfo(hwInfoIn) {
|
2018-02-20 15:11:24 +08:00
|
|
|
requiredThreadArbitrationPolicy = PreambleHelper<GfxFamily>::getDefaultThreadArbitrationPolicy();
|
2018-04-10 16:26:59 +08:00
|
|
|
resetKmdNotifyHelper(new KmdNotifyHelper(&(hwInfoIn.capabilityTable.kmdNotifyProperties)));
|
2018-04-04 17:34:46 +08:00
|
|
|
flatBatchBufferHelper.reset(new FlatBatchBufferHelperHw<GfxFamily>(this->memoryManager));
|
2018-09-03 22:44:42 +08:00
|
|
|
defaultSshSize = getSshHeapSize();
|
2018-02-20 15:11:24 +08:00
|
|
|
}
|
|
|
|
|
2018-02-02 17:33:31 +08:00
|
|
|
template <typename GfxFamily>
|
2018-08-27 21:48:29 +08:00
|
|
|
FlushStamp CommandStreamReceiverHw<GfxFamily>::flush(BatchBuffer &batchBuffer, EngineType engineType, ResidencyContainer *allocationsForResidency, OsContext &osContext) {
|
2018-02-02 17:33:31 +08:00
|
|
|
return flushStamp->peekStamp();
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
inline void CommandStreamReceiverHw<GfxFamily>::addBatchBufferEnd(LinearStream &commandStream, void **patchLocation) {
|
|
|
|
typedef typename GfxFamily::MI_BATCH_BUFFER_END MI_BATCH_BUFFER_END;
|
|
|
|
|
|
|
|
auto pCmd = (MI_BATCH_BUFFER_END *)commandStream.getSpace(sizeof(MI_BATCH_BUFFER_END));
|
|
|
|
*pCmd = GfxFamily::cmdInitBatchBufferEnd;
|
|
|
|
if (patchLocation) {
|
|
|
|
*patchLocation = pCmd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
2018-07-05 17:23:28 +08:00
|
|
|
inline void CommandStreamReceiverHw<GfxFamily>::addBatchBufferStart(MI_BATCH_BUFFER_START *commandBufferMemory, uint64_t startAddress, bool secondary) {
|
2017-12-21 07:45:38 +08:00
|
|
|
*commandBufferMemory = GfxFamily::cmdInitBatchBufferStart;
|
|
|
|
commandBufferMemory->setBatchBufferStartAddressGraphicsaddress472(startAddress);
|
|
|
|
commandBufferMemory->setAddressSpaceIndicator(MI_BATCH_BUFFER_START::ADDRESS_SPACE_INDICATOR_PPGTT);
|
2018-07-05 17:23:28 +08:00
|
|
|
if (secondary) {
|
|
|
|
commandBufferMemory->setSecondLevelBatchBuffer(MI_BATCH_BUFFER_START::SECOND_LEVEL_BATCH_BUFFER_SECOND_LEVEL_BATCH);
|
|
|
|
}
|
2018-04-04 17:34:46 +08:00
|
|
|
if (DebugManager.flags.FlattenBatchBufferForAUBDump.get()) {
|
|
|
|
flatBatchBufferHelper->registerBatchBufferStartAddress(reinterpret_cast<uint64_t>(commandBufferMemory), startAddress);
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
inline void CommandStreamReceiverHw<GfxFamily>::alignToCacheLine(LinearStream &commandStream) {
|
|
|
|
auto used = commandStream.getUsed();
|
|
|
|
auto alignment = MemoryConstants::cacheLineSize;
|
|
|
|
auto partialCacheline = used & (alignment - 1);
|
|
|
|
if (partialCacheline) {
|
|
|
|
auto amountToPad = alignment - partialCacheline;
|
|
|
|
auto pCmd = commandStream.getSpace(amountToPad);
|
|
|
|
memset(pCmd, 0, amountToPad);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
2018-08-16 17:18:05 +08:00
|
|
|
inline size_t CommandStreamReceiverHw<GfxFamily>::getRequiredCmdSizeForPreamble(Device &device) const {
|
2018-05-15 15:46:22 +08:00
|
|
|
size_t size = 0;
|
2018-05-11 17:18:33 +08:00
|
|
|
|
2018-05-15 15:46:22 +08:00
|
|
|
if (mediaVfeStateDirty) {
|
|
|
|
size += sizeof(typename GfxFamily::PIPE_CONTROL) + sizeof(typename GfxFamily::MEDIA_VFE_STATE);
|
|
|
|
}
|
2018-05-11 17:18:33 +08:00
|
|
|
if (!this->isPreambleSent) {
|
2018-08-16 17:18:05 +08:00
|
|
|
size += PreambleHelper<GfxFamily>::getAdditionalCommandsSize(device);
|
2018-05-11 17:18:33 +08:00
|
|
|
}
|
2018-04-20 19:55:54 +08:00
|
|
|
if (!this->isPreambleSent || this->lastSentThreadArbitrationPolicy != this->requiredThreadArbitrationPolicy) {
|
|
|
|
size += PreambleHelper<GfxFamily>::getThreadArbitrationCommandsSize();
|
|
|
|
}
|
|
|
|
return size;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
inline typename GfxFamily::PIPE_CONTROL *CommandStreamReceiverHw<GfxFamily>::addPipeControlCmd(LinearStream &commandStream) {
|
|
|
|
typedef typename GfxFamily::PIPE_CONTROL PIPE_CONTROL;
|
|
|
|
auto pCmd = reinterpret_cast<PIPE_CONTROL *>(commandStream.getSpace(sizeof(PIPE_CONTROL)));
|
|
|
|
*pCmd = GfxFamily::cmdInitPipeControl;
|
|
|
|
pCmd->setCommandStreamerStallEnable(true);
|
|
|
|
return pCmd;
|
|
|
|
}
|
|
|
|
|
2018-01-18 20:57:07 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
void CommandStreamReceiverHw<GfxFamily>::programPipelineSelect(LinearStream &commandStream, DispatchFlags &dispatchFlags) {
|
|
|
|
if (csrSizeRequestFlags.mediaSamplerConfigChanged || !isPreambleSent) {
|
|
|
|
PreambleHelper<GfxFamily>::programPipelineSelect(&commandStream, dispatchFlags.mediaSamplerRequired);
|
|
|
|
this->lastMediaSamplerConfig = dispatchFlags.mediaSamplerRequired;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-13 17:05:09 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
inline size_t CommandStreamReceiverHw<GfxFamily>::getCmdSizeForPipelineSelect() const {
|
|
|
|
if (csrSizeRequestFlags.mediaSamplerConfigChanged || !isPreambleSent) {
|
|
|
|
return sizeof(typename GfxFamily::PIPELINE_SELECT);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
CompletionStamp CommandStreamReceiverHw<GfxFamily>::flushTask(
|
|
|
|
LinearStream &commandStreamTask,
|
|
|
|
size_t commandStreamStartTask,
|
2018-04-17 19:50:50 +08:00
|
|
|
const IndirectHeap &dsh,
|
|
|
|
const IndirectHeap &ioh,
|
|
|
|
const IndirectHeap &ssh,
|
2017-12-21 07:45:38 +08:00
|
|
|
uint32_t taskLevel,
|
2018-08-01 16:01:41 +08:00
|
|
|
DispatchFlags &dispatchFlags,
|
|
|
|
Device &device) {
|
2017-12-21 07:45:38 +08:00
|
|
|
typedef typename GfxFamily::MI_BATCH_BUFFER_START MI_BATCH_BUFFER_START;
|
|
|
|
typedef typename GfxFamily::MI_BATCH_BUFFER_END MI_BATCH_BUFFER_END;
|
|
|
|
typedef typename GfxFamily::PIPE_CONTROL PIPE_CONTROL;
|
|
|
|
typedef typename GfxFamily::STATE_BASE_ADDRESS STATE_BASE_ADDRESS;
|
|
|
|
|
|
|
|
DEBUG_BREAK_IF(&commandStreamTask == &commandStream);
|
2018-08-01 16:01:41 +08:00
|
|
|
DEBUG_BREAK_IF(!(dispatchFlags.preemptionMode == PreemptionMode::Disabled ? device.getPreemptionMode() == PreemptionMode::Disabled : true));
|
2017-12-21 07:45:38 +08:00
|
|
|
DEBUG_BREAK_IF(taskLevel >= Event::eventNotReady);
|
|
|
|
|
|
|
|
DBG_LOG(LogTaskCounts, __FUNCTION__, "Line: ", __LINE__, "taskLevel", taskLevel);
|
|
|
|
|
|
|
|
auto levelClosed = false;
|
|
|
|
void *currentPipeControlForNooping = nullptr;
|
2018-02-15 15:29:57 +08:00
|
|
|
void *epiloguePipeControlLocation = nullptr;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-06-13 02:33:03 +08:00
|
|
|
if (DebugManager.flags.ForceCsrFlushing.get()) {
|
|
|
|
flushBatchedSubmissions();
|
|
|
|
}
|
|
|
|
if (DebugManager.flags.ForceCsrReprogramming.get()) {
|
|
|
|
initProgrammingFlags();
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
if (dispatchFlags.blocking || dispatchFlags.dcFlush || dispatchFlags.guardCommandBufferWithPipeControl) {
|
2018-04-04 17:34:46 +08:00
|
|
|
if (this->dispatchMode == DispatchMode::ImmediateDispatch) {
|
2017-12-21 07:45:38 +08:00
|
|
|
//for ImmediateDispatch we will send this right away, therefore this pipe control will close the level
|
|
|
|
//for BatchedSubmissions it will be nooped and only last ppc in batch will be emitted.
|
|
|
|
levelClosed = true;
|
2018-02-13 17:01:20 +08:00
|
|
|
//if we guard with ppc, flush dc as well to speed up completion latency
|
|
|
|
if (dispatchFlags.guardCommandBufferWithPipeControl) {
|
|
|
|
dispatchFlags.dcFlush = true;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-03-05 18:03:38 +08:00
|
|
|
epiloguePipeControlLocation = ptrOffset(commandStreamTask.getCpuBase(), commandStreamTask.getUsed());
|
2018-02-15 15:29:57 +08:00
|
|
|
|
2018-09-06 15:03:07 +08:00
|
|
|
if ((dispatchFlags.outOfOrderExecutionAllowed || timestampPacketWriteEnabled) &&
|
2018-08-30 17:05:18 +08:00
|
|
|
!dispatchFlags.dcFlush) {
|
2018-02-15 15:29:57 +08:00
|
|
|
currentPipeControlForNooping = epiloguePipeControlLocation;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//Some architectures (SKL) requires to have pipe control prior to pipe control with tag write, add it here
|
|
|
|
addPipeControlWA(commandStreamTask, dispatchFlags.dcFlush);
|
|
|
|
|
|
|
|
auto pCmd = addPipeControlCmd(commandStreamTask);
|
|
|
|
pCmd->setPostSyncOperation(PIPE_CONTROL::POST_SYNC_OPERATION_WRITE_IMMEDIATE_DATA);
|
|
|
|
|
|
|
|
//Some architectures (BDW) requires to have at least one flush bit set
|
|
|
|
addDcFlushToPipeControl(pCmd, dispatchFlags.dcFlush);
|
|
|
|
|
|
|
|
if (DebugManager.flags.FlushAllCaches.get()) {
|
|
|
|
pCmd->setDcFlushEnable(true);
|
|
|
|
pCmd->setRenderTargetCacheFlushEnable(true);
|
|
|
|
pCmd->setInstructionCacheInvalidateEnable(true);
|
|
|
|
pCmd->setTextureCacheInvalidationEnable(true);
|
|
|
|
pCmd->setPipeControlFlushEnable(true);
|
|
|
|
pCmd->setVfCacheInvalidationEnable(true);
|
|
|
|
pCmd->setConstantCacheInvalidationEnable(true);
|
|
|
|
pCmd->setStateCacheInvalidationEnable(true);
|
|
|
|
}
|
|
|
|
|
2018-08-24 21:23:45 +08:00
|
|
|
auto address = getTagAllocation()->getGpuAddress();
|
2017-12-21 07:45:38 +08:00
|
|
|
pCmd->setAddressHigh(address >> 32);
|
|
|
|
pCmd->setAddress(address & (0xffffffff));
|
|
|
|
pCmd->setImmediateData(taskCount + 1);
|
|
|
|
|
|
|
|
this->latestSentTaskCount = taskCount + 1;
|
|
|
|
DBG_LOG(LogTaskCounts, __FUNCTION__, "Line: ", __LINE__, "taskCount", taskCount);
|
2018-04-04 17:34:46 +08:00
|
|
|
if (DebugManager.flags.AddPatchInfoCommentsForAUBDump.get()) {
|
|
|
|
flatBatchBufferHelper->setPatchInfoData(PatchInfoData(address, 0u,
|
|
|
|
PatchInfoAllocationType::TagAddress,
|
|
|
|
commandStreamTask.getGraphicsAllocation()->getGpuAddress(),
|
|
|
|
commandStreamTask.getUsed() - 2 * sizeof(uint64_t),
|
|
|
|
PatchInfoAllocationType::Default));
|
|
|
|
flatBatchBufferHelper->setPatchInfoData(PatchInfoData(address, 0u,
|
|
|
|
PatchInfoAllocationType::TagValue,
|
|
|
|
commandStreamTask.getGraphicsAllocation()->getGpuAddress(),
|
|
|
|
commandStreamTask.getUsed() - sizeof(uint64_t),
|
|
|
|
PatchInfoAllocationType::Default));
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (DebugManager.flags.ForceSLML3Config.get()) {
|
|
|
|
dispatchFlags.useSLM = true;
|
|
|
|
}
|
2018-02-20 15:11:24 +08:00
|
|
|
if (DebugManager.flags.OverrideThreadArbitrationPolicy.get() != -1) {
|
|
|
|
requestThreadArbitrationPolicy(static_cast<uint32_t>(DebugManager.flags.OverrideThreadArbitrationPolicy.get()));
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-02-15 03:14:20 +08:00
|
|
|
auto newL3Config = PreambleHelper<GfxFamily>::getL3Config(peekHwInfo(), dispatchFlags.useSLM);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
csrSizeRequestFlags.l3ConfigChanged = this->lastSentL3Config != newL3Config;
|
|
|
|
csrSizeRequestFlags.coherencyRequestChanged = this->lastSentCoherencyRequest != static_cast<int8_t>(dispatchFlags.requiresCoherency);
|
|
|
|
csrSizeRequestFlags.preemptionRequestChanged = this->lastPreemptionMode != dispatchFlags.preemptionMode;
|
2018-01-17 15:37:47 +08:00
|
|
|
csrSizeRequestFlags.mediaSamplerConfigChanged = this->lastMediaSamplerConfig != static_cast<int8_t>(dispatchFlags.mediaSamplerRequired);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-08-01 16:01:41 +08:00
|
|
|
size_t requiredScratchSizeInBytes = requiredScratchSize * device.getDeviceInfo().computeUnitsUsedForScratch;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
auto force32BitAllocations = getMemoryManager()->peekForce32BitAllocations();
|
|
|
|
|
|
|
|
bool stateBaseAddressDirty = false;
|
|
|
|
|
|
|
|
if (requiredScratchSize && (!scratchAllocation || scratchAllocation->getUnderlyingBufferSize() < requiredScratchSizeInBytes)) {
|
|
|
|
if (scratchAllocation) {
|
|
|
|
scratchAllocation->taskCount = this->taskCount;
|
|
|
|
getMemoryManager()->storeAllocation(std::unique_ptr<GraphicsAllocation>(scratchAllocation), TEMPORARY_ALLOCATION);
|
|
|
|
}
|
2018-07-25 00:36:26 +08:00
|
|
|
scratchAllocation = getMemoryManager()->allocateGraphicsMemoryInPreferredPool(true, nullptr, requiredScratchSizeInBytes, GraphicsAllocation::AllocationType::SCRATCH_SURFACE);
|
2017-12-21 07:45:38 +08:00
|
|
|
overrideMediaVFEStateDirty(true);
|
|
|
|
if (is64bit && !force32BitAllocations) {
|
|
|
|
stateBaseAddressDirty = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-07 15:07:50 +08:00
|
|
|
auto &commandStreamCSR = this->getCS(getRequiredCmdStreamSizeAligned(dispatchFlags, device));
|
2018-05-15 15:46:22 +08:00
|
|
|
auto commandStreamStartCSR = commandStreamCSR.getUsed();
|
|
|
|
|
2018-09-07 20:31:37 +08:00
|
|
|
if (dispatchFlags.outOfDeviceDependencies) {
|
|
|
|
programOutOfDeviceWaitlistSemaphores(commandStreamCSR, dispatchFlags, device);
|
|
|
|
}
|
2018-05-15 15:46:22 +08:00
|
|
|
initPageTableManagerRegisters(commandStreamCSR);
|
2018-08-16 17:18:05 +08:00
|
|
|
programPreemption(commandStreamCSR, device, dispatchFlags);
|
2018-05-15 15:46:22 +08:00
|
|
|
programCoherency(commandStreamCSR, dispatchFlags);
|
|
|
|
programL3(commandStreamCSR, dispatchFlags, newL3Config);
|
|
|
|
programPipelineSelect(commandStreamCSR, dispatchFlags);
|
2018-08-16 17:18:05 +08:00
|
|
|
programPreamble(commandStreamCSR, device, dispatchFlags, newL3Config);
|
2018-05-15 15:46:22 +08:00
|
|
|
programMediaSampler(commandStreamCSR, dispatchFlags);
|
|
|
|
|
2018-02-20 15:11:24 +08:00
|
|
|
if (this->lastSentThreadArbitrationPolicy != this->requiredThreadArbitrationPolicy) {
|
2017-12-21 07:45:38 +08:00
|
|
|
PreambleHelper<GfxFamily>::programThreadArbitration(&commandStreamCSR, this->requiredThreadArbitrationPolicy);
|
2018-02-20 15:11:24 +08:00
|
|
|
this->lastSentThreadArbitrationPolicy = this->requiredThreadArbitrationPolicy;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
stateBaseAddressDirty |= ((GSBAFor32BitProgrammed ^ dispatchFlags.GSBA32BitRequired) && force32BitAllocations);
|
|
|
|
|
|
|
|
programVFEState(commandStreamCSR, dispatchFlags);
|
|
|
|
|
|
|
|
bool dshDirty = dshState.updateAndCheck(&dsh);
|
|
|
|
bool iohDirty = iohState.updateAndCheck(&ioh);
|
|
|
|
bool sshDirty = sshState.updateAndCheck(&ssh);
|
|
|
|
|
2018-03-27 18:55:20 +08:00
|
|
|
auto isStateBaseAddressDirty = dshDirty || iohDirty || sshDirty || stateBaseAddressDirty;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
auto requiredL3Index = CacheSettings::l3CacheOn;
|
|
|
|
if (this->disableL3Cache) {
|
|
|
|
requiredL3Index = CacheSettings::l3CacheOff;
|
|
|
|
this->disableL3Cache = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (requiredL3Index != latestSentStatelessMocsConfig) {
|
|
|
|
isStateBaseAddressDirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Reprogram state base address if required
|
|
|
|
if (isStateBaseAddressDirty) {
|
|
|
|
auto pCmd = addPipeControlCmd(commandStreamCSR);
|
|
|
|
pCmd->setTextureCacheInvalidationEnable(true);
|
|
|
|
pCmd->setDcFlushEnable(true);
|
|
|
|
|
|
|
|
uint64_t newGSHbase = 0;
|
|
|
|
GSBAFor32BitProgrammed = false;
|
|
|
|
if (is64bit && scratchAllocation && !force32BitAllocations) {
|
|
|
|
newGSHbase = (uint64_t)scratchAllocation->getUnderlyingBuffer() - PreambleHelper<GfxFamily>::getScratchSpaceOffsetFor64bit();
|
|
|
|
} else if (is64bit && force32BitAllocations && dispatchFlags.GSBA32BitRequired) {
|
|
|
|
newGSHbase = memoryManager->allocator32Bit->getBase();
|
|
|
|
GSBAFor32BitProgrammed = true;
|
|
|
|
}
|
|
|
|
|
2018-03-14 18:07:51 +08:00
|
|
|
auto stateBaseAddressCmdOffset = commandStreamCSR.getUsed();
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
StateBaseAddressHelper<GfxFamily>::programStateBaseAddress(
|
|
|
|
commandStreamCSR,
|
|
|
|
dsh,
|
|
|
|
ioh,
|
|
|
|
ssh,
|
|
|
|
newGSHbase,
|
2018-03-27 18:55:20 +08:00
|
|
|
requiredL3Index,
|
2018-07-23 18:23:48 +08:00
|
|
|
memoryManager->getInternalHeapBaseAddress(),
|
2018-08-01 16:01:41 +08:00
|
|
|
device.getGmmHelper());
|
2018-03-14 18:07:51 +08:00
|
|
|
|
2018-08-29 19:39:27 +08:00
|
|
|
if (sshDirty) {
|
|
|
|
StateBaseAddressHelper<GfxFamily>::programBindingTableBaseAddress(commandStreamCSR, ssh, stateBaseAddressCmdOffset,
|
|
|
|
device.getGmmHelper());
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
latestSentStatelessMocsConfig = requiredL3Index;
|
2018-03-14 18:07:51 +08:00
|
|
|
|
|
|
|
if (DebugManager.flags.AddPatchInfoCommentsForAUBDump.get()) {
|
2018-04-04 17:34:46 +08:00
|
|
|
collectStateBaseAddresPatchInfo(commandStream.getGraphicsAllocation()->getGpuAddress(), stateBaseAddressCmdOffset, dsh, ioh, ssh, newGSHbase);
|
2018-03-14 18:07:51 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
DBG_LOG(LogTaskCounts, __FUNCTION__, "Line: ", __LINE__, "this->taskLevel", (uint32_t)this->taskLevel);
|
|
|
|
|
2018-08-01 16:01:41 +08:00
|
|
|
if (device.getWaTable()->waSamplerCacheFlushBetweenRedescribedSurfaceReads) {
|
2018-01-10 21:05:34 +08:00
|
|
|
if (this->samplerCacheFlushRequired != SamplerCacheFlushState::samplerCacheFlushNotRequired) {
|
|
|
|
auto pCmd = addPipeControlCmd(commandStreamCSR);
|
|
|
|
pCmd->setTextureCacheInvalidationEnable(true);
|
|
|
|
if (this->samplerCacheFlushRequired == SamplerCacheFlushState::samplerCacheFlushBefore) {
|
|
|
|
this->samplerCacheFlushRequired = SamplerCacheFlushState::samplerCacheFlushAfter;
|
|
|
|
} else {
|
|
|
|
this->samplerCacheFlushRequired = SamplerCacheFlushState::samplerCacheFlushNotRequired;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-07-05 17:23:28 +08:00
|
|
|
|
|
|
|
if (experimentalCmdBuffer.get() != nullptr) {
|
|
|
|
size_t startingOffset = experimentalCmdBuffer->programExperimentalCommandBuffer<GfxFamily>();
|
|
|
|
experimentalCmdBuffer->injectBufferStart<GfxFamily>(commandStreamCSR, startingOffset);
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
// Add a PC if we have a dependency on a previous walker to avoid concurrency issues.
|
|
|
|
if (taskLevel > this->taskLevel) {
|
2018-09-06 15:03:07 +08:00
|
|
|
if (!timestampPacketWriteEnabled) {
|
2018-08-30 17:05:18 +08:00
|
|
|
addPipeControl(commandStreamCSR, false);
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
this->taskLevel = taskLevel;
|
|
|
|
DBG_LOG(LogTaskCounts, __FUNCTION__, "Line: ", __LINE__, "this->taskCount", this->taskCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto dshAllocation = dsh.getGraphicsAllocation();
|
|
|
|
auto iohAllocation = ioh.getGraphicsAllocation();
|
|
|
|
auto sshAllocation = ssh.getGraphicsAllocation();
|
|
|
|
|
|
|
|
this->makeResident(*dshAllocation);
|
2018-04-12 16:05:35 +08:00
|
|
|
dshAllocation->setEvictable(false);
|
2017-12-21 07:45:38 +08:00
|
|
|
this->makeResident(*iohAllocation);
|
|
|
|
this->makeResident(*sshAllocation);
|
2018-04-12 16:05:35 +08:00
|
|
|
iohAllocation->setEvictable(false);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
this->makeResident(*tagAllocation);
|
|
|
|
|
|
|
|
if (requiredScratchSize)
|
|
|
|
makeResident(*scratchAllocation);
|
|
|
|
|
|
|
|
if (preemptionCsrAllocation)
|
|
|
|
makeResident(*preemptionCsrAllocation);
|
|
|
|
|
2018-08-01 16:01:41 +08:00
|
|
|
if (dispatchFlags.preemptionMode == PreemptionMode::MidThread || device.isSourceLevelDebuggerActive()) {
|
|
|
|
auto sipType = SipKernel::getSipKernelType(device.getHardwareInfo().pPlatform->eRenderCoreFamily, device.isSourceLevelDebuggerActive());
|
2018-08-22 19:57:21 +08:00
|
|
|
makeResident(*device.getExecutionEnvironment()->getBuiltIns()->getSipKernel(sipType, device).getSipAllocation());
|
2018-03-13 00:18:00 +08:00
|
|
|
}
|
|
|
|
|
2018-07-05 17:23:28 +08:00
|
|
|
if (experimentalCmdBuffer.get() != nullptr) {
|
|
|
|
experimentalCmdBuffer->makeResidentAllocations();
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
// If the CSR has work in its CS, flush it before the task
|
|
|
|
bool submitTask = commandStreamStartTask != commandStreamTask.getUsed();
|
|
|
|
bool submitCSR = commandStreamStartCSR != commandStreamCSR.getUsed();
|
|
|
|
bool submitCommandStreamFromCsr = false;
|
|
|
|
void *bbEndLocation = nullptr;
|
|
|
|
auto bbEndPaddingSize = this->dispatchMode == DispatchMode::ImmediateDispatch ? 0 : sizeof(MI_BATCH_BUFFER_START) - sizeof(MI_BATCH_BUFFER_END);
|
2018-03-01 05:50:41 +08:00
|
|
|
size_t chainedBatchBufferStartOffset = 0;
|
|
|
|
GraphicsAllocation *chainedBatchBuffer = nullptr;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
if (submitTask) {
|
|
|
|
this->addBatchBufferEnd(commandStreamTask, &bbEndLocation);
|
|
|
|
this->emitNoop(commandStreamTask, bbEndPaddingSize);
|
|
|
|
this->alignToCacheLine(commandStreamTask);
|
|
|
|
|
|
|
|
if (submitCSR) {
|
2018-03-01 05:50:41 +08:00
|
|
|
chainedBatchBufferStartOffset = commandStreamCSR.getUsed();
|
|
|
|
chainedBatchBuffer = commandStreamTask.getGraphicsAllocation();
|
2017-12-21 07:45:38 +08:00
|
|
|
// Add MI_BATCH_BUFFER_START to chain from CSR -> Task
|
|
|
|
auto pBBS = reinterpret_cast<MI_BATCH_BUFFER_START *>(commandStreamCSR.getSpace(sizeof(MI_BATCH_BUFFER_START)));
|
2018-07-05 17:23:28 +08:00
|
|
|
addBatchBufferStart(pBBS, ptrOffset(commandStreamTask.getGraphicsAllocation()->getGpuAddress(), commandStreamStartTask), false);
|
2018-04-04 17:34:46 +08:00
|
|
|
if (DebugManager.flags.FlattenBatchBufferForAUBDump.get()) {
|
|
|
|
flatBatchBufferHelper->registerCommandChunk(commandStreamTask.getGraphicsAllocation()->getGpuAddress(),
|
|
|
|
reinterpret_cast<uint64_t>(commandStreamTask.getCpuBase()),
|
|
|
|
commandStreamStartTask,
|
|
|
|
static_cast<uint64_t>(ptrDiff(bbEndLocation,
|
|
|
|
commandStreamTask.getGraphicsAllocation()->getGpuAddress())) +
|
|
|
|
sizeof(MI_BATCH_BUFFER_START));
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
auto commandStreamAllocation = commandStreamTask.getGraphicsAllocation();
|
|
|
|
DEBUG_BREAK_IF(commandStreamAllocation == nullptr);
|
|
|
|
|
|
|
|
this->makeResident(*commandStreamAllocation);
|
|
|
|
this->alignToCacheLine(commandStreamCSR);
|
|
|
|
submitCommandStreamFromCsr = true;
|
|
|
|
}
|
|
|
|
} else if (submitCSR) {
|
|
|
|
this->addBatchBufferEnd(commandStreamCSR, &bbEndLocation);
|
|
|
|
this->emitNoop(commandStreamCSR, bbEndPaddingSize);
|
|
|
|
this->alignToCacheLine(commandStreamCSR);
|
|
|
|
DEBUG_BREAK_IF(commandStreamCSR.getUsed() > commandStreamCSR.getMaxAvailableSpace());
|
|
|
|
submitCommandStreamFromCsr = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t startOffset = submitCommandStreamFromCsr ? commandStreamStartCSR : commandStreamStartTask;
|
|
|
|
auto &streamToSubmit = submitCommandStreamFromCsr ? commandStreamCSR : commandStreamTask;
|
2018-03-01 05:50:41 +08:00
|
|
|
BatchBuffer batchBuffer{streamToSubmit.getGraphicsAllocation(), startOffset, chainedBatchBufferStartOffset, chainedBatchBuffer, dispatchFlags.requiresCoherency, dispatchFlags.lowPriority, dispatchFlags.throttle, streamToSubmit.getUsed(), &streamToSubmit};
|
2018-08-01 16:01:41 +08:00
|
|
|
EngineType engineType = device.getEngineType();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
if (submitCSR | submitTask) {
|
|
|
|
if (this->dispatchMode == DispatchMode::ImmediateDispatch) {
|
2018-09-11 17:19:21 +08:00
|
|
|
flushStamp->setStamp(this->flush(batchBuffer, engineType, &this->getResidencyAllocations(), *device.getOsContext()));
|
2017-12-21 07:45:38 +08:00
|
|
|
this->latestFlushedTaskCount = this->taskCount + 1;
|
2018-08-02 21:17:58 +08:00
|
|
|
this->makeSurfacePackNonResident(nullptr);
|
2017-12-21 07:45:38 +08:00
|
|
|
} else {
|
2018-08-16 17:18:05 +08:00
|
|
|
auto commandBuffer = new CommandBuffer(device);
|
2017-12-21 07:45:38 +08:00
|
|
|
commandBuffer->batchBuffer = batchBuffer;
|
|
|
|
commandBuffer->surfaces.swap(getMemoryManager()->getResidencyAllocations());
|
|
|
|
commandBuffer->batchBufferEndLocation = bbEndLocation;
|
|
|
|
commandBuffer->taskCount = this->taskCount + 1;
|
|
|
|
commandBuffer->flushStamp->replaceStampObject(dispatchFlags.flushStampReference);
|
2018-02-15 15:29:57 +08:00
|
|
|
commandBuffer->pipeControlThatMayBeErasedLocation = currentPipeControlForNooping;
|
|
|
|
commandBuffer->epiloguePipeControlLocation = epiloguePipeControlLocation;
|
2017-12-21 07:45:38 +08:00
|
|
|
this->submissionAggregator->recordCommandBuffer(commandBuffer);
|
|
|
|
}
|
|
|
|
} else {
|
2018-08-02 21:17:58 +08:00
|
|
|
this->makeSurfacePackNonResident(nullptr);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//check if we are not over the budget, if we are do implicit flush
|
|
|
|
if (getMemoryManager()->isMemoryBudgetExhausted()) {
|
2018-08-01 16:01:41 +08:00
|
|
|
if (this->totalMemoryUsed >= device.getDeviceInfo().globalMemSize / 4) {
|
2017-12-21 07:45:38 +08:00
|
|
|
dispatchFlags.implicitFlush = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->dispatchMode == DispatchMode::BatchedDispatch && (dispatchFlags.blocking || dispatchFlags.implicitFlush)) {
|
|
|
|
this->flushBatchedSubmissions();
|
|
|
|
}
|
|
|
|
|
|
|
|
++taskCount;
|
|
|
|
DBG_LOG(LogTaskCounts, __FUNCTION__, "Line: ", __LINE__, "taskCount", taskCount);
|
|
|
|
DBG_LOG(LogTaskCounts, __FUNCTION__, "Line: ", __LINE__, "Current taskCount:", tagAddress ? *tagAddress : 0);
|
|
|
|
|
|
|
|
CompletionStamp completionStamp = {
|
|
|
|
taskCount,
|
|
|
|
this->taskLevel,
|
|
|
|
flushStamp->peekStamp(),
|
|
|
|
0,
|
2017-11-14 18:15:09 +08:00
|
|
|
engineType};
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
this->taskLevel += levelClosed ? 1 : 0;
|
2018-02-08 23:00:20 +08:00
|
|
|
|
2018-03-23 01:46:09 +08:00
|
|
|
if (gtpinIsGTPinInitialized()) {
|
|
|
|
gtpinNotifyFlushTask(completionStamp.taskCount);
|
|
|
|
}
|
2018-02-08 23:00:20 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
return completionStamp;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
inline void CommandStreamReceiverHw<GfxFamily>::flushBatchedSubmissions() {
|
2018-04-04 17:34:46 +08:00
|
|
|
if (this->dispatchMode == DispatchMode::ImmediateDispatch) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
typedef typename GfxFamily::MI_BATCH_BUFFER_START MI_BATCH_BUFFER_START;
|
2018-02-13 17:01:20 +08:00
|
|
|
typedef typename GfxFamily::PIPE_CONTROL PIPE_CONTROL;
|
2018-08-06 20:55:04 +08:00
|
|
|
std::unique_lock<MutexType> lockGuard(ownershipMutex);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
auto &commandBufferList = this->submissionAggregator->peekCmdBufferList();
|
|
|
|
if (!commandBufferList.peekIsEmpty()) {
|
2018-08-16 17:18:05 +08:00
|
|
|
auto &device = commandBufferList.peekHead()->device;
|
|
|
|
EngineType engineType = device.getEngineType();
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
ResidencyContainer surfacesForSubmit;
|
|
|
|
ResourcePackage resourcePackage;
|
|
|
|
auto pipeControlLocationSize = getRequiredPipeControlSize();
|
2018-02-15 15:29:57 +08:00
|
|
|
void *currentPipeControlForNooping = nullptr;
|
|
|
|
void *epiloguePipeControlLocation = nullptr;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
while (!commandBufferList.peekIsEmpty()) {
|
|
|
|
size_t totalUsedSize = 0u;
|
2018-08-16 17:18:05 +08:00
|
|
|
this->submissionAggregator->aggregateCommandBuffers(resourcePackage, totalUsedSize, (size_t)device.getDeviceInfo().globalMemSize * 5 / 10);
|
2017-12-21 07:45:38 +08:00
|
|
|
auto primaryCmdBuffer = commandBufferList.removeFrontOne();
|
|
|
|
auto nextCommandBuffer = commandBufferList.peekHead();
|
|
|
|
auto currentBBendLocation = primaryCmdBuffer->batchBufferEndLocation;
|
|
|
|
auto lastTaskCount = primaryCmdBuffer->taskCount;
|
|
|
|
|
|
|
|
FlushStampUpdateHelper flushStampUpdateHelper;
|
|
|
|
flushStampUpdateHelper.insert(primaryCmdBuffer->flushStamp->getStampReference());
|
|
|
|
|
2018-02-15 15:29:57 +08:00
|
|
|
currentPipeControlForNooping = primaryCmdBuffer->pipeControlThatMayBeErasedLocation;
|
|
|
|
epiloguePipeControlLocation = primaryCmdBuffer->epiloguePipeControlLocation;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-04-04 17:34:46 +08:00
|
|
|
if (DebugManager.flags.FlattenBatchBufferForAUBDump.get()) {
|
|
|
|
flatBatchBufferHelper->registerCommandChunk(primaryCmdBuffer.get()->batchBuffer, sizeof(MI_BATCH_BUFFER_START));
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
while (nextCommandBuffer && nextCommandBuffer->inspectionId == primaryCmdBuffer->inspectionId) {
|
|
|
|
//noop pipe control
|
2018-02-15 15:29:57 +08:00
|
|
|
if (currentPipeControlForNooping) {
|
2018-04-04 17:34:46 +08:00
|
|
|
if (DebugManager.flags.AddPatchInfoCommentsForAUBDump.get()) {
|
|
|
|
flatBatchBufferHelper->removePipeControlData(pipeControlLocationSize, currentPipeControlForNooping);
|
|
|
|
}
|
2018-02-15 15:29:57 +08:00
|
|
|
memset(currentPipeControlForNooping, 0, pipeControlLocationSize);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
//obtain next candidate for nooping
|
2018-02-15 15:29:57 +08:00
|
|
|
currentPipeControlForNooping = nextCommandBuffer->pipeControlThatMayBeErasedLocation;
|
|
|
|
//track epilogue pipe control
|
|
|
|
epiloguePipeControlLocation = nextCommandBuffer->epiloguePipeControlLocation;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
flushStampUpdateHelper.insert(nextCommandBuffer->flushStamp->getStampReference());
|
2018-08-24 21:23:45 +08:00
|
|
|
auto nextCommandBufferAddress = nextCommandBuffer->batchBuffer.commandBufferAllocation->getGpuAddress();
|
2017-12-21 07:45:38 +08:00
|
|
|
auto offsetedCommandBuffer = (uint64_t)ptrOffset(nextCommandBufferAddress, nextCommandBuffer->batchBuffer.startOffset);
|
2018-07-05 17:23:28 +08:00
|
|
|
addBatchBufferStart((MI_BATCH_BUFFER_START *)currentBBendLocation, offsetedCommandBuffer, false);
|
2018-04-04 17:34:46 +08:00
|
|
|
if (DebugManager.flags.FlattenBatchBufferForAUBDump.get()) {
|
|
|
|
flatBatchBufferHelper->registerCommandChunk(nextCommandBuffer->batchBuffer, sizeof(MI_BATCH_BUFFER_START));
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
currentBBendLocation = nextCommandBuffer->batchBufferEndLocation;
|
|
|
|
lastTaskCount = nextCommandBuffer->taskCount;
|
|
|
|
nextCommandBuffer = nextCommandBuffer->next;
|
|
|
|
commandBufferList.removeFrontOne();
|
|
|
|
}
|
|
|
|
surfacesForSubmit.reserve(resourcePackage.size() + 1);
|
|
|
|
for (auto &surface : resourcePackage) {
|
|
|
|
surfacesForSubmit.push_back(surface);
|
|
|
|
}
|
|
|
|
|
2018-02-13 17:01:20 +08:00
|
|
|
//make sure we flush DC
|
2018-03-09 21:48:42 +08:00
|
|
|
if (epiloguePipeControlLocation) {
|
|
|
|
((PIPE_CONTROL *)epiloguePipeControlLocation)->setDcFlushEnable(true);
|
|
|
|
}
|
2018-08-27 21:48:29 +08:00
|
|
|
auto flushStamp = this->flush(primaryCmdBuffer->batchBuffer, engineType, &surfacesForSubmit, *device.getOsContext());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
//after flush task level is closed
|
|
|
|
this->taskLevel++;
|
|
|
|
|
|
|
|
flushStampUpdateHelper.updateAll(flushStamp);
|
|
|
|
|
|
|
|
this->latestFlushedTaskCount = lastTaskCount;
|
|
|
|
this->flushStamp->setStamp(flushStamp);
|
2018-08-02 21:17:58 +08:00
|
|
|
this->makeSurfacePackNonResident(&surfacesForSubmit);
|
2017-12-21 07:45:38 +08:00
|
|
|
resourcePackage.clear();
|
|
|
|
}
|
|
|
|
this->totalMemoryUsed = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
void CommandStreamReceiverHw<GfxFamily>::addPipeControl(LinearStream &commandStream, bool dcFlush) {
|
|
|
|
typedef typename GfxFamily::PIPE_CONTROL PIPE_CONTROL;
|
|
|
|
|
|
|
|
addPipeControlWA(commandStream, dcFlush);
|
|
|
|
|
|
|
|
// Add a PIPE_CONTROL w/ CS_stall
|
|
|
|
auto pCmd = reinterpret_cast<PIPE_CONTROL *>(commandStream.getSpace(sizeof(PIPE_CONTROL)));
|
|
|
|
*pCmd = GfxFamily::cmdInitPipeControl;
|
|
|
|
pCmd->setCommandStreamerStallEnable(true);
|
|
|
|
//Some architectures (BDW) requires to have at least one flush bit set
|
|
|
|
addDcFlushToPipeControl(pCmd, true);
|
|
|
|
|
|
|
|
if (DebugManager.flags.FlushAllCaches.get()) {
|
|
|
|
pCmd->setDcFlushEnable(true);
|
|
|
|
pCmd->setRenderTargetCacheFlushEnable(true);
|
|
|
|
pCmd->setInstructionCacheInvalidateEnable(true);
|
|
|
|
pCmd->setTextureCacheInvalidationEnable(true);
|
|
|
|
pCmd->setPipeControlFlushEnable(true);
|
|
|
|
pCmd->setVfCacheInvalidationEnable(true);
|
|
|
|
pCmd->setConstantCacheInvalidationEnable(true);
|
|
|
|
pCmd->setStateCacheInvalidationEnable(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
uint64_t CommandStreamReceiverHw<GfxFamily>::getScratchPatchAddress() {
|
|
|
|
//for 32 bit scratch space pointer is being programmed in Media VFE State and is relative to 0 as General State Base Address
|
|
|
|
//for 64 bit, scratch space pointer is being programmed as "General State Base Address - scratchSpaceOffsetFor64bit"
|
|
|
|
// and "0 + scratchSpaceOffsetFor64bit" is being programmed in Media VFE state
|
|
|
|
|
|
|
|
uint64_t scratchAddress = 0;
|
|
|
|
if (requiredScratchSize) {
|
|
|
|
scratchAddress = scratchAllocation->getGpuAddressToPatch();
|
|
|
|
if (is64bit && !getMemoryManager()->peekForce32BitAllocations()) {
|
|
|
|
//this is to avoid scractch allocation offset "0"
|
|
|
|
scratchAddress = PreambleHelper<GfxFamily>::getScratchSpaceOffsetFor64bit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return scratchAddress;
|
|
|
|
}
|
2018-01-24 17:11:37 +08:00
|
|
|
template <typename GfxFamily>
|
2018-08-07 15:07:50 +08:00
|
|
|
size_t CommandStreamReceiverHw<GfxFamily>::getRequiredCmdStreamSizeAligned(const DispatchFlags &dispatchFlags, Device &device) {
|
|
|
|
size_t size = getRequiredCmdStreamSize(dispatchFlags, device);
|
2018-01-24 17:11:37 +08:00
|
|
|
return alignUp(size, MemoryConstants::cacheLineSize);
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-08-30 17:05:18 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
size_t CommandStreamReceiverHw<GfxFamily>::getRequiredStateBaseAddressSize() const {
|
2018-08-29 19:39:27 +08:00
|
|
|
return sizeof(typename GfxFamily::STATE_BASE_ADDRESS) + sizeof(PIPE_CONTROL);
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
template <typename GfxFamily>
|
2018-08-07 15:07:50 +08:00
|
|
|
size_t CommandStreamReceiverHw<GfxFamily>::getRequiredCmdStreamSize(const DispatchFlags &dispatchFlags, Device &device) {
|
2018-08-16 17:18:05 +08:00
|
|
|
size_t size = getRequiredCmdSizeForPreamble(device);
|
2018-08-29 19:39:27 +08:00
|
|
|
size += getRequiredStateBaseAddressSize();
|
2018-04-20 19:55:54 +08:00
|
|
|
size += getRequiredPipeControlSize();
|
|
|
|
size += sizeof(typename GfxFamily::MI_BATCH_BUFFER_START);
|
2018-04-13 17:05:09 +08:00
|
|
|
|
|
|
|
size += getCmdSizeForL3Config();
|
2017-12-21 07:45:38 +08:00
|
|
|
size += getCmdSizeForCoherency();
|
2018-01-19 20:29:25 +08:00
|
|
|
size += getCmdSizeForMediaSampler(dispatchFlags.mediaSamplerRequired);
|
2018-04-13 17:05:09 +08:00
|
|
|
size += getCmdSizeForPipelineSelect();
|
|
|
|
size += getCmdSizeForPreemption(dispatchFlags);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-08-07 15:07:50 +08:00
|
|
|
if (device.getWaTable()->waSamplerCacheFlushBetweenRedescribedSurfaceReads) {
|
2018-01-10 21:05:34 +08:00
|
|
|
if (this->samplerCacheFlushRequired != SamplerCacheFlushState::samplerCacheFlushNotRequired) {
|
|
|
|
size += sizeof(typename GfxFamily::PIPE_CONTROL);
|
|
|
|
}
|
|
|
|
}
|
2018-07-05 17:23:28 +08:00
|
|
|
if (experimentalCmdBuffer.get() != nullptr) {
|
|
|
|
size += experimentalCmdBuffer->getRequiredInjectionSize<GfxFamily>();
|
|
|
|
}
|
2018-09-07 20:31:37 +08:00
|
|
|
if (dispatchFlags.outOfDeviceDependencies) {
|
|
|
|
size += dispatchFlags.outOfDeviceDependencies->numEventsInWaitList * sizeof(typename GfxFamily::MI_SEMAPHORE_WAIT);
|
|
|
|
}
|
2018-01-24 17:11:37 +08:00
|
|
|
return size;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
inline void CommandStreamReceiverHw<GfxFamily>::emitNoop(LinearStream &commandStream, size_t bytesToUpdate) {
|
|
|
|
if (bytesToUpdate) {
|
|
|
|
auto ptr = commandStream.getSpace(bytesToUpdate);
|
|
|
|
memset(ptr, 0, bytesToUpdate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
2018-08-27 21:48:29 +08:00
|
|
|
inline void CommandStreamReceiverHw<GfxFamily>::waitForTaskCountWithKmdNotifyFallback(uint32_t taskCountToWait, FlushStamp flushStampToWait, bool useQuickKmdSleep, OsContext &osContext) {
|
2018-04-10 16:26:59 +08:00
|
|
|
int64_t waitTimeout = 0;
|
|
|
|
bool enableTimeout = kmdNotifyHelper->obtainTimeoutParams(waitTimeout, useQuickKmdSleep, *getTagAddress(), taskCountToWait, flushStampToWait);
|
2018-03-21 17:00:49 +08:00
|
|
|
|
2018-04-10 16:26:59 +08:00
|
|
|
auto status = waitForCompletionWithTimeout(enableTimeout, waitTimeout, taskCountToWait);
|
2017-12-21 07:45:38 +08:00
|
|
|
if (!status) {
|
2018-08-27 21:48:29 +08:00
|
|
|
waitForFlushStamp(flushStampToWait, osContext);
|
2017-12-21 07:45:38 +08:00
|
|
|
//now call blocking wait, this is to ensure that task count is reached
|
2018-03-22 16:41:17 +08:00
|
|
|
waitForCompletionWithTimeout(false, 0, taskCountToWait);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
UNRECOVERABLE_IF(*getTagAddress() < taskCountToWait);
|
2018-03-22 16:41:17 +08:00
|
|
|
|
2018-04-10 16:26:59 +08:00
|
|
|
if (kmdNotifyHelper->quickKmdSleepForSporadicWaitsEnabled()) {
|
|
|
|
kmdNotifyHelper->updateLastWaitForCompletionTimestamp();
|
2018-03-22 16:41:17 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
2018-08-16 17:18:05 +08:00
|
|
|
inline void CommandStreamReceiverHw<GfxFamily>::programPreemption(LinearStream &csr, Device &device, DispatchFlags &dispatchFlags) {
|
|
|
|
PreemptionHelper::programCmdStream<GfxFamily>(csr, dispatchFlags.preemptionMode, this->lastPreemptionMode, preemptionCsrAllocation, device);
|
2018-01-08 22:58:02 +08:00
|
|
|
this->lastPreemptionMode = dispatchFlags.preemptionMode;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-04-13 17:05:09 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
inline size_t CommandStreamReceiverHw<GfxFamily>::getCmdSizeForPreemption(const DispatchFlags &dispatchFlags) const {
|
|
|
|
return PreemptionHelper::getRequiredCmdStreamSize<GfxFamily>(dispatchFlags.preemptionMode, this->lastPreemptionMode);
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
inline void CommandStreamReceiverHw<GfxFamily>::programL3(LinearStream &csr, DispatchFlags &dispatchFlags, uint32_t &newL3Config) {
|
|
|
|
typedef typename GfxFamily::PIPE_CONTROL PIPE_CONTROL;
|
|
|
|
if (csrSizeRequestFlags.l3ConfigChanged && this->isPreambleSent) {
|
|
|
|
// Add a PIPE_CONTROL w/ CS_stall
|
|
|
|
auto pCmd = (PIPE_CONTROL *)csr.getSpace(sizeof(PIPE_CONTROL));
|
|
|
|
*pCmd = GfxFamily::cmdInitPipeControl;
|
|
|
|
pCmd->setCommandStreamerStallEnable(true);
|
|
|
|
pCmd->setDcFlushEnable(true);
|
2018-05-21 16:57:28 +08:00
|
|
|
addClearSLMWorkAround(pCmd);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
PreambleHelper<GfxFamily>::programL3(&csr, newL3Config);
|
|
|
|
this->lastSentL3Config = newL3Config;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-13 17:05:09 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
inline size_t CommandStreamReceiverHw<GfxFamily>::getCmdSizeForL3Config() const {
|
|
|
|
if (!this->isPreambleSent) {
|
|
|
|
return sizeof(typename GfxFamily::MI_LOAD_REGISTER_IMM);
|
|
|
|
} else if (csrSizeRequestFlags.l3ConfigChanged) {
|
|
|
|
return sizeof(typename GfxFamily::MI_LOAD_REGISTER_IMM) + sizeof(typename GfxFamily::PIPE_CONTROL);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
template <typename GfxFamily>
|
2018-08-16 17:18:05 +08:00
|
|
|
inline void CommandStreamReceiverHw<GfxFamily>::programPreamble(LinearStream &csr, Device &device, DispatchFlags &dispatchFlags, uint32_t &newL3Config) {
|
2017-12-21 07:45:38 +08:00
|
|
|
if (!this->isPreambleSent) {
|
2018-08-16 17:18:05 +08:00
|
|
|
PreambleHelper<GfxFamily>::programPreamble(&csr, device, newL3Config, this->requiredThreadArbitrationPolicy, this->preemptionCsrAllocation);
|
2017-12-21 07:45:38 +08:00
|
|
|
this->isPreambleSent = true;
|
|
|
|
this->lastSentL3Config = newL3Config;
|
2018-02-20 15:11:24 +08:00
|
|
|
this->lastSentThreadArbitrationPolicy = this->requiredThreadArbitrationPolicy;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
inline void CommandStreamReceiverHw<GfxFamily>::programVFEState(LinearStream &csr, DispatchFlags &dispatchFlags) {
|
|
|
|
if (mediaVfeStateDirty) {
|
|
|
|
PreambleHelper<GfxFamily>::programVFEState(&csr, hwInfo, requiredScratchSize, getScratchPatchAddress());
|
|
|
|
overrideMediaVFEStateDirty(false);
|
|
|
|
}
|
|
|
|
}
|
2018-01-19 20:29:25 +08:00
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
void CommandStreamReceiverHw<GfxFamily>::programMediaSampler(LinearStream &commandStream, DispatchFlags &dispatchFlags) {
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
size_t CommandStreamReceiverHw<GfxFamily>::getCmdSizeForMediaSampler(bool mediaSamplerRequired) const {
|
|
|
|
return 0;
|
|
|
|
}
|
2018-03-23 02:02:58 +08:00
|
|
|
|
2018-03-14 18:07:51 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
void CommandStreamReceiverHw<GfxFamily>::collectStateBaseAddresPatchInfo(
|
|
|
|
uint64_t baseAddress,
|
|
|
|
uint64_t commandOffset,
|
|
|
|
const LinearStream &dsh,
|
|
|
|
const LinearStream &ioh,
|
|
|
|
const LinearStream &ssh,
|
2018-04-04 17:34:46 +08:00
|
|
|
uint64_t generalStateBase) {
|
2018-03-14 18:07:51 +08:00
|
|
|
|
|
|
|
typedef typename GfxFamily::STATE_BASE_ADDRESS STATE_BASE_ADDRESS;
|
|
|
|
|
2018-04-04 17:34:46 +08:00
|
|
|
PatchInfoData dynamicStatePatchInfo = {dsh.getGraphicsAllocation()->getGpuAddress(), 0u, PatchInfoAllocationType::DynamicStateHeap, baseAddress, commandOffset + STATE_BASE_ADDRESS::PATCH_CONSTANTS::DYNAMICSTATEBASEADDRESS_BYTEOFFSET, PatchInfoAllocationType::Default};
|
2018-03-14 18:07:51 +08:00
|
|
|
PatchInfoData generalStatePatchInfo = {generalStateBase, 0u, PatchInfoAllocationType::GeneralStateHeap, baseAddress, commandOffset + STATE_BASE_ADDRESS::PATCH_CONSTANTS::GENERALSTATEBASEADDRESS_BYTEOFFSET, PatchInfoAllocationType::Default};
|
2018-04-04 17:34:46 +08:00
|
|
|
PatchInfoData surfaceStatePatchInfo = {ssh.getGraphicsAllocation()->getGpuAddress(), 0u, PatchInfoAllocationType::SurfaceStateHeap, baseAddress, commandOffset + STATE_BASE_ADDRESS::PATCH_CONSTANTS::SURFACESTATEBASEADDRESS_BYTEOFFSET, PatchInfoAllocationType::Default};
|
|
|
|
PatchInfoData indirectObjectPatchInfo = {ioh.getGraphicsAllocation()->getGpuAddress(), 0u, PatchInfoAllocationType::IndirectObjectHeap, baseAddress, commandOffset + STATE_BASE_ADDRESS::PATCH_CONSTANTS::INDIRECTOBJECTBASEADDRESS_BYTEOFFSET, PatchInfoAllocationType::Default};
|
|
|
|
|
|
|
|
flatBatchBufferHelper->setPatchInfoData(dynamicStatePatchInfo);
|
|
|
|
flatBatchBufferHelper->setPatchInfoData(generalStatePatchInfo);
|
|
|
|
flatBatchBufferHelper->setPatchInfoData(surfaceStatePatchInfo);
|
|
|
|
flatBatchBufferHelper->setPatchInfoData(indirectObjectPatchInfo);
|
2018-03-14 18:07:51 +08:00
|
|
|
}
|
|
|
|
|
2018-04-10 16:26:59 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
void CommandStreamReceiverHw<GfxFamily>::resetKmdNotifyHelper(KmdNotifyHelper *newHelper) {
|
|
|
|
kmdNotifyHelper.reset(newHelper);
|
|
|
|
kmdNotifyHelper->updateAcLineStatus();
|
|
|
|
if (kmdNotifyHelper->quickKmdSleepForSporadicWaitsEnabled()) {
|
|
|
|
kmdNotifyHelper->updateLastWaitForCompletionTimestamp();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-21 16:57:28 +08:00
|
|
|
template <typename GfxFamily>
|
|
|
|
void CommandStreamReceiverHw<GfxFamily>::addClearSLMWorkAround(typename GfxFamily::PIPE_CONTROL *pCmd) {
|
|
|
|
}
|
2018-09-07 20:31:37 +08:00
|
|
|
|
|
|
|
template <typename GfxFamily>
|
|
|
|
void CommandStreamReceiverHw<GfxFamily>::programOutOfDeviceWaitlistSemaphores(LinearStream &csr, DispatchFlags &dispatchFlags, Device ¤tDevice) {
|
|
|
|
using MI_SEMAPHORE_WAIT = typename GfxFamily::MI_SEMAPHORE_WAIT;
|
|
|
|
|
|
|
|
for (cl_uint i = 0; i < dispatchFlags.outOfDeviceDependencies->numEventsInWaitList; i++) {
|
|
|
|
auto event = castToObjectOrAbort<Event>(dispatchFlags.outOfDeviceDependencies->eventWaitList[i]);
|
|
|
|
if (event->isUserEvent() || (&event->getCommandQueue()->getDevice() == ¤tDevice)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
auto timestampPacket = event->getTimestampPacket();
|
|
|
|
|
|
|
|
auto compareAddress = timestampPacket->pickAddressForDataWrite(TimestampPacket::DataIndex::ContextEnd);
|
|
|
|
|
2018-09-11 16:15:54 +08:00
|
|
|
KernelCommandsHelper<GfxFamily>::programMiSemaphoreWait(csr, compareAddress, 1);
|
2018-09-07 20:31:37 +08:00
|
|
|
}
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
} // namespace OCLRT
|