-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
//
-// 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.
+// 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.
#include "Renderer.hpp"
#include "Debug.hpp"
#include "Reactor/Reactor.hpp"
-#include <malloc.h>
-
#undef max
bool disableServer = true;
extern bool symmetricNormalizedDepth; // [-1, 1] instead of [0, 1]
extern bool booleanFaceRegister;
extern bool fullPixelPositionRegister;
+ extern bool leadingVertexFirst; // Flat shading uses first vertex, else last
+ extern bool secondaryColor; // Specular lighting is applied after texturing
extern bool forceWindowed;
extern bool complementaryDepthBuffer;
extern bool postBlendSRGB;
extern bool exactColorRounding;
- extern bool leadingVertexFirst;
extern TransparencyAntialiasing transparencyAntialiasing;
extern bool forceClearRegisters;
{
queries = 0;
- vsDirtyConstF = 256 + 1;
+ vsDirtyConstF = VERTEX_UNIFORM_VECTORS + 1;
vsDirtyConstI = 16;
vsDirtyConstB = 16;
- psDirtyConstF = 224;
+ psDirtyConstF = FRAGMENT_UNIFORM_VECTORS;
psDirtyConstI = 16;
psDirtyConstB = 16;
deallocate(data);
}
- Renderer::Renderer(Context *context, Conventions conventions, bool exactColorRounding) : context(context), VertexProcessor(context), PixelProcessor(context), SetupProcessor(context), viewport()
+ Renderer::Renderer(Context *context, Conventions conventions, bool exactColorRounding) : VertexProcessor(context), PixelProcessor(context), SetupProcessor(context), context(context), viewport()
{
sw::halfIntegerCoordinates = conventions.halfIntegerCoordinates;
sw::symmetricNormalizedDepth = conventions.symmetricNormalizedDepth;
sw::booleanFaceRegister = conventions.booleanFaceRegister;
sw::fullPixelPositionRegister = conventions.fullPixelPositionRegister;
sw::leadingVertexFirst = conventions.leadingVertexFirst;
+ sw::secondaryColor = conventions.secondaryColor;
sw::exactColorRounding = exactColorRounding;
setRenderTarget(0, 0);
- clipper = new Clipper();
+ clipper = new Clipper(symmetricNormalizedDepth);
+ blitter = new Blitter;
updateViewMatrix = true;
updateBaseMatrix = true;
sync->destruct();
delete clipper;
- clipper = 0;
+ clipper = nullptr;
+
+ delete blitter;
+ blitter = nullptr;
terminateThreads();
delete resumeApp;
delete swiftConfig;
}
- 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)
for(int q = 0; q < ss; q++)
{
- int oldMultiSampleMask = context->multiSampleMask;
+ unsigned int oldMultiSampleMask = context->multiSampleMask;
context->multiSampleMask = (context->sampleMask >> (ms * q)) & ((unsigned)0xFFFFFFFF >> (32 - ms));
if(!context->multiSampleMask)
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();
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;
if(queries.size() != 0)
{
+ draw->queries = new std::list<Query*>();
+ bool includePrimitivesWrittenQueries = vertexState.transformFeedbackQueryEnabled && vertexState.transformFeedbackEnabled;
for(std::list<Query*>::iterator query = queries.begin(); query != queries.end(); query++)
{
- atomicIncrement(&(*query)->reference);
+ Query* q = *query;
+ if(includePrimitivesWrittenQueries || (q->type != Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN))
+ {
+ atomicIncrement(&(q->reference));
+ draw->queries->push_back(q);
+ }
}
-
- draw->queries = new std::list<Query*>(queries);
}
draw->drawType = drawType;
draw->setupPrimitives = setupPrimitives;
draw->setupState = setupState;
- for(int i = 0; i < 16; i++)
+ for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
{
draw->vertexStream[i] = context->input[i].resource;
data->input[i] = context->input[i].buffer;
memcpy(&data->ps.b, PixelProcessor::b, sizeof(bool) * draw->psDirtyConstB);
draw->psDirtyConstB = 0;
}
+
+ PixelProcessor::lockUniformBuffers(data->ps.u, draw->pUniformBuffers);
}
-
+ else
+ {
+ for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++)
+ {
+ draw->pUniformBuffers[i] = nullptr;
+ }
+ }
+
if(context->pixelShaderVersion() <= 0x0104)
{
for(int stage = 0; stage < 8; stage++)
draw->vsDirtyConstB = 0;
}
- if(context->vertexShader->instanceIdDeclared)
+ if(context->vertexShader->isInstanceIdDeclared())
{
data->instanceID = context->instanceID;
}
+
+ VertexProcessor::lockUniformBuffers(data->vs.u, draw->vUniformBuffers);
+ VertexProcessor::lockTransformFeedbackBuffers(data->vs.t, data->vs.reg, data->vs.row, data->vs.col, data->vs.str, draw->transformFeedbackBuffers);
}
else
{
data->ff = ff;
- draw->vsDirtyConstF = 256 + 1;
+ draw->vsDirtyConstF = VERTEX_UNIFORM_VECTORS + 1;
draw->vsDirtyConstI = 16;
draw->vsDirtyConstB = 16;
+
+ for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++)
+ {
+ draw->vUniformBuffers[i] = nullptr;
+ }
+
+ for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; i++)
+ {
+ draw->transformFeedbackBuffers[i] = nullptr;
+ }
}
if(pixelState.stencilActive)
data->Wx16 = replicate(W * 16);
data->Hx16 = replicate(H * 16);
- data->X0x16 = replicate(X0 * 16);
- data->Y0x16 = replicate(Y0 * 16);
+ data->X0x16 = replicate(X0 * 16 - 8);
+ data->Y0x16 = replicate(Y0 * 16 - 8);
data->XXXX = replicate(X[s][q] / W);
data->YYYY = replicate(Y[s][q] / H);
data->halfPixelX = replicate(0.5f / W);
// Target
{
- for(int index = 0; index < 4; index++)
+ for(int index = 0; index < RENDERTARGETS; index++)
{
draw->renderTarget[index] = context->renderTarget[index];
}
}
- draw->depthStencil = context->depthStencil;
+ draw->depthBuffer = context->depthBuffer;
+ draw->stencilBuffer = context->stencilBuffer;
- if(draw->depthStencil)
+ if(draw->depthBuffer)
{
- data->depthBuffer = (float*)context->depthStencil->lockInternal(0, 0, q * ms, LOCK_READWRITE, MANAGED);
- data->depthPitchB = context->depthStencil->getInternalPitchB();
- data->depthSliceB = context->depthStencil->getInternalSliceB();
+ data->depthBuffer = (float*)context->depthBuffer->lockInternal(0, 0, q * ms, LOCK_READWRITE, MANAGED);
+ data->depthPitchB = context->depthBuffer->getInternalPitchB();
+ data->depthSliceB = context->depthBuffer->getInternalSliceB();
+ }
- data->stencilBuffer = (unsigned char*)context->depthStencil->lockStencil(q * ms, MANAGED);
- data->stencilPitchB = context->depthStencil->getStencilPitchB();
- data->stencilSliceB = context->depthStencil->getStencilSliceB();
+ if(draw->stencilBuffer)
+ {
+ data->stencilBuffer = (unsigned char*)context->stencilBuffer->lockStencil(0, 0, q * ms, MANAGED);
+ data->stencilPitchB = context->stencilBuffer->getStencilPitchB();
+ data->stencilSliceB = context->stencilBuffer->getStencilSliceB();
}
}
nextDraw++;
schedulerMutex.unlock();
- if(!threadsAwake)
+ #ifndef NDEBUG
+ if(threadCount == 1) // Use main thread for draw execution
{
- suspend[0]->wait();
-
threadsAwake = 1;
task[0].type = Task::RESUME;
- resume[0]->signal();
+ taskLoop(0);
+ }
+ else
+ #endif
+ {
+ if(!threadsAwake)
+ {
+ suspend[0]->wait();
+
+ threadsAwake = 1;
+ task[0].type = Task::RESUME;
+
+ resume[0]->signal();
+ }
}
}
}
+ 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;
}
}
}
-
+
// Find primitive tasks
if(currentDraw == nextDraw)
{
case Task::PRIMITIVES:
{
int unit = task[threadIndex].primitiveUnit;
-
+
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);
startTick = time;
#endif
- int visible = setupPrimitives(this, unit, count);
+ int visible = 0;
+
+ if(!draw->setupState.rasterizerDiscard)
+ {
+ visible = (this->*setupPrimitives)(unit, count);
+ }
primitiveProgress[unit].visible = visible;
primitiveProgress[unit].references = clusterCount;
DrawData &data = *draw.data;
int primitive = primitiveProgress[unit].firstPrimitive;
int count = primitiveProgress[unit].primitiveCount;
+ int processedPrimitives = primitive + count;
- pixelProgress[cluster].processedPrimitives = primitive + count;
+ pixelProgress[cluster].processedPrimitives = processedPrimitives;
if(pixelProgress[cluster].processedPrimitives >= draw.count)
{
{
Query *query = *q;
- for(int cluster = 0; cluster < clusterCount; cluster++)
+ switch(query->type)
{
- atomicAdd((volatile int*)&query->data, data.occlusion[cluster]);
+ case Query::FRAGMENTS_PASSED:
+ for(int cluster = 0; cluster < clusterCount; cluster++)
+ {
+ atomicAdd((volatile int*)&query->data, data.occlusion[cluster]);
+ }
+ break;
+ case Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+ atomicAdd((volatile int*)&query->data, processedPrimitives);
+ break;
+ default:
+ break;
}
atomicDecrement(&query->reference);
draw.queries = 0;
}
- for(int i = 0; i < 4; i++)
+ for(int i = 0; i < RENDERTARGETS; i++)
{
if(draw.renderTarget[i])
{
}
}
- if(draw.depthStencil)
+ if(draw.depthBuffer)
+ {
+ draw.depthBuffer->unlockInternal();
+ }
+
+ if(draw.stencilBuffer)
{
- draw.depthStencil->unlockInternal();
- draw.depthStencil->unlockStencil();
+ draw.stencilBuffer->unlockStencil();
}
for(int i = 0; i < TOTAL_IMAGE_UNITS; i++)
}
}
- for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
+ for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
{
if(draw.vertexStream[i])
{
draw.indexBuffer->unlock();
}
+ for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++)
+ {
+ if(draw.pUniformBuffers[i])
+ {
+ draw.pUniformBuffers[i]->unlock();
+ }
+ if(draw.vUniformBuffers[i])
+ {
+ draw.vUniformBuffers[i]->unlock();
+ }
+ }
+
+ for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; i++)
+ {
+ if(draw.transformFeedbackBuffers[i])
+ {
+ draw.transformFeedbackBuffers[i]->unlock();
+ }
+ }
+
draw.vertexRoutine->unbind();
draw.setupRoutine->unbind();
draw.pixelRoutine->unbind();
}
}
break;
- case DRAW_QUADLIST:
+ case DRAW_QUADLIST:
{
unsigned int index = 4 * start / 2;
batch[i+0][1] = index + 1;
batch[i+0][2] = index + 2;
- batch[i+1][0] = index + 0;
+ batch[i+1][0] = index + 0;
batch[i+1][1] = index + 2;
batch[i+1][2] = index + 3;
break;
default:
ASSERT(false);
+ return;
}
+ task->primitiveStart = start;
task->vertexCount = triangleCount * 3;
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;
if(clipFlagsOr != Clipper::CLIP_FINITE)
{
- if(!renderer->clipper->clip(polygon, clipFlagsOr, draw))
+ if(!clipper->clip(polygon, clipFlagsOr, draw))
{
continue;
}
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;
for(int i = 0; i < 3; i++)
{
- if(setupLine(renderer, *primitive, *triangle, draw))
+ if(setupLine(*primitive, *triangle, draw))
{
primitive->area = 0.5f * d;
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;
for(int i = 0; i < 3; i++)
{
- if(setupPoint(renderer, *primitive, *triangle, draw))
+ if(setupPoint(*primitive, *triangle, draw))
{
primitive->area = 0.5f * d;
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++;
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++;
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;
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)
{
if(clipFlagsOr != Clipper::CLIP_FINITE)
{
- if(!renderer->clipper->clip(polygon, clipFlagsOr, draw))
+ if(!clipper->clip(polygon, clipFlagsOr, draw))
{
return false;
}
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)
{
if(clipFlagsOr != Clipper::CLIP_FINITE)
{
- if(!renderer->clipper->clip(polygon, clipFlagsOr, draw))
+ if(!clipper->clip(polygon, clipFlagsOr, draw))
{
return false;
}
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;
int pts = state.pointSizeRegister;
- if(state.pointSizeRegister != 0xF)
+ if(state.pointSizeRegister != Unused)
{
pSize = v.v[pts].y;
}
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;
if(clipFlagsOr != Clipper::CLIP_FINITE)
{
- if(!renderer->clipper->clip(polygon, clipFlagsOr, draw))
+ if(!clipper->clip(polygon, clipFlagsOr, draw))
{
return false;
}
}
-
+
return setupRoutine(&primitive, &triangle, &polygon, &data);
}
return false;
}
- unsigned int Renderer::computeClipFlags(const float4 &v, const DrawData &data)
- {
- float clX = v.x + data.halfPixelX[0] * v.w;
- float clY = v.y + data.halfPixelY[0] * v.w;
-
- return ((clX > v.w) << 0) |
- ((clY > v.w) << 1) |
- ((v.z > v.w) << 2) |
- ((clX < -v.w) << 3) |
- ((clY < -v.w) << 4) |
- ((v.z < 0) << 5) |
- Clipper::CLIP_FINITE; // FIXME: xyz finite
- }
-
void Renderer::initializeThreads()
{
unitCount = ceilPow2(threadCount);
exitThreads = true;
resume[thread]->signal();
worker[thread]->join();
-
+
delete worker[thread];
worker[thread] = 0;
delete resume[thread];
delete suspend[thread];
suspend[thread] = 0;
}
-
+
deallocate(vertexTask[thread]);
vertexTask[thread] = 0;
}
bool Renderer::isReadWriteTexture(int sampler)
{
- for(int index = 0; index < 4; index++)
+ for(int index = 0; index < RENDERTARGETS; index++)
{
if(context->renderTarget[index] && context->texture[sampler] == context->renderTarget[index]->getResource())
{
return true;
}
}
-
- if(context->depthStencil && context->texture[sampler] == context->depthStencil->getResource())
+
+ if(context->depthBuffer && context->texture[sampler] == context->depthBuffer->getResource())
{
return true;
}
return false;
}
-
+
void Renderer::updateClipper()
{
if(updateClipPlanes)
void Renderer::setTextureLevel(unsigned int sampler, unsigned int face, unsigned int level, Surface *surface, TextureType type)
{
ASSERT(sampler < TOTAL_IMAGE_UNITS && face < 6 && level < MIPMAP_LEVELS);
-
+
context->sampler[sampler].setTextureLevel(face, level, surface, type);
}
}
}
+ void Renderer::setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR)
+ {
+ if(type == SAMPLER_PIXEL)
+ {
+ PixelProcessor::setSwizzleR(sampler, swizzleR);
+ }
+ else
+ {
+ VertexProcessor::setSwizzleR(sampler, swizzleR);
+ }
+ }
+
+ void Renderer::setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG)
+ {
+ if(type == SAMPLER_PIXEL)
+ {
+ PixelProcessor::setSwizzleG(sampler, swizzleG);
+ }
+ else
+ {
+ VertexProcessor::setSwizzleG(sampler, swizzleG);
+ }
+ }
+
+ void Renderer::setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB)
+ {
+ if(type == SAMPLER_PIXEL)
+ {
+ PixelProcessor::setSwizzleB(sampler, swizzleB);
+ }
+ else
+ {
+ VertexProcessor::setSwizzleB(sampler, swizzleB);
+ }
+ }
+
+ void Renderer::setSwizzleA(SamplerType type, int sampler, SwizzleType swizzleA)
+ {
+ if(type == SAMPLER_PIXEL)
+ {
+ PixelProcessor::setSwizzleA(sampler, swizzleA);
+ }
+ else
+ {
+ VertexProcessor::setSwizzleA(sampler, swizzleA);
+ }
+ }
+
+ 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);
slopeDepthBias = slopeBias;
}
+ void Renderer::setRasterizerDiscard(bool rasterizerDiscard)
+ {
+ context->rasterizerDiscard = rasterizerDiscard;
+ }
+
void Renderer::setPixelShader(const PixelShader *shader)
{
context->pixelShader = shader;
{
queries.push_back(query);
}
-
+
void Renderer::removeQuery(Query *query)
{
queries.remove(query);
{
return threadCount;
}
-
+
int64_t Renderer::getVertexTime(int thread)
{
return vertexTime[thread];
{
return setupTime[thread];
}
-
+
int64_t Renderer::getPixelTime(int thread)
{
return pixelTime[thread];
void Renderer::setClipPlane(unsigned int index, const float plane[4])
{
- if(index < 6)
+ if(index < MAX_CLIP_PLANES)
{
userPlane[index] = plane;
}
{
terminateThreads();
- SwiftConfig::Configuration configuration = {0};
+ SwiftConfig::Configuration configuration = {};
swiftConfig->getConfiguration(configuration);
precacheVertex = !newConfiguration && configuration.precache;