OSDN Git Service

Fix resetting current display when no current context.
[android-x86/external-swiftshader.git] / src / Renderer / SetupProcessor.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 "SetupProcessor.hpp"
16
17 #include "SetupRoutine.hpp"
18 #include "Primitive.hpp"
19 #include "Polygon.hpp"
20 #include "Context.hpp"
21 #include "Renderer.hpp"
22 #include "Constants.hpp"
23 #include "Debug.hpp"
24
25 namespace sw
26 {
27         extern bool complementaryDepthBuffer;
28         extern bool fullPixelPositionRegister;
29
30         bool precacheSetup = false;
31
32         unsigned int SetupProcessor::States::computeHash()
33         {
34                 unsigned int *state = (unsigned int*)this;
35                 unsigned int hash = 0;
36
37                 for(unsigned int i = 0; i < sizeof(States) / 4; i++)
38                 {
39                         hash ^= state[i];
40                 }
41
42                 return hash;
43         }
44
45         SetupProcessor::State::State(int i)
46         {
47                 memset(this, 0, sizeof(State));
48         }
49
50         bool SetupProcessor::State::operator==(const State &state) const
51         {
52                 if(hash != state.hash)
53                 {
54                         return false;
55                 }
56
57                 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
58         }
59
60         SetupProcessor::SetupProcessor(Context *context) : context(context)
61         {
62                 routineCache = 0;
63                 setRoutineCacheSize(1024);
64         }
65
66         SetupProcessor::~SetupProcessor()
67         {
68                 delete routineCache;
69                 routineCache = 0;
70         }
71
72         SetupProcessor::State SetupProcessor::update() const
73         {
74                 State state;
75
76                 bool vPosZW = (context->pixelShader && context->pixelShader->isVPosDeclared() && fullPixelPositionRegister);
77
78                 state.isDrawPoint = context->isDrawPoint(true);
79                 state.isDrawLine = context->isDrawLine(true);
80                 state.isDrawTriangle = context->isDrawTriangle(false);
81                 state.isDrawSolidTriangle = context->isDrawTriangle(true);
82                 state.interpolateZ = context->depthBufferActive() || context->pixelFogActive() != FOG_NONE || vPosZW;
83                 state.interpolateW = context->perspectiveActive() || vPosZW;
84                 state.perspective = context->perspectiveActive();
85                 state.pointSprite = context->pointSpriteActive();
86                 state.cullMode = context->cullMode;
87                 state.twoSidedStencil = context->stencilActive() && context->twoSidedStencil;
88                 state.slopeDepthBias = slopeDepthBias != 0.0f;
89                 state.vFace = context->pixelShader && context->pixelShader->isVFaceDeclared();
90
91                 state.positionRegister = Pos;
92                 state.pointSizeRegister = Unused;
93
94                 state.multiSample = context->getMultiSampleCount();
95                 state.rasterizerDiscard = context->rasterizerDiscard;
96
97                 if(context->vertexShader)
98                 {
99                         state.positionRegister = context->vertexShader->getPositionRegister();
100                         state.pointSizeRegister = context->vertexShader->getPointSizeRegister();
101                 }
102                 else if(context->pointSizeActive())
103                 {
104                         state.pointSizeRegister = Pts;
105                 }
106
107                 for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
108                 {
109                         for(int component = 0; component < 4; component++)
110                         {
111                                 state.gradient[interpolant][component].attribute = Unused;
112                                 state.gradient[interpolant][component].flat = false;
113                                 state.gradient[interpolant][component].wrap = false;
114                         }
115                 }
116
117                 state.fog.attribute = Unused;
118                 state.fog.flat = false;
119                 state.fog.wrap = false;
120
121                 const bool point = context->isDrawPoint(true);
122                 const bool sprite = context->pointSpriteActive();
123                 const bool flatShading = (context->shadingMode == SHADING_FLAT) || point;
124
125                 if(context->vertexShader && context->pixelShader)
126                 {
127                         for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
128                         {
129                                 for(int component = 0; component < 4; component++)
130                                 {
131                                         int project = context->isProjectionComponent(interpolant - 2, component) ? 1 : 0;
132                                         const Shader::Semantic& semantic = context->pixelShader->getInput(interpolant, component - project);
133
134                                         if(semantic.active())
135                                         {
136                                                 int input = interpolant;
137                                                 for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
138                                                 {
139                                                         if(semantic == context->vertexShader->getOutput(i, component - project))
140                                                         {
141                                                                 input = i;
142                                                                 break;
143                                                         }
144                                                 }
145
146                                                 bool flat = point;
147
148                                                 switch(semantic.usage)
149                                                 {
150                                                 case Shader::USAGE_TEXCOORD: flat = point && !sprite;             break;
151                                                 case Shader::USAGE_COLOR:    flat = semantic.flat || flatShading; break;
152                                                 }
153
154                                                 state.gradient[interpolant][component].attribute = input;
155                                                 state.gradient[interpolant][component].flat = flat;
156                                         }
157                                 }
158                         }
159                 }
160                 else if(context->preTransformed && context->pixelShader)
161                 {
162                         for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
163                         {
164                                 for(int component = 0; component < 4; component++)
165                                 {
166                                         const Shader::Semantic& semantic = context->pixelShader->getInput(interpolant, component);
167
168                                         switch(semantic.usage)
169                                         {
170                                         case 0xFF:
171                                                 break;
172                                         case Shader::USAGE_TEXCOORD:
173                                                 state.gradient[interpolant][component].attribute = T0 + semantic.index;
174                                                 state.gradient[interpolant][component].flat = semantic.flat || (point && !sprite);
175                                                 break;
176                                         case Shader::USAGE_COLOR:
177                                                 state.gradient[interpolant][component].attribute = C0 + semantic.index;
178                                                 state.gradient[interpolant][component].flat = semantic.flat || flatShading;
179                                                 break;
180                                         default:
181                                                 ASSERT(false);
182                                         }
183                                 }
184                         }
185                 }
186                 else if(context->pixelShaderVersion() < 0x0300)
187                 {
188                         for(int coordinate = 0; coordinate < 8; coordinate++)
189                         {
190                                 for(int component = 0; component < 4; component++)
191                                 {
192                                         if(context->textureActive(coordinate, component))
193                                         {
194                                                 state.texture[coordinate][component].attribute = T0 + coordinate;
195                                                 state.texture[coordinate][component].flat = point && !sprite;
196                                                 state.texture[coordinate][component].wrap = (context->textureWrap[coordinate] & (1 << component)) != 0;
197                                         }
198                                 }
199                         }
200
201                         for(int color = 0; color < 2; color++)
202                         {
203                                 for(int component = 0; component < 4; component++)
204                                 {
205                                         if(context->colorActive(color, component))
206                                         {
207                                                 state.color[color][component].attribute = C0 + color;
208                                                 state.color[color][component].flat = flatShading;
209                                         }
210                                 }
211                         }
212                 }
213                 else ASSERT(false);
214
215                 if(context->fogActive())
216                 {
217                         state.fog.attribute = Fog;
218                         state.fog.flat = point;
219                 }
220
221                 state.hash = state.computeHash();
222
223                 return state;
224         }
225
226         Routine *SetupProcessor::routine(const State &state)
227         {
228                 Routine *routine = routineCache->query(state);
229
230                 if(!routine)
231                 {
232                         SetupRoutine *generator = new SetupRoutine(state);
233                         generator->generate();
234                         routine = generator->getRoutine();
235                         delete generator;
236
237                         routineCache->add(state, routine);
238                 }
239
240                 return routine;
241         }
242
243         void SetupProcessor::setRoutineCacheSize(int cacheSize)
244         {
245                 delete routineCache;
246                 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheSetup ? "sw-setup" : 0);
247         }
248 }