OSDN Git Service

Make Blitter part of Renderer.
[android-x86/external-swiftshader.git] / src / Renderer / Renderer.cpp
index 2cb19e3..a84423d 100644 (file)
@@ -113,7 +113,8 @@ namespace sw
                sw::exactColorRounding = exactColorRounding;
 
                setRenderTarget(0, 0);
-               clipper = new Clipper();
+               clipper = new Clipper(symmetricNormalizedDepth);
+               blitter = new Blitter;
 
                updateViewMatrix = true;
                updateBaseMatrix = true;
@@ -177,7 +178,10 @@ namespace sw
                sync->destruct();
 
                delete clipper;
-               clipper = 0;
+               clipper = nullptr;
+
+               delete blitter;
+               blitter = nullptr;
 
                terminateThreads();
                delete resumeApp;
@@ -190,19 +194,16 @@ namespace sw
                delete swiftConfig;
        }
 
-       void Renderer::clear(void *pixel, Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask)
-       {
-               blitter.clear(pixel, format, dest, dRect, rgbaMask);
-       }
-
-       void Renderer::blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter)
+       // This object has to be mem aligned
+       void* Renderer::operator new(size_t size)
        {
-               blitter.blit(source, sRect, dest, dRect, filter);
+               ASSERT(size == sizeof(Renderer)); // This operator can't be called from a derived class
+               return sw::allocate(sizeof(Renderer), 16);
        }
 
-       void Renderer::blit3D(Surface *source, Surface *dest)
+       void Renderer::operator delete(void * mem)
        {
-               blitter.blit3D(source, dest);
+               sw::deallocate(mem);
        }
 
        void Renderer::draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update)
@@ -234,13 +235,9 @@ namespace sw
 
                        sync->lock(sw::PRIVATE);
 
-                       Routine *vertexRoutine;
-                       Routine *setupRoutine;
-                       Routine *pixelRoutine;
-
                        if(update || oldMultiSampleMask != context->multiSampleMask)
                        {
-                               vertexState = VertexProcessor::update();
+                               vertexState = VertexProcessor::update(drawType);
                                setupState = SetupProcessor::update();
                                pixelState = PixelProcessor::update();
 
@@ -251,33 +248,35 @@ namespace sw
 
                        int batch = batchSize / ms;
 
-                       int (*setupPrimitives)(Renderer *renderer, int batch, int count);
+                       int (Renderer::*setupPrimitives)(int batch, int count);
 
                        if(context->isDrawTriangle())
                        {
                                switch(context->fillMode)
                                {
                                case FILL_SOLID:
-                                       setupPrimitives = setupSolidTriangles;
+                                       setupPrimitives = &Renderer::setupSolidTriangles;
                                        break;
                                case FILL_WIREFRAME:
-                                       setupPrimitives = setupWireframeTriangle;
+                                       setupPrimitives = &Renderer::setupWireframeTriangle;
                                        batch = 1;
                                        break;
                                case FILL_VERTEX:
-                                       setupPrimitives = setupVertexTriangle;
+                                       setupPrimitives = &Renderer::setupVertexTriangle;
                                        batch = 1;
                                        break;
-                               default: ASSERT(false);
+                               default:
+                                       ASSERT(false);
+                                       return;
                                }
                        }
                        else if(context->isDrawLine())
                        {
-                               setupPrimitives = setupLines;
+                               setupPrimitives = &Renderer::setupLines;
                        }
                        else   // Point draw
                        {
-                               setupPrimitives = setupPoints;
+                               setupPrimitives = &Renderer::setupPoints;
                        }
 
                        DrawCall *draw = 0;
@@ -447,7 +446,7 @@ namespace sw
                                        draw->vsDirtyConstB = 0;
                                }
 
-                               if(context->vertexShader->instanceIdDeclared)
+                               if(context->vertexShader->isInstanceIdDeclared())
                                {
                                        data->instanceID = context->instanceID;
                                }
@@ -624,7 +623,7 @@ namespace sw
 
                                if(draw->stencilBuffer)
                                {
-                                       data->stencilBuffer = (unsigned char*)context->stencilBuffer->lockStencil(q * ms, MANAGED);
+                                       data->stencilBuffer = (unsigned char*)context->stencilBuffer->lockStencil(0, 0, q * ms, MANAGED);
                                        data->stencilPitchB = context->stencilBuffer->getStencilPitchB();
                                        data->stencilSliceB = context->stencilBuffer->getStencilSliceB();
                                }
@@ -647,7 +646,16 @@ namespace sw
                        nextDraw++;
                        schedulerMutex.unlock();
 
-                       if(threadCount > 1)
+                       #ifndef NDEBUG
+                       if(threadCount == 1)   // Use main thread for draw execution
+                       {
+                               threadsAwake = 1;
+                               task[0].type = Task::RESUME;
+
+                               taskLoop(0);
+                       }
+                       else
+                       #endif
                        {
                                if(!threadsAwake)
                                {
@@ -659,16 +667,24 @@ namespace sw
                                        resume[0]->signal();
                                }
                        }
-                       else   // Use main thread for draw execution
-                       {
-                               threadsAwake = 1;
-                               task[0].type = Task::RESUME;
-
-                               taskLoop(0);
-                       }
                }
        }
 
+       void Renderer::clear(void *pixel, Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask)
+       {
+               blitter->clear(pixel, format, dest, dRect, rgbaMask);
+       }
+
+       void Renderer::blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil)
+       {
+               blitter->blit(source, sRect, dest, dRect, filter, isStencil);
+       }
+
+       void Renderer::blit3D(Surface *source, Surface *dest)
+       {
+               blitter->blit3D(source, dest);
+       }
+
        void Renderer::threadFunction(void *parameters)
        {
                Renderer *renderer = static_cast<Parameters*>(parameters)->renderer;
@@ -841,7 +857,7 @@ namespace sw
                                int input = primitiveProgress[unit].firstPrimitive;
                                int count = primitiveProgress[unit].primitiveCount;
                                DrawCall *draw = drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
-                               int (*setupPrimitives)(Renderer *renderer, int batch, int count) = draw->setupPrimitives;
+                               int (Renderer::*setupPrimitives)(int batch, int count) = draw->setupPrimitives;
 
                                processPrimitiveVertices(unit, input, count, draw->count, threadIndex);
 
@@ -851,7 +867,12 @@ namespace sw
                                        startTick = time;
                                #endif
 
-                               int visible = draw->setupState.rasterizerDiscard ? 0 : setupPrimitives(this, unit, count);
+                               int visible = 0;
+
+                               if(!draw->setupState.rasterizerDiscard)
+                               {
+                                       visible = (this->*setupPrimitives)(unit, count);
+                               }
 
                                primitiveProgress[unit].visible = visible;
                                primitiveProgress[unit].references = clusterCount;
@@ -1460,21 +1481,17 @@ namespace sw
                        return;
                }
 
-               task->vertexStart = start * 3;
+               task->primitiveStart = start;
                task->vertexCount = triangleCount * 3;
-               // Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
-               //       which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
-               DrawType type = static_cast<DrawType>(static_cast<unsigned int>(draw->drawType) & 0xF);
-               task->verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);
                vertexRoutine(&triangle->v0, (unsigned int*)&batch, task, data);
        }
 
-       int Renderer::setupSolidTriangles(Renderer *renderer, int unit, int count)
+       int Renderer::setupSolidTriangles(int unit, int count)
        {
-               Triangle *triangle = renderer->triangleBatch[unit];
-               Primitive *primitive = renderer->primitiveBatch[unit];
+               Triangle *triangle = triangleBatch[unit];
+               Primitive *primitive = primitiveBatch[unit];
 
-               DrawCall &draw = *renderer->drawList[renderer->primitiveProgress[unit].drawCall % DRAW_COUNT];
+               DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
                SetupProcessor::State &state = draw.setupState;
                const SetupProcessor::RoutinePointer &setupRoutine = draw.setupPointer;
 
@@ -1497,7 +1514,7 @@ namespace sw
 
                                if(clipFlagsOr != Clipper::CLIP_FINITE)
                                {
-                                       if(!renderer->clipper->clip(polygon, clipFlagsOr, draw))
+                                       if(!clipper->clip(polygon, clipFlagsOr, draw))
                                        {
                                                continue;
                                        }
@@ -1514,15 +1531,14 @@ namespace sw
                return visible;
        }
 
-       int Renderer::setupWireframeTriangle(Renderer *renderer, int unit, int count)
+       int Renderer::setupWireframeTriangle(int unit, int count)
        {
-               Triangle *triangle = renderer->triangleBatch[unit];
-               Primitive *primitive = renderer->primitiveBatch[unit];
+               Triangle *triangle = triangleBatch[unit];
+               Primitive *primitive = primitiveBatch[unit];
                int visible = 0;
 
-               DrawCall &draw = *renderer->drawList[renderer->primitiveProgress[unit].drawCall % DRAW_COUNT];
+               DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
                SetupProcessor::State &state = draw.setupState;
-               SetupProcessor::RoutinePointer setupRoutine = draw.setupPointer;
 
                const Vertex &v0 = triangle[0].v0;
                const Vertex &v1 = triangle[0].v1;
@@ -1558,7 +1574,7 @@ namespace sw
 
                for(int i = 0; i < 3; i++)
                {
-                       if(setupLine(renderer, *primitive, *triangle, draw))
+                       if(setupLine(*primitive, *triangle, draw))
                        {
                                primitive->area = 0.5f * d;
 
@@ -1572,13 +1588,13 @@ namespace sw
                return visible;
        }
 
-       int Renderer::setupVertexTriangle(Renderer *renderer, int unit, int count)
+       int Renderer::setupVertexTriangle(int unit, int count)
        {
-               Triangle *triangle = renderer->triangleBatch[unit];
-               Primitive *primitive = renderer->primitiveBatch[unit];
+               Triangle *triangle = triangleBatch[unit];
+               Primitive *primitive = primitiveBatch[unit];
                int visible = 0;
 
-               DrawCall &draw = *renderer->drawList[renderer->primitiveProgress[unit].drawCall % DRAW_COUNT];
+               DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
                SetupProcessor::State &state = draw.setupState;
 
                const Vertex &v0 = triangle[0].v0;
@@ -1602,7 +1618,7 @@ namespace sw
 
                for(int i = 0; i < 3; i++)
                {
-                       if(setupPoint(renderer, *primitive, *triangle, draw))
+                       if(setupPoint(*primitive, *triangle, draw))
                        {
                                primitive->area = 0.5f * d;
 
@@ -1616,20 +1632,20 @@ namespace sw
                return visible;
        }
 
-       int Renderer::setupLines(Renderer *renderer, int unit, int count)
+       int Renderer::setupLines(int unit, int count)
        {
-               Triangle *triangle = renderer->triangleBatch[unit];
-               Primitive *primitive = renderer->primitiveBatch[unit];
+               Triangle *triangle = triangleBatch[unit];
+               Primitive *primitive = primitiveBatch[unit];
                int visible = 0;
 
-               DrawCall &draw = *renderer->drawList[renderer->primitiveProgress[unit].drawCall % DRAW_COUNT];
+               DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
                SetupProcessor::State &state = draw.setupState;
 
                int ms = state.multiSample;
 
                for(int i = 0; i < count; i++)
                {
-                       if(setupLine(renderer, *primitive, *triangle, draw))
+                       if(setupLine(*primitive, *triangle, draw))
                        {
                                primitive += ms;
                                visible++;
@@ -1641,20 +1657,20 @@ namespace sw
                return visible;
        }
 
-       int Renderer::setupPoints(Renderer *renderer, int unit, int count)
+       int Renderer::setupPoints(int unit, int count)
        {
-               Triangle *triangle = renderer->triangleBatch[unit];
-               Primitive *primitive = renderer->primitiveBatch[unit];
+               Triangle *triangle = triangleBatch[unit];
+               Primitive *primitive = primitiveBatch[unit];
                int visible = 0;
 
-               DrawCall &draw = *renderer->drawList[renderer->primitiveProgress[unit].drawCall % DRAW_COUNT];
+               DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
                SetupProcessor::State &state = draw.setupState;
 
                int ms = state.multiSample;
 
                for(int i = 0; i < count; i++)
                {
-                       if(setupPoint(renderer, *primitive, *triangle, draw))
+                       if(setupPoint(*primitive, *triangle, draw))
                        {
                                primitive += ms;
                                visible++;
@@ -1666,7 +1682,7 @@ namespace sw
                return visible;
        }
 
-       bool Renderer::setupLine(Renderer *renderer, Primitive &primitive, Triangle &triangle, const DrawCall &draw)
+       bool Renderer::setupLine(Primitive &primitive, Triangle &triangle, const DrawCall &draw)
        {
                const SetupProcessor::RoutinePointer &setupRoutine = draw.setupPointer;
                const SetupProcessor::State &state = draw.setupState;
@@ -1725,19 +1741,19 @@ namespace sw
 
                        P[0].x += -dy0w + -dx0w;
                        P[0].y += -dx0h + +dy0h;
-                       C[0] = computeClipFlags(P[0], data);
+                       C[0] = clipper->computeClipFlags(P[0]);
 
                        P[1].x += -dy1w + +dx1w;
                        P[1].y += -dx1h + +dy1h;
-                       C[1] = computeClipFlags(P[1], data);
+                       C[1] = clipper->computeClipFlags(P[1]);
 
                        P[2].x += +dy1w + +dx1w;
                        P[2].y += +dx1h + -dy1h;
-                       C[2] = computeClipFlags(P[2], data);
+                       C[2] = clipper->computeClipFlags(P[2]);
 
                        P[3].x += +dy0w + -dx0w;
                        P[3].y += +dx0h + +dy0h;
-                       C[3] = computeClipFlags(P[3], data);
+                       C[3] = clipper->computeClipFlags(P[3]);
 
                        if((C[0] & C[1] & C[2] & C[3]) == Clipper::CLIP_FINITE)
                        {
@@ -1747,7 +1763,7 @@ namespace sw
 
                                if(clipFlagsOr != Clipper::CLIP_FINITE)
                                {
-                                       if(!renderer->clipper->clip(polygon, clipFlagsOr, draw))
+                                       if(!clipper->clip(polygon, clipFlagsOr, draw))
                                        {
                                                return false;
                                        }
@@ -1777,28 +1793,28 @@ namespace sw
                        float dy1 = lineWidth * 0.5f * P1.w / H;
 
                        P[0].x += -dx0;
-                       C[0] = computeClipFlags(P[0], data);
+                       C[0] = clipper->computeClipFlags(P[0]);
 
                        P[1].y += +dy0;
-                       C[1] = computeClipFlags(P[1], data);
+                       C[1] = clipper->computeClipFlags(P[1]);
 
                        P[2].x += +dx0;
-                       C[2] = computeClipFlags(P[2], data);
+                       C[2] = clipper->computeClipFlags(P[2]);
 
                        P[3].y += -dy0;
-                       C[3] = computeClipFlags(P[3], data);
+                       C[3] = clipper->computeClipFlags(P[3]);
 
                        P[4].x += -dx1;
-                       C[4] = computeClipFlags(P[4], data);
+                       C[4] = clipper->computeClipFlags(P[4]);
 
                        P[5].y += +dy1;
-                       C[5] = computeClipFlags(P[5], data);
+                       C[5] = clipper->computeClipFlags(P[5]);
 
                        P[6].x += +dx1;
-                       C[6] = computeClipFlags(P[6], data);
+                       C[6] = clipper->computeClipFlags(P[6]);
 
                        P[7].y += -dy1;
-                       C[7] = computeClipFlags(P[7], data);
+                       C[7] = clipper->computeClipFlags(P[7]);
 
                        if((C[0] & C[1] & C[2] & C[3] & C[4] & C[5] & C[6] & C[7]) == Clipper::CLIP_FINITE)
                        {
@@ -1853,7 +1869,7 @@ namespace sw
 
                                if(clipFlagsOr != Clipper::CLIP_FINITE)
                                {
-                                       if(!renderer->clipper->clip(polygon, clipFlagsOr, draw))
+                                       if(!clipper->clip(polygon, clipFlagsOr, draw))
                                        {
                                                return false;
                                        }
@@ -1866,7 +1882,7 @@ namespace sw
                return false;
        }
 
-       bool Renderer::setupPoint(Renderer *renderer, Primitive &primitive, Triangle &triangle, const DrawCall &draw)
+       bool Renderer::setupPoint(Primitive &primitive, Triangle &triangle, const DrawCall &draw)
        {
                const SetupProcessor::RoutinePointer &setupRoutine = draw.setupPointer;
                const SetupProcessor::State &state = draw.setupState;
@@ -1904,19 +1920,19 @@ namespace sw
 
                P[0].x -= X;
                P[0].y += Y;
-               C[0] = computeClipFlags(P[0], data);
+               C[0] = clipper->computeClipFlags(P[0]);
 
                P[1].x += X;
                P[1].y += Y;
-               C[1] = computeClipFlags(P[1], data);
+               C[1] = clipper->computeClipFlags(P[1]);
 
                P[2].x += X;
                P[2].y -= Y;
-               C[2] = computeClipFlags(P[2], data);
+               C[2] = clipper->computeClipFlags(P[2]);
 
                P[3].x -= X;
                P[3].y -= Y;
-               C[3] = computeClipFlags(P[3], data);
+               C[3] = clipper->computeClipFlags(P[3]);
 
                triangle.v1 = triangle.v0;
                triangle.v2 = triangle.v0;
@@ -1932,7 +1948,7 @@ namespace sw
 
                        if(clipFlagsOr != Clipper::CLIP_FINITE)
                        {
-                               if(!renderer->clipper->clip(polygon, clipFlagsOr, draw))
+                               if(!clipper->clip(polygon, clipFlagsOr, draw))
                                {
                                        return false;
                                }
@@ -1944,17 +1960,6 @@ namespace sw
                return false;
        }
 
-       unsigned int Renderer::computeClipFlags(const float4 &v, const DrawData &data)
-       {
-               return ((v.x > v.w)  << 0) |
-                      ((v.y > v.w)  << 1) |
-                      ((v.z > v.w)  << 2) |
-                      ((v.x < -v.w) << 3) |
-                      ((v.y < -v.w) << 4) |
-                      ((v.z < 0)    << 5) |
-                      Clipper::CLIP_FINITE;   // FIXME: xyz finite
-       }
-
        void Renderer::initializeThreads()
        {
                unitCount = ceilPow2(threadCount);
@@ -2357,6 +2362,54 @@ namespace sw
                }
        }
 
+       void Renderer::setBaseLevel(SamplerType type, int sampler, int baseLevel)
+       {
+               if(type == SAMPLER_PIXEL)
+               {
+                       PixelProcessor::setBaseLevel(sampler, baseLevel);
+               }
+               else
+               {
+                       VertexProcessor::setBaseLevel(sampler, baseLevel);
+               }
+       }
+
+       void Renderer::setMaxLevel(SamplerType type, int sampler, int maxLevel)
+       {
+               if(type == SAMPLER_PIXEL)
+               {
+                       PixelProcessor::setMaxLevel(sampler, maxLevel);
+               }
+               else
+               {
+                       VertexProcessor::setMaxLevel(sampler, maxLevel);
+               }
+       }
+
+       void Renderer::setMinLod(SamplerType type, int sampler, float minLod)
+       {
+               if(type == SAMPLER_PIXEL)
+               {
+                       PixelProcessor::setMinLod(sampler, minLod);
+               }
+               else
+               {
+                       VertexProcessor::setMinLod(sampler, minLod);
+               }
+       }
+
+       void Renderer::setMaxLod(SamplerType type, int sampler, float maxLod)
+       {
+               if(type == SAMPLER_PIXEL)
+               {
+                       PixelProcessor::setMaxLod(sampler, maxLod);
+               }
+               else
+               {
+                       VertexProcessor::setMaxLod(sampler, maxLod);
+               }
+       }
+
        void Renderer::setPointSpriteEnable(bool pointSpriteEnable)
        {
                context->setPointSpriteEnable(pointSpriteEnable);