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