Slightly refactor ImGui rendering.

This commit is contained in:
Skyth 2024-12-11 17:35:45 +03:00
parent 1282c1384e
commit bbe869c25f

View file

@ -1895,6 +1895,25 @@ static void ProcDrawImGui(const RenderCommand& cmd)
pushConstants.inverseDisplaySize = { 1.0f / drawData.DisplaySize.x, 1.0f / drawData.DisplaySize.y }; pushConstants.inverseDisplaySize = { 1.0f / drawData.DisplaySize.x, 1.0f / drawData.DisplaySize.y };
commandList->setGraphicsPushConstants(0, &pushConstants); commandList->setGraphicsPushConstants(0, &pushConstants);
size_t pushConstantRangeMin = ~0;
size_t pushConstantRangeMax = 0;
auto setPushConstants = [&](void* destination, const void* source, size_t size)
{
bool dirty = memcmp(destination, source, size) != 0;
memcpy(destination, source, size);
if (dirty)
{
size_t offset = reinterpret_cast<size_t>(destination) - reinterpret_cast<size_t>(&pushConstants);
pushConstantRangeMin = std::min(pushConstantRangeMin, offset);
pushConstantRangeMax = std::max(pushConstantRangeMax, offset + size);
}
};
ImRect clipRect{};
for (int i = 0; i < drawData.CmdListsCount; i++) for (int i = 0; i < drawData.CmdListsCount; i++)
{ {
auto& drawList = drawData.CmdLists[i]; auto& drawList = drawData.CmdLists[i];
@ -1919,19 +1938,22 @@ static void ProcDrawImGui(const RenderCommand& cmd)
switch (static_cast<ImGuiCallback>(reinterpret_cast<size_t>(drawCmd.UserCallback))) switch (static_cast<ImGuiCallback>(reinterpret_cast<size_t>(drawCmd.UserCallback)))
{ {
case ImGuiCallback::SetGradient: case ImGuiCallback::SetGradient:
commandList->setGraphicsPushConstants(0, &callbackData->setGradient, offsetof(ImGuiPushConstants, boundsMin), sizeof(callbackData->setGradient)); setPushConstants(&pushConstants.boundsMin, &callbackData->setGradient, sizeof(callbackData->setGradient));
break; break;
case ImGuiCallback::SetShaderModifier: case ImGuiCallback::SetShaderModifier:
commandList->setGraphicsPushConstants(0, &callbackData->setShaderModifier, offsetof(ImGuiPushConstants, shaderModifier), sizeof(callbackData->setShaderModifier)); setPushConstants(&pushConstants.shaderModifier, &callbackData->setShaderModifier, sizeof(callbackData->setShaderModifier));
break; break;
case ImGuiCallback::SetOrigin: case ImGuiCallback::SetOrigin:
commandList->setGraphicsPushConstants(0, &callbackData->setOrigin, offsetof(ImGuiPushConstants, origin), sizeof(callbackData->setOrigin)); setPushConstants(&pushConstants.origin, &callbackData->setOrigin, sizeof(callbackData->setOrigin));
break; break;
case ImGuiCallback::SetScale: case ImGuiCallback::SetScale:
commandList->setGraphicsPushConstants(0, &callbackData->setScale, offsetof(ImGuiPushConstants, scale), sizeof(callbackData->setScale)); setPushConstants(&pushConstants.scale, &callbackData->setScale, sizeof(callbackData->setScale));
break; break;
case ImGuiCallback::SetMarqueeFade: case ImGuiCallback::SetMarqueeFade:
commandList->setGraphicsPushConstants(0, &callbackData->setScale, offsetof(ImGuiPushConstants, boundsMin), sizeof(callbackData->setMarqueeFade)); setPushConstants(&pushConstants.boundsMin, &callbackData->setMarqueeFade, sizeof(callbackData->setMarqueeFade));
break;
default:
assert(false && "Unknown ImGui callback type.");
break; break;
} }
} }
@ -1956,10 +1978,23 @@ static void ProcDrawImGui(const RenderCommand& cmd)
if (texture == g_imFontTexture.get()) if (texture == g_imFontTexture.get())
descriptorIndex |= 0x80000000; descriptorIndex |= 0x80000000;
setPushConstants(&pushConstants.texture2DDescriptorIndex, &descriptorIndex, sizeof(descriptorIndex));
}
if (pushConstantRangeMin < pushConstantRangeMax)
{
commandList->setGraphicsPushConstants(0, reinterpret_cast<const uint8_t*>(&pushConstants) + pushConstantRangeMin, pushConstantRangeMin, pushConstantRangeMax - pushConstantRangeMin);
pushConstantRangeMin = ~0;
pushConstantRangeMax = 0;
}
if (memcmp(&clipRect, &drawCmd.ClipRect, sizeof(clipRect)) != 0)
{
commandList->setScissors(RenderRect(int32_t(drawCmd.ClipRect.x), int32_t(drawCmd.ClipRect.y), int32_t(drawCmd.ClipRect.z), int32_t(drawCmd.ClipRect.w)));
clipRect = drawCmd.ClipRect;
} }
commandList->setGraphicsPushConstants(0, &descriptorIndex, offsetof(ImGuiPushConstants, texture2DDescriptorIndex), sizeof(descriptorIndex));
commandList->setScissors(RenderRect(int32_t(drawCmd.ClipRect.x), int32_t(drawCmd.ClipRect.y), int32_t(drawCmd.ClipRect.z), int32_t(drawCmd.ClipRect.w)));
commandList->drawIndexedInstanced(drawCmd.ElemCount, 1, drawCmd.IdxOffset, drawCmd.VtxOffset, 0); commandList->drawIndexedInstanced(drawCmd.ElemCount, 1, drawCmd.IdxOffset, drawCmd.VtxOffset, 0);
} }
} }