Add rendering verification to dEQP-VK.api.smoke.*triangle
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiSmokeTests.cpp
index 58037dd..27c1bfb 100644 (file)
@@ -4,28 +4,17 @@
  *
  * Copyright (c) 2015 Google Inc.
  *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and/or associated documentation files (the
- * "Materials"), to deal in the Materials without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Materials, and to
- * permit persons to whom the Materials are furnished to do so, subject to
- * the following conditions:
+ * 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
  *
- * The above copyright notice(s) and this permission notice shall be
- * included in all copies or substantial portions of the Materials.
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
- * The Materials are Confidential Information as defined by the
- * Khronos Membership Agreement until designated non-confidential by
- * Khronos, at which point this condition clause shall be removed.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ * 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
 #include "vkDeviceUtil.hpp"
 #include "vkPrograms.hpp"
 #include "vkTypeUtil.hpp"
+#include "vkImageUtil.hpp"
 
 #include "tcuTestLog.hpp"
 #include "tcuFormatUtil.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuImageCompare.hpp"
+
+#include "rrRenderer.hpp"
 
 #include "deUniquePtr.hpp"
 
@@ -78,11 +72,12 @@ tcu::TestStatus createSamplerTest (Context& context)
                        0u,                                                                                     // flags
                        VK_FILTER_NEAREST,                                                      // magFilter
                        VK_FILTER_NEAREST,                                                      // minFilter
-                       VK_SAMPLER_MIPMAP_MODE_BASE,                            // mipmapMode
+                       VK_SAMPLER_MIPMAP_MODE_NEAREST,                         // mipmapMode
                        VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // addressModeU
                        VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // addressModeV
                        VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // addressModeW
                        0.0f,                                                                           // mipLodBias
+                       VK_FALSE,                                                                       // anisotropyEnable
                        1.0f,                                                                           // maxAnisotropy
                        DE_FALSE,                                                                       // compareEnable
                        VK_COMPARE_OP_ALWAYS,                                           // compareOp
@@ -106,7 +101,7 @@ tcu::TestStatus createSamplerTest (Context& context)
 void createShaderProgs (SourceCollections& dst)
 {
        dst.glslSources.add("test") << glu::VertexSource(
-               "#version 300 es\n"
+               "#version 310 es\n"
                "in highp vec4 a_position;\n"
                "void main (void) { gl_Position = a_position; }\n");
 }
@@ -131,12 +126,12 @@ void createTriangleAsmProgs (SourceCollections& dst)
                "                OpName %4 \"main\"\n"
                "                OpName %10 \"gl_Position\"\n"
                "                OpName %12 \"a_position\"\n"
-               "                OpName %16 \"gl_VertexID\"\n"
-               "                OpName %17 \"gl_InstanceID\"\n"
+               "                OpName %16 \"gl_VertexIndex\"\n"
+               "                OpName %17 \"gl_InstanceIndex\"\n"
                "                OpDecorate %10 BuiltIn Position\n"
                "                OpDecorate %12 Location 0\n"
-               "                OpDecorate %16 BuiltIn VertexId\n"
-               "                OpDecorate %17 BuiltIn InstanceId\n"
+               "                OpDecorate %16 BuiltIn VertexIndex\n"
+               "                OpDecorate %17 BuiltIn InstanceIndex\n"
                "%2 =    OpTypeVoid\n"
                "%3 =    OpTypeFunction %2\n"
                "%7 =    OpTypeFloat 32\n"
@@ -189,15 +184,78 @@ void createTriangleAsmProgs (SourceCollections& dst)
 void createTriangleProgs (SourceCollections& dst)
 {
        dst.glslSources.add("vert") << glu::VertexSource(
-               "#version 300 es\n"
+               "#version 310 es\n"
                "layout(location = 0) in highp vec4 a_position;\n"
                "void main (void) { gl_Position = a_position; }\n");
        dst.glslSources.add("frag") << glu::FragmentSource(
-               "#version 300 es\n"
+               "#version 310 es\n"
                "layout(location = 0) out lowp vec4 o_color;\n"
                "void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
 }
 
+class RefVertexShader : public rr::VertexShader
+{
+public:
+       RefVertexShader (void)
+               : rr::VertexShader(1, 0)
+       {
+               m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
+       }
+
+       void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
+       {
+               for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
+               {
+                       packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0],
+                                                                                                                                        packets[packetNdx]->instanceNdx,
+                                                                                                                                        packets[packetNdx]->vertexNdx);
+               }
+       }
+};
+
+class RefFragmentShader : public rr::FragmentShader
+{
+public:
+       RefFragmentShader (void)
+               : rr::FragmentShader(0, 1)
+       {
+               m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
+       }
+
+       void shadeFragments (rr::FragmentPacket*, const int numPackets, const rr::FragmentShadingContext& context) const
+       {
+               for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
+               {
+                       for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
+                       {
+                               rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f));
+                       }
+               }
+       }
+};
+
+void renderReferenceTriangle (const tcu::PixelBufferAccess& dst, const tcu::Vec4 (&vertices)[3])
+{
+       const RefVertexShader                                   vertShader;
+       const RefFragmentShader                                 fragShader;
+       const rr::Program                                               program                 (&vertShader, &fragShader);
+       const rr::MultisamplePixelBufferAccess  colorBuffer             = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(dst);
+       const rr::RenderTarget                                  renderTarget    (colorBuffer);
+       const rr::RenderState                                   renderState             ((rr::ViewportState(colorBuffer)));
+       const rr::Renderer                                              renderer;
+       const rr::VertexAttrib                                  vertexAttribs[] =
+       {
+               rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, vertices[0].getPtr())
+       };
+
+       renderer.draw(rr::DrawCommand(renderState,
+                                                                 renderTarget,
+                                                                 program,
+                                                                 DE_LENGTH_OF_ARRAY(vertexAttribs),
+                                                                 &vertexAttribs[0],
+                                                                 rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, DE_LENGTH_OF_ARRAY(vertices), 0)));
+}
+
 tcu::TestStatus renderTriangleTest (Context& context)
 {
        const VkDevice                                                  vkDevice                                = context.getDevice();
@@ -206,6 +264,8 @@ tcu::TestStatus renderTriangleTest (Context& context)
        const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
        SimpleAllocator                                                 memAlloc                                (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
        const tcu::IVec2                                                renderSize                              (256, 256);
+       const VkFormat                                                  colorFormat                             = VK_FORMAT_R8G8B8A8_UNORM;
+       const tcu::Vec4                                                 clearColor                              (0.125f, 0.25f, 0.75f, 1.0f);
 
        const tcu::Vec4                                                 vertices[]                              =
        {
@@ -254,7 +314,7 @@ tcu::TestStatus renderTriangleTest (Context& context)
                0u,                                                                                                                                             // flags
                VK_IMAGE_TYPE_2D,                                                                                                               // imageType
                VK_FORMAT_R8G8B8A8_UNORM,                                                                                               // format
-               { renderSize.x(), renderSize.y(), 1 },                                                                  // extent
+               { (deUint32)renderSize.x(), (deUint32)renderSize.y(), 1 },                              // extent
                1u,                                                                                                                                             // mipLevels
                1u,                                                                                                                                             // arraySize
                VK_SAMPLE_COUNT_1_BIT,                                                                                                  // samples
@@ -432,8 +492,8 @@ tcu::TestStatus renderTriangleTest (Context& context)
                        0u,                                                                                                                     // y
                },                                                                                                                      // offset
                {
-                       renderSize.x(),                                                                                         // width
-                       renderSize.y(),                                                                                         // height
+                       (deUint32)renderSize.x(),                                                                       // width
+                       (deUint32)renderSize.y(),                                                                       // height
                },                                                                                                                      // extent;
        };
        const VkPipelineViewportStateCreateInfo         viewportParams                  =
@@ -531,14 +591,6 @@ tcu::TestStatus renderTriangleTest (Context& context)
                &attBlendParams,                                                                                        // pAttachments
                { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // blendConstants[4]
        };
-       const VkPipelineDynamicStateCreateInfo  dynamicStateInfo                =
-       {
-               VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,   // sType
-               DE_NULL,                                                                                                // pNext
-               0u,                                                                                                             // flags
-               0u,                                                                                                             // dynamicStateCount
-               DE_NULL                                                                                                 // pDynamicStates
-       };
        const VkGraphicsPipelineCreateInfo              pipelineParams                  =
        {
                VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                // sType
@@ -554,7 +606,7 @@ tcu::TestStatus renderTriangleTest (Context& context)
                &multisampleParams,                                                                             // pMultisampleState
                &depthStencilParams,                                                                    // pDepthStencilState
                &blendParams,                                                                                   // pColorBlendState
-               &dynamicStateInfo,                                                                              // pDynamicState
+               (const VkPipelineDynamicStateCreateInfo*)DE_NULL,               // pDynamicState
                *pipelineLayout,                                                                                // layout
                *renderPass,                                                                                    // renderPass
                0u,                                                                                                             // subpass
@@ -604,12 +656,7 @@ tcu::TestStatus renderTriangleTest (Context& context)
                VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // sType
                DE_NULL,                                                                                                // pNext
                0u,                                                                                                             // flags
-               DE_NULL,                                                                                                // renderPass
-               0u,                                                                                                             // subpass
-               DE_NULL,                                                                                                // framebuffer
-               VK_FALSE,                                                                                               // occlusionQueryEnable
-               (VkQueryControlFlags)0u,                                                                // queryFlags
-               (VkQueryPipelineStatisticFlags)0u,                                              // pipelineStatistics
+               (const VkCommandBufferInheritanceInfo*)DE_NULL,
        };
 
        // Record commands
@@ -643,19 +690,24 @@ tcu::TestStatus renderTriangleTest (Context& context)
                                1u,                                                                                     // layerCount
                        }                                                                                       // subresourceRange
                };
-               const void*                             barriers[]                              = { &vertFlushBarrier, &colorAttBarrier };
-               vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, DE_FALSE, (deUint32)DE_LENGTH_OF_ARRAY(barriers), barriers);
+               vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &colorAttBarrier);
        }
 
        {
-               const VkClearValue                      clearValue              = makeClearValueColorF32(0.125f, 0.25f, 0.75f, 1.0f);
+               const VkClearValue                      clearValue              = makeClearValueColorF32(clearColor[0],
+                                                                                                                                                        clearColor[1],
+                                                                                                                                                        clearColor[2],
+                                                                                                                                                        clearColor[3]);
                const VkRenderPassBeginInfo     passBeginParams =
                {
                        VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                       // sType
                        DE_NULL,                                                                                        // pNext
                        *renderPass,                                                                            // renderPass
                        *framebuffer,                                                                           // framebuffer
-                       { { 0, 0 }, { renderSize.x(), renderSize.y() } },       // renderArea
+                       {
+                               { 0, 0 },
+                               { (deUint32)renderSize.x(), (deUint32)renderSize.y() }
+                       },                                                                                                      // renderArea
                        1u,                                                                                                     // clearValueCount
                        &clearValue,                                                                            // pClearValues
                };
@@ -690,8 +742,7 @@ tcu::TestStatus renderTriangleTest (Context& context)
                                1u,                                                                                     // arraySize
                        }                                                                                       // subresourceRange
                };
-               const void*                             barriers[]                              = { &renderFinishBarrier };
-               vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, DE_FALSE, (deUint32)DE_LENGTH_OF_ARRAY(barriers), barriers);
+               vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &renderFinishBarrier);
        }
 
        {
@@ -707,7 +758,11 @@ tcu::TestStatus renderTriangleTest (Context& context)
                                1u,                                                                             // layerCount
                        },                                                                              // imageSubresource
                        { 0u, 0u, 0u },                                                 // imageOffset
-                       { renderSize.x(), renderSize.y(), 1u }  // imageExtent
+                       {
+                               (deUint32)renderSize.x(),
+                               (deUint32)renderSize.y(),
+                               1u
+                       }                                                                               // imageExtent
                };
                vk.cmdCopyImageToBuffer(*cmdBuf, *image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, &copyParams);
        }
@@ -725,8 +780,7 @@ tcu::TestStatus renderTriangleTest (Context& context)
                        0u,                                                                                     // offset
                        imageSizeBytes                                                          // size
                };
-               const void*                             barriers[]                              = { &copyFinishBarrier };
-               vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, DE_FALSE, (deUint32)DE_LENGTH_OF_ARRAY(barriers), barriers);
+               vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &copyFinishBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
        }
 
        VK_CHECK(vk.endCommandBuffer(*cmdBuf));
@@ -761,6 +815,7 @@ tcu::TestStatus renderTriangleTest (Context& context)
                        DE_NULL,                                                                // pNext
                        0u,                                                                             // waitSemaphoreCount
                        DE_NULL,                                                                // pWaitSemaphores
+                       (const VkPipelineStageFlags*)DE_NULL,
                        1u,                                                                             // commandBufferCount
                        &cmdBuf.get(),                                                  // pCommandBuffers
                        0u,                                                                             // signalSemaphoreCount
@@ -772,9 +827,10 @@ tcu::TestStatus renderTriangleTest (Context& context)
                VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), DE_TRUE, ~0ull));
        }
 
-       // Log image
+       // Read results, render reference, compare
        {
-               const VkMappedMemoryRange       range           =
+               const tcu::TextureFormat                        tcuFormat               = vk::mapVkFormat(colorFormat);
+               const VkMappedMemoryRange                       range                   =
                {
                        VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  // sType
                        DE_NULL,                                                                // pNext
@@ -782,10 +838,31 @@ tcu::TestStatus renderTriangleTest (Context& context)
                        0,                                                                              // offset
                        imageSizeBytes,                                                 // size
                };
-               void*                                           imagePtr        = readImageBufferMemory->getHostPtr();
+               const tcu::ConstPixelBufferAccess       resultAccess    (tcuFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
 
                VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
-               context.getTestContext().getLog() << TestLog::Image("Result", "Result", tcu::ConstPixelBufferAccess(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), renderSize.x(), renderSize.y(), 1, imagePtr));
+
+               {
+                       tcu::TextureLevel       refImage                (tcuFormat, renderSize.x(), renderSize.y());
+                       const tcu::UVec4        threshold               (0u);
+                       const tcu::IVec3        posDeviation    (1,1,0);
+
+                       tcu::clear(refImage.getAccess(), clearColor);
+                       renderReferenceTriangle(refImage.getAccess(), vertices);
+
+                       if (tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(),
+                                                                                                                 "ComparisonResult",
+                                                                                                                 "Image comparison result",
+                                                                                                                 refImage.getAccess(),
+                                                                                                                 resultAccess,
+                                                                                                                 threshold,
+                                                                                                                 posDeviation,
+                                                                                                                 false,
+                                                                                                                 tcu::COMPARE_LOG_RESULT))
+                               return tcu::TestStatus::pass("Rendering succeeded");
+                       else
+                               return tcu::TestStatus::fail("Image comparison failed");
+               }
        }
 
        return tcu::TestStatus::pass("Rendering succeeded");