Add missing checks in the GraphicsPipeline constructor

Adjusted a few checks in the GraphicsPipeline constructor,
specifically stages' specialization info and sample mask,
which can either be null or default.

Also fixed destroying Pipeline objects, making sure there's
no confusion between GraphicsPipeline and ComputePipeline's
destroy() methods inherited from their 2 base classes
(Pipeline::destroy() and ObjectBase::destroy()).

Bug b/118386749

Change-Id: I78be9f0bbb735518e07d52f7372dbf08b9834abf
Reviewed-on: https://swiftshader-review.googlesource.com/c/23110
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp
index 2282df2..59ff864 100644
--- a/src/Vulkan/VkPipeline.cpp
+++ b/src/Vulkan/VkPipeline.cpp
@@ -203,7 +203,9 @@
 	const VkPipelineShaderStageCreateInfo& vertexStage = pCreateInfo->pStages[0];
 	if((vertexStage.stage != VK_SHADER_STAGE_VERTEX_BIT) ||
 	   (vertexStage.flags != 0) ||
-	   (vertexStage.pSpecializationInfo != nullptr))
+	   !((vertexStage.pSpecializationInfo == nullptr) ||
+	     ((vertexStage.pSpecializationInfo->mapEntryCount == 0) &&
+	      (vertexStage.pSpecializationInfo->dataSize == 0))))
 	{
 		UNIMPLEMENTED();
 	}
@@ -211,7 +213,9 @@
 	const VkPipelineShaderStageCreateInfo& fragmentStage = pCreateInfo->pStages[1];
 	if((fragmentStage.stage != VK_SHADER_STAGE_FRAGMENT_BIT) ||
 	   (fragmentStage.flags != 0) ||
-	   (fragmentStage.pSpecializationInfo != nullptr))
+	   !((fragmentStage.pSpecializationInfo == nullptr) ||
+	     ((fragmentStage.pSpecializationInfo->mapEntryCount == 0) &&
+	      (fragmentStage.pSpecializationInfo->dataSize == 0))))
 	{
 		UNIMPLEMENTED();
 	}
@@ -287,7 +291,8 @@
 	if((multisampleState->flags != 0) ||
 	   (multisampleState->rasterizationSamples != VK_SAMPLE_COUNT_1_BIT) ||
 	   (multisampleState->sampleShadingEnable != 0) ||
-	   (multisampleState->pSampleMask != nullptr) ||
+	   !((multisampleState->pSampleMask == nullptr) ||
+	     (*(multisampleState->pSampleMask) == 0xFFFFFFFFu)) ||
 	   (multisampleState->alphaToCoverageEnable != 0) ||
 	   (multisampleState->alphaToOneEnable != 0))
 	{
@@ -363,7 +368,7 @@
 	}
 }
 
-void GraphicsPipeline::destroy(const VkAllocationCallbacks* pAllocator)
+void GraphicsPipeline::destroyPipeline(const VkAllocationCallbacks* pAllocator)
 {
 }
 
@@ -402,11 +407,10 @@
 {
 }
 
-void ComputePipeline::destroy(const VkAllocationCallbacks* pAllocator)
+void ComputePipeline::destroyPipeline(const VkAllocationCallbacks* pAllocator)
 {
 }
 
-
 size_t ComputePipeline::ComputeRequiredAllocationSize(const VkComputePipelineCreateInfo* pCreateInfo)
 {
 	return 0;
diff --git a/src/Vulkan/VkPipeline.hpp b/src/Vulkan/VkPipeline.hpp
index 18327ef..77a3d21 100644
--- a/src/Vulkan/VkPipeline.hpp
+++ b/src/Vulkan/VkPipeline.hpp
@@ -24,18 +24,28 @@
 class Pipeline
 {
 public:
-	virtual void destroy(const VkAllocationCallbacks* pAllocator) = 0;
+	operator VkPipeline()
+	{
+		return reinterpret_cast<VkPipeline>(this);
+	}
+
+	void destroy(const VkAllocationCallbacks* pAllocator)
+	{
+		destroyPipeline(pAllocator);
+	}
+
+	virtual void destroyPipeline(const VkAllocationCallbacks* pAllocator) = 0;
 #ifndef NDEBUG
 	virtual VkPipelineBindPoint bindPoint() const = 0;
 #endif
 };
 
-class GraphicsPipeline : public Pipeline, public Object<GraphicsPipeline, VkPipeline>
+class GraphicsPipeline : public Pipeline, public ObjectBase<GraphicsPipeline, VkPipeline>
 {
 public:
 	GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateInfo, void* mem);
 	~GraphicsPipeline() = delete;
-	void destroy(const VkAllocationCallbacks* pAllocator) override;
+	void destroyPipeline(const VkAllocationCallbacks* pAllocator) override;
 
 #ifndef NDEBUG
 	VkPipelineBindPoint bindPoint() const override
@@ -62,12 +72,12 @@
 	sw::Color<float> blendConstants;
 };
 
-class ComputePipeline : public Pipeline, public Object<ComputePipeline, VkPipeline>
+class ComputePipeline : public Pipeline, public ObjectBase<ComputePipeline, VkPipeline>
 {
 public:
 	ComputePipeline(const VkComputePipelineCreateInfo* pCreateInfo, void* mem);
 	~ComputePipeline() = delete;
-	void destroy(const VkAllocationCallbacks* pAllocator) override;
+	void destroyPipeline(const VkAllocationCallbacks* pAllocator) override;
 
 #ifndef NDEBUG
 	VkPipelineBindPoint bindPoint() const override