| // SwiftShader Software Renderer | |
| // | |
| // Copyright(c) 2005-2012 TransGaming Inc. | |
| // | |
| // All rights reserved. No part of this software may be copied, distributed, transmitted, | |
| // transcribed, stored in a retrieval system, translated into any human or computer | |
| // language by any means, or disclosed to third parties without the explicit written | |
| // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express | |
| // or implied, including but not limited to any patent rights, are granted to you. | |
| // | |
| #ifndef sw_Renderer_hpp | |
| #define sw_Renderer_hpp | |
| #include "VertexProcessor.hpp" | |
| #include "PixelProcessor.hpp" | |
| #include "SetupProcessor.hpp" | |
| #include "Plane.hpp" | |
| #include "Blitter.hpp" | |
| #include "Common/MutexLock.hpp" | |
| #include "Common/Thread.hpp" | |
| #include "Main/Config.hpp" | |
| #include <list> | |
| namespace sw | |
| { | |
| class Clipper; | |
| class PixelShader; | |
| class VertexShader; | |
| class SwiftConfig; | |
| struct Task; | |
| class Resource; | |
| class Renderer; | |
| extern int batchSize; | |
| extern int threadCount; | |
| extern int unitCount; | |
| extern int clusterCount; | |
| enum TranscendentalPrecision | |
| { | |
| APPROXIMATE, | |
| PARTIAL, // 2^-10 | |
| ACCURATE, | |
| WHQL, // 2^-21 | |
| IEEE // 2^-23 | |
| }; | |
| extern TranscendentalPrecision logPrecision; | |
| extern TranscendentalPrecision expPrecision; | |
| extern TranscendentalPrecision rcpPrecision; | |
| extern TranscendentalPrecision rsqPrecision; | |
| extern bool perspectiveCorrection; | |
| struct Query | |
| { | |
| Query() | |
| { | |
| building = false; | |
| reference = 0; | |
| data = 0; | |
| } | |
| void begin() | |
| { | |
| building = true; | |
| data = 0; | |
| } | |
| void end() | |
| { | |
| building = false; | |
| } | |
| bool building; | |
| volatile int reference; | |
| volatile unsigned int data; | |
| }; | |
| struct DrawData | |
| { | |
| const void *constants; | |
| const void *input[16]; | |
| unsigned int stride[16]; | |
| Texture mipmap[16 + 4]; | |
| const void *indices; | |
| struct VS | |
| { | |
| float4 c[256 + 1]; // One extra for indices out of range, c[256] = {0, 0, 0, 0} | |
| int4 i[16]; | |
| bool b[16]; | |
| }; | |
| struct PS | |
| { | |
| word4 cW[8][4]; | |
| float4 c[224]; | |
| int4 i[16]; | |
| bool b[16]; | |
| }; | |
| union | |
| { | |
| VS vs; | |
| VertexProcessor::FixedFunction ff; | |
| }; | |
| PS ps; | |
| VertexProcessor::PointSprite point; | |
| PixelProcessor::Stencil stencil[2]; // clockwise, counterclockwise | |
| PixelProcessor::Stencil stencilCCW; | |
| PixelProcessor::Fog fog; | |
| PixelProcessor::Factor factor; | |
| unsigned int occlusion[16]; // Number of pixels passing depth test | |
| #if PERF_PROFILE | |
| int64_t cycles[PERF_TIMERS][16]; | |
| #endif | |
| TextureStage::Uniforms textureStage[8]; | |
| float4 Wx16; | |
| float4 Hx16; | |
| float4 X0x16; | |
| float4 Y0x16; | |
| float4 XXXX; | |
| float4 YYYY; | |
| float4 halfPixelX; | |
| float4 halfPixelY; | |
| float viewportHeight; | |
| float slopeDepthBias; | |
| float depthRange; | |
| float depthNear; | |
| Plane clipPlane[6]; | |
| unsigned int *colorBuffer[4]; | |
| int colorPitchB[4]; | |
| int colorSliceB[4]; | |
| float *depthBuffer; | |
| int depthPitchB; | |
| int depthSliceB; | |
| unsigned char *stencilBuffer; | |
| int stencilPitchB; | |
| int stencilSliceB; | |
| int scissorX0; | |
| int scissorX1; | |
| int scissorY0; | |
| int scissorY1; | |
| float4 a2c0; | |
| float4 a2c1; | |
| float4 a2c2; | |
| float4 a2c3; | |
| }; | |
| struct DrawCall | |
| { | |
| DrawCall(); | |
| ~DrawCall(); | |
| Context::DrawType drawType; | |
| int batchSize; | |
| Routine *vertexRoutine; | |
| Routine *setupRoutine; | |
| Routine *pixelRoutine; | |
| VertexProcessor::RoutinePointer vertexPointer; | |
| SetupProcessor::RoutinePointer setupPointer; | |
| PixelProcessor::RoutinePointer pixelPointer; | |
| int (*setupPrimitives)(Renderer *renderer, int batch, int count); | |
| SetupProcessor::State setupState; | |
| Resource *vertexStream[16]; | |
| Resource *indexBuffer; | |
| Surface *renderTarget[4]; | |
| Surface *depthStencil; | |
| Resource *texture[16 + 4]; | |
| int vsDirtyConstF; | |
| int vsDirtyConstI; | |
| int vsDirtyConstB; | |
| int psDirtyConstF; | |
| int psDirtyConstI; | |
| int psDirtyConstB; | |
| std::list<Query*> *queries; | |
| int clipFlags; | |
| volatile int primitive; // Current primitive to enter pipeline | |
| volatile int count; // Number of primitives to render | |
| volatile int references; // Remaining references to this draw call, 0 when done drawing, -1 when resources unlocked and slot is free | |
| DrawData *data; | |
| }; | |
| struct Viewport | |
| { | |
| float x0; | |
| float y0; | |
| float width; | |
| float height; | |
| float minZ; | |
| float maxZ; | |
| }; | |
| class Renderer : public VertexProcessor, public PixelProcessor, public SetupProcessor | |
| { | |
| struct Task | |
| { | |
| enum Type | |
| { | |
| PRIMITIVES, | |
| PIXELS, | |
| RESUME, | |
| SUSPEND | |
| }; | |
| volatile Type type; | |
| volatile int primitiveUnit; | |
| volatile int pixelCluster; | |
| }; | |
| struct PrimitiveProgress | |
| { | |
| void init() | |
| { | |
| drawCall = 0; | |
| firstPrimitive = 0; | |
| primitiveCount = 0; | |
| visible = 0; | |
| references = 0; | |
| } | |
| volatile int drawCall; | |
| volatile int firstPrimitive; | |
| volatile int primitiveCount; | |
| volatile int visible; | |
| volatile int references; | |
| }; | |
| struct PixelProgress | |
| { | |
| void init() | |
| { | |
| drawCall = 0; | |
| processedPrimitives = 0; | |
| executing = false; | |
| } | |
| volatile int drawCall; | |
| volatile int processedPrimitives; | |
| volatile bool executing; | |
| }; | |
| public: | |
| Renderer(Context *context, bool halfIntegerCoordinates, bool symmetricNormalizedDepth, bool booleanFaceRegister, bool fullPixelPositionRegister, bool exactColorRounding); | |
| virtual ~Renderer(); | |
| virtual void blit(Surface *source, const Rect &sRect, Surface *dest, const Rect &dRect, bool filter); | |
| virtual void draw(Context::DrawType drawType, unsigned int indexOffset, unsigned int count, bool update = true); | |
| virtual void setIndexBuffer(Resource *indexBuffer); | |
| virtual void setMultiSampleMask(unsigned int mask); | |
| virtual void setTransparencyAntialiasing(Context::TransparencyAntialiasing transparencyAntialiasing); | |
| virtual void setTextureResource(unsigned int sampler, Resource *resource); | |
| virtual void setTextureLevel(unsigned int sampler, unsigned int face, unsigned int level, Surface *surface, TextureType type); | |
| virtual void setTextureFilter(SamplerType type, int sampler, FilterType textureFilter); | |
| virtual void setMipmapFilter(SamplerType type, int sampler, MipmapType mipmapFilter); | |
| virtual void setGatherEnable(SamplerType type, int sampler, bool enable); | |
| virtual void setAddressingModeU(SamplerType type, int sampler, AddressingMode addressingMode); | |
| virtual void setAddressingModeV(SamplerType type, int sampler, AddressingMode addressingMode); | |
| virtual void setAddressingModeW(SamplerType type, int sampler, AddressingMode addressingMode); | |
| virtual void setReadSRGB(SamplerType type, int sampler, bool sRGB); | |
| virtual void setMipmapLOD(SamplerType type, int sampler, float bias); | |
| virtual void setBorderColor(SamplerType type, int sampler, const Color<float> &borderColor); | |
| virtual void setMaxAnisotropy(SamplerType type, int sampler, unsigned int maxAnisotropy); | |
| virtual void setPointSpriteEnable(bool pointSpriteEnable); | |
| virtual void setPointScaleEnable(bool pointScaleEnable); | |
| virtual void setDepthBias(float bias); | |
| virtual void setSlopeDepthBias(float slopeBias); | |
| // Programmable pipelines | |
| virtual void setPixelShader(const PixelShader *shader); | |
| virtual void setVertexShader(const VertexShader *shader); | |
| virtual void setPixelShaderConstantF(int index, const float value[4], int count = 1); | |
| virtual void setPixelShaderConstantI(int index, const int value[4], int count = 1); | |
| virtual void setPixelShaderConstantB(int index, const int *boolean, int count = 1); | |
| virtual void setVertexShaderConstantF(int index, const float value[4], int count = 1); | |
| virtual void setVertexShaderConstantI(int index, const int value[4], int count = 1); | |
| virtual void setVertexShaderConstantB(int index, const int *boolean, int count = 1); | |
| // Viewport & Clipper | |
| virtual void setViewport(const Viewport &viewport); | |
| virtual void setScissor(const Rect &scissor); | |
| virtual void setClipFlags(int flags); | |
| virtual void setClipPlane(unsigned int index, const float plane[4]); | |
| // Partial transform | |
| virtual void setModelMatrix(const Matrix &M, int i = 0); | |
| virtual void setViewMatrix(const Matrix &V); | |
| virtual void setBaseMatrix(const Matrix &B); | |
| virtual void setProjectionMatrix(const Matrix &P); | |
| virtual void addQuery(Query *query); | |
| virtual void removeQuery(Query *query); | |
| void synchronize(); | |
| #if PERF_HUD | |
| // Performance timers | |
| int getThreadCount(); | |
| int64_t getVertexTime(int thread); | |
| int64_t getSetupTime(int thread); | |
| int64_t getPixelTime(int thread); | |
| void resetTimers(); | |
| #endif | |
| private: | |
| static void threadFunction(void *parameters); | |
| void threadLoop(int threadIndex); | |
| void taskLoop(int threadIndex); | |
| void findAvailableTasks(); | |
| void scheduleTask(int threadIndex); | |
| void executeTask(int threadIndex); | |
| void finishRendering(Task &pixelTask); | |
| void processPrimitiveVertices(int unit, unsigned int start, unsigned int count, unsigned int loop, int thread); | |
| static int setupSolidTriangles(Renderer *renderer, int batch, int count); | |
| static int setupWireframeTriangle(Renderer *renderer, int batch, int count); | |
| static int setupVertexTriangle(Renderer *renderer, int batch, int count); | |
| static int setupLines(Renderer *renderer, int batch, int count); | |
| static int setupPoints(Renderer *renderer, int batch, int count); | |
| static bool setupLine(Renderer *renderer, Primitive &primitive, Triangle &triangle, const DrawCall &draw); | |
| static bool setupPoint(Renderer *renderer, Primitive &primitive, Triangle &triangle, const DrawCall &draw); | |
| bool isReadWriteTexture(int sampler); | |
| void updateClipper(); | |
| void updateConfiguration(bool initialUpdate = false); | |
| static unsigned int computeClipFlags(const float4 &v, const DrawData &data); | |
| void initializeThreads(int threadCount); | |
| void terminateThreads(); | |
| void deleteBatches(); | |
| void loadConstants(const VertexShader *vertexShader); | |
| void loadConstants(const PixelShader *pixelShader); | |
| Context *context; | |
| Clipper *clipper; | |
| Viewport viewport; | |
| Rect scissor; | |
| int clipFlags; | |
| Triangle *triangleBatch[16]; | |
| Primitive *primitiveBatch[16]; | |
| // User-defined clipping planes | |
| Plane userPlane[6]; | |
| Plane clipPlane[6]; // Tranformed to clip space | |
| bool updateClipPlanes; | |
| volatile bool exitThreads; | |
| volatile int threadsAwake; | |
| Thread *worker[16]; | |
| Event *resume[16]; // Events for resuming threads | |
| Event *suspend[16]; // Events for suspending threads | |
| Event *resumeApp; // Event for resuming the application thread | |
| PrimitiveProgress primitiveProgress[16]; | |
| PixelProgress pixelProgress[16]; | |
| Task task[16]; // Current tasks for threads | |
| enum {DRAW_COUNT = 16}; // Number of draw calls buffered | |
| DrawCall *drawCall[DRAW_COUNT]; | |
| DrawCall *drawList[DRAW_COUNT]; | |
| volatile int currentDraw; | |
| volatile int nextDraw; | |
| Task taskQueue[32]; | |
| unsigned int qHead; | |
| unsigned int qSize; | |
| BackoffLock mutex; | |
| #if PERF_HUD | |
| int64_t vertexTime[16]; | |
| int64_t setupTime[16]; | |
| int64_t pixelTime[16]; | |
| #endif | |
| VertexTask *vertexTask[16]; | |
| SwiftConfig *swiftConfig; | |
| std::list<Query*> queries; | |
| Resource *sync; | |
| VertexProcessor::State vertexState; | |
| SetupProcessor::State setupState; | |
| PixelProcessor::State pixelState; | |
| int (*setupPrimitives)(Renderer *renderer, int batch, int count); | |
| Routine *vertexRoutine; | |
| Routine *setupRoutine; | |
| Routine *pixelRoutine; | |
| Blitter blitter; | |
| }; | |
| } | |
| #endif // sw_Renderer_hpp |