// Copyright 2020 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "Context.hpp"

#include "Vulkan/VkBuffer.hpp"
#include "Vulkan/VkDevice.hpp"
#include "Vulkan/VkImageView.hpp"
#include "Vulkan/VkPipeline.hpp"
#include "Vulkan/VkRenderPass.hpp"
#include "Vulkan/VkStringify.hpp"

namespace {

uint32_t ComputePrimitiveCount(VkPrimitiveTopology topology, uint32_t vertexCount)
{
	switch(topology)
	{
	case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
		return vertexCount;
	case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
		return vertexCount / 2;
	case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
		return std::max<uint32_t>(vertexCount, 1) - 1;
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
		return vertexCount / 3;
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
		return std::max<uint32_t>(vertexCount, 2) - 2;
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
		return std::max<uint32_t>(vertexCount, 2) - 2;
	default:
		UNSUPPORTED("VkPrimitiveTopology %d", int(topology));
	}

	return 0;
}

template<typename T>
void ProcessPrimitiveRestart(T *indexBuffer,
                             VkPrimitiveTopology topology,
                             uint32_t count,
                             std::vector<std::pair<uint32_t, void *>> *indexBuffers)
{
	static const T RestartIndex = static_cast<T>(-1);
	T *indexBufferStart = indexBuffer;
	uint32_t vertexCount = 0;
	for(uint32_t i = 0; i < count; i++)
	{
		if(indexBuffer[i] == RestartIndex)
		{
			// Record previous segment
			if(vertexCount > 0)
			{
				uint32_t primitiveCount = ComputePrimitiveCount(topology, vertexCount);
				if(primitiveCount > 0)
				{
					indexBuffers->push_back({ primitiveCount, indexBufferStart });
				}
			}
			vertexCount = 0;
		}
		else
		{
			if(vertexCount == 0)
			{
				indexBufferStart = indexBuffer + i;
			}
			vertexCount++;
		}
	}

	// Record last segment
	if(vertexCount > 0)
	{
		uint32_t primitiveCount = ComputePrimitiveCount(topology, vertexCount);
		if(primitiveCount > 0)
		{
			indexBuffers->push_back({ primitiveCount, indexBufferStart });
		}
	}
}

vk::InputsDynamicStateFlags ParseInputsDynamicStateFlags(const VkPipelineDynamicStateCreateInfo *dynamicStateCreateInfo)
{
	vk::InputsDynamicStateFlags dynamicStateFlags = {};

	if(dynamicStateCreateInfo == nullptr)
	{
		return dynamicStateFlags;
	}

	for(uint32_t i = 0; i < dynamicStateCreateInfo->dynamicStateCount; i++)
	{
		VkDynamicState dynamicState = dynamicStateCreateInfo->pDynamicStates[i];
		switch(dynamicState)
		{
		case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE:
			dynamicStateFlags.dynamicVertexInputBindingStride = true;
			break;
		case VK_DYNAMIC_STATE_VERTEX_INPUT_EXT:
			dynamicStateFlags.dynamicVertexInput = true;
			dynamicStateFlags.dynamicVertexInputBindingStride = true;
			break;

		default:
			// The rest of the dynamic state is handled by ParseDynamicStateFlags.
			break;
		}
	}

	return dynamicStateFlags;
}

vk::DynamicStateFlags ParseDynamicStateFlags(const VkPipelineDynamicStateCreateInfo *dynamicStateCreateInfo)
{
	vk::DynamicStateFlags dynamicStateFlags = {};

	if(dynamicStateCreateInfo == nullptr)
	{
		return dynamicStateFlags;
	}

	if(dynamicStateCreateInfo->flags != 0)
	{
		// Vulkan 1.3: "flags is reserved for future use." "flags must be 0"
		UNSUPPORTED("dynamicStateCreateInfo->flags 0x%08X", int(dynamicStateCreateInfo->flags));
	}

	for(uint32_t i = 0; i < dynamicStateCreateInfo->dynamicStateCount; i++)
	{
		VkDynamicState dynamicState = dynamicStateCreateInfo->pDynamicStates[i];
		switch(dynamicState)
		{
		// Vertex input interface:
		case VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE:
			dynamicStateFlags.vertexInputInterface.dynamicPrimitiveRestartEnable = true;
			break;
		case VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY:
			dynamicStateFlags.vertexInputInterface.dynamicPrimitiveTopology = true;
			break;
		case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE:
		case VK_DYNAMIC_STATE_VERTEX_INPUT_EXT:
			// Handled by ParseInputsDynamicStateFlags
			break;

		// Pre-rasterization:
		case VK_DYNAMIC_STATE_LINE_WIDTH:
			dynamicStateFlags.preRasterization.dynamicLineWidth = true;
			break;
		case VK_DYNAMIC_STATE_DEPTH_BIAS:
			dynamicStateFlags.preRasterization.dynamicDepthBias = true;
			break;
		case VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE:
			dynamicStateFlags.preRasterization.dynamicDepthBiasEnable = true;
			break;
		case VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT:
			dynamicStateFlags.preRasterization.dynamicDepthClampEnable = true;
			break;
		case VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT:
			dynamicStateFlags.preRasterization.dynamicDepthClipEnable = true;
			break;
		case VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT:
			dynamicStateFlags.preRasterization.dynamicDepthClipNegativeOneToOne = true;
			break;
		case VK_DYNAMIC_STATE_CULL_MODE:
			dynamicStateFlags.preRasterization.dynamicCullMode = true;
			break;
		case VK_DYNAMIC_STATE_FRONT_FACE:
			dynamicStateFlags.preRasterization.dynamicFrontFace = true;
			break;
		case VK_DYNAMIC_STATE_POLYGON_MODE_EXT:
			dynamicStateFlags.preRasterization.dynamicPolygonMode = true;
			break;
		case VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT:
			dynamicStateFlags.preRasterization.dynamicLineRasterizationMode = true;
			break;
		case VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT:
			dynamicStateFlags.preRasterization.dynamicProvokingVertexMode = true;
			break;
		case VK_DYNAMIC_STATE_VIEWPORT:
			dynamicStateFlags.preRasterization.dynamicViewport = true;
			break;
		case VK_DYNAMIC_STATE_SCISSOR:
			dynamicStateFlags.preRasterization.dynamicScissor = true;
			break;
		case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT:
			dynamicStateFlags.preRasterization.dynamicViewportWithCount = true;
			break;
		case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT:
			dynamicStateFlags.preRasterization.dynamicScissorWithCount = true;
			break;
		case VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE:
			dynamicStateFlags.preRasterization.dynamicRasterizerDiscardEnable = true;
			break;

		// Fragment:
		case VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE:
			dynamicStateFlags.fragment.dynamicDepthTestEnable = true;
			break;
		case VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE:
			dynamicStateFlags.fragment.dynamicDepthWriteEnable = true;
			break;
		case VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE:
			dynamicStateFlags.fragment.dynamicDepthBoundsTestEnable = true;
			break;
		case VK_DYNAMIC_STATE_DEPTH_BOUNDS:
			dynamicStateFlags.fragment.dynamicDepthBounds = true;
			break;
		case VK_DYNAMIC_STATE_DEPTH_COMPARE_OP:
			dynamicStateFlags.fragment.dynamicDepthCompareOp = true;
			break;
		case VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE:
			dynamicStateFlags.fragment.dynamicStencilTestEnable = true;
			break;
		case VK_DYNAMIC_STATE_STENCIL_OP:
			dynamicStateFlags.fragment.dynamicStencilOp = true;
			break;
		case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
			dynamicStateFlags.fragment.dynamicStencilCompareMask = true;
			break;
		case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
			dynamicStateFlags.fragment.dynamicStencilWriteMask = true;
			break;
		case VK_DYNAMIC_STATE_STENCIL_REFERENCE:
			dynamicStateFlags.fragment.dynamicStencilReference = true;
			break;

		// Fragment or fragment output interface:
		case VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT:
			dynamicStateFlags.fragment.dynamicRasterizationSamples = true;
			dynamicStateFlags.fragmentOutputInterface.dynamicRasterizationSamples = true;
			break;
		case VK_DYNAMIC_STATE_SAMPLE_MASK_EXT:
			dynamicStateFlags.fragment.dynamicSampleMask = true;
			dynamicStateFlags.fragmentOutputInterface.dynamicSampleMask = true;
			break;
		case VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT:
			dynamicStateFlags.fragment.dynamicAlphaToCoverageEnable = true;
			dynamicStateFlags.fragmentOutputInterface.dynamicAlphaToCoverageEnable = true;
			break;

		// Fragment output interface:
		case VK_DYNAMIC_STATE_BLEND_CONSTANTS:
			dynamicStateFlags.fragmentOutputInterface.dynamicBlendConstants = true;
			break;
		case VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT:
			dynamicStateFlags.fragmentOutputInterface.dynamicColorBlendEnable = true;
			break;
		case VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT:
			dynamicStateFlags.fragmentOutputInterface.dynamicColorBlendEquation = true;
			break;
		case VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT:
			dynamicStateFlags.fragmentOutputInterface.dynamicColorBlendAdvanced = true;
			break;
		case VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT:
			dynamicStateFlags.fragmentOutputInterface.dynamicColorWriteMask = true;
			break;

		default:
			UNSUPPORTED("VkDynamicState %d", int(dynamicState));
		}
	}

	return dynamicStateFlags;
}
}  // namespace

namespace vk {

uint32_t IndexBuffer::bytesPerIndex() const
{
	return indexType == VK_INDEX_TYPE_UINT8_EXT ? 1u : indexType == VK_INDEX_TYPE_UINT16 ? 2u
	                                                                                     : 4u;
}

void IndexBuffer::setIndexBufferBinding(const VertexInputBinding &indexBufferBinding, VkIndexType type)
{
	binding = indexBufferBinding;
	indexType = type;
}

void IndexBuffer::getIndexBuffers(VkPrimitiveTopology topology, uint32_t count, uint32_t first, bool indexed, bool hasPrimitiveRestartEnable, std::vector<std::pair<uint32_t, void *>> *indexBuffers) const
{
	if(indexed)
	{
		const VkDeviceSize bufferSize = binding.buffer->getSize();
		if(binding.offset >= bufferSize)
		{
			return;  // Nothing to draw
		}

		const VkDeviceSize maxIndices = (bufferSize - binding.offset) / bytesPerIndex();
		if(first > maxIndices)
		{
			return;  // Nothing to draw
		}

		void *indexBuffer = binding.buffer->getOffsetPointer(binding.offset + first * bytesPerIndex());
		if(hasPrimitiveRestartEnable)
		{
			switch(indexType)
			{
			case VK_INDEX_TYPE_UINT8_EXT:
				ProcessPrimitiveRestart(static_cast<uint8_t *>(indexBuffer), topology, count, indexBuffers);
				break;
			case VK_INDEX_TYPE_UINT16:
				ProcessPrimitiveRestart(static_cast<uint16_t *>(indexBuffer), topology, count, indexBuffers);
				break;
			case VK_INDEX_TYPE_UINT32:
				ProcessPrimitiveRestart(static_cast<uint32_t *>(indexBuffer), topology, count, indexBuffers);
				break;
			default:
				UNSUPPORTED("VkIndexType %d", int(indexType));
			}
		}
		else
		{
			indexBuffers->push_back({ ComputePrimitiveCount(topology, count), indexBuffer });
		}
	}
	else
	{
		indexBuffers->push_back({ ComputePrimitiveCount(topology, count), nullptr });
	}
}

VkFormat Attachments::colorFormat(int location) const
{
	ASSERT((location >= 0) && (location < sw::MAX_COLOR_BUFFERS));

	if(colorBuffer[location])
	{
		return colorBuffer[location]->getFormat();
	}
	else
	{
		return VK_FORMAT_UNDEFINED;
	}
}

VkFormat Attachments::depthFormat() const
{
	if(depthBuffer)
	{
		return depthBuffer->getFormat();
	}
	else
	{
		return VK_FORMAT_UNDEFINED;
	}
}

VkFormat Attachments::depthStencilFormat() const
{
	if(depthBuffer)
	{
		return depthBuffer->getFormat();
	}
	else if(stencilBuffer)
	{
		return stencilBuffer->getFormat();
	}
	else
	{
		return VK_FORMAT_UNDEFINED;
	}
}

void Inputs::initialize(const VkPipelineVertexInputStateCreateInfo *vertexInputState, const VkPipelineDynamicStateCreateInfo *dynamicStateCreateInfo)
{
	dynamicStateFlags = ParseInputsDynamicStateFlags(dynamicStateCreateInfo);

	if(dynamicStateFlags.dynamicVertexInput)
	{
		return;
	}

	if(vertexInputState->flags != 0)
	{
		// Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
		UNSUPPORTED("vertexInputState->flags");
	}

	// Temporary in-binding-order representation of buffer strides, to be consumed below
	// when considering attributes. TODO: unfuse buffers from attributes in backend, is old GL model.
	uint32_t vertexStrides[MAX_VERTEX_INPUT_BINDINGS];
	uint32_t instanceStrides[MAX_VERTEX_INPUT_BINDINGS];
	VkVertexInputRate inputRates[MAX_VERTEX_INPUT_BINDINGS];
	for(uint32_t i = 0; i < vertexInputState->vertexBindingDescriptionCount; i++)
	{
		const auto &desc = vertexInputState->pVertexBindingDescriptions[i];
		inputRates[desc.binding] = desc.inputRate;
		vertexStrides[desc.binding] = desc.inputRate == VK_VERTEX_INPUT_RATE_VERTEX ? desc.stride : 0;
		instanceStrides[desc.binding] = desc.inputRate == VK_VERTEX_INPUT_RATE_INSTANCE ? desc.stride : 0;
	}

	for(uint32_t i = 0; i < vertexInputState->vertexAttributeDescriptionCount; i++)
	{
		const auto &desc = vertexInputState->pVertexAttributeDescriptions[i];
		sw::Stream &input = stream[desc.location];
		input.format = desc.format;
		input.offset = desc.offset;
		input.binding = desc.binding;
		input.inputRate = inputRates[desc.binding];
		if(!dynamicStateFlags.dynamicVertexInputBindingStride)
		{
			// The following gets overriden with dynamic state anyway and setting it is
			// harmless.  But it is not done to be able to catch bugs with this dynamic
			// state easier.
			input.vertexStride = vertexStrides[desc.binding];
			input.instanceStride = instanceStrides[desc.binding];
		}
	}
}

void Inputs::updateDescriptorSets(const DescriptorSet::Array &dso,
                                  const DescriptorSet::Bindings &ds,
                                  const DescriptorSet::DynamicOffsets &ddo)
{
	descriptorSetObjects = dso;
	descriptorSets = ds;
	descriptorDynamicOffsets = ddo;
}

void Inputs::bindVertexInputs(int firstInstance)
{
	for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
	{
		auto &attrib = stream[i];
		if(attrib.format != VK_FORMAT_UNDEFINED)
		{
			const auto &vertexInput = vertexInputBindings[attrib.binding];
			VkDeviceSize offset = attrib.offset + vertexInput.offset +
			                      getInstanceStride(i) * firstInstance;
			attrib.buffer = vertexInput.buffer ? vertexInput.buffer->getOffsetPointer(offset) : nullptr;

			VkDeviceSize size = vertexInput.buffer ? vertexInput.buffer->getSize() : 0;
			attrib.robustnessSize = (size > offset) ? size - offset : 0;
		}
	}
}

void Inputs::setVertexInputBinding(const VertexInputBinding bindings[], const DynamicState &dynamicState)
{
	for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; ++i)
	{
		vertexInputBindings[i] = bindings[i];
	}

	if(dynamicStateFlags.dynamicVertexInput)
	{
		// If the entire vertex input state is dynamic, recalculate the contents of `stream`.
		// This is similar to Inputs::initialize.
		for(uint32_t i = 0; i < sw::MAX_INTERFACE_COMPONENTS / 4; i++)
		{
			const auto &desc = dynamicState.vertexInputAttributes[i];
			const auto &bindingDesc = dynamicState.vertexInputBindings[desc.binding];
			sw::Stream &input = stream[i];
			input.format = desc.format;
			input.offset = desc.offset;
			input.binding = desc.binding;
			input.inputRate = bindingDesc.inputRate;
		}
	}

	// Stride may come from two different dynamic states
	if(dynamicStateFlags.dynamicVertexInput || dynamicStateFlags.dynamicVertexInputBindingStride)
	{
		for(uint32_t i = 0; i < sw::MAX_INTERFACE_COMPONENTS / 4; i++)
		{
			sw::Stream &input = stream[i];
			const VkDeviceSize stride = dynamicState.vertexInputBindings[input.binding].stride;

			input.vertexStride = input.inputRate == VK_VERTEX_INPUT_RATE_VERTEX ? stride : 0;
			input.instanceStride = input.inputRate == VK_VERTEX_INPUT_RATE_INSTANCE ? stride : 0;
		}
	}
}

void Inputs::advanceInstanceAttributes()
{
	for(uint32_t i = 0; i < vk::MAX_VERTEX_INPUT_BINDINGS; i++)
	{
		auto &attrib = stream[i];

		VkDeviceSize instanceStride = getInstanceStride(i);
		if((attrib.format != VK_FORMAT_UNDEFINED) && instanceStride && (instanceStride < attrib.robustnessSize))
		{
			// Under the casts: attrib.buffer += instanceStride
			attrib.buffer = (const void *)((uintptr_t)attrib.buffer + instanceStride);
			attrib.robustnessSize -= instanceStride;
		}
	}
}

VkDeviceSize Inputs::getVertexStride(uint32_t i) const
{
	auto &attrib = stream[i];
	if(attrib.format != VK_FORMAT_UNDEFINED)
	{
		return attrib.vertexStride;
	}

	return 0;
}

VkDeviceSize Inputs::getInstanceStride(uint32_t i) const
{
	auto &attrib = stream[i];
	if(attrib.format != VK_FORMAT_UNDEFINED)
	{
		return attrib.instanceStride;
	}

	return 0;
}

void MultisampleState::set(const FragmentOutputInterfaceDynamicStateFlags &dynamicStateFlags, const VkPipelineMultisampleStateCreateInfo *multisampleState)
{
	if(multisampleState->flags != 0)
	{
		// Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
		UNSUPPORTED("pCreateInfo->pMultisampleState->flags 0x%08X", int(multisampleState->flags));
	}

	sampleShadingEnable = (multisampleState->sampleShadingEnable != VK_FALSE);
	if(sampleShadingEnable)
	{
		minSampleShading = multisampleState->minSampleShading;
	}

	if(multisampleState->alphaToOneEnable != VK_FALSE)
	{
		UNSUPPORTED("VkPhysicalDeviceFeatures::alphaToOne");
	}

	switch(multisampleState->rasterizationSamples)
	{
	case VK_SAMPLE_COUNT_1_BIT:
		sampleCount = 1;
		break;
	case VK_SAMPLE_COUNT_4_BIT:
		sampleCount = 4;
		break;
	default:
		if(!dynamicStateFlags.dynamicRasterizationSamples)
		{
			UNSUPPORTED("Unsupported sample count");
		}
		sampleCount = 4;
	}

	if(multisampleState->pSampleMask)
	{
		staticSampleMask = multisampleState->pSampleMask[0];
	}
	else  // "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
	{
		staticSampleMask = ~0;
	}

	alphaToCoverage = (multisampleState->alphaToCoverageEnable != VK_FALSE);
	multiSampleMask = staticSampleMask & ((unsigned)0xFFFFFFFF >> (32 - sampleCount));
}

void VertexInputInterfaceState::initialize(const VkPipelineVertexInputStateCreateInfo *vertexInputState,
                                           const VkPipelineInputAssemblyStateCreateInfo *inputAssemblyState,
                                           const DynamicStateFlags &allDynamicStateFlags)
{
	dynamicStateFlags = allDynamicStateFlags.vertexInputInterface;

	if(vertexInputState && vertexInputState->flags != 0)
	{
		// Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
		UNSUPPORTED("vertexInputState->flags");
	}

	// The spec says:
	//
	// If the VK_EXT_extended_dynamic_state3 extension is enabled, it can be NULL if the
	// pipeline is created with both VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE, and
	// VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY dynamic states set and
	// dynamicPrimitiveTopologyUnrestricted is VK_TRUE.
	//
	// SwiftShader sets dynamicPrimitiveTopologyUnrestricted to VK_TRUE.
	if(inputAssemblyState == nullptr)
	{
		ASSERT(dynamicStateFlags.dynamicPrimitiveRestartEnable &&
		       dynamicStateFlags.dynamicPrimitiveTopology);
		return;
	}

	if(inputAssemblyState->flags != 0)
	{
		// Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
		UNSUPPORTED("pCreateInfo->pInputAssemblyState->flags 0x%08X", int(inputAssemblyState->flags));
	}

	primitiveRestartEnable = (inputAssemblyState->primitiveRestartEnable != VK_FALSE);
	topology = inputAssemblyState->topology;
}

void VertexInputInterfaceState::applyState(const DynamicState &dynamicState)
{
	if(dynamicStateFlags.dynamicPrimitiveRestartEnable)
	{
		primitiveRestartEnable = dynamicState.primitiveRestartEnable;
	}

	if(dynamicStateFlags.dynamicPrimitiveTopology)
	{
		topology = dynamicState.primitiveTopology;
	}
}

bool VertexInputInterfaceState::isDrawPoint(bool polygonModeAware, VkPolygonMode polygonMode) const
{
	switch(topology)
	{
	case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
		return true;
	case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
	case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
		return false;
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
		return polygonModeAware ? (polygonMode == VK_POLYGON_MODE_POINT) : false;
	default:
		UNSUPPORTED("topology %d", int(topology));
	}
	return false;
}

bool VertexInputInterfaceState::isDrawLine(bool polygonModeAware, VkPolygonMode polygonMode) const
{
	switch(topology)
	{
	case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
		return false;
	case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
	case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
		return true;
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
		return polygonModeAware ? (polygonMode == VK_POLYGON_MODE_LINE) : false;
	default:
		UNSUPPORTED("topology %d", int(topology));
	}
	return false;
}

bool VertexInputInterfaceState::isDrawTriangle(bool polygonModeAware, VkPolygonMode polygonMode) const
{
	switch(topology)
	{
	case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
	case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
	case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
		return false;
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
	case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
		return polygonModeAware ? (polygonMode == VK_POLYGON_MODE_FILL) : true;
	default:
		UNSUPPORTED("topology %d", int(topology));
	}
	return false;
}

void PreRasterizationState::initialize(const vk::Device *device,
                                       const PipelineLayout *layout,
                                       const VkPipelineViewportStateCreateInfo *viewportState,
                                       const VkPipelineRasterizationStateCreateInfo *rasterizationState,
                                       const vk::RenderPass *renderPass, uint32_t subpassIndex,
                                       const VkPipelineRenderingCreateInfo *rendering,
                                       const DynamicStateFlags &allDynamicStateFlags)
{
	pipelineLayout = layout;
	dynamicStateFlags = allDynamicStateFlags.preRasterization;

	// The spec says:
	//
	// If the VK_EXT_extended_dynamic_state3 extension is enabled, it can be NULL if the
	// pipeline is created with all of VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT,
	// VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE, VK_DYNAMIC_STATE_POLYGON_MODE_EXT,
	// VK_DYNAMIC_STATE_CULL_MODE, VK_DYNAMIC_STATE_FRONT_FACE,
	// VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE, VK_DYNAMIC_STATE_DEPTH_BIAS, and
	// VK_DYNAMIC_STATE_LINE_WIDTH dynamic states set.
	if(rasterizationState == nullptr)
	{
		ASSERT(dynamicStateFlags.dynamicDepthClampEnable &&
		       dynamicStateFlags.dynamicRasterizerDiscardEnable &&
		       dynamicStateFlags.dynamicPolygonMode &&
		       dynamicStateFlags.dynamicCullMode &&
		       dynamicStateFlags.dynamicFrontFace &&
		       dynamicStateFlags.dynamicDepthBiasEnable &&
		       dynamicStateFlags.dynamicDepthBias &&
		       dynamicStateFlags.dynamicLineWidth);
	}
	else
	{
		if(rasterizationState->flags != 0)
		{
			// Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
			UNSUPPORTED("pCreateInfo->pRasterizationState->flags 0x%08X", int(rasterizationState->flags));
		}

		rasterizerDiscard = rasterizationState->rasterizerDiscardEnable != VK_FALSE;
		cullMode = rasterizationState->cullMode;
		frontFace = rasterizationState->frontFace;
		polygonMode = rasterizationState->polygonMode;
		depthBiasEnable = rasterizationState->depthBiasEnable;
		constantDepthBias = rasterizationState->depthBiasConstantFactor;
		slopeDepthBias = rasterizationState->depthBiasSlopeFactor;
		depthBiasClamp = rasterizationState->depthBiasClamp;
		depthRangeUnrestricted = device->hasExtension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME);
		depthClampEnable = rasterizationState->depthClampEnable != VK_FALSE;
		depthClipEnable = !depthClampEnable;
		depthClipEnableIsExplicit = false;

		// From the Vulkan spec for vkCmdSetDepthBias:
		//    The bias value O for a polygon is:
		//        O = dbclamp(...)
		//    where dbclamp(x) =
		//        * x                       depthBiasClamp = 0 or NaN
		//        * min(x, depthBiasClamp)  depthBiasClamp > 0
		//        * max(x, depthBiasClamp)  depthBiasClamp < 0
		// So it should be safe to resolve NaNs to 0.0f.
		if(std::isnan(depthBiasClamp))
		{
			depthBiasClamp = 0.0f;
		}

		if(!dynamicStateFlags.dynamicLineWidth)
		{
			lineWidth = rasterizationState->lineWidth;
		}

		const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(rasterizationState->pNext);
		while(extensionCreateInfo)
		{
			switch(extensionCreateInfo->sType)
			{
			case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT:
				{
					const VkPipelineRasterizationLineStateCreateInfoEXT *lineStateCreateInfo = reinterpret_cast<const VkPipelineRasterizationLineStateCreateInfoEXT *>(extensionCreateInfo);
					lineRasterizationMode = lineStateCreateInfo->lineRasterizationMode;
				}
				break;
			case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT:
				{
					const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *provokingVertexModeCreateInfo =
					    reinterpret_cast<const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *>(extensionCreateInfo);
					provokingVertexMode = provokingVertexModeCreateInfo->provokingVertexMode;
				}
				break;
			case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT:
				{
					const auto *depthClipInfo = reinterpret_cast<const VkPipelineRasterizationDepthClipStateCreateInfoEXT *>(extensionCreateInfo);
					// Reserved for future use.
					ASSERT(depthClipInfo->flags == 0);
					depthClipEnable = depthClipInfo->depthClipEnable != VK_FALSE;
					depthClipEnableIsExplicit = !dynamicStateFlags.dynamicDepthClipEnable;
				}
				break;
			case VK_STRUCTURE_TYPE_APPLICATION_INFO:
				// SwiftShader doesn't interact with application info, but dEQP includes it
				break;
			case VK_STRUCTURE_TYPE_MAX_ENUM:
				// dEQP tests that this value is ignored.
				break;
			default:
				UNSUPPORTED("pCreateInfo->pRasterizationState->pNext sType = %s", vk::Stringify(extensionCreateInfo->sType).c_str());
				break;
			}

			extensionCreateInfo = extensionCreateInfo->pNext;
		}
	}

	// The spec says:
	//
	// If the VK_EXT_extended_dynamic_state3 extension is enabled, it can be NULL if the
	// pipeline is created with both VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, and
	// VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT dynamic states set.
	if(viewportState == nullptr)
	{
		ASSERT(dynamicStateFlags.dynamicViewportWithCount &&
		       dynamicStateFlags.dynamicScissorWithCount);
		return;
	}

	if(!rasterizerDiscard || dynamicStateFlags.dynamicRasterizerDiscardEnable)
	{
		const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(viewportState->pNext);
		while(extensionCreateInfo != nullptr)
		{
			switch(extensionCreateInfo->sType)
			{
			case VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT:
				{
					const auto *depthClipControl = reinterpret_cast<const VkPipelineViewportDepthClipControlCreateInfoEXT *>(extensionCreateInfo);
					depthClipNegativeOneToOne = depthClipControl->negativeOneToOne != VK_FALSE;
				}
				break;
			case VK_STRUCTURE_TYPE_MAX_ENUM:
				// dEQP passes this value expecting the driver to ignore it.
				break;
			default:
				UNSUPPORTED("pCreateInfo->pViewportState->pNext sType = %s", vk::Stringify(extensionCreateInfo->sType).c_str());
				break;
			}
			extensionCreateInfo = extensionCreateInfo->pNext;
		}

		if(viewportState->flags != 0)
		{
			// Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
			UNSUPPORTED("pCreateInfo->pViewportState->flags 0x%08X", int(viewportState->flags));
		}

		if((viewportState->viewportCount > 1) ||
		   (viewportState->scissorCount > 1))
		{
			UNSUPPORTED("VkPhysicalDeviceFeatures::multiViewport");
		}

		if(!dynamicStateFlags.dynamicScissor && !dynamicStateFlags.dynamicScissorWithCount)
		{
			scissor = viewportState->pScissors[0];
		}

		if(!dynamicStateFlags.dynamicViewport && !dynamicStateFlags.dynamicViewportWithCount)
		{
			viewport = viewportState->pViewports[0];
		}
	}
}

void PreRasterizationState::applyState(const DynamicState &dynamicState)
{
	if(dynamicStateFlags.dynamicLineWidth)
	{
		lineWidth = dynamicState.lineWidth;
	}

	if(dynamicStateFlags.dynamicDepthBias)
	{
		constantDepthBias = dynamicState.depthBiasConstantFactor;
		slopeDepthBias = dynamicState.depthBiasSlopeFactor;
		depthBiasClamp = dynamicState.depthBiasClamp;
	}

	if(dynamicStateFlags.dynamicDepthBiasEnable)
	{
		depthBiasEnable = dynamicState.depthBiasEnable;
	}

	if(dynamicStateFlags.dynamicDepthClampEnable)
	{
		depthClampEnable = dynamicState.depthClampEnable;
		if(!depthClipEnableIsExplicit && !dynamicStateFlags.dynamicDepthClipEnable)
		{
			depthClipEnable = !dynamicState.depthClampEnable;
		}
	}

	if(dynamicStateFlags.dynamicDepthClipEnable)
	{
		depthClipEnable = dynamicState.depthClipEnable;
	}

	if(dynamicStateFlags.dynamicDepthClipNegativeOneToOne)
	{
		depthClipNegativeOneToOne = dynamicState.depthClipNegativeOneToOne;
	}

	if(dynamicStateFlags.dynamicCullMode)
	{
		cullMode = dynamicState.cullMode;
	}

	if(dynamicStateFlags.dynamicFrontFace)
	{
		frontFace = dynamicState.frontFace;
	}

	if(dynamicStateFlags.dynamicPolygonMode)
	{
		polygonMode = dynamicState.polygonMode;
	}

	if(dynamicStateFlags.dynamicLineRasterizationMode)
	{
		lineRasterizationMode = dynamicState.lineRasterizationMode;
	}

	if(dynamicStateFlags.dynamicProvokingVertexMode)
	{
		provokingVertexMode = dynamicState.provokingVertexMode;
	}

	if(dynamicStateFlags.dynamicViewport)
	{
		viewport = dynamicState.viewport;
	}

	if(dynamicStateFlags.dynamicScissor)
	{
		scissor = dynamicState.scissor;
	}

	if(dynamicStateFlags.dynamicViewportWithCount && dynamicState.viewportCount > 0)
	{
		viewport = dynamicState.viewports[0];
	}

	if(dynamicStateFlags.dynamicScissorWithCount && dynamicState.scissorCount > 0)
	{
		scissor = dynamicState.scissors[0];
	}

	if(dynamicStateFlags.dynamicRasterizerDiscardEnable)
	{
		rasterizerDiscard = dynamicState.rasterizerDiscardEnable;
	}
}

void FragmentState::initialize(
    const PipelineLayout *layout,
    const VkPipelineDepthStencilStateCreateInfo *depthStencilState,
    const vk::RenderPass *renderPass, uint32_t subpassIndex,
    const VkPipelineRenderingCreateInfo *rendering,
    const DynamicStateFlags &allDynamicStateFlags)
{
	pipelineLayout = layout;
	dynamicStateFlags = allDynamicStateFlags.fragment;

	// The spec says:
	//
	// If the VK_EXT_extended_dynamic_state3 extension is enabled, it can be NULL if the
	// pipeline is created with all of VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE,
	// VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE, VK_DYNAMIC_STATE_DEPTH_COMPARE_OP,
	// VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE, VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE,
	// VK_DYNAMIC_STATE_STENCIL_OP, and VK_DYNAMIC_STATE_DEPTH_BOUNDS dynamic states set.
	//
	// But pDepthStencilState can still be nullptr if no subpass uses depth/stencil.
	if(depthStencilState == nullptr)
	{
		return;
	}

	if(renderPass)
	{
		const VkSubpassDescription &subpass = renderPass->getSubpass(subpassIndex);

		// Ignore pDepthStencilState when "the subpass of the render pass the pipeline
		// is created against does not use a depth/stencil attachment"
		if(subpass.pDepthStencilAttachment &&
		   subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)
		{
			setDepthStencilState(depthStencilState);
		}
	}
	else  // No render pass
	{
		// When a pipeline is created without a VkRenderPass, if the VkPipelineRenderingCreateInfo structure
		// is present in the pNext chain of VkGraphicsPipelineCreateInfo, it specifies the view mask and
		// format of attachments used for rendering. If this structure is not specified, and the pipeline
		// does not include a VkRenderPass, viewMask and colorAttachmentCount are 0, and
		// depthAttachmentFormat and stencilAttachmentFormat are VK_FORMAT_UNDEFINED. If a graphics pipeline
		// is created with a valid VkRenderPass, parameters of this structure are ignored.

		if(rendering)
		{
			if((rendering->depthAttachmentFormat != VK_FORMAT_UNDEFINED) ||
			   (rendering->stencilAttachmentFormat != VK_FORMAT_UNDEFINED))
			{
				// If renderPass is VK_NULL_HANDLE, the pipeline is being created with fragment
				// shader state, and either of VkPipelineRenderingCreateInfo::depthAttachmentFormat
				// or VkPipelineRenderingCreateInfo::stencilAttachmentFormat are not
				// VK_FORMAT_UNDEFINED, pDepthStencilState must be a valid pointer to a valid
				// VkPipelineDepthStencilStateCreateInfo structure
				ASSERT(depthStencilState);

				setDepthStencilState(depthStencilState);
			}
		}
	}
}

void FragmentState::applyState(const DynamicState &dynamicState)
{
	if(dynamicStateFlags.dynamicDepthTestEnable)
	{
		depthTestEnable = dynamicState.depthTestEnable;
	}

	if(dynamicStateFlags.dynamicDepthWriteEnable)
	{
		depthWriteEnable = dynamicState.depthWriteEnable;
	}

	if(dynamicStateFlags.dynamicDepthBoundsTestEnable)
	{
		depthBoundsTestEnable = dynamicState.depthBoundsTestEnable;
	}

	if(dynamicStateFlags.dynamicDepthBounds && depthBoundsTestEnable)
	{
		minDepthBounds = dynamicState.minDepthBounds;
		maxDepthBounds = dynamicState.maxDepthBounds;
	}

	if(dynamicStateFlags.dynamicDepthCompareOp)
	{
		depthCompareMode = dynamicState.depthCompareOp;
	}

	if(dynamicStateFlags.dynamicStencilTestEnable)
	{
		stencilEnable = dynamicState.stencilTestEnable;
	}

	if(dynamicStateFlags.dynamicStencilOp && stencilEnable)
	{
		if(dynamicState.faceMask & VK_STENCIL_FACE_FRONT_BIT)
		{
			frontStencil.compareOp = dynamicState.frontStencil.compareOp;
			frontStencil.depthFailOp = dynamicState.frontStencil.depthFailOp;
			frontStencil.failOp = dynamicState.frontStencil.failOp;
			frontStencil.passOp = dynamicState.frontStencil.passOp;
		}

		if(dynamicState.faceMask & VK_STENCIL_FACE_BACK_BIT)
		{
			backStencil.compareOp = dynamicState.backStencil.compareOp;
			backStencil.depthFailOp = dynamicState.backStencil.depthFailOp;
			backStencil.failOp = dynamicState.backStencil.failOp;
			backStencil.passOp = dynamicState.backStencil.passOp;
		}
	}

	if(dynamicStateFlags.dynamicStencilCompareMask && stencilEnable)
	{
		frontStencil.compareMask = dynamicState.frontStencil.compareMask;
		backStencil.compareMask = dynamicState.backStencil.compareMask;
	}

	if(dynamicStateFlags.dynamicStencilWriteMask && stencilEnable)
	{
		frontStencil.writeMask = dynamicState.frontStencil.writeMask;
		backStencil.writeMask = dynamicState.backStencil.writeMask;
	}

	if(dynamicStateFlags.dynamicStencilReference && stencilEnable)
	{
		frontStencil.reference = dynamicState.frontStencil.reference;
		backStencil.reference = dynamicState.backStencil.reference;
	}
}

bool FragmentState::depthWriteActive(const Attachments &attachments) const
{
	// "Depth writes are always disabled when depthTestEnable is VK_FALSE."
	return depthTestActive(attachments) && depthWriteEnable;
}

bool FragmentState::depthTestActive(const Attachments &attachments) const
{
	return attachments.depthBuffer && depthTestEnable;
}

bool FragmentState::stencilActive(const Attachments &attachments) const
{
	return attachments.stencilBuffer && stencilEnable;
}

bool FragmentState::depthBoundsTestActive(const Attachments &attachments) const
{
	return attachments.depthBuffer && depthBoundsTestEnable;
}

void FragmentState::setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo *depthStencilState)
{
	if((depthStencilState->flags &
	    ~(VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT |
	      VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT)) != 0)
	{
		UNSUPPORTED("depthStencilState->flags 0x%08X", int(depthStencilState->flags));
	}

	depthBoundsTestEnable = (depthStencilState->depthBoundsTestEnable != VK_FALSE);
	minDepthBounds = depthStencilState->minDepthBounds;
	maxDepthBounds = depthStencilState->maxDepthBounds;

	depthTestEnable = (depthStencilState->depthTestEnable != VK_FALSE);
	depthWriteEnable = (depthStencilState->depthWriteEnable != VK_FALSE);
	depthCompareMode = depthStencilState->depthCompareOp;

	stencilEnable = (depthStencilState->stencilTestEnable != VK_FALSE);
	if(stencilEnable)
	{
		frontStencil = depthStencilState->front;
		backStencil = depthStencilState->back;
	}
}

void FragmentOutputInterfaceState::initialize(const VkPipelineColorBlendStateCreateInfo *colorBlendState,
                                              const VkPipelineMultisampleStateCreateInfo *multisampleState,
                                              const vk::RenderPass *renderPass, uint32_t subpassIndex,
                                              const VkPipelineRenderingCreateInfo *rendering,
                                              const DynamicStateFlags &allDynamicStateFlags)
{
	dynamicStateFlags = allDynamicStateFlags.fragmentOutputInterface;

	// The spec says:
	//
	// If the VK_EXT_extended_dynamic_state3 extension is enabled, it [pMultisampleState] can be
	// NULL if the pipeline is created with all of VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
	// VK_DYNAMIC_STATE_SAMPLE_MASK_EXT, and VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT
	// dynamic states set, and either the alphaToOne feature is not enabled or
	// VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT is set, in which case
	// VkPipelineMultisampleStateCreateInfo::sampleShadingEnable is assumed to be VK_FALSE.
	//
	// SwiftShader does not support alphaToOne.
	if(multisampleState == nullptr)
	{
		ASSERT(dynamicStateFlags.dynamicRasterizationSamples &&
		       dynamicStateFlags.dynamicSampleMask &&
		       dynamicStateFlags.dynamicAlphaToCoverageEnable);
	}
	else
	{
		multisample.set(dynamicStateFlags, multisampleState);
	}

	// The spec says:
	//
	// If the VK_EXT_extended_dynamic_state3 extension is enabled, it [pColorBlendState] can be
	// NULL if the pipeline is created with all of VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
	// VK_DYNAMIC_STATE_LOGIC_OP_EXT, VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
	// VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT, VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT, and
	// VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic states set.
	//
	// SwiftShader does not support logic op; if everything else is static there is no need to
	// look at colorBlendState.
	//
	// pColorBlendState may be nullptr if there are no attachments.
	if(colorBlendState == nullptr)
	{
		return;
	}

	if(renderPass)
	{
		const VkSubpassDescription &subpass = renderPass->getSubpass(subpassIndex);

		// Ignore pColorBlendState when "the subpass of the render pass the pipeline
		// is created against does not use any color attachments"
		for(uint32_t i = 0; i < subpass.colorAttachmentCount; i++)
		{
			if(subpass.pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED)
			{
				setColorBlendState(colorBlendState);
				break;
			}
		}
	}
	else  // No render pass
	{
		// When a pipeline is created without a VkRenderPass, if the VkPipelineRenderingCreateInfo structure
		// is present in the pNext chain of VkGraphicsPipelineCreateInfo, it specifies the view mask and
		// format of attachments used for rendering. If this structure is not specified, and the pipeline
		// does not include a VkRenderPass, viewMask and colorAttachmentCount are 0, and
		// depthAttachmentFormat and stencilAttachmentFormat are VK_FORMAT_UNDEFINED. If a graphics pipeline
		// is created with a valid VkRenderPass, parameters of this structure are ignored.

		if(rendering)
		{
			if(rendering->colorAttachmentCount > 0)
			{
				// If renderPass is VK_NULL_HANDLE, the pipeline is being created with fragment
				// output interface state, and VkPipelineRenderingCreateInfo::colorAttachmentCount
				// is not equal to 0, pColorBlendState must be a valid pointer to a valid
				// VkPipelineColorBlendStateCreateInfo structure
				ASSERT(colorBlendState);

				setColorBlendState(colorBlendState);
			}
		}
	}
}

void FragmentOutputInterfaceState::applyState(const DynamicState &dynamicState)
{
	// State that affects both Fragment and Fragment Output subsets are always stored in the
	// Fragment Output subset in SwiftShader
	if(dynamicStateFlags.dynamicRasterizationSamples)
	{
		multisample.sampleCount = dynamicState.rasterizationSamples;
	}

	if(dynamicStateFlags.dynamicSampleMask || dynamicStateFlags.dynamicRasterizationSamples)
	{
		unsigned int sampleMask = dynamicStateFlags.dynamicSampleMask ? dynamicState.sampleMask : multisample.staticSampleMask;
		multisample.multiSampleMask = sampleMask & ((unsigned)0xFFFFFFFF >> (32 - multisample.sampleCount));
	}

	if(dynamicStateFlags.dynamicAlphaToCoverageEnable)
	{
		multisample.alphaToCoverage = dynamicState.alphaToCoverageEnable;
	}

	if(dynamicStateFlags.dynamicBlendConstants)
	{
		blendConstants = dynamicState.blendConstants;
	}

	if(dynamicStateFlags.dynamicColorBlendEnable)
	{
		for(uint32_t i = 0; i < sw::MAX_COLOR_BUFFERS; ++i)
		{
			blendState[i].alphaBlendEnable = dynamicState.colorBlendEnables[i] != VK_FALSE;
		}
	}

	if(dynamicStateFlags.dynamicColorBlendEquation)
	{
		for(uint32_t i = 0; i < sw::MAX_COLOR_BUFFERS; ++i)
		{
			blendState[i].sourceBlendFactor = dynamicState.colorBlendEquations[i].srcColorBlendFactor;
			blendState[i].destBlendFactor = dynamicState.colorBlendEquations[i].dstColorBlendFactor;
			blendState[i].sourceBlendFactorAlpha = dynamicState.colorBlendEquations[i].srcAlphaBlendFactor;
			blendState[i].destBlendFactorAlpha = dynamicState.colorBlendEquations[i].dstAlphaBlendFactor;
			blendState[i].blendOperationAlpha = dynamicState.colorBlendEquations[i].alphaBlendOp;
		}
	}

	// colorBlendOp may be set either by COLOR_BLEND_EQUATION or COLOR_BLEND_ADVANCED dynamic
	// states
	if(dynamicStateFlags.dynamicColorBlendEquation || dynamicStateFlags.dynamicColorBlendAdvanced)
	{
		for(uint32_t i = 0; i < sw::MAX_COLOR_BUFFERS; ++i)
		{
			blendState[i].blendOperation = dynamicState.colorBlendEquations[i].colorBlendOp;
		}
	}

	if(dynamicStateFlags.dynamicColorWriteMask)
	{
		for(uint32_t i = 0; i < sw::MAX_COLOR_BUFFERS; ++i)
		{
			colorWriteMask[i] = dynamicState.colorWriteMasks[i];
		}
	}
}

void FragmentOutputInterfaceState::setColorBlendState(const VkPipelineColorBlendStateCreateInfo *colorBlendState)
{
	if(colorBlendState->flags != 0 &&
	   colorBlendState->flags != VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT)
	{
		UNSUPPORTED("colorBlendState->flags 0x%08X", int(colorBlendState->flags));
	}

	if(colorBlendState->logicOpEnable != VK_FALSE)
	{
		UNSUPPORTED("VkPhysicalDeviceFeatures::logicOp");
	}

	if(!dynamicStateFlags.dynamicBlendConstants)
	{
		blendConstants.x = colorBlendState->blendConstants[0];
		blendConstants.y = colorBlendState->blendConstants[1];
		blendConstants.z = colorBlendState->blendConstants[2];
		blendConstants.w = colorBlendState->blendConstants[3];
	}

	const VkBaseInStructure *extensionColorBlendInfo = reinterpret_cast<const VkBaseInStructure *>(colorBlendState->pNext);
	while(extensionColorBlendInfo)
	{
		switch(extensionColorBlendInfo->sType)
		{
		case VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT:
			{
				const VkPipelineColorBlendAdvancedStateCreateInfoEXT *colorBlendAdvancedCreateInfo = reinterpret_cast<const VkPipelineColorBlendAdvancedStateCreateInfoEXT *>(extensionColorBlendInfo);
				ASSERT(colorBlendAdvancedCreateInfo->blendOverlap == VK_BLEND_OVERLAP_UNCORRELATED_EXT);
				ASSERT(colorBlendAdvancedCreateInfo->dstPremultiplied == VK_TRUE);
				ASSERT(colorBlendAdvancedCreateInfo->srcPremultiplied == VK_TRUE);
			}
			break;
		case VK_STRUCTURE_TYPE_MAX_ENUM:
			// dEQP tests that this value is ignored.
			break;
		default:
			UNSUPPORTED("colorBlendState->pNext sType = %s", vk::Stringify(extensionColorBlendInfo->sType).c_str());
			break;
		}

		extensionColorBlendInfo = extensionColorBlendInfo->pNext;
	}

	if(colorBlendState->pAttachments)
	{
		ASSERT(colorBlendState->attachmentCount <= sw::MAX_COLOR_BUFFERS);
		for(auto i = 0u; i < colorBlendState->attachmentCount; i++)
		{
			const VkPipelineColorBlendAttachmentState &attachment = colorBlendState->pAttachments[i];
			colorWriteMask[i] = attachment.colorWriteMask;
			blendState[i] = { (attachment.blendEnable != VK_FALSE),
				              attachment.srcColorBlendFactor, attachment.dstColorBlendFactor, attachment.colorBlendOp,
				              attachment.srcAlphaBlendFactor, attachment.dstAlphaBlendFactor, attachment.alphaBlendOp };
		}
	}
}

BlendState FragmentOutputInterfaceState::getBlendState(int location, const Attachments &attachments, bool fragmentContainsKill) const
{
	ASSERT((location >= 0) && (location < sw::MAX_COLOR_BUFFERS));
	const uint32_t index = attachments.locationToIndex[location];
	if(index == VK_ATTACHMENT_UNUSED)
	{
		return {};
	}

	ASSERT((index >= 0) && (index < sw::MAX_COLOR_BUFFERS));
	auto &state = blendState[index];

	BlendState activeBlendState = {};
	activeBlendState.alphaBlendEnable = alphaBlendActive(location, attachments, fragmentContainsKill);

	if(activeBlendState.alphaBlendEnable)
	{
		vk::Format format = attachments.colorBuffer[location]->getFormat(VK_IMAGE_ASPECT_COLOR_BIT);

		activeBlendState.sourceBlendFactor = blendFactor(state.blendOperation, state.sourceBlendFactor);
		activeBlendState.destBlendFactor = blendFactor(state.blendOperation, state.destBlendFactor);
		activeBlendState.blendOperation = blendOperation(state.blendOperation, state.sourceBlendFactor, state.destBlendFactor, format);
		activeBlendState.sourceBlendFactorAlpha = blendFactor(state.blendOperationAlpha, state.sourceBlendFactorAlpha);
		activeBlendState.destBlendFactorAlpha = blendFactor(state.blendOperationAlpha, state.destBlendFactorAlpha);
		activeBlendState.blendOperationAlpha = blendOperation(state.blendOperationAlpha, state.sourceBlendFactorAlpha, state.destBlendFactorAlpha, format);
	}

	return activeBlendState;
}

bool FragmentOutputInterfaceState::alphaBlendActive(int location, const Attachments &attachments, bool fragmentContainsKill) const
{
	ASSERT((location >= 0) && (location < sw::MAX_COLOR_BUFFERS));
	const uint32_t index = attachments.locationToIndex[location];
	if(index == VK_ATTACHMENT_UNUSED)
	{
		return false;
	}

	ASSERT((index >= 0) && (index < sw::MAX_COLOR_BUFFERS));
	auto &state = blendState[index];

	if(!attachments.colorBuffer[location] || !blendState[index].alphaBlendEnable)
	{
		return false;
	}

	if(!(colorWriteActive(attachments) || fragmentContainsKill))
	{
		return false;
	}

	vk::Format format = attachments.colorBuffer[location]->getFormat(VK_IMAGE_ASPECT_COLOR_BIT);
	bool colorBlend = blendOperation(state.blendOperation, state.sourceBlendFactor, state.destBlendFactor, format) != VK_BLEND_OP_SRC_EXT;
	bool alphaBlend = blendOperation(state.blendOperationAlpha, state.sourceBlendFactorAlpha, state.destBlendFactorAlpha, format) != VK_BLEND_OP_SRC_EXT;

	return colorBlend || alphaBlend;
}

VkBlendFactor FragmentOutputInterfaceState::blendFactor(VkBlendOp blendOperation, VkBlendFactor blendFactor) const
{
	switch(blendOperation)
	{
	case VK_BLEND_OP_ADD:
	case VK_BLEND_OP_SUBTRACT:
	case VK_BLEND_OP_REVERSE_SUBTRACT:
		return blendFactor;
	case VK_BLEND_OP_MIN:
	case VK_BLEND_OP_MAX:
	case VK_BLEND_OP_MULTIPLY_EXT:
	case VK_BLEND_OP_SCREEN_EXT:
	case VK_BLEND_OP_OVERLAY_EXT:
	case VK_BLEND_OP_DARKEN_EXT:
	case VK_BLEND_OP_LIGHTEN_EXT:
	case VK_BLEND_OP_COLORDODGE_EXT:
	case VK_BLEND_OP_COLORBURN_EXT:
	case VK_BLEND_OP_HARDLIGHT_EXT:
	case VK_BLEND_OP_SOFTLIGHT_EXT:
	case VK_BLEND_OP_DIFFERENCE_EXT:
	case VK_BLEND_OP_EXCLUSION_EXT:
	case VK_BLEND_OP_HSL_HUE_EXT:
	case VK_BLEND_OP_HSL_SATURATION_EXT:
	case VK_BLEND_OP_HSL_COLOR_EXT:
	case VK_BLEND_OP_HSL_LUMINOSITY_EXT:
		return VK_BLEND_FACTOR_ONE;
	default:
		ASSERT(false);
		return blendFactor;
	}
}

VkBlendOp FragmentOutputInterfaceState::blendOperation(VkBlendOp blendOperation, VkBlendFactor sourceBlendFactor, VkBlendFactor destBlendFactor, vk::Format format) const
{
	switch(blendOperation)
	{
	case VK_BLEND_OP_ADD:
		if(sourceBlendFactor == VK_BLEND_FACTOR_ZERO)
		{
			if(destBlendFactor == VK_BLEND_FACTOR_ZERO)
			{
				return VK_BLEND_OP_ZERO_EXT;
			}
			else if(destBlendFactor == VK_BLEND_FACTOR_ONE)
			{
				return VK_BLEND_OP_DST_EXT;
			}
		}
		else if(sourceBlendFactor == VK_BLEND_FACTOR_ONE)
		{
			if(destBlendFactor == VK_BLEND_FACTOR_ZERO)
			{
				return VK_BLEND_OP_SRC_EXT;
			}
		}
		break;
	case VK_BLEND_OP_SUBTRACT:
		if(sourceBlendFactor == VK_BLEND_FACTOR_ZERO)
		{
			if(destBlendFactor == VK_BLEND_FACTOR_ZERO)
			{
				return VK_BLEND_OP_ZERO_EXT;
			}
			else if(format.isUnsignedNormalized())
			{
				return VK_BLEND_OP_ZERO_EXT;  // Negative, clamped to zero
			}
		}
		else if(sourceBlendFactor == VK_BLEND_FACTOR_ONE)
		{
			if(destBlendFactor == VK_BLEND_FACTOR_ZERO)
			{
				return VK_BLEND_OP_SRC_EXT;
			}
		}
		break;
	case VK_BLEND_OP_REVERSE_SUBTRACT:
		if(sourceBlendFactor == VK_BLEND_FACTOR_ZERO)
		{
			if(destBlendFactor == VK_BLEND_FACTOR_ZERO)
			{
				return VK_BLEND_OP_ZERO_EXT;
			}
			else if(destBlendFactor == VK_BLEND_FACTOR_ONE)
			{
				return VK_BLEND_OP_DST_EXT;
			}
		}
		else
		{
			if(destBlendFactor == VK_BLEND_FACTOR_ZERO && format.isUnsignedNormalized())
			{
				return VK_BLEND_OP_ZERO_EXT;  // Negative, clamped to zero
			}
		}
		break;
	case VK_BLEND_OP_MIN:
		return VK_BLEND_OP_MIN;
	case VK_BLEND_OP_MAX:
		return VK_BLEND_OP_MAX;
	case VK_BLEND_OP_MULTIPLY_EXT:
	case VK_BLEND_OP_SCREEN_EXT:
	case VK_BLEND_OP_OVERLAY_EXT:
	case VK_BLEND_OP_DARKEN_EXT:
	case VK_BLEND_OP_LIGHTEN_EXT:
	case VK_BLEND_OP_COLORDODGE_EXT:
	case VK_BLEND_OP_COLORBURN_EXT:
	case VK_BLEND_OP_HARDLIGHT_EXT:
	case VK_BLEND_OP_SOFTLIGHT_EXT:
	case VK_BLEND_OP_DIFFERENCE_EXT:
	case VK_BLEND_OP_EXCLUSION_EXT:
	case VK_BLEND_OP_HSL_HUE_EXT:
	case VK_BLEND_OP_HSL_SATURATION_EXT:
	case VK_BLEND_OP_HSL_COLOR_EXT:
	case VK_BLEND_OP_HSL_LUMINOSITY_EXT:
		return blendOperation;
	default:
		ASSERT(false);
	}

	return blendOperation;
}

bool FragmentOutputInterfaceState::colorWriteActive(const Attachments &attachments) const
{
	for(int i = 0; i < sw::MAX_COLOR_BUFFERS; i++)
	{
		if(colorWriteActive(i, attachments))
		{
			return true;
		}
	}

	return false;
}

int FragmentOutputInterfaceState::colorWriteActive(int location, const Attachments &attachments) const
{
	ASSERT((location >= 0) && (location < sw::MAX_COLOR_BUFFERS));
	const uint32_t index = attachments.locationToIndex[location];
	if(index == VK_ATTACHMENT_UNUSED)
	{
		return 0;
	}

	ASSERT((index >= 0) && (index < sw::MAX_COLOR_BUFFERS));
	auto &state = blendState[index];

	if(!attachments.colorBuffer[location] || attachments.colorBuffer[location]->getFormat() == VK_FORMAT_UNDEFINED)
	{
		return 0;
	}

	vk::Format format = attachments.colorBuffer[location]->getFormat(VK_IMAGE_ASPECT_COLOR_BIT);

	if(state.alphaBlendEnable &&
	   blendOperation(state.blendOperation, state.sourceBlendFactor, state.destBlendFactor, format) == VK_BLEND_OP_DST_EXT &&
	   blendOperation(state.blendOperationAlpha, state.sourceBlendFactorAlpha, state.destBlendFactorAlpha, format) == VK_BLEND_OP_DST_EXT)
	{
		return 0;
	}

	return colorWriteMask[index];
}

GraphicsState::GraphicsState(const Device *device, const VkGraphicsPipelineCreateInfo *pCreateInfo,
                             const PipelineLayout *layout)
{
	if((pCreateInfo->flags &
	    ~(VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT |
	      VK_PIPELINE_CREATE_DERIVATIVE_BIT |
	      VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT |
	      VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT |
	      VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT |
	      VK_PIPELINE_CREATE_LIBRARY_BIT_KHR |
	      VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT |
	      VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT)) != 0)
	{
		UNSUPPORTED("pCreateInfo->flags 0x%08X", int(pCreateInfo->flags));
	}

	DynamicStateFlags dynamicStateFlags = ParseDynamicStateFlags(pCreateInfo->pDynamicState);
	const auto *rendering = GetExtendedStruct<VkPipelineRenderingCreateInfo>(pCreateInfo, VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO);

	// First, get the subset of state specified in pCreateInfo itself.
	validSubset = GraphicsPipeline::GetGraphicsPipelineSubset(pCreateInfo);

	// If rasterizer discard is enabled (and not dynamically overridable), ignore the fragment
	// and fragment output subsets, as they will not be used.
	if((validSubset & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) != 0 &&
	   !dynamicStateFlags.preRasterization.dynamicRasterizerDiscardEnable &&
	   pCreateInfo->pRasterizationState->rasterizerDiscardEnable)
	{
		validSubset &= ~(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT | VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT);
	}

	if((validSubset & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) != 0)
	{
		vertexInputInterfaceState.initialize(pCreateInfo->pVertexInputState,
		                                     pCreateInfo->pInputAssemblyState,
		                                     dynamicStateFlags);
	}
	if((validSubset & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) != 0)
	{
		preRasterizationState.initialize(device,
		                                 layout,
		                                 pCreateInfo->pViewportState,
		                                 pCreateInfo->pRasterizationState,
		                                 vk::Cast(pCreateInfo->renderPass),
		                                 pCreateInfo->subpass,
		                                 rendering,
		                                 dynamicStateFlags);
	}
	if((validSubset & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) != 0)
	{
		fragmentState.initialize(layout,
		                         pCreateInfo->pDepthStencilState,
		                         vk::Cast(pCreateInfo->renderPass),
		                         pCreateInfo->subpass,
		                         rendering,
		                         dynamicStateFlags);
	}
	if((validSubset & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) != 0)
	{
		fragmentOutputInterfaceState.initialize(pCreateInfo->pColorBlendState,
		                                        pCreateInfo->pMultisampleState,
		                                        vk::Cast(pCreateInfo->renderPass),
		                                        pCreateInfo->subpass,
		                                        rendering,
		                                        dynamicStateFlags);
	}

	// Then, apply state coming from pipeline libraries.
	const auto *libraryCreateInfo = vk::GetExtendedStruct<VkPipelineLibraryCreateInfoKHR>(pCreateInfo->pNext, VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR);
	if(libraryCreateInfo)
	{
		for(uint32_t i = 0; i < libraryCreateInfo->libraryCount; ++i)
		{
			const auto *library = static_cast<const GraphicsPipeline *>(vk::Cast(libraryCreateInfo->pLibraries[i]));
			const GraphicsState &libraryState = library->getState();
			const VkGraphicsPipelineLibraryFlagsEXT librarySubset = libraryState.validSubset;

			// The library subsets should be disjoint
			ASSERT((libraryState.validSubset & validSubset) == 0);

			if((librarySubset & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) != 0)
			{
				vertexInputInterfaceState = libraryState.vertexInputInterfaceState;
			}
			if((librarySubset & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) != 0)
			{
				preRasterizationState = libraryState.preRasterizationState;
				if(layout)
				{
					preRasterizationState.overridePipelineLayout(layout);
				}
			}
			if((librarySubset & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) != 0)
			{
				fragmentState = libraryState.fragmentState;
				if(layout)
				{
					fragmentState.overridePipelineLayout(layout);
				}
			}
			if((librarySubset & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) != 0)
			{
				fragmentOutputInterfaceState = libraryState.fragmentOutputInterfaceState;
			}

			validSubset |= libraryState.validSubset;
		}
	}
}

GraphicsState GraphicsState::combineStates(const DynamicState &dynamicState) const
{
	GraphicsState combinedState = *this;

	// Make a copy of the states for modification, then either keep the pipeline state or apply the dynamic state.
	combinedState.vertexInputInterfaceState.applyState(dynamicState);
	combinedState.preRasterizationState.applyState(dynamicState);
	combinedState.fragmentState.applyState(dynamicState);
	combinedState.fragmentOutputInterfaceState.applyState(dynamicState);

	return combinedState;
}

}  // namespace vk
