Created
September 27, 2025 18:25
-
-
Save philipturner/48c48b903299505d60151a8c8a89af2d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #if os(Windows) | |
| import FidelityFX | |
| import SwiftCOM | |
| import WinSDK | |
| // Old reference code that just exists to make sure FidelityFX links properly. | |
| public struct FFXUpscalerDescriptor { | |
| public var device: Device? | |
| public init() { | |
| } | |
| } | |
| public class FFXUpscaler { | |
| let d3d12Device: SwiftCOM.ID3D12Device | |
| public init(descriptor: FFXUpscalerDescriptor) { | |
| guard let device = descriptor.device else { | |
| fatalError("Descriptor was incomplete.") | |
| } | |
| self.d3d12Device = device.d3d12Device | |
| } | |
| public func createContext() -> ffxContext { | |
| // Set the backend header. | |
| let createBackend = UnsafeMutablePointer<ffxCreateBackendDX12Desc> | |
| .allocate(capacity: 1) | |
| createBackend.pointee.header.type = UInt64( | |
| FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_DX12) | |
| createBackend.pointee.header.pNext = nil | |
| do { | |
| // Retrieve the DirectX device. | |
| // | |
| // I did not balance this with a call to `IUnknown::Release`, so something | |
| // bad is probably going to happen eventually. I would like to wait until | |
| // after the `ffxContext` is created. Otherwise, semantically, the | |
| // device could be deallocated before reaching that function. | |
| // | |
| // Probably best solved with a deinitializer, once this code matures. | |
| let iid = SwiftCOM.ID3D12Device.IID | |
| let interface = try! d3d12Device.QueryInterface(iid: iid) | |
| let device = interface!.assumingMemoryBound(to: WinSDK.ID3D12Device.self) | |
| createBackend.pointee.device = device | |
| } | |
| // Set the upscale header. | |
| let createUpscale = UnsafeMutablePointer<ffxCreateContextDescUpscale> | |
| .allocate(capacity: 1) | |
| createUpscale.pointee.header.type = UInt64( | |
| FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE) | |
| createBackend.withMemoryRebound( | |
| to: ffxApiHeader.self, capacity: 1 | |
| ) { pointer in | |
| createUpscale.pointee.header.pNext = pointer | |
| } | |
| do { | |
| // Invert the depth, but keep the range at [1, 0]. This is for compatibility | |
| // with the Metal implementation, which uses 'isDepthReversed = true'. | |
| createUpscale.pointee.flags = | |
| UInt32(FFX_UPSCALE_ENABLE_DEPTH_INVERTED.rawValue) | |
| // Set the input dimensions as 480x480. | |
| let rayTracedTextureSize: Int = 480 | |
| var rayTracedDimensions = FfxApiDimensions2D() | |
| rayTracedDimensions.width = UInt32(rayTracedTextureSize) | |
| rayTracedDimensions.height = UInt32(rayTracedTextureSize) | |
| createUpscale.pointee.maxRenderSize = rayTracedDimensions | |
| // Set the output dimensions as 1440x1440. | |
| let upscaledSize: Int = 1440 | |
| var upscaledDimensions = FfxApiDimensions2D() | |
| upscaledDimensions.width = UInt32(upscaledSize) | |
| upscaledDimensions.height = UInt32(upscaledSize) | |
| createUpscale.pointee.maxUpscaleSize = upscaledDimensions | |
| } | |
| // Set the callback to crash on all warnings. | |
| createUpscale.pointee.fpMessage = { type, message in | |
| print("[FidelityFX] Encountered message of type \(type).") | |
| if let message { | |
| let string = String(decodingCString: message, as: UTF16.self) | |
| print("[FidelityFX] \(string)") | |
| } else { | |
| print("[FidelityFX] Message was a null pointer.") | |
| } | |
| fatalError() | |
| } | |
| // Create the FFX object context. | |
| var upscaleContext: ffxContext? = nil | |
| createUpscale.withMemoryRebound( | |
| to: ffxApiHeader.self, capacity: 1 | |
| ) { pointer in | |
| let error = ffxCreateContext( | |
| &upscaleContext, pointer, nil) | |
| guard error == 0 else { | |
| fatalError("Failed to create context. Received error code \(error).") | |
| } | |
| } | |
| guard let upscaleContext else { | |
| fatalError("Could not create context.") | |
| } | |
| return upscaleContext | |
| } | |
| } | |
| #endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment