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 #ifndef sw_Renderer_hpp
16 #define sw_Renderer_hpp
17 
18 #include "VertexProcessor.hpp"
19 #include "PixelProcessor.hpp"
20 #include "SetupProcessor.hpp"
21 #include "Plane.hpp"
22 #include "Blitter.hpp"
23 #include "Common/MutexLock.hpp"
24 #include "Common/Thread.hpp"
25 #include "Main/Config.hpp"
26 
27 #include <list>
28 
29 namespace sw
30 {
31 	class Clipper;
32 	class PixelShader;
33 	class VertexShader;
34 	class SwiftConfig;
35 	struct Task;
36 	class Resource;
37 	class Renderer;
38 	struct Constants;
39 
40 	enum TranscendentalPrecision
41 	{
42 		APPROXIMATE,
43 		PARTIAL,	// 2^-10
44 		ACCURATE,
45 		WHQL,		// 2^-21
46 		IEEE		// 2^-23
47 	};
48 
49 	extern TranscendentalPrecision logPrecision;
50 	extern TranscendentalPrecision expPrecision;
51 	extern TranscendentalPrecision rcpPrecision;
52 	extern TranscendentalPrecision rsqPrecision;
53 	extern bool perspectiveCorrection;
54 
55 	struct Conventions
56 	{
57 		bool halfIntegerCoordinates;
58 		bool symmetricNormalizedDepth;
59 		bool booleanFaceRegister;
60 		bool fullPixelPositionRegister;
61 		bool leadingVertexFirst;
62 		bool secondaryColor;
63 		bool colorsDefaultToZero;
64 	};
65 
66 	static const Conventions OpenGL =
67 	{
68 		true,    // halfIntegerCoordinates
69 		true,    // symmetricNormalizedDepth
70 		true,    // booleanFaceRegister
71 		true,    // fullPixelPositionRegister
72 		false,   // leadingVertexFirst
73 		false,   // secondaryColor
74 		true,    // colorsDefaultToZero
75 	};
76 
77 	static const Conventions Direct3D =
78 	{
79 		false,   // halfIntegerCoordinates
80 		false,   // symmetricNormalizedDepth
81 		false,   // booleanFaceRegister
82 		false,   // fullPixelPositionRegister
83 		true,    // leadingVertexFirst
84 		true,    // secondardyColor
85 		false,   // colorsDefaultToZero
86 	};
87 
88 	struct Query
89 	{
90 		enum Type { FRAGMENTS_PASSED, TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN };
91 
Querysw::Query92 		Query(Type type) : building(false), reference(0), data(0), type(type)
93 		{
94 		}
95 
beginsw::Query96 		void begin()
97 		{
98 			building = true;
99 			data = 0;
100 		}
101 
endsw::Query102 		void end()
103 		{
104 			building = false;
105 		}
106 
107 		bool building;
108 		AtomicInt reference;
109 		AtomicInt data;
110 
111 		const Type type;
112 	};
113 
114 	struct DrawData
115 	{
116 		const Constants *constants;
117 
118 		const void *input[MAX_VERTEX_INPUTS];
119 		unsigned int stride[MAX_VERTEX_INPUTS];
120 		Texture mipmap[TOTAL_IMAGE_UNITS];
121 		const void *indices;
122 
123 		struct VS
124 		{
125 			float4 c[VERTEX_UNIFORM_VECTORS + 1];   // One extra for indices out of range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0}
126 			byte* u[MAX_UNIFORM_BUFFER_BINDINGS];
127 			byte* t[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS];
128 			unsigned int reg[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Offset used when reading from registers, in components
129 			unsigned int row[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Number of rows to read
130 			unsigned int col[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Number of columns to read
131 			unsigned int str[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Number of components between each varying in output buffer
132 			int4 i[16];
133 			bool b[16];
134 		};
135 
136 		struct PS
137 		{
138 			word4 cW[8][4];
139 			float4 c[FRAGMENT_UNIFORM_VECTORS];
140 			byte* u[MAX_UNIFORM_BUFFER_BINDINGS];
141 			int4 i[16];
142 			bool b[16];
143 		};
144 
145 		union
146 		{
147 			VS vs;
148 			VertexProcessor::FixedFunction ff;
149 		};
150 
151 		PS ps;
152 
153 		int instanceID;
154 
155 		VertexProcessor::PointSprite point;
156 		float lineWidth;
157 
158 		PixelProcessor::Stencil stencil[2];   // clockwise, counterclockwise
159 		PixelProcessor::Stencil stencilCCW;
160 		PixelProcessor::Fog fog;
161 		PixelProcessor::Factor factor;
162 		unsigned int occlusion[16];   // Number of pixels passing depth test
163 
164 		#if PERF_PROFILE
165 			int64_t cycles[PERF_TIMERS][16];
166 		#endif
167 
168 		TextureStage::Uniforms textureStage[8];
169 
170 		float4 Wx16;
171 		float4 Hx16;
172 		float4 X0x16;
173 		float4 Y0x16;
174 		float4 XXXX;
175 		float4 YYYY;
176 		float4 halfPixelX;
177 		float4 halfPixelY;
178 		float viewportHeight;
179 		float slopeDepthBias;
180 		float depthRange;
181 		float depthNear;
182 		Plane clipPlane[6];
183 
184 		unsigned int *colorBuffer[RENDERTARGETS];
185 		int colorPitchB[RENDERTARGETS];
186 		int colorSliceB[RENDERTARGETS];
187 		float *depthBuffer;
188 		int depthPitchB;
189 		int depthSliceB;
190 		unsigned char *stencilBuffer;
191 		int stencilPitchB;
192 		int stencilSliceB;
193 
194 		int scissorX0;
195 		int scissorX1;
196 		int scissorY0;
197 		int scissorY1;
198 
199 		float4 a2c0;
200 		float4 a2c1;
201 		float4 a2c2;
202 		float4 a2c3;
203 	};
204 
205 	struct DrawCall
206 	{
207 		DrawCall();
208 
209 		~DrawCall();
210 
211 		AtomicInt drawType;
212 		AtomicInt batchSize;
213 
214 		Routine *vertexRoutine;
215 		Routine *setupRoutine;
216 		Routine *pixelRoutine;
217 
218 		VertexProcessor::RoutinePointer vertexPointer;
219 		SetupProcessor::RoutinePointer setupPointer;
220 		PixelProcessor::RoutinePointer pixelPointer;
221 
222 		int (Renderer::*setupPrimitives)(int batch, int count);
223 		SetupProcessor::State setupState;
224 
225 		Resource *vertexStream[MAX_VERTEX_INPUTS];
226 		Resource *indexBuffer;
227 		Surface *renderTarget[RENDERTARGETS];
228 		Surface *depthBuffer;
229 		Surface *stencilBuffer;
230 		Resource *texture[TOTAL_IMAGE_UNITS];
231 		Resource* pUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
232 		Resource* vUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
233 		Resource* transformFeedbackBuffers[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS];
234 
235 		unsigned int vsDirtyConstF;
236 		unsigned int vsDirtyConstI;
237 		unsigned int vsDirtyConstB;
238 
239 		unsigned int psDirtyConstF;
240 		unsigned int psDirtyConstI;
241 		unsigned int psDirtyConstB;
242 
243 		std::list<Query*> *queries;
244 
245 		AtomicInt clipFlags;
246 
247 		AtomicInt primitive;    // Current primitive to enter pipeline
248 		AtomicInt count;        // Number of primitives to render
249 		AtomicInt references;   // Remaining references to this draw call, 0 when done drawing, -1 when resources unlocked and slot is free
250 
251 		DrawData *data;
252 	};
253 
254 	struct Viewport
255 	{
256 		float x0;
257 		float y0;
258 		float width;
259 		float height;
260 		float minZ;
261 		float maxZ;
262 	};
263 
264 	class Renderer : public VertexProcessor, public PixelProcessor, public SetupProcessor
265 	{
266 		struct Task
267 		{
268 			enum Type
269 			{
270 				PRIMITIVES,
271 				PIXELS,
272 
273 				RESUME,
274 				SUSPEND
275 			};
276 
277 			AtomicInt type;
278 			AtomicInt primitiveUnit;
279 			AtomicInt pixelCluster;
280 		};
281 
282 		struct PrimitiveProgress
283 		{
initsw::Renderer::PrimitiveProgress284 			void init()
285 			{
286 				drawCall = 0;
287 				firstPrimitive = 0;
288 				primitiveCount = 0;
289 				visible = 0;
290 				references = 0;
291 			}
292 
293 			AtomicInt drawCall;
294 			AtomicInt firstPrimitive;
295 			AtomicInt primitiveCount;
296 			AtomicInt visible;
297 			AtomicInt references;
298 		};
299 
300 		struct PixelProgress
301 		{
initsw::Renderer::PixelProgress302 			void init()
303 			{
304 				drawCall = 0;
305 				processedPrimitives = 0;
306 				executing = false;
307 			}
308 
309 			AtomicInt drawCall;
310 			AtomicInt processedPrimitives;
311 			AtomicInt executing;
312 		};
313 
314 	public:
315 		Renderer(Context *context, Conventions conventions, bool exactColorRounding);
316 
317 		virtual ~Renderer();
318 
319 		void *operator new(size_t size);
320 		void operator delete(void * mem);
321 
322 		void draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update = true);
323 
324 		void clear(void *value, Format format, Surface *dest, const Rect &rect, unsigned int rgbaMask);
325 		void blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil = false, bool sRGBconversion = true);
326 		void blit3D(Surface *source, Surface *dest);
327 
328 		void setIndexBuffer(Resource *indexBuffer);
329 
330 		void setMultiSampleMask(unsigned int mask);
331 		void setTransparencyAntialiasing(TransparencyAntialiasing transparencyAntialiasing);
332 
333 		void setTextureResource(unsigned int sampler, Resource *resource);
334 		void setTextureLevel(unsigned int sampler, unsigned int face, unsigned int level, Surface *surface, TextureType type);
335 
336 		void setTextureFilter(SamplerType type, int sampler, FilterType textureFilter);
337 		void setMipmapFilter(SamplerType type, int sampler, MipmapType mipmapFilter);
338 		void setGatherEnable(SamplerType type, int sampler, bool enable);
339 		void setAddressingModeU(SamplerType type, int sampler, AddressingMode addressingMode);
340 		void setAddressingModeV(SamplerType type, int sampler, AddressingMode addressingMode);
341 		void setAddressingModeW(SamplerType type, int sampler, AddressingMode addressingMode);
342 		void setReadSRGB(SamplerType type, int sampler, bool sRGB);
343 		void setMipmapLOD(SamplerType type, int sampler, float bias);
344 		void setBorderColor(SamplerType type, int sampler, const Color<float> &borderColor);
345 		void setMaxAnisotropy(SamplerType type, int sampler, float maxAnisotropy);
346 		void setHighPrecisionFiltering(SamplerType type, int sampler, bool highPrecisionFiltering);
347 		void setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR);
348 		void setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG);
349 		void setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB);
350 		void setSwizzleA(SamplerType type, int sampler, SwizzleType swizzleA);
351 		void setCompareFunc(SamplerType type, int sampler, CompareFunc compare);
352 		void setBaseLevel(SamplerType type, int sampler, int baseLevel);
353 		void setMaxLevel(SamplerType type, int sampler, int maxLevel);
354 		void setMinLod(SamplerType type, int sampler, float minLod);
355 		void setMaxLod(SamplerType type, int sampler, float maxLod);
356 
357 		void setPointSpriteEnable(bool pointSpriteEnable);
358 		void setPointScaleEnable(bool pointScaleEnable);
359 		void setLineWidth(float width);
360 
361 		void setDepthBias(float bias);
362 		void setSlopeDepthBias(float slopeBias);
363 
364 		void setRasterizerDiscard(bool rasterizerDiscard);
365 
366 		// Programmable pipelines
367 		void setPixelShader(const PixelShader *shader);
368 		void setVertexShader(const VertexShader *shader);
369 
370 		void setPixelShaderConstantF(unsigned int index, const float value[4], unsigned int count = 1);
371 		void setPixelShaderConstantI(unsigned int index, const int value[4], unsigned int count = 1);
372 		void setPixelShaderConstantB(unsigned int index, const int *boolean, unsigned int count = 1);
373 
374 		void setVertexShaderConstantF(unsigned int index, const float value[4], unsigned int count = 1);
375 		void setVertexShaderConstantI(unsigned int index, const int value[4], unsigned int count = 1);
376 		void setVertexShaderConstantB(unsigned int index, const int *boolean, unsigned int count = 1);
377 
378 		// Viewport & Clipper
379 		void setViewport(const Viewport &viewport);
380 		void setScissor(const Rect &scissor);
381 		void setClipFlags(int flags);
382 		void setClipPlane(unsigned int index, const float plane[4]);
383 
384 		// Partial transform
385 		void setModelMatrix(const Matrix &M, int i = 0);
386 		void setViewMatrix(const Matrix &V);
387 		void setBaseMatrix(const Matrix &B);
388 		void setProjectionMatrix(const Matrix &P);
389 
390 		void addQuery(Query *query);
391 		void removeQuery(Query *query);
392 
393 		void synchronize();
394 
395 		#if PERF_HUD
396 			// Performance timers
397 			int getThreadCount();
398 			int64_t getVertexTime(int thread);
399 			int64_t getSetupTime(int thread);
400 			int64_t getPixelTime(int thread);
401 			void resetTimers();
402 		#endif
403 
getClusterCount()404 		static int getClusterCount() { return clusterCount; }
405 
406 	private:
407 		static void threadFunction(void *parameters);
408 		void threadLoop(int threadIndex);
409 		void taskLoop(int threadIndex);
410 		void findAvailableTasks();
411 		void scheduleTask(int threadIndex);
412 		void executeTask(int threadIndex);
413 		void finishRendering(Task &pixelTask);
414 
415 		void processPrimitiveVertices(int unit, unsigned int start, unsigned int count, unsigned int loop, int thread);
416 
417 		int setupSolidTriangles(int batch, int count);
418 		int setupWireframeTriangle(int batch, int count);
419 		int setupVertexTriangle(int batch, int count);
420 		int setupLines(int batch, int count);
421 		int setupPoints(int batch, int count);
422 
423 		bool setupLine(Primitive &primitive, Triangle &triangle, const DrawCall &draw);
424 		bool setupPoint(Primitive &primitive, Triangle &triangle, const DrawCall &draw);
425 
426 		bool isReadWriteTexture(int sampler);
427 		void updateClipper();
428 		void updateConfiguration(bool initialUpdate = false);
429 		void initializeThreads();
430 		void terminateThreads();
431 
432 		void loadConstants(const VertexShader *vertexShader);
433 		void loadConstants(const PixelShader *pixelShader);
434 
435 		Context *context;
436 		Clipper *clipper;
437 		Blitter *blitter;
438 		Viewport viewport;
439 		Rect scissor;
440 		int clipFlags;
441 
442 		Triangle *triangleBatch[16];
443 		Primitive *primitiveBatch[16];
444 
445 		// User-defined clipping planes
446 		Plane userPlane[MAX_CLIP_PLANES];
447 		Plane clipPlane[MAX_CLIP_PLANES];   // Tranformed to clip space
448 		bool updateClipPlanes;
449 
450 		AtomicInt exitThreads;
451 		AtomicInt threadsAwake;
452 		Thread *worker[16];
453 		Event *resume[16];         // Events for resuming threads
454 		Event *suspend[16];        // Events for suspending threads
455 		Event *resumeApp;          // Event for resuming the application thread
456 
457 		PrimitiveProgress primitiveProgress[16];
458 		PixelProgress pixelProgress[16];
459 		Task task[16];   // Current tasks for threads
460 
461 		enum {
462 			DRAW_COUNT = 16,   // Number of draw calls buffered (must be power of 2)
463 			DRAW_COUNT_BITS = DRAW_COUNT - 1,
464 		};
465 		DrawCall *drawCall[DRAW_COUNT];
466 		DrawCall *drawList[DRAW_COUNT];
467 
468 		AtomicInt currentDraw;
469 		AtomicInt nextDraw;
470 
471 		enum {
472 			TASK_COUNT = 32,   // Size of the task queue (must be power of 2)
473 			TASK_COUNT_BITS = TASK_COUNT - 1,
474 		};
475 		Task taskQueue[TASK_COUNT];
476 		AtomicInt qHead;
477 		AtomicInt qSize;
478 
479 		static AtomicInt unitCount;
480 		static AtomicInt clusterCount;
481 
482 		MutexLock schedulerMutex;
483 
484 		#if PERF_HUD
485 			int64_t vertexTime[16];
486 			int64_t setupTime[16];
487 			int64_t pixelTime[16];
488 		#endif
489 
490 		VertexTask *vertexTask[16];
491 
492 		SwiftConfig *swiftConfig;
493 
494 		std::list<Query*> queries;
495 		Resource *sync;
496 
497 		VertexProcessor::State vertexState;
498 		SetupProcessor::State setupState;
499 		PixelProcessor::State pixelState;
500 
501 		Routine *vertexRoutine;
502 		Routine *setupRoutine;
503 		Routine *pixelRoutine;
504 	};
505 }
506 
507 #endif   // sw_Renderer_hpp
508