Commit 29364a05 by Sean Risser

Fix buffer overflow on Mac

For OpenGL on Mac, Swiftshader renders directly to the IOSurface given to us by the OS. This surface is not necessarily vertically padded so its height is a multiple of 2. Since we render 4 pixels at a time in a quad, the bottom 2 pixels may not be written to legal memory if the height of the target surface is an odd number. This change prevents Swiftshader from rendering quads on Mac if doing so would overflow the buffer. Bug: chromium:944796 Bug: angleproject:2764 Change-Id: I08bec895980b42f99b8a4434969edcaf7d331284 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/32030 Presubmit-Ready: Sean Risser <srisser@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarSean Risser <srisser@google.com>
parent 9555830f
......@@ -53,8 +53,8 @@ namespace sw
Do
{
Int yMin = *Pointer<Int>(primitive + OFFSET(Primitive,yMin));
Int yMax = *Pointer<Int>(primitive + OFFSET(Primitive,yMax));
yMin = *Pointer<Int>(primitive + OFFSET(Primitive,yMin));
yMax = *Pointer<Int>(primitive + OFFSET(Primitive,yMax));
Int cluster2 = cluster + cluster;
yMin += clusterCount * 2 - 2 - cluster2;
......@@ -63,7 +63,7 @@ namespace sw
If(yMin < yMax)
{
rasterize(yMin, yMax);
rasterize();
}
primitive += sizeof(Primitive) * state.multiSample;
......@@ -90,7 +90,7 @@ namespace sw
Return();
}
void QuadRasterizer::rasterize(Int &yMin, Int &yMax)
void QuadRasterizer::rasterize()
{
Pointer<Byte> cBuffer[RENDERTARGETS];
Pointer<Byte> zBuffer;
......@@ -114,7 +114,7 @@ namespace sw
sBuffer = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,stencilBuffer)) + yMin * *Pointer<Int>(data + OFFSET(DrawData,stencilPitchB));
}
Int y = yMin;
y = yMin;
Do
{
......@@ -287,7 +287,7 @@ namespace sw
cMask[q] = SignMask(PackSigned(mask, mask)) & 0x0000000F;
}
quad(cBuffer, zBuffer, sBuffer, cMask, x, y);
quad(cBuffer, zBuffer, sBuffer, cMask, x);
}
}
......
......@@ -40,11 +40,15 @@ namespace sw
UInt occlusion;
Int y;
Int yMin;
Int yMax;
#if PERF_PROFILE
Long cycles[PERF_TIMERS];
#endif
virtual void quad(Pointer<Byte> cBuffer[4], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y) = 0;
virtual void quad(Pointer<Byte> cBuffer[4], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x) = 0;
bool interpolateZ() const;
bool interpolateW() const;
......@@ -54,7 +58,7 @@ namespace sw
const PixelShader *const shader;
private:
void rasterize(Int &yMin, Int &yMax);
void rasterize();
};
}
......
......@@ -48,7 +48,7 @@ namespace sw
{
}
void PixelRoutine::quad(Pointer<Byte> cBuffer[RENDERTARGETS], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y)
void PixelRoutine::quad(Pointer<Byte> cBuffer[RENDERTARGETS], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x)
{
#if PERF_PROFILE
Long pipeTime = Ticks();
......@@ -1684,10 +1684,17 @@ namespace sw
c23 |= masked;
}
c23 &= *Pointer<Short4>(constants + OFFSET(Constants,maskD23Q) + xMask * 8);
value &= *Pointer<Short4>(constants + OFFSET(Constants,invMaskD23Q) + xMask * 8);
c23 |= value;
*Pointer<Short4>(buffer) = c23;
#ifdef __APPLE__
// On Mac we render directly to an IOSurface that isn't vertically padded. So we
// only render the bottom half of quads when it won't overflow the buffer.
If ((y + 1) < yMax)
#endif
{
c23 &= *Pointer<Short4>(constants + OFFSET(Constants,maskD23Q) + xMask * 8);
value &= *Pointer<Short4>(constants + OFFSET(Constants,invMaskD23Q) + xMask * 8);
c23 |= value;
*Pointer<Short4>(buffer) = c23;
}
}
break;
case FORMAT_A8B8G8R8:
......
......@@ -47,7 +47,7 @@ namespace sw
virtual Bool alphaTest(Int cMask[4]) = 0;
virtual void rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]) = 0;
virtual void quad(Pointer<Byte> cBuffer[4], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y);
virtual void quad(Pointer<Byte> cBuffer[4], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x);
void alphaTest(Int &aMask, Short4 &alpha);
void alphaToCoverage(Int cMask[4], Float4 &alpha);
......
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