Commit bc6ce4f1 by Alexis Hetu Committed by Alexis Hétu

Fixed crash in Renderer

The problem was at line 827, where "(qHead - qSize) % 32" could give unexpected results if qSize > gHead (which wasn't a problem with unsigned values). Also removed other % operations which could have cause some issues. Change-Id: Ia443e05ce1add3879720e90f7dbac771e712d2ab Reviewed-on: https://swiftshader-review.googlesource.com/12568Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 8beb2402
...@@ -290,7 +290,7 @@ namespace sw ...@@ -290,7 +290,7 @@ namespace sw
if(drawCall[i]->references == -1) if(drawCall[i]->references == -1)
{ {
draw = drawCall[i]; draw = drawCall[i];
drawList[nextDraw % DRAW_COUNT] = draw; drawList[nextDraw & DRAW_COUNT_BITS] = draw;
break; break;
} }
...@@ -750,7 +750,7 @@ namespace sw ...@@ -750,7 +750,7 @@ namespace sw
pixelProgress[cluster].executing = true; pixelProgress[cluster].executing = true;
// Commit to the task queue // Commit to the task queue
qHead = (qHead + 1) % 32; qHead = (qHead + 1) & TASK_COUNT_BITS;
qSize++; qSize++;
break; break;
...@@ -769,7 +769,7 @@ namespace sw ...@@ -769,7 +769,7 @@ namespace sw
for(int unit = 0; unit < unitCount; unit++) for(int unit = 0; unit < unitCount; unit++)
{ {
DrawCall *draw = drawList[currentDraw % DRAW_COUNT]; DrawCall *draw = drawList[currentDraw & DRAW_COUNT_BITS];
int primitive = draw->primitive; int primitive = draw->primitive;
int count = draw->count; int count = draw->count;
...@@ -783,7 +783,7 @@ namespace sw ...@@ -783,7 +783,7 @@ namespace sw
return; // No more primitives to process return; // No more primitives to process
} }
draw = drawList[currentDraw % DRAW_COUNT]; draw = drawList[currentDraw & DRAW_COUNT_BITS];
} }
if(!primitiveProgress[unit].references) // Task not already being executed and not still in use by a pixel unit if(!primitiveProgress[unit].references) // Task not already being executed and not still in use by a pixel unit
...@@ -805,7 +805,7 @@ namespace sw ...@@ -805,7 +805,7 @@ namespace sw
primitiveProgress[unit].references = -1; primitiveProgress[unit].references = -1;
// Commit to the task queue // Commit to the task queue
qHead = (qHead + 1) % 32; qHead = (qHead + 1) & TASK_COUNT_BITS;
qSize++; qSize++;
} }
} }
...@@ -824,7 +824,7 @@ namespace sw ...@@ -824,7 +824,7 @@ namespace sw
if(qSize != 0) if(qSize != 0)
{ {
task[threadIndex] = taskQueue[(qHead - qSize) % 32]; task[threadIndex] = taskQueue[(qHead - qSize) & TASK_COUNT_BITS];
qSize--; qSize--;
if(curThreadsAwake != threadCount) if(curThreadsAwake != threadCount)
...@@ -869,7 +869,7 @@ namespace sw ...@@ -869,7 +869,7 @@ namespace sw
int input = primitiveProgress[unit].firstPrimitive; int input = primitiveProgress[unit].firstPrimitive;
int count = primitiveProgress[unit].primitiveCount; int count = primitiveProgress[unit].primitiveCount;
DrawCall *draw = drawList[primitiveProgress[unit].drawCall % DRAW_COUNT]; DrawCall *draw = drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
int (Renderer::*setupPrimitives)(int batch, int count) = draw->setupPrimitives; int (Renderer::*setupPrimitives)(int batch, int count) = draw->setupPrimitives;
processPrimitiveVertices(unit, input, count, draw->count, threadIndex); processPrimitiveVertices(unit, input, count, draw->count, threadIndex);
...@@ -904,7 +904,7 @@ namespace sw ...@@ -904,7 +904,7 @@ namespace sw
{ {
int cluster = task[threadIndex].pixelCluster; int cluster = task[threadIndex].pixelCluster;
Primitive *primitive = primitiveBatch[unit]; Primitive *primitive = primitiveBatch[unit];
DrawCall *draw = drawList[pixelProgress[cluster].drawCall % DRAW_COUNT]; DrawCall *draw = drawList[pixelProgress[cluster].drawCall & DRAW_COUNT_BITS];
DrawData *data = draw->data; DrawData *data = draw->data;
PixelProcessor::RoutinePointer pixelRoutine = draw->pixelPointer; PixelProcessor::RoutinePointer pixelRoutine = draw->pixelPointer;
...@@ -938,7 +938,7 @@ namespace sw ...@@ -938,7 +938,7 @@ namespace sw
int unit = pixelTask.primitiveUnit; int unit = pixelTask.primitiveUnit;
int cluster = pixelTask.pixelCluster; int cluster = pixelTask.pixelCluster;
DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT]; DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
DrawData &data = *draw.data; DrawData &data = *draw.data;
int primitive = primitiveProgress[unit].firstPrimitive; int primitive = primitiveProgress[unit].firstPrimitive;
int count = primitiveProgress[unit].primitiveCount; int count = primitiveProgress[unit].primitiveCount;
...@@ -1075,7 +1075,7 @@ namespace sw ...@@ -1075,7 +1075,7 @@ namespace sw
{ {
Triangle *triangle = triangleBatch[unit]; Triangle *triangle = triangleBatch[unit];
int primitiveDrawCall = primitiveProgress[unit].drawCall; int primitiveDrawCall = primitiveProgress[unit].drawCall;
DrawCall *draw = drawList[primitiveDrawCall % DRAW_COUNT]; DrawCall *draw = drawList[primitiveDrawCall & DRAW_COUNT_BITS];
DrawData *data = draw->data; DrawData *data = draw->data;
VertexTask *task = vertexTask[thread]; VertexTask *task = vertexTask[thread];
...@@ -1505,7 +1505,7 @@ namespace sw ...@@ -1505,7 +1505,7 @@ namespace sw
Triangle *triangle = triangleBatch[unit]; Triangle *triangle = triangleBatch[unit];
Primitive *primitive = primitiveBatch[unit]; Primitive *primitive = primitiveBatch[unit];
DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT]; DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
SetupProcessor::State &state = draw.setupState; SetupProcessor::State &state = draw.setupState;
const SetupProcessor::RoutinePointer &setupRoutine = draw.setupPointer; const SetupProcessor::RoutinePointer &setupRoutine = draw.setupPointer;
...@@ -1551,7 +1551,7 @@ namespace sw ...@@ -1551,7 +1551,7 @@ namespace sw
Primitive *primitive = primitiveBatch[unit]; Primitive *primitive = primitiveBatch[unit];
int visible = 0; int visible = 0;
DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT]; DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
SetupProcessor::State &state = draw.setupState; SetupProcessor::State &state = draw.setupState;
const Vertex &v0 = triangle[0].v0; const Vertex &v0 = triangle[0].v0;
...@@ -1608,7 +1608,7 @@ namespace sw ...@@ -1608,7 +1608,7 @@ namespace sw
Primitive *primitive = primitiveBatch[unit]; Primitive *primitive = primitiveBatch[unit];
int visible = 0; int visible = 0;
DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT]; DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
SetupProcessor::State &state = draw.setupState; SetupProcessor::State &state = draw.setupState;
const Vertex &v0 = triangle[0].v0; const Vertex &v0 = triangle[0].v0;
...@@ -1652,7 +1652,7 @@ namespace sw ...@@ -1652,7 +1652,7 @@ namespace sw
Primitive *primitive = primitiveBatch[unit]; Primitive *primitive = primitiveBatch[unit];
int visible = 0; int visible = 0;
DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT]; DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
SetupProcessor::State &state = draw.setupState; SetupProcessor::State &state = draw.setupState;
int ms = state.multiSample; int ms = state.multiSample;
...@@ -1677,7 +1677,7 @@ namespace sw ...@@ -1677,7 +1677,7 @@ namespace sw
Primitive *primitive = primitiveBatch[unit]; Primitive *primitive = primitiveBatch[unit];
int visible = 0; int visible = 0;
DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT]; DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
SetupProcessor::State &state = draw.setupState; SetupProcessor::State &state = draw.setupState;
int ms = state.multiSample; int ms = state.multiSample;
......
...@@ -460,14 +460,21 @@ namespace sw ...@@ -460,14 +460,21 @@ namespace sw
PixelProgress pixelProgress[16]; PixelProgress pixelProgress[16];
Task task[16]; // Current tasks for threads Task task[16]; // Current tasks for threads
enum {DRAW_COUNT = 16}; // Number of draw calls buffered enum {
DRAW_COUNT = 16, // Number of draw calls buffered (must be power of 2)
DRAW_COUNT_BITS = DRAW_COUNT - 1,
};
DrawCall *drawCall[DRAW_COUNT]; DrawCall *drawCall[DRAW_COUNT];
DrawCall *drawList[DRAW_COUNT]; DrawCall *drawList[DRAW_COUNT];
AtomicInt currentDraw; AtomicInt currentDraw;
AtomicInt nextDraw; AtomicInt nextDraw;
Task taskQueue[32]; enum {
TASK_COUNT = 32, // Size of the task queue (must be power of 2)
TASK_COUNT_BITS = TASK_COUNT - 1,
};
Task taskQueue[TASK_COUNT];
AtomicInt qHead; AtomicInt qHead;
AtomicInt qSize; AtomicInt qSize;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment