diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/Framebuffer.h')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/Framebuffer.h | 319 |
1 files changed, 252 insertions, 67 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/Framebuffer.h b/src/3rdparty/angle/src/libANGLE/Framebuffer.h index b07b59ac90..70223f0bc7 100644 --- a/src/3rdparty/angle/src/libANGLE/Framebuffer.h +++ b/src/3rdparty/angle/src/libANGLE/Framebuffer.h @@ -12,16 +12,18 @@ #include <vector> +#include "common/Optional.h" #include "common/angleutils.h" #include "libANGLE/Constants.h" #include "libANGLE/Debug.h" #include "libANGLE/Error.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/RefCountObject.h" +#include "libANGLE/signal_utils.h" namespace rx { -class ImplFactory; +class GLImplFactory; class FramebufferImpl; class RenderbufferImpl; class SurfaceImpl; @@ -29,98 +31,171 @@ class SurfaceImpl; namespace egl { +class Display; class Surface; } namespace gl { class Context; +class ContextState; +class Framebuffer; class Renderbuffer; class State; class Texture; class TextureCapsMap; +class ValidationContext; struct Caps; -struct Data; struct Extensions; struct ImageIndex; struct Rectangle; -class Framebuffer final : public LabeledObject +class FramebufferState final : angle::NonCopyable { public: + FramebufferState(); + explicit FramebufferState(const Caps &caps); + ~FramebufferState(); - class Data final : angle::NonCopyable + const std::string &getLabel(); + size_t getReadIndex() const; + + const FramebufferAttachment *getAttachment(GLenum attachment) const; + const FramebufferAttachment *getReadAttachment() const; + const FramebufferAttachment *getFirstNonNullAttachment() const; + const FramebufferAttachment *getFirstColorAttachment() const; + const FramebufferAttachment *getDepthOrStencilAttachment() const; + const FramebufferAttachment *getStencilOrDepthStencilAttachment() const; + const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const; + const FramebufferAttachment *getDepthAttachment() const; + const FramebufferAttachment *getStencilAttachment() const; + const FramebufferAttachment *getDepthStencilAttachment() const; + + const std::vector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; } + DrawBufferMask getEnabledDrawBuffers() const { return mEnabledDrawBuffers; } + GLenum getReadBufferState() const { return mReadBufferState; } + const std::vector<FramebufferAttachment> &getColorAttachments() const { - public: - explicit Data(); - explicit Data(const Caps &caps); - ~Data(); + return mColorAttachments; + } - const std::string &getLabel(); + bool attachmentsHaveSameDimensions() const; + bool colorAttachmentsAreUniqueImages() const; + Box getDimensions() const; - const FramebufferAttachment *getReadAttachment() const; - const FramebufferAttachment *getFirstColorAttachment() const; - const FramebufferAttachment *getDepthOrStencilAttachment() const; - const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const; - const FramebufferAttachment *getDepthAttachment() const; - const FramebufferAttachment *getStencilAttachment() const; - const FramebufferAttachment *getDepthStencilAttachment() const; + const FramebufferAttachment *getDrawBuffer(size_t drawBufferIdx) const; + size_t getDrawBufferCount() const; - const std::vector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; } - GLenum getReadBufferState() const { return mReadBufferState; } - const std::vector<FramebufferAttachment> &getColorAttachments() const { return mColorAttachments; } + GLint getDefaultWidth() const { return mDefaultWidth; }; + GLint getDefaultHeight() const { return mDefaultHeight; }; + GLint getDefaultSamples() const { return mDefaultSamples; }; + bool getDefaultFixedSampleLocations() const { return mDefaultFixedSampleLocations; }; - bool attachmentsHaveSameDimensions() const; + bool hasDepth() const; + bool hasStencil() const; - private: - friend class Framebuffer; + GLenum getMultiviewLayout() const; + GLsizei getNumViews() const; + const std::vector<Offset> *getViewportOffsets() const; + GLint getBaseViewIndex() const; - std::string mLabel; + private: + friend class Framebuffer; - std::vector<FramebufferAttachment> mColorAttachments; - FramebufferAttachment mDepthAttachment; - FramebufferAttachment mStencilAttachment; + std::string mLabel; - std::vector<GLenum> mDrawBufferStates; - GLenum mReadBufferState; - }; + std::vector<FramebufferAttachment> mColorAttachments; + FramebufferAttachment mDepthAttachment; + FramebufferAttachment mStencilAttachment; - Framebuffer(const Caps &caps, rx::ImplFactory *factory, GLuint id); - Framebuffer(rx::SurfaceImpl *surface); - virtual ~Framebuffer(); + std::vector<GLenum> mDrawBufferStates; + GLenum mReadBufferState; + DrawBufferMask mEnabledDrawBuffers; + + GLint mDefaultWidth; + GLint mDefaultHeight; + GLint mDefaultSamples; + bool mDefaultFixedSampleLocations; + + // It's necessary to store all this extra state so we can restore attachments + // when DEPTH_STENCIL/DEPTH/STENCIL is unbound in WebGL 1. + FramebufferAttachment mWebGLDepthStencilAttachment; + FramebufferAttachment mWebGLDepthAttachment; + FramebufferAttachment mWebGLStencilAttachment; + bool mWebGLDepthStencilConsistent; + + // Tracks if we need to initialize the resources for each attachment. + angle::BitSet<IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS + 2> mResourceNeedsInit; +}; + +class Framebuffer final : public LabeledObject, public OnAttachmentDirtyReceiver +{ + public: + // Constructor to build application-defined framebuffers + Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id); + // Constructor to build default framebuffers for a surface + Framebuffer(const egl::Display *display, egl::Surface *surface); + // Constructor to build a fake default framebuffer when surfaceless + Framebuffer(rx::GLImplFactory *factory); + + ~Framebuffer() override; + void onDestroy(const Context *context); + void destroyDefault(const egl::Display *display); void setLabel(const std::string &label) override; const std::string &getLabel() const override; - const rx::FramebufferImpl *getImplementation() const { return mImpl; } - rx::FramebufferImpl *getImplementation() { return mImpl; } + rx::FramebufferImpl *getImplementation() const { return mImpl; } GLuint id() const { return mId; } - void setAttachment(GLenum type, + void setAttachment(const Context *context, + GLenum type, GLenum binding, const ImageIndex &textureIndex, FramebufferAttachmentObject *resource); - void resetAttachment(GLenum binding); - - void detachTexture(GLuint texture); - void detachRenderbuffer(GLuint renderbuffer); + void setAttachmentMultiviewLayered(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLint baseViewIndex); + void setAttachmentMultiviewSideBySide(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + const GLint *viewportOffsets); + void resetAttachment(const Context *context, GLenum binding); + + bool detachTexture(const Context *context, GLuint texture); + bool detachRenderbuffer(const Context *context, GLuint renderbuffer); const FramebufferAttachment *getColorbuffer(size_t colorAttachment) const; const FramebufferAttachment *getDepthbuffer() const; const FramebufferAttachment *getStencilbuffer() const; const FramebufferAttachment *getDepthStencilBuffer() const; const FramebufferAttachment *getDepthOrStencilbuffer() const; + const FramebufferAttachment *getStencilOrDepthStencilAttachment() const; const FramebufferAttachment *getReadColorbuffer() const; GLenum getReadColorbufferType() const; const FramebufferAttachment *getFirstColorbuffer() const; + const FramebufferAttachment *getFirstNonNullAttachment() const; const FramebufferAttachment *getAttachment(GLenum attachment) const; + GLenum getMultiviewLayout() const; + GLsizei getNumViews() const; + GLint getBaseViewIndex() const; + const std::vector<Offset> *getViewportOffsets() const; size_t getDrawbufferStateCount() const; GLenum getDrawBufferState(size_t drawBuffer) const; + const std::vector<GLenum> &getDrawBufferStates() const; void setDrawBuffers(size_t count, const GLenum *buffers); const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const; + GLenum getDrawbufferWriteType(size_t drawBuffer) const; bool hasEnabledDrawBuffer() const; GLenum getReadBufferState() const; @@ -129,48 +204,81 @@ class Framebuffer final : public LabeledObject size_t getNumColorBuffers() const; bool hasDepth() const; bool hasStencil() const; - int getSamples(const gl::Data &data) const; + bool usingExtendedDrawBuffers() const; - GLenum checkStatus(const gl::Data &data) const; + // This method calls checkStatus. + int getSamples(const Context *context); + + Error getSamplePosition(size_t index, GLfloat *xy) const; + + GLint getDefaultWidth() const; + GLint getDefaultHeight() const; + GLint getDefaultSamples() const; + bool getDefaultFixedSampleLocations() const; + void setDefaultWidth(GLint defaultWidth); + void setDefaultHeight(GLint defaultHeight); + void setDefaultSamples(GLint defaultSamples); + void setDefaultFixedSampleLocations(bool defaultFixedSampleLocations); + + void invalidateCompletenessCache(); + + GLenum checkStatus(const Context *context); + + // TODO(jmadill): Remove this kludge. + GLenum checkStatus(const ValidationContext *context); + int getSamples(const ValidationContext *context); + + // For when we don't want to check completeness in getSamples(). + int getCachedSamples(const Context *context); + + // Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE. + bool complete(const Context *context); + bool cachedComplete() const; + bool hasValidDepthStencil() const; - Error discard(size_t count, const GLenum *attachments); - Error invalidate(size_t count, const GLenum *attachments); - Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area); + Error discard(const Context *context, size_t count, const GLenum *attachments); + Error invalidate(const Context *context, size_t count, const GLenum *attachments); + Error invalidateSub(const Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area); - Error clear(const gl::Data &data, GLbitfield mask); - Error clearBufferfv(const gl::Data &data, + Error clear(const gl::Context *context, GLbitfield mask); + Error clearBufferfv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *values); - Error clearBufferuiv(const gl::Data &data, + Error clearBufferuiv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLuint *values); - Error clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values); - Error clearBufferfi(const gl::Data &data, + Error clearBufferiv(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + const GLint *values); + Error clearBufferfi(const gl::Context *context, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); - GLenum getImplementationColorReadFormat() const; - GLenum getImplementationColorReadType() const; - Error readPixels(const gl::State &state, + GLenum getImplementationColorReadFormat(const Context *context) const; + GLenum getImplementationColorReadType(const Context *context) const; + Error readPixels(const gl::Context *context, const gl::Rectangle &area, GLenum format, GLenum type, - GLvoid *pixels) const; + void *pixels); - Error blit(const State &state, + Error blit(const gl::Context *context, const Rectangle &sourceArea, const Rectangle &destArea, GLbitfield mask, - GLenum filter, - const Framebuffer *sourceFramebuffer); + GLenum filter); - enum DirtyBitType + enum DirtyBitType : size_t { DIRTY_BIT_COLOR_ATTACHMENT_0, DIRTY_BIT_COLOR_ATTACHMENT_MAX = @@ -179,26 +287,103 @@ class Framebuffer final : public LabeledObject DIRTY_BIT_STENCIL_ATTACHMENT, DIRTY_BIT_DRAW_BUFFERS, DIRTY_BIT_READ_BUFFER, + DIRTY_BIT_DEFAULT_WIDTH, + DIRTY_BIT_DEFAULT_HEIGHT, + DIRTY_BIT_DEFAULT_SAMPLES, + DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS, DIRTY_BIT_UNKNOWN, - DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN, + DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN }; - typedef std::bitset<DIRTY_BIT_MAX> DirtyBits; + typedef angle::BitSet<DIRTY_BIT_MAX> DirtyBits; bool hasAnyDirtyBit() const { return mDirtyBits.any(); } - void syncState() const; + void syncState(const Context *context); - protected: - void detachResourceById(GLenum resourceType, GLuint resourceId); + // OnAttachmentChangedReceiver implementation + void signal(size_t dirtyBit, InitState state) override; - Data mData; + bool formsRenderingFeedbackLoopWith(const State &state) const; + bool formsCopyingFeedbackLoopWith(GLuint copyTextureID, + GLint copyTextureLevel, + GLint copyTextureLayer) const; + + Error ensureDrawAttachmentsInitialized(const Context *context); + Error ensureReadAttachmentInitialized(const Context *context, GLbitfield blitMask); + Box getDimensions() const; + + bool hasTextureAttachment(const Texture *texture) const; + + private: + bool detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId); + bool detachMatchingAttachment(const Context *context, + FramebufferAttachment *attachment, + GLenum matchType, + GLuint matchId, + size_t dirtyBit); + GLenum checkStatusImpl(const Context *context); + void setAttachment(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets); + void commitWebGL1DepthStencilIfConsistent(const Context *context, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets); + void setAttachmentImpl(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets); + void updateAttachment(const Context *context, + FramebufferAttachment *attachment, + size_t dirtyBit, + OnAttachmentDirtyBinding *onDirtyBinding, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets); + + void markDrawAttachmentsInitialized(bool color, bool depth, bool stencil); + void markBufferInitialized(GLenum bufferType, GLint bufferIndex); + Error ensureBufferInitialized(const Context *context, GLenum bufferType, GLint bufferIndex); + + // Checks that we have a partially masked clear: + // * some color channels are masked out + // * some stencil values are masked out + // * scissor test partially overlaps the framebuffer + bool partialClearNeedsInit(const Context *context, bool color, bool depth, bool stencil); + bool partialBufferClearNeedsInit(const Context *context, GLenum bufferType); + + FramebufferState mState; rx::FramebufferImpl *mImpl; GLuint mId; - // TODO(jmadill): See if we can make this non-mutable. - mutable DirtyBits mDirtyBits; + Optional<GLenum> mCachedStatus; + std::vector<OnAttachmentDirtyBinding> mDirtyColorAttachmentBindings; + OnAttachmentDirtyBinding mDirtyDepthAttachmentBinding; + OnAttachmentDirtyBinding mDirtyStencilAttachmentBinding; + + DirtyBits mDirtyBits; + + // A cache of attached textures for quick validation of feedback loops. + mutable Optional<std::set<const FramebufferAttachmentObject *>> mAttachedTextures; }; -} +} // namespace gl -#endif // LIBANGLE_FRAMEBUFFER_H_ +#endif // LIBANGLE_FRAMEBUFFER_H_ |