예제 #1
0
        public static Texture2D RenderTarget(Graphics g, int width, int height)
        {
            const Format format = Format.B8G8R8A8UNorm;

            // Create optimal tiled target image.
            Image image = g.Context.Device.CreateImage(new ImageCreateInfo
            {
                ImageType     = ImageType.Image2D,
                Format        = format,
                MipLevels     = 1,
                ArrayLayers   = 1,
                Samples       = SampleCounts.Count1,
                Tiling        = ImageTiling.Optimal,
                SharingMode   = SharingMode.Exclusive,
                InitialLayout = ImageLayout.Undefined,
                Extent        = new Extent3D(width, height, 1),
                Usage         = ImageUsages.Sampled | ImageUsages.TransferDst | ImageUsages.TransferSrc | ImageUsages.ColorAttachment
            });
            MemoryRequirements imageMemReq = image.GetMemoryRequirements();
            int imageHeapIndex             = g.Context.MemoryProperties.MemoryTypes.IndexOf(
                imageMemReq.MemoryTypeBits, MemoryProperties.DeviceLocal);
            DeviceMemory memory = g.Context.Device.AllocateMemory(new MemoryAllocateInfo(imageMemReq.Size, imageHeapIndex));

            image.BindMemory(memory);

            var subresourceRange = new ImageSubresourceRange(ImageAspects.Color, 0, 1, 0, 1);

            // Create image view.
            ImageView view = image.CreateView(new ImageViewCreateInfo(format, subresourceRange));

            var sampler = VKHelper.CreateSampler(g.Context, Filter.Linear, Filter.Linear, SamplerMipmapMode.Linear);

            return(new Texture2D(g.Context, image, memory, view, format, new Vector2I(width, height), true));
        }
예제 #2
0
        internal void Build()
        {
            GraphicsCommandPool?.Reset();
            ComputeCommandPool?.Reset();

            ImageAvailableSemaphore?.Dispose();
            RenderingFinishedSemaphore?.Dispose();
            Swapchain?.Dispose();

            ImageAvailableSemaphore    = ToDispose(Device.CreateSemaphore());
            RenderingFinishedSemaphore = ToDispose(Device.CreateSemaphore());

            Swapchain = ToDispose(VKHelper.CreateSwapchain(this));
            CacheSwapchainImages();
        }
예제 #3
0
        public void Build()
        {
            DescriptorSetLayout?.Dispose();
            PipelineLayout?.Dispose();
            //UsingSamplers?.DisposeRange();
            DescriptorPool?.Dispose();
            RenderPass?.Dispose();
            Pipeline?.Dispose();

            DescriptorSetLayout = VKHelper.CreateDescriptorSetLayout(Graphics, DescriptorItems);
            PipelineLayout      = VKHelper.CreatePipelineLayout(Graphics, DescriptorSetLayout);
            DescriptorPool      = VKHelper.CreateDescriptorPool(Graphics, DescriptorItems);
            DescriptorSet       = VKHelper.CreateDescriptorSet(DescriptorPool, DescriptorSetLayout, DescriptorItems, out UsingSamplers);
            RenderPass          = VKHelper.CreateRenderPass(Graphics, ClearDepthOnBeginPass);
            Pipeline            = VKHelper.CreateGraphicsPipeline(Graphics, PipelineLayout, RenderPass, Shaders, DepthTest, DepthWrite, Instancing, InstanceInfoType, BlendMode, PrimitiveType, PrimitiveRenderMode, PrimitiveCullMode, LineWidth, ViewportPos, ViewportSize);
        }
예제 #4
0
        public static DescriptorItem CombinedImageSampler(ShaderType shaderType, Texture2D texture, SamplerFilter minFilter, SamplerFilter magFilter, SamplerFilter mipmapFilter = SamplerFilter.Nearest)
        {
            var item = new DescriptorItem();

            item.Type    = DescriptorType.CombinedImageSampler;
            item.Shader  = shaderType;
            item.Texture = texture;
            item.Sampler = VKHelper.CreateSampler(
                texture.Context,
                minFilter == SamplerFilter.Nearest ? Filter.Nearest :
                minFilter == SamplerFilter.Cubic ? Filter.CubicImg :
                Filter.Linear,
                magFilter == SamplerFilter.Nearest ? Filter.Nearest :
                magFilter == SamplerFilter.Cubic ? Filter.CubicImg :
                Filter.Linear,
                mipmapFilter == SamplerFilter.Linear ? SamplerMipmapMode.Linear :
                SamplerMipmapMode.Nearest
                );
            return(item);
        }
예제 #5
0
        public Context(GameWindow window)
        {
            Window              = window;
            Instance            = ToDispose(VKHelper.CreateInstance());
            DebugReportCallback = ToDispose(VKHelper.CreateDebugReportCallback(Instance));
            Surface             = ToDispose(VKHelper.CreateSurface(Instance, Window.Handle));

            foreach (PhysicalDevice physicalDevice in Instance.EnumeratePhysicalDevices())
            {
                QueueFamilyProperties[] queueFamilyProperties = physicalDevice.GetQueueFamilyProperties();
                for (int i = 0; i < queueFamilyProperties.Length; i++)
                {
                    if (queueFamilyProperties[i].QueueFlags.HasFlag(Queues.Graphics))
                    {
                        if (GraphicsQueueFamilyIndex == -1)
                        {
                            GraphicsQueueFamilyIndex = i;
                        }
                        if (ComputeQueueFamilyIndex == -1)
                        {
                            ComputeQueueFamilyIndex = i;
                        }

                        if (physicalDevice.GetSurfaceSupportKhr(i, Surface) &&
                            VKHelper.GetPresentationSupport(physicalDevice, i))
                        {
                            PresentQueueFamilyIndex = i;
                        }

                        if (GraphicsQueueFamilyIndex != -1 &&
                            ComputeQueueFamilyIndex != -1 &&
                            PresentQueueFamilyIndex != -1)
                        {
                            PhysicalDevice = physicalDevice;
                            break;
                        }
                    }
                }
                if (PhysicalDevice != null)
                {
                    break;
                }
            }

            if (PhysicalDevice == null)
            {
                throw new InvalidOperationException("No suitable physical device found.");
            }

            GenerateDepthStencilFormat();

            // Store memory properties of the physical device.
            MemoryProperties = PhysicalDevice.GetMemoryProperties();
            Features         = PhysicalDevice.GetFeatures();
            Properties       = PhysicalDevice.GetProperties();

            // Create a logical device.
            bool sameGraphicsAndPresent = GraphicsQueueFamilyIndex == PresentQueueFamilyIndex;
            var  queueCreateInfos       = new DeviceQueueCreateInfo[sameGraphicsAndPresent ? 1 : 2];

            queueCreateInfos[0] = new DeviceQueueCreateInfo(GraphicsQueueFamilyIndex, 1, 1.0f);
            if (!sameGraphicsAndPresent)
            {
                queueCreateInfos[1] = new DeviceQueueCreateInfo(PresentQueueFamilyIndex, 1, 1.0f);
            }

            var deviceCreateInfo = new DeviceCreateInfo(
                queueCreateInfos,
                new[] { Constant.DeviceExtension.KhrSwapchain, Constant.DeviceExtension.KhrMaintenance1 },
                Features);

            Device = PhysicalDevice.CreateDevice(deviceCreateInfo);

            // Get queue(s).
            GraphicsQueue = Device.GetQueue(GraphicsQueueFamilyIndex);
            ComputeQueue  = ComputeQueueFamilyIndex == GraphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(ComputeQueueFamilyIndex);
            PresentQueue = PresentQueueFamilyIndex == GraphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(PresentQueueFamilyIndex);

            Content = new Content(this);

            GraphicsCommandPool = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(GraphicsQueueFamilyIndex, CommandPoolCreateFlags.ResetCommandBuffer)));
            ComputeCommandPool  = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(ComputeQueueFamilyIndex)));

            Graphics = ToDispose(new Graphics(this));

            Build();
        }
예제 #6
0
        internal static Texture2D FromTextureData(Context ctx, TextureData tex2D)
        {
            var stagingBuffer = ctx.Device.CreateBuffer(
                new BufferCreateInfo(tex2D.Mipmaps[0].Size, BufferUsages.TransferSrc));
            MemoryRequirements stagingMemReq = stagingBuffer.GetMemoryRequirements();
            int heapIndex = ctx.MemoryProperties.MemoryTypes.IndexOf(
                stagingMemReq.MemoryTypeBits, MemoryProperties.HostVisible);
            DeviceMemory stagingMemory = ctx.Device.AllocateMemory(
                new MemoryAllocateInfo(stagingMemReq.Size, heapIndex));

            stagingBuffer.BindMemory(stagingMemory);

            unsafe
            {
                var dest = (byte *)stagingMemory.Map(0, stagingMemReq.Size);
                var src  = (byte *)tex2D.Mipmaps[0].Data.Scan0;
                for (var i = 0; i < stagingMemReq.Size - 3; i += 4)
                {
                    *(dest + 2) = *(src++);
                    *(dest + 1) = *(src++);
                    *(dest)     = *(src++);
                    *(dest + 3) = *(src++);
                    dest       += 4;
                }
            }
            //Interop.Write(ptr, tex2D.Mipmaps[0].Data);
            stagingMemory.Unmap();

            // Setup buffer copy regions for each mip level.
            var bufferCopyRegions = new BufferImageCopy[tex2D.Mipmaps.Length];
            int offset            = 0;

            for (int i = 0; i < bufferCopyRegions.Length; i++)
            {
                bufferCopyRegions = new[]
                {
                    new BufferImageCopy
                    {
                        ImageSubresource = new ImageSubresourceLayers(ImageAspects.Color, i, 0, 1),
                        ImageExtent      = tex2D.Mipmaps[0].Extent,
                        BufferOffset     = offset
                    }
                };
                offset += tex2D.Mipmaps[i].Size;
            }

            // Create optimal tiled target image.
            Image image = ctx.Device.CreateImage(new ImageCreateInfo
            {
                ImageType     = ImageType.Image2D,
                Format        = tex2D.Format,
                MipLevels     = tex2D.Mipmaps.Length,
                ArrayLayers   = 1,
                Samples       = SampleCounts.Count1,
                Tiling        = ImageTiling.Optimal,
                SharingMode   = SharingMode.Exclusive,
                InitialLayout = ImageLayout.Undefined,
                Extent        = tex2D.Mipmaps[0].Extent,
                Usage         = ImageUsages.Sampled | ImageUsages.TransferDst
            });
            MemoryRequirements imageMemReq = image.GetMemoryRequirements();
            int imageHeapIndex             = ctx.MemoryProperties.MemoryTypes.IndexOf(
                imageMemReq.MemoryTypeBits, MemoryProperties.DeviceLocal);
            DeviceMemory memory = ctx.Device.AllocateMemory(new MemoryAllocateInfo(imageMemReq.Size, imageHeapIndex));

            image.BindMemory(memory);

            var subresourceRange = new ImageSubresourceRange(ImageAspects.Color, 0, tex2D.Mipmaps.Length, 0, 1);

            // Copy the data from staging buffers to device local buffers.
            CommandBuffer cmdBuffer = ctx.GraphicsCommandPool.AllocateBuffers(new CommandBufferAllocateInfo(CommandBufferLevel.Primary, 1))[0];

            cmdBuffer.Begin(new CommandBufferBeginInfo(CommandBufferUsages.OneTimeSubmit));
            cmdBuffer.CmdPipelineBarrier(PipelineStages.TopOfPipe, PipelineStages.Transfer,
                                         imageMemoryBarriers: new[]
            {
                new ImageMemoryBarrier(
                    image, subresourceRange,
                    0, Accesses.TransferWrite,
                    ImageLayout.Undefined, ImageLayout.TransferDstOptimal)
            });
            cmdBuffer.CmdCopyBufferToImage(stagingBuffer, image, ImageLayout.TransferDstOptimal, bufferCopyRegions);
            cmdBuffer.CmdPipelineBarrier(PipelineStages.Transfer, PipelineStages.FragmentShader,
                                         imageMemoryBarriers: new[]
            {
                new ImageMemoryBarrier(
                    image, subresourceRange,
                    Accesses.TransferWrite, Accesses.ShaderRead,
                    ImageLayout.TransferDstOptimal, ImageLayout.ShaderReadOnlyOptimal)
            });
            cmdBuffer.End();

            // Submit.
            Fence fence = ctx.Device.CreateFence();

            ctx.GraphicsQueue.Submit(new SubmitInfo(commandBuffers: new[] { cmdBuffer }), fence);
            fence.Wait();

            // Cleanup staging resources.
            fence.Dispose();
            stagingMemory.Dispose();
            stagingBuffer.Dispose();

            // Create image view.
            ImageView view = image.CreateView(new ImageViewCreateInfo(tex2D.Format, subresourceRange));

            var sampler = VKHelper.CreateSampler(ctx, Filter.Linear, Filter.Linear, SamplerMipmapMode.Linear);

            return(new Texture2D(ctx, image, memory, view, tex2D.Format, new Vector2I(tex2D.Mipmaps[0].Extent.Width, tex2D.Mipmaps[0].Extent.Height), false));
        }