Skip to content

Commit

Permalink
More paring down for SO
Browse files Browse the repository at this point in the history
  • Loading branch information
SaganRitual committed May 12, 2020
1 parent 1e78735 commit a0cac20
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 103 deletions.
33 changes: 15 additions & 18 deletions Foil/FoilViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
38 changes: 9 additions & 29 deletions Renderer/FoilRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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()
Expand All @@ -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"
Expand All @@ -104,7 +101,7 @@ class FoilRenderer: NSObject, MTKViewDelegate {
)

renderEncoder.setVertexBuffer(
dynamicUniformBuffers[currentBufferIndex],
dynamicUniformBuffer,
offset: 0, index: Int(FoilRenderBufferIndexUniforms.rawValue)
)

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
65 changes: 9 additions & 56 deletions Simulation/FoilSimulation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -148,8 +137,6 @@ class FoilSimulation {
oldBufferIndex = newBufferIndex
newBufferIndex = tmpIndex

commandBuffer.popDebugGroup()

self.simulationTime += Double(config.simInterval)

return positions[newBufferIndex]
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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(
Expand All @@ -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() }
}
}

0 comments on commit a0cac20

Please sign in to comment.