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