fix: Fixes for parsing, improved errors, more robust LUT image loading

This commit is contained in:
Stuart Carnie
2022-12-24 09:20:49 +11:00
parent 6f078630c4
commit 355693636a
4 changed files with 65 additions and 24 deletions
+8
View File
@@ -248,6 +248,14 @@ struct ConfigScanner {
return false
}
if scalars[pos] == "/" {
let peek = scalars.index(after: pos)
if peek != scalars.endIndex, scalars[pos] == "/" {
// comments can also be //
return false
}
}
return true
}
+30 -1
View File
@@ -944,7 +944,11 @@ public final class FilterChain {
let t: MTLTexture
do {
let data = try cc.getLUTByName(lut.name)
t = try loader.newTexture(data: data, options: opts)
if let cgImg = CGContext.makeForTexture(data: data)?.makeImage() {
t = try loader.newTexture(cgImage: cgImg, options: opts)
} else {
t = checkers
}
} catch {
os_log("Unable to load LUT texture, using default. Path '%{public}@: %{public}@", log: .default, type: .error,
lut.url.absoluteString, error.localizedDescription)
@@ -1234,3 +1238,28 @@ extension MTLPixelFormat {
}
}
}
extension CGContext {
/// Returns a context using the dimensions and contents from the image identified by the data.
/// The context data format is compatible with BGRA8
/// - Parameter data: The data of the source image.
/// - Returns: a new ``CGContext`` with dimensions and contents matching the source image.
static func makeForTexture(data: Data) -> CGContext? {
guard
let src = CGImageSourceCreateWithData(data as CFData, nil),
let img = CGImageSourceCreateImageAtIndex(src, CGImageSourceGetPrimaryImageIndex(src), nil)
else { return nil }
guard let context = CGContext(data: nil,
width: img.width, height: img.height,
bitsPerComponent: 8, bytesPerRow: img.width * 4,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue)
else { return nil }
context.interpolationQuality = .none
context.draw(img, in: CGRect(x: 0, y: 0, width: img.width, height: img.height))
return context
}
}
+11 -11
View File
@@ -80,18 +80,18 @@ class SlangCompiler {
guard shader.preprocess(input: &inp)
else {
let msg = shader.preprocessed_code
os_log(.error, log: .default, "Error preprocessing shader: %{public}s", msg)
let msg = String(cString: shader.info_log)
os_log(.error, log: .default, "Error preprocessing shader: %{public}@", msg)
throw SlangCompilerError.preprocess(reason: String(cString: msg))
throw SlangCompilerError.preprocess(reason: msg)
}
guard shader.parse(input: &inp)
else {
let msg = shader.preprocessed_code
os_log(.error, log: .default, "Error parsing shader: %{public}s", msg)
let msg = String(cString: shader.info_log)
os_log(.error, log: .default, "Error parsing shader: %{public}@", msg)
throw SlangCompilerError.parse(reason: String(cString: msg))
throw SlangCompilerError.parse(reason: msg)
}
let program = CGLSLangProgram()
@@ -101,13 +101,13 @@ class SlangCompiler {
guard program.link(messages: inp.messages)
else {
let infoLog = program.info_log
let infoDebugLog = program.info_debug_log
let infoLog = String(cString: program.info_log)
let infoDebugLog = String(cString: program.info_debug_log)
os_log(.error, log: .default, "Error linking shader info log: %{public}s", infoLog)
os_log(.error, log: .default, "Error linking shader info debug log: %{public}s", infoDebugLog)
os_log(.error, log: .default, "Error linking shader info log: %{public}@", infoLog)
os_log(.error, log: .default, "Error linking shader info debug log: %{public}@", infoDebugLog)
throw SlangCompilerError.link(reason: String(cString: infoLog))
throw SlangCompilerError.link(reason: infoLog)
}
program.spirv_generate(stage: stage)
+16 -12
View File
@@ -183,15 +183,12 @@ class SourceParser {
var oe = lines.makeIterator()
if isRoot {
let line = oe.next()
switch line?.hasPrefix(Prefixes.version) {
case .some(false), .none:
guard let line = oe.next(), line.hasPrefix(Prefixes.version) else {
throw SourceParserError.missingVersion
default:
buffer.append(line!)
buffer.append("#extension GL_GOOGLE_cpp_style_line_directive : require")
lno += 1
}
buffer.append(line)
buffer.append("#extension GL_GOOGLE_cpp_style_line_directive : require")
lno += 1
}
buffer.append("#line \(lno) \"\(filename)\"")
@@ -213,16 +210,21 @@ class SourceParser {
included.insert(file.absoluteString)
}
} else {
buffer.append(line)
var hasPreprocessor = false
let hasPreprocessor: Bool
if line.hasPrefix(Prefixes.pragma) {
hasPreprocessor = true
try processPragma(line: line)
if try processPragma(line: line) {
// skip line
continue
}
} else if line.hasPrefix(Prefixes.endif) {
hasPreprocessor = true
} else {
hasPreprocessor = false
}
buffer.append(line)
if hasPreprocessor {
buffer.append("#line \(lno + 1) \"\(filename)\"")
}
@@ -237,7 +239,7 @@ class SourceParser {
return set as CharacterSet
}
private func processPragma(line: String) throws {
private func processPragma(line: String) throws -> Bool {
if line.hasPrefix(Prefixes.pragmaName) {
if name != nil {
throw SourceParserError.multipleNamePragma
@@ -303,6 +305,8 @@ class SourceParser {
throw SourceParserError.invalidFormatPragma
}
}
return !line.hasPrefix(Prefixes.pragmaStage)
}
}