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 "System/MutexLock.hpp"
24 #include "System/Thread.hpp"
25 #include "Device/Config.hpp"
26 
27 #include <list>
28 
29 namespace sw
30 {
31 	class Clipper;
32 	struct DrawCall;
33 	class PixelShader;
34 	class VertexShader;
35 	class SwiftConfig;
36 	struct Task;
37 	class Resource;
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 			float4 c[FRAGMENT_UNIFORM_VECTORS];
139 			byte* u[MAX_UNIFORM_BUFFER_BINDINGS];
140 			int4 i[16];
141 			bool b[16];
142 		};
143 
144 		VS vs;
145 		PS ps;
146 
147 		int instanceID;
148 
149 		float pointSizeMin;
150 		float pointSizeMax;
151 		float lineWidth;
152 
153 		PixelProcessor::Stencil stencil[2];   // clockwise, counterclockwise
154 		PixelProcessor::Stencil stencilCCW;
155 		PixelProcessor::Factor factor;
156 		unsigned int occlusion[16];   // Number of pixels passing depth test
157 
158 		#if PERF_PROFILE
159 			int64_t cycles[PERF_TIMERS][16];
160 		#endif
161 
162 		float4 Wx16;
163 		float4 Hx16;
164 		float4 X0x16;
165 		float4 Y0x16;
166 		float4 halfPixelX;
167 		float4 halfPixelY;
168 		float viewportHeight;
169 		float slopeDepthBias;
170 		float depthRange;
171 		float depthNear;
172 		Plane clipPlane[6];
173 
174 		unsigned int *colorBuffer[RENDERTARGETS];
175 		int colorPitchB[RENDERTARGETS];
176 		int colorSliceB[RENDERTARGETS];
177 		float *depthBuffer;
178 		int depthPitchB;
179 		int depthSliceB;
180 		unsigned char *stencilBuffer;
181 		int stencilPitchB;
182 		int stencilSliceB;
183 
184 		int scissorX0;
185 		int scissorX1;
186 		int scissorY0;
187 		int scissorY1;
188 
189 		float4 a2c0;
190 		float4 a2c1;
191 		float4 a2c2;
192 		float4 a2c3;
193 	};
194 
195 	class Renderer : public VertexProcessor, public PixelProcessor, public SetupProcessor
196 	{
197 		struct Task
198 		{
199 			enum Type
200 			{
201 				PRIMITIVES,
202 				PIXELS,
203 
204 				RESUME,
205 				SUSPEND
206 			};
207 
208 			AtomicInt type;
209 			AtomicInt primitiveUnit;
210 			AtomicInt pixelCluster;
211 		};
212 
213 		struct PrimitiveProgress
214 		{
initsw::Renderer::PrimitiveProgress215 			void init()
216 			{
217 				drawCall = 0;
218 				firstPrimitive = 0;
219 				primitiveCount = 0;
220 				visible = 0;
221 				references = 0;
222 			}
223 
224 			AtomicInt drawCall;
225 			AtomicInt firstPrimitive;
226 			AtomicInt primitiveCount;
227 			AtomicInt visible;
228 			AtomicInt references;
229 		};
230 
231 		struct PixelProgress
232 		{
initsw::Renderer::PixelProgress233 			void init()
234 			{
235 				drawCall = 0;
236 				processedPrimitives = 0;
237 				executing = false;
238 			}
239 
240 			AtomicInt drawCall;
241 			AtomicInt processedPrimitives;
242 			AtomicInt executing;
243 		};
244 
245 	public:
246 		Renderer(Context *context, Conventions conventions, bool exactColorRounding);
247 
248 		virtual ~Renderer();
249 
250 		void *operator new(size_t size);
251 		void operator delete(void * mem);
252 
253 		void draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update = true);
254 
255 		void clear(void *value, VkFormat format, Surface *dest, const Rect &rect, unsigned int rgbaMask);
256 		void blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil = false, bool sRGBconversion = true);
257 		void blit3D(Surface *source, Surface *dest);
258 
259 		void setContext(const sw::Context& context);
260 		void setIndexBuffer(Resource *indexBuffer);
261 
262 		void setMultiSampleMask(unsigned int mask);
263 		void setTransparencyAntialiasing(TransparencyAntialiasing transparencyAntialiasing);
264 
265 		void setTextureResource(unsigned int sampler, Resource *resource);
266 		void setTextureLevel(unsigned int sampler, unsigned int face, unsigned int level, Surface *surface, TextureType type);
267 
268 		void setTextureFilter(SamplerType type, int sampler, FilterType textureFilter);
269 		void setMipmapFilter(SamplerType type, int sampler, MipmapType mipmapFilter);
270 		void setGatherEnable(SamplerType type, int sampler, bool enable);
271 		void setAddressingModeU(SamplerType type, int sampler, AddressingMode addressingMode);
272 		void setAddressingModeV(SamplerType type, int sampler, AddressingMode addressingMode);
273 		void setAddressingModeW(SamplerType type, int sampler, AddressingMode addressingMode);
274 		void setReadSRGB(SamplerType type, int sampler, bool sRGB);
275 		void setMipmapLOD(SamplerType type, int sampler, float bias);
276 		void setBorderColor(SamplerType type, int sampler, const Color<float> &borderColor);
277 		void setMaxAnisotropy(SamplerType type, int sampler, float maxAnisotropy);
278 		void setHighPrecisionFiltering(SamplerType type, int sampler, bool highPrecisionFiltering);
279 		void setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR);
280 		void setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG);
281 		void setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB);
282 		void setSwizzleA(SamplerType type, int sampler, SwizzleType swizzleA);
283 		void setCompareFunc(SamplerType type, int sampler, CompareFunc compare);
284 		void setBaseLevel(SamplerType type, int sampler, int baseLevel);
285 		void setMaxLevel(SamplerType type, int sampler, int maxLevel);
286 		void setMinLod(SamplerType type, int sampler, float minLod);
287 		void setMaxLod(SamplerType type, int sampler, float maxLod);
288 
289 		void setLineWidth(float width);
290 
291 		void setDepthBias(float bias);
292 		void setSlopeDepthBias(float slopeBias);
293 
294 		void setRasterizerDiscard(bool rasterizerDiscard);
295 
296 		// Programmable pipelines
297 		void setPixelShader(const PixelShader *shader);
298 		void setVertexShader(const VertexShader *shader);
299 
300 		void setPixelShaderConstantF(unsigned int index, const float value[4], unsigned int count = 1);
301 		void setPixelShaderConstantI(unsigned int index, const int value[4], unsigned int count = 1);
302 		void setPixelShaderConstantB(unsigned int index, const int *boolean, unsigned int count = 1);
303 
304 		void setVertexShaderConstantF(unsigned int index, const float value[4], unsigned int count = 1);
305 		void setVertexShaderConstantI(unsigned int index, const int value[4], unsigned int count = 1);
306 		void setVertexShaderConstantB(unsigned int index, const int *boolean, unsigned int count = 1);
307 
308 		// Viewport & Clipper
309 		void setViewport(const VkViewport &viewport);
310 		void setScissor(const Rect &scissor);
311 		void setClipFlags(int flags);
312 		void setClipPlane(unsigned int index, const float plane[4]);
313 
314 		// Partial transform
315 		void setModelMatrix(const Matrix &M, int i = 0);
316 		void setViewMatrix(const Matrix &V);
317 		void setBaseMatrix(const Matrix &B);
318 		void setProjectionMatrix(const Matrix &P);
319 
320 		void addQuery(Query *query);
321 		void removeQuery(Query *query);
322 
323 		void synchronize();
324 
325 		#if PERF_HUD
326 			// Performance timers
327 			int getThreadCount();
328 			int64_t getVertexTime(int thread);
329 			int64_t getSetupTime(int thread);
330 			int64_t getPixelTime(int thread);
331 			void resetTimers();
332 		#endif
333 
getClusterCount()334 		static int getClusterCount() { return clusterCount; }
335 
336 	private:
337 		static void threadFunction(void *parameters);
338 		void threadLoop(int threadIndex);
339 		void taskLoop(int threadIndex);
340 		void findAvailableTasks();
341 		void scheduleTask(int threadIndex);
342 		void executeTask(int threadIndex);
343 		void finishRendering(Task &pixelTask);
344 
345 		void processPrimitiveVertices(int unit, unsigned int start, unsigned int count, unsigned int loop, int thread);
346 
347 		int setupTriangles(int batch, int count);
348 		int setupLines(int batch, int count);
349 		int setupPoints(int batch, int count);
350 
351 		bool setupLine(Primitive &primitive, Triangle &triangle, const DrawCall &draw);
352 		bool setupPoint(Primitive &primitive, Triangle &triangle, const DrawCall &draw);
353 
354 		bool isReadWriteTexture(int sampler);
355 		void updateClipper();
356 		void updateConfiguration(bool initialUpdate = false);
357 		void initializeThreads();
358 		void terminateThreads();
359 
360 		void loadConstants(const VertexShader *vertexShader);
361 		void loadConstants(const PixelShader *pixelShader);
362 
363 		Context *context;
364 		Clipper *clipper;
365 		Blitter *blitter;
366 		VkViewport viewport;
367 		Rect scissor;
368 		int clipFlags;
369 
370 		Triangle *triangleBatch[16];
371 		Primitive *primitiveBatch[16];
372 
373 		// User-defined clipping planes
374 		Plane userPlane[MAX_CLIP_PLANES];
375 		Plane clipPlane[MAX_CLIP_PLANES];   // Tranformed to clip space
376 		bool updateClipPlanes;
377 
378 		AtomicInt exitThreads;
379 		AtomicInt threadsAwake;
380 		Thread *worker[16];
381 		Event *resume[16];         // Events for resuming threads
382 		Event *suspend[16];        // Events for suspending threads
383 		Event *resumeApp;          // Event for resuming the application thread
384 
385 		PrimitiveProgress primitiveProgress[16];
386 		PixelProgress pixelProgress[16];
387 		Task task[16];   // Current tasks for threads
388 
389 		enum {
390 			DRAW_COUNT = 16,   // Number of draw calls buffered (must be power of 2)
391 			DRAW_COUNT_BITS = DRAW_COUNT - 1,
392 		};
393 		DrawCall *drawCall[DRAW_COUNT];
394 		DrawCall *drawList[DRAW_COUNT];
395 
396 		AtomicInt currentDraw;
397 		AtomicInt nextDraw;
398 
399 		enum {
400 			TASK_COUNT = 32,   // Size of the task queue (must be power of 2)
401 			TASK_COUNT_BITS = TASK_COUNT - 1,
402 		};
403 		Task taskQueue[TASK_COUNT];
404 		AtomicInt qHead;
405 		AtomicInt qSize;
406 
407 		static AtomicInt unitCount;
408 		static AtomicInt clusterCount;
409 
410 		MutexLock schedulerMutex;
411 
412 		#if PERF_HUD
413 			int64_t vertexTime[16];
414 			int64_t setupTime[16];
415 			int64_t pixelTime[16];
416 		#endif
417 
418 		VertexTask *vertexTask[16];
419 
420 		SwiftConfig *swiftConfig;
421 
422 		std::list<Query*> queries;
423 		Resource *sync;
424 
425 		VertexProcessor::State vertexState;
426 		SetupProcessor::State setupState;
427 		PixelProcessor::State pixelState;
428 
429 		Routine *vertexRoutine;
430 		Routine *setupRoutine;
431 		Routine *pixelRoutine;
432 	};
433 
434 	struct DrawCall
435 	{
436 		DrawCall();
437 
438 		~DrawCall();
439 
440 		AtomicInt drawType;
441 		AtomicInt batchSize;
442 
443 		Routine *vertexRoutine;
444 		Routine *setupRoutine;
445 		Routine *pixelRoutine;
446 
447 		VertexProcessor::RoutinePointer vertexPointer;
448 		SetupProcessor::RoutinePointer setupPointer;
449 		PixelProcessor::RoutinePointer pixelPointer;
450 
451 		int (Renderer::*setupPrimitives)(int batch, int count);
452 		SetupProcessor::State setupState;
453 
454 		Resource *vertexStream[MAX_VERTEX_INPUTS];
455 		Resource *indexBuffer;
456 		Surface *renderTarget[RENDERTARGETS];
457 		Surface *depthBuffer;
458 		Surface *stencilBuffer;
459 		Resource *texture[TOTAL_IMAGE_UNITS];
460 		Resource* pUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
461 		Resource* vUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
462 		Resource* transformFeedbackBuffers[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS];
463 
464 		unsigned int vsDirtyConstF;
465 		unsigned int vsDirtyConstI;
466 		unsigned int vsDirtyConstB;
467 
468 		unsigned int psDirtyConstF;
469 		unsigned int psDirtyConstI;
470 		unsigned int psDirtyConstB;
471 
472 		std::list<Query*> *queries;
473 
474 		AtomicInt clipFlags;
475 
476 		AtomicInt primitive;    // Current primitive to enter pipeline
477 		AtomicInt count;        // Number of primitives to render
478 		AtomicInt references;   // Remaining references to this draw call, 0 when done drawing, -1 when resources unlocked and slot is free
479 
480 		DrawData *data;
481 	};
482 }
483 
484 #endif   // sw_Renderer_hpp
485