feat(zebin): support data const/global buffer arg
Add support for kernel payload arguments describing data const and data global buffers in zeInfo. Argument contains: * Offset in cross thread data where buffer's address should be written to. To be removed later. Relocations should be used instead. * Index in binding table where corresponding Surface State should be present. Required for bindful access to data buffers. Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
This commit is contained in:
parent
46136cd2f6
commit
b2a51146a5
|
@ -201,6 +201,7 @@ inline constexpr ConstStringRef filterMode("sampler_desc_filtermode");
|
|||
inline constexpr ConstStringRef normalized("sampler_desc_normalized");
|
||||
inline constexpr ConstStringRef isPipe("is_pipe");
|
||||
inline constexpr ConstStringRef isPtr("is_ptr");
|
||||
inline constexpr ConstStringRef btiValue("bti_value");
|
||||
|
||||
namespace ArgType {
|
||||
inline constexpr ConstStringRef localSize("local_size");
|
||||
|
@ -218,6 +219,8 @@ inline constexpr ConstStringRef workDimensions("work_dimensions");
|
|||
inline constexpr ConstStringRef implicitArgBuffer("implicit_arg_buffer");
|
||||
inline constexpr ConstStringRef syncBuffer("sync_buffer");
|
||||
inline constexpr ConstStringRef rtGlobalBuffer("rt_global_buffer");
|
||||
inline constexpr ConstStringRef dataConstBuffer("const_base");
|
||||
inline constexpr ConstStringRef dataGlobalBuffer("global_base");
|
||||
|
||||
namespace Image {
|
||||
inline constexpr ConstStringRef width("image_width");
|
||||
|
@ -579,6 +582,8 @@ enum ArgType : uint8_t {
|
|||
ArgTypeVmeSearchPathType,
|
||||
ArgTypeSyncBuffer,
|
||||
ArgTypeRtGlobalBuffer,
|
||||
ArgTypeDataConstBuffer,
|
||||
ArgTypeDataGlobalBuffer,
|
||||
ArgTypeMax
|
||||
};
|
||||
|
||||
|
@ -667,7 +672,7 @@ enum SamplerType : uint8_t {
|
|||
};
|
||||
|
||||
using ArgTypeT = ArgType;
|
||||
using OffseT = int32_t;
|
||||
using OffsetT = int32_t;
|
||||
using SourceOffseT = int32_t;
|
||||
using SizeT = int32_t;
|
||||
using ArgIndexT = int32_t;
|
||||
|
@ -676,28 +681,32 @@ using AddrspaceT = AddressSpace;
|
|||
using AccessTypeT = AccessType;
|
||||
using SlmAlignmentT = uint8_t;
|
||||
using SamplerIndexT = int32_t;
|
||||
using BtiValueT = int32_t;
|
||||
|
||||
namespace Defaults {
|
||||
inline constexpr ArgIndexT argIndex = -1;
|
||||
inline constexpr SlmAlignmentT slmArgAlignment = 16U;
|
||||
inline constexpr SamplerIndexT samplerIndex = -1;
|
||||
inline constexpr SourceOffseT sourceOffset = -1;
|
||||
inline constexpr OffsetT offset = -1;
|
||||
inline constexpr BtiValueT btiValue = -1;
|
||||
} // namespace Defaults
|
||||
|
||||
struct PayloadArgumentBaseT {
|
||||
ArgTypeT argType = ArgTypeUnknown;
|
||||
OffseT offset = 0;
|
||||
OffsetT offset = Defaults::offset;
|
||||
SourceOffseT sourceOffset = Defaults::sourceOffset;
|
||||
SizeT size = 0;
|
||||
ArgIndexT argIndex = Defaults::argIndex;
|
||||
BtiValueT btiValue = Defaults::btiValue;
|
||||
AddrmodeT addrmode = MemoryAddressingModeUnknown;
|
||||
AddrspaceT addrspace = AddressSpaceUnknown;
|
||||
AccessTypeT accessType = AccessTypeUnknown;
|
||||
SamplerIndexT samplerIndex = Defaults::samplerIndex;
|
||||
SlmAlignmentT slmArgAlignment = Defaults::slmArgAlignment;
|
||||
ImageType imageType = ImageTypeUnknown;
|
||||
bool imageTransformable = false;
|
||||
SamplerType samplerType = SamplerTypeUnknown;
|
||||
bool imageTransformable = false;
|
||||
bool isPipe = false;
|
||||
bool isPtr = false;
|
||||
};
|
||||
|
|
|
@ -22,7 +22,7 @@ using namespace Tags::Kernel::PayloadArgument::ArgType::Sampler::Vme;
|
|||
using ArgType = Types::Kernel::ArgType;
|
||||
|
||||
inline constexpr ConstStringRef name = "argument type";
|
||||
inline constexpr LookupArray<ConstStringRef, ArgType, 36> lookup({{{packedLocalIds, ArgType::ArgTypePackedLocalIds},
|
||||
inline constexpr LookupArray<ConstStringRef, ArgType, 38> lookup({{{packedLocalIds, ArgType::ArgTypePackedLocalIds},
|
||||
{localId, ArgType::ArgTypeLocalId},
|
||||
{localSize, ArgType::ArgTypeLocalSize},
|
||||
{groupCount, ArgType::ArgTypeGroupCount},
|
||||
|
@ -57,7 +57,9 @@ inline constexpr LookupArray<ConstStringRef, ArgType, 36> lookup({{{packedLocalI
|
|||
{sadAdjustMode, ArgType::ArgTypeVmeSadAdjustMode},
|
||||
{searchPathType, ArgType::ArgTypeVmeSearchPathType},
|
||||
{syncBuffer, ArgType::ArgTypeSyncBuffer},
|
||||
{rtGlobalBuffer, ArgType::ArgTypeRtGlobalBuffer}}});
|
||||
{rtGlobalBuffer, ArgType::ArgTypeRtGlobalBuffer},
|
||||
{dataConstBuffer, ArgType::ArgTypeDataConstBuffer},
|
||||
{dataGlobalBuffer, ArgType::ArgTypeDataGlobalBuffer}}});
|
||||
static_assert(lookup.size() == ArgType::ArgTypeMax - 1, "Every enum field must be present");
|
||||
} // namespace ArgType
|
||||
|
||||
|
|
|
@ -593,6 +593,8 @@ DecodeError readZeInfoPayloadArguments(const NEO::Yaml::YamlParser &parser, cons
|
|||
validPayload &= readZeInfoValueChecked(parser, payloadArgumentMemberNd, payloadArgMetadata.isPipe, context, outErrReason);
|
||||
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::PayloadArgument::isPtr == key) {
|
||||
validPayload &= readZeInfoValueChecked(parser, payloadArgumentMemberNd, payloadArgMetadata.isPtr, context, outErrReason);
|
||||
} else if (NEO::Elf::ZebinKernelMetadata::Tags::Kernel::PayloadArgument::btiValue == key) {
|
||||
validPayload &= readZeInfoValueChecked(parser, payloadArgumentMemberNd, payloadArgMetadata.btiValue, context, outErrReason);
|
||||
} else {
|
||||
outWarning.append("DeviceBinaryFormat::Zebin::" + NEO::Elf::SectionsNamesZebin::zeInfo.str() + " : Unknown entry \"" + key.str() + "\" for payload argument in context of " + context.str() + "\n");
|
||||
}
|
||||
|
@ -720,6 +722,15 @@ bool setVecArgIndicesBasedOnSize(CrossThreadDataOffset (&vec)[Len], size_t vecSi
|
|||
return true;
|
||||
}
|
||||
|
||||
bool setSSHOffsetBasedOnBti(SurfaceStateHeapOffset &offset, Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::BtiValueT bti) {
|
||||
if (bti < 0) {
|
||||
return false;
|
||||
}
|
||||
constexpr auto surfaceStateSize = 64U;
|
||||
offset = surfaceStateSize * bti;
|
||||
return true;
|
||||
}
|
||||
|
||||
NEO::DecodeError populateArgDescriptor(const NEO::Elf::ZebinKernelMetadata::Types::Kernel::PerThreadPayloadArgument::PerThreadPayloadArgumentBaseT &src, NEO::KernelDescriptor &dst, uint32_t grfSize,
|
||||
std::string &outErrReason, std::string &outWarning) {
|
||||
switch (src.argType) {
|
||||
|
@ -791,7 +802,9 @@ NEO::DecodeError populateArgDescriptor(const NEO::Elf::ZebinKernelMetadata::Type
|
|||
|
||||
NEO::DecodeError populateArgDescriptor(const NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::PayloadArgumentBaseT &src, NEO::KernelDescriptor &dst, uint32_t &crossThreadDataSize,
|
||||
std::string &outErrReason, std::string &outWarning) {
|
||||
if (src.offset != Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::Defaults::offset) {
|
||||
crossThreadDataSize = std::max<uint32_t>(crossThreadDataSize, src.offset + src.size);
|
||||
}
|
||||
|
||||
auto &explicitArgs = dst.payloadMappings.explicitArgs;
|
||||
auto getVmeDescriptor = [&src, &dst]() {
|
||||
|
@ -1104,6 +1117,28 @@ NEO::DecodeError populateArgDescriptor(const NEO::Elf::ZebinKernelMetadata::Type
|
|||
dst.payloadMappings.implicitArgs.rtDispatchGlobals.stateless = src.offset;
|
||||
dst.kernelAttributes.flags.hasRTCalls = true;
|
||||
break;
|
||||
|
||||
case NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeDataConstBuffer: {
|
||||
if (src.offset != Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::Defaults::offset) {
|
||||
dst.payloadMappings.implicitArgs.globalConstantsSurfaceAddress.stateless = src.offset;
|
||||
dst.payloadMappings.implicitArgs.globalConstantsSurfaceAddress.pointerSize = src.size;
|
||||
}
|
||||
if (false == setSSHOffsetBasedOnBti(dst.payloadMappings.implicitArgs.globalConstantsSurfaceAddress.bindful, src.btiValue)) {
|
||||
outErrReason.append("DeviceBinaryFormat::Zebin : Invalid bti for argument of type " + NEO::Elf::ZebinKernelMetadata::Tags::Kernel::PayloadArgument::ArgType::dataConstBuffer.str() + " in context of : " + dst.kernelMetadata.kernelName + "\n");
|
||||
return DecodeError::InvalidBinary;
|
||||
}
|
||||
} break;
|
||||
|
||||
case NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeDataGlobalBuffer: {
|
||||
if (src.offset != Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::Defaults::offset) {
|
||||
dst.payloadMappings.implicitArgs.globalVariablesSurfaceAddress.stateless = src.offset;
|
||||
dst.payloadMappings.implicitArgs.globalVariablesSurfaceAddress.pointerSize = src.size;
|
||||
}
|
||||
if (false == setSSHOffsetBasedOnBti(dst.payloadMappings.implicitArgs.globalVariablesSurfaceAddress.bindful, src.btiValue)) {
|
||||
outErrReason.append("DeviceBinaryFormat::Zebin : Invalid bti for argument of type " + NEO::Elf::ZebinKernelMetadata::Tags::Kernel::PayloadArgument::ArgType::dataGlobalBuffer.str() + " in context of : " + dst.kernelMetadata.kernelName + "\n");
|
||||
return DecodeError::InvalidBinary;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
return DecodeError::Success;
|
||||
|
|
|
@ -2181,6 +2181,10 @@ kernels:
|
|||
size : 4
|
||||
arg_index : 2
|
||||
is_ptr : true
|
||||
- arg_type : const_base
|
||||
offset : 32
|
||||
size : 8
|
||||
bti_value : 1
|
||||
...
|
||||
)===";
|
||||
|
||||
|
@ -2200,7 +2204,7 @@ kernels:
|
|||
EXPECT_EQ(NEO::DecodeError::Success, err);
|
||||
EXPECT_TRUE(errors.empty()) << errors;
|
||||
EXPECT_TRUE(warnings.empty()) << warnings;
|
||||
ASSERT_EQ(2U, args.size());
|
||||
ASSERT_EQ(3U, args.size());
|
||||
|
||||
EXPECT_EQ(NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeArgBypointer, args[0].argType);
|
||||
EXPECT_EQ(16, args[0].offset);
|
||||
|
@ -2213,7 +2217,13 @@ kernels:
|
|||
EXPECT_EQ(NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeArgByvalue, args[1].argType);
|
||||
EXPECT_EQ(24, args[1].offset);
|
||||
EXPECT_EQ(4, args[1].size);
|
||||
EXPECT_EQ(2, args[1].argIndex);
|
||||
EXPECT_TRUE(args[1].isPtr);
|
||||
|
||||
EXPECT_EQ(NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeDataConstBuffer, args[2].argType);
|
||||
EXPECT_EQ(32, args[2].offset);
|
||||
EXPECT_EQ(8, args[2].size);
|
||||
EXPECT_EQ(1, args[2].btiValue);
|
||||
}
|
||||
|
||||
TEST(ReadZeInfoPayloadArguments, GivenUnknownEntryThenEmmitsWarning) {
|
||||
|
@ -5648,6 +5658,76 @@ TEST(PopulateArgDescriptor, GivenValidArgOfTypeRTGlobalBufferThenRtGlobalBufferI
|
|||
EXPECT_TRUE(kernelDescriptor.kernelAttributes.flags.hasRTCalls);
|
||||
}
|
||||
|
||||
TEST(PopulateArgDescriptor, GivenValidConstDataBufferArgThenItIsPopulatedCorrectly) {
|
||||
NEO::KernelDescriptor kernelDescriptor;
|
||||
NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::PayloadArgumentBaseT dataConstBuffer;
|
||||
dataConstBuffer.argType = NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeDataConstBuffer;
|
||||
dataConstBuffer.size = 8;
|
||||
dataConstBuffer.offset = 32;
|
||||
dataConstBuffer.btiValue = 1;
|
||||
|
||||
uint32_t crossThreadDataSize = 0U;
|
||||
std::string errors, warnings;
|
||||
auto err = NEO::populateArgDescriptor(dataConstBuffer, kernelDescriptor, crossThreadDataSize, errors, warnings);
|
||||
EXPECT_EQ(NEO::DecodeError::Success, err);
|
||||
EXPECT_TRUE(errors.empty());
|
||||
EXPECT_TRUE(warnings.empty());
|
||||
EXPECT_EQ(40U, crossThreadDataSize);
|
||||
EXPECT_EQ(8U, kernelDescriptor.payloadMappings.implicitArgs.globalConstantsSurfaceAddress.pointerSize);
|
||||
EXPECT_EQ(32U, kernelDescriptor.payloadMappings.implicitArgs.globalConstantsSurfaceAddress.stateless);
|
||||
EXPECT_EQ(64U, kernelDescriptor.payloadMappings.implicitArgs.globalConstantsSurfaceAddress.bindful);
|
||||
}
|
||||
|
||||
TEST(PopulateArgDescriptor, GivenInvalidConstDataBufferArgThenErrorIsReturned) {
|
||||
NEO::KernelDescriptor kernelDescriptor;
|
||||
kernelDescriptor.kernelMetadata.kernelName = "kernel";
|
||||
NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::PayloadArgumentBaseT dataConstBuffer;
|
||||
dataConstBuffer.argType = NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeDataConstBuffer;
|
||||
dataConstBuffer.btiValue = -1;
|
||||
|
||||
uint32_t crossThreadDataSize = 0U;
|
||||
std::string errors, warnings;
|
||||
auto err = NEO::populateArgDescriptor(dataConstBuffer, kernelDescriptor, crossThreadDataSize, errors, warnings);
|
||||
EXPECT_EQ(NEO::DecodeError::InvalidBinary, err);
|
||||
EXPECT_TRUE(warnings.empty());
|
||||
EXPECT_STREQ("DeviceBinaryFormat::Zebin : Invalid bti for argument of type const_base in context of : kernel\n", errors.c_str());
|
||||
}
|
||||
|
||||
TEST(PopulateArgDescriptor, GivenValidGlobalDataBufferArgThenItIsPopulatedCorrectly) {
|
||||
NEO::KernelDescriptor kernelDescriptor;
|
||||
NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::PayloadArgumentBaseT dataGlobalBuffer;
|
||||
dataGlobalBuffer.argType = NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeDataGlobalBuffer;
|
||||
dataGlobalBuffer.size = 8;
|
||||
dataGlobalBuffer.offset = 32;
|
||||
dataGlobalBuffer.btiValue = 1;
|
||||
|
||||
uint32_t crossThreadDataSize = 0U;
|
||||
std::string errors, warnings;
|
||||
auto err = NEO::populateArgDescriptor(dataGlobalBuffer, kernelDescriptor, crossThreadDataSize, errors, warnings);
|
||||
EXPECT_EQ(NEO::DecodeError::Success, err);
|
||||
EXPECT_TRUE(errors.empty());
|
||||
EXPECT_TRUE(warnings.empty());
|
||||
EXPECT_EQ(40U, crossThreadDataSize);
|
||||
EXPECT_EQ(8U, kernelDescriptor.payloadMappings.implicitArgs.globalVariablesSurfaceAddress.pointerSize);
|
||||
EXPECT_EQ(32U, kernelDescriptor.payloadMappings.implicitArgs.globalVariablesSurfaceAddress.stateless);
|
||||
EXPECT_EQ(64U, kernelDescriptor.payloadMappings.implicitArgs.globalVariablesSurfaceAddress.bindful);
|
||||
}
|
||||
|
||||
TEST(PopulateArgDescriptor, GivenInvalidGlobalDataBufferArgThenErrorIsReturned) {
|
||||
NEO::KernelDescriptor kernelDescriptor;
|
||||
kernelDescriptor.kernelMetadata.kernelName = "kernel";
|
||||
NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::PayloadArgumentBaseT dataGlobalBuffer;
|
||||
dataGlobalBuffer.argType = NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypeDataGlobalBuffer;
|
||||
dataGlobalBuffer.btiValue = -1;
|
||||
|
||||
uint32_t crossThreadDataSize = 0U;
|
||||
std::string errors, warnings;
|
||||
auto err = NEO::populateArgDescriptor(dataGlobalBuffer, kernelDescriptor, crossThreadDataSize, errors, warnings);
|
||||
EXPECT_EQ(NEO::DecodeError::InvalidBinary, err);
|
||||
EXPECT_TRUE(warnings.empty());
|
||||
EXPECT_STREQ("DeviceBinaryFormat::Zebin : Invalid bti for argument of type global_base in context of : kernel\n", errors.c_str());
|
||||
}
|
||||
|
||||
TEST(PopulateArgDescriptorCrossthreadPayload, GivenArgTypePrintfBufferWhenOffsetAndSizeIsValidThenPopulatesKernelDescriptor) {
|
||||
NEO::ConstStringRef zeinfo = R"===(
|
||||
kernels:
|
||||
|
|
Loading…
Reference in New Issue