// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)

//- GENERATED CODE

#ifndef RENDER_D3D11_META_H
#define RENDER_D3D11_META_H

typedef enum R_D3D11_VShadKind
{
R_D3D11_VShadKind_Rect,
R_D3D11_VShadKind_Blur,
R_D3D11_VShadKind_Mesh,
R_D3D11_VShadKind_Geo3DComposite,
R_D3D11_VShadKind_Finalize,
R_D3D11_VShadKind_COUNT,
} R_D3D11_VShadKind;

typedef enum R_D3D11_PShadKind
{
R_D3D11_PShadKind_Rect,
R_D3D11_PShadKind_Blur,
R_D3D11_PShadKind_Mesh,
R_D3D11_PShadKind_Geo3DComposite,
R_D3D11_PShadKind_Finalize,
R_D3D11_PShadKind_COUNT,
} R_D3D11_PShadKind;

typedef enum R_D3D11_UniformTypeKind
{
R_D3D11_UniformTypeKind_Rect,
R_D3D11_UniformTypeKind_Blur,
R_D3D11_UniformTypeKind_Mesh,
R_D3D11_UniformTypeKind_COUNT,
} R_D3D11_UniformTypeKind;

C_LINKAGE_BEGIN
read_only global String8 r_d3d11_g_rect_shader_src =
str8_lit_comp(
""
"\n"
"cbuffer Globals : register(b0)\n"
"{\n"
"  float2 viewport_size_px;\n"
"  float opacity;\n"
"  row_major float4x4 texture_sample_channel_map;\n"
"  float2 texture_t2d_size_px;\n"
"  row_major float3x3 xform;\n"
"  float2 xform_scale;\n"
"}\n"
"\n"
"struct CPU2Vertex\n"
"{\n"
"  float4 dst_rect_px     : POS;\n"
"  float4 src_rect_px     : TEX;\n"
"  float4 color00         : COL0;\n"
"  float4 color01         : COL1;\n"
"  float4 color10         : COL2;\n"
"  float4 color11         : COL3;\n"
"  float4 corner_radii_px : CRAD;\n"
"  float4 style_params    : STY; // x: border_thickness_px, y: softness_px, z: omit_texture, w: unused\n"
"  uint vertex_id         : SV_VertexID;\n"
"};\n"
"\n"
"struct Vertex2Pixel\n"
"{\n"
"  float4 position           : SV_POSITION;\n"
"  nointerpolation float2 rect_half_size_px  : PSIZE;\n"
"  float2 texcoord_pct       : TEX;\n"
"  float2 sdf_sample_pos     : SDF;\n"
"  float4 tint               : TINT;\n"
"  float corner_radius_px    : CRAD;\n"
"  nointerpolation float border_thickness_px : BTHC;\n"
"  nointerpolation float softness_px         : SFT;\n"
"  nointerpolation float omit_texture        : OTX;\n"
"};\n"
"\n"
"Texture2D    main_t2d     : register(t0);\n"
"SamplerState main_sampler : register(s0);\n"
"\n"
"float rect_sdf(float2 sample_pos, float2 rect_half_size, float r)\n"
"{\n"
"  return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r;\n"
"}\n"
"\n"
"//- rjf: vertex shader\n"
"\n"
"Vertex2Pixel\n"
"vs_main(CPU2Vertex cpu2vertex)\n"
"{\n"
"  //- rjf: unpack & xform rectangle src/dst vertices\n"
"  float2 dst_p0_px  = cpu2vertex.dst_rect_px.xy;\n"
"  float2 dst_p1_px  = cpu2vertex.dst_rect_px.zw;\n"
"  float2 src_p0_px  = cpu2vertex.src_rect_px.xy;\n"
"  float2 src_p1_px  = cpu2vertex.src_rect_px.zw;\n"
"  float2 dst_size_px = abs(dst_p1_px - dst_p0_px);\n"
"  \n"
"  //- rjf: unpack style params\n"
"  float border_thickness_px = cpu2vertex.style_params.x;\n"
"  float softness_px         = cpu2vertex.style_params.y;\n"
"  float omit_texture        = cpu2vertex.style_params.z;\n"
"  \n"
"  //- rjf: prep per-vertex arrays to sample from (p: position, t: texcoord, c: colorcoord, r: cornerradius)\n"
"  float2 dst_p_verts_px[] =\n"
"  {\n"
"    float2(dst_p0_px.x, dst_p1_px.y),\n"
"    float2(dst_p0_px.x, dst_p0_px.y),\n"
"    float2(dst_p1_px.x, dst_p1_px.y),\n"
"    float2(dst_p1_px.x, dst_p0_px.y),\n"
"  };\n"
"  float2 src_p_verts_px[] =\n"
"  {\n"
"    float2(src_p0_px.x, src_p1_px.y),\n"
"    float2(src_p0_px.x, src_p0_px.y),\n"
"    float2(src_p1_px.x, src_p1_px.y),\n"
"    float2(src_p1_px.x, src_p0_px.y),\n"
"  };\n"
"  float dst_r_verts_px[] =\n"
"  {\n"
"    cpu2vertex.corner_radii_px.y,\n"
"    cpu2vertex.corner_radii_px.x,\n"
"    cpu2vertex.corner_radii_px.w,\n"
"    cpu2vertex.corner_radii_px.z,\n"
"  };\n"
"  float4 src_color[] = {\n"
"    cpu2vertex.color01,\n"
"    cpu2vertex.color00,\n"
"    cpu2vertex.color11,\n"
"    cpu2vertex.color10,\n"
"  };\n"
"  float2 dst_verts_pct = float2((cpu2vertex.vertex_id >> 1) ? 1.f : 0.f,\n"
"                                (cpu2vertex.vertex_id & 1)  ? 0.f : 1.f);\n"
"  \n"
"  // rjf: fill vertex -> pixel data\n"
"  Vertex2Pixel vertex2pixel;\n"
"  {\n"
"    float2 xformed_pos = mul(xform, float3(dst_p_verts_px[cpu2vertex.vertex_id], 1.f)).xy;\n"
"    xformed_pos.y = viewport_size_px.y - xformed_pos.y;\n"
"    vertex2pixel.position.xy          = 2.f * xformed_pos/viewport_size_px - 1.f;\n"
"    vertex2pixel.position.z           = 0.f;\n"
"    vertex2pixel.position.w           = 1.f;\n"
"    vertex2pixel.rect_half_size_px    = dst_size_px / 2.f * xform_scale;\n"
"    vertex2pixel.texcoord_pct         = src_p_verts_px[cpu2vertex.vertex_id] / texture_t2d_size_px;\n"
"    vertex2pixel.sdf_sample_pos       = (2.f * dst_verts_pct - 1.f) * vertex2pixel.rect_half_size_px;\n"
"    vertex2pixel.tint                 = src_color[cpu2vertex.vertex_id];\n"
"    vertex2pixel.corner_radius_px     = dst_r_verts_px[cpu2vertex.vertex_id];\n"
"    vertex2pixel.border_thickness_px  = border_thickness_px;\n"
"    vertex2pixel.softness_px          = softness_px;\n"
"    vertex2pixel.omit_texture         = omit_texture;\n"
"  }\n"
"  return vertex2pixel;\n"
"}\n"
"\n"
"//- rjf: pixel shader\n"
"\n"
"float4\n"
"ps_main(Vertex2Pixel vertex2pixel) : SV_TARGET\n"
"{\n"
"  // rjf: blend corner colors to produce final tint\n"
"  float4 tint = vertex2pixel.tint;\n"
"  \n"
"  // rjf: sample texture\n"
"  float4 albedo_sample = float4(1, 1, 1, 1);\n"
"  if(vertex2pixel.omit_texture < 1)\n"
"  {\n"
"    albedo_sample = mul(main_t2d.Sample(main_sampler, vertex2pixel.texcoord_pct), texture_sample_channel_map);\n"
"  }\n"
"  \n"
"  // rjf: determine SDF sample position\n"
"  float2 sdf_sample_pos = vertex2pixel.sdf_sample_pos;\n"
"  \n"
"  // rjf: sample for borders\n"
"  float border_sdf_t = 1;\n"
"  if(vertex2pixel.border_thickness_px > 0)\n"
"  {\n"
"    float border_sdf_s = rect_sdf(sdf_sample_pos,\n"
"                                  vertex2pixel.rect_half_size_px - float2(vertex2pixel.softness_px*2.f, vertex2pixel.softness_px*2.f) - vertex2pixel.border_thickness_px,\n"
"                                  max(vertex2pixel.corner_radius_px-vertex2pixel.border_thickness_px, 0));\n"
"    border_sdf_t = smoothstep(0, 2*vertex2pixel.softness_px, border_sdf_s);\n"
"  }\n"
"  if(border_sdf_t < 0.001f)\n"
"  {\n"
"    discard;\n"
"  }\n"
"  \n"
"  // rjf: sample for corners\n"
"  float corner_sdf_t = 1;\n"
"  if(vertex2pixel.corner_radius_px > 0 || vertex2pixel.softness_px > 0.75f)\n"
"  {\n"
"    float corner_sdf_s = rect_sdf(sdf_sample_pos,\n"
"                                  vertex2pixel.rect_half_size_px - float2(vertex2pixel.softness_px*2.f, vertex2pixel.softness_px*2.f),\n"
"                                  vertex2pixel.corner_radius_px);\n"
"    corner_sdf_t = 1-smoothstep(0, 2*vertex2pixel.softness_px, corner_sdf_s);\n"
"  }\n"
"  \n"
"  // rjf: form+return final color\n"
"  float4 final_color = albedo_sample;\n"
"  final_color *= tint;\n"
"  final_color.a *= opacity;\n"
"  final_color.a *= corner_sdf_t;\n"
"  final_color.a *= border_sdf_t;\n"
"  return final_color;\n"
"}\n"
""
);

read_only global String8 r_d3d11_g_blur_shader_src =
str8_lit_comp(
""
"\n"
"cbuffer Globals : register(b0)\n"
"{\n"
"  float4 rect;\n"
"  float4 corner_radii_px;\n"
"  float2 direction;\n"
"  float2 viewport_size;\n"
"  uint blur_count;\n"
"}\n"
"\n"
"cbuffer Kernel : register(b1)\n"
"{\n"
"  float4 kernel[32];\n"
"}\n"
"\n"
"struct CPU2Vertex\n"
"{\n"
"  uint vertex_id         : SV_VertexID;\n"
"};\n"
"\n"
"struct Vertex2Pixel\n"
"{\n"
"  float4 position        : SV_POSITION;\n"
"  float2 texcoord        : TEX;\n"
"  float2 sdf_sample_pos  : SDF;\n"
"  nointerpolation float2 rect_half_size : RHS;\n"
"  float corner_radius    : RAD;\n"
"};\n"
"\n"
"Texture2D    stage_t2d     : register(t0);\n"
"SamplerState stage_sampler : register(s0);\n"
"\n"
"float rect_sdf(float2 sample_pos, float2 rect_half_size, float r)\n"
"{\n"
"  return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r;\n"
"}\n"
"\n"
"//- rjf: vertex shader\n"
"\n"
"Vertex2Pixel\n"
"vs_main(CPU2Vertex c2v)\n"
"{\n"
"  float2 vertex_positions__scrn[] =\n"
"  {\n"
"    rect.xw,\n"
"    rect.xy,\n"
"    rect.zw,\n"
"    rect.zy,\n"
"  };\n"
"  float corner_radii__px[] =\n"
"  {\n"
"    corner_radii_px.y,\n"
"    corner_radii_px.x,\n"
"    corner_radii_px.w,\n"
"    corner_radii_px.z,\n"
"  };\n"
"  float2 cornercoords__pct = float2(\n"
"                                    (c2v.vertex_id >> 1) ? 1.f : 0.f,\n"
"                                    (c2v.vertex_id & 1)  ? 0.f : 1.f);\n"
"  \n"
"  float2 vertex_position__pct = vertex_positions__scrn[c2v.vertex_id] / viewport_size;\n"
"  float2 vertex_position__scr = 2.f * vertex_position__pct - 1.f;\n"
"  \n"
"  float2 rect_half_size = float2((rect.z-rect.x)/2, (rect.w-rect.y)/2);\n"
"  \n"
"  Vertex2Pixel v2p;\n"
"  {\n"
"    v2p.position = float4(vertex_position__scr.x, -vertex_position__scr.y, 0.f, 1.f);\n"
"    v2p.texcoord = vertex_position__pct;\n"
"    v2p.sdf_sample_pos = (2.f * cornercoords__pct - 1.f) * rect_half_size;\n"
"    v2p.rect_half_size = rect_half_size - 2.f;\n"
"    v2p.corner_radius = corner_radii__px[c2v.vertex_id];\n"
"  }\n"
"  return v2p;\n"
"}\n"
"\n"
"//- rjf: pixel shader\n"
"\n"
"float4\n"
"ps_main(Vertex2Pixel v2p) : SV_TARGET\n"
"{\n"
"  // rjf: blend weighted texture samples into color\n"
"  float3 color = kernel[0].x * stage_t2d.Sample(stage_sampler, v2p.texcoord).rgb;\n"
"  \n"
"  for(uint i = 1; i < blur_count; i += 1)\n"
"  {\n"
"    float weight = kernel[i].x;\n"
"    float offset = kernel[i].y;\n"
"    color += weight * stage_t2d.Sample(stage_sampler, v2p.texcoord - offset * direction).rgb;\n"
"    color += weight * stage_t2d.Sample(stage_sampler, v2p.texcoord + offset * direction).rgb;\n"
"  }\n"
"  \n"
"  // rjf: sample for corners\n"
"  float corner_sdf_s = rect_sdf(v2p.sdf_sample_pos, v2p.rect_half_size, v2p.corner_radius);\n"
"  float corner_sdf_t = 1-smoothstep(0, 2, corner_sdf_s);\n"
"  \n"
"  // rjf: weight output color by sdf\n"
"  // this is doing alpha testing, leave blurring only where mostly opaque pixels are\n"
"  if (corner_sdf_t < 0.9f)\n"
"  {\n"
"    discard;\n"
"  }\n"
"  \n"
"  return float4(color, 1.f);\n"
"}\n"
""
);

read_only global String8 r_d3d11_g_mesh_shader_src =
str8_lit_comp(
""
"\n"
"cbuffer Uniforms : register(b0)\n"
"{\n"
"  row_major float4x4 xform;\n"
"}\n"
"\n"
"struct CPU2Vertex\n"
"{\n"
"  float3 position : POS;\n"
"  float3 normal   : NOR;\n"
"  float2 texcoord : TEX;\n"
"  float3 color    : COL;\n"
"};\n"
"\n"
"struct Vertex2Pixel\n"
"{\n"
"  float4 position : SV_POSITION;\n"
"  float2 texcoord : TEX;\n"
"  float4 color    : COL;\n"
"};\n"
"\n"
"Vertex2Pixel vs_main(CPU2Vertex c2v)\n"
"{\n"
"  Vertex2Pixel v2p;\n"
"  v2p.position = mul(float4(c2v.position, 1.f), xform);\n"
"  v2p.texcoord = c2v.texcoord;\n"
"  v2p.color    = float4(c2v.color, 1.f);\n"
"  return v2p;\n"
"}\n"
"\n"
"float4 ps_main(Vertex2Pixel v2p) : SV_TARGET\n"
"{\n"
"  return v2p.color;\n"
"}\n"
""
);

read_only global String8 r_d3d11_g_geo3dcomposite_shader_src =
str8_lit_comp(
""
"\n"
"struct CPU2Vertex\n"
"{\n"
"  uint vertex_id         : SV_VertexID;\n"
"};\n"
"\n"
"struct Vertex2Pixel\n"
"{\n"
"  float4 position        : SV_POSITION;\n"
"  float2 texcoord        : TEX;\n"
"};\n"
"\n"
"Texture2D    stage_t2d     : register(t0);\n"
"SamplerState stage_sampler : register(s0);\n"
"\n"
"//- rjf: vertex shader\n"
"\n"
"Vertex2Pixel\n"
"vs_main(CPU2Vertex c2v)\n"
"{\n"
"  float4 vertex_positions__modl[] =\n"
"  {\n"
"    float4(0, 0, 0, 1),\n"
"    float4(0, 1, 0, 1),\n"
"    float4(1, 0, 0, 1),\n"
"    float4(1, 1, 0, 1),\n"
"  };\n"
"  float4 vertex_position__modl = vertex_positions__modl[c2v.vertex_id];\n"
"  float4 vertex_position__clip = float4(2*vertex_position__modl.x - 1, 2*vertex_position__modl.y - 1, 0, 1);\n"
"  float2 texcoord              = float2(vertex_position__modl.x, vertex_position__modl.y);\n"
"  texcoord.y = 1-texcoord.y;\n"
"  Vertex2Pixel v2p;\n"
"  {\n"
"    v2p.position = vertex_position__clip;\n"
"    v2p.texcoord = texcoord;\n"
"  }\n"
"  return v2p;\n"
"}\n"
"\n"
"//- rjf: pixel shader\n"
"\n"
"float4\n"
"ps_main(Vertex2Pixel v2p) : SV_TARGET\n"
"{\n"
"  float4 final_color = stage_t2d.Sample(stage_sampler, v2p.texcoord);\n"
"  return final_color;\n"
"}\n"
""
);

read_only global String8 r_d3d11_g_finalize_shader_src =
str8_lit_comp(
""
"\n"
"struct CPU2Vertex\n"
"{\n"
"  uint vertex_id         : SV_VertexID;\n"
"};\n"
"\n"
"struct Vertex2Pixel\n"
"{\n"
"  float4 position        : SV_POSITION;\n"
"  float2 texcoord        : TEX;\n"
"};\n"
"\n"
"Texture2D    stage_t2d     : register(t0);\n"
"SamplerState stage_sampler : register(s0);\n"
"\n"
"//- rjf: vertex shader\n"
"\n"
"Vertex2Pixel\n"
"vs_main(CPU2Vertex c2v)\n"
"{\n"
"  float4 vertex_positions__modl[] =\n"
"  {\n"
"    float4(0, 0, 0, 1),\n"
"    float4(0, 1, 0, 1),\n"
"    float4(1, 0, 0, 1),\n"
"    float4(1, 1, 0, 1),\n"
"  };\n"
"  float4 vertex_position__modl = vertex_positions__modl[c2v.vertex_id];\n"
"  float4 vertex_position__clip = float4(2*vertex_position__modl.x - 1, 2*vertex_position__modl.y - 1, 0, 1);\n"
"  float2 texcoord              = float2(vertex_position__modl.x, vertex_position__modl.y);\n"
"  texcoord.y = 1-texcoord.y;\n"
"  Vertex2Pixel v2p;\n"
"  {\n"
"    v2p.position = vertex_position__clip;\n"
"    v2p.texcoord = texcoord;\n"
"  }\n"
"  return v2p;\n"
"}\n"
"\n"
"//- rjf: pixel shader\n"
"\n"
"float4\n"
"ps_main(Vertex2Pixel v2p) : SV_TARGET\n"
"{\n"
"  float4 final_color = stage_t2d.Sample(stage_sampler, v2p.texcoord);\n"
"  final_color.a = 1;\n"
"  return final_color;\n"
"}\n"
""
);


C_LINKAGE_END

#endif // RENDER_D3D11_META_H
