summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/render/gpu/SDL_shaders_gpu.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
committer3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
commit5a079a2d114f96d4847d1ee305d5b7c16eeec50e (patch)
tree8926ab44f168acf787d8e19608857b3af0f82758 /contrib/SDL-3.2.8/src/render/gpu/SDL_shaders_gpu.c
Initial commit
Diffstat (limited to 'contrib/SDL-3.2.8/src/render/gpu/SDL_shaders_gpu.c')
-rw-r--r--contrib/SDL-3.2.8/src/render/gpu/SDL_shaders_gpu.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/render/gpu/SDL_shaders_gpu.c b/contrib/SDL-3.2.8/src/render/gpu/SDL_shaders_gpu.c
new file mode 100644
index 0000000..a56fb0c
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/render/gpu/SDL_shaders_gpu.c
@@ -0,0 +1,232 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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/dxil60.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/metal.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_sm60_dxil)
88 SHADER_METAL(linepoint_vert_metal)
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_sm60_dxil)
95 SHADER_METAL(tri_color_vert_metal)
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_sm60_dxil)
102 SHADER_METAL(tri_texture_vert_metal)
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 = 0,
110 SHADER_SPIRV(color_frag_spv)
111 SHADER_DXIL60(color_frag_sm60_dxil)
112 SHADER_METAL(color_frag_metal)
113 },
114 [FRAG_SHADER_TEXTURE_RGB] = {
115 .num_samplers = 1,
116 .num_uniform_buffers = 0,
117 SHADER_SPIRV(texture_rgb_frag_spv)
118 SHADER_DXIL60(texture_rgb_frag_sm60_dxil)
119 SHADER_METAL(texture_rgb_frag_metal)
120 },
121 [FRAG_SHADER_TEXTURE_RGBA] = {
122 .num_samplers = 1,
123 .num_uniform_buffers = 0,
124 SHADER_SPIRV(texture_rgba_frag_spv)
125 SHADER_DXIL60(texture_rgba_frag_sm60_dxil)
126 SHADER_METAL(texture_rgba_frag_metal)
127 },
128};
129// clang-format on
130
131static SDL_GPUShader *CompileShader(const GPU_ShaderSources *sources, SDL_GPUDevice *device, SDL_GPUShaderStage stage)
132{
133 const GPU_ShaderModuleSource *sms = NULL;
134 SDL_GPUShaderFormat formats = SDL_GetGPUShaderFormats(device);
135
136 if (formats == SDL_GPU_SHADERFORMAT_INVALID) {
137 // SDL_GetGPUShaderFormats already set the error
138 return NULL;
139#if HAVE_SPIRV_SHADERS
140 } else if (formats & SDL_GPU_SHADERFORMAT_SPIRV) {
141 sms = &sources->spirv;
142#endif // HAVE_SPIRV_SHADERS
143#if HAVE_DXIL60_SHADERS
144 } else if (formats & SDL_GPU_SHADERFORMAT_DXIL) {
145 sms = &sources->dxil60;
146#endif // HAVE_DXIL60_SHADERS
147#if HAVE_METAL_SHADERS
148 } else if (formats & SDL_GPU_SHADERFORMAT_MSL) {
149 sms = &sources->msl;
150#endif // HAVE_METAL_SHADERS
151 } else {
152 SDL_SetError("Unsupported GPU backend");
153 return NULL;
154 }
155
156 SDL_GPUShaderCreateInfo sci = { 0 };
157 sci.code = sms->code;
158 sci.code_size = sms->code_len;
159 sci.format = sms->format;
160 // FIXME not sure if this is correct
161 sci.entrypoint =
162#if HAVE_METAL_SHADERS
163 (sms == &sources->msl) ? "main0" :
164#endif // HAVE_METAL_SHADERS
165 "main";
166 sci.num_samplers = sources->num_samplers;
167 sci.num_uniform_buffers = sources->num_uniform_buffers;
168 sci.stage = stage;
169
170 return SDL_CreateGPUShader(device, &sci);
171}
172
173bool GPU_InitShaders(GPU_Shaders *shaders, SDL_GPUDevice *device)
174{
175 for (int i = 0; i < SDL_arraysize(vert_shader_sources); ++i) {
176 shaders->vert_shaders[i] = CompileShader(
177 &vert_shader_sources[i], device, SDL_GPU_SHADERSTAGE_VERTEX);
178 if (shaders->vert_shaders[i] == NULL) {
179 GPU_ReleaseShaders(shaders, device);
180 return false;
181 }
182 }
183
184 for (int i = 0; i < SDL_arraysize(frag_shader_sources); ++i) {
185 shaders->frag_shaders[i] = CompileShader(
186 &frag_shader_sources[i], device, SDL_GPU_SHADERSTAGE_FRAGMENT);
187 if (shaders->frag_shaders[i] == NULL) {
188 GPU_ReleaseShaders(shaders, device);
189 return false;
190 }
191 }
192
193 return true;
194}
195
196void GPU_ReleaseShaders(GPU_Shaders *shaders, SDL_GPUDevice *device)
197{
198 for (int i = 0; i < SDL_arraysize(shaders->vert_shaders); ++i) {
199 SDL_ReleaseGPUShader(device, shaders->vert_shaders[i]);
200 shaders->vert_shaders[i] = NULL;
201 }
202
203 for (int i = 0; i < SDL_arraysize(shaders->frag_shaders); ++i) {
204 SDL_ReleaseGPUShader(device, shaders->frag_shaders[i]);
205 shaders->frag_shaders[i] = NULL;
206 }
207}
208
209SDL_GPUShader *GPU_GetVertexShader(GPU_Shaders *shaders, GPU_VertexShaderID id)
210{
211 SDL_assert((unsigned int)id < SDL_arraysize(shaders->vert_shaders));
212 SDL_GPUShader *shader = shaders->vert_shaders[id];
213 SDL_assert(shader != NULL);
214 return shader;
215}
216
217SDL_GPUShader *GPU_GetFragmentShader(GPU_Shaders *shaders, GPU_FragmentShaderID id)
218{
219 SDL_assert((unsigned int)id < SDL_arraysize(shaders->frag_shaders));
220 SDL_GPUShader *shader = shaders->frag_shaders[id];
221 SDL_assert(shader != NULL);
222 return shader;
223}
224
225void GPU_FillSupportedShaderFormats(SDL_PropertiesID props)
226{
227 SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN, HAVE_SPIRV_SHADERS);
228 SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN, HAVE_DXIL60_SHADERS);
229 SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN, HAVE_METAL_SHADERS);
230}
231
232#endif // SDL_VIDEO_RENDER_GPU