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