Use host-visible buffers for text rendering

Remove text caching logic and m_lastRenderedText. Switch to direct
memory-mapped updates of dynamic vertex and index buffers each frame,
eliminating staging/caching paths and simplifying debug/update logic.
This commit is contained in:
ubuntu1804 2025-11-11 09:38:47 +08:00
parent 9786baed86
commit d0ffdc4867
2 changed files with 5 additions and 38 deletions

View File

@ -2663,35 +2663,7 @@ void VulkanRenderer::drawText(VkCommandBuffer commandBuffer, int frameCount,
return; // Text rendering not available
}
// 构建当前帧的文本内容(用于缓存比较)
std::string currentText = lockInfo + "|" + std::to_string(paintingEnabled) + "|"
+ std::to_string(m_width) + "x" + std::to_string(m_height);
// 检查文本是否变化,只在变化时重建 buffers
bool needsRebuild = (currentText != m_lastRenderedText) || (m_textVertexBuffer == VK_NULL_HANDLE);
// 如果文本没有变化且 buffers 已存在,直接使用缓存的 buffers
if (!needsRebuild && m_textVertexBuffer != VK_NULL_HANDLE && m_textIndexBuffer != VK_NULL_HANDLE) {
// Bind text pipeline
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_textPipeline);
// Bind descriptor sets for text rendering (if using textures)
if (!m_descriptorSets.empty()) {
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_textPipelineLayout, 0, 1,
&m_descriptorSets[0], 0, nullptr);
}
// Draw text using cached buffers
VkBuffer vertexBuffers[] = {m_textVertexBuffer};
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
vkCmdBindIndexBuffer(commandBuffer, m_textIndexBuffer, 0, VK_INDEX_TYPE_UINT16);
vkCmdDrawIndexed(commandBuffer, m_textIndexCount, 1, 0, 0, 0);
return;
}
// 文本变化了,需要重建 buffers
// 使用 host-visible buffers 后,每帧更新成本很低(只是 memcpy无需缓存
// Bind text pipeline
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_textPipeline);
@ -2808,7 +2780,7 @@ void VulkanRenderer::drawText(VkCommandBuffer commandBuffer, int frameCount,
return;
}
if (textDebugCounter % 300 == 1 || needsRebuild) {
if (textDebugCounter % 300 == 1) {
std::cout << "Drawing text with " << vertices.size() << " vertices, "
<< indices.size() << " indices" << std::endl;
std::cout << "Window size: " << m_width << "x" << m_height << std::endl;
@ -2826,7 +2798,6 @@ void VulkanRenderer::drawText(VkCommandBuffer commandBuffer, int frameCount,
if (!createDynamicVertexBuffer(textVertexSize, m_textVertexBuffer, m_textVertexMemory)) {
logError("Failed to create dynamic text vertex buffer");
m_lastRenderedText.clear();
return;
}
if (!createDynamicIndexBuffer(textIndexSize, m_textIndexBuffer, m_textIndexMemory)) {
@ -2835,29 +2806,26 @@ void VulkanRenderer::drawText(VkCommandBuffer commandBuffer, int frameCount,
vkFreeMemory(m_device, m_textVertexMemory, nullptr);
m_textVertexBuffer = VK_NULL_HANDLE;
m_textVertexMemory = VK_NULL_HANDLE;
m_lastRenderedText.clear();
return;
}
std::cout << "Dynamic text buffers created (host-visible, no staging)" << std::endl;
}
// 直接更新 buffer 内容(通过内存映射,无需命令队列)
// 每帧直接更新 buffer 内容(通过内存映射,无需命令队列)
// 使用 host-visible buffers 后,更新成本极低,无需缓存
if (!vertices.empty() && !indices.empty()) {
if (!updateDynamicBuffer(m_textVertexMemory, vertices.data(),
sizeof(Vertex) * vertices.size())) {
logError("Failed to update text vertex buffer");
m_lastRenderedText.clear();
return;
}
if (!updateDynamicBuffer(m_textIndexMemory, indices.data(),
sizeof(uint16_t) * indices.size())) {
logError("Failed to update text index buffer");
m_lastRenderedText.clear();
return;
}
m_textIndexCount = indices.size();
m_lastRenderedText = currentText; // 缓存当前文本内容
}
// Draw text with newly created buffers

View File

@ -384,8 +384,7 @@ private:
VkSampler m_fontSampler;
std::map<char, CharInfo> m_charInfoMap;
// 文本缓存,避免每帧重建 text buffers
std::string m_lastRenderedText;
// 文本动态 buffershost-visible每帧直接映射更新
VkBuffer m_textVertexBuffer;
VkDeviceMemory m_textVertexMemory;
VkBuffer m_textIndexBuffer;