blob: 691d3255996a110ac11d41d7f610927dcb4a2538 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman89401822014-05-06 15:04:28 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// 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
John Bauman89401822014-05-06 15:04:28 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
John Bauman89401822014-05-06 15:04:28 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// 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.
John Bauman89401822014-05-06 15:04:28 -040014
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
23namespace sw
24{
25 extern bool veryEarlyDepthTest;
26 extern bool complementaryDepthBuffer;
Alexis Hetuf2a8c372015-07-13 11:08:41 -040027 extern bool fullPixelPositionRegister;
John Bauman89401822014-05-06 15:04:28 -040028
29 extern int clusterCount;
30
Nicolas Capensba53fbf2016-01-14 13:43:42 -050031 QuadRasterizer::QuadRasterizer(const PixelProcessor::State &state, const PixelShader *pixelShader) : state(state), shader(pixelShader)
John Bauman89401822014-05-06 15:04:28 -040032 {
33 }
34
35 QuadRasterizer::~QuadRasterizer()
36 {
37 }
38
39 void QuadRasterizer::generate()
40 {
Nicolas Capens4f172c72016-01-13 08:34:30 -050041 #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
Nicolas Capens4f172c72016-01-13 08:34:30 -050050 constants = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,constants));
51 occlusion = 0;
52
53 Do
John Bauman89401822014-05-06 15:04:28 -040054 {
Nicolas Capens4f172c72016-01-13 08:34:30 -050055 Int yMin = *Pointer<Int>(primitive + OFFSET(Primitive,yMin));
56 Int yMax = *Pointer<Int>(primitive + OFFSET(Primitive,yMax));
John Bauman89401822014-05-06 15:04:28 -040057
Nicolas Capens4f172c72016-01-13 08:34:30 -050058 Int cluster2 = cluster + cluster;
59 yMin += clusterCount * 2 - 2 - cluster2;
60 yMin &= -clusterCount * 2;
61 yMin += cluster2;
John Bauman89401822014-05-06 15:04:28 -040062
Nicolas Capens4f172c72016-01-13 08:34:30 -050063 If(yMin < yMax)
John Bauman89401822014-05-06 15:04:28 -040064 {
Nicolas Capens4f172c72016-01-13 08:34:30 -050065 rasterize(yMin, yMax);
John Bauman89401822014-05-06 15:04:28 -040066 }
67
Nicolas Capens4f172c72016-01-13 08:34:30 -050068 primitive += sizeof(Primitive) * state.multiSample;
69 count--;
70 }
71 Until(count == 0)
John Bauman89401822014-05-06 15:04:28 -040072
Nicolas Capens4f172c72016-01-13 08:34:30 -050073 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;
John Bauman89401822014-05-06 15:04:28 -040078 }
79
Nicolas Capens4f172c72016-01-13 08:34:30 -050080 #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();
John Bauman89401822014-05-06 15:04:28 -040090 }
91
Nicolas Capens4f172c72016-01-13 08:34:30 -050092 void QuadRasterizer::rasterize(Int &yMin, Int &yMax)
John Bauman89401822014-05-06 15:04:28 -040093 {
Alexis Hetu1edcd8b2015-11-05 11:12:41 -050094 Pointer<Byte> cBuffer[RENDERTARGETS];
John Bauman89401822014-05-06 15:04:28 -040095 Pointer<Byte> zBuffer;
96 Pointer<Byte> sBuffer;
97
Alexis Hetu1edcd8b2015-11-05 11:12:41 -050098 for(int index = 0; index < RENDERTARGETS; index++)
John Bauman89401822014-05-06 15:04:28 -040099 {
100 if(state.colorWriteActive(index))
101 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500102 cBuffer[index] = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,colorBuffer[index])) + yMin * *Pointer<Int>(data + OFFSET(DrawData,colorPitchB[index]));
John Bauman89401822014-05-06 15:04:28 -0400103 }
104 }
105
106 if(state.depthTestActive)
107 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500108 zBuffer = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,depthBuffer)) + yMin * *Pointer<Int>(data + OFFSET(DrawData,depthPitchB));
John Bauman89401822014-05-06 15:04:28 -0400109 }
110
111 if(state.stencilActive)
112 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500113 sBuffer = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,stencilBuffer)) + yMin * *Pointer<Int>(data + OFFSET(DrawData,stencilPitchB));
John Bauman89401822014-05-06 15:04:28 -0400114 }
115
116 Int y = yMin;
Nicolas Capens81f18302016-01-14 09:32:35 -0500117
John Bauman89401822014-05-06 15:04:28 -0400118 Do
119 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500120 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)));
Nicolas Capensc50d35d2015-01-27 01:52:41 -0500122 Int x0 = Min(x0a, x0b);
Nicolas Capens81f18302016-01-14 09:32:35 -0500123
John Bauman89401822014-05-06 15:04:28 -0400124 for(unsigned int q = 1; q < state.multiSample; q++)
125 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500126 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)));
Nicolas Capensc50d35d2015-01-27 01:52:41 -0500128 x0 = Min(x0, Min(x0a, x0b));
John Bauman89401822014-05-06 15:04:28 -0400129 }
Nicolas Capens81f18302016-01-14 09:32:35 -0500130
John Bauman89401822014-05-06 15:04:28 -0400131 x0 &= 0xFFFFFFFE;
132
Nicolas Capens4f172c72016-01-13 08:34:30 -0500133 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)));
Nicolas Capensc50d35d2015-01-27 01:52:41 -0500135 Int x1 = Max(x1a, x1b);
John Bauman89401822014-05-06 15:04:28 -0400136
137 for(unsigned int q = 1; q < state.multiSample; q++)
138 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500139 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)));
Nicolas Capensc50d35d2015-01-27 01:52:41 -0500141 x1 = Max(x1, Max(x1a, x1b));
John Bauman89401822014-05-06 15:04:28 -0400142 }
143
Nicolas Capens4f172c72016-01-13 08:34:30 -0500144 Float4 yyyy = Float4(Float(y)) + *Pointer<Float4>(primitive + OFFSET(Primitive,yQuad), 16);
John Bauman89401822014-05-06 15:04:28 -0400145
John Bauman19bac1e2014-05-06 15:23:49 -0400146 if(interpolateZ())
John Bauman89401822014-05-06 15:04:28 -0400147 {
148 for(unsigned int q = 0; q < state.multiSample; q++)
149 {
150 Float4 y = yyyy;
151
152 if(state.multiSample > 1)
153 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500154 y -= *Pointer<Float4>(constants + OFFSET(Constants,Y) + q * sizeof(float4));
John Bauman89401822014-05-06 15:04:28 -0400155 }
156
Nicolas Capens4f172c72016-01-13 08:34:30 -0500157 Dz[q] = *Pointer<Float4>(primitive + OFFSET(Primitive,z.C), 16) + y * *Pointer<Float4>(primitive + OFFSET(Primitive,z.B), 16);
John Bauman89401822014-05-06 15:04:28 -0400158 }
159 }
160
161 if(veryEarlyDepthTest && state.multiSample == 1)
162 {
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400163 if(!state.stencilActive && state.depthTestActive && (state.depthCompareMode == DEPTH_LESSEQUAL || state.depthCompareMode == DEPTH_LESS)) // FIXME: Both modes ok?
John Bauman89401822014-05-06 15:04:28 -0400164 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500165 Float4 xxxx = Float4(Float(x0)) + *Pointer<Float4>(primitive + OFFSET(Primitive,xQuad), 16);
John Bauman89401822014-05-06 15:04:28 -0400166
167 Pointer<Byte> buffer;
168 Int pitch;
169
170 if(!state.quadLayoutDepthBuffer)
171 {
172 buffer = zBuffer + 4 * x0;
Nicolas Capens4f172c72016-01-13 08:34:30 -0500173 pitch = *Pointer<Int>(data + OFFSET(DrawData,depthPitchB));
John Bauman89401822014-05-06 15:04:28 -0400174 }
175 else
Nicolas Capens81f18302016-01-14 09:32:35 -0500176 {
John Bauman89401822014-05-06 15:04:28 -0400177 buffer = zBuffer + 8 * x0;
178 }
179
180 For(Int x = x0, x < x1, x += 2)
181 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500182 Float4 z = interpolate(xxxx, Dz[0], z, primitive + OFFSET(Primitive,z), false, false);
John Bauman89401822014-05-06 15:04:28 -0400183
184 Float4 zValue;
Nicolas Capens81f18302016-01-14 09:32:35 -0500185
John Bauman89401822014-05-06 15:04:28 -0400186 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 {
John Bauman19bac1e2014-05-06 15:23:49 -0400235 if(interpolateW())
John Bauman89401822014-05-06 15:04:28 -0400236 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500237 Dw = *Pointer<Float4>(primitive + OFFSET(Primitive,w.C), 16) + yyyy * *Pointer<Float4>(primitive + OFFSET(Primitive,w.B), 16);
John Bauman89401822014-05-06 15:04:28 -0400238 }
239
Nicolas Capens3b4c93f2016-05-18 12:51:37 -0400240 for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
John Bauman89401822014-05-06 15:04:28 -0400241 {
Nicolas Capens66be2452015-01-27 14:58:57 -0500242 for(int component = 0; component < 4; component++)
John Bauman89401822014-05-06 15:04:28 -0400243 {
244 if(state.interpolant[interpolant].component & (1 << component))
245 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500246 Dv[interpolant][component] = *Pointer<Float4>(primitive + OFFSET(Primitive,V[interpolant][component].C), 16);
John Bauman89401822014-05-06 15:04:28 -0400247
248 if(!(state.interpolant[interpolant].flat & (1 << component)))
249 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500250 Dv[interpolant][component] += yyyy * *Pointer<Float4>(primitive + OFFSET(Primitive,V[interpolant][component].B), 16);
John Bauman89401822014-05-06 15:04:28 -0400251 }
252 }
253 }
254 }
255
Nicolas Capens66be2452015-01-27 14:58:57 -0500256 if(state.fog.component)
257 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500258 Df = *Pointer<Float4>(primitive + OFFSET(Primitive,f.C), 16);
Nicolas Capens66be2452015-01-27 14:58:57 -0500259
260 if(!state.fog.flat)
261 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500262 Df += yyyy * *Pointer<Float4>(primitive + OFFSET(Primitive,f.B), 16);
Nicolas Capens66be2452015-01-27 14:58:57 -0500263 }
264 }
265
John Bauman89401822014-05-06 15:04:28 -0400266 Short4 xLeft[4];
267 Short4 xRight[4];
268
269 for(unsigned int q = 0; q < state.multiSample; q++)
270 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500271 xLeft[q] = *Pointer<Short4>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline) + y * sizeof(Primitive::Span));
John Bauman89401822014-05-06 15:04:28 -0400272 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
Nicolas Capens4f172c72016-01-13 08:34:30 -0500289 quad(cBuffer, zBuffer, sBuffer, cMask, x, y);
John Bauman89401822014-05-06 15:04:28 -0400290 }
291 }
292
Alexis Hetu1edcd8b2015-11-05 11:12:41 -0500293 for(int index = 0; index < RENDERTARGETS; index++)
John Bauman89401822014-05-06 15:04:28 -0400294 {
295 if(state.colorWriteActive(index))
296 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500297 cBuffer[index] += *Pointer<Int>(data + OFFSET(DrawData,colorPitchB[index])) << (1 + sw::log2(clusterCount)); // FIXME: Precompute
John Bauman89401822014-05-06 15:04:28 -0400298 }
299 }
300
301 if(state.depthTestActive)
302 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500303 zBuffer += *Pointer<Int>(data + OFFSET(DrawData,depthPitchB)) << (1 + sw::log2(clusterCount)); // FIXME: Precompute
John Bauman89401822014-05-06 15:04:28 -0400304 }
305
306 if(state.stencilActive)
307 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500308 sBuffer += *Pointer<Int>(data + OFFSET(DrawData,stencilPitchB)) << (1 + sw::log2(clusterCount)); // FIXME: Precompute
John Bauman89401822014-05-06 15:04:28 -0400309 }
310
311 y += 2 * clusterCount;
312 }
313 Until(y >= yMax)
314 }
Alexis Hetuf2a8c372015-07-13 11:08:41 -0400315
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
333 bool QuadRasterizer::interpolateZ() const
334 {
335 return state.depthTestActive || state.pixelFogActive() || (shader && shader->vPosDeclared && fullPixelPositionRegister);
336 }
337
338 bool QuadRasterizer::interpolateW() const
339 {
340 return state.perspective || (shader && shader->vPosDeclared && fullPixelPositionRegister);
341 }
John Bauman89401822014-05-06 15:04:28 -0400342}