The short version
Doom (1993) runs under a real-time path tracer — every pixel traced: direct light, bounced light, reflections, soft shadows — at 90 FPS at 450p internal on an Intel Arc A770, upscaled to 1080p. It did not run at first: RayTracedGL1 is a Vulkan renderer written for Nvidia; porting it to Arc took two forks and about fifteen commits.
What “ray-traced Doom” really means
PrBoom+ is the game; RayTracedGL1 (RTGL1) is the Vulkan renderer; prboom-plus-rt by sultim-t intercepts Doom’s renderer and hands its walls, floors, ceilings, sprites and lights to RTGL1. RTGL1 uses path tracing with ReSTIR GI, A-SVGF denoising and DLSS/FSR upscaling, and was built for Nvidia RTX: ray tracing is a Vulkan extension (VK_KHR_ray_tracing_pipeline, VK_KHR_acceleration_structure), and support is far from uniform.
Why the Arc A770
The A770 is Intel’s flagship Arc: 32 Xe-cores, 32 ray-tracing units, 16 GB GDDR6, 225 W. Reviews put its ray-tracing throughput around the RTX 3060 tier, not the 3060 Ti — matching the 3060 at 1440p while trailing at 1080p (PCWorld, 2022) — and the 16 GB of VRAM is the clear win. A path tracer is maximally parallel and GPU-bound, which Arc handles well; the catch is a stack built around Nvidia’s extension behaviour.
Layer 1: Making it run under Hyprland
Under Hyprland (Wayland) the process deadlocks before drawing a frame: in prboom2/src/SDL/i_video.c the renderer presents once SDL reports the window shown, but the window is shown only after the first frame — and Wayland’s SDL reports no focus until then. The fix drops the focus requirement; the launcher forces SDL onto X11 because RTGL1 presents to an Xlib Vulkan surface:
// prboom2/src/SDL/i_video.c, after
if ((flags & SDL_WINDOW_SHOWN) && !(flags & SDL_WINDOW_MINIMIZED))
{
window_focused = true;
}
export SDL_VIDEODRIVER=x11 # XWayland; RTGL1 uses an Xlib surface
export LD_LIBRARY_PATH="$(pwd):${LD_LIBRARY_PATH}"
exec ./prboom-plus -iwad doom2.wad -iwadrt ovrd/map_metainfo_doom2.txt "$@"
Layer 2: Pitch-black maps and blurry textures
Doom 2 was completely black — geometry traced, lights absent. RTGL1 lights a scene from a separate metainfo file mapping sectors to light colours and weights; PrBoom+ RT ships map_metainfo_doom1.txt, but commercial Doom 2 ships no lighting data, and RT_GetSectorLightLevelWeight returns a light or nothing. rellik66’s doom2rt-0.9 addon supplies map_metainfo_doom2.txt plus emissive textures; alternatively a fallback in prboom2/src/RT/rt_geom.c lights every visible ceiling white when no metainfo exists, gated by RT_HasSectorLightingData() in rt_maps_metainfo.c (GetMapMetaInfo(gameepisode, gamemap) != NULL). A fallback, not a solution — deliberately slower (see performance).
The other problem was texture blur: linear minification with mipmaps is wrong for 1993 pixel art, so force nearest-neighbour — .textureSamplerForceMinificationFilterLinear = false in rt_main.c, DefaultDynamicSamplerFilter = RG_SAMPLER_FILTER_NEAREST in TextureManager.cpp, mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST in SamplerManager.cpp.
Layer 3: The Vulkan porting work
Nearly all of it lives in VulkanDevice.cpp. On Nvidia, RTGL1 could request features it never used and the driver granted them; on Arc, an unadvertised request fails device creation. And VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME was dropped because it was promoted into core Vulkan 1.2, which Arc does not re-advertise — requesting it fails, omitting it changes nothing.
// RTGL1 Source/VulkanDevice.cpp
features.shaderStorageImageMultisample = 0; // was 1
features.shaderFloat64 = 0;
vulkan12Features.shaderFloat16 = 0;
storage16.storageBuffer16BitAccess = 0;
The lesson generalises: a Vulkan porting bug is usually a request for something the target never needed. Build work too: GCC 16 needs explicit casts ((_GLUfuncptr), (const GLcharARB **)) for GLU’s gluTessCallback and OpenGL shader-source; robin_hood.h and vk_mem_alloc.h needed <cstdint>/<cstdio>; anisotropy was zeroed for world samplers.
The render-size change
A performance fix, not an Arc fix: RTGL1 mapped FSR quality levels to a resolution mode, so internal resolution tracked window size — 1080p fullscreen traced twice the pixels of a 1080p window. The patch fixes internal size by rt_renderscale times an explicit factor (1 = 0.77×, 2 = 0.67×, 3 = 0.59×, 4 = 0.50×) and upscales with nearest rather than FSR’s filter (RG_RENDER_UPSCALE_TECHNIQUE_NEAREST; RG_RENDER_UPSCALE_TECHNIQUE_NVIDIA_DLSS stays for DLSS). Windowed and fullscreen cost the same, nearest upscaling keeps pixels sharp, and rt_renderscale is clamped at or below the window height (at 1080p, renderscale 9/1440 becomes 8/1200).
Performance: the numbers
Measured on a clean Arc A770 rig, timedemo demo1, vsync off, single-bounce GI, nearest stretch: 600p (8 × 4) = 53.8 FPS, 450p (6 × 4) = 89.9 FPS, 360p (5 × 4) = 131.5 FPS. 90 FPS at 450p internal, upscaled to 1080p is the sweet spot (540p ≈ 65–70, 600p ≈ 54). Single runs — no frame-time trace, no percentiles — so a few percent is variation; the wide spans are real (450p vs 600p is 2.5× the pixels). Cost is dominated by resolution (internal, not window) and GI bounces (rt_bounce_quality 1 skips the second diffuse bounce for ~29%, my default). The five knobs: rt_renderscale, rt_fsr, rt_bounce_quality, render_vsync, -iwadrt <file>. Vsync is the trap: at render_vsync 1 the game locks to 60 Hz and hides headroom; with render_vsync 0 a 160p internal render runs at 638 FPS — proof the GPU is not the ceiling — but uncapping tears on a fixed 60 Hz panel. The CPU is not the problem: the single-threaded upload loop already sustains well over 90 FPS, and the GPU is already one ray per pixel.
What Arc gets right, and what it costs
Benefits: a genuine path tracer at a playable frame rate (90 FPS at 1080p output on a mid-range 2022 card); 16 GB of VRAM; and a small port — ten lines of device-feature edits plus three build fixes.
Costs: FSR is not really FSR here (a nearest-neighbour stretch — right for Doom, wrong for photorealism); no DLSS, ever; brittle Vulkan feature negotiation; vsync hides headroom, uncapping tears; the lighting-data dependency; X11 only.
Should you bother?
For most people, no — this is a research project, not a game recommendation. To play Doom today, use a stock source port (GZDoom, DSDA-Doom), the official remaster, or a modern RT shooter; for path-traced Doom specifically, an RTX card runs the same upstream code with DLSS and zero porting. The audience is someone with an Arc card, tolerance for building from source, and interest in why a port is hard.
Porting any RTGL1 app to Arc
The fixes are Doom’s; the method transfers. When an Nvidia-working renderer fails on Arc: did it fail at device creation? Then it is almost certainly a feature or extension request — check VkDeviceCreateInfo / VkPhysicalDeviceFeatures2. Does it use the feature it requests? Four here were never used (shaderStorageImageMultisample, shaderFloat64, shaderFloat16, storageBuffer16BitAccess). Is the missing extension core now? VK_KHR_shader_float16_int8 was promoted into 1.2 but not re-advertised. Re-test after each change — they all fail the same way. Then the surface, then the art. The set is three commits in RayTracedGL1 arc-a770-fixes.
The verdict
Doom under a real-time path tracer on an Arc A770 is 90 FPS, fully playable, genuinely good-looking, and the porting effort fits in two forks and a weekend. Most of the work was un-teaching an Nvidia-shaped approximation from a renderer that never needed it: unused features, a promoted extension, a focus check that assumed X11, an upscaler computing resolution from the wrong number — portability debts, not hardware limits. Run it: launcher, pinned state and build commands are in doom-rt, forks tagged working-20260908.
Reproducing this
Build lleqsnoom/RayTracedGL1 (arc-a770-fixes) first — it produces libRayTracedGL1.so — then lleqsnoom/prboom-plus-rt (doom2-rt-improvements) with RTGL1_SDK_PATH pointing at the renderer tree (-DRG_WITH_SURFACE_XLIB=ON, -DVulkan_INCLUDE_DIR=$HOME/Vulkan-Headers/include). Supply your own doom2.wad; drop the lighting addon into ovrd/; Vulkan headers newer than the distro’s go at ~/Vulkan-Headers.
Built on Intel Arc A770 16 GB, Ryzen 7 5800X, Arch Linux with Hyprland, mesa 25.x, on 2026-09-08. Benchmarks are timedemo demo1, vsync off, single run — ballpark, not gospel.
References
- RayTracedGL1 — Vulkan path tracer
- prboom-plus-rt — Doom source port with RT handoff
- Intel Arc A770 specifications — 32 Xe-cores, 16 GB GDDR6
- Vulkan
VK_KHR_shader_float16_int8— promoted to Vulkan 1.2 core - doom2rt-0.9 by rellik66 — Doom 2 lighting addon
- doom-rt — launcher and build instructions
- PCWorld: RTX 3060 vs. Arc A770 — RT tier comparison