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