Skip to content

Commit a29b48c

Browse files
committed
Add shdbin (precompiled shader binary)
1 parent 3e72957 commit a29b48c

95 files changed

Lines changed: 1338 additions & 748 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ option(PATHFINDER_BACKEND_OPENGL "Enable OpenGL backend" ON)
1212
option(PATHFINDER_BACKEND_VULKAN "Enable Vulkan backend" ON)
1313
option(PATHFINDER_BUILD_DEMO "Build demo" OFF)
1414
option(PATHFINDER_USE_D3D11 "Use D3D11" OFF)
15+
option(PATHFINDER_RUNTIME_SHADER_COMPLICATION "Compile shaders at runtime using SPV" OFF)
16+
option(PATHFINDER_BUILD_SHADER_GENERATOR "Shader generator" OFF)
1517

1618
# Identify Linux.
1719
if (UNIX AND NOT APPLE AND NOT ANDROID)
@@ -104,6 +106,13 @@ if ((WIN32 OR LINUX OR APPLE) AND NOT (EMSCRIPTEN OR ANDROID))
104106
target_link_libraries(pathfinder PUBLIC glfw)
105107
endif ()
106108

109+
if (PATHFINDER_RUNTIME_SHADER_COMPLICATION)
110+
add_subdirectory("third_party/spirv-cross")
111+
add_subdirectory("third_party/glslang")
112+
target_link_libraries(pathfinder PUBLIC spirv-cross glslang)
113+
target_compile_definitions(pathfinder PRIVATE PATHFINDER_USE_GLSLANG)
114+
endif ()
115+
107116
if (PATHFINDER_BUILD_DEMO)
108117
message("[Pathfinder] Build demo")
109118

@@ -127,3 +136,10 @@ if (PATHFINDER_BUILD_DEMO)
127136
add_subdirectory(demo/web)
128137
endif ()
129138
endif ()
139+
140+
if (PATHFINDER_BUILD_SHADER_GENERATOR)
141+
add_subdirectory("third_party/spirv-cross")
142+
add_subdirectory("third_party/glslang")
143+
144+
add_subdirectory(shader_generator)
145+
endif ()

download_deps.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import os
2+
import sys
3+
import platform
4+
5+
deps = [
6+
('https://github.com/KhronosGroup/glslang.git', 'glslang', 'vulkan-sdk-1.4.321'),
7+
('https://github.com/KhronosGroup/SPIRV-Cross.git', 'spirv-cross', 'vulkan-sdk-1.4.321'),
8+
('https://github.com/CLIUtils/CLI11.git', 'CLI11', 'v2.3.2'), # For shader builder only.
9+
]
10+
11+
12+
def download_deps():
13+
for url, name, branch in dev_deps:
14+
if not os.path.exists('third_party/' + name):
15+
cmd = 'git clone -b ' + branch + ' ' + url + ' third_party/' + name
16+
17+
print(cmd)
18+
os.system(cmd)
19+
20+
# Get glslang deps
21+
if name == "glslang":
22+
os.chdir('./3rd/glslang')
23+
os.system(python_alias + ' update_glslang_sources.py')
24+
os.chdir('../..')
25+
26+
27+
if __name__ == "__main__":
28+
python_alias = "python3"
29+
30+
if platform.system() == 'Windows':
31+
python_alias = "python"
32+
33+
download_deps()

pathfinder/core/d3d11/renderer.cpp

Lines changed: 82 additions & 109 deletions
Large diffs are not rendered by default.

pathfinder/core/d3d9/renderer.cpp

Lines changed: 49 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,14 @@
1010
#include "../paint/palette.h"
1111

1212
/* clang-format off */
13-
// SPV
14-
#include "../../shaders/generated/fill_frag_spv.h"
15-
#include "../../shaders/generated/fill_vert_spv.h"
16-
#include "../../shaders/generated/tile_clip_combine_frag_spv.h"
17-
#include "../../shaders/generated/tile_clip_combine_vert_spv.h"
18-
#include "../../shaders/generated/tile_clip_copy_frag_spv.h"
19-
#include "../../shaders/generated/tile_clip_copy_vert_spv.h"
20-
#include "../../shaders/generated/tile_frag_spv.h"
21-
#include "../../shaders/generated/tile_vert_spv.h"
22-
// GLSL
23-
#include "../../shaders/generated/fill_frag.h"
24-
#include "../../shaders/generated/fill_vert.h"
25-
#include "../../shaders/generated/tile_clip_combine_frag.h"
26-
#include "../../shaders/generated/tile_clip_combine_vert.h"
27-
#include "../../shaders/generated/tile_clip_copy_frag.h"
28-
#include "../../shaders/generated/tile_clip_copy_vert.h"
29-
#include "../../shaders/generated/tile_frag.h"
30-
#include "../../shaders/generated/tile_vert.h"
13+
#include "../../shaders/generated/fill_frag_shdbin.h"
14+
#include "../../shaders/generated/fill_vert_shdbin.h"
15+
#include "../../shaders/generated/tile_clip_combine_frag_shdbin.h"
16+
#include "../../shaders/generated/tile_clip_combine_vert_shdbin.h"
17+
#include "../../shaders/generated/tile_clip_copy_frag_shdbin.h"
18+
#include "../../shaders/generated/tile_clip_copy_vert_shdbin.h"
19+
#include "../../shaders/generated/tile_frag_shdbin.h"
20+
#include "../../shaders/generated/tile_vert_shdbin.h"
3121
/* clang-format on */
3222

3323
#include <array>
@@ -111,16 +101,6 @@ void RendererD3D9::update_tile_batch_storage(uint32_t new_tile_batch_count) {
111101
void RendererD3D9::set_up_pipelines() {
112102
// Fill pipeline.
113103
{
114-
std::vector<char> fill_vert_source, fill_frag_source;
115-
116-
if (device->get_backend_type() == BackendType::Vulkan) {
117-
fill_vert_source = std::vector<char>(std::begin(fill_vert_spv), std::end(fill_vert_spv));
118-
fill_frag_source = std::vector<char>(std::begin(fill_frag_spv), std::end(fill_frag_spv));
119-
} else {
120-
fill_vert_source = std::vector<char>(std::begin(fill_vert), std::end(fill_vert));
121-
fill_frag_source = std::vector<char>(std::begin(fill_frag), std::end(fill_frag));
122-
}
123-
124104
// Set vertex attributes.
125105
std::vector<VertexInputAttributeDescription> attribute_descriptions;
126106
{
@@ -142,8 +122,8 @@ void RendererD3D9::set_up_pipelines() {
142122

143123
{
144124
std::vector<DescriptorLayout> layouts = {
145-
DescriptorLayout{0, ShaderStage::Vertex, DescriptorType::UniformBuffer, "bUniform"},
146-
DescriptorLayout{1, ShaderStage::Fragment, DescriptorType::Sampler, "uAreaLUT"},
125+
DescriptorLayout{0, ShaderStage::Vertex, DescriptorType::UniformBuffer},
126+
DescriptorLayout{1, ShaderStage::Fragment, DescriptorType::Sampler},
147127
};
148128

149129
fill_descriptor_set_layout_ = device->create_descriptor_set_layout(layouts);
@@ -155,11 +135,14 @@ void RendererD3D9::set_up_pipelines() {
155135
Descriptor::sampled(1, allocator->get_texture(area_lut_texture_id), get_default_sampler()),
156136
});
157137

158-
auto fill_vert_shader = device->create_shader_module(fill_vert_source, ShaderStage::Vertex, "fill vert");
159-
auto fill_frag_shader = device->create_shader_module(fill_frag_source, ShaderStage::Fragment, "fill frag");
138+
auto fill_vert_shader = Shader::create_from_shdbin(fill_vert_shdbin, sizeof(fill_vert_shdbin));
139+
auto fill_frag_shader = Shader::create_from_shdbin(fill_frag_shdbin, sizeof(fill_frag_shdbin));
160140

161-
fill_pipeline = device->create_render_pipeline(fill_vert_shader,
162-
fill_frag_shader,
141+
auto fill_vert_shader_module = device->create_shader_module(fill_vert_shader, "fill vert");
142+
auto fill_frag_shader_module = device->create_shader_module(fill_frag_shader, "fill frag");
143+
144+
fill_pipeline = device->create_render_pipeline(fill_vert_shader_module,
145+
fill_frag_shader_module,
163146
attribute_descriptions,
164147
BlendState::from_equal(),
165148
fill_descriptor_set_layout_,
@@ -169,21 +152,9 @@ void RendererD3D9::set_up_pipelines() {
169152

170153
// Tile pipeline.
171154
{
172-
std::vector<char> tile_vert_source, tile_frag_source;
173-
174-
if (device->get_backend_type() == BackendType::Vulkan) {
175-
tile_vert_source = std::vector<char>(std::begin(tile_vert_spv), std::end(tile_vert_spv));
176-
tile_frag_source = std::vector<char>(std::begin(tile_frag_spv), std::end(tile_frag_spv));
177-
} else {
178-
tile_vert_source = std::vector<char>(std::begin(tile_vert), std::end(tile_vert));
179-
tile_frag_source = std::vector<char>(std::begin(tile_frag), std::end(tile_frag));
180-
}
181-
182155
// Set vertex attributes.
183156
std::vector<VertexInputAttributeDescription> attribute_descriptions;
184157
{
185-
attribute_descriptions.reserve(6);
186-
187158
// Quad vertex.
188159
attribute_descriptions.push_back({0, 2, DataType::u16, 2 * sizeof(uint16_t), 0, VertexInputRate::Vertex});
189160

@@ -204,25 +175,28 @@ void RendererD3D9::set_up_pipelines() {
204175

205176
{
206177
std::vector<DescriptorLayout> layouts = {
207-
DescriptorLayout{0, ShaderStage::Vertex, DescriptorType::Sampler, "uTextureMetadata"},
208-
DescriptorLayout{1, ShaderStage::Vertex, DescriptorType::Sampler, "uZBuffer"},
209-
DescriptorLayout{2, ShaderStage::VertexAndFragment, DescriptorType::UniformBuffer, "bUniform"},
210-
DescriptorLayout{3, ShaderStage::Fragment, DescriptorType::Sampler, "uColorTexture0"},
211-
DescriptorLayout{4, ShaderStage::Fragment, DescriptorType::Sampler, "uMaskTexture0"},
212-
DescriptorLayout{5, ShaderStage::Fragment, DescriptorType::Sampler, "uDestTexture"},
213-
DescriptorLayout{6, ShaderStage::Fragment, DescriptorType::Sampler, "uGammaLUT"},
178+
DescriptorLayout{0, ShaderStage::Vertex, DescriptorType::Sampler},
179+
DescriptorLayout{1, ShaderStage::Vertex, DescriptorType::Sampler},
180+
DescriptorLayout{2, ShaderStage::VertexAndFragment, DescriptorType::UniformBuffer},
181+
DescriptorLayout{3, ShaderStage::Fragment, DescriptorType::Sampler},
182+
DescriptorLayout{4, ShaderStage::Fragment, DescriptorType::Sampler},
183+
DescriptorLayout{5, ShaderStage::Fragment, DescriptorType::Sampler},
184+
DescriptorLayout{6, ShaderStage::Fragment, DescriptorType::Sampler},
214185
};
215186

216187
tile_descriptor_set_layout_ = device->create_descriptor_set_layout(layouts);
217188
}
218189

219190
update_tile_batch_storage(DEFAULT_TILE_BATCH_COUNT);
220191

221-
auto tile_vert_shader = device->create_shader_module(tile_vert_source, ShaderStage::Vertex, "tile vert");
222-
auto tile_frag_shader = device->create_shader_module(tile_frag_source, ShaderStage::Fragment, "tile frag");
192+
auto tile_vert_shader = Shader::create_from_shdbin(tile_vert_shdbin, sizeof(tile_vert_shdbin));
193+
auto tile_frag_shader = Shader::create_from_shdbin(tile_frag_shdbin, sizeof(tile_frag_shdbin));
194+
195+
auto tile_vert_shader_module = device->create_shader_module(tile_vert_shader, "tile vert");
196+
auto tile_frag_shader_module = device->create_shader_module(tile_frag_shader, "tile frag");
223197

224-
tile_pipeline = device->create_render_pipeline(tile_vert_shader,
225-
tile_frag_shader,
198+
tile_pipeline = device->create_render_pipeline(tile_vert_shader_module,
199+
tile_frag_shader_module,
226200
attribute_descriptions,
227201
BlendState::from_over(),
228202
tile_descriptor_set_layout_,
@@ -265,18 +239,6 @@ void RendererD3D9::reallocate_alpha_tile_pages_if_necessary() {
265239
}
266240

267241
void RendererD3D9::create_tile_clip_copy_pipeline() {
268-
std::vector<char> tile_clip_copy_vert_source, tile_clip_copy_frag_source;
269-
270-
if (device->get_backend_type() == BackendType::Vulkan) {
271-
tile_clip_copy_vert_source =
272-
std::vector<char>(std::begin(tile_clip_copy_vert_spv), std::end(tile_clip_copy_vert_spv));
273-
tile_clip_copy_frag_source =
274-
std::vector<char>(std::begin(tile_clip_copy_frag_spv), std::end(tile_clip_copy_frag_spv));
275-
} else {
276-
tile_clip_copy_vert_source = std::vector<char>(std::begin(tile_clip_copy_vert), std::end(tile_clip_copy_vert));
277-
tile_clip_copy_frag_source = std::vector<char>(std::begin(tile_clip_copy_frag), std::end(tile_clip_copy_frag));
278-
}
279-
280242
// Set vertex attributes.
281243
std::vector<VertexInputAttributeDescription> attribute_descriptions;
282244
{
@@ -290,8 +252,8 @@ void RendererD3D9::create_tile_clip_copy_pipeline() {
290252

291253
{
292254
std::vector<DescriptorLayout> layouts = {
293-
DescriptorLayout{0, ShaderStage::Vertex, DescriptorType::UniformBuffer, "bUniform"},
294-
DescriptorLayout{1, ShaderStage::Fragment, DescriptorType::Sampler, "uSrc"},
255+
DescriptorLayout{0, ShaderStage::Vertex, DescriptorType::UniformBuffer},
256+
DescriptorLayout{1, ShaderStage::Fragment, DescriptorType::Sampler},
295257
};
296258

297259
tile_clip_copy_descriptor_set_layout_ = device->create_descriptor_set_layout(layouts);
@@ -303,14 +265,15 @@ void RendererD3D9::create_tile_clip_copy_pipeline() {
303265
Descriptor::uniform(0, allocator->get_buffer(fill_ub_id)),
304266
});
305267

306-
auto tile_clip_copy_vert_shader =
307-
device->create_shader_module(tile_clip_copy_vert_source, ShaderStage::Vertex, "tile clip copy vert");
308-
auto tile_clip_copy_frag_shader =
309-
device->create_shader_module(tile_clip_copy_frag_source, ShaderStage::Fragment, "tile clip copy frag");
268+
auto vert_shader = Shader::create_from_shdbin(tile_clip_copy_vert_shdbin, sizeof(tile_clip_copy_vert_shdbin));
269+
auto frag_shader = Shader::create_from_shdbin(tile_clip_copy_frag_shdbin, sizeof(tile_clip_copy_frag_shdbin));
270+
271+
auto vert_shader_module = device->create_shader_module(vert_shader, "tile clip copy vert");
272+
auto frag_shader_module = device->create_shader_module(frag_shader, "tile clip copy frag");
310273

311274
// We have to disable blend for tile clip copy.
312-
tile_clip_copy_pipeline = device->create_render_pipeline(tile_clip_copy_vert_shader,
313-
tile_clip_copy_frag_shader,
275+
tile_clip_copy_pipeline = device->create_render_pipeline(vert_shader_module,
276+
frag_shader_module,
314277
attribute_descriptions,
315278
{false},
316279
tile_clip_copy_descriptor_set_layout_,
@@ -319,15 +282,6 @@ void RendererD3D9::create_tile_clip_copy_pipeline() {
319282
}
320283

321284
void RendererD3D9::create_tile_clip_combine_pipeline() {
322-
std::vector<char> vert_source, frag_source;
323-
if (device->get_backend_type() == BackendType::Vulkan) {
324-
vert_source = std::vector<char>(std::begin(tile_clip_combine_vert_spv), std::end(tile_clip_combine_vert_spv));
325-
frag_source = std::vector<char>(std::begin(tile_clip_combine_frag_spv), std::end(tile_clip_combine_frag_spv));
326-
} else {
327-
vert_source = std::vector<char>(std::begin(tile_clip_combine_vert), std::end(tile_clip_combine_vert));
328-
frag_source = std::vector<char>(std::begin(tile_clip_combine_frag), std::end(tile_clip_combine_frag));
329-
}
330-
331285
// Set vertex attributes.
332286
std::vector<VertexInputAttributeDescription> attribute_descriptions;
333287
{
@@ -347,8 +301,8 @@ void RendererD3D9::create_tile_clip_combine_pipeline() {
347301

348302
{
349303
std::vector<DescriptorLayout> layouts = {
350-
DescriptorLayout{0, ShaderStage::Vertex, DescriptorType::UniformBuffer, "bUniform"},
351-
DescriptorLayout{1, ShaderStage::Fragment, DescriptorType::Sampler, "uSrc"},
304+
DescriptorLayout{0, ShaderStage::Vertex, DescriptorType::UniformBuffer},
305+
DescriptorLayout{1, ShaderStage::Fragment, DescriptorType::Sampler},
352306
};
353307

354308
tile_clip_combine_descriptor_set_layout_ = device->create_descriptor_set_layout(layouts);
@@ -360,14 +314,15 @@ void RendererD3D9::create_tile_clip_combine_pipeline() {
360314
Descriptor::uniform(0, allocator->get_buffer(fill_ub_id)),
361315
});
362316

363-
auto tile_clip_combine_vert_shader =
364-
device->create_shader_module(vert_source, ShaderStage::Vertex, "tile clip combine vert");
365-
auto tile_clip_combine_frag_shader =
366-
device->create_shader_module(frag_source, ShaderStage::Fragment, "tile clip combine frag");
317+
auto vert_shader = Shader::create_from_shdbin(tile_clip_combine_vert_shdbin, sizeof(tile_clip_combine_vert_shdbin));
318+
auto frag_shader = Shader::create_from_shdbin(tile_clip_combine_frag_shdbin, sizeof(tile_clip_combine_frag_shdbin));
319+
320+
auto vert_shader_module = device->create_shader_module(vert_shader, "tile clip combine vert");
321+
auto frag_shader_module = device->create_shader_module(frag_shader, "tile clip combine frag");
367322

368323
// We have to disable blend for tile clip combine.
369-
tile_clip_combine_pipeline = device->create_render_pipeline(tile_clip_combine_vert_shader,
370-
tile_clip_combine_frag_shader,
324+
tile_clip_combine_pipeline = device->create_render_pipeline(vert_shader_module,
325+
frag_shader_module,
371326
attribute_descriptions,
372327
{false},
373328
tile_clip_combine_descriptor_set_layout_,

pathfinder/gpu/base.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ enum class ShaderStage {
4747
Vertex,
4848
Fragment,
4949
Compute,
50+
Geometry,
5051
VertexAndFragment,
5152
};
5253

pathfinder/gpu/descriptor_set.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ struct DescriptorLayout {
1717
uint32_t binding{};
1818
ShaderStage stage{};
1919
DescriptorType type{};
20-
/// For compatibility with lower versions of OpenGL.
21-
std::string binding_name;
20+
/// For compatibility with lower versions of OpenGL. Deprecated, this has become automatic.
21+
// std::string binding_name;
2222
};
2323

2424
class DescriptorSetLayout {
@@ -114,8 +114,7 @@ struct Descriptor {
114114
return desc;
115115
}
116116

117-
static Descriptor image(uint32_t binding,
118-
const std::shared_ptr<Texture>& texture = nullptr) {
117+
static Descriptor image(uint32_t binding, const std::shared_ptr<Texture>& texture = nullptr) {
119118
Descriptor desc{};
120119
desc.type = DescriptorType::Image;
121120
desc.binding = binding;

pathfinder/gpu/device.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "framebuffer.h"
1010
#include "render_pass.h"
1111
#include "render_pipeline.h"
12+
#include "shader.h"
1213
#include "shader_module.h"
1314

1415
namespace Pathfinder {
@@ -48,6 +49,9 @@ class Device : public std::enable_shared_from_this<Device> {
4849
virtual std::shared_ptr<RenderPass> create_swap_chain_render_pass(TextureFormat format,
4950
AttachmentLoadOp load_op) = 0;
5051

52+
virtual std::shared_ptr<ShaderModule> create_shader_module(const std::shared_ptr<Shader> &shader,
53+
const std::string &label) = 0;
54+
5155
virtual std::shared_ptr<ShaderModule> create_shader_module(const std::vector<char> &source_code,
5256
ShaderStage shader_stage,
5357
const std::string &label) = 0;

0 commit comments

Comments
 (0)