Add tests for inverted depth ranges.
authorAri Suonpaa <ari.suonpaa@siru.fi>
Thu, 14 Sep 2017 08:02:24 +0000 (11:02 +0300)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Tue, 17 Oct 2017 07:49:16 +0000 (03:49 -0400)
Added a new test under draw group that draws a triangle with
interpolated depth values. Viewport minDepth and maxDepth is
configured so that minDepth >= maxDepth. Test is run with both
depth clamp enabled and disabled.

Affects: dEQP-VK.draw.inverted_depth_ranges.*

Components: Vulkan

VK-GL-CTS issue: 616

Change-Id: I68ff5ea420831600a7cfcc0741820802bb745bdc

AndroidGen.mk
android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/draw/CMakeLists.txt
external/vulkancts/modules/vulkan/draw/vktDrawInvertedDepthRangesTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/draw/vktDrawInvertedDepthRangesTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/draw/vktDrawTests.cpp
external/vulkancts/mustpass/1.0.3/vk-default.txt

index fb05620..1da9609 100644 (file)
@@ -87,6 +87,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/draw/vktDrawIndexedTest.cpp \
        external/vulkancts/modules/vulkan/draw/vktDrawIndirectTest.cpp \
        external/vulkancts/modules/vulkan/draw/vktDrawInstancedTests.cpp \
+       external/vulkancts/modules/vulkan/draw/vktDrawInvertedDepthRangesTests.cpp \
        external/vulkancts/modules/vulkan/draw/vktDrawNegativeViewportHeightTests.cpp \
        external/vulkancts/modules/vulkan/draw/vktDrawShaderDrawParametersTests.cpp \
        external/vulkancts/modules/vulkan/draw/vktDrawSimpleTest.cpp \
index 654987d..d44773f 100644 (file)
@@ -204861,6 +204861,14 @@ dEQP-VK.draw.negative_viewport_height.front_cw_cull_none
 dEQP-VK.draw.negative_viewport_height.front_cw_cull_front
 dEQP-VK.draw.negative_viewport_height.front_cw_cull_back
 dEQP-VK.draw.negative_viewport_height.front_cw_cull_both
+dEQP-VK.draw.inverted_depth_ranges.depthclamp_deltazero
+dEQP-VK.draw.inverted_depth_ranges.depthclamp_deltasmall
+dEQP-VK.draw.inverted_depth_ranges.depthclamp_deltaone
+dEQP-VK.draw.inverted_depth_ranges.depthclamp_deltalarge
+dEQP-VK.draw.inverted_depth_ranges.nodepthclamp_deltazero
+dEQP-VK.draw.inverted_depth_ranges.nodepthclamp_deltasmall
+dEQP-VK.draw.inverted_depth_ranges.nodepthclamp_deltaone
+dEQP-VK.draw.inverted_depth_ranges.nodepthclamp_deltalarge
 dEQP-VK.compute.basic.empty_shader
 dEQP-VK.compute.basic.ubo_to_ssbo_single_invocation
 dEQP-VK.compute.basic.ubo_to_ssbo_single_group
index d61a007..eb89c3b 100644 (file)
@@ -9,6 +9,8 @@ set(DEQP_VK_DRAW_SRCS
        vktDrawIndirectTest.cpp
        vktDrawInstancedTests.hpp
        vktDrawInstancedTests.cpp
+       vktDrawInvertedDepthRangesTests.hpp
+       vktDrawInvertedDepthRangesTests.cpp
        vktDrawShaderDrawParametersTests.hpp
        vktDrawShaderDrawParametersTests.cpp
        vktDrawSimpleTest.hpp
diff --git a/external/vulkancts/modules/vulkan/draw/vktDrawInvertedDepthRangesTests.cpp b/external/vulkancts/modules/vulkan/draw/vktDrawInvertedDepthRangesTests.cpp
new file mode 100644 (file)
index 0000000..96f58fa
--- /dev/null
@@ -0,0 +1,484 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2017 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 Inverted depth ranges tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDrawInvertedDepthRangesTests.hpp"
+#include "vktDrawCreateInfoUtil.hpp"
+#include "vktDrawImageObjectUtil.hpp"
+#include "vktDrawBufferObjectUtil.hpp"
+#include "vktTestGroupUtil.hpp"
+#include "vktTestCaseUtil.hpp"
+
+#include "vkPrograms.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkImageUtil.hpp"
+
+#include "tcuVector.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuTestLog.hpp"
+
+#include "deSharedPtr.hpp"
+
+namespace vkt
+{
+namespace Draw
+{
+namespace
+{
+using namespace vk;
+using tcu::Vec4;
+using de::SharedPtr;
+using de::MovePtr;
+
+struct TestParams
+{
+       VkBool32        depthClampEnable;
+       float           minDepth;
+       float           maxDepth;
+};
+
+class InvertedDepthRangesTestInstance : public TestInstance
+{
+public:
+                                                                       InvertedDepthRangesTestInstance (Context& context, const TestParams& params);
+       tcu::TestStatus                                 iterate                                                 (void);
+       tcu::ConstPixelBufferAccess             draw                                                    (const VkViewport viewport);
+       MovePtr<tcu::TextureLevel>              generateReferenceImage                  (void) const;
+
+private:
+       const TestParams                                m_params;
+       const VkFormat                                  m_colorAttachmentFormat;
+       SharedPtr<Image>                                m_colorTargetImage;
+       Move<VkImageView>                               m_colorTargetView;
+       SharedPtr<Buffer>                               m_vertexBuffer;
+       Move<VkRenderPass>                              m_renderPass;
+       Move<VkFramebuffer>                             m_framebuffer;
+       Move<VkPipelineLayout>                  m_pipelineLayout;
+       Move<VkPipeline>                                m_pipeline;
+};
+
+InvertedDepthRangesTestInstance::InvertedDepthRangesTestInstance (Context& context, const TestParams& params)
+       : TestInstance                          (context)
+       , m_params                                      (params)
+       , m_colorAttachmentFormat       (VK_FORMAT_R8G8B8A8_UNORM)
+{
+       const DeviceInterface&  vk              = m_context.getDeviceInterface();
+       const VkDevice                  device  = m_context.getDevice();
+
+       // Vertex data
+       {
+               std::vector<Vec4> vertexData;
+
+               vertexData.push_back(Vec4(-0.8f, -0.8f, -0.2f, 1.0f));  //  0-----2
+               vertexData.push_back(Vec4(-0.8f,  0.8f,  0.0f, 1.0f));  //   |  /
+               vertexData.push_back(Vec4( 0.8f, -0.8f,  1.2f, 1.0f));  //  1|/
+
+               const VkDeviceSize dataSize = vertexData.size() * sizeof(Vec4);
+               m_vertexBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
+                                                                                               m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
+
+               deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), &vertexData[0], static_cast<std::size_t>(dataSize));
+               flushMappedMemoryRange(vk, device, m_vertexBuffer->getBoundMemory().getMemory(), m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
+       }
+
+       // Render pass
+       {
+               const VkExtent3D                targetImageExtent               = { 256, 256, 1 };
+               const VkImageUsageFlags targetImageUsageFlags   = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+
+               const ImageCreateInfo   targetImageCreateInfo(
+                       VK_IMAGE_TYPE_2D,                                               // imageType,
+                       m_colorAttachmentFormat,                                // format,
+                       targetImageExtent,                                              // extent,
+                       1u,                                                                             // mipLevels,
+                       1u,                                                                             // arrayLayers,
+                       VK_SAMPLE_COUNT_1_BIT,                                  // samples,
+                       VK_IMAGE_TILING_OPTIMAL,                                // tiling,
+                       targetImageUsageFlags);                                 // usage,
+
+               m_colorTargetImage = Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator());
+
+               RenderPassCreateInfo    renderPassCreateInfo;
+               renderPassCreateInfo.addAttachment(AttachmentDescription(
+                       m_colorAttachmentFormat,                                // format
+                       VK_SAMPLE_COUNT_1_BIT,                                  // samples
+                       VK_ATTACHMENT_LOAD_OP_LOAD,                             // loadOp
+                       VK_ATTACHMENT_STORE_OP_STORE,                   // storeOp
+                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,                // stencilLoadOp
+                       VK_ATTACHMENT_STORE_OP_DONT_CARE,               // stencilStoreOp
+                       VK_IMAGE_LAYOUT_GENERAL,                                // initialLayout
+                       VK_IMAGE_LAYOUT_GENERAL));                              // finalLayout
+
+               const VkAttachmentReference colorAttachmentReference =
+               {
+                       0u,
+                       VK_IMAGE_LAYOUT_GENERAL
+               };
+
+               renderPassCreateInfo.addSubpass(SubpassDescription(
+                       VK_PIPELINE_BIND_POINT_GRAPHICS,                // pipelineBindPoint
+                       (VkSubpassDescriptionFlags)0,                   // flags
+                       0u,                                                                             // inputAttachmentCount
+                       DE_NULL,                                                                // inputAttachments
+                       1u,                                                                             // colorAttachmentCount
+                       &colorAttachmentReference,                              // colorAttachments
+                       DE_NULL,                                                                // resolveAttachments
+                       AttachmentReference(),                                  // depthStencilAttachment
+                       0u,                                                                             // preserveAttachmentCount
+                       DE_NULL));                                                              // preserveAttachments
+
+               m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
+       }
+
+       // Framebuffer
+       {
+               const ImageViewCreateInfo colorTargetViewInfo (m_colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
+               m_colorTargetView = createImageView(vk, device, &colorTargetViewInfo);
+
+               std::vector<VkImageView> colorAttachments(1);
+               colorAttachments[0] = *m_colorTargetView;
+
+               const FramebufferCreateInfo     framebufferCreateInfo(*m_renderPass, colorAttachments, 256, 256, 1);
+               m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
+       }
+
+       // Vertex input
+
+       const VkVertexInputBindingDescription           vertexInputBindingDescription =
+       {
+               0u,                                                                             // uint32_t             binding;
+               sizeof(Vec4),                                                   // uint32_t             stride;
+               VK_VERTEX_INPUT_RATE_VERTEX,                    // VkVertexInputRate    inputRate;
+       };
+
+       const VkVertexInputAttributeDescription         vertexInputAttributeDescription =
+       {
+               0u,                                                                             // uint32_t    location;
+               0u,                                                                             // uint32_t    binding;
+               VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat    format;
+               0u                                                                              // uint32_t    offset;
+       };
+
+       const PipelineCreateInfo::VertexInputState      vertexInputState = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription,
+                                                                                                                                                                                                               1, &vertexInputAttributeDescription);
+
+       // Graphics pipeline
+
+       const VkRect2D scissor =
+       {
+               { 0,    0       },      // x, y
+               { 256,  256     },      // width, height
+       };
+
+       std::vector<VkDynamicState>             dynamicStates;
+       dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);
+
+       const Unique<VkShaderModule>    vertexModule    (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
+       const Unique<VkShaderModule>    fragmentModule  (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
+
+       const PipelineLayoutCreateInfo  pipelineLayoutCreateInfo;
+       m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
+
+       const PipelineCreateInfo::ColorBlendState::Attachment colorBlendAttachmentState;
+
+       PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
+       pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vertexModule,   "main", VK_SHADER_STAGE_VERTEX_BIT));
+       pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fragmentModule, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
+       pipelineCreateInfo.addState (PipelineCreateInfo::VertexInputState       (vertexInputState));
+       pipelineCreateInfo.addState (PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
+       pipelineCreateInfo.addState (PipelineCreateInfo::ColorBlendState        (1, &colorBlendAttachmentState));
+       pipelineCreateInfo.addState (PipelineCreateInfo::ViewportState          (1, std::vector<VkViewport>(), std::vector<VkRect2D>(1, scissor)));
+       pipelineCreateInfo.addState (PipelineCreateInfo::DepthStencilState      ());
+       pipelineCreateInfo.addState (PipelineCreateInfo::RasterizerState        (
+               m_params.depthClampEnable,      // depthClampEnable
+               VK_FALSE,                                       // rasterizerDiscardEnable
+               VK_POLYGON_MODE_FILL,           // polygonMode
+               VK_CULL_MODE_NONE,                      // cullMode
+               VK_FRONT_FACE_CLOCKWISE,        // frontFace
+               VK_FALSE,                                       // depthBiasEnable
+               0.0f,                                           // depthBiasConstantFactor
+               0.0f,                                           // depthBiasClamp
+               0.0f,                                           // depthBiasSlopeFactor
+               1.0f));                                         // lineWidth
+       pipelineCreateInfo.addState (PipelineCreateInfo::MultiSampleState       ());
+       pipelineCreateInfo.addState (PipelineCreateInfo::DynamicState           (dynamicStates));
+
+       m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
+}
+
+tcu::ConstPixelBufferAccess InvertedDepthRangesTestInstance::draw (const VkViewport viewport)
+{
+       const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
+       const VkDevice                  device                          = m_context.getDevice();
+       const VkQueue                   queue                           = m_context.getUniversalQueue();
+       const deUint32                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
+
+       // Command buffer
+
+       const CmdPoolCreateInfo                 cmdPoolCreateInfo       (queueFamilyIndex);
+       const Unique<VkCommandPool>             cmdPool                         (createCommandPool(vk, device, &cmdPoolCreateInfo));
+       const Unique<VkCommandBuffer>   cmdBuffer                       (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+
+       // Draw
+
+       {
+               const CmdBufferBeginInfo beginInfo;
+               vk.beginCommandBuffer(*cmdBuffer, &beginInfo);
+       }
+
+       vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport);
+
+       {
+               const VkClearColorValue         clearColor                      = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f).color;
+               const ImageSubresourceRange subresourceRange    (VK_IMAGE_ASPECT_COLOR_BIT);
+
+               initialTransitionColor2DImage(vk, *cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL);
+               vk.cmdClearColorImage(*cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
+       }
+       {
+               const VkMemoryBarrier memBarrier =
+               {
+                       VK_STRUCTURE_TYPE_MEMORY_BARRIER,                                                                                               // VkStructureType    sType;
+                       DE_NULL,                                                                                                                                                // const void*        pNext;
+                       VK_ACCESS_TRANSFER_WRITE_BIT,                                                                                                   // VkAccessFlags      srcAccessMask;
+                       VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT              // VkAccessFlags      dstAccessMask;
+               };
+
+               vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
+       }
+       {
+               const VkRect2D                          renderArea              = { { 0, 0 }, { 256, 256 } };
+               const RenderPassBeginInfo       renderPassBegin (*m_renderPass, *m_framebuffer, renderArea);
+
+               vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBegin, VK_SUBPASS_CONTENTS_INLINE);
+       }
+       {
+               const VkDeviceSize      offset  = 0;
+               const VkBuffer          buffer  = m_vertexBuffer->object();
+
+               vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &buffer, &offset);
+       }
+
+       vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+       vk.cmdDraw(*cmdBuffer, 3, 1, 0, 0);
+       vk.cmdEndRenderPass(*cmdBuffer);
+       vk.endCommandBuffer(*cmdBuffer);
+
+       // Submit
+       {
+               const Unique<VkFence>   fence           (createFence(vk, device));
+               const VkSubmitInfo              submitInfo      =
+               {
+                       VK_STRUCTURE_TYPE_SUBMIT_INFO,                          // VkStructureType                sType;
+                       DE_NULL,                                                                        // const void*                    pNext;
+                       0,                                                                                      // uint32_t                       waitSemaphoreCount;
+                       DE_NULL,                                                                        // const VkSemaphore*             pWaitSemaphores;
+                       (const VkPipelineStageFlags*)DE_NULL,           // const VkPipelineStageFlags*    pWaitDstStageMask;
+                       1,                                                                                      // uint32_t                       commandBufferCount;
+                       &cmdBuffer.get(),                                                       // const VkCommandBuffer*         pCommandBuffers;
+                       0,                                                                                      // uint32_t                       signalSemaphoreCount;
+                       DE_NULL                                                                         // const VkSemaphore*             pSignalSemaphores;
+               };
+
+               VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
+               VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), VK_TRUE, ~0ull));
+       }
+
+       // Get result
+       {
+               const VkOffset3D zeroOffset = { 0, 0, 0 };
+               return m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_GENERAL, zeroOffset, 256, 256, VK_IMAGE_ASPECT_COLOR_BIT);
+       }
+}
+
+MovePtr<tcu::TextureLevel> InvertedDepthRangesTestInstance::generateReferenceImage (void) const
+{
+       MovePtr<tcu::TextureLevel>              image                   (new tcu::TextureLevel(mapVkFormat(m_colorAttachmentFormat), 256, 256));
+       const tcu::PixelBufferAccess    access                  (image->getAccess());
+       const Vec4                                              black                   (0.0f, 0.0f, 0.0f, 1.0f);
+       const int                                               p1                              = static_cast<int>(256.0f * 0.2f / 2.0f);
+       const int                                               p2                              = static_cast<int>(256.0f * 1.8f / 2.0f);
+       const float                                             delta                   = 256.0f * 1.6f / 2.0f;
+       const float                                             depthValues[]   = { -0.2f, 0.0f, 1.2f };
+
+       tcu::clear(access, black);
+
+       for (int y = p1; y <= p2; ++y)
+               for (int x = p1; x <  256 - y;  ++x)
+               {
+                       const float     a = static_cast<float>(p2 - x + p1 - y) / delta;
+                       const float     b = static_cast<float>(y - p1) / delta;
+                       const float     c = 1.0f - a - b;
+                       const float     depth = a * depthValues[0] + b * depthValues[1] + c * depthValues[2];
+                       const float     depthClamped = de::clamp(depth, 0.0f, 1.0f);
+                       const float     depthFinal = depthClamped * m_params.maxDepth + (1.0f - depthClamped) * m_params.minDepth;
+
+                       if (m_params.depthClampEnable || (depth >= 0.0f && depth <= 1.0f))
+                               access.setPixel(Vec4(depthFinal, 0.5f, 0.5f, 1.0f), x, y);
+               }
+
+       return image;
+}
+
+tcu::TestStatus InvertedDepthRangesTestInstance::iterate (void)
+{
+       // Check requirements
+
+       if (m_params.depthClampEnable && !m_context.getDeviceFeatures().depthClamp)
+               TCU_THROW(NotSupportedError, "DepthClamp device feature not supported.");
+
+
+       // Set up the viewport and draw
+
+       const VkViewport viewport =
+       {
+               0.0f,                           // float    x;
+               0.0f,                           // float    y;
+               256.0f,                         // float    width;
+               256.0f,                         // float    height;
+               m_params.minDepth,      // float    minDepth;
+               m_params.maxDepth,      // float    maxDepth;
+       };
+
+       const tcu::ConstPixelBufferAccess       resultImage     = draw(viewport);
+
+       // Verify the results
+
+       tcu::TestLog&                           log                             = m_context.getTestContext().getLog();
+       MovePtr<tcu::TextureLevel>      referenceImage  = generateReferenceImage();
+
+       if (!tcu::fuzzyCompare(log, "Image compare", "Image compare", referenceImage->getAccess(), resultImage, 0.02f, tcu::COMPARE_LOG_RESULT))
+               return tcu::TestStatus::fail("Rendered image is incorrect");
+       else
+               return tcu::TestStatus::pass("Pass");
+}
+
+class InvertedDepthRangesTest : public TestCase
+{
+public:
+       InvertedDepthRangesTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
+               : TestCase      (testCtx, name, description)
+               , m_params      (params)
+       {
+       }
+
+       void initPrograms (SourceCollections& programCollection) const
+       {
+               // Vertex shader
+               {
+                       std::ostringstream src;
+                       src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                               << "\n"
+                               << "layout(location = 0) in vec4 in_position;\n"
+                               << "\n"
+                               << "out gl_PerVertex {\n"
+                               << "    vec4  gl_Position;\n"
+                               << "};\n"
+                               << "\n"
+                               << "void main(void)\n"
+                               << "{\n"
+                               << "    gl_Position = in_position;\n"
+                               << "}\n";
+
+                       programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
+               }
+
+               // Fragment shader
+               {
+                       std::ostringstream src;
+                       src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                               << "\n"
+                               << "layout(location = 0) out vec4 out_color;\n"
+                               << "\n"
+                               << "void main(void)\n"
+                               << "{\n"
+                               << "    out_color = vec4(gl_FragCoord.z, 0.5, 0.5, 1.0);\n"
+                               << "}\n";
+
+                       programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
+               }
+       }
+
+       virtual TestInstance* createInstance (Context& context) const
+       {
+               return new InvertedDepthRangesTestInstance(context, m_params);
+       }
+
+private:
+       const TestParams        m_params;
+};
+
+void populateTestGroup (tcu::TestCaseGroup* testGroup)
+{
+       const struct
+       {
+               const char* const       name;
+               VkBool32                        depthClamp;
+       } depthClamp[] =
+       {
+               { "depthclamp",         VK_TRUE         },
+               { "nodepthclamp",       VK_FALSE        },
+       };
+
+       const struct
+       {
+               const char* const       name;
+               float                           delta;
+       } delta[] =
+       {
+               { "deltazero",  0.0f    },
+               { "deltasmall", 0.3f    },
+               { "deltaone",   1.0f    },
+               { "deltalarge", 2.7f    },
+       };
+
+       for (int ndxDepthClamp = 0; ndxDepthClamp < DE_LENGTH_OF_ARRAY(depthClamp); ++ndxDepthClamp)
+       for (int ndxDelta = 0; ndxDelta < DE_LENGTH_OF_ARRAY(delta); ++ndxDelta)
+       {
+               const float minDepth = 0.5f + delta[ndxDelta].delta / 2.0f;
+               const float maxDepth = minDepth - delta[ndxDelta].delta;
+               DE_ASSERT(minDepth >= maxDepth);
+
+               const TestParams params =
+               {
+                       depthClamp[ndxDepthClamp].depthClamp,
+                       minDepth,
+                       maxDepth
+               };
+               std::ostringstream      name;
+               name << depthClamp[ndxDepthClamp].name << "_" << delta[ndxDelta].name;
+
+               testGroup->addChild(new InvertedDepthRangesTest(testGroup->getTestContext(), name.str(), "", params));
+       }
+}
+
+}      // anonymous
+
+tcu::TestCaseGroup*    createInvertedDepthRangesTests (tcu::TestContext& testCtx)
+{
+       return createTestGroup(testCtx, "inverted_depth_ranges", "Inverted depth ranges", populateTestGroup);
+}
+
+}      // Draw
+}      // vkt
diff --git a/external/vulkancts/modules/vulkan/draw/vktDrawInvertedDepthRangesTests.hpp b/external/vulkancts/modules/vulkan/draw/vktDrawInvertedDepthRangesTests.hpp
new file mode 100644 (file)
index 0000000..675d632
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _VKTDRAWINVERTEDDEPTHRANGESTESTS_HPP
+#define _VKTDRAWINVERTEDDEPTHRANGESTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2017 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 Inverted depth ranges tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace Draw
+{
+
+tcu::TestCaseGroup*    createInvertedDepthRangesTests (tcu::TestContext& testCtx);
+
+}      // Draw
+}      // vkt
+
+#endif // _VKTDRAWINVERTEDDEPTHRANGESTESTS_HPP
index 58094cf..7afb290 100644 (file)
@@ -32,6 +32,7 @@
 #include "vktBasicDrawTests.hpp"
 #include "vktDrawShaderDrawParametersTests.hpp"
 #include "vktDrawNegativeViewportHeightTests.hpp"
+#include "vktDrawInvertedDepthRangesTests.hpp"
 
 namespace vkt
 {
@@ -52,6 +53,7 @@ void createChildren (tcu::TestCaseGroup* group)
        group->addChild(new InstancedTests                                      (testCtx));
        group->addChild(new ShaderDrawParametersTests           (testCtx));
        group->addChild(createNegativeViewportHeightTests       (testCtx));
+       group->addChild(createInvertedDepthRangesTests          (testCtx));
 }
 
 } // anonymous
index 5c1e670..67ebad5 100644 (file)
@@ -204846,6 +204846,14 @@ dEQP-VK.draw.negative_viewport_height.front_cw_cull_none
 dEQP-VK.draw.negative_viewport_height.front_cw_cull_front
 dEQP-VK.draw.negative_viewport_height.front_cw_cull_back
 dEQP-VK.draw.negative_viewport_height.front_cw_cull_both
+dEQP-VK.draw.inverted_depth_ranges.depthclamp_deltazero
+dEQP-VK.draw.inverted_depth_ranges.depthclamp_deltasmall
+dEQP-VK.draw.inverted_depth_ranges.depthclamp_deltaone
+dEQP-VK.draw.inverted_depth_ranges.depthclamp_deltalarge
+dEQP-VK.draw.inverted_depth_ranges.nodepthclamp_deltazero
+dEQP-VK.draw.inverted_depth_ranges.nodepthclamp_deltasmall
+dEQP-VK.draw.inverted_depth_ranges.nodepthclamp_deltaone
+dEQP-VK.draw.inverted_depth_ranges.nodepthclamp_deltalarge
 dEQP-VK.compute.basic.empty_shader
 dEQP-VK.compute.basic.ubo_to_ssbo_single_invocation
 dEQP-VK.compute.basic.ubo_to_ssbo_single_group