From 68ee9460976d1add6e36d0f2f216bb6c1c86aa96 Mon Sep 17 00:00:00 2001 From: Peter Siket Date: Thu, 4 Aug 2016 15:21:14 -0700 Subject: [PATCH] Extend shader built-in variable tests 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 | 47 +- android/cts/master/vk-master.txt | 13 +- .../vulkan/shaderrender/vktShaderRender.cpp | 62 +- .../vulkan/shaderrender/vktShaderRender.hpp | 9 + .../vktShaderRenderBuiltinVarTests.cpp | 653 ++++++++++++++++++++- external/vulkancts/mustpass/1.0.1/vk-default.txt | 13 +- 6 files changed, 770 insertions(+), 27 deletions(-) diff --git a/android/cts/master/com.drawelements.deqp.vk.xml b/android/cts/master/com.drawelements.deqp.vk.xml index 2021dda..91470ff 100644 --- a/android/cts/master/com.drawelements.deqp.vk.xml +++ b/android/cts/master/com.drawelements.deqp.vk.xml @@ -293754,11 +293754,48 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt index bf57c26..7f36dd7 100644 --- a/android/cts/master/vk-master.txt +++ b/android/cts/master/vk-master.txt @@ -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 diff --git a/external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.cpp b/external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.cpp index e7aa41f..fde3cbb 100644 --- a/external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.cpp +++ b/external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.cpp @@ -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 graphicsPipeline; vk::Move vertexShaderModule; vk::Move fragmentShaderModule; - vk::Move indiceBuffer; - de::MovePtr indiceBufferAlloc; + vk::Move indexBuffer; + de::MovePtr indexBufferAlloc; vk::Move descriptorSetLayout; vk::Move descriptorPool; vk::Move 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 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)); diff --git a/external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.hpp b/external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.hpp index 5411736..71cbfbf 100644 --- a/external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.hpp +++ b/external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.hpp @@ -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 m_vertexBufferAllocs; vk::VkSampleCountFlagBits m_sampleCount; + std::vector m_pushConstantRanges; // Wrapper functions around m_context calls to support sparse cases. vk::VkDevice getDevice (void) const; diff --git a/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp b/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp index 79fd52f..4f89e18 100644 --- a/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp +++ b/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp @@ -30,6 +30,11 @@ #include "tcuStringTemplate.hpp" #include "tcuTextureUtil.hpp" +#include "deMath.h" +#include "deRandom.hpp" + +#include + 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 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::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::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 vertexParams; + map 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 varyingGroup(new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests.")); + de::MovePtr builtinGroup (new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests.")); + de::MovePtr simpleGroup (new TestCaseGroup(testCtx, "simple", "Simple cases.")); + de::MovePtr 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 diff --git a/external/vulkancts/mustpass/1.0.1/vk-default.txt b/external/vulkancts/mustpass/1.0.1/vk-default.txt index 34b9ea9..9afc33f 100644 --- a/external/vulkancts/mustpass/1.0.1/vk-default.txt +++ b/external/vulkancts/mustpass/1.0.1/vk-default.txt @@ -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 -- 2.7.4