mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 13:48:30 +09:00
[Feat] (MG_Impl, MG_Backend): implement the integer direct state access framebuffer clears
glClearNamedFramebufferiv and glClearNamedFramebufferuiv were stubs, so a clear through them was silently dropped and the attachment kept whatever it held. Their float siblings were already implemented, which is what made the gap look like a rendering bug rather than a missing entry point. Which buffers they accept is narrower than glClearNamedFramebufferfv and differs between the two: signed values clear COLOR or STENCIL, unsigned only COLOR (GL 4.6 core 17.4.3.1). Only the colour buffer is indexed, so a stencil clear naming any drawbuffer other than 0 is INVALID_VALUE rather than merely ignored, and anything else is INVALID_ENUM. Resolving the framebuffer by name goes through the same helper the float forms use, which is what reports INVALID_OPERATION for a name that is neither zero nor an existing framebuffer. Both backends express them the way they already express the float forms: DirectGLES binds the named framebuffer and forwards to glClearBuffer*, Magma queues the payload against the named framebuffer rather than the bound one. direct_state_access.framebuffers_clear_errors passes on both backends, and framebuffers_clear passes on Espryt. Magma still fails that one, for a separate reason on the materialization side rather than in these entry points.
This commit is contained in:
@@ -145,6 +145,10 @@ namespace MobileGL {
|
|||||||
GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
||||||
void (*ClearNamedFramebufferfi)(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
void (*ClearNamedFramebufferfi)(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||||
|
void (*ClearNamedFramebufferiv)(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
|
GLenum buffer, GLint drawbuffer, const GLint* value);
|
||||||
|
void (*ClearNamedFramebufferuiv)(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
|
GLenum buffer, GLint drawbuffer, const GLuint* value);
|
||||||
void (*BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0,
|
void (*BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0,
|
||||||
GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
|
GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
|
||||||
void (*BlitNamedFramebuffer)(const SharedPtr<MG_State::GLState::FramebufferObject>& readFramebuffer,
|
void (*BlitNamedFramebuffer)(const SharedPtr<MG_State::GLState::FramebufferObject>& readFramebuffer,
|
||||||
|
|||||||
@@ -988,6 +988,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
funcsTable.GL.ClearBufferuiv = ClearBufferuiv;
|
funcsTable.GL.ClearBufferuiv = ClearBufferuiv;
|
||||||
funcsTable.GL.ClearBufferiv = ClearBufferiv;
|
funcsTable.GL.ClearBufferiv = ClearBufferiv;
|
||||||
funcsTable.GL.ClearNamedFramebufferfv = ClearNamedFramebufferfv;
|
funcsTable.GL.ClearNamedFramebufferfv = ClearNamedFramebufferfv;
|
||||||
|
funcsTable.GL.ClearNamedFramebufferiv = ClearNamedFramebufferiv;
|
||||||
|
funcsTable.GL.ClearNamedFramebufferuiv = ClearNamedFramebufferuiv;
|
||||||
funcsTable.GL.ClearNamedFramebufferfi = ClearNamedFramebufferfi;
|
funcsTable.GL.ClearNamedFramebufferfi = ClearNamedFramebufferfi;
|
||||||
funcsTable.GL.BlitFramebuffer = BlitFramebuffer;
|
funcsTable.GL.BlitFramebuffer = BlitFramebuffer;
|
||||||
funcsTable.GL.BlitNamedFramebuffer = BlitNamedFramebuffer;
|
funcsTable.GL.BlitNamedFramebuffer = BlitNamedFramebuffer;
|
||||||
|
|||||||
@@ -4431,6 +4431,40 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
ForceBindCurrentFBO(FramebufferTarget::Draw);
|
ForceBindCurrentFBO(FramebufferTarget::Draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearNamedFramebufferiv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
|
GLenum buffer, GLint drawbuffer, const GLint* value) {
|
||||||
|
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG && MOBILEGL_ENABLE_SCOPE_MARKER
|
||||||
|
DebugImpl::OpenGLScopeMarker marker(__func__);
|
||||||
|
#endif
|
||||||
|
TextureImpl::SyncNeccessaryTextures();
|
||||||
|
RenderStateImpl::SyncRenderState();
|
||||||
|
|
||||||
|
SyncAndBindFramebufferObject(framebuffer, FramebufferTarget::Draw, true);
|
||||||
|
g_GLESFuncs.glClearBufferiv(buffer, drawbuffer, value);
|
||||||
|
DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
|
||||||
|
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
|
||||||
|
});
|
||||||
|
|
||||||
|
ForceBindCurrentFBO(FramebufferTarget::Draw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearNamedFramebufferuiv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
|
GLenum buffer, GLint drawbuffer, const GLuint* value) {
|
||||||
|
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG && MOBILEGL_ENABLE_SCOPE_MARKER
|
||||||
|
DebugImpl::OpenGLScopeMarker marker(__func__);
|
||||||
|
#endif
|
||||||
|
TextureImpl::SyncNeccessaryTextures();
|
||||||
|
RenderStateImpl::SyncRenderState();
|
||||||
|
|
||||||
|
SyncAndBindFramebufferObject(framebuffer, FramebufferTarget::Draw, true);
|
||||||
|
g_GLESFuncs.glClearBufferuiv(buffer, drawbuffer, value);
|
||||||
|
DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
|
||||||
|
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
|
||||||
|
});
|
||||||
|
|
||||||
|
ForceBindCurrentFBO(FramebufferTarget::Draw);
|
||||||
|
}
|
||||||
|
|
||||||
static SizeT AlignPixelRow(SizeT rowBytes, Int alignment) {
|
static SizeT AlignPixelRow(SizeT rowBytes, Int alignment) {
|
||||||
const SizeT resolvedAlignment = static_cast<SizeT>(std::max(alignment, 1));
|
const SizeT resolvedAlignment = static_cast<SizeT>(std::max(alignment, 1));
|
||||||
return (rowBytes + resolvedAlignment - 1) & ~(resolvedAlignment - 1);
|
return (rowBytes + resolvedAlignment - 1) & ~(resolvedAlignment - 1);
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
||||||
void ClearNamedFramebufferfi(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
void ClearNamedFramebufferfi(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||||
|
void ClearNamedFramebufferiv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
|
GLenum buffer, GLint drawbuffer, const GLint* value);
|
||||||
|
void ClearNamedFramebufferuiv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
|
GLenum buffer, GLint drawbuffer, const GLuint* value);
|
||||||
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
|
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
|
||||||
GLint dstY1, GLbitfield mask, GLenum filter);
|
GLint dstY1, GLbitfield mask, GLenum filter);
|
||||||
void BlitNamedFramebuffer(const SharedPtr<MG_State::GLState::FramebufferObject>& readFramebuffer,
|
void BlitNamedFramebuffer(const SharedPtr<MG_State::GLState::FramebufferObject>& readFramebuffer,
|
||||||
|
|||||||
@@ -597,6 +597,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
funcsTable.GL.ClearBufferiv = ClearBufferiv;
|
funcsTable.GL.ClearBufferiv = ClearBufferiv;
|
||||||
funcsTable.GL.ClearNamedFramebufferfv = ClearNamedFramebufferfv;
|
funcsTable.GL.ClearNamedFramebufferfv = ClearNamedFramebufferfv;
|
||||||
funcsTable.GL.ClearNamedFramebufferfi = ClearNamedFramebufferfi;
|
funcsTable.GL.ClearNamedFramebufferfi = ClearNamedFramebufferfi;
|
||||||
|
funcsTable.GL.ClearNamedFramebufferiv = ClearNamedFramebufferiv;
|
||||||
|
funcsTable.GL.ClearNamedFramebufferuiv = ClearNamedFramebufferuiv;
|
||||||
funcsTable.GL.BlitFramebuffer = BlitFramebuffer;
|
funcsTable.GL.BlitFramebuffer = BlitFramebuffer;
|
||||||
funcsTable.GL.BlitNamedFramebuffer = BlitNamedFramebuffer;
|
funcsTable.GL.BlitNamedFramebuffer = BlitNamedFramebuffer;
|
||||||
funcsTable.GL.CopyTexImage2D = CopyTexImage2D;
|
funcsTable.GL.CopyTexImage2D = CopyTexImage2D;
|
||||||
|
|||||||
@@ -440,6 +440,20 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
pVulkanRenderer->ClearNamedFramebufferfv(framebuffer, buffer, drawbuffer, value);
|
pVulkanRenderer->ClearNamedFramebufferfv(framebuffer, buffer, drawbuffer, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearNamedFramebufferiv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer,
|
||||||
|
GLint drawbuffer, const GLint* value) {
|
||||||
|
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearNamedFramebufferiv called with null VulkanRenderer");
|
||||||
|
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ClearNamedFramebufferiv called with null GL context");
|
||||||
|
pVulkanRenderer->ClearNamedFramebufferiv(framebuffer, buffer, drawbuffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearNamedFramebufferuiv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer,
|
||||||
|
GLint drawbuffer, const GLuint* value) {
|
||||||
|
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearNamedFramebufferuiv called with null VulkanRenderer");
|
||||||
|
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ClearNamedFramebufferuiv called with null GL context");
|
||||||
|
pVulkanRenderer->ClearNamedFramebufferuiv(framebuffer, buffer, drawbuffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
void ClearNamedFramebufferfi(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer,
|
void ClearNamedFramebufferfi(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer,
|
||||||
GLint drawbuffer, GLfloat depth, GLint stencil) {
|
GLint drawbuffer, GLfloat depth, GLint stencil) {
|
||||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearNamedFramebufferfi called with null VulkanRenderer");
|
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearNamedFramebufferfi called with null VulkanRenderer");
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value);
|
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value);
|
||||||
void ClearNamedFramebufferfv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer,
|
void ClearNamedFramebufferfv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer,
|
||||||
GLint drawbuffer, const GLfloat* value);
|
GLint drawbuffer, const GLfloat* value);
|
||||||
|
void ClearNamedFramebufferiv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer,
|
||||||
|
GLint drawbuffer, const GLint* value);
|
||||||
|
void ClearNamedFramebufferuiv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer,
|
||||||
|
GLint drawbuffer, const GLuint* value);
|
||||||
void ClearNamedFramebufferfi(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer,
|
void ClearNamedFramebufferfi(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer,
|
||||||
GLint drawbuffer, GLfloat depth, GLint stencil);
|
GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||||
void Clear(GLbitfield mask);
|
void Clear(GLbitfield mask);
|
||||||
|
|||||||
@@ -5771,6 +5771,46 @@ void main() {
|
|||||||
QueueClearBufferPayloadForFramebuffer(*framebuffer, buffer, drawbuffer, payload);
|
QueueClearBufferPayloadForFramebuffer(*framebuffer, buffer, drawbuffer, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The integer clears carry the same payload as their target-based siblings; only the
|
||||||
|
// destination differs, so they queue against the named framebuffer rather than the bound one.
|
||||||
|
void VulkanRenderer::ClearNamedFramebufferiv(
|
||||||
|
const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer, GLint drawbuffer,
|
||||||
|
const GLint* value) {
|
||||||
|
if (!framebuffer || value == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ClearAttachmentPayload payload{};
|
||||||
|
switch (buffer) {
|
||||||
|
case GL_COLOR:
|
||||||
|
payload.mask = GL_COLOR_BUFFER_BIT;
|
||||||
|
payload.color = FloatVec4(static_cast<Float>(value[0]), static_cast<Float>(value[1]),
|
||||||
|
static_cast<Float>(value[2]), static_cast<Float>(value[3]));
|
||||||
|
break;
|
||||||
|
case GL_STENCIL:
|
||||||
|
payload.mask = GL_STENCIL_BUFFER_BIT;
|
||||||
|
payload.stencil = static_cast<Uint32>(std::max(value[0], 0));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QueueClearBufferPayloadForFramebuffer(*framebuffer, buffer, drawbuffer, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanRenderer::ClearNamedFramebufferuiv(
|
||||||
|
const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer, GLint drawbuffer,
|
||||||
|
const GLuint* value) {
|
||||||
|
if (!framebuffer || value == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ClearAttachmentPayload payload{};
|
||||||
|
if (buffer == GL_COLOR) {
|
||||||
|
payload.mask = GL_COLOR_BUFFER_BIT;
|
||||||
|
payload.color = FloatVec4(static_cast<Float>(value[0]), static_cast<Float>(value[1]),
|
||||||
|
static_cast<Float>(value[2]), static_cast<Float>(value[3]));
|
||||||
|
}
|
||||||
|
QueueClearBufferPayloadForFramebuffer(*framebuffer, buffer, drawbuffer, payload);
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanRenderer::ClearNamedFramebufferfi(
|
void VulkanRenderer::ClearNamedFramebufferfi(
|
||||||
const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer, GLint drawbuffer,
|
const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer, GLint drawbuffer,
|
||||||
GLfloat depth, GLint stencil) {
|
GLfloat depth, GLint stencil) {
|
||||||
|
|||||||
@@ -181,6 +181,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value);
|
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value);
|
||||||
void ClearNamedFramebufferfv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
void ClearNamedFramebufferfv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
||||||
|
void ClearNamedFramebufferiv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
|
GLenum buffer, GLint drawbuffer, const GLint* value);
|
||||||
|
void ClearNamedFramebufferuiv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
|
GLenum buffer, GLint drawbuffer, const GLuint* value);
|
||||||
void ClearNamedFramebufferfi(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
void ClearNamedFramebufferfi(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||||
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
||||||
|
|||||||
@@ -1036,8 +1036,8 @@ DECLARE_GL_FUNCTION_HEAD(void, NamedFramebufferDrawBuffers, GLuint framebuffer,
|
|||||||
DECLARE_GL_FUNCTION_HEAD(void, NamedFramebufferReadBuffer, GLuint framebuffer, GLenum src) DECLARE_GL_FUNCTION_END_NO_RETURN(void, NamedFramebufferReadBuffer, framebuffer, src)
|
DECLARE_GL_FUNCTION_HEAD(void, NamedFramebufferReadBuffer, GLuint framebuffer, GLenum src) DECLARE_GL_FUNCTION_END_NO_RETURN(void, NamedFramebufferReadBuffer, framebuffer, src)
|
||||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, InvalidateNamedFramebufferData, GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, InvalidateNamedFramebufferData, framebuffer, numAttachments, attachments)
|
DECLARE_GL_FUNCTION_STUB_HEAD(void, InvalidateNamedFramebufferData, GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, InvalidateNamedFramebufferData, framebuffer, numAttachments, attachments)
|
||||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, InvalidateNamedFramebufferSubData, GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, InvalidateNamedFramebufferSubData, framebuffer, numAttachments, attachments, x, y, width, height)
|
DECLARE_GL_FUNCTION_STUB_HEAD(void, InvalidateNamedFramebufferSubData, GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, InvalidateNamedFramebufferSubData, framebuffer, numAttachments, attachments, x, y, width, height)
|
||||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, ClearNamedFramebufferiv, GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ClearNamedFramebufferiv, framebuffer, buffer, drawbuffer, value)
|
DECLARE_GL_FUNCTION_HEAD(void, ClearNamedFramebufferiv, GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ClearNamedFramebufferiv, framebuffer, buffer, drawbuffer, value)
|
||||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, ClearNamedFramebufferuiv, GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ClearNamedFramebufferuiv, framebuffer, buffer, drawbuffer, value)
|
DECLARE_GL_FUNCTION_HEAD(void, ClearNamedFramebufferuiv, GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ClearNamedFramebufferuiv, framebuffer, buffer, drawbuffer, value)
|
||||||
DECLARE_GL_FUNCTION_HEAD(void, ClearNamedFramebufferfv, GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ClearNamedFramebufferfv, framebuffer, buffer, drawbuffer, value)
|
DECLARE_GL_FUNCTION_HEAD(void, ClearNamedFramebufferfv, GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ClearNamedFramebufferfv, framebuffer, buffer, drawbuffer, value)
|
||||||
DECLARE_GL_FUNCTION_HEAD(void, ClearNamedFramebufferfi, GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ClearNamedFramebufferfi, framebuffer, buffer, drawbuffer, depth, stencil)
|
DECLARE_GL_FUNCTION_HEAD(void, ClearNamedFramebufferfi, GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ClearNamedFramebufferfi, framebuffer, buffer, drawbuffer, depth, stencil)
|
||||||
DECLARE_GL_FUNCTION_HEAD(void, BlitNamedFramebuffer, GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlitNamedFramebuffer, readFramebuffer, drawFramebuffer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter)
|
DECLARE_GL_FUNCTION_HEAD(void, BlitNamedFramebuffer, GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlitNamedFramebuffer, readFramebuffer, drawFramebuffer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter)
|
||||||
|
|||||||
@@ -467,6 +467,26 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
clearNamedFramebufferfi(framebuffer, buffer, drawbuffer, depth, stencil);
|
clearNamedFramebufferfi(framebuffer, buffer, drawbuffer, depth, stencil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearNamedFramebufferiv_Backend(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
|
GLenum buffer, GLint drawbuffer, const GLint* value) {
|
||||||
|
auto clearNamedFramebufferiv = MG_Backend::gBackendFunctionsTable.GL.ClearNamedFramebufferiv;
|
||||||
|
if (!clearNamedFramebufferiv) {
|
||||||
|
MGLOG_E("glClearNamedFramebufferiv skipped: backend does not implement explicit framebuffer clear.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearNamedFramebufferiv(framebuffer, buffer, drawbuffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearNamedFramebufferuiv_Backend(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||||
|
GLenum buffer, GLint drawbuffer, const GLuint* value) {
|
||||||
|
auto clearNamedFramebufferuiv = MG_Backend::gBackendFunctionsTable.GL.ClearNamedFramebufferuiv;
|
||||||
|
if (!clearNamedFramebufferuiv) {
|
||||||
|
MGLOG_E("glClearNamedFramebufferuiv skipped: backend does not implement explicit framebuffer clear.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearNamedFramebufferuiv(framebuffer, buffer, drawbuffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
void SampleMaski_State(GLuint maskNumber, GLbitfield mask) {
|
void SampleMaski_State(GLuint maskNumber, GLbitfield mask) {
|
||||||
if (maskNumber != 0) {
|
if (maskNumber != 0) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
@@ -1586,6 +1606,66 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
ClearNamedFramebufferfi_Backend(framebufferObject, buffer, drawbuffer, depth, stencil);
|
ClearNamedFramebufferfi_Backend(framebufferObject, buffer, drawbuffer, depth, stencil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Which buffers the integer clears accept is narrower than the float one, and differs between
|
||||||
|
// them: signed values can clear COLOR or STENCIL, unsigned only COLOR (GL 4.6 core 17.4.3.1).
|
||||||
|
// Only the colour buffer is indexed; a stencil clear names the single stencil buffer, so any
|
||||||
|
// drawbuffer other than 0 is out of range rather than merely unused.
|
||||||
|
Bool ValidateNamedClearIntegerv_State(GLenum buffer, GLint drawbuffer, const void* value, Bool allowStencil,
|
||||||
|
const char* caller) {
|
||||||
|
if (!value) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidValue,
|
||||||
|
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller, "value pointer cannot be null."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (buffer == GL_STENCIL && allowStencil) {
|
||||||
|
if (drawbuffer != 0) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidValue,
|
||||||
|
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller, "stencil clear requires drawbuffer 0."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidEnum,
|
||||||
|
MakeUnique<GenericErrorInfo>(
|
||||||
|
"MG_Impl/GLImpl", caller,
|
||||||
|
std::format("buffer {} is not accepted for this clear.", MG_Util::ConvertGLEnumToString(buffer))));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearNamedFramebufferiv_State(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value) {
|
||||||
|
auto framebufferObject = GetFramebufferObjectForNamedClear(framebuffer, "ClearNamedFramebufferiv_State");
|
||||||
|
if (!framebufferObject) return;
|
||||||
|
if (!ValidateNamedClearIntegerv_State(buffer, drawbuffer, value, true, "ClearNamedFramebufferiv_State")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ClearNamedFramebufferiv_Backend(framebufferObject, buffer, drawbuffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearNamedFramebufferuiv_State(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value) {
|
||||||
|
auto framebufferObject = GetFramebufferObjectForNamedClear(framebuffer, "ClearNamedFramebufferuiv_State");
|
||||||
|
if (!framebufferObject) return;
|
||||||
|
if (!ValidateNamedClearIntegerv_State(buffer, drawbuffer, value, false, "ClearNamedFramebufferuiv_State")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ClearNamedFramebufferuiv_Backend(framebufferObject, buffer, drawbuffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
void DeleteRenderbuffers_State(GLsizei n, const GLuint* renderbuffers) {
|
void DeleteRenderbuffers_State(GLsizei n, const GLuint* renderbuffers) {
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
@@ -2273,6 +2353,14 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
ClearBufferiv_Backend(buffer, drawbuffer, value);
|
ClearBufferiv_Backend(buffer, drawbuffer, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value) {
|
||||||
|
ClearNamedFramebufferiv_State(framebuffer, buffer, drawbuffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value) {
|
||||||
|
ClearNamedFramebufferuiv_State(framebuffer, buffer, drawbuffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
void SampleMaski(GLuint maskNumber, GLbitfield mask) {
|
void SampleMaski(GLuint maskNumber, GLbitfield mask) {
|
||||||
SampleMaski_State(maskNumber, mask);
|
SampleMaski_State(maskNumber, mask);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
void NamedFramebufferReadBuffer(GLuint framebuffer, GLenum src);
|
void NamedFramebufferReadBuffer(GLuint framebuffer, GLenum src);
|
||||||
void ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
void ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
||||||
void ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
void ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||||
|
void ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value);
|
||||||
|
void ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value);
|
||||||
GLenum CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target);
|
GLenum CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target);
|
||||||
void GetNamedFramebufferAttachmentParameteriv(GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params);
|
void GetNamedFramebufferAttachmentParameteriv(GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params);
|
||||||
void BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1,
|
void BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1,
|
||||||
|
|||||||
Reference in New Issue
Block a user