Files
electron/patches/angle/cherry-pick-95a32cb37edb.patch
Keeley Hammond b0ba443ff3 chore: cherry-pick 95a32cb37edb from angle (#49201)
* build: add angle patch dir

* chore: cherry-pick 95a32cb37edb from angle

* chore: update patches
2025-12-12 06:12:18 -08:00

91 lines
4.1 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Fri, 5 Dec 2025 18:31:06 -0500
Subject: Metal: Don't use pixelsDepthPitch to size buffers.
pixelsDepthPitch is based on GL_UNPACK_IMAGE_HEIGHT which can be smaller
than the image height.
Bug: chromium:466192044
Change-Id: Idb07fb861a74e36576c0fed4a31e04fe58d1bd1d
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/7232774
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Commit-Queue: Kenneth Russell <kbr@chromium.org>
diff --git a/src/libANGLE/renderer/metal/TextureMtl.mm b/src/libANGLE/renderer/metal/TextureMtl.mm
index 5a1fc9091c3af273c0bb4764fb98c09aadce9e58..9301862a49a4cd42db567aa427cfb631d668fe88 100644
--- a/src/libANGLE/renderer/metal/TextureMtl.mm
+++ b/src/libANGLE/renderer/metal/TextureMtl.mm
@@ -2347,9 +2347,9 @@ uint32_t height(GLuint glLevel) const
{
// Current command buffer implementation does not support 64-bit offsets.
ANGLE_CHECK_GL_MATH(contextMtl, offset <= std::numeric_limits<uint32_t>::max());
+ size_t imageSize = pixelsRowPitch * mtlArea.size.height;
mtl::BufferRef stagingBuffer;
- ANGLE_TRY(
- mtl::Buffer::MakeBuffer(contextMtl, pixelsDepthPitch, nullptr, &stagingBuffer));
+ ANGLE_TRY(mtl::Buffer::MakeBuffer(contextMtl, imageSize, nullptr, &stagingBuffer));
ASSERT(pixelsAngleFormat.pixelBytes == 4 && offset % 4 == 0);
ANGLE_TRY(SaturateDepth(contextMtl, sourceBuffer, stagingBuffer,
@@ -2360,11 +2360,13 @@ uint32_t height(GLuint glLevel) const
offset = 0;
}
+ size_t srcBytesPerImage = mtlArea.size.depth > 1 ? pixelsDepthPitch : 0;
+
// Use blit encoder to copy
mtl::BlitCommandEncoder *blitEncoder = GetBlitCommandEncoderForResources(
contextMtl, {sourceBuffer.get(), imageDef.image.get()});
CopyBufferToOriginalTextureIfDstIsAView(
- contextMtl, blitEncoder, sourceBuffer, offset, pixelsRowPitch, pixelsDepthPitch,
+ contextMtl, blitEncoder, sourceBuffer, offset, pixelsRowPitch, srcBytesPerImage,
mtlArea.size, imageDef.image, slice, mtl::kZeroNativeMipLevel, mtlArea.origin,
imageFormat.isPVRTC() ? MTLBlitOptionRowLinearPVRTC : MTLBlitOptionNone);
}
diff --git a/src/tests/gl_tests/PackUnpackTest.cpp b/src/tests/gl_tests/PackUnpackTest.cpp
index e0664e75414ca117a48c4f0ba528d558f8ae3643..b34816ba724f1db718ea6a96512915259e063e72 100644
--- a/src/tests/gl_tests/PackUnpackTest.cpp
+++ b/src/tests/gl_tests/PackUnpackTest.cpp
@@ -8,6 +8,7 @@
//
#include "test_utils/ANGLETest.h"
+#include "test_utils/gl_raii.h"
using namespace angle;
@@ -236,6 +237,32 @@ TEST_P(PackUnpackTest, PackUnpackSnormOverflow)
compareBeforeAfter(mSNormProgram, 16384.0f, -16384.0f, 1.0f, -1.0f);
}
+// Test that the SaturateDepth pass in Metal uses the correct buffer size when the unpack image
+// height is smaller than the image height.
+TEST_P(PackUnpackTest, D32FSaturateDepth)
+{
+ glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 128);
+ ASSERT_GL_NO_ERROR();
+
+ std::vector<float> kInitData(1024, 0);
+
+ GLBuffer unpackBuffer;
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(float) * kInitData.size(), kInitData.data(),
+ GL_STATIC_DRAW);
+
+ GLTexture tex;
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 512, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
+ 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
+ drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
+ ASSERT_GL_NO_ERROR();
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PackUnpackTest);
ANGLE_INSTANTIATE_TEST_ES3(PackUnpackTest);
} // namespace