Ejemplo n.º 1
0
        Program() : base(false)
        {
            vbo     = new HostBuffer <Vertex> (dev, VkBufferUsageFlags.VertexBuffer, vertices);
            ibo     = new HostBuffer <ushort> (dev, VkBufferUsageFlags.IndexBuffer, indices);
            uboMats = new HostBuffer(dev, VkBufferUsageFlags.UniformBuffer, matrices);

            descriptorPool = new DescriptorPool(dev, 1, new VkDescriptorPoolSize(VkDescriptorType.UniformBuffer));
            dsLayout       = new DescriptorSetLayout(dev,
                                                     new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer));

            GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1);

            cfg.Layout     = new PipelineLayout(dev, dsLayout);
            cfg.RenderPass = new RenderPass(dev, swapChain.ColorFormat, dev.GetSuitableDepthFormat(), cfg.Samples);
            cfg.AddVertexBinding <Vertex> (0);
            cfg.AddVertexAttributes(0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat);

            cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/triangle.vert.spv");
            cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/triangle.frag.spv");

            pipeline = new GraphicPipeline(cfg);

            descriptorSet = descriptorPool.Allocate(dsLayout);
            DescriptorSetWrites uboUpdate = new DescriptorSetWrites(descriptorSet, dsLayout);

            uboUpdate.Write(dev, uboMats.Descriptor);

            uboMats.Map();
        }
Ejemplo n.º 2
0
        protected override void initVulkan()
        {
            base.initVulkan();

            cmds = cmdPool.AllocateCommandBuffer(swapChain.ImageCount);

            loadTexture(imgPathes[currentImgIndex]);

            vbo = new GPUBuffer <float> (presentQueue, cmdPool, VkBufferUsageFlags.VertexBuffer, vertices);
            ibo = new GPUBuffer <ushort> (presentQueue, cmdPool, VkBufferUsageFlags.IndexBuffer, indices);

            descriptorPool = new DescriptorPool(dev, 1,
                                                new VkDescriptorPoolSize(VkDescriptorType.UniformBuffer),
                                                new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler)
                                                );

            dsLayout = new DescriptorSetLayout(dev, 0,
                                               new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer),
                                               new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler));

            using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount4)) {
                cfg.Layout     = new PipelineLayout(dev, dsLayout);
                cfg.RenderPass = new RenderPass(dev, swapChain.ColorFormat, dev.GetSuitableDepthFormat(), cfg.Samples);

                cfg.AddVertexBinding(0, 5 * sizeof(float));
                cfg.AddVertexAttributes(0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32Sfloat);

                cfg.AddShader(dev, VkShaderStageFlags.Vertex, "#shaders.main.vert.spv");
                cfg.AddShader(dev, VkShaderStageFlags.Fragment, "#shaders.main.frag.spv");

                pipeline = new GraphicPipeline(cfg);
            }


            uboMats = new HostBuffer(dev, VkBufferUsageFlags.UniformBuffer, matrices);
            uboMats.Map();             //permanent map

            descriptorSet = descriptorPool.Allocate(dsLayout);

            updateTextureSet();

            DescriptorSetWrites uboUpdate = new DescriptorSetWrites(descriptorSet, dsLayout.Bindings[0]);

            uboUpdate.Write(dev, uboMats.Descriptor);
        }
Ejemplo n.º 3
0
        Vector4 outlineColor = new Vector4(1.0f, 0.0f, 0.0f, 0.6f);      //alpha => 0:disabled 1:enabled

        protected override void initVulkan()
        {
            base.initVulkan();

            cmds = cmdPool.AllocateCommandBuffer(swapChain.ImageCount);

            font = new BMFont(vke.samples.Utils.GetDataFile("font.fnt"));

            vbo = new GPUBuffer <float> (dev, VkBufferUsageFlags.VertexBuffer | VkBufferUsageFlags.TransferDst, 1024);
            ibo = new GPUBuffer <ushort> (dev, VkBufferUsageFlags.IndexBuffer | VkBufferUsageFlags.TransferDst, 2048);

            descriptorPool = new DescriptorPool(dev, 1,
                                                new VkDescriptorPoolSize(VkDescriptorType.UniformBuffer),
                                                new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler)
                                                );

            dsLayout = new DescriptorSetLayout(dev, 0,
                                               new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer),
                                               new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler));

            using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount4, false)) {
                cfg.Layout = new PipelineLayout(dev, dsLayout);
                cfg.Layout.AddPushConstants(new VkPushConstantRange(VkShaderStageFlags.Fragment, (uint)Marshal.SizeOf <Vector4> () * 2));

                cfg.RenderPass = new RenderPass(dev, swapChain.ColorFormat, cfg.Samples);

                cfg.blendAttachments[0] = new VkPipelineColorBlendAttachmentState(
                    true, VkBlendFactor.One, VkBlendFactor.OneMinusSrcAlpha, VkBlendOp.Add, VkBlendFactor.One, VkBlendFactor.Zero);

                cfg.AddVertexBinding(0, 5 * sizeof(float));
                cfg.AddVertexAttributes(0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32Sfloat);

                cfg.AddShader(dev, VkShaderStageFlags.Vertex, "#shaders.main.vert.spv");
                cfg.AddShader(dev, VkShaderStageFlags.Fragment, "#shaders.main.frag.spv");

                pipeline = new GraphicPipeline(cfg);
            }

            uboMats = new HostBuffer(dev, VkBufferUsageFlags.UniformBuffer, matrices);
            uboMats.Map();             //permanent map

            descriptorSet = descriptorPool.Allocate(dsLayout);

            fontTexture = font.GetPageTexture(0, presentQueue, cmdPool);
            fontTexture.CreateView();
            fontTexture.CreateSampler();
            fontTexture.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;

            DescriptorSetWrites dsUpdate = new DescriptorSetWrites(descriptorSet, dsLayout);

            dsUpdate.Write(dev, uboMats.Descriptor, fontTexture.Descriptor);

            generateText("Vulkan", out HostBuffer <Vertex> staggingVbo, out HostBuffer <ushort> staggingIbo);

            PrimaryCommandBuffer cmd = cmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);

            staggingVbo.CopyTo(cmd, vbo);
            staggingIbo.CopyTo(cmd, ibo);

            presentQueue.EndSubmitAndWait(cmd);

            staggingVbo.Dispose();
            staggingIbo.Dispose();

            UpdateFrequency = 10;
        }
Ejemplo n.º 4
0
		//TODO: some buffer data are reused between primitives, and I duplicate the datas
		//buffers must be constructed without duplications
		public Mesh[] LoadMeshes<TVertex> (VkIndexType indexType, Buffer vbo, ulong vboOffset, Buffer ibo, ulong iboOffset) {
			ulong vCount, iCount;
			VkIndexType idxType;

			GetVertexCount (out vCount, out iCount, out idxType);

			int vertexByteSize = Marshal.SizeOf<TVertex> ();
			ulong vertSize = vCount * (ulong)vertexByteSize;
			ulong idxSize = iCount * (indexType == VkIndexType.Uint16 ? 2ul : 4ul);
			ulong size = vertSize + idxSize;

			int vertexCount = 0, indexCount = 0;
			int autoNamedMesh = 1;

			meshes = new List<Mesh> ();

			using (HostBuffer stagging = new HostBuffer (dev, VkBufferUsageFlags.TransferSrc, size)) {
				stagging.Map ();

				unsafe {

					Span<byte> stagVertPtrInit = new Span<byte>(stagging.MappedData.ToPointer (), (int)vertSize);
					Span<byte> stagIdxPtrInit = new Span<byte>((byte*)stagging.MappedData.ToPointer() + vertSize, (int)idxSize);
					Span<byte> stagVertPtr = stagVertPtrInit, stagIdxPtr = stagIdxPtrInit;

					foreach (GL.Mesh mesh in gltf.Meshes) {

						string meshName = mesh.Name;
						if (string.IsNullOrEmpty (meshName)) {
							meshName = "mesh_" + autoNamedMesh.ToString ();
							autoNamedMesh++;
						}
						Mesh m = new Mesh { Name = meshName };

						foreach (GL.MeshPrimitive p in mesh.Primitives) {
							GL.Accessor AccPos = null, AccNorm = null, AccUv = null, AccUv1 = null;

							int accessorIdx;
							if (p.Attributes.TryGetValue ("POSITION", out accessorIdx)) {
								AccPos = gltf.Accessors[accessorIdx];
								ensureBufferIsLoaded (gltf.BufferViews[(int)AccPos.BufferView].Buffer);
							}
							if (p.Attributes.TryGetValue ("NORMAL", out accessorIdx)) {
								AccNorm = gltf.Accessors[accessorIdx];
								ensureBufferIsLoaded (gltf.BufferViews[(int)AccNorm.BufferView].Buffer);
							}
							if (p.Attributes.TryGetValue ("TEXCOORD_0", out accessorIdx)) {
								AccUv = gltf.Accessors[accessorIdx];
								ensureBufferIsLoaded (gltf.BufferViews[(int)AccUv.BufferView].Buffer);
							}
							if (p.Attributes.TryGetValue ("TEXCOORD_1", out accessorIdx)) {
								AccUv1 = gltf.Accessors[accessorIdx];
								ensureBufferIsLoaded (gltf.BufferViews[(int)AccUv1.BufferView].Buffer);
							}

							Primitive prim = new Primitive {
								indexBase = (uint)indexCount,
								vertexBase = vertexCount,
								vertexCount = (uint)AccPos.Count,
								material = (uint)(p.Material ?? 0)
							};

							prim.bb.min.ImportFloatArray (AccPos.Min);
							prim.bb.max.ImportFloatArray (AccPos.Max);
							prim.bb.isValid = true;

							//Interleaving vertices
							Span<byte> inPosPtr = Span<byte>.Empty, inNormPtr = Span<byte>.Empty, inUvPtr = Span<byte>.Empty, inUv1Ptr = Span<byte>.Empty;

							GL.BufferView bv = gltf.BufferViews[(int)AccPos.BufferView];
							inPosPtr = loadedBuffers[bv.Buffer].Span.Slice (AccPos.ByteOffset + bv.ByteOffset);

							if (AccNorm != null) {
								bv = gltf.BufferViews[(int)AccNorm.BufferView];
								inNormPtr = loadedBuffers[bv.Buffer].Span.Slice (AccNorm.ByteOffset + bv.ByteOffset);
							}
							if (AccUv != null) {
								bv = gltf.BufferViews[(int)AccUv.BufferView];
								inUvPtr = loadedBuffers[bv.Buffer].Span.Slice (AccUv.ByteOffset + bv.ByteOffset);
							}
							if (AccUv1 != null) {
								bv = gltf.BufferViews[(int)AccUv1.BufferView];
								inUv1Ptr = loadedBuffers[bv.Buffer].Span.Slice (AccUv1.ByteOffset + bv.ByteOffset);
							}

							//TODO: use vertex attributes scan for copying data if they exists
							for (int j = 0; j < prim.vertexCount; j++) {
								inPosPtr.Slice (0, 12).CopyTo (stagVertPtr);
								inPosPtr = inPosPtr.Slice(12);
								if (!inNormPtr.IsEmpty) {
									inNormPtr.Slice (0, 12).CopyTo (stagVertPtr.Slice (12));
									inNormPtr = inNormPtr.Slice (12);
								}
								if (inUvPtr != null) {
									inUvPtr.Slice (0, 8).CopyTo (stagVertPtr.Slice (24));
									inUvPtr = inUvPtr.Slice (8);
								}
								if (inUv1Ptr != null) {
									inUv1Ptr.Slice (0, 8).CopyTo (stagVertPtr.Slice (32));
									inUv1Ptr = inUvPtr.Slice (8);
								}
								stagVertPtr = stagVertPtr.Slice (vertexByteSize);
							}

							/*Span<byte> s = stagVertPtrInit;
							for (int i = 0; i < s.Length; i++)
								Console.Write (s[i].ToString ("X2") + (i % 32 == 0 ? "\n" : " "));*/


							//indices loading
							if (p.Indices != null) {
								GL.Accessor acc = gltf.Accessors[(int)p.Indices];
								bv = gltf.BufferViews[(int)acc.BufferView];

								Span<byte> inIdxPtr = loadedBuffers[bv.Buffer].Span.Slice (acc.ByteOffset + bv.ByteOffset);

								//TODO:double check this, I dont seems to increment stag pointer
								if (acc.ComponentType == GL.Accessor.ComponentTypeEnum.UNSIGNED_SHORT) {
									if (indexType == VkIndexType.Uint16) {
										inIdxPtr.Slice (0, acc.Count * 2).CopyTo (stagIdxPtr);
										stagIdxPtr = stagIdxPtr.Slice (acc.Count * 2);
									} else {

										Span<uint> usPtr = MemoryMarshal.Cast<byte, uint> (stagIdxPtr);
										Span<ushort> inPtr = MemoryMarshal.Cast < byte, ushort> (inIdxPtr);
										for (int i = 0; i < acc.Count; i++)
											usPtr[i] = inPtr[i];
										stagIdxPtr = stagIdxPtr.Slice (acc.Count * 4);
									}
								} else if (acc.ComponentType == GL.Accessor.ComponentTypeEnum.UNSIGNED_INT) {
									if (indexType == VkIndexType.Uint32) {
										inIdxPtr.Slice (0, acc.Count * 4).CopyTo (stagIdxPtr);
										stagIdxPtr = stagIdxPtr.Slice (acc.Count * 4);
									} else {
										Span<ushort> usPtr = MemoryMarshal.Cast<byte, ushort> (stagIdxPtr);
										Span<uint> inPtr = MemoryMarshal.Cast<byte, uint> (inIdxPtr);

										for (int i = 0; i < acc.Count; i++) 
											usPtr[i] = (ushort)inPtr[i];
										stagIdxPtr = stagIdxPtr.Slice (acc.Count * 2);
									}
								} else if (acc.ComponentType == GL.Accessor.ComponentTypeEnum.UNSIGNED_BYTE) {
									//convert
									if (indexType == VkIndexType.Uint16) {
										Span<ushort> usPtr = MemoryMarshal.Cast<byte, ushort> (stagIdxPtr);
										for (int i = 0; i < acc.Count; i++)
											usPtr[i] = (ushort)inIdxPtr[i];
										stagIdxPtr = stagIdxPtr.Slice (acc.Count * 2);
									} else {
										Span<uint> usPtr = MemoryMarshal.Cast<byte, uint> (stagIdxPtr);
										for (int i = 0; i < acc.Count; i++)
											usPtr[i] = (uint)inIdxPtr[i];
										stagIdxPtr = stagIdxPtr.Slice (acc.Count * 4);
									}
								} else
									throw new NotImplementedException ();

								prim.indexCount = (uint)acc.Count;
								indexCount += acc.Count;
							}

							m.AddPrimitive (prim);

							vertexCount += AccPos.Count;
						}
						meshes.Add (m);
					}

					/*ReadOnlySpan<byte> tmp = new ReadOnlySpan<byte> (stagging.MappedData.ToPointer (), (int)size);
					Memory<byte> mtmp = new Memory<byte> (tmp.ToArray());
					mtmp.Dump();*/
				}

				stagging.Unmap ();

				PrimaryCommandBuffer cmd = cmdPool.AllocateCommandBuffer ();
				cmd.Start (VkCommandBufferUsageFlags.OneTimeSubmit);

				stagging.CopyTo (cmd, vbo, vertSize, 0, vboOffset);
				if (iCount>0)
					stagging.CopyTo (cmd, ibo, idxSize, vertSize, iboOffset);

				cmd.End ();

				transferQ.Submit (cmd);

				dev.WaitIdle ();
				cmd.Free ();

			}

			return meshes.ToArray ();
		}
Ejemplo n.º 5
0
        void init()
        {
            renderPass = new RenderPass(dev);
            renderPass.AddAttachment(swapChain.ColorFormat, VkImageLayout.ColorAttachmentOptimal, VkSampleCountFlags.SampleCount1);
            renderPass.AddAttachment(dev.GetSuitableDepthFormat(), VkImageLayout.DepthStencilAttachmentOptimal, samples);
            renderPass.AddAttachment(VkFormat.R8g8b8a8Unorm, VkImageLayout.ColorAttachmentOptimal);
            renderPass.AddAttachment(VkFormat.R8g8b8a8Unorm, VkImageLayout.ColorAttachmentOptimal);
            renderPass.AddAttachment(VkFormat.R16g16b16a16Sfloat, VkImageLayout.ColorAttachmentOptimal);
            renderPass.AddAttachment(VkFormat.R16g16b16a16Sfloat, VkImageLayout.ColorAttachmentOptimal);

            renderPass.ClearValues.Add(new VkClearValue {
                color = new VkClearColorValue(0.0f, 0.0f, 0.0f)
            });
            renderPass.ClearValues.Add(new VkClearValue {
                depthStencil = new VkClearDepthStencilValue(1.0f, 0)
            });
            renderPass.ClearValues.Add(new VkClearValue {
                color = new VkClearColorValue(0.0f, 0.0f, 0.0f)
            });
            renderPass.ClearValues.Add(new VkClearValue {
                color = new VkClearColorValue(0.0f, 0.0f, 0.0f)
            });
            renderPass.ClearValues.Add(new VkClearValue {
                color = new VkClearColorValue(0.0f, 0.0f, 0.0f)
            });
            renderPass.ClearValues.Add(new VkClearValue {
                color = new VkClearColorValue(0.0f, 0.0f, 0.0f)
            });

            SubPass[] subpass = { new SubPass(), new SubPass() };
            subpass[0].AddColorReference(new VkAttachmentReference(2, VkImageLayout.ColorAttachmentOptimal),
                                         new VkAttachmentReference(3, VkImageLayout.ColorAttachmentOptimal),
                                         new VkAttachmentReference(4, VkImageLayout.ColorAttachmentOptimal),
                                         new VkAttachmentReference(5, VkImageLayout.ColorAttachmentOptimal));
            subpass[0].SetDepthReference(1, VkImageLayout.DepthStencilAttachmentOptimal);

            subpass[1].AddColorReference(0, VkImageLayout.ColorAttachmentOptimal);
            subpass[1].AddInputReference(new VkAttachmentReference(2, VkImageLayout.ShaderReadOnlyOptimal),
                                         new VkAttachmentReference(3, VkImageLayout.ShaderReadOnlyOptimal),
                                         new VkAttachmentReference(4, VkImageLayout.ShaderReadOnlyOptimal),
                                         new VkAttachmentReference(5, VkImageLayout.ShaderReadOnlyOptimal));
            renderPass.AddSubpass(subpass);

            renderPass.AddDependency(Vk.SubpassExternal, 0,
                                     VkPipelineStageFlags.BottomOfPipe, VkPipelineStageFlags.ColorAttachmentOutput,
                                     VkAccessFlags.MemoryRead, VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite);
            renderPass.AddDependency(0, 1,
                                     VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.FragmentShader,
                                     VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.ShaderRead);
            renderPass.AddDependency(1, Vk.SubpassExternal,
                                     VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.BottomOfPipe,
                                     VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.MemoryRead);


            descriptorPool = new DescriptorPool(dev, 3,
                                                new VkDescriptorPoolSize(VkDescriptorType.UniformBuffer, 2),
                                                new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler, 3),
                                                new VkDescriptorPoolSize(VkDescriptorType.InputAttachment, 4)
                                                );

            descLayoutMain = new DescriptorSetLayout(dev,
                                                     new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer),
                                                     new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                     new VkDescriptorSetLayoutBinding(2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                     new VkDescriptorSetLayoutBinding(3, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler));

            descLayoutModelTextures = new DescriptorSetLayout(dev,
                                                              new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                              new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                              new VkDescriptorSetLayoutBinding(2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                              new VkDescriptorSetLayoutBinding(3, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                              new VkDescriptorSetLayoutBinding(4, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)
                                                              );

            descLayoutGBuff = new DescriptorSetLayout(dev,
                                                      new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),
                                                      new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),
                                                      new VkDescriptorSetLayoutBinding(2, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),
                                                      new VkDescriptorSetLayoutBinding(3, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment));

            dsMain  = descriptorPool.Allocate(descLayoutMain);
            dsGBuff = descriptorPool.Allocate(descLayoutGBuff);

            GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, samples);

            cfg.Layout = new PipelineLayout(dev, descLayoutMain, descLayoutModelTextures, descLayoutGBuff);
            cfg.Layout.AddPushConstants(
                new VkPushConstantRange(VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf <Matrix4x4> ()),
                new VkPushConstantRange(VkShaderStageFlags.Fragment, sizeof(int), 64)
                );
            cfg.RenderPass = renderPass;
            cfg.blendAttachments.Add(new VkPipelineColorBlendAttachmentState(false));
            cfg.blendAttachments.Add(new VkPipelineColorBlendAttachmentState(false));
            cfg.blendAttachments.Add(new VkPipelineColorBlendAttachmentState(false));

            cfg.AddVertexBinding <Model.Vertex> (0);
            cfg.SetVertexAttributes(0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat, VkFormat.R32g32Sfloat);
            cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/pbrtest.vert.spv");
            cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/GBuffPbr.frag.spv");

            gBuffPipeline = new GraphicPipeline(cfg);
            cfg.blendAttachments.Clear();
            cfg.blendAttachments.Add(new VkPipelineColorBlendAttachmentState(false));
            cfg.ResetShadersAndVerticesInfos();
            cfg.SubpassIndex = 1;
            cfg.Layout       = gBuffPipeline.Layout;
            cfg.depthStencilState.depthTestEnable  = false;
            cfg.depthStencilState.depthWriteEnable = false;
            cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/FullScreenQuad.vert.spv");
            cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/pbrtest.frag.spv");
            composePipeline = new GraphicPipeline(cfg);

            envCube = new EnvironmentCube(presentQueue, renderPass);

            uboMats = new HostBuffer(dev, VkBufferUsageFlags.UniformBuffer, (ulong)Marshal.SizeOf <Matrices> () * 2);
            uboMats.Map();             //permanent map

            DescriptorSetWrites uboUpdate = new DescriptorSetWrites(descLayoutMain);

            uboUpdate.Write(dev, dsMain, uboMats.Descriptor,
                            envCube.lutBrdf.Descriptor,
                            envCube.irradianceCube.Descriptor,
                            envCube.prefilterCube.Descriptor);
            uboMats.Descriptor.offset = (ulong)Marshal.SizeOf <Matrices> ();
            envCube.WriteDesc(uboMats.Descriptor);
#if DEBUG
            debugDraw = new DebugDrawPipeline(dev, descLayoutMain, swapChain.ColorFormat);
            debugDraw.AddLine(Vector3.Zero, new Vector3(matrices.lightPos.X, matrices.lightPos.Y, matrices.lightPos.Z) * 3, 1, 1, 1);
            debugDraw.AddLine(Vector3.Zero, Vector3.UnitX, 1, 0, 0);
            debugDraw.AddLine(Vector3.Zero, Vector3.UnitY, 0, 1, 0);
            debugDraw.AddLine(Vector3.Zero, Vector3.UnitZ, 0, 0, 1);
#endif


            model = new Model(presentQueue, "../data/models/DamagedHelmet/glTF/DamagedHelmet.gltf");
            //model = new Model (presentQueue, "../data/models/chess.gltf");
            //model = new Model (presentQueue, "../data/models/Sponza/glTF/Sponza.gltf");
            //model = new Model (dev, presentQueue, "../data/models/icosphere.gltf");
            //model = new Model (dev, presentQueue, cmdPool, "../data/models/cube.gltf");
            model.WriteMaterialsDescriptorSets(descLayoutModelTextures,
                                               VK.AttachmentType.Color,
                                               VK.AttachmentType.Normal,
                                               VK.AttachmentType.AmbientOcclusion,
                                               VK.AttachmentType.PhysicalProps,
                                               VK.AttachmentType.Emissive);
        }
Ejemplo n.º 6
0
        void init(VkSampleCountFlags samples = VkSampleCountFlags.SampleCount4)
        {
            descriptorPool = new DescriptorPool(dev, 2,
                                                new VkDescriptorPoolSize(VkDescriptorType.UniformBuffer),
                                                new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler)
                                                );

            descLayoutMatrix = new DescriptorSetLayout(dev,
                                                       new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer),
                                                       new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)
                                                       );

            descLayoutTextures = new DescriptorSetLayout(dev,
                                                         new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                         new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                         new VkDescriptorSetLayoutBinding(2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                         new VkDescriptorSetLayoutBinding(3, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                         new VkDescriptorSetLayoutBinding(4, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)
                                                         );

            dsMats = descriptorPool.Allocate(descLayoutMatrix);

            GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, samples);

            cfg.Layout = new PipelineLayout(dev, descLayoutMatrix, descLayoutTextures);
            cfg.Layout.AddPushConstants(
                new VkPushConstantRange(VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf <Matrix4x4> ()),
                new VkPushConstantRange(VkShaderStageFlags.Fragment, (uint)Marshal.SizeOf <Model.PbrMaterial> (), 64)
                );
            cfg.RenderPass = new RenderPass(dev, swapChain.ColorFormat, dev.GetSuitableDepthFormat(), samples);

            cfg.AddVertexBinding <Model.Vertex> (0);
            cfg.SetVertexAttributes(0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat, VkFormat.R32g32Sfloat);

            cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/pbrtest.vert.spv");
            cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/pbrtest.frag.spv");

            pipeline = new GraphicPipeline(cfg);

            cfg.ResetShadersAndVerticesInfos();
            cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/FullScreenQuad.vert.spv");
            cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/simpletexture.frag.spv");

            cfg.blendAttachments[0] = new VkPipelineColorBlendAttachmentState(true);

            uiPipeline = new GraphicPipeline(cfg);

            uboMats = new HostBuffer(dev, VkBufferUsageFlags.UniformBuffer, (ulong)Marshal.SizeOf <Matrices>());
            uboMats.Map();             //permanent map

            DescriptorSetWrites uboUpdate = new DescriptorSetWrites(dsMats, descLayoutMatrix.Bindings[0]);

            uboUpdate.Write(dev, uboMats.Descriptor);

            cfg.Layout.SetName("Main Pipeline layout");
            uboMats.SetName("uboMats");
            descriptorPool.SetName("main pool");
            descLayoutTextures.SetName("descLayoutTextures");

            statPool = new PipelineStatisticsQueryPool(dev,
                                                       VkQueryPipelineStatisticFlags.InputAssemblyVertices |
                                                       VkQueryPipelineStatisticFlags.InputAssemblyPrimitives |
                                                       VkQueryPipelineStatisticFlags.ClippingInvocations |
                                                       VkQueryPipelineStatisticFlags.ClippingPrimitives |
                                                       VkQueryPipelineStatisticFlags.FragmentShaderInvocations);

            timestampQPool = new TimestampQueryPool(dev);
        }
Ejemplo n.º 7
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.Min(1, br.ReadUInt32());
                    UInt32 numberOfArrayElements = br.ReadUInt32();             //only for array text, else 0
                    UInt32 numberOfFaces         = br.ReadUInt32();             //only for cube map, else
                    UInt32 numberOfMipmapLevels  = Math.Min(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);
                        }
                    }

                    VkFormatFeatureFlags phyFormatSupport = (tiling == VkImageTiling.Linear) ?
                                                            staggingQ.Dev.phy.GetFormatProperties(vkFormat).linearTilingFeatures :
                                                            staggingQ.Dev.phy.GetFormatProperties(vkFormat).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 == 0) ? 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 (imgType != VkImageType.Image3D)
                    {
                        pixelDepth = 1;
                    }

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

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


                    if (memoryProperty.HasFlag(VkMemoryPropertyFlags.DeviceLocal))
                    {
                        ulong staggingSize = img.AllocatedDeviceMemorySize;


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

                            CommandBuffer cmd = staggingCmdPool.AllocateCommandBuffer();
                            cmd.Start(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.height;
                            uint  imgHeight    = img.CreateInfo.extent.width;

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

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

                                if (createFlags.HasFlag(VkImageCreateFlags.CubeCompatible))
                                {
                                    IntPtr ptrFace = img.MappedData;
                                    bufferCopyRegion.imageSubresource.layerCount = 1;
                                    for (uint face = 0; face < numberOfFaces; face++)
                                    {
                                        bufferCopyRegion.imageSubresource.baseArrayLayer = face;
                                        Marshal.Copy(br.ReadBytes((int)imgSize), 0, stagging.MappedData + (int)bufferOffset, (int)imgSize);
                                        buffCopies.Add(bufferCopyRegion);
                                        uint faceOffset = imgSize + (imgSize % 4);
                                        ptrFace      += (int)faceOffset;                                   //cube padding
                                        bufferOffset += faceOffset;
                                        bufferCopyRegion.bufferOffset = bufferOffset;
                                    }
                                }
                                else
                                {
                                    Marshal.Copy(br.ReadBytes((int)imgSize), 0, stagging.MappedData, (int)imgSize);
                                    buffCopies.Add(bufferCopyRegion);
                                }
                                bufferOffset += imgSize;
                                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.AllGraphics);
                            }

                            cmd.End();

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

                            cmd.Free();
                        }

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

                        /*VkImageBlit imageBlit = new VkImageBlit {
                         *      srcSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color, numberOfArrayElements, (uint)mips - 1),
                         *      srcOffsets_1 = new VkOffset3D((int)pixelWidth >> (mips - 1), (int)pixelHeight >> (mips - 1),1),
                         *      dstSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, numberOfArrayElements, (uint)mips),
                         *      dstOffsets_1 = new VkOffset3D ((int)pixelWidth >> mips, (int)pixelHeight >> mips, 1),
                         * };*/
                        //for (int layer = 0; layer < numberOfArrayElements; layer++) {
                        //for (int face = 0; face < numberOfFaces; face++) {
                        //for (int slice = 0; slice < pixelDepth; slice++) {

                        /*for (int y = 0; y < pixelHeight; y++) {
                         *      for (int x = 0; x < pixelWidth; x++) {
                         *              //Uncompressed texture data matches a GL_UNPACK_ALIGNMENT of 4.
                         *      }
                         * }*/
                        //}
                        //Byte cubePadding[0-3]
                        //}
                        //}
                        //Byte mipPadding[0-3]
                        //}
                    }
                }
            }

            return(img);
        }
Ejemplo n.º 8
0
        public Program() : base()
        {
            if (Instance.DEBUG_UTILS)
            {
                dbgReport = new DebugReport(instance,
                                            VkDebugReportFlagsEXT.ErrorEXT
                                            | VkDebugReportFlagsEXT.DebugEXT
                                            | VkDebugReportFlagsEXT.WarningEXT
                                            | VkDebugReportFlagsEXT.PerformanceWarningEXT

                                            );
            }
            imgResult = new Image(dev, VkFormat.R32g32b32a32Sfloat, VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled, VkMemoryPropertyFlags.DeviceLocal,
                                  imgDim, imgDim);
            imgResult.CreateView();
            imgResult.CreateSampler(VkFilter.Nearest, VkFilter.Nearest, VkSamplerMipmapMode.Nearest, VkSamplerAddressMode.ClampToBorder);
            imgResult.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;

            datas = new float[data_size];

            addSeed(imgDim / 2 - 1, imgDim / 2 - 1);


            stagingDataBuff = new HostBuffer <float> (dev, VkBufferUsageFlags.TransferSrc, datas);
            stagingDataBuff.Map();

            inBuff  = new GPUBuffer <float> (dev, VkBufferUsageFlags.StorageBuffer | VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst, (int)data_size);
            outBuff = new GPUBuffer <float> (dev, VkBufferUsageFlags.StorageBuffer | VkBufferUsageFlags.TransferSrc, (int)data_size);

            dsPool = new DescriptorPool(dev, 3,
                                        new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler),
                                        new VkDescriptorPoolSize(VkDescriptorType.StorageBuffer, 4));
            dslImage = new DescriptorSetLayout(dev,
                                               new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)
                                               );
            dslCompute = new DescriptorSetLayout(dev,
                                                 new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Compute, VkDescriptorType.StorageBuffer),
                                                 new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Compute, VkDescriptorType.StorageBuffer)
                                                 );

            GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1);

            cfg.Layout     = new PipelineLayout(dev, dslImage);
            cfg.RenderPass = new RenderPass(dev, swapChain.ColorFormat, dev.GetSuitableDepthFormat(), VkSampleCountFlags.SampleCount1);
            cfg.RenderPass.ClearValues[0] = new VkClearValue {
                color = new VkClearColorValue(0.0f, 0.1f, 0.0f)
            };

            cfg.ResetShadersAndVerticesInfos();
            cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/FullScreenQuad.vert.spv");
            cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/simpletexture.frag.spv");

            cfg.blendAttachments[0] = new VkPipelineColorBlendAttachmentState(true);

            grPipeline = new GraphicPipeline(cfg);

            plCompute = new ComputePipeline(
                new PipelineLayout(dev, new VkPushConstantRange(VkShaderStageFlags.Compute, 2 * sizeof(int)), dslCompute),
                "shaders/computeTest.comp.spv");
            plNormalize = new ComputePipeline(
                plCompute.Layout,
                "shaders/normalize.comp.spv");

            dsImage  = dsPool.Allocate(dslImage);
            dsetPing = dsPool.Allocate(dslCompute);
            dsetPong = dsPool.Allocate(dslCompute);

            DescriptorSetWrites dsUpdate = new DescriptorSetWrites(dsetPing, dslCompute);

            dsUpdate.Write(dev, inBuff.Descriptor, outBuff.Descriptor);
            dsUpdate.Write(dev, dsetPong, outBuff.Descriptor, inBuff.Descriptor);
            dsUpdate = new DescriptorSetWrites(dsImage, dslImage);
            dsUpdate.Write(dev, imgResult.Descriptor);

            UpdateFrequency = 5;
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
0
        public Program() : base()
        {
#if DEBUG
            dbgReport = new DebugReport(instance,
                                        VkDebugReportFlagsEXT.ErrorEXT
                                        | VkDebugReportFlagsEXT.DebugEXT
                                        | VkDebugReportFlagsEXT.WarningEXT
                                        | VkDebugReportFlagsEXT.PerformanceWarningEXT

                                        );
#endif
            imgResult = new Image(dev, VkFormat.R32g32b32a32Sfloat, VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled, VkMemoryPropertyFlags.DeviceLocal,
                                  IMG_DIM, IMG_DIM);
            imgResult.CreateView();
            imgResult.CreateSampler(VkFilter.Nearest, VkFilter.Nearest, VkSamplerMipmapMode.Nearest, VkSamplerAddressMode.ClampToBorder);
            imgResult.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;


            staggingVBO = new HostBuffer <Vector2> (dev, VkBufferUsageFlags.TransferSrc, MAX_VERTICES);
            staggingVBO.Map();

            vbo = new GPUBuffer <Vector2> (dev, VkBufferUsageFlags.VertexBuffer | VkBufferUsageFlags.StorageBuffer | VkBufferUsageFlags.TransferDst, MAX_VERTICES);
            ibo = new GPUBuffer <uint> (dev, VkBufferUsageFlags.IndexBuffer | VkBufferUsageFlags.StorageBuffer, MAX_VERTICES * 3);

            inBuff  = new GPUBuffer <float> (dev, VkBufferUsageFlags.StorageBuffer | VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst, (int)data_size);
            outBuff = new GPUBuffer <float> (dev, VkBufferUsageFlags.StorageBuffer | VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst, (int)data_size);

            dsPool = new DescriptorPool(dev, 4,
                                        new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler),
                                        new VkDescriptorPoolSize(VkDescriptorType.StorageBuffer, 6));
            dslImage = new DescriptorSetLayout(dev,
                                               new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)
                                               );
            dslCompute = new DescriptorSetLayout(dev,
                                                 new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Compute, VkDescriptorType.StorageBuffer),
                                                 new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Compute, VkDescriptorType.StorageBuffer)
                                                 );
            dslVAO = new DescriptorSetLayout(dev,
                                             new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Compute, VkDescriptorType.StorageBuffer),
                                             new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Compute, VkDescriptorType.StorageBuffer)
                                             );

            plInit = new ComputePipeline(
                new PipelineLayout(dev, new VkPushConstantRange(VkShaderStageFlags.Compute, 3 * sizeof(int)), dslCompute, dslVAO),
                "shaders/init.comp.spv");
            plCompute   = new ComputePipeline(plInit.Layout, "shaders/computeTest.comp.spv");
            plNormalize = new ComputePipeline(plInit.Layout, "shaders/normalize.comp.spv");

            GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1);

            cfg.Layout     = new PipelineLayout(dev, dslImage);
            cfg.RenderPass = new RenderPass(dev, swapChain.ColorFormat, dev.GetSuitableDepthFormat(), VkSampleCountFlags.SampleCount1);
            cfg.RenderPass.ClearValues[0] = new VkClearValue {
                color = new VkClearColorValue(0.1f, 0.1f, 0.1f)
            };
            cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/FullScreenQuad.vert.spv");
            cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/simpletexture.frag.spv");

            cfg.blendAttachments[0] = new VkPipelineColorBlendAttachmentState(true);

            grPipeline = new GraphicPipeline(cfg);

            cfg.ResetShadersAndVerticesInfos();
            cfg.Layout = new PipelineLayout(dev, new VkPushConstantRange(VkShaderStageFlags.Vertex, 4 * sizeof(int)));
            cfg.inputAssemblyState.topology = VkPrimitiveTopology.LineStrip;
            cfg.AddVertexBinding <Vector2> (0);
            cfg.SetVertexAttributes(0, VkFormat.R32g32Sfloat);
            cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/triangle.vert.spv");
            cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/triangle.frag.spv");

            trianglesPipeline = new GraphicPipeline(cfg);

            dsImage = dsPool.Allocate(dslImage);
            dsPing  = dsPool.Allocate(dslCompute);
            dsPong  = dsPool.Allocate(dslCompute);
            dsVAO   = dsPool.Allocate(dslCompute);


            DescriptorSetWrites dsUpdate = new DescriptorSetWrites(dsPing, dslCompute);
            dsUpdate.Write(dev, inBuff.Descriptor, outBuff.Descriptor);
            dsUpdate.Write(dev, dsPong, outBuff.Descriptor, inBuff.Descriptor);
            dsUpdate = new DescriptorSetWrites(dsImage, dslImage);
            dsUpdate.Write(dev, imgResult.Descriptor);
            dsUpdate = new DescriptorSetWrites(dsVAO, dslVAO);
            dsUpdate.Write(dev, vbo.Descriptor, ibo.Descriptor);

            UpdateFrequency = 5;

            addPoint(IMG_DIM / 2 - 1, IMG_DIM / 2 - 1);
        }