Пример #1
0
        void initGpuBuffers()
        {
            using (CommandPool staggingCmdPool = new CommandPool(dev, transferQ.qFamIndex)) {
                CommandBuffer cmd = staggingCmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);

                stagingDataBuff.CopyTo(cmd, inBuff);

                transferQ.EndSubmitAndWait(cmd);
            }
        }
Пример #2
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);
            }
        }
Пример #3
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 ();
		}