SuperTuxKart 1.5 upstream source (from official release tarball)
This commit is contained in:
@@ -0,0 +1,341 @@
|
||||
#ifndef HEADER_GE_VULKAN_DRAW_CALL_HPP
|
||||
#define HEADER_GE_VULKAN_DRAW_CALL_HPP
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "vulkan_wrapper.h"
|
||||
|
||||
#include "matrix4.h"
|
||||
#include "vector3d.h"
|
||||
#include "ESceneNodeTypes.h"
|
||||
#include "SColor.h"
|
||||
#include "SMaterial.h"
|
||||
|
||||
#include "LinearMath/btQuaternion.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
class ISceneNode; class IBillboardSceneNode; struct SParticle;
|
||||
class IMesh; class ILightSceneNode;
|
||||
}
|
||||
}
|
||||
|
||||
namespace GE
|
||||
{
|
||||
class GECullingTool;
|
||||
class GESPMBuffer;
|
||||
class GEVulkanAnimatedMeshSceneNode;
|
||||
class GEVulkanCameraSceneNode;
|
||||
class GEVulkanDriver;
|
||||
class GEVulkanDynamicBuffer;
|
||||
class GEVulkanDynamicSPMBuffer;
|
||||
class GEVulkanLightHandler;
|
||||
class GEVulkanSkyBoxRenderer;
|
||||
class GEVulkanTextureDescriptor;
|
||||
|
||||
typedef std::pair<std::vector<VkVertexInputBindingDescription>,
|
||||
std::vector<VkVertexInputAttributeDescription> > VertexDescription;
|
||||
|
||||
struct ObjectData
|
||||
{
|
||||
float m_translation_x;
|
||||
float m_translation_y;
|
||||
float m_translation_z;
|
||||
float m_hue_change;
|
||||
float m_rotation[4];
|
||||
float m_scale_x;
|
||||
float m_scale_y;
|
||||
float m_scale_z;
|
||||
irr::video::SColor m_custom_vertex_color;
|
||||
int m_skinning_offset;
|
||||
int m_material_id;
|
||||
float m_texture_trans[2];
|
||||
// ------------------------------------------------------------------------
|
||||
void init(irr::scene::ISceneNode* node, int material_id,
|
||||
int skinning_offset, int irrlicht_material_id);
|
||||
// ------------------------------------------------------------------------
|
||||
void init(irr::scene::IBillboardSceneNode* node, int material_id,
|
||||
const btQuaternion& rotation);
|
||||
// ------------------------------------------------------------------------
|
||||
void init(const irr::scene::SParticle& particle, int material_id,
|
||||
const btQuaternion& rotation,
|
||||
const irr::core::vector3df& view_position, bool flips,
|
||||
bool sky_particle, bool backface_culling);
|
||||
};
|
||||
|
||||
enum GEVulkanPipelineType : unsigned
|
||||
{
|
||||
GVPT_DEPTH = 1,
|
||||
GVPT_SOLID,
|
||||
GVPT_DEFERRED_LIGHTING,
|
||||
GVPT_DEFERRED_CONVERT_COLOR,
|
||||
GVPT_GHOST_DEPTH,
|
||||
GVPT_TRANSPARENT,
|
||||
GVPT_SKYBOX,
|
||||
GVPT_DISPLACE_MASK,
|
||||
GVPT_DISPLACE_COLOR,
|
||||
};
|
||||
|
||||
struct GEMaterial;
|
||||
|
||||
struct PipelineSettings
|
||||
{
|
||||
std::string m_shader_name;
|
||||
std::shared_ptr<const GEMaterial> m_material;
|
||||
char m_drawing_priority;
|
||||
VkPipelineLayout m_custom_pl;
|
||||
VkCompareOp m_depth_op;
|
||||
VkPrimitiveTopology m_topology;
|
||||
VertexDescription m_vertex_description;
|
||||
GEVulkanPipelineType m_pipeline_type;
|
||||
|
||||
PipelineSettings();
|
||||
void loadMaterial(const GEMaterial& m);
|
||||
};
|
||||
|
||||
struct PipelineData
|
||||
{
|
||||
PipelineSettings m_settings;
|
||||
std::map<GEVulkanPipelineType, std::shared_ptr<VkPipeline> > m_pipelines;
|
||||
};
|
||||
|
||||
struct DrawCallData
|
||||
{
|
||||
VkDrawIndexedIndirectCommand m_cmd;
|
||||
std::string m_shader;
|
||||
std::string m_sorting_key;
|
||||
GESPMBuffer* m_mb;
|
||||
int m_material_id;
|
||||
uint32_t m_dynamic_offset;
|
||||
};
|
||||
|
||||
class GEVulkanHiZDepth;
|
||||
class GEVulkanDrawCall
|
||||
{
|
||||
private:
|
||||
typedef std::array<const irr::video::ITexture*,
|
||||
_IRR_MATERIAL_MAX_TEXTURES_> TexturesList;
|
||||
|
||||
const int BILLBOARD_NODE = -1;
|
||||
|
||||
const int PARTICLE_NODE = -2;
|
||||
|
||||
std::map<TexturesList, GESPMBuffer*> m_billboard_buffers;
|
||||
|
||||
irr::core::vector3df m_view_position;
|
||||
|
||||
btQuaternion m_billboard_rotation;
|
||||
|
||||
std::map<std::pair<GESPMBuffer*, TexturesList>, std::unordered_map<std::string,
|
||||
std::vector<std::pair<irr::scene::ISceneNode*, int> > > >
|
||||
m_visible_nodes;
|
||||
|
||||
std::map<std::pair<GESPMBuffer*, TexturesList>, irr::scene::IMesh*> m_mb_map;
|
||||
|
||||
std::map<std::string, std::vector<
|
||||
std::pair<GEVulkanDynamicSPMBuffer*, irr::scene::ISceneNode*> > >
|
||||
m_dynamic_spm_buffers;
|
||||
|
||||
GECullingTool* m_culling_tool;
|
||||
|
||||
GEVulkanLightHandler* m_light_handler;
|
||||
|
||||
std::vector<DrawCallData> m_cmds;
|
||||
|
||||
std::vector<ObjectData> m_visible_objects;
|
||||
|
||||
GEVulkanDynamicBuffer* m_dynamic_data;
|
||||
|
||||
GEVulkanDynamicBuffer* m_sbo_data;
|
||||
|
||||
const VkPhysicalDeviceLimits& m_limits;
|
||||
|
||||
size_t m_object_data_padded_size;
|
||||
|
||||
size_t m_skinning_data_padded_size;
|
||||
|
||||
size_t m_materials_padded_size;
|
||||
|
||||
size_t m_dynamic_spm_padded_size;
|
||||
|
||||
bool m_update_data_descriptor_sets;
|
||||
|
||||
VkDescriptorSetLayout m_data_layout;
|
||||
|
||||
VkDescriptorPool m_descriptor_pool;
|
||||
|
||||
std::vector<VkDescriptorSet> m_data_descriptor_sets;
|
||||
|
||||
VkPipelineLayout m_pipeline_layout, m_skybox_layout;
|
||||
|
||||
std::vector<VkPipelineLayout> m_deferred_layouts;
|
||||
|
||||
std::unordered_map<std::string, PipelineData> m_graphics_pipelines;
|
||||
|
||||
std::unordered_map<GEVulkanDynamicSPMBuffer*, std::pair<int, size_t> > m_dyspmb_materials;
|
||||
|
||||
GEVulkanSkyBoxRenderer* m_skybox_renderer;
|
||||
|
||||
GEVulkanTextureDescriptor* m_texture_descriptor;
|
||||
|
||||
std::unordered_set<GEVulkanAnimatedMeshSceneNode*> m_skinning_nodes;
|
||||
|
||||
std::unordered_map<std::string, std::pair<uint32_t, std::vector<int> > >
|
||||
m_materials_data;
|
||||
|
||||
GEVulkanHiZDepth* m_hiz_depth;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void createAllPipelines(GEVulkanDriver* vk);
|
||||
// ------------------------------------------------------------------------
|
||||
void createPipeline(GEVulkanDriver* vk, const PipelineSettings& settings,
|
||||
std::unordered_map<std::string, std::shared_ptr<VkPipeline> >& dp_cache);
|
||||
// ------------------------------------------------------------------------
|
||||
void createVulkanData();
|
||||
// ------------------------------------------------------------------------
|
||||
std::string getShader(const irr::video::SMaterial& m);
|
||||
// ------------------------------------------------------------------------
|
||||
std::string getShader(irr::scene::ISceneNode* node, int material_id);
|
||||
// ------------------------------------------------------------------------
|
||||
bool bindPipeline(VkCommandBuffer cmd, const std::string& name,
|
||||
VkPipeline* prev_pipeline,
|
||||
GEVulkanPipelineType pt) const;
|
||||
// ------------------------------------------------------------------------
|
||||
TexturesList getTexturesList(const irr::video::SMaterial& m)
|
||||
{
|
||||
TexturesList textures;
|
||||
for (unsigned i = 0; i < textures.size(); i++)
|
||||
textures[i] = m.TextureLayer[i].Texture;
|
||||
return textures;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
size_t getInitialSBOSize() const;
|
||||
// ------------------------------------------------------------------------
|
||||
void updateDataDescriptorSets(GEVulkanDriver* vk);
|
||||
// ------------------------------------------------------------------------
|
||||
void bindBaseVertex(GEVulkanDriver* vk, VkCommandBuffer cmd);
|
||||
// ------------------------------------------------------------------------
|
||||
std::string getDynamicBufferKey(const std::string& shader) const
|
||||
{
|
||||
char drawing_priority = (char)1;
|
||||
auto it = m_graphics_pipelines.find(shader);
|
||||
if (it != m_graphics_pipelines.end())
|
||||
drawing_priority = it->second.m_settings.m_drawing_priority;
|
||||
return std::string(1, drawing_priority) + shader;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
std::string getShaderFromKey(const std::string& key) const
|
||||
{ return key.substr(1); }
|
||||
// ------------------------------------------------------------------------
|
||||
void bindSingleMaterial(VkCommandBuffer cmd,
|
||||
const std::string& cur_pipeline,
|
||||
int material_id, GEVulkanPipelineType pt);
|
||||
// ------------------------------------------------------------------------
|
||||
void bindDataDescriptor(VkCommandBuffer cmd, int current_buffer_idx,
|
||||
std::vector<uint32_t>& dynamic_offsets)
|
||||
{
|
||||
vkCmdBindDescriptorSets(cmd,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 1, 1,
|
||||
&m_data_descriptor_sets[current_buffer_idx],
|
||||
dynamic_offsets.size(), dynamic_offsets.data());
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
VertexDescription getDefaultVertexDescription() const;
|
||||
// ------------------------------------------------------------------------
|
||||
size_t getLightDataOffset() const;
|
||||
// ------------------------------------------------------------------------
|
||||
std::vector<uint32_t> getDefaultDynamicOffsets() const;
|
||||
// ------------------------------------------------------------------------
|
||||
VkRenderPass getRenderPassForPipelineCreation(GEVulkanDriver* vk,
|
||||
GEVulkanPipelineType type);
|
||||
// ------------------------------------------------------------------------
|
||||
uint32_t getSubpassForPipelineCreation(GEVulkanDriver* vk,
|
||||
GEVulkanPipelineType type);
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
GEVulkanDrawCall();
|
||||
// ------------------------------------------------------------------------
|
||||
~GEVulkanDrawCall();
|
||||
// ------------------------------------------------------------------------
|
||||
void addNode(irr::scene::ISceneNode* node);
|
||||
// ------------------------------------------------------------------------
|
||||
void addBillboardNode(irr::scene::ISceneNode* node,
|
||||
irr::scene::ESCENE_NODE_TYPE node_type);
|
||||
// ------------------------------------------------------------------------
|
||||
void prepare(GEVulkanCameraSceneNode* cam);
|
||||
// ------------------------------------------------------------------------
|
||||
void generate(GEVulkanDriver* vk);
|
||||
// ------------------------------------------------------------------------
|
||||
void uploadDynamicData(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
|
||||
VkCommandBuffer custom_cmd = VK_NULL_HANDLE);
|
||||
// ------------------------------------------------------------------------
|
||||
bool doDepthOnlyRenderingFirst();
|
||||
// ------------------------------------------------------------------------
|
||||
void bindAllMaterials(VkCommandBuffer cmd);
|
||||
// ------------------------------------------------------------------------
|
||||
void prepareRendering(GEVulkanDriver* vk);
|
||||
// ------------------------------------------------------------------------
|
||||
void prepareViewport(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
|
||||
VkCommandBuffer cmd);
|
||||
// ------------------------------------------------------------------------
|
||||
void renderPipeline(GEVulkanDriver* vk, VkCommandBuffer cmd,
|
||||
GEVulkanPipelineType pt, bool& rebind_base_vertex);
|
||||
// ------------------------------------------------------------------------
|
||||
bool renderSkyBox(GEVulkanDriver* vk, VkCommandBuffer cmd);
|
||||
// ------------------------------------------------------------------------
|
||||
void renderDeferredLighting(GEVulkanDriver* vk, VkCommandBuffer cmd);
|
||||
// ------------------------------------------------------------------------
|
||||
void renderDeferredConvertColor(GEVulkanDriver* vk, VkCommandBuffer cmd);
|
||||
// ------------------------------------------------------------------------
|
||||
void renderDisplaceColor(GEVulkanDriver* vk, VkCommandBuffer cmd,
|
||||
VkBool32 has_displace);
|
||||
// ------------------------------------------------------------------------
|
||||
unsigned getPolyCount() const
|
||||
{
|
||||
unsigned result = 0;
|
||||
for (auto& cmd : m_cmds)
|
||||
result += (cmd.m_cmd.indexCount / 3) * cmd.m_cmd.instanceCount;
|
||||
return result;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void reset()
|
||||
{
|
||||
m_visible_nodes.clear();
|
||||
m_mb_map.clear();
|
||||
m_cmds.clear();
|
||||
m_visible_objects.clear();
|
||||
m_dyspmb_materials.clear();
|
||||
m_skinning_nodes.clear();
|
||||
m_materials_data.clear();
|
||||
m_dynamic_spm_buffers.clear();
|
||||
m_skybox_renderer = NULL;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void addSkyBox(irr::scene::ISceneNode* node);
|
||||
// ------------------------------------------------------------------------
|
||||
void addLightNode(irr::scene::ILightSceneNode* node);
|
||||
// ------------------------------------------------------------------------
|
||||
bool hasShaderForRendering(const std::string& shader)
|
||||
{
|
||||
const std::string& dbk = getDynamicBufferKey(shader);
|
||||
if (m_dynamic_spm_buffers.find(dbk) != m_dynamic_spm_buffers.end())
|
||||
return true;
|
||||
return m_materials_data.find(shader) != m_materials_data.end();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
GEVulkanHiZDepth* getHiZDepth() const { return m_hiz_depth; }
|
||||
}; // GEVulkanDrawCall
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user