Add Vulkan DrawContext utility class
authorDavid Sodman <dsodman@google.com>
Thu, 1 Sep 2016 17:40:21 +0000 (10:40 -0700)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 31 Aug 2017 18:19:15 +0000 (14:19 -0400)
This is the first in a series of changes to move the DrawContext class
for more general use.

Test: run clipping tests on Vulkan
Affects: dEQP-VK.clipping.*

Change-Id: Ia9b8953d25c10ec2a6c227bf300637dcd62ea898
(cherry picked from commit 9a928cdc2014c830eb8cb43043746f8f2ea6969a)

13 files changed:
Android.mk
external/vulkancts/framework/vulkan/CMakeLists.txt
external/vulkancts/framework/vulkan/vkBufferWithMemory.cpp [new file with mode: 0644]
external/vulkancts/framework/vulkan/vkBufferWithMemory.hpp [new file with mode: 0644]
external/vulkancts/framework/vulkan/vkImageWithMemory.cpp [new file with mode: 0644]
external/vulkancts/framework/vulkan/vkImageWithMemory.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/CMakeLists.txt
external/vulkancts/modules/vulkan/clipping/CMakeLists.txt
external/vulkancts/modules/vulkan/clipping/vktClippingTests.cpp
external/vulkancts/modules/vulkan/clipping/vktClippingUtil.cpp [deleted file]
external/vulkancts/modules/vulkan/clipping/vktClippingUtil.hpp [deleted file]
external/vulkancts/modules/vulkan/vktDrawUtil.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/vktDrawUtil.hpp [new file with mode: 0644]

index f61d22e..97e217e 100644 (file)
@@ -697,6 +697,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/framework/vulkan/vkAllocationCallbackUtil.cpp \
        external/vulkancts/framework/vulkan/vkApiVersion.cpp \
        external/vulkancts/framework/vulkan/vkBinaryRegistry.cpp \
+       external/vulkancts/framework/vulkan/vkBufferWithMemory.cpp \
        external/vulkancts/framework/vulkan/vkBuilderUtil.cpp \
        external/vulkancts/framework/vulkan/vkDebugReportUtil.cpp \
        external/vulkancts/framework/vulkan/vkDefs.cpp \
@@ -704,6 +705,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/framework/vulkan/vkGlslProgram.cpp \
        external/vulkancts/framework/vulkan/vkGlslToSpirV.cpp \
        external/vulkancts/framework/vulkan/vkImageUtil.cpp \
+       external/vulkancts/framework/vulkan/vkImageWithMemory.cpp \
        external/vulkancts/framework/vulkan/vkMemUtil.cpp \
        external/vulkancts/framework/vulkan/vkNullDriver.cpp \
        external/vulkancts/framework/vulkan/vkPlatform.cpp \
@@ -738,7 +740,6 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/binding_model/vktBindingModelTests.cpp \
        external/vulkancts/modules/vulkan/binding_model/vktBindingShaderAccessTests.cpp \
        external/vulkancts/modules/vulkan/clipping/vktClippingTests.cpp \
-       external/vulkancts/modules/vulkan/clipping/vktClippingUtil.cpp \
        external/vulkancts/modules/vulkan/compute/vktComputeBasicComputeShaderTests.cpp \
        external/vulkancts/modules/vulkan/compute/vktComputeIndirectComputeDispatchTests.cpp \
        external/vulkancts/modules/vulkan/compute/vktComputeShaderBuiltinVarTests.cpp \
@@ -911,6 +912,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.cpp \
        external/vulkancts/modules/vulkan/ubo/vktUniformBlockTests.cpp \
        external/vulkancts/modules/vulkan/vktExternalMemoryUtil.cpp \
+       external/vulkancts/modules/vulkan/vktDrawUtil.cpp \
        external/vulkancts/modules/vulkan/vktInfoTests.cpp \
        external/vulkancts/modules/vulkan/vktShaderLibrary.cpp \
        external/vulkancts/modules/vulkan/vktTestCase.cpp \
index baef5d7..fa8e8f4 100644 (file)
@@ -47,6 +47,10 @@ set(VKUTIL_SRCS
        vkDebugReportUtil.hpp
        vkGlslProgram.cpp
        vkGlslProgram.hpp
+       vkBufferWithMemory.cpp
+       vkBufferWithMemory.hpp
+       vkImageWithMemory.cpp
+       vkImageWithMemory.hpp
        )
 
 set(VKUTIL_LIBS
diff --git a/external/vulkancts/framework/vulkan/vkBufferWithMemory.cpp b/external/vulkancts/framework/vulkan/vkBufferWithMemory.cpp
new file mode 100644 (file)
index 0000000..64ef9ea
--- /dev/null
@@ -0,0 +1,27 @@
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Buffer backed with memory
+ *//*--------------------------------------------------------------------*/
+
+#include "vkBufferWithMemory.hpp"
+
+DE_EMPTY_CPP_FILE
diff --git a/external/vulkancts/framework/vulkan/vkBufferWithMemory.hpp b/external/vulkancts/framework/vulkan/vkBufferWithMemory.hpp
new file mode 100644 (file)
index 0000000..1fcd299
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef _VKBUFFERWITHMEMORY_HPP
+#define _VKBUFFERWITHMEMORY_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Buffer backed with memory
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+
+#include "vkMemUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+
+namespace vk
+{
+class BufferWithMemory
+{
+public:
+                                                                               BufferWithMemory        (const vk::DeviceInterface&             vk,
+                                                                                                                        const vk::VkDevice                             device,
+                                                                                                                        vk::Allocator&                                 allocator,
+                                                                                                                        const vk::VkBufferCreateInfo&  bufferCreateInfo,
+                                                                                                                        const vk::MemoryRequirement    memoryRequirement)
+
+                                                                                       : m_buffer              (createBuffer(vk, device, &bufferCreateInfo))
+                                                                                       , m_allocation  (allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement))
+                                                                               {
+                                                                                       VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
+                                                                               }
+
+       const vk::VkBuffer&                                     get                             (void) const { return *m_buffer; }
+       const vk::VkBuffer&                                     operator*               (void) const { return get(); }
+       vk::Allocation&                                         getAllocation   (void) const { return *m_allocation; }
+
+private:
+       const vk::Unique<vk::VkBuffer>          m_buffer;
+       const de::UniquePtr<vk::Allocation>     m_allocation;
+
+       // "deleted"
+                                                                               BufferWithMemory        (const BufferWithMemory&);
+       BufferWithMemory                                        operator=                       (const BufferWithMemory&);
+};
+} // vk
+
+#endif // _VKBUFFERWITHMEMORY_HPP
diff --git a/external/vulkancts/framework/vulkan/vkImageWithMemory.cpp b/external/vulkancts/framework/vulkan/vkImageWithMemory.cpp
new file mode 100644 (file)
index 0000000..b8f680f
--- /dev/null
@@ -0,0 +1,27 @@
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Image backed with memory
+ *//*--------------------------------------------------------------------*/
+
+#include "vkImageWithMemory.hpp"
+
+DE_EMPTY_CPP_FILE
diff --git a/external/vulkancts/framework/vulkan/vkImageWithMemory.hpp b/external/vulkancts/framework/vulkan/vkImageWithMemory.hpp
new file mode 100644 (file)
index 0000000..23f0859
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef _VKIMAGEWITHMEMORY_HPP
+#define _VKIMAGEWITHMEMORY_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Image backed with memory
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+#include "vkMemUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+
+namespace vk
+{
+class ImageWithMemory
+{
+public:
+                                                                               ImageWithMemory (const vk::DeviceInterface&             vk,
+                                                                                                                const vk::VkDevice                             device,
+                                                                                                                vk::Allocator&                                 allocator,
+                                                                                                                const vk::VkImageCreateInfo&   imageCreateInfo,
+                                                                                                                const vk::MemoryRequirement    memoryRequirement)
+
+                                                                                       : m_image               (createImage(vk, device, &imageCreateInfo))
+                                                                                       , m_allocation  (allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement))
+                                                                               {
+                                                                                       VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset()));
+                                                                               }
+
+       const vk::VkImage&                                      get                             (void) const { return *m_image; }
+       const vk::VkImage&                                      operator*               (void) const { return get(); }
+       vk::Allocation&                                         getAllocation   (void) const { return *m_allocation; }
+
+private:
+       const vk::Unique<vk::VkImage>           m_image;
+       const de::UniquePtr<vk::Allocation>     m_allocation;
+
+       // "deleted"
+                                                                               ImageWithMemory (const ImageWithMemory&);
+       ImageWithMemory&                                        operator=               (const ImageWithMemory&);
+};
+} // vk
+
+#endif // _VKIMAGEWITHMEMORY_HPP
index 24f2291..c6cec98 100644 (file)
@@ -67,6 +67,8 @@ set(DEQP_VK_COMMON_SRCS
        vktInfoTests.hpp
        vktExternalMemoryUtil.cpp
        vktExternalMemoryUtil.hpp
+       vktDrawUtil.cpp
+       vktDrawUtil.hpp
        )
 
 set(DEQP_VK_COMMON_LIBS
index 2fb6331..fc2e61f 100644 (file)
@@ -3,8 +3,6 @@ include_directories(..)
 set(DEQP_VK_CLIPPING_SRCS
        vktClippingTests.cpp
        vktClippingTests.hpp
-       vktClippingUtil.cpp
-       vktClippingUtil.hpp
        )
 
 set(DEQP_VK_CLIPPING_LIBS
index 15d1443..627e06d 100644 (file)
@@ -25,7 +25,7 @@
 #include "vktTestCase.hpp"
 #include "vktTestGroupUtil.hpp"
 #include "vktTestCaseUtil.hpp"
-#include "vktClippingUtil.hpp"
+#include "vktDrawUtil.hpp"
 #include "vkRefUtil.hpp"
 #include "vkTypeUtil.hpp"
 #include "vkImageUtil.hpp"
@@ -45,524 +45,60 @@ using de::MovePtr;
 using tcu::UVec2;
 using tcu::Vec4;
 using tcu::IVec2;
+using namespace drawutil;
 
-enum Constants
+enum FeatureFlagBits
 {
-       RENDER_SIZE                                                             = 16,
-       RENDER_SIZE_LARGE                                               = 128,
-       NUM_RENDER_PIXELS                                               = RENDER_SIZE * RENDER_SIZE,
-       NUM_PATCH_CONTROL_POINTS                                = 3,
-       MAX_NUM_SHADER_MODULES                                  = 5,
-       MAX_CLIP_DISTANCES                                              = 8,
-       MAX_CULL_DISTANCES                                              = 8,
-       MAX_COMBINED_CLIP_AND_CULL_DISTANCES    = 8,
+       FEATURE_TESSELLATION_SHADER                                                     = 1u << 0,
+       FEATURE_GEOMETRY_SHADER                                                         = 1u << 1,
+       FEATURE_SHADER_FLOAT_64                                                         = 1u << 2,
+       FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS                      = 1u << 3,
+       FEATURE_FRAGMENT_STORES_AND_ATOMICS                                     = 1u << 4,
+       FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE     = 1u << 5,
+       FEATURE_DEPTH_CLAMP                                                                     = 1u << 6,
+       FEATURE_LARGE_POINTS                                                            = 1u << 7,
+       FEATURE_WIDE_LINES                                                                      = 1u << 8,
+       FEATURE_SHADER_CLIP_DISTANCE                                            = 1u << 9,
+       FEATURE_SHADER_CULL_DISTANCE                                            = 1u << 10,
 };
+typedef deUint32 FeatureFlags;
 
-struct Shader
+void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
 {
-       VkShaderStageFlagBits   stage;
-       const ProgramBinary*    binary;
+       const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
 
-       Shader (const VkShaderStageFlagBits stage_, const ProgramBinary& binary_)
-               : stage         (stage_)
-               , binary        (&binary_)
-       {
-       }
-};
-
-//! Sets up a graphics pipeline and enables simple draw calls to predefined attachments.
-//! Clip volume uses wc = 1.0, which gives clip coord ranges: x = [-1, 1], y = [-1, 1], z = [0, 1]
-//! Clip coords (-1,-1) map to viewport coords (0, 0).
-class DrawContext
-{
-public:
-                                                                       DrawContext             (Context&                                               context,
-                                                                                                        const std::vector<Shader>&             shaders,
-                                                                                                        const std::vector<Vec4>&               vertices,
-                                                                                                        const VkPrimitiveTopology              primitiveTopology,
-                                                                                                        const deUint32                                 renderSize                      = static_cast<deUint32>(RENDER_SIZE),
-                                                                                                        const bool                                             depthClampEnable        = false,
-                                                                                                        const bool                                             blendEnable                     = false,
-                                                                                                        const float                                    lineWidth                       = 1.0f);
-
-       void                                                    draw                    (void);
-       tcu::ConstPixelBufferAccess             getColorPixels  (void) const;
-
-private:
-       Context&                                                m_context;
-       const VkFormat                                  m_colorFormat;
-       const VkImageSubresourceRange   m_colorSubresourceRange;
-       const UVec2                                             m_renderSize;
-       const VkExtent3D                                m_imageExtent;
-       const VkPrimitiveTopology               m_primitiveTopology;
-       const bool                                              m_depthClampEnable;
-       const bool                                              m_blendEnable;
-       const deUint32                                  m_numVertices;
-       const float                                             m_lineWidth;
-       const deUint32                                  m_numPatchControlPoints;
-       MovePtr<Buffer>                                 m_vertexBuffer;
-       MovePtr<Image>                                  m_colorImage;
-       MovePtr<Buffer>                                 m_colorAttachmentBuffer;
-       Move<VkImageView>                               m_colorImageView;
-       Move<VkRenderPass>                              m_renderPass;
-       Move<VkFramebuffer>                             m_framebuffer;
-       Move<VkPipelineLayout>                  m_pipelineLayout;
-       Move<VkPipeline>                                m_pipeline;
-       Move<VkCommandPool>                             m_cmdPool;
-       Move<VkCommandBuffer>                   m_cmdBuffer;
-       Move<VkShaderModule>                    m_shaderModules[MAX_NUM_SHADER_MODULES];
-
-                                                                       DrawContext             (const DrawContext&);   // "deleted"
-       DrawContext&                                    operator=               (const DrawContext&);   // "deleted"
-};
-
-DrawContext::DrawContext (Context&                                             context,
-                                                 const std::vector<Shader>&    shaders,
-                                                 const std::vector<Vec4>&              vertices,
-                                                 const VkPrimitiveTopology             primitiveTopology,
-                                                 const deUint32                                renderSize,
-                                                 const bool                                    depthClampEnable,
-                                                 const bool                                    blendEnable,
-                                                 const float                                   lineWidth)
-       : m_context                                     (context)
-       , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
-       , m_colorSubresourceRange       (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
-       , m_renderSize                          (renderSize, renderSize)
-       , m_imageExtent                         (makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u))
-       , m_primitiveTopology           (primitiveTopology)
-       , m_depthClampEnable            (depthClampEnable)
-       , m_blendEnable                         (blendEnable)
-       , m_numVertices                         (static_cast<deUint32>(vertices.size()))
-       , m_lineWidth                           (lineWidth)
-       , m_numPatchControlPoints       (NUM_PATCH_CONTROL_POINTS)              // we're treating patches as triangles
-{
-       const DeviceInterface&  vk                      = m_context.getDeviceInterface();
-       const VkDevice                  device          = m_context.getDevice();
-       Allocator&                              allocator       = m_context.getDefaultAllocator();
-
-       // Command buffer
-       {
-               m_cmdPool       = makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
-               m_cmdBuffer     = makeCommandBuffer(vk, device, *m_cmdPool);
-       }
-
-       // Color attachment image
-       {
-               const VkImageUsageFlags usage                   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
-               const VkImageCreateInfo imageCreateInfo =
-               {
-                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType          sType;
-                       DE_NULL,                                                                        // const void*              pNext;
-                       (VkImageCreateFlags)0,                                          // VkImageCreateFlags       flags;
-                       VK_IMAGE_TYPE_2D,                                                       // VkImageType              imageType;
-                       m_colorFormat,                                                          // VkFormat                 format;
-                       m_imageExtent,                                                          // VkExtent3D               extent;
-                       1u,                                                                                     // uint32_t                 mipLevels;
-                       1u,                                                                                     // uint32_t                 arrayLayers;
-                       VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits    samples;
-                       VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling            tiling;
-                       usage,                                                                          // VkImageUsageFlags        usage;
-                       VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode            sharingMode;
-                       VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t                 queueFamilyIndexCount;
-                       DE_NULL,                                                                        // const uint32_t*          pQueueFamilyIndices;
-                       VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout            initialLayout;
-               };
-
-               m_colorImage = MovePtr<Image>(new Image(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
-               m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorSubresourceRange);
-
-               // Buffer to copy attachment data after rendering
-
-               const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_colorFormat)) * m_renderSize.x() * m_renderSize.y();
-               m_colorAttachmentBuffer = MovePtr<Buffer>(new Buffer(
-                       vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
-
-               {
-                       const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
-                       deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
-                       flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bitmapSize);
-               }
-       }
-
-       // Vertex buffer
-       {
-               const VkDeviceSize bufferSize = vertices.size() * sizeof(vertices[0]);
-               m_vertexBuffer = MovePtr<Buffer>(new Buffer(
-                       vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
-
-               const Allocation& alloc = m_vertexBuffer->getAllocation();
-               deMemcpy(alloc.getHostPtr(), &vertices[0], (size_t)bufferSize);
-               flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bufferSize);
-       }
-
-       // Pipeline layout
-       {
-               m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
-       }
-
-       // Renderpass
-       {
-               const VkAttachmentDescription colorAttachmentDescription =
-               {
-                       (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
-                       m_colorFormat,                                                                          // VkFormat                                                     format;
-                       VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
-                       VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
-                       VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
-                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
-                       VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
-                       VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout;
-                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
-               };
+       if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
+               throw tcu::NotSupportedError("Tessellation shader not supported");
 
-               const VkAttachmentReference colorAttachmentReference =
-               {
-                       0u,                                                                                                     // deUint32                     attachment;
-                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
-               };
+       if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
+               throw tcu::NotSupportedError("Geometry shader not supported");
 
-               const VkAttachmentReference depthAttachmentReference =
-               {
-                       VK_ATTACHMENT_UNUSED,                                                           // deUint32                     attachment;
-                       VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout        layout;
-               };
+       if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
+               throw tcu::NotSupportedError("Double-precision floats not supported");
 
-               const VkSubpassDescription subpassDescription =
-               {
-                       (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
-                       VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
-                       0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
-                       DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
-                       1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
-                       &colorAttachmentReference,                                                      // const VkAttachmentReference*         pColorAttachments;
-                       DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
-                       &depthAttachmentReference,                                                      // const VkAttachmentReference*         pDepthStencilAttachment;
-                       0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
-                       DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
-               };
+       if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
+               throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
 
-               const VkRenderPassCreateInfo renderPassInfo =
-               {
-                       VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
-                       DE_NULL,                                                                                        // const void*                                          pNext;
-                       (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
-                       1u,                                                                                                     // deUint32                                                     attachmentCount;
-                       &colorAttachmentDescription,                                            // const VkAttachmentDescription*       pAttachments;
-                       1u,                                                                                                     // deUint32                                                     subpassCount;
-                       &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
-                       0u,                                                                                                     // deUint32                                                     dependencyCount;
-                       DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
-               };
+       if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
+               throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
 
-               m_renderPass = createRenderPass(vk, device, &renderPassInfo);
-       }
+       if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
+               throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
 
-       // Framebuffer
-       {
-               const VkFramebufferCreateInfo framebufferInfo = {
-                       VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType                             sType;
-                       DE_NULL,                                                                                // const void*                                 pNext;
-                       (VkFramebufferCreateFlags)0,                                    // VkFramebufferCreateFlags                    flags;
-                       *m_renderPass,                                                                  // VkRenderPass                                renderPass;
-                       1u,                                                                                             // uint32_t                                    attachmentCount;
-                       &m_colorImageView.get(),                                                // const VkImageView*                          pAttachments;
-                       m_renderSize.x(),                                                               // uint32_t                                    width;
-                       m_renderSize.y(),                                                               // uint32_t                                    height;
-                       1u,                                                                                             // uint32_t                                    layers;
-               };
-
-               m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
-       }
+       if (((flags & FEATURE_DEPTH_CLAMP) != 0) && !features.depthClamp)
+               throw tcu::NotSupportedError("Depth clamp not supported");
 
-       // Graphics pipeline
-       {
-               const deUint32  vertexStride    = sizeof(Vec4);
-               const VkFormat  vertexFormat    = VK_FORMAT_R32G32B32A32_SFLOAT;
+       if (((flags & FEATURE_LARGE_POINTS) != 0) && !features.largePoints)
+               throw tcu::NotSupportedError("Large points not supported");
 
-               const VkVertexInputBindingDescription bindingDesc =
-               {
-                       0u,                                                                     // uint32_t                             binding;
-                       vertexStride,                                           // uint32_t                             stride;
-                       VK_VERTEX_INPUT_RATE_VERTEX,            // VkVertexInputRate    inputRate;
-               };
-               const VkVertexInputAttributeDescription attributeDesc =
-               {
-                       0u,                                                                     // uint32_t                     location;
-                       0u,                                                                     // uint32_t                     binding;
-                       vertexFormat,                                           // VkFormat                     format;
-                       0u,                                                                     // uint32_t                     offset;
-               };
-
-               const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                             sType;
-                       DE_NULL,                                                                                                                // const void*                                 pNext;
-                       (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags       flags;
-                       1u,                                                                                                                             // uint32_t                                    vertexBindingDescriptionCount;
-                       &bindingDesc,                                                                                                   // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
-                       1u,                                                                                                                             // uint32_t                                    vertexAttributeDescriptionCount;
-                       &attributeDesc,                                                                                                 // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
-               };
-
-               const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                             sType;
-                       DE_NULL,                                                                                                                // const void*                                 pNext;
-                       (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags     flags;
-                       m_primitiveTopology,                                                                                    // VkPrimitiveTopology                         topology;
-                       VK_FALSE,                                                                                                               // VkBool32                                    primitiveRestartEnable;
-               };
-
-               const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,              // VkStructureType                             sType;
-                       DE_NULL,                                                                                                                // const void*                                 pNext;
-                       (VkPipelineTessellationStateCreateFlags)0,                                              // VkPipelineTessellationStateCreateFlags      flags;
-                       m_numPatchControlPoints,                                                                                // uint32_t                                    patchControlPoints;
-               };
-
-               const VkViewport viewport = makeViewport(
-                       0.0f, 0.0f,
-                       static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
-                       0.0f, 1.0f);
-
-               const VkRect2D scissor = {
-                       makeOffset2D(0, 0),
-                       makeExtent2D(m_renderSize.x(), m_renderSize.y()),
-               };
-
-               const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                             sType;
-                       DE_NULL,                                                                                                // const void*                                 pNext;
-                       (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags          flags;
-                       1u,                                                                                                             // uint32_t                                    viewportCount;
-                       &viewport,                                                                                              // const VkViewport*                           pViewports;
-                       1u,                                                                                                             // uint32_t                                    scissorCount;
-                       &scissor,                                                                                               // const VkRect2D*                             pScissors;
-               };
-
-               const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                          sType;
-                       DE_NULL,                                                                                                                // const void*                              pNext;
-                       (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags  flags;
-                       m_depthClampEnable,                                                                                             // VkBool32                                 depthClampEnable;
-                       VK_FALSE,                                                                                                               // VkBool32                                 rasterizerDiscardEnable;
-                       VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
-                       VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
-                       VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
-                       VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
-                       0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
-                       0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
-                       0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
-                       m_lineWidth,                                                                                                    // float                                                                        lineWidth;
-               };
-
-               const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
-                       DE_NULL,                                                                                                        // const void*                                                          pNext;
-                       (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
-                       VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
-                       VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
-                       0.0f,                                                                                                           // float                                                                        minSampleShading;
-                       DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
-                       VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
-                       VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
-               };
-
-               const VkStencilOpState stencilOpState = makeStencilOpState(
-                       VK_STENCIL_OP_KEEP,             // stencil fail
-                       VK_STENCIL_OP_KEEP,             // depth & stencil pass
-                       VK_STENCIL_OP_KEEP,             // depth only fail
-                       VK_COMPARE_OP_NEVER,    // compare op
-                       0u,                                             // compare mask
-                       0u,                                             // write mask
-                       0u);                                    // reference
-
-               const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
-                       DE_NULL,                                                                                                        // const void*                                                          pNext;
-                       (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
-                       VK_FALSE,                                                                                                       // VkBool32                                                                     depthTestEnable;
-                       VK_FALSE,                                                                                                       // VkBool32                                                                     depthWriteEnable;
-                       VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
-                       VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
-                       VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
-                       stencilOpState,                                                                                         // VkStencilOpState                                                     front;
-                       stencilOpState,                                                                                         // VkStencilOpState                                                     back;
-                       0.0f,                                                                                                           // float                                                                        minDepthBounds;
-                       1.0f,                                                                                                           // float                                                                        maxDepthBounds;
-               };
-
-               const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
-               const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
-               {
-                       m_blendEnable,                                          // VkBool32                                     blendEnable;
-                       VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcColorBlendFactor;
-                       VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstColorBlendFactor;
-                       VK_BLEND_OP_ADD,                                        // VkBlendOp                            colorBlendOp;
-                       VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcAlphaBlendFactor;
-                       VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstAlphaBlendFactor;
-                       VK_BLEND_OP_ADD,                                        // VkBlendOp                            alphaBlendOp;
-                       colorComponentsAll,                                     // VkColorComponentFlags        colorWriteMask;
-               };
-
-               const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
-                       DE_NULL,                                                                                                        // const void*                                                                  pNext;
-                       (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
-                       VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
-                       VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
-                       1u,                                                                                                                     // deUint32                                                                             attachmentCount;
-                       &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
-                       { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
-               };
-
-               // Create shader stages
-
-               std::vector<VkPipelineShaderStageCreateInfo>    shaderStages;
-               VkShaderStageFlags                                                              stageFlags = (VkShaderStageFlags)0;
-
-               DE_ASSERT(shaders.size() <= MAX_NUM_SHADER_MODULES);
-               for (deUint32 shaderNdx = 0; shaderNdx < shaders.size(); ++shaderNdx)
-               {
-                       m_shaderModules[shaderNdx] = createShaderModule(vk, device, *shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
-
-                       const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
-                       {
-                               VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
-                               DE_NULL,                                                                                                // const void*                                                  pNext;
-                               (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
-                               shaders[shaderNdx].stage,                                                               // VkShaderStageFlagBits                                stage;
-                               *m_shaderModules[shaderNdx],                                                    // VkShaderModule                                               module;
-                               "main",                                                                                                 // const char*                                                  pName;
-                               DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
-                       };
-
-                       shaderStages.push_back(pipelineShaderStageInfo);
-                       stageFlags |= shaders[shaderNdx].stage;
-               }
-
-               DE_ASSERT(
-                       (m_primitiveTopology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
-                       (stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
-
-               const bool tessellationEnabled = (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
-               const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
-               {
-                       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                                // VkStructureType                                                                      sType;
-                       DE_NULL,                                                                                                                                // const void*                                                                          pNext;
-                       (VkPipelineCreateFlags)0,                                                                                               // VkPipelineCreateFlags                                                        flags;
-                       static_cast<deUint32>(shaderStages.size()),                                                             // deUint32                                                                                     stageCount;
-                       &shaderStages[0],                                                                                                               // const VkPipelineShaderStageCreateInfo*                       pStages;
-                       &vertexInputStateInfo,                                                                                                  // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
-                       &pipelineInputAssemblyStateInfo,                                                                                // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
-                       (tessellationEnabled ? &pipelineTessellationStateInfo : DE_NULL),               // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
-                       &pipelineViewportStateInfo,                                                                                             // const VkPipelineViewportStateCreateInfo*                     pViewportState;
-                       &pipelineRasterizationStateInfo,                                                                                // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
-                       &pipelineMultisampleStateInfo,                                                                                  // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
-                       &pipelineDepthStencilStateInfo,                                                                                 // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
-                       &pipelineColorBlendStateInfo,                                                                                   // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
-                       DE_NULL,                                                                                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
-                       *m_pipelineLayout,                                                                                                              // VkPipelineLayout                                                                     layout;
-                       *m_renderPass,                                                                                                                  // VkRenderPass                                                                         renderPass;
-                       0u,                                                                                                                                             // deUint32                                                                                     subpass;
-                       DE_NULL,                                                                                                                                // VkPipeline                                                                           basePipelineHandle;
-                       0,                                                                                                                                              // deInt32                                                                                      basePipelineIndex;
-               };
-
-               m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
-       }
-
-       // Record commands
-       {
-               const VkDeviceSize zeroOffset = 0ull;
-
-               beginCommandBuffer(vk, *m_cmdBuffer);
-
-               // Begin render pass
-               {
-                       const VkClearValue      clearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f));
-                       const VkRect2D          renderArea =
-                       {
-                               makeOffset2D(0, 0),
-                               makeExtent2D(m_renderSize.x(), m_renderSize.y())
-                       };
-
-                       const VkRenderPassBeginInfo renderPassBeginInfo = {
-                               VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType         sType;
-                               DE_NULL,                                                                                // const void*             pNext;
-                               *m_renderPass,                                                                  // VkRenderPass            renderPass;
-                               *m_framebuffer,                                                                 // VkFramebuffer           framebuffer;
-                               renderArea,                                                                             // VkRect2D                renderArea;
-                               1u,                                                                                             // uint32_t                clearValueCount;
-                               &clearValue,                                                                    // const VkClearValue*     pClearValues;
-                       };
-
-                       vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
-               }
-
-               vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
-               vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
-
-               vk.cmdDraw(*m_cmdBuffer, m_numVertices, 1u, 0u, 1u);
-               vk.cmdEndRenderPass(*m_cmdBuffer);
-
-               // Barrier: draw -> copy from image
-               {
-                       const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
-                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
-                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                               **m_colorImage, m_colorSubresourceRange);
-
-                       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
-                               0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
-               }
-
-               {
-                       const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), m_imageExtent);
-                       vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, &copyRegion);
-               }
-
-               // Barrier: copy to buffer -> host read
-               {
-                       const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
-                               VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
-                               **m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
-
-                       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
-                               0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
-               }
-
-               endCommandBuffer(vk, *m_cmdBuffer);
-       }
-}
-
-void DrawContext::draw (void)
-{
-       const DeviceInterface&  vk                      = m_context.getDeviceInterface();
-       const VkDevice                  device          = m_context.getDevice();
-       const VkQueue                   queue           = m_context.getUniversalQueue();
-       tcu::TestLog&                   log                     = m_context.getTestContext().getLog();
-
-       submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
-
-       log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
-}
-
-tcu::ConstPixelBufferAccess DrawContext::getColorPixels (void) const
-{
-       const DeviceInterface&  vk                      = m_context.getDeviceInterface();
-       const VkDevice                  device          = m_context.getDevice();
+       if (((flags & FEATURE_WIDE_LINES) != 0) && !features.wideLines)
+               throw tcu::NotSupportedError("Wide lines not supported");
 
-       const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
-       invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE);
+       if (((flags & FEATURE_SHADER_CLIP_DISTANCE) != 0) && !features.shaderClipDistance)
+               throw tcu::NotSupportedError("Shader ClipDistance not supported");
 
-       return tcu::ConstPixelBufferAccess(mapVkFormat(m_colorFormat), m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, alloc.getHostPtr());
+       if (((flags & FEATURE_SHADER_CULL_DISTANCE) != 0) && !features.shaderCullDistance)
+               throw tcu::NotSupportedError("Shader CullDistance not supported");
 }
 
 std::vector<Vec4> genVertices (const VkPrimitiveTopology topology, const Vec4& offset, const float slope)
diff --git a/external/vulkancts/modules/vulkan/clipping/vktClippingUtil.cpp b/external/vulkancts/modules/vulkan/clipping/vktClippingUtil.cpp
deleted file mode 100644 (file)
index 4b95413..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/*------------------------------------------------------------------------
- * Vulkan Conformance Tests
- * ------------------------
- *
- * Copyright (c) 2016 The Khronos Group Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *//*!
- * \file
- * \brief Clipping tests utilities
- *//*--------------------------------------------------------------------*/
-
-#include "vktClippingUtil.hpp"
-#include "vkTypeUtil.hpp"
-
-namespace vkt
-{
-namespace clipping
-{
-using namespace vk;
-
-VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize                    bufferSize,
-                                                                                const VkBufferUsageFlags       usage)
-{
-       const VkBufferCreateInfo bufferCreateInfo =
-       {
-               VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
-               DE_NULL,                                                                // const void*                  pNext;
-               (VkBufferCreateFlags)0,                                 // VkBufferCreateFlags  flags;
-               bufferSize,                                                             // VkDeviceSize                 size;
-               usage,                                                                  // VkBufferUsageFlags   usage;
-               VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
-               0u,                                                                             // deUint32                             queueFamilyIndexCount;
-               DE_NULL,                                                                // const deUint32*              pQueueFamilyIndices;
-       };
-       return bufferCreateInfo;
-}
-
-VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags     srcAccessMask,
-                                                                                          const VkAccessFlags  dstAccessMask,
-                                                                                          const VkBuffer               buffer,
-                                                                                          const VkDeviceSize   offset,
-                                                                                          const VkDeviceSize   bufferSizeBytes)
-{
-       const VkBufferMemoryBarrier barrier =
-       {
-               VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
-               DE_NULL,                                                                        // const void*          pNext;
-               srcAccessMask,                                                          // VkAccessFlags        srcAccessMask;
-               dstAccessMask,                                                          // VkAccessFlags        dstAccessMask;
-               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
-               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     destQueueFamilyIndex;
-               buffer,                                                                         // VkBuffer                     buffer;
-               offset,                                                                         // VkDeviceSize         offset;
-               bufferSizeBytes,                                                        // VkDeviceSize         size;
-       };
-       return barrier;
-}
-
-VkImageMemoryBarrier makeImageMemoryBarrier    (const VkAccessFlags                    srcAccessMask,
-                                                                                        const VkAccessFlags                    dstAccessMask,
-                                                                                        const VkImageLayout                    oldLayout,
-                                                                                        const VkImageLayout                    newLayout,
-                                                                                        const VkImage                                  image,
-                                                                                        const VkImageSubresourceRange  subresourceRange)
-{
-       const VkImageMemoryBarrier barrier =
-       {
-               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
-               DE_NULL,                                                                                // const void*                          pNext;
-               srcAccessMask,                                                                  // VkAccessFlags                        outputMask;
-               dstAccessMask,                                                                  // VkAccessFlags                        inputMask;
-               oldLayout,                                                                              // VkImageLayout                        oldLayout;
-               newLayout,                                                                              // VkImageLayout                        newLayout;
-               VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
-               VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
-               image,                                                                                  // VkImage                                      image;
-               subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
-       };
-       return barrier;
-}
-
-Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
-{
-       const VkCommandPoolCreateInfo info =
-       {
-               VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType                      sType;
-               DE_NULL,                                                                                        // const void*                          pNext;
-               VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // VkCommandPoolCreateFlags     flags;
-               queueFamilyIndex,                                                                       // deUint32                                     queueFamilyIndex;
-       };
-       return createCommandPool(vk, device, &info);
-}
-
-Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
-{
-       const VkCommandBufferAllocateInfo info =
-       {
-               VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,         // VkStructureType              sType;
-               DE_NULL,                                                                                        // const void*                  pNext;
-               commandPool,                                                                            // VkCommandPool                commandPool;
-               VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                        // VkCommandBufferLevel level;
-               1u,                                                                                                     // deUint32                             commandBufferCount;
-       };
-       return allocateCommandBuffer(vk, device, &info);
-}
-
-Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&                        vk,
-                                                                                const VkDevice                                 device,
-                                                                                const VkDescriptorPool                 descriptorPool,
-                                                                                const VkDescriptorSetLayout    setLayout)
-{
-       const VkDescriptorSetAllocateInfo info =
-       {
-               VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // VkStructureType                              sType;
-               DE_NULL,                                                                                        // const void*                                  pNext;
-               descriptorPool,                                                                         // VkDescriptorPool                             descriptorPool;
-               1u,                                                                                                     // deUint32                                             descriptorSetCount;
-               &setLayout,                                                                                     // const VkDescriptorSetLayout* pSetLayouts;
-       };
-       return allocateDescriptorSet(vk, device, &info);
-}
-
-Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&              vk,
-                                                                                  const VkDevice                               device,
-                                                                                  const VkDescriptorSetLayout  descriptorSetLayout)
-{
-       const VkPipelineLayoutCreateInfo info =
-       {
-               VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
-               DE_NULL,                                                                                        // const void*                                  pNext;
-               (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
-               1u,                                                                                                     // deUint32                                             setLayoutCount;
-               &descriptorSetLayout,                                                           // const VkDescriptorSetLayout* pSetLayouts;
-               0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
-               DE_NULL,                                                                                        // const VkPushConstantRange*   pPushConstantRanges;
-       };
-       return createPipelineLayout(vk, device, &info);
-}
-
-Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface&            vk,
-                                                                                                                        const VkDevice                         device)
-{
-       const VkPipelineLayoutCreateInfo info =
-       {
-               VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
-               DE_NULL,                                                                                        // const void*                                  pNext;
-               (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
-               0u,                                                                                                     // deUint32                                             setLayoutCount;
-               DE_NULL,                                                                                        // const VkDescriptorSetLayout* pSetLayouts;
-               0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
-               DE_NULL,                                                                                        // const VkPushConstantRange*   pPushConstantRanges;
-       };
-       return createPipelineLayout(vk, device, &info);
-}
-
-Move<VkImageView> makeImageView (const DeviceInterface&                        vk,
-                                                                const VkDevice                                 device,
-                                                                const VkImage                                  image,
-                                                                const VkImageViewType                  viewType,
-                                                                const VkFormat                                 format,
-                                                                const VkImageSubresourceRange  subresourceRange)
-{
-       const VkImageViewCreateInfo imageViewParams =
-       {
-               VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
-               DE_NULL,                                                                                // const void*                          pNext;
-               (VkImageViewCreateFlags)0,                                              // VkImageViewCreateFlags       flags;
-               image,                                                                                  // VkImage                                      image;
-               viewType,                                                                               // VkImageViewType                      viewType;
-               format,                                                                                 // VkFormat                                     format;
-               makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
-               subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
-       };
-       return createImageView(vk, device, &imageViewParams);
-}
-
-VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers  subresourceLayers,
-                                                                          const VkExtent3D                                     extent)
-{
-       const VkBufferImageCopy copyParams =
-       {
-               0ull,                                                                           //      VkDeviceSize                            bufferOffset;
-               0u,                                                                                     //      deUint32                                        bufferRowLength;
-               0u,                                                                                     //      deUint32                                        bufferImageHeight;
-               subresourceLayers,                                                      //      VkImageSubresourceLayers        imageSubresource;
-               makeOffset3D(0, 0, 0),                                          //      VkOffset3D                                      imageOffset;
-               extent,                                                                         //      VkExtent3D                                      imageExtent;
-       };
-       return copyParams;
-}
-
-void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
-{
-       const VkCommandBufferBeginInfo info =
-       {
-               VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                          sType;
-               DE_NULL,                                                                                // const void*                              pNext;
-               VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags                flags;
-               DE_NULL,                                                                                // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
-       };
-       VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
-}
-
-void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
-{
-       VK_CHECK(vk.endCommandBuffer(commandBuffer));
-}
-
-void submitCommandsAndWait (const DeviceInterface&     vk,
-                                                       const VkDevice                  device,
-                                                       const VkQueue                   queue,
-                                                       const VkCommandBuffer   commandBuffer)
-{
-       const VkFenceCreateInfo fenceInfo =
-       {
-               VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
-               DE_NULL,                                                                // const void*                  pNext;
-               (VkFenceCreateFlags)0,                                  // VkFenceCreateFlags   flags;
-       };
-       const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
-
-       const VkSubmitInfo submitInfo =
-       {
-               VK_STRUCTURE_TYPE_SUBMIT_INFO,          // VkStructureType                sType;
-               DE_NULL,                                                        // const void*                    pNext;
-               0u,                                                                     // uint32_t                       waitSemaphoreCount;
-               DE_NULL,                                                        // const VkSemaphore*             pWaitSemaphores;
-               DE_NULL,                                                        // const VkPipelineStageFlags*    pWaitDstStageMask;
-               1u,                                                                     // uint32_t                       commandBufferCount;
-               &commandBuffer,                                         // const VkCommandBuffer*         pCommandBuffers;
-               0u,                                                                     // uint32_t                       signalSemaphoreCount;
-               DE_NULL,                                                        // const VkSemaphore*             pSignalSemaphores;
-       };
-       VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
-       VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
-}
-
-void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
-{
-       const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
-
-       if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
-               throw tcu::NotSupportedError("Tessellation shader not supported");
-
-       if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
-               throw tcu::NotSupportedError("Geometry shader not supported");
-
-       if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
-               throw tcu::NotSupportedError("Double-precision floats not supported");
-
-       if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
-               throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
-
-       if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
-               throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
-
-       if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
-               throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
-
-       if (((flags & FEATURE_DEPTH_CLAMP) != 0) && !features.depthClamp)
-               throw tcu::NotSupportedError("Depth clamp not supported");
-
-       if (((flags & FEATURE_LARGE_POINTS) != 0) && !features.largePoints)
-               throw tcu::NotSupportedError("Large points not supported");
-
-       if (((flags & FEATURE_WIDE_LINES) != 0) && !features.wideLines)
-               throw tcu::NotSupportedError("Wide lines not supported");
-
-       if (((flags & FEATURE_SHADER_CLIP_DISTANCE) != 0) && !features.shaderClipDistance)
-               throw tcu::NotSupportedError("Shader ClipDistance not supported");
-
-       if (((flags & FEATURE_SHADER_CULL_DISTANCE) != 0) && !features.shaderCullDistance)
-               throw tcu::NotSupportedError("Shader CullDistance not supported");
-}
-
-std::string getPrimitiveTopologyShortName (const VkPrimitiveTopology topology)
-{
-       std::string name(getPrimitiveTopologyName(topology));
-       return de::toLower(name.substr(22));
-}
-
-} // clipping
-} // vkt
diff --git a/external/vulkancts/modules/vulkan/clipping/vktClippingUtil.hpp b/external/vulkancts/modules/vulkan/clipping/vktClippingUtil.hpp
deleted file mode 100644 (file)
index c975813..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef _VKTCLIPPINGUTIL_HPP
-#define _VKTCLIPPINGUTIL_HPP
-/*------------------------------------------------------------------------
- * Vulkan Conformance Tests
- * ------------------------
- *
- * Copyright (c) 2016 The Khronos Group Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *//*!
- * \file
- * \brief Clipping tests utilities
- *//*--------------------------------------------------------------------*/
-
-#include "vkDefs.hpp"
-#include "vkQueryUtil.hpp"
-#include "vkMemUtil.hpp"
-#include "vkRefUtil.hpp"
-#include "vkPrograms.hpp"
-#include "tcuVector.hpp"
-
-namespace vkt
-{
-namespace clipping
-{
-
-class Buffer
-{
-public:
-                                                                               Buffer                  (const vk::DeviceInterface&             vk,
-                                                                                                                const vk::VkDevice                             device,
-                                                                                                                vk::Allocator&                                 allocator,
-                                                                                                                const vk::VkBufferCreateInfo&  bufferCreateInfo,
-                                                                                                                const vk::MemoryRequirement    memoryRequirement)
-
-                                                                                       : m_buffer              (createBuffer(vk, device, &bufferCreateInfo))
-                                                                                       , m_allocation  (allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement))
-                                                                               {
-                                                                                       VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
-                                                                               }
-
-       const vk::VkBuffer&                                     get                             (void) const { return *m_buffer; }
-       const vk::VkBuffer&                                     operator*               (void) const { return get(); }
-       vk::Allocation&                                         getAllocation   (void) const { return *m_allocation; }
-
-private:
-       const vk::Unique<vk::VkBuffer>          m_buffer;
-       const de::UniquePtr<vk::Allocation>     m_allocation;
-
-       // "deleted"
-                                                                               Buffer                  (const Buffer&);
-       Buffer&                                                         operator=               (const Buffer&);
-};
-
-class Image
-{
-public:
-                                                                               Image                   (const vk::DeviceInterface&             vk,
-                                                                                                                const vk::VkDevice                             device,
-                                                                                                                vk::Allocator&                                 allocator,
-                                                                                                                const vk::VkImageCreateInfo&   imageCreateInfo,
-                                                                                                                const vk::MemoryRequirement    memoryRequirement)
-
-                                                                                       : m_image               (createImage(vk, device, &imageCreateInfo))
-                                                                                       , m_allocation  (allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement))
-                                                                               {
-                                                                                       VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset()));
-                                                                               }
-
-       const vk::VkImage&                                      get                             (void) const { return *m_image; }
-       const vk::VkImage&                                      operator*               (void) const { return get(); }
-       vk::Allocation&                                         getAllocation   (void) const { return *m_allocation; }
-
-private:
-       const vk::Unique<vk::VkImage>           m_image;
-       const de::UniquePtr<vk::Allocation>     m_allocation;
-
-       // "deleted"
-                                                                               Image                   (const Image&);
-       Image&                                                          operator=               (const Image&);
-};
-
-enum FeatureFlagBits
-{
-       FEATURE_TESSELLATION_SHADER                                                     = 1u << 0,
-       FEATURE_GEOMETRY_SHADER                                                         = 1u << 1,
-       FEATURE_SHADER_FLOAT_64                                                         = 1u << 2,
-       FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS                      = 1u << 3,
-       FEATURE_FRAGMENT_STORES_AND_ATOMICS                                     = 1u << 4,
-       FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE     = 1u << 5,
-       FEATURE_DEPTH_CLAMP                                                                     = 1u << 6,
-       FEATURE_LARGE_POINTS                                                            = 1u << 7,
-       FEATURE_WIDE_LINES                                                                      = 1u << 8,
-       FEATURE_SHADER_CLIP_DISTANCE                                            = 1u << 9,
-       FEATURE_SHADER_CULL_DISTANCE                                            = 1u << 10,
-};
-typedef deUint32 FeatureFlags;
-
-vk::VkBufferCreateInfo                 makeBufferCreateInfo                                            (const vk::VkDeviceSize bufferSize, const vk::VkBufferUsageFlags usage);
-vk::Move<vk::VkCommandPool>            makeCommandPool                                                         (const vk::DeviceInterface& vk, const vk::VkDevice device, const deUint32 queueFamilyIndex);
-vk::Move<vk::VkCommandBuffer>  makeCommandBuffer                                                       (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkCommandPool commandPool);
-vk::Move<vk::VkDescriptorSet>  makeDescriptorSet                                                       (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkDescriptorPool descriptorPool, const vk::VkDescriptorSetLayout setLayout);
-vk::Move<vk::VkPipelineLayout> makePipelineLayout                                                      (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkDescriptorSetLayout descriptorSetLayout);
-vk::Move<vk::VkPipelineLayout> makePipelineLayoutWithoutDescriptors            (const vk::DeviceInterface& vk, const vk::VkDevice device);
-vk::Move<vk::VkImageView>              makeImageView                                                           (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkImage image, const vk::VkImageViewType viewType, const vk::VkFormat format, const vk::VkImageSubresourceRange subresourceRange);
-vk::VkBufferImageCopy                  makeBufferImageCopy                                                     (const vk::VkImageSubresourceLayers subresourceLayers, const vk::VkExtent3D extent);
-vk::VkBufferMemoryBarrier              makeBufferMemoryBarrier                                         (const vk::VkAccessFlags srcAccessMask, const vk::VkAccessFlags dstAccessMask, const vk::VkBuffer buffer, const vk::VkDeviceSize offset, const vk::VkDeviceSize bufferSizeBytes);
-vk::VkImageMemoryBarrier               makeImageMemoryBarrier                                          (const vk::VkAccessFlags srcAccessMask, const vk::VkAccessFlags dstAccessMask, const vk::VkImageLayout oldLayout, const vk::VkImageLayout newLayout, const vk::VkImage image, const vk::VkImageSubresourceRange subresourceRange);
-
-void                                                   beginCommandBuffer                                                      (const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer);
-void                                                   endCommandBuffer                                                        (const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer);
-void                                                   submitCommandsAndWait                                           (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkQueue queue, const vk::VkCommandBuffer commandBuffer);
-void                                                   requireFeatures                                                         (const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physDevice, const FeatureFlags flags);
-
-std::string                                            getPrimitiveTopologyShortName                           (const vk::VkPrimitiveTopology topology);
-
-} // clipping
-} // vkt
-
-#endif // _VKTCLIPPINGUTIL_HPP
diff --git a/external/vulkancts/modules/vulkan/vktDrawUtil.cpp b/external/vulkancts/modules/vulkan/vktDrawUtil.cpp
new file mode 100644 (file)
index 0000000..ae59db4
--- /dev/null
@@ -0,0 +1,744 @@
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Utility for generating simple work
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDrawUtil.hpp"
+#include "vkBufferWithMemory.hpp"
+#include "vkImageWithMemory.hpp"
+#include "vkTypeUtil.hpp"
+#include "tcuTestLog.hpp"
+
+namespace vkt
+{
+namespace drawutil
+{
+
+using namespace de;
+using namespace tcu;
+using namespace vk;
+
+VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize                    bufferSize,
+                                                                                const VkBufferUsageFlags       usage)
+{
+       const VkBufferCreateInfo bufferCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
+               DE_NULL,                                                                // const void*                  pNext;
+               (VkBufferCreateFlags)0,                                 // VkBufferCreateFlags  flags;
+               bufferSize,                                                             // VkDeviceSize                 size;
+               usage,                                                                  // VkBufferUsageFlags   usage;
+               VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
+               0u,                                                                             // deUint32                             queueFamilyIndexCount;
+               DE_NULL,                                                                // const deUint32*              pQueueFamilyIndices;
+       };
+       return bufferCreateInfo;
+}
+
+VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags     srcAccessMask,
+                                                                                          const VkAccessFlags  dstAccessMask,
+                                                                                          const VkBuffer               buffer,
+                                                                                          const VkDeviceSize   offset,
+                                                                                          const VkDeviceSize   bufferSizeBytes)
+{
+       const VkBufferMemoryBarrier barrier =
+       {
+               VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
+               DE_NULL,                                                                        // const void*          pNext;
+               srcAccessMask,                                                          // VkAccessFlags        srcAccessMask;
+               dstAccessMask,                                                          // VkAccessFlags        dstAccessMask;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     destQueueFamilyIndex;
+               buffer,                                                                         // VkBuffer                     buffer;
+               offset,                                                                         // VkDeviceSize         offset;
+               bufferSizeBytes,                                                        // VkDeviceSize         size;
+       };
+       return barrier;
+}
+
+VkImageMemoryBarrier makeImageMemoryBarrier    (const VkAccessFlags                    srcAccessMask,
+                                                                                        const VkAccessFlags                    dstAccessMask,
+                                                                                        const VkImageLayout                    oldLayout,
+                                                                                        const VkImageLayout                    newLayout,
+                                                                                        const VkImage                                  image,
+                                                                                        const VkImageSubresourceRange  subresourceRange)
+{
+       const VkImageMemoryBarrier barrier =
+       {
+               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
+               DE_NULL,                                                                                // const void*                          pNext;
+               srcAccessMask,                                                                  // VkAccessFlags                        outputMask;
+               dstAccessMask,                                                                  // VkAccessFlags                        inputMask;
+               oldLayout,                                                                              // VkImageLayout                        oldLayout;
+               newLayout,                                                                              // VkImageLayout                        newLayout;
+               VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
+               VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
+               image,                                                                                  // VkImage                                      image;
+               subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
+       };
+       return barrier;
+}
+
+Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
+{
+       const VkCommandPoolCreateInfo info =
+       {
+               VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType                      sType;
+               DE_NULL,                                                                                        // const void*                          pNext;
+               VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // VkCommandPoolCreateFlags     flags;
+               queueFamilyIndex,                                                                       // deUint32                                     queueFamilyIndex;
+       };
+       return createCommandPool(vk, device, &info);
+}
+
+Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
+{
+       const VkCommandBufferAllocateInfo info =
+       {
+               VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,         // VkStructureType              sType;
+               DE_NULL,                                                                                        // const void*                  pNext;
+               commandPool,                                                                            // VkCommandPool                commandPool;
+               VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                        // VkCommandBufferLevel level;
+               1u,                                                                                                     // deUint32                             commandBufferCount;
+       };
+       return allocateCommandBuffer(vk, device, &info);
+}
+
+Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&                        vk,
+                                                                                const VkDevice                                 device,
+                                                                                const VkDescriptorPool                 descriptorPool,
+                                                                                const VkDescriptorSetLayout    setLayout)
+{
+       const VkDescriptorSetAllocateInfo info =
+       {
+               VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // VkStructureType                              sType;
+               DE_NULL,                                                                                        // const void*                                  pNext;
+               descriptorPool,                                                                         // VkDescriptorPool                             descriptorPool;
+               1u,                                                                                                     // deUint32                                             descriptorSetCount;
+               &setLayout,                                                                                     // const VkDescriptorSetLayout* pSetLayouts;
+       };
+       return allocateDescriptorSet(vk, device, &info);
+}
+
+Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&              vk,
+                                                                                  const VkDevice                               device,
+                                                                                  const VkDescriptorSetLayout  descriptorSetLayout)
+{
+       const VkPipelineLayoutCreateInfo info =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
+               DE_NULL,                                                                                        // const void*                                  pNext;
+               (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
+               1u,                                                                                                     // deUint32                                             setLayoutCount;
+               &descriptorSetLayout,                                                           // const VkDescriptorSetLayout* pSetLayouts;
+               0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
+               DE_NULL,                                                                                        // const VkPushConstantRange*   pPushConstantRanges;
+       };
+       return createPipelineLayout(vk, device, &info);
+}
+
+Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface&            vk,
+                                                                                                                        const VkDevice                         device)
+{
+       const VkPipelineLayoutCreateInfo info =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
+               DE_NULL,                                                                                        // const void*                                  pNext;
+               (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
+               0u,                                                                                                     // deUint32                                             setLayoutCount;
+               DE_NULL,                                                                                        // const VkDescriptorSetLayout* pSetLayouts;
+               0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
+               DE_NULL,                                                                                        // const VkPushConstantRange*   pPushConstantRanges;
+       };
+       return createPipelineLayout(vk, device, &info);
+}
+
+Move<VkImageView> makeImageView (const DeviceInterface&                        vk,
+                                                                const VkDevice                                 device,
+                                                                const VkImage                                  image,
+                                                                const VkImageViewType                  viewType,
+                                                                const VkFormat                                 format,
+                                                                const VkImageSubresourceRange  subresourceRange)
+{
+       const VkImageViewCreateInfo imageViewParams =
+       {
+               VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
+               DE_NULL,                                                                                // const void*                          pNext;
+               (VkImageViewCreateFlags)0,                                              // VkImageViewCreateFlags       flags;
+               image,                                                                                  // VkImage                                      image;
+               viewType,                                                                               // VkImageViewType                      viewType;
+               format,                                                                                 // VkFormat                                     format;
+               makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
+               subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
+       };
+       return createImageView(vk, device, &imageViewParams);
+}
+
+VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers  subresourceLayers,
+                                                                          const VkExtent3D                                     extent)
+{
+       const VkBufferImageCopy copyParams =
+       {
+               0ull,                                                                           //      VkDeviceSize                            bufferOffset;
+               0u,                                                                                     //      deUint32                                        bufferRowLength;
+               0u,                                                                                     //      deUint32                                        bufferImageHeight;
+               subresourceLayers,                                                      //      VkImageSubresourceLayers        imageSubresource;
+               makeOffset3D(0, 0, 0),                                          //      VkOffset3D                                      imageOffset;
+               extent,                                                                         //      VkExtent3D                                      imageExtent;
+       };
+       return copyParams;
+}
+
+void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
+{
+       const VkCommandBufferBeginInfo info =
+       {
+               VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                          sType;
+               DE_NULL,                                                                                // const void*                              pNext;
+               VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags                flags;
+               DE_NULL,                                                                                // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
+       };
+       VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
+}
+
+void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
+{
+       VK_CHECK(vk.endCommandBuffer(commandBuffer));
+}
+
+void submitCommandsAndWait (const DeviceInterface&     vk,
+                                                       const VkDevice                  device,
+                                                       const VkQueue                   queue,
+                                                       const VkCommandBuffer   commandBuffer)
+{
+       const VkFenceCreateInfo fenceInfo =
+       {
+               VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
+               DE_NULL,                                                                // const void*                  pNext;
+               (VkFenceCreateFlags)0,                                  // VkFenceCreateFlags   flags;
+       };
+       const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
+
+       const VkSubmitInfo submitInfo =
+       {
+               VK_STRUCTURE_TYPE_SUBMIT_INFO,          // VkStructureType                sType;
+               DE_NULL,                                                        // const void*                    pNext;
+               0u,                                                                     // uint32_t                       waitSemaphoreCount;
+               DE_NULL,                                                        // const VkSemaphore*             pWaitSemaphores;
+               DE_NULL,                                                        // const VkPipelineStageFlags*    pWaitDstStageMask;
+               1u,                                                                     // uint32_t                       commandBufferCount;
+               &commandBuffer,                                         // const VkCommandBuffer*         pCommandBuffers;
+               0u,                                                                     // uint32_t                       signalSemaphoreCount;
+               DE_NULL,                                                        // const VkSemaphore*             pSignalSemaphores;
+       };
+       VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
+       VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
+}
+
+std::string getPrimitiveTopologyShortName (const VkPrimitiveTopology topology)
+{
+       std::string name(getPrimitiveTopologyName(topology));
+       return de::toLower(name.substr(22));
+}
+DrawContext::DrawContext (Context&                                             context,
+                                                 const std::vector<Shader>&    shaders,
+                                                 const std::vector<Vec4>&              vertices,
+                                                 const VkPrimitiveTopology             primitiveTopology,
+                                                 const deUint32                                renderSize,
+                                                 const bool                                    depthClampEnable,
+                                                 const bool                                    blendEnable,
+                                                 const float                                   lineWidth)
+       : m_context                                     (context)
+       , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
+       , m_depthFormat                         (VK_FORMAT_D32_SFLOAT)
+       , m_colorSubresourceRange       (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
+       , m_depthSubresourceRange       (makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u))
+       , m_renderSize                          (renderSize, renderSize)
+       , m_imageExtent                         (makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u))
+       , m_primitiveTopology           (primitiveTopology)
+       , m_depthClampEnable            (depthClampEnable)
+       , m_blendEnable                         (blendEnable)
+       , m_numVertices                         (static_cast<deUint32>(vertices.size()))
+       , m_lineWidth                           (lineWidth)
+       , m_numPatchControlPoints       (NUM_PATCH_CONTROL_POINTS)              // we're treating patches as triangles
+{
+       const DeviceInterface&  vk                      = m_context.getDeviceInterface();
+       const VkDevice                  device          = m_context.getDevice();
+       Allocator&                              allocator       = m_context.getDefaultAllocator();
+
+       // Command buffer
+       {
+               m_cmdPool       = makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
+               m_cmdBuffer     = makeCommandBuffer(vk, device, *m_cmdPool);
+       }
+
+       // Color attachment image
+       {
+               const VkImageUsageFlags usage                   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+               const VkImageCreateInfo imageCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType          sType;
+                       DE_NULL,                                                                        // const void*              pNext;
+                       (VkImageCreateFlags)0,                                          // VkImageCreateFlags       flags;
+                       VK_IMAGE_TYPE_2D,                                                       // VkImageType              imageType;
+                       m_colorFormat,                                                          // VkFormat                 format;
+                       m_imageExtent,                                                          // VkExtent3D               extent;
+                       1u,                                                                                     // uint32_t                 mipLevels;
+                       1u,                                                                                     // uint32_t                 arrayLayers;
+                       VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits    samples;
+                       VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling            tiling;
+                       usage,                                                                          // VkImageUsageFlags        usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode            sharingMode;
+                       VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t                 queueFamilyIndexCount;
+                       DE_NULL,                                                                        // const uint32_t*          pQueueFamilyIndices;
+                       VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout            initialLayout;
+               };
+
+               m_colorImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
+               m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorSubresourceRange);
+
+               // Buffer to copy attachment data after rendering
+
+               const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_colorFormat)) * m_renderSize.x() * m_renderSize.y();
+               m_colorAttachmentBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
+                       vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
+
+               {
+                       const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
+                       deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
+                       flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bitmapSize);
+               }
+       }
+
+       // Depth attachment image
+       {
+               const VkImageCreateInfo imageCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                    // VkStructureType                      sType
+                       DE_NULL,                                                                                // const void*                          pNext
+                       0u,                                                                                             // VkImageCreateFlags           flags
+                       VK_IMAGE_TYPE_2D,                                                               // VkImageType                          imageType
+                       m_depthFormat,                                                                  // VkFormat                                     depthFormat
+                       { m_renderSize.x(), m_renderSize.y(), 1u },             // VkExtent3D                           externt
+                       1u,                                                                                             // deUint32                                     mipLevels
+                       1u,                                                                                             // deUint32                                     arrayLayers
+                       VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits        samples
+                       VK_IMAGE_TILING_OPTIMAL,                                                // VkImageTiling                        tiling
+                       VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,    // VkImageUsageFlags            usage
+                       VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode
+                       0u,                                                                                             // deUint32                                     queueFamilyIndexCount
+                       DE_NULL,                                                                                // const deUint32*                      pQueueFamilyIndices
+                       VK_IMAGE_LAYOUT_UNDEFINED                                               // VkImageLayout                        initialLayout
+               };
+
+               m_depthImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::HostVisible));
+               m_depthImageView = makeImageView(vk, device, **m_depthImage, VK_IMAGE_VIEW_TYPE_2D, m_depthFormat, m_depthSubresourceRange);
+       }
+
+       // Vertex buffer
+       {
+               const VkDeviceSize bufferSize = vertices.size() * sizeof(vertices[0]);
+               m_vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
+                       vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
+
+               const Allocation& alloc = m_vertexBuffer->getAllocation();
+               deMemcpy(alloc.getHostPtr(), &vertices[0], (size_t)bufferSize);
+               flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bufferSize);
+       }
+
+       // Pipeline layout
+       {
+               m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
+       }
+
+       // Renderpass
+       {
+               const VkAttachmentDescription colorAttachmentDescription =
+               {
+                       (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
+                       m_colorFormat,                                                                          // VkFormat                                                     format;
+                       VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
+                       VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
+                       VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
+                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
+                       VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
+                       VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout;
+                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
+               };
+
+               const VkAttachmentReference colorAttachmentReference =
+               {
+                       0u,                                                                                                     // deUint32                     attachment;
+                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
+               };
+
+               const VkAttachmentReference depthAttachmentReference =
+               {
+                       VK_ATTACHMENT_UNUSED,                                                           // deUint32                     attachment;
+                       VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout        layout;
+               };
+
+               const VkSubpassDescription subpassDescription =
+               {
+                       (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
+                       VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
+                       0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
+                       DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
+                       1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
+                       &colorAttachmentReference,                                                      // const VkAttachmentReference*         pColorAttachments;
+                       DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
+                       &depthAttachmentReference,                                                      // const VkAttachmentReference*         pDepthStencilAttachment;
+                       0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
+                       DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
+               };
+
+               const VkRenderPassCreateInfo renderPassInfo =
+               {
+                       VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
+                       DE_NULL,                                                                                        // const void*                                          pNext;
+                       (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
+                       1u,                                                                                                     // deUint32                                                     attachmentCount;
+                       &colorAttachmentDescription,                                            // const VkAttachmentDescription*       pAttachments;
+                       1u,                                                                                                     // deUint32                                                     subpassCount;
+                       &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
+                       0u,                                                                                                     // deUint32                                                     dependencyCount;
+                       DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
+               };
+
+               m_renderPass = createRenderPass(vk, device, &renderPassInfo);
+       }
+
+       // Framebuffer
+       {
+               const VkImageView attachmentBindInfos[] =
+               {
+                       m_colorImageView.get(),
+                       m_depthImageView.get()
+               };
+
+               const VkFramebufferCreateInfo framebufferInfo = {
+                       VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType                             sType;
+                       DE_NULL,                                                                                // const void*                                 pNext;
+                       (VkFramebufferCreateFlags)0,                                    // VkFramebufferCreateFlags                    flags;
+                       *m_renderPass,                                                                  // VkRenderPass                                renderPass;
+                       DE_LENGTH_OF_ARRAY(attachmentBindInfos),                // uint32_t                                    attachmentCount;
+                       attachmentBindInfos,                                                    // const VkImageView*                          pAttachments;
+                       m_renderSize.x(),                                                               // uint32_t                                    width;
+                       m_renderSize.y(),                                                               // uint32_t                                    height;
+                       1u,                                                                                             // uint32_t                                    layers;
+               };
+
+               m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
+       }
+
+       // Graphics pipeline
+       {
+               const deUint32  vertexStride    = sizeof(Vec4);
+               const VkFormat  vertexFormat    = VK_FORMAT_R32G32B32A32_SFLOAT;
+
+               const VkVertexInputBindingDescription bindingDesc =
+               {
+                       0u,                                                                     // uint32_t                             binding;
+                       vertexStride,                                           // uint32_t                             stride;
+                       VK_VERTEX_INPUT_RATE_VERTEX,            // VkVertexInputRate    inputRate;
+               };
+               const VkVertexInputAttributeDescription attributeDesc =
+               {
+                       0u,                                                                     // uint32_t                     location;
+                       0u,                                                                     // uint32_t                     binding;
+                       vertexFormat,                                           // VkFormat                     format;
+                       0u,                                                                     // uint32_t                     offset;
+               };
+
+               const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                             sType;
+                       DE_NULL,                                                                                                                // const void*                                 pNext;
+                       (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags       flags;
+                       1u,                                                                                                                             // uint32_t                                    vertexBindingDescriptionCount;
+                       &bindingDesc,                                                                                                   // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
+                       1u,                                                                                                                             // uint32_t                                    vertexAttributeDescriptionCount;
+                       &attributeDesc,                                                                                                 // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
+               };
+
+               const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                             sType;
+                       DE_NULL,                                                                                                                // const void*                                 pNext;
+                       (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags     flags;
+                       m_primitiveTopology,                                                                                    // VkPrimitiveTopology                         topology;
+                       VK_FALSE,                                                                                                               // VkBool32                                    primitiveRestartEnable;
+               };
+
+               const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,              // VkStructureType                             sType;
+                       DE_NULL,                                                                                                                // const void*                                 pNext;
+                       (VkPipelineTessellationStateCreateFlags)0,                                              // VkPipelineTessellationStateCreateFlags      flags;
+                       m_numPatchControlPoints,                                                                                // uint32_t                                    patchControlPoints;
+               };
+
+               const VkViewport viewport = makeViewport(
+                       0.0f, 0.0f,
+                       static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
+                       0.0f, 1.0f);
+
+               const VkRect2D scissor = {
+                       makeOffset2D(0, 0),
+                       makeExtent2D(m_renderSize.x(), m_renderSize.y()),
+               };
+
+               const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                             sType;
+                       DE_NULL,                                                                                                // const void*                                 pNext;
+                       (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags          flags;
+                       1u,                                                                                                             // uint32_t                                    viewportCount;
+                       &viewport,                                                                                              // const VkViewport*                           pViewports;
+                       1u,                                                                                                             // uint32_t                                    scissorCount;
+                       &scissor,                                                                                               // const VkRect2D*                             pScissors;
+               };
+
+               const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                          sType;
+                       DE_NULL,                                                                                                                // const void*                              pNext;
+                       (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags  flags;
+                       m_depthClampEnable,                                                                                             // VkBool32                                 depthClampEnable;
+                       VK_FALSE,                                                                                                               // VkBool32                                 rasterizerDiscardEnable;
+                       VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
+                       VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
+                       VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
+                       VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
+                       0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
+                       0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
+                       0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
+                       m_lineWidth,                                                                                                    // float                                                                        lineWidth;
+               };
+
+               const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
+                       DE_NULL,                                                                                                        // const void*                                                          pNext;
+                       (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
+                       VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
+                       VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
+                       0.0f,                                                                                                           // float                                                                        minSampleShading;
+                       DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
+                       VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
+                       VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
+               };
+
+               const VkStencilOpState stencilOpState = makeStencilOpState(
+                       VK_STENCIL_OP_KEEP,             // stencil fail
+                       VK_STENCIL_OP_KEEP,             // depth & stencil pass
+                       VK_STENCIL_OP_KEEP,             // depth only fail
+                       VK_COMPARE_OP_NEVER,    // compare op
+                       0u,                                             // compare mask
+                       0u,                                             // write mask
+                       0u);                                    // reference
+
+               const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
+                       DE_NULL,                                                                                                        // const void*                                                          pNext;
+                       (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
+                       VK_FALSE,                                                                                                       // VkBool32                                                                     depthTestEnable;
+                       VK_FALSE,                                                                                                       // VkBool32                                                                     depthWriteEnable;
+                       VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
+                       VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
+                       VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
+                       stencilOpState,                                                                                         // VkStencilOpState                                                     front;
+                       stencilOpState,                                                                                         // VkStencilOpState                                                     back;
+                       0.0f,                                                                                                           // float                                                                        minDepthBounds;
+                       1.0f,                                                                                                           // float                                                                        maxDepthBounds;
+               };
+
+               const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
+               const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
+               {
+                       m_blendEnable,                                          // VkBool32                                     blendEnable;
+                       VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcColorBlendFactor;
+                       VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstColorBlendFactor;
+                       VK_BLEND_OP_ADD,                                        // VkBlendOp                            colorBlendOp;
+                       VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcAlphaBlendFactor;
+                       VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstAlphaBlendFactor;
+                       VK_BLEND_OP_ADD,                                        // VkBlendOp                            alphaBlendOp;
+                       colorComponentsAll,                                     // VkColorComponentFlags        colorWriteMask;
+               };
+
+               const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
+                       DE_NULL,                                                                                                        // const void*                                                                  pNext;
+                       (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
+                       VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
+                       VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
+                       1u,                                                                                                                     // deUint32                                                                             attachmentCount;
+                       &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
+                       { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
+               };
+
+               // Create shader stages
+
+               std::vector<VkPipelineShaderStageCreateInfo>    shaderStages;
+               VkShaderStageFlags                                                              stageFlags = (VkShaderStageFlags)0;
+
+               DE_ASSERT(shaders.size() <= MAX_NUM_SHADER_MODULES);
+               for (deUint32 shaderNdx = 0; shaderNdx < shaders.size(); ++shaderNdx)
+               {
+                       m_shaderModules[shaderNdx] = createShaderModule(vk, device, *shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
+
+                       const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
+                       {
+                               VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
+                               DE_NULL,                                                                                                // const void*                                                  pNext;
+                               (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
+                               shaders[shaderNdx].stage,                                                               // VkShaderStageFlagBits                                stage;
+                               *m_shaderModules[shaderNdx],                                                    // VkShaderModule                                               module;
+                               "main",                                                                                                 // const char*                                                  pName;
+                               DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
+                       };
+
+                       shaderStages.push_back(pipelineShaderStageInfo);
+                       stageFlags |= shaders[shaderNdx].stage;
+               }
+
+               DE_ASSERT(
+                       (m_primitiveTopology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
+                       (stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
+
+               const bool tessellationEnabled = (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
+               const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
+               {
+                       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                                // VkStructureType                                                                      sType;
+                       DE_NULL,                                                                                                                                // const void*                                                                          pNext;
+                       (VkPipelineCreateFlags)0,                                                                                               // VkPipelineCreateFlags                                                        flags;
+                       static_cast<deUint32>(shaderStages.size()),                                                             // deUint32                                                                                     stageCount;
+                       &shaderStages[0],                                                                                                               // const VkPipelineShaderStageCreateInfo*                       pStages;
+                       &vertexInputStateInfo,                                                                                                  // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
+                       &pipelineInputAssemblyStateInfo,                                                                                // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
+                       (tessellationEnabled ? &pipelineTessellationStateInfo : DE_NULL),               // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
+                       &pipelineViewportStateInfo,                                                                                             // const VkPipelineViewportStateCreateInfo*                     pViewportState;
+                       &pipelineRasterizationStateInfo,                                                                                // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
+                       &pipelineMultisampleStateInfo,                                                                                  // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
+                       &pipelineDepthStencilStateInfo,                                                                                 // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
+                       &pipelineColorBlendStateInfo,                                                                                   // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
+                       DE_NULL,                                                                                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
+                       *m_pipelineLayout,                                                                                                              // VkPipelineLayout                                                                     layout;
+                       *m_renderPass,                                                                                                                  // VkRenderPass                                                                         renderPass;
+                       0u,                                                                                                                                             // deUint32                                                                                     subpass;
+                       DE_NULL,                                                                                                                                // VkPipeline                                                                           basePipelineHandle;
+                       0,                                                                                                                                              // deInt32                                                                                      basePipelineIndex;
+               };
+
+               m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
+       }
+
+       // Record commands
+       {
+               const VkDeviceSize zeroOffset = 0ull;
+
+               beginCommandBuffer(vk, *m_cmdBuffer);
+
+               // Begin render pass
+               {
+                       const VkClearValue      clearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+                       const VkRect2D          renderArea =
+                       {
+                               makeOffset2D(0, 0),
+                               makeExtent2D(m_renderSize.x(), m_renderSize.y())
+                       };
+
+                       const VkRenderPassBeginInfo renderPassBeginInfo = {
+                               VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType         sType;
+                               DE_NULL,                                                                                // const void*             pNext;
+                               *m_renderPass,                                                                  // VkRenderPass            renderPass;
+                               *m_framebuffer,                                                                 // VkFramebuffer           framebuffer;
+                               renderArea,                                                                             // VkRect2D                renderArea;
+                               1u,                                                                                             // uint32_t                clearValueCount;
+                               &clearValue,                                                                    // const VkClearValue*     pClearValues;
+                       };
+
+                       vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+               }
+
+               vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+               vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
+
+               vk.cmdDraw(*m_cmdBuffer, m_numVertices, 1u, 0u, 1u);
+               vk.cmdEndRenderPass(*m_cmdBuffer);
+
+               // Barrier: draw -> copy from image
+               {
+                       const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
+                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
+                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                               **m_colorImage, m_colorSubresourceRange);
+
+                       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
+                               0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+               }
+
+               {
+                       const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), m_imageExtent);
+                       vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, &copyRegion);
+               }
+
+               // Barrier: copy to buffer -> host read
+               {
+                       const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
+                               VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
+                               **m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
+
+                       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
+                               0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
+               }
+
+               endCommandBuffer(vk, *m_cmdBuffer);
+       }
+}
+
+void DrawContext::draw (void)
+{
+       const DeviceInterface&  vk                      = m_context.getDeviceInterface();
+       const VkDevice                  device          = m_context.getDevice();
+       const VkQueue                   queue           = m_context.getUniversalQueue();
+       tcu::TestLog&                   log                     = m_context.getTestContext().getLog();
+
+       submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
+
+       log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
+}
+
+tcu::ConstPixelBufferAccess DrawContext::getColorPixels (void) const
+{
+       const DeviceInterface&  vk                      = m_context.getDeviceInterface();
+       const VkDevice                  device          = m_context.getDevice();
+
+       const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
+       invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE);
+
+       return tcu::ConstPixelBufferAccess(mapVkFormat(m_colorFormat), m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, alloc.getHostPtr());
+}
+} // drawutil
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/vktDrawUtil.hpp b/external/vulkancts/modules/vulkan/vktDrawUtil.hpp
new file mode 100644 (file)
index 0000000..9a74092
--- /dev/null
@@ -0,0 +1,118 @@
+#ifndef _VKTDRAWUTIL_HPP
+#define _VKTDRAWUTIL_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Utility for generating simple work
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+
+#include "deUniquePtr.hpp"
+#include "vkBufferWithMemory.hpp"
+#include "vkImageWithMemory.hpp"
+#include "vkImageUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace drawutil
+{
+
+enum Constants
+{
+       RENDER_SIZE                                                             = 16,
+       RENDER_SIZE_LARGE                                               = 128,
+       NUM_RENDER_PIXELS                                               = RENDER_SIZE * RENDER_SIZE,
+       NUM_PATCH_CONTROL_POINTS                                = 3,
+       MAX_NUM_SHADER_MODULES                                  = 5,
+       MAX_CLIP_DISTANCES                                              = 8,
+       MAX_CULL_DISTANCES                                              = 8,
+       MAX_COMBINED_CLIP_AND_CULL_DISTANCES    = 8,
+};
+
+struct Shader
+{
+       vk::VkShaderStageFlagBits       stage;
+       const vk::ProgramBinary*        binary;
+
+       Shader (const vk::VkShaderStageFlagBits stage_, const vk::ProgramBinary& binary_)
+               : stage         (stage_)
+               , binary        (&binary_)
+       {
+       }
+};
+//! Sets up a graphics pipeline and enables simple draw calls to predefined attachments.
+//! Clip volume uses wc = 1.0, which gives clip coord ranges: x = [-1, 1], y = [-1, 1], z = [0, 1]
+//! Clip coords (-1,-1) map to viewport coords (0, 0).
+class DrawContext
+{
+public:
+                                                                       DrawContext             (Context&                                               context,
+                                                                                                        const std::vector<Shader>&             shaders,
+                                                                                                        const std::vector<tcu::Vec4>&  vertices,
+                                                                                                        const vk::VkPrimitiveTopology  primitiveTopology,
+                                                                                                        const deUint32                                 renderSize                      = static_cast<deUint32>(RENDER_SIZE),
+                                                                                                        const bool                                             depthClampEnable        = false,
+                                                                                                        const bool                                             blendEnable                     = false,
+                                                                                                        const float                                    lineWidth                       = 1.0f);
+
+       void                                                    draw                    (void);
+       tcu::ConstPixelBufferAccess             getColorPixels  (void) const;
+
+private:
+       Context&                                                                        m_context;
+       const vk::VkFormat                                                      m_colorFormat;
+       const vk::VkFormat                                                      m_depthFormat;
+       const vk::VkImageSubresourceRange                       m_colorSubresourceRange;
+       const vk::VkImageSubresourceRange                       m_depthSubresourceRange;
+       const tcu::UVec2                                                        m_renderSize;
+       const vk::VkExtent3D                                            m_imageExtent;
+       const vk::VkPrimitiveTopology                           m_primitiveTopology;
+       const bool                                                                      m_depthClampEnable;
+       const bool                                                                      m_blendEnable;
+       const deUint32                                                          m_numVertices;
+       const float                                                                     m_lineWidth;
+       const deUint32                                                          m_numPatchControlPoints;
+       de::MovePtr<vk::BufferWithMemory>                       m_vertexBuffer;
+       de::MovePtr<vk::ImageWithMemory>                        m_colorImage;
+       de::MovePtr<vk::ImageWithMemory>                        m_depthImage;
+       de::MovePtr<vk::BufferWithMemory>                       m_colorAttachmentBuffer;
+       vk::refdetails::Move<vk::VkImageView>           m_colorImageView;
+       vk::refdetails::Move<vk::VkImageView>           m_depthImageView;
+       vk::refdetails::Move<vk::VkRenderPass>          m_renderPass;
+       vk::refdetails::Move<vk::VkFramebuffer>         m_framebuffer;
+       vk::refdetails::Move<vk::VkPipelineLayout>      m_pipelineLayout;
+       vk::refdetails::Move<vk::VkPipeline>            m_pipeline;
+       vk::refdetails::Move<vk::VkCommandPool>         m_cmdPool;
+       vk::refdetails::Move<vk::VkCommandBuffer>       m_cmdBuffer;
+       vk::refdetails::Move<vk::VkShaderModule>        m_shaderModules[MAX_NUM_SHADER_MODULES];
+
+                                                                       DrawContext             (const DrawContext&);   // "deleted"
+       DrawContext&                                    operator=               (const DrawContext&);   // "deleted"
+};
+std::string getPrimitiveTopologyShortName (const vk::VkPrimitiveTopology topology);
+
+} // drwwutil
+} // vkt
+
+#endif // _VKTDRAWUTIL_HPP