From 9d7422d967a97fea7888449652ad93da88e92b54 Mon Sep 17 00:00:00 2001
From: FernandoS27 <fsahmkow27@gmail.com>
Date: Mon, 29 Mar 2021 20:05:38 +0200
Subject: [PATCH] shader: Add PointCoord attribute

---
 src/shader_recompiler/backend/spirv/emit_context.cpp        | 3 +++
 src/shader_recompiler/backend/spirv/emit_context.h          | 2 ++
 .../backend/spirv/emit_spirv_context_get_set.cpp            | 6 ++++++
 src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp   | 4 ++++
 src/shader_recompiler/shader_info.h                         | 1 +
 5 files changed, 16 insertions(+)

diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp
index ecee1220e1..2c93bada51 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_context.cpp
@@ -425,6 +425,9 @@ void EmitContext::DefineInputs(const Info& info) {
     if (info.loads_front_face) {
         front_face = DefineInput(*this, U1, spv::BuiltIn::FrontFacing);
     }
+    if (info.loads_point_coord) {
+        point_coord = DefineInput(*this, F32[2], spv::BuiltIn::PointCoord);
+    }
     for (size_t index = 0; index < info.input_generics.size(); ++index) {
         const InputVarying generic{info.input_generics[index]};
         if (!generic.used) {
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h
index 97e055db42..071e66c2ae 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.h
+++ b/src/shader_recompiler/backend/spirv/emit_context.h
@@ -103,6 +103,8 @@ public:
     Id vertex_index{};
     Id base_vertex{};
     Id front_face{};
+    Id point_coord{};
+
     Id fswzadd_lut_a{};
     Id fswzadd_lut_b{};
 
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
index c870fac47d..d02761f320 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
@@ -179,6 +179,12 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr) {
         return ctx.OpSelect(ctx.U32[1], ctx.OpLoad(ctx.U1, ctx.front_face),
                             ctx.Constant(ctx.U32[1], std::numeric_limits<u32>::max()),
                             ctx.u32_zero_value);
+    case IR::Attribute::PointSpriteS:
+        return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.point_coord,
+                                                        ctx.Constant(ctx.U32[1], 0U)));
+    case IR::Attribute::PointSpriteT:
+        return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.point_coord,
+                                                        ctx.Constant(ctx.U32[1], 1U)));
     default:
         throw NotImplementedException("Read attribute {}", attr);
     }
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
index a47d54b9c9..eb3d1343f8 100644
--- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
+++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
@@ -47,6 +47,10 @@ void GetAttribute(Info& info, IR::Attribute attribute) {
     case IR::Attribute::FrontFace:
         info.loads_front_face = true;
         break;
+    case IR::Attribute::PointSpriteS:
+    case IR::Attribute::PointSpriteT:
+        info.loads_point_coord = true;
+        break;
     default:
         throw NotImplementedException("Get attribute {}", attribute);
     }
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h
index 3d8e089094..c9f6d9ef74 100644
--- a/src/shader_recompiler/shader_info.h
+++ b/src/shader_recompiler/shader_info.h
@@ -74,6 +74,7 @@ struct Info {
     bool loads_instance_id{};
     bool loads_vertex_id{};
     bool loads_front_face{};
+    bool loads_point_coord{};
 
     std::array<bool, 8> stores_frag_color{};
     bool stores_frag_depth{};