Skip to content

Commit

Permalink
back-port from gles3-dev: Support PBuffer
Browse files Browse the repository at this point in the history
  • Loading branch information
kakashidinho committed Mar 9, 2021
1 parent 9eea7c8 commit f3ab2c2
Show file tree
Hide file tree
Showing 15 changed files with 556 additions and 251 deletions.
6 changes: 3 additions & 3 deletions scripts/code_generation_hashes/Metal_format_table.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"src/libANGLE/renderer/angle_format_map.json":
"bca5e686001f6dd0af306af234a36677",
"src/libANGLE/renderer/metal/gen_mtl_format_table.py":
"7e8db284f892a6bb1377ea7fb498d484",
"4c7af4111f23f6bc6424b05859aea47b",
"src/libANGLE/renderer/metal/mtl_format_map.json":
"57b49eb11a5401824c256ec3475b6eed",
"86ce732999366526c9b7b248ea09c91f",
"src/libANGLE/renderer/metal/mtl_format_table_autogen.mm":
"d998f8645c7bc92695652346142c1c93"
"35ee19e595ad95f6f3a36988ad5ffd28"
}
4 changes: 2 additions & 2 deletions src/libANGLE/renderer/metal/ContextMtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class FramebufferMtl;
class VertexArrayMtl;
class ProgramMtl;
class RenderTargetMtl;
class SurfaceMtl;
class WindowSurfaceMtl;
class TransformFeedbackMtl;

class ContextMtl : public ContextImpl, public mtl::Context
Expand Down Expand Up @@ -211,7 +211,7 @@ class ContextMtl : public ContextImpl, public mtl::Context
void onDrawFrameBufferChangedState(const gl::Context *context,
FramebufferMtl *framebuffer,
bool renderPassChanged);
void onBackbufferResized(const gl::Context *context, SurfaceMtl *backbuffer);
void onBackbufferResized(const gl::Context *context, WindowSurfaceMtl *backbuffer);

// Invoke by QueryMtl
angle::Result onOcclusionQueryBegan(const gl::Context *context, QueryMtl *query);
Expand Down
2 changes: 1 addition & 1 deletion src/libANGLE/renderer/metal/ContextMtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1691,7 +1691,7 @@ bool IsTransformFeedbackOnly(const gl::State &glState)
}
}

void ContextMtl::onBackbufferResized(const gl::Context *context, SurfaceMtl *backbuffer)
void ContextMtl::onBackbufferResized(const gl::Context *context, WindowSurfaceMtl *backbuffer)
{
const gl::State &glState = getState();
FramebufferMtl *framebuffer = mtl::GetImpl(glState.getDrawFramebuffer());
Expand Down
15 changes: 7 additions & 8 deletions src/libANGLE/renderer/metal/DisplayMtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,13 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override
EGLNativeWindowType window,
const egl::AttributeMap &attribs)
{
return new SurfaceMtl(this, state, window, attribs);
return new WindowSurfaceMtl(this, state, window, attribs);
}

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,
Expand Down Expand Up @@ -336,9 +335,9 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override
config.sampleBuffers = 0;
config.level = 0;
config.bindToTextureRGB = EGL_FALSE;
config.bindToTextureRGBA = EGL_FALSE;
config.bindToTextureRGBA = EGL_TRUE;

config.surfaceType = EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;

#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
config.minSwapInterval = 0;
Expand Down Expand Up @@ -475,7 +474,7 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override
mNativeCaps.maxElementIndex = std::numeric_limits<GLuint>::max() - 1;
mNativeCaps.max3DTextureSize = 2048;
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
mNativeCaps.max2DTextureSize = 16384;
mNativeCaps.max2DTextureSize = 16384;
// On macOS exclude [[position]] from maxVaryingVectors.
mNativeCaps.maxVaryingVectors = 31 - 1;
mNativeCaps.maxVertexOutputComponents = mNativeCaps.maxFragmentInputComponents = 124 - 4;
Expand Down Expand Up @@ -504,11 +503,11 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override
// on Intel and 64 on AMD for now.
if ([mMetalDevice.get().name rangeOfString:@"Intel"].location != NSNotFound)
{
mNativeCaps.maxAliasedPointSize = 255;
mNativeCaps.maxAliasedPointSize = 255;
}
else
{
mNativeCaps.maxAliasedPointSize = 64;
mNativeCaps.maxAliasedPointSize = 64;
}

mNativeCaps.minAliasedLineWidth = 1.0f;
Expand Down
12 changes: 7 additions & 5 deletions src/libANGLE/renderer/metal/FrameBufferMtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ namespace mtl
class RenderCommandEncoder;
} // namespace mtl
class ContextMtl;
class SurfaceMtl;
class WindowSurfaceMtl;

class FramebufferMtl : public FramebufferImpl
{
public:
explicit FramebufferMtl(const gl::FramebufferState &state, bool flipY, SurfaceMtl *backbuffer);
explicit FramebufferMtl(const gl::FramebufferState &state,
bool flipY,
WindowSurfaceMtl *backbuffer);
~FramebufferMtl() override;
void destroy(const gl::Context *context) override;

Expand Down Expand Up @@ -93,7 +95,7 @@ class FramebufferMtl : public FramebufferImpl

gl::Rectangle getCompleteRenderArea() const;
int getSamples() const;
SurfaceMtl *getAttachedBackbuffer() const { return mBackbuffer; }
WindowSurfaceMtl *getAttachedBackbuffer() const { return mBackbuffer; }

bool renderPassHasStarted(ContextMtl *contextMtl) const;
mtl::RenderCommandEncoder *ensureRenderPassStarted(const gl::Context *context);
Expand Down Expand Up @@ -203,8 +205,8 @@ class FramebufferMtl : public FramebufferImpl
// as by a compute pass.
bool mRenderPassCleanStart = false;

SurfaceMtl *mBackbuffer = nullptr;
const bool mFlipY = false;
WindowSurfaceMtl *mBackbuffer = nullptr;
const bool mFlipY = false;

mtl::BufferRef mReadPixelBuffer;
};
Expand Down
5 changes: 2 additions & 3 deletions src/libANGLE/renderer/metal/FrameBufferMtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
// FramebufferMtl implementation
FramebufferMtl::FramebufferMtl(const gl::FramebufferState &state,
bool flipY,
SurfaceMtl *backbuffer)
WindowSurfaceMtl *backbuffer)
: FramebufferImpl(state), mBackbuffer(backbuffer), mFlipY(flipY)
{
reset();
Expand Down Expand Up @@ -600,8 +600,7 @@ PackPixelsParams params(flippedArea, angleFormat, outputPitch, packState.reverse
case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
break;
default:
{
default: {
static_assert(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0, "FB dirty bits");
if (dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX)
{
Expand Down
138 changes: 114 additions & 24 deletions src/libANGLE/renderer/metal/SurfaceMtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#import <QuartzCore/CALayer.h>
#import <QuartzCore/CAMetalLayer.h>

#include <unordered_map>

#include "libANGLE/renderer/FramebufferImpl.h"
#include "libANGLE/renderer/SurfaceImpl.h"
#include "libANGLE/renderer/metal/RenderTargetMtl.h"
Expand All @@ -29,7 +31,6 @@ class SurfaceMtl : public SurfaceImpl
public:
SurfaceMtl(DisplayMtl *display,
const egl::SurfaceState &state,
EGLNativeWindowType window,
const egl::AttributeMap &attribs);
~SurfaceMtl() override;

Expand All @@ -55,19 +56,78 @@ class SurfaceMtl : public SurfaceImpl
egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
void setSwapInterval(EGLint interval) override;
void setSwapBehavior(EGLint behavior) override;
void setFixedWidth(EGLint width) override;
void setFixedHeight(EGLint height) override;

// width and height can change with client window resizing
EGLint getWidth() const override;
EGLint getHeight() const override;

EGLint isPostSubBufferSupported() const override;
EGLint getSwapBehavior() const override;

const mtl::TextureRef &getColorTexture() { return mColorTexture; }
const mtl::Format &getColorFormat() const { return mColorFormat; }
int getSamples() const { return mSamples; }
bool preserveBuffer() const { return mRetainBuffer; }

angle::Result getAttachmentRenderTarget(const gl::Context *context,
GLenum binding,
const gl::ImageIndex &imageIndex,
GLsizei samples,
FramebufferAttachmentRenderTarget **rtOut) override;

protected:
// Ensure companion (MS, depth, stencil) textures' size is correct w.r.t color texture.
angle::Result ensureCompanionTexturesSizeCorrect(const gl::Context *context,
const gl::Extents &size);
angle::Result resolveColorTextureIfNeeded(const gl::Context *context);

// Normal textures
mtl::TextureRef mColorTexture;
mtl::TextureRef mDepthTexture;
mtl::TextureRef mStencilTexture;

// Implicit multisample texture
mtl::TextureRef mMSColorTexture;

bool mUsePackedDepthStencil = false;
bool mAutoResolveMSColorTexture = false;

mtl::Format mColorFormat;
mtl::Format mDepthFormat;
mtl::Format mStencilFormat;

int mSamples = 0;

RenderTargetMtl mColorRenderTarget;
RenderTargetMtl mColorManualResolveRenderTarget;
RenderTargetMtl mDepthRenderTarget;
RenderTargetMtl mStencilRenderTarget;
};

class WindowSurfaceMtl : public SurfaceMtl
{
public:
WindowSurfaceMtl(DisplayMtl *display,
const egl::SurfaceState &state,
EGLNativeWindowType window,
const egl::AttributeMap &attribs);
~WindowSurfaceMtl() override;

void destroy(const egl::Display *display) override;

egl::Error initialize(const egl::Display *display) override;
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
const gl::FramebufferState &state) override;

egl::Error swap(const gl::Context *context) override;

void setSwapInterval(EGLint interval) override;
void setSwapBehavior(EGLint behavior) override;
EGLint getSwapBehavior() const override;

// width and height can change with client window resizing
EGLint getWidth() const override;
EGLint getHeight() const override;

angle::Result getAttachmentRenderTarget(const gl::Context *context,
GLenum binding,
Expand All @@ -77,10 +137,12 @@ class SurfaceMtl : public SurfaceImpl

angle::Result ensureCurrentDrawableObtained(const gl::Context *context);

bool preserveBuffer() const { return mRetainBuffer; }

private:
angle::Result swapImpl(const gl::Context *context);
angle::Result obtainNextDrawable(const gl::Context *context);
angle::Result ensureTexturesSizeCorrect(const gl::Context *context);
angle::Result ensureCompanionTexturesSizeCorrect(const gl::Context *context);

CGSize calcExpectedDrawableSize() const;
// Check if metal layer has been resized.
Expand All @@ -95,36 +157,64 @@ class SurfaceMtl : public SurfaceImpl
CALayer *mLayer;
mtl::AutoObjCPtr<id<CAMetalDrawable>> mCurrentDrawable = nil;

// Texture for preserving content of color buffer (used when multisample texture is not
// enabled).
mtl::TextureRef mRetainedColorTexture;

bool mRetainBuffer = false;

// Cache last known drawable size that is used by GL context. Can be used to detect resize
// event. We don't use mMetalLayer.drawableSize directly since it might be changed internally by
// metal runtime.
CGSize mCurrentKnownDrawableSize;
};

// Normal textures
mtl::TextureRef mDrawableTexture;
mtl::TextureRef mDepthTexture;
mtl::TextureRef mStencilTexture;
class OffscreenSurfaceMtl : public SurfaceMtl
{
public:
OffscreenSurfaceMtl(DisplayMtl *display,
const egl::SurfaceState &state,
const egl::AttributeMap &attribs);
~OffscreenSurfaceMtl() override;

// Implicit multisample texture
mtl::TextureRef mMSColorTexture;
void destroy(const egl::Display *display) override;

// Texture for preserving content of color buffer.
mtl::TextureRef mRetainedColorTexture;
egl::Error swap(const gl::Context *context) override;

bool mUsePackedDepthStencil = false;
bool mAutoResolveMSColorTexture = false;
egl::Error bindTexImage(const gl::Context *context,
gl::Texture *texture,
EGLint buffer) override;
egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;

mtl::Format mColorFormat;
mtl::Format mDepthFormat;
mtl::Format mStencilFormat;
angle::Result getAttachmentRenderTarget(const gl::Context *context,
GLenum binding,
const gl::ImageIndex &imageIndex,
GLsizei samples,
FramebufferAttachmentRenderTarget **rtOut) override;

int mSamples = 0;
bool mRetainBuffer = false;
// Get or create implicit MS color texture. Used by glFramebufferTexture2DMultisampleEXT()
// after eglBindTexImage()
angle::Result getAttachmentMSColorTexture(const gl::Context *context,
GLsizei samples,
mtl::TextureRef *texOut);

RenderTargetMtl mColorRenderTarget;
RenderTargetMtl mColorManualResolveRenderTarget;
RenderTargetMtl mDepthRenderTarget;
RenderTargetMtl mStencilRenderTarget;
protected:
angle::Result ensureTexturesSizeCorrect(const gl::Context *context);

gl::Extents mSize;

std::unordered_map<GLsizei, mtl::TextureRef> mAttachmentMSColorTextures;
};

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;
};

} // namespace rx
Expand Down
Loading

0 comments on commit f3ab2c2

Please sign in to comment.