mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Fix] (MG_Impl/GLImpl): fix more OpenGL 3.x piglit cases
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user