From f328cbbec8ddeb23fb2ef5ac077821a38c70b16c Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Sun, 16 Mar 2025 15:20:25 -0400 Subject: [PATCH] Move around common MSL Signed-off-by: Isaac Marovitz --- XenosRecomp/shader_common.h | 200 ++++++++++++++++++++++ XenosRecomp/shader_common_msl.metal | 248 ---------------------------- 2 files changed, 200 insertions(+), 248 deletions(-) delete mode 100644 XenosRecomp/shader_common_msl.metal diff --git a/XenosRecomp/shader_common.h b/XenosRecomp/shader_common.h index 7f32cd0..6858a08 100644 --- a/XenosRecomp/shader_common.h +++ b/XenosRecomp/shader_common.h @@ -34,6 +34,46 @@ struct PushConstants #define g_SpecConstants() g_SpecConstants +#elif __air__ + +#include + +using namespace metal; + +constant uint G_SPEC_CONSTANT [[function_constant(0)]]; + +uint g_SpecConstants() { + return G_SPEC_CONSTANT; +} + +constant uint SPEC_CONSTANT_R11G11B10_NORMAL = (1 << 0); +constant uint SPEC_CONSTANT_ALPHA_TEST = (1 << 1); +constant uint SPEC_CONSTANT_BICUBIC_GI_FILTER = (1 << 2); +constant uint SPEC_CONSTANT_ALPHA_TO_COVERAGE = (1 << 3); +constant uint SPEC_CONSTANT_REVERSE_Z = (1 << 4); + +struct PushConstants +{ + ulong vertexShaderConstants; + ulong pixelShaderConstants; + ulong sharedConstants; +}; + +uint g_Booleans(constant PushConstants& constants) +{ + return *(reinterpret_cast(constants.sharedConstants + 256)); +} + +uint g_SwappedTexcoords(constant PushConstants& constants) +{ + return *(reinterpret_cast(constants.sharedConstants + 260)); +} + +float g_AlphaThreshold(constant PushConstants& constants) +{ + return *(reinterpret_cast(constants.sharedConstants + 264)); +} + #else #define DEFINE_SHARED_CONSTANTS() \ @@ -45,6 +85,56 @@ uint g_SpecConstants(); #endif +#ifdef __air__ + +struct Texture2DDescriptorHeap +{ + array, 1> g [[id(0)]]; +}; + +struct Texture3DDescriptorHeap +{ + array, 1> g [[id(0)]]; +}; + +struct TextureCubeDescriptorHeap +{ + array, 1> g [[id(0)]]; +}; + +struct SamplerDescriptorHeap +{ + array g [[id(0)]]; +}; + +uint2 getTexture2DDimensions(texture2d texture) +{ + return uint2(texture.get_width(), texture.get_height()); +} + +float4 tfetch2D(constant Texture2DDescriptorHeap& textureHeap, + constant SamplerDescriptorHeap& samplerHeap, + uint resourceDescriptorIndex, + uint samplerDescriptorIndex, + float2 texCoord, float2 offset) +{ + texture2d texture = textureHeap.g[resourceDescriptorIndex]; + sampler sampler = samplerHeap.g[samplerDescriptorIndex]; + return texture.sample(sampler, texCoord + offset / (float2)getTexture2DDimensions(texture)); +} + +float2 getWeights2D(constant Texture2DDescriptorHeap& textureHeap, + constant SamplerDescriptorHeap& samplerHeap, + uint resourceDescriptorIndex, + uint samplerDescriptorIndex, + float2 texCoord, float2 offset) +{ + texture2d texture = textureHeap.g[resourceDescriptorIndex]; + return select(fract(texCoord * (float2)getTexture2DDimensions(texture) + offset - 0.5), 0.0, isnan(texCoord)); +} + +#else + Texture2D g_Texture2DDescriptorHeap[] : register(t0, space0); Texture3D g_Texture3DDescriptorHeap[] : register(t0, space1); TextureCube g_TextureCubeDescriptorHeap[] : register(t0, space2); @@ -69,6 +159,8 @@ float2 getWeights2D(uint resourceDescriptorIndex, uint samplerDescriptorIndex, f return select(isnan(texCoord), 0.0, frac(texCoord * getTexture2DDimensions(texture) + offset - 0.5)); } +#endif + float w0(float a) { return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f); @@ -109,6 +201,74 @@ float h1(float a) return 1.0f + w3(a) / (w2(a) + w3(a)) + 0.5f; } +#ifdef __air__ + +float4 tfetch2DBicubic(constant Texture2DDescriptorHeap& textureHeap, + constant SamplerDescriptorHeap& samplerHeap, + uint resourceDescriptorIndex, + uint samplerDescriptorIndex, + float2 texCoord, float2 offset) +{ + texture2d texture = textureHeap.g[resourceDescriptorIndex]; + sampler sampler = samplerHeap.g[samplerDescriptorIndex]; + uint2 dimensions = getTexture2DDimensions(texture); + + float x = texCoord.x * dimensions.x + offset.x; + float y = texCoord.y * dimensions.y + offset.y; + + x -= 0.5f; + y -= 0.5f; + float px = floor(x); + float py = floor(y); + float fx = x - px; + float fy = y - py; + + float g0x = g0(fx); + float g1x = g1(fx); + float h0x = h0(fx); + float h1x = h1(fx); + float h0y = h0(fy); + float h1y = h1(fy); + + float4 r = + g0(fy) * (g0x * texture.sample(sampler, float2(px + h0x, py + h0y) / float2(dimensions)) + + g1x * texture.sample(sampler, float2(px + h1x, py + h0y) / float2(dimensions))) + + g1(fy) * (g0x * texture.sample(sampler, float2(px + h0x, py + h1y) / float2(dimensions)) + + g1x * texture.sample(sampler, float2(px + h1x, py + h1y) / float2(dimensions))); + + return r; +} + +float4 tfetch3D(constant Texture3DDescriptorHeap& textureHeap, + constant SamplerDescriptorHeap& samplerHeap, + uint resourceDescriptorIndex, + uint samplerDescriptorIndex, + float3 texCoord) +{ + texture3d texture = textureHeap.g[resourceDescriptorIndex]; + sampler sampler = samplerHeap.g[samplerDescriptorIndex]; + return texture.sample(sampler, texCoord); +} + +struct CubeMapData +{ + float3 cubeMapDirections[2]; + uint cubeMapIndex; +}; + +float4 tfetchCube(constant TextureCubeDescriptorHeap& textureHeap, + constant SamplerDescriptorHeap& samplerHeap, + uint resourceDescriptorIndex, + uint samplerDescriptorIndex, + float3 texCoord, thread CubeMapData* cubeMapData) +{ + texturecube texture = textureHeap.g[resourceDescriptorIndex]; + sampler sampler = samplerHeap.g[samplerDescriptorIndex]; + return texture.sample(sampler, cubeMapData->cubeMapDirections[(uint)texCoord.z]); +} + +#else + float4 tfetch2DBicubic(uint resourceDescriptorIndex, uint samplerDescriptorIndex, float2 texCoord, float2 offset) { Texture2D texture = g_Texture2DDescriptorHeap[resourceDescriptorIndex]; @@ -157,6 +317,8 @@ float4 tfetchCube(uint resourceDescriptorIndex, uint samplerDescriptorIndex, flo return g_TextureCubeDescriptorHeap[resourceDescriptorIndex].Sample(g_SamplerDescriptorHeap[samplerDescriptorIndex], cubeMapData.cubeMapDirections[texCoord.z]); } +#endif + float4 tfetchR11G11B10(uint4 value) { if (g_SpecConstants() & SPEC_CONSTANT_R11G11B10_NORMAL) @@ -169,7 +331,11 @@ float4 tfetchR11G11B10(uint4 value) } else { +#ifdef __air__ + return (float4)value; +#else return asfloat(value); +#endif } } @@ -178,6 +344,19 @@ float4 tfetchTexcoord(uint swappedTexcoords, float4 value, uint semanticIndex) return (swappedTexcoords & (1ull << semanticIndex)) != 0 ? value.yxwz : value; } +#ifdef __air__ + +float4 cube(float4 value, thread CubeMapData* cubeMapData) +{ + uint index = cubeMapData->cubeMapIndex; + cubeMapData->cubeMapDirections[index] = value.xyz; + ++cubeMapData->cubeMapIndex; + + return float4(0.0, 0.0, 0.0, index); +} + +#else + float4 cube(float4 value, inout CubeMapData cubeMapData) { uint index = cubeMapData.cubeMapIndex; @@ -187,6 +366,8 @@ float4 cube(float4 value, inout CubeMapData cubeMapData) return float4(0.0, 0.0, 0.0, index); } +#endif + float4 dst(float4 src0, float4 src1) { float4 dest; @@ -202,15 +383,34 @@ float4 max4(float4 src0) return max(max(src0.x, src0.y), max(src0.z, src0.w)); } +#ifdef __air__ + +float2 getPixelCoord(constant Texture2DDescriptorHeap& textureHeap, + uint resourceDescriptorIndex, + float2 texCoord) +{ + texture2d texture = textureHeap.g[resourceDescriptorIndex]; + return (float2)getTexture2DDimensions(texture) * texCoord; +} + +#else + float2 getPixelCoord(uint resourceDescriptorIndex, float2 texCoord) { return getTexture2DDimensions(g_Texture2DDescriptorHeap[resourceDescriptorIndex]) * texCoord; } +#endif + float computeMipLevel(float2 pixelCoord) { +#ifdef __air__ + float2 dx = dfdx(pixelCoord); + float2 dy = dfdy(pixelCoord); +#else float2 dx = ddx(pixelCoord); float2 dy = ddy(pixelCoord); +#endif float deltaMaxSqr = max(dot(dx, dx), dot(dy, dy)); return max(0.0, 0.5 * log2(deltaMaxSqr)); } diff --git a/XenosRecomp/shader_common_msl.metal b/XenosRecomp/shader_common_msl.metal deleted file mode 100644 index ecc377e..0000000 --- a/XenosRecomp/shader_common_msl.metal +++ /dev/null @@ -1,248 +0,0 @@ -#include - -using namespace metal; - -constant uint G_SPEC_CONSTANT [[function_constant(0)]]; - -uint g_SpecConstants() { - return G_SPEC_CONSTANT; -} - -constant uint SPEC_CONSTANT_R11G11B10_NORMAL = (1 << 0); -constant uint SPEC_CONSTANT_ALPHA_TEST = (1 << 1); -constant uint SPEC_CONSTANT_BICUBIC_GI_FILTER = (1 << 2); -constant uint SPEC_CONSTANT_ALPHA_TO_COVERAGE = (1 << 3); -constant uint SPEC_CONSTANT_REVERSE_Z = (1 << 4); - -struct PushConstants -{ - ulong vertexShaderConstants; - ulong pixelShaderConstants; - ulong sharedConstants; -}; - -uint g_Booleans(constant PushConstants& constants) -{ - return *(reinterpret_cast(constants.sharedConstants + 256)); -} - -uint g_SwappedTexcoords(constant PushConstants& constants) -{ - return *(reinterpret_cast(constants.sharedConstants + 260)); -} - -float g_AlphaThreshold(constant PushConstants& constants) -{ - return *(reinterpret_cast(constants.sharedConstants + 264)); -} - -struct Texture2DDescriptorHeap -{ - array, 1> g [[id(0)]]; -}; - -struct Texture3DDescriptorHeap -{ - array, 1> g [[id(0)]]; -}; - -struct TextureCubeDescriptorHeap -{ - array, 1> g [[id(0)]]; -}; - -struct SamplerDescriptorHeap -{ - array g [[id(0)]]; -}; - -uint2 getTexture2DDimensions(texture2d texture) -{ - return uint2(texture.get_width(), texture.get_height()); -} - -float4 tfetch2D(constant Texture2DDescriptorHeap& textureHeap, - constant SamplerDescriptorHeap& samplerHeap, - uint resourceDescriptorIndex, - uint samplerDescriptorIndex, - float2 texCoord, float2 offset) -{ - texture2d texture = textureHeap.g[resourceDescriptorIndex]; - sampler sampler = samplerHeap.g[samplerDescriptorIndex]; - return texture.sample(sampler, texCoord + offset / (float2)getTexture2DDimensions(texture)); -} - -float2 getWeights2D(constant Texture2DDescriptorHeap& textureHeap, - constant SamplerDescriptorHeap& samplerHeap, - uint resourceDescriptorIndex, - uint samplerDescriptorIndex, - float2 texCoord, float2 offset) -{ - texture2d texture = textureHeap.g[resourceDescriptorIndex]; - return select(fract(texCoord * (float2)getTexture2DDimensions(texture) + offset - 0.5), 0.0, isnan(texCoord)); -} - -float w0(float a) -{ - return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f); -} - -float w1(float a) -{ - return (1.0f / 6.0f) * (a * a * (3.0f * a - 6.0f) + 4.0f); -} - -float w2(float a) -{ - return (1.0f / 6.0f) * (a * (a * (-3.0f * a + 3.0f) + 3.0f) + 1.0f); -} - -float w3(float a) -{ - return (1.0f / 6.0f) * (a * a * a); -} - -float g0(float a) -{ - return w0(a) + w1(a); -} - -float g1(float a) -{ - return w2(a) + w3(a); -} - -float h0(float a) -{ - return -1.0f + w1(a) / (w0(a) + w1(a)) + 0.5f; -} - -float h1(float a) -{ - return 1.0f + w3(a) / (w2(a) + w3(a)) + 0.5f; -} - -float4 tfetch2DBicubic(constant Texture2DDescriptorHeap& textureHeap, - constant SamplerDescriptorHeap& samplerHeap, - uint resourceDescriptorIndex, - uint samplerDescriptorIndex, - float2 texCoord, float2 offset) -{ - texture2d texture = textureHeap.g[resourceDescriptorIndex]; - sampler sampler = samplerHeap.g[samplerDescriptorIndex]; - uint2 dimensions = getTexture2DDimensions(texture); - - float x = texCoord.x * dimensions.x + offset.x; - float y = texCoord.y * dimensions.y + offset.y; - - x -= 0.5f; - y -= 0.5f; - float px = floor(x); - float py = floor(y); - float fx = x - px; - float fy = y - py; - - float g0x = g0(fx); - float g1x = g1(fx); - float h0x = h0(fx); - float h1x = h1(fx); - float h0y = h0(fy); - float h1y = h1(fy); - - float4 r = - g0(fy) * (g0x * texture.sample(sampler, float2(px + h0x, py + h0y) / float2(dimensions)) + - g1x * texture.sample(sampler, float2(px + h1x, py + h0y) / float2(dimensions))) + - g1(fy) * (g0x * texture.sample(sampler, float2(px + h0x, py + h1y) / float2(dimensions)) + - g1x * texture.sample(sampler, float2(px + h1x, py + h1y) / float2(dimensions))); - - return r; -} - -float4 tfetch3D(constant Texture3DDescriptorHeap& textureHeap, - constant SamplerDescriptorHeap& samplerHeap, - uint resourceDescriptorIndex, - uint samplerDescriptorIndex, - float3 texCoord) -{ - texture3d texture = textureHeap.g[resourceDescriptorIndex]; - sampler sampler = samplerHeap.g[samplerDescriptorIndex]; - return texture.sample(sampler, texCoord); -} - -struct CubeMapData -{ - float3 cubeMapDirections[2]; - uint cubeMapIndex; -}; - -float4 tfetchCube(constant TextureCubeDescriptorHeap& textureHeap, - constant SamplerDescriptorHeap& samplerHeap, - uint resourceDescriptorIndex, - uint samplerDescriptorIndex, - float3 texCoord, thread CubeMapData* cubeMapData) -{ - texturecube texture = textureHeap.g[resourceDescriptorIndex]; - sampler sampler = samplerHeap.g[samplerDescriptorIndex]; - return texture.sample(sampler, cubeMapData->cubeMapDirections[(uint)texCoord.z]); -} - -float4 tfetchR11G11B10(uint4 value) -{ - if (g_SpecConstants() & SPEC_CONSTANT_R11G11B10_NORMAL) - { - return float4( - (value.x & 0x00000400 ? -1.0 : 0.0) + ((value.x & 0x3FF) / 1024.0), - (value.x & 0x00200000 ? -1.0 : 0.0) + (((value.x >> 11) & 0x3FF) / 1024.0), - (value.x & 0x80000000 ? -1.0 : 0.0) + (((value.x >> 22) & 0x1FF) / 512.0), - 0.0); - } - else - { - return (float4)value; - } -} - -float4 tfetchTexcoord(uint swappedTexcoords, float4 value, uint semanticIndex) -{ - return (swappedTexcoords & (1ull << semanticIndex)) != 0 ? value.yxwz : value; -} - -float4 cube(float4 value, thread CubeMapData* cubeMapData) -{ - uint index = cubeMapData->cubeMapIndex; - cubeMapData->cubeMapDirections[index] = value.xyz; - ++cubeMapData->cubeMapIndex; - - return float4(0.0, 0.0, 0.0, index); -} - -float4 dst(float4 src0, float4 src1) -{ - float4 dest; - dest.x = 1.0; - dest.y = src0.y * src1.y; - dest.z = src0.z; - dest.w = src1.w; - return dest; -} - -float4 max4(float4 src0) -{ - return max(src0.x, max3(src0.y, src0.z, src0.w)); -} - -float2 getPixelCoord(constant Texture2DDescriptorHeap& textureHeap, - uint resourceDescriptorIndex, - float2 texCoord) -{ - texture2d texture = textureHeap.g[resourceDescriptorIndex]; - return (float2)getTexture2DDimensions(texture) * texCoord; -} - -float computeMipLevel(float2 pixelCoord) -{ - float2 dx = dfdx(pixelCoord); - float2 dy = dfdy(pixelCoord); - float deltaMaxSqr = max(dot(dx, dx), dot(dy, dy)); - return max(0.0, 0.5 * log2(deltaMaxSqr)); -}