Dispatch the Diamond-Square render pass onto a worker queue to keep the main thread free
This commit is contained in:
parent
6a43c10b9f
commit
cb16b84ab9
2 changed files with 26 additions and 16 deletions
|
@ -329,18 +329,24 @@ public class DiamondSquareGenerator: TerrainGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
var algorithm: Algorithm
|
var algorithm: Algorithm
|
||||||
let texture: MTLTexture
|
let textures: [MTLTexture]
|
||||||
let textureSemaphore = DispatchSemaphore(value: 1)
|
private var activeTexture: Int = 0
|
||||||
|
|
||||||
init?(device: MTLDevice) {
|
init?(device: MTLDevice) {
|
||||||
let size = DiamondSquareGenerator.textureSize
|
let size = DiamondSquareGenerator.textureSize
|
||||||
let desc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .r32Float, width: size.width, height: size.height, mipmapped: false)
|
do {
|
||||||
desc.usage = [.shaderRead, .shaderWrite]
|
textures = try (0..<2).map { (i: Int) -> MTLTexture in
|
||||||
guard let tex = device.makeTexture(descriptor: desc) else {
|
let desc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .r32Float, width: size.width, height: size.height, mipmapped: false)
|
||||||
|
desc.usage = [.shaderRead, .shaderWrite]
|
||||||
|
guard let tex = device.makeTexture(descriptor: desc) else {
|
||||||
|
throw KernelError.textureCreationFailed
|
||||||
|
}
|
||||||
|
return tex
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
print("Couldn't create texture for Diamond-Squares algorithm.")
|
print("Couldn't create texture for Diamond-Squares algorithm.")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
texture = tex
|
|
||||||
|
|
||||||
algorithm = Algorithm(grid: Box(origin: Point(), size: Size(w: DiamondSquareGenerator.textureSize.width, h: DiamondSquareGenerator.textureSize.height)))
|
algorithm = Algorithm(grid: Box(origin: Point(), size: Size(w: DiamondSquareGenerator.textureSize.width, h: DiamondSquareGenerator.textureSize.height)))
|
||||||
}
|
}
|
||||||
|
@ -348,13 +354,15 @@ public class DiamondSquareGenerator: TerrainGenerator {
|
||||||
func render() {
|
func render() {
|
||||||
let heightMap = algorithm.render()
|
let heightMap = algorithm.render()
|
||||||
let region = MTLRegion(origin: MTLOrigin(), size: DiamondSquareGenerator.textureSize)
|
let region = MTLRegion(origin: MTLOrigin(), size: DiamondSquareGenerator.textureSize)
|
||||||
texture.replace(region: region, mipmapLevel: 0, withBytes: heightMap, bytesPerRow: MemoryLayout<Float>.stride * DiamondSquareGenerator.textureSize.width)
|
let newActiveTexture = (activeTexture + 1) % textures.count
|
||||||
|
textures[newActiveTexture].replace(region: region, mipmapLevel: 0, withBytes: heightMap, bytesPerRow: MemoryLayout<Float>.stride * DiamondSquareGenerator.textureSize.width)
|
||||||
|
activeTexture = newActiveTexture
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Algorithm
|
// MARK: Algorithm
|
||||||
|
|
||||||
var outTexture: MTLTexture {
|
var outTexture: MTLTexture {
|
||||||
return texture
|
return textures[activeTexture]
|
||||||
}
|
}
|
||||||
|
|
||||||
func encode(in encoder: MTLComputeCommandEncoder) {
|
func encode(in encoder: MTLComputeCommandEncoder) {
|
||||||
|
|
|
@ -34,14 +34,13 @@ class Renderer: NSObject, MTKViewDelegate {
|
||||||
let inFlightSemaphore = DispatchSemaphore(value: maxBuffersInFlight)
|
let inFlightSemaphore = DispatchSemaphore(value: maxBuffersInFlight)
|
||||||
let regenerationSemaphore = DispatchSemaphore(value: 1)
|
let regenerationSemaphore = DispatchSemaphore(value: 1)
|
||||||
|
|
||||||
|
let generatorQueue = DispatchQueue(label: "me.erynwells.Terrain.generatorQueue")
|
||||||
|
|
||||||
var uniformBufferOffset = 0
|
var uniformBufferOffset = 0
|
||||||
|
|
||||||
var uniformBufferIndex = 0
|
var uniformBufferIndex = 0
|
||||||
|
|
||||||
var uniforms: UnsafeMutablePointer<Uniforms>
|
var uniforms: UnsafeMutablePointer<Uniforms>
|
||||||
|
|
||||||
var projectionMatrix: matrix_float4x4 = matrix_float4x4()
|
var projectionMatrix: matrix_float4x4 = matrix_float4x4()
|
||||||
|
|
||||||
var rotation: Float = 0
|
var rotation: Float = 0
|
||||||
|
|
||||||
var terrain: Terrain
|
var terrain: Terrain
|
||||||
|
@ -142,7 +141,13 @@ class Renderer: NSObject, MTKViewDelegate {
|
||||||
|
|
||||||
func scheduleAlgorithmIteration() {
|
func scheduleAlgorithmIteration() {
|
||||||
regenerationSemaphore.wait()
|
regenerationSemaphore.wait()
|
||||||
iterateTerrainAlgorithm = true
|
if !terrain.generator.needsGPU {
|
||||||
|
generatorQueue.async {
|
||||||
|
print("Rendering terrain...")
|
||||||
|
self.terrain.generator.render()
|
||||||
|
print("Rendering terrain...complete!")
|
||||||
|
}
|
||||||
|
}
|
||||||
regenerationSemaphore.signal()
|
regenerationSemaphore.signal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,9 +166,6 @@ class Renderer: NSObject, MTKViewDelegate {
|
||||||
if iterateTerrainAlgorithm {
|
if iterateTerrainAlgorithm {
|
||||||
if terrain.generator.needsGPU {
|
if terrain.generator.needsGPU {
|
||||||
terrain.generator.updateUniforms()
|
terrain.generator.updateUniforms()
|
||||||
} else {
|
|
||||||
print("Rendering terrain...")
|
|
||||||
terrain.generator.render()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +200,7 @@ class Renderer: NSObject, MTKViewDelegate {
|
||||||
|
|
||||||
self.updateGameState()
|
self.updateGameState()
|
||||||
|
|
||||||
if iterateTerrainAlgorithm && !terrain.generator.needsGPU, let computeEncoder = commandBuffer.makeComputeCommandEncoder() {
|
if iterateTerrainAlgorithm && terrain.generator.needsGPU, let computeEncoder = commandBuffer.makeComputeCommandEncoder() {
|
||||||
print("Scheduling terrain generator iteration with \(terrain.generator.name) algorithm")
|
print("Scheduling terrain generator iteration with \(terrain.generator.name) algorithm")
|
||||||
computeEncoder.label = "Generator Encoder"
|
computeEncoder.label = "Generator Encoder"
|
||||||
computeEncoder.pushDebugGroup("Generate Terrain: \(terrain.generator.name)")
|
computeEncoder.pushDebugGroup("Generate Terrain: \(terrain.generator.name)")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue