Ejemplo n.º 1
0
        public AttributelessObject(
            RenderScene scene,
            int vertexCount,
            ReadOnlySpan <TextureInfo> textureInfos)
        {
            if (scene == null)
            {
                throw new ArgumentNullException(nameof(scene));
            }
            this.vertexCount = vertexCount;

            //Prepare the inputs
            inputs = new IShaderInput[textureInfos.Length];
            for (int i = 0; i < inputs.Length; i++)
            {
                DeviceTexture texture = DeviceTexture.UploadTexture(
                    texture: textureInfos[i].Texture as IInternalTexture,
                    scene, generateMipMaps: textureInfos[i].UseMipMaps);
                inputs[i] = new DeviceSampler(
                    scene.LogicalDevice,
                    texture,
                    disposeTexture: true,
                    repeat: textureInfos[i].Repeat,
                    maxAnisotropy: 8f);
            }
        }
        internal DeviceSampler(
            Device logicalDevice,
            DeviceTexture texture,
            bool disposeTexture = true,
            bool repeat         = false,
            bool pointFilter    = false,
            float maxAnisotropy = -1f)
        {
            if (logicalDevice == null)
            {
                throw new ArgumentNullException(nameof(logicalDevice));
            }

            this.texture        = texture;
            this.disposeTexture = disposeTexture;
            sampler             = logicalDevice.CreateSampler(new SamplerCreateInfo {
                MagFilter               = pointFilter ? Filter.Nearest : Filter.Linear,
                MinFilter               = pointFilter ? Filter.Nearest : Filter.Linear,
                AddressModeU            = repeat ? SamplerAddressMode.Repeat : SamplerAddressMode.ClampToEdge,
                AddressModeV            = repeat ? SamplerAddressMode.Repeat : SamplerAddressMode.ClampToEdge,
                AddressModeW            = repeat ? SamplerAddressMode.Repeat : SamplerAddressMode.ClampToEdge,
                AnisotropyEnable        = maxAnisotropy > 0,
                MaxAnisotropy           = maxAnisotropy,
                CompareEnable           = false,
                MipmapMode              = SamplerMipmapMode.Linear,
                MipLodBias              = 0f,
                MinLod                  = 0f,
                MaxLod                  = texture.MipLevels,
                BorderColor             = BorderColor.IntOpaqueBlack,
                UnnormalizedCoordinates = false
            });
        }
        public InstancedObject(
            RenderScene scene,
            Mesh mesh,
            TextureInfo[] textureInfos,
            int maxInstances = 100_000)
        {
            if (scene == null)
            {
                throw new ArgumentNullException(nameof(scene));
            }
            if (mesh == null)
            {
                throw new ArgumentNullException(nameof(mesh));
            }

            //Prepare the inputs
            inputs = new IShaderInput[textureInfos.Length];
            for (int i = 0; i < inputs.Length; i++)
            {
                DeviceTexture texture = DeviceTexture.UploadTexture(
                    texture: textureInfos[i].Texture as IInternalTexture,
                    scene, generateMipMaps: textureInfos[i].UseMipMaps);
                inputs[i] = new DeviceSampler(
                    scene.LogicalDevice,
                    texture,
                    disposeTexture: true,
                    repeat: textureInfos[i].Repeat,
                    maxAnisotropy: 8f);
            }

            //Upload our mesh to the gpu
            deviceMesh = new DeviceMesh(mesh, scene);

            //Allocate a buffers for the instance data and indirect args
            instanceDataBuffer = new Memory.HostBuffer(
                logicalDevice: scene.LogicalDevice,
                memoryPool: scene.MemoryPool,
                usages: BufferUsages.VertexBuffer,
                size: InstanceData.SIZE * maxInstances);
            indirectArgumentsBuffer = new Memory.HostBuffer(
                logicalDevice: scene.LogicalDevice,
                memoryPool: scene.MemoryPool,
                usages: BufferUsages.IndirectBuffer,
                size: DrawIndexedIndirectCommand.SIZE);

            //Write defaults to the indirect args buffer
            indirectArgumentsBuffer.Write(new DrawIndexedIndirectCommand(
                                              indexCount: (uint)deviceMesh.IndexCount,
                                              instanceCount: 0, firstIndex: 0, vertexOffset: 0, firstInstance: 0));
        }
Ejemplo n.º 4
0
        private void CreateSwapchain(int swapchainCount)
        {
            SurfaceCapabilitiesKhr capabilities = hostDevice.GetCurrentCapabilities(surface);

            //Clamp the size to within the min and max extends reported by the surface capabilities
            swapchainSize = nativeWindow.ClientRect.Size.Clamp(
                new Int2(capabilities.MinImageExtent.Width, capabilities.MinImageExtent.Height),
                new Int2(capabilities.MaxImageExtent.Width, capabilities.MaxImageExtent.Height));

            //Gather info about the swapchain
            var createInfo = new SwapchainCreateInfoKhr
                             (
                surface: surface,
                minImageCount: swapchainCount,
                imageFormat: surfaceFormat,
                imageColorSpace: surfaceColorspace,
                imageExtent: new Extent2D(swapchainSize.X, swapchainSize.Y),
                imageArrayLayers: 1,
                imageUsage: ImageUsages.ColorAttachment,

                //If the graphics and present queues are different we need to allow sharing the
                //swapchain images
                imageSharingMode: graphicsQueue.FamilyIndex == presentQueue.FamilyIndex ?
                SharingMode.Exclusive : SharingMode.Concurrent,
                queueFamilyIndices: graphicsQueue.FamilyIndex == presentQueue.FamilyIndex ?
                null : new [] { graphicsQueue.FamilyIndex, presentQueue.FamilyIndex },

                preTransform: capabilities.CurrentTransform,
                compositeAlpha: CompositeAlphasKhr.Opaque,
                presentMode: presentMode,
                clipped: true
                             );

            //Create the swapchain
            swapchain = logicalDevice.CreateSwapchainKhr(createInfo);
            var swapchainImages = swapchain.GetImages();

            //Verify that we got the amount of images we expected
            if (swapchainImages.Length != swapchainCount)
            {
                throw new Exception(
                          $"[{nameof(Window)}] Incorrect number of swapchain images acquired, expected: {swapchainCount}, got: {swapchainImages.Length}");
            }

            //Create the image targets
            swapchainTextures = new DeviceTexture[swapchainCount];
            for (int i = 0; i < swapchainTextures.Length; i++)
            {
                swapchainTextures[i] = DeviceTexture.CreateSwapchainTarget(
                    swapchainSize, surfaceFormat, swapchainImages[i]);
            }

            logger?.Log(nameof(Window),
                        $@"Swapchain created:
{{
    size: {swapchainSize},
    texCount: {swapchainTextures.Length},
    mode: {presentMode},
    format: {surfaceFormat},
    colorSpace: {surfaceColorspace}
}}");
        }