using System; using System.Runtime.InteropServices; using UnityEngine; namespace FidelityFX { public static class FfxSpd { public static void SetupSpdConstants(Vector2Int resolution, ref SpdConstants spdConstants, out Vector2Int dispatchThreadGroupCount, int mips = -1) { RectInt rectInfo = new RectInt(0, 0, resolution.x, resolution.y); SpdSetup(rectInfo, out dispatchThreadGroupCount, out Vector2Int workGroupOffset, out Vector2Int numWorkGroupsAndMips, mips); spdConstants.numWorkGroups = (uint)numWorkGroupsAndMips.x; spdConstants.mips = (uint)numWorkGroupsAndMips.y; spdConstants.workGroupOffsetX = (uint)workGroupOffset.x; spdConstants.workGroupOffsetY = (uint)workGroupOffset.y; } public static void SpdSetup(RectInt rectInfo, out Vector2Int dispatchThreadGroupCount, out Vector2Int workGroupOffset, out Vector2Int numWorkGroupsAndMips, int mips = -1) { workGroupOffset = new Vector2Int(rectInfo.x / 64, rectInfo.y / 64); int endIndexX = (rectInfo.x + rectInfo.width - 1) / 64; int endIndexY = (rectInfo.y + rectInfo.height - 1) / 64; dispatchThreadGroupCount = new Vector2Int(endIndexX + 1 - workGroupOffset.x, endIndexY + 1 - workGroupOffset.y); numWorkGroupsAndMips = new Vector2Int(dispatchThreadGroupCount.x * dispatchThreadGroupCount.y, mips); if (mips < 0) { float resolution = Math.Max(rectInfo.width, rectInfo.height); numWorkGroupsAndMips.y = Math.Min(Mathf.FloorToInt(Mathf.Log(resolution, 2.0f)), 12); } } [Serializable, StructLayout(LayoutKind.Sequential)] public struct SpdConstants { public uint mips; public uint numWorkGroups; public uint workGroupOffsetX; public uint workGroupOffsetY; } } }