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/12568 Reviewed-by: Nicolas Capens <nicolascapens@google.com> Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp index 1027ee0..43ae3d9 100644 --- a/src/Renderer/Renderer.cpp +++ b/src/Renderer/Renderer.cpp
@@ -290,7 +290,7 @@ if(drawCall[i]->references == -1) { draw = drawCall[i]; - drawList[nextDraw % DRAW_COUNT] = draw; + drawList[nextDraw & DRAW_COUNT_BITS] = draw; break; } @@ -750,7 +750,7 @@ pixelProgress[cluster].executing = true; // Commit to the task queue - qHead = (qHead + 1) % 32; + qHead = (qHead + 1) & TASK_COUNT_BITS; qSize++; break; @@ -769,7 +769,7 @@ 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 count = draw->count; @@ -783,7 +783,7 @@ 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 @@ -805,7 +805,7 @@ primitiveProgress[unit].references = -1; // Commit to the task queue - qHead = (qHead + 1) % 32; + qHead = (qHead + 1) & TASK_COUNT_BITS; qSize++; } } @@ -824,7 +824,7 @@ if(qSize != 0) { - task[threadIndex] = taskQueue[(qHead - qSize) % 32]; + task[threadIndex] = taskQueue[(qHead - qSize) & TASK_COUNT_BITS]; qSize--; if(curThreadsAwake != threadCount) @@ -869,7 +869,7 @@ int input = primitiveProgress[unit].firstPrimitive; 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; processPrimitiveVertices(unit, input, count, draw->count, threadIndex); @@ -904,7 +904,7 @@ { int cluster = task[threadIndex].pixelCluster; 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; PixelProcessor::RoutinePointer pixelRoutine = draw->pixelPointer; @@ -938,7 +938,7 @@ int unit = pixelTask.primitiveUnit; 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; int primitive = primitiveProgress[unit].firstPrimitive; int count = primitiveProgress[unit].primitiveCount; @@ -1075,7 +1075,7 @@ { Triangle *triangle = triangleBatch[unit]; int primitiveDrawCall = primitiveProgress[unit].drawCall; - DrawCall *draw = drawList[primitiveDrawCall % DRAW_COUNT]; + DrawCall *draw = drawList[primitiveDrawCall & DRAW_COUNT_BITS]; DrawData *data = draw->data; VertexTask *task = vertexTask[thread]; @@ -1505,7 +1505,7 @@ Triangle *triangle = triangleBatch[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; const SetupProcessor::RoutinePointer &setupRoutine = draw.setupPointer; @@ -1551,7 +1551,7 @@ Primitive *primitive = primitiveBatch[unit]; 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; const Vertex &v0 = triangle[0].v0; @@ -1608,7 +1608,7 @@ Primitive *primitive = primitiveBatch[unit]; 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; const Vertex &v0 = triangle[0].v0; @@ -1652,7 +1652,7 @@ Primitive *primitive = primitiveBatch[unit]; 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; int ms = state.multiSample; @@ -1677,7 +1677,7 @@ Primitive *primitive = primitiveBatch[unit]; 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; int ms = state.multiSample;
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp index 173706d..d455754 100644 --- a/src/Renderer/Renderer.hpp +++ b/src/Renderer/Renderer.hpp
@@ -460,14 +460,21 @@ PixelProgress pixelProgress[16]; 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 *drawList[DRAW_COUNT]; AtomicInt currentDraw; 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 qSize;