示例#1
0
        private static void InitMips(VkDevice device, VkQueue queue, VkImage image, int width, int height, uint mipLevels, uint layerCount, int cmdPool)
        {
            VkCommandBufferAllocateInfo pAllocateInfo = VkCommandBufferAllocateInfo.New();

            pAllocateInfo.commandPool        = CommandPoolManager.GetPool(cmdPool);
            pAllocateInfo.level              = VkCommandBufferLevel.Primary;
            pAllocateInfo.commandBufferCount = 1;

            VkCommandBuffer cmdBuffer = VkCommandBuffer.Null;

            Assert(vkAllocateCommandBuffers(device, &pAllocateInfo, &cmdBuffer));


            Assert(vkResetCommandBuffer(cmdBuffer, VkCommandBufferResetFlags.None));
            VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New();

            beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit;

            Assert(vkBeginCommandBuffer(cmdBuffer, &beginInfo));

            VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New();

            imageMemoryBarrier.srcAccessMask       = VkAccessFlags.None;
            imageMemoryBarrier.dstAccessMask       = VkAccessFlags.TransferWrite;
            imageMemoryBarrier.oldLayout           = VkImageLayout.Undefined;
            imageMemoryBarrier.newLayout           = VkImageLayout.TransferDstOptimal;
            imageMemoryBarrier.srcQueueFamilyIndex = VulkanNative.QueueFamilyIgnored;
            imageMemoryBarrier.dstQueueFamilyIndex = VulkanNative.QueueFamilyIgnored;
            imageMemoryBarrier.image            = image;
            imageMemoryBarrier.subresourceRange = new VkImageSubresourceRange()
            {
                baseMipLevel   = 0,
                levelCount     = mipLevels,
                baseArrayLayer = 0,
                layerCount     = layerCount,
                aspectMask     = VkImageAspectFlags.Color
            };

            vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion,
                                 0, null, 0, null, 1, &imageMemoryBarrier);

            for (int i = 1; i < mipLevels; i++)
            {
                imageMemoryBarrier.oldLayout     = VkImageLayout.TransferDstOptimal;
                imageMemoryBarrier.newLayout     = VkImageLayout.TransferSrcOptimal;
                imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferWrite;
                imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferRead;
                imageMemoryBarrier.subresourceRange.baseMipLevel = (uint)(i - 1);
                imageMemoryBarrier.subresourceRange.levelCount   = 1;
                vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion,
                                     0, null, 0, null, 1, &imageMemoryBarrier);

                VkImageBlit blit = new VkImageBlit();
                blit.srcOffsets_0 = new VkOffset3D {
                    x = 0, y = 0, z = 0
                };
                blit.srcOffsets_1 = new VkOffset3D {
                    x = width, y = height, z = 1
                };
                blit.srcSubresource.aspectMask     = VkImageAspectFlags.Color;
                blit.srcSubresource.mipLevel       = (uint)(i - 1);
                blit.srcSubresource.baseArrayLayer = 0;
                blit.srcSubresource.layerCount     = layerCount;
                blit.dstOffsets_0 = new VkOffset3D {
                    x = 0, y = 0, z = 0
                };
                blit.dstOffsets_1 = new VkOffset3D {
                    x = width / 2, y = height / 2, z = 1
                };
                blit.dstSubresource.aspectMask     = VkImageAspectFlags.Color;
                blit.dstSubresource.mipLevel       = (uint)i;
                blit.dstSubresource.baseArrayLayer = 0;
                blit.dstSubresource.layerCount     = layerCount;
                vkCmdBlitImage(cmdBuffer, image, VkImageLayout.TransferSrcOptimal, image, VkImageLayout.TransferDstOptimal,
                               1, &blit, VkFilter.Linear);
                width  /= 2;
                height /= 2;

                imageMemoryBarrier.oldLayout     = VkImageLayout.TransferSrcOptimal;
                imageMemoryBarrier.newLayout     = VkImageLayout.ShaderReadOnlyOptimal;
                imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
                imageMemoryBarrier.dstAccessMask = VkAccessFlags.ShaderRead;
                imageMemoryBarrier.subresourceRange.baseMipLevel = (uint)(i - 1);
                imageMemoryBarrier.subresourceRange.levelCount   = 1;
                vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion,
                                     0, null, 0, null, 1, &imageMemoryBarrier);
            }

            imageMemoryBarrier.oldLayout     = VkImageLayout.Undefined;
            imageMemoryBarrier.newLayout     = VkImageLayout.ShaderReadOnlyOptimal;
            imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
            imageMemoryBarrier.dstAccessMask = VkAccessFlags.ShaderRead;
            imageMemoryBarrier.subresourceRange.baseMipLevel = mipLevels - 1;
            imageMemoryBarrier.subresourceRange.levelCount   = 1;
            vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion,
                                 0, null, 0, null, 1, &imageMemoryBarrier);

            Assert(vkEndCommandBuffer(cmdBuffer));

            VkSubmitInfo submitInfo = VkSubmitInfo.New();

            submitInfo.commandBufferCount = 1;
            submitInfo.pCommandBuffers    = &cmdBuffer;
            Assert(vkQueueSubmit(queue, 1, &submitInfo, VkFence.Null));
        }
示例#2
0
		///// <summary>
		///// build texture array
		///// </summary>
		///// <returns>The images.</returns>
		///// <param name="textureSize">Uniformized Texture size for all images</param>
		public void BuildTexArray (ref Image texArray, uint firstImg = 0) {
			int texDim = (int)texArray.CreateInfo.extent.width;

			PrimaryCommandBuffer cmd = cmdPool.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit);
			texArray.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal, 
						VkPipelineStageFlags.BottomOfPipe, VkPipelineStageFlags.Transfer);
			transferQ.EndSubmitAndWait (cmd, true);
			
			VkImageBlit imageBlit = new VkImageBlit {
				srcSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, 1, 0),
				dstOffsets_1 = new VkOffset3D (texDim, texDim, 1)
			};

			for (int l = 0; l < gltf.Images.Length; l++) {
				GL.Image img = gltf.Images[l];
				Image vkimg = null;

				if (img.BufferView != null) {//load image from gltf buffer view
					GL.BufferView bv = gltf.BufferViews[(int)img.BufferView];
					ensureBufferIsLoaded (bv.Buffer);
					vkimg = Image.Load (dev, loadedBuffers[bv.Buffer].Slice (bv.ByteOffset), (ulong)bv.ByteLength, VkImageUsageFlags.TransferSrc);
				} else if (img.Uri.StartsWith ("data:", StringComparison.Ordinal)) {//load base64 encoded image
					Debug.WriteLine ("loading embedded image {0} : {1}", img.Name, img.MimeType);
					vkimg = Image.Load (dev, glTFLoader.loadDataUri (img), VkImageUsageFlags.TransferSrc);
				} else {
					Debug.WriteLine ("loading image {0} : {1} : {2}", img.Name, img.MimeType, img.Uri);//load image from file path in uri
					vkimg = Image.Load (dev, Path.Combine (baseDirectory, img.Uri), VkImageUsageFlags.TransferSrc);
				}

				imageBlit.srcOffsets_1 = new VkOffset3D ((int)vkimg.CreateInfo.extent.width, (int)vkimg.CreateInfo.extent.height, 1);
				imageBlit.dstSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, 1, 0, (uint)l + firstImg);

				cmd = cmdPool.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit);

				vkimg.SetLayout (cmd, VkImageAspectFlags.Color,
						VkAccessFlags.HostWrite, VkAccessFlags.TransferRead,
						VkImageLayout.Undefined, VkImageLayout.TransferSrcOptimal,
						VkPipelineStageFlags.Host, VkPipelineStageFlags.Transfer);

				Vk.vkCmdBlitImage (cmd.Handle, vkimg.Handle, VkImageLayout.TransferSrcOptimal,
					texArray.Handle, VkImageLayout.TransferDstOptimal, 1, ref imageBlit, VkFilter.Linear);
				
				transferQ.EndSubmitAndWait (cmd, true);								

				vkimg.Dispose ();
			}

			cmd = cmdPool.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit);

			uint imgCount = (uint)gltf.Images.Length;
			VkImageSubresourceRange mipSubRange = new VkImageSubresourceRange (VkImageAspectFlags.Color, 0, 1, firstImg, imgCount);

			for (int i = 1; i < texArray.CreateInfo.mipLevels; i++) {
				imageBlit = new VkImageBlit {
					srcSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, imgCount, (uint)i - 1, firstImg),
					srcOffsets_1 = new VkOffset3D ((int)texDim >> (i - 1), (int)texDim >> (i - 1), 1),
					dstSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, imgCount, (uint)i, firstImg),
					dstOffsets_1 = new VkOffset3D ((int)texDim >> i, (int)texDim >> i, 1)
				};

				texArray.SetLayout (cmd,
					VkAccessFlags.TransferWrite, VkAccessFlags.TransferRead,
					VkImageLayout.TransferDstOptimal, VkImageLayout.TransferSrcOptimal, mipSubRange,
					VkPipelineStageFlags.Transfer, VkPipelineStageFlags.Transfer);

				Vk.vkCmdBlitImage (cmd.Handle, texArray.Handle, VkImageLayout.TransferSrcOptimal,
					texArray.Handle, VkImageLayout.TransferDstOptimal, 1, ref imageBlit, VkFilter.Linear);
				texArray.SetLayout (cmd, VkImageLayout.TransferSrcOptimal, VkImageLayout.ShaderReadOnlyOptimal, mipSubRange,
					VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader);

				mipSubRange.baseMipLevel = (uint)i;
			}
			mipSubRange.baseMipLevel = texArray.CreateInfo.mipLevels - 1;
			texArray.SetLayout (cmd, VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal, mipSubRange,
				VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader);

			cmd.End ();
			transferQ.Submit (cmd);
			transferQ.WaitIdle ();
			cmd.Free ();
		}
示例#3
0
        public unsafe void BlitImage(
            VkImage source,
            VkFormat sourceFormat,
            VkImageLayout sourceLayout,
            int sourceX, int sourceY,
            int sourceWidth, int sourceHeight,
            uint sourceMipLevel,
            VkImage destination,
            VkFormat destinationFormat,
            VkImageLayout destinationLayout,
            int destinationX, int destinationY,
            int destinationWidth, int destinationHeight,
            uint destinationMipLevel
            )
        {
            var regionInfo = new VkImageBlit
            {
                srcOffsets_0 = new VkOffset3D
                {
                    x = sourceX,
                    y = sourceY,
                    z = 0
                },
                srcOffsets_1 = new VkOffset3D
                {
                    x = sourceWidth,
                    y = sourceHeight,
                    z = 1
                },
                srcSubresource = new VkImageSubresourceLayers
                {
                    aspectMask = GetAspectFlags(
                        source,
                        sourceFormat,
                        sourceLayout
                        ),
                    mipLevel       = sourceMipLevel,
                    baseArrayLayer = 0,
                    layerCount     = 1
                },
                dstOffsets_0 = new VkOffset3D
                {
                    x = destinationX,
                    y = destinationY,
                    z = 0
                },
                dstOffsets_1 = new VkOffset3D
                {
                    x = destinationWidth,
                    y = destinationHeight,
                    z = 1
                },
                dstSubresource = new VkImageSubresourceLayers
                {
                    aspectMask = GetAspectFlags(
                        destination,
                        destinationFormat,
                        destinationLayout
                        ),
                    mipLevel       = destinationMipLevel,
                    baseArrayLayer = 0,
                    layerCount     = 1
                }
            };

            VulkanNative.vkCmdBlitImage(
                _handle,
                source,
                sourceLayout,
                destination,
                destinationLayout,
                1,
                &regionInfo,
                VkFilter.Linear
                );
        }