diff --git a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp index 0beff124..1e7293d8 100644 --- a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp @@ -61,8 +61,8 @@ namespace MobileGL { return; } - BufferMappingAccessBit mappingAccess = bufferObject->GetMappingAccess(); - if(!Any(mappingAccess & BufferMappingAccessBit::FlushExplicit)) { + auto mappingAccess = bufferObject->GetMappingAccess(); + if(!(mappingAccess & BufferMappingAccessBit::FlushExplicit)) { MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, MakeShared("MG_Impl/GLImpl", "FlushMappedBufferRange_State", "Cannot flush a buffer object that is not mapped with GL_MAP_FLUSH_EXPLICIT_BIT.")); @@ -134,19 +134,19 @@ namespace MobileGL { auto accessBits = MG_Util::ConvertGLEnumToBufferMappingAccess(access); if (!BufferImpl::ValidateBufferMappingAccess(accessBits)) return nullptr; - if (!Any(accessBits & (BufferMappingAccessBit::Read | BufferMappingAccessBit::Write))) { + if (!(accessBits & (BufferMappingAccessBit::Read | BufferMappingAccessBit::Write))) { MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, MakeShared("MG_Impl/GLImpl", "MapBufferRange_State", "At least one of GL_MAP_READ_BIT or GL_MAP_WRITE_BIT must be set.")); return nullptr; } - if (Any(accessBits & BufferMappingAccessBit::Read)) { + if (accessBits & BufferMappingAccessBit::Read) { const auto invalidFlags = BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer | BufferMappingAccessBit::Unsynchronized; - if (Any(accessBits & invalidFlags)) { + if (accessBits & invalidFlags) { MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, MakeShared("MG_Impl/GLImpl", "MapBufferRange_State", "GL_MAP_READ_BIT cannot be combined with invalidation or unsynchronized flags.")); @@ -154,8 +154,8 @@ namespace MobileGL { } } - if (Any(accessBits & BufferMappingAccessBit::FlushExplicit)) { - if (!(Any(accessBits & BufferMappingAccessBit::Write))) { + if (accessBits & BufferMappingAccessBit::FlushExplicit) { + if (!(accessBits & BufferMappingAccessBit::Write)) { MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, MakeShared("MG_Impl/GLImpl", "MapBufferRange_State", "GL_MAP_FLUSH_EXPLICIT_BIT requires GL_MAP_WRITE_BIT.")); @@ -163,10 +163,10 @@ namespace MobileGL { } } - const BufferMappingAccessBit storageFlags = + const auto storageFlags = BufferMappingAccessBit::Persistent | BufferMappingAccessBit::Coherent; - BufferMappingAccessBit requiredFlags = accessBits & storageFlags; - if (Any(requiredFlags)) { + auto requiredFlags = accessBits & storageFlags; + if (requiredFlags) { // TODO: check if the buffer data is created by BufferStorage and its flags after its implementation MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, MakeShared("MG_Impl/GLImpl", "MapBufferRange_State", @@ -178,7 +178,7 @@ namespace MobileGL { const auto invalidateFlags = BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer; - if (!Any(accessBits & invalidateFlags)) { + if (!(accessBits & invalidateFlags)) { MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, MakeShared("MG_Impl/GLImpl", "MapBufferRange_State", "Cannot map a buffer object that is already mapped.")); @@ -280,7 +280,7 @@ namespace MobileGL { } auto isIllegallyMapped = [](const SharedPtr& buffer) { - return buffer->IsMapped() && !Any(buffer->GetMappingAccess() & BufferMappingAccessBit::Persistent); + return buffer->IsMapped() && !(buffer->GetMappingAccess() & BufferMappingAccessBit::Persistent); }; if (isIllegallyMapped(readBufferObject) || isIllegallyMapped(writeBufferObject)) { MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, @@ -328,8 +328,8 @@ namespace MobileGL { return; } - BufferMappingAccessBit mappingAccess = bufferObject->GetMappingAccess(); - if (bufferObject->IsMapped() && !Any(mappingAccess & BufferMappingAccessBit::Persistent)) { + auto mappingAccess = bufferObject->GetMappingAccess(); + if (bufferObject->IsMapped() && !(mappingAccess & BufferMappingAccessBit::Persistent)) { Range1D mappedRange = bufferObject->GetMappedRange(); if (offset + size >= mappedRange.start) { MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, diff --git a/MobileGL/MG_Impl/GLImpl/Buffer/Validators.cpp b/MobileGL/MG_Impl/GLImpl/Buffer/Validators.cpp index 82430131..91e58e5c 100644 --- a/MobileGL/MG_Impl/GLImpl/Buffer/Validators.cpp +++ b/MobileGL/MG_Impl/GLImpl/Buffer/Validators.cpp @@ -48,7 +48,7 @@ namespace MobileGL::MG_Impl::GLImpl { return false; } - bool ValidateBufferMappingAccess(BufferMappingAccessBit accessBits) { + bool ValidateBufferMappingAccess(Flags accessBits) { if (accessBits == BufferMappingAccessBit::Null) { MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum, MakeShared("MG_Impl/GLImpl/BufferImpl", "ValidateBufferMappingAccess", @@ -56,7 +56,7 @@ namespace MobileGL::MG_Impl::GLImpl { return false; } - const BufferMappingAccessBit validBits = + const auto validBits = BufferMappingAccessBit::Read | BufferMappingAccessBit::Write | BufferMappingAccessBit::InvalidateRange | diff --git a/MobileGL/MG_Impl/GLImpl/Buffer/Validators.h b/MobileGL/MG_Impl/GLImpl/Buffer/Validators.h index 16df8c3d..25539a3c 100644 --- a/MobileGL/MG_Impl/GLImpl/Buffer/Validators.h +++ b/MobileGL/MG_Impl/GLImpl/Buffer/Validators.h @@ -5,6 +5,6 @@ namespace MobileGL::MG_Impl::GLImpl { bool ValidateBufferTarget(BufferTarget target); bool ValidateBufferName(Uint index); bool ValidateBufferUsage(BufferUsage usage); - bool ValidateBufferMappingAccess(BufferMappingAccessBit accessBits); + bool ValidateBufferMappingAccess(Flags accessBits); } } \ No newline at end of file diff --git a/MobileGL/MG_State/GLState/BufferState/BufferObject.cpp b/MobileGL/MG_State/GLState/BufferState/BufferObject.cpp index 990bf56d..0e363b73 100644 --- a/MobileGL/MG_State/GLState/BufferState/BufferObject.cpp +++ b/MobileGL/MG_State/GLState/BufferState/BufferObject.cpp @@ -30,8 +30,8 @@ namespace MobileGL { void BufferObject::ReleaseMemory() { if (!m_isMapped) return; - if (Any(m_mappingAccess & BufferMappingAccessBit::Write)) { // if we wrote to the buffer - if (!Any(m_mappingAccess & BufferMappingAccessBit::FlushExplicit)) { // if we didn't flush explicitly + if (m_mappingAccess & BufferMappingAccessBit::Write) { // if we wrote to the buffer + if (!(m_mappingAccess & BufferMappingAccessBit::FlushExplicit)) { // if we didn't flush explicitly memcpy(m_data.data() + m_mappedRange.start, m_stagingData.data(), m_mappedRange.end - m_mappedRange.start); @@ -49,8 +49,8 @@ namespace MobileGL { void BufferObject::FlushMemoryRange(SizeT offset, SizeT length) { assert(m_isMapped); - assert(Any(m_mappingAccess & BufferMappingAccessBit::FlushExplicit)); - assert(Any(m_mappingAccess & BufferMappingAccessBit::Write)); + assert((m_mappingAccess & BufferMappingAccessBit::FlushExplicit)); + assert((m_mappingAccess & BufferMappingAccessBit::Write)); SizeT start = m_mappedRange.start + offset; SizeT end = start + length; @@ -82,16 +82,17 @@ namespace MobileGL { void* BufferObject::AcquireMemory(Bool markMapped, Bool read, Bool write) { if (markMapped) { m_isMapped = true; + auto a = BufferMappingAccessBit::Coherent | BufferMappingAccessBit::Read; m_mappingAccess = (read ? BufferMappingAccessBit::Read : BufferMappingAccessBit::Null) | (write ? BufferMappingAccessBit::Write : BufferMappingAccessBit::Null); m_mappedRange = { 0, m_size }; - if (Any(m_mappingAccess & BufferMappingAccessBit::Write)) { + if (m_mappingAccess & BufferMappingAccessBit::Write) { m_stagingData.resize(m_size); m_ownsStagingData = true; - if (!Any(m_mappingAccess & (BufferMappingAccessBit::InvalidateRange | + if (!(m_mappingAccess & (BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer))) { memcpy(m_stagingData.data(), m_data.data(), m_size); } @@ -103,17 +104,17 @@ namespace MobileGL { return m_data.data(); } - void* BufferObject::AcquireMemoryRange(Range1D range, BufferMappingAccessBit access) { + void* BufferObject::AcquireMemoryRange(Range1D range, Flags access) { assert(range.end <= m_size && range.start <= range.end); m_isMapped = true; m_mappingAccess = access; m_mappedRange = range; - if (Any(access & BufferMappingAccessBit::Write)) { + if (access & BufferMappingAccessBit::Write) { m_stagingData.resize(range.end - range.start); m_ownsStagingData = true; - if (!Any(access & (BufferMappingAccessBit::InvalidateRange | + if (!(access & (BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer))) { memcpy(m_stagingData.data(), m_data.data() + range.start, m_stagingData.size()); } @@ -150,7 +151,7 @@ namespace MobileGL { return m_isMapped ? m_mappedRange : Range1D{ 0, 0 }; } - BufferMappingAccessBit BufferObject::GetMappingAccess() const { + Flags BufferObject::GetMappingAccess() const { return m_isMapped ? m_mappingAccess : BufferMappingAccessBit::Null; } } diff --git a/MobileGL/MG_State/GLState/BufferState/BufferObject.h b/MobileGL/MG_State/GLState/BufferState/BufferObject.h index 7f46ed6f..bcbf3b47 100644 --- a/MobileGL/MG_State/GLState/BufferState/BufferObject.h +++ b/MobileGL/MG_State/GLState/BufferState/BufferObject.h @@ -1,4 +1,5 @@ #pragma once +#include "MG_Util/Types.h" namespace MobileGL { enum class BufferTarget { @@ -45,25 +46,23 @@ namespace MobileGL { Coherent = 0x80 }; - inline BufferMappingAccessBit operator|(BufferMappingAccessBit a, BufferMappingAccessBit b) { - using T = std::underlying_type_t; - return static_cast(static_cast(a) | static_cast(b)); - } + // inline Flags operator|(BufferMappingAccessBit a, const BufferMappingAccessBit b) { + // return Flags(a) | b; + // } + // + // inline BufferMappingAccessBit& operator|=(BufferMappingAccessBit& a, BufferMappingAccessBit b) { + // a = a | b; + // return a; + // } - inline BufferMappingAccessBit& operator|=(BufferMappingAccessBit& a, BufferMappingAccessBit b) { - a = a | b; - return a; - } + // inline Flags operator&(const BufferMappingAccessBit a, const BufferMappingAccessBit b) { + // return Flags(a) & b; + // } - inline BufferMappingAccessBit operator&(BufferMappingAccessBit a, BufferMappingAccessBit b) { - using T = std::underlying_type_t; - return static_cast(static_cast(a) & static_cast(b)); - } - - inline bool Any(BufferMappingAccessBit a) { - using T = std::underlying_type_t; - return static_cast(a) != 0; - } + // inline bool Any(BufferMappingAccessBit a) { + // using T = std::underlying_type_t; + // return static_cast(a) != 0; + // } namespace MG_State { namespace GLState { @@ -77,7 +76,7 @@ namespace MobileGL { void UploadData(DataPtr data, SizeT atOffset); void SetUsage(BufferUsage usage); void* AcquireMemory(Bool markMapped, Bool read, Bool write); - void* AcquireMemoryRange(Range1D range, BufferMappingAccessBit access); + void* AcquireMemoryRange(Range1D range, Flags access); void ReleaseMemory(); void FlushMemoryRange(SizeT offset, SizeT length); void UploadSubData(DataPtr data, SizeT atOffset); @@ -89,14 +88,14 @@ namespace MobileGL { BufferUsage GetUsage() const; Range1D GetDirtyRange() const; Range1D GetMappedRange() const; - BufferMappingAccessBit GetMappingAccess() const; + Flags GetMappingAccess() const; private: Int m_id = 0; SizeT m_size = 0; BufferUsage m_usage = BufferUsage::StaticDraw; Data m_data; Bool m_isMapped; - BufferMappingAccessBit m_mappingAccess; + Flags m_mappingAccess; Range1D m_dirtyRange; Range1D m_mappedRange; std::vector m_stagingData; @@ -104,4 +103,4 @@ namespace MobileGL { }; } } -} \ No newline at end of file +} diff --git a/MobileGL/MG_Util/Converters/GLToMG/BufferEnumConverter.cpp b/MobileGL/MG_Util/Converters/GLToMG/BufferEnumConverter.cpp index 10ee459b..4a21e8d8 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/BufferEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/GLToMG/BufferEnumConverter.cpp @@ -38,8 +38,8 @@ namespace MobileGL { } } - BufferMappingAccessBit ConvertGLEnumToBufferMappingAccess(GLbitfield access) { - BufferMappingAccessBit result = BufferMappingAccessBit::Null; + Flags ConvertGLEnumToBufferMappingAccess(GLbitfield access) { + Flags result = BufferMappingAccessBit::Null; if (access & GL_MAP_READ_BIT) result |= BufferMappingAccessBit::Read; if (access & GL_MAP_WRITE_BIT) result |= BufferMappingAccessBit::Write; if (access & GL_MAP_INVALIDATE_RANGE_BIT) result |= BufferMappingAccessBit::InvalidateRange; diff --git a/MobileGL/MG_Util/Converters/GLToMG/BufferEnumConverter.h b/MobileGL/MG_Util/Converters/GLToMG/BufferEnumConverter.h index 5ee97dc7..e6b68ad3 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/BufferEnumConverter.h +++ b/MobileGL/MG_Util/Converters/GLToMG/BufferEnumConverter.h @@ -4,6 +4,6 @@ namespace MobileGL { namespace MG_Util { BufferTarget ConvertGLEnumToBufferTarget(GLenum bufferTarget); BufferUsage ConvertGLEnumToBufferUsage(GLenum usage); - BufferMappingAccessBit ConvertGLEnumToBufferMappingAccess(GLbitfield access); + Flags ConvertGLEnumToBufferMappingAccess(GLbitfield access); } } \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/MGToGL/BufferEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToGL/BufferEnumConverter.cpp index 2563e582..060673a6 100644 --- a/MobileGL/MG_Util/Converters/MGToGL/BufferEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToGL/BufferEnumConverter.cpp @@ -40,14 +40,14 @@ namespace MobileGL { GLbitfield ConvertBufferMappingAccessToGLEnum(BufferMappingAccessBit access) { GLbitfield result = 0; - if (Any(access & BufferMappingAccessBit::Read)) result |= GL_MAP_READ_BIT; - if (Any(access & BufferMappingAccessBit::Write)) result |= GL_MAP_WRITE_BIT; - if (Any(access & BufferMappingAccessBit::InvalidateRange)) result |= GL_MAP_INVALIDATE_RANGE_BIT; - if (Any(access & BufferMappingAccessBit::InvalidateBuffer)) result |= GL_MAP_INVALIDATE_BUFFER_BIT; - if (Any(access & BufferMappingAccessBit::FlushExplicit)) result |= GL_MAP_FLUSH_EXPLICIT_BIT; - if (Any(access & BufferMappingAccessBit::Unsynchronized)) result |= GL_MAP_UNSYNCHRONIZED_BIT; - if (Any(access & BufferMappingAccessBit::Persistent)) result |= GL_MAP_PERSISTENT_BIT; - if (Any(access & BufferMappingAccessBit::Coherent)) result |= GL_MAP_COHERENT_BIT; + if (access & BufferMappingAccessBit::Read) result |= GL_MAP_READ_BIT; + if (access & BufferMappingAccessBit::Write) result |= GL_MAP_WRITE_BIT; + if (access & BufferMappingAccessBit::InvalidateRange) result |= GL_MAP_INVALIDATE_RANGE_BIT; + if (access & BufferMappingAccessBit::InvalidateBuffer) result |= GL_MAP_INVALIDATE_BUFFER_BIT; + if (access & BufferMappingAccessBit::FlushExplicit) result |= GL_MAP_FLUSH_EXPLICIT_BIT; + if (access & BufferMappingAccessBit::Unsynchronized) result |= GL_MAP_UNSYNCHRONIZED_BIT; + if (access & BufferMappingAccessBit::Persistent) result |= GL_MAP_PERSISTENT_BIT; + if (access & BufferMappingAccessBit::Coherent) result |= GL_MAP_COHERENT_BIT; return result; } } diff --git a/MobileGL/MG_Util/Converters/MGToStr/BufferEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToStr/BufferEnumConverter.cpp index 9fe73797..f9833df2 100644 --- a/MobileGL/MG_Util/Converters/MGToStr/BufferEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToStr/BufferEnumConverter.cpp @@ -38,16 +38,16 @@ namespace MobileGL { } } - String ConvertBufferMappingAccessToString(BufferMappingAccessBit access) { + String ConvertBufferMappingAccessToString(Flags access) { String result = "["; - if (Any(access & BufferMappingAccessBit::Read)) result += "Read, "; - if (Any(access & BufferMappingAccessBit::Write)) result += "Write, "; - if (Any(access & BufferMappingAccessBit::InvalidateRange)) result += "InvalidateRange, "; - if (Any(access & BufferMappingAccessBit::InvalidateBuffer)) result += "InvalidateBuffer, "; - if (Any(access & BufferMappingAccessBit::FlushExplicit)) result += "FlushExplicit, "; - if (Any(access & BufferMappingAccessBit::Unsynchronized)) result += "Unsynchronized, "; - if (Any(access & BufferMappingAccessBit::Persistent)) result += "Persistent, "; - if (Any(access & BufferMappingAccessBit::Coherent)) result += "Coherent, "; + if (access & BufferMappingAccessBit::Read) result += "Read, "; + if (access & BufferMappingAccessBit::Write) result += "Write, "; + if (access & BufferMappingAccessBit::InvalidateRange) result += "InvalidateRange, "; + if (access & BufferMappingAccessBit::InvalidateBuffer) result += "InvalidateBuffer, "; + if (access & BufferMappingAccessBit::FlushExplicit) result += "FlushExplicit, "; + if (access & BufferMappingAccessBit::Unsynchronized) result += "Unsynchronized, "; + if (access & BufferMappingAccessBit::Persistent) result += "Persistent, "; + if (access & BufferMappingAccessBit::Coherent) result += "Coherent, "; result.pop_back(); result.pop_back(); result += "]"; diff --git a/MobileGL/MG_Util/Converters/MGToStr/BufferEnumConverter.h b/MobileGL/MG_Util/Converters/MGToStr/BufferEnumConverter.h index 720bab15..c14d4b1d 100644 --- a/MobileGL/MG_Util/Converters/MGToStr/BufferEnumConverter.h +++ b/MobileGL/MG_Util/Converters/MGToStr/BufferEnumConverter.h @@ -4,6 +4,6 @@ namespace MobileGL { namespace MG_Util { String ConvertBufferTargetToString(BufferTarget bufferTarget); String ConvertBufferUsageToString(BufferUsage usage); - String ConvertBufferMappingAccessToString(BufferMappingAccessBit access); + String ConvertBufferMappingAccessToString(Flags access); } } \ No newline at end of file diff --git a/MobileGL/MG_Util/ShaderTranspiler/Types.h b/MobileGL/MG_Util/ShaderTranspiler/Types.h index e9276194..74cd83c2 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/Types.h +++ b/MobileGL/MG_Util/ShaderTranspiler/Types.h @@ -8,9 +8,15 @@ namespace MobileGL { struct EmptyType {}; + enum class ShaderCompileBits : Uint { + EmitDiscardAsDemote = 1 << 0, + + }; + struct ShaderAttrib { GLenum shaderType; String sourceStr; + Flags flags; }; struct ProgramAttrib { diff --git a/MobileGL/MG_Util/Types.h b/MobileGL/MG_Util/Types.h index 6d93880f..e19e622d 100644 --- a/MobileGL/MG_Util/Types.h +++ b/MobileGL/MG_Util/Types.h @@ -172,6 +172,93 @@ namespace MobileGL { GLInfo RendererGLInfo; BackendCap BackendCapability; }; + + template , std::underlying_type_t> + > + class Flags { + public: + Flags() = default; + + Flags(Bit b): flags(static_cast(b)) {} + + Flags(typename Underlying::type b): flags(b) {} + + // Flags - Bit + Flags operator|(const Bit b) const { + return Flags(flags | static_cast(b)); + } + + Flags operator&(const Bit b) const { + return Flags(flags & static_cast(b)); + } + + Flags& operator|=(const Bit b) { + flags |= static_cast(b); + return *this; + } + + Flags& operator&=(const Bit b) { + flags &= static_cast(b); + return *this; + } + + bool operator==(const Bit b) const { + return flags == static_cast(b); + } + + bool operator!=(const Bit b) const { + return !(*this == b); + } + + // Flags - Flags + Flags operator|(const Flags b) const { + return Flags(flags | b.flags); + } + + Flags operator&(const Flags b) const { + return Flags(flags & b.flags); + } + + Flags& operator|=(Flags b) { + flags |= b.flags; + return *this; + } + + Flags& operator&=(Flags b) { + flags &= b.flags; + return *this; + } + + bool operator==(const Flags b) const { + return flags == b.flags; + } + + bool operator!=(const Flags b) const { + return !(*this == b); + } + + operator bool() const { + return Any(); + } + + private: + bool Any() const { + return static_cast(flags) != 0; + } + + typename Underlying::type flags = 0; + }; + + template>> + Flags operator|(const Bit lhs, const Bit rhs) { + return Flags(lhs) | rhs; + } + + template>> + Flags operator&(const Bit lhs, const Bit rhs) { + return Flags(lhs) & rhs; + } } #include "../MG_Util/ShaderTranspiler/Types.h"