From 8ba59662bff835d72077feb906ace49c17a09a52 Mon Sep 17 00:00:00 2001 From: Maciej Jesionowski Date: Wed, 9 Nov 2016 12:54:59 +0100 Subject: [PATCH] Add tests for VK_KHR_shader_draw_parameters New tests: - dEQP-VK.draw.shader_draw_parameters.* Fixes #500 Change-Id: I8e735bbf8ac7fcb24918a84d6bd9a93cf2fbf53b --- android/cts/master/vk-master.txt | 14 + .../draw/VertexFetchShaderDrawParameters.vert | 26 ++ .../VertexFetchShaderDrawParametersDrawIndex.vert | 26 ++ .../modules/vulkan/api/vktApiFeatureInfo.cpp | 3 +- .../vulkancts/modules/vulkan/draw/CMakeLists.txt | 2 + .../draw/vktDrawShaderDrawParametersTests.cpp | 405 +++++++++++++++++++++ .../draw/vktDrawShaderDrawParametersTests.hpp | 47 +++ .../vulkancts/modules/vulkan/draw/vktDrawTests.cpp | 12 +- external/vulkancts/mustpass/1.0.2/vk-default.txt | 14 + 9 files changed, 543 insertions(+), 6 deletions(-) create mode 100644 external/vulkancts/data/vulkan/draw/VertexFetchShaderDrawParameters.vert create mode 100644 external/vulkancts/data/vulkan/draw/VertexFetchShaderDrawParametersDrawIndex.vert create mode 100644 external/vulkancts/modules/vulkan/draw/vktDrawShaderDrawParametersTests.cpp create mode 100644 external/vulkancts/modules/vulkan/draw/vktDrawShaderDrawParametersTests.hpp diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt index 1ceb541..79ebe48 100644 --- a/android/cts/master/vk-master.txt +++ b/android/cts/master/vk-master.txt @@ -122345,6 +122345,20 @@ dEQP-VK.draw.instanced.draw_vk_primitive_topology_triangle_fan dEQP-VK.draw.instanced.draw_indexed_vk_primitive_topology_triangle_fan dEQP-VK.draw.instanced.draw_indirect_vk_primitive_topology_triangle_fan dEQP-VK.draw.instanced.draw_indexed_indirect_vk_primitive_topology_triangle_fan +dEQP-VK.draw.shader_draw_parameters.base_vertex.draw +dEQP-VK.draw.shader_draw_parameters.base_vertex.draw_indexed +dEQP-VK.draw.shader_draw_parameters.base_vertex.draw_indirect +dEQP-VK.draw.shader_draw_parameters.base_vertex.draw_indexed_indirect +dEQP-VK.draw.shader_draw_parameters.base_instance.draw +dEQP-VK.draw.shader_draw_parameters.base_instance.draw_indexed +dEQP-VK.draw.shader_draw_parameters.base_instance.draw_indirect +dEQP-VK.draw.shader_draw_parameters.base_instance.draw_indirect_first_instance +dEQP-VK.draw.shader_draw_parameters.base_instance.draw_indexed_indirect +dEQP-VK.draw.shader_draw_parameters.base_instance.draw_indexed_indirect_first_instance +dEQP-VK.draw.shader_draw_parameters.draw_index.draw +dEQP-VK.draw.shader_draw_parameters.draw_index.draw_instanced +dEQP-VK.draw.shader_draw_parameters.draw_index.draw_indexed +dEQP-VK.draw.shader_draw_parameters.draw_index.draw_indexed_instanced dEQP-VK.compute.basic.empty_shader dEQP-VK.compute.basic.ubo_to_ssbo_single_invocation dEQP-VK.compute.basic.ubo_to_ssbo_single_group diff --git a/external/vulkancts/data/vulkan/draw/VertexFetchShaderDrawParameters.vert b/external/vulkancts/data/vulkan/draw/VertexFetchShaderDrawParameters.vert new file mode 100644 index 0000000..0be6bda --- /dev/null +++ b/external/vulkancts/data/vulkan/draw/VertexFetchShaderDrawParameters.vert @@ -0,0 +1,26 @@ +#version 450 core +#extension GL_ARB_shader_draw_parameters : require + +layout(location = 0) in vec4 in_position; +layout(location = 1) in vec4 in_color; +layout(location = 2) in int in_refVertexIndex; + +layout(location = 0) out vec4 out_color; + +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() { + vec2 perVertex = vec2(in_position.x, in_position.y); + vec2 perInstance[5] = vec2[5](vec2(0.0, 0.0), vec2(-0.3, 0.0), vec2(0.0, 0.3), vec2(0.5, 0.5), vec2(0.75, -0.8)); + vec4 colors[4] = vec4[4](vec4(1.0), vec4(0.0, 0.0, 1.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), vec4(0.0, 1.0, 1.0, 1.0)); + int baseInstanceIndex = gl_InstanceIndex - gl_BaseInstanceARB; + + gl_Position = vec4(perVertex + perInstance[baseInstanceIndex], 0.0, 1.0); + + if ((gl_VertexIndex - gl_BaseVertexARB) == in_refVertexIndex && gl_DrawIDARB == 0) + out_color = in_color * colors[baseInstanceIndex]; + else + out_color = vec4(1.0, 0.0, 0.0, 1.0); +} diff --git a/external/vulkancts/data/vulkan/draw/VertexFetchShaderDrawParametersDrawIndex.vert b/external/vulkancts/data/vulkan/draw/VertexFetchShaderDrawParametersDrawIndex.vert new file mode 100644 index 0000000..596287c --- /dev/null +++ b/external/vulkancts/data/vulkan/draw/VertexFetchShaderDrawParametersDrawIndex.vert @@ -0,0 +1,26 @@ +#version 450 core +#extension GL_ARB_shader_draw_parameters : require + +layout(location = 0) in vec4 in_position; +layout(location = 1) in vec4 in_color; +layout(location = 2) in int in_refVertexIndex; + +layout(location = 0) out vec4 out_color; + +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() { + vec2 perVertex = vec2(in_position.x, in_position.y); + vec2 perInstance[5] = vec2[5](vec2(0.0, 0.0), vec2(-0.3, 0.0), vec2(0.0, 0.3), vec2(0.5, 0.5), vec2(0.75, -0.8)); + vec2 perDraw[4] = vec2[4](vec2(0.0, 0.0), vec2(-0.3, -0.3), vec2(0.3, 0.3), vec2(1.0, 0.5)); + vec4 colors[4] = vec4[4](vec4(1.0), vec4(0.0, 0.0, 1.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), vec4(0.0, 1.0, 1.0, 1.0)); + + gl_Position = vec4(perVertex + perInstance[gl_InstanceIndex - gl_BaseInstanceARB] + perDraw[gl_DrawIDARB], 0.0, 1.0); + + if ((gl_VertexIndex - gl_BaseVertexARB) == in_refVertexIndex) + out_color = in_color * colors[gl_DrawIDARB]; + else + out_color = vec4(1.0, 0.0, 0.0, 1.0); +} diff --git a/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp b/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp index 229c188..eb1fcd5 100644 --- a/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp +++ b/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp @@ -663,7 +663,8 @@ void checkDeviceExtensions (tcu::ResultCollector& results, const vector& { "VK_KHR_swapchain", "VK_KHR_display_swapchain", - "VK_KHR_sampler_mirror_clamp_to_edge" + "VK_KHR_sampler_mirror_clamp_to_edge", + "VK_KHR_shader_draw_parameters", }; checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedInstanceKhrExtensions), s_allowedInstanceKhrExtensions); diff --git a/external/vulkancts/modules/vulkan/draw/CMakeLists.txt b/external/vulkancts/modules/vulkan/draw/CMakeLists.txt index e7a06c5..5a83703 100644 --- a/external/vulkancts/modules/vulkan/draw/CMakeLists.txt +++ b/external/vulkancts/modules/vulkan/draw/CMakeLists.txt @@ -9,6 +9,8 @@ set(DEQP_VK_DRAW_SRCS vktDrawIndirectTest.cpp vktDrawInstancedTests.hpp vktDrawInstancedTests.cpp + vktDrawShaderDrawParametersTests.hpp + vktDrawShaderDrawParametersTests.cpp vktDrawSimpleTest.hpp vktDrawSimpleTest.cpp vktDrawBaseClass.hpp diff --git a/external/vulkancts/modules/vulkan/draw/vktDrawShaderDrawParametersTests.cpp b/external/vulkancts/modules/vulkan/draw/vktDrawShaderDrawParametersTests.cpp new file mode 100644 index 0000000..53bb063 --- /dev/null +++ b/external/vulkancts/modules/vulkan/draw/vktDrawShaderDrawParametersTests.cpp @@ -0,0 +1,405 @@ +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2016 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief VK_KHR_shader_draw_parameters tests + *//*--------------------------------------------------------------------*/ + +#include "vktDrawShaderDrawParametersTests.hpp" + +#include "vktTestCaseUtil.hpp" +#include "vktDrawTestCaseUtil.hpp" +#include "vktDrawBaseClass.hpp" + +#include "vkQueryUtil.hpp" + +#include "tcuTestLog.hpp" +#include "tcuImageCompare.hpp" +#include "tcuTextureUtil.hpp" + +namespace vkt +{ +namespace Draw +{ +namespace +{ + +enum TestFlagBits +{ + TEST_FLAG_INSTANCED = 1u << 0, + TEST_FLAG_INDEXED = 1u << 1, + TEST_FLAG_INDIRECT = 1u << 2, + TEST_FLAG_MULTIDRAW = 1u << 3, //!< multiDrawIndirect + TEST_FLAG_FIRST_INSTANCE = 1u << 4, //!< drawIndirectFirstInstance +}; +typedef deUint32 TestFlags; + +struct FlagsTestSpec : public TestSpecBase +{ + TestFlags flags; +}; + +inline FlagsTestSpec addFlags (FlagsTestSpec spec, const TestFlags flags) +{ + spec.flags |= flags; + return spec; +} + +enum Constants +{ + // \note Data layout in buffers (junk data and good data is intertwined). + // Values are largely arbitrary, but we try to avoid "nice" numbers to make sure the test doesn't pass by accident. + NUM_VERTICES = 4, //!< number of consecutive good vertices + NDX_FIRST_VERTEX = 2, //!< index of first good vertex data + NDX_SECOND_VERTEX = 9, //!< index of second good vertex data + NDX_FIRST_INDEX = 11, //!< index of a first good index (in index data) + NDX_SECOND_INDEX = 17, //!< index of a second good index + OFFSET_FIRST_INDEX = 1, //!< offset added to the first index + OFFSET_SECOND_INDEX = 4, //!< offset added to the second index + MAX_INSTANCE_COUNT = 3, //!< max number of draw instances + MAX_INDIRECT_DRAW_COUNT = 3, //!< max drawCount of indirect calls +}; + +class DrawTest : public DrawTestsBaseClass +{ +public: + typedef FlagsTestSpec TestSpec; + DrawTest (Context &context, TestSpec testSpec); + tcu::TestStatus iterate (void); + +private: + template + void setIndirectCommand (const T (&pCmdData)[N]); + + void drawReferenceImage (const tcu::PixelBufferAccess& refImage) const; + + bool isInstanced (void) const { return (m_flags & TEST_FLAG_INSTANCED) != 0; } + bool isIndexed (void) const { return (m_flags & TEST_FLAG_INDEXED) != 0; } + bool isIndirect (void) const { return (m_flags & TEST_FLAG_INDIRECT) != 0; } + bool isMultiDraw (void) const { return (m_flags & TEST_FLAG_MULTIDRAW) != 0; } + bool isFirstInstance (void) const { return (m_flags & TEST_FLAG_FIRST_INSTANCE) != 0; } + + const TestFlags m_flags; + de::SharedPtr m_indexBuffer; + de::SharedPtr m_indirectBuffer; +}; + +DrawTest::DrawTest (Context &context, TestSpec testSpec) + : DrawTestsBaseClass(context, testSpec.shaders[glu::SHADERTYPE_VERTEX], testSpec.shaders[glu::SHADERTYPE_FRAGMENT], testSpec.topology) + , m_flags (testSpec.flags) +{ + DE_ASSERT(m_topology == vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP); + DE_ASSERT(!isMultiDraw() || isIndirect()); + DE_ASSERT(!isFirstInstance() || (isIndirect() && isInstanced())); + + // Requirements + { + if (!de::contains(m_context.getDeviceExtensions().begin(), m_context.getDeviceExtensions().end(), std::string("VK_KHR_shader_draw_parameters"))) + TCU_THROW(NotSupportedError, "Missing extension: VK_KHR_shader_draw_parameters"); + + if (isMultiDraw() && !m_context.getDeviceFeatures().multiDrawIndirect) + TCU_THROW(NotSupportedError, "Missing feature: multiDrawIndirect"); + + if (isFirstInstance() && !m_context.getDeviceFeatures().drawIndirectFirstInstance) + TCU_THROW(NotSupportedError, "Missing feature: drawIndirectFirstInstance"); + } + + // Vertex data + { + int refIndex = NDX_FIRST_VERTEX - OFFSET_FIRST_INDEX; + + m_data.push_back(VertexElementData(tcu::Vec4( 1.0f, -1.0f, 1.0f, 1.0f), tcu::Vec4(1.0f), -1)); + m_data.push_back(VertexElementData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(1.0f), -1)); + + if (!isIndexed()) + refIndex = 0; + + m_data.push_back(VertexElementData(tcu::Vec4(-0.3f, -0.3f, 1.0f, 1.0f), tcu::Vec4(1.0f), refIndex++)); + m_data.push_back(VertexElementData(tcu::Vec4(-0.3f, 0.3f, 1.0f, 1.0f), tcu::Vec4(1.0f), refIndex++)); + m_data.push_back(VertexElementData(tcu::Vec4( 0.3f, -0.3f, 1.0f, 1.0f), tcu::Vec4(1.0f), refIndex++)); + m_data.push_back(VertexElementData(tcu::Vec4( 0.3f, 0.3f, 1.0f, 1.0f), tcu::Vec4(1.0f), refIndex++)); + + m_data.push_back(VertexElementData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(1.0f), -1)); + m_data.push_back(VertexElementData(tcu::Vec4( 1.0f, -1.0f, 1.0f, 1.0f), tcu::Vec4(1.0f), -1)); + m_data.push_back(VertexElementData(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::Vec4(1.0f), -1)); + + if (!isIndexed()) + refIndex = 0; + + m_data.push_back(VertexElementData(tcu::Vec4(-0.3f, -0.3f, 1.0f, 1.0f), tcu::Vec4(1.0f), refIndex++)); + m_data.push_back(VertexElementData(tcu::Vec4(-0.3f, 0.3f, 1.0f, 1.0f), tcu::Vec4(1.0f), refIndex++)); + m_data.push_back(VertexElementData(tcu::Vec4( 0.3f, -0.3f, 1.0f, 1.0f), tcu::Vec4(1.0f), refIndex++)); + m_data.push_back(VertexElementData(tcu::Vec4( 0.3f, 0.3f, 1.0f, 1.0f), tcu::Vec4(1.0f), refIndex++)); + + m_data.push_back(VertexElementData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(1.0f), -1)); + m_data.push_back(VertexElementData(tcu::Vec4( 1.0f, -1.0f, 1.0f, 1.0f), tcu::Vec4(1.0f), -1)); + + // Make sure constants are up to date + DE_ASSERT(m_data.size() == NDX_SECOND_VERTEX + NUM_VERTICES + 2); + DE_ASSERT(NDX_SECOND_VERTEX - NDX_FIRST_VERTEX - NUM_VERTICES == 3); + } + + if (isIndirect()) + { + const std::size_t indirectBufferSize = MAX_INDIRECT_DRAW_COUNT * 32; // space for COUNT commands plus some gratuitous padding + m_indirectBuffer = Buffer::createAndAlloc(m_vk, m_context.getDevice(), BufferCreateInfo(indirectBufferSize, vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), + m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible); + + deMemset(m_indirectBuffer->getBoundMemory().getHostPtr(), 0, indirectBufferSize); + vk::flushMappedMemoryRange(m_vk, m_context.getDevice(), m_indirectBuffer->getBoundMemory().getMemory(), m_indirectBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE); + } + + if (isIndexed()) + { + DE_ASSERT(NDX_FIRST_INDEX + NUM_VERTICES <= NDX_SECOND_INDEX); + const std::size_t indexBufferSize = sizeof(deUint32) * (NDX_SECOND_INDEX + NUM_VERTICES); + m_indexBuffer = Buffer::createAndAlloc(m_vk, m_context.getDevice(), BufferCreateInfo(indexBufferSize, vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT), + m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible); + deUint32* indices = static_cast(m_indexBuffer->getBoundMemory().getHostPtr()); + + deMemset(indices, 0, indexBufferSize); + + for (int i = 0; i < NUM_VERTICES; i++) + { + indices[NDX_FIRST_INDEX + i] = static_cast(NDX_FIRST_VERTEX + i) - OFFSET_FIRST_INDEX; + indices[NDX_SECOND_INDEX + i] = static_cast(NDX_SECOND_VERTEX + i) - OFFSET_SECOND_INDEX; + } + + vk::flushMappedMemoryRange(m_vk, m_context.getDevice(), m_indexBuffer->getBoundMemory().getMemory(), m_indexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE); + } + + initialize(); +} + +template +void DrawTest::setIndirectCommand (const T (&pCmdData)[N]) +{ + DE_ASSERT(N != 0 && N <= MAX_INDIRECT_DRAW_COUNT); + + const std::size_t dataSize = N * sizeof(T); + + deMemcpy(m_indirectBuffer->getBoundMemory().getHostPtr(), pCmdData, dataSize); + vk::flushMappedMemoryRange(m_vk, m_context.getDevice(), m_indirectBuffer->getBoundMemory().getMemory(), m_indirectBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE); +} + +//! This function must be kept in sync with the shader. +void DrawTest::drawReferenceImage (const tcu::PixelBufferAccess& refImage) const +{ + using tcu::Vec2; + using tcu::Vec4; + using tcu::IVec4; + + const Vec2 perInstanceOffset[] = { Vec2(0.0f, 0.0f), Vec2(-0.3f, 0.0f), Vec2(0.0f, 0.3f) }; + const Vec2 perDrawOffset[] = { Vec2(0.0f, 0.0f), Vec2(-0.3f, -0.3f), Vec2(0.3f, 0.3f) }; + const Vec4 allColors[] = { Vec4(1.0f), Vec4(0.0f, 0.0f, 1.0f, 1.0f), Vec4(0.0f, 1.0f, 0.0f, 1.0f) }; + const int numInstances = isInstanced() ? MAX_INSTANCE_COUNT : 1; + const int numIndirectDraws = isMultiDraw() ? MAX_INDIRECT_DRAW_COUNT : 1; + const int rectWidth = static_cast(WIDTH * 0.6f / 2.0f); + const int rectHeight = static_cast(HEIGHT * 0.6f / 2.0f); + + DE_ASSERT(DE_LENGTH_OF_ARRAY(perInstanceOffset) >= numInstances); + DE_ASSERT(DE_LENGTH_OF_ARRAY(allColors) >= numInstances && DE_LENGTH_OF_ARRAY(allColors) >= numIndirectDraws); + DE_ASSERT(DE_LENGTH_OF_ARRAY(perDrawOffset) >= numIndirectDraws); + + tcu::clear(refImage, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); + + for (int drawNdx = 0; drawNdx < numIndirectDraws; ++drawNdx) + for (int instanceNdx = 0; instanceNdx < numInstances; ++instanceNdx) + { + const Vec2 offset = perInstanceOffset[instanceNdx] + perDrawOffset[drawNdx]; + const Vec4& color = allColors[isMultiDraw() ? drawNdx : instanceNdx]; + int x = static_cast(WIDTH * (1.0f - 0.3f + offset.x()) / 2.0f); + int y = static_cast(HEIGHT * (1.0f - 0.3f + offset.y()) / 2.0f); + + tcu::clear(tcu::getSubregion(refImage, x, y, rectWidth, rectHeight), color); + } +} + +tcu::TestStatus DrawTest::iterate (void) +{ + // Draw + { + beginRenderPass(); + + const vk::VkDeviceSize vertexBufferOffset = 0; + const vk::VkBuffer vertexBuffer = m_vertexBuffer->object(); + + m_vk.cmdBindVertexBuffers (*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset); + m_vk.cmdBindPipeline (*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline); + + if (isIndexed()) + m_vk.cmdBindIndexBuffer(*m_cmdBuffer, m_indexBuffer->object(), 0ull, vk::VK_INDEX_TYPE_UINT32); + + const deUint32 numInstances = isInstanced() ? MAX_INSTANCE_COUNT : 1; + + if (isIndirect()) + { + if (isIndexed()) + { + const vk::VkDrawIndexedIndirectCommand commands[] = + { + // indexCount, instanceCount, firstIndex, vertexOffset, firstInstance + { NUM_VERTICES, numInstances, NDX_FIRST_INDEX, OFFSET_FIRST_INDEX, (isFirstInstance() ? 2u : 0u) }, + { NUM_VERTICES, numInstances, NDX_SECOND_INDEX, OFFSET_SECOND_INDEX, (isFirstInstance() ? 1u : 0u) }, + { NUM_VERTICES, numInstances, NDX_FIRST_INDEX, OFFSET_FIRST_INDEX, (isFirstInstance() ? 3u : 0u) }, + }; + setIndirectCommand(commands); + } + else + { + const vk::VkDrawIndirectCommand commands[] = + { + // vertexCount, instanceCount, firstVertex, firstInstance + { NUM_VERTICES, numInstances, NDX_FIRST_VERTEX, (isFirstInstance() ? 2u : 0u) }, + { NUM_VERTICES, numInstances, NDX_SECOND_VERTEX, (isFirstInstance() ? 1u : 0u) }, + { NUM_VERTICES, numInstances, NDX_FIRST_VERTEX, (isFirstInstance() ? 3u : 0u) }, + }; + setIndirectCommand(commands); + } + } + + if (isIndirect()) + { + const deUint32 numIndirectDraws = isMultiDraw() ? MAX_INDIRECT_DRAW_COUNT : 1; + + if (isIndexed()) + m_vk.cmdDrawIndexedIndirect(*m_cmdBuffer, m_indirectBuffer->object(), 0ull, numIndirectDraws, sizeof(vk::VkDrawIndexedIndirectCommand)); + else + m_vk.cmdDrawIndirect(*m_cmdBuffer, m_indirectBuffer->object(), 0ull, numIndirectDraws, sizeof(vk::VkDrawIndirectCommand)); + } + else + { + const deUint32 firstInstance = 2; + + if (isIndexed()) + m_vk.cmdDrawIndexed(*m_cmdBuffer, NUM_VERTICES, numInstances, NDX_FIRST_INDEX, OFFSET_FIRST_INDEX, firstInstance); + else + m_vk.cmdDraw(*m_cmdBuffer, NUM_VERTICES, numInstances, NDX_FIRST_VERTEX, firstInstance); + } + + m_vk.cmdEndRenderPass(*m_cmdBuffer); + m_vk.endCommandBuffer(*m_cmdBuffer); + } + + // Submit + { + const vk::VkQueue queue = m_context.getUniversalQueue(); + const vk::VkSubmitInfo submitInfo = + { + vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0, // deUint32 waitSemaphoreCount; + DE_NULL, // const VkSemaphore* pWaitSemaphores; + (const vk::VkPipelineStageFlags*)DE_NULL, + 1, // deUint32 commandBufferCount; + &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; + 0, // deUint32 signalSemaphoreCount; + DE_NULL // const VkSemaphore* pSignalSemaphores; + }; + VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL)); + VK_CHECK(m_vk.queueWaitIdle(queue)); + } + + // Validate + { + tcu::TextureLevel referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), static_cast(0.5f + WIDTH), static_cast(0.5f + HEIGHT)); + + drawReferenceImage(referenceFrame.getAccess()); + + const vk::VkOffset3D zeroOffset = { 0, 0, 0 }; + const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(m_context.getUniversalQueue(), m_context.getDefaultAllocator(), + vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT); + + if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", referenceFrame.getAccess(), renderedFrame, 0.05f, tcu::COMPARE_LOG_RESULT)) + return tcu::TestStatus::fail("Rendered image is incorrect"); + else + return tcu::TestStatus::pass("OK"); + } +} + +void addDrawCase (tcu::TestCaseGroup* group, const DrawTest::TestSpec testSpec, const TestFlags flags) +{ + std::ostringstream name; + name << "draw"; + + if (flags & TEST_FLAG_INDEXED) name << "_indexed"; + if (flags & TEST_FLAG_INDIRECT) name << "_indirect"; + if (flags & TEST_FLAG_INSTANCED) name << "_instanced"; + if (flags & TEST_FLAG_FIRST_INSTANCE) name << "_first_instance"; + + group->addChild(new InstanceFactory(group->getTestContext(), name.str(), "", addFlags(testSpec, flags))); +} + +} // anonymous + +ShaderDrawParametersTests::ShaderDrawParametersTests (tcu::TestContext &testCtx) + : TestCaseGroup (testCtx, "shader_draw_parameters", "VK_KHR_shader_draw_parameters") +{ +} + +void ShaderDrawParametersTests::init (void) +{ + { + DrawTest::TestSpec testSpec; + testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/draw/VertexFetchShaderDrawParameters.vert"; + testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/draw/VertexFetch.frag"; + testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + testSpec.flags = 0; + + de::MovePtr group(new tcu::TestCaseGroup(getTestContext(), "base_vertex", "")); + addDrawCase(group.get(), testSpec, 0); + addDrawCase(group.get(), testSpec, TEST_FLAG_INDEXED); + addDrawCase(group.get(), testSpec, TEST_FLAG_INDIRECT); + addDrawCase(group.get(), testSpec, TEST_FLAG_INDEXED | TEST_FLAG_INDIRECT); + addChild(group.release()); + } + { + DrawTest::TestSpec testSpec; + testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/draw/VertexFetchShaderDrawParameters.vert"; + testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/draw/VertexFetch.frag"; + testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + testSpec.flags = TEST_FLAG_INSTANCED; + + de::MovePtr group(new tcu::TestCaseGroup(getTestContext(), "base_instance", "")); + addDrawCase(group.get(), testSpec, 0); + addDrawCase(group.get(), testSpec, TEST_FLAG_INDEXED); + addDrawCase(group.get(), testSpec, TEST_FLAG_INDIRECT); + addDrawCase(group.get(), testSpec, TEST_FLAG_INDIRECT | TEST_FLAG_FIRST_INSTANCE); + addDrawCase(group.get(), testSpec, TEST_FLAG_INDEXED | TEST_FLAG_INDIRECT); + addDrawCase(group.get(), testSpec, TEST_FLAG_INDEXED | TEST_FLAG_INDIRECT | TEST_FLAG_FIRST_INSTANCE); + addChild(group.release()); + } + { + DrawTest::TestSpec testSpec; + testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/draw/VertexFetchShaderDrawParametersDrawIndex.vert"; + testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/draw/VertexFetch.frag"; + testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + testSpec.flags = TEST_FLAG_INDIRECT | TEST_FLAG_MULTIDRAW; + + de::MovePtr group(new tcu::TestCaseGroup(getTestContext(), "draw_index", "")); + addDrawCase(group.get(), testSpec, 0); + addDrawCase(group.get(), testSpec, TEST_FLAG_INSTANCED); + addDrawCase(group.get(), testSpec, TEST_FLAG_INDEXED); + addDrawCase(group.get(), testSpec, TEST_FLAG_INDEXED | TEST_FLAG_INSTANCED); + addChild(group.release()); + } +} + +} // DrawTests +} // vkt diff --git a/external/vulkancts/modules/vulkan/draw/vktDrawShaderDrawParametersTests.hpp b/external/vulkancts/modules/vulkan/draw/vktDrawShaderDrawParametersTests.hpp new file mode 100644 index 0000000..02c532a --- /dev/null +++ b/external/vulkancts/modules/vulkan/draw/vktDrawShaderDrawParametersTests.hpp @@ -0,0 +1,47 @@ +#ifndef _VKTDRAWSHADERDRAWPARAMETERSTESTS_HPP +#define _VKTDRAWSHADERDRAWPARAMETERSTESTS_HPP +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2016 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief VK_KHR_shader_draw_parameters tests + *//*--------------------------------------------------------------------*/ + +#include "vktTestCase.hpp" + +namespace vkt +{ +namespace Draw +{ + +class ShaderDrawParametersTests : public tcu::TestCaseGroup +{ +public: + ShaderDrawParametersTests (tcu::TestContext& testCtx); + void init (void); + +private: + ShaderDrawParametersTests (const ShaderDrawParametersTests& other); + ShaderDrawParametersTests& operator= (const ShaderDrawParametersTests& other); +}; + +} // Draw +} // vkt + +#endif // _VKTDRAWSHADERDRAWPARAMETERSTESTS_HPP diff --git a/external/vulkancts/modules/vulkan/draw/vktDrawTests.cpp b/external/vulkancts/modules/vulkan/draw/vktDrawTests.cpp index ee04acf..301698e 100644 --- a/external/vulkancts/modules/vulkan/draw/vktDrawTests.cpp +++ b/external/vulkancts/modules/vulkan/draw/vktDrawTests.cpp @@ -30,6 +30,7 @@ #include "vktDrawInstancedTests.hpp" #include "vktTestGroupUtil.hpp" #include "vktBasicDrawTests.hpp" +#include "vktDrawShaderDrawParametersTests.hpp" namespace vkt { @@ -43,11 +44,12 @@ void createChildren (tcu::TestCaseGroup* group) { tcu::TestContext& testCtx = group->getTestContext(); - group->addChild(new SimpleDrawTests(testCtx)); - group->addChild(new DrawIndexedTests(testCtx)); - group->addChild(new IndirectDrawTests(testCtx)); - group->addChild(createBasicDrawTests(testCtx)); - group->addChild(new InstancedTests(testCtx)); + group->addChild(new SimpleDrawTests (testCtx)); + group->addChild(new DrawIndexedTests (testCtx)); + group->addChild(new IndirectDrawTests (testCtx)); + group->addChild(createBasicDrawTests (testCtx)); + group->addChild(new InstancedTests (testCtx)); + group->addChild(new ShaderDrawParametersTests (testCtx)); } } // anonymous diff --git a/external/vulkancts/mustpass/1.0.2/vk-default.txt b/external/vulkancts/mustpass/1.0.2/vk-default.txt index c8f333b..77f4e43 100644 --- a/external/vulkancts/mustpass/1.0.2/vk-default.txt +++ b/external/vulkancts/mustpass/1.0.2/vk-default.txt @@ -116824,6 +116824,20 @@ dEQP-VK.draw.instanced.draw_vk_primitive_topology_triangle_fan dEQP-VK.draw.instanced.draw_indexed_vk_primitive_topology_triangle_fan dEQP-VK.draw.instanced.draw_indirect_vk_primitive_topology_triangle_fan dEQP-VK.draw.instanced.draw_indexed_indirect_vk_primitive_topology_triangle_fan +dEQP-VK.draw.shader_draw_parameters.base_vertex.draw +dEQP-VK.draw.shader_draw_parameters.base_vertex.draw_indexed +dEQP-VK.draw.shader_draw_parameters.base_vertex.draw_indirect +dEQP-VK.draw.shader_draw_parameters.base_vertex.draw_indexed_indirect +dEQP-VK.draw.shader_draw_parameters.base_instance.draw +dEQP-VK.draw.shader_draw_parameters.base_instance.draw_indexed +dEQP-VK.draw.shader_draw_parameters.base_instance.draw_indirect +dEQP-VK.draw.shader_draw_parameters.base_instance.draw_indirect_first_instance +dEQP-VK.draw.shader_draw_parameters.base_instance.draw_indexed_indirect +dEQP-VK.draw.shader_draw_parameters.base_instance.draw_indexed_indirect_first_instance +dEQP-VK.draw.shader_draw_parameters.draw_index.draw +dEQP-VK.draw.shader_draw_parameters.draw_index.draw_instanced +dEQP-VK.draw.shader_draw_parameters.draw_index.draw_indexed +dEQP-VK.draw.shader_draw_parameters.draw_index.draw_indexed_instanced dEQP-VK.compute.basic.empty_shader dEQP-VK.compute.basic.ubo_to_ssbo_single_invocation dEQP-VK.compute.basic.ubo_to_ssbo_single_group -- 2.7.4