1 //
2 // Copyright 2016 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 #include "pxr/imaging/hdSt/shaderKey.h"
25
26 #include "pxr/base/tf/iterator.h"
27 #include "pxr/base/tf/token.h"
28 #include <boost/functional/hash.hpp>
29 #include <sstream>
30
31 PXR_NAMESPACE_OPEN_SCOPE
32
33 /*virtual*/
~HdSt_ShaderKey()34 HdSt_ShaderKey::~HdSt_ShaderKey()
35 {
36 /*NOTHING*/
37 }
38
39 HdSt_ShaderKey::ID
ComputeHash() const40 HdSt_ShaderKey::ComputeHash() const
41 {
42 ID hash = GetGlslfxFilename().Hash();
43
44 TfToken const *VS = GetVS();
45 TfToken const *TCS = GetTCS();
46 TfToken const *TES = GetTES();
47 TfToken const *GS = GetGS();
48 TfToken const *FS = GetFS();
49
50 while (VS && (!VS->IsEmpty())) {
51 boost::hash_combine(hash, VS->Hash());
52 ++VS;
53 }
54 while (TCS && (!TCS->IsEmpty())) {
55 boost::hash_combine(hash, TCS->Hash());
56 ++TCS;
57 }
58 while (TES && (!TES->IsEmpty())) {
59 boost::hash_combine(hash, TES->Hash());
60 ++TES;
61 }
62 while (GS && (!GS->IsEmpty())) {
63 boost::hash_combine(hash, GS->Hash());
64 ++GS;
65 }
66 while (FS && (!FS->IsEmpty())) {
67 boost::hash_combine(hash, FS->Hash());
68 ++FS;
69 }
70
71 // During batching, we rely on geometric shader equality, and thus the
72 // shaderKey hash factors the following state opinions besides the mixins
73 // themselves.
74 // Note that the GLSL programs still can be shared across GeometricShader
75 // instances, when they are identical except the GL states, as long as
76 // Hd_GeometricShader::ComputeHash() provides consistent hash values.
77 boost::hash_combine(hash, GetPrimitiveType());
78 boost::hash_combine(hash, GetCullStyle());
79 boost::hash_combine(hash, UseHardwareFaceCulling());
80 if (UseHardwareFaceCulling()) {
81 boost::hash_combine(hash, HasMirroredTransform());
82 boost::hash_combine(hash, IsDoubleSided());
83 }
84 boost::hash_combine(hash, GetPolygonMode());
85 boost::hash_combine(hash, IsFrustumCullingPass());
86 boost::hash_combine(hash, GetLineWidth());
87 boost::hash_combine(hash, GetFvarPatchType());
88
89 return hash;
90 }
91
92 static
93 std::string
_JoinTokens(const char * stage,TfToken const * tokens,bool * firstStage)94 _JoinTokens(const char *stage, TfToken const *tokens, bool *firstStage)
95 {
96 if ((!tokens) || tokens->IsEmpty()) return std::string();
97
98 std::stringstream ss;
99
100 if (*firstStage == false) ss << ", ";
101 *firstStage = false;
102
103 ss << "\"" << stage << "\" : { "
104 << "\"source\" : [";
105
106 bool first = true;
107 while (!tokens->IsEmpty()) {
108 if (first == false) ss << ", ";
109 ss << "\"" << tokens->GetText() << "\"";
110 ++tokens;
111 first = false;
112 }
113
114 ss << "] }\n";
115 return ss.str();
116 }
117
118 std::string
GetGlslfxString() const119 HdSt_ShaderKey::GetGlslfxString() const
120 {
121 std::stringstream ss;
122
123 ss << "-- glslfx version 0.1\n";
124
125 if (!GetGlslfxFilename().IsEmpty())
126 ss << "#import $TOOLS/hdSt/shaders/"
127 << GetGlslfxFilename().GetText() << "\n";
128
129 ss << "-- configuration\n"
130 << "{\"techniques\": {\"default\": {\n";
131
132 bool firstStage = true;
133 ss << _JoinTokens("vertexShader", GetVS(), &firstStage);
134 ss << _JoinTokens("tessControlShader", GetTCS(), &firstStage);
135 ss << _JoinTokens("tessEvalShader", GetTES(), &firstStage);
136 ss << _JoinTokens("geometryShader", GetGS(), &firstStage);
137 ss << _JoinTokens("fragmentShader", GetFS(), &firstStage);
138 ss << "}}}\n";
139
140 return ss.str();
141 }
142
143 /*virtual*/
144 TfToken const*
GetVS() const145 HdSt_ShaderKey::GetVS() const
146 {
147 return nullptr;
148 }
149
150 /*virtual*/
151 TfToken const*
GetTCS() const152 HdSt_ShaderKey::GetTCS() const
153 {
154 return nullptr;
155 }
156
157 /*virtual*/
158 TfToken const*
GetTES() const159 HdSt_ShaderKey::GetTES() const
160 {
161 return nullptr;
162 }
163
164 /*virtual*/
165 TfToken const*
GetGS() const166 HdSt_ShaderKey::GetGS() const
167 {
168 return nullptr;
169 }
170
171 /*virtual*/
172 TfToken const*
GetFS() const173 HdSt_ShaderKey::GetFS() const
174 {
175 return nullptr;
176 }
177
178 /*virtual*/
179 bool
IsFrustumCullingPass() const180 HdSt_ShaderKey::IsFrustumCullingPass() const
181 {
182 return false;
183 }
184
185 /*virtual*/
186 HdCullStyle
GetCullStyle() const187 HdSt_ShaderKey::GetCullStyle() const
188 {
189 return HdCullStyleDontCare;
190 }
191
192 /*virtual*/
193 bool
UseHardwareFaceCulling() const194 HdSt_ShaderKey::UseHardwareFaceCulling() const
195 {
196 return false;
197 }
198
199 /*virtual*/
200 bool
HasMirroredTransform() const201 HdSt_ShaderKey::HasMirroredTransform() const
202 {
203 return false;
204 }
205
206 /*virtual*/
207 bool
IsDoubleSided() const208 HdSt_ShaderKey::IsDoubleSided() const
209 {
210 return false;
211 }
212
213 /*virtual*/
214 HdPolygonMode
GetPolygonMode() const215 HdSt_ShaderKey::GetPolygonMode() const
216 {
217 return HdPolygonModeFill;
218 }
219
220 /*virtual*/
221 float
GetLineWidth() const222 HdSt_ShaderKey::GetLineWidth() const
223 {
224 return 0.0f;
225 }
226
227 /*virtual*/
228 HdSt_GeometricShader::FvarPatchType
GetFvarPatchType() const229 HdSt_ShaderKey::GetFvarPatchType() const {
230 return HdSt_GeometricShader::FvarPatchType::PATCH_NONE;
231 }
232
233 PXR_NAMESPACE_CLOSE_SCOPE
234
235