diff --git a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp index bf4bc47a..92c89f4f 100644 --- a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp +++ b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp @@ -67,7 +67,7 @@ namespace MobileGL::MG_Impl::GLImpl { } const auto& vao = MG_State::pGLContext->GetBoundVertexArray(); - if (MG_State::pEGLContext->IsCurrentContextOpenGLCoreProfile() && vao && vao->GetExternalIndex() == 0) { + if (vao && vao->GetExternalIndex() == 0) { MG_State::pGLContext->RecordError( ErrorCode::InvalidOperation, MakeUnique("MG_Impl/GLImpl", functionName, diff --git a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp index ca5a1918..8d3da96a 100644 --- a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp @@ -851,7 +851,7 @@ namespace MobileGL::MG_Impl::GLImpl { } void DrawBuffersForFramebuffer_State(const SharedPtr& fbo, Bool isDefaultFBO, - GLsizei n, const GLenum* bufs) { + GLsizei n, const GLenum* bufs, Bool allowDefaultFBOAliases) { if (n < 0) { MG_State::pGLContext->RecordError( ErrorCode::InvalidValue, @@ -874,6 +874,16 @@ namespace MobileGL::MG_Impl::GLImpl { std::fill(existenceMap, existenceMap + (SizeT)FramebufferAttachmentType::FramebufferAttachmentTypeCount, -1); for (GLsizei i = 0; i < n; ++i) { + if (isDefaultFBO && !allowDefaultFBOAliases && (bufs[i] == GL_FRONT || bufs[i] == GL_BACK)) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeUnique( + "MG_Impl/GLImpl", __func__, + std::format("glDrawBuffers cannot use default framebuffer alias {}.", + MG_Util::ConvertGLEnumToString(bufs[i])))); + return; + } + auto attType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(bufs[i]); // ------------------- Check validity begin ------------------------ @@ -945,15 +955,18 @@ namespace MobileGL::MG_Impl::GLImpl { auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw); auto& fbo = bindingSlot.GetBoundObject(); const bool isDefaultFBO = (fbo == FramebufferImpl::pDefaultFramebufferInfo->defaultFBO); - DrawBuffersForFramebuffer_State(fbo, isDefaultFBO, n, bufs); + DrawBuffersForFramebuffer_State(fbo, isDefaultFBO, n, bufs, false); } void DrawBuffer_State(GLenum buf) { if (buf == GL_NONE) { DrawBuffers_State(0, nullptr); } else { + auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw); + auto& fbo = bindingSlot.GetBoundObject(); + const bool isDefaultFBO = (fbo == FramebufferImpl::pDefaultFramebufferInfo->defaultFBO); static GLenum bufs[] = {buf}; - DrawBuffers_State(1, bufs); + DrawBuffersForFramebuffer_State(fbo, isDefaultFBO, 1, bufs, true); } } @@ -1016,7 +1029,7 @@ namespace MobileGL::MG_Impl::GLImpl { void NamedFramebufferDrawBuffers_State(GLuint framebuffer, GLsizei n, const GLenum* bufs) { auto framebufferObject = GetNamedFramebufferObject_State(framebuffer, "NamedFramebufferDrawBuffers_State"); if (!framebufferObject) return; - DrawBuffersForFramebuffer_State(framebufferObject, false, n, bufs); + DrawBuffersForFramebuffer_State(framebufferObject, false, n, bufs, false); } void NamedFramebufferDrawBuffer_State(GLuint framebuffer, GLenum buf) { @@ -1436,6 +1449,80 @@ namespace MobileGL::MG_Impl::GLImpl { MG_Backend::gBackendFunctionsTable.GL.ClearBufferiv(buffer, drawbuffer, value); } + Bool ValidateClearBufferDrawbuffer_State(GLenum buffer, GLint drawbuffer, const char* caller) { + if (buffer == GL_COLOR) { + if (drawbuffer < 0 || + drawbuffer >= static_cast(MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS)) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeUnique("MG_Impl/GLImpl", caller, "color drawbuffer index is out of range.")); + return false; + } + return true; + } + + if (drawbuffer != 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeUnique("MG_Impl/GLImpl", caller, + "depth, stencil, and depth/stencil clears require drawbuffer 0.")); + return false; + } + return true; + } + + Bool ValidateClearBufferfv_State(GLenum buffer, GLint drawbuffer) { + if (buffer != GL_COLOR && buffer != GL_DEPTH) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeUnique( + "MG_Impl/GLImpl", "ValidateClearBufferfv_State", + std::format("buffer {} is not accepted for glClearBufferfv.", + MG_Util::ConvertGLEnumToString(buffer)))); + return false; + } + return ValidateClearBufferDrawbuffer_State(buffer, drawbuffer, "ValidateClearBufferfv_State"); + } + + Bool ValidateClearBufferiv_State(GLenum buffer, GLint drawbuffer) { + if (buffer != GL_COLOR && buffer != GL_STENCIL) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeUnique( + "MG_Impl/GLImpl", "ValidateClearBufferiv_State", + std::format("buffer {} is not accepted for glClearBufferiv.", + MG_Util::ConvertGLEnumToString(buffer)))); + return false; + } + return ValidateClearBufferDrawbuffer_State(buffer, drawbuffer, "ValidateClearBufferiv_State"); + } + + Bool ValidateClearBufferuiv_State(GLenum buffer, GLint drawbuffer) { + if (buffer != GL_COLOR && buffer != GL_STENCIL) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeUnique( + "MG_Impl/GLImpl", "ValidateClearBufferuiv_State", + std::format("buffer {} is not accepted for glClearBufferuiv.", + MG_Util::ConvertGLEnumToString(buffer)))); + return false; + } + return ValidateClearBufferDrawbuffer_State(buffer, drawbuffer, "ValidateClearBufferuiv_State"); + } + + Bool ValidateClearBufferfi_State(GLenum buffer, GLint drawbuffer) { + if (buffer != GL_DEPTH_STENCIL) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeUnique( + "MG_Impl/GLImpl", "ValidateClearBufferfi_State", + std::format("buffer {} is not accepted for glClearBufferfi.", + MG_Util::ConvertGLEnumToString(buffer)))); + return false; + } + return ValidateClearBufferDrawbuffer_State(buffer, drawbuffer, "ValidateClearBufferfi_State"); + } + Bool ReadPixels_State(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); @@ -1571,18 +1658,22 @@ namespace MobileGL::MG_Impl::GLImpl { } void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { + if (!ValidateClearBufferfi_State(buffer, drawbuffer)) return; ClearBufferfi_Backend(buffer, drawbuffer, depth, stencil); } void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) { + if (!ValidateClearBufferfv_State(buffer, drawbuffer)) return; ClearBufferfv_Backend(buffer, drawbuffer, value); } void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) { + if (!ValidateClearBufferuiv_State(buffer, drawbuffer)) return; ClearBufferuiv_Backend(buffer, drawbuffer, value); } void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) { + if (!ValidateClearBufferiv_State(buffer, drawbuffer)) return; ClearBufferiv_Backend(buffer, drawbuffer, value); } diff --git a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp index 2ce579c2..1b36058b 100644 --- a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp +++ b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp @@ -62,10 +62,18 @@ namespace MobileGL::MG_Impl::GLImpl { constexpr GLint kFrontendMaxCombinedUniformBlocks = kFrontendMaxVertexUniformBlocks + kFrontendMaxGeometryUniformBlocks + kFrontendMaxFragmentUniformBlocks; - constexpr GLint kFrontendMaxVaryingComponents = 60; + constexpr GLint kFrontendMaxVaryingComponents = 64; constexpr GLint kFrontendMaxVaryingVectors = 8; constexpr GLint kFrontendMaxProgramTexelOffset = 7; constexpr GLint kFrontendMinProgramTexelOffset = -8; + constexpr GLint kFrontendMaxTransformFeedbackInterleavedComponents = 64; + constexpr GLint kFrontendMaxTransformFeedbackSeparateAttribs = 4; + constexpr GLint kFrontendMaxTransformFeedbackSeparateComponents = 4; + constexpr GLint kFrontendMaxGeometryOutputVertices = 256; + constexpr GLint kFrontendMaxGeometryTotalOutputComponents = 1024; + constexpr GLint kFrontendMinUniformBufferBindings = 36; + constexpr GLint kFrontendSubpixelBits = 4; + constexpr GLint kFrontendMaxSamples = 4; GLint GetMaxCombinedUniformComponents(GLint maxDefaultUniformComponents, GLint maxUniformBlocks, GLint maxUniformBlockSizeBytes) { @@ -1006,9 +1014,15 @@ namespace MobileGL::MG_Impl::GLImpl { case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS: *params = kFrontendMaxGeometryOutputComponents; return; + case GL_MAX_GEOMETRY_OUTPUT_VERTICES: + *params = kFrontendMaxGeometryOutputVertices; + return; case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: *params = kFrontendMaxGeometryTextureImageUnits; return; + case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: + *params = kFrontendMaxGeometryTotalOutputComponents; + return; case GL_MAX_GEOMETRY_UNIFORM_BLOCKS: *params = kFrontendMaxGeometryUniformBlocks; return; @@ -1601,6 +1615,12 @@ namespace MobileGL::MG_Impl::GLImpl { kFrontendMaxGeometryUniformBlocks, dynamicParameters.MaxUniformBlockSize); break; + case GL_MAX_GEOMETRY_OUTPUT_VERTICES: + *params = kFrontendMaxGeometryOutputVertices; + break; + case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: + *params = kFrontendMaxGeometryTotalOutputComponents; + break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = dynamicParameters.MaxCombinedTextureImageUnits; break; @@ -1654,6 +1674,15 @@ namespace MobileGL::MG_Impl::GLImpl { case GL_MAX_TEXTURE_BUFFER_SIZE: *params = dynamicParameters.MaxTextureBufferSize; break; + case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: + *params = kFrontendMaxTransformFeedbackInterleavedComponents; + break; + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: + *params = kFrontendMaxTransformFeedbackSeparateAttribs; + break; + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: + *params = kFrontendMaxTransformFeedbackSeparateComponents; + break; case GL_MAX_TEXTURE_IMAGE_UNITS: *params = dynamicParameters.MaxTextureImageUnits; break; @@ -1661,7 +1690,7 @@ namespace MobileGL::MG_Impl::GLImpl { *params = dynamicParameters.MaxTextureSize; break; case GL_MAX_UNIFORM_BUFFER_BINDINGS: - *params = dynamicParameters.MaxUniformBufferBindings; + *params = std::max(dynamicParameters.MaxUniformBufferBindings, kFrontendMinUniformBufferBindings); break; case GL_MAX_UNIFORM_BLOCK_SIZE: *params = dynamicParameters.MaxUniformBlockSize; @@ -1699,7 +1728,7 @@ namespace MobileGL::MG_Impl::GLImpl { *params = static_cast(dynamicParameters.SmoothLineWidthGranularity); break; case GL_SUBPIXEL_BITS: - *params = dynamicParameters.ViewportSubpixelBits; + *params = std::max(dynamicParameters.ViewportSubpixelBits, kFrontendSubpixelBits); break; case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = static_cast(dynamicParameters.UniformBufferOffsetAlignment); @@ -1709,7 +1738,7 @@ namespace MobileGL::MG_Impl::GLImpl { params[1] = static_cast(dynamicParameters.ViewportBoundsRangeMax); break; case GL_VIEWPORT_SUBPIXEL_BITS: - *params = dynamicParameters.ViewportSubpixelBits; + *params = std::max(dynamicParameters.ViewportSubpixelBits, kFrontendSubpixelBits); break; case GL_MAX_COLOR_ATTACHMENTS: case GL_MAX_DRAW_BUFFERS: @@ -1717,7 +1746,7 @@ namespace MobileGL::MG_Impl::GLImpl { : dynamicParameters.MaxDrawBuffers; break; case GL_MAX_SAMPLES: - *params = dynamicParameters.MaxSamples; + *params = std::max(dynamicParameters.MaxSamples, kFrontendMaxSamples); break; default: MGLOG_E("glGetIntegerv: Invalid enum %s (0x%X)", MG_Util::ConvertGLEnumToString(pname).c_str(), pname); diff --git a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp index ca2d6ff9..9c66ee06 100644 --- a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp +++ b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp @@ -1158,6 +1158,20 @@ namespace MobileGL::MG_Impl::GLImpl { std::to_string(program) + " is not the name of a program object.")); return; } + if (name == nullptr) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeUnique("MG_Impl/GLImpl", __func__, "name cannot be null.")); + return; + } + const auto& dynamicParameters = MG_Backend::pActiveBackendObject->GetDynamicParameters(); + if (colorNumber >= static_cast(dynamicParameters.MaxDrawBuffers)) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeUnique("MG_Impl/GLImpl", __func__, + "colorNumber is greater than or equal to GL_MAX_DRAW_BUFFERS.")); + return; + } if (strncmp(name, "gl_", 3) == 0) { MG_State::pGLContext->RecordError( ErrorCode::InvalidOperation, @@ -1165,7 +1179,6 @@ namespace MobileGL::MG_Impl::GLImpl { "name " + std::string(name) + " starts with the reserved prefix `gl_`.")); return; } - // TODO: Emit error "if `colorNumber` is greater than or equal to `GL_MAX_DRAW_BUFFERS`" MGLOG_D("%s: loc %02d = \"%s\"", __func__, colorNumber, name); programObject->SetExplicitFragmentOutLocation(colorNumber, name); diff --git a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp index 3e39021e..6e60ba4b 100644 --- a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp +++ b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp @@ -86,6 +86,100 @@ namespace MobileGL::MG_Impl::GLImpl { MG_Util::ConvertGLEnumToTexturePixelDataType(realType)); } + GLint GetTextureComponentType(TextureInternalFormat textureInternalFormat, GLint size, Bool depthComponent, + Bool stencilComponent) { + if (size <= 0) return GL_NONE; + if (stencilComponent) return GL_UNSIGNED_INT; + if (depthComponent) { + return (textureInternalFormat == TextureInternalFormat::DepthComponent32F || + textureInternalFormat == TextureInternalFormat::Depth32FStencil8) + ? GL_FLOAT + : GL_UNSIGNED_NORMALIZED; + } + switch (textureInternalFormat) { + case TextureInternalFormat::R8I: + case TextureInternalFormat::R16I: + case TextureInternalFormat::R32I: + case TextureInternalFormat::RG8I: + case TextureInternalFormat::RG16I: + case TextureInternalFormat::RG32I: + case TextureInternalFormat::RGB8I: + case TextureInternalFormat::RGB16I: + case TextureInternalFormat::RGB32I: + case TextureInternalFormat::RGBA8I: + case TextureInternalFormat::RGBA16I: + case TextureInternalFormat::RGBA32I: + return GL_INT; + case TextureInternalFormat::R8UI: + case TextureInternalFormat::R16UI: + case TextureInternalFormat::R32UI: + case TextureInternalFormat::RG8UI: + case TextureInternalFormat::RG16UI: + case TextureInternalFormat::RG32UI: + case TextureInternalFormat::RGB8UI: + case TextureInternalFormat::RGB16UI: + case TextureInternalFormat::RGB32UI: + case TextureInternalFormat::RGBA8UI: + case TextureInternalFormat::RGBA16UI: + case TextureInternalFormat::RGBA32UI: + case TextureInternalFormat::RGB10A2UI: + return GL_UNSIGNED_INT; + case TextureInternalFormat::R16F: + case TextureInternalFormat::RG16F: + case TextureInternalFormat::RGB16F: + case TextureInternalFormat::RGBA16F: + case TextureInternalFormat::R32F: + case TextureInternalFormat::RG32F: + case TextureInternalFormat::RGB32F: + case TextureInternalFormat::RGBA32F: + case TextureInternalFormat::R11FG11FB10F: + case TextureInternalFormat::RGB9E5: + return GL_FLOAT; + case TextureInternalFormat::R8Snorm: + case TextureInternalFormat::R16Snorm: + case TextureInternalFormat::RG8Snorm: + case TextureInternalFormat::RG16Snorm: + case TextureInternalFormat::RGB8Snorm: + case TextureInternalFormat::RGB16Snorm: + case TextureInternalFormat::RGBA8Snorm: + case TextureInternalFormat::RGBA16Snorm: + return GL_SIGNED_NORMALIZED; + default: + return GL_UNSIGNED_NORMALIZED; + } + } + + GLint GetTextureLevelComponentParameter(TextureInternalFormat textureInternalFormat, GLenum pname) { + const ComponentSizes componentSizes = MG_Util::GetComponentSizesForInternalFormat(textureInternalFormat); + switch (pname) { + case GL_TEXTURE_RED_SIZE: + return componentSizes.Red; + case GL_TEXTURE_GREEN_SIZE: + return componentSizes.Green; + case GL_TEXTURE_BLUE_SIZE: + return componentSizes.Blue; + case GL_TEXTURE_ALPHA_SIZE: + return componentSizes.Alpha; + case GL_TEXTURE_DEPTH_SIZE: + return componentSizes.Depth; + case GL_TEXTURE_STENCIL_SIZE: + return componentSizes.Stencil; + case GL_TEXTURE_RED_TYPE: + return GetTextureComponentType(textureInternalFormat, componentSizes.Red, false, false); + case GL_TEXTURE_GREEN_TYPE: + return GetTextureComponentType(textureInternalFormat, componentSizes.Green, false, false); + case GL_TEXTURE_BLUE_TYPE: + return GetTextureComponentType(textureInternalFormat, componentSizes.Blue, false, false); + case GL_TEXTURE_ALPHA_TYPE: + return GetTextureComponentType(textureInternalFormat, componentSizes.Alpha, false, false); + case GL_TEXTURE_DEPTH_TYPE: + return GetTextureComponentType(textureInternalFormat, componentSizes.Depth, true, false); + default: + MOBILEGL_ASSERT(false, "Invalid texture level component pname: %d", pname); + return 0; + } + } + Uint ComputeFullMipmapLevelCount(const IntVec3& baseTexelSize) { Int maxDimension = std::max( baseTexelSize.x(), @@ -1761,16 +1855,28 @@ namespace MobileGL::MG_Impl::GLImpl { case GL_TEXTURE_BLUE_SIZE: case GL_TEXTURE_ALPHA_SIZE: case GL_TEXTURE_DEPTH_SIZE: + case GL_TEXTURE_STENCIL_SIZE: + if (params) { + *params = GetTextureLevelComponentParameter(textureObject->GetFormat(), pname); + } + break; case GL_TEXTURE_COMPRESSED: + if (params) { + *params = GL_FALSE; + } + break; case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: - break; // TODO + if (params) { + *params = 0; + } + break; default: MG_State::pGLContext->RecordError( ErrorCode::InvalidEnum, MakeUnique("MG_Impl/GLImpl", "GetTexLevelParameteriv_State", "pname is not a valid texture level parameter.")); return; } - MGLOG_D("returned %u",*params); + if (params) MGLOG_D("returned %u", *params); } void GetTexLevelParameterfv_State(GLenum target, GLint level, GLenum pname, GLfloat* params) { @@ -1861,9 +1967,21 @@ namespace MobileGL::MG_Impl::GLImpl { case GL_TEXTURE_BLUE_SIZE: case GL_TEXTURE_ALPHA_SIZE: case GL_TEXTURE_DEPTH_SIZE: + case GL_TEXTURE_STENCIL_SIZE: + if (params) { + *params = static_cast(GetTextureLevelComponentParameter(textureObject->GetFormat(), pname)); + } + break; case GL_TEXTURE_COMPRESSED: + if (params) { + *params = 0.0f; + } + break; case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: - break; // TODO + if (params) { + *params = 0.0f; + } + break; default: MG_State::pGLContext->RecordError( ErrorCode::InvalidEnum, MakeUnique("MG_Impl/GLImpl", "GetTexLevelParameterfv_State", @@ -2911,8 +3029,8 @@ namespace MobileGL::MG_Impl::GLImpl { if (targetIndex >= MG_Backend::kFormatCapabilityTargetCount) return; const SizeT formatIndex = static_cast(textureInternalFormat); - MG_Backend::FormatCapabilityFlags fullCaps; - MG_Backend::FormatCapabilityFlags caveatCaps; + MG_Backend::FormatCapabilityFlags fullCaps{}; + MG_Backend::FormatCapabilityFlags caveatCaps{}; const Vector* sampleCounts = nullptr; if (MG_Backend::pActiveBackendObject) { const auto& cache = MG_Backend::pActiveBackendObject->GetFormatCapabilities(); @@ -2938,68 +3056,6 @@ namespace MobileGL::MG_Impl::GLImpl { if (hasCaveat(primary) || hasFull(fallback) || hasCaveat(fallback)) return GL_CAVEAT_SUPPORT; return GL_NONE; }; - auto componentType = [&](GLint size, Bool depthComponent, Bool stencilComponent) -> GLint { - if (size <= 0) return GL_NONE; - if (stencilComponent) return GL_UNSIGNED_INT; - if (depthComponent) { - return (textureInternalFormat == TextureInternalFormat::DepthComponent32F || - textureInternalFormat == TextureInternalFormat::Depth32FStencil8) - ? GL_FLOAT - : GL_UNSIGNED_NORMALIZED; - } - switch (textureInternalFormat) { - case TextureInternalFormat::R8I: - case TextureInternalFormat::R16I: - case TextureInternalFormat::R32I: - case TextureInternalFormat::RG8I: - case TextureInternalFormat::RG16I: - case TextureInternalFormat::RG32I: - case TextureInternalFormat::RGB8I: - case TextureInternalFormat::RGB16I: - case TextureInternalFormat::RGB32I: - case TextureInternalFormat::RGBA8I: - case TextureInternalFormat::RGBA16I: - case TextureInternalFormat::RGBA32I: - return GL_INT; - case TextureInternalFormat::R8UI: - case TextureInternalFormat::R16UI: - case TextureInternalFormat::R32UI: - case TextureInternalFormat::RG8UI: - case TextureInternalFormat::RG16UI: - case TextureInternalFormat::RG32UI: - case TextureInternalFormat::RGB8UI: - case TextureInternalFormat::RGB16UI: - case TextureInternalFormat::RGB32UI: - case TextureInternalFormat::RGBA8UI: - case TextureInternalFormat::RGBA16UI: - case TextureInternalFormat::RGBA32UI: - case TextureInternalFormat::RGB10A2UI: - return GL_UNSIGNED_INT; - case TextureInternalFormat::R16F: - case TextureInternalFormat::RG16F: - case TextureInternalFormat::RGB16F: - case TextureInternalFormat::RGBA16F: - case TextureInternalFormat::R32F: - case TextureInternalFormat::RG32F: - case TextureInternalFormat::RGB32F: - case TextureInternalFormat::RGBA32F: - case TextureInternalFormat::R11FG11FB10F: - case TextureInternalFormat::RGB9E5: - return GL_FLOAT; - case TextureInternalFormat::R8Snorm: - case TextureInternalFormat::R16Snorm: - case TextureInternalFormat::RG8Snorm: - case TextureInternalFormat::RG16Snorm: - case TextureInternalFormat::RGB8Snorm: - case TextureInternalFormat::RGB16Snorm: - case TextureInternalFormat::RGBA8Snorm: - case TextureInternalFormat::RGBA16Snorm: - return GL_SIGNED_NORMALIZED; - default: - return GL_UNSIGNED_NORMALIZED; - } - }; - switch (pname) { case GL_INTERNALFORMAT_SUPPORTED: writeValues({(hasFull(MG_Backend::FormatCapability::Creatable) || @@ -3032,22 +3088,22 @@ namespace MobileGL::MG_Impl::GLImpl { writeValues({textureInternalFormat == TextureInternalFormat::RGB9E5 ? 5 : 0}); return; case GL_INTERNALFORMAT_RED_TYPE: - writeValues({componentType(componentSizes.Red, false, false)}); + writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Red, false, false)}); return; case GL_INTERNALFORMAT_GREEN_TYPE: - writeValues({componentType(componentSizes.Green, false, false)}); + writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Green, false, false)}); return; case GL_INTERNALFORMAT_BLUE_TYPE: - writeValues({componentType(componentSizes.Blue, false, false)}); + writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Blue, false, false)}); return; case GL_INTERNALFORMAT_ALPHA_TYPE: - writeValues({componentType(componentSizes.Alpha, false, false)}); + writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Alpha, false, false)}); return; case GL_INTERNALFORMAT_DEPTH_TYPE: - writeValues({componentType(componentSizes.Depth, true, false)}); + writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Depth, true, false)}); return; case GL_INTERNALFORMAT_STENCIL_TYPE: - writeValues({componentType(componentSizes.Stencil, false, true)}); + writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Stencil, false, true)}); return; case GL_TEXTURE_IMAGE_FORMAT: writeValues({static_cast(imageFormat)}); diff --git a/MobileGL/MG_State/GLState/BufferState/BufferState.h b/MobileGL/MG_State/GLState/BufferState/BufferState.h index a515a783..3a6cba42 100644 --- a/MobileGL/MG_State/GLState/BufferState/BufferState.h +++ b/MobileGL/MG_State/GLState/BufferState/BufferState.h @@ -19,6 +19,7 @@ namespace MobileGL::MG_State::GLState { BufferTarget::DrawIndirect, BufferTarget::Parameter, BufferTarget::ShaderStorage); constexpr const auto BufferBindPointTargets = ToArray(BufferTarget::Uniform, BufferTarget::TransformFeedback, BufferTarget::AtomicCounter, BufferTarget::ShaderStorage); + constexpr SizeT BufferBindingPointCount = 36; class BufferState { public: @@ -45,6 +46,7 @@ namespace MobileGL::MG_State::GLState { Array, GlobalBufferTargets.size()> m_bindingSlots; // TODO: query the count somewhere globally? // For glBindBufferBase / glBindBufferRange - Array, 16>, BufferBindPointTargets.size()> m_bufferBindPointTargets; + Array, BufferBindingPointCount>, BufferBindPointTargets.size()> + m_bufferBindPointTargets; }; } // namespace MobileGL::MG_State::GLState