1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2018-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #ifndef __IGC_H
10 #define __IGC_H
11 
12 #include "igc_api_calls.h"
13 
14 #if defined(_DEBUG) || defined(_INTERNAL)
15 # define IGC_DEBUG
16 #endif
17 
18 #include <string>
19 #include "../../common/EmUtils.h"
20 #include "../IGC/Compiler/CodeGenPublicEnums.h"
21 // TODO: add all external declarations so that external projects only need
22 // to include this file only.
23 
24 // Definition of integer Registry-key Values
25 // (may merge this into igc_flags.h's macro)
26 enum {
27     // ForcePixelShaderSIMDMode
28     FLAG_PS_SIMD_MODE_DEFAULT = 0,                 // default is SIMD8 compilation + heuristics to determine if we want to compile SIMD32/SIMD16
29     FLAG_PS_SIMD_MODE_FORCE_SIMD8 = 1,             // Force SIMD8 compilation
30     FLAG_PS_SIMD_MODE_FORCE_SIMD16 = 2,            // Force SIMD16 compilation
31     FLAG_PS_SIMD_MODE_FORCE_SIMD32 = 4,            // Force SIMD32 compilation
32 };
33 
34 enum {
35     BIT_CG_SIMD8     = 0b0000000000000001,
36     BIT_CG_SIMD16    = 0b0000000000000010,
37     BIT_CG_SIMD32    = 0b0000000000000100,
38     BIT_CG_SPILL8    = 0b0000000000001000,
39     BIT_CG_SPILL16   = 0b0000000000010000,
40     BIT_CG_SPILL32   = 0b0000000000100000,
41     BIT_CG_RETRY     = 0b0000000001000000,
42     BIT_CG_DO_SIMD32 = 0b0000000010000000,
43     BIT_CG_DO_SIMD16 = 0b0000000100000000,
44 };
45 
46 typedef unsigned short CG_CTX_STATS_t;
47 
48 // shader stat for opt customization
49 typedef struct {
50     uint32_t         m_tempCount;
51     uint32_t         m_sampler;
52     uint32_t         m_inputCount;
53     uint32_t         m_dxbcCount;
54     uint32_t         m_ConstantBufferCount;
55     IGC::Float_DenormMode m_floatDenormMode16;
56     IGC::Float_DenormMode m_floatDenormMode32;
57     IGC::Float_DenormMode m_floatDenormMode64;
58 } SHADER_STATS_t;
59 
60 typedef struct {
61     CG_CTX_STATS_t  m_stats;              // record what simd has been generated
62     void*           m_pixelShaderGen;     // Generated pixel shader output
63     char*           m_savedBitcodeCharArray; // Serialized Bitcode
64     unsigned int    m_savedBitcodeCharArraySize;
65     void*           m_savedInstrTypes;
66     SHADER_STATS_t  m_savedShaderStats;
67 } CG_CTX_t;
68 
69 #define IsRetry(stats)               (stats & (BIT_CG_RETRY))
70 #define DoSimd16(stats)              (stats & (BIT_CG_DO_SIMD16))
71 #define DoSimd32(stats)              (stats & (BIT_CG_DO_SIMD32))
72 #define HasSimd(MODE, stats)         (stats & (BIT_CG_SIMD##MODE))
73 #define HasSimdSpill(MODE, stats)   ((stats & (BIT_CG_SIMD##MODE)) &&  (stats & (BIT_CG_SPILL##MODE)))
74 #define HasSimdNoSpill(MODE, stats) ((stats & (BIT_CG_SIMD##MODE)) && !(stats & (BIT_CG_SPILL##MODE)))
75 #define SetRetry(stats)              (stats = (stats | (BIT_CG_RETRY)))
76 #define SetSimd16(stats)             (stats = (stats | (BIT_CG_DO_SIMD16)))
77 #define SetSimd32(stats)             (stats = (stats | (BIT_CG_DO_SIMD32)))
78 #define SetSimdSpill(MODE, stats)    (stats = (stats | (BIT_CG_SIMD##MODE) |  (BIT_CG_SPILL##MODE)))
79 #define SetSimdNoSpill(MODE, stats)  (stats = (stats | (BIT_CG_SIMD##MODE) & ~(BIT_CG_SPILL##MODE)))
80 
81 typedef enum {
82     FLAG_CG_ALL_SIMDS = 0,
83     FLAG_CG_STAGE1_FAST_COMPILE = 1,
84     FLAG_CG_STAGE1_BEST_PERF = 2,
85     FLAG_CG_STAGE1_FASTEST_COMPILE = 3,
86 } CG_FLAG_t;
87 
88 #define IsSupportedForStagedCompilation(platform) (true)
89 #define RequestStage2(flag, ctx_ptr) (ctx_ptr != nullptr || flag == FLAG_CG_STAGE1_FASTEST_COMPILE)
90 
91 #define IsStage2RestSIMDs(prev_ctx_ptr) (prev_ctx_ptr != nullptr)
92 #define IsStage1FastCompile(flag, prev_ctx_ptr) (!IsStage2RestSIMDs(prev_ctx_ptr) && flag == FLAG_CG_STAGE1_FAST_COMPILE)
93 #define IsStage1FastestCompile(flag, prev_ctx_ptr) (!IsStage2RestSIMDs(prev_ctx_ptr) && flag == FLAG_CG_STAGE1_FASTEST_COMPILE)
94 #define IsStage1BestPerf(flag, prev_ctx_ptr)    (!IsStage2RestSIMDs(prev_ctx_ptr) && flag == FLAG_CG_STAGE1_BEST_PERF)
95 #define IsAllSIMDs(flag, prev_ctx_ptr)          (!IsStage2RestSIMDs(prev_ctx_ptr) && flag == FLAG_CG_ALL_SIMDS)
96 #define IsStage1(pCtx)   (IsStage1BestPerf(pCtx->m_CgFlag, pCtx->m_StagingCtx) || \
97                           IsStage1FastCompile(pCtx->m_CgFlag, pCtx->m_StagingCtx))
98 #define HasSavedIR(pCtx) (pCtx && IsStage2RestSIMDs(pCtx->m_StagingCtx) && \
99                           pCtx->m_StagingCtx->m_savedBitcodeCharArraySize > 0)
100 
101 #define DoSimd32Stage2(prev_ctx_ptr) (IsStage2RestSIMDs(prev_ctx_ptr) && DoSimd32(prev_ctx_ptr->m_stats))
102 #define DoSimd16Stage2(prev_ctx_ptr) (IsStage2RestSIMDs(prev_ctx_ptr) && DoSimd16(prev_ctx_ptr->m_stats))
103 
104 #define ContinueFastCompileStage1(flag, prev_ctx_ptr, stats) ( \
105     IsStage1FastCompile(flag, prev_ctx_ptr) && \
106     (IsRetry(stats) || DoSimd16(stats)))
107 
108 // If the staged compilation enabled, we don't need compile continuation when SIMD8 is spilled.
109 #define ContinueBestPerfStage1(flag, prev_ctx_ptr, stats) ( \
110     IsStage1BestPerf(flag, prev_ctx_ptr) && \
111      (( IGC_IS_FLAG_ENABLED(ExtraRetrySIMD16) && !HasSimdSpill(8, stats)) || \
112       (!IGC_IS_FLAG_ENABLED(ExtraRetrySIMD16) && (!HasSimd(8, stats) || DoSimd32(stats)))))
113 
114 // We don't need compile continuation if no staged compilation enabled denoted by RegKeys.
115 #define HasCompileContinuation(Ail, flag, prev_ctx_ptr, stats) ( \
116     (IGC_IS_FLAG_ENABLED(StagedCompilation) || Ail) && \
117     (ContinueFastCompileStage1(flag, prev_ctx_ptr, stats) || \
118      ContinueBestPerfStage1(flag, prev_ctx_ptr, stats)))
119 
120 // Return true when simd MODE has been generated previously
121 #define AvoidDupStage2(MODE, flag, prev_ctx_ptr)      (IsStage2RestSIMDs(prev_ctx_ptr) && HasSimdNoSpill(MODE, prev_ctx_ptr->m_stats))
122 
123 // Fast CG always returns simd 8
124 #define ValidFastModes(flag, prev_ctx_ptr, stats)     (IsStage1FastCompile(flag, prev_ctx_ptr) && HasSimd(8, stats) && !HasSimd(16, stats) && !HasSimd(32, stats))
125 // Fastest CG always returns simd 8
126 #define ValidFastestModes(flag, prev_ctx_ptr, stats)     (IsStage1FastestCompile(flag, prev_ctx_ptr) && HasSimd(8, stats) && !HasSimd(16, stats) && !HasSimd(32, stats))
127 // Best CG returns simd 8 or 16
128 #define ValidBestModes(flag, prev_ctx_ptr, stats)     (IsStage1BestPerf(flag, prev_ctx_ptr) && (HasSimd(8, stats) || HasSimd(16, stats)) && !HasSimd(32, stats))
129 // ALL_SIMDS CG must have simd 8 in any case
130 #define ValidAllSimdsModes(flag, prev_ctx_ptr, stats) (IsAllSIMDs(flag, prev_ctx_ptr) && HasSimd(8, stats))
131 
132 // Rest Stage2 CG would not generate duplicated simd 32 or 16 modes, and
133 // When simd 8 spills in Stage1 for FAST_COMPILE, we may generate simd again;
134 // otherwise it must be generated either from Stage1 or Stage2
135 #define ValidStage2Modes(prev_ctx_ptr, stats) ( \
136     IsStage2RestSIMDs(prev_ctx_ptr) && \
137     (!HasSimd(32, prev_ctx_ptr->m_stats) || !HasSimd(32, stats)) && \
138     (!HasSimd(16, prev_ctx_ptr->m_stats) || !HasSimd(16, stats)) && \
139     ((HasSimd(8,  prev_ctx_ptr->m_stats) ^ HasSimd(8,  stats)) || HasSimdSpill(8,  prev_ctx_ptr->m_stats)) \
140     )
141 
142 #define ValidGeneratedModes(flag, prev_ctx_ptr, stats) ( \
143     ValidFastestModes(flag, prev_ctx_ptr, stats) || \
144     ValidFastModes(flag, prev_ctx_ptr, stats) || \
145     ValidBestModes(flag, prev_ctx_ptr, stats) || \
146     ValidAllSimdsModes(flag, prev_ctx_ptr, stats) || \
147     ValidStage2Modes(prev_ctx_ptr, stats) \
148     )
149 
150 // CodePatch compilation experimental flags
151 typedef enum
152 {
153     CODE_PATCH_NO_EXPRIMENT                  = 0,
154     CODE_PATCH_NO_PullSampleIndex            = ( 0x1 << 0x0 ),
155     CODE_PATCH_NO_PullSnapped                = ( 0x1 << 0x1 ),
156     CODE_PATCH_NO_PullCentroid               = ( 0x1 << 0x2 ),
157     CODE_PATCH_NO_ZWDelta                    = ( 0x1 << 0x3 ),
158 } CODE_PATCH_FLAG_t;
159 
160 // Fastest compilation experimental flags
161 typedef enum
162 {
163     FCEXP_NO_EXPRIMENT                  = 0,
164     FCEXP_DISABLE_LVN                   = ( 0x1 << 0x0 ),
165     FCEXP_LINEARSCAN                    = ( 0x1 << 0x1 ),
166     FCEXP_DISABLE_GOPT                  = ( 0x1 << 0x2 ),
167     FCEXP_1PASSRA                       = ( 0x1 << 0x3 ),
168     FCEXP_FASTSPILL                     = ( 0x1 << 0x4 ),
169     FCEXP_LOCAL_SCHEDULING              = ( 0x1 << 0x5 ),
170     FCEXP_PRERA_SCHEDULING              = ( 0x1 << 0x6 ),
171     FCEXP_NO_REMAT                      = ( 0x1 << 0x7 ),
172     FCEXP_SPILL_COMPRESSION             = ( 0x1 << 0x8 ),
173     FCEXP_LOCAL_DECL_SPLIT_GLOBAL_RA    = ( 0x1 << 0x9 ),
174     FCEXP_QUICKTOKEN_ALLOC              = ( 0x1 << 0xa ),
175     FCEXP_TOBE_DESIGNED                 = ( 0x1 << 0xb ),
176 } FCEXP_FLAG_t;
177 
178 #endif // __IGC_H
179 
180