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