[MG_Backend] (Disaggregated): P5f fm - retain blit scissor clipping across wire arm

This commit is contained in:
2026-09-19 22:20:53 -04:00
parent 911cc74a57
commit 4b3afe7840
2 changed files with 32 additions and 32 deletions
+1 -1
View File
@@ -10,7 +10,7 @@
#include <Includes.h>
#include "MG_State/GLState/TextureState/TextureEnum.h"
#if MOBILEGL_BUILD_DISAGGREGATED
#include <MG_Pipe/MGPipeTypes.h>
#include <MG_Pipe/MGPipeHandles.h>
#endif
namespace MobileGL {
@@ -8994,6 +8994,37 @@ void main() {
void VulkanRenderer::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter) {
// The scissor test clips blit writes: intersect the destination rectangle with
// the scissor box and shrink the source proportionally.
if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::ScissorTest)) {
const IntVec4& scissor = MGB_CTX->GetScissorBox();
const auto clipAxis = [](GLint& d0, GLint& d1, GLint& s0, GLint& s1, GLint clipLo, GLint clipHi) -> Bool {
const Bool dstFlipped = d1 < d0;
GLint lo = dstFlipped ? d1 : d0;
GLint hi = dstFlipped ? d0 : d1;
const GLint newLo = std::max(lo, clipLo);
const GLint newHi = std::min(hi, clipHi);
if (newLo >= newHi) {
return false;
}
const double srcSpan = static_cast<double>(s1 - s0);
const double dstSpan = static_cast<double>(d1 - d0);
const double scale = dstSpan != 0.0 ? srcSpan / dstSpan : 0.0;
const GLint origD0 = d0;
const GLint clippedD0 = dstFlipped ? newHi : newLo;
const GLint clippedD1 = dstFlipped ? newLo : newHi;
s0 = s0 + static_cast<GLint>(std::lround((clippedD0 - origD0) * scale));
s1 = s0 + static_cast<GLint>(std::lround((clippedD1 - clippedD0) * scale));
d0 = clippedD0;
d1 = clippedD1;
return true;
};
if (!clipAxis(dstX0, dstX1, srcX0, srcX1, scissor.x(), scissor.x() + scissor.z()) ||
!clipAxis(dstY0, dstY1, srcY0, srcY1, scissor.y(), scissor.y() + scissor.w())) {
return; // fully scissored out
}
}
#if MOBILEGL_BUILD_DISAGGREGATED
if (MG_Config::Transport != MG_Config::TransportMode::Monolith) {
BlitWireFramebuffers(srcX0,srcY0,srcX1,srcY1,dstX0,dstY0,dstX1,dstY1,mask,filter);
@@ -9031,37 +9062,6 @@ void main() {
return;
}
// The scissor test clips blit writes: intersect the destination rectangle with
// the scissor box and shrink the source proportionally.
if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::ScissorTest)) {
const IntVec4& scissor = MGB_CTX->GetScissorBox();
const auto clipAxis = [](GLint& d0, GLint& d1, GLint& s0, GLint& s1, GLint clipLo, GLint clipHi) -> Bool {
const Bool dstFlipped = d1 < d0;
GLint lo = dstFlipped ? d1 : d0;
GLint hi = dstFlipped ? d0 : d1;
const GLint newLo = std::max(lo, clipLo);
const GLint newHi = std::min(hi, clipHi);
if (newLo >= newHi) {
return false;
}
const double srcSpan = static_cast<double>(s1 - s0);
const double dstSpan = static_cast<double>(d1 - d0);
const double scale = dstSpan != 0.0 ? srcSpan / dstSpan : 0.0;
const GLint origD0 = d0;
const GLint clippedD0 = dstFlipped ? newHi : newLo;
const GLint clippedD1 = dstFlipped ? newLo : newHi;
s0 = s0 + static_cast<GLint>(std::lround((clippedD0 - origD0) * scale));
s1 = s0 + static_cast<GLint>(std::lround((clippedD1 - clippedD0) * scale));
d0 = clippedD0;
d1 = clippedD1;
return true;
};
if (!clipAxis(dstX0, dstX1, srcX0, srcX1, scissor.x(), scissor.x() + scissor.z()) ||
!clipAxis(dstY0, dstY1, srcY0, srcY1, scissor.y(), scissor.y() + scissor.w())) {
return; // fully scissored out
}
}
MOBILEGL_ASSERT(readFbo != nullptr, "VulkanRenderer::BlitFramebuffer: read framebuffer is null");
MOBILEGL_ASSERT(drawFbo != nullptr, "VulkanRenderer::BlitFramebuffer: draw framebuffer is null");
if (IsUnsupportedFramebufferForDirectVulkan(*readFbo) ||