1 //
2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // ShaderStorageBlockOutputHLSL: A traverser to translate a buffer variable of shader storage block
7 // to an offset of RWByteAddressBuffer.
8 //
9 
10 #ifndef COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKOUTPUTHLSL_H_
11 #define COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKOUTPUTHLSL_H_
12 
13 #include "compiler/translator/IntermNode.h"
14 #include "compiler/translator/ShaderStorageBlockFunctionHLSL.h"
15 #include "compiler/translator/blocklayout.h"
16 
17 namespace sh
18 {
19 class ResourcesHLSL;
20 class OutputHLSL;
21 class TSymbolTable;
22 
23 struct TReferencedBlock : angle::NonCopyable
24 {
25     POOL_ALLOCATOR_NEW_DELETE
26     TReferencedBlock(const TInterfaceBlock *block, const TVariable *instanceVariable);
27     const TInterfaceBlock *block;
28     const TVariable *instanceVariable;  // May be nullptr if the block is not instanced.
29 };
30 
31 // Maps from uniqueId to a variable.
32 using ReferencedInterfaceBlocks = std::map<int, const TReferencedBlock *>;
33 
34 // Used to save shader storage block field member information.
35 using BlockMemberInfoMap = std::map<const TField *, BlockMemberInfo>;
36 
37 using ShaderVarToFieldMap = std::map<std::string, const TField *>;
38 
39 class ShaderStorageBlockOutputHLSL
40 {
41   public:
42     ShaderStorageBlockOutputHLSL(OutputHLSL *outputHLSL,
43                                  ResourcesHLSL *resourcesHLSL,
44                                  const std::vector<InterfaceBlock> &shaderStorageBlocks);
45 
46     ~ShaderStorageBlockOutputHLSL();
47 
48     // This writes part of the function call to store a value to a SSBO to the output stream. After
49     // calling this, ", <stored value>)" should be written to the output stream to complete the
50     // function call.
51     void outputStoreFunctionCallPrefix(TIntermTyped *node);
52     // This writes the function call to load a SSBO value to the output stream.
53     void outputLoadFunctionCall(TIntermTyped *node);
54     // This writes the function call to get the lengh of unsized array member of SSBO.
55     void outputLengthFunctionCall(TIntermTyped *node);
56     // Writes the atomic memory function calls for SSBO.
57     void outputAtomicMemoryFunctionCallPrefix(TIntermTyped *node, TOperator op);
58 
59     void writeShaderStorageBlocksHeader(TInfoSinkBase &out) const;
60 
61   private:
62     void traverseSSBOAccess(TIntermTyped *node, SSBOMethod method);
63     TIntermTyped *traverseNode(TInfoSinkBase &out,
64                                TIntermTyped *node,
65                                BlockMemberInfo *blockMemberInfo);
66     int getMatrixStride(TIntermTyped *node,
67                         TLayoutBlockStorage storage,
68                         bool rowMajor,
69                         bool *isRowMajor) const;
70     TIntermTyped *writeEOpIndexDirectOrIndirectOutput(TInfoSinkBase &out,
71                                                       TIntermBinary *node,
72                                                       BlockMemberInfo *blockMemberInfo);
73     // Common part in dot operations.
74     TIntermTyped *createFieldOffset(const TField *field, BlockMemberInfo *blockMemberInfo);
75     void collectShaderStorageBlocks(TIntermTyped *node);
76     OutputHLSL *mOutputHLSL;
77     ShaderStorageBlockFunctionHLSL *mSSBOFunctionHLSL;
78     ResourcesHLSL *mResourcesHLSL;
79     ReferencedInterfaceBlocks mReferencedShaderStorageBlocks;
80 
81     BlockMemberInfoMap mBlockMemberInfoMap;
82     const std::vector<InterfaceBlock> &mShaderStorageBlocks;
83 };
84 }  // namespace sh
85 
86 #endif  // COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKOUTPUTHLSL_H_
87