/* * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/source/device_binary_format/patchtokens_decoder.h" #include "shared/source/helpers/string.h" #include "opencl/source/platform/platform.h" #include "opencl/source/program/program.h" #include "opencl/test/unit_test/fixtures/kernel_data_fixture.h" #include "opencl/test/unit_test/helpers/gtest_helpers.h" TEST_F(KernelDataTest, GivenKernelNameWhenBuildingThenProgramIsCorrect) { kernelName = "myTestKernel"; kernelNameSize = (uint32_t)alignUp(strlen(kernelName.c_str()) + 1, sizeof(uint32_t)); buildAndDecode(); } TEST_F(KernelDataTest, GivenHeapsWhenBuildingThenProgramIsCorrect) { char gshData[8] = "a"; char dshData[8] = "bb"; char sshData[8] = "ccc"; char kernelHeapData[8] = "dddd"; pGsh = gshData; pDsh = dshData; pSsh = sshData; pKernelHeap = kernelHeapData; gshSize = 4; dshSize = 4; sshSize = 4; kernelHeapSize = 4; buildAndDecode(); } TEST_F(KernelDataTest, GivenAllocateLocalSurfaceWhenBuildingThenProgramIsCorrect) { iOpenCL::SPatchAllocateLocalSurface allocateLocalSurface; allocateLocalSurface.Token = PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE; allocateLocalSurface.Size = sizeof(SPatchAllocateLocalSurface); allocateLocalSurface.Offset = 0; // think this is SSH offset for local memory when we used to have surface state for local memory allocateLocalSurface.TotalInlineLocalMemorySize = 4; // 4 bytes of local memory just for test pPatchList = &allocateLocalSurface; patchListSize = allocateLocalSurface.Size; buildAndDecode(); EXPECT_EQ_VAL(allocateLocalSurface.TotalInlineLocalMemorySize, pKernelInfo->kernelDescriptor.kernelAttributes.slmInlineSize); } TEST_F(KernelDataTest, GivenAllocateStatelessConstantMemoryWithInitWhenBuildingThenProgramIsCorrect) { iOpenCL::SPatchAllocateStatelessConstantMemorySurfaceWithInitialization allocateStatelessConstantMemoryWithInit; allocateStatelessConstantMemoryWithInit.Token = PATCH_TOKEN_ALLOCATE_STATELESS_CONSTANT_MEMORY_SURFACE_WITH_INITIALIZATION; allocateStatelessConstantMemoryWithInit.Size = sizeof(SPatchAllocateStatelessConstantMemorySurfaceWithInitialization); allocateStatelessConstantMemoryWithInit.ConstantBufferIndex = 0; allocateStatelessConstantMemoryWithInit.SurfaceStateHeapOffset = 0xddu; pPatchList = &allocateStatelessConstantMemoryWithInit; patchListSize = allocateStatelessConstantMemoryWithInit.Size; buildAndDecode(); EXPECT_EQ_VAL(0xddu, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.globalConstantsSurfaceAddress.bindful); } TEST_F(KernelDataTest, GivenAllocateStatelessGlobalMemoryWithInitWhenBuildingThenProgramIsCorrect) { iOpenCL::SPatchAllocateStatelessGlobalMemorySurfaceWithInitialization allocateStatelessGlobalMemoryWithInit; allocateStatelessGlobalMemoryWithInit.Token = PATCH_TOKEN_ALLOCATE_STATELESS_GLOBAL_MEMORY_SURFACE_WITH_INITIALIZATION; allocateStatelessGlobalMemoryWithInit.Size = sizeof(SPatchAllocateStatelessGlobalMemorySurfaceWithInitialization); allocateStatelessGlobalMemoryWithInit.GlobalBufferIndex = 0; allocateStatelessGlobalMemoryWithInit.SurfaceStateHeapOffset = 0xddu; pPatchList = &allocateStatelessGlobalMemoryWithInit; patchListSize = allocateStatelessGlobalMemoryWithInit.Size; buildAndDecode(); EXPECT_EQ_VAL(0xddu, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.globalVariablesSurfaceAddress.bindful); } TEST_F(KernelDataTest, GivenPrintfStringWhenBuildingThenProgramIsCorrect) { char stringValue[] = "%d\n"; size_t strSize = strlen(stringValue) + 1; iOpenCL::SPatchString printfString; printfString.Token = PATCH_TOKEN_STRING; printfString.Size = static_cast(sizeof(SPatchString) + strSize); printfString.Index = 0; printfString.StringSize = static_cast(strSize); iOpenCL::SPatchString emptyString; emptyString.Token = PATCH_TOKEN_STRING; emptyString.Size = static_cast(sizeof(SPatchString)); emptyString.Index = 1; emptyString.StringSize = 0; cl_char *pPrintfString = new cl_char[printfString.Size + emptyString.Size]; memcpy_s(pPrintfString, sizeof(SPatchString), &printfString, sizeof(SPatchString)); memcpy_s((cl_char *)pPrintfString + sizeof(printfString), strSize, stringValue, strSize); memcpy_s((cl_char *)pPrintfString + printfString.Size, emptyString.Size, &emptyString, emptyString.Size); pPatchList = (void *)pPrintfString; patchListSize = printfString.Size + emptyString.Size; buildAndDecode(); EXPECT_EQ_VAL(0, strcmp(stringValue, pKernelInfo->kernelDescriptor.kernelMetadata.printfStringsMap.find(0)->second.c_str())); delete[] pPrintfString; } TEST_F(KernelDataTest, GivenMediaVfeStateWhenBuildingThenProgramIsCorrect) { iOpenCL::SPatchMediaVFEState MediaVFEState; MediaVFEState.Token = PATCH_TOKEN_MEDIA_VFE_STATE; MediaVFEState.Size = sizeof(SPatchMediaVFEState); MediaVFEState.PerThreadScratchSpace = 1; // lets say 1KB of perThreadScratchSpace MediaVFEState.ScratchSpaceOffset = 0; pPatchList = &MediaVFEState; patchListSize = MediaVFEState.Size; buildAndDecode(); EXPECT_EQ_VAL(MediaVFEState.PerThreadScratchSpace, pKernelInfo->kernelDescriptor.kernelAttributes.perThreadScratchSize[0]); } TEST_F(KernelDataTest, WhenMediaVfeStateSlot1TokenIsParsedThenCorrectValuesAreSet) { iOpenCL::SPatchMediaVFEState MediaVFEState; MediaVFEState.Token = PATCH_TOKEN_MEDIA_VFE_STATE_SLOT1; MediaVFEState.Size = sizeof(SPatchMediaVFEState); MediaVFEState.PerThreadScratchSpace = 1; MediaVFEState.ScratchSpaceOffset = 0; pPatchList = &MediaVFEState; patchListSize = MediaVFEState.Size; buildAndDecode(); EXPECT_EQ_VAL(MediaVFEState.PerThreadScratchSpace, pKernelInfo->kernelDescriptor.kernelAttributes.perThreadScratchSize[1]); } TEST_F(KernelDataTest, GivenSyncBufferTokenWhenParsingProgramThenTokenIsFound) { SPatchAllocateSyncBuffer token; token.Token = PATCH_TOKEN_ALLOCATE_SYNC_BUFFER; token.Size = static_cast(sizeof(SPatchAllocateSyncBuffer)); token.SurfaceStateHeapOffset = 32; token.DataParamOffset = 1024; token.DataParamSize = 2; pPatchList = &token; patchListSize = token.Size; buildAndDecode(); EXPECT_TRUE(pKernelInfo->kernelDescriptor.kernelAttributes.flags.usesSyncBuffer); EXPECT_EQ(token.SurfaceStateHeapOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.syncBufferAddress.bindful); EXPECT_EQ(token.DataParamOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.syncBufferAddress.stateless); EXPECT_EQ(token.DataParamSize, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.syncBufferAddress.pointerSize); } TEST_F(KernelDataTest, GivenSamplerArgumentWhenBuildingThenProgramIsCorrect) { iOpenCL::SPatchSamplerKernelArgument samplerData; samplerData.Token = PATCH_TOKEN_SAMPLER_KERNEL_ARGUMENT; samplerData.ArgumentNumber = 3; samplerData.Offset = 0x40; samplerData.Type = iOpenCL::SAMPLER_OBJECT_TEXTURE; samplerData.Size = sizeof(samplerData); pPatchList = &samplerData; patchListSize = samplerData.Size; buildAndDecode(); EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(3).is()); EXPECT_EQ_VAL(samplerData.Offset, pKernelInfo->getArgDescriptorAt(3).as().bindful); } TEST_F(KernelDataTest, GivenAcceleratorArgumentWhenBuildingThenProgramIsCorrect) { iOpenCL::SPatchSamplerKernelArgument samplerData; samplerData.Token = PATCH_TOKEN_SAMPLER_KERNEL_ARGUMENT; samplerData.ArgumentNumber = 3; samplerData.Offset = 0x40; samplerData.Type = iOpenCL::SAMPLER_OBJECT_VME; samplerData.Size = sizeof(samplerData); pPatchList = &samplerData; patchListSize = samplerData.Size; buildAndDecode(); EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(3).is()); EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(3).getExtendedTypeInfo().isAccelerator); EXPECT_EQ_VAL(samplerData.Offset, pKernelInfo->getArgDescriptorAt(3).as().bindful); } TEST_F(KernelDataTest, GivenBindingTableStateWhenBuildingThenProgramIsCorrect) { iOpenCL::SPatchBindingTableState bindingTableState; bindingTableState.Token = PATCH_TOKEN_BINDING_TABLE_STATE; bindingTableState.Size = sizeof(SPatchBindingTableState); bindingTableState.Count = 0xaa; bindingTableState.Offset = 0xbb; bindingTableState.SurfaceStateOffset = 0xcc; pPatchList = &bindingTableState; patchListSize = bindingTableState.Size; buildAndDecode(); EXPECT_EQ_CONST(bindingTableState.Count, pKernelInfo->kernelDescriptor.payloadMappings.bindingTable.numEntries); EXPECT_EQ_CONST(bindingTableState.Offset, pKernelInfo->kernelDescriptor.payloadMappings.bindingTable.tableOffset); } TEST_F(KernelDataTest, GivenDataParameterStreamWhenBuildingThenProgramIsCorrect) { iOpenCL::SPatchDataParameterStream dataParameterStream; dataParameterStream.Token = PATCH_TOKEN_DATA_PARAMETER_STREAM; dataParameterStream.Size = sizeof(SPatchDataParameterStream); dataParameterStream.DataParameterStreamSize = 64; pPatchList = &dataParameterStream; patchListSize = dataParameterStream.Size; buildAndDecode(); EXPECT_EQ_CONST(dataParameterStream.DataParameterStreamSize, pKernelInfo->kernelDescriptor.kernelAttributes.crossThreadDataSize); } TEST_F(KernelDataTest, GivenExecutionEnvironmentNoReqdWorkGroupSizeWhenBuildingThenProgramIsCorrect) { iOpenCL::SPatchExecutionEnvironment executionEnvironment = {}; executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT; executionEnvironment.Size = sizeof(SPatchExecutionEnvironment); executionEnvironment.RequiredWorkGroupSizeX = 0; executionEnvironment.RequiredWorkGroupSizeY = 0; executionEnvironment.RequiredWorkGroupSizeZ = 0; executionEnvironment.LargestCompiledSIMDSize = 32; executionEnvironment.CompiledSubGroupsNumber = 0xaa; executionEnvironment.HasBarriers = false; executionEnvironment.DisableMidThreadPreemption = true; executionEnvironment.MayAccessUndeclaredResource = false; executionEnvironment.UsesFencesForReadWriteImages = false; executionEnvironment.UsesStatelessSpillFill = false; executionEnvironment.IsCoherent = true; executionEnvironment.IsInitializer = false; executionEnvironment.IsFinalizer = false; executionEnvironment.SubgroupIndependentForwardProgressRequired = false; executionEnvironment.CompiledForGreaterThan4GBBuffers = false; executionEnvironment.IndirectStatelessCount = 0; pPatchList = &executionEnvironment; patchListSize = executionEnvironment.Size; buildAndDecode(); EXPECT_EQ_VAL(0, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[0]); EXPECT_EQ_VAL(0, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[1]); EXPECT_EQ_VAL(0, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[2]); EXPECT_FALSE(pKernelInfo->hasIndirectStatelessAccess); } TEST_F(KernelDataTest, GivenExecutionEnvironmentWhenBuildingThenProgramIsCorrect) { iOpenCL::SPatchExecutionEnvironment executionEnvironment = {}; executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT; executionEnvironment.Size = sizeof(SPatchExecutionEnvironment); executionEnvironment.RequiredWorkGroupSizeX = 32; executionEnvironment.RequiredWorkGroupSizeY = 16; executionEnvironment.RequiredWorkGroupSizeZ = 8; executionEnvironment.LargestCompiledSIMDSize = 32; executionEnvironment.CompiledSubGroupsNumber = 0xaa; executionEnvironment.HasBarriers = false; executionEnvironment.DisableMidThreadPreemption = true; executionEnvironment.MayAccessUndeclaredResource = false; executionEnvironment.UsesFencesForReadWriteImages = false; executionEnvironment.UsesStatelessSpillFill = false; executionEnvironment.IsCoherent = true; executionEnvironment.IsInitializer = false; executionEnvironment.IsFinalizer = false; executionEnvironment.SubgroupIndependentForwardProgressRequired = false; executionEnvironment.CompiledForGreaterThan4GBBuffers = false; executionEnvironment.IndirectStatelessCount = 1; pPatchList = &executionEnvironment; patchListSize = executionEnvironment.Size; buildAndDecode(); EXPECT_EQ(32u, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[0]); EXPECT_EQ(16u, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[1]); EXPECT_EQ(8u, pKernelInfo->kernelDescriptor.kernelAttributes.requiredWorkgroupSize[2]); EXPECT_TRUE(pKernelInfo->hasIndirectStatelessAccess); EXPECT_EQ(KernelDescriptor::BindfulAndStateless, pKernelInfo->kernelDescriptor.kernelAttributes.bufferAddressingMode); } TEST_F(KernelDataTest, GivenExecutionEnvironmentCompiledForGreaterThan4gbBuffersWhenBuildingThenProgramIsCorrect) { iOpenCL::SPatchExecutionEnvironment executionEnvironment = {}; executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT; executionEnvironment.Size = sizeof(SPatchExecutionEnvironment); executionEnvironment.RequiredWorkGroupSizeX = 32; executionEnvironment.RequiredWorkGroupSizeY = 16; executionEnvironment.RequiredWorkGroupSizeZ = 8; executionEnvironment.LargestCompiledSIMDSize = 32; executionEnvironment.CompiledSubGroupsNumber = 0xaa; executionEnvironment.HasBarriers = false; executionEnvironment.DisableMidThreadPreemption = true; executionEnvironment.MayAccessUndeclaredResource = false; executionEnvironment.UsesFencesForReadWriteImages = false; executionEnvironment.UsesStatelessSpillFill = false; executionEnvironment.IsCoherent = true; executionEnvironment.IsInitializer = false; executionEnvironment.IsFinalizer = false; executionEnvironment.SubgroupIndependentForwardProgressRequired = false; executionEnvironment.CompiledForGreaterThan4GBBuffers = true; pPatchList = &executionEnvironment; patchListSize = executionEnvironment.Size; buildAndDecode(); EXPECT_EQ(KernelDescriptor::Stateless, pKernelInfo->kernelDescriptor.kernelAttributes.bufferAddressingMode); } TEST_F(KernelDataTest, WhenDecodingExecutionEnvironmentTokenThenWalkOrderIsForcedToXMajor) { iOpenCL::SPatchExecutionEnvironment executionEnvironment = {}; executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT; executionEnvironment.Size = sizeof(SPatchExecutionEnvironment); pPatchList = &executionEnvironment; patchListSize = executionEnvironment.Size; buildAndDecode(); const uint8_t expectedWalkOrder[3] = {0, 1, 2}; const uint8_t expectedDimsIds[3] = {0, 1, 2}; EXPECT_EQ(0, memcmp(expectedWalkOrder, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupWalkOrder, sizeof(expectedWalkOrder))); EXPECT_EQ(0, memcmp(expectedDimsIds, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupDimensionsOrder, sizeof(expectedDimsIds))); EXPECT_FALSE(pKernelInfo->kernelDescriptor.kernelAttributes.flags.requiresWorkgroupWalkOrder); } TEST_F(KernelDataTest, whenWorkgroupOrderIsSpecifiedViaPatchTokenThenProperWorkGroupOrderIsParsed) { iOpenCL::SPatchExecutionEnvironment executionEnvironment = {}; executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT; executionEnvironment.Size = sizeof(SPatchExecutionEnvironment); //dim0 : [0 : 1]; dim1 : [2 : 3]; dim2 : [4 : 5] executionEnvironment.WorkgroupWalkOrderDims = 1 | (2 << 2); pPatchList = &executionEnvironment; patchListSize = executionEnvironment.Size; buildAndDecode(); uint8_t expectedWalkOrder[3] = {1, 2, 0}; uint8_t expectedDimsIds[3] = {2, 0, 1}; EXPECT_EQ(0, memcmp(expectedWalkOrder, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupWalkOrder, sizeof(expectedWalkOrder))); EXPECT_EQ(0, memcmp(expectedDimsIds, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupDimensionsOrder, sizeof(expectedDimsIds))); EXPECT_TRUE(pKernelInfo->kernelDescriptor.kernelAttributes.flags.requiresWorkgroupWalkOrder); } TEST_F(KernelDataTest, whenWorkgroupOrderIsSpecifiedViaPatchToken2ThenProperWorkGroupOrderIsParsed) { iOpenCL::SPatchExecutionEnvironment executionEnvironment = {}; executionEnvironment.Token = PATCH_TOKEN_EXECUTION_ENVIRONMENT; executionEnvironment.Size = sizeof(SPatchExecutionEnvironment); //dim0 : [0 : 1]; dim1 : [2 : 3]; dim2 : [4 : 5] executionEnvironment.WorkgroupWalkOrderDims = 2 | (1 << 4); pPatchList = &executionEnvironment; patchListSize = executionEnvironment.Size; buildAndDecode(); uint8_t expectedWalkOrder[3] = {2, 0, 1}; uint8_t expectedDimsIds[3] = {1, 2, 0}; EXPECT_EQ(0, memcmp(expectedWalkOrder, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupWalkOrder, sizeof(expectedWalkOrder))); EXPECT_EQ(0, memcmp(expectedDimsIds, pKernelInfo->kernelDescriptor.kernelAttributes.workgroupDimensionsOrder, sizeof(expectedDimsIds))); EXPECT_TRUE(pKernelInfo->kernelDescriptor.kernelAttributes.flags.requiresWorkgroupWalkOrder); } // Test all the different data parameters with the same "made up" data class DataParameterTest : public KernelDataTest, public testing::WithParamInterface {}; TEST_P(DataParameterTest, GivenTokenTypeWhenBuildingThenProgramIsCorrect) { SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = GetParam(); dataParameterToken.ArgumentNumber = 1; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; dataParameterToken.Offset = 0; dataParameterToken.SourceOffset = 8; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); if (DATA_PARAMETER_KERNEL_ARGUMENT == GetParam()) { ASSERT_NE(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); EXPECT_EQ(dataParameterToken.ArgumentNumber, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments[0].argNum); EXPECT_EQ(dataParameterToken.Offset, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments[0].byValueElement.offset); EXPECT_EQ(dataParameterToken.SourceOffset, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments[0].byValueElement.sourceOffset); EXPECT_EQ(dataParameterToken.DataSize, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments[0].byValueElement.size); } else { EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); } if (pKernelInfo->kernelDescriptor.payloadMappings.explicitArgs.size() > 0) { EXPECT_EQ(dataParameterToken.ArgumentNumber + 1, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgs.size()); const auto &arg = pKernelInfo->getArgDescriptorAt(dataParameterToken.ArgumentNumber); if (arg.is()) { const auto &argAsPtr = arg.as(); EXPECT_EQ(GetParam() == DATA_PARAMETER_BUFFER_STATEFUL, argAsPtr.isPureStateful()); } } } // note that we start at '2' because we test kernel arg tokens elsewhere INSTANTIATE_TEST_CASE_P(DataParameterTests, DataParameterTest, testing::Range(2u, static_cast(NUM_DATA_PARAMETER_TOKENS))); class KernelDataParameterTest : public KernelDataTest {}; TEST_F(KernelDataParameterTest, GivenDataParameterBufferOffsetWhenBuildingThenProgramIsCorrect) { SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_BUFFER_OFFSET; dataParameterToken.ArgumentNumber = 1; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; dataParameterToken.Offset = 128; dataParameterToken.SourceOffset = 8; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgs.size()); EXPECT_EQ_VAL(pKernelInfo->getArgDescriptorAt(1).as().bufferOffset, dataParameterToken.Offset) } TEST_F(KernelDataParameterTest, givenDataParameterBufferStatefulWhenDecodingThenSetArgAsPureStateful) { SPatchDataParameterBuffer dataParameterToken = {}; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_BUFFER_STATEFUL; dataParameterToken.ArgumentNumber = 1; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(1).as().isPureStateful()); } TEST_F(KernelDataParameterTest, givenUnknownDataParameterWhenDecodedThenParameterIsIgnored) { SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = NUM_DATA_PARAMETER_TOKENS + 1; dataParameterToken.ArgumentNumber = 1; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; dataParameterToken.Offset = 0; dataParameterToken.SourceOffset = 8; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ_VAL(0u, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); } TEST_F(KernelDataTest, GivenDataParameterSumOfLocalMemoryObjectArgumentSizesWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 16; uint32_t offsetCrossThread = 4; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_SUM_OF_LOCAL_MEMORY_OBJECT_ARGUMENT_SIZES; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetCrossThread; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); const auto &argAsPtr = pKernelInfo->getArgDescriptorAt(argumentNumber).as(); EXPECT_EQ(alignment, argAsPtr.requiredSlmAlignment); ASSERT_EQ(offsetCrossThread, argAsPtr.slmOffset); } TEST_F(KernelDataTest, GivenDataParameterImageWidthWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 16; uint32_t offsetImgWidth = 4; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_IMAGE_WIDTH; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetImgWidth; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetImgWidth, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.imgWidth); } TEST_F(KernelDataTest, GivenDataParameterImageHeightWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 16; uint32_t offsetImgHeight = 8; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_IMAGE_HEIGHT; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetImgHeight; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetImgHeight, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.imgHeight); } TEST_F(KernelDataTest, GivenDataParameterImageDepthWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 16; uint32_t offsetImgDepth = 12; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_IMAGE_DEPTH; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetImgDepth; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetImgDepth, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.imgDepth); } TEST_F(KernelDataTest, GivenDataParameterImageNumSamplersWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 16; uint32_t offsetNumSamples = 60; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_IMAGE_NUM_SAMPLES; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetNumSamples; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetNumSamples, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.numSamples); } TEST_F(KernelDataTest, GivenDataParameterImageNumMipLevelsWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 16; uint32_t offsetNumMipLevels = 60; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_IMAGE_NUM_MIP_LEVELS; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetNumMipLevels; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetNumMipLevels, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.numMipLevels); } TEST_F(KernelDataTest, givenFlatImageDataParamTokenWhenDecodingThenSetAllOffsets) { uint32_t argumentNumber = 1; uint32_t alignment = 16; auto testToken = [&](iOpenCL::DATA_PARAMETER_TOKEN token, uint32_t offsetToken) { { // reset program if (pKernelData) { alignedFree(pKernelData); } program = std::make_unique(pContext, false, toClDeviceVector(*pContext->getDevice(0))); } SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = token; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetToken; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); }; testToken(iOpenCL::DATA_PARAMETER_TOKEN::DATA_PARAMETER_FLAT_IMAGE_BASEOFFSET, 10u); EXPECT_EQ(10u, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.flatBaseOffset); testToken(iOpenCL::DATA_PARAMETER_TOKEN::DATA_PARAMETER_FLAT_IMAGE_WIDTH, 14u); EXPECT_EQ(14u, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.flatWidth); testToken(iOpenCL::DATA_PARAMETER_TOKEN::DATA_PARAMETER_FLAT_IMAGE_HEIGHT, 16u); EXPECT_EQ(16u, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.flatHeight); testToken(iOpenCL::DATA_PARAMETER_TOKEN::DATA_PARAMETER_FLAT_IMAGE_PITCH, 18u); EXPECT_EQ(18u, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.flatPitch); } TEST_F(KernelDataTest, GivenDataParameterImageDataTypeWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 16; uint32_t offsetChannelDataType = 52; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_IMAGE_CHANNEL_DATA_TYPE; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetChannelDataType; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetChannelDataType, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.channelDataType); } TEST_F(KernelDataTest, GivenDataParameterImageChannelOrderWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 16; uint32_t offsetChannelOrder = 56; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_IMAGE_CHANNEL_ORDER; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetChannelOrder; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetChannelOrder, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.channelOrder); } TEST_F(KernelDataTest, GivenDataParameterImageArraySizeWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 16; uint32_t offsetImageArraySize = 60; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_IMAGE_ARRAY_SIZE; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetImageArraySize; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetImageArraySize, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.arraySize); } TEST_F(KernelDataTest, GivenDataParameterWorkDimensionsWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 16; uint32_t offsetWorkDim = 12; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_WORK_DIMENSIONS; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetWorkDim; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); EXPECT_EQ(0U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetWorkDim, pKernelInfo->kernelDescriptor.payloadMappings.dispatchTraits.workDim); } TEST_F(KernelDataTest, GivenDataParameterSimdSizeWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 17; uint32_t alignment = 16; uint32_t offsetSimdSize = 16; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_SIMD_SIZE; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetSimdSize; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); EXPECT_EQ(0u, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetSimdSize, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.simdSize); } TEST_F(KernelDataTest, GivenParameterPrivateMemoryStatelessSizeWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 17; uint32_t alignment = 16; uint32_t offset = 16; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_PRIVATE_MEMORY_STATELESS_SIZE; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offset; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); EXPECT_EQ(0u, pKernelInfo->getExplicitArgs().size()); } TEST_F(KernelDataTest, GivenDataParameterLocalMemoryStatelessWindowSizeWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 17; uint32_t alignment = 16; uint32_t offset = 16; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_LOCAL_MEMORY_STATELESS_WINDOW_SIZE; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offset; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); EXPECT_EQ(0u, pKernelInfo->getExplicitArgs().size()); } TEST_F(KernelDataTest, GivenDataParameterLocalMemoryStatelessWindowStartAddressWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 17; uint32_t alignment = 16; uint32_t offset = 16; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_LOCAL_MEMORY_STATELESS_WINDOW_START_ADDRESS; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offset; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); EXPECT_EQ(0u, pKernelInfo->getExplicitArgs().size()); } TEST_F(KernelDataTest, GivenDataParameterNumWorkGroupsWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 4; uint32_t offsetNumWorkGroups[3] = {0, 4, 8}; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_NUM_WORK_GROUPS; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetNumWorkGroups[argumentNumber]; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = argumentNumber * alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); EXPECT_EQ(0U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetNumWorkGroups[argumentNumber], pKernelInfo->kernelDescriptor.payloadMappings.dispatchTraits.numWorkGroups[argumentNumber]); } TEST_F(KernelDataTest, GivenDataParameterMaxWorkgroupSizeWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 4; uint32_t offsetMaxWorkGroupSize = 4; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_MAX_WORKGROUP_SIZE; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetMaxWorkGroupSize; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); EXPECT_EQ(0U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(offsetMaxWorkGroupSize, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.maxWorkGroupSize); } TEST_F(KernelDataTest, GivenDataParameterSamplerAddressModeWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 0; uint32_t dataOffset = 20; uint32_t dataSize = sizeof(uint32_t); SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_SAMPLER_ADDRESS_MODE; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = dataOffset; dataParameterToken.DataSize = dataSize; dataParameterToken.SourceOffset = 0; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(1U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(dataOffset, pKernelInfo->getArgDescriptorAt(0).as().metadataPayload.samplerAddressingMode); } TEST_F(KernelDataTest, GivenDataParameterSamplerCoordinateSnapWaIsRequiredThenKernelInfoIsCorrect) { uint32_t argumentNumber = 1; uint32_t dataOffset = 20; uint32_t dataSize = sizeof(uint32_t); SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_SAMPLER_COORDINATE_SNAP_WA_REQUIRED; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = dataOffset; dataParameterToken.DataSize = dataSize; dataParameterToken.SourceOffset = 0; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(dataOffset, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.samplerSnapWa); } TEST_F(KernelDataTest, GivenDataParameterSamplerNormalizedCoordsThenKernelInfoIsCorrect) { uint32_t argumentNumber = 1; uint32_t dataOffset = 20; uint32_t dataSize = sizeof(uint32_t); SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_SAMPLER_NORMALIZED_COORDS; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = dataOffset; dataParameterToken.DataSize = dataSize; dataParameterToken.SourceOffset = 0; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ(dataOffset, pKernelInfo->getArgDescriptorAt(argumentNumber).as().metadataPayload.samplerNormalizedCoords); } TEST_F(KernelDataTest, GivenDataParameterKernelArgumentWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 0; uint32_t dataOffset = 20; uint32_t dataSize = sizeof(uint32_t); SPatchDataParameterBuffer dataParameterTokens[2]; dataParameterTokens[0].Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterTokens[0].Size = sizeof(SPatchDataParameterBuffer); dataParameterTokens[0].Type = DATA_PARAMETER_KERNEL_ARGUMENT; dataParameterTokens[0].ArgumentNumber = argumentNumber; dataParameterTokens[0].Offset = dataOffset + dataSize * 0; dataParameterTokens[0].DataSize = dataSize; dataParameterTokens[0].SourceOffset = 0; dataParameterTokens[0].LocationIndex = 0x0; dataParameterTokens[0].LocationIndex2 = 0x0; dataParameterTokens[1].Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterTokens[1].Size = sizeof(SPatchDataParameterBuffer); dataParameterTokens[1].Type = DATA_PARAMETER_KERNEL_ARGUMENT; dataParameterTokens[1].ArgumentNumber = argumentNumber; dataParameterTokens[1].Offset = dataOffset + dataSize * 1; dataParameterTokens[1].DataSize = dataSize; dataParameterTokens[1].SourceOffset = dataSize * 1; dataParameterTokens[1].LocationIndex = 0x0; dataParameterTokens[1].LocationIndex2 = 0x0; pPatchList = &dataParameterTokens[0]; patchListSize = dataParameterTokens[0].Size * (sizeof(dataParameterTokens) / sizeof(SPatchDataParameterBuffer)); buildAndDecode(); ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(1u, pKernelInfo->getExplicitArgs().size()); auto &elements = pKernelInfo->getArgDescriptorAt(0).as().elements; ASSERT_EQ(2u, elements.size()); EXPECT_EQ(dataSize, elements[0].size); EXPECT_EQ(dataOffset + dataSize * 0, elements[0].offset); EXPECT_EQ(dataSize, elements[1].size); EXPECT_EQ(dataOffset + dataSize * 1, elements[1].offset); } TEST_F(KernelDataTest, GivenPatchTokenAllocateLocalSurfaceWhenBuildingThenProgramIsCorrect) { SPatchAllocateLocalSurface slmToken; slmToken.TotalInlineLocalMemorySize = 1024; slmToken.Size = sizeof(SPatchAllocateLocalSurface); slmToken.Token = PATCH_TOKEN_ALLOCATE_LOCAL_SURFACE; pPatchList = &slmToken; patchListSize = slmToken.Size; buildAndDecode(); EXPECT_EQ(1024u, pKernelInfo->kernelDescriptor.kernelAttributes.slmInlineSize); } TEST_F(KernelDataTest, GivenPatchTokenAllocateStatelessPrintfSurfaceWhenBuildingThenProgramIsCorrect) { SPatchAllocateStatelessPrintfSurface printfSurface; printfSurface.Token = PATCH_TOKEN_ALLOCATE_STATELESS_PRINTF_SURFACE; printfSurface.Size = static_cast(sizeof(SPatchAllocateStatelessPrintfSurface)); printfSurface.PrintfSurfaceIndex = 33; printfSurface.SurfaceStateHeapOffset = 0x1FF0; printfSurface.DataParamOffset = 0x3FF0; printfSurface.DataParamSize = 0xFF; pPatchList = &printfSurface; patchListSize = printfSurface.Size; buildAndDecode(); EXPECT_TRUE(pKernelInfo->kernelDescriptor.kernelAttributes.flags.usesPrintf); EXPECT_EQ(printfSurface.SurfaceStateHeapOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.printfSurfaceAddress.bindful); EXPECT_EQ(printfSurface.DataParamOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.printfSurfaceAddress.stateless); EXPECT_EQ(printfSurface.DataParamSize, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.printfSurfaceAddress.pointerSize); } TEST_F(KernelDataTest, GivenPatchTokenSamplerStateArrayWhenBuildingThenProgramIsCorrect) { SPatchSamplerStateArray token; token.Token = PATCH_TOKEN_SAMPLER_STATE_ARRAY; token.Size = static_cast(sizeof(SPatchSamplerStateArray)); token.Offset = 33; token.Count = 0xF0; token.BorderColorOffset = 0x3FF0; pPatchList = &token; patchListSize = token.Size; buildAndDecode(); EXPECT_EQ_VAL(token.Offset, pKernelInfo->kernelDescriptor.payloadMappings.samplerTable.tableOffset); EXPECT_EQ_VAL(token.Count, pKernelInfo->kernelDescriptor.payloadMappings.samplerTable.numSamplers); EXPECT_EQ_VAL(token.BorderColorOffset, pKernelInfo->kernelDescriptor.payloadMappings.samplerTable.borderColor); } TEST_F(KernelDataTest, GivenPatchTokenAllocateStatelessPrivateMemoryWhenBuildingThenProgramIsCorrect) { SPatchAllocateStatelessPrivateSurface token; token.Token = PATCH_TOKEN_ALLOCATE_STATELESS_PRIVATE_MEMORY; token.Size = static_cast(sizeof(SPatchAllocateStatelessPrivateSurface)); token.SurfaceStateHeapOffset = 64; token.DataParamOffset = 40; token.DataParamSize = 8; token.PerThreadPrivateMemorySize = 112; pPatchList = &token; patchListSize = token.Size; buildAndDecode(); EXPECT_EQ_VAL(token.SurfaceStateHeapOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.privateMemoryAddress.bindful); EXPECT_EQ_VAL(token.DataParamOffset, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.privateMemoryAddress.stateless); EXPECT_EQ_VAL(token.DataParamSize, pKernelInfo->kernelDescriptor.payloadMappings.implicitArgs.privateMemoryAddress.pointerSize); EXPECT_EQ_VAL(PatchTokenBinary::getPerHwThreadPrivateSurfaceSize(token, pKernelInfo->kernelDescriptor.kernelAttributes.simdSize), pKernelInfo->kernelDescriptor.kernelAttributes.perHwThreadPrivateMemorySize); } TEST_F(KernelDataTest, GivenDataParameterVmeMbBlockTypeWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 16; uint32_t offsetVmeMbBlockType = 0xaa; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_VME_MB_BLOCK_TYPE; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetVmeMbBlockType; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(argumentNumber).getExtendedTypeInfo().hasVmeExtendedDescriptor); ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors.size()); auto vmeArgDesc = reinterpret_cast(pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors[1].get()); EXPECT_EQ(offsetVmeMbBlockType, vmeArgDesc->mbBlockType); } TEST_F(KernelDataTest, GivenDataParameterDataVmeSubpixelModeWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 17; uint32_t offsetVmeSubpixelMode = 0xab; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_VME_SUBPIXEL_MODE; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetVmeSubpixelMode; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(argumentNumber).getExtendedTypeInfo().hasVmeExtendedDescriptor); ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors.size()); auto vmeArgDesc = reinterpret_cast(pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors[1].get()); EXPECT_EQ(offsetVmeSubpixelMode, vmeArgDesc->subpixelMode); } TEST_F(KernelDataTest, GivenDataParameterVmeSadAdjustModeWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 18; uint32_t offsetVmeSadAdjustMode = 0xac; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_VME_SAD_ADJUST_MODE; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetVmeSadAdjustMode; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(argumentNumber).getExtendedTypeInfo().hasVmeExtendedDescriptor); ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors.size()); auto vmeArgDesc = reinterpret_cast(pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors[1].get()); EXPECT_EQ(offsetVmeSadAdjustMode, vmeArgDesc->sadAdjustMode); } TEST_F(KernelDataTest, GivenDataParameterVmeSearchPathTypeWhenBuildingThenProgramIsCorrect) { uint32_t argumentNumber = 1; uint32_t alignment = 19; uint32_t offsetVmeSearchPathType = 0xad; SPatchDataParameterBuffer dataParameterToken; dataParameterToken.Token = PATCH_TOKEN_DATA_PARAMETER_BUFFER; dataParameterToken.Size = sizeof(SPatchDataParameterBuffer); dataParameterToken.Type = DATA_PARAMETER_VME_SEARCH_PATH_TYPE; dataParameterToken.ArgumentNumber = argumentNumber; dataParameterToken.Offset = offsetVmeSearchPathType; dataParameterToken.DataSize = sizeof(uint32_t); dataParameterToken.SourceOffset = alignment; dataParameterToken.LocationIndex = 0x0; dataParameterToken.LocationIndex2 = 0x0; pPatchList = &dataParameterToken; patchListSize = dataParameterToken.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); ASSERT_EQ(2U, pKernelInfo->getExplicitArgs().size()); EXPECT_TRUE(pKernelInfo->getArgDescriptorAt(argumentNumber).getExtendedTypeInfo().hasVmeExtendedDescriptor); ASSERT_EQ(2U, pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors.size()); auto vmeArgDesc = reinterpret_cast(pKernelInfo->kernelDescriptor.payloadMappings.explicitArgsExtendedDescriptors[1].get()); EXPECT_EQ(offsetVmeSearchPathType, vmeArgDesc->searchPathType); } TEST_F(KernelDataTest, GivenPatchTokenStateSipWhenBuildingThenProgramIsCorrect) { SPatchStateSIP token; token.Token = PATCH_TOKEN_STATE_SIP; token.Size = static_cast(sizeof(SPatchStateSIP)); token.SystemKernelOffset = 33; pPatchList = &token; patchListSize = token.Size; buildAndDecode(); EXPECT_EQ(0U, pKernelInfo->kernelDescriptor.kernelMetadata.allByValueKernelArguments.size()); EXPECT_EQ(0U, pKernelInfo->getExplicitArgs().size()); EXPECT_EQ_VAL(token.SystemKernelOffset, pKernelInfo->systemKernelOffset); } TEST_F(KernelDataTest, givenSymbolTablePatchTokenThenLinkerInputIsCreated) { SPatchFunctionTableInfo token; token.Token = PATCH_TOKEN_PROGRAM_SYMBOL_TABLE; token.Size = static_cast(sizeof(SPatchFunctionTableInfo)); token.NumEntries = 0; pPatchList = &token; patchListSize = token.Size; buildAndDecode(); EXPECT_NE(nullptr, program->getLinkerInput(pContext->getDevice(0)->getRootDeviceIndex())); } TEST_F(KernelDataTest, givenRelocationTablePatchTokenThenLinkerInputIsCreated) { SPatchFunctionTableInfo token; token.Token = PATCH_TOKEN_PROGRAM_RELOCATION_TABLE; token.Size = static_cast(sizeof(SPatchFunctionTableInfo)); token.NumEntries = 0; pPatchList = &token; patchListSize = token.Size; buildAndDecode(); EXPECT_NE(nullptr, program->getLinkerInput(pContext->getDevice(0)->getRootDeviceIndex())); }