OSDN Git Service

Fix resetting current display when no current context.
[android-x86/external-swiftshader.git] / src / Renderer / TextureStage.cpp
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "TextureStage.hpp"
16
17 #include "Sampler.hpp"
18 #include "Debug.hpp"
19
20 #include <string.h>
21
22 namespace sw
23 {
24         TextureStage::State::State()
25         {
26                 memset(this, 0, sizeof(State));
27         }
28
29         TextureStage::TextureStage() : sampler(0), previousStage(0)
30         {
31         }
32
33         TextureStage::~TextureStage()
34         {
35         }
36
37         void TextureStage::init(int stage, const Sampler *sampler, const TextureStage *previousStage)
38         {
39                 this->stage = stage;
40
41                 stageOperation = (stage == 0 ? STAGE_MODULATE : STAGE_DISABLE);
42                 firstArgument = SOURCE_TEXTURE;
43                 secondArgument = SOURCE_CURRENT;
44                 thirdArgument = SOURCE_CURRENT;
45                 stageOperationAlpha = (stage == 0 ? STAGE_SELECTARG1 : STAGE_DISABLE);
46                 firstArgumentAlpha = SOURCE_DIFFUSE;
47                 secondArgumentAlpha = SOURCE_CURRENT;
48                 thirdArgumentAlpha = SOURCE_CURRENT;
49                 firstModifier = MODIFIER_COLOR;
50                 secondModifier = MODIFIER_COLOR;
51                 thirdModifier = MODIFIER_COLOR;
52             firstModifierAlpha = MODIFIER_COLOR;
53                 secondModifierAlpha = MODIFIER_COLOR;
54                 thirdModifierAlpha = MODIFIER_COLOR;
55                 destinationArgument = DESTINATION_CURRENT;
56
57                 texCoordIndex = stage;
58                 this->sampler = sampler;
59                 this->previousStage = previousStage;
60         }
61
62         TextureStage::State TextureStage::textureStageState() const
63         {
64                 State state;
65
66                 if(!isStageDisabled())
67                 {
68                         state.stageOperation = stageOperation;
69                         state.firstArgument = firstArgument;
70                         state.secondArgument = secondArgument;
71                         state.thirdArgument = thirdArgument;
72                         state.stageOperationAlpha = stageOperationAlpha;
73                         state.firstArgumentAlpha = firstArgumentAlpha;
74                         state.secondArgumentAlpha = secondArgumentAlpha;
75                         state.thirdArgumentAlpha = thirdArgumentAlpha;
76                         state.firstModifier = firstModifier;
77                         state.secondModifier = secondModifier;
78                         state.thirdModifier = thirdModifier;
79                         state.firstModifierAlpha = firstModifierAlpha;
80                         state.secondModifierAlpha = secondModifierAlpha;
81                         state.thirdModifierAlpha = thirdModifierAlpha;
82                         state.destinationArgument = destinationArgument;
83                         state.texCoordIndex = texCoordIndex;
84
85                         state.cantUnderflow = sampler->hasUnsignedTexture() || !usesTexture();
86                         state.usesTexture = usesTexture();
87                 }
88
89                 return state;
90         }
91
92         void TextureStage::setConstantColor(const Color<float> &constantColor)
93         {
94                 // FIXME: Compact into generic function   // FIXME: Clamp
95                 short r = iround(4095 * constantColor.r);
96                 short g = iround(4095 * constantColor.g);
97                 short b = iround(4095 * constantColor.b);
98                 short a = iround(4095 * constantColor.a);
99
100                 uniforms.constantColor4[0][0] = uniforms.constantColor4[0][1] = uniforms.constantColor4[0][2] = uniforms.constantColor4[0][3] = r;
101                 uniforms.constantColor4[1][0] = uniforms.constantColor4[1][1] = uniforms.constantColor4[1][2] = uniforms.constantColor4[1][3] = g;
102                 uniforms.constantColor4[2][0] = uniforms.constantColor4[2][1] = uniforms.constantColor4[2][2] = uniforms.constantColor4[2][3] = b;
103                 uniforms.constantColor4[3][0] = uniforms.constantColor4[3][1] = uniforms.constantColor4[3][2] = uniforms.constantColor4[3][3] = a;
104         }
105
106         void TextureStage::setBumpmapMatrix(int element, float value)
107         {
108                 uniforms.bumpmapMatrix4F[element / 2][element % 2][0] = value;
109                 uniforms.bumpmapMatrix4F[element / 2][element % 2][1] = value;
110                 uniforms.bumpmapMatrix4F[element / 2][element % 2][2] = value;
111                 uniforms.bumpmapMatrix4F[element / 2][element % 2][3] = value;
112
113                 uniforms.bumpmapMatrix4W[element / 2][element % 2][0] = iround(4095 * value);
114                 uniforms.bumpmapMatrix4W[element / 2][element % 2][1] = iround(4095 * value);
115                 uniforms.bumpmapMatrix4W[element / 2][element % 2][2] = iround(4095 * value);
116                 uniforms.bumpmapMatrix4W[element / 2][element % 2][3] = iround(4095 * value);
117         }
118
119         void TextureStage::setLuminanceScale(float value)
120         {
121                 short scale = iround(4095 * value);
122
123                 uniforms.luminanceScale4[0] = uniforms.luminanceScale4[1] = uniforms.luminanceScale4[2] = uniforms.luminanceScale4[3] = scale;
124         }
125
126         void TextureStage::setLuminanceOffset(float value)
127         {
128                 short offset = iround(4095 * value);
129
130                 uniforms.luminanceOffset4[0] = uniforms.luminanceOffset4[1] = uniforms.luminanceOffset4[2] = uniforms.luminanceOffset4[3] = offset;
131         }
132
133         void TextureStage::setTexCoordIndex(unsigned int texCoordIndex)
134         {
135                 ASSERT(texCoordIndex < 8);
136
137                 this->texCoordIndex = texCoordIndex;
138         }
139
140         void TextureStage::setStageOperation(StageOperation stageOperation)
141         {
142                 this->stageOperation = stageOperation;
143         }
144
145         void TextureStage::setFirstArgument(SourceArgument firstArgument)
146         {
147                 this->firstArgument = firstArgument;
148         }
149
150         void TextureStage::setSecondArgument(SourceArgument secondArgument)
151         {
152                 this->secondArgument = secondArgument;
153         }
154
155         void TextureStage::setThirdArgument(SourceArgument thirdArgument)
156         {
157                 this->thirdArgument = thirdArgument;
158         }
159
160         void TextureStage::setStageOperationAlpha(StageOperation stageOperationAlpha)
161         {
162                 this->stageOperationAlpha = stageOperationAlpha;
163         }
164
165         void TextureStage::setFirstArgumentAlpha(SourceArgument firstArgumentAlpha)
166         {
167                 this->firstArgumentAlpha = firstArgumentAlpha;
168         }
169
170         void TextureStage::setSecondArgumentAlpha(SourceArgument secondArgumentAlpha)
171         {
172                 this->secondArgumentAlpha = secondArgumentAlpha;
173         }
174
175         void TextureStage::setThirdArgumentAlpha(SourceArgument thirdArgumentAlpha)
176         {
177                 this->thirdArgumentAlpha= thirdArgumentAlpha;
178         }
179
180         void TextureStage::setFirstModifier(ArgumentModifier firstModifier)
181         {
182                 this->firstModifier = firstModifier;
183         }
184
185         void TextureStage::setSecondModifier(ArgumentModifier secondModifier)
186         {
187                 this->secondModifier = secondModifier;
188         }
189
190         void TextureStage::setThirdModifier(ArgumentModifier thirdModifier)
191         {
192                 this->thirdModifier = thirdModifier;
193         }
194
195         void TextureStage::setFirstModifierAlpha(ArgumentModifier firstModifierAlpha)
196         {
197                 this->firstModifierAlpha = firstModifierAlpha;
198         }
199
200         void TextureStage::setSecondModifierAlpha(ArgumentModifier secondModifierAlpha)
201         {
202                 this->secondModifierAlpha = secondModifierAlpha;
203         }
204
205         void TextureStage::setThirdModifierAlpha(ArgumentModifier thirdModifierAlpha)
206         {
207                 this->thirdModifierAlpha = thirdModifierAlpha;
208         }
209
210         void TextureStage::setDestinationArgument(DestinationArgument destinationArgument)
211         {
212                 this->destinationArgument = destinationArgument;
213         }
214
215         bool TextureStage::usesColor(SourceArgument source) const
216         {
217                 // One argument
218                 if(stageOperation == STAGE_SELECTARG1 || stageOperation == STAGE_PREMODULATE)
219                 {
220                         return firstArgument == source;
221                 }
222                 else if(stageOperation == STAGE_SELECTARG2)
223                 {
224                         return secondArgument == source;
225                 }
226                 else if(stageOperation == STAGE_SELECTARG3)
227                 {
228                         return thirdArgument == source;
229                 }
230                 else
231                 {
232                         // Two arguments or more
233                         if(firstArgument == source || secondArgument == source)
234                         {
235                                 return true;
236                         }
237
238                         // Three arguments
239                         if(stageOperation == STAGE_MULTIPLYADD || stageOperation == STAGE_LERP)
240                         {
241                                 return thirdArgument == source;
242                         }
243                 }
244         
245                 return false;
246         }
247
248         bool TextureStage::usesAlpha(SourceArgument source) const
249         {
250                 if(stageOperationAlpha == STAGE_DISABLE)
251                 {
252                         return false;
253                 }
254
255                 if(source == SOURCE_TEXTURE)
256                 {
257                         if(stageOperation == STAGE_BLENDTEXTUREALPHA || stageOperation == STAGE_BLENDTEXTUREALPHAPM)
258                         {
259                                 return true;
260                         }
261                 }
262                 else if(source == SOURCE_CURRENT)
263                 {
264                         if(stageOperation == STAGE_BLENDCURRENTALPHA)
265                         {
266                                 return true;
267                         }
268                 }
269                 else if(source == SOURCE_DIFFUSE)
270                 {
271                         if(stageOperation == STAGE_BLENDDIFFUSEALPHA)
272                         {
273                                 return true;
274                         }
275                 }
276                 else if(source == SOURCE_TFACTOR)
277                 {
278                         if(stageOperation == STAGE_BLENDFACTORALPHA)
279                         {
280                                 return true;
281                         }
282                 }
283
284                 // One argument
285                 if(stageOperation == STAGE_SELECTARG1 || stageOperation == STAGE_PREMODULATE)
286                 {
287                         if(firstArgument == source && (firstModifier == MODIFIER_ALPHA || firstModifier == MODIFIER_INVALPHA))
288                         {
289                                 return true;
290                         }
291                 }
292                 else if(stageOperation == STAGE_SELECTARG2)
293                 {
294                         if(secondArgument == source && (secondModifier == MODIFIER_ALPHA || secondModifier == MODIFIER_INVALPHA))
295                         {
296                                 return true;
297                         }
298                 }
299                 else if(stageOperation == STAGE_SELECTARG3)
300                 {
301                         if(thirdArgument == source && (thirdModifier == MODIFIER_ALPHA || thirdModifier == MODIFIER_INVALPHA))
302                         {
303                                 return true;
304                         }
305                 }
306                 else
307                 {
308                         // Two arguments or more
309                         if(firstArgument == source || secondArgument == source)
310                         {
311                                 if(firstArgument == source && (firstModifier == MODIFIER_ALPHA || firstModifier == MODIFIER_INVALPHA))
312                                 {
313                                         return true;
314                                 }
315
316                                 if(secondArgument == source && (secondModifier == MODIFIER_ALPHA || secondModifier == MODIFIER_INVALPHA))
317                                 {
318                                         return true;
319                                 }
320                         }
321
322                         // Three arguments
323                         if(stageOperation == STAGE_MULTIPLYADD || stageOperation == STAGE_LERP)
324                         {
325                                 if(thirdArgument == source && (thirdModifier == MODIFIER_ALPHA || thirdModifier == MODIFIER_INVALPHA))
326                                 {
327                                         return true;
328                                 }
329                         }
330                 }
331
332                 // One argument
333                 if(stageOperationAlpha == STAGE_SELECTARG1 || stageOperationAlpha == STAGE_PREMODULATE)
334                 {
335                         return firstArgumentAlpha == source;
336                 }
337                 else if(stageOperationAlpha == STAGE_SELECTARG2)
338                 {
339                         return secondArgumentAlpha == source;
340                 }
341                 else if(stageOperationAlpha == STAGE_SELECTARG3)
342                 {
343                         return thirdArgumentAlpha == source;
344                 }
345                 else
346                 {
347                         // Two arguments or more
348                         if(firstArgumentAlpha == source || secondArgumentAlpha == source)
349                         {
350                                 return true;
351                         }
352
353                         // Three arguments
354                         if(stageOperationAlpha == STAGE_MULTIPLYADD || stageOperationAlpha == STAGE_LERP)
355                         {
356                                 return thirdArgumentAlpha == source;
357                         }
358                 }
359                 
360                 return false;
361         }
362
363         bool TextureStage::uses(SourceArgument source) const
364         {
365                 return usesColor(source) || usesAlpha(source);
366         }
367
368         bool TextureStage::usesCurrent() const
369         {
370                 return uses(SOURCE_CURRENT) || (stageOperation == STAGE_BLENDCURRENTALPHA || stageOperationAlpha == STAGE_BLENDCURRENTALPHA);
371         }
372
373         bool TextureStage::usesDiffuse() const
374         {
375                 return uses(SOURCE_DIFFUSE) || (stageOperation == STAGE_BLENDDIFFUSEALPHA || stageOperationAlpha == STAGE_BLENDDIFFUSEALPHA);
376         }
377
378         bool TextureStage::usesSpecular() const
379         {
380                 return uses(SOURCE_SPECULAR);
381         }
382
383         bool TextureStage::usesTexture() const
384         {
385                 return uses(SOURCE_TEXTURE) ||
386                        stageOperation == STAGE_BLENDTEXTUREALPHA ||
387                        stageOperationAlpha == STAGE_BLENDTEXTUREALPHA ||
388                        stageOperation == STAGE_BLENDTEXTUREALPHAPM ||
389                        stageOperationAlpha == STAGE_BLENDTEXTUREALPHAPM ||
390                        (previousStage && previousStage->stageOperation == STAGE_PREMODULATE) ||
391                        (previousStage && previousStage->stageOperationAlpha == STAGE_PREMODULATE);
392         }
393
394         bool TextureStage::isStageDisabled() const
395         {
396                 bool disabled = (stageOperation == STAGE_DISABLE) || (!sampler->hasTexture() && usesTexture());
397
398                 if(!previousStage || disabled)
399                 {
400                         return disabled;
401                 }
402                 else
403                 {
404                         return previousStage->isStageDisabled();
405                 }
406         }
407
408         bool TextureStage::writesCurrent() const
409         {
410                 return !isStageDisabled() && destinationArgument == DESTINATION_CURRENT && stageOperation != STAGE_BUMPENVMAP && stageOperation != STAGE_BUMPENVMAPLUMINANCE;
411         }
412 }