1 //
2 // Copyright 2020 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #include "pxr/imaging/hgiVulkan/shaderSection.h"
26 
27 PXR_NAMESPACE_OPEN_SCOPE
28 
HgiVulkanShaderSection(const std::string & identifier,const HgiShaderSectionAttributeVector & attributes,const std::string & storageQualifier,const std::string & defaultValue)29 HgiVulkanShaderSection::HgiVulkanShaderSection(
30     const std::string &identifier,
31     const HgiShaderSectionAttributeVector &attributes,
32     const std::string &storageQualifier,
33     const std::string &defaultValue)
34   : HgiShaderSection(identifier, attributes, defaultValue)
35   , _storageQualifier(storageQualifier)
36 {
37 }
38 
39 HgiVulkanShaderSection::~HgiVulkanShaderSection() = default;
40 
41 void
WriteDeclaration(std::ostream & ss) const42 HgiVulkanShaderSection::WriteDeclaration(std::ostream &ss) const
43 {
44     //If it has attributes, write them with corresponding layout
45     //identifiers and indicies
46     const HgiShaderSectionAttributeVector &attributes = GetAttributes();
47 
48     if(!attributes.empty()) {
49         ss << "layout(";
50         for (size_t i = 0; i < attributes.size(); ++i) {
51             const HgiShaderSectionAttribute &a = attributes[i];
52             if (i > 0) {
53                 ss << ", ";
54             }
55             ss << a.identifier;
56             if(!a.index.empty()) {
57                 ss << " = " << a.index;
58             }
59         }
60         ss << ") ";
61     }
62     //If it has a storage qualifier, declare it
63     if(!_storageQualifier.empty()) {
64         ss << _storageQualifier << " ";
65     }
66     WriteType(ss);
67     ss << " ";
68     WriteIdentifier(ss);
69     ss << ";";
70 }
71 
72 void
WriteParameter(std::ostream & ss) const73 HgiVulkanShaderSection::WriteParameter(std::ostream &ss) const
74 {
75     WriteType(ss);
76     ss << " ";
77     WriteIdentifier(ss);
78     ss << ";";
79 }
80 
81 bool
VisitGlobalIncludes(std::ostream & ss)82 HgiVulkanShaderSection::VisitGlobalIncludes(std::ostream &ss)
83 {
84     return false;
85 }
86 
87 bool
VisitGlobalMacros(std::ostream & ss)88 HgiVulkanShaderSection::VisitGlobalMacros(std::ostream &ss)
89 {
90     return false;
91 }
92 
93 bool
VisitGlobalStructs(std::ostream & ss)94 HgiVulkanShaderSection::VisitGlobalStructs(std::ostream &ss)
95 {
96     return false;
97 }
98 
VisitGlobalMemberDeclarations(std::ostream & ss)99 bool HgiVulkanShaderSection::VisitGlobalMemberDeclarations(std::ostream &ss)
100 {
101     return false;
102 }
103 
104 bool
VisitGlobalFunctionDefinitions(std::ostream & ss)105 HgiVulkanShaderSection::VisitGlobalFunctionDefinitions(std::ostream &ss)
106 {
107     return false;
108 }
109 
HgiVulkanMacroShaderSection(const std::string & macroDeclaration,const std::string & macroComment)110 HgiVulkanMacroShaderSection::HgiVulkanMacroShaderSection(
111     const std::string &macroDeclaration,
112     const std::string &macroComment)
113   : HgiVulkanShaderSection(macroDeclaration)
114   , _macroComment(macroComment)
115 {
116 }
117 
118 HgiVulkanMacroShaderSection::~HgiVulkanMacroShaderSection() = default;
119 
120 bool
VisitGlobalMacros(std::ostream & ss)121 HgiVulkanMacroShaderSection::VisitGlobalMacros(std::ostream &ss)
122 {
123     WriteIdentifier(ss);
124     return true;
125 }
126 
HgiVulkanMemberShaderSection(const std::string & identifier,const std::string & typeName,const HgiShaderSectionAttributeVector & attributes,const std::string & storageQualifier,const std::string & defaultValue)127 HgiVulkanMemberShaderSection::HgiVulkanMemberShaderSection(
128     const std::string &identifier,
129     const std::string &typeName,
130     const HgiShaderSectionAttributeVector &attributes,
131     const std::string &storageQualifier,
132     const std::string &defaultValue)
133   : HgiVulkanShaderSection(identifier,
134                            attributes,
135                            storageQualifier,
136                            defaultValue)
137   , _typeName(typeName)
138 {
139 }
140 
141 HgiVulkanMemberShaderSection::~HgiVulkanMemberShaderSection() = default;
142 
143 bool
VisitGlobalMemberDeclarations(std::ostream & ss)144 HgiVulkanMemberShaderSection::VisitGlobalMemberDeclarations(std::ostream &ss)
145 {
146     WriteDeclaration(ss);
147     return true;
148 }
149 
150 void
WriteType(std::ostream & ss) const151 HgiVulkanMemberShaderSection::WriteType(std::ostream& ss) const
152 {
153     ss << _typeName;
154 }
155 
HgiVulkanBlockShaderSection(const std::string & identifier,const HgiShaderFunctionParamDescVector & parameters)156 HgiVulkanBlockShaderSection::HgiVulkanBlockShaderSection(
157     const std::string &identifier,
158     const HgiShaderFunctionParamDescVector &parameters)
159   : HgiVulkanShaderSection(identifier)
160   , _parameters(parameters)
161 {
162 }
163 
164 HgiVulkanBlockShaderSection::~HgiVulkanBlockShaderSection() = default;
165 
166 bool
VisitGlobalMemberDeclarations(std::ostream & ss)167 HgiVulkanBlockShaderSection::VisitGlobalMemberDeclarations(std::ostream &ss)
168 {
169     ss << "layout(push_constant) " << "uniform" << " ";
170     WriteIdentifier(ss);
171     ss << "\n";
172     ss << "{\n";
173     for(const HgiShaderFunctionParamDesc &param : _parameters) {
174         ss << "    " << param.type << " " << param.nameInShader << ";\n";
175     }
176     ss << "\n};";
177     return true;
178 }
179 
HgiVulkanTextureShaderSection(const std::string & identifier,const unsigned int layoutIndex,const unsigned int dimensions,const HgiShaderSectionAttributeVector & attributes,const std::string & defaultValue)180 HgiVulkanTextureShaderSection::HgiVulkanTextureShaderSection(
181     const std::string &identifier,
182     const unsigned int layoutIndex,
183     const unsigned int dimensions,
184     const HgiShaderSectionAttributeVector &attributes,
185     const std::string &defaultValue)
186   : HgiVulkanShaderSection( identifier,
187                             attributes,
188                             "uniform",
189                             defaultValue)
190   , _dimensions(dimensions)
191 {
192 }
193 
194 HgiVulkanTextureShaderSection::~HgiVulkanTextureShaderSection() = default;
195 
196 void
WriteType(std::ostream & ss) const197 HgiVulkanTextureShaderSection::WriteType(std::ostream &ss) const
198 {
199     if(_dimensions < 1 || _dimensions > 3) {
200         TF_CODING_ERROR("Invalid texture dimension");
201     }
202     ss << "sampler" << _dimensions << "D";
203 }
204 
205 bool
VisitGlobalMemberDeclarations(std::ostream & ss)206 HgiVulkanTextureShaderSection::VisitGlobalMemberDeclarations(std::ostream &ss)
207 {
208     WriteDeclaration(ss);
209     return true;
210 }
211 
212 bool
VisitGlobalFunctionDefinitions(std::ostream & ss)213 HgiVulkanTextureShaderSection::VisitGlobalFunctionDefinitions(std::ostream &ss)
214 {
215     //Write a function that let's you query the texture with HDGet_texName(uv)
216     //Used to unify texture sampling across platforms that depend on samplers
217     //and don't store textures in global space
218     ss << "vec4 HdGet_";
219     WriteIdentifier(ss);
220     ss << "(vec" << _dimensions
221              << " uv) {\n";
222     ss << "    vec4 result = texture(";
223     WriteIdentifier(ss);
224     ss << ", uv);\n";
225     ss << "    return result;\n";
226     ss << "}";
227 
228     //Same except for texelfetch
229     if(_dimensions != 2) {
230         return true;
231     }
232 
233     ss << "vec4 HdTexelFetch_";
234     WriteIdentifier(ss);
235     ss << "(ivec2 coord) {\n";
236     ss << "    vec4 result = texelFetch(";
237     WriteIdentifier(ss);
238     ss << ", coord, 0);\n";
239     ss << "    return result;\n";
240     ss << "}\n";
241 
242     return true;
243 }
244 
HgiVulkanBufferShaderSection(const std::string & identifier,const uint32_t layoutIndex,const std::string & type,const HgiShaderSectionAttributeVector & attributes)245 HgiVulkanBufferShaderSection::HgiVulkanBufferShaderSection(
246     const std::string &identifier,
247     const uint32_t layoutIndex,
248     const std::string &type,
249     const HgiShaderSectionAttributeVector &attributes)
250   : HgiVulkanShaderSection( identifier,
251                         attributes,
252                         "buffer",
253                         "")
254   , _type(type)
255 {
256 }
257 
258 HgiVulkanBufferShaderSection::~HgiVulkanBufferShaderSection() = default;
259 
260 void
WriteType(std::ostream & ss) const261 HgiVulkanBufferShaderSection::WriteType(std::ostream &ss) const
262 {
263     ss << _type;
264 }
265 
266 bool
VisitGlobalMemberDeclarations(std::ostream & ss)267 HgiVulkanBufferShaderSection::VisitGlobalMemberDeclarations(std::ostream &ss)
268 {
269     //If it has attributes, write them with corresponding layout
270     //identifiers and indicies
271     const HgiShaderSectionAttributeVector &attributes = GetAttributes();
272 
273     if(!attributes.empty()) {
274         ss << "layout(";
275         for (size_t i = 0; i < attributes.size(); i++)
276         {
277             if (i > 0) {
278                 ss << ", ";
279             }
280             const HgiShaderSectionAttribute &a = attributes[i];
281             ss << a.identifier;
282             if(!a.index.empty()) {
283                 ss << " = " << a.index;
284             }
285         }
286         ss << ") ";
287     }
288     //If it has a storage qualifier, declare it
289     ss << " buffer ";
290     WriteIdentifier(ss);
291     ss << " { ";
292     WriteType(ss);
293     ss << " ";
294     WriteIdentifier(ss);
295     ss << "[]; };";
296 
297     return true;
298 }
299 
HgiVulkanKeywordShaderSection(const std::string & identifier,const std::string & type,const std::string & keyword)300 HgiVulkanKeywordShaderSection::HgiVulkanKeywordShaderSection(
301     const std::string &identifier,
302     const std::string &type,
303     const std::string &keyword)
304   : HgiVulkanShaderSection(identifier)
305   , _type(type)
306   , _keyword(keyword)
307 {
308 }
309 
310 HgiVulkanKeywordShaderSection::~HgiVulkanKeywordShaderSection() = default;
311 
312 void
WriteType(std::ostream & ss) const313 HgiVulkanKeywordShaderSection::WriteType(std::ostream &ss) const
314 {
315     ss << _type;
316 }
317 
318 bool
VisitGlobalMemberDeclarations(std::ostream & ss)319 HgiVulkanKeywordShaderSection::VisitGlobalMemberDeclarations(std::ostream &ss)
320 {
321     WriteType(ss);
322     ss << " ";
323     WriteIdentifier(ss);
324     ss << " = ";
325     ss << _keyword;
326     ss << ";";
327 
328     return true;
329 }
330 
331 PXR_NAMESPACE_CLOSE_SCOPE
332