mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[MG_Backend] (Disaggregated): P5f fm - fence remaining buffer debt and preserve native transfer layouts
This commit is contained in:
@@ -32,6 +32,16 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
UniquePtr<VulkanRenderer>& pVulkanRenderer = *new UniquePtr<VulkanRenderer>();
|
||||
|
||||
namespace {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
void RejectWireLegacyBuffer() {
|
||||
if (MG_Config::Transport != MG_Config::TransportMode::Monolith) {
|
||||
MGLOG_F("MGPipe: Fatal{RoleViolation, \"buffer-legacy-arm\"} (Magma P7 buffer consumer)");
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
#else
|
||||
inline void RejectWireLegacyBuffer() {}
|
||||
#endif
|
||||
// Generation of the live VulkanRenderer instance, mirroring
|
||||
// DirectGLES's g_syncContextGeneration. BackendObject_DirectVulkan
|
||||
// bumps it (BumpRendererGeneration) wherever pVulkanRenderer is reset
|
||||
@@ -391,11 +401,17 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
|
||||
void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RejectWireLegacyBuffer();
|
||||
#endif
|
||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawElementsIndirect called with null VulkanRenderer");
|
||||
MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawElementsIndirect called with null GL context");
|
||||
pVulkanRenderer->MultiDrawElementsIndirect(mode, type, indirect, drawcount, stride);
|
||||
}
|
||||
void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RejectWireLegacyBuffer();
|
||||
#endif
|
||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawArraysIndirect called with null VulkanRenderer");
|
||||
MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawArraysIndirect called with null GL context");
|
||||
|
||||
@@ -447,12 +463,18 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
void MultiDrawElementsIndirectCount(GLenum mode, GLenum type, const void* indirect, GLintptr drawcount,
|
||||
GLsizei maxdrawcount, GLsizei stride) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RejectWireLegacyBuffer();
|
||||
#endif
|
||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawElementsIndirectCount called with null VulkanRenderer");
|
||||
MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawElementsIndirectCount called with null GL context");
|
||||
pVulkanRenderer->MultiDrawElementsIndirectCount(mode, type, indirect, drawcount, maxdrawcount, stride);
|
||||
}
|
||||
void MultiDrawArraysIndirectCount(GLenum mode, const void* indirect, GLintptr drawcount,
|
||||
GLsizei maxdrawcount, GLsizei stride) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RejectWireLegacyBuffer();
|
||||
#endif
|
||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawArraysIndirectCount called with null VulkanRenderer");
|
||||
MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawArraysIndirectCount called with null GL context");
|
||||
|
||||
@@ -525,6 +547,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
DrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instancecount, 0, 0);
|
||||
}
|
||||
void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RejectWireLegacyBuffer();
|
||||
#endif
|
||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawElementsIndirect called with null VulkanRenderer");
|
||||
MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawElementsIndirect called with null GL context");
|
||||
|
||||
@@ -584,6 +609,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
DrawArraysInstancedBaseInstance(mode, first, count, instancecount, 0);
|
||||
}
|
||||
void DrawArraysIndirect(GLenum mode, const void* indirect) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RejectWireLegacyBuffer();
|
||||
#endif
|
||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawArraysIndirect called with null VulkanRenderer");
|
||||
MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawArraysIndirect called with null GL context");
|
||||
|
||||
@@ -652,6 +680,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
|
||||
void DispatchComputeIndirect(GLintptr indirect) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RejectWireLegacyBuffer();
|
||||
#endif
|
||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DispatchComputeIndirect called with null VulkanRenderer");
|
||||
MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DispatchComputeIndirect called with null GL context");
|
||||
pVulkanRenderer->DispatchComputeIndirect(indirect);
|
||||
@@ -817,6 +848,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
// memory) into uint32 values with the loop-closing first index appended.
|
||||
static Bool BuildClosedLineLoopIndices(GLsizei count, GLenum type, const void* indices,
|
||||
Vector<Uint32>& outIndices) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RejectWireLegacyBuffer();
|
||||
#endif
|
||||
const SizeT indexSize = MG_Util::GetGLTypeSize(type);
|
||||
if (indexSize == 0 || count < 2) {
|
||||
return false;
|
||||
@@ -932,6 +966,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
// vkCmdDrawIndexed all carry natively.
|
||||
static void MultiDrawElementsImpl(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
|
||||
GLsizei drawcount, const GLint* basevertex) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RejectWireLegacyBuffer();
|
||||
#endif
|
||||
if (drawcount <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6869,7 +6869,7 @@ void main() {
|
||||
const IndexBufferView* pIndexBufferView) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
if (MG_Config::Transport != MG_Config::TransportMode::Monolith)
|
||||
return SetupWireDraw(frame, mode, aspects, drawParams);
|
||||
return SetupWireDraw(frame, mode, aspects, drawParams, pIndexBufferView);
|
||||
#endif
|
||||
// Sync each sampled texture at most once across this whole draw: the layout
|
||||
// probe loop, the post-transition loop, and ResolveSamplerDescriptor would
|
||||
@@ -11226,7 +11226,13 @@ void main() {
|
||||
}
|
||||
|
||||
// Store honoring the client pack state (single slice).
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
const SharedPtr<MG_State::GLState::BufferObject> wireReplyHasNoPackBuffer;
|
||||
#endif
|
||||
const auto& pixelPackBufferObject =
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
MG_Config::Transport != MG_Config::TransportMode::Monolith ? wireReplyHasNoPackBuffer :
|
||||
#endif
|
||||
MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject();
|
||||
const auto packParams = MGB_CTX->GetPixelStoreParameters(false);
|
||||
const SizeT rowPixels = static_cast<SizeT>(packParams.RowLength > 0 ? packParams.RowLength : width);
|
||||
|
||||
@@ -458,7 +458,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
GLenum format, GLenum type, void* pixels);
|
||||
void GenerateWireMipmap();
|
||||
Bool SetupWireDraw(FrameContext::FrameData& frame, GLenum mode, Flags<DrawSetupAspect> aspects,
|
||||
const DrawCmdParam& drawParams);
|
||||
const DrawCmdParam& drawParams, const IndexBufferView* indices);
|
||||
void DestroyWireDrawPass();
|
||||
void DispatchWireCompute(GLuint x, GLuint y, GLuint z);
|
||||
UniquePtr<RenderPassEntry> m_wireDrawPass;
|
||||
|
||||
@@ -23,11 +23,12 @@
|
||||
}
|
||||
|
||||
Bool VulkanRenderer::SetupWireDraw(FrameContext::FrameData& frame, GLenum mode,
|
||||
Flags<DrawSetupAspect> aspects, const DrawCmdParam& drawParams) {
|
||||
Flags<DrawSetupAspect> aspects, const DrawCmdParam& drawParams, const IndexBufferView* indices) {
|
||||
auto& state = MG_Pipe::MGPipeApplier();
|
||||
const auto program = WireProgramSource(state.BoundShaderCso);
|
||||
if (!program.GetLinkStatus() || !program.GetSpirvStatus()) return false;
|
||||
if (aspects & DrawSetupAspect::IndexBuffer || aspects & DrawSetupAspect::IndirectDrawBuffer ||
|
||||
if (((aspects & DrawSetupAspect::IndexBuffer) && (!indices || !indices->forceClientMemory)) ||
|
||||
aspects & DrawSetupAspect::IndirectDrawBuffer ||
|
||||
MGB_CTX->IsTransformFeedbackActive()) WireBufferLegacyFatal();
|
||||
const auto* fbo = state.DrawFramebuffer();
|
||||
if (!fbo) MagmaWireFatal("draw-framebuffer-record");
|
||||
@@ -43,6 +44,7 @@
|
||||
if (programObject->pointSizeCapabilityUnsupported) return false;
|
||||
const auto& programObj = *programObject;
|
||||
const auto vaoHandle = state.BoundVertexElements;
|
||||
if (MG_Pipe::MGPipeHandleIsNull(vaoHandle)) MagmaWireFatal("vertex-elements-record");
|
||||
if (!MG_Pipe::MGPipeHandleIsNull(vaoHandle)) {
|
||||
if (vaoHandle.Slot >= state.VertexElementsCsos.size()) MagmaWireFatal("vertex-elements-record");
|
||||
const auto& vao = state.VertexElementsCsos[vaoHandle.Slot];
|
||||
@@ -55,7 +57,7 @@
|
||||
Vector<VkAttachmentDescription> attachments;
|
||||
Vector<VkImageView> views;
|
||||
Vector<VkAttachmentReference> colors;
|
||||
VkAttachmentReference depth{VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
|
||||
VkAttachmentReference depth{VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL};
|
||||
VkExtent2D extent{~0u, ~0u};
|
||||
Uint32 layers = ~0u;
|
||||
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
@@ -65,7 +67,7 @@
|
||||
if (!image.image) return VK_ATTACHMENT_UNUSED;
|
||||
m_textureManager->FlushPendingUploads();
|
||||
const VkImageLayout layout = aspect == VK_IMAGE_ASPECT_COLOR_BIT ?
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_GENERAL;
|
||||
TransitionWireImage(image, layout);
|
||||
VkImageViewCreateInfo info{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
|
||||
info.image = image.image;
|
||||
@@ -101,7 +103,7 @@
|
||||
for (Uint32 i = 0; i < MG_Pipe::kMGPipeMaxColorAttachments; ++i) {
|
||||
const Int32 slot = fbo->DrawBuffers[i];
|
||||
const Uint32 index = slot < 0 ? VK_ATTACHMENT_UNUSED : add(fbo->Color[slot], VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
colors.push_back({index, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL});
|
||||
colors.push_back({index, VK_IMAGE_LAYOUT_GENERAL});
|
||||
}
|
||||
while (!colors.empty() && colors.back().attachment == VK_ATTACHMENT_UNUSED) colors.pop_back();
|
||||
if (fbo->IsDefault || fbo->Depth.Kind != MG_Pipe::kMGPipeSurfaceKindNone)
|
||||
@@ -154,6 +156,14 @@
|
||||
data, size, 16, slice)) return false;
|
||||
vkCmdBindVertexBuffers(frame.commandBuffer, binding++, 1, &slice.buffer, &slice.offset);
|
||||
}
|
||||
if (indices) {
|
||||
BufferSlice slice{};
|
||||
if (!m_bufferManager.UploadTransient(BufferKind::Index, m_frameContext.GetCurrentFrameIndex(),
|
||||
reinterpret_cast<const void*>(indices->indexByteOffset), indices->indexByteSize, 16, slice)) return false;
|
||||
const VkIndexType type = indices->indexType == GL_UNSIGNED_INT ? VK_INDEX_TYPE_UINT32 :
|
||||
indices->indexType == GL_UNSIGNED_SHORT ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT8;
|
||||
vkCmdBindIndexBuffer(frame.commandBuffer, slice.buffer, slice.offset, type);
|
||||
}
|
||||
if (!VkRenderPassManager::BeginRenderPass(frame.commandBuffer, pass)) return false;
|
||||
vkCmdBindPipeline(frame.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
ApplyDynamicDrawStateTail(frame, pass.extent, fbo->IsDefault,
|
||||
|
||||
@@ -283,9 +283,27 @@
|
||||
region.dstOffsets[0].y = static_cast<GLint>(destination.extent.height)-dy0;
|
||||
region.dstOffsets[1].y = static_cast<GLint>(destination.extent.height)-dy1;
|
||||
}
|
||||
vkCmdBlitImage(m_frameContext.GetCurrent().commandBuffer,source.image,srcLayout,
|
||||
destination.image,dstLayout,1,®ion,
|
||||
filter == GL_LINEAR ? VK_FILTER_LINEAR : VK_FILTER_NEAREST);
|
||||
auto command = m_frameContext.GetCurrent().commandBuffer;
|
||||
if (source.samples != VK_SAMPLE_COUNT_1_BIT || destination.samples != VK_SAMPLE_COUNT_1_BIT) {
|
||||
const Int32 width = region.srcOffsets[1].x - region.srcOffsets[0].x;
|
||||
const Int32 height = region.srcOffsets[1].y - region.srcOffsets[0].y;
|
||||
if (width <= 0 || height <= 0 || width != region.dstOffsets[1].x - region.dstOffsets[0].x ||
|
||||
height != region.dstOffsets[1].y - region.dstOffsets[0].y || source.format != destination.format)
|
||||
MagmaWireFatal("multisample-blit-shape@P7");
|
||||
if (source.samples != VK_SAMPLE_COUNT_1_BIT && destination.samples == VK_SAMPLE_COUNT_1_BIT &&
|
||||
aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
|
||||
VkImageResolve resolve{region.srcSubresource, region.srcOffsets[0],
|
||||
region.dstSubresource, region.dstOffsets[0], {static_cast<Uint32>(width), static_cast<Uint32>(height), 1}};
|
||||
vkCmdResolveImage(command, source.image, srcLayout, destination.image, dstLayout, 1, &resolve);
|
||||
} else if (source.samples == destination.samples) {
|
||||
VkImageCopy copy{region.srcSubresource, region.srcOffsets[0], region.dstSubresource,
|
||||
region.dstOffsets[0], {static_cast<Uint32>(width), static_cast<Uint32>(height), 1}};
|
||||
vkCmdCopyImage(command, source.image, srcLayout, destination.image, dstLayout, 1, ©);
|
||||
} else MagmaWireFatal("multisample-blit-aspect@P7");
|
||||
} else {
|
||||
vkCmdBlitImage(command,source.image,srcLayout,destination.image,dstLayout,1,®ion,
|
||||
filter == GL_LINEAR ? VK_FILTER_LINEAR : VK_FILTER_NEAREST);
|
||||
}
|
||||
if (!destination.isDefault && dst.Kind == MG_Pipe::kMGPipeSurfaceKindTexture)
|
||||
m_textureManager->MarkWireTextureGpuWritten(destination.storage, destination.level, destination.layer, destination.layers);
|
||||
if (destination.isDefault) {
|
||||
@@ -328,8 +346,12 @@
|
||||
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);
|
||||
const Bool sameImage = source.image == destination.image;
|
||||
const VkImageLayout srcLayout = sameImage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
const VkImageLayout dstLayout = sameImage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
TransitionWireImage(source,srcLayout);
|
||||
if (sameImage) destination.layout = source.layout;
|
||||
else TransitionWireImage(destination,dstLayout);
|
||||
VkImageBlit region{};
|
||||
region.srcSubresource = {aspect,source.level,source.layer,1};
|
||||
region.dstSubresource = {aspect,destination.level,destination.layer,1};
|
||||
@@ -339,8 +361,8 @@
|
||||
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,®ion,VK_FILTER_NEAREST);
|
||||
vkCmdBlitImage(m_frameContext.GetCurrent().commandBuffer,source.image,srcLayout,
|
||||
destination.image,dstLayout,1,®ion,VK_FILTER_NEAREST);
|
||||
m_textureManager->MarkWireTextureGpuWritten(destination.storage,destination.level,destination.layer);
|
||||
}
|
||||
|
||||
|
||||
@@ -2386,7 +2386,7 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
|
||||
foreach(fmSlot PartialTextureUploadPreservesGpuClear TextureViewClearTargetsItsRootMipAndLayer 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"
|
||||
TEST_FILTER "F1WireScenario.${fmSlot}*"
|
||||
DISCOVERY_TIMEOUT 30
|
||||
PROPERTIES
|
||||
LABELS "integration-magma-split"
|
||||
|
||||
Reference in New Issue
Block a user