internal static DeviceTexture CreateColorTarget( Int2 size, Format format, Device logicalDevice, Memory.Pool memoryPool, TransientExecutor executor, bool allowSampling = true) { if (logicalDevice == null) { throw new ArgumentNullException(nameof(logicalDevice)); } if (memoryPool == null) { throw new ArgumentNullException(nameof(memoryPool)); } if (executor == null) { throw new ArgumentNullException(nameof(executor)); } var usage = allowSampling ? ImageUsages.ColorAttachment | ImageUsages.Sampled : ImageUsages.ColorAttachment | ImageUsages.TransientAttachment; var aspects = ImageAspects.Color; var image = CreateImage( logicalDevice, format, size, mipLevels: 1, usage, cubeMap: false); var memory = memoryPool.AllocateAndBind(image, Chunk.Location.Device); //Transition the image to the depth attachment layout TransitionImageLayout(image, aspects, baseMipLevel: 0, mipLevels: 1, baseLayer: 0, layers: 1, oldLayout: ImageLayout.Undefined, newLayout: ImageLayout.ColorAttachmentOptimal, executor: executor); var view = CreateView(image, format, mipLevels: 1, aspects, cubeMap: false); return(new DeviceTexture( size, format, ImageLayout.ShaderReadOnlyOptimal, //Used for shader reading mipLevels: 1, aspects, image, memory, view)); }
internal static DeviceTexture UploadTexture( IInternalTexture texture, Device logicalDevice, Memory.Pool memoryPool, Memory.HostBuffer stagingBuffer, TransientExecutor executor, bool generateMipMaps = false) { if (texture == null) { throw new ArgumentNullException(nameof(texture)); } if (logicalDevice == null) { throw new ArgumentNullException(nameof(logicalDevice)); } if (memoryPool == null) { throw new ArgumentNullException(nameof(memoryPool)); } if (stagingBuffer == null) { throw new ArgumentNullException(nameof(stagingBuffer)); } if (executor == null) { throw new ArgumentNullException(nameof(executor)); } int mipLevels = generateMipMaps ? CalculateMipLevels(texture.Size) : 1; int layers = texture.IsCubeMap ? 6 : 1; var aspects = ImageAspects.Color; var image = CreateImage( logicalDevice, texture.Format, texture.Size, mipLevels, //Also include 'TransferSrc' because we read from the image to generate the mip-maps ImageUsages.TransferSrc | ImageUsages.TransferDst | ImageUsages.Sampled, cubeMap: texture.IsCubeMap); var memory = memoryPool.AllocateAndBind(image, Chunk.Location.Device); //Transition the entire image (all mip-levels and layers) to 'TransferDstOptimal' TransitionImageLayout(image, aspects, baseMipLevel: 0, mipLevels, baseLayer: 0, layers, oldLayout: ImageLayout.Undefined, newLayout: ImageLayout.TransferDstOptimal, executor: executor); //Upload the data to mipmap 0 texture.Upload(stagingBuffer, executor, image, aspects); //Create the other mipmap levels Int2 prevMipSize = texture.Size; for (int i = 1; i < mipLevels; i++) { Int2 curMipSize = new Int2( prevMipSize.X > 1 ? prevMipSize.X / 2 : 1, prevMipSize.Y > 1 ? prevMipSize.Y / 2 : 1); //Move the previous mip-level to a transfer source layout TransitionImageLayout(image, aspects, baseMipLevel: i - 1, mipLevels: 1, baseLayer: 0, layers, oldLayout: ImageLayout.TransferDstOptimal, newLayout: ImageLayout.TransferSrcOptimal, executor: executor); //Blit the previous mip-level to the current at half the size BlitImage(aspects, fromImage: image, fromRegion: new IntRect(min: Int2.Zero, max: prevMipSize), fromMipLevel: i - 1, fromLayerCount: layers, toImage: image, toRegion: new IntRect(min: Int2.Zero, max: curMipSize), toMipLevel: i, toLayerCount: layers, executor); //Transition the previous mip-level to the shader-read layout TransitionImageLayout(image, aspects, baseMipLevel: i - 1, mipLevels: 1, baseLayer: 0, layers, oldLayout: ImageLayout.TransferSrcOptimal, newLayout: ImageLayout.ShaderReadOnlyOptimal, executor: executor); //Update the prev mip-size prevMipSize = curMipSize; } //Transition the last mip-level to the shader-read layout TransitionImageLayout(image, aspects, baseMipLevel: mipLevels - 1, mipLevels: 1, baseLayer: 0, layers, oldLayout: ImageLayout.TransferDstOptimal, newLayout: ImageLayout.ShaderReadOnlyOptimal, executor: executor); var view = CreateView( image, texture.Format, mipLevels, aspects, cubeMap: texture.IsCubeMap); return(new DeviceTexture( texture.Size, texture.Format, ImageLayout.ShaderReadOnlyOptimal, //Used for shader reading, mipLevels, aspects, image, memory, view)); }
public RenderScene(Window window, TextureInfo reflectionTexture, ShaderProgram postVertProg, ShaderProgram bloomFragProg, ShaderProgram aoFragProg, ShaderProgram gaussBlurFragProg, ShaderProgram boxBlurFragProg, ShaderProgram compositionFragProg, Logger logger = null) { if (window == null) { throw new ArgumentNullException(nameof(window)); } if (reflectionTexture.Texture == null) { throw new ArgumentNullException(nameof(reflectionTexture)); } if (postVertProg == null) { throw new ArgumentNullException(nameof(postVertProg)); } if (bloomFragProg == null) { throw new ArgumentNullException(nameof(bloomFragProg)); } if (aoFragProg == null) { throw new ArgumentNullException(nameof(aoFragProg)); } if (gaussBlurFragProg == null) { throw new ArgumentNullException(nameof(gaussBlurFragProg)); } if (boxBlurFragProg == null) { throw new ArgumentNullException(nameof(boxBlurFragProg)); } if (compositionFragProg == null) { throw new ArgumentNullException(nameof(compositionFragProg)); } this.window = window; this.logger = logger; camera = new Camera(); //Create resources executor = new TransientExecutor(window.LogicalDevice, window.GraphicsFamilyIndex); memoryPool = new Memory.Pool(window.LogicalDevice, window.HostDevice, logger); stagingBuffer = new Memory.HostBuffer( window.LogicalDevice, memoryPool, BufferUsages.TransferSrc, size: ByteUtils.MegabyteToByte(16)); sceneDataBuffer = new Memory.HostBuffer( window.LogicalDevice, memoryPool, BufferUsages.UniformBuffer, size: SceneData.SIZE * window.SwapchainCount); inputManager = new ShaderInputManager(window.LogicalDevice, logger); //Create techniques gbufferTechnique = new GBufferTechnique(this, logger); shadowTechnique = new ShadowTechnique(this, logger); bloomTechnique = new BloomTechnique( gbufferTechnique, postVertProg, bloomFragProg, gaussBlurFragProg, this, logger); aoTechnique = new AmbientOcclusionTechnique( gbufferTechnique, postVertProg, aoFragProg, boxBlurFragProg, this, logger); deferredTechnique = new DeferredTechnique( gbufferTechnique, shadowTechnique, bloomTechnique, aoTechnique, reflectionTexture, postVertProg, compositionFragProg, this, logger); }