Add setDirtyOffset for GEVulkanDynamicSPMBuffer
This commit is contained in:
parent
1d00e44f97
commit
ddc0b9d1ed
@ -5,6 +5,7 @@
|
||||
|
||||
namespace GE
|
||||
{
|
||||
class GEVulkanDriver;
|
||||
class GEVulkanDynamicBuffer;
|
||||
|
||||
class GEVulkanDynamicSPMBuffer : public GESPMBuffer
|
||||
@ -13,6 +14,12 @@ private:
|
||||
GEVulkanDynamicBuffer* m_vertex_buffer;
|
||||
|
||||
GEVulkanDynamicBuffer* m_index_buffer;
|
||||
|
||||
GEVulkanDriver* m_vk;
|
||||
|
||||
uint32_t* m_vertex_update_offsets;
|
||||
|
||||
uint32_t* m_index_update_offsets;
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
GEVulkanDynamicSPMBuffer();
|
||||
@ -34,6 +41,9 @@ public:
|
||||
void updateVertexIndexBuffer(int buffer_index);
|
||||
// ------------------------------------------------------------------------
|
||||
void drawDynamicVertexIndexBuffer(VkCommandBuffer cmd, int buffer_index);
|
||||
// ------------------------------------------------------------------------
|
||||
void setDirtyOffset(irr::u32 offset,
|
||||
irr::scene::E_BUFFER_TYPE buffer = irr::scene::EBT_VERTEX_AND_INDEX);
|
||||
};
|
||||
|
||||
} // end namespace GE
|
||||
|
@ -12,39 +12,69 @@ namespace GE
|
||||
// ----------------------------------------------------------------------------
|
||||
GEVulkanDynamicSPMBuffer::GEVulkanDynamicSPMBuffer()
|
||||
{
|
||||
unsigned frame_count = GEVulkanDriver::getMaxFrameInFlight() + 1;
|
||||
m_vertex_buffer = new GEVulkanDynamicBuffer(
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, 100,
|
||||
GEVulkanDriver::getMaxFrameInFlight() + 1, 0);
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, 100, frame_count, 0);
|
||||
m_index_buffer = new GEVulkanDynamicBuffer(
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT, 100,
|
||||
GEVulkanDriver::getMaxFrameInFlight() + 1, 0);
|
||||
getVKDriver()->addDynamicSPMBuffer(this);
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT, 100, frame_count, 0);
|
||||
m_vk = getVKDriver();
|
||||
m_vk->addDynamicSPMBuffer(this);
|
||||
m_vertex_update_offsets = new uint32_t[frame_count]();
|
||||
m_index_update_offsets = new uint32_t[frame_count]();
|
||||
} // GEVulkanDynamicSPMBuffer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
GEVulkanDynamicSPMBuffer::~GEVulkanDynamicSPMBuffer()
|
||||
{
|
||||
getVKDriver()->removeDynamicSPMBuffer(this);
|
||||
m_vk->removeDynamicSPMBuffer(this);
|
||||
delete m_vertex_buffer;
|
||||
delete m_index_buffer;
|
||||
delete [] m_vertex_update_offsets;
|
||||
delete [] m_index_update_offsets;
|
||||
} // ~GEVulkanDynamicSPMBuffer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDynamicSPMBuffer::updateVertexIndexBuffer(int buffer_index)
|
||||
{
|
||||
if (m_vertex_update_offsets[buffer_index] == m_vertices.size() &&
|
||||
m_index_update_offsets[buffer_index] == m_indices.size())
|
||||
return;
|
||||
|
||||
const size_t stride = sizeof(irr::video::S3DVertexSkinnedMesh) - 16;
|
||||
double vertex_size = (double)(m_vertices.size() * stride);
|
||||
double base = std::log2(vertex_size);
|
||||
m_vertex_buffer->resizeIfNeeded(2 << (unsigned)base);
|
||||
unsigned frame_count = GEVulkanDriver::getMaxFrameInFlight() + 1;
|
||||
if (m_vertex_buffer->resizeIfNeeded(2 << (unsigned)base))
|
||||
std::fill_n(m_vertex_update_offsets, frame_count, 0);
|
||||
|
||||
uint8_t* mapped_addr = (uint8_t*)m_vertex_buffer->getMappedAddr()
|
||||
[buffer_index];
|
||||
for (unsigned i = 0; i < m_vertices.size(); i++)
|
||||
unsigned voffset = m_vertex_update_offsets[buffer_index] * stride;
|
||||
mapped_addr += voffset;
|
||||
for (unsigned i = m_vertex_update_offsets[buffer_index];
|
||||
i < m_vertices.size(); i++)
|
||||
{
|
||||
memcpy(mapped_addr, &m_vertices[i], stride);
|
||||
mapped_addr += stride;
|
||||
}
|
||||
m_index_buffer->setCurrentData(m_indices.data(), m_indices.size() *
|
||||
sizeof(uint16_t), NULL, buffer_index);
|
||||
m_vertex_update_offsets[buffer_index] = m_vertices.size();
|
||||
|
||||
double index_size = (double)(m_indices.size() * sizeof(uint16_t));
|
||||
base = std::log2(index_size);
|
||||
if (m_index_buffer->resizeIfNeeded(2 << (unsigned)base))
|
||||
std::fill_n(m_index_update_offsets, frame_count, 0);
|
||||
|
||||
mapped_addr = (uint8_t*)m_index_buffer->getMappedAddr()
|
||||
[buffer_index];
|
||||
unsigned ioffset = m_index_update_offsets[buffer_index] * sizeof(uint16_t);
|
||||
mapped_addr += ioffset;
|
||||
for (unsigned i = m_index_update_offsets[buffer_index];
|
||||
i < m_indices.size(); i++)
|
||||
{
|
||||
memcpy(mapped_addr, &m_indices[i], sizeof(uint16_t));
|
||||
mapped_addr += sizeof(uint16_t);
|
||||
}
|
||||
m_index_update_offsets[buffer_index] = m_indices.size();
|
||||
} // updateVertexIndexBuffer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -68,4 +98,35 @@ void GEVulkanDynamicSPMBuffer::drawDynamicVertexIndexBuffer(VkCommandBuffer cmd,
|
||||
vkCmdDrawIndexed(cmd, getIndexCount(), 1, 0, 0, 0);
|
||||
} // drawDynamicVertexIndexBuffer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDynamicSPMBuffer::setDirtyOffset(irr::u32 offset,
|
||||
irr::scene::E_BUFFER_TYPE buffer)
|
||||
{
|
||||
int vertex_update_offset = -1;
|
||||
int index_update_offset = -1;
|
||||
if (buffer == irr::scene::EBT_VERTEX_AND_INDEX)
|
||||
vertex_update_offset = index_update_offset = offset;
|
||||
else if (buffer == irr::scene::EBT_VERTEX)
|
||||
vertex_update_offset = offset;
|
||||
else if (buffer == irr::scene::EBT_INDEX)
|
||||
index_update_offset = offset;
|
||||
unsigned frame_count = GEVulkanDriver::getMaxFrameInFlight() + 1;
|
||||
if (vertex_update_offset != -1)
|
||||
{
|
||||
for (unsigned i = 0; i < frame_count; i++)
|
||||
{
|
||||
if (m_vertex_update_offsets[i] > vertex_update_offset)
|
||||
m_vertex_update_offsets[i] = vertex_update_offset;
|
||||
}
|
||||
}
|
||||
if (index_update_offset != -1)
|
||||
{
|
||||
for (unsigned i = 0; i < frame_count; i++)
|
||||
{
|
||||
if (m_index_update_offsets[i] > index_update_offset)
|
||||
m_index_update_offsets[i] = index_update_offset;
|
||||
}
|
||||
}
|
||||
} // setDirtyOffset
|
||||
|
||||
} // end namespace GE
|
||||
|
@ -146,6 +146,10 @@ namespace scene
|
||||
//! flags the meshbuffer as changed, reloads hardware buffers
|
||||
virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) = 0;
|
||||
|
||||
//! flags the meshbuffer as changed with offset, reloads hardware buffers
|
||||
virtual void setDirtyOffset(u32 offset,
|
||||
E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) {}
|
||||
|
||||
//! Get the currently used ID for identification of changes.
|
||||
/** This shouldn't be used for anything outside the VideoDriver. */
|
||||
virtual u32 getChangedID_Vertex() const = 0;
|
||||
|
@ -188,6 +188,7 @@ void Shadow::update(bool enabled)
|
||||
.toIrrVector());
|
||||
}
|
||||
buffer->recalculateBoundingBox();
|
||||
buffer->setDirtyOffset(0, irr::scene::EBT_VERTEX);
|
||||
mesh->setBoundingBox(buffer->getBoundingBox());
|
||||
}
|
||||
} // update
|
||||
|
@ -372,6 +372,11 @@ void SkidMarks::SkidMarkQuads::addLegacy(const Vec3& left,
|
||||
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);
|
||||
int vertex_update_offset = buffer->getVertexCount();
|
||||
vertex_update_offset -= 4;
|
||||
if (vertex_update_offset < 0)
|
||||
vertex_update_offset = 0;
|
||||
buffer->setDirtyOffset(vertex_update_offset, irr::scene::EBT_VERTEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -405,6 +410,8 @@ void SkidMarks::SkidMarkQuads::addLegacy(const Vec3& left,
|
||||
m_node->setVisible(true);
|
||||
std::array<uint16_t, 6> indices = {{ }};
|
||||
buffer->append(NULL, 0, indices.data(), indices.size());
|
||||
buffer->setDirtyOffset(buffer->getIndexCount() - 6,
|
||||
irr::scene::EBT_INDEX);
|
||||
unsigned idx = buffer->getIndexCount() - indices.size();
|
||||
buffer->getIndices()[idx + 0] = n - 2;
|
||||
buffer->getIndices()[idx + 1] = n - 1;
|
||||
|
@ -203,6 +203,7 @@ void RubberBand::updateGraphics(float dt)
|
||||
buffer->getIndices()[5] = 3;
|
||||
}
|
||||
buffer->recalculateBoundingBox();
|
||||
buffer->setDirtyOffset(0, irr::scene::EBT_VERTEX_AND_INDEX);
|
||||
mesh->setBoundingBox(buffer->getBoundingBox());
|
||||
}
|
||||
else if (m_dy_dc)
|
||||
|
Loading…
Reference in New Issue
Block a user