Skip to content

Commit

Permalink
Split ComputeFilter from AbstractFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnCoates committed Oct 14, 2016
1 parent 84facf4 commit f9af5cd
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 51 deletions.
4 changes: 4 additions & 0 deletions Documentation/Shaders/GaussianBlur.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ https://github.com/mattdesl/lwjgl-basics/wiki/OpenGL-ES-Blurs

https://github.com/Jam3/glsl-fast-gaussian-blur
http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/

Optimizing
https://www.youtube.com/watch?v=HB9LMdldTqU
https://software.intel.com/en-us/blogs/2014/07/15/an-investigation-of-fast-real-time-gpu-based-image-blur-algorithms/?utm_source=ISTV&utm_medium=Video&utm_campaign=ISTV_2016
12 changes: 12 additions & 0 deletions Slate.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
FA2F8E541DA23E5500993949 /* PassthroughFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA2F8E521DA23E5500993949 /* PassthroughFilter.swift */; };
FA4021C61DA0AEE800752F3B /* MetalCameraController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4021C51DA0AEE800752F3B /* MetalCameraController.swift */; };
FA4021C71DA0AEE800752F3B /* MetalCameraController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4021C51DA0AEE800752F3B /* MetalCameraController.swift */; };
FA4D54161DB055A00091184D /* FragmentFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4D54151DB055A00091184D /* FragmentFilter.swift */; };
FA4D54171DB055A00091184D /* FragmentFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4D54151DB055A00091184D /* FragmentFilter.swift */; };
FA4D54191DB055BB0091184D /* ComputeFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4D54181DB055BB0091184D /* ComputeFilter.swift */; };
FA4D541A1DB055BB0091184D /* ComputeFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4D54181DB055BB0091184D /* ComputeFilter.swift */; };
FA4DFED11D9DBD1A0068706F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4DFED01D9DBD1A0068706F /* AppDelegate.swift */; };
FA4DFED31D9DBD1A0068706F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA4DFED21D9DBD1A0068706F /* Assets.xcassets */; };
FA4DFED61D9DBD1A0068706F /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA4DFED41D9DBD1A0068706F /* MainMenu.xib */; };
Expand Down Expand Up @@ -131,6 +135,8 @@
FA2F8E4D1DA22AD700993949 /* ChromaticAberrationFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChromaticAberrationFilter.swift; sourceTree = "<group>"; };
FA2F8E521DA23E5500993949 /* PassthroughFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PassthroughFilter.swift; sourceTree = "<group>"; };
FA4021C51DA0AEE800752F3B /* MetalCameraController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalCameraController.swift; sourceTree = "<group>"; };
FA4D54151DB055A00091184D /* FragmentFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FragmentFilter.swift; sourceTree = "<group>"; };
FA4D54181DB055BB0091184D /* ComputeFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComputeFilter.swift; sourceTree = "<group>"; };
FA4DFECE1D9DBD1A0068706F /* macSlate.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = macSlate.app; sourceTree = BUILT_PRODUCTS_DIR; };
FA4DFED01D9DBD1A0068706F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
FA4DFED21D9DBD1A0068706F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
Expand Down Expand Up @@ -289,6 +295,8 @@
isa = PBXGroup;
children = (
FA2F8E461DA2293000993949 /* AbstractFilter.swift */,
FA4D54151DB055A00091184D /* FragmentFilter.swift */,
FA4D54181DB055BB0091184D /* ComputeFilter.swift */,
);
path = Abstract;
sourceTree = "<group>";
Expand Down Expand Up @@ -830,7 +838,9 @@
FABB16AE1D9F6DAB00A8AC6C /* ChromaticAberration.metal in Sources */,
FA4DFED11D9DBD1A0068706F /* AppDelegate.swift in Sources */,
FA4021C71DA0AEE800752F3B /* MetalCameraController.swift in Sources */,
FA4D541A1DB055BB0091184D /* ComputeFilter.swift in Sources */,
FABB169F1D9F308C00A8AC6C /* Vertices.swift in Sources */,
FA4D54171DB055A00091184D /* FragmentFilter.swift in Sources */,
FABB16B31D9F858800A8AC6C /* Platform.swift in Sources */,
FABB16B21D9F822800A8AC6C /* CameraController.swift in Sources */,
FA2F8E4B1DA2296E00993949 /* GaussianBlurFilter.swift in Sources */,
Expand All @@ -846,11 +856,13 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FA4D54191DB055BB0091184D /* ComputeFilter.swift in Sources */,
FABB16A21D9F402C00A8AC6C /* TextureCoordinates.swift in Sources */,
FA2F8E4E1DA22AD700993949 /* ChromaticAberrationFilter.swift in Sources */,
FAADE0D01D9D0AC200AA5729 /* Renderer.swift in Sources */,
FA834BDD1D9920010017CCCA /* Platform.swift in Sources */,
FABB16AD1D9F6DAB00A8AC6C /* ChromaticAberration.metal in Sources */,
FA4D54161DB055A00091184D /* FragmentFilter.swift in Sources */,
FA2F8E531DA23E5500993949 /* PassthroughFilter.swift in Sources */,
FA834BE41D9929710017CCCA /* CaptureButton.swift in Sources */,
FA2F8E471DA2293000993949 /* AbstractFilter.swift in Sources */,
Expand Down
48 changes: 0 additions & 48 deletions Source/Rendering/Filters/Abstract/AbstractFilter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,54 +14,6 @@ class AbstractFilter {
let device: MTLDevice
init(device: MTLDevice) {
self.device = device
buildPipeline()
}

func buildPipeline() {
fatalError("Filter \(self) must implement buildPipeline()")
}

// MARK: - Textures

fileprivate var outputTexture: MTLTexture?
func outputTexture(forInputTexture inputTexture: MTLTexture) -> MTLTexture {
if let outputTexture = outputTexture {
if outputTexture.width == inputTexture.width, outputTexture.height == inputTexture.height {
return outputTexture
}

}
let descriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .bgra8Unorm,
width: inputTexture.width,
height: inputTexture.height,
mipmapped: false)
descriptor.usage = [.shaderRead, .shaderWrite, .renderTarget]
let texture = device.makeTexture(descriptor: descriptor)
outputTexture = texture
return texture
}

// MARK: - Thread Groups

// TODO: check device.maxThreadsPerThreadgroup
lazy var threadsPerGroup: MTLSize = MTLSize(width: 22, height: 22, depth: 1)
fileprivate var threadGroups: MTLSize?
fileprivate var threadTextureSize: MTLSize?
func threadGroups(forInputTexture inputTexture: MTLTexture) -> MTLSize {
if let threadGroups = threadGroups, let threadTextureSize = threadTextureSize {
if threadTextureSize.width == inputTexture.width,
threadTextureSize.height == inputTexture.height {
return threadGroups
}
}
let widthSteps = inputTexture.width / threadsPerGroup.width
let heightSteps = inputTexture.height / threadsPerGroup.height
let groups = MTLSizeMake(widthSteps, heightSteps, 1)
threadGroups = groups
threadTextureSize = MTLSize(width: inputTexture.width,
height: inputTexture.height,
depth: inputTexture.depth)
return groups
}

// MARK: - Filtering
Expand Down
64 changes: 64 additions & 0 deletions Source/Rendering/Filters/Abstract/ComputeFilter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// AbstractComputeFilter.swift
// Slate
//
// Created by John Coates on 10/13/16.
// Copyright © 2016 John Coates. All rights reserved.
//

import Foundation
import MetalKit

class ComputeFilter: AbstractFilter {
override init(device: MTLDevice) {
super.init(device: device)
buildPipeline()
}

func buildPipeline() {
fatalError("Filter \(self) must implement buildPipeline()")
}

// MARK: - Textures

fileprivate var outputTexture: MTLTexture?
func outputTexture(forInputTexture inputTexture: MTLTexture) -> MTLTexture {
if let outputTexture = outputTexture {
if outputTexture.width == inputTexture.width, outputTexture.height == inputTexture.height {
return outputTexture
}

}
let descriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .bgra8Unorm,
width: inputTexture.width,
height: inputTexture.height,
mipmapped: false)
descriptor.usage = [.shaderRead, .shaderWrite, .renderTarget]
let texture = device.makeTexture(descriptor: descriptor)
outputTexture = texture
return texture
}

// MARK: - Thread Groups

// TODO: check device.maxThreadsPerThreadgroup
lazy var threadsPerGroup: MTLSize = MTLSize(width: 22, height: 22, depth: 1)
fileprivate var threadGroups: MTLSize?
fileprivate var threadTextureSize: MTLSize?
func threadGroups(forInputTexture inputTexture: MTLTexture) -> MTLSize {
if let threadGroups = threadGroups, let threadTextureSize = threadTextureSize {
if threadTextureSize.width == inputTexture.width,
threadTextureSize.height == inputTexture.height {
return threadGroups
}
}
let widthSteps = inputTexture.width / threadsPerGroup.width
let heightSteps = inputTexture.height / threadsPerGroup.height
let groups = MTLSizeMake(widthSteps, heightSteps, 1)
threadGroups = groups
threadTextureSize = MTLSize(width: inputTexture.width,
height: inputTexture.height,
depth: inputTexture.depth)
return groups
}
}
9 changes: 9 additions & 0 deletions Source/Rendering/Filters/Abstract/FragmentFilter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// AbstractFragmentFilter.swift
// Slate
//
// Created by John Coates on 10/13/16.
// Copyright © 2016 John Coates. All rights reserved.
//

import Foundation
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import Foundation
import MetalKit

final class ChromaticAberrationFilter: AbstractFilter {
final class ChromaticAberrationFilter: ComputeFilter {

var pipelineState: MTLComputePipelineState!
override func buildPipeline() {
Expand Down
1 change: 1 addition & 0 deletions Source/UI/Capture/Metal/Controllers/CameraController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class CameraController: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {
return AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
}
}

func startCapturingVideo() {
session.beginConfiguration()

Expand Down
4 changes: 2 additions & 2 deletions Source/UI/Capture/Metal/Shaders/ChromaticAberration.metal
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ struct VertexOut {
float2 textureCoordinates [[user(texturecoord)]];
};

fragment float4 fragmentShader(VertexOut fragmentIn [[ stage_in ]],
texture2d<float, access::sample> texture [[texture(0)]]) {
fragment float4 chromaticAberrationFragment(VertexOut fragmentIn [[ stage_in ]],
texture2d<float, access::sample> texture [[texture(0)]]) {
float2 coordinates = fragmentIn.textureCoordinates;
constexpr sampler qsampler;
float4 color = texture.sample(qsampler, coordinates);
Expand Down

0 comments on commit f9af5cd

Please sign in to comment.