From a0cac2001b29f274a88988d8554b2bcbb39a04bb Mon Sep 17 00:00:00 2001 From: Rob Bishop Date: Mon, 11 May 2020 18:58:35 -0700 Subject: [PATCH] More paring down for SO --- Foil/FoilViewController.swift | 33 ++++++++--------- Renderer/FoilRenderer.swift | 38 +++++-------------- Simulation/FoilSimulation.swift | 65 +++++---------------------------- 3 files changed, 33 insertions(+), 103 deletions(-) diff --git a/Foil/FoilViewController.swift b/Foil/FoilViewController.swift index 1838a55..a1e74bc 100644 --- a/Foil/FoilViewController.swift +++ b/Foil/FoilViewController.swift @@ -184,29 +184,26 @@ class FoilViewController: NSViewController { // If the simulation and device are using the same device _commandQueue will be set // Create a command buffer to both execute a simulation frame and render an update - if let commandQueue = self.commandQueue, - let commandBuffer = commandQueue.makeCommandBuffer() { - commandBuffer.pushDebugGroup("Controller Frame") + guard let commandQueue = self.commandQueue, + let simulate_render_commandBuffer = commandQueue.makeCommandBuffer() + else { fatalError() } - // Simulate the frame and obtain the new positions for the update. If this is the final - // frame positionBuffer will be filled with the all positions used for the simulation - let positionBuffer = simulation.simulateFrame(commandBuffer: commandBuffer) + simulate_render_commandBuffer.label = "simulate_render_commandBuffer" - // Render the updated positions (or all positions in the case that the simulation is complete) - renderer.drawWithCommandBuffer( - commandBuffer: commandBuffer, - positionsBuffer: positionBuffer, - numBodies: numBodies - ) + // Simulate the frame and obtain the new positions for the update. If this is the final + // frame positionBuffer will be filled with the all positions used for the simulation + let positionsBuffer = simulation.simulateFrame(simulate_render_commandBuffer) - commandBuffer.commit() + // Render the updated positions (or all positions in the case that the simulation is complete) + renderer.draw( + simulate_render_commandBuffer, + positionsBuffer: positionsBuffer, + numBodies: numBodies + ) - commandBuffer.popDebugGroup() + simulate_render_commandBuffer.commit() - simulationTime += Double(config.simInterval) - } else { - renderer.drawProvidedPositionDataWithNumBodies(numParticles: numBodies) - } + simulationTime += Double(config.simInterval) var percentComplete = 0 diff --git a/Renderer/FoilRenderer.swift b/Renderer/FoilRenderer.swift index fe096e4..0f70c62 100644 --- a/Renderer/FoilRenderer.swift +++ b/Renderer/FoilRenderer.swift @@ -25,16 +25,13 @@ class FoilRenderer: NSObject, MTKViewDelegate { // Metal objects var depthState: MTLDepthStencilState! - var dynamicUniformBuffers = [MTLBuffer]() + var dynamicUniformBuffer: MTLBuffer! var positionsBuffer: MTLBuffer! var renderPipeline: MTLRenderPipelineState! let view: MTKView let viewController: FoilViewController - // Current buffer to fill with dynamic uniform data and set for the current frame - var currentBufferIndex = 0 - // Projection matrix calculated as a function of view size var projectionMatrix = matrix_float4x4() @@ -69,12 +66,12 @@ class FoilRenderer: NSObject, MTKViewDelegate { } /// Draw particles at the supplied positions using the given command buffer to the given view - func drawWithCommandBuffer( - commandBuffer: MTLCommandBuffer, + func draw( + _ drawCommandBuffer: MTLCommandBuffer, positionsBuffer: MTLBuffer, numBodies: Int ) { - commandBuffer.pushDebugGroup("Draw Simulation Data") + drawCommandBuffer.label = "Draw Simulation Data" setNumRenderBodies(numBodies) updateState() @@ -83,7 +80,7 @@ class FoilRenderer: NSObject, MTKViewDelegate { // If a renderPassDescriptor has been obtained, render to the drawable, otherwise skip // any rendering this frame because there is no drawable to draw to guard let renderPassDescriptor = view.currentRenderPassDescriptor, - let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) + let renderEncoder = drawCommandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else { fatalError() } renderEncoder.label = "Render Commands" @@ -104,7 +101,7 @@ class FoilRenderer: NSObject, MTKViewDelegate { ) renderEncoder.setVertexBuffer( - dynamicUniformBuffers[currentBufferIndex], + dynamicUniformBuffer, offset: 0, index: Int(FoilRenderBufferIndexUniforms.rawValue) ) @@ -118,9 +115,7 @@ class FoilRenderer: NSObject, MTKViewDelegate { ) renderEncoder.endEncoding() - commandBuffer.present(view.currentDrawable!) - - commandBuffer.popDebugGroup() + drawCommandBuffer.present(view.currentDrawable!) } /// Generates a texture to make rounded points for particles @@ -226,14 +221,14 @@ class FoilRenderer: NSObject, MTKViewDelegate { else { fatalError() } dub.label = "UniformBuffer" - dynamicUniformBuffers.append(dub) + self.dynamicUniformBuffer = dub commandQueue = device.makeCommandQueue() } /// Update any render state (including updating dynamically changing Metal buffers) func updateState() { - let uniforms = dynamicUniformBuffers[currentBufferIndex].contents() + let uniforms = dynamicUniformBuffer.contents() var u = uniforms.assumingMemoryBound(to: FoilUniforms.self).pointee u.pointSize = FoilRenderer.bodyPointSize @@ -286,21 +281,6 @@ class FoilRenderer: NSObject, MTKViewDelegate { } } - func drawProvidedPositionDataWithNumBodies(numParticles: Int) { - // Create a new command buffer for each render pass to the current drawable - guard let commandBuffer = commandQueue.makeCommandBuffer() else { fatalError() } - commandBuffer.label = "Render Command Buffer" - - drawWithCommandBuffer( - commandBuffer: commandBuffer, - positionsBuffer: positionsBuffer, - numBodies: numParticles - ) - - // Finalize rendering here & push the command buffer to the GPU - commandBuffer.commit() - } - func setRenderScale(renderScale: Float) { self.renderScale = renderScale updateProjectionMatrix() diff --git a/Simulation/FoilSimulation.swift b/Simulation/FoilSimulation.swift index 7dfe9bf..5d24049 100644 --- a/Simulation/FoilSimulation.swift +++ b/Simulation/FoilSimulation.swift @@ -110,22 +110,11 @@ class FoilSimulation { ) } - // Execute simulation on another thread, providing updates and final results with supplied blocks - func runAsyncWithUpdateHandler( - updateHandler: @escaping FoilDataUpdateHandler - ) { - simulationDispatchQueue.async { - self.commandQueue = self.device.makeCommandQueue() - - self.runAsyncLoopWithUpdateHandler(updateHandler: updateHandler) - } - } - // Execute a single frame of the simulation (on the current thread) - func simulateFrame(commandBuffer: MTLCommandBuffer) -> MTLBuffer { - commandBuffer.pushDebugGroup("Simulation") + func simulateFrame(_ simulateFrameCommandBuffer: MTLCommandBuffer) -> MTLBuffer { + simulateFrameCommandBuffer.label = "Simulation" - guard let computeEncoder = commandBuffer.makeComputeCommandEncoder() + guard let computeEncoder = simulateFrameCommandBuffer.makeComputeCommandEncoder() else { fatalError() } computeEncoder.label = "Compute Encoder" @@ -148,8 +137,6 @@ class FoilSimulation { oldBufferIndex = newBufferIndex newBufferIndex = tmpIndex - commandBuffer.popDebugGroup() - self.simulationTime += Double(config.simInterval) return positions[newBufferIndex] @@ -321,9 +308,9 @@ class FoilSimulation { /// Blit a subset of the positions data for this frame and provide them to the client /// to show a summary of the simulation's progress func fillUpdateBufferWithPositionBuffer( - buffer: MTLBuffer, usingCommandBuffer commandBuffer: MTLCommandBuffer + buffer: MTLBuffer, blitCommandBuffer: MTLCommandBuffer ) { - guard let blitEncoder = commandBuffer.makeBlitCommandEncoder() else { fatalError() } + guard let blitEncoder = blitCommandBuffer.makeBlitCommandEncoder() else { fatalError() } blitEncoder.label = "Position Update Blit Encoder" blitEncoder.pushDebugGroup("Position Update Blit Commands") @@ -360,10 +347,10 @@ class FoilSimulation { func provideFullData( dataProvider: FoilFullDatasetProvider, forSimulationTime time: CFAbsoluteTime ) { - guard let commandBuffer = commandQueue.makeCommandBuffer() else { fatalError() } - commandBuffer.label = "Full Transfer Command Buffer" + guard let blitCommandBuffer = commandQueue.makeCommandBuffer() else { fatalError() } + blitCommandBuffer.label = "blitCommandBuffer" - guard let blitEncoder = commandBuffer.makeBlitCommandEncoder() else { fatalError() } + guard let blitEncoder = blitCommandBuffer.makeBlitCommandEncoder() else { fatalError() } blitEncoder.label = "Full Transfer Blits" let (positionsBuffer, positionsData) = makeBufferForRenderBodiesVectors( @@ -381,42 +368,8 @@ class FoilSimulation { blitEncoder.endEncoding() - commandBuffer.commit() + blitCommandBuffer.commit() dataProvider(positionsData, velocitiesData, time) } - - /// Run the asynchronous simulation loop - func runAsyncLoopWithUpdateHandler(updateHandler: @escaping FoilDataUpdateHandler) { - var loopCounter = 0 - - repeat { - defer { loopCounter += 1 } - - guard let commandBuffer = commandQueue.makeCommandBuffer() else - { fatalError() } - - let positionBuffer = simulateFrame(commandBuffer: commandBuffer) - - fillUpdateBufferWithPositionBuffer( - buffer: positionBuffer, usingCommandBuffer: commandBuffer - ) - - // Pass data back to client to update it with a summary of progress - guard let updateSimulationTime = simulationTime else { fatalError() } - - addCommandCompletionHandler(commandBuffer, loopCounter) { - updateHandler(self.updateData, updateSimulationTime) - } - - commandBuffer.commit() - - } while(simulationTime < config.simDuration && !halt) - } - - func addCommandCompletionHandler( - _ commandBuffer: MTLCommandBuffer, _ loopCounter: Int, _ updateHandler: @escaping () -> Void - ) { - commandBuffer.addCompletedHandler { _ in updateHandler() } - } }