| // Copyright 2016 The SwiftShader Authors. All Rights Reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #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; | |
| struct Constants; | |
| 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 Conventions | |
| { | |
| bool halfIntegerCoordinates; | |
| bool symmetricNormalizedDepth; | |
| bool booleanFaceRegister; | |
| bool fullPixelPositionRegister; | |
| bool leadingVertexFirst; | |
| bool secondaryColor; | |
| }; | |
| static const Conventions OpenGL = | |
| { | |
| true, // halfIntegerCoordinates | |
| true, // symmetricNormalizedDepth | |
| true, // booleanFaceRegister | |
| true, // fullPixelPositionRegister | |
| false, // leadingVertexFirst | |
| false // secondaryColor | |
| }; | |
| static const Conventions Direct3D = | |
| { | |
| false, // halfIntegerCoordinates | |
| false, // symmetricNormalizedDepth | |
| false, // booleanFaceRegister | |
| false, // fullPixelPositionRegister | |
| true, // leadingVertexFirst | |
| true, // secondardyColor | |
| }; | |
| struct Query | |
| { | |
| enum Type { FRAGMENTS_PASSED, TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN }; | |
| Query(Type type) : building(false), reference(0), data(0), type(type) | |
| { | |
| } | |
| void begin() | |
| { | |
| building = true; | |
| data = 0; | |
| } | |
| void end() | |
| { | |
| building = false; | |
| } | |
| bool building; | |
| volatile int reference; | |
| volatile unsigned int data; | |
| const Type type; | |
| }; | |
| struct DrawData | |
| { | |
| const Constants *constants; | |
| const void *input[MAX_VERTEX_INPUTS]; | |
| unsigned int stride[MAX_VERTEX_INPUTS]; | |
| Texture mipmap[TOTAL_IMAGE_UNITS]; | |
| const void *indices; | |
| struct VS | |
| { | |
| float4 c[VERTEX_UNIFORM_VECTORS + 1]; // One extra for indices out of range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0} | |
| byte* u[MAX_UNIFORM_BUFFER_BINDINGS]; | |
| byte* t[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; | |
| unsigned int reg[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Offset used when reading from registers, in components | |
| unsigned int row[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Number of rows to read | |
| unsigned int col[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Number of columns to read | |
| unsigned int str[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; // Number of components between each varying in output buffer | |
| int4 i[16]; | |
| bool b[16]; | |
| }; | |
| struct PS | |
| { | |
| word4 cW[8][4]; | |
| float4 c[FRAGMENT_UNIFORM_VECTORS]; | |
| byte* u[MAX_UNIFORM_BUFFER_BINDINGS]; | |
| int4 i[16]; | |
| bool b[16]; | |
| }; | |
| union | |
| { | |
| VS vs; | |
| VertexProcessor::FixedFunction ff; | |
| }; | |
| PS ps; | |
| int instanceID; | |
| VertexProcessor::PointSprite point; | |
| float lineWidth; | |
| 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[RENDERTARGETS]; | |
| int colorPitchB[RENDERTARGETS]; | |
| int colorSliceB[RENDERTARGETS]; | |
| 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 (Renderer::*setupPrimitives)(int batch, int count); | |
| SetupProcessor::State setupState; | |
| Resource *vertexStream[MAX_VERTEX_INPUTS]; | |
| Resource *indexBuffer; | |
| Surface *renderTarget[RENDERTARGETS]; | |
| Surface *depthBuffer; | |
| Surface *stencilBuffer; | |
| Resource *texture[TOTAL_IMAGE_UNITS]; | |
| Resource* pUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS]; | |
| Resource* vUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS]; | |
| Resource* transformFeedbackBuffers[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS]; | |
| 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, Conventions conventions, bool exactColorRounding); | |
| virtual ~Renderer(); | |
| void *operator new(size_t size); | |
| void operator delete(void * mem); | |
| void clear(void* pixel, Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask); | |
| void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter); | |
| void blit3D(Surface *source, Surface *dest); | |
| void draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update = true); | |
| void setIndexBuffer(Resource *indexBuffer); | |
| void setMultiSampleMask(unsigned int mask); | |
| void setTransparencyAntialiasing(TransparencyAntialiasing transparencyAntialiasing); | |
| void setTextureResource(unsigned int sampler, Resource *resource); | |
| void setTextureLevel(unsigned int sampler, unsigned int face, unsigned int level, Surface *surface, TextureType type); | |
| void setTextureFilter(SamplerType type, int sampler, FilterType textureFilter); | |
| void setMipmapFilter(SamplerType type, int sampler, MipmapType mipmapFilter); | |
| void setGatherEnable(SamplerType type, int sampler, bool enable); | |
| void setAddressingModeU(SamplerType type, int sampler, AddressingMode addressingMode); | |
| void setAddressingModeV(SamplerType type, int sampler, AddressingMode addressingMode); | |
| void setAddressingModeW(SamplerType type, int sampler, AddressingMode addressingMode); | |
| void setReadSRGB(SamplerType type, int sampler, bool sRGB); | |
| void setMipmapLOD(SamplerType type, int sampler, float bias); | |
| void setBorderColor(SamplerType type, int sampler, const Color<float> &borderColor); | |
| void setMaxAnisotropy(SamplerType type, int sampler, float maxAnisotropy); | |
| void setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR); | |
| void setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG); | |
| void setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB); | |
| void setSwizzleA(SamplerType type, int sampler, SwizzleType swizzleA); | |
| void setBaseLevel(SamplerType type, int sampler, int baseLevel); | |
| void setMaxLevel(SamplerType type, int sampler, int maxLevel); | |
| void setMinLod(SamplerType type, int sampler, float minLod); | |
| void setMaxLod(SamplerType type, int sampler, float maxLod); | |
| void setPointSpriteEnable(bool pointSpriteEnable); | |
| void setPointScaleEnable(bool pointScaleEnable); | |
| void setLineWidth(float width); | |
| void setDepthBias(float bias); | |
| void setSlopeDepthBias(float slopeBias); | |
| void setRasterizerDiscard(bool rasterizerDiscard); | |
| // Programmable pipelines | |
| void setPixelShader(const PixelShader *shader); | |
| void setVertexShader(const VertexShader *shader); | |
| void setPixelShaderConstantF(int index, const float value[4], int count = 1); | |
| void setPixelShaderConstantI(int index, const int value[4], int count = 1); | |
| void setPixelShaderConstantB(int index, const int *boolean, int count = 1); | |
| void setVertexShaderConstantF(int index, const float value[4], int count = 1); | |
| void setVertexShaderConstantI(int index, const int value[4], int count = 1); | |
| void setVertexShaderConstantB(int index, const int *boolean, int count = 1); | |
| // Viewport & Clipper | |
| void setViewport(const Viewport &viewport); | |
| void setScissor(const Rect &scissor); | |
| void setClipFlags(int flags); | |
| void setClipPlane(unsigned int index, const float plane[4]); | |
| // Partial transform | |
| void setModelMatrix(const Matrix &M, int i = 0); | |
| void setViewMatrix(const Matrix &V); | |
| void setBaseMatrix(const Matrix &B); | |
| void setProjectionMatrix(const Matrix &P); | |
| void addQuery(Query *query); | |
| 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); | |
| int setupSolidTriangles(int batch, int count); | |
| int setupWireframeTriangle(int batch, int count); | |
| int setupVertexTriangle(int batch, int count); | |
| int setupLines(int batch, int count); | |
| int setupPoints(int batch, int count); | |
| bool setupLine(Primitive &primitive, Triangle &triangle, const DrawCall &draw); | |
| bool setupPoint(Primitive &primitive, Triangle &triangle, const DrawCall &draw); | |
| bool isReadWriteTexture(int sampler); | |
| void updateClipper(); | |
| void updateConfiguration(bool initialUpdate = false); | |
| 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[MAX_CLIP_PLANES]; | |
| Plane clipPlane[MAX_CLIP_PLANES]; // 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 schedulerMutex; | |
| #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; | |
| Routine *vertexRoutine; | |
| Routine *setupRoutine; | |
| Routine *pixelRoutine; | |
| }; | |
| } | |
| #endif // sw_Renderer_hpp |