예제 #1
0
 public void RecordDraw(CommandBuffer cmd)
 {
     cmd.BindDescriptorSet(Layout, dsMain);
     envCube.RecordDraw(cmd);
     drawModel(cmd);
 }
예제 #2
0
 void drawModel(CommandBuffer cmd)
 {
     Bind(cmd);
     model.Bind(cmd);
     model.DrawAll(cmd, Layout);
 }
예제 #3
0
 //TODO:destset for binding must be variable
 //TODO: ADD REFAULT MAT IF NO MAT DEFINED
 public abstract void RenderNode(CommandBuffer cmd, PipelineLayout pipelineLayout, Node node, Matrix4x4 currentTransform, bool shadowPass = false);
예제 #4
0
 /// <summary> bind vertex and index buffers </summary>
 public virtual void Bind(CommandBuffer cmd)
 {
     cmd.BindVertexBuffer(vbo);
     cmd.BindIndexBuffer(ibo, IndexBufferType);
 }
예제 #5
0
파일: Image.cs 프로젝트: Svengali/vk.net
        // Create an image memory barrier for changing the layout of
        // an image and put it into an active command buffer
        // See chapter 11.4 "Image Layout" for details
        public void SetLayout(
            CommandBuffer cmdbuffer,
            VkImageLayout oldImageLayout,
            VkImageLayout newImageLayout,
            VkImageSubresourceRange subresourceRange,
            VkPipelineStageFlags srcStageMask = VkPipelineStageFlags.AllCommands,
            VkPipelineStageFlags dstStageMask = VkPipelineStageFlags.AllCommands)
        {
            // Create an image barrier object
            VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New();

            imageMemoryBarrier.srcQueueFamilyIndex = Vk.QueueFamilyIgnored;
            imageMemoryBarrier.dstQueueFamilyIndex = Vk.QueueFamilyIgnored;
            imageMemoryBarrier.oldLayout           = oldImageLayout;
            imageMemoryBarrier.newLayout           = newImageLayout;
            imageMemoryBarrier.image            = handle;
            imageMemoryBarrier.subresourceRange = subresourceRange;

            // Source layouts (old)
            // Source access mask controls actions that have to be finished on the old layout
            // before it will be transitioned to the new layout
            switch (oldImageLayout)
            {
            case VkImageLayout.Undefined:
                // Image layout is undefined (or does not matter)
                // Only valid as initial layout
                // No flags required, listed only for completeness
                imageMemoryBarrier.srcAccessMask = 0;
                break;

            case VkImageLayout.Preinitialized:
                // Image is preinitialized
                // Only valid as initial layout for linear images, preserves memory contents
                // Make sure host writes have been finished
                imageMemoryBarrier.srcAccessMask = VkAccessFlags.HostWrite;
                break;

            case VkImageLayout.ColorAttachmentOptimal:
                // Image is a color attachment
                // Make sure any writes to the color buffer have been finished
                imageMemoryBarrier.srcAccessMask = VkAccessFlags.ColorAttachmentWrite;
                break;

            case VkImageLayout.DepthStencilAttachmentOptimal:
                // Image is a depth/stencil attachment
                // Make sure any writes to the depth/stencil buffer have been finished
                imageMemoryBarrier.srcAccessMask = VkAccessFlags.DepthStencilAttachmentWrite;
                break;

            case VkImageLayout.TransferSrcOptimal:
                // Image is a transfer source
                // Make sure any reads from the image have been finished
                imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
                break;

            case VkImageLayout.TransferDstOptimal:
                // Image is a transfer destination
                // Make sure any writes to the image have been finished
                imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferWrite;
                break;

            case VkImageLayout.ShaderReadOnlyOptimal:
                // Image is read by a shader
                // Make sure any shader reads from the image have been finished
                imageMemoryBarrier.srcAccessMask = VkAccessFlags.ShaderRead;
                break;
            }

            // Target layouts (new)
            // Destination access mask controls the dependency for the new image layout
            switch (newImageLayout)
            {
            case VkImageLayout.TransferDstOptimal:
                // Image will be used as a transfer destination
                // Make sure any writes to the image have been finished
                imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferWrite;
                break;

            case VkImageLayout.TransferSrcOptimal:
                // Image will be used as a transfer source
                // Make sure any reads from and writes to the image have been finished
                imageMemoryBarrier.srcAccessMask = imageMemoryBarrier.srcAccessMask | VkAccessFlags.TransferRead;
                imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferRead;
                break;

            case VkImageLayout.ColorAttachmentOptimal:
                // Image will be used as a color attachment
                // Make sure any writes to the color buffer have been finished
                imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
                imageMemoryBarrier.dstAccessMask = VkAccessFlags.ColorAttachmentWrite;
                break;

            case VkImageLayout.DepthStencilAttachmentOptimal:
                // Image layout will be used as a depth/stencil attachment
                // Make sure any writes to depth/stencil buffer have been finished
                imageMemoryBarrier.dstAccessMask = imageMemoryBarrier.dstAccessMask | VkAccessFlags.DepthStencilAttachmentWrite;
                break;

            case VkImageLayout.ShaderReadOnlyOptimal:
                // Image will be read in a shader (sampler, input attachment)
                // Make sure any writes to the image have been finished
                if (imageMemoryBarrier.srcAccessMask == 0)
                {
                    imageMemoryBarrier.srcAccessMask = VkAccessFlags.HostWrite | VkAccessFlags.TransferWrite;
                }
                imageMemoryBarrier.dstAccessMask = VkAccessFlags.ShaderRead;
                break;
            }

            // Put barrier inside setup command buffer
            Vk.vkCmdPipelineBarrier(
                cmdbuffer.Handle,
                srcStageMask,
                dstStageMask,
                0,
                0, IntPtr.Zero,
                0, IntPtr.Zero,
                1, ref imageMemoryBarrier);
        }
예제 #6
0
        ///// <summary>
        ///// build texture array
        ///// </summary>
        ///// <returns>The images.</returns>
        ///// <param name="textureSize">Texture size.</param>
        public void BuildTexArray(ref Image texArray, uint firstImg = 0)
        {
            int texDim = (int)texArray.CreateInfo.extent.width;

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

            texArray.SetLayout(cmd, VkImageAspectFlags.Color, VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal,
                               VkPipelineStageFlags.BottomOfPipe, VkPipelineStageFlags.Transfer);
            cmd.End();
            transferQ.Submit(cmd);
            transferQ.WaitIdle();
            cmd.Free();

            VkImageBlit imageBlit = new VkImageBlit {
                srcSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color, 1, 0),
                dstOffsets_1   = new VkOffset3D(texDim, texDim, 1)
            };

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

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

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

                cmd = cmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);

                vkimg.SetLayout(cmd, VkImageAspectFlags.Color, VkImageLayout.Undefined, VkImageLayout.TransferSrcOptimal,
                                VkPipelineStageFlags.Transfer, VkPipelineStageFlags.Transfer);

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

                cmd.End();
                transferQ.Submit(cmd);
                transferQ.WaitIdle();
                cmd.Free();

                vkimg.Dispose();
            }

            uint imgCount = (uint)gltf.Images.Length;

            VkImageSubresourceRange mipSubRange = new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, 1, firstImg, imgCount);

            cmd = cmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);
            texArray.SetLayout(cmd, VkImageLayout.Undefined, VkImageLayout.TransferSrcOptimal, mipSubRange,
                               VkPipelineStageFlags.Transfer, VkPipelineStageFlags.Transfer);

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

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

            texArray.SetLayout(cmd, VkImageAspectFlags.Color, VkImageLayout.TransferSrcOptimal, VkImageLayout.ShaderReadOnlyOptimal,
                               VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader);

            cmd.End();
            transferQ.Submit(cmd);
            transferQ.WaitIdle();
            cmd.Free();
        }
예제 #7
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());
        }