1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Utilities for images.
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineImageUtil.hpp"
26 #include "vkImageUtil.hpp"
27 #include "vkMemUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkCmdUtil.hpp"
31 #include "vkTypeUtil.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuAstcUtil.hpp"
34 #include "deRandom.hpp"
35 #include "deSharedPtr.hpp"
36
37 namespace vkt
38 {
39 namespace pipeline
40 {
41
42 using namespace vk;
43
44 /*! Gets the next multiple of a given divisor */
getNextMultiple(deUint32 divisor,deUint32 value)45 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
46 {
47 if (value % divisor == 0)
48 {
49 return value;
50 }
51 return value + divisor - (value % divisor);
52 }
53
54 /*! Gets the next value that is multiple of all given divisors */
getNextMultiple(const std::vector<deUint32> & divisors,deUint32 value)55 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
56 {
57 deUint32 nextMultiple = value;
58 bool nextMultipleFound = false;
59
60 while (true)
61 {
62 nextMultipleFound = true;
63
64 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
65 nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
66
67 if (nextMultipleFound)
68 break;
69
70 DE_ASSERT(nextMultiple < ~((deUint32)0u));
71 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
72 }
73
74 return nextMultiple;
75 }
76
isSupportedSamplableFormat(const InstanceInterface & instanceInterface,VkPhysicalDevice device,VkFormat format)77 bool isSupportedSamplableFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
78 {
79 if (isCompressedFormat(format))
80 {
81 VkPhysicalDeviceFeatures physicalFeatures;
82 const tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(format);
83
84 instanceInterface.getPhysicalDeviceFeatures(device, &physicalFeatures);
85
86 if (tcu::isAstcFormat(compressedFormat))
87 {
88 if (!physicalFeatures.textureCompressionASTC_LDR)
89 return false;
90 }
91 else if (tcu::isEtcFormat(compressedFormat))
92 {
93 if (!physicalFeatures.textureCompressionETC2)
94 return false;
95 }
96 else
97 {
98 DE_FATAL("Unsupported compressed format");
99 }
100 }
101
102 VkFormatProperties formatProps;
103 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
104
105 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
106 }
107
isLinearFilteringSupported(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkFormat format,VkImageTiling tiling)108 bool isLinearFilteringSupported (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling)
109 {
110 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
111 const VkFormatFeatureFlags formatFeatures = tiling == VK_IMAGE_TILING_LINEAR
112 ? formatProperties.linearTilingFeatures
113 : formatProperties.optimalTilingFeatures;
114
115 return (formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) != 0;
116 }
117
isMinMaxFilteringSupported(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkFormat format,VkImageTiling tiling)118 bool isMinMaxFilteringSupported (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling)
119 {
120 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
121 const VkFormatFeatureFlags formatFeatures = tiling == VK_IMAGE_TILING_LINEAR
122 ? formatProperties.linearTilingFeatures
123 : formatProperties.optimalTilingFeatures;
124
125 return (formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT) != 0;
126 }
127
getFormatBorderColor(BorderColor color,VkFormat format)128 VkBorderColor getFormatBorderColor (BorderColor color, VkFormat format)
129 {
130 if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format)))
131 {
132 switch (color)
133 {
134 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
135 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
136 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
137 case BORDER_COLOR_CUSTOM: return VK_BORDER_COLOR_INT_CUSTOM_EXT;
138 default:
139 break;
140 }
141 }
142 else
143 {
144 switch (color)
145 {
146 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
147 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
148 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
149 case BORDER_COLOR_CUSTOM: return VK_BORDER_COLOR_FLOAT_CUSTOM_EXT;
150 default:
151 break;
152 }
153 }
154
155 DE_ASSERT(false);
156 return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
157 }
158
getFormatCustomBorderColor(tcu::Vec4 floatValue,tcu::IVec4 intValue,vk::VkFormat format)159 rr::GenericVec4 getFormatCustomBorderColor (tcu::Vec4 floatValue, tcu::IVec4 intValue, vk::VkFormat format)
160 {
161 if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format)))
162 {
163 return rr::GenericVec4(intValue);
164 }
165 else
166 {
167 return rr::GenericVec4(floatValue);
168 }
169 }
170
getLookupScaleBias(vk::VkFormat format,tcu::Vec4 & lookupScale,tcu::Vec4 & lookupBias)171 void getLookupScaleBias (vk::VkFormat format, tcu::Vec4& lookupScale, tcu::Vec4& lookupBias)
172 {
173 if (!isCompressedFormat(format))
174 {
175 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(mapVkFormat(format));
176
177 // Needed to normalize various formats to 0..1 range for writing into RT
178 lookupScale = fmtInfo.lookupScale;
179 lookupBias = fmtInfo.lookupBias;
180 }
181 else
182 {
183 switch (format)
184 {
185 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
186 lookupScale = tcu::Vec4(0.5f, 1.0f, 1.0f, 1.0f);
187 lookupBias = tcu::Vec4(0.5f, 0.0f, 0.0f, 0.0f);
188 break;
189
190 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
191 lookupScale = tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f);
192 lookupBias = tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f);
193 break;
194
195 default:
196 // else: All supported compressed formats are fine with no normalization.
197 // ASTC LDR blocks decompress to f16 so querying normalization parameters
198 // based on uncompressed formats would actually lead to massive precision loss
199 // and complete lack of coverage in case of R8G8B8A8_UNORM RT.
200 lookupScale = tcu::Vec4(1.0f);
201 lookupBias = tcu::Vec4(0.0f);
202 break;
203 }
204 }
205 }
206
readColorAttachment(const vk::DeviceInterface & vk,vk::VkDevice device,vk::VkQueue queue,deUint32 queueFamilyIndex,vk::Allocator & allocator,vk::VkImage image,vk::VkFormat format,const tcu::UVec2 & renderSize)207 de::MovePtr<tcu::TextureLevel> readColorAttachment (const vk::DeviceInterface& vk,
208 vk::VkDevice device,
209 vk::VkQueue queue,
210 deUint32 queueFamilyIndex,
211 vk::Allocator& allocator,
212 vk::VkImage image,
213 vk::VkFormat format,
214 const tcu::UVec2& renderSize)
215 {
216 Move<VkBuffer> buffer;
217 de::MovePtr<Allocation> bufferAlloc;
218 Move<VkCommandPool> cmdPool;
219 Move<VkCommandBuffer> cmdBuffer;
220 Move<VkFence> fence;
221 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
222 const VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * tcuFormat.getPixelSize();
223 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y()));
224
225 // Create destination buffer
226 {
227 const VkBufferCreateInfo bufferParams =
228 {
229 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
230 DE_NULL, // const void* pNext;
231 0u, // VkBufferCreateFlags flags;
232 pixelDataSize, // VkDeviceSize size;
233 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
234 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
235 0u, // deUint32 queueFamilyIndexCount;
236 DE_NULL // const deUint32* pQueueFamilyIndices;
237 };
238
239 buffer = createBuffer(vk, device, &bufferParams);
240 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
241 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
242 }
243
244 // Create command pool and buffer
245 cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
246 cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
247
248 // Create fence
249 fence = createFence(vk, device);
250
251 beginCommandBuffer(vk, *cmdBuffer);
252 copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()));
253 endCommandBuffer(vk, *cmdBuffer);
254
255 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
256
257 // Read buffer data
258 invalidateAlloc(vk, device, *bufferAlloc);
259 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
260
261 return resultLevel;
262 }
263
readDepthAttachment(const vk::DeviceInterface & vk,vk::VkDevice device,vk::VkQueue queue,deUint32 queueFamilyIndex,vk::Allocator & allocator,vk::VkImage image,vk::VkFormat format,const tcu::UVec2 & renderSize,vk::VkImageLayout currentLayout)264 de::MovePtr<tcu::TextureLevel> readDepthAttachment (const vk::DeviceInterface& vk,
265 vk::VkDevice device,
266 vk::VkQueue queue,
267 deUint32 queueFamilyIndex,
268 vk::Allocator& allocator,
269 vk::VkImage image,
270 vk::VkFormat format,
271 const tcu::UVec2& renderSize,
272 vk::VkImageLayout currentLayout)
273 {
274 Move<VkBuffer> buffer;
275 de::MovePtr<Allocation> bufferAlloc;
276 Move<VkCommandPool> cmdPool;
277 Move<VkCommandBuffer> cmdBuffer;
278
279 tcu::TextureFormat retFormat (tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
280 tcu::TextureFormat bufferFormat (tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
281 const VkImageAspectFlags barrierAspect = VK_IMAGE_ASPECT_DEPTH_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_STENCIL_BIT : (VkImageAspectFlagBits)0);
282
283 switch (format)
284 {
285 case vk::VK_FORMAT_D16_UNORM:
286 case vk::VK_FORMAT_D16_UNORM_S8_UINT:
287 bufferFormat.type = retFormat.type = tcu::TextureFormat::UNORM_INT16;
288 break;
289 case vk::VK_FORMAT_D24_UNORM_S8_UINT:
290 case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
291 retFormat.type = tcu::TextureFormat::UNORM_INT24;
292 // vkCmdCopyBufferToImage copies D24 data to 32-bit pixels.
293 bufferFormat.type = tcu::TextureFormat::UNSIGNED_INT_24_8_REV;
294 break;
295 case vk::VK_FORMAT_D32_SFLOAT:
296 case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
297 bufferFormat.type = retFormat.type = tcu::TextureFormat::FLOAT;
298 break;
299 default:
300 TCU_FAIL("unrecognized format");
301 }
302
303 const VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
304 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
305
306 // Create destination buffer
307 {
308 const VkBufferCreateInfo bufferParams =
309 {
310 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
311 DE_NULL, // const void* pNext;
312 0u, // VkBufferCreateFlags flags;
313 pixelDataSize, // VkDeviceSize size;
314 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
315 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
316 0u, // deUint32 queueFamilyIndexCount;
317 DE_NULL // const deUint32* pQueueFamilyIndices;
318 };
319
320 buffer = createBuffer(vk, device, &bufferParams);
321 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
322 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
323 }
324
325 // Create command pool and buffer
326 cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
327 cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
328
329 beginCommandBuffer(vk, *cmdBuffer);
330 copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect, VK_IMAGE_ASPECT_DEPTH_BIT);
331 endCommandBuffer(vk, *cmdBuffer);
332
333 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
334
335 // Read buffer data
336 invalidateAlloc(vk, device, *bufferAlloc);
337 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
338
339 return resultLevel;
340 }
341
readStencilAttachment(const vk::DeviceInterface & vk,vk::VkDevice device,vk::VkQueue queue,deUint32 queueFamilyIndex,vk::Allocator & allocator,vk::VkImage image,vk::VkFormat format,const tcu::UVec2 & renderSize,vk::VkImageLayout currentLayout)342 de::MovePtr<tcu::TextureLevel> readStencilAttachment (const vk::DeviceInterface& vk,
343 vk::VkDevice device,
344 vk::VkQueue queue,
345 deUint32 queueFamilyIndex,
346 vk::Allocator& allocator,
347 vk::VkImage image,
348 vk::VkFormat format,
349 const tcu::UVec2& renderSize,
350 vk::VkImageLayout currentLayout)
351 {
352 Move<VkBuffer> buffer;
353 de::MovePtr<Allocation> bufferAlloc;
354 Move<VkCommandPool> cmdPool;
355 Move<VkCommandBuffer> cmdBuffer;
356
357 tcu::TextureFormat retFormat (tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
358 tcu::TextureFormat bufferFormat (tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
359
360 const VkImageAspectFlags barrierAspect = VK_IMAGE_ASPECT_STENCIL_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_DEPTH_BIT : (VkImageAspectFlagBits)0);
361 const VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
362 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
363
364 // Create destination buffer
365 {
366 const VkBufferCreateInfo bufferParams =
367 {
368 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
369 DE_NULL, // const void* pNext;
370 0u, // VkBufferCreateFlags flags;
371 pixelDataSize, // VkDeviceSize size;
372 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
373 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
374 0u, // deUint32 queueFamilyIndexCount;
375 DE_NULL // const deUint32* pQueueFamilyIndices;
376 };
377
378 buffer = createBuffer(vk, device, &bufferParams);
379 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
380 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
381 }
382
383 // Create command pool and buffer
384 cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
385 cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
386
387 beginCommandBuffer(vk, *cmdBuffer);
388 copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect, VK_IMAGE_ASPECT_STENCIL_BIT);
389 endCommandBuffer(vk, *cmdBuffer);
390
391 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
392
393 // Read buffer data
394 invalidateAlloc(vk, device, *bufferAlloc);
395 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
396
397 return resultLevel;
398 }
399
uploadTestTextureInternal(const DeviceInterface & vk,VkDevice device,VkQueue queue,deUint32 queueFamilyIndex,Allocator & allocator,const TestTexture & srcTexture,const TestTexture * srcStencilTexture,tcu::TextureFormat format,VkImage destImage)400 void uploadTestTextureInternal (const DeviceInterface& vk,
401 VkDevice device,
402 VkQueue queue,
403 deUint32 queueFamilyIndex,
404 Allocator& allocator,
405 const TestTexture& srcTexture,
406 const TestTexture* srcStencilTexture,
407 tcu::TextureFormat format,
408 VkImage destImage)
409 {
410 Move<VkBuffer> buffer;
411 de::MovePtr<Allocation> bufferAlloc;
412 Move<VkCommandPool> cmdPool;
413 Move<VkCommandBuffer> cmdBuffer;
414 const VkImageAspectFlags imageAspectFlags = getImageAspectFlags(format);
415 deUint32 stencilOffset = 0u;
416 std::vector<VkBufferImageCopy> copyRegions = srcTexture.getBufferCopyRegions();
417 deUint32 bufferSize = (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
418
419 // Stencil-only texture should be provided if (and only if) the image has a combined DS format
420 DE_ASSERT((tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order)) == (srcStencilTexture != DE_NULL));
421
422 if (srcStencilTexture != DE_NULL)
423 {
424 stencilOffset = static_cast<deUint32>(deAlign32(static_cast<deInt32>(bufferSize), 4));
425 bufferSize = stencilOffset + srcStencilTexture->getSize();
426 }
427
428 // Create source buffer
429 {
430 const VkBufferCreateInfo bufferParams =
431 {
432 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
433 DE_NULL, // const void* pNext;
434 0u, // VkBufferCreateFlags flags;
435 bufferSize, // VkDeviceSize size;
436 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
437 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
438 0u, // deUint32 queueFamilyIndexCount;
439 DE_NULL, // const deUint32* pQueueFamilyIndices;
440 };
441
442 buffer = createBuffer(vk, device, &bufferParams);
443 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
444 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
445 }
446
447 // Write buffer data
448 {
449 srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
450
451 if (srcStencilTexture != DE_NULL)
452 {
453 DE_ASSERT(stencilOffset != 0u);
454
455 srcStencilTexture->write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()) + stencilOffset);
456
457 std::vector<VkBufferImageCopy> stencilCopyRegions = srcStencilTexture->getBufferCopyRegions();
458 for (size_t regionIdx = 0; regionIdx < stencilCopyRegions.size(); regionIdx++)
459 {
460 VkBufferImageCopy region = stencilCopyRegions[regionIdx];
461 region.bufferOffset += stencilOffset;
462
463 copyRegions.push_back(region);
464 }
465 }
466
467 flushAlloc(vk, device, *bufferAlloc);
468 }
469
470 copyBufferToImage(vk, device, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, imageAspectFlags, srcTexture.getNumLevels(), srcTexture.getArraySize(), destImage);
471 }
472
checkSparseImageFormatSupport(const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,const VkImageCreateInfo & imageCreateInfo)473 bool checkSparseImageFormatSupport (const VkPhysicalDevice physicalDevice,
474 const InstanceInterface& instance,
475 const VkImageCreateInfo& imageCreateInfo)
476 {
477 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec =
478 getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.samples, imageCreateInfo.usage, imageCreateInfo.tiling);
479
480 return (sparseImageFormatPropVec.size() != 0);
481 }
482
uploadTestTextureInternalSparse(const DeviceInterface & vk,VkDevice device,const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,const VkImageCreateInfo & imageCreateInfo,VkQueue universalQueue,deUint32 universalQueueFamilyIndex,VkQueue sparseQueue,Allocator & allocator,std::vector<de::SharedPtr<Allocation>> & allocations,const TestTexture & srcTexture,const TestTexture * srcStencilTexture,tcu::TextureFormat format,VkImage destImage)483 void uploadTestTextureInternalSparse (const DeviceInterface& vk,
484 VkDevice device,
485 const VkPhysicalDevice physicalDevice,
486 const InstanceInterface& instance,
487 const VkImageCreateInfo& imageCreateInfo,
488 VkQueue universalQueue,
489 deUint32 universalQueueFamilyIndex,
490 VkQueue sparseQueue,
491 Allocator& allocator,
492 std::vector<de::SharedPtr<Allocation> >& allocations,
493 const TestTexture& srcTexture,
494 const TestTexture* srcStencilTexture,
495 tcu::TextureFormat format,
496 VkImage destImage)
497 {
498 deUint32 bufferSize = (srcTexture.isCompressed()) ? srcTexture.getCompressedSize(): srcTexture.getSize();
499 const VkImageAspectFlags imageAspectFlags = getImageAspectFlags(format);
500 deUint32 stencilOffset = 0u;
501 const Unique<VkSemaphore> imageMemoryBindSemaphore(createSemaphore(vk, device));
502 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, universalQueueFamilyIndex);
503 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
504 Move<VkFence> fence = createFence(vk, device);
505 std::vector<VkBufferImageCopy> copyRegions = srcTexture.getBufferCopyRegions();
506 Move<VkBuffer> buffer;
507 de::MovePtr<Allocation> bufferAlloc;
508
509 // Stencil-only texture should be provided if (and only if) the image has a combined DS format
510 DE_ASSERT((tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order)) == (srcStencilTexture != DE_NULL));
511
512 if (srcStencilTexture != DE_NULL)
513 {
514 stencilOffset = static_cast<deUint32>(deAlign32(static_cast<deInt32>(bufferSize), 4));
515 bufferSize = stencilOffset + srcStencilTexture->getSize();
516 }
517
518 allocateAndBindSparseImage (vk, device, physicalDevice, instance, imageCreateInfo, imageMemoryBindSemaphore.get(), sparseQueue, allocator, allocations, format, destImage);
519
520 {
521 // Create source buffer
522 const VkBufferCreateInfo bufferParams =
523 {
524 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
525 DE_NULL, // const void* pNext;
526 0u, // VkBufferCreateFlags flags;
527 bufferSize, // VkDeviceSize size;
528 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
529 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
530 0u, // deUint32 queueFamilyIndexCount;
531 DE_NULL, // const deUint32* pQueueFamilyIndices;
532 };
533
534 buffer = createBuffer(vk, device, &bufferParams);
535 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
536
537 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
538 }
539
540 {
541 // Write buffer data
542 srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
543
544 if (srcStencilTexture != DE_NULL)
545 {
546 DE_ASSERT(stencilOffset != 0u);
547
548 srcStencilTexture->write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()) + stencilOffset);
549
550 std::vector<VkBufferImageCopy> stencilCopyRegions = srcStencilTexture->getBufferCopyRegions();
551 for (size_t regionIdx = 0; regionIdx < stencilCopyRegions.size(); regionIdx++)
552 {
553 VkBufferImageCopy region = stencilCopyRegions[regionIdx];
554 region.bufferOffset += stencilOffset;
555
556 copyRegions.push_back(region);
557 }
558 }
559
560 flushAlloc(vk, device, *bufferAlloc);
561 }
562
563 copyBufferToImage(vk, device, universalQueue, universalQueueFamilyIndex, *buffer, bufferSize, copyRegions, &(*imageMemoryBindSemaphore), imageAspectFlags, imageCreateInfo.mipLevels, imageCreateInfo.arrayLayers, destImage);
564 }
565
uploadTestTexture(const DeviceInterface & vk,VkDevice device,VkQueue queue,deUint32 queueFamilyIndex,Allocator & allocator,const TestTexture & srcTexture,VkImage destImage)566 void uploadTestTexture (const DeviceInterface& vk,
567 VkDevice device,
568 VkQueue queue,
569 deUint32 queueFamilyIndex,
570 Allocator& allocator,
571 const TestTexture& srcTexture,
572 VkImage destImage)
573 {
574 if (tcu::isCombinedDepthStencilType(srcTexture.getTextureFormat().type))
575 {
576 de::MovePtr<TestTexture> srcDepthTexture;
577 de::MovePtr<TestTexture> srcStencilTexture;
578
579 if (tcu::hasDepthComponent(srcTexture.getTextureFormat().order))
580 {
581 tcu::TextureFormat format;
582 switch (srcTexture.getTextureFormat().type)
583 {
584 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
585 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
586 break;
587 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
588 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
589 break;
590 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
591 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
592 break;
593 default:
594 DE_FATAL("Unexpected source texture format.");
595 break;
596 }
597 srcDepthTexture = srcTexture.copy(format);
598 }
599
600 if (tcu::hasStencilComponent(srcTexture.getTextureFormat().order))
601 srcStencilTexture = srcTexture.copy(tcu::getEffectiveDepthStencilTextureFormat(srcTexture.getTextureFormat(), tcu::Sampler::MODE_STENCIL));
602
603 uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, *srcDepthTexture, srcStencilTexture.get(), srcTexture.getTextureFormat(), destImage);
604 }
605 else
606 uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, srcTexture, DE_NULL, srcTexture.getTextureFormat(), destImage);
607 }
608
uploadTestTextureSparse(const DeviceInterface & vk,VkDevice device,const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,const VkImageCreateInfo & imageCreateInfo,VkQueue universalQueue,deUint32 universalQueueFamilyIndex,VkQueue sparseQueue,Allocator & allocator,std::vector<de::SharedPtr<Allocation>> & allocations,const TestTexture & srcTexture,VkImage destImage)609 void uploadTestTextureSparse (const DeviceInterface& vk,
610 VkDevice device,
611 const VkPhysicalDevice physicalDevice,
612 const InstanceInterface& instance,
613 const VkImageCreateInfo& imageCreateInfo,
614 VkQueue universalQueue,
615 deUint32 universalQueueFamilyIndex,
616 VkQueue sparseQueue,
617 Allocator& allocator,
618 std::vector<de::SharedPtr<Allocation> >& allocations,
619 const TestTexture& srcTexture,
620 VkImage destImage)
621 {
622 if (tcu::isCombinedDepthStencilType(srcTexture.getTextureFormat().type))
623 {
624 de::MovePtr<TestTexture> srcDepthTexture;
625 de::MovePtr<TestTexture> srcStencilTexture;
626
627 if (tcu::hasDepthComponent(srcTexture.getTextureFormat().order))
628 {
629 tcu::TextureFormat format;
630 switch (srcTexture.getTextureFormat().type)
631 {
632 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
633 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
634 break;
635 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
636 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
637 break;
638 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
639 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
640 break;
641 default:
642 DE_FATAL("Unexpected source texture format.");
643 break;
644 }
645 srcDepthTexture = srcTexture.copy(format);
646 }
647
648 if (tcu::hasStencilComponent(srcTexture.getTextureFormat().order))
649 srcStencilTexture = srcTexture.copy(tcu::getEffectiveDepthStencilTextureFormat(srcTexture.getTextureFormat(), tcu::Sampler::MODE_STENCIL));
650
651 uploadTestTextureInternalSparse (vk,
652 device,
653 physicalDevice,
654 instance,
655 imageCreateInfo,
656 universalQueue,
657 universalQueueFamilyIndex,
658 sparseQueue,
659 allocator,
660 allocations,
661 *srcDepthTexture,
662 srcStencilTexture.get(),
663 srcTexture.getTextureFormat(),
664 destImage);
665 }
666 else
667 {
668 uploadTestTextureInternalSparse (vk,
669 device,
670 physicalDevice,
671 instance,
672 imageCreateInfo,
673 universalQueue,
674 universalQueueFamilyIndex,
675 sparseQueue,
676 allocator,
677 allocations,
678 srcTexture,
679 DE_NULL,
680 srcTexture.getTextureFormat(),
681 destImage);
682 }
683 }
684
685 // Utilities for test textures
686
687 template<typename TcuTextureType>
allocateLevels(TcuTextureType & texture)688 void allocateLevels (TcuTextureType& texture)
689 {
690 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
691 texture.allocLevel(levelNdx);
692 }
693
694 template<typename TcuTextureType>
getLevelsVector(const TcuTextureType & texture)695 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
696 {
697 std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
698
699 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
700 levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
701
702 return levels;
703 }
704
705 // TestTexture
706
TestTexture(const tcu::TextureFormat & format,int width,int height,int depth)707 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
708 {
709 DE_ASSERT(width >= 1);
710 DE_ASSERT(height >= 1);
711 DE_ASSERT(depth >= 1);
712
713 DE_UNREF(format);
714 DE_UNREF(width);
715 DE_UNREF(height);
716 DE_UNREF(depth);
717 }
718
TestTexture(const tcu::CompressedTexFormat & format,int width,int height,int depth)719 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
720 {
721 DE_ASSERT(width >= 1);
722 DE_ASSERT(height >= 1);
723 DE_ASSERT(depth >= 1);
724
725 DE_UNREF(format);
726 DE_UNREF(width);
727 DE_UNREF(height);
728 DE_UNREF(depth);
729 }
730
~TestTexture(void)731 TestTexture::~TestTexture (void)
732 {
733 for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
734 delete m_compressedLevels[levelNdx];
735 }
736
getSize(void) const737 deUint32 TestTexture::getSize (void) const
738 {
739 std::vector<deUint32> offsetMultiples;
740 deUint32 textureSize = 0;
741
742 offsetMultiples.push_back(4);
743 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
744
745 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
746 {
747 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
748 {
749 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
750 textureSize = getNextMultiple(offsetMultiples, textureSize);
751 textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
752 }
753 }
754
755 return textureSize;
756 }
757
getCompressedSize(void) const758 deUint32 TestTexture::getCompressedSize (void) const
759 {
760 if (!isCompressed())
761 throw tcu::InternalError("Texture is not compressed");
762
763 std::vector<deUint32> offsetMultiples;
764 deUint32 textureSize = 0;
765
766 offsetMultiples.push_back(4);
767 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
768
769 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
770 {
771 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
772 {
773 textureSize = getNextMultiple(offsetMultiples, textureSize);
774 textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
775 }
776 }
777
778 return textureSize;
779 }
780
getCompressedLevel(int level,int layer)781 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
782 {
783 DE_ASSERT(level >= 0 && level < getNumLevels());
784 DE_ASSERT(layer >= 0 && layer < getArraySize());
785
786 return *m_compressedLevels[level * getArraySize() + layer];
787 }
788
getCompressedLevel(int level,int layer) const789 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
790 {
791 DE_ASSERT(level >= 0 && level < getNumLevels());
792 DE_ASSERT(layer >= 0 && layer < getArraySize());
793
794 return *m_compressedLevels[level * getArraySize() + layer];
795 }
796
getBufferCopyRegions(void) const797 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
798 {
799 std::vector<deUint32> offsetMultiples;
800 std::vector<VkBufferImageCopy> regions;
801 deUint32 layerDataOffset = 0;
802
803 offsetMultiples.push_back(4);
804
805 if (isCompressed())
806 {
807 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
808
809 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
810 {
811 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
812 {
813 const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
814 tcu::IVec3 blockPixelSize = getBlockPixelSize(level.getFormat());
815 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
816
817 const VkBufferImageCopy layerRegion =
818 {
819 layerDataOffset, // VkDeviceSize bufferOffset;
820 (deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()), // deUint32 bufferRowLength;
821 (deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()), // deUint32 bufferImageHeight;
822 { // VkImageSubresourceLayers imageSubresource;
823 VK_IMAGE_ASPECT_COLOR_BIT,
824 (deUint32)levelNdx,
825 (deUint32)layerNdx,
826 1u
827 },
828 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
829 { // VkExtent3D imageExtent;
830 (deUint32)level.getWidth(),
831 (deUint32)level.getHeight(),
832 (deUint32)level.getDepth()
833 }
834 };
835
836 regions.push_back(layerRegion);
837 layerDataOffset += level.getDataSize();
838 }
839 }
840 }
841 else
842 {
843 std::vector<VkImageAspectFlags> imageAspects;
844 tcu::TextureFormat textureFormat = getTextureFormat();
845
846 if (tcu::hasDepthComponent(textureFormat.order))
847 imageAspects.push_back(VK_IMAGE_ASPECT_DEPTH_BIT);
848
849 if (tcu::hasStencilComponent(textureFormat.order))
850 imageAspects.push_back(VK_IMAGE_ASPECT_STENCIL_BIT);
851
852 if (imageAspects.empty())
853 imageAspects.push_back(VK_IMAGE_ASPECT_COLOR_BIT);
854
855 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
856
857 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
858 {
859 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
860 {
861 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
862
863 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
864
865 for (size_t aspectIndex = 0; aspectIndex < imageAspects.size(); ++aspectIndex)
866 {
867 const VkBufferImageCopy layerRegion =
868 {
869 layerDataOffset, // VkDeviceSize bufferOffset;
870 (deUint32)level.getWidth(), // deUint32 bufferRowLength;
871 (deUint32)level.getHeight(), // deUint32 bufferImageHeight;
872 { // VkImageSubresourceLayers imageSubresource;
873 imageAspects[aspectIndex],
874 (deUint32)levelNdx,
875 (deUint32)layerNdx,
876 1u
877 },
878 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
879 { // VkExtent3D imageExtent;
880 (deUint32)level.getWidth(),
881 (deUint32)level.getHeight(),
882 (deUint32)level.getDepth()
883 }
884 };
885
886 regions.push_back(layerRegion);
887 }
888 layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
889 }
890 }
891 }
892
893 return regions;
894 }
895
write(deUint8 * destPtr) const896 void TestTexture::write (deUint8* destPtr) const
897 {
898 std::vector<deUint32> offsetMultiples;
899 deUint32 levelOffset = 0;
900
901 offsetMultiples.push_back(4);
902
903 if (isCompressed())
904 {
905 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
906
907 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
908 {
909 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
910 {
911 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
912
913 const tcu::CompressedTexture& compressedTex = getCompressedLevel(levelNdx, layerNdx);
914
915 deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
916 levelOffset += compressedTex.getDataSize();
917 }
918 }
919 }
920 else
921 {
922 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
923
924 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
925 {
926 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
927 {
928 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
929
930 const tcu::ConstPixelBufferAccess srcAccess = getLevel(levelNdx, layerNdx);
931 const tcu::PixelBufferAccess destAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
932
933 tcu::copy(destAccess, srcAccess);
934 levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
935 }
936 }
937 }
938 }
939
copyToTexture(TestTexture & destTexture) const940 void TestTexture::copyToTexture (TestTexture& destTexture) const
941 {
942 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
943 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
944 tcu::copy(destTexture.getLevel(levelNdx, layerNdx), getLevel(levelNdx, layerNdx));
945 }
946
populateLevels(const std::vector<tcu::PixelBufferAccess> & levels)947 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
948 {
949 for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
950 TestTexture::fillWithGradient(levels[levelNdx]);
951 }
952
populateCompressedLevels(tcu::CompressedTexFormat format,const std::vector<tcu::PixelBufferAccess> & decompressedLevels)953 void TestTexture::populateCompressedLevels (tcu::CompressedTexFormat format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
954 {
955 // Generate random compressed data and update decompressed data
956
957 de::Random random(123);
958
959 for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
960 {
961 const tcu::PixelBufferAccess level = decompressedLevels[levelNdx];
962 tcu::CompressedTexture* compressedLevel = new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
963 deUint8* const compressedData = (deUint8*)compressedLevel->getData();
964
965 if (tcu::isAstcFormat(format))
966 {
967 // \todo [2016-01-20 pyry] Comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
968 tcu::astc::generateRandomValidBlocks(compressedData, compressedLevel->getDataSize()/tcu::astc::BLOCK_SIZE_BYTES,
969 format, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
970 }
971 else
972 {
973 // Generate random compressed data
974 // Random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
975 if (format != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
976 for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
977 compressedData[byteNdx] = 0xFF & random.getUint32();
978 }
979
980 m_compressedLevels.push_back(compressedLevel);
981
982 // Store decompressed data
983 compressedLevel->decompress(level, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
984 }
985 }
986
fillWithGradient(const tcu::PixelBufferAccess & levelAccess)987 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
988 {
989 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
990 tcu::fillWithComponentGradients2(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
991 }
992
993 // TestTexture1D
994
TestTexture1D(const tcu::TextureFormat & format,int width)995 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
996 : TestTexture (format, width, 1, 1)
997 , m_texture (format, width)
998 {
999 allocateLevels(m_texture);
1000 TestTexture::populateLevels(getLevelsVector(m_texture));
1001 }
1002
TestTexture1D(const tcu::CompressedTexFormat & format,int width)1003 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
1004 : TestTexture (format, width, 1, 1)
1005 , m_texture (tcu::getUncompressedFormat(format), width)
1006 {
1007 allocateLevels(m_texture);
1008 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1009 }
1010
~TestTexture1D(void)1011 TestTexture1D::~TestTexture1D (void)
1012 {
1013 }
1014
getNumLevels(void) const1015 int TestTexture1D::getNumLevels (void) const
1016 {
1017 return m_texture.getNumLevels();
1018 }
1019
getLevel(int level,int layer)1020 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
1021 {
1022 DE_ASSERT(layer == 0);
1023 DE_UNREF(layer);
1024 return m_texture.getLevel(level);
1025 }
1026
getLevel(int level,int layer) const1027 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
1028 {
1029 DE_ASSERT(layer == 0);
1030 DE_UNREF(layer);
1031 return m_texture.getLevel(level);
1032 }
1033
getTexture(void) const1034 const tcu::Texture1D& TestTexture1D::getTexture (void) const
1035 {
1036 return m_texture;
1037 }
1038
getTexture(void)1039 tcu::Texture1D& TestTexture1D::getTexture (void)
1040 {
1041 return m_texture;
1042 }
1043
copy(const tcu::TextureFormat format) const1044 de::MovePtr<TestTexture> TestTexture1D::copy(const tcu::TextureFormat format) const
1045 {
1046 DE_ASSERT(!isCompressed());
1047
1048 de::MovePtr<TestTexture> texture (new TestTexture1D(format, m_texture.getWidth()));
1049
1050 copyToTexture(*texture);
1051
1052 return texture;
1053 }
1054
1055 // TestTexture1DArray
1056
TestTexture1DArray(const tcu::TextureFormat & format,int width,int arraySize)1057 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
1058 : TestTexture (format, width, 1, arraySize)
1059 , m_texture (format, width, arraySize)
1060 {
1061 allocateLevels(m_texture);
1062 TestTexture::populateLevels(getLevelsVector(m_texture));
1063 }
1064
TestTexture1DArray(const tcu::CompressedTexFormat & format,int width,int arraySize)1065 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
1066 : TestTexture (format, width, 1, arraySize)
1067 , m_texture (tcu::getUncompressedFormat(format), width, arraySize)
1068 {
1069 allocateLevels(m_texture);
1070
1071 std::vector<tcu::PixelBufferAccess> layers;
1072 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1073 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
1074 layers.push_back(getLevel(levelNdx, layerNdx));
1075
1076 TestTexture::populateCompressedLevels(format, layers);
1077 }
1078
~TestTexture1DArray(void)1079 TestTexture1DArray::~TestTexture1DArray (void)
1080 {
1081 }
1082
getNumLevels(void) const1083 int TestTexture1DArray::getNumLevels (void) const
1084 {
1085 return m_texture.getNumLevels();
1086 }
1087
getLevel(int level,int layer)1088 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
1089 {
1090 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
1091 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
1092 const deUint32 layerOffset = layerSize * layer;
1093
1094 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1095 }
1096
getLevel(int level,int layer) const1097 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
1098 {
1099 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
1100 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
1101 const deUint32 layerOffset = layerSize * layer;
1102
1103 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1104 }
1105
getTexture(void) const1106 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
1107 {
1108 return m_texture;
1109 }
1110
getTexture(void)1111 tcu::Texture1DArray& TestTexture1DArray::getTexture (void)
1112 {
1113 return m_texture;
1114 }
1115
getArraySize(void) const1116 int TestTexture1DArray::getArraySize (void) const
1117 {
1118 return m_texture.getNumLayers();
1119 }
1120
copy(const tcu::TextureFormat format) const1121 de::MovePtr<TestTexture> TestTexture1DArray::copy(const tcu::TextureFormat format) const
1122 {
1123 DE_ASSERT(!isCompressed());
1124
1125 de::MovePtr<TestTexture> texture (new TestTexture1DArray(format, m_texture.getWidth(), getArraySize()));
1126
1127 copyToTexture(*texture);
1128
1129 return texture;
1130 }
1131
1132 // TestTexture2D
1133
TestTexture2D(const tcu::TextureFormat & format,int width,int height)1134 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
1135 : TestTexture (format, width, height, 1)
1136 , m_texture (format, width, height)
1137 {
1138 allocateLevels(m_texture);
1139 TestTexture::populateLevels(getLevelsVector(m_texture));
1140 }
1141
TestTexture2D(const tcu::TextureFormat & format,int width,int height,int miplevels)1142 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height, int miplevels)
1143 : TestTexture(format, width, height, 1)
1144 , m_texture(format, width, height, miplevels)
1145 {
1146 allocateLevels(m_texture);
1147 TestTexture::populateLevels(getLevelsVector(m_texture));
1148 }
1149
1150
TestTexture2D(const tcu::CompressedTexFormat & format,int width,int height)1151 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
1152 : TestTexture (format, width, height, 1)
1153 , m_texture (tcu::getUncompressedFormat(format), width, height)
1154 {
1155 allocateLevels(m_texture);
1156 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1157 }
1158
~TestTexture2D(void)1159 TestTexture2D::~TestTexture2D (void)
1160 {
1161 }
1162
getNumLevels(void) const1163 int TestTexture2D::getNumLevels (void) const
1164 {
1165 return m_texture.getNumLevels();
1166 }
1167
getLevel(int level,int layer)1168 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
1169 {
1170 DE_ASSERT(layer == 0);
1171 DE_UNREF(layer);
1172 return m_texture.getLevel(level);
1173 }
1174
getLevel(int level,int layer) const1175 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
1176 {
1177 DE_ASSERT(layer == 0);
1178 DE_UNREF(layer);
1179 return m_texture.getLevel(level);
1180 }
1181
getTexture(void) const1182 const tcu::Texture2D& TestTexture2D::getTexture (void) const
1183 {
1184 return m_texture;
1185 }
1186
getTexture(void)1187 tcu::Texture2D& TestTexture2D::getTexture (void)
1188 {
1189 return m_texture;
1190 }
1191
copy(const tcu::TextureFormat format) const1192 de::MovePtr<TestTexture> TestTexture2D::copy(const tcu::TextureFormat format) const
1193 {
1194 DE_ASSERT(!isCompressed());
1195
1196 de::MovePtr<TestTexture> texture (new TestTexture2D(format, m_texture.getWidth(), m_texture.getHeight(), m_texture.getNumLevels()));
1197
1198 copyToTexture(*texture);
1199
1200 return texture;
1201 }
1202
1203 // TestTexture2DArray
1204
TestTexture2DArray(const tcu::TextureFormat & format,int width,int height,int arraySize)1205 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
1206 : TestTexture (format, width, height, arraySize)
1207 , m_texture (format, width, height, arraySize)
1208 {
1209 allocateLevels(m_texture);
1210 TestTexture::populateLevels(getLevelsVector(m_texture));
1211 }
1212
TestTexture2DArray(const tcu::CompressedTexFormat & format,int width,int height,int arraySize)1213 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
1214 : TestTexture (format, width, height, arraySize)
1215 , m_texture (tcu::getUncompressedFormat(format), width, height, arraySize)
1216 {
1217 allocateLevels(m_texture);
1218
1219 std::vector<tcu::PixelBufferAccess> layers;
1220 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1221 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
1222 layers.push_back(getLevel(levelNdx, layerNdx));
1223
1224 TestTexture::populateCompressedLevels(format, layers);
1225 }
1226
~TestTexture2DArray(void)1227 TestTexture2DArray::~TestTexture2DArray (void)
1228 {
1229 }
1230
getNumLevels(void) const1231 int TestTexture2DArray::getNumLevels (void) const
1232 {
1233 return m_texture.getNumLevels();
1234 }
1235
getLevel(int level,int layer)1236 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
1237 {
1238 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
1239 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1240 const deUint32 layerOffset = layerSize * layer;
1241
1242 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1243 }
1244
getLevel(int level,int layer) const1245 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
1246 {
1247 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
1248 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1249 const deUint32 layerOffset = layerSize * layer;
1250
1251 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1252 }
1253
getTexture(void) const1254 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
1255 {
1256 return m_texture;
1257 }
1258
getTexture(void)1259 tcu::Texture2DArray& TestTexture2DArray::getTexture (void)
1260 {
1261 return m_texture;
1262 }
1263
getArraySize(void) const1264 int TestTexture2DArray::getArraySize (void) const
1265 {
1266 return m_texture.getNumLayers();
1267 }
1268
copy(const tcu::TextureFormat format) const1269 de::MovePtr<TestTexture> TestTexture2DArray::copy(const tcu::TextureFormat format) const
1270 {
1271 DE_ASSERT(!isCompressed());
1272
1273 de::MovePtr<TestTexture> texture (new TestTexture2DArray(format, m_texture.getWidth(), m_texture.getHeight(), getArraySize()));
1274
1275 copyToTexture(*texture);
1276
1277 return texture;
1278 }
1279
1280 // TestTexture3D
1281
TestTexture3D(const tcu::TextureFormat & format,int width,int height,int depth)1282 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
1283 : TestTexture (format, width, height, depth)
1284 , m_texture (format, width, height, depth)
1285 {
1286 allocateLevels(m_texture);
1287 TestTexture::populateLevels(getLevelsVector(m_texture));
1288 }
1289
TestTexture3D(const tcu::CompressedTexFormat & format,int width,int height,int depth)1290 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
1291 : TestTexture (format, width, height, depth)
1292 , m_texture (tcu::getUncompressedFormat(format), width, height, depth)
1293 {
1294 allocateLevels(m_texture);
1295 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1296 }
1297
~TestTexture3D(void)1298 TestTexture3D::~TestTexture3D (void)
1299 {
1300 }
1301
getNumLevels(void) const1302 int TestTexture3D::getNumLevels (void) const
1303 {
1304 return m_texture.getNumLevels();
1305 }
1306
getLevel(int level,int layer)1307 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
1308 {
1309 DE_ASSERT(layer == 0);
1310 DE_UNREF(layer);
1311 return m_texture.getLevel(level);
1312 }
1313
getLevel(int level,int layer) const1314 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
1315 {
1316 DE_ASSERT(layer == 0);
1317 DE_UNREF(layer);
1318 return m_texture.getLevel(level);
1319 }
1320
getTexture(void) const1321 const tcu::Texture3D& TestTexture3D::getTexture (void) const
1322 {
1323 return m_texture;
1324 }
1325
getTexture(void)1326 tcu::Texture3D& TestTexture3D::getTexture (void)
1327 {
1328 return m_texture;
1329 }
1330
copy(const tcu::TextureFormat format) const1331 de::MovePtr<TestTexture> TestTexture3D::copy(const tcu::TextureFormat format) const
1332 {
1333 DE_ASSERT(!isCompressed());
1334
1335 de::MovePtr<TestTexture> texture (new TestTexture3D(format, m_texture.getWidth(), m_texture.getHeight(), m_texture.getDepth()));
1336
1337 copyToTexture(*texture);
1338
1339 return texture;
1340 }
1341
1342 // TestTextureCube
1343
1344 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
1345 {
1346 tcu::CUBEFACE_POSITIVE_X,
1347 tcu::CUBEFACE_NEGATIVE_X,
1348 tcu::CUBEFACE_POSITIVE_Y,
1349 tcu::CUBEFACE_NEGATIVE_Y,
1350 tcu::CUBEFACE_POSITIVE_Z,
1351 tcu::CUBEFACE_NEGATIVE_Z
1352 };
1353
TestTextureCube(const tcu::TextureFormat & format,int size)1354 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
1355 : TestTexture (format, size, size, 1)
1356 , m_texture (format, size)
1357 {
1358 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1359 {
1360 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1361 {
1362 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1363 TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
1364 }
1365 }
1366 }
1367
TestTextureCube(const tcu::CompressedTexFormat & format,int size)1368 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
1369 : TestTexture (format, size, size, 1)
1370 , m_texture (tcu::getUncompressedFormat(format), size)
1371 {
1372 std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
1373
1374 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1375 {
1376 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1377 {
1378 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1379 levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
1380 }
1381 }
1382
1383 TestTexture::populateCompressedLevels(format, levels);
1384 }
1385
~TestTextureCube(void)1386 TestTextureCube::~TestTextureCube (void)
1387 {
1388 }
1389
getNumLevels(void) const1390 int TestTextureCube::getNumLevels (void) const
1391 {
1392 return m_texture.getNumLevels();
1393 }
1394
getLevel(int level,int layer)1395 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int layer)
1396 {
1397 return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1398 }
1399
getLevel(int level,int layer) const1400 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int layer) const
1401 {
1402 return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1403 }
1404
getArraySize(void) const1405 int TestTextureCube::getArraySize (void) const
1406 {
1407 return (int)tcu::CUBEFACE_LAST;
1408 }
1409
getTexture(void) const1410 const tcu::TextureCube& TestTextureCube::getTexture (void) const
1411 {
1412 return m_texture;
1413 }
1414
getTexture(void)1415 tcu::TextureCube& TestTextureCube::getTexture (void)
1416 {
1417 return m_texture;
1418 }
1419
copy(const tcu::TextureFormat format) const1420 de::MovePtr<TestTexture> TestTextureCube::copy(const tcu::TextureFormat format) const
1421 {
1422 DE_ASSERT(!isCompressed());
1423
1424 de::MovePtr<TestTexture> texture (new TestTextureCube(format, m_texture.getSize()));
1425
1426 copyToTexture(*texture);
1427
1428 return texture;
1429 }
1430
1431 // TestTextureCubeArray
1432
TestTextureCubeArray(const tcu::TextureFormat & format,int size,int arraySize)1433 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
1434 : TestTexture (format, size, size, arraySize)
1435 , m_texture (format, size, arraySize)
1436 {
1437 allocateLevels(m_texture);
1438 TestTexture::populateLevels(getLevelsVector(m_texture));
1439 }
1440
TestTextureCubeArray(const tcu::CompressedTexFormat & format,int size,int arraySize)1441 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
1442 : TestTexture (format, size, size, arraySize)
1443 , m_texture (tcu::getUncompressedFormat(format), size, arraySize)
1444 {
1445 DE_ASSERT(arraySize % 6 == 0);
1446
1447 allocateLevels(m_texture);
1448
1449 std::vector<tcu::PixelBufferAccess> layers;
1450 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1451 for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
1452 layers.push_back(getLevel(levelNdx, layerNdx));
1453
1454 TestTexture::populateCompressedLevels(format, layers);
1455 }
1456
~TestTextureCubeArray(void)1457 TestTextureCubeArray::~TestTextureCubeArray (void)
1458 {
1459 }
1460
getNumLevels(void) const1461 int TestTextureCubeArray::getNumLevels (void) const
1462 {
1463 return m_texture.getNumLevels();
1464 }
1465
getLevel(int level,int layer)1466 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
1467 {
1468 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
1469 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1470 const deUint32 layerOffset = layerSize * layer;
1471
1472 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1473 }
1474
getLevel(int level,int layer) const1475 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
1476 {
1477 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
1478 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1479 const deUint32 layerOffset = layerSize * layer;
1480
1481 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1482 }
1483
getArraySize(void) const1484 int TestTextureCubeArray::getArraySize (void) const
1485 {
1486 return m_texture.getDepth();
1487 }
1488
getTexture(void) const1489 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const
1490 {
1491 return m_texture;
1492 }
1493
getTexture(void)1494 tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void)
1495 {
1496 return m_texture;
1497 }
1498
copy(const tcu::TextureFormat format) const1499 de::MovePtr<TestTexture> TestTextureCubeArray::copy(const tcu::TextureFormat format) const
1500 {
1501 DE_ASSERT(!isCompressed());
1502
1503 de::MovePtr<TestTexture> texture (new TestTextureCubeArray(format, m_texture.getSize(), getArraySize()));
1504
1505 copyToTexture(*texture);
1506
1507 return texture;
1508 }
1509
1510 } // pipeline
1511 } // vkt
1512