1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2021 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Vulkan SC VK_KHR_object_refresh Tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktObjectRefreshTests.hpp"
25
26 #include "vkDefs.hpp"
27 #include "vkRefUtil.hpp"
28 #include "vkDefs.hpp"
29 #include "vkDeviceUtil.hpp"
30 #include "vkPlatform.hpp"
31 #include "vkTypeUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkObjUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vktTestCaseUtil.hpp"
37 #include "vkQueryUtil.hpp"
38
39 #include <map>
40 #include <vector>
41
42 namespace vkt
43 {
44 namespace sc
45 {
46 namespace
47 {
48
queryRefreshableObjects(Context & context)49 tcu::TestStatus queryRefreshableObjects(Context& context)
50 {
51 deUint32 countReported = 0u;
52 vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
53 const vk::InstanceInterface& vki = context.getInstanceInterface();
54
55 // get number of refreshable objects
56 vk::VkResult result = vki.getPhysicalDeviceRefreshableObjectTypesKHR(physicalDevice, &countReported, DE_NULL);
57 if (result != vk::VK_SUCCESS)
58 TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceRefreshableObjectTypesKHR returned invalid return code");
59
60 if (countReported == 0)
61 TCU_THROW(NotSupportedError, "No refreshable objects available");
62
63 deUint32 refreshableObjectsMaxCount (countReported + 2);
64 std::vector<vk::VkObjectType> refreshableObjects (refreshableObjectsMaxCount);
65
66 for (deUint32 countRequested = 0; countRequested < refreshableObjectsMaxCount; ++countRequested)
67 {
68 // get refreshable objects
69 deUint32 countRetrieved = countRequested;
70 std::fill(refreshableObjects.begin(), refreshableObjects.end(), vk::VK_OBJECT_TYPE_UNKNOWN);
71 result = vki.getPhysicalDeviceRefreshableObjectTypesKHR(physicalDevice, &countRetrieved, refreshableObjects.data());
72
73 // verify returned code
74 if ((result != vk::VK_SUCCESS) && (result != vk::VK_INCOMPLETE))
75 TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceRefreshableObjectTypesKHR returned invalid return code");
76
77 // verify number of retrieved objects
78 if (countRetrieved != std::min(countRequested, countReported))
79 TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceRefreshableObjectTypesKHR returned invalid number of retrieved objects");
80
81 // verify retrieved objects
82 for (deUint32 i = 0; i < countRetrieved; ++i)
83 {
84 if (refreshableObjects[i] == vk::VK_OBJECT_TYPE_UNKNOWN)
85 TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceRefreshableObjectTypesKHR returned invalid object type");
86 }
87 }
88
89 return tcu::TestStatus::pass("pass");
90 }
91
refreshObjects(Context & context,bool individualRefresh)92 tcu::TestStatus refreshObjects(Context& context, bool individualRefresh)
93 {
94 deUint32 countReported = 0u;
95 vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
96 const vk::InstanceInterface& vki = context.getInstanceInterface();
97 const vk::DeviceInterface& vkd = context.getDeviceInterface();
98
99 vk::VkResult result = vki.getPhysicalDeviceRefreshableObjectTypesKHR(physicalDevice, &countReported, DE_NULL);
100 if ((result != vk::VK_SUCCESS) || (countReported == 0))
101 TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceRefreshableObjectTypesKHR failed");
102
103 std::vector<vk::VkObjectType> refreshableObjectTypes(countReported);
104 result = vki.getPhysicalDeviceRefreshableObjectTypesKHR(physicalDevice, &countReported, refreshableObjectTypes.data());
105 if (result != vk::VK_SUCCESS)
106 TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceRefreshableObjectTypesKHR failed");
107
108 // create all possible objects
109 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
110 vk::VkDevice device = context.getDevice();
111 vk::VkQueue queue = context.getUniversalQueue();
112 vk::Allocator& allocator = context.getDefaultAllocator();
113 vk::Move<vk::VkCommandPool> cmdPool = createCommandPool(vkd, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
114 vk::Move<vk::VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
115 vk::Move<vk::VkFence> fence = createFence(vkd, device);
116 vk::Move<vk::VkSemaphore> semaphore = createSemaphore(vkd, device);
117 vk::Move<vk::VkEvent> event = createEvent(vkd, device);
118 const vk::VkQueryPoolCreateInfo queryPoolCreateInfo
119 {
120 vk::VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType sType;
121 DE_NULL, // const void* pNext;
122 0u, // VkQueryPoolCreateFlags flags;
123 vk::VK_QUERY_TYPE_OCCLUSION, // VkQueryType queryType;
124 1u, // deUint32 queryCount;
125 0u, // VkQueryPipelineStatisticFlags pipelineStatistics;
126 };
127 vk::Move<vk::VkQueryPool> queryPool = createQueryPool(vkd, device, &queryPoolCreateInfo);
128 const vk::VkBufferCreateInfo bufferCreateInfo
129 {
130 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
131 DE_NULL, // const void* pNext
132 0u, // VkBufferCreateFlags flags
133 (vk::VkDeviceSize)64, // VkDeviceSize size
134 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT | vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, // VkBufferUsageFlags usage
135 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
136 0u, // deUint32 queueFamilyIndexCount
137 DE_NULL // const deUint32* pQueueFamilyIndices
138 };
139 vk::Move<vk::VkBuffer> buffer = createBuffer(vkd, device, &bufferCreateInfo);
140 const vk::VkMemoryRequirements bufferRequirements = getBufferMemoryRequirements(vkd, device, *buffer);
141 de::MovePtr<vk::Allocation> bufferAllocation = allocator.allocate(bufferRequirements, vk::MemoryRequirement::HostVisible);
142 vkd.bindBufferMemory(device, *buffer, bufferAllocation->getMemory(), 0);
143 vk::Move<vk::VkBufferView> bufferView = makeBufferView(vkd, device, *buffer, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 0ull, VK_WHOLE_SIZE);
144 const vk::VkSamplerCreateInfo samplerCreateInfo
145 {
146 vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
147 DE_NULL, // const void* pNext;
148 (vk::VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags;
149 vk::VK_FILTER_NEAREST, // VkFilter magFilter;
150 vk::VK_FILTER_NEAREST, // VkFilter minFilter;
151 vk::VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
152 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
153 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
154 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
155 0.0f, // float mipLodBias;
156 VK_FALSE, // VkBool32 anisotropyEnable;
157 1.0f, // float maxAnisotropy;
158 VK_FALSE, // VkBool32 compareEnable;
159 vk::VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
160 0.0f, // float minLod;
161 0.0f, // float maxLod;
162 vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
163 VK_FALSE, // VkBool32 unnormalizedCoordinates;
164 };
165 vk::Move<vk::VkSampler> sampler = createSampler(vkd, device, &samplerCreateInfo);
166 const vk::VkSamplerYcbcrConversionCreateInfo conversionInfo
167 {
168 vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, // VkStructureType sType;
169 DE_NULL, // const void* pNext;
170 vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, // VkFormat format;
171 vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY, // VkSamplerYcbcrModelConversion ycbcrModel;
172 vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL, // VkSamplerYcbcrRange ycbcrRange;
173 { // VkComponentMapping components;
174 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
175 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
176 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
177 vk::VK_COMPONENT_SWIZZLE_IDENTITY
178 },
179 vk::VK_CHROMA_LOCATION_MIDPOINT, // VkChromaLocation xChromaOffset;
180 vk::VK_CHROMA_LOCATION_MIDPOINT, // VkChromaLocation yChromaOffset;
181 vk::VK_FILTER_NEAREST, // VkFilter chromaFilter;
182 DE_FALSE // VkBool32 forceExplicitReconstruction;
183 };
184 vk::Move<vk::VkSamplerYcbcrConversion> ycbcrConversion = vk::createSamplerYcbcrConversion(vkd, device, &conversionInfo);
185 const vk::VkImageCreateInfo imageCreateInfo
186 {
187 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
188 DE_NULL, // const void* pNext;
189 0u, // VkImageCreateFlags flags;
190 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType;
191 vk::VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
192 { 64, 64, 1 }, // VkExtent3D extent;
193 1u, // deUint32 mipLevels;
194 1u, // deUint32 arrayLayers;
195 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
196 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
197 vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage;
198 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
199 1u, // deUint32 queueFamilyIndexCount;
200 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
201 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
202 };
203 vk::Move<vk::VkImage> image = createImage(vkd, device, &imageCreateInfo);
204 const vk::VkMemoryRequirements imageRequirements = getImageMemoryRequirements(vkd, device, *image);
205 de::MovePtr<vk::Allocation> imageAllocation = allocator.allocate(imageRequirements, vk::MemoryRequirement::Any);
206 vkd.bindImageMemory(device, *image, imageAllocation->getMemory(), imageAllocation->getOffset());
207 vk::Move<vk::VkImageView> imageView = makeImageView(vkd, device, *image, vk::VK_IMAGE_VIEW_TYPE_2D, vk::VK_FORMAT_R8G8B8A8_UNORM, makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
208 vk::Move<vk::VkShaderModule> shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get("comp"), 0u);
209 vk::Move<vk::VkRenderPass> renderPass = makeRenderPass(vkd, device, vk::VK_FORMAT_R8G8B8A8_UNORM);
210 vk::Move<vk::VkFramebuffer> framebuffer = makeFramebuffer(vkd, device, *renderPass, *imageView, 64, 64);
211 const vk::VkPipelineCacheCreateInfo pipelineCacheCreateInfo
212 {
213 vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
214 DE_NULL, // const void* pNext;
215 vk::VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
216 vk::VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
217 context.getResourceInterface()->getCacheDataSize(), // deUintptr initialDataSize;
218 context.getResourceInterface()->getCacheData() // const void* pInitialData;
219 };
220 vk::Move<vk::VkPipelineCache> pipelineCache = createPipelineCache(vkd, device, &pipelineCacheCreateInfo);
221 vk::Move<vk::VkPipelineLayout> pipelineLayout = makePipelineLayout(vkd, device);
222 vk::Move<vk::VkPipeline> pipeline = makeComputePipeline(vkd, device, *pipelineLayout, 0u, *shaderModule, 0u, DE_NULL);
223 const vk::VkDescriptorPoolSize descriptorPoolSize
224 {
225 vk::VK_DESCRIPTOR_TYPE_SAMPLER, // VkDescriptorType type;
226 8 // deUint32 descriptorCount;
227 };
228 const vk::VkDescriptorPoolCreateInfo descriptorPoolCreateInfo
229 {
230 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType;
231 NULL, // const void* pNext;
232 0u, // VkDescriptorPoolCreateFlags flags;
233 8, // deUint32 maxSets;
234 1, // deUint32 poolSizeCount;
235 &descriptorPoolSize // const VkDescriptorPoolSize* pPoolSizes;
236 };
237 vk::Move<vk::VkDescriptorPool> descriptorPool = createDescriptorPool(vkd, device, &descriptorPoolCreateInfo);
238 const vk::VkDescriptorSetLayoutBinding descriptorSetLayoutBinding
239 {
240 0, // deUint32 binding;
241 vk::VK_DESCRIPTOR_TYPE_SAMPLER, // VkDescriptorType descriptorType;
242 1, // deUint32 descriptorCount;
243 vk::VK_SHADER_STAGE_ALL, // VkShaderStageFlags stageFlags;
244 NULL // const VkSampler* pImmutableSamplers;
245 };
246 const vk::VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo
247 {
248 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
249 NULL, // const void* pNext;
250 0, // VkDescriptorSetLayoutCreateFlags flags;
251 1, // deUint32 bindingCount;
252 &descriptorSetLayoutBinding // const VkDescriptorSetLayoutBinding* pBindings;
253 };
254 vk::Move<vk::VkDescriptorSetLayout> descriptorSetLayout = createDescriptorSetLayout(vkd, device, &descriptorSetLayoutInfo);
255 vk::Move<vk::VkDescriptorSet> descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
256
257 std::map<vk::VkObjectType, deUint64> objectHandlesMap
258 {
259 { vk::VK_OBJECT_TYPE_INSTANCE, 0 },
260 { vk::VK_OBJECT_TYPE_PHYSICAL_DEVICE, 0 },
261 { vk::VK_OBJECT_TYPE_DEVICE, 0 },
262 { vk::VK_OBJECT_TYPE_QUEUE, 0 },
263 { vk::VK_OBJECT_TYPE_SEMAPHORE, semaphore.get().getInternal() },
264 { vk::VK_OBJECT_TYPE_COMMAND_BUFFER, 0 },
265 { vk::VK_OBJECT_TYPE_FENCE, fence.get().getInternal() },
266 { vk::VK_OBJECT_TYPE_DEVICE_MEMORY, bufferAllocation->getMemory().getInternal() },
267 { vk::VK_OBJECT_TYPE_BUFFER, buffer.get().getInternal() },
268 { vk::VK_OBJECT_TYPE_IMAGE, image.get().getInternal() },
269 { vk::VK_OBJECT_TYPE_EVENT, event.get().getInternal() },
270 { vk::VK_OBJECT_TYPE_QUERY_POOL, queryPool.get().getInternal() },
271 { vk::VK_OBJECT_TYPE_BUFFER_VIEW, bufferView.get().getInternal() },
272 { vk::VK_OBJECT_TYPE_IMAGE_VIEW, imageView.get().getInternal() },
273 { vk::VK_OBJECT_TYPE_SHADER_MODULE, shaderModule.get().getInternal() },
274 { vk::VK_OBJECT_TYPE_PIPELINE_CACHE, pipelineCache.get().getInternal() },
275 { vk::VK_OBJECT_TYPE_PIPELINE_LAYOUT, pipelineLayout.get().getInternal() },
276 { vk::VK_OBJECT_TYPE_RENDER_PASS, renderPass.get().getInternal() },
277 { vk::VK_OBJECT_TYPE_PIPELINE, pipeline.get().getInternal() },
278 { vk::VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, descriptorSetLayout.get().getInternal() },
279 { vk::VK_OBJECT_TYPE_SAMPLER, sampler.get().getInternal() },
280 { vk::VK_OBJECT_TYPE_DESCRIPTOR_POOL, descriptorPool.get().getInternal() },
281 { vk::VK_OBJECT_TYPE_DESCRIPTOR_SET, descriptorSet.get().getInternal() },
282 { vk::VK_OBJECT_TYPE_FRAMEBUFFER, framebuffer.get().getInternal() },
283 { vk::VK_OBJECT_TYPE_COMMAND_POOL, cmdPool.get().getInternal() },
284 { vk::VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, ycbcrConversion.get().getInternal() },
285 { vk::VK_OBJECT_TYPE_SURFACE_KHR, 0 },
286 { vk::VK_OBJECT_TYPE_SWAPCHAIN_KHR, 0 },
287 { vk::VK_OBJECT_TYPE_DISPLAY_KHR, 0 },
288 { vk::VK_OBJECT_TYPE_DISPLAY_MODE_KHR, 0 },
289 { vk::VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT, 0 }
290 };
291
292 const vk::VkMemoryBarrier objRefreshBarrier
293 {
294 vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
295 DE_NULL,
296 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
297 vk::VK_ACCESS_MEMORY_READ_BIT
298 };
299
300 // record command buffer
301 vk::beginCommandBuffer(vkd, *cmdBuffer);
302
303 if (individualRefresh)
304 {
305 for (const auto& object : objectHandlesMap)
306 {
307 vk::VkObjectType objectType = object.first;
308 deUint64 objectHandle = object.second;
309
310 // skip object type if it can't be refreshed on current implementation
311 if (std::find(refreshableObjectTypes.begin(), refreshableObjectTypes.end(), objectType) == refreshableObjectTypes.end())
312 continue;
313
314 if (!objectHandle)
315 continue;
316
317 vk::VkRefreshObjectKHR refreshObject = { objectType, objectHandle, 0 };
318 vk::VkRefreshObjectListKHR refreshList = { vk::VK_STRUCTURE_TYPE_REFRESH_OBJECT_LIST_KHR, DE_NULL, 1, &refreshObject };
319 vkd.cmdRefreshObjectsKHR(*cmdBuffer, &refreshList);
320 vkd.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 1, &objRefreshBarrier, 0, DE_NULL, 0, DE_NULL);
321 }
322 }
323 else
324 {
325 deUint32 countUsed = 0;
326 std::vector<vk::VkRefreshObjectKHR> objectsToRefreshList(countReported);
327 for (deUint32 i = 0 ; i < countReported ; ++i)
328 {
329 vk::VkObjectType objectType = refreshableObjectTypes[i];
330 deUint64 objectHandle = objectHandlesMap.at(objectType);
331
332 if (!objectHandle)
333 continue;
334
335 objectsToRefreshList[countUsed++] =
336 {
337 objectType,
338 objectHandle,
339 0
340 };
341 }
342
343 vk::VkRefreshObjectListKHR refreshList = { vk::VK_STRUCTURE_TYPE_REFRESH_OBJECT_LIST_KHR, DE_NULL, countUsed, objectsToRefreshList.data() };
344 vkd.cmdRefreshObjectsKHR(*cmdBuffer, &refreshList);
345 vkd.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 1, &objRefreshBarrier, 0, DE_NULL, 0, DE_NULL);
346 }
347
348 vk::endCommandBuffer(vkd, *cmdBuffer);
349 vk::submitCommandsAndWait(vkd, device, queue, *cmdBuffer);
350
351 return tcu::TestStatus::pass("Pass");
352 }
353
createComputeSource(vk::SourceCollections & dst)354 void createComputeSource(vk::SourceCollections& dst)
355 {
356 dst.glslSources.add("comp") << glu::ComputeSource(
357 "#version 450\n"
358 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
359 "void main (void)\n"
360 "{\n"
361 " vec4 dummy = vec4(1.0);\n"
362 "}\n");
363 }
364
refreshIndividualObjects(Context & context)365 tcu::TestStatus refreshIndividualObjects(Context& context)
366 {
367 return refreshObjects(context, true);
368 }
369
refreshAllObjects(Context & context)370 tcu::TestStatus refreshAllObjects(Context& context)
371 {
372 return refreshObjects(context, false);
373 }
374
checkRefreshSupport(Context & context)375 void checkRefreshSupport(Context& context)
376 {
377 context.requireDeviceFunctionality("VK_KHR_object_refresh");
378 }
379
380 } // anonymous
381
createObjectRefreshTests(tcu::TestContext & testCtx)382 tcu::TestCaseGroup* createObjectRefreshTests (tcu::TestContext& testCtx)
383 {
384 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "object_refresh", "Tests VK_KHR_object_refresh"));
385
386 addFunctionCase(group.get(), "query_refreshable_objects", "Test VK_KHR_object_refresh extension", checkRefreshSupport, queryRefreshableObjects);
387 addFunctionCaseWithPrograms(group.get(), "refresh_individual_objects", "Test VK_KHR_object_refresh extension", checkRefreshSupport, createComputeSource, refreshIndividualObjects);
388 addFunctionCaseWithPrograms(group.get(), "refresh_all_objects", "Test VK_KHR_object_refresh extension", checkRefreshSupport, createComputeSource, refreshAllObjects);
389
390 return group.release();
391 }
392
393 } // sc
394
395 } // vkt
396