• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "QuadRasterizer.hpp"
16 
17 #include "Math.hpp"
18 #include "Primitive.hpp"
19 #include "Renderer.hpp"
20 #include "Constants.hpp"
21 #include "Debug.hpp"
22 
23 namespace sw
24 {
25 	extern bool veryEarlyDepthTest;
26 	extern bool complementaryDepthBuffer;
27 	extern bool fullPixelPositionRegister;
28 
29 	extern int clusterCount;
30 
QuadRasterizer(const PixelProcessor::State & state,const PixelShader * pixelShader)31 	QuadRasterizer::QuadRasterizer(const PixelProcessor::State &state, const PixelShader *pixelShader) : state(state), shader(pixelShader)
32 	{
33 	}
34 
~QuadRasterizer()35 	QuadRasterizer::~QuadRasterizer()
36 	{
37 	}
38 
generate()39 	void QuadRasterizer::generate()
40 	{
41 		#if PERF_PROFILE
42 			for(int i = 0; i < PERF_TIMERS; i++)
43 			{
44 				cycles[i] = 0;
45 			}
46 
47 			Long pixelTime = Ticks();
48 		#endif
49 
50 		constants = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,constants));
51 		occlusion = 0;
52 
53 		Do
54 		{
55 			Int yMin = *Pointer<Int>(primitive + OFFSET(Primitive,yMin));
56 			Int yMax = *Pointer<Int>(primitive + OFFSET(Primitive,yMax));
57 
58 			Int cluster2 = cluster + cluster;
59 			yMin += clusterCount * 2 - 2 - cluster2;
60 			yMin &= -clusterCount * 2;
61 			yMin += cluster2;
62 
63 			If(yMin < yMax)
64 			{
65 				rasterize(yMin, yMax);
66 			}
67 
68 			primitive += sizeof(Primitive) * state.multiSample;
69 			count--;
70 		}
71 		Until(count == 0)
72 
73 		if(state.occlusionEnabled)
74 		{
75 			UInt clusterOcclusion = *Pointer<UInt>(data + OFFSET(DrawData,occlusion) + 4 * cluster);
76 			clusterOcclusion += occlusion;
77 			*Pointer<UInt>(data + OFFSET(DrawData,occlusion) + 4 * cluster) = clusterOcclusion;
78 		}
79 
80 		#if PERF_PROFILE
81 			cycles[PERF_PIXEL] = Ticks() - pixelTime;
82 
83 			for(int i = 0; i < PERF_TIMERS; i++)
84 			{
85 				*Pointer<Long>(data + OFFSET(DrawData,cycles[i]) + 8 * cluster) += cycles[i];
86 			}
87 		#endif
88 
89 		Return();
90 	}
91 
rasterize(Int & yMin,Int & yMax)92 	void QuadRasterizer::rasterize(Int &yMin, Int &yMax)
93 	{
94 		Pointer<Byte> cBuffer[RENDERTARGETS];
95 		Pointer<Byte> zBuffer;
96 		Pointer<Byte> sBuffer;
97 
98 		for(int index = 0; index < RENDERTARGETS; index++)
99 		{
100 			if(state.colorWriteActive(index))
101 			{
102 				cBuffer[index] = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,colorBuffer[index])) + yMin * *Pointer<Int>(data + OFFSET(DrawData,colorPitchB[index]));
103 			}
104 		}
105 
106 		if(state.depthTestActive)
107 		{
108 			zBuffer = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,depthBuffer)) + yMin * *Pointer<Int>(data + OFFSET(DrawData,depthPitchB));
109 		}
110 
111 		if(state.stencilActive)
112 		{
113 			sBuffer = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,stencilBuffer)) + yMin * *Pointer<Int>(data + OFFSET(DrawData,stencilPitchB));
114 		}
115 
116 		Int y = yMin;
117 
118 		Do
119 		{
120 			Int x0a = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->left) + (y + 0) * sizeof(Primitive::Span)));
121 			Int x0b = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->left) + (y + 1) * sizeof(Primitive::Span)));
122 			Int x0 = Min(x0a, x0b);
123 
124 			for(unsigned int q = 1; q < state.multiSample; q++)
125 			{
126 				x0a = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->left) + (y + 0) * sizeof(Primitive::Span)));
127 				x0b = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->left) + (y + 1) * sizeof(Primitive::Span)));
128 				x0 = Min(x0, Min(x0a, x0b));
129 			}
130 
131 			x0 &= 0xFFFFFFFE;
132 
133 			Int x1a = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->right) + (y + 0) * sizeof(Primitive::Span)));
134 			Int x1b = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->right) + (y + 1) * sizeof(Primitive::Span)));
135 			Int x1 = Max(x1a, x1b);
136 
137 			for(unsigned int q = 1; q < state.multiSample; q++)
138 			{
139 				x1a = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->right) + (y + 0) * sizeof(Primitive::Span)));
140 				x1b = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->right) + (y + 1) * sizeof(Primitive::Span)));
141 				x1 = Max(x1, Max(x1a, x1b));
142 			}
143 
144 			Float4 yyyy = Float4(Float(y)) + *Pointer<Float4>(primitive + OFFSET(Primitive,yQuad), 16);
145 
146 			if(interpolateZ())
147 			{
148 				for(unsigned int q = 0; q < state.multiSample; q++)
149 				{
150 					Float4 y = yyyy;
151 
152 					if(state.multiSample > 1)
153 					{
154 						y -= *Pointer<Float4>(constants + OFFSET(Constants,Y) + q * sizeof(float4));
155 					}
156 
157 					Dz[q] = *Pointer<Float4>(primitive + OFFSET(Primitive,z.C), 16) + y * *Pointer<Float4>(primitive + OFFSET(Primitive,z.B), 16);
158 				}
159 			}
160 
161 			if(veryEarlyDepthTest && state.multiSample == 1)
162 			{
163 				if(!state.stencilActive && state.depthTestActive && (state.depthCompareMode == DEPTH_LESSEQUAL || state.depthCompareMode == DEPTH_LESS))   // FIXME: Both modes ok?
164 				{
165 					Float4 xxxx = Float4(Float(x0)) + *Pointer<Float4>(primitive + OFFSET(Primitive,xQuad), 16);
166 
167 					Pointer<Byte> buffer;
168 					Int pitch;
169 
170 					if(!state.quadLayoutDepthBuffer)
171 					{
172 						buffer = zBuffer + 4 * x0;
173 						pitch = *Pointer<Int>(data + OFFSET(DrawData,depthPitchB));
174 					}
175 					else
176 					{
177 						buffer = zBuffer + 8 * x0;
178 					}
179 
180 					For(Int x = x0, x < x1, x += 2)
181 					{
182 						Float4 z = interpolate(xxxx, Dz[0], z, primitive + OFFSET(Primitive,z), false, false);
183 
184 						Float4 zValue;
185 
186 						if(!state.quadLayoutDepthBuffer)
187 						{
188 							// FIXME: Properly optimizes?
189 							zValue.xy = *Pointer<Float4>(buffer);
190 							zValue.zw = *Pointer<Float4>(buffer + pitch - 8);
191 						}
192 						else
193 						{
194 							zValue = *Pointer<Float4>(buffer, 16);
195 						}
196 
197 						Int4 zTest;
198 
199 						if(complementaryDepthBuffer)
200 						{
201 							zTest = CmpLE(zValue, z);
202 						}
203 						else
204 						{
205 							zTest = CmpNLT(zValue, z);
206 						}
207 
208 						Int zMask = SignMask(zTest);
209 
210 						If(zMask == 0)
211 						{
212 							x0 += 2;
213 						}
214 						Else
215 						{
216 							x = x1;
217 						}
218 
219 						xxxx += Float4(2);
220 
221 						if(!state.quadLayoutDepthBuffer)
222 						{
223 							buffer += 8;
224 						}
225 						else
226 						{
227 							buffer += 16;
228 						}
229 					}
230 				}
231 			}
232 
233 			If(x0 < x1)
234 			{
235 				if(interpolateW())
236 				{
237 					Dw = *Pointer<Float4>(primitive + OFFSET(Primitive,w.C), 16) + yyyy * *Pointer<Float4>(primitive + OFFSET(Primitive,w.B), 16);
238 				}
239 
240 				for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
241 				{
242 					for(int component = 0; component < 4; component++)
243 					{
244 						if(state.interpolant[interpolant].component & (1 << component))
245 						{
246 							Dv[interpolant][component] = *Pointer<Float4>(primitive + OFFSET(Primitive,V[interpolant][component].C), 16);
247 
248 							if(!(state.interpolant[interpolant].flat & (1 << component)))
249 							{
250 								Dv[interpolant][component] += yyyy * *Pointer<Float4>(primitive + OFFSET(Primitive,V[interpolant][component].B), 16);
251 							}
252 						}
253 					}
254 				}
255 
256 				if(state.fog.component)
257 				{
258 					Df = *Pointer<Float4>(primitive + OFFSET(Primitive,f.C), 16);
259 
260 					if(!state.fog.flat)
261 					{
262 						Df += yyyy * *Pointer<Float4>(primitive + OFFSET(Primitive,f.B), 16);
263 					}
264 				}
265 
266 				Short4 xLeft[4];
267 				Short4 xRight[4];
268 
269 				for(unsigned int q = 0; q < state.multiSample; q++)
270 				{
271 					xLeft[q] = *Pointer<Short4>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline) + y * sizeof(Primitive::Span));
272 					xRight[q] = xLeft[q];
273 
274 					xLeft[q] = Swizzle(xLeft[q], 0xA0) - Short4(1, 2, 1, 2);
275 					xRight[q] = Swizzle(xRight[q], 0xF5) - Short4(0, 1, 0, 1);
276 				}
277 
278 				For(Int x = x0, x < x1, x += 2)
279 				{
280 					Short4 xxxx = Short4(x);
281 					Int cMask[4];
282 
283 					for(unsigned int q = 0; q < state.multiSample; q++)
284 					{
285 						Short4 mask = CmpGT(xxxx, xLeft[q]) & CmpGT(xRight[q], xxxx);
286 						cMask[q] = SignMask(Pack(mask, mask)) & 0x0000000F;
287 					}
288 
289 					quad(cBuffer, zBuffer, sBuffer, cMask, x, y);
290 				}
291 			}
292 
293 			for(int index = 0; index < RENDERTARGETS; index++)
294 			{
295 				if(state.colorWriteActive(index))
296 				{
297 					cBuffer[index] += *Pointer<Int>(data + OFFSET(DrawData,colorPitchB[index])) << (1 + sw::log2(clusterCount));   // FIXME: Precompute
298 				}
299 			}
300 
301 			if(state.depthTestActive)
302 			{
303 				zBuffer += *Pointer<Int>(data + OFFSET(DrawData,depthPitchB)) << (1 + sw::log2(clusterCount));   // FIXME: Precompute
304 			}
305 
306 			if(state.stencilActive)
307 			{
308 				sBuffer += *Pointer<Int>(data + OFFSET(DrawData,stencilPitchB)) << (1 + sw::log2(clusterCount));   // FIXME: Precompute
309 			}
310 
311 			y += 2 * clusterCount;
312 		}
313 		Until(y >= yMax)
314 	}
315 
interpolate(Float4 & x,Float4 & D,Float4 & rhw,Pointer<Byte> planeEquation,bool flat,bool perspective)316 	Float4 QuadRasterizer::interpolate(Float4 &x, Float4 &D, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective)
317 	{
318 		Float4 interpolant = D;
319 
320 		if(!flat)
321 		{
322 			interpolant += x * *Pointer<Float4>(planeEquation + OFFSET(PlaneEquation, A), 16);
323 
324 			if(perspective)
325 			{
326 				interpolant *= rhw;
327 			}
328 		}
329 
330 		return interpolant;
331 	}
332 
interpolateZ() const333 	bool QuadRasterizer::interpolateZ() const
334 	{
335 		return state.depthTestActive || state.pixelFogActive() || (shader && shader->isVPosDeclared() && fullPixelPositionRegister);
336 	}
337 
interpolateW() const338 	bool QuadRasterizer::interpolateW() const
339 	{
340 		return state.perspective || (shader && shader->isVPosDeclared() && fullPixelPositionRegister);
341 	}
342 }
343