mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-24 03:18:25 +02:00
RTI (ray tracing inspector) is a GUI for inspecting acceleration structures and ray tracing dispatches. There are some general classes for application lifetime, gpu resource managment and rendering. The visualization and BVH/node info needs to be implemented by driver/hardware specific backends (By overriding the virtual functions in rti_file_view). Reviewed-by: Natalie Vock <natalie.vock@gmx.de> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41806>
153 lines
5 KiB
C++
153 lines
5 KiB
C++
/*
|
|
* Copyright © 2026 Valve Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include <cstdint>
|
|
|
|
#include "rti_app.h"
|
|
#include "rti_file_view.h"
|
|
#include "rti_util.h"
|
|
|
|
#include "backends/imgui_impl_sdl3.h"
|
|
#include "vulkan/vulkan_core.h"
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
rti_app app = rti_app();
|
|
int ret = rti_app_init(&app);
|
|
if (ret)
|
|
return ret;
|
|
|
|
for (int i = 1; i < argc; i++)
|
|
app.open_files.push_back(rti_create_file_view(&app, argv[i]));
|
|
|
|
VkResult result;
|
|
bool needs_resize = true;
|
|
bool done = false;
|
|
while (!done) {
|
|
SDL_Event event;
|
|
|
|
while (SDL_PollEvent(&event)) {
|
|
ImGui_ImplSDL3_ProcessEvent(&event);
|
|
if (event.type == SDL_EVENT_QUIT)
|
|
done = true;
|
|
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(app.window))
|
|
done = true;
|
|
}
|
|
|
|
if (SDL_GetWindowFlags(app.window) & SDL_WINDOW_MINIMIZED) {
|
|
SDL_Delay(10);
|
|
continue;
|
|
}
|
|
|
|
int width, height;
|
|
SDL_GetWindowSize(app.window, &width, &height);
|
|
if (app.imgui_window.Width != width || app.imgui_window.Height != height)
|
|
needs_resize = true;
|
|
|
|
if (needs_resize) {
|
|
rti_app_resize(&app, width, height);
|
|
needs_resize = false;
|
|
continue;
|
|
}
|
|
|
|
VkSemaphore image_acquired_semaphore =
|
|
app.imgui_window.FrameSemaphores[app.imgui_window.SemaphoreIndex].ImageAcquiredSemaphore;
|
|
VkSemaphore render_complete_semaphore =
|
|
app.imgui_window.FrameSemaphores[app.imgui_window.SemaphoreIndex].RenderCompleteSemaphore;
|
|
result = vkAcquireNextImageKHR(app.device, app.imgui_window.Swapchain, UINT64_MAX, image_acquired_semaphore,
|
|
VK_NULL_HANDLE, &app.imgui_window.FrameIndex);
|
|
if (result != VK_SUCCESS) {
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
|
|
needs_resize = true;
|
|
continue;
|
|
}
|
|
rti_check_vk_result(result);
|
|
}
|
|
|
|
ImGui_ImplVulkanH_Frame *fd = &app.imgui_window.Frames[app.imgui_window.FrameIndex];
|
|
rti_check_vk_result(vkWaitForFences(app.device, 1, &fd->Fence, VK_TRUE, UINT64_MAX));
|
|
rti_check_vk_result(vkResetFences(app.device, 1, &fd->Fence));
|
|
|
|
rti_check_vk_result(vkResetCommandPool(app.device, fd->CommandPool, 0));
|
|
|
|
VkCommandBufferBeginInfo command_buffer_begin_info = {
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
|
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
|
};
|
|
rti_check_vk_result(vkBeginCommandBuffer(fd->CommandBuffer, &command_buffer_begin_info));
|
|
|
|
ImGui_ImplVulkan_NewFrame();
|
|
ImGui_ImplSDL3_NewFrame();
|
|
ImGui::NewFrame();
|
|
|
|
app.command_buffer = fd->CommandBuffer;
|
|
if (rti_app_run(&app))
|
|
break;
|
|
|
|
ImGui::Render();
|
|
|
|
ImDrawData *draw_data = ImGui::GetDrawData();
|
|
|
|
VkRenderPassBeginInfo render_pass_begin_info = {
|
|
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
|
.renderPass = app.imgui_window.RenderPass,
|
|
.framebuffer = fd->Framebuffer,
|
|
.renderArea =
|
|
{
|
|
.extent =
|
|
{
|
|
.width = (uint32_t)app.imgui_window.Width,
|
|
.height = (uint32_t)app.imgui_window.Height,
|
|
},
|
|
},
|
|
.clearValueCount = 1,
|
|
.pClearValues = &app.imgui_window.ClearValue,
|
|
};
|
|
vkCmdBeginRenderPass(fd->CommandBuffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer);
|
|
|
|
vkCmdEndRenderPass(fd->CommandBuffer);
|
|
|
|
rti_check_vk_result(vkEndCommandBuffer(fd->CommandBuffer));
|
|
|
|
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
VkSubmitInfo submit_info = {
|
|
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
|
.waitSemaphoreCount = 1,
|
|
.pWaitSemaphores = &image_acquired_semaphore,
|
|
.pWaitDstStageMask = &wait_stage,
|
|
.commandBufferCount = 1,
|
|
.pCommandBuffers = &fd->CommandBuffer,
|
|
.signalSemaphoreCount = 1,
|
|
.pSignalSemaphores = &render_complete_semaphore,
|
|
};
|
|
rti_check_vk_result(vkQueueSubmit(app.queue, 1, &submit_info, fd->Fence));
|
|
|
|
VkPresentInfoKHR present_info = {
|
|
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
|
.waitSemaphoreCount = 1,
|
|
.pWaitSemaphores = &render_complete_semaphore,
|
|
.swapchainCount = 1,
|
|
.pSwapchains = &app.imgui_window.Swapchain,
|
|
.pImageIndices = &app.imgui_window.FrameIndex,
|
|
};
|
|
result = vkQueuePresentKHR(app.queue, &present_info);
|
|
if (result != VK_SUCCESS) {
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
|
|
needs_resize = true;
|
|
continue;
|
|
}
|
|
rti_check_vk_result(result);
|
|
}
|
|
app.imgui_window.SemaphoreIndex = (app.imgui_window.SemaphoreIndex + 1) % app.imgui_window.SemaphoreCount;
|
|
}
|
|
|
|
rti_app_finish(&app);
|
|
|
|
return 0;
|
|
}
|