1 | #pragma once |
2 | |
3 | #include <algorithm> |
4 | #include <array> |
5 | #include <chrono> |
6 | #include <cstdint> |
7 | #include <cstdlib> |
8 | #include <cstring> |
9 | #include <fstream> |
10 | #include <iostream> |
11 | #include <optional> |
12 | #include <set> |
13 | #include <stdexcept> |
14 | #include <vector> |
15 | |
16 | #include "taichi/rhi/vulkan/vulkan_device.h" |
17 | #include "taichi/ui/backends/vulkan/app_context.h" |
18 | #include "taichi/ui/backends/vulkan/swap_chain.h" |
19 | #include "taichi/ui/backends/vulkan/vertex.h" |
20 | #include "taichi/ui/common/renderable_info.h" |
21 | #include "taichi/ui/utils/utils.h" |
22 | |
23 | namespace taichi { |
24 | namespace ui { |
25 | namespace vulkan { |
26 | |
27 | using taichi::lang::DeviceAllocation; |
28 | using taichi::lang::DeviceAllocationUnique; |
29 | using taichi::lang::DevicePtr; |
30 | using taichi::lang::Pipeline; |
31 | using taichi::lang::RasterResources; |
32 | using taichi::lang::ShaderResourceSet; |
33 | |
34 | struct RenderableConfig { |
35 | int vertices_count{0}; |
36 | int indices_count{0}; |
37 | int draw_vertex_count{0}; |
38 | int draw_first_vertex{0}; |
39 | int draw_index_count{0}; |
40 | int draw_first_index{0}; |
41 | size_t ubo_size{0}; |
42 | size_t ssbo_size{0}; |
43 | bool blending{false}; |
44 | |
45 | std::string vertex_shader_path; |
46 | std::string fragment_shader_path; |
47 | taichi::lang::TopologyType topology_type{ |
48 | taichi::lang::TopologyType::Triangles}; |
49 | taichi::lang::PolygonMode polygon_mode{taichi::lang::PolygonMode::Fill}; |
50 | bool depth{false}; |
51 | bool vertex_input_rate_instance{false}; |
52 | }; |
53 | |
54 | class Renderable { |
55 | public: |
56 | void update_data(const RenderableInfo &info); |
57 | |
58 | virtual void record_this_frame_commands( |
59 | taichi::lang::CommandList *command_list); |
60 | |
61 | virtual void record_prepass_this_frame_commands( |
62 | taichi::lang::CommandList *command_list) { |
63 | } |
64 | |
65 | virtual ~Renderable() = default; |
66 | |
67 | taichi::lang::Pipeline &pipeline(); |
68 | const taichi::lang::Pipeline &pipeline() const; |
69 | |
70 | static void create_buffer_with_staging(taichi::lang::Device &device, |
71 | size_t size, |
72 | taichi::lang::AllocUsage usage, |
73 | DeviceAllocationUnique &buffer, |
74 | DeviceAllocationUnique &staging); |
75 | |
76 | static void copy_helper(taichi::lang::Program *prog, |
77 | DevicePtr dst, |
78 | DevicePtr src, |
79 | DevicePtr staging, |
80 | size_t size); |
81 | |
82 | protected: |
83 | RenderableConfig config_; |
84 | AppContext *app_context_; |
85 | |
86 | int max_vertices_count{0}; |
87 | int max_indices_count{0}; |
88 | |
89 | Pipeline *pipeline_{nullptr}; // Factory owns pipelines |
90 | std::unique_ptr<ShaderResourceSet> resource_set_{nullptr}; |
91 | |
92 | DeviceAllocationUnique vertex_buffer_{nullptr}; |
93 | DeviceAllocationUnique index_buffer_{nullptr}; |
94 | |
95 | // these staging buffers are used to copy data into the actual buffers |
96 | DeviceAllocationUnique staging_vertex_buffer_{nullptr}; |
97 | DeviceAllocationUnique staging_index_buffer_{nullptr}; |
98 | |
99 | DeviceAllocationUnique uniform_buffer_{nullptr}; |
100 | DeviceAllocationUnique storage_buffer_{nullptr}; |
101 | |
102 | bool indexed_{false}; |
103 | |
104 | protected: |
105 | void init(const RenderableConfig &config_, AppContext *app_context); |
106 | void init_buffers(); |
107 | |
108 | virtual void create_graphics_pipeline(); |
109 | |
110 | void resize_storage_buffers(int new_ssbo_size); |
111 | }; |
112 | |
113 | } // namespace vulkan |
114 | } // namespace ui |
115 | } // namespace taichi |
116 | |