mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-11 16:57:12 +01:00
Vulkan: parity with GL (P1–P7), shared GPU culling records (N6c), threaded command recording and render thread (M1, M4)
This commit is contained in:
@@ -24,17 +24,27 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "rendering/lightarray.h"
|
||||
#include "rendering/common/scenewalk.h"
|
||||
#include "rendering/common/locallights.h"
|
||||
#include "rendering/common/skylight.h"
|
||||
#include "rendering/common/weatherstate.h"
|
||||
#include "rendering/common/shadowfit.h"
|
||||
#include "rendering/common/gpuparticles.h"
|
||||
#include "rendering/particles.h"
|
||||
#include "model/material.h"
|
||||
#include "vehicle/Camera.h"
|
||||
#include "gl/ubo.h"
|
||||
|
||||
class world_environment;
|
||||
struct VkRenderingInfo;
|
||||
namespace vk14
|
||||
{
|
||||
struct scene_program;
|
||||
struct target_formats;
|
||||
class image;
|
||||
class compute_kernel;
|
||||
struct draw_constants;
|
||||
enum class blend_mode;
|
||||
class instance_cull;
|
||||
struct image_use;
|
||||
} // namespace vk14
|
||||
|
||||
class vulkan14_renderer : public gfx_renderer, public gfx::scene_walk
|
||||
@@ -69,6 +79,10 @@ class vulkan14_renderer : public gfx_renderer, public gfx::scene_walk
|
||||
bool Blendable_Material(material_handle const Material) override;
|
||||
void Bind_Material(material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr) override;
|
||||
IMaterial const *Material(material_handle const Material) const override;
|
||||
material_handle Terrain_Material(material_handle const Reuse, std::vector<gfx::terrain_layer> const &Layers, int const Samples, std::uint8_t const *Weights, glm::vec3 const &Placement,
|
||||
int const HoleSamples = 0, std::uint8_t const *Holes = nullptr) override;
|
||||
void Terrain_Release(material_handle const Material) override;
|
||||
void Terrain_Grass(std::vector<gfx::grass_kind> const &Kinds, std::vector<gfx::grass_chunk> const &Chunks) override;
|
||||
// shaders
|
||||
std::shared_ptr<gfx::shader_program> Fetch_Shader(std::string const &name) override;
|
||||
std::string Shader_Name(std::shared_ptr<gfx::shader_program> const &Program) const override;
|
||||
@@ -158,6 +172,89 @@ class vulkan14_renderer : public gfx_renderer, public gfx::scene_walk
|
||||
void walk_glare_draw(TSubModel *Submodel, gfx::geometry_handle const &Geometry) override;
|
||||
void walk_light_query(TSubModel *Submodel, bool const Begin) override;
|
||||
void walk_editor_cursor() override;
|
||||
gfx::geometrybank_manager &walk_geometry() override;
|
||||
bool walk_blending_enabled() const override;
|
||||
void walk_region_begin() override;
|
||||
bool walk_instances_begin() override;
|
||||
void walk_instances_end() override;
|
||||
|
||||
// the gpu culling of the instances (vulkan14indirect.cpp, the stage P5; opengl46_renderer::Render_Instances_Indirect() and the
|
||||
// rest): the cullings of the passes and the depth pyramid, made when the renderer starts
|
||||
bool init_cull();
|
||||
void destroy_cull();
|
||||
// the rendering of the pass under way, kept to be begun again where it was: it's ended for the compute passes of the culling
|
||||
// in the middle of the walk, and begun again with what it drew loaded, with the state of the draws as it was
|
||||
void remember_rendering(VkRenderingInfo const &Info, std::vector<vk14::image_use> const &Uses);
|
||||
void suspend_rendering();
|
||||
void resume_rendering();
|
||||
// the pass sets with the output of the culling as the instance buffer, made when the pass sets or the output changed; bound by
|
||||
// the draws until they're dropped (nullptr)
|
||||
void use_cull_pass_sets(vk14::instance_cull *Cull);
|
||||
// writes the pass sets (Cull null) or those of the culling
|
||||
void write_pass_sets(vk14::instance_cull *Cull);
|
||||
// draws of the instances made, and the calls which made them
|
||||
struct indirect_counts
|
||||
{
|
||||
std::uint32_t draws{0};
|
||||
std::uint32_t calls{0};
|
||||
indirect_counts &operator+=(indirect_counts const &Other)
|
||||
{
|
||||
draws += Other.draws;
|
||||
calls += Other.calls;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
using command_set = gfx::instance_cull::command_set;
|
||||
// the instances of the main view drawn from its culling: the depth pyramid, the culling, the walks, the depth and the colour,
|
||||
// in two phases with the occlusion test of the instances drawn first; inside the depth pass of the scene the depth alone,
|
||||
// the colour waits for the colour pass (render_instances_indirect_pending())
|
||||
void render_instances_indirect();
|
||||
// the same for the passes other than the main view: no occlusion test, no depth prepass, one phase
|
||||
void render_instances_indirect_pass();
|
||||
void render_instances_indirect_pending();
|
||||
// the walks of the culled groups (gfx::scene_walk::Walk_Indirect_Draws()), the draws put in order for the multi draws, and the
|
||||
// commands filled in by the culling
|
||||
void record_indirect_draws(vk14::instance_cull &Cull, bool const Cascade);
|
||||
// the recorded draws with the commands of the set: their colour with the programs of their materials, their depth with the
|
||||
// programs of the depth prepass, the shadows with the programs of the shadows
|
||||
indirect_counts draw_indirect_colour(vk14::instance_cull &Cull, command_set const Set);
|
||||
indirect_counts draw_indirect_depth(vk14::instance_cull &Cull, command_set const Set);
|
||||
indirect_counts draw_indirect_shadow(vk14::instance_cull &Cull, command_set const Set);
|
||||
// Count recorded draws from First with the program (a multi draw with more than one) and the state of the draws
|
||||
bool draw_indirect(vk14::instance_cull &Cull, command_set const Set, std::size_t const First, std::uint32_t const Count, vk14::scene_program &Program, vk14::blend_mode const Blend);
|
||||
// the variant of a program for the multi draws, nullptr when there's none
|
||||
vk14::scene_program *multidraw_program(vk14::scene_program &Program);
|
||||
vk14::instance_cull &pass_cull();
|
||||
// the shadow maps of the lamps (vulkan14lamps.cpp, the stage P4; opengl46_renderer::Render_local_shadows() and the rest): the cab
|
||||
// lamp, the scenery lamps, one of them, the headlights, one set of them; the culling of a map (nullptr when its instances go
|
||||
// through the cpu); the rendering of the map set up by the maps; the maps put in the layout the shading reads them in
|
||||
void render_local_shadows();
|
||||
void render_lamp_shadows();
|
||||
void render_lamp_shadow(std::size_t const Slot, bool const Vehicles, TDynamicObject *Cab);
|
||||
void render_headlight_shadows();
|
||||
void render_headlight_shadow(std::size_t const Slot, light_array::light_record const &Light, TDynamicObject *Cab);
|
||||
vk14::instance_cull *light_shadow_cull(std::vector<std::unique_ptr<vk14::instance_cull>> &Culls, std::size_t const Index, bool const Enabled);
|
||||
void begin_local_shadow_rendering();
|
||||
void end_local_shadow_rendering();
|
||||
void ready_lamp_maps();
|
||||
bool m_cubeshadows{false}; // the shadow pass draws to a cube map, with the programs of the cube maps
|
||||
vk14::instance_cull *m_lightshadowcull{nullptr}; // the culling of the map of headlights or of a lamp being drawn
|
||||
std::size_t m_lampscenerydrawn{0}; // scenery parts of the maps of lamps drawn in this frame so far
|
||||
unsigned int m_instancecullframe{~0u}; // the frame the culling of the main view ran in last
|
||||
int m_shadowcascade{-1}; // the cascade of the sun shadows being drawn
|
||||
bool m_indirectmultidraw{false}; // the recorded draws are in order for the multi draws
|
||||
vk14::instance_cull *m_indirectcull{nullptr}; // the culling the recorded draws were made for
|
||||
command_set m_indirectcolourset{command_set::first}; // the commands the colour pass draws the pending instances with
|
||||
// the cascades of the sun shadows fitted to the depth of the main view (gfx.shadow.sdsm): the cascades of the frame fitted to the
|
||||
// latest measurement (opengl46_renderer::Shadow_Fit()), the measurement of the depth of the finished view, the state for the panel,
|
||||
// the area of the cascade being set up and the sizes setup_pass() found for it
|
||||
bool shadow_fit(viewport_config const &Viewport, std::array<float, gl::MAX_CASCADES + 1> &Splits, gfx::shadow_fit::areas &Areas);
|
||||
char const *shadow_fit_unavailable(viewport_config const &Viewport) const;
|
||||
void measure_shadow_fit(std::size_t const Viewport);
|
||||
gfx::shadow_fit::fit_state m_shadowfitstate;
|
||||
std::array<glm::vec3, 8> const *m_shadowfitarea{nullptr};
|
||||
float m_shadowslicesize{0.f};
|
||||
float m_shadowdrawnsize{0.f};
|
||||
|
||||
// the scene (vulkan14scene.cpp)
|
||||
bool init_scene(std::string &Reason);
|
||||
@@ -196,6 +293,14 @@ class vulkan14_renderer : public gfx_renderer, public gfx::scene_walk
|
||||
void setup_shadow_matrices();
|
||||
// the light clusters of the pass: the grid and the lists of the lights
|
||||
void update_clusters(glm::ivec2 const &Targetsize);
|
||||
// which program of the depth prepass stands for the program of the material: 0 none, 1 without the alpha test, 2 with it
|
||||
int prepass_class(material_handle const Material);
|
||||
// the depth of the whole opaque scene of the colour pass of the main viewport before its colour, for the contact shadows
|
||||
// (Contactonly: with them alone) or for itself (gfx.depthprepass.scene), and the contact shadows set up to read it
|
||||
void render_scene_depth(std::size_t const Viewport, glm::mat4 const &Future);
|
||||
bool contact_shadows_wanted(viewport_config const &Viewport) const;
|
||||
void setup_contact_shadows(std::size_t const Viewport);
|
||||
bool m_contactshadows{false};
|
||||
// the materials
|
||||
material_handle invalid_material() const
|
||||
{
|
||||
@@ -215,6 +320,44 @@ class vulkan14_renderer : public gfx_renderer, public gfx::scene_walk
|
||||
// the screenshot copied with a frame the gpu is done with, saved
|
||||
void update_screenshot();
|
||||
void bind_pass_set();
|
||||
void update_pass_sets();
|
||||
// the pass set of the colour of the main view bound for the compute kernels, before the dispatches of Kernel (the kernels share
|
||||
// the layout of set 0 and the push constants, so the set stays bound for the ones which follow)
|
||||
void bind_compute_set(vk14::compute_kernel const &Kernel);
|
||||
// the light of the sky (vulkan14sky.cpp): the resources, their first state, the light of the frame worked out before its
|
||||
// passes, the environment map prefiltered with the GGX lobe, the stars of the sky pass
|
||||
bool init_sky(std::string &Reason);
|
||||
void destroy_sky();
|
||||
void clear_sky_images();
|
||||
void update_sky();
|
||||
void prefilter_environment();
|
||||
void render_stars(glm::mat4 const &View);
|
||||
// the automatic exposure of the image of the main view, and its bloom chain; the result of the chain, null without it
|
||||
void measure_exposure(vk14::image &Image);
|
||||
vk14::image *render_bloom(std::size_t const Viewport, vk14::image &Image);
|
||||
// the weather (vulkan14weather.cpp): the resources, the noises of the clouds, the block of the pass, what the weather is for the
|
||||
// frame (before its passes), the clouds and the fog volume of the colour pass of the main view, the clouds and the fog over the sky
|
||||
bool init_weather(std::string &Reason);
|
||||
void destroy_weather();
|
||||
void make_cloud_noise();
|
||||
void upload_weather_block();
|
||||
void update_weather();
|
||||
void render_weather_view(glm::mat4 const &Projection, glm::mat4 const &View, glm::dvec3 const &Camera, glm::ivec2 const &Size, int const Cablamp);
|
||||
void render_sky_weather(glm::mat4 const &Projection, bool const Mainview);
|
||||
// the ambient occlusion (vulkan14ao.cpp): the resources, and the occlusion of a viewport multiplied into its colour
|
||||
bool init_ao(std::string &Reason);
|
||||
void destroy_ao();
|
||||
void render_ao(std::size_t const Viewport, int const Mode);
|
||||
// the particles of the gpu: what the colour pass under way draws them with, and the depth of the scene drawn so far copied for
|
||||
// the soft particles (false: they aren't soft)
|
||||
gfx::gpu_particles::view particles_view() const;
|
||||
bool setup_particles_depth(std::size_t const Viewport);
|
||||
bool m_particlesoft{false};
|
||||
// the grass of the heightmap terrain seen from the main view, over the opaque scene (opengl46_renderer::Render_grass())
|
||||
void render_grass(glm::mat4 const &Future);
|
||||
// a pass of the post-processing: the fragment shader drawn over the whole of the target, reading the images (Pass: a pass of
|
||||
// its own, for the gpu times). Repeated: a bit for each input read texel by texel and repeated (the noise of the ssao)
|
||||
void post_pass(char const *Fragment, vk14::image &Target, std::vector<vk14::image *> const &Inputs, vk14::draw_constants const &Constants, char const *Pass = nullptr, unsigned const Repeated = 0);
|
||||
bool bind_scene_pipeline(vk14::scene_program &Program, vk14::target_formats const &Targets, vk14::blend_mode const Blend, int const Topology);
|
||||
void apply_draw_state();
|
||||
void push_textures();
|
||||
@@ -223,6 +366,11 @@ class vulkan14_renderer : public gfx_renderer, public gfx::scene_walk
|
||||
void update_texture_release();
|
||||
|
||||
std::unique_ptr<context> m_context;
|
||||
// the light of the sky and the weather of the frame, shared with the opengl renderer
|
||||
gfx::sky_light m_skylight;
|
||||
gfx::weather_state m_weatherstate;
|
||||
// the environment map prefiltered with the GGX lobe is bound for the pass (light_data.env_ggx)
|
||||
bool m_envmap_bound{false};
|
||||
// the data of the geometry, which the simulation reads back, and the banks with it on the gpu
|
||||
gfx::geometrybank_manager m_geometry;
|
||||
std::vector<gfx::geometry_bank *> m_banks;
|
||||
@@ -295,6 +443,24 @@ class vulkan14_renderer : public gfx_renderer, public gfx::scene_walk
|
||||
debug_stats m_laststats;
|
||||
|
||||
void update_info();
|
||||
// the debug windows (vulkan14debug.cpp, opengl46_renderer::draw_debug_ui()), the lines of the cullings and of the scene for them
|
||||
// and for the statistics, the counters of the light clusters read back, and the heatmap of the clusters over the output of a
|
||||
// viewport (opengl46_renderer::Render_cluster_heatmap())
|
||||
void draw_debug_ui();
|
||||
std::string cull_info();
|
||||
std::string scene_info();
|
||||
void collect_cluster_stats();
|
||||
void render_cluster_heatmap(std::size_t const Viewport);
|
||||
// the headlights (opengl46_renderer::headlight_config_s), set by the debug window
|
||||
struct headlight_config
|
||||
{
|
||||
float in_cutoff{1.005f};
|
||||
float out_cutoff{0.993f};
|
||||
float falloff_linear{0.15f};
|
||||
float falloff_quadratic{0.15f};
|
||||
float intensity{1.0f};
|
||||
float ambient{0.0f};
|
||||
} m_headlightconfig;
|
||||
// the device was lost: what was on the gpu goes to the log
|
||||
void report_device_lost(char const *Where);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user