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
23namespace taichi {
24namespace ui {
25namespace vulkan {
26
27using taichi::lang::DeviceAllocation;
28using taichi::lang::DeviceAllocationUnique;
29using taichi::lang::DevicePtr;
30using taichi::lang::Pipeline;
31using taichi::lang::RasterResources;
32using taichi::lang::ShaderResourceSet;
33
34struct 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
54class 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