Skip to content
This repository was archived by the owner on Aug 11, 2021. It is now read-only.

Commit ad2fd87

Browse files
committed
Bind a shader resource without the pipeline stage
1 parent 6848872 commit ad2fd87

14 files changed

+388
-314
lines changed

CMakeLists.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ add_library(gfx
1717
include/gfx/Fence.h
1818
src/std_lib.h
1919
src/Lru_cache.h
20-
src/Device.cpp)
20+
src/Device.cpp
21+
src/Pipeline.cpp)
2122

2223
target_include_directories(gfx
2324
PUBLIC

demo/Gfx_demo.cpp

+19-36
Original file line numberDiff line numberDiff line change
@@ -681,59 +681,44 @@ void Gfx_demo::record_light_render_pass_()
681681

682682
render_encoder->vertex_buffer(buffers_["cube_vertex"].get(), 0, 0);
683683
render_encoder->index_buffer(buffers_["cube_index"].get(), 0, Index_type::uint16);
684-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["matrix_info"].get(), 0, 0);
684+
render_encoder->shader_buffer(buffers_["matrix_info"].get(), 0, 0);
685685
render_encoder->pipeline(pipelines_["lamp"].get());
686686
render_encoder->draw_indexed(draw_counts_["cube"]);
687687

688688
render_encoder->vertex_buffer(buffers_["plane_vertex"].get(), 0, 0);
689689
render_encoder->index_buffer(buffers_["plane_index"].get(), 0, Index_type::uint16);
690-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["matrix_info"].get(), 512 * 2, 0);
691-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["light_info"].get(), 0, 1);
692-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["material_info"].get(), 256 * 2, 2);
693-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["matrix_info"].get(), 512 * 2, 0);
694-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["light_info"].get(), 0, 1);
695-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["material_info"].get(), 256 * 2, 2);
690+
render_encoder->shader_buffer(buffers_["matrix_info"].get(), 512 * 2, 0);
691+
render_encoder->shader_buffer(buffers_["light_info"].get(), 0, 1);
692+
render_encoder->shader_buffer(buffers_["material_info"].get(), 256 * 2, 2);
696693
render_encoder->pipeline(pipelines_["phong"].get());
697694
render_encoder->draw_indexed(draw_counts_["plane"]);
698695

699-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["matrix_info"].get(), 512 * 3, 0);
700-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["light_info"].get(), 0, 1);
701-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["material_info"].get(), 256 * 3, 2);
702-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["matrix_info"].get(), 512 * 3, 0);
703-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["light_info"].get(), 0, 1);
704-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["material_info"].get(), 256 * 3, 2);
696+
render_encoder->shader_buffer(buffers_["matrix_info"].get(), 512 * 3, 0);
697+
render_encoder->shader_buffer(buffers_["light_info"].get(), 0, 1);
698+
render_encoder->shader_buffer(buffers_["material_info"].get(), 256 * 3, 2);
705699
render_encoder->draw_indexed(draw_counts_["plane"]);
706700

707701
render_encoder->vertex_buffer(buffers_["cube_vertex"].get(), 0, 0);
708702
render_encoder->index_buffer(buffers_["cube_index"].get(), 0, Index_type::uint16);
709-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["matrix_info"].get(), 512 * 4, 0);
710-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["light_info"].get(), 0, 1);
711-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["material_info"].get(), 256 * 4, 2);
712-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["matrix_info"].get(), 512 * 4, 0);
713-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["light_info"].get(), 0, 1);
714-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["material_info"].get(), 256 * 4, 2);
703+
render_encoder->shader_buffer(buffers_["matrix_info"].get(), 512 * 4, 0);
704+
render_encoder->shader_buffer(buffers_["light_info"].get(), 0, 1);
705+
render_encoder->shader_buffer(buffers_["material_info"].get(), 256 * 4, 2);
715706
render_encoder->pipeline(pipeline(cfgs_.cube.style));
716707
render_encoder->draw_indexed(draw_counts_["cube"]);
717708

718709
render_encoder->vertex_buffer(buffers_["torus_vertex"].get(), 0, 0);
719710
render_encoder->index_buffer(buffers_["torus_index"].get(), 0, Index_type::uint16);
720-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["matrix_info"].get(), 512 * 5, 0);
721-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["light_info"].get(), 0, 1);
722-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["material_info"].get(), 256 * 5, 2);
723-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["matrix_info"].get(), 512 * 5, 0);
724-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["light_info"].get(), 0, 1);
725-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["material_info"].get(), 256 * 5, 2);
711+
render_encoder->shader_buffer(buffers_["matrix_info"].get(), 512 * 5, 0);
712+
render_encoder->shader_buffer(buffers_["light_info"].get(), 0, 1);
713+
render_encoder->shader_buffer(buffers_["material_info"].get(), 256 * 5, 2);
726714
render_encoder->pipeline(pipeline(cfgs_.torus.style));
727715
render_encoder->draw_indexed(draw_counts_["torus"]);
728716

729717
render_encoder->vertex_buffer(buffers_["sphere_vertex"].get(), 0, 0);
730718
render_encoder->index_buffer(buffers_["sphere_index"].get(), 0, Index_type::uint16);
731-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["matrix_info"].get(), 512 * 6, 0);
732-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["light_info"].get(), 0, 1);
733-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["material_info"].get(), 256 * 6, 2);
734-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["matrix_info"].get(), 512 * 6, 0);
735-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["light_info"].get(), 0, 1);
736-
render_encoder->shader_buffer(Pipeline_stage::fragment_shader, buffers_["material_info"].get(), 256 * 6, 2);
719+
render_encoder->shader_buffer(buffers_["matrix_info"].get(), 512 * 6, 0);
720+
render_encoder->shader_buffer(buffers_["light_info"].get(), 0, 1);
721+
render_encoder->shader_buffer(buffers_["material_info"].get(), 256 * 6, 2);
737722
render_encoder->pipeline(pipeline(cfgs_.sphere.style));
738723
render_encoder->draw_indexed(draw_counts_["sphere"]);
739724

@@ -838,15 +823,13 @@ void Gfx_demo::record_present_render_pass_()
838823

839824
auto render_encoder = cmd_buffer_->create(desc);
840825

841-
render_encoder->shader_texture(Pipeline_stage::fragment_shader,
842-
images_["light_color"].get(), samplers_["light_linear"].get(), 0);
826+
render_encoder->shader_texture(images_["light_color"].get(), samplers_["light_linear"].get(), 0);
843827
render_encoder->pipeline(pipelines_["composite"].get());
844828
render_encoder->draw(3, 0);
845829

846830
if (draw_data->CmdListsCount) {
847-
render_encoder->shader_buffer(Pipeline_stage::vertex_shader, buffers_["imgui_shader_Imgui_info"].get(), 0, 0);
848-
render_encoder->shader_texture(Pipeline_stage::fragment_shader,
849-
images_["imgui_font"].get(), samplers_["light_linear"].get(), 0);
831+
render_encoder->shader_buffer(buffers_["imgui_shader_Imgui_info"].get(), 0, 0);
832+
render_encoder->shader_texture(images_["imgui_font"].get(), samplers_["light_linear"].get(), 0);
850833
render_encoder->pipeline(pipelines_["imgui"].get());
851834

852835
auto vertex_buffer_offset {0};

include/gfx/Cmd_buffer.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ class Render_encoder {
5656

5757
virtual void index_buffer(Buffer* buffer, uint64_t offset, Index_type index_type) = 0;
5858

59-
virtual void shader_buffer(Pipeline_stage stage, Buffer* buffer, uint32_t offset, uint32_t index) = 0;
59+
virtual void shader_buffer(Buffer* buffer, uint32_t offset, uint32_t index) = 0;
6060

61-
virtual void shader_texture(Pipeline_stage stage, Image* image, Sampler* sampler, uint32_t index) = 0;
61+
virtual void shader_texture(Image* image, Sampler* sampler, uint32_t index) = 0;
6262

6363
virtual void pipeline(Pipeline* pipeline) = 0;
6464

include/gfx/Pipeline.h

+16-9
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define GFX_PIPELINE_GUARD
88

99
#include <array>
10+
#include <unordered_map>
1011
#include "enums.h"
1112

1213
namespace Gfx_lib {
@@ -115,6 +116,13 @@ struct Output_merger final {
115116

116117
//----------------------------------------------------------------------------------------------------------------------
117118

119+
struct Reflection {
120+
std::unordered_map<uint32_t, uint32_t> buffers;
121+
std::unordered_map<uint32_t, uint32_t> textures;
122+
};
123+
124+
//----------------------------------------------------------------------------------------------------------------------
125+
118126
struct Pipeline_desc final {
119127
Vertex_input vertex_input;
120128
Input_assembly input_assembly;
@@ -131,15 +139,7 @@ struct Pipeline_desc final {
131139

132140
class Pipeline {
133141
public:
134-
explicit Pipeline(const Pipeline_desc& desc) :
135-
vertex_input_ {desc.vertex_input},
136-
input_assembly_ {desc.input_assembly},
137-
rasterization_ {desc.rasterization},
138-
multisample_ {desc.multisample},
139-
depth_stencil_ {desc.depth_stencil},
140-
color_blend_ {desc.color_blend},
141-
output_merger_ {desc.output_merger}
142-
{}
142+
explicit Pipeline(const Pipeline_desc& desc);
143143

144144
virtual ~Pipeline() = default;
145145

@@ -166,6 +166,12 @@ class Pipeline {
166166
inline auto output_merger() const noexcept
167167
{ return output_merger_; }
168168

169+
inline auto reflection() const noexcept
170+
{ return reflection_; }
171+
172+
private:
173+
void init_reflection_(const std::vector<Shader*> shaders);
174+
169175
protected:
170176
Vertex_input vertex_input_;
171177
Input_assembly input_assembly_;
@@ -174,6 +180,7 @@ class Pipeline {
174180
Depth_stencil depth_stencil_;
175181
Color_blend color_blend_;
176182
Output_merger output_merger_;
183+
Reflection reflection_;
177184
};
178185

179186
//----------------------------------------------------------------------------------------------------------------------

include/gfx/enums.h

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ enum class Address_mode : uint8_t {
6969
//----------------------------------------------------------------------------------------------------------------------
7070

7171
enum class Pipeline_stage : uint8_t {
72+
invalid = 0,
7273
vertex_shader = 0x01, fragment_shader = 0x02, output_merger = 0x04, transfer = 0x08
7374
};
7475

src/Pipeline.cpp

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//
2+
// This file is part of the "gfx" project
3+
// See "LICENSE" for license information.
4+
//
5+
6+
#include "std_lib.h"
7+
#include "Pipeline.h"
8+
#include "Shader.h"
9+
10+
using namespace std;
11+
using namespace Sc_lib;
12+
using namespace Gfx_lib;
13+
14+
namespace Gfx_lib {
15+
16+
//----------------------------------------------------------------------------------------------------------------------
17+
18+
Pipeline::Pipeline(const Pipeline_desc& desc) :
19+
vertex_input_ {desc.vertex_input},
20+
input_assembly_ {desc.input_assembly},
21+
rasterization_ {desc.rasterization},
22+
multisample_ {desc.multisample},
23+
depth_stencil_ {desc.depth_stencil},
24+
color_blend_ {desc.color_blend},
25+
output_merger_ {desc.output_merger},
26+
reflection_ {}
27+
{
28+
init_reflection_({desc.vertex_shader, desc.fragment_shader});
29+
}
30+
31+
//----------------------------------------------------------------------------------------------------------------------
32+
33+
void Pipeline::init_reflection_(const std::vector<Shader*> shaders)
34+
{
35+
unordered_map<Shader_type, Signature> signatures;
36+
37+
for (auto shader : shaders)
38+
signatures.emplace(shader->type(), shader->reflect());
39+
40+
for (auto& [shader_type, signature] : signatures) {
41+
for (auto& [binding, buffer] : signature.buffers) {
42+
switch (shader_type) {
43+
case Shader_type::vertex:
44+
reflection_.buffers[binding] |= static_cast<uint8_t>(Pipeline_stage::vertex_shader);
45+
break;
46+
case Shader_type::fragment:
47+
reflection_.buffers[binding] |= static_cast<uint8_t>(Pipeline_stage::fragment_shader);
48+
break;
49+
default:
50+
throw runtime_error("fail to create a pipeline");
51+
}
52+
}
53+
54+
for (auto& [binding, texture] : signature.textures) {
55+
switch (shader_type) {
56+
case Shader_type::vertex:
57+
reflection_.textures[binding] |= static_cast<uint8_t>(Pipeline_stage::vertex_shader);
58+
break;
59+
case Shader_type::fragment:
60+
reflection_.textures[binding] |= static_cast<uint8_t>(Pipeline_stage::fragment_shader);
61+
break;
62+
default:
63+
throw runtime_error("fail to create a pipeline");
64+
}
65+
}
66+
}
67+
}
68+
69+
//----------------------------------------------------------------------------------------------------------------------
70+
71+
} // of namespace Gfx_lib

src/mtl/Mtl_cmd_buffer.h

+21-27
Original file line numberDiff line numberDiff line change
@@ -53,44 +53,32 @@ inline auto operator==(const Mtl_index_stream& lhs, const Mtl_index_stream& rhs)
5353

5454
//----------------------------------------------------------------------------------------------------------------------
5555

56-
template<typename T>
57-
using Mtl_arg_array = std::array<T, 16>;
58-
59-
//----------------------------------------------------------------------------------------------------------------------
60-
61-
struct Mtl_arg_buffer {
56+
struct Mtl_arg_buffer final {
6257
Mtl_buffer* buffer {nullptr};
58+
uint32_t buffer_stages {0};
6359
uint32_t offset {0};
60+
uint32_t offset_stages {0};
6461
};
6562

6663
//----------------------------------------------------------------------------------------------------------------------
6764

68-
struct Mtl_arg_texture {
65+
struct Mtl_arg_texture final {
6966
Mtl_image* image {nullptr};
67+
uint32_t image_stages {0};
7068
Mtl_sampler* sampler {nullptr};
69+
uint32_t sampler_stages {0};
7170
};
7271

7372
//----------------------------------------------------------------------------------------------------------------------
7473

75-
class Mtl_arg_table final {
76-
public:
77-
Mtl_arg_table();
78-
79-
void clear();
80-
81-
void arg_buffer(const Mtl_arg_buffer& arg_buffer, uint32_t index);
82-
83-
void arg_texture(const Mtl_arg_texture& arg_texture, uint32_t index);
84-
85-
inline auto arg_buffer(uint32_t index) const noexcept
86-
{ return arg_buffers_[index]; }
74+
template<typename T>
75+
using Mtl_arg_array = std::array<T, 16>;
8776

88-
inline auto arg_texture(uint32_t index) const noexcept
89-
{ return arg_textures_[index]; }
77+
//----------------------------------------------------------------------------------------------------------------------
9078

91-
private:
92-
Mtl_arg_array<Mtl_arg_buffer> arg_buffers_;
93-
Mtl_arg_array<Mtl_arg_texture> arg_textures_;
79+
struct Mtl_arg_table final {
80+
Mtl_arg_array<Mtl_arg_buffer> buffers;
81+
Mtl_arg_array<Mtl_arg_texture> textures;
9482
};
9583

9684
//----------------------------------------------------------------------------------------------------------------------
@@ -109,9 +97,9 @@ class Mtl_render_encoder final : public Render_encoder {
10997

11098
void index_buffer(Buffer* buffer, uint64_t offset, Index_type index_type) override;
11199

112-
void shader_buffer(Pipeline_stage stage, Buffer* buffer, uint32_t offset, uint32_t index) override;
100+
void shader_buffer(Buffer* buffer, uint32_t offset, uint32_t index) override;
113101

114-
void shader_texture(Pipeline_stage stage, Image* image, Sampler* sampler, uint32_t index) override;
102+
void shader_texture(Image* image, Sampler* sampler, uint32_t index) override;
115103

116104
void pipeline(Pipeline* pipeline) override;
117105

@@ -127,12 +115,18 @@ class Mtl_render_encoder final : public Render_encoder {
127115
private:
128116
void init_render_command_encoder_(const Render_encoder_desc& desc);
129117

118+
void bind_arg_table_();
119+
120+
void bind_arg_buffer_(uint64_t index, uint32_t stages);
121+
122+
void bind_arg_texture_(uint64_t index, uint32_t stages);
123+
130124
private:
131125
Mtl_cmd_buffer* cmd_buffer_;
132126
id<MTLRenderCommandEncoder> render_command_encoder_;
133127
std::array<Mtl_vertex_stream, 2> vertex_streams_;
134128
Mtl_index_stream index_stream_;
135-
std::unordered_map<Pipeline_stage, Mtl_arg_table> arg_tables_;
129+
Mtl_arg_table arg_table_;
136130
Mtl_pipeline* pipeline_;
137131
};
138132

0 commit comments

Comments
 (0)