Merge commit '411251c6242b04119edc41ce83f09f0714e2d32b' as 'external/SDL'
This commit is contained in:
Vendored
+3622
File diff suppressed because it is too large
Load Diff
Vendored
+1240
File diff suppressed because it is too large
Load Diff
+3349
File diff suppressed because it is too large
Load Diff
+97
@@ -0,0 +1,97 @@
|
||||
#define BlitRS \
|
||||
"DescriptorTable ( Sampler(s0, space=2), visibility = SHADER_VISIBILITY_PIXEL ),"\
|
||||
"DescriptorTable ( SRV(t0, space=2), visibility = SHADER_VISIBILITY_PIXEL ),"\
|
||||
"CBV(b0, space=3, visibility = SHADER_VISIBILITY_PIXEL),"\
|
||||
|
||||
struct VertexToPixel
|
||||
{
|
||||
float2 tex : TEXCOORD0;
|
||||
float4 pos : SV_POSITION;
|
||||
};
|
||||
|
||||
cbuffer SourceRegionBuffer : register(b0, space3)
|
||||
{
|
||||
float2 UVLeftTop;
|
||||
float2 UVDimensions;
|
||||
uint MipLevel;
|
||||
float LayerOrDepth;
|
||||
};
|
||||
|
||||
Texture2D SourceTexture2D : register(t0, space2);
|
||||
Texture2DArray SourceTexture2DArray : register(t0, space2);
|
||||
Texture3D SourceTexture3D : register(t0, space2);
|
||||
TextureCube SourceTextureCube : register(t0, space2);
|
||||
TextureCubeArray SourceTextureCubeArray : register(t0, space2);
|
||||
sampler SourceSampler : register(s0, space2);
|
||||
|
||||
[RootSignature(BlitRS)]
|
||||
VertexToPixel FullscreenVert(uint vI : SV_VERTEXID)
|
||||
{
|
||||
float2 inTex = float2((vI << 1) & 2, vI & 2);
|
||||
VertexToPixel Out = (VertexToPixel)0;
|
||||
Out.tex = inTex;
|
||||
Out.pos = float4(inTex * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
|
||||
return Out;
|
||||
}
|
||||
|
||||
[RootSignature(BlitRS)]
|
||||
float4 BlitFrom2D(VertexToPixel input) : SV_Target0
|
||||
{
|
||||
float2 newCoord = UVLeftTop + UVDimensions * input.tex;
|
||||
return SourceTexture2D.SampleLevel(SourceSampler, newCoord, MipLevel);
|
||||
}
|
||||
|
||||
[RootSignature(BlitRS)]
|
||||
float4 BlitFrom2DArray(VertexToPixel input) : SV_Target0
|
||||
{
|
||||
float3 newCoord = float3(UVLeftTop + UVDimensions * input.tex, (uint)LayerOrDepth);
|
||||
return SourceTexture2DArray.SampleLevel(SourceSampler, newCoord, MipLevel);
|
||||
}
|
||||
|
||||
[RootSignature(BlitRS)]
|
||||
float4 BlitFrom3D(VertexToPixel input) : SV_Target0
|
||||
{
|
||||
float3 newCoord = float3(UVLeftTop + UVDimensions * input.tex, LayerOrDepth);
|
||||
return SourceTexture3D.SampleLevel(SourceSampler, newCoord, MipLevel);
|
||||
}
|
||||
|
||||
[RootSignature(BlitRS)]
|
||||
float4 BlitFromCube(VertexToPixel input) : SV_Target0
|
||||
{
|
||||
// Thanks, Wikipedia! https://en.wikipedia.org/wiki/Cube_mapping
|
||||
float3 newCoord;
|
||||
float2 scaledUV = UVLeftTop + UVDimensions * input.tex;
|
||||
float u = 2.0 * scaledUV.x - 1.0;
|
||||
float v = 2.0 * scaledUV.y - 1.0;
|
||||
switch ((uint)LayerOrDepth) {
|
||||
case 0: newCoord = float3(1.0, -v, -u); break; // POSITIVE X
|
||||
case 1: newCoord = float3(-1.0, -v, u); break; // NEGATIVE X
|
||||
case 2: newCoord = float3(u, 1.0, -v); break; // POSITIVE Y
|
||||
case 3: newCoord = float3(u, -1.0, v); break; // NEGATIVE Y
|
||||
case 4: newCoord = float3(u, -v, 1.0); break; // POSITIVE Z
|
||||
case 5: newCoord = float3(-u, -v, -1.0); break; // NEGATIVE Z
|
||||
default: newCoord = float3(0, 0, 0); break; // silences warning
|
||||
}
|
||||
return SourceTextureCube.SampleLevel(SourceSampler, newCoord, MipLevel);
|
||||
}
|
||||
|
||||
[RootSignature(BlitRS)]
|
||||
float4 BlitFromCubeArray(VertexToPixel input) : SV_Target0
|
||||
{
|
||||
// Thanks, Wikipedia! https://en.wikipedia.org/wiki/Cube_mapping
|
||||
float3 newCoord;
|
||||
float2 scaledUV = UVLeftTop + UVDimensions * input.tex;
|
||||
float u = 2.0 * scaledUV.x - 1.0;
|
||||
float v = 2.0 * scaledUV.y - 1.0;
|
||||
uint ArrayIndex = (uint)LayerOrDepth / 6;
|
||||
switch ((uint)LayerOrDepth % 6) {
|
||||
case 0: newCoord = float3(1.0, -v, -u); break; // POSITIVE X
|
||||
case 1: newCoord = float3(-1.0, -v, u); break; // NEGATIVE X
|
||||
case 2: newCoord = float3(u, 1.0, -v); break; // POSITIVE Y
|
||||
case 3: newCoord = float3(u, -1.0, v); break; // NEGATIVE Y
|
||||
case 4: newCoord = float3(u, -v, 1.0); break; // POSITIVE Z
|
||||
case 5: newCoord = float3(-u, -v, -1.0); break; // NEGATIVE Z
|
||||
default: newCoord = float3(0, 0, 0); break; // silences warning
|
||||
}
|
||||
return SourceTextureCubeArray.SampleLevel(SourceSampler, float4(newCoord, float(ArrayIndex)), MipLevel);
|
||||
}
|
||||
+10170
File diff suppressed because it is too large
Load Diff
+18
@@ -0,0 +1,18 @@
|
||||
rem This script runs for the Windows build, but also via the _xbox variant with these vars set.
|
||||
rem Make sure to default to building for Windows if they're not set.
|
||||
if %DXC%.==. set DXC=dxc
|
||||
if %SUFFIX%.==. set SUFFIX=.h
|
||||
|
||||
echo Building with %DXC%
|
||||
echo Suffix %SUFFIX%
|
||||
|
||||
cd "%~dp0"
|
||||
|
||||
%DXC% -E FullscreenVert -T vs_6_0 -Fh D3D12_FullscreenVert.h D3D_Blit.hlsl
|
||||
%DXC% -E BlitFrom2D -T ps_6_0 -Fh D3D12_BlitFrom2D.h D3D_Blit.hlsl
|
||||
%DXC% -E BlitFrom2DArray -T ps_6_0 -Fh D3D12_BlitFrom2DArray.h D3D_Blit.hlsl
|
||||
%DXC% -E BlitFrom3D -T ps_6_0 -Fh D3D12_BlitFrom3D.h D3D_Blit.hlsl
|
||||
%DXC% -E BlitFromCube -T ps_6_0 -Fh D3D12_BlitFromCube.h D3D_Blit.hlsl
|
||||
%DXC% -E BlitFromCubeArray -T ps_6_0 -Fh D3D12_BlitFromCubeArray.h D3D_Blit.hlsl
|
||||
copy /b D3D12_FullscreenVert.h+D3D12_BlitFrom2D.h+D3D12_BlitFrom2DArray.h+D3D12_BlitFrom3D.h+D3D12_BlitFromCube.h+D3D12_BlitFromCubeArray.h D3D12_Blit%SUFFIX%
|
||||
del D3D12_FullscreenVert.h D3D12_BlitFrom2D.h D3D12_BlitFrom2DArray.h D3D12_BlitFrom3D.h D3D12_BlitFromCube.h D3D12_BlitFromCubeArray.h
|
||||
@@ -0,0 +1,13 @@
|
||||
if %2.==one. goto setxboxone
|
||||
rem Xbox Series compile
|
||||
set DXC="%GameDKLatest%\GXDK\bin\Scarlett\DXC.exe"
|
||||
set SUFFIX=_Series.h
|
||||
goto startbuild
|
||||
|
||||
:setxboxone
|
||||
set DXC="%GameDKLatest%\GXDK\bin\XboxOne\DXC.exe"
|
||||
set SUFFIX=_One.h
|
||||
|
||||
:startbuild
|
||||
|
||||
call "%~dp0\compile_shaders.bat"
|
||||
+10088
File diff suppressed because it is too large
Load Diff
+110
@@ -0,0 +1,110 @@
|
||||
#include <metal_stdlib>
|
||||
using namespace metal;
|
||||
|
||||
struct VertexToFragment {
|
||||
float2 tex;
|
||||
float4 pos [[position]];
|
||||
};
|
||||
|
||||
struct SourceRegion {
|
||||
float2 UVLeftTop;
|
||||
float2 UVDimensions;
|
||||
uint MipLevel;
|
||||
float LayerOrDepth;
|
||||
};
|
||||
|
||||
#if COMPILE_FullscreenVert
|
||||
vertex VertexToFragment FullscreenVert(uint vI [[vertex_id]]) {
|
||||
float2 inTex = float2((vI << 1) & 2, vI & 2);
|
||||
VertexToFragment out;
|
||||
out.tex = inTex;
|
||||
out.pos = float4(inTex * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if COMPILE_BlitFrom2D
|
||||
fragment float4 BlitFrom2D(
|
||||
VertexToFragment input [[stage_in]],
|
||||
constant SourceRegion &sourceRegion [[buffer(0)]],
|
||||
texture2d<float> sourceTexture [[texture(0)]],
|
||||
sampler sourceSampler [[sampler(0)]])
|
||||
{
|
||||
float2 newCoord = sourceRegion.UVLeftTop + sourceRegion.UVDimensions * input.tex;
|
||||
return sourceTexture.sample(sourceSampler, newCoord, level(sourceRegion.MipLevel));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if COMPILE_BlitFrom2DArray
|
||||
fragment float4 BlitFrom2DArray(
|
||||
VertexToFragment input [[stage_in]],
|
||||
constant SourceRegion &sourceRegion [[buffer(0)]],
|
||||
texture2d_array<float> sourceTexture [[texture(0)]],
|
||||
sampler sourceSampler [[sampler(0)]])
|
||||
{
|
||||
float2 newCoord = sourceRegion.UVLeftTop + sourceRegion.UVDimensions * input.tex;
|
||||
return sourceTexture.sample(sourceSampler, newCoord, (uint)sourceRegion.LayerOrDepth, level(sourceRegion.MipLevel));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if COMPILE_BlitFrom3D
|
||||
fragment float4 BlitFrom3D(
|
||||
VertexToFragment input [[stage_in]],
|
||||
constant SourceRegion &sourceRegion [[buffer(0)]],
|
||||
texture3d<float> sourceTexture [[texture(0)]],
|
||||
sampler sourceSampler [[sampler(0)]])
|
||||
{
|
||||
float2 newCoord = sourceRegion.UVLeftTop + sourceRegion.UVDimensions * input.tex;
|
||||
return sourceTexture.sample(sourceSampler, float3(newCoord, sourceRegion.LayerOrDepth), level(sourceRegion.MipLevel));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if COMPILE_BlitFromCube
|
||||
fragment float4 BlitFromCube(
|
||||
VertexToFragment input [[stage_in]],
|
||||
constant SourceRegion &sourceRegion [[buffer(0)]],
|
||||
texturecube<float> sourceTexture [[texture(0)]],
|
||||
sampler sourceSampler [[sampler(0)]])
|
||||
{
|
||||
// Thanks, Wikipedia! https://en.wikipedia.org/wiki/Cube_mapping
|
||||
float2 scaledUV = sourceRegion.UVLeftTop + sourceRegion.UVDimensions * input.tex;
|
||||
float u = 2.0 * scaledUV.x - 1.0;
|
||||
float v = 2.0 * scaledUV.y - 1.0;
|
||||
float3 newCoord;
|
||||
switch ((uint)sourceRegion.LayerOrDepth) {
|
||||
case 0: newCoord = float3(1.0, -v, -u); break; // POSITIVE X
|
||||
case 1: newCoord = float3(-1.0, -v, u); break; // NEGATIVE X
|
||||
case 2: newCoord = float3(u, 1.0, -v); break; // POSITIVE Y
|
||||
case 3: newCoord = float3(u, -1.0, v); break; // NEGATIVE Y
|
||||
case 4: newCoord = float3(u, -v, 1.0); break; // POSITIVE Z
|
||||
case 5: newCoord = float3(-u, -v, -1.0); break; // NEGATIVE Z
|
||||
default: newCoord = float3(0, 0, 0); break; // silences warning
|
||||
}
|
||||
return sourceTexture.sample(sourceSampler, newCoord, level(sourceRegion.MipLevel));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if COMPILE_BlitFromCubeArray
|
||||
fragment float4 BlitFromCubeArray(
|
||||
VertexToFragment input [[stage_in]],
|
||||
constant SourceRegion &sourceRegion [[buffer(0)]],
|
||||
texturecube_array<float> sourceTexture [[texture(0)]],
|
||||
sampler sourceSampler [[sampler(0)]])
|
||||
{
|
||||
// Thanks, Wikipedia! https://en.wikipedia.org/wiki/Cube_mapping
|
||||
float2 scaledUV = sourceRegion.UVLeftTop + sourceRegion.UVDimensions * input.tex;
|
||||
float u = 2.0 * scaledUV.x - 1.0;
|
||||
float v = 2.0 * scaledUV.y - 1.0;
|
||||
float3 newCoord;
|
||||
switch (((uint)sourceRegion.LayerOrDepth) % 6) {
|
||||
case 0: newCoord = float3(1.0, -v, -u); break; // POSITIVE X
|
||||
case 1: newCoord = float3(-1.0, -v, u); break; // NEGATIVE X
|
||||
case 2: newCoord = float3(u, 1.0, -v); break; // POSITIVE Y
|
||||
case 3: newCoord = float3(u, -1.0, v); break; // NEGATIVE Y
|
||||
case 4: newCoord = float3(u, -v, 1.0); break; // POSITIVE Z
|
||||
case 5: newCoord = float3(-u, -v, -1.0); break; // NEGATIVE Z
|
||||
default: newCoord = float3(0, 0, 0); break; // silences warning
|
||||
}
|
||||
return sourceTexture.sample(sourceSampler, newCoord, (uint)sourceRegion.LayerOrDepth / 6, level(sourceRegion.MipLevel));
|
||||
}
|
||||
#endif
|
||||
+4722
File diff suppressed because it is too large
Load Diff
+68
@@ -0,0 +1,68 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
set -e
|
||||
cd `dirname "$0"`
|
||||
|
||||
shadernames=(FullscreenVert BlitFrom2D BlitFrom2DArray BlitFrom3D BlitFromCube BlitFromCubeArray)
|
||||
|
||||
generate_shaders()
|
||||
{
|
||||
fileplatform=$1
|
||||
compileplatform=$2
|
||||
sdkplatform=$3
|
||||
minversion=$4
|
||||
|
||||
for shadername in "${shadernames[@]}"; do
|
||||
xcrun -sdk $sdkplatform metal -c -std=$compileplatform-metal2.0 -m$sdkplatform-version-min=$minversion -Wall -O3 -D COMPILE_$shadername -o ./$shadername.air ./Metal_Blit.metal || exit $?
|
||||
xcrun -sdk $sdkplatform metallib -o $shadername.metallib $shadername.air || exit $?
|
||||
xxd -i $shadername.metallib | perl -w -p -e 's/\Aunsigned /const unsigned /;' >./${shadername}_$fileplatform.h
|
||||
rm -f $shadername.air $shadername.metallib
|
||||
done
|
||||
}
|
||||
|
||||
generate_shaders macos macos macosx 10.11
|
||||
generate_shaders ios ios iphoneos 11.0
|
||||
generate_shaders iphonesimulator ios iphonesimulator 11.0
|
||||
generate_shaders tvos ios appletvos 11.0
|
||||
generate_shaders tvsimulator ios appletvsimulator 11.0
|
||||
|
||||
# Bundle together one mega-header
|
||||
catShaders()
|
||||
{
|
||||
target=$1
|
||||
for shadername in "${shadernames[@]}"; do
|
||||
cat ${shadername}_$target.h >> Metal_Blit.h
|
||||
done
|
||||
}
|
||||
|
||||
rm -f Metal_Blit.h
|
||||
echo "#if defined(SDL_PLATFORM_IOS)" >> Metal_Blit.h
|
||||
echo "#if TARGET_OS_SIMULATOR" >> Metal_Blit.h
|
||||
catShaders iphonesimulator
|
||||
echo "#else" >> Metal_Blit.h
|
||||
catShaders ios
|
||||
echo "#endif" >> Metal_Blit.h
|
||||
echo "#elif defined(SDL_PLATFORM_TVOS)" >> Metal_Blit.h
|
||||
echo "#if TARGET_OS_SIMULATOR" >> Metal_Blit.h
|
||||
catShaders tvsimulator
|
||||
echo "#else" >> Metal_Blit.h
|
||||
catShaders tvos
|
||||
echo "#endif" >> Metal_Blit.h
|
||||
echo "#else" >> Metal_Blit.h
|
||||
catShaders macos
|
||||
echo "#endif" >> Metal_Blit.h
|
||||
|
||||
# Clean up
|
||||
cleanupShaders()
|
||||
{
|
||||
target=$1
|
||||
for shadername in "${shadernames[@]}"; do
|
||||
rm -f ${shadername}_$target.h
|
||||
done
|
||||
}
|
||||
cleanupShaders iphonesimulator
|
||||
cleanupShaders ios
|
||||
cleanupShaders tvsimulator
|
||||
cleanupShaders tvos
|
||||
cleanupShaders macos
|
||||
+13712
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Global functions from the Vulkan Loader
|
||||
*/
|
||||
|
||||
#ifndef VULKAN_GLOBAL_FUNCTION
|
||||
#define VULKAN_GLOBAL_FUNCTION(name)
|
||||
#endif
|
||||
VULKAN_GLOBAL_FUNCTION(vkCreateInstance)
|
||||
VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceExtensionProperties)
|
||||
VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceLayerProperties)
|
||||
|
||||
/*
|
||||
* vkInstance, created by global vkCreateInstance function
|
||||
*/
|
||||
|
||||
#ifndef VULKAN_INSTANCE_FUNCTION
|
||||
#define VULKAN_INSTANCE_FUNCTION(name)
|
||||
#endif
|
||||
|
||||
// Vulkan 1.0
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetDeviceProcAddr)
|
||||
VULKAN_INSTANCE_FUNCTION(vkCreateDevice)
|
||||
VULKAN_INSTANCE_FUNCTION(vkDestroyInstance)
|
||||
VULKAN_INSTANCE_FUNCTION(vkEnumerateDeviceExtensionProperties)
|
||||
VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices)
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures)
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFormatProperties)
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceImageFormatProperties)
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceMemoryProperties)
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties)
|
||||
|
||||
// Vulkan 1.1 (Needed for opt-in feature checks)
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures2)
|
||||
|
||||
// VK_KHR_get_physical_device_properties2, needed for KHR_driver_properties
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties2KHR)
|
||||
|
||||
// VK_KHR_surface
|
||||
VULKAN_INSTANCE_FUNCTION(vkDestroySurfaceKHR)
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR)
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR)
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR)
|
||||
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR)
|
||||
|
||||
// VK_EXT_debug_utils
|
||||
VULKAN_INSTANCE_FUNCTION(vkCmdBeginDebugUtilsLabelEXT)
|
||||
VULKAN_INSTANCE_FUNCTION(vkSetDebugUtilsObjectNameEXT)
|
||||
VULKAN_INSTANCE_FUNCTION(vkCmdEndDebugUtilsLabelEXT)
|
||||
VULKAN_INSTANCE_FUNCTION(vkCmdInsertDebugUtilsLabelEXT)
|
||||
|
||||
/*
|
||||
* vkDevice, created by a vkInstance
|
||||
*/
|
||||
|
||||
#ifndef VULKAN_DEVICE_FUNCTION
|
||||
#define VULKAN_DEVICE_FUNCTION(name)
|
||||
#endif
|
||||
|
||||
// Vulkan 1.0
|
||||
VULKAN_DEVICE_FUNCTION(vkAllocateCommandBuffers)
|
||||
VULKAN_DEVICE_FUNCTION(vkAllocateDescriptorSets)
|
||||
VULKAN_DEVICE_FUNCTION(vkAllocateMemory)
|
||||
VULKAN_DEVICE_FUNCTION(vkBeginCommandBuffer)
|
||||
VULKAN_DEVICE_FUNCTION(vkBindBufferMemory)
|
||||
VULKAN_DEVICE_FUNCTION(vkBindImageMemory)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdBeginRenderPass)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdBindDescriptorSets)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdBindIndexBuffer)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdBindPipeline)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdBindVertexBuffers)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdBlitImage)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdClearAttachments)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdClearColorImage)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdClearDepthStencilImage)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdCopyBuffer)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdCopyImage)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdCopyBufferToImage)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdCopyImageToBuffer)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdDispatch)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdDispatchIndirect)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdDraw)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdDrawIndexed)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdDrawIndexedIndirect)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdDrawIndirect)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdEndRenderPass)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdPipelineBarrier)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdResolveImage)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdSetBlendConstants)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdSetDepthBias)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdSetScissor)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdSetStencilReference)
|
||||
VULKAN_DEVICE_FUNCTION(vkCmdSetViewport)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateBuffer)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateCommandPool)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateDescriptorPool)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateDescriptorSetLayout)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateFence)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateFramebuffer)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateComputePipelines)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateGraphicsPipelines)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateImage)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateImageView)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreatePipelineCache)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreatePipelineLayout)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateRenderPass)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateSampler)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateSemaphore)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateShaderModule)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyBuffer)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyCommandPool)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyDescriptorPool)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyDescriptorSetLayout)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyDevice)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyFence)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyFramebuffer)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyImage)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyImageView)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyPipeline)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyPipelineCache)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyPipelineLayout)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyRenderPass)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroySampler)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroySemaphore)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroyShaderModule)
|
||||
VULKAN_DEVICE_FUNCTION(vkDeviceWaitIdle)
|
||||
VULKAN_DEVICE_FUNCTION(vkEndCommandBuffer)
|
||||
VULKAN_DEVICE_FUNCTION(vkFreeCommandBuffers)
|
||||
VULKAN_DEVICE_FUNCTION(vkFreeMemory)
|
||||
VULKAN_DEVICE_FUNCTION(vkGetDeviceQueue)
|
||||
VULKAN_DEVICE_FUNCTION(vkGetPipelineCacheData)
|
||||
VULKAN_DEVICE_FUNCTION(vkGetFenceStatus)
|
||||
VULKAN_DEVICE_FUNCTION(vkGetBufferMemoryRequirements)
|
||||
VULKAN_DEVICE_FUNCTION(vkGetImageMemoryRequirements)
|
||||
VULKAN_DEVICE_FUNCTION(vkMapMemory)
|
||||
VULKAN_DEVICE_FUNCTION(vkQueueSubmit)
|
||||
VULKAN_DEVICE_FUNCTION(vkQueueWaitIdle)
|
||||
VULKAN_DEVICE_FUNCTION(vkResetCommandBuffer)
|
||||
VULKAN_DEVICE_FUNCTION(vkResetCommandPool)
|
||||
VULKAN_DEVICE_FUNCTION(vkResetDescriptorPool)
|
||||
VULKAN_DEVICE_FUNCTION(vkResetFences)
|
||||
VULKAN_DEVICE_FUNCTION(vkUnmapMemory)
|
||||
VULKAN_DEVICE_FUNCTION(vkUpdateDescriptorSets)
|
||||
VULKAN_DEVICE_FUNCTION(vkWaitForFences)
|
||||
|
||||
// VK_KHR_swapchain
|
||||
VULKAN_DEVICE_FUNCTION(vkAcquireNextImageKHR)
|
||||
VULKAN_DEVICE_FUNCTION(vkCreateSwapchainKHR)
|
||||
VULKAN_DEVICE_FUNCTION(vkDestroySwapchainKHR)
|
||||
VULKAN_DEVICE_FUNCTION(vkQueuePresentKHR)
|
||||
VULKAN_DEVICE_FUNCTION(vkGetSwapchainImagesKHR)
|
||||
|
||||
/*
|
||||
* Redefine these every time you include this header!
|
||||
*/
|
||||
#undef VULKAN_GLOBAL_FUNCTION
|
||||
#undef VULKAN_INSTANCE_FUNCTION
|
||||
#undef VULKAN_DEVICE_FUNCTION
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef HAVE_GPU_OPENXR
|
||||
|
||||
#include "SDL_gpu_openxr.h"
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
#include "../../core/android/SDL_android.h"
|
||||
#endif
|
||||
|
||||
#define VALIDATION_LAYER_API_NAME "XR_APILAYER_LUNARG_core_validation"
|
||||
|
||||
/* On Android, the OpenXR loader is initialized by SDL_OpenXR_LoadLibrary() in SDL_openxrdyn.c
|
||||
* which must be called before this. That function handles the complex initialization using
|
||||
* direct SDL_LoadFunction calls to avoid issues with xrGetInstanceProcAddr from runtime
|
||||
* negotiation not supporting pre-instance calls. This stub is kept for API compatibility. */
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
static bool SDL_OPENXR_INTERNAL_InitializeAndroidLoader(void)
|
||||
{
|
||||
/* The loader should already be initialized by SDL_OpenXR_LoadLibrary().
|
||||
* We just verify that xrGetInstanceProcAddr is available. */
|
||||
if (xrGetInstanceProcAddr == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_GPU, "xrGetInstanceProcAddr is NULL - SDL_OpenXR_LoadLibrary was not called first");
|
||||
return false;
|
||||
}
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "Android OpenXR loader verified (was initialized by SDL_OpenXR_LoadLibrary)");
|
||||
return true;
|
||||
}
|
||||
#endif /* SDL_PLATFORM_ANDROID */
|
||||
|
||||
static bool SDL_OPENXR_INTERNAL_ValidationLayerAvailable(void)
|
||||
{
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
/* On Android/Quest, the xrGetInstanceProcAddr obtained through runtime negotiation
|
||||
* crashes when used for pre-instance global functions. Skip validation layer check. */
|
||||
return false;
|
||||
#else
|
||||
|
||||
Uint32 apiLayerCount;
|
||||
if (XR_FAILED(xrEnumerateApiLayerProperties(0, &apiLayerCount, NULL))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (apiLayerCount <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
XrApiLayerProperties *apiLayerProperties = SDL_stack_alloc(XrApiLayerProperties, apiLayerCount);
|
||||
if (XR_FAILED(xrEnumerateApiLayerProperties(apiLayerCount, &apiLayerCount, apiLayerProperties))) {
|
||||
SDL_stack_free(apiLayerProperties);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (Uint32 i = 0; i < apiLayerCount; i++) {
|
||||
XrApiLayerProperties apiLayer = apiLayerProperties[i];
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "api layer available: %s", apiLayer.layerName);
|
||||
if (SDL_strcmp(apiLayer.layerName, VALIDATION_LAYER_API_NAME) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_stack_free(apiLayerProperties);
|
||||
return found;
|
||||
#endif
|
||||
}
|
||||
|
||||
XrResult SDL_OPENXR_INTERNAL_GPUInitOpenXR(
|
||||
bool debugMode,
|
||||
XrExtensionProperties gpuExtension,
|
||||
SDL_PropertiesID props,
|
||||
XrInstance *instance,
|
||||
XrSystemId *systemId,
|
||||
XrInstancePfns **xr)
|
||||
{
|
||||
XrResult xrResult;
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
// Android requires loader initialization before any other XR calls
|
||||
if (!SDL_OPENXR_INTERNAL_InitializeAndroidLoader()) {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_GPU, "Failed to initialize Android OpenXR loader");
|
||||
return XR_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool validationLayersAvailable = SDL_OPENXR_INTERNAL_ValidationLayerAvailable();
|
||||
|
||||
Uint32 userApiLayerCount = (Uint32)SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_LAYER_COUNT_NUMBER, 0);
|
||||
const char *const *userApiLayerNames = SDL_GetPointerProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_LAYER_NAMES_POINTER, NULL);
|
||||
|
||||
Uint32 userExtensionCount = (Uint32)SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_EXTENSION_COUNT_NUMBER, 0);
|
||||
const char *const *userExtensionNames = SDL_GetPointerProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_EXTENSION_NAMES_POINTER, NULL);
|
||||
|
||||
// allocate enough space for the validation layer + the user's api layers
|
||||
const char **apiLayerNames = SDL_stack_alloc(const char *, userApiLayerCount + 1);
|
||||
SDL_memcpy((void *)apiLayerNames, userApiLayerNames, sizeof(const char *) * (userApiLayerCount));
|
||||
apiLayerNames[userApiLayerCount] = VALIDATION_LAYER_API_NAME;
|
||||
|
||||
// On Android, we need an extra extension for android_create_instance
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
const Uint32 platformExtensionCount = 2; // GPU extension + Android create instance
|
||||
#else
|
||||
const Uint32 platformExtensionCount = 1; // GPU extension only
|
||||
#endif
|
||||
|
||||
const char **extensionNames = SDL_stack_alloc(const char *, userExtensionCount + platformExtensionCount);
|
||||
SDL_memcpy((void *)extensionNames, userExtensionNames, sizeof(const char *) * (userExtensionCount));
|
||||
extensionNames[userExtensionCount] = gpuExtension.extensionName;
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
extensionNames[userExtensionCount + 1] = XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME;
|
||||
#endif
|
||||
|
||||
XrInstanceCreateInfo xrInstanceCreateInfo;
|
||||
SDL_zero(xrInstanceCreateInfo);
|
||||
xrInstanceCreateInfo.type = XR_TYPE_INSTANCE_CREATE_INFO;
|
||||
xrInstanceCreateInfo.applicationInfo.apiVersion = SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_VERSION_NUMBER, XR_API_VERSION_1_0);
|
||||
xrInstanceCreateInfo.enabledApiLayerCount = userApiLayerCount + ((debugMode && validationLayersAvailable) ? 1 : 0); // in debug mode, we enable the validation layer
|
||||
xrInstanceCreateInfo.enabledApiLayerNames = apiLayerNames;
|
||||
xrInstanceCreateInfo.enabledExtensionCount = userExtensionCount + platformExtensionCount;
|
||||
xrInstanceCreateInfo.enabledExtensionNames = extensionNames;
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
// Get JNI environment and JavaVM for Android instance creation
|
||||
JNIEnv *env = (JNIEnv *)SDL_GetAndroidJNIEnv();
|
||||
JavaVM *vm = NULL;
|
||||
if (env) {
|
||||
(*env)->GetJavaVM(env, &vm);
|
||||
}
|
||||
void *activity = SDL_GetAndroidActivity();
|
||||
|
||||
XrInstanceCreateInfoAndroidKHR instanceCreateInfoAndroid = {};
|
||||
instanceCreateInfoAndroid.type = XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR;
|
||||
instanceCreateInfoAndroid.applicationVM = vm;
|
||||
instanceCreateInfoAndroid.applicationActivity = activity;
|
||||
xrInstanceCreateInfo.next = &instanceCreateInfoAndroid;
|
||||
#endif
|
||||
|
||||
const char *applicationName = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_APPLICATION_NAME_STRING, "SDL Application");
|
||||
Uint32 applicationVersion = (Uint32)SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_APPLICATION_VERSION_NUMBER, 0);
|
||||
|
||||
SDL_strlcpy(xrInstanceCreateInfo.applicationInfo.applicationName, applicationName, XR_MAX_APPLICATION_NAME_SIZE);
|
||||
xrInstanceCreateInfo.applicationInfo.applicationVersion = applicationVersion;
|
||||
|
||||
const char *engineName = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_ENGINE_NAME_STRING, "SDLGPU");
|
||||
uint32_t engineVersion = (uint32_t)SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_ENGINE_VERSION_NUMBER, SDL_VERSION);
|
||||
|
||||
SDL_strlcpy(xrInstanceCreateInfo.applicationInfo.engineName, engineName, XR_MAX_APPLICATION_NAME_SIZE);
|
||||
xrInstanceCreateInfo.applicationInfo.engineVersion = engineVersion;
|
||||
|
||||
if ((xrResult = xrCreateInstance(&xrInstanceCreateInfo, instance)) != XR_SUCCESS) {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_GPU, "Failed to create OpenXR instance");
|
||||
SDL_stack_free(apiLayerNames);
|
||||
SDL_stack_free(extensionNames);
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_stack_free(apiLayerNames);
|
||||
SDL_stack_free(extensionNames);
|
||||
|
||||
*xr = SDL_OPENXR_LoadInstanceSymbols(*instance);
|
||||
if (!*xr) {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_GPU, "Failed to load required OpenXR instance symbols");
|
||||
/* NOTE: we can't actually destroy the created OpenXR instance here,
|
||||
as we only get that function pointer by loading the instance symbols...
|
||||
let's just hope that doesn't happen. */
|
||||
return false;
|
||||
}
|
||||
|
||||
XrSystemGetInfo systemGetInfo;
|
||||
SDL_zero(systemGetInfo);
|
||||
systemGetInfo.type = XR_TYPE_SYSTEM_GET_INFO;
|
||||
systemGetInfo.formFactor = (XrFormFactor)SDL_GetNumberProperty(props, SDL_PROP_GPU_DEVICE_CREATE_XR_FORM_FACTOR_NUMBER, XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY);
|
||||
if ((xrResult = (*xr)->xrGetSystem(*instance, &systemGetInfo, systemId)) != XR_SUCCESS) {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_GPU, "Failed to get OpenXR system");
|
||||
(*xr)->xrDestroyInstance(*instance);
|
||||
SDL_free(*xr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* HAVE_GPU_OPENXR */
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_openxrdyn.h"
|
||||
|
||||
XrResult SDL_OPENXR_INTERNAL_GPUInitOpenXR(
|
||||
bool debugMode,
|
||||
XrExtensionProperties gpuExtension,
|
||||
SDL_PropertiesID props,
|
||||
XrInstance *instance,
|
||||
XrSystemId *systemId,
|
||||
XrInstancePfns **xr);
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* This internal header provides access to the vendored OpenXR headers
|
||||
* without requiring include path modifications in project files.
|
||||
* Similar to SDL_vulkan_internal.h for Vulkan headers.
|
||||
*/
|
||||
|
||||
#ifndef SDL_openxr_internal_h_
|
||||
#define SDL_openxr_internal_h_
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
/* Define platform-specific OpenXR macros BEFORE including openxr headers */
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
#include <jni.h>
|
||||
#define XR_USE_PLATFORM_ANDROID
|
||||
#endif
|
||||
|
||||
/* Include the vendored OpenXR headers using relative path */
|
||||
#include "../../video/khronos/openxr/openxr.h"
|
||||
#include "../../video/khronos/openxr/openxr_platform.h"
|
||||
|
||||
/* Compatibility: XR_API_VERSION_1_0 was added in OpenXR 1.1.x */
|
||||
#ifndef XR_API_VERSION_1_0
|
||||
#define XR_API_VERSION_1_0 XR_MAKE_VERSION(1, 0, XR_VERSION_PATCH(XR_CURRENT_API_VERSION))
|
||||
#endif
|
||||
|
||||
#define SDL_OPENXR_CHECK_VERSION(x, y, z) \
|
||||
(XR_VERSION_MAJOR(XR_CURRENT_API_VERSION) > x || \
|
||||
(XR_VERSION_MAJOR(XR_CURRENT_API_VERSION) == x && XR_VERSION_MINOR(XR_CURRENT_API_VERSION) > y) || \
|
||||
(XR_VERSION_MAJOR(XR_CURRENT_API_VERSION) == x && XR_VERSION_MINOR(XR_CURRENT_API_VERSION) == y && XR_VERSION_PATCH(XR_CURRENT_API_VERSION) >= z))
|
||||
|
||||
#endif /* SDL_openxr_internal_h_ */
|
||||
+417
@@ -0,0 +1,417 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include "SDL_openxrdyn.h"
|
||||
|
||||
#ifdef HAVE_GPU_OPENXR
|
||||
|
||||
#include <SDL3/SDL_dlopennote.h>
|
||||
#include <SDL3/SDL_openxr.h>
|
||||
|
||||
#if defined(SDL_PLATFORM_APPLE)
|
||||
static const char *openxr_library_names[] = { "libopenxr_loader.dylib", NULL };
|
||||
#elif defined(SDL_PLATFORM_WINDOWS)
|
||||
static const char *openxr_library_names[] = { "openxr_loader.dll", NULL };
|
||||
#elif defined(SDL_PLATFORM_ANDROID)
|
||||
/* On Android, use the Khronos OpenXR loader (libopenxr_loader.so) which properly
|
||||
* exports xrGetInstanceProcAddr. This is bundled via the Gradle dependency:
|
||||
* implementation 'org.khronos.openxr:openxr_loader_for_android:X.Y.Z'
|
||||
*
|
||||
* The Khronos loader handles runtime discovery internally via the Android broker
|
||||
* pattern and properly supports all pre-instance global functions.
|
||||
*
|
||||
* Note: Do NOT use Meta's forwardloader (libopenxr_forwardloader.so) - it doesn't
|
||||
* export xrGetInstanceProcAddr directly and the function obtained via runtime
|
||||
* negotiation crashes on pre-instance calls (e.g., xrEnumerateApiLayerProperties). */
|
||||
static const char *openxr_library_names[] = { "libopenxr_loader.so", NULL };
|
||||
#else
|
||||
static const char *openxr_library_names[] = { "libopenxr_loader.so.1", NULL };
|
||||
SDL_ELF_NOTE_DLOPEN(
|
||||
"gpu-openxr",
|
||||
"Support for OpenXR with SDL_GPU rendering",
|
||||
SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
|
||||
"libopenxr_loader.so.1"
|
||||
)
|
||||
#endif
|
||||
|
||||
#define DEBUG_DYNAMIC_OPENXR 0
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_SharedObject *lib;
|
||||
} openxrdynlib;
|
||||
|
||||
static openxrdynlib openxr_loader = { NULL };
|
||||
|
||||
#ifndef SDL_PLATFORM_ANDROID
|
||||
static void *OPENXR_GetSym(const char *fnname, bool *failed)
|
||||
{
|
||||
void *fn = SDL_LoadFunction(openxr_loader.lib, fnname);
|
||||
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
if (fn) {
|
||||
SDL_Log("OPENXR: Found '%s' in %s (%p)\n", fnname, dynlib->libname, fn);
|
||||
} else {
|
||||
SDL_Log("OPENXR: Symbol '%s' NOT FOUND!\n", fnname);
|
||||
}
|
||||
#endif
|
||||
|
||||
return fn;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Define all the function pointers and wrappers...
|
||||
#define SDL_OPENXR_SYM(name) PFN_##name OPENXR_##name = NULL;
|
||||
#include "SDL_openxrsym.h"
|
||||
|
||||
static int openxr_load_refcount = 0;
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
#include <jni.h>
|
||||
#include "../../video/khronos/openxr/openxr_platform.h"
|
||||
|
||||
/* On Android, we need to initialize the loader with JNI context before use */
|
||||
static bool openxr_android_loader_initialized = false;
|
||||
|
||||
static bool OPENXR_InitializeAndroidLoader(void)
|
||||
{
|
||||
XrResult result;
|
||||
PFN_xrInitializeLoaderKHR initializeLoader = NULL;
|
||||
PFN_xrGetInstanceProcAddr loaderGetProcAddr = NULL;
|
||||
JNIEnv *env = NULL;
|
||||
JavaVM *vm = NULL;
|
||||
jobject activity = NULL;
|
||||
|
||||
if (openxr_android_loader_initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* The Khronos OpenXR loader (libopenxr_loader.so) properly exports xrGetInstanceProcAddr.
|
||||
* Get it directly from the library - this is the standard approach. */
|
||||
loaderGetProcAddr = (PFN_xrGetInstanceProcAddr)SDL_LoadFunction(openxr_loader.lib, "xrGetInstanceProcAddr");
|
||||
|
||||
if (loaderGetProcAddr == NULL) {
|
||||
SDL_SetError("Failed to get xrGetInstanceProcAddr from OpenXR loader. "
|
||||
"Make sure you're using the Khronos loader (libopenxr_loader.so), "
|
||||
"not Meta's forwardloader.");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: Got xrGetInstanceProcAddr from loader: %p", (void*)loaderGetProcAddr);
|
||||
#endif
|
||||
|
||||
/* Get xrInitializeLoaderKHR via xrGetInstanceProcAddr */
|
||||
result = loaderGetProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction*)&initializeLoader);
|
||||
if (XR_FAILED(result) || initializeLoader == NULL) {
|
||||
SDL_SetError("Failed to get xrInitializeLoaderKHR (result: %d)", (int)result);
|
||||
return false;
|
||||
}
|
||||
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: Got xrInitializeLoaderKHR: %p", (void*)initializeLoader);
|
||||
#endif
|
||||
|
||||
/* Get Android environment info from SDL */
|
||||
env = (JNIEnv *)SDL_GetAndroidJNIEnv();
|
||||
if (!env) {
|
||||
SDL_SetError("Failed to get Android JNI environment");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((*env)->GetJavaVM(env, &vm) != 0) {
|
||||
SDL_SetError("Failed to get JavaVM from JNIEnv");
|
||||
return false;
|
||||
}
|
||||
|
||||
activity = (jobject)SDL_GetAndroidActivity();
|
||||
if (!activity) {
|
||||
SDL_SetError("Failed to get Android activity");
|
||||
return false;
|
||||
}
|
||||
|
||||
XrLoaderInitInfoAndroidKHR loaderInitInfo = {
|
||||
.type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR,
|
||||
.next = NULL,
|
||||
.applicationVM = vm,
|
||||
.applicationContext = activity
|
||||
};
|
||||
|
||||
result = initializeLoader((XrLoaderInitInfoBaseHeaderKHR *)&loaderInitInfo);
|
||||
if (XR_FAILED(result)) {
|
||||
SDL_SetError("xrInitializeLoaderKHR failed with result %d", (int)result);
|
||||
return false;
|
||||
}
|
||||
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: xrInitializeLoaderKHR succeeded");
|
||||
#endif
|
||||
|
||||
/* Store the xrGetInstanceProcAddr function - this one properly handles
|
||||
* all pre-instance calls (unlike Meta's forwardloader runtime negotiation) */
|
||||
OPENXR_xrGetInstanceProcAddr = loaderGetProcAddr;
|
||||
xrGetInstanceProcAddr = loaderGetProcAddr;
|
||||
|
||||
openxr_android_loader_initialized = true;
|
||||
return true;
|
||||
}
|
||||
#endif /* SDL_PLATFORM_ANDROID */
|
||||
|
||||
SDL_DECLSPEC void SDLCALL SDL_OpenXR_UnloadLibrary(void)
|
||||
{
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: UnloadLibrary called, current refcount=%d", openxr_load_refcount);
|
||||
#endif
|
||||
|
||||
// Don't actually unload if more than one module is using the libs...
|
||||
if (openxr_load_refcount > 0) {
|
||||
if (--openxr_load_refcount == 0) {
|
||||
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: Refcount reached 0, unloading library");
|
||||
#endif
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
/* On Android/Quest, don't actually unload the library or reset the loader state.
|
||||
* The Quest OpenXR runtime doesn't support being re-initialized after teardown.
|
||||
* xrInitializeLoaderKHR and xrNegotiateLoaderRuntimeInterface must only be called once.
|
||||
* We keep the library loaded and the loader initialized.
|
||||
*
|
||||
* IMPORTANT: We also keep xrGetInstanceProcAddr intact so we can reload other
|
||||
* function pointers on the next LoadLibrary call. Only NULL out the other symbols. */
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: Android - keeping library loaded and loader initialized");
|
||||
#endif
|
||||
|
||||
// Only NULL out non-essential function pointers, keep xrGetInstanceProcAddr
|
||||
#define SDL_OPENXR_SYM(name) \
|
||||
if (SDL_strcmp(#name, "xrGetInstanceProcAddr") != 0) { \
|
||||
OPENXR_##name = NULL; \
|
||||
}
|
||||
#include "SDL_openxrsym.h"
|
||||
#else
|
||||
// On non-Android, NULL everything and unload
|
||||
#define SDL_OPENXR_SYM(name) OPENXR_##name = NULL;
|
||||
#include "SDL_openxrsym.h"
|
||||
|
||||
SDL_UnloadObject(openxr_loader.lib);
|
||||
openxr_loader.lib = NULL;
|
||||
#endif
|
||||
}
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
else {
|
||||
SDL_Log("SDL/OpenXR: Refcount is now %d, not unloading", openxr_load_refcount);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// returns non-zero if all needed symbols were loaded.
|
||||
SDL_DECLSPEC bool SDLCALL SDL_OpenXR_LoadLibrary(void)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: LoadLibrary called, current refcount=%d, lib=%p", openxr_load_refcount, (void*)openxr_loader.lib);
|
||||
#endif
|
||||
|
||||
// deal with multiple modules (gpu, openxr, etc) needing these symbols...
|
||||
if (openxr_load_refcount++ == 0) {
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
/* On Android, the library may already be loaded if this is a reload after
|
||||
* unload (we don't actually unload on Android to preserve runtime state) */
|
||||
if (openxr_loader.lib == NULL) {
|
||||
#endif
|
||||
const char *path_hint = SDL_GetHint(SDL_HINT_OPENXR_LIBRARY);
|
||||
|
||||
// If a hint was specified, try that first
|
||||
if (path_hint && *path_hint) {
|
||||
openxr_loader.lib = SDL_LoadObject(path_hint);
|
||||
}
|
||||
|
||||
// If no hint or hint failed, try the default library names
|
||||
if (!openxr_loader.lib) {
|
||||
for (int i = 0; openxr_library_names[i] != NULL; i++) {
|
||||
openxr_loader.lib = SDL_LoadObject(openxr_library_names[i]);
|
||||
if (openxr_loader.lib) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!openxr_loader.lib) {
|
||||
SDL_SetError("Failed to load OpenXR loader library. "
|
||||
"On Windows, ensure openxr_loader.dll is in your application directory or PATH. "
|
||||
"On Linux, install the OpenXR loader package (libopenxr-loader) or set LD_LIBRARY_PATH. "
|
||||
"You can also use the SDL_HINT_OPENXR_LIBRARY hint to specify the loader path.");
|
||||
openxr_load_refcount--;
|
||||
return false;
|
||||
}
|
||||
#if defined(SDL_PLATFORM_ANDROID)
|
||||
} else {
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: Library already loaded (Android reload), skipping SDL_LoadObject");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
/* On Android, we need to initialize the loader before other functions work.
|
||||
* OPENXR_InitializeAndroidLoader() will return early if already initialized. */
|
||||
if (!OPENXR_InitializeAndroidLoader()) {
|
||||
SDL_UnloadObject(openxr_loader.lib);
|
||||
openxr_loader.lib = NULL;
|
||||
openxr_load_refcount--;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool failed = false;
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
/* On Android with Meta's forwardloader, we need special handling.
|
||||
* After calling xrInitializeLoaderKHR, the global functions should be available
|
||||
* either as direct exports from the forwardloader or via xrGetInstanceProcAddr(NULL, ...).
|
||||
*
|
||||
* Try getting functions directly from the forwardloader first since they'll go
|
||||
* through the proper forwarding path. */
|
||||
XrResult xrResult;
|
||||
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: Loading global functions...");
|
||||
#endif
|
||||
|
||||
/* First try to get functions directly from the forwardloader library */
|
||||
OPENXR_xrEnumerateApiLayerProperties = (PFN_xrEnumerateApiLayerProperties)SDL_LoadFunction(openxr_loader.lib, "xrEnumerateApiLayerProperties");
|
||||
OPENXR_xrCreateInstance = (PFN_xrCreateInstance)SDL_LoadFunction(openxr_loader.lib, "xrCreateInstance");
|
||||
OPENXR_xrEnumerateInstanceExtensionProperties = (PFN_xrEnumerateInstanceExtensionProperties)SDL_LoadFunction(openxr_loader.lib, "xrEnumerateInstanceExtensionProperties");
|
||||
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: Direct symbols - xrEnumerateApiLayerProperties=%p, xrCreateInstance=%p, xrEnumerateInstanceExtensionProperties=%p",
|
||||
(void*)OPENXR_xrEnumerateApiLayerProperties,
|
||||
(void*)OPENXR_xrCreateInstance,
|
||||
(void*)OPENXR_xrEnumerateInstanceExtensionProperties);
|
||||
#endif
|
||||
|
||||
/* If direct loading failed, fall back to xrGetInstanceProcAddr(NULL, ...) */
|
||||
if (OPENXR_xrEnumerateApiLayerProperties == NULL) {
|
||||
xrResult = xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrEnumerateApiLayerProperties", (PFN_xrVoidFunction*)&OPENXR_xrEnumerateApiLayerProperties);
|
||||
if (XR_FAILED(xrResult) || OPENXR_xrEnumerateApiLayerProperties == NULL) {
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: Failed to get xrEnumerateApiLayerProperties via xrGetInstanceProcAddr");
|
||||
#endif
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (OPENXR_xrCreateInstance == NULL) {
|
||||
xrResult = xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrCreateInstance", (PFN_xrVoidFunction*)&OPENXR_xrCreateInstance);
|
||||
if (XR_FAILED(xrResult) || OPENXR_xrCreateInstance == NULL) {
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: Failed to get xrCreateInstance via xrGetInstanceProcAddr");
|
||||
#endif
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (OPENXR_xrEnumerateInstanceExtensionProperties == NULL) {
|
||||
xrResult = xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrEnumerateInstanceExtensionProperties", (PFN_xrVoidFunction*)&OPENXR_xrEnumerateInstanceExtensionProperties);
|
||||
if (XR_FAILED(xrResult) || OPENXR_xrEnumerateInstanceExtensionProperties == NULL) {
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: Failed to get xrEnumerateInstanceExtensionProperties via xrGetInstanceProcAddr");
|
||||
#endif
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
SDL_Log("SDL/OpenXR: Final symbols - xrEnumerateApiLayerProperties=%p, xrCreateInstance=%p, xrEnumerateInstanceExtensionProperties=%p",
|
||||
(void*)OPENXR_xrEnumerateApiLayerProperties,
|
||||
(void*)OPENXR_xrCreateInstance,
|
||||
(void*)OPENXR_xrEnumerateInstanceExtensionProperties);
|
||||
|
||||
SDL_Log("SDL/OpenXR: Global functions loading %s", failed ? "FAILED" : "succeeded");
|
||||
#endif
|
||||
#else
|
||||
#define SDL_OPENXR_SYM(name) OPENXR_##name = (PFN_##name)OPENXR_GetSym(#name, &failed);
|
||||
#include "SDL_openxrsym.h"
|
||||
#endif
|
||||
|
||||
if (failed) {
|
||||
// in case something got loaded...
|
||||
SDL_OpenXR_UnloadLibrary();
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
#if DEBUG_DYNAMIC_OPENXR
|
||||
else {
|
||||
SDL_Log("SDL/OpenXR: Library already loaded (refcount=%d), skipping", openxr_load_refcount);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SDL_DECLSPEC PFN_xrGetInstanceProcAddr SDLCALL SDL_OpenXR_GetXrGetInstanceProcAddr(void)
|
||||
{
|
||||
if (xrGetInstanceProcAddr == NULL) {
|
||||
SDL_SetError("The OpenXR loader has not been loaded");
|
||||
}
|
||||
|
||||
return xrGetInstanceProcAddr;
|
||||
}
|
||||
|
||||
XrInstancePfns *SDL_OPENXR_LoadInstanceSymbols(XrInstance instance)
|
||||
{
|
||||
XrResult result;
|
||||
|
||||
XrInstancePfns *pfns = SDL_calloc(1, sizeof(XrInstancePfns));
|
||||
|
||||
#define SDL_OPENXR_INSTANCE_SYM(name) \
|
||||
result = xrGetInstanceProcAddr(instance, #name, (PFN_xrVoidFunction *)&pfns->name); \
|
||||
if (result != XR_SUCCESS) { \
|
||||
SDL_free(pfns); \
|
||||
return NULL; \
|
||||
}
|
||||
#include "SDL_openxrsym.h"
|
||||
|
||||
return pfns;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SDL_DECLSPEC bool SDLCALL SDL_OpenXR_LoadLibrary(void)
|
||||
{
|
||||
return SDL_SetError("OpenXR is not enabled in this build of SDL");
|
||||
}
|
||||
|
||||
SDL_DECLSPEC void SDLCALL SDL_OpenXR_UnloadLibrary(void)
|
||||
{
|
||||
SDL_SetError("OpenXR is not enabled in this build of SDL");
|
||||
}
|
||||
|
||||
SDL_DECLSPEC PFN_xrGetInstanceProcAddr SDLCALL SDL_OpenXR_GetXrGetInstanceProcAddr(void)
|
||||
{
|
||||
return (PFN_xrGetInstanceProcAddr)SDL_SetError("OpenXR is not enabled in this build of SDL");
|
||||
}
|
||||
|
||||
#endif // HAVE_GPU_OPENXR
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_openxrdyn_h_
|
||||
#define SDL_openxrdyn_h_
|
||||
|
||||
/* Use the internal header for vendored OpenXR includes */
|
||||
#include "SDL_openxr_internal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct XrInstancePfns
|
||||
{
|
||||
#define SDL_OPENXR_INSTANCE_SYM(name) \
|
||||
PFN_##name name;
|
||||
#include "SDL_openxrsym.h"
|
||||
} XrInstancePfns;
|
||||
|
||||
extern XrInstancePfns *SDL_OPENXR_LoadInstanceSymbols(XrInstance instance);
|
||||
|
||||
/* Define the function pointers */
|
||||
#define SDL_OPENXR_SYM(name) \
|
||||
extern PFN_##name OPENXR_##name;
|
||||
#include "SDL_openxrsym.h"
|
||||
|
||||
#define xrGetInstanceProcAddr OPENXR_xrGetInstanceProcAddr
|
||||
#define xrEnumerateApiLayerProperties OPENXR_xrEnumerateApiLayerProperties
|
||||
#define xrEnumerateInstanceExtensionProperties OPENXR_xrEnumerateInstanceExtensionProperties
|
||||
#define xrCreateInstance OPENXR_xrCreateInstance
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDL_openxrdyn_h_
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* *INDENT-OFF* */ // clang-format off
|
||||
|
||||
#include "../../video/khronos/openxr/openxr.h"
|
||||
|
||||
#ifndef SDL_OPENXR_SYM
|
||||
#define SDL_OPENXR_SYM(name)
|
||||
#endif
|
||||
|
||||
#ifndef SDL_OPENXR_INSTANCE_SYM
|
||||
#define SDL_OPENXR_INSTANCE_SYM(name)
|
||||
#endif
|
||||
|
||||
SDL_OPENXR_SYM(xrGetInstanceProcAddr)
|
||||
SDL_OPENXR_SYM(xrEnumerateApiLayerProperties)
|
||||
SDL_OPENXR_SYM(xrCreateInstance)
|
||||
SDL_OPENXR_SYM(xrEnumerateInstanceExtensionProperties)
|
||||
SDL_OPENXR_INSTANCE_SYM(xrEnumerateSwapchainFormats)
|
||||
SDL_OPENXR_INSTANCE_SYM(xrCreateSession)
|
||||
SDL_OPENXR_INSTANCE_SYM(xrGetSystem)
|
||||
SDL_OPENXR_INSTANCE_SYM(xrCreateSwapchain)
|
||||
SDL_OPENXR_INSTANCE_SYM(xrEnumerateSwapchainImages)
|
||||
SDL_OPENXR_INSTANCE_SYM(xrDestroyInstance)
|
||||
SDL_OPENXR_INSTANCE_SYM(xrDestroySwapchain)
|
||||
|
||||
#undef SDL_OPENXR_SYM
|
||||
#undef SDL_OPENXR_INSTANCE_SYM
|
||||
|
||||
/* *INDENT-ON* */ // clang-format on
|
||||
Reference in New Issue
Block a user