From 767459e4cdb3c5dee210656332210317fd4ffc1f Mon Sep 17 00:00:00 2001 From: SDL Wiki Bot Date: Tue, 11 Aug 2026 05:04:02 +0000 Subject: [PATCH] Sync SDL3 wiki -> header [ci skip] --- include/SDL3/SDL_gpu.h | 208 ++++++++++++++++++++++++++++++-------- include/SDL3/SDL_system.h | 2 + include/SDL3/SDL_timer.h | 4 +- 3 files changed, 172 insertions(+), 42 deletions(-) diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h index a1620ab081..cc8cb85492 100644 --- a/include/SDL3/SDL_gpu.h +++ b/include/SDL3/SDL_gpu.h @@ -750,6 +750,13 @@ typedef enum SDL_GPUIndexElementSize * Unless D16_UNORM is sufficient for your purposes, always check which of * D24/D32 is supported before creating a depth-stencil texture! * + * For SIMULTANEOUS_READ_WRITE usage, the following formats are universally + * supported: + * + * - R32_FLOAT + * - R32_UINT + * - R32_INT + * * \since This enum is available since SDL 3.2.0. * * \sa SDL_CreateGPUTexture @@ -2712,57 +2719,174 @@ extern SDL_DECLSPEC SDL_GPUSampler * SDLCALL SDL_CreateGPUSampler( /** * Creates a shader to be used when creating a graphics pipeline. * - * Shader resource bindings must be authored to follow a particular order - * depending on the shader format. + * Shader resource bindings must be authored to follow a particular convention + * depending on the shader format. See below for details. * - * For SPIR-V shaders, use the following resource sets: + * --- * - * For vertex shaders: + * **SPIR-V** * - * - 0: Sampled textures, followed by storage textures, followed by storage - * buffers - * - 1: Uniform buffers + * For vertex shaders, use: - Set 0 for samplers, storage textures, and + * storage buffers - Set 1 for uniform data * - * For fragment shaders: + * For fragment shaders, use: - Set 2 for samplers, storage textures, and + * storage buffers - Set 3 for uniform data * - * - 2: Sampled textures, followed by storage textures, followed by storage - * buffers - * - 3: Uniform buffers + * The first resource in a given set must have a `binding` of 0. Additional + * resources must appear at consecutive bindings (1, 2, etc), leaving no gaps + * in the set. * - * For DXBC and DXIL shaders, use the following register order: + * All samplers must come first in the binding order, in order of how they are + * bound via `SDL_BindGPU*Samplers()`. * - * For vertex shaders: + * All storage textures must come after all samplers in the binding order, in + * order of how they are bound via `SDL_Bind*StorageTextures()`. * - * - (t[n], space0): Sampled textures, followed by storage textures, followed - * by storage buffers - * - (s[n], space0): Samplers with indices corresponding to the sampled - * textures - * - (b[n], space1): Uniform buffers + * All storage buffers must come after all storage textures in the binding + * order, in order of how they are bound via `SDL_Bind*StorageBuffers()`. * - * For pixel shaders: + * **Example** * - * - (t[n], space2): Sampled textures, followed by storage textures, followed - * by storage buffers - * - (s[n], space2): Samplers with indices corresponding to the sampled - * textures - * - (b[n], space3): Uniform buffers + * If a vertex shader binds 2 samplers, 2 storage textures, 2 storage buffers, + * and 2 uniform buffers, its binding layout should look like this: * - * For MSL/metallib, use the following order: + * ```glsl + * // Any samplers come first in the set, in SDL bind slot order + * layout(set = 0, binding = 0) sampler2d samplerBoundToSlot0; + * layout(set = 0, binding = 1) sampler2d samplerBoundToSlot1; + * // Any storage textures come next in the set, in SDL bind slot order + * layout(set = 0, binding = 2) texture2d storageTextureBoundToSlot0; + * layout(set = 0, binding = 3) texture2d storageTextureBoundToSlot1; + * // Any storage buffers come next in the set, in SDL bind slot order + * layout(set = 0, binding = 4) buffer storageBufferBoundToSlot0; + * layout(set = 0, binding = 5) buffer storageBufferBoundToSlot1; + * // Any uniform buffers are in their own set, in SDL slot order + * layout(set = 1, binding = 0) uniform UniformDataBoundToSlot0 {}; + * layout(set = 1, binding = 1) uniform UniformDataBoundToSlot1 {}; + * ``` * - * - [[texture]]: Sampled textures, followed by storage textures - * - [[sampler]]: Samplers with indices corresponding to the sampled textures - * - [[buffer]]: Uniform buffers, followed by storage buffers. Vertex buffer 0 - * is bound at [[buffer(14)]], vertex buffer 1 at [[buffer(15)]], and so on. - * Rather than manually authoring vertex buffer indices, use the - * [[stage_in]] attribute which will automatically use the vertex input - * information from the SDL_GPUGraphicsPipeline. + * --- * - * Shader semantics other than system-value semantics do not matter in D3D12 - * and for ease of use the SDL implementation assumes that non system-value - * semantics will all be TEXCOORD. If you are using HLSL as the shader source - * language, your vertex semantics should start at TEXCOORD0 and increment - * like so: TEXCOORD1, TEXCOORD2, etc. If you wish to change the semantic - * prefix to something other than TEXCOORD you can use + * **DXBC / DXIL (HLSL)** + * + * For vertex shaders, use: - `(t[n], space0)` for sampled textures, storage + * textures, and storage buffers - `(s[n], space0)` for samplers - `(b[n], + * space1)` for uniform data + * + * For fragment (aka "pixel") shaders, use: - `(t[n], space2)` for sampled + * textures, storage textures, and storage buffers - `(s[n], space2)` for + * samplers - `(b[n], space3)` for uniform data + * + * The first resource in a given register set must have a register index of + * `0`. Additional resources must appear at consecutive indices (1, 2, etc), + * leaving no gaps in the register set. + * + * All sampled textures must come first in the `t` register set, in order of + * how they are bound via `SDL_BindGPU*Samplers()`. + * + * All sampler objects must be in the `s` register set, in the same order as + * the textures above. + * + * All storage textures must come after all samplers in the `t` register set, + * in order of how they are bound via `SDL_Bind*StorageTextures()`. + * + * All storage buffers must come after all storage textures in the `t` + * register set, in order of how they are bound via + * `SDL_Bind*StorageBuffers()`. + * + * **Example** + * + * If a pixel shader binds 2 samplers, 2 storage textures, 2 storage buffers, + * and 2 uniform buffers, its binding layout should look like this: + * + * ```c + * // Any samplers and sampled textures come first in their respective register sets, in SDL bind slot order + * SamplerState SamplerBoundToSlot0 : register( s0, space2 ); + * SamplerState SamplerBoundToSlot1 : register( s1, space2 ); + * Texture2D SampledTextureBoundToSlot0 : register( t0, space2 ); + * Texture2D SampledTextureBoundToSlot1 : register( t1, space2 ); + * // Any storage textures come next in the `t` register set, in SDL bind slot order + * Texture2D StorageTextureBoundToSlot0 : register( t2, space2 ); + * Texture2D StorageTextureBoundToSlot1 : register( t3, space2 ); + * // Any storage buffers come next in the `t` register set, in SDL bind slot order + * ByteAddressBuffer StorageBufferBoundToSlot0 : register( t4, space2 ); + * ByteAddressBuffer StorageBufferBoundToSlot0 : register( t4, space2 ); + * // Any uniform buffers are in the `b` register set *and* in their own space, in SDL slot order + * cbuffer UniformDataBoundToSlot0 : register( b0, space4 ) { ... }; + * cbuffer UniformDataBoundToSlot1 : register( b1, space4 ) { ... }; + * ``` + * + * --- + * + * **MSL / Metallib (Metal Shading Language)** + * + * The first resource in a given argument table must have an index of `0`. + * Additional resources must appear at consecutive indices (1, 2, etc), + * leaving no gaps in the table. (_Except_ in the case of vertex buffers, + * which are mentioned below.) + * + * All sampled textures must come first in the `[[texture]]` argument table, + * in order of how they are bound via `SDL_BindGPU*Samplers()`. + * + * All sampler objects must be in the `[[sampler]]` argument table, in the + * same order as the textures above. + * + * All storage textures must come after all sampled textures in the + * `[[texture]]` argument table, in order of how they are bound via + * `SDL_BindGPU*StorageTextures()`. + * + * All uniform buffers must come first in the `[[buffer]]` argument table, in + * order of their slots in `SDL_PushGPU*UniformData()`. + * + * All storage buffers must come after all uniform buffers in the `[[buffer]]` + * argument table, in order of how they are bound via + * `SDL_BindGPU*StorageBuffers()`. + * + * In Metal, vertex buffers are also included in the `[[buffer]]` argument + * table. To work around this, SDL forces the vertex buffer bound to slot 0 to + * be bound at `[[buffer(14)]]`. The vertex buffer in slot 1 will be bound to + * `[[buffer(15)]]`, and so on. Rather than manually authoring vertex buffer + * indices, use the `[[stage_in]]` attribute which will automatically use the + * vertex input information from the SDL_GPUGraphicsPipeline. + * + * **Example** + * + * For a vertex shader with 1 vertex buffer, 2 samplers, 2 storage textures, 2 + * storage buffers, and 2 uniform buffers, the main function signature should + * look something like this: + * + * ```c++ + * vertex VertexOutput ExampleVertexShader( + * // Vertex buffers are their own special thing... + * SomeVertexInput input [[stage_in]], // alternatively, SomeVertexInput input [[buffer(14)]] + * // Any samplers go in the `sampler` table, in SDL bind slot order + * sampler samplerBoundToSlot0 [[sampler(0)]], + * sampler samplerBoundToSlot1 [[sampler(1)]], + * // Any sampled textures come first in the `texture` table, in SDL bind slot order + * texture2d sampledTextureBoundToSlot0 [[texture(0)]], + * texture2d sampledTextureBoundToSlot1 [[texture(1)]], + * // Any storage textures come next in the `texture` table, in SDL bind slot order + * texture2d storageTextureBoundToSlot0 [[texture(2)]], + * texture2d storageTextureBoundToSlot1 [[texture(3)]], + * // Any uniform buffers come first in the `buffer` table, in SDL slot order + * constant SomeUniformStruct uniformDataBoundToSlot0 [[buffer(0)]], + * constant SomeUniformStruct uniformDataBoundToSlot1 [[buffer(1)]], + * // Any storage buffers come next in the `buffer` table, in SDL bind slot order + * device SomeBufferStruct& storageBufferBoundToSlot0 [[buffer(2)]], + * device SomeBufferStruct& storageBufferBoundToSlot1 [[buffer(3)]]); + * + * ``` + * + * --- + * + * Shader semantics other than system-value semantics do not matter in D3D12. + * For ease of use, the SDL implementation assumes that non system-value + * semantics will all be `TEXCOORD`. If you are using HLSL as the shader + * source language, your vertex semantics should start at `TEXCOORD0` and + * increment like so: `TEXCOORD1`, `TEXCOORD2`, etc. + * + * If you wish to change the semantic prefix to something other than + * `TEXCOORD` you can use * SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING with * SDL_CreateGPUDeviceWithProperties(). * @@ -2929,6 +3053,8 @@ extern SDL_DECLSPEC SDL_GPUBuffer * SDLCALL SDL_CreateGPUBuffer( * * \since This function is available since SDL 3.2.0. * + * \sa SDL_MapGPUTransferBuffer + * \sa SDL_UnmapGPUTransferBuffer * \sa SDL_UploadToGPUBuffer * \sa SDL_DownloadFromGPUBuffer * \sa SDL_UploadToGPUTexture @@ -3875,9 +4001,9 @@ extern SDL_DECLSPEC void SDLCALL SDL_EndGPUComputePass( /** * Maps a transfer buffer into application address space. * - * You must unmap the transfer buffer before encoding upload commands. The - * memory is owned by the graphics driver - do NOT call SDL_free() on the - * returned pointer. + * You must unmap the transfer buffer before encoding upload commands using + * SDL_UnmapGPUTransferBuffer. The memory is owned by the graphics driver - do + * NOT call SDL_free() on the returned pointer. * * \param device a GPU context. * \param transfer_buffer a transfer buffer. diff --git a/include/SDL3/SDL_system.h b/include/SDL3/SDL_system.h index 9e889df523..fb58b71c42 100644 --- a/include/SDL3/SDL_system.h +++ b/include/SDL3/SDL_system.h @@ -641,6 +641,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_IsPhone(void); * \threadsafety It is safe to call this function from any thread. * * \since This function is available since SDL 3.2.0. + * + * \sa SDL_IsPhone */ extern SDL_DECLSPEC bool SDLCALL SDL_IsTablet(void); diff --git a/include/SDL3/SDL_timer.h b/include/SDL3/SDL_timer.h index dfeec31f20..c03da14dc3 100644 --- a/include/SDL3/SDL_timer.h +++ b/include/SDL3/SDL_timer.h @@ -234,7 +234,9 @@ extern SDL_DECLSPEC Uint64 SDLCALL SDL_GetPerformanceCounter(void); /** * Get the count per second of the high resolution counter. * - * \returns a platform-specific count per second. + * \returns the frequency at which the result from SDL_GetPerformanceCounter + * is adjusted, measured in counts per second. This value is + * platform-dependent. * * \threadsafety It is safe to call this function from any thread. *