public void UpdateInstances(ReadOnlySpan <InstanceData> instances) { instanceDataBuffer.Write(instances); indirectArgumentsBuffer.Write(new DrawIndexedIndirectCommand( indexCount: (uint)deviceMesh.IndexCount, instanceCount: (uint)instances.Length, firstIndex: 0, vertexOffset: 0, firstInstance: 0)); }
internal void PreDraw(FrameTracker tracker, int swapchainIndex) { //Update the scene data SceneData sceneData = new SceneData( tracker.FrameNumber, (float)tracker.ElapsedTime, tracker.DeltaTime); sceneDataBuffer.Write(sceneData, SceneData.SIZE * swapchainIndex); gbufferTechnique.PreDraw(swapchainIndex); shadowTechnique.PreDraw(swapchainIndex, sunDirection, shadowDistance); }
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)); }
internal static DeviceBuffer UploadData <T>( ReadOnlySpan <T> data, Device logicalDevice, Pool memoryPool, BufferUsages usages, HostBuffer stagingBuffer, TransientExecutor executor) where T : struct { //First write the data to the staging buffer int size = stagingBuffer.Write <T>(data, offset: 0); //Then create a device buffer with that size DeviceBuffer targetBuffer = new DeviceBuffer(logicalDevice, memoryPool, usages, size); //Then copy the data from the staging buffer to the devicebuffer executor.ExecuteBlocking(commandBuffer => { commandBuffer.CmdCopyBuffer( srcBuffer: stagingBuffer.VulkanBuffer, dstBuffer: targetBuffer.VulkanBuffer, new BufferCopy(size: size, srcOffset: 0, dstOffset: 0)); }); return(targetBuffer); }