Support SharedTextureMemory from AHBs for the GL backend.
Create and store EGLImages in SharedTextureMemoryEGL and produce
native GL textures on SharedTextureMemory::CreaeteTexture.
Unknown format enums are treated as RGBA8 and all usages except
sampling are disabled. They are often vendor-specific YUV formats
that are unknowable.
Bug: 42241435
Change-Id: I47b5ecd653dc7efd0ec89207e96b3d5d45ba9ff2
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/211834
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/dawn/native/AHBFunctions.cpp b/src/dawn/native/AHBFunctions.cpp
index 25d66e7..ec89898 100644
--- a/src/dawn/native/AHBFunctions.cpp
+++ b/src/dawn/native/AHBFunctions.cpp
@@ -29,6 +29,82 @@
namespace dawn::native {
+namespace {
+
+// Convert from AHardwareBuffer_Format to wgpu::TextureFormat. Returns:
+// - The exact corresponding wgpu::TextureFormat if the AHardwareBuffer format matches channel and
+// bit count.
+// - External if the format miss-matches in channel count or bit count but is still usable as an
+// OpenGL or Vulkan texture in Dawn.
+// - Undefined if the format is not applicable for WebGPU to import as a texture.
+wgpu::TextureFormat FormatFromAHardwareBufferFormat(uint32_t ahbFormat) {
+ switch (ahbFormat) {
+ // Formats with exact WebGPU representations
+ case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
+ return wgpu::TextureFormat::RGBA8Unorm;
+ case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
+ return wgpu::TextureFormat::RGBA16Float;
+ case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+ return wgpu::TextureFormat::RGB10A2Unorm;
+ case AHARDWAREBUFFER_FORMAT_D16_UNORM:
+ return wgpu::TextureFormat::Depth16Unorm;
+ case AHARDWAREBUFFER_FORMAT_D24_UNORM:
+ return wgpu::TextureFormat::Depth24Plus;
+ case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
+ return wgpu::TextureFormat::Depth24PlusStencil8;
+ case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
+ return wgpu::TextureFormat::Depth32Float;
+ case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
+ return wgpu::TextureFormat::Depth32FloatStencil8;
+ case AHARDWAREBUFFER_FORMAT_S8_UINT:
+ return wgpu::TextureFormat::Stencil8;
+ case AHARDWAREBUFFER_FORMAT_R8_UNORM:
+ return wgpu::TextureFormat::R8Unorm;
+ case AHARDWAREBUFFER_FORMAT_R16_UINT:
+ return wgpu::TextureFormat::R16Uint;
+ case AHARDWAREBUFFER_FORMAT_R16G16_UINT:
+ return wgpu::TextureFormat::RG16Uint;
+
+ // R8G8B8X8 is used in Vulkan as VK_FORMAT_R8G8B8A8_UNORM and GLES as GL_RGB8. In Vulkan the
+ // alpha channel can be read and written but GL always treats it as opaque. Data can be
+ // uploaded as if it's RGBA8.
+ case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+ return wgpu::TextureFormat::RGBA8Unorm;
+
+ // YUV formats are sampleable with external Vulkan samplers or as opaque samplers in GLES.
+ // Treat them as External.
+ case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
+ return wgpu::TextureFormat::External;
+ case AHARDWAREBUFFER_FORMAT_YCbCr_P010:
+ return wgpu::TextureFormat::External;
+
+ // RGB formats with no direct representation in WebGPU. Trivially sampleable and renderable
+ // in Vulkan and GLES but data uploads are not currently supported.
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+ return wgpu::TextureFormat::External;
+ case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
+ return wgpu::TextureFormat::External;
+
+ // R10G10B10A10 maps to Vulkan format VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 and no
+ // GLES format. Not supported with no known use case.
+ case AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM:
+ return wgpu::TextureFormat::Undefined;
+
+ // Can be used as a Vulkan buffer or bound to a GLES buffer using GL_EXT_external_buffer.
+ // These use cases are not currently supported.
+ case AHARDWAREBUFFER_FORMAT_BLOB:
+ return wgpu::TextureFormat::Undefined;
+
+ // Android drivers make use of formats outside of the defined enums to represent internal
+ // YUV formats used by the camera and video decoder. Treat these all as external and
+ // sampleable.
+ default:
+ return wgpu::TextureFormat::External;
+ }
+}
+
+} // anonymous namespace
+
AHBFunctions::AHBFunctions() {
if (!mNativeWindowLib.Open("libnativewindow.so") ||
!mNativeWindowLib.GetProc(&Acquire, "AHardwareBuffer_acquire") ||
@@ -44,4 +120,28 @@
return mNativeWindowLib.Valid();
}
+SharedTextureMemoryProperties GetAHBSharedTextureMemoryProperties(
+ const AHBFunctions* ahbFunctions,
+ ::AHardwareBuffer* aHardwareBuffer) {
+ AHardwareBuffer_Desc aHardwareBufferDesc{};
+ ahbFunctions->Describe(aHardwareBuffer, &aHardwareBufferDesc);
+
+ SharedTextureMemoryProperties properties;
+ properties.size = {aHardwareBufferDesc.width, aHardwareBufferDesc.height,
+ aHardwareBufferDesc.layers};
+ properties.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
+ if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER) {
+ properties.usage |= wgpu::TextureUsage::RenderAttachment;
+ }
+ if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) {
+ properties.usage |= wgpu::TextureUsage::TextureBinding;
+ }
+ if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER) {
+ properties.usage |= wgpu::TextureUsage::StorageBinding;
+ }
+ properties.format = FormatFromAHardwareBufferFormat(aHardwareBufferDesc.format);
+
+ return properties;
+}
+
} // namespace dawn::native
diff --git a/src/dawn/native/AHBFunctions.h b/src/dawn/native/AHBFunctions.h
index 1d42b9b..bf1d50c 100644
--- a/src/dawn/native/AHBFunctions.h
+++ b/src/dawn/native/AHBFunctions.h
@@ -31,6 +31,7 @@
#include <android/hardware_buffer.h>
#include "dawn/common/DynamicLib.h"
+#include "dawn/native/dawn_platform.h"
namespace dawn::native {
@@ -50,6 +51,10 @@
DynamicLib mNativeWindowLib;
};
+SharedTextureMemoryProperties GetAHBSharedTextureMemoryProperties(
+ const AHBFunctions* ahbFunctions,
+ ::AHardwareBuffer* aHardwareBuffer);
+
} // namespace dawn::native
#endif // SRC_DAWN_NATIVE_AHBFUNCTIONS_H_
diff --git a/src/dawn/native/BUILD.gn b/src/dawn/native/BUILD.gn
index 766688d..8089e30 100644
--- a/src/dawn/native/BUILD.gn
+++ b/src/dawn/native/BUILD.gn
@@ -757,6 +757,10 @@
"opengl/SamplerGL.h",
"opengl/ShaderModuleGL.cpp",
"opengl/ShaderModuleGL.h",
+ "opengl/SharedTextureMemoryEGL.cpp",
+ "opengl/SharedTextureMemoryEGL.h",
+ "opengl/SharedTextureMemoryGL.cpp",
+ "opengl/SharedTextureMemoryGL.h",
"opengl/SwapChainEGL.cpp",
"opengl/SwapChainEGL.h",
"opengl/TextureGL.cpp",
diff --git a/src/dawn/native/CMakeLists.txt b/src/dawn/native/CMakeLists.txt
index 1bcb6b2..35dffb2 100644
--- a/src/dawn/native/CMakeLists.txt
+++ b/src/dawn/native/CMakeLists.txt
@@ -611,6 +611,8 @@
"opengl/RenderPipelineGL.h"
"opengl/SamplerGL.h"
"opengl/ShaderModuleGL.h"
+ "opengl/SharedTextureMemoryEGL.h"
+ "opengl/SharedTextureMemoryGL.h"
"opengl/SwapChainEGL.h"
"opengl/TextureGL.h"
"opengl/UtilsEGL.h"
@@ -640,6 +642,8 @@
"opengl/RenderPipelineGL.cpp"
"opengl/SamplerGL.cpp"
"opengl/ShaderModuleGL.cpp"
+ "opengl/SharedTextureMemoryEGL.cpp"
+ "opengl/SharedTextureMemoryGL.cpp"
"opengl/SwapChainEGL.cpp"
"opengl/TextureGL.cpp"
"opengl/UtilsEGL.cpp"
diff --git a/src/dawn/native/opengl/DeviceGL.cpp b/src/dawn/native/opengl/DeviceGL.cpp
index 6ee1ca1..dd9568f 100644
--- a/src/dawn/native/opengl/DeviceGL.cpp
+++ b/src/dawn/native/opengl/DeviceGL.cpp
@@ -48,11 +48,16 @@
#include "dawn/native/opengl/RenderPipelineGL.h"
#include "dawn/native/opengl/SamplerGL.h"
#include "dawn/native/opengl/ShaderModuleGL.h"
+#include "dawn/native/opengl/SharedTextureMemoryEGL.h"
#include "dawn/native/opengl/SwapChainEGL.h"
#include "dawn/native/opengl/TextureGL.h"
#include "dawn/native/opengl/UtilsGL.h"
#include "dawn/native/opengl/opengl_platform.h"
+#if DAWN_PLATFORM_IS(ANDROID)
+#include "dawn/native/AHBFunctions.h"
+#endif // DAWN_PLATFORM_IS(ANDROID)
+
namespace {
void KHRONOS_APIENTRY OnGLDebugMessage(GLenum source,
@@ -281,6 +286,28 @@
return AcquireRef(new TextureView(texture, descriptor));
}
+ResultOrError<Ref<SharedTextureMemoryBase>> Device::ImportSharedTextureMemoryImpl(
+ const SharedTextureMemoryDescriptor* descriptor) {
+ UnpackedPtr<SharedTextureMemoryDescriptor> unpacked;
+ DAWN_TRY_ASSIGN(unpacked, ValidateAndUnpack(descriptor));
+
+ wgpu::SType type;
+ DAWN_TRY_ASSIGN(
+ type, (unpacked.ValidateBranches<Branch<SharedTextureMemoryAHardwareBufferDescriptor>>()));
+
+ switch (type) {
+ case wgpu::SType::SharedTextureMemoryAHardwareBufferDescriptor:
+ DAWN_INVALID_IF(!HasFeature(Feature::SharedTextureMemoryAHardwareBuffer),
+ "%s is not enabled.",
+ wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer);
+ return SharedTextureMemoryEGL::Create(
+ this, descriptor->label,
+ unpacked.Get<SharedTextureMemoryAHardwareBufferDescriptor>());
+ default:
+ DAWN_UNREACHABLE();
+ }
+}
+
MaybeError Device::ValidateTextureCanBeWrapped(const UnpackedPtr<TextureDescriptor>& descriptor) {
DAWN_INVALID_IF(descriptor->dimension != wgpu::TextureDimension::e2D,
"Texture dimension (%s) is not %s.", descriptor->dimension,
@@ -340,7 +367,7 @@
// TODO(dawn:803): Validate the OpenGL texture format from the EGLImage against the format
// in the passed-in TextureDescriptor.
- auto result = AcquireRef(new Texture(this, textureDescriptor, tex));
+ auto result = AcquireRef(new Texture(this, textureDescriptor, tex, OwnsHandle::No));
result->SetIsSubresourceContentInitialized(descriptor->isInitialized,
result->GetAllSubresources());
return result;
@@ -381,7 +408,7 @@
return nullptr;
}
- auto result = AcquireRef(new Texture(this, textureDescriptor, texture));
+ auto result = AcquireRef(new Texture(this, textureDescriptor, texture, OwnsHandle::No));
result->SetIsSubresourceContentInitialized(descriptor->isInitialized,
result->GetAllSubresources());
return result;
@@ -431,6 +458,17 @@
return true;
}
+const AHBFunctions* Device::GetOrLoadAHBFunctions() {
+#if DAWN_PLATFORM_IS(ANDROID)
+ if (mAHBFunctions == nullptr) {
+ mAHBFunctions = std::make_unique<AHBFunctions>();
+ }
+ return mAHBFunctions.get();
+#else
+ DAWN_UNREACHABLE();
+#endif // DAWN_PLATFORM_IS(ANDROID)
+}
+
const OpenGLFunctions& Device::GetGL() const {
mContext->MakeCurrent();
ToBackend(GetQueue())->OnGLUsed();
diff --git a/src/dawn/native/opengl/DeviceGL.h b/src/dawn/native/opengl/DeviceGL.h
index f4418f6..13a551c 100644
--- a/src/dawn/native/opengl/DeviceGL.h
+++ b/src/dawn/native/opengl/DeviceGL.h
@@ -41,6 +41,10 @@
#include "dawn/native/opengl/GLFormat.h"
#include "dawn/native/opengl/OpenGLFunctions.h"
+namespace dawn::native {
+class AHBFunctions;
+} // namespace dawn::native
+
namespace dawn::native::opengl {
class ContextEGL;
@@ -101,6 +105,8 @@
bool MayRequireDuplicationOfIndirectParameters() const override;
bool ShouldApplyIndexBufferOffsetToFirstIndex() const override;
+ const AHBFunctions* GetOrLoadAHBFunctions();
+
private:
Device(AdapterBase* adapter,
const UnpackedPtr<DeviceDescriptor>& descriptor,
@@ -138,6 +144,8 @@
const UnpackedPtr<ComputePipelineDescriptor>& descriptor) override;
Ref<RenderPipelineBase> CreateUninitializedRenderPipelineImpl(
const UnpackedPtr<RenderPipelineDescriptor>& descriptor) override;
+ ResultOrError<Ref<SharedTextureMemoryBase>> ImportSharedTextureMemoryImpl(
+ const SharedTextureMemoryDescriptor* descriptor) override;
GLenum GetBGRAInternalFormat(const OpenGLFunctions& gl) const;
void DestroyImpl() override;
@@ -147,6 +155,10 @@
GLFormatTable mFormatTable;
std::unique_ptr<ContextEGL> mContext;
int mMaxTextureMaxAnisotropy = 0;
+
+#if DAWN_PLATFORM_IS(ANDROID)
+ std::unique_ptr<AHBFunctions> mAHBFunctions;
+#endif // DAWN_PLATFORM_IS(ANDROID)
};
} // namespace dawn::native::opengl
diff --git a/src/dawn/native/opengl/EGLFunctions.cpp b/src/dawn/native/opengl/EGLFunctions.cpp
index 867d5ff..4c0d4bd 100644
--- a/src/dawn/native/opengl/EGLFunctions.cpp
+++ b/src/dawn/native/opengl/EGLFunctions.cpp
@@ -86,6 +86,9 @@
{EGLExt::NoConfigContext, "EGL_KHR_no_config_context", NeverPromoted, ExtType::Display},
{EGLExt::PixelFormatFloat, "EGL_EXT_pixel_format_float", NeverPromoted, ExtType::Display},
{EGLExt::GLColorspace, "EGL_KHR_gl_colorspace", NeverPromoted, ExtType::Display},
+ {EGLExt::ImageNativeBuffer, "EGL_ANDROID_image_native_buffer", NeverPromoted, ExtType::Display},
+ {EGLExt::GetNativeClientBuffer, "EGL_ANDROID_get_native_client_buffer", NeverPromoted,
+ ExtType::Display},
//
}};
@@ -235,6 +238,10 @@
GET_PROC_WITH_NAME(SignalSync, "eglSignalSyncKHR");
}
+ if (HasExt(EGLExt::GetNativeClientBuffer)) {
+ GET_PROC_WITH_NAME(GetNativeClientBuffer, "eglGetNativeClientBufferANDROID");
+ }
+
return {};
}
diff --git a/src/dawn/native/opengl/EGLFunctions.h b/src/dawn/native/opengl/EGLFunctions.h
index a2b2aae..68ef1d1 100644
--- a/src/dawn/native/opengl/EGLFunctions.h
+++ b/src/dawn/native/opengl/EGLFunctions.h
@@ -61,6 +61,10 @@
PixelFormatFloat,
GLColorspace,
+ // EGL image creation extensions
+ ImageNativeBuffer, // EGL_ANDROID_image_native_buffer
+ GetNativeClientBuffer, // EGL_ANDROID_get_native_client_buffer
+
EnumCount,
};
@@ -135,6 +139,9 @@
// EGL_KHR_reusable_sync
PFNEGLSIGNALSYNCKHRPROC SignalSync;
+ // EGL_ANDROID_get_native_client_buffer
+ PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC GetNativeClientBuffer;
+
private:
MaybeError LoadClientExtensions();
diff --git a/src/dawn/native/opengl/PhysicalDeviceGL.cpp b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
index 1755178..ec61445 100644
--- a/src/dawn/native/opengl/PhysicalDeviceGL.cpp
+++ b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
@@ -252,6 +252,11 @@
EnableFeature(dawn::native::Feature::ANGLETextureSharing);
}
+ if (mDisplay->egl.HasExt(EGLExt::ImageNativeBuffer) &&
+ mDisplay->egl.HasExt(EGLExt::GetNativeClientBuffer)) {
+ EnableFeature(dawn::native::Feature::SharedTextureMemoryAHardwareBuffer);
+ }
+
// Non-zero baseInstance requires at least desktop OpenGL 4.2, and it is not supported in
// OpenGL ES OpenGL:
// https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDrawElementsIndirect.xhtml
diff --git a/src/dawn/native/opengl/SharedTextureMemoryEGL.cpp b/src/dawn/native/opengl/SharedTextureMemoryEGL.cpp
new file mode 100644
index 0000000..c45261c
--- /dev/null
+++ b/src/dawn/native/opengl/SharedTextureMemoryEGL.cpp
@@ -0,0 +1,111 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "dawn/native/opengl/SharedTextureMemoryEGL.h"
+
+#include <utility>
+
+#include "dawn/native/opengl/DeviceGL.h"
+#include "dawn/native/opengl/TextureGL.h"
+
+#if DAWN_PLATFORM_IS(ANDROID)
+#include <android/hardware_buffer.h>
+
+#include "dawn/native/AHBFunctions.h"
+#endif // DAWN_PLATFORM_IS(ANDROID)
+
+namespace dawn::native::opengl {
+
+ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemoryEGL::Create(
+ Device* device,
+ StringView label,
+ const SharedTextureMemoryAHardwareBufferDescriptor* descriptor) {
+#if DAWN_PLATFORM_IS(ANDROID)
+ const EGLFunctions& egl = device->GetEGL(false);
+ DAWN_ASSERT(egl.HasExt(EGLExt::ImageNativeBuffer) && egl.HasExt(EGLExt::GetNativeClientBuffer));
+
+ ::AHardwareBuffer* aHardwareBuffer = static_cast<struct AHardwareBuffer*>(descriptor->handle);
+ DAWN_INVALID_IF(aHardwareBuffer == nullptr, "AHardwareBuffer is missing.");
+
+ // Reflect the properties of the AHardwareBuffer.
+ SharedTextureMemoryProperties properties =
+ GetAHBSharedTextureMemoryProperties(device->GetOrLoadAHBFunctions(), aHardwareBuffer);
+ DAWN_INVALID_IF(properties.format == wgpu::TextureFormat::Undefined,
+ "Unknown AHardwareBuffer format cannot be imported.");
+
+ // If the format of the AHB is unknown due to not having an equivalent wgpu::TextureFormat or
+ // being an unknowable Android video format, disable all usages except sampling.
+ if (properties.format == wgpu::TextureFormat::External) {
+ properties.usage &= wgpu::TextureUsage::TextureBinding;
+ }
+
+ const EGLAttrib attribs[] = {
+ EGL_NONE,
+ };
+ EGLClientBuffer clientBuffer = egl.GetNativeClientBuffer(aHardwareBuffer);
+ ::EGLImage image = egl.CreateImage(device->GetEGLDisplay(), EGL_NO_CONTEXT,
+ EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attribs);
+ DAWN_INVALID_IF(image == nullptr, "EGLImage creation failed, 0x%X", egl.GetError());
+
+ auto result = AcquireRef(new SharedTextureMemoryEGL(device, label, properties, image));
+ result->Initialize();
+ return result;
+#else
+ DAWN_UNREACHABLE();
+#endif // DAWN_PLATFORM_IS(ANDROID)
+}
+
+SharedTextureMemoryEGL::SharedTextureMemoryEGL(Device* device,
+ StringView label,
+ const SharedTextureMemoryProperties& properties,
+ ::EGLImage image)
+ : SharedTextureMemory(device, label, properties), mEGLImage(image) {}
+
+void SharedTextureMemoryEGL::DestroyImpl() {
+ if (mEGLImage) {
+ Device* device = ToBackend(GetDevice());
+ const EGLFunctions& egl = device->GetEGL(false);
+
+ egl.DestroyImage(device->GetEGLDisplay(), mEGLImage);
+ mEGLImage = nullptr;
+ }
+}
+
+GLuint SharedTextureMemoryEGL::GenerateGLTexture() {
+ Device* device = ToBackend(GetDevice());
+ const OpenGLFunctions& gl = device->GetGL();
+
+ GLuint tex;
+ gl.GenTextures(1, &tex);
+ gl.BindTexture(GL_TEXTURE_2D, tex);
+ gl.EGLImageTargetTexture2DOES(GL_TEXTURE_2D, mEGLImage);
+ gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+
+ return tex;
+}
+
+} // namespace dawn::native::opengl
diff --git a/src/dawn/native/opengl/SharedTextureMemoryEGL.h b/src/dawn/native/opengl/SharedTextureMemoryEGL.h
new file mode 100644
index 0000000..4fbffb2
--- /dev/null
+++ b/src/dawn/native/opengl/SharedTextureMemoryEGL.h
@@ -0,0 +1,61 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_DAWN_NATIVE_OPENGL_SHARED_TEXTURE_MEMORY_EGL_H_
+#define SRC_DAWN_NATIVE_OPENGL_SHARED_TEXTURE_MEMORY_EGL_H_
+
+#include "dawn/native/opengl/SharedTextureMemoryGL.h"
+#include "dawn/native/opengl/opengl_platform.h"
+
+namespace dawn::native::opengl {
+
+class Device;
+
+class SharedTextureMemoryEGL final : public SharedTextureMemory {
+ public:
+ static ResultOrError<Ref<SharedTextureMemory>> Create(
+ Device* device,
+ StringView label,
+ const SharedTextureMemoryAHardwareBufferDescriptor* descriptor);
+
+ GLuint GenerateGLTexture() override;
+
+ private:
+ SharedTextureMemoryEGL(Device* device,
+ StringView label,
+ const SharedTextureMemoryProperties& properties,
+ ::EGLImage image);
+
+ void DestroyImpl() override;
+
+ private:
+ ::EGLImage mEGLImage = nullptr;
+};
+
+} // namespace dawn::native::opengl
+
+#endif // SRC_DAWN_NATIVE_OPENGL_SHARED_TEXTURE_MEMORY_EGL_H_
diff --git a/src/dawn/native/opengl/SharedTextureMemoryGL.cpp b/src/dawn/native/opengl/SharedTextureMemoryGL.cpp
new file mode 100644
index 0000000..0b8f21c
--- /dev/null
+++ b/src/dawn/native/opengl/SharedTextureMemoryGL.cpp
@@ -0,0 +1,60 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "dawn/native/opengl/SharedTextureMemoryGL.h"
+
+#include <utility>
+
+#include "dawn/native/opengl/DeviceGL.h"
+#include "dawn/native/opengl/TextureGL.h"
+
+namespace dawn::native::opengl {
+
+SharedTextureMemory::SharedTextureMemory(Device* device,
+ StringView label,
+ const SharedTextureMemoryProperties& properties)
+ : SharedTextureMemoryBase(device, label, properties) {}
+
+ResultOrError<Ref<TextureBase>> SharedTextureMemory::CreateTextureImpl(
+ const UnpackedPtr<TextureDescriptor>& descriptor) {
+ return Texture::CreateFromSharedTextureMemory(this, descriptor);
+}
+
+MaybeError SharedTextureMemory::BeginAccessImpl(
+ TextureBase* texture,
+ const UnpackedPtr<BeginAccessDescriptor>& descriptor) {
+ return {};
+}
+
+ResultOrError<FenceAndSignalValue> SharedTextureMemory::EndAccessImpl(
+ TextureBase* texture,
+ ExecutionSerial lastUsageSerial,
+ UnpackedPtr<EndAccessState>& state) {
+ return DAWN_VALIDATION_ERROR("No shared fence features supported.");
+}
+
+} // namespace dawn::native::opengl
diff --git a/src/dawn/native/opengl/SharedTextureMemoryGL.h b/src/dawn/native/opengl/SharedTextureMemoryGL.h
new file mode 100644
index 0000000..7572bfc
--- /dev/null
+++ b/src/dawn/native/opengl/SharedTextureMemoryGL.h
@@ -0,0 +1,58 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_DAWN_NATIVE_OPENGL_SHARED_TEXTURE_MEMORY_GL_H_
+#define SRC_DAWN_NATIVE_OPENGL_SHARED_TEXTURE_MEMORY_GL_H_
+
+#include "dawn/native/SharedTextureMemory.h"
+#include "dawn/native/opengl/opengl_platform.h"
+
+namespace dawn::native::opengl {
+
+class Device;
+
+class SharedTextureMemory : public SharedTextureMemoryBase {
+ public:
+ virtual GLuint GenerateGLTexture() = 0;
+
+ protected:
+ SharedTextureMemory(Device* device,
+ StringView label,
+ const SharedTextureMemoryProperties& properties);
+
+ ResultOrError<Ref<TextureBase>> CreateTextureImpl(
+ const UnpackedPtr<TextureDescriptor>& descriptor) override;
+ MaybeError BeginAccessImpl(TextureBase* texture,
+ const UnpackedPtr<BeginAccessDescriptor>& descriptor) override;
+ ResultOrError<FenceAndSignalValue> EndAccessImpl(TextureBase* texture,
+ ExecutionSerial lastUsageSerial,
+ UnpackedPtr<EndAccessState>& state) override;
+};
+
+} // namespace dawn::native::opengl
+
+#endif // SRC_DAWN_NATIVE_OPENGL_SHARED_TEXTURE_MEMORY_GL_H_
diff --git a/src/dawn/native/opengl/TextureGL.cpp b/src/dawn/native/opengl/TextureGL.cpp
index 771adc6..1fd249d 100644
--- a/src/dawn/native/opengl/TextureGL.cpp
+++ b/src/dawn/native/opengl/TextureGL.cpp
@@ -38,6 +38,7 @@
#include "dawn/native/opengl/BufferGL.h"
#include "dawn/native/opengl/CommandBufferGL.h"
#include "dawn/native/opengl/DeviceGL.h"
+#include "dawn/native/opengl/SharedTextureMemoryGL.h"
#include "dawn/native/opengl/UtilsGL.h"
namespace dawn::native::opengl {
@@ -192,12 +193,25 @@
return std::move(texture);
}
+// static
+ResultOrError<Ref<Texture>> Texture::CreateFromSharedTextureMemory(
+ SharedTextureMemory* memory,
+ const UnpackedPtr<TextureDescriptor>& descriptor) {
+ Device* device = ToBackend(memory->GetDevice());
+
+ GLuint textureId = memory->GenerateGLTexture();
+ DAWN_ASSERT(textureId != 0);
+
+ Ref<Texture> texture = AcquireRef(new Texture(device, descriptor, textureId, OwnsHandle::Yes));
+ texture->mSharedResourceMemoryContents = memory->GetContents();
+ return texture;
+}
+
Texture::Texture(Device* device, const UnpackedPtr<TextureDescriptor>& descriptor)
- : Texture(device, descriptor, 0) {
+ : Texture(device, descriptor, 0, OwnsHandle::Yes) {
const OpenGLFunctions& gl = device->GetGL();
gl.GenTextures(1, &mHandle);
- mOwnsHandle = true;
uint32_t levels = GetNumMipLevels();
const GLFormat& glFormat = GetGLFormat();
@@ -211,8 +225,11 @@
gl.TexParameteri(mTarget, GL_TEXTURE_MAX_LEVEL, levels - 1);
}
-Texture::Texture(Device* device, const UnpackedPtr<TextureDescriptor>& descriptor, GLuint handle)
- : TextureBase(device, descriptor), mHandle(handle) {
+Texture::Texture(Device* device,
+ const UnpackedPtr<TextureDescriptor>& descriptor,
+ GLuint handle,
+ OwnsHandle ownsHandle)
+ : TextureBase(device, descriptor), mHandle(handle), mOwnsHandle(ownsHandle) {
mTarget = TargetForTextureViewDimension(GetCompatibilityTextureBindingViewDimension(),
descriptor->sampleCount);
}
@@ -221,7 +238,7 @@
void Texture::DestroyImpl() {
TextureBase::DestroyImpl();
- if (mOwnsHandle) {
+ if (mOwnsHandle == OwnsHandle::Yes) {
const OpenGLFunctions& gl = ToBackend(GetDevice())->GetGL();
gl.DeleteTextures(1, &mHandle);
mHandle = 0;
diff --git a/src/dawn/native/opengl/TextureGL.h b/src/dawn/native/opengl/TextureGL.h
index f971dd4..d63a4f8 100644
--- a/src/dawn/native/opengl/TextureGL.h
+++ b/src/dawn/native/opengl/TextureGL.h
@@ -36,12 +36,25 @@
class Device;
struct GLFormat;
+class SharedTextureMemory;
+
+enum class OwnsHandle : uint8_t {
+ Yes,
+ No,
+};
class Texture final : public TextureBase {
public:
static ResultOrError<Ref<Texture>> Create(Device* device,
const UnpackedPtr<TextureDescriptor>& descriptor);
- Texture(Device* device, const UnpackedPtr<TextureDescriptor>& descriptor, GLuint handle);
+ static ResultOrError<Ref<Texture>> CreateFromSharedTextureMemory(
+ SharedTextureMemory* memory,
+ const UnpackedPtr<TextureDescriptor>& descriptor);
+
+ Texture(Device* device,
+ const UnpackedPtr<TextureDescriptor>& descriptor,
+ GLuint handle,
+ OwnsHandle ownsHandle);
GLuint GetHandle() const;
GLenum GetGLTarget() const;
@@ -57,7 +70,7 @@
MaybeError ClearTexture(const SubresourceRange& range, TextureBase::ClearValue clearValue);
GLuint mHandle;
- bool mOwnsHandle = false;
+ OwnsHandle mOwnsHandle = OwnsHandle::No;
GLenum mTarget;
};
diff --git a/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp b/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
index 1122d45..6967083 100644
--- a/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
+++ b/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
@@ -493,27 +493,12 @@
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
// Reflect the properties of the AHardwareBuffer.
- AHardwareBuffer_Desc aHardwareBufferDesc{};
- ahbFunctions->Describe(aHardwareBuffer, &aHardwareBufferDesc);
+ SharedTextureMemoryProperties properties =
+ GetAHBSharedTextureMemoryProperties(ahbFunctions, aHardwareBuffer);
- SharedTextureMemoryProperties properties;
- properties.size = {aHardwareBufferDesc.width, aHardwareBufferDesc.height,
- aHardwareBufferDesc.layers};
if (useExternalFormat) {
- if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) {
- properties.usage = wgpu::TextureUsage::TextureBinding;
- }
- } else {
- properties.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
- if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER) {
- properties.usage |= wgpu::TextureUsage::RenderAttachment;
- }
- if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) {
- properties.usage |= wgpu::TextureUsage::TextureBinding;
- }
- if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER) {
- properties.usage |= wgpu::TextureUsage::StorageBinding;
- }
+ // When using the external YUV texture format, only TextureBinding usage is valid.
+ properties.usage &= wgpu::TextureUsage::TextureBinding;
}
VkFormat vkFormat;
diff --git a/src/dawn/tests/white_box/SharedTextureMemoryTests.cpp b/src/dawn/tests/white_box/SharedTextureMemoryTests.cpp
index 2e16605..d5666be 100644
--- a/src/dawn/tests/white_box/SharedTextureMemoryTests.cpp
+++ b/src/dawn/tests/white_box/SharedTextureMemoryTests.cpp
@@ -829,6 +829,9 @@
// Test that it is an error to import a shared fence with no chained struct.
// Also test that ExportInfo reports an Undefined type for the error fence.
TEST_P(SharedTextureMemoryTests, ImportSharedFenceNoChain) {
+ // TODO(dawn/42241435): No shared texture memory extensions are supported yet.
+ DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
+
wgpu::SharedFenceDescriptor desc;
ASSERT_DEVICE_ERROR_MSG(wgpu::SharedFence fence = device.ImportSharedFence(&desc),
HasSubstr("chain"));
@@ -2242,6 +2245,9 @@
// Not supported if using the same device. Not possible to lose one without losing the other.
DAWN_TEST_UNSUPPORTED_IF(GetParam().mBackend->UseSameDevice());
+ // TODO(dawn/42241435): No shared texture memory extensions are supported yet.
+ DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
+
// crbug.com/358166479
DAWN_SUPPRESS_TEST_IF(IsLinux() && IsNvidia() && IsVulkan());
@@ -2309,6 +2315,9 @@
TEST_P(SharedTextureMemoryTests, SeparateDevicesWriteThenConcurrentReadThenWrite) {
DAWN_TEST_UNSUPPORTED_IF(!GetParam().mBackend->SupportsConcurrentRead());
+ // TODO(dawn/42241435): No shared texture memory extensions are supported yet.
+ DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
+
// crbug.com/358166479
DAWN_SUPPRESS_TEST_IF(IsLinux() && IsNvidia() && IsVulkan());
@@ -2592,6 +2601,9 @@
// Test that textures created from SharedTextureMemory may perform sRGB reinterpretation.
TEST_P(SharedTextureMemoryTests, SRGBReinterpretation) {
+ // Format reinterpretation is not available in compatibility mode.
+ DAWN_SUPPRESS_TEST_IF(IsCompatibilityMode());
+
// crbug.com/358166479
DAWN_SUPPRESS_TEST_IF(IsLinux() && IsNvidia() && IsVulkan());
diff --git a/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp b/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp
index cb1706c..7145f67 100644
--- a/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp
+++ b/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp
@@ -42,21 +42,11 @@
namespace dawn {
namespace {
-class Backend : public SharedTextureMemoryTestVulkanBackend {
+template <typename BackendBase>
+class SharedTextureMemoryTestAndroidBackend : public BackendBase {
public:
- static SharedTextureMemoryTestBackend* GetInstance() {
- static Backend b;
- return &b;
- }
-
std::string Name() const override { return "AHardwareBuffer"; }
- std::vector<wgpu::FeatureName> RequiredFeatures(const wgpu::Adapter&) const override {
- return {wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer,
- wgpu::FeatureName::SharedFenceVkSemaphoreSyncFD,
- wgpu::FeatureName::YCbCrVulkanSamplers};
- }
-
static std::string MakeLabel(const AHardwareBuffer_Desc& desc) {
std::string label = std::to_string(desc.width) + "x" + std::to_string(desc.height);
switch (desc.format) {
@@ -138,9 +128,11 @@
int layerCount) override {
std::vector<std::vector<wgpu::SharedTextureMemory>> memories;
+ // AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM behaves inconsistantly between GLES (alpha is
+ // always 1.0) and Vulkan (alpha is writeable) so it is omitted. There is no TextureFormat
+ // to represent the difference so it's undetectable when testing.
for (auto format : {
AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
- AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT,
AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM,
AHARDWAREBUFFER_FORMAT_R8_UNORM,
@@ -179,8 +171,38 @@
}
};
+class SharedTextureMemoryTestAndroidVulkanBackend
+ : public SharedTextureMemoryTestAndroidBackend<SharedTextureMemoryTestVulkanBackend> {
+ public:
+ static SharedTextureMemoryTestBackend* GetInstance() {
+ static SharedTextureMemoryTestAndroidVulkanBackend b;
+ return &b;
+ }
+
+ std::vector<wgpu::FeatureName> RequiredFeatures(const wgpu::Adapter&) const override {
+ return {wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer,
+ wgpu::FeatureName::SharedFenceVkSemaphoreSyncFD,
+ wgpu::FeatureName::YCbCrVulkanSamplers};
+ }
+};
+
+class SharedTextureMemoryTestAndroidOpenGLESBackend
+ : public SharedTextureMemoryTestAndroidBackend<SharedTextureMemoryTestBackend> {
+ public:
+ static SharedTextureMemoryTestBackend* GetInstance() {
+ static SharedTextureMemoryTestAndroidOpenGLESBackend b;
+ return &b;
+ }
+
+ std::vector<wgpu::FeatureName> RequiredFeatures(const wgpu::Adapter&) const override {
+ return {wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer};
+ }
+};
+
// Test clearing the texture memory on the device, then reading it on the CPU.
TEST_P(SharedTextureMemoryTests, GPUWriteThenCPURead) {
+ DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::SharedFenceVkSemaphoreSyncFD}));
+
AHardwareBuffer_Desc aHardwareBufferDesc = {
.width = 4,
.height = 4,
@@ -322,6 +344,8 @@
// Test validation of an incorrectly-configured SharedTextureMemoryAHardwareBufferProperties
// instance.
TEST_P(SharedTextureMemoryTests, InvalidSharedTextureMemoryAHardwareBufferProperties) {
+ DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::YCbCrVulkanSamplers}));
+
AHardwareBuffer_Desc aHardwareBufferDesc = {
.width = 4,
.height = 4,
@@ -353,6 +377,8 @@
// Test querying YCbCr info from the Device.
TEST_P(SharedTextureMemoryTests, QueryYCbCrInfoFromDevice) {
+ DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::YCbCrVulkanSamplers}));
+
AHardwareBuffer_Desc aHardwareBufferDesc = {
.width = 4,
.height = 4,
@@ -414,6 +440,8 @@
// Test querying YCbCr info from the SharedTextureMemory without external format.
TEST_P(SharedTextureMemoryTests, QueryYCbCrInfoWithoutExternalFormat) {
+ DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::YCbCrVulkanSamplers}));
+
AHardwareBuffer_Desc aHardwareBufferDesc = {
.width = 4,
.height = 4,
@@ -488,6 +516,8 @@
// Test querying YCbCr info from the SharedTextureMemory with external format.
TEST_P(SharedTextureMemoryTests, QueryYCbCrInfoWithExternalFormat) {
+ DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::YCbCrVulkanSamplers}));
+
AHardwareBuffer_Desc aHardwareBufferDesc = {
.width = 4,
.height = 4,
@@ -563,6 +593,8 @@
// Test BeginAccess on an uninitialized texture with external format fails.
TEST_P(SharedTextureMemoryTests, GPUReadForUninitializedTextureWithExternalFormatFails) {
+ DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::YCbCrVulkanSamplers}));
+
const AHardwareBuffer_Desc aHardwareBufferDesc = {
.width = 4,
.height = 4,
@@ -605,13 +637,25 @@
DAWN_INSTANTIATE_PREFIXED_TEST_P(Vulkan,
SharedTextureMemoryNoFeatureTests,
{VulkanBackend()},
- {Backend::GetInstance()},
+ {SharedTextureMemoryTestAndroidVulkanBackend::GetInstance()},
{1});
DAWN_INSTANTIATE_PREFIXED_TEST_P(Vulkan,
SharedTextureMemoryTests,
{VulkanBackend()},
- {Backend::GetInstance()},
+ {SharedTextureMemoryTestAndroidVulkanBackend::GetInstance()},
+ {1});
+
+DAWN_INSTANTIATE_PREFIXED_TEST_P(OpenGLES,
+ SharedTextureMemoryNoFeatureTests,
+ {OpenGLESBackend()},
+ {SharedTextureMemoryTestAndroidOpenGLESBackend::GetInstance()},
+ {1});
+
+DAWN_INSTANTIATE_PREFIXED_TEST_P(OpenGLES,
+ SharedTextureMemoryTests,
+ {OpenGLESBackend()},
+ {SharedTextureMemoryTestAndroidOpenGLESBackend::GetInstance()},
{1});
} // anonymous namespace