--- /dev/null
+#version 400
+in vec4 in_color;
+layout(location = 0) out vec4 out_color;
+void main()
+{
+ out_color = in_color;
+}
\ No newline at end of file
--- /dev/null
+#version 430
+
+layout(location = 0) in vec4 in_position;
+layout(location = 1) in vec4 in_color;
+
+layout(location = 0) out vec4 out_color;
+
+void main() {
+ gl_Position = in_position;
+ out_color = in_color;
+}
\ No newline at end of file
--- /dev/null
+#version 430
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 3) out;
+
+void main() {
+ for (int i=0; i<gl_in.length(); ++i) {
+ gl_Position = gl_in[i].gl_Position;
+ gl_ViewportIndex = int(gl_in[i].gl_Position.z);
+ EmitVertex();
+ }
+ EndPrimitive();
+}
\ No newline at end of file
add_subdirectory(spirv_assembly)
add_subdirectory(shaderrender)
add_subdirectory(memory)
+add_subdirectory(dynamic_state)
include_directories(
api
spirv_assembly
shaderrender
memory
+ dynamic_state
)
set(DEQP_VK_COMMON_SRCS
deqp-vk-spirv-assembly
deqp-vk-shaderrender
deqp-vk-memory
+ deqp-vk-dynamic_state
)
if (DE_OS_IS_WIN32 OR DE_OS_IS_UNIX OR DE_OS_IS_OSX)
--- /dev/null
+include_directories(..)
+
+set(DEQP_VK_DYNAMIC_STATE_SRCS
+ vktDynamicStateTestCaseUtil.hpp
+ vktDynamicStateBaseClass.hpp
+ vktDynamicStateCBTests.cpp
+ vktDynamicStateCBTests.hpp
+ vktDynamicStateDSTests.cpp
+ vktDynamicStateDSTests.hpp
+ vktDynamicStateGeneralTests.cpp
+ vktDynamicStateGeneralTests.hpp
+ vktDynamicStateRSTests.cpp
+ vktDynamicStateRSTests.hpp
+ vktDynamicStateTests.cpp
+ vktDynamicStateTests.hpp
+ vktDynamicStateVPTests.cpp
+ vktDynamicStateVPTests.hpp
+ vktDynamicStateCreateInfoUtil.hpp
+ vktDynamicStateCreateInfoUtil.cpp
+ vktDynamicStateBufferObjectUtil.hpp
+ vktDynamicStateBufferObjectUtil.cpp
+ vktDynamicStateImageObjectUtil.hpp
+ vktDynamicStateImageObjectUtil.cpp
+)
+
+set(DEQP_VK_DYNAMIC_STATE_LIBS
+ tcutil
+ vkutil
+)
+
+add_library(deqp-vk-dynamic-state STATIC ${DEQP_VK_DYNAMIC_STATE_SRCS})
+target_link_libraries(deqp-vk-dynamic-state ${DEQP_VK_DYNAMIC_STATE_LIBS})
--- /dev/null
+#ifndef _VKTDYNAMICSTATEBASECLASS_HPP
+#define _VKTDYNAMICSTATEBASECLASS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic State Tests - Base Class
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuResource.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuCommandLine.hpp"
+
+#include "vkRefUtil.hpp"
+#include "vkImageUtil.hpp"
+
+#include "vktDynamicStateImageObjectUtil.hpp"
+#include "vktDynamicStateBufferObjectUtil.hpp"
+#include "vktDynamicStateCreateInfoUtil.hpp"
+#include "vkPrograms.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+inline tcu::Vec4 vec4Red (void)
+{
+ return tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
+}
+
+inline tcu::Vec4 vec4Green (void)
+{
+ return tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
+}
+
+inline tcu::Vec4 vec4Blue (void)
+{
+ return tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
+}
+
+struct Vec4RGBA
+{
+ Vec4RGBA(tcu::Vec4 p, tcu::Vec4 c)
+ : position(p)
+ , color(c)
+ {}
+ tcu::Vec4 position;
+ tcu::Vec4 color;
+};
+
+vk::Move<vk::VkShader> createShader(const vk::DeviceInterface &vk, const vk::VkDevice device,
+ const vk::VkShaderModule module, const char* name, vk::VkShaderStage stage);
+
+class DynamicStateBaseClass : public TestInstance
+{
+public:
+ DynamicStateBaseClass(Context &context, const char* vertexShaderName, const char* fragmentShaderName)
+ : TestInstance (context)
+ , m_colorAttachmentFormat (vk::VK_FORMAT_R8G8B8A8_UNORM)
+ , m_topology (vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
+ , m_vertexShaderName (vertexShaderName)
+ , m_fragmentShaderName (fragmentShaderName)
+ , m_vk (context.getDeviceInterface())
+ {
+ }
+
+protected:
+
+ enum
+ {
+ WIDTH = 128,
+ HEIGHT = 128
+ };
+
+ vk::VkFormat m_colorAttachmentFormat;
+
+ vk::VkPrimitiveTopology m_topology;
+
+ const vk::DeviceInterface& m_vk;
+
+ vk::Move<vk::VkPipeline> m_pipeline;
+ vk::Move<vk::VkPipelineLayout> m_pipelineLayout;
+
+ de::SharedPtr<Image> m_colorTargetImage;
+ vk::Move<vk::VkImageView> m_colorTargetView;
+
+ PipelineCreateInfo::VertexInputState m_vertexInputState;
+ de::SharedPtr<Buffer> m_vertexBuffer;
+
+ vk::Move<vk::VkCmdPool> m_cmdPool;
+ vk::Move<vk::VkCmdBuffer> m_cmdBuffer;
+
+ vk::Move<vk::VkFramebuffer> m_framebuffer;
+ vk::Move<vk::VkRenderPass> m_renderPass;
+
+ const std::string m_vertexShaderName;
+ const std::string m_fragmentShaderName;
+
+ std::vector<Vec4RGBA> m_data;
+
+ void initialize (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkDevice device = m_context.getDevice();
+ const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+
+ const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
+ m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
+
+ const vk::VkExtent3D targetImageExtent = { WIDTH, HEIGHT, 1 };
+ const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, targetImageExtent, 1, 1, 1,
+ vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT);
+
+ m_colorTargetImage = Image::CreateAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator());
+
+ const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
+ m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
+
+ RenderPassCreateInfo renderPassCreateInfo;
+ renderPassCreateInfo.addAttachment(AttachmentDescription(
+ m_colorAttachmentFormat,
+ 1,
+ vk::VK_ATTACHMENT_LOAD_OP_LOAD,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_IMAGE_LAYOUT_GENERAL,
+ vk::VK_IMAGE_LAYOUT_GENERAL
+ )
+ );
+
+ const vk::VkAttachmentReference colorAttachmentReference =
+ {
+ 0,
+ vk::VK_IMAGE_LAYOUT_GENERAL
+ };
+
+ renderPassCreateInfo.addSubpass(SubpassDescription(
+ vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
+ 0,
+ 0,
+ DE_NULL,
+ 1,
+ &colorAttachmentReference,
+ DE_NULL,
+ AttachmentReference(),
+ 0,
+ DE_NULL
+ )
+ );
+
+ m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
+
+ std::vector<vk::VkImageView> colorAttachments(1);
+ colorAttachments[0] = *m_colorTargetView;
+
+ const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, colorAttachments, WIDTH, HEIGHT, 1);
+
+ m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
+
+ const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
+ {
+ 0,
+ sizeof(tcu::Vec4) * 2,
+ vk::VK_VERTEX_INPUT_STEP_RATE_VERTEX,
+ };
+
+ const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
+ {
+ {
+ 0u,
+ 0u,
+ vk::VK_FORMAT_R32G32B32A32_SFLOAT,
+ 0u
+ },
+ {
+ 1u,
+ 0u,
+ vk::VK_FORMAT_R32G32B32A32_SFLOAT,
+ (deUint32)(sizeof(float)* 4),
+ }
+ };
+
+ m_vertexInputState = PipelineCreateInfo::VertexInputState(
+ 1,
+ &vertexInputBindingDescription,
+ 2,
+ vertexInputAttributeDescriptions);
+
+ const vk::VkDeviceSize dataSize = m_data.size() * sizeof(Vec4RGBA);
+ m_vertexBuffer = Buffer::CreateAndAlloc(m_vk, device, BufferCreateInfo(dataSize,
+ vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
+
+ unsigned char *ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
+ deMemcpy(ptr, &m_data[0], dataSize);
+
+ vk::flushMappedMemoryRange(m_vk, device,
+ m_vertexBuffer->getBoundMemory().getMemory(),
+ m_vertexBuffer->getBoundMemory().getOffset(),
+ dataSize);
+
+ const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
+ m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
+
+ const CmdBufferCreateInfo cmdBufCreateInfo(*m_cmdPool, vk::VK_CMD_BUFFER_LEVEL_PRIMARY, 0);
+ m_cmdBuffer = vk::createCommandBuffer(m_vk, device, &cmdBufCreateInfo);
+
+ initPipeline(device);
+ }
+
+ virtual void initPipeline (const vk::VkDevice device)
+ {
+ const vk::Unique<vk::VkShader> vs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_VERTEX));
+
+ const vk::Unique<vk::VkShader> fs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_FRAGMENT));
+
+ const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
+
+ PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
+ pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, vk::VK_SHADER_STAGE_VERTEX));
+ pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, vk::VK_SHADER_STAGE_FRAGMENT));
+ pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
+ pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
+ pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
+ pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1));
+ pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState());
+
+ m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ TCU_FAIL("Implement iterate() method!");
+ }
+
+ void beginRenderPass (void)
+ {
+ const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
+ beginRenderPassWithClearColor(clearColor);
+ }
+
+ void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor)
+ {
+ const CmdBufferBeginInfo beginInfo;
+ m_vk.beginCommandBuffer(*m_cmdBuffer, &beginInfo);
+
+ initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL);
+
+ const ImageSubresourceRange subresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT);
+ m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
+
+ const vk::VkRect2D renderArea = { { 0, 0 }, { WIDTH, HEIGHT } };
+ const RenderPassBeginInfo renderPassBegin(*m_renderPass, *m_framebuffer, renderArea);
+
+ m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBegin, vk::VK_RENDER_PASS_CONTENTS_INLINE);
+ }
+
+ void setDynamicViewportState (const deUint32 width, const deUint32 height)
+ {
+ vk::VkViewport viewport;
+ viewport.originX = 0;
+ viewport.originY = 0;
+ viewport.width = static_cast<float>(width);
+ viewport.height = static_cast<float>(height);
+ viewport.minDepth = 0.0f;
+ viewport.maxDepth = 1.0f;
+
+ m_vk.cmdSetViewport(*m_cmdBuffer, 1, &viewport);
+
+ vk::VkRect2D scissor;
+ scissor.offset.x = 0;
+ scissor.offset.y = 0;
+ scissor.extent.width = width;
+ scissor.extent.height = height;
+ m_vk.cmdSetScissor(*m_cmdBuffer, 1, &scissor);
+ }
+
+ void setDynamicViewportState (deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
+ {
+ m_vk.cmdSetViewport(*m_cmdBuffer, viewportCount, pViewports);
+ m_vk.cmdSetScissor(*m_cmdBuffer, viewportCount, pScissors);
+ }
+
+ void setDynamicRasterState (const float lineWidth = 1.0f,
+ const float depthBias = 0.0f,
+ const float depthBiasClamp = 0.0f,
+ const float slopeScaledDepthBias = 0.0f)
+ {
+ m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
+ m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBias, depthBiasClamp, slopeScaledDepthBias);
+ }
+
+ void setDynamicBlendState (const float const1 = 0.0f, const float const2 = 0.0f,
+ const float const3 = 0.0f, const float const4 = 0.0f)
+ {
+ float blendConstants[4] = { const1, const2, const3, const4 };
+ m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstants);
+ }
+
+ void setDynamicDepthStencilState (const float minDepthBounds = -1.0f,
+ const float maxDepthBounds = 1.0f,
+ const deUint32 stencilFrontCompareMask = 0xffffffffu,
+ const deUint32 stencilFrontWriteMask = 0xffffffffu,
+ const deUint32 stencilFrontReference = 0,
+ const deUint32 stencilBackCompareMask = 0xffffffffu,
+ const deUint32 stencilBackWriteMask = 0xffffffffu,
+ const deUint32 stencilBackReference = 0)
+ {
+ m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
+ m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
+ m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
+ m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
+ m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
+ m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
+ m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
+ }
+};
+
+} //DynamicState
+} //vkt
+
+#endif // _VKTDYNAMICSTATEBASECLASS_HPP
--- /dev/null
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Buffer Object Util
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDynamicStateBufferObjectUtil.hpp"
+
+
+#include "vkQueryUtil.hpp"
+
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+Buffer::Buffer (const vk::DeviceInterface &vk, vk::VkDevice device, vk::Move<vk::VkBuffer> object)
+ : m_object (object)
+ , m_allocation (DE_NULL)
+ , m_vk (vk)
+ , m_device (device)
+{
+}
+
+void Buffer::bindMemory (de::MovePtr<vk::Allocation> allocation)
+{
+ if (allocation)
+ {
+ VK_CHECK(m_vk.bindBufferMemory(m_device, *m_object, allocation->getMemory(), allocation->getOffset()));
+ }
+ else
+ {
+ VK_CHECK(m_vk.bindBufferMemory(m_device, *m_object, DE_NULL, 0));
+ }
+ m_allocation = allocation;
+}
+
+de::SharedPtr<Buffer> Buffer::CreateAndAlloc (const vk::DeviceInterface &vk,
+ vk::VkDevice device,
+ const vk::VkBufferCreateInfo &createInfo,
+ vk::Allocator &allocator,
+ vk::MemoryRequirement memoryRequirement)
+{
+ de::SharedPtr<Buffer> ret = Create(vk, device, createInfo);
+
+ vk::VkMemoryRequirements bufferRequirements = vk::getBufferMemoryRequirements(vk, device, ret->object());
+ ret->bindMemory(allocator.allocate(bufferRequirements, memoryRequirement));
+ return ret;
+}
+
+de::SharedPtr<Buffer> Buffer::Create (const vk::DeviceInterface &vk,
+ vk::VkDevice device,
+ const vk::VkBufferCreateInfo &createInfo)
+{
+ return de::SharedPtr<Buffer>(new Buffer(vk, device, vk::createBuffer(vk, device, &createInfo)));
+}
+
+} //DynamicState
+} //vkt
--- /dev/null
+#ifndef _VKT_DYNAMIC_STATE_BUFFEROBJECTUTIL_HPP
+#define _VKT_DYNAMIC_STATE_BUFFEROBJECTUTIL_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Buffer Object Util
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+#include "vkMemUtil.hpp"
+#include "vkRefUtil.hpp"
+
+#include "deSharedPtr.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+class Buffer
+{
+public:
+
+ static de::SharedPtr<Buffer> Create (const vk::DeviceInterface& vk, vk::VkDevice device, const vk::VkBufferCreateInfo &createInfo);
+
+ static de::SharedPtr<Buffer> CreateAndAlloc (const vk::DeviceInterface& vk,
+ vk::VkDevice device,
+ const vk::VkBufferCreateInfo& createInfo,
+ vk::Allocator& allocator,
+ vk::MemoryRequirement allocationMemoryProperties = vk::MemoryRequirement::Any);
+
+ Buffer (const vk::DeviceInterface &vk, vk::VkDevice device, vk::Move<vk::VkBuffer> object);
+
+ inline vk::VkBuffer object (void) const { return *m_object; }
+
+ void bindMemory (de::MovePtr<vk::Allocation> allocation);
+ inline vk::Allocation getBoundMemory (void) const { return *m_allocation; }
+
+private:
+
+ Buffer (const Buffer &other); // Not allowed!
+ Buffer &operator= (const Buffer &other); // Not allowed!
+
+
+ de::MovePtr<vk::Allocation> m_allocation;
+ vk::Unique<vk::VkBuffer> m_object;
+
+ const vk::DeviceInterface & m_vk;
+ vk::VkDevice m_device;
+};
+
+} //DynamicState
+} //vkt
+
+#endif // _VKT_DYNAMIC_STATE_BUFFEROBJECTUTIL_HPP
--- /dev/null
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic CB State Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDynamicStateCBTests.hpp"
+#include "vktDynamicStateBaseClass.hpp"
+
+#include "vktTestCaseUtil.hpp"
+#include "tcuTextureUtil.hpp"
+
+#include "vktDynamicStateTestCaseUtil.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+namespace
+{
+
+class BlendConstantsTestInstance : public DynamicStateBaseClass
+{
+public:
+ BlendConstantsTestInstance (Context &context, ShaderMap shaders)
+ : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ {
+ m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), vec4Green()));
+
+ DynamicStateBaseClass::initialize();
+ }
+
+ virtual void initPipeline (const vk::VkDevice device)
+ {
+ const vk::Unique<vk::VkShader> vs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_VERTEX));
+
+ const vk::Unique<vk::VkShader> fs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_FRAGMENT));
+
+ const vk::VkPipelineColorBlendAttachmentState VkPipelineColorBlendAttachmentState =
+ PipelineCreateInfo::ColorBlendState::Attachment(
+ vk::VK_TRUE,
+ vk::VK_BLEND_SRC_ALPHA, vk::VK_BLEND_CONSTANT_COLOR, vk::VK_BLEND_OP_ADD,
+ vk::VK_BLEND_SRC_ALPHA, vk::VK_BLEND_CONSTANT_ALPHA, vk::VK_BLEND_OP_ADD);
+
+ PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
+ pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, vk::VK_SHADER_STAGE_VERTEX));
+ pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, vk::VK_SHADER_STAGE_FRAGMENT));
+ pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
+ pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
+ pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &VkPipelineColorBlendAttachmentState));
+ pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1));
+ pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState());
+
+ m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ const vk::VkClearColorValue clearColor = { { 1.0f, 1.0f, 1.0f, 1.0f } };
+ beginRenderPassWithClearColor(clearColor);
+
+ // bind states here
+ setDynamicViewportState(WIDTH, HEIGHT);
+ setDynamicRasterState();
+ setDynamicDepthStencilState();
+ setDynamicBlendState(0.33f, 0.1f, 0.66f, 0.5f);
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ //validation
+ {
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if ((yCoord >= -1.0f && yCoord <= 1.0f && xCoord >= -1.0f && xCoord <= 1.0f))
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.33f, 1.0f, 0.66f, 1.0f), x, y);
+ }
+ }
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT))
+ {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+ }
+};
+
+} //anonymous
+
+DynamicStateCBTests::DynamicStateCBTests (tcu::TestContext &testCtx)
+ : TestCaseGroup (testCtx, "cb_state", "Tests for color blend state")
+{
+ /* Left blank on purpose */
+}
+
+DynamicStateCBTests::~DynamicStateCBTests (void) {}
+
+void DynamicStateCBTests::init (void)
+{
+ ShaderMap shaderPaths;
+ shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
+ shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
+ addChild(new InstanceFactory<BlendConstantsTestInstance>(m_testCtx, "blend_constants", "Check if blend constants are working properly", shaderPaths));
+}
+
+} //DynamicState
+} //vkt
--- /dev/null
+#ifndef _VKTDYNAMICSTATECBTESTS_HPP
+#define _VKTDYNAMICSTATECBTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic CB State Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+class DynamicStateCBTests : public tcu::TestCaseGroup
+{
+public:
+ DynamicStateCBTests (tcu::TestContext &testCtx);
+ ~DynamicStateCBTests (void);
+ void init (void);
+
+private:
+ DynamicStateCBTests (const DynamicStateCBTests &other);
+ DynamicStateCBTests &operator=(const DynamicStateCBTests &other);
+};
+
+} //DynamicState
+} //vkt
+
+
+#endif // _VKTDYNAMICSTATECBTESTS_HPP
--- /dev/null
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief CreateInfo utilities
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDynamicStateCreateInfoUtil.hpp"
+
+#include "vkImageUtil.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+ImageSubresourceRange::ImageSubresourceRange ( vk::VkImageAspectFlags _aspectMask,
+ deUint32 _baseMipLevel,
+ deUint32 _mipLevels,
+ deUint32 _baseArrayLayer,
+ deUint32 _arraySize)
+{
+ aspectMask = _aspectMask;
+ baseMipLevel = _baseMipLevel;
+ mipLevels = _mipLevels;
+ baseArrayLayer = _baseArrayLayer;
+ arraySize = _arraySize;
+}
+
+ChannelMapping::ChannelMapping (vk::VkChannelSwizzle _r,
+ vk::VkChannelSwizzle _g,
+ vk::VkChannelSwizzle _b,
+ vk::VkChannelSwizzle _a)
+{
+ r = _r;
+ g = _g;
+ b = _b;
+ a = _a;
+}
+
+ImageViewCreateInfo::ImageViewCreateInfo ( vk::VkImage _image,
+ vk::VkImageViewType _viewType,
+ vk::VkFormat _format,
+ const vk::VkImageSubresourceRange& _subresourceRange,
+ const vk::VkChannelMapping& _channels,
+ vk::VkImageViewCreateFlags _flags)
+{
+ sType = vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ pNext = DE_NULL;
+ image = _image;
+ viewType = _viewType;
+ format = _format;
+ channels.r = _channels.r;
+ channels.g = _channels.g;
+ channels.b = _channels.b;
+ channels.a = _channels.a;
+ subresourceRange = _subresourceRange;
+ flags = _flags;
+}
+
+ImageViewCreateInfo::ImageViewCreateInfo ( vk::VkImage _image,
+ vk::VkImageViewType _viewType,
+ vk::VkFormat _format,
+ const vk::VkChannelMapping& _channels,
+ vk::VkImageViewCreateFlags _flags)
+{
+ sType = vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ pNext = DE_NULL;
+ image = _image;
+ viewType = _viewType;
+ format = _format;
+ channels.r = _channels.r;
+ channels.g = _channels.g;
+ channels.b = _channels.b;
+ channels.a = _channels.a;
+
+ vk::VkImageAspectFlags aspectFlags;
+ const tcu::TextureFormat tcuFormat = vk::mapVkFormat(_format);
+
+ switch (tcuFormat.order)
+ {
+ case tcu::TextureFormat::R:\r
+ case tcu::TextureFormat::A:\r
+ case tcu::TextureFormat::I:\r
+ case tcu::TextureFormat::L:\r
+ case tcu::TextureFormat::LA:\r
+ case tcu::TextureFormat::RG:\r
+ case tcu::TextureFormat::RA:\r
+ case tcu::TextureFormat::RGB:\r
+ case tcu::TextureFormat::RGBA:\r
+ case tcu::TextureFormat::ARGB:\r
+ case tcu::TextureFormat::BGRA:\r
+ case tcu::TextureFormat::sR:\r
+ case tcu::TextureFormat::sRG:\r
+ case tcu::TextureFormat::sRGB:\r
+ case tcu::TextureFormat::sRGBA:
+ aspectFlags = vk::VK_IMAGE_ASPECT_COLOR_BIT;
+ break;
+ case tcu::TextureFormat::D:
+ aspectFlags = vk::VK_IMAGE_ASPECT_DEPTH_BIT;
+ break;
+ case tcu::TextureFormat::S:
+ aspectFlags = vk::VK_IMAGE_ASPECT_STENCIL_BIT;
+ break;
+ case tcu::TextureFormat::DS:
+ aspectFlags = vk::VK_IMAGE_ASPECT_STENCIL_BIT | vk::VK_IMAGE_ASPECT_DEPTH_BIT;
+ break;
+ default:
+ TCU_FAIL("unhandled format");
+ }
+
+ subresourceRange = ImageSubresourceRange(aspectFlags);;
+ flags = _flags;
+}
+
+BufferViewCreateInfo::BufferViewCreateInfo (vk::VkBuffer _buffer,
+ vk::VkFormat _format,
+ vk::VkDeviceSize _offset,
+ vk::VkDeviceSize _range)
+{
+ sType = vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
+ pNext = DE_NULL;
+
+ buffer = _buffer;
+ format = _format;
+ offset = _offset;
+ range = _range;
+}
+
+
+BufferCreateInfo::BufferCreateInfo ( vk::VkDeviceSize _size,
+ vk::VkBufferUsageFlags _usage,
+ vk::VkSharingMode _sharingMode,
+ deUint32 _queueFamilyCount,
+ const deUint32* _pQueueFamilyIndices,
+ vk::VkBufferCreateFlags _flags)
+{
+ sType = vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ pNext = DE_NULL;
+ size = _size;
+ usage = _usage;
+ flags = _flags;
+ sharingMode = _sharingMode;
+ queueFamilyCount = _queueFamilyCount;
+
+ if (_queueFamilyCount)
+ {
+ m_queueFamilyIndices = std::vector<deUint32>(
+ _pQueueFamilyIndices, _pQueueFamilyIndices + _queueFamilyCount);
+ pQueueFamilyIndices = &m_queueFamilyIndices[0];
+ } else
+ pQueueFamilyIndices = _pQueueFamilyIndices;
+
+
+}
+
+BufferCreateInfo::BufferCreateInfo (const BufferCreateInfo &other)
+{
+ sType = other.sType;
+ pNext = other.pNext;
+ size = other.size;
+ usage = other.usage;
+ flags = other.flags;
+ sharingMode = other.sharingMode;
+ queueFamilyCount = other.queueFamilyCount;
+
+ m_queueFamilyIndices = other.m_queueFamilyIndices;
+ DE_ASSERT(m_queueFamilyIndices.size() == queueFamilyCount);
+
+ if (m_queueFamilyIndices.size())
+ {
+ pQueueFamilyIndices = &m_queueFamilyIndices[0];
+ }
+ else
+ {
+ pQueueFamilyIndices = DE_NULL;
+ }
+}
+
+BufferCreateInfo & BufferCreateInfo::operator= (const BufferCreateInfo &other)
+{
+ sType = other.sType;
+ pNext = other.pNext;
+ size = other.size;
+ usage = other.usage;
+ flags = other.flags;
+ sharingMode = other.sharingMode;
+ queueFamilyCount = other.queueFamilyCount;
+
+ m_queueFamilyIndices = other.m_queueFamilyIndices;
+
+ DE_ASSERT(m_queueFamilyIndices.size() == queueFamilyCount);
+
+ if (m_queueFamilyIndices.size())
+ {
+ pQueueFamilyIndices = &m_queueFamilyIndices[0];
+ }
+ else
+ {
+ pQueueFamilyIndices = DE_NULL;
+ }
+
+ return *this;
+}
+
+ImageCreateInfo::ImageCreateInfo ( vk::VkImageType _imageType,
+ vk::VkFormat _format,
+ vk::VkExtent3D _extent,
+ deUint32 _mipLevels,
+ deUint32 _arraySize,
+ deUint32 _samples,
+ vk::VkImageTiling _tiling,
+ vk::VkImageUsageFlags _usage,
+ vk::VkSharingMode _sharingMode,
+ deUint32 _queueFamilyCount,
+ const deUint32* _pQueueFamilyIndices,
+ vk::VkImageCreateFlags _flags,
+ vk::VkImageLayout _initialLayout)
+{
+ if (_queueFamilyCount)
+ {
+ m_queueFamilyIndices = std::vector<deUint32>(_pQueueFamilyIndices, _pQueueFamilyIndices + _queueFamilyCount);
+ }
+
+ sType = vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ pNext = DE_NULL;
+ imageType = _imageType;
+ format = _format;
+ extent = _extent;
+ mipLevels = _mipLevels;
+ arraySize = _arraySize;
+ samples = _samples;
+ tiling = _tiling;
+ usage = _usage;
+ sharingMode = _sharingMode;
+ queueFamilyCount = _queueFamilyCount;
+
+ if (m_queueFamilyIndices.size())
+ {
+ pQueueFamilyIndices = &m_queueFamilyIndices[0];
+ }
+ else
+ {
+ pQueueFamilyIndices = DE_NULL;
+ }
+
+ flags = _flags;
+ initialLayout = _initialLayout;
+}
+
+FramebufferCreateInfo::FramebufferCreateInfo ( vk::VkRenderPass _renderPass,
+ const std::vector<vk::VkImageView>& atachments,
+ deUint32 _width,
+ deUint32 _height,
+ deUint32 _layers)
+{
+ sType = vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+ pNext = DE_NULL;
+
+ renderPass = _renderPass;
+ attachmentCount = static_cast<deUint32>(atachments.size());
+
+ if (attachmentCount)
+ {
+ pAttachments = const_cast<vk::VkImageView *>(&atachments[0]);
+ }
+
+ width = _width;
+ height = _height;
+ layers = _layers;
+}
+
+RenderPassCreateInfo::RenderPassCreateInfo (const std::vector<vk::VkAttachmentDescription>& attachments,
+ const std::vector<vk::VkSubpassDescription>& subpasses,
+ const std::vector<vk::VkSubpassDependency>& dependiences)
+
+ : m_attachments (attachments.begin(), attachments.end())
+ , m_subpasses (subpasses.begin(), subpasses.end())
+ , m_dependiences (dependiences.begin(), dependiences.end())
+ , m_attachmentsStructs (m_attachments.begin(), m_attachments.end())
+ , m_subpassesStructs (m_subpasses.begin(), m_subpasses.end())
+ , m_dependiencesStructs (m_dependiences.begin(), m_dependiences.end())
+{
+ sType = vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+ pNext = DE_NULL;
+
+ attachmentCount = static_cast<deUint32>(m_attachments.size());
+ pAttachments = &m_attachmentsStructs[0];
+ subpassCount = static_cast<deUint32>(m_subpasses.size());
+ pSubpasses = &m_subpassesStructs[0];
+ dependencyCount = static_cast<deUint32>(m_dependiences.size());
+ pDependencies = &m_dependiencesStructs[0];
+}
+
+RenderPassCreateInfo::RenderPassCreateInfo ( deUint32 _attachmentCount,
+ const vk::VkAttachmentDescription* _pAttachments,
+ deUint32 _subpassCount,
+ const vk::VkSubpassDescription* _pSubpasses,
+ deUint32 _dependencyCount,
+ const vk::VkSubpassDependency* _pDependiences)
+{
+
+ m_attachments = std::vector<AttachmentDescription>(_pAttachments, _pAttachments + _attachmentCount);
+ m_subpasses = std::vector<SubpassDescription>(_pSubpasses, _pSubpasses + _subpassCount);
+ m_dependiences = std::vector<SubpassDependency>(_pDependiences, _pDependiences + _dependencyCount);
+
+ m_attachmentsStructs = std::vector<vk::VkAttachmentDescription> (m_attachments.begin(), m_attachments.end());
+ m_subpassesStructs = std::vector<vk::VkSubpassDescription> (m_subpasses.begin(), m_subpasses.end());
+ m_dependiencesStructs = std::vector<vk::VkSubpassDependency> (m_dependiences.begin(), m_dependiences.end());
+
+ sType = vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+ pNext = DE_NULL;
+
+ attachmentCount = static_cast<deUint32>(m_attachments.size());
+
+ if (attachmentCount) {
+ pAttachments = &m_attachmentsStructs[0];
+ }
+ else
+ {
+ pAttachments = DE_NULL;
+ }
+
+ subpassCount = static_cast<deUint32>(m_subpasses.size());
+
+ if (subpassCount) {
+ pSubpasses = &m_subpassesStructs[0];
+ }
+ else
+ {
+ pSubpasses = DE_NULL;
+ }
+
+ dependencyCount = static_cast<deUint32>(m_dependiences.size());
+
+ if (dependencyCount) {
+ pDependencies = &m_dependiencesStructs[0];
+ }
+ else
+ {
+ pDependencies = DE_NULL;
+ }
+}
+
+void
+RenderPassCreateInfo::addAttachment (vk::VkAttachmentDescription attachment)
+{
+
+ m_attachments.push_back(attachment);
+ m_attachmentsStructs = std::vector<vk::VkAttachmentDescription>(m_attachments.begin(), m_attachments.end());
+ attachmentCount = static_cast<deUint32>(m_attachments.size());
+ pAttachments = &m_attachmentsStructs[0];
+}
+
+void
+RenderPassCreateInfo::addSubpass (vk::VkSubpassDescription subpass)
+{
+
+ m_subpasses.push_back(subpass);
+ m_subpassesStructs = std::vector<vk::VkSubpassDescription>(m_subpasses.begin(), m_subpasses.end());
+ subpassCount = static_cast<deUint32>(m_subpasses.size());
+ pSubpasses = &m_subpassesStructs[0];
+}
+
+void
+RenderPassCreateInfo::addDependency (vk::VkSubpassDependency dependency)
+{
+
+ m_dependiences.push_back(dependency);
+ m_dependiencesStructs = std::vector<vk::VkSubpassDependency>(m_dependiences.begin(), m_dependiences.end());
+
+ dependencyCount = static_cast<deUint32>(m_dependiences.size());
+ pDependencies = &m_dependiencesStructs[0];
+}
+
+RenderPassBeginInfo::RenderPassBeginInfo ( vk::VkRenderPass _renderPass,
+ vk::VkFramebuffer _framebuffer,
+ vk::VkRect2D _renderArea,
+ const std::vector<vk::VkClearValue>& _clearValues)
+{
+
+ m_clearValues = _clearValues;
+
+ sType = vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+ pNext = DE_NULL;
+ renderPass = _renderPass;
+ framebuffer = _framebuffer;
+ renderArea = _renderArea;
+ clearValueCount = static_cast<deUint32>(m_clearValues.size());
+ pClearValues = m_clearValues.size() ? &m_clearValues[0] : DE_NULL;
+}
+
+CmdPoolCreateInfo::CmdPoolCreateInfo (deUint32 _queueFamilyIndex, unsigned int _flags)
+{
+ sType = vk::VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO;
+ pNext = DE_NULL;
+
+ queueFamilyIndex = _queueFamilyIndex;
+ flags = _flags;
+}
+
+CmdBufferCreateInfo::CmdBufferCreateInfo (vk::VkCmdPool _pool, vk::VkCmdBufferLevel _level, unsigned int _flags)
+{
+ sType = vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO;
+ pNext = DE_NULL;
+ cmdPool = _pool;
+ level = _level;
+ flags = _flags;
+}
+
+AttachmentDescription::AttachmentDescription ( vk::VkFormat _format,
+ deUint32 _samples,
+ vk::VkAttachmentLoadOp _loadOp,
+ vk::VkAttachmentStoreOp _storeOp,
+ vk::VkAttachmentLoadOp _stencilLoadOp,
+ vk::VkAttachmentStoreOp _stencilStoreOp,
+ vk::VkImageLayout _initialLayout,
+ vk::VkImageLayout _finalLayout)
+{
+ sType = vk::VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION;
+ pNext = DE_NULL;
+ format = _format;
+ samples = _samples;
+ loadOp = _loadOp;
+ storeOp = _storeOp;
+ stencilLoadOp = _stencilLoadOp;
+ stencilStoreOp = _stencilStoreOp;
+ initialLayout = _initialLayout;
+ finalLayout = _finalLayout;
+}
+
+AttachmentDescription::AttachmentDescription (const vk::VkAttachmentDescription &rhs)
+{
+
+ DE_ASSERT(rhs.sType == vk::VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION);
+ DE_ASSERT(rhs.pNext == DE_NULL);
+
+ sType = rhs.sType;
+ pNext = rhs.pNext;
+ format = rhs.format;
+ samples = rhs.samples;
+ loadOp = rhs.loadOp;
+ storeOp = rhs.storeOp;
+ stencilLoadOp = rhs.stencilLoadOp;
+ stencilStoreOp = rhs.stencilStoreOp;
+ initialLayout = rhs.initialLayout;
+ finalLayout = rhs.finalLayout;
+}
+
+AttachmentReference::AttachmentReference (deUint32 _attachment, vk::VkImageLayout _layout)
+{
+ attachment = _attachment;
+ layout = _layout;
+}
+
+AttachmentReference::AttachmentReference (void)
+{
+ attachment = vk::VK_ATTACHMENT_UNUSED;
+ layout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
+}
+
+SubpassDescription::SubpassDescription( vk::VkPipelineBindPoint _pipelineBindPoint,
+ vk::VkSubpassDescriptionFlags _flags,
+ deUint32 _inputCount,
+ const vk::VkAttachmentReference* _inputAttachments,
+ deUint32 _colorCount,
+ const vk::VkAttachmentReference* _colorAttachments,
+ const vk::VkAttachmentReference* _resolveAttachments,
+ vk::VkAttachmentReference _depthStencilAttachment,
+ deUint32 _preserveCount,
+ const vk::VkAttachmentReference* _preserveAttachments)
+{
+ m_InputAttachments = std::vector<vk::VkAttachmentReference>(_inputAttachments, _inputAttachments + _inputCount);
+ m_ColorAttachments = std::vector<vk::VkAttachmentReference>(_colorAttachments, _colorAttachments + _colorCount);
+
+ if (_resolveAttachments)
+ {
+ m_ResolveAttachments = std::vector<vk::VkAttachmentReference>(_resolveAttachments, _resolveAttachments + _colorCount);
+ }
+
+ m_PreserveAttachments = std::vector<vk::VkAttachmentReference>(_preserveAttachments, _preserveAttachments + _preserveCount);
+
+ sType = vk::VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION;
+ pNext = DE_NULL;
+ pipelineBindPoint = _pipelineBindPoint;
+ flags = _flags;
+ inputCount = _inputCount;
+ pInputAttachments = DE_NULL;
+ colorCount = _colorCount;
+ pColorAttachments = DE_NULL;
+ pResolveAttachments = DE_NULL;
+ depthStencilAttachment = _depthStencilAttachment;
+ pPreserveAttachments = DE_NULL;
+ preserveCount = _preserveCount;
+
+ if (m_InputAttachments.size()) {
+ pInputAttachments = &m_InputAttachments[0];
+ }
+
+ if (m_ColorAttachments.size()) {
+ pColorAttachments = &m_ColorAttachments[0];
+ }
+
+ if (m_ResolveAttachments.size()) {
+ pResolveAttachments = &m_ResolveAttachments[0];
+ }
+
+ if (m_PreserveAttachments.size()) {
+ pPreserveAttachments = &m_PreserveAttachments[0];
+ }
+}
+
+SubpassDescription::SubpassDescription (const vk::VkSubpassDescription &rhs)
+{
+
+ DE_ASSERT(rhs.sType == vk::VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION);
+ DE_ASSERT(rhs.pNext == DE_NULL);
+
+ *static_cast<vk::VkSubpassDescription*>(this) = rhs;
+
+ m_InputAttachments = std::vector<vk::VkAttachmentReference>(
+ rhs.pInputAttachments, rhs.pInputAttachments + rhs.inputCount);
+
+ m_ColorAttachments = std::vector<vk::VkAttachmentReference>(
+ rhs.pColorAttachments, rhs.pColorAttachments + rhs.colorCount);
+
+ if (rhs.pResolveAttachments) {
+ m_ResolveAttachments = std::vector<vk::VkAttachmentReference>(
+ rhs.pResolveAttachments, rhs.pResolveAttachments + rhs.colorCount);
+ }
+ m_PreserveAttachments = std::vector<vk::VkAttachmentReference>(
+ rhs.pPreserveAttachments, rhs.pPreserveAttachments + rhs.preserveCount);
+
+ if (m_InputAttachments.size()) {
+ pInputAttachments = &m_InputAttachments[0];
+ }
+ if (m_ColorAttachments.size()) {
+ pColorAttachments = &m_ColorAttachments[0];
+ }
+
+ if (m_ResolveAttachments.size()) {
+ pResolveAttachments = &m_ResolveAttachments[0];
+ }
+
+ if (m_PreserveAttachments.size()) {
+ pPreserveAttachments = &m_PreserveAttachments[0];
+ }
+}
+
+SubpassDescription::SubpassDescription (const SubpassDescription &rhs) {
+ *this = rhs;
+}
+
+SubpassDescription &SubpassDescription::operator= (const SubpassDescription &rhs)
+{
+ *static_cast<vk::VkSubpassDescription*>(this) = rhs;
+
+ m_InputAttachments = rhs.m_InputAttachments;
+ m_ColorAttachments = rhs.m_ColorAttachments;
+ m_ResolveAttachments = rhs.m_ResolveAttachments;
+ m_PreserveAttachments = rhs.m_PreserveAttachments;
+
+ if (m_InputAttachments.size()) {
+ pInputAttachments = &m_InputAttachments[0];
+ }
+ if (m_ColorAttachments.size()) {
+ pColorAttachments = &m_ColorAttachments[0];
+ }
+
+ if (m_ResolveAttachments.size()) {
+ pResolveAttachments = &m_ResolveAttachments[0];
+ }
+
+ if (m_PreserveAttachments.size()) {
+ pPreserveAttachments = &m_PreserveAttachments[0];
+ }
+
+ return *this;
+}
+
+SubpassDependency::SubpassDependency ( deUint32 _srcSubpass,
+ deUint32 _destSubpass,
+ vk::VkPipelineStageFlags _srcStageMask,
+ vk::VkPipelineStageFlags _destStageMask,
+ vk::VkMemoryOutputFlags _outputMask,
+ vk::VkMemoryInputFlags _inputMask,
+ vk::VkBool32 _byRegion)
+{
+
+ sType = vk::VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY;
+ pNext = DE_NULL;
+ srcSubpass = _srcSubpass;
+ destSubpass = _destSubpass;
+ srcStageMask = _srcStageMask;
+ destStageMask = _destStageMask;
+ outputMask = _outputMask;
+ inputMask = _inputMask;
+ byRegion = _byRegion;
+}
+
+SubpassDependency::SubpassDependency (const vk::VkSubpassDependency &rhs)
+{
+
+ DE_ASSERT(rhs.sType == vk::VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY);
+ DE_ASSERT(rhs.pNext == DE_NULL);
+
+ sType = rhs.sType;
+ pNext = DE_NULL;
+ srcSubpass = rhs.srcSubpass;
+ destSubpass = rhs.destSubpass;
+ srcStageMask = rhs.srcStageMask;
+ destStageMask = rhs.destStageMask;
+ outputMask = rhs.outputMask;
+ inputMask = rhs.inputMask;
+ byRegion = rhs.byRegion;
+}
+
+CmdBufferBeginInfo::CmdBufferBeginInfo (vk::VkCmdBufferOptimizeFlags _flags)
+{
+ sType = vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO;
+ pNext = DE_NULL;
+ renderPass = DE_NULL;
+ subpass = 0;
+ framebuffer = DE_NULL;
+ flags = _flags;
+}
+
+CmdBufferBeginInfo::CmdBufferBeginInfo (vk::VkRenderPass _renderPass,
+ deUint32 _subpass,
+ vk::VkFramebuffer _framebuffer,
+ vk::VkCmdBufferOptimizeFlags _flags)
+{
+
+ sType = vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO;
+ pNext = DE_NULL;
+ renderPass = _renderPass;
+ subpass = _subpass;
+ framebuffer = _framebuffer;
+ flags = _flags;
+}
+
+DescriptorPoolCreateInfo::DescriptorPoolCreateInfo (const std::vector<vk::VkDescriptorTypeCount>& typeCounts,\r
+ vk::VkDescriptorPoolUsage _poolUsage,\r
+ deUint32 _maxSets)
+ : m_typeCounts(typeCounts)
+{
+ sType = vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+ pNext = DE_NULL;
+ poolUsage = _poolUsage;
+ maxSets = _maxSets;
+ count = static_cast<deUint32>(m_typeCounts.size());
+ pTypeCount = &m_typeCounts[0];
+}
+
+DescriptorPoolCreateInfo& DescriptorPoolCreateInfo::addDescriptors (vk::VkDescriptorType type, deUint32 count)
+{
+ vk::VkDescriptorTypeCount typeCount = { type, count };
+ m_typeCounts.push_back(typeCount);
+
+ count = static_cast<deUint32>(m_typeCounts.size());
+ pTypeCount = &m_typeCounts[0];
+
+ return *this;
+}
+
+DescriptorSetLayoutCreateInfo::DescriptorSetLayoutCreateInfo (deUint32 _count, const vk::VkDescriptorSetLayoutBinding* _pBinding)
+{
+ sType = vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+ pNext = DE_NULL;
+ count = _count;
+ pBinding = _pBinding;
+}
+
+
+PipelineLayoutCreateInfo::PipelineLayoutCreateInfo (deUint32 _descriptorSetCount,
+ const vk::VkDescriptorSetLayout* _pSetLayouts,
+ deUint32 _pushConstantRangeCount,
+ const vk::VkPushConstantRange* _pPushConstantRanges)
+ : m_pushConstantRanges(_pPushConstantRanges, _pPushConstantRanges + _pushConstantRangeCount)
+{
+ for (unsigned int i = 0; i < _descriptorSetCount; i++)
+ {
+ m_setLayouts.push_back(_pSetLayouts[i]);
+ }
+
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+ pNext = DE_NULL;
+ descriptorSetCount = static_cast<deUint32>(m_setLayouts.size());
+ pSetLayouts = descriptorSetCount > 0 ? &m_setLayouts[0] : DE_NULL;
+ pushConstantRangeCount = static_cast<deUint32>(m_pushConstantRanges.size());
+
+ if (m_pushConstantRanges.size()) {
+ pPushConstantRanges = &m_pushConstantRanges[0];
+ }
+ else
+ {
+ pPushConstantRanges = DE_NULL;
+ }
+}
+
+PipelineLayoutCreateInfo::PipelineLayoutCreateInfo ( const std::vector<vk::VkDescriptorSetLayout>& setLayouts,
+ deUint32 _pushConstantRangeCount,
+ const vk::VkPushConstantRange* _pPushConstantRanges)
+ : m_setLayouts (setLayouts)
+ , m_pushConstantRanges (_pPushConstantRanges, _pPushConstantRanges + _pushConstantRangeCount)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+ pNext = DE_NULL;
+
+ descriptorSetCount = static_cast<deUint32>(m_setLayouts.size());
+
+ if (descriptorSetCount)
+ {
+ pSetLayouts = &m_setLayouts[0];
+ }
+ else
+ {
+ pSetLayouts = DE_NULL;
+ }
+
+ pushConstantRangeCount = static_cast<deUint32>(m_pushConstantRanges.size());
+ if (pushConstantRangeCount) {
+ pPushConstantRanges = &m_pushConstantRanges[0];
+ }
+ else
+ {
+ pPushConstantRanges = DE_NULL;
+ }
+}
+
+
+PipelineCreateInfo::PipelineShaderStage::PipelineShaderStage (vk::VkShader _shader, vk::VkShaderStage _stage)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+ pNext = DE_NULL;
+ stage = _stage;
+ shader = _shader;
+ pSpecializationInfo = DE_NULL;
+}
+
+PipelineCreateInfo::VertexInputState::VertexInputState ( deUint32 _bindingCount,
+ const vk::VkVertexInputBindingDescription* _pVertexBindingDescriptions,
+ deUint32 _attributeCount,
+ const vk::VkVertexInputAttributeDescription* _pVertexAttributeDescriptions)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+ pNext = DE_NULL;
+ bindingCount = _bindingCount;
+ pVertexBindingDescriptions = _pVertexBindingDescriptions;
+ attributeCount = _attributeCount;
+ pVertexAttributeDescriptions = _pVertexAttributeDescriptions;
+}
+
+PipelineCreateInfo::InputAssemblerState::InputAssemblerState ( vk::VkPrimitiveTopology _topology,
+ vk::VkBool32 _primitiveRestartEnable)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+ pNext = DE_NULL;
+ topology = _topology;
+ primitiveRestartEnable = _primitiveRestartEnable;
+}
+
+PipelineCreateInfo::TesselationState::TesselationState (deUint32 _patchControlPoints)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
+ pNext = DE_NULL;
+ patchControlPoints = _patchControlPoints;
+}
+
+PipelineCreateInfo::ViewportState::ViewportState ( deUint32 _viewportCount,
+ std::vector<vk::VkViewport> _viewports,
+ std::vector<vk::VkRect2D> _scissors)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+ pNext = DE_NULL;
+ viewportCount = _viewportCount;\r
+ scissorCount = _viewportCount;\r
+ \r
+ if (!_viewports.size())\r
+ {\r
+ m_viewports.resize(viewportCount);\r
+ deMemset(&m_viewports[0], 0, sizeof(m_viewports[0]) * m_viewports.size());\r
+ }\r
+ else\r
+ {\r
+ m_viewports = _viewports;\r
+ }\r
+\r
+ if (!_scissors.size())\r
+ {\r
+ m_scissors.resize(scissorCount);\r
+ deMemset(&m_scissors[0], 0, sizeof(m_scissors[0]) * m_scissors.size());\r
+ }\r
+ else\r
+ {\r
+ m_scissors = _scissors;\r
+ }\r
+\r
+ pViewports = &m_viewports[0];\r
+ pScissors = &m_scissors[0];
+}
+
+PipelineCreateInfo::ViewportState::ViewportState (const ViewportState &other)
+{
+ sType = other.sType;\r
+ pNext = other.pNext;
+ viewportCount = other.viewportCount;\r
+ scissorCount = other.scissorCount;
+
+ m_viewports = std::vector<vk::VkViewport>(other.pViewports, other.pViewports + viewportCount);
+ m_scissors = std::vector<vk::VkRect2D>(other.pScissors, other.pScissors + scissorCount);
+
+ pViewports = &m_viewports[0];\r
+ pScissors = &m_scissors[0];
+}
+
+PipelineCreateInfo::ViewportState & PipelineCreateInfo::ViewportState::operator= (const ViewportState &other)
+{
+ sType = other.sType;\r
+ pNext = other.pNext;
+ viewportCount = other.viewportCount;\r
+ scissorCount = other.scissorCount;
+
+ m_viewports = std::vector<vk::VkViewport>(other.pViewports, other.pViewports + scissorCount);
+ m_scissors = std::vector<vk::VkRect2D>(other.pScissors, other.pScissors + scissorCount);
+
+ pViewports = &m_viewports[0];\r
+ pScissors = &m_scissors[0];
+ return *this;
+}
+
+PipelineCreateInfo::RasterizerState::RasterizerState ( vk::VkBool32 _depthClipEnable,
+ vk::VkBool32 _rasterizerDiscardEnable,
+ vk::VkFillMode _fillMode,
+ vk::VkCullMode _cullMode,
+ vk::VkFrontFace _frontFace,
+ vk::VkBool32 _depthBiasEnable,\r
+ float _depthBias,
+ float _depthBiasClamp,
+ float _slopeScaledDepthBias,
+ float _lineWidth)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO;
+ pNext = DE_NULL;
+ depthClipEnable = _depthClipEnable;
+ rasterizerDiscardEnable = _rasterizerDiscardEnable;
+ fillMode = _fillMode;
+ cullMode = _cullMode;
+ frontFace = _frontFace;
+
+ depthBiasEnable = _depthBiasEnable;\r
+ depthBias = _depthBias;
+ depthBiasClamp = _depthBiasClamp;
+ slopeScaledDepthBias = _slopeScaledDepthBias;
+ lineWidth = _lineWidth;
+}
+
+PipelineCreateInfo::MultiSampleState::MultiSampleState ( deUint32 _rasterSamples,
+ vk::VkBool32 _sampleShadingEnable,
+ float _minSampleShading,
+ const std::vector<vk::VkSampleMask>& _sampleMask)
+ : m_sampleMask(_sampleMask)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+ pNext = DE_NULL;
+ rasterSamples = _rasterSamples;
+ sampleShadingEnable = _sampleShadingEnable;
+ minSampleShading = _minSampleShading;
+ pSampleMask = &m_sampleMask[0];
+}
+
+PipelineCreateInfo::MultiSampleState::MultiSampleState (const MultiSampleState &other)
+{
+ sType = other.sType;\r
+ pNext = other.pNext;\r
+ rasterSamples = other.rasterSamples;\r
+ sampleShadingEnable = other.sampleShadingEnable;\r
+ minSampleShading = other.minSampleShading;\r
+ \r
+ const size_t sampleMaskArrayLen = (sizeof(vk::VkSampleMask) * 8 + other.rasterSamples) / (sizeof(vk::VkSampleMask) * 8);
+
+ m_sampleMask = std::vector<vk::VkSampleMask>(other.pSampleMask, other.pSampleMask + sampleMaskArrayLen);\r
+ pSampleMask = &m_sampleMask[0];
+}
+
+PipelineCreateInfo::MultiSampleState& PipelineCreateInfo::MultiSampleState::operator= (const MultiSampleState & other)
+{
+ sType = other.sType;\r
+ pNext = other.pNext;\r
+ rasterSamples = other.rasterSamples;\r
+ sampleShadingEnable = other.sampleShadingEnable;\r
+ minSampleShading = other.minSampleShading;\r
+\r
+ const size_t sampleMaskArrayLen = (sizeof(vk::VkSampleMask) * 8 + other.rasterSamples) / (sizeof(vk::VkSampleMask) * 8);
+
+ m_sampleMask = std::vector<vk::VkSampleMask>(other.pSampleMask, other.pSampleMask + sampleMaskArrayLen);\r
+ pSampleMask = &m_sampleMask[0];
+
+ return *this;
+}
+
+PipelineCreateInfo::ColorBlendState::ColorBlendState ( const std::vector<vk::VkPipelineColorBlendAttachmentState>& _attachments,
+ vk::VkBool32 _alphaToCoverageEnable,
+ vk::VkBool32 _logicOpEnable,
+ vk::VkLogicOp _logicOp,
+ vk::VkBool32 _alphaToOneEnable)
+ : m_attachments(_attachments)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+ pNext = DE_NULL;
+ alphaToCoverageEnable = _alphaToCoverageEnable;
+ alphaToOneEnable = _alphaToOneEnable;
+ logicOpEnable = _logicOpEnable;
+ logicOp = _logicOp;
+ attachmentCount = static_cast<deUint32>(m_attachments.size());
+ pAttachments = &m_attachments[0];
+}
+
+PipelineCreateInfo::ColorBlendState::ColorBlendState ( deUint32 _attachmentCount,
+ const vk::VkPipelineColorBlendAttachmentState* _attachments,
+ vk::VkBool32 _alphaToCoverageEnable,
+ vk::VkBool32 _logicOpEnable,
+ vk::VkLogicOp _logicOp,
+ vk::VkBool32 _alphaToOneEnable)
+ : m_attachments(_attachments, _attachments + _attachmentCount)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+ pNext = DE_NULL;
+ alphaToCoverageEnable = _alphaToCoverageEnable;
+ alphaToOneEnable = _alphaToOneEnable;
+
+ logicOpEnable = _logicOpEnable;
+ logicOp = _logicOp;
+ attachmentCount = _attachmentCount;
+ attachmentCount = static_cast<deUint32>(m_attachments.size());
+ pAttachments = &m_attachments[0];
+}
+
+PipelineCreateInfo::ColorBlendState::ColorBlendState (const vk::VkPipelineColorBlendStateCreateInfo &createInfo)
+ : m_attachments (createInfo.pAttachments, createInfo.pAttachments + createInfo.attachmentCount)
+{
+ sType = createInfo.sType;
+ pNext = createInfo.pNext;
+ alphaToCoverageEnable = createInfo.alphaToCoverageEnable;
+ logicOpEnable = createInfo.logicOpEnable;
+ logicOp = createInfo.logicOp;
+ attachmentCount = static_cast<deUint32>(m_attachments.size());
+ pAttachments = &m_attachments[0];
+}
+
+PipelineCreateInfo::ColorBlendState::ColorBlendState (const ColorBlendState &createInfo, std::vector<float> _blendConst)
+ : m_attachments (createInfo.pAttachments, createInfo.pAttachments + createInfo.attachmentCount)
+{
+ sType = createInfo.sType;
+ pNext = createInfo.pNext;
+ alphaToCoverageEnable = createInfo.alphaToCoverageEnable;
+ logicOpEnable = createInfo.logicOpEnable;
+ logicOp = createInfo.logicOp;
+ attachmentCount = static_cast<deUint32>(m_attachments.size());
+ pAttachments = &m_attachments[0];
+ deMemcpy(blendConst, &_blendConst[0], 4 * sizeof(float));
+}
+
+PipelineCreateInfo::ColorBlendState::Attachment::Attachment ( vk::VkBool32 _blendEnable,
+ vk::VkBlend _srcBlendColor,
+ vk::VkBlend _destBlendColor,
+ vk::VkBlendOp _blendOpColor,
+ vk::VkBlend _srcBlendAlpha,
+ vk::VkBlend _destBlendAlpha,
+ vk::VkBlendOp _blendOpAlpha,
+ deUint8 _channelWriteMask)
+{
+ blendEnable = _blendEnable;
+ srcBlendColor = _srcBlendColor;
+ destBlendColor = _destBlendColor;
+ blendOpColor = _blendOpColor;
+ srcBlendAlpha = _srcBlendAlpha;
+ destBlendAlpha = _destBlendAlpha;
+ blendOpAlpha = _blendOpAlpha;
+ channelWriteMask = _channelWriteMask;
+}
+
+PipelineCreateInfo::DepthStencilState::StencilOpState::StencilOpState ( vk::VkStencilOp _stencilFailOp,
+ vk::VkStencilOp _stencilPassOp,
+ vk::VkStencilOp _stencilDepthFailOp,
+ vk::VkCompareOp _stencilCompareOp,
+ deUint32 _stencilCompareMask,\r
+ deUint32 _stencilWriteMask,\r
+ deUint32 _stencilReference)
+{
+ stencilFailOp = _stencilFailOp;
+ stencilPassOp = _stencilPassOp;
+ stencilDepthFailOp = _stencilDepthFailOp;
+ stencilCompareOp = _stencilCompareOp;
+\r
+ stencilCompareMask = _stencilCompareMask;
+ stencilWriteMask = _stencilWriteMask;
+ stencilReference = _stencilReference;
+}
+
+PipelineCreateInfo::DepthStencilState::DepthStencilState (vk::VkBool32 _depthTestEnable,
+ vk::VkBool32 _depthWriteEnable,
+ vk::VkCompareOp _depthCompareOp,
+ vk::VkBool32 _depthBoundsTestEnable,
+ vk::VkBool32 _stencilTestEnable,
+ StencilOpState _front,
+ StencilOpState _back,
+ float _minDepthBounds,
+ float _maxDepthBounds)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+ pNext = DE_NULL;
+ depthTestEnable = _depthTestEnable;
+ depthWriteEnable = _depthWriteEnable;
+ depthCompareOp = _depthCompareOp;
+ depthBoundsTestEnable = _depthBoundsTestEnable;
+ stencilTestEnable = _stencilTestEnable;
+ front = _front;
+ back = _back;
+
+ minDepthBounds = _minDepthBounds;
+ maxDepthBounds = _maxDepthBounds;
+}
+
+PipelineCreateInfo::DynamicState::DynamicState (const std::vector<vk::VkDynamicState>& _dynamicStates)
+{
+ sType = vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+ pNext = DE_NULL;
+
+ if (!_dynamicStates.size())
+ {
+ for (size_t i = 0; i < vk::VK_DYNAMIC_STATE_LAST; ++i)
+ {
+ m_dynamicStates.push_back(static_cast<vk::VkDynamicState>(i));
+ }
+ }
+ else
+ m_dynamicStates = _dynamicStates;
+
+ dynamicStateCount = static_cast<deUint32>(m_dynamicStates.size());
+ pDynamicStates = &m_dynamicStates[0];
+}
+
+PipelineCreateInfo::DynamicState::DynamicState (const DynamicState &other)
+{
+ sType = other.sType;\r
+ pNext = other.pNext;
+
+ dynamicStateCount = other.dynamicStateCount;
+
+ m_dynamicStates = std::vector<vk::VkDynamicState>(other.pDynamicStates, other.pDynamicStates + dynamicStateCount);
+ pDynamicStates = &m_dynamicStates[0];
+}
+
+PipelineCreateInfo::DynamicState & PipelineCreateInfo::DynamicState::operator= (const DynamicState &other)
+{
+ sType = other.sType;\r
+ pNext = other.pNext;
+
+ dynamicStateCount = other.dynamicStateCount;
+
+ m_dynamicStates = std::vector<vk::VkDynamicState>(other.pDynamicStates, other.pDynamicStates + dynamicStateCount);
+ pDynamicStates = &m_dynamicStates[0];
+
+ return *this;
+}
+
+PipelineCreateInfo::PipelineCreateInfo (vk::VkPipelineLayout _layout,
+ vk::VkRenderPass _renderPass,
+ int _subpass,
+ vk::VkPipelineCreateFlags _flags)
+{
+ memset(static_cast<vk::VkGraphicsPipelineCreateInfo *>(this), 0,
+ sizeof(vk::VkGraphicsPipelineCreateInfo));
+
+ sType = vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+ pNext = DE_NULL;
+ renderPass = _renderPass;
+ subpass = _subpass;
+
+ flags = _flags;
+ layout = _layout;
+ basePipelineHandle = DE_NULL;
+ basePipelineIndex = 0;
+ pDynamicState = DE_NULL;
+}
+
+PipelineCreateInfo& PipelineCreateInfo::addShader (const vk::VkPipelineShaderStageCreateInfo &shader)
+{
+ m_shaders.push_back(shader);
+
+ stageCount = static_cast<deUint32>(m_shaders.size());
+ pStages = &m_shaders[0];
+
+ return *this;
+}
+
+PipelineCreateInfo& PipelineCreateInfo::addState (const vk::VkPipelineVertexInputStateCreateInfo& state)
+{
+ m_vertexInputState = de::SharedPtr<vk::VkPipelineVertexInputStateCreateInfo>(
+ new vk::VkPipelineVertexInputStateCreateInfo(state));
+
+ pVertexInputState = m_vertexInputState.get();
+
+ return *this;
+}
+
+PipelineCreateInfo& PipelineCreateInfo::addState (const vk::VkPipelineInputAssemblyStateCreateInfo& state)
+{
+ m_iputAssemblyState = de::SharedPtr<vk::VkPipelineInputAssemblyStateCreateInfo>(
+ new vk::VkPipelineInputAssemblyStateCreateInfo(state));
+
+ pInputAssemblyState = m_iputAssemblyState.get();
+
+ return *this;
+}
+
+PipelineCreateInfo& PipelineCreateInfo::addState (const vk::VkPipelineColorBlendStateCreateInfo& state)
+{
+ m_colorBlendStateAttachments = std::vector<vk::VkPipelineColorBlendAttachmentState>(
+ state.pAttachments, state.pAttachments + state.attachmentCount);
+
+ m_colorBlendState = de::SharedPtr<vk::VkPipelineColorBlendStateCreateInfo>(
+ new vk::VkPipelineColorBlendStateCreateInfo(state));
+
+ m_colorBlendState->pAttachments = &m_colorBlendStateAttachments[0];
+
+ pColorBlendState = m_colorBlendState.get();
+
+ return *this;
+}
+
+PipelineCreateInfo& PipelineCreateInfo::addState (const vk::VkPipelineViewportStateCreateInfo& state)
+{
+ m_viewports = std::vector<vk::VkViewport>(state.pViewports, state.pViewports + state.viewportCount);
+ m_scissors = std::vector<vk::VkRect2D>(state.pScissors, state.pScissors + state.scissorCount);
+
+ m_viewportState = de::SharedPtr<vk::VkPipelineViewportStateCreateInfo>(
+ new vk::VkPipelineViewportStateCreateInfo(state));
+
+ m_viewportState->pViewports = &m_viewports[0];
+ m_viewportState->pScissors = &m_scissors[0];
+
+ pViewportState = m_viewportState.get();
+
+ return *this;
+}
+
+PipelineCreateInfo& PipelineCreateInfo::addState (const vk::VkPipelineDepthStencilStateCreateInfo& state)
+{
+ m_dynamicDepthStencilState = de::SharedPtr<vk::VkPipelineDepthStencilStateCreateInfo>(
+ new vk::VkPipelineDepthStencilStateCreateInfo(state));
+
+ pDepthStencilState = m_dynamicDepthStencilState.get();
+
+ return *this;
+}
+
+PipelineCreateInfo& PipelineCreateInfo::addState (const vk::VkPipelineTessellationStateCreateInfo& state)
+{
+ m_tessState = de::SharedPtr<vk::VkPipelineTessellationStateCreateInfo>(
+ new vk::VkPipelineTessellationStateCreateInfo(state));
+
+ pTessellationState = m_tessState.get();
+
+ return *this;
+}
+
+PipelineCreateInfo& PipelineCreateInfo::addState (const vk::VkPipelineRasterStateCreateInfo& state)
+{
+ m_rasterState = de::SharedPtr<vk::VkPipelineRasterStateCreateInfo>(new vk::VkPipelineRasterStateCreateInfo(state));
+ pRasterState = m_rasterState.get();
+
+ return *this;
+}
+
+PipelineCreateInfo& PipelineCreateInfo::addState (const vk::VkPipelineMultisampleStateCreateInfo& state)
+{
+
+ const size_t sampleMaskArrayLen = (sizeof(vk::VkSampleMask) * 8 + state.rasterSamples) / ( sizeof(vk::VkSampleMask) * 8 );
+ m_multisampleStateSampleMask = std::vector<vk::VkSampleMask>(state.pSampleMask, state.pSampleMask + sampleMaskArrayLen);
+
+ m_multisampleState = de::SharedPtr<vk::VkPipelineMultisampleStateCreateInfo>(new vk::VkPipelineMultisampleStateCreateInfo(state));
+
+ m_multisampleState->pSampleMask = &m_multisampleStateSampleMask[0];
+
+ pMultisampleState = m_multisampleState.get();
+
+ return *this;
+}
+PipelineCreateInfo& PipelineCreateInfo::addState (const vk::VkPipelineDynamicStateCreateInfo& state)
+{
+ m_dynamicStates = std::vector<vk::VkDynamicState>(state.pDynamicStates, state.pDynamicStates + state.dynamicStateCount);
+ m_dynamicState = de::SharedPtr<vk::VkPipelineDynamicStateCreateInfo>(new vk::VkPipelineDynamicStateCreateInfo(state));
+
+ m_dynamicState->pDynamicStates = &m_dynamicStates[0];
+
+ pDynamicState = m_dynamicState.get();
+
+ return *this;
+}
+
+SamplerCreateInfo::SamplerCreateInfo ( vk::VkTexFilter _magFilter,
+ vk::VkTexFilter _minFilter,
+ vk::VkTexMipmapMode _mipMode,
+ vk::VkTexAddressMode _addressModeU,
+ vk::VkTexAddressMode _addressModeV,
+ vk::VkTexAddressMode _addressModeW,
+ float _mipLodBias,
+ float _maxAnisotropy,
+ vk::VkBool32 _compareEnable,
+ vk::VkCompareOp _compareOp,
+ float _minLod,
+ float _maxLod,
+ vk::VkBorderColor _borderColor,
+ vk::VkBool32 _unnormalizedCoordinates)
+{
+ sType = vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+ pNext = DE_NULL;
+ magFilter = _magFilter;
+ minFilter = _minFilter;
+ mipMode = _mipMode;
+ addressModeU = _addressModeU;
+ addressModeV = _addressModeV;
+ addressModeW = _addressModeW;
+ mipLodBias = _mipLodBias;
+ maxAnisotropy = _maxAnisotropy;
+ compareEnable = _compareEnable;
+ compareOp = _compareOp;
+ minLod = _minLod;
+ maxLod = _maxLod;
+ borderColor = _borderColor;
+ unnormalizedCoordinates = _unnormalizedCoordinates;
+}
+
+} // DynamicState
+} // vkt
--- /dev/null
+#ifndef _VKT_DYNAMIC_STATE_CREATEINFO_UTIL_HPP
+#define _VKT_DYNAMIC_STATE_CREATEINFO_UTIL_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief CreateInfo utilities
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+#include "tcuVector.hpp"
+
+#include "deSharedPtr.hpp"
+
+#include <vector>
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+class ImageSubresourceRange : public vk::VkImageSubresourceRange
+{
+public:
+ ImageSubresourceRange ( vk::VkImageAspectFlags aspectMask,
+ deUint32 baseMipLevel = 0,
+ deUint32 mipLevels = 1,
+ deUint32 baseArrayLayer = 0,
+ deUint32 arraySize = 1);
+};
+
+class ChannelMapping : public vk::VkChannelMapping
+{
+public:
+ ChannelMapping ( vk::VkChannelSwizzle r = vk::VK_CHANNEL_SWIZZLE_R,
+ vk::VkChannelSwizzle g = vk::VK_CHANNEL_SWIZZLE_G,
+ vk::VkChannelSwizzle b = vk::VK_CHANNEL_SWIZZLE_B,
+ vk::VkChannelSwizzle a = vk::VK_CHANNEL_SWIZZLE_A);
+};
+
+class ImageViewCreateInfo : public vk::VkImageViewCreateInfo
+{
+public:
+ ImageViewCreateInfo ( vk::VkImage image,
+ vk::VkImageViewType viewType,
+ vk::VkFormat format,
+ const vk::VkImageSubresourceRange& subresourceRange,
+ const vk::VkChannelMapping& channels = ChannelMapping(),
+ vk::VkImageViewCreateFlags flags = 0);
+
+ ImageViewCreateInfo ( vk::VkImage image,
+ vk::VkImageViewType viewType,
+ vk::VkFormat format,
+ const vk::VkChannelMapping& channels = ChannelMapping(),
+ vk::VkImageViewCreateFlags flags = 0);
+};
+
+class BufferViewCreateInfo : public vk::VkBufferViewCreateInfo
+{
+public:
+ BufferViewCreateInfo ( vk::VkBuffer buffer,
+ vk::VkFormat format,
+ vk::VkDeviceSize offset,
+ vk::VkDeviceSize range);
+};
+
+class BufferCreateInfo : public vk::VkBufferCreateInfo
+{
+public:
+ BufferCreateInfo ( vk::VkDeviceSize size,
+ vk::VkBufferCreateFlags usage,
+ vk::VkSharingMode sharingMode = vk::VK_SHARING_MODE_EXCLUSIVE,
+ deUint32 queueFamilyCount = 0,
+ const deUint32* pQueueFamilyIndices = DE_NULL,
+ vk::VkBufferCreateFlags flags = 0);
+
+ BufferCreateInfo (const BufferCreateInfo &other);
+ BufferCreateInfo &operator= (const BufferCreateInfo &other);
+
+private:
+ std::vector<deUint32> m_queueFamilyIndices;
+};
+
+
+class ImageCreateInfo : public vk::VkImageCreateInfo
+{
+public:
+ ImageCreateInfo ( vk::VkImageType imageType,
+ vk::VkFormat format,
+ vk::VkExtent3D extent,
+ deUint32 mipLevels,
+ deUint32 arraySize,
+ deUint32 samples,
+ vk::VkImageTiling tiling,
+ vk::VkImageUsageFlags usage,
+ vk::VkSharingMode sharingMode = vk::VK_SHARING_MODE_EXCLUSIVE,
+ deUint32 queueFamilyCount = 0,
+ const deUint32* pQueueFamilyIndices = DE_NULL,
+ vk::VkImageCreateFlags flags = 0,
+ vk::VkImageLayout initialLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED);
+
+private:
+ ImageCreateInfo (const ImageCreateInfo &other);
+ ImageCreateInfo &operator= (const ImageCreateInfo &other);
+
+ std::vector<deUint32> m_queueFamilyIndices;
+};
+
+class FramebufferCreateInfo : public vk::VkFramebufferCreateInfo
+{
+public:
+ FramebufferCreateInfo ( vk::VkRenderPass renderPass,
+ const std::vector<vk::VkImageView>& attachments,
+ deUint32 width,
+ deUint32 height,
+ deUint32 layers);
+};
+
+class AttachmentDescription : public vk::VkAttachmentDescription
+{
+public:
+ AttachmentDescription ( vk::VkFormat format,
+ deUint32 samples,
+ vk::VkAttachmentLoadOp loadOp,
+ vk::VkAttachmentStoreOp storeOp,
+ vk::VkAttachmentLoadOp stencilLoadOp,
+ vk::VkAttachmentStoreOp stencilStoreOp,
+ vk::VkImageLayout initialLayout,
+ vk::VkImageLayout finalLayout);
+
+ AttachmentDescription (const vk::VkAttachmentDescription &);
+};
+
+class AttachmentReference : public vk::VkAttachmentReference
+{
+public:
+ AttachmentReference (deUint32 attachment, vk::VkImageLayout layout);
+ AttachmentReference (void);
+};
+
+class SubpassDescription : public vk::VkSubpassDescription
+{
+public:
+ SubpassDescription ( vk::VkPipelineBindPoint pipelineBindPoint,
+ vk::VkSubpassDescriptionFlags flags,
+ deUint32 inputCount,
+ const vk::VkAttachmentReference* inputAttachments,
+ deUint32 colorCount,
+ const vk::VkAttachmentReference* colorAttachments,
+ const vk::VkAttachmentReference* resolveAttachments,
+ vk::VkAttachmentReference depthStencilAttachment,
+ deUint32 preserveCount,
+ const vk::VkAttachmentReference* preserveAttachments);
+
+ SubpassDescription (const vk::VkSubpassDescription &other);
+ SubpassDescription (const SubpassDescription &other);
+ SubpassDescription &operator= (const SubpassDescription &other);
+
+private:
+ std::vector<vk::VkAttachmentReference> m_InputAttachments;
+ std::vector<vk::VkAttachmentReference> m_ColorAttachments;
+ std::vector<vk::VkAttachmentReference> m_ResolveAttachments;
+ std::vector<vk::VkAttachmentReference> m_PreserveAttachments;
+};
+
+class SubpassDependency : public vk::VkSubpassDependency
+{
+public:
+ SubpassDependency ( deUint32 srcSubpass,
+ deUint32 destSubpass,
+ vk::VkPipelineStageFlags srcStageMask,
+ vk::VkPipelineStageFlags destStageMask,
+ vk::VkMemoryOutputFlags outputMask,
+ vk::VkMemoryInputFlags inputMask,
+ vk::VkBool32 byRegion);
+
+ SubpassDependency (const vk::VkSubpassDependency& other);
+};
+
+class RenderPassCreateInfo : public vk::VkRenderPassCreateInfo
+{
+public:
+ RenderPassCreateInfo ( const std::vector<vk::VkAttachmentDescription>& attachments,
+ const std::vector<vk::VkSubpassDescription>& subpasses,
+ const std::vector<vk::VkSubpassDependency>& dependiences = std::vector<vk::VkSubpassDependency>());
+
+ RenderPassCreateInfo ( deUint32 attachmentCount = 0,
+ const vk::VkAttachmentDescription* pAttachments = DE_NULL,
+ deUint32 subpassCount = 0,
+ const vk::VkSubpassDescription* pSubpasses = DE_NULL,
+ deUint32 dependencyCount = 0,
+ const vk::VkSubpassDependency* pDependiences = DE_NULL);
+
+ void addAttachment (vk::VkAttachmentDescription attachment);
+ void addSubpass (vk::VkSubpassDescription subpass);
+ void addDependency (vk::VkSubpassDependency dependency);
+
+private:
+ std::vector<AttachmentDescription> m_attachments;
+ std::vector<SubpassDescription> m_subpasses;
+ std::vector<SubpassDependency> m_dependiences;
+
+ std::vector<vk::VkAttachmentDescription> m_attachmentsStructs;
+ std::vector<vk::VkSubpassDescription> m_subpassesStructs;
+ std::vector<vk::VkSubpassDependency> m_dependiencesStructs;
+
+ RenderPassCreateInfo (const RenderPassCreateInfo &other); //Not allowed!
+ RenderPassCreateInfo &operator= (const RenderPassCreateInfo &other); //Not allowed!
+};
+
+class RenderPassBeginInfo : public vk::VkRenderPassBeginInfo
+{
+public:
+ RenderPassBeginInfo ( vk::VkRenderPass renderPass,
+ vk::VkFramebuffer framebuffer,
+ vk::VkRect2D renderArea,
+ const std::vector<vk::VkClearValue>& clearValues = std::vector<vk::VkClearValue>());
+
+private:
+ std::vector<vk::VkClearValue> m_clearValues;
+
+ RenderPassBeginInfo (const RenderPassBeginInfo &other); //Not allowed!
+ RenderPassBeginInfo &operator= (const RenderPassBeginInfo &other); //Not allowed!
+};
+
+class CmdPoolCreateInfo : public vk::VkCmdPoolCreateInfo
+{
+public:
+ CmdPoolCreateInfo (deUint32 queueFamilyIndex,
+ vk::VkCmdPoolCreateFlags flags = vk::VK_CMD_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
+};
+
+class CmdBufferCreateInfo : public vk::VkCmdBufferCreateInfo
+{
+public:
+ CmdBufferCreateInfo (vk::VkCmdPool pool, vk::VkCmdBufferLevel level, vk::VkCmdBufferCreateFlags flags);
+};
+
+class CmdBufferBeginInfo : public vk::VkCmdBufferBeginInfo
+{
+public:
+ CmdBufferBeginInfo (vk::VkCmdBufferOptimizeFlags flags = 0);
+ CmdBufferBeginInfo (vk::VkRenderPass renderPass,
+ deUint32 subpass,
+ vk::VkFramebuffer framebuffer,
+ vk::VkCmdBufferOptimizeFlags flags = 0);
+};
+
+
+class DescriptorTypeCount : public vk::VkDescriptorTypeCount
+{
+public:
+ DescriptorTypeCount (vk::VkDescriptorType _type, deUint32 _count)
+ {
+ type = _type;
+ count = _count;
+ }
+};
+
+class DescriptorPoolCreateInfo : public vk::VkDescriptorPoolCreateInfo
+{
+public:
+ DescriptorPoolCreateInfo ( const std::vector<vk::VkDescriptorTypeCount>& typeCounts,\r
+ vk::VkDescriptorPoolUsage poolUsage, \r
+ deUint32 maxSets);
+
+ DescriptorPoolCreateInfo& addDescriptors (vk::VkDescriptorType type, deUint32 count);
+
+private:
+ std::vector<vk::VkDescriptorTypeCount> m_typeCounts;
+};
+
+
+class DescriptorSetLayoutCreateInfo : public vk::VkDescriptorSetLayoutCreateInfo
+{
+public:
+ DescriptorSetLayoutCreateInfo (deUint32 count, const vk::VkDescriptorSetLayoutBinding* pBinding);
+};
+
+
+class PipelineLayoutCreateInfo : public vk::VkPipelineLayoutCreateInfo
+{
+public:
+ PipelineLayoutCreateInfo ( deUint32 descriptorSetCount,
+ const vk::VkDescriptorSetLayout* pSetLayouts,
+ deUint32 pushConstantRangeCount = 0,
+ const vk::VkPushConstantRange* pPushConstantRanges = DE_NULL);
+
+ PipelineLayoutCreateInfo ( const std::vector<vk::VkDescriptorSetLayout>& setLayouts = std::vector<vk::VkDescriptorSetLayout>(),
+ deUint32 pushConstantRangeCount = 0,
+ const vk::VkPushConstantRange* pPushConstantRanges = DE_NULL);
+
+private:
+ std::vector<vk::VkDescriptorSetLayout> m_setLayouts;
+ std::vector<vk::VkPushConstantRange> m_pushConstantRanges;
+};
+
+class PipelineCreateInfo : public vk::VkGraphicsPipelineCreateInfo
+{
+public:
+ class VertexInputState : public vk::VkPipelineVertexInputStateCreateInfo
+ {
+ public:
+ VertexInputState ( deUint32 bindingCount = 0,
+ const vk::VkVertexInputBindingDescription* pVertexBindingDescriptions = NULL,
+ deUint32 attributeCount = 0,
+ const vk::VkVertexInputAttributeDescription* pVertexAttributeDescriptions = NULL);
+ };
+
+ class InputAssemblerState : public vk::VkPipelineInputAssemblyStateCreateInfo
+ {
+ public:
+ InputAssemblerState (vk::VkPrimitiveTopology topology, vk::VkBool32 primitiveRestartEnable = false);
+ };
+
+ class TesselationState : public vk::VkPipelineTessellationStateCreateInfo
+ {
+ public:
+ TesselationState (deUint32 patchControlPoints = 0);
+ };
+
+ class ViewportState : public vk::VkPipelineViewportStateCreateInfo
+ {
+ public:
+ ViewportState ( deUint32 viewportCount,
+ std::vector<vk::VkViewport> viewports = std::vector<vk::VkViewport>(0),
+ std::vector<vk::VkRect2D> scissors = std::vector<vk::VkRect2D>(0));
+
+ ViewportState (const ViewportState &other);
+ ViewportState &operator= (const ViewportState &other);
+
+ std::vector<vk::VkViewport> m_viewports;
+ std::vector<vk::VkRect2D> m_scissors;
+ };
+
+ class RasterizerState : public vk::VkPipelineRasterStateCreateInfo
+ {
+ public:
+ RasterizerState ( vk::VkBool32 depthClipEnable = false,
+ vk::VkBool32 rasterizerDiscardEnable = false,
+ vk::VkFillMode fillMode = vk::VK_FILL_MODE_SOLID,
+ vk::VkCullMode cullMode = vk::VK_CULL_MODE_NONE,
+ vk::VkFrontFace frontFace = vk::VK_FRONT_FACE_CW,
+ vk::VkBool32 depthBiasEnable = true,\r
+ float depthBias = 0.0f,
+ float depthBiasClamp = 0.0f,
+ float slopeScaledDepthBias = 0.0f,
+ float lineWidth = 1.0f);
+ };
+
+ class MultiSampleState : public vk::VkPipelineMultisampleStateCreateInfo
+ {
+ public:
+ MultiSampleState ( deUint32 rasterSamples = 1,
+ vk::VkBool32 sampleShadingEnable = false,
+ float minSampleShading = 0.0f,
+ const std::vector<vk::VkSampleMask>& sampleMask = std::vector<vk::VkSampleMask>(1, 0xffffffff));
+
+ MultiSampleState (const MultiSampleState &other);
+ MultiSampleState &operator= (const MultiSampleState &other);
+
+ private:
+ std::vector<vk::VkSampleMask> m_sampleMask;
+ };
+
+ class ColorBlendState : public vk::VkPipelineColorBlendStateCreateInfo
+ {
+ public:
+ class Attachment : public vk::VkPipelineColorBlendAttachmentState
+ {
+ public:
+ Attachment (vk::VkBool32 blendEnable = false,
+ vk::VkBlend srcBlendColor = vk::VK_BLEND_SRC_COLOR,
+ vk::VkBlend destBlendColor = vk::VK_BLEND_DEST_COLOR,
+ vk::VkBlendOp blendOpColor = vk::VK_BLEND_OP_ADD,
+ vk::VkBlend srcBlendAlpha = vk::VK_BLEND_SRC_COLOR,
+ vk::VkBlend destBlendAlpha = vk::VK_BLEND_DEST_COLOR,
+ vk::VkBlendOp blendOpAlpha = vk::VK_BLEND_OP_ADD,
+ deUint8 channelWriteMask = 0xff);
+ };
+
+ ColorBlendState ( const std::vector<vk::VkPipelineColorBlendAttachmentState>& attachments,
+ vk::VkBool32 alphaToCoverageEnable = false,
+ vk::VkBool32 logicOpEnable = false,
+ vk::VkLogicOp logicOp = vk::VK_LOGIC_OP_COPY,
+ vk::VkBool32 alphaToOneEnable = false);
+
+ ColorBlendState ( deUint32 attachmentCount,
+ const vk::VkPipelineColorBlendAttachmentState* attachments,
+ vk::VkBool32 alphaToCoverageEnable = false,
+ vk::VkBool32 logicOpEnable = false,
+ vk::VkLogicOp logicOp = vk::VK_LOGIC_OP_COPY,
+ vk::VkBool32 alphaToOneEnable = false);
+
+ ColorBlendState (const vk::VkPipelineColorBlendStateCreateInfo &createInfo);
+ ColorBlendState (const ColorBlendState &createInfo, std::vector<float> blendConst = std::vector<float>(4));
+
+ private:
+ std::vector<vk::VkPipelineColorBlendAttachmentState> m_attachments;
+ };
+
+ class DepthStencilState : public vk::VkPipelineDepthStencilStateCreateInfo
+ {
+ public:
+ class StencilOpState : public vk::VkStencilOpState
+ {
+ public:
+ StencilOpState (vk::VkStencilOp stencilFailOp = vk::VK_STENCIL_OP_REPLACE,
+ vk::VkStencilOp stencilPassOp = vk::VK_STENCIL_OP_REPLACE,
+ vk::VkStencilOp stencilDepthFailOp = vk::VK_STENCIL_OP_REPLACE,
+ vk::VkCompareOp stencilCompareOp = vk::VK_COMPARE_OP_ALWAYS,
+ deUint32 stencilCompareMask = 0xffffffffu,\r
+ deUint32 stencilWriteMask = 0xffffffffu,\r
+ deUint32 stencilReference = 0);
+ };
+
+ DepthStencilState ( vk::VkBool32 depthTestEnable = false,
+ vk::VkBool32 depthWriteEnable = false,
+ vk::VkCompareOp depthCompareOp = vk::VK_COMPARE_OP_ALWAYS,
+ vk::VkBool32 depthBoundsTestEnable = false,
+ vk::VkBool32 stencilTestEnable = false,
+ StencilOpState front = StencilOpState(),
+ StencilOpState back = StencilOpState(),
+ float minDepthBounds = -1.0f,
+ float maxDepthBounds = 1.0f);
+ };
+
+ class PipelineShaderStage : public vk::VkPipelineShaderStageCreateInfo
+ {
+ public:
+ PipelineShaderStage (vk::VkShader shader, vk::VkShaderStage stage);
+ };
+
+ class DynamicState : public vk::VkPipelineDynamicStateCreateInfo
+ {
+ public:
+ DynamicState (const std::vector<vk::VkDynamicState>& dynamicStates = std::vector<vk::VkDynamicState>(0));
+
+ DynamicState (const DynamicState &other);
+ DynamicState &operator= (const DynamicState &other);
+
+ std::vector<vk::VkDynamicState> m_dynamicStates;
+ };
+
+ PipelineCreateInfo(vk::VkPipelineLayout layout, vk::VkRenderPass renderPass, int subpass, vk::VkPipelineCreateFlags flags);
+
+ PipelineCreateInfo &addShader (const vk::VkPipelineShaderStageCreateInfo& shader);
+
+ PipelineCreateInfo &addState (const vk::VkPipelineVertexInputStateCreateInfo& state);
+ PipelineCreateInfo &addState (const vk::VkPipelineInputAssemblyStateCreateInfo& state);
+ PipelineCreateInfo &addState (const vk::VkPipelineColorBlendStateCreateInfo& state);
+ PipelineCreateInfo &addState (const vk::VkPipelineViewportStateCreateInfo& state);
+ PipelineCreateInfo &addState (const vk::VkPipelineDepthStencilStateCreateInfo& state);
+ PipelineCreateInfo &addState (const vk::VkPipelineTessellationStateCreateInfo& state);
+ PipelineCreateInfo &addState (const vk::VkPipelineRasterStateCreateInfo& state);
+ PipelineCreateInfo &addState (const vk::VkPipelineMultisampleStateCreateInfo& state);
+ PipelineCreateInfo &addState (const vk::VkPipelineDynamicStateCreateInfo& state);
+
+private:
+ std::vector<vk::VkPipelineShaderStageCreateInfo> m_shaders;
+
+ de::SharedPtr<vk::VkPipelineVertexInputStateCreateInfo> m_vertexInputState;
+ de::SharedPtr<vk::VkPipelineInputAssemblyStateCreateInfo> m_iputAssemblyState;
+ std::vector<vk::VkPipelineColorBlendAttachmentState> m_colorBlendStateAttachments;
+ de::SharedPtr<vk::VkPipelineColorBlendStateCreateInfo> m_colorBlendState;
+ de::SharedPtr<vk::VkPipelineViewportStateCreateInfo> m_viewportState;
+ de::SharedPtr<vk::VkPipelineDepthStencilStateCreateInfo> m_dynamicDepthStencilState;
+ de::SharedPtr<vk::VkPipelineTessellationStateCreateInfo> m_tessState;
+ de::SharedPtr<vk::VkPipelineRasterStateCreateInfo> m_rasterState;
+ de::SharedPtr<vk::VkPipelineMultisampleStateCreateInfo> m_multisampleState;
+ de::SharedPtr<vk::VkPipelineDynamicStateCreateInfo> m_dynamicState;
+
+ std::vector<vk::VkDynamicState> m_dynamicStates;
+
+ std::vector<vk::VkViewport> m_viewports;
+ std::vector<vk::VkRect2D> m_scissors;
+
+ std::vector<vk::VkSampleMask> m_multisampleStateSampleMask;
+};
+
+class SamplerCreateInfo : public vk::VkSamplerCreateInfo
+{
+public:
+ SamplerCreateInfo ( vk::VkTexFilter magFilter = vk::VK_TEX_FILTER_NEAREST,
+ vk::VkTexFilter minFilter = vk::VK_TEX_FILTER_NEAREST,
+ vk::VkTexMipmapMode mipMode = vk::VK_TEX_MIPMAP_MODE_NEAREST,
+ vk::VkTexAddressMode addressU = vk::VK_TEX_ADDRESS_MODE_MIRROR,
+ vk::VkTexAddressMode addressV = vk::VK_TEX_ADDRESS_MODE_MIRROR,
+ vk::VkTexAddressMode addressW = vk::VK_TEX_ADDRESS_MODE_MIRROR,
+ float mipLodBias = 0.0f,
+ float maxAnisotropy = 1.0f,
+ vk::VkBool32 compareEnable = false,
+ vk::VkCompareOp compareOp = vk::VK_COMPARE_OP_ALWAYS,
+ float minLod = 0.0f,
+ float maxLod = 16.0f,
+ vk::VkBorderColor borderColor = vk::VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
+ vk::VkBool32 unnormalizedCoordinates = false);
+};
+
+} // DynamicState
+} // vkt
+
+#endif // _VKT_DYNAMIC_STATE_CREATEINFO_UTIL_HPP
--- /dev/null
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic State Depth Stencil Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDynamicStateDSTests.hpp"
+
+#include "vktTestCaseUtil.hpp"
+#include "vktDynamicStateTestCaseUtil.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuResource.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuCommandLine.hpp"
+#include "tcuTextureUtil.hpp"
+
+#include "vkRefUtil.hpp"
+#include "vkImageUtil.hpp"
+
+#include "vktDynamicStateCreateInfoUtil.hpp"
+#include "vktDynamicStateImageObjectUtil.hpp"
+#include "vktDynamicStateBufferObjectUtil.hpp"
+#include "vkPrograms.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+inline tcu::Vec4 vec4Red (void)
+{
+ return tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
+}
+
+inline tcu::Vec4 vec4Green (void)
+{
+ return tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
+}
+
+inline tcu::Vec4 vec4Blue (void)
+{
+ return tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
+}
+
+vk::Move<vk::VkShader> createShader(const vk::DeviceInterface &vk, const vk::VkDevice device,
+ const vk::VkShaderModule module, const char* name, const vk::VkShaderStage stage)
+{
+ vk::VkShaderCreateInfo createInfo;
+ createInfo.sType = vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO;
+ createInfo.pNext = DE_NULL;
+ createInfo.module = module;
+ createInfo.pName = name;
+ createInfo.flags = 0;
+ createInfo.stage = stage;
+ return vk::createShader(vk, device, &createInfo);
+}
+
+namespace
+{
+
+struct Vec4RGBA
+{
+ Vec4RGBA(tcu::Vec4 p, tcu::Vec4 c)
+ : position(p)
+ , color(c)
+ {}
+ tcu::Vec4 position;
+ tcu::Vec4 color;
+};
+
+class DepthStencilBaseCase : public TestInstance
+{
+public:
+ DepthStencilBaseCase (Context &context, const char* vertexShaderName, const char* fragmentShaderName)
+ : TestInstance (context)
+ , m_colorAttachmentFormat (vk::VK_FORMAT_R8G8B8A8_UNORM)
+ , m_depthStencilAttachmentFormat (vk::VK_FORMAT_D24_UNORM_S8_UINT)
+ , m_topology (vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
+ , m_vertexShaderName (vertexShaderName)
+ , m_fragmentShaderName (fragmentShaderName)
+ , m_vk (context.getDeviceInterface())
+ {
+ }
+
+protected:
+
+ enum
+ {
+ WIDTH = 128,
+ HEIGHT = 128
+ };
+
+ vk::VkFormat m_colorAttachmentFormat;
+ vk::VkFormat m_depthStencilAttachmentFormat;
+
+ vk::VkPrimitiveTopology m_topology;
+
+ const vk::DeviceInterface& m_vk;
+
+ vk::Move<vk::VkPipeline> m_pipeline_1;
+ vk::Move<vk::VkPipeline> m_pipeline_2;
+ vk::Move<vk::VkPipelineLayout> m_pipelineLayout;
+
+ de::SharedPtr<Image> m_colorTargetImage;
+ vk::Move<vk::VkImageView> m_colorTargetView;
+
+ de::SharedPtr<Image> m_depthStencilImage;
+ vk::Move<vk::VkImageView> m_attachmentView;
+
+ PipelineCreateInfo::VertexInputState m_vertexInputState;
+ de::SharedPtr<Buffer> m_vertexBuffer;
+
+ vk::Move<vk::VkCmdPool> m_cmdPool;
+ vk::Move<vk::VkCmdBuffer> m_cmdBuffer;
+
+ vk::Move<vk::VkFramebuffer> m_framebuffer;
+ vk::Move<vk::VkRenderPass> m_renderPass;
+
+ const std::string m_vertexShaderName;
+ const std::string m_fragmentShaderName;
+
+ std::vector<Vec4RGBA> m_data;
+
+ PipelineCreateInfo::DepthStencilState m_depthStencilState_1;
+ PipelineCreateInfo::DepthStencilState m_depthStencilState_2;
+
+ void initialize (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkDevice device = m_context.getDevice();
+
+ const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
+ m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
+
+ const vk::Unique<vk::VkShader> vs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_VERTEX));
+
+ const vk::Unique<vk::VkShader> fs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_FRAGMENT));
+
+
+ const vk::VkExtent3D imageExtent = { WIDTH, HEIGHT, 1 };
+ const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, 1,
+ vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT);
+
+ m_colorTargetImage = Image::CreateAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator());
+
+ const ImageCreateInfo depthStencilImageCreateInfo(
+ vk::VK_IMAGE_TYPE_2D, m_depthStencilAttachmentFormat, imageExtent,
+ 1, 1, 1, vk::VK_IMAGE_TILING_OPTIMAL,
+ vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
+
+ m_depthStencilImage = Image::CreateAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator());
+
+ const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
+ m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
+
+ const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthStencilAttachmentFormat);
+ m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo);
+
+ RenderPassCreateInfo renderPassCreateInfo;
+ renderPassCreateInfo.addAttachment(AttachmentDescription(
+ m_colorAttachmentFormat,
+ 1,
+ vk::VK_ATTACHMENT_LOAD_OP_LOAD,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_IMAGE_LAYOUT_GENERAL,
+ vk::VK_IMAGE_LAYOUT_GENERAL));
+
+ renderPassCreateInfo.addAttachment(AttachmentDescription(
+ m_depthStencilAttachmentFormat,
+ 1,
+ vk::VK_ATTACHMENT_LOAD_OP_LOAD,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+ vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
+
+ const vk::VkAttachmentReference colorAttachmentReference =
+ {
+ 0,
+ vk::VK_IMAGE_LAYOUT_GENERAL
+ };
+
+ const vk::VkAttachmentReference depthAttachmentReference =
+ {
+ 1,
+ vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
+ };
+
+ renderPassCreateInfo.addSubpass(SubpassDescription(
+ vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
+ vk::VK_SUBPASS_DESCRIPTION_NO_OVERDRAW_BIT,
+ 0,
+ DE_NULL,
+ 1,
+ &colorAttachmentReference,
+ DE_NULL,
+ depthAttachmentReference,
+ 0,
+ DE_NULL));
+
+ m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
+
+ const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
+ {
+ 0,
+ sizeof(tcu::Vec4) * 2,
+ vk::VK_VERTEX_INPUT_STEP_RATE_VERTEX,
+ };
+
+ const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
+ {
+ {
+ 0u,
+ 0u,
+ vk::VK_FORMAT_R32G32B32A32_SFLOAT,
+ 0u
+ },
+ {
+ 1u,
+ 0u,
+ vk::VK_FORMAT_R32G32B32A32_SFLOAT,
+ (deUint32)(sizeof(float)* 4),
+ }
+ };
+
+ m_vertexInputState = PipelineCreateInfo::VertexInputState(
+ 1,
+ &vertexInputBindingDescription,
+ 2,
+ vertexInputAttributeDescriptions);
+
+ const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
+
+ PipelineCreateInfo pipelineCreateInfo_1(*m_pipelineLayout, *m_renderPass, 0, 0);
+ pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, vk::VK_SHADER_STAGE_VERTEX));
+ pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, vk::VK_SHADER_STAGE_FRAGMENT));
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::ViewportState(1));
+ pipelineCreateInfo_1.addState(m_depthStencilState_1);
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::RasterizerState());
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::MultiSampleState());
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::DynamicState());
+
+ PipelineCreateInfo pipelineCreateInfo_2(*m_pipelineLayout, *m_renderPass, 0, 0);
+ pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, vk::VK_SHADER_STAGE_VERTEX));
+ pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, vk::VK_SHADER_STAGE_FRAGMENT));
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::ViewportState(1));
+ pipelineCreateInfo_2.addState(m_depthStencilState_2);
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::RasterizerState());
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::MultiSampleState());
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::DynamicState());
+
+ m_pipeline_1 = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_1);
+ m_pipeline_2 = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_2);
+
+ std::vector<vk::VkImageView> attachments(2);
+ attachments[0] = *m_colorTargetView;
+ attachments[1] = *m_attachmentView;
+
+ const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
+
+ m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
+
+ const vk::VkDeviceSize dataSize = m_data.size() * sizeof(Vec4RGBA);
+ m_vertexBuffer = Buffer::CreateAndAlloc(m_vk, device, BufferCreateInfo(dataSize,
+ vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
+ m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
+
+ unsigned char *ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
+ deMemcpy(ptr, &m_data[0], dataSize);
+
+ vk::flushMappedMemoryRange(m_vk, device,
+ m_vertexBuffer->getBoundMemory().getMemory(),
+ m_vertexBuffer->getBoundMemory().getOffset(),
+ sizeof(dataSize));
+
+ const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
+ m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
+
+ const CmdBufferCreateInfo cmdBufCreateInfo(*m_cmdPool, vk::VK_CMD_BUFFER_LEVEL_PRIMARY, 0);
+ m_cmdBuffer = vk::createCommandBuffer(m_vk, device, &cmdBufCreateInfo);
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ TCU_FAIL("Implement iterate() method!");
+ }
+
+ void beginRenderPass (void)
+ {
+ const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
+ beginRenderPassWithClearColor(clearColor);
+ }
+
+ void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor)
+ {
+ const CmdBufferBeginInfo beginInfo;
+ m_vk.beginCommandBuffer(*m_cmdBuffer, &beginInfo);
+
+ initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL);
+ initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL);
+
+ const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT);
+ m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRangeImage);
+
+ const vk::VkClearDepthStencilValue depthStencilClearValue = { 0.0f, 0 };
+
+ const ImageSubresourceRange subresourceRangeDepthStencil[2] = { vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_ASPECT_STENCIL_BIT };
+ m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(),
+ vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, &depthStencilClearValue, 2, subresourceRangeDepthStencil);
+
+ const vk::VkRect2D renderArea = { { 0, 0 }, { WIDTH, HEIGHT } };
+ const RenderPassBeginInfo renderPassBegin(*m_renderPass, *m_framebuffer, renderArea);
+
+ m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBegin, vk::VK_RENDER_PASS_CONTENTS_INLINE);
+ }
+
+ void setDynamicViewportState (const deUint32 width, const deUint32 height)
+ {
+ vk::VkViewport viewport;
+ viewport.originX = 0;
+ viewport.originY = 0;
+ viewport.width = static_cast<float>(width);
+ viewport.height = static_cast<float>(height);
+ viewport.minDepth = 0.0f;
+ viewport.maxDepth = 1.0f;
+
+ m_vk.cmdSetViewport(*m_cmdBuffer, 1, &viewport);
+
+ vk::VkRect2D scissor;
+ scissor.offset.x = 0;
+ scissor.offset.y = 0;
+ scissor.extent.width = width;
+ scissor.extent.height = height;
+ m_vk.cmdSetScissor(*m_cmdBuffer, 1, &scissor);
+ }
+
+ void setDynamicViewportState(const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
+ {
+ m_vk.cmdSetViewport(*m_cmdBuffer, viewportCount, pViewports);
+ m_vk.cmdSetScissor(*m_cmdBuffer, viewportCount, pScissors);
+ }
+
+ void setDynamicRasterState(const float lineWidth = 1.0f,
+ const float depthBias = 0.0f,
+ const float depthBiasClamp = 0.0f,
+ const float slopeScaledDepthBias = 0.0f)
+ {
+ m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
+ m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBias, depthBiasClamp, slopeScaledDepthBias);
+ }
+
+ void setDynamicBlendState(const float const1 = 0.0f, const float const2 = 0.0f,
+ const float const3 = 0.0f, const float const4 = 0.0f)
+ {
+ float blendConstants[4] = { const1, const2, const3, const4 };
+ m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstants);
+ }
+
+ void setDynamicDepthStencilState(const float minDepthBounds = -1.0f,
+ const float maxDepthBounds = 1.0f,
+ const deUint32 stencilFrontCompareMask = 0xffffffffu,
+ const deUint32 stencilFrontWriteMask = 0xffffffffu,
+ const deUint32 stencilFrontReference = 0,
+ const deUint32 stencilBackCompareMask = 0xffffffffu,
+ const deUint32 stencilBackWriteMask = 0xffffffffu,
+ const deUint32 stencilBackReference = 0)
+ {
+ m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
+ m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
+ m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
+ m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
+ m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
+ m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
+ m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
+ }
+};
+
+class DepthBoundsParamTestInstance : public DepthStencilBaseCase
+{
+public:
+ DepthBoundsParamTestInstance (Context &context, ShaderMap shaders)
+ : DepthStencilBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ {
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 0.375f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.0f, 1.0f, 0.375f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 0.375f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.0f, -1.0f, 0.375f, 1.0f), vec4Green()));
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.0f, 1.0f, 0.625f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 0.625f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.0f, -1.0f, 0.625f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 0.625f, 1.0f), vec4Green()));
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), vec4Blue()));
+
+ m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
+ vk::VK_TRUE, vk::VK_TRUE, vk::VK_COMPARE_OP_ALWAYS, vk::VK_FALSE);
+
+ // enable depth bounds test
+ m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
+ vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_TRUE);
+
+ DepthStencilBaseCase::initialize();
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ vk::VkPhysicalDeviceFeatures features;
+ m_context.getInstanceInterface().getPhysicalDeviceFeatures(m_context.getPhysicalDevice(), &features);
+
+ if (!features.depthBounds)
+ return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "depthBounds Vulkan feature is not supported");
+
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ // set states here
+ setDynamicViewportState(WIDTH, HEIGHT);
+ setDynamicRasterState();
+ setDynamicBlendState();
+ setDynamicDepthStencilState(0.5f, 0.75f);
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+
+ // validation
+ {
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if (xCoord >= 0.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
+ else
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
+ }
+ }
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT))
+ {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+ }
+};
+
+class StencilParamsBasicTestInstance : public DepthStencilBaseCase
+{
+protected:
+ deUint32 m_writeMask;
+ deUint32 m_readMask;
+ deUint32 m_expectedValue;
+ tcu::Vec4 m_expectedColor;
+
+public:
+ StencilParamsBasicTestInstance (Context &context, const char* vertexShaderName, const char* fragmentShaderName,
+ const deUint32 writeMask, const deUint32 readMask,
+ const deUint32 expectedValue, const tcu::Vec4 expectedColor)
+ : DepthStencilBaseCase (context, vertexShaderName, fragmentShaderName)
+ , m_expectedColor (1.0f, 1.0f, 1.0f, 1.0f)
+ {
+ m_writeMask = writeMask;
+ m_readMask = readMask;
+ m_expectedValue = expectedValue;
+ m_expectedColor = expectedColor;
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), vec4Green()));
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), vec4Blue()));
+
+ const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
+ PipelineCreateInfo::DepthStencilState::StencilOpState(
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_COMPARE_OP_ALWAYS);
+
+ const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
+ PipelineCreateInfo::DepthStencilState::StencilOpState(
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_COMPARE_OP_ALWAYS);
+
+ const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
+ PipelineCreateInfo::DepthStencilState::StencilOpState(
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_COMPARE_OP_EQUAL);
+
+ const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
+ PipelineCreateInfo::DepthStencilState::StencilOpState(
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_COMPARE_OP_EQUAL);
+
+ // enable stencil test
+ m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
+ vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_1, backState_1);
+
+ m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
+ vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_2, backState_2);
+
+ DepthStencilBaseCase::initialize();
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ // set states here
+ setDynamicViewportState(WIDTH, HEIGHT);
+ setDynamicRasterState();
+ setDynamicBlendState();
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
+ setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, m_writeMask, 0x0F, 0xFF, m_writeMask, 0x0F);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
+ setDynamicDepthStencilState(-1.0f, 1.0f, m_readMask, 0xFF, m_expectedValue, m_readMask, 0xFF, m_expectedValue);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+
+ // validation
+ {
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
+ referenceFrame.getLevel(0).setPixel(m_expectedColor, x, y);
+ }
+ }
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT))
+ {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+ }
+};
+
+class StencilParamsBasicTestCase : public TestCase
+{
+protected:
+ TestInstance* createInstance(Context& context) const
+ {
+ return new StencilParamsBasicTestInstance(context, "VertexFetch.vert", "VertexFetch.frag",
+ m_writeMask, m_readMask, m_expectedValue, m_expectedColor);
+ }
+
+ virtual void initPrograms(vk::SourceCollections& programCollection) const
+ {
+ programCollection.glslSources.add("VertexFetch.vert") <<
+ glu::VertexSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.vert"));
+
+ programCollection.glslSources.add("VertexFetch.frag") <<
+ glu::FragmentSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.frag"));
+ }
+
+ deUint32 m_writeMask;
+ deUint32 m_readMask;
+ deUint32 m_expectedValue;
+ tcu::Vec4 m_expectedColor;
+
+public:
+ StencilParamsBasicTestCase (tcu::TestContext &context, const char *name, const char *description,
+ const deUint32 writeMask, const deUint32 readMask,
+ const deUint32 expectedValue, const tcu::Vec4 expectedColor)
+ : TestCase (context, name, description)
+ , m_writeMask (writeMask)
+ , m_readMask (readMask)
+ , m_expectedValue (expectedValue)
+ , m_expectedColor (expectedColor)
+ {
+ }
+};
+
+class StencilParamsAdvancedTestInstance : public DepthStencilBaseCase
+{
+public:
+ StencilParamsAdvancedTestInstance (Context &context, ShaderMap shaders)
+ : DepthStencilBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ {
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), vec4Green()));
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), vec4Blue()));
+
+ const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
+ PipelineCreateInfo::DepthStencilState::StencilOpState(
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_COMPARE_OP_ALWAYS);
+
+ const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
+ PipelineCreateInfo::DepthStencilState::StencilOpState(
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_COMPARE_OP_ALWAYS);
+
+ const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
+ PipelineCreateInfo::DepthStencilState::StencilOpState(
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_COMPARE_OP_NOT_EQUAL);
+
+ const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
+ PipelineCreateInfo::DepthStencilState::StencilOpState(
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_STENCIL_OP_REPLACE,
+ vk::VK_COMPARE_OP_NOT_EQUAL);
+
+ // enable stencil test
+ m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
+ vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_1, backState_1);
+
+ m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
+ vk::VK_FALSE, vk::VK_FALSE, vk::VK_COMPARE_OP_NEVER, vk::VK_FALSE, vk::VK_TRUE, frontState_2, backState_2);
+
+ DepthStencilBaseCase::initialize();
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ // set states here
+ setDynamicViewportState(WIDTH, HEIGHT);
+ setDynamicRasterState();
+ setDynamicBlendState();
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
+ setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0x0E, 0x0F, 0xFF, 0x0E, 0x0F);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
+ setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0xFF, 0x0E, 0xFF, 0xFF, 0x0E);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+
+ // validation
+ {
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
+ else
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
+ }
+ }
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT))
+ {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+ }
+};
+
+} //anonymous
+
+DynamicStateDSTests::DynamicStateDSTests (tcu::TestContext &testCtx)
+ : TestCaseGroup (testCtx, "ds_state", "Tests for depth stencil state")
+{
+ /* Left blank on purpose */
+}
+
+DynamicStateDSTests::~DynamicStateDSTests () {}
+
+void DynamicStateDSTests::init (void)
+{
+ ShaderMap shaderPaths;
+ shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
+ shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
+
+ addChild(new InstanceFactory<DepthBoundsParamTestInstance>(m_testCtx, "depth_bounds", "Perform depth bounds test", shaderPaths));
+ addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_1", "Perform basic stencil test 1", 0x0D, 0x06, 0x05, tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f)));
+ addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_2", "Perform basic stencil test 2", 0x06, 0x02, 0x05, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)));
+ addChild(new InstanceFactory<StencilParamsAdvancedTestInstance>(m_testCtx, "stencil_params_advanced", "Perform advanced stencil test", shaderPaths));
+}
+
+} //DynamicState
+} //vkt
--- /dev/null
+#ifndef _VKTDYNAMICSTATEDSTESTS_HPP
+#define _VKTDYNAMICSTATEDSTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic State Depth Stencil Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+class DynamicStateDSTests : public tcu::TestCaseGroup
+{
+public:
+ DynamicStateDSTests (tcu::TestContext &testCtx);
+ ~DynamicStateDSTests (void);
+ void init (void);
+
+private:
+ DynamicStateDSTests (const DynamicStateDSTests &other);
+ DynamicStateDSTests &operator=(const DynamicStateDSTests &other);
+};
+
+} //DynamicState
+} //vkt
+
+#endif // _VKTDYNAMICSTATEDSTESTS_HPP
--- /dev/null
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic State Tests - General
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDynamicStateGeneralTests.hpp"
+
+#include "vktTestCaseUtil.hpp"
+#include "vktDynamicStateTestCaseUtil.hpp"
+#include "vktDynamicStateBaseClass.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuResource.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuTextureUtil.hpp"
+
+#include "vkDefs.hpp"
+#include "vktDynamicStateCreateInfoUtil.hpp"
+#include "vktDynamicStateImageObjectUtil.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+namespace
+{
+
+class StateSwitchTestInstance : public DynamicStateBaseClass
+{
+public:
+ StateSwitchTestInstance (Context &context, ShaderMap shaders)
+ : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ {
+ m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), vec4Green()));
+
+ DynamicStateBaseClass::initialize();
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ // bind states here
+ vk::VkViewport viewport = { 0, 0, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
+ vk::VkRect2D scissor_1 = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
+ vk::VkRect2D scissor_2 = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
+
+ setDynamicRasterState();
+ setDynamicBlendState();
+ setDynamicDepthStencilState();
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ // bind first state
+ setDynamicViewportState(1, &viewport, &scissor_1);
+ m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
+
+ // bind second state
+ setDynamicViewportState(1, &viewport, &scissor_2);
+ m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+
+ //validation
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
+ (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
+ }
+ }
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT)) {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+};
+
+class BindOrderTestInstance : public DynamicStateBaseClass
+{
+public:
+ BindOrderTestInstance (Context &context, ShaderMap shaders)
+ : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ {
+ m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), vec4Green()));
+
+ DynamicStateBaseClass::initialize();
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ // bind states here
+ vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
+ vk::VkRect2D scissor_1 = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
+ vk::VkRect2D scissor_2 = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
+
+ setDynamicRasterState();
+ setDynamicBlendState();
+ setDynamicDepthStencilState();
+ setDynamicViewportState(1, &viewport, &scissor_1);
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ // rebind in different order
+ setDynamicBlendState();
+ setDynamicRasterState();
+ setDynamicDepthStencilState();
+
+ // bind first state
+ setDynamicViewportState(1, &viewport, &scissor_1);
+ m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
+
+ setDynamicViewportState(1, &viewport, &scissor_2);
+ m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+
+ //validation
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
+ (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
+ }
+ }
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT)) {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+};
+
+class StatePersistenceTestInstance : public DynamicStateBaseClass
+{
+protected:
+ vk::Move<vk::VkPipeline> m_pipelineAdditional;
+
+public:
+ StatePersistenceTestInstance (Context &context, ShaderMap shaders)
+ : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ {
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), vec4Green()));
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), vec4Blue()));
+
+ DynamicStateBaseClass::initialize();
+ }
+ virtual void initPipeline (const vk::VkDevice device)
+ {
+ // shaders
+ const vk::Unique<vk::VkShader> vs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_VERTEX));
+
+ const vk::Unique<vk::VkShader> fs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_FRAGMENT));
+
+ const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
+
+ PipelineCreateInfo pipelineCreateInfo_1(*m_pipelineLayout, *m_renderPass, 0, 0);
+ pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, vk::VK_SHADER_STAGE_VERTEX));
+ pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, vk::VK_SHADER_STAGE_FRAGMENT));
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::InputAssemblerState(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP));
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::ViewportState(1));
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::DepthStencilState());
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::RasterizerState());
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::MultiSampleState());
+ pipelineCreateInfo_1.addState(PipelineCreateInfo::DynamicState());
+
+ PipelineCreateInfo pipelineCreateInfo_2(*m_pipelineLayout, *m_renderPass, 0, 0);
+ pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, vk::VK_SHADER_STAGE_VERTEX));
+ pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, vk::VK_SHADER_STAGE_FRAGMENT));
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::InputAssemblerState(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::ViewportState(1));
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::DepthStencilState());
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::RasterizerState());
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::MultiSampleState());
+ pipelineCreateInfo_2.addState(PipelineCreateInfo::DynamicState());
+
+ m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_1);
+ m_pipelineAdditional = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_2);
+ }
+
+ virtual tcu::TestStatus iterate(void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ // bind states here
+ const vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
+ const vk::VkRect2D scissor_1 = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
+ const vk::VkRect2D scissor_2 = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
+
+ setDynamicRasterState();
+ setDynamicBlendState();
+ setDynamicDepthStencilState();
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ // bind first state
+ setDynamicViewportState(1, &viewport, &scissor_1);
+ // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineAdditional);
+
+ // bind second state
+ setDynamicViewportState(1, &viewport, &scissor_2);
+ // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
+ m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 4, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+
+ //validation
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if (yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f)
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
+ else if (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f)
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
+ }
+ }
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT)) {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+};
+
+} //anonymous
+
+DynamicStateGeneralTests::DynamicStateGeneralTests (tcu::TestContext &testCtx)
+ : TestCaseGroup (testCtx, "general_state", "General tests for dynamic states")
+{
+ /* Left blank on purpose */
+}
+
+DynamicStateGeneralTests::~DynamicStateGeneralTests (void) {}
+
+void DynamicStateGeneralTests::init (void)
+{
+ ShaderMap shaderPaths;
+ shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
+ shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
+
+ addChild(new InstanceFactory<StateSwitchTestInstance>(m_testCtx, "state_switch", "Perform multiple draws with different VP states (scissor test)", shaderPaths));
+ addChild(new InstanceFactory<BindOrderTestInstance>(m_testCtx, "bind_order", "Check if binding order is not important for pipeline configuration", shaderPaths));
+ addChild(new InstanceFactory<StatePersistenceTestInstance>(m_testCtx, "state_persistence", "Check if bound states are persistent across pipelines", shaderPaths));
+}
+
+} //DynamicState
+} //vkt
--- /dev/null
+#ifndef _VKTDYNAMICSTATEGENERALTESTS_HPP
+#define _VKTDYNAMICSTATEGENERALTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic State Tests - General
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+class DynamicStateGeneralTests : public tcu::TestCaseGroup
+{
+public:
+ DynamicStateGeneralTests (tcu::TestContext &testCtx);
+ ~DynamicStateGeneralTests (void);
+ void init (void);
+
+private:
+ DynamicStateGeneralTests (const DynamicStateGeneralTests &other);
+ DynamicStateGeneralTests &operator=(const DynamicStateGeneralTests &other);
+};
+
+} //DynamicState
+} //vkt
+
+#endif // _VKTDYNAMICSTATEGENERALTESTS_HPP
--- /dev/null
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Image Object Util
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDynamicStateImageObjectUtil.hpp"
+
+#include "tcuSurface.hpp"
+#include "tcuVectorUtil.hpp"
+
+#include "vkRefUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkImageUtil.hpp"
+#include "vktDynamicStateCreateInfoUtil.hpp"
+#include "vktDynamicStateBufferObjectUtil.hpp"
+
+#include "tcuTextureUtil.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+void MemoryOp::pack (int pixelSize,
+ int width,
+ int height,
+ int depth,
+ vk::VkDeviceSize rowPitch,
+ vk::VkDeviceSize depthPitch,
+ const void * srcBuffer,
+ void * destBuffer)
+{
+ if (rowPitch == 0)
+ rowPitch = width * pixelSize;
+
+ if (depthPitch == 0)
+ depthPitch = rowPitch * height;
+
+ const vk::VkDeviceSize size = depthPitch * depth;
+
+ const char *srcRow = reinterpret_cast<const char *>(srcBuffer);
+ const char *srcStart;
+ srcStart = srcRow;
+ char *dstRow = reinterpret_cast<char *>(destBuffer);
+ char *dstStart;
+ dstStart = dstRow;
+
+ if (rowPitch == static_cast<vk::VkDeviceSize>(width * pixelSize) &&
+ depthPitch == static_cast<vk::VkDeviceSize>(rowPitch * height))
+ {
+ // fast path
+ deMemcpy(dstRow, srcRow, static_cast<size_t>(size));
+ }
+ else
+ {
+ // slower, per row path
+ for (int d = 0; d < depth; d++)
+ {
+ vk::VkDeviceSize offsetDepthDst = d * depthPitch;
+ vk::VkDeviceSize offsetDepthSrc = d * (pixelSize * width * height);
+ srcRow = srcStart + offsetDepthSrc;
+ dstRow = dstStart + offsetDepthDst;
+ for (int r = 0; r < height; ++r)
+ {
+ deMemcpy(dstRow, srcRow, static_cast<size_t>(rowPitch));
+ srcRow += pixelSize * width;
+ dstRow += rowPitch;
+ }
+ }
+ }
+}
+
+void MemoryOp::unpack (int pixelSize,
+ int width,
+ int height,
+ int depth,
+ vk::VkDeviceSize rowPitch,
+ vk::VkDeviceSize depthPitch,
+ const void * srcBuffer,
+ void * destBuffer)
+{
+ if (rowPitch == 0)
+ rowPitch = width * pixelSize;
+
+ if (depthPitch == 0)
+ depthPitch = rowPitch * height;
+
+ const vk::VkDeviceSize size = depthPitch * depth;
+
+ const char *srcRow = reinterpret_cast<const char *>(srcBuffer);
+ const char *srcStart;
+ srcStart = srcRow;
+ char *dstRow = reinterpret_cast<char *>(destBuffer);
+ char *dstStart;
+ dstStart = dstRow;
+
+ if (rowPitch == static_cast<vk::VkDeviceSize>(width * pixelSize) &&
+ depthPitch == static_cast<vk::VkDeviceSize>(rowPitch * height))
+ {
+ // fast path
+ deMemcpy(dstRow, srcRow, static_cast<size_t>(size));
+ }
+ else {
+ // slower, per row path
+ for (size_t d = 0; d < (size_t)depth; d++)
+ {
+ vk::VkDeviceSize offsetDepthDst = d * (pixelSize * width * height);
+ vk::VkDeviceSize offsetDepthSrc = d * depthPitch;
+ srcRow = srcStart + offsetDepthSrc;
+ dstRow = dstStart + offsetDepthDst;
+ for (int r = 0; r < height; ++r)
+ {
+ deMemcpy(dstRow, srcRow, static_cast<size_t>(pixelSize * width));
+ srcRow += rowPitch;
+ dstRow += pixelSize * width;
+ }
+ }
+ }
+}
+
+Image::Image (const vk::DeviceInterface &vk,
+ vk::VkDevice device,
+ vk::VkFormat format,
+ const vk::VkExtent3D &extend,
+ deUint32 mipLevels,
+ deUint32 arraySize,
+ vk::Move<vk::VkImage> object)
+ : m_allocation (DE_NULL)
+ , m_object (object)
+ , m_format (format)
+ , m_extent (extend)
+ , m_mipLevels (mipLevels)
+ , m_arraySize (arraySize)
+ , m_vk(vk)
+ , m_device(device)
+{
+}
+
+tcu::ConstPixelBufferAccess Image::readSurface (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel,
+ unsigned int arrayElement)
+{
+ m_pixelAccessData.resize(width * height * vk::mapVkFormat(m_format).getPixelSize());
+ memset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ read(queue, allocator, layout, offset, width, height, 1, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_2D,
+ m_pixelAccessData.data());
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH || aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ readUsingBuffer(queue, allocator, layout, offset, width, height, 1, mipLevel, arrayElement, aspect, m_pixelAccessData.data());
+ }
+ return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, 1, m_pixelAccessData.data());
+}
+
+tcu::ConstPixelBufferAccess Image::readVolume (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel,
+ unsigned int arrayElement)
+{
+ m_pixelAccessData.resize(width * height * depth * vk::mapVkFormat(m_format).getPixelSize());
+ memset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ read(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_3D,
+ m_pixelAccessData.data());
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH || aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ readUsingBuffer(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect, m_pixelAccessData.data());
+ }
+ return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, depth, m_pixelAccessData.data());
+}
+
+tcu::ConstPixelBufferAccess Image::readSurface1D(vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel,
+ unsigned int arrayElement)
+{
+ m_pixelAccessData.resize(width * vk::mapVkFormat(m_format).getPixelSize());
+ memset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ read(queue, allocator, layout, offset, width, 1, 1, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_1D,
+ m_pixelAccessData.data());
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH || aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ readUsingBuffer(queue, allocator, layout, offset, width, 1, 1, mipLevel, arrayElement, aspect,
+ m_pixelAccessData.data());
+ }
+ return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, 1, 1, m_pixelAccessData.data());
+}
+
+void Image::read (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ vk::VkImageType type,
+ void * data)
+{
+ if (layout != vk::VK_IMAGE_LAYOUT_GENERAL && layout != vk::VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL)
+ TCU_FAIL("Image::uploadFromSurface usage error: this function is not going to change Image layout!");
+
+ de::SharedPtr<Image> stagingResource = copyToLinearImage(queue, allocator, layout, offset, width,
+ height, depth, mipLevel, arrayElement, aspect, type);
+ const vk::VkOffset3D zeroOffset = {0, 0, 0};
+ stagingResource->readLinear(zeroOffset, width, height, depth, 0, 0, aspect, data);
+}
+
+void Image::readUsingBuffer (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ void * data)
+{
+ if (layout != vk::VK_IMAGE_LAYOUT_GENERAL && layout != vk::VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL)
+ TCU_FAIL("Image::uploadFromSurface usage error: this function is not going to change Image layout!");
+
+ de::SharedPtr<Buffer> stagingResource;
+
+ bool isCombinedType = isCombinedDepthStencilType(vk::mapVkFormat(m_format).type);
+ vk::VkDeviceSize bufferSize = 0;
+
+ if (!isCombinedType)
+ bufferSize = vk::mapVkFormat(m_format).getPixelSize() * width * height * depth;
+
+ if (isCombinedType)
+ {
+ int pixelSize = 0;
+ switch (m_format)
+ {
+ case vk::VK_FORMAT_D16_UNORM_S8_UINT:
+ pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH) ? 2 : 1;
+ break;
+ case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
+ pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH) ? 4 : 1;
+ break;
+ case vk::VK_FORMAT_D24_UNORM_X8:
+ case vk::VK_FORMAT_D24_UNORM_S8_UINT:
+ pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH) ? 3 : 1;
+ break;
+ }
+ bufferSize = pixelSize*width*height*depth;
+ }
+
+ BufferCreateInfo stagingBufferResourceCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT | vk::VK_BUFFER_USAGE_TRANSFER_SOURCE_BIT);
+ stagingResource = Buffer::CreateAndAlloc(m_vk, m_device, stagingBufferResourceCreateInfo, allocator, vk::MemoryRequirement::HostVisible);
+
+ {
+ #pragma message("Get queue family index")
+ CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
+ vk::Unique<vk::VkCmdPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, ©CmdPoolCreateInfo));
+
+ CmdBufferCreateInfo copyCmdBufCreateInfo(*copyCmdPool, vk::VK_CMD_BUFFER_LEVEL_PRIMARY, 0);
+ vk::Unique<vk::VkCmdBuffer> copyCmdBuffer(vk::createCommandBuffer(m_vk, m_device, ©CmdBufCreateInfo));
+
+ CmdBufferBeginInfo beginInfo;
+ VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
+
+ if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
+ {
+ layout = vk::VK_IMAGE_LAYOUT_GENERAL;
+
+ vk::VkImageMemoryBarrier barrier;
+ barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.pNext = DE_NULL;
+ barrier.outputMask = 0;
+ barrier.inputMask = 0;
+ barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
+ barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
+ barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
+ barrier.destQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = object();
+
+ vk::VkImageAspectFlags aspectMask = 0;
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
+ }
+
+ barrier.subresourceRange.aspectMask = aspectMask;
+ barrier.subresourceRange.baseMipLevel = 0;
+ barrier.subresourceRange.mipLevels = m_mipLevels;
+ barrier.subresourceRange.baseArrayLayer = 0;
+ barrier.subresourceRange.arraySize = m_arraySize;
+
+ void* barriers[] = { &barrier };
+
+ m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ false, DE_LENGTH_OF_ARRAY(barriers), barriers);
+ }
+
+ vk::VkImageAspectFlags aspectMask = 0;
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
+ }
+
+ vk::VkBufferImageCopy region =
+ {
+ 0, 0, 0,
+ { aspect, mipLevel, arrayElement, 1 },
+ offset,
+ { width, height, depth }
+ };
+
+ m_vk.cmdCopyImageToBuffer(*copyCmdBuffer, object(), layout, stagingResource->object(), 1, ®ion);
+ VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
+
+ VK_CHECK(m_vk.queueSubmit(queue, 1, ©CmdBuffer.get(), DE_NULL));
+
+ // TODO: make this less intrusive
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+ }
+
+ char* destPtr = reinterpret_cast<char*>(stagingResource->getBoundMemory().getHostPtr());
+ deMemcpy(data, destPtr, bufferSize);
+}
+
+tcu::ConstPixelBufferAccess Image::readSurfaceLinear (vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel,
+ unsigned int arrayElement)
+{
+ m_pixelAccessData.resize(width * height * vk::mapVkFormat(m_format).getPixelSize());
+ readLinear(offset, width, height, depth, mipLevel, arrayElement, aspect, m_pixelAccessData.data());
+ return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, 1, m_pixelAccessData.data());
+}
+
+void Image::readLinear (vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ void * data)
+{
+ vk::VkImageSubresource imageSubResource = { aspect, mipLevel, arrayElement };
+
+ vk::VkSubresourceLayout imageLayout = {};
+
+ VK_CHECK(m_vk.getImageSubresourceLayout(m_device, object(), &imageSubResource, &imageLayout));
+
+ const char* srcPtr = reinterpret_cast<const char*>(getBoundMemory().getHostPtr());
+ srcPtr += imageLayout.offset + getPixelOffset(offset, imageLayout.rowPitch, imageLayout.depthPitch, mipLevel, arrayElement);
+
+ MemoryOp::unpack(vk::mapVkFormat(m_format).getPixelSize(), width, height, depth,
+ imageLayout.rowPitch, imageLayout.depthPitch, srcPtr, data);
+}
+
+de::SharedPtr<Image> Image::copyToLinearImage (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ vk::VkImageType type)
+{
+ de::SharedPtr<Image> stagingResource;
+ {
+ vk::VkExtent3D stagingExtent = {width, height, depth};
+ ImageCreateInfo stagingResourceCreateInfo(
+ type, m_format, stagingExtent, 1, 1, 1,
+ vk::VK_IMAGE_TILING_LINEAR, vk::VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT);
+
+ stagingResource = Image::CreateAndAlloc(m_vk, m_device, stagingResourceCreateInfo, allocator,
+ vk::MemoryRequirement::HostVisible);
+
+ #pragma message("Get queue family index")
+ CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
+ vk::Unique<vk::VkCmdPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, ©CmdPoolCreateInfo));
+
+ CmdBufferCreateInfo copyCmdBufCreateInfo(*copyCmdPool, vk::VK_CMD_BUFFER_LEVEL_PRIMARY, 0);
+ vk::Unique<vk::VkCmdBuffer> copyCmdBuffer(vk::createCommandBuffer(m_vk, m_device, ©CmdBufCreateInfo));
+
+ CmdBufferBeginInfo beginInfo;
+ VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
+
+
+ vk::VkImageAspectFlags aspectMask = 0;
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
+ }
+
+ transition2DImage(m_vk, *copyCmdBuffer, stagingResource->object(), aspectMask, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL);
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ vk::VkImageCopy region = { {aspect, mipLevel, arrayElement, 1}, offset, {aspect, 0, 0, 1}, zeroOffset, {width, height, depth} };
+
+ m_vk.cmdCopyImage(*copyCmdBuffer, object(), layout, stagingResource->object(), vk::VK_IMAGE_LAYOUT_GENERAL, 1, ®ion);
+ VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
+
+ VK_CHECK(m_vk.queueSubmit(queue, 1, ©CmdBuffer.get(), DE_NULL));
+
+ // TODO: make this less intrusive
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+ }
+ return stagingResource;
+}
+
+void Image::uploadVolume(const tcu::ConstPixelBufferAccess &access,
+ vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel,
+ unsigned int arrayElement)
+{
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ upload(queue, allocator, layout, offset, access.getWidth(),
+ access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_3D,
+ access.getDataPtr());
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH || aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
+ access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
+ }
+}
+
+void Image::uploadSurface (const tcu::ConstPixelBufferAccess &access,
+ vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel,
+ unsigned int arrayElement)
+{
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ upload(queue, allocator, layout, offset, access.getWidth(),
+ access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_2D,
+ access.getDataPtr());
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH || aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
+ access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
+ }
+}
+
+void Image::uploadSurface1D (const tcu::ConstPixelBufferAccess &access,
+ vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel,
+ unsigned int arrayElement)
+{
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ upload(queue, allocator, layout, offset, access.getWidth(),
+ access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_1D,
+ access.getDataPtr());
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH || aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
+ access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
+ }
+}
+
+void Image::uploadSurfaceLinear (const tcu::ConstPixelBufferAccess &access,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel,
+ unsigned int arrayElement)
+{
+ uploadLinear(offset, width, height, depth, mipLevel, arrayElement, aspect, access.getDataPtr());
+}
+
+void Image::upload (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ vk::VkImageType type,
+ const void * data)
+{
+
+ if (layout != vk::VK_IMAGE_LAYOUT_UNDEFINED
+ && layout != vk::VK_IMAGE_LAYOUT_GENERAL
+ && layout != vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL)
+ {
+ TCU_FAIL("Image::uploadFromRaw usage error: this function is not going to change Image layout!");
+ }
+
+ de::SharedPtr<Image> stagingResource;
+ vk::VkExtent3D extent = {width, height, depth};
+ ImageCreateInfo stagingResourceCreateInfo(
+ type, m_format, extent, 1, 1, 1,
+ vk::VK_IMAGE_TILING_LINEAR, vk::VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT);
+
+ stagingResource = Image::CreateAndAlloc(m_vk, m_device, stagingResourceCreateInfo, allocator,
+ vk::MemoryRequirement::HostVisible);
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ stagingResource->uploadLinear(zeroOffset, width, height, depth, 0, 0, aspect, data);
+
+ {
+ #pragma message("Get queue family index")
+ CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
+ vk::Unique<vk::VkCmdPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, ©CmdPoolCreateInfo));
+
+ CmdBufferCreateInfo copyCmdBufCreateInfo(*copyCmdPool, vk::VK_CMD_BUFFER_LEVEL_PRIMARY, 0);
+ vk::Unique<vk::VkCmdBuffer> copyCmdBuffer(vk::createCommandBuffer(m_vk, m_device, ©CmdBufCreateInfo));
+
+ CmdBufferBeginInfo beginInfo;
+ VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
+
+ if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
+ {
+ layout = vk::VK_IMAGE_LAYOUT_GENERAL;
+
+ vk::VkImageMemoryBarrier barrier;
+ barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.pNext = DE_NULL;
+ barrier.outputMask = 0;
+ barrier.inputMask = 0;
+ barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
+ barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
+ barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
+ barrier.destQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = object();
+
+ vk::VkImageAspectFlags aspectMask = 0;
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
+ }
+
+ barrier.subresourceRange.aspectMask = aspectMask;
+ barrier.subresourceRange.baseMipLevel = 0;
+ barrier.subresourceRange.mipLevels = m_mipLevels;
+ barrier.subresourceRange.baseArrayLayer = 0;
+ barrier.subresourceRange.arraySize = m_arraySize;
+
+ void* barriers[] = { &barrier };
+
+ m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, DE_LENGTH_OF_ARRAY(barriers), barriers);
+ }
+
+ vk::VkImageAspectFlags aspectMask = 0;
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
+ }
+
+ transition2DImage(m_vk, *copyCmdBuffer, stagingResource->object(), aspectMask, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL);
+
+ vk::VkImageCopy region = {{aspect, 0, 0, 1},
+ zeroOffset,
+ {aspect, mipLevel, arrayElement, 1},
+ offset,
+ {width, height, depth}};
+
+ m_vk.cmdCopyImage(*copyCmdBuffer, stagingResource->object(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, object(), layout, 1, ®ion);
+ VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
+
+ VK_CHECK(m_vk.queueSubmit(queue, 1, ©CmdBuffer.get(), DE_NULL));
+
+ // TODO: make this less intrusive
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+ }
+}
+
+void Image::uploadUsingBuffer (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ const void * data)
+{
+ if (layout != vk::VK_IMAGE_LAYOUT_UNDEFINED
+ && layout != vk::VK_IMAGE_LAYOUT_GENERAL
+ && layout != vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL)
+ {
+ TCU_FAIL("Image::uploadFromRaw usage error: this function is not going to change Image layout!");
+ }
+
+ de::SharedPtr<Buffer> stagingResource;
+ bool isCombinedType = isCombinedDepthStencilType(vk::mapVkFormat(m_format).type);
+ vk::VkDeviceSize bufferSize = 0;
+ if (!isCombinedType)
+ bufferSize = vk::mapVkFormat(m_format).getPixelSize() *width*height*depth;
+ if (isCombinedType)
+ {
+ int pixelSize = 0;
+ switch (m_format)
+ {
+ case vk::VK_FORMAT_D16_UNORM_S8_UINT:
+ pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH) ? 2 : 1;
+ break;
+ case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
+ pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH) ? 4 : 1;
+ break;
+ case vk::VK_FORMAT_D24_UNORM_X8:
+ case vk::VK_FORMAT_D24_UNORM_S8_UINT:
+ pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH) ? 3 : 1;
+ break;
+ }
+ bufferSize = pixelSize*width*height*depth;
+ }
+ BufferCreateInfo stagingBufferResourceCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT | vk::VK_BUFFER_USAGE_TRANSFER_SOURCE_BIT);
+ stagingResource = Buffer::CreateAndAlloc(m_vk, m_device, stagingBufferResourceCreateInfo, allocator, vk::MemoryRequirement::HostVisible);
+ char* destPtr = reinterpret_cast<char*>(stagingResource->getBoundMemory().getHostPtr());
+ deMemcpy(destPtr, data, bufferSize);
+ vk::flushMappedMemoryRange(m_vk, m_device, stagingResource->getBoundMemory().getMemory(), stagingResource->getBoundMemory().getOffset(), bufferSize);
+ {
+ #pragma message("Get queue family index")
+ CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
+ vk::Unique<vk::VkCmdPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, ©CmdPoolCreateInfo));
+
+ CmdBufferCreateInfo copyCmdBufCreateInfo(*copyCmdPool, vk::VK_CMD_BUFFER_LEVEL_PRIMARY, 0);
+ vk::Unique<vk::VkCmdBuffer> copyCmdBuffer(vk::createCommandBuffer(m_vk, m_device, ©CmdBufCreateInfo));
+
+ CmdBufferBeginInfo beginInfo;
+ VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
+
+ if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
+ {
+ layout = vk::VK_IMAGE_LAYOUT_GENERAL;
+
+ vk::VkImageMemoryBarrier barrier;
+ barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.pNext = DE_NULL;
+ barrier.outputMask = 0;
+ barrier.inputMask = 0;
+ barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
+ barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
+ barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
+ barrier.destQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = object();
+
+ vk::VkImageAspectFlags aspectMask = 0;
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
+ }
+
+ barrier.subresourceRange.aspectMask = aspectMask;
+ barrier.subresourceRange.baseMipLevel = 0;
+ barrier.subresourceRange.mipLevels = m_mipLevels;
+ barrier.subresourceRange.baseArrayLayer = 0;
+ barrier.subresourceRange.arraySize = m_arraySize;
+
+ void* barriers[] = { &barrier };
+
+ m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, DE_LENGTH_OF_ARRAY(barriers), barriers);
+ }
+
+ vk::VkImageAspectFlags aspectMask = 0;
+ if (aspect == vk::VK_IMAGE_ASPECT_COLOR)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_DEPTH)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
+ }
+ if (aspect == vk::VK_IMAGE_ASPECT_STENCIL)
+ {
+ aspectMask |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
+ }
+
+ vk::VkBufferImageCopy region = {
+ 0, 0, 0,
+ { aspect, mipLevel, arrayElement, 1 },
+ offset,
+ { width, height, depth }
+ };
+
+ m_vk.cmdCopyBufferToImage(*copyCmdBuffer, stagingResource->object(),
+ object(), layout, 1, ®ion);
+ VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
+
+ VK_CHECK(m_vk.queueSubmit(queue, 1, ©CmdBuffer.get(), DE_NULL));
+
+ // TODO: make this less intrusive
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+ }
+}
+
+
+void Image::uploadLinear (vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ const void * data)
+{
+ vk::VkSubresourceLayout imageLayout;
+
+ vk::VkImageSubresource imageSubResource = {aspect, mipLevel, arrayElement};
+
+ VK_CHECK(m_vk.getImageSubresourceLayout(m_device, object(), &imageSubResource,
+ &imageLayout));
+
+ char* destPtr = reinterpret_cast<char*>(getBoundMemory().getHostPtr());
+
+ destPtr += imageLayout.offset + getPixelOffset(offset, imageLayout.rowPitch, imageLayout.depthPitch, mipLevel, arrayElement);
+
+ MemoryOp::pack(vk::mapVkFormat(m_format).getPixelSize(), width, height, depth,
+ imageLayout.rowPitch, imageLayout.depthPitch, data, destPtr);
+}
+
+vk::VkDeviceSize Image::getPixelOffset (vk::VkOffset3D offset,
+ vk::VkDeviceSize rowPitch,
+ vk::VkDeviceSize depthPitch,
+ unsigned int mipLevel,
+ unsigned int arrayElement)
+{
+ if (mipLevel >= m_mipLevels)
+ TCU_FAIL("mip level too large");
+
+ if (arrayElement >= m_arraySize)
+ TCU_FAIL("array element too large");
+
+ vk::VkDeviceSize mipLevelSizes[32];
+ vk::VkDeviceSize mipLevelRectSizes[32];
+ tcu::IVec3 mipExtend
+ = tcu::IVec3(m_extent.width, m_extent.height, m_extent.depth);
+
+ vk::VkDeviceSize arrayElemSize = 0;
+ for (unsigned int i = 0; i < m_mipLevels && (mipExtend[0] > 1 || mipExtend[1] > 1 || mipExtend[2] > 1); ++i)
+ {
+ // Rect size is just a 3D image size;
+ mipLevelSizes[i] = mipExtend[2] * depthPitch;
+
+ arrayElemSize += mipLevelSizes[0];
+
+ mipExtend = tcu::max(mipExtend / 2, tcu::IVec3(1));
+ }
+
+ vk::VkDeviceSize pixelOffset = arrayElement * arrayElemSize;
+ for (size_t i = 0; i < mipLevel; ++i) {
+ pixelOffset += mipLevelSizes[i];
+ }
+ pixelOffset += offset.z * mipLevelRectSizes[mipLevel];
+ pixelOffset += offset.y * rowPitch;
+ pixelOffset += offset.x;
+
+ return pixelOffset;
+}
+
+void Image::bindMemory (de::MovePtr<vk::Allocation> allocation)
+{
+ if (allocation)
+ {
+ VK_CHECK(m_vk.bindImageMemory(m_device, *m_object, allocation->getMemory(), allocation->getOffset()));
+ }
+ else
+ {
+ VK_CHECK(m_vk.bindImageMemory(m_device, *m_object, DE_NULL, 0));
+ }
+ m_allocation = allocation;
+}
+
+de::SharedPtr<Image> Image::CreateAndAlloc(const vk::DeviceInterface &vk,
+ vk::VkDevice device,
+ const vk::VkImageCreateInfo &createInfo,
+ vk::Allocator &allocator,
+ vk::MemoryRequirement memoryRequirement)
+{
+ de::SharedPtr<Image> ret = Create(vk, device, createInfo);
+
+ vk::VkMemoryRequirements imageRequirements = vk::getImageMemoryRequirements(vk, device, ret->object());
+ ret->bindMemory(allocator.allocate(imageRequirements, memoryRequirement));
+ return ret;
+}
+
+de::SharedPtr<Image> Image::Create(const vk::DeviceInterface &vk,
+ vk::VkDevice device,
+ const vk::VkImageCreateInfo &createInfo)
+{
+ return de::SharedPtr<Image>(new Image(vk, device, createInfo.format, createInfo.extent,
+ createInfo.mipLevels, createInfo.arraySize,
+ vk::createImage(vk, device, &createInfo)));
+}
+
+void transition2DImage (const vk::DeviceInterface &vk,
+ vk::VkCmdBuffer cmdBuffer,
+ vk::VkImage image,
+ vk::VkImageAspectFlags aspectMask,
+ vk::VkImageLayout oldLayout,
+ vk::VkImageLayout newLayout)
+{
+ vk::VkImageMemoryBarrier barrier;
+ barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.pNext = DE_NULL;
+ barrier.outputMask = 0;
+ barrier.inputMask = 0;
+ barrier.oldLayout = oldLayout;
+ barrier.newLayout = newLayout;
+ barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
+ barrier.destQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = image;
+ barrier.subresourceRange.aspectMask = aspectMask;
+ barrier.subresourceRange.baseMipLevel = 0;
+ barrier.subresourceRange.mipLevels = 1;
+ barrier.subresourceRange.baseArrayLayer = 0;
+ barrier.subresourceRange.arraySize = 1;
+
+ void* barriers[] = { &barrier };
+
+ vk.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, DE_LENGTH_OF_ARRAY(barriers), barriers);
+}
+
+
+void initialTransitionColor2DImage (const vk::DeviceInterface &vk, vk::VkCmdBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
+{
+ transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_COLOR_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
+}
+
+void initialTransitionDepth2DImage (const vk::DeviceInterface &vk, vk::VkCmdBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
+{
+ transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
+}
+
+void initialTransitionStencil2DImage (const vk::DeviceInterface &vk, vk::VkCmdBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
+{
+ transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
+}
+
+void initialTransitionDepthStencil2DImage (const vk::DeviceInterface &vk, vk::VkCmdBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
+{
+ transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
+}
+
+} //DynamicState
+} //vkt
--- /dev/null
+#ifndef _VKT_DYNAMIC_STATE_IMAGEOBJECTUTIL_HPP
+#define _VKT_DYNAMIC_STATE_IMAGEOBJECTUTIL_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Image Object Util
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+#include "vkMemUtil.hpp"
+#include "vkRefUtil.hpp"
+
+#include "deSharedPtr.hpp"
+
+#include "tcuTexture.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+class MemoryOp
+{
+public:
+ static void pack (int pixelSize,
+ int width,
+ int height,
+ int depth,
+ vk::VkDeviceSize rowPitch,
+ vk::VkDeviceSize depthPitch,
+ const void * srcBuffer,
+ void * destBuffer);
+
+ static void unpack (int pixelSize,
+ int width,
+ int height,
+ int depth,
+ vk::VkDeviceSize rowPitch,
+ vk::VkDeviceSize depthPitch,
+ const void * srcBuffer,
+ void * destBuffer);
+};
+
+
+class Image
+{
+public:
+ static de::SharedPtr<Image> Create (const vk::DeviceInterface &vk, vk::VkDevice device, const vk::VkImageCreateInfo &createInfo);
+
+ static de::SharedPtr<Image> CreateAndAlloc (const vk::DeviceInterface &vk,
+ vk::VkDevice device,
+ const vk::VkImageCreateInfo &createInfo,
+ vk::Allocator &allocator,
+ vk::MemoryRequirement memoryRequirement = vk::MemoryRequirement::Any);
+
+ tcu::ConstPixelBufferAccess readSurface (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel = 0,
+ unsigned int arrayElement = 0);
+
+ tcu::ConstPixelBufferAccess readSurface1D (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel = 0,
+ unsigned int arrayElement = 0);
+
+ tcu::ConstPixelBufferAccess readVolume (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel = 0,
+ unsigned int arrayElement = 0);
+
+
+ tcu::ConstPixelBufferAccess readSurfaceLinear (vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel = 0,
+ unsigned int arrayElement = 0);
+
+ void read (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ vk::VkImageType type,
+ void * data);
+
+ void readUsingBuffer (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ void * data);
+
+ void readLinear (vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ void * data);
+
+ void uploadVolume (const tcu::ConstPixelBufferAccess &access,
+ vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel = 0,
+ unsigned int arrayElement = 0);
+
+ void uploadSurface (const tcu::ConstPixelBufferAccess &access,
+ vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel = 0,
+ unsigned int arrayElement = 0);
+
+ void uploadSurface1D (const tcu::ConstPixelBufferAccess &access,
+ vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel = 0,
+ unsigned int arrayElement = 0);
+
+ void uploadSurfaceLinear (const tcu::ConstPixelBufferAccess &access,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ vk::VkImageAspect aspect,
+ unsigned int mipLevel = 0,
+ unsigned int arrayElement = 0);
+
+ void upload (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ vk::VkImageType type,
+ const void * data);
+
+ void uploadUsingBuffer (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ const void * data);
+
+ void uploadLinear (vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ const void * data);
+
+ de::SharedPtr<Image> copyToLinearImage (vk::VkQueue queue,
+ vk::Allocator &allocator,
+ vk::VkImageLayout layout,
+ vk::VkOffset3D offset,
+ int width,
+ int height,
+ int depth,
+ unsigned int mipLevel,
+ unsigned int arrayElement,
+ vk::VkImageAspect aspect,
+ vk::VkImageType type);
+
+ inline const vk::VkFormat & getFormat (void) const
+ {
+ return m_format;
+ }
+
+ inline vk::VkImage object (void) const { return *m_object; }
+
+ void bindMemory (de::MovePtr<vk::Allocation> allocation);
+
+ inline vk::Allocation getBoundMemory (void) const { return *m_allocation; }
+
+private:
+ vk::VkDeviceSize getPixelOffset (vk::VkOffset3D offset,
+ vk::VkDeviceSize rowPitch,
+ vk::VkDeviceSize depthPitch,
+ unsigned int mipLevel,
+ unsigned int arrayElement);
+
+ Image (const vk::DeviceInterface &vk,
+ vk::VkDevice device,
+ vk::VkFormat format,
+ const vk::VkExtent3D &extend,
+ deUint32 mipLevels,
+ deUint32 arraySize,
+ vk::Move<vk::VkImage> object);
+
+ Image (const Image &other); // Not allowed!
+ Image &operator= (const Image &other); // Not allowed!
+
+ de::MovePtr<vk::Allocation> m_allocation;
+ vk::Unique<vk::VkImage> m_object;
+
+ vk::VkFormat m_format;
+ vk::VkExtent3D m_extent;
+ deUint32 m_mipLevels;
+ deUint32 m_arraySize;
+
+ std::vector<deUint8> m_pixelAccessData;
+
+ const vk::DeviceInterface &m_vk;
+ vk::VkDevice m_device;
+};
+
+void transition2DImage (const vk::DeviceInterface &vk, vk::VkCmdBuffer cmdBuffer, vk::VkImage image, vk::VkImageAspectFlags aspectMask, vk::VkImageLayout oldLayout, vk::VkImageLayout newLayout);
+
+void initialTransitionColor2DImage (const vk::DeviceInterface &vk, vk::VkCmdBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout);
+
+void initialTransitionDepth2DImage (const vk::DeviceInterface &vk, vk::VkCmdBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout);
+
+void initialTransitionStencil2DImage (const vk::DeviceInterface &vk, vk::VkCmdBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout);
+
+void initialTransitionDepthStencil2DImage (const vk::DeviceInterface &vk, vk::VkCmdBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout);
+
+} //DynamicState
+} //vkt
+
+#endif // _VKT_DYNAMIC_STATE_IMAGEOBJECTUTIL_HPP
--- /dev/null
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic Raster State Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDynamicStateRSTests.hpp"
+#include "vktDynamicStateBaseClass.hpp"
+
+#include "vktDynamicStateTestCaseUtil.hpp"
+#include "tcuTextureUtil.hpp"
+
+#include "deMath.h"
+
+namespace vkt
+{
+namespace DynamicState
+{
+namespace
+{
+
+class DepthBiasBaseCase : public TestInstance
+{
+public:
+ DepthBiasBaseCase (Context &context, const char* vertexShaderName, const char* fragmentShaderName)
+ : TestInstance (context)
+ , m_colorAttachmentFormat (vk::VK_FORMAT_R8G8B8A8_UNORM)
+ , m_depthStencilAttachmentFormat (vk::VK_FORMAT_D24_UNORM_S8_UINT)
+ , m_topology (vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
+ , m_vertexShaderName (vertexShaderName)
+ , m_fragmentShaderName (fragmentShaderName)
+ , m_vk (context.getDeviceInterface())
+ {
+ }
+
+protected:
+
+ enum
+ {
+ WIDTH = 128,
+ HEIGHT = 128
+ };
+
+ vk::VkFormat m_colorAttachmentFormat;
+ vk::VkFormat m_depthStencilAttachmentFormat;
+
+ vk::VkPrimitiveTopology m_topology;
+
+ const vk::DeviceInterface& m_vk;
+
+ vk::Move<vk::VkPipeline> m_pipeline;
+ vk::Move<vk::VkPipelineLayout> m_pipelineLayout;
+
+ de::SharedPtr<Image> m_colorTargetImage;
+ vk::Move<vk::VkImageView> m_colorTargetView;
+
+ de::SharedPtr<Image> m_depthStencilImage;
+ vk::Move<vk::VkImageView> m_attachmentView;
+
+ PipelineCreateInfo::VertexInputState m_vertexInputState;
+ de::SharedPtr<Buffer> m_vertexBuffer;
+
+ vk::Move<vk::VkCmdPool> m_cmdPool;
+ vk::Move<vk::VkCmdBuffer> m_cmdBuffer;
+
+ vk::Move<vk::VkFramebuffer> m_framebuffer;
+ vk::Move<vk::VkRenderPass> m_renderPass;
+
+ std::string m_vertexShaderName;
+ std::string m_fragmentShaderName;
+
+ std::vector<Vec4RGBA> m_data;
+
+ PipelineCreateInfo::DepthStencilState m_depthStencilState;
+
+ void initialize (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkDevice device = m_context.getDevice();
+
+ const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
+ m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
+
+ const vk::Unique<vk::VkShader> vs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_VERTEX));
+
+ const vk::Unique<vk::VkShader> fs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_FRAGMENT));
+
+ const vk::VkExtent3D imageExtent = { WIDTH, HEIGHT, 1 };
+ ImageCreateInfo targetImageCreateInfo(
+ vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, 1, vk::VK_IMAGE_TILING_OPTIMAL,
+ vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT);
+
+ m_colorTargetImage = Image::CreateAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator());
+
+ const ImageCreateInfo depthStencilImageCreateInfo(
+ vk::VK_IMAGE_TYPE_2D, m_depthStencilAttachmentFormat, imageExtent,
+ 1, 1, 1, vk::VK_IMAGE_TILING_OPTIMAL,
+ vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
+
+ m_depthStencilImage = Image::CreateAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator());
+
+ const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
+ m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
+
+ const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthStencilAttachmentFormat);
+ m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo);
+
+ RenderPassCreateInfo renderPassCreateInfo;
+ renderPassCreateInfo.addAttachment(AttachmentDescription(
+ m_colorAttachmentFormat,
+ 1,
+ vk::VK_ATTACHMENT_LOAD_OP_LOAD,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_IMAGE_LAYOUT_GENERAL,
+ vk::VK_IMAGE_LAYOUT_GENERAL));
+
+ renderPassCreateInfo.addAttachment(AttachmentDescription(
+ m_depthStencilAttachmentFormat,
+ 1,
+ vk::VK_ATTACHMENT_LOAD_OP_LOAD,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+ vk::VK_ATTACHMENT_STORE_OP_STORE,
+ vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+ vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
+
+ const vk::VkAttachmentReference colorAttachmentReference =
+ {
+ 0,
+ vk::VK_IMAGE_LAYOUT_GENERAL
+ };
+
+ const vk::VkAttachmentReference depthAttachmentReference =
+ {
+ 1,
+ vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
+ };
+
+ renderPassCreateInfo.addSubpass(SubpassDescription(
+ vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
+ vk::VK_SUBPASS_DESCRIPTION_NO_OVERDRAW_BIT,
+ 0,
+ DE_NULL,
+ 1,
+ &colorAttachmentReference,
+ DE_NULL,
+ depthAttachmentReference,
+ 0,
+ DE_NULL));
+
+ m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
+
+ const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
+ {
+ 0,
+ sizeof(tcu::Vec4) * 2,
+ vk::VK_VERTEX_INPUT_STEP_RATE_VERTEX,
+ };
+
+ const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
+ {
+ {
+ 0u,
+ 0u,
+ vk::VK_FORMAT_R32G32B32A32_SFLOAT,
+ 0u
+ },
+ {
+ 1u,
+ 0u,
+ vk::VK_FORMAT_R32G32B32A32_SFLOAT,
+ (deUint32)(sizeof(float)* 4),
+ }
+ };
+
+ m_vertexInputState = PipelineCreateInfo::VertexInputState(
+ 1,
+ &vertexInputBindingDescription,
+ 2,
+ vertexInputAttributeDescriptions);
+
+ const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
+
+ PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
+ pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, vk::VK_SHADER_STAGE_VERTEX));
+ pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, vk::VK_SHADER_STAGE_FRAGMENT));
+ pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
+ pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
+ pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
+ pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1));
+ pipelineCreateInfo.addState(m_depthStencilState);
+ pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState());
+
+ m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
+
+ std::vector<vk::VkImageView> attachments(2);
+ attachments[0] = *m_colorTargetView;
+ attachments[1] = *m_attachmentView;
+
+ const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
+
+ m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
+
+ const vk::VkDeviceSize dataSize = m_data.size() * sizeof(Vec4RGBA);
+ m_vertexBuffer = Buffer::CreateAndAlloc(m_vk, device, BufferCreateInfo(dataSize,
+ vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
+ m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
+
+ unsigned char *ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
+ deMemcpy(ptr, &m_data[0], dataSize);
+
+ vk::flushMappedMemoryRange(m_vk, device,
+ m_vertexBuffer->getBoundMemory().getMemory(),
+ m_vertexBuffer->getBoundMemory().getOffset(),
+ sizeof(dataSize));
+
+ const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
+ m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
+
+ const CmdBufferCreateInfo cmdBufCreateInfo(*m_cmdPool, vk::VK_CMD_BUFFER_LEVEL_PRIMARY, 0);
+ m_cmdBuffer = vk::createCommandBuffer(m_vk, device, &cmdBufCreateInfo);
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ TCU_FAIL("Implement iterate() method!");
+ }
+
+ void beginRenderPass (void)
+ {
+ const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
+ beginRenderPassWithClearColor(clearColor);
+ }
+
+ void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor)
+ {
+ const CmdBufferBeginInfo beginInfo;
+ m_vk.beginCommandBuffer(*m_cmdBuffer, &beginInfo);
+
+ initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL);
+ initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL);
+
+ const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT);
+ m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRangeImage);
+
+ const vk::VkClearDepthStencilValue depthStencilClearValue = { 0.0f, 0 };
+
+ const ImageSubresourceRange subresourceRangeDepthStencil[2] = { vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_ASPECT_STENCIL_BIT };
+ m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(),
+ vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, &depthStencilClearValue, 2, subresourceRangeDepthStencil);
+
+ const vk::VkRect2D renderArea = { { 0, 0 }, { WIDTH, HEIGHT } };
+ const RenderPassBeginInfo renderPassBegin(*m_renderPass, *m_framebuffer, renderArea);
+
+ m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBegin, vk::VK_RENDER_PASS_CONTENTS_INLINE);
+ }
+
+ void setDynamicViewportState (const deUint32 width, const deUint32 height)
+ {
+ vk::VkViewport viewport;
+ viewport.originX = 0;
+ viewport.originY = 0;
+ viewport.width = static_cast<float>(width);
+ viewport.height = static_cast<float>(height);
+ viewport.minDepth = 0.0f;
+ viewport.maxDepth = 1.0f;
+
+ m_vk.cmdSetViewport(*m_cmdBuffer, 1, &viewport);
+
+ vk::VkRect2D scissor;
+ scissor.offset.x = 0;
+ scissor.offset.y = 0;
+ scissor.extent.width = width;
+ scissor.extent.height = height;
+ m_vk.cmdSetScissor(*m_cmdBuffer, 1, &scissor);
+ }
+
+ void setDynamicViewportState (const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
+ {
+ m_vk.cmdSetViewport(*m_cmdBuffer, viewportCount, pViewports);
+ m_vk.cmdSetScissor(*m_cmdBuffer, viewportCount, pScissors);
+ }
+
+ void setDynamicRasterState (const float lineWidth = 1.0f,
+ const float depthBias = 0.0f,
+ const float depthBiasClamp = 0.0f,
+ const float slopeScaledDepthBias = 0.0f)
+ {
+ m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
+ m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBias, depthBiasClamp, slopeScaledDepthBias);
+ }
+
+ void setDynamicBlendState (const float const1 = 0.0f, const float const2 = 0.0f,
+ const float const3 = 0.0f, const float const4 = 0.0f)
+ {
+ float blendConstants[4] = { const1, const2, const3, const4 };
+ m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstants);
+ }
+
+ void setDynamicDepthStencilState (const float minDepthBounds = -1.0f, const float maxDepthBounds = 1.0f,
+ const deUint32 stencilFrontCompareMask = 0xffffffffu, const deUint32 stencilFrontWriteMask = 0xffffffffu,
+ const deUint32 stencilFrontReference = 0, const deUint32 stencilBackCompareMask = 0xffffffffu,
+ const deUint32 stencilBackWriteMask = 0xffffffffu, const deUint32 stencilBackReference = 0)
+ {
+ m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
+ m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
+ m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
+ m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
+ m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
+ m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
+ m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
+ }
+};
+
+class DepthBiasParamTestInstance : public DepthBiasBaseCase
+{
+public:
+ DepthBiasParamTestInstance (Context &context, ShaderMap shaders)
+ : DepthBiasBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ {
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), vec4Blue()));
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), vec4Green()));
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), vec4Red()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), vec4Red()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), vec4Red()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), vec4Red()));
+
+ // enable depth test
+ m_depthStencilState = PipelineCreateInfo::DepthStencilState(
+ vk::VK_TRUE, vk::VK_TRUE, vk::VK_COMPARE_OP_GREATER_EQUAL);
+
+ DepthBiasBaseCase::initialize();
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ // set states here
+ setDynamicViewportState(WIDTH, HEIGHT);
+ setDynamicBlendState();
+ setDynamicDepthStencilState();
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ setDynamicRasterState(1.0f, 0.0f);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
+
+ setDynamicRasterState(1.0f, -1.0f);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+
+ // validation
+ {
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
+ else
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
+ }
+ }
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT))
+ {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+ }
+};
+
+class DepthBiasClampParamTestInstance : public DepthBiasBaseCase
+{
+public:
+ DepthBiasClampParamTestInstance (Context &context, ShaderMap shaders)
+ : DepthBiasBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ {
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), vec4Blue()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f), vec4Blue()));
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-0.5f, 0.5f, 0.01f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.5f, 0.5f, 0.01f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-0.5f, -0.5f, 0.01f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.5f, -0.5f, 0.01f, 1.0f), vec4Green()));
+
+ // enable depth test
+ m_depthStencilState = PipelineCreateInfo::DepthStencilState(
+ vk::VK_TRUE, vk::VK_TRUE, vk::VK_COMPARE_OP_GREATER_EQUAL);
+
+ DepthBiasBaseCase::initialize();
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ // set states here
+ setDynamicViewportState(WIDTH, HEIGHT);
+ setDynamicBlendState();
+ setDynamicDepthStencilState();
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ setDynamicRasterState(1.0f, 1000.0f, 0.005f);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
+
+ setDynamicRasterState(1.0f, 0.0f);
+ m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+
+ // validation
+ {
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
+ else
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
+ }
+ }
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT))
+ {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+ }
+};
+
+class LineWidthParamTestInstance : public DynamicStateBaseClass
+{
+public:
+ LineWidthParamTestInstance (Context &context, ShaderMap shaders)
+ : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ {
+ m_topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), vec4Green()));
+
+ DynamicStateBaseClass::initialize();
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ // set states here
+ vk::VkPhysicalDeviceProperties deviceProperties;
+ m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
+
+ setDynamicViewportState(WIDTH, HEIGHT);
+ setDynamicBlendState();
+ setDynamicDepthStencilState();
+ setDynamicRasterState(floor(deviceProperties.limits.lineWidthRange[1]));
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+
+ // validation
+ {
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+ float lineHalfWidth = (1.0f / (float)deFloor(deviceProperties.limits.lineWidthRange[1])) * 0.5f;
+
+ if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -lineHalfWidth && yCoord <= lineHalfWidth)
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
+ }
+ }
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT))
+ {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+ }
+};
+
+} //anonymous
+
+DynamicStateRSTests::DynamicStateRSTests (tcu::TestContext &testCtx)
+ : TestCaseGroup (testCtx, "rs_state", "Tests for rasterizer state")
+{
+ /* Left blank on purpose */
+}
+
+DynamicStateRSTests::~DynamicStateRSTests () {}
+
+void DynamicStateRSTests::init (void)
+{
+ ShaderMap shaderPaths;
+ shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
+ shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
+
+ addChild(new InstanceFactory<DepthBiasParamTestInstance>(m_testCtx, "depth_bias", "Test depth bias functionality", shaderPaths));
+ addChild(new InstanceFactory<DepthBiasClampParamTestInstance>(m_testCtx, "depth_bias_clamp", "Test depth bias clamp functionality", shaderPaths));
+ addChild(new InstanceFactory<LineWidthParamTestInstance>(m_testCtx, "line_width", "Draw a line with width set to max defined by physical device", shaderPaths));
+}
+
+} //DynamicState
+} //vkt
--- /dev/null
+#ifndef _VKTDYNAMICSTATERSTESTS_HPP
+#define _VKTDYNAMICSTATERSTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic Raster State Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+class DynamicStateRSTests : public tcu::TestCaseGroup
+{
+public:
+ DynamicStateRSTests (tcu::TestContext &testCtx);
+ ~DynamicStateRSTests (void);
+ void init(void);
+
+private:
+ DynamicStateRSTests (const DynamicStateRSTests &other);
+ DynamicStateRSTests &operator=(const DynamicStateRSTests &other);
+};
+
+} //DynamicState
+} //vkt
+
+
+#endif // _VKTDYNAMICSTATERSTESTS_HPP
--- /dev/null
+#ifndef _VKTDYNAMICSTATETESTCASEUTIL_HPP
+#define _VKTDYNAMICSTATETESTCASEUTIL_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic State Tests Test Case Utilities
+ *//*--------------------------------------------------------------------*/
+
+
+#include "tcuDefs.hpp"
+#include "tcuResource.hpp"
+
+#include "vktTestCase.hpp"
+
+#include "gluShaderUtil.hpp"
+#include "vkPrograms.hpp"
+
+#include <map>
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+class ShaderSourceProvider
+{
+public:
+ static std::string getSource(tcu::Archive& archive, const char* path)
+ {
+ tcu::Resource *resource = archive.getResource(path);
+
+ std::vector<deUint8> readBuffer(resource->getSize() + 1);
+ resource->read(&readBuffer[0], resource->getSize());
+ readBuffer[readBuffer.size() - 1] = 0;
+
+ return reinterpret_cast<const char*>(&readBuffer[0]);
+ }
+};
+
+typedef std::map<glu::ShaderType, const char*> ShaderMap;
+
+template<typename Instance>
+class InstanceFactory : public TestCase
+{
+public:
+ InstanceFactory (tcu::TestContext& testCtx, const std::string& name, const std::string& desc,
+ const std::map<glu::ShaderType, const char*> shaderPaths)
+ : TestCase (testCtx, name, desc)
+ , m_shaderPaths (shaderPaths)
+ {
+ }
+
+ TestInstance* createInstance (Context& context) const
+ {
+ return new Instance(context, m_shaderPaths);
+ }
+
+ virtual void initPrograms (vk::SourceCollections& programCollection) const
+ {
+ for (ShaderMap::const_iterator i = m_shaderPaths.begin(); i != m_shaderPaths.end(); ++i)
+ {
+ programCollection.glslSources.add(i->second) <<
+ glu::ShaderSource(i->first, ShaderSourceProvider::getSource(m_testCtx.getArchive(), i->second));
+ }
+ }
+
+private:
+ const ShaderMap m_shaderPaths;
+};
+
+
+} //DynamicState
+} //vkt
+
+#endif
\ No newline at end of file
--- /dev/null
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic State Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDynamicStateTests.hpp"
+
+#include "vktDynamicStateVPTests.hpp"
+#include "vktDynamicStateRSTests.hpp"
+#include "vktDynamicStateCBTests.hpp"
+#include "vktDynamicStateDSTests.hpp"
+#include "vktDynamicStateGeneralTests.hpp"
+
+#include "deUniquePtr.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "dynamic-state", "Dynamic State Tests"));
+
+ group->addChild(new DynamicStateVPTests(testCtx));
+ group->addChild(new DynamicStateRSTests(testCtx));
+ group->addChild(new DynamicStateCBTests(testCtx));
+ group->addChild(new DynamicStateDSTests(testCtx));
+ group->addChild(new DynamicStateGeneralTests(testCtx));
+
+ return group.release();
+}
+
+} // DynamicState
+} // vkt
\ No newline at end of file
--- /dev/null
+#ifndef _VKTDYNAMICSTATETESTS_HPP
+#define _VKTDYNAMICSTATETESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic State Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx);
+
+} //DynamicState
+} //vkt
+
+#endif // _VKTDYNAMICSTATETESTS_HPP
--- /dev/null
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic State Viewport Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDynamicStateVPTests.hpp"
+#include "vktDynamicStateBaseClass.hpp"
+
+#include "vktDynamicStateTestCaseUtil.hpp"
+#include "tcuTextureUtil.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+namespace
+{
+
+class ViewportStateBaseCase : public DynamicStateBaseClass
+{
+public:
+ ViewportStateBaseCase (Context &context, const char* vertexShaderName, const char* fragmentShaderName)
+ : DynamicStateBaseClass (context, vertexShaderName, fragmentShaderName)
+ {}
+
+ void initialize(void)
+ {
+ m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), vec4Green()));
+
+ DynamicStateBaseClass::initialize();
+ }
+
+ virtual tcu::Texture2D buildReferenceFrame (void)
+ {
+ TCU_FAIL("Implement buildReferenceFrame() method and return valid surface!");
+ }
+
+ virtual void setDynamicStates (void)
+ {
+ TCU_FAIL("Implement setDynamicStates() method!");
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkDevice device = m_context.getDevice();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ // set states here
+ setDynamicStates();
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+
+ // validation
+ {
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ tcu::Texture2D referenceFrame = buildReferenceFrame();
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT))
+ {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+ }
+};
+
+class ViewportParamTestInstane : public ViewportStateBaseCase
+{
+public:
+ ViewportParamTestInstane (Context &context, ShaderMap shaders)
+ : ViewportStateBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ {
+ ViewportStateBaseCase::initialize();
+ }
+
+ virtual void setDynamicStates(void)
+ {
+ const vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH * 2, (float)HEIGHT * 2, 0.0f, 0.0f };
+ const vk::VkRect2D scissor = { { 0, 0 }, { WIDTH, HEIGHT } };
+
+ setDynamicViewportState(1, &viewport, &scissor);
+ setDynamicRasterState();
+ setDynamicBlendState();
+ setDynamicDepthStencilState();
+ }
+
+ virtual tcu::Texture2D buildReferenceFrame (void)
+ {
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if (xCoord >= 0.0f && xCoord <= 1.0f && yCoord >= 0.0f && yCoord <= 1.0f)
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
+ }
+ }
+
+ return referenceFrame;
+ }
+};
+
+class ScissorParamTestInstance : public ViewportStateBaseCase
+{
+public:
+ ScissorParamTestInstance (Context &context, ShaderMap shaders)
+ : ViewportStateBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ {
+ ViewportStateBaseCase::initialize();
+ }
+
+ virtual void setDynamicStates (void)
+ {
+ const vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
+ const vk::VkRect2D scissor = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
+
+ setDynamicViewportState(1, &viewport, &scissor);
+ setDynamicRasterState();
+ setDynamicBlendState();
+ setDynamicDepthStencilState();
+ }
+
+ virtual tcu::Texture2D buildReferenceFrame (void)
+ {
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if (xCoord >= -0.5f && xCoord <= 0.0f && yCoord >= -0.5f && yCoord <= 0.0f)
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
+ }
+ }
+
+ return referenceFrame;
+ }
+};
+
+
+class ViewportArrayTestInstance : public DynamicStateBaseClass
+{
+protected:
+ std::string m_geometryShaderName;
+
+public:
+
+ ViewportArrayTestInstance (Context &context, ShaderMap shaders)
+ : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
+ , m_geometryShaderName (shaders[glu::SHADERTYPE_GEOMETRY])
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, (float)i, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, (float)i, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, (float)i, 1.0f), vec4Green()));
+ m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, (float)i, 1.0f), vec4Green()));
+ }
+
+ DynamicStateBaseClass::initialize();
+ }
+
+ virtual void initPipeline (const vk::VkDevice device)
+ {
+ const vk::Unique<vk::VkShader> vs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_VERTEX));
+
+ const vk::Unique<vk::VkShader> gs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_geometryShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_GEOMETRY));
+
+ const vk::Unique<vk::VkShader> fs(createShader(m_vk, device,
+ *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0),
+ "main", vk::VK_SHADER_STAGE_FRAGMENT));
+
+ const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
+
+ PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
+ pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, vk::VK_SHADER_STAGE_VERTEX));
+ pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*gs, vk::VK_SHADER_STAGE_GEOMETRY));
+ pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, vk::VK_SHADER_STAGE_FRAGMENT));
+ pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
+ pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
+ pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
+ pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(4));
+ pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
+ pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState());
+
+ m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
+ }
+
+ virtual tcu::TestStatus iterate (void)
+ {
+ tcu::TestLog &log = m_context.getTestContext().getLog();
+ const vk::VkQueue queue = m_context.getUniversalQueue();
+
+ beginRenderPass();
+
+ // set states here
+ const float halfWidth = (float)WIDTH / 2;
+ const float halfHeight = (float)HEIGHT / 2;
+ const deInt32 quarterWidth = WIDTH / 4;
+ const deInt32 quarterHeight = HEIGHT / 4;
+
+ const vk::VkViewport viewports[4] =
+ {
+ { 0.0f, 0.0f, (float)halfWidth, (float)halfHeight, 0.0f, 0.0f },
+ { halfWidth, 0.0f, (float)halfWidth, (float)halfHeight, 0.0f, 0.0f },
+ { halfWidth, halfHeight, (float)halfWidth, (float)halfHeight, 0.0f, 0.0f },
+ { 0.0f, halfHeight, (float)halfWidth, (float)halfHeight, 0.0f, 0.0f }
+ };
+
+ const vk::VkRect2D scissors[4] =
+ {
+ { { quarterWidth, quarterHeight }, { quarterWidth, quarterHeight } },
+ { { halfWidth, quarterHeight }, { quarterWidth, quarterHeight } },
+ { { halfWidth, halfHeight }, { quarterWidth, quarterHeight } },
+ { { quarterWidth, halfHeight }, { quarterWidth, quarterHeight } },
+ };
+
+ setDynamicViewportState(4, viewports, scissors);
+ setDynamicRasterState();
+ setDynamicBlendState();
+ setDynamicDepthStencilState();
+
+ m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+ const vk::VkDeviceSize vertexBufferOffset = 0;
+ const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
+ m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
+
+ m_vk.cmdEndRenderPass(*m_cmdBuffer);
+ m_vk.endCommandBuffer(*m_cmdBuffer);
+
+ const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
+ VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
+
+ // validation
+ {
+ VK_CHECK(m_vk.queueWaitIdle(queue));
+
+ tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
+ referenceFrame.allocLevel(0);
+
+ const deInt32 frameWidth = referenceFrame.getWidth();
+ const deInt32 frameHeight = referenceFrame.getHeight();
+
+ tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ for (int y = 0; y < frameHeight; y++)
+ {
+ const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
+
+ for (int x = 0; x < frameWidth; x++)
+ {
+ const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
+
+ if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
+ referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
+ }
+ }
+
+ const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
+ const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
+ vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
+
+ qpTestResult res = QP_TEST_RESULT_PASS;
+
+ if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
+ referenceFrame.getLevel(0), renderedFrame, 0.05f,
+ tcu::COMPARE_LOG_RESULT))
+ {
+ res = QP_TEST_RESULT_FAIL;
+ }
+
+ return tcu::TestStatus(res, qpGetTestResultName(res));
+ }
+ }
+};
+
+} //anonymous
+
+DynamicStateVPTests::DynamicStateVPTests (tcu::TestContext &testCtx)
+ : TestCaseGroup (testCtx, "vp_state", "Tests for viewport state")
+{
+ /* Left blank on purpose */
+}
+
+DynamicStateVPTests::~DynamicStateVPTests () {}
+
+void DynamicStateVPTests::init (void)
+{
+ ShaderMap shaderPaths;
+ shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
+ shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
+
+ addChild(new InstanceFactory<ViewportParamTestInstane>(m_testCtx, "viewport", "Set viewport which is twice bigger than screen size", shaderPaths));
+ addChild(new InstanceFactory<ScissorParamTestInstance>(m_testCtx, "scissor", "Perform a scissor test on 1/4 bottom-left part of the surface", shaderPaths));
+
+ shaderPaths[glu::SHADERTYPE_GEOMETRY] = "vulkan/dynamic_state/ViewportArray.geom";
+ addChild(new InstanceFactory<ViewportArrayTestInstance>(m_testCtx, "viewport_array", "Multiple viewports and scissors", shaderPaths));
+}
+
+} //DynamicState
+} //vkt
--- /dev/null
+#ifndef _VKTDYNAMICSTATEVPTESTS_HPP
+#define _VKTDYNAMICSTATEVPTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Dynamic State Viewport Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace DynamicState
+{
+
+class DynamicStateVPTests : public tcu::TestCaseGroup
+{
+public:
+ DynamicStateVPTests (tcu::TestContext &testCtx);
+ ~DynamicStateVPTests (void);
+ void init (void);
+
+private:
+ DynamicStateVPTests (const DynamicStateVPTests &other);
+ DynamicStateVPTests &operator=(const DynamicStateVPTests &other);
+};
+
+} //DynamicState
+} //vkt
+
+
+#endif // _VKTDYNAMICSTATEVPTESTS_HPP
#include "vktRenderPassTests.hpp"
#include "vktShaderRenderTests.hpp"
#include "vktMemoryTests.hpp"
+#include "vktDynamicStateTests.hpp"
+
#include <vector>
#include <sstream>
addChild(createRenderPassTests (m_testCtx));
addChild(sr::createTests (m_testCtx));
addChild(memory::createTests (m_testCtx));
+ addChild(DynamicState::createTests (m_testCtx));
}
} // vkt