blob: 0631acd83869c85c5360810ea8cf600ca2dbf22e [file] [log] [blame]
John Bauman66b8ab22014-05-06 15:57:45 -04001// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2012 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12#ifndef sw_Renderer_hpp
13#define sw_Renderer_hpp
14
15#include "VertexProcessor.hpp"
16#include "PixelProcessor.hpp"
17#include "SetupProcessor.hpp"
18#include "Plane.hpp"
19#include "Blitter.hpp"
20#include "Common/MutexLock.hpp"
21#include "Common/Thread.hpp"
22#include "Main/Config.hpp"
23
24#include <list>
25
26namespace sw
27{
28 class Clipper;
29 class PixelShader;
30 class VertexShader;
31 class SwiftConfig;
32 struct Task;
33 class Resource;
34 class Renderer;
35
36 extern int batchSize;
37 extern int threadCount;
38 extern int unitCount;
39 extern int clusterCount;
40
41 enum TranscendentalPrecision
42 {
43 APPROXIMATE,
44 PARTIAL, // 2^-10
45 ACCURATE,
46 WHQL, // 2^-21
47 IEEE // 2^-23
48 };
49
50 extern TranscendentalPrecision logPrecision;
51 extern TranscendentalPrecision expPrecision;
52 extern TranscendentalPrecision rcpPrecision;
53 extern TranscendentalPrecision rsqPrecision;
54 extern bool perspectiveCorrection;
55
56 struct Query
57 {
58 Query()
59 {
60 building = false;
61 reference = 0;
62 data = 0;
63 }
64
65 void begin()
66 {
67 building = true;
68 data = 0;
69 }
70
71 void end()
72 {
73 building = false;
74 }
75
76 bool building;
77 volatile int reference;
78 volatile unsigned int data;
79 };
80
81 struct DrawData
82 {
83 const void *constants;
84
Alexis Hetu0b65c5e2015-03-31 11:48:57 -040085 const void *input[TEXTURE_IMAGE_UNITS];
86 unsigned int stride[TEXTURE_IMAGE_UNITS];
87 Texture mipmap[TOTAL_IMAGE_UNITS];
John Bauman66b8ab22014-05-06 15:57:45 -040088 const void *indices;
89
90 struct VS
91 {
92 float4 c[256 + 1]; // One extra for indices out of range, c[256] = {0, 0, 0, 0}
93 int4 i[16];
94 bool b[16];
95 };
96
97 struct PS
98 {
99 word4 cW[8][4];
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400100 float4 c[FRAGMENT_UNIFORM_VECTORS];
John Bauman66b8ab22014-05-06 15:57:45 -0400101 int4 i[16];
102 bool b[16];
103 };
104
105 union
106 {
107 VS vs;
108 VertexProcessor::FixedFunction ff;
109 };
110
111 PS ps;
112
113 VertexProcessor::PointSprite point;
Nicolas Capens235781d2015-01-27 01:46:53 -0500114 float lineWidth;
John Bauman66b8ab22014-05-06 15:57:45 -0400115
116 PixelProcessor::Stencil stencil[2]; // clockwise, counterclockwise
117 PixelProcessor::Stencil stencilCCW;
118 PixelProcessor::Fog fog;
119 PixelProcessor::Factor factor;
120 unsigned int occlusion[16]; // Number of pixels passing depth test
121
122 #if PERF_PROFILE
123 int64_t cycles[PERF_TIMERS][16];
124 #endif
125
126 TextureStage::Uniforms textureStage[8];
127
128 float4 Wx16;
129 float4 Hx16;
130 float4 X0x16;
131 float4 Y0x16;
132 float4 XXXX;
133 float4 YYYY;
134 float4 halfPixelX;
135 float4 halfPixelY;
136 float viewportHeight;
137 float slopeDepthBias;
138 float depthRange;
139 float depthNear;
140 Plane clipPlane[6];
141
142 unsigned int *colorBuffer[4];
143 int colorPitchB[4];
144 int colorSliceB[4];
145 float *depthBuffer;
146 int depthPitchB;
147 int depthSliceB;
148 unsigned char *stencilBuffer;
149 int stencilPitchB;
150 int stencilSliceB;
151
152 int scissorX0;
153 int scissorX1;
154 int scissorY0;
155 int scissorY1;
156
157 float4 a2c0;
158 float4 a2c1;
159 float4 a2c2;
160 float4 a2c3;
161 };
162
163 struct DrawCall
164 {
165 DrawCall();
166
167 ~DrawCall();
168
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400169 DrawType drawType;
John Bauman66b8ab22014-05-06 15:57:45 -0400170 int batchSize;
171
172 Routine *vertexRoutine;
173 Routine *setupRoutine;
174 Routine *pixelRoutine;
175
176 VertexProcessor::RoutinePointer vertexPointer;
177 SetupProcessor::RoutinePointer setupPointer;
178 PixelProcessor::RoutinePointer pixelPointer;
179
180 int (*setupPrimitives)(Renderer *renderer, int batch, int count);
181 SetupProcessor::State setupState;
182
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400183 Resource *vertexStream[TEXTURE_IMAGE_UNITS];
John Bauman66b8ab22014-05-06 15:57:45 -0400184 Resource *indexBuffer;
185 Surface *renderTarget[4];
186 Surface *depthStencil;
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400187 Resource *texture[TOTAL_IMAGE_UNITS];
John Bauman66b8ab22014-05-06 15:57:45 -0400188
189 int vsDirtyConstF;
190 int vsDirtyConstI;
191 int vsDirtyConstB;
192
193 int psDirtyConstF;
194 int psDirtyConstI;
195 int psDirtyConstB;
196
197 std::list<Query*> *queries;
198
199 int clipFlags;
200
201 volatile int primitive; // Current primitive to enter pipeline
202 volatile int count; // Number of primitives to render
203 volatile int references; // Remaining references to this draw call, 0 when done drawing, -1 when resources unlocked and slot is free
204
205 DrawData *data;
206 };
207
208 struct Viewport
209 {
210 float x0;
211 float y0;
212 float width;
213 float height;
214 float minZ;
215 float maxZ;
216 };
217
218 class Renderer : public VertexProcessor, public PixelProcessor, public SetupProcessor
219 {
220 struct Task
221 {
222 enum Type
223 {
224 PRIMITIVES,
225 PIXELS,
226
227 RESUME,
228 SUSPEND
229 };
230
231 volatile Type type;
232 volatile int primitiveUnit;
233 volatile int pixelCluster;
234 };
235
236 struct PrimitiveProgress
237 {
238 void init()
239 {
240 drawCall = 0;
241 firstPrimitive = 0;
242 primitiveCount = 0;
243 visible = 0;
244 references = 0;
245 }
246
247 volatile int drawCall;
248 volatile int firstPrimitive;
249 volatile int primitiveCount;
250 volatile int visible;
251 volatile int references;
252 };
253
254 struct PixelProgress
255 {
256 void init()
257 {
258 drawCall = 0;
259 processedPrimitives = 0;
260 executing = false;
261 }
262
263 volatile int drawCall;
264 volatile int processedPrimitives;
265 volatile bool executing;
266 };
267
268 public:
269 Renderer(Context *context, bool halfIntegerCoordinates, bool symmetricNormalizedDepth, bool booleanFaceRegister, bool fullPixelPositionRegister, bool exactColorRounding);
270
271 virtual ~Renderer();
272
Alexis Hetuf7be67f2015-02-11 16:11:07 -0500273 virtual void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter);
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400274 virtual void draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update = true);
John Bauman66b8ab22014-05-06 15:57:45 -0400275
276 virtual void setIndexBuffer(Resource *indexBuffer);
277
278 virtual void setMultiSampleMask(unsigned int mask);
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400279 virtual void setTransparencyAntialiasing(TransparencyAntialiasing transparencyAntialiasing);
John Bauman66b8ab22014-05-06 15:57:45 -0400280
281 virtual void setTextureResource(unsigned int sampler, Resource *resource);
282 virtual void setTextureLevel(unsigned int sampler, unsigned int face, unsigned int level, Surface *surface, TextureType type);
283
284 virtual void setTextureFilter(SamplerType type, int sampler, FilterType textureFilter);
285 virtual void setMipmapFilter(SamplerType type, int sampler, MipmapType mipmapFilter);
286 virtual void setGatherEnable(SamplerType type, int sampler, bool enable);
287 virtual void setAddressingModeU(SamplerType type, int sampler, AddressingMode addressingMode);
288 virtual void setAddressingModeV(SamplerType type, int sampler, AddressingMode addressingMode);
289 virtual void setAddressingModeW(SamplerType type, int sampler, AddressingMode addressingMode);
290 virtual void setReadSRGB(SamplerType type, int sampler, bool sRGB);
291 virtual void setMipmapLOD(SamplerType type, int sampler, float bias);
292 virtual void setBorderColor(SamplerType type, int sampler, const Color<float> &borderColor);
Alexis Hetu617a5d52014-11-13 10:56:20 -0500293 virtual void setMaxAnisotropy(SamplerType type, int sampler, float maxAnisotropy);
John Bauman66b8ab22014-05-06 15:57:45 -0400294
295 virtual void setPointSpriteEnable(bool pointSpriteEnable);
296 virtual void setPointScaleEnable(bool pointScaleEnable);
Nicolas Capens235781d2015-01-27 01:46:53 -0500297 virtual void setLineWidth(float width);
John Bauman66b8ab22014-05-06 15:57:45 -0400298
299 virtual void setDepthBias(float bias);
300 virtual void setSlopeDepthBias(float slopeBias);
301
302 // Programmable pipelines
303 virtual void setPixelShader(const PixelShader *shader);
304 virtual void setVertexShader(const VertexShader *shader);
305
306 virtual void setPixelShaderConstantF(int index, const float value[4], int count = 1);
307 virtual void setPixelShaderConstantI(int index, const int value[4], int count = 1);
308 virtual void setPixelShaderConstantB(int index, const int *boolean, int count = 1);
309
310 virtual void setVertexShaderConstantF(int index, const float value[4], int count = 1);
311 virtual void setVertexShaderConstantI(int index, const int value[4], int count = 1);
312 virtual void setVertexShaderConstantB(int index, const int *boolean, int count = 1);
313
314 // Viewport & Clipper
315 virtual void setViewport(const Viewport &viewport);
316 virtual void setScissor(const Rect &scissor);
317 virtual void setClipFlags(int flags);
318 virtual void setClipPlane(unsigned int index, const float plane[4]);
319
320 // Partial transform
321 virtual void setModelMatrix(const Matrix &M, int i = 0);
322 virtual void setViewMatrix(const Matrix &V);
323 virtual void setBaseMatrix(const Matrix &B);
324 virtual void setProjectionMatrix(const Matrix &P);
325
326 virtual void addQuery(Query *query);
327 virtual void removeQuery(Query *query);
328
329 void synchronize();
330
331 #if PERF_HUD
332 // Performance timers
333 int getThreadCount();
334 int64_t getVertexTime(int thread);
335 int64_t getSetupTime(int thread);
336 int64_t getPixelTime(int thread);
337 void resetTimers();
338 #endif
339
340 private:
341 static void threadFunction(void *parameters);
342 void threadLoop(int threadIndex);
343 void taskLoop(int threadIndex);
344 void findAvailableTasks();
345 void scheduleTask(int threadIndex);
346 void executeTask(int threadIndex);
347 void finishRendering(Task &pixelTask);
348
349 void processPrimitiveVertices(int unit, unsigned int start, unsigned int count, unsigned int loop, int thread);
350
351 static int setupSolidTriangles(Renderer *renderer, int batch, int count);
352 static int setupWireframeTriangle(Renderer *renderer, int batch, int count);
353 static int setupVertexTriangle(Renderer *renderer, int batch, int count);
354 static int setupLines(Renderer *renderer, int batch, int count);
355 static int setupPoints(Renderer *renderer, int batch, int count);
356
357 static bool setupLine(Renderer *renderer, Primitive &primitive, Triangle &triangle, const DrawCall &draw);
358 static bool setupPoint(Renderer *renderer, Primitive &primitive, Triangle &triangle, const DrawCall &draw);
359
360 bool isReadWriteTexture(int sampler);
361 void updateClipper();
362 void updateConfiguration(bool initialUpdate = false);
363 static unsigned int computeClipFlags(const float4 &v, const DrawData &data);
Nicolas Capens7381c992014-05-06 23:48:15 -0400364 void initializeThreads();
John Bauman66b8ab22014-05-06 15:57:45 -0400365 void terminateThreads();
John Bauman66b8ab22014-05-06 15:57:45 -0400366
367 void loadConstants(const VertexShader *vertexShader);
368 void loadConstants(const PixelShader *pixelShader);
369
370 Context *context;
371 Clipper *clipper;
372 Viewport viewport;
373 Rect scissor;
374 int clipFlags;
375
376 Triangle *triangleBatch[16];
377 Primitive *primitiveBatch[16];
378
379 // User-defined clipping planes
380 Plane userPlane[6];
381 Plane clipPlane[6]; // Tranformed to clip space
382 bool updateClipPlanes;
383
384 volatile bool exitThreads;
385 volatile int threadsAwake;
386 Thread *worker[16];
387 Event *resume[16]; // Events for resuming threads
388 Event *suspend[16]; // Events for suspending threads
389 Event *resumeApp; // Event for resuming the application thread
390
391 PrimitiveProgress primitiveProgress[16];
392 PixelProgress pixelProgress[16];
393 Task task[16]; // Current tasks for threads
394
395 enum {DRAW_COUNT = 16}; // Number of draw calls buffered
396 DrawCall *drawCall[DRAW_COUNT];
397 DrawCall *drawList[DRAW_COUNT];
398
399 volatile int currentDraw;
400 volatile int nextDraw;
401
402 Task taskQueue[32];
403 unsigned int qHead;
404 unsigned int qSize;
405
Nicolas Capensebe67642015-03-20 13:34:51 -0400406 BackoffLock schedulerMutex;
John Bauman66b8ab22014-05-06 15:57:45 -0400407
408 #if PERF_HUD
409 int64_t vertexTime[16];
410 int64_t setupTime[16];
411 int64_t pixelTime[16];
412 #endif
413
414 VertexTask *vertexTask[16];
415
416 SwiftConfig *swiftConfig;
417
418 std::list<Query*> queries;
419 Resource *sync;
420
421 VertexProcessor::State vertexState;
422 SetupProcessor::State setupState;
423 PixelProcessor::State pixelState;
John Bauman66b8ab22014-05-06 15:57:45 -0400424
425 Blitter blitter;
426 };
427}
428
429#endif // sw_Renderer_hpp