public PbrModelSeparatedTextures(Queue transferQ, string path, DescriptorSetLayout layout, params AttachmentType[] attachments)
        {
            dev = transferQ.Dev;
            using (CommandPool cmdPool = new CommandPool(dev, transferQ.index)) {
                using (glTFLoader ctx = new glTFLoader(path, transferQ, cmdPool)) {
                    ulong vertexCount, indexCount;

                    ctx.GetVertexCount(out vertexCount, out indexCount, out IndexBufferType);
                    ulong vertSize = vertexCount * (ulong)Marshal.SizeOf <Vertex> ();
                    ulong idxSize  = indexCount * (IndexBufferType == VkIndexType.Uint16 ? 2ul : 4ul);
                    ulong size     = vertSize + idxSize;

                    vbo = new GPUBuffer(dev, VkBufferUsageFlags.VertexBuffer | VkBufferUsageFlags.TransferDst, vertSize);
                    ibo = new GPUBuffer(dev, VkBufferUsageFlags.IndexBuffer | VkBufferUsageFlags.TransferDst, idxSize);

                    vbo.SetName("vbo gltf");
                    ibo.SetName("ibo gltf");

                    Meshes = new List <Mesh> (ctx.LoadMeshes <Vertex> (IndexBufferType, vbo, 0, ibo, 0));

                    textures = ctx.LoadImages();

                    loadMaterials(ctx, layout, attachments);

                    materialUBO = new HostBuffer <Material> (dev, VkBufferUsageFlags.UniformBuffer, materials);

                    Scenes = new List <Scene> (ctx.LoadScenes(out defaultSceneIndex));
                }
            }
        }
Example #2
0
        public DebugDrawPipeline(Device dev, DescriptorSetLayout dsLayout, VkFormat colorFormat, VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1) :
            base(new RenderPass(dev, colorFormat), "Debug draw pipeline")
        {
            GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.LineList, samples);

            cfg.rasterizationState.lineWidth = 1.0f;
            cfg.RenderPass = RenderPass;
            cfg.Layout     = new PipelineLayout(dev, dsLayout);
            cfg.Layout.AddPushConstants(
                new VkPushConstantRange(VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf <Matrix4x4> () * 2)
                );
            cfg.AddVertexBinding(0, 6 * sizeof(float));
            cfg.SetVertexAttributes(0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat);

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

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

            layout = cfg.Layout;

            init(cfg);

            Vertices = new HostBuffer(dev, VkBufferUsageFlags.VertexBuffer, vboLength);
            Vertices.Map();
        }
Example #3
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)) {
                    ulong vertexCount, indexCount;

                    ctx.GetVertexCount(out vertexCount, out indexCount, out IndexBufferType);
                    ulong vertSize = vertexCount * (ulong)Marshal.SizeOf <Vertex> ();
                    ulong idxSize  = indexCount * (IndexBufferType == VkIndexType.Uint16 ? 2ul : 4ul);
                    ulong size     = vertSize + idxSize;

                    vbo = new GPUBuffer(dev, VkBufferUsageFlags.VertexBuffer | VkBufferUsageFlags.TransferDst, vertSize);
                    ibo = new GPUBuffer(dev, VkBufferUsageFlags.IndexBuffer | VkBufferUsageFlags.TransferDst, idxSize);

                    vbo.SetName("vbo gltf");
                    ibo.SetName("ibo gltf");

                    Meshes = new List <Mesh> (ctx.LoadMeshes <Vertex> (IndexBufferType, vbo, 0, ibo, 0));

                    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);

                        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);

                    Scenes = new List <Scene> (ctx.LoadScenes(out defaultSceneIndex));
                }
            }
        }
Example #4
0
        /// <summary>
        /// load bitmap from pointer
        /// </summary>
        void load(Queue staggingQ, CommandPool staggingCmdPool, IntPtr bitmap, bool generateMipmaps = true)
        {
            long size = info.extent.width * info.extent.height * 4 * info.extent.depth;

            if (MemoryFlags.HasFlag(VkMemoryPropertyFlags.HostVisible))
            {
                Map();
                unsafe {
                    System.Buffer.MemoryCopy(bitmap.ToPointer(), MappedData.ToPointer(), size, size);
                }
                Unmap();

                if (generateMipmaps)
                {
                    BuildMipmaps(staggingQ, staggingCmdPool);
                }
            }
            else
            {
                using (HostBuffer stagging = new HostBuffer(Dev, VkBufferUsageFlags.TransferSrc, (UInt64)size, bitmap)) {
                    CommandBuffer cmd = staggingCmdPool.AllocateCommandBuffer();

                    cmd.Start(VkCommandBufferUsageFlags.OneTimeSubmit);

                    stagging.CopyTo(cmd, this);
                    if (generateMipmaps)
                    {
                        BuildMipmaps(cmd);
                    }

                    cmd.End();
                    staggingQ.Submit(cmd);
                    staggingQ.WaitIdle();
                    cmd.Free();
                }
            }
        }
Example #5
0
        public PBRPipeline(Queue staggingQ, RenderPass renderPass, Image uiImage, PipelineCache pipelineCache = null) :
            base(renderPass, pipelineCache, "pbr pipeline")
        {
            descriptorPool = new DescriptorPool(Dev, 2,
                                                new VkDescriptorPoolSize(VkDescriptorType.UniformBuffer, 2),
                                                new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler, 9)
                                                );

            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),
                                                     new VkDescriptorSetLayoutBinding(4, VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer),
                                                     new VkDescriptorSetLayoutBinding(5, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler));//ui image

            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)
                                                         );

            GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, renderPass.Samples);

            cfg.Layout = new PipelineLayout(Dev, descLayoutMain, descLayoutTextures);
            cfg.Layout.AddPushConstants(
                new VkPushConstantRange(VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf <Matrix4x4> ()),
                new VkPushConstantRange(VkShaderStageFlags.Fragment, sizeof(int), 64)
                );
            cfg.RenderPass = renderPass;
            cfg.AddVertexBinding <PbrModel2.Vertex> (0);
            cfg.AddVertexAttributes(0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat, VkFormat.R32g32Sfloat, VkFormat.R32g32Sfloat);

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

            layout = cfg.Layout;

            init(cfg);

            dsMain = descriptorPool.Allocate(descLayoutMain);

            envCube = new EnvironmentCube(dsMain, layout, staggingQ, RenderPass);

            matrices.prefilteredCubeMipLevels = envCube.prefilterCube.CreateInfo.mipLevels;
            uboMats = new HostBuffer(Dev, VkBufferUsageFlags.UniformBuffer, matrices, true);

            string[] modelPathes =
            {
                "data/models/DamagedHelmet/glTF/DamagedHelmet.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Avocado/glTF/Avocado.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/BarramundiFish/glTF/BarramundiFish.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/BoomBoxWithAxes/glTF/BoomBoxWithAxes.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Box/glTF/Box.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/EnvironmentTest/glTF/EnvironmentTest.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/MetalRoughSpheres/glTF/MetalRoughSpheres.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/OrientationTest/glTF/OrientationTest.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Buggy/glTF/Buggy.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/2CylinderEngine/glTF-Embedded/2CylinderEngine.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/FlightHelmet/glTF/FlightHelmet.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/GearboxAssy/glTF/GearboxAssy.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Lantern/glTF/Lantern.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/SciFiHelmet/glTF/SciFiHelmet.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Sponza/glTF/Sponza.gltf",
                "/mnt/devel/vkChess/data/chess.gltf"
            };


            model = new PbrModel2(staggingQ, modelPathes[0], descLayoutTextures,
                                  AttachmentType.Color,
                                  AttachmentType.PhysicalProps,
                                  AttachmentType.Normal,
                                  AttachmentType.AmbientOcclusion,
                                  AttachmentType.Emissive);
            //model = new Model (Dev, presentQueue, "../data/models/icosphere.gltf");
            //model = new Model (Dev, presentQueue, cmdPool, "../data/models/cube.gltf");
            DescriptorSetWrites uboUpdate = new DescriptorSetWrites(descLayoutMain);

            uboUpdate.Write(Dev, dsMain,
                            uboMats.Descriptor,
                            envCube.irradianceCube.Descriptor,
                            envCube.prefilterCube.Descriptor,
                            envCube.lutBrdf.Descriptor,
                            model.materialUBO.Descriptor,
                            uiImage.Descriptor);
        }
Example #6
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 {
                    byte *stagVertPtrInit = (byte *)stagging.MappedData.ToPointer();
                    byte *stagIdxPtrInit  = (byte *)(stagging.MappedData.ToPointer()) + vertSize;
                    byte *stagVertPtr     = stagVertPtrInit;
                    byte *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
                            byte *inPosPtr = null, inNormPtr = null, inUvPtr = null, inUv1Ptr = null;

                            GL.BufferView bv = gltf.BufferViews[(int)AccPos.BufferView];
                            inPosPtr  = (byte *)bufferHandles[bv.Buffer].AddrOfPinnedObject().ToPointer();
                            inPosPtr += AccPos.ByteOffset + bv.ByteOffset;

                            if (AccNorm != null)
                            {
                                bv         = gltf.BufferViews[(int)AccNorm.BufferView];
                                inNormPtr  = (byte *)bufferHandles[bv.Buffer].AddrOfPinnedObject().ToPointer();
                                inNormPtr += AccNorm.ByteOffset + bv.ByteOffset;
                            }
                            if (AccUv != null)
                            {
                                bv       = gltf.BufferViews[(int)AccUv.BufferView];
                                inUvPtr  = (byte *)bufferHandles[bv.Buffer].AddrOfPinnedObject().ToPointer();
                                inUvPtr += AccUv.ByteOffset + bv.ByteOffset;
                            }
                            if (AccUv1 != null)
                            {
                                bv        = gltf.BufferViews[(int)AccUv1.BufferView];
                                inUv1Ptr  = (byte *)bufferHandles[bv.Buffer].AddrOfPinnedObject().ToPointer();
                                inUv1Ptr += AccUv1.ByteOffset + bv.ByteOffset;
                            }


                            for (int j = 0; j < prim.vertexCount; j++)
                            {
                                System.Buffer.MemoryCopy(inPosPtr, stagVertPtr, 12, 12);
                                inPosPtr += 12;
                                if (inNormPtr != null)
                                {
                                    System.Buffer.MemoryCopy(inNormPtr, stagVertPtr + 12, 12, 12);
                                    inNormPtr += 12;
                                }
                                if (inUvPtr != null)
                                {
                                    System.Buffer.MemoryCopy(inUvPtr, stagVertPtr + 24, 8, 8);
                                    inUvPtr += 8;
                                }
                                if (inUv1Ptr != null)
                                {
                                    System.Buffer.MemoryCopy(inUv1Ptr, stagVertPtr + 32, 8, 8);
                                    inUv1Ptr += 8;
                                }
                                stagVertPtr += vertexByteSize;
                            }

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

                                byte *inIdxPtr = (byte *)bufferHandles[bv.Buffer].AddrOfPinnedObject().ToPointer();
                                inIdxPtr += 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)
                                    {
                                        System.Buffer.MemoryCopy(inIdxPtr, stagIdxPtr, (long)acc.Count * 2, (long)acc.Count * 2);
                                        stagIdxPtr += (long)acc.Count * 2;
                                    }
                                    else
                                    {
                                        uint *  usPtr = (uint *)stagIdxPtr;
                                        ushort *inPtr = (ushort *)inIdxPtr;
                                        for (int i = 0; i < acc.Count; i++)
                                        {
                                            usPtr[i] = inPtr[i];
                                        }
                                        stagIdxPtr += (long)acc.Count * 4;
                                    }
                                }
                                else if (acc.ComponentType == GL.Accessor.ComponentTypeEnum.UNSIGNED_INT)
                                {
                                    if (indexType == VkIndexType.Uint32)
                                    {
                                        System.Buffer.MemoryCopy(inIdxPtr, stagIdxPtr, (long)acc.Count * 4, (long)acc.Count * 4);
                                        stagIdxPtr += (long)acc.Count * 4;
                                    }
                                    else
                                    {
                                        ushort *usPtr = (ushort *)stagIdxPtr;
                                        uint *  inPtr = (uint *)inIdxPtr;
                                        for (int i = 0; i < acc.Count; i++)
                                        {
                                            usPtr[i] = (ushort)inPtr[i];
                                        }
                                        stagIdxPtr += (long)acc.Count * 2;
                                    }
                                }
                                else if (acc.ComponentType == GL.Accessor.ComponentTypeEnum.UNSIGNED_BYTE)
                                {
                                    //convert
                                    if (indexType == VkIndexType.Uint16)
                                    {
                                        ushort *usPtr = (ushort *)stagIdxPtr;
                                        for (int i = 0; i < acc.Count; i++)
                                        {
                                            usPtr[i] = (ushort)inIdxPtr[i];
                                        }
                                        stagIdxPtr += (long)acc.Count * 2;
                                    }
                                    else
                                    {
                                        uint *usPtr = (uint *)stagIdxPtr;
                                        for (int i = 0; i < acc.Count; i++)
                                        {
                                            usPtr[i] = (uint)inIdxPtr[i];
                                        }
                                        stagIdxPtr += (long)acc.Count * 4;
                                    }
                                }
                                else
                                {
                                    throw new NotImplementedException();
                                }

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

                            m.AddPrimitive(prim);

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

                stagging.Unmap();

                CommandBuffer 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());
        }