// Responsive 2D Quad Draw Shader
// Notes:
// - SIZE  : normalized (w,h) in screen units (0..1 relative to res)
// - OFFSET: normalized (x,y) where (0,0) is top-left in UI space
// - Draws a quad in clip space using SV_VertexID (no vertex buffer)
// - Pixel shader samples tex (t127) with texel-accurate Load()

Texture1D<float4> IniParams : register(t120);

static const uint PARAM_INDEX = 87;
#define SIZE   (IniParams[PARAM_INDEX].xy)
#define OFFSET (IniParams[PARAM_INDEX].zw)

struct VSOut
{
    float4 pos : SV_Position0;
    float2 uv  : TEXCOORD1;
};

#ifdef VERTEX_SHADER

// Convert normalized UI offset (0..1, top-left origin) to clip-space (-1..1)
float2 UiToClipOffset(float2 uiOffset)
{
    // ui (0..1) -> clip (-1..1)
    // Y is flipped because UI space assumes top-left origin.
    float x = uiOffset.x * 2.0 - 1.0;
    float y = (1.0 - uiOffset.y) * 2.0 - 1.0;
    return float2(x, y);
}

// Convert normalized size (0..1 relative to screen) into clip-space extents.
// Note: Y is negative so that increasing UI Y goes downward on screen.
float2 SizeToClipExtent(float2 uiSize)
{
    return float2(2.0 * uiSize.x, -2.0 * uiSize.y);
}

void main(out VSOut o, uint vid : SV_VertexID)
{
    const float2 clipOffset = UiToClipOffset(OFFSET);
    const float2 clipExtent = SizeToClipExtent(SIZE);

    // 4 corners for a triangle strip:
    // vid: 0 (right,bottom), 1 (right,top), 2 (left,bottom), 3 (left,top)
    float2 corner01;
    float2 uv01;

    // Use bit logic for compact, deterministic corner selection:
    // left  = (vid & 2) != 0
    // top   = (vid & 1) != 0
    const bool isLeft = (vid & 2u) != 0u;
    const bool isTop  = (vid & 1u) != 0u;

    // X: left -> 0, right -> extent.x
    // Y: top  -> 0, bottom-> extent.y
    corner01.x = isLeft ? 0.0 : clipExtent.x;
    corner01.y = isTop  ? 0.0 : clipExtent.y;

    // UVs match the same layout (with later PS Y-flip)
    uv01.x = isLeft ? 0.0 : 1.0;
    uv01.y = isTop  ? 1.0 : 0.0;

    o.pos = float4(corner01 + clipOffset, 0.0, 1.0);
    o.uv  = uv01;
}
#endif

#ifdef PIXEL_SHADER
Texture2D<float4> tex : register(t127);

void main(VSOut i, out float4 outColor : SV_Target0)
{
    uint w, h;
    tex.GetDimensions(w, h);
    if (w == 0 || h == 0) discard;

    // Match the original behavior: flip V before sampling
    float2 uv = i.uv;
    uv.y = 1.0 - uv.y;

    // Texel-accurate sampling (no filtering)
    int2 p = int2(uv * float2((float)w, (float)h));
    outColor = tex.Load(int3(p, 0));
}
#endif