Esempio n. 1
0
        void printResults()
        {
            dev.WaitIdle();
            using (CommandPool cmdPoolTransfer = new CommandPool(dev, transferQ.qFamIndex)) {
                CommandBuffer cmd = cmdPoolTransfer.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);

                imgResult.SetLayout(cmd, VkImageAspectFlags.Color,
                                    VkImageLayout.ShaderReadOnlyOptimal, VkImageLayout.TransferDstOptimal,
                                    VkPipelineStageFlags.FragmentShader, VkPipelineStageFlags.Transfer);

                if (pong)
                {
                    outBuff.CopyTo(cmd, imgResult, VkImageLayout.ShaderReadOnlyOptimal);
                }
                else
                {
                    inBuff.CopyTo(cmd, imgResult, VkImageLayout.ShaderReadOnlyOptimal);
                }

                cmd.End();

                transferQ.Submit(cmd);
                transferQ.WaitIdle();
            }
        }
Esempio n. 2
0
        public void Run()
        {
            using (CommandPool cmdPool = new CommandPool(dev, computeQ.qFamIndex)) {
                CommandBuffer cmd = cmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);

                bool pong = false;

                plCompute.Bind(cmd);
                cmd.PushConstant(plCompute.Layout, VkShaderStageFlags.Compute, imgDim);

                for (int i = 0; i < 4; i++)
                {
                    if (pong)
                    {
                        plCompute.BindDescriptorSet(cmd, dsetPong);
                    }
                    else
                    {
                        plCompute.BindDescriptorSet(cmd, dsetPing);
                    }

                    cmd.Dispatch(imgDim, imgDim);
                }

                cmd.End();

                computeQ.Submit(cmd);
                computeQ.WaitIdle();
            }
        }
Esempio n. 3
0
        public void update_shadow_map(CommandPool cmdPool)
        {
            update_light_matrices();

            CommandBuffer cmd = cmdPool.AllocateAndStart();

            shadowPass.Begin(cmd, fbShadowMap);

            cmd.SetViewport(SHADOWMAP_SIZE, SHADOWMAP_SIZE);
            cmd.SetScissor(SHADOWMAP_SIZE, SHADOWMAP_SIZE);

            cmd.BindDescriptorSet(shadowPipeline.Layout, dsShadow);

            Vk.vkCmdSetDepthBias(cmd.Handle, depthBiasConstant, 0.0f, depthBiasSlope);

            shadowPipeline.Bind(cmd);

            if (renderer.model != null)
            {
                renderer.model.Bind(cmd);
                renderer.model.DrawAll(cmd, shadowPipeline.Layout, true);
            }

            shadowPass.End(cmd);

            renderer.presentQueue.EndSubmitAndWait(cmd);
            updateShadowMap = false;
        }
Esempio n. 4
0
        public override void Update()
        {
            initGpuBuffers();

            using (CommandPool cmdPoolCompute = new CommandPool(dev, computeQ.qFamIndex)) {
                CommandBuffer cmd = cmdPoolCompute.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);

                pong = false;
                uint stepSize = imgDim / 2;

                plCompute.Bind(cmd);
                cmd.PushConstant(plCompute.Layout, VkShaderStageFlags.Compute, imgDim, sizeof(int));

                int pass = 0;
                while (stepSize > 0 && pass < invocationCount)
                {
                    cmd.PushConstant(plCompute.Layout, VkShaderStageFlags.Compute, stepSize);

                    if (pong)
                    {
                        plCompute.BindDescriptorSet(cmd, dsetPong);
                    }
                    else
                    {
                        plCompute.BindDescriptorSet(cmd, dsetPing);
                    }

                    cmd.Dispatch(imgDim, imgDim);

                    VkMemoryBarrier memBar = VkMemoryBarrier.New();
                    memBar.srcAccessMask = VkAccessFlags.ShaderWrite;
                    memBar.dstAccessMask = VkAccessFlags.ShaderRead;
                    Vk.vkCmdPipelineBarrier(cmd.Handle, VkPipelineStageFlags.ComputeShader, VkPipelineStageFlags.ComputeShader, VkDependencyFlags.ByRegion,
                                            1, ref memBar, 0, IntPtr.Zero, 0, IntPtr.Zero);

                    pong      = !pong;
                    stepSize /= 2;
                    pass++;
                }

                plNormalize.Bind(cmd);
                if (pong)
                {
                    plNormalize.BindDescriptorSet(cmd, dsetPong);
                }
                else
                {
                    plNormalize.BindDescriptorSet(cmd, dsetPing);
                }
                cmd.Dispatch(imgDim, imgDim);
                pong = !pong;

                cmd.End();

                computeQ.Submit(cmd);
                computeQ.WaitIdle();
            }

            printResults();
        }
Esempio n. 5
0
        void initGpuBuffers()
        {
            using (CommandPool staggingCmdPool = new CommandPool(dev, transferQ.qFamIndex)) {
                CommandBuffer cmd = staggingCmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);

                stagingDataBuff.CopyTo(cmd, inBuff);

                transferQ.EndSubmitAndWait(cmd);
            }
        }
Esempio n. 6
0
        public void Run()
        {
            using (CommandPool cmdPool = new CommandPool(dev, computeQ.qFamIndex)) {
                PrimaryCommandBuffer cmd = cmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);
                plCompute.Bind(cmd);
                plCompute.BindDescriptorSet(cmd, dset);
                cmd.Dispatch(data_size * sizeof(int));
                cmd.End();

                computeQ.Submit(cmd);
                computeQ.WaitIdle();
            }

            printResults();
        }
Esempio n. 7
0
        void initGpuBuffers()
        {
            using (CommandPool staggingCmdPool = new CommandPool(dev, transferQ.qFamIndex)) {
                CommandBuffer cmd = staggingCmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);

                if (clear)
                {
                    if (pong)
                    {
                        inBuff.Fill(cmd, 0);
                    }
                    else
                    {
                        outBuff.Fill(cmd, 0);
                    }
                }

                staggingVBO.CopyTo(cmd, vbo, pointCount * (ulong)Marshal.SizeOf <Vector2>());

                transferQ.EndSubmitAndWait(cmd);
            }
        }
Esempio n. 8
0
        public PbrModelTexArray(Queue transferQ, string path)
        {
            dev = transferQ.Dev;
            using (CommandPool cmdPool = new CommandPool(dev, transferQ.index)) {
                using (glTFLoader ctx = new glTFLoader(path, transferQ, cmdPool)) {
                    loadSolids <Vertex> (ctx);

                    if (ctx.ImageCount > 0)
                    {
                        texArray = new Image(dev, Image.DefaultTextureFormat, VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferDst | VkImageUsageFlags.TransferSrc,
                                             VkMemoryPropertyFlags.DeviceLocal, TEXTURE_DIM, TEXTURE_DIM, VkImageType.Image2D,
                                             VkSampleCountFlags.SampleCount1, VkImageTiling.Optimal, Image.ComputeMipLevels(TEXTURE_DIM), ctx.ImageCount);

                        ctx.BuildTexArray(ref texArray, 0);
                    }
                    else
                    {
                        texArray = new Image(dev, Image.DefaultTextureFormat, VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferDst | VkImageUsageFlags.TransferSrc,
                                             VkMemoryPropertyFlags.DeviceLocal, TEXTURE_DIM, TEXTURE_DIM, VkImageType.Image2D,
                                             VkSampleCountFlags.SampleCount1, VkImageTiling.Optimal, Image.ComputeMipLevels(TEXTURE_DIM), 1);
                        PrimaryCommandBuffer cmd = cmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);
                        texArray.SetLayout(cmd, VkImageAspectFlags.Color, VkImageLayout.ShaderReadOnlyOptimal);
                        transferQ.EndSubmitAndWait(cmd, true);
                    }

                    texArray.CreateView(VkImageViewType.ImageView2DArray, VkImageAspectFlags.Color, texArray.CreateInfo.arrayLayers);
                    texArray.CreateSampler();
                    texArray.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
                    texArray.SetName("model texArray");


                    loadMaterials(ctx);
                    materialUBO = new HostBuffer <Material> (dev, VkBufferUsageFlags.UniformBuffer, materials);
                }
            }
        }
Esempio n. 9
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 ();
		}
Esempio n. 10
0
        public static Image Load(Queue staggingQ, CommandPool staggingCmdPool, string ktxPath, VkImageUsageFlags usage = VkImageUsageFlags.Sampled,
                                 VkMemoryPropertyFlags memoryProperty = VkMemoryPropertyFlags.DeviceLocal, bool generateMipmaps = true,
                                 VkImageTiling tiling = VkImageTiling.Optimal)
        {
            Image img = null;

            using (Stream ktxStream = File.Open(ktxPath, FileMode.Open, FileAccess.Read)) {
                using (BinaryReader br = new BinaryReader(ktxStream)) {
                    if (!br.ReadBytes(12).AreEquals(ktxSignature))
                    {
                        throw new KtxException("Not a ktx file: " + ktxPath);
                    }

                    UInt32 endianness            = br.ReadUInt32();
                    UInt32 glType                = br.ReadUInt32();
                    UInt32 glTypeSize            = br.ReadUInt32();
                    UInt32 glFormat              = br.ReadUInt32();
                    UInt32 glInternalFormat      = br.ReadUInt32();
                    UInt32 glBaseInternalFormat  = br.ReadUInt32();
                    UInt32 pixelWidth            = br.ReadUInt32();
                    UInt32 pixelHeight           = br.ReadUInt32();
                    UInt32 pixelDepth            = Math.Max(1, br.ReadUInt32());
                    UInt32 numberOfArrayElements = br.ReadUInt32();             //only for array text, else 0
                    UInt32 numberOfFaces         = br.ReadUInt32();             //only for cube map, else 1
                    UInt32 numberOfMipmapLevels  = Math.Max(1, br.ReadUInt32());
                    UInt32 bytesOfKeyValueData   = br.ReadUInt32();

                    VkFormat vkFormat = GLHelper.vkGetFormatFromOpenGLInternalFormat(glInternalFormat);
                    if (vkFormat == VkFormat.Undefined)
                    {
                        vkFormat = GLHelper.vkGetFormatFromOpenGLFormat(glFormat, glType);
                        if (vkFormat == VkFormat.Undefined)
                        {
                            throw new KtxException("Undefined format: " + ktxPath);
                        }
                    }
                    VkFormatProperties   formatProperties = staggingQ.Dev.phy.GetFormatProperties(vkFormat);
                    VkFormatFeatureFlags phyFormatSupport = (tiling == VkImageTiling.Linear) ?
                                                            formatProperties.linearTilingFeatures :
                                                            formatProperties.optimalTilingFeatures;

                    uint requestedMipsLevels = numberOfMipmapLevels;
                    if (numberOfMipmapLevels == 1)
                    {
                        requestedMipsLevels = (generateMipmaps && phyFormatSupport.HasFlag(VkFormatFeatureFlags.BlitSrc | VkFormatFeatureFlags.BlitDst)) ?
                                              (uint)Math.Floor(Math.Log(Math.Max(pixelWidth, pixelHeight))) + 1 : 1;
                    }

                    if (tiling == VkImageTiling.Optimal)
                    {
                        usage |= VkImageUsageFlags.TransferDst;
                    }
                    if (generateMipmaps)
                    {
                        usage |= (VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst);
                    }

                    VkImageCreateFlags createFlags = 0;

                    VkImageType imgType =
                        (pixelWidth == 0) ? throw new KtxException("pixelWidth must be > 0") :
                              (pixelHeight == 0) ? imgType = VkImageType.Image1D :
                                                             (pixelDepth == 1) ? imgType = VkImageType.Image2D : imgType = VkImageType.Image3D;


                    VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1;

                    if (numberOfFaces > 1)
                    {
                        if (imgType != VkImageType.Image2D)
                        {
                            throw new KtxException("cubemap faces must be 2D textures");
                        }
                        createFlags           = VkImageCreateFlags.CubeCompatible;
                        samples               = VkSampleCountFlags.SampleCount1;
                        numberOfArrayElements = numberOfFaces;
                    }
                    else
                    {
                        numberOfFaces = 1;
                        if (numberOfArrayElements == 0)
                        {
                            numberOfArrayElements = 1;
                        }
                    }

                    if (!Image.CheckFormatIsSupported(usage, phyFormatSupport))
                    {
                        throw new Exception($"Unsupported image format: {vkFormat}, {tiling}, {usage}");
                    }

                    img = new Image(staggingQ.Dev, vkFormat, usage, memoryProperty, pixelWidth, pixelHeight, imgType, samples,
                                    tiling, requestedMipsLevels, numberOfArrayElements, pixelDepth, createFlags);

                    byte[] keyValueDatas = br.ReadBytes((int)bytesOfKeyValueData);

                    uint blockW, blockH;
                    bool isCompressed = vkFormat.TryGetCompressedFormatBlockSize(out blockW, out blockH);
                    uint blockSize    = blockW * blockH;

                    if (memoryProperty.HasFlag(VkMemoryPropertyFlags.DeviceLocal))
                    {
                        ulong staggingSize = img.AllocatedDeviceMemorySize;
                        Console.WriteLine($"KtxStream size = {ktxStream.Length}, img Allocation = {img.AllocatedDeviceMemorySize}");

                        using (HostBuffer stagging = new HostBuffer(staggingQ.Dev, VkBufferUsageFlags.TransferSrc, staggingSize)) {
                            stagging.Map();

                            PrimaryCommandBuffer cmd = staggingCmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);
                            img.SetLayout(cmd, VkImageAspectFlags.Color,
                                          VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal,
                                          VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.Transfer);

                            List <VkBufferImageCopy> buffCopies = new List <VkBufferImageCopy> ();

                            VkBufferImageCopy bufferCopyRegion = new VkBufferImageCopy {
                                imageExtent      = img.CreateInfo.extent,
                                imageSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color, img.CreateInfo.arrayLayers, 0)
                            };

                            ulong bufferOffset = 0;
                            uint  imgWidth     = img.CreateInfo.extent.width;
                            uint  imgHeight    = img.CreateInfo.extent.height;

                            for (int mips = 0; mips < numberOfMipmapLevels; mips++)
                            {
                                UInt32 imgSize = br.ReadUInt32();

                                bufferCopyRegion.bufferRowLength   = imgWidth;
                                bufferCopyRegion.bufferImageHeight = imgHeight;

                                if (isCompressed && (imgWidth % blockW > 0 || imgHeight % blockH > 0))
                                {
                                    bufferCopyRegion.bufferRowLength   += blockW - imgWidth % blockW;
                                    bufferCopyRegion.bufferImageHeight += blockH - imgHeight % blockH;
                                }
                                bufferCopyRegion.bufferOffset = bufferOffset;
                                bufferCopyRegion.imageSubresource.mipLevel = (uint)mips;
                                bufferCopyRegion.imageExtent.width         = imgWidth;
                                bufferCopyRegion.imageExtent.height        = imgHeight;

                                if (createFlags.HasFlag(VkImageCreateFlags.CubeCompatible))
                                {
                                    //TODO:handle compressed formats
                                    for (uint face = 0; face < numberOfFaces; face++)
                                    {
                                        Marshal.Copy(br.ReadBytes((int)imgSize), 0, stagging.MappedData + (int)bufferOffset, (int)imgSize);
                                        uint faceOffset = imgSize + (imgSize % 4);                                        //cube padding
                                        bufferOffset += faceOffset;
                                    }
                                    buffCopies.Add(bufferCopyRegion);
                                    bufferCopyRegion.bufferOffset = bufferOffset;
                                }
                                else if (isCompressed && (imgWidth % blockW > 0 || imgHeight % blockH > 0))
                                {
                                    for (int line = 0; line < imgHeight; line++)
                                    {
                                        Marshal.Copy(br.ReadBytes((int)imgWidth), 0, stagging.MappedData + (int)bufferOffset, (int)imgWidth);
                                        bufferOffset += bufferCopyRegion.bufferRowLength;
                                    }
                                    buffCopies.Add(bufferCopyRegion);
                                }
                                else
                                {
                                    Marshal.Copy(br.ReadBytes((int)imgSize), 0, stagging.MappedData + (int)bufferOffset, (int)imgSize);
                                    buffCopies.Add(bufferCopyRegion);
                                    bufferOffset += imgSize;
                                }

                                if (isCompressed && bufferOffset % blockSize > 0)
                                {
                                    bufferOffset += blockSize - bufferOffset % blockSize;
                                }

                                imgWidth  /= 2;
                                imgHeight /= 2;
                            }
                            stagging.Unmap();

                            Vk.vkCmdCopyBufferToImage(cmd.Handle, stagging.handle, img.handle, VkImageLayout.TransferDstOptimal,
                                                      (uint)buffCopies.Count, buffCopies.Pin());
                            buffCopies.Unpin();

                            if (requestedMipsLevels > numberOfMipmapLevels)
                            {
                                img.BuildMipmaps(cmd);
                            }
                            else
                            {
                                img.SetLayout(cmd, VkImageAspectFlags.Color,
                                              VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal,
                                              VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader);
                            }

                            cmd.End();

                            staggingQ.Submit(cmd);
                            staggingQ.WaitIdle();

                            cmd.Free();
                        }
                    }
                    else
                    {
                    }
                }
            }

            return(img);
        }