blob: 67694ef377bc89932b4fe5a06c8800de2a76525b [file] [log] [blame]
/*-------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2017 Khronos Group
*
* 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 API Maintenance3 Check test - checks structs and function from VK_KHR_maintenance3
*//*--------------------------------------------------------------------*/
#include "tcuTestLog.hpp"
#include "vkQueryUtil.hpp"
#include "vktApiMaintenance3Check.hpp"
#include "vktTestCase.hpp"
#define VK_DESCRIPTOR_TYPE_LAST (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 1)
using namespace vk;
namespace vkt
{
namespace api
{
namespace
{
using ::std::string;
using ::std::vector;
typedef vk::VkPhysicalDeviceProperties DevProp1;
typedef vk::VkPhysicalDeviceProperties2 DevProp2;
typedef vk::VkPhysicalDeviceMaintenance3Properties MainDevProp3;
void checkSupport (const Context& m_context)
{
const vector<string> extensions = m_context.getDeviceExtensions();
if (!isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_maintenance3"))
TCU_THROW(NotSupportedError, "VK_KHR_maintenance3 extension is not supported");
}
class Maintenance3StructTestInstance : public TestInstance
{
public:
Maintenance3StructTestInstance (Context& ctx)
: TestInstance (ctx)
{}
virtual tcu::TestStatus iterate (void)
{
checkSupport(m_context);
tcu::TestLog& log = m_context.getTestContext().getLog();
// these variables are equal to minimal values for maxMemoryAllocationSize and maxPerSetDescriptors
const deUint32 maxMemoryAllocationSize = 1073741824u;
const deUint32 maxDescriptorsInSet = 1024u;
// set values to be a bit smaller than required minimum values
MainDevProp3 mainProp3 =
{
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, //VkStructureType sType;
DE_NULL, //void* pNext;
maxDescriptorsInSet - 1u, //deUint32 maxPerSetDescriptors;
maxMemoryAllocationSize - 1u //VkDeviceSize maxMemoryAllocationSize;
};
DevProp2 prop2;
deMemset(&prop2, 0, sizeof(prop2)); // zero the structure
prop2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
prop2.pNext = &mainProp3;
m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &prop2);
if (mainProp3.maxMemoryAllocationSize < maxMemoryAllocationSize)
return tcu::TestStatus::fail("Fail");
if (mainProp3.maxPerSetDescriptors < maxDescriptorsInSet)
return tcu::TestStatus::fail("Fail");
log << tcu::TestLog::Message << "maxMemoryAllocationSize: " << mainProp3.maxMemoryAllocationSize << tcu::TestLog::EndMessage;
log << tcu::TestLog::Message << "maxPerSetDescriptors: " << mainProp3.maxPerSetDescriptors << tcu::TestLog::EndMessage;
return tcu::TestStatus::pass("Pass");
}
};
class Maintenance3StructTestCase : public TestCase
{
public:
Maintenance3StructTestCase (tcu::TestContext& testCtx)
: TestCase(testCtx, "maintenance3_properties", "tests VkPhysicalDeviceMaintenance3Properties struct")
{}
virtual ~Maintenance3StructTestCase (void)
{}
virtual TestInstance* createInstance (Context& ctx) const
{
return new Maintenance3StructTestInstance(ctx);
}
private:
};
class Maintenance3DescriptorTestInstance : public TestInstance
{
public:
Maintenance3DescriptorTestInstance (Context& ctx)
: TestInstance(ctx)
{}
virtual tcu::TestStatus iterate (void)
{
checkSupport(m_context);
// these variables are equal to minimal values for maxMemoryAllocationSize and maxPerSetDescriptors
const deUint32 maxMemoryAllocationSize = 1073741824u;
const deUint32 maxDescriptorsInSet = 1024u;
MainDevProp3 mainProp3 =
{
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, //VkStructureType sType;
DE_NULL, //void* pNext;
maxDescriptorsInSet, //deUint32 maxPerSetDescriptors;
maxMemoryAllocationSize //VkDeviceSize maxMemoryAllocationSize;
};
DevProp2 prop2 =
{
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, //VkStructureType sType;
&mainProp3, //void* pNext;
VkPhysicalDeviceProperties() //VkPhysicalDeviceProperties properties;
};
DevProp1 prop1;
m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &prop1);
m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &prop2);
// setup for descriptors sets
VkDescriptorSetLayoutBinding descriptorSetLayoutBinding[VK_DESCRIPTOR_TYPE_LAST];
for (deUint32 ndx = 0u; ndx < VK_DESCRIPTOR_TYPE_LAST; ++ndx)
{
descriptorSetLayoutBinding[ndx].binding = ndx;
descriptorSetLayoutBinding[ndx].descriptorType = static_cast<VkDescriptorType>(ndx);
descriptorSetLayoutBinding[ndx].descriptorCount = mainProp3.maxPerSetDescriptors;
descriptorSetLayoutBinding[ndx].stageFlags = VK_SHADER_STAGE_ALL;
descriptorSetLayoutBinding[ndx].pImmutableSamplers = DE_NULL;
}
// VkDescriptorSetLayoutCreateInfo setup
vk::VkDescriptorSetLayoutCreateInfo pCreateInfo =
{
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, //VkStructureType sType;
DE_NULL, //const void* pNext;
0u, //VkDescriptorSetLayoutCreateFlags flags;
1u, //deUint32 bindingCount;
DE_NULL //const VkDescriptorSetLayoutBinding* pBindings;
};
// VkDescriptorSetLayoutSupport setup
vk::VkDescriptorSetLayoutSupport pSupport =
{
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, //VkStructureType sType;
DE_NULL, //void* pNext;
VK_FALSE //VkBool32 supported;
};
// check for single descriptors
for (deUint32 ndx = 0u; ndx < VK_DESCRIPTOR_TYPE_LAST; ++ndx)
{
pCreateInfo.pBindings = &descriptorSetLayoutBinding[ndx];
m_context.getDeviceInterface().getDescriptorSetLayoutSupport(m_context.getDevice(), &pCreateInfo, &pSupport);
if(extraLimitCheck(descriptorSetLayoutBinding, ndx, pCreateInfo.bindingCount, prop1))
{
if (pSupport.supported == VK_FALSE)
return tcu::TestStatus::fail("fail");
}
}
// check for accumulated descriptors (all eleven types)
pCreateInfo.pBindings = &descriptorSetLayoutBinding[0u];
pCreateInfo.bindingCount = static_cast<deUint32>(VK_DESCRIPTOR_TYPE_LAST);
deUint32 fraction = mainProp3.maxPerSetDescriptors / static_cast<deUint32>(VK_DESCRIPTOR_TYPE_LAST);
deUint32 rest = mainProp3.maxPerSetDescriptors % static_cast<deUint32>(VK_DESCRIPTOR_TYPE_LAST);
for (deUint32 ndx = 0u; ndx < VK_DESCRIPTOR_TYPE_LAST; ++ndx)
descriptorSetLayoutBinding[ndx].descriptorCount = fraction;
descriptorSetLayoutBinding[0u].descriptorCount += rest;
m_context.getDeviceInterface().getDescriptorSetLayoutSupport(m_context.getDevice(), &pCreateInfo, &pSupport);
if (extraLimitCheck(descriptorSetLayoutBinding, 0u, pCreateInfo.bindingCount, prop1))
{
if (pSupport.supported == VK_FALSE)
return tcu::TestStatus::fail("fail");
}
return tcu::TestStatus::pass("Pass");
}
private:
bool extraLimitCheck (const VkDescriptorSetLayoutBinding* descriptorSetLayoutBinding, const deUint32& curNdx, const deUint32& size, const DevProp1& prop1)
{
deUint32 maxPerStageDescriptorSamplers = 0u;
deUint32 maxPerStageDescriptorUniformBuffers = 0u;
deUint32 maxPerStageDescriptorStorageBuffers = 0u;
deUint32 maxPerStageDescriptorSampledImages = 0u;
deUint32 maxPerStageDescriptorStorageImages = 0u;
deUint32 maxPerStageDescriptorInputAttachments = 0u;
for(deUint32 ndx = curNdx; ndx < curNdx + size; ++ndx)
{
if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER))
maxPerStageDescriptorSamplers += descriptorSetLayoutBinding->descriptorCount;
if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC))
maxPerStageDescriptorUniformBuffers += descriptorSetLayoutBinding->descriptorCount;
if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC))
maxPerStageDescriptorStorageBuffers += descriptorSetLayoutBinding->descriptorCount;
if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER))
maxPerStageDescriptorSampledImages += descriptorSetLayoutBinding->descriptorCount;
if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
(descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER))
maxPerStageDescriptorStorageImages += descriptorSetLayoutBinding->descriptorCount;
if (descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
maxPerStageDescriptorInputAttachments += descriptorSetLayoutBinding->descriptorCount;
}
if (prop1.limits.maxPerStageDescriptorSamplers < maxPerStageDescriptorSamplers)
return false;
if (prop1.limits.maxPerStageDescriptorUniformBuffers < maxPerStageDescriptorUniformBuffers)
return false;
if (prop1.limits.maxPerStageDescriptorStorageBuffers < maxPerStageDescriptorStorageBuffers)
return false;
if (prop1.limits.maxPerStageDescriptorSampledImages < maxPerStageDescriptorSampledImages)
return false;
if (prop1.limits.maxPerStageDescriptorStorageImages < maxPerStageDescriptorStorageImages)
return false;
if (prop1.limits.maxPerStageDescriptorInputAttachments < maxPerStageDescriptorInputAttachments)
return false;
return true;
}
};
class Maintenance3DescriptorTestCase : public TestCase
{
public:
Maintenance3DescriptorTestCase (tcu::TestContext& testCtx)
: TestCase(testCtx, "descriptor_set", "tests vkGetDescriptorSetLayoutSupport struct")
{}
virtual ~Maintenance3DescriptorTestCase (void)
{}
virtual TestInstance* createInstance (Context& ctx) const
{
return new Maintenance3DescriptorTestInstance(ctx);
}
private:
};
} // anonymous
tcu::TestCaseGroup* createMaintenance3Tests (tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> main3Tests(new tcu::TestCaseGroup(testCtx, "maintenance3_check", "Maintenance3 Tests"));
main3Tests->addChild(new Maintenance3StructTestCase(testCtx));
main3Tests->addChild(new Maintenance3DescriptorTestCase(testCtx));
return main3Tests.release();
}
} // api
} // vkt