source: CLRX/CLRadeonExtender/trunk/CLRX/amdbin/GalliumBinaries.h @ 2682

Last change on this file since 2682 was 2682, checked in by matszpk, 3 years ago

CLRadeonExtender: Update copyright's years.

File size: 14.9 KB
Line 
1/*
2 *  CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3 *  Copyright (C) 2014-2017 Mateusz Szpakowski
4 *
5 *  This library is free software; you can redistribute it and/or
6 *  modify it under the terms of the GNU Lesser General Public
7 *  License as published by the Free Software Foundation; either
8 *  version 2.1 of the License, or (at your option) any later version.
9 *
10 *  This library is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  Lesser General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Lesser General Public
16 *  License along with this library; if not, write to the Free Software
17 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19/*! \file GalliumBinaries.h
20 * \brief GalliumCompute binaries handling (only with LLVM 3.6)
21 */
22
23#ifndef __CLRX_GALLIUMBINARIES_H__
24#define __CLRX_GALLIUMBINARIES_H__
25
26#include <CLRX/Config.h>
27#include <cstdint>
28#include <string>
29#include <vector>
30#include <ostream>
31#include <utility>
32#include <memory>
33#include <CLRX/amdbin/Elf.h>
34#include <CLRX/amdbin/ElfBinaries.h>
35#include <CLRX/utils/MemAccess.h>
36#include <CLRX/utils/Utilities.h>
37#include <CLRX/utils/GPUId.h>
38#include <CLRX/utils/Containers.h>
39#include <CLRX/utils/InputOutput.h>
40
41/// main namespace
42namespace CLRX
43{
44
45enum : Flags {
46    GALLIUM_INNER_CREATE_SECTIONMAP = 0x10, ///< create map of sections for inner binaries
47    GALLIUM_INNER_CREATE_SYMBOLMAP = 0x20,  ///< create map of kernels for inner binaries
48    /** create map of dynamic kernels for inner binaries */
49    GALLIUM_INNER_CREATE_DYNSYMMAP = 0x40,
50    GALLIUM_INNER_CREATE_PROGINFOMAP = 0x100, ///< create prinfomap for inner binaries
51   
52    GALLIUM_ELF_CREATE_PROGINFOMAP = 0x10,  ///< create elf proginfomap
53   
54    GALLIUM_CREATE_ALL = ELF_CREATE_ALL | 0xfff0, ///< all Gallium binaries flags
55    GALLIUM_INNER_SHIFT = 4 ///< shift for convert inner binary flags into elf binary flags
56};
57
58/// GalliumCompute Kernel Arg type
59enum class GalliumArgType: cxbyte
60{
61    SCALAR = 0, ///< scalar type
62    CONSTANT,   ///< constant pointer
63    GLOBAL,     ///< global pointer
64    LOCAL,      ///< local pointer
65    IMAGE2D_RDONLY, ///< read-only 2d image
66    IMAGE2D_WRONLY, ///< write-only 2d image
67    IMAGE3D_RDONLY, ///< read-only 3d image
68    IMAGE3D_WRONLY, ///< write-only 3d image
69    SAMPLER,    ///< sampler
70    MAX_VALUE = SAMPLER ///< last value
71};
72
73/// Gallium semantic field type
74enum class GalliumArgSemantic: cxbyte
75{
76    GENERAL = 0,    ///< general
77    GRID_DIMENSION,     ///< ???
78    GRID_OFFSET,    ///< ???
79    IMAGE_SIZE,     ///< image size
80    IMAGE_FORMAT,   ///< image format
81    MAX_VALUE = IMAGE_FORMAT ///< last value
82};
83
84/// kernel program info entry for Gallium binaries
85struct GalliumProgInfoEntry
86{
87    uint32_t address;   ///< address
88    uint32_t value;     ///< value
89};
90
91/// kernel argument (Gallium binaries)
92struct GalliumArgInfo
93{
94    GalliumArgType type;    ///< type of argument
95    bool signExtended;  ///< is signed extended
96    GalliumArgSemantic semantic;    ///< semantic of array
97    uint32_t size;  ///< size of argument
98    uint32_t targetSize;    ///< target size
99    uint32_t targetAlign;   ///< target alignment
100};
101
102/// kernel info structure (Gallium binaries)
103struct GalliumKernel
104{
105    CString kernelName;   ///< kernel's name
106    uint32_t sectionId; ///< section id
107    uint32_t offset;    ///< offset in ElfBinary
108    Array<GalliumArgInfo> argInfos;   ///< arguments
109};
110
111/// Gallium format section type
112enum class GalliumSectionType: cxbyte
113{
114    TEXT = 0,   ///< section for text (binary code)
115    DATA_CONSTANT,  ///< constant data (???)
116    DATA_GLOBAL,    ///< global data (???)
117    DATA_LOCAL,     ///< local data (???)
118    DATA_PRIVATE,   ///< private data (???)
119    MAX_VALUE = DATA_PRIVATE    ///< last value
120};
121
122/// Gallium binarie's Section
123struct GalliumSection
124{
125    uint32_t sectionId; ///< section id
126    GalliumSectionType type;    ///< type of section
127    uint32_t offset;    ///< offset in binary
128    uint32_t size;      ///< size of section
129};
130
131/// Gallium elf binary base (for 32-bit and 64-bit)
132class GalliumElfBinaryBase
133{
134public:
135    /// program info entry index map
136    typedef Array<std::pair<const char*, size_t> > ProgInfoEntryIndexMap;
137protected:
138    uint32_t progInfosNum;  ///< program info entries number
139    GalliumProgInfoEntry* progInfoEntries;  ///< program info entries
140    ProgInfoEntryIndexMap progInfoEntryMap; ///< program info map
141    size_t disasmSize;  ///< disassembly size
142    size_t disasmOffset;    ///< disassembly offset
143   
144    /// routine to load binary fro internal ELF
145    template<typename ElfBinary>
146    void loadFromElf(ElfBinary& elfBinary);
147public:
148    /// empty constructor
149    GalliumElfBinaryBase();
150    /// destructor
151    virtual ~GalliumElfBinaryBase();
152   
153    /// returns program infos number
154    uint32_t getProgramInfosNum() const
155    { return progInfosNum; }
156   
157    /// returns number of program info entries for program info
158    uint32_t getProgramInfoEntriesNum(uint32_t index) const;
159   
160    /// returns index for programinfo entries index for specified kernel name
161    uint32_t getProgramInfoEntryIndex(const char* name) const;
162   
163    /// returns program info entries for specified kernel name
164    const GalliumProgInfoEntry* getProgramInfo(const char* name) const
165    { return reinterpret_cast<GalliumProgInfoEntry*>(progInfoEntries) +
166        getProgramInfoEntryIndex(name); }
167   
168    /// returns program info entries for specified kernel name
169    GalliumProgInfoEntry* getProgramInfo(const char* name)
170    { return reinterpret_cast<GalliumProgInfoEntry*>(progInfoEntries) +
171        getProgramInfoEntryIndex(name); }
172   
173    /// returns program info entries for specified kernel index
174    const GalliumProgInfoEntry* getProgramInfo(uint32_t index) const;
175    /// returns program info entries for specified kernel index
176    GalliumProgInfoEntry* getProgramInfo(uint32_t index);
177   
178    /// returns true if disassembly available
179    bool hasDisassembly() const
180    { return disasmOffset != 0; }
181   
182    /// returns size of disassembly
183    size_t getDisassemblySize() const
184    { return disasmSize; }
185};
186
187/* INFO: in this file is used ULEV function for conversion
188 * from LittleEndian and unaligned access to other memory access policy and endianness
189 * Please use this function whenever you want to get or set word in ELF binary,
190 * because ELF binaries can be unaligned in memory (as inner binaries).
191 */
192/// 32-bit Gallium ELF binary
193/** ULEV function is required to access programInfoEntry fields */
194class GalliumElfBinary32: public GalliumElfBinaryBase, public ElfBinary32
195{
196public:
197    /// empty constructor
198    GalliumElfBinary32();
199    /// constructor
200    GalliumElfBinary32(size_t binaryCodeSize, cxbyte* binaryCode, Flags creationFlags);
201    /// destructor
202    virtual ~GalliumElfBinary32();
203   
204    /// return true if binary has program info map
205    bool hasProgInfoMap() const
206    { return (creationFlags & GALLIUM_ELF_CREATE_PROGINFOMAP) != 0; }
207   
208    /// return disassembly content (without null-character)
209    const char* getDisassembly() const
210    { return reinterpret_cast<const char*>(binaryCode + disasmOffset); }
211};
212
213/// 64-bit Gallium ELF binary
214class GalliumElfBinary64: public GalliumElfBinaryBase, public ElfBinary64
215{
216public:
217    /// empty constructor
218    GalliumElfBinary64();
219    /// constructor
220    GalliumElfBinary64(size_t binaryCodeSize, cxbyte* binaryCode, Flags creationFlags);
221    /// destructor
222    virtual ~GalliumElfBinary64();
223   
224    /// return true if binary has program info map
225    bool hasProgInfoMap() const
226    { return (creationFlags & GALLIUM_ELF_CREATE_PROGINFOMAP) != 0; }
227   
228    /// return disassembly content (without null-character)
229    const char* getDisassembly() const
230    { return reinterpret_cast<const char*>(binaryCode + disasmOffset); }
231};
232
233/** GalliumBinary object. This object converts to host-endian fields and
234  * ULEV is not needed to access to fields of kernels and sections */
235class GalliumBinary: public NonCopyableAndNonMovable
236{
237private:
238    Flags creationFlags;
239    size_t binaryCodeSize;
240    cxbyte* binaryCode;
241    uint32_t kernelsNum;
242    uint32_t sectionsNum;
243    std::unique_ptr<GalliumKernel[]> kernels;
244    std::unique_ptr<GalliumSection[]> sections;
245   
246    bool elf64BitBinary;
247    std::unique_ptr<GalliumElfBinaryBase> elfBinary;
248public:
249    /// constructor
250    GalliumBinary(size_t binaryCodeSize, cxbyte* binaryCode, Flags creationFlags);
251    /// destructor
252    ~GalliumBinary() = default;
253   
254    /// get creation flags
255    Flags getCreationFlags()
256    { return creationFlags; }
257   
258    /// get size of binaries
259    size_t getSize() const
260    { return binaryCodeSize; }
261   
262    /// returns true if object is initialized
263    operator bool() const
264    { return binaryCode!=nullptr; }
265   
266    /// returns true if object is uninitialized
267    bool operator!() const
268    { return binaryCode==nullptr; }
269   
270    /// returns binary code data
271    const cxbyte* getBinaryCode() const
272    { return binaryCode; }
273   
274    /// returns binary code data
275    cxbyte* getBinaryCode()
276    { return binaryCode; }
277    /// return true if inner binary is 64-bit
278    bool is64BitElfBinary() const
279    { return elf64BitBinary; }
280   
281    /// returns Gallium inner ELF 32-bit binary
282    GalliumElfBinary32& getElfBinary32()
283    { return *static_cast<GalliumElfBinary32*>(elfBinary.get()); }
284   
285    /// returns Gallium inner ELF 32-bit binary
286    const GalliumElfBinary32& getElfBinary32() const
287    { return *static_cast<const GalliumElfBinary32*>(elfBinary.get()); }
288   
289    /// returns Gallium inner ELF 64-bit binary
290    GalliumElfBinary64& getElfBinary64()
291    { return *static_cast<GalliumElfBinary64*>(elfBinary.get()); }
292   
293    /// returns Gallium inner ELF 64-bit binary
294    const GalliumElfBinary64& getElfBinary64() const
295    { return *static_cast<const GalliumElfBinary64*>(elfBinary.get()); }
296   
297    /// get sections number
298    uint32_t getSectionsNum() const
299    { return sectionsNum; }
300   
301    /// get size of section with specified index
302    uint32_t getSectionSize(uint32_t index) const
303    { return sections[index].size; }
304   
305    /// get content for section with specified index
306    const cxbyte* getSectionContent(uint32_t index) const
307    { return binaryCode + sections[index].offset; }
308   
309    /// get content for section with specified index
310    cxbyte* getSectionContent(uint32_t index)
311    { return binaryCode + sections[index].offset; }
312   
313    /// get section with specified index
314    const GalliumSection& getSection(uint32_t index) const
315    { return sections[index]; }
316   
317    /// returns kernels number
318    uint32_t getKernelsNum() const
319    { return kernelsNum;; }
320   
321    /// returns kernel index
322    uint32_t getKernelIndex(const char* name) const;
323   
324    /// get kernel by index
325    const GalliumKernel& getKernel(uint32_t index) const
326    { return kernels[index]; }
327   
328    /// get kernel with speciified name
329    const GalliumKernel& getKernel(const char* name) const
330    { return kernels[getKernelIndex(name)]; }
331};
332
333enum: cxuint {
334    GALLIUMSECTID_GPUCONFIG = ELFSECTID_OTHER_BUILTIN,
335    GALLIUMSECTID_NOTEGNUSTACK,
336    GALLIUMSECTID_MAX = GALLIUMSECTID_NOTEGNUSTACK
337};
338
339/*
340 * Gallium Binary generator
341 */
342
343/// kernel config
344struct GalliumKernelConfig
345{
346    cxuint dimMask;    ///< mask of dimension (bits: 0 - X, 1 - Y, 2 - Z)
347    cxuint usedVGPRsNum;  ///< number of used VGPRs
348    cxuint usedSGPRsNum;  ///< number of used SGPRs
349    uint32_t pgmRSRC1;      ///< pgmRSRC1 register value
350    uint32_t pgmRSRC2;      ///< pgmRSRC2 register value
351    cxbyte userDataNum;   ///< number of user data
352    bool ieeeMode;  ///< IEEE mode
353    cxbyte floatMode; ///< float mode
354    cxbyte priority;    ///< priority
355    cxbyte exceptions;      ///< enabled exceptions
356    bool tgSize;        ///< enable TG_SIZE_EN bit
357    bool debugMode;     ///< debug mode
358    bool privilegedMode;   ///< prvileged mode
359    bool dx10Clamp;     ///< DX10 CLAMP mode
360    size_t localSize; ///< used local size (not local defined in kernel arguments)
361    uint32_t scratchBufferSize; ///< size of scratch buffer
362};
363
364/// kernel info structure (Gallium binaries)
365struct GalliumKernelInput
366{
367    CString kernelName;   ///< kernel's name
368    GalliumProgInfoEntry progInfo[3];   ///< program info for kernel
369    bool useConfig;         ///< true if configuration has been used to generate binary
370    GalliumKernelConfig config; ///< kernel's configuration
371    uint32_t offset;    ///< offset of kernel code
372    std::vector<GalliumArgInfo> argInfos;   ///< arguments
373};
374
375/// Gallium input
376struct GalliumInput
377{
378    bool is64BitElf;   ///< is 64-bit elf binary
379    GPUDeviceType deviceType;   ///< GPU device type
380    size_t globalDataSize;  ///< global constant data size
381    const cxbyte* globalData;   ///< global constant data
382    std::vector<GalliumKernelInput> kernels;    ///< input kernel list
383    size_t codeSize;        ///< code size
384    const cxbyte* code;     ///< code
385    size_t commentSize; ///< comment size (can be null)
386    const char* comment; ///< comment
387    std::vector<BinSection> extraSections;  ///< extra sections
388    std::vector<BinSymbol> extraSymbols;    ///< extra symbols
389   
390    /// add empty kernel with default values
391    void addEmptyKernel(const char* kernelName);
392};
393
394/// gallium code binary generator
395class GalliumBinGenerator: public NonCopyableAndNonMovable
396{
397private:
398    bool manageable;
399    const GalliumInput* input;
400   
401    void generateInternal(std::ostream* osPtr, std::vector<char>* vPtr,
402             Array<cxbyte>* aPtr) const;
403public:
404    GalliumBinGenerator();
405    /// constructor with gallium input
406    GalliumBinGenerator(const GalliumInput* galliumInput);
407   
408    /// constructor
409    /**
410     * \param _64bitMode 64-bit elf binary
411     * \param deviceType device type
412     * \param codeSize size of code
413     * \param code code pointer
414     * \param globalDataSize global data size
415     * \param globalData global data pointer
416     * \param kernels vector of kernels
417     */
418    GalliumBinGenerator(bool _64bitMode, GPUDeviceType deviceType, size_t codeSize,
419            const cxbyte* code, size_t globalDataSize, const cxbyte* globalData,
420            const std::vector<GalliumKernelInput>& kernels);
421    /// constructor
422    GalliumBinGenerator(bool _64bitMode, GPUDeviceType deviceType, size_t codeSize,
423            const cxbyte* code, size_t globalDataSize, const cxbyte* globalData,
424            std::vector<GalliumKernelInput>&& kernels);
425    ~GalliumBinGenerator();
426   
427    /// get input
428    const GalliumInput* getInput() const
429    { return input; }
430   
431    /// set input
432    void setInput(const GalliumInput* input);
433   
434    /// generates binary to array of bytes
435    void generate(Array<cxbyte>& array) const;
436   
437    /// generates binary to output stream
438    void generate(std::ostream& os) const;
439   
440    /// generates binary to vector of char
441    void generate(std::vector<char>& vector) const;
442};
443
444};
445
446#endif
Note: See TracBrowser for help on using the repository browser.