From cc205d326a69cf38e0d0cb997699fb778cf66552 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Wed, 30 Sep 2026 05:35:52 +0200 Subject: [PATCH] Expose CopySrc for snapshot textures & expose raw texture objects (#2643) Fixes https://github.com/TwilitRealm/dusklight/issues/2639 Requires https://github.com/encounter/aurora/pull/260 to be merged first. --- sdk/include/mods/svc/gfx.h | 8 ++++++-- src/dusk/mods/svc/gfx.cpp | 28 ++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/sdk/include/mods/svc/gfx.h b/sdk/include/mods/svc/gfx.h index b95f7ec712..ebfde28f6b 100644 --- a/sdk/include/mods/svc/gfx.h +++ b/sdk/include/mods/svc/gfx.h @@ -33,7 +33,7 @@ #define GFX_SERVICE_ID DUSKLIGHT_SERVICE_ID_PREFIX "gfx" #define GFX_SERVICE_MAJOR 1u -#define GFX_SERVICE_MINOR 3u +#define GFX_SERVICE_MINOR 4u /* Maximum size for push_draw payload */ #define GFX_INLINE_DRAW_PAYLOAD_SIZE 128u @@ -212,10 +212,14 @@ typedef struct GfxResolvedTargets { uint32_t height; /* Minor version 3 */ WGPUTextureView normal; /* view-space normal snapshot, RGB10A2Unorm when available */ + /* Minor version 4 */ + WGPUTexture colorTexture; + WGPUTexture depthTexture; + WGPUTexture normalTexture; } GfxResolvedTargets; #define GFX_RESOLVED_TARGETS_INIT \ - {sizeof(GfxResolvedTargets), NULL, NULL, WGPUTextureFormat_Undefined, 0u, 0u, NULL} + {sizeof(GfxResolvedTargets), NULL, NULL, WGPUTextureFormat_Undefined, 0u, 0u, NULL, NULL, NULL, NULL} /* * Passed to GfxComputeFn on the render worker thread; valid only during the call. The encoder is diff --git a/src/dusk/mods/svc/gfx.cpp b/src/dusk/mods/svc/gfx.cpp index 1f84a255b3..28dc791991 100644 --- a/src/dusk/mods/svc/gfx.cpp +++ b/src/dusk/mods/svc/gfx.cpp @@ -696,6 +696,10 @@ ModResult gfx_resolve_pass(LoadedMod& mod, const GfxResolveDesc& desc, GfxResolv out.width = resolved.width; out.height = resolved.height; out.normal = resolved.normal.Get(); + + out.colorTexture = resolved.colorTexture.Get(); + out.depthTexture = resolved.depthTexture.Get(); + out.normalTexture = resolved.normalTexture.Get(); return MOD_OK; } @@ -1336,31 +1340,39 @@ ModResult gfx_resolve_pass_impl( ModContext* context, const GfxResolveDesc* desc, GfxResolvedTargets* outTargets) { OH_FUCK_SYNC - constexpr size_t legacyDescSize = offsetof(GfxResolveDesc, normal); - constexpr size_t legacyTargetsSize = offsetof(GfxResolvedTargets, normal); + constexpr size_t v0DescSize = offsetof(GfxResolveDesc, normal); + constexpr size_t v3DescSize = sizeof(GfxResolveDesc); + constexpr size_t v0TargetsSize = offsetof(GfxResolvedTargets, normal); + constexpr size_t v3TargetsSize = offsetof(GfxResolvedTargets, colorTexture); + constexpr size_t v4TargetsSize = sizeof(GfxResolvedTargets); const size_t outputSize = outTargets != nullptr ? std::min(outTargets->struct_size, sizeof(GfxResolvedTargets)) : 0; + GfxResolvedTargets resolved = GFX_RESOLVED_TARGETS_INIT; - if (outputSize >= legacyTargetsSize) { - resolved.struct_size = static_cast(outputSize); + if (outputSize == v0TargetsSize || outputSize == v3TargetsSize || outputSize >= v4TargetsSize) { + resolved.struct_size = outputSize; std::memcpy(outTargets, &resolved, outputSize); + } else { + return MOD_INVALID_ARGUMENT; } + auto* mod = mod_from_context(context); - if (mod == nullptr || desc == nullptr || desc->struct_size < legacyDescSize || - outputSize < legacyTargetsSize) + if (mod == nullptr || desc == nullptr || desc->struct_size < v0DescSize) { return MOD_INVALID_ARGUMENT; } + GfxResolveDesc request = GFX_RESOLVE_DESC_INIT; request.color = desc->color; request.depth = desc->depth; - request.normal = desc->struct_size >= sizeof(GfxResolveDesc) ? desc->normal : 0; + request.normal = desc->struct_size >= v3DescSize ? desc->normal : 0; if ((!request.color && !request.depth && !request.normal) || - (request.normal && outputSize < sizeof(GfxResolvedTargets))) + (request.normal && outputSize < v3TargetsSize)) { return MOD_INVALID_ARGUMENT; } + const auto result = gfx_resolve_pass(*mod, request, resolved); resolved.struct_size = static_cast(outputSize); std::memcpy(outTargets, &resolved, outputSize);