update SDL3 from 3.2.20 to 3.4.2
This commit is contained in:
+388
-162
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
@@ -35,7 +35,7 @@
|
||||
#define UNIFORM_BUFFER_SIZE 32768
|
||||
#define MAX_VERTEX_BUFFERS 16
|
||||
#define MAX_VERTEX_ATTRIBUTES 16
|
||||
#define MAX_COLOR_TARGET_BINDINGS 4
|
||||
#define MAX_COLOR_TARGET_BINDINGS 8
|
||||
#define MAX_PRESENT_COUNT 16
|
||||
#define MAX_FRAMES_IN_FLIGHT 3
|
||||
|
||||
@@ -446,6 +446,154 @@ static inline bool IsIntegerFormat(
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool IsCompressedFormat(
|
||||
SDL_GPUTextureFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC4_R_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC5_RG_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_FLOAT:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool FormatHasAlpha(
|
||||
SDL_GPUTextureFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_FLOAT:
|
||||
// ASTC textures may or may not have alpha; return true as this is mainly intended for validation
|
||||
return true;
|
||||
|
||||
case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_A8_UNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SNORM:
|
||||
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT:
|
||||
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT:
|
||||
case SDL_GPU_TEXTUREFORMAT_R32G32B32A32_UINT:
|
||||
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_INT:
|
||||
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_INT:
|
||||
case SDL_GPU_TEXTUREFORMAT_R32G32B32A32_INT:
|
||||
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline Uint32 IndexSize(SDL_GPUIndexElementSize size)
|
||||
{
|
||||
return (size == SDL_GPU_INDEXELEMENTSIZE_16BIT) ? 2 : 4;
|
||||
@@ -517,10 +665,12 @@ typedef struct SDL_GPURenderer SDL_GPURenderer;
|
||||
|
||||
struct SDL_GPUDevice
|
||||
{
|
||||
// Quit
|
||||
// Device
|
||||
|
||||
void (*DestroyDevice)(SDL_GPUDevice *device);
|
||||
|
||||
SDL_PropertiesID (*GetDeviceProperties)(SDL_GPUDevice *device);
|
||||
|
||||
// State Creation
|
||||
|
||||
SDL_GPUComputePipeline *(*CreateComputePipeline)(
|
||||
@@ -946,12 +1096,16 @@ struct SDL_GPUDevice
|
||||
|
||||
// Store this for SDL_gpu.c's debug layer
|
||||
bool debug_mode;
|
||||
bool default_enable_depth_clip;
|
||||
bool validate_feature_depth_clamp_disabled;
|
||||
bool validate_feature_anisotropy_disabled;
|
||||
};
|
||||
|
||||
#define ASSIGN_DRIVER_FUNC(func, name) \
|
||||
result->func = name##_##func;
|
||||
#define ASSIGN_DRIVER(name) \
|
||||
ASSIGN_DRIVER_FUNC(DestroyDevice, name) \
|
||||
ASSIGN_DRIVER_FUNC(GetDeviceProperties, name) \
|
||||
ASSIGN_DRIVER_FUNC(CreateComputePipeline, name) \
|
||||
ASSIGN_DRIVER_FUNC(CreateGraphicsPipeline, name) \
|
||||
ASSIGN_DRIVER_FUNC(CreateSampler, name) \
|
||||
@@ -1037,8 +1191,7 @@ struct SDL_GPUDevice
|
||||
typedef struct SDL_GPUBootstrap
|
||||
{
|
||||
const char *name;
|
||||
const SDL_GPUShaderFormat shader_formats;
|
||||
bool (*PrepareDriver)(SDL_VideoDevice *_this);
|
||||
bool (*PrepareDriver)(SDL_VideoDevice *_this, SDL_PropertiesID props);
|
||||
SDL_GPUDevice *(*CreateDevice)(bool debug_mode, bool prefer_low_power, SDL_PropertiesID props);
|
||||
} SDL_GPUBootstrap;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
@@ -31,7 +31,7 @@
|
||||
// Defines
|
||||
|
||||
#define METAL_FIRST_VERTEX_BUFFER_SLOT 14
|
||||
#define WINDOW_PROPERTY_DATA "SDL_GPUMetalWindowPropertyData"
|
||||
#define WINDOW_PROPERTY_DATA "SDL.internal.gpu.metal.data"
|
||||
#define SDL_GPU_SHADERSTAGE_COMPUTE 2
|
||||
|
||||
#define TRACK_RESOURCE(resource, type, array, count, capacity) \
|
||||
@@ -423,6 +423,8 @@ static MTLDepthClipMode SDLToMetal_DepthClipMode(
|
||||
|
||||
// Structs
|
||||
|
||||
typedef struct MetalRenderer MetalRenderer;
|
||||
|
||||
typedef struct MetalTexture
|
||||
{
|
||||
id<MTLTexture> handle;
|
||||
@@ -452,6 +454,8 @@ typedef struct MetalFence
|
||||
typedef struct MetalWindowData
|
||||
{
|
||||
SDL_Window *window;
|
||||
MetalRenderer *renderer;
|
||||
int refcount;
|
||||
SDL_MetalView view;
|
||||
CAMetalLayer *layer;
|
||||
SDL_GPUPresentMode presentMode;
|
||||
@@ -523,8 +527,6 @@ typedef struct MetalUniformBuffer
|
||||
Uint32 drawOffset;
|
||||
} MetalUniformBuffer;
|
||||
|
||||
typedef struct MetalRenderer MetalRenderer;
|
||||
|
||||
typedef struct MetalCommandBuffer
|
||||
{
|
||||
CommandBufferCommonHeader common;
|
||||
@@ -631,6 +633,7 @@ struct MetalRenderer
|
||||
id<MTLCommandQueue> queue;
|
||||
|
||||
bool debugMode;
|
||||
SDL_PropertiesID props;
|
||||
Uint32 allowedFramesInFlight;
|
||||
|
||||
MetalWindowData **claimedWindows;
|
||||
@@ -753,11 +756,20 @@ static void METAL_DestroyDevice(SDL_GPUDevice *device)
|
||||
// Release the command queue
|
||||
renderer->queue = nil;
|
||||
|
||||
// Release properties
|
||||
SDL_DestroyProperties(renderer->props);
|
||||
|
||||
// Free the primary structures
|
||||
SDL_free(renderer);
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
static SDL_PropertiesID METAL_GetDeviceProperties(SDL_GPUDevice *device)
|
||||
{
|
||||
MetalRenderer *renderer = (MetalRenderer *)device->driverData;
|
||||
return renderer->props;
|
||||
}
|
||||
|
||||
// Resource tracking
|
||||
|
||||
static void METAL_INTERNAL_TrackBuffer(
|
||||
@@ -814,6 +826,17 @@ typedef struct MetalLibraryFunction
|
||||
id<MTLFunction> function;
|
||||
} MetalLibraryFunction;
|
||||
|
||||
static bool METAL_INTERNAL_IsValidMetalLibrary(
|
||||
const Uint8 *code,
|
||||
size_t codeSize)
|
||||
{
|
||||
// Metal libraries have a 4 byte header containing `MTLB`.
|
||||
if (codeSize < 4 || code == NULL) {
|
||||
return false;
|
||||
}
|
||||
return SDL_memcmp(code, "MTLB", 4) == 0;
|
||||
}
|
||||
|
||||
// This function assumes that it's called from within an autorelease pool
|
||||
static MetalLibraryFunction METAL_INTERNAL_CompileShader(
|
||||
MetalRenderer *renderer,
|
||||
@@ -842,6 +865,11 @@ static MetalLibraryFunction METAL_INTERNAL_CompileShader(
|
||||
options:nil
|
||||
error:&error];
|
||||
} else if (format == SDL_GPU_SHADERFORMAT_METALLIB) {
|
||||
if (!METAL_INTERNAL_IsValidMetalLibrary(code, codeSize)) {
|
||||
SET_STRING_ERROR_AND_RETURN(
|
||||
"The provided shader code is not a valid Metal library!",
|
||||
libraryFunction);
|
||||
}
|
||||
data = dispatch_data_create(
|
||||
code,
|
||||
codeSize,
|
||||
@@ -1090,6 +1118,13 @@ static SDL_GPUGraphicsPipeline *METAL_CreateGraphicsPipeline(
|
||||
SDL_assert_release(!"CreateGraphicsPipeline was passed a vertex shader for the fragment stage");
|
||||
}
|
||||
}
|
||||
#ifdef SDL_PLATFORM_VISIONOS
|
||||
// The default is depth clipping enabled and it can't be changed
|
||||
if (!createinfo->rasterizer_state.enable_depth_clip) {
|
||||
SDL_assert_release(!"Rasterizer state enable_depth_clip must be true on this platform");
|
||||
}
|
||||
#endif
|
||||
|
||||
pipelineDescriptor = [MTLRenderPipelineDescriptor new];
|
||||
|
||||
// Blend
|
||||
@@ -1114,6 +1149,7 @@ static SDL_GPUGraphicsPipeline *METAL_CreateGraphicsPipeline(
|
||||
// Multisample
|
||||
|
||||
pipelineDescriptor.rasterSampleCount = SDLToMetal_SampleCount[createinfo->multisample_state.sample_count];
|
||||
pipelineDescriptor.alphaToCoverageEnabled = createinfo->multisample_state.enable_alpha_to_coverage;
|
||||
|
||||
// Depth Stencil
|
||||
|
||||
@@ -1778,7 +1814,8 @@ static void METAL_UploadToTexture(
|
||||
copyFromBuffer:bufferContainer->activeBuffer->handle
|
||||
sourceOffset:source->offset
|
||||
sourceBytesPerRow:BytesPerRow(destination->w, textureContainer->header.info.format)
|
||||
sourceBytesPerImage:SDL_CalculateGPUTextureFormatSize(textureContainer->header.info.format, destination->w, destination->h, destination->d)
|
||||
// sourceBytesPerImage expects the stride between 2D images (slices) of a 3D texture, not the size of the entire region
|
||||
sourceBytesPerImage:SDL_CalculateGPUTextureFormatSize(textureContainer->header.info.format, destination->w, destination->h, 1)
|
||||
sourceSize:MTLSizeMake(destination->w, destination->h, destination->d)
|
||||
toTexture:metalTexture->handle
|
||||
destinationSlice:destination->layer
|
||||
@@ -2292,6 +2329,8 @@ static void METAL_BeginRenderPass(
|
||||
depthStencilTargetInfo->cycle);
|
||||
|
||||
passDescriptor.depthAttachment.texture = texture->handle;
|
||||
passDescriptor.depthAttachment.level = depthStencilTargetInfo->mip_level;
|
||||
passDescriptor.depthAttachment.slice = depthStencilTargetInfo->layer;
|
||||
passDescriptor.depthAttachment.loadAction = SDLToMetal_LoadOp[depthStencilTargetInfo->load_op];
|
||||
passDescriptor.depthAttachment.storeAction = SDLToMetal_StoreOp[depthStencilTargetInfo->store_op];
|
||||
passDescriptor.depthAttachment.clearDepth = depthStencilTargetInfo->clear_depth;
|
||||
@@ -2325,8 +2364,8 @@ static void METAL_BeginRenderPass(
|
||||
|
||||
if (depthStencilTargetInfo != NULL) {
|
||||
MetalTextureContainer *container = (MetalTextureContainer *)depthStencilTargetInfo->texture;
|
||||
Uint32 w = container->header.info.width;
|
||||
Uint32 h = container->header.info.height;
|
||||
Uint32 w = container->header.info.width >> depthStencilTargetInfo->mip_level;
|
||||
Uint32 h = container->header.info.height >> depthStencilTargetInfo->mip_level;
|
||||
|
||||
if (w < vpWidth) {
|
||||
vpWidth = w;
|
||||
@@ -2372,6 +2411,7 @@ static void METAL_BindGraphicsPipeline(
|
||||
{
|
||||
@autoreleasepool {
|
||||
MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer;
|
||||
MetalGraphicsPipeline *previousPipeline = metalCommandBuffer->graphics_pipeline;
|
||||
MetalGraphicsPipeline *pipeline = (MetalGraphicsPipeline *)graphicsPipeline;
|
||||
SDL_GPURasterizerState *rast = &pipeline->rasterizerState;
|
||||
Uint32 i;
|
||||
@@ -2384,7 +2424,9 @@ static void METAL_BindGraphicsPipeline(
|
||||
[metalCommandBuffer->renderEncoder setTriangleFillMode:SDLToMetal_PolygonMode[pipeline->rasterizerState.fill_mode]];
|
||||
[metalCommandBuffer->renderEncoder setCullMode:SDLToMetal_CullMode[pipeline->rasterizerState.cull_mode]];
|
||||
[metalCommandBuffer->renderEncoder setFrontFacingWinding:SDLToMetal_FrontFace[pipeline->rasterizerState.front_face]];
|
||||
#ifndef SDL_PLATFORM_VISIONOS
|
||||
[metalCommandBuffer->renderEncoder setDepthClipMode:SDLToMetal_DepthClipMode(pipeline->rasterizerState.enable_depth_clip)];
|
||||
#endif
|
||||
[metalCommandBuffer->renderEncoder
|
||||
setDepthBias:((rast->enable_depth_bias) ? rast->depth_bias_constant_factor : 0)
|
||||
slopeScale:((rast->enable_depth_bias) ? rast->depth_bias_slope_factor : 0)
|
||||
@@ -2414,6 +2456,17 @@ static void METAL_BindGraphicsPipeline(
|
||||
metalCommandBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (previousPipeline && previousPipeline != pipeline) {
|
||||
// if the number of uniform buffers has changed, the storage buffers will move as well
|
||||
// and need a rebind at their new locations
|
||||
if (previousPipeline->header.num_vertex_uniform_buffers != pipeline->header.num_vertex_uniform_buffers) {
|
||||
metalCommandBuffer->needVertexStorageBufferBind = true;
|
||||
}
|
||||
if (previousPipeline->header.num_fragment_uniform_buffers != pipeline->header.num_fragment_uniform_buffers) {
|
||||
metalCommandBuffer->needFragmentStorageBufferBind = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3594,7 +3647,7 @@ static bool METAL_SupportsSwapchainComposition(
|
||||
}
|
||||
|
||||
// This function assumes that it's called from within an autorelease pool
|
||||
static Uint8 METAL_INTERNAL_CreateSwapchain(
|
||||
static bool METAL_INTERNAL_CreateSwapchain(
|
||||
MetalRenderer *renderer,
|
||||
MetalWindowData *windowData,
|
||||
SDL_GPUSwapchainComposition swapchainComposition,
|
||||
@@ -3666,7 +3719,7 @@ static Uint8 METAL_INTERNAL_CreateSwapchain(
|
||||
windowData->textureContainer.header.info.width = (Uint32)drawableSize.width;
|
||||
windowData->textureContainer.header.info.height = (Uint32)drawableSize.height;
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool METAL_SupportsPresentMode(
|
||||
@@ -3696,6 +3749,8 @@ static bool METAL_ClaimWindow(
|
||||
if (windowData == NULL) {
|
||||
windowData = (MetalWindowData *)SDL_calloc(1, sizeof(MetalWindowData));
|
||||
windowData->window = window;
|
||||
windowData->renderer = renderer;
|
||||
windowData->refcount = 1;
|
||||
|
||||
if (METAL_INTERNAL_CreateSwapchain(renderer, windowData, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC)) {
|
||||
SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData);
|
||||
@@ -3716,10 +3771,13 @@ static bool METAL_ClaimWindow(
|
||||
return true;
|
||||
} else {
|
||||
SDL_free(windowData);
|
||||
SET_STRING_ERROR_AND_RETURN("Could not create swapchain, failed to claim window", false);
|
||||
return false;
|
||||
}
|
||||
} else if (windowData->renderer == renderer) {
|
||||
++windowData->refcount;
|
||||
return true;
|
||||
} else {
|
||||
SET_ERROR_AND_RETURN("%s", "Window already claimed!", false);
|
||||
SET_STRING_ERROR_AND_RETURN("Window already claimed", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3733,7 +3791,15 @@ static void METAL_ReleaseWindow(
|
||||
MetalWindowData *windowData = METAL_INTERNAL_FetchWindowData(window);
|
||||
|
||||
if (windowData == NULL) {
|
||||
SET_STRING_ERROR_AND_RETURN("Window is not claimed by this SDL_GpuDevice", );
|
||||
return;
|
||||
}
|
||||
if (windowData->renderer != renderer) {
|
||||
SDL_SetError("Window not claimed by this device");
|
||||
return;
|
||||
}
|
||||
if (windowData->refcount > 1) {
|
||||
--windowData->refcount;
|
||||
return;
|
||||
}
|
||||
|
||||
METAL_Wait(driverData);
|
||||
@@ -3812,7 +3878,7 @@ static bool METAL_INTERNAL_AcquireSwapchainTexture(
|
||||
|
||||
windowData = METAL_INTERNAL_FetchWindowData(window);
|
||||
if (windowData == NULL) {
|
||||
SET_STRING_ERROR_AND_RETURN("Window is not claimed by this SDL_GpuDevice", false);
|
||||
SET_STRING_ERROR_AND_RETURN("Window is not claimed by this SDL_GPUDevice", false);
|
||||
}
|
||||
|
||||
// Update the window size
|
||||
@@ -4269,8 +4335,13 @@ static bool METAL_SupportsTextureFormat(
|
||||
|
||||
// Device Creation
|
||||
|
||||
static bool METAL_PrepareDriver(SDL_VideoDevice *this)
|
||||
static bool METAL_PrepareDriver(SDL_VideoDevice *this, SDL_PropertiesID props)
|
||||
{
|
||||
if (!SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN, false) &&
|
||||
!SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (@available(macOS 10.14, iOS 13.0, tvOS 13.0, *)) {
|
||||
return (this->Metal_CreateView != NULL);
|
||||
}
|
||||
@@ -4435,6 +4506,11 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD
|
||||
id<MTLDevice> device = NULL;
|
||||
bool hasHardwareSupport = false;
|
||||
|
||||
bool verboseLogs = SDL_GetBooleanProperty(
|
||||
props,
|
||||
SDL_PROP_GPU_DEVICE_CREATE_VERBOSE_BOOLEAN,
|
||||
true);
|
||||
|
||||
if (debugMode) {
|
||||
/* Due to a Metal driver quirk, once a MTLDevice has been created
|
||||
* with this environment variable set, the Metal validation layers
|
||||
@@ -4466,11 +4542,21 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD
|
||||
|
||||
#ifdef SDL_PLATFORM_MACOS
|
||||
hasHardwareSupport = true;
|
||||
bool allowMacFamily1 = SDL_GetBooleanProperty(
|
||||
props,
|
||||
SDL_PROP_GPU_DEVICE_CREATE_METAL_ALLOW_MACFAMILY1_BOOLEAN,
|
||||
false);
|
||||
if (@available(macOS 10.15, *)) {
|
||||
hasHardwareSupport = [device supportsFamily:MTLGPUFamilyMac2];
|
||||
hasHardwareSupport = allowMacFamily1 ?
|
||||
[device supportsFamily:MTLGPUFamilyMac1] :
|
||||
[device supportsFamily:MTLGPUFamilyMac2];
|
||||
} else if (@available(macOS 10.14, *)) {
|
||||
hasHardwareSupport = [device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily2_v1];
|
||||
hasHardwareSupport = allowMacFamily1 ?
|
||||
[device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v4] :
|
||||
[device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily2_v1];
|
||||
}
|
||||
#elif defined(SDL_PLATFORM_VISIONOS)
|
||||
hasHardwareSupport = true;
|
||||
#else
|
||||
if (@available(iOS 13.0, tvOS 13.0, *)) {
|
||||
hasHardwareSupport = [device supportsFamily:MTLGPUFamilyApple3];
|
||||
@@ -4488,12 +4574,20 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD
|
||||
renderer->device = device;
|
||||
renderer->queue = [device newCommandQueue];
|
||||
|
||||
// Print driver info
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Metal");
|
||||
SDL_LogInfo(
|
||||
SDL_LOG_CATEGORY_GPU,
|
||||
"Metal Device: %s",
|
||||
[device.name UTF8String]);
|
||||
renderer->props = SDL_CreateProperties();
|
||||
if (verboseLogs) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Metal");
|
||||
}
|
||||
|
||||
// Record device name
|
||||
const char *deviceName = [device.name UTF8String];
|
||||
SDL_SetStringProperty(
|
||||
renderer->props,
|
||||
SDL_PROP_GPU_DEVICE_NAME_STRING,
|
||||
deviceName);
|
||||
if (verboseLogs) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "Metal Device: %s", deviceName);
|
||||
}
|
||||
|
||||
// Remember debug mode
|
||||
renderer->debugMode = debugMode;
|
||||
@@ -4568,7 +4662,6 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD
|
||||
|
||||
SDL_GPUBootstrap MetalDriver = {
|
||||
"metal",
|
||||
SDL_GPU_SHADERFORMAT_MSL | SDL_GPU_SHADERFORMAT_METALLIB,
|
||||
METAL_PrepareDriver,
|
||||
METAL_CreateDevice
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
@@ -51,6 +51,9 @@ 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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user