dEQP-VK.spirv_assembly.instruction.compute.16bit_storage.push_constant_16_to_32.scalar_uint
dEQP-VK.spirv_assembly.instruction.compute.16bit_storage.push_constant_16_to_32.vector_sint
dEQP-VK.spirv_assembly.instruction.compute.16bit_storage.push_constant_16_to_32.vector_uint
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opselect_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opfunctioncall_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opphi_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opcopyobject_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.stores_private_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.stores_function_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opptraccesschain_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.writes_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opselect_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opfunctioncall_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opphi_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opcopyobject_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.stores_private_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.stores_function_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opptraccesschain_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.writes_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.workgroup_two_buffers
dEQP-VK.spirv_assembly.instruction.compute.android.opsrem.positive
dEQP-VK.spirv_assembly.instruction.compute.android.opsrem.all
dEQP-VK.spirv_assembly.instruction.compute.android.opsmod.positive
dEQP-VK.spirv_assembly.instruction.graphics.16bit_storage.push_constant_int_16_to_32.uint_vector_tesse
dEQP-VK.spirv_assembly.instruction.graphics.16bit_storage.push_constant_int_16_to_32.uint_vector_geom
dEQP-VK.spirv_assembly.instruction.graphics.16bit_storage.push_constant_int_16_to_32.uint_vector_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_two_buffers_frag
dEQP-VK.glsl.arrays.constructor.float3_vertex
dEQP-VK.glsl.arrays.constructor.float3_fragment
dEQP-VK.glsl.arrays.constructor.float4_vertex
"libpng",
postExtract = postExtractLibpng),
GitRepo(
- "https://github.com/KhronosGroup/SPIRV-Tools.git",
- None,
- "bf68c814268cfa8b0311f93f16db4c3eed6eb7d2",
+ "https://gitlab.khronos.org/spirv/spirv-tools.git",
+ "git@gitlab.khronos.org:spirv/spirv-tools.git",
+ "5ef1440f3ec5a5fc6e5cf368383c4b1ae323f0f8",
"spirv-tools"),
GitRepo(
"https://github.com/KhronosGroup/glslang.git",
"a5c5fb61180e8703ca85f36d618f98e16dc317e2",
"glslang"),
GitRepo(
- "https://github.com/KhronosGroup/SPIRV-Headers.git",
- None,
- "db5cf6176137003ca4c25df96f7c0649998c3499",
+ "https://gitlab.khronos.org/spirv/SPIRV-Headers.git",
+ "git@gitlab.khronos.org:spirv/SPIRV-Headers.git",
+ "de4c26af39f243b0c2176f9e15089f5968d52394",
"spirv-headers"),
]
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000,
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001,
VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = 1000120000,
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = 1000127000,
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = 1000127001,
VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = 1000146000,
std::ostream& operator<< (std::ostream& s, const VkPastPresentationTimingGOOGLE& value);
std::ostream& operator<< (std::ostream& s, const VkPresentTimeGOOGLE& value);
std::ostream& operator<< (std::ostream& s, const VkPresentTimesInfoGOOGLE& value);
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceVariablePointerFeaturesKHR& value);
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR: return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR";
case VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR: return "VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR";
case VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR: return "VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR";
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR: return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR";
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR: return "VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR";
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR: return "VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR";
case VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR: return "VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR";
s << '}';
return s;
}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceVariablePointerFeaturesKHR& value)
+{
+ s << "VkPhysicalDeviceVariablePointerFeaturesKHR = {\n";
+ s << "\tsType = " << value.sType << '\n';
+ s << "\tpNext = " << value.pNext << '\n';
+ s << "\tvariablePointersStorageBuffer = " << value.variablePointersStorageBuffer << '\n';
+ s << "\tvariablePointers = " << value.variablePointers << '\n';
+ s << '}';
+ return s;
+}
const VkPresentTimeGOOGLE* pTimes;
};
+struct VkPhysicalDeviceVariablePointerFeaturesKHR
+{
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 variablePointersStorageBuffer;
+ VkBool32 variablePointers;
+};
+
vktSpvAsmTests.hpp
vktSpvAsmUtils.cpp
vktSpvAsmUtils.hpp
+ vktSpvAsmVariablePointersTests.cpp
+ vktSpvAsmVariablePointersTests.hpp
)
set(DEQP_VK_SPIRV_ASSEMBLY_LIBS
{"uniform", "StorageUniform16", "Block", VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER},
};
-ExtensionFeatures get16BitStorageFeatures (const char* cap)
+VulkanFeatures get16BitStorageFeatures (const char* cap)
{
+ VulkanFeatures features;
if (string(cap) == "uniform_buffer_block")
- return ExtensionFeatures(EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK);
+ features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
+ else if (string(cap) == "uniform")
+ features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM;
+ else
+ DE_ASSERT(false && "not supported");
- if (string(cap) == "uniform")
- return ExtensionFeatures(EXT16BITSTORAGEFEATURES_UNIFORM);
-
- DE_ASSERT(false && "not supported");
- return ExtensionFeatures(0);
+ return features;
}
spec.inputs.push_back(BufferSp(new Float16Buffer(float16Data)));
spec.outputs.push_back(BufferSp(new Float32Buffer(float32Data)));
spec.extensions.push_back("VK_KHR_16bit_storage");
- spec.requestedExtensionFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
+ spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
}
else
spec.outputs.push_back(BufferSp(new Int32Buffer(uOutputs)));
spec.extensions.push_back("VK_KHR_16bit_storage");
- spec.requestedExtensionFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
+ spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
}
spec.outputs.push_back(BufferSp(new Float32Buffer(float32Data)));
spec.extensions.push_back("VK_KHR_16bit_storage");
- spec.requestedExtensionFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
+ spec.requestedVulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
}
else
spec.outputs.push_back(BufferSp(new Int32Buffer(uOutputs)));
spec.extensions.push_back("VK_KHR_16bit_storage");
- spec.requestedExtensionFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
+ spec.requestedVulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
group->addChild(new SpvAsmComputeShaderCase(testCtx, testName, testName, spec));
}
// So put dummy data in the expected values.
spec.outputs.push_back(BufferSp(new Float16Buffer(float16DummyData)));
spec.extensions.push_back("VK_KHR_16bit_storage");
- spec.requestedExtensionFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
+ spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
}
spec.inputs.push_back(BufferSp(new Int32Buffer(inputs)));
spec.outputs.push_back(BufferSp(new Int16Buffer(outputs)));
spec.extensions.push_back("VK_KHR_16bit_storage");
- spec.requestedExtensionFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
+ spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
}
}
};
- ExtensionFeatures extensionFeatures;
- extensionFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
+ VulkanFeatures requiredFeatures;
+ requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
for (deUint32 rndModeIdx = 0; rndModeIdx < DE_LENGTH_OF_ARRAY(rndModes); ++rndModeIdx)
}
interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT32), BufferSp(new Float32Buffer(subInputs))),
std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT16), BufferSp(new Float16Buffer(subOutputs))));
- createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, extensionFeatures);
+ createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
}
}
}
}
};
- ExtensionFeatures extensionFeatures;
- extensionFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
+ VulkanFeatures requiredFeatures;
+ requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
{
}
interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT16), BufferSp(new Float16Buffer(subInputs))),
std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT32), BufferSp(new Float32Buffer(subOutputs))));
- createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, extensionFeatures);
+ createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
}
}
}
{"vector_uint", vecInterfaceOpFunc, vecPreMain, "v4u32", "v4u16", "0", "OpUConvert", 4 * 4, 4},
};
- ExtensionFeatures extensionFeatures;
- extensionFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
+ VulkanFeatures requiredFeatures;
+ requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
{
interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT32), BufferSp(new Int32Buffer(subInputs))),
std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT16), BufferSp(new Int16Buffer(subOutputs))));
}
- createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, extensionFeatures);
+ createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
}
}
}
{"vector_uint", vecIfOpFunc, vecPreMain, "v4u32", "v4u16", "0", "OpUConvert", 4 * 4, 4},
};
- ExtensionFeatures extensionFeatures;
- extensionFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
+ VulkanFeatures requiredFeatures;
+ requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
{
interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT16), BufferSp(new Int16Buffer(subInputs))),
std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT32), BufferSp(new Int32Buffer(subOutputs))));
}
- createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, extensionFeatures);
+ createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
}
}
}
const deUint32 numDataPoints = 64;
vector<deFloat16> float16Data (getFloat16s(rnd, numDataPoints));
vector<float> float32Data;
- ExtensionFeatures extensionFeatures;
+ VulkanFeatures requiredFeatures;
float32Data.reserve(numDataPoints);
for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
float32Data.push_back(deFloat16To32(float16Data[numIdx]));
extensions.push_back("VK_KHR_16bit_storage");
- extensionFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
+ requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
fragments["capability"] = "OpCapability StoragePushConstant16\n";
fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
fragments["testfun"] = testFun.specialize(specs);
- createTestsForAllStages("scalar", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, extensionFeatures);
+ createTestsForAllStages("scalar", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
}
{ // Vector cases
fragments["testfun"] = testFun.specialize(specs);
- createTestsForAllStages("vector", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, extensionFeatures);
+ createTestsForAllStages("vector", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
}
{ // Matrix cases
fragments["testfun"] = testFun.specialize(specs);
- createTestsForAllStages("matrix", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, extensionFeatures);
+ createTestsForAllStages("matrix", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
}
}
vector<string> extensions;
const deUint16 signBitMask = 0x8000;
const deUint32 signExtendMask = 0xffff0000;
- ExtensionFeatures extensionFeatures;
+ VulkanFeatures requiredFeatures;
sOutputs.reserve(inputs.size());
uOutputs.reserve(inputs.size());
}
extensions.push_back("VK_KHR_16bit_storage");
- extensionFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
+ requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
fragments["capability"] = "OpCapability StoragePushConstant16\n";
fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
resources.outputs.clear();
resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int32Buffer(sOutputs))));
- createTestsForAllStages("sint_scalar", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, extensionFeatures);
+ createTestsForAllStages("sint_scalar", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
}
{ // signed int
map<string, string> specs;
resources.outputs.clear();
resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int32Buffer(uOutputs))));
- createTestsForAllStages("uint_scalar", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, extensionFeatures);
+ createTestsForAllStages("uint_scalar", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
}
}
resources.outputs.clear();
resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int32Buffer(sOutputs))));
- createTestsForAllStages("sint_vector", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, extensionFeatures);
+ createTestsForAllStages("sint_vector", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
}
{ // signed int
map<string, string> specs;
resources.outputs.clear();
resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int32Buffer(uOutputs))));
- createTestsForAllStages("uint_vector", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, extensionFeatures);
+ createTestsForAllStages("uint_vector", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
}
}
}
// 16bit storage features
{
- if (!is16BitStorageFeaturesSupported(vki, physicalDevice, m_context.getInstanceExtensions(), m_shaderSpec.requestedExtensionFeatures.ext16BitStorage))
+ if (!is16BitStorageFeaturesSupported(vki, physicalDevice, m_context.getInstanceExtensions(), m_shaderSpec.requestedVulkanFeatures.ext16BitStorage))
TCU_THROW(NotSupportedError, "Requested 16bit storage features not supported");
}
+
+ // VariablePointers features
+ {
+ if (!isVariablePointersFeaturesSupported(vki, physicalDevice, m_context.getInstanceExtensions(), m_shaderSpec.requestedVulkanFeatures.extVariablePointers))
+ TCU_THROW(NotSupportedError, "Request Variable Pointer feature not supported");
+ }
}
// defer device and resource creation until after feature checks
std::vector<deUint32> specConstants;
BufferSp pushConstants;
std::vector<std::string> extensions;
- ExtensionFeatures requestedExtensionFeatures;
+ VulkanFeatures requestedVulkanFeatures;
qpTestResult failResult;
std::string failMessage;
// If null, a default verification will be performed by comparing the memory pointed to by outputAllocations
ComputeShaderSpec (void)
: entryPoint ("main")
, pushConstants (DE_NULL)
- , requestedExtensionFeatures ()
+ , requestedVulkanFeatures ()
, failResult (QP_TEST_RESULT_FAIL)
, failMessage ("Output doesn't match with expected")
, verifyIO (DE_NULL)
const GraphicsInterfaces& interfaces_,
const vector<string>& extensions_,
const vector<string>& features_,
- ExtensionFeatures extensionFeatures_)
+ VulkanFeatures vulkanFeatures_,
+ VkShaderStageFlags customizedStages_)
: testCodeFragments (testCodeFragments_)
, specConstants (specConstants_)
, hasTessellation (false)
, requiredStages (static_cast<VkShaderStageFlagBits>(0))
, requiredDeviceExtensions (extensions_)
, requiredDeviceFeatures (features_)
- , requestedExtensionFeatures (extensionFeatures_)
+ , requestedFeatures (vulkanFeatures_)
, pushConstants (pushConsants_)
+ , customizedStages (customizedStages_)
, resources (resources_)
, interfaces (interfaces_)
, failResult (QP_TEST_RESULT_FAIL)
, requiredStages (other.requiredStages)
, requiredDeviceExtensions (other.requiredDeviceExtensions)
, requiredDeviceFeatures (other.requiredDeviceFeatures)
- , requestedExtensionFeatures (other.requestedExtensionFeatures)
+ , requestedFeatures (other.requestedFeatures)
, pushConstants (other.pushConstants)
+ , customizedStages (other.customizedStages)
, resources (other.resources)
, interfaces (other.interfaces)
, failResult (other.failResult)
"%isUniqueIdZero = OpFunction %bool None %bool_function\n"
"%getId_label = OpLabel\n"
"%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
- "%is_id_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
- "OpReturnValue %is_id_0\n"
+ "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
+ "%TC_0_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
+ "%TC_1_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
+ "%TC_2_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
+ "%TC_W_0 = OpLoad %f32 %TC_0_loc\n"
+ "%TC_W_1 = OpLoad %f32 %TC_1_loc\n"
+ "%TC_W_2 = OpLoad %f32 %TC_2_loc\n"
+ "%is_W_0_1 = OpFOrdEqual %bool %TC_W_0 %c_f32_1\n"
+ "%is_W_1_0 = OpFOrdEqual %bool %TC_W_1 %c_f32_0\n"
+ "%is_W_2_0 = OpFOrdEqual %bool %TC_W_2 %c_f32_0\n"
+ "%is_tessCoord_1_0 = OpLogicalAnd %bool %is_W_0_1 %is_W_1_0\n"
+ "%is_tessCoord_1_0_0 = OpLogicalAnd %bool %is_tessCoord_1_0 %is_W_2_0\n"
+ "%is_unique_id_0 = OpLogicalAnd %bool %is_tessCoord_1_0_0 %is_primitive_0\n"
+ "OpReturnValue %is_unique_id_0\n"
"OpFunctionEnd\n"
"${testfun}\n";
"%BP_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
"%BP_a3_per_vertex_in = OpTypeArray %BP_per_vertex_in %c_u32_3\n"
"%BP_ip_a3_per_vertex_in = OpTypePointer Input %BP_a3_per_vertex_in\n"
+ "%BP_pp_i32 = OpTypePointer Private %i32\n"
+ "%BP_pp_v4i32 = OpTypePointer Private %v4i32\n"
"%BP_gl_in = OpVariable %BP_ip_a3_per_vertex_in Input\n"
"%BP_out_color = OpVariable %op_v4f32 Output\n"
"%BP_in_color = OpVariable %ip_a3v4f32 Input\n"
"%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
"%BP_out_gl_position = OpVariable %op_v4f32 Output\n"
+ "%BP_vertexIdInCurrentPatch = OpVariable %BP_pp_v4i32 Private\n"
"${pre_main:opt}\n"
"${IF_variable:opt}\n"
"${IF_carryforward:opt}\n"
+ "%BP_primitiveId = OpLoad %i32 %BP_gl_PrimitiveID\n"
+ "%BP_addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %BP_primitiveId\n"
+
"%BP_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
"%BP_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
"%BP_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"
"%BP_in_color_1 = OpLoad %v4f32 %BP_in_color_1_ptr\n"
"%BP_in_color_2 = OpLoad %v4f32 %BP_in_color_2_ptr\n"
+ "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_0\n"
"%BP_transformed_in_color_0 = OpFunctionCall %v4f32 %test_code %BP_in_color_0\n"
+ "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_1\n"
"%BP_transformed_in_color_1 = OpFunctionCall %v4f32 %test_code %BP_in_color_1\n"
+ "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_2\n"
"%BP_transformed_in_color_2 = OpFunctionCall %v4f32 %test_code %BP_in_color_2\n"
"%isUniqueIdZero = OpFunction %bool None %bool_function\n"
"%getId_label = OpLabel\n"
"%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
- "%is_id_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
- "OpReturnValue %is_id_0\n"
+ "%addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %primitive_id\n"
+ "%vertexIdInCurrentPatch = OpLoad %i32 %addr_vertexIdInCurrentPatch\n"
+ "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
+ "%is_vertex_0 = OpIEqual %bool %vertexIdInCurrentPatch %c_i32_0\n"
+ "%is_unique_id_0 = OpLogicalAnd %bool %is_primitive_0 %is_vertex_0\n"
+ "OpReturnValue %is_unique_id_0\n"
"OpFunctionEnd\n"
"${testfun}\n";
// 16bit storage features
{
- if (!is16BitStorageFeaturesSupported(vkInstance, vkPhysicalDevice, context.getInstanceExtensions(), instance.requestedExtensionFeatures.ext16BitStorage))
+ if (!is16BitStorageFeaturesSupported(vkInstance, vkPhysicalDevice, context.getInstanceExtensions(), instance.requestedFeatures.ext16BitStorage))
TCU_THROW(NotSupportedError, "Requested 16bit storage features not supported");
}
+ // Variable Pointers features
+ {
+ if (!isVariablePointersFeaturesSupported(vkInstance, vkPhysicalDevice, context.getInstanceExtensions(), instance.requestedFeatures.extVariablePointers))
+ TCU_THROW(NotSupportedError, "Requested Variable Pointer features not supported");
+
+ if (instance.requestedFeatures.extVariablePointers)
+ {
+ // The device doesn't have the vertexPipelineStoresAndAtomics feature, but the test requires the feature for
+ // vertex, tesselation, and geometry stages.
+ if (features.vertexPipelineStoresAndAtomics == DE_FALSE &&
+ instance.requestedFeatures.coreFeatures.vertexPipelineStoresAndAtomics == DE_TRUE &&
+ (instance.customizedStages & vk::VK_SHADER_STAGE_VERTEX_BIT ||
+ instance.customizedStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ||
+ instance.customizedStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
+ instance.customizedStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT))
+ TCU_THROW(NotSupportedError, "This VK_KHR_variable_pointers extension test requires vertexPipelineStoresAndAtomics device feature.");
+
+ // The device doesn't have the fragmentStoresAndAtomics feature, but the test requires this feature for the fragment stage.
+ if (features.fragmentStoresAndAtomics == DE_FALSE &&
+ instance.requestedFeatures.coreFeatures.fragmentStoresAndAtomics == DE_TRUE &&
+ instance.customizedStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT)
+ TCU_THROW(NotSupportedError, "This VK_KHR_variable_pointers extension test requires fragmentStoresAndAtomics device feature.");
+ }
+ }
+
// defer device and other resource creation until after feature checks
const Unique<VkDevice> vkDevice (createDeviceWithExtensions(context, queueFamilyIndex, context.getDeviceExtensions(), instance.requiredDeviceExtensions));
const DeviceDriver vk (vkInstance, *vkDevice);
const GraphicsInterfaces& interfaces,
const vector<string>& extensions,
const vector<string>& features,
- ExtensionFeatures extensionFeatures,
+ VulkanFeatures vulkanFeatures,
tcu::TestCaseGroup* tests,
const qpTestResult failResult,
const string& failMessageTemplate)
addFunctionCaseWithPrograms<InstanceContext>(
tests, name + "_vert", "", addShaderCodeCustomVertex, runAndVerifyDefaultPipeline,
createInstanceContext(vertFragPipelineStages, inputColors, outputColors, testCodeFragments,
- specConstantMap, pushConstants, resources, interfaces, extensions, features, extensionFeatures, failResult, failMessageTemplate));
+ specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_VERTEX_BIT, failResult, failMessageTemplate));
specConstantMap.clear();
specConstantMap[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = specConstants;
addFunctionCaseWithPrograms<InstanceContext>(
tests, name + "_tessc", "", addShaderCodeCustomTessControl, runAndVerifyDefaultPipeline,
createInstanceContext(tessPipelineStages, inputColors, outputColors, testCodeFragments,
- specConstantMap, pushConstants, resources, interfaces, extensions, features, extensionFeatures, failResult, failMessageTemplate));
+ specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, failResult, failMessageTemplate));
specConstantMap.clear();
specConstantMap[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = specConstants;
addFunctionCaseWithPrograms<InstanceContext>(
tests, name + "_tesse", "", addShaderCodeCustomTessEval, runAndVerifyDefaultPipeline,
createInstanceContext(tessPipelineStages, inputColors, outputColors, testCodeFragments,
- specConstantMap, pushConstants, resources, interfaces, extensions, features, extensionFeatures, failResult, failMessageTemplate));
+ specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, failResult, failMessageTemplate));
specConstantMap.clear();
specConstantMap[VK_SHADER_STAGE_GEOMETRY_BIT] = specConstants;
addFunctionCaseWithPrograms<InstanceContext>(
tests, name + "_geom", "", addShaderCodeCustomGeometry, runAndVerifyDefaultPipeline,
createInstanceContext(geomPipelineStages, inputColors, outputColors, testCodeFragments,
- specConstantMap, pushConstants, resources, interfaces, extensions, features, extensionFeatures, failResult, failMessageTemplate));
+ specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_GEOMETRY_BIT, failResult, failMessageTemplate));
specConstantMap.clear();
specConstantMap[VK_SHADER_STAGE_FRAGMENT_BIT] = specConstants;
addFunctionCaseWithPrograms<InstanceContext>(
tests, name + "_frag", "", addShaderCodeCustomFragment, runAndVerifyDefaultPipeline,
createInstanceContext(vertFragPipelineStages, inputColors, outputColors, testCodeFragments,
- specConstantMap, pushConstants, resources, interfaces, extensions, features, extensionFeatures, failResult, failMessageTemplate));
+ specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_FRAGMENT_BIT, failResult, failMessageTemplate));
}
void addTessCtrlTest(tcu::TestCaseGroup* group, const char* name, const map<string, string>& fragments)
pipelineStages, defaultColors, defaultColors, fragments,
StageToSpecConstantMap(), PushConstants(), GraphicsResources(),
GraphicsInterfaces(), vector<string>(), vector<string>(),
- ExtensionFeatures()));
+ VulkanFeatures(), vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
}
} // SpirVAssembly
vk::VkShaderStageFlagBits requiredStages;
std::vector<std::string> requiredDeviceExtensions;
std::vector<std::string> requiredDeviceFeatures;
- ExtensionFeatures requestedExtensionFeatures;
+ VulkanFeatures requestedFeatures;
PushConstants pushConstants;
+ // Specifies the (one or more) stages that use a customized shader code.
+ VkShaderStageFlags customizedStages;
// Possible resources used by the graphics pipeline.
// If it is not empty, a single descriptor set (number 0) will be allocated
// to point to all resources specified. Binding numbers are allocated in
const GraphicsInterfaces& interfaces_,
const std::vector<std::string>& extensions_,
const std::vector<std::string>& features_,
- ExtensionFeatures extFeatures_);
+ VulkanFeatures vulkanFeatures_,
+ VkShaderStageFlags customizedStages_);
InstanceContext (const InstanceContext& other);
const GraphicsInterfaces& interfaces,
const std::vector<std::string>& extensions,
const std::vector<std::string>& features,
- ExtensionFeatures extensionFeatures,
+ VulkanFeatures vulkanFeatures,
+ VkShaderStageFlags customizedStages,
const qpTestResult failResult = QP_TEST_RESULT_FAIL,
const std::string& failMessageTemplate = std::string())
{
- InstanceContext ctx (inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources, interfaces, extensions, features, extensionFeatures);
+ InstanceContext ctx (inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, customizedStages);
for (size_t i = 0; i < N; ++i)
{
ctx.moduleMap[elements[i].moduleName].push_back(std::make_pair(elements[i].entryName, elements[i].stage));
return createInstanceContext(elements, inputColors, outputColors, testCodeFragments,
StageToSpecConstantMap(), PushConstants(), GraphicsResources(),
GraphicsInterfaces(), std::vector<std::string>(), std::vector<std::string>(),
- ExtensionFeatures());
+ VulkanFeatures(), vk::VK_SHADER_STAGE_ALL);
}
// The same as createInstanceContext above, but with default colors.
const GraphicsInterfaces& interfaces,
const std::vector<std::string>& extensions,
const std::vector<std::string>& features,
- ExtensionFeatures extensionFeatures,
+ VulkanFeatures vulkanFeatures,
tcu::TestCaseGroup* tests,
const qpTestResult failResult = QP_TEST_RESULT_FAIL,
const std::string& failMessageTemplate = std::string());
createTestsForAllStages(
name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
- noResources, noInterfaces, noExtensions, noFeatures, ExtensionFeatures(),
+ noResources, noInterfaces, noExtensions, noFeatures, VulkanFeatures(),
tests, failResult, failMessageTemplate);
}
createTestsForAllStages(
name, inputColors, outputColors, testCodeFragments, specConstants, noPushConstants,
- noResources, noInterfaces, noExtensions, noFeatures, ExtensionFeatures(),
+ noResources, noInterfaces, noExtensions, noFeatures, VulkanFeatures(),
tests, failResult, failMessageTemplate);
}
const GraphicsResources& resources,
const std::vector<std::string>& extensions,
tcu::TestCaseGroup* tests,
- ExtensionFeatures extensionFeatures = ExtensionFeatures(),
+ VulkanFeatures vulkanFeatures = VulkanFeatures(),
const qpTestResult failResult = QP_TEST_RESULT_FAIL,
const std::string& failMessageTemplate = std::string())
{
createTestsForAllStages(
name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
- resources, noInterfaces, extensions, noFeatures, extensionFeatures,
+ resources, noInterfaces, extensions, noFeatures, vulkanFeatures,
tests, failResult, failMessageTemplate);
}
const GraphicsInterfaces interfaces,
const std::vector<std::string>& extensions,
tcu::TestCaseGroup* tests,
- ExtensionFeatures extensionFeatures = ExtensionFeatures(),
+ VulkanFeatures vulkanFeatures = VulkanFeatures(),
const qpTestResult failResult = QP_TEST_RESULT_FAIL,
const std::string& failMessageTemplate = std::string())
{
createTestsForAllStages(
name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
- noResources, interfaces, extensions, noFeatures, extensionFeatures,
+ noResources, interfaces, extensions, noFeatures, vulkanFeatures,
tests, failResult, failMessageTemplate);
}
const GraphicsResources& resources,
const std::vector<std::string>& extensions,
tcu::TestCaseGroup* tests,
- ExtensionFeatures extensionFeatures = ExtensionFeatures(),
+ VulkanFeatures vulkanFeatures = VulkanFeatures(),
const qpTestResult failResult = QP_TEST_RESULT_FAIL,
const std::string& failMessageTemplate = std::string())
{
createTestsForAllStages(
name, inputColors, outputColors, testCodeFragments, noSpecConstants, pushConstants,
- resources, noInterfaces, extensions, noFeatures, extensionFeatures,
+ resources, noInterfaces, extensions, noFeatures, vulkanFeatures,
tests, failResult, failMessageTemplate);
}
#include "vktSpvAsmComputeShaderCase.hpp"
#include "vktSpvAsmComputeShaderTestUtil.hpp"
#include "vktSpvAsmGraphicsShaderTestUtil.hpp"
+#include "vktSpvAsmVariablePointersTests.hpp"
#include "vktTestCaseUtil.hpp"
#include <cmath>
computeTests->addChild(createShaderDefaultOutputGroup(testCtx));
computeTests->addChild(create16BitStorageComputeGroup(testCtx));
-
+ computeTests->addChild(createVariablePointersComputeGroup(testCtx));
{
de::MovePtr<tcu::TestCaseGroup> computeAndroidTests (new tcu::TestCaseGroup(testCtx, "android", "Android CTS Tests"));
}
graphicsTests->addChild(create16BitStorageGraphicsGroup(testCtx));
+ graphicsTests->addChild(createVariablePointersGraphicsGroup(testCtx));
instructionTests->addChild(computeTests.release());
instructionTests->addChild(graphicsTests.release());
return extensionFeatures;
}
+VkPhysicalDeviceVariablePointerFeaturesKHR querySupportedVariablePointersFeatures (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
+{
+ VkPhysicalDeviceVariablePointerFeaturesKHR extensionFeatures =
+ {
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR, // sType
+ DE_NULL, // pNext
+ false, // variablePointersStorageBuffer
+ false, // variablePointers
+ };
+
+ VkPhysicalDeviceFeatures2KHR features;
+ deMemset(&features, 0, sizeof(features));
+ features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
+ features.pNext = &extensionFeatures;
+
+ // Call the getter only if supported. Otherwise above "zero" defaults are used
+ if (de::contains(instanceExtensions.begin(), instanceExtensions.end(), "VK_KHR_get_physical_device_properties2"))
+ {
+ vki.getPhysicalDeviceFeatures2KHR(device, &features);
+ }
+
+ return extensionFeatures;
+}
+
} // anonymous
bool is16BitStorageFeaturesSupported (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, Extension16BitStorageFeatures toCheck)
return true;
}
+bool isVariablePointersFeaturesSupported (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, ExtensionVariablePointersFeatures toCheck)
+{
+ VkPhysicalDeviceVariablePointerFeaturesKHR extensionFeatures = querySupportedVariablePointersFeatures(vki, device, instanceExtensions);
+
+ if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER) != 0 && extensionFeatures.variablePointersStorageBuffer == VK_FALSE)
+ return false;
+
+ if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS) != 0 && extensionFeatures.variablePointers == VK_FALSE)
+ return false;
+
+ return true;
+}
+
Move<VkDevice> createDeviceWithExtensions (Context& context,
const deUint32 queueFamilyIndex,
const std::vector<std::string>& supportedExtensions,
const std::vector<std::string>& requiredExtensions)
{
- const InstanceInterface& vki = context.getInstanceInterface();
- const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
- std::vector<const char*> extensions (requiredExtensions.size());
- bool requires16BitStorageExtension = false;
+ const InstanceInterface& vki = context.getInstanceInterface();
+ const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
+ std::vector<const char*> extensions (requiredExtensions.size());
+ void* pExtension = DE_NULL;
+ const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(vki, physicalDevice);
+ VkPhysicalDevice16BitStorageFeaturesKHR ext16BitStorageFeatures;
+ VkPhysicalDeviceVariablePointerFeaturesKHR extVariablePointerFeatures;
for (deUint32 extNdx = 0; extNdx < requiredExtensions.size(); ++extNdx)
{
TCU_THROW(NotSupportedError, (std::string("Device extension not supported: ") + ext).c_str());
}
+ // Currently don't support enabling multiple extensions at the same time.
if (ext == "VK_KHR_16bit_storage")
{
- requires16BitStorageExtension = true;
+ // For the 16bit storage extension, we have four features to test. Requesting all features supported.
+ // Note that we don't throw NotImplemented errors here if a specific feature is not supported;
+ // that should be done when actually trying to use that specific feature.
+ ext16BitStorageFeatures = querySupported16BitStorageFeatures(vki, physicalDevice, context.getInstanceExtensions());
+ pExtension = &ext16BitStorageFeatures;
+ }
+ else if (ext == "VK_KHR_variable_pointers")
+ {
+ // For the VariablePointers extension, we have two features to test. Requesting all features supported.
+ extVariablePointerFeatures = querySupportedVariablePointersFeatures(vki, physicalDevice, context.getInstanceExtensions());
+ pExtension = &extVariablePointerFeatures;
}
extensions[extNdx] = ext.c_str();
}
- // For the 16bit storage extension, we have four features to test. Requesting all features supported.
- // Note that we don't throw NotImplemented errors here if a specific feature is not supported;
- // that should be done when actually trying to use that specific feature.
- VkPhysicalDevice16BitStorageFeaturesKHR ext16BitStorageFeatures = querySupported16BitStorageFeatures(vki, physicalDevice, context.getInstanceExtensions());
-
const float queuePriorities[] = { 1.0f };
const VkDeviceQueueCreateInfo queueInfos[] =
{
&queuePriorities[0]
}
};
- const VkPhysicalDeviceFeatures features = filterDefaultDeviceFeatures(getPhysicalDeviceFeatures(vki, physicalDevice));
+ const VkPhysicalDeviceFeatures features = filterDefaultDeviceFeatures(deviceFeatures);
const VkDeviceCreateInfo deviceParams =
{
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- (requires16BitStorageExtension ? &ext16BitStorageFeatures : DE_NULL),
+ pExtension,
(VkDeviceCreateFlags)0,
DE_LENGTH_OF_ARRAY(queueInfos),
&queueInfos[0],
};
typedef deUint32 Extension16BitStorageFeatures;
-struct ExtensionFeatures
+enum ExtensionVariablePointersFeaturesBits
{
- Extension16BitStorageFeatures ext16BitStorage;
+ EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER = (1u << 1),
+ EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS = (1u << 2),
+};
+typedef deUint32 ExtensionVariablePointersFeatures;
- ExtensionFeatures (void)
- : ext16BitStorage (0)
- {}
- explicit ExtensionFeatures (Extension16BitStorageFeatures ext16BitStorage_)
- : ext16BitStorage (ext16BitStorage_)
+struct VulkanFeatures
+{
+ Extension16BitStorageFeatures ext16BitStorage;
+ ExtensionVariablePointersFeatures extVariablePointers;
+ vk::VkPhysicalDeviceFeatures coreFeatures;
+
+ VulkanFeatures (void)
+ : ext16BitStorage (0)
+ , extVariablePointers (0)
+ , coreFeatures (vk::VkPhysicalDeviceFeatures())
{}
};
const std::vector<std::string>& instanceExtensions,
Extension16BitStorageFeatures toCheck);
+// Returns true if the given variable pointers extension features in `toCheck` are all supported.
+bool isVariablePointersFeaturesSupported (const vk::InstanceInterface& vkInstance,
+ vk::VkPhysicalDevice device,
+ const std::vector<std::string>& instanceExtensions,
+ ExtensionVariablePointersFeatures toCheck);
+
// Creates a Vulkan logical device with the requiredExtensions enabled and all other extensions disabled.
// The logical device will be created from the instance and physical device in the given context.
// A single queue will be created from the given queue family.
--- /dev/null
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 Google 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 SPIR-V Assembly Tests for the SPV_KHR_variable_pointers extension
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuFloat.hpp"
+#include "tcuRGBA.hpp"
+#include "tcuStringTemplate.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuVectorUtil.hpp"
+
+#include "vkDefs.hpp"
+#include "vkDeviceUtil.hpp"
+#include "vkMemUtil.hpp"
+#include "vkPlatform.hpp"
+#include "vkPrograms.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "vkStrUtil.hpp"
+#include "vkTypeUtil.hpp"
+
+#include "deRandom.hpp"
+#include "deStringUtil.hpp"
+#include "deUniquePtr.hpp"
+#include "deMath.h"
+
+#include "vktSpvAsmComputeShaderCase.hpp"
+#include "vktSpvAsmComputeShaderTestUtil.hpp"
+#include "vktSpvAsmGraphicsShaderTestUtil.hpp"
+#include "vktSpvAsmVariablePointersTests.hpp"
+#include "vktTestCaseUtil.hpp"
+#include "vktTestGroupUtil.hpp"
+
+#include <limits>
+#include <map>
+#include <string>
+#include <sstream>
+#include <utility>
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+using namespace vk;
+using std::map;
+using std::string;
+using std::vector;
+using tcu::IVec3;
+using tcu::IVec4;
+using tcu::RGBA;
+using tcu::TestLog;
+using tcu::TestStatus;
+using tcu::Vec4;
+using de::UniquePtr;
+using tcu::StringTemplate;
+using tcu::Vec4;
+
+namespace
+{
+
+template<typename T>
+void fillRandomScalars (de::Random& rnd, T minValue, T maxValue, void* dst, int numValues, int offset = 0)
+{
+ T* const typedPtr = (T*)dst;
+ for (int ndx = 0; ndx < numValues; ndx++)
+ typedPtr[offset + ndx] = randomScalar<T>(rnd, minValue, maxValue);
+}
+
+void addComputeVariablePointersGroup (tcu::TestCaseGroup* group)
+{
+ tcu::TestContext& testCtx = group->getTestContext();
+ de::Random rnd (deStringHash(group->getName()));
+ const int seed = testCtx.getCommandLine().getBaseSeed();
+ const int numMuxes = 100;
+ std::string inputArraySize = "200";
+ vector<float> inputAFloats (2*numMuxes, 0);
+ vector<float> inputBFloats (2*numMuxes, 0);
+ vector<float> inputSFloats (numMuxes, 0);
+ vector<float> AmuxAOutputFloats (numMuxes, 0);
+ vector<float> AmuxBOutputFloats (numMuxes, 0);
+ vector<float> incrAmuxAOutputFloats (numMuxes, 0);
+ vector<float> incrAmuxBOutputFloats (numMuxes, 0);
+ VulkanFeatures requiredFeatures;
+
+ // Each output entry is chosen as follows: ( 0 <= i < numMuxes)
+ // 1) For tests with one input buffer: output[i] = (s[i] < 0) ? A[2*i] : A[2*i+1];
+ // 2) For tests with two input buffers: output[i] = (s[i] < 0) ? A[i] : B[i];
+
+ fillRandomScalars(rnd, -100.f, 100.f, &inputAFloats[0], 2*numMuxes);
+ fillRandomScalars(rnd, -100.f, 100.f, &inputBFloats[0], 2*numMuxes);
+
+ // We want to guarantee that the S input has some positive and some negative values.
+ // We choose random negative numbers for the first half, random positive numbers for the second half, and then shuffle.
+ fillRandomScalars(rnd, -100.f, -1.f , &inputSFloats[0], numMuxes / 2);
+ fillRandomScalars(rnd, 1.f , 100.f, &inputSFloats[numMuxes / 2], numMuxes / 2);
+ de::Random(seed).shuffle(inputSFloats.begin(), inputSFloats.end());
+
+ for (size_t i = 0; i < numMuxes; ++i)
+ {
+ AmuxAOutputFloats[i] = (inputSFloats[i] < 0) ? inputAFloats[2*i] : inputAFloats[2*i+1];
+ AmuxBOutputFloats[i] = (inputSFloats[i] < 0) ? inputAFloats[i] : inputBFloats[i];
+ incrAmuxAOutputFloats[i] = (inputSFloats[i] < 0) ? 1 + inputAFloats[2*i] : 1+ inputAFloats[2*i+1];
+ incrAmuxBOutputFloats[i] = (inputSFloats[i] < 0) ? 1 + inputAFloats[i] : 1 + inputBFloats[i];
+ }
+
+ const StringTemplate shaderTemplate (
+ "OpCapability Shader\n"
+
+ "${ExtraCapability}\n"
+
+ "OpExtension \"SPV_KHR_variable_pointers\"\n"
+ "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
+ "OpMemoryModel Logical GLSL450\n"
+ "OpEntryPoint GLCompute %main \"main\" %id\n"
+ "OpExecutionMode %main LocalSize 1 1 1\n"
+
+ "OpSource GLSL 430\n"
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ // Decorations
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+ "OpDecorate %indata_a DescriptorSet 0\n"
+ "OpDecorate %indata_a Binding 0\n"
+ "OpDecorate %indata_b DescriptorSet 0\n"
+ "OpDecorate %indata_b Binding 1\n"
+ "OpDecorate %indata_s DescriptorSet 0\n"
+ "OpDecorate %indata_s Binding 2\n"
+ "OpDecorate %outdata DescriptorSet 0\n"
+ "OpDecorate %outdata Binding 3\n"
+ "OpDecorate %f32arr ArrayStride 4\n"
+ "OpDecorate %sb_f32ptr ArrayStride 4\n"
+ "OpDecorate %buf Block\n"
+ "OpMemberDecorate %buf 0 Offset 0\n"
+
+ + string(getComputeAsmCommonTypes()) +
+
+ "%sb_f32ptr = OpTypePointer StorageBuffer %f32\n"
+ "%buf = OpTypeStruct %f32arr\n"
+ "%bufptr = OpTypePointer StorageBuffer %buf\n"
+ "%indata_a = OpVariable %bufptr StorageBuffer\n"
+ "%indata_b = OpVariable %bufptr StorageBuffer\n"
+ "%indata_s = OpVariable %bufptr StorageBuffer\n"
+ "%outdata = OpVariable %bufptr StorageBuffer\n"
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%one = OpConstant %i32 1\n"
+ "%fzero = OpConstant %f32 0\n"
+ "%fone = OpConstant %f32 1\n"
+
+ "${ExtraTypes}"
+
+ "${ExtraGlobalScopeVars}"
+
+ // We're going to put the "selector" function here.
+ // This function type is needed tests that use OpFunctionCall.
+ "%selector_func_type = OpTypeFunction %sb_f32ptr %bool %sb_f32ptr %sb_f32ptr\n"
+ "%choose_input_func = OpFunction %sb_f32ptr None %selector_func_type\n"
+ "%is_neg_param = OpFunctionParameter %bool\n"
+ "%first_ptr_param = OpFunctionParameter %sb_f32ptr\n"
+ "%second_ptr_param = OpFunctionParameter %sb_f32ptr\n"
+ "%selector_func_begin = OpLabel\n"
+ "%result_ptr = OpSelect %sb_f32ptr %is_neg_param %first_ptr_param %second_ptr_param\n"
+ "OpReturnValue %result_ptr\n"
+ "OpFunctionEnd\n"
+
+ // main function is the entry_point
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+
+ "${ExtraFunctionScopeVars}"
+
+ "%idval = OpLoad %uvec3 %id\n"
+ "%i = OpCompositeExtract %u32 %idval 0\n"
+ "%two_i = OpIAdd %u32 %i %i\n"
+ "%two_i_plus_1 = OpIAdd %u32 %two_i %one\n"
+ "%inloc_a_i = OpAccessChain %sb_f32ptr %indata_a %zero %i\n"
+ "%inloc_b_i = OpAccessChain %sb_f32ptr %indata_b %zero %i\n"
+ "%inloc_s_i = OpAccessChain %sb_f32ptr %indata_s %zero %i\n"
+ "%outloc_i = OpAccessChain %sb_f32ptr %outdata %zero %i\n"
+ "%inloc_a_2i = OpAccessChain %sb_f32ptr %indata_a %zero %two_i\n"
+ "%inloc_a_2i_plus_1 = OpAccessChain %sb_f32ptr %indata_a %zero %two_i_plus_1\n"
+ "%inval_s_i = OpLoad %f32 %inloc_s_i\n"
+ "%is_neg = OpFOrdLessThan %bool %inval_s_i %fzero\n"
+
+ "${ExtraSetupComputations}"
+
+ "${ResultStrategy}"
+
+ "%mux_output = OpLoad %f32 ${VarPtrName}\n"
+ " OpStore %outloc_i %mux_output\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n");
+
+ const bool singleInputBuffer[] = { true, false };
+ for (int inputBufferTypeIndex = 0 ; inputBufferTypeIndex < 2; ++inputBufferTypeIndex)
+ {
+ const bool isSingleInputBuffer = singleInputBuffer[inputBufferTypeIndex];
+ const string extraCap = isSingleInputBuffer ? "OpCapability VariablePointersStorageBuffer\n" : "OpCapability VariablePointers\n";
+ const vector<float>& expectedOutput = isSingleInputBuffer ? AmuxAOutputFloats : AmuxBOutputFloats;
+ const vector<float>& expectedIncrOutput = isSingleInputBuffer ? incrAmuxAOutputFloats : incrAmuxBOutputFloats;
+ const string bufferType = isSingleInputBuffer ? "single_buffer" : "two_buffers";
+ const string muxInput1 = isSingleInputBuffer ? " %inloc_a_2i " : " %inloc_a_i ";
+ const string muxInput2 = isSingleInputBuffer ? " %inloc_a_2i_plus_1 " : " %inloc_b_i ";
+
+ // Set the proper extension features required for the test
+ if (isSingleInputBuffer)
+ requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER;
+ else
+ requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS;
+
+ { // Variable Pointer Reads (using OpSelect)
+ ComputeShaderSpec spec;
+ map<string, string> specs;
+ string name = "reads_opselect_" + bufferType;
+ specs["ExtraCapability"] = extraCap;
+ specs["ExtraTypes"] = "";
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraSetupComputations"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] = "%mux_output_var_ptr = OpSelect %sb_f32ptr %is_neg" + muxInput1 + muxInput2 + "\n";
+ spec.inputTypes[0] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[1] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[2] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.assembly = shaderTemplate.specialize(specs);
+ spec.numWorkGroups = IVec3(numMuxes, 1, 1);
+ spec.requestedVulkanFeatures = requiredFeatures;
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputAFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputBFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputSFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
+ spec.extensions.push_back("VK_KHR_variable_pointers");
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, name.c_str(), name.c_str(), spec));
+ }
+ { // Variable Pointer Reads (using OpFunctionCall)
+ ComputeShaderSpec spec;
+ map<string, string> specs;
+ string name = "reads_opfunctioncall_" + bufferType;
+ specs["ExtraCapability"] = extraCap;
+ specs["ExtraTypes"] = "";
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraSetupComputations"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] = "%mux_output_var_ptr = OpFunctionCall %sb_f32ptr %choose_input_func %is_neg" + muxInput1 + muxInput2 + "\n";
+ spec.inputTypes[0] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[1] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[2] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.assembly = shaderTemplate.specialize(specs);
+ spec.numWorkGroups = IVec3(numMuxes, 1, 1);
+ spec.requestedVulkanFeatures = requiredFeatures;
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputAFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputBFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputSFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
+ spec.extensions.push_back("VK_KHR_variable_pointers");
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, name.c_str(), name.c_str(), spec));
+ }
+ { // Variable Pointer Reads (using OpPhi)
+ ComputeShaderSpec spec;
+ map<string, string> specs;
+ string name = "reads_opphi_" + bufferType;
+ specs["ExtraCapability"] = extraCap;
+ specs["ExtraTypes"] = "";
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraSetupComputations"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] =
+ " OpSelectionMerge %end_label None\n"
+ " OpBranchConditional %is_neg %take_mux_input_1 %take_mux_input_2\n"
+ "%take_mux_input_1 = OpLabel\n"
+ " OpBranch %end_label\n"
+ "%take_mux_input_2 = OpLabel\n"
+ " OpBranch %end_label\n"
+ "%end_label = OpLabel\n"
+ "%mux_output_var_ptr = OpPhi %sb_f32ptr" + muxInput1 + "%take_mux_input_1" + muxInput2 + "%take_mux_input_2\n";
+ spec.inputTypes[0] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[1] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[2] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.assembly = shaderTemplate.specialize(specs);
+ spec.numWorkGroups = IVec3(numMuxes, 1, 1);
+ spec.requestedVulkanFeatures = requiredFeatures;
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputAFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputBFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputSFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
+ spec.extensions.push_back("VK_KHR_variable_pointers");
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, name.c_str(), name.c_str(), spec));
+ }
+ { // Variable Pointer Reads (using OpCopyObject)
+ ComputeShaderSpec spec;
+ map<string, string> specs;
+ string name = "reads_opcopyobject_" + bufferType;
+ specs["ExtraCapability"] = extraCap;
+ specs["ExtraTypes"] = "";
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraSetupComputations"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] =
+ "%mux_input_1_copy = OpCopyObject %sb_f32ptr" + muxInput1 + "\n"
+ "%mux_input_2_copy = OpCopyObject %sb_f32ptr" + muxInput2 + "\n"
+ "%mux_output_var_ptr = OpSelect %sb_f32ptr %is_neg %mux_input_1_copy %mux_input_2_copy\n";
+ spec.inputTypes[0] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[1] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[2] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.assembly = shaderTemplate.specialize(specs);
+ spec.numWorkGroups = IVec3(numMuxes, 1, 1);
+ spec.requestedVulkanFeatures = requiredFeatures;
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputAFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputBFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputSFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
+ spec.extensions.push_back("VK_KHR_variable_pointers");
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, name.c_str(), name.c_str(), spec));
+ }
+ { // Test storing into Private variables.
+ const char* storageClasses[] = {"Private", "Function"};
+ for (int classId = 0; classId < 2; ++classId)
+ {
+ ComputeShaderSpec spec;
+ map<string, string> specs;
+ std::string storageClass = storageClasses[classId];
+ std::string name = "stores_" + string(de::toLower(storageClass)) + "_" + bufferType;
+ std::string description = "Test storing variable pointer into " + storageClass + " variable.";
+ std::string extraVariable = "%mux_output_copy = OpVariable %sb_f32ptrptr " + storageClass + "\n";
+ specs["ExtraTypes"] = "%sb_f32ptrptr = OpTypePointer " + storageClass + " %sb_f32ptr\n";
+ specs["ExtraCapability"] = extraCap;
+ specs["ExtraGlobalScopeVars"] = (classId == 0) ? extraVariable : "";
+ specs["ExtraFunctionScopeVars"] = (classId == 1) ? extraVariable : "";
+ specs["ExtraSetupComputations"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] =
+ "%opselect_result = OpSelect %sb_f32ptr %is_neg" + muxInput1 + muxInput2 + "\n"
+ " OpStore %mux_output_copy %opselect_result\n"
+ "%mux_output_var_ptr = OpLoad %sb_f32ptr %mux_output_copy\n";
+ spec.inputTypes[0] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[1] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[2] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.assembly = shaderTemplate.specialize(specs);
+ spec.numWorkGroups = IVec3(numMuxes, 1, 1);
+ spec.requestedVulkanFeatures = requiredFeatures;
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputAFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputBFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputSFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
+ spec.extensions.push_back("VK_KHR_variable_pointers");
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, name.c_str(), description.c_str(), spec));
+ }
+ }
+ { // Variable Pointer Reads (Using OpPtrAccessChain)
+ ComputeShaderSpec spec;
+ map<string, string> specs;
+ std::string name = "reads_opptraccesschain_" + bufferType;
+ std::string in_1 = isSingleInputBuffer ? " %a_2i_ptr " : " %a_i_ptr ";
+ std::string in_2 = isSingleInputBuffer ? " %a_2i_plus_1_ptr " : " %b_i_ptr ";
+ specs["ExtraTypes"] = "";
+ specs["ExtraCapability"] = extraCap;
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraSetupComputations"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] =
+ "%a_ptr = OpAccessChain %sb_f32ptr %indata_a %zero %zero\n"
+ "%b_ptr = OpAccessChain %sb_f32ptr %indata_b %zero %zero\n"
+ "%s_ptr = OpAccessChain %sb_f32ptr %indata_s %zero %zero\n"
+ "%out_ptr = OpAccessChain %sb_f32ptr %outdata %zero %zero\n"
+ "%a_i_ptr = OpPtrAccessChain %sb_f32ptr %a_ptr %i\n"
+ "%b_i_ptr = OpPtrAccessChain %sb_f32ptr %b_ptr %i\n"
+ "%s_i_ptr = OpPtrAccessChain %sb_f32ptr %s_ptr %i\n"
+ "%a_2i_ptr = OpPtrAccessChain %sb_f32ptr %a_ptr %two_i\n"
+ "%a_2i_plus_1_ptr = OpPtrAccessChain %sb_f32ptr %a_ptr %two_i_plus_1\n"
+ "%mux_output_var_ptr = OpSelect %sb_f32ptr %is_neg " + in_1 + in_2 + "\n";
+ spec.inputTypes[0] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[1] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[2] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.assembly = shaderTemplate.specialize(specs);
+ spec.numWorkGroups = IVec3(numMuxes, 1, 1);
+ spec.requestedVulkanFeatures = requiredFeatures;
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputAFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputBFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputSFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
+ spec.extensions.push_back("VK_KHR_variable_pointers");
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, name.c_str(), name.c_str(), spec));
+ }
+ { // Variable Pointer Writes
+ ComputeShaderSpec spec;
+ map<string, string> specs;
+ std::string name = "writes_" + bufferType;
+ specs["ExtraCapability"] = extraCap;
+ specs["ExtraTypes"] = "";
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraSetupComputations"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] = "%mux_output_var_ptr = OpSelect %sb_f32ptr %is_neg" + muxInput1 + muxInput2 + "\n" +
+ " %val = OpLoad %f32 %mux_output_var_ptr\n"
+ " %val_plus_1 = OpFAdd %f32 %val %fone\n"
+ " OpStore %mux_output_var_ptr %val_plus_1\n";
+ spec.inputTypes[0] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[1] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[2] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.assembly = shaderTemplate.specialize(specs);
+ spec.numWorkGroups = IVec3(numMuxes, 1, 1);
+ spec.requestedVulkanFeatures = requiredFeatures;
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputAFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputBFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputSFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(expectedIncrOutput)));
+ spec.extensions.push_back("VK_KHR_variable_pointers");
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, name.c_str(), name.c_str(), spec));
+ }
+
+ // If we only have VariablePointersStorageBuffer, then the extension does not apply to Workgroup storage class.
+ // Therefore the Workgroup tests apply to cases where the VariablePointers capability is used (when 2 input buffers are used).
+ if (!isSingleInputBuffer)
+ {
+ // VariablePointers on Workgroup
+ ComputeShaderSpec spec;
+ map<string, string> specs;
+ std::string name = "workgroup_" + bufferType;
+ specs["ExtraCapability"] = extraCap;
+ specs["ExtraTypes"] =
+ "%c_i32_N = OpConstant %i32 " + inputArraySize + " \n"
+ "%f32arr_N = OpTypeArray %f32 %c_i32_N\n"
+ "%f32arr_wrkgrp_ptr = OpTypePointer Workgroup %f32arr_N\n"
+ "%f32_wrkgrp_ptr = OpTypePointer Workgroup %f32\n";
+ specs["ExtraGlobalScopeVars"] =
+ "%AW = OpVariable %f32arr_wrkgrp_ptr Workgroup\n"
+ "%BW = OpVariable %f32arr_wrkgrp_ptr Workgroup\n";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraSetupComputations"] =
+ "%loc_AW_i = OpAccessChain %f32_wrkgrp_ptr %AW %i\n"
+ "%loc_BW_i = OpAccessChain %f32_wrkgrp_ptr %BW %i\n"
+ "%inval_a_i = OpLoad %f32 %inloc_a_i\n"
+ "%inval_b_i = OpLoad %f32 %inloc_b_i\n"
+ "%inval_a_2i = OpLoad %f32 %inloc_a_2i\n"
+ "%inval_a_2i_plus_1 = OpLoad %f32 %inloc_a_2i_plus_1\n";
+ specs["VarPtrName"] = "%output_var_ptr";
+ specs["ResultStrategy"] =
+ " OpStore %loc_AW_i %inval_a_i\n"
+ " OpStore %loc_BW_i %inval_b_i\n"
+ "%output_var_ptr = OpSelect %f32_wrkgrp_ptr %is_neg %loc_AW_i %loc_BW_i\n";
+ spec.inputTypes[0] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[1] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.inputTypes[2] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ spec.assembly = shaderTemplate.specialize(specs);
+ spec.numWorkGroups = IVec3(numMuxes, 1, 1);
+ spec.requestedVulkanFeatures = requiredFeatures;
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputAFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputBFloats)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputSFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
+ spec.extensions.push_back("VK_KHR_variable_pointers");
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, name.c_str(), name.c_str(), spec));
+ }
+ }
+}
+
+void addGraphicsVariablePointersGroup (tcu::TestCaseGroup* testGroup)
+{
+ tcu::TestContext& testCtx = testGroup->getTestContext();
+ de::Random rnd (deStringHash(testGroup->getName()));
+ map<string, string> fragments;
+ RGBA defaultColors[4];
+ vector<string> extensions;
+ const int seed = testCtx.getCommandLine().getBaseSeed();
+ const int numMuxes = 100;
+ const std::string numMuxesStr = "100";
+ vector<float> inputAFloats (2*numMuxes, 0);
+ vector<float> inputBFloats (2*numMuxes, 0);
+ vector<float> inputSFloats (numMuxes, 0);
+ vector<float> AmuxAOutputFloats (numMuxes, 0);
+ vector<float> AmuxBOutputFloats (numMuxes, 0);
+ vector<float> incrAmuxAOutputFloats (numMuxes, 0);
+ vector<float> incrAmuxBOutputFloats (numMuxes, 0);
+ VulkanFeatures requiredFeatures;
+
+ extensions.push_back("VK_KHR_variable_pointers");
+ getDefaultColors(defaultColors);
+
+ // Each output entry is chosen as follows: ( 0 <= i < numMuxes)
+ // 1) For tests with one input buffer: output[i] = (s[i] < 0) ? A[2*i] : A[2*i+1];
+ // 2) For tests with two input buffers: output[i] = (s[i] < 0) ? A[i] : B[i];
+
+ fillRandomScalars(rnd, -100.f, 100.f, &inputAFloats[0], 2*numMuxes);
+ fillRandomScalars(rnd, -100.f, 100.f, &inputBFloats[0], 2*numMuxes);
+
+ // We want to guarantee that the S input has some positive and some negative values.
+ // We choose random negative numbers for the first half, random positive numbers for the second half, and then shuffle.
+ fillRandomScalars(rnd, -100.f, -1.f , &inputSFloats[0], numMuxes / 2);
+ fillRandomScalars(rnd, 1.f , 100.f, &inputSFloats[numMuxes / 2], numMuxes / 2);
+ de::Random(seed).shuffle(inputSFloats.begin(), inputSFloats.end());
+
+ for (size_t i = 0; i < numMuxes; ++i)
+ {
+ AmuxAOutputFloats[i] = (inputSFloats[i] < 0) ? inputAFloats[2*i] : inputAFloats[2*i+1];
+ AmuxBOutputFloats[i] = (inputSFloats[i] < 0) ? inputAFloats[i] : inputBFloats[i];
+ incrAmuxAOutputFloats[i] = (inputSFloats[i] < 0) ? 1 + inputAFloats[2*i] : 1 + inputAFloats[2*i+1];
+ incrAmuxBOutputFloats[i] = (inputSFloats[i] < 0) ? 1 + inputAFloats[i] : 1 + inputBFloats[i];
+ }
+
+ fragments["extension"] = "OpExtension \"SPV_KHR_variable_pointers\"\n"
+ "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
+
+ const StringTemplate preMain (
+ "%c_i32_limit = OpConstant %i32 " + numMuxesStr + "\n"
+ " %sb_f32 = OpTypePointer StorageBuffer %f32\n"
+ " %ra_f32 = OpTypeRuntimeArray %f32\n"
+ " %buf = OpTypeStruct %ra_f32\n"
+ " %sb_buf = OpTypePointer StorageBuffer %buf\n"
+
+ " ${ExtraTypes}"
+
+ " ${ExtraGlobalScopeVars}"
+
+ " %indata_a = OpVariable %sb_buf StorageBuffer\n"
+ " %indata_b = OpVariable %sb_buf StorageBuffer\n"
+ " %indata_s = OpVariable %sb_buf StorageBuffer\n"
+ " %outdata = OpVariable %sb_buf StorageBuffer\n"
+
+ " ${ExtraFunctions} ");
+
+ const std::string selectorFunction (
+ // We're going to put the "selector" function here.
+ // This function type is needed for tests that use OpFunctionCall.
+ "%selector_func_type = OpTypeFunction %sb_f32 %bool %sb_f32 %sb_f32\n"
+ "%choose_input_func = OpFunction %sb_f32 None %selector_func_type\n"
+ "%is_neg_param = OpFunctionParameter %bool\n"
+ "%first_ptr_param = OpFunctionParameter %sb_f32\n"
+ "%second_ptr_param = OpFunctionParameter %sb_f32\n"
+ "%selector_func_begin = OpLabel\n"
+ "%result_ptr = OpSelect %sb_f32 %is_neg_param %first_ptr_param %second_ptr_param\n"
+ "OpReturnValue %result_ptr\n"
+ "OpFunctionEnd\n");
+
+ const StringTemplate decoration (
+ "OpMemberDecorate %buf 0 Offset 0\n"
+ "OpDecorate %buf Block\n"
+ "OpDecorate %ra_f32 ArrayStride 4\n"
+ "OpDecorate %sb_f32 ArrayStride 4\n"
+ "OpDecorate %indata_a DescriptorSet 0\n"
+ "OpDecorate %indata_b DescriptorSet 0\n"
+ "OpDecorate %indata_s DescriptorSet 0\n"
+ "OpDecorate %outdata DescriptorSet 0\n"
+ "OpDecorate %indata_a Binding 0\n"
+ "OpDecorate %indata_b Binding 1\n"
+ "OpDecorate %indata_s Binding 2\n"
+ "OpDecorate %outdata Binding 3\n");
+
+ const StringTemplate testFunction (
+ "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+ "%param = OpFunctionParameter %v4f32\n"
+ "%entry = OpLabel\n"
+
+ "${ExtraFunctionScopeVars}"
+
+ "%i = OpVariable %fp_i32 Function\n"
+
+ "%should_run = OpFunctionCall %bool %isUniqueIdZero\n"
+ " OpSelectionMerge %end_if None\n"
+ " OpBranchConditional %should_run %run_test %end_if\n"
+
+ "%run_test = OpLabel\n"
+ " OpStore %i %c_i32_0\n"
+ " OpBranch %loop\n"
+ // loop header
+ "%loop = OpLabel\n"
+ "%15 = OpLoad %i32 %i\n"
+ "%lt = OpSLessThan %bool %15 %c_i32_limit\n"
+ " OpLoopMerge %merge %inc None\n"
+ " OpBranchConditional %lt %write %merge\n"
+ // loop body
+ "%write = OpLabel\n"
+ "%30 = OpLoad %i32 %i\n"
+ "%two_i = OpIAdd %i32 %30 %30\n"
+ "%two_i_plus_1 = OpIAdd %i32 %two_i %c_i32_1\n"
+ "%loc_s_i = OpAccessChain %sb_f32 %indata_s %c_i32_0 %30\n"
+ "%loc_a_i = OpAccessChain %sb_f32 %indata_a %c_i32_0 %30\n"
+ "%loc_b_i = OpAccessChain %sb_f32 %indata_b %c_i32_0 %30\n"
+ "%loc_a_2i = OpAccessChain %sb_f32 %indata_a %c_i32_0 %two_i\n"
+ "%loc_a_2i_plus_1 = OpAccessChain %sb_f32 %indata_a %c_i32_0 %two_i_plus_1\n"
+ "%loc_outdata_i = OpAccessChain %sb_f32 %outdata %c_i32_0 %30\n"
+ "%val_s_i = OpLoad %f32 %loc_s_i\n"
+ "%is_neg = OpFOrdLessThan %bool %val_s_i %c_f32_0\n"
+
+ // select using a strategy.
+ "${ResultStrategy}"
+
+ // load through the variable pointer
+ "%mux_output = OpLoad %f32 ${VarPtrName}\n"
+
+ // store to the output vector.
+ " OpStore %loc_outdata_i %mux_output\n"
+ " OpBranch %inc\n"
+ // ++i
+ " %inc = OpLabel\n"
+ " %37 = OpLoad %i32 %i\n"
+ " %39 = OpIAdd %i32 %37 %c_i32_1\n"
+ " OpStore %i %39\n"
+ " OpBranch %loop\n"
+
+ // Return and FunctionEnd
+ "%merge = OpLabel\n"
+ " OpBranch %end_if\n"
+ "%end_if = OpLabel\n"
+ "OpReturnValue %param\n"
+ "OpFunctionEnd\n");
+
+ const bool singleInputBuffer[] = { true, false };
+ for (int inputBufferTypeIndex = 0 ; inputBufferTypeIndex < 2; ++inputBufferTypeIndex)
+ {
+ const bool isSingleInputBuffer = singleInputBuffer[inputBufferTypeIndex];
+ const string cap = isSingleInputBuffer ? "OpCapability VariablePointersStorageBuffer\n" : "OpCapability VariablePointers\n";
+ const vector<float>& expectedOutput = isSingleInputBuffer ? AmuxAOutputFloats : AmuxBOutputFloats;
+ const vector<float>& expectedIncrOutput = isSingleInputBuffer ? incrAmuxAOutputFloats : incrAmuxBOutputFloats;
+ const string bufferType = isSingleInputBuffer ? "single_buffer" : "two_buffers";
+ const string muxInput1 = isSingleInputBuffer ? " %loc_a_2i " : " %loc_a_i ";
+ const string muxInput2 = isSingleInputBuffer ? " %loc_a_2i_plus_1 " : " %loc_b_i ";
+
+ // Set the proper extension features required for the test
+ if (isSingleInputBuffer)
+ requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER;
+ else
+ requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS;
+
+ // All of the following tests write their results into an output SSBO, therefore they require the following features.
+ requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
+ requiredFeatures.coreFeatures.fragmentStoresAndAtomics = DE_TRUE;
+
+ { // Variable Pointer Reads (using OpSelect)
+ GraphicsResources resources;
+ map<string, string> specs;
+ string name = "reads_opselect_" + bufferType;
+ specs["ExtraTypes"] = "";
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraFunctions"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] = "%mux_output_var_ptr = OpSelect %sb_f32 %is_neg" + muxInput1 + muxInput2 + "\n";
+
+ fragments["capability"] = cap;
+ fragments["decoration"] = decoration.specialize(specs);
+ fragments["pre_main"] = preMain.specialize(specs);
+ fragments["testfun"] = testFunction.specialize(specs);
+
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputAFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputBFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputSFloats))));
+ resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(expectedOutput))));
+ createTestsForAllStages(name.c_str(), defaultColors, defaultColors, fragments, resources, extensions, testGroup, requiredFeatures);
+ }
+ { // Variable Pointer Reads (using OpFunctionCall)
+ GraphicsResources resources;
+ map<string, string> specs;
+ string name = "reads_opfunctioncall_" + bufferType;
+ specs["ExtraTypes"] = "";
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraFunctions"] = selectorFunction;
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] = "%mux_output_var_ptr = OpFunctionCall %sb_f32 %choose_input_func %is_neg" + muxInput1 + muxInput2 + "\n";
+
+ fragments["capability"] = cap;
+ fragments["decoration"] = decoration.specialize(specs);
+ fragments["pre_main"] = preMain.specialize(specs);
+ fragments["testfun"] = testFunction.specialize(specs);
+
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputAFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputBFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputSFloats))));
+ resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(expectedOutput))));
+ createTestsForAllStages(name.c_str(), defaultColors, defaultColors, fragments, resources, extensions, testGroup, requiredFeatures);
+ }
+ { // Variable Pointer Reads (using OpPhi)
+ GraphicsResources resources;
+ map<string, string> specs;
+ string name = "reads_opphi_" + bufferType;
+ specs["ExtraTypes"] = "";
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraFunctions"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] =
+ " OpSelectionMerge %end_label None\n"
+ " OpBranchConditional %is_neg %take_mux_input_1 %take_mux_input_2\n"
+ "%take_mux_input_1 = OpLabel\n"
+ " OpBranch %end_label\n"
+ "%take_mux_input_2 = OpLabel\n"
+ " OpBranch %end_label\n"
+ "%end_label = OpLabel\n"
+ "%mux_output_var_ptr = OpPhi %sb_f32" + muxInput1 + "%take_mux_input_1" + muxInput2 + "%take_mux_input_2\n";
+
+ fragments["capability"] = cap;
+ fragments["decoration"] = decoration.specialize(specs);
+ fragments["pre_main"] = preMain.specialize(specs);
+ fragments["testfun"] = testFunction.specialize(specs);
+
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputAFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputBFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputSFloats))));
+ resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(expectedOutput))));
+ createTestsForAllStages(name.c_str(), defaultColors, defaultColors, fragments, resources, extensions, testGroup, requiredFeatures);
+ }
+ { // Variable Pointer Reads (using OpCopyObject)
+ GraphicsResources resources;
+ map<string, string> specs;
+ string name = "reads_opcopyobject_" + bufferType;
+ specs["ExtraTypes"] = "";
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraFunctions"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] =
+ "%mux_input_1_copy = OpCopyObject %sb_f32" + muxInput1 + "\n"
+ "%mux_input_2_copy = OpCopyObject %sb_f32" + muxInput2 + "\n"
+ "%mux_output_var_ptr = OpSelect %sb_f32 %is_neg %mux_input_1_copy %mux_input_2_copy\n";
+
+ fragments["capability"] = cap;
+ fragments["decoration"] = decoration.specialize(specs);
+ fragments["pre_main"] = preMain.specialize(specs);
+ fragments["testfun"] = testFunction.specialize(specs);
+
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputAFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputBFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputSFloats))));
+ resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(expectedOutput))));
+ createTestsForAllStages(name.c_str(), defaultColors, defaultColors, fragments, resources, extensions, testGroup, requiredFeatures);
+ }
+ { // Test storing into Private variables.
+ const char* storageClasses[] = {"Private", "Function"};
+ for (int classId = 0; classId < 2; ++classId)
+ {
+ GraphicsResources resources;
+ map<string, string> specs;
+ std::string storageClass = storageClasses[classId];
+ std::string name = "stores_" + string(de::toLower(storageClass)) + "_" + bufferType;
+ std::string extraVariable = "%mux_output_copy = OpVariable %sb_f32ptrptr " + storageClass + "\n";
+ specs["ExtraTypes"] = "%sb_f32ptrptr = OpTypePointer " + storageClass + " %sb_f32\n";
+ specs["ExtraGlobalScopeVars"] = (classId == 0) ? extraVariable : "";
+ specs["ExtraFunctionScopeVars"] = (classId == 1) ? extraVariable : "";
+ specs["ExtraFunctions"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] =
+ "%opselect_result = OpSelect %sb_f32 %is_neg" + muxInput1 + muxInput2 + "\n"
+ " OpStore %mux_output_copy %opselect_result\n"
+ "%mux_output_var_ptr = OpLoad %sb_f32 %mux_output_copy\n";
+
+ fragments["capability"] = cap;
+ fragments["decoration"] = decoration.specialize(specs);
+ fragments["pre_main"] = preMain.specialize(specs);
+ fragments["testfun"] = testFunction.specialize(specs);
+
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputAFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputBFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputSFloats))));
+ resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(expectedOutput))));
+ createTestsForAllStages(name.c_str(), defaultColors, defaultColors, fragments, resources, extensions, testGroup, requiredFeatures);
+ }
+ }
+ { // Variable Pointer Reads (using OpPtrAccessChain)
+ GraphicsResources resources;
+ map<string, string> specs;
+ std::string name = "reads_opptraccesschain_" + bufferType;
+ std::string in_1 = isSingleInputBuffer ? " %a_2i_ptr " : " %a_i_ptr ";
+ std::string in_2 = isSingleInputBuffer ? " %a_2i_plus_1_ptr " : " %b_i_ptr ";
+ specs["ExtraTypes"] = "";
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraFunctions"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] =
+ "%a_ptr = OpAccessChain %sb_f32 %indata_a %c_i32_0 %c_i32_0\n"
+ "%b_ptr = OpAccessChain %sb_f32 %indata_b %c_i32_0 %c_i32_0\n"
+ "%s_ptr = OpAccessChain %sb_f32 %indata_s %c_i32_0 %c_i32_0\n"
+ "%out_ptr = OpAccessChain %sb_f32 %outdata %c_i32_0 %c_i32_0\n"
+ "%a_i_ptr = OpPtrAccessChain %sb_f32 %a_ptr %30\n"
+ "%b_i_ptr = OpPtrAccessChain %sb_f32 %b_ptr %30\n"
+ "%s_i_ptr = OpPtrAccessChain %sb_f32 %s_ptr %30\n"
+ "%a_2i_ptr = OpPtrAccessChain %sb_f32 %a_ptr %two_i\n"
+ "%a_2i_plus_1_ptr = OpPtrAccessChain %sb_f32 %a_ptr %two_i_plus_1\n"
+ "%mux_output_var_ptr = OpSelect %sb_f32 %is_neg " + in_1 + in_2 + "\n";
+
+ fragments["decoration"] = decoration.specialize(specs);
+ fragments["pre_main"] = preMain.specialize(specs);
+ fragments["testfun"] = testFunction.specialize(specs);
+ fragments["capability"] = cap;
+
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputAFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputBFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputSFloats))));
+ resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(expectedOutput))));
+ createTestsForAllStages(name.c_str(), defaultColors, defaultColors, fragments, resources, extensions, testGroup, requiredFeatures);
+ }
+ { // Variable Pointer Writes
+ GraphicsResources resources;
+ map<string, string> specs;
+ std::string name = "writes_" + bufferType;
+ specs["ExtraTypes"] = "";
+ specs["ExtraGlobalScopeVars"] = "";
+ specs["ExtraFunctionScopeVars"] = "";
+ specs["ExtraFunctions"] = "";
+ specs["VarPtrName"] = "%mux_output_var_ptr";
+ specs["ResultStrategy"] =
+ "%mux_output_var_ptr = OpSelect %sb_f32 %is_neg" + muxInput1 + muxInput2 + "\n" +
+ " %val = OpLoad %f32 %mux_output_var_ptr\n"
+ " %val_plus_1 = OpFAdd %f32 %val %c_f32_1\n"
+ " OpStore %mux_output_var_ptr %val_plus_1\n";
+ fragments["capability"] = cap;
+ fragments["decoration"] = decoration.specialize(specs);
+ fragments["pre_main"] = preMain.specialize(specs);
+ fragments["testfun"] = testFunction.specialize(specs);
+
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputAFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputBFloats))));
+ resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputSFloats))));
+ resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(expectedIncrOutput))));
+ createTestsForAllStages(name.c_str(), defaultColors, defaultColors, fragments, resources, extensions, testGroup, requiredFeatures);
+ }
+ }
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createVariablePointersComputeGroup (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "variable_pointers", "Compute tests for SPV_KHR_variable_pointers extension"));
+ addTestGroup(group.get(), "compute", "Test the variable pointer extension using a compute shader", addComputeVariablePointersGroup);
+
+ // \todo [2017-03-17 ehsann] A couple of things to do:
+ // * Add more tests (similar to existing ones) using data types other than Float.
+ return group.release();
+}
+
+tcu::TestCaseGroup* createVariablePointersGraphicsGroup (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "variable_pointers", "Graphics tests for SPV_KHR_variable_pointers extension"));
+ addTestGroup(group.get(), "graphics", "Testing Variable Pointers in graphics pipeline", addGraphicsVariablePointersGroup);
+
+ // \todo [2017-03-17 ehsann] A couple of things to do:
+ // * Add more tests (similar to existing ones) using data types other than Float.
+ return group.release();
+}
+
+} // SpirVAssembly
+} // vkt
--- /dev/null
+#ifndef _VKTSPVASMVARIABLEPOINTERSTESTS_HPP
+#define _VKTSPVASMVARIABLEPOINTERSTESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 Google 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 SPIR-V Assembly Tests for SPV_KHR_variable_pointers
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+tcu::TestCaseGroup* createVariablePointersComputeGroup (tcu::TestContext& testCtx);
+tcu::TestCaseGroup* createVariablePointersGraphicsGroup (tcu::TestContext& testCtx);
+
+} // SpirVAssembly
+} // vkt
+
+#endif // _VKTSPVASMVARIABLEPOINTERSTESTS_HPP
dEQP-VK.spirv_assembly.instruction.compute.16bit_storage.push_constant_16_to_32.scalar_uint
dEQP-VK.spirv_assembly.instruction.compute.16bit_storage.push_constant_16_to_32.vector_sint
dEQP-VK.spirv_assembly.instruction.compute.16bit_storage.push_constant_16_to_32.vector_uint
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opselect_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opfunctioncall_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opphi_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opcopyobject_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.stores_private_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.stores_function_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opptraccesschain_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.writes_single_buffer
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opselect_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opfunctioncall_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opphi_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opcopyobject_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.stores_private_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.stores_function_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.reads_opptraccesschain_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.writes_two_buffers
+dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.compute.workgroup_two_buffers
dEQP-VK.spirv_assembly.instruction.graphics.opnop.opnop_vert
dEQP-VK.spirv_assembly.instruction.graphics.opnop.opnop_tessc
dEQP-VK.spirv_assembly.instruction.graphics.opnop.opnop_tesse
dEQP-VK.spirv_assembly.instruction.graphics.16bit_storage.push_constant_int_16_to_32.uint_vector_tesse
dEQP-VK.spirv_assembly.instruction.graphics.16bit_storage.push_constant_int_16_to_32.uint_vector_geom
dEQP-VK.spirv_assembly.instruction.graphics.16bit_storage.push_constant_int_16_to_32.uint_vector_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_single_buffer_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_single_buffer_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_single_buffer_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_single_buffer_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_single_buffer_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opselect_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opfunctioncall_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opphi_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opcopyobject_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_private_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.stores_function_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.reads_opptraccesschain_two_buffers_frag
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_two_buffers_vert
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_two_buffers_tessc
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_two_buffers_tesse
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_two_buffers_geom
+dEQP-VK.spirv_assembly.instruction.graphics.variable_pointers.graphics.writes_two_buffers_frag
dEQP-VK.glsl.arrays.constructor.float3_vertex
dEQP-VK.glsl.arrays.constructor.float3_fragment
dEQP-VK.glsl.arrays.constructor.float4_vertex
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000,
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001,
VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = 1000120000,
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = 1000127000,
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = 1000127001,
VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = 1000146000,
#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 2
#define VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace"
+#define VK_KHR_variable_pointers 1
+#define VK_KHR_VARIABLE_POINTERS_SPEC_VERSION 1
+#define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME "VK_KHR_variable_pointers"
+
+typedef struct VkPhysicalDeviceVariablePointerFeaturesKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 variablePointersStorageBuffer;
+ VkBool32 variablePointers;
+} VkPhysicalDeviceVariablePointerFeaturesKHR;
+
#ifdef __cplusplus
}