Atlas - SDL_shaders_gpu.c
Home / ext / SDL / src / render / gpu Lines: 1 | Size: 8615 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_internal.h" 22 23#ifdef SDL_VIDEO_RENDER_GPU 24 25#include "SDL_shaders_gpu.h" 26 27// SDL_GPU shader implementation 28 29typedef struct GPU_ShaderModuleSource 30{ 31 const unsigned char *code; 32 unsigned int code_len; 33 SDL_GPUShaderFormat format; 34} GPU_ShaderModuleSource; 35 36#if defined(SDL_GPU_VULKAN) && SDL_GPU_VULKAN 37#define IF_VULKAN(...) __VA_ARGS__ 38#define HAVE_SPIRV_SHADERS 1 39#include "shaders/spir-v.h" 40#else 41#define IF_VULKAN(...) 42#define HAVE_SPIRV_SHADERS 0 43#endif 44 45#ifdef SDL_GPU_D3D12 46#define IF_D3D12(...) __VA_ARGS__ 47#define HAVE_DXIL60_SHADERS 1 48#include "shaders/dxil.h" 49#else 50#define IF_D3D12(...) 51#define HAVE_DXIL60_SHADERS 0 52#endif 53 54#ifdef SDL_GPU_METAL 55#define IF_METAL(...) __VA_ARGS__ 56#define HAVE_METAL_SHADERS 1 57#include "shaders/msl.h" 58#else 59#define IF_METAL(...) 60#define HAVE_METAL_SHADERS 0 61#endif 62 63typedef struct GPU_ShaderSources 64{ 65 IF_VULKAN(GPU_ShaderModuleSource spirv;) 66 IF_D3D12(GPU_ShaderModuleSource dxil60;) 67 IF_METAL(GPU_ShaderModuleSource msl;) 68 unsigned int num_samplers; 69 unsigned int num_uniform_buffers; 70} GPU_ShaderSources; 71 72#define SHADER_SPIRV(code) \ 73 IF_VULKAN(.spirv = { code, sizeof(code), SDL_GPU_SHADERFORMAT_SPIRV }, ) 74 75#define SHADER_DXIL60(code) \ 76 IF_D3D12(.dxil60 = { code, sizeof(code), SDL_GPU_SHADERFORMAT_DXIL }, ) 77 78#define SHADER_METAL(code) \ 79 IF_METAL(.msl = { code, sizeof(code), SDL_GPU_SHADERFORMAT_MSL }, ) 80 81// clang-format off 82static const GPU_ShaderSources vert_shader_sources[NUM_VERT_SHADERS] = { 83 [VERT_SHADER_LINEPOINT] = { 84 .num_samplers = 0, 85 .num_uniform_buffers = 1, 86 SHADER_SPIRV(linepoint_vert_spv) 87 SHADER_DXIL60(linepoint_vert_dxil) 88 SHADER_METAL(linepoint_vert_msl) 89 }, 90 [VERT_SHADER_TRI_COLOR] = { 91 .num_samplers = 0, 92 .num_uniform_buffers = 1, 93 SHADER_SPIRV(tri_color_vert_spv) 94 SHADER_DXIL60(tri_color_vert_dxil) 95 SHADER_METAL(tri_color_vert_msl) 96 }, 97 [VERT_SHADER_TRI_TEXTURE] = { 98 .num_samplers = 0, 99 .num_uniform_buffers = 1, 100 SHADER_SPIRV(tri_texture_vert_spv) 101 SHADER_DXIL60(tri_texture_vert_dxil) 102 SHADER_METAL(tri_texture_vert_msl) 103 }, 104}; 105 106static const GPU_ShaderSources frag_shader_sources[NUM_FRAG_SHADERS] = { 107 [FRAG_SHADER_COLOR] = { 108 .num_samplers = 0, 109 .num_uniform_buffers = 1, 110 SHADER_SPIRV(color_frag_spv) 111 SHADER_DXIL60(color_frag_dxil) 112 SHADER_METAL(color_frag_msl) 113 }, 114 [FRAG_SHADER_TEXTURE_RGB] = { 115 .num_samplers = 1, 116 .num_uniform_buffers = 1, 117 SHADER_SPIRV(texture_rgb_frag_spv) 118 SHADER_DXIL60(texture_rgb_frag_dxil) 119 SHADER_METAL(texture_rgb_frag_msl) 120 }, 121 [FRAG_SHADER_TEXTURE_RGBA] = { 122 .num_samplers = 1, 123 .num_uniform_buffers = 1, 124 SHADER_SPIRV(texture_rgba_frag_spv) 125 SHADER_DXIL60(texture_rgba_frag_dxil) 126 SHADER_METAL(texture_rgba_frag_msl) 127 }, 128 [FRAG_SHADER_TEXTURE_ADVANCED] = { 129 .num_samplers = 3, 130 .num_uniform_buffers = 1, 131 SHADER_SPIRV(texture_advanced_frag_spv) 132 SHADER_DXIL60(texture_advanced_frag_dxil) 133 SHADER_METAL(texture_advanced_frag_msl) 134 }, 135}; 136// clang-format on 137 138static SDL_GPUShader *CompileShader(const GPU_ShaderSources *sources, SDL_GPUDevice *device, SDL_GPUShaderStage stage) 139{ 140 const GPU_ShaderModuleSource *sms = NULL; 141 SDL_GPUShaderFormat formats = SDL_GetGPUShaderFormats(device); 142 143 if (formats == SDL_GPU_SHADERFORMAT_INVALID) { 144 // SDL_GetGPUShaderFormats already set the error 145 return NULL; 146#if HAVE_SPIRV_SHADERS 147 } else if (formats & SDL_GPU_SHADERFORMAT_SPIRV) { 148 sms = &sources->spirv; 149#endif // HAVE_SPIRV_SHADERS 150#if HAVE_DXIL60_SHADERS 151 } else if (formats & SDL_GPU_SHADERFORMAT_DXIL) { 152 sms = &sources->dxil60; 153#endif // HAVE_DXIL60_SHADERS 154#if HAVE_METAL_SHADERS 155 } else if (formats & SDL_GPU_SHADERFORMAT_MSL) { 156 sms = &sources->msl; 157#endif // HAVE_METAL_SHADERS 158 } else { 159 SDL_SetError("Unsupported GPU backend"); 160 return NULL; 161 } 162 163 SDL_GPUShaderCreateInfo sci = { 0 }; 164 sci.code = sms->code; 165 sci.code_size = sms->code_len; 166 sci.format = sms->format; 167 // FIXME not sure if this is correct 168 sci.entrypoint = 169#if HAVE_METAL_SHADERS 170 (sms == &sources->msl) ? "main0" : 171#endif // HAVE_METAL_SHADERS 172 "main"; 173 sci.num_samplers = sources->num_samplers; 174 sci.num_uniform_buffers = sources->num_uniform_buffers; 175 sci.stage = stage; 176 177 return SDL_CreateGPUShader(device, &sci); 178} 179 180bool GPU_InitShaders(GPU_Shaders *shaders, SDL_GPUDevice *device) 181{ 182 for (int i = 0; i < SDL_arraysize(vert_shader_sources); ++i) { 183 shaders->vert_shaders[i] = CompileShader( 184 &vert_shader_sources[i], device, SDL_GPU_SHADERSTAGE_VERTEX); 185 if (shaders->vert_shaders[i] == NULL) { 186 GPU_ReleaseShaders(shaders, device); 187 return false; 188 } 189 } 190 191 for (int i = 0; i < SDL_arraysize(frag_shader_sources); ++i) { 192 if (i == FRAG_SHADER_TEXTURE_CUSTOM) { 193 continue; 194 } 195 shaders->frag_shaders[i] = CompileShader( 196 &frag_shader_sources[i], device, SDL_GPU_SHADERSTAGE_FRAGMENT); 197 if (shaders->frag_shaders[i] == NULL) { 198 GPU_ReleaseShaders(shaders, device); 199 return false; 200 } 201 } 202 203 return true; 204} 205 206void GPU_ReleaseShaders(GPU_Shaders *shaders, SDL_GPUDevice *device) 207{ 208 for (int i = 0; i < SDL_arraysize(shaders->vert_shaders); ++i) { 209 SDL_ReleaseGPUShader(device, shaders->vert_shaders[i]); 210 shaders->vert_shaders[i] = NULL; 211 } 212 213 for (int i = 0; i < SDL_arraysize(shaders->frag_shaders); ++i) { 214 if (i == FRAG_SHADER_TEXTURE_CUSTOM) { 215 continue; 216 } 217 SDL_ReleaseGPUShader(device, shaders->frag_shaders[i]); 218 shaders->frag_shaders[i] = NULL; 219 } 220} 221 222SDL_GPUShader *GPU_GetVertexShader(GPU_Shaders *shaders, GPU_VertexShaderID id) 223{ 224 SDL_assert((unsigned int)id < SDL_arraysize(shaders->vert_shaders)); 225 SDL_GPUShader *shader = shaders->vert_shaders[id]; 226 SDL_assert(shader != NULL); 227 return shader; 228} 229 230SDL_GPUShader *GPU_GetFragmentShader(GPU_Shaders *shaders, GPU_FragmentShaderID id) 231{ 232 SDL_assert((unsigned int)id < SDL_arraysize(shaders->frag_shaders)); 233 SDL_GPUShader *shader = shaders->frag_shaders[id]; 234 SDL_assert(shader != NULL); 235 return shader; 236} 237 238void GPU_FillSupportedShaderFormats(SDL_PropertiesID props) 239{ 240 bool custom_shaders = false; 241 if (SDL_GetBooleanProperty(props, SDL_PROP_RENDERER_CREATE_GPU_SHADERS_SPIRV_BOOLEAN, false)) { 242 SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN, HAVE_SPIRV_SHADERS); 243 custom_shaders = true; 244 } 245 if (SDL_GetBooleanProperty(props, SDL_PROP_RENDERER_CREATE_GPU_SHADERS_DXIL_BOOLEAN, false)) { 246 SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN, HAVE_DXIL60_SHADERS); 247 custom_shaders = true; 248 } 249 if (SDL_GetBooleanProperty(props, SDL_PROP_RENDERER_CREATE_GPU_SHADERS_MSL_BOOLEAN, false)) { 250 SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN, HAVE_METAL_SHADERS); 251 custom_shaders = true; 252 } 253 if (!custom_shaders) { 254 SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN, HAVE_SPIRV_SHADERS); 255 SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN, HAVE_DXIL60_SHADERS); 256 SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN, HAVE_METAL_SHADERS); 257 } 258} 259 260#endif // SDL_VIDEO_RENDER_GPU 261[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.