static NSRange GenerateSliceRange(MgImageSubresourceRange subresourceRange) { return(new NSRange { Location = (nint)subresourceRange.BaseArrayLayer, Length = (nint)subresourceRange.LayerCount, }); }
static NSRange GenerateLevelRange(MgImageSubresourceRange subresourceRange) { return(new NSRange { Location = (nint)subresourceRange.BaseMipLevel, Length = (nint)subresourceRange.LevelCount, }); }
// Create an image memory barrier for changing the layout of // an image and put it into an active command buffer void setImageLayout(IMgCommandBuffer cmdBuffer, IMgImage image, MgImageAspectFlagBits aspectMask, MgImageLayout oldImageLayout, MgImageLayout newImageLayout, MgImageSubresourceRange subresourceRange) { // Create an image barrier object var imageMemoryBarrier = new MgImageMemoryBarrier { OldLayout = oldImageLayout, NewLayout = newImageLayout, Image = image, SubresourceRange = subresourceRange, }; // Only sets masks for layouts used in this example // For a more complete version that can be used with other layouts see IMgTools::setImageLayout // Source layouts (old) switch (oldImageLayout) { case MgImageLayout.UNDEFINED: // Only valid as initial layout, memory contents are not preserved // Can be accessed directly, no source dependency required imageMemoryBarrier.SrcAccessMask = 0; break; case MgImageLayout.PREINITIALIZED: // Only valid as initial layout for linear images, preserves memory contents // Make sure host writes to the image have been finished imageMemoryBarrier.SrcAccessMask = MgAccessFlagBits.HOST_WRITE_BIT; break; case MgImageLayout.TRANSFER_DST_OPTIMAL: // Old layout is transfer destination // Make sure any writes to the image have been finished imageMemoryBarrier.SrcAccessMask = MgAccessFlagBits.TRANSFER_WRITE_BIT; break; } // Target layouts (new) switch (newImageLayout) { case MgImageLayout.TRANSFER_SRC_OPTIMAL: // Transfer source (copy, blit) // Make sure any reads from the image have been finished imageMemoryBarrier.DstAccessMask = MgAccessFlagBits.TRANSFER_READ_BIT; break; case MgImageLayout.TRANSFER_DST_OPTIMAL: // Transfer destination (copy, blit) // Make sure any writes to the image have been finished imageMemoryBarrier.DstAccessMask = MgAccessFlagBits.TRANSFER_WRITE_BIT; break; case MgImageLayout.SHADER_READ_ONLY_OPTIMAL: // Shader read (sampler, input attachment) imageMemoryBarrier.DstAccessMask = MgAccessFlagBits.SHADER_READ_BIT; break; } // Put barrier on top of pipeline var srcStageFlags = MgPipelineStageFlagBits.TOP_OF_PIPE_BIT; var destStageFlags = MgPipelineStageFlagBits.TOP_OF_PIPE_BIT; // Put barrier inside setup command buffer cmdBuffer.CmdPipelineBarrier( srcStageFlags, destStageFlags, 0, null, null, new[] { imageMemoryBarrier }); }