Home | History | Annotate | Download | only in dynamic_state
      1 /*------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2015 The Khronos Group Inc.
      6  * Copyright (c) 2015 Intel Corporation
      7  *
      8  * Licensed under the Apache License, Version 2.0 (the "License");
      9  * you may not use this file except in compliance with the License.
     10  * You may obtain a copy of the License at
     11  *
     12  *      http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing, software
     15  * distributed under the License is distributed on an "AS IS" BASIS,
     16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17  * See the License for the specific language governing permissions and
     18  * limitations under the License.
     19  *
     20  *//*!
     21  * \file
     22  * \brief Dynamic Raster State Tests
     23  *//*--------------------------------------------------------------------*/
     24 
     25 #include "vktDynamicStateRSTests.hpp"
     26 
     27 #include "vktDynamicStateBaseClass.hpp"
     28 #include "vktDynamicStateTestCaseUtil.hpp"
     29 
     30 #include "vkImageUtil.hpp"
     31 
     32 #include "tcuTextureUtil.hpp"
     33 #include "tcuImageCompare.hpp"
     34 #include "tcuRGBA.hpp"
     35 
     36 #include "deMath.h"
     37 
     38 namespace vkt
     39 {
     40 namespace DynamicState
     41 {
     42 
     43 using namespace Draw;
     44 
     45 namespace
     46 {
     47 
     48 class DepthBiasBaseCase : public TestInstance
     49 {
     50 public:
     51 	DepthBiasBaseCase (Context& context, const char* vertexShaderName, const char* fragmentShaderName)
     52 		: TestInstance						(context)
     53 		, m_colorAttachmentFormat			(vk::VK_FORMAT_R8G8B8A8_UNORM)
     54 		, m_topology						(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
     55 		, m_vk								(context.getDeviceInterface())
     56 		, m_vertexShaderName				(vertexShaderName)
     57 		, m_fragmentShaderName				(fragmentShaderName)
     58 	{
     59 	}
     60 
     61 protected:
     62 
     63 	enum
     64 	{
     65 		WIDTH	= 128,
     66 		HEIGHT	= 128
     67 	};
     68 
     69 	vk::VkFormat									m_colorAttachmentFormat;
     70 	vk::VkFormat									m_depthStencilAttachmentFormat;
     71 
     72 	vk::VkPrimitiveTopology							m_topology;
     73 
     74 	const vk::DeviceInterface&						m_vk;
     75 
     76 	vk::Move<vk::VkPipeline>						m_pipeline;
     77 	vk::Move<vk::VkPipelineLayout>					m_pipelineLayout;
     78 
     79 	de::SharedPtr<Image>							m_colorTargetImage;
     80 	vk::Move<vk::VkImageView>						m_colorTargetView;
     81 
     82 	de::SharedPtr<Image>							m_depthStencilImage;
     83 	vk::Move<vk::VkImageView>						m_attachmentView;
     84 
     85 	PipelineCreateInfo::VertexInputState			m_vertexInputState;
     86 	de::SharedPtr<Buffer>							m_vertexBuffer;
     87 
     88 	vk::Move<vk::VkCommandPool>						m_cmdPool;
     89 	vk::Move<vk::VkCommandBuffer>					m_cmdBuffer;
     90 
     91 	vk::Move<vk::VkFramebuffer>						m_framebuffer;
     92 	vk::Move<vk::VkRenderPass>						m_renderPass;
     93 
     94 	std::string										m_vertexShaderName;
     95 	std::string										m_fragmentShaderName;
     96 
     97 	std::vector<PositionColorVertex>				m_data;
     98 
     99 	PipelineCreateInfo::DepthStencilState			m_depthStencilState;
    100 
    101 	void initialize (void)
    102 	{
    103 		const vk::VkDevice device	= m_context.getDevice();
    104 
    105 		vk::VkFormatProperties formatProperties;
    106 		// check for VK_FORMAT_D24_UNORM_S8_UINT support
    107 		m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties);
    108 		if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
    109 		{
    110 			m_depthStencilAttachmentFormat = vk::VK_FORMAT_D24_UNORM_S8_UINT;
    111 		}
    112 		else
    113 		{
    114 			// check for VK_FORMAT_D32_SFLOAT_S8_UINT support
    115 			m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProperties);
    116 			if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
    117 			{
    118 				m_depthStencilAttachmentFormat = vk::VK_FORMAT_D32_SFLOAT_S8_UINT;
    119 			}
    120 			else
    121 				throw tcu::NotSupportedError("No valid depth stencil attachment available");
    122 		}
    123 
    124 		const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
    125 		m_pipelineLayout			= vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
    126 
    127 		const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
    128 		const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
    129 
    130 		const vk::VkExtent3D imageExtent = { WIDTH, HEIGHT, 1 };
    131 		ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
    132 											  vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
    133 
    134 		m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator());
    135 
    136 		const ImageCreateInfo depthStencilImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthStencilAttachmentFormat, imageExtent,
    137 														  1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
    138 														  vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
    139 
    140 		m_depthStencilImage = Image::createAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator());
    141 
    142 		const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
    143 		m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
    144 
    145 		const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthStencilAttachmentFormat);
    146 		m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo);
    147 
    148 		RenderPassCreateInfo renderPassCreateInfo;
    149 		renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
    150 																 vk::VK_SAMPLE_COUNT_1_BIT,
    151 																 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
    152 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
    153 																 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
    154 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
    155 																 vk::VK_IMAGE_LAYOUT_GENERAL,
    156 																 vk::VK_IMAGE_LAYOUT_GENERAL));
    157 
    158 		renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthStencilAttachmentFormat,
    159 																 vk::VK_SAMPLE_COUNT_1_BIT,
    160 																 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
    161 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
    162 																 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
    163 																 vk::VK_ATTACHMENT_STORE_OP_STORE,
    164 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
    165 																 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
    166 
    167 		const vk::VkAttachmentReference colorAttachmentReference =
    168 		{
    169 			0,
    170 			vk::VK_IMAGE_LAYOUT_GENERAL
    171 		};
    172 
    173 		const vk::VkAttachmentReference depthAttachmentReference =
    174 		{
    175 			1,
    176 			vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
    177 		};
    178 
    179 		renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
    180 														   0,
    181 														   0,
    182 														   DE_NULL,
    183 														   1,
    184 														   &colorAttachmentReference,
    185 														   DE_NULL,
    186 														   depthAttachmentReference,
    187 														   0,
    188 														   DE_NULL));
    189 
    190 		m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
    191 
    192 		const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
    193 		{
    194 			0,
    195 			(deUint32)sizeof(tcu::Vec4) * 2,
    196 			vk::VK_VERTEX_INPUT_RATE_VERTEX,
    197 		};
    198 
    199 		const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
    200 		{
    201 			{
    202 				0u,
    203 				0u,
    204 				vk::VK_FORMAT_R32G32B32A32_SFLOAT,
    205 				0u
    206 			},
    207 			{
    208 				1u,
    209 				0u,
    210 				vk::VK_FORMAT_R32G32B32A32_SFLOAT,
    211 				(deUint32)(sizeof(float)* 4),
    212 			}
    213 		};
    214 
    215 		m_vertexInputState = PipelineCreateInfo::VertexInputState(1,
    216 																  &vertexInputBindingDescription,
    217 																  2,
    218 																  vertexInputAttributeDescriptions);
    219 
    220 		const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
    221 
    222 		PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
    223 		pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
    224 		pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
    225 		pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
    226 		pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
    227 		pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
    228 		pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1));
    229 		pipelineCreateInfo.addState(m_depthStencilState);
    230 		pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
    231 		pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
    232 		pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState());
    233 
    234 		m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
    235 
    236 		std::vector<vk::VkImageView> attachments(2);
    237 		attachments[0] = *m_colorTargetView;
    238 		attachments[1] = *m_attachmentView;
    239 
    240 		const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
    241 
    242 		m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
    243 
    244 		const vk::VkDeviceSize dataSize = m_data.size() * sizeof(PositionColorVertex);
    245 		m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize,
    246 			vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
    247 			m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
    248 
    249 		deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
    250 		deMemcpy(ptr, &m_data[0], static_cast<size_t>(dataSize));
    251 
    252 		vk::flushMappedMemoryRange(m_vk, device,
    253 								   m_vertexBuffer->getBoundMemory().getMemory(),
    254 								   m_vertexBuffer->getBoundMemory().getOffset(),
    255 								   dataSize);
    256 
    257 		const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
    258 		m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
    259 
    260 		const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
    261 		{
    262 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
    263 			DE_NULL,											// const void*				pNext;
    264 			*m_cmdPool,											// VkCommandPool			commandPool;
    265 			vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
    266 			1u,													// deUint32					bufferCount;
    267 		};
    268 		m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, &cmdBufferAllocateInfo);
    269 	}
    270 
    271 	virtual tcu::TestStatus iterate (void)
    272 	{
    273 		DE_ASSERT(false);
    274 		return tcu::TestStatus::fail("Should reimplement iterate() method");
    275 	}
    276 
    277 	void beginRenderPass (void)
    278 	{
    279 		const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
    280 		beginRenderPassWithClearColor(clearColor);
    281 	}
    282 
    283 	void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor)
    284 	{
    285 		const CmdBufferBeginInfo beginInfo;
    286 		m_vk.beginCommandBuffer(*m_cmdBuffer, &beginInfo);
    287 
    288 		initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL);
    289 		initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, vk::VK_ACCESS_TRANSFER_WRITE_BIT);
    290 
    291 		const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT);
    292 		m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
    293 								vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRangeImage);
    294 
    295 		const vk::VkClearDepthStencilValue depthStencilClearValue = { 0.0f, 0 };
    296 
    297 		const ImageSubresourceRange subresourceRangeDepthStencil[2] = { vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_ASPECT_STENCIL_BIT };
    298 
    299 		m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(),
    300 									   vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencilClearValue, 2, subresourceRangeDepthStencil);
    301 
    302 		const vk::VkMemoryBarrier memBarrier =
    303 		{
    304 			vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
    305 			DE_NULL,
    306 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
    307 			vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
    308 				vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
    309 		};
    310 
    311 		m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
    312 			vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
    313 			vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
    314 			0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
    315 
    316 		const vk::VkRect2D renderArea = { { 0, 0 }, { WIDTH, HEIGHT } };
    317 		const RenderPassBeginInfo renderPassBegin(*m_renderPass, *m_framebuffer, renderArea);
    318 
    319 		transition2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
    320 
    321 		m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBegin, vk::VK_SUBPASS_CONTENTS_INLINE);
    322 	}
    323 
    324 	void setDynamicViewportState (const deUint32 width, const deUint32 height)
    325 	{
    326 		vk::VkViewport viewport;
    327 		viewport.x = 0;
    328 		viewport.y = 0;
    329 		viewport.width = static_cast<float>(width);
    330 		viewport.height = static_cast<float>(height);
    331 		viewport.minDepth = 0.0f;
    332 		viewport.maxDepth = 1.0f;
    333 
    334 		m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
    335 
    336 		vk::VkRect2D scissor;
    337 		scissor.offset.x = 0;
    338 		scissor.offset.y = 0;
    339 		scissor.extent.width = width;
    340 		scissor.extent.height = height;
    341 		m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
    342 	}
    343 
    344 	void setDynamicViewportState (const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
    345 	{
    346 		m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
    347 		m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
    348 	}
    349 
    350 	void setDynamicRasterizationState (const float lineWidth = 1.0f,
    351 		const float depthBiasConstantFactor = 0.0f,
    352 		const float depthBiasClamp = 0.0f,
    353 		const float depthBiasSlopeFactor = 0.0f)
    354 	{
    355 		m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
    356 		m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
    357 	}
    358 
    359 	void setDynamicBlendState (const float const1 = 0.0f, const float const2 = 0.0f,
    360 		const float const3 = 0.0f, const float const4 = 0.0f)
    361 	{
    362 		float blendConstantsants[4] = { const1, const2, const3, const4 };
    363 		m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
    364 	}
    365 
    366 	void setDynamicDepthStencilState (const float minDepthBounds = -1.0f, const float maxDepthBounds = 1.0f,
    367 		const deUint32 stencilFrontCompareMask = 0xffffffffu, const deUint32 stencilFrontWriteMask = 0xffffffffu,
    368 		const deUint32 stencilFrontReference = 0, const deUint32 stencilBackCompareMask = 0xffffffffu,
    369 		const deUint32 stencilBackWriteMask = 0xffffffffu, const deUint32 stencilBackReference = 0)
    370 	{
    371 		m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
    372 		m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
    373 		m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
    374 		m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
    375 		m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
    376 		m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
    377 		m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
    378 	}
    379 };
    380 
    381 class DepthBiasParamTestInstance : public DepthBiasBaseCase
    382 {
    383 public:
    384 	DepthBiasParamTestInstance (Context& context, ShaderMap shaders)
    385 		: DepthBiasBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
    386 	{
    387 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
    388 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
    389 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
    390 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
    391 
    392 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
    393 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
    394 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
    395 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
    396 
    397 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
    398 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
    399 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
    400 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
    401 
    402 		// enable depth test
    403 		m_depthStencilState = PipelineCreateInfo::DepthStencilState(
    404 			VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_GREATER_OR_EQUAL);
    405 
    406 		DepthBiasBaseCase::initialize();
    407 	}
    408 
    409 	virtual tcu::TestStatus iterate (void)
    410 	{
    411 		tcu::TestLog &log		= m_context.getTestContext().getLog();
    412 		const vk::VkQueue queue = m_context.getUniversalQueue();
    413 
    414 		beginRenderPass();
    415 
    416 		// set states here
    417 		setDynamicViewportState(WIDTH, HEIGHT);
    418 		setDynamicBlendState();
    419 		setDynamicDepthStencilState();
    420 
    421 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
    422 
    423 		const vk::VkDeviceSize vertexBufferOffset	= 0;
    424 		const vk::VkBuffer vertexBuffer				= m_vertexBuffer->object();
    425 		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
    426 
    427 		setDynamicRasterizationState(1.0f, 0.0f);
    428 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
    429 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
    430 
    431 		setDynamicRasterizationState(1.0f, -1.0f);
    432 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
    433 
    434 		m_vk.cmdEndRenderPass(*m_cmdBuffer);
    435 		m_vk.endCommandBuffer(*m_cmdBuffer);
    436 
    437 		vk::VkSubmitInfo submitInfo =
    438 		{
    439 			vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
    440 			DE_NULL,							// const void*				pNext;
    441 			0,									// deUint32					waitSemaphoreCount;
    442 			DE_NULL,							// const VkSemaphore*		pWaitSemaphores;
    443 			(const vk::VkPipelineStageFlags*)DE_NULL,
    444 			1,									// deUint32					commandBufferCount;
    445 			&m_cmdBuffer.get(),					// const VkCommandBuffer*	pCommandBuffers;
    446 			0,									// deUint32					signalSemaphoreCount;
    447 			DE_NULL								// const VkSemaphore*		pSignalSemaphores;
    448 		};
    449 		m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
    450 
    451 		// validation
    452 		{
    453 			VK_CHECK(m_vk.queueWaitIdle(queue));
    454 
    455 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
    456 			referenceFrame.allocLevel(0);
    457 
    458 			const deInt32 frameWidth = referenceFrame.getWidth();
    459 			const deInt32 frameHeight = referenceFrame.getHeight();
    460 
    461 			tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
    462 
    463 			for (int y = 0; y < frameHeight; y++)
    464 			{
    465 				const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
    466 
    467 				for (int x = 0; x < frameWidth; x++)
    468 				{
    469 					const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
    470 
    471 					if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
    472 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
    473 					else
    474 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
    475 				}
    476 			}
    477 
    478 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
    479 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
    480 				vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
    481 
    482 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
    483 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
    484 				tcu::COMPARE_LOG_RESULT))
    485 			{
    486 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
    487 			}
    488 
    489 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
    490 		}
    491 	}
    492 };
    493 
    494 class DepthBiasClampParamTestInstance : public DepthBiasBaseCase
    495 {
    496 public:
    497 	DepthBiasClampParamTestInstance (Context& context, ShaderMap shaders)
    498 		: DepthBiasBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
    499 	{
    500 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
    501 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
    502 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
    503 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
    504 
    505 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
    506 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
    507 		m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
    508 		m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
    509 
    510 		// enable depth test
    511 		m_depthStencilState = PipelineCreateInfo::DepthStencilState(VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_GREATER_OR_EQUAL);
    512 
    513 		DepthBiasBaseCase::initialize();
    514 	}
    515 
    516 	virtual tcu::TestStatus iterate (void)
    517 	{
    518 		tcu::TestLog &log = m_context.getTestContext().getLog();
    519 		const vk::VkQueue queue = m_context.getUniversalQueue();
    520 
    521 		beginRenderPass();
    522 
    523 		// set states here
    524 		setDynamicViewportState(WIDTH, HEIGHT);
    525 		setDynamicBlendState();
    526 		setDynamicDepthStencilState();
    527 
    528 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
    529 
    530 		const vk::VkDeviceSize vertexBufferOffset = 0;
    531 		const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
    532 		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
    533 
    534 		setDynamicRasterizationState(1.0f, 1000.0f, 0.005f);
    535 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
    536 
    537 		setDynamicRasterizationState(1.0f, 0.0f);
    538 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
    539 
    540 		m_vk.cmdEndRenderPass(*m_cmdBuffer);
    541 		m_vk.endCommandBuffer(*m_cmdBuffer);
    542 
    543 		vk::VkSubmitInfo submitInfo =
    544 		{
    545 			vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
    546 			DE_NULL,							// const void*				pNext;
    547 			0,									// deUint32					waitSemaphoreCount;
    548 			DE_NULL,							// const VkSemaphore*		pWaitSemaphores;
    549 			(const vk::VkPipelineStageFlags*)DE_NULL,
    550 			1,									// deUint32					commandBufferCount;
    551 			&m_cmdBuffer.get(),					// const VkCommandBuffer*	pCommandBuffers;
    552 			0,									// deUint32					signalSemaphoreCount;
    553 			DE_NULL								// const VkSemaphore*		pSignalSemaphores;
    554 		};
    555 		m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
    556 
    557 		// validation
    558 		{
    559 			VK_CHECK(m_vk.queueWaitIdle(queue));
    560 
    561 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
    562 			referenceFrame.allocLevel(0);
    563 
    564 			const deInt32 frameWidth	= referenceFrame.getWidth();
    565 			const deInt32 frameHeight	= referenceFrame.getHeight();
    566 
    567 			tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
    568 
    569 			for (int y = 0; y < frameHeight; y++)
    570 			{
    571 				float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
    572 
    573 				for (int x = 0; x < frameWidth; x++)
    574 				{
    575 					float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
    576 
    577 					if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
    578 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
    579 					else
    580 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
    581 				}
    582 			}
    583 
    584 			const vk::VkOffset3D zeroOffset					= { 0, 0, 0 };
    585 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
    586 				vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
    587 
    588 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
    589 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
    590 				tcu::COMPARE_LOG_RESULT))
    591 			{
    592 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
    593 			}
    594 
    595 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
    596 		}
    597 	}
    598 };
    599 
    600 class LineWidthParamTestInstance : public DynamicStateBaseClass
    601 {
    602 public:
    603 	LineWidthParamTestInstance (Context& context, ShaderMap shaders)
    604 		: DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
    605 	{
    606 		// Check if line width test is supported
    607 		{
    608 			const vk::VkPhysicalDeviceFeatures& deviceFeatures = m_context.getDeviceFeatures();
    609 
    610 			if (!deviceFeatures.wideLines)
    611 				throw tcu::NotSupportedError("Line width test is unsupported");
    612 		}
    613 
    614 		m_topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
    615 
    616 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), tcu::RGBA::green().toVec()));
    617 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::RGBA::green().toVec()));
    618 
    619 		DynamicStateBaseClass::initialize();
    620 	}
    621 
    622 	virtual tcu::TestStatus iterate (void)
    623 	{
    624 		tcu::TestLog &log		= m_context.getTestContext().getLog();
    625 		const vk::VkQueue queue = m_context.getUniversalQueue();
    626 
    627 		beginRenderPass();
    628 
    629 		// set states here
    630 		vk::VkPhysicalDeviceProperties deviceProperties;
    631 		m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
    632 
    633 		setDynamicViewportState(WIDTH, HEIGHT);
    634 		setDynamicBlendState();
    635 		setDynamicDepthStencilState();
    636 		setDynamicRasterizationState(deFloatFloor(deviceProperties.limits.lineWidthRange[1]));
    637 
    638 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
    639 
    640 		const vk::VkDeviceSize vertexBufferOffset	= 0;
    641 		const vk::VkBuffer vertexBuffer				= m_vertexBuffer->object();
    642 		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
    643 
    644 		m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
    645 
    646 		m_vk.cmdEndRenderPass(*m_cmdBuffer);
    647 		m_vk.endCommandBuffer(*m_cmdBuffer);
    648 
    649 		vk::VkSubmitInfo submitInfo =
    650 		{
    651 			vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
    652 			DE_NULL,							// const void*				pNext;
    653 			0,									// deUint32					waitSemaphoreCount;
    654 			DE_NULL,							// const VkSemaphore*		pWaitSemaphores;
    655 			(const vk::VkPipelineStageFlags*)DE_NULL,
    656 			1,									// deUint32					commandBufferCount;
    657 			&m_cmdBuffer.get(),					// const VkCommandBuffer*	pCommandBuffers;
    658 			0,									// deUint32					signalSemaphoreCount;
    659 			DE_NULL								// const VkSemaphore*		pSignalSemaphores;
    660 		};
    661 		m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
    662 
    663 		// validation
    664 		{
    665 			VK_CHECK(m_vk.queueWaitIdle(queue));
    666 
    667 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
    668 			referenceFrame.allocLevel(0);
    669 
    670 			const deInt32 frameWidth = referenceFrame.getWidth();
    671 			const deInt32 frameHeight = referenceFrame.getHeight();
    672 
    673 			tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
    674 
    675 			for (int y = 0; y < frameHeight; y++)
    676 			{
    677 				float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
    678 
    679 				for (int x = 0; x < frameWidth; x++)
    680 				{
    681 					float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
    682 					float lineHalfWidth = (float)(deFloor(deviceProperties.limits.lineWidthRange[1]) / frameHeight);
    683 
    684 					if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -lineHalfWidth && yCoord <= lineHalfWidth)
    685 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
    686 				}
    687 			}
    688 
    689 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
    690 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
    691 																							  vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT,
    692 																							  vk::VK_IMAGE_ASPECT_COLOR_BIT);
    693 
    694 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
    695 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
    696 				tcu::COMPARE_LOG_RESULT))
    697 			{
    698 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
    699 			}
    700 
    701 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
    702 		}
    703 	}
    704 };
    705 
    706 } //anonymous
    707 
    708 DynamicStateRSTests::DynamicStateRSTests (tcu::TestContext& testCtx)
    709 	: TestCaseGroup (testCtx, "rs_state", "Tests for rasterizer state")
    710 {
    711 	/* Left blank on purpose */
    712 }
    713 
    714 DynamicStateRSTests::~DynamicStateRSTests ()
    715 {
    716 }
    717 
    718 void DynamicStateRSTests::init (void)
    719 {
    720 	ShaderMap shaderPaths;
    721 	shaderPaths[glu::SHADERTYPE_VERTEX]		= "vulkan/dynamic_state/VertexFetch.vert";
    722 	shaderPaths[glu::SHADERTYPE_FRAGMENT]	= "vulkan/dynamic_state/VertexFetch.frag";
    723 
    724 	addChild(new InstanceFactory<DepthBiasParamTestInstance>(m_testCtx, "depth_bias", "Test depth bias functionality", shaderPaths));
    725 	addChild(new InstanceFactory<DepthBiasClampParamTestInstance>(m_testCtx, "depth_bias_clamp", "Test depth bias clamp functionality", shaderPaths));
    726 	addChild(new InstanceFactory<LineWidthParamTestInstance>(m_testCtx, "line_width", "Draw a line with width set to max defined by physical device", shaderPaths));
    727 }
    728 
    729 } // DynamicState
    730 } // vkt
    731