blob: 6b319b4117f6b2b3b7999967dd2a399d7e3a6352 [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
John Bauman89401822014-05-06 15:04:28 -040017#include "Primitive.hpp"
18#include "Renderer.hpp"
Nicolas Capens708c24b2017-10-26 13:07:10 -040019#include "Shader/Constants.hpp"
20#include "Common/Math.hpp"
21#include "Common/Debug.hpp"
John Bauman89401822014-05-06 15:04:28 -040022
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;
Alexis Hetuaa8239a2017-09-22 17:02:24 -040052 int clusterCount = Renderer::getClusterCount();
Nicolas Capens4f172c72016-01-13 08:34:30 -050053
54 Do
John Bauman89401822014-05-06 15:04:28 -040055 {
Nicolas Capens4f172c72016-01-13 08:34:30 -050056 Int yMin = *Pointer<Int>(primitive + OFFSET(Primitive,yMin));
57 Int yMax = *Pointer<Int>(primitive + OFFSET(Primitive,yMax));
John Bauman89401822014-05-06 15:04:28 -040058
Nicolas Capens4f172c72016-01-13 08:34:30 -050059 Int cluster2 = cluster + cluster;
60 yMin += clusterCount * 2 - 2 - cluster2;
61 yMin &= -clusterCount * 2;
62 yMin += cluster2;
John Bauman89401822014-05-06 15:04:28 -040063
Nicolas Capens4f172c72016-01-13 08:34:30 -050064 If(yMin < yMax)
John Bauman89401822014-05-06 15:04:28 -040065 {
Nicolas Capens4f172c72016-01-13 08:34:30 -050066 rasterize(yMin, yMax);
John Bauman89401822014-05-06 15:04:28 -040067 }
68
Nicolas Capens4f172c72016-01-13 08:34:30 -050069 primitive += sizeof(Primitive) * state.multiSample;
70 count--;
71 }
72 Until(count == 0)
John Bauman89401822014-05-06 15:04:28 -040073
Nicolas Capens4f172c72016-01-13 08:34:30 -050074 if(state.occlusionEnabled)
75 {
76 UInt clusterOcclusion = *Pointer<UInt>(data + OFFSET(DrawData,occlusion) + 4 * cluster);
77 clusterOcclusion += occlusion;
78 *Pointer<UInt>(data + OFFSET(DrawData,occlusion) + 4 * cluster) = clusterOcclusion;
John Bauman89401822014-05-06 15:04:28 -040079 }
80
Nicolas Capens4f172c72016-01-13 08:34:30 -050081 #if PERF_PROFILE
82 cycles[PERF_PIXEL] = Ticks() - pixelTime;
83
84 for(int i = 0; i < PERF_TIMERS; i++)
85 {
86 *Pointer<Long>(data + OFFSET(DrawData,cycles[i]) + 8 * cluster) += cycles[i];
87 }
88 #endif
89
90 Return();
John Bauman89401822014-05-06 15:04:28 -040091 }
92
Nicolas Capens4f172c72016-01-13 08:34:30 -050093 void QuadRasterizer::rasterize(Int &yMin, Int &yMax)
John Bauman89401822014-05-06 15:04:28 -040094 {
Alexis Hetu1edcd8b2015-11-05 11:12:41 -050095 Pointer<Byte> cBuffer[RENDERTARGETS];
John Bauman89401822014-05-06 15:04:28 -040096 Pointer<Byte> zBuffer;
97 Pointer<Byte> sBuffer;
98
Alexis Hetu1edcd8b2015-11-05 11:12:41 -050099 for(int index = 0; index < RENDERTARGETS; index++)
John Bauman89401822014-05-06 15:04:28 -0400100 {
101 if(state.colorWriteActive(index))
102 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500103 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 -0400104 }
105 }
106
107 if(state.depthTestActive)
108 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500109 zBuffer = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,depthBuffer)) + yMin * *Pointer<Int>(data + OFFSET(DrawData,depthPitchB));
John Bauman89401822014-05-06 15:04:28 -0400110 }
111
112 if(state.stencilActive)
113 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500114 sBuffer = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,stencilBuffer)) + yMin * *Pointer<Int>(data + OFFSET(DrawData,stencilPitchB));
John Bauman89401822014-05-06 15:04:28 -0400115 }
116
117 Int y = yMin;
Nicolas Capens81f18302016-01-14 09:32:35 -0500118
John Bauman89401822014-05-06 15:04:28 -0400119 Do
120 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500121 Int x0a = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->left) + (y + 0) * sizeof(Primitive::Span)));
122 Int x0b = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->left) + (y + 1) * sizeof(Primitive::Span)));
Nicolas Capensc50d35d2015-01-27 01:52:41 -0500123 Int x0 = Min(x0a, x0b);
Nicolas Capens81f18302016-01-14 09:32:35 -0500124
John Bauman89401822014-05-06 15:04:28 -0400125 for(unsigned int q = 1; q < state.multiSample; q++)
126 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500127 x0a = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->left) + (y + 0) * sizeof(Primitive::Span)));
128 x0b = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->left) + (y + 1) * sizeof(Primitive::Span)));
Nicolas Capensc50d35d2015-01-27 01:52:41 -0500129 x0 = Min(x0, Min(x0a, x0b));
John Bauman89401822014-05-06 15:04:28 -0400130 }
Nicolas Capens81f18302016-01-14 09:32:35 -0500131
John Bauman89401822014-05-06 15:04:28 -0400132 x0 &= 0xFFFFFFFE;
133
Nicolas Capens4f172c72016-01-13 08:34:30 -0500134 Int x1a = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->right) + (y + 0) * sizeof(Primitive::Span)));
135 Int x1b = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->right) + (y + 1) * sizeof(Primitive::Span)));
Nicolas Capensc50d35d2015-01-27 01:52:41 -0500136 Int x1 = Max(x1a, x1b);
John Bauman89401822014-05-06 15:04:28 -0400137
138 for(unsigned int q = 1; q < state.multiSample; q++)
139 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500140 x1a = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->right) + (y + 0) * sizeof(Primitive::Span)));
141 x1b = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->right) + (y + 1) * sizeof(Primitive::Span)));
Nicolas Capensc50d35d2015-01-27 01:52:41 -0500142 x1 = Max(x1, Max(x1a, x1b));
John Bauman89401822014-05-06 15:04:28 -0400143 }
144
Nicolas Capens4f172c72016-01-13 08:34:30 -0500145 Float4 yyyy = Float4(Float(y)) + *Pointer<Float4>(primitive + OFFSET(Primitive,yQuad), 16);
John Bauman89401822014-05-06 15:04:28 -0400146
John Bauman19bac1e2014-05-06 15:23:49 -0400147 if(interpolateZ())
John Bauman89401822014-05-06 15:04:28 -0400148 {
149 for(unsigned int q = 0; q < state.multiSample; q++)
150 {
151 Float4 y = yyyy;
152
153 if(state.multiSample > 1)
154 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500155 y -= *Pointer<Float4>(constants + OFFSET(Constants,Y) + q * sizeof(float4));
John Bauman89401822014-05-06 15:04:28 -0400156 }
157
Nicolas Capens4f172c72016-01-13 08:34:30 -0500158 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 -0400159 }
160 }
161
Nicolas Capense70208e2018-01-02 15:10:56 -0500162 if(veryEarlyDepthTest && state.multiSample == 1 && !state.depthOverride)
John Bauman89401822014-05-06 15:04:28 -0400163 {
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400164 if(!state.stencilActive && state.depthTestActive && (state.depthCompareMode == DEPTH_LESSEQUAL || state.depthCompareMode == DEPTH_LESS)) // FIXME: Both modes ok?
John Bauman89401822014-05-06 15:04:28 -0400165 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500166 Float4 xxxx = Float4(Float(x0)) + *Pointer<Float4>(primitive + OFFSET(Primitive,xQuad), 16);
John Bauman89401822014-05-06 15:04:28 -0400167
168 Pointer<Byte> buffer;
169 Int pitch;
170
171 if(!state.quadLayoutDepthBuffer)
172 {
173 buffer = zBuffer + 4 * x0;
Nicolas Capens4f172c72016-01-13 08:34:30 -0500174 pitch = *Pointer<Int>(data + OFFSET(DrawData,depthPitchB));
John Bauman89401822014-05-06 15:04:28 -0400175 }
176 else
Nicolas Capens81f18302016-01-14 09:32:35 -0500177 {
John Bauman89401822014-05-06 15:04:28 -0400178 buffer = zBuffer + 8 * x0;
179 }
180
181 For(Int x = x0, x < x1, x += 2)
182 {
Nicolas Capens5ba372f2017-10-05 16:05:47 -0400183 Float4 z = interpolate(xxxx, Dz[0], z, primitive + OFFSET(Primitive,z), false, false, state.depthClamp);
John Bauman89401822014-05-06 15:04:28 -0400184
185 Float4 zValue;
Nicolas Capens81f18302016-01-14 09:32:35 -0500186
John Bauman89401822014-05-06 15:04:28 -0400187 if(!state.quadLayoutDepthBuffer)
188 {
189 // FIXME: Properly optimizes?
190 zValue.xy = *Pointer<Float4>(buffer);
191 zValue.zw = *Pointer<Float4>(buffer + pitch - 8);
192 }
193 else
194 {
195 zValue = *Pointer<Float4>(buffer, 16);
196 }
197
198 Int4 zTest;
199
200 if(complementaryDepthBuffer)
201 {
202 zTest = CmpLE(zValue, z);
203 }
204 else
205 {
206 zTest = CmpNLT(zValue, z);
207 }
208
209 Int zMask = SignMask(zTest);
210
211 If(zMask == 0)
212 {
213 x0 += 2;
214 }
215 Else
216 {
217 x = x1;
218 }
219
220 xxxx += Float4(2);
221
222 if(!state.quadLayoutDepthBuffer)
223 {
224 buffer += 8;
225 }
226 else
227 {
228 buffer += 16;
229 }
230 }
231 }
232 }
233
234 If(x0 < x1)
235 {
John Bauman19bac1e2014-05-06 15:23:49 -0400236 if(interpolateW())
John Bauman89401822014-05-06 15:04:28 -0400237 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500238 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 -0400239 }
240
Nicolas Capens3b4c93f2016-05-18 12:51:37 -0400241 for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
John Bauman89401822014-05-06 15:04:28 -0400242 {
Nicolas Capens66be2452015-01-27 14:58:57 -0500243 for(int component = 0; component < 4; component++)
John Bauman89401822014-05-06 15:04:28 -0400244 {
245 if(state.interpolant[interpolant].component & (1 << component))
246 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500247 Dv[interpolant][component] = *Pointer<Float4>(primitive + OFFSET(Primitive,V[interpolant][component].C), 16);
John Bauman89401822014-05-06 15:04:28 -0400248
249 if(!(state.interpolant[interpolant].flat & (1 << component)))
250 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500251 Dv[interpolant][component] += yyyy * *Pointer<Float4>(primitive + OFFSET(Primitive,V[interpolant][component].B), 16);
John Bauman89401822014-05-06 15:04:28 -0400252 }
253 }
254 }
255 }
256
Nicolas Capens66be2452015-01-27 14:58:57 -0500257 if(state.fog.component)
258 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500259 Df = *Pointer<Float4>(primitive + OFFSET(Primitive,f.C), 16);
Nicolas Capens66be2452015-01-27 14:58:57 -0500260
261 if(!state.fog.flat)
262 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500263 Df += yyyy * *Pointer<Float4>(primitive + OFFSET(Primitive,f.B), 16);
Nicolas Capens66be2452015-01-27 14:58:57 -0500264 }
265 }
266
John Bauman89401822014-05-06 15:04:28 -0400267 Short4 xLeft[4];
268 Short4 xRight[4];
269
270 for(unsigned int q = 0; q < state.multiSample; q++)
271 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500272 xLeft[q] = *Pointer<Short4>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline) + y * sizeof(Primitive::Span));
John Bauman89401822014-05-06 15:04:28 -0400273 xRight[q] = xLeft[q];
274
275 xLeft[q] = Swizzle(xLeft[q], 0xA0) - Short4(1, 2, 1, 2);
276 xRight[q] = Swizzle(xRight[q], 0xF5) - Short4(0, 1, 0, 1);
277 }
278
279 For(Int x = x0, x < x1, x += 2)
280 {
281 Short4 xxxx = Short4(x);
282 Int cMask[4];
283
284 for(unsigned int q = 0; q < state.multiSample; q++)
285 {
286 Short4 mask = CmpGT(xxxx, xLeft[q]) & CmpGT(xRight[q], xxxx);
Nicolas Capens33438a62017-09-27 11:47:35 -0400287 cMask[q] = SignMask(PackSigned(mask, mask)) & 0x0000000F;
John Bauman89401822014-05-06 15:04:28 -0400288 }
289
Nicolas Capens4f172c72016-01-13 08:34:30 -0500290 quad(cBuffer, zBuffer, sBuffer, cMask, x, y);
John Bauman89401822014-05-06 15:04:28 -0400291 }
292 }
293
Alexis Hetuaa8239a2017-09-22 17:02:24 -0400294 int clusterCount = Renderer::getClusterCount();
295
Alexis Hetu1edcd8b2015-11-05 11:12:41 -0500296 for(int index = 0; index < RENDERTARGETS; index++)
John Bauman89401822014-05-06 15:04:28 -0400297 {
298 if(state.colorWriteActive(index))
299 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500300 cBuffer[index] += *Pointer<Int>(data + OFFSET(DrawData,colorPitchB[index])) << (1 + sw::log2(clusterCount)); // FIXME: Precompute
John Bauman89401822014-05-06 15:04:28 -0400301 }
302 }
303
304 if(state.depthTestActive)
305 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500306 zBuffer += *Pointer<Int>(data + OFFSET(DrawData,depthPitchB)) << (1 + sw::log2(clusterCount)); // FIXME: Precompute
John Bauman89401822014-05-06 15:04:28 -0400307 }
308
309 if(state.stencilActive)
310 {
Nicolas Capens4f172c72016-01-13 08:34:30 -0500311 sBuffer += *Pointer<Int>(data + OFFSET(DrawData,stencilPitchB)) << (1 + sw::log2(clusterCount)); // FIXME: Precompute
John Bauman89401822014-05-06 15:04:28 -0400312 }
313
314 y += 2 * clusterCount;
315 }
316 Until(y >= yMax)
317 }
Alexis Hetuf2a8c372015-07-13 11:08:41 -0400318
Nicolas Capens5ba372f2017-10-05 16:05:47 -0400319 Float4 QuadRasterizer::interpolate(Float4 &x, Float4 &D, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective, bool clamp)
Alexis Hetuf2a8c372015-07-13 11:08:41 -0400320 {
321 Float4 interpolant = D;
322
323 if(!flat)
324 {
325 interpolant += x * *Pointer<Float4>(planeEquation + OFFSET(PlaneEquation, A), 16);
326
327 if(perspective)
328 {
329 interpolant *= rhw;
330 }
331 }
332
Nicolas Capens5ba372f2017-10-05 16:05:47 -0400333 if(clamp)
334 {
335 interpolant = Min(Max(interpolant, Float4(0.0f)), Float4(1.0f));
336 }
337
Alexis Hetuf2a8c372015-07-13 11:08:41 -0400338 return interpolant;
339 }
340
341 bool QuadRasterizer::interpolateZ() const
342 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400343 return state.depthTestActive || state.pixelFogActive() || (shader && shader->isVPosDeclared() && fullPixelPositionRegister);
Alexis Hetuf2a8c372015-07-13 11:08:41 -0400344 }
345
346 bool QuadRasterizer::interpolateW() const
347 {
Alexis Hetu02ad0aa2016-08-02 11:18:14 -0400348 return state.perspective || (shader && shader->isVPosDeclared() && fullPixelPositionRegister);
Alexis Hetuf2a8c372015-07-13 11:08:41 -0400349 }
John Bauman89401822014-05-06 15:04:28 -0400350}