Home | History | Annotate | Download | only in Device
      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 
     92 		Query(Type type) : building(false), reference(0), data(0), type(type)
     93 		{
     94 		}
     95 
     96 		void begin()
     97 		{
     98 			building = true;
     99 			data = 0;
    100 		}
    101 
    102 		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 		{
    215 			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 		{
    233 			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 
    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