#define FLT_MIN asfloat(0xff7fffff) #define FLT_MAX asfloat(0x7f7fffff) #define INPUT_LAYOUT_FLAG_HAS_R11G11B10_NORMAL (1 << 0) #ifdef __spirv__ struct PushConstants { uint64_t VertexShaderConstants; uint64_t PixelShaderConstants; uint64_t SharedConstants; }; [[vk::push_constant]] ConstantBuffer g_PushConstants; #define g_AlphaTestMode vk::RawBufferLoad(g_PushConstants.SharedConstants + 128) #define g_AlphaThreshold vk::RawBufferLoad(g_PushConstants.SharedConstants + 132) #define g_Booleans vk::RawBufferLoad(g_PushConstants.SharedConstants + 136) #define g_SwappedTexcoords vk::RawBufferLoad(g_PushConstants.SharedConstants + 140) #define g_InputLayoutFlags vk::RawBufferLoad(g_PushConstants.SharedConstants + 144) #define g_EnableGIBicubicFiltering vk::RawBufferLoad(g_PushConstants.SharedConstants + 148) #else #define DEFINE_SHARED_CONSTANTS() \ uint g_AlphaTestMode : packoffset(c8.x); \ float g_AlphaThreshold : packoffset(c8.y); \ uint g_Booleans : packoffset(c8.z); \ uint g_SwappedTexcoords : packoffset(c8.w); \ uint g_InputLayoutFlags : packoffset(c9.x); \ bool g_EnableGIBicubicFiltering : packoffset(c9.y) #endif Texture2D g_Texture2DDescriptorHeap[] : register(t0, space0); Texture3D g_Texture3DDescriptorHeap[] : register(t0, space1); TextureCube g_TextureCubeDescriptorHeap[] : register(t0, space2); SamplerState g_SamplerDescriptorHeap[] : register(s0, space3); uint2 getTexture2DDimensions(Texture2D texture) { uint2 dimensions; texture.GetDimensions(dimensions.x, dimensions.y); return dimensions; } float4 tfetch2D(uint resourceDescriptorIndex, uint samplerDescriptorIndex, float2 texCoord, float2 offset) { Texture2D texture = g_Texture2DDescriptorHeap[resourceDescriptorIndex]; return texture.Sample(g_SamplerDescriptorHeap[samplerDescriptorIndex], texCoord + offset / getTexture2DDimensions(texture)); } float2 getWeights2D(uint resourceDescriptorIndex, uint samplerDescriptorIndex, float2 texCoord, float2 offset) { Texture2D texture = g_Texture2DDescriptorHeap[resourceDescriptorIndex]; return frac(texCoord * getTexture2DDimensions(texture) + offset - 0.5); } 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(uint resourceDescriptorIndex, uint samplerDescriptorIndex, float2 texCoord, float2 offset) { Texture2D texture = g_Texture2DDescriptorHeap[resourceDescriptorIndex]; SamplerState samplerState = g_SamplerDescriptorHeap[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(samplerState, float2(px + h0x, py + h0y) / float2(dimensions)) + g1x * texture.Sample(samplerState, float2(px + h1x, py + h0y) / float2(dimensions))) + g1(fy) * (g0x * texture.Sample(samplerState, float2(px + h0x, py + h1y) / float2(dimensions)) + g1x * texture.Sample(samplerState, float2(px + h1x, py + h1y) / float2(dimensions))); return r; } float4 tfetch3D(uint resourceDescriptorIndex, uint samplerDescriptorIndex, float3 texCoord) { return g_Texture3DDescriptorHeap[resourceDescriptorIndex].Sample(g_SamplerDescriptorHeap[samplerDescriptorIndex], texCoord); } struct CubeMapData { float3 cubeMapDirections[2]; uint cubeMapIndex; }; float4 tfetchCube(uint resourceDescriptorIndex, uint samplerDescriptorIndex, float3 texCoord, inout CubeMapData cubeMapData) { return g_TextureCubeDescriptorHeap[resourceDescriptorIndex].Sample(g_SamplerDescriptorHeap[samplerDescriptorIndex], cubeMapData.cubeMapDirections[texCoord.z]); } float4 tfetchR11G11B10(uint inputLayoutFlags, uint4 value) { if (inputLayoutFlags & INPUT_LAYOUT_FLAG_HAS_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 asfloat(value); } } float4 tfetchTexcoord(uint swappedTexcoords, float4 value, uint semanticIndex) { return (swappedTexcoords & (1 << semanticIndex)) != 0 ? value.yxwz : value; } float4 cube(float4 value, inout 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(max(src0.x, src0.y), max(src0.z, src0.w)); } float2 getPixelCoord(uint resourceDescriptorIndex, float2 texCoord) { return getTexture2DDimensions(g_Texture2DDescriptorHeap[resourceDescriptorIndex]) * texCoord; } float computeMipLevel(float2 pixelCoord) { float2 dx = ddx(pixelCoord); float2 dy = ddy(pixelCoord); float deltaMaxSqr = max(dot(dx, dx), dot(dy, dy)); return max(0.0, 0.5 * log2(deltaMaxSqr)); }