/* * Copyright (C) 2018-2020 Intel Corporation * * SPDX-License-Identifier: MIT * */ #pragma once #include "shared/source/built_ins/built_ins.h" #include "shared/source/command_stream/linear_stream.h" #include "shared/source/command_stream/preemption.h" #include "shared/source/helpers/register_offsets.h" #include "shared/source/helpers/timestamp_packet.h" #include "shared/source/helpers/vec.h" #include "shared/source/indirect_heap/indirect_heap.h" #include "shared/source/utilities/tag_allocator.h" #include "opencl/source/command_queue/command_queue.h" #include "opencl/source/context/context.h" #include "opencl/source/device_queue/device_queue_hw.h" #include "opencl/source/event/hw_timestamps.h" #include "opencl/source/event/perf_counter.h" #include "opencl/source/helpers/dispatch_info.h" #include "opencl/source/helpers/hardware_commands_helper.h" #include "opencl/source/helpers/task_information.h" #include "opencl/source/kernel/kernel.h" #include "opencl/source/program/kernel_info.h" namespace NEO { struct RootDeviceEnvironment; template using WALKER_TYPE = typename GfxFamily::WALKER_TYPE; template using MI_STORE_REG_MEM = typename GfxFamily::MI_STORE_REGISTER_MEM_CMD; void computeWorkgroupSize1D( uint32_t maxWorkGroupSize, size_t workGroupSize[3], const size_t workItems[3], size_t simdSize); void computeWorkgroupSizeND( WorkSizeInfo wsInfo, size_t workGroupSize[3], const size_t workItems[3], const uint32_t workDim); void computeWorkgroupSize2D( uint32_t maxWorkGroupSize, size_t workGroupSize[3], const size_t workItems[3], size_t simdSize); void computeWorkgroupSizeSquared( uint32_t maxWorkGroupSize, size_t workGroupSize[3], const size_t workItems[3], size_t simdSize, const uint32_t workDim); Vec3 computeWorkgroupSize( const DispatchInfo &dispatchInfo); Vec3 generateWorkgroupSize( const DispatchInfo &dispatchInfo); Vec3 computeWorkgroupsNumber( const Vec3 gws, const Vec3 lws); Vec3 generateWorkgroupsNumber( const Vec3 gws, const Vec3 lws); Vec3 generateWorkgroupsNumber( const DispatchInfo &dispatchInfo); inline uint32_t calculateDispatchDim(Vec3 dispatchSize, Vec3 dispatchOffset) { return std::max(1U, std::max(dispatchSize.getSimplifiedDim(), dispatchOffset.getSimplifiedDim())); } Vec3 canonizeWorkgroup( Vec3 workgroup); void provideLocalWorkGroupSizeHints(Context *context, DispatchInfo dispatchInfo); void setSpecialWorkgroupSize(size_t workgroupSize[3]); inline cl_uint computeDimensions(const size_t workItems[3]) { return (workItems[2] > 1) ? 3 : (workItems[1] > 1) ? 2 : 1; } template class GpgpuWalkerHelper { public: static void applyWADisableLSQCROPERFforOCL(LinearStream *pCommandStream, const Kernel &kernel, bool disablePerfMode); static size_t getSizeForWADisableLSQCROPERFforOCL(const Kernel *pKernel); static size_t setGpgpuWalkerThreadData( WALKER_TYPE *walkerCmd, const size_t globalOffsets[3], const size_t startWorkGroups[3], const size_t numWorkGroups[3], const size_t localWorkSizesIn[3], uint32_t simd, uint32_t workDim, bool localIdsGenerationByRuntime, bool inlineDataProgrammingRequired, const iOpenCL::SPatchThreadPayload &threadPayload, uint32_t requiredWorkgroupOrder); static void dispatchProfilingCommandsStart( TagNode &hwTimeStamps, LinearStream *commandStream, const HardwareInfo &hwInfo); static void dispatchProfilingCommandsEnd( TagNode &hwTimeStamps, LinearStream *commandStream); static void dispatchPerfCountersCommandsStart( CommandQueue &commandQueue, TagNode &hwPerfCounter, LinearStream *commandStream); static void dispatchPerfCountersCommandsEnd( CommandQueue &commandQueue, TagNode &hwPerfCounter, LinearStream *commandStream); static void setupTimestampPacket( LinearStream *cmdStream, WALKER_TYPE *walkerCmd, TagNode *timestampPacketNode, TimestampPacketStorage::WriteOperationType writeOperationType, const RootDeviceEnvironment &rootDeviceEnvironment); static void dispatchScheduler( LinearStream &commandStream, DeviceQueueHw &devQueueHw, PreemptionMode preemptionMode, SchedulerKernel &scheduler, IndirectHeap *ssh, IndirectHeap *dsh, bool isCcsUsed); static void adjustMiStoreRegMemMode(MI_STORE_REG_MEM *storeCmd); private: using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL; static void addAluReadModifyWriteRegister( LinearStream *pCommandStream, uint32_t aluRegister, AluRegisters operation, uint32_t mask); }; template struct EnqueueOperation { using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL; static size_t getTotalSizeRequiredCS(uint32_t eventType, const CsrDependencies &csrDeps, bool reserveProfilingCmdsSpace, bool reservePerfCounters, bool blitEnqueue, CommandQueue &commandQueue, const MultiDispatchInfo &multiDispatchInfo); static size_t getSizeRequiredCS(uint32_t cmdType, bool reserveProfilingCmdsSpace, bool reservePerfCounters, CommandQueue &commandQueue, const Kernel *pKernel); static size_t getSizeRequiredForTimestampPacketWrite(); private: static size_t getSizeRequiredCSKernel(bool reserveProfilingCmdsSpace, bool reservePerfCounters, CommandQueue &commandQueue, const Kernel *pKernel); static size_t getSizeRequiredCSNonKernel(bool reserveProfilingCmdsSpace, bool reservePerfCounters, CommandQueue &commandQueue); }; template LinearStream &getCommandStream(CommandQueue &commandQueue, const CsrDependencies &csrDeps, bool reserveProfilingCmdsSpace, bool reservePerfCounterCmdsSpace, bool blitEnqueue, const MultiDispatchInfo &multiDispatchInfo, Surface **surfaces, size_t numSurfaces) { size_t expectedSizeCS = EnqueueOperation::getTotalSizeRequiredCS(eventType, csrDeps, reserveProfilingCmdsSpace, reservePerfCounterCmdsSpace, blitEnqueue, commandQueue, multiDispatchInfo); return commandQueue.getCS(expectedSizeCS); } template IndirectHeap &getIndirectHeap(CommandQueue &commandQueue, const MultiDispatchInfo &multiDispatchInfo) { size_t expectedSize = 0; IndirectHeap *ih = nullptr; // clang-format off switch (heapType) { case IndirectHeap::DYNAMIC_STATE: expectedSize = HardwareCommandsHelper::getTotalSizeRequiredDSH(multiDispatchInfo); break; case IndirectHeap::INDIRECT_OBJECT: expectedSize = HardwareCommandsHelper::getTotalSizeRequiredIOH(multiDispatchInfo); break; case IndirectHeap::SURFACE_STATE: expectedSize = HardwareCommandsHelper::getTotalSizeRequiredSSH(multiDispatchInfo); break; } // clang-format on if (Kernel *parentKernel = multiDispatchInfo.peekParentKernel()) { if (heapType == IndirectHeap::SURFACE_STATE) { expectedSize += HardwareCommandsHelper::getSshSizeForExecutionModel(*parentKernel); } else //if (heapType == IndirectHeap::DYNAMIC_STATE || heapType == IndirectHeap::INDIRECT_OBJECT) { DeviceQueueHw *pDevQueue = castToObject>(commandQueue.getContext().getDefaultDeviceQueue()); DEBUG_BREAK_IF(pDevQueue == nullptr); ih = pDevQueue->getIndirectHeap(IndirectHeap::DYNAMIC_STATE); } } if (ih == nullptr) ih = &commandQueue.getIndirectHeap(heapType, expectedSize); return *ih; } } // namespace NEO