1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #pragma once
10 #include "Compiler/CISACodeGen/ShaderCodeGen.hpp"
11 #include "common/Types.hpp"
12 
13 namespace IGC
14 {
15 struct PSSignature
16 {
17     struct DispatchSignature
18     {
19         std::vector<unsigned int> inputOffset;
20         std::map<unsigned int, unsigned int> PSOutputOffset;
21         unsigned int              pixelOffset;
22         unsigned int              ZWDelta;
23         unsigned int              oMaskOffset;
24         unsigned int              r1;
25         bool                      CoarseMask;
DispatchSignatureIGC::PSSignature::DispatchSignature26         DispatchSignature() : CoarseMask(false) {}
27     };
28     DispatchSignature dispatchSign[3];
29     std::map<unsigned int, uint64_t> PSConstantOutput;
30 };
31 
32 
33 class CPixelShader : public CShader
34 {
35 public:
36     CPixelShader(llvm::Function* pFunc, CShaderProgram* pProgram);
37     ~CPixelShader();
38     CVariable* GetR1();
39     std::vector<CVariable*>& GetR1Lo();
40     void AppendR1Lo(CVariable* var);
41     CVariable* GetCoarseR1();
42     CVariable* GetBaryReg(e_interpolation mode);
43     CVariable* GetBaryRegLoweredHalf(e_interpolation mode);
44     CVariable* GetBaryRegLoweredFloat(e_interpolation mode);
45     CVariable* GetInputDelta(uint index, bool loweredInput = false);
46     CVariable* GetInputDeltaLowered(uint index);
47     CVariable* GetZWDelta();
48     CVariable* GetPositionZ();
49     CVariable* GetPositionW();
50     CVariable* GetPositionXYOffset();
51     CVariable* GetSampleOffsetX();
52     CVariable* GetSampleOffsetY();
53     CVariable* GetInputCoverageMask();
54     CVariable* GetCPSRequestedSizeX();
55     CVariable* GetCPSRequestedSizeY();
56     CVariable* GetCoarseParentIndex();
57     CVariable* GetCurrentPhaseCounter();
58 
59     /// Get mask for pixels not discarded
GetDiscardPixelMask()60     CVariable* GetDiscardPixelMask() { return m_KillPixelMask; }
SetDiscardPixelMask(CVariable * mask)61     void SetDiscardPixelMask(CVariable* mask) { m_KillPixelMask = mask; }
62 
63     void InitEncoder(SIMDMode simdMode, bool canAbortOnSpill, ShaderDispatchMode shaderMode = ShaderDispatchMode::NOT_APPLICABLE) override;
64     void PreCompile() override;
65     void AllocatePayload() override;
66     void AddPrologue() override;
67     void PreAnalysisPass() override;
68     void AddEpilogue(llvm::ReturnInst* ret) override;
69     bool CompileSIMDSize(SIMDMode simdMode, EmitPass& EP, llvm::Function& F) override;
70     void ExtractGlobalVariables() override;
71 
72     void        AllocatePSPayload();
73     void        AllocatePixelPhasePayload();
74     void        MapPushedInputs() override;
75     int         getSetupIndex(uint inputIndex);
76 
77     void        FillProgram(SPixelShaderKernelProgram* pKernelProgram);
78     void        AddRenderTarget(uint index);
79     void        DeclareSGV(uint usage);
80     void        ParseShaderSpecificOpcode(llvm::Instruction* inst) override;
81     void        PullPixelPhasePayload();
82 
83     void        AddCoarseOutput(CVariable* var, unsigned int index);
84     CVariable* GetCoarseInput(unsigned int index, uint16_t vectorSize, VISA_Type type);
85     void        SetCoarseoMask(CVariable* var);
86     CVariable* GetCoarseMask();
OutputDepth()87     void        OutputDepth() { m_HasoDepth = true; };
OutputStencil()88     void        OutputStencil() { m_HasoStencil = true; }
OutputMask()89     void        OutputMask() { m_HasoMask = true; }
HasRenderTarget()90     bool        HasRenderTarget() { return m_RenderTargetMask != 0; }
SetPhase(PixelShaderPhaseType phase)91     void        SetPhase(PixelShaderPhaseType phase) { m_phase = phase; }
GetPhase() const92     PixelShaderPhaseType GetPhase() const { return m_phase; }
SetLastPhase()93     void        SetLastPhase() { m_IsLastPhase = true; }
SetPSSignature(PSSignature * signature)94     void        SetPSSignature(PSSignature* signature) { m_Signature = signature; }
IsLastPhase()95     bool        IsLastPhase() { return m_IsLastPhase; }
IsPerSample()96     bool        IsPerSample() { return m_isPerSample || m_PerspectiveSample || m_NoPerspectiveSample; }
97 
HasDiscard()98     bool        HasDiscard() { return m_HasDiscard; }
NeedVMask()99     bool        NeedVMask() { return m_VectorMask; }
100     void        MarkConstantInterpolation(unsigned int index);
101 
HasZWDelta()102     bool        HasZWDelta() { return m_ZWDelta != nullptr; }
103 
104     // check whether it's the last render target write
105     bool        IsLastRTWrite(llvm::GenIntrinsicInst* inst);
106 
107     void emitPSInputLowering();
108 
109     std::vector<std::pair<llvm::Instruction*, bool> > rtWriteList;
110     bool        m_hasEOT;
111     bool        m_NeedPSSync;
112 
113     std::vector<CVariable*> setupLowered;
114     std::set<uint> loweredSetupIndexes;
115     std::bitset<NUMBER_EINTERPOLATION> m_ModeUsedHalf;
116     std::bitset<NUMBER_EINTERPOLATION> m_ModeUsedFloat;
117     bool LowerPSInput();
118     static bool IsInterpolationLinear(e_interpolation mode);
119     // attribute "packing"
120     // Non continuous "input indexes" may be received and they are allocated one after another.
121     // We need to map them to "setup indexes".
122     std::set<unsigned int> m_SetupIndicesUsed;
123 
124 protected:
125     void CreatePassThroughVar();
126     bool IsReturnBlock(llvm::BasicBlock* bb);
127 
128 private:
129     PSSignature::DispatchSignature& GetDispatchSignature();
130     USC::GFX3DSTATE_SF_ATTRIBUTE_ACTIVE_COMPONENT GetActiveComponents(uint attribute) const;
131 
132     CVariable* m_R1;
133     std::vector<CVariable*> m_R1Lo;
134     CVariable* m_PerspectiveBaryPlanes;
135     CVariable* m_NonPerspectiveBaryPlanes;
136     CVariable* m_CoarseR1;
137     CVariable* m_PerspectivePixel;
138     CVariable* m_PerspectiveCentroid;
139     CVariable* m_PerspectiveSample;
140     CVariable* m_NoPerspectivePixel;
141     CVariable* m_NoPerspectiveCentroid;
142     CVariable* m_NoPerspectiveSample;
143     std::array<CVariable*, NUMBER_EINTERPOLATION> m_BaryRegLoweredHalf;
144     std::array<CVariable*, NUMBER_EINTERPOLATION> m_BaryRegLoweredFloat;
145     CVariable* m_KillPixelMask;
146     CVariable* m_pPositionZPixel;
147     CVariable* m_pPositionWPixel;
148     CVariable* m_pPositionXYOffset;
149     CVariable* m_ZWDelta;
150     CVariable* m_pInputCoverageMask;
151     CVariable* m_pCPSRequestedSizeX;
152     CVariable* m_pCPSRequestedSizeY;
153     uint       m_RenderTargetMask;
154     bool       m_HasoDepth;
155     bool       m_HasoStencil;
156     bool       m_HasoMask;
157     bool       m_HasInputCoverageMask;
158     bool       m_isPerSample;
159     bool       m_HasPullBary;
160     bool       m_HasCoarseSize;
161     bool       m_hasDualBlendSource;
162     unsigned int m_MaxSetupIndex = 0;
163     /// workaround to force SIMD8 compilation when double are present
164     bool       m_HasDouble;
165     bool       m_VectorMask;
166     uint       m_ConstantInterpolationMask = 0;
167 
168     bool       m_HasDiscard;
169 
170     // Multi phase shader properties
171     PixelShaderPhaseType m_phase;
172     bool       m_IsLastPhase;
173     uint       m_pixelPhaseLabel;
174     uint       m_epilogueLabel;
175     CVariable* m_PixelPhasePayload;
176     CVariable* m_PixelPhaseCounter;
177     CVariable* m_CurrentPhaseCounter;
178     CVariable* m_CoarseParentIndex;
179     CVariable* m_SampleOffsetX;
180     CVariable* m_SampleOffsetY;
181     CVariable* m_CoarseoMask;
182     CVariable* m_CoarseMaskInput;
183     std::map<unsigned int, CVariable*> m_CoarseOutput;
184     std::map<unsigned int, CVariable*> m_CoarseInput;
185     PSSignature* m_Signature;
186     unsigned int m_samplerCount;
187 };
188 
189 }//namespace IGC
190