[MG_Backend, MG_IntegrationTest] (Disaggregated): P5f fm - carry framebuffer copies and exercise Magma wire verbs

This commit is contained in:
2026-09-19 22:11:38 -04:00
parent 4593719a3c
commit 20bbf9647e
4 changed files with 62 additions and 0 deletions
@@ -9612,6 +9612,12 @@ void main() {
void VulkanRenderer::CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height) {
#if MOBILEGL_BUILD_DISAGGREGATED
if (MG_Config::Transport != MG_Config::TransportMode::Monolith) {
CopyWireFramebufferToTexture(target,level,xoffset,yoffset,x,y,width,height);
return;
}
#endif
if (width <= 0 || height <= 0) {
return;
}
@@ -455,6 +455,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
void ReadWirePixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, void* pixels);
void GenerateWireMipmap();
void CopyWireFramebufferToTexture(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height);
#endif
void QueueClearBufferPayloadForFramebuffer(const MG_State::GLState::FramebufferObject& framebuffer,
GLenum buffer, GLint drawbuffer,
@@ -282,6 +282,45 @@
if (mask & GL_DEPTH_BUFFER_BIT) blit(read->Depth,draw->Depth,VK_IMAGE_ASPECT_DEPTH_BIT);
if (mask & GL_STENCIL_BUFFER_BIT) blit(read->Stencil,draw->Stencil,VK_IMAGE_ASPECT_STENCIL_BIT);
}
void VulkanRenderer::CopyWireFramebufferToTexture(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height) {
if (width <= 0 || height <= 0) return;
if (target != GL_TEXTURE_2D) {
RecordTextureCopyError(__func__,ErrorCode::InvalidOperation,
"CopyTexSubImage2D currently only supports GL_TEXTURE_2D destinations.");
return;
}
auto& state = MG_Pipe::MGPipeApplier();
const auto* read = state.ReadFramebuffer();
if (!read) MagmaWireFatal("copy-framebuffer-record");
const auto* texture = m_textureManager->SyncTextureResourceByHandle(state.VerbCopyTexDst);
if (!texture) MagmaWireFatal("copy-destination-record");
const VkImageAspectFlags aspect = texture->aspect;
MG_Pipe::MGPFramebufferState fake{};
MG_Pipe::MGPSurface surface{};
surface.Kind = MG_Pipe::kMGPipeSurfaceKindTexture;
surface.Res = state.VerbCopyTexDst;
surface.Level = static_cast<Uint16>(level);
WireImage source = ResolveWireImage(*read,aspect & VK_IMAGE_ASPECT_DEPTH_BIT ? read->Depth :
aspect & VK_IMAGE_ASPECT_STENCIL_BIT ? read->Stencil : read->ReadSurface,aspect);
WireImage destination = ResolveWireImage(fake,surface,aspect);
if (!source.image || !destination.image) return;
m_textureManager->FlushPendingUploads();
TransitionWireImage(source,VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
TransitionWireImage(destination,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkImageBlit region{};
region.srcSubresource = {aspect,source.level,source.layer,1};
region.dstSubresource = {aspect,destination.level,destination.layer,1};
region.srcOffsets[0] = {x,y,0}; region.srcOffsets[1] = {x+width,y+height,1};
region.dstOffsets[0] = {xoffset,yoffset,0}; region.dstOffsets[1] = {xoffset+width,yoffset+height,1};
if (source.isDefault) {
region.srcOffsets[0].y = static_cast<Int32>(source.extent.height)-y;
region.srcOffsets[1].y = static_cast<Int32>(source.extent.height)-y-height;
}
vkCmdBlitImage(m_frameContext.GetCurrent().commandBuffer,source.image,VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
destination.image,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,1,&region,VK_FILTER_NEAREST);
}
void VulkanRenderer::GenerateWireMipmap() {
auto& state = MG_Pipe::MGPipeApplier();
const auto handle = state.VerbMipRes;
@@ -2378,6 +2378,21 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
ENVIRONMENT "${MGL_ITEST_GLES_SPLIT_ENVIRONMENT}\;MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/p5b-f1-${f1Slot}.log"
)
endforeach()
# P5f fm: the framebuffer/copy/mipmap verbs now consume server records on Magma too.
mgl_itest_join_environment(MGL_ITEST_MAGMA_WIRE_ENVIRONMENT
"MOBILEGL_BACKEND_TYPE=DirectVulkan" "MOBILEGL_TRANSPORT=inproc"
"MOBILEGL_ITEST_REQUIRE_GPU=1" "MGITEST_SPLIT_LANE=1"
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_COMMON_ENV})
foreach(fmSlot ClearBufferfi ClearBufferfv ClearBufferiv ClearBufferuiv ClearNamedFramebufferfi ClearNamedFramebufferfv ClearNamedFramebufferiv ClearNamedFramebufferuiv CopyTexImage2D CopyTexSubImage2D GenerateMipmap GenerateMipmapPackedFloat GenerateMipmapDepth)
gtest_discover_tests(MobileGLIntegrationTest
TEST_PREFIX "DirectVulkan.Split.Fm."
TEST_FILTER "F1WireScenario.${fmSlot}Pixels"
DISCOVERY_TIMEOUT 30
PROPERTIES
LABELS "integration-magma-split"
TIMEOUT ${MGL_ITEST_TIMEOUT}
ENVIRONMENT "${MGL_ITEST_MAGMA_WIRE_ENVIRONMENT}\;MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/p5f-fm-${fmSlot}.log")
endforeach()
endif()
# P5c ct (MG_Remote/CONTRACT-P5C.md §5): the two control records, split-only source for the