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:
@@ -5771,6 +5771,46 @@ void main() {
|
||||
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(
|
||||
const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer, GLenum buffer, GLint drawbuffer,
|
||||
GLfloat depth, GLint stencil) {
|
||||
|
||||
@@ -181,6 +181,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value);
|
||||
void ClearNamedFramebufferfv(const SharedPtr<MG_State::GLState::FramebufferObject>& framebuffer,
|
||||
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,
|
||||
GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
||||
|
||||
Reference in New Issue
Block a user