Use GEVulkanDynamicSPMBuffer on streaming buffers

This commit is contained in:
Benau 2022-11-29 13:02:36 +08:00
parent d5fdcb2d98
commit 90a22a691a
6 changed files with 121 additions and 38 deletions

View File

@ -16,10 +16,10 @@ class GESPMBuffer : public irr::scene::IMeshBuffer
protected:
irr::video::SMaterial m_material;
private:
std::vector<irr::video::S3DVertexSkinnedMesh> m_vertices;
std::vector<irr::u16> m_indices;
private:
irr::core::aabbox3d<irr::f32> m_bounding_box;
@ -178,7 +178,7 @@ public:
// ------------------------------------------------------------------------
void setHasSkinning(bool val) { m_has_skinning = val; }
// ------------------------------------------------------------------------
void bindVertexIndexBuffer(VkCommandBuffer cmd)
virtual void bindVertexIndexBuffer(VkCommandBuffer cmd)
{
VkBuffer buffer = getVkBuffer();
std::array<VkBuffer, 2> vertex_buffer =
@ -197,9 +197,9 @@ public:
VK_INDEX_TYPE_UINT16);
}
// ------------------------------------------------------------------------
void createVertexIndexBuffer();
virtual void createVertexIndexBuffer();
// ------------------------------------------------------------------------
void destroyVertexIndexBuffer();
virtual void destroyVertexIndexBuffer();
// ------------------------------------------------------------------------
std::vector<irr::video::S3DVertexSkinnedMesh>& getVerticesVector()
{ return m_vertices; }

View File

@ -18,6 +18,18 @@ public:
GEVulkanDynamicSPMBuffer();
// ------------------------------------------------------------------------
~GEVulkanDynamicSPMBuffer();
// ------------------------------------------------------------------------
virtual irr::scene::E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const
{ return irr::scene::EHM_STREAM; }
// ------------------------------------------------------------------------
virtual irr::scene::E_HARDWARE_MAPPING getHardwareMappingHint_Index() const
{ return irr::scene::EHM_STREAM; }
// ------------------------------------------------------------------------
virtual void bindVertexIndexBuffer(VkCommandBuffer cmd) {}
// ------------------------------------------------------------------------
virtual void createVertexIndexBuffer() {}
// ------------------------------------------------------------------------
virtual void destroyVertexIndexBuffer() {}
};
} // end namespace GE

View File

@ -246,6 +246,9 @@ void GEVulkanDrawCall::addNode(irr::scene::ISceneNode* node)
if (m_culling_tool->isCulled(buffer, node))
continue;
const std::string& shader = getShader(node, i);
if (buffer->getHardwareMappingHint_Vertex() == irr::scene::EHM_STREAM ||
buffer->getHardwareMappingHint_Index() == irr::scene::EHM_STREAM)
continue;
m_visible_nodes[buffer][shader].emplace_back(node, i);
m_mb_map[buffer] = mesh;
if (anode && !added_skinning &&

View File

@ -31,7 +31,9 @@
#ifndef SERVER_ONLY
#include <array>
#include <ge_vulkan_dynamic_spm_buffer.hpp>
#include <IMeshSceneNode.h>
#include <IVideoDriver.h>
#include <SMesh.h>
#include <SMeshBuffer.h>
@ -60,13 +62,27 @@ Shadow::Shadow(Material* shadow_mat, const AbstractKart& kart)
}
else
{
video::S3DVertex v;
v.Color = (video::SColor)-1;
std::array<video::S3DVertex, 4> vertices = {{ v, v, v, v }};
std::array<uint16_t, 6> indices = {{ 0, 1, 2, 0, 2, 3 }};
scene::SMeshBuffer* buffer = new scene::SMeshBuffer();
buffer->append(vertices.data(), vertices.size(), indices.data(),
indices.size());
scene::IMeshBuffer* buffer = NULL;
if (irr_driver->getVideoDriver()->getDriverType() == video::EDT_VULKAN)
{
buffer = new GE::GEVulkanDynamicSPMBuffer();
video::S3DVertexSkinnedMesh v;
v.m_color = (video::SColor)-1;
std::array<video::S3DVertexSkinnedMesh, 4> vertices =
{{ v, v, v, v }};
buffer->append(vertices.data(), vertices.size(), indices.data(),
indices.size());
}
else
{
buffer = new scene::SMeshBuffer();
video::S3DVertex v;
v.Color = (video::SColor)-1;
std::array<video::S3DVertex, 4> vertices = {{ v, v, v, v }};
buffer->append(vertices.data(), vertices.size(), indices.data(),
indices.size());
}
buffer->setTCoords(0, core::vector2df(0.0f, 0.0f));
buffer->setTCoords(1, core::vector2df(1.0f, 0.0f));
buffer->setTCoords(2, core::vector2df(1.0f, 1.0f));

View File

@ -38,7 +38,9 @@
#ifndef SERVER_ONLY
#include <ge_vulkan_dynamic_spm_buffer.hpp>
#include <IMeshSceneNode.h>
#include <IVideoDriver.h>
#include <SMesh.h>
#include <SMeshBuffer.h>
#include <ge_render_info.hpp>
@ -250,7 +252,11 @@ SkidMarks::SkidMarkQuads::SkidMarkQuads(const Vec3 &left,
}
else
{
scene::SMeshBuffer* buffer = new scene::SMeshBuffer();
scene::IMeshBuffer* buffer = NULL;
if (irr_driver->getVideoDriver()->getDriverType() == video::EDT_VULKAN)
buffer = new GE::GEVulkanDynamicSPMBuffer();
else
buffer = new scene::SMeshBuffer();
material->setMaterialProperties(&buffer->getMaterial(), buffer);
buffer->getMaterial().setTexture(0, material->getTexture());
buffer->setHardwareMappingHint(scene::EHM_STREAM);
@ -338,28 +344,58 @@ void SkidMarks::SkidMarkQuads::addLegacy(const Vec3& left,
// too much with the track.
int n = buffer->getVertexCount();
std::array<video::S3DVertex, 2> v;
v[0].Color = m_start_color;
v[0].Color.setAlpha(0); // initially create all vertices at alpha=0...
v[1] = v[0];
// then when adding a new set of vertices, make the previous 2 opaque.
// this ensures that the last two vertices are always at alpha=0,
// producing a fade-out effect
video::S3DVertex* vertices = (video::S3DVertex*)buffer->getVertices();
if (n > 4)
if (irr_driver->getVideoDriver()->getDriverType() == video::EDT_VULKAN)
{
vertices[n - 1].Color.setAlpha(m_start_alpha);
vertices[n - 2].Color.setAlpha(m_start_alpha);
std::array<video::S3DVertexSkinnedMesh, 2> v = {{ }};
v[0].m_color = m_start_color;
v[0].m_color.setAlpha(0); // initially create all vertices at alpha=0...
v[1] = v[0];
// then when adding a new set of vertices, make the previous 2 opaque.
// this ensures that the last two vertices are always at alpha=0,
// producing a fade-out effect
video::S3DVertexSkinnedMesh* vertices = (video::S3DVertexSkinnedMesh*)
buffer->getVertices();
if (n > 4)
{
vertices[n - 1].m_color.setAlpha(m_start_alpha);
vertices[n - 2].m_color.setAlpha(m_start_alpha);
}
v[0].m_position = Vec3(left + normal * m_z_offset).toIrrVector();
v[0].m_normal = MiniGLM::compressVector3(normal.toIrrVector());
short half_distance = MiniGLM::toFloat16(distance * 0.5f);
v[0].m_all_uvs[1] = half_distance;
v[1].m_position = Vec3(right + normal * m_z_offset).toIrrVector();
v[1].m_normal = MiniGLM::compressVector3(normal.toIrrVector());
short half_float_1 = 15360;
v[1].m_all_uvs[0] = half_float_1;
v[1].m_all_uvs[1] = half_distance;
buffer->append(v.data(), v.size(), NULL, 0);
}
else
{
std::array<video::S3DVertex, 2> v;
v[0].Color = m_start_color;
v[0].Color.setAlpha(0);
v[1] = v[0];
video::S3DVertex* vertices = (video::S3DVertex*)buffer->getVertices();
if (n > 4)
{
vertices[n - 1].Color.setAlpha(m_start_alpha);
vertices[n - 2].Color.setAlpha(m_start_alpha);
}
v[0].Pos = Vec3(left + normal * m_z_offset).toIrrVector();
v[0].Normal = normal.toIrrVector();
v[0].TCoords = core::vector2df(0.0f, distance * 0.5f);
v[1].Pos = Vec3(right + normal * m_z_offset).toIrrVector();
v[1].Normal = normal.toIrrVector();
v[1].TCoords = core::vector2df(1.0f, distance * 0.5f);
buffer->append(v.data(), v.size(), NULL, 0);
}
v[0].Pos = Vec3(left + normal * m_z_offset).toIrrVector();
v[0].Normal = normal.toIrrVector();
v[0].TCoords = core::vector2df(0.0f, distance * 0.5f);
v[1].Pos = Vec3(right + normal * m_z_offset).toIrrVector();
v[1].Normal = normal.toIrrVector();
v[1].TCoords = core::vector2df(1.0f, distance * 0.5f);
buffer->append(v.data(), v.size(), NULL, 0);
// Out of the box Irrlicht only supports triangle meshes and not
// triangle strips. Since this is a strip it would be more efficient
// to use a special triangle strip scene node.

View File

@ -32,11 +32,12 @@
#include "modes/world.hpp"
#include "physics/physics.hpp"
#include "race/race_manager.hpp"
#include "mini_glm.hpp"
#include "utils/string_utils.hpp"
#include <array>
#include <ge_vulkan_dynamic_spm_buffer.hpp>
#include <IMeshSceneNode.h>
#include <IVideoDriver.h>
#include <SMesh.h>
#include <SMeshBuffer.h>
@ -81,14 +82,29 @@ RubberBand::RubberBand(Plunger *plunger, AbstractKart *kart)
}
else
{
video::S3DVertex v;
v.Normal = core::vector3df(0, 1, 0);
v.Color = color;
std::array<video::S3DVertex, 4> vertices = {{ v, v, v, v }};
std::array<uint16_t, 6> indices = {{ 0, 1, 2, 0, 2, 3 }};
scene::SMeshBuffer* buffer = new scene::SMeshBuffer();
buffer->append(vertices.data(), vertices.size(), indices.data(),
indices.size());
scene::IMeshBuffer* buffer = NULL;
if (irr_driver->getVideoDriver()->getDriverType() == video::EDT_VULKAN)
{
buffer = new GE::GEVulkanDynamicSPMBuffer();
video::S3DVertexSkinnedMesh v;
v.m_normal = 0x1FF << 10;
v.m_color = color;
std::array<video::S3DVertexSkinnedMesh, 4> vertices =
{{ v, v, v, v }};
buffer->append(vertices.data(), vertices.size(), indices.data(),
indices.size());
}
else
{
buffer = new scene::SMeshBuffer();
video::S3DVertex v;
v.Normal = core::vector3df(0, 1, 0);
v.Color = color;
std::array<video::S3DVertex, 4> vertices = {{ v, v, v, v }};
buffer->append(vertices.data(), vertices.size(), indices.data(),
indices.size());
}
buffer->getMaterial().AmbientColor = color;
buffer->getMaterial().DiffuseColor = color;
buffer->getMaterial().EmissiveColor = color;