Skip to content

Commit f3ab2c2

Browse files
committed
back-port from gles3-dev: Support PBuffer
1 parent 9eea7c8 commit f3ab2c2

File tree

15 files changed

+556
-251
lines changed

15 files changed

+556
-251
lines changed

scripts/code_generation_hashes/Metal_format_table.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"src/libANGLE/renderer/angle_format_map.json":
55
"bca5e686001f6dd0af306af234a36677",
66
"src/libANGLE/renderer/metal/gen_mtl_format_table.py":
7-
"7e8db284f892a6bb1377ea7fb498d484",
7+
"4c7af4111f23f6bc6424b05859aea47b",
88
"src/libANGLE/renderer/metal/mtl_format_map.json":
9-
"57b49eb11a5401824c256ec3475b6eed",
9+
"86ce732999366526c9b7b248ea09c91f",
1010
"src/libANGLE/renderer/metal/mtl_format_table_autogen.mm":
11-
"d998f8645c7bc92695652346142c1c93"
11+
"35ee19e595ad95f6f3a36988ad5ffd28"
1212
}

src/libANGLE/renderer/metal/ContextMtl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class FramebufferMtl;
2929
class VertexArrayMtl;
3030
class ProgramMtl;
3131
class RenderTargetMtl;
32-
class SurfaceMtl;
32+
class WindowSurfaceMtl;
3333
class TransformFeedbackMtl;
3434

3535
class ContextMtl : public ContextImpl, public mtl::Context
@@ -211,7 +211,7 @@ class ContextMtl : public ContextImpl, public mtl::Context
211211
void onDrawFrameBufferChangedState(const gl::Context *context,
212212
FramebufferMtl *framebuffer,
213213
bool renderPassChanged);
214-
void onBackbufferResized(const gl::Context *context, SurfaceMtl *backbuffer);
214+
void onBackbufferResized(const gl::Context *context, WindowSurfaceMtl *backbuffer);
215215

216216
// Invoke by QueryMtl
217217
angle::Result onOcclusionQueryBegan(const gl::Context *context, QueryMtl *query);

src/libANGLE/renderer/metal/ContextMtl.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,7 @@ bool IsTransformFeedbackOnly(const gl::State &glState)
16911691
}
16921692
}
16931693

1694-
void ContextMtl::onBackbufferResized(const gl::Context *context, SurfaceMtl *backbuffer)
1694+
void ContextMtl::onBackbufferResized(const gl::Context *context, WindowSurfaceMtl *backbuffer)
16951695
{
16961696
const gl::State &glState = getState();
16971697
FramebufferMtl *framebuffer = mtl::GetImpl(glState.getDrawFramebuffer());

src/libANGLE/renderer/metal/DisplayMtl.mm

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,13 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override
183183
EGLNativeWindowType window,
184184
const egl::AttributeMap &attribs)
185185
{
186-
return new SurfaceMtl(this, state, window, attribs);
186+
return new WindowSurfaceMtl(this, state, window, attribs);
187187
}
188188

189189
SurfaceImpl *DisplayMtl::createPbufferSurface(const egl::SurfaceState &state,
190190
const egl::AttributeMap &attribs)
191191
{
192-
UNIMPLEMENTED();
193-
return static_cast<SurfaceImpl *>(0);
192+
return new PBufferSurfaceMtl(this, state, attribs);
194193
}
195194

196195
SurfaceImpl *DisplayMtl::createPbufferFromClientBuffer(const egl::SurfaceState &state,
@@ -336,9 +335,9 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override
336335
config.sampleBuffers = 0;
337336
config.level = 0;
338337
config.bindToTextureRGB = EGL_FALSE;
339-
config.bindToTextureRGBA = EGL_FALSE;
338+
config.bindToTextureRGBA = EGL_TRUE;
340339

341-
config.surfaceType = EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
340+
config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
342341

343342
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
344343
config.minSwapInterval = 0;
@@ -475,7 +474,7 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override
475474
mNativeCaps.maxElementIndex = std::numeric_limits<GLuint>::max() - 1;
476475
mNativeCaps.max3DTextureSize = 2048;
477476
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
478-
mNativeCaps.max2DTextureSize = 16384;
477+
mNativeCaps.max2DTextureSize = 16384;
479478
// On macOS exclude [[position]] from maxVaryingVectors.
480479
mNativeCaps.maxVaryingVectors = 31 - 1;
481480
mNativeCaps.maxVertexOutputComponents = mNativeCaps.maxFragmentInputComponents = 124 - 4;
@@ -504,11 +503,11 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override
504503
// on Intel and 64 on AMD for now.
505504
if ([mMetalDevice.get().name rangeOfString:@"Intel"].location != NSNotFound)
506505
{
507-
mNativeCaps.maxAliasedPointSize = 255;
506+
mNativeCaps.maxAliasedPointSize = 255;
508507
}
509508
else
510509
{
511-
mNativeCaps.maxAliasedPointSize = 64;
510+
mNativeCaps.maxAliasedPointSize = 64;
512511
}
513512

514513
mNativeCaps.minAliasedLineWidth = 1.0f;

src/libANGLE/renderer/metal/FrameBufferMtl.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@ namespace mtl
2323
class RenderCommandEncoder;
2424
} // namespace mtl
2525
class ContextMtl;
26-
class SurfaceMtl;
26+
class WindowSurfaceMtl;
2727

2828
class FramebufferMtl : public FramebufferImpl
2929
{
3030
public:
31-
explicit FramebufferMtl(const gl::FramebufferState &state, bool flipY, SurfaceMtl *backbuffer);
31+
explicit FramebufferMtl(const gl::FramebufferState &state,
32+
bool flipY,
33+
WindowSurfaceMtl *backbuffer);
3234
~FramebufferMtl() override;
3335
void destroy(const gl::Context *context) override;
3436

@@ -93,7 +95,7 @@ class FramebufferMtl : public FramebufferImpl
9395

9496
gl::Rectangle getCompleteRenderArea() const;
9597
int getSamples() const;
96-
SurfaceMtl *getAttachedBackbuffer() const { return mBackbuffer; }
98+
WindowSurfaceMtl *getAttachedBackbuffer() const { return mBackbuffer; }
9799

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

206-
SurfaceMtl *mBackbuffer = nullptr;
207-
const bool mFlipY = false;
208+
WindowSurfaceMtl *mBackbuffer = nullptr;
209+
const bool mFlipY = false;
208210

209211
mtl::BufferRef mReadPixelBuffer;
210212
};

src/libANGLE/renderer/metal/FrameBufferMtl.mm

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
// FramebufferMtl implementation
5050
FramebufferMtl::FramebufferMtl(const gl::FramebufferState &state,
5151
bool flipY,
52-
SurfaceMtl *backbuffer)
52+
WindowSurfaceMtl *backbuffer)
5353
: FramebufferImpl(state), mBackbuffer(backbuffer), mFlipY(flipY)
5454
{
5555
reset();
@@ -600,8 +600,7 @@ PackPixelsParams params(flippedArea, angleFormat, outputPitch, packState.reverse
600600
case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
601601
case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
602602
break;
603-
default:
604-
{
603+
default: {
605604
static_assert(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0, "FB dirty bits");
606605
if (dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX)
607606
{

src/libANGLE/renderer/metal/SurfaceMtl.h

Lines changed: 114 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#import <QuartzCore/CALayer.h>
1313
#import <QuartzCore/CAMetalLayer.h>
1414

15+
#include <unordered_map>
16+
1517
#include "libANGLE/renderer/FramebufferImpl.h"
1618
#include "libANGLE/renderer/SurfaceImpl.h"
1719
#include "libANGLE/renderer/metal/RenderTargetMtl.h"
@@ -29,7 +31,6 @@ class SurfaceMtl : public SurfaceImpl
2931
public:
3032
SurfaceMtl(DisplayMtl *display,
3133
const egl::SurfaceState &state,
32-
EGLNativeWindowType window,
3334
const egl::AttributeMap &attribs);
3435
~SurfaceMtl() override;
3536

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

62-
// width and height can change with client window resizing
6362
EGLint getWidth() const override;
6463
EGLint getHeight() const override;
6564

6665
EGLint isPostSubBufferSupported() const override;
6766
EGLint getSwapBehavior() const override;
6867

68+
const mtl::TextureRef &getColorTexture() { return mColorTexture; }
69+
const mtl::Format &getColorFormat() const { return mColorFormat; }
6970
int getSamples() const { return mSamples; }
70-
bool preserveBuffer() const { return mRetainBuffer; }
71+
72+
angle::Result getAttachmentRenderTarget(const gl::Context *context,
73+
GLenum binding,
74+
const gl::ImageIndex &imageIndex,
75+
GLsizei samples,
76+
FramebufferAttachmentRenderTarget **rtOut) override;
77+
78+
protected:
79+
// Ensure companion (MS, depth, stencil) textures' size is correct w.r.t color texture.
80+
angle::Result ensureCompanionTexturesSizeCorrect(const gl::Context *context,
81+
const gl::Extents &size);
82+
angle::Result resolveColorTextureIfNeeded(const gl::Context *context);
83+
84+
// Normal textures
85+
mtl::TextureRef mColorTexture;
86+
mtl::TextureRef mDepthTexture;
87+
mtl::TextureRef mStencilTexture;
88+
89+
// Implicit multisample texture
90+
mtl::TextureRef mMSColorTexture;
91+
92+
bool mUsePackedDepthStencil = false;
93+
bool mAutoResolveMSColorTexture = false;
94+
95+
mtl::Format mColorFormat;
96+
mtl::Format mDepthFormat;
97+
mtl::Format mStencilFormat;
98+
99+
int mSamples = 0;
100+
101+
RenderTargetMtl mColorRenderTarget;
102+
RenderTargetMtl mColorManualResolveRenderTarget;
103+
RenderTargetMtl mDepthRenderTarget;
104+
RenderTargetMtl mStencilRenderTarget;
105+
};
106+
107+
class WindowSurfaceMtl : public SurfaceMtl
108+
{
109+
public:
110+
WindowSurfaceMtl(DisplayMtl *display,
111+
const egl::SurfaceState &state,
112+
EGLNativeWindowType window,
113+
const egl::AttributeMap &attribs);
114+
~WindowSurfaceMtl() override;
115+
116+
void destroy(const egl::Display *display) override;
117+
118+
egl::Error initialize(const egl::Display *display) override;
119+
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
120+
const gl::FramebufferState &state) override;
121+
122+
egl::Error swap(const gl::Context *context) override;
123+
124+
void setSwapInterval(EGLint interval) override;
125+
void setSwapBehavior(EGLint behavior) override;
126+
EGLint getSwapBehavior() const override;
127+
128+
// width and height can change with client window resizing
129+
EGLint getWidth() const override;
130+
EGLint getHeight() const override;
71131

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

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

140+
bool preserveBuffer() const { return mRetainBuffer; }
141+
80142
private:
81143
angle::Result swapImpl(const gl::Context *context);
82144
angle::Result obtainNextDrawable(const gl::Context *context);
83-
angle::Result ensureTexturesSizeCorrect(const gl::Context *context);
145+
angle::Result ensureCompanionTexturesSizeCorrect(const gl::Context *context);
84146

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

160+
// Texture for preserving content of color buffer (used when multisample texture is not
161+
// enabled).
162+
mtl::TextureRef mRetainedColorTexture;
163+
164+
bool mRetainBuffer = false;
165+
98166
// Cache last known drawable size that is used by GL context. Can be used to detect resize
99167
// event. We don't use mMetalLayer.drawableSize directly since it might be changed internally by
100168
// metal runtime.
101169
CGSize mCurrentKnownDrawableSize;
170+
};
102171

103-
// Normal textures
104-
mtl::TextureRef mDrawableTexture;
105-
mtl::TextureRef mDepthTexture;
106-
mtl::TextureRef mStencilTexture;
172+
class OffscreenSurfaceMtl : public SurfaceMtl
173+
{
174+
public:
175+
OffscreenSurfaceMtl(DisplayMtl *display,
176+
const egl::SurfaceState &state,
177+
const egl::AttributeMap &attribs);
178+
~OffscreenSurfaceMtl() override;
107179

108-
// Implicit multisample texture
109-
mtl::TextureRef mMSColorTexture;
180+
void destroy(const egl::Display *display) override;
110181

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

114-
bool mUsePackedDepthStencil = false;
115-
bool mAutoResolveMSColorTexture = false;
184+
egl::Error bindTexImage(const gl::Context *context,
185+
gl::Texture *texture,
186+
EGLint buffer) override;
187+
egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
116188

117-
mtl::Format mColorFormat;
118-
mtl::Format mDepthFormat;
119-
mtl::Format mStencilFormat;
189+
angle::Result getAttachmentRenderTarget(const gl::Context *context,
190+
GLenum binding,
191+
const gl::ImageIndex &imageIndex,
192+
GLsizei samples,
193+
FramebufferAttachmentRenderTarget **rtOut) override;
120194

121-
int mSamples = 0;
122-
bool mRetainBuffer = false;
195+
// Get or create implicit MS color texture. Used by glFramebufferTexture2DMultisampleEXT()
196+
// after eglBindTexImage()
197+
angle::Result getAttachmentMSColorTexture(const gl::Context *context,
198+
GLsizei samples,
199+
mtl::TextureRef *texOut);
123200

124-
RenderTargetMtl mColorRenderTarget;
125-
RenderTargetMtl mColorManualResolveRenderTarget;
126-
RenderTargetMtl mDepthRenderTarget;
127-
RenderTargetMtl mStencilRenderTarget;
201+
protected:
202+
angle::Result ensureTexturesSizeCorrect(const gl::Context *context);
203+
204+
gl::Extents mSize;
205+
206+
std::unordered_map<GLsizei, mtl::TextureRef> mAttachmentMSColorTextures;
207+
};
208+
209+
class PBufferSurfaceMtl : public OffscreenSurfaceMtl
210+
{
211+
public:
212+
PBufferSurfaceMtl(DisplayMtl *display,
213+
const egl::SurfaceState &state,
214+
const egl::AttributeMap &attribs);
215+
216+
void setFixedWidth(EGLint width) override;
217+
void setFixedHeight(EGLint height) override;
128218
};
129219

130220
} // namespace rx

0 commit comments

Comments
 (0)