mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-10 05:08:31 +09:00
[Fix] (DirectVulkan): clear an integer colour buffer with an integer value
glClearBufferiv and glClearBufferuiv flattened their values into the payload's float vector, and every clear was later written into VkClearColorValue::float32. Vulkan reads that union according to the destination image's format rather than converting between its members, so an R8I attachment cleared to -16 received the bit pattern of -16.0f. On top of that, QueueRenderbufferClear copied only the float vector into the pending clear, so even the flattened value was dropped and the attachment kept reading zero - which is what the conformance tests actually observed. The payload now records which of the three entry points supplied the colour and keeps the value in that form, and one helper builds the union member the encoding calls for. GL's rule that a format with no alpha channel reads as one has to be applied in the value's own type, so the "does this format lack alpha" question is now asked separately from the substitution and the helper applies it to whichever member is live. glClear is left on the float path explicitly: ClearFramebufferPayload has no other form. Takes every integer renderbuffer format in direct_state_access.renderbuffers_storage from failing to passing on Magma - 115 reported mismatches down to 20, the rest being the stencil formats Espryt fails too and SRGB8_ALPHA8 - and makes framebuffers_clear pass on both backends.
This commit is contained in:
@@ -17,6 +17,45 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
target <= TextureUploadTarget::CubeMapNegativeZ;
|
||||
}
|
||||
|
||||
VkClearColorValue MakeVkClearColorValue(const ClearAttachmentPayload& payload, Bool formatLacksAlpha) {
|
||||
VkClearColorValue clearValue{};
|
||||
switch (payload.colorEncoding) {
|
||||
case ClearColorEncoding::Int:
|
||||
clearValue.int32[0] = payload.colorInt.x();
|
||||
clearValue.int32[1] = payload.colorInt.y();
|
||||
clearValue.int32[2] = payload.colorInt.z();
|
||||
clearValue.int32[3] = formatLacksAlpha ? 1 : payload.colorInt.w();
|
||||
break;
|
||||
case ClearColorEncoding::Uint:
|
||||
clearValue.uint32[0] = payload.colorUint.x();
|
||||
clearValue.uint32[1] = payload.colorUint.y();
|
||||
clearValue.uint32[2] = payload.colorUint.z();
|
||||
clearValue.uint32[3] = formatLacksAlpha ? 1u : payload.colorUint.w();
|
||||
break;
|
||||
case ClearColorEncoding::Float:
|
||||
clearValue.float32[0] = payload.color.x();
|
||||
clearValue.float32[1] = payload.color.y();
|
||||
clearValue.float32[2] = payload.color.z();
|
||||
clearValue.float32[3] = formatLacksAlpha ? 1.0f : payload.color.w();
|
||||
break;
|
||||
}
|
||||
return clearValue;
|
||||
}
|
||||
|
||||
void ForceOpaqueClearAlpha(ClearAttachmentPayload& payload) {
|
||||
switch (payload.colorEncoding) {
|
||||
case ClearColorEncoding::Int:
|
||||
payload.colorInt = IntVec4(payload.colorInt.x(), payload.colorInt.y(), payload.colorInt.z(), 1);
|
||||
break;
|
||||
case ClearColorEncoding::Uint:
|
||||
payload.colorUint = UintVec4(payload.colorUint.x(), payload.colorUint.y(), payload.colorUint.z(), 1u);
|
||||
break;
|
||||
case ClearColorEncoding::Float:
|
||||
payload.color = FloatVec4(payload.color.x(), payload.color.y(), payload.color.z(), 1.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Bool PendingClearMatchesTextureIdentity(const PendingClearKey& key, const TextureIdentity& identity) {
|
||||
return key.texture == identity.texture && key.textureLifetimeId == identity.lifetimeId;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user