[Fix] (MG_Impl/GLImpl): fix more OpenGL 3.x piglit cases

This commit is contained in:
2026-07-02 12:36:58 +08:00
parent 9b06475811
commit 3c643d943a
6 changed files with 276 additions and 85 deletions
@@ -67,7 +67,7 @@ namespace MobileGL::MG_Impl::GLImpl {
} }
const auto& vao = MG_State::pGLContext->GetBoundVertexArray(); 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( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", functionName, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", functionName,
@@ -851,7 +851,7 @@ namespace MobileGL::MG_Impl::GLImpl {
} }
void DrawBuffersForFramebuffer_State(const SharedPtr<MG_State::GLState::FramebufferObject>& fbo, Bool isDefaultFBO, void DrawBuffersForFramebuffer_State(const SharedPtr<MG_State::GLState::FramebufferObject>& fbo, Bool isDefaultFBO,
GLsizei n, const GLenum* bufs) { GLsizei n, const GLenum* bufs, Bool allowDefaultFBOAliases) {
if (n < 0) { if (n < 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, ErrorCode::InvalidValue,
@@ -874,6 +874,16 @@ namespace MobileGL::MG_Impl::GLImpl {
std::fill(existenceMap, existenceMap + (SizeT)FramebufferAttachmentType::FramebufferAttachmentTypeCount, -1); std::fill(existenceMap, existenceMap + (SizeT)FramebufferAttachmentType::FramebufferAttachmentTypeCount, -1);
for (GLsizei i = 0; i < n; ++i) { 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<GenericErrorInfo>(
"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]); auto attType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(bufs[i]);
// ------------------- Check validity begin ------------------------ // ------------------- Check validity begin ------------------------
@@ -945,15 +955,18 @@ namespace MobileGL::MG_Impl::GLImpl {
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw); auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw);
auto& fbo = bindingSlot.GetBoundObject(); auto& fbo = bindingSlot.GetBoundObject();
const bool isDefaultFBO = (fbo == FramebufferImpl::pDefaultFramebufferInfo->defaultFBO); 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) { void DrawBuffer_State(GLenum buf) {
if (buf == GL_NONE) { if (buf == GL_NONE) {
DrawBuffers_State(0, nullptr); DrawBuffers_State(0, nullptr);
} else { } else {
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw);
auto& fbo = bindingSlot.GetBoundObject();
const bool isDefaultFBO = (fbo == FramebufferImpl::pDefaultFramebufferInfo->defaultFBO);
static GLenum bufs[] = {buf}; 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) { void NamedFramebufferDrawBuffers_State(GLuint framebuffer, GLsizei n, const GLenum* bufs) {
auto framebufferObject = GetNamedFramebufferObject_State(framebuffer, "NamedFramebufferDrawBuffers_State"); auto framebufferObject = GetNamedFramebufferObject_State(framebuffer, "NamedFramebufferDrawBuffers_State");
if (!framebufferObject) return; if (!framebufferObject) return;
DrawBuffersForFramebuffer_State(framebufferObject, false, n, bufs); DrawBuffersForFramebuffer_State(framebufferObject, false, n, bufs, false);
} }
void NamedFramebufferDrawBuffer_State(GLuint framebuffer, GLenum buf) { void NamedFramebufferDrawBuffer_State(GLuint framebuffer, GLenum buf) {
@@ -1436,6 +1449,80 @@ namespace MobileGL::MG_Impl::GLImpl {
MG_Backend::gBackendFunctionsTable.GL.ClearBufferiv(buffer, drawbuffer, value); 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<GLint>(MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("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<GenericErrorInfo>("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<GenericErrorInfo>(
"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<GenericErrorInfo>(
"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<GenericErrorInfo>(
"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<GenericErrorInfo>(
"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) { Bool ReadPixels_State(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format);
TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); 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) { void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
if (!ValidateClearBufferfi_State(buffer, drawbuffer)) return;
ClearBufferfi_Backend(buffer, drawbuffer, depth, stencil); ClearBufferfi_Backend(buffer, drawbuffer, depth, stencil);
} }
void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) { void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) {
if (!ValidateClearBufferfv_State(buffer, drawbuffer)) return;
ClearBufferfv_Backend(buffer, drawbuffer, value); ClearBufferfv_Backend(buffer, drawbuffer, value);
} }
void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) { void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) {
if (!ValidateClearBufferuiv_State(buffer, drawbuffer)) return;
ClearBufferuiv_Backend(buffer, drawbuffer, value); ClearBufferuiv_Backend(buffer, drawbuffer, value);
} }
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) { void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) {
if (!ValidateClearBufferiv_State(buffer, drawbuffer)) return;
ClearBufferiv_Backend(buffer, drawbuffer, value); ClearBufferiv_Backend(buffer, drawbuffer, value);
} }
+34 -5
View File
@@ -62,10 +62,18 @@ namespace MobileGL::MG_Impl::GLImpl {
constexpr GLint kFrontendMaxCombinedUniformBlocks = kFrontendMaxVertexUniformBlocks + constexpr GLint kFrontendMaxCombinedUniformBlocks = kFrontendMaxVertexUniformBlocks +
kFrontendMaxGeometryUniformBlocks + kFrontendMaxGeometryUniformBlocks +
kFrontendMaxFragmentUniformBlocks; kFrontendMaxFragmentUniformBlocks;
constexpr GLint kFrontendMaxVaryingComponents = 60; constexpr GLint kFrontendMaxVaryingComponents = 64;
constexpr GLint kFrontendMaxVaryingVectors = 8; constexpr GLint kFrontendMaxVaryingVectors = 8;
constexpr GLint kFrontendMaxProgramTexelOffset = 7; constexpr GLint kFrontendMaxProgramTexelOffset = 7;
constexpr GLint kFrontendMinProgramTexelOffset = -8; 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 GetMaxCombinedUniformComponents(GLint maxDefaultUniformComponents, GLint maxUniformBlocks,
GLint maxUniformBlockSizeBytes) { GLint maxUniformBlockSizeBytes) {
@@ -1006,9 +1014,15 @@ namespace MobileGL::MG_Impl::GLImpl {
case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS: case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS:
*params = kFrontendMaxGeometryOutputComponents; *params = kFrontendMaxGeometryOutputComponents;
return; return;
case GL_MAX_GEOMETRY_OUTPUT_VERTICES:
*params = kFrontendMaxGeometryOutputVertices;
return;
case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
*params = kFrontendMaxGeometryTextureImageUnits; *params = kFrontendMaxGeometryTextureImageUnits;
return; return;
case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
*params = kFrontendMaxGeometryTotalOutputComponents;
return;
case GL_MAX_GEOMETRY_UNIFORM_BLOCKS: case GL_MAX_GEOMETRY_UNIFORM_BLOCKS:
*params = kFrontendMaxGeometryUniformBlocks; *params = kFrontendMaxGeometryUniformBlocks;
return; return;
@@ -1601,6 +1615,12 @@ namespace MobileGL::MG_Impl::GLImpl {
kFrontendMaxGeometryUniformBlocks, kFrontendMaxGeometryUniformBlocks,
dynamicParameters.MaxUniformBlockSize); dynamicParameters.MaxUniformBlockSize);
break; 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: case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
*params = dynamicParameters.MaxCombinedTextureImageUnits; *params = dynamicParameters.MaxCombinedTextureImageUnits;
break; break;
@@ -1654,6 +1674,15 @@ namespace MobileGL::MG_Impl::GLImpl {
case GL_MAX_TEXTURE_BUFFER_SIZE: case GL_MAX_TEXTURE_BUFFER_SIZE:
*params = dynamicParameters.MaxTextureBufferSize; *params = dynamicParameters.MaxTextureBufferSize;
break; 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: case GL_MAX_TEXTURE_IMAGE_UNITS:
*params = dynamicParameters.MaxTextureImageUnits; *params = dynamicParameters.MaxTextureImageUnits;
break; break;
@@ -1661,7 +1690,7 @@ namespace MobileGL::MG_Impl::GLImpl {
*params = dynamicParameters.MaxTextureSize; *params = dynamicParameters.MaxTextureSize;
break; break;
case GL_MAX_UNIFORM_BUFFER_BINDINGS: case GL_MAX_UNIFORM_BUFFER_BINDINGS:
*params = dynamicParameters.MaxUniformBufferBindings; *params = std::max(dynamicParameters.MaxUniformBufferBindings, kFrontendMinUniformBufferBindings);
break; break;
case GL_MAX_UNIFORM_BLOCK_SIZE: case GL_MAX_UNIFORM_BLOCK_SIZE:
*params = dynamicParameters.MaxUniformBlockSize; *params = dynamicParameters.MaxUniformBlockSize;
@@ -1699,7 +1728,7 @@ namespace MobileGL::MG_Impl::GLImpl {
*params = static_cast<GLint>(dynamicParameters.SmoothLineWidthGranularity); *params = static_cast<GLint>(dynamicParameters.SmoothLineWidthGranularity);
break; break;
case GL_SUBPIXEL_BITS: case GL_SUBPIXEL_BITS:
*params = dynamicParameters.ViewportSubpixelBits; *params = std::max(dynamicParameters.ViewportSubpixelBits, kFrontendSubpixelBits);
break; break;
case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
*params = static_cast<Int>(dynamicParameters.UniformBufferOffsetAlignment); *params = static_cast<Int>(dynamicParameters.UniformBufferOffsetAlignment);
@@ -1709,7 +1738,7 @@ namespace MobileGL::MG_Impl::GLImpl {
params[1] = static_cast<GLint>(dynamicParameters.ViewportBoundsRangeMax); params[1] = static_cast<GLint>(dynamicParameters.ViewportBoundsRangeMax);
break; break;
case GL_VIEWPORT_SUBPIXEL_BITS: case GL_VIEWPORT_SUBPIXEL_BITS:
*params = dynamicParameters.ViewportSubpixelBits; *params = std::max(dynamicParameters.ViewportSubpixelBits, kFrontendSubpixelBits);
break; break;
case GL_MAX_COLOR_ATTACHMENTS: case GL_MAX_COLOR_ATTACHMENTS:
case GL_MAX_DRAW_BUFFERS: case GL_MAX_DRAW_BUFFERS:
@@ -1717,7 +1746,7 @@ namespace MobileGL::MG_Impl::GLImpl {
: dynamicParameters.MaxDrawBuffers; : dynamicParameters.MaxDrawBuffers;
break; break;
case GL_MAX_SAMPLES: case GL_MAX_SAMPLES:
*params = dynamicParameters.MaxSamples; *params = std::max(dynamicParameters.MaxSamples, kFrontendMaxSamples);
break; break;
default: default:
MGLOG_E("glGetIntegerv: Invalid enum %s (0x%X)", MG_Util::ConvertGLEnumToString(pname).c_str(), pname); MGLOG_E("glGetIntegerv: Invalid enum %s (0x%X)", MG_Util::ConvertGLEnumToString(pname).c_str(), pname);
+14 -1
View File
@@ -1158,6 +1158,20 @@ namespace MobileGL::MG_Impl::GLImpl {
std::to_string(program) + " is not the name of a program object.")); std::to_string(program) + " is not the name of a program object."));
return; return;
} }
if (name == nullptr) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "name cannot be null."));
return;
}
const auto& dynamicParameters = MG_Backend::pActiveBackendObject->GetDynamicParameters();
if (colorNumber >= static_cast<GLuint>(dynamicParameters.MaxDrawBuffers)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"colorNumber is greater than or equal to GL_MAX_DRAW_BUFFERS."));
return;
}
if (strncmp(name, "gl_", 3) == 0) { if (strncmp(name, "gl_", 3) == 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
@@ -1165,7 +1179,6 @@ namespace MobileGL::MG_Impl::GLImpl {
"name " + std::string(name) + " starts with the reserved prefix `gl_`.")); "name " + std::string(name) + " starts with the reserved prefix `gl_`."));
return; 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); MGLOG_D("%s: loc %02d = \"%s\"", __func__, colorNumber, name);
programObject->SetExplicitFragmentOutLocation(colorNumber, name); programObject->SetExplicitFragmentOutLocation(colorNumber, name);
+129 -73
View File
@@ -86,6 +86,100 @@ namespace MobileGL::MG_Impl::GLImpl {
MG_Util::ConvertGLEnumToTexturePixelDataType(realType)); 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) { Uint ComputeFullMipmapLevelCount(const IntVec3& baseTexelSize) {
Int maxDimension = std::max<Int>( Int maxDimension = std::max<Int>(
baseTexelSize.x(), baseTexelSize.x(),
@@ -1761,16 +1855,28 @@ namespace MobileGL::MG_Impl::GLImpl {
case GL_TEXTURE_BLUE_SIZE: case GL_TEXTURE_BLUE_SIZE:
case GL_TEXTURE_ALPHA_SIZE: case GL_TEXTURE_ALPHA_SIZE:
case GL_TEXTURE_DEPTH_SIZE: case GL_TEXTURE_DEPTH_SIZE:
case GL_TEXTURE_STENCIL_SIZE:
if (params) {
*params = GetTextureLevelComponentParameter(textureObject->GetFormat(), pname);
}
break;
case GL_TEXTURE_COMPRESSED: case GL_TEXTURE_COMPRESSED:
if (params) {
*params = GL_FALSE;
}
break;
case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
break; // TODO if (params) {
*params = 0;
}
break;
default: default:
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexLevelParameteriv_State", ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexLevelParameteriv_State",
"pname is not a valid texture level parameter.")); "pname is not a valid texture level parameter."));
return; return;
} }
MGLOG_D("returned %u",*params); if (params) MGLOG_D("returned %u", *params);
} }
void GetTexLevelParameterfv_State(GLenum target, GLint level, GLenum pname, GLfloat* 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_BLUE_SIZE:
case GL_TEXTURE_ALPHA_SIZE: case GL_TEXTURE_ALPHA_SIZE:
case GL_TEXTURE_DEPTH_SIZE: case GL_TEXTURE_DEPTH_SIZE:
case GL_TEXTURE_STENCIL_SIZE:
if (params) {
*params = static_cast<GLfloat>(GetTextureLevelComponentParameter(textureObject->GetFormat(), pname));
}
break;
case GL_TEXTURE_COMPRESSED: case GL_TEXTURE_COMPRESSED:
if (params) {
*params = 0.0f;
}
break;
case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
break; // TODO if (params) {
*params = 0.0f;
}
break;
default: default:
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexLevelParameterfv_State", ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexLevelParameterfv_State",
@@ -2911,8 +3029,8 @@ namespace MobileGL::MG_Impl::GLImpl {
if (targetIndex >= MG_Backend::kFormatCapabilityTargetCount) return; if (targetIndex >= MG_Backend::kFormatCapabilityTargetCount) return;
const SizeT formatIndex = static_cast<SizeT>(textureInternalFormat); const SizeT formatIndex = static_cast<SizeT>(textureInternalFormat);
MG_Backend::FormatCapabilityFlags fullCaps; MG_Backend::FormatCapabilityFlags fullCaps{};
MG_Backend::FormatCapabilityFlags caveatCaps; MG_Backend::FormatCapabilityFlags caveatCaps{};
const Vector<Int>* sampleCounts = nullptr; const Vector<Int>* sampleCounts = nullptr;
if (MG_Backend::pActiveBackendObject) { if (MG_Backend::pActiveBackendObject) {
const auto& cache = MG_Backend::pActiveBackendObject->GetFormatCapabilities(); 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; if (hasCaveat(primary) || hasFull(fallback) || hasCaveat(fallback)) return GL_CAVEAT_SUPPORT;
return GL_NONE; 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) { switch (pname) {
case GL_INTERNALFORMAT_SUPPORTED: case GL_INTERNALFORMAT_SUPPORTED:
writeValues({(hasFull(MG_Backend::FormatCapability::Creatable) || writeValues({(hasFull(MG_Backend::FormatCapability::Creatable) ||
@@ -3032,22 +3088,22 @@ namespace MobileGL::MG_Impl::GLImpl {
writeValues({textureInternalFormat == TextureInternalFormat::RGB9E5 ? 5 : 0}); writeValues({textureInternalFormat == TextureInternalFormat::RGB9E5 ? 5 : 0});
return; return;
case GL_INTERNALFORMAT_RED_TYPE: case GL_INTERNALFORMAT_RED_TYPE:
writeValues({componentType(componentSizes.Red, false, false)}); writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Red, false, false)});
return; return;
case GL_INTERNALFORMAT_GREEN_TYPE: case GL_INTERNALFORMAT_GREEN_TYPE:
writeValues({componentType(componentSizes.Green, false, false)}); writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Green, false, false)});
return; return;
case GL_INTERNALFORMAT_BLUE_TYPE: case GL_INTERNALFORMAT_BLUE_TYPE:
writeValues({componentType(componentSizes.Blue, false, false)}); writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Blue, false, false)});
return; return;
case GL_INTERNALFORMAT_ALPHA_TYPE: case GL_INTERNALFORMAT_ALPHA_TYPE:
writeValues({componentType(componentSizes.Alpha, false, false)}); writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Alpha, false, false)});
return; return;
case GL_INTERNALFORMAT_DEPTH_TYPE: case GL_INTERNALFORMAT_DEPTH_TYPE:
writeValues({componentType(componentSizes.Depth, true, false)}); writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Depth, true, false)});
return; return;
case GL_INTERNALFORMAT_STENCIL_TYPE: case GL_INTERNALFORMAT_STENCIL_TYPE:
writeValues({componentType(componentSizes.Stencil, false, true)}); writeValues({GetTextureComponentType(textureInternalFormat, componentSizes.Stencil, false, true)});
return; return;
case GL_TEXTURE_IMAGE_FORMAT: case GL_TEXTURE_IMAGE_FORMAT:
writeValues({static_cast<GLint>(imageFormat)}); writeValues({static_cast<GLint>(imageFormat)});
@@ -19,6 +19,7 @@ namespace MobileGL::MG_State::GLState {
BufferTarget::DrawIndirect, BufferTarget::Parameter, BufferTarget::ShaderStorage); BufferTarget::DrawIndirect, BufferTarget::Parameter, BufferTarget::ShaderStorage);
constexpr const auto BufferBindPointTargets = ToArray(BufferTarget::Uniform, BufferTarget::TransformFeedback, constexpr const auto BufferBindPointTargets = ToArray(BufferTarget::Uniform, BufferTarget::TransformFeedback,
BufferTarget::AtomicCounter, BufferTarget::ShaderStorage); BufferTarget::AtomicCounter, BufferTarget::ShaderStorage);
constexpr SizeT BufferBindingPointCount = 36;
class BufferState { class BufferState {
public: public:
@@ -45,6 +46,7 @@ namespace MobileGL::MG_State::GLState {
Array<BindingSlot<BufferObject>, GlobalBufferTargets.size()> m_bindingSlots; Array<BindingSlot<BufferObject>, GlobalBufferTargets.size()> m_bindingSlots;
// TODO: query the count somewhere globally? // TODO: query the count somewhere globally?
// For glBindBufferBase / glBindBufferRange // For glBindBufferBase / glBindBufferRange
Array<Array<BindingSlotRange1D<BufferObject>, 16>, BufferBindPointTargets.size()> m_bufferBindPointTargets; Array<Array<BindingSlotRange1D<BufferObject>, BufferBindingPointCount>, BufferBindPointTargets.size()>
m_bufferBindPointTargets;
}; };
} // namespace MobileGL::MG_State::GLState } // namespace MobileGL::MG_State::GLState