Support for the largePoints feature in Vulkan

Bug: b/149537975

Tests: dEQP-VK.*point*

Change-Id: I22ee0c0ebc4e7b414e055e2b87010004dfc8741a
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/41948
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Marc-Antoine Desroches <madesroches@google.com>
diff --git a/src/Device/Primitive.hpp b/src/Device/Primitive.hpp
index 591b974..fcacdb8 100644
--- a/src/Device/Primitive.hpp
+++ b/src/Device/Primitive.hpp
@@ -66,6 +66,7 @@
 
 	float pointCoordX;
 	float pointCoordY;
+	float pointSizeInv;
 
 	PlaneEquation z;
 	PlaneEquation w;
diff --git a/src/Device/Renderer.cpp b/src/Device/Renderer.cpp
index 393f317..538ed96 100644
--- a/src/Device/Renderer.cpp
+++ b/src/Device/Renderer.cpp
@@ -1153,6 +1153,7 @@
 
 		triangle.v1.projected.x += iround(subPixF * 0.5f * pSize);
 		triangle.v2.projected.y -= iround(subPixF * 0.5f * pSize) * (data.HxF[0] > 0.0f ? 1 : -1);  // Both Direct3D and OpenGL expect (0, 0) in the top-left corner
+		primitive.pointSizeInv = 1.0f / pSize;
 		return draw.setupRoutine(&primitive, &triangle, &polygon, &data);
 	}
 
diff --git a/src/Pipeline/PixelProgram.cpp b/src/Pipeline/PixelProgram.cpp
index fff8b93..b92d48e 100644
--- a/src/Pipeline/PixelProgram.cpp
+++ b/src/Pipeline/PixelProgram.cpp
@@ -66,10 +66,7 @@
 	routine.fragCoord[1] = SIMD::Float(Float(y)) + SIMD::Float(0.5f, 0.5f, 1.5f, 1.5f);
 	routine.fragCoord[2] = z[0];  // sample 0
 	routine.fragCoord[3] = w;
-	routine.pointCoord[0] = SIMD::Float(0.5f) +
-	                        SIMD::Float(Float(x) - (*Pointer<Float>(primitive + OFFSET(Primitive, pointCoordX))));
-	routine.pointCoord[1] = SIMD::Float(0.5f) +
-	                        SIMD::Float(Float(y) - (*Pointer<Float>(primitive + OFFSET(Primitive, pointCoordY))));
+
 	routine.invocationsPerSubgroup = SIMD::Width;
 	routine.helperInvocation = ~maskAny(cMask);
 	routine.windowSpacePosition[0] = x + SIMD::Int(0, 1, 0, 1);
@@ -91,10 +88,10 @@
 
 	routine.setInputBuiltin(spirvShader, spv::BuiltInPointCoord, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
 		assert(builtin.SizeInComponents == 2);
-		value[builtin.FirstComponent + 0] = SIMD::Float(0.5f, 1.5f, 0.5f, 1.5f) +
-		                                    SIMD::Float(Float(x) - (*Pointer<Float>(primitive + OFFSET(Primitive, pointCoordX))));
-		value[builtin.FirstComponent + 1] = SIMD::Float(0.5f, 0.5f, 1.5f, 1.5f) +
-		                                    SIMD::Float(Float(y) - (*Pointer<Float>(primitive + OFFSET(Primitive, pointCoordY))));
+		Float pointSizeFactor = *Pointer<Float>(primitive + OFFSET(Primitive, pointSizeInv));
+		value[builtin.FirstComponent + 0] = SIMD::Float(0.5f) + SIMD::Float(pointSizeFactor) * (((SIMD::Float(Float(x)) + SIMD::Float(0.f, 1.f, 0.f, 1.f)) - SIMD::Float(*Pointer<Float>(primitive + OFFSET(Primitive, pointCoordX)))));
+
+		value[builtin.FirstComponent + 1] = SIMD::Float(0.5f) + SIMD::Float(pointSizeFactor) * (((SIMD::Float(Float(y)) + SIMD::Float(0.f, 0.f, 1.f, 1.f)) - SIMD::Float(*Pointer<Float>(primitive + OFFSET(Primitive, pointCoordY)))));
 	});
 
 	routine.setInputBuiltin(spirvShader, spv::BuiltInSubgroupSize, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
diff --git a/src/Vulkan/VkConfig.h b/src/Vulkan/VkConfig.h
index 85b36e4..eaf0b1d 100644
--- a/src/Vulkan/VkConfig.h
+++ b/src/Vulkan/VkConfig.h
@@ -74,7 +74,7 @@
 
 enum
 {
-	MAX_POINT_SIZE = 1,		// Large points are not supported. If/when we turn this on, must be >= 64.
+	MAX_POINT_SIZE = 1023,
 };
 
 constexpr int SUBPIXEL_PRECISION_BITS = 4;
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index ba22551..3cd4561 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -71,7 +71,7 @@
 		VK_TRUE,   // fillModeNonSolid
 		VK_FALSE,  // depthBounds
 		VK_FALSE,  // wideLines
-		VK_FALSE,  // largePoints
+		VK_TRUE,   // largePoints
 		VK_FALSE,  // alphaToOne
 		VK_FALSE,  // multiViewport
 		VK_TRUE,   // samplerAnisotropy