Set up test groups for SPIR-V assembly tests.
Set up Vulkan environment for compute pipeline.
Added a simple compute shader which just negates data from input
buffer. And test SPIR-V instruction OpNop based on that.
Change-Id: I8ccd518d9441899667edd58a042315780b068d1e
add_subdirectory(api)
add_subdirectory(pipeline)
add_subdirectory(binding_model)
+add_subdirectory(spirv_assembly)
include_directories(
api
pipeline
binding_model
+ spirv_assembly
)
set(DEQP_VK_COMMON_SRCS
deqp-vk-api
deqp-vk-pipeline
deqp-vk-binding-model
+ deqp-vk-spirv-assembly
)
if (DE_OS_IS_WIN32 OR DE_OS_IS_UNIX OR DE_OS_IS_OSX)
--- /dev/null
+# SPIR-V assembly tests
+
+include_directories(..)
+
+set(DEQP_VK_SPIRV_ASSEMBLY_SRCS
+ vktSpvAsmComputeShaderCase.cpp
+ vktSpvAsmComputeShaderCase.hpp
+ vktSpvAsmComputeShaderTestUtil.cpp
+ vktSpvAsmComputeShaderTestUtil.hpp
+ vktSpvAsmInstructionTests.cpp
+ vktSpvAsmInstructionTests.hpp
+ vktSpvAsmTests.cpp
+ vktSpvAsmTests.hpp
+ )
+
+set(DEQP_VK_SPIRV_ASSEMBLY_LIBS
+ tcutil
+ vkutil
+ )
+
+add_library(deqp-vk-spirv-assembly STATIC ${DEQP_VK_SPIRV_ASSEMBLY_SRCS})
+target_link_libraries(deqp-vk-spirv-assembly ${DEQP_VK_SPIRV_ASSEMBLY_LIBS})
--- /dev/null
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Test Case Skeleton Based on Compute Shaders
+ *//*--------------------------------------------------------------------*/
+
+#include "vktSpvAsmComputeShaderCase.hpp"
+
+#include "deSharedPtr.hpp"
+
+#include "vkBuilderUtil.hpp"
+#include "vkMemUtil.hpp"
+#include "vkRefUtil.hpp"
+#include "vkQueryUtil.hpp"
+
+namespace
+{
+
+using namespace vk;
+using std::vector;
+
+typedef de::MovePtr<Allocation> AllocationMp;
+typedef de::SharedPtr<Allocation> AllocationSp;
+typedef Unique<VkBuffer> BufferHandleUp;
+typedef de::SharedPtr<BufferHandleUp> BufferHandleSp;
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Create storage buffer, allocate and bind memory for the buffer
+ *
+ * The memory is created as host visible and passed back as a vk::Allocation
+ * instance via outMemory.
+ *//*--------------------------------------------------------------------*/
+Move<VkBuffer> createBufferAndBindMemory (const DeviceInterface& vkdi, const VkDevice& device, Allocator& allocator, size_t numBytes, AllocationMp* outMemory)
+{
+ const VkBufferCreateInfo bufferCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
+ DE_NULL, // pNext
+ numBytes, // size
+ VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
+ 0u, // flags
+ VK_SHARING_MODE_EXCLUSIVE, // sharingMode
+ 0u, // queueFamilyCount
+ DE_NULL, // pQueueFamilyIndices
+ };
+
+ Move<VkBuffer> buffer (createBuffer(vkdi, device, &bufferCreateInfo));
+ const VkMemoryRequirements requirements = getBufferMemoryRequirements(vkdi, device, *buffer);
+ AllocationMp bufferMemory = allocator.allocate(requirements, MemoryRequirement::HostVisible);
+
+ VK_CHECK(vkdi.bindBufferMemory(device, *buffer, bufferMemory->getMemory(), bufferMemory->getOffset()));
+ *outMemory = bufferMemory;
+
+ return buffer;
+}
+
+void setMemory (const DeviceInterface& vkdi, const VkDevice& device, Allocation* destAlloc, size_t numBytes, const void* data)
+{
+ void* const hostPtr = destAlloc->getHostPtr();
+
+ deMemcpy((deUint8*)hostPtr, data, numBytes);
+ flushMappedMemoryRange(vkdi, device, destAlloc->getMemory(), destAlloc->getOffset(), numBytes);
+}
+
+void clearMemory (const DeviceInterface& vkdi, const VkDevice& device, Allocation* destAlloc, size_t numBytes)
+{
+ void* const hostPtr = destAlloc->getHostPtr();
+
+ deMemset((deUint8*)hostPtr, 0, numBytes);
+ flushMappedMemoryRange(vkdi, device, destAlloc->getMemory(), destAlloc->getOffset(), numBytes);
+}
+
+VkDescriptorInfo createDescriptorInfo (VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range)
+{
+ const VkDescriptorInfo info =
+ {
+ 0, // bufferView
+ 0, // sampler
+ 0, // imageView
+ (VkImageLayout)0, // imageLayout
+ { buffer, offset, range }, // bufferInfo
+ };
+
+ return info;
+}
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Create a descriptor set layout with numBindings descriptors
+ *
+ * All descriptors are created for shader storage buffer objects and
+ * compute pipeline.
+ *//*--------------------------------------------------------------------*/
+Move<VkDescriptorSetLayout> createDescriptorSetLayout (const DeviceInterface& vkdi, const VkDevice& device, size_t numBindings)
+{
+ DescriptorSetLayoutBuilder builder;
+
+ for (size_t bindingNdx = 0; bindingNdx < numBindings; ++bindingNdx)
+ builder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
+
+ return builder.build(vkdi, device);
+}
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Create a pipeline layout with one descriptor set
+ *//*--------------------------------------------------------------------*/
+Move<VkPipelineLayout> createPipelineLayout (const DeviceInterface& vkdi, const VkDevice& device, VkDescriptorSetLayout descriptorSetLayout)
+{
+ const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
+ DE_NULL, // pNext
+ 1u, // descriptorSetCount
+ &descriptorSetLayout, // pSetLayouts
+ 0u, // pushConstantRangeCount
+ DE_NULL, // pPushConstantRanges
+ };
+
+ return createPipelineLayout(vkdi, device, &pipelineLayoutCreateInfo);
+}
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Create a one-time descriptor pool for one descriptor set
+ *
+ * The pool supports numDescriptors storage buffer descriptors.
+ *//*--------------------------------------------------------------------*/
+inline Move<VkDescriptorPool> createDescriptorPool (const DeviceInterface& vkdi, const VkDevice& device, deUint32 numDescriptors)
+{
+ return DescriptorPoolBuilder()
+ .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, numDescriptors)
+ .build(vkdi, device, VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, /* maxSets = */ 1);
+}
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Create a descriptor set
+ *
+ * The descriptor set's layout should contain numViews descriptors.
+ * All the descriptors represent buffer views, and they are sequentially
+ * binded to binding point starting from 0.
+ *//*--------------------------------------------------------------------*/
+Move<VkDescriptorSet> createDescriptorSet (const DeviceInterface& vkdi, const VkDevice& device, VkDescriptorPool pool, VkDescriptorSetLayout layout, size_t numViews, const vector<VkDescriptorInfo>& descriptorInfos)
+{
+ Move<VkDescriptorSet> descriptorSet = allocDescriptorSet(vkdi, device, pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
+ DescriptorSetUpdateBuilder builder;
+
+ for (deUint32 descriptorNdx = 0; descriptorNdx < numViews; ++descriptorNdx)
+ builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(descriptorNdx), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfos[descriptorNdx]);
+ builder.update(vkdi, device);
+
+ return descriptorSet;
+}
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Create a shader from the given shader module
+ *
+ * The entry point of the shader is assumed to be "main".
+ *//*--------------------------------------------------------------------*/
+Move<VkShader> createShader (const DeviceInterface& vkdi, const VkDevice& device, VkShaderModule module)
+{
+ const VkShaderCreateInfo shaderCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, // sType
+ DE_NULL, // pNext
+ module, // module
+ "main", // pName
+ 0u, // flags
+ VK_SHADER_STAGE_COMPUTE, // stage
+ };
+
+ return createShader(vkdi, device, &shaderCreateInfo);
+}
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Create a compute pipeline based on the given shader
+ *//*--------------------------------------------------------------------*/
+Move<VkPipeline> createComputePipeline (const DeviceInterface& vkdi, const VkDevice& device, VkPipelineLayout pipelineLayout, VkShader shader)
+{
+ const VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
+ DE_NULL, // pNext
+ VK_SHADER_STAGE_COMPUTE, // stage
+ shader, // shader
+ DE_NULL, // pSpecializationInfo
+ };
+ const VkComputePipelineCreateInfo pipelineCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // sType
+ DE_NULL, // pNext
+ pipelineShaderStageCreateInfo, // cs
+ 0u, // flags
+ pipelineLayout, // layout
+ (VkPipeline)0, // basePipelineHandle
+ 0u, // basePipelineIndex
+ };
+
+ return createComputePipeline(vkdi, device, (VkPipelineCache)0u, &pipelineCreateInfo);
+}
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Create a command pool
+ *
+ * The created command pool is designated for use on the queue type
+ * represented by the given queueFamilyIndex.
+ *//*--------------------------------------------------------------------*/
+Move<VkCmdPool> createCommandPool (const DeviceInterface& vkdi, VkDevice device, deUint32 queueFamilyIndex)
+{
+ const VkCmdPoolCreateInfo cmdPoolCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // sType
+ DE_NULL, // pNext
+ queueFamilyIndex, // queueFamilyIndex
+ 0u // flags
+ };
+
+ return createCommandPool(vkdi, device, &cmdPoolCreateInfo);
+}
+
+} // anonymous
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Test instance for compute pipeline
+ *
+ * The compute shader is specified in the format of SPIR-V assembly, which
+ * is allowed to access MAX_NUM_INPUT_BUFFERS input storage buffers and
+ * MAX_NUM_OUTPUT_BUFFERS output storage buffers maximally. The shader
+ * source and input/output data are given in a ComputeShaderSpec object.
+ *
+ * This instance runs the given compute shader by feeding the data from input
+ * buffers and compares the data in the output buffers with the expected.
+ *//*--------------------------------------------------------------------*/
+class SpvAsmComputeShaderInstance : public TestInstance
+{
+public:
+ SpvAsmComputeShaderInstance (Context& ctx, const ComputeShaderSpec& spec);
+ tcu::TestStatus iterate (void);
+
+private:
+ const ComputeShaderSpec& m_shaderSpec;
+};
+
+// ComputeShaderTestCase implementations
+
+SpvAsmComputeShaderCase::SpvAsmComputeShaderCase (tcu::TestContext& testCtx, const char* name, const char* description, const ComputeShaderSpec& spec)
+ : TestCase (testCtx, name, description)
+ , m_shaderSpec (spec)
+{
+}
+
+void SpvAsmComputeShaderCase::initPrograms (SourceCollections& programCollection) const
+{
+ programCollection.spirvAsmSources.add("compute") << m_shaderSpec.assembly.c_str();
+}
+
+TestInstance* SpvAsmComputeShaderCase::createInstance (Context& ctx) const
+{
+ return new SpvAsmComputeShaderInstance(ctx, m_shaderSpec);
+}
+
+// ComputeShaderTestInstance implementations
+
+SpvAsmComputeShaderInstance::SpvAsmComputeShaderInstance (Context& ctx, const ComputeShaderSpec& spec)
+ : TestInstance (ctx)
+ , m_shaderSpec (spec)
+{
+}
+
+tcu::TestStatus SpvAsmComputeShaderInstance::iterate (void)
+{
+ const DeviceInterface& vkdi = m_context.getDeviceInterface();
+ const VkDevice& device = m_context.getDevice();
+ Allocator& allocator = m_context.getDefaultAllocator();
+
+ vector<AllocationSp> inputAllocs;
+ vector<AllocationSp> outputAllocs;
+ vector<BufferHandleSp> inputBuffers;
+ vector<BufferHandleSp> outputBuffers;
+ vector<VkDescriptorInfo> descriptorInfos;
+
+ DE_ASSERT(!m_shaderSpec.outputs.empty());
+ const size_t numBuffers = m_shaderSpec.inputs.size() + m_shaderSpec.outputs.size();
+
+ // Create buffer object, allocate storage, and create view for all input/output buffers.
+
+ for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
+ {
+ AllocationMp alloc;
+ const BufferSp& input = m_shaderSpec.inputs[inputNdx];
+ const size_t numBytes = input->getNumBytes();
+ BufferHandleUp* buffer = new BufferHandleUp(createBufferAndBindMemory(vkdi, device, allocator, numBytes, &alloc));
+
+ setMemory(vkdi, device, &*alloc, numBytes, input->data());
+ descriptorInfos.push_back(createDescriptorInfo(**buffer, 0u, numBytes));
+ inputBuffers.push_back(BufferHandleSp(buffer));
+ inputAllocs.push_back(de::SharedPtr<Allocation>(alloc.release()));
+ }
+
+ for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
+ {
+ AllocationMp alloc;
+ const BufferSp& output = m_shaderSpec.outputs[outputNdx];
+ const size_t numBytes = output->getNumBytes();
+ BufferHandleUp* buffer = new BufferHandleUp(createBufferAndBindMemory(vkdi, device, allocator, numBytes, &alloc));
+
+ clearMemory(vkdi, device, &*alloc, numBytes);
+ descriptorInfos.push_back(createDescriptorInfo(**buffer, 0u, numBytes));
+ outputBuffers.push_back(BufferHandleSp(buffer));
+ outputAllocs.push_back(de::SharedPtr<Allocation>(alloc.release()));
+ }
+
+ // Create layouts and descriptor set.
+
+ Unique<VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout(vkdi, device, numBuffers));
+ Unique<VkPipelineLayout> pipelineLayout (createPipelineLayout(vkdi, device, *descriptorSetLayout));
+ Unique<VkDescriptorPool> descriptorPool (createDescriptorPool(vkdi, device, (deUint32)numBuffers));
+ Unique<VkDescriptorSet> descriptorSet (createDescriptorSet(vkdi, device, *descriptorPool, *descriptorSetLayout, numBuffers, descriptorInfos));
+
+ // Create compute shader and pipeline.
+
+ const ProgramBinary& binary = m_context.getBinaryCollection().get("compute");
+ Unique<VkShaderModule> module (createShaderModule(vkdi, device, binary, (VkShaderModuleCreateFlags)0u));
+ Unique<VkShader> shader (createShader(vkdi, device, *module));
+
+ Unique<VkPipeline> computePipeline (createComputePipeline(vkdi, device, *pipelineLayout, *shader));
+
+ // Create command buffer and record commands
+
+ const Unique<VkCmdPool> cmdPool (createCommandPool(vkdi, device, m_context.getUniversalQueueFamilyIndex()));
+ const VkCmdBufferCreateInfo cmdBufferCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // sType
+ NULL, // pNext
+ *cmdPool, // cmdPool
+ VK_CMD_BUFFER_LEVEL_PRIMARY, // level
+ 0u // flags
+ };
+
+ Unique<VkCmdBuffer> cmdBuffer (createCommandBuffer(vkdi, device, &cmdBufferCreateInfo));
+
+ const VkCmdBufferBeginInfo cmdBufferBeginInfo =
+ {
+ VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, // sType
+ DE_NULL, // pNext
+ VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
+ (VkRenderPass)0u, // renderPass
+ 0u, // subpass
+ (VkFramebuffer)0u, // framebuffer
+ };
+
+ const tcu::IVec3& numWorkGroups = m_shaderSpec.numWorkGroups;
+
+ VK_CHECK(vkdi.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
+ vkdi.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
+ vkdi.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
+ vkdi.cmdDispatch(*cmdBuffer, numWorkGroups.x(), numWorkGroups.y(), numWorkGroups.z());
+ VK_CHECK(vkdi.endCommandBuffer(*cmdBuffer));
+
+ // Create fence and run.
+
+ const VkFenceCreateInfo fenceCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // sType
+ NULL, // pNext
+ 0 // flags
+ };
+ const Unique<VkFence> cmdCompleteFence (createFence(vkdi, device, &fenceCreateInfo));
+ const deUint64 infiniteTimeout = ~(deUint64)0u;
+
+ VK_CHECK(vkdi.queueSubmit(m_context.getUniversalQueue(), 1, &cmdBuffer.get(), *cmdCompleteFence));
+ VK_CHECK(vkdi.waitForFences(device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
+
+ // Check output.
+
+ for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
+ {
+ const BufferSp& expectedOutput = m_shaderSpec.outputs[outputNdx];
+ if (deMemCmp(expectedOutput->data(), outputAllocs[outputNdx]->getHostPtr(), expectedOutput->getNumBytes()))
+ return tcu::TestStatus::fail("Output doesn't match with expected");
+ }
+
+ return tcu::TestStatus::pass("Ouput match with expected");
+}
+
+} // SpirVAssembly
+} // vkt
--- /dev/null
+#ifndef _VKTSPVASMCOMPUTESHADERCASE_HPP
+#define _VKTSPVASMCOMPUTESHADERCASE_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Test Case Skeleton Based on Compute Shaders
+ *//*--------------------------------------------------------------------*/
+
+#include "vkPrograms.hpp"
+#include "vktTestCase.hpp"
+
+#include "vktSpvAsmComputeShaderTestUtil.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+class SpvAsmComputeShaderCase : public TestCase
+{
+public:
+ SpvAsmComputeShaderCase (tcu::TestContext& testCtx, const char* name, const char* description, const ComputeShaderSpec& spec);
+ void initPrograms (vk::SourceCollections& programCollection) const;
+ TestInstance* createInstance (Context& ctx) const;
+
+private:
+ ComputeShaderSpec m_shaderSpec;
+};
+
+} // SpirVAssembly
+} // vkt
+
+#endif // _VKTSPVASMCOMPUTESHADERCASE_HPP
--- /dev/null
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Compute Shader Based Test Case Utility Structs/Functions
+ *//*--------------------------------------------------------------------*/
+
+#include "vktSpvAsmComputeShaderTestUtil.hpp"
+
+DE_EMPTY_CPP_FILE
--- /dev/null
+#ifndef _VKTSPVASMCOMPUTESHADERTESTUTIL_HPP
+#define _VKTSPVASMCOMPUTESHADERTESTUTIL_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Compute Shader Based Test Case Utility Structs/Functions
+ *//*--------------------------------------------------------------------*/
+
+#include "deDefs.h"
+#include "deSharedPtr.hpp"
+#include "tcuVector.hpp"
+
+#include <string>
+#include <vector>
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Abstract class for an input/output storage buffer object
+ *//*--------------------------------------------------------------------*/
+class BufferInterface
+{
+public:
+ virtual ~BufferInterface (void) {}
+
+ virtual size_t getNumBytes (void) const = 0;
+ virtual const void* data (void) const = 0;
+};
+
+typedef de::SharedPtr<BufferInterface> BufferSp;
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Concrete class for an input/output storage buffer object
+ *//*--------------------------------------------------------------------*/
+template<typename E>
+class Buffer : public BufferInterface
+{
+public:
+ Buffer (const std::vector<E>& elements)
+ : m_elements(elements)
+ {}
+
+ size_t getNumBytes (void) const { return m_elements.size() * sizeof(E); }
+ const void* data (void) const { return &m_elements.front(); }
+
+private:
+ std::vector<E> m_elements;
+};
+
+typedef Buffer<float> Float32Buffer;
+
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Specification for a compute shader.
+ *
+ * This struct bundles SPIR-V assembly code, input and expected output
+ * together.
+ *//*--------------------------------------------------------------------*/
+struct ComputeShaderSpec
+{
+ std::string assembly;
+ std::vector<BufferSp> inputs;
+ std::vector<BufferSp> outputs;
+ tcu::IVec3 numWorkGroups;
+};
+
+} // SpirVAssembly
+} // vkt
+
+#endif // _VKTSPVASMCOMPUTESHADERTESTUTIL_HPP
--- /dev/null
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief SPIR-V Assembly Tests for Instructions (special opcode/operand)
+ *//*--------------------------------------------------------------------*/
+
+#include "vktSpvAsmInstructionTests.hpp"
+
+#include "deUniquePtr.hpp"
+
+#include "vktSpvAsmComputeShaderCase.hpp"
+#include "vktSpvAsmComputeShaderTestUtil.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+namespace
+{
+
+using std::vector;
+using tcu::IVec3;
+
+SpvAsmComputeShaderCase* createOpNopTestCase (tcu::TestContext& testCtx)
+{
+ ComputeShaderSpec spec;
+ // Based on GLSL source code:
+ //
+ // #version 430
+ //
+ // layout(set = 0, binding = 0) readonly buffer Input {
+ // float elements[];
+ // } input_data;
+ // layout(set = 0, binding = 1) writeonly buffer Output {
+ // float elements[];
+ // } output_data;
+ //
+ // layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+ //
+ // void main() {
+ // uint x = gl_GlobalInvocationID.x;
+ // output_data.elements[x] = -input_data.elements[x];
+ // }
+ spec.assembly =
+ "OpNop\n" // As the first instruction
+
+ "OpSource GLSL 430\n"
+ "OpCapability Shader\n"
+ "%std450 = OpExtInstImport \"GLSL.std.450\"\n"
+ "OpMemoryModel Logical GLSL450\n"
+
+ "OpEntryPoint GLCompute %main \"main\"\n"
+
+ "OpNop\n" // After OpEntryPoint but before any type definitions
+
+ "OpExecutionMode %main LocalSize 1 1 1\n"
+
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+ "OpName %outbuf \"Output\"\n"
+ "OpMemberName %outbuf 0 \"elements\"\n"
+ "OpName %outdata \"output_data\"\n"
+ "OpName %inbuf \"Input\"\n"
+ "OpMemberName %inbuf 0 \"elements\"\n"
+ "OpName %indata \"input_data\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+ "OpDecorate %inbuf GLSLShared\n"
+ "OpDecorate %inbuf BufferBlock\n"
+ "OpDecorate %indata DescriptorSet 0\n"
+ "OpDecorate %indata Binding 0\n"
+ "OpDecorate %outbuf GLSLShared\n"
+ "OpDecorate %outbuf BufferBlock\n"
+ "OpDecorate %outdata DescriptorSet 0\n"
+ "OpDecorate %outdata Binding 1\n"
+
+ "%void = OpTypeVoid\n"
+ "%voidf = OpTypeFunction %void\n"
+
+ " OpNop\n" // In the middle of type definitions
+
+ "%u32 = OpTypeInt 32 0\n"
+ "%uvec3 = OpTypeVector %u32 3\n"
+ "%uvec3ptr = OpTypePointer Input %uvec3\n"
+ "%f32 = OpTypeFloat 32\n"
+ "%f32ptr = OpTypePointer Uniform %f32\n"
+ "%f32arr = OpTypeRuntimeArray %f32\n"
+ "%outbuf = OpTypeStruct %f32arr\n"
+ "%outbufptr = OpTypePointer Uniform %outbuf\n"
+ "%inbuf = OpTypeStruct %f32arr\n"
+ "%inbufptr = OpTypePointer Uniform %inbuf\n"
+ "%i32 = OpTypeInt 32 1\n"
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%indata = OpVariable %inbufptr Uniform\n"
+ "%outdata = OpVariable %outbufptr Uniform\n"
+ "%zero = OpConstant %i32 0\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+
+ " OpNop\n" // Inside a function body
+
+ "%inloc = OpAccessChain %f32ptr %indata %zero %x\n"
+ "%inval = OpLoad %f32 %inloc\n"
+ "%neg = OpFNegate %f32 %inval\n"
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %x\n"
+ " OpStore %outloc %neg\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n";
+
+ const int numElements = 100;
+ vector<float> positiveFloats(numElements, 42.42f);
+ vector<float> negativeFloats(numElements, -42.42f);
+
+ spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
+
+ spec.numWorkGroups = IVec3(numElements, 1, 1);
+
+ return new SpvAsmComputeShaderCase(testCtx, "opnop_test", "Test the OpNop instruction", spec);
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createInstructionTests (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> instructionTests (new tcu::TestCaseGroup(testCtx, "instruction", "Instructions with special opcodes/operands"));
+
+ instructionTests->addChild(createOpNopTestCase(testCtx));
+
+ return instructionTests.release();
+}
+
+} // SpirVAssembly
+} // vkt
--- /dev/null
+#ifndef _VKTSPVASMINSTRUCTIONTESTS_HPP
+#define _VKTSPVASMINSTRUCTIONTESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief SPIR-V Assembly Tests for Instructions (special opcode/operand)
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+tcu::TestCaseGroup* createInstructionTests (tcu::TestContext& testCtx);
+
+} // SpirVAssembly
+} // vkt
+
+#endif // _VKTSPVASMINSTRUCTIONTESTS_HPP
--- /dev/null
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief SPIR-V Assembly Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktSpvAsmTests.hpp"
+
+#include "deUniquePtr.hpp"
+
+#include "vktSpvAsmInstructionTests.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> spirVAssemblyTests (new tcu::TestCaseGroup(testCtx, "spirv_assembly", "SPIR-V Assembly tests"));
+
+ spirVAssemblyTests->addChild(createInstructionTests(testCtx));
+ // \todo [2015-09-28 antiagainst] control flow
+ // \todo [2015-09-28 antiagainst] multiple entry points for the same shader stage
+ // \todo [2015-09-28 antiagainst] multiple shaders in the same module
+
+ return spirVAssemblyTests.release();
+}
+
+} // SpirVAssembly
+} // vkt
--- /dev/null
+#ifndef _VKTSPVASMESTS_HPP
+#define _VKTSPVASMESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief SPIR-V Assembly Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx);
+
+} // SpirVAssembly
+} // vkt
+
+#endif // _VKTSPVASMESTS_HPP
#include "vktApiTests.hpp"
#include "vktPipelineTests.hpp"
#include "vktBindingModelTests.hpp"
+#include "vktSpvAsmTests.hpp"
#include <vector>
#include <sstream>
addChild(api::createTests (m_testCtx));
addChild(pipeline::createTests (m_testCtx));
addChild(BindingModel::createTests (m_testCtx));
+ addChild(SpirVAssembly::createTests (m_testCtx));
}
} // vkt