mirror of
https://github.com/godotengine/godot-angle-static.git
synced 2026-01-03 14:09:33 +03:00
Metal: Implement EGL_ANGLE_iosurface_client_buffer.
GL_R16UI format is not supported yet. It will be implemented once integer textures are implemented in metal back-end. Bug: angleproject:4847 Bug: angleproject:2634 Change-Id: I60a52c0ce327a524c74e80b18bb15978ac52065b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2329091 Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
committed by
Commit Bot
parent
a5a08b5e4e
commit
69ca10255c
@@ -2,9 +2,9 @@
|
||||
"src/libANGLE/renderer/angle_format.py":
|
||||
"32ba71942c0fd00e6807104f1bb80a3c",
|
||||
"src/libANGLE/renderer/metal/gen_mtl_format_table.py":
|
||||
"b6468446dd1da3e44ac9dd11690b5bf1",
|
||||
"780f56abea19db610d2b829ba817fdc6",
|
||||
"src/libANGLE/renderer/metal/mtl_format_map.json":
|
||||
"223e0b729f5df7d91af382fa3af32254",
|
||||
"7aad5b3ed806e0d932cbbfe6d3b8a834",
|
||||
"src/libANGLE/renderer/metal/mtl_format_table_autogen.mm":
|
||||
"d924184394625032e8a3e97c8b936a5f"
|
||||
"efd031ead828c19f5476413b2b743087"
|
||||
}
|
||||
@@ -93,6 +93,11 @@ class DisplayMtl : public DisplayImpl
|
||||
|
||||
bool isValidNativeWindow(EGLNativeWindowType window) const override;
|
||||
|
||||
egl::Error validateClientBuffer(const egl::Config *configuration,
|
||||
EGLenum buftype,
|
||||
EGLClientBuffer clientBuffer,
|
||||
const egl::AttributeMap &attribs) const override;
|
||||
|
||||
egl::ConfigSet generateConfigs() override;
|
||||
|
||||
std::string getRendererDescription() const;
|
||||
|
||||
@@ -166,8 +166,7 @@ SurfaceImpl *DisplayMtl::createWindowSurface(const egl::SurfaceState &state,
|
||||
SurfaceImpl *DisplayMtl::createPbufferSurface(const egl::SurfaceState &state,
|
||||
const egl::AttributeMap &attribs)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return static_cast<SurfaceImpl *>(0);
|
||||
return new PBufferSurfaceMtl(this, state, attribs);
|
||||
}
|
||||
|
||||
SurfaceImpl *DisplayMtl::createPbufferFromClientBuffer(const egl::SurfaceState &state,
|
||||
@@ -175,8 +174,15 @@ SurfaceImpl *DisplayMtl::createPbufferFromClientBuffer(const egl::SurfaceState &
|
||||
EGLClientBuffer clientBuffer,
|
||||
const egl::AttributeMap &attribs)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return static_cast<SurfaceImpl *>(0);
|
||||
switch (buftype)
|
||||
{
|
||||
case EGL_IOSURFACE_ANGLE:
|
||||
return new IOSurfaceSurfaceMtl(this, state, clientBuffer, attribs);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SurfaceImpl *DisplayMtl::createPixmapSurface(const egl::SurfaceState &state,
|
||||
@@ -249,6 +255,7 @@ egl::Error DisplayMtl::makeCurrent(egl::Surface *drawSurface,
|
||||
void DisplayMtl::generateExtensions(egl::DisplayExtensions *outExtensions) const
|
||||
{
|
||||
outExtensions->flexibleSurfaceCompatibility = true;
|
||||
outExtensions->iosurfaceClientBuffer = true;
|
||||
}
|
||||
|
||||
void DisplayMtl::generateCaps(egl::Caps *outCaps) const {}
|
||||
@@ -278,9 +285,10 @@ egl::ConfigSet DisplayMtl::generateConfigs()
|
||||
config.transparentType = EGL_NONE;
|
||||
|
||||
// Pbuffer
|
||||
config.maxPBufferWidth = 4096;
|
||||
config.maxPBufferHeight = 4096;
|
||||
config.maxPBufferPixels = 4096 * 4096;
|
||||
config.bindToTextureTarget = EGL_TEXTURE_2D;
|
||||
config.maxPBufferWidth = 4096;
|
||||
config.maxPBufferHeight = 4096;
|
||||
config.maxPBufferPixels = 4096 * 4096;
|
||||
|
||||
// Caveat
|
||||
config.configCaveat = EGL_NONE;
|
||||
@@ -290,9 +298,9 @@ egl::ConfigSet DisplayMtl::generateConfigs()
|
||||
config.samples = 0;
|
||||
config.level = 0;
|
||||
config.bindToTextureRGB = EGL_FALSE;
|
||||
config.bindToTextureRGBA = EGL_FALSE;
|
||||
config.bindToTextureRGBA = EGL_TRUE;
|
||||
|
||||
config.surfaceType = EGL_WINDOW_BIT;
|
||||
config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
|
||||
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
config.minSwapInterval = 0;
|
||||
@@ -360,6 +368,26 @@ bool DisplayMtl::isValidNativeWindow(EGLNativeWindowType window) const
|
||||
}
|
||||
}
|
||||
|
||||
egl::Error DisplayMtl::validateClientBuffer(const egl::Config *configuration,
|
||||
EGLenum buftype,
|
||||
EGLClientBuffer clientBuffer,
|
||||
const egl::AttributeMap &attribs) const
|
||||
{
|
||||
switch (buftype)
|
||||
{
|
||||
case EGL_IOSURFACE_ANGLE:
|
||||
if (!IOSurfaceSurfaceMtl::ValidateAttributes(clientBuffer, attribs))
|
||||
{
|
||||
return egl::EglBadAttribute();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return egl::EglBadAttribute();
|
||||
}
|
||||
return egl::NoError();
|
||||
}
|
||||
|
||||
std::string DisplayMtl::getRendererDescription() const
|
||||
{
|
||||
ANGLE_MTL_OBJC_SCOPE
|
||||
|
||||
@@ -158,6 +158,79 @@ class WindowSurfaceMtl : public SurfaceMtl
|
||||
CGSize mCurrentKnownDrawableSize;
|
||||
};
|
||||
|
||||
// Offscreen surface, base class of PBuffer, IOSurface.
|
||||
class OffscreenSurfaceMtl : public SurfaceMtl
|
||||
{
|
||||
public:
|
||||
OffscreenSurfaceMtl(DisplayMtl *display,
|
||||
const egl::SurfaceState &state,
|
||||
const egl::AttributeMap &attribs);
|
||||
~OffscreenSurfaceMtl() override;
|
||||
|
||||
void destroy(const egl::Display *display) override;
|
||||
|
||||
egl::Error swap(const gl::Context *context) override;
|
||||
|
||||
egl::Error bindTexImage(const gl::Context *context,
|
||||
gl::Texture *texture,
|
||||
EGLint buffer) override;
|
||||
egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
|
||||
|
||||
angle::Result getAttachmentRenderTarget(const gl::Context *context,
|
||||
GLenum binding,
|
||||
const gl::ImageIndex &imageIndex,
|
||||
GLsizei samples,
|
||||
FramebufferAttachmentRenderTarget **rtOut) override;
|
||||
|
||||
protected:
|
||||
angle::Result ensureTexturesSizeCorrect(const gl::Context *context);
|
||||
|
||||
gl::Extents mSize;
|
||||
};
|
||||
|
||||
// PBuffer surface
|
||||
class PBufferSurfaceMtl : public OffscreenSurfaceMtl
|
||||
{
|
||||
public:
|
||||
PBufferSurfaceMtl(DisplayMtl *display,
|
||||
const egl::SurfaceState &state,
|
||||
const egl::AttributeMap &attribs);
|
||||
|
||||
void setFixedWidth(EGLint width) override;
|
||||
void setFixedHeight(EGLint height) override;
|
||||
};
|
||||
|
||||
// Offscreen created from IOSurface
|
||||
class IOSurfaceSurfaceMtl : public OffscreenSurfaceMtl
|
||||
{
|
||||
public:
|
||||
IOSurfaceSurfaceMtl(DisplayMtl *display,
|
||||
const egl::SurfaceState &state,
|
||||
EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs);
|
||||
~IOSurfaceSurfaceMtl() override;
|
||||
|
||||
egl::Error bindTexImage(const gl::Context *context,
|
||||
gl::Texture *texture,
|
||||
EGLint buffer) override;
|
||||
egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
|
||||
|
||||
angle::Result getAttachmentRenderTarget(const gl::Context *context,
|
||||
GLenum binding,
|
||||
const gl::ImageIndex &imageIndex,
|
||||
GLsizei samples,
|
||||
FramebufferAttachmentRenderTarget **rtOut) override;
|
||||
|
||||
static bool ValidateAttributes(EGLClientBuffer buffer, const egl::AttributeMap &attribs);
|
||||
|
||||
private:
|
||||
angle::Result ensureColorTextureCreated(const gl::Context *context);
|
||||
|
||||
IOSurfaceRef mIOSurface;
|
||||
NSUInteger mIOSurfacePlane;
|
||||
int mIOSurfaceFormatIdx;
|
||||
};
|
||||
|
||||
} // namespace rx
|
||||
|
||||
#endif /* LIBANGLE_RENDERER_METAL_SURFACEMTL_H_ */
|
||||
|
||||
@@ -46,6 +46,40 @@ constexpr angle::FormatID kDefaultFrameBufferStencilFormatId = angle::FormatID::
|
||||
constexpr angle::FormatID kDefaultFrameBufferDepthStencilFormatId =
|
||||
angle::FormatID::D24_UNORM_S8_UINT;
|
||||
|
||||
struct IOSurfaceFormatInfo
|
||||
{
|
||||
GLenum internalFormat;
|
||||
GLenum type;
|
||||
size_t componentBytes;
|
||||
|
||||
angle::FormatID nativeAngleFormatId;
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
// NOTE(hqle): Support R16_UINT once GLES3 is complete.
|
||||
constexpr std::array<IOSurfaceFormatInfo, 6> kIOSurfaceFormats = {{
|
||||
{GL_RED, GL_UNSIGNED_BYTE, 1, angle::FormatID::R8_UNORM},
|
||||
{GL_RG, GL_UNSIGNED_BYTE, 2, angle::FormatID::R8G8_UNORM},
|
||||
{GL_RGB, GL_UNSIGNED_BYTE, 4, angle::FormatID::B8G8R8A8_UNORM},
|
||||
{GL_BGRA_EXT, GL_UNSIGNED_BYTE, 4, angle::FormatID::B8G8R8A8_UNORM},
|
||||
{GL_RGBA, GL_HALF_FLOAT, 8, angle::FormatID::R16G16B16A16_FLOAT},
|
||||
{GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV, 4, angle::FormatID::B10G10R10A2_UNORM},
|
||||
}};
|
||||
// clang-format on
|
||||
|
||||
int FindIOSurfaceFormatIndex(GLenum internalFormat, GLenum type)
|
||||
{
|
||||
for (int i = 0; i < static_cast<int>(kIOSurfaceFormats.size()); ++i)
|
||||
{
|
||||
const auto &formatInfo = kIOSurfaceFormats[i];
|
||||
if (formatInfo.internalFormat == internalFormat && formatInfo.type == type)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
angle::Result CreateTexture(const gl::Context *context,
|
||||
const mtl::Format &format,
|
||||
uint32_t width,
|
||||
@@ -209,14 +243,7 @@ SurfaceMtl::SurfaceMtl(DisplayMtl *display,
|
||||
const egl::AttributeMap &attribs)
|
||||
: SurfaceImpl(state)
|
||||
{
|
||||
|
||||
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf says that BGRA8Unorm is
|
||||
// only supported if depth24Stencil8PixelFormatSupported capabilitiy is YES. Yet
|
||||
// CAMetalLayer can be created with pixelFormat MTLPixelFormatBGRA8Unorm. So the mtl::Format
|
||||
// used for SurfaceMtl is initialized a bit differently from normal TextureMtl's mtl::Format.
|
||||
// It won't use format table, instead we initialize its values here to use BGRA8Unorm directly:
|
||||
mColorFormat.intendedFormatId = mColorFormat.actualFormatId = angle::FormatID::B8G8R8A8_UNORM;
|
||||
mColorFormat.metalFormat = MTLPixelFormatBGRA8Unorm;
|
||||
mColorFormat = display->getPixelFormat(angle::FormatID::B8G8R8A8_UNORM);
|
||||
|
||||
mSamples = state.config->samples;
|
||||
|
||||
@@ -747,4 +774,248 @@ angle::Result WindowSurfaceMtl::swapImpl(const gl::Context *context)
|
||||
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
// OffscreenSurfaceMtl implementation
|
||||
OffscreenSurfaceMtl::OffscreenSurfaceMtl(DisplayMtl *display,
|
||||
const egl::SurfaceState &state,
|
||||
const egl::AttributeMap &attribs)
|
||||
: SurfaceMtl(display, state, attribs)
|
||||
{
|
||||
mSize = gl::Extents(attribs.getAsInt(EGL_WIDTH, 1), attribs.getAsInt(EGL_HEIGHT, 1), 1);
|
||||
}
|
||||
|
||||
OffscreenSurfaceMtl::~OffscreenSurfaceMtl() {}
|
||||
|
||||
void OffscreenSurfaceMtl::destroy(const egl::Display *display)
|
||||
{
|
||||
SurfaceMtl::destroy(display);
|
||||
}
|
||||
|
||||
egl::Error OffscreenSurfaceMtl::swap(const gl::Context *context)
|
||||
{
|
||||
// Check for surface resize.
|
||||
ANGLE_TO_EGL_TRY(ensureTexturesSizeCorrect(context));
|
||||
|
||||
return egl::NoError();
|
||||
}
|
||||
|
||||
egl::Error OffscreenSurfaceMtl::bindTexImage(const gl::Context *context,
|
||||
gl::Texture *texture,
|
||||
EGLint buffer)
|
||||
{
|
||||
ContextMtl *contextMtl = mtl::GetImpl(context);
|
||||
contextMtl->flushCommandBufer();
|
||||
|
||||
// Initialize offscreen textures if needed:
|
||||
ANGLE_TO_EGL_TRY(ensureTexturesSizeCorrect(context));
|
||||
|
||||
return egl::NoError();
|
||||
}
|
||||
|
||||
egl::Error OffscreenSurfaceMtl::releaseTexImage(const gl::Context *context, EGLint buffer)
|
||||
{
|
||||
ContextMtl *contextMtl = mtl::GetImpl(context);
|
||||
|
||||
if (mMSColorTexture)
|
||||
{
|
||||
ANGLE_TO_EGL_TRY(resolveColorTextureIfNeeded(context));
|
||||
}
|
||||
|
||||
// NOTE(hqle): Should we finishCommandBuffer or flush is enough?
|
||||
contextMtl->flushCommandBufer();
|
||||
return egl::NoError();
|
||||
}
|
||||
|
||||
angle::Result OffscreenSurfaceMtl::getAttachmentRenderTarget(
|
||||
const gl::Context *context,
|
||||
GLenum binding,
|
||||
const gl::ImageIndex &imageIndex,
|
||||
GLsizei samples,
|
||||
FramebufferAttachmentRenderTarget **rtOut)
|
||||
{
|
||||
// Initialize offscreen textures if needed:
|
||||
ANGLE_TRY(ensureTexturesSizeCorrect(context));
|
||||
|
||||
return SurfaceMtl::getAttachmentRenderTarget(context, binding, imageIndex, samples, rtOut);
|
||||
}
|
||||
|
||||
angle::Result OffscreenSurfaceMtl::ensureTexturesSizeCorrect(const gl::Context *context)
|
||||
{
|
||||
if (!mColorTexture || mColorTexture->size() != mSize)
|
||||
{
|
||||
ANGLE_TRY(CreateTexture(context, mColorFormat, mSize.width, mSize.height, 1,
|
||||
/** renderTargetOnly */ false, &mColorTexture));
|
||||
|
||||
mColorRenderTarget.set(mColorTexture, 0, 0, mColorFormat);
|
||||
}
|
||||
|
||||
return ensureCompanionTexturesSizeCorrect(context, mSize);
|
||||
}
|
||||
|
||||
// PBufferSurfaceMtl implementation
|
||||
PBufferSurfaceMtl::PBufferSurfaceMtl(DisplayMtl *display,
|
||||
const egl::SurfaceState &state,
|
||||
const egl::AttributeMap &attribs)
|
||||
: OffscreenSurfaceMtl(display, state, attribs)
|
||||
{}
|
||||
|
||||
void PBufferSurfaceMtl::setFixedWidth(EGLint width)
|
||||
{
|
||||
mSize.width = width;
|
||||
}
|
||||
|
||||
void PBufferSurfaceMtl::setFixedHeight(EGLint height)
|
||||
{
|
||||
mSize.height = height;
|
||||
}
|
||||
|
||||
// IOSurfaceSurfaceMtl implementation.
|
||||
IOSurfaceSurfaceMtl::IOSurfaceSurfaceMtl(DisplayMtl *display,
|
||||
const egl::SurfaceState &state,
|
||||
EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs)
|
||||
: OffscreenSurfaceMtl(display, state, attribs), mIOSurface((__bridge IOSurfaceRef)(buffer))
|
||||
{
|
||||
CFRetain(mIOSurface);
|
||||
|
||||
mIOSurfacePlane = static_cast<int>(attribs.get(EGL_IOSURFACE_PLANE_ANGLE));
|
||||
|
||||
EGLAttrib internalFormat = attribs.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE);
|
||||
EGLAttrib type = attribs.get(EGL_TEXTURE_TYPE_ANGLE);
|
||||
mIOSurfaceFormatIdx =
|
||||
FindIOSurfaceFormatIndex(static_cast<GLenum>(internalFormat), static_cast<GLenum>(type));
|
||||
ASSERT(mIOSurfaceFormatIdx >= 0);
|
||||
|
||||
mColorFormat =
|
||||
display->getPixelFormat(kIOSurfaceFormats[mIOSurfaceFormatIdx].nativeAngleFormatId);
|
||||
}
|
||||
IOSurfaceSurfaceMtl::~IOSurfaceSurfaceMtl()
|
||||
{
|
||||
if (mIOSurface != nullptr)
|
||||
{
|
||||
CFRelease(mIOSurface);
|
||||
mIOSurface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
egl::Error IOSurfaceSurfaceMtl::bindTexImage(const gl::Context *context,
|
||||
gl::Texture *texture,
|
||||
EGLint buffer)
|
||||
{
|
||||
ContextMtl *contextMtl = mtl::GetImpl(context);
|
||||
StartFrameCapture(contextMtl);
|
||||
|
||||
// Initialize offscreen texture if needed:
|
||||
ANGLE_TO_EGL_TRY(ensureColorTextureCreated(context));
|
||||
|
||||
return OffscreenSurfaceMtl::bindTexImage(context, texture, buffer);
|
||||
}
|
||||
|
||||
egl::Error IOSurfaceSurfaceMtl::releaseTexImage(const gl::Context *context, EGLint buffer)
|
||||
{
|
||||
egl::Error re = OffscreenSurfaceMtl::releaseTexImage(context, buffer);
|
||||
StopFrameCapture();
|
||||
return re;
|
||||
}
|
||||
|
||||
angle::Result IOSurfaceSurfaceMtl::getAttachmentRenderTarget(
|
||||
const gl::Context *context,
|
||||
GLenum binding,
|
||||
const gl::ImageIndex &imageIndex,
|
||||
GLsizei samples,
|
||||
FramebufferAttachmentRenderTarget **rtOut)
|
||||
{
|
||||
// Initialize offscreen texture if needed:
|
||||
ANGLE_TRY(ensureColorTextureCreated(context));
|
||||
|
||||
return OffscreenSurfaceMtl::getAttachmentRenderTarget(context, binding, imageIndex, samples,
|
||||
rtOut);
|
||||
}
|
||||
|
||||
angle::Result IOSurfaceSurfaceMtl::ensureColorTextureCreated(const gl::Context *context)
|
||||
{
|
||||
if (mColorTexture)
|
||||
{
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
ContextMtl *contextMtl = mtl::GetImpl(context);
|
||||
ANGLE_MTL_OBJC_SCOPE
|
||||
{
|
||||
auto texDesc =
|
||||
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:mColorFormat.metalFormat
|
||||
width:mSize.width
|
||||
height:mSize.height
|
||||
mipmapped:NO];
|
||||
|
||||
texDesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
|
||||
|
||||
id<MTLTexture> texture =
|
||||
[contextMtl->getMetalDevice() newTextureWithDescriptor:texDesc
|
||||
iosurface:mIOSurface
|
||||
plane:mIOSurfacePlane];
|
||||
|
||||
mColorTexture = mtl::Texture::MakeFromMetal([texture ANGLE_MTL_AUTORELEASE]);
|
||||
}
|
||||
|
||||
mColorRenderTarget.set(mColorTexture, 0, 0, mColorFormat);
|
||||
|
||||
if (kIOSurfaceFormats[mIOSurfaceFormatIdx].internalFormat == GL_RGB)
|
||||
{
|
||||
// This format has emulated alpha channel. Initialize texture's alpha channel to 1.0.
|
||||
ANGLE_TRY(mtl::InitializeTextureContentsGPU(
|
||||
context, mColorTexture, gl::ImageIndex::Make2D(0), MTLColorWriteMaskAlpha));
|
||||
|
||||
// Disable subsequent rendering to alpha channel.
|
||||
mColorTexture->setColorWritableMask(MTLColorWriteMaskAll & (~MTLColorWriteMaskAlpha));
|
||||
}
|
||||
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
// static
|
||||
bool IOSurfaceSurfaceMtl::ValidateAttributes(EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs)
|
||||
{
|
||||
IOSurfaceRef ioSurface = (__bridge IOSurfaceRef)(buffer);
|
||||
|
||||
// The plane must exist for this IOSurface. IOSurfaceGetPlaneCount can return 0 for non-planar
|
||||
// ioSurfaces but we will treat non-planar like it is a single plane.
|
||||
size_t surfacePlaneCount = std::max(size_t(1), IOSurfaceGetPlaneCount(ioSurface));
|
||||
EGLAttrib plane = attribs.get(EGL_IOSURFACE_PLANE_ANGLE);
|
||||
if (plane < 0 || static_cast<size_t>(plane) >= surfacePlaneCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// The width height specified must be at least (1, 1) and at most the plane size
|
||||
EGLAttrib width = attribs.get(EGL_WIDTH);
|
||||
EGLAttrib height = attribs.get(EGL_HEIGHT);
|
||||
if (width <= 0 || static_cast<size_t>(width) > IOSurfaceGetWidthOfPlane(ioSurface, plane) ||
|
||||
height <= 0 || static_cast<size_t>(height) > IOSurfaceGetHeightOfPlane(ioSurface, plane))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find this IOSurface format
|
||||
EGLAttrib internalFormat = attribs.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE);
|
||||
EGLAttrib type = attribs.get(EGL_TEXTURE_TYPE_ANGLE);
|
||||
|
||||
int formatIndex =
|
||||
FindIOSurfaceFormatIndex(static_cast<GLenum>(internalFormat), static_cast<GLenum>(type));
|
||||
|
||||
if (formatIndex < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the format matches this IOSurface plane
|
||||
if (IOSurfaceGetBytesPerElementOfPlane(ioSurface, plane) !=
|
||||
kIOSurfaceFormats[formatIndex].componentBytes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
#include "common/MemoryBuffer.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/mathutil.h"
|
||||
#include "libANGLE/Surface.h"
|
||||
#include "libANGLE/renderer/metal/ContextMtl.h"
|
||||
#include "libANGLE/renderer/metal/DisplayMtl.h"
|
||||
#include "libANGLE/renderer/metal/FrameBufferMtl.h"
|
||||
#include "libANGLE/renderer/metal/SurfaceMtl.h"
|
||||
#include "libANGLE/renderer/metal/mtl_common.h"
|
||||
#include "libANGLE/renderer/metal/mtl_format_utils.h"
|
||||
#include "libANGLE/renderer/metal/mtl_utils.h"
|
||||
@@ -732,16 +734,32 @@ angle::Result TextureMtl::setBaseLevel(const gl::Context *context, GLuint baseLe
|
||||
|
||||
angle::Result TextureMtl::bindTexImage(const gl::Context *context, egl::Surface *surface)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
releaseTexture(true);
|
||||
|
||||
return angle::Result::Stop;
|
||||
auto pBuffer = GetImplAs<OffscreenSurfaceMtl>(surface);
|
||||
mNativeTexture = pBuffer->getColorTexture();
|
||||
mFormat = pBuffer->getColorFormat();
|
||||
gl::Extents size = mNativeTexture->size();
|
||||
mIsPow2 = gl::isPow2(size.width) && gl::isPow2(size.height) && gl::isPow2(size.depth);
|
||||
ANGLE_TRY(ensureSamplerStateCreated(context));
|
||||
|
||||
ASSERT(mState.getType() == gl::TextureType::_2D);
|
||||
mLayeredRenderTargets.resize(1);
|
||||
mLayeredRenderTargets[0].set(mNativeTexture, 0, 0, mFormat);
|
||||
mLayeredTextureViews.resize(1);
|
||||
mLayeredTextureViews[0] = mNativeTexture;
|
||||
|
||||
// Tell context to rebind textures
|
||||
ContextMtl *contextMtl = mtl::GetImpl(context);
|
||||
contextMtl->invalidateCurrentTextures();
|
||||
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
angle::Result TextureMtl::releaseTexImage(const gl::Context *context)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
|
||||
return angle::Result::Stop;
|
||||
releaseTexture(true);
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
angle::Result TextureMtl::getAttachmentRenderTarget(const gl::Context *context,
|
||||
|
||||
@@ -160,7 +160,7 @@ def gen_image_map_switch_string(image_table):
|
||||
angle_override = image_table["override"]
|
||||
mac_override = image_table["override_mac"]
|
||||
ios_override = image_table["override_ios"]
|
||||
mac_fallbacks = image_table["fallbacks_mac"]
|
||||
mac_fallbacks = image_table["d24s8_fallbacks_mac"]
|
||||
angle_to_mtl = image_table["map"]
|
||||
mac_specific_map = image_table["map_mac"]
|
||||
ios_specific_map = image_table["map_ios"]
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
"B8G8R8A8_UNORM_SRGB": "MTLPixelFormatBGRA8Unorm_sRGB",
|
||||
"D32_FLOAT": "MTLPixelFormatDepth32Float",
|
||||
"S8_UINT": "MTLPixelFormatStencil8",
|
||||
"D32_FLOAT_S8X24_UINT": "MTLPixelFormatDepth32Float_Stencil8"
|
||||
"D32_FLOAT_S8X24_UINT": "MTLPixelFormatDepth32Float_Stencil8",
|
||||
"B10G10R10A2_UNORM": "MTLPixelFormatBGR10A2Unorm"
|
||||
},
|
||||
"map_ios": {
|
||||
"R5G6B5_UNORM": "MTLPixelFormatB5G6R5Unorm",
|
||||
@@ -85,14 +86,8 @@
|
||||
"R5G5B5A1_UNORM": "R8G8B8A8_UNORM",
|
||||
"R4G4B4A4_UNORM": "R8G8B8A8_UNORM"
|
||||
},
|
||||
"fallbacks_mac": {
|
||||
"B8G8R8A8_UNORM": "R8G8B8A8_UNORM",
|
||||
"D24_UNORM_S8_UINT": "D32_FLOAT_S8X24_UINT",
|
||||
"R8_UNORM": "NONE",
|
||||
"R16_FLOAT": "NONE",
|
||||
"R32_FLOAT": "NONE",
|
||||
"R16G16B16A16_FLOAT": "NONE",
|
||||
"R32G32B32A32_FLOAT": "NONE"
|
||||
"d24s8_fallbacks_mac": {
|
||||
"D24_UNORM_S8_UINT": "D32_FLOAT_S8X24_UINT"
|
||||
}
|
||||
},
|
||||
"vertex": {
|
||||
|
||||
@@ -34,27 +34,16 @@ void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
|
||||
this->actualFormatId = angle::FormatID::A8_UNORM;
|
||||
break;
|
||||
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::B8G8R8A8_UNORM:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatBGRA8Unorm;
|
||||
this->actualFormatId = angle::FormatID::B8G8R8A8_UNORM;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatRGBA8Unorm;
|
||||
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
|
||||
}
|
||||
case angle::FormatID::B10G10R10A2_UNORM:
|
||||
this->metalFormat = MTLPixelFormatBGR10A2Unorm;
|
||||
this->actualFormatId = angle::FormatID::B10G10R10A2_UNORM;
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::B8G8R8A8_UNORM:
|
||||
this->metalFormat = MTLPixelFormatBGRA8Unorm;
|
||||
this->actualFormatId = angle::FormatID::B8G8R8A8_UNORM;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::B8G8R8A8_UNORM_SRGB:
|
||||
this->metalFormat = MTLPixelFormatBGRA8Unorm_sRGB;
|
||||
this->actualFormatId = angle::FormatID::B8G8R8A8_UNORM_SRGB;
|
||||
@@ -75,105 +64,41 @@ void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
break;
|
||||
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R16G16B16A16_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatRGBA16Float;
|
||||
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R16G16B16A16_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRGBA16Float;
|
||||
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R16G16_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRG16Float;
|
||||
this->actualFormatId = angle::FormatID::R16G16_FLOAT;
|
||||
break;
|
||||
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R16_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatR16Float;
|
||||
this->actualFormatId = angle::FormatID::R16_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R16_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatR16Float;
|
||||
this->actualFormatId = angle::FormatID::R16_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R16_UNORM:
|
||||
this->metalFormat = MTLPixelFormatR16Unorm;
|
||||
this->actualFormatId = angle::FormatID::R16_UNORM;
|
||||
break;
|
||||
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R32G32B32A32_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatRGBA32Float;
|
||||
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R32G32B32A32_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRGBA32Float;
|
||||
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R32G32_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRG32Float;
|
||||
this->actualFormatId = angle::FormatID::R32G32_FLOAT;
|
||||
break;
|
||||
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R32_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatR32Float;
|
||||
this->actualFormatId = angle::FormatID::R32_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R32_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatR32Float;
|
||||
this->actualFormatId = angle::FormatID::R32_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R8G8B8A8_UNORM:
|
||||
this->metalFormat = MTLPixelFormatRGBA8Unorm;
|
||||
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
|
||||
@@ -189,74 +114,26 @@ void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
|
||||
this->actualFormatId = angle::FormatID::R8G8_UNORM;
|
||||
break;
|
||||
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R8_UNORM:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatR8Unorm;
|
||||
this->actualFormatId = angle::FormatID::R8_UNORM;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R8_UNORM:
|
||||
this->metalFormat = MTLPixelFormatR8Unorm;
|
||||
this->actualFormatId = angle::FormatID::R8_UNORM;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::S8_UINT:
|
||||
this->metalFormat = MTLPixelFormatStencil8;
|
||||
this->actualFormatId = angle::FormatID::S8_UINT;
|
||||
break;
|
||||
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::A16_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatRGBA16Float;
|
||||
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::A16_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRGBA16Float;
|
||||
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::A32_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatRGBA32Float;
|
||||
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::A32_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRGBA32Float;
|
||||
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::D24_UNORM_X8_UINT:
|
||||
this->metalFormat = MTLPixelFormatDepth32Float;
|
||||
this->actualFormatId = angle::FormatID::D32_FLOAT;
|
||||
@@ -267,90 +144,26 @@ void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
|
||||
this->actualFormatId = angle::FormatID::D32_FLOAT;
|
||||
break;
|
||||
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::L16A16_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatRGBA16Float;
|
||||
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::L16A16_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRGBA16Float;
|
||||
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::L16_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatRGBA16Float;
|
||||
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::L16_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRGBA16Float;
|
||||
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::L32A32_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatRGBA32Float;
|
||||
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::L32A32_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRGBA32Float;
|
||||
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::L32_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatRGBA32Float;
|
||||
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::L32_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRGBA32Float;
|
||||
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::L8A8_UNORM:
|
||||
this->metalFormat = MTLPixelFormatRGBA8Unorm;
|
||||
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
|
||||
@@ -361,48 +174,16 @@ void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
|
||||
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
|
||||
break;
|
||||
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R16G16B16_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatRGBA16Float;
|
||||
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R16G16B16_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRGBA16Float;
|
||||
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R32G32B32_FLOAT:
|
||||
if (metalDevice.depth24Stencil8PixelFormatSupported)
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatRGBA32Float;
|
||||
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->metalFormat = MTLPixelFormatInvalid;
|
||||
this->actualFormatId = angle::FormatID::NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R32G32B32_FLOAT:
|
||||
this->metalFormat = MTLPixelFormatRGBA32Float;
|
||||
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
|
||||
break;
|
||||
|
||||
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case angle::FormatID::R8G8B8_UNORM:
|
||||
this->metalFormat = MTLPixelFormatRGBA8Unorm;
|
||||
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
|
||||
|
||||
@@ -34,6 +34,7 @@ bool OverrideTextureCaps(const DisplayMtl *display, angle::FormatID formatId, gl
|
||||
case angle::FormatID::R8G8B8A8_UNORM_SRGB:
|
||||
case angle::FormatID::B8G8R8A8_UNORM:
|
||||
case angle::FormatID::B8G8R8A8_UNORM_SRGB:
|
||||
case angle::FormatID::B10G10R10A2_UNORM:
|
||||
// NOTE: even though iOS devices don't support filtering depth textures, we still report as
|
||||
// supported here in order for the OES_depth_texture extension to be enabled.
|
||||
// During draw call, the filter modes will be converted to nearest.
|
||||
@@ -214,6 +215,7 @@ bool Format::FormatRenderable(MTLPixelFormat format)
|
||||
case MTLPixelFormatDepth32Float:
|
||||
case MTLPixelFormatStencil8:
|
||||
case MTLPixelFormatDepth32Float_Stencil8:
|
||||
case MTLPixelFormatBGR10A2Unorm:
|
||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||
case MTLPixelFormatDepth16Unorm:
|
||||
case MTLPixelFormatDepth24Unorm_Stencil8:
|
||||
|
||||
@@ -28,10 +28,17 @@ namespace mtl
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// Initialize texture content to (0, 0, 0, 1)
|
||||
angle::Result InitializeTextureContents(const gl::Context *context,
|
||||
const TextureRef &texture,
|
||||
const Format &textureObjFormat,
|
||||
const gl::ImageIndex &index);
|
||||
// Same as above but using GPU clear operation instead of CPU.
|
||||
// - channelsToInit parameter controls which channels will get their content initialized.
|
||||
angle::Result InitializeTextureContentsGPU(const gl::Context *context,
|
||||
const TextureRef &texture,
|
||||
const gl::ImageIndex &index,
|
||||
MTLColorWriteMask channelsToInit);
|
||||
|
||||
MTLViewport GetViewport(const gl::Rectangle &rect, double znear = 0, double zfar = 1);
|
||||
MTLViewport GetViewportFlipY(const gl::Rectangle &rect,
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "common/MemoryBuffer.h"
|
||||
#include "libANGLE/renderer/metal/ContextMtl.h"
|
||||
#include "libANGLE/renderer/metal/DisplayMtl.h"
|
||||
#include "libANGLE/renderer/metal/mtl_render_utils.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
@@ -77,6 +79,47 @@ angle::Result InitializeTextureContents(const gl::Context *context,
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
angle::Result InitializeTextureContentsGPU(const gl::Context *context,
|
||||
const TextureRef &texture,
|
||||
const gl::ImageIndex &index,
|
||||
MTLColorWriteMask channelsToInit)
|
||||
{
|
||||
ContextMtl *contextMtl = mtl::GetImpl(context);
|
||||
// Use clear render command
|
||||
|
||||
// temporarily enable color channels requested via channelsToInit. Some emulated format has some
|
||||
// channels write mask disabled when the texture is created.
|
||||
MTLColorWriteMask oldMask = texture->getColorWritableMask();
|
||||
texture->setColorWritableMask(channelsToInit);
|
||||
|
||||
RenderCommandEncoder *encoder;
|
||||
if (channelsToInit == MTLColorWriteMaskAll)
|
||||
{
|
||||
// If all channels will be initialized, use clear loadOp.
|
||||
Optional<MTLClearColor> blackColor = MTLClearColorMake(0, 0, 0, 1);
|
||||
encoder = contextMtl->getRenderCommandEncoder(texture, index, blackColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there are some channels don't need to be initialized, we must use clearWithDraw.
|
||||
encoder = contextMtl->getRenderCommandEncoder(texture, index);
|
||||
|
||||
ClearRectParams clearParams;
|
||||
clearParams.clearColor = {.alpha = 1};
|
||||
clearParams.clearArea = gl::Rectangle(0, 0, texture->width(), texture->height());
|
||||
|
||||
ANGLE_TRY(
|
||||
contextMtl->getDisplay()->getUtils().clearWithDraw(context, encoder, clearParams));
|
||||
}
|
||||
ANGLE_UNUSED_VARIABLE(encoder);
|
||||
contextMtl->endEncoding(true);
|
||||
|
||||
// Restore texture's intended write mask
|
||||
texture->setColorWritableMask(oldMask);
|
||||
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
MTLViewport GetViewport(const gl::Rectangle &rect, double znear, double zfar)
|
||||
{
|
||||
MTLViewport re;
|
||||
|
||||
@@ -211,6 +211,10 @@ class IOSurfaceClientBufferTest : public ANGLETest
|
||||
EXPECT_EGL_TRUE(result);
|
||||
EXPECT_EGL_SUCCESS();
|
||||
|
||||
// IOSurface client buffer's rendering doesn't automatically finish after
|
||||
// eglReleaseTexImage(). Need to explicitly call glFinish().
|
||||
glFinish();
|
||||
|
||||
IOSurfaceLock(ioSurface.get(), kIOSurfaceLockReadOnly, nullptr);
|
||||
std::array<T, dataSize> iosurfaceData;
|
||||
memcpy(iosurfaceData.data(), IOSurfaceGetBaseAddress(ioSurface.get()),
|
||||
@@ -294,6 +298,11 @@ class IOSurfaceClientBufferTest : public ANGLETest
|
||||
|
||||
void doBlitTest(bool ioSurfaceIsSource, int width, int height)
|
||||
{
|
||||
if (!hasBlitExt())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Create IOSurface and bind it to a texture.
|
||||
ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(width, height, 'BGRA', 4);
|
||||
EGLSurface pbuffer;
|
||||
@@ -361,6 +370,10 @@ class IOSurfaceClientBufferTest : public ANGLETest
|
||||
}
|
||||
|
||||
bool hasIOSurfaceExt() const { return IsEGLDisplayExtensionEnabled(mDisplay, kIOSurfaceExt); }
|
||||
bool hasBlitExt() const
|
||||
{
|
||||
return IsEGLDisplayExtensionEnabled(mDisplay, "ANGLE_framebuffer_blit");
|
||||
}
|
||||
|
||||
EGLConfig mConfig;
|
||||
EGLDisplay mDisplay;
|
||||
@@ -465,6 +478,9 @@ TEST_P(IOSurfaceClientBufferTest, RenderToR16IOSurface)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());
|
||||
|
||||
// This test only works on ES3 since it requires an integer texture.
|
||||
ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
|
||||
|
||||
// TODO(http://anglebug.com/4369)
|
||||
ANGLE_SKIP_TEST_IF(isSwiftshader());
|
||||
|
||||
@@ -990,4 +1006,5 @@ ANGLE_INSTANTIATE_TEST(IOSurfaceClientBufferTest,
|
||||
ES2_OPENGL(),
|
||||
ES3_OPENGL(),
|
||||
ES2_VULKAN_SWIFTSHADER(),
|
||||
ES3_VULKAN_SWIFTSHADER());
|
||||
ES3_VULKAN_SWIFTSHADER(),
|
||||
ES2_METAL());
|
||||
|
||||
Reference in New Issue
Block a user