/* * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/source/helpers/hw_helper.h" #include "shared/source/helpers/ptr_math.h" #include "shared/source/helpers/string.h" #include "shared/test/unit_test/cmd_parse/gen_cmd_parse.h" #include "shared/test/unit_test/fixtures/command_container_fixture.h" #include "shared/test/unit_test/fixtures/front_window_fixture.h" #include "shared/test/unit_test/helpers/debug_manager_state_restore.h" #include "shared/test/unit_test/mocks/mock_device.h" using namespace NEO; using CommandEncodeStatesTest = Test; HWTEST_F(CommandEncodeStatesTest, GivenCommandStreamWhenEncodeCopySamplerStateThenIndirectStatePointerIsCorrect) { using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE; uint32_t numSamplers = 1; SAMPLER_STATE samplerState; auto dsh = cmdContainer->getIndirectHeap(HeapType::DYNAMIC_STATE); auto usedBefore = dsh->getUsed(); auto samplerStateOffset = EncodeStates::copySamplerState(dsh, 0, numSamplers, 0, &samplerState, nullptr); auto pSmplr = reinterpret_cast(ptrOffset(dsh->getCpuBase(), samplerStateOffset)); EXPECT_EQ(pSmplr->getIndirectStatePointer(), usedBefore); } using BindlessCommandEncodeStatesTest = Test; HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorWithoutAlphaThenBorderColorPtrReturned) { using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE; DebugManagerStateRestore restorer; DebugManager.flags.UseBindlessMode.set(1); using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE; uint32_t numSamplers = 1; pDevice->getExecutionEnvironment()->rootDeviceEnvironments[pDevice->getRootDeviceIndex()]->createBindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); uint32_t borderColorSize = 0x40; SAMPLER_BORDER_COLOR_STATE samplerState; samplerState.init(); auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH); EncodeStates::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper()); auto expectedValue = pDevice->getBindlessHeapsHelper()->getDefaultBorderColorOffset(); auto pSmplr = reinterpret_cast(dsh->getGraphicsAllocation()->getUnderlyingBuffer()); EXPECT_EQ(pSmplr->getIndirectStatePointer(), expectedValue); } HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorWithAlphaThenBorderColorPtrOffseted) { using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE; DebugManagerStateRestore restorer; DebugManager.flags.UseBindlessMode.set(1); using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE; uint32_t numSamplers = 1; pDevice->getExecutionEnvironment()->rootDeviceEnvironments[pDevice->getRootDeviceIndex()]->createBindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); uint32_t borderColorSize = 0x40; SAMPLER_BORDER_COLOR_STATE samplerState; samplerState.init(); samplerState.setBorderColorAlpha(1.0); auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH); EncodeStates::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper()); auto expectedValue = pDevice->getBindlessHeapsHelper()->getAlphaBorderColorOffset(); auto pSmplr = reinterpret_cast(dsh->getGraphicsAllocation()->getUnderlyingBuffer()); EXPECT_EQ(pSmplr->getIndirectStatePointer(), expectedValue); } HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorsRedChanelIsNotZeroThenExceptionThrown) { using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE; DebugManagerStateRestore restorer; DebugManager.flags.UseBindlessMode.set(1); using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE; uint32_t numSamplers = 1; pDevice->getExecutionEnvironment()->rootDeviceEnvironments[pDevice->getRootDeviceIndex()]->createBindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); uint32_t borderColorSize = 0x40; SAMPLER_BORDER_COLOR_STATE samplerState; samplerState.init(); samplerState.setBorderColorRed(0.5); auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH); EXPECT_THROW(EncodeStates::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper()), std::exception); } HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorsGreenChanelIsNotZeroThenExceptionThrown) { using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE; DebugManagerStateRestore restorer; DebugManager.flags.UseBindlessMode.set(1); using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE; uint32_t numSamplers = 1; pDevice->getExecutionEnvironment()->rootDeviceEnvironments[pDevice->getRootDeviceIndex()]->createBindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); uint32_t borderColorSize = 0x40; SAMPLER_BORDER_COLOR_STATE samplerState; samplerState.init(); samplerState.setBorderColorGreen(0.5); auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH); EXPECT_THROW(EncodeStates::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper()), std::exception); } HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorsBlueChanelIsNotZeroThenExceptionThrown) { using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE; DebugManagerStateRestore restorer; DebugManager.flags.UseBindlessMode.set(1); using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE; uint32_t numSamplers = 1; pDevice->getExecutionEnvironment()->rootDeviceEnvironments[pDevice->getRootDeviceIndex()]->createBindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); uint32_t borderColorSize = 0x40; SAMPLER_BORDER_COLOR_STATE samplerState; samplerState.init(); samplerState.setBorderColorBlue(0.5); auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH); EXPECT_THROW(EncodeStates::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper()), std::exception); } HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorsAlphaChanelIsNotZeroOrOneThenExceptionThrown) { using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE; DebugManagerStateRestore restorer; DebugManager.flags.UseBindlessMode.set(1); using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE; uint32_t numSamplers = 1; pDevice->getExecutionEnvironment()->rootDeviceEnvironments[pDevice->getRootDeviceIndex()]->createBindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); uint32_t borderColorSize = 0x40; SAMPLER_BORDER_COLOR_STATE samplerState; samplerState.init(); samplerState.setBorderColorAlpha(0.5); auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH); EXPECT_THROW(EncodeStates::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper()), std::exception); } HWTEST_F(CommandEncodeStatesTest, givenCreatedSurfaceStateBufferWhenAllocationProvidedThenUseAllocationAsInput) { using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE; using SURFACE_TYPE = typename RENDER_SURFACE_STATE::SURFACE_TYPE; using AUXILIARY_SURFACE_MODE = typename RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE; void *stateBuffer = alignedMalloc(sizeof(RENDER_SURFACE_STATE), sizeof(RENDER_SURFACE_STATE)); ASSERT_NE(nullptr, stateBuffer); RENDER_SURFACE_STATE *state = reinterpret_cast(stateBuffer); memset(stateBuffer, 0, sizeof(RENDER_SURFACE_STATE)); size_t size = 0x1000; SURFACE_STATE_BUFFER_LENGTH length; void *cpuAddr = reinterpret_cast(0x4000); uint64_t gpuAddr = 0x4000u; size_t allocSize = size; length.Length = static_cast(allocSize - 1); GraphicsAllocation allocation(0, GraphicsAllocation::AllocationType::UNKNOWN, cpuAddr, gpuAddr, 0u, allocSize, MemoryPool::MemoryNull, 1); EncodeSurfaceState::encodeBuffer(stateBuffer, gpuAddr, allocSize, 1, false, false, false, 1u, &allocation, pDevice->getGmmHelper(), false, 1u); EXPECT_EQ(length.SurfaceState.Depth + 1u, state->getDepth()); EXPECT_EQ(length.SurfaceState.Width + 1u, state->getWidth()); EXPECT_EQ(length.SurfaceState.Height + 1u, state->getHeight()); EXPECT_EQ(gpuAddr, state->getSurfaceBaseAddress()); alignedFree(stateBuffer); } HWTEST_F(CommandEncodeStatesTest, givenCreatedSurfaceStateBufferWhenAllocationNotProvidedThenStateTypeIsNull) { using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE; void *stateBuffer = alignedMalloc(sizeof(RENDER_SURFACE_STATE), sizeof(RENDER_SURFACE_STATE)); ASSERT_NE(nullptr, stateBuffer); RENDER_SURFACE_STATE *state = reinterpret_cast(stateBuffer); memset(stateBuffer, 0, sizeof(RENDER_SURFACE_STATE)); size_t size = 0x1000; SURFACE_STATE_BUFFER_LENGTH length; uint64_t gpuAddr = 0; size_t allocSize = size; length.Length = static_cast(allocSize - 1); EncodeSurfaceState::encodeBuffer(stateBuffer, gpuAddr, allocSize, 1, true, false, false, 1u, nullptr, pDevice->getGmmHelper(), false, 1u); EXPECT_EQ(RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_NULL, state->getSurfaceType()); EXPECT_EQ(RENDER_SURFACE_STATE::COHERENCY_TYPE_IA_COHERENT, state->getCoherencyType()); alignedFree(stateBuffer); } HWTEST_F(CommandEncodeStatesTest, givenCreatedSurfaceStateBufferWhenGpuCoherencyProvidedThenCoherencyGpuIsSet) { using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE; void *stateBuffer = alignedMalloc(sizeof(RENDER_SURFACE_STATE), sizeof(RENDER_SURFACE_STATE)); ASSERT_NE(nullptr, stateBuffer); RENDER_SURFACE_STATE *state = reinterpret_cast(stateBuffer); memset(stateBuffer, 0, sizeof(RENDER_SURFACE_STATE)); size_t size = 0x1000; SURFACE_STATE_BUFFER_LENGTH length; uint64_t gpuAddr = 0; size_t allocSize = size; length.Length = static_cast(allocSize - 1); EncodeSurfaceState::encodeBuffer(stateBuffer, gpuAddr, allocSize, 1, false, false, false, 1u, nullptr, pDevice->getGmmHelper(), false, 1u); EXPECT_EQ(RENDER_SURFACE_STATE::COHERENCY_TYPE_GPU_COHERENT, state->getCoherencyType()); alignedFree(stateBuffer); } HWTEST_F(CommandEncodeStatesTest, givenCommandContainerWithDirtyHeapsWhenSetStateBaseAddressCalledThenStateBaseAddressAreNotSet) { using STATE_BASE_ADDRESS = typename FamilyType::STATE_BASE_ADDRESS; cmdContainer->dirtyHeaps = 0; cmdContainer->setHeapDirty(NEO::HeapType::DYNAMIC_STATE); cmdContainer->setHeapDirty(NEO::HeapType::INDIRECT_OBJECT); cmdContainer->setHeapDirty(NEO::HeapType::SURFACE_STATE); STATE_BASE_ADDRESS sba; EncodeStateBaseAddress::encode(*cmdContainer.get(), sba); auto dsh = cmdContainer->getIndirectHeap(NEO::HeapType::DYNAMIC_STATE); auto ioh = cmdContainer->getIndirectHeap(NEO::HeapType::INDIRECT_OBJECT); auto ssh = cmdContainer->getIndirectHeap(NEO::HeapType::SURFACE_STATE); GenCmdList commands; CmdParse::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed()); auto itorCmd = find(commands.begin(), commands.end()); auto pCmd = genCmdCast(*itorCmd); EXPECT_EQ(dsh->getHeapGpuBase(), pCmd->getDynamicStateBaseAddress()); EXPECT_EQ(ioh->getHeapGpuBase(), pCmd->getIndirectObjectBaseAddress()); EXPECT_EQ(ssh->getHeapGpuBase(), pCmd->getSurfaceStateBaseAddress()); EXPECT_EQ(sba.getDynamicStateBaseAddress(), pCmd->getDynamicStateBaseAddress()); EXPECT_EQ(sba.getIndirectObjectBaseAddress(), pCmd->getIndirectObjectBaseAddress()); EXPECT_EQ(sba.getSurfaceStateBaseAddress(), pCmd->getSurfaceStateBaseAddress()); } HWTEST_F(CommandEncodeStatesTest, givenCommandContainerWhenSetStateBaseAddressCalledThenStateBaseAddressIsSetCorrectly) { using STATE_BASE_ADDRESS = typename FamilyType::STATE_BASE_ADDRESS; cmdContainer->dirtyHeaps = 0; STATE_BASE_ADDRESS sba; EncodeStateBaseAddress::encode(*cmdContainer.get(), sba); auto dsh = cmdContainer->getIndirectHeap(NEO::HeapType::DYNAMIC_STATE); auto ssh = cmdContainer->getIndirectHeap(NEO::HeapType::SURFACE_STATE); GenCmdList commands; CmdParse::parseCommandBuffer(commands, ptrOffset(cmdContainer->getCommandStream()->getCpuBase(), 0), cmdContainer->getCommandStream()->getUsed()); auto itorCmd = find(commands.begin(), commands.end()); ASSERT_NE(itorCmd, commands.end()); auto cmd = genCmdCast(*itorCmd); EXPECT_NE(dsh->getHeapGpuBase(), cmd->getDynamicStateBaseAddress()); EXPECT_NE(ssh->getHeapGpuBase(), cmd->getSurfaceStateBaseAddress()); } HWTEST_F(CommandEncodeStatesTest, givenAnAlignedDstPtrThenNoAlignmentNorOffsetNeeded) { uintptr_t ptr = NEO::EncodeSurfaceState::getSurfaceBaseAddressAlignment() << 1; size_t offset = 0; NEO::EncodeSurfaceState::getSshAlignedPointer(ptr, offset); EXPECT_TRUE((ptr & (NEO::EncodeSurfaceState::getSurfaceBaseAddressAlignment() - 1)) == 0x0u); EXPECT_EQ(0u, offset); } HWTEST_F(CommandEncodeStatesTest, givenAnUnalignedDstPtrThenCorrectAlignedPtrAndOffsetAreCalculated) { uintptr_t ptr = NEO::EncodeSurfaceState::getSurfaceBaseAddressAlignment() >> 1; size_t offset = 0; NEO::EncodeSurfaceState::getSshAlignedPointer(ptr, offset); EXPECT_TRUE((ptr & (NEO::EncodeSurfaceState::getSurfaceBaseAddressAlignment() - 1)) == 0x0u); EXPECT_NE(0u, offset); }