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