コード例 #1
0
        private void CopyDataSingleStagingBuffer(IntPtr pixelsFront, IntPtr pixelsBack, IntPtr pixelsLeft, IntPtr pixelsRight, IntPtr pixelsTop, IntPtr pixelsBottom, VkMemoryRequirements memReqs)
        {
            VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New();

            bufferCI.size  = memReqs.size;
            bufferCI.usage = VkBufferUsageFlags.TransferSrc;
            vkCreateBuffer(_device, ref bufferCI, null, out VkBuffer stagingBuffer);

            vkGetBufferMemoryRequirements(_device, stagingBuffer, out VkMemoryRequirements stagingMemReqs);
            VkMemoryBlock stagingMemory = _memoryManager.Allocate(
                FindMemoryType(
                    _physicalDevice,
                    stagingMemReqs.memoryTypeBits,
                    VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent),
                stagingMemReqs.size,
                stagingMemReqs.alignment);

            VkResult result = vkBindBufferMemory(_device, stagingBuffer, stagingMemory.DeviceMemory, 0);

            CheckResult(result);

            StackList <IntPtr, Size6IntPtr> faces = new StackList <IntPtr, Size6IntPtr>();

            faces.Add(pixelsRight);
            faces.Add(pixelsLeft);
            faces.Add(pixelsTop);
            faces.Add(pixelsBottom);
            faces.Add(pixelsBack);
            faces.Add(pixelsFront);

            for (uint i = 0; i < 6; i++)
            {
                VkImageSubresource subresource;
                subresource.aspectMask = VkImageAspectFlags.Color;
                subresource.arrayLayer = i;
                subresource.mipLevel   = 0;
                vkGetImageSubresourceLayout(_device, _image, ref subresource, out VkSubresourceLayout faceLayout);
                void *mappedPtr;
                result = vkMapMemory(_device, stagingMemory.DeviceMemory, faceLayout.offset, faceLayout.size, 0, &mappedPtr);
                CheckResult(result);
                Buffer.MemoryCopy((void *)faces[i], mappedPtr, faceLayout.size, faceLayout.size);
                vkUnmapMemory(_device, stagingMemory.DeviceMemory);
            }

            StackList <VkBufferImageCopy, Size512Bytes> copyRegions = new StackList <VkBufferImageCopy, Size512Bytes>();

            for (uint i = 0; i < 6; i++)
            {
                VkImageSubresource subres;
                subres.aspectMask = VkImageAspectFlags.Color;
                subres.mipLevel   = 0;
                subres.arrayLayer = i;
                vkGetImageSubresourceLayout(_device, _image, ref subres, out VkSubresourceLayout layout);

                VkBufferImageCopy copyRegion;
                copyRegion.bufferOffset       = layout.offset;
                copyRegion.bufferImageHeight  = 0;
                copyRegion.bufferRowLength    = 0;
                copyRegion.imageExtent.width  = (uint)Width;
                copyRegion.imageExtent.height = (uint)Height;
                copyRegion.imageExtent.depth  = 1;
                copyRegion.imageOffset.x      = 0;
                copyRegion.imageOffset.y      = 0;
                copyRegion.imageOffset.z      = 0;
                copyRegion.imageSubresource.baseArrayLayer = i;
                copyRegion.imageSubresource.aspectMask     = VkImageAspectFlags.Color;
                copyRegion.imageSubresource.layerCount     = 1;
                copyRegion.imageSubresource.mipLevel       = 0;

                copyRegions.Add(copyRegion);
            }

            VkFenceCreateInfo fenceCI = VkFenceCreateInfo.New();

            result = vkCreateFence(_device, ref fenceCI, null, out VkFence copyFence);
            CheckResult(result);

            TransitionImageLayout(_image, (uint)MipLevels, 0, 6, _imageLayout, VkImageLayout.TransferDstOptimal);

            VkCommandBuffer copyCmd = _rc.BeginOneTimeCommands();

            vkCmdCopyBufferToImage(copyCmd, stagingBuffer, _image, VkImageLayout.TransferDstOptimal, copyRegions.Count, (IntPtr)copyRegions.Data);
            _rc.EndOneTimeCommands(copyCmd, copyFence);
            result = vkWaitForFences(_device, 1, ref copyFence, true, ulong.MaxValue);
            CheckResult(result);

            vkDestroyBuffer(_device, stagingBuffer, null);
            _memoryManager.Free(stagingMemory);
        }
コード例 #2
0
        public void SetTextureData(int mipLevel, int x, int y, int width, int height, IntPtr data, int dataSizeInBytes)
        {
            if (x != 0 || y != 0)
            {
                throw new NotImplementedException();
            }

            // First, create a staging texture.
            CreateImage(
                _device,
                _physicalDevice,
                _memoryManager,
                (uint)width,
                (uint)height,
                1,
                Format,
                VkImageTiling.Linear,
                VkImageUsageFlags.TransferSrc,
                VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                out VkImage stagingImage,
                out VkMemoryBlock stagingMemory);

            VkImageSubresource subresource = new VkImageSubresource();

            subresource.aspectMask = VkImageAspectFlags.Color;
            subresource.mipLevel   = 0;
            subresource.arrayLayer = 0;
            vkGetImageSubresourceLayout(_device, stagingImage, ref subresource, out VkSubresourceLayout stagingLayout);
            ulong rowPitch = stagingLayout.rowPitch;

            void *   mappedPtr;
            VkResult result = vkMapMemory(_device, stagingMemory.DeviceMemory, stagingMemory.Offset, stagingLayout.size, 0, &mappedPtr);

            CheckResult(result);

            if (rowPitch == (ulong)width)
            {
                Buffer.MemoryCopy(data.ToPointer(), mappedPtr, dataSizeInBytes, dataSizeInBytes);
            }
            else
            {
                int pixelSizeInBytes = FormatHelpers.GetPixelSizeInBytes(_veldridFormat);
                for (uint yy = 0; yy < height; yy++)
                {
                    byte *dstRowStart = ((byte *)mappedPtr) + (rowPitch * yy);
                    byte *srcRowStart = ((byte *)data.ToPointer()) + (width * yy * pixelSizeInBytes);
                    Unsafe.CopyBlock(dstRowStart, srcRowStart, (uint)(width * pixelSizeInBytes));
                }
            }

            vkUnmapMemory(_device, stagingMemory.DeviceMemory);

            TransitionImageLayout(stagingImage, 1, VkImageLayout.Preinitialized, VkImageLayout.TransferSrcOptimal);
            TransitionImageLayout(_image, (uint)MipLevels, _imageLayout, VkImageLayout.TransferDstOptimal);
            CopyImage(stagingImage, 0, _image, (uint)mipLevel, (uint)width, (uint)height);
            TransitionImageLayout(_image, (uint)MipLevels, VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal);
            _imageLayout = VkImageLayout.ShaderReadOnlyOptimal;

            vkDestroyImage(_device, stagingImage, null);
            _memoryManager.Free(stagingMemory);
        }