1 /* 2 * Copyright (C) 2018-2021 Intel Corporation 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 */ 7 8 #pragma once 9 #include "shared/source/command_stream/command_stream_receiver.h" 10 #include "shared/source/command_stream/linear_stream.h" 11 #include "shared/source/helpers/pipeline_select_helper.h" 12 #include "shared/source/helpers/ptr_math.h" 13 #include "shared/source/os_interface/hw_info_config.h" 14 #include "shared/test/common/cmd_parse/gen_cmd_parse.h" 15 #include "shared/test/common/helpers/default_hw_info.h" 16 17 #include "gtest/gtest.h" 18 19 namespace NEO { 20 21 struct HardwareParse { HardwareParseHardwareParse22 HardwareParse() { 23 itorMediaInterfaceDescriptorLoad = cmdList.end(); 24 itorMediaVfeState = cmdList.end(); 25 itorPipelineSelect = cmdList.end(); 26 itorStateBaseAddress = cmdList.end(); 27 itorWalker = cmdList.end(); 28 itorGpgpuCsrBaseAddress = cmdList.end(); 29 } 30 SetUpHardwareParse31 void SetUp() { 32 } 33 TearDownHardwareParse34 void TearDown() { 35 cmdList.clear(); 36 lriList.clear(); 37 pipeControlList.clear(); 38 } 39 40 template <typename CmdType> getCommandsListHardwareParse41 GenCmdList getCommandsList() { 42 GenCmdList list; 43 for (auto it = cmdList.begin(); it != cmdList.end(); it++) { 44 auto cmd = genCmdCast<CmdType *>(*it); 45 if (cmd) { 46 list.push_back(*it); 47 } 48 } 49 return list; 50 } 51 52 template <typename FamilyType> 53 void findCsrBaseAddress(); 54 55 template <typename FamilyType> 56 void findHardwareCommands(); 57 58 template <typename FamilyType> 59 void findHardwareCommands(IndirectHeap *dsh); 60 61 template <typename FamilyType> 62 void parseCommands(NEO::LinearStream &commandStream, size_t startOffset = 0) { 63 ASSERT_LE(startOffset, commandStream.getUsed()); 64 auto sizeToParse = commandStream.getUsed() - startOffset; 65 ASSERT_TRUE(FamilyType::PARSE::parseCommandBuffer( 66 cmdList, 67 ptrOffset(commandStream.getCpuBase(), startOffset), 68 sizeToParse)); 69 } 70 71 template <typename FamilyType> parseCommandsHardwareParse72 void parseCommands(NEO::CommandStreamReceiver &commandStreamReceiver, NEO::LinearStream &commandStream) { 73 auto &commandStreamCSR = commandStreamReceiver.getCS(); 74 75 parseCommands<FamilyType>(commandStreamCSR, startCSRCS); 76 startCSRCS = commandStreamCSR.getUsed(); 77 78 if (previousCS != &commandStream) { 79 startCS = 0; 80 } 81 parseCommands<FamilyType>(commandStream, startCS); 82 startCS = commandStream.getUsed(); 83 previousCS = &commandStream; 84 85 sizeUsed = commandStream.getUsed(); 86 findHardwareCommands<FamilyType>(&commandStreamReceiver.getIndirectHeap(IndirectHeap::DYNAMIC_STATE, 0)); 87 } 88 89 template <typename FamilyType> getSurfaceStateHardwareParse90 const typename FamilyType::RENDER_SURFACE_STATE &getSurfaceState(IndirectHeap *ssh, uint32_t index) { 91 typedef typename FamilyType::BINDING_TABLE_STATE BINDING_TABLE_STATE; 92 typedef typename FamilyType::INTERFACE_DESCRIPTOR_DATA INTERFACE_DESCRIPTOR_DATA; 93 typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE; 94 typedef typename FamilyType::STATE_BASE_ADDRESS STATE_BASE_ADDRESS; 95 96 const auto &interfaceDescriptorData = *(INTERFACE_DESCRIPTOR_DATA *)cmdInterfaceDescriptorData; 97 98 auto cmdSBA = (STATE_BASE_ADDRESS *)cmdStateBaseAddress; 99 auto surfaceStateHeap = cmdSBA->getSurfaceStateBaseAddress(); 100 if (ssh && (ssh->getHeapGpuBase() == surfaceStateHeap)) { 101 surfaceStateHeap = reinterpret_cast<uint64_t>(ssh->getCpuBase()); 102 } 103 EXPECT_NE(0u, surfaceStateHeap); 104 105 auto bindingTablePointer = interfaceDescriptorData.getBindingTablePointer(); 106 107 const auto &bindingTableState = reinterpret_cast<BINDING_TABLE_STATE *>(surfaceStateHeap + bindingTablePointer)[index]; 108 auto surfaceStatePointer = bindingTableState.getSurfaceStatePointer(); 109 110 return *(RENDER_SURFACE_STATE *)(surfaceStateHeap + surfaceStatePointer); 111 } 112 113 template <typename FamilyType> getSamplerStateHardwareParse114 const typename FamilyType::SAMPLER_STATE &getSamplerState(uint32_t index) { 115 typedef typename FamilyType::INTERFACE_DESCRIPTOR_DATA INTERFACE_DESCRIPTOR_DATA; 116 typedef typename FamilyType::SAMPLER_STATE SAMPLER_STATE; 117 typedef typename FamilyType::STATE_BASE_ADDRESS STATE_BASE_ADDRESS; 118 119 const auto &interfaceDescriptorData = *(INTERFACE_DESCRIPTOR_DATA *)cmdInterfaceDescriptorData; 120 121 auto cmdSBA = (STATE_BASE_ADDRESS *)cmdStateBaseAddress; 122 auto dynamicStateHeap = cmdSBA->getDynamicStateBaseAddress(); 123 EXPECT_NE(0, dynamicStateHeap); 124 125 const auto samplerState = reinterpret_cast<SAMPLER_STATE *>(dynamicStateHeap + interfaceDescriptorData.getSamplerStatePointer()); 126 return samplerState[index]; 127 } 128 129 template <typename FamilyType> 130 const void *getStatelessArgumentPointer(const KernelInfo &kernelInfo, uint32_t indexArg, IndirectHeap &ioh, uint32_t rootDeviceIndex); 131 132 template <typename CmdType> getCommandHardwareParse133 CmdType *getCommand(GenCmdList::iterator itorStart, GenCmdList::iterator itorEnd) { 134 auto itorCmd = find<CmdType *>(itorStart, itorEnd); 135 return itorCmd != cmdList.end() 136 ? genCmdCast<CmdType *>(*itorCmd) 137 : nullptr; 138 } 139 140 template <typename CmdType> getCommandHardwareParse141 CmdType *getCommand() { 142 return getCommand<CmdType>(cmdList.begin(), cmdList.end()); 143 } 144 145 template <typename FamilyType> getNumberOfPipelineSelectsThatEnablePipelineSelectHardwareParse146 int getNumberOfPipelineSelectsThatEnablePipelineSelect() { 147 typedef typename FamilyType::PIPELINE_SELECT PIPELINE_SELECT; 148 int numberOfGpgpuSelects = 0; 149 int numberOf3dSelects = 0; 150 auto itorCmd = find<PIPELINE_SELECT *>(cmdList.begin(), cmdList.end()); 151 while (itorCmd != cmdList.end()) { 152 auto cmd = getCommand<PIPELINE_SELECT>(itorCmd, cmdList.end()); 153 if (cmd->getPipelineSelection() == PIPELINE_SELECT::PIPELINE_SELECTION_GPGPU && 154 pipelineSelectEnablePipelineSelectMaskBits == (pipelineSelectEnablePipelineSelectMaskBits & cmd->getMaskBits())) { 155 numberOfGpgpuSelects++; 156 } 157 if (cmd->getPipelineSelection() == PIPELINE_SELECT::PIPELINE_SELECTION_3D && 158 pipelineSelectEnablePipelineSelectMaskBits == (pipelineSelectEnablePipelineSelectMaskBits & cmd->getMaskBits())) { 159 numberOf3dSelects++; 160 } 161 itorCmd = find<PIPELINE_SELECT *>(++itorCmd, cmdList.end()); 162 } 163 const auto &hwInfoConfig = *HwInfoConfig::get(defaultHwInfo->platform.eProductFamily); 164 if (hwInfoConfig.is3DPipelineSelectWARequired()) { 165 auto maximalNumberOf3dSelectsRequired = 2; 166 EXPECT_LE(numberOf3dSelects, maximalNumberOf3dSelectsRequired); 167 EXPECT_EQ(numberOf3dSelects, numberOfGpgpuSelects); 168 auto numberOfGpgpuSelectsAddedByWa = numberOf3dSelects - 1; 169 numberOfGpgpuSelects -= numberOfGpgpuSelectsAddedByWa; 170 } else { 171 EXPECT_EQ(0, numberOf3dSelects); 172 } 173 return numberOfGpgpuSelects; 174 } 175 176 template <typename CmdType> getCommandCountHardwareParse177 uint32_t getCommandCount() { 178 GenCmdList::iterator cmdItor = cmdList.begin(); 179 uint32_t cmdCount = 0; 180 181 do { 182 cmdItor = find<CmdType *>(cmdItor, cmdList.end()); 183 if (cmdItor != cmdList.end()) { 184 ++cmdCount; 185 ++cmdItor; 186 } 187 } while (cmdItor != cmdList.end()); 188 189 return cmdCount; 190 } 191 192 template <typename FamilyType> getCommandNameHardwareParse193 static const char *getCommandName(void *cmd) { 194 return FamilyType::PARSE::getCommandName(cmd); 195 } 196 197 // The starting point of parsing commandBuffers. This is important 198 // because as buffers get reused, we only want to parse the deltas. 199 LinearStream *previousCS = nullptr; 200 size_t startCS = 0u; 201 size_t startCSRCS = 0u; 202 203 size_t sizeUsed = 0u; 204 GenCmdList cmdList; 205 GenCmdList lriList; 206 GenCmdList pipeControlList; 207 GenCmdList::iterator itorMediaInterfaceDescriptorLoad; 208 GenCmdList::iterator itorMediaVfeState; 209 GenCmdList::iterator itorPipelineSelect; 210 GenCmdList::iterator itorStateBaseAddress; 211 GenCmdList::iterator itorWalker; 212 GenCmdList::iterator itorBBStartAfterWalker; 213 GenCmdList::iterator itorGpgpuCsrBaseAddress; 214 215 void *cmdInterfaceDescriptorData = nullptr; 216 void *cmdMediaInterfaceDescriptorLoad = nullptr; 217 void *cmdMediaVfeState = nullptr; 218 void *cmdPipelineSelect = nullptr; 219 void *cmdStateBaseAddress = nullptr; 220 void *cmdWalker = nullptr; 221 void *cmdBBStartAfterWalker = nullptr; 222 void *cmdGpgpuCsrBaseAddress = nullptr; 223 224 bool parsePipeControl = false; 225 }; 226 227 } // namespace NEO 228