コード例 #1
0
ファイル: VulkanUtil.cs プロジェクト: bbi-ashmatheson/veldrid
        public static void CreateImage(
            VkDevice device,
            VkPhysicalDevice physicalDevice,
            VkDeviceMemoryManager memoryManager,
            uint width,
            uint height,
            uint arrayLayers,
            VkFormat format,
            VkImageTiling tiling,
            VkImageUsageFlags usage,
            VkMemoryPropertyFlags properties,
            out VkImage image,
            out VkMemoryBlock memory)
        {
            VkImageCreateInfo imageCI = VkImageCreateInfo.New();

            imageCI.imageType     = VkImageType.Image2D;
            imageCI.extent.width  = width;
            imageCI.extent.height = height;
            imageCI.extent.depth  = 1;
            imageCI.mipLevels     = 1;
            imageCI.arrayLayers   = arrayLayers;
            imageCI.format        = format;
            imageCI.tiling        = tiling;
            imageCI.initialLayout = VkImageLayout.Preinitialized;
            imageCI.usage         = usage;
            imageCI.sharingMode   = VkSharingMode.Exclusive;
            imageCI.samples       = VkSampleCountFlags.Count1;

            VkResult result = vkCreateImage(device, ref imageCI, null, out image);

            CheckResult(result);

            vkGetImageMemoryRequirements(device, image, out VkMemoryRequirements memRequirements);
            VkMemoryBlock memoryToken = memoryManager.Allocate(
                FindMemoryType(physicalDevice, memRequirements.memoryTypeBits, properties),
                memRequirements.size,
                memRequirements.alignment);

            memory = memoryToken;
            result = vkBindImageMemory(device, image, memory.DeviceMemory, memory.Offset);
            CheckResult(result);
        }
コード例 #2
0
        public VkCubemapTexture(
            VkDevice device,
            VkPhysicalDevice physicalDevice,
            VkDeviceMemoryManager memoryManager,
            VkRenderContext rc,
            IntPtr pixelsFront,
            IntPtr pixelsBack,
            IntPtr pixelsLeft,
            IntPtr pixelsRight,
            IntPtr pixelsTop,
            IntPtr pixelsBottom,
            int width,
            int height,
            PixelFormat format)
        {
            _device         = device;
            _physicalDevice = physicalDevice;
            _rc             = rc;
            _memoryManager  = memoryManager;

            Width     = width;
            Height    = height;
            _format   = format;
            _vkFormat = VkFormats.VeldridToVkPixelFormat(_format);

            vkGetPhysicalDeviceImageFormatProperties(
                _physicalDevice,
                _vkFormat,
                VkImageType.Image2D,
                VkImageTiling.Linear,
                VkImageUsageFlags.Sampled,
                VkImageCreateFlags.CubeCompatible,
                out VkImageFormatProperties linearProps);

            vkGetPhysicalDeviceImageFormatProperties(
                _physicalDevice,
                _vkFormat,
                VkImageType.Image2D,
                VkImageTiling.Optimal,
                VkImageUsageFlags.Sampled,
                VkImageCreateFlags.CubeCompatible,
                out VkImageFormatProperties optimalProps);

            bool useSingleStagingBuffer = linearProps.maxArrayLayers >= 6;

            VkImageCreateInfo imageCI = VkImageCreateInfo.New();

            imageCI.imageType     = VkImageType.Image2D;
            imageCI.flags         = VkImageCreateFlags.CubeCompatible;
            imageCI.format        = _vkFormat;
            imageCI.extent.width  = (uint)width;
            imageCI.extent.height = (uint)height;
            imageCI.extent.depth  = 1;
            imageCI.mipLevels     = 1;
            imageCI.arrayLayers   = 6;
            imageCI.samples       = VkSampleCountFlags.Count1;
            imageCI.tiling        = useSingleStagingBuffer ? VkImageTiling.Linear : VkImageTiling.Optimal;
            imageCI.usage         = VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferDst;
            imageCI.initialLayout = VkImageLayout.Preinitialized;

            VkResult result = vkCreateImage(_device, ref imageCI, null, out _image);

            CheckResult(result);

            vkGetImageMemoryRequirements(_device, _image, out VkMemoryRequirements memReqs);
            uint memoryType = FindMemoryType(_physicalDevice, memReqs.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal);

            _memory = memoryManager.Allocate(memoryType, memReqs.size, memReqs.alignment);
            vkBindImageMemory(_device, _image, _memory.DeviceMemory, _memory.Offset);

            if (useSingleStagingBuffer)
            {
                CopyDataSingleStagingBuffer(pixelsFront, pixelsBack, pixelsLeft, pixelsRight, pixelsTop, pixelsBottom, memReqs);
            }
            else
            {
                CopyDataMultiImage(pixelsFront, pixelsBack, pixelsLeft, pixelsRight, pixelsTop, pixelsBottom);
            }

            TransitionImageLayout(_image, (uint)MipLevels, 0, 6, VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal);
            _imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
        }
コード例 #3
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);
        }
コード例 #4
0
        public VkTexture2D(
            VkDevice device,
            VkPhysicalDevice physicalDevice,
            VkDeviceMemoryManager memoryManager,
            VkRenderContext rc,
            int mipLevels,
            int width,
            int height,
            PixelFormat veldridFormat,
            DeviceTextureCreateOptions createOptions)
        {
            _device         = device;
            _physicalDevice = physicalDevice;
            _memoryManager  = memoryManager;
            _rc             = rc;

            MipLevels      = mipLevels;
            _width         = width;
            _height        = height;
            _createOptions = createOptions;
            if (createOptions == DeviceTextureCreateOptions.DepthStencil)
            {
                Format = VkFormat.D16Unorm;
            }
            else
            {
                Format = VkFormats.VeldridToVkPixelFormat(veldridFormat);
            }

            _veldridFormat = veldridFormat;

            VkImageCreateInfo imageCI = VkImageCreateInfo.New();

            imageCI.mipLevels     = (uint)mipLevels;
            imageCI.arrayLayers   = 1;
            imageCI.imageType     = VkImageType.Image2D;
            imageCI.extent.width  = (uint)width;
            imageCI.extent.height = (uint)height;
            imageCI.extent.depth  = 1;
            imageCI.initialLayout = VkImageLayout.Preinitialized; // TODO: Use proper VkImageLayout values and transitions.
            imageCI.usage         = VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled;
            if (createOptions == DeviceTextureCreateOptions.RenderTarget)
            {
                imageCI.usage |= VkImageUsageFlags.ColorAttachment;
            }
            else if (createOptions == DeviceTextureCreateOptions.DepthStencil)
            {
                imageCI.usage |= VkImageUsageFlags.DepthStencilAttachment;
            }
            imageCI.tiling = createOptions == DeviceTextureCreateOptions.DepthStencil ? VkImageTiling.Optimal : VkImageTiling.Optimal;
            imageCI.format = Format;

            imageCI.samples = VkSampleCountFlags.Count1;

            VkResult result = vkCreateImage(device, ref imageCI, null, out _image);

            CheckResult(result);

            vkGetImageMemoryRequirements(_device, _image, out VkMemoryRequirements memoryRequirements);

            VkMemoryBlock memoryToken = memoryManager.Allocate(
                FindMemoryType(
                    _physicalDevice,
                    memoryRequirements.memoryTypeBits,
                    VkMemoryPropertyFlags.DeviceLocal),
                memoryRequirements.size,
                memoryRequirements.alignment);

            _memory = memoryToken;
            vkBindImageMemory(_device, _image, _memory.DeviceMemory, _memory.Offset);
        }