#ifdef WITH_RIVE_SCRIPTING
#if defined(RIVE_CANVAS) && defined(RIVE_ORE)
#include "lualib.h"
#include "rive/lua/rive_lua_libs.hpp"
#include "rive/renderer/ore/ore_binding_map.hpp"
#include "rive/renderer/ore/ore_context.hpp"
#include "rive/renderer/ore/ore_rstb_entry_container.hpp"
#include "rive/renderer/ore/ore_render_pass.hpp"
#include "rive/renderer/ore/cmd/ore_deferred_render_pass.hpp"
#include "rive/renderer/ore/ore_shader_module.hpp"
#include "rive/renderer/cmd/deferred_canvas_host.hpp"
#include "rive/renderer/cmd/deferred_render_resource.hpp"
#include "rive/renderer/render_canvas.hpp"
#include "rive/renderer/render_context.hpp"
#include "rive/renderer/render_context_impl.hpp"
#include "rive/renderer/rive_renderer.hpp"
#include "rive/assets/shader_asset.hpp"
#include "rive/assets/script_asset.hpp"
#include "rive/file.hpp"
#include "rive/scripted/scripted_object.hpp"
#include "rive/shapes/paint/color.hpp"

#include <algorithm>
#include <cassert>
#include <cstring>
#include <stdio.h>
#include <string>
#include <unordered_map>
#include <vector>

using namespace rive;
using namespace rive::ore;

// ============================================================================
// String-to-enum helpers
// ============================================================================

static BufferUsage bufferUsageFromString(lua_State* L, const char* s)
{
    if (strcmp(s, "vertex") == 0)
        return BufferUsage::vertex;
    if (strcmp(s, "index") == 0)
        return BufferUsage::index;
    if (strcmp(s, "uniform") == 0)
        return BufferUsage::uniform;
    luaL_error(L,
               "invalid BufferUsage '%s' (expected 'vertex', 'index', or "
               "'uniform')",
               s);
    return BufferUsage::vertex;
}

// Read a `usage` that is either a single string or an array of strings. The
// type is the dual shape BufferUsage | {BufferUsage} so the array form is
// forward-compatible with future multi-usage flags. Today a buffer has one
// usage, so a multi-element array is rejected rather than silently collapsed.
static BufferUsage lua_tobufferusagefield(lua_State* L, int idx)
{
    lua_getfield(L, idx, "usage");
    BufferUsage usage = BufferUsage::vertex;
    if (lua_isstring(L, -1))
    {
        usage = bufferUsageFromString(L, lua_tostring(L, -1));
    }
    else if (lua_istable(L, -1))
    {
        int n = lua_objlen(L, -1);
        if (n != 1)
        {
            luaL_error(L,
                       "GPUBuffer.new: usage array must hold exactly one "
                       "value; multiple usages are not yet supported");
        }
        lua_rawgeti(L, -1, 1);
        if (!lua_isstring(L, -1))
            luaL_error(L, "GPUBuffer.new: usage array must hold strings");
        usage = bufferUsageFromString(L, lua_tostring(L, -1));
        lua_pop(L, 1);
    }
    else
    {
        luaL_error(L,
                   "GPUBuffer.new: 'usage' is required (a string or array of "
                   "strings)");
    }
    lua_pop(L, 1);
    return usage;
}

static TextureFormat lua_totextureformat(lua_State* L, const char* s)
{
    if (strcmp(s, "r8unorm") == 0)
        return TextureFormat::r8unorm;
    if (strcmp(s, "rg8unorm") == 0)
        return TextureFormat::rg8unorm;
    if (strcmp(s, "rgba8unorm") == 0)
        return TextureFormat::rgba8unorm;
    if (strcmp(s, "bgra8unorm") == 0)
        return TextureFormat::bgra8unorm;
    if (strcmp(s, "rgba16float") == 0)
        return TextureFormat::rgba16float;
    if (strcmp(s, "rg16float") == 0)
        return TextureFormat::rg16float;
    if (strcmp(s, "r16float") == 0)
        return TextureFormat::r16float;
    if (strcmp(s, "rgba32float") == 0)
        return TextureFormat::rgba32float;
    if (strcmp(s, "rgb10a2unorm") == 0)
        return TextureFormat::rgb10a2unorm;
    if (strcmp(s, "rg11b10ufloat") == 0)
        return TextureFormat::r11g11b10float;
    if (strcmp(s, "depth16unorm") == 0)
        return TextureFormat::depth16unorm;
    if (strcmp(s, "depth24plus-stencil8") == 0)
        return TextureFormat::depth24plusStencil8;
    if (strcmp(s, "depth32float") == 0)
        return TextureFormat::depth32float;
    if (strcmp(s, "depth32float-stencil8") == 0)
        return TextureFormat::depth32floatStencil8;
    if (strcmp(s, "bc1-rgba-unorm") == 0)
        return TextureFormat::bc1unorm;
    if (strcmp(s, "bc3-rgba-unorm") == 0)
        return TextureFormat::bc3unorm;
    if (strcmp(s, "bc7-rgba-unorm") == 0)
        return TextureFormat::bc7unorm;
    if (strcmp(s, "etc2-rgb8unorm") == 0)
        return TextureFormat::etc2rgb8;
    if (strcmp(s, "etc2-rgba8unorm") == 0)
        return TextureFormat::etc2rgba8;
    if (strcmp(s, "astc-4x4-unorm") == 0)
        return TextureFormat::astc4x4;
    if (strcmp(s, "astc-6x6-unorm") == 0)
        return TextureFormat::astc6x6;
    if (strcmp(s, "astc-8x8-unorm") == 0)
        return TextureFormat::astc8x8;
    luaL_error(L, "invalid TextureFormat: %s", s);
    return TextureFormat::rgba8unorm;
}

static const char* lua_totextureformatstring(TextureFormat fmt)
{
    switch (fmt)
    {
        case TextureFormat::r8unorm:
            return "r8unorm";
        case TextureFormat::rg8unorm:
            return "rg8unorm";
        case TextureFormat::rgba8unorm:
            return "rgba8unorm";
        case TextureFormat::bgra8unorm:
            return "bgra8unorm";
        case TextureFormat::rgba16float:
            return "rgba16float";
        case TextureFormat::rg16float:
            return "rg16float";
        case TextureFormat::r16float:
            return "r16float";
        case TextureFormat::rgba32float:
            return "rgba32float";
        case TextureFormat::rg32float:
            return "rg32float";
        case TextureFormat::r32float:
            return "r32float";
        case TextureFormat::rgb10a2unorm:
            return "rgb10a2unorm";
        case TextureFormat::r11g11b10float:
            return "rg11b10ufloat";
        case TextureFormat::depth16unorm:
            return "depth16unorm";
        case TextureFormat::depth24plusStencil8:
            return "depth24plus-stencil8";
        case TextureFormat::depth32float:
            return "depth32float";
        case TextureFormat::depth32floatStencil8:
            return "depth32float-stencil8";
        default:
            return "rgba8unorm";
    }
}

// Float color render-target capability a format needs, or none if it is not a
// float format. 16-bit floats need colorBufferHalfFloat; 32-bit and packed
// floats need the full colorBufferFloat.
enum class FloatColorClass
{
    none,
    half,
    full,
};

static FloatColorClass floatColorClass(TextureFormat fmt)
{
    switch (fmt)
    {
        case TextureFormat::rgba16float:
        case TextureFormat::rg16float:
        case TextureFormat::r16float:
            return FloatColorClass::half;
        case TextureFormat::rgba32float:
        case TextureFormat::rg32float:
        case TextureFormat::r32float:
        case TextureFormat::r11g11b10float:
            return FloatColorClass::full;
        default:
            return FloatColorClass::none;
    }
}

static TextureType lua_totexturetype(lua_State* L, const char* s)
{
    if (strcmp(s, "2d") == 0)
        return TextureType::texture2D;
    if (strcmp(s, "cube") == 0)
        return TextureType::cube;
    if (strcmp(s, "3d") == 0)
        return TextureType::texture3D;
    if (strcmp(s, "2d-array") == 0)
        return TextureType::array2D;
    luaL_error(L, "invalid TextureType: %s", s);
    return TextureType::texture2D;
}

static CompareFunction lua_tocompare(lua_State* L, const char* s)
{
    if (strcmp(s, "never") == 0)
        return CompareFunction::never;
    if (strcmp(s, "less") == 0)
        return CompareFunction::less;
    if (strcmp(s, "equal") == 0)
        return CompareFunction::equal;
    if (strcmp(s, "less-equal") == 0)
        return CompareFunction::lessEqual;
    if (strcmp(s, "greater") == 0)
        return CompareFunction::greater;
    if (strcmp(s, "not-equal") == 0)
        return CompareFunction::notEqual;
    if (strcmp(s, "greater-equal") == 0)
        return CompareFunction::greaterEqual;
    if (strcmp(s, "always") == 0)
        return CompareFunction::always;
    luaL_error(L, "invalid CompareFunction: %s", s);
    return CompareFunction::none;
}

static Filter lua_tofilter(lua_State* L, const char* s)
{
    if (strcmp(s, "nearest") == 0)
        return Filter::nearest;
    if (strcmp(s, "linear") == 0)
        return Filter::linear;
    luaL_error(L, "invalid Filter: %s", s);
    return Filter::nearest;
}

static WrapMode lua_towrapmode(lua_State* L, const char* s)
{
    if (strcmp(s, "repeat") == 0)
        return WrapMode::repeat;
    if (strcmp(s, "mirror-repeat") == 0)
        return WrapMode::mirrorRepeat;
    if (strcmp(s, "clamp-to-edge") == 0)
        return WrapMode::clampToEdge;
    luaL_error(L, "invalid WrapMode: %s", s);
    return WrapMode::clampToEdge;
}

static VertexFormat lua_tovertexformat(lua_State* L, const char* s)
{
    if (strcmp(s, "float32") == 0)
        return VertexFormat::float1;
    if (strcmp(s, "float32x2") == 0)
        return VertexFormat::float2;
    if (strcmp(s, "float32x3") == 0)
        return VertexFormat::float3;
    if (strcmp(s, "float32x4") == 0)
        return VertexFormat::float4;
    if (strcmp(s, "uint8x4") == 0)
        return VertexFormat::uint8x4;
    if (strcmp(s, "unorm8x4") == 0)
        return VertexFormat::unorm8x4;
    if (strcmp(s, "snorm8x4") == 0)
        return VertexFormat::snorm8x4;
    if (strcmp(s, "float16x2") == 0)
        return VertexFormat::float16x2;
    if (strcmp(s, "float16x4") == 0)
        return VertexFormat::float16x4;
    luaL_error(L, "invalid VertexFormat: %s", s);
    return VertexFormat::float4;
}

static CullMode lua_tocullmode(lua_State* L, const char* s)
{
    if (strcmp(s, "none") == 0)
        return CullMode::none;
    if (strcmp(s, "front") == 0)
        return CullMode::front;
    if (strcmp(s, "back") == 0)
        return CullMode::back;
    luaL_error(L, "invalid CullMode: %s", s);
    return CullMode::none;
}

static PrimitiveTopology lua_totopology(lua_State* L, const char* s)
{
    if (strcmp(s, "triangle-list") == 0)
        return PrimitiveTopology::triangleList;
    if (strcmp(s, "triangle-strip") == 0)
        return PrimitiveTopology::triangleStrip;
    if (strcmp(s, "line-list") == 0)
        return PrimitiveTopology::lineList;
    if (strcmp(s, "line-strip") == 0)
        return PrimitiveTopology::lineStrip;
    if (strcmp(s, "point-list") == 0)
        return PrimitiveTopology::pointList;
    luaL_error(L, "invalid PrimitiveTopology: %s", s);
    return PrimitiveTopology::triangleList;
}

static BlendFactor lua_toblendfactor(lua_State* L, const char* s)
{
    if (strcmp(s, "zero") == 0)
        return BlendFactor::zero;
    if (strcmp(s, "one") == 0)
        return BlendFactor::one;
    if (strcmp(s, "src") == 0)
        return BlendFactor::srcColor;
    if (strcmp(s, "one-minus-src") == 0)
        return BlendFactor::oneMinusSrcColor;
    if (strcmp(s, "src-alpha") == 0)
        return BlendFactor::srcAlpha;
    if (strcmp(s, "one-minus-src-alpha") == 0)
        return BlendFactor::oneMinusSrcAlpha;
    if (strcmp(s, "dst") == 0)
        return BlendFactor::dstColor;
    if (strcmp(s, "one-minus-dst") == 0)
        return BlendFactor::oneMinusDstColor;
    if (strcmp(s, "dst-alpha") == 0)
        return BlendFactor::dstAlpha;
    if (strcmp(s, "one-minus-dst-alpha") == 0)
        return BlendFactor::oneMinusDstAlpha;
    if (strcmp(s, "src-alpha-saturated") == 0)
        return BlendFactor::srcAlphaSaturated;
    if (strcmp(s, "constant") == 0)
        return BlendFactor::blendColor;
    if (strcmp(s, "one-minus-constant") == 0)
        return BlendFactor::oneMinusBlendColor;
    luaL_error(L, "invalid BlendFactor: %s", s);
    return BlendFactor::one;
}

static BlendOp lua_toblendop(lua_State* L, const char* s)
{
    if (strcmp(s, "add") == 0)
        return BlendOp::add;
    if (strcmp(s, "subtract") == 0)
        return BlendOp::subtract;
    if (strcmp(s, "reverse-subtract") == 0)
        return BlendOp::reverseSubtract;
    if (strcmp(s, "min") == 0)
        return BlendOp::min;
    if (strcmp(s, "max") == 0)
        return BlendOp::max;
    luaL_error(L, "invalid BlendOp: %s", s);
    return BlendOp::add;
}

static FaceWinding lua_towinding(lua_State* L, const char* s)
{
    if (strcmp(s, "cw") == 0)
        return FaceWinding::clockwise;
    if (strcmp(s, "ccw") == 0)
        return FaceWinding::counterClockwise;
    luaL_error(L, "invalid FaceWinding: %s", s);
    return FaceWinding::counterClockwise;
}

static StencilOp lua_tostencilop(lua_State* L, const char* s)
{
    if (strcmp(s, "keep") == 0)
        return StencilOp::keep;
    if (strcmp(s, "zero") == 0)
        return StencilOp::zero;
    if (strcmp(s, "replace") == 0)
        return StencilOp::replace;
    if (strcmp(s, "increment-clamp") == 0)
        return StencilOp::incrementClamp;
    if (strcmp(s, "decrement-clamp") == 0)
        return StencilOp::decrementClamp;
    if (strcmp(s, "invert") == 0)
        return StencilOp::invert;
    if (strcmp(s, "increment-wrap") == 0)
        return StencilOp::incrementWrap;
    if (strcmp(s, "decrement-wrap") == 0)
        return StencilOp::decrementWrap;
    luaL_error(L, "invalid StencilOp: %s", s);
    return StencilOp::keep;
}

// Parse a color writemask string. Each of "r"/"g"/"b"/"a" present in the
// string enables that channel. Recognized special values: "" or "none"
// disables all; "all" / "rgba" enables all (also the default if the
// field is absent). Order doesn't matter.
static ColorWriteMask lua_towritemask(lua_State* L, const char* s)
{
    if (s == nullptr || strcmp(s, "all") == 0 || strcmp(s, "rgba") == 0)
        return ColorWriteMask::all;
    if (s[0] == '\0' || strcmp(s, "none") == 0)
        return ColorWriteMask::none;
    ColorWriteMask out = ColorWriteMask::none;
    for (const char* p = s; *p; ++p)
    {
        switch (*p)
        {
            case 'r':
            case 'R':
                out = out | ColorWriteMask::red;
                break;
            case 'g':
            case 'G':
                out = out | ColorWriteMask::green;
                break;
            case 'b':
            case 'B':
                out = out | ColorWriteMask::blue;
                break;
            case 'a':
            case 'A':
                out = out | ColorWriteMask::alpha;
                break;
            default:
                luaL_error(L,
                           "invalid ColorWriteMask: '%s' "
                           "(expected r/g/b/a chars or 'all'/'none')",
                           s);
        }
    }
    return out;
}

// Helper to get a string field from a table at idx, returns nullptr if
// the field doesn't exist.
static const char* lua_getoptionalstringfield(lua_State* L,
                                              int idx,
                                              const char* field)
{
    lua_getfield(L, idx, field);
    const char* s = lua_isstring(L, -1) ? lua_tostring(L, -1) : nullptr;
    lua_pop(L, 1);
    return s;
}

// Parse a stencil-face state table:
//   { compare="...", failOp="...", depthFailOp="...", passOp="..." }
// Defined after `lua_getoptionalstringfield` because it uses that helper —
// Android NDK clang's `-Werror` rejects forward use of a `static` function
// that hasn't been declared yet.
static void lua_tostencilface(lua_State* L, int idx, StencilFaceState* face)
{
    if (!lua_istable(L, idx))
        return;
    const char* s = lua_getoptionalstringfield(L, idx, "compare");
    if (s)
        face->compare = lua_tocompare(L, s);
    s = lua_getoptionalstringfield(L, idx, "failOp");
    if (s)
        face->failOp = lua_tostencilop(L, s);
    s = lua_getoptionalstringfield(L, idx, "depthFailOp");
    if (s)
        face->depthFailOp = lua_tostencilop(L, s);
    s = lua_getoptionalstringfield(L, idx, "passOp");
    if (s)
        face->passOp = lua_tostencilop(L, s);
}

static double lua_getoptionalnumberfield(lua_State* L,
                                         int idx,
                                         const char* field,
                                         double def)
{
    lua_getfield(L, idx, field);
    double v = lua_isnumber(L, -1) ? lua_tonumber(L, -1) : def;
    lua_pop(L, 1);
    return v;
}

static bool lua_getoptionalboolfield(lua_State* L,
                                     int idx,
                                     const char* field,
                                     bool def)
{
    lua_getfield(L, idx, field);
    bool v = lua_isboolean(L, -1) ? lua_toboolean(L, -1) : def;
    lua_pop(L, 1);
    return v;
}

// ============================================================================
// Debug tracing
// ============================================================================

// ============================================================================
// Shader (ore::ShaderModule)
// ============================================================================

// Retrieves the ore GPU context for the current VM from its ScriptingContext.
static Context* getOreContext(lua_State* L)
{
    return static_cast<Context*>(
        static_cast<ScriptingContext*>(lua_getthreaddata(L))->oreContext());
}

/// Whether a capability gate below can be decided at all. A recording context
/// with no replay device attached yet holds Features' own initializers, which
/// deny nearly everything; gating on those would reject an operation the
/// replay device very likely supports. These gates are diagnostics — the real
/// backend is the authority — so an undecidable one lets the call through
/// rather than inventing a refusal, which is the same fiction as inventing a
/// capability, only in the direction that breaks working content.
static bool features_are_known(Context* oreCtx)
{
    return oreCtx != nullptr && oreCtx->featuresKnown();
}

/// RSTB ShaderTarget the active ore backend consumes.
static ShaderTarget currentShaderTarget(Context* oreCtx)
{
    return oreCtx != nullptr ? oreCtx->shaderTarget() : ShaderTarget::glsl;
}

/// Build a ScriptedShader's entry list from a decoded ShaderAsset for the
/// active backend target. Parses the RSTB v4 entry-point container
/// (ore_rstb_entry_container.hpp): whole-module targets (WGSL/MSL/SPIR-V) share
/// one ShaderModule across all entries; per-entry targets (GLSL/HLSL) build one
/// module per entry. Returns true if at least one entry/module was created.
static bool buildShaderEntries(Context* oreCtx,
                               const ShaderAsset& asset,
                               ScriptedShader* out)
{
    if (oreCtx == nullptr || out == nullptr)
        return false;

    // Start from a clean slate: a ScriptedShader may be reloaded (editor live
    // preview) and stale entry records would corrupt entry-point resolution.
    out->entries.clear();

    ShaderTarget target = currentShaderTarget(oreCtx);
    auto blob = asset.findShader(static_cast<uint8_t>(target));
    if (blob.empty())
        return false;
    const uint8_t* blobData = blob.data();
    uint32_t blobSize = static_cast<uint32_t>(blob.size());
    const uint32_t assetId = asset.assetId();

    // Binding-map sidecar (mandatory for module creation) + GL fixup sidecars
    // (GLSL only). Every shipped shader carries a sidecar per source variant.
    auto bindingMapTargetFor = [](ShaderTarget t) -> uint8_t {
        switch (t)
        {
            case ShaderTarget::wgsl:
                return 16;
            case ShaderTarget::glsl:
                return 11;
            case ShaderTarget::msl:
                return 10;
            case ShaderTarget::hlsl:
                return 12;
            case ShaderTarget::spirv:
                return 13;
        }
        return 255;
    };
    uint8_t bmTarget = bindingMapTargetFor(target);
    auto bindingMapBlob =
        (bmTarget == 255) ? Span<const uint8_t>{} : asset.findShader(bmTarget);
    const uint8_t* bindingMapBytes =
        bindingMapBlob.empty() ? nullptr : bindingMapBlob.data();
    uint32_t bindingMapSize = static_cast<uint32_t>(bindingMapBlob.size());
    auto vsGLFixupBlob = (target == ShaderTarget::glsl) ? asset.findShader(14)
                                                        : Span<const uint8_t>{};
    auto fsGLFixupBlob = (target == ShaderTarget::glsl) ? asset.findShader(15)
                                                        : Span<const uint8_t>{};

    // Texture-sampler pairs, applied to every module created below.
    std::vector<ShaderModule::TextureSamplerPair> pairVec;
    {
        auto pairs = asset.textureSamplerPairs();
        pairVec.reserve(pairs.size());
        for (size_t i = 0; i < pairs.size(); i++)
        {
            pairVec.push_back({pairs[i].texGroup,
                               pairs[i].texBinding,
                               pairs[i].sampGroup,
                               pairs[i].sampBinding});
        }
    }

    // Per-entry targets: one ShaderModule per entry (GL compiles a `main`,
    // HLSL D3DCompiles against the cleansed physical name).
    if (target == ShaderTarget::glsl || target == ShaderTarget::hlsl)
    {
        std::vector<rive::ore::RstbEntryView> views;
        if (!rive::ore::parsePerEntryContainer(blobData, blobSize, views))
            return false;
        for (const auto& v : views)
        {
            // GL/HLSL containers only carry vertex/fragment entries; ignore any
            // other stage rather than misclassifying it as a fragment module.
            if (v.stage != 0 && v.stage != 1)
                continue;
            ShaderModuleDesc desc;
            desc.stage =
                (v.stage == 0) ? ShaderStage::vertex : ShaderStage::fragment;
            desc.bindingMapBytes = bindingMapBytes;
            desc.bindingMapSize = bindingMapSize;
            desc.shaderAssetId = assetId;
            if (target == ShaderTarget::hlsl)
            {
                desc.hlslSource = reinterpret_cast<const char*>(v.source);
                desc.hlslSourceSize = v.sourceSize;
                desc.hlslEntryPoint = v.physical.c_str();
            }
            else // glsl
            {
                desc.code = v.source;
                desc.codeSize = v.sourceSize;
                auto fx = (v.stage == 0) ? vsGLFixupBlob : fsGLFixupBlob;
                desc.glFixupBytes = fx.empty() ? nullptr : fx.data();
                desc.glFixupSize = static_cast<uint32_t>(fx.size());
            }

            auto mod = oreCtx->makeShaderModule(desc);
            if (!mod)
                return false;
            if (!pairVec.empty())
                mod->m_textureSamplerPairs = pairVec;
            ScriptedShaderEntry e;
            e.stage = v.stage;
            e.logical = v.logical;
            e.physical = v.physical;
            e.module = std::move(mod);
            out->entries.push_back(std::move(e));
        }
        return !out->entries.empty();
    }

    // Whole-module targets: one shared module, one entry record per entry, all
    // referencing it. The driver selects the entry by its physical name.
    std::vector<rive::ore::RstbEntryView> views;
    const uint8_t* src = nullptr;
    uint32_t srcLen = 0;
    if (!rive::ore::parseWholeModuleContainer(blobData,
                                              blobSize,
                                              views,
                                              &src,
                                              &srcLen))
        return false;
    ShaderModuleDesc desc;
    desc.code = src;
    desc.codeSize = srcLen;
    desc.bindingMapBytes = bindingMapBytes;
    desc.bindingMapSize = bindingMapSize;
    desc.shaderAssetId = assetId;
    auto mod = oreCtx->makeShaderModule(desc);
    if (!mod)
        return false;
    if (!pairVec.empty())
        mod->m_textureSamplerPairs = pairVec;
    for (const auto& v : views)
    {
        ScriptedShaderEntry e;
        e.stage = v.stage;
        e.logical = v.logical;
        e.physical = v.physical;
        e.module = mod;
        out->entries.push_back(std::move(e));
    }
    return !out->entries.empty();
}

#ifdef WITH_RIVE_TOOLS
/// Editor live-preview: decode raw RSTB bytes then build entries. The workspace
/// hands us unsigned bytes, so prepend a zero SignedContentHeader envelope byte
/// (`[flags:1][inner]`) to produce ShaderAsset::decode's expected input.
static bool makeShaderFromRstb(Context* oreCtx,
                               const uint8_t* data,
                               uint32_t len,
                               ScriptedShader* out)
{
    if (oreCtx == nullptr || data == nullptr || len == 0 || out == nullptr)
        return false;
    ShaderAsset asset;
    SimpleArray<uint8_t> bytes(static_cast<size_t>(len) + 1);
    bytes[0] = 0x00; // flags: unsigned, version 0
    memcpy(bytes.data() + 1, data, len);
    if (!asset.decode(bytes, nullptr))
        return false;
    return buildShaderEntries(oreCtx, asset, out);
}
#endif // WITH_RIVE_TOOLS

/// Look up a shader by name: first check the per-VM RSTB blobs on the
/// ScriptingContext (editor path, compiled during requestVM), then try the
/// ShaderAsset from file->assets() (runtime .riv path).
/// Populates both vertex and fragment modules on the ScriptedShader.
/// Returns true on success.
bool lua_gpu_load_shader_by_name(
    ScriptedShader* out,
    ScriptingContext* context,
    const ScriptingContext::ScopedAssetReference& reference,
    ShaderAsset* fileAsset)
{
    Context* oreCtx = static_cast<Context*>(
        context != nullptr ? context->oreContext() : nullptr);

#ifdef WITH_RIVE_TOOLS
    // Editor path: RSTB blobs compiled from WGSL during requestVM, stored
    // per-VM on the ScriptingContext.
    if (context != nullptr)
    {
        const auto* rstb = context->findShaderRstb(reference);
        if (rstb != nullptr)
        {
            return makeShaderFromRstb(oreCtx,
                                      rstb->data(),
                                      static_cast<uint32_t>(rstb->size()),
                                      out);
        }
    }
#endif
    // Runtime path: ShaderAsset from the .riv file's asset list. Same
    // container parsing as the editor path (buildShaderEntries) so entry-point
    // resolution is identical on all backends.
    if (fileAsset != nullptr && oreCtx != nullptr)
    {
        return buildShaderEntries(oreCtx, *fileAsset, out);
    }

    return false;
}

ShaderAsset* lua_gpu_find_shader_asset(
    File* file,
    const ScriptingContext::ScopedAssetReference& reference)
{
    if (file == nullptr)
    {
        return nullptr;
    }
    ShaderAsset* found = nullptr;
    int bestRank = 0;
    for (const auto& asset : file->assets())
    {
        if (!asset->is<ShaderAsset>())
        {
            continue;
        }
        auto* shaderAsset = asset->as<ShaderAsset>();
        const std::string& folderPath = shaderAsset->folderPath();
        std::string registered = folderPath.empty()
                                     ? shaderAsset->name()
                                     : folderPath + "/" + shaderAsset->name();
        int rank = reference.match(registered, shaderAsset->name());
        if (rank > bestRank)
        {
            bestRank = rank;
            found = shaderAsset;
        }
    }
    return found;
}

int lua_gpu_push_shader_by_name(lua_State* L, const char* name)
{
    auto* context = static_cast<ScriptingContext*>(lua_getthreaddata(L));
    ScriptingContext::ScopedAssetReference reference(L, name);

    // Resolve the file-side ShaderAsset. Without this, the lookup falls
    // back to the editor-only RSTB cache which is empty at runtime.
    ShaderAsset* fileAsset = nullptr;
    if (context != nullptr)
    {
        if (auto* scriptedObject = context->currentScriptedObject())
        {
            if (auto* scriptAsset = scriptedObject->scriptAsset())
            {
                fileAsset =
                    lua_gpu_find_shader_asset(scriptAsset->file(), reference);
            }
        }
    }

    auto* scripted = lua_newrive<ScriptedShader>(L);
    if (!lua_gpu_load_shader_by_name(scripted, context, reference, fileAsset))
    {
        lua_pop(L, 1);
        return 0;
    }
    return 1;
}

// ============================================================================
// GPUBuffer
// ============================================================================

// `GPUBuffer.new({ size, usage, data?, immutable?, label? })`:
//   - `size`       : size in bytes.
//   - `usage`      : 'vertex' | 'index' | 'uniform', or a one-element array of
//                    the same (the array form is reserved for future
//                    multi-usage flags).
//   - `data`       : Lua buffer with initial contents. Required when
//                    `immutable=true`. Length must match `size` exactly so
//                    backends can populate the GPU resource at create time.
//   - `immutable`  : when true, the buffer is GPU-only (no `:write` after
//                    creation). Required for `BufferDesc::immutable`, which
//                    backends with a USAGE_IMMUTABLE concept (D3D11) honor
//                    for static vertex/index buffers.
//   - `label`      : optional debug name.
static int gpubuffer_construct(lua_State* L)
{
    if (getOreContext(L) == nullptr)
    {
        luaL_error(L, "GPU context not initialized");
    }
    luaL_checktype(L, 1, LUA_TTABLE);

    BufferDesc desc;
    // Required positive size that fits in uint32. The raw number path would
    // otherwise truncate floats or wrap negatives.
    lua_getfield(L, 1, "size");
    if (!lua_isnumber(L, -1))
        luaL_error(L, "GPUBuffer.new: 'size' is required (bytes)");
    double sizeNum = lua_tonumber(L, -1);
    lua_pop(L, 1);
    // Prove the value is finite and in range before any integer cast: casting
    // NaN or out-of-range doubles to uint32 is undefined. The positive range
    // test is false for NaN, so the && short-circuits before the cast.
    bool validInt =
        sizeNum >= 1.0 && sizeNum <= 4294967295.0 &&
        sizeNum == static_cast<double>(static_cast<uint32_t>(sizeNum));
    if (!validInt)
    {
        luaL_error(L,
                   "GPUBuffer.new: 'size' must be a positive integer number "
                   "of bytes");
    }
    desc.size = static_cast<uint32_t>(sizeNum);
    desc.usage = lua_tobufferusagefield(L, 1);
    desc.immutable = lua_getoptionalboolfield(L, 1, "immutable", false);
    desc.label = lua_getoptionalstringfield(L, 1, "label");

    lua_getfield(L, 1, "data");
    if (!lua_isnil(L, -1))
    {
        size_t dataLen = 0;
        const void* dataPtr = lua_tobuffer(L, -1, &dataLen);
        if (dataPtr == nullptr)
        {
            luaL_error(L, "GPUBuffer.new: 'data' must be a Luau buffer");
        }
        if (dataLen != desc.size)
        {
            luaL_error(L,
                       "GPUBuffer.new: data length (%zu) must equal size (%u)",
                       dataLen,
                       desc.size);
        }
        desc.data = dataPtr;
    }
    lua_pop(L, 1);

    if (desc.immutable && desc.data == nullptr)
    {
        luaL_error(L,
                   "GPUBuffer.new: immutable=true requires 'data' (the GPU "
                   "buffer is GPU-only after creation)");
    }

    auto* ctx = getOreContext(L);
    ctx->clearLastError();
    auto buffer = ctx->makeBuffer(desc);
    if (!buffer)
    {
        if (!ctx->lastError().empty())
            luaL_error(L, "GPUBuffer.new: %s", ctx->lastError().c_str());
        luaL_error(L, "GPUBuffer.new: failed to create buffer");
    }

    auto* scripted = lua_newrive<ScriptedGPUBuffer>(L);
    scripted->buffer = std::move(buffer);
    scripted->immutable = desc.immutable;
    return 1;
}

static int gpubuffer_write(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPUBuffer>(L, 1);
    if (self->immutable)
    {
        luaL_error(L,
                   "GPUBuffer:write: buffer was created with "
                   "immutable=true; its contents are fixed at construction");
    }
    // Luau buffer type
    size_t len;
    const void* data = lua_tobuffer(L, 2, &len);
    if (data == nullptr)
    {
        luaL_typeerror(L, 2, "buffer");
    }
    uint32_t dstOffset =
        lua_isnumber(L, 3) ? static_cast<uint32_t>(lua_tonumber(L, 3)) : 0;
    uint32_t srcOffset =
        lua_isnumber(L, 4) ? static_cast<uint32_t>(lua_tonumber(L, 4)) : 0;
    if (srcOffset > len)
    {
        luaL_error(L,
                   "GPUBuffer:write: srcOffset(%u) exceeds source buffer "
                   "size(%u)",
                   srcOffset,
                   (uint32_t)len);
    }
    uint32_t byteLength = lua_isnumber(L, 5)
                              ? static_cast<uint32_t>(lua_tonumber(L, 5))
                              : static_cast<uint32_t>(len - srcOffset);

    if (uint64_t(srcOffset) + byteLength > len)
    {
        luaL_error(L,
                   "GPUBuffer:write: srcOffset(%u) + byteLength(%u) exceeds "
                   "source buffer size(%u)",
                   srcOffset,
                   byteLength,
                   (uint32_t)len);
    }
    if (uint64_t(dstOffset) + byteLength > self->buffer->size())
    {
        luaL_error(L,
                   "GPUBuffer:write: offset(%u) + size(%u) = %u exceeds "
                   "buffer size(%u)",
                   dstOffset,
                   byteLength,
                   (uint32_t)(dstOffset + byteLength),
                   self->buffer->size());
    }

    self->buffer->update(static_cast<const uint8_t*>(data) + srcOffset,
                         byteLength,
                         dstOffset);
    return 0;
}

static int gpubuffer_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::write:
                return gpubuffer_write(L);
        }
    }
    luaL_error(L,
               "%s is not a valid method of %s",
               str,
               ScriptedGPUBuffer::luaName);
    return 0;
}

static void gpubuffer_direct_size(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(
        result,
        (double)((ScriptedGPUBuffer*)udata)->buffer->size());
}

static int gpubuffer_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
    }
    auto* self = lua_torive<ScriptedGPUBuffer>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::size:
            lua_pushnumber(L, self->buffer->size());
            return 1;
    }
    luaL_error(L, "'%s' is not a valid index of GPUBuffer", key);
    return 0;
}

// ============================================================================
// GPUTexture
// ============================================================================

// Validate a user-supplied sampleCount against the device's actual limit.
// Errors with a clear message rather than letting Metal/Vulkan assert-fail.
static void lua_checksamplecount(lua_State* L, uint32_t sampleCount)
{
    if (sampleCount <= 1)
        return;
    // Must be a power of two.
    if ((sampleCount & (sampleCount - 1)) != 0)
        luaL_error(L,
                   "sampleCount must be a power of two (got %u)",
                   sampleCount);
    auto* ctx = getOreContext(L);
    if (features_are_known(ctx))
    {
        uint32_t maxSamples = ctx->features().maxSamples;
        if (sampleCount > maxSamples)
            luaL_error(L,
                       "sampleCount %u exceeds device maximum of %u — "
                       "query context:features().maxSamples before creating "
                       "MSAA textures",
                       sampleCount,
                       maxSamples);
    }
}

static int gputexture_construct(lua_State* L)
{
    if (getOreContext(L) == nullptr)
    {
        luaL_error(L, "GPU context not initialized");
    }

    luaL_checktype(L, 1, LUA_TTABLE);
    int descIdx = 1;

    TextureDesc desc;
    desc.width = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "width", 0));
    desc.height = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "height", 0));
    if (desc.width == 0 || desc.height == 0)
    {
        luaL_error(L, "GPUTexture requires width and height");
    }

    const char* fmt = lua_getoptionalstringfield(L, descIdx, "format");
    if (fmt)
        desc.format = lua_totextureformat(L, fmt);

    const char* typ = lua_getoptionalstringfield(L, descIdx, "type");
    if (typ)
        desc.type = lua_totexturetype(L, typ);

    desc.renderTarget =
        lua_getoptionalboolfield(L, descIdx, "renderTarget", false);
    desc.sampleCount = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "sampleCount", 1));
    lua_checksamplecount(L, desc.sampleCount);
    desc.numMipmaps = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "mipmaps", 1));
    desc.depthOrArrayLayers = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "layers", 1));

    auto* ctx = getOreContext(L);
    // Gate float render targets: without the matching capability they make an
    // incomplete FBO that renders black. Sampled-only float textures are fine.
    // 16-bit floats need half-float, 32-bit and packed need full float.
    if (desc.renderTarget && features_are_known(ctx))
    {
        FloatColorClass fc = floatColorClass(desc.format);
        const Features& feat = ctx->features();
        bool ok = fc == FloatColorClass::none ||
                  (fc == FloatColorClass::half && feat.colorBufferHalfFloat) ||
                  (fc == FloatColorClass::full && feat.colorBufferFloat);
        if (!ok)
        {
            const char* cap = fc == FloatColorClass::half
                                  ? "colorBufferHalfFloat"
                                  : "colorBufferFloat";
            luaL_error(L,
                       "GPUTexture.new: float format %s as a renderTarget "
                       "requires the %s feature, which the active backend does "
                       "not support",
                       lua_totextureformatstring(desc.format),
                       cap);
        }
    }
    ctx->clearLastError();
    auto texture = ctx->makeTexture(desc);
    if (!texture)
    {
        if (!ctx->lastError().empty())
            luaL_error(L, "GPUTexture.new: %s", ctx->lastError().c_str());
        luaL_error(L, "GPUTexture.new: failed to create texture");
    }

    auto* scripted = lua_newrive<ScriptedGPUTexture>(L);
    scripted->texture = std::move(texture);
    return 1;
}

static int gputexture_view(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPUTexture>(L, 1);

    TextureViewDesc viewDesc;
    viewDesc.texture = self->texture.get();
    viewDesc.mipCount = self->texture->numMipmaps();
    viewDesc.layerCount = self->texture->depthOrArrayLayers();

    // Map TextureType -> TextureViewDimension
    switch (self->texture->type())
    {
        case TextureType::texture2D:
            viewDesc.dimension = TextureViewDimension::texture2D;
            break;
        case TextureType::cube:
            viewDesc.dimension = TextureViewDimension::cube;
            break;
        case TextureType::texture3D:
            viewDesc.dimension = TextureViewDimension::texture3D;
            break;
        case TextureType::array2D:
            viewDesc.dimension = TextureViewDimension::array2D;
            break;
    }

    if (lua_istable(L, 2))
    {
        const char* dim = lua_getoptionalstringfield(L, 2, "dimension");
        if (dim)
        {
            if (strcmp(dim, "2d") == 0)
                viewDesc.dimension = TextureViewDimension::texture2D;
            else if (strcmp(dim, "cube") == 0)
                viewDesc.dimension = TextureViewDimension::cube;
            else if (strcmp(dim, "3d") == 0)
                viewDesc.dimension = TextureViewDimension::texture3D;
            else if (strcmp(dim, "2d-array") == 0)
                viewDesc.dimension = TextureViewDimension::array2D;
        }
        viewDesc.baseMipLevel = static_cast<uint32_t>(
            lua_getoptionalnumberfield(L, 2, "baseMipLevel", 0));
        viewDesc.mipCount = static_cast<uint32_t>(
            lua_getoptionalnumberfield(L, 2, "mipCount", viewDesc.mipCount));
        viewDesc.baseLayer = static_cast<uint32_t>(
            lua_getoptionalnumberfield(L, 2, "baseLayer", 0));
        viewDesc.layerCount = static_cast<uint32_t>(
            lua_getoptionalnumberfield(L,
                                       2,
                                       "layerCount",
                                       viewDesc.layerCount));
    }

    auto* ctx = getOreContext(L);
    ctx->clearLastError();
    auto tv = ctx->makeTextureView(viewDesc);
    if (!tv)
    {
        if (!ctx->lastError().empty())
            luaL_error(L, "GPUTexture:view: %s", ctx->lastError().c_str());
        luaL_error(L, "GPUTexture:view: failed to create texture view");
    }

    auto* scripted = lua_newrive<ScriptedGPUTextureView>(L);
    scripted->view = std::move(tv);
    return 1;
}

static int gputexture_upload(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPUTexture>(L, 1);
    luaL_checktype(L, 2, LUA_TTABLE);
    int descIdx = 2;

    lua_getfield(L, descIdx, "data");
    size_t len;
    const void* data = lua_tobuffer(L, -1, &len);
    if (!data)
    {
        luaL_error(L, "upload requires 'data' field of type buffer");
    }
    lua_pop(L, 1);

    TextureDataDesc uploadDesc;
    uploadDesc.data = data;
    uploadDesc.width = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L,
                                   descIdx,
                                   "width",
                                   self->texture->width()));
    uploadDesc.height = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L,
                                   descIdx,
                                   "height",
                                   self->texture->height()));
    uploadDesc.depth = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "depth", 1));
    uploadDesc.x =
        static_cast<uint32_t>(lua_getoptionalnumberfield(L, descIdx, "x", 0));
    uploadDesc.y =
        static_cast<uint32_t>(lua_getoptionalnumberfield(L, descIdx, "y", 0));
    uploadDesc.z =
        static_cast<uint32_t>(lua_getoptionalnumberfield(L, descIdx, "z", 0));
    uploadDesc.mipLevel = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "mipLevel", 0));
    uploadDesc.layer = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "layer", 0));
    uploadDesc.bytesPerRow = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "bytesPerRow", 0));
    uploadDesc.rowsPerImage = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "rowsPerImage", 0));

    // Validate region/level/layer against the texture's actual dimensions —
    // out-of-range values trip backend asserts (Metal API Validation, D3D12
    // GPU hangs, Vulkan validation). Per the
    // `feedback_lua_gpu_misuse_validation` rule, surface as luaL_error.
    if (uploadDesc.mipLevel >= self->texture->numMipmaps())
    {
        luaL_error(L,
                   "upload: mipLevel %u out of range [0, %u)",
                   uploadDesc.mipLevel,
                   self->texture->numMipmaps());
    }
    if (uploadDesc.layer >= self->texture->depthOrArrayLayers())
    {
        luaL_error(L,
                   "upload: layer %u out of range [0, %u)",
                   uploadDesc.layer,
                   self->texture->depthOrArrayLayers());
    }
    // Mip-level dimensions: floor-div-by-2 per level, min 1.
    uint32_t mipW = std::max(1u, self->texture->width() >> uploadDesc.mipLevel);
    uint32_t mipH =
        std::max(1u, self->texture->height() >> uploadDesc.mipLevel);
    if (uploadDesc.x > mipW || uploadDesc.width > mipW - uploadDesc.x)
    {
        luaL_error(L,
                   "upload: x+width (%u+%u) exceeds mip %u width %u",
                   uploadDesc.x,
                   uploadDesc.width,
                   uploadDesc.mipLevel,
                   mipW);
    }
    if (uploadDesc.y > mipH || uploadDesc.height > mipH - uploadDesc.y)
    {
        luaL_error(L,
                   "upload: y+height (%u+%u) exceeds mip %u height %u",
                   uploadDesc.y,
                   uploadDesc.height,
                   uploadDesc.mipLevel,
                   mipH);
    }

    // Compute a tightly-packed bytesPerRow when the caller omits it.
    if (uploadDesc.bytesPerRow == 0)
    {
        uint32_t bpt = textureFormatBytesPerTexel(self->texture->format());
        if (bpt == 0)
        {
            luaL_error(L,
                       "upload: bytesPerRow must be provided for "
                       "block-compressed formats");
        }
        uploadDesc.bytesPerRow = uploadDesc.width * bpt;
    }

    // Default rowsPerImage to height so Metal's bytesPerImage is correct.
    if (uploadDesc.rowsPerImage == 0)
    {
        uploadDesc.rowsPerImage = uploadDesc.height;
    }

    // Validate the data buffer is large enough to cover the region.
    // GPUs read past the supplied bytes if we don't catch it here; on
    // Metal the validation layer aborts, on others it's a silent OOB.
    const uint64_t requiredBytes =
        static_cast<uint64_t>(uploadDesc.bytesPerRow) *
        uploadDesc.rowsPerImage * std::max(1u, uploadDesc.depth);
    if (len < requiredBytes)
    {
        luaL_error(L,
                   "upload: data buffer is %zu bytes but region requires "
                   "%llu (bytesPerRow=%u * rowsPerImage=%u * depth=%u)",
                   len,
                   static_cast<unsigned long long>(requiredBytes),
                   uploadDesc.bytesPerRow,
                   uploadDesc.rowsPerImage,
                   std::max(1u, uploadDesc.depth));
    }

    self->texture->upload(uploadDesc);
    return 0;
}

static int gputexture_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::view:
                return gputexture_view(L);
            case (int)LuaAtoms::upload:
                return gputexture_upload(L);
        }
    }
    luaL_error(L,
               "%s is not a valid method of %s",
               str,
               ScriptedGPUTexture::luaName);
    return 0;
}

static void gputexture_direct_width(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(
        result,
        (double)((ScriptedGPUTexture*)udata)->texture->width());
}

static void gputexture_direct_height(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(
        result,
        (double)((ScriptedGPUTexture*)udata)->texture->height());
}

static int gputexture_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
    }
    auto* self = lua_torive<ScriptedGPUTexture>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::width:
            lua_pushnumber(L, self->texture->width());
            return 1;
        case (int)LuaAtoms::height:
            lua_pushnumber(L, self->texture->height());
            return 1;
        case (int)LuaAtoms::format:
            lua_pushstring(L,
                           lua_totextureformatstring(self->texture->format()));
            return 1;
    }
    luaL_error(L, "'%s' is not a valid index of GPUTexture", key);
    return 0;
}

static int gputextureview_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
    }
    auto* self = lua_torive<ScriptedGPUTextureView>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::format:
            if (self->view && self->view->texture())
                lua_pushstring(
                    L,
                    lua_totextureformatstring(self->view->texture()->format()));
            else
                lua_pushnil(L);
            return 1;
    }
    luaL_error(L, "'%s' is not a valid index of GPUTextureView", key);
    return 0;
}

// ============================================================================
// GPUSampler
// ============================================================================

static int gpusampler_construct(lua_State* L)
{
    if (getOreContext(L) == nullptr)
    {
        luaL_error(L, "GPU context not initialized");
    }

    SamplerDesc desc;

    if (lua_istable(L, 1))
    {
        int descIdx = 1;
        const char* s;

        s = lua_getoptionalstringfield(L, descIdx, "min");
        if (s)
            desc.minFilter = lua_tofilter(L, s);
        s = lua_getoptionalstringfield(L, descIdx, "mag");
        if (s)
            desc.magFilter = lua_tofilter(L, s);
        s = lua_getoptionalstringfield(L, descIdx, "mipmap");
        if (s)
            desc.mipmapFilter = lua_tofilter(L, s);
        s = lua_getoptionalstringfield(L, descIdx, "wrapU");
        if (s)
            desc.wrapU = lua_towrapmode(L, s);
        s = lua_getoptionalstringfield(L, descIdx, "wrapV");
        if (s)
            desc.wrapV = lua_towrapmode(L, s);
        s = lua_getoptionalstringfield(L, descIdx, "wrapW");
        if (s)
            desc.wrapW = lua_towrapmode(L, s);
        s = lua_getoptionalstringfield(L, descIdx, "compare");
        if (s)
            desc.compare = lua_tocompare(L, s);
        desc.minLod = static_cast<float>(
            lua_getoptionalnumberfield(L, descIdx, "minLod", 0.0));
        desc.maxLod = static_cast<float>(
            lua_getoptionalnumberfield(L, descIdx, "maxLod", 32.0));
        if (desc.minLod > desc.maxLod)
        {
            luaL_error(L,
                       "GPUSampler.new: minLod (%g) > maxLod (%g)",
                       desc.minLod,
                       desc.maxLod);
        }
        desc.maxAnisotropy = static_cast<uint32_t>(
            lua_getoptionalnumberfield(L, descIdx, "maxAnisotropy", 1));
        // WebGPU + every backend caps anisotropy at 16x and accepts only
        // power-of-two values. Reject out-of-range early so a bad sampler
        // doesn't cause a backend-specific create failure later.
        const uint32_t a = desc.maxAnisotropy;
        if (a < 1 || a > 16 || (a & (a - 1)) != 0)
        {
            luaL_error(L,
                       "GPUSampler.new: maxAnisotropy must be a power of "
                       "two in [1, 16] (got %u)",
                       a);
        }
        if (a > 1 && features_are_known(getOreContext(L)) &&
            !getOreContext(L)->features().anisotropicFiltering)
        {
            luaL_error(L,
                       "GPUSampler.new: maxAnisotropy=%u requires "
                       "anisotropicFiltering feature, which the active "
                       "backend does not support",
                       a);
        }
    }

    auto* ctx = getOreContext(L);
    ctx->clearLastError();
    auto sampler = ctx->makeSampler(desc);
    if (!sampler)
    {
        if (!ctx->lastError().empty())
            luaL_error(L, "GPUSampler.new: %s", ctx->lastError().c_str());
        luaL_error(L, "GPUSampler.new: failed to create sampler");
    }

    auto* scripted = lua_newrive<ScriptedGPUSampler>(L);
    scripted->sampler = std::move(sampler);
    return 1;
}

// ============================================================================
// GPUBindGroup
// ============================================================================

ScriptedGPUBindGroup::~ScriptedGPUBindGroup() {}

// ============================================================================
// GPUBindGroupLayout.new — explicit BindGroupLayout (Phase E).
// ============================================================================

// Map binding-map types to layout-entry types. These mirror the GM helper
// `makeLayoutFromShader` so Lua-built layouts validate the same way as
// C++-built ones.
static BindingKind bindingKindFromResource(ResourceKind k)
{
    switch (k)
    {
        case ResourceKind::UniformBuffer:
            return BindingKind::uniformBuffer;
        case ResourceKind::StorageBufferRO:
            return BindingKind::storageBufferRO;
        case ResourceKind::StorageBufferRW:
            return BindingKind::storageBufferRW;
        case ResourceKind::SampledTexture:
            return BindingKind::sampledTexture;
        case ResourceKind::StorageTexture:
            return BindingKind::storageTexture;
        case ResourceKind::Sampler:
            return BindingKind::sampler;
        case ResourceKind::ComparisonSampler:
            return BindingKind::comparisonSampler;
    }
    return BindingKind::uniformBuffer;
}

static TextureViewDimension viewDimFromBindingMap(TextureViewDim d)
{
    switch (d)
    {
        case TextureViewDim::Cube:
            return TextureViewDimension::cube;
        case TextureViewDim::CubeArray:
            return TextureViewDimension::cubeArray;
        case TextureViewDim::D3:
            return TextureViewDimension::texture3D;
        case TextureViewDim::D2Array:
            return TextureViewDimension::array2D;
        case TextureViewDim::D1:
        case TextureViewDim::D2:
        case TextureViewDim::Undefined:
            return TextureViewDimension::texture2D;
    }
    return TextureViewDimension::texture2D;
}

static BindGroupLayoutEntry::SampleType sampleTypeFromBindingMap(
    TextureSampleType s)
{
    switch (s)
    {
        case TextureSampleType::UnfilterableFloat:
            return BindGroupLayoutEntry::SampleType::floatUnfilterable;
        case TextureSampleType::Depth:
            return BindGroupLayoutEntry::SampleType::depth;
        case TextureSampleType::Sint:
            return BindGroupLayoutEntry::SampleType::sint;
        case TextureSampleType::Uint:
            return BindGroupLayoutEntry::SampleType::uint;
        case TextureSampleType::Float:
        case TextureSampleType::Undefined:
            return BindGroupLayoutEntry::SampleType::floatFilterable;
    }
    return BindGroupLayoutEntry::SampleType::floatFilterable;
}

// Walk a shader's BindingMap for the given group, populating layout entries
// with kind / visibility / texture metadata / native slots — the same path the
// GM helper takes. Returns the entry count actually filled.
static uint32_t populateEntriesFromShader(BindGroupLayoutEntry* entries,
                                          uint32_t maxEntries,
                                          const ore::ShaderModule* shader,
                                          uint32_t group,
                                          const uint32_t* dynamicUBOBindings,
                                          uint32_t dynamicUBOCount)
{
    if (shader == nullptr)
        return 0;
    auto isDynamic = [&](uint32_t binding) -> bool {
        for (uint32_t i = 0; i < dynamicUBOCount; ++i)
            if (dynamicUBOBindings[i] == binding)
                return true;
        return false;
    };
    const BindingMap& bm = shader->m_bindingMap;
    uint32_t n = 0;
    for (size_t i = 0; i < bm.size() && n < maxEntries; ++i)
    {
        const BindingMap::Entry& e = bm.at(i);
        if (e.group != group)
            continue;
        BindGroupLayoutEntry& out = entries[n++];
        out.binding = e.binding;
        out.kind = bindingKindFromResource(e.kind);
        uint8_t vis = 0;
        if (e.stageMask & BindingMap::kStageVertex)
            vis |= StageVisibility::kVertex;
        if (e.stageMask & BindingMap::kStageFragment)
            vis |= StageVisibility::kFragment;
        if (e.stageMask & BindingMap::kStageCompute)
            vis |= StageVisibility::kCompute;
        out.visibility.mask = vis;
        out.hasDynamicOffset =
            (out.kind == BindingKind::uniformBuffer && isDynamic(e.binding));
        out.textureViewDim = viewDimFromBindingMap(e.textureViewDim);
        out.textureSampleType = sampleTypeFromBindingMap(e.textureSampleType);
        out.textureMultisampled = e.textureMultisampled;
        const uint16_t vs =
            e.backendSlot[static_cast<size_t>(BindingMap::Stage::VS)];
        const uint16_t fs =
            e.backendSlot[static_cast<size_t>(BindingMap::Stage::FS)];
        out.nativeSlotVS = (vs == BindingMap::kAbsent)
                               ? BindGroupLayoutEntry::kNativeSlotAbsent
                               : static_cast<uint32_t>(vs);
        out.nativeSlotFS = (fs == BindingMap::kAbsent)
                               ? BindGroupLayoutEntry::kNativeSlotAbsent
                               : static_cast<uint32_t>(fs);
    }
    return n;
}

static int gpubindgrouplayout_construct(lua_State* L)
{
    Context* oreCtx = getOreContext(L);
    if (oreCtx == nullptr)
        luaL_error(L, "GPU context not initialized");

    luaL_checktype(L, 1, LUA_TTABLE);
    int descIdx = 1;

    BindGroupLayoutDesc desc;
    desc.groupIndex = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "groupIndex", 0));
    if (desc.groupIndex >= ore::kMaxBindGroups)
        luaL_error(L,
                   "GPUBindGroupLayout.new: groupIndex must be in [0, %u)",
                   ore::kMaxBindGroups);

    // Resolve the source shader. Layouts must always derive from a shader
    // module — Lua callers cannot meaningfully fill in `nativeSlotVS/FS`
    // without the binding map, and getting kind/visibility wrong would
    // fail validation anyway.
    lua_getfield(L, descIdx, "shader");
    auto* scripted = lua_torive<ScriptedShader>(L, -1);
    lua_pop(L, 1);
    if (scripted == nullptr || !scripted->hasModule())
        luaL_error(L,
                   "GPUBindGroupLayout.new: 'shader' must be a Shader with "
                   "a loaded module");

    static constexpr int kMaxEntries = 16;
    BindGroupLayoutEntry entries[kMaxEntries]{};

    // Optional `dynamicUBOs`: array of WGSL @binding values whose UBO
    // entries should set hasDynamicOffset.
    uint32_t dynUBOs[kMaxEntries] = {};
    uint32_t dynUBOCount = 0;
    lua_getfield(L, descIdx, "dynamicUBOs");
    if (lua_istable(L, -1))
    {
        int dynTbl = lua_gettop(L);
        int dynN = (int)lua_objlen(L, dynTbl);
        for (int i = 0; i < dynN && dynUBOCount < kMaxEntries; ++i)
        {
            lua_rawgeti(L, dynTbl, i + 1);
            if (lua_isnumber(L, -1))
                dynUBOs[dynUBOCount++] =
                    static_cast<uint32_t>(lua_tonumber(L, -1));
            lua_pop(L, 1);
        }
    }
    lua_pop(L, 1); // dynamicUBOs

    // Vertex module carries the merged binding map for both stages —
    // the same module the GM helper walks.
    uint32_t entryCount = populateEntriesFromShader(entries,
                                                    kMaxEntries,
                                                    scripted->vertexMod(),
                                                    desc.groupIndex,
                                                    dynUBOs,
                                                    dynUBOCount);

    desc.entries = entries;
    desc.entryCount = entryCount;

    rcp<BindGroupLayout> layout = oreCtx->makeBindGroupLayout(desc);
    if (!layout)
    {
        const std::string& err = oreCtx->lastError();
        oreCtx->clearLastError();
        luaL_error(L,
                   "GPUBindGroupLayout.new: %s",
                   err.empty() ? "failed" : err.c_str());
    }

    auto* w = lua_newrive<ScriptedGPUBindGroupLayout>(L);
    w->layout = std::move(layout);
    return 1;
}

static int gpubindgroup_construct(lua_State* L)
{
    Context* oreCtx = getOreContext(L);
    if (oreCtx == nullptr)
    {
        luaL_error(L, "GPU context not initialized");
    }

    luaL_checktype(L, 1, LUA_TTABLE);
    int descIdx = 1;

    BindGroupDesc desc;

    // layout (required) — replaces the legacy `pipeline` field. The
    // BindGroup is built against a BindGroupLayout (Phase E); the
    // layout's groupIndex determines which @group(N) the BindGroup
    // binds to.
    lua_getfield(L, descIdx, "layout");
    auto* layoutScripted = lua_torive<ScriptedGPUBindGroupLayout>(L, -1);
    if (layoutScripted == nullptr)
    {
        luaL_error(L,
                   "GPUBindGroup.new: 'layout' field is required and must be "
                   "a GPUBindGroupLayout");
    }
    desc.layout = layoutScripted->layout.get();
    lua_pop(L, 1);

    // Parse UBO entries
    static constexpr int MAX_ENTRIES = 8;
    BindGroupDesc::UBOEntry uboEntries[MAX_ENTRIES];
    uint32_t uboCount = 0;

    lua_getfield(L, descIdx, "ubos");
    if (lua_istable(L, -1))
    {
        int tbl = lua_gettop(L);
        int n = (int)lua_objlen(L, tbl);
        for (int i = 0; i < n && i < MAX_ENTRIES; i++)
        {
            lua_rawgeti(L, tbl, i + 1);
            int entry = lua_gettop(L);

            uboEntries[uboCount].slot = static_cast<uint32_t>(
                lua_getoptionalnumberfield(L, entry, "slot", 0));
            if (uboEntries[uboCount].slot > 7)
            {
                luaL_error(L,
                           "GPUBindGroup.new: UBO slot must be 0-7 (got %u)",
                           uboEntries[uboCount].slot);
            }

            lua_getfield(L, entry, "buffer");
            auto* bufScripted = lua_torive<ScriptedGPUBuffer>(L, -1);
            uboEntries[uboCount].buffer = bufScripted->buffer.get();
            lua_pop(L, 1);

            uboEntries[uboCount].offset = static_cast<uint32_t>(
                lua_getoptionalnumberfield(L, entry, "offset", 0));
            uboEntries[uboCount].size = static_cast<uint32_t>(
                lua_getoptionalnumberfield(L, entry, "size", 0));

            lua_pop(L, 1); // entry table
            uboCount++;
        }
    }
    lua_pop(L, 1);
    desc.ubos = uboEntries;
    desc.uboCount = uboCount;

    // Parse texture entries
    BindGroupDesc::TexEntry texEntries[MAX_ENTRIES];
    uint32_t texCount = 0;

    lua_getfield(L, descIdx, "textures");
    if (lua_istable(L, -1))
    {
        int tbl = lua_gettop(L);
        int n = (int)lua_objlen(L, tbl);
        for (int i = 0; i < n && i < MAX_ENTRIES; i++)
        {
            lua_rawgeti(L, tbl, i + 1);
            int entry = lua_gettop(L);

            texEntries[texCount].slot = static_cast<uint32_t>(
                lua_getoptionalnumberfield(L, entry, "slot", 0));
            if (texEntries[texCount].slot > 7)
            {
                luaL_error(
                    L,
                    "GPUBindGroup.new: texture slot must be 0-7 (got %u)",
                    texEntries[texCount].slot);
            }

            lua_getfield(L, entry, "view");
            auto* tv = lua_torive<ScriptedGPUTextureView>(L, -1);
            texEntries[texCount].view = tv->view.get();
            lua_pop(L, 1);

            lua_pop(L, 1); // entry table
            texCount++;
        }
    }
    lua_pop(L, 1);
    desc.textures = texEntries;
    desc.textureCount = texCount;

    // Parse sampler entries
    BindGroupDesc::SampEntry sampEntries[MAX_ENTRIES];
    uint32_t sampCount = 0;

    lua_getfield(L, descIdx, "samplers");
    if (lua_istable(L, -1))
    {
        int tbl = lua_gettop(L);
        int n = (int)lua_objlen(L, tbl);
        for (int i = 0; i < n && i < MAX_ENTRIES; i++)
        {
            lua_rawgeti(L, tbl, i + 1);
            int entry = lua_gettop(L);

            sampEntries[sampCount].slot = static_cast<uint32_t>(
                lua_getoptionalnumberfield(L, entry, "slot", 0));
            if (sampEntries[sampCount].slot > 7)
            {
                luaL_error(
                    L,
                    "GPUBindGroup.new: sampler slot must be 0-7 (got %u)",
                    sampEntries[sampCount].slot);
            }

            lua_getfield(L, entry, "sampler");
            auto* ss = lua_torive<ScriptedGPUSampler>(L, -1);
            sampEntries[sampCount].sampler = ss->sampler.get();
            lua_pop(L, 1);

            lua_pop(L, 1); // entry table
            sampCount++;
        }
    }
    lua_pop(L, 1);
    desc.samplers = sampEntries;
    desc.samplerCount = sampCount;

    oreCtx->clearLastError();
    auto bindGroup = oreCtx->makeBindGroup(desc);
    if (!bindGroup)
    {
        if (!oreCtx->lastError().empty())
            luaL_error(L, "GPUBindGroup.new: %s", oreCtx->lastError().c_str());
        luaL_error(L, "GPUBindGroup.new: failed to create bind group");
    }

    auto* scripted = lua_newrive<ScriptedGPUBindGroup>(L);
    scripted->bindGroup = std::move(bindGroup);
    return 1;
}

// ============================================================================
// GPUPipeline
// ============================================================================

// Resolve a stage's entry on a shader by optional WGSL name. Errors (listing
// available names) if a named entry is missing.
static void resolveShaderEntry(lua_State* L,
                               ScriptedShader* shader,
                               uint8_t stage,
                               const char* entryReq,
                               const char* stageName,
                               ore::ShaderModule** outModule,
                               std::string* outEntryName)
{
    const ScriptedShaderEntry* e = shader->resolveEntry(stage, entryReq);
    if (e == nullptr)
    {
        std::string avail;
        for (const auto& rec : shader->entries)
        {
            if (rec.stage != stage)
                continue;
            if (!avail.empty())
                avail += ", ";
            avail += rec.logical;
        }
        if (entryReq != nullptr && entryReq[0] != '\0')
            luaL_error(L,
                       "GPUPipeline.new: %s entry point '%s' not found "
                       "(available: %s)",
                       stageName,
                       entryReq,
                       avail.empty() ? "<none>" : avail.c_str());
        luaL_error(L,
                   "GPUPipeline.new: %s shader has no %s entry point",
                   stageName,
                   stageName);
    }
    *outModule = e->module.get();
    *outEntryName = e->physical;
}

// Parse a pipeline stage descriptor at stack index `valueIdx`: a bare Shader or
// WebGPU-style { module = Shader, entryPoint = string? }. Omitting entryPoint
// selects the first entry of that stage. Returns the ScriptedShader (for the
// combined-file fragment fallback) plus the resolved module + physical entry
// name. Returns false only when the value is nil.
static bool resolveStageEntry(lua_State* L,
                              int valueIdx,
                              uint8_t stage,
                              const char* stageName,
                              ScriptedShader** outShader,
                              ore::ShaderModule** outModule,
                              std::string* outEntryName)
{
    if (lua_isnil(L, valueIdx))
        return false;
    ScriptedShader* shader = nullptr;
    const char* entryReq = nullptr;
    if (lua_istable(L, valueIdx))
    {
        lua_getfield(L, valueIdx, "module");
        shader = lua_torive<ScriptedShader>(L, -1);
        lua_pop(L, 1);
        entryReq = lua_getoptionalstringfield(L, valueIdx, "entryPoint");
    }
    else
    {
        shader = lua_torive<ScriptedShader>(L, valueIdx);
    }
    if (shader == nullptr || !shader->hasModule())
        luaL_error(L,
                   "GPUPipeline.new: '%s' must be a Shader or "
                   "{ module = Shader, entryPoint = string? }",
                   stageName);
    resolveShaderEntry(L,
                       shader,
                       stage,
                       entryReq,
                       stageName,
                       outModule,
                       outEntryName);
    if (outShader)
        *outShader = shader;
    return true;
}

static int gpupipeline_construct(lua_State* L)
{
    if (getOreContext(L) == nullptr)
    {
        luaL_error(L, "GPU context not initialized");
    }

    luaL_checktype(L, 1, LUA_TTABLE);
    int descIdx = 1;

    PipelineDesc desc;

    // vertex / fragment accept a bare Shader or WebGPU-style
    // { module = Shader, entryPoint = string? }. Omitting entryPoint selects
    // the first @vertex/@fragment of the module (WebGPU default). The resolved
    // physical entry names are held in these std::strings, which must outlive
    // the makePipeline call below (PipelineDesc keeps const char* into them).
    std::string vsEntryName, fsEntryName;
    ScriptedShader* vsShader = nullptr;

    // vertex shader (required)
    lua_getfield(L, descIdx, "vertex");
    {
        ore::ShaderModule* mod = nullptr;
        if (!resolveStageEntry(L,
                               lua_gettop(L),
                               0,
                               "vertex",
                               &vsShader,
                               &mod,
                               &vsEntryName))
            luaL_error(L, "GPUPipeline.new: 'vertex' is required");
        desc.vertexModule = mod;
        desc.vertexEntryPoint = vsEntryName.c_str();
    }
    lua_pop(L, 1);

    // fragment shader. Three cases:
    //   * explicit `fragment` → use it.
    //   * absent + at least one colorTarget → fall back to the vertex shader's
    //     fragment entry (combined file). Deferred until colorTargets parsed.
    //   * absent + no colorTargets → depth-only pipeline, no fragment.
    bool explicitFragment = false;
    lua_getfield(L, descIdx, "fragment");
    if (!lua_isnil(L, -1))
    {
        ore::ShaderModule* mod = nullptr;
        ScriptedShader* fsShader = nullptr;
        resolveStageEntry(L,
                          lua_gettop(L),
                          1,
                          "fragment",
                          &fsShader,
                          &mod,
                          &fsEntryName);
        desc.fragmentModule = mod;
        desc.fragmentEntryPoint = fsEntryName.c_str();
        explicitFragment = true;
    }
    lua_pop(L, 1);

    // vertexLayout (required)
    lua_getfield(L, descIdx, "vertexLayout");
    luaL_checktype(L, -1, LUA_TTABLE);
    int layoutTableIdx = lua_gettop(L);
    int vbCount = (int)lua_objlen(L, layoutTableIdx);

    // Stack-allocate vertex buffer layouts and attributes
    static constexpr int MAX_VB = 8;
    static constexpr int MAX_ATTRS = 32;
    VertexBufferLayout vbLayouts[MAX_VB];
    VertexAttribute attrs[MAX_ATTRS];
    int totalAttrs = 0;

    for (int vb = 0; vb < vbCount && vb < MAX_VB; vb++)
    {
        lua_rawgeti(L, layoutTableIdx, vb + 1);
        int vbIdx = lua_gettop(L);

        vbLayouts[vb].stride = static_cast<uint32_t>(
            lua_getoptionalnumberfield(L, vbIdx, "stride", 0));

        const char* stepMode = lua_getoptionalstringfield(L, vbIdx, "stepMode");
        if (stepMode && strcmp(stepMode, "instance") == 0)
            vbLayouts[vb].stepMode = VertexStepMode::instance;
        else
            vbLayouts[vb].stepMode = VertexStepMode::vertex;

        lua_getfield(L, vbIdx, "attributes");
        int attrTableIdx = lua_gettop(L);
        int attrCount = (int)lua_objlen(L, attrTableIdx);

        vbLayouts[vb].attributes = &attrs[totalAttrs];
        vbLayouts[vb].attributeCount = attrCount;

        for (int a = 0; a < attrCount && totalAttrs < MAX_ATTRS; a++)
        {
            lua_rawgeti(L, attrTableIdx, a + 1);
            int attrIdx = lua_gettop(L);

            const char* fmt = lua_getoptionalstringfield(L, attrIdx, "format");
            if (fmt)
                attrs[totalAttrs].format = lua_tovertexformat(L, fmt);

            attrs[totalAttrs].shaderSlot = static_cast<uint32_t>(
                lua_getoptionalnumberfield(L, attrIdx, "slot", 0));
            attrs[totalAttrs].offset = static_cast<uint32_t>(
                lua_getoptionalnumberfield(L, attrIdx, "offset", 0));

            totalAttrs++;
            lua_pop(L, 1); // pop attr entry
        }
        lua_pop(L, 1); // pop attributes table
        lua_pop(L, 1); // pop vb entry
    }
    lua_pop(L, 1); // pop vertexLayout table

    // colorTargets (optional). WebGPU-shaped: omitting it means "no color
    // outputs" (depth-only pipeline, e.g. shadow map). We override the C++
    // PipelineDesc default of colorCount=1 so that scripts don't get a
    // phantom color target that mismatches a depth-only render pass.
    desc.colorCount = 0;
    lua_getfield(L, descIdx, "colorTargets");
    if (lua_istable(L, -1))
    {
        int ctTableIdx = lua_gettop(L);
        int ctCount = (int)lua_objlen(L, ctTableIdx);
        constexpr int kMaxColorTargets =
            sizeof(desc.colorTargets) / sizeof(desc.colorTargets[0]);
        if (ctCount > kMaxColorTargets)
        {
            luaL_error(L,
                       "GPUPipeline.new: colorTargets count %d exceeds "
                       "maximum of %d",
                       ctCount,
                       kMaxColorTargets);
        }
        desc.colorCount = ctCount;

        for (int ct = 0; ct < ctCount; ct++)
        {
            lua_rawgeti(L, ctTableIdx, ct + 1);
            int ctIdx = lua_gettop(L);

            const char* fmt = lua_getoptionalstringfield(L, ctIdx, "format");
            if (fmt)
                desc.colorTargets[ct].format = lua_totextureformat(L, fmt);

            // writeMask: optional. String like "rgba" / "rg" / "" / "all".
            // Default (when absent) is `ColorWriteMask::all` from PipelineDesc.
            const char* wm = lua_getoptionalstringfield(L, ctIdx, "writeMask");
            if (wm)
                desc.colorTargets[ct].writeMask = lua_towritemask(L, wm);

            lua_getfield(L, ctIdx, "blend");
            if (lua_istable(L, -1))
            {
                int blendIdx = lua_gettop(L);
                desc.colorTargets[ct].blendEnabled = true;
                const char* s;

                s = lua_getoptionalstringfield(L, blendIdx, "srcColor");
                if (s)
                    desc.colorTargets[ct].blend.srcColor =
                        lua_toblendfactor(L, s);
                s = lua_getoptionalstringfield(L, blendIdx, "dstColor");
                if (s)
                    desc.colorTargets[ct].blend.dstColor =
                        lua_toblendfactor(L, s);
                s = lua_getoptionalstringfield(L, blendIdx, "colorOp");
                if (s)
                    desc.colorTargets[ct].blend.colorOp = lua_toblendop(L, s);
                s = lua_getoptionalstringfield(L, blendIdx, "srcAlpha");
                if (s)
                    desc.colorTargets[ct].blend.srcAlpha =
                        lua_toblendfactor(L, s);
                s = lua_getoptionalstringfield(L, blendIdx, "dstAlpha");
                if (s)
                    desc.colorTargets[ct].blend.dstAlpha =
                        lua_toblendfactor(L, s);
                s = lua_getoptionalstringfield(L, blendIdx, "alphaOp");
                if (s)
                    desc.colorTargets[ct].blend.alphaOp = lua_toblendop(L, s);
            }
            lua_pop(L, 1); // pop blend
            lua_pop(L, 1); // pop color target entry
        }
    }
    lua_pop(L, 1); // pop colorTargets

    // Resolve the deferred fragment-module decision (see "fragment shader"
    // block above). With color outputs but no explicit fragment shader, fall
    // back to the vertex shader's first fragment entry (combined file).
    if (!explicitFragment && desc.colorCount > 0)
    {
        ore::ShaderModule* mod = nullptr;
        resolveShaderEntry(L,
                           vsShader,
                           1,
                           nullptr,
                           "fragment",
                           &mod,
                           &fsEntryName);
        desc.fragmentModule = mod;
        desc.fragmentEntryPoint = fsEntryName.c_str();
    }

    // depthStencil (optional)
    lua_getfield(L, descIdx, "depthStencil");
    if (lua_istable(L, -1))
    {
        int dsIdx = lua_gettop(L);
        const char* fmt = lua_getoptionalstringfield(L, dsIdx, "format");
        if (fmt)
            desc.depthStencil.format = lua_totextureformat(L, fmt);
        const char* cmp = lua_getoptionalstringfield(L, dsIdx, "compare");
        if (cmp)
            desc.depthStencil.depthCompare = lua_tocompare(L, cmp);
        desc.depthStencil.depthWriteEnabled =
            lua_getoptionalboolfield(L, dsIdx, "write", false);
        desc.depthStencil.depthBias = static_cast<int32_t>(
            lua_getoptionalnumberfield(L, dsIdx, "depthBias", 0));
        desc.depthStencil.depthBiasSlopeScale = static_cast<float>(
            lua_getoptionalnumberfield(L, dsIdx, "depthBiasSlopeScale", 0));
        desc.depthStencil.depthBiasClamp = static_cast<float>(
            lua_getoptionalnumberfield(L, dsIdx, "depthBiasClamp", 0));
    }
    lua_pop(L, 1);

    // stencilFront / stencilBack (optional, both default to "always pass,
    // keep on every op"). Each is a table of compare + failOp + depthFailOp
    // + passOp strings.
    lua_getfield(L, descIdx, "stencilFront");
    lua_tostencilface(L, lua_gettop(L), &desc.stencilFront);
    lua_pop(L, 1);
    lua_getfield(L, descIdx, "stencilBack");
    lua_tostencilface(L, lua_gettop(L), &desc.stencilBack);
    lua_pop(L, 1);

    // stencilReadMask / stencilWriteMask (optional, default 0xFF).
    desc.stencilReadMask = static_cast<uint8_t>(
        lua_getoptionalnumberfield(L, descIdx, "stencilReadMask", 0xFF));
    desc.stencilWriteMask = static_cast<uint8_t>(
        lua_getoptionalnumberfield(L, descIdx, "stencilWriteMask", 0xFF));

    // bindGroupLayouts (optional). When absent, derive layouts per
    // @group(N) from the shader's binding map (WebGPU's `layout: 'auto'`).
    // Supply explicitly to share one layout across multiple pipelines.
    BindGroupLayout* layoutPtrs[ore::kMaxBindGroups] = {};
    uint32_t layoutCount = 0;
    std::vector<rcp<BindGroupLayout>> autoLayouts;
    lua_getfield(L, descIdx, "bindGroupLayouts");
    bool explicitLayouts = lua_istable(L, -1);
    if (explicitLayouts)
    {
        int blglIdx = lua_gettop(L);
        int n = (int)lua_objlen(L, blglIdx);
        if (n > static_cast<int>(ore::kMaxBindGroups))
        {
            luaL_error(L,
                       "GPUPipeline.new: bindGroupLayouts count %d exceeds "
                       "maximum of %u",
                       n,
                       ore::kMaxBindGroups);
        }
        for (int i = 0; i < n; ++i)
        {
            lua_rawgeti(L, blglIdx, i + 1);
            auto* l = lua_torive<ScriptedGPUBindGroupLayout>(L, -1);
            layoutPtrs[i] = l ? l->layout.get() : nullptr;
            lua_pop(L, 1);
        }
        layoutCount = static_cast<uint32_t>(n);
    }
    lua_pop(L, 1);
    if (!explicitLayouts)
    {
        // Auto path: scan the binding map for unique groups, build a
        // layout per group. Sparse-group shaders are supported (e.g.
        // group 0 + group 2 → autoLayouts[1] is null/empty).
        const BindingMap& bm = vsShader->vertexMod()->m_bindingMap;
        uint32_t maxGroup = 0;
        bool seen[ore::kMaxBindGroups] = {};
        for (size_t i = 0; i < bm.size(); ++i)
        {
            uint32_t g = bm.at(i).group;
            if (g >= ore::kMaxBindGroups)
                continue;
            seen[g] = true;
            if (g + 1 > maxGroup)
                maxGroup = g + 1;
        }
        autoLayouts.resize(maxGroup);
        static constexpr int kMaxEntries = 16;
        for (uint32_t g = 0; g < maxGroup; ++g)
        {
            if (!seen[g])
                continue;
            BindGroupLayoutEntry entries[kMaxEntries]{};
            uint32_t n = populateEntriesFromShader(entries,
                                                   kMaxEntries,
                                                   vsShader->vertexMod(),
                                                   g,
                                                   nullptr,
                                                   0);
            BindGroupLayoutDesc lDesc;
            lDesc.groupIndex = g;
            lDesc.entries = entries;
            lDesc.entryCount = n;
            autoLayouts[g] = getOreContext(L)->makeBindGroupLayout(lDesc);
            layoutPtrs[g] = autoLayouts[g].get();
        }
        layoutCount = maxGroup;
    }
    desc.bindGroupLayouts = layoutPtrs;
    desc.bindGroupLayoutCount = layoutCount;

    // cullMode (optional)
    const char* cull = lua_getoptionalstringfield(L, descIdx, "cullMode");
    if (cull)
        desc.cullMode = lua_tocullmode(L, cull);

    // winding (optional, default counterClockwise)
    const char* wind = lua_getoptionalstringfield(L, descIdx, "winding");
    if (wind)
        desc.winding = lua_towinding(L, wind);

    // topology (optional)
    const char* topo = lua_getoptionalstringfield(L, descIdx, "topology");
    if (topo)
        desc.topology = lua_totopology(L, topo);

    // sampleCount (optional, default 1)
    uint32_t pipelineSampleCount = static_cast<uint32_t>(
        lua_getoptionalnumberfield(L, descIdx, "sampleCount", 1));
    desc.sampleCount = pipelineSampleCount;

    // Allocate the ScriptedGPUPipeline first so we can deep-copy the vertex
    // layout data into it. Pipeline shallow-copies PipelineDesc, so the
    // vertex buffer layout pointers must outlive the Pipeline.
    auto* scripted = lua_newrive<ScriptedGPUPipeline>(L);

    // Deep-copy layouts and attributes into a single byte buffer:
    //   [ VertexBufferLayout[vbCount] ][ VertexAttribute[totalAttrs] ]
    size_t layoutBytes = sizeof(VertexBufferLayout) * vbCount;
    size_t attrBytes = sizeof(VertexAttribute) * totalAttrs;
    scripted->ownedVertexLayoutData.resize(layoutBytes + attrBytes);

    auto* ownedLayouts = reinterpret_cast<VertexBufferLayout*>(
        scripted->ownedVertexLayoutData.data());
    auto* ownedAttrs = reinterpret_cast<VertexAttribute*>(
        scripted->ownedVertexLayoutData.data() + layoutBytes);

    memcpy(ownedLayouts, vbLayouts, layoutBytes);
    memcpy(ownedAttrs, attrs, attrBytes);

    // Patch each layout's attributes pointer to point into the owned copy.
    int attrOffset = 0;
    for (int vb = 0; vb < vbCount; vb++)
    {
        ownedLayouts[vb].attributes = ownedAttrs + attrOffset;
        attrOffset += ownedLayouts[vb].attributeCount;
    }

    desc.vertexBuffers = ownedLayouts;
    desc.vertexBufferCount = vbCount;

    std::string pipelineError;
    auto pipeline = getOreContext(L)->makePipeline(desc, &pipelineError);
    if (!pipeline)
    {
        if (pipelineError.empty())
            luaL_error(L, "GPUPipeline.new: failed to create pipeline");
        else
            luaL_error(L, "GPUPipeline.new: %s", pipelineError.c_str());
    }

    scripted->pipeline = std::move(pipeline);
    scripted->sampleCount = pipelineSampleCount;
    scripted->autoBindGroupLayouts = std::move(autoLayouts);
    return 1;
}

// pipeline:getBindGroupLayout(groupIndex) — returns an auto-derived layout
// (WebGPU's pipeline.getBindGroupLayout). Errors when explicit layouts were
// supplied — share the explicit one directly instead.
static int gpupipeline_getbindgrouplayout(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPUPipeline>(L, 1);
    uint32_t group = static_cast<uint32_t>(luaL_checkunsigned(L, 2));
    if (self->autoBindGroupLayouts.empty())
        luaL_error(L,
                   "getBindGroupLayout: pipeline was built with explicit "
                   "bindGroupLayouts; reuse the layout you supplied");
    if (group >= self->autoBindGroupLayouts.size() ||
        !self->autoBindGroupLayouts[group])
        luaL_error(L,
                   "getBindGroupLayout: group %u not present in shader",
                   group);
    auto* w = lua_newrive<ScriptedGPUBindGroupLayout>(L);
    w->layout = self->autoBindGroupLayouts[group];
    return 1;
}

static int gpupipeline_namecall(lua_State* L)
{
    int atom;
    const char* method = lua_namecallatom(L, &atom);
    if (method == nullptr)
        luaL_error(L, "GPUPipeline: no method specified");
    if (strcmp(method, "getBindGroupLayout") == 0)
        return gpupipeline_getbindgrouplayout(L);
    luaL_error(L, "GPUPipeline: unknown method '%s'", method);
    return 0;
}

// ============================================================================
// GPURenderPass
// ============================================================================

static void validate_render_pass(lua_State* L, ScriptedGPURenderPass* self)
{
    // pass->isFinished() catches the case where a *previous*
    // beginRenderPass auto-finished this pass (because the script forgot
    // to :finish() before opening the next one). The wrapper's own
    // m_finished is still false there.
    if (self->m_finished || !self->pass || self->pass->isFinished())
    {
        luaL_error(L,
                   "render pass expired — already finished, or auto-"
                   "finished by a subsequent beginRenderPass");
    }
}

static void validate_pipeline_set(lua_State* L, ScriptedGPURenderPass* self)
{
    if (!self->m_pipelineSet)
    {
        luaL_error(L,
                   "setPipeline must be called before draw/setVertexBuffer/"
                   "setBindGroup");
    }
}

static int gpurenderpass_setpipeline(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPURenderPass>(L, 1);
    validate_render_pass(L, self);
    auto* pipeline = lua_torive<ScriptedGPUPipeline>(L, 2);
    if (pipeline->sampleCount != self->sampleCount)
    {
        luaL_error(L,
                   "pipeline sampleCount (%u) does not match render pass "
                   "sampleCount (%u) — recreate the pipeline with matching "
                   "sampleCount",
                   pipeline->sampleCount,
                   self->sampleCount);
    }
    // Capture any attachment-compat failure from ore::RenderPass::setPipeline.
    // Without this, checkPipelineCompat failures silently no-op the Metal
    // encoder state and subsequent draws crash inside the driver.
    Context* oreCtx = getOreContext(L);
    if (oreCtx)
        oreCtx->clearLastError();
    self->pass->setPipeline(pipeline->pipeline.get());
    if (oreCtx && !oreCtx->lastError().empty())
    {
        luaL_error(L, "setPipeline: %s", oreCtx->lastError().c_str());
    }
    self->m_pipelineSet = true;
    return 0;
}

static int gpurenderpass_setvertexbuffer(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPURenderPass>(L, 1);
    validate_render_pass(L, self);
    // Note: WebGPU / Metal / Vulkan / D3D11 all permit `setVertexBuffer`
    // before `setPipeline` — vertex-buffer state is layered onto whatever
    // pipeline is current at draw time. Don't gate on `m_pipelineSet`.
    uint32_t slot = static_cast<uint32_t>(luaL_checkunsigned(L, 2));
    if (slot > 7)
    {
        luaL_error(L, "setVertexBuffer: slot must be 0-7 (got %u)", slot);
    }
    auto* buffer = lua_torive<ScriptedGPUBuffer>(L, 3);
    self->pass->setVertexBuffer(slot, buffer->buffer.get());
    return 0;
}

static int gpurenderpass_setindexbuffer(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPURenderPass>(L, 1);
    validate_render_pass(L, self);
    auto* buffer = lua_torive<ScriptedGPUBuffer>(L, 2);
    IndexFormat fmt = IndexFormat::uint16;
    if (lua_isstring(L, 3))
    {
        const char* s = lua_tostring(L, 3);
        if (strcmp(s, "uint32") == 0)
            fmt = IndexFormat::uint32;
    }
    self->pass->setIndexBuffer(buffer->buffer.get(), fmt);
    return 0;
}

static int gpurenderpass_setbindgroup(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPURenderPass>(L, 1);
    validate_render_pass(L, self);
    uint32_t groupIndex = static_cast<uint32_t>(luaL_checkunsigned(L, 2));
    if (groupIndex >= ore::kMaxBindGroups)
    {
        luaL_error(L,
                   "setBindGroup: groupIndex must be in [0, %u) (got %u)",
                   ore::kMaxBindGroups,
                   groupIndex);
    }
    auto* bg = lua_torive<ScriptedGPUBindGroup>(L, 3);

    // Parse optional dynamic offsets array.
    //
    // WebGPU contract: `dynamicOffsets[i]` corresponds to the i-th dynamic
    // entry in the BindGroupLayout, ordered by ascending `@binding`.
    // The count must equal the BindGroup's dynamic-offset count exactly,
    // and each value must be aligned to `minUniformBufferOffsetAlignment`
    // (256 bytes — D3D11.1's `firstConstant` requirement, D3D12's CBV
    // alignment, Vulkan's adapter-default minimum). Validate here so a
    // misuse error surfaces on the Lua call site instead of a backend
    // assert / silent misbind.
    constexpr uint32_t kDynamicOffsetAlign = 256;
    uint32_t dynamicOffsets[8] = {};
    uint32_t dynamicOffsetCount = 0;
    if (lua_istable(L, 4))
    {
        int tbl = 4;
        int n = (int)lua_objlen(L, tbl);
        if (n > 8)
        {
            luaL_error(L,
                       "setBindGroup: dynamicOffsets count %d exceeds "
                       "maximum of 8",
                       n);
        }
        for (int i = 0; i < n; i++)
        {
            lua_rawgeti(L, tbl, i + 1);
            uint32_t off = static_cast<uint32_t>(lua_tonumber(L, -1));
            lua_pop(L, 1);
            if ((off % kDynamicOffsetAlign) != 0)
            {
                luaL_error(L,
                           "setBindGroup: dynamicOffsets[%d] = %u is not a "
                           "multiple of %u (alignment requirement)",
                           i,
                           off,
                           kDynamicOffsetAlign);
            }
            dynamicOffsets[dynamicOffsetCount++] = off;
        }
    }

    if (bg->bindGroup &&
        dynamicOffsetCount != bg->bindGroup->dynamicOffsetCount())
    {
        luaL_error(L,
                   "setBindGroup: dynamicOffsets count %u does not match the "
                   "BindGroup's declared dynamic UBO count %u",
                   dynamicOffsetCount,
                   bg->bindGroup->dynamicOffsetCount());
    }

    self->pass->setBindGroup(groupIndex,
                             bg->bindGroup.get(),
                             dynamicOffsetCount > 0 ? dynamicOffsets : nullptr,
                             dynamicOffsetCount);
    return 0;
}

static int gpurenderpass_setviewport(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPURenderPass>(L, 1);
    validate_render_pass(L, self);
    float x = static_cast<float>(luaL_checknumber(L, 2));
    float y = static_cast<float>(luaL_checknumber(L, 3));
    float w = static_cast<float>(luaL_checknumber(L, 4));
    float h = static_cast<float>(luaL_checknumber(L, 5));
    self->pass->setViewport(x, y, w, h);
    return 0;
}

static int gpurenderpass_setscissorrect(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPURenderPass>(L, 1);
    validate_render_pass(L, self);
    uint32_t x = static_cast<uint32_t>(luaL_checkunsigned(L, 2));
    uint32_t y = static_cast<uint32_t>(luaL_checkunsigned(L, 3));
    uint32_t w = static_cast<uint32_t>(luaL_checkunsigned(L, 4));
    uint32_t h = static_cast<uint32_t>(luaL_checkunsigned(L, 5));
    self->pass->setScissorRect(x, y, w, h);
    return 0;
}

static int gpurenderpass_setstencilreference(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPURenderPass>(L, 1);
    validate_render_pass(L, self);
    uint32_t ref = static_cast<uint32_t>(luaL_checkunsigned(L, 2));
    self->pass->setStencilReference(ref);
    return 0;
}

static int gpurenderpass_setblendcolor(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPURenderPass>(L, 1);
    validate_render_pass(L, self);
    float r = static_cast<float>(luaL_checknumber(L, 2));
    float g = static_cast<float>(luaL_checknumber(L, 3));
    float b = static_cast<float>(luaL_checknumber(L, 4));
    float a = static_cast<float>(luaL_checknumber(L, 5));
    self->pass->setBlendColor(r, g, b, a);
    return 0;
}

// `pass:draw(vertexCount [, instanceCount [, firstVertex
//                       [, firstInstance]]])`
static int gpurenderpass_draw(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPURenderPass>(L, 1);
    validate_render_pass(L, self);
    validate_pipeline_set(L, self);
    uint32_t vertexCount = static_cast<uint32_t>(luaL_checkunsigned(L, 2));
    uint32_t instanceCount =
        lua_isnumber(L, 3) ? static_cast<uint32_t>(lua_tonumber(L, 3)) : 1;
    uint32_t firstVertex =
        lua_isnumber(L, 4) ? static_cast<uint32_t>(lua_tonumber(L, 4)) : 0;
    uint32_t firstInstance =
        lua_isnumber(L, 5) ? static_cast<uint32_t>(lua_tonumber(L, 5)) : 0;
    if (firstInstance > 0 && features_are_known(getOreContext(L)) &&
        !getOreContext(L)->features().drawBaseInstance)
    {
        luaL_error(L,
                   "draw: firstInstance=%u requires the drawBaseInstance "
                   "feature, which the active backend does not support",
                   firstInstance);
    }
    self->pass->draw(vertexCount, instanceCount, firstVertex, firstInstance);
    self->drawCallCount++;
    return 0;
}

// `pass:drawIndexed(indexCount [, instanceCount [, firstIndex
//                                [, baseVertex [, firstInstance]]]])`
static int gpurenderpass_drawindexed(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPURenderPass>(L, 1);
    validate_render_pass(L, self);
    validate_pipeline_set(L, self);
    uint32_t indexCount = static_cast<uint32_t>(luaL_checkunsigned(L, 2));
    uint32_t instanceCount =
        lua_isnumber(L, 3) ? static_cast<uint32_t>(lua_tonumber(L, 3)) : 1;
    uint32_t firstIndex =
        lua_isnumber(L, 4) ? static_cast<uint32_t>(lua_tonumber(L, 4)) : 0;
    int32_t baseVertex =
        lua_isnumber(L, 5) ? static_cast<int32_t>(lua_tointeger(L, 5)) : 0;
    uint32_t firstInstance =
        lua_isnumber(L, 6) ? static_cast<uint32_t>(lua_tonumber(L, 6)) : 0;
    if (baseVertex != 0 && features_are_known(getOreContext(L)) &&
        !getOreContext(L)->features().drawBaseInstance)
    {
        luaL_error(L,
                   "drawIndexed: baseVertex=%d requires the "
                   "drawBaseInstance feature, which the active backend "
                   "does not support",
                   baseVertex);
    }
    if (firstInstance > 0 && features_are_known(getOreContext(L)) &&
        !getOreContext(L)->features().drawBaseInstance)
    {
        luaL_error(L,
                   "drawIndexed: firstInstance=%u requires the "
                   "drawBaseInstance feature, which the active backend "
                   "does not support",
                   firstInstance);
    }
    self->pass->drawIndexed(indexCount,
                            instanceCount,
                            firstIndex,
                            baseVertex,
                            firstInstance);
    self->drawCallCount++;
    return 0;
}

static int gpurenderpass_finish(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPURenderPass>(L, 1);
    validate_render_pass(L, self);
    self->pass->finish();
    self->m_finished = true;
    // Clear the context's active pass pointer so the next beginRenderPass
    // doesn't see a stale (already-finished) pass.
    Context* oreCtx = getOreContext(L);
    if (oreCtx && oreCtx->activeRenderPass() == self->pass.get())
        oreCtx->setActiveRenderPass(nullptr);
    return 0;
}

static int gpurenderpass_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::setPipeline:
                return gpurenderpass_setpipeline(L);
            case (int)LuaAtoms::setVertexBuffer:
                return gpurenderpass_setvertexbuffer(L);
            case (int)LuaAtoms::setIndexBuffer:
                return gpurenderpass_setindexbuffer(L);
            case (int)LuaAtoms::setBindGroup:
                return gpurenderpass_setbindgroup(L);
            case (int)LuaAtoms::setViewport:
                return gpurenderpass_setviewport(L);
            case (int)LuaAtoms::setScissorRect:
                return gpurenderpass_setscissorrect(L);
            case (int)LuaAtoms::setStencilReference:
                return gpurenderpass_setstencilreference(L);
            case (int)LuaAtoms::setBlendColor:
                return gpurenderpass_setblendcolor(L);
            case (int)LuaAtoms::draw:
                return gpurenderpass_draw(L);
            case (int)LuaAtoms::drawIndexed:
                return gpurenderpass_drawindexed(L);
            case (int)LuaAtoms::finish:
                return gpurenderpass_finish(L);
        }
    }
    luaL_error(L,
               "%s is not a valid method of %s",
               str,
               ScriptedGPURenderPass::luaName);
    return 0;
}

// ============================================================================
// ScriptedGPUCanvas / ScriptedCanvas — destructors
// ============================================================================

ScriptedGPUCanvas::~ScriptedGPUCanvas()
{
    if (m_L != nullptr && m_imageRef != LUA_NOREF)
    {
        lua_unref(m_L, m_imageRef);
    }
}

ScriptedGPURenderPass::~ScriptedGPURenderPass()
{
    // If the script GC'd the wrapper without :finish(), drop the active-
    // pass slot before unique_ptr destroys the backend RenderPass — else
    // ore::Context::activeRenderPass() would dangle into the next
    // beginRenderPass.
    if (m_context && pass && m_context->activeRenderPass() == pass.get())
    {
        m_context->setActiveRenderPass(nullptr);
    }
}

ScriptedCanvas::~ScriptedCanvas()
{
    // Clean up any active frame renderer that was never ended
    delete m_riveRenderer;
    m_riveRenderer = nullptr;
    if (m_L != nullptr)
    {
        if (m_rendererRef != LUA_NOREF)
            lua_unref(m_L, m_rendererRef);
        if (m_imageRef != LUA_NOREF)
            lua_unref(m_L, m_imageRef);
    }
}

// ============================================================================
// GPUCanvas
// ============================================================================

static LoadOp lua_toloadop_str(const char* s)
{
    if (strcmp(s, "load") == 0)
        return LoadOp::load;
    return LoadOp::clear;
}

static StoreOp lua_tostoreop_str(const char* s)
{
    if (strcmp(s, "discard") == 0)
        return StoreOp::discard;
    return StoreOp::store;
}

// canvas:beginRenderPass(desc) — open a render pass against this canvas.
//
// `desc` is required: at least one color attachment or a depthStencil
// attachment must be supplied. Every attachment carries its own view, and
// sampleCount is derived from those views (all attachments must share one
// sampleCount, matching WebGPU validation).
//
// Color attachment `view` is optional: when omitted it defaults to the
// receiving canvas's own colorView. Provide an explicit view for cases
// where the target differs (e.g. MSAA: view = msaa:view(),
// resolveTarget = canvas:colorView()).
int gpucanvas_beginrenderpass(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPUCanvas>(L, 1);

    Context* oreCtx = getOreContext(L);
    if (oreCtx == nullptr)
    {
        luaL_error(L, "GPUCanvas:beginRenderPass() requires a GPU context");
    }

    auto* scriptingContext =
        static_cast<ScriptingContext*>(lua_getthreaddata(L));
    // Recording brackets the pass; an immediate context cannot nest a pass
    // inside the open screen frame.
    if (scriptingContext == nullptr || !oreCtx->isRecording())
    {
        luaL_error(L,
                   "GPUCanvas:beginRenderPass() requires the deferred "
                   "recorder");
    }

    luaL_checktype(L, 2, LUA_TTABLE);

    RenderPassDesc passDesc{};
    passDesc.colorCount = 0;

    // Tracks the first attachment we see (any color slot or depth) and
    // becomes the pass's authoritative sampleCount. Subsequent attachments
    // must match. -1 means "not yet seen any attachment". The label owns
    // its storage so per-iteration stack buffers don't dangle into the
    // error path.
    int32_t passSampleCount = -1;
    std::string sampleCountSourceLabel;

    auto recordSampleCount = [&](uint32_t sc, const char* label) {
        if (passSampleCount == -1)
        {
            passSampleCount = static_cast<int32_t>(sc);
            sampleCountSourceLabel = label;
        }
        else if (static_cast<uint32_t>(passSampleCount) != sc)
        {
            luaL_error(
                L,
                "beginRenderPass: %s sampleCount (%u) does not match %s "
                "sampleCount (%u). All render-pass attachments must share "
                "one sampleCount.",
                label,
                sc,
                sampleCountSourceLabel.c_str(),
                static_cast<uint32_t>(passSampleCount));
        }
    };

    lua_getfield(L, 2, "color");
    if (lua_istable(L, -1))
    {
        for (int ci = 1; ci <= 4; ++ci)
        {
            lua_rawgeti(L, -1, ci);
            if (!lua_istable(L, -1))
            {
                lua_pop(L, 1);
                break;
            }
            int slot = passDesc.colorCount++;

            lua_getfield(L, -1, "view");
            ore::TextureView* viewPtr = nullptr;
            if (lua_isnil(L, -1))
            {
                // Sugar: omitting `view` defaults to the receiving canvas's
                // own colorView. Errors only if the canvas is deferred
                // (zero-sized — no backing texture).
                if (!self->oreColorView)
                {
                    luaL_error(L,
                               "beginRenderPass: color[%d].view omitted but "
                               "the receiving canvas has no backing texture "
                               "(zero-sized). Call canvas:resize(w, h) "
                               "before drawing, or pass an explicit view.",
                               slot + 1);
                }
                viewPtr = self->oreColorView.get();
            }
            else
            {
                auto* tv = lua_torive<ScriptedGPUTextureView>(L, -1);
                if (!tv || !tv->view)
                {
                    luaL_error(L,
                               "beginRenderPass: color[%d].view is not a "
                               "valid GPUTextureView",
                               slot + 1);
                }
                viewPtr = tv->view.get();
            }
            passDesc.colorAttachments[slot].view = viewPtr;
            char colorLabel[32];
            snprintf(colorLabel, sizeof(colorLabel), "color[%d]", slot + 1);
            recordSampleCount(viewPtr->texture()->sampleCount(), colorLabel);
            lua_pop(L, 1); // view

            // resolveTarget (optional — for MSAA). Source view must be
            // multisampled; resolve target must be sampleCount=1 and
            // format-matched to the source.
            lua_getfield(L, -1, "resolveTarget");
            if (!lua_isnil(L, -1))
            {
                auto* rtv = lua_torive<ScriptedGPUTextureView>(L, -1);
                if (rtv && rtv->view)
                {
                    auto* msaaTex =
                        passDesc.colorAttachments[slot].view
                            ? passDesc.colorAttachments[slot].view->texture()
                            : nullptr;
                    if (msaaTex && msaaTex->sampleCount() == 1)
                    {
                        luaL_error(
                            L,
                            "beginRenderPass: color[%d].resolveTarget is "
                            "meaningless when the source `view` is single-"
                            "sampled — drop it, or use an MSAA texture as "
                            "`view`",
                            slot + 1);
                    }
                    if (msaaTex &&
                        rtv->view->texture()->format() != msaaTex->format())
                    {
                        luaL_error(
                            L,
                            "beginRenderPass: resolveTarget format '%s' does "
                            "not match MSAA attachment format '%s' — resolve "
                            "requires identical formats. Use canvas.format to "
                            "match your pipeline and textures.",
                            lua_totextureformatstring(
                                rtv->view->texture()->format()),
                            lua_totextureformatstring(msaaTex->format()));
                    }
                    if (rtv->view->texture()->sampleCount() != 1)
                    {
                        luaL_error(L,
                                   "beginRenderPass: color[%d].resolveTarget "
                                   "must have sampleCount=1 (got %u)",
                                   slot + 1,
                                   rtv->view->texture()->sampleCount());
                    }
                    passDesc.colorAttachments[slot].resolveTarget =
                        rtv->view.get();
                }
            }
            lua_pop(L, 1); // resolveTarget

            lua_getfield(L, -1, "loadOp");
            if (!lua_isnil(L, -1))
            {
                passDesc.colorAttachments[slot].loadOp =
                    lua_toloadop_str(luaL_checkstring(L, -1));
            }
            else
            {
                passDesc.colorAttachments[slot].loadOp = LoadOp::clear;
            }
            lua_pop(L, 1); // loadOp

            lua_getfield(L, -1, "storeOp");
            if (lua_isnil(L, -1))
            {
                lua_pop(L, 1);
                luaL_error(L,
                           "beginRenderPass: color[%d].storeOp is required "
                           "— use 'discard' for MSAA color (after resolve) "
                           "or 'store' to keep the rendered output",
                           slot + 1);
            }
            passDesc.colorAttachments[slot].storeOp =
                lua_tostoreop_str(luaL_checkstring(L, -1));
            lua_pop(L, 1); // storeOp

            lua_getfield(L, -1, "clearColor");
            if (lua_istable(L, -1))
            {
                lua_rawgeti(L, -1, 1);
                passDesc.colorAttachments[slot].clearColor.r =
                    (float)lua_tonumber(L, -1);
                lua_pop(L, 1);
                lua_rawgeti(L, -1, 2);
                passDesc.colorAttachments[slot].clearColor.g =
                    (float)lua_tonumber(L, -1);
                lua_pop(L, 1);
                lua_rawgeti(L, -1, 3);
                passDesc.colorAttachments[slot].clearColor.b =
                    (float)lua_tonumber(L, -1);
                lua_pop(L, 1);
                lua_rawgeti(L, -1, 4);
                passDesc.colorAttachments[slot].clearColor.a =
                    (float)lua_tonumber(L, -1);
                lua_pop(L, 1);
            }
            lua_pop(L, 1); // clearColor
            lua_pop(L, 1); // entry table
        }
    }
    lua_pop(L, 1); // color

    lua_getfield(L, 2, "depthStencil");
    if (lua_istable(L, -1))
    {
        lua_getfield(L, -1, "view");
        if (lua_isnil(L, -1))
        {
            luaL_error(L,
                       "beginRenderPass: depthStencil.view is required — "
                       "pass GPUTexture:view()");
        }
        auto* tv = lua_torive<ScriptedGPUTextureView>(L, -1);
        if (!tv || !tv->view)
        {
            luaL_error(L,
                       "beginRenderPass: depthStencil.view is not a valid "
                       "GPUTextureView");
        }
        passDesc.depthStencil.view = tv->view.get();
        recordSampleCount(tv->view->texture()->sampleCount(), "depthStencil");
        lua_pop(L, 1); // view

        passDesc.depthStencil.depthLoadOp = LoadOp::clear;
        lua_getfield(L, -1, "depthLoadOp");
        if (!lua_isnil(L, -1))
        {
            passDesc.depthStencil.depthLoadOp =
                lua_toloadop_str(luaL_checkstring(L, -1));
        }
        lua_pop(L, 1);

        lua_getfield(L, -1, "depthStoreOp");
        if (lua_isnil(L, -1))
        {
            lua_pop(L, 1);
            luaL_error(L,
                       "beginRenderPass: depthStencil.depthStoreOp is "
                       "required — use 'discard' for transient/MSAA depth or "
                       "'store' if you need to read it later");
        }
        passDesc.depthStencil.depthStoreOp =
            lua_tostoreop_str(luaL_checkstring(L, -1));
        lua_pop(L, 1);

        lua_getfield(L, -1, "depthClearValue");
        if (!lua_isnil(L, -1))
        {
            passDesc.depthStencil.depthClearValue =
                static_cast<float>(lua_tonumber(L, -1));
        }
        lua_pop(L, 1);
    }
    lua_pop(L, 1); // depthStencil

    if (passDesc.colorCount == 0 && !passDesc.depthStencil.view)
    {
        luaL_error(L,
                   "beginRenderPass: descriptor must include at least one "
                   "color attachment or a depthStencil attachment");
    }

    // Metal (and other backends) only allow one active encoder per command
    // buffer. If a previous pass was left open, finish it before opening
    // a new encoder.
    if (oreCtx->activeRenderPass() && !oreCtx->activeRenderPass()->isFinished())
    {
        oreCtx->activeRenderPass()->finish();
        oreCtx->setActiveRenderPass(nullptr);
    }

    auto* rp = lua_newrive<ScriptedGPURenderPass>(L);
    // Records in deferred mode, returns the live backend pass in immediate.
    rp->pass = ore::cmd::beginRenderPassRecordingOrImmediate(*oreCtx, passDesc);
    rp->m_context = oreCtx;
    rp->m_finished = false;
    rp->sampleCount =
        passSampleCount < 1 ? 1u : static_cast<uint32_t>(passSampleCount);
    rp->label = passDesc.label ? passDesc.label : "";
    rp->drawCallCount = 0;
    oreCtx->setActiveRenderPass(rp->pass.get());
    return 1;
}

rcp<gpu::RenderCanvas> rive::allocScriptRenderCanvas(gpu::RenderContext* rc,
                                                     ScriptingContext* ctx,
                                                     uint32_t width,
                                                     uint32_t height)
{
    assert(rc != nullptr);
    assert(ctx != nullptr);
    if (ctx->deferredCanvasHost() != nullptr || ctx->renderContextIsLateBound())
    {
        return rc->makeDeferredRenderCanvas(width, height);
    }
    return rc->makeRenderCanvas(width, height);
}

// The device a canvas should allocate against right now, which is not
// necessarily the one that existed when the handle was made: web builds one per
// render texture and attaches it after the file has imported.
static gpu::RenderContext* liveRenderContext(ScriptingContext* scriptingCtx)
{
    if (scriptingCtx == nullptr)
    {
        return nullptr;
    }
    return static_cast<gpu::RenderContext*>(scriptingCtx->renderContext());
}

// Allocates the backing for a pending size, if there is one and a device has
// turned up to allocate it against. Errors only on a device that is present and
// refuses; a device that has not arrived yet leaves the request pending, which
// is what makes a size-less canvas usable on a host that attaches late.
static void gpucanvas_satisfyPending(lua_State* L, ScriptedGPUCanvas* self)
{
    if (self->pendingWidth == 0 || self->pendingHeight == 0)
    {
        return;
    }
    auto* scriptingCtx = static_cast<ScriptingContext*>(lua_getthreaddata(L));
    auto* renderCtx = liveRenderContext(scriptingCtx);
    if (renderCtx == nullptr)
    {
        return;
    }
    auto* oreCtx = getOreContext(L);
    if (oreCtx == nullptr)
    {
        return;
    }
    self->renderCtx = renderCtx;
    uint32_t w = self->pendingWidth, h = self->pendingHeight;

    // Allocate and wrap the new backing BEFORE touching the existing
    // canvas/view/imageRef. If either step throws (via luaL_error), the
    // canvas keeps its previous, still-valid backing.
    auto newCanvas = allocScriptRenderCanvas(renderCtx, scriptingCtx, w, h);
    if (!newCanvas)
    {
        luaL_error(L, "GPUCanvas:resize() failed to create RenderCanvas");
    }
    auto newColorView = oreCtx->wrapCanvasTexture(newCanvas.get());
    if (!newColorView)
    {
        luaL_error(L, "GPUCanvas:resize() failed to wrap canvas texture");
    }

    if (self->m_L != nullptr && self->m_imageRef != LUA_NOREF)
    {
        lua_unref(self->m_L, self->m_imageRef);
        self->m_imageRef = LUA_NOREF;
    }
    self->canvas = std::move(newCanvas);
    self->oreColorView = std::move(newColorView);
    self->pendingWidth = 0;
    self->pendingHeight = 0;

    auto* img = lua_newrive<ScriptedImage>(L);
    img->image =
        ref_rcp(static_cast<RenderImage*>(self->canvas->renderImage()));
    self->m_imageRef = lua_ref(L, -1);
    lua_pop(L, 1); // pop image
}

// Recreate the underlying RenderCanvas at a new size, then re-wrap its backing
// texture for use in ORE render passes.  The handle's `.image` ref continues to
// point to the updated canvas image. Resizing to zero in either dimension
// drops the backing texture and leaves the canvas in a deferred state.
static int gpucanvashandle_resize(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPUCanvas>(L, 1);
    uint32_t w = static_cast<uint32_t>(luaL_checkunsigned(L, 2));
    uint32_t h = static_cast<uint32_t>(luaL_checkunsigned(L, 3));

    if (w == 0 || h == 0)
    {
        if (self->m_L != nullptr && self->m_imageRef != LUA_NOREF)
        {
            lua_unref(self->m_L, self->m_imageRef);
            self->m_imageRef = LUA_NOREF;
        }
        self->canvas = nullptr;
        self->oreColorView = nullptr;
        self->pendingWidth = 0;
        self->pendingHeight = 0;
        return 0;
    }

    // Generators call resize() every frame, so recreating on an unchanged
    // size would churn a new texture per frame and stall the render thread.
    if (self->canvas != nullptr && self->canvas->width() == w &&
        self->canvas->height() == h)
    {
        return 0;
    }

    // A generator resizes once, when layout hands it the real size. On web that
    // still precedes the render texture's attach, so the request is recorded
    // and satisfied on first use rather than refused for a device the contract
    // did not require at init either.
    self->pendingWidth = w;
    self->pendingHeight = h;
    gpucanvas_satisfyPending(L, self);
    return 0;
}

static int gpucanvashandle_colorview(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPUCanvas>(L, 1);
    gpucanvas_satisfyPending(L, self);
    if (!self->oreColorView)
    {
        luaL_error(L,
                   "GPUCanvas:colorView() called on a zero-sized canvas; "
                   "call canvas:resize(w, h) first");
    }
    auto* tv = lua_newrive<ScriptedGPUTextureView>(L);
    tv->view = self->oreColorView;
    return 1;
}

// A canvas has a size from the moment resize() is called; only the texture may
// still be pending. Reporting zero here instead would break the generator that
// sizes its depth and MSAA attachments off canvas.width the same frame.
static void gpucanvashandle_direct_width(void* udata, void* result)
{
    auto* self = (ScriptedGPUCanvas*)udata;
    lua_userdatadirectfield_setnumber(result,
                                      self->canvas ? self->canvas->width()
                                                   : self->pendingWidth);
}

static void gpucanvashandle_direct_height(void* udata, void* result)
{
    auto* self = (ScriptedGPUCanvas*)udata;
    lua_userdatadirectfield_setnumber(result,
                                      self->canvas ? self->canvas->height()
                                                   : self->pendingHeight);
}

static int gpucanvashandle_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
    }
    auto* self = lua_torive<ScriptedGPUCanvas>(L, 1);
    // Every field below reads the backing, and a generator reads them each
    // frame, so this is where a size pending on a late device is honoured.
    gpucanvas_satisfyPending(L, self);
    switch (atom)
    {
        case (int)LuaAtoms::image:
            if (self->m_imageRef != LUA_NOREF)
            {
                rive_lua_pushRef(L, self->m_imageRef);
                return 1;
            }
            lua_pushnil(L);
            return 1;
        case (int)LuaAtoms::width:
            lua_pushnumber(L,
                           self->canvas ? self->canvas->width()
                                        : self->pendingWidth);
            return 1;
        case (int)LuaAtoms::height:
            lua_pushnumber(L,
                           self->canvas ? self->canvas->height()
                                        : self->pendingHeight);
            return 1;
        case (int)LuaAtoms::format:
            // Realized canvas reports its texture format. Deferred canvas
            // reports the format makeRenderCanvas always allocates.
            if (self->oreColorView && self->oreColorView->texture())
                lua_pushstring(L,
                               lua_totextureformatstring(
                                   self->oreColorView->texture()->format()));
            else
                lua_pushstring(
                    L,
                    lua_totextureformatstring(TextureFormat::rgba8unorm));
            return 1;
    }
    luaL_error(L, "'%s' is not a valid index of GPUCanvas", key);
    return 0;
}

static int gpucanvashandle_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::colorView:
                return gpucanvashandle_colorview(L);
            case (int)LuaAtoms::resize:
                return gpucanvashandle_resize(L);
            case (int)LuaAtoms::beginRenderPass:
                return gpucanvas_beginrenderpass(L);
            default:
                break;
        }
    }
    luaL_error(L,
               "%s is not a valid method of %s",
               str,
               ScriptedGPUCanvas::luaName);
    return 0;
}

// ============================================================================
// Canvas (2D Rive renderer canvas)
// ============================================================================

// The 2D counterpart of gpucanvas_satisfyPending, for the same reason: a
// size-less canvas is legal, and on web the device shows up after layout has
// already handed the generator its real size.
static void canvas_satisfyPending(lua_State* L, ScriptedCanvas* self)
{
    if (self->pendingWidth == 0 || self->pendingHeight == 0)
    {
        return;
    }
    auto* scriptingCtx = static_cast<ScriptingContext*>(lua_getthreaddata(L));
    auto* renderCtx = liveRenderContext(scriptingCtx);
    if (renderCtx == nullptr)
    {
        return;
    }
    self->renderCtx = renderCtx;

    // Allocate the new backing BEFORE touching the existing canvas/imageRef.
    // If allocation throws (via luaL_error), the canvas keeps its previous,
    // still-valid backing.
    auto newCanvas = allocScriptRenderCanvas(renderCtx,
                                             scriptingCtx,
                                             self->pendingWidth,
                                             self->pendingHeight);
    if (!newCanvas)
    {
        luaL_error(L, "Canvas:resize() failed to create RenderCanvas");
    }

    if (self->m_L != nullptr && self->m_imageRef != LUA_NOREF)
    {
        lua_unref(self->m_L, self->m_imageRef);
        self->m_imageRef = LUA_NOREF;
    }
    self->canvas = std::move(newCanvas);
    self->pendingWidth = 0;
    self->pendingHeight = 0;

    auto* img = lua_newrive<ScriptedImage>(L);
    img->image =
        ref_rcp(static_cast<RenderImage*>(self->canvas->renderImage()));
    self->m_imageRef = lua_ref(L, -1);
    lua_pop(L, 1);
}

// Recreate the underlying RenderCanvas at a new size. Must not be called
// between beginFrame() and endFrame(). Resizing to zero in either dimension
// drops the backing texture and leaves the canvas in a deferred state.
static int canvashandle_resize(lua_State* L)
{
    auto* self = lua_torive<ScriptedCanvas>(L, 1);
    uint32_t w = static_cast<uint32_t>(luaL_checkunsigned(L, 2));
    uint32_t h = static_cast<uint32_t>(luaL_checkunsigned(L, 3));

    if (self->m_state != CanvasState::Idle)
    {
        luaL_error(L, "Canvas:resize() called during an active frame");
    }

    if (w == 0 || h == 0)
    {
        if (self->m_L != nullptr && self->m_imageRef != LUA_NOREF)
        {
            lua_unref(self->m_L, self->m_imageRef);
            self->m_imageRef = LUA_NOREF;
        }
        self->canvas = nullptr;
        self->pendingWidth = 0;
        self->pendingHeight = 0;
        return 0;
    }

    // Resizing to an unchanged size would churn a new texture per frame.
    if (self->canvas != nullptr && self->canvas->width() == w &&
        self->canvas->height() == h)
    {
        return 0;
    }

    self->pendingWidth = w;
    self->pendingHeight = h;
    canvas_satisfyPending(L, self);
    return 0;
}

// Begin a Rive rendering frame on this canvas.  Returns a Renderer that the
// caller can use to issue Rive draw calls.  Must be paired with endFrame().
//
// Optional `desc` table fields:
//   clearColor: Color?   ARGB integer (e.g. 0xFF000000 for opaque black).
//                        Defaults to transparent black (0).
static int canvashandle_beginframe(lua_State* L)
{
    auto* self = lua_torive<ScriptedCanvas>(L, 1);
    canvas_satisfyPending(L, self);
    if (self->renderCtx == nullptr)
    {
        luaL_error(L, "Canvas: renderCtx not initialized");
    }
    auto* scriptingContext =
        static_cast<ScriptingContext*>(lua_getthreaddata(L));
    // Recording brackets the content instead of opening a real frame; an
    // immediate context cannot nest one inside the open screen frame.
    Context* recordingOre = getOreContext(L);
    if (scriptingContext == nullptr || recordingOre == nullptr ||
        !recordingOre->isRecording())
    {
        luaL_error(L, "Canvas:beginFrame() requires the deferred recorder");
    }
    if (self->m_state != CanvasState::Idle)
    {
        luaL_error(L, "Canvas:beginFrame() called during an active frame");
    }
    if (!self->canvas)
    {
        luaL_error(L,
                   "Canvas:beginFrame() called on a zero-sized canvas; "
                   "call canvas:resize(w, h) first");
    }

    gpu::RenderContext::FrameDescriptor desc{};
    desc.renderTargetWidth = self->canvas->width();
    desc.renderTargetHeight = self->canvas->height();
    desc.loadAction = gpu::LoadAction::clear;
    desc.clearColor = 0; // transparent black

    if (lua_gettop(L) >= 2 && lua_istable(L, 2))
    {
        lua_getfield(L, 2, "clearColor");
        if (!lua_isnil(L, -1))
        {
            // clearColor is a ColorInt (ARGB uint32)
            desc.clearColor = static_cast<ColorInt>(lua_tounsigned(L, -1));
        }
        lua_pop(L, 1);
    }

    // A deferred host hands back a recorder instead of opening a real
    // RenderContext frame, the real canvas frame opens at replay.
    Renderer* renderer = nullptr;
    if (auto* host = scriptingContext->deferredCanvasHost())
    {
        self->m_deferredHost = host;
        renderer =
            host->beginCanvasContent(self->canvas.get(), desc.clearColor);
    }
    else
    {
        self->renderCtx->beginFrame(desc);
        // Allocate a RiveRenderer that issues into this render context. Deleted
        // in endFrame() (or in the destructor if endFrame is never called).
        self->m_riveRenderer = new RiveRenderer(self->renderCtx);
        renderer = self->m_riveRenderer;
    }
    self->m_state = CanvasState::Rendering;

    // Track the open frame on the context so the post-error cleanup can close
    // it if the script never reaches endFrame. The ref also pins the canvas.
    lua_pushvalue(L, 1);
    self->m_openFrameRef = lua_ref(L, -1);
    lua_pop(L, 1);
    scriptingContext->registerOpenCanvasFrame(self->m_openFrameRef);

    // Push a non-owning ScriptedRenderer wrapping our renderer and keep a
    // registry ref so the Lua object stays alive until endFrame().
    lua_newrive<ScriptedRenderer>(L, renderer);
    lua_pushvalue(L, -1);
    self->m_rendererRef = lua_ref(L, -1);
    lua_pop(L, 1); // pop the extra copy used for ref; original stays on stack

    return 1; // returns the ScriptedRenderer
}

// The body of Canvas:endFrame, shared with the post-error orphan cleanup.
static void canvasEndFrameImpl(lua_State* L, ScriptedCanvas* self)
{
    if (self->m_openFrameRef != LUA_NOREF)
    {
        auto* context = static_cast<ScriptingContext*>(lua_getthreaddata(L));
        if (context != nullptr)
        {
            context->unregisterOpenCanvasFrame(self->m_openFrameRef);
        }
        lua_unref(L, self->m_openFrameRef);
        self->m_openFrameRef = LUA_NOREF;
    }

    // Null out the ScriptedRenderer's pointer so it can no longer issue draws.
    if (self->m_L != nullptr && self->m_rendererRef != LUA_NOREF)
    {
        rive_lua_pushRef(L, self->m_rendererRef);
        if (!lua_isnil(L, -1))
        {
            auto* sr = lua_torive<ScriptedRenderer>(L, -1);
            if (sr != nullptr)
                sr->end();
        }
        lua_pop(L, 1);
        lua_unref(self->m_L, self->m_rendererRef);
        self->m_rendererRef = LUA_NOREF;
    }

    // Close the content bracket, the real canvas frame flushes at replay.
    if (self->m_deferredHost != nullptr)
    {
        self->m_deferredHost->endCanvasContent(self->canvas.get());
        self->m_deferredHost = nullptr;
        self->m_state = CanvasState::Idle;
        return;
    }

    // Create a command buffer, flush the render context into the canvas
    // render target, then commit. Without a proper command buffer the
    // buffer ring mutex would never be unlocked (the completion handler
    // that unlocks it is registered on the command buffer).
    void* commandBuffer = self->renderCtx->impl()->makeCommandBuffer();

    gpu::RenderContext::FlushResources flush{};
    flush.renderTarget = self->canvas->renderTarget();
    flush.externalCommandBuffer = commandBuffer;
    self->renderCtx->flush(flush);

    self->renderCtx->impl()->commitCommandBuffer(commandBuffer);

    // Destroy the RiveRenderer — it is no longer valid after flush().
    delete self->m_riveRenderer;
    self->m_riveRenderer = nullptr;
    self->m_state = CanvasState::Idle;
}

// Flush all pending Rive draw calls for this frame to the canvas render target,
// then release the renderer.  Must be called after beginFrame().
static int canvashandle_endframe(lua_State* L)
{
    auto* self = lua_torive<ScriptedCanvas>(L, 1);
    if (self->m_state != CanvasState::Rendering)
    {
        luaL_error(L, "Canvas:endFrame() called without beginFrame()");
    }
    canvasEndFrameImpl(L, self);
    return 0;
}

static void canvashandle_direct_width(void* udata, void* result)
{
    auto* self = (ScriptedCanvas*)udata;
    lua_userdatadirectfield_setnumber(result,
                                      self->canvas ? self->canvas->width()
                                                   : self->pendingWidth);
}

static void canvashandle_direct_height(void* udata, void* result)
{
    auto* self = (ScriptedCanvas*)udata;
    lua_userdatadirectfield_setnumber(result,
                                      self->canvas ? self->canvas->height()
                                                   : self->pendingHeight);
}

static int canvashandle_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
    }
    auto* self = lua_torive<ScriptedCanvas>(L, 1);
    canvas_satisfyPending(L, self);
    switch (atom)
    {
        case (int)LuaAtoms::image:
            if (self->m_imageRef != LUA_NOREF)
            {
                rive_lua_pushRef(L, self->m_imageRef);
                return 1;
            }
            lua_pushnil(L);
            return 1;
        case (int)LuaAtoms::width:
            lua_pushnumber(L,
                           self->canvas ? self->canvas->width()
                                        : self->pendingWidth);
            return 1;
        case (int)LuaAtoms::height:
            lua_pushnumber(L,
                           self->canvas ? self->canvas->height()
                                        : self->pendingHeight);
            return 1;
    }
    luaL_error(L, "'%s' is not a valid index of Canvas", key);
    return 0;
}

static int canvashandle_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::beginFrame:
                return canvashandle_beginframe(L);
            case (int)LuaAtoms::endFrame:
                return canvashandle_endframe(L);
            case (int)LuaAtoms::resize:
                return canvashandle_resize(L);
            default:
                break;
        }
    }
    luaL_error(L,
               "%s is not a valid method of %s",
               str,
               ScriptedCanvas::luaName);
    return 0;
}

// ============================================================================
// Registration
// ============================================================================

static const luaL_Reg empty[] = {
    {NULL, NULL},
};

template <typename T>
static void register_type_with_constructor(lua_State* L,
                                           lua_CFunction constructor,
                                           lua_CFunction namecall = nullptr,
                                           lua_CFunction indexfn = nullptr)
{
    luaL_register(L, T::luaName, empty);
    lua_register_rive<T>(L);

    if (namecall)
    {
        lua_pushcfunction(L, namecall, nullptr);
        lua_setfield(L, -2, "__namecall");
    }
    if (indexfn)
    {
        lua_pushcfunction(L, indexfn, nullptr);
        lua_setfield(L, -2, "__index");
    }

    // Create metatable for the metatable (so we can call T.new())
    lua_createtable(L, 0, 1);
    lua_pushcfunction(L, constructor, nullptr);
    lua_setfield(L, -2, "__index");

    // Also set __call so T.new(...) works
    // Actually the pattern is T.new(), so set new on the __index table
    // Let's do it properly: make __index return the new function
    lua_pop(L, 1); // pop the meta-meta

    // Simpler: just put "new" on the library table directly
    lua_pushcfunction(L, constructor, nullptr);
    lua_setfield(L, -2, "new");

    lua_setreadonly(L, -1, true);
    lua_pop(L, 1); // pop the metatable
}

int luaopen_rive_gpu(lua_State* L)
{
    // Shader has no constructor; shaders are obtained via context:shader(name).
    static const luaL_Reg shaderStatics[] = {{nullptr, nullptr}};
    static const luaL_Reg gpuBufferStatics[] = {{"new", gpubuffer_construct},
                                                {nullptr, nullptr}};
    static const luaL_Reg gpuTextureStatics[] = {{"new", gputexture_construct},
                                                 {nullptr, nullptr}};
    static const luaL_Reg gpuSamplerStatics[] = {{"new", gpusampler_construct},
                                                 {nullptr, nullptr}};
    static const luaL_Reg gpuPipelineStatics[] = {
        {"new", gpupipeline_construct},
        {nullptr, nullptr}};
    static const luaL_Reg gpuBindGroupStatics[] = {
        {"new", gpubindgroup_construct},
        {nullptr, nullptr}};
    static const luaL_Reg gpuBindGroupLayoutStatics[] = {
        {"new", gpubindgrouplayout_construct},
        {nullptr, nullptr}};
    // Shader
    {
        luaL_register(L, ScriptedShader::luaName, shaderStatics);
        lua_register_rive<ScriptedShader>(L);
        lua_setreadonly(L, -1, true);
        lua_pop(L, 1);
    }

    // GPUBuffer
    {
        luaL_register(L, ScriptedGPUBuffer::luaName, gpuBufferStatics);
        lua_register_rive<ScriptedGPUBuffer>(L);
        lua_pushcfunction(L, gpubuffer_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");
        lua_pushcfunction(L, gpubuffer_index, nullptr);
        lua_setfield(L, -2, "__index");
        lua_setreadonly(L, -1, true);
        lua_pop(L, 1);

        lua_registeruserdatadirectfieldget(L,
                                           ScriptedGPUBuffer::luaTag,
                                           "size",
                                           gpubuffer_direct_size);
    }

    // GPUTexture
    {
        luaL_register(L, ScriptedGPUTexture::luaName, gpuTextureStatics);
        lua_register_rive<ScriptedGPUTexture>(L);
        lua_pushcfunction(L, gputexture_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");
        lua_pushcfunction(L, gputexture_index, nullptr);
        lua_setfield(L, -2, "__index");
        lua_setreadonly(L, -1, true);
        lua_pop(L, 1);

        lua_registeruserdatadirectfieldget(L,
                                           ScriptedGPUTexture::luaTag,
                                           "width",
                                           gputexture_direct_width);
        lua_registeruserdatadirectfieldget(L,
                                           ScriptedGPUTexture::luaTag,
                                           "height",
                                           gputexture_direct_height);
    }

    // GPUSampler
    {
        luaL_register(L, ScriptedGPUSampler::luaName, gpuSamplerStatics);
        lua_register_rive<ScriptedGPUSampler>(L);
        lua_setreadonly(L, -1, true);
        lua_pop(L, 1);
    }

    // GPUPipeline
    {
        luaL_register(L, ScriptedGPUPipeline::luaName, gpuPipelineStatics);
        lua_register_rive<ScriptedGPUPipeline>(L);
        lua_pushcfunction(L, gpupipeline_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");
        lua_setreadonly(L, -1, true);
        lua_pop(L, 1);
    }

    // GPUBindGroup
    {
        luaL_register(L, ScriptedGPUBindGroup::luaName, gpuBindGroupStatics);
        lua_register_rive<ScriptedGPUBindGroup>(L);
        lua_setreadonly(L, -1, true);
        lua_pop(L, 1);
    }

    // GPUBindGroupLayout
    {
        luaL_register(L,
                      ScriptedGPUBindGroupLayout::luaName,
                      gpuBindGroupLayoutStatics);
        lua_register_rive<ScriptedGPUBindGroupLayout>(L);
        lua_setreadonly(L, -1, true);
        lua_pop(L, 1);
    }

    // GPURenderPass
    {
        luaL_register(L, ScriptedGPURenderPass::luaName, empty);
        lua_register_rive<ScriptedGPURenderPass>(L);
        lua_pushcfunction(L, gpurenderpass_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");
        lua_setreadonly(L, -1, true);
        lua_pop(L, 1);
    }

    // GPUTextureView (no constructor — created via GPUTexture:view())
    {
        luaL_register(L, ScriptedGPUTextureView::luaName, empty);
        lua_register_rive<ScriptedGPUTextureView>(L);
        lua_pushcfunction(L, gputextureview_index, nullptr);
        lua_setfield(L, -2, "__index");
        lua_setreadonly(L, -1, true);
        lua_pop(L, 1);
    }

    // GPUCanvas (no public constructor — created via context:gpuCanvas())
    {
        luaL_register(L, ScriptedGPUCanvas::luaName, empty);
        lua_register_rive<ScriptedGPUCanvas>(L);
        lua_pushcfunction(L, gpucanvashandle_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");
        lua_pushcfunction(L, gpucanvashandle_index, nullptr);
        lua_setfield(L, -2, "__index");
        lua_setreadonly(L, -1, true);
        lua_pop(L, 1);

        lua_registeruserdatadirectfieldget(L,
                                           ScriptedGPUCanvas::luaTag,
                                           "width",
                                           gpucanvashandle_direct_width);
        lua_registeruserdatadirectfieldget(L,
                                           ScriptedGPUCanvas::luaTag,
                                           "height",
                                           gpucanvashandle_direct_height);
    }

    // Canvas (no public constructor — created via context:canvas())
    {
        luaL_register(L, ScriptedCanvas::luaName, empty);
        lua_register_rive<ScriptedCanvas>(L);
        lua_pushcfunction(L, canvashandle_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");
        lua_pushcfunction(L, canvashandle_index, nullptr);
        lua_setfield(L, -2, "__index");
        lua_setreadonly(L, -1, true);
        lua_pop(L, 1);

        lua_registeruserdatadirectfieldget(L,
                                           ScriptedCanvas::luaTag,
                                           "width",
                                           canvashandle_direct_width);
        lua_registeruserdatadirectfieldget(L,
                                           ScriptedCanvas::luaTag,
                                           "height",
                                           canvashandle_direct_height);
    }

    return 0;
}

// ============================================================================
// Image:view() implementation — called from lua_image.cpp
// Lives here because ore headers require ObjC++ on Apple.
// ============================================================================

#include "rive/renderer/rive_render_image.hpp"

// ore::TextureView is complete here — define the destructor and factory.
ScriptedImage::~ScriptedImage() = default;
ScriptedImage* ScriptedImage::luaNew(lua_State* L)
{
    return lua_newrive<ScriptedImage>(L);
}

int riveImageViewImpl(lua_State* L)
{
    auto* self = lua_torive<ScriptedImage>(L, 1);
    if (!self->image)
    {
        luaL_error(L, "Image has no backing texture");
        return 0;
    }

    // Get ore::Context from scripting context.
    auto* ctx = static_cast<ScriptingContext*>(lua_getthreaddata(L));
    auto* oreCtx = static_cast<ore::Context*>(ctx->oreContext());
    if (!oreCtx)
    {
        luaL_error(L, "GPU context not available for Image:view()");
        return 0;
    }

    if (!self->cachedOreView && oreCtx->isRecording())
    {
        // Image:view() must not touch the driver while recording, so record
        // by resource id and let the consumer wrap at replay.
        if (auto* deferredImage =
                lite_rtti_cast<rive::cmd::DeferredRenderImage*>(
                    self->image.get()))
        {
            self->cachedOreView =
                oreCtx->recordWrapImageView(deferredImage->id(),
                                            self->image->width(),
                                            self->image->height());
        }
        else
        {
            self->cachedOreView =
                oreCtx->recordWrapCanvasImage(self->image.get(),
                                              self->image->width(),
                                              self->image->height());
        }
        if (!self->cachedOreView)
        {
            luaL_error(L, "Image:view() recording failed");
            return 0;
        }
    }
    else if (!self->cachedOreView)
    {
        // Immediate mode requires a live GPU backed image.
        auto* riveImage = lite_rtti_cast<RiveRenderImage*>(self->image.get());
        if (!riveImage)
        {
            luaL_error(L, "Image is not a GPU-backed RiveRenderImage");
            return 0;
        }
        gpu::Texture* sourceGpuTex = riveImage->getTexture();
        if (!sourceGpuTex)
        {
            luaL_error(L, "Image GPU texture not available");
            return 0;
        }
        // GL canvas-import boundary: on GL/WebGL, sampling a Rive 2D
        // RenderCanvas as a WGSL texture requires a Y-flipped companion
        // because PLS renders the canvas bottom-up while WGSL expects
        // V=0 at the visual top of the image. The render context's
        // getCanvasImportMirror returns nullptr on every backend except
        // GL — on GL it lazily allocates a companion texture, registers
        // a per-flush blit hook, and returns the companion image. We
        // cache the companion's RiveRenderImage so the companion stays
        // alive as long as this ScriptedImage does.
        //
        // See dev/ore_canvas_import_invariant.md.
        gpu::Texture* texToWrap = sourceGpuTex;
#if defined(ORE_BACKEND_GL)
        {
            auto* renderCtx =
                static_cast<gpu::RenderContext*>(ctx->renderContext());
            self->cachedMirrorImage =
                getCanvasImportMirrorGL(renderCtx,
                                        sourceGpuTex,
                                        self->image->width(),
                                        self->image->height());
            if (self->cachedMirrorImage != nullptr)
            {
                auto* mirrorRive = lite_rtti_cast<RiveRenderImage*>(
                    self->cachedMirrorImage.get());
                if (mirrorRive != nullptr &&
                    mirrorRive->getTexture() != nullptr)
                {
                    texToWrap = mirrorRive->getTexture();
                }
            }
        }
#endif // ORE_BACKEND_GL

        self->cachedOreView = oreCtx->wrapRiveTexture(texToWrap,
                                                      self->image->width(),
                                                      self->image->height());
        if (!self->cachedOreView)
        {
            luaL_error(L, "Image:view() not supported on this backend");
            return 0;
        }
    }

    // Create the GPUTextureView and have it retain the RenderImage so the
    // underlying gpu::Texture stays alive even if the Image is GC'd.
    auto* tv = lua_newrive<ScriptedGPUTextureView>(L);
    tv->view = self->cachedOreView;
    tv->retainedImage = self->image;

    return 1;
}

namespace rive
{
void rive_lua_closeOrphanRenderPass(lua_State* L)
{
    auto* context = static_cast<ScriptingContext*>(lua_getthreaddata(L));
    if (context == nullptr)
        return;
    auto* oreCtx = static_cast<ore::Context*>(context->oreContext());
    if (oreCtx == nullptr)
        return;
    auto* pass = oreCtx->activeRenderPass();
    if (pass == nullptr || pass->isFinished())
        return;
    pass->finish();
    oreCtx->setActiveRenderPass(nullptr);
    lua_pushstring(L,
                   "GPU render pass left open at script return. "
                   "Call :finish() on render passes before returning.");
    context->printError(L);
    lua_pop(L, 1);
}

void rive_lua_closeOrphanCanvasFrames(lua_State* L)
{
    auto* context = static_cast<ScriptingContext*>(lua_getthreaddata(L));
    if (context == nullptr)
    {
        return;
    }
    auto refs = context->takeOpenCanvasFrames();
    if (refs.empty())
    {
        return;
    }
    for (int ref : refs)
    {
        rive_lua_pushRef(L, ref);
        if (!lua_isnil(L, -1))
        {
            auto* canvas = lua_torive<ScriptedCanvas>(L, -1);
            if (canvas != nullptr && canvas->m_state == CanvasState::Rendering)
            {
                // Also releases the refs, including this one.
                canvasEndFrameImpl(L, canvas);
            }
        }
        lua_pop(L, 1);
    }
    lua_pushstring(L,
                   "Canvas frame left open at script return. "
                   "Call canvas:endFrame() before returning.");
    context->printError(L);
    lua_pop(L, 1);
}
} // namespace rive

#endif // RIVE_CANVAS && RIVE_ORE
#endif // WITH_RIVE_SCRIPTING
