Skip to content

Commit

Permalink
chore: cherry-pick ed5f62c36d from angle. (#28874)
Browse files Browse the repository at this point in the history
* chore: cherry-pick ed5f62c36d from angle.

* update patches

Co-authored-by: Electron Bot <electron@github.com>
  • Loading branch information
ppontes and electron-bot committed Apr 28, 2021
1 parent 882eb8a commit 72f3c5e
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 0 deletions.
1 change: 1 addition & 0 deletions patches/angle/.patches
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
cherry-pick-2882e1afd982.patch
d3d11_skip_blits_if_there_is_no_intersection_of_dest_areas.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Mon, 19 Apr 2021 12:47:05 -0400
Subject: D3D11: Skip blits if there is no intersection of dest areas

Blit11 would clip the destination rectangle with the destination size
but ignore the result. gl::ClipRectangle returns false when the
rectangles do not intersect at all, indicating the blit can be skipped.

This could lead to an out-of-bounds write to the GPU memory for the
destination texture.

Mark ClipRectangle as nodiscard to prevent future issues.

Bug: chromium:1199402
Change-Id: I260e82d0917b8aa7e7887f2c9f7ed4b1a03ba785
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2836786
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
(cherry picked from commit b574643ef28c92fcea5122dd7a72acb42a514eed)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2846982
Reviewed-by: Geoff Lang <geofflang@chromium.org>

diff --git a/src/libANGLE/angletypes.h b/src/libANGLE/angletypes.h
index e9e955b58f053a4a895c3c3fa105aac9db3c8baf..37740dda4be1aa59b57529841e0f13ee8a349af6 100644
--- a/src/libANGLE/angletypes.h
+++ b/src/libANGLE/angletypes.h
@@ -62,7 +62,7 @@ struct Rectangle
bool operator==(const Rectangle &a, const Rectangle &b);
bool operator!=(const Rectangle &a, const Rectangle &b);

-bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection);
+ANGLE_NO_DISCARD bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection);

struct Offset
{
diff --git a/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp b/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
index 55f8f8f4d38f30990d7061de6ebaa0595f0447da..6d9365af8db5fa9835127650162d5aeb6ce46b77 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
@@ -141,7 +141,10 @@ void StretchedBlitNearest(const gl::Box &sourceArea,
uint8_t *destData)
{
gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height);
- gl::ClipRectangle(clippedDestArea, clipRect, &clippedDestArea);
+ if (!gl::ClipRectangle(clippedDestArea, clipRect, &clippedDestArea))
+ {
+ return;
+ }

// Determine if entire rows can be copied at once instead of each individual pixel. There
// must be no out of bounds lookups, whole rows copies, and no scale.
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.cpp b/src/libANGLE/renderer/gl/FramebufferGL.cpp
index 2dd83c1f2d7c4be71bcc16a3c5d6f7f209a5b6b1..d709449547af9021ccf4ef2476e217af2f1517e5 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.cpp
+++ b/src/libANGLE/renderer/gl/FramebufferGL.cpp
@@ -1115,7 +1115,10 @@ angle::Result FramebufferGL::clipSrcRegion(const gl::Context *context,
// If pixels lying outside the read framebuffer, adjust src region
// and dst region to appropriate in-bounds regions respectively.
gl::Rectangle realSourceRegion;
- ClipRectangle(bounds.sourceRegion, bounds.sourceBounds, &realSourceRegion);
+ if (!ClipRectangle(bounds.sourceRegion, bounds.sourceBounds, &realSourceRegion))
+ {
+ return angle::Result::Stop;
+ }
GLuint xOffset = realSourceRegion.x - bounds.sourceRegion.x;
GLuint yOffset = realSourceRegion.y - bounds.sourceRegion.y;

diff --git a/src/libANGLE/renderer/metal/ContextMtl.mm b/src/libANGLE/renderer/metal/ContextMtl.mm
index d8d421f925675113a7d95250572e692fecb986ef..4bda9cf8518f24b8628ec4576e19ee7499131f10 100644
--- a/src/libANGLE/renderer/metal/ContextMtl.mm
+++ b/src/libANGLE/renderer/metal/ContextMtl.mm
@@ -1282,7 +1282,10 @@ void ContextMtl::updateScissor(const gl::State &glState)

// Clip the render area to the viewport.
gl::Rectangle viewportClippedRenderArea;
- gl::ClipRectangle(renderArea, glState.getViewport(), &viewportClippedRenderArea);
+ if (!gl::ClipRectangle(renderArea, glState.getViewport(), &viewportClippedRenderArea))
+ {
+ viewportClippedRenderArea = gl::Rectangle();
+ }

gl::Rectangle scissoredArea = ClipRectToScissor(getState(), viewportClippedRenderArea, false);
if (framebufferMtl->flipY())
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 0276a4a8b579d36f239cd86527a6f8e08291d058..6092575364db4896caaf755eeaf93fb1d2fad9c4 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -2533,8 +2533,11 @@ angle::Result ContextVk::updateScissor(const gl::State &glState)

// Clip the render area to the viewport.
gl::Rectangle viewportClippedRenderArea;
- gl::ClipRectangle(renderArea, getCorrectedViewport(glState.getViewport()),
- &viewportClippedRenderArea);
+ if (!gl::ClipRectangle(renderArea, getCorrectedViewport(glState.getViewport()),
+ &viewportClippedRenderArea))
+ {
+ viewportClippedRenderArea = gl::Rectangle();
+ }

gl::Rectangle scissoredArea = ClipRectToScissor(getState(), viewportClippedRenderArea, false);
gl::Rectangle rotatedScissoredArea;
diff --git a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
index 79ba46aa10ae8c689b1546b3e1e99ce815f414bd..b38bebb31f17d9f1d127e170495fd810aba21390 100644
--- a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
+++ b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
@@ -1997,6 +1997,30 @@ TEST_P(BlitFramebufferTest, BlitFramebufferSizeOverflow2)
EXPECT_GL_ERROR(GL_INVALID_VALUE);
}

+// Test an edge case in D3D11 stencil blitting on the CPU that does not properly clip the
+// destination regions
+TEST_P(BlitFramebufferTest, BlitFramebufferStencilClipNoIntersection)
+{
+ GLFramebuffer framebuffers[2];
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);
+
+ GLRenderbuffer renderbuffers[2];
+ glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[0]);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 4, 4);
+ glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
+ renderbuffers[0]);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[1]);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 4, 4);
+ glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
+ renderbuffers[1]);
+
+ glBlitFramebuffer(0, 0, 4, 4, 1 << 24, 1 << 24, 1 << 25, 1 << 25, GL_STENCIL_BUFFER_BIT,
+ GL_NEAREST);
+ EXPECT_GL_NO_ERROR();
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST(BlitFramebufferANGLETest,

0 comments on commit 72f3c5e

Please sign in to comment.