[Feat] (MG_Impl/Texture, MG_State/TextureState, MG_Impl/Framebuffer, MG_Test/Texture): implement multisample frontend state

This commit is contained in:
BZLZHH
2026-06-10 01:37:59 +08:00
parent 3da0b1dfd4
commit c499480692
11 changed files with 362 additions and 16 deletions
@@ -362,8 +362,8 @@ DECLARE_GL_FUNCTION_HEAD(void, BindImageTexture, GLuint unit, GLuint texture, GL
DECLARE_GL_FUNCTION_HEAD(void, GetBooleani_v, GLenum target, GLuint index, GLboolean* data) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetBooleani_v, target, index, data)
DECLARE_GL_FUNCTION_HEAD(void, MemoryBarrier, GLbitfield barriers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, MemoryBarrier, barriers)
DECLARE_GL_FUNCTION_HEAD(void, MemoryBarrierByRegion, GLbitfield barriers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, MemoryBarrierByRegion, barriers)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexStorage2DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexStorage2DMultisample, target, samples, internalformat, width, height, fixedsamplelocations)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetMultisamplefv, GLenum pname, GLuint index, GLfloat* val) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetMultisamplefv, pname, index, val)
DECLARE_GL_FUNCTION_HEAD(void, TexStorage2DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TexStorage2DMultisample, target, samples, internalformat, width, height, fixedsamplelocations)
DECLARE_GL_FUNCTION_HEAD(void, GetMultisamplefv, GLenum pname, GLuint index, GLfloat* val) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetMultisamplefv, pname, index, val)
DECLARE_GL_FUNCTION_HEAD(void, SampleMaski, GLuint maskNumber, GLbitfield mask) DECLARE_GL_FUNCTION_END_NO_RETURN(void, SampleMaski, maskNumber, mask)
DECLARE_GL_FUNCTION_HEAD(void, GetTexLevelParameteriv, GLenum target, GLint level, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetTexLevelParameteriv, target, level, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, GetTexLevelParameterfv, GLenum target, GLint level, GLenum pname, GLfloat* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetTexLevelParameterfv, target, level, pname, params)
@@ -419,7 +419,7 @@ DECLARE_GL_FUNCTION_HEAD(void, GetSamplerParameterIiv, GLuint sampler, GLenum pn
DECLARE_GL_FUNCTION_HEAD(void, GetSamplerParameterIuiv, GLuint sampler, GLenum pname, GLuint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetSamplerParameterIuiv, sampler, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, TexBuffer, GLenum target, GLenum internalformat, GLuint buffer) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TexBuffer, target, internalformat, buffer)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexBufferRange, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexBufferRange, target, internalformat, buffer, offset, size)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexStorage3DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexStorage3DMultisample, target, samples, internalformat, width, height, depth, fixedsamplelocations)
DECLARE_GL_FUNCTION_HEAD(void, TexStorage3DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TexStorage3DMultisample, target, samples, internalformat, width, height, depth, fixedsamplelocations)
DECLARE_GL_FUNCTION_HEAD(void*, MapBufferRange, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) DECLARE_GL_FUNCTION_END(void*, MapBufferRange, target, offset, length, access)
DECLARE_GL_FUNCTION_STUB_HEAD(void, ClearIndex, GLfloat c) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ClearIndex, c)
DECLARE_GL_FUNCTION_STUB_HEAD(void, IndexMask, GLuint mask) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, IndexMask, mask)
@@ -1030,7 +1030,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, GetNamedFramebufferParameteriv, GLuint frame
DECLARE_GL_FUNCTION_HEAD(void, GetNamedFramebufferAttachmentParameteriv, GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetNamedFramebufferAttachmentParameteriv, framebuffer, attachment, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, CreateRenderbuffers, GLsizei n, GLuint* renderbuffers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, CreateRenderbuffers, n, renderbuffers)
DECLARE_GL_FUNCTION_HEAD(void, NamedRenderbufferStorage, GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_END_NO_RETURN(void, NamedRenderbufferStorage, renderbuffer, internalformat, width, height)
DECLARE_GL_FUNCTION_STUB_HEAD(void, NamedRenderbufferStorageMultisample, GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, NamedRenderbufferStorageMultisample, renderbuffer, samples, internalformat, width, height)
DECLARE_GL_FUNCTION_HEAD(void, NamedRenderbufferStorageMultisample, GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_END_NO_RETURN(void, NamedRenderbufferStorageMultisample, renderbuffer, samples, internalformat, width, height)
DECLARE_GL_FUNCTION_HEAD(void, GetNamedRenderbufferParameteriv, GLuint renderbuffer, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetNamedRenderbufferParameteriv, renderbuffer, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, CreateTextures, GLenum target, GLsizei n, GLuint* textures) DECLARE_GL_FUNCTION_END_NO_RETURN(void, CreateTextures, target, n, textures)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TextureBuffer, GLuint texture, GLenum internalformat, GLuint buffer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TextureBuffer, texture, internalformat, buffer)
@@ -1038,8 +1038,8 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, TextureBufferRange, GLuint texture, GLenum i
DECLARE_GL_FUNCTION_HEAD(void, TextureStorage1D, GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureStorage1D, texture, levels, internalformat, width)
DECLARE_GL_FUNCTION_HEAD(void, TextureStorage2D, GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureStorage2D, texture, levels, internalformat, width, height)
DECLARE_GL_FUNCTION_HEAD(void, TextureStorage3D, GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureStorage3D, texture, levels, internalformat, width, height, depth)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TextureStorage2DMultisample, GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TextureStorage2DMultisample, texture, samples, internalformat, width, height, fixedsamplelocations)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TextureStorage3DMultisample, GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TextureStorage3DMultisample, texture, samples, internalformat, width, height, depth, fixedsamplelocations)
DECLARE_GL_FUNCTION_HEAD(void, TextureStorage2DMultisample, GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureStorage2DMultisample, texture, samples, internalformat, width, height, fixedsamplelocations)
DECLARE_GL_FUNCTION_HEAD(void, TextureStorage3DMultisample, GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureStorage3DMultisample, texture, samples, internalformat, width, height, depth, fixedsamplelocations)
DECLARE_GL_FUNCTION_HEAD(void, TextureSubImage1D, GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureSubImage1D, texture, level, xoffset, width, format, type, pixels)
DECLARE_GL_FUNCTION_HEAD(void, TextureSubImage2D, GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureSubImage2D, texture, level, xoffset, yoffset, width, height, format, type, pixels)
DECLARE_GL_FUNCTION_HEAD(void, TextureSubImage3D, GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureSubImage3D, texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels)
@@ -1887,7 +1887,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, GetNamedProgramivEXT, GLuint program, GLenum
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetNamedProgramStringEXT, GLuint program, GLenum target, GLenum pname, void* string) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetNamedProgramStringEXT, program, target, pname, string)
DECLARE_GL_FUNCTION_HEAD(void, NamedRenderbufferStorageEXT, GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_END_NO_RETURN(void, NamedRenderbufferStorage, renderbuffer, internalformat, width, height)
DECLARE_GL_FUNCTION_HEAD(void, GetNamedRenderbufferParameterivEXT, GLuint renderbuffer, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetNamedRenderbufferParameteriv, renderbuffer, pname, params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, NamedRenderbufferStorageMultisampleEXT, GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, NamedRenderbufferStorageMultisampleEXT, renderbuffer, samples, internalformat, width, height)
DECLARE_GL_FUNCTION_HEAD(void, NamedRenderbufferStorageMultisampleEXT, GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_END_NO_RETURN(void, NamedRenderbufferStorageMultisample, renderbuffer, samples, internalformat, width, height)
DECLARE_GL_FUNCTION_STUB_HEAD(void, NamedRenderbufferStorageMultisampleCoverageEXT, GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, NamedRenderbufferStorageMultisampleCoverageEXT, renderbuffer, coverageSamples, colorSamples, internalformat, width, height)
DECLARE_GL_FUNCTION_STUB_HEAD(GLenum, CheckNamedFramebufferStatusEXT, GLuint framebuffer, GLenum target) DECLARE_GL_FUNCTION_STUB_END(GLenum, CheckNamedFramebufferStatusEXT, framebuffer, target)
DECLARE_GL_FUNCTION_STUB_HEAD(void, NamedFramebufferTexture1DEXT, GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, NamedFramebufferTexture1DEXT, framebuffer, attachment, textarget, texture, level)
@@ -1952,8 +1952,8 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, TextureBufferRangeEXT, GLuint texture, GLenu
DECLARE_GL_FUNCTION_HEAD(void, TextureStorage1DEXT, GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureStorage1D, texture, levels, internalformat, width)
DECLARE_GL_FUNCTION_HEAD(void, TextureStorage2DEXT, GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureStorage2D, texture, levels, internalformat, width, height)
DECLARE_GL_FUNCTION_HEAD(void, TextureStorage3DEXT, GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureStorage3D, texture, levels, internalformat, width, height, depth)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TextureStorage2DMultisampleEXT, GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TextureStorage2DMultisampleEXT, texture, target, samples, internalformat, width, height, fixedsamplelocations)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TextureStorage3DMultisampleEXT, GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TextureStorage3DMultisampleEXT, texture, target, samples, internalformat, width, height, depth, fixedsamplelocations)
DECLARE_GL_FUNCTION_HEAD(void, TextureStorage2DMultisampleEXT, GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureStorage2DMultisample, texture, samples, internalformat, width, height, fixedsamplelocations)
DECLARE_GL_FUNCTION_HEAD(void, TextureStorage3DMultisampleEXT, GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TextureStorage3DMultisample, texture, samples, internalformat, width, height, depth, fixedsamplelocations)
DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexArrayBindVertexBufferEXT, GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexArrayBindVertexBufferEXT, vaobj, bindingindex, buffer, offset, stride)
DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexArrayVertexAttribFormatEXT, GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexArrayVertexAttribFormatEXT, vaobj, attribindex, size, type, normalized, relativeoffset)
DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexArrayVertexAttribIFormatEXT, GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexArrayVertexAttribIFormatEXT, vaobj, attribindex, size, type, relativeoffset)
@@ -2298,7 +2298,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, GetMapParameterfvNV, GLenum target, GLenum p
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetMapAttribParameterivNV, GLenum target, GLuint index, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetMapAttribParameterivNV, target, index, pname, params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetMapAttribParameterfvNV, GLenum target, GLuint index, GLenum pname, GLfloat* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetMapAttribParameterfvNV, target, index, pname, params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, EvalMapsNV, GLenum target, GLenum mode) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, EvalMapsNV, target, mode)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetMultisamplefvNV, GLenum pname, GLuint index, GLfloat* val) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetMultisamplefvNV, pname, index, val)
DECLARE_GL_FUNCTION_HEAD(void, GetMultisamplefvNV, GLenum pname, GLuint index, GLfloat* val) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetMultisamplefv, pname, index, val)
DECLARE_GL_FUNCTION_STUB_HEAD(void, SampleMaskIndexedNV, GLuint index, GLbitfield mask) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, SampleMaskIndexedNV, index, mask)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexRenderbufferNV, GLenum target, GLuint renderbuffer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexRenderbufferNV, target, renderbuffer)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteFencesNV, GLsizei n, const GLuint* fences) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DeleteFencesNV, n, fences)
@@ -438,6 +438,34 @@ namespace MobileGL::MG_Impl::GLImpl {
"NamedRenderbufferStorage_State");
}
void NamedRenderbufferStorageMultisample_State(GLuint renderbuffer, GLsizei samples, GLenum internalformat,
GLsizei width, GLsizei height) {
auto renderbufferObject =
GetNamedRenderbufferObject_State(renderbuffer, "NamedRenderbufferStorageMultisample_State");
if (!renderbufferObject) return;
TextureInternalFormat format = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
if (!TextureImpl::ValidateTextureInternalFormat(format)) return;
if (samples < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "NamedRenderbufferStorageMultisample_State",
"Sample count must be non-negative."));
return;
}
if (width < 0 || height < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "NamedRenderbufferStorageMultisample_State",
"Width and height must be non-negative."));
return;
}
renderbufferObject->AllocateStorage({width, height});
renderbufferObject->SetInternalFormat(format);
renderbufferObject->SetSamples(samples);
}
void GenFramebuffers_State(GLsizei n, GLuint* framebuffers) {
if (n < 0) {
MG_State::pGLContext->RecordError(
@@ -1499,6 +1527,11 @@ namespace MobileGL::MG_Impl::GLImpl {
NamedRenderbufferStorage_State(renderbuffer, internalformat, width, height);
}
void NamedRenderbufferStorageMultisample(GLuint renderbuffer, GLsizei samples, GLenum internalformat,
GLsizei width, GLsizei height) {
NamedRenderbufferStorageMultisample_State(renderbuffer, samples, internalformat, width, height);
}
void GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname, GLint* params) {
GetNamedRenderbufferParameteriv_State(renderbuffer, pname, params);
}
@@ -26,6 +26,8 @@ namespace MobileGL::MG_Impl::GLImpl {
void GenRenderbuffers(GLsizei n, GLuint* renderbuffers);
void CreateRenderbuffers(GLsizei n, GLuint* renderbuffers);
void NamedRenderbufferStorage(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
void NamedRenderbufferStorageMultisample(GLuint renderbuffer, GLsizei samples, GLenum internalformat,
GLsizei width, GLsizei height);
void GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname, GLint* params);
void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
void NamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget,
+240 -2
View File
@@ -85,6 +85,102 @@ namespace MobileGL::MG_Impl::GLImpl {
MG_Util::GetInternalBytesPerPixel(textureInternalFormat,
MG_Util::ConvertGLEnumToTexturePixelDataType(realType));
}
Bool IsMultisampleTextureTarget(TextureTarget target) {
return target == TextureTarget::Texture2DMultisample ||
target == TextureTarget::Texture2DMultisampleArray;
}
Int GetMaxSupportedTextureSamples(TextureInternalFormat textureInternalFormat) {
if (MG_Backend::pActiveBackendObject == nullptr) {
return std::numeric_limits<Int>::max();
}
const auto& dynamicParameters = MG_Backend::pActiveBackendObject->GetDynamicParameters();
if (MG_Util::IsDepthFormatInternalFormat(textureInternalFormat) ||
MG_Util::IsStencilFormatInternalFormat(textureInternalFormat)) {
return std::max(dynamicParameters.MaxDepthTextureSamples, 1);
}
GLenum normalizedInternalFormat = MG_Util::ConvertTextureInternalFormatToGLEnum(textureInternalFormat);
GLenum normalizedFormat = GL_RGBA;
GLenum normalizedType = GL_UNSIGNED_BYTE;
MG_Util::TextureFormatProcessor::NormalizePixelFormat(
normalizedInternalFormat, PixelFormatNormalizeOptionBit::None, &normalizedInternalFormat,
&normalizedFormat, &normalizedType);
const Bool isIntegerFormat = normalizedFormat == GL_RED_INTEGER || normalizedFormat == GL_RG_INTEGER ||
normalizedFormat == GL_RGB_INTEGER || normalizedFormat == GL_RGBA_INTEGER;
return std::max(isIntegerFormat ? dynamicParameters.MaxIntegerSamples
: dynamicParameters.MaxColorTextureSamples,
1);
}
Bool ValidateTextureMultisampleStorage(TextureTarget textureTarget, GLsizei samples, GLsizei width,
GLsizei height, GLsizei depth, TextureInternalFormat textureInternalFormat,
const char* caller) {
if (!IsMultisampleTextureTarget(textureTarget)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
"Target is not a multisample texture target."));
return false;
}
if (samples <= 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller, "Sample count must be positive."));
return false;
}
if (width < 0 || height < 0 || depth < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller, "Texture size must be non-negative."));
return false;
}
if (textureTarget == TextureTarget::Texture2DMultisample && depth != 1) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
"2D multisample textures must use depth 1."));
return false;
}
if (textureTarget == TextureTarget::Texture2DMultisampleArray && depth == 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
"2D multisample array textures must have at least one layer."));
return false;
}
const Int maxSamples = GetMaxSupportedTextureSamples(textureInternalFormat);
if (samples > maxSamples) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl", caller,
std::format("Sample count {} exceeds the supported maximum {} for this texture format.",
samples, maxSamples)));
return false;
}
return true;
}
void AllocateMultisampleTextureStorage(const SharedPtr<MG_State::GLState::ITextureObject>& textureObject,
TextureUploadTarget textureUploadTarget,
TextureInternalFormat textureInternalFormat, GLsizei samples,
GLsizei width, GLsizei height, GLsizei depth,
GLboolean fixedsamplelocations) {
MOBILEGL_ASSERT(textureObject != nullptr, "AllocateMultisampleTextureStorage requires a texture object");
MOBILEGL_ASSERT(textureObject->GetStorageType() == TextureStorageType::Mipmap,
"AllocateMultisampleTextureStorage requires mipmap-backed storage");
auto* textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
textureObject->SetInternalFormat(textureInternalFormat);
textureObject->SetSamples(samples);
textureObject->SetFixedSampleLocations(fixedsamplelocations == GL_TRUE);
textureMipmapObject->AllocateStorage(textureUploadTarget, 0, {{width, height, depth}, 0});
textureMipmapObject->MarkStorageDirty(textureUploadTarget, 0, false);
}
} // namespace
const SharedPtr<MG_State::GLState::ITextureObject>& GetTextureObjectByName(GLuint texture, const char* caller) {
@@ -814,12 +910,84 @@ namespace MobileGL::MG_Impl::GLImpl {
void TexImage3DMultisample_State(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) {
// TODO: implement
TextureUploadTarget textureUploadTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
if (!TextureImpl::ValidateTextureTarget(textureTarget)) return;
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadTarget)) return;
if (textureTarget != TextureTarget::Texture2DMultisampleArray) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Target must be GL_TEXTURE_2D_MULTISAMPLE_ARRAY or its proxy."));
return;
}
textureInternalFormat = MG_Util::ConvertInternalFormatToSized(textureInternalFormat, TextureInputFormat::RGBA,
TexturePixelDataType::UnsignedByte);
if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return;
if (!ValidateTextureMultisampleStorage(textureTarget, samples, width, height, depth, textureInternalFormat,
__func__))
return;
auto& activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
const Bool isProxy = TextureImpl::IsProxyTextureTarget(textureUploadTarget);
auto& textureObject =
isProxy ? TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadTarget)
: bindingSlot.GetBoundObject();
if (!TextureImpl::ValidateTextureObject(textureObject)) return;
if (textureObject->GetStorageType() != TextureStorageType::Mipmap) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Texture storage is not mipmap-backed."));
return;
}
AllocateMultisampleTextureStorage(textureObject, textureUploadTarget, textureInternalFormat, samples, width,
height, depth, fixedsamplelocations);
}
void TexImage2DMultisample_State(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height, GLboolean fixedsamplelocations) {
// TODO: implement
TextureUploadTarget textureUploadTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
if (!TextureImpl::ValidateTextureTarget(textureTarget)) return;
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadTarget)) return;
if (textureTarget != TextureTarget::Texture2DMultisample) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Target must be GL_TEXTURE_2D_MULTISAMPLE or its proxy."));
return;
}
textureInternalFormat = MG_Util::ConvertInternalFormatToSized(textureInternalFormat, TextureInputFormat::RGBA,
TexturePixelDataType::UnsignedByte);
if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return;
if (!ValidateTextureMultisampleStorage(textureTarget, samples, width, height, 1, textureInternalFormat,
__func__))
return;
auto& activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
const Bool isProxy = TextureImpl::IsProxyTextureTarget(textureUploadTarget);
auto& textureObject =
isProxy ? TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadTarget)
: bindingSlot.GetBoundObject();
if (!TextureImpl::ValidateTextureObject(textureObject)) return;
if (textureObject->GetStorageType() != TextureStorageType::Mipmap) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Texture storage is not mipmap-backed."));
return;
}
AllocateMultisampleTextureStorage(textureObject, textureUploadTarget, textureInternalFormat, samples, width,
height, 1, fixedsamplelocations);
}
void TexImage3D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
@@ -1505,6 +1673,16 @@ namespace MobileGL::MG_Impl::GLImpl {
*params = (GLint)MG_Util::ConvertTextureInternalFormatToGLEnum(textureObject->GetFormat());
}
break;
case GL_TEXTURE_SAMPLES:
if (params) {
*params = textureObject->GetSamples();
}
break;
case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
if (params) {
*params = textureObject->HasFixedSampleLocations() ? GL_TRUE : GL_FALSE;
}
break;
case GL_TEXTURE_RED_TYPE:
case GL_TEXTURE_GREEN_TYPE:
case GL_TEXTURE_BLUE_TYPE:
@@ -1595,6 +1773,16 @@ namespace MobileGL::MG_Impl::GLImpl {
*params = (GLfloat)MG_Util::ConvertTextureInternalFormatToGLEnum(textureObject->GetFormat());
}
break;
case GL_TEXTURE_SAMPLES:
if (params) {
*params = static_cast<GLfloat>(textureObject->GetSamples());
}
break;
case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
if (params) {
*params = textureObject->HasFixedSampleLocations() ? 1.0f : 0.0f;
}
break;
case GL_TEXTURE_RED_TYPE:
case GL_TEXTURE_GREEN_TYPE:
case GL_TEXTURE_BLUE_TYPE:
@@ -2157,6 +2345,22 @@ namespace MobileGL::MG_Impl::GLImpl {
}
}
void TextureStorage2DMultisample(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height, GLboolean fixedsamplelocations) {
auto textureObject = GetTextureObjectByName(texture, __func__);
WithTemporarilyBoundNamedTexture(textureObject, [&](GLenum target) {
TexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations);
});
}
void TextureStorage3DMultisample(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) {
auto textureObject = GetTextureObjectByName(texture, __func__);
WithTemporarilyBoundNamedTexture(textureObject, [&](GLenum target) {
TexStorage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations);
});
}
void TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) {
const auto textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
const auto textureUploadTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
@@ -2200,6 +2404,16 @@ namespace MobileGL::MG_Impl::GLImpl {
TextureStorage3D(textureObject->GetExternalIndex(), levels, internalformat, width, height, depth);
}
void TexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height, GLboolean fixedsamplelocations) {
TexImage2DMultisample_State(target, samples, internalformat, width, height, fixedsamplelocations);
}
void TexStorage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) {
TexImage3DMultisample_State(target, samples, internalformat, width, height, depth, fixedsamplelocations);
}
void TextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type,
const void* pixels) {
auto textureObject = GetTextureObjectByName(texture, __func__);
@@ -2613,6 +2827,30 @@ namespace MobileGL::MG_Impl::GLImpl {
}
}
void GetMultisamplefv(GLenum pname, GLuint index, GLfloat* val) {
if (val == nullptr) return;
if (pname != GL_SAMPLE_POSITION) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Only GL_SAMPLE_POSITION is supported."));
return;
}
const Int maxSamples = MG_Backend::pActiveBackendObject != nullptr
? std::max(MG_Backend::pActiveBackendObject->GetDynamicParameters().MaxSamples, 1)
: 1;
if (static_cast<Int>(index) >= maxSamples) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Sample index is out of range."));
return;
}
// Keep sample positions deterministic even before the backend exposes vendor-specific patterns.
val[0] = 0.5f;
val[1] = 0.5f;
}
void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width,
GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) {
TexSubImage3D_State(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
@@ -20,6 +20,10 @@ namespace MobileGL::MG_Impl::GLImpl {
void TextureStorage2D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
void TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth);
void TextureStorage2DMultisample(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height, GLboolean fixedsamplelocations);
void TextureStorage3DMultisample(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
void TextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type,
const void* pixels);
void TextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
@@ -47,6 +51,10 @@ namespace MobileGL::MG_Impl::GLImpl {
void TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
void TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth);
void TexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height, GLboolean fixedsamplelocations);
void TexStorage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width,
GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels);
void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
@@ -78,6 +86,7 @@ namespace MobileGL::MG_Impl::GLImpl {
void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
void GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params);
void GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params);
void GetMultisamplefv(GLenum pname, GLuint index, GLfloat* val);
void GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
void GetCompressedTexImage(GLenum target, GLint level, void* img);
void GenTextures(GLsizei n, GLuint* textures);
@@ -230,6 +230,18 @@ namespace MobileGL::MG_Impl::GLImpl::TextureImpl {
return false;
}
}
if (target == TextureUploadTarget::Texture2DMultisample ||
target == TextureUploadTarget::ProxyTexture2DMultisample ||
target == TextureUploadTarget::Texture2DMultisampleArray ||
target == TextureUploadTarget::ProxyTexture2DMultisampleArray) {
if (level != 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureLevelWithUploadTarget",
"Level must be zero for multisample textures"));
return false;
}
}
return true;
}
@@ -139,6 +139,22 @@ namespace MobileGL {
return m_textureParamsVersion;
}
Int TextureObjectBase::GetSamples() const {
return m_samples;
}
void TextureObjectBase::SetSamples(Int samples) {
m_samples = samples;
}
Bool TextureObjectBase::HasFixedSampleLocations() const {
return m_fixedSampleLocations;
}
void TextureObjectBase::SetFixedSampleLocations(Bool fixedSampleLocations) {
m_fixedSampleLocations = fixedSampleLocations;
}
Uint TextureObjectWithOneMipmap::GetMipmapLevelCount() const {
return m_textureStorage.GetLevelCount();
}
@@ -40,6 +40,10 @@ namespace MobileGL::MG_State::GLState {
virtual void SetBaseLevel(Uint baseLevel) = 0;
virtual void SetMaxLevel(Uint maxLevel) = 0;
virtual Uint16 GetTextureParamsVersion() const = 0;
virtual Int GetSamples() const = 0;
virtual void SetSamples(Int samples) = 0;
virtual Bool HasFixedSampleLocations() const = 0;
virtual void SetFixedSampleLocations(Bool fixedSampleLocations) = 0;
protected:
virtual Uint GetIndexOfTextureUploadTarget(TextureUploadTarget target) const = 0;
@@ -67,6 +71,10 @@ namespace MobileGL::MG_State::GLState {
void SetBaseLevel(Uint baseLevel) override;
void SetMaxLevel(Uint maxLevel) override;
Uint16 GetTextureParamsVersion() const override;
Int GetSamples() const override;
void SetSamples(Int samples) override;
Bool HasFixedSampleLocations() const override;
void SetFixedSampleLocations(Bool fixedSampleLocations) override;
protected:
const Uint m_externalIndex;
@@ -78,6 +86,8 @@ namespace MobileGL::MG_State::GLState {
TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha};
UintVec2 m_levelRange = {0, 1000};
Uint16 m_textureParamsVersion = 0;
Int m_samples = 0;
Bool m_fixedSampleLocations = true;
};
class TextureObjectMipmap : public TextureObjectBase {
@@ -15,12 +15,11 @@ namespace MobileGL {
namespace GLState {
/* These texture types are not yet implemented:
* TextureRectangle,
* Texture2DMultisample,
* TextureBuffer,
* Texture1DArray,
* Texture2DArray,
* TextureCubeMapArray,
* Texture2DMultisampleArray
* Texture2DMultisampleArray layered attachment behavior
*/
#define STUB_TEXTURE_OBJECT_CLASS_DEFINITION(className, texTarget, uploadTargets) \
class className : public TextureObjectWithOneMipmap { \
@@ -58,4 +57,4 @@ namespace MobileGL {
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
} // namespace MobileGL
@@ -57,7 +57,7 @@ namespace MobileGL::MG_State::GLState {
textureObject = MakeShared<TextureObjectBuffer>(index);
break;
// These texture types are stubbed:
// These texture types are still stubbed:
case TextureTarget::TextureRectangle:
textureObject = MakeShared<TextureObjectRectangle>(index);
break;
+27
View File
@@ -123,6 +123,33 @@ TEST_F(TextureTest, BoundTexStorage2DAllocatesRedTextureForSubImageUpdates) {
EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR);
}
TEST_F(TextureTest, TextureStorage2DMultisampleTracksNamedObjectState) {
GLuint texture = 0;
MG_Impl::GLImpl::CreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &texture);
MG_Impl::GLImpl::TextureStorage2DMultisample(texture, 4, GL_RGBA8, 8, 6, GL_TRUE);
const auto textureObject = MG_State::pGLContext->GetTextureObject(texture);
ASSERT_NE(textureObject, nullptr);
EXPECT_EQ(textureObject->GetTarget(), TextureTarget::Texture2DMultisample);
EXPECT_EQ(textureObject->GetSamples(), 4);
EXPECT_TRUE(textureObject->HasFixedSampleLocations());
auto* textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
ASSERT_NE(textureMipmapObject, nullptr);
EXPECT_EQ(textureMipmapObject->GetMipmapLevelCount(), 1u);
EXPECT_EQ(textureMipmapObject->GetMipmapTexelSize(TextureUploadTarget::Texture2DMultisample, 0), IntVec3(8, 6, 1));
EXPECT_FALSE(textureMipmapObject->IsStorageDirty(TextureUploadTarget::Texture2DMultisample, 0));
GLint samples = 0;
GLint fixed = 0;
MG_Impl::GLImpl::GetTextureLevelParameteriv(texture, 0, GL_TEXTURE_SAMPLES, &samples);
MG_Impl::GLImpl::GetTextureLevelParameteriv(texture, 0, GL_TEXTURE_FIXED_SAMPLE_LOCATIONS, &fixed);
EXPECT_EQ(samples, 4);
EXPECT_EQ(fixed, GL_TRUE);
EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR);
}
TEST_F(TextureTest, GetTextureImageReadsNamedObjectWithoutBinding) {
GLuint texture = 0;
MG_Impl::GLImpl::CreateTextures(GL_TEXTURE_2D, 1, &texture);