| // 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(); |
| |
| 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(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(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(); |
| void terminateThreads(); |
| |
| 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 |