-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshader.cpp
More file actions
123 lines (118 loc) · 3.85 KB
/
Copy pathshader.cpp
File metadata and controls
123 lines (118 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <SDL3/SDL.h>
#include <cassert>
#include <cstdint>
#include <exception>
#include <format>
#include <fstream>
#include <iterator>
#include <string>
#include <string_view>
#include "json.hpp"
#include "shader.hpp"
static void* Load(SDL_GPUDevice* device, const std::string_view& name)
{
SDL_GPUShaderFormat shaderFormat = SDL_GetGPUShaderFormats(device);
const char* entrypoint;
const char* fileExtension;
if (shaderFormat & SDL_GPU_SHADERFORMAT_SPIRV)
{
shaderFormat = SDL_GPU_SHADERFORMAT_SPIRV;
entrypoint = "main";
fileExtension = "spv";
}
else if (shaderFormat & SDL_GPU_SHADERFORMAT_DXIL)
{
shaderFormat = SDL_GPU_SHADERFORMAT_DXIL;
entrypoint = "main";
fileExtension = "dxil";
}
else if (shaderFormat & SDL_GPU_SHADERFORMAT_MSL)
{
shaderFormat = SDL_GPU_SHADERFORMAT_MSL;
entrypoint = "main0";
fileExtension = "msl";
}
else
{
assert(false);
}
std::string shaderPath = std::format("{}.{}", name, fileExtension);
std::ifstream shaderFile(shaderPath, std::ios::binary);
if (shaderFile.fail())
{
SDL_Log("Failed to open shader: %s", shaderPath.data());
return nullptr;
}
std::string jsonPath = std::format("{}.json", name);
std::ifstream jsonFile(jsonPath, std::ios::binary);
if (jsonFile.fail())
{
SDL_Log("Failed to open json: %s", jsonPath.data());
return nullptr;
}
std::string shaderData(std::istreambuf_iterator<char>(shaderFile), {});
nlohmann::json json;
try
{
jsonFile >> json;
}
catch (const std::exception& exception)
{
SDL_Log("Failed to parse json: %s, %s", jsonPath.data(), exception.what());
return nullptr;
}
void* shader = nullptr;
if (name.contains(".comp"))
{
SDL_GPUComputePipelineCreateInfo info{};
info.num_samplers = json["samplers"];
info.num_readonly_storage_textures = json["readonly_storage_textures"];
info.num_readonly_storage_buffers = json["readonly_storage_buffers"];
info.num_readwrite_storage_textures = json["readwrite_storage_textures"];
info.num_readwrite_storage_buffers = json["readwrite_storage_buffers"];
info.num_uniform_buffers = json["uniform_buffers"];
info.threadcount_x = json["threadcount_x"];
info.threadcount_y = json["threadcount_y"];
info.threadcount_z = json["threadcount_z"];
info.code = reinterpret_cast<Uint8*>(shaderData.data());
info.code_size = shaderData.size();
info.entrypoint = entrypoint;
info.format = shaderFormat;
shader = SDL_CreateGPUComputePipeline(device, &info);
}
else
{
SDL_GPUShaderCreateInfo info{};
info.num_samplers = json["samplers"];
info.num_storage_textures = json["storage_textures"];
info.num_storage_buffers = json["storage_buffers"];
info.num_uniform_buffers = json["uniform_buffers"];
info.code = reinterpret_cast<Uint8*>(shaderData.data());
info.code_size = shaderData.size();
info.entrypoint = entrypoint;
info.format = shaderFormat;
if (name.contains(".frag"))
{
info.stage = SDL_GPU_SHADERSTAGE_FRAGMENT;
}
else
{
info.stage = SDL_GPU_SHADERSTAGE_VERTEX;
}
shader = SDL_CreateGPUShader(device, &info);
}
if (!shader)
{
SDL_Log("Failed to create shader: %s, %s", name.data(), SDL_GetError());
return nullptr;
}
return shader;
}
SDL_GPUShader* LoadShader(SDL_GPUDevice* device, const std::string_view& name)
{
return static_cast<SDL_GPUShader*>(Load(device, name));
}
SDL_GPUComputePipeline* LoadComputePipeline(SDL_GPUDevice* device, const std::string_view& name)
{
return static_cast<SDL_GPUComputePipeline*>(Load(device, name));
}