*
*//*!
* \file
- * \brief Tests for VK_VALVE_mutable_descriptor_type.
+ * \brief Tests for VK_VALVE_mutable_descriptor_type and VK_EXT_mutable_descriptor_type.
*//*--------------------------------------------------------------------*/
-#include "vktBindingValveMutableTests.hpp"
+#include "vktBindingMutableTests.hpp"
#include "vktTestCase.hpp"
+#include "vktTestGroupUtil.hpp"
+#include "vktCustomInstancesDevices.hpp"
+
+#include "tcuCommandLine.hpp"
#include "vkDefs.hpp"
#include "vkRefUtil.hpp"
using namespace vk;
+de::SharedPtr<Move<vk::VkDevice>> g_singletonDevice;
+
+static std::vector<std::string> removeExtensions (const std::vector<std::string>& a, const std::vector<const char*>& b)
+{
+ std::vector<std::string> res;
+ std::set<std::string> removeExts (b.begin(), b.end());
+
+ for (std::vector<std::string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
+ {
+ if (!de::contains(removeExts, *aIter))
+ res.push_back(*aIter);
+ }
+
+ return res;
+}
+
+VkDevice getDevice(Context& context)
+{
+ if (!g_singletonDevice)
+ {
+ const float queuePriority = 1.0f;
+
+ // Create a universal queue that supports graphics and compute
+ const VkDeviceQueueCreateInfo queueParams
+ {
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkDeviceQueueCreateFlags flags;
+ context.getUniversalQueueFamilyIndex(), // deUint32 queueFamilyIndex;
+ 1u, // deUint32 queueCount;
+ &queuePriority // const float* pQueuePriorities;
+ };
+
+ // \note Extensions in core are not explicitly enabled even though
+ // they are in the extension list advertised to tests.
+ std::vector<const char*> extensionPtrs;
+ std::vector<const char*> coreExtensions;
+ getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
+ std::vector<std::string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));
+
+ extensionPtrs.resize(nonCoreExtensions.size());
+
+ for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
+ extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
+
+ VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationStructureFeatures = initVulkanStructure();
+ VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures = initVulkanStructure(&accelerationStructureFeatures);
+ VkPhysicalDeviceRayTracingPipelineFeaturesKHR rayTracingPipelineFeatures = initVulkanStructure(&bufferDeviceAddressFeatures);
+ VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures = initVulkanStructure(&rayTracingPipelineFeatures);
+ VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT mutableDescriptorTypeFeatures = initVulkanStructure(&rayQueryFeatures);
+ VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures = initVulkanStructure(&mutableDescriptorTypeFeatures);
+ VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(&descriptorIndexingFeatures);
+
+ context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
+
+ const VkDeviceCreateInfo deviceCreateInfo
+ {
+ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType;
+ &features2, //pNext;
+ (VkDeviceCreateFlags)0u, //flags
+ 1, //queueRecordCount;
+ &queueParams, //pRequestedQueues;
+ 0, //layerCount;
+ DE_NULL, //ppEnabledLayerNames;
+ (deUint32)extensionPtrs.size(), // deUint32 enabledExtensionCount;
+ (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]), // const char* const* ppEnabledExtensionNames;
+ DE_NULL, //pEnabledFeatures;
+ };
+
+ Move<VkDevice> device = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceCreateInfo);
+ g_singletonDevice = de::SharedPtr<Move<VkDevice>>(new Move<VkDevice>(device));
+ }
+
+ return g_singletonDevice->get();
+}
+
deUint32 getDescriptorNumericValue (deUint32 iteration, deUint32 bindingIdx, deUint32 descriptorIdx = 0u)
{
// When assigning numeric values for the descriptor contents, each descriptor will get 0x5aIIBBDD. II is an octed containing the
{
return std::vector<VkDescriptorType>
{
- VK_DESCRIPTOR_TYPE_MUTABLE_VALVE,
+ VK_DESCRIPTOR_TYPE_MUTABLE_EXT,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT,
DTFB_INLINE_UNIFORM_BLOCK_EXT = (1 << 11),
DTFB_ACCELERATION_STRUCTURE_KHR = (1 << 12),
DTFB_ACCELERATION_STRUCTURE_NV = (1 << 13),
- DTFB_MUTABLE_VALVE = (1 << 14),
+ DTFB_MUTABLE = (1 << 14),
};
using DescriptorTypeFlags = deUint32;
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: return DTFB_INLINE_UNIFORM_BLOCK_EXT;
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: return DTFB_ACCELERATION_STRUCTURE_KHR;
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: return DTFB_ACCELERATION_STRUCTURE_NV;
- case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE: return DTFB_MUTABLE_VALVE;
+ case VK_DESCRIPTOR_TYPE_MUTABLE_EXT: return DTFB_MUTABLE;
default: break;
}
if (bitfield & DTFB_INLINE_UNIFORM_BLOCK_EXT) result.push_back(VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT);
if (bitfield & DTFB_ACCELERATION_STRUCTURE_KHR) result.push_back(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR);
if (bitfield & DTFB_ACCELERATION_STRUCTURE_NV) result.push_back(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV);
- if (bitfield & DTFB_MUTABLE_VALVE) result.push_back(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE);
+ if (bitfield & DTFB_MUTABLE) result.push_back(VK_DESCRIPTOR_TYPE_MUTABLE_EXT);
return result;
}
DE_UNREF(kBeginForbidden);
DE_UNREF(kEndForbidden);
- if (type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)
+ if (type != VK_DESCRIPTOR_TYPE_MUTABLE_EXT)
{
DE_ASSERT(mutableTypesVec.empty());
}
deUint32 maxTypes () const override
{
- if (type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)
+ if (type != VK_DESCRIPTOR_TYPE_MUTABLE_EXT)
return 1u;
const auto vecSize = mutableTypesVec.size();
DE_ASSERT(vecSize <= std::numeric_limits<deUint32>::max());
std::vector<VkDescriptorType> usedTypes () const
{
- if (type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)
+ if (type != VK_DESCRIPTOR_TYPE_MUTABLE_EXT)
return std::vector<VkDescriptorType>(1u, type);
return mutableTypesVec;
}
DE_UNREF(iteration);
static const auto kMandatoryMutableTypeFlags = toDescriptorTypeFlags(getMandatoryMutableTypes());
- if (type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)
+ if (type == VK_DESCRIPTOR_TYPE_MUTABLE_EXT)
{
const auto descFlags = toDescriptorTypeFlags(mutableTypesVec);
return de::MovePtr<BindingInterface>(new SingleBinding(type, toDescriptorTypeVector(descFlags)));
// Convert the binding to mutable using a wider set of descriptor types if possible, including the binding type.
const auto descFlags = (kMandatoryMutableTypeFlags | toDescriptorTypeFlagBit(type));
- return de::MovePtr<BindingInterface>(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, toDescriptorTypeVector(descFlags)));
+ return de::MovePtr<BindingInterface>(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_EXT, toDescriptorTypeVector(descFlags)));
}
de::MovePtr<BindingInterface> toNonMutable (deUint32 iteration) const override
// Makes a descriptor pool that can be used when allocating descriptors for this set.
Move<VkDescriptorPool> makeDescriptorPool (const DeviceInterface& vkd, VkDevice device, PoolMutableStrategy strategy, VkDescriptorPoolCreateFlags flags) const
{
- std::vector<VkDescriptorPoolSize> poolSizes;
- std::vector<std::vector<VkDescriptorType>> mutableTypesVec;
- std::vector<VkMutableDescriptorTypeListVALVE> mutableTypeLists;
+ std::vector<VkDescriptorPoolSize> poolSizes;
+ std::vector<std::vector<VkDescriptorType>> mutableTypesVec;
+ std::vector<VkMutableDescriptorTypeListEXT> mutableTypeLists;
// Make vector element addresses stable.
const auto bindingCount = numBindings();
if (strategy == PoolMutableStrategy::KEEP_TYPES || strategy == PoolMutableStrategy::EXPAND_TYPES)
{
- if (mainType == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)
+ if (mainType == VK_DESCRIPTOR_TYPE_MUTABLE_EXT)
{
if (strategy == PoolMutableStrategy::KEEP_TYPES)
{
}
const auto& lastVec = mutableTypesVec.back();
- const VkMutableDescriptorTypeListVALVE typeList = { static_cast<deUint32>(lastVec.size()), de::dataOrNull(lastVec) };
+ const VkMutableDescriptorTypeListEXT typeList = { static_cast<deUint32>(lastVec.size()), de::dataOrNull(lastVec) };
mutableTypeLists.push_back(typeList);
}
else
{
- const VkMutableDescriptorTypeListVALVE typeList = { 0u, nullptr };
+ const VkMutableDescriptorTypeListEXT typeList = { 0u, nullptr };
mutableTypeLists.push_back(typeList);
}
}
poolCreateInfo.poolSizeCount = static_cast<deUint32>(poolSizes.size());
poolCreateInfo.pPoolSizes = de::dataOrNull(poolSizes);
- VkMutableDescriptorTypeCreateInfoVALVE mutableInfo = initVulkanStructure();
+ VkMutableDescriptorTypeCreateInfoEXT mutableInfo = initVulkanStructure();
if (strategy == PoolMutableStrategy::KEEP_TYPES || strategy == PoolMutableStrategy::EXPAND_TYPES)
{
DescriptorSetLayoutResult makeOrCheckDescriptorSetLayout (bool checkOnly, const DeviceInterface& vkd, VkDevice device, VkShaderStageFlags stageFlags, VkDescriptorSetLayoutCreateFlags createFlags) const
{
- const auto numIterations = maxTypes();
- std::vector<VkDescriptorSetLayoutBinding> bindingsVec;
- std::vector<std::vector<VkDescriptorType>> mutableTypesVec;
- std::vector<VkMutableDescriptorTypeListVALVE> mutableTypeLists;
+ const auto numIterations = maxTypes();
+ std::vector<VkDescriptorSetLayoutBinding> bindingsVec;
+ std::vector<std::vector<VkDescriptorType>> mutableTypesVec;
+ std::vector<VkMutableDescriptorTypeListEXT> mutableTypeLists;
// Make vector element addresses stable.
const auto bindingCount = numBindings();
mutableTypesVec.push_back(binding->mutableTypes());
const auto& lastVec = mutableTypesVec.back();
- const VkMutableDescriptorTypeListVALVE typeList = {
+ const VkMutableDescriptorTypeListEXT typeList = {
static_cast<deUint32>(lastVec.size()), // deUint32 descriptorTypeCount;
de::dataOrNull(lastVec), // const VkDescriptorType* pDescriptorTypes;
};
flagsCreateInfo->pBindingFlags = de::dataOrNull(*bindingFlagsVec);
}
- const VkMutableDescriptorTypeCreateInfoVALVE createInfoValve = {
- VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE,
+ const VkMutableDescriptorTypeCreateInfoEXT createInfoMutable = {
+ VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT,
flagsCreateInfo.get(),
static_cast<deUint32>(mutableTypeLists.size()),
de::dataOrNull(mutableTypeLists),
const VkDescriptorSetLayoutCreateInfo layoutCreateInfo = {
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
- &createInfoValve, // const void* pNext;
+ &createInfoMutable, // const void* pNext;
createFlags, // VkDescriptorSetLayoutCreateFlags flags;
static_cast<deUint32>(bindingsVec.size()), // deUint32 bindingCount;
de::dataOrNull(bindingsVec), // const VkDescriptorSetLayoutBinding* pBindings;
createFlags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
if (isSourceSet && sourceSetType == SourceSetType::HOST_ONLY)
- createFlags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE;
+ createFlags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT;
return createFlags;
}
poolCreateFlags |= VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT;
if (isSourceSet && sourceSetType == SourceSetType::HOST_ONLY)
- poolCreateFlags |= VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE;
+ poolCreateFlags |= VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT;
return poolCreateFlags;
}
void MutableTypesTest::checkSupport (Context& context) const
{
- context.requireDeviceFunctionality("VK_VALVE_mutable_descriptor_type");
+ if (!context.isDeviceFunctionalitySupported("VK_VALVE_mutable_descriptor_type") &&
+ !context.isDeviceFunctionalitySupported("VK_EXT_mutable_descriptor_type"))
+
+ TCU_THROW(NotSupportedError, "VK_VALVE_mutable_descriptor_type or VK_EXT_mutable_descriptor_type is not supported");
+
+ VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT mutableDescriptorType = initVulkanStructure();
+ VkPhysicalDeviceFeatures2KHR features2 = initVulkanStructure(&mutableDescriptorType);
+
+ context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
+
+ if (!mutableDescriptorType.mutableDescriptorType)
+ TCU_THROW(NotSupportedError, "mutableDescriptorType feature is not supported");
// Check ray tracing if needed.
const bool rayTracing = isRayTracingStage(m_params.testingStage);
}
break;
- case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE:
- TCU_THROW(InternalError, "Found VK_DESCRIPTOR_TYPE_MUTABLE_VALVE in list of used descriptor types");
+ case VK_DESCRIPTOR_TYPE_MUTABLE_EXT:
+ TCU_THROW(InternalError, "Found VK_DESCRIPTOR_TYPE_MUTABLE_EXT in list of used descriptor types");
default:
TCU_THROW(InternalError, "Unexpected descriptor type found in list of used descriptor types: " + de::toString(descType));
context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
break;
- case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE:
- TCU_THROW(InternalError, "Found VK_DESCRIPTOR_TYPE_MUTABLE_VALVE in list of used array descriptor types");
+ case VK_DESCRIPTOR_TYPE_MUTABLE_EXT:
+ TCU_THROW(InternalError, "Found VK_DESCRIPTOR_TYPE_MUTABLE_EXT in list of used array descriptor types");
default:
TCU_THROW(InternalError, "Unexpected descriptor type found in list of used descriptor types: " + de::toString(descType));
// Check layout support.
{
const auto& vkd = context.getDeviceInterface();
- const auto device = context.getDevice();
+ const auto device = getDevice(context);
const auto stageFlags = m_params.getStageFlags();
{
tcu::TestStatus MutableTypesInstance::iterate ()
{
- const auto device = m_context.getDevice();
+ const auto& vki = m_context.getInstanceInterface();
+ const auto& vkd = m_context.getDeviceInterface();
+ const auto device = getDevice(m_context);
const auto physDev = m_context.getPhysicalDevice();
const auto qIndex = m_context.getUniversalQueueFamilyIndex();
- const auto queue = m_context.getUniversalQueue();
+ const auto queue = getDeviceQueue(vkd, device, m_context.getUniversalQueueFamilyIndex(), 0);
- const auto& vki = m_context.getInstanceInterface();
- const auto& vkd = m_context.getDeviceInterface();
- auto & alloc = m_context.getDefaultAllocator();
- const auto& paramSet = m_params.descriptorSet;
+ SimpleAllocator alloc(vkd, device, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
+ const auto& paramSet = m_params.descriptorSet;
const auto numIterations = paramSet->maxTypes();
const bool useExternalImage = needsExternalImage(*m_params.descriptorSet);
const bool useExternalSampler = needsExternalSampler(*m_params.descriptorSet);
return de::toLower(de::toString(descriptorType).substr(prefixLen));
}
-tcu::TestCaseGroup* createDescriptorValveMutableTests (tcu::TestContext& testCtx)
+static void createChildren (tcu::TestCaseGroup* testGroup);
+
+static void cleanupGroup (tcu::TestCaseGroup* testGroup)
{
- GroupPtr mainGroup(new tcu::TestCaseGroup(testCtx, "mutable_descriptor", "Tests for VK_VALVE_mutable_descriptor_type"));
+ DE_UNREF(testGroup);
+ // Destroy singleton objects.
+ g_singletonDevice.clear();
+}
+
+tcu::TestCaseGroup* createDescriptorMutableTests (tcu::TestContext& testCtx)
+{
+ return createTestGroup(testCtx, "mutable_descriptor", "Tests for VK_VALVE_mutable_descriptor_type and VK_EXT_mutable_descriptor_type", createChildren, cleanupGroup);
+}
+
+void createChildren (tcu::TestCaseGroup* mainGroup)
+{
+ tcu::TestContext& testCtx = mainGroup->getTestContext();
const VkDescriptorType basicDescriptorTypes[] = {
VK_DESCRIPTOR_TYPE_SAMPLER,
DescriptorSetPtr setPtr;
{
DescriptorSet::BindingPtrVector setBindings;
- setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, actualTypes));
+ setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_EXT, actualTypes));
setPtr = DescriptorSetPtr(new DescriptorSet(setBindings));
}
DescriptorSetPtr setPtr;
{
DescriptorSet::BindingPtrVector setBindings;
- setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, mandatoryTypes));
+ setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_EXT, mandatoryTypes));
setPtr = DescriptorSetPtr(new DescriptorSet(setBindings));
}
const std::vector<VkDescriptorType> mutableTypes { initialDescriptorType, finalDescriptorType };
DescriptorSet::BindingPtrVector setBindings;
- setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, mutableTypes));
+ setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_EXT, mutableTypes));
DescriptorSetPtr setPtr = DescriptorSetPtr(new DescriptorSet(setBindings));
std::rotate(beginPtr, &rotatedTypes[typeIdx], endPtr);
- arrayBindings.emplace_back(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, rotatedTypes);
+ arrayBindings.emplace_back(VK_DESCRIPTOR_TYPE_MUTABLE_EXT, rotatedTypes);
}
}
else
{
// Without aliasing, all descriptors use the same type at the same time.
- const SingleBinding noAliasingBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, mandatoryTypesVector);
+ const SingleBinding noAliasingBinding(VK_DESCRIPTOR_TYPE_MUTABLE_EXT, mandatoryTypesVector);
arrayBindings.resize(mandatoryTypesVector.size(), noAliasingBinding);
}
DescriptorSet::BindingPtrVector setBindings;
std::vector<SingleBinding> arrayBindings;
- // Single mutable descriptor as the first binding.
- setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_EXT, mandatoryTypes));
-
- // Descriptor array as the second binding.
+ // Add single type beyond the mandatory ones.
auto arrayBindingDescTypes = mandatoryTypes;
arrayBindingDescTypes.push_back(descriptorType);
- setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, arrayBindingDescTypes));
+ // Single mutable descriptor as the first binding.
++ setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_EXT, arrayBindingDescTypes));
+
+ // Descriptor array as the second binding.
if (aliasingCase.aliasing)
{
// With aliasing, the descriptor types rotate in each descriptor.
std::rotate(beginPtr, &rotatedTypes[typeIdx], endPtr);
- arrayBindings.emplace_back(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, rotatedTypes);
+ arrayBindings.emplace_back(VK_DESCRIPTOR_TYPE_MUTABLE_EXT, rotatedTypes);
}
}
else
{
// Without aliasing, all descriptors use the same type at the same time.
- const SingleBinding noAliasingBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, arrayBindingDescTypes);
+ const SingleBinding noAliasingBinding(VK_DESCRIPTOR_TYPE_MUTABLE_EXT, arrayBindingDescTypes);
arrayBindings.resize(arrayBindingDescTypes.size(), noAliasingBinding);
}
const auto endPtr = beginPtr + rotatedTypes.size();
std::rotate(beginPtr, &rotatedTypes[typeIdx], endPtr);
- setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, rotatedTypes));
+ setBindings.emplace_back(new SingleBinding(VK_DESCRIPTOR_TYPE_MUTABLE_EXT, rotatedTypes));
// Additional non-mutable binding interleaved with the mutable ones.
if (mixed)
multipleGroup->addChild(mixedGroup.release());
mainGroup->addChild(multipleGroup.release());
}
-
- return mainGroup.release();
}
} // BindingModel