Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions test_apps/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,8 @@ target_link_libraries(sr_common PUBLIC
dwrite
)

# D3D11 atlas readback. Pulled into sr_common (not sr_common_base) so
# only D3D11-linking targets get it — the rest of the cube_handle apps
# add their respective atlas_capture_<api>.cpp directly.
target_sources(sr_common PRIVATE
atlas_capture_d3d11.cpp
)
# Atlas capture is runtime-owned now (XR_EXT_atlas_capture); the cube_handle
# apps call dxr_capture::RequestRuntimeAtlasCapture (in sr_common_base) instead
# of a per-API readback. The Windows-only D3D11/D3D12 readback TUs were deleted;
# atlas_capture_{gl,vk}.cpp + atlas_capture_metal.mm remain for the macOS apps,
# which haven't migrated yet.
37 changes: 37 additions & 0 deletions test_apps/common/atlas_capture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "stb_image_write.h"

#include "atlas_capture.h"
#include "xr_session_common.h" // XrSessionManager + XR_EXT_atlas_capture
#include "logging.h"

#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "ole32.lib")
Expand Down Expand Up @@ -159,4 +161,39 @@ void TickCaptureFlash(HWND parent) {
SetLayeredWindowAttributes(g_flashHwnd, 0, (BYTE)g_flashAlpha, LWA_ALPHA);
}

// ---------------------------------------------------------------------------
// Runtime-owned atlas capture (XR_EXT_atlas_capture) — the unified path.
// ---------------------------------------------------------------------------

bool RequestRuntimeAtlasCapture(const ::XrSessionManager& xr,
const char* appName,
uint32_t tileColumns,
uint32_t tileRows,
HWND flashHwnd) {
if (xr.pfnCaptureAtlasEXT == nullptr || xr.session == XR_NULL_HANDLE) {
LOG_WARN("Atlas capture unavailable: XR_EXT_atlas_capture not active");
return false;
}
// Captures the app's projection atlas; meaningless for a mono (1×1) layout.
if (tileColumns <= 1 && tileRows <= 1) {
LOG_INFO("Capture skipped: need 3D mode with cols/rows > 1");
return false;
}

std::string prefix = MakeCaptureAtlasPrefix(appName ? appName : "capture", tileColumns, tileRows);
XrAtlasCaptureInfoEXT info = {XR_TYPE_ATLAS_CAPTURE_INFO_EXT};
info.next = nullptr;
info.stage = XR_ATLAS_CAPTURE_STAGE_PROJECTION_ONLY_EXT;
strncpy_s(info.pathPrefix, prefix.c_str(), _TRUNCATE);

XrResult cr = xr.pfnCaptureAtlasEXT(xr.session, &info, nullptr);
if (XR_SUCCEEDED(cr)) {
LOG_INFO("Atlas capture requested -> %s_atlas.png", prefix.c_str());
PostFlashRequest(flashHwnd);
return true;
}
LOG_WARN("xrCaptureAtlasEXT failed: 0x%x", (unsigned)cr);
return false;
}

} // namespace dxr_capture
50 changes: 26 additions & 24 deletions test_apps/common/atlas_capture.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ typedef struct VkCommandPool_T* VkCommandPool;
typedef struct VkImage_T* VkImage;
#endif

// Forward-declared (global scope) so the runtime-capture helper below can take
// it without this header pulling in xr_session_common.h; atlas_capture.cpp
// includes that header for the full definition.
struct XrSessionManager;

namespace dxr_capture {

// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -130,6 +135,23 @@ void TickCaptureFlash(HWND parent);
inline void PostFlashRequest(HWND hwnd) {
PostMessageW(hwnd, kFlashUserMsg, 0, 0);
}

// ---------------------------------------------------------------------------
// Runtime-owned atlas capture (XR_EXT_atlas_capture). The single, graphics-
// API-agnostic capture path: the runtime does the GPU readback, so apps no
// longer need a per-API CaptureAtlasRegion* helper. Handles the 3D-mode guard,
// filename numbering (MakeCaptureAtlasPrefix), the xrCaptureAtlasEXT call
// (PROJECTION_ONLY = the app's own projection atlas), the flash overlay, and
// logging. Call from the render loop when the 'I' key flag is set.
//
// Returns true iff a capture was requested. No-ops (returns false) when the
// runtime didn't expose the extension (pfn NULL) or for mono/1×1 layouts.
// ---------------------------------------------------------------------------
bool RequestRuntimeAtlasCapture(const ::XrSessionManager& xr,
const char* appName,
uint32_t tileColumns,
uint32_t tileRows,
HWND flashHwnd);
#endif

#ifdef __APPLE__
Expand Down Expand Up @@ -171,30 +193,10 @@ bool CaptureAtlasRegionVk(VkDevice device,
const std::string& outPath,
bool linearBytesInSrgbImage = false);

#ifdef _WIN32
bool CaptureAtlasRegionD3D11(ID3D11Device* device,
ID3D11DeviceContext* context,
ID3D11Texture2D* srcTex,
uint32_t rectX,
uint32_t rectY,
uint32_t rectW,
uint32_t rectH,
const std::string& outPath);

bool CaptureAtlasRegionD3D12(ID3D12Device* device,
ID3D12CommandQueue* queue,
ID3D12Resource* srcTex,
uint32_t srcImageWidth,
uint32_t srcImageHeight,
// Resource state on entry; we transition back
// to it before returning (caller's lifecycle).
int /*D3D12_RESOURCE_STATES*/ entryState,
uint32_t rectX,
uint32_t rectY,
uint32_t rectW,
uint32_t rectH,
const std::string& outPath);
#endif
// NB: the D3D11/D3D12 per-API readback helpers were removed — those apps use
// the runtime-owned dxr_capture::RequestRuntimeAtlasCapture (XR_EXT_atlas_capture)
// above. The VK / GL / Metal readbacks below remain for the macOS apps, which
// have not migrated yet.

// OpenGL helper. Available on both Windows and macOS — the caller must have
// a current GL context bound. Loads its own FBO/blit function pointers
Expand Down
111 changes: 0 additions & 111 deletions test_apps/common/atlas_capture_d3d11.cpp

This file was deleted.

Loading
Loading