public void EndDraw(uint[] nextImage, IMgCommandBuffer prePresent, IMgSemaphore[] renderComplete) { Result err; var presentImages = new List <MgPresentInfoKHRImage>(); foreach (var image in nextImage) { var currentBuffer = mLayers[image]; //submitPrePresentBarrier(prePresent, currentBuffer.Image); presentImages.Add(new MgPresentInfoKHRImage { ImageIndex = image, Swapchain = mCollection.Swapchain, }); } var presentInfo = new MgPresentInfoKHR { WaitSemaphores = renderComplete, Images = presentImages.ToArray(), }; //err = swapChain.queuePresent(queue, currentBuffer, semaphores.renderComplete); err = mPartition.Queue.QueuePresentKHR(presentInfo); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); err = mPartition.Queue.QueueWaitIdle(); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); }
// Command buffers for submitting present barriers void setupPresentationBarriers() { var cmdBufAllocateInfo = new MgCommandBufferAllocateInfo { CommandBufferCount = 2, CommandPool = mManager.Configuration.Partition.CommandPool, Level = MgCommandBufferLevel.PRIMARY, }; mPresentBuffers = new IMgCommandBuffer[2]; var device = mManager.Configuration.Device; Debug.Assert(device != null); var err = device.AllocateCommandBuffers(cmdBufAllocateInfo, mPresentBuffers); Debug.Assert(err == Result.SUCCESS); // Pre present mPrePresentCmdBuffer = mPresentBuffers[0]; // Post present mPostPresentCmdBuffer = mPresentBuffers[1]; }
void CreateCommandBuffers() { drawCmdBuffers = new IMgCommandBuffer[mGraphicsDevice.Framebuffers.Length]; { var cmdBufAllocateInfo = new MgCommandBufferAllocateInfo { CommandBufferCount = (uint)mGraphicsDevice.Framebuffers.Length, CommandPool = mConfiguration.Partition.CommandPool, Level = MgCommandBufferLevel.PRIMARY, }; var err = mConfiguration.Device.AllocateCommandBuffers(cmdBufAllocateInfo, drawCmdBuffers); Debug.Assert(err == Result.SUCCESS); } { var cmdBufAllocateInfo = new MgCommandBufferAllocateInfo { CommandBufferCount = 2, CommandPool = mConfiguration.Partition.CommandPool, Level = MgCommandBufferLevel.PRIMARY, }; var presentBuffers = new IMgCommandBuffer[2]; var err = mConfiguration.Device.AllocateCommandBuffers(cmdBufAllocateInfo, presentBuffers); Debug.Assert(err == Result.SUCCESS); mPrePresentCmdBuffer = presentBuffers[0]; mPostPresentCmdBuffer = presentBuffers[1]; } }
IMgCommandBuffer getCommandBuffer(bool begin) { var buffers = new IMgCommandBuffer[1]; var cmdBufAllocateInfo = new MgCommandBufferAllocateInfo { CommandPool = mConfiguration.Partition.CommandPool, Level = MgCommandBufferLevel.PRIMARY, CommandBufferCount = 1, }; var err = mConfiguration.Device.AllocateCommandBuffers(cmdBufAllocateInfo, buffers); Debug.Assert(err == Result.SUCCESS); var cmdBuf = buffers[0]; if (begin) { var cmdBufInfo = new MgCommandBufferBeginInfo(); err = cmdBuf.BeginCommandBuffer(cmdBufInfo); Debug.Assert(err == Result.SUCCESS); } return(cmdBuf); }
private void CmdDraw(IMgCommandBuffer cmdBuf, MeshPrimitive meshPrimitive, RenderInstanceChunk drawCall, int sliceIndex) { cmdBuf.CmdDraw( meshPrimitive.VertexCount, drawCall.InstanceCount, drawCall.FirstVertex, drawCall.FirstInstance); }
public void Initialize(MgGraphicsDeviceCreateInfo createInfo) { mWidth = createInfo.Width; mHeight = createInfo.Height; mConfiguration.Initialize(mWidth, mHeight); Debug.Assert(mConfiguration.Partition != null); const int NO_OF_BUFFERS = 1; var buffers = new IMgCommandBuffer[NO_OF_BUFFERS]; var pAllocateInfo = new MgCommandBufferAllocateInfo { CommandBufferCount = NO_OF_BUFFERS, CommandPool = mConfiguration.Partition.CommandPool, Level = MgCommandBufferLevel.PRIMARY, }; mConfiguration.Device.AllocateCommandBuffers(pAllocateInfo, buffers); var setupCmdBuffer = buffers[0]; var cmdBufInfo = new MgCommandBufferBeginInfo { }; var err = setupCmdBuffer.BeginCommandBuffer(cmdBufInfo); Debug.Assert(err == Result.SUCCESS); mGraphicsDevice.Create(setupCmdBuffer, mSwapchains, createInfo); err = setupCmdBuffer.EndCommandBuffer(); Debug.Assert(err == Result.SUCCESS); var submission = new[] { new MgSubmitInfo { CommandBuffers = new IMgCommandBuffer[] { buffers[0], }, } }; err = mConfiguration.Queue.QueueSubmit(submission, null); Debug.Assert(err == Result.SUCCESS); mConfiguration.Queue.QueueWaitIdle(); mConfiguration.Device.FreeCommandBuffers(mConfiguration.Partition.CommandPool, buffers); }
public void Create(IMgCommandBuffer setupCmdBuffer, IMgSwapchainCollection swapchainCollection, MgGraphicsDeviceCreateInfo createInfo) { if (setupCmdBuffer == null) { throw new ArgumentNullException(nameof(setupCmdBuffer)); } if (createInfo == null) { throw new ArgumentNullException(nameof(createInfo)); } if (swapchainCollection == null) { throw new ArgumentNullException(nameof(swapchainCollection)); } Setup(); // Check if device supports requested sample count for color and depth frame buffer if ( (mProperties.Limits.FramebufferColorSampleCounts < createInfo.Samples) || (mProperties.Limits.FramebufferDepthSampleCounts < createInfo.Samples)) { throw new ArgumentOutOfRangeException("createInfo.Samples", "MgDefaultDepthStencilBuffer : This physical device cannot fulfil the requested sample count for BOTH color and depth frame buffer"); } ReleaseUnmanagedResources(); mDeviceCreated = false; CreateDepthStencil(setupCmdBuffer, createInfo); CreateRenderpass(createInfo); swapchainCollection.Create(setupCmdBuffer, createInfo.Width, createInfo.Height); mFramebuffers.Create(swapchainCollection, mRenderpass, mDepthStencilImageView, createInfo.Width, createInfo.Height); Scissor = new MgRect2D { Extent = new MgExtent2D { Width = createInfo.Width, Height = createInfo.Height }, Offset = new MgOffset2D { X = 0, Y = 0 }, }; // initialize viewport CurrentViewport = new MgViewport { Width = createInfo.Width, Height = createInfo.Height, X = 0, Y = 0, MinDepth = 0f, MaxDepth = 1f, }; mDeviceCreated = true; }
private void InitSwapchain(uint width, uint height) { Debug.Assert(mConfiguration.Partition != null); const int NO_OF_BUFFERS = 1; var buffers = new IMgCommandBuffer[NO_OF_BUFFERS]; var pAllocateInfo = new MgCommandBufferAllocateInfo { CommandBufferCount = NO_OF_BUFFERS, CommandPool = mConfiguration.Partition.CommandPool, Level = MgCommandBufferLevel.PRIMARY, }; mConfiguration.Device.AllocateCommandBuffers(pAllocateInfo, buffers); var createInfo = new MgGraphicsDeviceCreateInfo { Samples = MgSampleCountFlagBits.COUNT_1_BIT, Color = MgFormat.R8G8B8A8_UINT, DepthStencil = MgFormat.D24_UNORM_S8_UINT, Width = mWidth, Height = mHeight, }; var setupCmdBuffer = buffers[0]; var cmdBufInfo = new MgCommandBufferBeginInfo(); var err = setupCmdBuffer.BeginCommandBuffer(cmdBufInfo); Debug.Assert(err == Result.SUCCESS); mGraphicsDevice.Create(setupCmdBuffer, mSwapchains, createInfo); err = setupCmdBuffer.EndCommandBuffer(); Debug.Assert(err == Result.SUCCESS); var submission = new[] { new MgSubmitInfo { CommandBuffers = new IMgCommandBuffer[] { buffers[0], }, } }; err = mConfiguration.Queue.QueueSubmit(submission, null); Debug.Assert(err == Result.SUCCESS); mConfiguration.Queue.QueueWaitIdle(); mConfiguration.Device.FreeCommandBuffers(mConfiguration.Partition.CommandPool, buffers); }
void SetupGraphicsDevice() { try { var setupCommands = new IMgCommandBuffer[1]; var pAllocateInfo = new MgCommandBufferAllocateInfo { CommandPool = mConfiguration.Partition.CommandPool, CommandBufferCount = 1, Level = MgCommandBufferLevel.PRIMARY, }; var err = mConfiguration.Device.AllocateCommandBuffers(pAllocateInfo, setupCommands); Debug.Assert(err == Result.SUCCESS); var dsCreateInfo = new MgGraphicsDeviceCreateInfo { Color = MgFormat.B8G8R8A8_UNORM, DepthStencil = MgFormat.D32_SFLOAT_S8_UINT, Samples = MgSampleCountFlagBits.COUNT_1_BIT, Width = mWidth, Height = mHeight, }; var cmdBuf = setupCommands[0]; var cmdBufInfo = new MgCommandBufferBeginInfo { }; cmdBuf.BeginCommandBuffer(cmdBufInfo); mGraphicsDevice.Create(cmdBuf, mSwapchains, dsCreateInfo); cmdBuf.EndCommandBuffer(); var pSubmits = new MgSubmitInfo[] { new MgSubmitInfo { CommandBuffers = new IMgCommandBuffer[] { cmdBuf, }, } }; mConfiguration.Partition.Queue.QueueSubmit(pSubmits, null); mConfiguration.Partition.Queue.QueueWaitIdle(); mConfiguration.Partition.Device.FreeCommandBuffers( mConfiguration.Partition.CommandPool, setupCommands); } catch (Exception ex) { Console.WriteLine(ex.Message); throw ex; } }
public uint BeginDraw(IMgCommandBuffer postPresent, IMgSemaphore presentComplete, ulong timeout) { var currentIndex = 0U; mLayers[currentIndex].Inflight.WaitOne(); if (mLayers[currentIndex].Drawable != null) { mLayers[currentIndex].Drawable.Dispose(); } mLayers[currentIndex].Drawable = mView.CurrentDrawable; return(currentIndex); }
public void Create(IMgCommandBuffer setupCmdBuffer, IMgSwapchainCollection swapchainCollection, MgGraphicsDeviceCreateInfo createInfo) { if (createInfo == null) { throw new ArgumentNullException(nameof(createInfo)); } if (setupCmdBuffer == null) { throw new ArgumentNullException(nameof(setupCmdBuffer)); } if (swapchainCollection == null) { throw new ArgumentNullException(nameof(swapchainCollection)); } ReleaseUnmanagedResources(); mDeviceCreated = false; SetupContext(createInfo); SetupRenderpass(createInfo); // MANDATORY swapchainCollection.Create(setupCmdBuffer, createInfo.Width, createInfo.Height); SetupSwapchain(swapchainCollection, createInfo); mFramebuffers.Create(swapchainCollection, mRenderpass, mView, createInfo.Width, createInfo.Height); Scissor = new MgRect2D { Extent = new MgExtent2D { Width = createInfo.Width, Height = createInfo.Height }, Offset = new MgOffset2D { X = 0, Y = 0 }, }; // initialize viewport CurrentViewport = new MgViewport { Width = createInfo.Width, Height = createInfo.Height, X = 0, Y = 0, MinDepth = 0f, MaxDepth = 1f, }; mDeviceCreated = true; }
public void SubmitPrePresentBarrier(IMgCommandBuffer prePresent, IMgImage image) { if (prePresent == null) { throw new InvalidOperationException(); } MgCommandBufferBeginInfo cmdBufInfo = new MgCommandBufferBeginInfo { }; var vkRes = prePresent.BeginCommandBuffer(cmdBufInfo); Debug.Assert(vkRes == Result.SUCCESS, vkRes + " != Result.SUCCESS"); const uint VK_QUEUE_FAMILY_IGNORED = ~0U; var prePresentBarrier = new MgImageMemoryBarrier { Image = image, SrcAccessMask = MgAccessFlagBits.COLOR_ATTACHMENT_WRITE_BIT, DstAccessMask = 0, OldLayout = MgImageLayout.COLOR_ATTACHMENT_OPTIMAL, NewLayout = MgImageLayout.PRESENT_SRC_KHR, SrcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, DstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, SubresourceRange = new MgImageSubresourceRange { AspectMask = MgImageAspectFlagBits.COLOR_BIT, BaseArrayLayer = 0, LayerCount = 1, BaseMipLevel = 0, LevelCount = 1, }, }; const int VK_FLAGS_NONE = 0; prePresent.CmdPipelineBarrier( MgPipelineStageFlagBits.ALL_COMMANDS_BIT, MgPipelineStageFlagBits.TOP_OF_PIPE_BIT, VK_FLAGS_NONE, null, // No memory barriers, null, // No buffer barriers, new[] { prePresentBarrier }); vkRes = prePresent.EndCommandBuffer(); Debug.Assert(vkRes == Result.SUCCESS, vkRes + " != Result.SUCCESS"); }
// Fixed sub resource on first mip level and layer public void SetImageLayout( IMgCommandBuffer cmdbuffer, IMgImage image, MgImageAspectFlagBits aspectMask, MgImageLayout oldImageLayout, MgImageLayout newImageLayout) { var subresourceRange = new MgImageSubresourceRange { AspectMask = aspectMask, BaseMipLevel = 0, LevelCount = 1, LayerCount = 1, }; PushImageMemoryBarrier(cmdbuffer, image, aspectMask, oldImageLayout, newImageLayout, subresourceRange); }
private void CmdDrawIndexed(IMgCommandBuffer cmdBuf, MeshPrimitive meshPrimitive, RenderInstanceChunk drawCall, int sliceIndex) { var allocation = mStaticStorage.Map.Allocations[meshPrimitive.Indices[sliceIndex]]; var indexBlock = mStaticStorage.Storage.Blocks[allocation.BlockIndex]; var vertexDef = PerVertexDefinitionEncoder.Decode(meshPrimitive.PerVertexDefinition); var indexType = vertexDef.IndexType == PerVertexIndexType.Uint16 ? MgIndexType.UINT16 : MgIndexType.UINT32; cmdBuf.CmdBindIndexBuffer(indexBlock.Buffer, allocation.Offset, indexType); cmdBuf.CmdDrawIndexed(meshPrimitive.IndexCount, drawCall.InstanceCount, drawCall.FirstIndex, drawCall.VertexOffset, drawCall.FirstInstance); }
private void InitializeRenderCommandBuffers() { const uint MAX_NO_OF_PRESENT_BUFFERS = 2; mPresentingCmdBuffers = new Magnesium.IMgCommandBuffer[MAX_NO_OF_PRESENT_BUFFERS]; var pAllocateInfo = new Magnesium.MgCommandBufferAllocateInfo { CommandPool = mConfiguration.Partition.CommandPool, CommandBufferCount = MAX_NO_OF_PRESENT_BUFFERS, Level = Magnesium.MgCommandBufferLevel.PRIMARY, }; var err = mConfiguration.Device.AllocateCommandBuffers(pAllocateInfo, mPresentingCmdBuffers); Debug.Assert(err == Result.SUCCESS); mPrePresentBarrierCmd = mPresentingCmdBuffers[0]; mPostPresentBarrierCmd = mPresentingCmdBuffers[1]; }
public uint BeginDraw(IMgCommandBuffer postPresent, IMgSemaphore presentComplete, ulong timeout) { // Get next image in the swap chain (back/front buffer) //err = swapChain.acquireNextImage(semaphores.presentComplete, ¤tBuffer); var nextImage = AcquireNextImage(presentComplete, timeout); var currentBuffer = mCollection.Buffers [nextImage]; mBarrier.SubmitPostPresentBarrier(postPresent, currentBuffer.Image); var submitInfo = new[] { new MgSubmitInfo { CommandBuffers = new [] { postPresent }, } }; var result = mGraphicsConfiguration.Queue.QueueSubmit(submitInfo, null); Debug.Assert(result == Result.SUCCESS, result + " != Result.SUCCESS"); return(nextImage); }
void flushCommandBuffer(IMgCommandBuffer commandBuffer) { Debug.Assert(commandBuffer != null); var err = commandBuffer.EndCommandBuffer(); Debug.Assert(err == Result.SUCCESS); var submitInfos = new [] { new MgSubmitInfo { CommandBuffers = new [] { commandBuffer } } }; var fenceCreateInfo = new MgFenceCreateInfo(); err = mConfiguration.Device.CreateFence(fenceCreateInfo, null, out IMgFence fence); Debug.Assert(err == Result.SUCCESS); err = mConfiguration.Queue.QueueSubmit(submitInfos, fence); Debug.Assert(err == Result.SUCCESS); err = mConfiguration.Queue.QueueWaitIdle(); Debug.Assert(err == Result.SUCCESS); err = mConfiguration.Device.WaitForFences(new[] { fence }, true, ulong.MaxValue); Debug.Assert(err == Result.SUCCESS); fence.DestroyFence(mConfiguration.Device, null); mConfiguration.Device.FreeCommandBuffers(mConfiguration.Partition.CommandPool, new[] { commandBuffer }); }
public MgTextureInfo Load(byte[] imageData, MgImageSource source, IMgAllocationCallbacks allocator, IMgFence fence) { // Prefer using optimal tiling, as linear tiling // may support only a small set of features // depending on implementation (e.g. no mip maps, only one layer, etc.) IMgImage mappableImage; IMgDeviceMemory mappableMemory; uint mipLevels = (uint)source.Mipmaps.Length; // Load mip map level 0 to linear tiling image var imageCreateInfo = new MgImageCreateInfo { ImageType = MgImageType.TYPE_2D, Format = source.Format, MipLevels = mipLevels, ArrayLayers = 1, Samples = MgSampleCountFlagBits.COUNT_1_BIT, Tiling = MgImageTiling.LINEAR, Usage = MgImageUsageFlagBits.SAMPLED_BIT, SharingMode = MgSharingMode.EXCLUSIVE, InitialLayout = MgImageLayout.PREINITIALIZED, Extent = new MgExtent3D { Width = source.Width, Height = source.Height, Depth = 1 }, }; var device = mGraphicsConfiguration.Device; var err = device.CreateImage(imageCreateInfo, allocator, out mappableImage); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); // Get memory requirements for this image // like size and alignment MgMemoryRequirements memReqs; device.GetImageMemoryRequirements(mappableImage, out memReqs); // Set memory allocation size to required memory size var memAllocInfo = new MgMemoryAllocateInfo { AllocationSize = memReqs.Size, }; Debug.Assert(mGraphicsConfiguration.Partition != null); // Get memory type that can be mapped to host memory uint memoryTypeIndex; bool isValid = mGraphicsConfiguration.Partition.GetMemoryType(memReqs.MemoryTypeBits, MgMemoryPropertyFlagBits.HOST_VISIBLE_BIT, out memoryTypeIndex); Debug.Assert(isValid); memAllocInfo.MemoryTypeIndex = memoryTypeIndex; // Allocate host memory err = device.AllocateMemory(memAllocInfo, allocator, out mappableMemory); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); // Bind allocated image for use err = mappableImage.BindImageMemory(device, mappableMemory, 0); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); // Get sub resource layout // Mip map count, array layer, etc. var subRes = new MgImageSubresource { AspectMask = MgImageAspectFlagBits.COLOR_BIT, }; MgSubresourceLayout subResLayout; IntPtr data; // Get sub resources layout // Includes row pitch, size offsets, etc. device.GetImageSubresourceLayout(mappableImage, subRes, out subResLayout); // Map image memory err = mappableMemory.MapMemory(device, 0, memReqs.Size, 0, out data); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); // Copy image data into memory //memcpy(data, tex2D[subRes.mipLevel].data(), tex2D[subRes.mipLevel].size()); Marshal.Copy(imageData, 0, data, (int)source.Size); mappableMemory.UnmapMemory(device); // Linear tiled images don't need to be staged // and can be directly used as textures var texture = new MgTextureInfo { Image = mappableImage, DeviceMemory = mappableMemory, ImageLayout = MgImageLayout.SHADER_READ_ONLY_OPTIMAL, }; var cmdPool = mGraphicsConfiguration.Partition.CommandPool; var cmdBufAllocateInfo = new MgCommandBufferAllocateInfo { CommandPool = cmdPool, Level = MgCommandBufferLevel.PRIMARY, CommandBufferCount = 1, }; var commands = new IMgCommandBuffer[1]; err = device.AllocateCommandBuffers(cmdBufAllocateInfo, commands); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); var cmdBufInfo = new MgCommandBufferBeginInfo { Flags = 0, }; texture.Command = commands [0]; err = commands[0].BeginCommandBuffer(cmdBufInfo); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); // Setup image memory barrier transfer image to shader read layout mImageTools.SetImageLayout( texture.Command, texture.Image, MgImageAspectFlagBits.COLOR_BIT, MgImageLayout.PREINITIALIZED, texture.ImageLayout, 0, mipLevels); err = texture.Command.EndCommandBuffer(); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); var submitInfo = new MgSubmitInfo { CommandBuffers = commands, }; var queue = mGraphicsConfiguration.Queue; queue.QueueSubmit(new[] { submitInfo }, fence); // // NOT SURE IF // err = queue.QueueWaitIdle(); // Debug.Assert (err == Result.SUCCESS, err + " != Result.SUCCESS"); // // device.FreeCommandBuffers(cmdPool, commands); // texture.Command = copyCmd; return(texture); }
void CreateDepthStencil(IMgCommandBuffer setupCmdBuffer, MgGraphicsDeviceCreateInfo createInfo) { var image = new MgImageCreateInfo { ImageType = MgImageType.TYPE_2D, Format = createInfo.DepthStencil, Extent = new MgExtent3D { Width = createInfo.Width, Height = createInfo.Height, Depth = 1 }, MipLevels = 1, ArrayLayers = 1, Samples = createInfo.Samples, Tiling = MgImageTiling.OPTIMAL, // TODO : multisampled uses MgImageUsageFlagBits.TRANSIENT_ATTACHMENT_BIT | MgImageUsageFlagBits.DEPTH_STENCIL_ATTACHMENT_BIT; Usage = MgImageUsageFlagBits.DEPTH_STENCIL_ATTACHMENT_BIT | MgImageUsageFlagBits.TRANSFER_SRC_BIT, Flags = 0, }; var mem_alloc = new MgMemoryAllocateInfo { AllocationSize = 0, MemoryTypeIndex = 0, }; MgMemoryRequirements memReqs; Debug.Assert(mGraphicsConfiguration.Partition != null); Result err; { IMgImage dsImage; err = mGraphicsConfiguration.Partition.Device.CreateImage(image, null, out dsImage); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); mImage = dsImage; } mGraphicsConfiguration.Partition.Device.GetImageMemoryRequirements(mImage, out memReqs); mem_alloc.AllocationSize = memReqs.Size; uint memTypeIndex; bool memoryTypeFound = mGraphicsConfiguration.Partition.GetMemoryType(memReqs.MemoryTypeBits, MgMemoryPropertyFlagBits.DEVICE_LOCAL_BIT, out memTypeIndex); Debug.Assert(memoryTypeFound); mem_alloc.MemoryTypeIndex = memTypeIndex; { IMgDeviceMemory dsDeviceMemory; err = mGraphicsConfiguration.Partition.Device.AllocateMemory(mem_alloc, null, out dsDeviceMemory); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); mDeviceMemory = dsDeviceMemory; } err = mImage.BindImageMemory(mGraphicsConfiguration.Partition.Device, mDeviceMemory, 0); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); mImageTools.SetImageLayout(setupCmdBuffer, mImage, MgImageAspectFlagBits.DEPTH_BIT | MgImageAspectFlagBits.STENCIL_BIT, MgImageLayout.UNDEFINED, MgImageLayout.DEPTH_STENCIL_ATTACHMENT_OPTIMAL); var depthStencilView = new MgImageViewCreateInfo { Image = mImage, ViewType = MgImageViewType.TYPE_2D, Format = createInfo.DepthStencil, Flags = 0, SubresourceRange = new MgImageSubresourceRange { AspectMask = MgImageAspectFlagBits.DEPTH_BIT | MgImageAspectFlagBits.STENCIL_BIT, BaseMipLevel = 0, LevelCount = 1, BaseArrayLayer = 0, LayerCount = 1, }, }; { IMgImageView dsView; err = mGraphicsConfiguration.Partition.Device.CreateImageView(depthStencilView, null, out dsView); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); mDepthStencilImageView = dsView; } }
public void SubmitPrePresentBarrier(IMgCommandBuffer prePresent, IMgImage image) { }
public void Create(IMgCommandBuffer setupCmdBuffer, IMgSwapchainCollection swapchainCollection, MgGraphicsDeviceCreateInfo dsCreateInfo) { if (dsCreateInfo == null) { throw new ArgumentNullException(nameof(dsCreateInfo)); } if (swapchainCollection == null) { throw new ArgumentNullException(nameof(swapchainCollection)); } mDeviceCreated = false; var colorFormat = AmtFormatExtensions.GetPixelFormat(dsCreateInfo.Color); var depthFormat = AmtFormatExtensions.GetPixelFormat(dsCreateInfo.DepthStencil); var sampleCount = AmtSampleCountFlagBitExtensions.TranslateSampleCount(dsCreateInfo.Samples); ReleaseUnmanagedResources(); mApplicationView.SampleCount = sampleCount; // FIXME : RUNTIME ISSUE WITH SETTING COLOR FORMAT; SHOULD "FIGURE" OUT APPROPRIATE COLOR FORMAT SOMEHOW mApplicationView.ColorPixelFormat = colorFormat; mApplicationView.DepthStencilPixelFormat = depthFormat; CreateDepthStencilImageView(); CreateRenderpass(dsCreateInfo); var bSwapchainCollection = (AmtSwapchainCollection)swapchainCollection; bSwapchainCollection.Format = dsCreateInfo.Color; bSwapchainCollection.Create(setupCmdBuffer, dsCreateInfo.Width, dsCreateInfo.Height); mFramebuffers.Create( swapchainCollection, mRenderpass, mDepthStencilView, dsCreateInfo.Width, dsCreateInfo.Height); Scissor = new MgRect2D { Extent = new MgExtent2D { Width = dsCreateInfo.Width, Height = dsCreateInfo.Height }, Offset = new MgOffset2D { X = 0, Y = 0 }, }; // initialise viewport CurrentViewport = new MgViewport { Width = dsCreateInfo.Width, Height = dsCreateInfo.Height, X = 0, Y = 0, MinDepth = 0f, MaxDepth = 1f, }; mDeviceCreated = true; }
public void Create(IMgCommandBuffer cmd, uint width, uint height) { Width = width; Height = height; }
public void Create(IMgCommandBuffer cmd, UInt32 width, UInt32 height) { mWidth = width; mHeight = height; Result err; IMgSwapchainKHR oldSwapchain = mSwapChain; Setup(); // Get physical device surface properties and formats MgSurfaceCapabilitiesKHR surfCaps; err = mPartition.PhysicalDevice.GetPhysicalDeviceSurfaceCapabilitiesKHR(mLayer.Surface, out surfCaps); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); // Get available present modes MgPresentModeKHR[] presentModes; err = mPartition.PhysicalDevice.GetPhysicalDeviceSurfacePresentModesKHR(mLayer.Surface, out presentModes); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); var swapchainExtent = new MgExtent2D { }; // width and height are either both -1, or both not -1. if ((int)surfCaps.CurrentExtent.Width == -1) { // If the surface size is undefined, the size is set to // the size of the images requested. swapchainExtent.Width = mWidth; swapchainExtent.Height = mHeight; } else { // If the surface size is defined, the swap chain size must match swapchainExtent = surfCaps.CurrentExtent; mWidth = surfCaps.CurrentExtent.Width; mHeight = surfCaps.CurrentExtent.Height; } // Prefer mailbox mode if present, it's the lowest latency non-tearing present mode MgPresentModeKHR swapchainPresentMode = MgPresentModeKHR.FIFO_KHR; for (uint i = 0; i < presentModes.Length; i++) { if (presentModes[i] == MgPresentModeKHR.MAILBOX_KHR) { swapchainPresentMode = MgPresentModeKHR.MAILBOX_KHR; break; } if ((swapchainPresentMode != MgPresentModeKHR.MAILBOX_KHR) && (presentModes[i] == MgPresentModeKHR.IMMEDIATE_KHR)) { swapchainPresentMode = MgPresentModeKHR.IMMEDIATE_KHR; } } // Determine the number of images uint desiredNumberOfSwapchainImages = surfCaps.MinImageCount + 1; if ((surfCaps.MaxImageCount > 0) && (desiredNumberOfSwapchainImages > surfCaps.MaxImageCount)) { desiredNumberOfSwapchainImages = surfCaps.MaxImageCount; } MgSurfaceTransformFlagBitsKHR preTransform; if ((surfCaps.SupportedTransforms & MgSurfaceTransformFlagBitsKHR.IDENTITY_BIT_KHR) != 0) { preTransform = MgSurfaceTransformFlagBitsKHR.IDENTITY_BIT_KHR; } else { preTransform = surfCaps.CurrentTransform; } var swapchainCI = new MgSwapchainCreateInfoKHR { Surface = mLayer.Surface, MinImageCount = desiredNumberOfSwapchainImages, ImageFormat = Format, ImageColorSpace = mColorSpace, ImageExtent = swapchainExtent, ImageUsage = MgImageUsageFlagBits.COLOR_ATTACHMENT_BIT, PreTransform = (MgSurfaceTransformFlagBitsKHR)preTransform, ImageArrayLayers = 1, ImageSharingMode = MgSharingMode.EXCLUSIVE, QueueFamilyIndices = null, PresentMode = swapchainPresentMode, OldSwapchain = oldSwapchain, Clipped = true, CompositeAlpha = MgCompositeAlphaFlagBitsKHR.OPAQUE_BIT_KHR, }; err = mPartition.Device.CreateSwapchainKHR(swapchainCI, null, out mSwapChain); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); // If an existing swap chain is re-created, destroy the old swap chain // This also cleans up all the presentable images if (oldSwapchain != null) { for (uint i = 0; i < mImageCount; i++) { mBuffers[i].View.DestroyImageView(mPartition.Device, null); } oldSwapchain.DestroySwapchainKHR(mPartition.Device, null); } // Get the swap chain images err = mPartition.Device.GetSwapchainImagesKHR(mSwapChain, out mImages); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); // Get the swap chain buffers containing the image and imageview mImageCount = (uint)mImages.Length; mBuffers = new MgSwapchainBuffer[mImageCount]; for (uint i = 0; i < mImageCount; i++) { var buffer = new MgSwapchainBuffer(); var colorAttachmentView = new MgImageViewCreateInfo { Format = Format, Components = new MgComponentMapping { R = MgComponentSwizzle.R, G = MgComponentSwizzle.G, B = MgComponentSwizzle.B, A = MgComponentSwizzle.A, }, SubresourceRange = new MgImageSubresourceRange { AspectMask = MgImageAspectFlagBits.COLOR_BIT, BaseMipLevel = 0, LevelCount = 1, BaseArrayLayer = 0, LayerCount = 1, }, ViewType = MgImageViewType.TYPE_2D, Flags = 0, }; buffer.Image = mImages[i]; // Transform images from initial (undefined) to present layout mImageTools.SetImageLayout( cmd, buffer.Image, MgImageAspectFlagBits.COLOR_BIT, MgImageLayout.UNDEFINED, MgImageLayout.PRESENT_SRC_KHR); colorAttachmentView.Image = buffer.Image; IMgImageView bufferView; err = mPartition.Device.CreateImageView(colorAttachmentView, null, out bufferView); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); buffer.View = bufferView; mBuffers [i] = buffer; } }
public void Preamble() { // PRIVATE IMPLEMENTATION UNIT TESTING mContainer = new Container(); mContainer.Register <IMgQueue, GLCmdQueue>(Reuse.Singleton); mContainer.Register <IGLCmdStateRenderer, GLCmdStateRenderer>(Reuse.Singleton); mContainer.Register <IGLCmdBlendEntrypoint, MockGLCmdBlendEntrypoint>(Reuse.Singleton); mContainer.Register <IGLCmdStencilEntrypoint, MockGLCmdStencilEntrypoint>(Reuse.Singleton); mContainer.Register <IGLCmdRasterizationEntrypoint, MockGLCmdRasterizationEntrypoint>(Reuse.Singleton); mContainer.Register <IGLCmdDepthEntrypoint, MockGLCmdDepthEntrypoint>(Reuse.Singleton); mContainer.Register <IGLCmdScissorsEntrypoint, MockGLCmdScissorsEntrypoint>(Reuse.Singleton); mContainer.Register <IGLCmdDrawEntrypoint, MockGLCmdDrawEntrypoint>(Reuse.Singleton); mContainer.Register <IGLCmdClearEntrypoint, MockGLCmdClearEntrypoint>(Reuse.Singleton); mContainer.Register <IGLErrorHandler, MockGLErrorHandler>(Reuse.Singleton); mContainer.Register <IGLNextCmdShaderProgramCache, GLNextCmdShaderProgramCache>(Reuse.Singleton); mContainer.Register <IGLCmdShaderProgramEntrypoint, MockGLCmdShaderProgramEntrypoint>(Reuse.Singleton); mContainer.Register <IGLBlitOperationEntrypoint, MockGLBlitOperationEntrypoint>(Reuse.Singleton); mContainer.Register <IGLSemaphoreEntrypoint, MockGLSemaphoreEntrypoint>(Reuse.Singleton); mContainer.Register <IGLCmdImageEntrypoint, MockGLCmdImageEntrypoint>(Reuse.Singleton); mContainer.Register <IGLCmdBlitEncoder, GLCmdBlitEncoder>(Reuse.Singleton); mContainer.Register <GLCmdBlitBag>(Reuse.Singleton); mContainer.Register <IGLCmdComputeEncoder, GLCmdComputeEncoder>(Reuse.Singleton); mContainer.Register <IGLCmdGraphicsEncoder, GLCmdGraphicsEncoder>(Reuse.Singleton); mContainer.Register <GLCmdGraphicsBag>(Reuse.Singleton); mContainer.Register <IGLCmdVBOEntrypoint, MockGLCmdVBOEntrypoint>(Reuse.Singleton); mContainer.Register <IGLDescriptorSetBinder, GLNextDescriptorSetBinder>(Reuse.Singleton); mContainer.Register <IGLCmdEncoderContextSorter, GLCmdIncrementalContextSorter>(Reuse.Singleton); mContainer.Register <GLCmdCommandEncoder>(Reuse.Singleton); mContainer.Register <GLInternalCache>(Reuse.Singleton); mContainer.Register <IMgPipeline, GLGraphicsPipeline>(Reuse.Singleton); mContainer.Register <IGLGraphicsPipelineCompiler, MockGLGraphicsPipelineCompiler>(Reuse.Singleton); mContainer.Register <IGLGraphicsPipelineEntrypoint, MockGLGraphicsPipelineEntrypoint>(Reuse.Singleton); queue = mContainer.Resolve <IMgQueue>(); var cmdEncoder = mContainer.Resolve <GLCmdCommandEncoder>(); cmdBuf = new Magnesium.OpenGL.Internals.GLCmdCommandBuffer(true, cmdEncoder); framebuffer = new Magnesium.OpenGL.Internals.GLFramebuffer(); renderpass = new GLRenderPass(new MgAttachmentDescription[] { }); vertexBuffer = new MockGLBuffer { BufferId = 1, Usage = MgBufferUsageFlagBits.VERTEX_BUFFER_BIT, }; indexBuffer = new MockGLBuffer { BufferId = 2, Usage = MgBufferUsageFlagBits.INDEX_BUFFER_BIT, }; var layout = new MockGLPipelineLayout { }; mContainer.RegisterInstance <IGLPipelineLayout>(layout, Reuse.Singleton); var blockEntries = new GLUniformBlockEntry[] { }; var arrayMapper = new Magnesium.OpenGL.Internals.GLInternalCacheArrayMapper(layout, blockEntries); mContainer.RegisterInstance <GLInternalCacheArrayMapper>(arrayMapper, Reuse.Singleton); var entrypoint = mContainer.Resolve <IGLGraphicsPipelineEntrypoint>(); var internalCache = mContainer.Resolve <GLInternalCache>(); var info = new MgGraphicsPipelineCreateInfo { VertexInputState = new MgPipelineVertexInputStateCreateInfo { VertexAttributeDescriptions = new[] { new MgVertexInputAttributeDescription { Binding = 0, Location = 0, Format = MgFormat.R8G8B8A8_SNORM, } }, VertexBindingDescriptions = new[] { new MgVertexInputBindingDescription { Binding = 0, InputRate = MgVertexInputRate.VERTEX, Stride = 32, } } }, RasterizationState = new MgPipelineRasterizationStateCreateInfo { PolygonMode = MgPolygonMode.FILL, }, InputAssemblyState = new MgPipelineInputAssemblyStateCreateInfo { Topology = MgPrimitiveTopology.TRIANGLE_LIST, } }; pipeline = new Magnesium.OpenGL.Internals.GLGraphicsPipeline(entrypoint, 1, info, internalCache, layout); var stateRenderer = mContainer.Resolve <IGLCmdStateRenderer>(); stateRenderer.Initialize(); }
public uint BeginDraw(IMgCommandBuffer postPresent, IMgSemaphore presentComplete) { return(BeginDraw(postPresent, presentComplete, ulong.MaxValue)); }
// 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 }); }
// FROM texture.cpp (2016) Sascha Williams public MgTextureInfo Load(byte[] imageData, MgImageSource source, IMgAllocationCallbacks allocator, IMgFence fence) { var device = mGraphicsConfiguration.Device; var queue = mGraphicsConfiguration.Queue; var cmdPool = mGraphicsConfiguration.Partition.CommandPool; uint mipLevels = (uint)source.Mipmaps.Length; // Create a host-visible staging buffer that contains the raw image data IMgBuffer stagingBuffer; IMgDeviceMemory stagingMemory; var bufferCreateInfo = new MgBufferCreateInfo { Size = source.Size, Usage = MgBufferUsageFlagBits.TRANSFER_SRC_BIT, SharingMode = MgSharingMode.EXCLUSIVE, }; // This buffer is used as a transfer source for the buffer copy var result = device.CreateBuffer(bufferCreateInfo, allocator, out stagingBuffer); Debug.Assert(result == Result.SUCCESS); MgMemoryRequirements memReqs; // Get memory requirements for the staging buffer (alignment, memory type bits) mGraphicsConfiguration.Device.GetBufferMemoryRequirements(stagingBuffer, out memReqs); var memAllocInfo = new MgMemoryAllocateInfo { AllocationSize = memReqs.Size, }; // Get memory type index for a host visible buffer uint memoryTypeIndex; bool isTypeValid = mGraphicsConfiguration.Partition.GetMemoryType(memReqs.MemoryTypeBits, MgMemoryPropertyFlagBits.HOST_VISIBLE_BIT, out memoryTypeIndex); Debug.Assert(isTypeValid); memAllocInfo.MemoryTypeIndex = memoryTypeIndex; result = device.AllocateMemory(memAllocInfo, allocator, out stagingMemory); Debug.Assert(result == Result.SUCCESS); result = stagingBuffer.BindBufferMemory(device, stagingMemory, 0); Debug.Assert(result == Result.SUCCESS); // Copy texture data into staging buffer IntPtr data; result = stagingMemory.MapMemory(device, 0, memReqs.Size, 0, out data); Debug.Assert(result == Result.SUCCESS); // TODO : Copy here Marshal.Copy(imageData, 0, data, (int)source.Size); stagingMemory.UnmapMemory(device); // Setup buffer copy regions for each mip level var bufferCopyRegions = new MgBufferImageCopy[source.Mipmaps.Length]; for (uint i = 0; i < bufferCopyRegions.Length; ++i) { bufferCopyRegions [i] = new MgBufferImageCopy { ImageSubresource = new MgImageSubresourceLayers { AspectMask = MgImageAspectFlagBits.COLOR_BIT, MipLevel = i, BaseArrayLayer = 0, LayerCount = 1, }, ImageExtent = new MgExtent3D { Width = source.Mipmaps[i].Width, Height = source.Mipmaps[i].Height, Depth = 1, }, BufferOffset = source.Mipmaps[i].Offset, }; } // Create optimal tiled target image var imageCreateInfo = new MgImageCreateInfo { ImageType = MgImageType.TYPE_2D, Format = source.Format, MipLevels = mipLevels, ArrayLayers = 1, Samples = MgSampleCountFlagBits.COUNT_1_BIT, Tiling = MgImageTiling.OPTIMAL, SharingMode = MgSharingMode.EXCLUSIVE, InitialLayout = MgImageLayout.PREINITIALIZED, Extent = new MgExtent3D { Width = source.Width, Height = source.Height, Depth = 1 }, Usage = MgImageUsageFlagBits.TRANSFER_DST_BIT | MgImageUsageFlagBits.SAMPLED_BIT, }; var texture = new MgTextureInfo(); IMgImage image; result = device.CreateImage(imageCreateInfo, allocator, out image); Debug.Assert(result == Result.SUCCESS); texture.Image = image; device.GetImageMemoryRequirements(texture.Image, out memReqs); memAllocInfo.AllocationSize = memReqs.Size; isTypeValid = mGraphicsConfiguration.Partition.GetMemoryType(memReqs.MemoryTypeBits, MgMemoryPropertyFlagBits.DEVICE_LOCAL_BIT, out memoryTypeIndex); Debug.Assert(isTypeValid); memAllocInfo.MemoryTypeIndex = memoryTypeIndex; IMgDeviceMemory deviceMem; result = device.AllocateMemory(memAllocInfo, allocator, out deviceMem); Debug.Assert(result == Result.SUCCESS); texture.DeviceMemory = deviceMem; result = texture.Image.BindImageMemory(device, texture.DeviceMemory, 0); Debug.Assert(result == Result.SUCCESS); var cmdBufAllocateInfo = new MgCommandBufferAllocateInfo { CommandPool = cmdPool, Level = MgCommandBufferLevel.PRIMARY, CommandBufferCount = 1, }; var commands = new IMgCommandBuffer[1]; result = device.AllocateCommandBuffers(cmdBufAllocateInfo, commands); Debug.Assert(result == Result.SUCCESS); var cmdBufInfo = new MgCommandBufferBeginInfo { Flags = 0, }; texture.Command = commands [0]; result = commands[0].BeginCommandBuffer(cmdBufInfo); Debug.Assert(result == Result.SUCCESS); // Image barrier for optimal image (target) // Optimal image will be used as destination for the copy mImageTools.SetImageLayout( texture.Command, texture.Image, MgImageAspectFlagBits.COLOR_BIT, MgImageLayout.PREINITIALIZED, MgImageLayout.TRANSFER_DST_OPTIMAL, 0, mipLevels); // Copy mip levels from staging buffer texture.Command.CmdCopyBufferToImage( stagingBuffer, texture.Image, MgImageLayout.TRANSFER_DST_OPTIMAL, bufferCopyRegions ); // Change texture image layout to shader read after all mip levels have been copied texture.ImageLayout = MgImageLayout.SHADER_READ_ONLY_OPTIMAL; mImageTools.SetImageLayout( texture.Command, texture.Image, MgImageAspectFlagBits.COLOR_BIT, MgImageLayout.TRANSFER_DST_OPTIMAL, texture.ImageLayout, 0, mipLevels); result = texture.Command.EndCommandBuffer(); Debug.Assert(result == Result.SUCCESS); var submitInfo = new MgSubmitInfo { CommandBuffers = commands, }; queue.QueueSubmit(new[] { submitInfo }, fence); // result = queue.QueueWaitIdle(); // Debug.Assert (result == Result.SUCCESS); // // device.FreeCommandBuffers(cmdPool, commands); // texture.Command = copyCmd; // Clean up staging resources stagingMemory.FreeMemory(device, allocator); stagingBuffer.DestroyBuffer(device, allocator); return(texture); }
// Create an image memory barrier for changing the layout of // an image and put it into an active command buffer public void SetImageLayout( IMgCommandBuffer cmdBuffer, IMgImage image, MgImageAspectFlagBits aspectMask, MgImageLayout oldImageLayout, MgImageLayout newImageLayout, uint mipLevel, uint mipLevelCount) { // Create an image barrier object var imageMemoryBarrier = new MgImageMemoryBarrier() { OldLayout = oldImageLayout, NewLayout = newImageLayout, Image = image, SubresourceRange = new MgImageSubresourceRange { AspectMask = aspectMask, BaseMipLevel = mipLevel, LevelCount = mipLevelCount, LayerCount = 1, }, }; // Only sets masks for layouts used in this example // For a more complete version that can be used with // other layouts see vkTools::setImageLayout // Source layouts (new) if (oldImageLayout == MgImageLayout.PREINITIALIZED) { imageMemoryBarrier.SrcAccessMask = MgAccessFlagBits.HOST_WRITE_BIT | MgAccessFlagBits.TRANSFER_WRITE_BIT; } // Target layouts (new) // New layout is transfer destination (copy, blit) // Make sure any reads from and writes to the image have been finished if (newImageLayout == MgImageLayout.TRANSFER_DST_OPTIMAL) { imageMemoryBarrier.DstAccessMask = MgAccessFlagBits.TRANSFER_READ_BIT | MgAccessFlagBits.HOST_WRITE_BIT | MgAccessFlagBits.TRANSFER_WRITE_BIT; } // New layout is shader read (sampler, input attachment) // Make sure any writes to the image have been finished if (newImageLayout == MgImageLayout.SHADER_READ_ONLY_OPTIMAL) { imageMemoryBarrier.SrcAccessMask = MgAccessFlagBits.HOST_WRITE_BIT | MgAccessFlagBits.TRANSFER_WRITE_BIT; imageMemoryBarrier.DstAccessMask = MgAccessFlagBits.SHADER_READ_BIT; } // New layout is transfer source (copy, blit) // Make sure any reads from and writes to the image have been finished if (newImageLayout == MgImageLayout.TRANSFER_SRC_OPTIMAL) { imageMemoryBarrier.DstAccessMask = MgAccessFlagBits.TRANSFER_READ_BIT | MgAccessFlagBits.HOST_WRITE_BIT | MgAccessFlagBits.TRANSFER_WRITE_BIT; } // Put barrier on top MgPipelineStageFlagBits srcStageFlags = MgPipelineStageFlagBits.TOP_OF_PIPE_BIT; MgPipelineStageFlagBits destStageFlags = MgPipelineStageFlagBits.TOP_OF_PIPE_BIT; const int VK_FLAGS_NONE = 0; // Put barrier inside setup command buffer cmdBuffer.CmdPipelineBarrier( srcStageFlags, destStageFlags, VK_FLAGS_NONE, null, null, new [] { imageMemoryBarrier }); }
// Create an image memory barrier for changing the layout of // an image and put it into an active command buffer // See chapter 11.4 "Image Layout" for details private void PushImageMemoryBarrier( IMgCommandBuffer cmdbuffer, IMgImage image, MgImageAspectFlagBits aspectMask, MgImageLayout oldImageLayout, MgImageLayout newImageLayout, MgImageSubresourceRange subresourceRange) { const uint VK_QUEUE_FAMILY_IGNORED = ~0U; // 0xffffffff; // Create an image barrier object MgImageMemoryBarrier imageMemoryBarrier = new MgImageMemoryBarrier { OldLayout = oldImageLayout, NewLayout = newImageLayout, Image = image, SubresourceRange = subresourceRange, // Some default values SrcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, DstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, }; // Source layouts (old) // Undefined layout // Only allowed as initial layout! // Make sure any writes to the image have been finished if (oldImageLayout == MgImageLayout.PREINITIALIZED) { imageMemoryBarrier.SrcAccessMask = (MgAccessFlagBits.HOST_WRITE_BIT | MgAccessFlagBits.TRANSFER_WRITE_BIT); } // Old layout is color attachment // Make sure any writes to the color buffer have been finished if (oldImageLayout == MgImageLayout.COLOR_ATTACHMENT_OPTIMAL) { imageMemoryBarrier.SrcAccessMask = MgAccessFlagBits.COLOR_ATTACHMENT_WRITE_BIT; } // Old layout is depth/stencil attachment // Make sure any writes to the depth/stencil buffer have been finished if (oldImageLayout == MgImageLayout.DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { imageMemoryBarrier.SrcAccessMask = MgAccessFlagBits.DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; } // Old layout is transfer source // Make sure any reads from the image have been finished if (oldImageLayout == MgImageLayout.TRANSFER_SRC_OPTIMAL) { imageMemoryBarrier.SrcAccessMask = MgAccessFlagBits.TRANSFER_READ_BIT; } // Old layout is shader read (sampler, input attachment) // Make sure any shader reads from the image have been finished if (oldImageLayout == MgImageLayout.SHADER_READ_ONLY_OPTIMAL) { imageMemoryBarrier.SrcAccessMask = MgAccessFlagBits.SHADER_READ_BIT; } // Target layouts (new) // New layout is transfer destination (copy, blit) // Make sure any copyies to the image have been finished if (newImageLayout == MgImageLayout.TRANSFER_DST_OPTIMAL) { imageMemoryBarrier.DstAccessMask = MgAccessFlagBits.TRANSFER_WRITE_BIT; } // New layout is transfer source (copy, blit) // Make sure any reads from and writes to the image have been finished if (newImageLayout == MgImageLayout.TRANSFER_SRC_OPTIMAL) { imageMemoryBarrier.SrcAccessMask = imageMemoryBarrier.SrcAccessMask | MgAccessFlagBits.TRANSFER_READ_BIT; imageMemoryBarrier.DstAccessMask = MgAccessFlagBits.TRANSFER_READ_BIT; } // New layout is color attachment // Make sure any writes to the color buffer have been finished if (newImageLayout == MgImageLayout.COLOR_ATTACHMENT_OPTIMAL) { imageMemoryBarrier.DstAccessMask = MgAccessFlagBits.COLOR_ATTACHMENT_WRITE_BIT; imageMemoryBarrier.SrcAccessMask = MgAccessFlagBits.TRANSFER_READ_BIT; } // New layout is depth attachment // Make sure any writes to depth/stencil buffer have been finished if (newImageLayout == MgImageLayout.DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { imageMemoryBarrier.DstAccessMask = imageMemoryBarrier.DstAccessMask | MgAccessFlagBits.DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; } // New layout is shader read (sampler, input attachment) // Make sure any writes to the image have been finished if (newImageLayout == MgImageLayout.SHADER_READ_ONLY_OPTIMAL) { imageMemoryBarrier.SrcAccessMask = MgAccessFlagBits.HOST_WRITE_BIT | MgAccessFlagBits.TRANSFER_WRITE_BIT; imageMemoryBarrier.DstAccessMask = MgAccessFlagBits.SHADER_READ_BIT; } // Put barrier on top MgPipelineStageFlagBits srcStageFlags = MgPipelineStageFlagBits.TOP_OF_PIPE_BIT; MgPipelineStageFlagBits destStageFlags = MgPipelineStageFlagBits.TOP_OF_PIPE_BIT; // Put barrier inside setup command buffer cmdbuffer.CmdPipelineBarrier( srcStageFlags, destStageFlags, 0, null, null, new [] { imageMemoryBarrier }); }
public void Build(IMgCommandBuffer cmdBuf, int sliceIndex) { cmdBuf.BeginCommandBuffer(new MgCommandBufferBeginInfo { }); // TODO: RENDER PASS STUFF // CLEAR COLOR // VIEWPORTS // SCISSORS foreach (var group in Groups.Values) { cmdBuf.CmdBindPipeline(MgPipelineBindPoint.GRAPHICS, group.Pipeline); var noOfDescriptorSets = DescriptorSets.Length; for (var i = 0; i < noOfDescriptorSets; i += 1) { cmdBuf.CmdBindDescriptorSets( MgPipelineBindPoint.GRAPHICS, group.Layout, 0, new[] { DescriptorSets[i] }, null ); var range = group.Ranges[i]; var meshPrimitive = Scene.MeshPrimitives[range.MeshPrimitive]; foreach (var drawCall in range.InstanceDrawCalls) { var perInstance = mDynamicStorage.Map.Allocations[drawCall.PerInstance[sliceIndex]]; var perInstanceBlock = mDynamicStorage.Storage.Blocks[perInstance.BlockIndex]; var perVertex = mStaticStorage.Map.Allocations[meshPrimitive.Vertices[sliceIndex]]; var perVertexBlock = mStaticStorage.Storage.Blocks[perVertex.BlockIndex]; cmdBuf.CmdBindVertexBuffers( 0, // TODO: multiple per-vertex buffers new[] { perVertexBlock.Buffer, perInstanceBlock.Buffer, }, new [] { perVertex.Offset, perInstance.Offset, } ); switch (group.DrawMode) { case LocalDrawMode.Draw: CmdDraw(cmdBuf, meshPrimitive, drawCall, sliceIndex); break; case LocalDrawMode.DrawIndexed: CmdDrawIndexed(cmdBuf, meshPrimitive, drawCall, sliceIndex); break; default: throw new InvalidOperationException("draw mode not implemented"); } } } } cmdBuf.EndCommandBuffer(); }