diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index 608ebd0d..1e6e249a 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -10146,6 +10146,18 @@ void main() { // dstLevel and the z origins below arrived relative to whichever name the application // passed - so a view's level 0 has to become the parent level it opened onto before it // can index a subresource, exactly as at every other attachment boundary. +#if MOBILEGL_BUILD_DISAGGREGATED + if (wire) { + Uint32 srcMip = static_cast(srcLevel), srcLayer = static_cast(srcZ); + Uint32 dstMip = static_cast(dstLevel), dstLayer = static_cast(dstZ); + if (MG_Pipe::MGPipeHandleIsNull(m_textureManager->ResolveWireTextureStorage( + srcEndpoint.TextureHandle, srcMip, srcLayer)) || + MG_Pipe::MGPipeHandleIsNull(m_textureManager->ResolveWireTextureStorage( + dstEndpoint.TextureHandle, dstMip, dstLayer))) MagmaWireFatal("copy-image-view-record"); + srcLevel = static_cast(srcMip); srcZ = static_cast(srcLayer); + dstLevel = static_cast(dstMip); dstZ = static_cast(dstLayer); + } +#endif srcLevel = static_cast(ToStorageMipLevel(srcEndpoint.Texture.get(), srcLevel)); dstLevel = static_cast(ToStorageMipLevel(dstEndpoint.Texture.get(), dstLevel)); srcZ = static_cast(ToStorageArrayLayer(srcEndpoint.Texture.get(), srcZ)); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.inc b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.inc index 34f28548..c1c2097c 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.inc +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.inc @@ -17,6 +17,9 @@ } void VulkanRenderer::DestroyWireDrawPass() { + // FlushPendingCommands only submits. These objects may still be referenced by + // that submission, so retire this temporary pass after the queue completes. + if (m_wireDrawPass || !m_wireDrawViews.empty()) VK_VERIFY(vkQueueWaitIdle(m_graphicsQueue)); m_wireDrawPass.reset(); for (const auto view : m_wireDrawViews) vkDestroyImageView(m_device, view, nullptr); m_wireDrawViews.clear(); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.inc b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.inc index 8eb767e9..f5bef129 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.inc +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.inc @@ -369,14 +369,15 @@ void VulkanRenderer::GenerateWireMipmap() { if (HasPendingRecordedWork() && !FlushPendingCommands()) MagmaWireFatal("wire-verb-flush"); auto& state = MG_Pipe::MGPipeApplier(); - const auto handle = state.VerbMipRes; + Uint32 base = state.VerbMipBaseLevel, baseLayer = 0, layerCount = 1; + const auto handle = m_textureManager->ResolveWireTextureStorage(state.VerbMipRes, base, baseLayer, + nullptr, &layerCount); auto* resource = m_textureManager->SyncTextureResourceByHandle(handle); if (!resource) MagmaWireFatal("mipmap-resource"); m_textureManager->FlushPendingUploads(); if (HasPendingRecordedWork() && !FlushPendingCommands()) MagmaWireFatal("mipmap-flush"); auto& frame = m_frameContext.GetCurrent(); if (!frame.isCommandRecording) m_frameContext.BeginCommandRecording(); - const Uint32 base = state.VerbMipBaseLevel; const Uint32 count = state.VerbMipLevelCount; if (count <= 1) return; if (!m_textureManager->GrowWireTextureMipChain(handle,base+count,frame.commandBuffer)) @@ -401,8 +402,8 @@ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,VK_PIPELINE_STAGE_TRANSFER_BIT,VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,VK_ACCESS_TRANSFER_READ_BIT,resource->aspect,level-1,1); VkImageBlit blit{}; - blit.srcSubresource = {resource->aspect,level-1,0,resource->arrayLayers}; - blit.dstSubresource = {resource->aspect,level,0,resource->arrayLayers}; + blit.srcSubresource = {resource->aspect,level-1,baseLayer,layerCount}; + blit.dstSubresource = {resource->aspect,level,baseLayer,layerCount}; blit.srcOffsets[1] = {static_cast(std::max(resource->extent.width>>(level-1),1u)), static_cast(std::max(resource->extent.height>>(level-1),1u)), static_cast(std::max(resource->depth>>(level-1),1u))}; @@ -424,7 +425,8 @@ const auto target = static_cast(record.Desc.Target); // The resource descriptor determines the upload-target set; no texture unit or // client upload-target vector participates in defining the generated shadow. - for (Uint32 face=0;face<(target==MG_Pipe::MGPipeResourceTarget::TexCube ? 6u : 1u);++face) { + for (Uint32 face = target == MG_Pipe::MGPipeResourceTarget::TexCube ? baseLayer : 0; + face < (target == MG_Pipe::MGPipeResourceTarget::TexCube ? baseLayer + layerCount : 1u); ++face) { TextureUploadTarget upload = TextureUploadTarget::Texture2D; switch (target) { case MG_Pipe::MGPipeResourceTarget::Tex1D: upload=TextureUploadTarget::Texture1D; break; @@ -437,9 +439,8 @@ default: break; } for (Uint32 level=base+1;level(std::max(resource->extent.width>>level,1u)), - static_cast(std::max(resource->extent.height>>level,1u)), - static_cast(std::max(resource->depth>>level,1u))}; + const IntVec3 extent = MG_Remote::Server::StagedTextureMipExtent( + record.Desc.Target, record.Desc.Width, record.Desc.Height, record.Desc.Depth, level); store.NoteLevelDefined(key,static_cast(upload),static_cast(level),extent); store.MarkLevelGpuDirty(key,static_cast(upload),static_cast(level),true); } diff --git a/MobileGL/MG_Pipe/PipeApply.cpp b/MobileGL/MG_Pipe/PipeApply.cpp index bbc93007..f2e359c7 100644 --- a/MobileGL/MG_Pipe/PipeApply.cpp +++ b/MobileGL/MG_Pipe/PipeApply.cpp @@ -2012,7 +2012,8 @@ namespace MobileGL::MG_Pipe { // system. Textures only: a buffer's storage is the ops table's own Respecify hook, and // a renderbuffer has no levels. if (desc.Target != kMGPipeResourceTargetBuffer && - desc.Target != static_cast(MGPipeResourceTarget::Renderbuffer) && !metadataOnly) { + desc.Target != static_cast(MGPipeResourceTarget::Renderbuffer) && + (level != nullptr || !metadataOnly)) { if (g_resourceOps != nullptr && g_resourceOps->TextureRespecify != nullptr) g_resourceOps->TextureRespecify(desc.Resource, desc, level); else