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