blob: 35e50449a7662c3a1bcd41b20bf7b8ee72d7fedc [file] [log] [blame]
 // // Copyright 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2 #ifndef LIBANGLE_ANGLETYPES_H_ #define LIBANGLE_ANGLETYPES_H_ #include "common/Color.h" #include "common/FixedVector.h" #include "common/PackedEnums.h" #include "common/bitset_utils.h" #include "common/vector_utils.h" #include "libANGLE/Constants.h" #include "libANGLE/Error.h" #include "libANGLE/RefCountObject.h" #include "nb/cpp14oncpp11.h" #include #include #include #include #include namespace gl { class Buffer; class Texture; struct Rectangle { Rectangle() : x(0), y(0), width(0), height(0) {} constexpr Rectangle(int x_in, int y_in, int width_in, int height_in) : x(x_in), y(y_in), width(width_in), height(height_in) {} int x0() const { return x; } int y0() const { return y; } int x1() const { return x + width; } int y1() const { return y + height; } bool isReversedX() const { return width < 0; } bool isReversedY() const { return height < 0; } // Returns a rectangle with the same area but flipped in X, Y, neither or both. Rectangle flip(bool flipX, bool flipY) const; // Returns a rectangle with the same area but with height and width guaranteed to be positive. Rectangle removeReversal() const; bool encloses(const gl::Rectangle &inside) const; int x; int y; int width; int height; }; bool operator==(const Rectangle &a, const Rectangle &b); bool operator!=(const Rectangle &a, const Rectangle &b); bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection); struct Offset { constexpr Offset() : x(0), y(0), z(0) {} constexpr Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) {} int x; int y; int z; }; constexpr Offset kOffsetZero(0, 0, 0); bool operator==(const Offset &a, const Offset &b); bool operator!=(const Offset &a, const Offset &b); struct Extents { Extents() : width(0), height(0), depth(0) {} Extents(int width_, int height_, int depth_) : width(width_), height(height_), depth(depth_) {} Extents(const Extents &other) = default; Extents &operator=(const Extents &other) = default; bool empty() const { return (width * height * depth) == 0; } int width; int height; int depth; }; bool operator==(const Extents &lhs, const Extents &rhs); bool operator!=(const Extents &lhs, const Extents &rhs); struct Box { Box() : x(0), y(0), z(0), width(0), height(0), depth(0) {} Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in) : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in) {} Box(const Offset &offset, const Extents &size) : x(offset.x), y(offset.y), z(offset.z), width(size.width), height(size.height), depth(size.depth) {} bool operator==(const Box &other) const; bool operator!=(const Box &other) const; Rectangle toRect() const; int x; int y; int z; int width; int height; int depth; }; struct RasterizerState final { // This will zero-initialize the struct, including padding. RasterizerState(); bool cullFace; CullFaceMode cullMode; GLenum frontFace; bool polygonOffsetFill; GLfloat polygonOffsetFactor; GLfloat polygonOffsetUnits; bool pointDrawMode; bool multiSample; bool rasterizerDiscard; }; bool operator==(const RasterizerState &a, const RasterizerState &b); bool operator!=(const RasterizerState &a, const RasterizerState &b); struct BlendState final { // This will zero-initialize the struct, including padding. BlendState(); BlendState(const BlendState &other); bool allChannelsMasked() const; bool blend; GLenum sourceBlendRGB; GLenum destBlendRGB; GLenum sourceBlendAlpha; GLenum destBlendAlpha; GLenum blendEquationRGB; GLenum blendEquationAlpha; bool colorMaskRed; bool colorMaskGreen; bool colorMaskBlue; bool colorMaskAlpha; bool sampleAlphaToCoverage; bool dither; }; bool operator==(const BlendState &a, const BlendState &b); bool operator!=(const BlendState &a, const BlendState &b); struct DepthStencilState final { // This will zero-initialize the struct, including padding. DepthStencilState(); DepthStencilState(const DepthStencilState &other); bool depthTest; GLenum depthFunc; bool depthMask; bool stencilTest; GLenum stencilFunc; GLuint stencilMask; GLenum stencilFail; GLenum stencilPassDepthFail; GLenum stencilPassDepthPass; GLuint stencilWritemask; GLenum stencilBackFunc; GLuint stencilBackMask; GLenum stencilBackFail; GLenum stencilBackPassDepthFail; GLenum stencilBackPassDepthPass; GLuint stencilBackWritemask; }; bool operator==(const DepthStencilState &a, const DepthStencilState &b); bool operator!=(const DepthStencilState &a, const DepthStencilState &b); // Packs a sampler state for completeness checks: // * minFilter: 5 values (3 bits) // * magFilter: 2 values (1 bit) // * wrapS: 3 values (2 bits) // * wrapT: 3 values (2 bits) // * compareMode: 1 bit (for == GL_NONE). // This makes a total of 9 bits. We can pack this easily into 32 bits: // * minFilter: 8 bits // * magFilter: 8 bits // * wrapS: 8 bits // * wrapT: 4 bits // * compareMode: 4 bits struct PackedSamplerCompleteness { uint8_t minFilter; uint8_t magFilter; uint8_t wrapS; uint8_t wrapTCompareMode; }; static_assert(sizeof(PackedSamplerCompleteness) == sizeof(uint32_t), "Unexpected size"); // State from Table 6.10 (state per sampler object) class SamplerState final { public: // This will zero-initialize the struct, including padding. SamplerState(); SamplerState(const SamplerState &other); static SamplerState CreateDefaultForTarget(TextureType type); GLenum getMinFilter() const { return mMinFilter; } void setMinFilter(GLenum minFilter); GLenum getMagFilter() const { return mMagFilter; } void setMagFilter(GLenum magFilter); GLenum getWrapS() const { return mWrapS; } void setWrapS(GLenum wrapS); GLenum getWrapT() const { return mWrapT; } void setWrapT(GLenum wrapT); GLenum getWrapR() const { return mWrapR; } void setWrapR(GLenum wrapR); float getMaxAnisotropy() const { return mMaxAnisotropy; } void setMaxAnisotropy(float maxAnisotropy); GLfloat getMinLod() const { return mMinLod; } void setMinLod(GLfloat minLod); GLfloat getMaxLod() const { return mMaxLod; } void setMaxLod(GLfloat maxLod); GLenum getCompareMode() const { return mCompareMode; } void setCompareMode(GLenum compareMode); GLenum getCompareFunc() const { return mCompareFunc; } void setCompareFunc(GLenum compareFunc); GLenum getSRGBDecode() const { return mSRGBDecode; } void setSRGBDecode(GLenum sRGBDecode); void setBorderColor(const ColorGeneric &color); const ColorGeneric &getBorderColor() const { return mBorderColor; } bool sameCompleteness(const SamplerState &samplerState) const { return mCompleteness.packed == samplerState.mCompleteness.packed; } private: void updateWrapTCompareMode(); GLenum mMinFilter; GLenum mMagFilter; GLenum mWrapS; GLenum mWrapT; GLenum mWrapR; // From EXT_texture_filter_anisotropic float mMaxAnisotropy; GLfloat mMinLod; GLfloat mMaxLod; GLenum mCompareMode; GLenum mCompareFunc; GLenum mSRGBDecode; ColorGeneric mBorderColor; union Completeness { uint32_t packed; PackedSamplerCompleteness typed; }; Completeness mCompleteness; }; bool operator==(const SamplerState &a, const SamplerState &b); bool operator!=(const SamplerState &a, const SamplerState &b); struct DrawArraysIndirectCommand { GLuint count; GLuint instanceCount; GLuint first; GLuint baseInstance; }; static_assert(sizeof(DrawArraysIndirectCommand) == 16, "Unexpected size of DrawArraysIndirectCommand"); struct DrawElementsIndirectCommand { GLuint count; GLuint primCount; GLuint firstIndex; GLint baseVertex; GLuint baseInstance; }; static_assert(sizeof(DrawElementsIndirectCommand) == 20, "Unexpected size of DrawElementsIndirectCommand"); struct ImageUnit { ImageUnit(); ImageUnit(const ImageUnit &other); ~ImageUnit(); BindingPointer texture; GLint level; GLboolean layered; GLint layer; GLenum access; GLenum format; }; using ImageUnitTextureTypeMap = std::map; struct PixelStoreStateBase { GLint alignment = 4; GLint rowLength = 0; GLint skipRows = 0; GLint skipPixels = 0; GLint imageHeight = 0; GLint skipImages = 0; }; struct PixelUnpackState : PixelStoreStateBase {}; struct PixelPackState : PixelStoreStateBase { bool reverseRowOrder = false; }; // Used in Program and VertexArray. using AttributesMask = angle::BitSet; // Used in Program using UniformBlockBindingMask = angle::BitSet; // Used in Framebuffer / Program using DrawBufferMask = angle::BitSet; // Used in StateCache using StorageBuffersMask = angle::BitSet; template using TexLevelArray = std::array; enum class ComponentType { Float = 0, Int = 1, UnsignedInt = 2, NoType = 3, EnumCount = 4, InvalidEnum = 4, }; CONSTEXPR_OR_INLINE ComponentType GLenumToComponentType(GLenum componentType) { switch (componentType) { case GL_FLOAT: return ComponentType::Float; case GL_INT: return ComponentType::Int; case GL_UNSIGNED_INT: return ComponentType::UnsignedInt; case GL_NONE: return ComponentType::NoType; default: return ComponentType::InvalidEnum; } } extern CONSTEXPR angle::PackedEnumMap kComponentMasks; constexpr size_t kMaxComponentTypeMaskIndex = 16; using ComponentTypeMask = angle::BitSet; ANGLE_INLINE void SetComponentTypeMask(ComponentType type, size_t index, ComponentTypeMask *mask) { ASSERT(index <= kMaxComponentTypeMaskIndex); *mask &= ~(0x10001 << index); *mask |= kComponentMasks[type] << index; } ANGLE_INLINE ComponentType GetComponentTypeMask(const ComponentTypeMask &mask, size_t index) { ASSERT(index <= kMaxComponentTypeMaskIndex); uint32_t mask_bits = static_cast((mask.to_ulong() >> index) & 0x10001); switch (mask_bits) { case 0x10001: return ComponentType::Float; case 0x00001: return ComponentType::Int; case 0x10000: return ComponentType::UnsignedInt; default: return ComponentType::InvalidEnum; } } bool ValidateComponentTypeMasks(unsigned long outputTypes, unsigned long inputTypes, unsigned long outputMask, unsigned long inputMask); using ContextID = uintptr_t; constexpr size_t kCubeFaceCount = 6; template using TextureTypeMap = angle::PackedEnumMap; using TextureMap = TextureTypeMap>; // ShaderVector can contain one item per shader. It differs from ShaderMap in that the values are // not indexed by ShaderType. template using ShaderVector = angle::FixedVector(ShaderType::EnumCount)>; template using AttachmentArray = std::array; template using DrawBuffersArray = std::array; template using DrawBuffersVector = angle::FixedVector; template using AttribArray = std::array; using ActiveTextureMask = angle::BitSet; template using ActiveTextureArray = std::array; using ActiveTexturePointerArray = ActiveTextureArray; using ActiveTextureTypeArray = ActiveTextureArray; template using UniformBuffersArray = std::array; template using StorageBuffersArray = std::array; template using AtomicCounterBuffersArray = std::array; using AtomicCounterBufferMask = angle::BitSet; template using ImagesArray = std::array; using ImageUnitMask = angle::BitSet; using SupportedSampleSet = std::set; template using TransformFeedbackBuffersArray = std::array; constexpr size_t kBarrierVectorDefaultSize = 16; template using BarrierVector = angle::FastVector; using BufferBarrierVector = BarrierVector; struct TextureAndLayout { Texture *texture; GLenum layout; }; using TextureBarrierVector = BarrierVector; // OffsetBindingPointer.getSize() returns the size specified by the user, which may be larger than // the size of the bound buffer. This function reduces the returned size to fit the bound buffer if // necessary. Returns 0 if no buffer is bound or if integer overflow occurs. GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer &binding); } // namespace gl namespace rx { // A macro that determines whether an object has a given runtime type. #if defined(__clang__) # if __has_feature(cxx_rtti) # define ANGLE_HAS_DYNAMIC_CAST 1 # endif #elif !defined(NDEBUG) && (!defined(_MSC_VER) || defined(_CPPRTTI)) && \ (!defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || \ defined(__GXX_RTTI)) # define ANGLE_HAS_DYNAMIC_CAST 1 #endif #ifdef ANGLE_HAS_DYNAMIC_CAST # define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (dynamic_cast(obj) != nullptr) # undef ANGLE_HAS_DYNAMIC_CAST #else # define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (obj != nullptr) #endif // Downcast a base implementation object (EG TextureImpl to TextureD3D) template inline DestT *GetAs(SrcT *src) { ASSERT(ANGLE_HAS_DYNAMIC_TYPE(DestT *, src)); return static_cast(src); } template inline const DestT *GetAs(const SrcT *src) { ASSERT(ANGLE_HAS_DYNAMIC_TYPE(const DestT *, src)); return static_cast(src); } #undef ANGLE_HAS_DYNAMIC_TYPE // Downcast a GL object to an Impl (EG gl::Texture to rx::TextureD3D) template inline DestT *GetImplAs(SrcT *src) { return GetAs(src->getImplementation()); } template inline DestT *SafeGetImplAs(SrcT *src) { return src != nullptr ? GetAs(src->getImplementation()) : nullptr; } } // namespace rx #include "angletypes.inc" namespace angle { // Zero-based for better array indexing enum FramebufferBinding { FramebufferBindingRead = 0, FramebufferBindingDraw, FramebufferBindingSingletonMax, FramebufferBindingBoth = FramebufferBindingSingletonMax, FramebufferBindingMax, FramebufferBindingUnknown = FramebufferBindingMax, }; inline FramebufferBinding EnumToFramebufferBinding(GLenum enumValue) { switch (enumValue) { case GL_READ_FRAMEBUFFER: return FramebufferBindingRead; case GL_DRAW_FRAMEBUFFER: return FramebufferBindingDraw; case GL_FRAMEBUFFER: return FramebufferBindingBoth; default: UNREACHABLE(); return FramebufferBindingUnknown; } } inline GLenum FramebufferBindingToEnum(FramebufferBinding binding) { switch (binding) { case FramebufferBindingRead: return GL_READ_FRAMEBUFFER; case FramebufferBindingDraw: return GL_DRAW_FRAMEBUFFER; case FramebufferBindingBoth: return GL_FRAMEBUFFER; default: UNREACHABLE(); return GL_NONE; } } template class DestroyThenDelete { public: DestroyThenDelete(const ContextT *context) : mContext(context) {} void operator()(ObjT *obj) { (void)(obj->onDestroy(mContext)); delete obj; } private: const ContextT *mContext; }; // Helper class for wrapping an onDestroy function. template class UniqueObjectPointerBase : angle::NonCopyable { public: template UniqueObjectPointerBase(const ContextT *context) : mObject(nullptr), mDeleter(context) {} template UniqueObjectPointerBase(ObjT *obj, const ContextT *context) : mObject(obj), mDeleter(context) {} ~UniqueObjectPointerBase() { if (mObject) { mDeleter(mObject); } } ObjT *operator->() const { return mObject; } ObjT *release() { auto obj = mObject; mObject = nullptr; return obj; } ObjT *get() const { return mObject; } void reset(ObjT *obj) { if (mObject) { mDeleter(mObject); } mObject = obj; } private: ObjT *mObject; DeleterT mDeleter; }; template using UniqueObjectPointer = UniqueObjectPointerBase>; } // namespace angle namespace gl { class State; } // namespace gl #endif // LIBANGLE_ANGLETYPES_H_