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));
 }
示例#2
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);
        }