printf support with ZEBinary
Resolves: NEO-5657 Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
This commit is contained in:
parent
e19a4aadd6
commit
d62049035a
|
@ -29,10 +29,11 @@ NEO::GraphicsAllocation *PrintfHandler::createPrintfBuffer(Device *device) {
|
||||||
void PrintfHandler::printOutput(const KernelImmutableData *kernelData,
|
void PrintfHandler::printOutput(const KernelImmutableData *kernelData,
|
||||||
NEO::GraphicsAllocation *printfBuffer, Device *device) {
|
NEO::GraphicsAllocation *printfBuffer, Device *device) {
|
||||||
bool using32BitGpuPointers = kernelData->getDescriptor().kernelAttributes.gpuPointerSize == 4u;
|
bool using32BitGpuPointers = kernelData->getDescriptor().kernelAttributes.gpuPointerSize == 4u;
|
||||||
NEO::PrintFormatter printfFormatter{static_cast<uint8_t *>(printfBuffer->getUnderlyingBuffer()),
|
NEO::PrintFormatter printfFormatter{
|
||||||
|
static_cast<uint8_t *>(printfBuffer->getUnderlyingBuffer()),
|
||||||
static_cast<uint32_t>(printfBuffer->getUnderlyingBufferSize()),
|
static_cast<uint32_t>(printfBuffer->getUnderlyingBufferSize()),
|
||||||
using32BitGpuPointers,
|
using32BitGpuPointers,
|
||||||
kernelData->getDescriptor().kernelMetadata.printfStringsMap};
|
kernelData->getDescriptor().kernelAttributes.flags.usesStringMapForPrintf ? &kernelData->getDescriptor().kernelMetadata.printfStringsMap : nullptr};
|
||||||
printfFormatter.printKernelOutput();
|
printfFormatter.printKernelOutput();
|
||||||
|
|
||||||
*reinterpret_cast<uint32_t *>(printfBuffer->getUnderlyingBuffer()) =
|
*reinterpret_cast<uint32_t *>(printfBuffer->getUnderlyingBuffer()) =
|
||||||
|
|
|
@ -77,7 +77,8 @@ void PrintfHandler::makeResident(CommandStreamReceiver &commandStreamReceiver) {
|
||||||
|
|
||||||
void PrintfHandler::printEnqueueOutput() {
|
void PrintfHandler::printEnqueueOutput() {
|
||||||
PrintFormatter printFormatter(reinterpret_cast<const uint8_t *>(printfSurface->getUnderlyingBuffer()), static_cast<uint32_t>(printfSurface->getUnderlyingBufferSize()),
|
PrintFormatter printFormatter(reinterpret_cast<const uint8_t *>(printfSurface->getUnderlyingBuffer()), static_cast<uint32_t>(printfSurface->getUnderlyingBufferSize()),
|
||||||
kernel->is32Bit(), kernel->getKernelInfo().kernelDescriptor.kernelMetadata.printfStringsMap);
|
kernel->is32Bit(),
|
||||||
|
kernel->getDescriptor().kernelAttributes.flags.usesStringMapForPrintf ? &kernel->getDescriptor().kernelMetadata.printfStringsMap : nullptr);
|
||||||
printFormatter.printKernelOutput();
|
printFormatter.printKernelOutput();
|
||||||
}
|
}
|
||||||
} // namespace NEO
|
} // namespace NEO
|
||||||
|
|
|
@ -52,7 +52,10 @@ class MockKernelInfo : public KernelInfo {
|
||||||
|
|
||||||
void addExtendedDeviceSideEnqueueDescriptor(uint32_t index, uint32_t objectId);
|
void addExtendedDeviceSideEnqueueDescriptor(uint32_t index, uint32_t objectId);
|
||||||
|
|
||||||
inline void addToPrintfStringsMap(uint32_t index, const std::string &string) { kernelDescriptor.kernelMetadata.printfStringsMap.insert(std::make_pair(index, string)); }
|
inline void addToPrintfStringsMap(uint32_t index, const std::string &string) {
|
||||||
|
kernelDescriptor.kernelAttributes.flags.usesStringMapForPrintf = true;
|
||||||
|
kernelDescriptor.kernelMetadata.printfStringsMap.insert(std::make_pair(index, string));
|
||||||
|
}
|
||||||
void setPrintfSurface(uint8_t dataParamSize = sizeof(uintptr_t), CrossThreadDataOffset crossThreadDataOffset = undefined<CrossThreadDataOffset>, SurfaceStateHeapOffset sshOffset = undefined<SurfaceStateHeapOffset>);
|
void setPrintfSurface(uint8_t dataParamSize = sizeof(uintptr_t), CrossThreadDataOffset crossThreadDataOffset = undefined<CrossThreadDataOffset>, SurfaceStateHeapOffset sshOffset = undefined<SurfaceStateHeapOffset>);
|
||||||
void setBindingTable(SurfaceStateHeapOffset tableOffset, uint8_t numEntries);
|
void setBindingTable(SurfaceStateHeapOffset tableOffset, uint8_t numEntries);
|
||||||
void setGlobalVariablesSurface(uint8_t pointerSize, CrossThreadDataOffset stateless, SurfaceStateHeapOffset bindful = undefined<CrossThreadDataOffset>);
|
void setGlobalVariablesSurface(uint8_t pointerSize, CrossThreadDataOffset stateless, SurfaceStateHeapOffset bindful = undefined<CrossThreadDataOffset>);
|
||||||
|
|
|
@ -54,7 +54,7 @@ class PrintFormatterTest : public testing::Test {
|
||||||
program = std::make_unique<MockProgram>(toClDeviceVector(*device));
|
program = std::make_unique<MockProgram>(toClDeviceVector(*device));
|
||||||
kernel = new MockKernel(program.get(), *kernelInfo, *device);
|
kernel = new MockKernel(program.get(), *kernelInfo, *device);
|
||||||
|
|
||||||
printFormatter = std::unique_ptr<PrintFormatter>(new PrintFormatter(static_cast<uint8_t *>(data->getUnderlyingBuffer()), printfBufferSize, is32bit, kernelInfo->kernelDescriptor.kernelMetadata.printfStringsMap));
|
printFormatter = std::unique_ptr<PrintFormatter>(new PrintFormatter(static_cast<uint8_t *>(data->getUnderlyingBuffer()), printfBufferSize, is32bit, &kernelInfo->kernelDescriptor.kernelMetadata.printfStringsMap));
|
||||||
|
|
||||||
underlyingBuffer[0] = 0;
|
underlyingBuffer[0] = 0;
|
||||||
underlyingBuffer[1] = 0;
|
underlyingBuffer[1] = 0;
|
||||||
|
@ -259,7 +259,7 @@ TEST_P(PrintfUint32Test, GivenFormatContainingUintWhenPrintingThenValueIsInserte
|
||||||
|
|
||||||
TEST_P(PrintfUint32Test, GivenBufferSizeGreaterThanPrintBufferWhenPrintingThenBufferIsTrimmed) {
|
TEST_P(PrintfUint32Test, GivenBufferSizeGreaterThanPrintBufferWhenPrintingThenBufferIsTrimmed) {
|
||||||
auto input = GetParam();
|
auto input = GetParam();
|
||||||
printFormatter = std::unique_ptr<PrintFormatter>(new PrintFormatter(static_cast<uint8_t *>(data->getUnderlyingBuffer()), 0, is32bit, kernelInfo->kernelDescriptor.kernelMetadata.printfStringsMap));
|
printFormatter = std::unique_ptr<PrintFormatter>(new PrintFormatter(static_cast<uint8_t *>(data->getUnderlyingBuffer()), 0, is32bit, &kernelInfo->kernelDescriptor.kernelMetadata.printfStringsMap));
|
||||||
|
|
||||||
auto stringIndex = injectFormatString(input.format);
|
auto stringIndex = injectFormatString(input.format);
|
||||||
storeData(stringIndex);
|
storeData(stringIndex);
|
||||||
|
@ -807,7 +807,7 @@ TEST_F(PrintFormatterTest, GivenPointerWhenPrintingThenValueIsInserted) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PrintFormatterTest, GivenPointerWith32BitKernelWhenPrintingThen32BitPointerIsPrinted) {
|
TEST_F(PrintFormatterTest, GivenPointerWith32BitKernelWhenPrintingThen32BitPointerIsPrinted) {
|
||||||
printFormatter.reset(new PrintFormatter(static_cast<uint8_t *>(data->getUnderlyingBuffer()), printfBufferSize, true, kernelInfo->kernelDescriptor.kernelMetadata.printfStringsMap));
|
printFormatter.reset(new PrintFormatter(static_cast<uint8_t *>(data->getUnderlyingBuffer()), printfBufferSize, true, &kernelInfo->kernelDescriptor.kernelMetadata.printfStringsMap));
|
||||||
auto stringIndex = injectFormatString("%p");
|
auto stringIndex = injectFormatString("%p");
|
||||||
storeData(stringIndex);
|
storeData(stringIndex);
|
||||||
kernelInfo->kernelDescriptor.kernelAttributes.gpuPointerSize = 4;
|
kernelInfo->kernelDescriptor.kernelAttributes.gpuPointerSize = 4;
|
||||||
|
@ -878,6 +878,34 @@ TEST_F(PrintFormatterTest, GivenEmptyBufferWhenPrintingThenFailSafely) {
|
||||||
EXPECT_STREQ("", actualOutput);
|
EXPECT_STREQ("", actualOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PrintFormatterTest, GivenNoStringMapAndBufferWithFormatStringThenItIsPrintedProperly) {
|
||||||
|
printFormatter.reset(new PrintFormatter(static_cast<uint8_t *>(data->getUnderlyingBuffer()), printfBufferSize, true));
|
||||||
|
const char *formatString = "test string";
|
||||||
|
storeData(formatString);
|
||||||
|
|
||||||
|
char output[maxPrintfOutputLength];
|
||||||
|
printFormatter->printKernelOutput([&output](char *str) { strncpy_s(output, maxPrintfOutputLength, str, maxPrintfOutputLength); });
|
||||||
|
EXPECT_STREQ(formatString, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PrintFormatterTest, GivenNoStringMapAndBufferWithFormatStringAnd2StringsThenDataIsParsedAndPrintedProperly) {
|
||||||
|
printFormatter.reset(new PrintFormatter(static_cast<uint8_t *>(data->getUnderlyingBuffer()), printfBufferSize, true));
|
||||||
|
const char *formatString = "%s %s";
|
||||||
|
storeData(formatString);
|
||||||
|
|
||||||
|
const char *string1 = "str1";
|
||||||
|
storeData(PRINTF_DATA_TYPE::STRING);
|
||||||
|
storeData(string1);
|
||||||
|
const char *string2 = "str2";
|
||||||
|
storeData(PRINTF_DATA_TYPE::STRING);
|
||||||
|
storeData(string2);
|
||||||
|
|
||||||
|
const char *expectedOutput = "str1 str2";
|
||||||
|
char output[maxPrintfOutputLength];
|
||||||
|
printFormatter->printKernelOutput([&output](char *str) { strncpy_s(output, maxPrintfOutputLength, str, maxPrintfOutputLength); });
|
||||||
|
EXPECT_STREQ(expectedOutput, output);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(printToSTDOUTTest, GivenStringWhenPrintingToStdoutThenOutputOccurs) {
|
TEST(printToSTDOUTTest, GivenStringWhenPrintingToStdoutThenOutputOccurs) {
|
||||||
testing::internal::CaptureStdout();
|
testing::internal::CaptureStdout();
|
||||||
printToSTDOUT("test");
|
printToSTDOUT("test");
|
||||||
|
|
|
@ -136,6 +136,7 @@ static constexpr ConstStringRef privateBaseStateless("private_base_stateless");
|
||||||
static constexpr ConstStringRef argByvalue("arg_byvalue");
|
static constexpr ConstStringRef argByvalue("arg_byvalue");
|
||||||
static constexpr ConstStringRef argBypointer("arg_bypointer");
|
static constexpr ConstStringRef argBypointer("arg_bypointer");
|
||||||
static constexpr ConstStringRef bufferOffset("buffer_offset");
|
static constexpr ConstStringRef bufferOffset("buffer_offset");
|
||||||
|
static constexpr ConstStringRef printfBuffer("printf_buffer");
|
||||||
} // namespace ArgType
|
} // namespace ArgType
|
||||||
namespace MemoryAddressingMode {
|
namespace MemoryAddressingMode {
|
||||||
static constexpr ConstStringRef stateless("stateless");
|
static constexpr ConstStringRef stateless("stateless");
|
||||||
|
@ -298,7 +299,8 @@ enum ArgType : uint8_t {
|
||||||
ArgTypePrivateBaseStateless,
|
ArgTypePrivateBaseStateless,
|
||||||
ArgTypeArgByvalue,
|
ArgTypeArgByvalue,
|
||||||
ArgTypeArgBypointer,
|
ArgTypeArgBypointer,
|
||||||
ArgTypeBufferOffset
|
ArgTypeBufferOffset,
|
||||||
|
ArgTypePrintfBuffer
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace PerThreadPayloadArgument {
|
namespace PerThreadPayloadArgument {
|
||||||
|
|
|
@ -260,6 +260,8 @@ bool readEnumChecked(const Yaml::Token *token, NEO::Elf::ZebinKernelMetadata::Ty
|
||||||
out = ArgTypeT::ArgTypeArgBypointer;
|
out = ArgTypeT::ArgTypeArgBypointer;
|
||||||
} else if (tokenValue == PayloadArgument::ArgType::bufferOffset) {
|
} else if (tokenValue == PayloadArgument::ArgType::bufferOffset) {
|
||||||
out = ArgTypeT::ArgTypeBufferOffset;
|
out = ArgTypeT::ArgTypeBufferOffset;
|
||||||
|
} else if (tokenValue == PayloadArgument::ArgType::printfBuffer) {
|
||||||
|
out = ArgTypeT::ArgTypePrintfBuffer;
|
||||||
} else {
|
} else {
|
||||||
outErrReason.append("DeviceBinaryFormat::Zebin::" + NEO::Elf::SectionsNamesZebin::zeInfo.str() + " : Unhandled \"" + tokenValue.str() + "\" argument type in context of " + context.str() + "\n");
|
outErrReason.append("DeviceBinaryFormat::Zebin::" + NEO::Elf::SectionsNamesZebin::zeInfo.str() + " : Unhandled \"" + tokenValue.str() + "\" argument type in context of " + context.str() + "\n");
|
||||||
return false;
|
return false;
|
||||||
|
@ -762,6 +764,13 @@ NEO::DecodeError populateArgDescriptor(const NEO::Elf::ZebinKernelMetadata::Type
|
||||||
argAsPointer.bufferOffset = src.offset;
|
argAsPointer.bufferOffset = src.offset;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case NEO::Elf::ZebinKernelMetadata::Types::Kernel::ArgTypePrintfBuffer: {
|
||||||
|
dst.kernelAttributes.flags.usesPrintf = true;
|
||||||
|
dst.payloadMappings.implicitArgs.printfSurfaceAddress.stateless = src.offset;
|
||||||
|
dst.payloadMappings.implicitArgs.printfSurfaceAddress.pointerSize = src.size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DecodeError::Success;
|
return DecodeError::Success;
|
||||||
|
|
|
@ -82,6 +82,7 @@ struct KernelDescriptor final {
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
|
bool usesStringMapForPrintf : 1;
|
||||||
bool usesPrintf : 1;
|
bool usesPrintf : 1;
|
||||||
bool usesFencesForReadWriteImages : 1;
|
bool usesFencesForReadWriteImages : 1;
|
||||||
bool usesFlattenedLocalIds;
|
bool usesFlattenedLocalIds;
|
||||||
|
|
|
@ -171,6 +171,7 @@ void populateKernelDescriptor(KernelDescriptor &dst, const SPatchAllocateStatele
|
||||||
|
|
||||||
void populateKernelDescriptor(KernelDescriptor &dst, const SPatchAllocateStatelessPrintfSurface &token) {
|
void populateKernelDescriptor(KernelDescriptor &dst, const SPatchAllocateStatelessPrintfSurface &token) {
|
||||||
dst.kernelAttributes.flags.usesPrintf = true;
|
dst.kernelAttributes.flags.usesPrintf = true;
|
||||||
|
dst.kernelAttributes.flags.usesStringMapForPrintf = true;
|
||||||
populatePointerKernelArg(dst.payloadMappings.implicitArgs.printfSurfaceAddress, token, dst.kernelAttributes.bufferAddressingMode);
|
populatePointerKernelArg(dst.payloadMappings.implicitArgs.printfSurfaceAddress, token, dst.kernelAttributes.bufferAddressingMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,12 @@
|
||||||
namespace NEO {
|
namespace NEO {
|
||||||
|
|
||||||
PrintFormatter::PrintFormatter(const uint8_t *printfOutputBuffer, uint32_t printfOutputBufferMaxSize,
|
PrintFormatter::PrintFormatter(const uint8_t *printfOutputBuffer, uint32_t printfOutputBufferMaxSize,
|
||||||
bool using32BitPointers, const StringMap &stringLiteralMap)
|
bool using32BitPointers, const StringMap *stringLiteralMap)
|
||||||
: printfOutputBuffer(printfOutputBuffer),
|
: printfOutputBuffer(printfOutputBuffer),
|
||||||
printfOutputBufferSize(printfOutputBufferMaxSize),
|
printfOutputBufferSize(printfOutputBufferMaxSize),
|
||||||
stringLiteralMap(stringLiteralMap),
|
using32BitPointers(using32BitPointers),
|
||||||
using32BitPointers(using32BitPointers) {
|
usesStringMap(stringLiteralMap != nullptr),
|
||||||
|
stringLiteralMap(stringLiteralMap) {
|
||||||
|
|
||||||
output.reset(new char[maxSinglePrintStringLength]);
|
output.reset(new char[maxSinglePrintStringLength]);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +32,7 @@ void PrintFormatter::printKernelOutput(const std::function<void(char *)> &print)
|
||||||
read(&printfOutputBufferSizeRead);
|
read(&printfOutputBufferSizeRead);
|
||||||
printfOutputBufferSize = std::min(printfOutputBufferSizeRead, printfOutputBufferSize);
|
printfOutputBufferSize = std::min(printfOutputBufferSizeRead, printfOutputBufferSize);
|
||||||
|
|
||||||
|
if (usesStringMap) {
|
||||||
uint32_t stringIndex = 0;
|
uint32_t stringIndex = 0;
|
||||||
while (currentOffset + 4 <= printfOutputBufferSize) {
|
while (currentOffset + 4 <= printfOutputBufferSize) {
|
||||||
read(&stringIndex);
|
read(&stringIndex);
|
||||||
|
@ -39,6 +41,13 @@ void PrintFormatter::printKernelOutput(const std::function<void(char *)> &print)
|
||||||
printString(formatString, print);
|
printString(formatString, print);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
while (currentOffset + sizeof(char *) <= printfOutputBufferSize) {
|
||||||
|
char *formatString = nullptr;
|
||||||
|
read(&formatString);
|
||||||
|
printString(formatString, print);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintFormatter::printString(const char *formatString, const std::function<void(char *)> &print) {
|
void PrintFormatter::printString(const char *formatString, const std::function<void(char *)> &print) {
|
||||||
|
@ -140,16 +149,27 @@ size_t PrintFormatter::printToken(char *output, size_t size, const char *formatS
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PrintFormatter::printStringToken(char *output, size_t size, const char *formatString) {
|
size_t PrintFormatter::printStringToken(char *output, size_t size, const char *formatString) {
|
||||||
int index = 0;
|
|
||||||
int type = 0;
|
int type = 0;
|
||||||
// additional read to discard the token
|
|
||||||
read(&type);
|
read(&type);
|
||||||
|
|
||||||
|
const char *string = nullptr;
|
||||||
|
if (usesStringMap) {
|
||||||
|
int index = 0;
|
||||||
read(&index);
|
read(&index);
|
||||||
|
string = queryPrintfString(index);
|
||||||
|
} else {
|
||||||
|
char *str = nullptr;
|
||||||
|
read(&str);
|
||||||
|
string = str;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == static_cast<int>(PRINTF_DATA_TYPE::STRING)) {
|
if (type == static_cast<int>(PRINTF_DATA_TYPE::STRING)) {
|
||||||
return simple_sprintf(output, size, formatString, queryPrintfString(index));
|
return simple_sprintf(output, size, formatString, string);
|
||||||
} else {
|
} else {
|
||||||
return simple_sprintf(output, size, formatString, 0);
|
return simple_sprintf(output, size, formatString, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PrintFormatter::printPointerToken(char *output, size_t size, const char *formatString) {
|
size_t PrintFormatter::printPointerToken(char *output, size_t size, const char *formatString) {
|
||||||
|
@ -163,6 +183,11 @@ size_t PrintFormatter::printPointerToken(char *output, size_t size, const char *
|
||||||
return simple_sprintf(output, size, formatString, value);
|
return simple_sprintf(output, size, formatString, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *PrintFormatter::queryPrintfString(uint32_t index) const {
|
||||||
|
auto stringEntry = stringLiteralMap->find(index);
|
||||||
|
return stringEntry == stringLiteralMap->end() ? nullptr : stringEntry->second.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
char PrintFormatter::escapeChar(char escape) {
|
char PrintFormatter::escapeChar(char escape) {
|
||||||
switch (escape) {
|
switch (escape) {
|
||||||
case 'n':
|
case 'n':
|
||||||
|
@ -197,9 +222,4 @@ bool PrintFormatter::isConversionSpecifier(char c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *PrintFormatter::queryPrintfString(uint32_t index) const {
|
|
||||||
auto stringEntry = stringLiteralMap.find(index);
|
|
||||||
return stringEntry == stringLiteralMap.end() ? nullptr : stringEntry->second.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NEO
|
} // namespace NEO
|
||||||
|
|
|
@ -45,7 +45,7 @@ enum class PRINTF_DATA_TYPE : int {
|
||||||
class PrintFormatter {
|
class PrintFormatter {
|
||||||
public:
|
public:
|
||||||
PrintFormatter(const uint8_t *printfOutputBuffer, uint32_t printfOutputBufferMaxSize,
|
PrintFormatter(const uint8_t *printfOutputBuffer, uint32_t printfOutputBufferMaxSize,
|
||||||
bool using32BitPointers, const StringMap &stringLiteralMap);
|
bool using32BitPointers, const StringMap *stringLiteralMap = nullptr);
|
||||||
void printKernelOutput(const std::function<void(char *)> &print = [](char *str) { printToSTDOUT(str); });
|
void printKernelOutput(const std::function<void(char *)> &print = [](char *str) { printToSTDOUT(str); });
|
||||||
|
|
||||||
constexpr static size_t maxSinglePrintStringLength = 16 * MemoryConstants::kiloByte;
|
constexpr static size_t maxSinglePrintStringLength = 16 * MemoryConstants::kiloByte;
|
||||||
|
@ -118,8 +118,9 @@ class PrintFormatter {
|
||||||
const uint8_t *printfOutputBuffer = nullptr; // buffer extracted from the kernel, contains values to be printed
|
const uint8_t *printfOutputBuffer = nullptr; // buffer extracted from the kernel, contains values to be printed
|
||||||
uint32_t printfOutputBufferSize = 0; // size of the data contained in the buffer
|
uint32_t printfOutputBufferSize = 0; // size of the data contained in the buffer
|
||||||
|
|
||||||
const StringMap &stringLiteralMap;
|
|
||||||
bool using32BitPointers = false;
|
bool using32BitPointers = false;
|
||||||
|
const bool usesStringMap;
|
||||||
|
const StringMap *stringLiteralMap;
|
||||||
|
|
||||||
uint32_t currentOffset = 0; // current position in currently parsed buffer
|
uint32_t currentOffset = 0; // current position in currently parsed buffer
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "shared/source/device_binary_format/elf/elf_encoder.h"
|
|
||||||
#include "shared/source/device_binary_format/elf/zebin_elf.h"
|
#include "shared/source/device_binary_format/elf/zebin_elf.h"
|
||||||
#include "shared/source/device_binary_format/zebin_decoder.h"
|
#include "shared/source/device_binary_format/zebin_decoder.h"
|
||||||
#include "shared/source/helpers/ptr_math.h"
|
#include "shared/source/helpers/ptr_math.h"
|
||||||
|
@ -4250,3 +4249,39 @@ TEST(PopulateArgDescriptorCrossthreadPayload, GivenArgTypeBufferOffsetWhenSizeIs
|
||||||
EXPECT_TRUE(warnings.empty()) << warnings;
|
EXPECT_TRUE(warnings.empty()) << warnings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PopulateArgDescriptorCrossthreadPayload, GivenArgTypePrintfBufferWhenOffsetAndSizeIsValidThenPopulatesKernelDescriptor) {
|
||||||
|
NEO::ConstStringRef zeinfo = R"===(
|
||||||
|
kernels:
|
||||||
|
- name : some_kernel
|
||||||
|
execution_env:
|
||||||
|
simd_size: 32
|
||||||
|
payload_arguments:
|
||||||
|
- arg_type: printf_buffer
|
||||||
|
offset: 32
|
||||||
|
size: 8
|
||||||
|
)===";
|
||||||
|
NEO::ProgramInfo programInfo;
|
||||||
|
ZebinTestData::ValidEmptyProgram zebin;
|
||||||
|
zebin.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::textPrefix.str() + "some_kernel", {});
|
||||||
|
std::string errors, warnings;
|
||||||
|
auto elf = NEO::Elf::decodeElf(zebin.storage, errors, warnings);
|
||||||
|
ASSERT_NE(nullptr, elf.elfFileHeader) << errors << " " << warnings;
|
||||||
|
|
||||||
|
NEO::Yaml::YamlParser parser;
|
||||||
|
bool parseSuccess = parser.parse(zeinfo, errors, warnings);
|
||||||
|
ASSERT_TRUE(parseSuccess) << errors << " " << warnings;
|
||||||
|
|
||||||
|
NEO::ZebinSections zebinSections;
|
||||||
|
auto extractErr = NEO::extractZebinSections(elf, zebinSections, errors, warnings);
|
||||||
|
ASSERT_EQ(NEO::DecodeError::Success, extractErr) << errors << " " << warnings;
|
||||||
|
|
||||||
|
auto &kernelNode = *parser.createChildrenRange(*parser.findNodeWithKeyDfs("kernels")).begin();
|
||||||
|
auto err = NEO::populateKernelDescriptor(programInfo, elf, zebinSections, parser, kernelNode, errors, warnings);
|
||||||
|
EXPECT_EQ(NEO::DecodeError::Success, err);
|
||||||
|
EXPECT_TRUE(errors.empty()) << errors;
|
||||||
|
EXPECT_TRUE(warnings.empty()) << warnings;
|
||||||
|
const auto printfSurfaceAddress = programInfo.kernelInfos[0]->kernelDescriptor.payloadMappings.implicitArgs.printfSurfaceAddress;
|
||||||
|
ASSERT_EQ(32U, printfSurfaceAddress.stateless);
|
||||||
|
EXPECT_EQ(8U, printfSurfaceAddress.pointerSize);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue