I know I’m making a mistake could please help me to spot it.
I’m trying to follow sascha willems I’m Gui Ui example. But I’m facing the problem :vkCmdDrawIndexed() index size (2) * (firstIndex (375) + indexCount (1117650944)) + binding offset (0) = an ending offset of 2235302638 bytes, which is greater than the index buffer size (5310).
I believe I’m not filling the indexBuffer properly.
void Interface::updateBuffers()
{
ImDrawData* imDrawData = ImGui::GetDrawData();
VkDeviceSize vertexBufferSize = imDrawData-> TotalVtxCount * sizeof(ImDrawVert);
VkDeviceSize indexBufferSize = imDrawData->TotalIdxCount * sizeof(ImDrawIdx);
if ((vertexBufferSize == 0) || (indexBufferSize == 0)) {
return;
}
if ((!initializedVert) || (vertexCount != imDrawData->TotalVtxCount)) {
if (vertmapped != nullptr) {
vkUnmapMemory(*device, interfaceObj.vertexBufferMemory);
vertmapped = nullptr;
vkDestroyBuffer(*device, interfaceObj.vertexBuffer, nullptr);
vkFreeMemory(*device, interfaceObj.vertexBufferMemory, nullptr);
}
initializedVert = true;
vertexCount = imDrawData->TotalVtxCount;
VkDeviceSize bufferSize = vertexBufferSize;
renderTools->tcreateBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, interfaceObj.vertexBuffer, interfaceObj.vertexBufferMemory);
vkMapMemory(*device, interfaceObj.vertexBufferMemory, 0, bufferSize, 0, &vertmapped);
}
if ((!initializedIndex) || (indexCount != imDrawData->TotalIdxCount)) {
if (indmapped != nullptr) {
vkUnmapMemory(*device, interfaceObj.indexBufferMemory);
indmapped = nullptr;
vkDestroyBuffer(*device, interfaceObj.indexBuffer, nullptr);
vkFreeMemory(*device, interfaceObj.indexBufferMemory, nullptr);
}
initializedIndex = true;
VkDeviceSize bufferSize = indexBufferSize;
//Buffer should have VK_BUFFER_USAGE_INDEX_BUFFER_BIT se
indexCount = imDrawData->TotalIdxCount;
renderTools->tcreateBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, interfaceObj.indexBuffer, interfaceObj.indexBufferMemory);
vkMapMemory(*device, interfaceObj.indexBufferMemory, 0, bufferSize, 0, &indmapped);
}
//upload data
ImDrawVert* vtxDst = (ImDrawVert*)vertmapped;
ImDrawIdx* idxDst = ( ImDrawIdx*)indmapped;
for (int n = 0; n < imDrawData->CmdListsCount; n++) {
const ImDrawList* cmd_list = imDrawData->CmdLists[n];
memcpy(vtxDst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idxDst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtxDst += cmd_list->VtxBuffer.Size;
idxDst += cmd_list->IdxBuffer.Size;
}
VkMappedMemoryRange mappedRange = {};
mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
mappedRange.memory = interfaceObj.vertexBufferMemory;
mappedRange.offset = 0;
mappedRange.size = VK_WHOLE_SIZE;
vkFlushMappedMemoryRanges(*device, 1, &mappedRange);
VkMappedMemoryRange mappedRange2 = {};
mappedRange2.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
mappedRange2.memory = interfaceObj.indexBufferMemory;
mappedRange2.offset = 0;
mappedRange2.size = VK_WHOLE_SIZE;
vkFlushMappedMemoryRanges(*device, 1, &mappedRange2);
}
void Interface::drawFrame(VkCommandBuffer commandBuffer)
{
ImGuiIO& io = ImGui::GetIO();
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, interfaceObj.pipelineLayout, 0, 1, &interfaceObj.descritproset, 0, nullptr);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, interfaceObj.pipeline);
// Bind vertex and index buffer
VkDeviceSize offsets[1] = { 0 };
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &interfaceObj.vertexBuffer, offsets);
vkCmdBindIndexBuffer(commandBuffer, interfaceObj.indexBuffer, 0, VK_INDEX_TYPE_UINT16);
VkViewport viewport = initializeVulkanStructure::viewport(ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y, 0.0f, 1.0f);
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
// UI scale and translate via push constants
pushConstBlock.scale = glm::vec2(2.0f / io.DisplaySize.x, 2.0f / io.DisplaySize.y);
pushConstBlock.translate = glm::vec2(-1.0f);
vkCmdPushConstants(commandBuffer, interfaceObj.pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(InterfacePushBlock), &pushConstBlock);
// Render commands
ImDrawData* imDrawData = ImGui::GetDrawData();
int32_t vertexOffset = 0;
int32_t indexOffset = 0;
for (int32_t i = 0; i < imDrawData->CmdListsCount; i++)
{
const ImDrawList* cmd_list = imDrawData->CmdLists[i];
for (int32_t j = 0; j < cmd_list->CmdBuffer.Size; j++)
if (imDrawData->CmdListsCount > 0) {
VkDeviceSize offsets[1] = { 0 };
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &interfaceObj.vertexBuffer, offsets);
vkCmdBindIndexBuffer(commandBuffer, interfaceObj.indexBuffer, 0, VK_INDEX_TYPE_UINT16);
for (int32_t i = 0; i < imDrawData->CmdListsCount; i++)
{
const ImDrawList* cmd_list = imDrawData->CmdLists[i];
for (int32_t j = 0; j < cmd_list->CmdBuffer.Size; j++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[j];
VkRect2D scissorRect;
scissorRect.offset.x = std::max((int32_t)(pcmd->ClipRect.x), 0);
scissorRect.offset.y = std::max((int32_t)(pcmd->ClipRect.y), 0);
scissorRect.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x);
scissorRect.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y);
vkCmdSetScissor(commandBuffer, 0, 1, &scissorRect);
vkCmdDrawIndexed(commandBuffer, pcmd->ElemCount, 1, indexOffset, vertexOffset, 0);
indexOffset += pcmd->ElemCount;
}
vertexOffset += cmd_list->VtxBuffer.Size;
}
}
}
}