Extend shader built-in variable tests
authorPeter Siket <ps.szeged@partner.samsung.com>
Thu, 4 Aug 2016 22:21:14 +0000 (15:21 -0700)
committerPeter Siket <ps.szeged@partner.samsung.com>
Fri, 26 Aug 2016 09:04:55 +0000 (11:04 +0200)
This branch extends the shader builtin tests, with additional tests
ported from the GLES2 tests.

These test are ported:

dEQP-GLES2.functional.shaders.builtin_variable.fragcoord_xyz
dEQP-GLES2.functional.shaders.builtin_variable.fragcoord_w
dEQP-GLES2.functional.shaders.builtin_variable.pointcoord

Besides this additional test group
(dEQP-VK.glsl.builtin_var.input_variations) is added for testing
combinations of different shader input types. (#300)

Change-Id: I8cb6f2197f87b28c1e13335b9ab55ab59e92d665

android/cts/master/com.drawelements.deqp.vk.xml
android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.cpp
external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.hpp
external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp
external/vulkancts/mustpass/1.0.1/vk-default.txt

index 2021dda..91470ff 100644 (file)
                                        </TestSuite>
                                </TestSuite>
                        </TestSuite>
-                       <TestCase name="builtin_var">
-                               <Test name="gl_frontfacing">
-                                       <TestInstance/>
-                               </Test>
-                       </TestCase>
+                       <TestSuite name="builtin_var">
+                               <TestCase name="simple">
+                                       <Test name="frontfacing">
+                                               <TestInstance/>
+                                       </Test>
+                                       <Test name="fragcoord_xyz">
+                                               <TestInstance/>
+                                       </Test>
+                                       <Test name="fragcoord_w">
+                                               <TestInstance/>
+                                       </Test>
+                                       <Test name="pointcoord">
+                                               <TestInstance/>
+                                       </Test>
+                               </TestCase>
+                               <TestCase name="input_variations">
+                                       <Test name="input_none">
+                                               <TestInstance/>
+                                       </Test>
+                                       <Test name="input_builtin">
+                                               <TestInstance/>
+                                       </Test>
+                                       <Test name="input_varying">
+                                               <TestInstance/>
+                                       </Test>
+                                       <Test name="input_builtin_varying">
+                                               <TestInstance/>
+                                       </Test>
+                                       <Test name="input_constant">
+                                               <TestInstance/>
+                                       </Test>
+                                       <Test name="input_builtin_constant">
+                                               <TestInstance/>
+                                       </Test>
+                                       <Test name="input_varying_constant">
+                                               <TestInstance/>
+                                       </Test>
+                                       <Test name="input_builtin_varying_constant">
+                                               <TestInstance/>
+                                       </Test>
+                               </TestCase>
+                       </TestSuite>
                        <TestSuite name="builtin">
                                <TestSuite name="function">
                                        <TestSuite name="common">
index bf57c26..7f36dd7 100644 (file)
@@ -92022,7 +92022,18 @@ dEQP-VK.glsl.texture_gather.offsets.min_required_offset.2d_array.depth32f.base_l
 dEQP-VK.glsl.texture_gather.offsets.min_required_offset.2d_array.depth32f.base_level.sparse_level_1
 dEQP-VK.glsl.texture_gather.offsets.min_required_offset.2d_array.depth32f.base_level.level_2
 dEQP-VK.glsl.texture_gather.offsets.min_required_offset.2d_array.depth32f.base_level.sparse_level_2
-dEQP-VK.glsl.builtin_var.gl_frontfacing
+dEQP-VK.glsl.builtin_var.simple.frontfacing
+dEQP-VK.glsl.builtin_var.simple.fragcoord_xyz
+dEQP-VK.glsl.builtin_var.simple.fragcoord_w
+dEQP-VK.glsl.builtin_var.simple.pointcoord
+dEQP-VK.glsl.builtin_var.input_variations.input_none
+dEQP-VK.glsl.builtin_var.input_variations.input_builtin
+dEQP-VK.glsl.builtin_var.input_variations.input_varying
+dEQP-VK.glsl.builtin_var.input_variations.input_builtin_varying
+dEQP-VK.glsl.builtin_var.input_variations.input_constant
+dEQP-VK.glsl.builtin_var.input_variations.input_builtin_constant
+dEQP-VK.glsl.builtin_var.input_variations.input_varying_constant
+dEQP-VK.glsl.builtin_var.input_variations.input_builtin_varying_constant
 dEQP-VK.glsl.builtin.function.common.abs.float_mediump_vertex
 dEQP-VK.glsl.builtin.function.common.abs.float_mediump_fragment
 dEQP-VK.glsl.builtin.function.common.abs.float_mediump_geometry
index e7aa41f..fde3cbb 100644 (file)
@@ -773,6 +773,7 @@ void ShaderRenderCaseInstance::setup (void)
        m_vertexAttributeDescription.clear();
        m_vertexBuffers.clear();
        m_vertexBufferAllocs.clear();
+       m_pushConstantRanges.clear();
 }
 
 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr)
@@ -2081,6 +2082,19 @@ void ShaderRenderCaseInstance::useSampler (deUint32 bindingLocation, deUint32 te
        createSamplerUniform(bindingLocation, textureType, textureBinding.getParameters().initialization, texFormat, texSize, textureData, refSampler, mipLevels, arrayLayers, textureParams);
 }
 
+void ShaderRenderCaseInstance::setPushConstantRanges (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges)
+{
+       m_pushConstantRanges.clear();
+       for (deUint32 i = 0; i < rangeCount; ++i)
+       {
+               m_pushConstantRanges.push_back(pcRanges[i]);
+       }
+}
+
+void ShaderRenderCaseInstance::updatePushConstants (vk::VkCommandBuffer, vk::VkPipelineLayout)
+{
+}
+
 void ShaderRenderCaseInstance::createSamplerUniform (deUint32                                          bindingLocation,
                                                                                                         TextureBinding::Type                   textureType,
                                                                                                         TextureBinding::Init                   textureInit,
@@ -2300,6 +2314,15 @@ void ShaderRenderCaseInstance::render (deUint32                          numVertices,
                                                                           const deUint16*              indices,
                                                                           const tcu::Vec4&             constCoords)
 {
+       render(numVertices, numTriangles * 3, indices, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, constCoords);
+}
+
+void ShaderRenderCaseInstance::render (deUint32                                numVertices,
+                                                                          deUint32                             numIndices,
+                                                                          const deUint16*              indices,
+                                                                          VkPrimitiveTopology  topology,
+                                                                          const tcu::Vec4&             constCoords)
+{
        const VkDevice                                                                          vkDevice                                        = getDevice();
        const DeviceInterface&                                                          vk                                                      = getDeviceInterface();
        const VkQueue                                                                           queue                                           = getUniversalQueue();
@@ -2317,8 +2340,8 @@ void ShaderRenderCaseInstance::render (deUint32                           numVertices,
        vk::Move<vk::VkPipeline>                                                        graphicsPipeline;
        vk::Move<vk::VkShaderModule>                                            vertexShaderModule;
        vk::Move<vk::VkShaderModule>                                            fragmentShaderModule;
-       vk::Move<vk::VkBuffer>                                                          indiceBuffer;
-       de::MovePtr<vk::Allocation>                                                     indiceBufferAlloc;
+       vk::Move<vk::VkBuffer>                                                          indexBuffer;
+       de::MovePtr<vk::Allocation>                                                     indexBufferAlloc;
        vk::Move<vk::VkDescriptorSetLayout>                                     descriptorSetLayout;
        vk::Move<vk::VkDescriptorPool>                                          descriptorPool;
        vk::Move<vk::VkDescriptorSet>                                           descriptorSet;
@@ -2612,6 +2635,7 @@ void ShaderRenderCaseInstance::render (deUint32                           numVertices,
 
        // Create pipeline layout
        {
+               const VkPushConstantRange* const                                pcRanges                                        = m_pushConstantRanges.empty() ? DE_NULL : &m_pushConstantRanges[0];
                const VkPipelineLayoutCreateInfo                                pipelineLayoutParams            =
                {
                        VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
@@ -2619,8 +2643,8 @@ void ShaderRenderCaseInstance::render (deUint32                           numVertices,
                        (VkPipelineLayoutCreateFlags)0,
                        1u,                                                                                                     // deUint32                                             descriptorSetCount;
                        &*descriptorSetLayout,                                                          // const VkDescriptorSetLayout* pSetLayouts;
-                       0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
-                       DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
+                       deUint32(m_pushConstantRanges.size()),                          // deUint32                                             pushConstantRangeCount;
+                       pcRanges                                                                                        // const VkPushConstantRange*   pPushConstantRanges;
                };
 
                pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
@@ -2679,7 +2703,7 @@ void ShaderRenderCaseInstance::render (deUint32                           numVertices,
                        VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType              sType;
                        DE_NULL,                                                                                                                // const void*                  pNext;
                        (VkPipelineInputAssemblyStateCreateFlags)0,
-                       VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology  topology;
+                       topology,                                                                                                               // VkPrimitiveTopology  topology;
                        false                                                                                                                   // VkBool32                             primitiveRestartEnable;
                };
 
@@ -2800,28 +2824,29 @@ void ShaderRenderCaseInstance::render (deUint32                         numVertices,
        }
 
        // Create vertex indices buffer
+       if (numIndices != 0)
        {
-               const VkDeviceSize                                                              indiceBufferSize                        = numTriangles * 3 * sizeof(deUint16);
-               const VkBufferCreateInfo                                                indiceBufferParams                      =
+               const VkDeviceSize                                                              indexBufferSize                 = numIndices * sizeof(deUint16);
+               const VkBufferCreateInfo                                                indexBufferParams               =
                {
                        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
                        DE_NULL,                                                                        // const void*                  pNext;
                        0u,                                                                                     // VkBufferCreateFlags  flags;
-                       indiceBufferSize,                                                       // VkDeviceSize                 size;
+                       indexBufferSize,                                                        // VkDeviceSize                 size;
                        VK_BUFFER_USAGE_INDEX_BUFFER_BIT,                       // VkBufferUsageFlags   usage;
                        VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
                        1u,                                                                                     // deUint32                             queueFamilyCount;
                        &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
                };
 
-               indiceBuffer            = createBuffer(vk, vkDevice, &indiceBufferParams);
-               indiceBufferAlloc       = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *indiceBuffer), MemoryRequirement::HostVisible);
+               indexBuffer                     = createBuffer(vk, vkDevice, &indexBufferParams);
+               indexBufferAlloc        = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), MemoryRequirement::HostVisible);
 
-               VK_CHECK(vk.bindBufferMemory(vkDevice, *indiceBuffer, indiceBufferAlloc->getMemory(), indiceBufferAlloc->getOffset()));
+               VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset()));
 
                // Load vertice indices into buffer
-               deMemcpy(indiceBufferAlloc->getHostPtr(), indices, (size_t)indiceBufferSize);
-               flushMappedMemoryRange(vk, vkDevice, indiceBufferAlloc->getMemory(), indiceBufferAlloc->getOffset(), indiceBufferSize);
+               deMemcpy(indexBufferAlloc->getHostPtr(), indices, (size_t)indexBufferSize);
+               flushMappedMemoryRange(vk, vkDevice, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset(), indexBufferSize);
        }
 
        // Create command pool
@@ -2926,11 +2951,10 @@ void ShaderRenderCaseInstance::render (deUint32                         numVertices,
                }
 
                vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
-
+               updatePushConstants(*cmdBuffer, *pipelineLayout);
                vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
                if (!m_uniformInfos.empty())
                        vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
-               vk.cmdBindIndexBuffer(*cmdBuffer, *indiceBuffer, 0, VK_INDEX_TYPE_UINT16);
 
                const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
                const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
@@ -2942,7 +2966,13 @@ void ShaderRenderCaseInstance::render (deUint32                          numVertices,
                }
 
                vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
-               vk.cmdDrawIndexed(*cmdBuffer, numTriangles * 3, 1, 0, 0, 0);
+               if (numIndices != 0)
+               {
+                       vk.cmdBindIndexBuffer(*cmdBuffer, *indexBuffer, 0, VK_INDEX_TYPE_UINT16);
+                       vk.cmdDrawIndexed(*cmdBuffer, numIndices, 1, 0, 0, 0);
+               }
+               else
+                       vk.cmdDraw(*cmdBuffer, numVertices,  1, 0, 1);
 
                vk.cmdEndRenderPass(*cmdBuffer);
                VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
index 5411736..71cbfbf 100644 (file)
@@ -469,6 +469,8 @@ public:
                                                                                                                                                                        deUint32                                textureId);
 
        static const tcu::Vec4                                                          getDefaultConstCoords           (void) { return tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f); }
+       void                                                                                            setPushConstantRanges           (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges);
+       virtual void                                                                            updatePushConstants                     (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout);
 
 protected:
                                                                                                                ShaderRenderCaseInstance        (Context&                                       context,
@@ -487,6 +489,12 @@ protected:
                                                                                                                                                                         const deUint16*                        indices,
                                                                                                                                                                         const tcu::Vec4&                       constCoords             = getDefaultConstCoords());
 
+       void                                                                                            render                                          (deUint32                                       numVertices,
+                                                                                                                                                                        deUint32                                       numIndices,
+                                                                                                                                                                        const deUint16*                        indices,
+                                                                                                                                                                        vk::VkPrimitiveTopology        topology,
+                                                                                                                                                                        const tcu::Vec4&                       constCoords             = getDefaultConstCoords());
+
        const tcu::TextureLevel&                                                        getResultImage                          (void) const { return m_resultImage; }
 
        const tcu::UVec2                                                                        getViewportSize                         (void) const;
@@ -642,6 +650,7 @@ private:
        std::vector<AllocationSp>                                                       m_vertexBufferAllocs;
 
        vk::VkSampleCountFlagBits                                                       m_sampleCount;
+       std::vector<vk::VkPushConstantRange>                            m_pushConstantRanges;
 
        // Wrapper functions around m_context calls to support sparse cases.
        vk::VkDevice                                                                            getDevice                                               (void) const;
index 79fd52f..4f89e18 100644 (file)
 #include "tcuStringTemplate.hpp"
 #include "tcuTextureUtil.hpp"
 
+#include "deMath.h"
+#include "deRandom.hpp"
+
+#include <map>
+
 using namespace std;
 using namespace tcu;
 using namespace vk;
@@ -106,7 +111,7 @@ void BuiltinGlFrontFacingCaseInstance::setupDefaultInputs (void)
                -1.0f,  1.0f, 0.0f, 1.0f
        };
 
-       addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)sizeof(float) * 4, 6, vertices);
+       addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
 }
 
 class BuiltinGlFrontFacingCase : public TestCase
@@ -159,15 +164,655 @@ TestInstance* BuiltinGlFrontFacingCase::createInstance (Context& context) const
        return new BuiltinGlFrontFacingCaseInstance(context);
 }
 
+class BuiltinGlFragCoordXYZCaseInstance : public ShaderRenderCaseInstance
+{
+public:
+                                       BuiltinGlFragCoordXYZCaseInstance       (Context& context);
+
+       TestStatus              iterate                                                         (void);
+       virtual void    setupDefaultInputs                                      (void);
+};
+
+BuiltinGlFragCoordXYZCaseInstance::BuiltinGlFragCoordXYZCaseInstance (Context& context)
+       : ShaderRenderCaseInstance      (context)
+{
+}
+
+TestStatus BuiltinGlFragCoordXYZCaseInstance::iterate (void)
+{
+       const UVec2             viewportSize    = getViewportSize();
+       const int               width                   = viewportSize.x();
+       const int               height                  = viewportSize.y();
+       const tcu::Vec3 scale                   (1.f / float(width), 1.f / float(height), 1.0f);
+       const tcu::RGBA threshold               (2, 2, 2, 2);
+       Surface                 resImage                (width, height);
+       Surface                 refImage                (width, height);
+       bool                    compareOk               = false;
+       const deUint16  indices[6]              =
+       {
+               2, 1, 3,
+               0, 1, 2,
+       };
+
+       setup();
+       addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale);
+
+       render(4, 2, indices);
+       copy(resImage.getAccess(), getResultImage().getAccess());
+
+       // Reference image
+       for (int y = 0; y < refImage.getHeight(); y++)
+       {
+               for (int x = 0; x < refImage.getWidth(); x++)
+               {
+                       const float     xf                      = (float(x)+.5f) / float(refImage.getWidth());
+                       const float     yf                      = (float(refImage.getHeight()-y-1)+.5f) / float(refImage.getHeight());
+                       const float     z                       = (xf + yf) / 2.0f;
+                       const Vec3      fragCoord       (float(x)+.5f, float(y)+.5f, z);
+                       const Vec3      scaledFC        = fragCoord*scale;
+                       const Vec4      color           (scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f);
+
+                       refImage.setPixel(x, y, RGBA(color));
+               }
+       }
+
+       compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
+
+       if (compareOk)
+               return TestStatus::pass("Result image matches reference");
+       else
+               return TestStatus::fail("Image mismatch");
+}
+
+void BuiltinGlFragCoordXYZCaseInstance::setupDefaultInputs (void)
+{
+       const float             vertices[]              =
+       {
+               -1.0f,  1.0f,  0.0f, 1.0f,
+               -1.0f, -1.0f,  0.5f, 1.0f,
+                1.0f,  1.0f,  0.5f, 1.0f,
+                1.0f, -1.0f,  1.0f, 1.0f,
+       };
+
+       addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
+}
+
+class BuiltinGlFragCoordXYZCase : public TestCase
+{
+public:
+                                                               BuiltinGlFragCoordXYZCase       (TestContext& testCtx, const string& name, const string& description);
+       virtual                                         ~BuiltinGlFragCoordXYZCase      (void);
+
+       void                                            initPrograms                            (SourceCollections& dst) const;
+       TestInstance*                           createInstance                          (Context& context) const;
+
+private:
+                                                               BuiltinGlFragCoordXYZCase       (const BuiltinGlFragCoordXYZCase&);     // not allowed!
+       BuiltinGlFragCoordXYZCase&      operator=                                       (const BuiltinGlFragCoordXYZCase&);     // not allowed!
+};
+
+BuiltinGlFragCoordXYZCase::BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description)
+       : TestCase(testCtx, name, description)
+{
+}
+
+BuiltinGlFragCoordXYZCase::~BuiltinGlFragCoordXYZCase (void)
+{
+}
+
+void BuiltinGlFragCoordXYZCase::initPrograms (SourceCollections& dst) const
+{
+       dst.glslSources.add("vert") << glu::VertexSource(
+               "#version 310 es\n"
+               "layout(location = 0) in highp vec4 a_position;\n"
+               "void main (void)\n"
+               "{\n"
+               "       gl_Position = a_position;\n"
+               "}\n");
+
+       dst.glslSources.add("frag") << glu::FragmentSource(
+               "#version 310 es\n"
+               "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
+               "layout(location = 0) out highp vec4 o_color;\n"
+               "void main (void)\n"
+               "{\n"
+               "       o_color = vec4(gl_FragCoord.xyz * u_scale, 1.0);\n"
+               "}\n");
+}
+
+TestInstance* BuiltinGlFragCoordXYZCase::createInstance (Context& context) const
+{
+       return new BuiltinGlFragCoordXYZCaseInstance(context);
+}
+
+inline float projectedTriInterpolate (const Vec3& s, const Vec3& w, float nx, float ny)
+{
+       return (s[0]*(1.0f-nx-ny)/w[0] + s[1]*ny/w[1] + s[2]*nx/w[2]) / ((1.0f-nx-ny)/w[0] + ny/w[1] + nx/w[2]);
+}
+
+class BuiltinGlFragCoordWCaseInstance : public ShaderRenderCaseInstance
+{
+public:
+                                       BuiltinGlFragCoordWCaseInstance (Context& context);
+
+       TestStatus              iterate                                                 (void);
+       virtual void    setupDefaultInputs                              (void);
+
+private:
+
+       const Vec4              m_w;
+
+};
+
+BuiltinGlFragCoordWCaseInstance::BuiltinGlFragCoordWCaseInstance (Context& context)
+       : ShaderRenderCaseInstance      (context)
+       , m_w                                           (1.7f, 2.0f, 1.2f, 1.0f)
+{
+}
+
+TestStatus BuiltinGlFragCoordWCaseInstance::iterate (void)
+{
+       const UVec2             viewportSize    = getViewportSize();
+       const int               width                   = viewportSize.x();
+       const int               height                  = viewportSize.y();
+       const tcu::RGBA threshold               (2, 2, 2, 2);
+       Surface                 resImage                (width, height);
+       Surface                 refImage                (width, height);
+       bool                    compareOk               = false;
+       const deUint16  indices[6]              =
+       {
+               2, 1, 3,
+               0, 1, 2,
+       };
+
+       setup();
+       render(4, 2, indices);
+       copy(resImage.getAccess(), getResultImage().getAccess());
+
+       // Reference image
+       for (int y = 0; y < refImage.getHeight(); y++)
+       {
+               for (int x = 0; x < refImage.getWidth(); x++)
+               {
+                       const float     xf                      = (float(x)+.5f) / float(refImage.getWidth());
+                       const float     yf                      = (float(refImage.getHeight()-y-1)+.5f) / float(refImage.getHeight());
+                       const float     oow                     = ((xf + yf) < 1.0f)
+                                                                               ? projectedTriInterpolate(Vec3(m_w[0], m_w[1], m_w[2]), Vec3(m_w[0], m_w[1], m_w[2]), xf, yf)
+                                                                               : projectedTriInterpolate(Vec3(m_w[3], m_w[2], m_w[1]), Vec3(m_w[3], m_w[2], m_w[1]), 1.0f-xf, 1.0f-yf);
+                       const Vec4      color           (0.0f, oow - 1.0f, 0.0f, 1.0f);
+
+                       refImage.setPixel(x, y, RGBA(color));
+               }
+       }
+
+       compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
+
+       if (compareOk)
+               return TestStatus::pass("Result image matches reference");
+       else
+               return TestStatus::fail("Image mismatch");
+}
+
+void BuiltinGlFragCoordWCaseInstance::setupDefaultInputs (void)
+{
+       const float vertices[] =
+       {
+               -m_w[0],  m_w[0], 0.0f, m_w[0],
+               -m_w[1], -m_w[1], 0.0f, m_w[1],
+                m_w[2],  m_w[2], 0.0f, m_w[2],
+                m_w[3], -m_w[3], 0.0f, m_w[3]
+       };
+
+       addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
+}
+
+class BuiltinGlFragCoordWCase : public TestCase
+{
+public:
+                                                               BuiltinGlFragCoordWCase         (TestContext& testCtx, const string& name, const string& description);
+       virtual                                         ~BuiltinGlFragCoordWCase        (void);
+
+       void                                            initPrograms                            (SourceCollections& dst) const;
+       TestInstance*                           createInstance                          (Context& context) const;
+
+private:
+                                                               BuiltinGlFragCoordWCase         (const BuiltinGlFragCoordWCase&);       // not allowed!
+       BuiltinGlFragCoordWCase&        operator=                                       (const BuiltinGlFragCoordWCase&);       // not allowed!
+};
+
+BuiltinGlFragCoordWCase::BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description)
+       : TestCase(testCtx, name, description)
+{
+}
+
+BuiltinGlFragCoordWCase::~BuiltinGlFragCoordWCase (void)
+{
+}
+
+void BuiltinGlFragCoordWCase::initPrograms (SourceCollections& dst) const
+{
+       dst.glslSources.add("vert") << glu::VertexSource(
+               "#version 310 es\n"
+               "layout(location = 0) in highp vec4 a_position;\n"
+               "void main (void)\n"
+               "{\n"
+               "       gl_Position = a_position;\n"
+               "}\n");
+
+       dst.glslSources.add("frag") << glu::FragmentSource(
+               "#version 310 es\n"
+               "layout(location = 0) out highp vec4 o_color;\n"
+               "void main (void)\n"
+               "{\n"
+               "       o_color = vec4(0.0, 1.0 / gl_FragCoord.w - 1.0, 0.0, 1.0);\n"
+               "}\n");
+}
+
+TestInstance* BuiltinGlFragCoordWCase::createInstance (Context& context) const
+{
+       return new BuiltinGlFragCoordWCaseInstance(context);
+}
+
+class BuiltinGlPointCoordCaseInstance : public ShaderRenderCaseInstance
+{
+public:
+                                       BuiltinGlPointCoordCaseInstance (Context& context);
+
+       TestStatus              iterate                                                         (void);
+       virtual void    setupDefaultInputs                                      (void);
+};
+
+BuiltinGlPointCoordCaseInstance::BuiltinGlPointCoordCaseInstance (Context& context)
+       : ShaderRenderCaseInstance      (context)
+{
+}
+
+TestStatus BuiltinGlPointCoordCaseInstance::iterate (void)
+{
+       const UVec2                             viewportSize    = getViewportSize();
+       const int                               width                   = viewportSize.x();
+       const int                               height                  = viewportSize.y();
+       const float                             threshold               = 0.02f;
+       const int                               numPoints               = 16;
+       vector<Vec3>                    coords                  (numPoints);
+       de::Random                              rnd                             (0x145fa);
+       Surface                                 resImage                (width, height);
+       Surface                                 refImage                (width, height);
+       bool                                    compareOk               = false;
+       VkPhysicalDeviceLimits  limits                  = m_context.getDeviceProperties().limits;
+
+       // Compute coordinates.
+       {
+               for (vector<Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord)
+               {
+                       coord->x() = rnd.getFloat(-0.9f, 0.9f);
+                       coord->y() = rnd.getFloat(-0.9f, 0.9f);
+                       coord->z() = limits.pointSizeRange[0] + float(rnd.getInt(0, int((limits.pointSizeRange[1] - limits.pointSizeRange[0]) / limits.pointSizeGranularity))) * limits.pointSizeGranularity;
+               }
+       }
+
+       setup();
+       addAttribute(0u, VK_FORMAT_R32G32B32_SFLOAT, deUint32(sizeof(Vec3)), numPoints, &coords[0]);
+       render(numPoints, 0, DE_NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
+       copy(resImage.getAccess(), getResultImage().getAccess());
+
+       // Draw reference
+       clear(refImage.getAccess(), m_clearColor);
+       for (vector<Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter)
+       {
+               const int       x0              = deRoundFloatToInt32(float(width) *(pointIter->x()*0.5f + 0.5f) - pointIter->z()*0.5f);
+               const int       y0              = deRoundFloatToInt32(float(height)*(pointIter->y()*0.5f + 0.5f) - pointIter->z()*0.5f);
+               const int       x1              = deRoundFloatToInt32(float(width) *(pointIter->x()*0.5f + 0.5f) + pointIter->z()*0.5f);
+               const int       y1              = deRoundFloatToInt32(float(height)*(pointIter->y()*0.5f + 0.5f) + pointIter->z()*0.5f);
+               const int       w               = x1-x0;
+               const int       h               = y1-y0;
+
+               for (int yo = 0; yo < h; yo++)
+               {
+                       for (int xo = 0; xo < w; xo++)
+                       {
+                               const float             xf              = (float(xo)+0.5f) / float(w);
+                               const float             yf              = (float(yo)+0.5f) / float(h);
+                               const Vec4              color   (xf, yf, 0.0f, 1.0f);
+                               const int               dx              = x0+xo;
+                               const int               dy              = y0+yo;
+
+                               if (de::inBounds(dx, 0, refImage.getWidth()) && de::inBounds(dy, 0, refImage.getHeight()))
+                                       refImage.setPixel(dx, dy, RGBA(color));
+                       }
+               }
+       }
+
+       compareOk = fuzzyCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
+
+       if (compareOk)
+               return TestStatus::pass("Result image matches reference");
+       else
+               return TestStatus::fail("Image mismatch");
+}
+
+void BuiltinGlPointCoordCaseInstance::setupDefaultInputs (void)
+{
+}
+
+class BuiltinGlPointCoordCase : public TestCase
+{
+public:
+                                                               BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description);
+       virtual                                         ~BuiltinGlPointCoordCase        (void);
+
+       void                                            initPrograms                            (SourceCollections& dst) const;
+       TestInstance*                           createInstance                          (Context& context) const;
+
+private:
+                                                               BuiltinGlPointCoordCase (const BuiltinGlPointCoordCase&);       // not allowed!
+       BuiltinGlPointCoordCase&        operator=                                       (const BuiltinGlPointCoordCase&);       // not allowed!
+};
+
+BuiltinGlPointCoordCase::BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description)
+       : TestCase(testCtx, name, description)
+{
+}
+
+BuiltinGlPointCoordCase::~BuiltinGlPointCoordCase (void)
+{
+}
+
+void BuiltinGlPointCoordCase::initPrograms (SourceCollections& dst) const
+{
+       dst.glslSources.add("vert") << glu::VertexSource(
+               "#version 310 es\n"
+               "layout(location = 0) in highp vec3 a_position;\n"
+               "void main (void)\n"
+               "{\n"
+               "    gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
+               "    gl_PointSize = a_position.z;\n"
+               "}\n");
+
+       dst.glslSources.add("frag") << glu::FragmentSource(
+               "#version 310 es\n"
+               "layout(location = 0) out lowp vec4 o_color;\n"
+               "void main (void)\n"
+               "{\n"
+               "    o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
+               "}\n");
+}
+
+TestInstance* BuiltinGlPointCoordCase::createInstance (Context& context) const
+{
+       return new BuiltinGlPointCoordCaseInstance(context);
+}
+
+enum ShaderInputTypeBits
+{
+       SHADER_INPUT_BUILTIN_BIT        = 0x01,
+       SHADER_INPUT_VARYING_BIT        = 0x02,
+       SHADER_INPUT_CONSTANT_BIT       = 0x04
+};
+
+typedef deUint16 ShaderInputTypes;
+
+string shaderInputTypeToString (ShaderInputTypes type)
+{
+       string typeString = "input";
+
+       if (type == 0)
+               return "input_none";
+
+       if (type & SHADER_INPUT_BUILTIN_BIT)
+               typeString += "_builtin";
+
+       if (type & SHADER_INPUT_VARYING_BIT)
+               typeString += "_varying";
+
+       if (type & SHADER_INPUT_CONSTANT_BIT)
+               typeString += "_constant";
+
+       return typeString;
+}
+
+class BuiltinInputVariationsCaseInstance : public ShaderRenderCaseInstance
+{
+public:
+                                                       BuiltinInputVariationsCaseInstance      (Context& context, const ShaderInputTypes shaderInputTypes);
+
+       TestStatus                              iterate                                                         (void);
+       virtual void                    setupDefaultInputs                                      (void);
+       virtual void                    updatePushConstants                                     (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout);
+
+private:
+       const ShaderInputTypes  m_shaderInputTypes;
+       const Vec4                              m_constantColor;
+};
+
+BuiltinInputVariationsCaseInstance::BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes)
+       : ShaderRenderCaseInstance      (context)
+       , m_shaderInputTypes            (shaderInputTypes)
+       , m_constantColor                       (0.1f, 0.05f, 0.2f, 0.0f)
+{
+}
+
+TestStatus BuiltinInputVariationsCaseInstance::iterate (void)
+{
+       const UVec2                                     viewportSize    = getViewportSize();
+       const int                                       width                   = viewportSize.x();
+       const int                                       height                  = viewportSize.y();
+       const tcu::RGBA                         threshold               (2, 2, 2, 2);
+       Surface                                         resImage                (width, height);
+       Surface                                         refImage                (width, height);
+       bool                                            compareOk               = false;
+       const VkPushConstantRange       pcRanges                =
+       {
+               VK_SHADER_STAGE_FRAGMENT_BIT,   // VkShaderStageFlags   stageFlags;
+               0u,                                                             // deUint32                             offset;
+               sizeof(Vec4)                                    // deUint32                             size;
+       };
+       const deUint16                          indices[12]             =
+       {
+               0, 4, 1,
+               0, 5, 4,
+               1, 2, 3,
+               1, 3, 4
+       };
+
+       setup();
+
+       if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
+               setPushConstantRanges(1, &pcRanges);
+
+       render(6, 4, indices);
+       copy(resImage.getAccess(), getResultImage().getAccess());
+
+       // Reference image
+       for (int y = 0; y < refImage.getHeight(); y++)
+       {
+               for (int x = 0; x < refImage.getWidth(); x++)
+               {
+                       Vec4 color (0.1f, 0.2f, 0.3f, 1.0f);
+
+                       if (((m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT) && (x < refImage.getWidth() / 2)) ||
+                               !(m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT))
+                       {
+                               if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
+                               {
+                                       const float xf = (float(x)+.5f) / float(refImage.getWidth());
+                                       color += Vec4(0.6f * (1 - xf), 0.6f * xf, 0.0f, 0.0f);
+                               }
+                               else
+                                       color += Vec4(0.3f, 0.2f, 0.1f, 0.0f);
+                       }
+
+                       if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
+                               color += m_constantColor;
+
+                       refImage.setPixel(x, y, RGBA(color));
+               }
+       }
+
+       compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
+
+       if (compareOk)
+               return TestStatus::pass("Result image matches reference");
+       else
+               return TestStatus::fail("Image mismatch");
+}
+
+void BuiltinInputVariationsCaseInstance::setupDefaultInputs (void)
+{
+       const float vertices[] =
+       {
+               -1.0f, -1.0f, 0.0f, 1.0f,
+                0.0f, -1.0f, 0.0f, 1.0f,
+                1.0f, -1.0f, 0.0f, 1.0f,
+                1.0f,  1.0f, 0.0f, 1.0f,
+                0.0f,  1.0f, 0.0f, 1.0f,
+               -1.0f,  1.0f, 0.0f, 1.0f
+       };
+
+       addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
+
+       if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
+       {
+               const float colors[] =
+               {
+                        0.6f,  0.0f, 0.0f, 1.0f,
+                        0.3f,  0.3f, 0.0f, 1.0f,
+                        0.0f,  0.6f, 0.0f, 1.0f,
+                        0.0f,  0.6f, 0.0f, 1.0f,
+                        0.3f,  0.3f, 0.0f, 1.0f,
+                        0.6f,  0.0f, 0.0f, 1.0f
+               };
+               addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, colors);
+       }
+}
+
+void BuiltinInputVariationsCaseInstance::updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout)
+{
+       if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
+       {
+               const DeviceInterface& vk = m_context.getDeviceInterface();
+               vk.cmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4), &m_constantColor);
+       }
+}
+
+class BuiltinInputVariationsCase : public TestCase
+{
+public:
+                                                               BuiltinInputVariationsCase      (TestContext& testCtx, const string& name, const string& description, const ShaderInputTypes shaderInputTypes);
+       virtual                                         ~BuiltinInputVariationsCase     (void);
+
+       void                                            initPrograms                            (SourceCollections& dst) const;
+       TestInstance*                           createInstance                          (Context& context) const;
+
+private:
+                                                               BuiltinInputVariationsCase      (const BuiltinInputVariationsCase&);    // not allowed!
+       BuiltinInputVariationsCase&     operator=                                       (const BuiltinInputVariationsCase&);    // not allowed!
+       const ShaderInputTypes          m_shaderInputTypes;
+};
+
+BuiltinInputVariationsCase::BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, ShaderInputTypes shaderInputTypes)
+       : TestCase                              (testCtx, name, description)
+       , m_shaderInputTypes    (shaderInputTypes)
+{
+}
+
+BuiltinInputVariationsCase::~BuiltinInputVariationsCase (void)
+{
+}
+
+void BuiltinInputVariationsCase::initPrograms (SourceCollections& dst) const
+{
+       map<string, string>                     vertexParams;
+       map<string, string>                     fragmentParams;
+       const tcu::StringTemplate       vertexCodeTemplate              (
+               "#version 450\n"
+               "layout(location = 0) in highp vec4 a_position;\n"
+               "out gl_PerVertex {\n"
+               "       vec4 gl_Position;\n"
+               "};\n"
+               "${VARYING_DECL}"
+               "void main (void)\n"
+               "{\n"
+               "    gl_Position = a_position;\n"
+               "    ${VARYING_USAGE}"
+               "}\n");
+
+       const tcu::StringTemplate       fragmentCodeTemplate    (
+               "#version 450\n"
+               "${VARYING_DECL}"
+               "${CONSTANT_DECL}"
+               "layout(location = 0) out highp vec4 o_color;\n"
+               "void main (void)\n"
+               "{\n"
+               "    o_color = vec4(0.1, 0.2, 0.3, 1.0);\n"
+               "    ${BUILTIN_USAGE}"
+               "    ${VARYING_USAGE}"
+               "    ${CONSTANT_USAGE}"
+               "}\n");
+
+       vertexParams["VARYING_DECL"]            =
+               m_shaderInputTypes & SHADER_INPUT_VARYING_BIT   ? "layout(location = 1) in highp vec4 a_color;\n"
+                                                                                                                 "layout(location = 0) out highp vec4 v_color;\n"
+                                                                                                               : "";
+
+       vertexParams["VARYING_USAGE"]           =
+               m_shaderInputTypes & SHADER_INPUT_VARYING_BIT   ? "v_color = a_color;\n"
+                                                                                                               : "";
+
+       fragmentParams["VARYING_DECL"]          =
+               m_shaderInputTypes & SHADER_INPUT_VARYING_BIT   ? "layout(location = 0) in highp vec4 a_color;\n"
+                                                                                                               : "";
+
+       fragmentParams["CONSTANT_DECL"]         =
+               m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT  ? "layout(push_constant) uniform PCBlock {\n"
+                                                                                                                 "  vec4 color;\n"
+                                                                                                                 "} pc;\n"
+                                                                                                               : "";
+
+       fragmentParams["BUILTIN_USAGE"]         =
+               m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT   ? "if (gl_FrontFacing)\n"
+                                                                                                               : "";
+
+       fragmentParams["VARYING_USAGE"]         =
+               m_shaderInputTypes & SHADER_INPUT_VARYING_BIT   ? "o_color += vec4(a_color.xyz, 0.0);\n"
+                                                                                                               : "o_color += vec4(0.3, 0.2, 0.1, 0.0);\n";
+
+
+       fragmentParams["CONSTANT_USAGE"]        =
+               m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT  ? "o_color += pc.color;\n"
+                                                                                                               : "";
+
+       dst.glslSources.add("vert") << glu::VertexSource(vertexCodeTemplate.specialize(vertexParams));
+       dst.glslSources.add("frag") << glu::FragmentSource(fragmentCodeTemplate.specialize(fragmentParams));
+}
+
+TestInstance* BuiltinInputVariationsCase::createInstance (Context& context) const
+{
+       return new BuiltinInputVariationsCaseInstance(context, m_shaderInputTypes);
+}
+
 } // anonymous
 
 TestCaseGroup* createBuiltinVarTests (TestContext& testCtx)
 {
-       de::MovePtr<TestCaseGroup> varyingGroup(new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests."));
+       de::MovePtr<TestCaseGroup> builtinGroup                 (new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests."));
+       de::MovePtr<TestCaseGroup> simpleGroup                  (new TestCaseGroup(testCtx, "simple", "Simple cases."));
+       de::MovePtr<TestCaseGroup> inputVariationsGroup (new TestCaseGroup(testCtx, "input_variations", "Input type variation tests."));
+
+       simpleGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, "frontfacing", "FrontFacing test"));
+       simpleGroup->addChild(new BuiltinGlFragCoordXYZCase(testCtx, "fragcoord_xyz", "FragCoord xyz test"));
+       simpleGroup->addChild(new BuiltinGlFragCoordWCase(testCtx, "fragcoord_w", "FragCoord w test"));
+       simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord", "PointCoord test"));
+
+       builtinGroup->addChild(simpleGroup.release());
 
-       varyingGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, "gl_frontfacing", "gl_FrontFacing test"));
+       for (deUint16 shaderType = 0; shaderType <= (SHADER_INPUT_BUILTIN_BIT | SHADER_INPUT_VARYING_BIT | SHADER_INPUT_CONSTANT_BIT); ++shaderType)
+       {
+               inputVariationsGroup->addChild(new BuiltinInputVariationsCase(testCtx, shaderInputTypeToString(shaderType), "Input variation test", shaderType));
+       }
 
-       return varyingGroup.release();
+       builtinGroup->addChild(inputVariationsGroup.release());
+       return builtinGroup.release();
 }
 
 } // sr
index 34b9ea9..9afc33f 100644 (file)
@@ -85590,7 +85590,18 @@ dEQP-VK.glsl.texture_gather.offsets.min_required_offset.2d_array.depth32f.base_l
 dEQP-VK.glsl.texture_gather.offsets.min_required_offset.2d_array.depth32f.base_level.sparse_level_1
 dEQP-VK.glsl.texture_gather.offsets.min_required_offset.2d_array.depth32f.base_level.level_2
 dEQP-VK.glsl.texture_gather.offsets.min_required_offset.2d_array.depth32f.base_level.sparse_level_2
-dEQP-VK.glsl.builtin_var.gl_frontfacing
+dEQP-VK.glsl.builtin_var.simple.frontfacing
+dEQP-VK.glsl.builtin_var.simple.fragcoord_xyz
+dEQP-VK.glsl.builtin_var.simple.fragcoord_w
+dEQP-VK.glsl.builtin_var.simple.pointcoord
+dEQP-VK.glsl.builtin_var.input_variations.input_none
+dEQP-VK.glsl.builtin_var.input_variations.input_builtin
+dEQP-VK.glsl.builtin_var.input_variations.input_varying
+dEQP-VK.glsl.builtin_var.input_variations.input_builtin_varying
+dEQP-VK.glsl.builtin_var.input_variations.input_constant
+dEQP-VK.glsl.builtin_var.input_variations.input_builtin_constant
+dEQP-VK.glsl.builtin_var.input_variations.input_varying_constant
+dEQP-VK.glsl.builtin_var.input_variations.input_builtin_varying_constant
 dEQP-VK.glsl.builtin.function.common.abs.float_mediump_vertex
 dEQP-VK.glsl.builtin.function.common.abs.float_mediump_fragment
 dEQP-VK.glsl.builtin.function.common.abs.float_mediump_geometry