#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/ore_shader_module.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 <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());
}

/// 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 char* name,
                                 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(name);
        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;
}

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

    // Resolve the file-side ShaderAsset by name. 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())
            {
                if (File* file = scriptAsset->file())
                {
                    for (const auto& asset : file->assets())
                    {
                        if (asset->is<ShaderAsset>())
                        {
                            auto* sa = asset->as<ShaderAsset>();
                            // match folderPath/name or bare name
                            const std::string& fp = sa->folderPath();
                            if (sa->name() == name ||
                                (!fp.empty() && fp + "/" + sa->name() == name))
                            {
                                fileAsset = sa;
                                break;
                            }
                        }
                    }
                }
            }
        }
    }

    auto* scripted = lua_newrive<ScriptedShader>(L);
    if (!lua_gpu_load_shader_by_name(scripted, context, name, 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 (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)
    {
        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 && !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 && !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 && !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 && !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));
    if (scriptingContext == nullptr || !scriptingContext->canvasDrawingPhase())
    {
        luaL_error(L,
                   "GPUCanvas:beginRenderPass() called outside drawing phase");
    }

    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);
    rp->pass = oreCtx->beginRenderPass(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;
}

// 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 (self->renderCtx == nullptr)
    {
        luaL_error(L, "GPUCanvas: renderCtx not initialized");
    }
    auto* oreCtx = getOreContext(L);
    if (oreCtx == nullptr)
    {
        luaL_error(L, "GPUCanvas: GPU context not initialized");
    }

    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;
        return 0;
    }

    // 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 = self->renderCtx->makeRenderCanvas(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);

    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

    return 0;
}

static int gpucanvashandle_colorview(lua_State* L)
{
    auto* self = lua_torive<ScriptedGPUCanvas>(L, 1);
    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;
}

static void gpucanvashandle_direct_width(void* udata, void* result)
{
    auto* self = (ScriptedGPUCanvas*)udata;
    lua_userdatadirectfield_setnumber(result,
                                      self->canvas ? self->canvas->width() : 0);
}

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

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);
    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() : 0);
            return 1;
        case (int)LuaAtoms::height:
            lua_pushnumber(L, self->canvas ? self->canvas->height() : 0);
            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)
// ============================================================================

// 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->renderCtx == nullptr)
    {
        luaL_error(L, "Canvas: renderCtx not initialized");
    }
    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;
        return 0;
    }

    // Allocate the new backing BEFORE touching the existing canvas/imageRef.
    // If makeRenderCanvas throws (via luaL_error), the canvas keeps its
    // previous, still-valid backing.
    auto newCanvas = self->renderCtx->makeRenderCanvas(w, h);
    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);

    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);

    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);
    if (self->renderCtx == nullptr)
    {
        luaL_error(L, "Canvas: renderCtx not initialized");
    }
    auto* scriptingContext =
        static_cast<ScriptingContext*>(lua_getthreaddata(L));
    if (scriptingContext == nullptr || !scriptingContext->canvasDrawingPhase())
    {
        luaL_error(L, "Canvas:beginFrame() called outside drawing phase");
    }
    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);
    }

    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);
    self->m_state = CanvasState::Rendering;

    // Push a non-owning ScriptedRenderer wrapping our RiveRenderer and keep a
    // registry ref so the Lua object stays alive until endFrame().
    lua_newrive<ScriptedRenderer>(L, self->m_riveRenderer);
    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
}

// 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()");
    }

    // 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;
    }

    // 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;

    return 0;
}

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

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

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);
    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() : 0);
            return 1;
        case (int)LuaAtoms::height:
            lua_pushnumber(L, self->canvas ? self->canvas->height() : 0);
            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;
    }

    // Safe cast — returns nullptr if the image isn't GPU-backed.
    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;
    }

    // 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)
    {
        // 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);
}
} // namespace rive

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